4 errors

Dependencies:   KS0108_PCF8574 mbed

Committer:
GuiTwo
Date:
Wed Sep 05 07:21:59 2012 +0000
Revision:
0:936f1c020120
With KS0108;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
GuiTwo 0:936f1c020120 1 #include "mbed.h"
GuiTwo 0:936f1c020120 2 #include "include/menbedNavigator.h"
GuiTwo 0:936f1c020120 3 #include "include/menbedButtonEvent.h"
GuiTwo 0:936f1c020120 4 #include "include/menbedMenuMessage.h"
GuiTwo 0:936f1c020120 5 #include "include/menbedMenu.h"
GuiTwo 0:936f1c020120 6 #include <cstdio>
GuiTwo 0:936f1c020120 7
GuiTwo 0:936f1c020120 8 extern void toggleLed3();
GuiTwo 0:936f1c020120 9
GuiTwo 0:936f1c020120 10 MenbedNavigator::MenbedNavigator(MenbedMenu *rootMenu,
GuiTwo 0:936f1c020120 11 MenbedDisplayer *displayer) :
GuiTwo 0:936f1c020120 12 activeMenu(rootMenu), displayer(displayer)
GuiTwo 0:936f1c020120 13 {
GuiTwo 0:936f1c020120 14 selectedItemIndex = -1;
GuiTwo 0:936f1c020120 15 topOfScreenItemIndex = 0;
GuiTwo 0:936f1c020120 16 paramEditMode = false;
GuiTwo 0:936f1c020120 17
GuiTwo 0:936f1c020120 18 numLines = displayer->getDisplay()->getLines();
GuiTwo 0:936f1c020120 19 lineLength = displayer->getDisplay()->getLineLength();
GuiTwo 0:936f1c020120 20 }
GuiTwo 0:936f1c020120 21
GuiTwo 0:936f1c020120 22 void MenbedNavigator::updateDisplay()
GuiTwo 0:936f1c020120 23 {
GuiTwo 0:936f1c020120 24 MenbedMenuMessage menuMsg (numLines, lineLength);
GuiTwo 0:936f1c020120 25
GuiTwo 0:936f1c020120 26 printMenu (menuMsg.text);
GuiTwo 0:936f1c020120 27 menuMsg.showUpArrow = (topOfScreenItemIndex >= 1);
GuiTwo 0:936f1c020120 28 menuMsg.showDownArrow = (topOfScreenItemIndex + numLines < (int)(activeMenu->menuItems.size()));
GuiTwo 0:936f1c020120 29
GuiTwo 0:936f1c020120 30 displayer->update (&menuMsg);
GuiTwo 0:936f1c020120 31 }
GuiTwo 0:936f1c020120 32
GuiTwo 0:936f1c020120 33
GuiTwo 0:936f1c020120 34 void MenbedNavigator::handleButtonEvent (MenbedButtonEvent buttonEvent)
GuiTwo 0:936f1c020120 35 {
GuiTwo 0:936f1c020120 36 numButtons = buttonEvent.numButtons;
GuiTwo 0:936f1c020120 37
GuiTwo 0:936f1c020120 38 switch (buttonEvent.name)
GuiTwo 0:936f1c020120 39 {
GuiTwo 0:936f1c020120 40 case MenbedButtonEvent::ButtonSelect: // Select
GuiTwo 0:936f1c020120 41 if (!paramEditMode && (buttonEvent.action ==
GuiTwo 0:936f1c020120 42 MenbedButtonEvent::BUTTON_ACTION_RELEASED_SHORT))
GuiTwo 0:936f1c020120 43 selectItem();
GuiTwo 0:936f1c020120 44 else if (paramEditMode && (buttonEvent.action ==
GuiTwo 0:936f1c020120 45 MenbedButtonEvent::BUTTON_ACTION_RELEASED_SHORT))
GuiTwo 0:936f1c020120 46 saveParam();
GuiTwo 0:936f1c020120 47 else if ((numButtons < 4) &&
GuiTwo 0:936f1c020120 48 paramEditMode && (buttonEvent.action ==
GuiTwo 0:936f1c020120 49 MenbedButtonEvent::BUTTON_ACTION_HELD_LONG))
GuiTwo 0:936f1c020120 50 restoreParam();
GuiTwo 0:936f1c020120 51 else if ((numButtons < 4) && !paramEditMode &&
GuiTwo 0:936f1c020120 52 (buttonEvent.action ==
GuiTwo 0:936f1c020120 53 MenbedButtonEvent::BUTTON_ACTION_HELD_LONG))
GuiTwo 0:936f1c020120 54 gotoParent();
GuiTwo 0:936f1c020120 55 break;
GuiTwo 0:936f1c020120 56
GuiTwo 0:936f1c020120 57 case MenbedButtonEvent::ButtonDown:
GuiTwo 0:936f1c020120 58 if (paramEditMode &&
GuiTwo 0:936f1c020120 59 (buttonEvent.action == MenbedButtonEvent::BUTTON_ACTION_PUSHED))
GuiTwo 0:936f1c020120 60 decParam();
GuiTwo 0:936f1c020120 61 else if (!paramEditMode &&
GuiTwo 0:936f1c020120 62 (buttonEvent.action == MenbedButtonEvent::BUTTON_ACTION_PUSHED))
GuiTwo 0:936f1c020120 63 moveDown();
GuiTwo 0:936f1c020120 64 break;
GuiTwo 0:936f1c020120 65
GuiTwo 0:936f1c020120 66 case MenbedButtonEvent::ButtonUp:
GuiTwo 0:936f1c020120 67 if (numButtons > 2)
GuiTwo 0:936f1c020120 68 {
GuiTwo 0:936f1c020120 69 if (paramEditMode &&
GuiTwo 0:936f1c020120 70 (buttonEvent.action == MenbedButtonEvent::BUTTON_ACTION_PUSHED))
GuiTwo 0:936f1c020120 71 incParam();
GuiTwo 0:936f1c020120 72 else if (!paramEditMode &&
GuiTwo 0:936f1c020120 73 (buttonEvent.action == MenbedButtonEvent::BUTTON_ACTION_PUSHED))
GuiTwo 0:936f1c020120 74 moveUp();
GuiTwo 0:936f1c020120 75 }
GuiTwo 0:936f1c020120 76 break;
GuiTwo 0:936f1c020120 77
GuiTwo 0:936f1c020120 78 case MenbedButtonEvent::ButtonCancel:
GuiTwo 0:936f1c020120 79 if (numButtons > 3)
GuiTwo 0:936f1c020120 80 {
GuiTwo 0:936f1c020120 81 if (paramEditMode &&
GuiTwo 0:936f1c020120 82 (buttonEvent.action == MenbedButtonEvent::BUTTON_ACTION_PUSHED))
GuiTwo 0:936f1c020120 83 restoreParam();
GuiTwo 0:936f1c020120 84 else if (!paramEditMode &&
GuiTwo 0:936f1c020120 85 (buttonEvent.action == MenbedButtonEvent::BUTTON_ACTION_PUSHED))
GuiTwo 0:936f1c020120 86 gotoParent();
GuiTwo 0:936f1c020120 87 }
GuiTwo 0:936f1c020120 88 break;
GuiTwo 0:936f1c020120 89 }
GuiTwo 0:936f1c020120 90
GuiTwo 0:936f1c020120 91 updateDisplay();
GuiTwo 0:936f1c020120 92 //menuRefresh_refreshed();
GuiTwo 0:936f1c020120 93 }
GuiTwo 0:936f1c020120 94
GuiTwo 0:936f1c020120 95
GuiTwo 0:936f1c020120 96 void MenbedNavigator::selectItem()
GuiTwo 0:936f1c020120 97 {
GuiTwo 0:936f1c020120 98 MenbedMenu **childMenuPtr;
GuiTwo 0:936f1c020120 99 MenbedMenu *childMenu;
GuiTwo 0:936f1c020120 100
GuiTwo 0:936f1c020120 101 if ((selectedItemIndex < 0) ||
GuiTwo 0:936f1c020120 102 (selectedItemIndex >= (int)(activeMenu->menuItems.size())))
GuiTwo 0:936f1c020120 103 return;
GuiTwo 0:936f1c020120 104
GuiTwo 0:936f1c020120 105 // If it exists, execute the function associated with the menu item
GuiTwo 0:936f1c020120 106 if (activeMenu->menuItems[selectedItemIndex]->selFcn != NULL)
GuiTwo 0:936f1c020120 107 activeMenu->menuItems[selectedItemIndex]->selFcn();
GuiTwo 0:936f1c020120 108
GuiTwo 0:936f1c020120 109 // Show the child menu associated with the menu item. Initially, the first
GuiTwo 0:936f1c020120 110 // item in the child menu is placed at the top of the screen, but is it
GuiTwo 0:936f1c020120 111 // left unselected.
GuiTwo 0:936f1c020120 112 childMenuPtr = activeMenu->menuItems[selectedItemIndex]->childMenu;
GuiTwo 0:936f1c020120 113 if (childMenuPtr != NULL)
GuiTwo 0:936f1c020120 114 {
GuiTwo 0:936f1c020120 115 childMenu = *(activeMenu->menuItems[selectedItemIndex]->childMenu);
GuiTwo 0:936f1c020120 116
GuiTwo 0:936f1c020120 117 if (!activeMenu->menuItems[selectedItemIndex]->childMenuIsAncestor)
GuiTwo 0:936f1c020120 118 {
GuiTwo 0:936f1c020120 119 childMenu->parentMenu = activeMenu;
GuiTwo 0:936f1c020120 120 childMenu->parentSelectedItemIndex = selectedItemIndex;
GuiTwo 0:936f1c020120 121 childMenu->parentTopOfScreenItemIndex = topOfScreenItemIndex;
GuiTwo 0:936f1c020120 122 }
GuiTwo 0:936f1c020120 123 else
GuiTwo 0:936f1c020120 124 childMenu->parentMenu = NULL;
GuiTwo 0:936f1c020120 125
GuiTwo 0:936f1c020120 126 activeMenu = childMenu;
GuiTwo 0:936f1c020120 127 topOfScreenItemIndex = 0;
GuiTwo 0:936f1c020120 128 selectedItemIndex = -1;
GuiTwo 0:936f1c020120 129 }
GuiTwo 0:936f1c020120 130 // Otherwise, if the current menu item has a parameter that can be modified,
GuiTwo 0:936f1c020120 131 // we switch to the parameter editing mode.
GuiTwo 0:936f1c020120 132 else if ((activeMenu->menuItems[selectedItemIndex]->param != NULL) &&
GuiTwo 0:936f1c020120 133 (activeMenu->menuItems[selectedItemIndex]->param->inc() != 0))
GuiTwo 0:936f1c020120 134 {
GuiTwo 0:936f1c020120 135 // All incrementing and decrementing of the parameter actually happens
GuiTwo 0:936f1c020120 136 // to a shadow variable in the param structure named tempValue. The
GuiTwo 0:936f1c020120 137 // parameter value used by the other parts of the system is not updated
GuiTwo 0:936f1c020120 138 // until the user is done editing the parameter.
GuiTwo 0:936f1c020120 139 activeMenu->menuItems[selectedItemIndex]->param->initVal =
GuiTwo 0:936f1c020120 140 activeMenu->menuItems[selectedItemIndex]->param->getVal();
GuiTwo 0:936f1c020120 141 activeMenu->menuItems[selectedItemIndex]->param->tempVal =
GuiTwo 0:936f1c020120 142 activeMenu->menuItems[selectedItemIndex]->param->initVal;
GuiTwo 0:936f1c020120 143 paramEditMode = true;
GuiTwo 0:936f1c020120 144 }
GuiTwo 0:936f1c020120 145 }
GuiTwo 0:936f1c020120 146
GuiTwo 0:936f1c020120 147
GuiTwo 0:936f1c020120 148 void MenbedNavigator::gotoParent()
GuiTwo 0:936f1c020120 149 {
GuiTwo 0:936f1c020120 150 if (activeMenu->parentMenu == NULL)
GuiTwo 0:936f1c020120 151 return;
GuiTwo 0:936f1c020120 152
GuiTwo 0:936f1c020120 153 selectedItemIndex = activeMenu->parentSelectedItemIndex;
GuiTwo 0:936f1c020120 154 topOfScreenItemIndex = activeMenu->parentTopOfScreenItemIndex;
GuiTwo 0:936f1c020120 155 activeMenu = activeMenu->parentMenu;
GuiTwo 0:936f1c020120 156 }
GuiTwo 0:936f1c020120 157
GuiTwo 0:936f1c020120 158
GuiTwo 0:936f1c020120 159 void MenbedNavigator::moveUp()
GuiTwo 0:936f1c020120 160 {
GuiTwo 0:936f1c020120 161 // If we're already at the top of the menu, do nothing
GuiTwo 0:936f1c020120 162 if (selectedItemIndex <= -1)
GuiTwo 0:936f1c020120 163 return;
GuiTwo 0:936f1c020120 164 // If the top item of the menu is already selected, we send a NOP message
GuiTwo 0:936f1c020120 165 // which deselects the top line and displays the down arrow if the menu
GuiTwo 0:936f1c020120 166 // contains more items than can fit on the screen. In effect, this allows
GuiTwo 0:936f1c020120 167 // the user to deselect all menu items which adds a nice look to the system.
GuiTwo 0:936f1c020120 168 else if (selectedItemIndex == 0)
GuiTwo 0:936f1c020120 169 selectedItemIndex = -1;
GuiTwo 0:936f1c020120 170 // If the currently selected menu item is the also the one at the top of the
GuiTwo 0:936f1c020120 171 // screen, we need to scroll the screen down and add the item above the
GuiTwo 0:936f1c020120 172 // currently selected one to the top of the screen.
GuiTwo 0:936f1c020120 173 else if (selectedItemIndex == topOfScreenItemIndex)
GuiTwo 0:936f1c020120 174 {
GuiTwo 0:936f1c020120 175 selectedItemIndex--;
GuiTwo 0:936f1c020120 176 topOfScreenItemIndex--;
GuiTwo 0:936f1c020120 177 }
GuiTwo 0:936f1c020120 178 // The selected item is not the top item on the screen. All we need to do
GuiTwo 0:936f1c020120 179 // is select the item above the currently selected item.
GuiTwo 0:936f1c020120 180 else
GuiTwo 0:936f1c020120 181 selectedItemIndex--;
GuiTwo 0:936f1c020120 182 }
GuiTwo 0:936f1c020120 183
GuiTwo 0:936f1c020120 184
GuiTwo 0:936f1c020120 185
GuiTwo 0:936f1c020120 186 void MenbedNavigator::moveDown()
GuiTwo 0:936f1c020120 187 {
GuiTwo 0:936f1c020120 188 // If the last item of the menu is already selected, our behavior depends
GuiTwo 0:936f1c020120 189 // on how many buttons are present. If there is no up button, we cycle
GuiTwo 0:936f1c020120 190 // back to the top of the menu. Otherwise, if an up button is present,
GuiTwo 0:936f1c020120 191 // we do nothing.
GuiTwo 0:936f1c020120 192 if (selectedItemIndex >= ((int)(activeMenu->menuItems.size()) - 1))
GuiTwo 0:936f1c020120 193 {
GuiTwo 0:936f1c020120 194 if (numButtons < 3)
GuiTwo 0:936f1c020120 195 {
GuiTwo 0:936f1c020120 196 selectedItemIndex = -1;
GuiTwo 0:936f1c020120 197 topOfScreenItemIndex = 0;
GuiTwo 0:936f1c020120 198 }
GuiTwo 0:936f1c020120 199 else
GuiTwo 0:936f1c020120 200 ;
GuiTwo 0:936f1c020120 201 }
GuiTwo 0:936f1c020120 202 // If the menu item displayed at the bottom of the screen is already
GuiTwo 0:936f1c020120 203 // selected, we will need to scroll the screen up to make room for a new
GuiTwo 0:936f1c020120 204 // line at the bottom of the screen.
GuiTwo 0:936f1c020120 205 else if (selectedItemIndex ==
GuiTwo 0:936f1c020120 206 (topOfScreenItemIndex + numLines - 1))
GuiTwo 0:936f1c020120 207 {
GuiTwo 0:936f1c020120 208 selectedItemIndex++;
GuiTwo 0:936f1c020120 209 topOfScreenItemIndex++;
GuiTwo 0:936f1c020120 210 }
GuiTwo 0:936f1c020120 211 // Otherwise, if the currently selected menu item is now the one displayed
GuiTwo 0:936f1c020120 212 // at the bottom of the screen, we simply change which of the visible items
GuiTwo 0:936f1c020120 213 // is highlighted.
GuiTwo 0:936f1c020120 214 else
GuiTwo 0:936f1c020120 215 selectedItemIndex++;
GuiTwo 0:936f1c020120 216
GuiTwo 0:936f1c020120 217 }
GuiTwo 0:936f1c020120 218
GuiTwo 0:936f1c020120 219
GuiTwo 0:936f1c020120 220 void MenbedNavigator::incParam()
GuiTwo 0:936f1c020120 221 {
GuiTwo 0:936f1c020120 222 float inc;
GuiTwo 0:936f1c020120 223 float tempVal;
GuiTwo 0:936f1c020120 224
GuiTwo 0:936f1c020120 225 if (paramEditMode != true)
GuiTwo 0:936f1c020120 226 return;
GuiTwo 0:936f1c020120 227
GuiTwo 0:936f1c020120 228 inc = activeMenu->menuItems[selectedItemIndex]->param->inc();
GuiTwo 0:936f1c020120 229
GuiTwo 0:936f1c020120 230 // Initialize our own local copy of the parameter's temporary value. We do
GuiTwo 0:936f1c020120 231 // this so that we can more easily check for violations of the allowed min
GuiTwo 0:936f1c020120 232 // and max values.
GuiTwo 0:936f1c020120 233 tempVal = activeMenu->menuItems[selectedItemIndex]->param->tempVal;
GuiTwo 0:936f1c020120 234 tempVal += inc;
GuiTwo 0:936f1c020120 235
GuiTwo 0:936f1c020120 236 // Check the bounds on the parameter.
GuiTwo 0:936f1c020120 237 if (tempVal > activeMenu->menuItems[selectedItemIndex]->param->max())
GuiTwo 0:936f1c020120 238 tempVal = activeMenu->menuItems[selectedItemIndex]->param->max();
GuiTwo 0:936f1c020120 239 else if (tempVal < activeMenu->menuItems[selectedItemIndex]->param->min())
GuiTwo 0:936f1c020120 240 tempVal = activeMenu->menuItems[selectedItemIndex]->param->min();
GuiTwo 0:936f1c020120 241
GuiTwo 0:936f1c020120 242 // Assign the local temp. value back to the temporary value in the active
GuiTwo 0:936f1c020120 243 // parameter structue.
GuiTwo 0:936f1c020120 244 activeMenu->menuItems[selectedItemIndex]->param->tempVal = tempVal;
GuiTwo 0:936f1c020120 245
GuiTwo 0:936f1c020120 246 // If the parameter is configured to produce live updates, call the
GuiTwo 0:936f1c020120 247 // finalValFcn.
GuiTwo 0:936f1c020120 248 if (activeMenu->menuItems[selectedItemIndex]->param->liveUpdate())
GuiTwo 0:936f1c020120 249 activeMenu->menuItems[selectedItemIndex]->param->setVal(tempVal);
GuiTwo 0:936f1c020120 250 }
GuiTwo 0:936f1c020120 251
GuiTwo 0:936f1c020120 252
GuiTwo 0:936f1c020120 253 void MenbedNavigator::decParam()
GuiTwo 0:936f1c020120 254 {
GuiTwo 0:936f1c020120 255 float inc;
GuiTwo 0:936f1c020120 256 float tempVal;
GuiTwo 0:936f1c020120 257
GuiTwo 0:936f1c020120 258 if (paramEditMode != true)
GuiTwo 0:936f1c020120 259 return;
GuiTwo 0:936f1c020120 260
GuiTwo 0:936f1c020120 261 inc = activeMenu->menuItems[selectedItemIndex]->param->inc();
GuiTwo 0:936f1c020120 262
GuiTwo 0:936f1c020120 263 // Initialize our own local copy of the parameter's temporary value. We do
GuiTwo 0:936f1c020120 264 // this so that we can more easily check for violations of the allowed min
GuiTwo 0:936f1c020120 265 // and max values.
GuiTwo 0:936f1c020120 266 tempVal = activeMenu->menuItems[selectedItemIndex]->param->tempVal;
GuiTwo 0:936f1c020120 267 tempVal -= inc;
GuiTwo 0:936f1c020120 268
GuiTwo 0:936f1c020120 269 // Check the bounds on the parameter.
GuiTwo 0:936f1c020120 270 if (tempVal > activeMenu->menuItems[selectedItemIndex]->param->max())
GuiTwo 0:936f1c020120 271 tempVal = activeMenu->menuItems[selectedItemIndex]->param->max();
GuiTwo 0:936f1c020120 272 // If we reach the minimum parameter value when we only have a down button
GuiTwo 0:936f1c020120 273 // and not an up button connected to the system, we wrap the parameter
GuiTwo 0:936f1c020120 274 // value back around to its maximum. Otherwise, if there is an up button
GuiTwo 0:936f1c020120 275 // present, we peg the parameter at its minimum value.
GuiTwo 0:936f1c020120 276 else if (tempVal < activeMenu->menuItems[selectedItemIndex]->param->min())
GuiTwo 0:936f1c020120 277 {
GuiTwo 0:936f1c020120 278 if (numButtons >= 3)
GuiTwo 0:936f1c020120 279 tempVal = activeMenu->menuItems[selectedItemIndex]->param->min();
GuiTwo 0:936f1c020120 280 else
GuiTwo 0:936f1c020120 281 tempVal = activeMenu->menuItems[selectedItemIndex]->param->max();
GuiTwo 0:936f1c020120 282 }
GuiTwo 0:936f1c020120 283
GuiTwo 0:936f1c020120 284 // Assign the local temp. value back to the temporary value in the active
GuiTwo 0:936f1c020120 285 // parameter structue.
GuiTwo 0:936f1c020120 286 activeMenu->menuItems[selectedItemIndex]->param->tempVal = tempVal;
GuiTwo 0:936f1c020120 287
GuiTwo 0:936f1c020120 288 // If the parameter is configured to produce live updates, call the
GuiTwo 0:936f1c020120 289 // finalValFcn.
GuiTwo 0:936f1c020120 290 if (activeMenu->menuItems[selectedItemIndex]->param->liveUpdate())
GuiTwo 0:936f1c020120 291 activeMenu->menuItems[selectedItemIndex]->param->setVal(tempVal);
GuiTwo 0:936f1c020120 292 }
GuiTwo 0:936f1c020120 293
GuiTwo 0:936f1c020120 294
GuiTwo 0:936f1c020120 295 void MenbedNavigator::saveParam()
GuiTwo 0:936f1c020120 296 {
GuiTwo 0:936f1c020120 297 // Save the changes made the shadow variable tempValue to the real parameter
GuiTwo 0:936f1c020120 298 // value that is used by the rest of the application.
GuiTwo 0:936f1c020120 299 activeMenu->menuItems[selectedItemIndex]->param->setVal (
GuiTwo 0:936f1c020120 300 activeMenu->menuItems[selectedItemIndex]->param->tempVal
GuiTwo 0:936f1c020120 301 );
GuiTwo 0:936f1c020120 302 paramEditMode = false;
GuiTwo 0:936f1c020120 303 }
GuiTwo 0:936f1c020120 304
GuiTwo 0:936f1c020120 305
GuiTwo 0:936f1c020120 306 void MenbedNavigator::restoreParam()
GuiTwo 0:936f1c020120 307 {
GuiTwo 0:936f1c020120 308 // Revert any changes made the parameter by calling the finalValFcn with
GuiTwo 0:936f1c020120 309 // the initVal that was stored when we first began editing this parameter.
GuiTwo 0:936f1c020120 310 activeMenu->menuItems[selectedItemIndex]->param->setVal(
GuiTwo 0:936f1c020120 311 activeMenu->menuItems[selectedItemIndex]->param->initVal
GuiTwo 0:936f1c020120 312 );
GuiTwo 0:936f1c020120 313 paramEditMode = false;
GuiTwo 0:936f1c020120 314 }
GuiTwo 0:936f1c020120 315
GuiTwo 0:936f1c020120 316
GuiTwo 0:936f1c020120 317 void MenbedNavigator::printMenu (char *menuStr)
GuiTwo 0:936f1c020120 318 {
GuiTwo 0:936f1c020120 319 uint8_t i;
GuiTwo 0:936f1c020120 320 char *lineStr = new char[lineLength];
GuiTwo 0:936f1c020120 321 bool itemSel;
GuiTwo 0:936f1c020120 322
GuiTwo 0:936f1c020120 323 menuStr[0] = '\0';
GuiTwo 0:936f1c020120 324
GuiTwo 0:936f1c020120 325 for (i=topOfScreenItemIndex; i<topOfScreenItemIndex + numLines; i++)
GuiTwo 0:936f1c020120 326 {
GuiTwo 0:936f1c020120 327 // Make sure we don't try to print more menu items than exist in the
GuiTwo 0:936f1c020120 328 // active menu.
GuiTwo 0:936f1c020120 329 if (i > ((int)activeMenu->menuItems.size() - 1))
GuiTwo 0:936f1c020120 330 {
GuiTwo 0:936f1c020120 331 strcat (menuStr, "\n");
GuiTwo 0:936f1c020120 332 continue;
GuiTwo 0:936f1c020120 333 }
GuiTwo 0:936f1c020120 334
GuiTwo 0:936f1c020120 335 itemSel = (i == selectedItemIndex);
GuiTwo 0:936f1c020120 336
GuiTwo 0:936f1c020120 337 printItem (activeMenu->menuItems[i], lineStr, itemSel,
GuiTwo 0:936f1c020120 338 paramEditMode && itemSel);
GuiTwo 0:936f1c020120 339
GuiTwo 0:936f1c020120 340 strncat (menuStr, lineStr, lineLength);
GuiTwo 0:936f1c020120 341 strcat (menuStr, "\n");
GuiTwo 0:936f1c020120 342 }
GuiTwo 0:936f1c020120 343
GuiTwo 0:936f1c020120 344 delete[] lineStr;
GuiTwo 0:936f1c020120 345 }
GuiTwo 0:936f1c020120 346
GuiTwo 0:936f1c020120 347
GuiTwo 0:936f1c020120 348 void MenbedNavigator::printItem (MenbedMenuItem *item, char *line, bool itemSel,
GuiTwo 0:936f1c020120 349 bool paramSel)
GuiTwo 0:936f1c020120 350 {
GuiTwo 0:936f1c020120 351 uint8_t i = 0;
GuiTwo 0:936f1c020120 352 int8_t j;
GuiTwo 0:936f1c020120 353 char *tempStr = new char[lineLength];
GuiTwo 0:936f1c020120 354 char *frontTab, *backTab;
GuiTwo 0:936f1c020120 355 char *subStr = new char[lineLength];
GuiTwo 0:936f1c020120 356 uint8_t copySize;
GuiTwo 0:936f1c020120 357
GuiTwo 0:936f1c020120 358 // Clear the line of text
GuiTwo 0:936f1c020120 359 line[0] = '\0';
GuiTwo 0:936f1c020120 360
GuiTwo 0:936f1c020120 361 // Iterate over the element in the array of text strings in the provided
GuiTwo 0:936f1c020120 362 // menu item until an empty string is found indicating the end of the text
GuiTwo 0:936f1c020120 363 // that should be printed for the current line. For safety, we assume there
GuiTwo 0:936f1c020120 364 // are a maximum of three element in the array: 1) text before the
GuiTwo 0:936f1c020120 365 // parameter, 2) the parameter, and 3) text after the parameter.
GuiTwo 0:936f1c020120 366
GuiTwo 0:936f1c020120 367 frontTab = item->text;
GuiTwo 0:936f1c020120 368 while ((strlen (frontTab) > 0) && (i < 3))
GuiTwo 0:936f1c020120 369 {
GuiTwo 0:936f1c020120 370 backTab = strchr (frontTab, '\t');
GuiTwo 0:936f1c020120 371 if (backTab == NULL)
GuiTwo 0:936f1c020120 372 {
GuiTwo 0:936f1c020120 373 backTab = frontTab + strlen(frontTab);
GuiTwo 0:936f1c020120 374 i = 3; // force our way out of the while loop
GuiTwo 0:936f1c020120 375 }
GuiTwo 0:936f1c020120 376
GuiTwo 0:936f1c020120 377 copySize = backTab - frontTab;
GuiTwo 0:936f1c020120 378 if (copySize >= lineLength)
GuiTwo 0:936f1c020120 379 copySize = lineLength - 1;
GuiTwo 0:936f1c020120 380
GuiTwo 0:936f1c020120 381 strncpy (subStr, frontTab, copySize);
GuiTwo 0:936f1c020120 382 subStr[copySize] = '\0';
GuiTwo 0:936f1c020120 383
GuiTwo 0:936f1c020120 384 // If the current string in the array is a printf-style conversion
GuiTwo 0:936f1c020120 385 // specifier for a float, we replace it with the parameter value.
GuiTwo 0:936f1c020120 386 if (checkConvSpec (subStr))
GuiTwo 0:936f1c020120 387 {
GuiTwo 0:936f1c020120 388 // If the user is currently editing the parameter, print the value
GuiTwo 0:936f1c020120 389 // of the shadow variable tempValue instead of the parameters actual
GuiTwo 0:936f1c020120 390 // value. The tempValue is not copied over to the value field of
GuiTwo 0:936f1c020120 391 // the structure until the user is done editing the parameter. To
GuiTwo 0:936f1c020120 392 // show that the parameter is being edited, we highlight the value
GuiTwo 0:936f1c020120 393 // by inverting the text.
GuiTwo 0:936f1c020120 394 if (paramSel)
GuiTwo 0:936f1c020120 395 {
GuiTwo 0:936f1c020120 396 snprintf (tempStr, lineLength, subStr, item->param->tempVal);
GuiTwo 0:936f1c020120 397
GuiTwo 0:936f1c020120 398 // We highlight the parameter by inverting the characters on the
GuiTwo 0:936f1c020120 399 // screen. The menu system only allows the standard (0-127)
GuiTwo 0:936f1c020120 400 // ASCII character, so we use the MSB/7th bit of each character
GuiTwo 0:936f1c020120 401 // to indicate that it should be inverted when printed on the
GuiTwo 0:936f1c020120 402 // screen.
GuiTwo 0:936f1c020120 403 for (j=strlen(tempStr) - 1; j>=0; j--)
GuiTwo 0:936f1c020120 404 tempStr[j] |= 0x80;
GuiTwo 0:936f1c020120 405
GuiTwo 0:936f1c020120 406 }
GuiTwo 0:936f1c020120 407 // If the user is not currently editing the parameter, we display
GuiTwo 0:936f1c020120 408 // the value pointed to by the value field of the param structure.
GuiTwo 0:936f1c020120 409 else
GuiTwo 0:936f1c020120 410 snprintf (tempStr, lineLength,
GuiTwo 0:936f1c020120 411 subStr, item->param->getVal());
GuiTwo 0:936f1c020120 412
GuiTwo 0:936f1c020120 413 // Attach the parameter string to the growing line.
GuiTwo 0:936f1c020120 414 strncat (line, tempStr, lineLength);
GuiTwo 0:936f1c020120 415 }
GuiTwo 0:936f1c020120 416 // If the string is not a printf-style conversion specifier for a float,
GuiTwo 0:936f1c020120 417 // simply catenate the string with the growing line of text.
GuiTwo 0:936f1c020120 418 else
GuiTwo 0:936f1c020120 419 {
GuiTwo 0:936f1c020120 420 strncat (line, subStr, lineLength);
GuiTwo 0:936f1c020120 421 }
GuiTwo 0:936f1c020120 422
GuiTwo 0:936f1c020120 423 frontTab = backTab + 1;
GuiTwo 0:936f1c020120 424 i++;
GuiTwo 0:936f1c020120 425 }
GuiTwo 0:936f1c020120 426
GuiTwo 0:936f1c020120 427 // Append a space to the very end of the line. The LCD driver looks to the
GuiTwo 0:936f1c020120 428 // last character in the line to determine whether to highlight any
GuiTwo 0:936f1c020120 429 // remaining whitespace after the text ends. This approach causes problems
GuiTwo 0:936f1c020120 430 // when the parameter is the last text on the line and we are in parameter
GuiTwo 0:936f1c020120 431 // modification mode. Without the extra space at the end of the line, the
GuiTwo 0:936f1c020120 432 // LCD controller will highlight the rest of the line even though it is only
GuiTwo 0:936f1c020120 433 // the parameter itself that should be highlighted.
GuiTwo 0:936f1c020120 434 strncat (line, " ", lineLength);
GuiTwo 0:936f1c020120 435
GuiTwo 0:936f1c020120 436 // If the parameter has not been selected for modification but the menu item
GuiTwo 0:936f1c020120 437 // is currently selected, we highlight the entire line. In the menu system,
GuiTwo 0:936f1c020120 438 // the only allowable character are the standard ASCII codes (0-127). We
GuiTwo 0:936f1c020120 439 // use the (MSB) 7th bit of every character to indicate whether it should be
GuiTwo 0:936f1c020120 440 // highlighted/inverted.
GuiTwo 0:936f1c020120 441 if (!paramSel && itemSel)
GuiTwo 0:936f1c020120 442 {
GuiTwo 0:936f1c020120 443 // Set the MSB of each character to invert it when displayed.
GuiTwo 0:936f1c020120 444 for (j = strlen(line) - 1; j>= 0; j--)
GuiTwo 0:936f1c020120 445 line[j] |= 0x80;
GuiTwo 0:936f1c020120 446 }
GuiTwo 0:936f1c020120 447
GuiTwo 0:936f1c020120 448 delete[] tempStr;
GuiTwo 0:936f1c020120 449 delete[] subStr;
GuiTwo 0:936f1c020120 450 }
GuiTwo 0:936f1c020120 451
GuiTwo 0:936f1c020120 452
GuiTwo 0:936f1c020120 453 // Returns true if the provided string is a printf-style conversion specifier
GuiTwo 0:936f1c020120 454 // for a float (conversion character is f, e, E, g, or G). Otherwise, returns
GuiTwo 0:936f1c020120 455 // false.
GuiTwo 0:936f1c020120 456 bool MenbedNavigator::checkConvSpec (const char *s)
GuiTwo 0:936f1c020120 457 {
GuiTwo 0:936f1c020120 458 char lastChar;
GuiTwo 0:936f1c020120 459
GuiTwo 0:936f1c020120 460 // Conversion specifications must begin with a '%'.
GuiTwo 0:936f1c020120 461 if (s[0] != '%')
GuiTwo 0:936f1c020120 462 return false;
GuiTwo 0:936f1c020120 463
GuiTwo 0:936f1c020120 464 // Identify the last last character in the conversion specification
GuiTwo 0:936f1c020120 465 lastChar = s[strlen(s) - 1];
GuiTwo 0:936f1c020120 466
GuiTwo 0:936f1c020120 467 // Check that the last character in the conversion specification is either a
GuiTwo 0:936f1c020120 468 // 'f', 'e', 'E', 'g', or 'G'--the conversion specifiers for floats. If it
GuiTwo 0:936f1c020120 469 // is, the conversion specification is probably a valid conversion
GuiTwo 0:936f1c020120 470 // specification.
GuiTwo 0:936f1c020120 471 if ((lastChar == 'f') || (lastChar == 'e') || (lastChar == 'E') ||
GuiTwo 0:936f1c020120 472 (lastChar == 'g') || (lastChar == 'G'))
GuiTwo 0:936f1c020120 473 return true;
GuiTwo 0:936f1c020120 474
GuiTwo 0:936f1c020120 475 // Otherwise, it is not.
GuiTwo 0:936f1c020120 476 return false;
GuiTwo 0:936f1c020120 477 }