Mercurial > public > ostc4
annotate Discovery/Src/tMenuEditCvOption.c @ 1071:b4a79464caf7 Icon_Integration
Dynamic menu creation for CV views:
Because of the increasing features of the OSTC the maintenance of the the menus becomes difficult. Some are not available because of HW version or connected sensors. To keep the "legacy" menus stable the functionality of the cv options page has been increased. Based on enabled cv views and connected sensors the page will be filled dynamically. The page items allow quick acces to the view related options. For the first implementation the views: compass, timer, sensor O2 and sensor CO2 are supported.
| author | Ideenmodellierer |
|---|---|
| date | Thu, 19 Feb 2026 13:28:37 +0100 |
| parents | 195bfbdf961d |
| children | 734f84b72b30 |
| rev | line source |
|---|---|
| 999 | 1 /////////////////////////////////////////////////////////////////////////////// |
| 2 /// -*- coding: UTF-8 -*- | |
| 3 /// | |
| 4 /// \file Discovery/Src/tMenuEditCvOption.c | |
| 5 /// \brief Menu for configuration depended items | |
| 6 /// \author heinrichs weikamp gmbh | |
| 7 /// \date 24-Apr-2025 | |
| 8 /// | |
| 9 /// \details | |
| 10 /// | |
| 11 /// $Id$ | |
| 12 /////////////////////////////////////////////////////////////////////////////// | |
| 13 /// \par Copyright (c) 2014-2025 Heinrichs Weikamp gmbh | |
| 14 /// | |
| 15 /// This program is free software: you can redistribute it and/or modify | |
| 16 /// it under the terms of the GNU General Public License as published by | |
| 17 /// the Free Software Foundation, either version 3 of the License, or | |
| 18 /// (at your option) any later version. | |
| 19 /// | |
| 20 /// This program is distributed in the hope that it will be useful, | |
| 21 /// but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 22 /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 23 /// GNU General Public License for more details. | |
| 24 /// | |
| 25 /// You should have received a copy of the GNU General Public License | |
| 26 /// along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| 27 ////////////////////////////////////////////////////////////////////////////// | |
| 28 | |
| 29 /* Includes ------------------------------------------------------------------*/ | |
| 30 #include "tMenuEditCvOption.h" | |
| 1071 | 31 #include "tMenuCvOptionText.h" |
| 999 | 32 #include "tMenuEdit.h" |
| 33 | |
| 34 #include "gfx_fonts.h" | |
| 35 #include "ostc.h" | |
| 36 #include "tMenuEdit.h" | |
| 37 #include "tHome.h" | |
| 38 | |
| 1032 | 39 #include "cv_heartbeat.h" |
| 40 | |
| 1071 | 41 |
| 42 static openFunc_t openFctPointerTable[MAXLINES]; /* function pointer for refresh */ | |
| 43 | |
| 999 | 44 /* Private function prototypes -----------------------------------------------*/ |
| 45 static void openEdit_Timer(void); | |
| 46 void openEdit_Compass(void); | |
| 47 | |
| 48 /* Announced function prototypes -----------------------------------------------*/ | |
| 49 uint8_t OnAction_Compass (uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action); | |
| 50 static uint8_t OnAction_CompassDeclination(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action); | |
| 51 uint8_t OnAction_Bearing (uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action); | |
| 52 uint8_t OnAction_BearingClear (uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action); | |
| 53 uint8_t OnAction_InertiaLevel (uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action); | |
| 54 static uint8_t OnAction_Timer(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action); | |
| 55 | |
| 56 /* Exported functions --------------------------------------------------------*/ | |
| 57 | |
| 1071 | 58 |
| 59 void tMCvOption_SetOpenFnct(uint8_t cvOptId, uint8_t index) | |
| 60 { | |
| 61 if(index < MAXLINES) | |
| 62 { | |
| 63 switch(cvOptId) | |
| 64 { | |
| 65 case CVOPT_Compass: openFctPointerTable[index] = openEdit_Compass; | |
| 66 break; | |
| 67 case CVOPT_Timer: openFctPointerTable[index] = openEdit_Timer; | |
| 68 break; | |
| 69 case CVOPT_END: openFctPointerTable[index] = NULL; | |
| 70 break; | |
| 71 default: break; | |
| 72 } | |
| 73 } | |
| 74 } | |
| 75 | |
| 76 | |
| 999 | 77 void openEdit_CvOption(uint8_t line) |
| 78 { | |
| 1071 | 79 if(openFctPointerTable[line - 1] != NULL) |
| 999 | 80 { |
| 1071 | 81 openFctPointerTable[line - 1](); |
| 999 | 82 } |
| 83 } | |
| 84 | |
| 85 /* Private functions ---------------------------------------------------------*/ | |
| 86 | |
| 87 static uint8_t OnAction_CompassDeclination(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action) | |
| 88 { | |
| 89 SSettings *settings = settingsGetPointer(); | |
| 90 uint8_t digitContentNew; | |
| 91 switch (action) { | |
| 92 case ACTION_BUTTON_ENTER: | |
| 93 | |
| 94 return digitContent; | |
| 95 case ACTION_BUTTON_ENTER_FINAL: | |
| 96 { | |
| 97 int32_t compassDeclinationDeg; | |
| 98 evaluateNewString(editId, (uint32_t *)&compassDeclinationDeg, NULL, NULL, NULL); | |
| 99 | |
| 100 if (compassDeclinationDeg > 99) { | |
| 101 compassDeclinationDeg = 99; | |
| 102 } else if (compassDeclinationDeg < -99) { | |
| 103 compassDeclinationDeg = -99; | |
| 104 } | |
| 105 | |
| 106 settings->compassDeclinationDeg = compassDeclinationDeg; | |
| 107 | |
| 108 tMenuEdit_newInput(editId, ((input_u)compassDeclinationDeg).uint32, 0, 0, 0); | |
| 109 } | |
| 110 | |
| 111 break; | |
| 112 case ACTION_BUTTON_NEXT: | |
| 113 if (digitNumber == 0) { | |
| 114 digitContentNew = togglePlusMinus(digitContent); | |
| 115 } else { | |
| 116 digitContentNew = digitContent + 1; | |
| 117 if (digitContentNew > '9') { | |
| 118 digitContentNew = '0'; | |
| 119 } | |
| 120 } | |
| 121 | |
| 122 return digitContentNew; | |
| 123 case ACTION_BUTTON_BACK: | |
| 124 if (digitNumber == 0) { | |
| 125 digitContentNew = togglePlusMinus(digitContent); | |
| 126 } else { | |
| 127 digitContentNew = digitContent - 1; | |
| 128 if (digitContentNew < '0') { | |
| 129 digitContentNew = '9'; | |
| 130 } | |
| 131 } | |
| 132 | |
| 133 return digitContentNew; | |
| 134 } | |
| 135 | |
| 136 return UNSPECIFIC_RETURN; | |
| 137 } | |
| 138 | |
| 139 | |
| 140 static void showCompassDeclination(SSettings *settings, bool isRefresh) | |
| 141 { | |
| 142 char text[16]; | |
| 143 snprintf(text, 16, "%c%c:", TXT_2BYTE, TXT2BYTE_CompassDeclination); | |
| 144 write_label_var(30, 800, ME_Y_LINE6, &FontT48, text); | |
| 145 if (isRefresh) { | |
| 146 tMenuEdit_refresh_field(StMOption_Compass_Declination); | |
| 147 } else { | |
| 148 write_field_sdigit(StMOption_Compass_Declination, 500, 800, ME_Y_LINE6, &FontT48, "\034###`", settings->compassDeclinationDeg, 0, 0, 0); | |
| 149 } | |
| 150 } | |
| 151 | |
| 152 | |
| 153 void refresh_CompassEdit(void) | |
| 154 { | |
| 155 SSettings *settings = settingsGetPointer(); | |
| 156 | |
| 157 uint16_t heading; | |
| 158 char text[32]; | |
| 159 uint8_t textIndex = 0; | |
| 160 | |
| 161 text[0] = '\001'; | |
| 162 text[1] = TXT_2BYTE; | |
| 163 text[2] = TXT2BYTE_Compass; | |
| 164 text[3] = 0; | |
| 165 write_topline(text); | |
| 166 | |
| 167 if(settings->compassInertia) | |
| 168 { | |
| 169 heading = (uint16_t)compass_getCompensated(); | |
| 170 } | |
| 171 else | |
| 172 { | |
| 173 heading = (uint16_t)stateUsed->lifeData.compass_heading; | |
| 174 } | |
| 175 snprintf(text,32,"\001%03i`",heading); | |
| 176 write_label_var( 0, 800, ME_Y_LINE1, &FontT54, text); | |
| 177 | |
| 178 tMenuEdit_refresh_field(StMOption_Compass_SetCourse); | |
| 179 tMenuEdit_refresh_field(StMOption_Compass_Calibrate); | |
| 180 tMenuEdit_refresh_field(StMOption_Compass_ResetCourse); | |
| 181 text[textIndex++] = TXT_2BYTE; | |
| 182 text[textIndex++] = TXT2BYTE_CompassInertia; | |
| 183 text[textIndex++] = ':'; | |
| 184 text[textIndex++] = ' '; | |
| 185 text[textIndex++] = '0' + settings->compassInertia; | |
| 186 | |
| 187 write_label_var(30, 800, ME_Y_LINE5, &FontT48, text); | |
| 188 | |
| 189 showCompassDeclination(settings, true); | |
| 190 | |
| 191 write_buttonTextline(TXT2BYTE_ButtonBack,TXT2BYTE_ButtonEnter,TXT2BYTE_ButtonNext); | |
| 192 } | |
| 193 | |
| 194 | |
| 195 void openEdit_Compass(void) | |
| 196 { | |
| 197 SSettings *settings = settingsGetPointer(); | |
| 198 | |
| 199 char text[10]; | |
| 200 uint8_t textIndex = 0; | |
| 201 | |
| 202 | |
| 203 set_globalState(StMOption_Compass); | |
| 204 resetMenuEdit(CLUT_MenuPageHardware); | |
| 205 | |
| 206 text[textIndex++] = '\001'; | |
| 207 text[textIndex++] = TXT_2BYTE; | |
| 208 text[textIndex++] = TXT2BYTE_Compass; | |
| 209 text[textIndex++] = 0; | |
| 210 write_topline(text); | |
| 211 | |
| 212 text[0] = TXT_2BYTE; | |
| 213 text[2] = 0; | |
| 214 | |
| 215 text[1] = TXT2BYTE_SetBearing; | |
| 216 write_field_button(StMOption_Compass_SetCourse, 30, 800, ME_Y_LINE2, &FontT48, text); | |
| 217 | |
| 218 text[1] = TXT2BYTE_ResetBearing; | |
| 219 write_field_button(StMOption_Compass_ResetCourse, 30, 800, ME_Y_LINE3, &FontT48, text); | |
| 220 | |
| 221 text[1] = TXT2BYTE_CompassCalib; | |
| 222 write_field_button(StMOption_Compass_Calibrate, 30, 800, ME_Y_LINE4, &FontT48, text); | |
| 223 | |
| 224 text[1] = TXT2BYTE_CompassInertia; | |
| 225 textIndex = 2; | |
| 226 text[textIndex++] = ':'; | |
| 227 text[textIndex++] = ' '; | |
| 228 text[textIndex++] = '0' + settings->compassInertia; | |
| 229 text[textIndex++] = 0; | |
| 230 | |
| 231 write_field_button(StMOption_Compass_Inertia, 30, 800, ME_Y_LINE5, &FontT48, text); | |
| 232 | |
| 233 showCompassDeclination(settings, false); | |
| 234 | |
| 235 setEvent(StMOption_Compass_SetCourse, (uint32_t)OnAction_Bearing); | |
| 236 setEvent(StMOption_Compass_ResetCourse, (uint32_t)OnAction_BearingClear); | |
| 237 setEvent(StMOption_Compass_Calibrate, (uint32_t)OnAction_Compass); | |
| 238 setEvent(StMOption_Compass_Inertia, (uint32_t)OnAction_InertiaLevel); | |
| 239 setEvent(StMOption_Compass_Declination, (uint32_t)OnAction_CompassDeclination); | |
| 240 | |
| 241 tMenuEdit_select(StMOption_Compass_SetCourse); | |
| 242 | |
| 243 write_buttonTextline(TXT2BYTE_ButtonBack,TXT2BYTE_ButtonEnter,TXT2BYTE_ButtonNext); | |
| 244 } | |
| 245 | |
| 246 | |
| 247 uint8_t OnAction_Compass (uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action) | |
| 248 { | |
| 249 calibrateCompass(); | |
| 250 return EXIT_TO_INFO_COMPASS; | |
| 251 } | |
| 252 | |
| 253 | |
| 254 uint8_t OnAction_Bearing (uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action) | |
| 255 { | |
| 256 if((int16_t)stateUsed->lifeData.compass_heading != -1) | |
| 257 { | |
| 258 settingsGetPointer()->compassBearing = (int16_t)stateUsed->lifeData.compass_heading; | |
| 259 } | |
| 260 else | |
| 261 { | |
| 262 settingsGetPointer()->compassBearing = 0; | |
| 263 } | |
| 264 | |
| 265 if(settingsGetPointer()->compassBearing == 0) | |
| 266 settingsGetPointer()->compassBearing = 360; | |
| 267 return UPDATE_AND_EXIT_TO_MENU; | |
| 268 } | |
| 269 | |
| 270 | |
| 271 uint8_t OnAction_BearingClear (uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action) | |
| 272 { | |
| 273 settingsGetPointer()->compassBearing = 0; | |
| 274 return UPDATE_AND_EXIT_TO_MENU; | |
| 275 } | |
| 276 | |
| 277 | |
| 278 uint8_t OnAction_InertiaLevel (uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action) | |
| 279 { | |
| 280 uint8_t newLevel = 0; | |
| 281 | |
| 282 newLevel = settingsGetPointer()->compassInertia + 1; | |
| 283 if(newLevel > MAX_COMPASS_COMP) | |
| 284 { | |
| 285 newLevel = 0; | |
| 286 } | |
| 287 settingsGetPointer()->compassInertia = newLevel; | |
| 288 return UPDATE_DIVESETTINGS; | |
| 289 } | |
| 290 | |
| 291 static void openEdit_Timer(void) | |
| 292 { | |
| 293 SSettings *settings = settingsGetPointer(); | |
| 294 | |
| 295 char text[32]; | |
| 296 snprintf(text, 32, "\001%c%c", TXT_2BYTE, TXT2BYTE_Timer); | |
| 297 write_topline(text); | |
| 298 | |
|
1001
21142f4fa968
Cleanup menu structucture afer menu shift:
Ideenmodellierer
parents:
999
diff
changeset
|
299 set_globalState(StMOption_Timer); |
|
1005
85f7e19c6688
Switch menu position of Buzzer and flipdisplay option:
Ideenmodellierer
parents:
1001
diff
changeset
|
300 resetMenuEdit(CLUT_MenuPageCvOption); |
|
1001
21142f4fa968
Cleanup menu structucture afer menu shift:
Ideenmodellierer
parents:
999
diff
changeset
|
301 |
| 999 | 302 uint16_t yPos = ME_Y_LINE_BASE + get_globalState_Menu_Line() * ME_Y_LINE_STEP; |
| 303 snprintf(text, 32, "%c%c", TXT_2BYTE, TXT2BYTE_Timer); | |
| 304 write_label_var(30, 299, yPos, &FontT48, text); | |
|
1005
85f7e19c6688
Switch menu position of Buzzer and flipdisplay option:
Ideenmodellierer
parents:
1001
diff
changeset
|
305 write_field_udigit(StMOption_Timer_Value, 300, 392, yPos, &FontT48, "#:##", settings->timerDurationS / 60, settings->timerDurationS % 60, 0, 0); |
| 999 | 306 write_label_var(393, 800, yPos, &FontT48, "\016\016 [m:ss]\017"); |
| 307 | |
| 308 write_buttonTextline(TXT2BYTE_ButtonMinus, TXT2BYTE_ButtonEnter, TXT2BYTE_ButtonPlus); | |
| 309 | |
|
1005
85f7e19c6688
Switch menu position of Buzzer and flipdisplay option:
Ideenmodellierer
parents:
1001
diff
changeset
|
310 setEvent(StMOption_Timer_Value, (uint32_t)OnAction_Timer); |
| 999 | 311 startEdit(); |
| 312 } | |
| 313 static uint8_t OnAction_Timer(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action) | |
| 314 { | |
| 315 SSettings *settings = settingsGetPointer(); | |
| 316 uint8_t digitContentNew; | |
| 317 switch (action) { | |
| 318 case ACTION_BUTTON_ENTER: | |
| 319 | |
| 320 return digitContent; | |
| 321 case ACTION_BUTTON_ENTER_FINAL: | |
| 322 { | |
| 323 uint32_t timerM; | |
| 324 uint32_t timerS; | |
| 325 evaluateNewString(editId, &timerM, &timerS, 0, 0); | |
| 326 if (timerM > 9) { | |
| 327 timerM = 9; | |
| 328 } | |
| 329 if (timerS > 59) { | |
| 330 timerS = 59; | |
| 331 } | |
| 332 | |
| 333 uint16_t timerDurationS = 60 * timerM + timerS; | |
| 334 | |
| 335 if (timerDurationS < 1) { | |
| 336 timerDurationS = 1; | |
| 337 } | |
| 338 | |
| 339 if (timerDurationS != settings->timerDurationS) { | |
| 340 settings->timerDurationS = timerDurationS; | |
| 341 | |
| 342 disableTimer(); | |
| 343 | |
| 344 tMenuEdit_newInput(editId, settings->timerDurationS / 60, settings->timerDurationS % 60, 0, 0); | |
| 345 } | |
| 346 | |
|
1014
8c0134a287da
Add a log data event to the scrubber timer at the start of the dive and every time the timer (in minutes)
heinrichsweikamp
parents:
1005
diff
changeset
|
347 settings->cv_configuration |= (1 << CVIEW_Timer); |
|
8c0134a287da
Add a log data event to the scrubber timer at the start of the dive and every time the timer (in minutes)
heinrichsweikamp
parents:
1005
diff
changeset
|
348 |
| 999 | 349 return EXIT_TO_MENU; |
| 350 } | |
| 351 case ACTION_BUTTON_NEXT: | |
| 352 digitContentNew = digitContent + 1; | |
| 353 if ((blockNumber == 1 && digitNumber == 0 && digitContentNew > '5') || digitContentNew > '9') { | |
| 354 digitContentNew = '0'; | |
| 355 } | |
| 356 | |
| 357 return digitContentNew; | |
| 358 case ACTION_BUTTON_BACK: | |
| 359 digitContentNew = digitContent - 1; | |
| 360 if (digitContentNew < '0') { | |
| 361 if (blockNumber == 1 && digitNumber == 0) { | |
| 362 digitContentNew = '5'; | |
| 363 } else { | |
| 364 digitContentNew = '9'; | |
| 365 } | |
| 366 } | |
| 367 | |
| 368 return digitContentNew; | |
| 369 } | |
| 370 | |
| 371 return EXIT_TO_MENU; | |
| 372 } | |
| 373 | |
| 374 |
