137 lines
3.9 KiB
C++
137 lines
3.9 KiB
C++
![]() |
/*
|
||
|
* "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
|
||
|
}
|
||
|
}
|