It's mainly meant for my game framework, but perhaps some inspiration on some 
of these problems can be rung out of <https://github.com/beef331/gooey/>

Instead of using a DSL for declaring the GUI it just uses tuples(This would be 
a smidgen nicer with object constructor having generic inference). The benefit 
of this is it's just normal Nim code with no caveats.
    
    
    let
        # these only are here cause `template named(name, val: untyped): 
untyped = let name = val`
        # does not work
        myLabel = Label(
          color: (0, 255, 127, 255),
          text: "Huh",
          anchor: {bottom, right},
          size: Vec2.init(100, 50)
        )
        
        slider = Slider[float32](
          rng: 1f..5f,
          pos: (10, 10, 0),
          size: (100, 30),
          color: (123, 155, 200, 255),
          slideBar: Element(color: (62, 88, 170, 255)),
          anchor: {bottom, left},
          onChange: proc(f: float32) =
            myLabel.size.y = f * 50
            myLabel.size.x = f * 100
        )
      
      (
        Button(
          pos: Vec3.init(10, 10, 0),
          anchor: {top, left},
          size: Vec2.init(100, 50),
          clickCb: proc() = echo("Hello"),
          label: Label(text: "Hello", color: (0, 0, 0, 255))
        ),
        Label(text: "Hmmm", anchor: {bottom, right}, size: Vec2.init(300, 200)),
        myLabel,
        slider,
        HGroup[(Label, Button)](
          pos: (10, 10, 0),
          anchor: {top, right},
          entries: (
            Label(text: "Test:", size: (100, 50)),
            Button(
              size: (100, 50),
              color: (99, 64, 99, 255),
              hoveredColor: (188, 124, 188, 255),
              label: Label(text: "Really!", color: (0, 35, 127, 255)))
            )
        ),...
    
    
    Run

It's also backend/vector agnostic using generics, inheritance, and concepts to 
implement most logic the gooey implementation followed by implementation in my 
sdl api can be seen below. (I use proc instead of methods as I had a desire to 
have it purely statically type and never rely on type information to reason 
dispatch, in any sensible library probably would use methods or pointer procs 
created from constructors for generics.)
    
    
    # gooey/buttons.nim
    import gooey, mathtypes
    
    type ButtonBase*[Base] = ref object of Base # This exists so we can be 
vector/renderer agnostic, the user passes in our data as a sort of dependency 
injection
      clickCb*: proc()
    
    proc layout*[Base](button: ButtonBase[Base], parent: Base, offset: Vec3, 
state: UiState) =
      mixin layout
      Base(button).layout(parent, offset, state)
    
    proc onClick*[Base](button: ButtonBase[Base], uiState: var UiState) =
      if button.clickCb != nil:
        button.clickCb()
    
    # sdlimpl.nim
    type
      Button = ref object of ButtonBase[Element]
        baseColor: Color
        hoveredColor: Color = (127, 127, 127, 255)
        label: Label
    
    proc upload(button: Button, state: UiState, target: var RenderTarget) =
      Element(button).upload(state, target)
      if button.label != nil:
        button.label.upload(state, target)
    
    proc layout(button: Button, parent: Element, offset: Vec3, state: UiState) =
      buttons.layout(button, parent, offset, state)
      if button.label != nil:
        button.label.size = button.size
        button.label.layout(button, (0f, 0f, 0f), state)
    
    proc onEnter(button: Button, uiState: var UiState) =
      button.flags.incl {hovered}
      button.baseColor = button.color
      button.color = button.hoveredColor
    
    proc onExit(button: Button, uiState: var UiState) =
      button.color = button.baseColor
    
    proc onClick(button: Button, uiState: var UiState) = 
buttons.onClick(button, uiState)
    
    
    
    Run

Though this is likely much lower level and limited than desired, I think it 
might be a good source of inspiration for agnosticism. As I already have 
implemented an Opengl implementation along with an SDL implementation for this 
UI "framework which can be viewed in their entirety below.

<https://github.com/beef331/gooey/blob/master/example/sdlimpl.nim> 
<https://github.com/beef331/truss3d/blob/master/src/truss3D/gui.nim>

Reply via email to