2019-09-19 22:17:19 +03:00

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))
}
}