Add memory histogram
@ -1 +1 @@
|
|||||||
Subproject commit ac7c7aa8eed4623310d08fbcb7dc95b3e12f125d
|
Subproject commit 5a7def9f0d79216aa71694d9ebb60f29df63d591
|
||||||
BIN
sprites/BarSegment.png
Normal file
|
After Width: | Height: | Size: 527 B |
BIN
sprites/buttons/BottomDrawerClose.png
Normal file
|
After Width: | Height: | Size: 606 B |
BIN
sprites/buttons/BottomDrawerOpen.png
Normal file
|
After Width: | Height: | Size: 601 B |
BIN
sprites/panel/BorderB.png
Normal file
|
After Width: | Height: | Size: 487 B |
BIN
sprites/panel/BorderL.png
Normal file
|
After Width: | Height: | Size: 488 B |
BIN
sprites/panel/BorderR.png
Normal file
|
After Width: | Height: | Size: 491 B |
BIN
sprites/panel/BorderT.png
Normal file
|
After Width: | Height: | Size: 488 B |
BIN
sprites/panel/CornerBL.png
Normal file
|
After Width: | Height: | Size: 504 B |
BIN
sprites/panel/CornerBR.png
Normal file
|
After Width: | Height: | Size: 497 B |
BIN
sprites/panel/CornerTL.png
Normal file
|
After Width: | Height: | Size: 492 B |
BIN
sprites/panel/CornerTR.png
Normal file
|
After Width: | Height: | Size: 503 B |
BIN
sprites/panel/Fill.png
Normal file
|
After Width: | Height: | Size: 480 B |
@ -61,3 +61,12 @@ TextInputBorderErrorFocused = #cc6666
|
|||||||
ButtonBackground = #aaaaaa
|
ButtonBackground = #aaaaaa
|
||||||
ButtonBorder = #888888
|
ButtonBorder = #888888
|
||||||
ButtonForeground = #333333
|
ButtonForeground = #333333
|
||||||
|
|
||||||
|
BottomDrawerBorder = #888888
|
||||||
|
|
||||||
|
HistogramBarEmpty = #336633
|
||||||
|
HistogramBarTop = #ccfdcc
|
||||||
|
HistogramBarFill = #64cc65
|
||||||
|
HistogramGrid = #336633
|
||||||
|
HistogramFill = #73ff7360
|
||||||
|
HistogramEdge = #ccfdcc
|
||||||
|
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 62 KiB |
@ -1,21 +1,24 @@
|
|||||||
BackgroundPattern 0 0 304 304
|
BackgroundPattern 0 0 304 304
|
||||||
|
BarSegment 415 105 16 4
|
||||||
ComputerMotherboard 305 0 79 70
|
ComputerMotherboard 305 0 79 70
|
||||||
Empty 498 11 1 1
|
Empty 497 21 1 1
|
||||||
EmptySlot 441 147 18 18
|
EmptySlot 441 147 18 18
|
||||||
Knob 385 0 50 50
|
Knob 385 0 50 50
|
||||||
KnobCenter 436 0 50 50
|
KnobCenter 436 0 50 50
|
||||||
KnobLimits 305 71 50 50
|
KnobLimits 305 71 50 50
|
||||||
ShadowBorder 487 0 1 24
|
ShadowBorder 487 0 1 24
|
||||||
ShadowCorner 424 122 24 24
|
ShadowCorner 424 122 24 24
|
||||||
buttons/PowerOff 460 147 18 18
|
buttons/BottomDrawerClose 460 147 18 18
|
||||||
buttons/PowerOn 479 147 18 18
|
buttons/BottomDrawerOpen 479 147 18 18
|
||||||
icons/CPU 424 195 16 16
|
buttons/PowerOff 424 180 18 18
|
||||||
icons/Card 441 195 16 16
|
buttons/PowerOn 443 180 18 18
|
||||||
icons/ComponentBus 458 195 16 16
|
icons/CPU 424 199 16 16
|
||||||
icons/DragLMB 424 180 21 14
|
icons/Card 441 199 16 16
|
||||||
icons/DragRMB 446 180 21 14
|
icons/ComponentBus 458 199 16 16
|
||||||
icons/EEPROM 475 195 16 16
|
icons/DragLMB 462 180 21 14
|
||||||
icons/Floppy 492 195 16 16
|
icons/DragRMB 484 180 21 14
|
||||||
|
icons/EEPROM 475 199 16 16
|
||||||
|
icons/Floppy 492 199 16 16
|
||||||
icons/HDD 449 122 16 16
|
icons/HDD 449 122 16 16
|
||||||
icons/LMB 373 105 11 14
|
icons/LMB 373 105 11 14
|
||||||
icons/Memory 466 122 16 16
|
icons/Memory 466 122 16 16
|
||||||
@ -82,7 +85,7 @@ items/Server2 424 71 16 16
|
|||||||
items/Server3 441 71 16 16
|
items/Server3 441 71 16 16
|
||||||
items/WirelessNetworkCard0 458 71 16 16
|
items/WirelessNetworkCard0 458 71 16 16
|
||||||
items/WirelessNetworkCard1 475 71 16 16
|
items/WirelessNetworkCard1 475 71 16 16
|
||||||
nodes/Cable 415 105 8 8
|
nodes/Cable 356 236 8 8
|
||||||
nodes/Computer 492 71 16 16
|
nodes/Computer 492 71 16 16
|
||||||
nodes/ComputerActivityOverlay 356 88 16 16
|
nodes/ComputerActivityOverlay 356 88 16 16
|
||||||
nodes/ComputerErrorOverlay 373 88 16 16
|
nodes/ComputerErrorOverlay 373 88 16 16
|
||||||
@ -94,16 +97,25 @@ nodes/NewNode 458 88 16 16
|
|||||||
nodes/Relay 475 88 16 16
|
nodes/Relay 475 88 16 16
|
||||||
nodes/Screen 492 88 16 16
|
nodes/Screen 492 88 16 16
|
||||||
nodes/ScreenOnOverlay 356 105 16 16
|
nodes/ScreenOnOverlay 356 105 16 16
|
||||||
|
panel/BorderB 495 0 4 4
|
||||||
|
panel/BorderL 489 21 4 2
|
||||||
|
panel/BorderR 500 0 4 4
|
||||||
|
panel/BorderT 505 0 4 4
|
||||||
|
panel/CornerBL 489 11 4 4
|
||||||
|
panel/CornerBR 494 11 4 4
|
||||||
|
panel/CornerTL 499 11 4 4
|
||||||
|
panel/CornerTR 504 11 4 4
|
||||||
|
panel/Fill 494 21 2 2
|
||||||
screen/BorderB 492 0 2 8
|
screen/BorderB 492 0 2 8
|
||||||
screen/BorderT 489 0 2 10
|
screen/BorderT 489 0 2 10
|
||||||
screen/CornerBL 424 105 8 8
|
screen/CornerBL 365 236 8 8
|
||||||
screen/CornerBR 433 105 8 8
|
screen/CornerBR 374 236 8 8
|
||||||
screen/CornerTL 397 105 8 10
|
screen/CornerTL 397 105 8 10
|
||||||
screen/CornerTR 406 105 8 10
|
screen/CornerTR 406 105 8 10
|
||||||
window/BorderDark 494 11 1 4
|
window/BorderDark 509 16 1 4
|
||||||
window/BorderLight 496 11 1 4
|
window/BorderLight 509 11 1 4
|
||||||
window/CloseButton 442 105 7 6
|
window/CloseButton 383 236 7 6
|
||||||
window/CornerBL 495 0 4 4
|
window/CornerBL 489 16 4 4
|
||||||
window/CornerBR 500 0 4 4
|
window/CornerBR 494 16 4 4
|
||||||
window/CornerTL 505 0 4 4
|
window/CornerTL 499 16 4 4
|
||||||
window/CornerTR 489 11 4 4
|
window/CornerTR 504 16 4 4
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import ocelot.desktop.graphics.Graphics
|
|||||||
import ocelot.desktop.ui.layout.{Layout, LinearLayout}
|
import ocelot.desktop.ui.layout.{Layout, LinearLayout}
|
||||||
import ocelot.desktop.ui.widget._
|
import ocelot.desktop.ui.widget._
|
||||||
import ocelot.desktop.ui.widget.window.BasicWindow
|
import ocelot.desktop.ui.widget.window.BasicWindow
|
||||||
|
import ocelot.desktop.util.animation.UnitAnimation
|
||||||
import ocelot.desktop.util.{DrawUtils, Orientation}
|
import ocelot.desktop.util.{DrawUtils, Orientation}
|
||||||
import totoro.ocelot.brain.entity.Case
|
import totoro.ocelot.brain.entity.Case
|
||||||
|
|
||||||
@ -19,6 +20,57 @@ class ComputerWindow(computerNode: ComputerNode) extends BasicWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val eepromBox = new PaddingBox(computerNode.eepromSlot, Padding2D(right = 10))
|
private val eepromBox = new PaddingBox(computerNode.eepromSlot, Padding2D(right = 10))
|
||||||
|
private val bottomDrawerAnimation = UnitAnimation.easeInOutQuad(0.2f)
|
||||||
|
bottomDrawerAnimation.goDown()
|
||||||
|
|
||||||
|
private val bottomDrawer = new Widget {
|
||||||
|
override def shouldClip: Boolean = true
|
||||||
|
override def minimumSize: Size2D = Size2D(layout.minimumSize.width, 0)
|
||||||
|
|
||||||
|
children :+= new PaddingBox(new Widget {
|
||||||
|
children :+= new PaddingBox(new Widget {
|
||||||
|
override protected val layout: Layout = new LinearLayout(this, orientation = Orientation.Vertical)
|
||||||
|
|
||||||
|
children :+= new Histogram {
|
||||||
|
private var oldTime = computer.machine.worldTime
|
||||||
|
|
||||||
|
override def update(): Unit = {
|
||||||
|
super.update()
|
||||||
|
if (!computer.machine.isRunning) {
|
||||||
|
text = f"N/A"
|
||||||
|
history = Seq.fill(21)(0.0f).toArray
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val newTime = computer.machine.worldTime
|
||||||
|
|
||||||
|
if (newTime > oldTime) {
|
||||||
|
oldTime = newTime
|
||||||
|
|
||||||
|
val arch = computer.machine.architecture
|
||||||
|
val usedMemory = arch.totalMemory - arch.freeMemory
|
||||||
|
val memoryRatio = usedMemory.toFloat / arch.totalMemory.toFloat
|
||||||
|
|
||||||
|
text = f"${usedMemory.toFloat / 1024f / 1024f}%.1fM"
|
||||||
|
history = history.slice(1, history.length) ++ Array(memoryRatio)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, Padding2D.equal(7))
|
||||||
|
|
||||||
|
override def draw(g: Graphics): Unit = {
|
||||||
|
DrawUtils.panel(g, position.x, position.y, width, height)
|
||||||
|
super.draw(g)
|
||||||
|
}
|
||||||
|
}, Padding2D(10, 12, 0, 12))
|
||||||
|
|
||||||
|
override def draw(g: Graphics): Unit = {
|
||||||
|
if (height < 1) return
|
||||||
|
|
||||||
|
super.draw(g)
|
||||||
|
g.rect(position.x + 6, position.y + 2, width - 12, 2, ColorScheme("BottomDrawerBorder"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private val inner = new Widget {
|
private val inner = new Widget {
|
||||||
override protected val layout: Layout = new LinearLayout(this, orientation = Orientation.Vertical)
|
override protected val layout: Layout = new LinearLayout(this, orientation = Orientation.Vertical)
|
||||||
@ -30,6 +82,11 @@ class ComputerWindow(computerNode: ComputerNode) extends BasicWindow {
|
|||||||
}, Padding2D(bottom = 8))
|
}, Padding2D(bottom = 8))
|
||||||
|
|
||||||
children :+= new Widget {
|
children :+= new Widget {
|
||||||
|
children :+= new PaddingBox(new IconButton("buttons/BottomDrawerOpen", "buttons/BottomDrawerClose", isSwitch = true) {
|
||||||
|
override def onPressed(): Unit = bottomDrawerAnimation.goUp()
|
||||||
|
override def onReleased(): Unit = bottomDrawerAnimation.goDown()
|
||||||
|
}, Padding2D(top = 120))
|
||||||
|
|
||||||
children :+= new PaddingBox(new Widget {
|
children :+= new PaddingBox(new Widget {
|
||||||
children :+= new PaddingBox(computerNode.eepromSlot, Padding2D(right = 10))
|
children :+= new PaddingBox(computerNode.eepromSlot, Padding2D(right = 10))
|
||||||
|
|
||||||
@ -40,13 +97,18 @@ class ComputerWindow(computerNode: ComputerNode) extends BasicWindow {
|
|||||||
override def onPressed(): Unit = computer.turnOn()
|
override def onPressed(): Unit = computer.turnOn()
|
||||||
override def onReleased(): Unit = computer.turnOff()
|
override def onReleased(): Unit = computer.turnOff()
|
||||||
}
|
}
|
||||||
}, Padding2D(top = 44, left = 40))
|
}, Padding2D(top = 44, left = 22))
|
||||||
|
|
||||||
children :+= slotsWidget
|
children :+= slotsWidget
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
children :+= new PaddingBox(inner, Padding2D(10, 12, 10, 12))
|
children :+= new PaddingBox(new Widget {
|
||||||
|
override protected val layout: Layout = new LinearLayout(this, orientation = Orientation.Vertical)
|
||||||
|
|
||||||
|
children :+= new PaddingBox(inner, Padding2D(10, 12, 0, 12))
|
||||||
|
children :+= bottomDrawer
|
||||||
|
}, Padding2D(bottom = 10))
|
||||||
|
|
||||||
private def slotsWidget: Widget = {
|
private def slotsWidget: Widget = {
|
||||||
val rows = Array(
|
val rows = Array(
|
||||||
@ -72,6 +134,12 @@ class ComputerWindow(computerNode: ComputerNode) extends BasicWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override def update(): Unit = {
|
||||||
|
super.update()
|
||||||
|
bottomDrawerAnimation.update()
|
||||||
|
height = minimumSize.height + (bottomDrawerAnimation.value * bottomDrawer.maximumSize.height).round
|
||||||
|
}
|
||||||
|
|
||||||
override def draw(g: Graphics): Unit = {
|
override def draw(g: Graphics): Unit = {
|
||||||
beginDraw(g)
|
beginDraw(g)
|
||||||
DrawUtils.windowWithShadow(g, position.x, position.y, size.width, size.height, 1f, 0.5f)
|
DrawUtils.windowWithShadow(g, position.x, position.y, size.width, size.height, 1f, 0.5f)
|
||||||
|
|||||||
60
src/main/scala/ocelot/desktop/ui/widget/Histogram.scala
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
package ocelot.desktop.ui.widget
|
||||||
|
import ocelot.desktop.ColorScheme
|
||||||
|
import ocelot.desktop.color.Color
|
||||||
|
import ocelot.desktop.geometry.Size2D
|
||||||
|
import ocelot.desktop.graphics.Graphics
|
||||||
|
|
||||||
|
class Histogram extends Widget {
|
||||||
|
override def minimumSize: Size2D = Size2D(274, 70)
|
||||||
|
override def maximumSize: Size2D = minimumSize
|
||||||
|
|
||||||
|
var text = "N/A"
|
||||||
|
var history: Array[Float] = Seq.fill(21)(0.0f).toArray
|
||||||
|
|
||||||
|
private def drawBars(g: Graphics): Unit = {
|
||||||
|
def drawBarSegment(i: Int, color: Color): Unit = {
|
||||||
|
g.sprite("BarSegment", position.x, position.y + i * 6, 16, 4, color)
|
||||||
|
g.sprite("BarSegment", position.x + 18, position.y + i * 6, 16, 4, color)
|
||||||
|
}
|
||||||
|
|
||||||
|
val ratio = history.last
|
||||||
|
val fillBars = (ratio * 10).round
|
||||||
|
val emptyBars = 9 - fillBars
|
||||||
|
|
||||||
|
for (i <- 0 until emptyBars) {
|
||||||
|
drawBarSegment(i, ColorScheme("HistogramBarEmpty"))
|
||||||
|
}
|
||||||
|
for (i <- emptyBars + 1 until 10) {
|
||||||
|
drawBarSegment(i, ColorScheme("HistogramBarFill"))
|
||||||
|
}
|
||||||
|
drawBarSegment(emptyBars, ColorScheme("HistogramBarTop"))
|
||||||
|
}
|
||||||
|
|
||||||
|
private def drawText(g: Graphics): Unit = {
|
||||||
|
g.setSmallFont()
|
||||||
|
g.text(position.x + 17 - text.length * 4, position.y + 62, text)
|
||||||
|
g.setNormalFont()
|
||||||
|
}
|
||||||
|
|
||||||
|
private def drawHistogram(g: Graphics): Unit = {
|
||||||
|
for (i <- 0 until 22) {
|
||||||
|
g.rect(position.x + 41 + i * 11, position.y, 2, 57, ColorScheme("HistogramGrid"))
|
||||||
|
}
|
||||||
|
for (i <- 0 until 6) {
|
||||||
|
g.rect(position.x + 41, position.y + i * 11, 233, 2, ColorScheme("HistogramGrid"))
|
||||||
|
}
|
||||||
|
|
||||||
|
for ((entry, i) <- history.zipWithIndex) {
|
||||||
|
val width = if (i == 20) 13 else 11
|
||||||
|
val height = (entry * 57).max(2)
|
||||||
|
g.rect(position.x + 41 + i * 11, position.y + 57 - height, width, 2, ColorScheme("HistogramEdge"))
|
||||||
|
g.rect(position.x + 41 + i * 11, position.y + 59 - height, width, height - 2, ColorScheme("HistogramFill"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override def draw(g: Graphics): Unit = {
|
||||||
|
drawBars(g)
|
||||||
|
drawText(g)
|
||||||
|
drawHistogram(g)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -29,6 +29,20 @@ object DrawUtils {
|
|||||||
g.restore()
|
g.restore()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def panel(g: Graphics, x: Float, y: Float, w: Float, h: Float): Unit = {
|
||||||
|
g.sprite("panel/CornerTL", x, y, 4, 4)
|
||||||
|
g.sprite("panel/CornerTR", x + w - 4, y, 4, 4)
|
||||||
|
g.sprite("panel/CornerBL", x, y + h - 4, 4, 4)
|
||||||
|
g.sprite("panel/CornerBR", x + w - 4, y + h - 4, 4, 4)
|
||||||
|
|
||||||
|
g.sprite("panel/BorderT", x + 4, y, w - 8, 4)
|
||||||
|
g.sprite("panel/BorderB", x + 4, y + h - 4, w - 8, 4)
|
||||||
|
g.sprite("panel/BorderL", x, y + 4, 4, h - 8)
|
||||||
|
g.sprite("panel/BorderR", x + w - 4, y + 4, 4, h - 8)
|
||||||
|
|
||||||
|
g.sprite("panel/Fill", x + 4, y + 4, w - 8, h - 8)
|
||||||
|
}
|
||||||
|
|
||||||
def isValidPolyline(points: Array[Vector2D]): Boolean = {
|
def isValidPolyline(points: Array[Vector2D]): Boolean = {
|
||||||
if (points.length < 3) return true
|
if (points.length < 3) return true
|
||||||
var start = points(0)
|
var start = points(0)
|
||||||
|
|||||||