[FL-1756, FL-1769, FL-1776, FL-1759] Gui: input events complementary V3, refactoring. SubGhz: read/emulate fixes. Cleanup. (#684)
* Gui: move rotation logic to ViewPort, replace delayed View switch in ViewDispatcher with event filtering and redirection to previous view. * SubGhz: add function description * Gui, Input: add event id to input events. * SubGhz: fix "crashing on ?" * SubGhz: add icon scanning * SubGhz: updated interface read scene, updated interface config scene * Assets: update subghz assets * SubGhz: replaced the picture in the read scene, changed the paths to additional files * SubGhz: fix deadlock in timer callback * SubGhz: fix icon read scene * SubGhz: fix icon read scene * SubGhz: fix duble text transmitter scene * SubGhz: correct spelling. Gui: bigger queue for ViewDispatcher. * SubGhz: fix creation and transmission of dynamic code without the presence of a manufactory key * SubGhz: fix keelog, setting a name in the absence of a manufactory key * SubGhz: fix load bad keelog key * Format sources * Furi: remove garbage from core. GpioTester: fix memory leak and cleanup * Accessor: remove obsolete notification code * MusicPlayer: remove input event injection * Input: rename id to sequence Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
This commit is contained in:
@@ -309,12 +309,15 @@ void canvas_set_orientation(Canvas* canvas, CanvasOrientation orientation) {
|
||||
furi_assert(canvas);
|
||||
if(canvas->orientation != orientation) {
|
||||
canvas->orientation = orientation;
|
||||
if(canvas->orientation == CanvasOrientationHorizontal)
|
||||
if(canvas->orientation == CanvasOrientationHorizontal) {
|
||||
FURI_SWAP(canvas->width, canvas->height);
|
||||
u8g2_SetDisplayRotation(&canvas->fb, U8G2_R0);
|
||||
else if(canvas->orientation == CanvasOrientationVertical)
|
||||
} else if(canvas->orientation == CanvasOrientationVertical) {
|
||||
FURI_SWAP(canvas->width, canvas->height);
|
||||
u8g2_SetDisplayRotation(&canvas->fb, U8G2_R3);
|
||||
else
|
||||
} else {
|
||||
furi_assert(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,40 +1,5 @@
|
||||
#include "gui_i.h"
|
||||
|
||||
static void gui_rotate_buttons(InputEvent* event) {
|
||||
switch(event->key) {
|
||||
case InputKeyUp:
|
||||
event->key = InputKeyRight;
|
||||
break;
|
||||
case InputKeyDown:
|
||||
event->key = InputKeyLeft;
|
||||
break;
|
||||
case InputKeyRight:
|
||||
event->key = InputKeyDown;
|
||||
break;
|
||||
case InputKeyLeft:
|
||||
event->key = InputKeyUp;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void gui_setup_fs_orientation(const ViewPort* view_port, Canvas* canvas) {
|
||||
ViewPortOrientation view_port_orientation = view_port_get_orientation(view_port);
|
||||
CanvasOrientation canvas_orientation = canvas_get_orientation(canvas);
|
||||
if(view_port_orientation == ViewPortOrientationHorizontal) {
|
||||
canvas_frame_set(canvas, 0, 0, GUI_DISPLAY_WIDTH, GUI_DISPLAY_HEIGHT);
|
||||
if(canvas_orientation != CanvasOrientationHorizontal) {
|
||||
canvas_set_orientation(canvas, CanvasOrientationHorizontal);
|
||||
}
|
||||
} else if(view_port_orientation == ViewPortOrientationVertical) {
|
||||
canvas_frame_set(canvas, 0, 0, GUI_DISPLAY_HEIGHT, GUI_DISPLAY_WIDTH);
|
||||
if(canvas_orientation != CanvasOrientationVertical) {
|
||||
canvas_set_orientation(canvas, CanvasOrientationVertical);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ViewPort* gui_view_port_find_enabled(ViewPortArray_t array) {
|
||||
// Iterating backward
|
||||
ViewPortArray_it_t it;
|
||||
@@ -66,9 +31,10 @@ void gui_input_events_callback(const void* value, void* ctx) {
|
||||
|
||||
// Only Fullscreen supports vertical display for now
|
||||
bool gui_redraw_fs(Gui* gui) {
|
||||
canvas_set_orientation(gui->canvas, CanvasOrientationHorizontal);
|
||||
canvas_frame_set(gui->canvas, 0, 0, GUI_DISPLAY_WIDTH, GUI_DISPLAY_HEIGHT);
|
||||
ViewPort* view_port = gui_view_port_find_enabled(gui->layers[GuiLayerFullscreen]);
|
||||
if(view_port) {
|
||||
gui_setup_fs_orientation(view_port, gui->canvas);
|
||||
view_port_draw(view_port, gui->canvas);
|
||||
return true;
|
||||
} else {
|
||||
@@ -225,9 +191,10 @@ void gui_input(Gui* gui, InputEvent* input_event) {
|
||||
} else if(!(gui->ongoing_input & key_bit)) {
|
||||
FURI_LOG_W(
|
||||
"Gui",
|
||||
"non-complementary input, discarding key %s type %s",
|
||||
"non-complementary input, discarding key: %s type: %s, sequence: %p",
|
||||
input_get_key_name(input_event->key),
|
||||
input_get_type_name(input_event->type));
|
||||
input_get_type_name(input_event->type),
|
||||
input_event->sequence);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -241,21 +208,27 @@ void gui_input(Gui* gui, InputEvent* input_event) {
|
||||
gui->ongoing_input_view_port = view_port;
|
||||
}
|
||||
|
||||
if(view_port) {
|
||||
if(view_port == gui->ongoing_input_view_port) {
|
||||
if(view_port_get_orientation(view_port) == ViewPortOrientationVertical) {
|
||||
gui_rotate_buttons(input_event);
|
||||
}
|
||||
view_port_input(view_port, input_event);
|
||||
} else {
|
||||
FURI_LOG_W(
|
||||
"Gui",
|
||||
"ViewPort change while key press %x -> %x. Discarding key: %s, type: %s",
|
||||
gui->ongoing_input_view_port,
|
||||
view_port,
|
||||
input_get_key_name(input_event->key),
|
||||
input_get_type_name(input_event->type));
|
||||
}
|
||||
if(view_port && view_port == gui->ongoing_input_view_port) {
|
||||
view_port_input(view_port, input_event);
|
||||
} else if(gui->ongoing_input_view_port && input_event->type == InputTypeRelease) {
|
||||
FURI_LOG_W(
|
||||
"Gui",
|
||||
"ViewPort changed while key press %p -> %p. Sending key: %s, type: %s, sequence: %p to previous view port",
|
||||
gui->ongoing_input_view_port,
|
||||
view_port,
|
||||
input_get_key_name(input_event->key),
|
||||
input_get_type_name(input_event->type),
|
||||
input_event->sequence);
|
||||
view_port_input(gui->ongoing_input_view_port, input_event);
|
||||
} else {
|
||||
FURI_LOG_W(
|
||||
"Gui",
|
||||
"ViewPort changed while key press %p -> %p. Discarding key: %s, type: %s, sequence: %p",
|
||||
gui->ongoing_input_view_port,
|
||||
view_port,
|
||||
input_get_key_name(input_event->key),
|
||||
input_get_type_name(input_event->type),
|
||||
input_event->sequence);
|
||||
}
|
||||
|
||||
gui_unlock(gui);
|
||||
@@ -355,6 +328,10 @@ void gui_remove_view_port(Gui* gui, ViewPort* view_port) {
|
||||
}
|
||||
}
|
||||
|
||||
if(gui->ongoing_input_view_port == view_port) {
|
||||
gui->ongoing_input_view_port = NULL;
|
||||
}
|
||||
|
||||
gui_unlock(gui);
|
||||
}
|
||||
|
||||
|
@@ -37,7 +37,7 @@ void view_dispatcher_free(ViewDispatcher* view_dispatcher) {
|
||||
void view_dispatcher_enable_queue(ViewDispatcher* view_dispatcher) {
|
||||
furi_assert(view_dispatcher);
|
||||
furi_assert(view_dispatcher->queue == NULL);
|
||||
view_dispatcher->queue = osMessageQueueNew(8, sizeof(ViewDispatcherMessage), NULL);
|
||||
view_dispatcher->queue = osMessageQueueNew(16, sizeof(ViewDispatcherMessage), NULL);
|
||||
}
|
||||
|
||||
void view_dispatcher_set_event_callback_context(ViewDispatcher* view_dispatcher, void* context) {
|
||||
@@ -149,6 +149,10 @@ void view_dispatcher_remove_view(ViewDispatcher* view_dispatcher, uint32_t view_
|
||||
if(view_dispatcher->current_view == view) {
|
||||
view_dispatcher_set_current_view(view_dispatcher, NULL);
|
||||
}
|
||||
// Check if view is recieving input
|
||||
if(view_dispatcher->ongoing_input_view == view) {
|
||||
view_dispatcher->ongoing_input_view = NULL;
|
||||
}
|
||||
// Remove view
|
||||
ViewDict_erase(view_dispatcher->views, view_id);
|
||||
|
||||
@@ -169,12 +173,7 @@ void view_dispatcher_switch_to_view(ViewDispatcher* view_dispatcher, uint32_t vi
|
||||
} else {
|
||||
View** view_pp = ViewDict_get(view_dispatcher->views, view_id);
|
||||
furi_check(view_pp != NULL);
|
||||
if(view_dispatcher->ongoing_input) {
|
||||
view_dispatcher->delayed_next_view = *view_pp;
|
||||
} else {
|
||||
view_dispatcher->delayed_next_view = NULL;
|
||||
view_dispatcher_set_current_view(view_dispatcher, *view_pp);
|
||||
}
|
||||
view_dispatcher_set_current_view(view_dispatcher, *view_pp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -227,39 +226,52 @@ void view_dispatcher_handle_input(ViewDispatcher* view_dispatcher, InputEvent* e
|
||||
} else if(!(view_dispatcher->ongoing_input & key_bit)) {
|
||||
FURI_LOG_W(
|
||||
"ViewDispatcher",
|
||||
"non-complementary input, discarding key: %s, type: %s",
|
||||
"non-complementary input, discarding key: %s, type: %s, sequence: %p",
|
||||
input_get_key_name(event->key),
|
||||
input_get_type_name(event->type));
|
||||
input_get_type_name(event->type),
|
||||
event->sequence);
|
||||
return;
|
||||
}
|
||||
|
||||
bool is_consumed = false;
|
||||
if(view_dispatcher->current_view) {
|
||||
is_consumed = view_input(view_dispatcher->current_view, event);
|
||||
}
|
||||
if(!is_consumed && event->type == InputTypeShort) {
|
||||
// TODO remove view navigation handlers
|
||||
uint32_t view_id = VIEW_IGNORE;
|
||||
if(event->key == InputKeyBack) {
|
||||
view_id = view_previous(view_dispatcher->current_view);
|
||||
if((view_id == VIEW_IGNORE) && (view_dispatcher->navigation_event_callback)) {
|
||||
is_consumed =
|
||||
view_dispatcher->navigation_event_callback(view_dispatcher->event_context);
|
||||
if(!is_consumed) {
|
||||
view_dispatcher_stop(view_dispatcher);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!is_consumed) {
|
||||
view_dispatcher_switch_to_view(view_dispatcher, view_id);
|
||||
}
|
||||
// Set ongoing input view if this is event is first press event
|
||||
if(!(view_dispatcher->ongoing_input & ~key_bit) && event->type == InputTypePress) {
|
||||
view_dispatcher->ongoing_input_view = view_dispatcher->current_view;
|
||||
}
|
||||
|
||||
// Delayed view switch
|
||||
if(view_dispatcher->delayed_next_view && !(view_dispatcher->ongoing_input)) {
|
||||
view_dispatcher_set_current_view(view_dispatcher, view_dispatcher->delayed_next_view);
|
||||
view_dispatcher->delayed_next_view = NULL;
|
||||
// Deliver event
|
||||
if(view_dispatcher->ongoing_input_view == view_dispatcher->current_view) {
|
||||
bool is_consumed = false;
|
||||
if(view_dispatcher->current_view) {
|
||||
is_consumed = view_input(view_dispatcher->current_view, event);
|
||||
}
|
||||
if(!is_consumed && event->type == InputTypeShort) {
|
||||
// TODO remove view navigation handlers
|
||||
uint32_t view_id = VIEW_IGNORE;
|
||||
if(event->key == InputKeyBack) {
|
||||
view_id = view_previous(view_dispatcher->current_view);
|
||||
if((view_id == VIEW_IGNORE) && (view_dispatcher->navigation_event_callback)) {
|
||||
is_consumed =
|
||||
view_dispatcher->navigation_event_callback(view_dispatcher->event_context);
|
||||
if(!is_consumed) {
|
||||
view_dispatcher_stop(view_dispatcher);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!is_consumed) {
|
||||
view_dispatcher_switch_to_view(view_dispatcher, view_id);
|
||||
}
|
||||
}
|
||||
} else if(view_dispatcher->ongoing_input_view && event->type == InputTypeRelease) {
|
||||
FURI_LOG_W(
|
||||
"ViewDispatcher",
|
||||
"View changed while key press %p -> %p. Sending key: %s, type: %s, sequence: %p to previous view port",
|
||||
view_dispatcher->ongoing_input_view,
|
||||
view_dispatcher->current_view,
|
||||
input_get_key_name(event->key),
|
||||
input_get_type_name(event->type),
|
||||
event->sequence);
|
||||
view_input(view_dispatcher->ongoing_input_view, event);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -17,7 +17,7 @@ struct ViewDispatcher {
|
||||
|
||||
View* current_view;
|
||||
|
||||
View* delayed_next_view;
|
||||
View* ongoing_input_view;
|
||||
uint8_t ongoing_input;
|
||||
|
||||
ViewDispatcherCustomEventCallback custom_event_callback;
|
||||
|
@@ -7,6 +7,33 @@
|
||||
|
||||
// TODO add mutex to view_port ops
|
||||
|
||||
static void view_port_rotate_buttons(InputEvent* event) {
|
||||
switch(event->key) {
|
||||
case InputKeyUp:
|
||||
event->key = InputKeyRight;
|
||||
break;
|
||||
case InputKeyDown:
|
||||
event->key = InputKeyLeft;
|
||||
break;
|
||||
case InputKeyRight:
|
||||
event->key = InputKeyDown;
|
||||
break;
|
||||
case InputKeyLeft:
|
||||
event->key = InputKeyUp;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void view_port_setup_canvas_orientation(const ViewPort* view_port, Canvas* canvas) {
|
||||
if(view_port->orientation == ViewPortOrientationHorizontal) {
|
||||
canvas_set_orientation(canvas, CanvasOrientationHorizontal);
|
||||
} else if(view_port->orientation == ViewPortOrientationVertical) {
|
||||
canvas_set_orientation(canvas, CanvasOrientationVertical);
|
||||
}
|
||||
}
|
||||
|
||||
ViewPort* view_port_alloc() {
|
||||
ViewPort* view_port = furi_alloc(sizeof(ViewPort));
|
||||
view_port->orientation = ViewPortOrientationHorizontal;
|
||||
@@ -84,6 +111,7 @@ void view_port_draw(ViewPort* view_port, Canvas* canvas) {
|
||||
furi_check(view_port->gui);
|
||||
|
||||
if(view_port->draw_callback) {
|
||||
view_port_setup_canvas_orientation(view_port, canvas);
|
||||
view_port->draw_callback(canvas, view_port->draw_callback_context);
|
||||
}
|
||||
}
|
||||
@@ -94,6 +122,9 @@ void view_port_input(ViewPort* view_port, InputEvent* event) {
|
||||
furi_check(view_port->gui);
|
||||
|
||||
if(view_port->input_callback) {
|
||||
if(view_port_get_orientation(view_port) == ViewPortOrientationVertical) {
|
||||
view_port_rotate_buttons(event);
|
||||
}
|
||||
view_port->input_callback(event, view_port->input_callback_context);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user