Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add terminal watchface #932

Closed
wants to merge 38 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
88f0190
add terminal watchface
13werwolf13 Jan 12, 2022
6dfa141
typo fix
Jan 12, 2022
1808a78
typo fix
13werwolf13 Jan 12, 2022
79273fe
typo fix
13werwolf13 Jan 12, 2022
4c58476
typo fix
13werwolf13 Jan 12, 2022
7288301
add menue item
13werwolf13 Jan 12, 2022
e540d10
add patch
13werwolf13 Jan 13, 2022
d3fd348
time format
13werwolf13 Jan 13, 2022
471a4c9
time format
13werwolf13 Jan 13, 2022
3afedca
time format
13werwolf13 Jan 13, 2022
ebbb31a
typo fix
13werwolf13 Jan 14, 2022
fc246be
typo fix
13werwolf13 Jan 15, 2022
e2f7e31
typo fix
13werwolf13 Jan 17, 2022
d684988
Update src/displayapp/screens/WatchFaceTerminal.cpp
13werwolf13 Jan 18, 2022
477a3a7
Update src/displayapp/screens/WatchFaceTerminal.cpp
13werwolf13 Jan 18, 2022
0ed45a9
typo fix
13werwolf13 Jan 18, 2022
68d3d9b
add ble state text output
13werwolf13 Jan 20, 2022
fda1c08
add ble state text output
13werwolf13 Jan 20, 2022
eb8bd4d
add ble state text output
13werwolf13 Jan 20, 2022
1e4a676
no errors, no warnings, no work..
13werwolf13 Jan 21, 2022
74eea9f
some fixes
13werwolf13 Jan 22, 2022
bba34f6
some fixes
13werwolf13 Jan 22, 2022
6853166
Update src/displayapp/screens/WatchFaceTerminal.cpp
13werwolf13 Feb 2, 2022
471a843
Update src/displayapp/screens/WatchFaceTerminal.cpp
13werwolf13 Feb 2, 2022
b4669be
Update src/displayapp/screens/WatchFaceTerminal.cpp
13werwolf13 Feb 2, 2022
265fec5
Update src/displayapp/screens/WatchFaceTerminal.cpp
13werwolf13 Feb 2, 2022
342ce8c
Update src/displayapp/screens/WatchFaceTerminal.cpp
13werwolf13 Feb 2, 2022
e6c0f32
Update src/displayapp/screens/WatchFaceTerminal.h
13werwolf13 Feb 2, 2022
12e1b0f
Update src/displayapp/screens/WatchFaceTerminal.cpp
13werwolf13 Feb 2, 2022
25fdafc
Update src/displayapp/screens/WatchFaceTerminal.cpp
13werwolf13 Feb 2, 2022
6bc6c1a
Update src/displayapp/screens/WatchFaceTerminal.h
13werwolf13 Feb 2, 2022
af483be
Update src/displayapp/screens/WatchFaceTerminal.cpp
13werwolf13 Feb 2, 2022
4d85028
Update src/displayapp/screens/WatchFaceTerminal.cpp
13werwolf13 Feb 2, 2022
6959d8c
Update src/displayapp/screens/WatchFaceTerminal.cpp
13werwolf13 Feb 2, 2022
60b6b4e
Update src/displayapp/screens/WatchFaceTerminal.cpp
13werwolf13 Feb 2, 2022
757ca2d
Update src/displayapp/screens/WatchFaceTerminal.cpp
13werwolf13 Feb 2, 2022
3515616
Update src/displayapp/screens/WatchFaceTerminal.cpp
13werwolf13 Feb 2, 2022
138a655
Update src/displayapp/screens/WatchFaceTerminal.h
13werwolf13 Feb 2, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,7 @@ list(APPEND SOURCE_FILES
displayapp/icons/bg_clock.c
displayapp/screens/WatchFaceAnalog.cpp
displayapp/screens/WatchFaceDigital.cpp
displayapp/screens/WatchFaceTerminal.cpp
displayapp/screens/PineTimeStyle.cpp

##
Expand Down
24 changes: 17 additions & 7 deletions src/displayapp/screens/Clock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "components/settings/Settings.h"
#include "displayapp/DisplayApp.h"
#include "displayapp/screens/WatchFaceDigital.h"
#include "displayapp/screens/WatchFaceTerminal.h"
#include "displayapp/screens/WatchFaceAnalog.h"
#include "displayapp/screens/PineTimeStyle.h"

Expand Down Expand Up @@ -41,6 +42,9 @@ Clock::Clock(DisplayApp* app,
case 2:
return PineTimeStyleScreen();
break;
case 3:
return WatchFaceTerminalScreen();
break;
}
return WatchFaceDigitalScreen();
}()} {
Expand Down Expand Up @@ -76,11 +80,17 @@ std::unique_ptr<Screen> Clock::WatchFaceAnalogScreen() {
}

std::unique_ptr<Screen> Clock::PineTimeStyleScreen() {
return std::make_unique<Screens::PineTimeStyle>(app,
dateTimeController,
batteryController,
bleController,
notificatioManager,
settingsController,
motionController);
return std::make_unique<Screens::PineTimeStyle>(
app, dateTimeController, batteryController, bleController, notificatioManager, settingsController, motionController);
}

std::unique_ptr<Screen> Clock::WatchFaceTerminalScreen() {
return std::make_unique<Screens::WatchFaceTerminal>(app,
dateTimeController,
batteryController,
bleController,
notificatioManager,
settingsController,
heartRateController,
motionController);
}
1 change: 1 addition & 0 deletions src/displayapp/screens/Clock.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ namespace Pinetime {
std::unique_ptr<Screen> WatchFaceDigitalScreen();
std::unique_ptr<Screen> WatchFaceAnalogScreen();
std::unique_ptr<Screen> PineTimeStyleScreen();
std::unique_ptr<Screen> WatchFaceTerminalScreen();
};
}
}
Expand Down
205 changes: 205 additions & 0 deletions src/displayapp/screens/WatchFaceTerminal.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
#include "WatchFaceTerminal.h"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please use includes relative to the src directory, helps me greatly with the simulator

Suggested change
#include "WatchFaceTerminal.h"
#include "displayapp/screens/WatchFaceTerminal.h"


#include <date/date.h>
#include <lvgl/lvgl.h>
#include <cstdio>
#include "displayapp/screens/BatteryIcon.h"
#include "displayapp/screens/BleIcon.h"
#include "displayapp/screens/NotificationIcon.h"
#include "displayapp/screens/Symbols.h"
#include "components/battery/BatteryController.h"
#include "components/ble/BleController.h"
#include "components/ble/NotificationManager.h"
#include "components/heartrate/HeartRateController.h"
#include "components/motion/MotionController.h"
#include "components/settings/Settings.h"

using namespace Pinetime::Applications::Screens;

WatchFaceTerminal::WatchFaceTerminal(DisplayApp* app,
Controllers::DateTime& dateTimeController,
Controllers::Battery& batteryController,
Controllers::Ble& bleController,
Controllers::NotificationManager& notificatioManager,
Controllers::Settings& settingsController,
Controllers::HeartRateController& heartRateController,
Controllers::MotionController& motionController)
: Screen(app),
currentDateTime {{}},
dateTimeController {dateTimeController},
batteryController {batteryController},
bleController {bleController},
notificatioManager {notificatioManager},
settingsController {settingsController},
heartRateController {heartRateController},
motionController {motionController} {
settingsController.SetClockFace(3);

batteryIcon = lv_label_create(lv_scr_act(), nullptr);
lv_label_set_text(batteryIcon, Symbols::batteryFull);
lv_obj_align(batteryIcon, lv_scr_act(), LV_ALIGN_IN_BOTTOM_RIGHT, -5, 2);

batteryPlug = lv_label_create(lv_scr_act(), nullptr);
lv_label_set_text(batteryPlug, Symbols::plug);
lv_obj_align(batteryPlug, batteryIcon, LV_ALIGN_OUT_LEFT_MID, -5, 0);

batteryValue = lv_label_create(lv_scr_act(), nullptr);
lv_label_set_recolor(batteryValue, true);
lv_obj_align(batteryValue, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, -20);

connectState = lv_label_create(lv_scr_act(), nullptr);
lv_label_set_recolor(connectState, true);
lv_label_set_text(connectState, "[STAT]#387b54 Disconnected#");
lv_obj_align(connectState, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, 40);

// bleIcon = lv_label_create(lv_scr_act(), nullptr);
// lv_label_set_text(bleIcon, Symbols::bluetooth);
// lv_obj_align(bleIcon, batteryPlug, LV_ALIGN_OUT_LEFT_MID, -5, 0);

notificationIcon = lv_label_create(lv_scr_act(), NULL);
lv_label_set_text(notificationIcon, NotificationIcon::GetIcon(false));
lv_obj_align(notificationIcon, nullptr, LV_ALIGN_IN_TOP_LEFT, 10, 0);

label_date = lv_label_create(lv_scr_act(), nullptr);
lv_label_set_recolor(label_date, true);
lv_obj_align(label_date, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, -40);

label_prompt_1 = lv_label_create(lv_scr_act(), nullptr);
lv_obj_align(label_prompt_1, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, -80);
lv_label_set_text(label_prompt_1, "user@watch:~ $ now");

label_prompt_2 = lv_label_create(lv_scr_act(), nullptr);
lv_obj_align(label_prompt_2, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, 60);
lv_label_set_text(label_prompt_2, "user@watch:~ $");

label_time = lv_label_create(lv_scr_act(), nullptr);
lv_label_set_recolor(label_time, true);
lv_obj_align(label_time, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, -60);

backgroundLabel = lv_label_create(lv_scr_act(), nullptr);
lv_obj_set_click(backgroundLabel, true);
lv_label_set_long_mode(backgroundLabel, LV_LABEL_LONG_CROP);
lv_obj_set_size(backgroundLabel, 240, 240);
lv_obj_set_pos(backgroundLabel, 0, 0);
lv_label_set_text(backgroundLabel, "");

heartbeatValue = lv_label_create(lv_scr_act(), nullptr);
lv_label_set_recolor(heartbeatValue, true);
lv_label_set_text(heartbeatValue, "[L_HR]#ee3311 0 bpm#");
lv_obj_align(heartbeatValue, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, 20);

stepValue = lv_label_create(lv_scr_act(), nullptr);
lv_label_set_recolor(stepValue, true);
lv_label_set_text(stepValue, "[STEP]#ee3377 0 steps#");
lv_obj_align(stepValue, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, 0);

taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this);
Refresh();
}

WatchFaceTerminal::~WatchFaceTerminal() {
lv_task_del(taskRefresh);
lv_obj_clean(lv_scr_act());
}

void WatchFaceTerminal::Refresh() {
powerPresent = batteryController.IsPowerPresent();
if (powerPresent.IsUpdated()) {
lv_label_set_text_static(batteryPlug, BatteryIcon::GetPlugIcon(powerPresent.Get()));
}

batteryPercentRemaining = batteryController.PercentRemaining();
if (batteryPercentRemaining.IsUpdated()) {
auto batteryPercent = batteryPercentRemaining.Get();
if (batteryPercent == 100) {
lv_obj_set_style_local_text_color(batteryIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GREEN);
} else {
lv_obj_set_style_local_text_color(batteryIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE);
}
lv_label_set_text(batteryIcon, BatteryIcon::GetBatteryIcon(batteryPercent));
lv_label_set_text_fmt(batteryValue, "[BATT]#387b54 %d%\%#", batteryPercent);
}

bleState = bleController.IsConnected();
if (bleState.IsUpdated()) {
if (bleState.Get()) {
lv_label_set_text_static(connectState, "[STAT]#387b54 Connected#");
} else {
lv_label_set_text_static(connectState, "[STAT]#387b54 Disconnected#");
}
}

notificationState = notificatioManager.AreNewNotificationsAvailable();
if (notificationState.IsUpdated()) {
if (notificationState.Get() == true) {
lv_label_set_text(notificationIcon, NotificationIcon::GetIcon(true));
} else {
lv_label_set_text(notificationIcon, NotificationIcon::GetIcon(false));
}
}

currentDateTime = dateTimeController.CurrentDateTime();

if (currentDateTime.IsUpdated()) {
auto newDateTime = currentDateTime.Get();

auto dp = date::floor<date::days>(newDateTime);
auto time = date::make_time(newDateTime - dp);
auto yearMonthDay = date::year_month_day(dp);

auto year = static_cast<int>(yearMonthDay.year());
auto month = static_cast<Pinetime::Controllers::DateTime::Months>(static_cast<unsigned>(yearMonthDay.month()));
auto day = static_cast<unsigned>(yearMonthDay.day());
auto dayOfWeek = static_cast<Pinetime::Controllers::DateTime::Days>(date::weekday(yearMonthDay).iso_encoding());

uint8_t hour = time.hours().count();
uint8_t minute = time.minutes().count();
uint8_t second = time.seconds().count();

if (displayedHour != hour || displayedMinute != minute || displayedSecond != second) {
displayedHour = hour;
displayedMinute = minute;
displayedSecond = second;

if (settingsController.GetClockType() == Controllers::Settings::ClockType::H12) {
char ampmChar[3] = "AM";
if (hour == 0) {
hour = 12;
} else if (hour == 12) {
ampmChar[0] = 'P';
} else if (hour > 12) {
hour = hour - 12;
ampmChar[0] = 'P';
}
lv_label_set_text_fmt(label_time, "[TIME]#11cc55 %02d:%02d:%02d %s#", hour, minute, second, ampmChar);
} else {
lv_label_set_text_fmt(label_time, "[TIME]#11cc55 %02d:%02d:%02d", hour, minute, second);
}
}

if ((year != currentYear) || (month != currentMonth) || (dayOfWeek != currentDayOfWeek) || (day != currentDay)) {
lv_label_set_text_fmt(label_date, "[DATE]#007fff %04d.%02d.%02d#", short(year), char(month), char(day));

currentYear = year;
currentMonth = month;
currentDayOfWeek = dayOfWeek;
currentDay = day;
}
}

heartbeat = heartRateController.HeartRate();
heartbeatRunning = heartRateController.State() != Controllers::HeartRateController::States::Stopped;
if (heartbeat.IsUpdated() || heartbeatRunning.IsUpdated()) {
if (heartbeatRunning.Get()) {
lv_label_set_text_fmt(heartbeatValue, "[L_HR]#ee3311 %d bpm#", heartbeat.Get());
} else {
lv_label_set_text_static(heartbeatValue, "[L_HR]#ee3311 ---#");
}
}

stepCount = motionController.NbSteps();
motionSensorOk = motionController.IsSensorOk();
if (stepCount.IsUpdated() || motionSensorOk.IsUpdated()) {
lv_label_set_text_fmt(stepValue, "[STEP]#ee3377 %lu steps#", stepCount.Get());
}
}
88 changes: 88 additions & 0 deletions src/displayapp/screens/WatchFaceTerminal.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#pragma once

#include <lvgl/src/lv_core/lv_obj.h>
#include <chrono>
#include <cstdint>
#include <memory>
#include "displayapp/screens/Screen.h"
#include "components/datetime/DateTimeController.h"

namespace Pinetime {
namespace Controllers {
class Settings;
class Battery;
class Ble;
class NotificationManager;
class HeartRateController;
class MotionController;
}

namespace Applications {
namespace Screens {

class WatchFaceTerminal : public Screen {
public:
WatchFaceTerminal(DisplayApp* app,
Controllers::DateTime& dateTimeController,
Controllers::Battery& batteryController,
Controllers::Ble& bleController,
Controllers::NotificationManager& notificatioManager,
Controllers::Settings& settingsController,
Controllers::HeartRateController& heartRateController,
Controllers::MotionController& motionController);
~WatchFaceTerminal() override;

void Refresh() override;

void OnObjectEvent(lv_obj_t* pObj, lv_event_t i);

private:
uint8_t displayedHour = -1;
uint8_t displayedMinute = -1;
uint8_t displayedSecond = -1;

uint16_t currentYear = 1970;
Pinetime::Controllers::DateTime::Months currentMonth = Pinetime::Controllers::DateTime::Months::Unknown;
Pinetime::Controllers::DateTime::Days currentDayOfWeek = Pinetime::Controllers::DateTime::Days::Unknown;
uint8_t currentDay = 0;

DirtyValue<int> batteryPercentRemaining {};
13werwolf13 marked this conversation as resolved.
Show resolved Hide resolved
DirtyValue<bool> powerPresent {};
DirtyValue<bool> bleState {};
DirtyValue<std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds>> currentDateTime {};
DirtyValue<bool> motionSensorOk {};
DirtyValue<uint32_t> stepCount {};
DirtyValue<uint8_t> heartbeat {};
DirtyValue<bool> heartbeatRunning {};
DirtyValue<bool> notificationState {};

lv_obj_t* label_time;
lv_obj_t* label_date;
lv_obj_t* label_prompt_1;
lv_obj_t* label_prompt_2;
lv_obj_t* backgroundLabel;
lv_obj_t* batteryIcon;
lv_obj_t* bleIcon;
lv_obj_t* batteryPlug;
lv_obj_t* batteryValue;
lv_obj_t* heartbeatIcon;
lv_obj_t* heartbeatValue;
lv_obj_t* heartbeatBpm;
lv_obj_t* stepValue;
lv_obj_t* notificationIcon;
lv_obj_t* connectState;
lv_obj_t* bleValue;

Controllers::DateTime& dateTimeController;
Controllers::Battery& batteryController;
Controllers::Ble& bleController;
Controllers::NotificationManager& notificatioManager;
Controllers::Settings& settingsController;
Controllers::HeartRateController& heartRateController;
Controllers::MotionController& motionController;

lv_task_t* taskRefresh;
};
}
}
}
2 changes: 1 addition & 1 deletion src/displayapp/screens/settings/SettingWatchFace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace {
}
}

constexpr std::array<const char*, 3> SettingWatchFace::options;
constexpr std::array<const char*, 4> SettingWatchFace::options;

SettingWatchFace::SettingWatchFace(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::Settings& settingsController)
: Screen(app), settingsController {settingsController} {
Expand Down
2 changes: 1 addition & 1 deletion src/displayapp/screens/settings/SettingWatchFace.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ namespace Pinetime {
void UpdateSelected(lv_obj_t* object, lv_event_t event);

private:
static constexpr std::array<const char*, 3> options = {" Digital face", " Analog face", " PineTimeStyle"};
static constexpr std::array<const char*, 4> options = {" Digital face", " Analog face", " PineTimeStyle", " Terminal"};
Controllers::Settings& settingsController;

lv_obj_t* cbOption[options.size()];
Expand Down