mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-04-24 03:29:57 -07:00
GUI: Checkerboard overlay behind popup elements (#380)
* GUI: Checkerboard overlay behind popup elements Adds setting 'Popup Overlay' (default ON) which draws a checkerboard pattern behind popups, like the Archive actions menu, keypad/pin lock modal, and the varitemlist locked message. Gives the illusion of separation from the popup element and the background content and is an aesthetic improvement. * Refactor * Update changelog --------- Co-authored-by: Willy-JL <49810075+Willy-JL@users.noreply.github.com>
This commit is contained in:
@@ -37,7 +37,9 @@
|
||||
- Add item count to directory info scene (#378 by @956MB)
|
||||
- OFW: Pinning of settings options (by @portasynthinca3)
|
||||
- Clock: 12 hour "midnight format" in Momentum Settings (#341 by @956MB)
|
||||
- GUI: Add marquee 'Text Scroll' option in Momentum Settings (#363 by @956MB)
|
||||
- GUI:
|
||||
- Add marquee 'Text Scroll' option in Momentum Settings (#363 by @956MB)
|
||||
- Checkerboard overlay behind popup elements, can be disabled in Momentum Settings (#380 by @956MB)
|
||||
- UL: Input: Vibro on Button press option (by @Dmitry422)
|
||||
- Desktop:
|
||||
- UL: Option to prevent Auto Lock when connected to USB/RPC (by @Dmitry422)
|
||||
|
||||
@@ -194,9 +194,9 @@ static void render_item_menu(Canvas* canvas, ArchiveBrowserViewModel* model) {
|
||||
const uint8_t calc_height = menu_height - ((MENU_ITEMS - size_menu - 1) * line_height);
|
||||
|
||||
canvas_set_color(canvas, ColorWhite);
|
||||
canvas_draw_box(canvas, 72, 2, 56, calc_height + 4);
|
||||
canvas_draw_rbox(canvas, 72, 2, 56, calc_height + 4, 3);
|
||||
canvas_set_color(canvas, ColorBlack);
|
||||
elements_slightly_rounded_frame(canvas, 71, 2, 57, calc_height + 4);
|
||||
canvas_draw_rframe(canvas, 71, 2, 57, calc_height + 4, 3);
|
||||
|
||||
canvas_draw_str_aligned(
|
||||
canvas, 100, 11, AlignCenter, AlignBottom, model->menu_manage ? "Manage:" : "Actions:");
|
||||
@@ -246,75 +246,93 @@ static void archive_draw_loading(Canvas* canvas, ArchiveBrowserViewModel* model)
|
||||
canvas_draw_icon(canvas, x, y, &A_Loading_24);
|
||||
}
|
||||
|
||||
static void draw_list(Canvas* canvas, ArchiveBrowserViewModel* model) {
|
||||
furi_assert(model);
|
||||
|
||||
static void draw_list_item(
|
||||
Canvas* canvas,
|
||||
ArchiveBrowserViewModel* model,
|
||||
bool scrollbar,
|
||||
uint32_t i,
|
||||
int32_t idx) {
|
||||
size_t array_size = files_array_size(model->files);
|
||||
bool scrollbar = model->item_cnt > 4;
|
||||
|
||||
for(uint32_t i = 0; i < MIN(model->item_cnt, MENU_ITEMS); ++i) {
|
||||
FuriString* str_buf;
|
||||
str_buf = furi_string_alloc();
|
||||
int32_t idx = CLAMP((uint32_t)(i + model->list_offset), model->item_cnt, 0u);
|
||||
uint8_t x_offset = (model->move_fav && model->item_idx == idx) ? MOVE_OFFSET : 0;
|
||||
FuriString* str_buf;
|
||||
str_buf = furi_string_alloc();
|
||||
uint8_t x_offset = (model->move_fav && model->item_idx == idx) ? MOVE_OFFSET : 0;
|
||||
|
||||
ArchiveFileTypeEnum file_type = ArchiveFileTypeLoading;
|
||||
uint8_t* custom_icon_data = NULL;
|
||||
ArchiveFileTypeEnum file_type = ArchiveFileTypeLoading;
|
||||
uint8_t* custom_icon_data = NULL;
|
||||
|
||||
if(!model->list_loading && archive_is_item_in_array(model, idx)) {
|
||||
ArchiveFile_t* file = files_array_get(
|
||||
model->files, CLAMP(idx - model->array_offset, (int32_t)(array_size - 1), 0));
|
||||
file_type = file->type;
|
||||
bool ext = model->tab_idx == ArchiveTabBrowser ||
|
||||
model->tab_idx == ArchiveTabInternal ||
|
||||
model->tab_idx == ArchiveTabDiskImage || model->tab_idx == ArchiveTabSearch;
|
||||
if(file_type == ArchiveFileTypeApplication) {
|
||||
if(file->custom_icon_data) {
|
||||
custom_icon_data = file->custom_icon_data;
|
||||
furi_string_set(str_buf, file->custom_name);
|
||||
} else {
|
||||
file_type = ArchiveFileTypeUnknown;
|
||||
path_extract_filename(file->path, str_buf, !ext);
|
||||
}
|
||||
if(!model->list_loading && archive_is_item_in_array(model, idx)) {
|
||||
ArchiveFile_t* file = files_array_get(
|
||||
model->files, CLAMP(idx - model->array_offset, (int32_t)(array_size - 1), 0));
|
||||
file_type = file->type;
|
||||
bool ext = model->tab_idx == ArchiveTabBrowser || model->tab_idx == ArchiveTabInternal ||
|
||||
model->tab_idx == ArchiveTabDiskImage || model->tab_idx == ArchiveTabSearch;
|
||||
if(file_type == ArchiveFileTypeApplication) {
|
||||
if(file->custom_icon_data) {
|
||||
custom_icon_data = file->custom_icon_data;
|
||||
furi_string_set(str_buf, file->custom_name);
|
||||
} else {
|
||||
file_type = ArchiveFileTypeUnknown;
|
||||
path_extract_filename(file->path, str_buf, !ext);
|
||||
}
|
||||
} else {
|
||||
furi_string_set(str_buf, "---");
|
||||
path_extract_filename(file->path, str_buf, !ext);
|
||||
}
|
||||
} else {
|
||||
furi_string_set(str_buf, "---");
|
||||
}
|
||||
|
||||
size_t scroll_counter = model->scroll_counter;
|
||||
size_t scroll_counter = model->scroll_counter;
|
||||
|
||||
if(!model->list_loading && model->item_idx == idx) {
|
||||
archive_draw_frame(canvas, i, scrollbar, model->move_fav);
|
||||
if(scroll_counter < SCROLL_DELAY) {
|
||||
scroll_counter = 0;
|
||||
} else {
|
||||
scroll_counter -= SCROLL_DELAY;
|
||||
}
|
||||
} else {
|
||||
canvas_set_color(canvas, ColorBlack);
|
||||
if(!model->list_loading && model->item_idx == idx) {
|
||||
archive_draw_frame(canvas, i, scrollbar, model->move_fav);
|
||||
if(scroll_counter < SCROLL_DELAY) {
|
||||
scroll_counter = 0;
|
||||
}
|
||||
|
||||
if(custom_icon_data) {
|
||||
canvas_draw_bitmap(
|
||||
canvas, 2 + x_offset, 16 + i * FRAME_HEIGHT, 11, 10, custom_icon_data);
|
||||
} else {
|
||||
canvas_draw_icon(
|
||||
canvas, 2 + x_offset, 16 + i * FRAME_HEIGHT, ArchiveItemIcons[file_type]);
|
||||
scroll_counter -= SCROLL_DELAY;
|
||||
}
|
||||
} else {
|
||||
canvas_set_color(canvas, ColorBlack);
|
||||
scroll_counter = 0;
|
||||
}
|
||||
|
||||
elements_scrollable_text_line(
|
||||
canvas,
|
||||
15 + x_offset,
|
||||
24 + i * FRAME_HEIGHT,
|
||||
((scrollbar ? MAX_LEN_PX - 6 : MAX_LEN_PX) - x_offset),
|
||||
str_buf,
|
||||
scroll_counter,
|
||||
(model->item_idx != idx));
|
||||
if(custom_icon_data) {
|
||||
canvas_draw_bitmap(canvas, 2 + x_offset, 16 + i * FRAME_HEIGHT, 11, 10, custom_icon_data);
|
||||
} else {
|
||||
canvas_draw_icon(canvas, 2 + x_offset, 16 + i * FRAME_HEIGHT, ArchiveItemIcons[file_type]);
|
||||
}
|
||||
|
||||
furi_string_free(str_buf);
|
||||
elements_scrollable_text_line(
|
||||
canvas,
|
||||
15 + x_offset,
|
||||
24 + i * FRAME_HEIGHT,
|
||||
((scrollbar ? MAX_LEN_PX - 6 : MAX_LEN_PX) - x_offset),
|
||||
str_buf,
|
||||
scroll_counter,
|
||||
(model->item_idx != idx));
|
||||
|
||||
furi_string_free(str_buf);
|
||||
}
|
||||
|
||||
static void draw_list(Canvas* canvas, ArchiveBrowserViewModel* model) {
|
||||
furi_assert(model);
|
||||
|
||||
bool scrollbar = model->item_cnt > 4;
|
||||
|
||||
for(uint32_t i = 0; i < MIN(model->item_cnt, MENU_ITEMS); ++i) {
|
||||
int32_t idx = CLAMP((uint32_t)(i + model->list_offset), model->item_cnt, 0u);
|
||||
if(model->item_idx == idx) continue;
|
||||
draw_list_item(canvas, model, scrollbar, i, idx);
|
||||
}
|
||||
|
||||
if(momentum_settings.popup_overlay && model->menu) {
|
||||
canvas_draw_overlay(canvas);
|
||||
}
|
||||
|
||||
for(uint32_t i = 0; i < MIN(model->item_cnt, MENU_ITEMS); ++i) {
|
||||
int32_t idx = CLAMP((uint32_t)(i + model->list_offset), model->item_cnt, 0u);
|
||||
if(model->item_idx != idx) continue;
|
||||
draw_list_item(canvas, model, scrollbar, i, idx);
|
||||
}
|
||||
|
||||
if(scrollbar) {
|
||||
@@ -361,7 +379,7 @@ static void archive_render_status_bar(Canvas* canvas, ArchiveBrowserViewModel* m
|
||||
9,
|
||||
45,
|
||||
model->archive->browser->formatted_path,
|
||||
model->scroll_counter,
|
||||
model->menu ? 0 : model->scroll_counter,
|
||||
false,
|
||||
true);
|
||||
}
|
||||
|
||||
@@ -26,6 +26,14 @@ static void momentum_app_scene_interface_general_midnight_format_changed(Variabl
|
||||
app->save_settings = true;
|
||||
}
|
||||
|
||||
static void momentum_app_scene_interface_general_popup_overlay_changed(VariableItem* item) {
|
||||
MomentumApp* app = variable_item_get_context(item);
|
||||
bool value = variable_item_get_current_value_index(item);
|
||||
variable_item_set_current_value_text(item, value ? "ON" : "OFF");
|
||||
momentum_settings.popup_overlay = value;
|
||||
app->save_settings = true;
|
||||
}
|
||||
|
||||
void momentum_app_scene_interface_general_on_enter(void* context) {
|
||||
MomentumApp* app = context;
|
||||
VariableItemList* var_item_list = app->var_item_list;
|
||||
@@ -51,6 +59,15 @@ void momentum_app_scene_interface_general_on_enter(void* context) {
|
||||
variable_item_set_current_value_text(
|
||||
item, momentum_settings.midnight_format_00 ? "00:XX" : "12:XX");
|
||||
|
||||
item = variable_item_list_add(
|
||||
var_item_list,
|
||||
"Popup Overlay",
|
||||
2,
|
||||
momentum_app_scene_interface_general_popup_overlay_changed,
|
||||
app);
|
||||
variable_item_set_current_value_index(item, momentum_settings.popup_overlay);
|
||||
variable_item_set_current_value_text(item, momentum_settings.popup_overlay ? "ON" : "OFF");
|
||||
|
||||
variable_item_list_set_enter_callback(
|
||||
var_item_list, momentum_app_scene_interface_general_var_item_list_callback, app);
|
||||
|
||||
|
||||
@@ -167,6 +167,9 @@ void desktop_lock_menu_draw_callback(Canvas* canvas, void* model) {
|
||||
}
|
||||
|
||||
if(m->show_lock_popup) {
|
||||
if(momentum_settings.popup_overlay) {
|
||||
canvas_draw_overlay(canvas);
|
||||
}
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
elements_bold_rounded_frame(canvas, 24, 4, 80, 56);
|
||||
canvas_draw_str_aligned(canvas, 64, 16, AlignCenter, AlignCenter, "Keypad Lock");
|
||||
|
||||
@@ -484,6 +484,22 @@ void canvas_draw_dot(Canvas* canvas, int32_t x, int32_t y) {
|
||||
u8g2_DrawPixel(&canvas->fb, x, y);
|
||||
}
|
||||
|
||||
void canvas_draw_overlay(Canvas* canvas) {
|
||||
furi_check(canvas);
|
||||
uint8_t original = canvas->fb.draw_color;
|
||||
canvas_set_color(canvas, ColorWhite);
|
||||
for(size_t j = 0; j < canvas->height; j++) {
|
||||
bool draw_pixel = (j % 2) == 0;
|
||||
for(size_t i = 0; i < canvas->width; i += 2) {
|
||||
size_t x = i + (draw_pixel ? 0 : 1);
|
||||
if(x < canvas->width) {
|
||||
canvas_draw_dot(canvas, x, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
canvas->fb.draw_color = original;
|
||||
}
|
||||
|
||||
void canvas_draw_box(Canvas* canvas, int32_t x, int32_t y, size_t width, size_t height) {
|
||||
furi_check(canvas);
|
||||
x += canvas->offset_x;
|
||||
|
||||
@@ -346,6 +346,12 @@ void canvas_draw_xbm_ex(
|
||||
*/
|
||||
void canvas_draw_dot(Canvas* canvas, int32_t x, int32_t y);
|
||||
|
||||
/** Draw overlay
|
||||
*
|
||||
* @param canvas Canvas instance
|
||||
*/
|
||||
void canvas_draw_overlay(Canvas* canvas);
|
||||
|
||||
/** Draw box of width, height at x,y
|
||||
*
|
||||
* @param canvas Canvas instance
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <assets_icons.h>
|
||||
#include <m-array.h>
|
||||
#include <stdint.h>
|
||||
#include <momentum/settings.h>
|
||||
|
||||
struct VariableItem {
|
||||
FuriString* label;
|
||||
@@ -146,6 +147,9 @@ static void variable_item_list_draw_callback(Canvas* canvas, void* _model) {
|
||||
elements_scrollbar(canvas, model->position, VariableItemArray_size(model->items));
|
||||
|
||||
if(model->locked_message_visible) {
|
||||
if(momentum_settings.popup_overlay) {
|
||||
canvas_draw_overlay(canvas);
|
||||
}
|
||||
canvas_set_color(canvas, ColorWhite);
|
||||
canvas_draw_box(canvas, 8, 10, 110, 48);
|
||||
canvas_set_color(canvas, ColorBlack);
|
||||
|
||||
@@ -37,6 +37,7 @@ MomentumSettings momentum_settings = {
|
||||
.rgb_backlight = false, // OFF
|
||||
.butthurt_timer = 21600, // 6 H
|
||||
.midnight_format_00 = true, // 00:XX
|
||||
.popup_overlay = true, // ON
|
||||
.spi_cc1101_handle = SpiDefault, // &furi_hal_spi_bus_handle_external
|
||||
.spi_nrf24_handle = SpiDefault, // &furi_hal_spi_bus_handle_external
|
||||
.uart_esp_channel = FuriHalSerialIdUsart, // pin 13,14
|
||||
@@ -109,6 +110,7 @@ static const struct {
|
||||
{setting_bool(rgb_backlight)},
|
||||
{setting_uint(butthurt_timer, 0, 172800)},
|
||||
{setting_bool(midnight_format_00)},
|
||||
{setting_bool(popup_overlay)},
|
||||
{setting_enum(spi_cc1101_handle, SpiCount)},
|
||||
{setting_enum(spi_nrf24_handle, SpiCount)},
|
||||
{setting_enum(uart_esp_channel, FuriHalSerialIdMax)},
|
||||
|
||||
@@ -94,6 +94,7 @@ typedef struct {
|
||||
bool rgb_backlight;
|
||||
uint32_t butthurt_timer;
|
||||
bool midnight_format_00;
|
||||
bool popup_overlay;
|
||||
SpiHandle spi_cc1101_handle;
|
||||
SpiHandle spi_nrf24_handle;
|
||||
FuriHalSerialId uart_esp_channel;
|
||||
|
||||
@@ -849,6 +849,7 @@ Function,+,canvas_draw_icon_animation,void,"Canvas*, int32_t, int32_t, IconAnima
|
||||
Function,+,canvas_draw_icon_animation_ex,void,"Canvas*, int32_t, int32_t, int32_t, int32_t, IconAnimation*"
|
||||
Function,+,canvas_draw_icon_ex,void,"Canvas*, int32_t, int32_t, const Icon*, IconRotation"
|
||||
Function,+,canvas_draw_line,void,"Canvas*, int32_t, int32_t, int32_t, int32_t"
|
||||
Function,+,canvas_draw_overlay,void,Canvas*
|
||||
Function,+,canvas_draw_rbox,void,"Canvas*, int32_t, int32_t, size_t, size_t, size_t"
|
||||
Function,+,canvas_draw_rframe,void,"Canvas*, int32_t, int32_t, size_t, size_t, size_t"
|
||||
Function,+,canvas_draw_str,void,"Canvas*, int32_t, int32_t, const char*"
|
||||
|
||||
|
Reference in New Issue
Block a user