diff --git a/lib/ocelot-brain b/lib/ocelot-brain index 4691662..a47c5c7 160000 --- a/lib/ocelot-brain +++ b/lib/ocelot-brain @@ -1 +1 @@ -Subproject commit 4691662178402268036de50fc85522b3795fe190 +Subproject commit a47c5c77fcf007f8fc54246cd3b0a15f53bec5b0 diff --git a/sprites/Knob.png b/sprites/Knob.png new file mode 100644 index 0000000..70b1dcf Binary files /dev/null and b/sprites/Knob.png differ diff --git a/sprites/KnobCenter.png b/sprites/KnobCenter.png new file mode 100644 index 0000000..2d33316 Binary files /dev/null and b/sprites/KnobCenter.png differ diff --git a/sprites/KnobLimits.png b/sprites/KnobLimits.png new file mode 100644 index 0000000..ffb85ff Binary files /dev/null and b/sprites/KnobLimits.png differ diff --git a/src/main/resources/ocelot/desktop/spritesheet.png b/src/main/resources/ocelot/desktop/spritesheet.png index fa0b5a7..38e6fd1 100644 Binary files a/src/main/resources/ocelot/desktop/spritesheet.png and b/src/main/resources/ocelot/desktop/spritesheet.png differ diff --git a/src/main/resources/ocelot/desktop/spritesheet.txt b/src/main/resources/ocelot/desktop/spritesheet.txt index 1cbc08d..5a1243b 100644 --- a/src/main/resources/ocelot/desktop/spritesheet.txt +++ b/src/main/resources/ocelot/desktop/spritesheet.txt @@ -1,105 +1,108 @@ BackgroundPattern 0 0 304 304 ComputerMotherboard 305 0 79 70 -Empty 417 0 1 1 -EmptySlot 441 96 18 18 -ShadowBorder 385 0 1 24 -ShadowCorner 424 71 24 24 -buttons/PowerOff 460 96 18 18 -buttons/PowerOn 479 96 18 18 -icons/CPU 424 144 16 16 -icons/Card 441 144 16 16 -icons/ComponentBus 458 144 16 16 -icons/DragLMB 424 129 21 14 -icons/DragRMB 446 129 21 14 -icons/EEPROM 475 144 16 16 -icons/Floppy 492 144 16 16 -icons/HDD 449 71 16 16 -icons/LMB 424 268 11 14 -icons/Memory 466 71 16 16 -icons/NA 483 71 16 16 -icons/RMB 436 268 11 14 -icons/RackMountable 356 168 16 16 -icons/Tier0 373 168 16 16 -icons/Tier1 390 168 16 16 -icons/Tier2 407 168 16 16 -items/APU0 356 71 16 96 -items/APU1 373 71 16 96 -items/APU2 390 71 16 96 -items/CPU0 424 168 16 16 -items/CPU1 441 168 16 16 -items/CPU2 458 168 16 16 -items/CardBase 475 168 16 16 -items/CircuitBoard 492 168 16 16 -items/ComponentBus0 305 200 16 16 -items/ComponentBus1 322 200 16 16 -items/ComponentBus2 339 200 16 16 -items/ComponentBus3 356 200 16 16 -items/DataCard0 305 71 16 128 -items/DataCard1 322 71 16 128 -items/DataCard2 339 71 16 128 -items/DebugCard 373 200 16 16 -items/DiskDriveMountable 390 200 16 16 -items/EEPROM 407 200 16 16 -items/FloppyDisk_dyeBlack 424 200 16 16 -items/FloppyDisk_dyeBlue 441 200 16 16 -items/FloppyDisk_dyeBrown 458 200 16 16 -items/FloppyDisk_dyeCyan 475 200 16 16 -items/FloppyDisk_dyeGray 492 200 16 16 -items/FloppyDisk_dyeGreen 305 217 16 16 -items/FloppyDisk_dyeLightBlue 322 217 16 16 -items/FloppyDisk_dyeLightGray 339 217 16 16 -items/FloppyDisk_dyeLime 356 217 16 16 -items/FloppyDisk_dyeMagenta 373 217 16 16 -items/FloppyDisk_dyeOrange 390 217 16 16 -items/FloppyDisk_dyePink 407 217 16 16 -items/FloppyDisk_dyePurple 424 217 16 16 -items/FloppyDisk_dyeRed 441 217 16 16 -items/FloppyDisk_dyeWhite 458 217 16 16 -items/FloppyDisk_dyeYellow 475 217 16 16 -items/GraphicsCard0 492 217 16 16 -items/GraphicsCard1 305 234 16 16 -items/GraphicsCard2 322 234 16 16 -items/HardDiskDrive0 339 234 16 16 -items/HardDiskDrive1 356 234 16 16 -items/HardDiskDrive2 373 234 16 16 -items/InternetCard 424 96 16 32 -items/LinkedCard 407 71 16 96 -items/Memory0 390 234 16 16 -items/Memory1 407 234 16 16 -items/Memory2 424 234 16 16 -items/Memory3 441 234 16 16 -items/Memory4 458 234 16 16 -items/Memory5 475 234 16 16 -items/NetworkCard 492 234 16 16 -items/RedstoneCard0 305 251 16 16 -items/RedstoneCard1 322 251 16 16 -items/Server0 339 251 16 16 -items/Server1 356 251 16 16 -items/Server2 373 251 16 16 -items/Server3 390 251 16 16 -items/WirelessNetworkCard0 407 251 16 16 -items/WirelessNetworkCard1 424 251 16 16 -nodes/Computer 441 251 16 16 -nodes/ComputerActivityOverlay 458 251 16 16 -nodes/ComputerErrorOverlay 475 251 16 16 -nodes/ComputerOnOverlay 492 251 16 16 -nodes/DiskDrive 305 268 16 16 -nodes/DiskDriveActivity 322 268 16 16 -nodes/DiskDriveFloppy 339 268 16 16 -nodes/NewNode 356 268 16 16 -nodes/Relay 373 268 16 16 -nodes/Screen 390 268 16 16 -nodes/ScreenOnOverlay 407 268 16 16 -screen/BorderB 390 0 2 8 -screen/BorderT 387 0 2 10 -screen/CornerBL 466 268 8 8 -screen/CornerBR 475 268 8 8 -screen/CornerTL 448 268 8 10 -screen/CornerTR 457 268 8 10 -window/BorderDark 413 0 1 4 -window/BorderLight 415 0 1 4 -window/CloseButton 484 268 7 6 -window/CornerBL 393 0 4 4 -window/CornerBR 398 0 4 4 -window/CornerTL 403 0 4 4 -window/CornerTR 408 0 4 4 +Empty 498 11 1 1 +EmptySlot 441 147 18 18 +Knob 385 0 50 50 +KnobCenter 436 0 50 50 +KnobLimits 305 71 50 50 +ShadowBorder 487 0 1 24 +ShadowCorner 424 122 24 24 +buttons/PowerOff 460 147 18 18 +buttons/PowerOn 479 147 18 18 +icons/CPU 424 195 16 16 +icons/Card 441 195 16 16 +icons/ComponentBus 458 195 16 16 +icons/DragLMB 424 180 21 14 +icons/DragRMB 446 180 21 14 +icons/EEPROM 475 195 16 16 +icons/Floppy 492 195 16 16 +icons/HDD 449 122 16 16 +icons/LMB 373 105 11 14 +icons/Memory 466 122 16 16 +icons/NA 483 122 16 16 +icons/RMB 385 105 11 14 +icons/RackMountable 356 219 16 16 +icons/Tier0 373 219 16 16 +icons/Tier1 390 219 16 16 +icons/Tier2 407 219 16 16 +items/APU0 356 122 16 96 +items/APU1 373 122 16 96 +items/APU2 390 122 16 96 +items/CPU0 424 219 16 16 +items/CPU1 441 219 16 16 +items/CPU2 458 219 16 16 +items/CardBase 475 219 16 16 +items/CircuitBoard 492 219 16 16 +items/ComponentBus0 305 251 16 16 +items/ComponentBus1 322 251 16 16 +items/ComponentBus2 339 251 16 16 +items/ComponentBus3 356 251 16 16 +items/DataCard0 305 122 16 128 +items/DataCard1 322 122 16 128 +items/DataCard2 339 122 16 128 +items/DebugCard 373 251 16 16 +items/DiskDriveMountable 390 251 16 16 +items/EEPROM 407 251 16 16 +items/FloppyDisk_dyeBlack 424 251 16 16 +items/FloppyDisk_dyeBlue 441 251 16 16 +items/FloppyDisk_dyeBrown 458 251 16 16 +items/FloppyDisk_dyeCyan 475 251 16 16 +items/FloppyDisk_dyeGray 492 251 16 16 +items/FloppyDisk_dyeGreen 305 268 16 16 +items/FloppyDisk_dyeLightBlue 322 268 16 16 +items/FloppyDisk_dyeLightGray 339 268 16 16 +items/FloppyDisk_dyeLime 356 268 16 16 +items/FloppyDisk_dyeMagenta 373 268 16 16 +items/FloppyDisk_dyeOrange 390 268 16 16 +items/FloppyDisk_dyePink 407 268 16 16 +items/FloppyDisk_dyePurple 424 268 16 16 +items/FloppyDisk_dyeRed 441 268 16 16 +items/FloppyDisk_dyeWhite 458 268 16 16 +items/FloppyDisk_dyeYellow 475 268 16 16 +items/GraphicsCard0 492 268 16 16 +items/GraphicsCard1 305 285 16 16 +items/GraphicsCard2 322 285 16 16 +items/HardDiskDrive0 339 285 16 16 +items/HardDiskDrive1 356 285 16 16 +items/HardDiskDrive2 373 285 16 16 +items/InternetCard 424 147 16 32 +items/LinkedCard 407 122 16 96 +items/Memory0 390 285 16 16 +items/Memory1 407 285 16 16 +items/Memory2 424 285 16 16 +items/Memory3 441 285 16 16 +items/Memory4 458 285 16 16 +items/Memory5 475 285 16 16 +items/NetworkCard 492 285 16 16 +items/RedstoneCard0 356 71 16 16 +items/RedstoneCard1 373 71 16 16 +items/Server0 390 71 16 16 +items/Server1 407 71 16 16 +items/Server2 424 71 16 16 +items/Server3 441 71 16 16 +items/WirelessNetworkCard0 458 71 16 16 +items/WirelessNetworkCard1 475 71 16 16 +nodes/Computer 492 71 16 16 +nodes/ComputerActivityOverlay 356 88 16 16 +nodes/ComputerErrorOverlay 373 88 16 16 +nodes/ComputerOnOverlay 390 88 16 16 +nodes/DiskDrive 407 88 16 16 +nodes/DiskDriveActivity 424 88 16 16 +nodes/DiskDriveFloppy 441 88 16 16 +nodes/NewNode 458 88 16 16 +nodes/Relay 475 88 16 16 +nodes/Screen 492 88 16 16 +nodes/ScreenOnOverlay 356 105 16 16 +screen/BorderB 492 0 2 8 +screen/BorderT 489 0 2 10 +screen/CornerBL 415 105 8 8 +screen/CornerBR 424 105 8 8 +screen/CornerTL 397 105 8 10 +screen/CornerTR 406 105 8 10 +window/BorderDark 494 11 1 4 +window/BorderLight 496 11 1 4 +window/CloseButton 433 105 7 6 +window/CornerBL 495 0 4 4 +window/CornerBR 500 0 4 4 +window/CornerTL 505 0 4 4 +window/CornerTR 489 11 4 4 diff --git a/src/main/scala/ocelot/desktop/node/nodes/ComputerWindow.scala b/src/main/scala/ocelot/desktop/node/nodes/ComputerWindow.scala index 45647ab..4d4f630 100644 --- a/src/main/scala/ocelot/desktop/node/nodes/ComputerWindow.scala +++ b/src/main/scala/ocelot/desktop/node/nodes/ComputerWindow.scala @@ -9,6 +9,7 @@ import ocelot.desktop.ui.widget._ import ocelot.desktop.ui.widget.window.BasicWindow import ocelot.desktop.util.{DrawUtils, Orientation} import totoro.ocelot.brain.entity.Case +import totoro.ocelot.brain.util.DyeColor class ComputerWindow(computerNode: ComputerNode) extends BasicWindow { def computer: Case = computerNode.computer @@ -42,6 +43,7 @@ class ComputerWindow(computerNode: ComputerNode) extends BasicWindow { } }, Padding2D(top = 44, left = 40)) + children :+= slotsWidget } } diff --git a/src/main/scala/ocelot/desktop/ui/widget/Knob.scala b/src/main/scala/ocelot/desktop/ui/widget/Knob.scala new file mode 100644 index 0000000..193aab2 --- /dev/null +++ b/src/main/scala/ocelot/desktop/ui/widget/Knob.scala @@ -0,0 +1,56 @@ +package ocelot.desktop.ui.widget + +import ocelot.desktop.color.{Color, IntColor} +import ocelot.desktop.geometry.{Size2D, Vector2D} +import ocelot.desktop.graphics.Graphics +import ocelot.desktop.ui.UiHandler +import ocelot.desktop.ui.event.MouseEvent +import totoro.ocelot.brain.util.DyeColor + +abstract class Knob(dyeColor: DyeColor = DyeColor.RED) extends Widget { + def value: Int + def value_=(v: Int): Unit + + val color: Color = { + var hsv = IntColor(dyeColor.rgb).toHSVA + if (hsv.v > 0.6) hsv = hsv.copy(v = 0.6f) + hsv.toRGBANorm + } + + override def minimumSize: Size2D = Size2D(25, 25) + override def maximumSize: Size2D = minimumSize + + override def receiveMouseEvents: Boolean = true + + private var movePos: Option[Vector2D] = None + private var startValue: Int = 0 + + eventHandlers += { + case MouseEvent(MouseEvent.State.Press, MouseEvent.Button.Left) => + val mousePos = UiHandler.mousePosition + if (bounds.contains(mousePos)) { + movePos = Some(mousePos) + startValue = value + } + + case MouseEvent(MouseEvent.State.Release, MouseEvent.Button.Left) => + movePos = None + } + + override def update(): Unit = { + super.update() + if (movePos.isEmpty) return + val dist = (UiHandler.mousePosition.x - movePos.get.x) / 2f + value = (startValue + dist.toInt) min 15 max 0 + } + + override def draw(g: Graphics): Unit = { + g.sprite("KnobLimits", position.x, position.y, 25, 25) + g.save() + g.translate(position.x + 12.5f, position.y + 12.5f) + g.rotate(value.toFloat / 15f * 4.71239f - 0.785398f) + g.sprite("Knob", -12.5f, -12.5f, 25, 25, color) + g.restore() + g.sprite("KnobCenter", position.x, position.y, 25, 25) + } +} diff --git a/src/main/scala/ocelot/desktop/ui/widget/card/Redstone2Window.scala b/src/main/scala/ocelot/desktop/ui/widget/card/Redstone2Window.scala new file mode 100644 index 0000000..a20c826 --- /dev/null +++ b/src/main/scala/ocelot/desktop/ui/widget/card/Redstone2Window.scala @@ -0,0 +1,79 @@ +package ocelot.desktop.ui.widget.card + +import ocelot.desktop.geometry.{Padding2D, Size2D} +import ocelot.desktop.graphics.Graphics +import ocelot.desktop.ui.layout.{AlignItems, Layout, LinearLayout} +import ocelot.desktop.ui.widget.{Knob, Label, PaddingBox, Widget} +import ocelot.desktop.ui.widget.window.BasicWindow +import ocelot.desktop.util.{DrawUtils, Orientation} +import totoro.ocelot.brain.entity.Redstone +import totoro.ocelot.brain.util.DyeColor + +class Redstone2Window(card: Redstone.Tier2) extends BasicWindow { + private def bundledKnob(side: Int, col: Int) = new Knob(DyeColor.byCode(col)) { + override def value: Int = { + card.bundledRedstoneInput(side)(col) + } + + override def value_=(v: Int): Unit = { + card.bundledRedstoneInput(side)(col) = v + } + } + + private def bundledBlock(side: Int, name: String) = new PaddingBox(new Widget { + override protected val layout: Layout = new LinearLayout(this, orientation = Orientation.Vertical, alignItems = AlignItems.Center) + children :+= new Label { + override def text: String = name + override def maximumSize: Size2D = minimumSize + } + children :+= new Widget { + children :+= bundledKnob(side, 0) + children :+= bundledKnob(side, 1) + children :+= bundledKnob(side, 2) + children :+= bundledKnob(side, 3) + } + children :+= new Widget { + children :+= bundledKnob(side, 4) + children :+= bundledKnob(side, 5) + children :+= bundledKnob(side, 6) + children :+= bundledKnob(side, 7) + } + children :+= new Widget { + children :+= bundledKnob(side, 8) + children :+= bundledKnob(side, 9) + children :+= bundledKnob(side, 10) + children :+= bundledKnob(side, 11) + } + children :+= new Widget { + children :+= bundledKnob(side, 12) + children :+= bundledKnob(side, 13) + children :+= bundledKnob(side, 14) + children :+= bundledKnob(side, 15) + } + }, Padding2D.equal(4)) + + children :+= new PaddingBox(new Widget { + children :+= new Widget { + override protected val layout: Layout = new LinearLayout(this, orientation = Orientation.Vertical) + children :+= bundledBlock(0, "Bottom") + children :+= bundledBlock(1, "Top") + } + children :+= new Widget { + override protected val layout: Layout = new LinearLayout(this, orientation = Orientation.Vertical) + children :+= bundledBlock(2, "Back") + children :+= bundledBlock(3, "Front") + } + children :+= new Widget { + override protected val layout: Layout = new LinearLayout(this, orientation = Orientation.Vertical) + children :+= bundledBlock(4, "Right") + children :+= bundledBlock(5, "Left") + } + }, Padding2D.equal(8)) + + override def draw(g: Graphics): Unit = { + beginDraw(g) + DrawUtils.windowWithShadow(g, position.x, position.y, size.width, size.height, 1f, 0.5f) + drawChildren(g) + endDraw(g) + } +} diff --git a/src/main/scala/ocelot/desktop/ui/widget/slot/CardSlot.scala b/src/main/scala/ocelot/desktop/ui/widget/slot/CardSlot.scala index 7d81207..caeeb96 100644 --- a/src/main/scala/ocelot/desktop/ui/widget/slot/CardSlot.scala +++ b/src/main/scala/ocelot/desktop/ui/widget/slot/CardSlot.scala @@ -2,7 +2,10 @@ package ocelot.desktop.ui.widget.slot import ocelot.desktop.graphics.IconDef import ocelot.desktop.node.nodes.ComputerNode +import ocelot.desktop.ui.UiHandler +import ocelot.desktop.ui.widget.card.Redstone2Window import ocelot.desktop.ui.widget.contextmenu.{ContextMenu, ContextMenuEntry, ContextMenuSubmenu} +import totoro.ocelot.brain.entity.Redstone import totoro.ocelot.brain.entity.traits.Entity import totoro.ocelot.brain.util.Tier @@ -12,6 +15,16 @@ class CardSlot(node: ComputerNode, val tier: Int) extends InventorySlot[Entity]( override def icon: IconDef = new IconDef("icons/Card") override def tierIcon: Option[IconDef] = Some(new IconDef("icons/Tier" + tier)) + override def fillRmbMenu(menu: ContextMenu): Unit = { + val pool = UiHandler.root.workspaceView.windowPool + item match { + case Some(card: Redstone.Tier2) => + menu.addEntry(new ContextMenuEntry("Open", () => pool.openWindow(new Redstone2Window(card)))) + case _ => + } + super.fillRmbMenu(menu) + } + override def fillLmbMenu(menu: ContextMenu): Unit = { val entries = CardRegistry.entries