mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-07-31 02:23:04 -07:00
updated protoview
This commit is contained in:
@@ -3,6 +3,122 @@
|
||||
|
||||
#include "app.h"
|
||||
|
||||
/* =========================== Subview handling ================================
|
||||
* Note that these are not the Flipper subviews, but the subview system
|
||||
* implemented inside ProtoView.
|
||||
* ========================================================================== */
|
||||
|
||||
/* Return the ID of the currently selected subview, of the current
|
||||
* view. */
|
||||
int ui_get_current_subview(ProtoViewApp *app) {
|
||||
return app->current_subview[app->current_view];
|
||||
}
|
||||
|
||||
/* Called by view rendering callback that has subviews, to show small triangles
|
||||
* facing down/up if there are other subviews the user can access with up
|
||||
* and down. */
|
||||
void ui_show_available_subviews(Canvas *canvas, ProtoViewApp *app,
|
||||
int last_subview)
|
||||
{
|
||||
int subview = ui_get_current_subview(app);
|
||||
if (subview != 0)
|
||||
canvas_draw_triangle(canvas,120,5,8,5,CanvasDirectionBottomToTop);
|
||||
if (subview != last_subview-1)
|
||||
canvas_draw_triangle(canvas,120,59,8,5,CanvasDirectionTopToBottom);
|
||||
}
|
||||
|
||||
/* Handle up/down keys when we are in a subview. If the function catched
|
||||
* such keypress, it returns true, so that the actual view input callback
|
||||
* knows it can just return ASAP without doing anything. */
|
||||
bool ui_process_subview_updown(ProtoViewApp *app, InputEvent input, int last_subview) {
|
||||
int subview = ui_get_current_subview(app);
|
||||
if (input.type == InputTypePress) {
|
||||
if (input.key == InputKeyUp) {
|
||||
if (subview != 0)
|
||||
app->current_subview[app->current_view]--;
|
||||
return true;
|
||||
} else if (input.key == InputKeyDown) {
|
||||
if (subview != last_subview-1)
|
||||
app->current_subview[app->current_view]++;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* ============================= Text input ====================================
|
||||
* Normally we just use our own private UI widgets. However for the text input
|
||||
* widget, that is quite complex, visualizes a keyboard and must be standardized
|
||||
* for user coherent experience, we use the one provided by the Flipper
|
||||
* framework. The following two functions allow to show the keyboard to get
|
||||
* text and later dismiss it.
|
||||
* ========================================================================== */
|
||||
|
||||
/* Show the keyboard, take the user input and store it into the specified
|
||||
* 'buffer' of 'buflen' total bytes. When the user is done, the done_callback
|
||||
* is called passing the application context to it. Such callback needs
|
||||
* to do whatever it wants with the input buffer and dismissi the keyboard
|
||||
* calling: dismiss_keyboard(app);
|
||||
*
|
||||
* Note: if the buffer is not a null-termined zero string, what it contains will
|
||||
* be used as initial input for the user. */
|
||||
void ui_show_keyboard(ProtoViewApp *app, char *buffer, uint32_t buflen,
|
||||
void (*done_callback)(void*))
|
||||
{
|
||||
app->show_text_input = true;
|
||||
app->text_input_buffer = buffer;
|
||||
app->text_input_buffer_len = buflen;
|
||||
app->text_input_done_callback = done_callback;
|
||||
}
|
||||
|
||||
void ui_dismiss_keyboard(ProtoViewApp *app) {
|
||||
view_dispatcher_stop(app->view_dispatcher);
|
||||
}
|
||||
|
||||
/* ================================= Alert ================================== */
|
||||
|
||||
/* Set an alert message to be shown over any currently active view, for
|
||||
* the specified amount of time of 'ttl' milliseconds. */
|
||||
void ui_show_alert(ProtoViewApp *app, const char *text, uint32_t ttl) {
|
||||
app->alert_dismiss_time = furi_get_tick() + furi_ms_to_ticks(ttl);
|
||||
snprintf(app->alert_text,ALERT_MAX_LEN,"%s",text);
|
||||
}
|
||||
|
||||
/* Cancel the alert before its time has elapsed. */
|
||||
void ui_dismiss_alert(ProtoViewApp *app) {
|
||||
app->alert_dismiss_time = 0;
|
||||
}
|
||||
|
||||
/* Show the alert if an alert is set. This is called after the currently
|
||||
* active view displayed its stuff, so we overwrite the screen with the
|
||||
* alert message. */
|
||||
void ui_draw_alert_if_needed(Canvas *canvas, ProtoViewApp *app) {
|
||||
if (app->alert_dismiss_time == 0) {
|
||||
/* No active alert. */
|
||||
return;
|
||||
} else if (app->alert_dismiss_time < furi_get_tick()) {
|
||||
/* Alert just expired. */
|
||||
ui_dismiss_alert(app);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Show the alert. A box with black border and a text inside. */
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
uint8_t w = canvas_string_width(canvas, app->alert_text);
|
||||
uint8_t h = 8; // Font height.
|
||||
uint8_t text_x = 64-(w/2);
|
||||
uint8_t text_y = 32+4;
|
||||
uint8_t padding = 3;
|
||||
canvas_set_color(canvas,ColorBlack);
|
||||
canvas_draw_box(canvas,text_x-padding,text_y-padding-h,w+padding*2,h+padding*2);
|
||||
canvas_set_color(canvas,ColorWhite);
|
||||
canvas_draw_box(canvas,text_x-padding+1,text_y-padding-h+1,w+padding*2-2,h+padding*2-2);
|
||||
canvas_set_color(canvas,ColorBlack);
|
||||
canvas_draw_str(canvas,text_x,text_y,app->alert_text);
|
||||
}
|
||||
|
||||
/* =========================== Canvas extensions ============================ */
|
||||
|
||||
void canvas_draw_str_with_border(Canvas* canvas, uint8_t x, uint8_t y, const char* str, Color text_color, Color border_color)
|
||||
{
|
||||
struct {
|
||||
|
||||
Reference in New Issue
Block a user