from stdint import * import drivers.video.vesafb.gfx as gfx import drivers.video.ui.sheet as sheet import string import t, c UI_LABEL: t.CDefine = 0 UI_BUTTON: t.CDefine = 1 UI_PANEL: t.CDefine = 2 UI_PROGRESS: t.CDefine = 3 @t.Object class UIComponent: id: t.CInt ctype: t.CInt x: t.CInt y: t.CInt w: t.CInt h: t.CInt visible: t.CInt sheet: sheet.Sheet | t.CPtr fg_color: t.CUInt32T bg_color: t.CUInt32T text: t.CArray[t.CChar, 128] text_len: t.CInt value: t.CInt def __init__(self, ctype: t.CInt, sh: sheet.Sheet | t.CPtr, x: t.CInt, y: t.CInt, w: t.CInt, h: t.CInt): global _next_component_id self.id = _next_component_id _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(c.Addr(self.text), 0, 128) self.text_len = 0 self.value = 0 def SetText(self, s: str): i: t.CInt = 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: t.CInt): self.value = v def Render(self): if self.visible == 0: return sh: sheet.Sheet = c.Deref(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: t.CInt = 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: t.CInt, py: t.CInt) -> t.CInt: if px >= self.x and px < self.x + self.w and py >= self.y and py < self.y + self.h: return 1 return 0 @t.Object class UIManager: sheets: t.CArray[sheet.Sheet | t.CPtr, 64] sheet_count: t.CInt components: t.CArray[UIComponent | t.CPtr, 256] component_count: t.CInt screen_w: t.CInt screen_h: t.CInt def __init__(self, w: t.CInt, h: t.CInt): self.sheet_count = 0 self.component_count = 0 self.screen_w = w self.screen_h = h i: t.CInt for i in range(64): self.sheets[i] = None for i in range(256): self.components[i] = None def AddSheet(self, sh: sheet.Sheet | t.CPtr) -> t.CInt: if self.sheet_count >= 64: return -1 self.sheets[self.sheet_count] = sh self.sheet_count += 1 return 0 def AddComponent(self, comp: UIComponent | t.CPtr) -> t.CInt: if self.component_count >= 256: return -1 self.components[self.component_count] = comp self.component_count += 1 return 0 def FindComponent(self, cid: t.CInt) -> UIComponent | t.CPtr: i: t.CInt for i in range(self.component_count): p: UIComponent | t.CPtr = self.components[i] if p is not None: comp: UIComponent = c.Deref(p) if comp.id == cid: return p return None def RenderAll(self): i: t.CInt for i in range(self.component_count): p: UIComponent | t.CPtr = self.components[i] if p is not None: comp: UIComponent = c.Deref(p) comp.Render() def HitTest(self, px: t.CInt, py: t.CInt) -> UIComponent | t.CPtr: i: t.CInt = self.component_count - 1 while i >= 0: p: UIComponent | t.CPtr = self.components[i] if p is not None: comp: UIComponent = c.Deref(p) if comp.visible == 1 and comp.Contains(px, py) == 1: return p i -= 1 return None