import std/os, std/strformat, std/math, files
import illwill

type
  # basic types
  Mod     = object
    modid:  int
    name:   string
    author: string
  Vec2    = tuple
    x:      int = 0
    y:      int = 0
  # layout types
  SectVariant   = enum
    empty,
    label,
    button,
    checkbox
  SectCase     = object
    case kind:   SectVariant
    of empty:    nil
    of label:    label:    Label
    of button:   button:   Button
    of checkbox: checkbox: Checkbox
  Label        = object
    text:        string  = "Label"
    position:    Vec2
    color:       ForegroundColor
    parent:      Element
  Button       = object
    text:        string  = "Button"
    position:    Vec2
    accented:    bool    = false
    parent:      Element
  Checkbox     = object
    position:    Vec2
    checked:     bool    = false
    accented:    bool    = false
    parent:      Element
  SectData     = ref SectCase
  Element      = ref object
    name:        string
    size:        Vec2
    position:    Vec2
    variant:     SectVariant
    data:        SectData

proc updateLabel(src: SectData, tb: var TerminalBuffer) =
  let data = src.label
  let x    = data.parent.position.x + data.position.x
  let y    = data.parent.position.y + data.position.y

  tb.resetAttributes()
  tb.setForegroundColor(data.color, bright=true)
  tb.write(x, y, data.text)

proc updateButton(src: SectData, tb: var TerminalBuffer) =
  let data = src.button
  let x    = data.parent.position.x + data.position.x
  let y    = data.parent.position.y + data.position.y

  tb.resetAttributes()
  tb.setForegroundColor(fgBlue, bright=data.accented)
  tb.write(x, y, data.text)

proc updateCheckbox(src: SectData, tb: var TerminalBuffer) =
  let data = src.checkbox
  let x    = data.parent.position.x + data.position.x
  let y    = data.parent.position.y + data.position.y

  tb.resetAttributes()
  tb.setForegroundColor(fgBlue, bright=data.accented)
  tb.write(x, y, "placeholder")

proc updateEmpty(parent: Element, tb: var TerminalBuffer) =
  var x = parent.position.x + floorDiv(parent.size.x, 2)
  var y = parent.position.y + floorDiv(parent.size.y, 2)
  if x > 4: x -= 3
  if y > 4: y -= 3

  tb.resetAttributes()
  tb.setForegroundColor(fgBlue, bright=true)
  tb.write(x, y, "empty space")

proc updateElement(element: Element, tb: var TerminalBuffer) =
  case element.variant
  of label:    updateLabel(element.data, tb)
  of button:   updateButton(element.data, tb)
  of checkbox: updateCheckbox(element.data, tb)
  else:        updateEmpty(element, tb)

var base_menu = Element(
  name:     "menu",
  size:     (x: 0, y: 0),
  position: (x: 0, y: 0),
  variant:  SectVariant(empty)
)

proc exitProc() {.noconv.} =
  illwillDeinit()
  showCursor()
  quit(0)

proc main() =
  illwillInit(fullscreen=true)
  setControlCHook(exitProc)
  hideCursor()

  var elements: seq[Element] = @[base_menu]

  while true:
    var tb  = newTerminalBuffer(terminalWidth(), terminalHeight())
    var key = getKey()

    case key
    of Key.Escape, Key.Q: exitProc()
    else: discard

    for value in elements:
      updateElement(value, tb)

    tb.display()

    sleep(20)

main()
Edit Report
Pub: 10 Dec 2024 18:39 UTC
Views: 22