123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552 |
- /**
- * Marlin 3D Printer Firmware
- * Copyright (c) 2022 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
- *
- * Based on Sprinter and grbl.
- * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
- /**
- * Menu functions for ProUI
- * Author: Miguel A. Risco-Castillo
- * Version: 1.4.1
- * Date: 2022/04/14
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
- #include "../../../inc/MarlinConfigPre.h"
-
- #if ENABLED(DWIN_LCD_PROUI)
-
- #include "../common/encoder.h"
- #include "dwin_lcd.h"
- #include "dwinui.h"
- #include "dwin.h"
- #include "menus.h"
-
- int8_t MenuItemTotal = 0;
- int8_t MenuItemCount = 0;
- MenuItemClass** MenuItems = nullptr;
- MenuClass *CurrentMenu = nullptr;
- MenuClass *PreviousMenu = nullptr;
- void (*onMenuDraw)(MenuClass* menu) = nullptr;
- void (*onCursorErase)(const int8_t line) = nullptr;
- void (*onCursorDraw)(const int8_t line) = nullptr;
- MenuData_t MenuData;
-
- // Menuitem Drawing functions =================================================
-
- void Draw_Title(TitleClass* title) {
- DWIN_Draw_Rectangle(1, HMI_data.TitleBg_color, 0, 0, DWIN_WIDTH - 1, TITLE_HEIGHT - 1);
- if (title->frameid)
- DWIN_Frame_AreaCopy(title->frameid, title->frame.left, title->frame.top, title->frame.right, title->frame.bottom, 14, (TITLE_HEIGHT - (title->frame.bottom - title->frame.top)) / 2 - 1);
- else
- DWIN_Draw_String(false, DWIN_FONT_HEAD, HMI_data.TitleTxt_color, HMI_data.TitleBg_color, 14, (TITLE_HEIGHT - DWINUI::fontHeight(DWIN_FONT_HEAD)) / 2 - 1, title->caption);
- }
-
- void Draw_Menu(MenuClass* menu) {
- DWINUI::SetColors(HMI_data.Text_Color, HMI_data.Background_Color, HMI_data.StatusBg_Color);
- DWIN_Draw_Rectangle(1, DWINUI::backcolor, 0, TITLE_HEIGHT, DWIN_WIDTH - 1, STATUS_Y - 1);
- }
-
- void Draw_Menu_Cursor(const int8_t line) {
- const uint16_t ypos = MYPOS(line);
- DWINUI::Draw_Box(1, HMI_data.Cursor_color, {0, ypos, 15, MLINE - 1});
- }
-
- void Erase_Menu_Cursor(const int8_t line) {
- const uint16_t ypos = MYPOS(line);
- DWINUI::Draw_Box(1, HMI_data.Background_Color, {0, ypos, 15, MLINE - 1});
- }
-
- void Draw_Menu_Line(const uint8_t line, const uint8_t icon /*=0*/, const char * const label /*=nullptr*/, bool more /*=false*/) {
- if (icon) DWINUI::Draw_Icon(icon, ICOX, MBASE(line) - 3);
- if (label) DWINUI::Draw_String(LBLX, MBASE(line) - 1, (char*)label);
- if (more) DWINUI::Draw_Icon(ICON_More, VALX + 16, MBASE(line) - 3);
- DWIN_Draw_HLine(HMI_data.SplitLine_Color, 16, MYPOS(line + 1), 240);
- }
-
- void Draw_Chkb_Line(const uint8_t line, const bool checked) {
- DWINUI::Draw_Checkbox(HMI_data.Text_Color, HMI_data.Background_Color, VALX + 3 * DWINUI::fontWidth(), MBASE(line) - 1, checked);
- }
-
- void Draw_Menu_IntValue(uint16_t bcolor, const uint8_t line, uint8_t iNum, const int32_t value /*=0*/) {
- DWINUI::Draw_Signed_Int(HMI_data.Text_Color, bcolor, iNum , VALX, MBASE(line) - 1, value);
- }
-
- void onDrawMenuItem(MenuItemClass* menuitem, int8_t line) {
- if (menuitem->icon) DWINUI::Draw_Icon(menuitem->icon, ICOX, MBASE(line) - 3);
- if (menuitem->frameid)
- DWIN_Frame_AreaCopy(menuitem->frameid, menuitem->frame.left, menuitem->frame.top, menuitem->frame.right, menuitem->frame.bottom, LBLX, MBASE(line));
- else if (menuitem->caption)
- DWINUI::Draw_String(LBLX, MBASE(line) - 1, menuitem->caption);
- DWIN_Draw_HLine(HMI_data.SplitLine_Color, 16, MYPOS(line + 1), 240);
- }
-
- void onDrawSubMenu(MenuItemClass* menuitem, int8_t line) {
- onDrawMenuItem(menuitem, line);
- DWINUI::Draw_Icon(ICON_More, VALX + 16, MBASE(line) - 3);
- }
-
- void onDrawIntMenu(MenuItemClass* menuitem, int8_t line, int32_t value) {
- onDrawMenuItem(menuitem, line);
- Draw_Menu_IntValue(HMI_data.Background_Color, line, 4, value);
- }
-
- void onDrawPIntMenu(MenuItemClass* menuitem, int8_t line) {
- const int16_t value = *(int16_t*)static_cast<MenuItemPtrClass*>(menuitem)->value;
- onDrawIntMenu(menuitem, line, value);
- }
-
- void onDrawPInt8Menu(MenuItemClass* menuitem, int8_t line) {
- const uint8_t value = *(uint8_t*)static_cast<MenuItemPtrClass*>(menuitem)->value;
- onDrawIntMenu(menuitem, line, value);
- }
-
- void onDrawPInt32Menu(MenuItemClass* menuitem, int8_t line) {
- const uint32_t value = *(uint32_t*)static_cast<MenuItemPtrClass*>(menuitem)->value;
- onDrawIntMenu(menuitem, line, value);
- }
-
- void onDrawFloatMenu(MenuItemClass* menuitem, int8_t line, uint8_t dp, const float value) {
- onDrawMenuItem(menuitem, line);
- DWINUI::Draw_Signed_Float(HMI_data.Text_Color, HMI_data.Background_Color, 3, dp, VALX - dp * DWINUI::fontWidth(DWIN_FONT_MENU), MBASE(line), value);
- }
-
- void onDrawPFloatMenu(MenuItemClass* menuitem, int8_t line) {
- const float value = *(float*)static_cast<MenuItemPtrClass*>(menuitem)->value;
- const int8_t dp = UNITFDIGITS;
- onDrawFloatMenu(menuitem, line, dp, value);
- }
-
- void onDrawPFloat2Menu(MenuItemClass* menuitem, int8_t line) {
- const float value = *(float*)static_cast<MenuItemPtrClass*>(menuitem)->value;
- onDrawFloatMenu(menuitem, line, 2, value);
- }
-
- void onDrawPFloat3Menu(MenuItemClass* menuitem, int8_t line) {
- const float value = *(float*)static_cast<MenuItemPtrClass*>(menuitem)->value;
- onDrawFloatMenu(menuitem, line, 3, value);
- }
-
- void onDrawChkbMenu(MenuItemClass* menuitem, int8_t line, bool checked) {
- onDrawMenuItem(menuitem, line);
- Draw_Chkb_Line(line, checked);
- }
-
- void onDrawChkbMenu(MenuItemClass* menuitem, int8_t line) {
- const bool val = *(bool*)static_cast<MenuItemPtrClass*>(menuitem)->value;
- onDrawChkbMenu(menuitem, line, val);
- }
-
- //-----------------------------------------------------------------------------
- // On click functions
- //-----------------------------------------------------------------------------
-
- // Generic onclick event without draw
- // process: process id HMI destiny
- // lo: low limit
- // hi: high limit
- // dp: decimal places, 0 for integers
- // val: value / scaled value
- // LiveUpdate: live update function when the encoder changes
- // Apply: update function when the encoder is pressed
- void SetOnClick(uint8_t process, const int32_t lo, const int32_t hi, uint8_t dp, const int32_t val, void (*Apply)() /*= nullptr*/, void (*LiveUpdate)() /*= nullptr*/) {
- checkkey = process;
- MenuData.MinValue = lo;
- MenuData.MaxValue = hi;
- MenuData.dp = dp;
- MenuData.Apply = Apply;
- MenuData.LiveUpdate = LiveUpdate;
- MenuData.Value = constrain(val, lo, hi);
- EncoderRate.enabled = true;
- }
-
- // Generic onclick event for integer values
- // process: process id HMI destiny
- // lo: scaled low limit
- // hi: scaled high limit
- // val: value
- // LiveUpdate: live update function when the encoder changes
- // Apply: update function when the encoder is pressed
- void SetValueOnClick(uint8_t process, const int32_t lo, const int32_t hi, const int32_t val, void (*Apply)() /*= nullptr*/, void (*LiveUpdate)() /*= nullptr*/) {
- SetOnClick(process, lo, hi, 0, val, Apply, LiveUpdate);
- Draw_Menu_IntValue(HMI_data.Selected_Color, CurrentMenu->line(), 4, MenuData.Value);
- }
-
- // Generic onclick event for float values
- // process: process id HMI destiny
- // lo: scaled low limit
- // hi: scaled high limit
- // val: value
- // LiveUpdate: live update function when the encoder changes
- // Apply: update function when the encoder is pressed
- void SetValueOnClick(uint8_t process, const float lo, const float hi, uint8_t dp, const float val, void (*Apply)() /*= nullptr*/, void (*LiveUpdate)() /*= nullptr*/) {
- const int32_t value = round(val * POW(10, dp));
- SetOnClick(process, lo * POW(10, dp), hi * POW(10, dp), dp, value, Apply, LiveUpdate);
- DWINUI::Draw_Signed_Float(HMI_data.Text_Color, HMI_data.Selected_Color, 3, dp, VALX - dp * DWINUI::fontWidth(DWIN_FONT_MENU), MBASE(CurrentMenu->line()), val);
- }
-
- // Generic onclick event for integer values
- // lo: scaled low limit
- // hi: scaled high limit
- // val: value
- // LiveUpdate: live update function when the encoder changes
- // Apply: update function when the encoder is pressed
- void SetIntOnClick(const int32_t lo, const int32_t hi, const int32_t val, void (*Apply)() /*= nullptr*/, void (*LiveUpdate)() /*= nullptr*/) {
- SetValueOnClick(SetInt, lo, hi, val, Apply, LiveUpdate);
- }
-
- // Generic onclick event for set pointer to 16 bit uinteger values
- // lo: low limit
- // hi: high limit
- // LiveUpdate: live update function when the encoder changes
- // Apply: update function when the encoder is pressed
- void SetPIntOnClick(const int32_t lo, const int32_t hi, void (*Apply)() /*= nullptr*/, void (*LiveUpdate)() /*= nullptr*/) {
- MenuData.P_Int = (int16_t*)static_cast<MenuItemPtrClass*>(CurrentMenu->SelectedItem())->value;
- const int32_t value = *MenuData.P_Int;
- SetValueOnClick(SetPInt, lo, hi, value, Apply, LiveUpdate);
- }
-
- // Generic onclick event for float values
- // process: process id HMI destiny
- // lo: low limit
- // hi: high limit
- // dp: decimal places
- // val: value
- void SetFloatOnClick(const float lo, const float hi, uint8_t dp, const float val, void (*Apply)() /*= nullptr*/, void (*LiveUpdate)() /*= nullptr*/) {
- SetValueOnClick(SetFloat, lo, hi, dp, val, Apply, LiveUpdate);
- }
-
- // Generic onclick event for set pointer to float values
- // lo: low limit
- // hi: high limit
- // LiveUpdate: live update function when the encoder changes
- // Apply: update function when the encoder is pressed
- void SetPFloatOnClick(const float lo, const float hi, uint8_t dp, void (*Apply)() /*= nullptr*/, void (*LiveUpdate)() /*= nullptr*/) {
- MenuData.P_Float = (float*)static_cast<MenuItemPtrClass*>(CurrentMenu->SelectedItem())->value;
- SetValueOnClick(SetPFloat, lo, hi, dp, *MenuData.P_Float, Apply, LiveUpdate);
- }
-
- // HMI Control functions ======================================================
-
- // Generic menu control using the encoder
- void HMI_Menu() {
- EncoderState encoder_diffState = get_encoder_state();
- if (encoder_diffState == ENCODER_DIFF_NO) return;
- if (CurrentMenu) {
- if (encoder_diffState == ENCODER_DIFF_ENTER)
- CurrentMenu->onClick();
- else
- CurrentMenu->onScroll(encoder_diffState == ENCODER_DIFF_CW);
- }
- }
-
- // Get an integer value using the encoder without draw anything
- // lo: low limit
- // hi: high limit
- // Return value:
- // 0 : no change
- // 1 : live change
- // 2 : apply change
- int8_t HMI_GetIntNoDraw(const int32_t lo, const int32_t hi) {
- const int32_t cval = MenuData.Value;
- EncoderState encoder_diffState = Encoder_ReceiveAnalyze();
- if (encoder_diffState != ENCODER_DIFF_NO) {
- if (Apply_Encoder(encoder_diffState, MenuData.Value)) {
- EncoderRate.enabled = false;
- checkkey = Menu;
- return 2;
- }
- LIMIT(MenuData.Value, lo, hi);
- }
- return int8_t(cval != MenuData.Value);
- }
-
- // Get an integer value using the encoder
- // lo: low limit
- // hi: high limit
- // Return value:
- // 0 : no change
- // 1 : live change
- // 2 : apply change
- int8_t HMI_GetInt(const int32_t lo, const int32_t hi) {
- EncoderState encoder_diffState = Encoder_ReceiveAnalyze();
- if (encoder_diffState != ENCODER_DIFF_NO) {
- if (Apply_Encoder(encoder_diffState, MenuData.Value)) {
- EncoderRate.enabled = false;
- DWINUI::Draw_Signed_Int(HMI_data.Text_Color, HMI_data.Background_Color, 4 , VALX, MBASE(CurrentMenu->line()) - 1, MenuData.Value);
- checkkey = Menu;
- return 2;
- }
- LIMIT(MenuData.Value, lo, hi);
- DWINUI::Draw_Signed_Int(HMI_data.Text_Color, HMI_data.Selected_Color, 4 , VALX, MBASE(CurrentMenu->line()) - 1, MenuData.Value);
- return 1;
- }
- return 0;
- }
-
- // Set an integer using the encoder
- void HMI_SetInt() {
- int8_t val = HMI_GetInt(MenuData.MinValue, MenuData.MaxValue);
- switch (val) {
- case 0: return; break;
- case 1: if (MenuData.LiveUpdate) MenuData.LiveUpdate(); break;
- case 2: if (MenuData.Apply) MenuData.Apply(); break;
- }
- }
-
- // Set an integer without drawing
- void HMI_SetIntNoDraw() {
- int8_t val = HMI_GetIntNoDraw(MenuData.MinValue, MenuData.MaxValue);
- switch (val) {
- case 0: return; break;
- case 1: if (MenuData.LiveUpdate) MenuData.LiveUpdate(); break;
- case 2: if (MenuData.Apply) MenuData.Apply(); break;
- }
- }
-
- // Set an integer pointer variable using the encoder
- void HMI_SetPInt() {
- int8_t val = HMI_GetInt(MenuData.MinValue, MenuData.MaxValue);
- switch (val) {
- case 0: return;
- case 1: if (MenuData.LiveUpdate) MenuData.LiveUpdate(); break;
- case 2: *MenuData.P_Int = MenuData.Value; if (MenuData.Apply) MenuData.Apply(); break;
- }
- }
-
- // Get a scaled float value using the encoder
- // dp: decimal places
- // lo: scaled low limit
- // hi: scaled high limit
- // Return value:
- // 0 : no change
- // 1 : live change
- // 2 : apply change
- int8_t HMI_GetFloat(uint8_t dp, int32_t lo, int32_t hi) {
- EncoderState encoder_diffState = Encoder_ReceiveAnalyze();
- if (encoder_diffState != ENCODER_DIFF_NO) {
- if (Apply_Encoder(encoder_diffState, MenuData.Value)) {
- EncoderRate.enabled = false;
- DWINUI::Draw_Signed_Float(HMI_data.Text_Color, HMI_data.Background_Color, 3, dp, VALX - dp * DWINUI::fontWidth(DWIN_FONT_MENU), MBASE(CurrentMenu->line()), MenuData.Value / POW(10, dp));
- checkkey = Menu;
- return 2;
- }
- LIMIT(MenuData.Value, lo, hi);
- DWINUI::Draw_Signed_Float(HMI_data.Text_Color, HMI_data.Selected_Color, 3, dp, VALX - dp * DWINUI::fontWidth(DWIN_FONT_MENU), MBASE(CurrentMenu->line()), MenuData.Value / POW(10, dp));
- return 1;
- }
- return 0;
- }
-
- // Set a scaled float using the encoder
- void HMI_SetFloat() {
- const int8_t val = HMI_GetFloat(MenuData.dp, MenuData.MinValue, MenuData.MaxValue);
- switch (val) {
- case 0: return;
- case 1: if (MenuData.LiveUpdate) MenuData.LiveUpdate(); break;
- case 2: if (MenuData.Apply) MenuData.Apply(); break;
- }
- }
-
- // Set a scaled float pointer variable using the encoder
- void HMI_SetPFloat() {
- const int8_t val = HMI_GetFloat(MenuData.dp, MenuData.MinValue, MenuData.MaxValue);
- switch (val) {
- case 0: return;
- case 1: if (MenuData.LiveUpdate) MenuData.LiveUpdate(); break;
- case 2: *MenuData.P_Float = MenuData.Value / POW(10, MenuData.dp); if (MenuData.Apply) MenuData.Apply(); break;
- }
- }
-
- // Menu Classes ===============================================================
-
- MenuClass::MenuClass() {
- selected = 0;
- topline = 0;
- }
-
- void MenuClass::draw() {
- MenuTitle.draw();
- if (onMenuDraw != nullptr) onMenuDraw(this);
- for (int8_t i = 0; i < MenuItemCount; i++)
- MenuItems[i]->draw(i - topline);
- if (onCursorDraw != nullptr) onCursorDraw(line());
- DWIN_UpdateLCD();
- }
-
- void MenuClass::onScroll(bool dir) {
- int8_t sel = selected;
- if (dir) sel++; else sel--;
- LIMIT(sel, 0, MenuItemCount - 1);
- if (sel != selected) {
- if (onCursorErase != nullptr) onCursorErase(line());
- DWIN_UpdateLCD();
- if ((sel - topline) == TROWS) {
- DWIN_Frame_AreaMove(1, DWIN_SCROLL_UP, MLINE, DWINUI::backcolor, 0, TITLE_HEIGHT + 1, DWIN_WIDTH, STATUS_Y - 1);
- topline++;
- MenuItems[sel]->draw(TROWS - 1);
- }
- if ((sel < topline)) {
- DWIN_Frame_AreaMove(1, DWIN_SCROLL_DOWN, MLINE, DWINUI::backcolor, 0, TITLE_HEIGHT + 1, DWIN_WIDTH, STATUS_Y - 1);
- topline--;
- MenuItems[sel]->draw(0);
- }
- selected = sel;
- if (onCursorDraw != nullptr) onCursorDraw(line());
- DWIN_UpdateLCD();
- }
- }
-
- void MenuClass::onClick() {
- if (MenuItems[selected]->onClick != nullptr) (*MenuItems[selected]->onClick)();
- }
-
- MenuItemClass *MenuClass::SelectedItem() {
- return MenuItems[selected];
- }
-
- MenuItemClass** MenuClass::Items() {
- return MenuItems;
- }
-
- int8_t MenuClass::count() {
- return MenuItemCount;
- };
-
- /* MenuItem Class ===========================================================*/
-
- MenuItemClass::MenuItemClass(uint8_t cicon, const char * const text, void (*ondraw)(MenuItemClass* menuitem, int8_t line), void (*onclick)()) {
- icon = cicon;
- onClick = onclick;
- onDraw = ondraw;
- const uint8_t len = _MIN(sizeof(caption) - 1, strlen(text));
- memcpy(&caption[0], text, len);
- caption[len] = '\0';
- }
-
- MenuItemClass::MenuItemClass(uint8_t cicon, uint8_t id, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, void (*ondraw)(MenuItemClass* menuitem, int8_t line), void (*onclick)()) {
- icon = cicon;
- onClick = onclick;
- onDraw = ondraw;
- caption[0] = '\0';
- frameid = id;
- frame = { x1, y1, x2, y2 };
- }
-
- void MenuItemClass::SetFrame(uint8_t id, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) {
- caption[0] = '\0';
- frameid = id;
- frame = { x1, y1, x2, y2 };
- }
-
- void MenuItemClass::draw(int8_t line) {
- if (line < 0 || line >= TROWS) return;
- if (onDraw != nullptr) (*onDraw)(this, line);
- };
-
- void MenuItemClass::redraw() {
- draw(CurrentMenu->line(this->pos));
- }
-
- MenuItemPtrClass::MenuItemPtrClass(uint8_t cicon, const char * const text, void (*ondraw)(MenuItemClass* menuitem, int8_t line), void (*onclick)(), void* val) : MenuItemClass(cicon, text, ondraw, onclick) {
- value = val;
- };
-
- // Menu auxiliary functions ===================================================
-
- void MenuItemsClear() {
- if (MenuItems == nullptr) return;
- for (int8_t i = 0; i < MenuItemCount; i++) delete MenuItems[i];
- delete[] MenuItems;
- MenuItems = nullptr;
- MenuItemCount = 0;
- MenuItemTotal = 0;
- }
-
- void MenuItemsPrepare(int8_t totalitems) {
- MenuItemsClear();
- MenuItemTotal = totalitems;
- MenuItems = new MenuItemClass*[totalitems];
- }
-
- MenuItemClass* MenuItemsAdd(MenuItemClass* menuitem) {
- MenuItems[MenuItemCount] = menuitem;
- menuitem->pos = MenuItemCount++;
- return menuitem;
- }
-
- MenuItemClass* MenuItemsAdd(uint8_t cicon, const char * const text/*=nullptr*/, void (*ondraw)(MenuItemClass* menuitem, int8_t line)/*=nullptr*/, void (*onclick)()/*=nullptr*/) {
- if (MenuItemCount < MenuItemTotal) {
- MenuItemClass* menuitem = new MenuItemClass(cicon, text, ondraw, onclick);
- return MenuItemsAdd(menuitem);
- }
- else return nullptr;
- }
-
- MenuItemClass* MenuItemsAdd(uint8_t cicon, uint8_t id, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, void (*ondraw)(MenuItemClass* menuitem, int8_t line)/*=nullptr*/, void (*onclick)()/*=nullptr*/) {
- if (MenuItemCount < MenuItemTotal) {
- MenuItemClass* menuitem = new MenuItemClass(cicon, id, x1, y1, x2, y2, ondraw, onclick);
- return MenuItemsAdd(menuitem);
- }
- else return nullptr;
- }
-
- MenuItemClass* MenuItemsAdd(uint8_t cicon, const char * const text, void (*ondraw)(MenuItemClass* menuitem, int8_t line), void (*onclick)(), void* val) {
- if (MenuItemCount < MenuItemTotal) {
- MenuItemClass* menuitem = new MenuItemPtrClass(cicon, text, ondraw, onclick, val);
- return MenuItemsAdd(menuitem);
- }
- else return nullptr;
- }
-
- bool SetMenu(MenuClass* &menu, FSTR_P title, int8_t totalitems) {
- if (!menu) menu = new MenuClass();
- const bool NotCurrent = (CurrentMenu != menu);
- if (NotCurrent) {
- menu->MenuTitle.SetCaption(title);
- MenuItemsPrepare(totalitems);
- }
- return NotCurrent;
- }
-
- void UpdateMenu(MenuClass* &menu) {
- if (!menu) return;
- if (CurrentMenu != menu) {
- PreviousMenu = CurrentMenu;
- CurrentMenu = menu;
- }
- menu->draw();
- }
-
- void ReDrawMenu() { if (CurrentMenu && checkkey==Menu) CurrentMenu->draw(); }
-
- #endif // DWIN_LCD_PROUI
|