mirror of
https://gitlab.com/cc-ru/ocelot/ocelot-desktop.git
synced 2025-12-20 11:09:20 +01:00
135 lines
4.5 KiB
Scala
135 lines
4.5 KiB
Scala
package ocelot.desktop.ui.window
|
|
|
|
import ocelot.desktop.color.{IntColor, RGBAColor, RGBAColorNorm}
|
|
import ocelot.desktop.geometry.{Rect2D, Size2D, Vector2D}
|
|
import ocelot.desktop.graphics.Graphics
|
|
import ocelot.desktop.ui.event.{CloseWindowEvent, KeyEvent, MouseEvent, ScrollEvent}
|
|
import ocelot.desktop.ui.{MouseHandler, UiHandler}
|
|
import ocelot.desktop.util.{DrawUtils, Logging}
|
|
import totoro.ocelot.brain.entity.Screen
|
|
import totoro.ocelot.brain.user.User
|
|
import totoro.ocelot.brain.util.PackedColor
|
|
|
|
class ScreenWindow(screen: Screen) extends BasicWindow with Logging {
|
|
private val fontWidth = 8f
|
|
private val fontHeight = 16f
|
|
|
|
private def width: Int = screen.getWidth
|
|
|
|
private def height: Int = screen.getHeight
|
|
|
|
override def minimumSize: Size2D = Size2D(width * fontWidth + 32, height * fontHeight + 20)
|
|
|
|
override def maximumSize: Size2D = minimumSize
|
|
|
|
private var lastMousePos = Vector2D(0, 0)
|
|
private var sentTouchEvent = false
|
|
|
|
eventHandlers += {
|
|
case event: KeyEvent =>
|
|
event.state match {
|
|
case KeyEvent.State.Press | KeyEvent.State.Repeat =>
|
|
screen.keyDown(event.char, event.code, User("myself"))
|
|
|
|
if (event.code == 1)
|
|
hide()
|
|
|
|
// note: in opencomputers, key_down signal is fired __before__ clipboard signal
|
|
if (event.code == 210)
|
|
screen.clipboard(UiHandler.clipboard, User("myself"))
|
|
case KeyEvent.State.Release =>
|
|
screen.keyUp(event.char, event.code, User("myself"))
|
|
}
|
|
|
|
case event: MouseEvent =>
|
|
val pos = convertMousePos(UiHandler.mousePosition)
|
|
val inside = checkBounds(pos)
|
|
|
|
if (inside)
|
|
lastMousePos = pos
|
|
|
|
event.state match {
|
|
case MouseEvent.State.Press if inside =>
|
|
screen.mouseDown(pos.x, pos.y, event.button.id, User("myself"))
|
|
sentTouchEvent = true
|
|
|
|
case MouseEvent.State.Release =>
|
|
if (event.button == MouseEvent.Button.Middle && inside)
|
|
screen.clipboard(UiHandler.clipboard, User("myself"))
|
|
|
|
if (sentTouchEvent) {
|
|
screen.mouseUp(lastMousePos.x, lastMousePos.y, event.button.id, User("myself"))
|
|
sentTouchEvent = false
|
|
} else if (closeButtonBounds.contains(UiHandler.mousePosition)) {
|
|
hide()
|
|
}
|
|
|
|
case _ =>
|
|
}
|
|
|
|
case event: ScrollEvent =>
|
|
screen.mouseScroll(lastMousePos.x, lastMousePos.y, event.offset, User("myself"))
|
|
}
|
|
|
|
private def checkBounds(p: Vector2D): Boolean = p.x >= 0 && p.y >= 0 && p.x < width && p.y < height
|
|
|
|
private def convertMousePos(p: Vector2D): Vector2D = {
|
|
Vector2D(
|
|
math.floor((p.x - 16f - position.x) / fontWidth),
|
|
math.floor((p.y - 16f - position.y) / fontHeight)
|
|
)
|
|
}
|
|
|
|
override def dragRegions: Iterator[Rect2D] = Iterator(Rect2D(position.x, position.y, size.width, 20))
|
|
|
|
override def update(): Unit = {
|
|
super.update()
|
|
|
|
val currentMousePos = convertMousePos(UiHandler.mousePosition)
|
|
if (!checkBounds(currentMousePos) || currentMousePos == lastMousePos) return
|
|
|
|
lastMousePos = currentMousePos
|
|
|
|
for (button <- MouseHandler.pressedButtons) {
|
|
screen.mouseDrag(lastMousePos.x, lastMousePos.y, button.id, User("myself"))
|
|
}
|
|
}
|
|
|
|
private def closeButtonBounds: Rect2D = Rect2D(
|
|
position.x + fontWidth * width + 2,
|
|
position.y - 2, 22, 22)
|
|
|
|
override def draw(g: Graphics): Unit = {
|
|
val sx = position.x + 16
|
|
val sy = position.y + 20
|
|
val w = fontWidth * width
|
|
val h = fontHeight * height
|
|
|
|
DrawUtils.shadow(g, sx - 22, sy - 22, w + 44, h + 52, shadowAlpha)
|
|
DrawUtils.screenBorder(g, sx, sy, w, h, RGBAColorNorm(1, 1, 1, backgroundAlpha))
|
|
|
|
for (y <- 0 until height) {
|
|
for (x <- 0 until width) {
|
|
val char = screen.data.buffer(y)(x)
|
|
val color = screen.data.color(y)(x)
|
|
val bg = PackedColor.unpackBackground(color, screen.data.format)
|
|
val fg = PackedColor.unpackForeground(color, screen.data.format)
|
|
g.background = IntColor(bg).toRGBANorm.withAlpha(backgroundAlpha)
|
|
g.foreground = IntColor(fg).toRGBANorm.withAlpha(backgroundAlpha)
|
|
g.char(sx + x * fontWidth, sy + y * fontHeight, char)
|
|
}
|
|
}
|
|
|
|
g.setSmallFont()
|
|
g.background = RGBAColor(0, 0, 0, 0)
|
|
val col = (backgroundAlpha * 110).toShort
|
|
val alpha = (backgroundAlpha * 255).toShort
|
|
g.foreground = RGBAColor(col, col, col, alpha)
|
|
g.text(sx - 4, sy - 14, screen.node.address)
|
|
g.setNormalFont()
|
|
|
|
g.sprite("window/CloseButton", sx + w - 7, sy - 13, 7, 6,
|
|
color = RGBAColor(255, 255, 255, alpha))
|
|
}
|
|
}
|