/* * "Menu.cpp" implements the "Menuitem" class. */ #include "menu.h" // Class definition Menuitem::Menuitem () {} // Placeholder constructor /* * In the original macro implementation, one could enter "text" as a string in the format: * "\2line1\0line2" for 2 line button labels. In the original implementation, the string * was parsed everytime the button was created. * * Here, we'll parse it into "_text1" and "_text2" when the object is created saving some * work each time the object is used. If the "text" does not begin with the '\2', it's a * one-line label and we set "_text2" to NULL. * * This constructor is used for "MT_FUNC" type objects where the third argument is a * pointer to the function that process the menu item. */ Menuitem::Menuitem ( uint8_t type, const char* text, fptr callback ) { _type = type; // Menu item type _callback = callback; // Save pointer to callback function ParseLabel ( text ); // Parse two line labels } /* * This constructor is used for "MT_MENU" type objects. It's identical to the previous * constructor except the third argument is the address of the sub-menu to be displayed. */ Menuitem::Menuitem ( uint8_t type, const char* text, Menuitem* submenu ) { _type = type; // Menu item type _submenu = submenu; // Save pointer to the sub-menu ParseLabel ( text ); // Parse two line labels } /* * This constructor is for the "MT_BACK" type objects where we need only the type and * a label, but no menu or function pointer. * * It is also used for the "MT_END" type objects where we don't need a label or a pointer. * The "text" argument defaults to "NULL" if it is not specified. Note that if a button * label is supplied we do allow a two-line label, but we really don't expect that to * be used. */ Menuitem::Menuitem ( uint8_t type, const char* text ) { _type = type; // Menu item type ParseLabel ( text ); // Parse two line labels } /* * The "Call" member simply calls the callback function with the specified argument, * which is it's position in the menu list. If the object isn't an "MT_FUNC" type, it * does nothing, ensuring we don't try to call some bogus address. */ void Menuitem::Call ( int num ) { if ( _type == MT_FUNC ) // "Call" only works for "FUNC" type _callback ( num ); } /* * These two functions return the text for line1 and (if a multiline label), the text * for line2 of the label. If it's a single line label, "Text2" returns NULL. */ const char* Menuitem::Text1 () { return _text1; } const char* Menuitem::Text2 () { return _text2; } /* * Return the menu item type ( MT_MENU, MT_FUNC, MT_CLOSE, MT_BACK, or MT_END ) */ uint8_t Menuitem::Type () { return _type; } /* * Returns "true" if the button label has 2 lines; false if it's a single-line label. */ bool Menuitem::isMultiline () { return ( _text2 != NULL ); // If "_text2" isn't "NULL", the answer is "true" } Menuitem* Menuitem::GetSubmenu () // For "MENU" type object, returns the sub-menu pointer { if ( _type == MT_MENU ) // Only allowed for "MENU" types return _submenu; } /* * This private function handles parsing the two-line buttopn labels into "_text1" and * "_text2". If it's a single line label, "_text2" is set to "NULL". */ void Menuitem::ParseLabel ( const char* text ) // Parse two line labels { if ( text == NULL ) // If NULL pointer return; // Nothing to see here! if ( text[0] == '\2' ) // It's a two-line label { _text1 = &text[1]; // Address of 1st line _text2 = &text[1] + strlen ( &text[1] ) + 1; // Address of line 2 } else // Single line label { _text1 = text; // Only one line _text2 = NULL; // and no second line } }