aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/displayapp/DisplayApp.cpp1
-rw-r--r--src/displayapp/UserApps.h1
-rw-r--r--src/displayapp/apps/Apps.h.in1
-rw-r--r--src/displayapp/apps/CMakeLists.txt1
-rw-r--r--src/displayapp/fonts/fonts.json2
-rw-r--r--src/displayapp/screens/Dice.cpp199
-rw-r--r--src/displayapp/screens/Dice.h61
-rw-r--r--src/displayapp/screens/Symbols.h1
9 files changed, 268 insertions, 1 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 1b3de51c..0f872f46 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -390,6 +390,7 @@ list(APPEND SOURCE_FILES
displayapp/screens/BatteryInfo.cpp
displayapp/screens/Steps.cpp
displayapp/screens/Timer.cpp
+ displayapp/screens/Dice.cpp
displayapp/screens/PassKey.cpp
displayapp/screens/Error.cpp
displayapp/screens/Alarm.cpp
@@ -609,6 +610,7 @@ set(INCLUDE_FILES
displayapp/screens/Metronome.h
displayapp/screens/Motion.h
displayapp/screens/Timer.h
+ displayapp/screens/Dice.h
displayapp/screens/Alarm.h
displayapp/Colors.h
displayapp/widgets/Counter.h
diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp
index 938d1179..e5329b2d 100644
--- a/src/displayapp/DisplayApp.cpp
+++ b/src/displayapp/DisplayApp.cpp
@@ -26,6 +26,7 @@
#include "displayapp/screens/FlashLight.h"
#include "displayapp/screens/BatteryInfo.h"
#include "displayapp/screens/Steps.h"
+#include "displayapp/screens/Dice.h"
#include "displayapp/screens/PassKey.h"
#include "displayapp/screens/Error.h"
diff --git a/src/displayapp/UserApps.h b/src/displayapp/UserApps.h
index 0307035a..67bbfa7d 100644
--- a/src/displayapp/UserApps.h
+++ b/src/displayapp/UserApps.h
@@ -3,6 +3,7 @@
#include "Controllers.h"
#include "displayapp/screens/Alarm.h"
+#include "displayapp/screens/Dice.h"
#include "displayapp/screens/Timer.h"
#include "displayapp/screens/Twos.h"
#include "displayapp/screens/Tile.h"
diff --git a/src/displayapp/apps/Apps.h.in b/src/displayapp/apps/Apps.h.in
index e6e8d7dc..77d3b366 100644
--- a/src/displayapp/apps/Apps.h.in
+++ b/src/displayapp/apps/Apps.h.in
@@ -27,6 +27,7 @@ namespace Pinetime {
Metronome,
Motion,
Steps,
+ Dice,
PassKey,
QuickSettings,
Settings,
diff --git a/src/displayapp/apps/CMakeLists.txt b/src/displayapp/apps/CMakeLists.txt
index a531bdff..51c08595 100644
--- a/src/displayapp/apps/CMakeLists.txt
+++ b/src/displayapp/apps/CMakeLists.txt
@@ -10,6 +10,7 @@ else ()
set(DEFAULT_USER_APP_TYPES "${DEFAULT_USER_APP_TYPES}, Apps::Paint")
set(DEFAULT_USER_APP_TYPES "${DEFAULT_USER_APP_TYPES}, Apps::Paddle")
set(DEFAULT_USER_APP_TYPES "${DEFAULT_USER_APP_TYPES}, Apps::Twos")
+ set(DEFAULT_USER_APP_TYPES "${DEFAULT_USER_APP_TYPES}, Apps::Dice")
set(DEFAULT_USER_APP_TYPES "${DEFAULT_USER_APP_TYPES}, Apps::Metronome")
set(DEFAULT_USER_APP_TYPES "${DEFAULT_USER_APP_TYPES}, Apps::Navigation")
#set(DEFAULT_USER_APP_TYPES "${DEFAULT_USER_APP_TYPES}, Apps::Weather")
diff --git a/src/displayapp/fonts/fonts.json b/src/displayapp/fonts/fonts.json
index ead5239e..d9127dea 100644
--- a/src/displayapp/fonts/fonts.json
+++ b/src/displayapp/fonts/fonts.json
@@ -7,7 +7,7 @@
},
{
"file": "FontAwesome5-Solid+Brands+Regular.woff",
- "range": "0xf294, 0xf242, 0xf54b, 0xf21e, 0xf1e6, 0xf017, 0xf129, 0xf03a, 0xf185, 0xf560, 0xf001, 0xf3fd, 0xf1fc, 0xf45d, 0xf59f, 0xf5a0, 0xf027, 0xf028, 0xf6a9, 0xf04b, 0xf04c, 0xf048, 0xf051, 0xf095, 0xf3dd, 0xf04d, 0xf2f2, 0xf024, 0xf252, 0xf569, 0xf06e, 0xf015, 0xf00c, 0xf743"
+ "range": "0xf294, 0xf242, 0xf54b, 0xf21e, 0xf1e6, 0xf017, 0xf129, 0xf03a, 0xf185, 0xf560, 0xf001, 0xf3fd, 0xf1fc, 0xf45d, 0xf59f, 0xf5a0, 0xf027, 0xf028, 0xf6a9, 0xf04b, 0xf04c, 0xf048, 0xf051, 0xf095, 0xf3dd, 0xf04d, 0xf2f2, 0xf024, 0xf252, 0xf569, 0xf06e, 0xf015, 0xf00c, 0xf522, 0xf743"
}
],
"bpp": 1,
diff --git a/src/displayapp/screens/Dice.cpp b/src/displayapp/screens/Dice.cpp
new file mode 100644
index 00000000..302c5f3f
--- /dev/null
+++ b/src/displayapp/screens/Dice.cpp
@@ -0,0 +1,199 @@
+#include "displayapp/screens/Dice.h"
+#include "displayapp/screens/Screen.h"
+#include "displayapp/screens/Symbols.h"
+#include "components/settings/Settings.h"
+#include "components/motor/MotorController.h"
+#include "components/motion/MotionController.h"
+
+using namespace Pinetime::Applications::Screens;
+
+namespace {
+ lv_obj_t* MakeLabel(lv_font_t* font,
+ lv_color_t color,
+ lv_label_long_mode_t longMode,
+ uint8_t width,
+ lv_label_align_t labelAlignment,
+ const char* text,
+ lv_obj_t* reference,
+ lv_align_t alignment,
+ int8_t x,
+ int8_t y) {
+ lv_obj_t* label = lv_label_create(lv_scr_act(), nullptr);
+ lv_obj_set_style_local_text_font(label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font);
+ lv_obj_set_style_local_text_color(label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, color);
+ lv_label_set_long_mode(label, longMode);
+ if (width != 0) {
+ lv_obj_set_width(label, width);
+ }
+ lv_label_set_align(label, labelAlignment);
+ lv_label_set_text(label, text);
+ lv_obj_align(label, reference, alignment, x, y);
+ return label;
+ }
+
+ void btnRollEventHandler(lv_obj_t* obj, lv_event_t event) {
+ auto* screen = static_cast<Dice*>(obj->user_data);
+ if (event == LV_EVENT_CLICKED) {
+ screen->Roll();
+ }
+ }
+}
+
+Dice::Dice(Controllers::MotionController& motionController,
+ Controllers::MotorController& motorController,
+ Controllers::Settings& settingsController)
+ : motorController {motorController}, motionController {motionController}, settingsController {settingsController} {
+ std::seed_seq sseq {static_cast<uint32_t>(xTaskGetTickCount()),
+ static_cast<uint32_t>(motionController.X()),
+ static_cast<uint32_t>(motionController.Y()),
+ static_cast<uint32_t>(motionController.Z())};
+ gen.seed(sseq);
+
+ lv_obj_t* nCounterLabel = MakeLabel(&jetbrains_mono_bold_20,
+ LV_COLOR_WHITE,
+ LV_LABEL_LONG_EXPAND,
+ 0,
+ LV_LABEL_ALIGN_CENTER,
+ "count",
+ lv_scr_act(),
+ LV_ALIGN_IN_TOP_LEFT,
+ 0,
+ 0);
+
+ lv_obj_t* dCounterLabel = MakeLabel(&jetbrains_mono_bold_20,
+ LV_COLOR_WHITE,
+ LV_LABEL_LONG_EXPAND,
+ 0,
+ LV_LABEL_ALIGN_CENTER,
+ "sides",
+ nCounterLabel,
+ LV_ALIGN_OUT_RIGHT_MID,
+ 20,
+ 0);
+
+ nCounter.Create();
+ lv_obj_align(nCounter.GetObject(), nCounterLabel, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);
+ nCounter.SetValue(1);
+
+ dCounter.Create();
+ lv_obj_align(dCounter.GetObject(), dCounterLabel, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);
+ dCounter.SetValue(6);
+
+ std::uniform_int_distribution<> distrib(0, resultColors.size() - 1);
+ currentColorIndex = distrib(gen);
+
+ resultTotalLabel = MakeLabel(&jetbrains_mono_42,
+ resultColors[currentColorIndex],
+ LV_LABEL_LONG_BREAK,
+ 120,
+ LV_LABEL_ALIGN_CENTER,
+ "",
+ lv_scr_act(),
+ LV_ALIGN_IN_TOP_RIGHT,
+ 11,
+ 38);
+ resultIndividualLabel = MakeLabel(&jetbrains_mono_bold_20,
+ resultColors[currentColorIndex],
+ LV_LABEL_LONG_BREAK,
+ 90,
+ LV_LABEL_ALIGN_CENTER,
+ "",
+ resultTotalLabel,
+ LV_ALIGN_OUT_BOTTOM_MID,
+ 0,
+ 10);
+
+ Roll();
+ openingRoll = false;
+
+ btnRoll = lv_btn_create(lv_scr_act(), nullptr);
+ btnRoll->user_data = this;
+ lv_obj_set_event_cb(btnRoll, btnRollEventHandler);
+ lv_obj_set_size(btnRoll, 240, 50);
+ lv_obj_align(btnRoll, lv_scr_act(), LV_ALIGN_IN_BOTTOM_MID, 0, 0);
+
+ btnRollLabel = MakeLabel(&jetbrains_mono_bold_20,
+ LV_COLOR_WHITE,
+ LV_LABEL_LONG_EXPAND,
+ 0,
+ LV_LABEL_ALIGN_CENTER,
+ Symbols::dice,
+ btnRoll,
+ LV_ALIGN_CENTER,
+ 0,
+ 0);
+
+ // Spagetti code in motion controller: it only updates the shake speed when shake to wake is on...
+ enableShakeForDice = !settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::Shake);
+ if (enableShakeForDice) {
+ settingsController.setWakeUpMode(Pinetime::Controllers::Settings::WakeUpMode::Shake, true);
+ }
+ refreshTask = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this);
+}
+
+Dice::~Dice() {
+ // reset the shake to wake mode.
+ if (enableShakeForDice) {
+ settingsController.setWakeUpMode(Pinetime::Controllers::Settings::WakeUpMode::Shake, false);
+ enableShakeForDice = false;
+ }
+ lv_task_del(refreshTask);
+ lv_obj_clean(lv_scr_act());
+}
+
+void Dice::Refresh() {
+ // we only reset the hysteresis when at rest
+ if (motionController.CurrentShakeSpeed() >= settingsController.GetShakeThreshold()) {
+ if (currentRollHysteresis <= 0) {
+ // this timestamp is used for the screen timeout
+ lv_disp_get_next(NULL)->last_activity_time = lv_tick_get();
+
+ Roll();
+ }
+ } else if (currentRollHysteresis > 0)
+ --currentRollHysteresis;
+}
+
+void Dice::Roll() {
+ uint8_t resultIndividual;
+ uint16_t resultTotal = 0;
+ std::uniform_int_distribution<> distrib(1, dCounter.GetValue());
+
+ lv_label_set_text(resultIndividualLabel, "");
+
+ if (nCounter.GetValue() == 1) {
+ resultTotal = distrib(gen);
+ if (dCounter.GetValue() == 2) {
+ switch (resultTotal) {
+ case 1:
+ lv_label_set_text(resultIndividualLabel, "HEADS");
+ break;
+ case 2:
+ lv_label_set_text(resultIndividualLabel, "TAILS");
+ break;
+ }
+ }
+ } else {
+ for (uint8_t i = 0; i < nCounter.GetValue(); i++) {
+ resultIndividual = distrib(gen);
+ resultTotal += resultIndividual;
+ lv_label_ins_text(resultIndividualLabel, LV_LABEL_POS_LAST, std::to_string(resultIndividual).c_str());
+ if (i < (nCounter.GetValue() - 1)) {
+ lv_label_ins_text(resultIndividualLabel, LV_LABEL_POS_LAST, "+");
+ }
+ }
+ }
+
+ lv_label_set_text_fmt(resultTotalLabel, "%d", resultTotal);
+ if (openingRoll == false) {
+ motorController.RunForDuration(30);
+ NextColor();
+ currentRollHysteresis = rollHysteresis;
+ }
+}
+
+void Dice::NextColor() {
+ currentColorIndex = (currentColorIndex + 1) % resultColors.size();
+ lv_obj_set_style_local_text_color(resultTotalLabel, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, resultColors[currentColorIndex]);
+ lv_obj_set_style_local_text_color(resultIndividualLabel, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, resultColors[currentColorIndex]);
+}
diff --git a/src/displayapp/screens/Dice.h b/src/displayapp/screens/Dice.h
new file mode 100644
index 00000000..da91657d
--- /dev/null
+++ b/src/displayapp/screens/Dice.h
@@ -0,0 +1,61 @@
+#pragma once
+
+#include "displayapp/apps/Apps.h"
+#include "displayapp/screens/Screen.h"
+#include "displayapp/widgets/Counter.h"
+#include "displayapp/Controllers.h"
+#include "Symbols.h"
+
+#include <array>
+#include <random>
+
+namespace Pinetime {
+ namespace Applications {
+ namespace Screens {
+ class Dice : public Screen {
+ public:
+ Dice(Controllers::MotionController& motionController,
+ Controllers::MotorController& motorController,
+ Controllers::Settings& settingsController);
+ ~Dice() override;
+ void Roll();
+ void Refresh() override;
+
+ private:
+ lv_obj_t* btnRoll;
+ lv_obj_t* btnRollLabel;
+ lv_obj_t* resultTotalLabel;
+ lv_obj_t* resultIndividualLabel;
+ lv_task_t* refreshTask;
+ bool enableShakeForDice = false;
+
+ std::mt19937 gen;
+
+ std::array<lv_color_t, 3> resultColors = {LV_COLOR_YELLOW, LV_COLOR_MAGENTA, LV_COLOR_AQUA};
+ uint8_t currentColorIndex;
+ void NextColor();
+
+ Widgets::Counter nCounter = Widgets::Counter(1, 9, jetbrains_mono_42);
+ Widgets::Counter dCounter = Widgets::Counter(2, 99, jetbrains_mono_42);
+
+ bool openingRoll = true;
+ uint8_t currentRollHysteresis = 0;
+ static constexpr uint8_t rollHysteresis = 10;
+
+ Controllers::MotorController& motorController;
+ Controllers::MotionController& motionController;
+ Controllers::Settings& settingsController;
+ };
+ }
+
+ template <>
+ struct AppTraits<Apps::Dice> {
+ static constexpr Apps app = Apps::Dice;
+ static constexpr const char* icon = Screens::Symbols::dice;
+
+ static Screens::Screen* Create(AppControllers& controllers) {
+ return new Screens::Dice(controllers.motionController, controllers.motorController, controllers.settingsController);
+ };
+ };
+ }
+}
diff --git a/src/displayapp/screens/Symbols.h b/src/displayapp/screens/Symbols.h
index 549ea04f..4434194b 100644
--- a/src/displayapp/screens/Symbols.h
+++ b/src/displayapp/screens/Symbols.h
@@ -34,6 +34,7 @@ namespace Pinetime {
static constexpr const char* hourGlass = "\xEF\x89\x92";
static constexpr const char* lapsFlag = "\xEF\x80\xA4";
static constexpr const char* drum = "\xEF\x95\xA9";
+ static constexpr const char* dice = "\xEF\x94\xA2";
static constexpr const char* eye = "\xEF\x81\xAE";
static constexpr const char* home = "\xEF\x80\x95";
static constexpr const char* sleep = "\xEE\xBD\x84";