switch case kind menu in Espruino?

Posted on
  • I Wonder how to make simple menu for LCD or OLED ssd1306, I know how to create it in arduino programming style using switch case function, are here any samples about that?

  • I did a menu on an LCD - there's an old version of the code in this thread over here, though I haven't updated the code there to the latest version I'm using, and I don't have it in github for some stupid reason:

    https://www.hackster.io/azzy/adjustable-color-temperature-desk-lamp (there's also a thread here on it but the code on hackster is newer, I think)

    It's sort of ugly though. I avoid switch-case whenever possible - my track record with writing switch/case statements and not screwing them up is miserable.

  • I actually had a menu library I'd fiddled with myself. I'll see if I can dig it out. Personally, I stored the whole menu as structure where the values were functions that got executed when selected, something like:

    var myMenu2 = {
      "A Title":0,
      "Back":function() {set_menu(myMenu); },
    };
    var myMenu = {
      "Main Menu Title":0,
      "A Submenu":function() { set_menu(myMenu2); },
      "Run some code":function() { ... }
    };
    

    It made it relatively simple and easy to read. The menu code then just iterates over the object's fields and draws them, then when selected it runs the function.

  • Ok, just dug it out:

    var exports = {};
    
    exports.list = function(g, items) {
      var options = items[""];
      if (!(options instanceof Object)) options = {};
      if (options.selected === undefined)
        options.selected = 0;
      if (!options.fontHeight)
        options.fontHeight = 6;
      var y = 0|options.y;
      if (options.title)
        y += options.fontHeight+2;
    
      var menuItems = Object.keys(items).slice(1); // remove first item
     
      var l = {
        draw : function() {
          g.clear();
          g.setColor(-1);
          if (options.title) {
            g.drawString(options.title,(g.getWidth()-g.stringWidth(options.title))/2,y-options.fontHeight-2);
            g.drawLine(0,y-2,g.getWidth(),y-2);
          }
    
          var rows = 0|Math.min((g.getHeight()-y) / options.fontHeight,menuItems.length);
          var idx = E.clip(options.selected-rows/2,0,menuItems.length-rows);
          var iy = y;
    
          while (rows--) {
            if (idx==options.selected) {
              g.fillRect(0,iy,g.getWidth()-1,iy+options.fontHeight-1);
              g.setColor(0);
            }
            g.drawString(menuItems[idx++],0,iy);
            g.setColor(-1);
            iy += options.fontHeight;
          }
          if (g.flip) g.flip();
        },
        select : function() {
          var item = items[menuItems[options.selected]];
          if ("function" == typeof item)
            item();
        },
        move : function(dir) {
          options.selected = 0|Math.clip(options.selected+dir,0,menuItems.length-1);
          l.draw();
        }
      };
      l.draw();
      return l;
    };
    
    
    var menu = exports; // would be a require if this were a library
    A5.write(0); // GND
    A7.write(1); // VCC
    
    // Setup SPI
    var spi = new SPI();
    spi.setup({ sck:B1, mosi:B10 });
    
    var g,m;
    
    var mainmenu = {
      "" : {
        "title" : "-- Menu --"
      },
      "Light On" : function() { LED1.set(); },
      "Light Off" : function() { LED1.reset(); },
      "Submenu" : function() { m=menu.list(g, submenu); },
    };
    
    var submenu = {
      "" : {
        "title" : "-- SubMenu --"
      },
      "One" : undefined,
      "Two" : undefined,
      "< Back" : function() { m=menu.list(g, mainmenu); },
    };
                                             
    
    function onInit() {
      g = require("PCD8544").connect(spi,B13,B14,B15, function() {
        m = menu.list(g, mainmenu);
      });
    }
    
    // Now just call things when buttons are pressed
    // m.move(1); moves down
    // m.move(-1); moves up
    // m.select(); selects item
    
    onInit();
    

    Anyone think this would be worth turning into a 'proper' module?

  • Note: LCD is set up as in this tutorial

  • Thanks Gordon, I'll check it later on today, will try to use it under SSD1306, hope I can manage

  • Great! it should be fine with that - the default font is quite small.

    Let me know if you've got any thoughts - I'd love to get this into a module as soon as possible really.

  • hi, still fighting with it ;) could you tell me how to change font size ;)

    ok, I've got it, it was in the graphic library, g.setFontVector(..);
    every day I see more and more how easy Espruino is ;)

  • Great! :)

    Actually if you want some fonts that look a bit better, you can load in Bitmap fonts as well: http://www.espruino.com/Fonts

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

switch case kind menu in Espruino?

Posted by Avatar for bigplik @bigplik

Actions