-
Notifications
You must be signed in to change notification settings - Fork 67
Modules
This page is currently under development.
Modules are a User Interface concept, but the topic is so big I decided to make a separate page for them. The code for all of the modules is found in the applications/services/gui/modules folder in the firmware.
Modules are views that you can configure with specific data, then leverage the view in your own application. All modules expose _alloc, _free and _get_view methods. Many modules also expose methods to configure the module and to set additional callbacks needed by the module (like result_callback, validator_callback, etc.)
For a list of all of the modules available in applications/services/gui, please see A Visual Guide to Flipper Zero GUI Components over on brodan.biz/blog.
Lots of information we can add about Widget. I wonder if Instantiator has anything written already?
TextBox is a Module that handles display of large amounts of text, and supports scrolling.
Import the header file for the TextBox object.
#include <gui/modules/text_box.h>
Returns a TextBox object & allocates resources (such as model).
TextBox* text_box = text_box_alloc();
Resets the allocated TextBox object to default state (text set to NULL, font reset to default, focus is at the beginning of the text).
text_box_reset(text_box);
Returns the View associated with a TextBox.
TextBox* text_box_view = text_box_get_view(text_box);
// Typically, apps register the returned View with a view dispatcher, then switch to it to show the view.
Sets the text which will be displayed in the text box. The length of the text is only limited by Flipper availble resources, so take appropriate recautions if you plan to display a text with unknown length (such as some log for example).
text_box_set_text(text_box, "Enter your name");
Sets the display font for TextBox (TextBoxFontText
or TextBoxFontHex
).
Font is set to TextBoxFontText
when text_box_alloc()
or text_box_reset()
called.
text_box_set_font(text_box, TextBoxFontHex);
Sets the cursor position in a TextBox. TextBoxFocusStart
puts cursor at the beginning of the text, TextBoxFocusEnd
puts the cursor at the end of ext. text_box_alloc()
or text_box_reset()
both put cursor at the beginning of the text.
text_box_set_focus(text_box, TextBoxFocusEnd);
Frees all resources allocated by text_box_alloc.
TextInput is a Module that has a header row (prompt text) and a keyboard for the user to enter data. When the user clicks on 'ENTER' it will run a validator. If the validation fails, it will show the validation messsage. If the validation passes (or there is no validator) then it will invoke the result callback with the text from the user. Long press on the keyboard inverts the case (lower/upper) from what is displayed. This keyboard only seems to support uppercase A-Z, lowercase a-z, digits 0-9, space, underscore.
Import the header file for the TextInput object.
#include <gui/modules/text_input.h>
Returns a TextInput object & allocates resources (such as model and timer).
TextInput* text_input = text_input_alloc();
Clears the buffers, cursors and header text that is associated with the TextInput. This is already called for your during text_input_alloc
.
// Clear everything, including the header text.
text_input_reset(text_input);
Sets the header text (prompt at the top of input).
text_input_set_header_text(text_input, "Enter your name");
When ENTER is pressed on the keyboard, if a validator is set it will invoke the validation callback to confirm the entry is valid. The callback returns true if the entry is valid, and false if it is invalid. text_input_set_validator
sets the TextInputValidatorCallback
and context parameter to pass to the validation callback. The TextInputValidator takes three parameters. The first parameter (const char* text) is the text to validate. The second parameter is a FuriString* with the error message to display. The third parameter is the context that was originally passed to text_input_set_validator
. NOTE: The validation message does not automatically wrap, so you need to test your message to ensure it fits properly (use \n for forced line breaks).
// The first parameter is the text the user entered.
// The second parameter is a FuriString that you can set for returning error message.
// The third parameter is the context that was passed when registering the callback.
bool text_input_validator(const char* text, FuriString* error, void* context) {
UNUSED(context);
bool validated = true;
if(strlen(text) < 3) {
furi_string_set(error, "123456789012345\nWWWWWWWWWWWW\niiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii!");
validated = false;
}
return validated;
}
When configuring your text_input, you would use code similar to the following:
// The context parameter will be the void* context your callback will get.
text_input_set_validator(app->text_input, text_input_validator, my_context);
Sets the result callback that gets invoked when the user presses ENTER on the keyboard and validation passed (or no validator was present).
void text_input_callback(void* context) {
UNUSED(context);
// User has entered text, which is stored in the buffer we provided when registering this callback.
}
When configuring your text_input, you would use code similar to the following:
uint8_t user_name_size = 16;
char* user_name = malloc(user_name_size);
text_input_set_result_callback(text_input, text_input_callback, my_context, user_name, user_name_size, true);
Returns the View associated with a TextInput.
View* input_view = text_input_get_view(text_input);
// Typically, apps register the returned View with a view dispatcher, then switch to it to show the view.
Frees all resources allocated by text_input_alloc, including the timer resource.
text_input_free(text_input);
VariableItemList is a Module that is often used for configuration. Each added item has a label, a current value, an index, a count, and a callback. Left and right arrows appear/disappear depending on where your index is relative to the count. When left or right button is pressed, a callback for that item is invoked. The callback has access to context and the new index. The callback typically returns the updated text to display. When up or down is pressed, the selected item changes. When OK is pressed, the enter callback is invoked.
Import the header file for the VariableItemList object.
#include <gui/modules/variable_item_list.h>
Returns a VariableItemList object & allocates resources (such as model).
VariableItemList* variable_item_list = variable_item_list_alloc();
Clears the items and strings associated with the list. TODO: It does not clear out position or window_position; so what happens if different size number of items are added?
// Remove all the items from the list.
variable_item_list_reset(variable_item_list);
Adds an item to the list. Specify the label, total entries for this item, callback, and a context for the item. The returned object is a VariableItem*, which is updated with variable_item_set_current_value_index
and variable_item_set_current_value_text
to display the current values.
Typically, you have a callback that will update the text based on current item index:
void x_offset_change_callback(VariableItem* item) {
App* app = variable_item_get_context(item); // get context passed during variable_item_list_add.
uint8_t index = variable_item_get_current_value_index(item);
variable_item_set_current_value_text(item, x_offset_strings[index]);
app->x_offset = x_offset_values[index];
}
Here is the code that adds an item to the list...
VariableItem* item = variable_item_list_add(variable_item_list,
"X offset", // label to display
COUNT_OF(x_offset_strings), // number of choices
x_offset_change_callback, // callback
app); // context [use variable_item_get_context(item) to access]
And then you will want to use the returned value to add the current index and text...
variable_item_set_current_value_index(item, 0);
variable_item_set_current_value_text(item, x_offset_strings[0]);
Used to set the current index of the VariableItem* that was returned by variable_item_list_add
. This should be less than the total count that was passed to the add method. If the index is 0, there will be no left arrow icon. If the index is (total-1) there will be no right arrow icon.
variable_item_set_current_value_index(item, 0);
Used to set the current text of the VariableItem* that was returned by variable_item_list_add
. This is used both to set the initial value and also in the update callback to change the text based on the variable_item_get_current_value_index
.
variable_item_set_current_value_text(item, x_offset_strings[i]);
Gets the context of the VariableItem* that was specified when the item was added.
App* app = variable_item_get_context(item); // get context passed during variable_item_list_add.
Gets the current index of the VariableItem*. Typically, this is used in the update callback to get the current index and then set the new text based on this index.
uint8_t index = variable_item_get_current_value_index(item);
Returns the View associated with a VariableItemList.
View* list_view = variable_item_list_get_view(variable_item_list);
// Typically, apps register the returned View with a view dispatcher, then switch to it to show the view.
Sets a callback to invoke when the OK button is pressed.
Define a callback to invoke:
// The selected item index is a uint32_t but the internal position index is actually a uint8_t.
void enter_callback(void* context, uint32_t index) {
}
Register the callback to invoke when the OK button is pressed
variable_item_list_set_enter_callback(variable_item_list,
enter_callback, // callback function to invoke on OK press
app); // context object to pass to the callback function
Frees all resources allocated by variable_item_list_alloc.
variable_item_list_free(variable_item_list);
Sets which item is selected. This is helpful if you want restore a previous selection (like have a config screen that continues where it was before).
variable_item_list_set_selected_item(variable_item_list, index);
Sets which entry is selected within the item.
variable_item_set_current_value_index(variable_item, index);
Sets the total number of entries for an item.
### variable_item_set_values_count(variable_item, new_count);
Gets which item index is selected. Typically, you would register an enter callback, which will already be provided this index.
uint8_t current_index = variable_item_list_get_selected_item_index(variable_item_list);