#pragma once #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "GLOBALS.h" #include #include #include #include "event_manager.h" // Forward declarations class Shell; class TFT_Handler; struct TaskBarItem { std::string name; short place_x; short place_y; short width; short height; char id; char offset_x; bool focused; }; struct DesktopItem { std::string program_class; // Which program class to instantiate std::string name; short place_x; short place_y; char id; char icon_size_x; char icon_size_y; }; enum class WindowAction : uint8_t { EXIT = 1, FILE = 2, HELP = 3, MINIMIZE = 4, CLOSE = 5, }; struct WindowDecoration { short x_offset; short y_offset; short width; short height; WindowAction action; }; struct TextLine { std::string text; short local_y; // Y position relative to the text box }; struct ScrollableTextBox { std::string content; std::vector lines; short x; short y; short width; short height; short scroll_offset; short cursor_pos; short text_size; short line_height; bool selected; void reflow_text(TFT_Handler* tft); // Declaration only void scroll(short delta) { scroll_offset += delta; // Clamp scroll offset short max_scroll = 0; if (!lines.empty()) { max_scroll = std::max(0, (int)(lines.back().local_y + line_height - height)); } if (scroll_offset < 0) scroll_offset = 0; if (scroll_offset > max_scroll) scroll_offset = max_scroll; } }; struct WindowContentText { std::string text; short x; short y; short width; short height; char size; bool selectable = false; bool selected = false; }; struct ContentButton { std::string action; short x; short y; short width; short height; bool pressed; }; struct Window { std::string title; std::vector text_boxes; std::vector window_content_text; std::vector window_decorations; std::vector content_buttons; unsigned short x; unsigned short y; unsigned short width; unsigned short height; unsigned short background_color; unsigned short foreground_color; char id; bool focused; bool minimized; }; // Base Program class - all programs inherit from this class Program : public IEventListener { protected: std::string _name; Window* _window; CALIBRATION_IDLE _calibration_idle; Shell* _shell; TFT_Handler* _tft; DISPLAY_STATE* _display_state; TaskHandle_t _task_handle; char _id; bool _running; static void task_wrapper(void* pvParameters); public: Program(); virtual ~Program(); // Initialize the program with its window and shell reference void init(char id, const std::string& name, Window* window, Shell* shell, TFT_Handler* tft, DISPLAY_STATE* display_state, CALIBRATION_IDLE calibration_idle); // Override this in your specific programs virtual void run() = 0; // listen to click events void on_click_event(CLICK_EVENT event) override; // Called when the program should stop virtual void close(); // Getters short get_id() const { return _id; } std::string get_name() const { return _name; } Window* get_window() const { return _window; } };