Skip to content

Commit e7de0dc

Browse files
committed
Add list of pawn apps present in external flash
It's pretty hacky, I know
1 parent 90283b5 commit e7de0dc

11 files changed

Lines changed: 184 additions & 29 deletions

File tree

src/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,7 @@ list(APPEND SOURCE_FILES
405405
displayapp/screens/Styles.cpp
406406
displayapp/screens/WeatherSymbols.cpp
407407
displayapp/screens/Pawn.cpp
408+
displayapp/screens/PawnList.cpp
408409
displayapp/Colors.cpp
409410
displayapp/widgets/Counter.cpp
410411
displayapp/widgets/PageIndicator.cpp

src/displayapp/DisplayApp.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,15 @@ void DisplayApp::StartApp(Apps app, DisplayApp::FullRefreshDirections direction)
503503
nextDirection = direction;
504504
}
505505

506+
void DisplayApp::StartPawnApp(const char* path, DisplayApp::FullRefreshDirections direction) {
507+
nextApp = Apps::Pawn;
508+
nextDirection = direction;
509+
510+
int path_len = strlen(path);
511+
nextPawnFile = new char[path_len + 1];
512+
strcpy(nextPawnFile, path);
513+
}
514+
506515
void DisplayApp::LoadNewScreen(Apps app, DisplayApp::FullRefreshDirections direction) {
507516
// Don't add the same screen to the stack back to back.
508517
// This is mainly to fix an issue with receiving two notifications at the same time
@@ -651,6 +660,17 @@ void DisplayApp::LoadScreen(Apps app, DisplayApp::FullRefreshDirections directio
651660
case Apps::FlashLight:
652661
currentScreen = std::make_unique<Screens::FlashLight>(*systemTask, brightnessController);
653662
break;
663+
case Apps::Pawn:
664+
if (nextPawnFile) {
665+
currentScreen =
666+
std::make_unique<Screens::Pawn>(controllers, std::make_unique<Screens::Pawn::LfsFile>(controllers.filesystem, nextPawnFile));
667+
668+
delete nextPawnFile;
669+
nextPawnFile = nullptr;
670+
} else {
671+
currentScreen = std::make_unique<Screens::Pawn>(controllers);
672+
}
673+
break;
654674
default: {
655675
const auto* d = std::ranges::find_if(userApps, [app](const AppDescription& appDescription) {
656676
return appDescription.app == app;

src/displayapp/DisplayApp.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ namespace Pinetime {
7474
void PushMessage(Display::Messages msg);
7575

7676
void StartApp(Apps app, DisplayApp::FullRefreshDirections direction);
77+
void StartPawnApp(const char* path, DisplayApp::FullRefreshDirections direction);
7778

7879
void SetFullRefresh(FullRefreshDirections direction);
7980

@@ -131,6 +132,7 @@ namespace Pinetime {
131132
void PushMessageToSystemTask(Pinetime::System::Messages message);
132133

133134
Apps nextApp = Apps::None;
135+
char* nextPawnFile = nullptr;
134136
DisplayApp::FullRefreshDirections nextDirection;
135137
System::BootErrors bootError;
136138
void ApplyBrightness();

src/displayapp/UserApps.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "displayapp/screens/Alarm.h"
66
#include "displayapp/screens/Dice.h"
77
#include "displayapp/screens/Pawn.h"
8+
#include "displayapp/screens/PawnList.h"
89
#include "displayapp/screens/Timer.h"
910
#include "displayapp/screens/Twos.h"
1011
#include "displayapp/screens/Tile.h"

src/displayapp/apps/Apps.h.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ namespace Pinetime {
3232
Weather,
3333
PassKey,
3434
Pawn,
35+
PawnList,
3536
QuickSettings,
3637
Settings,
3738
SettingWatchFace,

src/displayapp/apps/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ if(DEFINED ENABLE_USERAPPS)
33
else ()
44
set(DEFAULT_USER_APP_TYPES "Apps::StopWatch")
55
set(DEFAULT_USER_APP_TYPES "${DEFAULT_USER_APP_TYPES}, Apps::Pawn")
6+
set(DEFAULT_USER_APP_TYPES "${DEFAULT_USER_APP_TYPES}, Apps::PawnList")
67
set(DEFAULT_USER_APP_TYPES "${DEFAULT_USER_APP_TYPES}, Apps::Alarm")
78
set(DEFAULT_USER_APP_TYPES "${DEFAULT_USER_APP_TYPES}, Apps::Timer")
89
set(DEFAULT_USER_APP_TYPES "${DEFAULT_USER_APP_TYPES}, Apps::Steps")

src/displayapp/screens/Pawn.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -573,11 +573,6 @@ int Pawn::LoadProgram() {
573573
return result;
574574
}
575575

576-
#include "program.h"
577-
578-
Pawn::Pawn(AppControllers& controllers) : Pawn(controllers, std::make_unique<LfsFile>(controllers.filesystem, "/flash.amx")) {
579-
}
580-
581576
Pawn::Pawn(AppControllers& controllers, std::unique_ptr<File> file) : controllers(controllers), file(std::move(file)) {
582577
int result = LoadProgram();
583578
if (result != AMX_ERR_NONE) {

src/displayapp/screens/Pawn.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,9 @@ namespace Pinetime {
146146
}
147147
};
148148

149-
Pawn(AppControllers& controllers);
149+
Pawn(AppControllers& controllers) : controllers(controllers) {
150+
// Should never be called, this constructor is only present for conformity to the apps interface
151+
}
150152
Pawn(AppControllers& controllers, std::unique_ptr<File> file);
151153
~Pawn() override;
152154

@@ -188,12 +190,12 @@ namespace Pinetime {
188190
static constexpr Apps app = Apps::Pawn;
189191
static constexpr const char* icon = "P";
190192

191-
static Screens::Screen* Create(AppControllers& controllers) {
192-
return new Screens::Pawn(controllers);
193+
static Screens::Screen* Create(AppControllers& /*controllers*/) {
194+
return nullptr;
193195
};
194196

195197
static bool IsAvailable(Pinetime::Controllers::FS& /*filesystem*/) {
196-
return true;
198+
return false;
197199
};
198200
};
199201
}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
#include "PawnList.h"
2+
3+
#include "components/fs/FS.h"
4+
#include "displayapp/DisplayApp.h"
5+
6+
using namespace Pinetime::Applications::Screens;
7+
8+
#define PAWN_EXTENSION ".amx"
9+
constexpr int appsPerScreen = 4;
10+
11+
void ButtonCallback(lv_obj_t* obj, lv_event_t event) {
12+
if (event == LV_EVENT_CLICKED) {
13+
PawnList::AppListing* data = static_cast<PawnList::AppListing*>(obj->user_data);
14+
data->pawnList->ButtonClickedHandler(data->index);
15+
}
16+
}
17+
18+
PawnList::PawnList(Pinetime::Controllers::FS& filesystem, Applications::DisplayApp* displayApp) : displayApp(displayApp) {
19+
lfs_dir_t dir;
20+
lfs_info info;
21+
if (filesystem.DirOpen("/apps", &dir) == LFS_ERR_OK) {
22+
int i = 0;
23+
24+
while (filesystem.DirRead(&dir, &info)) {
25+
if (info.type == LFS_TYPE_DIR)
26+
continue;
27+
28+
size_t len = strlen(info.name);
29+
if (len < sizeof(PAWN_EXTENSION) || strcmp(info.name + len - (sizeof(PAWN_EXTENSION) - 1), PAWN_EXTENSION) != 0)
30+
continue;
31+
32+
pawnApps.push_back(AppListing {
33+
.pawnList = this,
34+
.name = std::string(info.name, len - (sizeof(PAWN_EXTENSION) - 1)), // Remove extension
35+
.index = i++,
36+
});
37+
}
38+
39+
filesystem.DirClose(&dir);
40+
}
41+
42+
ShowScreen();
43+
}
44+
45+
PawnList::~PawnList() {
46+
lv_obj_clean(lv_scr_act());
47+
}
48+
49+
void PawnList::ButtonClickedHandler(int index) {
50+
char path[LFS_NAME_MAX];
51+
snprintf(path, sizeof(path), "/apps/%s" PAWN_EXTENSION, pawnApps[index].name.c_str());
52+
displayApp->StartPawnApp(path, Applications::DisplayApp::FullRefreshDirections::LeftAnim);
53+
}
54+
55+
bool PawnList::OnTouchEvent(TouchEvents event) {
56+
switch (event) {
57+
case TouchEvents::SwipeUp:
58+
if (currentScreen < pawnApps.size() / appsPerScreen) {
59+
currentScreen++;
60+
displayApp->SetFullRefresh(DisplayApp::FullRefreshDirections::Up);
61+
ShowScreen();
62+
return true;
63+
}
64+
break;
65+
66+
case TouchEvents::SwipeDown:
67+
if (currentScreen > 0) {
68+
currentScreen--;
69+
displayApp->SetFullRefresh(DisplayApp::FullRefreshDirections::Down);
70+
ShowScreen();
71+
return true;
72+
}
73+
break;
74+
75+
default:
76+
return false;
77+
}
78+
79+
return false;
80+
}
81+
82+
void PawnList::ShowScreen() {
83+
int relCount = 0;
84+
85+
lv_obj_clean(lv_scr_act());
86+
87+
for (size_t i = appsPerScreen * currentScreen; i < pawnApps.size(); i++) {
88+
lv_obj_t* btn = lv_btn_create(lv_scr_act(), nullptr);
89+
lv_obj_set_size(btn, 240, 240 / appsPerScreen);
90+
lv_obj_set_pos(btn, 0, relCount * 240 / appsPerScreen);
91+
lv_obj_set_event_cb(btn, ButtonCallback);
92+
lv_obj_set_user_data(btn, &pawnApps[i]);
93+
94+
lv_obj_t* label = lv_label_create(btn, nullptr);
95+
lv_label_set_long_mode(label, LV_LABEL_LONG_SROLL);
96+
lv_label_set_align(label, LV_LABEL_ALIGN_CENTER);
97+
lv_label_set_text_static(label, pawnApps[i].name.c_str());
98+
lv_obj_set_style_local_pad_hor(label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, 10);
99+
lv_obj_set_width(label, 240);
100+
101+
relCount++;
102+
}
103+
}

src/displayapp/screens/PawnList.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#pragma once
2+
3+
#include <vector>
4+
#include <string>
5+
#include "displayapp/apps/Apps.h"
6+
#include "Screen.h"
7+
#include "displayapp/Controllers.h"
8+
9+
namespace Pinetime {
10+
namespace Applications {
11+
namespace Screens {
12+
class PawnList : public Screen {
13+
public:
14+
struct AppListing {
15+
PawnList* pawnList;
16+
std::string name;
17+
int index;
18+
};
19+
20+
explicit PawnList(Pinetime::Controllers::FS& filesystem, Applications::DisplayApp* displayApp);
21+
~PawnList() override;
22+
23+
void ButtonClickedHandler(int n);
24+
bool OnTouchEvent(TouchEvents event) override;
25+
26+
private:
27+
std::vector<AppListing> pawnApps {};
28+
unsigned int currentScreen = 0;
29+
Applications::DisplayApp* displayApp;
30+
31+
void ShowScreen();
32+
};
33+
}
34+
35+
template <>
36+
struct AppTraits<Apps::PawnList> {
37+
static constexpr Apps app = Apps::PawnList;
38+
static constexpr const char* icon = "L";
39+
40+
static Screens::Screen* Create(AppControllers& controllers) {
41+
return new Screens::PawnList(controllers.filesystem, controllers.displayApp);
42+
};
43+
44+
static bool IsAvailable(Pinetime::Controllers::FS& /*filesystem*/) {
45+
return true;
46+
};
47+
};
48+
}
49+
}

0 commit comments

Comments
 (0)