Hi y'all!

I'm working on graphics/ui Library for the fantastic 
[picostdlib](https://forum.nim-lang.org/postActivity.xml#picostdlib) (actually 
I'm using the nice 
[rework](https://forum.nim-lang.org/postActivity.xml#rework)) Right now I'm 
pondering on how to organize the widgets and make them simple to use, here is a 
broken down code of what I'm trying to do:
    
    
    type
      # Concept for display, so that all displays can use the same basic 
functions for drawing
      AnyDisplay*[T] = concept display   # T is the type of the color, e.g. for 
1 bit displays uint8 and for rgb displays uint32
        display.getPixel(int, int) is T
        display.setPixel(int, int, T)
        display.color is T # this is only used so that T can be infered other 
places
      
      # implementation for a 1 bit display that uses uint8 for the color
      OneBitDisplay* = object
            color*: uint8 # this is only used so that the color type can be 
infered elsewhere
    
    
    proc getPixel*(disp: OneBitDisplay; x, y: int): uint8 =
      discard
    
    proc setPixel*(disp: var OneBitDisplay; x, y: int; color: uint8) =
      discard
    
    # check if concept is matched
    echo("OneBitDisplay is AnyDisplay: ",OneBitDisplay is AnyDisplay)
    
    
    type
      # Basic Type for widgets that draw on a display
      Widget*[T: AnyDisplay] = ref object of RootObj # T is of type AnyDisplay, 
so that the widget can use the drawing functions
          bgcolor*: typeof(T.color)
          display: T
    
    proc initWidget*[T](display: T): Widget[T] =
        new(result)
        result.display = display
    
    proc draw*[T](self: Widget[T]) =
      echo("Drawing normal widget")
    
    type
      # Label that contains text
      Label*[T] = ref object of Widget[T]
          text = ""
    
    proc initLabel*[T](display: T, label: string): Label[T] =
        new(result)
        result.display = display
    
    proc draw*[T](self: Label[T]) =
      echo("Drawing Label: ", self.text)
    
    
    type
        # type for handling events, drawing, etc
        UserInterface*[T] = object
            activeWidget {.cursor.}: Widget[T] # widget which should be drawn
    
    
    proc setActiveWidget*[T](self: var UserInterface[T], w: Widget[T]) =
        self.activeWidget = w
    
    proc draw*[T](self: var UserInterface[T]) =
        self.activeWidget.draw()
    
    
    var
      d: OneBitDisplay
      w = initWidget(d)
      l = initLabel(d, "blubb")
      ui: UserInterface[OneBitDisplay]
    
    
    ui.setActiveWidget(w)
    ui.draw()
    ui.setActiveWidget(l)
    ui.draw()
    
    
    Run

Of course this does not work as I want it to, the output is:
    
    
    Drawing normal widget
    Drawing normal widget
    
    
    Run

Usually I would use methods in this case, but they are not available for 
generic types, so the question is: How would I implement something like this 
the nim way? (I don't want to use object variants, as there should be an easy 
way to define new widget types in different places in the code)

Reply via email to