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)