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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers menu.h Source File

menu.h

00001 
00002 #ifndef MENU_H
00003 #define MENU_H
00004 
00005 #include "RA8875.h"
00006 
00007 #define CANVAS  0
00008 #define MENUS   1
00009 
00010 /// A very simple menu system, for use with the RA8875 display library.
00011 ///
00012 /// This will seem like a "throwback" to the 90's. As designed, it is 
00013 /// not for "finger" but for stylus, since menu picks are the size of 
00014 /// the selected font. The user could change the font size, and the
00015 /// menu should resize accordingly.
00016 ///
00017 /// The user defines some simple arrays of structures which define
00018 /// menu picks.
00019 ///
00020 /// The menu is created horizontally on the screen, starting in the top-
00021 /// left.
00022 ///
00023 /// Submenus, of which only 1 submenu level is supported, are also
00024 /// shown horizontally starting directly beneath the top-level (and 
00025 /// 1 char to the right). Care should be taken if it may cause wordwrap,
00026 /// as this is not supported (and the behavior has not been tested).
00027 ///
00028 /// @note When using this menu system, it uses the two-layer mode of the 
00029 /// RA8875 display, which limits the display to those with not more
00030 /// than 480x272 pixels in size.
00031 ///
00032 /// @code
00033 /// // +----------------------------------------------------+
00034 /// // | File | Pen | Tools                                 |
00035 /// // +----------------------------------------------------+ fontheight()
00036 /// // |                                                    |
00037 /// // |                                                    |
00038 /// // |                                                    |
00039 /// // |                                                    |
00040 /// // |                                                    |
00041 /// // |                                                    |
00042 /// // |                                                    |
00043 /// // |                                                    |
00044 /// // |                                                    |
00045 /// // |                                                    |
00046 /// // |                                                    |
00047 /// // +----------------------------------------------------+ 
00048 ///
00049 /// // +----------------------------------------------------+
00050 /// // | File | Pen | Tools                                 |
00051 /// // +----------------------------------------------------+
00052 /// // || New... | Save... | Save all | Calibrate | Reset | |
00053 /// // |                                                    |
00054 ///
00055 /// // +----------------------------------------------------+
00056 /// // | File | Pen | Tools                                 |
00057 /// // +----------------------------------------------------+
00058 /// // |       | 1 pix | 2 pix | 4 pix | ...                |
00059 /// //
00060 /// @endcode
00061 ///
00062 class Menu
00063 {
00064 public:
00065     /// When menu functions are called, they can return a command
00066     /// to the menu system to determine what it should do - if
00067     /// anything.
00068     ///
00069     typedef enum 
00070     {
00071         no_action,          ///< take no action on return.
00072         close_menu,         ///< close the menu immediately.
00073     } post_fnc_action_t;
00074     
00075     /// Each menu item is a structure as defined here. An array
00076     /// of these create multple entries on that menu level.
00077     /// The array must be terminated by a NULL entry.
00078     ///
00079     typedef struct menu_item_t
00080     {
00081         char * menuText;                            ///< text to show (keep it brief!)
00082         post_fnc_action_t (* fncPress)(uint32_t);   ///< function to call "on touch", or NULL
00083         post_fnc_action_t (* fncHeld)(uint32_t);    ///< function to call "on held", or NULL
00084         post_fnc_action_t (* fncRelease)(uint32_t); ///< function to call "on release", or NULL
00085         uint32_t param;                             ///< parameter to pass to the function.
00086         menu_item_t * child;                        ///< child menu, if this is an upper menu.
00087     } menu_item_t;
00088 
00089     /// The constructor for the menu class.
00090     ///
00091     /// This creates the instance of the menu. The initialization is done
00092     /// later.
00093     ///
00094     /// @code
00095     /// #include "menu.h"
00096     /// ...
00097     /// Menu::menu_item_t menudata[] = {
00098     ///     // Text    touch held  release  param childmenu
00099     ///     { "File",  File, NULL, NULL,     0, file_menu },
00100     ///     { "Pen",   NULL, NULL, NULL,     0, pen_menu },
00101     ///     { "Tools", NULL, NULL, NULL,     0, tools_menu },
00102     ///     { "Hide",  NULL, NULL, HideMenu, 0, NULL },
00103     ///     { NULL,    NULL, NULL, NULL,     0, NULL }, // NULL terminator
00104     /// };
00105     ///
00106     /// Menu menu(lcd, menudata);
00107     ///
00108     /// void main() {
00109     ///    menu.init();
00110     ///    for (;;) {
00111     ///        point_t p;
00112     ///        TouchCode_t touchcode = lcd.TouchPanelReadable(&p);
00113     ///
00114     ///        if (touchcode != no_touch) {
00115     ///            bool menuHandledIt = menu.HandledTouch(p, touchcode);
00116     ///            if (menuHandledIt) {
00117     ///                // menu handled it
00118     ///            } else {
00119     ///                // user code here for touch in non-menu areas.
00120     ///            }
00121     ///        }
00122     ///    }
00123     /// }
00124     /// @endcode
00125     ///
00126     /// @param lcd is a reference to the RA8875 display object. @see RA8875.
00127     /// @param menu is a pointer to the top-level menu list. @see menu_item_t.
00128     /// @param fg is the foreground color for the menu.
00129     /// @param bg is the background color for the menu.
00130     /// @param hl is the highlight color for the menu.
00131     ///
00132     Menu(RA8875 & lcd, menu_item_t * menu, color_t fg = BrightBlue, color_t bg = Black, color_t hl = Red);
00133     
00134     /// Destructure for the menu class.
00135     ~Menu();
00136     
00137     /// initialize the menu system to get it started.
00138     ///
00139     /// This sets up the RA8875 display and layering for the menu system.
00140     ///
00141     void init(void);
00142     
00143     /// This is the main "run-time" entry point. 
00144     ///
00145     /// Every touch should call this and pass in the point and touchcode.
00146     /// If the menu can handle this event, it will indicate so the
00147     /// return code.
00148     ///
00149     /// @param p is the point provided to this method indicating where
00150     ///         the last touch was detected.
00151     /// @param touchcode indicates the type of touch, and permits easy
00152     ///         handling of touch, held, release events.
00153     /// @returns true if the touch was handled by the menu system.
00154     /// 
00155     bool HandledTouch(point_t p, TouchCode_t touchcode);
00156     
00157     /// Force show the menu.
00158     ///
00159     void Show();
00160     
00161     /// Force hide the menu.
00162     ///
00163     void Hide();
00164     
00165     /// Indicates if the menu is currently visible.
00166     ///
00167     /// @returns true if the menu is visible.
00168     ///
00169     bool isVisible() { return isShowing; }
00170 
00171 private:
00172     /// This method expands a top-level menu to show the lower.
00173     /// 
00174     /// It also will first high any previously open submenu.
00175     ///
00176     /// @param menu is a pointer to the menu to expand if it has child menus.
00177     ///
00178     void Expand(menu_item_t * menu);
00179     void SetColors(color_t fg, color_t bg, color_t hl);
00180     bool _isTouched(menu_item_t * pTraverse, rect_t r, point_t p, menu_item_t ** menuTouched);
00181     bool _GetMenuRect(menu_item_t * pMenu, menu_item_t * needle, rect_t * pRect);
00182     void _ShowMenu_Helper(menu_item_t * pMenu, rect_t r, bool show = true);
00183     void _Rect(rect_t r, color_t c, fill_t fill = NOFILL);
00184     RA8875 & lcd;
00185     menu_item_t * pTopMenu;
00186     menu_item_t * pExpanded;    // points to an expanded menu
00187     bool isShowing;
00188     color_t menuForeground;
00189     color_t menuBackground;
00190     color_t menuHighlight;
00191 };
00192 
00193 #endif // MENU_H