A primitive menu system for touchscreen on the RA8875. This menu is not "finger friendly" and reminds one of the 90's using a Palm.
Dependents: FRDM_RA8875_mPaint PUB_RA8875_mPaint
menu.cpp
00001 00002 #include "menu.h" 00003 00004 //#define DEBUG "menu" 00005 // ... 00006 // INFO("Stuff to show %d", var); // new-line is automatically appended 00007 // 00008 #if (defined(DEBUG) && !defined(TARGET_LPC11U24)) 00009 #define INFO(x, ...) std::printf("[INF %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__); 00010 #define WARN(x, ...) std::printf("[WRN %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__); 00011 #define ERR(x, ...) std::printf("[ERR %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__); 00012 #else 00013 #define INFO(x, ...) 00014 #define WARN(x, ...) 00015 #define ERR(x, ...) 00016 #define HexDump(a, b, c) 00017 #endif 00018 00019 Menu::~Menu() 00020 { 00021 } 00022 00023 Menu::Menu(RA8875 & _lcd, menu_item_t * _menu, color_t fg, color_t bg, color_t hl) 00024 : lcd(_lcd), pTopMenu(_menu), pExpanded(0), isShowing(false), 00025 menuForeground(fg), menuBackground(bg), menuHighlight(hl) 00026 { 00027 } 00028 00029 void Menu::init() 00030 { 00031 lcd.SetLayerMode(RA8875::TransparentMode); 00032 lcd.SetLayerTransparency(0, 7); 00033 Show(); 00034 } 00035 00036 void Menu::SetColors(color_t fg, color_t bg, color_t hl) 00037 { 00038 menuForeground = fg; 00039 menuBackground = bg; 00040 menuHighlight = hl; 00041 } 00042 00043 bool Menu::_isTouched(menu_item_t * pMenu, rect_t r, point_t p, menu_item_t ** menuTouched) 00044 { 00045 while (pMenu->menuText) { 00046 r.p2.x += lcd.fontwidth() * (strlen(pMenu->menuText) + strlen(" ")); 00047 INFO("Is (%3d,%3d) in (%3d,%3d)-(%3d,%3d) %s", p.x, p.y, r.p1.x, r.p1.y, r.p2.x, r.p2.y, pMenu->menuText); 00048 if (lcd.Intersect(r, p)) { 00049 *menuTouched = pMenu; 00050 return true; 00051 } 00052 // if (!isShowing) // Activating this traps the menu activation to the first entry only. 00053 // break; // Disabling this permits anything on the top-line 00054 if (isShowing && pMenu->child && pExpanded == pMenu) { 00055 rect_t rectChild = r; 00056 INFO(" to child %s", pExpanded->child->menuText); 00057 rectChild.p1.x += lcd.fontwidth(); 00058 rectChild.p1.y += lcd.fontheight(); 00059 rectChild.p2.x = rectChild.p1.x; 00060 rectChild.p2.y = rectChild.p1.y + lcd.fontheight(); 00061 if(_isTouched(pMenu->child, rectChild, p, menuTouched)) // walk the child items 00062 return true; 00063 } 00064 r.p1.x = r.p2.x; 00065 pMenu++; 00066 } 00067 return false; 00068 } 00069 00070 bool Menu::HandledTouch(point_t p, TouchCode_t touchcode) 00071 { 00072 rect_t r; 00073 menu_item_t * pTouchedMenu = NULL; 00074 bool handled = false; 00075 00076 r.p1.x = r.p1.y = r.p2.x = 0; 00077 r.p2.y = lcd.fontheight(); 00078 00079 if (_isTouched(pTopMenu, r, p, &pTouchedMenu)) { 00080 INFO("Touched %s. touchcode:%d", pTouchedMenu->menuText, touchcode); 00081 if (!isShowing && touchcode == touch) { 00082 Show(); 00083 } 00084 post_fnc_action_t action = no_action; 00085 switch (touchcode) { 00086 case touch: 00087 if (pTouchedMenu->fncPress) { 00088 action = pTouchedMenu->fncPress(pTouchedMenu->param); 00089 } 00090 if (pTouchedMenu->child) { 00091 Expand(pTouchedMenu); 00092 } 00093 break; 00094 case held: 00095 if (pTouchedMenu->fncHeld) { 00096 action = pTouchedMenu->fncHeld(pTouchedMenu->param); 00097 } 00098 break; 00099 case release: 00100 if (pTouchedMenu->fncRelease) { 00101 action = pTouchedMenu->fncRelease(pTouchedMenu->param); 00102 } 00103 break; 00104 default: 00105 break; 00106 } 00107 if (action == close_menu) { 00108 INFO("Hide it"); 00109 Hide(); 00110 } 00111 handled = true; 00112 } 00113 return handled; 00114 } 00115 00116 bool Menu::_GetMenuRect(menu_item_t * pMenu, menu_item_t * needle, rect_t * pRect) 00117 { 00118 rect_t r; 00119 00120 if (needle->menuText == NULL) 00121 return false; 00122 r.p1.x = r.p1.y = r.p2.x = 0; 00123 r.p2.y = lcd.fontheight(); 00124 while (pMenu->menuText) { 00125 r.p2.x += lcd.fontwidth() * (strlen(pMenu->menuText) + strlen(" ")); 00126 if (pMenu == needle) { 00127 *pRect = r; 00128 return true; 00129 } 00130 r.p1.x = r.p2.x; 00131 pMenu++; 00132 } 00133 return false; 00134 } 00135 00136 void Menu::_Rect(rect_t r, color_t c, fill_t fill) 00137 { 00138 r.p2.x--; 00139 r.p2.y--; 00140 lcd.rect(r, c, fill); 00141 } 00142 00143 00144 void Menu::Expand(menu_item_t * thisMenu) 00145 { 00146 rect_t r; 00147 bool same = (pExpanded == thisMenu) ? true : false; 00148 INFO("Expand(%s)", thisMenu->menuText); 00149 if (pExpanded) { // need to hide this one first 00150 INFO(" Hiding children of %s. this=%s, same=%d", pExpanded->menuText, thisMenu->menuText, same); 00151 _GetMenuRect(pTopMenu, pExpanded, &r); 00152 _Rect(r, menuForeground); 00153 r.p1.x += lcd.fontwidth(); 00154 r.p1.y += lcd.fontheight(); 00155 r.p2.x = r.p1.x; 00156 r.p2.y = r.p1.y + lcd.fontheight(); 00157 _ShowMenu_Helper(pExpanded->child, r, false); 00158 pExpanded = NULL; 00159 } 00160 if (!same && _GetMenuRect(pTopMenu, thisMenu, &r)) { 00161 INFO(" Expanding to children of %s.", thisMenu->menuText); 00162 _Rect(r, menuHighlight); 00163 // index in a little, then down a row 00164 r.p1.x += lcd.fontwidth(); 00165 r.p1.y += lcd.fontheight(); 00166 r.p2.x = r.p1.x; 00167 r.p2.y = r.p1.y + lcd.fontheight(); 00168 _ShowMenu_Helper(thisMenu->child, r); 00169 pExpanded = thisMenu; 00170 } 00171 } 00172 00173 void Menu::Show() 00174 { 00175 rect_t r; 00176 INFO("Show()"); 00177 lcd.SelectDrawingLayer(MENUS); 00178 lcd.SetLayerTransparency(7, 0); // emphasize the menu 00179 lcd.SetTextCursor(0,0); 00180 r.p1.x = r.p1.y = r.p2.x = 0; 00181 r.p2.y = lcd.fontheight(); 00182 menu_item_t * pMenu = pTopMenu; 00183 _ShowMenu_Helper(pMenu, r); 00184 isShowing = true; 00185 } 00186 00187 void Menu::_ShowMenu_Helper(menu_item_t * pMenu, rect_t r, bool show) 00188 { 00189 while (pMenu->menuText) { 00190 lcd.SetTextCursor(r.p1.x, r.p1.y); 00191 r.p2.x += lcd.fontwidth() * (strlen(pMenu->menuText) + strlen(" ")); 00192 if (show) { 00193 INFO("(%3d,%3d)-(%3d,%3d) %s", r.p1.x, r.p1.y, r.p2.x, r.p2.y, pMenu->menuText); 00194 lcd.foreground(menuForeground); 00195 lcd.printf(" %s ", pMenu->menuText); 00196 _Rect(r, menuForeground); 00197 } else { 00198 INFO("HIDE (%3d,%3d)-(%3d,%3d) %s", r.p1.x, r.p1.y, r.p2.x, r.p2.y, pMenu->menuText); 00199 _Rect(r, menuBackground, FILL); 00200 } 00201 r.p1.x = r.p2.x; 00202 pMenu++; 00203 } 00204 isShowing = true; 00205 } 00206 00207 void Menu::Hide() 00208 { 00209 INFO("Hide()"); 00210 if (pExpanded) 00211 Expand(pExpanded); // hides this menu 00212 lcd.SelectDrawingLayer(CANVAS); 00213 isShowing = false; 00214 lcd.SetLayerTransparency(0, 7); // emphasize the canvas 00215 } 00216
Generated on Sat Jul 16 2022 06:37:36 by 1.7.2