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:
		@@ -31,6 +31,7 @@ int32_t music_player(void* p);
 | 
			
		||||
int32_t sdnfc(void* p);
 | 
			
		||||
int32_t floopper_bloopper(void* p);
 | 
			
		||||
int32_t sd_filesystem(void* p);
 | 
			
		||||
int32_t app_subghz(void* p);
 | 
			
		||||
 | 
			
		||||
int32_t gui_test(void* p);
 | 
			
		||||
 | 
			
		||||
@@ -148,6 +149,10 @@ const FlipperApplication FLIPPER_SERVICES[] = {
 | 
			
		||||
#ifdef APP_GUI_TEST
 | 
			
		||||
    {.app = gui_test, .name = "gui_test", .icon = A_Plugins_14},
 | 
			
		||||
#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);
 | 
			
		||||
@@ -220,6 +225,10 @@ const FlipperApplication FLIPPER_PLUGINS[] = {
 | 
			
		||||
#ifdef BUILD_GUI_TEST
 | 
			
		||||
    {.app = gui_test, .name = "gui_test", .icon = A_Plugins_14},
 | 
			
		||||
#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);
 | 
			
		||||
 
 | 
			
		||||
@@ -30,6 +30,7 @@ BUILD_MUSIC_PLAYER = 1
 | 
			
		||||
BUILD_FLOOPPER_BLOOPPER = 1
 | 
			
		||||
BUILD_IBUTTON = 1
 | 
			
		||||
BUILD_GUI_TEST = 1
 | 
			
		||||
BUILD_SUBGHZ = 1
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
APP_NFC ?= 0
 | 
			
		||||
@@ -276,6 +277,18 @@ CFLAGS		+= -DBUILD_GUI_TEST
 | 
			
		||||
C_SOURCES	+= $(wildcard $(APP_DIR)/gui-test/*.c)
 | 
			
		||||
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
 | 
			
		||||
ifeq ($(APP_SDNFC), 1)
 | 
			
		||||
CFLAGS		+= -DAPP_SDNFC
 | 
			
		||||
 
 | 
			
		||||
@@ -76,7 +76,7 @@ void popup_callback(void* context) {
 | 
			
		||||
    next_view(context);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void submenu_callback(void* context) {
 | 
			
		||||
void submenu_callback(void* context, uint32_t index) {
 | 
			
		||||
    next_view(context);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -100,15 +100,16 @@ int32_t gui_test(void* param) {
 | 
			
		||||
    view_dispatcher_attach_to_gui(gui_tester->view_dispatcher, gui, ViewDispatcherTypeFullscreen);
 | 
			
		||||
 | 
			
		||||
    // Submenu
 | 
			
		||||
    submenu_add_item(gui_tester->submenu, "Read", submenu_callback, gui_tester);
 | 
			
		||||
    submenu_add_item(gui_tester->submenu, "Saved", submenu_callback, gui_tester);
 | 
			
		||||
    submenu_add_item(gui_tester->submenu, "Emulate", submenu_callback, gui_tester);
 | 
			
		||||
    submenu_add_item(gui_tester->submenu, "Enter manually", submenu_callback, gui_tester);
 | 
			
		||||
    submenu_add_item(gui_tester->submenu, "Blah blah", submenu_callback, gui_tester);
 | 
			
		||||
    submenu_add_item(gui_tester->submenu, "Set time", submenu_callback, gui_tester);
 | 
			
		||||
    submenu_add_item(gui_tester->submenu, "Gender-bender", submenu_callback, gui_tester);
 | 
			
		||||
    submenu_add_item(gui_tester->submenu, "Hack American Elections", submenu_callback, gui_tester);
 | 
			
		||||
    submenu_add_item(gui_tester->submenu, "Hack the White House", submenu_callback, gui_tester);
 | 
			
		||||
    submenu_add_item(gui_tester->submenu, "Read", 0, submenu_callback, gui_tester);
 | 
			
		||||
    submenu_add_item(gui_tester->submenu, "Saved", 0, submenu_callback, gui_tester);
 | 
			
		||||
    submenu_add_item(gui_tester->submenu, "Emulate", 0, 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", 0, 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", 0, submenu_callback, gui_tester);
 | 
			
		||||
    submenu_add_item(
 | 
			
		||||
        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_set_result_callback(gui_tester->dialog, dialog_callback);
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,7 @@
 | 
			
		||||
 | 
			
		||||
struct SubmenuItem {
 | 
			
		||||
    const char* label;
 | 
			
		||||
    uint32_t index;
 | 
			
		||||
    SubmenuItemCallback callback;
 | 
			
		||||
    void* callback_context;
 | 
			
		||||
};
 | 
			
		||||
@@ -108,6 +109,7 @@ Submenu* submenu_alloc() {
 | 
			
		||||
        submenu->view, (SubmenuModel * model) {
 | 
			
		||||
            SubmenuItemArray_init(model->items);
 | 
			
		||||
            model->position = 0;
 | 
			
		||||
            model->window_position = 0;
 | 
			
		||||
            return true;
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
@@ -134,6 +136,7 @@ View* submenu_get_view(Submenu* submenu) {
 | 
			
		||||
SubmenuItem* submenu_add_item(
 | 
			
		||||
    Submenu* submenu,
 | 
			
		||||
    const char* label,
 | 
			
		||||
    uint32_t index,
 | 
			
		||||
    SubmenuItemCallback callback,
 | 
			
		||||
    void* callback_context) {
 | 
			
		||||
    SubmenuItem* item = NULL;
 | 
			
		||||
@@ -144,6 +147,7 @@ SubmenuItem* submenu_add_item(
 | 
			
		||||
        submenu->view, (SubmenuModel * model) {
 | 
			
		||||
            item = SubmenuItemArray_push_new(model->items);
 | 
			
		||||
            item->label = label;
 | 
			
		||||
            item->index = index;
 | 
			
		||||
            item->callback = callback;
 | 
			
		||||
            item->callback_context = callback_context;
 | 
			
		||||
            return true;
 | 
			
		||||
@@ -152,6 +156,18 @@ SubmenuItem* submenu_add_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) {
 | 
			
		||||
    with_view_model(
 | 
			
		||||
        submenu->view, (SubmenuModel * model) {
 | 
			
		||||
@@ -162,7 +178,9 @@ void submenu_process_up(Submenu* submenu) {
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                model->position = SubmenuItemArray_size(model->items) - 1;
 | 
			
		||||
                model->window_position = model->position - 3;
 | 
			
		||||
                if(model->position > 3) {
 | 
			
		||||
                    model->window_position = model->position - 3;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            return true;
 | 
			
		||||
        });
 | 
			
		||||
@@ -197,6 +215,6 @@ void submenu_process_ok(Submenu* submenu) {
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    if(item && item->callback) {
 | 
			
		||||
        item->callback(item->callback_context);
 | 
			
		||||
        item->callback(item->callback_context, item->index);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,10 +1,14 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include <gui/view.h>
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Submenu anonymous structure */
 | 
			
		||||
typedef struct Submenu Submenu;
 | 
			
		||||
typedef struct SubmenuItem SubmenuItem;
 | 
			
		||||
typedef void (*SubmenuItemCallback)(void* context);
 | 
			
		||||
typedef void (*SubmenuItemCallback)(void* context, uint32_t index);
 | 
			
		||||
 | 
			
		||||
/* Allocate and initialize submenu
 | 
			
		||||
 * This submenu is used to select one option
 | 
			
		||||
@@ -25,6 +29,7 @@ View* submenu_get_view(Submenu* submenu);
 | 
			
		||||
/* Add item to submenu
 | 
			
		||||
 * @param submenu - Submenu instance
 | 
			
		||||
 * @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_context - menu item callback context
 | 
			
		||||
 * @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(
 | 
			
		||||
    Submenu* submenu,
 | 
			
		||||
    const char* label,
 | 
			
		||||
    uint32_t index,
 | 
			
		||||
    SubmenuItemCallback callback,
 | 
			
		||||
    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);
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
 * @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); \
 | 
			
		||||
        view_commit_model(view, update);                          \
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
@@ -42,6 +42,17 @@ void view_dispatcher_add_view(ViewDispatcher* view_dispatcher, uint32_t view_id,
 | 
			
		||||
    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) {
 | 
			
		||||
    furi_assert(view_dispatcher);
 | 
			
		||||
    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);
 | 
			
		||||
 | 
			
		||||
/* 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
 | 
			
		||||
 * @param view_dispatcher, ViewDispatcher instance
 | 
			
		||||
 * @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;
 | 
			
		||||
};
 | 
			
		||||
		Reference in New Issue
	
	Block a user