Modified Text Editor to handle long presses. (#2698)

This commit is contained in:
Netro 2025-06-19 01:21:54 -04:00 committed by GitHub
parent fa4b74fd6f
commit b456c18008
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 124 additions and 25 deletions

View file

@ -319,7 +319,8 @@ void BLETxView::on_tx_progress(const bool done) {
BLETxView::BLETxView(NavigationView& nav) BLETxView::BLETxView(NavigationView& nav)
: nav_{nav} { : nav_{nav} {
add_children({&button_open, add_children({&dataEditView,
&button_open,
&text_filename, &text_filename,
&progressbar, &progressbar,
&check_rand_mac, &check_rand_mac,
@ -340,7 +341,6 @@ BLETxView::BLETxView(NavigationView& nav)
&label_mac_address, &label_mac_address,
&text_mac_address, &text_mac_address,
&label_data_packet, &label_data_packet,
&dataEditView,
&button_clear_marked, &button_clear_marked,
&button_save_packet, &button_save_packet,
&button_switch}); &button_switch});
@ -430,6 +430,23 @@ BLETxView::BLETxView(NavigationView& nav)
} }
}; };
dataEditView.on_change = [this](uint8_t value) {
// Reject setting newline at index 29.
if (cursor_pos.col != 29) {
uint16_t dataBytePos = (cursor_pos.line * 29) + cursor_pos.col;
packets[current_packet].advertisementData[dataBytePos] = uint_to_char(value, 16);
update_current_packet(packets[current_packet], current_packet);
}
};
dataEditView.on_cursor_moved = [this]() {
// Save last selected cursor.
cursor_pos.line = dataEditView.line();
cursor_pos.col = dataEditView.col();
};
button_clear_marked.on_select = [this](Button&) { button_clear_marked.on_select = [this](Button&) {
marked_counter = 0; marked_counter = 0;
markedBytes.clear(); markedBytes.clear();
@ -531,7 +548,6 @@ void BLETxView::update_current_packet(BLETxPacket packet, uint32_t currentIndex)
for (const std::string& str : strings) { for (const std::string& str : strings) {
dataFile.write(str.c_str(), str.size()); dataFile.write(str.c_str(), str.size());
dataFile.write("\n", 1); dataFile.write("\n", 1);
;
} }
dataFile.~File(); dataFile.~File();
@ -546,6 +562,7 @@ void BLETxView::update_current_packet(BLETxPacket packet, uint32_t currentIndex)
dataEditView.set_font_zoom(true); dataEditView.set_font_zoom(true);
dataEditView.set_file(*dataFileWrapper); dataEditView.set_file(*dataFileWrapper);
dataEditView.redraw(true, true); dataEditView.redraw(true, true);
dataEditView.cursor_set(cursor_pos.line, cursor_pos.col);
} }
void BLETxView::set_parent_rect(const Rect new_parent_rect) { void BLETxView::set_parent_rect(const Rect new_parent_rect) {

View file

@ -287,9 +287,6 @@ class BLETxView : public View {
Labels label_data_packet{ Labels label_data_packet{
{{0 * 8, 9 * 16}, "Packet Data:", Theme::getInstance()->fg_light->foreground}}; {{0 * 8, 9 * 16}, "Packet Data:", Theme::getInstance()->fg_light->foreground}};
Console console{
{0, 9 * 18, screen_width, screen_height - 80}};
TextViewer dataEditView{ TextViewer dataEditView{
{0, 9 * 18, screen_width, screen_height - 80}}; {0, 9 * 18, screen_width, screen_height - 80}};

View file

@ -26,6 +26,7 @@
#include "log_file.hpp" #include "log_file.hpp"
#include "string_format.hpp" #include "string_format.hpp"
#include "irq_controls.hpp"
using namespace portapack; using namespace portapack;
namespace fs = std::filesystem; namespace fs = std::filesystem;
@ -81,21 +82,75 @@ void TextViewer::paint(Painter& painter) {
paint_cursor(painter); paint_cursor(painter);
} }
void TextViewer::enable_long_press() {
// Enable long press on "Select".
SwitchesState config;
config[toUType(Switch::Sel)] = true;
set_switches_long_press_config(config);
}
void TextViewer::on_focus() {
enable_long_press();
}
bool TextViewer::on_key(const KeyEvent key) { bool TextViewer::on_key(const KeyEvent key) {
int16_t delta_col = 0; int16_t delta_col = 0;
int16_t delta_line = 0; int16_t delta_line = 0;
if (key == KeyEvent::Left) if (key == KeyEvent::Select) {
delta_col = -1; // Toggle 'digit' mode with long-press.
else if (key == KeyEvent::Right) if (digit_mode_ || key_is_long_pressed(key)) {
delta_col = 1; digit_mode_ = !digit_mode_;
else if (key == KeyEvent::Up) set_dirty();
delta_line = -1; return true;
else if (key == KeyEvent::Down) }
delta_line = 1; }
else if (key == KeyEvent::Select && on_select) {
on_select(); if (digit_mode_) {
return true; switch (key) {
case KeyEvent::Left:
delta_col = -1;
break;
case KeyEvent::Right:
delta_col = 1;
break;
case KeyEvent::Up:
set_value(value_ == 0x0F ? 0x00 : value_ + 1);
break;
case KeyEvent::Down:
set_value(value_ == 0x00 ? 0x0F : value_ - 1);
break;
default:
return false;
}
if (delta_col == 0 && delta_line == 0) {
return true;
}
} else {
switch (key) {
case KeyEvent::Left:
delta_col = -1;
break;
case KeyEvent::Right:
delta_col = 1;
break;
case KeyEvent::Up:
delta_line = -1;
break;
case KeyEvent::Down:
delta_line = 1;
break;
case KeyEvent::Select: {
if (on_select) {
on_select();
return true;
}
break;
}
default:
return false;
}
} }
// Always allow cursor direction to be updated. // Always allow cursor direction to be updated.
@ -111,19 +166,42 @@ bool TextViewer::on_key(const KeyEvent key) {
bool TextViewer::on_encoder(EncoderEvent delta) { bool TextViewer::on_encoder(EncoderEvent delta) {
bool updated = false; bool updated = false;
if (cursor_.dir == ScrollDirection::Horizontal) if (digit_mode_) {
updated = apply_scrolling_constraints(0, delta); if (delta > 0) {
else { set_value(value_ == 0x0F ? 0x00 : value_ + 1);
delta *= 16; } else if (delta < 0) {
updated = apply_scrolling_constraints(delta, 0); set_value(value_ == 0x00 ? 0x0F : value_ - 1);
}
updated = true;
} else {
if (cursor_.dir == ScrollDirection::Horizontal) {
updated = apply_scrolling_constraints(0, delta);
} else {
delta *= 16;
updated = apply_scrolling_constraints(delta, 0);
}
if (updated) {
redraw();
}
} }
if (updated)
redraw();
return updated; return updated;
} }
void TextViewer::set_value(uint8_t new_value) {
if (new_value != value_) {
value_ = new_value;
if (on_change) {
on_change(value_);
}
set_dirty();
}
}
void TextViewer::redraw(bool redraw_text, bool redraw_marked) { void TextViewer::redraw(bool redraw_text, bool redraw_marked) {
paint_state_.redraw_text = redraw_text; paint_state_.redraw_text = redraw_text;
paint_state_.redraw_marked = redraw_marked; paint_state_.redraw_marked = redraw_marked;

View file

@ -54,10 +54,13 @@ class TextViewer : public Widget {
std::function<void()> on_select{}; std::function<void()> on_select{};
std::function<void()> on_cursor_moved{}; std::function<void()> on_cursor_moved{};
std::function<void(uint8_t)> on_change{};
void paint(Painter& painter) override; void paint(Painter& painter) override;
bool on_key(KeyEvent key) override; bool on_key(KeyEvent key) override;
bool on_encoder(EncoderEvent delta) override; bool on_encoder(EncoderEvent delta) override;
void set_value(uint8_t new_value);
void on_focus() override;
void redraw(bool redraw_text = false, bool redraw_marked = false); void redraw(bool redraw_text = false, bool redraw_marked = false);
@ -74,6 +77,7 @@ class TextViewer : public Widget {
void cursor_set(uint16_t line, uint16_t col); void cursor_set(uint16_t line, uint16_t col);
void cursor_mark_selected(); void cursor_mark_selected();
void cursor_clear_marked(); void cursor_clear_marked();
void enable_long_press();
typedef std::pair<uint16_t, uint16_t> LineColPair; typedef std::pair<uint16_t, uint16_t> LineColPair;
std::vector<LineColPair> lineColPair{}; std::vector<LineColPair> lineColPair{};
@ -95,6 +99,9 @@ class TextViewer : public Widget {
int8_t char_height{}; int8_t char_height{};
uint8_t max_line{}; uint8_t max_line{};
uint8_t max_col{}; uint8_t max_col{};
bool digit_mode_{false};
uint8_t value_{0};
bool allow_digit_mode_{true};
/* Returns true if the cursor was updated. */ /* Returns true if the cursor was updated. */
bool apply_scrolling_constraints( bool apply_scrolling_constraints(