Merge develop into main (#339)
- Update ILI9341 driver to v2.0.1 - Lots of code cleanup for apps - Refactor app "type" into "category" and added flags to the manifest (for show/hide statusbar and for hidden apps) - Rename some ElfApp-related functionality and improved the way the static data was managed - Rename "filebrowser" to "files" - Added cstring functions to tt_init.cpp - Minor fix in Boot app - Updated external apps for SDK changes
This commit is contained in:
committed by
GitHub
parent
a2af95b92d
commit
faab6d825f
@@ -64,14 +64,14 @@ public:
|
||||
auto lock = getMutex().asScopedLock();
|
||||
lock.lock();
|
||||
|
||||
if (resultHolder != nullptr) {
|
||||
outResult = resultHolder->result;
|
||||
outBundle = std::move(resultHolder->resultData);
|
||||
resultHolder = nullptr;
|
||||
return true;
|
||||
} else {
|
||||
if (resultHolder == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
outResult = resultHolder->result;
|
||||
outBundle = std::move(resultHolder->resultData);
|
||||
resultHolder = nullptr;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ enum class Result;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
bool showStatusbar : 1;
|
||||
bool hideStatusbar : 1;
|
||||
};
|
||||
unsigned char flags;
|
||||
} Flags;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "Tactility/app/AppRegistration.h"
|
||||
#include <Tactility/app/AppRegistration.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
@@ -10,13 +10,7 @@ class App;
|
||||
class AppContext;
|
||||
|
||||
/** Application types */
|
||||
enum class Type {
|
||||
/** Boot screen, shown before desktop is launched. */
|
||||
Boot,
|
||||
/** A launcher app sits at the root of the app stack after the boot splash is finished */
|
||||
Launcher,
|
||||
/** Apps that generally aren't started from the desktop (e.g. image viewer) */
|
||||
Hidden,
|
||||
enum class Category {
|
||||
/** Standard apps, provided by the system. */
|
||||
System,
|
||||
/** The apps that are launched/shown by the Settings app. The Settings app itself is of type AppTypeSystem. */
|
||||
@@ -60,6 +54,15 @@ public:
|
||||
typedef std::shared_ptr<App>(*CreateApp)();
|
||||
|
||||
struct AppManifest {
|
||||
|
||||
struct Flags {
|
||||
constexpr static uint32_t None = 0;
|
||||
/** Don't show the statusbar */
|
||||
constexpr static uint32_t HideStatusBar = 1 << 0;
|
||||
/** Hint to other systems to not show this app (e.g. in launcher or settings) */
|
||||
constexpr static uint32_t Hidden = 1 << 1;
|
||||
};
|
||||
|
||||
/** The identifier by which the app is launched by the system and other apps. */
|
||||
std::string id = {};
|
||||
|
||||
@@ -69,12 +72,15 @@ struct AppManifest {
|
||||
/** Optional icon. */
|
||||
std::string icon = {};
|
||||
|
||||
/** App type affects launch behaviour. */
|
||||
Type type = Type::User;
|
||||
/** App category helps with listing apps in Launcher, app list or settings apps. */
|
||||
Category category = Category::User;
|
||||
|
||||
/** Where the app is located */
|
||||
Location location = Location::internal();
|
||||
|
||||
/** Controls various settings */
|
||||
uint32_t flags = Flags::None;
|
||||
|
||||
/** Create the instance of the app */
|
||||
CreateApp createApp = nullptr;
|
||||
};
|
||||
|
||||
@@ -14,9 +14,7 @@ typedef void (*OnShow)(void* appContext, void* _Nullable data, lv_obj_t* parent)
|
||||
typedef void (*OnHide)(void* appContext, void* _Nullable data);
|
||||
typedef void (*OnResult)(void* appContext, void* _Nullable data, LaunchId launchId, Result result, Bundle* resultData);
|
||||
|
||||
void setElfAppManifest(
|
||||
const char* name,
|
||||
const char* _Nullable icon,
|
||||
void setElfAppParameters(
|
||||
CreateData _Nullable createData,
|
||||
DestroyData _Nullable destroyData,
|
||||
OnCreate _Nullable onCreate,
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
#pragma once
|
||||
@@ -14,27 +14,28 @@
|
||||
*/
|
||||
namespace tt::app::alertdialog {
|
||||
|
||||
/**
|
||||
* Show a dialog with the provided title, message and 0, 1 or more buttons.
|
||||
* @param[in] title the title to show in the toolbar
|
||||
* @param[in] message the message to display
|
||||
* @param[in] buttonLabels the buttons to show
|
||||
* @return the launch id
|
||||
*/
|
||||
LaunchId start(const std::string& title, const std::string& message, const std::vector<std::string>& buttonLabels);
|
||||
/**
|
||||
* Show a dialog with the provided title, message and 0, 1 or more buttons.
|
||||
* @param[in] title the title to show in the toolbar
|
||||
* @param[in] message the message to display
|
||||
* @param[in] buttonLabels the buttons to show
|
||||
* @return the launch id
|
||||
*/
|
||||
LaunchId start(const std::string& title, const std::string& message, const std::vector<std::string>& buttonLabels);
|
||||
|
||||
/**
|
||||
* Show a dialog with the provided title, message and an OK button
|
||||
* @param[in] title the title to show in the toolbar
|
||||
* @param[in] message the message to display
|
||||
* @return the launch id
|
||||
*/
|
||||
LaunchId start(const std::string& title, const std::string& message);
|
||||
/**
|
||||
* Show a dialog with the provided title, message and an OK button
|
||||
* @param[in] title the title to show in the toolbar
|
||||
* @param[in] message the message to display
|
||||
* @return the launch id
|
||||
*/
|
||||
LaunchId start(const std::string& title, const std::string& message);
|
||||
|
||||
/**
|
||||
* Get the index of the button that the user selected.
|
||||
*
|
||||
* @return a value greater than 0 when a selection was done, or -1 when the app was closed clicking one of the selection buttons.
|
||||
*/
|
||||
int32_t getResultIndex(const Bundle& bundle);
|
||||
|
||||
/**
|
||||
* Get the index of the button that the user selected.
|
||||
*
|
||||
* @return a value greater than 0 when a selection was done, or -1 when the app was closed clicking one of the selection buttons.
|
||||
*/
|
||||
int32_t getResultIndex(const Bundle& bundle);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
namespace tt::app::filebrowser {
|
||||
namespace tt::app::files {
|
||||
|
||||
void start();
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#include <Tactility/Bundle.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* Start the app by its ID and provide:
|
||||
|
||||
@@ -15,12 +15,13 @@
|
||||
*/
|
||||
namespace tt::app::selectiondialog {
|
||||
|
||||
void start(const std::string& title, const std::vector<std::string>& items);
|
||||
void start(const std::string& title, const std::vector<std::string>& items);
|
||||
|
||||
/**
|
||||
* Get the index of the item that the user selected.
|
||||
*
|
||||
* @return a value greater than 0 when a selection was done, or -1 when the app was closed without selecting an item.
|
||||
*/
|
||||
int32_t getResultIndex(const Bundle& bundle);
|
||||
|
||||
/**
|
||||
* Get the index of the item that the user selected.
|
||||
*
|
||||
* @return a value greater than 0 when a selection was done, or -1 when the app was closed without selecting an item.
|
||||
*/
|
||||
int32_t getResultIndex(const Bundle& bundle);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "Tactility/app/AppContext.h"
|
||||
#include "Tactility/app/AppManifest.h"
|
||||
#include "Tactility/app/ElfApp.h"
|
||||
#include <Tactility/app/AppContext.h>
|
||||
#include <Tactility/app/AppManifest.h>
|
||||
#include <Tactility/app/ElfApp.h>
|
||||
|
||||
#include <Tactility/Bundle.h>
|
||||
#include <Tactility/Mutex.h>
|
||||
@@ -29,7 +29,7 @@ class AppInstance : public AppContext {
|
||||
const std::shared_ptr<AppManifest> manifest;
|
||||
State state = State::Initial;
|
||||
LaunchId launchId;
|
||||
Flags flags = { .showStatusbar = true };
|
||||
Flags flags = { .hideStatusbar = true };
|
||||
/** @brief Optional parameters to start the app with
|
||||
* When these are stored in the app struct, the struct takes ownership.
|
||||
* Do not mutate after app creation.
|
||||
|
||||
+5
-9
@@ -6,9 +6,9 @@
|
||||
#include <vector>
|
||||
#include <dirent.h>
|
||||
|
||||
namespace tt::app::filebrowser {
|
||||
namespace tt::app::files {
|
||||
|
||||
class State {
|
||||
class State final {
|
||||
|
||||
public:
|
||||
|
||||
@@ -44,7 +44,7 @@ public:
|
||||
|
||||
template <std::invocable<const std::vector<dirent> &> Func>
|
||||
void withEntries(Func&& onEntries) const {
|
||||
mutex.withLock([&]() {
|
||||
mutex.withLock([&] {
|
||||
std::invoke(std::forward<Func>(onEntries), dir_entries);
|
||||
});
|
||||
}
|
||||
@@ -61,13 +61,9 @@ public:
|
||||
|
||||
std::string getSelectedChildPath() const;
|
||||
|
||||
PendingAction getPendingAction() const {
|
||||
return action;
|
||||
}
|
||||
PendingAction getPendingAction() const { return action; }
|
||||
|
||||
void setPendingAction(PendingAction newAction) {
|
||||
action = newAction;
|
||||
}
|
||||
void setPendingAction(PendingAction newAction) { action = newAction; }
|
||||
};
|
||||
|
||||
}
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace tt::app::filebrowser {
|
||||
namespace tt::app::files {
|
||||
|
||||
bool isSupportedAppFile(const std::string& filename);
|
||||
bool isSupportedImageFile(const std::string& filename);
|
||||
+3
-3
@@ -2,14 +2,14 @@
|
||||
|
||||
#include "./State.h"
|
||||
|
||||
#include "Tactility/app/AppManifest.h"
|
||||
#include <Tactility/app/AppManifest.h>
|
||||
|
||||
#include <lvgl.h>
|
||||
#include <memory>
|
||||
|
||||
namespace tt::app::filebrowser {
|
||||
namespace tt::app::files {
|
||||
|
||||
class View {
|
||||
class View final {
|
||||
std::shared_ptr<State> state;
|
||||
|
||||
lv_obj_t* dir_entry_list = nullptr;
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
namespace tt::app::fileselection {
|
||||
|
||||
class State {
|
||||
class State final {
|
||||
|
||||
Mutex mutex = Mutex(Mutex::Type::Recursive);
|
||||
std::vector<dirent> dir_entries;
|
||||
|
||||
@@ -3,14 +3,14 @@
|
||||
#include "./State.h"
|
||||
#include "./FileSelectionPrivate.h"
|
||||
|
||||
#include "Tactility/app/AppManifest.h"
|
||||
#include <Tactility/app/AppManifest.h>
|
||||
|
||||
#include <lvgl.h>
|
||||
#include <memory>
|
||||
|
||||
namespace tt::app::fileselection {
|
||||
|
||||
class View {
|
||||
class View final {
|
||||
std::shared_ptr<State> state;
|
||||
|
||||
lv_obj_t* dir_entry_list = nullptr;
|
||||
|
||||
@@ -1,12 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <Tactility/hal/i2c/I2c.h>
|
||||
#include <Tactility/Mutex.h>
|
||||
#include <Tactility/TactilityCore.h>
|
||||
#include <Tactility/Thread.h>
|
||||
#include <Tactility/Timer.h>
|
||||
|
||||
#include <lvgl.h>
|
||||
#include <memory>
|
||||
|
||||
namespace tt::app::i2cscanner {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "Tactility/i18n/TextResources.h"
|
||||
#include <Tactility/i18n/TextResources.h>
|
||||
|
||||
// WARNING: This file is auto-generated. Do not edit manually.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "Tactility/i18n/TextResources.h"
|
||||
#include <Tactility/i18n/TextResources.h>
|
||||
|
||||
// WARNING: This file is auto-generated. Do not edit manually.
|
||||
|
||||
|
||||
+8
-8
@@ -1,13 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "./View.h"
|
||||
#include "View.h"
|
||||
|
||||
#include "Tactility/Preferences.h"
|
||||
#include "Tactility/Tactility.h"
|
||||
#include "Tactility/app/alertdialog/AlertDialog.h"
|
||||
#include "Tactility/hal/uart/Uart.h"
|
||||
#include "Tactility/lvgl/LvglSync.h"
|
||||
#include "Tactility/lvgl/Style.h"
|
||||
#include <Tactility/Preferences.h>
|
||||
#include <Tactility/Tactility.h>
|
||||
#include <Tactility/app/alertdialog/AlertDialog.h>
|
||||
#include <Tactility/hal/uart/Uart.h>
|
||||
#include <Tactility/lvgl/LvglSync.h>
|
||||
#include <Tactility/lvgl/Style.h>
|
||||
|
||||
#include <Tactility/StringUtils.h>
|
||||
#include <string>
|
||||
@@ -127,7 +127,7 @@ public:
|
||||
lv_obj_add_event_cb(connect_button, onConnectCallback, LV_EVENT_SHORT_CLICKED, this);
|
||||
}
|
||||
|
||||
void onStop() {
|
||||
void onStop() override {
|
||||
int speed = getSpeedInput();
|
||||
if (speed > 0) {
|
||||
preferences.putInt32("speed", speed);
|
||||
+5
-8
@@ -1,21 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "./View.h"
|
||||
#include "Tactility/Timer.h"
|
||||
#include <Tactility/app/serialconsole/View.h>
|
||||
#include <Tactility/Timer.h>
|
||||
#include <cstring>
|
||||
#include <sstream>
|
||||
|
||||
#define TAG "SerialConsole"
|
||||
|
||||
namespace tt::app::serialconsole {
|
||||
|
||||
constexpr auto* TAG = "SerialConsole";
|
||||
constexpr size_t receiveBufferSize = 512;
|
||||
constexpr size_t renderBufferSize = receiveBufferSize + 2; // Leave space for newline at split and null terminator at the end
|
||||
|
||||
class ConsoleView final : public View {
|
||||
|
||||
private:
|
||||
|
||||
lv_obj_t* _Nullable parent = nullptr;
|
||||
lv_obj_t* _Nullable logTextarea = nullptr;
|
||||
lv_obj_t* _Nullable inputTextarea = nullptr;
|
||||
@@ -215,7 +212,7 @@ public:
|
||||
viewThread = std::make_unique<Thread>(
|
||||
"SerConsView",
|
||||
4096,
|
||||
[this]() {
|
||||
[this] {
|
||||
return this->viewThreadMain();
|
||||
}
|
||||
);
|
||||
@@ -276,7 +273,7 @@ public:
|
||||
startViews(parent);
|
||||
}
|
||||
|
||||
void onStop() final {
|
||||
void onStop() override {
|
||||
stopViews();
|
||||
stopLogic();
|
||||
stopUart();
|
||||
-2
@@ -1,7 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <lvgl.h>
|
||||
|
||||
namespace tt::app::serialconsole {
|
||||
|
||||
class View {
|
||||
@@ -1,8 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <Tactility/Bundle.h>
|
||||
#include <Tactility/Mutex.h>
|
||||
#include <Tactility/service/wifi/Wifi.h>
|
||||
#include <string>
|
||||
|
||||
namespace tt::app::wifiapsettings {
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
namespace tt::app::wificonnect {
|
||||
|
||||
class State {
|
||||
class State final {
|
||||
Mutex lock;
|
||||
service::wifi::settings::WifiApSettings apSettings;
|
||||
bool connectionError = false;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include "./Bindings.h"
|
||||
#include "./State.h"
|
||||
|
||||
#include "Tactility/app/AppContext.h"
|
||||
#include <Tactility/app/AppContext.h>
|
||||
|
||||
#include <lvgl.h>
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace tt::app::wificonnect {
|
||||
|
||||
class WifiConnect;
|
||||
|
||||
class View {
|
||||
class View final {
|
||||
|
||||
Bindings* bindings;
|
||||
State* state;
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "Tactility/app/App.h"
|
||||
#include "Tactility/app/wificonnect/Bindings.h"
|
||||
#include "Tactility/app/wificonnect/State.h"
|
||||
#include "Tactility/app/wificonnect/View.h"
|
||||
#include <Tactility/app/App.h>
|
||||
#include <Tactility/app/wificonnect/Bindings.h>
|
||||
#include <Tactility/app/wificonnect/State.h>
|
||||
#include <Tactility/app/wificonnect/View.h>
|
||||
|
||||
#include <Tactility/Mutex.h>
|
||||
#include <Tactility/service/wifi/Wifi.h>
|
||||
|
||||
namespace tt::app::wificonnect {
|
||||
|
||||
class WifiConnect : public App {
|
||||
class WifiConnect final : public App {
|
||||
|
||||
Mutex mutex;
|
||||
State state;
|
||||
@@ -27,7 +27,7 @@ class WifiConnect : public App {
|
||||
public:
|
||||
|
||||
WifiConnect();
|
||||
~WifiConnect();
|
||||
~WifiConnect() override;
|
||||
|
||||
void lock();
|
||||
void unlock();
|
||||
@@ -39,7 +39,6 @@ public:
|
||||
Bindings& getBindings() { return bindings; }
|
||||
View& getView() { return view; }
|
||||
|
||||
|
||||
void requestViewUpdate();
|
||||
};
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace tt::app::wifimanage {
|
||||
/**
|
||||
* View's state
|
||||
*/
|
||||
class State {
|
||||
class State final {
|
||||
|
||||
Mutex mutex = Mutex(Mutex::Type::Recursive);
|
||||
bool scanning = false;
|
||||
@@ -32,7 +32,7 @@ public:
|
||||
|
||||
template <std::invocable<const std::vector<service::wifi::ApRecord>&> Func>
|
||||
void withApRecords(Func&& onApRecords) const {
|
||||
mutex.withLock([&]() {
|
||||
mutex.withLock([&] {
|
||||
std::invoke(std::forward<Func>(onApRecords), apRecords);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -3,19 +3,17 @@
|
||||
#include "./Bindings.h"
|
||||
#include "./State.h"
|
||||
|
||||
#include "Tactility/app/AppContext.h"
|
||||
#include <Tactility/app/AppContext.h>
|
||||
|
||||
#include <lvgl.h>
|
||||
|
||||
namespace tt::app::wifimanage {
|
||||
|
||||
class View {
|
||||
|
||||
private:
|
||||
class View final {
|
||||
|
||||
Bindings* bindings;
|
||||
State* state;
|
||||
std::unique_ptr<app::Paths> paths;
|
||||
std::unique_ptr<Paths> paths;
|
||||
lv_obj_t* root = nullptr;
|
||||
lv_obj_t* enable_switch = nullptr;
|
||||
lv_obj_t* enable_on_boot_switch = nullptr;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include "./View.h"
|
||||
#include "./State.h"
|
||||
|
||||
#include "Tactility/app/App.h"
|
||||
#include <Tactility/app/App.h>
|
||||
|
||||
#include <Tactility/PubSub.h>
|
||||
#include <Tactility/Mutex.h>
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
namespace tt::app::wifimanage {
|
||||
|
||||
class WifiManage : public App {
|
||||
class WifiManage final : public App {
|
||||
|
||||
PubSub<service::wifi::WifiEvent>::SubscriptionHandle wifiSubscription = nullptr;
|
||||
Mutex mutex;
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace app {
|
||||
namespace chat { extern const AppManifest manifest; }
|
||||
namespace development { extern const AppManifest manifest; }
|
||||
namespace display { extern const AppManifest manifest; }
|
||||
namespace filebrowser { extern const AppManifest manifest; }
|
||||
namespace files { extern const AppManifest manifest; }
|
||||
namespace fileselection { extern const AppManifest manifest; }
|
||||
namespace gpio { extern const AppManifest manifest; }
|
||||
namespace gpssettings { extern const AppManifest manifest; }
|
||||
@@ -102,7 +102,7 @@ static void registerSystemApps() {
|
||||
addApp(app::applist::manifest);
|
||||
addApp(app::calculator::manifest);
|
||||
addApp(app::display::manifest);
|
||||
addApp(app::filebrowser::manifest);
|
||||
addApp(app::files::manifest);
|
||||
addApp(app::fileselection::manifest);
|
||||
addApp(app::gpio::manifest);
|
||||
addApp(app::imageviewer::manifest);
|
||||
@@ -178,7 +178,7 @@ static void registerInstalledApp(std::string path) {
|
||||
app::addApp({
|
||||
.id = app_id_entry->second,
|
||||
.name = app_name_entry->second,
|
||||
.type = app::Type::User,
|
||||
.category = app::Category::User,
|
||||
.location = app::Location::external(path)
|
||||
});
|
||||
}
|
||||
|
||||
@@ -216,7 +216,7 @@ bool install(const std::string& path) {
|
||||
addApp({
|
||||
.id = app_id_iterator->second,
|
||||
.name = app_name_entry->second,
|
||||
.type = Type::User,
|
||||
.category = Category::User,
|
||||
.location = Location::external(renamed_target_path)
|
||||
});
|
||||
|
||||
|
||||
@@ -1,41 +1,22 @@
|
||||
#ifdef ESP_PLATFORM
|
||||
|
||||
#include "Tactility/app/ElfApp.h"
|
||||
#include "Tactility/file/File.h"
|
||||
#include "Tactility/file/FileLock.h"
|
||||
#include "Tactility/service/loader/Loader.h"
|
||||
|
||||
#include <Tactility/app/alertdialog/AlertDialog.h>
|
||||
#include <Tactility/app/ElfApp.h>
|
||||
#include <Tactility/file/File.h>
|
||||
#include <Tactility/file/FileLock.h>
|
||||
#include <Tactility/Log.h>
|
||||
#include <Tactility/service/loader/Loader.h>
|
||||
#include <Tactility/StringUtils.h>
|
||||
|
||||
#include "esp_elf.h"
|
||||
#include <esp_elf.h>
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <Tactility/app/alertdialog/AlertDialog.h>
|
||||
|
||||
namespace tt::app {
|
||||
|
||||
constexpr auto* TAG = "ElfApp";
|
||||
|
||||
struct ElfManifest {
|
||||
/** The user-readable name of the app. Used in UI. */
|
||||
std::string name;
|
||||
/** Optional icon. */
|
||||
std::string icon;
|
||||
CreateData _Nullable createData = nullptr;
|
||||
DestroyData _Nullable destroyData = nullptr;
|
||||
OnCreate _Nullable onCreate = nullptr;
|
||||
OnDestroy _Nullable onDestroy = nullptr;
|
||||
OnShow _Nullable onShow = nullptr;
|
||||
OnHide _Nullable onHide = nullptr;
|
||||
OnResult _Nullable onResult = nullptr;
|
||||
};
|
||||
|
||||
static size_t elfManifestSetCount = 0;
|
||||
static ElfManifest elfManifest;
|
||||
static std::shared_ptr<Lock> elfManifestLock = std::make_shared<Mutex>();
|
||||
|
||||
static std::string getErrorCodeString(int error_code) {
|
||||
switch (error_code) {
|
||||
case ENOMEM:
|
||||
@@ -47,7 +28,30 @@ static std::string getErrorCodeString(int error_code) {
|
||||
}
|
||||
}
|
||||
|
||||
class ElfApp : public App {
|
||||
class ElfApp final : public App {
|
||||
|
||||
public:
|
||||
|
||||
struct Parameters {
|
||||
CreateData _Nullable createData = nullptr;
|
||||
DestroyData _Nullable destroyData = nullptr;
|
||||
OnCreate _Nullable onCreate = nullptr;
|
||||
OnDestroy _Nullable onDestroy = nullptr;
|
||||
OnShow _Nullable onShow = nullptr;
|
||||
OnHide _Nullable onHide = nullptr;
|
||||
OnResult _Nullable onResult = nullptr;
|
||||
};
|
||||
|
||||
static void setParameters(const Parameters& parameters) {
|
||||
staticParameters = parameters;
|
||||
staticParametersSetCount++;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
static Parameters staticParameters;
|
||||
static size_t staticParametersSetCount;
|
||||
static std::shared_ptr<Lock> staticParametersLock;
|
||||
|
||||
const std::string appPath;
|
||||
std::unique_ptr<uint8_t[]> elfFileData;
|
||||
@@ -60,7 +64,7 @@ class ElfApp : public App {
|
||||
.entry = nullptr
|
||||
};
|
||||
bool shouldCleanupElf = false; // Whether we have to clean up the above "elf" object
|
||||
std::unique_ptr<ElfManifest> manifest;
|
||||
std::unique_ptr<Parameters> manifest;
|
||||
void* data = nullptr;
|
||||
std::string lastError = "";
|
||||
|
||||
@@ -128,10 +132,10 @@ public:
|
||||
void onCreate(AppContext& appContext) override {
|
||||
// Because we use global variables, we have to ensure that we are not starting 2 apps in parallel
|
||||
// We use a ScopedLock so we don't have to safeguard all branches
|
||||
auto lock = elfManifestLock->asScopedLock();
|
||||
auto lock = staticParametersLock->asScopedLock();
|
||||
lock.lock();
|
||||
|
||||
elfManifestSetCount = 0;
|
||||
staticParametersSetCount = 0;
|
||||
if (!startElf()) {
|
||||
service::loader::stopApp();
|
||||
auto message = lastError.empty() ? "Application failed to start." : std::format("Application failed to start: {}", lastError);
|
||||
@@ -139,13 +143,13 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
if (elfManifestSetCount == 0) {
|
||||
if (staticParametersSetCount == 0) {
|
||||
service::loader::stopApp();
|
||||
alertdialog::start("Error", "Application failed to start: application failed to register itself");
|
||||
return;
|
||||
}
|
||||
|
||||
manifest = std::make_unique<ElfManifest>(elfManifest);
|
||||
manifest = std::make_unique<Parameters>(staticParameters);
|
||||
lock.unlock();
|
||||
|
||||
if (manifest->createData != nullptr) {
|
||||
@@ -192,9 +196,11 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
void setElfAppManifest(
|
||||
const char* name,
|
||||
const char* _Nullable icon,
|
||||
ElfApp::Parameters ElfApp::staticParameters;
|
||||
size_t ElfApp::staticParametersSetCount = 0;
|
||||
std::shared_ptr<Lock> ElfApp::staticParametersLock = std::make_shared<Mutex>();
|
||||
|
||||
void setElfAppParameters(
|
||||
CreateData _Nullable createData,
|
||||
DestroyData _Nullable destroyData,
|
||||
OnCreate _Nullable onCreate,
|
||||
@@ -203,9 +209,7 @@ void setElfAppManifest(
|
||||
OnHide _Nullable onHide,
|
||||
OnResult _Nullable onResult
|
||||
) {
|
||||
elfManifest = ElfManifest {
|
||||
.name = name ? name : "",
|
||||
.icon = icon ? icon : "",
|
||||
ElfApp::setParameters({
|
||||
.createData = createData,
|
||||
.destroyData = destroyData,
|
||||
.onCreate = onCreate,
|
||||
@@ -213,8 +217,7 @@ void setElfAppManifest(
|
||||
.onShow = onShow,
|
||||
.onHide = onHide,
|
||||
.onResult = onResult
|
||||
};
|
||||
elfManifestSetCount++;
|
||||
});
|
||||
}
|
||||
|
||||
std::shared_ptr<App> createElfApp(const std::shared_ptr<AppManifest>& manifest) {
|
||||
|
||||
@@ -175,7 +175,8 @@ extern const AppManifest manifest = {
|
||||
.id = "AddGps",
|
||||
.name = "Add GPS",
|
||||
.icon = LV_SYMBOL_GPS,
|
||||
.type = Type::Hidden,
|
||||
.category = Category::System,
|
||||
.flags = AppManifest::Flags::Hidden,
|
||||
.createApp = create<AddGpsApp>
|
||||
};
|
||||
|
||||
|
||||
@@ -128,7 +128,8 @@ public:
|
||||
extern const AppManifest manifest = {
|
||||
.id = "AlertDialog",
|
||||
.name = "Alert Dialog",
|
||||
.type = Type::Hidden,
|
||||
.category = Category::System,
|
||||
.flags = AppManifest::Flags::Hidden,
|
||||
.createApp = create<AlertDialogApp>
|
||||
};
|
||||
|
||||
|
||||
@@ -40,7 +40,9 @@ public:
|
||||
std::ranges::sort(manifests, SortAppManifestByName);
|
||||
|
||||
for (const auto& manifest: manifests) {
|
||||
if (manifest->type == Type::User || manifest->type == Type::System) {
|
||||
bool is_valid_category = (manifest->category == Category::User) || (manifest->category == Category::System);
|
||||
bool is_visible = (manifest->flags & AppManifest::Flags::Hidden) == 0u;
|
||||
if (is_valid_category && is_visible) {
|
||||
createAppWidget(manifest, list);
|
||||
}
|
||||
}
|
||||
@@ -50,7 +52,8 @@ public:
|
||||
extern const AppManifest manifest = {
|
||||
.id = "AppList",
|
||||
.name = "Apps",
|
||||
.type = Type::Hidden,
|
||||
.category = Category::System,
|
||||
.flags = AppManifest::Flags::Hidden,
|
||||
.createApp = create<AppListApp>,
|
||||
};
|
||||
|
||||
|
||||
@@ -124,7 +124,6 @@ class BootApp : public App {
|
||||
settings::BootSettings boot_properties;
|
||||
if (!settings::loadBootSettings(boot_properties) || boot_properties.launcherAppId.empty()) {
|
||||
TT_LOG_E(TAG, "Launcher not configured");
|
||||
stop();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -164,7 +163,8 @@ public:
|
||||
extern const AppManifest manifest = {
|
||||
.id = "Boot",
|
||||
.name = "Boot",
|
||||
.type = Type::Boot,
|
||||
.category = Category::System,
|
||||
.flags = AppManifest::Flags::HideStatusBar | AppManifest::Flags::Hidden,
|
||||
.createApp = create<BootApp>
|
||||
};
|
||||
|
||||
|
||||
@@ -118,7 +118,8 @@ public:
|
||||
extern const AppManifest manifest = {
|
||||
.id = "CrashDiagnostics",
|
||||
.name = "Crash Diagnostics",
|
||||
.type = Type::Hidden,
|
||||
.category = Category::System,
|
||||
.flags = AppManifest::Flags::Hidden,
|
||||
.createApp = create<CrashDiagnosticsApp>
|
||||
};
|
||||
|
||||
|
||||
@@ -164,7 +164,7 @@ public:
|
||||
extern const AppManifest manifest = {
|
||||
.id = "Development",
|
||||
.name = "Development",
|
||||
.type = Type::Settings,
|
||||
.category = Category::Settings,
|
||||
.createApp = create<DevelopmentApp>
|
||||
};
|
||||
|
||||
|
||||
@@ -167,7 +167,7 @@ extern const AppManifest manifest = {
|
||||
.id = "Display",
|
||||
.name = "Display",
|
||||
.icon = TT_ASSETS_APP_ICON_DISPLAY_SETTINGS,
|
||||
.type = Type::Settings,
|
||||
.category = Category::Settings,
|
||||
.createApp = create<DisplayApp>
|
||||
};
|
||||
|
||||
|
||||
+11
-10
@@ -1,24 +1,24 @@
|
||||
#include "Tactility/app/filebrowser/View.h"
|
||||
#include "Tactility/app/filebrowser/State.h"
|
||||
#include "Tactility/app/AppContext.h"
|
||||
#include <Tactility/app/files/View.h>
|
||||
#include <Tactility/app/files/State.h>
|
||||
#include <Tactility/app/AppContext.h>
|
||||
|
||||
#include <Tactility/Assets.h>
|
||||
#include <Tactility/service/loader/Loader.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace tt::app::filebrowser {
|
||||
|
||||
constexpr auto* TAG = "FileBrowser";
|
||||
namespace tt::app::files {
|
||||
|
||||
extern const AppManifest manifest;
|
||||
|
||||
class FileBrowser : public App {
|
||||
class FilesApp final : public App {
|
||||
|
||||
std::unique_ptr<View> view;
|
||||
std::shared_ptr<State> state;
|
||||
|
||||
public:
|
||||
FileBrowser() {
|
||||
|
||||
FilesApp() {
|
||||
state = std::make_shared<State>();
|
||||
view = std::make_unique<View>(state);
|
||||
}
|
||||
@@ -36,8 +36,9 @@ extern const AppManifest manifest = {
|
||||
.id = "Files",
|
||||
.name = "Files",
|
||||
.icon = TT_ASSETS_APP_ICON_FILES,
|
||||
.type = Type::Hidden,
|
||||
.createApp = create<FileBrowser>
|
||||
.category = Category::System,
|
||||
.flags = AppManifest::Flags::Hidden,
|
||||
.createApp = create<FilesApp>
|
||||
};
|
||||
|
||||
void start() {
|
||||
@@ -1,7 +1,8 @@
|
||||
#include "Tactility/app/filebrowser/State.h"
|
||||
#include <Tactility/app/files/State.h>
|
||||
|
||||
#include <Tactility/file/File.h>
|
||||
#include "Tactility/hal/sdcard/SdCardDevice.h"
|
||||
#include <Tactility/file/FileLock.h>
|
||||
#include <Tactility/hal/sdcard/SdCardDevice.h>
|
||||
#include <Tactility/Log.h>
|
||||
#include <Tactility/MountPoints.h>
|
||||
#include <Tactility/kernel/Kernel.h>
|
||||
@@ -10,11 +11,10 @@
|
||||
#include <unistd.h>
|
||||
#include <vector>
|
||||
#include <dirent.h>
|
||||
#include <Tactility/file/FileLock.h>
|
||||
|
||||
namespace tt::app::filebrowser {
|
||||
namespace tt::app::files {
|
||||
|
||||
constexpr auto* TAG = "FileBrowser";
|
||||
constexpr auto* TAG = "Files";
|
||||
|
||||
State::State() {
|
||||
if (kernel::getPlatform() == kernel::PlatformSimulator) {
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
#include <Tactility/StringUtils.h>
|
||||
#include <Tactility/TactilityCore.h>
|
||||
|
||||
namespace tt::app::filebrowser {
|
||||
namespace tt::app::files {
|
||||
|
||||
constexpr auto* TAG = "FileBrowser";
|
||||
constexpr auto* TAG = "Files";
|
||||
|
||||
bool isSupportedAppFile(const std::string& filename) {
|
||||
return filename.ends_with(".app");
|
||||
@@ -1,13 +1,13 @@
|
||||
#include "Tactility/app/filebrowser/View.h"
|
||||
#include "Tactility/app/filebrowser/SupportedFiles.h"
|
||||
#include <Tactility/app/files/View.h>
|
||||
#include <Tactility/app/files/SupportedFiles.h>
|
||||
|
||||
#include "Tactility/app/alertdialog/AlertDialog.h"
|
||||
#include "Tactility/app/imageviewer/ImageViewer.h"
|
||||
#include "Tactility/app/inputdialog/InputDialog.h"
|
||||
#include "Tactility/app/notes/Notes.h"
|
||||
#include "Tactility/app/ElfApp.h"
|
||||
#include "Tactility/lvgl/Toolbar.h"
|
||||
#include "Tactility/lvgl/LvglSync.h"
|
||||
#include <Tactility/app/alertdialog/AlertDialog.h>
|
||||
#include <Tactility/app/imageviewer/ImageViewer.h>
|
||||
#include <Tactility/app/inputdialog/InputDialog.h>
|
||||
#include <Tactility/app/notes/Notes.h>
|
||||
#include <Tactility/app/ElfApp.h>
|
||||
#include <Tactility/lvgl/Toolbar.h>
|
||||
#include <Tactility/lvgl/LvglSync.h>
|
||||
|
||||
#include <Tactility/Tactility.h>
|
||||
#include <Tactility/file/File.h>
|
||||
@@ -19,17 +19,17 @@
|
||||
#include <Tactility/file/FileLock.h>
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
#include "Tactility/service/loader/Loader.h"
|
||||
#include <Tactility/service/loader/Loader.h>
|
||||
#endif
|
||||
|
||||
namespace tt::app::filebrowser {
|
||||
namespace tt::app::files {
|
||||
|
||||
constexpr auto* TAG = "FileBrowser";
|
||||
constexpr auto* TAG = "Files";
|
||||
|
||||
// region Callbacks
|
||||
|
||||
static void dirEntryListScrollBeginCallback(lv_event_t* event) {
|
||||
auto* view = static_cast<View*>(lv_event_get_user_data(event));
|
||||
auto* view = static_cast<files::View*>(lv_event_get_user_data(event));
|
||||
view->onDirEntryListScrollBegin();
|
||||
}
|
||||
|
||||
@@ -59,7 +59,8 @@ extern const AppManifest manifest = {
|
||||
.id = "FileSelection",
|
||||
.name = "File Selection",
|
||||
.icon = TT_ASSETS_APP_ICON_FILES,
|
||||
.type = Type::Hidden,
|
||||
.category = Category::System,
|
||||
.flags = AppManifest::Flags::Hidden,
|
||||
.createApp = create<FileSelection>
|
||||
};
|
||||
|
||||
|
||||
@@ -191,7 +191,7 @@ extern const AppManifest manifest = {
|
||||
.id = "Gpio",
|
||||
.name = "GPIO",
|
||||
.icon = TT_ASSETS_APP_ICON_GPIO,
|
||||
.type = Type::System,
|
||||
.category = Category::System,
|
||||
.createApp = create<GpioApp>
|
||||
};
|
||||
|
||||
|
||||
@@ -19,12 +19,12 @@ extern AppManifest manifest;
|
||||
|
||||
namespace tt::app::gpssettings {
|
||||
|
||||
constexpr const char* TAG = "GpsSettings";
|
||||
|
||||
extern const AppManifest manifest;
|
||||
|
||||
class GpsSettingsApp final : public App {
|
||||
|
||||
static constexpr auto* TAG = "GpsSettings";
|
||||
|
||||
std::unique_ptr<Timer> timer;
|
||||
std::shared_ptr<GpsSettingsApp*> appReference = std::make_shared<GpsSettingsApp*>(this);
|
||||
lv_obj_t* statusWrapper = nullptr;
|
||||
@@ -268,13 +268,13 @@ class GpsSettingsApp final : public App {
|
||||
public:
|
||||
|
||||
GpsSettingsApp() {
|
||||
timer = std::make_unique<Timer>(Timer::Type::Periodic, [this]() {
|
||||
timer = std::make_unique<Timer>(Timer::Type::Periodic, [this] {
|
||||
updateViews();
|
||||
});
|
||||
service = service::gps::findGpsService();
|
||||
}
|
||||
|
||||
void onShow(AppContext& app, lv_obj_t* parent) final {
|
||||
void onShow(AppContext& app, lv_obj_t* parent) override {
|
||||
lv_obj_set_flex_flow(parent, LV_FLEX_FLOW_COLUMN);
|
||||
lv_obj_set_style_pad_row(parent, 0, LV_STATE_DEFAULT);
|
||||
|
||||
@@ -337,7 +337,7 @@ public:
|
||||
updateViews();
|
||||
}
|
||||
|
||||
void onHide(AppContext& app) final {
|
||||
void onHide(AppContext& app) override {
|
||||
service->getStatePubsub()->unsubscribe(serviceStateSubscription);
|
||||
serviceStateSubscription = nullptr;
|
||||
}
|
||||
@@ -347,7 +347,7 @@ extern const AppManifest manifest = {
|
||||
.id = "GpsSettings",
|
||||
.name = "GPS",
|
||||
.icon = LV_SYMBOL_GPS,
|
||||
.type = Type::Settings,
|
||||
.category = Category::Settings,
|
||||
.createApp = create<GpsSettingsApp>
|
||||
};
|
||||
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
#include "Tactility/app/i2cscanner/I2cScannerPrivate.h"
|
||||
#include "Tactility/app/i2cscanner/I2cScannerThread.h"
|
||||
#include "Tactility/app/i2cscanner/I2cHelpers.h"
|
||||
#include <Tactility/app/i2cscanner/I2cScannerPrivate.h>
|
||||
#include <Tactility/app/i2cscanner/I2cHelpers.h>
|
||||
|
||||
#include "Tactility/Preferences.h"
|
||||
#include "Tactility/app/AppContext.h"
|
||||
#include "Tactility/hal/i2c/I2cDevice.h"
|
||||
#include "Tactility/lvgl/LvglSync.h"
|
||||
#include "Tactility/lvgl/Toolbar.h"
|
||||
#include "Tactility/service/loader/Loader.h"
|
||||
#include <Tactility/Preferences.h>
|
||||
#include <Tactility/app/AppContext.h>
|
||||
#include <Tactility/hal/i2c/I2cDevice.h>
|
||||
#include <Tactility/lvgl/LvglSync.h>
|
||||
#include <Tactility/lvgl/Toolbar.h>
|
||||
#include <Tactility/service/loader/Loader.h>
|
||||
|
||||
#include <Tactility/Assets.h>
|
||||
#include <Tactility/Tactility.h>
|
||||
@@ -15,14 +14,14 @@
|
||||
|
||||
#include <format>
|
||||
|
||||
#define START_SCAN_TEXT "Scan"
|
||||
#define STOP_SCAN_TEXT "Stop scan"
|
||||
|
||||
namespace tt::app::i2cscanner {
|
||||
|
||||
extern const AppManifest manifest;
|
||||
|
||||
class I2cScannerApp : public App {
|
||||
class I2cScannerApp final : public App {
|
||||
|
||||
static constexpr auto* START_SCAN_TEXT = "Scan";
|
||||
static constexpr auto* STOP_SCAN_TEXT = "Stop scan";
|
||||
|
||||
// Core
|
||||
Mutex mutex = Mutex(Mutex::Type::Recursive);
|
||||
@@ -181,13 +180,6 @@ void I2cScannerApp::onPressScanCallback(lv_event_t* event) {
|
||||
}
|
||||
}
|
||||
|
||||
void I2cScannerApp::onScanTimerCallback() {
|
||||
auto app = optApp();
|
||||
if (app != nullptr) {
|
||||
app->onScanTimer();
|
||||
}
|
||||
}
|
||||
|
||||
// endregion Callbacks
|
||||
|
||||
bool I2cScannerApp::getPort(i2c_port_t* outPort) {
|
||||
@@ -285,8 +277,8 @@ void I2cScannerApp::startScanning() {
|
||||
lv_obj_clean(scanListWidget);
|
||||
|
||||
scanState = ScanStateScanning;
|
||||
scanTimer = std::make_unique<Timer>(Timer::Type::Once, []{
|
||||
onScanTimerCallback();
|
||||
scanTimer = std::make_unique<Timer>(Timer::Type::Once, [this]{
|
||||
onScanTimer();
|
||||
});
|
||||
scanTimer->start(10);
|
||||
mutex.unlock();
|
||||
@@ -414,7 +406,7 @@ extern const AppManifest manifest = {
|
||||
.id = "I2cScanner",
|
||||
.name = "I2C Scanner",
|
||||
.icon = TT_ASSETS_APP_ICON_I2C_SETTINGS,
|
||||
.type = Type::System,
|
||||
.category = Category::System,
|
||||
.createApp = create<I2cScannerApp>
|
||||
};
|
||||
|
||||
|
||||
@@ -96,7 +96,7 @@ extern const AppManifest manifest = {
|
||||
.id = "I2cSettings",
|
||||
.name = "I2C",
|
||||
.icon = TT_ASSETS_APP_ICON_I2C_SETTINGS,
|
||||
.type = Type::Settings,
|
||||
.category = Category::Settings,
|
||||
.createApp = create<I2cSettingsApp>
|
||||
};
|
||||
|
||||
|
||||
@@ -62,7 +62,8 @@ class ImageViewerApp : public App {
|
||||
extern const AppManifest manifest = {
|
||||
.id = "ImageViewer",
|
||||
.name = "Image Viewer",
|
||||
.type = Type::Hidden,
|
||||
.category = Category::System,
|
||||
.flags = AppManifest::Flags::Hidden,
|
||||
.createApp = create<ImageViewerApp>
|
||||
};
|
||||
|
||||
|
||||
@@ -120,7 +120,8 @@ public:
|
||||
extern const AppManifest manifest = {
|
||||
.id = "InputDialog",
|
||||
.name = "Input Dialog",
|
||||
.type = Type::Hidden,
|
||||
.category = Category::System,
|
||||
.flags = AppManifest::Flags::Hidden,
|
||||
.createApp = create<InputDialogApp>
|
||||
};
|
||||
|
||||
|
||||
@@ -138,7 +138,7 @@ public:
|
||||
extern const AppManifest manifest = {
|
||||
.id = "Launcher",
|
||||
.name = "Launcher",
|
||||
.type = Type::Launcher,
|
||||
.category = Category::System,
|
||||
.createApp = create<LauncherApp>
|
||||
};
|
||||
|
||||
|
||||
@@ -165,7 +165,7 @@ extern const AppManifest manifest = {
|
||||
.id = "LocaleSettings",
|
||||
.name = "Region & Language",
|
||||
.icon = TT_ASSETS_APP_ICON_TIME_DATE_SETTINGS,
|
||||
.type = Type::Settings,
|
||||
.category = Category::Settings,
|
||||
.createApp = create<LocaleSettingsApp>
|
||||
};
|
||||
|
||||
|
||||
@@ -123,7 +123,7 @@ extern const AppManifest manifest = {
|
||||
.id = "Log",
|
||||
.name = "Log",
|
||||
.icon = LV_SYMBOL_LIST,
|
||||
.type = Type::System,
|
||||
.category = Category::System,
|
||||
.createApp = create<LogApp>
|
||||
};
|
||||
|
||||
|
||||
@@ -192,7 +192,7 @@ extern const AppManifest manifest = {
|
||||
.id = "Power",
|
||||
.name = "Power",
|
||||
.icon = TT_ASSETS_APP_ICON_POWER_SETTINGS,
|
||||
.type = Type::Settings,
|
||||
.category = Category::Settings,
|
||||
.createApp = create<PowerApp>
|
||||
};
|
||||
|
||||
|
||||
@@ -281,7 +281,7 @@ extern const AppManifest manifest = {
|
||||
.id = "Screenshot",
|
||||
.name = "Screenshot",
|
||||
.icon = LV_SYMBOL_IMAGE,
|
||||
.type = Type::System,
|
||||
.category = Category::System,
|
||||
.createApp = create<ScreenshotApp>
|
||||
};
|
||||
|
||||
|
||||
@@ -114,7 +114,8 @@ public:
|
||||
extern const AppManifest manifest = {
|
||||
.id = "SelectionDialog",
|
||||
.name = "Selection Dialog",
|
||||
.type = Type::Hidden,
|
||||
.category = Category::System,
|
||||
.flags = AppManifest::Flags::Hidden,
|
||||
.createApp = create<SelectionDialogApp>
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "Tactility/app/serialconsole/ConnectView.h"
|
||||
#include "../../../Private/Tactility/app/serialconsole/ConnectView.h"
|
||||
#include "Tactility/app/serialconsole/ConsoleView.h"
|
||||
|
||||
#include "Tactility/lvgl/Style.h"
|
||||
@@ -88,7 +88,7 @@ extern const AppManifest manifest = {
|
||||
.id = "SerialConsole",
|
||||
.name = "Serial Console",
|
||||
.icon = LV_SYMBOL_LIST,
|
||||
.type = Type::System,
|
||||
.category = Category::System,
|
||||
.createApp = create<SerialConsoleApp>
|
||||
};
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ class SettingsApp : public App {
|
||||
auto manifests = getApps();
|
||||
std::sort(manifests.begin(), manifests.end(), SortAppManifestByName);
|
||||
for (const auto& manifest: manifests) {
|
||||
if (manifest->type == Type::Settings) {
|
||||
if (manifest->category == Category::Settings) {
|
||||
createWidget(manifest, list);
|
||||
}
|
||||
}
|
||||
@@ -49,7 +49,8 @@ extern const AppManifest manifest = {
|
||||
.id = "Settings",
|
||||
.name = "Settings",
|
||||
.icon = TT_ASSETS_APP_ICON_SETTINGS,
|
||||
.type = Type::Hidden,
|
||||
.category = Category::System,
|
||||
.flags = AppManifest::Flags::Hidden,
|
||||
.createApp = create<SettingsApp>
|
||||
};
|
||||
|
||||
|
||||
@@ -295,7 +295,7 @@ extern const AppManifest manifest = {
|
||||
.id = "SystemInfo",
|
||||
.name = "System Info",
|
||||
.icon = TT_ASSETS_APP_ICON_SYSTEM_INFO,
|
||||
.type = Type::System,
|
||||
.category = Category::System,
|
||||
.createApp = create<SystemInfoApp>
|
||||
};
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ extern const AppManifest manifest = {
|
||||
.id = "TimeDateSettings",
|
||||
.name = "Time & Date",
|
||||
.icon = TT_ASSETS_APP_ICON_TIME_DATE_SETTINGS,
|
||||
.type = Type::Settings,
|
||||
.category = Category::Settings,
|
||||
.createApp = create<TimeDateSettingsApp>
|
||||
};
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#include "Tactility/app/AppContext.h"
|
||||
#include "Tactility/app/AppManifest.h"
|
||||
#include "Tactility/app/timezone/TimeZone.h"
|
||||
#include "Tactility/lvgl/Toolbar.h"
|
||||
#include "Tactility/lvgl/LvglSync.h"
|
||||
#include "Tactility/service/loader/Loader.h"
|
||||
#include <Tactility/app/AppContext.h>
|
||||
#include <Tactility/app/AppManifest.h>
|
||||
#include <Tactility/app/timezone/TimeZone.h>
|
||||
#include <Tactility/lvgl/Toolbar.h>
|
||||
#include <Tactility/lvgl/LvglSync.h>
|
||||
#include <Tactility/service/loader/Loader.h>
|
||||
|
||||
#include <Tactility/MountPoints.h>
|
||||
#include <Tactility/StringUtils.h>
|
||||
@@ -15,9 +15,8 @@
|
||||
namespace tt::app::timezone {
|
||||
|
||||
constexpr auto* TAG = "TimeZone";
|
||||
|
||||
#define RESULT_BUNDLE_CODE_INDEX "code"
|
||||
#define RESULT_BUNDLE_NAME_INDEX "name"
|
||||
constexpr auto* RESULT_BUNDLE_CODE_INDEX = "code";
|
||||
constexpr auto* RESULT_BUNDLE_NAME_INDEX = "name";
|
||||
|
||||
extern const AppManifest manifest;
|
||||
|
||||
@@ -113,14 +112,6 @@ class TimeZoneApp final : public App {
|
||||
lv_obj_add_event_cb(btn, &onListItemSelectedCallback, LV_EVENT_SHORT_CLICKED, (void*)index);
|
||||
}
|
||||
|
||||
static void updateTimerCallback() {
|
||||
auto appContext = getCurrentAppContext();
|
||||
if (appContext != nullptr && appContext->getManifest().id == manifest.id) {
|
||||
auto app = std::static_pointer_cast<TimeZoneApp>(appContext->getApp());
|
||||
app->updateList();
|
||||
}
|
||||
}
|
||||
|
||||
void readTimeZones(std::string filter) {
|
||||
auto path = std::string(file::MOUNT_POINT_SYSTEM) + "/timezones.csv";
|
||||
auto* file = fopen(path.c_str(), "rb");
|
||||
@@ -228,14 +219,17 @@ public:
|
||||
}
|
||||
|
||||
void onCreate(AppContext& app) override {
|
||||
updateTimer = std::make_unique<Timer>(Timer::Type::Once, [] { updateTimerCallback(); });
|
||||
updateTimer = std::make_unique<Timer>(Timer::Type::Once, [this] {
|
||||
updateList();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
extern const AppManifest manifest = {
|
||||
.id = "TimeZone",
|
||||
.name = "Select timezone",
|
||||
.type = Type::Hidden,
|
||||
.category = Category::System,
|
||||
.flags = AppManifest::Flags::Hidden,
|
||||
.createApp = create<TimeZoneApp>
|
||||
};
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ extern const AppManifest manifest = {
|
||||
.id = "UsbSettings",
|
||||
.name = "USB",
|
||||
.icon = LV_SYMBOL_USB,
|
||||
.type = Type::Settings,
|
||||
.category = Category::Settings,
|
||||
.createApp = create<UsbSettingsApp>
|
||||
};
|
||||
|
||||
|
||||
@@ -1,20 +1,18 @@
|
||||
#include "Tactility/app/wifiapsettings/WifiApSettings.h"
|
||||
|
||||
#include "Tactility/app/App.h"
|
||||
#include "Tactility/app/AppContext.h"
|
||||
#include "Tactility/app/AppManifest.h"
|
||||
#include "Tactility/app/alertdialog/AlertDialog.h"
|
||||
#include "Tactility/lvgl/Style.h"
|
||||
#include "Tactility/lvgl/Toolbar.h"
|
||||
|
||||
#include <Tactility/service/wifi/WifiApSettings.h>
|
||||
#include <Tactility/service/wifi/Wifi.h>
|
||||
#include <Tactility/app/App.h>
|
||||
#include <Tactility/app/AppContext.h>
|
||||
#include <Tactility/app/AppManifest.h>
|
||||
#include <Tactility/app/alertdialog/AlertDialog.h>
|
||||
#include <Tactility/lvgl/Style.h>
|
||||
#include <Tactility/lvgl/Toolbar.h>
|
||||
#include <Tactility/TactilityCore.h>
|
||||
#include <Tactility/service/wifi/WifiSettings.h>
|
||||
|
||||
#include <lvgl.h>
|
||||
|
||||
namespace tt::app::wifiapsettings {
|
||||
|
||||
#define TAG "wifi_ap_settings"
|
||||
constexpr auto* TAG = "WifiApSettings";
|
||||
|
||||
extern const AppManifest manifest;
|
||||
|
||||
@@ -146,7 +144,8 @@ extern const AppManifest manifest = {
|
||||
.id = "WifiApSettings",
|
||||
.name = "Wi-Fi AP Settings",
|
||||
.icon = LV_SYMBOL_WIFI,
|
||||
.type = Type::Hidden,
|
||||
.category = Category::System,
|
||||
.flags = AppManifest::Flags::Hidden,
|
||||
.createApp = create<WifiApSettings>
|
||||
};
|
||||
|
||||
|
||||
@@ -97,7 +97,8 @@ extern const AppManifest manifest = {
|
||||
.id = "WifiConnect",
|
||||
.name = "Wi-Fi Connect",
|
||||
.icon = LV_SYMBOL_WIFI,
|
||||
.type = Type::Hidden,
|
||||
.category = Category::System,
|
||||
.flags = AppManifest::Flags::Hidden,
|
||||
.createApp = create<WifiConnect>
|
||||
};
|
||||
|
||||
|
||||
@@ -136,7 +136,7 @@ extern const AppManifest manifest = {
|
||||
.id = "WifiManage",
|
||||
.name = "Wi-Fi",
|
||||
.icon = LV_SYMBOL_WIFI,
|
||||
.type = Type::Settings,
|
||||
.category = Category::Settings,
|
||||
.createApp = create<WifiManage>
|
||||
};
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "Tactility/service/gui/GuiService.h"
|
||||
#include "Tactility/lvgl/LvglSync.h"
|
||||
#include "Tactility/lvgl/Statusbar.h"
|
||||
#include "Tactility/lvgl/Style.h"
|
||||
#include "Tactility/service/loader/Loader.h"
|
||||
|
||||
#include <Tactility/Tactility.h>
|
||||
@@ -92,10 +91,10 @@ void GuiService::redraw() {
|
||||
lv_group_set_default(group);
|
||||
|
||||
app::Flags flags = std::static_pointer_cast<app::AppInstance>(appToRender)->getFlags();
|
||||
if (flags.showStatusbar) {
|
||||
lv_obj_remove_flag(statusbarWidget, LV_OBJ_FLAG_HIDDEN);
|
||||
} else {
|
||||
if (flags.hideStatusbar) {
|
||||
lv_obj_add_flag(statusbarWidget, LV_OBJ_FLAG_HIDDEN);
|
||||
} else {
|
||||
lv_obj_remove_flag(statusbarWidget, LV_OBJ_FLAG_HIDDEN);
|
||||
}
|
||||
|
||||
lv_obj_t* container = createAppViews(appRootWidget);
|
||||
|
||||
@@ -103,7 +103,7 @@ void LoaderService::onStartAppMessage(const std::string& id, app::LaunchId launc
|
||||
auto previous_app = !appStack.empty() ? appStack.top() : nullptr;
|
||||
auto new_app = std::make_shared<app::AppInstance>(app_manifest, launchId, parameters);
|
||||
|
||||
new_app->mutableFlags().showStatusbar = (app_manifest->type != app::Type::Boot);
|
||||
new_app->mutableFlags().hideStatusbar = (app_manifest->flags & app::AppManifest::Flags::HideStatusBar);
|
||||
|
||||
appStack.push(new_app);
|
||||
transitionAppToState(new_app, app::State::Initial);
|
||||
@@ -141,7 +141,7 @@ void LoaderService::onStopAppMessage(const std::string& id) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (original_stack_size == 1 && app_to_stop->getManifest().type != app::Type::Boot) {
|
||||
if (original_stack_size == 1 && app_to_stop->getManifest().name != "Boot") {
|
||||
TT_LOG_E(TAG, "Stop app: can't stop root app");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
#include "Tactility/lvgl/Statusbar.h"
|
||||
#include "Tactility/lvgl/LvglSync.h"
|
||||
#include <Tactility/lvgl/Statusbar.h>
|
||||
#include <Tactility/lvgl/LvglSync.h>
|
||||
|
||||
#include "Tactility/hal/power/PowerDevice.h"
|
||||
#include "Tactility/hal/sdcard/SdCardDevice.h"
|
||||
#include "Tactility/service/gps/GpsService.h"
|
||||
#include <Tactility/hal/power/PowerDevice.h>
|
||||
#include <Tactility/hal/sdcard/SdCardDevice.h>
|
||||
#include <Tactility/lvgl/Lvgl.h>
|
||||
#include <Tactility/service/gps/GpsService.h>
|
||||
#include <Tactility/Mutex.h>
|
||||
#include <Tactility/Tactility.h>
|
||||
#include <Tactility/Timer.h>
|
||||
@@ -16,31 +17,31 @@ namespace tt::service::statusbar {
|
||||
constexpr auto* TAG = "StatusbarService";
|
||||
|
||||
// SD card status
|
||||
#define STATUSBAR_ICON_SDCARD "sdcard.png"
|
||||
#define STATUSBAR_ICON_SDCARD_ALERT "sdcard_alert.png"
|
||||
constexpr auto* STATUSBAR_ICON_SDCARD = "sdcard.png";
|
||||
constexpr auto* STATUSBAR_ICON_SDCARD_ALERT = "sdcard_alert.png";
|
||||
|
||||
// Wifi status
|
||||
#define STATUSBAR_ICON_WIFI_OFF_WHITE "wifi_off_white.png"
|
||||
#define STATUSBAR_ICON_WIFI_SCAN_WHITE "wifi_scan_white.png"
|
||||
#define STATUSBAR_ICON_WIFI_SIGNAL_WEAK_WHITE "wifi_signal_weak_white.png"
|
||||
#define STATUSBAR_ICON_WIFI_SIGNAL_MEDIUM_WHITE "wifi_signal_medium_white.png"
|
||||
#define STATUSBAR_ICON_WIFI_SIGNAL_STRONG_WHITE "wifi_signal_strong_white.png"
|
||||
constexpr auto* STATUSBAR_ICON_WIFI_OFF_WHITE = "wifi_off_white.png";
|
||||
constexpr auto* STATUSBAR_ICON_WIFI_SCAN_WHITE = "wifi_scan_white.png";
|
||||
constexpr auto* STATUSBAR_ICON_WIFI_SIGNAL_WEAK_WHITE = "wifi_signal_weak_white.png";
|
||||
constexpr auto* STATUSBAR_ICON_WIFI_SIGNAL_MEDIUM_WHITE = "wifi_signal_medium_white.png";
|
||||
constexpr auto* STATUSBAR_ICON_WIFI_SIGNAL_STRONG_WHITE = "wifi_signal_strong_white.png";
|
||||
|
||||
// Power status
|
||||
#define STATUSBAR_ICON_POWER_0 "power_0.png"
|
||||
#define STATUSBAR_ICON_POWER_10 "power_10.png"
|
||||
#define STATUSBAR_ICON_POWER_20 "power_20.png"
|
||||
#define STATUSBAR_ICON_POWER_30 "power_30.png"
|
||||
#define STATUSBAR_ICON_POWER_40 "power_40.png"
|
||||
#define STATUSBAR_ICON_POWER_50 "power_50.png"
|
||||
#define STATUSBAR_ICON_POWER_60 "power_60.png"
|
||||
#define STATUSBAR_ICON_POWER_70 "power_70.png"
|
||||
#define STATUSBAR_ICON_POWER_80 "power_80.png"
|
||||
#define STATUSBAR_ICON_POWER_90 "power_90.png"
|
||||
#define STATUSBAR_ICON_POWER_100 "power_100.png"
|
||||
constexpr auto* STATUSBAR_ICON_POWER_0 = "power_0.png";
|
||||
constexpr auto* STATUSBAR_ICON_POWER_10 = "power_10.png";
|
||||
constexpr auto* STATUSBAR_ICON_POWER_20 = "power_20.png";
|
||||
constexpr auto* STATUSBAR_ICON_POWER_30 = "power_30.png";
|
||||
constexpr auto* STATUSBAR_ICON_POWER_40 = "power_40.png";
|
||||
constexpr auto* STATUSBAR_ICON_POWER_50 = "power_50.png";
|
||||
constexpr auto* STATUSBAR_ICON_POWER_60 = "power_60.png";
|
||||
constexpr auto* STATUSBAR_ICON_POWER_70 = "power_70.png";
|
||||
constexpr auto* STATUSBAR_ICON_POWER_80 = "power_80.png";
|
||||
constexpr auto* STATUSBAR_ICON_POWER_90 = "power_90.png";
|
||||
constexpr auto* STATUSBAR_ICON_POWER_100 = "power_100.png";
|
||||
|
||||
// GPS
|
||||
#define STATUSBAR_ICON_GPS "location.png"
|
||||
constexpr auto* STATUSBAR_ICON_GPS = "location.png";
|
||||
|
||||
extern const ServiceManifest manifest;
|
||||
|
||||
@@ -222,15 +223,15 @@ class StatusbarService final : public Service {
|
||||
}
|
||||
|
||||
void update() {
|
||||
// TODO: Make thread-safe for LVGL
|
||||
updateGpsIcon();
|
||||
updateWifiIcon();
|
||||
updateSdCardIcon();
|
||||
updatePowerStatusIcon();
|
||||
}
|
||||
|
||||
static void onUpdate(const std::shared_ptr<StatusbarService>& service) {
|
||||
service->update();
|
||||
if (lvgl::isStarted()) {
|
||||
if (lvgl::lock(100)) {
|
||||
updateGpsIcon();
|
||||
updateWifiIcon();
|
||||
updateSdCardIcon();
|
||||
updatePowerStatusIcon();
|
||||
lvgl::unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
@@ -262,10 +263,10 @@ public:
|
||||
|
||||
auto service = findServiceById<StatusbarService>(manifest.id);
|
||||
assert(service);
|
||||
onUpdate(service);
|
||||
service->update();
|
||||
|
||||
updateTimer = std::make_unique<Timer>(Timer::Type::Periodic, [service] {
|
||||
onUpdate(service);
|
||||
service->update();
|
||||
});
|
||||
|
||||
// We want to try and scan more often in case of startup or scan lock failure
|
||||
|
||||
Reference in New Issue
Block a user