mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-04-24 03:29:57 -07:00
Add usage example app
This commit is contained in:
13
applications/examples/example_date_time_input/ReadMe.md
Normal file
13
applications/examples/example_date_time_input/ReadMe.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# Date/Time Input {#example_date_time_input}
|
||||
|
||||
Simple view that allows the user to adjust a date and/or time.
|
||||
|
||||
## Source code
|
||||
|
||||
Source code for this example can be found [here](https://github.com/flipperdevices/flipperzero-firmware/tree/dev/applications/examples/example_date_time_input).
|
||||
|
||||
## General principle
|
||||
|
||||
Callbacks can be defined for every time a value is edited (useful for application-specific bounds checking or validation) and for when the user is done editing (back button is pressed). The provided DateTime object is used both as the initial value and as the place where the result is stored.
|
||||
|
||||
The fields which the user is allowed to edit can be defined using `date_time_input_set_editable_fields()`. Disabled fields are shown but aren't able to be selected and don't have an outer box. If all fields are disabled, the view is read-only and no cursor will be shown.
|
||||
@@ -0,0 +1,9 @@
|
||||
App(
|
||||
appid="example_date_time_input",
|
||||
name="Example: Date/Time Input",
|
||||
apptype=FlipperAppType.EXTERNAL,
|
||||
entry_point="example_date_time_input",
|
||||
requires=["gui"],
|
||||
stack_size=1 * 1024,
|
||||
fap_category="Examples",
|
||||
)
|
||||
@@ -0,0 +1,79 @@
|
||||
#include "example_date_time_input.h"
|
||||
|
||||
bool example_date_time_input_custom_event_callback(void* context, uint32_t event) {
|
||||
furi_assert(context);
|
||||
ExampleDateTimeInput* app = context;
|
||||
return scene_manager_handle_custom_event(app->scene_manager, event);
|
||||
}
|
||||
|
||||
static bool example_date_time_input_back_event_callback(void* context) {
|
||||
furi_assert(context);
|
||||
ExampleDateTimeInput* app = context;
|
||||
return scene_manager_handle_back_event(app->scene_manager);
|
||||
}
|
||||
|
||||
static ExampleDateTimeInput* example_date_time_input_alloc() {
|
||||
ExampleDateTimeInput* app = malloc(sizeof(ExampleDateTimeInput));
|
||||
app->gui = furi_record_open(RECORD_GUI);
|
||||
|
||||
app->view_dispatcher = view_dispatcher_alloc();
|
||||
|
||||
app->scene_manager = scene_manager_alloc(&example_date_time_input_scene_handlers, app);
|
||||
view_dispatcher_set_event_callback_context(app->view_dispatcher, app);
|
||||
view_dispatcher_set_custom_event_callback(
|
||||
app->view_dispatcher, example_date_time_input_custom_event_callback);
|
||||
view_dispatcher_set_navigation_event_callback(
|
||||
app->view_dispatcher, example_date_time_input_back_event_callback);
|
||||
|
||||
app->date_time_input = date_time_input_alloc();
|
||||
view_dispatcher_add_view(
|
||||
app->view_dispatcher,
|
||||
ExampleDateTimeInputViewIdDateTimeInput,
|
||||
date_time_input_get_view(app->date_time_input));
|
||||
|
||||
app->dialog_ex = dialog_ex_alloc();
|
||||
view_dispatcher_add_view(
|
||||
app->view_dispatcher,
|
||||
ExampleDateTimeInputViewIdShowDateTime,
|
||||
dialog_ex_get_view(app->dialog_ex));
|
||||
|
||||
// Fill in current date & time
|
||||
furi_hal_rtc_get_datetime(&app->date_time);
|
||||
app->edit_date = false;
|
||||
app->edit_time = false;
|
||||
|
||||
return app;
|
||||
}
|
||||
|
||||
static void example_date_time_input_free(ExampleDateTimeInput* app) {
|
||||
furi_assert(app);
|
||||
|
||||
view_dispatcher_remove_view(app->view_dispatcher, ExampleDateTimeInputViewIdShowDateTime);
|
||||
dialog_ex_free(app->dialog_ex);
|
||||
|
||||
view_dispatcher_remove_view(app->view_dispatcher, ExampleDateTimeInputViewIdDateTimeInput);
|
||||
date_time_input_free(app->date_time_input);
|
||||
|
||||
scene_manager_free(app->scene_manager);
|
||||
view_dispatcher_free(app->view_dispatcher);
|
||||
|
||||
furi_record_close(RECORD_GUI);
|
||||
app->gui = NULL;
|
||||
|
||||
free(app);
|
||||
}
|
||||
|
||||
int32_t example_date_time_input(void* p) {
|
||||
UNUSED(p);
|
||||
ExampleDateTimeInput* app = example_date_time_input_alloc();
|
||||
|
||||
view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
|
||||
|
||||
scene_manager_next_scene(app->scene_manager, ExampleDateTimeInputSceneShowDateTime);
|
||||
|
||||
view_dispatcher_run(app->view_dispatcher);
|
||||
|
||||
example_date_time_input_free(app);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
|
||||
#include <gui/gui.h>
|
||||
#include <gui/elements.h>
|
||||
#include <gui/scene_manager.h>
|
||||
#include <gui/modules/dialog_ex.h>
|
||||
#include <gui/modules/date_time_input.h>
|
||||
#include <gui/view.h>
|
||||
#include <gui/view_dispatcher.h>
|
||||
#include <input/input.h>
|
||||
|
||||
#include "scenes/example_date_time_input_scene.h"
|
||||
|
||||
typedef struct ExampleDateTimeInputShowDateTime ExampleDateTimeInputShowDateTime;
|
||||
|
||||
typedef enum {
|
||||
ExampleDateTimeInputViewIdShowDateTime,
|
||||
ExampleDateTimeInputViewIdDateTimeInput,
|
||||
} ExampleDateTimeInputViewId;
|
||||
|
||||
typedef struct {
|
||||
Gui* gui;
|
||||
SceneManager* scene_manager;
|
||||
ViewDispatcher* view_dispatcher;
|
||||
|
||||
DateTimeInput* date_time_input;
|
||||
DialogEx* dialog_ex;
|
||||
|
||||
DateTime date_time;
|
||||
|
||||
bool edit_date;
|
||||
bool edit_time;
|
||||
} ExampleDateTimeInput;
|
||||
@@ -0,0 +1,31 @@
|
||||
#include "example_date_time_input_scene.h"
|
||||
|
||||
// Generate scene on_enter handlers array
|
||||
#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter,
|
||||
void (*const example_date_time_input_on_enter_handlers[])(void*) = {
|
||||
#include "example_date_time_input_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 example_date_time_input_on_event_handlers[])(void* context, SceneManagerEvent event) =
|
||||
{
|
||||
#include "example_date_time_input_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 example_date_time_input_on_exit_handlers[])(void* context) = {
|
||||
#include "example_date_time_input_scene_config.h"
|
||||
};
|
||||
#undef ADD_SCENE
|
||||
|
||||
// Initialize scene handlers configuration structure
|
||||
const SceneManagerHandlers example_date_time_input_scene_handlers = {
|
||||
.on_enter_handlers = example_date_time_input_on_enter_handlers,
|
||||
.on_event_handlers = example_date_time_input_on_event_handlers,
|
||||
.on_exit_handlers = example_date_time_input_on_exit_handlers,
|
||||
.scene_num = ExampleDateTimeInputSceneNum,
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include <gui/scene_manager.h>
|
||||
|
||||
// Generate scene id and total number
|
||||
#define ADD_SCENE(prefix, name, id) ExampleDateTimeInputScene##id,
|
||||
typedef enum {
|
||||
#include "example_date_time_input_scene_config.h"
|
||||
ExampleDateTimeInputSceneNum,
|
||||
} ExampleDateTimeInputScene;
|
||||
#undef ADD_SCENE
|
||||
|
||||
extern const SceneManagerHandlers example_date_time_input_scene_handlers;
|
||||
|
||||
// Generate scene on_enter handlers declaration
|
||||
#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*);
|
||||
#include "example_date_time_input_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 "example_date_time_input_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 "example_date_time_input_scene_config.h"
|
||||
#undef ADD_SCENE
|
||||
@@ -0,0 +1,2 @@
|
||||
ADD_SCENE(example_date_time_input, input_date_time, InputDateTime)
|
||||
ADD_SCENE(example_date_time_input, show_date_time, ShowDateTime)
|
||||
@@ -0,0 +1,47 @@
|
||||
#include "../example_date_time_input.h"
|
||||
|
||||
void example_date_time_input_scene_input_date_time_callback(void* context) {
|
||||
ExampleDateTimeInput* app = context;
|
||||
view_dispatcher_send_custom_event(app->view_dispatcher, 0);
|
||||
}
|
||||
|
||||
void example_date_time_input_scene_input_date_time_on_enter(void* context) {
|
||||
furi_assert(context);
|
||||
ExampleDateTimeInput* app = context;
|
||||
DateTimeInput* date_time_input = app->date_time_input;
|
||||
|
||||
date_time_input_set_result_callback(
|
||||
date_time_input,
|
||||
NULL,
|
||||
example_date_time_input_scene_input_date_time_callback,
|
||||
context,
|
||||
&app->date_time);
|
||||
|
||||
date_time_input_set_editable_fields(
|
||||
date_time_input,
|
||||
|
||||
app->edit_date,
|
||||
app->edit_date,
|
||||
app->edit_date,
|
||||
|
||||
app->edit_time,
|
||||
app->edit_time,
|
||||
app->edit_time);
|
||||
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, ExampleDateTimeInputViewIdDateTimeInput);
|
||||
}
|
||||
|
||||
bool example_date_time_input_scene_input_date_time_on_event(void* context, SceneManagerEvent event) {
|
||||
ExampleDateTimeInput* app = context;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) { //Back button pressed
|
||||
scene_manager_previous_scene(app->scene_manager);
|
||||
return true;
|
||||
}
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void example_date_time_input_scene_input_date_time_on_exit(void* context) {
|
||||
UNUSED(context);
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
#include "../example_date_time_input.h"
|
||||
|
||||
static void
|
||||
example_date_time_input_scene_confirm_dialog_callback(DialogExResult result, void* context) {
|
||||
ExampleDateTimeInput* app = context;
|
||||
|
||||
view_dispatcher_send_custom_event(app->view_dispatcher, result);
|
||||
}
|
||||
|
||||
static void example_date_time_input_scene_update_view(void* context) {
|
||||
ExampleDateTimeInput* app = context;
|
||||
DialogEx* dialog_ex = app->dialog_ex;
|
||||
|
||||
dialog_ex_set_header(dialog_ex, "The date and time are", 64, 0, AlignCenter, AlignTop);
|
||||
|
||||
char buffer[26] = {};
|
||||
snprintf(
|
||||
buffer,
|
||||
sizeof(buffer),
|
||||
"%04d-%02d-%02d\n%02d:%02d:%02d",
|
||||
app->date_time.year,
|
||||
app->date_time.month,
|
||||
app->date_time.day,
|
||||
app->date_time.hour,
|
||||
app->date_time.minute,
|
||||
app->date_time.second);
|
||||
dialog_ex_set_text(dialog_ex, buffer, 64, 29, AlignCenter, AlignCenter);
|
||||
|
||||
dialog_ex_set_left_button_text(dialog_ex, "Date");
|
||||
dialog_ex_set_right_button_text(dialog_ex, "Time");
|
||||
dialog_ex_set_center_button_text(dialog_ex, "Both");
|
||||
|
||||
dialog_ex_set_result_callback(
|
||||
dialog_ex, example_date_time_input_scene_confirm_dialog_callback);
|
||||
dialog_ex_set_context(dialog_ex, app);
|
||||
}
|
||||
|
||||
void example_date_time_input_scene_show_date_time_on_enter(void* context) {
|
||||
furi_assert(context);
|
||||
ExampleDateTimeInput* app = context;
|
||||
|
||||
example_date_time_input_scene_update_view(app);
|
||||
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, ExampleDateTimeInputViewIdShowDateTime);
|
||||
}
|
||||
|
||||
bool example_date_time_input_scene_show_date_time_on_event(void* context, SceneManagerEvent event) {
|
||||
ExampleDateTimeInput* app = context;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
switch(event.event) {
|
||||
case DialogExResultCenter:
|
||||
app->edit_date = true;
|
||||
app->edit_time = true;
|
||||
scene_manager_next_scene(app->scene_manager, ExampleDateTimeInputSceneInputDateTime);
|
||||
consumed = true;
|
||||
break;
|
||||
case DialogExResultLeft:
|
||||
app->edit_date = true;
|
||||
app->edit_time = false;
|
||||
scene_manager_next_scene(app->scene_manager, ExampleDateTimeInputSceneInputDateTime);
|
||||
consumed = true;
|
||||
break;
|
||||
case DialogExResultRight:
|
||||
app->edit_date = false;
|
||||
app->edit_time = true;
|
||||
scene_manager_next_scene(app->scene_manager, ExampleDateTimeInputSceneInputDateTime);
|
||||
consumed = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void example_date_time_input_scene_show_date_time_on_exit(void* context) {
|
||||
UNUSED(context);
|
||||
}
|
||||
@@ -21,7 +21,6 @@ struct DateTimeInput {
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
const char* header;
|
||||
DateTime* datetime;
|
||||
|
||||
uint8_t row;
|
||||
@@ -335,7 +334,6 @@ DateTimeInput* date_time_input_alloc(void) {
|
||||
date_time_input->view,
|
||||
DateTimeInputModel * model,
|
||||
{
|
||||
model->header = "";
|
||||
model->changed_callback = NULL;
|
||||
model->callback_context = NULL;
|
||||
date_time_input_reset_model_input_data(model);
|
||||
@@ -377,13 +375,6 @@ void date_time_input_set_result_callback(
|
||||
true);
|
||||
}
|
||||
|
||||
void date_time_input_set_header_text(DateTimeInput* date_time_input, const char* text) {
|
||||
furi_check(date_time_input);
|
||||
|
||||
with_view_model(
|
||||
date_time_input->view, DateTimeInputModel * model, { model->header = text; }, true);
|
||||
}
|
||||
|
||||
void date_time_input_set_editable_fields(
|
||||
DateTimeInput* date_time_input,
|
||||
bool year,
|
||||
|
||||
@@ -58,13 +58,6 @@ void date_time_input_set_result_callback(
|
||||
void* callback_context,
|
||||
DateTime* datetime);
|
||||
|
||||
/** Set date/time input header text
|
||||
*
|
||||
* @param date_time_input date/time input instance
|
||||
* @param text text to be shown
|
||||
*/
|
||||
void date_time_input_set_header_text(DateTimeInput* date_time_input, const char* text);
|
||||
|
||||
/** Set date/time fields which can be edited
|
||||
*
|
||||
* @param date_time_input date/time input instance
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
entry,status,name,type,params
|
||||
Version,+,86.0,,
|
||||
Version,+,87.0,,
|
||||
Header,+,applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h,,
|
||||
Header,+,applications/services/bt/bt_service/bt.h,,
|
||||
Header,+,applications/services/bt/bt_service/bt_keys_storage.h,,
|
||||
@@ -930,7 +930,6 @@ Function,+,date_time_input_alloc,DateTimeInput*,
|
||||
Function,+,date_time_input_free,void,DateTimeInput*
|
||||
Function,+,date_time_input_get_view,View*,DateTimeInput*
|
||||
Function,+,date_time_input_set_editable_fields,void,"DateTimeInput*, _Bool, _Bool, _Bool, _Bool, _Bool, _Bool"
|
||||
Function,+,date_time_input_set_header_text,void,"DateTimeInput*, const char*"
|
||||
Function,+,date_time_input_set_result_callback,void,"DateTimeInput*, DateTimeChangedCallback, DateTimeDoneCallback, void*, DateTime*"
|
||||
Function,+,datetime_datetime_to_timestamp,uint32_t,DateTime*
|
||||
Function,+,datetime_get_days_per_month,uint8_t,"_Bool, uint8_t"
|
||||
|
||||
|
Reference in New Issue
Block a user