ArduinoMenu
ArduinoMenu copied to clipboard
Custom Two Line Output
I created my own in and out MenuIO files; jetiboxIn
and jetiBoxOu
t. I used the serialIn
and serialOut
as examples to work from. I need to be able to replicate this type of output
Each "window" if you will is two lines. I have to set the text for each line separately by calling jetiEx.SetJetiboxText(JetiExProtocol::LINE1, 0)
and jetiEx.SetJetiboxText(JetiExProtocol::LINE2, 0)
. Where I'm stumbling on is setCursor
and write
. It's unclear in io.h
and io.cpp
how these are called. I decided to create two panels; one for each line like this:
#include "jetiboxOut.h"
namespace Menu {
constMEM panel jetibox_panels[] MEMMODE = {{0, 0, 16, 1},{0, 1, 16, 1}};
navNode *jetibox_nodes[sizeof(jetibox_panels) / sizeof(panel)];
panelsList jetibox_panel_list(
jetibox_panels,
jetibox_nodes,
sizeof(jetibox_panels) / sizeof(panel)
);
} // namespace Menu
How does ArduinoMenu uses multiple panels in lieu of a single two line panel? How is the text being passed to write
? Is it one char at a time? Should I be keeping track of my "cursor" and copy each incoming char in write into the subsequent position in my output buffer? How does ArduinoMenu respect the defined width in chars of the given panels? Does it make more sense to have a single two line panel? Most windows are a label above and a choice or toggle on the 2nd line. I'd like to keep this as KISS as possible. Thanks!
yes, it is one character at a time due to its text-mode origins. panels are for isolating menus inside boxes (positioning and size) however menu is line based (again text origins), however you can control the height of a lines in pixels, not a single line but all lines on a given gfx menuOut and you can customize how items print, so they internally can use the 2 lines. also, because you can customize how items print themselves you can print in other way than the single character at a time and can customize so for whole classes of items, not just one. However that does not help the fact that centrally the menu system controls position and scrolls based on single lines.
you can simulate screen replacement by using custom print and a line height that corresponds to your device height.
thinking on an lcd (2 lines) and as you have already done a driver you case is viable. the driver should use the full screen (2 lines), but should inform a size of one single line.
all elements have to be custom drawn (or driver reworked to use sencond line as an extension of the single, but in this case the titles would all have to had the same length)
you can then provide a sequence of menu levels where all options of one level should lead to the same next level, see reuse
example
I went back to the library and I think lcdOut.h
and the cursorOut
base class are more appropriate for what I'm doing based on the fact that the target device is an LCD. I can manage a char* buffer for each line and copy chars into the buffer as they come in via write, using setCursor
to keep track of where I'm at. How does the library manage removing chars at each cursor position? Do I need to override more than just write
? Is the library just calling clear
before updating what's on a given "line"? Am I sure that if I'm using a cursorOut
derivative that setCursor
will be called? Since I'm using my own type, a fair amount of my setup is without macros; as per the noMacros
demo. Thanks.
lcd driver prints a blanks line I think and gfx draw a filled rectangle to clear line before print
In looking at the implementation of Write
in the Arduino core,
/* default implementation: may be overridden */
size_t Print::write(const uint8_t *buffer, size_t size)
{
size_t n = 0;
while (size--) {
if (write(*buffer++)) n++;
else break;
}
return n;
}
I can see the fact that each char is placed into the buffer.
@neu-rah what about setCursor
? Will that be called? Does occur in the cursorOut
base class?
Is the code calling fill
? That does call SetCursor and Write.
yes code calls clearLine, setCursor, fill and write
correction: for your menu to work ok and reflect selected values some dynamic position would be required (as navigation system clears positioning when entering a menu) or i can implement some flag to not reset as this menu type has no ramifications
also: can use first line as menu title and second line as menu options, no need for special driver, but still needs positioning to selected option when entering a menu (if that happens after nav system cleanup)
marking this as enhancement as it is a clear case where 2D nav could be used (not implemented yet) because usually you have to click to edit values, only menus can change selection without the need of initial click.
Instead of using menu prompts and tricky navigation positioning this could be better achieved by using fields (fields preserve values), however they require the initial click to edit.
except if we have more than 2 navigation buttons and a different navigation core (2D)
All the Jetibox has for nav is four buttons; up, down, left, and right. For example if you change a choice, you would navigate to the end then press the down button to save the config settings.
yes, understand that and while navigating the "pipe" each stage has to preserve its state with 4 buttons there's no need to select or click to edit, just change settings.
this kind of navigation is not yet implemented, there are codes for up/down/left/right and even a nav2D flag on navRoot class, but not much more.
https://github.com/neu-rah/ArduinoMenu/blob/master/src/nav.h#L95
it was leaved this way because the menu is already over-sized for medium avr's like the atmega328. The idea then was to leave this to next version along with deep review of IO and also a modular navigation core to slim down simple menus and only load whats needed... as you see its a pile of work and this might take a while (help appreciated, anyone?). However I will take a look of whats needed and if its viable on this version... will post here.
Obviously I'll help.
what mcu are you using?
I'm using a Mini Pro with a 328p. However I can use anything. I am looking at the SAMD51G19A now. Then arduino-core for the D51 was just released.
almost there, dev branch is using new input method (for version 5). Swapping the menu root (as in here https://github.com/neu-rah/ArduinoMenu/issues/166) is not enough to this case as focused item still need to be made active and state preserved, working on it...
Sounds great. I'll keep an eye out.