diff --git a/.gitignore b/.gitignore index e0a5c685..147de379 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ .vscode CMakeFiles CMakeCache.txt -extern/SDL2-2.28.5 \ No newline at end of file +extern/SDL2-2.28.5 +storage/apps/notes/data/notes.dat diff --git a/lib/graphics/src/Surface.cpp b/lib/graphics/src/Surface.cpp index 4c15b761..dfd6f78c 100644 --- a/lib/graphics/src/Surface.cpp +++ b/lib/graphics/src/Surface.cpp @@ -241,7 +241,7 @@ namespace graphics void Surface::fillRoundRectWithBorder(int16_t x, int16_t y, int16_t w, int16_t h, int16_t r, int16_t bs, uint16_t Backcolor, uint16_t Bordercolor) { m_sprite.fillSmoothRoundRect(x, y, w, h, r, Bordercolor); - m_sprite.fillSmoothRoundRect(x + bs, y + bs, w - 2 * bs, h - 2 * bs, r - bs, Backcolor); + m_sprite.fillSmoothRoundRect(x + bs, y + bs, w - 2 * bs, h - 2 * bs, r, Backcolor); } void Surface::drawRoundRect(const int16_t x, const int16_t y, const uint16_t w, const uint16_t h, const uint16_t r, const color_t color) diff --git a/lib/graphics/src/Surface.hpp b/lib/graphics/src/Surface.hpp index 878e641e..b726c65f 100644 --- a/lib/graphics/src/Surface.hpp +++ b/lib/graphics/src/Surface.hpp @@ -102,4 +102,4 @@ namespace graphics }; } // graphics -#endif // SURFACE_HPP +#endif // SURFACE_HPP \ No newline at end of file diff --git a/lib/graphics/src/color.hpp b/lib/graphics/src/color.hpp index 0c27b2ac..56f6bc69 100644 --- a/lib/graphics/src/color.hpp +++ b/lib/graphics/src/color.hpp @@ -21,11 +21,6 @@ namespace graphics #define COLOR_WARNING 0xFE00 #define COLOR_ERROR 0xD9A8 - -// #define COLOR_WHITE 0xFFFF -// #define COLOR_BLACK 0x0000 -// #define COLOR_GREY 0x8410 - #define COLOR_WHITE graphics::packRGB565(255, 255, 255) #define COLOR_BLACK graphics::packRGB565(0, 0, 0) #define COLOR_RED graphics::packRGB565(255, 0, 0) diff --git a/lib/gui/src/ElementBase.cpp b/lib/gui/src/ElementBase.cpp index 0a5910a0..8823bfc5 100644 --- a/lib/gui/src/ElementBase.cpp +++ b/lib/gui/src/ElementBase.cpp @@ -40,10 +40,13 @@ gui::ElementBase::ElementBase() : m_x(0), m_y(0), gui::ElementBase::~ElementBase() { + + // force le rafraichisseent sur un delete d'un enfant if (m_parent != nullptr) m_parent->localGraphicalUpdate(); - // Libération de la mémoire allouée pour les enfants de l'objet + + // Libération de la mémoire allouée pour les enfants de l'objet for (int i = 0; i < m_children.size(); i++) { if (m_children[i] != nullptr) diff --git a/lib/gui/src/elements/Image.cpp b/lib/gui/src/elements/Image.cpp index 4a0a0db7..1c9f4dac 100644 --- a/lib/gui/src/elements/Image.cpp +++ b/lib/gui/src/elements/Image.cpp @@ -5,7 +5,6 @@ #include #include -#include namespace gui::ImagesList { @@ -20,32 +19,32 @@ namespace gui::ImagesList std::vector images; - std::shared_ptr loadImage(storage::Path path, uint16_t width, uint16_t height, const color_t backgroundColor = 0xFFFF) { - // ReSharper disable once CppUseStructuredBinding - for (const auto& image : images) { - if (image.path.str() == path.str() && image.width == width && image.height == height) { - return image.surface; - } - } + std::shared_ptr loadImage(storage::Path path, uint16_t width, uint16_t height, const color_t backgroundColor = 0xFFFF) { + // ReSharper disable once CppUseStructuredBinding + for (const auto& image : images) { + if (image.path.str() == path.str() && image.width == width && image.height == height) { + return image.surface; + } + } - const auto i = graphics::SImage(path); + const auto i = graphics::SImage(path); - // libsystem::log("Image: " + std::to_string(i.getType()) + ", " + std::to_string(i.getWidth()) + ", " + std::to_string(i.getHeight()) + ", " + i.getPath().str()); + // libsystem::log("Image: " + std::to_string(i.getType()) + ", " + std::to_string(i.getWidth()) + ", " + std::to_string(i.getHeight()) + ", " + i.getPath().str()); - ImageLoaded img = { - path, - width, // i.getWidth(), - height, // i.getHeight(), - std::make_shared(width, height) - }; + ImageLoaded img = { + path, + i.getWidth(), + i.getHeight(), + std::make_shared(width, height) + }; - // Clear the background if it's a transparent image ? - // I guess so ? - if(i.getType() != graphics::ImageType::BMP) { - img.surface->clear(backgroundColor); - } + // Clear the background if it's a transparent image ? + // I guess so ? + if(i.getType() != graphics::ImageType::BMP) { + img.surface->clear(backgroundColor); + } - img.surface->drawImage(i, 0, 0, width, height); + img.surface->drawImage(i, 0, 0, width, height); images.push_back(img); @@ -59,7 +58,7 @@ namespace gui::ImagesList if (img->surface.use_count() == 1) { img = images.erase(img); - //std::cout << "[Image] image deleted" << std::endl; + std::cout << "[Image] image deleted" << std::endl; } else { @@ -93,13 +92,7 @@ namespace gui::elements load(m_backgroundColor); } - void Image::load(color_t background) - { - m_surface = gui::ImagesList::loadImage(this->m_path, this->m_width, this->m_height, background); - localGraphicalUpdate(); - } - - void Image::setTransparentColor(color_t color){ + void Image::setTransparentColor(color_t color){ if ( ! m_surface) { //std::cout << "[Image] m_surface is null"; load(color); @@ -107,4 +100,11 @@ namespace gui::elements m_surface->setTransparentColor(color); m_surface->setTransparency(true); } + + + void Image::load(color_t background) + { + m_surface = gui::ImagesList::loadImage(this->m_path, this->m_width, this->m_height, background); + localGraphicalUpdate(); + } } \ No newline at end of file diff --git a/lib/gui/src/elements/Label.cpp b/lib/gui/src/elements/Label.cpp index 088ad36a..1b3c45f3 100644 --- a/lib/gui/src/elements/Label.cpp +++ b/lib/gui/src/elements/Label.cpp @@ -9,14 +9,15 @@ #include #include -namespace gui::elements { +namespace gui::elements +{ Label::Label(const uint16_t x, const uint16_t y, const uint16_t width, const uint16_t height) : ElementBase(), - m_text(""), - m_fontSize(18), - m_textColor(COLOR_DARK), - m_textVerticalAlignment(UP), - m_textHorizontalAlignment(LEFT) + m_text(""), + m_fontSize(18), + m_textColor(COLOR_DARK), + m_textVerticalAlignment(UP), + m_textHorizontalAlignment(LEFT) { m_x = x; m_y = y; @@ -25,6 +26,7 @@ namespace gui::elements { m_hasCursor = false; m_cursorIndex = 0; + m_strikeOut = false; } Label::~Label() = default; @@ -34,7 +36,7 @@ namespace gui::elements { m_surface->clear(COLOR_WHITE); m_surface->fillRoundRectWithBorder(0, 0, m_width, m_height, m_borderRadius, m_borderSize, m_backgroundColor, m_borderColor); - m_surface->setTextColor((this->m_textColor == 0)?(1):(this->m_textColor)); + m_surface->setTextColor((this->m_textColor == 0) ? (1) : (this->m_textColor)); m_surface->setColor(this->m_backgroundColor); m_surface->setFontSize(this->m_fontSize); @@ -45,40 +47,40 @@ namespace gui::elements { int x; switch (int(m_textHorizontalAlignment)) { - case Alignement::LEFT: - x = getRadius()/2 + getBorderSize(); + case Alignement::LEFT: + x = getRadius() / 2 + getBorderSize(); break; - case Alignement::CENTER: - x = getRadius()/2 + getBorderSize() + getUsableWidth()/2 - m_surface->getTextWidth(lines[i])/2; + case Alignement::CENTER: + x = getRadius() / 2 + getBorderSize() + getUsableWidth() / 2 - m_surface->getTextWidth(lines[i]) / 2; break; - case Alignement::RIGHT: - x = getRadius()/2 + getBorderSize() + getUsableWidth() - m_surface->getTextWidth(lines[i]); + case Alignement::RIGHT: + x = getRadius() / 2 + getBorderSize() + getUsableWidth() - m_surface->getTextWidth(lines[i]); break; }; int y; switch (int(m_textVerticalAlignment)) { - case Alignement::UP: - y = getRadius()/2 + getBorderSize() + (m_surface->getTextHeight() + LINE_SPACING) * i; + case Alignement::UP: + y = getRadius() / 2 + getBorderSize() + (m_surface->getTextHeight() + LINE_SPACING) * i; break; - case Alignement::CENTER: - y = getRadius()/2 + getBorderSize() + getUsableHeight()/2 - - ((m_surface->getTextHeight() + LINE_SPACING) * lines.size()) / 2 - + (m_surface->getTextHeight() + LINE_SPACING) * i; + case Alignement::CENTER: + y = getRadius() / 2 + getBorderSize() + getUsableHeight() / 2 - ((m_surface->getTextHeight() + LINE_SPACING) * lines.size()) / 2 + (m_surface->getTextHeight() + LINE_SPACING) * i; break; - case Alignement::DOWN: - y = getRadius()/2 + getBorderSize() + getUsableHeight() - - ((m_surface->getTextHeight() + LINE_SPACING) * lines.size()) - + (m_surface->getTextHeight() + LINE_SPACING) * i; + case Alignement::DOWN: + y = getRadius() / 2 + getBorderSize() + getUsableHeight() - ((m_surface->getTextHeight() + LINE_SPACING) * lines.size()) + (m_surface->getTextHeight() + LINE_SPACING) * i; break; }; m_surface->drawText(lines[i], x, y); + if (m_strikeOut) + { + m_surface->drawLine(x, y + m_surface->getTextHeight() / 2, x + m_surface->getTextWidth(lines[i]), y + m_surface->getTextHeight() / 2, m_textColor); + } } } - void Label::setText(const std::string& text) + void Label::setText(const std::string &text) { this->m_text = text; localGraphicalUpdate(); @@ -106,9 +108,10 @@ namespace gui::elements { uint16_t charIndex = 0; // Global text index uint16_t lineCharIndex = 0; // X position - uint16_t lineIndex = 0; // Y position + uint16_t lineIndex = 0; // Y position - for (char c : m_text) { + for (char c : m_text) + { // Save cursor pos if (m_hasCursor) { @@ -124,41 +127,56 @@ namespace gui::elements { } } - if (c == '\n') { + if (c == '\n') + { output.m_lines.push_back(currentLine); currentLine = ""; lineIndex++; lineCharIndex = 0; - } else if (m_surface->getTextWidth(currentLine + c) <= getUsableWidth()) { + } + else if (m_surface->getTextWidth(currentLine + c) <= getUsableWidth()) + { currentLine += c; lineCharIndex++; - } else if (c == ' ') { + } + else if (c == ' ') + { output.m_lines.push_back(currentLine); currentLine = ""; lineIndex++; lineCharIndex = 0; - } else { - if (currentLine.empty()) { + } + else + { + if (currentLine.empty()) + { currentLine += c; lineCharIndex++; - } else if (currentLine.back() == ' ') { + } + else if (currentLine.back() == ' ') + { currentLine += c; lineCharIndex++; - } else { + } + else + { std::size_t lastSpace = currentLine.find_last_of(' '); - if (lastSpace == std::string::npos) { + if (lastSpace == std::string::npos) + { output.m_lines.push_back(currentLine); currentLine = ""; currentLine += c; lineIndex++; lineCharIndex = 1; - } else { + } + else + { std::string firstPart = currentLine.substr(0, lastSpace); output.m_lines.push_back(firstPart); currentLine = currentLine.substr(lastSpace + 1); @@ -182,7 +200,8 @@ namespace gui::elements { } } - if (!currentLine.empty()) { + if (!currentLine.empty()) + { output.m_lines.push_back(currentLine); } @@ -191,12 +210,12 @@ namespace gui::elements { uint16_t Label::getUsableWidth(void) { - return getWidth()-getRadius()-2*getBorderSize(); + return getWidth() - getRadius() - 2 * getBorderSize(); } uint16_t Label::getUsableHeight(void) { - return getHeight()-getRadius()-2*getBorderSize(); + return getHeight() - getRadius() - 2 * getBorderSize(); } void Label::setHorizontalAlignment(Alignement alignment) @@ -217,7 +236,7 @@ namespace gui::elements { uint16_t Label::getTextWidth() { - if(m_surface == nullptr) + if (m_surface == nullptr) m_surface = std::make_shared(m_width, m_height); m_surface->setFontSize(this->m_fontSize); return m_surface->getTextWidth(m_text); @@ -226,7 +245,7 @@ namespace gui::elements { uint16_t Label::getTextHeight() { bool allocatedSprite = false; - if(m_surface == nullptr) + if (m_surface == nullptr) { m_surface = std::make_shared(1, 1); allocatedSprite = true; @@ -235,9 +254,9 @@ namespace gui::elements { m_surface->setFontSize(this->m_fontSize); const auto [lines, cursorIndex, cursorLine] = parse(); - uint16_t out = getRadius() + getBorderSize()*2 + (m_surface->getTextHeight() + LINE_SPACING) * lines.size(); + uint16_t out = getRadius() + getBorderSize() * 2 + (m_surface->getTextHeight() + LINE_SPACING) * lines.size(); - if(allocatedSprite) + if (allocatedSprite) m_surface = nullptr; return out; @@ -262,11 +281,18 @@ namespace gui::elements { { m_cursorIndex = cursorIndex; - if (m_cursorIndex < 0) { + if (m_cursorIndex < 0) + { m_cursorIndex = 0; } - if (m_cursorIndex > m_text.length()) { + if (m_cursorIndex > m_text.length()) + { m_cursorIndex = static_cast(m_text.length()); } } + + void Label::setStrikeOut(bool strikeOut) + { + m_strikeOut = strikeOut; + } } // gui::elements \ No newline at end of file diff --git a/lib/gui/src/elements/Label.hpp b/lib/gui/src/elements/Label.hpp index 845d287c..0dc584ca 100644 --- a/lib/gui/src/elements/Label.hpp +++ b/lib/gui/src/elements/Label.hpp @@ -13,27 +13,29 @@ namespace gui::elements { /** * @brief Widget label displays text - **/ + **/ class Label final : public ElementBase { public: Label(uint16_t x, uint16_t y, uint16_t width, uint16_t height); ~Label() override; - enum Alignement { + enum Alignement + { CENTER, LEFT, RIGHT, UP, DOWN }; - + void render() override; - void setText(const std::string& text); + void setText(const std::string &text); std::string getText() const; void setTextColor(color_t color); void setFontSize(uint16_t fontSize); + void setStrikeOut(bool strikeOut); void setHorizontalAlignment(Alignement alignment); void setVerticalAlignment(Alignement alignment); @@ -48,11 +50,12 @@ namespace gui::elements void setCursorIndex(int16_t cursorIndex); private: - struct ParseDataOutput { + struct ParseDataOutput + { std::vector m_lines; uint16_t m_cursorIndex; // X - uint16_t m_cursorLine; // Y + uint16_t m_cursorLine; // Y }; ParseDataOutput parse(void); @@ -67,7 +70,8 @@ namespace gui::elements bool m_hasCursor; int16_t m_cursorIndex; + bool m_strikeOut; }; } // gui::elements -#endif //LABEL_HPP +#endif // LABEL_HPP diff --git a/lib/lua/src/lua_canvas.hpp b/lib/lua/src/lua_canvas.hpp index 0813b578..5c59cd12 100644 --- a/lib/lua/src/lua_canvas.hpp +++ b/lib/lua/src/lua_canvas.hpp @@ -40,7 +40,7 @@ class LuaCanvas : public LuaWidget void drawLine(int16_t x1, int16_t y1, int16_t x2, int16_t y2, color_t color) { widget->drawLine(x1, y1, x2, y2, color); } - void drawText(int16_t x, int16_t y, std::string text, color_t color) { widget->drawText(x, y, text, color); } + void drawText(int16_t x, int16_t y, std::string text, color_t color, float fontSize) { widget->drawText(x, y, text, color, fontSize); } // w and h are the width and height of the text bounding box void drawTextCentered(int16_t x, int16_t y, std::string text, color_t color, bool horizontallyCentered, bool verticallyCentered) { widget->drawTextCentered(x, y, text, color, horizontallyCentered, verticallyCentered); } diff --git a/lib/lua/src/lua_file.cpp b/lib/lua/src/lua_file.cpp index f47b112e..a88b411a 100755 --- a/lib/lua/src/lua_file.cpp +++ b/lib/lua/src/lua_file.cpp @@ -14,7 +14,6 @@ #include #include - /* LuaHttpClient::LuaHttpClient(LuaFile* lua) : httpClient() @@ -50,10 +49,10 @@ std::shared_ptr LuaNetwork::createHttpClient() }*/ LuaFile::LuaFile(storage::Path filename, storage::Path manifest) - :lua_gui(this), - lua_storage(this), - lua_time(this)/*, - lua_network(this)*/ + : lua_gui(this), + lua_storage(this), + lua_time(this) /*, + lua_network(this)*/ { this->filename = filename; this->manifest = manifest; @@ -72,30 +71,38 @@ LuaFile::~LuaFile() // libérer les ressources (events, etc) } -void* custom_allocator(void *ud, void *ptr, size_t osize, size_t nsize) { - //std::cout << "custom_allocator: " << nsize << std::endl; - if (nsize == 0) { +void *custom_allocator(void *ud, void *ptr, size_t osize, size_t nsize) +{ + // std::cout << "custom_allocator: " << nsize << std::endl; + if (nsize == 0) + { // Free the block - if (ptr != NULL) { + if (ptr != NULL) + { free(ptr); } return NULL; - } else { - // Allocate or resize the block - #ifdef ESP32 - return ps_realloc(ptr, nsize); - #else - return realloc(ptr, nsize); - #endif + } + else + { +// Allocate or resize the block +#ifdef ESP32 + return ps_realloc(ptr, nsize); +#else + return realloc(ptr, nsize); +#endif } } -int sol_exception_handler(lua_State* L, sol::optional maybe_exception, sol::string_view description) { +int sol_exception_handler(lua_State *L, sol::optional maybe_exception, sol::string_view description) +{ std::cerr << "An error occurred in Lua: "; - if (maybe_exception) { + if (maybe_exception) + { std::cerr << maybe_exception->what() << std::endl; } - else { + else + { std::cerr << description << std::endl; } lua_error(L); @@ -103,83 +110,112 @@ int sol_exception_handler(lua_State* L, sol::optional may return 0; } -int custom_panic_handler(lua_State* L) { +int custom_panic_handler(lua_State *L) +{ std::shared_ptr app = AppManager::get(L); app->errors += std::string(lua_tostring(L, -1)) + "\n"; app->app_state = AppManager::App::AppState::NOT_RUNNING; - const char* msg = lua_tostring(L, -1); + const char *msg = lua_tostring(L, -1); std::cerr << "Lua panic: " << msg << std::endl; - + return 0; } -std::string tableToString(const sol::table& table) { +std::string tableToString(const sol::table &table) +{ std::stringstream ss; ss << "{"; - + int size = 0; - for (const auto& pair : table) { size++;} - - int i=0; - for (const auto& pair : table) { - if (pair.first.is()) { - ss << "[\"" << pair.first.as() << "\"]"; - } else if(pair.first.is()) { - ss << "[" <()<< "]"; + for (const auto &pair : table) + { + size++; + } + + int i = 0; + for (const auto &pair : table) + { + if (pair.first.is()) + { + ss << "[\"" << pair.first.as() << "\"]"; + } + else if (pair.first.is()) + { + ss << "[" << pair.first.as() << "]"; } - else { // Assuming it's an identifier - ss << "[\"" << pair.first.as() << "\"]"; + else + { // Assuming it's an identifier + ss << "[\"" << pair.first.as() << "\"]"; } i++; ss << "="; // Handle different value types carefully - if (pair.second.is()) { + if (pair.second.is()) + { ss << "\"" << pair.second.as() << "\""; - } else if (pair.second.is()) { + } + else if (pair.second.is()) + { ss << pair.second.as(); - } else if (pair.second.is()) { - ss << tableToString(pair.second); + } + else if (pair.second.is()) + { + if (pair.second.as()) + ss << "true"; + else + ss << "false"; + } + else if (pair.second.is()) + { + ss << tableToString(pair.second); // You might want to recursively list nested tables here - } else { - //ss << "(Unknown type)"; } - - //std::cout << std::endl; - -// if (size != i) - ss << ", "; + else + { + // ss << "(Unknown type)"; + } + // std::cout << std::endl; + // if (size != i) + ss << ", "; } ss << "}"; - //std::cout << ss.str() << std::endl; + // std::cout << ss.str() << std::endl; return ss.str(); } - // Function to save a Lua table to a file -void save_lua_table(sol::state& lua, const std::string& path, sol::table table) { +void save_lua_table(sol::state &lua, const std::string &path, sol::table table) +{ std::ofstream file(path); - if (!file.is_open()) { + if (!file.is_open()) + { std::cerr << "Error: Could not open file for writing: " << path << std::endl; return; } - std::cout << tableToString(table) << std::endl; - try{ + // std::cout << tableToString(table) << std::endl; + try + { file << tableToString(table); } - catch (const sol::error& e) { + catch (const sol::error &e) + { // Handle Solidity specific errors std::cerr << "Sol error: " << e.what() << std::endl; - } catch (const std::exception& e) { + } + catch (const std::exception &e) + { // Handle other standard exceptions std::cerr << "Standard error: " << e.what() << std::endl; - } catch (...) { + } + catch (...) + { // Handle any other unknown exceptions std::cerr << "Unknown error" << std::endl; } @@ -187,9 +223,11 @@ void save_lua_table(sol::state& lua, const std::string& path, sol::table table) } // Function to load a Lua table from a file -sol::table load_lua_table(sol::state& lua, const std::string& path) { +sol::table load_lua_table(sol::state &lua, const std::string &path) +{ std::ifstream file(path); - if (!file.is_open()) { + if (!file.is_open()) + { std::cerr << "Error: Could not open file for reading: " << path << std::endl; return sol::table{}; } @@ -198,19 +236,25 @@ sol::table load_lua_table(sol::state& lua, const std::string& path) { content << file.rdbuf(); sol::table resultTable; - try { + try + { lua.script("returntable=" + content.str()); - std::string tableName = "returntable"; // Adjust if your table has a different name - // Retrieve the created table from the Lua state - resultTable= lua[tableName]; + std::string tableName = "returntable"; // Adjust if your table has a different name + // Retrieve the created table from the Lua state + resultTable = lua[tableName]; } - catch (const sol::error& e) { + catch (const sol::error &e) + { // Handle Solidity specific errors std::cerr << "Sol error on table serialisation" << e.what() << std::endl; - } catch (const std::exception& e) { + } + catch (const std::exception &e) + { // Handle other standard exceptions std::cerr << "Error: " << e.what() << std::endl; - } catch (...) { + } + catch (...) + { // Handle any other unknown exceptions std::cerr << "Unknown error" << std::endl; } @@ -220,7 +264,6 @@ sol::table load_lua_table(sol::state& lua, const std::string& path) { return resultTable; } - void LuaFile::load() { StandbyMode::triggerPower(); @@ -238,7 +281,7 @@ void LuaFile::load() std::string conf = file2.read(); file2.close(); - if(!nlohmann::json::accept(conf)) + if (!nlohmann::json::accept(conf)) { std::cerr << "Les permissions de l'app ne sont pas définies ou sont invalides" << std::endl; std::cerr << "Conf: " << conf << " in " << manifest.str() << std::endl; @@ -261,245 +304,227 @@ void LuaFile::load() // en fonction des permissions, charger certains modules - lua.set_function("nonothing", []() { - }); + lua.set_function("nonothing", []() {}); - lua["require"] = [&](const std::string& filename) -> sol::object { + lua["require"] = [&](const std::string &filename) -> sol::object + { storage::Path lib(filename); // Load the file sol::load_result chunk = lua.load_file(this->lua_storage.convertPath(lib).str()); - if (!chunk.valid()) { + if (!chunk.valid()) + { sol::error err = chunk; throw std::runtime_error("Error loading module '" + filename + "': " + err.what()); } // 4. Execute the loaded chunk and return its results - return chunk(); + return chunk(); }; - lua["saveTable"] = [&](const std::string& filename, const sol::table& table) + lua["saveTable"] = [&](const std::string &filename, const sol::table &table) { save_lua_table(lua, lua_storage.convertPath(filename).str(), table); }; - lua["loadTable"] = [&](const std::string& filename) + lua["loadTable"] = [&](const std::string &filename) { return load_lua_table(lua, lua_storage.convertPath(filename).str()); }; - if (perms.acces_hardware) // si hardware est autorisé + if (perms.acces_hardware) // si hardware est autorisé { lua.new_usertype("hardware", - "flash", &LuaHardware::flash - ); + "flash", &LuaHardware::flash); lua["hardware"] = &lua_hardware; } - if (perms.acces_files) // si storage est autorisé + if (perms.acces_files) // si storage est autorisé { lua.new_usertype("File", - "open", &LuaStorageFile::open, - "close", &LuaStorageFile::close, - "write", &LuaStorageFile::write, - "readChar", &LuaStorageFile::readChar, - "readLine", &LuaStorageFile::readLine, - "readAll", &LuaStorageFile::readAll - ); + "open", &LuaStorageFile::open, + "close", &LuaStorageFile::close, + "write", &LuaStorageFile::write, + "readChar", &LuaStorageFile::readChar, + "readLine", &LuaStorageFile::readLine, + "readAll", &LuaStorageFile::readAll); lua.new_usertype("storage", - "file", &LuaStorage::file, // return a (new LuaStorageFile) - "mkdir", &LuaStorage::newDir, - "mvFile", &LuaStorage::renameFile, - "mvDir", &LuaStorage::renameDir, - "rmFile", &LuaStorage::deleteFile, - "rmDir", &LuaStorage::deleteDir, - "isDir", &LuaStorage::isDir, - "isFile", &LuaStorage::isFile, - "listDir", &LuaStorage::listDir - ); + "file", &LuaStorage::file, // return a (new LuaStorageFile) + "mkdir", &LuaStorage::newDir, + "mvFile", &LuaStorage::renameFile, + "mvDir", &LuaStorage::renameDir, + "rmFile", &LuaStorage::deleteFile, + "rmDir", &LuaStorage::deleteDir, + "isDir", &LuaStorage::isDir, + "isFile", &LuaStorage::isFile, + "listDir", &LuaStorage::listDir); lua.set("READ", 0); lua.set("APPEND", 2); lua.set("WRITE", 1); - + auto json_ud = lua.new_usertype("Json", - "new", sol::constructors(), - "get", &LuaJson::get, - "is_null", &LuaJson::is_null, - "size", &LuaJson::size, - "has_key", &LuaJson::has_key, - "remove", &LuaJson::remove, - "get_int", &LuaJson::get_int, - "get_double", &LuaJson::get_double, - "get_bool", &LuaJson::get_bool, - "get_string", &LuaJson::get_string, - "set_int", &LuaJson::set_int, - "set_double", &LuaJson::set_double, - "set_bool", &LuaJson::set_bool, - "__index", sol::overload( - static_cast( &LuaJson::op ), - static_cast( &LuaJson::get_int ), - static_cast( &LuaJson::get_double ), - static_cast( &LuaJson::get_bool ) - ), - "__newindex", sol::overload( - static_cast( &LuaJson::set_int ), - static_cast( &LuaJson::set_double ), - static_cast( &LuaJson::set_bool ), - static_cast( &LuaJson::set ) - ) - ); + "new", sol::constructors(), + "get", &LuaJson::get, + "is_null", &LuaJson::is_null, + "size", &LuaJson::size, + "has_key", &LuaJson::has_key, + "remove", &LuaJson::remove, + "get_int", &LuaJson::get_int, + "get_double", &LuaJson::get_double, + "get_bool", &LuaJson::get_bool, + "get_string", &LuaJson::get_string, + "set_int", &LuaJson::set_int, + "set_double", &LuaJson::set_double, + "set_bool", &LuaJson::set_bool, + "__index", sol::overload(static_cast(&LuaJson::op), static_cast(&LuaJson::get_int), static_cast(&LuaJson::get_double), static_cast(&LuaJson::get_bool)), + "__newindex", sol::overload(static_cast(&LuaJson::set_int), static_cast(&LuaJson::set_double), static_cast(&LuaJson::set_bool), static_cast(&LuaJson::set))); lua["Json"] = json_ud; lua["storage"] = &lua_storage; } - if (perms.acces_gui) // si gui est autorisé + if (perms.acces_gui) // si gui est autorisé { lua.new_usertype("gui", - "box", &LuaGui::box, - "canvas", &LuaGui::canvas, - "image", sol::overload( - [](LuaGui* gui, LuaWidget* parent, std::string path, int x, int y, int width, int height) -> LuaImage* { - return gui->image(parent, path, x, y, width, height, COLOR_WHITE); - }, - &LuaGui::image - ), - "label", &LuaGui::label, - "input", &LuaGui::input, - "button", &LuaGui::button, - "window", &LuaGui::window, - "switch", &LuaGui::switchb, - "radio", &LuaGui::radio, - "vlist", &LuaGui::verticalList, - "hlist", &LuaGui::horizontalList, - "checkbox", &LuaGui::checkbox, - "del", &LuaGui::del, - "setWindow", &LuaGui::setMainWindow, - "getWindow", &LuaGui::getMainWindow, - "keyboard", &LuaGui::keyboard, - "showInfoMessage", &LuaGui::showInfoMessage, - "showWarningMessage", &LuaGui::showWarningMessage, - "showErrorMessage", &LuaGui::showErrorMessage - ); + "box", &LuaGui::box, + "canvas", &LuaGui::canvas, + "image", sol::overload([](LuaGui *gui, LuaWidget *parent, std::string path, int x, int y, int width, int height) -> LuaImage * + { return gui->image(parent, path, x, y, width, height, COLOR_WHITE); }, &LuaGui::image), + "label", &LuaGui::label, + "input", &LuaGui::input, + "button", &LuaGui::button, + "window", &LuaGui::window, + "switch", &LuaGui::switchb, + "radio", &LuaGui::radio, + "vlist", &LuaGui::verticalList, + "hlist", &LuaGui::horizontalList, + "checkbox", &LuaGui::checkbox, + "del", &LuaGui::del, + "setWindow", &LuaGui::setMainWindow, + "getWindow", &LuaGui::getMainWindow, + "keyboard", &LuaGui::keyboard, + "showInfoMessage", &LuaGui::showInfoMessage, + "showWarningMessage", &LuaGui::showWarningMessage, + "showErrorMessage", &LuaGui::showErrorMessage); lua["gui"] = &lua_gui; lua.new_usertype("widget", - "setX", &LuaWidget::setX, - "setY", &LuaWidget::setY, - "setWidth", &LuaWidget::setWidth, - "setHeight", &LuaWidget::setHeight, - "getX", &LuaWidget::getX, - "getY", &LuaWidget::getY, - "getWidth", &LuaWidget::getWidth, - "getHeight", &LuaWidget::getHeight, - "setBackgroundColor", &LuaWidget::setBackgroundColor, - "setBorderColor",&LuaWidget::setBorderColor, - "setRadius",&LuaWidget::setRadius, - "setBorderSize", &LuaWidget::setBorderSize, - "enable", &LuaWidget::enable, - "disable", &LuaWidget::disable, - "isEnabled", &LuaWidget::isEnabled, - "isTouched", &LuaWidget::isTouched, - "onClick", &LuaWidget::onClick, - "getChildAtIndex", &LuaWidget::getChildAtIndex - ); + "setX", &LuaWidget::setX, + "setY", &LuaWidget::setY, + "setWidth", &LuaWidget::setWidth, + "setHeight", &LuaWidget::setHeight, + "getX", &LuaWidget::getX, + "getY", &LuaWidget::getY, + "getWidth", &LuaWidget::getWidth, + "getHeight", &LuaWidget::getHeight, + "setBackgroundColor", &LuaWidget::setBackgroundColor, + "setBorderColor", &LuaWidget::setBorderColor, + "setRadius", &LuaWidget::setRadius, + "setBorderSize", &LuaWidget::setBorderSize, + "clear", &LuaWidget::clear, + "enable", &LuaWidget::enable, + "disable", &LuaWidget::disable, + "isEnabled", &LuaWidget::isEnabled, + "isTouched", &LuaWidget::isTouched, + "onClick", &LuaWidget::onClick, + "getChildAtIndex", &LuaWidget::getChildAtIndex); lua.new_usertype("LuaWindow", - sol::constructors(), // Empty constructor - sol::base_classes, sol::bases(), - - sol::meta_function::garbage_collect, - sol::destructor(LuaWindow::delete_LuaWindow) - ); + sol::constructors(), // Empty constructor + sol::base_classes, sol::bases(), + + sol::meta_function::garbage_collect, + sol::destructor(LuaWindow::delete_LuaWindow)); lua.new_usertype("LuaBox", - "setRadius", &LuaBox::setRadius, - sol::base_classes, sol::bases()); + "setRadius", &LuaBox::setRadius, + sol::base_classes, sol::bases()); lua.new_usertype("LuaCanvas", - "setPixel", &LuaCanvas::setPixel, - "drawRect", &LuaCanvas::drawRect, - "fillRect", &LuaCanvas::fillRect, - "drawCircle", &LuaCanvas::drawCircle, - "fillCircle", &LuaCanvas::fillCircle, - "drawRoundRect", &LuaCanvas::drawRoundRect, - "fillRoundRect", &LuaCanvas::fillRoundRect, - "drawPolygon", &LuaCanvas::drawPolygon, - "fillPolygon", &LuaCanvas::fillPolygon, - "drawLine", &LuaCanvas::drawLine, - "drawText", &LuaCanvas::drawText, - "drawTextCentered", &LuaCanvas::drawTextCentered, - "drawTextCenteredInBounds", &LuaCanvas::drawTextCenteredInRect, - "getTouch", &LuaCanvas::getTouch, - "onTouch", &LuaCanvas::onTouch, - sol::base_classes, sol::bases()); + "setPixel", &LuaCanvas::setPixel, + "drawRect", &LuaCanvas::drawRect, + "fillRect", &LuaCanvas::fillRect, + "drawCircle", &LuaCanvas::drawCircle, + "fillCircle", &LuaCanvas::fillCircle, + "drawRoundRect", &LuaCanvas::drawRoundRect, + "fillRoundRect", &LuaCanvas::fillRoundRect, + "drawPolygon", &LuaCanvas::drawPolygon, + "fillPolygon", &LuaCanvas::fillPolygon, + "drawLine", &LuaCanvas::drawLine, + "drawText", &LuaCanvas::drawText, + "drawTextCentered", &LuaCanvas::drawTextCentered, + "drawTextCenteredInBounds", &LuaCanvas::drawTextCenteredInRect, + "getTouch", &LuaCanvas::getTouch, + "onTouch", &LuaCanvas::onTouch, + sol::base_classes, sol::bases()); lua.new_usertype("LuaImage", - "setTransparentColor", &LuaImage::setTransparentColor, + "setTransparentColor", &LuaImage::setTransparentColor, - sol::base_classes, sol::bases()); + sol::base_classes, sol::bases()); lua.new_usertype("LuaLabel", - "setText", &LuaLabel::setText, - "getText", &LuaLabel::getText, - "setFontSize", &LuaLabel::setFontSize, - "getTextHeight", &LuaLabel::getTextHeight, - "getTextWidth", &LuaLabel::getTextWidth, - "setVerticalAlignment", &LuaLabel::setVerticalAlignment, - "setHorizontalAlignment", &LuaLabel::setHorizontalAlignment, - "setTextColor", &LuaLabel::setTextColor, - sol::base_classes, sol::bases()); + "setText", &LuaLabel::setText, + "getText", &LuaLabel::getText, + "setFontSize", &LuaLabel::setFontSize, + "getTextHeight", &LuaLabel::getTextHeight, + "getTextWidth", &LuaLabel::getTextWidth, + "setVerticalAlignment", &LuaLabel::setVerticalAlignment, + "setHorizontalAlignment", &LuaLabel::setHorizontalAlignment, + "setTextColor", &LuaLabel::setTextColor, + "setStrikeOut", &LuaLabel::setStrikeOut, + sol::base_classes, sol::bases()); lua.new_usertype("LuaInput", - "setText", &LuaInput::setText, - "getText", &LuaInput::getText, - "setPlaceHolder", &LuaInput::setPlaceHolder, - "setTitle", &LuaInput::setTitle, - sol::base_classes, sol::bases()); - + "setText", &LuaInput::setText, + "getText", &LuaInput::getText, + "setPlaceHolder", &LuaInput::setPlaceHolder, + "setTitle", &LuaInput::setTitle, + sol::base_classes, sol::bases()); + lua.new_usertype("LuaButton", - "setText", &LuaButton::setText, - "getText", &LuaButton::getText, - "setIcon", &LuaButton::setIcon, - "setTheme", &LuaButton::setTheme, - "format", &LuaButton::format, - sol::base_classes, sol::bases()); + "setText", &LuaButton::setText, + "getText", &LuaButton::getText, + "setIcon", &LuaButton::setIcon, + "setTheme", &LuaButton::setTheme, + "format", &LuaButton::format, + sol::base_classes, sol::bases()); lua.new_usertype("LuaSwitch", - "setState", &LuaSwitch::setState, - "getState", &LuaSwitch::getState, - sol::base_classes, sol::bases()); + "setState", &LuaSwitch::setState, + "getState", &LuaSwitch::getState, + sol::base_classes, sol::bases()); lua.new_usertype("LuaRadio", - "setState", &LuaRadio::setState, - "getState", &LuaRadio::getState, - sol::base_classes, sol::bases()); + "setState", &LuaRadio::setState, + "getState", &LuaRadio::getState, + sol::base_classes, sol::bases()); lua.new_usertype("LuaCheckbox", - "setState", &LuaCheckbox::setState, - "getState", &LuaCheckbox::getState, - sol::base_classes, sol::bases()); + "setState", &LuaCheckbox::setState, + "getState", &LuaCheckbox::getState, + sol::base_classes, sol::bases()); lua.new_usertype("LuaVList", - "setIndex", &LuaVerticalList::setIndex, - "setSpaceLine", &LuaVerticalList::setSpaceLine, - "setSelectionFocus", &LuaVerticalList::setFocus, - "getSelected", &LuaVerticalList::getSelected, - "select", &LuaVerticalList::select, - "setSelectionColor", &LuaVerticalList::setSelectionColor, - "setAutoSelect", &LuaVerticalList::setAutoSelect, - "onSelect", &LuaVerticalList::onSelect, - sol::base_classes, sol::bases()); + "setIndex", &LuaVerticalList::setIndex, + "setSpaceLine", &LuaVerticalList::setSpaceLine, + "setSelectionFocus", &LuaVerticalList::setFocus, + "getSelected", &LuaVerticalList::getSelected, + "select", &LuaVerticalList::select, + "setSelectionColor", &LuaVerticalList::setSelectionColor, + "setAutoSelect", &LuaVerticalList::setAutoSelect, + "onSelect", &LuaVerticalList::onSelect, + sol::base_classes, sol::bases()); lua.new_usertype("LuaHList", - //"add", &LuaHorizontalList::add, - "setSpaceLine", &LuaHorizontalList::setSpaceLine, - sol::base_classes, sol::bases()); + //"add", &LuaHorizontalList::add, + "setSpaceLine", &LuaHorizontalList::setSpaceLine, + sol::base_classes, sol::bases()); lua.set("SELECTION_UP", VerticalList::SelectionFocus::UP); lua.set("SELECTION_CENTER", VerticalList::SelectionFocus::CENTER); @@ -537,7 +562,7 @@ void LuaFile::load() lua.set("COLOR_LIGHT_GREY", COLOR_LIGHT_GREY); lua.set_function("launch", sol::overload([&](std::string name, std::vector arg) - { + { try{ AppManager::get(name)->run(false, arg); } @@ -548,42 +573,39 @@ void LuaFile::load() guiManager.showErrorMessage(e.what()); } - return true; - }, - [&](std::string name) - { - try{ - AppManager::get(name)->run(false, {}); - } - catch(std::runtime_error &e) { - std::cerr << "Erreur: " << e.what() << std::endl; - // Ajout message d'erreur - GuiManager &guiManager = GuiManager::getInstance(); - guiManager.showErrorMessage(e.what()); - - } - - return true; - } - ) - ); + return true; }, + [&](std::string name) + { + try + { + AppManager::get(name)->run(false, {}); + } + catch (std::runtime_error &e) + { + std::cerr << "Erreur: " << e.what() << std::endl; + // Ajout message d'erreur + GuiManager &guiManager = GuiManager::getInstance(); + guiManager.showErrorMessage(e.what()); + } + + return true; + })); } - if(perms.acces_time) + if (perms.acces_time) { lua.new_usertype("time", - "monotonic", &LuaTime::monotonic, - "get", &LuaTime::get, - "setInterval", &LuaTime::setInterval, - "setTimeout", &LuaTime::setTimeout, - "removeInterval", &LuaTime::removeInterval, - "removeTimeout", &LuaTime::removeTimeout - ); + "monotonic", &LuaTime::monotonic, + "get", &LuaTime::get, + "setInterval", &LuaTime::setInterval, + "setTimeout", &LuaTime::setTimeout, + "removeInterval", &LuaTime::removeInterval, + "removeTimeout", &LuaTime::removeTimeout); lua["time"] = &lua_time; } - if(perms.acces_gsm) + if (perms.acces_gsm) { sol::table luaGSM = lua.create_table(); @@ -604,66 +626,76 @@ void LuaFile::load() luaGSM["addContact"] = &Contacts::addContact; lua.new_usertype("Contact", - "name", &Contacts::contact::name, - "phone", &Contacts::contact::phone - ); + "name", &Contacts::contact::name, + "phone", &Contacts::contact::phone); - lua.new_usertype("Message", - "message", &Conversations::Message::message, - "who", &Conversations::Message::who, - "date", &Conversations::Message::date - ); - - luaGSM["getMessages"] = [&](const std::string& number) { + "message", &Conversations::Message::message, + "who", &Conversations::Message::who, + "date", &Conversations::Message::date); + + luaGSM["getMessages"] = [&](const std::string &number) + { return LuaGSM::getMessages(number, lua); }; lua["gsm"] = luaGSM; } - { // load events + { // load events sol::table luaEvents = lua.create_table(); - luaEvents["oncall"] = [&](sol::protected_function func) { this->oncall = func; }; - luaEvents["onmessage"] = [&](sol::protected_function func) { this->onmessage = func; std::cout << "onmessage event registered" << std::endl; }; - luaEvents["onlowbattery"] = [&](sol::protected_function func) { this->onlowbattery = func; }; - luaEvents["oncharging"] = [&](sol::protected_function func) { this->oncharging = func; }; - luaEvents["onmessageerror"] = [&](sol::protected_function func) { this->onmessageerror = func; }; + luaEvents["oncall"] = [&](sol::protected_function func) + { this->oncall = func; }; + luaEvents["onmessage"] = [&](sol::protected_function func) + { this->onmessage = func; std::cout << "onmessage event registered" << std::endl; }; + luaEvents["onlowbattery"] = [&](sol::protected_function func) + { this->onlowbattery = func; }; + luaEvents["oncharging"] = [&](sol::protected_function func) + { this->oncharging = func; }; + luaEvents["onmessageerror"] = [&](sol::protected_function func) + { this->onmessageerror = func; }; lua["events"] = luaEvents; } lua.set_panic(custom_panic_handler); - //lua.set_exception_handler(sol_exception_handler); + // lua.set_exception_handler(sol_exception_handler); } -#define SAFE_CALL(func, lua, arg) do { \ - sol::protected_function_result result = func(arg); \ - if (!result.valid()) { \ - sol::error err = result; \ - const char* what = err.what(); \ - if (what) { \ - printf("Error from Lua: %s\n", what); \ - } else { \ - printf("Unknown Lua error occurred\n"); \ - } \ - } \ -} while(0) +#define SAFE_CALL(func, lua, arg) \ + do \ + { \ + sol::protected_function_result result = func(arg); \ + if (!result.valid()) \ + { \ + sol::error err = result; \ + const char *what = err.what(); \ + if (what) \ + { \ + printf("Error from Lua: %s\n", what); \ + } \ + else \ + { \ + printf("Unknown Lua error occurred\n"); \ + } \ + } \ + } while (0) void LuaFile::run(std::vector arg) { // run the app - //lua.set_exception_handler(AppManager::pushError); + // lua.set_exception_handler(AppManager::pushError); std::cout << "Loading Lua File: " << filename.str() << std::endl; storage::FileStream file(filename.str(), storage::READ); - + std::string code = file.read(); file.close(); - lua.script(code); code.clear(); // load and delete the unnecessary code + lua.script(code); + code.clear(); // load and delete the unnecessary code SAFE_CALL(lua["run"], lua, arg); } @@ -679,7 +711,8 @@ void LuaFile::runBackground(std::vector arg) std::string code = file.read(); file.close(); - lua.script(code); code = ""; // load and delete the unnecessary code + lua.script(code); + code = ""; // load and delete the unnecessary code sol::protected_function func = lua["background"]; lua["background"](arg); @@ -696,7 +729,8 @@ void LuaFile::wakeup(std::vector arg) void LuaFile::stop(std::vector arg) { - const sol::protected_function func = lua.get("quit");; + const sol::protected_function func = lua.get("quit"); + ; if (!func.valid()) return; @@ -705,6 +739,6 @@ void LuaFile::stop(std::vector arg) void LuaFile::loop() { - //lua_gui.update(); // add App Priority To Acces Gui + // lua_gui.update(); // add App Priority To Acces Gui lua_time.update(); } \ No newline at end of file diff --git a/lib/lua/src/lua_file.hpp b/lib/lua/src/lua_file.hpp index 7d180570..e14c79bd 100755 --- a/lib/lua/src/lua_file.hpp +++ b/lib/lua/src/lua_file.hpp @@ -7,6 +7,7 @@ #include #include #include +#include #include "lua_gui.hpp" #include "lua_hardware.hpp" @@ -86,6 +87,7 @@ class LuaFile { storage::Path filename; Window* current_root; + EventHandler eventHandler; LuaHardware lua_hardware; LuaGui lua_gui; LuaStorage lua_storage; diff --git a/lib/lua/src/lua_gui.cpp b/lib/lua/src/lua_gui.cpp index bfe6d6ee..5bddf9b6 100644 --- a/lib/lua/src/lua_gui.cpp +++ b/lib/lua/src/lua_gui.cpp @@ -141,10 +141,24 @@ LuaWindow* LuaGui::window() void LuaGui::del(LuaWidget* widget) { - delete widget; - if(mainWindow == widget) - mainWindow = nullptr; - widget = nullptr; +// prevent a widget to remove itself during its execution + lua->eventHandler.setTimeout( + new Callback<>( + std::bind( + std::function( + [](LuaWidget* widget, LuaWidget* mainWindow) + { + delete widget; + if(mainWindow == widget) + mainWindow = nullptr; + widget = nullptr; + } + ), + widget, mainWindow + ) + ), 0 + + ); } void LuaGui::update() diff --git a/lib/lua/src/lua_image.hpp b/lib/lua/src/lua_image.hpp index 19b26400..b0b7d481 100644 --- a/lib/lua/src/lua_image.hpp +++ b/lib/lua/src/lua_image.hpp @@ -11,4 +11,5 @@ class LuaImage : public LuaWidget Image* widget = nullptr; }; + #endif \ No newline at end of file diff --git a/lib/lua/src/lua_label.hpp b/lib/lua/src/lua_label.hpp index 704e5793..491fa3bf 100644 --- a/lib/lua/src/lua_label.hpp +++ b/lib/lua/src/lua_label.hpp @@ -5,23 +5,24 @@ class LuaLabel : public LuaWidget { - public: - LuaLabel(LuaWidget* parent, int x, int y, int width, int height); +public: + LuaLabel(LuaWidget *parent, int x, int y, int width, int height); - void setText(const std::string& text){ widget->setText(text); } - std::string getText(){ return widget->getText(); } + void setText(const std::string &text) { widget->setText(text); } + std::string getText() { return widget->getText(); } - void setFontSize(int fontSize){ widget->setFontSize(fontSize); } + void setFontSize(int fontSize) { widget->setFontSize(fontSize); } - int getTextWidth(){ return widget->getTextWidth(); } - int getTextHeight(){ return widget->getTextHeight(); } - - void setVerticalAlignment(Label::Alignement alignment){ widget->setVerticalAlignment(alignment); } - void setHorizontalAlignment(Label::Alignement alignment){ widget->setHorizontalAlignment(alignment); } + int getTextWidth() { return widget->getTextWidth(); } + int getTextHeight() { return widget->getTextHeight(); } - void setTextColor(color_t color){ widget->setTextColor(color); } + void setVerticalAlignment(Label::Alignement alignment) { widget->setVerticalAlignment(alignment); } + void setHorizontalAlignment(Label::Alignement alignment) { widget->setHorizontalAlignment(alignment); } - Label* widget = nullptr; + void setTextColor(color_t color) { widget->setTextColor(color); } + void setStrikeOut(bool strikeout) { widget->setStrikeOut(strikeout); } + + Label *widget = nullptr; }; #endif \ No newline at end of file diff --git a/lib/lua/src/lua_widget.cpp b/lib/lua/src/lua_widget.cpp index 8b17bce8..2c34528f 100644 --- a/lib/lua/src/lua_widget.cpp +++ b/lib/lua/src/lua_widget.cpp @@ -163,6 +163,13 @@ void LuaWidget::update() } } +void LuaWidget::clear() { + + while (!this->children.empty()) { + delete this->children[0]; + } +} + void LuaWidget::addChild(LuaWidget* child) { diff --git a/lib/lua/src/lua_widget.hpp b/lib/lua/src/lua_widget.hpp index 85a8f3fc..ba06570a 100644 --- a/lib/lua/src/lua_widget.hpp +++ b/lib/lua/src/lua_widget.hpp @@ -36,6 +36,7 @@ class LuaWidget void onScrollRight(sol::protected_function func){onScrollRightFunc = func;} void onScrollLeft(sol::protected_function func){onScrollLeftFunc = func;} LuaWidget* getChildAtIndex(int index){return children[index];} + void clear(); void update(); virtual void specificUpdate(){}; diff --git a/storage/apps/demineur/app.lua b/storage/apps/demineur/app.lua new file mode 100644 index 00000000..3db0ed59 --- /dev/null +++ b/storage/apps/demineur/app.lua @@ -0,0 +1,442 @@ +-- Minesweeper Game in Lua + +-- Configuration +local level = '{"easy":{"gridSize":8, "mineCount":7, "colorNiveau": 1024},"medium":{"gridSize":12, "mineCount":25, "colorNiveau":31}, "hard":{"gridSize":14, "mineCount":37, "colorNiveau":63488}}' + +-- valeur par défaut de la taille de la grille et du nb de mines +local gridSize = 8 +local mineCount = 7 +local colorNiveau = COLOR_GREEN + +-- grille du démineur +local grid = {} +local espacementBox +local sizeCase + +-- Element +local imgStatut, boxActionFlag, lblNbMine +local lblTimer, idTimer +local flagAction = false +local isGameOver + +function run() + + -- affiche l'écran de sélection du niveau + afficheSelectionNiveau() + +end + +--Fonction helper int : renvoi x tronqué +function int(x) + return math.floor(x) +end + + +-- ------------------------------------------------ +-- GESTION DE L'ECRAN DE SELECTION DU NIVEAU +-- ------------------------------------------------ + + +-- Initialise l'écran du jeu +function afficheSelectionNiveau() + + + winSelectionNiveau = gui:window() + + lblTitle = gui:label(winSelectionNiveau, 15, 10, 200, 28) + lblTitle:setFontSize(24) + lblTitle:setText("Démineur") + + local lblEasy = gui:label(winSelectionNiveau, 50, 150, 200, 30) + lblEasy:setFontSize(20) + lblEasy:setHorizontalAlignment(CENTER_ALIGNMENT) + lblEasy:setVerticalAlignment(CENTER_ALIGNMENT) + lblEasy:setBorderSize(1) + lblEasy:setRadius(10) + lblEasy:setBackgroundColor(COLOR_LIGHT_GREY) + lblEasy:setText("easy") + lblEasy:onClick(function() selectionNiveau("easy") end) + + local lblMedium = gui:label(winSelectionNiveau, 50, 200, 200, 30) + lblMedium:setFontSize(20) + lblMedium:setHorizontalAlignment(CENTER_ALIGNMENT) + lblMedium:setVerticalAlignment(CENTER_ALIGNMENT) + lblMedium:setBorderSize(1) + lblMedium:setRadius(10) + lblMedium:setBackgroundColor(COLOR_LIGHT_GREY) + lblMedium:setText("medium") + lblMedium:onClick(function() selectionNiveau("medium") end) + + local lblHard = gui:label(winSelectionNiveau, 50, 250, 200, 30) + lblHard:setFontSize(20) + lblHard:setHorizontalAlignment(CENTER_ALIGNMENT) + lblHard:setVerticalAlignment(CENTER_ALIGNMENT) + lblHard:setBorderSize(1) + lblHard:setRadius(10) + lblHard:setBackgroundColor(COLOR_LIGHT_GREY) + lblHard:setText("hard") + lblHard:onClick(function() selectionNiveau("hard") end) + + gui:setWindow(winSelectionNiveau) + +end + + +function selectionNiveau(niveau) + + local json_obj = Json:new(level) + + if (json_obj:has_key(niveau)) then + gridSize = json_obj[niveau]:get_int("gridSize") + mineCount = json_obj[niveau]:get_int("mineCount") + colorNiveau = json_obj[niveau]:get_int("colorNiveau") + end + + prepareGame() + +end + +-- ------------------------------------------------ +-- GESTION DE L'ECRAN DE JEU +-- ------------------------------------------------ + +function prepareGame() +-- initGrid() + --placeMines() + initBoard() + placeMines() + calculateAdjacentMines() +end + +-- Initialise le board +function initBoard() + + win = gui:window() + + local sizeBord = 10 + espacementBox = 1 + sizeCase = int( (win:getWidth() - 2 * sizeBord)/gridSize) + local offsetHaut = win:getHeight() - win:getWidth() - sizeBord + + + local cnvContour = gui:label(win, int(sizeBord/2), int(sizeBord/2), win:getWidth()-sizeBord, win:getHeight()-sizeBord-2) + cnvContour:setRadius(10) + cnvContour:setBorderSize(1) + cnvContour:setBorderColor(colorNiveau) + + local imgHome = gui:image(win, "home.png", 10, 30, 40, 40, COLOR_WHITE) + imgHome:onClick(afficheSelectionNiveau) + + lblStatut = gui:label(win, 50, 90, 220, 40) + lblStatut:setFontSize(24) + lblStatut:setVerticalAlignment(CENTER_ALIGNMENT) + lblStatut:setHorizontalAlignment(CENTER_ALIGNMENT) + lblStatut:setText("") + + lblNbMine = gui:label(win, 55, 30, 80, 40) + lblNbMine:setBackgroundColor(COLOR_BLACK) + lblNbMine:setTextColor(COLOR_RED) + lblNbMine:setFontSize(24) + lblNbMine:setVerticalAlignment(CENTER_ALIGNMENT) + lblNbMine:setHorizontalAlignment(CENTER_ALIGNMENT) + lblNbMine:setText(tostring(mineCount)) + + imgStatut = gui:image(win, "new.png", 140, 30, 40, 40, COLOR_WHITE) + imgStatut:onClick(prepareGame) + + lblTimer = gui:label(win, 185, 30, 80, 40) + lblTimer:setBackgroundColor(COLOR_BLACK) + lblTimer:setTextColor(COLOR_RED) + lblTimer:setFontSize(24) + lblTimer:setVerticalAlignment(CENTER_ALIGNMENT) + lblTimer:setHorizontalAlignment(CENTER_ALIGNMENT) + lblTimer:setText("000") + + boxActionFlag = gui:box(win, 270, 30, 40, 40) + + -- imgActionFlag = gui:image(win, "drapeau.png", 270, 30, 40, 40) + + imgActionFlag = gui:image(boxActionFlag, "drapeau.png", 0, 0, 40, 40) + imgActionFlag:setTransparentColor(COLOR_WHITE) + imgActionFlag:onClick(setFlagAction) + + + for i = 1, gridSize do + grid[i] = {} + + for j = 1, gridSize do + local cnvBox = gui:box(win, sizeBord + sizeCase*(i-1) + espacementBox, offsetHaut + sizeCase*(j-1) - espacementBox, sizeCase - espacementBox, sizeCase - espacementBox) + cnvBox:setBackgroundColor(COLOR_GREY) + cnvBox:onClick(function() clickCase(i,j) end) + + grid[i][j] = { mine = false, revealed = false, adjacentMines = 0, flag = false, box=cnvBox } + + end + end + + if (idTimer) then + time:removeTimeout(idTimer) + end + timer() + + isGameOver = false + + gui:setWindow(win) + +end + + +-- Incrément de l'horloge toutes les secondes +function timer () + local intTimer = tonumber(lblTimer:getText()) + lblTimer:setText(tostring(intTimer+1)) + idTimer = time:setTimeout(timer, 1000) +end + + +-- Function to place mines randomly +function placeMines() + local placedMines = 0 + while placedMines < mineCount do + local x = math.random(1, gridSize) + local y = math.random(1, gridSize) + if not grid[x][y].mine then + grid[x][y].mine = true + placedMines = placedMines + 1 + end + end +end + + + +-- Active / Desactive le flag +function setFlagAction() + + flagAction = not flagAction + + if (flagAction) then + boxActionFlag:setBackgroundColor(COLOR_LIGHT_ORANGE) + else + boxActionFlag:setBackgroundColor(COLOR_WHITE) + end + +end + + +-- gestion d'une partie perdue +function gameover() + + isGameOver = true + -- arret du timer + if (idTimer) then + time:removeTimeout(idTimer) + end + + lblStatut:setText("Perdu !") + lblStatut:setTextColor(COLOR_RED) + + imgStatut = gui:image(win, "lost.png", 140, 30, 40, 40, COLOR_WHITE) + + -- reveal all mines + for x = 1, gridSize do + for y = 1, gridSize do + + if (grid[x][y].mine and not grid[x][y].revealed) then + local box = grid[x][y].box + local img = gui:image(box, "bombe.png",0, 0, sizeCase-espacementBox, sizeCase-espacementBox, COLOR_LIGHT_GREY) + end + end + end + +end + + +-- gestion d'une partie gagnée +function hasWon() + + isGameOver = true + -- arret du timer + if (idTimer) then + time:removeTimeout(idTimer) + end + + lblStatut:setText("gagné !") + lblStatut:setTextColor(COLOR_GREEN) + + +end + + +-- fonciton qui check si on a gagner +function checkHasWon() + + local count = mineCount + + for x = 1, gridSize do + for y = 1, gridSize do + if grid[x][y].mine and grid[x][y].flag then + count = count - 1 + end + end + end + + return count == 0 + +end + +-- decrease or increase nb Mines +-- parameter +function changeMineNum(increase) + + if isGameOver then + return + end + + local nbMine = tonumber(lblNbMine:getText()) + + if (increase and nbMine < mineCount) then + lblNbMine:setText(tostring(nbMine + 1)) + elseif (not increase and nbMine > 0) then + lblNbMine:setText(tostring(nbMine - 1)) + end + +end + +-- Action sur le clik d'une case +function clickCase(x,y) + + if (isGameOver) then + return + end + + -- si la case a déja un flag, on ne fait rien + if (not flagAction and grid[x][y].flag) then + return + end + + local box = grid[x][y].box + -- si on a activé l'action Flag, on affiche/masque le drapeau et on désactive l'action Flag + if (flagAction) then + + local nbMine = tonumber(lblNbMine:getText()) + -- si on veut mettre un flag et que le nombre de flag dispo est à 0, ou que la case est déjà revealed, on sort + if not grid[x][y].flag and nbMine == 0 or grid[x][y].revealed then + + return + end + + -- setFlagAction() + if (grid[x][y].flag) then + grid[x][y].flag = false + changeMineNum(true) + box:clear() + else + grid[x][y].flag = true + local img = gui:image(box, "drapeau.png",0, 0, sizeCase-espacementBox, sizeCase-espacementBox, COLOR_LIGHT_GREY) + changeMineNum(false) + end + if checkHasWon() then + hasWon() + end + return + end + + -- si on tombe sur on mine - gameover + if (grid[x][y].mine) then + local box = grid[x][y].box + local img = gui:image(box, "bombe.png",0, 0, sizeCase-espacementBox, sizeCase-espacementBox, COLOR_RED) + grid[x][y].revealed = true + gameover() + else + revealCell(x, y) + end + + -- rafraichement de la grille + updateGrid() +end + +function updateGrid() + + for x = 1, gridSize do + for y = 1, gridSize do + + if (grid[x][y].revealed and not grid[x][y].flag) then + + local box = grid[x][y].box + + if grid[x][y].mine then + -- on est sur une mine ! + else + box:setBackgroundColor(COLOR_LIGHT_GREY) + if (grid[x][y].adjacentMines > 0) then + local lblCount = gui:label(box, 0, 0, sizeCase-espacementBox, sizeCase-espacementBox) + lblCount:setBackgroundColor((COLOR_LIGHT_GREY)) + lblCount:setVerticalAlignment(CENTER_ALIGNMENT) + lblCount:setHorizontalAlignment(CENTER_ALIGNMENT) + lblCount:setFontSize(14) + if (grid[x][y].adjacentMines == 1) then + lblCount:setTextColor(COLOR_BLUE) + elseif (grid[x][y].adjacentMines == 2) then + lblCount:setTextColor(COLOR_GREEN) + elseif (grid[x][y].adjacentMines > 2) then + lblCount:setTextColor(COLOR_RED) + end + + lblCount:setText(tostring(grid[x][y].adjacentMines)) + end + end + else + -- case non revélée + end + end + end +end + + + +-- Function to calculate adjacent mines for each cell +function calculateAdjacentMines() + local directions = { + {-1, -1}, {-1, 0}, {-1, 1}, + {0, -1}, {0, 1}, + {1, -1}, {1, 0}, {1, 1} + } + + for x = 1, gridSize do + for y = 1, gridSize do + if not grid[x][y].mine then + local count = 0 + for _, dir in ipairs(directions) do + local nx, ny = x + dir[1], y + dir[2] + if nx >= 1 and nx <= gridSize and ny >= 1 and ny <= gridSize and grid[nx][ny].mine then + count = count + 1 + end + end + grid[x][y].adjacentMines = count + end + end + end +end + + + + +-- Fonction récursive pour révéler les cases adjacentes +function revealCell(x, y) + + if x < 1 or x > gridSize or y < 1 or y > gridSize or grid[x][y].revealed then + return + end + grid[x][y].revealed = true + if grid[x][y].adjacentMines == 0 and not grid[x][y].mine then + local directions = { + {-1, -1}, {-1, 0}, {-1, 1}, + {0, -1}, {0, 1}, + {1, -1}, {1, 0}, {1, 1} + } + for _, dir in ipairs(directions) do + revealCell(x + dir[1], y + dir[2]) + end + end +end + diff --git a/storage/apps/demineur/bombe.png b/storage/apps/demineur/bombe.png new file mode 100644 index 00000000..d3c16e4b Binary files /dev/null and b/storage/apps/demineur/bombe.png differ diff --git a/storage/apps/demineur/drapeau.png b/storage/apps/demineur/drapeau.png new file mode 100644 index 00000000..b0127f6d Binary files /dev/null and b/storage/apps/demineur/drapeau.png differ diff --git a/storage/apps/demineur/home.png b/storage/apps/demineur/home.png new file mode 100644 index 00000000..2ce9f2e4 Binary files /dev/null and b/storage/apps/demineur/home.png differ diff --git a/storage/apps/demineur/icon.png b/storage/apps/demineur/icon.png new file mode 100644 index 00000000..e23a8151 Binary files /dev/null and b/storage/apps/demineur/icon.png differ diff --git a/storage/apps/demineur/lost.png b/storage/apps/demineur/lost.png new file mode 100644 index 00000000..b260173b Binary files /dev/null and b/storage/apps/demineur/lost.png differ diff --git a/storage/apps/demineur/manifest.json b/storage/apps/demineur/manifest.json new file mode 100644 index 00000000..66da4a13 --- /dev/null +++ b/storage/apps/demineur/manifest.json @@ -0,0 +1,4 @@ +{ + "access": ["files", "files_root", "gsm", "gui", "hardware", "time", "web", "web_paxo"], + "name": "Démineur" +} diff --git a/storage/apps/demineur/new.png b/storage/apps/demineur/new.png new file mode 100644 index 00000000..70a11839 Binary files /dev/null and b/storage/apps/demineur/new.png differ diff --git a/storage/apps/notes/app.lua b/storage/apps/notes/app.lua new file mode 100644 index 00000000..554cfd66 --- /dev/null +++ b/storage/apps/notes/app.lua @@ -0,0 +1,334 @@ +local filename = "data/notes.dat" +local oldWin + +local data = {} + +-- ------------------------------------------- +-- Fonction initiale de l'application Notes +-- ------------------------------------------- +function run() + + loadDataFile() + initNotes() +end + +-- ------------------------------------------- +-- gestion des datas +-- ------------------------------------------- + +-- chargement du fichier data +function loadDataFile() + if storage:isFile(filename) then + data = loadTable(filename) + sortTable() + + if not data then data = {} end + else + print("[loadDataFile] file not found "..filename) + end +end + + +-- fonction de tri la table Data +function sortTable() + + table.sort(data, function(a,b) + if not a.closed and not b.closed or a.closed and b.closed then + return a.UID > b.UID + elseif a.closed and not b.closed then + return false + elseif not a.closed and b.closed then + return true + else + return a.UID > b.UID + end + end) +end + + +-- Efface les notes qui sont "closed" +function cleanData() + + local tmpData = {} + for i, note in ipairs(data) do + if not note.closed then + table.insert(tmpData, note) + end + end + data = tmpData + saveTable(filename,data) +end + +-- Récupère la note identifiée par UID +-- si UID est nil ou la note UID n'existe pas, créé une nouvelle note vierge et la renvoie +function getNote(UID) + + local note + if not UID or not data[UID] then + note = {} + note.UID = createUID() + note.Title = "" + note.TextNote = "" + note.closed = false + else + note = data[UID] + end + + return note + +end + +-- ------------------------------------------- +-- Ecran Principal +-- ------------------------------------------- + +function initNotes() + + win = manageWindow() + + local Frame = gui:box(win, 0, 0, 320, 65) + Frame:setBackgroundColor(COLOR_WARNING) + Frame:onClick(initNotes) + + local TitleApp = gui:label(Frame, 40, 15, 144, 28) + TitleApp:setText("Mes Notes") + TitleApp:setBackgroundColor(COLOR_WARNING) + TitleApp:setFontSize(32) + + local addLabel = gui:label(win, 270, 420, 40, 40) + addLabel:setRadius(20) + addLabel:setBackgroundColor(COLOR_BLACK) + + local addIcon = gui:image(addLabel, "plus.png", 12, 12, 16, 16, COLOR_BLACK) + addLabel:onClick(editNote) + + local SettingsIcon = gui:image(Frame, "menu.png", 10, 20, 20, 20, COLOR_WARNING) + SettingsIcon:onClick(Settings) + + local lstNotes = gui:vlist(win, 20, 80, 290, 320) + lstNotes:setSpaceLine(5) + + local dataNote = {} + local nbNotes=0 + local hauteurNote = 35 + + for i, note in ipairs(data) do + nbNotes = nbNotes+1 + local boxNote = gui:box(lstNotes, 0, 0, 290, hauteurNote) + boxNote:setBorderSize(1) + boxNote:setBorderColor(COLOR_LIGHT_GREY) + + local chkClosed = gui:checkbox(boxNote, 5, 5) + chkClosed:setState(note.closed) + chkClosed:onClick( + function() + local label = dataNote[i] + note.closed = chkClosed:getState() + label:setStrikeOut(note.closed) + if note.closed then + label:setTextColor(COLOR_GREY) + else + label:setTextColor(COLOR_BLACK) + end + saveTable(filename, data) + end + ) + + local lblNoteTitle = gui:label(boxNote, 30, 5, 258, 20) + dataNote[i] = lblNoteTitle + lblNoteTitle:setFontSize(16) + lblNoteTitle:setText(note.Title) + + if note.closed then + lblNoteTitle:setStrikeOut(true) + lblNoteTitle:setTextColor(COLOR_GREY) + end + + local lblNoteDate = gui:label(boxNote, 220, hauteurNote-11, 69, 10) + lblNoteDate:setTextColor(COLOR_GREY) + lblNoteDate:setVerticalAlignment(RIGHT_ALIGNMENT) + lblNoteDate:setFontSize(10) + lblNoteDate:setText(note.date) + + lblNoteTitle:onClick( + function() + if not chkClosed:getState() then + editNote(note.UID) + end + end + ) + end + + if nbNotes==0 then + local lblEmpty = gui:label(lstNotes, 0, 0, 290, 30) + lblEmpty:setText("aucune note") + lblEmpty:setTextColor(COLOR_GREY) + end + +end + + +-- -------------------------------------------- +-- Ecran de création / modification d'une note +-- @param string UID - ID de la note +-- -------------------------------------------- +function editNote(UID) + + local winNote = manageWindow() + + local Frame = gui:box(winNote, 0, 0, 320, 65) + Frame:setBackgroundColor(COLOR_WARNING) + + local newNote = getNote(UID) + + local TitleApp = gui:label(Frame, 20, 20, 250, 28) + TitleApp:setText("Edition d'une Note") + TitleApp:setBackgroundColor(COLOR_WARNING) + TitleApp:setFontSize(32) + + local inputTitleNote = gui:input(winNote, 35, 80, 250, 40) + inputTitleNote:setTitle("Titre") + inputTitleNote:setText(newNote.Title) + inputTitleNote:onClick( + function () + local keyboard = gui:keyboard("Titre de la note", newNote.Title) + inputTitleNote:setText(keyboard) + newNote.Title = keyboard + end + ) + + local lblNote = gui:label(winNote, 35, 150, 250, 20) + lblNote:setFontSize(16) + lblNote:setTextColor(COLOR_GREY) + lblNote:setText("Note") + + local TextNote = gui:label(winNote, 35, 170, 250, 200) + TextNote:setBorderSize(1) + TextNote:setBorderColor(COLOR_BLACK) + TextNote:setText(newNote.TextNote) + TextNote:onClick(function () + local keyboard = gui:keyboard("Titre de la note", newNote.TextNote) + TextNote:setText(keyboard) + newNote.TextNote = keyboard + end + ) + + cancel = gui:label(winNote, 35, 405, 250, 30) + cancel:setHorizontalAlignment(CENTER_ALIGNMENT) + cancel:setHorizontalAlignment(CENTER_ALIGNMENT) + cancel:setBorderColor(COLOR_BLACK) + cancel:setBorderSize(1) + cancel:setRadius(15) + cancel:setText("Annuler") + cancel:onClick(initNotes) + + edit = gui:label(winNote, 35, 440, 250, 30) + edit:setHorizontalAlignment(CENTER_ALIGNMENT) + edit:setHorizontalAlignment(CENTER_ALIGNMENT) + edit:setBorderSize(1) + edit:setBorderColor(COLOR_BLACK) + edit:setRadius(15) + edit:setText("Sauvegarder") + edit:onClick(function() + newNote.date = getDate() + data[newNote.UID] = newNote + saveTable(filename, data) + initNotes() + end) + +end + + +-- -------------------------------------------- +-- Ecran de Paramétrage +-- -------------------------------------------- + +function Settings() + + local winSetting = manageWindow() + + local Frame = gui:box(winSetting, 0, 0, 320, 65) + Frame:setBackgroundColor(COLOR_WARNING) + + local TitleApp = gui:label(Frame, 40, 15, 250, 28) + TitleApp:setText("Paramétrage") + TitleApp:setBackgroundColor(COLOR_WARNING) + TitleApp:setFontSize(32) + + local imgBack = gui:image(winSetting, "back.png", 10, 15, 20, 30, COLOR_WARNING ) + imgBack:onClick(initNotes) + + + local nbNotesClosed = 0 + local nbNotes = 0 + for i, note in pairs(data) do + nbNotes = nbNotes+1 + if note.closed then nbNotesClosed = nbNotesClosed +1 end + end + + local lblNbNotes = gui:label(winSetting, 30, 150, 200, 40) + lblNbNotes:setText("Nombre de Notes:") + + local lblCountNbNotes = gui:label(winSetting, 270, 150, 30, 40) + lblCountNbNotes:setText(tostring(nbNotes)) + + local lblNbNotesClosed = gui:label(winSetting, 30, 200, 200, 40) + lblNbNotesClosed:setText("Nombre de Notes cloturées:") + + local lblCountNbNotesClosed = gui:label(winSetting, 270, 200, 30, 40) + lblCountNbNotesClosed:setText(tostring(nbNotesClosed)) + + local btnEffacerNotesClosed = gui:label(winSetting, 50, 420, 220, 30) + btnEffacerNotesClosed:setRadius(15) + btnEffacerNotesClosed:setBorderSize(1) + btnEffacerNotesClosed:setBorderColor(COLOR_GREY) + btnEffacerNotesClosed:setHorizontalAlignment(CENTER_ALIGNMENT) + btnEffacerNotesClosed:setVerticalAlignment (CENTER_ALIGNMENT) + btnEffacerNotesClosed:setText("Effacer les notes cloturées") + btnEffacerNotesClosed:onClick(function() cleanData() Settings() end) +end + +-- ---------------------------------------------- +-- function manageWindow +-- +-- Créer une nouvelle fenetre et l'affiche +-- supprime l'ancienne fenetre affichée +-- @return nouvelle fenetre créée +-- @prerequisite variable oldWin est définie +-- ---------------------------------------------- +function manageWindow() + local win + + win = gui:window() + gui:setWindow(win) + + if oldWin then + gui:del(oldWin) + oldWin =nil + end + + oldWin = win + return win +end + + +-- Créer un UID unique sous forme de string +function createUID() + math.randomseed(time:monotonic()) + return "N"..time:monotonic()..math.random(99999) +end + + +-- renvoie la date et heure courante au format dd/mm/yyyy hh:mi +function getDate() + + local today = time:get("y,mo,d,h,mi,s") + local year = today[1] + local month = string.format("%02d", today[2]) + local day = string.format("%02d", today[3]) + local heure = string.format("%02d", today[4]) + local minute = string.format("%02d", today[5]) + + return day.."/"..month.."/"..year.." "..heure..":"..minute +end + diff --git a/storage/apps/calendrier/fleche_gauche.png b/storage/apps/notes/back.png similarity index 100% rename from storage/apps/calendrier/fleche_gauche.png rename to storage/apps/notes/back.png diff --git a/storage/apps/notes/data/notes.dat b/storage/apps/notes/data/notes.dat new file mode 100644 index 00000000..4b9414e1 --- /dev/null +++ b/storage/apps/notes/data/notes.dat @@ -0,0 +1 @@ +{[1]={["date"]="23/09/2024 19:17", ["Title"]="cruju", ["UID"]="N1879210006", ["closed"]=false, ["TextNote"]="jtv", }, } \ No newline at end of file diff --git a/storage/apps/notes/gestionDebug.lua b/storage/apps/notes/gestionDebug.lua new file mode 100644 index 00000000..c0d7f334 --- /dev/null +++ b/storage/apps/notes/gestionDebug.lua @@ -0,0 +1,56 @@ +-- ------------------ +-- FONCTION DE DEBUG +-- ------------------ + + +function debugPrint(t, indent) + + local debugType = true + + if not indent then print("[DEBUG] "..getVariableName(t))end + indent = indent or 0 + local spacing = string.rep(" ", indent) + + if type(t) == "table" then + for k, v in pairs(t) do + if type(v) == "table" then + if debugType then + print(spacing .."("..type(k)..") "..tostring(k) .. ":") + else + print(spacing ..tostring(k)) + end + debugPrint(v, indent + 1) + else + if debugType then + print(spacing .."("..type(k)..") "..tostring(k) .. ": " .. tostring(v) .." ("..type(v)..")") + else + print(spacing ..tostring(k) .. ": " .. tostring(v)) + end + end + end + else + if debugType then + print(spacing .. "("..type(t)..") "..tostring(t)) + else + print(spacing ..tostring(t)) + end + end +end + + +function getVariableName(var) + local name +-- for k, v in pairs(_G) do + for k, v in pairs(_G) do + if v == var then + name = k + break + end + end + if name then + return name + else + return "Variable not found" + end +end + diff --git a/storage/apps/notes/icon.png b/storage/apps/notes/icon.png new file mode 100644 index 00000000..ac08e12a Binary files /dev/null and b/storage/apps/notes/icon.png differ diff --git a/storage/apps/notes/manifest.json b/storage/apps/notes/manifest.json new file mode 100644 index 00000000..1260798c --- /dev/null +++ b/storage/apps/notes/manifest.json @@ -0,0 +1,4 @@ +{ + "access": ["files", "files_root", "gsm", "gui", "hardware", "time", "web", "web_paxo"], + "name": "notes" +} \ No newline at end of file diff --git a/storage/apps/notes/menu.png b/storage/apps/notes/menu.png new file mode 100644 index 00000000..89f28d8c Binary files /dev/null and b/storage/apps/notes/menu.png differ diff --git a/storage/apps/notes/plus.png b/storage/apps/notes/plus.png new file mode 100644 index 00000000..a384eca1 Binary files /dev/null and b/storage/apps/notes/plus.png differ diff --git a/storage/system/auth.list b/storage/system/auth.list index e344691c..ef76f687 100644 --- a/storage/system/auth.list +++ b/storage/system/auth.list @@ -8,4 +8,6 @@ ./storage/apps/horloge/app.lua ./storage/apps/alarme/app.lua ./storage/apps/calculatrice/app.lua -./storage/apps/calendrier/app.lua \ No newline at end of file +./storage/apps/demineur/app.lua +./storage/apps/calendrier/app.lua +./storage/apps/notes/app.lua \ No newline at end of file diff --git a/storage/system/demineur.json b/storage/system/demineur.json new file mode 100644 index 00000000..6ce7f31b --- /dev/null +++ b/storage/system/demineur.json @@ -0,0 +1,3 @@ +{ + "access": ["files", "gsm", "gui", "hardware", "time", "web", "web_paxo"] +} diff --git a/storage/system/notes.json b/storage/system/notes.json new file mode 100644 index 00000000..85c66393 --- /dev/null +++ b/storage/system/notes.json @@ -0,0 +1,3 @@ +{ + "access": ["files", "files_root", "contacts", "os", "gsm", "gui", "hardware", "time", "web", "web_paxo"] +}