Skip to content

Commit

Permalink
Send ASCII chars from USB serial to selected widget (#1708)
Browse files Browse the repository at this point in the history
* Initial commit for keyboard emulation
* Added on_keyboard to some widgets
* TextEdit partly
* Multi key send at once
* Frequency control support
* Fix encoder emulation
* Add keyboard to geomap
* More widgets
  • Loading branch information
htotoo committed Jan 4, 2024
1 parent 1b5125b commit 8761b9d
Show file tree
Hide file tree
Showing 15 changed files with 232 additions and 5 deletions.
12 changes: 12 additions & 0 deletions firmware/application/event_m0.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,18 @@ void EventDispatcher::emulateTouch(ui::TouchEvent event) {
on_touch_event(event);
}

void EventDispatcher::emulateKeyboard(ui::KeyboardEvent event) {
on_keyboard_event(event);
}

void EventDispatcher::on_keyboard_event(ui::KeyboardEvent event) {
// send the key to focused widget, or parent if not accepts it
auto target = context.focus_manager().focus_widget();
while ((target != nullptr) && !target->on_keyboard(event)) {
target = target->parent();
}
}

void EventDispatcher::on_touch_event(ui::TouchEvent event) {
/* TODO: Capture widget receiving the Start event, send Move and
* End events to the same widget.
Expand Down
2 changes: 2 additions & 0 deletions firmware/application/event_m0.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ class EventDispatcher {
}

void emulateTouch(ui::TouchEvent event);
void emulateKeyboard(ui::KeyboardEvent event);

private:
static Thread* thread_event_loop;
Expand All @@ -113,6 +114,7 @@ class EventDispatcher {
ui::Widget* captured_widget{nullptr};

void on_touch_event(ui::TouchEvent event);
void on_keyboard_event(ui::KeyboardEvent event);

// void blink_timer();
void handle_lcd_frame_sync();
Expand Down
9 changes: 5 additions & 4 deletions firmware/application/irq_controls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,12 +171,13 @@ static bool encoder_update(const uint8_t raw) {
}

static bool encoder_read() {
const auto delta = encoder.update(
encoder_debounce[0].state() | (injected_encoder == 1),
encoder_debounce[1].state() | (injected_encoder == 2));
auto delta = encoder.update(encoder_debounce[0].state(), encoder_debounce[1].state());

if (injected_encoder > 0)
if (injected_encoder > 0) {
if (injected_encoder == 1) delta = -1;
if (injected_encoder == 2) delta = 1;
injected_encoder = 0;
}

if (delta != 0) {
encoder_position += delta;
Expand Down
22 changes: 22 additions & 0 deletions firmware/application/ui/ui_freqlist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,28 @@ void FreqManUIList::on_blur() {
set_dirty();
}

bool FreqManUIList::on_keyboard(const KeyboardEvent key) {
if (!db_ || db_->empty())
return false;

auto delta = 0;
if (key == '-' && get_index() > 0) delta = -1;
if (key == '+' && get_index() < db_->entry_count() - 1) delta = 1;
if (delta != 0) {
adjust_selected_index(delta);
set_dirty();
return true;
}
if (key == 10) {
if (on_select) {
on_select(get_index());
return true;
}
}

return false;
}

bool FreqManUIList::on_key(const KeyEvent key) {
if (!db_ || db_->empty())
return false;
Expand Down
2 changes: 2 additions & 0 deletions firmware/application/ui/ui_freqlist.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ class FreqManUIList : public Widget {
void on_blur() override;
bool on_key(const KeyEvent key) override;
bool on_encoder(EncoderEvent delta) override;
bool on_keyboard(const KeyboardEvent event) override;

void set_parent_rect(Rect new_parent_rect) override;

void set_index(size_t index);
Expand Down
7 changes: 7 additions & 0 deletions firmware/application/ui/ui_geomap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,13 @@ void GeoMap::paint(Painter& painter) {
}
}

bool GeoMap::on_keyboard(KeyboardEvent key) {
if (key == '+' || key == ' ') return on_encoder(1);
if (key == '-') return on_encoder(-1);

return false;
}

bool GeoMap::on_touch(const TouchEvent event) {
if ((event.type == TouchEvent::Type::Start) && (mode_ == PROMPT)) {
set_highlighted(true);
Expand Down
1 change: 1 addition & 0 deletions firmware/application/ui/ui_geomap.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ class GeoMap : public Widget {

bool on_touch(const TouchEvent event) override;
bool on_encoder(const EncoderEvent delta) override;
bool on_keyboard(const KeyboardEvent event) override;

bool init();
void set_mode(GeoMapMode mode);
Expand Down
13 changes: 13 additions & 0 deletions firmware/application/ui/ui_menu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,19 @@ bool MenuView::on_key(const KeyEvent key) {
}
}

bool MenuView::on_keyboard(const KeyboardEvent key) {
if (key == '-') return set_highlighted(highlighted_item - 1);
if (key == '+') return set_highlighted(highlighted_item + 1);
if (key == 10) {
if (menu_items[highlighted_item].on_select) {
menu_items[highlighted_item].on_select(KeyEvent::Right);
}
return true;
}

return false;
}

bool MenuView::on_encoder(const EncoderEvent event) {
set_highlighted(highlighted_item + event);
return true;
Expand Down
1 change: 1 addition & 0 deletions firmware/application/ui/ui_menu.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ class MenuView : public View {
void on_blur() override;
bool on_key(const KeyEvent event) override;
bool on_encoder(const EncoderEvent event) override;
bool on_keyboard(const KeyboardEvent event) override;

private:
void update_items();
Expand Down
27 changes: 26 additions & 1 deletion firmware/application/ui/ui_receiver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,12 +165,18 @@ bool FrequencyField::on_key(KeyEvent event) {
return false;
}

bool FrequencyField::on_keyboard(KeyboardEvent key) {
if (key == '+' || key == ' ') return on_encoder(1);
if (key == '-') return on_encoder(-1);

return false;
}

bool FrequencyField::on_encoder(const EncoderEvent delta) {
if (digit_mode_)
set_value(value_ + (delta * digit_step()));
else
set_value(value_ + (delta * step_));

return true;
}

Expand Down Expand Up @@ -321,6 +327,25 @@ void FrequencyKeypadView::on_button(Button& button) {
update_text();
}

bool FrequencyKeypadView::on_keyboard(const KeyboardEvent key) {
if (key == 8) {
digit_delete();
update_text();
return true;
}
if (key >= '0' && key <= '9') {
digit_add(key);
update_text();
return true;
}
if (key == '.') {
field_toggle();
update_text();
return true;
}
return false;
}

void FrequencyKeypadView::digit_add(const char c) {
if (state == State::DigitMHz) {
if (clear_field_if_digits_entered) {
Expand Down
2 changes: 2 additions & 0 deletions firmware/application/ui/ui_receiver.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class FrequencyField : public Widget {

bool on_key(KeyEvent event) override;
bool on_encoder(EncoderEvent delta) override;
bool on_keyboard(KeyboardEvent key) override;
bool on_touch(TouchEvent event) override;
void on_focus() override;
void on_blur() override;
Expand Down Expand Up @@ -202,6 +203,7 @@ class FrequencyKeypadView : public View {
rf::Frequency value() const;
void set_value(const rf::Frequency new_value);
bool on_encoder(const EncoderEvent delta) override;
bool on_keyboard(const KeyboardEvent key) override;

private:
int16_t focused_button = 0;
Expand Down
39 changes: 39 additions & 0 deletions firmware/application/usb_serial_shell.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,44 @@ static void cmd_touch(BaseSequentialStream* chp, int argc, char* argv[]) {
chprintf(chp, "ok\r\n");
}

// send ascii keys in 2 char hex representation. Can send multiple keys at once like: keyboard 414243 (this will be ABC)
static void cmd_keyboard(BaseSequentialStream* chp, int argc, char* argv[]) {
if (argc != 1) {
chprintf(chp, "usage: keyboard XX\r\n");
return;
}

auto evtd = getEventDispatcherInstance();
if (evtd == NULL) {
chprintf(chp, "error\r\n");
}

size_t data_string_len = strlen(argv[0]);
if (data_string_len % 2 != 0) {
chprintf(chp, "usage: keyboard XXXX\r\n");
return;
}

for (size_t i = 0; i < data_string_len; i++) {
char c = argv[0][i];
if ((c < '0' || c > '9') && (c < 'A' || c > 'F')) {
chprintf(chp, "usage: keyboard XX\r\n");
return;
}
}

char buffer[3] = {0, 0, 0};

for (size_t i = 0; i < data_string_len / 2; i++) {
buffer[0] = argv[0][i * 2];
buffer[1] = argv[0][i * 2 + 1];
uint8_t chr = (uint8_t)strtol(buffer, NULL, 16);
evtd->emulateKeyboard(chr);
}

chprintf(chp, "ok\r\n");
}

static void cmd_sd_list_dir(BaseSequentialStream* chp, int argc, char* argv[]) {
if (argc != 1) {
chprintf(chp, "usage: ls /\r\n");
Expand Down Expand Up @@ -866,6 +904,7 @@ static const ShellCommand commands[] = {
{"read_memory", cmd_read_memory},
{"button", cmd_button},
{"touch", cmd_touch},
{"keyboard", cmd_keyboard},
{"ls", cmd_sd_list_dir},
{"rm", cmd_sd_delete},
{"open", cmd_sd_open},
Expand Down
1 change: 1 addition & 0 deletions firmware/common/ui.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,7 @@ enum class KeyEvent : uint8_t {
};

using EncoderEvent = int32_t;
using KeyboardEvent = uint8_t;

struct TouchEvent {
enum class Type : uint32_t {
Expand Down

0 comments on commit 8761b9d

Please sign in to comment.