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

App controller #1840

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose Debug or Release")
project(pinetime VERSION 1.13.0 LANGUAGES C CXX ASM)

set(CMAKE_C_STANDARD 99)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD 17)

# set(CMAKE_GENERATOR "Unix Makefiles")
set(CMAKE_C_EXTENSIONS OFF)
Expand Down
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,7 @@ set(INCLUDE_FILES
displayapp/Messages.h
displayapp/TouchEvents.h
displayapp/screens/Screen.h
displayapp/screens/AppController.h
displayapp/screens/Clock.h
displayapp/screens/Tile.h
displayapp/screens/InfiniPaint.h
Expand Down
6 changes: 3 additions & 3 deletions src/displayapp/Apps.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Pinetime {
namespace Applications {
enum class Apps {
enum class Apps : uint8_t {
None,
Launcher,
Clock,
Expand All @@ -18,7 +18,6 @@ namespace Pinetime {
Music,
Paint,
Paddle,
Twos,
HeartRate,
Navigation,
StopWatch,
Expand All @@ -37,7 +36,8 @@ namespace Pinetime {
SettingChimes,
SettingShakeThreshold,
SettingBluetooth,
Error
Error,
Dynamic,
};
}
}
89 changes: 55 additions & 34 deletions src/displayapp/DisplayApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,9 @@ void DisplayApp::Start(System::BootErrors error) {
lvgl.Init();

if (error == System::BootErrors::TouchController) {
LoadNewScreen(Apps::Error, DisplayApp::FullRefreshDirections::None);
LoadNewScreen(static_cast<uint8_t>(Apps::Error), DisplayApp::FullRefreshDirections::None);
} else {
LoadNewScreen(Apps::Clock, DisplayApp::FullRefreshDirections::None);
LoadNewScreen(static_cast<uint8_t>(Apps::Clock), DisplayApp::FullRefreshDirections::None);
}

if (pdPASS != xTaskCreate(DisplayApp::Process, "displayapp", 800, this, 0, &taskHandle)) {
Expand Down Expand Up @@ -240,31 +240,31 @@ void DisplayApp::Refresh() {
// Screens::Clock::BleConnectionStates::NotConnected);
break;
case Messages::NewNotification:
LoadNewScreen(Apps::NotificationsPreview, DisplayApp::FullRefreshDirections::Down);
LoadNewScreen(static_cast<uint8_t>(Apps::NotificationsPreview), DisplayApp::FullRefreshDirections::Down);
break;
case Messages::TimerDone:
if (state != States::Running) {
PushMessageToSystemTask(System::Messages::GoToRunning);
}
if (currentApp == Apps::Timer) {
if (currentApp == static_cast<uint8_t>(Apps::Timer)) {
lv_disp_trig_activity(nullptr);
auto* timer = static_cast<Screens::Timer*>(currentScreen.get());
timer->Reset();
} else {
LoadNewScreen(Apps::Timer, DisplayApp::FullRefreshDirections::Up);
LoadNewScreen(static_cast<uint8_t>(Apps::Timer), DisplayApp::FullRefreshDirections::Up);
}
motorController.RunForDuration(35);
break;
case Messages::AlarmTriggered:
if (currentApp == Apps::Alarm) {
if (currentApp == static_cast<uint8_t>(Apps::Alarm)) {
auto* alarm = static_cast<Screens::Alarm*>(currentScreen.get());
alarm->SetAlerting();
} else {
LoadNewScreen(Apps::Alarm, DisplayApp::FullRefreshDirections::None);
LoadNewScreen(static_cast<uint8_t>(Apps::Alarm), DisplayApp::FullRefreshDirections::None);
}
break;
case Messages::ShowPairingKey:
LoadNewScreen(Apps::PassKey, DisplayApp::FullRefreshDirections::Up);
LoadNewScreen(static_cast<uint8_t>(Apps::PassKey), DisplayApp::FullRefreshDirections::Up);
motorController.RunForDuration(35);
break;
case Messages::TouchEvent: {
Expand All @@ -290,16 +290,16 @@ void DisplayApp::Refresh() {
}
};
if (!currentScreen->OnTouchEvent(gesture)) {
if (currentApp == Apps::Clock) {
if (currentApp == static_cast<uint8_t>(Apps::Clock)) {
switch (gesture) {
case TouchEvents::SwipeUp:
LoadNewScreen(Apps::Launcher, DisplayApp::FullRefreshDirections::Up);
LoadNewScreen(static_cast<uint8_t>(Apps::Launcher), DisplayApp::FullRefreshDirections::Up);
break;
case TouchEvents::SwipeDown:
LoadNewScreen(Apps::Notifications, DisplayApp::FullRefreshDirections::Down);
LoadNewScreen(static_cast<uint8_t>(Apps::Notifications), DisplayApp::FullRefreshDirections::Down);
break;
case TouchEvents::SwipeRight:
LoadNewScreen(Apps::QuickSettings, DisplayApp::FullRefreshDirections::RightAnim);
LoadNewScreen(static_cast<uint8_t>(Apps::QuickSettings), DisplayApp::FullRefreshDirections::RightAnim);
break;
case TouchEvents::DoubleTap:
PushMessageToSystemTask(System::Messages::GoToSleep);
Expand All @@ -316,38 +316,38 @@ void DisplayApp::Refresh() {
} break;
case Messages::ButtonPushed:
if (!currentScreen->OnButtonPushed()) {
if (currentApp == Apps::Clock) {
if (currentApp == static_cast<uint8_t>(Apps::Clock)) {
PushMessageToSystemTask(System::Messages::GoToSleep);
} else {
LoadPreviousScreen();
}
}
break;
case Messages::ButtonLongPressed:
if (currentApp != Apps::Clock) {
if (currentApp == Apps::Notifications) {
LoadNewScreen(Apps::Clock, DisplayApp::FullRefreshDirections::Up);
} else if (currentApp == Apps::QuickSettings) {
LoadNewScreen(Apps::Clock, DisplayApp::FullRefreshDirections::LeftAnim);
if (currentApp != static_cast<uint8_t>(Apps::Clock)) {
if (currentApp == static_cast<uint8_t>(Apps::Notifications)) {
LoadNewScreen(static_cast<uint8_t>(Apps::Clock), DisplayApp::FullRefreshDirections::Up);
} else if (currentApp == static_cast<uint8_t>(Apps::QuickSettings)) {
LoadNewScreen(static_cast<uint8_t>(Apps::Clock), DisplayApp::FullRefreshDirections::LeftAnim);
} else {
LoadNewScreen(Apps::Clock, DisplayApp::FullRefreshDirections::Down);
LoadNewScreen(static_cast<uint8_t>(Apps::Clock), DisplayApp::FullRefreshDirections::Down);
}
appStackDirections.Reset();
returnAppStack.Reset();
}
break;
case Messages::ButtonLongerPressed:
// Create reboot app and open it instead
LoadNewScreen(Apps::SysInfo, DisplayApp::FullRefreshDirections::Up);
LoadNewScreen(static_cast<uint8_t>(Apps::SysInfo), DisplayApp::FullRefreshDirections::Up);
break;
case Messages::ButtonDoubleClicked:
if (currentApp != Apps::Notifications && currentApp != Apps::NotificationsPreview) {
LoadNewScreen(Apps::Notifications, DisplayApp::FullRefreshDirections::Down);
if (currentApp != static_cast<uint8_t>(Apps::Notifications) && currentApp != static_cast<uint8_t>(Apps::NotificationsPreview)) {
LoadNewScreen(static_cast<uint8_t>(Apps::Notifications), DisplayApp::FullRefreshDirections::Down);
}
break;

case Messages::BleFirmwareUpdateStarted:
LoadNewScreen(Apps::FirmwareUpdate, DisplayApp::FullRefreshDirections::Down);
LoadNewScreen(static_cast<uint8_t>(Apps::FirmwareUpdate), DisplayApp::FullRefreshDirections::Down);
break;
case Messages::BleRadioEnableToggle:
PushMessageToSystemTask(System::Messages::BleRadioEnableToggle);
Expand All @@ -357,7 +357,7 @@ void DisplayApp::Refresh() {
// What should happen here?
break;
case Messages::Chime:
LoadNewScreen(Apps::Clock, DisplayApp::FullRefreshDirections::None);
LoadNewScreen(static_cast<uint8_t>(Apps::Clock), DisplayApp::FullRefreshDirections::None);
motorController.RunForDuration(35);
break;
case Messages::OnChargingEvent:
Expand All @@ -371,18 +371,18 @@ void DisplayApp::Refresh() {
currentScreen->OnTouchEvent(touchHandler.GetX(), touchHandler.GetY());
}

if (nextApp != Apps::None) {
if (nextApp != static_cast<uint8_t>(Apps::None)) {
LoadNewScreen(nextApp, nextDirection);
nextApp = Apps::None;
nextApp = static_cast<uint8_t>(Apps::None);
}
}

void DisplayApp::StartApp(Apps app, DisplayApp::FullRefreshDirections direction) {
void DisplayApp::StartApp(uint8_t app, DisplayApp::FullRefreshDirections direction) {
nextApp = app;
nextDirection = direction;
}

void DisplayApp::LoadNewScreen(Apps app, DisplayApp::FullRefreshDirections direction) {
void DisplayApp::LoadNewScreen(uint8_t app, DisplayApp::FullRefreshDirections direction) {
// Don't add the same screen to the stack back to back.
// This is mainly to fix an issue with receiving two notifications at the same time
// and shouldn't happen otherwise.
Expand All @@ -393,18 +393,23 @@ void DisplayApp::LoadNewScreen(Apps app, DisplayApp::FullRefreshDirections direc
LoadScreen(app, direction);
}

void DisplayApp::LoadScreen(Apps app, DisplayApp::FullRefreshDirections direction) {
void DisplayApp::LoadScreen(uint8_t app, DisplayApp::FullRefreshDirections direction) {
lvgl.CancelTap();
lv_disp_trig_activity(nullptr);
motorController.StopRinging();

currentScreen.reset(nullptr);
SetFullRefresh(direction);

switch (app) {
switch (static_cast<Apps>(app)) {
case Apps::Launcher:
currentScreen =
std::make_unique<Screens::ApplicationList>(this, settingsController, batteryController, bleController, dateTimeController);
std::make_unique<Screens::ApplicationList>(this,
settingsController,
batteryController,
bleController,
dateTimeController,
appController);
break;
case Apps::Motion:
// currentScreen = std::make_unique<Screens::Motion>(motionController);
Expand Down Expand Up @@ -519,9 +524,9 @@ void DisplayApp::LoadScreen(Apps app, DisplayApp::FullRefreshDirections directio
case Apps::StopWatch:
currentScreen = std::make_unique<Screens::StopWatch>(*systemTask);
break;
case Apps::Twos:
currentScreen = std::make_unique<Screens::Twos>();
break;
// case Apps::Twos:
// currentScreen = std::make_unique<Screens::Twos>();
// break;
case Apps::Paint:
currentScreen = std::make_unique<Screens::InfiniPaint>(lvgl, motorController);
break;
Expand All @@ -548,6 +553,22 @@ void DisplayApp::LoadScreen(Apps app, DisplayApp::FullRefreshDirections directio
case Apps::Steps:
currentScreen = std::make_unique<Screens::Steps>(motionController, settingsController);
break;
default:
{
// Pinetime::Applications::AppInterface appInterface = {
// &lvgl,
// motorController,
// settingsController,
// alarmController,
// timer,
// heartRateController,
// systemTask,
// systemTask->nimble().music(),
// systemTask->nimble().navigation()
// };
currentScreen = appController.Get(app - static_cast<uint8_t>(Apps::Dynamic));
}
break;
}
currentApp = app;
}
Expand Down
16 changes: 9 additions & 7 deletions src/displayapp/DisplayApp.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "components/firmwarevalidator/FirmwareValidator.h"
#include "components/settings/Settings.h"
#include "displayapp/screens/Screen.h"
#include "displayapp/screens/AppController.h"
#include "components/timer/Timer.h"
#include "components/alarm/AlarmController.h"
#include "touchhandler/TouchHandler.h"
Expand Down Expand Up @@ -68,7 +69,7 @@ namespace Pinetime {
void Start(System::BootErrors error);
void PushMessage(Display::Messages msg);

void StartApp(Apps app, DisplayApp::FullRefreshDirections direction);
void StartApp(uint8_t app, DisplayApp::FullRefreshDirections direction);

void SetFullRefresh(FullRefreshDirections direction);

Expand All @@ -91,6 +92,7 @@ namespace Pinetime {
Pinetime::Controllers::BrightnessController& brightnessController;
Pinetime::Controllers::TouchHandler& touchHandler;
Pinetime::Controllers::FS& filesystem;
Pinetime::Applications::AppController appController;

Pinetime::Controllers::FirmwareValidator validator;
Pinetime::Components::LittleVgl lvgl;
Expand All @@ -106,26 +108,26 @@ namespace Pinetime {

std::unique_ptr<Screens::Screen> currentScreen;

Apps currentApp = Apps::None;
Apps returnToApp = Apps::None;
uint8_t currentApp = static_cast<uint8_t>(Apps::None);
uint8_t returnToApp = static_cast<uint8_t>(Apps::None);
FullRefreshDirections returnDirection = FullRefreshDirections::None;
TouchEvents returnTouchEvent = TouchEvents::None;

TouchEvents GetGesture();
static void Process(void* instance);
void InitHw();
void Refresh();
void LoadNewScreen(Apps app, DisplayApp::FullRefreshDirections direction);
void LoadScreen(Apps app, DisplayApp::FullRefreshDirections direction);
void LoadNewScreen(uint8_t app, DisplayApp::FullRefreshDirections direction);
void LoadScreen(uint8_t app, DisplayApp::FullRefreshDirections direction);
void PushMessageToSystemTask(Pinetime::System::Messages message);

Apps nextApp = Apps::None;
uint8_t nextApp = static_cast<uint8_t>(Apps::None);
DisplayApp::FullRefreshDirections nextDirection;
System::BootErrors bootError;
void ApplyBrightness();

static constexpr size_t returnAppStackSize = 10;
Utility::StaticStack<Apps, returnAppStackSize> returnAppStack;
Utility::StaticStack<uint8_t, returnAppStackSize> returnAppStack;
Utility::StaticStack<FullRefreshDirections, returnAppStackSize> appStackDirections;

bool isDimmed = false;
Expand Down
9 changes: 9 additions & 0 deletions src/displayapp/screens/AppController.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#include "displayapp/screens/AppController.h"

using namespace Pinetime::Applications;

AppController::AppController() {
symbols[current_apps] = Twos::Symbol;
constructors[current_apps] = Twos::Get;
current_apps++;
};
56 changes: 56 additions & 0 deletions src/displayapp/screens/AppController.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#pragma once

#include <array>
#include <functional>
#include <memory>
#include <nrf_log.h>

#include "displayapp/Apps.h"
#include "displayapp/screens/Twos.h"


namespace Pinetime {
namespace Applications {
class DisplayApp;

using namespace Screens;

struct AppInterface {
// Pinetime::Components::LittleVgl* lvgl;
// Pinetime::Controllers::MotorController& motorController;
// Pinetime::Controllers::Settings& settingsController;
// Pinetime::Controllers::AlarmController& alarmController;
// Pinetime::Controllers::Timer timer;
// Pinetime::Controllers::HeartRateController& heartRateController;
// Pinetime::System::SystemTask* systemTask;
// Pinetime::Controllers::MusicService& musicService;
// Pinetime::Controllers::NavigationService& navigationService;
// Pinetime::Controllers::WeatherService& weatherService;
};

class AppController {
public:
AppController();

const char* GetSymbol(uint8_t app) const {
app -= static_cast<uint8_t>(Apps::Dynamic);
return symbols[app];
};

std::unique_ptr<Screens::Screen> Get(uint8_t app) const {
return constructors[app]();
};

uint8_t NApps() const {
return current_apps;
};

private:
uint8_t current_apps = 0;
static constexpr uint8_t MAX_APP_COUNT = 24;

std::array<const char*, MAX_APP_COUNT> symbols {};
std::array<std::function<std::unique_ptr<Screen>()>, MAX_APP_COUNT> constructors {};
};
}
}
Loading