Fingercomp ce2eeaec0a
Require IconSource in all Graphics.sprite overloads
Well, almost. The smoke animation is too weird.
2025-08-17 16:00:50 +03:00

85 lines
2.4 KiB
Scala

package ocelot.desktop.node.nodes
import ocelot.desktop.color.RGBAColorNorm
import ocelot.desktop.entity.OcelotBlock
import ocelot.desktop.entity.traits.OcelotInterface
import ocelot.desktop.geometry.FloatUtils.ExtendedFloat
import ocelot.desktop.graphics.{Graphics, IconSource}
import ocelot.desktop.node.Node.HighlightThickness
import ocelot.desktop.node.nodes.OcelotBlockNode.ActivityFadeOutMs
import ocelot.desktop.node.{EntityNode, LabeledEntityNode, OcelotLogParticleNode, WindowedNode}
import ocelot.desktop.ui.widget.LogWidget
import ocelot.desktop.ui.widget.LogWidget.LogEntry
import ocelot.desktop.util.OcelotInterfaceLogStorage
import ocelot.desktop.windows.OcelotInterfaceWindow
class OcelotBlockNode(val ocelot: OcelotBlock)
extends EntityNode(ocelot)
with LabeledEntityNode
with OcelotLogParticleNode
with OcelotInterfaceLogStorage
with WindowedNode[OcelotInterfaceWindow] {
override def name: String = "Ocelot Block"
override def iconSource: IconSource = IconSource.Nodes.OcelotBlock.Default
override def rotatable: Boolean = false
override def ocelotInterface: OcelotInterface = ocelot
private var lastRx: Long = -1L
private var lastTx: Long = -1L
override protected def onMessagesAdded(entries: => Iterable[LogWidget.LogEntry]): Unit = {
super.onMessagesAdded(entries)
var hasRx = false
var hasTx = false
for (entry <- entries.iterator.takeWhile(_ => !hasRx || !hasTx)) {
entry match {
case _: LogEntry.Rx => hasRx = true
case _: LogEntry.Tx => hasTx = true
}
}
val t = System.currentTimeMillis()
if (hasRx) {
lastRx = t
}
if (hasTx) {
lastTx = t
}
}
override def draw(g: Graphics): Unit = {
super.draw(g)
val t = System.currentTimeMillis()
drawActivity(g, IconSource.Nodes.OcelotBlock.Rx, lastRx, t)
drawActivity(g, IconSource.Nodes.OcelotBlock.Tx, lastTx, t)
}
private def drawActivity(g: Graphics, icon: IconSource, lastActivity: Long, currentTime: Long): Unit = {
val alpha = (1 - (currentTime - lastActivity) / ActivityFadeOutMs).clamped()
if (alpha > 0) {
g.sprite(
icon,
position.x + HighlightThickness,
position.y + HighlightThickness,
size.width - HighlightThickness * 2,
size.height - HighlightThickness * 2,
RGBAColorNorm(1f, 1f, 1f, alpha),
)
}
}
}
object OcelotBlockNode {
private val ActivityFadeOutMs: Float = 300f
}