mirror of
https://github.com/DarkFlippers/unleashed-firmware.git
synced 2024-12-19 03:11:52 +03:00
Merge pull request #541 from CodyTolene/camera-suite
Add Camera Suite GPIO application for the ESP32-CAM module.
This commit is contained in:
commit
44baa84cf6
16
applications/external/camera-suite/application.fam
vendored
Normal file
16
applications/external/camera-suite/application.fam
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
App(
|
||||
appid="camerasuite",
|
||||
apptype=FlipperAppType.EXTERNAL,
|
||||
cdefines=["APP_CAMERA_SUITE"],
|
||||
entry_point="camera_suite_app",
|
||||
fap_author="Cody Tolene",
|
||||
fap_category="GPIO",
|
||||
fap_description="A camera suite application for the Flipper Zero ESP32-CAM module.",
|
||||
fap_icon="icons/camera-suite.png",
|
||||
fap_libs=["assets"],
|
||||
fap_weburl="https://github.com/CodyTolene/Flipper-Zero-Cam",
|
||||
name="[ESP32] Camera Suite",
|
||||
order=1,
|
||||
requires=["gui", "storage"],
|
||||
stack_size=8 * 1024
|
||||
)
|
139
applications/external/camera-suite/camera-suite.c
vendored
Normal file
139
applications/external/camera-suite/camera-suite.c
vendored
Normal file
@ -0,0 +1,139 @@
|
||||
#include "camera-suite.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
bool camera_suite_custom_event_callback(void* context, uint32_t event) {
|
||||
furi_assert(context);
|
||||
CameraSuite* app = context;
|
||||
return scene_manager_handle_custom_event(app->scene_manager, event);
|
||||
}
|
||||
|
||||
void camera_suite_tick_event_callback(void* context) {
|
||||
furi_assert(context);
|
||||
CameraSuite* app = context;
|
||||
scene_manager_handle_tick_event(app->scene_manager);
|
||||
}
|
||||
|
||||
//leave app if back button pressed
|
||||
bool camera_suite_navigation_event_callback(void* context) {
|
||||
furi_assert(context);
|
||||
CameraSuite* app = context;
|
||||
return scene_manager_handle_back_event(app->scene_manager);
|
||||
}
|
||||
|
||||
CameraSuite* camera_suite_app_alloc() {
|
||||
CameraSuite* app = malloc(sizeof(CameraSuite));
|
||||
app->gui = furi_record_open(RECORD_GUI);
|
||||
app->notification = furi_record_open(RECORD_NOTIFICATION);
|
||||
|
||||
//Turn backlight on, believe me this makes testing your app easier
|
||||
notification_message(app->notification, &sequence_display_backlight_on);
|
||||
|
||||
//Scene additions
|
||||
app->view_dispatcher = view_dispatcher_alloc();
|
||||
view_dispatcher_enable_queue(app->view_dispatcher);
|
||||
|
||||
app->scene_manager = scene_manager_alloc(&camera_suite_scene_handlers, app);
|
||||
view_dispatcher_set_event_callback_context(app->view_dispatcher, app);
|
||||
view_dispatcher_set_navigation_event_callback(
|
||||
app->view_dispatcher, camera_suite_navigation_event_callback);
|
||||
view_dispatcher_set_tick_event_callback(
|
||||
app->view_dispatcher, camera_suite_tick_event_callback, 100);
|
||||
view_dispatcher_set_custom_event_callback(
|
||||
app->view_dispatcher, camera_suite_custom_event_callback);
|
||||
app->submenu = submenu_alloc();
|
||||
|
||||
// Set defaults, in case no config loaded
|
||||
app->orientation = 0; // Orientation is "portrait", zero degrees by default.
|
||||
app->haptic = 1; // Haptic is on by default
|
||||
app->speaker = 1; // Speaker is on by default
|
||||
app->led = 1; // LED is on by default
|
||||
|
||||
// Load configs
|
||||
camera_suite_read_settings(app);
|
||||
|
||||
view_dispatcher_add_view(
|
||||
app->view_dispatcher, CameraSuiteViewIdMenu, submenu_get_view(app->submenu));
|
||||
|
||||
app->camera_suite_view_start = camera_suite_view_start_alloc();
|
||||
view_dispatcher_add_view(
|
||||
app->view_dispatcher,
|
||||
CameraSuiteViewIdStartscreen,
|
||||
camera_suite_view_start_get_view(app->camera_suite_view_start));
|
||||
|
||||
app->camera_suite_view_style_1 = camera_suite_view_style_1_alloc();
|
||||
view_dispatcher_add_view(
|
||||
app->view_dispatcher,
|
||||
CameraSuiteViewIdScene1,
|
||||
camera_suite_view_style_1_get_view(app->camera_suite_view_style_1));
|
||||
|
||||
app->camera_suite_view_style_2 = camera_suite_view_style_2_alloc();
|
||||
view_dispatcher_add_view(
|
||||
app->view_dispatcher,
|
||||
CameraSuiteViewIdScene2,
|
||||
camera_suite_view_style_2_get_view(app->camera_suite_view_style_2));
|
||||
|
||||
app->camera_suite_view_guide = camera_suite_view_guide_alloc();
|
||||
view_dispatcher_add_view(
|
||||
app->view_dispatcher,
|
||||
CameraSuiteViewIdGuide,
|
||||
camera_suite_view_guide_get_view(app->camera_suite_view_guide));
|
||||
|
||||
app->button_menu = button_menu_alloc();
|
||||
|
||||
app->variable_item_list = variable_item_list_alloc();
|
||||
view_dispatcher_add_view(
|
||||
app->view_dispatcher,
|
||||
CameraSuiteViewIdSettings,
|
||||
variable_item_list_get_view(app->variable_item_list));
|
||||
|
||||
//End Scene Additions
|
||||
|
||||
return app;
|
||||
}
|
||||
|
||||
void camera_suite_app_free(CameraSuite* app) {
|
||||
furi_assert(app);
|
||||
|
||||
// Scene manager
|
||||
scene_manager_free(app->scene_manager);
|
||||
|
||||
// View Dispatcher
|
||||
view_dispatcher_remove_view(app->view_dispatcher, CameraSuiteViewIdMenu);
|
||||
view_dispatcher_remove_view(app->view_dispatcher, CameraSuiteViewIdScene1);
|
||||
view_dispatcher_remove_view(app->view_dispatcher, CameraSuiteViewIdScene2);
|
||||
view_dispatcher_remove_view(app->view_dispatcher, CameraSuiteViewIdGuide);
|
||||
view_dispatcher_remove_view(app->view_dispatcher, CameraSuiteViewIdSettings);
|
||||
submenu_free(app->submenu);
|
||||
|
||||
view_dispatcher_free(app->view_dispatcher);
|
||||
furi_record_close(RECORD_GUI);
|
||||
|
||||
// Free remaining resources
|
||||
camera_suite_view_start_free(app->camera_suite_view_start);
|
||||
camera_suite_view_style_1_free(app->camera_suite_view_style_1);
|
||||
camera_suite_view_style_2_free(app->camera_suite_view_style_2);
|
||||
camera_suite_view_guide_free(app->camera_suite_view_guide);
|
||||
button_menu_free(app->button_menu);
|
||||
variable_item_list_free(app->variable_item_list);
|
||||
|
||||
app->gui = NULL;
|
||||
app->notification = NULL;
|
||||
|
||||
//Remove whatever is left
|
||||
free(app);
|
||||
}
|
||||
|
||||
/** Main entry point for initialization. */
|
||||
int32_t camera_suite_app(void* p) {
|
||||
UNUSED(p);
|
||||
CameraSuite* app = camera_suite_app_alloc();
|
||||
view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
|
||||
// Init with start scene.
|
||||
scene_manager_next_scene(app->scene_manager, CameraSuiteSceneStart);
|
||||
furi_hal_power_suppress_charge_enter();
|
||||
view_dispatcher_run(app->view_dispatcher);
|
||||
camera_suite_save_settings(app);
|
||||
furi_hal_power_suppress_charge_exit();
|
||||
camera_suite_app_free(app);
|
||||
return 0;
|
||||
}
|
71
applications/external/camera-suite/camera-suite.h
vendored
Normal file
71
applications/external/camera-suite/camera-suite.h
vendored
Normal file
@ -0,0 +1,71 @@
|
||||
#pragma once
|
||||
|
||||
#include "helpers/camera_suite_storage.h"
|
||||
#include "scenes/camera_suite_scene.h"
|
||||
#include "views/camera_suite_view_guide.h"
|
||||
#include "views/camera_suite_view_start.h"
|
||||
#include "views/camera_suite_view_style_1.h"
|
||||
#include "views/camera_suite_view_style_2.h"
|
||||
#include <assets_icons.h>
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
#include <gui/gui.h>
|
||||
#include <gui/modules/button_menu.h>
|
||||
#include <gui/modules/submenu.h>
|
||||
#include <gui/modules/variable_item_list.h>
|
||||
#include <gui/scene_manager.h>
|
||||
#include <gui/view_dispatcher.h>
|
||||
#include <input/input.h>
|
||||
#include <notification/notification_messages.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define TAG "Camera Suite"
|
||||
|
||||
typedef struct {
|
||||
Gui* gui;
|
||||
NotificationApp* notification;
|
||||
ViewDispatcher* view_dispatcher;
|
||||
Submenu* submenu;
|
||||
SceneManager* scene_manager;
|
||||
VariableItemList* variable_item_list;
|
||||
CameraSuiteViewStart* camera_suite_view_start;
|
||||
CameraSuiteViewStyle1* camera_suite_view_style_1;
|
||||
CameraSuiteViewStyle2* camera_suite_view_style_2;
|
||||
CameraSuiteViewGuide* camera_suite_view_guide;
|
||||
uint32_t orientation;
|
||||
uint32_t haptic;
|
||||
uint32_t speaker;
|
||||
uint32_t led;
|
||||
ButtonMenu* button_menu;
|
||||
} CameraSuite;
|
||||
|
||||
typedef enum {
|
||||
CameraSuiteViewIdStartscreen,
|
||||
CameraSuiteViewIdMenu,
|
||||
CameraSuiteViewIdScene1,
|
||||
CameraSuiteViewIdScene2,
|
||||
CameraSuiteViewIdGuide,
|
||||
CameraSuiteViewIdSettings,
|
||||
} CameraSuiteViewId;
|
||||
|
||||
typedef enum {
|
||||
CameraSuiteOrientation0,
|
||||
CameraSuiteOrientation90,
|
||||
CameraSuiteOrientation180,
|
||||
CameraSuiteOrientation270,
|
||||
} CameraSuiteOrientationState;
|
||||
|
||||
typedef enum {
|
||||
CameraSuiteHapticOff,
|
||||
CameraSuiteHapticOn,
|
||||
} CameraSuiteHapticState;
|
||||
|
||||
typedef enum {
|
||||
CameraSuiteSpeakerOff,
|
||||
CameraSuiteSpeakerOn,
|
||||
} CameraSuiteSpeakerState;
|
||||
|
||||
typedef enum {
|
||||
CameraSuiteLedOff,
|
||||
CameraSuiteLedOn,
|
||||
} CameraSuiteLedState;
|
74
applications/external/camera-suite/helpers/camera_suite_custom_event.h
vendored
Normal file
74
applications/external/camera-suite/helpers/camera_suite_custom_event.h
vendored
Normal file
@ -0,0 +1,74 @@
|
||||
#pragma once
|
||||
|
||||
typedef enum {
|
||||
// Scene events: Start menu
|
||||
CameraSuiteCustomEventStartUp,
|
||||
CameraSuiteCustomEventStartDown,
|
||||
CameraSuiteCustomEventStartLeft,
|
||||
CameraSuiteCustomEventStartRight,
|
||||
CameraSuiteCustomEventStartOk,
|
||||
CameraSuiteCustomEventStartBack,
|
||||
// Scene events: Camera style 1
|
||||
CameraSuiteCustomEventSceneStyle1Up,
|
||||
CameraSuiteCustomEventSceneStyle1Down,
|
||||
CameraSuiteCustomEventSceneStyle1Left,
|
||||
CameraSuiteCustomEventSceneStyle1Right,
|
||||
CameraSuiteCustomEventSceneStyle1Ok,
|
||||
CameraSuiteCustomEventSceneStyle1Back,
|
||||
// Scene events: Camera style 2
|
||||
CameraSuiteCustomEventSceneStyle2Up,
|
||||
CameraSuiteCustomEventSceneStyle2Down,
|
||||
CameraSuiteCustomEventSceneStyle2Left,
|
||||
CameraSuiteCustomEventSceneStyle2Right,
|
||||
CameraSuiteCustomEventSceneStyle2Ok,
|
||||
CameraSuiteCustomEventSceneStyle2Back,
|
||||
// Scene events: Guide
|
||||
CameraSuiteCustomEventSceneGuideUp,
|
||||
CameraSuiteCustomEventSceneGuideDown,
|
||||
CameraSuiteCustomEventSceneGuideLeft,
|
||||
CameraSuiteCustomEventSceneGuideRight,
|
||||
CameraSuiteCustomEventSceneGuideOk,
|
||||
CameraSuiteCustomEventSceneGuideBack,
|
||||
} CameraSuiteCustomEvent;
|
||||
|
||||
enum CameraSuiteCustomEventType {
|
||||
// Reserve first 100 events for button types and indexes, starting from 0.
|
||||
CameraSuiteCustomEventMenuVoid,
|
||||
CameraSuiteCustomEventMenuSelected,
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
typedef union {
|
||||
uint32_t packed_value;
|
||||
struct {
|
||||
uint16_t type;
|
||||
int16_t value;
|
||||
} content;
|
||||
} CameraSuiteCustomEventMenu;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
static inline uint32_t camera_suite_custom_menu_event_pack(uint16_t type, int16_t value) {
|
||||
CameraSuiteCustomEventMenu event = {.content = {.type = type, .value = value}};
|
||||
return event.packed_value;
|
||||
}
|
||||
|
||||
static inline void
|
||||
camera_suite_custom_menu_event_unpack(uint32_t packed_value, uint16_t* type, int16_t* value) {
|
||||
CameraSuiteCustomEventMenu event = {.packed_value = packed_value};
|
||||
if(type) *type = event.content.type;
|
||||
if(value) *value = event.content.value;
|
||||
}
|
||||
|
||||
static inline uint16_t camera_suite_custom_menu_event_get_type(uint32_t packed_value) {
|
||||
uint16_t type;
|
||||
camera_suite_custom_menu_event_unpack(packed_value, &type, NULL);
|
||||
return type;
|
||||
}
|
||||
|
||||
static inline int16_t camera_suite_custom_menu_event_get_value(uint32_t packed_value) {
|
||||
int16_t value;
|
||||
camera_suite_custom_menu_event_unpack(packed_value, NULL, &value);
|
||||
return value;
|
||||
}
|
35
applications/external/camera-suite/helpers/camera_suite_haptic.c
vendored
Normal file
35
applications/external/camera-suite/helpers/camera_suite_haptic.c
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
#include "camera_suite_haptic.h"
|
||||
#include "../camera-suite.h"
|
||||
|
||||
void camera_suite_play_happy_bump(void* context) {
|
||||
CameraSuite* app = context;
|
||||
if(app->haptic != 1) {
|
||||
return;
|
||||
}
|
||||
notification_message(app->notification, &sequence_set_vibro_on);
|
||||
furi_thread_flags_wait(0, FuriFlagWaitAny, 20);
|
||||
notification_message(app->notification, &sequence_reset_vibro);
|
||||
}
|
||||
|
||||
void camera_suite_play_bad_bump(void* context) {
|
||||
CameraSuite* app = context;
|
||||
if(app->haptic != 1) {
|
||||
return;
|
||||
}
|
||||
notification_message(app->notification, &sequence_set_vibro_on);
|
||||
furi_thread_flags_wait(0, FuriFlagWaitAny, 100);
|
||||
notification_message(app->notification, &sequence_reset_vibro);
|
||||
}
|
||||
|
||||
void camera_suite_play_long_bump(void* context) {
|
||||
CameraSuite* app = context;
|
||||
if(app->haptic != 1) {
|
||||
return;
|
||||
}
|
||||
for(int i = 0; i < 4; i++) {
|
||||
notification_message(app->notification, &sequence_set_vibro_on);
|
||||
furi_thread_flags_wait(0, FuriFlagWaitAny, 50);
|
||||
notification_message(app->notification, &sequence_reset_vibro);
|
||||
furi_thread_flags_wait(0, FuriFlagWaitAny, 100);
|
||||
}
|
||||
}
|
7
applications/external/camera-suite/helpers/camera_suite_haptic.h
vendored
Normal file
7
applications/external/camera-suite/helpers/camera_suite_haptic.h
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
#include <notification/notification_messages.h>
|
||||
|
||||
void camera_suite_play_happy_bump(void* context);
|
||||
|
||||
void camera_suite_play_bad_bump(void* context);
|
||||
|
||||
void camera_suite_play_long_bump(void* context);
|
38
applications/external/camera-suite/helpers/camera_suite_led.c
vendored
Normal file
38
applications/external/camera-suite/helpers/camera_suite_led.c
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
#include "camera_suite_led.h"
|
||||
#include "../camera-suite.h"
|
||||
|
||||
void camera_suite_led_set_rgb(void* context, int red, int green, int blue) {
|
||||
CameraSuite* app = context;
|
||||
if(app->led != 1) {
|
||||
return;
|
||||
}
|
||||
NotificationMessage notification_led_message_1;
|
||||
notification_led_message_1.type = NotificationMessageTypeLedRed;
|
||||
NotificationMessage notification_led_message_2;
|
||||
notification_led_message_2.type = NotificationMessageTypeLedGreen;
|
||||
NotificationMessage notification_led_message_3;
|
||||
notification_led_message_3.type = NotificationMessageTypeLedBlue;
|
||||
|
||||
notification_led_message_1.data.led.value = red;
|
||||
notification_led_message_2.data.led.value = green;
|
||||
notification_led_message_3.data.led.value = blue;
|
||||
const NotificationSequence notification_sequence = {
|
||||
¬ification_led_message_1,
|
||||
¬ification_led_message_2,
|
||||
¬ification_led_message_3,
|
||||
&message_do_not_reset,
|
||||
NULL,
|
||||
};
|
||||
notification_message(app->notification, ¬ification_sequence);
|
||||
//Delay, prevent removal from RAM before LED value set.
|
||||
furi_thread_flags_wait(0, FuriFlagWaitAny, 10);
|
||||
}
|
||||
|
||||
void camera_suite_led_reset(void* context) {
|
||||
CameraSuite* app = context;
|
||||
notification_message(app->notification, &sequence_reset_red);
|
||||
notification_message(app->notification, &sequence_reset_green);
|
||||
notification_message(app->notification, &sequence_reset_blue);
|
||||
//Delay, prevent removal from RAM before LED value set.
|
||||
furi_thread_flags_wait(0, FuriFlagWaitAny, 300);
|
||||
}
|
3
applications/external/camera-suite/helpers/camera_suite_led.h
vendored
Normal file
3
applications/external/camera-suite/helpers/camera_suite_led.h
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
void camera_suite_led_set_rgb(void* context, int red, int green, int blue);
|
||||
|
||||
void camera_suite_led_reset(void* context);
|
26
applications/external/camera-suite/helpers/camera_suite_speaker.c
vendored
Normal file
26
applications/external/camera-suite/helpers/camera_suite_speaker.c
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
#include "camera_suite_speaker.h"
|
||||
#include "../camera-suite.h"
|
||||
|
||||
#define NOTE_INPUT 587.33f
|
||||
|
||||
void camera_suite_play_input_sound(void* context) {
|
||||
CameraSuite* app = context;
|
||||
if(app->speaker != 1) {
|
||||
return;
|
||||
}
|
||||
float volume = 1.0f;
|
||||
if(furi_hal_speaker_is_mine() || furi_hal_speaker_acquire(30)) {
|
||||
furi_hal_speaker_start(NOTE_INPUT, volume);
|
||||
}
|
||||
}
|
||||
|
||||
void camera_suite_stop_all_sound(void* context) {
|
||||
CameraSuite* app = context;
|
||||
if(app->speaker != 1) {
|
||||
return;
|
||||
}
|
||||
if(furi_hal_speaker_is_mine()) {
|
||||
furi_hal_speaker_stop();
|
||||
furi_hal_speaker_release();
|
||||
}
|
||||
}
|
5
applications/external/camera-suite/helpers/camera_suite_speaker.h
vendored
Normal file
5
applications/external/camera-suite/helpers/camera_suite_speaker.h
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
#define NOTE_INPUT 587.33f
|
||||
|
||||
void camera_suite_play_input_sound(void* context);
|
||||
|
||||
void camera_suite_stop_all_sound(void* context);
|
113
applications/external/camera-suite/helpers/camera_suite_storage.c
vendored
Normal file
113
applications/external/camera-suite/helpers/camera_suite_storage.c
vendored
Normal file
@ -0,0 +1,113 @@
|
||||
#include "camera_suite_storage.h"
|
||||
|
||||
static Storage* camera_suite_open_storage() {
|
||||
return furi_record_open(RECORD_STORAGE);
|
||||
}
|
||||
|
||||
static void camera_suite_close_storage() {
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
}
|
||||
|
||||
static void camera_suite_close_config_file(FlipperFormat* file) {
|
||||
if(file == NULL) return;
|
||||
flipper_format_file_close(file);
|
||||
flipper_format_free(file);
|
||||
}
|
||||
|
||||
void camera_suite_save_settings(void* context) {
|
||||
CameraSuite* app = context;
|
||||
|
||||
FURI_LOG_D(TAG, "Saving Settings");
|
||||
Storage* storage = camera_suite_open_storage();
|
||||
FlipperFormat* fff_file = flipper_format_file_alloc(storage);
|
||||
|
||||
// Overwrite wont work, so delete first
|
||||
if(storage_file_exists(storage, BOILERPLATE_SETTINGS_SAVE_PATH)) {
|
||||
storage_simply_remove(storage, BOILERPLATE_SETTINGS_SAVE_PATH);
|
||||
}
|
||||
|
||||
// Open File, create if not exists
|
||||
if(!storage_common_stat(storage, BOILERPLATE_SETTINGS_SAVE_PATH, NULL) == FSE_OK) {
|
||||
FURI_LOG_D(
|
||||
TAG, "Config file %s is not found. Will create new.", BOILERPLATE_SETTINGS_SAVE_PATH);
|
||||
if(storage_common_stat(storage, CONFIG_FILE_DIRECTORY_PATH, NULL) == FSE_NOT_EXIST) {
|
||||
FURI_LOG_D(
|
||||
TAG, "Directory %s doesn't exist. Will create new.", CONFIG_FILE_DIRECTORY_PATH);
|
||||
if(!storage_simply_mkdir(storage, CONFIG_FILE_DIRECTORY_PATH)) {
|
||||
FURI_LOG_E(TAG, "Error creating directory %s", CONFIG_FILE_DIRECTORY_PATH);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!flipper_format_file_open_new(fff_file, BOILERPLATE_SETTINGS_SAVE_PATH)) {
|
||||
//totp_close_config_file(fff_file);
|
||||
FURI_LOG_E(TAG, "Error creating new file %s", BOILERPLATE_SETTINGS_SAVE_PATH);
|
||||
camera_suite_close_storage();
|
||||
return;
|
||||
}
|
||||
|
||||
// Store Settings
|
||||
flipper_format_write_header_cstr(
|
||||
fff_file, BOILERPLATE_SETTINGS_HEADER, BOILERPLATE_SETTINGS_FILE_VERSION);
|
||||
flipper_format_write_uint32(
|
||||
fff_file, BOILERPLATE_SETTINGS_KEY_ORIENTATION, &app->orientation, 1);
|
||||
flipper_format_write_uint32(fff_file, BOILERPLATE_SETTINGS_KEY_HAPTIC, &app->haptic, 1);
|
||||
flipper_format_write_uint32(fff_file, BOILERPLATE_SETTINGS_KEY_SPEAKER, &app->speaker, 1);
|
||||
flipper_format_write_uint32(fff_file, BOILERPLATE_SETTINGS_KEY_LED, &app->led, 1);
|
||||
|
||||
if(!flipper_format_rewind(fff_file)) {
|
||||
camera_suite_close_config_file(fff_file);
|
||||
FURI_LOG_E(TAG, "Rewind error");
|
||||
camera_suite_close_storage();
|
||||
return;
|
||||
}
|
||||
|
||||
camera_suite_close_config_file(fff_file);
|
||||
camera_suite_close_storage();
|
||||
}
|
||||
|
||||
void camera_suite_read_settings(void* context) {
|
||||
CameraSuite* app = context;
|
||||
Storage* storage = camera_suite_open_storage();
|
||||
FlipperFormat* fff_file = flipper_format_file_alloc(storage);
|
||||
|
||||
if(storage_common_stat(storage, BOILERPLATE_SETTINGS_SAVE_PATH, NULL) != FSE_OK) {
|
||||
camera_suite_close_config_file(fff_file);
|
||||
camera_suite_close_storage();
|
||||
return;
|
||||
}
|
||||
uint32_t file_version;
|
||||
FuriString* temp_str = furi_string_alloc();
|
||||
|
||||
if(!flipper_format_file_open_existing(fff_file, BOILERPLATE_SETTINGS_SAVE_PATH)) {
|
||||
FURI_LOG_E(TAG, "Cannot open file %s", BOILERPLATE_SETTINGS_SAVE_PATH);
|
||||
camera_suite_close_config_file(fff_file);
|
||||
camera_suite_close_storage();
|
||||
return;
|
||||
}
|
||||
|
||||
if(!flipper_format_read_header(fff_file, temp_str, &file_version)) {
|
||||
FURI_LOG_E(TAG, "Missing Header Data");
|
||||
camera_suite_close_config_file(fff_file);
|
||||
camera_suite_close_storage();
|
||||
return;
|
||||
}
|
||||
|
||||
if(file_version < BOILERPLATE_SETTINGS_FILE_VERSION) {
|
||||
FURI_LOG_I(TAG, "old config version, will be removed.");
|
||||
camera_suite_close_config_file(fff_file);
|
||||
camera_suite_close_storage();
|
||||
return;
|
||||
}
|
||||
|
||||
flipper_format_read_uint32(
|
||||
fff_file, BOILERPLATE_SETTINGS_KEY_ORIENTATION, &app->orientation, 1);
|
||||
flipper_format_read_uint32(fff_file, BOILERPLATE_SETTINGS_KEY_HAPTIC, &app->haptic, 1);
|
||||
flipper_format_read_uint32(fff_file, BOILERPLATE_SETTINGS_KEY_SPEAKER, &app->speaker, 1);
|
||||
flipper_format_read_uint32(fff_file, BOILERPLATE_SETTINGS_KEY_LED, &app->led, 1);
|
||||
|
||||
flipper_format_rewind(fff_file);
|
||||
|
||||
camera_suite_close_config_file(fff_file);
|
||||
camera_suite_close_storage();
|
||||
}
|
20
applications/external/camera-suite/helpers/camera_suite_storage.h
vendored
Normal file
20
applications/external/camera-suite/helpers/camera_suite_storage.h
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <storage/storage.h>
|
||||
#include <flipper_format/flipper_format_i.h>
|
||||
#include "../camera-suite.h"
|
||||
|
||||
#define BOILERPLATE_SETTINGS_FILE_VERSION 1
|
||||
#define CONFIG_FILE_DIRECTORY_PATH EXT_PATH("apps_data/camera-suite")
|
||||
#define BOILERPLATE_SETTINGS_SAVE_PATH CONFIG_FILE_DIRECTORY_PATH "/camera-suite.conf"
|
||||
#define BOILERPLATE_SETTINGS_SAVE_PATH_TMP BOILERPLATE_SETTINGS_SAVE_PATH ".tmp"
|
||||
#define BOILERPLATE_SETTINGS_HEADER "Camera Suite Config File"
|
||||
#define BOILERPLATE_SETTINGS_KEY_ORIENTATION "Orientation"
|
||||
#define BOILERPLATE_SETTINGS_KEY_HAPTIC "Haptic"
|
||||
#define BOILERPLATE_SETTINGS_KEY_LED "Led"
|
||||
#define BOILERPLATE_SETTINGS_KEY_SPEAKER "Speaker"
|
||||
#define BOILERPLATE_SETTINGS_KEY_SAVE_SETTINGS "SaveSettings"
|
||||
|
||||
void camera_suite_save_settings(void* context);
|
||||
|
||||
void camera_suite_read_settings(void* context);
|
BIN
applications/external/camera-suite/icons/camera-suite.png
vendored
Normal file
BIN
applications/external/camera-suite/icons/camera-suite.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.3 KiB |
30
applications/external/camera-suite/scenes/camera_suite_scene.c
vendored
Normal file
30
applications/external/camera-suite/scenes/camera_suite_scene.c
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
#include "camera_suite_scene.h"
|
||||
|
||||
// Generate scene on_enter handlers array
|
||||
#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter,
|
||||
void (*const camera_suite_on_enter_handlers[])(void*) = {
|
||||
#include "camera_suite_scene_config.h"
|
||||
};
|
||||
#undef ADD_SCENE
|
||||
|
||||
// Generate scene on_event handlers array
|
||||
#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_event,
|
||||
bool (*const camera_suite_on_event_handlers[])(void* context, SceneManagerEvent event) = {
|
||||
#include "camera_suite_scene_config.h"
|
||||
};
|
||||
#undef ADD_SCENE
|
||||
|
||||
// Generate scene on_exit handlers array
|
||||
#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_exit,
|
||||
void (*const camera_suite_on_exit_handlers[])(void* context) = {
|
||||
#include "camera_suite_scene_config.h"
|
||||
};
|
||||
#undef ADD_SCENE
|
||||
|
||||
// Initialize scene handlers configuration structure
|
||||
const SceneManagerHandlers camera_suite_scene_handlers = {
|
||||
.on_enter_handlers = camera_suite_on_enter_handlers,
|
||||
.on_event_handlers = camera_suite_on_event_handlers,
|
||||
.on_exit_handlers = camera_suite_on_exit_handlers,
|
||||
.scene_num = CameraSuiteSceneNum,
|
||||
};
|
29
applications/external/camera-suite/scenes/camera_suite_scene.h
vendored
Normal file
29
applications/external/camera-suite/scenes/camera_suite_scene.h
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include <gui/scene_manager.h>
|
||||
|
||||
// Generate scene id and total number
|
||||
#define ADD_SCENE(prefix, name, id) CameraSuiteScene##id,
|
||||
typedef enum {
|
||||
#include "camera_suite_scene_config.h"
|
||||
CameraSuiteSceneNum,
|
||||
} CameraSuiteScene;
|
||||
#undef ADD_SCENE
|
||||
|
||||
extern const SceneManagerHandlers camera_suite_scene_handlers;
|
||||
|
||||
// Generate scene on_enter handlers declaration
|
||||
#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*);
|
||||
#include "camera_suite_scene_config.h"
|
||||
#undef ADD_SCENE
|
||||
|
||||
// Generate scene on_event handlers declaration
|
||||
#define ADD_SCENE(prefix, name, id) \
|
||||
bool prefix##_scene_##name##_on_event(void* context, SceneManagerEvent event);
|
||||
#include "camera_suite_scene_config.h"
|
||||
#undef ADD_SCENE
|
||||
|
||||
// Generate scene on_exit handlers declaration
|
||||
#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_exit(void* context);
|
||||
#include "camera_suite_scene_config.h"
|
||||
#undef ADD_SCENE
|
6
applications/external/camera-suite/scenes/camera_suite_scene_config.h
vendored
Normal file
6
applications/external/camera-suite/scenes/camera_suite_scene_config.h
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
ADD_SCENE(camera_suite, start, Start)
|
||||
ADD_SCENE(camera_suite, menu, Menu)
|
||||
ADD_SCENE(camera_suite, style_1, Style_1)
|
||||
ADD_SCENE(camera_suite, style_2, Style_2)
|
||||
ADD_SCENE(camera_suite, guide, Guide)
|
||||
ADD_SCENE(camera_suite, settings, Settings)
|
51
applications/external/camera-suite/scenes/camera_suite_scene_guide.c
vendored
Normal file
51
applications/external/camera-suite/scenes/camera_suite_scene_guide.c
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
#include "../camera-suite.h"
|
||||
#include "../helpers/camera_suite_custom_event.h"
|
||||
#include "../views/camera_suite_view_guide.h"
|
||||
|
||||
void camera_suite_view_guide_callback(CameraSuiteCustomEvent event, void* context) {
|
||||
furi_assert(context);
|
||||
CameraSuite* app = context;
|
||||
view_dispatcher_send_custom_event(app->view_dispatcher, event);
|
||||
}
|
||||
|
||||
void camera_suite_scene_guide_on_enter(void* context) {
|
||||
furi_assert(context);
|
||||
CameraSuite* app = context;
|
||||
camera_suite_view_guide_set_callback(
|
||||
app->camera_suite_view_guide, camera_suite_view_guide_callback, app);
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, CameraSuiteViewIdGuide);
|
||||
}
|
||||
|
||||
bool camera_suite_scene_guide_on_event(void* context, SceneManagerEvent event) {
|
||||
CameraSuite* app = context;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
switch(event.event) {
|
||||
case CameraSuiteCustomEventSceneGuideLeft:
|
||||
case CameraSuiteCustomEventSceneGuideRight:
|
||||
case CameraSuiteCustomEventSceneGuideUp:
|
||||
case CameraSuiteCustomEventSceneGuideDown:
|
||||
// Do nothing.
|
||||
break;
|
||||
case CameraSuiteCustomEventSceneGuideBack:
|
||||
notification_message(app->notification, &sequence_reset_red);
|
||||
notification_message(app->notification, &sequence_reset_green);
|
||||
notification_message(app->notification, &sequence_reset_blue);
|
||||
if(!scene_manager_search_and_switch_to_previous_scene(
|
||||
app->scene_manager, CameraSuiteSceneMenu)) {
|
||||
scene_manager_stop(app->scene_manager);
|
||||
view_dispatcher_stop(app->view_dispatcher);
|
||||
}
|
||||
consumed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void camera_suite_scene_guide_on_exit(void* context) {
|
||||
CameraSuite* app = context;
|
||||
UNUSED(app);
|
||||
}
|
87
applications/external/camera-suite/scenes/camera_suite_scene_menu.c
vendored
Normal file
87
applications/external/camera-suite/scenes/camera_suite_scene_menu.c
vendored
Normal file
@ -0,0 +1,87 @@
|
||||
#include "../camera-suite.h"
|
||||
|
||||
enum SubmenuIndex {
|
||||
/** Atkinson Dithering Algorithm. */
|
||||
SubmenuIndexSceneStyle1 = 10,
|
||||
/** Floyd-Steinberg Dithering Algorithm. */
|
||||
SubmenuIndexSceneStyle2,
|
||||
/** Guide/how-to. */
|
||||
SubmenuIndexGuide,
|
||||
/** Settings menu. */
|
||||
SubmenuIndexSettings,
|
||||
};
|
||||
|
||||
void camera_suite_scene_menu_submenu_callback(void* context, uint32_t index) {
|
||||
CameraSuite* app = context;
|
||||
view_dispatcher_send_custom_event(app->view_dispatcher, index);
|
||||
}
|
||||
|
||||
void camera_suite_scene_menu_on_enter(void* context) {
|
||||
CameraSuite* app = context;
|
||||
|
||||
submenu_add_item(
|
||||
app->submenu,
|
||||
"Open Camera",
|
||||
SubmenuIndexSceneStyle1,
|
||||
camera_suite_scene_menu_submenu_callback,
|
||||
app);
|
||||
// Staged view for the future.
|
||||
// submenu_add_item(
|
||||
// app->submenu,
|
||||
// "Test",
|
||||
// SubmenuIndexSceneStyle2,
|
||||
// camera_suite_scene_menu_submenu_callback,
|
||||
// app);
|
||||
submenu_add_item(
|
||||
app->submenu, "Guide", SubmenuIndexGuide, camera_suite_scene_menu_submenu_callback, app);
|
||||
submenu_add_item(
|
||||
app->submenu,
|
||||
"Settings",
|
||||
SubmenuIndexSettings,
|
||||
camera_suite_scene_menu_submenu_callback,
|
||||
app);
|
||||
|
||||
submenu_set_selected_item(
|
||||
app->submenu, scene_manager_get_scene_state(app->scene_manager, CameraSuiteSceneMenu));
|
||||
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, CameraSuiteViewIdMenu);
|
||||
}
|
||||
|
||||
bool camera_suite_scene_menu_on_event(void* context, SceneManagerEvent event) {
|
||||
CameraSuite* app = context;
|
||||
UNUSED(app);
|
||||
if(event.type == SceneManagerEventTypeBack) {
|
||||
// Exit application.
|
||||
scene_manager_stop(app->scene_manager);
|
||||
view_dispatcher_stop(app->view_dispatcher);
|
||||
return true;
|
||||
} else if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == SubmenuIndexSceneStyle1) {
|
||||
scene_manager_set_scene_state(
|
||||
app->scene_manager, CameraSuiteSceneMenu, SubmenuIndexSceneStyle1);
|
||||
scene_manager_next_scene(app->scene_manager, CameraSuiteSceneStyle_1);
|
||||
return true;
|
||||
} else if(event.event == SubmenuIndexSceneStyle2) {
|
||||
scene_manager_set_scene_state(
|
||||
app->scene_manager, CameraSuiteSceneMenu, SubmenuIndexSceneStyle2);
|
||||
scene_manager_next_scene(app->scene_manager, CameraSuiteSceneStyle_2);
|
||||
return true;
|
||||
} else if(event.event == SubmenuIndexGuide) {
|
||||
scene_manager_set_scene_state(
|
||||
app->scene_manager, CameraSuiteSceneMenu, SubmenuIndexGuide);
|
||||
scene_manager_next_scene(app->scene_manager, CameraSuiteSceneGuide);
|
||||
return true;
|
||||
} else if(event.event == SubmenuIndexSettings) {
|
||||
scene_manager_set_scene_state(
|
||||
app->scene_manager, CameraSuiteSceneMenu, SubmenuIndexSettings);
|
||||
scene_manager_next_scene(app->scene_manager, CameraSuiteSceneSettings);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void camera_suite_scene_menu_on_exit(void* context) {
|
||||
CameraSuite* app = context;
|
||||
submenu_reset(app->submenu);
|
||||
}
|
137
applications/external/camera-suite/scenes/camera_suite_scene_settings.c
vendored
Normal file
137
applications/external/camera-suite/scenes/camera_suite_scene_settings.c
vendored
Normal file
@ -0,0 +1,137 @@
|
||||
#include "../camera-suite.h"
|
||||
#include <lib/toolbox/value_index.h>
|
||||
|
||||
// Camera orientation, in degrees.
|
||||
const char* const orientation_text[4] = {
|
||||
"0",
|
||||
"90",
|
||||
"180",
|
||||
"270",
|
||||
};
|
||||
|
||||
const uint32_t orientation_value[4] = {
|
||||
CameraSuiteOrientation0,
|
||||
CameraSuiteOrientation90,
|
||||
CameraSuiteOrientation180,
|
||||
CameraSuiteOrientation270,
|
||||
};
|
||||
|
||||
const char* const haptic_text[2] = {
|
||||
"OFF",
|
||||
"ON",
|
||||
};
|
||||
|
||||
const uint32_t haptic_value[2] = {
|
||||
CameraSuiteHapticOff,
|
||||
CameraSuiteHapticOn,
|
||||
};
|
||||
|
||||
const char* const speaker_text[2] = {
|
||||
"OFF",
|
||||
"ON",
|
||||
};
|
||||
|
||||
const uint32_t speaker_value[2] = {
|
||||
CameraSuiteSpeakerOff,
|
||||
CameraSuiteSpeakerOn,
|
||||
};
|
||||
|
||||
const char* const led_text[2] = {
|
||||
"OFF",
|
||||
"ON",
|
||||
};
|
||||
|
||||
const uint32_t led_value[2] = {
|
||||
CameraSuiteLedOff,
|
||||
CameraSuiteLedOn,
|
||||
};
|
||||
|
||||
static void camera_suite_scene_settings_set_camera_orientation(VariableItem* item) {
|
||||
CameraSuite* app = variable_item_get_context(item);
|
||||
uint8_t index = variable_item_get_current_value_index(item);
|
||||
|
||||
variable_item_set_current_value_text(item, orientation_text[index]);
|
||||
app->orientation = orientation_value[index];
|
||||
}
|
||||
|
||||
static void camera_suite_scene_settings_set_haptic(VariableItem* item) {
|
||||
CameraSuite* app = variable_item_get_context(item);
|
||||
uint8_t index = variable_item_get_current_value_index(item);
|
||||
|
||||
variable_item_set_current_value_text(item, haptic_text[index]);
|
||||
app->haptic = haptic_value[index];
|
||||
}
|
||||
|
||||
static void camera_suite_scene_settings_set_speaker(VariableItem* item) {
|
||||
CameraSuite* app = variable_item_get_context(item);
|
||||
uint8_t index = variable_item_get_current_value_index(item);
|
||||
variable_item_set_current_value_text(item, speaker_text[index]);
|
||||
app->speaker = speaker_value[index];
|
||||
}
|
||||
|
||||
static void camera_suite_scene_settings_set_led(VariableItem* item) {
|
||||
CameraSuite* app = variable_item_get_context(item);
|
||||
uint8_t index = variable_item_get_current_value_index(item);
|
||||
variable_item_set_current_value_text(item, led_text[index]);
|
||||
app->led = led_value[index];
|
||||
}
|
||||
|
||||
void camera_suite_scene_settings_submenu_callback(void* context, uint32_t index) {
|
||||
CameraSuite* app = context;
|
||||
view_dispatcher_send_custom_event(app->view_dispatcher, index);
|
||||
}
|
||||
|
||||
void camera_suite_scene_settings_on_enter(void* context) {
|
||||
CameraSuite* app = context;
|
||||
VariableItem* item;
|
||||
uint8_t value_index;
|
||||
|
||||
// Camera Orientation
|
||||
item = variable_item_list_add(
|
||||
app->variable_item_list,
|
||||
"Orientation:",
|
||||
4,
|
||||
camera_suite_scene_settings_set_camera_orientation,
|
||||
app);
|
||||
value_index = value_index_uint32(app->orientation, orientation_value, 4);
|
||||
variable_item_set_current_value_index(item, value_index);
|
||||
variable_item_set_current_value_text(item, orientation_text[value_index]);
|
||||
|
||||
// Haptic FX ON/OFF
|
||||
item = variable_item_list_add(
|
||||
app->variable_item_list, "Haptic FX:", 2, camera_suite_scene_settings_set_haptic, app);
|
||||
value_index = value_index_uint32(app->haptic, haptic_value, 2);
|
||||
variable_item_set_current_value_index(item, value_index);
|
||||
variable_item_set_current_value_text(item, haptic_text[value_index]);
|
||||
|
||||
// Sound FX ON/OFF
|
||||
item = variable_item_list_add(
|
||||
app->variable_item_list, "Sound FX:", 2, camera_suite_scene_settings_set_speaker, app);
|
||||
value_index = value_index_uint32(app->speaker, speaker_value, 2);
|
||||
variable_item_set_current_value_index(item, value_index);
|
||||
variable_item_set_current_value_text(item, speaker_text[value_index]);
|
||||
|
||||
// LED FX ON/OFF
|
||||
item = variable_item_list_add(
|
||||
app->variable_item_list, "LED FX:", 2, camera_suite_scene_settings_set_led, app);
|
||||
value_index = value_index_uint32(app->led, led_value, 2);
|
||||
variable_item_set_current_value_index(item, value_index);
|
||||
variable_item_set_current_value_text(item, led_text[value_index]);
|
||||
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, CameraSuiteViewIdSettings);
|
||||
}
|
||||
|
||||
bool camera_suite_scene_settings_on_event(void* context, SceneManagerEvent event) {
|
||||
CameraSuite* app = context;
|
||||
UNUSED(app);
|
||||
bool consumed = false;
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
}
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void camera_suite_scene_settings_on_exit(void* context) {
|
||||
CameraSuite* app = context;
|
||||
variable_item_list_set_selected_item(app->variable_item_list, 0);
|
||||
variable_item_list_reset(app->variable_item_list);
|
||||
}
|
55
applications/external/camera-suite/scenes/camera_suite_scene_start.c
vendored
Normal file
55
applications/external/camera-suite/scenes/camera_suite_scene_start.c
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
#include "../camera-suite.h"
|
||||
#include "../helpers/camera_suite_custom_event.h"
|
||||
#include "../views/camera_suite_view_start.h"
|
||||
|
||||
void camera_suite_scene_start_callback(CameraSuiteCustomEvent event, void* context) {
|
||||
furi_assert(context);
|
||||
CameraSuite* app = context;
|
||||
view_dispatcher_send_custom_event(app->view_dispatcher, event);
|
||||
}
|
||||
|
||||
void camera_suite_scene_start_on_enter(void* context) {
|
||||
furi_assert(context);
|
||||
CameraSuite* app = context;
|
||||
camera_suite_view_start_set_callback(
|
||||
app->camera_suite_view_start, camera_suite_scene_start_callback, app);
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, CameraSuiteViewIdStartscreen);
|
||||
}
|
||||
|
||||
bool camera_suite_scene_start_on_event(void* context, SceneManagerEvent event) {
|
||||
CameraSuite* app = context;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
switch(event.event) {
|
||||
case CameraSuiteCustomEventStartLeft:
|
||||
case CameraSuiteCustomEventStartRight:
|
||||
break;
|
||||
case CameraSuiteCustomEventStartUp:
|
||||
case CameraSuiteCustomEventStartDown:
|
||||
break;
|
||||
case CameraSuiteCustomEventStartOk:
|
||||
scene_manager_next_scene(app->scene_manager, CameraSuiteSceneMenu);
|
||||
consumed = true;
|
||||
break;
|
||||
case CameraSuiteCustomEventStartBack:
|
||||
notification_message(app->notification, &sequence_reset_red);
|
||||
notification_message(app->notification, &sequence_reset_green);
|
||||
notification_message(app->notification, &sequence_reset_blue);
|
||||
if(!scene_manager_search_and_switch_to_previous_scene(
|
||||
app->scene_manager, CameraSuiteSceneStart)) {
|
||||
scene_manager_stop(app->scene_manager);
|
||||
view_dispatcher_stop(app->view_dispatcher);
|
||||
}
|
||||
consumed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void camera_suite_scene_start_on_exit(void* context) {
|
||||
CameraSuite* app = context;
|
||||
UNUSED(app);
|
||||
}
|
52
applications/external/camera-suite/scenes/camera_suite_scene_style_1.c
vendored
Normal file
52
applications/external/camera-suite/scenes/camera_suite_scene_style_1.c
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
#include "../camera-suite.h"
|
||||
#include "../helpers/camera_suite_custom_event.h"
|
||||
#include "../views/camera_suite_view_style_1.h"
|
||||
|
||||
static void camera_suite_view_style_1_callback(CameraSuiteCustomEvent event, void* context) {
|
||||
furi_assert(context);
|
||||
CameraSuite* app = context;
|
||||
view_dispatcher_send_custom_event(app->view_dispatcher, event);
|
||||
}
|
||||
|
||||
void camera_suite_scene_style_1_on_enter(void* context) {
|
||||
furi_assert(context);
|
||||
CameraSuite* app = context;
|
||||
camera_suite_view_style_1_set_callback(
|
||||
app->camera_suite_view_style_1, camera_suite_view_style_1_callback, app);
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, CameraSuiteViewIdScene1);
|
||||
}
|
||||
|
||||
bool camera_suite_scene_style_1_on_event(void* context, SceneManagerEvent event) {
|
||||
CameraSuite* app = context;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
switch(event.event) {
|
||||
case CameraSuiteCustomEventSceneStyle1Left:
|
||||
case CameraSuiteCustomEventSceneStyle1Right:
|
||||
case CameraSuiteCustomEventSceneStyle1Up:
|
||||
case CameraSuiteCustomEventSceneStyle1Down:
|
||||
case CameraSuiteCustomEventSceneStyle1Ok:
|
||||
// Do nothing.
|
||||
break;
|
||||
case CameraSuiteCustomEventSceneStyle1Back:
|
||||
notification_message(app->notification, &sequence_reset_red);
|
||||
notification_message(app->notification, &sequence_reset_green);
|
||||
notification_message(app->notification, &sequence_reset_blue);
|
||||
if(!scene_manager_search_and_switch_to_previous_scene(
|
||||
app->scene_manager, CameraSuiteSceneMenu)) {
|
||||
scene_manager_stop(app->scene_manager);
|
||||
view_dispatcher_stop(app->view_dispatcher);
|
||||
}
|
||||
consumed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void camera_suite_scene_style_1_on_exit(void* context) {
|
||||
CameraSuite* app = context;
|
||||
UNUSED(app);
|
||||
}
|
54
applications/external/camera-suite/scenes/camera_suite_scene_style_2.c
vendored
Normal file
54
applications/external/camera-suite/scenes/camera_suite_scene_style_2.c
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
#include "../camera-suite.h"
|
||||
#include "../helpers/camera_suite_custom_event.h"
|
||||
#include "../helpers/camera_suite_haptic.h"
|
||||
#include "../helpers/camera_suite_led.h"
|
||||
#include "../views/camera_suite_view_style_2.h"
|
||||
|
||||
void camera_suite_view_style_2_callback(CameraSuiteCustomEvent event, void* context) {
|
||||
furi_assert(context);
|
||||
CameraSuite* app = context;
|
||||
view_dispatcher_send_custom_event(app->view_dispatcher, event);
|
||||
}
|
||||
|
||||
void camera_suite_scene_style_2_on_enter(void* context) {
|
||||
furi_assert(context);
|
||||
CameraSuite* app = context;
|
||||
camera_suite_view_style_2_set_callback(
|
||||
app->camera_suite_view_style_2, camera_suite_view_style_2_callback, app);
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, CameraSuiteViewIdScene2);
|
||||
}
|
||||
|
||||
bool camera_suite_scene_style_2_on_event(void* context, SceneManagerEvent event) {
|
||||
CameraSuite* app = context;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
switch(event.event) {
|
||||
case CameraSuiteCustomEventSceneStyle2Left:
|
||||
case CameraSuiteCustomEventSceneStyle2Right:
|
||||
case CameraSuiteCustomEventSceneStyle2Up:
|
||||
case CameraSuiteCustomEventSceneStyle2Down:
|
||||
case CameraSuiteCustomEventSceneStyle2Ok:
|
||||
// Do nothing.
|
||||
break;
|
||||
case CameraSuiteCustomEventSceneStyle2Back:
|
||||
notification_message(app->notification, &sequence_reset_red);
|
||||
notification_message(app->notification, &sequence_reset_green);
|
||||
notification_message(app->notification, &sequence_reset_blue);
|
||||
if(!scene_manager_search_and_switch_to_previous_scene(
|
||||
app->scene_manager, CameraSuiteSceneMenu)) {
|
||||
scene_manager_stop(app->scene_manager);
|
||||
view_dispatcher_stop(app->view_dispatcher);
|
||||
}
|
||||
consumed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void camera_suite_scene_style_2_on_exit(void* context) {
|
||||
CameraSuite* app = context;
|
||||
UNUSED(app);
|
||||
}
|
120
applications/external/camera-suite/views/camera_suite_view_guide.c
vendored
Normal file
120
applications/external/camera-suite/views/camera_suite_view_guide.c
vendored
Normal file
@ -0,0 +1,120 @@
|
||||
#include "../camera-suite.h"
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
#include <input/input.h>
|
||||
#include <gui/elements.h>
|
||||
#include <dolphin/dolphin.h>
|
||||
|
||||
struct CameraSuiteViewGuide {
|
||||
View* view;
|
||||
CameraSuiteViewGuideCallback callback;
|
||||
void* context;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
int some_value;
|
||||
} CameraSuiteViewGuideModel;
|
||||
|
||||
void camera_suite_view_guide_set_callback(
|
||||
CameraSuiteViewGuide* instance,
|
||||
CameraSuiteViewGuideCallback callback,
|
||||
void* context) {
|
||||
furi_assert(instance);
|
||||
furi_assert(callback);
|
||||
instance->callback = callback;
|
||||
instance->context = context;
|
||||
}
|
||||
|
||||
void camera_suite_view_guide_draw(Canvas* canvas, CameraSuiteViewGuideModel* model) {
|
||||
UNUSED(model);
|
||||
canvas_clear(canvas);
|
||||
canvas_set_color(canvas, ColorBlack);
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str_aligned(canvas, 0, 0, AlignLeft, AlignTop, "Guide");
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
canvas_draw_str_aligned(canvas, 0, 12, AlignLeft, AlignTop, "Left = Toggle Invert");
|
||||
canvas_draw_str_aligned(canvas, 0, 22, AlignLeft, AlignTop, "Right = Toggle Dithering");
|
||||
canvas_draw_str_aligned(canvas, 0, 32, AlignLeft, AlignTop, "Up = Contrast Up");
|
||||
canvas_draw_str_aligned(canvas, 0, 42, AlignLeft, AlignTop, "Down = Contrast Down");
|
||||
// TODO: Possibly update to take picture instead.
|
||||
canvas_draw_str_aligned(canvas, 0, 52, AlignLeft, AlignTop, "Center = Toggle Dither Type");
|
||||
}
|
||||
|
||||
static void camera_suite_view_guide_model_init(CameraSuiteViewGuideModel* const model) {
|
||||
model->some_value = 1;
|
||||
}
|
||||
|
||||
bool camera_suite_view_guide_input(InputEvent* event, void* context) {
|
||||
furi_assert(context);
|
||||
CameraSuiteViewGuide* instance = context;
|
||||
if(event->type == InputTypeRelease) {
|
||||
switch(event->key) {
|
||||
case InputKeyBack:
|
||||
with_view_model(
|
||||
instance->view,
|
||||
CameraSuiteViewGuideModel * model,
|
||||
{
|
||||
UNUSED(model);
|
||||
instance->callback(CameraSuiteCustomEventSceneGuideBack, instance->context);
|
||||
},
|
||||
true);
|
||||
break;
|
||||
case InputKeyLeft:
|
||||
case InputKeyRight:
|
||||
case InputKeyUp:
|
||||
case InputKeyDown:
|
||||
case InputKeyOk:
|
||||
case InputKeyMAX:
|
||||
// Do nothing.
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void camera_suite_view_guide_exit(void* context) {
|
||||
furi_assert(context);
|
||||
}
|
||||
|
||||
void camera_suite_view_guide_enter(void* context) {
|
||||
furi_assert(context);
|
||||
CameraSuiteViewGuide* instance = (CameraSuiteViewGuide*)context;
|
||||
with_view_model(
|
||||
instance->view,
|
||||
CameraSuiteViewGuideModel * model,
|
||||
{ camera_suite_view_guide_model_init(model); },
|
||||
true);
|
||||
}
|
||||
|
||||
CameraSuiteViewGuide* camera_suite_view_guide_alloc() {
|
||||
CameraSuiteViewGuide* instance = malloc(sizeof(CameraSuiteViewGuide));
|
||||
instance->view = view_alloc();
|
||||
view_allocate_model(instance->view, ViewModelTypeLocking, sizeof(CameraSuiteViewGuideModel));
|
||||
view_set_context(instance->view, instance); // furi_assert crashes in events without this
|
||||
view_set_draw_callback(instance->view, (ViewDrawCallback)camera_suite_view_guide_draw);
|
||||
view_set_input_callback(instance->view, camera_suite_view_guide_input);
|
||||
view_set_enter_callback(instance->view, camera_suite_view_guide_enter);
|
||||
view_set_exit_callback(instance->view, camera_suite_view_guide_exit);
|
||||
|
||||
with_view_model(
|
||||
instance->view,
|
||||
CameraSuiteViewGuideModel * model,
|
||||
{ camera_suite_view_guide_model_init(model); },
|
||||
true);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
void camera_suite_view_guide_free(CameraSuiteViewGuide* instance) {
|
||||
furi_assert(instance);
|
||||
|
||||
with_view_model(
|
||||
instance->view, CameraSuiteViewGuideModel * model, { UNUSED(model); }, true);
|
||||
view_free(instance->view);
|
||||
free(instance);
|
||||
}
|
||||
|
||||
View* camera_suite_view_guide_get_view(CameraSuiteViewGuide* instance) {
|
||||
furi_assert(instance);
|
||||
return instance->view;
|
||||
}
|
19
applications/external/camera-suite/views/camera_suite_view_guide.h
vendored
Normal file
19
applications/external/camera-suite/views/camera_suite_view_guide.h
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <gui/view.h>
|
||||
#include "../helpers/camera_suite_custom_event.h"
|
||||
|
||||
typedef struct CameraSuiteViewGuide CameraSuiteViewGuide;
|
||||
|
||||
typedef void (*CameraSuiteViewGuideCallback)(CameraSuiteCustomEvent event, void* context);
|
||||
|
||||
void camera_suite_view_guide_set_callback(
|
||||
CameraSuiteViewGuide* camera_suite_view_guide,
|
||||
CameraSuiteViewGuideCallback callback,
|
||||
void* context);
|
||||
|
||||
View* camera_suite_view_guide_get_view(CameraSuiteViewGuide* camera_suite_static);
|
||||
|
||||
CameraSuiteViewGuide* camera_suite_view_guide_alloc();
|
||||
|
||||
void camera_suite_view_guide_free(CameraSuiteViewGuide* camera_suite_static);
|
126
applications/external/camera-suite/views/camera_suite_view_start.c
vendored
Normal file
126
applications/external/camera-suite/views/camera_suite_view_start.c
vendored
Normal file
@ -0,0 +1,126 @@
|
||||
#include "../camera-suite.h"
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
#include <input/input.h>
|
||||
#include <gui/elements.h>
|
||||
|
||||
struct CameraSuiteViewStart {
|
||||
View* view;
|
||||
CameraSuiteViewStartCallback callback;
|
||||
void* context;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
int some_value;
|
||||
} CameraSuiteViewStartModel;
|
||||
|
||||
void camera_suite_view_start_set_callback(
|
||||
CameraSuiteViewStart* instance,
|
||||
CameraSuiteViewStartCallback callback,
|
||||
void* context) {
|
||||
furi_assert(instance);
|
||||
furi_assert(callback);
|
||||
instance->callback = callback;
|
||||
instance->context = context;
|
||||
}
|
||||
|
||||
void camera_suite_view_start_draw(Canvas* canvas, CameraSuiteViewStartModel* model) {
|
||||
UNUSED(model);
|
||||
canvas_clear(canvas);
|
||||
canvas_set_color(canvas, ColorBlack);
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str_aligned(canvas, 64, 10, AlignCenter, AlignTop, "Camera Suite");
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
canvas_draw_str_aligned(canvas, 64, 22, AlignCenter, AlignTop, "Flipper Zero");
|
||||
canvas_draw_str_aligned(canvas, 64, 32, AlignCenter, AlignTop, "ESP32 CAM");
|
||||
elements_button_center(canvas, "Start");
|
||||
}
|
||||
|
||||
static void camera_suite_view_start_model_init(CameraSuiteViewStartModel* const model) {
|
||||
model->some_value = 1;
|
||||
}
|
||||
|
||||
bool camera_suite_view_start_input(InputEvent* event, void* context) {
|
||||
furi_assert(context);
|
||||
CameraSuiteViewStart* instance = context;
|
||||
if(event->type == InputTypeRelease) {
|
||||
switch(event->key) {
|
||||
case InputKeyBack:
|
||||
// Exit application.
|
||||
with_view_model(
|
||||
instance->view,
|
||||
CameraSuiteViewStartModel * model,
|
||||
{
|
||||
UNUSED(model);
|
||||
instance->callback(CameraSuiteCustomEventStartBack, instance->context);
|
||||
},
|
||||
true);
|
||||
break;
|
||||
case InputKeyOk:
|
||||
// Start the application.
|
||||
with_view_model(
|
||||
instance->view,
|
||||
CameraSuiteViewStartModel * model,
|
||||
{
|
||||
UNUSED(model);
|
||||
instance->callback(CameraSuiteCustomEventStartOk, instance->context);
|
||||
},
|
||||
true);
|
||||
break;
|
||||
case InputKeyMAX:
|
||||
case InputKeyLeft:
|
||||
case InputKeyRight:
|
||||
case InputKeyUp:
|
||||
case InputKeyDown:
|
||||
// Do nothing.
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void camera_suite_view_start_exit(void* context) {
|
||||
furi_assert(context);
|
||||
}
|
||||
|
||||
void camera_suite_view_start_enter(void* context) {
|
||||
furi_assert(context);
|
||||
CameraSuiteViewStart* instance = (CameraSuiteViewStart*)context;
|
||||
with_view_model(
|
||||
instance->view,
|
||||
CameraSuiteViewStartModel * model,
|
||||
{ camera_suite_view_start_model_init(model); },
|
||||
true);
|
||||
}
|
||||
|
||||
CameraSuiteViewStart* camera_suite_view_start_alloc() {
|
||||
CameraSuiteViewStart* instance = malloc(sizeof(CameraSuiteViewStart));
|
||||
instance->view = view_alloc();
|
||||
view_allocate_model(instance->view, ViewModelTypeLocking, sizeof(CameraSuiteViewStartModel));
|
||||
// furi_assert crashes in events without this
|
||||
view_set_context(instance->view, instance);
|
||||
view_set_draw_callback(instance->view, (ViewDrawCallback)camera_suite_view_start_draw);
|
||||
view_set_input_callback(instance->view, camera_suite_view_start_input);
|
||||
|
||||
with_view_model(
|
||||
instance->view,
|
||||
CameraSuiteViewStartModel * model,
|
||||
{ camera_suite_view_start_model_init(model); },
|
||||
true);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
void camera_suite_view_start_free(CameraSuiteViewStart* instance) {
|
||||
furi_assert(instance);
|
||||
|
||||
with_view_model(
|
||||
instance->view, CameraSuiteViewStartModel * model, { UNUSED(model); }, true);
|
||||
view_free(instance->view);
|
||||
free(instance);
|
||||
}
|
||||
|
||||
View* camera_suite_view_start_get_view(CameraSuiteViewStart* instance) {
|
||||
furi_assert(instance);
|
||||
return instance->view;
|
||||
}
|
19
applications/external/camera-suite/views/camera_suite_view_start.h
vendored
Normal file
19
applications/external/camera-suite/views/camera_suite_view_start.h
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <gui/view.h>
|
||||
#include "../helpers/camera_suite_custom_event.h"
|
||||
|
||||
typedef struct CameraSuiteViewStart CameraSuiteViewStart;
|
||||
|
||||
typedef void (*CameraSuiteViewStartCallback)(CameraSuiteCustomEvent event, void* context);
|
||||
|
||||
void camera_suite_view_start_set_callback(
|
||||
CameraSuiteViewStart* camera_suite_view_start,
|
||||
CameraSuiteViewStartCallback callback,
|
||||
void* context);
|
||||
|
||||
View* camera_suite_view_start_get_view(CameraSuiteViewStart* camera_suite_static);
|
||||
|
||||
CameraSuiteViewStart* camera_suite_view_start_alloc();
|
||||
|
||||
void camera_suite_view_start_free(CameraSuiteViewStart* camera_suite_static);
|
401
applications/external/camera-suite/views/camera_suite_view_style_1.c
vendored
Normal file
401
applications/external/camera-suite/views/camera_suite_view_style_1.c
vendored
Normal file
@ -0,0 +1,401 @@
|
||||
#include "../camera-suite.h"
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
#include <input/input.h>
|
||||
#include <gui/elements.h>
|
||||
#include <dolphin/dolphin.h>
|
||||
#include "../helpers/camera_suite_haptic.h"
|
||||
#include "../helpers/camera_suite_speaker.h"
|
||||
#include "../helpers/camera_suite_led.h"
|
||||
|
||||
static CameraSuiteViewStyle1* current_instance = NULL;
|
||||
// Dithering type:
|
||||
// 0 = Floyd Steinberg (default)
|
||||
// 1 = Atkinson
|
||||
static int current_dithering = 0;
|
||||
|
||||
struct CameraSuiteViewStyle1 {
|
||||
CameraSuiteViewStyle1Callback callback;
|
||||
FuriStreamBuffer* rx_stream;
|
||||
FuriThread* worker_thread;
|
||||
View* view;
|
||||
void* context;
|
||||
};
|
||||
|
||||
void camera_suite_view_style_1_set_callback(
|
||||
CameraSuiteViewStyle1* instance,
|
||||
CameraSuiteViewStyle1Callback callback,
|
||||
void* context) {
|
||||
furi_assert(instance);
|
||||
furi_assert(callback);
|
||||
instance->callback = callback;
|
||||
instance->context = context;
|
||||
}
|
||||
|
||||
static void camera_suite_view_style_1_draw(Canvas* canvas, UartDumpModel* model) {
|
||||
// Clear the screen.
|
||||
canvas_set_color(canvas, ColorBlack);
|
||||
|
||||
// Draw the frame.
|
||||
canvas_draw_frame(canvas, 0, 0, FRAME_WIDTH, FRAME_HEIGHT);
|
||||
|
||||
CameraSuite* app = current_instance->context;
|
||||
|
||||
// Draw the pixels with rotation.
|
||||
for(size_t p = 0; p < FRAME_BUFFER_LENGTH; ++p) {
|
||||
uint8_t x = p % ROW_BUFFER_LENGTH; // 0 .. 15
|
||||
uint8_t y = p / ROW_BUFFER_LENGTH; // 0 .. 63
|
||||
|
||||
// Apply rotation
|
||||
int16_t rotated_x, rotated_y;
|
||||
switch(app->orientation) {
|
||||
case 1: // 90 degrees
|
||||
rotated_x = y;
|
||||
rotated_y = FRAME_WIDTH - 1 - x;
|
||||
break;
|
||||
case 2: // 180 degrees
|
||||
rotated_x = FRAME_WIDTH - 1 - x;
|
||||
rotated_y = FRAME_HEIGHT - 1 - y;
|
||||
break;
|
||||
case 3: // 270 degrees
|
||||
rotated_x = FRAME_HEIGHT - 1 - y;
|
||||
rotated_y = x;
|
||||
break;
|
||||
case 0: // 0 degrees
|
||||
default:
|
||||
rotated_x = x;
|
||||
rotated_y = y;
|
||||
break;
|
||||
}
|
||||
|
||||
for(uint8_t i = 0; i < 8; ++i) {
|
||||
if((model->pixels[p] & (1 << i)) != 0) {
|
||||
// Adjust the coordinates based on the new screen dimensions
|
||||
uint16_t screen_x, screen_y;
|
||||
switch(app->orientation) {
|
||||
case 1: // 90 degrees
|
||||
screen_x = rotated_x;
|
||||
screen_y = FRAME_HEIGHT - 8 + (rotated_y * 8) + i;
|
||||
break;
|
||||
case 2: // 180 degrees
|
||||
screen_x = FRAME_WIDTH - 8 + (rotated_x * 8) + i;
|
||||
screen_y = FRAME_HEIGHT - 1 - rotated_y;
|
||||
break;
|
||||
case 3: // 270 degrees
|
||||
screen_x = FRAME_WIDTH - 1 - rotated_x;
|
||||
screen_y = rotated_y * 8 + i;
|
||||
break;
|
||||
case 0: // 0 degrees
|
||||
default:
|
||||
screen_x = rotated_x * 8 + i;
|
||||
screen_y = rotated_y;
|
||||
break;
|
||||
}
|
||||
canvas_draw_dot(canvas, screen_x, screen_y);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Draw the guide if the camera is not initialized.
|
||||
if(!model->initialized) {
|
||||
canvas_draw_icon(canvas, 74, 16, &I_DolphinCommon_56x48);
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
canvas_draw_str(canvas, 8, 12, "Connect the ESP32-CAM");
|
||||
canvas_draw_str(canvas, 20, 24, "VCC - 3V3");
|
||||
canvas_draw_str(canvas, 20, 34, "GND - GND");
|
||||
canvas_draw_str(canvas, 20, 44, "U0R - TX");
|
||||
canvas_draw_str(canvas, 20, 54, "U0T - RX");
|
||||
}
|
||||
}
|
||||
|
||||
static void camera_suite_view_style_1_model_init(UartDumpModel* const model) {
|
||||
for(size_t i = 0; i < FRAME_BUFFER_LENGTH; i++) {
|
||||
model->pixels[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static bool camera_suite_view_style_1_input(InputEvent* event, void* context) {
|
||||
furi_assert(context);
|
||||
CameraSuiteViewStyle1* instance = context;
|
||||
if(event->type == InputTypeRelease) {
|
||||
switch(event->key) {
|
||||
default: // Stop all sounds, reset the LED.
|
||||
with_view_model(
|
||||
instance->view,
|
||||
UartDumpModel * model,
|
||||
{
|
||||
UNUSED(model);
|
||||
camera_suite_play_bad_bump(instance->context);
|
||||
camera_suite_stop_all_sound(instance->context);
|
||||
camera_suite_led_set_rgb(instance->context, 0, 0, 0);
|
||||
},
|
||||
true);
|
||||
break;
|
||||
}
|
||||
// Send `data` to the ESP32-CAM
|
||||
} else if(event->type == InputTypePress) {
|
||||
uint8_t data[1];
|
||||
switch(event->key) {
|
||||
case InputKeyBack:
|
||||
// Stop the camera stream.
|
||||
data[0] = 's';
|
||||
// Go back to the main menu.
|
||||
with_view_model(
|
||||
instance->view,
|
||||
UartDumpModel * model,
|
||||
{
|
||||
UNUSED(model);
|
||||
instance->callback(CameraSuiteCustomEventSceneStyle1Back, instance->context);
|
||||
},
|
||||
true);
|
||||
break;
|
||||
case InputKeyLeft:
|
||||
// Camera: Invert.
|
||||
data[0] = '<';
|
||||
with_view_model(
|
||||
instance->view,
|
||||
UartDumpModel * model,
|
||||
{
|
||||
UNUSED(model);
|
||||
camera_suite_play_happy_bump(instance->context);
|
||||
camera_suite_play_input_sound(instance->context);
|
||||
camera_suite_led_set_rgb(instance->context, 0, 0, 255);
|
||||
instance->callback(CameraSuiteCustomEventSceneStyle1Left, instance->context);
|
||||
},
|
||||
true);
|
||||
break;
|
||||
case InputKeyRight:
|
||||
// Camera: Enable/disable dithering.
|
||||
data[0] = '>';
|
||||
with_view_model(
|
||||
instance->view,
|
||||
UartDumpModel * model,
|
||||
{
|
||||
UNUSED(model);
|
||||
camera_suite_play_happy_bump(instance->context);
|
||||
camera_suite_play_input_sound(instance->context);
|
||||
camera_suite_led_set_rgb(instance->context, 0, 0, 255);
|
||||
instance->callback(CameraSuiteCustomEventSceneStyle1Right, instance->context);
|
||||
},
|
||||
true);
|
||||
break;
|
||||
case InputKeyUp:
|
||||
// Camera: Increase contrast.
|
||||
data[0] = 'C';
|
||||
with_view_model(
|
||||
instance->view,
|
||||
UartDumpModel * model,
|
||||
{
|
||||
UNUSED(model);
|
||||
camera_suite_play_happy_bump(instance->context);
|
||||
camera_suite_play_input_sound(instance->context);
|
||||
camera_suite_led_set_rgb(instance->context, 0, 0, 255);
|
||||
instance->callback(CameraSuiteCustomEventSceneStyle1Up, instance->context);
|
||||
},
|
||||
true);
|
||||
break;
|
||||
case InputKeyDown:
|
||||
// Camera: Reduce contrast.
|
||||
data[0] = 'c';
|
||||
with_view_model(
|
||||
instance->view,
|
||||
UartDumpModel * model,
|
||||
{
|
||||
UNUSED(model);
|
||||
camera_suite_play_happy_bump(instance->context);
|
||||
camera_suite_play_input_sound(instance->context);
|
||||
camera_suite_led_set_rgb(instance->context, 0, 0, 255);
|
||||
instance->callback(CameraSuiteCustomEventSceneStyle1Down, instance->context);
|
||||
},
|
||||
true);
|
||||
break;
|
||||
case InputKeyOk:
|
||||
if(current_dithering == 0) {
|
||||
data[0] = 'd'; // Update to Floyd Steinberg dithering.
|
||||
current_dithering = 1;
|
||||
} else {
|
||||
data[0] = 'D'; // Update to Atkinson dithering.
|
||||
current_dithering = 0;
|
||||
}
|
||||
with_view_model(
|
||||
instance->view,
|
||||
UartDumpModel * model,
|
||||
{
|
||||
UNUSED(model);
|
||||
camera_suite_play_happy_bump(instance->context);
|
||||
camera_suite_play_input_sound(instance->context);
|
||||
camera_suite_led_set_rgb(instance->context, 0, 0, 255);
|
||||
instance->callback(CameraSuiteCustomEventSceneStyle1Ok, instance->context);
|
||||
},
|
||||
true);
|
||||
break;
|
||||
case InputKeyMAX:
|
||||
break;
|
||||
}
|
||||
// Send `data` to the ESP32-CAM
|
||||
furi_hal_uart_tx(FuriHalUartIdUSART1, data, 1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void camera_suite_view_style_1_exit(void* context) {
|
||||
furi_assert(context);
|
||||
}
|
||||
|
||||
static void camera_suite_view_style_1_enter(void* context) {
|
||||
// Check `context` for null. If it is null, abort program, else continue.
|
||||
furi_assert(context);
|
||||
|
||||
// Cast `context` to `CameraSuiteViewStyle1*` and store it in `instance`.
|
||||
CameraSuiteViewStyle1* instance = (CameraSuiteViewStyle1*)context;
|
||||
|
||||
// Assign the current instance to the global variable
|
||||
current_instance = instance;
|
||||
|
||||
uint8_t data[1];
|
||||
data[0] = 'S'; // Uppercase `S` to start the camera
|
||||
// Send `data` to the ESP32-CAM
|
||||
furi_hal_uart_tx(FuriHalUartIdUSART1, data, 1);
|
||||
|
||||
with_view_model(
|
||||
instance->view,
|
||||
UartDumpModel * model,
|
||||
{ camera_suite_view_style_1_model_init(model); },
|
||||
true);
|
||||
}
|
||||
|
||||
static void camera_on_irq_cb(UartIrqEvent uartIrqEvent, uint8_t data, void* context) {
|
||||
// Check `context` for null. If it is null, abort program, else continue.
|
||||
furi_assert(context);
|
||||
|
||||
// Cast `context` to `CameraSuiteViewStyle1*` and store it in `instance`.
|
||||
CameraSuiteViewStyle1* instance = context;
|
||||
|
||||
// If `uartIrqEvent` is `UartIrqEventRXNE`, send the data to the
|
||||
// `rx_stream` and set the `WorkerEventRx` flag.
|
||||
if(uartIrqEvent == UartIrqEventRXNE) {
|
||||
furi_stream_buffer_send(instance->rx_stream, &data, 1, 0);
|
||||
furi_thread_flags_set(furi_thread_get_id(instance->worker_thread), WorkerEventRx);
|
||||
}
|
||||
}
|
||||
|
||||
static void process_ringbuffer(UartDumpModel* model, uint8_t byte) {
|
||||
// First char has to be 'Y' in the buffer.
|
||||
if(model->ringbuffer_index == 0 && byte != 'Y') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Second char has to be ':' in the buffer or reset.
|
||||
if(model->ringbuffer_index == 1 && byte != ':') {
|
||||
model->ringbuffer_index = 0;
|
||||
process_ringbuffer(model, byte);
|
||||
return;
|
||||
}
|
||||
|
||||
// Assign current byte to the ringbuffer.
|
||||
model->row_ringbuffer[model->ringbuffer_index] = byte;
|
||||
// Increment the ringbuffer index.
|
||||
++model->ringbuffer_index;
|
||||
|
||||
// Let's wait 'till the buffer fills.
|
||||
if(model->ringbuffer_index < RING_BUFFER_LENGTH) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Flush the ringbuffer to the framebuffer.
|
||||
model->ringbuffer_index = 0; // Reset the ringbuffer
|
||||
model->initialized = true; // Established the connection successfully.
|
||||
size_t row_start_index =
|
||||
model->row_ringbuffer[2] * ROW_BUFFER_LENGTH; // Third char will determine the row number
|
||||
|
||||
if(row_start_index > LAST_ROW_INDEX) { // Failsafe
|
||||
row_start_index = 0;
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < ROW_BUFFER_LENGTH; ++i) {
|
||||
model->pixels[row_start_index + i] =
|
||||
model->row_ringbuffer[i + 3]; // Writing the remaining 16 bytes into the frame buffer
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t camera_worker(void* context) {
|
||||
furi_assert(context);
|
||||
CameraSuiteViewStyle1* instance = context;
|
||||
|
||||
while(1) {
|
||||
uint32_t events =
|
||||
furi_thread_flags_wait(WORKER_EVENTS_MASK, FuriFlagWaitAny, FuriWaitForever);
|
||||
furi_check((events & FuriFlagError) == 0);
|
||||
|
||||
if(events & WorkerEventStop) {
|
||||
break;
|
||||
} else if(events & WorkerEventRx) {
|
||||
size_t length = 0;
|
||||
do {
|
||||
size_t intended_data_size = 64;
|
||||
uint8_t data[intended_data_size];
|
||||
length =
|
||||
furi_stream_buffer_receive(instance->rx_stream, data, intended_data_size, 0);
|
||||
|
||||
if(length > 0) {
|
||||
with_view_model(
|
||||
instance->view,
|
||||
UartDumpModel * model,
|
||||
{
|
||||
for(size_t i = 0; i < length; i++) {
|
||||
process_ringbuffer(model, data[i]);
|
||||
}
|
||||
},
|
||||
false);
|
||||
}
|
||||
} while(length > 0);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
CameraSuiteViewStyle1* camera_suite_view_style_1_alloc() {
|
||||
CameraSuiteViewStyle1* instance = malloc(sizeof(CameraSuiteViewStyle1));
|
||||
|
||||
instance->view = view_alloc();
|
||||
|
||||
instance->rx_stream = furi_stream_buffer_alloc(2048, 1);
|
||||
|
||||
// Set up views
|
||||
view_allocate_model(instance->view, ViewModelTypeLocking, sizeof(UartDumpModel));
|
||||
view_set_context(instance->view, instance); // furi_assert crashes in events without this
|
||||
view_set_draw_callback(instance->view, (ViewDrawCallback)camera_suite_view_style_1_draw);
|
||||
view_set_input_callback(instance->view, camera_suite_view_style_1_input);
|
||||
view_set_enter_callback(instance->view, camera_suite_view_style_1_enter);
|
||||
view_set_exit_callback(instance->view, camera_suite_view_style_1_exit);
|
||||
|
||||
with_view_model(
|
||||
instance->view,
|
||||
UartDumpModel * model,
|
||||
{ camera_suite_view_style_1_model_init(model); },
|
||||
true);
|
||||
|
||||
instance->worker_thread = furi_thread_alloc_ex("UsbUartWorker", 2048, camera_worker, instance);
|
||||
furi_thread_start(instance->worker_thread);
|
||||
|
||||
// Enable uart listener
|
||||
furi_hal_console_disable();
|
||||
furi_hal_uart_set_br(FuriHalUartIdUSART1, 230400);
|
||||
furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, camera_on_irq_cb, instance);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
void camera_suite_view_style_1_free(CameraSuiteViewStyle1* instance) {
|
||||
furi_assert(instance);
|
||||
|
||||
with_view_model(
|
||||
instance->view, UartDumpModel * model, { UNUSED(model); }, true);
|
||||
view_free(instance->view);
|
||||
free(instance);
|
||||
}
|
||||
|
||||
View* camera_suite_view_style_1_get_view(CameraSuiteViewStyle1* instance) {
|
||||
furi_assert(instance);
|
||||
return instance->view;
|
||||
}
|
60
applications/external/camera-suite/views/camera_suite_view_style_1.h
vendored
Normal file
60
applications/external/camera-suite/views/camera_suite_view_style_1.h
vendored
Normal file
@ -0,0 +1,60 @@
|
||||
#include "../helpers/camera_suite_custom_event.h"
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
#include <furi_hal_console.h>
|
||||
#include <furi_hal_uart.h>
|
||||
#include <gui/elements.h>
|
||||
#include <gui/gui.h>
|
||||
#include <gui/icon_i.h>
|
||||
#include <gui/modules/dialog_ex.h>
|
||||
#include <gui/view.h>
|
||||
#include <gui/view_dispatcher.h>
|
||||
#include <notification/notification.h>
|
||||
#include <notification/notification_messages.h>
|
||||
#include <storage/filesystem_api_defines.h>
|
||||
#include <storage/storage.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
#define FRAME_WIDTH 128
|
||||
#define FRAME_HEIGHT 64
|
||||
#define FRAME_BIT_DEPTH 1
|
||||
#define FRAME_BUFFER_LENGTH \
|
||||
(FRAME_WIDTH * FRAME_HEIGHT * FRAME_BIT_DEPTH / 8) // 128*64*1 / 8 = 1024
|
||||
#define ROW_BUFFER_LENGTH (FRAME_WIDTH / 8) // 128/8 = 16
|
||||
#define RING_BUFFER_LENGTH (ROW_BUFFER_LENGTH + 3) // ROW_BUFFER_LENGTH + Header => 16 + 3 = 19
|
||||
#define LAST_ROW_INDEX (FRAME_BUFFER_LENGTH - ROW_BUFFER_LENGTH) // 1024 - 16 = 1008
|
||||
|
||||
typedef struct UartDumpModel UartDumpModel;
|
||||
|
||||
struct UartDumpModel {
|
||||
bool initialized;
|
||||
int rotation_angle;
|
||||
uint8_t pixels[FRAME_BUFFER_LENGTH];
|
||||
uint8_t ringbuffer_index;
|
||||
uint8_t row_ringbuffer[RING_BUFFER_LENGTH];
|
||||
};
|
||||
|
||||
typedef struct CameraSuiteViewStyle1 CameraSuiteViewStyle1;
|
||||
|
||||
typedef void (*CameraSuiteViewStyle1Callback)(CameraSuiteCustomEvent event, void* context);
|
||||
|
||||
void camera_suite_view_style_1_set_callback(
|
||||
CameraSuiteViewStyle1* camera_suite_view_style_1,
|
||||
CameraSuiteViewStyle1Callback callback,
|
||||
void* context);
|
||||
|
||||
CameraSuiteViewStyle1* camera_suite_view_style_1_alloc();
|
||||
|
||||
void camera_suite_view_style_1_free(CameraSuiteViewStyle1* camera_suite_static);
|
||||
|
||||
View* camera_suite_view_style_1_get_view(CameraSuiteViewStyle1* camera_suite_static);
|
||||
|
||||
typedef enum {
|
||||
// Reserved for StreamBuffer internal event
|
||||
WorkerEventReserved = (1 << 0),
|
||||
WorkerEventStop = (1 << 1),
|
||||
WorkerEventRx = (1 << 2),
|
||||
} WorkerEventFlags;
|
||||
|
||||
#define WORKER_EVENTS_MASK (WorkerEventStop | WorkerEventRx)
|
249
applications/external/camera-suite/views/camera_suite_view_style_2.c
vendored
Normal file
249
applications/external/camera-suite/views/camera_suite_view_style_2.c
vendored
Normal file
@ -0,0 +1,249 @@
|
||||
#include "../camera-suite.h"
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
#include <input/input.h>
|
||||
#include <gui/elements.h>
|
||||
#include <dolphin/dolphin.h>
|
||||
#include "../helpers/camera_suite_haptic.h"
|
||||
#include "../helpers/camera_suite_speaker.h"
|
||||
#include "../helpers/camera_suite_led.h"
|
||||
|
||||
struct CameraSuiteViewStyle2 {
|
||||
View* view;
|
||||
CameraSuiteViewStyle2Callback callback;
|
||||
void* context;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
int screen_text;
|
||||
} CameraSuiteViewStyle2Model;
|
||||
|
||||
char buttonText[11][14] = {
|
||||
"",
|
||||
"Press Up",
|
||||
"Press Down",
|
||||
"Press Left",
|
||||
"Press Right",
|
||||
"Press Ok",
|
||||
"Release Up",
|
||||
"Release Down",
|
||||
"Release Left",
|
||||
"Release Right",
|
||||
"Release Ok",
|
||||
};
|
||||
|
||||
void camera_suite_view_style_2_set_callback(
|
||||
CameraSuiteViewStyle2* instance,
|
||||
CameraSuiteViewStyle2Callback callback,
|
||||
void* context) {
|
||||
furi_assert(instance);
|
||||
furi_assert(callback);
|
||||
instance->callback = callback;
|
||||
instance->context = context;
|
||||
}
|
||||
|
||||
void camera_suite_view_style_2_draw(Canvas* canvas, CameraSuiteViewStyle2Model* model) {
|
||||
canvas_clear(canvas);
|
||||
canvas_set_color(canvas, ColorBlack);
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str_aligned(canvas, 0, 10, AlignLeft, AlignTop, "Scene 2: Input Examples");
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
char* strInput = malloc(15);
|
||||
strcpy(strInput, buttonText[model->screen_text]);
|
||||
canvas_draw_str_aligned(canvas, 0, 22, AlignLeft, AlignTop, strInput);
|
||||
free(strInput);
|
||||
}
|
||||
|
||||
static void camera_suite_view_style_2_model_init(CameraSuiteViewStyle2Model* const model) {
|
||||
model->screen_text = 0;
|
||||
}
|
||||
|
||||
bool camera_suite_view_style_2_input(InputEvent* event, void* context) {
|
||||
furi_assert(context);
|
||||
CameraSuiteViewStyle2* instance = context;
|
||||
if(event->type == InputTypeRelease) {
|
||||
switch(event->key) {
|
||||
case InputKeyBack:
|
||||
with_view_model(
|
||||
instance->view,
|
||||
CameraSuiteViewStyle2Model * model,
|
||||
{
|
||||
UNUSED(model);
|
||||
camera_suite_stop_all_sound(instance->context);
|
||||
instance->callback(CameraSuiteCustomEventSceneStyle2Back, instance->context);
|
||||
camera_suite_play_long_bump(instance->context);
|
||||
},
|
||||
true);
|
||||
break;
|
||||
case InputKeyUp:
|
||||
with_view_model(
|
||||
instance->view,
|
||||
CameraSuiteViewStyle2Model * model,
|
||||
{
|
||||
model->screen_text = 6;
|
||||
camera_suite_play_bad_bump(instance->context);
|
||||
camera_suite_stop_all_sound(instance->context);
|
||||
camera_suite_led_set_rgb(instance->context, 255, 0, 255);
|
||||
},
|
||||
true);
|
||||
break;
|
||||
case InputKeyDown:
|
||||
with_view_model(
|
||||
instance->view,
|
||||
CameraSuiteViewStyle2Model * model,
|
||||
{
|
||||
model->screen_text = 7;
|
||||
camera_suite_play_bad_bump(instance->context);
|
||||
camera_suite_stop_all_sound(instance->context);
|
||||
camera_suite_led_set_rgb(instance->context, 255, 255, 0);
|
||||
},
|
||||
true);
|
||||
break;
|
||||
case InputKeyLeft:
|
||||
with_view_model(
|
||||
instance->view,
|
||||
CameraSuiteViewStyle2Model * model,
|
||||
{
|
||||
model->screen_text = 8;
|
||||
camera_suite_play_bad_bump(instance->context);
|
||||
camera_suite_stop_all_sound(instance->context);
|
||||
camera_suite_led_set_rgb(instance->context, 0, 255, 255);
|
||||
},
|
||||
true);
|
||||
break;
|
||||
case InputKeyRight:
|
||||
with_view_model(
|
||||
instance->view,
|
||||
CameraSuiteViewStyle2Model * model,
|
||||
{
|
||||
model->screen_text = 9;
|
||||
camera_suite_play_bad_bump(instance->context);
|
||||
camera_suite_stop_all_sound(instance->context);
|
||||
camera_suite_led_set_rgb(instance->context, 255, 0, 0);
|
||||
},
|
||||
true);
|
||||
break;
|
||||
case InputKeyOk:
|
||||
with_view_model(
|
||||
instance->view,
|
||||
CameraSuiteViewStyle2Model * model,
|
||||
{
|
||||
model->screen_text = 10;
|
||||
camera_suite_play_bad_bump(instance->context);
|
||||
camera_suite_stop_all_sound(instance->context);
|
||||
camera_suite_led_set_rgb(instance->context, 255, 255, 255);
|
||||
},
|
||||
true);
|
||||
break;
|
||||
case InputKeyMAX:
|
||||
break;
|
||||
}
|
||||
} else if(event->type == InputTypePress) {
|
||||
switch(event->key) {
|
||||
case InputKeyUp:
|
||||
with_view_model(
|
||||
instance->view,
|
||||
CameraSuiteViewStyle2Model * model,
|
||||
{
|
||||
model->screen_text = 1;
|
||||
camera_suite_play_happy_bump(instance->context);
|
||||
camera_suite_play_input_sound(instance->context);
|
||||
},
|
||||
true);
|
||||
break;
|
||||
case InputKeyDown:
|
||||
with_view_model(
|
||||
instance->view,
|
||||
CameraSuiteViewStyle2Model * model,
|
||||
{
|
||||
model->screen_text = 2;
|
||||
camera_suite_play_happy_bump(instance->context);
|
||||
camera_suite_play_input_sound(instance->context);
|
||||
},
|
||||
true);
|
||||
break;
|
||||
case InputKeyLeft:
|
||||
with_view_model(
|
||||
instance->view,
|
||||
CameraSuiteViewStyle2Model * model,
|
||||
{
|
||||
model->screen_text = 3;
|
||||
camera_suite_play_happy_bump(instance->context);
|
||||
camera_suite_play_input_sound(instance->context);
|
||||
},
|
||||
true);
|
||||
break;
|
||||
case InputKeyRight:
|
||||
with_view_model(
|
||||
instance->view,
|
||||
CameraSuiteViewStyle2Model * model,
|
||||
{
|
||||
model->screen_text = 4;
|
||||
camera_suite_play_happy_bump(instance->context);
|
||||
camera_suite_play_input_sound(instance->context);
|
||||
},
|
||||
true);
|
||||
break;
|
||||
case InputKeyOk:
|
||||
with_view_model(
|
||||
instance->view,
|
||||
CameraSuiteViewStyle2Model * model,
|
||||
{
|
||||
model->screen_text = 5;
|
||||
camera_suite_play_happy_bump(instance->context);
|
||||
camera_suite_play_input_sound(instance->context);
|
||||
},
|
||||
true);
|
||||
break;
|
||||
case InputKeyBack:
|
||||
case InputKeyMAX:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void camera_suite_view_style_2_exit(void* context) {
|
||||
furi_assert(context);
|
||||
CameraSuite* app = context;
|
||||
camera_suite_stop_all_sound(app);
|
||||
//camera_suite_led_reset(app);
|
||||
}
|
||||
|
||||
void camera_suite_view_style_2_enter(void* context) {
|
||||
furi_assert(context);
|
||||
dolphin_deed(DolphinDeedPluginStart);
|
||||
}
|
||||
|
||||
CameraSuiteViewStyle2* camera_suite_view_style_2_alloc() {
|
||||
CameraSuiteViewStyle2* instance = malloc(sizeof(CameraSuiteViewStyle2));
|
||||
instance->view = view_alloc();
|
||||
view_allocate_model(instance->view, ViewModelTypeLocking, sizeof(CameraSuiteViewStyle2Model));
|
||||
view_set_context(instance->view, instance);
|
||||
view_set_draw_callback(instance->view, (ViewDrawCallback)camera_suite_view_style_2_draw);
|
||||
view_set_input_callback(instance->view, camera_suite_view_style_2_input);
|
||||
//view_set_enter_callback(instance->view, camera_suite_view_style_2_enter);
|
||||
view_set_exit_callback(instance->view, camera_suite_view_style_2_exit);
|
||||
|
||||
with_view_model(
|
||||
instance->view,
|
||||
CameraSuiteViewStyle2Model * model,
|
||||
{ camera_suite_view_style_2_model_init(model); },
|
||||
true);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
void camera_suite_view_style_2_free(CameraSuiteViewStyle2* instance) {
|
||||
furi_assert(instance);
|
||||
|
||||
view_free(instance->view);
|
||||
free(instance);
|
||||
}
|
||||
|
||||
View* camera_suite_view_style_2_get_view(CameraSuiteViewStyle2* instance) {
|
||||
furi_assert(instance);
|
||||
|
||||
return instance->view;
|
||||
}
|
19
applications/external/camera-suite/views/camera_suite_view_style_2.h
vendored
Normal file
19
applications/external/camera-suite/views/camera_suite_view_style_2.h
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <gui/view.h>
|
||||
#include "../helpers/camera_suite_custom_event.h"
|
||||
|
||||
typedef struct CameraSuiteViewStyle2 CameraSuiteViewStyle2;
|
||||
|
||||
typedef void (*CameraSuiteViewStyle2Callback)(CameraSuiteCustomEvent event, void* context);
|
||||
|
||||
void camera_suite_view_style_2_set_callback(
|
||||
CameraSuiteViewStyle2* instance,
|
||||
CameraSuiteViewStyle2Callback callback,
|
||||
void* context);
|
||||
|
||||
CameraSuiteViewStyle2* camera_suite_view_style_2_alloc();
|
||||
|
||||
void camera_suite_view_style_2_free(CameraSuiteViewStyle2* camera_suite_static);
|
||||
|
||||
View* camera_suite_view_style_2_get_view(CameraSuiteViewStyle2* boilerpate_static);
|
Loading…
Reference in New Issue
Block a user