diff --git a/sprites/ComputerMotherboard.png b/sprites/ComputerMotherboard.png new file mode 100644 index 0000000..827243f Binary files /dev/null and b/sprites/ComputerMotherboard.png differ diff --git a/sprites/EmptySlot.png b/sprites/EmptySlot.png new file mode 100644 index 0000000..c8e7b04 Binary files /dev/null and b/sprites/EmptySlot.png differ diff --git a/sprites/icons/cpu.png b/sprites/icons/CPU.png similarity index 100% rename from sprites/icons/cpu.png rename to sprites/icons/CPU.png diff --git a/src/main/resources/ocelot/desktop/spritesheet.png b/src/main/resources/ocelot/desktop/spritesheet.png index 4628902..b4c796f 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 b1577b2..ead16c2 100644 --- a/src/main/resources/ocelot/desktop/spritesheet.txt +++ b/src/main/resources/ocelot/desktop/spritesheet.txt @@ -1,96 +1,98 @@ BackgroundPattern 0 0 304 304 -Empty 337 204 1 1 -ShadowBorder 305 204 1 24 -ShadowCorner 424 0 24 24 -buttons/PowerOff 441 25 18 18 -buttons/PowerOn 460 25 18 18 -icons/Card 479 25 16 16 -icons/ComponentBus 424 58 16 16 -icons/EEPROM 441 58 16 16 -icons/Floppy 458 58 16 16 -icons/HDD 475 58 16 16 -icons/Memory 492 58 16 16 -icons/NA 424 75 16 16 -icons/RackMountable 441 75 16 16 -icons/Tier0 458 75 16 16 -icons/Tier1 475 75 16 16 -icons/Tier2 492 75 16 16 -icons/cpu 449 0 16 16 -items/APU0 356 0 16 96 -items/APU1 373 0 16 96 -items/APU2 390 0 16 96 -items/CPU0 466 0 16 16 -items/CPU1 483 0 16 16 -items/CPU2 356 97 16 16 -items/CardBase 373 97 16 16 -items/CircuitBoard 390 97 16 16 -items/ComponentBus0 407 97 16 16 -items/ComponentBus1 424 97 16 16 -items/ComponentBus2 441 97 16 16 -items/ComponentBus3 458 97 16 16 -items/DataCard0 305 0 16 128 -items/DataCard1 322 0 16 128 -items/DataCard2 339 0 16 128 -items/DebugCard 475 97 16 16 -items/DiskDriveMountable 492 97 16 16 -items/EEPROM 305 129 16 16 -items/FloppyDisk_dyeBlack 322 129 16 16 -items/FloppyDisk_dyeBlue 339 129 16 16 -items/FloppyDisk_dyeBrown 356 129 16 16 -items/FloppyDisk_dyeCyan 373 129 16 16 -items/FloppyDisk_dyeGray 390 129 16 16 -items/FloppyDisk_dyeGreen 407 129 16 16 -items/FloppyDisk_dyeLightBlue 424 129 16 16 -items/FloppyDisk_dyeLightGray 441 129 16 16 -items/FloppyDisk_dyeLime 458 129 16 16 -items/FloppyDisk_dyeMagenta 475 129 16 16 -items/FloppyDisk_dyeOrange 492 129 16 16 -items/FloppyDisk_dyePink 305 146 16 16 -items/FloppyDisk_dyePurple 322 146 16 16 -items/FloppyDisk_dyeRed 339 146 16 16 -items/FloppyDisk_dyeWhite 356 146 16 16 -items/FloppyDisk_dyeYellow 373 146 16 16 -items/GraphicsCard0 390 146 16 16 -items/GraphicsCard1 407 146 16 16 -items/GraphicsCard2 424 146 16 16 -items/HardDiskDrive0 441 146 16 16 -items/HardDiskDrive1 458 146 16 16 -items/HardDiskDrive2 475 146 16 16 -items/InternetCard 424 25 16 32 -items/LinkedCard 407 0 16 96 -items/Memory0 492 146 16 16 -items/Memory1 305 163 16 16 -items/Memory2 322 163 16 16 -items/Memory3 339 163 16 16 -items/Memory4 356 163 16 16 -items/Memory5 373 163 16 16 -items/NetworkCard 390 163 16 16 -items/RedstoneCard0 407 163 16 16 -items/RedstoneCard1 424 163 16 16 -items/Server0 441 163 16 16 -items/Server1 458 163 16 16 -items/Server2 475 163 16 16 -items/Server3 492 163 16 16 -items/WirelessNetworkCard0 305 180 16 16 -items/WirelessNetworkCard1 322 180 16 16 -nodes/Computer 339 180 16 16 -nodes/ComputerActivityOverlay 356 180 16 16 -nodes/ComputerErrorOverlay 373 180 16 16 -nodes/ComputerOnOverlay 390 180 16 16 -nodes/NewNode 407 180 16 16 -nodes/Relay 424 180 16 16 -nodes/Screen 441 180 16 16 -nodes/ScreenOnOverlay 458 180 16 16 -screen/BorderB 310 204 2 8 -screen/BorderT 307 204 2 10 -screen/CornerBL 493 180 8 8 -screen/CornerBR 502 180 8 8 -screen/CornerTL 475 180 8 10 -screen/CornerTR 484 180 8 10 -window/BorderDark 333 204 1 4 -window/BorderLight 335 204 1 4 -window/CloseButton 305 197 7 6 -window/CornerBL 313 204 4 4 -window/CornerBR 318 204 4 4 -window/CornerTL 323 204 4 4 -window/CornerTR 328 204 4 4 +ComputerMotherboard 305 0 79 70 +Empty 337 277 1 1 +EmptySlot 441 96 18 18 +ShadowBorder 305 277 1 24 +ShadowCorner 424 71 24 24 +buttons/PowerOff 460 96 18 18 +buttons/PowerOn 479 96 18 18 +icons/CPU 424 129 16 16 +icons/Card 441 129 16 16 +icons/ComponentBus 458 129 16 16 +icons/EEPROM 475 129 16 16 +icons/Floppy 492 129 16 16 +icons/HDD 424 146 16 16 +icons/Memory 441 146 16 16 +icons/NA 458 146 16 16 +icons/RackMountable 475 146 16 16 +icons/Tier0 492 146 16 16 +icons/Tier1 449 71 16 16 +icons/Tier2 466 71 16 16 +items/APU0 356 71 16 96 +items/APU1 373 71 16 96 +items/APU2 390 71 16 96 +items/CPU0 483 71 16 16 +items/CPU1 356 168 16 16 +items/CPU2 373 168 16 16 +items/CardBase 390 168 16 16 +items/CircuitBoard 407 168 16 16 +items/ComponentBus0 424 168 16 16 +items/ComponentBus1 441 168 16 16 +items/ComponentBus2 458 168 16 16 +items/ComponentBus3 475 168 16 16 +items/DataCard0 305 71 16 128 +items/DataCard1 322 71 16 128 +items/DataCard2 339 71 16 128 +items/DebugCard 492 168 16 16 +items/DiskDriveMountable 305 200 16 16 +items/EEPROM 322 200 16 16 +items/FloppyDisk_dyeBlack 339 200 16 16 +items/FloppyDisk_dyeBlue 356 200 16 16 +items/FloppyDisk_dyeBrown 373 200 16 16 +items/FloppyDisk_dyeCyan 390 200 16 16 +items/FloppyDisk_dyeGray 407 200 16 16 +items/FloppyDisk_dyeGreen 424 200 16 16 +items/FloppyDisk_dyeLightBlue 441 200 16 16 +items/FloppyDisk_dyeLightGray 458 200 16 16 +items/FloppyDisk_dyeLime 475 200 16 16 +items/FloppyDisk_dyeMagenta 492 200 16 16 +items/FloppyDisk_dyeOrange 305 217 16 16 +items/FloppyDisk_dyePink 322 217 16 16 +items/FloppyDisk_dyePurple 339 217 16 16 +items/FloppyDisk_dyeRed 356 217 16 16 +items/FloppyDisk_dyeWhite 373 217 16 16 +items/FloppyDisk_dyeYellow 390 217 16 16 +items/GraphicsCard0 407 217 16 16 +items/GraphicsCard1 424 217 16 16 +items/GraphicsCard2 441 217 16 16 +items/HardDiskDrive0 458 217 16 16 +items/HardDiskDrive1 475 217 16 16 +items/HardDiskDrive2 492 217 16 16 +items/InternetCard 424 96 16 32 +items/LinkedCard 407 71 16 96 +items/Memory0 305 234 16 16 +items/Memory1 322 234 16 16 +items/Memory2 339 234 16 16 +items/Memory3 356 234 16 16 +items/Memory4 373 234 16 16 +items/Memory5 390 234 16 16 +items/NetworkCard 407 234 16 16 +items/RedstoneCard0 424 234 16 16 +items/RedstoneCard1 441 234 16 16 +items/Server0 458 234 16 16 +items/Server1 475 234 16 16 +items/Server2 492 234 16 16 +items/Server3 305 251 16 16 +items/WirelessNetworkCard0 322 251 16 16 +items/WirelessNetworkCard1 339 251 16 16 +nodes/Computer 356 251 16 16 +nodes/ComputerActivityOverlay 373 251 16 16 +nodes/ComputerErrorOverlay 390 251 16 16 +nodes/ComputerOnOverlay 407 251 16 16 +nodes/NewNode 424 251 16 16 +nodes/Relay 441 251 16 16 +nodes/Screen 458 251 16 16 +nodes/ScreenOnOverlay 475 251 16 16 +screen/BorderB 310 277 2 8 +screen/BorderT 307 277 2 10 +screen/CornerBL 305 268 8 8 +screen/CornerBR 314 268 8 8 +screen/CornerTL 492 251 8 10 +screen/CornerTR 501 251 8 10 +window/BorderDark 333 277 1 4 +window/BorderLight 335 277 1 4 +window/CloseButton 323 268 7 6 +window/CornerBL 313 277 4 4 +window/CornerBR 318 277 4 4 +window/CornerTL 323 277 4 4 +window/CornerTR 328 277 4 4 diff --git a/src/main/scala/ocelot/desktop/graphics/Graphics.scala b/src/main/scala/ocelot/desktop/graphics/Graphics.scala index dbb80d3..870b3e9 100644 --- a/src/main/scala/ocelot/desktop/graphics/Graphics.scala +++ b/src/main/scala/ocelot/desktop/graphics/Graphics.scala @@ -163,11 +163,7 @@ class Graphics extends Logging { for (c <- text) { char(ox, y, c) - - if (_font.isCharWide(c)) - ox += fontSize - else - ox += fontSize / 2f + ox += _font.charWidth(c) } } @@ -178,7 +174,7 @@ class Graphics extends Logging { val rect = _font.map.getOrElse(c, _font.map('?')) - val width = if (_font.isCharWide(c)) fontSize else fontSize / 2f + val width = _font.charWidth(c) val height = fontSize val uvTransform = Transform2D.translate( @@ -205,6 +201,15 @@ class Graphics extends Logging { z += 2 } + def sprite(name: String, bounds: Rect2D): Unit = { + sprite(name, bounds.origin, bounds.size, RGBAColorNorm(1f, 1f, 1f)) + } + + def sprite(name: String, bounds: Rect2D, color: Color): Unit = { + sprite(name, bounds.origin, bounds.size, color) + } + + def sprite(name: String, pos: Vector2D): Unit = { sprite(name, pos, Spritesheet.spriteSize(name), RGBAColorNorm(1f, 1f, 1f)) } diff --git a/src/main/scala/ocelot/desktop/node/Node.scala b/src/main/scala/ocelot/desktop/node/Node.scala index 4a5d781..b4a3b4b 100644 --- a/src/main/scala/ocelot/desktop/node/Node.scala +++ b/src/main/scala/ocelot/desktop/node/Node.scala @@ -153,8 +153,6 @@ trait Node extends Widget with DragHandler with ClickHandler with HoverHandler { override def minimumSize: Size2D = Size2D(68, 68) - override def maximumSize: Size2D = Size2D(68, 68) - def startMoving(): Unit = { highlight.goto(MovingHighlight) isMoving = true diff --git a/src/main/scala/ocelot/desktop/node/NodeTypeWidget.scala b/src/main/scala/ocelot/desktop/node/NodeTypeWidget.scala index 5e98ad1..e20463a 100644 --- a/src/main/scala/ocelot/desktop/node/NodeTypeWidget.scala +++ b/src/main/scala/ocelot/desktop/node/NodeTypeWidget.scala @@ -10,8 +10,6 @@ import ocelot.desktop.util.TierColor class NodeTypeWidget(val nodeType: NodeType) extends Widget with ClickHandler { override def minimumSize: Size2D = Size2D(68, 68) - override def maximumSize: Size2D = Size2D(68, 68) - size = maximumSize def onClick(): Unit = {} diff --git a/src/main/scala/ocelot/desktop/node/nodes/ComputerWindow.scala b/src/main/scala/ocelot/desktop/node/nodes/ComputerWindow.scala index 7e211f7..65084fd 100644 --- a/src/main/scala/ocelot/desktop/node/nodes/ComputerWindow.scala +++ b/src/main/scala/ocelot/desktop/node/nodes/ComputerWindow.scala @@ -1,30 +1,112 @@ package ocelot.desktop.node.nodes -import ocelot.desktop.geometry.Size2D +import ocelot.desktop.color.{Color, IntColor} +import ocelot.desktop.geometry.{Padding2D, Size2D, Vector2D} import ocelot.desktop.graphics.Graphics -import ocelot.desktop.ui.layout.{AlignItems, JustifyContent, Layout, LinearLayout} -import ocelot.desktop.ui.widget.IconButton +import ocelot.desktop.ui.layout.{Layout, LinearLayout} import ocelot.desktop.ui.widget.window.BasicWindow -import ocelot.desktop.util.DrawUtils +import ocelot.desktop.ui.widget._ +import ocelot.desktop.util.{DrawUtils, Orientation} import totoro.ocelot.brain.entity.Case +import totoro.ocelot.brain.util.Tier class ComputerWindow(computer: Case) extends BasicWindow { - override protected val layout: Layout = new LinearLayout(this, alignItems = AlignItems.Center, - justifyContent = JustifyContent.Center) + private val slots = getSlots - children :+= new IconButton("buttons/PowerOff", "buttons/PowerOn", - isSwitch = true, sizeMultiplier = 2) - { - override def isEnabled: Boolean = isFocused + private val inner = new Widget { + override protected val layout: Layout = new LinearLayout(this, orientation = Orientation.Vertical) - override def onPressed(): Unit = computer.turnOn() + children :+= new PaddingBox(new Label { + override def text: String = computer.node.address + override def isSmall: Boolean = true + override def color: Color = IntColor(0x333333) + }, Padding2D(bottom = 8)) - override def onReleased(): Unit = computer.turnOff() + children :+= new Widget { + children :+= new PaddingBox(new Widget { + children :+= new PaddingBox(new SlotWidget { + override def icon: String = "icons/EEPROM" + }, Padding2D(right = 10)) + + children :+= new IconButton("buttons/PowerOff", "buttons/PowerOn", + isSwitch = true, sizeMultiplier = 2) + { + override def onPressed(): Unit = computer.turnOn() + override def onReleased(): Unit = computer.turnOff() + } + }, Padding2D(top = 44, left = 40)) + + children :+= new Widget { + override protected val layout = new Layout(this) + + for (row <- slots) { + children :+= new Widget { + override protected val layout: Layout = new LinearLayout(this, orientation = Orientation.Vertical) + for (slot <- row) children :+= slot + } + } + + override def minimumSize: Size2D = Size2D(158, 140) + + override def draw(g: Graphics): Unit = { + children(0).position = position + Vector2D(22, 8) + children(1).position = position + Vector2D(66, 8) + children(2).position = position + Vector2D(110, 8) + + g.sprite("ComputerMotherboard", bounds.mapX(_ - 4)) + drawChildren(g) + } + } + } } - override def minimumSize: Size2D = Size2D(100, 100) + children :+= new PaddingBox(inner, Padding2D(10, 12, 10, 12)) - override def maximumSize: Size2D = minimumSize + private def getSlots: Array[Array[SlotWidget]] = { + def cardSlot(tier: Int): SlotWidget = new SlotWidget { + override def icon: String = "icons/Card" + override def tierIcon: String = "icons/Tier" + tier + } + + def cpuSlot(tier: Int): SlotWidget = new SlotWidget { + override def icon: String = "icons/CPU" + override def tierIcon: String = "icons/Tier" + tier + } + + def memorySlot(tier: Int): SlotWidget = new SlotWidget { + override def icon: String = "icons/Memory" + override def tierIcon: String = "icons/Tier" + tier + } + + def diskSlot(tier: Int): SlotWidget = new SlotWidget { + override def icon: String = "icons/HDD" + override def tierIcon: String = "icons/Tier" + tier + } + + def floppySlot: SlotWidget = new SlotWidget { + override def icon: String = "icons/Floppy" + override def tierIcon: String = "icons/Tier0" + } + + computer.tier match { + case Tier.One => Array( + Array(cardSlot(Tier.One), cardSlot(Tier.One)), + Array(cpuSlot(Tier.One), memorySlot(Tier.One), memorySlot(Tier.One)), + Array(diskSlot(Tier.One))) + case Tier.Two => Array( + Array(cardSlot(Tier.Two), cardSlot(Tier.One)), + Array(cpuSlot(Tier.Two), memorySlot(Tier.Two), memorySlot(Tier.Two)), + Array(diskSlot(Tier.Two), diskSlot(Tier.One))) + case Tier.Three => Array( + Array(cardSlot(Tier.Three), cardSlot(Tier.Two), cardSlot(Tier.Two)), + Array(cpuSlot(Tier.Three), memorySlot(Tier.Three), memorySlot(Tier.Three)), + Array(diskSlot(Tier.Three), diskSlot(Tier.Two), floppySlot)) + case _ => Array( + Array(cardSlot(Tier.Three), cardSlot(Tier.Three), cardSlot(Tier.Three)), + Array(cpuSlot(Tier.Three), memorySlot(Tier.Three), memorySlot(Tier.Three)), + Array(diskSlot(Tier.Three), diskSlot(Tier.Three), floppySlot)) + } + } override def draw(g: Graphics): Unit = { DrawUtils.windowWithShadow(g, position.x, position.y, size.width, size.height, backgroundAlpha, shadowAlpha) diff --git a/src/main/scala/ocelot/desktop/node/nodes/ScreenWindow.scala b/src/main/scala/ocelot/desktop/node/nodes/ScreenWindow.scala index 81f822f..02b26e1 100644 --- a/src/main/scala/ocelot/desktop/node/nodes/ScreenWindow.scala +++ b/src/main/scala/ocelot/desktop/node/nodes/ScreenWindow.scala @@ -26,8 +26,6 @@ class ScreenWindow(screen: Screen) extends BasicWindow with Logging { override def minimumSize: Size2D = Size2D(screenWidth * fontWidth + 32, screenHeight * fontHeight + 36) - override def maximumSize: Size2D = minimumSize - eventHandlers += { case event: KeyEvent if isFocused => event.state match { @@ -116,7 +114,7 @@ class ScreenWindow(screen: Screen) extends BasicWindow with Logging { for (y <- 0 until screenHeight) { for (x <- 0 until screenWidth) { - if (x == 0 || !g.font.isCharWide(screen.data.buffer(y)(x - 1))) { + if (x == 0 || g.font.charWidth(screen.data.buffer(y)(x - 1)) != 16) { val char = screen.data.buffer(y)(x) val color = screen.data.color(y)(x) val bg = PackedColor.unpackBackground(color, screen.data.format) diff --git a/src/main/scala/ocelot/desktop/ui/UiHandler.scala b/src/main/scala/ocelot/desktop/ui/UiHandler.scala index efc49d7..16d4516 100644 --- a/src/main/scala/ocelot/desktop/ui/UiHandler.scala +++ b/src/main/scala/ocelot/desktop/ui/UiHandler.scala @@ -12,7 +12,7 @@ import ocelot.desktop.ui.event.MouseEvent import ocelot.desktop.ui.event.handlers.HoverHandler import ocelot.desktop.ui.event.sources.{KeyEvents, MouseEvents, ScrollEvents} import ocelot.desktop.ui.widget.Widget -import ocelot.desktop.util.{Audio, FPSCalculator, Logging, Spritesheet} +import ocelot.desktop.util._ import org.apache.commons.io.FileUtils import org.apache.commons.lang3.SystemUtils import org.lwjgl.input.Mouse @@ -242,16 +242,13 @@ object UiHandler extends Logging { graphics.clear() root.draw(graphics) - // for ((widget, i) <- hierarchy.reverseIterator.zipWithIndex) - // if (widget != null) { - // val b = widget.clippedBounds - // if (b.w > 1f && b.h > 1f) { - // DrawUtils.ring(graphics, b.x, b.y, b.w, b.h, 1, RGBAColor(255, 0, 0)) - // graphics.setSmallFont() - // graphics.background = RGBAColor(0, 0, 0, 0) - // graphics.text(b.x, b.y + b.h - 9, i.toString) - // } - // } + // for ((widget, i) <- hierarchy.reverseIterator.zipWithIndex) + // if (widget != null) { + // val b = widget.clippedBounds + // if (b.w > 1f && b.h > 1f) { + // DrawUtils.ring(graphics, b.x, b.y, b.w, b.h, 1, RGBAColor(255, 0, 0)) + // } + // } graphics.commit() } diff --git a/src/main/scala/ocelot/desktop/ui/widget/IconButton.scala b/src/main/scala/ocelot/desktop/ui/widget/IconButton.scala index 2dcf567..ce8c820 100644 --- a/src/main/scala/ocelot/desktop/ui/widget/IconButton.scala +++ b/src/main/scala/ocelot/desktop/ui/widget/IconButton.scala @@ -1,9 +1,9 @@ package ocelot.desktop.ui.widget import ocelot.desktop.color.Color -import ocelot.desktop.geometry.{Size2D, Vector2D} +import ocelot.desktop.geometry.Size2D import ocelot.desktop.graphics.Graphics -import ocelot.desktop.ui.event.{ClickEvent, MouseEvent} import ocelot.desktop.ui.event.handlers.ClickHandler +import ocelot.desktop.ui.event.{ClickEvent, MouseEvent} import ocelot.desktop.util.Spritesheet import ocelot.desktop.util.animation.{ColorAnimation, ValueAnimation} @@ -29,8 +29,6 @@ class IconButton(releasedIcon: String, pressedIcon: String, if (!isSwitch || !isOn) released() else pressed() } - def isEnabled: Boolean = true - def onPressed(): Unit = {} def onReleased(): Unit = {} @@ -57,8 +55,6 @@ class IconButton(releasedIcon: String, pressedIcon: String, override def minimumSize: Size2D = releasedIconSize.max(pressedIconSize) - override def maximumSize: Size2D = minimumSize - override def draw(g: Graphics): Unit = { if (alphaAnimation.value < 1f) g.sprite(releasedIcon, position + (size - releasedIconSize) / 2f, releasedIconSize, diff --git a/src/main/scala/ocelot/desktop/ui/widget/Label.scala b/src/main/scala/ocelot/desktop/ui/widget/Label.scala new file mode 100644 index 0000000..0e38a5b --- /dev/null +++ b/src/main/scala/ocelot/desktop/ui/widget/Label.scala @@ -0,0 +1,33 @@ +package ocelot.desktop.ui.widget + +import ocelot.desktop.color.{Color, IntColor} +import ocelot.desktop.geometry.Size2D +import ocelot.desktop.graphics.Graphics + +class Label extends Widget { + def text: String = "" + + def isSmall: Boolean = false + + def color: Color = IntColor(0x333333) + + private var length = text.length * 8 + private def wideLength(g: Graphics): Int = text.map(g.font.charWidth(_)).sum + + override def minimumSize: Size2D = Size2D(length, 8) + + override def draw(g: Graphics): Unit = { + if (isSmall) g.setSmallFont() + + if (length < wideLength(g)) { + length = wideLength(g) + relayoutParent() + } + + g.background = Color.Transparent + g.foreground = color + g.text(position.x, position.y, text) + + g.setNormalFont() + } +} diff --git a/src/main/scala/ocelot/desktop/ui/widget/ScrollView.scala b/src/main/scala/ocelot/desktop/ui/widget/ScrollView.scala index 24eb6db..8a6943d 100644 --- a/src/main/scala/ocelot/desktop/ui/widget/ScrollView.scala +++ b/src/main/scala/ocelot/desktop/ui/widget/ScrollView.scala @@ -57,8 +57,6 @@ class ScrollView(val inner: Widget) extends Widget with Logging with HoverHandle override def minimumSize: Size2D = Size2D.Zero - override def maximumSize: Size2D = inner.maximumSize - override def size_=(value: Size2D): Unit = { super.size_=(value) clampOffsets() diff --git a/src/main/scala/ocelot/desktop/ui/widget/SlotWidget.scala b/src/main/scala/ocelot/desktop/ui/widget/SlotWidget.scala new file mode 100644 index 0000000..aca0af0 --- /dev/null +++ b/src/main/scala/ocelot/desktop/ui/widget/SlotWidget.scala @@ -0,0 +1,18 @@ +package ocelot.desktop.ui.widget +import ocelot.desktop.geometry.Size2D +import ocelot.desktop.graphics.Graphics + +class SlotWidget extends Widget { + def icon: String = "Empty" + + def tierIcon: String = null + + override def minimumSize: Size2D = Size2D(36, 36) + + override def draw(g: Graphics): Unit = { + g.sprite("EmptySlot", bounds) + if (tierIcon != null) + g.sprite(tierIcon, bounds.inflate(-2)) + g.sprite(icon, bounds.inflate(-2)) + } +} diff --git a/src/main/scala/ocelot/desktop/ui/widget/Widget.scala b/src/main/scala/ocelot/desktop/ui/widget/Widget.scala index 9b754af..3615c16 100644 --- a/src/main/scala/ocelot/desktop/ui/widget/Widget.scala +++ b/src/main/scala/ocelot/desktop/ui/widget/Widget.scala @@ -45,7 +45,7 @@ class Widget { def minimumSize: Size2D = layout.minimumSize - def maximumSize: Size2D = layout.maximumSize + def maximumSize: Size2D = layout.maximumSize.max(minimumSize) def position: Vector2D = _position diff --git a/src/main/scala/ocelot/desktop/util/Font.scala b/src/main/scala/ocelot/desktop/util/Font.scala index cac5aa3..47b66a2 100644 --- a/src/main/scala/ocelot/desktop/util/Font.scala +++ b/src/main/scala/ocelot/desktop/util/Font.scala @@ -27,7 +27,7 @@ class Font(val name: String, val fontSize: Int) extends Logging { init() - def isCharWide(char: Char): Boolean = map.get(char).exists(rect => rect.w == rect.h) + def charWidth(char: Char): Int = (map.getOrElse(char, map('?')).w * AtlasWidth).toInt private def init(): Unit = { logger.info(f"Loading font $name")