Subghz app example (#365)
* Gui: ported submenu and view_dispatcher_remove_view from iButton branch * App gui-test: use backported submenu api * App subghz: initial commit * App subghz: syntax fix * App gui-test: fix submenu callback * App subghz: add subfolders to build * Gui view: c++ verison of with_view_model * Subghz app: simple spectrum settings view * Subghz app: add spectrum settings view to view manager * Subghz app: spectrum settings scene Co-authored-by: coreglitch <mail@s3f.ru>
This commit is contained in:
		
							parent
							
								
									025b77ecc1
								
							
						
					
					
						commit
						7afdd14a4c
					
				| @ -31,6 +31,7 @@ int32_t music_player(void* p); | |||||||
| int32_t sdnfc(void* p); | int32_t sdnfc(void* p); | ||||||
| int32_t floopper_bloopper(void* p); | int32_t floopper_bloopper(void* p); | ||||||
| int32_t sd_filesystem(void* p); | int32_t sd_filesystem(void* p); | ||||||
|  | int32_t app_subghz(void* p); | ||||||
| 
 | 
 | ||||||
| int32_t gui_test(void* p); | int32_t gui_test(void* p); | ||||||
| 
 | 
 | ||||||
| @ -148,6 +149,10 @@ const FlipperApplication FLIPPER_SERVICES[] = { | |||||||
| #ifdef APP_GUI_TEST | #ifdef APP_GUI_TEST | ||||||
|     {.app = gui_test, .name = "gui_test", .icon = A_Plugins_14}, |     {.app = gui_test, .name = "gui_test", .icon = A_Plugins_14}, | ||||||
| #endif | #endif | ||||||
|  | 
 | ||||||
|  | #ifdef APP_SUBGHZ | ||||||
|  |     {.app = app_subghz, .name = "app_subghz", .icon = A_Plugins_14}, | ||||||
|  | #endif | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| const size_t FLIPPER_SERVICES_COUNT = sizeof(FLIPPER_SERVICES) / sizeof(FlipperApplication); | const size_t FLIPPER_SERVICES_COUNT = sizeof(FLIPPER_SERVICES) / sizeof(FlipperApplication); | ||||||
| @ -220,6 +225,10 @@ const FlipperApplication FLIPPER_PLUGINS[] = { | |||||||
| #ifdef BUILD_GUI_TEST | #ifdef BUILD_GUI_TEST | ||||||
|     {.app = gui_test, .name = "gui_test", .icon = A_Plugins_14}, |     {.app = gui_test, .name = "gui_test", .icon = A_Plugins_14}, | ||||||
| #endif | #endif | ||||||
|  | 
 | ||||||
|  | #ifdef BUILD_SUBGHZ | ||||||
|  |     {.app = app_subghz, .name = "app_subghz", .icon = A_Plugins_14}, | ||||||
|  | #endif | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| const size_t FLIPPER_PLUGINS_COUNT = sizeof(FLIPPER_PLUGINS) / sizeof(FlipperApplication); | const size_t FLIPPER_PLUGINS_COUNT = sizeof(FLIPPER_PLUGINS) / sizeof(FlipperApplication); | ||||||
|  | |||||||
| @ -30,6 +30,7 @@ BUILD_MUSIC_PLAYER = 1 | |||||||
| BUILD_FLOOPPER_BLOOPPER = 1 | BUILD_FLOOPPER_BLOOPPER = 1 | ||||||
| BUILD_IBUTTON = 1 | BUILD_IBUTTON = 1 | ||||||
| BUILD_GUI_TEST = 1 | BUILD_GUI_TEST = 1 | ||||||
|  | BUILD_SUBGHZ = 1 | ||||||
| endif | endif | ||||||
| 
 | 
 | ||||||
| APP_NFC ?= 0 | APP_NFC ?= 0 | ||||||
| @ -276,6 +277,18 @@ CFLAGS		+= -DBUILD_GUI_TEST | |||||||
| C_SOURCES	+= $(wildcard $(APP_DIR)/gui-test/*.c) | C_SOURCES	+= $(wildcard $(APP_DIR)/gui-test/*.c) | ||||||
| endif | endif | ||||||
| 
 | 
 | ||||||
|  | APP_SUBGHZ ?= 0 | ||||||
|  | ifeq ($(APP_SUBGHZ), 1) | ||||||
|  | CFLAGS		+= -DAPP_SUBGHZ | ||||||
|  | BUILD_SUBGHZ = 1 | ||||||
|  | endif | ||||||
|  | BUILD_SUBGHZ ?= 0 | ||||||
|  | ifeq ($(BUILD_SUBGHZ), 1) | ||||||
|  | CFLAGS		+= -DBUILD_SUBGHZ | ||||||
|  | CPP_SOURCES	+= $(wildcard $(APP_DIR)/subghz/*.cpp) | ||||||
|  | CPP_SOURCES	+= $(wildcard $(APP_DIR)/subghz/*/*.cpp) | ||||||
|  | endif | ||||||
|  | 
 | ||||||
| APP_SDNFC ?= 0 | APP_SDNFC ?= 0 | ||||||
| ifeq ($(APP_SDNFC), 1) | ifeq ($(APP_SDNFC), 1) | ||||||
| CFLAGS		+= -DAPP_SDNFC | CFLAGS		+= -DAPP_SDNFC | ||||||
|  | |||||||
| @ -76,7 +76,7 @@ void popup_callback(void* context) { | |||||||
|     next_view(context); |     next_view(context); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void submenu_callback(void* context) { | void submenu_callback(void* context, uint32_t index) { | ||||||
|     next_view(context); |     next_view(context); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -100,15 +100,16 @@ int32_t gui_test(void* param) { | |||||||
|     view_dispatcher_attach_to_gui(gui_tester->view_dispatcher, gui, ViewDispatcherTypeFullscreen); |     view_dispatcher_attach_to_gui(gui_tester->view_dispatcher, gui, ViewDispatcherTypeFullscreen); | ||||||
| 
 | 
 | ||||||
|     // Submenu
 |     // Submenu
 | ||||||
|     submenu_add_item(gui_tester->submenu, "Read", submenu_callback, gui_tester); |     submenu_add_item(gui_tester->submenu, "Read", 0, submenu_callback, gui_tester); | ||||||
|     submenu_add_item(gui_tester->submenu, "Saved", submenu_callback, gui_tester); |     submenu_add_item(gui_tester->submenu, "Saved", 0, submenu_callback, gui_tester); | ||||||
|     submenu_add_item(gui_tester->submenu, "Emulate", submenu_callback, gui_tester); |     submenu_add_item(gui_tester->submenu, "Emulate", 0, submenu_callback, gui_tester); | ||||||
|     submenu_add_item(gui_tester->submenu, "Enter manually", submenu_callback, gui_tester); |     submenu_add_item(gui_tester->submenu, "Enter manually", 0, submenu_callback, gui_tester); | ||||||
|     submenu_add_item(gui_tester->submenu, "Blah blah", submenu_callback, gui_tester); |     submenu_add_item(gui_tester->submenu, "Blah blah", 0, submenu_callback, gui_tester); | ||||||
|     submenu_add_item(gui_tester->submenu, "Set time", submenu_callback, gui_tester); |     submenu_add_item(gui_tester->submenu, "Set time", 0, submenu_callback, gui_tester); | ||||||
|     submenu_add_item(gui_tester->submenu, "Gender-bender", submenu_callback, gui_tester); |     submenu_add_item(gui_tester->submenu, "Gender-bender", 0, submenu_callback, gui_tester); | ||||||
|     submenu_add_item(gui_tester->submenu, "Hack American Elections", submenu_callback, gui_tester); |     submenu_add_item( | ||||||
|     submenu_add_item(gui_tester->submenu, "Hack the White House", submenu_callback, gui_tester); |         gui_tester->submenu, "Hack American Elections", 0, submenu_callback, gui_tester); | ||||||
|  |     submenu_add_item(gui_tester->submenu, "Hack the White House", 0, submenu_callback, gui_tester); | ||||||
| 
 | 
 | ||||||
|     // Dialog
 |     // Dialog
 | ||||||
|     dialog_set_result_callback(gui_tester->dialog, dialog_callback); |     dialog_set_result_callback(gui_tester->dialog, dialog_callback); | ||||||
|  | |||||||
| @ -5,6 +5,7 @@ | |||||||
| 
 | 
 | ||||||
| struct SubmenuItem { | struct SubmenuItem { | ||||||
|     const char* label; |     const char* label; | ||||||
|  |     uint32_t index; | ||||||
|     SubmenuItemCallback callback; |     SubmenuItemCallback callback; | ||||||
|     void* callback_context; |     void* callback_context; | ||||||
| }; | }; | ||||||
| @ -108,6 +109,7 @@ Submenu* submenu_alloc() { | |||||||
|         submenu->view, (SubmenuModel * model) { |         submenu->view, (SubmenuModel * model) { | ||||||
|             SubmenuItemArray_init(model->items); |             SubmenuItemArray_init(model->items); | ||||||
|             model->position = 0; |             model->position = 0; | ||||||
|  |             model->window_position = 0; | ||||||
|             return true; |             return true; | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
| @ -134,6 +136,7 @@ View* submenu_get_view(Submenu* submenu) { | |||||||
| SubmenuItem* submenu_add_item( | SubmenuItem* submenu_add_item( | ||||||
|     Submenu* submenu, |     Submenu* submenu, | ||||||
|     const char* label, |     const char* label, | ||||||
|  |     uint32_t index, | ||||||
|     SubmenuItemCallback callback, |     SubmenuItemCallback callback, | ||||||
|     void* callback_context) { |     void* callback_context) { | ||||||
|     SubmenuItem* item = NULL; |     SubmenuItem* item = NULL; | ||||||
| @ -144,6 +147,7 @@ SubmenuItem* submenu_add_item( | |||||||
|         submenu->view, (SubmenuModel * model) { |         submenu->view, (SubmenuModel * model) { | ||||||
|             item = SubmenuItemArray_push_new(model->items); |             item = SubmenuItemArray_push_new(model->items); | ||||||
|             item->label = label; |             item->label = label; | ||||||
|  |             item->index = index; | ||||||
|             item->callback = callback; |             item->callback = callback; | ||||||
|             item->callback_context = callback_context; |             item->callback_context = callback_context; | ||||||
|             return true; |             return true; | ||||||
| @ -152,6 +156,18 @@ SubmenuItem* submenu_add_item( | |||||||
|     return item; |     return item; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void submenu_clean(Submenu* submenu) { | ||||||
|  |     furi_assert(submenu); | ||||||
|  | 
 | ||||||
|  |     with_view_model( | ||||||
|  |         submenu->view, (SubmenuModel * model) { | ||||||
|  |             SubmenuItemArray_clean(model->items); | ||||||
|  |             model->position = 0; | ||||||
|  |             model->window_position = 0; | ||||||
|  |             return true; | ||||||
|  |         }); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void submenu_process_up(Submenu* submenu) { | void submenu_process_up(Submenu* submenu) { | ||||||
|     with_view_model( |     with_view_model( | ||||||
|         submenu->view, (SubmenuModel * model) { |         submenu->view, (SubmenuModel * model) { | ||||||
| @ -162,8 +178,10 @@ void submenu_process_up(Submenu* submenu) { | |||||||
|                 } |                 } | ||||||
|             } else { |             } else { | ||||||
|                 model->position = SubmenuItemArray_size(model->items) - 1; |                 model->position = SubmenuItemArray_size(model->items) - 1; | ||||||
|  |                 if(model->position > 3) { | ||||||
|                     model->window_position = model->position - 3; |                     model->window_position = model->position - 3; | ||||||
|                 } |                 } | ||||||
|  |             } | ||||||
|             return true; |             return true; | ||||||
|         }); |         }); | ||||||
| } | } | ||||||
| @ -197,6 +215,6 @@ void submenu_process_ok(Submenu* submenu) { | |||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|     if(item && item->callback) { |     if(item && item->callback) { | ||||||
|         item->callback(item->callback_context); |         item->callback(item->callback_context, item->index); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @ -1,10 +1,14 @@ | |||||||
| #pragma once | #pragma once | ||||||
| #include <gui/view.h> | #include <gui/view.h> | ||||||
| 
 | 
 | ||||||
|  | #ifdef __cplusplus | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
| /* Submenu anonymous structure */ | /* Submenu anonymous structure */ | ||||||
| typedef struct Submenu Submenu; | typedef struct Submenu Submenu; | ||||||
| typedef struct SubmenuItem SubmenuItem; | typedef struct SubmenuItem SubmenuItem; | ||||||
| typedef void (*SubmenuItemCallback)(void* context); | typedef void (*SubmenuItemCallback)(void* context, uint32_t index); | ||||||
| 
 | 
 | ||||||
| /* Allocate and initialize submenu
 | /* Allocate and initialize submenu
 | ||||||
|  * This submenu is used to select one option |  * This submenu is used to select one option | ||||||
| @ -25,6 +29,7 @@ View* submenu_get_view(Submenu* submenu); | |||||||
| /* Add item to submenu
 | /* Add item to submenu
 | ||||||
|  * @param submenu - Submenu instance |  * @param submenu - Submenu instance | ||||||
|  * @param label - menu item label |  * @param label - menu item label | ||||||
|  |  * @param index - menu item index, used for callback, may be the same with other items | ||||||
|  * @param callback - menu item callback |  * @param callback - menu item callback | ||||||
|  * @param callback_context - menu item callback context |  * @param callback_context - menu item callback context | ||||||
|  * @return SubmenuItem instance that can be used to modify or delete that item |  * @return SubmenuItem instance that can be used to modify or delete that item | ||||||
| @ -32,5 +37,15 @@ View* submenu_get_view(Submenu* submenu); | |||||||
| SubmenuItem* submenu_add_item( | SubmenuItem* submenu_add_item( | ||||||
|     Submenu* submenu, |     Submenu* submenu, | ||||||
|     const char* label, |     const char* label, | ||||||
|  |     uint32_t index, | ||||||
|     SubmenuItemCallback callback, |     SubmenuItemCallback callback, | ||||||
|     void* callback_context); |     void* callback_context); | ||||||
|  | 
 | ||||||
|  | /* Remove all items from submenu
 | ||||||
|  |  * @param submenu - Submenu instance | ||||||
|  |  */ | ||||||
|  | void submenu_clean(Submenu* submenu); | ||||||
|  | 
 | ||||||
|  | #ifdef __cplusplus | ||||||
|  | } | ||||||
|  | #endif | ||||||
| @ -141,6 +141,18 @@ void* view_get_model(View* view); | |||||||
|  */ |  */ | ||||||
| void view_commit_model(View* view, bool update); | void view_commit_model(View* view, bool update); | ||||||
| 
 | 
 | ||||||
|  | #ifdef __cplusplus | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifdef __cplusplus | ||||||
|  | #define with_view_model_cpp(view, type, var, function_body) \ | ||||||
|  |     {                                                       \ | ||||||
|  |         type* p = static_cast<type*>(view_get_model(view)); \ | ||||||
|  |         bool update = [&](type * var) function_body(p);     \ | ||||||
|  |         view_commit_model(view, update);                    \ | ||||||
|  |     } | ||||||
|  | #else | ||||||
| /* 
 | /* 
 | ||||||
|  * With clause for view model |  * With clause for view model | ||||||
|  * @param view, View instance pointer |  * @param view, View instance pointer | ||||||
| @ -153,7 +165,4 @@ void view_commit_model(View* view, bool update); | |||||||
|         bool update = ({ bool __fn__ function_body __fn__; })(p); \ |         bool update = ({ bool __fn__ function_body __fn__; })(p); \ | ||||||
|         view_commit_model(view, update);                          \ |         view_commit_model(view, update);                          \ | ||||||
|     } |     } | ||||||
| 
 |  | ||||||
| #ifdef __cplusplus |  | ||||||
| } |  | ||||||
| #endif | #endif | ||||||
| @ -42,6 +42,17 @@ void view_dispatcher_add_view(ViewDispatcher* view_dispatcher, uint32_t view_id, | |||||||
|     view_set_dispatcher(view, view_dispatcher); |     view_set_dispatcher(view, view_dispatcher); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void view_dispatcher_remove_view(ViewDispatcher* view_dispatcher, uint32_t view_id) { | ||||||
|  |     furi_assert(view_dispatcher); | ||||||
|  | 
 | ||||||
|  |     // Disable the view if it is active
 | ||||||
|  |     if(view_dispatcher->current_view == *ViewDict_get(view_dispatcher->views, view_id)) { | ||||||
|  |         view_dispatcher_set_current_view(view_dispatcher, NULL); | ||||||
|  |     } | ||||||
|  |     // Remove view
 | ||||||
|  |     ViewDict_erase(view_dispatcher->views, view_id); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void view_dispatcher_switch_to_view(ViewDispatcher* view_dispatcher, uint32_t view_id) { | void view_dispatcher_switch_to_view(ViewDispatcher* view_dispatcher, uint32_t view_id) { | ||||||
|     furi_assert(view_dispatcher); |     furi_assert(view_dispatcher); | ||||||
|     if(view_id == VIEW_NONE) { |     if(view_id == VIEW_NONE) { | ||||||
|  | |||||||
| @ -33,6 +33,12 @@ void view_dispatcher_free(ViewDispatcher* view_dispatcher); | |||||||
|  */ |  */ | ||||||
| void view_dispatcher_add_view(ViewDispatcher* view_dispatcher, uint32_t view_id, View* view); | void view_dispatcher_add_view(ViewDispatcher* view_dispatcher, uint32_t view_id, View* view); | ||||||
| 
 | 
 | ||||||
|  | /* Remove view from ViewDispatcher
 | ||||||
|  |  * @param view_dispatcher, ViewDispatcher instance | ||||||
|  |  * @param view_id, View id to remove | ||||||
|  |  */ | ||||||
|  | void view_dispatcher_remove_view(ViewDispatcher* view_dispatcher, uint32_t view_id); | ||||||
|  | 
 | ||||||
| /* Switch to View
 | /* Switch to View
 | ||||||
|  * @param view_dispatcher, ViewDispatcher instance |  * @param view_dispatcher, ViewDispatcher instance | ||||||
|  * @param view_id, View id to register |  * @param view_id, View id to register | ||||||
|  | |||||||
							
								
								
									
										13
									
								
								applications/subghz/scene/subghz-scene-generic.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								applications/subghz/scene/subghz-scene-generic.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,13 @@ | |||||||
|  | #pragma once | ||||||
|  | #include "../subghz-event.h" | ||||||
|  | 
 | ||||||
|  | class SubghzApp; | ||||||
|  | 
 | ||||||
|  | class SubghzScene { | ||||||
|  | public: | ||||||
|  |     virtual void on_enter(SubghzApp* app) = 0; | ||||||
|  |     virtual bool on_event(SubghzApp* app, SubghzEvent* event) = 0; | ||||||
|  |     virtual void on_exit(SubghzApp* app) = 0; | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  | }; | ||||||
							
								
								
									
										48
									
								
								applications/subghz/scene/subghz-scene-spectrum-settings.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								applications/subghz/scene/subghz-scene-spectrum-settings.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,48 @@ | |||||||
|  | #include "subghz-scene-spectrum-settings.h" | ||||||
|  | #include "../subghz-app.h" | ||||||
|  | #include "../subghz-view-manager.h" | ||||||
|  | #include "../subghz-event.h" | ||||||
|  | #include <callback-connector.h> | ||||||
|  | 
 | ||||||
|  | void SubghzSceneSpectrumSettings::on_enter(SubghzApp* app) { | ||||||
|  |     SubghzAppViewManager* view_manager = app->get_view_manager(); | ||||||
|  |     SubghzViewSpectrumSettings* spectrum_settings = view_manager->get_spectrum_settings(); | ||||||
|  | 
 | ||||||
|  |     auto callback = cbc::obtain_connector(this, &SubghzSceneSpectrumSettings::ok_callback); | ||||||
|  |     spectrum_settings->set_ok_callback(callback, app); | ||||||
|  |     spectrum_settings->set_start_freq(433); | ||||||
|  | 
 | ||||||
|  |     view_manager->switch_to(SubghzAppViewManager::ViewType::SpectrumSettings); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool SubghzSceneSpectrumSettings::on_event(SubghzApp* app, SubghzEvent* event) { | ||||||
|  |     bool consumed = false; | ||||||
|  | 
 | ||||||
|  |     if(event->type == SubghzEvent::Type::NextScene) { | ||||||
|  |         // save data
 | ||||||
|  |         // uint32_t start_freq = app->get_view_manager()->get_spectrum_settings()->get_start_freq();
 | ||||||
|  |         // app->get_spectrum_analyzer()->set_start_freq(start_freq);
 | ||||||
|  | 
 | ||||||
|  |         // switch to next scene
 | ||||||
|  |         // app->switch_to_next_scene(SubghzApp::Scene::SceneSpectrumAnalyze);
 | ||||||
|  |         consumed = true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return consumed; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void SubghzSceneSpectrumSettings::on_exit(SubghzApp* app) { | ||||||
|  |     SubghzAppViewManager* view_manager = app->get_view_manager(); | ||||||
|  |     SubghzViewSpectrumSettings* spectrum_settings = view_manager->get_spectrum_settings(); | ||||||
|  | 
 | ||||||
|  |     spectrum_settings->set_ok_callback(nullptr, nullptr); | ||||||
|  |     spectrum_settings->set_start_freq(0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void SubghzSceneSpectrumSettings::ok_callback(void* context) { | ||||||
|  |     SubghzApp* app = static_cast<SubghzApp*>(context); | ||||||
|  |     SubghzEvent event; | ||||||
|  | 
 | ||||||
|  |     event.type = SubghzEvent::Type::NextScene; | ||||||
|  |     app->get_view_manager()->send_event(&event); | ||||||
|  | } | ||||||
							
								
								
									
										12
									
								
								applications/subghz/scene/subghz-scene-spectrum-settings.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								applications/subghz/scene/subghz-scene-spectrum-settings.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | |||||||
|  | #pragma once | ||||||
|  | #include "subghz-scene-generic.h" | ||||||
|  | 
 | ||||||
|  | class SubghzSceneSpectrumSettings : public SubghzScene { | ||||||
|  | public: | ||||||
|  |     void on_enter(SubghzApp* app) final; | ||||||
|  |     bool on_event(SubghzApp* app, SubghzEvent* event) final; | ||||||
|  |     void on_exit(SubghzApp* app) final; | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     void ok_callback(void* context); | ||||||
|  | }; | ||||||
							
								
								
									
										67
									
								
								applications/subghz/scene/subghz-scene-start.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								applications/subghz/scene/subghz-scene-start.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,67 @@ | |||||||
|  | #include "subghz-scene-start.h" | ||||||
|  | #include "../subghz-app.h" | ||||||
|  | #include "../subghz-view-manager.h" | ||||||
|  | #include "../subghz-event.h" | ||||||
|  | #include <callback-connector.h> | ||||||
|  | 
 | ||||||
|  | typedef enum { | ||||||
|  |     SubmenuIndexSpectrumAnalyzer, | ||||||
|  |     SubmenuIndexFrequencyScanner, | ||||||
|  |     SubmenuIndexSignalAnalyzer, | ||||||
|  |     SubmenuIndexSignalTransmitter, | ||||||
|  |     SubmenuIndexApplications, | ||||||
|  | } SubmenuIndex; | ||||||
|  | 
 | ||||||
|  | void SubghzSceneStart::on_enter(SubghzApp* app) { | ||||||
|  |     SubghzAppViewManager* view_manager = app->get_view_manager(); | ||||||
|  |     Submenu* submenu = view_manager->get_submenu(); | ||||||
|  |     auto callback = cbc::obtain_connector(this, &SubghzSceneStart::submenu_callback); | ||||||
|  | 
 | ||||||
|  |     submenu_add_item(submenu, "Spectrum Analyzer", SubmenuIndexSpectrumAnalyzer, callback, app); | ||||||
|  |     submenu_add_item(submenu, "Frequency Scanner", SubmenuIndexFrequencyScanner, callback, app); | ||||||
|  |     submenu_add_item(submenu, "Signal Analyzer", SubmenuIndexSignalAnalyzer, callback, app); | ||||||
|  |     submenu_add_item(submenu, "Signal Transmitter", SubmenuIndexSignalTransmitter, callback, app); | ||||||
|  |     submenu_add_item(submenu, "Applications", SubmenuIndexApplications, callback, app); | ||||||
|  | 
 | ||||||
|  |     view_manager->switch_to(SubghzAppViewManager::ViewType::Submenu); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool SubghzSceneStart::on_event(SubghzApp* app, SubghzEvent* event) { | ||||||
|  |     bool consumed = false; | ||||||
|  | 
 | ||||||
|  |     if(event->type == SubghzEvent::Type::MenuSelected) { | ||||||
|  |         switch(event->payload.menu_index) { | ||||||
|  |         case SubmenuIndexSpectrumAnalyzer: | ||||||
|  |             app->switch_to_next_scene(SubghzApp::Scene::SceneSpectrumSettings); | ||||||
|  |             break; | ||||||
|  |         case SubmenuIndexFrequencyScanner: | ||||||
|  |             break; | ||||||
|  |         case SubmenuIndexSignalAnalyzer: | ||||||
|  |             break; | ||||||
|  |         case SubmenuIndexSignalTransmitter: | ||||||
|  |             break; | ||||||
|  |         case SubmenuIndexApplications: | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         consumed = true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return consumed; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void SubghzSceneStart::on_exit(SubghzApp* app) { | ||||||
|  |     SubghzAppViewManager* view_manager = app->get_view_manager(); | ||||||
|  |     Submenu* submenu = view_manager->get_submenu(); | ||||||
|  | 
 | ||||||
|  |     submenu_clean(submenu); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void SubghzSceneStart::submenu_callback(void* context, uint32_t index) { | ||||||
|  |     SubghzApp* app = static_cast<SubghzApp*>(context); | ||||||
|  |     SubghzEvent event; | ||||||
|  | 
 | ||||||
|  |     event.type = SubghzEvent::Type::MenuSelected; | ||||||
|  |     event.payload.menu_index = index; | ||||||
|  | 
 | ||||||
|  |     app->get_view_manager()->send_event(&event); | ||||||
|  | } | ||||||
							
								
								
									
										12
									
								
								applications/subghz/scene/subghz-scene-start.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								applications/subghz/scene/subghz-scene-start.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | |||||||
|  | #pragma once | ||||||
|  | #include "subghz-scene-generic.h" | ||||||
|  | 
 | ||||||
|  | class SubghzSceneStart : public SubghzScene { | ||||||
|  | public: | ||||||
|  |     void on_enter(SubghzApp* app) final; | ||||||
|  |     bool on_event(SubghzApp* app, SubghzEvent* event) final; | ||||||
|  |     void on_exit(SubghzApp* app) final; | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     void submenu_callback(void* context, uint32_t index); | ||||||
|  | }; | ||||||
							
								
								
									
										90
									
								
								applications/subghz/subghz-app.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								applications/subghz/subghz-app.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,90 @@ | |||||||
|  | #include "subghz-app.h" | ||||||
|  | #include <api-hal-power.h> | ||||||
|  | #include <stdarg.h> | ||||||
|  | 
 | ||||||
|  | void SubghzApp::run(void) { | ||||||
|  |     SubghzEvent event; | ||||||
|  |     bool consumed; | ||||||
|  |     bool exit = false; | ||||||
|  | 
 | ||||||
|  |     scenes[current_scene]->on_enter(this); | ||||||
|  | 
 | ||||||
|  |     while(!exit) { | ||||||
|  |         view.receive_event(&event); | ||||||
|  | 
 | ||||||
|  |         consumed = scenes[current_scene]->on_event(this, &event); | ||||||
|  | 
 | ||||||
|  |         if(!consumed) { | ||||||
|  |             if(event.type == SubghzEvent::Type::Back) { | ||||||
|  |                 exit = switch_to_previous_scene(); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     scenes[current_scene]->on_exit(this); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | SubghzApp::SubghzApp() { | ||||||
|  |     api_hal_power_insomnia_enter(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | SubghzApp::~SubghzApp() { | ||||||
|  |     api_hal_power_insomnia_exit(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | SubghzAppViewManager* SubghzApp::get_view_manager() { | ||||||
|  |     return &view; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void SubghzApp::switch_to_next_scene(Scene next_scene) { | ||||||
|  |     previous_scenes_list.push_front(current_scene); | ||||||
|  | 
 | ||||||
|  |     if(next_scene != Scene::SceneExit) { | ||||||
|  |         scenes[current_scene]->on_exit(this); | ||||||
|  |         current_scene = next_scene; | ||||||
|  |         scenes[current_scene]->on_enter(this); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void SubghzApp::search_and_switch_to_previous_scene(std::initializer_list<Scene> scenes_list) { | ||||||
|  |     Scene previous_scene = Scene::SceneStart; | ||||||
|  |     bool scene_found = false; | ||||||
|  | 
 | ||||||
|  |     while(!scene_found) { | ||||||
|  |         previous_scene = get_previous_scene(); | ||||||
|  |         for(Scene element : scenes_list) { | ||||||
|  |             if(previous_scene == element || previous_scene == Scene::SceneStart) { | ||||||
|  |                 scene_found = true; | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     scenes[current_scene]->on_exit(this); | ||||||
|  |     current_scene = previous_scene; | ||||||
|  |     scenes[current_scene]->on_enter(this); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool SubghzApp::switch_to_previous_scene(uint8_t count) { | ||||||
|  |     Scene previous_scene = Scene::SceneStart; | ||||||
|  | 
 | ||||||
|  |     for(uint8_t i = 0; i < count; i++) { | ||||||
|  |         previous_scene = get_previous_scene(); | ||||||
|  |         if(previous_scene == Scene::SceneExit) break; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if(previous_scene == Scene::SceneExit) { | ||||||
|  |         return true; | ||||||
|  |     } else { | ||||||
|  |         scenes[current_scene]->on_exit(this); | ||||||
|  |         current_scene = previous_scene; | ||||||
|  |         scenes[current_scene]->on_enter(this); | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | SubghzApp::Scene SubghzApp::get_previous_scene() { | ||||||
|  |     Scene scene = previous_scenes_list.front(); | ||||||
|  |     previous_scenes_list.pop_front(); | ||||||
|  |     return scene; | ||||||
|  | } | ||||||
							
								
								
									
										37
									
								
								applications/subghz/subghz-app.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								applications/subghz/subghz-app.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,37 @@ | |||||||
|  | #pragma once | ||||||
|  | #include <map> | ||||||
|  | #include <list> | ||||||
|  | #include "subghz-view-manager.h" | ||||||
|  | 
 | ||||||
|  | #include "scene/subghz-scene-start.h" | ||||||
|  | #include "scene/subghz-scene-spectrum-settings.h" | ||||||
|  | 
 | ||||||
|  | class SubghzApp { | ||||||
|  | public: | ||||||
|  |     void run(void); | ||||||
|  | 
 | ||||||
|  |     SubghzApp(); | ||||||
|  |     ~SubghzApp(); | ||||||
|  | 
 | ||||||
|  |     enum class Scene : uint8_t { | ||||||
|  |         SceneExit, | ||||||
|  |         SceneStart, | ||||||
|  |         SceneSpectrumSettings, | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     SubghzAppViewManager* get_view_manager(); | ||||||
|  |     void switch_to_next_scene(Scene index); | ||||||
|  |     void search_and_switch_to_previous_scene(std::initializer_list<Scene> scenes_list); | ||||||
|  |     bool switch_to_previous_scene(uint8_t count = 1); | ||||||
|  |     Scene get_previous_scene(); | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     std::list<Scene> previous_scenes_list = {Scene::SceneExit}; | ||||||
|  |     Scene current_scene = Scene::SceneStart; | ||||||
|  |     SubghzAppViewManager view; | ||||||
|  | 
 | ||||||
|  |     std::map<Scene, SubghzScene*> scenes = { | ||||||
|  |         {Scene::SceneStart, new SubghzSceneStart()}, | ||||||
|  |         {Scene::SceneSpectrumSettings, new SubghzSceneSpectrumSettings()}, | ||||||
|  |     }; | ||||||
|  | }; | ||||||
							
								
								
									
										21
									
								
								applications/subghz/subghz-event.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								applications/subghz/subghz-event.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,21 @@ | |||||||
|  | #pragma once | ||||||
|  | #include <stdint.h> | ||||||
|  | 
 | ||||||
|  | class SubghzEvent { | ||||||
|  | public: | ||||||
|  |     // events enum
 | ||||||
|  |     enum class Type : uint8_t { | ||||||
|  |         Tick, | ||||||
|  |         Back, | ||||||
|  |         MenuSelected, | ||||||
|  |         NextScene, | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     // payload
 | ||||||
|  |     union { | ||||||
|  |         uint32_t menu_index; | ||||||
|  |     } payload; | ||||||
|  | 
 | ||||||
|  |     // event type
 | ||||||
|  |     Type type; | ||||||
|  | }; | ||||||
							
								
								
									
										81
									
								
								applications/subghz/subghz-view-manager.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								applications/subghz/subghz-view-manager.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,81 @@ | |||||||
|  | #include "subghz-view-manager.h" | ||||||
|  | #include "subghz-event.h" | ||||||
|  | #include <callback-connector.h> | ||||||
|  | 
 | ||||||
|  | SubghzAppViewManager::SubghzAppViewManager() { | ||||||
|  |     event_queue = osMessageQueueNew(10, sizeof(SubghzEvent), NULL); | ||||||
|  | 
 | ||||||
|  |     view_dispatcher = view_dispatcher_alloc(); | ||||||
|  |     auto callback = cbc::obtain_connector(this, &SubghzAppViewManager::previous_view_callback); | ||||||
|  | 
 | ||||||
|  |     // allocate views
 | ||||||
|  |     submenu = submenu_alloc(); | ||||||
|  |     view_dispatcher_add_view( | ||||||
|  |         view_dispatcher, | ||||||
|  |         static_cast<uint32_t>(SubghzAppViewManager::ViewType::Submenu), | ||||||
|  |         submenu_get_view(submenu)); | ||||||
|  | 
 | ||||||
|  |     spectrum_settings = new SubghzViewSpectrumSettings(); | ||||||
|  |     view_dispatcher_add_view( | ||||||
|  |         view_dispatcher, | ||||||
|  |         static_cast<uint32_t>(SubghzAppViewManager::ViewType::SpectrumSettings), | ||||||
|  |         spectrum_settings->get_view()); | ||||||
|  | 
 | ||||||
|  |     gui = static_cast<Gui*>(furi_record_open("gui")); | ||||||
|  |     view_dispatcher_attach_to_gui(view_dispatcher, gui, ViewDispatcherTypeFullscreen); | ||||||
|  | 
 | ||||||
|  |     // set previous view callback for all views
 | ||||||
|  |     view_set_previous_callback(submenu_get_view(submenu), callback); | ||||||
|  |     view_set_previous_callback(spectrum_settings->get_view(), callback); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | SubghzAppViewManager::~SubghzAppViewManager() { | ||||||
|  |     // remove views
 | ||||||
|  |     view_dispatcher_remove_view( | ||||||
|  |         view_dispatcher, static_cast<uint32_t>(SubghzAppViewManager::ViewType::Submenu)); | ||||||
|  |     view_dispatcher_remove_view( | ||||||
|  |         view_dispatcher, static_cast<uint32_t>(SubghzAppViewManager::ViewType::SpectrumSettings)); | ||||||
|  | 
 | ||||||
|  |     // free view modules
 | ||||||
|  |     submenu_free(submenu); | ||||||
|  |     free(spectrum_settings); | ||||||
|  | 
 | ||||||
|  |     // free dispatcher
 | ||||||
|  |     view_dispatcher_free(view_dispatcher); | ||||||
|  | 
 | ||||||
|  |     // free event queue
 | ||||||
|  |     osMessageQueueDelete(event_queue); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void SubghzAppViewManager::switch_to(ViewType type) { | ||||||
|  |     view_dispatcher_switch_to_view(view_dispatcher, static_cast<uint32_t>(type)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | Submenu* SubghzAppViewManager::get_submenu() { | ||||||
|  |     return submenu; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | SubghzViewSpectrumSettings* SubghzAppViewManager::get_spectrum_settings() { | ||||||
|  |     return spectrum_settings; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void SubghzAppViewManager::receive_event(SubghzEvent* event) { | ||||||
|  |     if(osMessageQueueGet(event_queue, event, NULL, 100) != osOK) { | ||||||
|  |         event->type = SubghzEvent::Type::Tick; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void SubghzAppViewManager::send_event(SubghzEvent* event) { | ||||||
|  |     osStatus_t result = osMessageQueuePut(event_queue, event, 0, 0); | ||||||
|  |     furi_check(result == osOK); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint32_t SubghzAppViewManager::previous_view_callback(void* context) { | ||||||
|  |     if(event_queue != NULL) { | ||||||
|  |         SubghzEvent event; | ||||||
|  |         event.type = SubghzEvent::Type::Back; | ||||||
|  |         send_event(&event); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return VIEW_IGNORE; | ||||||
|  | } | ||||||
							
								
								
									
										37
									
								
								applications/subghz/subghz-view-manager.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								applications/subghz/subghz-view-manager.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,37 @@ | |||||||
|  | #pragma once | ||||||
|  | #include <furi.h> | ||||||
|  | #include <gui/view_dispatcher.h> | ||||||
|  | #include <gui/modules/submenu.h> | ||||||
|  | #include "subghz-event.h" | ||||||
|  | #include "view/subghz-view-spectrum-settings.h" | ||||||
|  | 
 | ||||||
|  | class SubghzAppViewManager { | ||||||
|  | public: | ||||||
|  |     enum class ViewType : uint8_t { | ||||||
|  |         Submenu, | ||||||
|  |         SpectrumSettings, | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     osMessageQueueId_t event_queue; | ||||||
|  | 
 | ||||||
|  |     SubghzAppViewManager(); | ||||||
|  |     ~SubghzAppViewManager(); | ||||||
|  | 
 | ||||||
|  |     void switch_to(ViewType type); | ||||||
|  | 
 | ||||||
|  |     void receive_event(SubghzEvent* event); | ||||||
|  |     void send_event(SubghzEvent* event); | ||||||
|  | 
 | ||||||
|  |     Submenu* get_submenu(); | ||||||
|  |     SubghzViewSpectrumSettings* get_spectrum_settings(); | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     ViewDispatcher* view_dispatcher; | ||||||
|  |     Gui* gui; | ||||||
|  | 
 | ||||||
|  |     uint32_t previous_view_callback(void* context); | ||||||
|  | 
 | ||||||
|  |     // view elements
 | ||||||
|  |     Submenu* submenu; | ||||||
|  |     SubghzViewSpectrumSettings* spectrum_settings; | ||||||
|  | }; | ||||||
							
								
								
									
										10
									
								
								applications/subghz/subghz.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								applications/subghz/subghz.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | |||||||
|  | #include "subghz-app.h" | ||||||
|  | 
 | ||||||
|  | // app enter function
 | ||||||
|  | extern "C" int32_t app_subghz(void* p) { | ||||||
|  |     SubghzApp* app = new SubghzApp(); | ||||||
|  |     app->run(); | ||||||
|  |     delete app; | ||||||
|  | 
 | ||||||
|  |     return 255; | ||||||
|  | } | ||||||
							
								
								
									
										95
									
								
								applications/subghz/view/subghz-view-spectrum-settings.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								applications/subghz/view/subghz-view-spectrum-settings.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,95 @@ | |||||||
|  | #include "subghz-view-spectrum-settings.h" | ||||||
|  | #include <callback-connector.h> | ||||||
|  | 
 | ||||||
|  | struct SpectrumSettingsModel { | ||||||
|  |     uint32_t start_freq; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /***************************************************************************************/ | ||||||
|  | 
 | ||||||
|  | static void draw_callback(Canvas* canvas, void* _model) { | ||||||
|  |     SpectrumSettingsModel* model = static_cast<SpectrumSettingsModel*>(_model); | ||||||
|  |     const uint8_t str_size = 64; | ||||||
|  |     char str_buffer[str_size]; | ||||||
|  | 
 | ||||||
|  |     canvas_clear(canvas); | ||||||
|  |     snprintf(str_buffer, str_size, "Start freq < %ld > MHz", model->start_freq); | ||||||
|  |     canvas_draw_str_aligned(canvas, 64, 32, AlignCenter, AlignCenter, str_buffer); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static bool input_callback(InputEvent* event, void* context) { | ||||||
|  |     SubghzViewSpectrumSettings* _this = static_cast<SubghzViewSpectrumSettings*>(context); | ||||||
|  | 
 | ||||||
|  |     bool consumed = false; | ||||||
|  | 
 | ||||||
|  |     // Process key presses only
 | ||||||
|  |     if(event->type == InputTypeShort) { | ||||||
|  |         if(event->key == InputKeyOk) { | ||||||
|  |             _this->call_ok_callback(); | ||||||
|  |             consumed = true; | ||||||
|  |         } else if(event->key == InputKeyLeft) { | ||||||
|  |             with_view_model_cpp(_this->get_view(), SpectrumSettingsModel, model, { | ||||||
|  |                 model->start_freq--; | ||||||
|  |                 return true; | ||||||
|  |             }); | ||||||
|  |             consumed = true; | ||||||
|  |         } else if(event->key == InputKeyRight) { | ||||||
|  |             with_view_model_cpp(_this->get_view(), SpectrumSettingsModel, model, { | ||||||
|  |                 model->start_freq++; | ||||||
|  |                 return true; | ||||||
|  |             }); | ||||||
|  |             consumed = true; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return consumed; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /***************************************************************************************/ | ||||||
|  | 
 | ||||||
|  | View* SubghzViewSpectrumSettings::get_view() { | ||||||
|  |     return view; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void SubghzViewSpectrumSettings::set_ok_callback(OkCallback callback, void* context) { | ||||||
|  |     ok_callback = callback; | ||||||
|  |     ok_callback_context = context; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void SubghzViewSpectrumSettings::call_ok_callback() { | ||||||
|  |     if(ok_callback != nullptr) { | ||||||
|  |         ok_callback(ok_callback_context); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void SubghzViewSpectrumSettings::set_start_freq(uint32_t start_freq) { | ||||||
|  |     with_view_model_cpp(view, SpectrumSettingsModel, model, { | ||||||
|  |         model->start_freq = start_freq; | ||||||
|  |         return true; | ||||||
|  |     }); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint32_t SubghzViewSpectrumSettings::get_start_freq() { | ||||||
|  |     uint32_t result; | ||||||
|  | 
 | ||||||
|  |     with_view_model_cpp(view, SpectrumSettingsModel, model, { | ||||||
|  |         result = model->start_freq; | ||||||
|  |         return false; | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | SubghzViewSpectrumSettings::SubghzViewSpectrumSettings() { | ||||||
|  |     view = view_alloc(); | ||||||
|  |     view_set_context(view, this); | ||||||
|  |     view_allocate_model(view, ViewModelTypeLocking, sizeof(SpectrumSettingsModel)); | ||||||
|  | 
 | ||||||
|  |     view_set_draw_callback(view, draw_callback); | ||||||
|  | 
 | ||||||
|  |     view_set_input_callback(view, input_callback); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | SubghzViewSpectrumSettings::~SubghzViewSpectrumSettings() { | ||||||
|  |     view_free(view); | ||||||
|  | } | ||||||
							
								
								
									
										25
									
								
								applications/subghz/view/subghz-view-spectrum-settings.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								applications/subghz/view/subghz-view-spectrum-settings.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,25 @@ | |||||||
|  | #include <gui/view.h> | ||||||
|  | 
 | ||||||
|  | class SubghzViewSpectrumSettings { | ||||||
|  | public: | ||||||
|  |     SubghzViewSpectrumSettings(); | ||||||
|  |     ~SubghzViewSpectrumSettings(); | ||||||
|  | 
 | ||||||
|  |     View* get_view(); | ||||||
|  | 
 | ||||||
|  |     // ok callback methods
 | ||||||
|  |     typedef void (*OkCallback)(void* context); | ||||||
|  |     void set_ok_callback(OkCallback callback, void* context); | ||||||
|  |     void call_ok_callback(); | ||||||
|  | 
 | ||||||
|  |     // model data getters/setters
 | ||||||
|  |     void set_start_freq(uint32_t start_freq); | ||||||
|  |     uint32_t get_start_freq(); | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     View* view; | ||||||
|  | 
 | ||||||
|  |     // ok callback data
 | ||||||
|  |     OkCallback ok_callback = nullptr; | ||||||
|  |     void* ok_callback_context = nullptr; | ||||||
|  | }; | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 SG
						SG