• I have created a menu on a Pixl, and this is normally controlled with the small buttons on the card.

    I would like, instead, to control this menu with external buttons connected to D1 ... D4.

    To understand what the internal events handlers of the menu really do, I tried to replace the setWatch calls by the suggestions of the link Graphical Menu:

    setWatch(function() {
      m.move(-1); // up
    }, BTN1, {repeat:true,debounce:50,edge:"rising"});
    
    setWatch(function() {
      m.move(1); // down
    }, BTN4, {repeat:true,debounce:50,edge:"rising"});
    
    setWatch(function() {
      m.select(); // select
    }, BTN3, {repeat:true,debounce:50,edge:"rising"});
    

    It works for a simple menu, but not for editing the value of a number, for example.

    So the questions are:

    1. Is it possible to reuse the event handlers of the menu (up/down etc...) and call them from another type of event ? (D1 ...)
    2. Or is there another way to use a menu with different events ?

    Many thanks in advance.

  • Hi!

    The code for the Pixl's menu implementation is at https://github.com/espruino/Espruino/blob/master/libs/js/pixljs/E_showMenu.js

    It does exactly as you have above:

      Pixl.btnWatches = [
        setWatch(function() { m.move(-1); }, BTN1, {repeat:1}),
        setWatch(function() { m.move(1); }, BTN4, {repeat:1}),
        setWatch(function() { m.select(); }, BTN3, {repeat:1})
      ];
    

    So really I'd have thought you could just do:

      Pixl.btnWatches.forEach(clearWatch);
      Pixl.btnWatches = [
        setWatch(function() { m.move(-1); }, BTN1, {repeat:1}),
        setWatch(function() { m.move(1); }, BTN4, {repeat:1}),
        setWatch(function() { m.select(); }, BTN3, {repeat:1})
      ];
    

    Immediately after calling E.showMenu and it would have exactly the same effect? If that doesn't work could you explain what's not working?

    One other option is to just overwrite the Pixl's default showMenu implementation:

    E.showMenu = (function(menudata) {
      if (Pixl.btnWatches) {
        Pixl.btnWatches.forEach(clearWatch);
        Pixl.btnWatches = undefined;
      }
      g.clear();g.flip(); // clear screen if no menu supplied
      if (!menudata) return;
      if (!menudata[""]) menudata[""]={};
      g.setFontBitmap();g.setFontAlign(-1,-1,0);
      var w = g.getWidth()-9;
      var h = g.getHeight();
      menudata[""].x=9;
      menudata[""].x2=w-2;
      menudata[""].preflip=function() {
        g.drawImage(E.toString(8,8,1,
          0b00010000,
          0b00111000,
          0b01111100,
          0b11111110,
          0b00010000,
          0b00010000,
          0b00010000,
          0b00010000,
        ),0,4);
        g.drawImage(E.toString(8,8,1,
          0b00010000,
          0b00010000,
          0b00010000,
          0b00010000,
          0b11111110,
          0b01111100,
          0b00111000,
          0b00010000,
        ),0,h-12);
        g.drawImage(E.toString(8,8,1,
          0b00000000,
          0b00001000,
          0b00001100,
          0b00001110,
          0b11111111,
          0b00001110,
          0b00001100,
          0b00001000,
        ),w+1,h-12);
        //g.drawLine(7,0,7,h);
        //g.drawLine(w,0,w,h);
      };
      var m = require("graphical_menu").list(g, menudata);
      Pixl.btnWatches = [
        setWatch(function() { m.move(-1); }, D1, {repeat:1}), // <------------ change these
        setWatch(function() { m.move(1); }, D2, {repeat:1}),  // <------------ change these
        setWatch(function() { m.select(); }, D3, {repeat:1})  // <------------ change these
      ];
      return m;
    });
    

    And now every time E.showMenu is called, it'll use the right button inputs

    edit: also, just moving this to the Pixl.js section of the forum

  • Thanks for your answer.
    The problem happens when setting a watch on BTN1 to call a function opening the menu. Then, changing the watches to the proper buttons used by the menu.
    At this moment, BTN1 and BTN4 work in the opposite way (BTN1 is down amd BTN4 is up), and it is not possible anymore to edit the value of a number.

    However, if I use BTN2, and do not clearWatch BTN1,3,4 , it works fine.

    Therefore, I "overwrote the Pixl's default showMenu implementation", and it worked perfectly.

    So, I suspect some sort of conflict when changing a watch once the menu is created. Like:
    m.setWatch() , returned_copy_of_m.clearWatch(), returned_copy_of_m.setWatch() after menu creation.
    Maybe, setting the second watch with a copy of the variable m ?

    Anyway, it works fine now, so thanks again.

  • Ahh, thanks! Yes, I think maybe when you go to edit a menu item and then come back, maybe there ends up being a different copy of m.

    Anyway, I'm glad that fixed it for you! Overwriting E.showMenu is definitely the safest, most flexible way of doing it

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

Controlling Pixl menu with D1,D2,D3 ... instead of BTN1,2,3 ... ?

Posted by Avatar for rchateauneu @rchateauneu

Actions