From 15c7523f21f5b3a40c5fe45ae17a36e189a162dc Mon Sep 17 00:00:00 2001 From: rasmus Date: Sun, 18 Jan 2026 20:08:39 +0100 Subject: [PATCH] Removed unused code --- Desktop_Test/GLOBALS.h | 2 + Desktop_Test/example_programs.h | 69 ++++++++++++++++---------- Desktop_Test/helpers.cpp | 48 ++++++++++++++++++ Desktop_Test/helpers.h | 3 +- Desktop_Test/input_manager.cpp | 87 ++++----------------------------- Desktop_Test/input_manager.h | 13 +---- Desktop_Test/program.h | 36 +++++++++++++- Desktop_Test/shell.cpp | 9 +--- Desktop_Test/tft_handler.cpp | 25 ++++++++++ Desktop_Test/tft_handler.h | 2 + 10 files changed, 169 insertions(+), 125 deletions(-) diff --git a/Desktop_Test/GLOBALS.h b/Desktop_Test/GLOBALS.h index 53b6587..9485868 100644 --- a/Desktop_Test/GLOBALS.h +++ b/Desktop_Test/GLOBALS.h @@ -19,6 +19,8 @@ enum CLICK_EVENTS : uint8_t { RIGHT_CLICK = 2, ENTER = 3, KEYBOARD = 4, + UP = 5, + DOWN = 6, }; struct CLICK_EVENT { diff --git a/Desktop_Test/example_programs.h b/Desktop_Test/example_programs.h index b7109e5..96303bd 100644 --- a/Desktop_Test/example_programs.h +++ b/Desktop_Test/example_programs.h @@ -50,31 +50,46 @@ public: }; class TextEditorProgram : public Program { +private: + short selected_box_index = -1; + public: ~TextEditorProgram() { EventManager::getInstance().unsubscribe(this); } - void on_click_event(CLICK_EVENT event) { + void on_click_event(CLICK_EVENT event) override { if (_window->minimized) return; - for (WindowContentText& text : _window->window_content_text) { - if (event.x >= text.x && event.x <= (text.x + text.width) && event.y >= text.y && event.y <= (text.y + text.height) && (event.event == CLICK_EVENTS::LEFT_CLICK || event.event == CLICK_EVENTS::ENTER)) { - if (text.selectable && !text.selected) { - for (WindowContentText& temp : _window->window_content_text) temp.selected = false; - text.selected = true; + for (size_t i = 0; i < _window->text_boxes.size(); i++) { + auto& box = _window->text_boxes[i]; + + if (event.x >= box.x && event.x <= (box.x + box.width) && + event.y >= box.y && event.y <= (box.y + box.height)) { + + if (event.event == CLICK_EVENTS::LEFT_CLICK) { + // Deselect all boxes + for (auto& b : _window->text_boxes) b.selected = false; + box.selected = true; + selected_box_index = i; + _display_state->update_display.store(true); } - } else if (event.event == CLICK_EVENTS::LEFT_CLICK || event.event == CLICK_EVENTS::ENTER) { - if (text.selected) text.selected = false; + } else { + if (event.event == CLICK_EVENTS::LEFT_CLICK) for (auto& b : _window->text_boxes) b.selected = false; } - - if (text.selected && event.event == CLICK_EVENTS::KEYBOARD) { - if ((text.x + text.width) >= (_window->x + _window->width)) { - text.text += "\n"; - Serial.println("Aight"); + } + + if (selected_box_index >= 0) { + auto& box = _window->text_boxes[selected_box_index]; + + if (event.event == CLICK_EVENTS::KEYBOARD) { + if (event.character == '\n' || event.character == '\r') { + box.content += '\n'; + } else { + box.content += event.character; } - text.text += event.character; - _tft->get_text_bounds(text.text, text.size, text.width, text.height); + box.reflow_text(_tft); + _display_state->update_display.store(true); } } } @@ -85,19 +100,19 @@ public: _window->x += 100; _window->width -= 50; - WindowContentText text; - text.x = _window->x + 5; - text.y = _window->y + 60; - text.width = 50; - text.height = 10; - text.size = 2; - text.selectable = true; - text.selected = false; - text.text = "asddsa"; + ScrollableTextBox box; + box.x = _window->x + 5; + box.y = _window->y + 60; + box.width = _window->width - 15; + box.height = _window->height - 70; + box.scroll_offset = 0; + box.text_size = 2; + box.line_height = 16; // Adjust based on your font + box.selected = false; + box.content = "Type here..."; + box.reflow_text(_tft); - _tft->get_text_bounds(text.text, text.size, text.width, text.height); - - _window->window_content_text.push_back(text); + _window->text_boxes.push_back(box); while (_running) { vTaskDelay(pdMS_TO_TICKS(1)); diff --git a/Desktop_Test/helpers.cpp b/Desktop_Test/helpers.cpp index b213a8c..a0b9a39 100644 --- a/Desktop_Test/helpers.cpp +++ b/Desktop_Test/helpers.cpp @@ -1,4 +1,6 @@ #include "helpers.h" +#include "program.h" +#include "tft_handler.h" void Helpers::recalculate_taskbar(std::vector& task_bar_items) { for (short i = 0; i < task_bar_items.size(); ++i) { @@ -9,4 +11,50 @@ void Helpers::recalculate_taskbar(std::vector& task_bar_items) { task_bar_items[i].place_x = prev.place_x + prev.offset_x; } } +} + +void ScrollableTextBox::reflow_text(TFT_Handler* tft) { + lines.clear(); + std::string current_line = ""; + short current_y = 0; + + for (size_t i = 0; i < content.length(); i++) { + char c = content[i]; + + if (c == '\n') { + // Explicit newline + lines.push_back({current_line, current_y}); + current_line = ""; + current_y += line_height; + continue; + } + + // Check if adding this character would exceed width + short test_width, test_height; + std::string test_str = current_line + c; + tft->get_text_bounds(test_str, text_size, test_width, test_height); + + if (test_width > width - 10) { // -10 for padding + // Word wrap - try to break at last space + size_t last_space = current_line.find_last_of(' '); + if (last_space != std::string::npos) { + // Break at space + std::string line_to_add = current_line.substr(0, last_space); + lines.push_back({line_to_add, current_y}); + current_line = current_line.substr(last_space + 1) + c; + } else { + // No space found, hard break + lines.push_back({current_line, current_y}); + current_line = std::string(1, c); + } + current_y += line_height; + } else { + current_line += c; + } + } + + // Add remaining text + if (!current_line.empty()) { + lines.push_back({current_line, current_y}); + } } \ No newline at end of file diff --git a/Desktop_Test/helpers.h b/Desktop_Test/helpers.h index fd27592..b81806f 100644 --- a/Desktop_Test/helpers.h +++ b/Desktop_Test/helpers.h @@ -5,4 +5,5 @@ struct Helpers { static void recalculate_taskbar(std::vector& task_bar_items); -}; \ No newline at end of file +}; + diff --git a/Desktop_Test/input_manager.cpp b/Desktop_Test/input_manager.cpp index bb6b51f..d4e90fe 100644 --- a/Desktop_Test/input_manager.cpp +++ b/Desktop_Test/input_manager.cpp @@ -19,34 +19,9 @@ void InputManager::init(DISPLAY_STATE* display_state, TFT_Handler* tf) { }; Wire.begin(); - - for (int i = 0; i < NUM_BUTTONS; i++) { - pinMode(BUTTON_PINS[i], INPUT_PULLUP); - } } void InputManager::update() { - for (int i = 0; i < NUM_BUTTONS; i++) { - short int reading = digitalRead(BUTTON_PINS[i]); - - if (reading != lastButtonState[i]) { - lastDebounceTime[i] = millis(); - } - - if ((millis() - lastDebounceTime[i]) > DEBOUNCE_DELAY) { - if (reading != buttonState[i]) { - buttonState[i] = reading; - - if (buttonState[i] == LOW) { - handle_button_press(i); - } - } - } - - lastButtonState[i] = reading; - } - - Wire.requestFrom(CARDKB_ADDR, 1); if (Wire.available()) { char c = Wire.read(); @@ -59,7 +34,7 @@ void InputManager::update() { void InputManager::handle_keyboard_input(char key) { bool needs_redraw = true; - //Serial.printf("key: %x\n", key & 0xff); + Serial.printf("key: %x\n", key & 0xff); CLICK_EVENT event; switch(key) { @@ -218,7 +193,12 @@ void InputManager::handle_keyboard_input(char key) { event.character = key; event.event = CLICK_EVENTS::KEYBOARD; break; - + + case 0x20: // Space + event.character = key; + event.event = CLICK_EVENTS::KEYBOARD; + break; + case 0xB4: // Left arrow key (CardKB sends special codes) mi.x = (mi.x - 5 < 0) ? 0 : mi.x - 5; break; @@ -229,10 +209,12 @@ void InputManager::handle_keyboard_input(char key) { case 0xB5: // Up arrow key mi.y = (mi.y - 5 < 0) ? 0 : mi.y - 5; + event.event = CLICK_EVENTS::UP; break; case 0xB6: // Down arrow key mi.y = (mi.y + 5 > 316) ? 316 : mi.y + 5; + event.event = CLICK_EVENTS::DOWN; break; case 0xD: // Enter key @@ -252,57 +234,6 @@ void InputManager::handle_keyboard_input(char key) { } } -void InputManager::handle_button_press(short buttonIndex) { - bool needs_redraw = false; - - switch(buttonIndex) { - case 0: - mi.x = (mi.x + 5 > 476) ? 476 : mi.x + 5; - needs_redraw = true; - break; - case 1: - mi.y = (mi.y + 5 > 316) ? 316 : mi.y + 5; - needs_redraw = true; - break; - case 2: - mi.y = (mi.y - 5 < 0) ? 0 : mi.y - 5; - needs_redraw = true; - break; - case 3: - mi.x = (mi.x - 5 < 0) ? 0 : mi.x - 5; - needs_redraw = true; - break; - case 4: // Click - { - CLICK_EVENT event = { - .x = mi.x, - .y = mi.y, - .event = CLICK_EVENTS::LEFT_CLICK - }; - EventManager::getInstance().publish(event); - } - break; - case 5: // Right click - { - CLICK_EVENT event = { - .x = mi.x, - .y = mi.y, - .event = CLICK_EVENTS::RIGHT_CLICK - }; - EventManager::getInstance().publish(event); - } - break; - } - - if (needs_redraw) { - _display_state->update_display.store(true); - } -} - void InputManager::draw_button() { _tf->draw_box(mi.x, mi.y, mi.size_x, mi.size_y, mi.color); -} - -bool InputManager::are_buttons_pressed(short btn1, short btn2) { - return (buttonState[btn1] == LOW && buttonState[btn2] == LOW); } \ No newline at end of file diff --git a/Desktop_Test/input_manager.h b/Desktop_Test/input_manager.h index bc5c4cb..2b295e4 100644 --- a/Desktop_Test/input_manager.h +++ b/Desktop_Test/input_manager.h @@ -7,20 +7,11 @@ class InputManager { private: - short BUTTON_PINS[6] = {4, 5, 6, 7, 17, 16}; - static constexpr short NUM_BUTTONS = 6; - short lastButtonState[NUM_BUTTONS] = {HIGH, HIGH, HIGH, HIGH, HIGH, HIGH}; - short buttonState[NUM_BUTTONS] = {HIGH, HIGH, HIGH, HIGH, HIGH, HIGH}; - const unsigned long DEBOUNCE_DELAY = 25; // milliseconds - unsigned long lastDebounceTime[NUM_BUTTONS] = {0}; - - DISPLAY_STATE* _display_state; - TFT_Handler* _tf; Mouse_Icon mi; + TFT_Handler* _tf; + DISPLAY_STATE* _display_state; void handle_keyboard_input(char key); - void handle_button_press(short buttonIndex); - bool are_buttons_pressed(short btn1, short btn2); public: void init(DISPLAY_STATE* display_state, TFT_Handler* tf); diff --git a/Desktop_Test/program.h b/Desktop_Test/program.h index 890a265..c1237e0 100644 --- a/Desktop_Test/program.h +++ b/Desktop_Test/program.h @@ -5,7 +5,6 @@ #include #include #include -#include "tft_handler.h" #include "event_manager.h" // Forward declarations @@ -49,6 +48,40 @@ struct WindowDecoration { 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; @@ -71,6 +104,7 @@ struct ContentButton { struct Window { std::string title; + std::vector text_boxes; std::vector window_content_text; std::vector window_decorations; std::vector content_buttons; diff --git a/Desktop_Test/shell.cpp b/Desktop_Test/shell.cpp index 0f2d590..5653560 100644 --- a/Desktop_Test/shell.cpp +++ b/Desktop_Test/shell.cpp @@ -235,13 +235,8 @@ void Shell::draw_window(const Window& window) { // Window content tft->draw_box(window.x + 3, window.y + 35, window.width - 6, window.height - 38, COL_WHITE); - for (WindowContentText text : window.window_content_text) { - if (text.selected) { - tft->draw_text(text.x, text.y, text.text, COL_BLACK, text.size); - tft->draw_rect(text.x, text.y, text.width, text.height, 2, COL_BLACK); - } else { - tft->draw_text(text.x, text.y, text.text, COL_BLACK, text.size); - } + for (const auto& box : window.text_boxes) { + tft->draw_scrollable_textbox(box); } for (ContentButton button : window.content_buttons) { diff --git a/Desktop_Test/tft_handler.cpp b/Desktop_Test/tft_handler.cpp index 0382120..cf3b9d3 100644 --- a/Desktop_Test/tft_handler.cpp +++ b/Desktop_Test/tft_handler.cpp @@ -64,4 +64,29 @@ void TFT_Handler::get_text_bounds(const std::string& str, short size, short& wid sprite.setTextSize(size); width = sprite.textWidth(str.c_str()); height = sprite.fontHeight() * size; +} + +void TFT_Handler::draw_scrollable_textbox(const ScrollableTextBox& box) { + // Draw box background + draw_box(box.x, box.y, box.width, box.height, COL_WHITE); + + if (box.selected) { + draw_rect(box.x, box.y, box.width, box.height, 2, COL_BLACK); + } + + // Set clipping region to prevent text from drawing outside box + sprite.setClipRect(box.x, box.y, box.width, box.height); + + // Draw visible lines + for (const auto& line : box.lines) { + short render_y = box.y + line.local_y - box.scroll_offset; + + // Only render if line is visible within the box + if (render_y >= box.y - box.line_height && render_y <= box.y + box.height) { + draw_text(box.x + 5, render_y, line.text, COL_BLACK, box.text_size); + } + } + + // Clear clipping + sprite.clearClipRect(); } \ No newline at end of file diff --git a/Desktop_Test/tft_handler.h b/Desktop_Test/tft_handler.h index 9fb77bf..9c22fe6 100644 --- a/Desktop_Test/tft_handler.h +++ b/Desktop_Test/tft_handler.h @@ -1,6 +1,7 @@ #pragma once #include #include "GLOBALS.h" +#include "program.h" #include #define MAX_X 480 @@ -69,4 +70,5 @@ public: void fill_screen(short color); void push_sprite(); void get_text_bounds(const std::string& str, short size, short& width, short& height); + void draw_scrollable_textbox(const ScrollableTextBox& box); };