1
mirror of https://github.com/DarkFlippers/unleashed-firmware.git synced 2025-12-12 20:49:49 +04:00

GUI module: SubMenu fix vertical orientation

This commit is contained in:
gid9798
2023-07-13 13:29:41 +03:00
parent ea357b8eaf
commit d3c0fbef3b
3 changed files with 103 additions and 25 deletions

View File

@@ -1,5 +1,4 @@
#include "submenu.h" #include "submenu.h"
#include <gui/canvas_i.h>
#include <assets_icons.h> #include <assets_icons.h>
#include <gui/elements.h> #include <gui/elements.h>
@@ -66,22 +65,23 @@ typedef struct {
size_t position; size_t position;
size_t window_position; size_t window_position;
bool locked_message_visible; bool locked_message_visible;
bool is_vertical;
} SubmenuModel; } SubmenuModel;
static void submenu_process_up(Submenu* submenu); static void submenu_process_up(Submenu* submenu);
static void submenu_process_down(Submenu* submenu); static void submenu_process_down(Submenu* submenu);
static void submenu_process_ok(Submenu* submenu); static void submenu_process_ok(Submenu* submenu);
static size_t submenu_items_on_screen(bool header, bool vertical) {
size_t res = (vertical) ? 8 : 4;
return (header) ? res - 1 : res;
}
static void submenu_view_draw_callback(Canvas* canvas, void* _model) { static void submenu_view_draw_callback(Canvas* canvas, void* _model) {
SubmenuModel* model = _model; SubmenuModel* model = _model;
const uint8_t item_height = 16; const uint8_t item_height = 16;
uint8_t item_width = 123; uint8_t item_width = canvas_width(canvas) - 5;
if(canvas->orientation == CanvasOrientationVertical ||
canvas->orientation == CanvasOrientationVerticalFlip) {
item_width = 60;
}
canvas_clear(canvas); canvas_clear(canvas);
@@ -97,7 +97,8 @@ static void submenu_view_draw_callback(Canvas* canvas, void* _model) {
for(SubmenuItemArray_it(it, model->items); !SubmenuItemArray_end_p(it); for(SubmenuItemArray_it(it, model->items); !SubmenuItemArray_end_p(it);
SubmenuItemArray_next(it)) { SubmenuItemArray_next(it)) {
const size_t item_position = position - model->window_position; const size_t item_position = position - model->window_position;
const size_t items_on_screen = furi_string_empty(model->header) ? 4 : 3; const size_t items_on_screen =
submenu_items_on_screen(!furi_string_empty(model->header), model->is_vertical);
uint8_t y_offset = furi_string_empty(model->header) ? 0 : 16; uint8_t y_offset = furi_string_empty(model->header) ? 0 : 16;
if(item_position < items_on_screen) { if(item_position < items_on_screen) {
@@ -117,7 +118,7 @@ static void submenu_view_draw_callback(Canvas* canvas, void* _model) {
if(SubmenuItemArray_cref(it)->locked) { if(SubmenuItemArray_cref(it)->locked) {
canvas_draw_icon( canvas_draw_icon(
canvas, canvas,
110, item_width - 10,
y_offset + (item_position * item_height) + item_height - 12, y_offset + (item_position * item_height) + item_height - 12,
&I_Lock_7x8); &I_Lock_7x8);
} }
@@ -125,7 +126,7 @@ static void submenu_view_draw_callback(Canvas* canvas, void* _model) {
FuriString* disp_str; FuriString* disp_str;
disp_str = furi_string_alloc_set(SubmenuItemArray_cref(it)->label); disp_str = furi_string_alloc_set(SubmenuItemArray_cref(it)->label);
elements_string_fit_width( elements_string_fit_width(
canvas, disp_str, item_width - (SubmenuItemArray_cref(it)->locked ? 25 : 11)); canvas, disp_str, item_width - (SubmenuItemArray_cref(it)->locked ? 21 : 11));
canvas_draw_str( canvas_draw_str(
canvas, canvas,
@@ -142,20 +143,39 @@ static void submenu_view_draw_callback(Canvas* canvas, void* _model) {
elements_scrollbar(canvas, model->position, SubmenuItemArray_size(model->items)); elements_scrollbar(canvas, model->position, SubmenuItemArray_size(model->items));
if(model->locked_message_visible) { if(model->locked_message_visible) {
const uint8_t frame_x = 7;
const uint8_t frame_width = canvas_width(canvas) - frame_x * 2;
const uint8_t frame_y = 7;
const uint8_t frame_height = canvas_height(canvas) - frame_y * 2;
canvas_set_color(canvas, ColorWhite); canvas_set_color(canvas, ColorWhite);
canvas_draw_box(canvas, 8, 10, 110, 48); canvas_draw_box(canvas, frame_x + 2, frame_y + 2, frame_width - 4, frame_height - 4);
canvas_set_color(canvas, ColorBlack); canvas_set_color(canvas, ColorBlack);
canvas_draw_icon(canvas, 10, 14, &I_WarningDolphin_45x42); canvas_draw_icon(
canvas_draw_rframe(canvas, 8, 8, 112, 50, 3); canvas, frame_x + 2, canvas_height(canvas) - frame_y - 2 - 42, &I_WarningDolphin_45x42);
canvas_draw_rframe(canvas, 9, 9, 110, 48, 2);
elements_multiline_text_aligned( canvas_draw_rframe(canvas, frame_x, frame_y, frame_width, frame_height, 3);
canvas, canvas_draw_rframe(canvas, frame_x + 1, frame_y + 1, frame_width - 2, frame_height - 2, 2);
84, if(model->is_vertical) {
32, elements_multiline_text_aligned(
AlignCenter, canvas,
AlignCenter, 32,
furi_string_get_cstr( 42,
SubmenuItemArray_get(model->items, model->position)->locked_message)); AlignCenter,
AlignCenter,
furi_string_get_cstr(
SubmenuItemArray_get(model->items, model->position)->locked_message));
} else {
elements_multiline_text_aligned(
canvas,
84,
32,
AlignCenter,
AlignCenter,
furi_string_get_cstr(
SubmenuItemArray_get(model->items, model->position)->locked_message));
}
} }
} }
@@ -303,6 +323,7 @@ void submenu_add_lockable_item(
void submenu_reset(Submenu* submenu) { void submenu_reset(Submenu* submenu) {
furi_assert(submenu); furi_assert(submenu);
view_set_orientation(submenu->view, ViewOrientationHorizontal);
with_view_model( with_view_model(
submenu->view, submenu->view,
@@ -311,6 +332,7 @@ void submenu_reset(Submenu* submenu) {
SubmenuItemArray_reset(model->items); SubmenuItemArray_reset(model->items);
model->position = 0; model->position = 0;
model->window_position = 0; model->window_position = 0;
model->is_vertical = false;
furi_string_reset(model->header); furi_string_reset(model->header);
}, },
true); true);
@@ -344,7 +366,8 @@ void submenu_set_selected_item(Submenu* submenu, uint32_t index) {
model->window_position -= 1; model->window_position -= 1;
} }
const size_t items_on_screen = furi_string_empty(model->header) ? 4 : 3; const size_t items_on_screen =
submenu_items_on_screen(!furi_string_empty(model->header), model->is_vertical);
if(items_size <= items_on_screen) { if(items_size <= items_on_screen) {
model->window_position = 0; model->window_position = 0;
@@ -363,7 +386,8 @@ void submenu_process_up(Submenu* submenu) {
submenu->view, submenu->view,
SubmenuModel * model, SubmenuModel * model,
{ {
const size_t items_on_screen = furi_string_empty(model->header) ? 4 : 3; const size_t items_on_screen =
submenu_items_on_screen(!furi_string_empty(model->header), model->is_vertical);
const size_t items_size = SubmenuItemArray_size(model->items); const size_t items_size = SubmenuItemArray_size(model->items);
if(model->position > 0) { if(model->position > 0) {
@@ -386,7 +410,8 @@ void submenu_process_down(Submenu* submenu) {
submenu->view, submenu->view,
SubmenuModel * model, SubmenuModel * model,
{ {
const size_t items_on_screen = furi_string_empty(model->header) ? 4 : 3; const size_t items_on_screen =
submenu_items_on_screen(!furi_string_empty(model->header), model->is_vertical);
const size_t items_size = SubmenuItemArray_size(model->items); const size_t items_size = SubmenuItemArray_size(model->items);
if(model->position < items_size - 1) { if(model->position < items_size - 1) {
@@ -441,3 +466,48 @@ void submenu_set_header(Submenu* submenu, const char* header) {
}, },
true); true);
} }
void submenu_set_orientation(Submenu* submenu, ViewOrientation orientation) {
furi_assert(submenu);
const bool is_vertical =
(orientation == ViewOrientationVertical || orientation == ViewOrientationVerticalFlip) ?
true :
false;
view_set_orientation(submenu->view, orientation);
with_view_model(
submenu->view,
SubmenuModel * model,
{
model->is_vertical = is_vertical;
// Recalculating the position
// Need if _set_orientation is called after _set_selected_item
size_t position = model->position;
const size_t items_size = SubmenuItemArray_size(model->items);
const size_t items_on_screen =
submenu_items_on_screen(!furi_string_empty(model->header), model->is_vertical);
if(position >= items_size) {
position = 0;
}
model->position = position;
model->window_position = position;
if(model->window_position > 0) {
model->window_position -= 1;
}
if(items_size <= items_on_screen) {
model->window_position = 0;
} else {
const size_t pos = items_size - items_on_screen;
if(model->window_position > pos) {
model->window_position = pos;
}
}
},
true);
}

View File

@@ -93,6 +93,13 @@ void submenu_set_selected_item(Submenu* submenu, uint32_t index);
*/ */
void submenu_set_header(Submenu* submenu, const char* header); void submenu_set_header(Submenu* submenu, const char* header);
/** Set Orientation
*
* @param submenu Submenu instance
* @param orientation either vertical or horizontal
*/
void submenu_set_orientation(Submenu* submenu, ViewOrientation orientation);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -2912,6 +2912,7 @@ Function,+,submenu_free,void,Submenu*
Function,+,submenu_get_view,View*,Submenu* Function,+,submenu_get_view,View*,Submenu*
Function,+,submenu_reset,void,Submenu* Function,+,submenu_reset,void,Submenu*
Function,+,submenu_set_header,void,"Submenu*, const char*" Function,+,submenu_set_header,void,"Submenu*, const char*"
Function,+,submenu_set_orientation,void,"Submenu*, ViewOrientation"
Function,+,submenu_set_selected_item,void,"Submenu*, uint32_t" Function,+,submenu_set_selected_item,void,"Submenu*, uint32_t"
Function,-,system,int,const char* Function,-,system,int,const char*
Function,+,t5577_write,void,LFRFIDT5577* Function,+,t5577_write,void,LFRFIDT5577*
1 entry status name type params
2912 Function + submenu_get_view View* Submenu*
2913 Function + submenu_reset void Submenu*
2914 Function + submenu_set_header void Submenu*, const char*
2915 Function + submenu_set_orientation void Submenu*, ViewOrientation
2916 Function + submenu_set_selected_item void Submenu*, uint32_t
2917 Function - system int const char*
2918 Function + t5577_write void LFRFIDT5577*