summaryrefslogtreecommitdiff
path: root/src/DisplayApp/Screens/ScreenList.cpp
blob: 48f71649f3621c05e4adb7a40d5d56010aa6f73c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#include <libs/lvgl/lvgl.h>
#include <DisplayApp/DisplayApp.h>
#include "ScreenList.h"

using namespace Pinetime::Applications::Screens;

// TODO this class must be improved to receive the list of "sub screens" via pointer or
// move operation.
// It should accept many type of "sub screen" (it only supports Label for now).
// The number of sub screen it supports must be dynamic.
ScreenList::ScreenList(Pinetime::Applications::DisplayApp *app,
        Pinetime::Controllers::DateTime &dateTimeController,
        Pinetime::Controllers::Battery& batteryController,
        Pinetime::Controllers::BrightnessController& brightnessController,
                       Pinetime::Controllers::Ble& bleController,
        Pinetime::Drivers::WatchdogView& watchdog) :
        Screen(app),
        dateTimeController{dateTimeController}, batteryController{batteryController},
        brightnessController{brightnessController}, bleController{bleController}, watchdog{watchdog} {
  screens.reserve(3);

  // TODO all of this is far too heavy (string processing). This should be improved.
  // TODO the info (battery, time,...) should be updated in the Refresh method.


  auto batteryPercent = static_cast<int16_t>(batteryController.PercentRemaining());
  if(batteryPercent > 100) batteryPercent = 100;
  else if(batteryPercent < 0) batteryPercent = 0;

  uint8_t brightness = 0;
  switch(brightnessController.Level()) {
    case Controllers::BrightnessController::Levels::Low: brightness = 1; break;
    case Controllers::BrightnessController::Levels::Medium: brightness = 2; break;
    case Controllers::BrightnessController::Levels::High: brightness = 3; break;
  }
  auto resetReason = [&watchdog]() {
    switch (watchdog.ResetReason()) {
      case Drivers::Watchdog::ResetReasons::Watchdog: return "wtdg";
      case Drivers::Watchdog::ResetReasons::HardReset: return "hardr";
      case Drivers::Watchdog::ResetReasons::NFC: return "nfc";
      case Drivers::Watchdog::ResetReasons::SoftReset: return "softr";
      case Drivers::Watchdog::ResetReasons::CpuLockup: return "cpulock";
      case Drivers::Watchdog::ResetReasons::SystemOff: return "off";
      case Drivers::Watchdog::ResetReasons::LpComp: return "lpcomp";
      case Drivers::Watchdog::ResetReasons::DebugInterface: return "dbg";
      case Drivers::Watchdog::ResetReasons::ResetPin: return "rst";
      default: return "?";
    }
  }();

  // uptime
  static constexpr uint32_t secondsInADay = 60*60*24;
  static constexpr uint32_t secondsInAnHour = 60*60;
  static constexpr uint32_t secondsInAMinute = 60;
  uint32_t uptimeSeconds = dateTimeController.Uptime().count();
  uint32_t uptimeDays = (uptimeSeconds / secondsInADay);
  uptimeSeconds = uptimeSeconds % secondsInADay;
  uint32_t uptimeHours = uptimeSeconds / secondsInAnHour;
  uptimeSeconds = uptimeSeconds % secondsInAnHour;
  uint32_t uptimeMinutes = uptimeSeconds / secondsInAMinute;
  uptimeSeconds = uptimeSeconds % secondsInAMinute;
  // TODO handle more than 100 days of uptime

  sprintf(t1, "Pinetime\n"
              "Version:%d.%d.%d\n"
              "Build: %s\n"
              "       %s\n"
              "Date: %02d/%02d/%04d\n"
              "Time: %02d:%02d:%02d\n"
              "Uptime: %02lud %02lu:%02lu:%02lu\n"
              "Battery: %d%%\n"
              "Backlight: %d/3\n"
              "Last reset: %s\n",
              Version::Major(), Version::Minor(), Version::Patch(),
              __DATE__, __TIME__,
              dateTimeController.Day(), dateTimeController.Month(), dateTimeController.Year(),
              dateTimeController.Hours(), dateTimeController.Minutes(), dateTimeController.Seconds(),
              uptimeDays, uptimeHours, uptimeMinutes, uptimeSeconds,
              batteryPercent, brightness, resetReason);

  screens.emplace_back(t1);

  auto& bleAddr = bleController.Address();
  sprintf(t2, "BLE MAC: \n  %2x:%2x:%2x:%2x:%2x:%2x",
          bleAddr[5], bleAddr[4], bleAddr[3], bleAddr[2], bleAddr[1], bleAddr[0]);
  screens.emplace_back(t2);

  strncpy(t3, "Hello from\nthe developper!", 27);

  screens.emplace_back(t3);

  auto &screen = screens[screenIndex];
  screen.Show();
}

ScreenList::~ScreenList() {
  lv_obj_clean(lv_scr_act());
}

bool ScreenList::Refresh() {
  auto &screen = screens[screenIndex];
  screen.Refresh();

  return running;
}

bool ScreenList::OnButtonPushed() {
  running = false;
  return true;
}

bool ScreenList::OnTouchEvent(Pinetime::Applications::TouchEvents event) {
  switch (event) {
    case TouchEvents::SwipeDown:
      if (screenIndex > 0) {
        app->SetFullRefresh(DisplayApp::FullRefreshDirections::Down);
        auto &oldScreen = screens[screenIndex];
        oldScreen.Hide();
        screenIndex--;
        auto &newScreen = screens[screenIndex];
        newScreen.Show();
      }
      return true;
    case TouchEvents::SwipeUp:
      app->SetFullRefresh(DisplayApp::FullRefreshDirections::Up);
      if (screenIndex < screens.size() - 1) {
        auto &oldScreen = screens[screenIndex];
        oldScreen.Hide();
        screenIndex++;
        auto &newScreen = screens[screenIndex];
        newScreen.Show();
      }
      return true;
    default:
      return false;
  }
  return false;
}