[FL-1755, FL-1756] added LL_DeInit timers, removed Analyze scene, redesigned astomatic frequency change mechanism, updated subghz read scene interface (#677)
* SubGhz: Fix Timer hopping * SubGhz: add display of received packages and their maximum number. redesigned interface, the maximum number of received packages increased to 50 * SubGhz: add clearing history on exit read scene, jump after saving the key into the history of received signals * SubGhz: Fix honoring the width of the icon for transmitter scene * RFID: Fix [FL-1755] freeze after key emulation * SubGhz: drop analyze scene and views * SubGhz: fix save scene * Input, GUI: new event delivery scheme that groups event for complementarity. * Gui: update View Dispatcher documentation * Gui: remove dead code, wait till all input events are delivered in ViewDispatcher in queue mode. * Gui: update comment in ViewDispatcher * FuriHal: fix incorrect clock disable invocation * FuriHal: proper include * SubGhz: properly reset history in receiver view * Gui: correct view switch order and non-complementary events discarding Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
This commit is contained in:
@@ -35,11 +35,6 @@ void view_set_previous_callback(View* view, ViewNavigationCallback callback) {
|
||||
view->previous_callback = callback;
|
||||
}
|
||||
|
||||
void view_set_next_callback(View* view, ViewNavigationCallback callback) {
|
||||
furi_assert(view);
|
||||
view->next_callback = callback;
|
||||
}
|
||||
|
||||
void view_set_enter_callback(View* view, ViewCallback callback) {
|
||||
furi_assert(view);
|
||||
view->enter_callback = callback;
|
||||
@@ -169,15 +164,6 @@ uint32_t view_previous(View* view) {
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t view_next(View* view) {
|
||||
furi_assert(view);
|
||||
if(view->next_callback) {
|
||||
return view->next_callback(view->context);
|
||||
} else {
|
||||
return VIEW_IGNORE;
|
||||
}
|
||||
}
|
||||
|
||||
void view_enter(View* view) {
|
||||
furi_assert(view);
|
||||
if(view->enter_callback) view->enter_callback(view->context);
|
||||
|
@@ -14,11 +14,6 @@ extern "C" {
|
||||
#define VIEW_NONE 0xFFFFFFFF
|
||||
/* Ignore navigation event */
|
||||
#define VIEW_IGNORE 0xFFFFFFFE
|
||||
/* Deatch from gui, deallocate Views and ViewDispatcher
|
||||
* BE SUPER CAREFUL, deallocation happens automatically on GUI thread
|
||||
* You ARE NOT owning ViewDispatcher and Views instances
|
||||
*/
|
||||
#define VIEW_DESTROY 0xFFFFFFFA
|
||||
|
||||
typedef enum {
|
||||
ViewOrientationHorizontal,
|
||||
@@ -119,12 +114,6 @@ void view_set_custom_callback(View* view, ViewCustomCallback callback);
|
||||
*/
|
||||
void view_set_previous_callback(View* view, ViewNavigationCallback callback);
|
||||
|
||||
/* Set Navigation Next callback
|
||||
* @param view, pointer to View
|
||||
* @param callback, input callback
|
||||
*/
|
||||
void view_set_next_callback(View* view, ViewNavigationCallback callback);
|
||||
|
||||
/* Set Enter callback
|
||||
* @param view, pointer to View
|
||||
* @param callback, callback
|
||||
|
39
applications/gui/view_dispatcher.c
Executable file → Normal file
39
applications/gui/view_dispatcher.c
Executable file → Normal file
@@ -91,6 +91,18 @@ void view_dispatcher_run(ViewDispatcher* view_dispatcher) {
|
||||
view_dispatcher_handle_custom_event(view_dispatcher, message.custom_event);
|
||||
}
|
||||
}
|
||||
|
||||
// Wait till all input events delivered
|
||||
while(view_dispatcher->ongoing_input_events_count > 0) {
|
||||
osMessageQueueGet(view_dispatcher->queue, &message, NULL, osWaitForever);
|
||||
if(message.type == ViewDispatcherMessageTypeInput) {
|
||||
if(message.input.type == InputTypePress) {
|
||||
view_dispatcher->ongoing_input_events_count++;
|
||||
} else if(message.input.type == InputTypeRelease) {
|
||||
view_dispatcher->ongoing_input_events_count--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void view_dispatcher_stop(ViewDispatcher* view_dispatcher) {
|
||||
@@ -153,12 +165,15 @@ void view_dispatcher_switch_to_view(ViewDispatcher* view_dispatcher, uint32_t vi
|
||||
if(view_id == VIEW_NONE) {
|
||||
view_dispatcher_set_current_view(view_dispatcher, NULL);
|
||||
} else if(view_id == VIEW_IGNORE) {
|
||||
} else if(view_id == VIEW_DESTROY) {
|
||||
view_dispatcher_free(view_dispatcher);
|
||||
} else {
|
||||
View** view_pp = ViewDict_get(view_dispatcher->views, view_id);
|
||||
furi_check(view_pp != NULL);
|
||||
view_dispatcher_set_current_view(view_dispatcher, *view_pp);
|
||||
if(view_dispatcher->ongoing_input_events_count > 0) {
|
||||
view_dispatcher->delayed_next_view = *view_pp;
|
||||
} else {
|
||||
view_dispatcher->delayed_next_view = NULL;
|
||||
view_dispatcher_set_current_view(view_dispatcher, *view_pp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,6 +217,16 @@ void view_dispatcher_input_callback(InputEvent* event, void* context) {
|
||||
}
|
||||
|
||||
void view_dispatcher_handle_input(ViewDispatcher* view_dispatcher, InputEvent* event) {
|
||||
// Ongoing input events counting
|
||||
if(event->type == InputTypeRelease && view_dispatcher->ongoing_input_events_count > 0) {
|
||||
view_dispatcher->ongoing_input_events_count--;
|
||||
} else if(event->type == InputTypePress) {
|
||||
view_dispatcher->ongoing_input_events_count++;
|
||||
} else if(view_dispatcher->ongoing_input_events_count == 0) {
|
||||
FURI_LOG_E("ViewDispatcher", "non-complementary input, discarding");
|
||||
return;
|
||||
}
|
||||
|
||||
bool is_consumed = false;
|
||||
if(view_dispatcher->current_view) {
|
||||
is_consumed = view_input(view_dispatcher->current_view, event);
|
||||
@@ -219,13 +244,17 @@ void view_dispatcher_handle_input(ViewDispatcher* view_dispatcher, InputEvent* e
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else if(event->key == InputKeyOk) {
|
||||
view_id = view_next(view_dispatcher->current_view);
|
||||
}
|
||||
if(!is_consumed) {
|
||||
view_dispatcher_switch_to_view(view_dispatcher, view_id);
|
||||
}
|
||||
}
|
||||
|
||||
// Delayed view switch
|
||||
if(view_dispatcher->delayed_next_view && view_dispatcher->ongoing_input_events_count == 0) {
|
||||
view_dispatcher_set_current_view(view_dispatcher, view_dispatcher->delayed_next_view);
|
||||
view_dispatcher->delayed_next_view = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void view_dispatcher_handle_tick_event(ViewDispatcher* view_dispatcher) {
|
||||
|
@@ -113,6 +113,7 @@ void view_dispatcher_remove_view(ViewDispatcher* view_dispatcher, uint32_t view_
|
||||
/** Switch to View
|
||||
* @param view_dispatcher ViewDispatcher instance
|
||||
* @param view_id View id to register
|
||||
* @warning switching may be delayed till input events complementarity reached
|
||||
*/
|
||||
void view_dispatcher_switch_to_view(ViewDispatcher* view_dispatcher, uint32_t view_id);
|
||||
|
||||
|
@@ -14,7 +14,12 @@ struct ViewDispatcher {
|
||||
Gui* gui;
|
||||
ViewPort* view_port;
|
||||
ViewDict_t views;
|
||||
|
||||
View* current_view;
|
||||
|
||||
View* delayed_next_view;
|
||||
uint8_t ongoing_input_events_count;
|
||||
|
||||
ViewDispatcherCustomEventCallback custom_event_callback;
|
||||
ViewDispatcherNavigationEventCallback navigation_event_callback;
|
||||
ViewDispatcherTickEventCallback tick_event_callback;
|
||||
|
@@ -15,7 +15,6 @@ struct View {
|
||||
|
||||
ViewModelType model_type;
|
||||
ViewNavigationCallback previous_callback;
|
||||
ViewNavigationCallback next_callback;
|
||||
ViewCallback enter_callback;
|
||||
ViewCallback exit_callback;
|
||||
ViewOrientation orientation;
|
||||
@@ -42,9 +41,6 @@ bool view_custom(View* view, uint32_t event);
|
||||
/* Previous Callback for View dispatcher */
|
||||
uint32_t view_previous(View* view);
|
||||
|
||||
/* Next Callback for View dispatcher */
|
||||
uint32_t view_next(View* view);
|
||||
|
||||
/* Enter Callback for View dispatcher */
|
||||
void view_enter(View* view);
|
||||
|
||||
|
Reference in New Issue
Block a user