• For the overall view (ui), I followed the DOM pattern and for the individual node - UI element - the box model, with the the ui being the DOM-'tree'. I like the object approach more than the array approach I took, but I did it intentionally - for performance and compactness/memory footprint. Indexes work like property names, as 'documented' in code for ui element (object - button, check(box), ...) in ui.elts[] (DOM):

    // 0=idx, 1=active, 2=type, 3=state, 4..7=x..y2, 8=brdrClr, 9=callback
    

    The ui three 'understands' touch screen events, passes them on to the element under the x/y coordinates (figured out by iin() - is 'in', passes control to the 'in' ui element, and lets it act on touch release like 'clicked' or 'tapped' (it also manages the drag: you touch in button 'aBtn' and release somewhere else: 'aBtn' has not been clicked/tapped - just as in the browser.

    The color values are basic color numbers - or when the ui.clrs[] table is populated, they are index into this colors table.

    More O-O: hink of ui as the factory and at the same time superclass that implements the UI element classes' behavior.

    Currently, the factory provides only only btn(...) and chk(box)(...) constructor methods and implements the behavior for these 'classes'. Arrays are a much more light-weight implementation than actual objects and by holding the type/class information in them, method branch out is possible (slow case statement, and slower the more types/classes there are), or - to be fast - the actual function/method is held on as action property (lambda) - just like callbacks are as well.

    I did not go beyond yet... but that's where its worth to extend. For a new view element:

    1. add a factory/constructor method
    2. add a draw method
    3. as needed, add ui specific method to for behavior

    Since drag is implemented, sliders are almost there, and so would be gauges.

    You may have noticed that for performance I try to use overlaying rectangles to get as fast as possible and with the least information border and fill. As said earlier: speed is a challenge.

    On construction UI element is returned and can be modified as needed, as well as in the event, it passes itself in the callback to allow access to the (ui)e(lement) from within the callback.

    If you generalize in your code btns[] and doBttons() and tuck it away (encapsulate/hide implementation) in a ui singleton - including some of your other globals, 'we' are not much different. Btw, I wondered where the Button() constructor is used... do I miss something, or did not all code make it into the post? Can you share a pic of the running UI?

  • Embarassing... yes, some code got cut off -- note line 116 ends with '...label:"Butt'! HAHAHA! I assure everyone I did not have an example button with the text "Butt" on the screen :-)

    Here's the complete end of the code, the btns array initialization repeated:

    var btns=[
      {tl:{x:50,y:100},br:{x:170,y:150},RGB:{R­:255,G:0,B:0},label:"Button",fontSize:20­,onPress:btnPress,onRelease:btnRelease,I­D:"btn0"},
      {tl:{x:10,y:40},br:{x:130,y:90},RGB:{R:0­,G:0,B:0},label:"BL off",fontSize:20,onPress:function(){LCD.­bloff();},ID:"btn1"},
      {tl:{x:280,y:100},br:{x:320,y:120},RGB:{­R:255,G:255,B:0},label:"Button",fontSize­:20,onPress:btnPress,onRelease:btnReleas­e,ID:"btn2"},
      {tl:{x:100,y:160},br:{x:220,y:185},RGB:{­R:255,G:0,B:255},label:"Button",fontSize­:20,onPress:btnPress,onRelease:btnReleas­e,ID:"btn3"}
    ];
    
    btns.forEach(function(c){a=new Button(c);});
                 
    
    

    Buttons are created in line 8 above. Since this was simply code to get some buttons on the screen to test the GUI code, I'm not saving the references to the 4 buttons anywhere. In a real app I'd keep those references when necessary.

    I agree completely that our two approaches are really (stripped of minor differences) fundamentally the same. However, ignoring performance considerations (:-)) leaves me more flexibility to implement a more convenient OO model approach. Also makes the code easier to understand (that is, code using the GUI).

    There's good reasons for both approaches... Ease-of-use OO-biased design where performance isn't critical (things like footprint, or where there is a heavy on-going CPU load for the application, so minimizing UI processing overhead is really needed). Performance-oriented, efficient running code where CPU cycles and RAM are precious.

    Alternatively, for applications like a distributed WS2812B light strip controller, performance isn't an issue at all -- that's basically my case. I'm implementing the controller on a HY-MiniSTM32V board with touchscreen display, then each strip has its own dedicated ESP8266-12E running Espruino, everything connected over wifi on my home network.

    So, for me, simplicity in writing the controller code (after the effort of creating the GUI library!) is the driving value proposition.

    Is there a screencap function for displays? Otherwise, I'll have to shoot a picture and post it.

About

Avatar for dwallersv @dwallersv started