@@ -1308,14 +1308,17 @@ void paintHorizontalAccuracy(displayCoords textCoords)
1308
1308
// Display clock with moving hands
1309
1309
void paintClock (std::vector<iconPropertyBlinking> *iconList, bool blinking)
1310
1310
{
1311
- // Animate icon to show system running
1312
- static uint8_t clockIconDisplayed = CLOCK_ICON_STATES - 1 ;
1313
- clockIconDisplayed++; // Goto next icon
1314
- clockIconDisplayed %= CLOCK_ICON_STATES; // Wrap
1311
+ // Animate icon to show system running. The 2* makes the blink correct
1312
+ static uint8_t clockIconDisplayed = ( 2 * CLOCK_ICON_STATES) - 1 ;
1313
+ clockIconDisplayed++; // Goto next icon
1314
+ clockIconDisplayed %= ( 2 * CLOCK_ICON_STATES) ; // Wrap
1315
1315
1316
1316
iconPropertyBlinking prop;
1317
- prop.icon = ClockIconProperties.iconDisplay [clockIconDisplayed][present.display_type ];
1318
- prop.duty = 0b01010101 ;
1317
+ prop.icon = ClockIconProperties.iconDisplay [clockIconDisplayed / 2 ][present.display_type ];
1318
+ if (blinking)
1319
+ prop.duty = 0b01010101 ;
1320
+ else
1321
+ prop.duty = 0b11111111 ;
1319
1322
iconList->push_back (prop);
1320
1323
1321
1324
displayCoords textCoords;
@@ -1717,19 +1720,21 @@ void printTextwithKerning(const char *newText, uint8_t xPos, uint8_t yPos, uint8
1717
1720
// Show transmission of RTCM correction data packets to NTRIP caster
1718
1721
void paintRTCM (std::vector<iconPropertyBlinking> *iconList)
1719
1722
{
1720
- uint8_t xPos = CrossHairProperties.iconDisplay [present.display_type ].xPos ;
1721
- uint8_t yPos = CrossHairProperties.iconDisplay [present.display_type ].yPos ;
1722
-
1723
1723
// Determine if the NTRIP Server is casting
1724
1724
bool casting = false ;
1725
1725
for (int serverIndex = 0 ; serverIndex < NTRIP_SERVER_MAX; serverIndex++)
1726
1726
casting |= online.ntripServer [serverIndex];
1727
1727
1728
- // Note: the "yPos - 1" is potentially brittle. TODO: find a better solution for this
1728
+ uint8_t xPos = CrossHairProperties.iconDisplay [present.display_type ].xPos ;
1729
+ uint8_t yPos = CrossHairProperties.iconDisplay [present.display_type ].yPos ;
1730
+
1731
+ if (present.display_type == DISPLAY_64x48)
1732
+ yPos = yPos - 1 ; // Move text up by 1 pixel on 64x48. Note: this is brittle. TODO: find a better solution
1733
+
1729
1734
if (casting)
1730
- printTextCenter (" Casting" , yPos - 1 , QW_FONT_8X16, 1 , false ); // text, y, font type, kerning, inverted
1735
+ printTextAt (" Casting" , xPos + 4 , yPos, QW_FONT_8X16, 1 ); // text, y, font type, kerning
1731
1736
else
1732
- printTextCenter (" Xmitting" , yPos - 1 , QW_FONT_8X16, 1 , false ); // text, y, font type, kerning, inverted
1737
+ printTextAt (" Xmitting" , xPos, yPos , QW_FONT_8X16, 1 ); // text, y, font type, kerning
1733
1738
1734
1739
xPos = SIVIconProperties.iconDisplay [present.display_type ].xPos ;
1735
1740
yPos = SIVIconProperties.iconDisplay [present.display_type ].yPos ;
@@ -1771,7 +1776,8 @@ void paintRTCM(std::vector<iconPropertyBlinking> *iconList)
1771
1776
paintResets ();
1772
1777
}
1773
1778
1774
- // Show connecting to NTRIP caster service
1779
+ // Show connecting to NTRIP caster service.
1780
+ // Note: NOT USED. TODO: if this is used, the text position needs to be changed for 128x64
1775
1781
void paintConnectingToNtripCaster ()
1776
1782
{
1777
1783
int yPos = 18 ;
@@ -2254,19 +2260,29 @@ void paintProfile(uint8_t profileUnit)
2254
2260
if (getProfileNameFromUnit (profileUnit, profileName, sizeof (profileName)) ==
2255
2261
true ) // Load the profile name, limited to 8 chars
2256
2262
{
2257
- settings.updateGNSSSettings = true ; // When this profile is loaded next, force system to update GNSS settings.
2258
- recordSystemSettings (); // Before switching, we need to record the current settings to LittleFS and SD
2263
+ // Lookup profileNumber based on unit.
2264
+ // getProfileNumberFromUnit should not fail (return -1), because we have already called getProfileNameFromUnit.
2265
+ int8_t profileNumber = getProfileNumberFromUnit (profileUnit);
2259
2266
2260
- // Lookup profileNumber based on unit
2261
- uint8_t profileNumber = getProfileNumberFromUnit (profileUnit);
2262
- recordProfileNumber (profileNumber); // Update internal settings with user's choice, mark unit for config update
2267
+ if (profileNumber >= 0 )
2268
+ {
2269
+ settings.updateGNSSSettings = true ; // When this profile is loaded next, force system to update GNSS settings.
2270
+ recordSystemSettings (); // Before switching, we need to record the current settings to LittleFS and SD
2263
2271
2264
- log_d ( " Going to profile number %d from unit %d, name '%s' " , profileNumber, profileUnit, profileName);
2272
+ recordProfileNumber (( uint8_t )profileNumber); // Update internal settings with user's choice, mark unit for config update
2265
2273
2266
- snprintf (profileMessage, sizeof (profileMessage), " Loading %s" , profileName);
2267
- displayMessage (profileMessage, 2000 );
2268
- ESP.restart (); // Profiles require full restart to take effect
2274
+ log_d (" Going to profile number %d from unit %d, name '%s'" , profileNumber, profileUnit, profileName);
2275
+
2276
+ snprintf (profileMessage, sizeof (profileMessage), " Loading %s" , profileName);
2277
+ displayMessage (profileMessage, 2000 );
2278
+ ESP.restart (); // Profiles require full restart to take effect
2279
+ }
2269
2280
}
2281
+
2282
+ log_d (" Cannot go to profileUnit %d. No profile name / number. Restarting..." , profileUnit);
2283
+ snprintf (profileMessage, sizeof (profileMessage), " Invalid profile%d" , profileUnit);
2284
+ displayMessage (profileMessage, 2000 );
2285
+ ESP.restart (); // Something bad happened. Restart...
2270
2286
}
2271
2287
2272
2288
// Display unit self-tests until user presses a button to exit
@@ -2434,168 +2450,62 @@ void paintSystemTest()
2434
2450
}
2435
2451
}
2436
2452
2437
- // Display the setup profiles
2438
- void paintDisplaySetupProfile (const char *firstState)
2453
+ // Show different menu 'buttons'.
2454
+ // The first button is always highlighted, ready for selection. The user needs to double tap it to select it
2455
+ void paintDisplaySetup ()
2439
2456
{
2440
- int index;
2441
- int itemsDisplayed;
2442
- char profileName[8 + 1 ];
2457
+ constructSetupDisplay (&setupButtons); // Construct the vector (linked list) of buttons
2443
2458
2444
- // Display the first state if this is the first profile
2445
- itemsDisplayed = 0 ;
2446
- if (displayProfile == 0 )
2447
- {
2448
- printTextCenter (firstState, 12 * itemsDisplayed, QW_FONT_8X16, 1 , false );
2449
- itemsDisplayed++;
2450
- }
2459
+ uint8_t maxButtons = ((present.display_type == DISPLAY_128x64) ? 5 : 4 );
2451
2460
2452
- // Display Bubble if this is the second profile
2453
- if (displayProfile <= 1 )
2454
- {
2455
- printTextCenter (" Bubble" , 12 * itemsDisplayed, QW_FONT_8X16, 1 , false );
2456
- itemsDisplayed++;
2457
- }
2461
+ uint8_t printedButtons = 0 ;
2458
2462
2459
- // Display Config if this is the third profile
2460
- if (displayProfile <= 2 )
2461
- {
2462
- printTextCenter (" Config" , 12 * itemsDisplayed, QW_FONT_8X16, 1 , false );
2463
- itemsDisplayed++;
2464
- }
2463
+ uint8_t thisIsButton = 0 ;
2465
2464
2466
- // displayProfile itemsDisplayed index
2467
- // 0 3 0
2468
- // 1 2 0
2469
- // 2 1 0
2470
- // 3 0 0
2471
- // 4 0 1
2472
- // 5 0 2
2473
- // n >= 3 0 n - 3
2474
-
2475
- // Display the profile names
2476
- for (index = (displayProfile >= 3 ) ? displayProfile - 3 : 0 ; itemsDisplayed < 4 ; itemsDisplayed++)
2465
+ for (auto it = setupButtons.begin (); it != setupButtons.end (); it = std::next (it))
2477
2466
{
2478
- // Lookup next available profile, limit to 8 characters
2479
- getProfileNameFromUnit (index, profileName, sizeof (profileName));
2480
-
2481
- profileName[6 ] = 0 ; // Shorten profileName to 6 characters
2482
-
2483
- char miniProfileName[16 ] = {0 };
2484
- snprintf (miniProfileName, sizeof (miniProfileName), " %d_%s" , index, profileName); // Prefix with index #
2485
-
2486
- printTextCenter (miniProfileName, 12 * itemsDisplayed, QW_FONT_8X16, 1 , itemsDisplayed == 3 );
2487
- index++;
2488
- }
2489
- }
2467
+ setupButton theButton = *it;
2490
2468
2491
- // Show different menu 'buttons' to allow user to pause on one to select it
2492
- void paintDisplaySetup ()
2493
- {
2494
- if (setupState == STATE_ROVER_NOT_STARTED)
2495
- {
2496
- if (present.ethernet_ws5500 == true )
2497
- {
2498
- printTextCenter (" Base" , 12 * 0 , QW_FONT_8X16, 1 , false ); // string, y, font type, kerning, inverted
2499
- printTextCenter (" Rover" , 12 * 1 , QW_FONT_8X16, 1 , true );
2500
- printTextCenter (" NTP" , 12 * 2 , QW_FONT_8X16, 1 , false );
2501
- printTextCenter (" Cfg Eth" , 12 * 3 , QW_FONT_8X16, 1 , false );
2502
- }
2503
- else
2504
- {
2505
- printTextCenter (" Mark" , 12 * 0 , QW_FONT_8X16, 1 , false );
2506
- printTextCenter (" Rover" , 12 * 1 , QW_FONT_8X16, 1 , true );
2507
- printTextCenter (" Base" , 12 * 2 , QW_FONT_8X16, 1 , false );
2508
- printTextCenter (" Config" , 12 * 3 , QW_FONT_8X16, 1 , false );
2509
- }
2510
- }
2511
- else if (setupState == STATE_BASE_NOT_STARTED)
2512
- {
2513
- if (present.ethernet_ws5500 == true )
2469
+ if (thisIsButton >= setupSelectedButton) // Should we display this button based on the global setupSelectedButton?
2514
2470
{
2515
- printTextCenter (" Base" , 12 * 0 , QW_FONT_8X16, 1 , true ); // string, y, font type, kerning, inverted
2516
- printTextCenter (" Rover" , 12 * 1 , QW_FONT_8X16, 1 , false );
2517
- printTextCenter (" NTP" , 12 * 2 , QW_FONT_8X16, 1 , false );
2518
- printTextCenter (" Cfg Eth" , 12 * 3 , QW_FONT_8X16, 1 , false );
2519
- }
2520
- else
2521
- {
2522
- printTextCenter (" Mark" , 12 * 0 , QW_FONT_8X16, 1 , false ); // string, y, font type, kerning, inverted
2523
- printTextCenter (" Rover" , 12 * 1 , QW_FONT_8X16, 1 , false );
2524
- printTextCenter (" Base" , 12 * 2 , QW_FONT_8X16, 1 , true );
2525
- printTextCenter (" Config" , 12 * 3 , QW_FONT_8X16, 1 , false );
2526
- }
2527
- }
2528
- else if (setupState == STATE_NTPSERVER_NOT_STARTED)
2529
- {
2530
- {
2531
- printTextCenter (" Base" , 12 * 0 , QW_FONT_8X16, 1 , false ); // string, y, font type, kerning, inverted
2532
- printTextCenter (" Rover" , 12 * 1 , QW_FONT_8X16, 1 , false );
2533
- printTextCenter (" NTP" , 12 * 2 , QW_FONT_8X16, 1 , true );
2534
- printTextCenter (" Cfg Eth" , 12 * 3 , QW_FONT_8X16, 1 , false );
2535
- }
2536
- }
2537
- else if (setupState == STATE_CONFIG_VIA_ETH_NOT_STARTED)
2538
- {
2539
- printTextCenter (" Base" , 12 * 0 , QW_FONT_8X16, 1 , false ); // string, y, font type, kerning, inverted
2540
- printTextCenter (" Rover" , 12 * 1 , QW_FONT_8X16, 1 , false );
2541
- printTextCenter (" NTP" , 12 * 2 , QW_FONT_8X16, 1 , false );
2542
- printTextCenter (" Cfg Eth" , 12 * 3 , QW_FONT_8X16, 1 , true );
2543
- }
2544
- else if (setupState == STATE_WIFI_CONFIG_NOT_STARTED)
2545
- {
2546
- if (present.ethernet_ws5500 == true )
2547
- {
2548
- printTextCenter (" Rover" , 12 * 0 , QW_FONT_8X16, 1 , false ); // string, y, font type, kerning, inverted
2549
- printTextCenter (" NTP" , 12 * 1 , QW_FONT_8X16, 1 , false );
2550
- printTextCenter (" Cfg Eth" , 12 * 2 , QW_FONT_8X16, 1 , false );
2551
- printTextCenter (" CfgWiFi" , 12 * 3 , QW_FONT_8X16, 1 , true );
2552
- }
2553
- else
2554
- {
2555
- printTextCenter (" Mark" , 12 * 0 , QW_FONT_8X16, 1 , false );
2556
- printTextCenter (" Rover" , 12 * 1 , QW_FONT_8X16, 1 , false );
2557
- printTextCenter (" Base" , 12 * 2 , QW_FONT_8X16, 1 , false );
2558
- printTextCenter (" Config" , 12 * 3 , QW_FONT_8X16, 1 , true );
2471
+ if (printedButtons < maxButtons) // Do we have room to display it?
2472
+ {
2473
+ if (theButton.newState == STATE_PROFILE)
2474
+ {
2475
+ int nameWidth = ((present.display_type == DISPLAY_128x64) ? 17 : 9 );
2476
+ char miniProfileName[nameWidth] = {0 };
2477
+ snprintf (miniProfileName, sizeof (miniProfileName), " %d_%s" , theButton.newProfile , theButton.name ); // Prefix with index #
2478
+ printTextCenter (miniProfileName, 12 * printedButtons, QW_FONT_8X16, 1 , printedButtons == 0 );
2479
+ }
2480
+ else
2481
+ printTextCenter (theButton.name , 12 * printedButtons, QW_FONT_8X16, 1 , printedButtons == 0 );
2482
+ printedButtons++;
2483
+ }
2559
2484
}
2560
- }
2561
2485
2562
- // If we are on an L-Band unit, display GetKeys option
2563
- else if (setupState == STATE_KEYS_NEEDED)
2564
- {
2565
- printTextCenter (" Rover" , 12 * 0 , QW_FONT_8X16, 1 , false );
2566
- printTextCenter (" Base" , 12 * 1 , QW_FONT_8X16, 1 , false );
2567
- printTextCenter (" Config" , 12 * 2 , QW_FONT_8X16, 1 , false );
2568
- printTextCenter (" GetKeys" , 12 * 3 , QW_FONT_8X16, 1 , true );
2486
+ thisIsButton++;
2569
2487
}
2570
2488
2571
- else if (setupState == STATE_ESPNOW_PAIRING_NOT_STARTED)
2489
+ // If we printed less than maxButtons, print more.
2490
+ // This causes Base to be printed below Exit, indicating you can "go round again".
2491
+ // I think that's what we want?
2492
+ // If not, we could comment this and leave the display blank below Exit.
2493
+ while (printedButtons < maxButtons)
2572
2494
{
2573
- if (present.ethernet_ws5500 == true )
2574
- {
2575
- printTextCenter (" NTP" , 12 * 0 , QW_FONT_8X16, 1 , false ); // string, y, font type, kerning, inverted
2576
- printTextCenter (" Cfg Eth" , 12 * 1 , QW_FONT_8X16, 1 , false );
2577
- printTextCenter (" CfgWiFi" , 12 * 2 , QW_FONT_8X16, 1 , false );
2578
- printTextCenter (" E-Pair" , 12 * 3 , QW_FONT_8X16, 1 , true );
2579
- }
2580
- else if (settings.pointPerfectCorrectionsSource != POINTPERFECT_CORRECTIONS_DISABLED)
2581
- {
2582
- // If we are on an L-Band unit, scroll GetKeys option
2583
- printTextCenter (" Base" , 12 * 0 , QW_FONT_8X16, 1 , false );
2584
- printTextCenter (" Config" , 12 * 1 , QW_FONT_8X16, 1 , false );
2585
- printTextCenter (" GetKeys" , 12 * 2 , QW_FONT_8X16, 1 , false );
2586
- printTextCenter (" E-Pair" , 12 * 3 , QW_FONT_8X16, 1 , true );
2587
- }
2588
- else
2495
+ for (auto it = setupButtons.begin (); it != setupButtons.end (); it = std::next (it))
2589
2496
{
2590
- printTextCenter (" Rover" , 12 * 0 , QW_FONT_8X16, 1 , false );
2591
- printTextCenter (" Base" , 12 * 1 , QW_FONT_8X16, 1 , false );
2592
- printTextCenter (" Config" , 12 * 2 , QW_FONT_8X16, 1 , false );
2593
- printTextCenter (" E-Pair" , 12 * 3 , QW_FONT_8X16, 1 , true );
2497
+ setupButton theButton = *it;
2498
+
2499
+ if (printedButtons < maxButtons) // Do we have room to display it?
2500
+ {
2501
+ printTextCenter (theButton.name , 12 * printedButtons, QW_FONT_8X16, 1 , printedButtons == 0 );
2502
+ printedButtons++;
2503
+ }
2504
+
2505
+ if (printedButtons == maxButtons)
2506
+ break ;
2594
2507
}
2595
2508
}
2596
-
2597
- else if (setupState == STATE_PROFILE)
2598
- paintDisplaySetupProfile (" Base" );
2599
2509
}
2600
2510
2601
2511
// Given text, and location, print text center of the screen
@@ -2635,6 +2545,24 @@ void printTextCenter(const char *text, uint8_t yPos, QwiicFont &fontType, uint8_
2635
2545
}
2636
2546
}
2637
2547
2548
+ // Given text, and location, print text to the screen
2549
+ void printTextAt (const char *text, uint8_t xPos, uint8_t yPos, QwiicFont &fontType, uint8_t kerning) // text, x, y, font type, kearning, inverted
2550
+ {
2551
+ oled->setFont (fontType);
2552
+ oled->setDrawMode (grROPXOR);
2553
+
2554
+ uint8_t fontWidth = fontType.width ;
2555
+ if (fontWidth == 8 )
2556
+ fontWidth = 7 ; // 8x16, but widest character is only 7 pixels.
2557
+
2558
+ for (int x = 0 ; x < strlen (text); x++)
2559
+ {
2560
+ oled->setCursor (xPos, yPos);
2561
+ oled->print (text[x]);
2562
+ xPos += fontWidth + kerning;
2563
+ }
2564
+ }
2565
+
2638
2566
// Given a message (one or two words) display centered
2639
2567
void displayMessage (const char *message, uint16_t displayTime)
2640
2568
{
0 commit comments