mirror of
https://gitlab.com/cc-ru/ocelot/ocelot-desktop.git
synced 2025-12-20 02:59:19 +01:00
208 lines
7.3 KiB
Scala
208 lines
7.3 KiB
Scala
package ocelot.desktop.windows
|
|
|
|
import ocelot.desktop.audio.{SoundSource, SoundSources}
|
|
import ocelot.desktop.color.Color
|
|
import ocelot.desktop.geometry.{Padding2D, Size2D}
|
|
import ocelot.desktop.graphics.Graphics
|
|
import ocelot.desktop.node.nodes.ComputerNode
|
|
import ocelot.desktop.ui.layout.{Layout, LinearLayout}
|
|
import ocelot.desktop.ui.widget._
|
|
import ocelot.desktop.ui.widget.tooltip.Tooltip
|
|
import ocelot.desktop.ui.widget.window.BasicWindow
|
|
import ocelot.desktop.util.animation.UnitAnimation
|
|
import ocelot.desktop.util.{DrawUtils, Orientation}
|
|
import ocelot.desktop.{ColorScheme, OcelotDesktop}
|
|
import totoro.ocelot.brain.entity.Case
|
|
import totoro.ocelot.brain.nbt.NBTTagCompound
|
|
|
|
class ComputerWindow(computerNode: ComputerNode) extends BasicWindow {
|
|
def computer: Case = computerNode.computer
|
|
|
|
def updateSlots(): Unit = {
|
|
eepromBox.children(0) = computerNode.eepromSlot
|
|
inner.children(1).children(2) = slotsWidget
|
|
}
|
|
|
|
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)
|
|
|
|
class PerTickHistogram extends Histogram {
|
|
private var lastTick = OcelotDesktop.ticker.tick
|
|
|
|
def tickUpdate(): Unit = {}
|
|
|
|
def reset(): Unit = {
|
|
text = "N/A"
|
|
history = Seq.fill(21)(0.0f).toArray
|
|
}
|
|
|
|
override def update(): Unit = {
|
|
super.update()
|
|
val curTick = OcelotDesktop.ticker.tick
|
|
if (curTick > lastTick) {
|
|
if (!computer.machine.isRunning) reset()
|
|
lastTick = curTick
|
|
tickUpdate()
|
|
}
|
|
}
|
|
}
|
|
|
|
children :+= new PerTickHistogram {
|
|
override def tickUpdate(): Unit = {
|
|
val (free, total) = computer.machine.latestMemoryUsage
|
|
val used = total - free
|
|
|
|
val ratio = if (total == 0) 0 else used.toFloat / total.toFloat
|
|
|
|
text = f"${used.toFloat / 1024f / 1024f}%.1fM"
|
|
history = history.slice(1, history.length) ++ Array(ratio)
|
|
}
|
|
override protected val tooltip: Option[Tooltip] = Some(
|
|
new LabelTooltip("Memory usage (in Mb)")
|
|
)
|
|
}
|
|
|
|
children :+= new PaddingBox(new PerTickHistogram {
|
|
override def tickUpdate(): Unit = {
|
|
val (start, _end) = computer.machine.latestExecutionInfo
|
|
val end = if (start < _end) _end else System.nanoTime()
|
|
val cpuUsage = if (start == 0) 0 else ((end - start).toFloat / 1000000000f * OcelotDesktop.tpsCounter.fps).min(1f)
|
|
text = f"${cpuUsage * 100}%.0f%%"
|
|
history = history.slice(1, history.length) ++ Array(cpuUsage)
|
|
}
|
|
override protected val tooltip: Option[Tooltip] = Some(
|
|
new LabelTooltip("CPU usage (in %)")
|
|
)
|
|
}, Padding2D(top = 8))
|
|
|
|
children :+= new PaddingBox(new PerTickHistogram {
|
|
override def tickUpdate(): Unit = {
|
|
val (budget, maxBudget) = computer.machine.latestCallBudget
|
|
text = f"${maxBudget - budget}%.1f"
|
|
history = history.slice(1, history.length) ++ Array((1.0 - budget / maxBudget).toFloat)
|
|
}
|
|
override protected val tooltip: Option[Tooltip] = Some(
|
|
new LabelTooltip("CPU usage (call budget)")
|
|
)
|
|
}, Padding2D(top = 8))
|
|
}, 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 drawerButton = new IconButton(
|
|
"buttons/BottomDrawerOpen", "buttons/BottomDrawerClose",
|
|
isSwitch = true, tooltip = Some("Toggle computer usage histogram")
|
|
) {
|
|
override def onPressed(): Unit = bottomDrawerAnimation.goUp()
|
|
override def onReleased(): Unit = bottomDrawerAnimation.goDown()
|
|
}
|
|
|
|
private val inner = new Widget {
|
|
override protected val layout: Layout = new LinearLayout(this, orientation = Orientation.Vertical)
|
|
|
|
children :+= new PaddingBox(new Label {
|
|
override def text: String = computerNode.labelOrAddress.take(36)
|
|
override def isSmall: Boolean = true
|
|
override def color: Color = ColorScheme("ComputerAddress")
|
|
}, Padding2D(bottom = 8))
|
|
|
|
children :+= new Widget {
|
|
children :+= new PaddingBox(drawerButton, Padding2D(top = 120))
|
|
|
|
children :+= new PaddingBox(new Widget {
|
|
children :+= new PaddingBox(computerNode.eepromSlot, Padding2D(right = 10))
|
|
|
|
children :+= new IconButton(
|
|
"buttons/PowerOff",
|
|
"buttons/PowerOn",
|
|
isSwitch = true,
|
|
sizeMultiplier = 2
|
|
) {
|
|
override def isOn: Boolean = computer.machine.isRunning
|
|
override def onPressed(): Unit = computerNode.turnOn()
|
|
override def onReleased(): Unit = computerNode.turnOff()
|
|
protected override def clickSoundSource: SoundSource = SoundSources.MinecraftClick
|
|
}
|
|
}, Padding2D(top = 44, left = 22))
|
|
|
|
children :+= slotsWidget
|
|
}
|
|
}
|
|
|
|
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 = {
|
|
val rows = Array(
|
|
(19, computerNode.cardSlots),
|
|
(8, Array(computerNode.cpuSlot) ++ computerNode.memorySlots),
|
|
(8, computerNode.diskSlots ++ computerNode.floppySlot.toArray)
|
|
)
|
|
|
|
new Widget {
|
|
for ((padding, row) <- rows) {
|
|
children :+= new PaddingBox(new Widget {
|
|
override protected val layout: Layout = new LinearLayout(this, orientation = Orientation.Vertical)
|
|
for (slot <- row) children :+= slot
|
|
}, Padding2D(left = padding, top = 8))
|
|
}
|
|
|
|
override def minimumSize: Size2D = Size2D(158, 140)
|
|
|
|
override def draw(g: Graphics): Unit = {
|
|
g.sprite("ComputerMotherboard", bounds.mapX(_ - 4).mapW(_ - 4))
|
|
drawChildren(g)
|
|
}
|
|
}
|
|
}
|
|
|
|
override def update(): Unit = {
|
|
super.update()
|
|
bottomDrawerAnimation.update()
|
|
height = minimumSize.height + (bottomDrawerAnimation.value * bottomDrawer.maximumSize.height).round
|
|
}
|
|
|
|
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)
|
|
}
|
|
|
|
override def save(nbt: NBTTagCompound): Unit = {
|
|
super.save(nbt)
|
|
bottomDrawerAnimation.save(nbt, "drawerAnimation")
|
|
}
|
|
|
|
override def load(nbt: NBTTagCompound): Unit = {
|
|
bottomDrawerAnimation.load(nbt, "drawerAnimation")
|
|
if (bottomDrawerAnimation.isGoingUp) drawerButton.playPressAnimation()
|
|
super.load(nbt)
|
|
}
|
|
}
|