内容由用户产出,本次仅代为提交、未做任何语义修改;含 static 修饰符前置迁移等(新增 static 前缀 16 行)。提交消息为中性描述——如需更精确的说明请 amend。
146 lines
4.4 KiB
Plaintext
146 lines
4.4 KiB
Plaintext
from stdint import *
|
|
import drivers.video.vesafb.gfx as gfx
|
|
import drivers.video.ui.sheet as sheet
|
|
import string
|
|
|
|
|
|
define UI_LABEL = 0
|
|
define UI_BUTTON = 1
|
|
define UI_PANEL = 2
|
|
define UI_PROGRESS = 3
|
|
|
|
class UIComponent:
|
|
id: int
|
|
ctype: int
|
|
x: int
|
|
y: int
|
|
w: int
|
|
h: int
|
|
visible: int
|
|
sheet: sheet.Sheet*
|
|
fg_color: uint32
|
|
bg_color: uint32
|
|
text: [128]char
|
|
text_len: int
|
|
value: int
|
|
|
|
def __init__(self, ctype: int, sh: sheet.Sheet*, x: int, y: int, w: int, h: int):
|
|
self.id = sheet._next_component_id
|
|
sheet._next_component_id += 1
|
|
self.ctype = ctype
|
|
self.x = x
|
|
self.y = y
|
|
self.w = w
|
|
self.h = h
|
|
self.visible = 1
|
|
self.sheet = sh
|
|
self.fg_color = gfx.COLOR_RGB(255, 255, 255)
|
|
self.bg_color = gfx.COLOR_RGB(40, 40, 60)
|
|
string.memset(&self.text, 0, 128)
|
|
self.text_len = 0
|
|
self.value = 0
|
|
|
|
def SetText(self, s: str):
|
|
i: int = 0
|
|
for ch in s:
|
|
if i >= 127: break
|
|
self.text[i] = ch
|
|
i += 1
|
|
self.text[i] = 0
|
|
self.text_len = i
|
|
|
|
def SetValue(self, v: int):
|
|
self.value = v
|
|
|
|
def Render(self):
|
|
if self.visible == 0: return
|
|
sh: sheet.Sheet = *self.sheet
|
|
match self.ctype:
|
|
case 0: self._RenderLabel(sh)
|
|
case 1: self._RenderButton(sh)
|
|
case 2: self._RenderPanel(sh)
|
|
case 3: self._RenderProgress(sh)
|
|
|
|
def _RenderLabel(self, sh: sheet.Sheet):
|
|
sh.DrawFilledRect(self.x, self.y, self.w, self.h, 0)
|
|
|
|
def _RenderButton(self, sh: sheet.Sheet):
|
|
sh.DrawFilledRect(self.x, self.y, self.w, self.h, self.bg_color)
|
|
sh.DrawRect(self.x, self.y, self.w, self.h, self.fg_color)
|
|
|
|
def _RenderPanel(self, sh: sheet.Sheet):
|
|
sh.DrawFilledRect(self.x, self.y, self.w, self.h, self.bg_color)
|
|
sh.DrawRect(self.x, self.y, self.w, self.h, gfx.COLOR_RGB(80, 80, 120))
|
|
|
|
def _RenderProgress(self, sh: sheet.Sheet):
|
|
sh.DrawFilledRect(self.x, self.y, self.w, self.h, gfx.COLOR_RGB(30, 30, 40))
|
|
fill_w: int = self.w * self.value / 100
|
|
if fill_w > 0:
|
|
sh.DrawFilledRect(self.x, self.y, fill_w, self.h, gfx.COLOR_RGB(0, 180, 255))
|
|
sh.DrawRect(self.x, self.y, self.w, self.h, gfx.COLOR_RGB(80, 80, 100))
|
|
|
|
def Contains(self, px: int, py: int) -> int:
|
|
if px >= self.x and px < self.x + self.w and py >= self.y and py < self.y + self.h:
|
|
return 1
|
|
return 0
|
|
|
|
|
|
class UIManager:
|
|
sheets: [64]sheet.Sheet*
|
|
sheet_count: int
|
|
components: [256]UIComponent*
|
|
component_count: int
|
|
screen_w: int
|
|
screen_h: int
|
|
|
|
def __init__(self, w: int, h: int):
|
|
self.sheet_count = 0
|
|
self.component_count = 0
|
|
self.screen_w = w
|
|
self.screen_h = h
|
|
i: int
|
|
for i in range(64):
|
|
self.sheets[i] = None
|
|
for i in range(256):
|
|
self.components[i] = None
|
|
|
|
def AddSheet(self, sh: sheet.Sheet*) -> int:
|
|
if self.sheet_count >= 64: return -1
|
|
self.sheets[self.sheet_count] = sh
|
|
self.sheet_count += 1
|
|
return 0
|
|
|
|
def AddComponent(self, comp: UIComponent*) -> int:
|
|
if self.component_count >= 256: return -1
|
|
self.components[self.component_count] = comp
|
|
self.component_count += 1
|
|
return 0
|
|
|
|
def FindComponent(self, cid: int) -> UIComponent*:
|
|
i: int
|
|
for i in range(self.component_count):
|
|
p: UIComponent* = self.components[i]
|
|
if p is not None:
|
|
comp: UIComponent = *p
|
|
if comp.id == cid: return p
|
|
return None
|
|
|
|
def RenderAll(self):
|
|
i: int
|
|
for i in range(self.component_count):
|
|
p: UIComponent* = self.components[i]
|
|
if p is not None:
|
|
comp: UIComponent = *p
|
|
comp.Render()
|
|
|
|
def HitTest(self, px: int, py: int) -> UIComponent*:
|
|
i: int = self.component_count - 1
|
|
while i >= 0:
|
|
p: UIComponent* = self.components[i]
|
|
if p is not None:
|
|
comp: UIComponent = *p
|
|
if comp.visible == 1 and comp.Contains(px, py) == 1:
|
|
return p
|
|
i -= 1
|
|
return None
|