Removed unused code
This commit is contained in:
parent
44a4c2ceba
commit
15c7523f21
@ -19,6 +19,8 @@ enum CLICK_EVENTS : uint8_t {
|
||||
RIGHT_CLICK = 2,
|
||||
ENTER = 3,
|
||||
KEYBOARD = 4,
|
||||
UP = 5,
|
||||
DOWN = 6,
|
||||
};
|
||||
|
||||
struct CLICK_EVENT {
|
||||
|
||||
@ -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;
|
||||
}
|
||||
} else if (event.event == CLICK_EVENTS::LEFT_CLICK || event.event == CLICK_EVENTS::ENTER) {
|
||||
if (text.selected) text.selected = false;
|
||||
}
|
||||
for (size_t i = 0; i < _window->text_boxes.size(); i++) {
|
||||
auto& box = _window->text_boxes[i];
|
||||
|
||||
if (text.selected && event.event == CLICK_EVENTS::KEYBOARD) {
|
||||
if ((text.x + text.width) >= (_window->x + _window->width)) {
|
||||
text.text += "\n";
|
||||
Serial.println("Aight");
|
||||
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);
|
||||
}
|
||||
text.text += event.character;
|
||||
_tft->get_text_bounds(text.text, text.size, text.width, text.height);
|
||||
} else {
|
||||
if (event.event == CLICK_EVENTS::LEFT_CLICK) for (auto& b : _window->text_boxes) b.selected = false;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
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));
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
#include "helpers.h"
|
||||
#include "program.h"
|
||||
#include "tft_handler.h"
|
||||
|
||||
void Helpers::recalculate_taskbar(std::vector<TaskBarItem>& task_bar_items) {
|
||||
for (short i = 0; i < task_bar_items.size(); ++i) {
|
||||
@ -10,3 +12,49 @@ void Helpers::recalculate_taskbar(std::vector<TaskBarItem>& task_bar_items) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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});
|
||||
}
|
||||
}
|
||||
@ -6,3 +6,4 @@
|
||||
struct Helpers {
|
||||
static void recalculate_taskbar(std::vector<TaskBarItem>& task_bar_items);
|
||||
};
|
||||
|
||||
|
||||
@ -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) {
|
||||
@ -219,6 +194,11 @@ void InputManager::handle_keyboard_input(char 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);
|
||||
}
|
||||
@ -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);
|
||||
|
||||
@ -5,7 +5,6 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <LovyanGFX.hpp>
|
||||
#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<TextLine> 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<ScrollableTextBox> text_boxes;
|
||||
std::vector<WindowContentText> window_content_text;
|
||||
std::vector<WindowDecoration> window_decorations;
|
||||
std::vector<ContentButton> content_buttons;
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -65,3 +65,28 @@ void TFT_Handler::get_text_bounds(const std::string& str, short size, short& wid
|
||||
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();
|
||||
}
|
||||
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
#include <LovyanGFX.hpp>
|
||||
#include "GLOBALS.h"
|
||||
#include "program.h"
|
||||
#include <string>
|
||||
|
||||
#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);
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user