neu-rah / ArduinoMenu

Arduino generic menu/interactivity system
GNU Lesser General Public License v2.1
933 stars 189 forks source link

Help: Struggling with Date/Time FIELD #319

Closed adrianbn closed 3 years ago

adrianbn commented 3 years ago

Hi,

Thanks for this library, it is life saving! I'm writing a menu with multiple HH:MM fields (E.g. 12:43) that can are editable. There are a few areas of the library that I haven't managed to twist to do what I want, but it may absolutely be that I missed something important somewhere. I think this is probably a common enough use case that having a library plugin for it would be very handy.

First, the validations for a HH:MM field are not as simple as a char* []. I'd like to pass a function that performs the validation, because the second digit's validation result will depend on the current value of the first digit. For instance, 15:14 is a valid time, but 25:14 isn't. I'd also like to do a bit more validation to make sure the new time does not overlap with existing ones.

Second, I wanted to add the ability while editing a time field of reading a number from the keypad and saving it instead of using up/down to set the current value. I've tried a custom field but I can't manage to make this work; it just seems like the menu ignores the numbers when pressed.

Third and last, I was trying to save a few bytes by storing the time as "1243" instead of "12:43" and then making the display add the ":" in the menu since it is just formatting. Once again, I tried creating a custom field that does this, but I couldn't make it work with the existing examples. It'd be great if someone could provide a template / example I could use to follow for this.

Thanks!

neu-rah commented 3 years ago

Hi!

date/time will work better with numeric field, range validated

this examples uses a date: https://github.com/neu-rah/ArduinoMenu/blob/master/examples/handlers/handlers/handlers.ino#L123

but time follows the same schema... using a pad menu => a sub-menu where items are shown on a single line

that will solve the text validation because it will be numeric validated by range.

to have more sophisticated validation.... this menu will reflect changes to the referred variables whenever they change (automatic), so whenever your code changes the target variables the changes will be shown.

But probably you want to check values when user is changing them, for that use the event handlers and validate/change your variables as needed, no extra action needed because changes will reflect back to display. This allows us to have a start and end time and do not allow end time to be less than the start time or even impose a time lapse between them... it will also allow us to change the end date when user edits the start date to respect the validation, because variables change/enforce is not related to the events... events are just a convenience.

hope its helps :)

adrianbn commented 3 years ago

Hey @neu-rah,

Thanks for the tips! The validators work and I can check for overlapping and other restrictions. Also, treating the fields as integers is not a bad idea, but the pad menu has problems displaying the times inside the LCD space (16x2). I've defined the start time like this:

PADMENU(schedule1StartMenu, "Start:", doNothing, anyEvent, noStyle,
  FIELD(schedules[0].start_hour, "", ":", 0, 23, 1, 1, doNothing, anyEvent, noStyle),
  FIELD(schedules[0].start_minute, "", ":", 0, 59, 1, 1, doNothing, anyEvent, noStyle)
);

MENU(schedule1Menu, "Schedule 1", doNothing, anyEvent, wrapStyle,
  SUBMENU(enableSched1),
  SUBMENU(schedule1StartMenu)
);

MENU(mainMenu, "Main menu", doNothing, noEvent, wrapStyle,
  SUBMENU(schedule1Menu)
);

When displaying the pad menu, that line looks like this (_ denotes a space): Start:__22:__43 I can't seem to make it display like this: Start:_22:43___ Or at least like Start:____22:43 In addition, when trying to edit the pad menu there are many symbols added to it which make it so that only the hour fits in the screen. For instance, when trying to edit the line Start:__22:__43, the display will show: Start::[:22:]__.

Is there a way to just display the integers aligned somehow and without all the additional : and [?

lorol commented 3 years ago

To remove separators etc. 1) you need to comment //out.print((root.navFocus == this&&sel) ? (menuField<T>::tunning ? '>' : ':') : ' '); of your customized class 2) In libraries/ArduinoMenu/src/menuIo.cpp #416 and 436 you disable printing of [ ], or you write an own replacement code if you dont want to hack the original source. Similar for the first :

But it is not getting nicer IMO anyway ...

adrianbn commented 3 years ago

Got it, thank you @lorol!