diff --git a/CHANGELOG.md b/CHANGELOG.md index 318057a16..b54dd2914 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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) diff --git a/applications/main/archive/views/archive_browser_view.c b/applications/main/archive/views/archive_browser_view.c index 88124a32a..eaa7e0cc0 100644 --- a/applications/main/archive/views/archive_browser_view.c +++ b/applications/main/archive/views/archive_browser_view.c @@ -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); } diff --git a/applications/main/momentum_app/scenes/momentum_app_scene_interface_general.c b/applications/main/momentum_app/scenes/momentum_app_scene_interface_general.c index 9ca573950..2d5630089 100644 --- a/applications/main/momentum_app/scenes/momentum_app_scene_interface_general.c +++ b/applications/main/momentum_app/scenes/momentum_app_scene_interface_general.c @@ -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); diff --git a/applications/services/desktop/views/desktop_view_lock_menu.c b/applications/services/desktop/views/desktop_view_lock_menu.c index b001df687..d6e5ffd34 100644 --- a/applications/services/desktop/views/desktop_view_lock_menu.c +++ b/applications/services/desktop/views/desktop_view_lock_menu.c @@ -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"); diff --git a/applications/services/gui/canvas.c b/applications/services/gui/canvas.c index 0a9ef6612..9ecf33687 100644 --- a/applications/services/gui/canvas.c +++ b/applications/services/gui/canvas.c @@ -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; diff --git a/applications/services/gui/canvas.h b/applications/services/gui/canvas.h index 2168a4ea4..e1b8f1881 100644 --- a/applications/services/gui/canvas.h +++ b/applications/services/gui/canvas.h @@ -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 diff --git a/applications/services/gui/modules/variable_item_list.c b/applications/services/gui/modules/variable_item_list.c index 934972a53..ff73c2977 100644 --- a/applications/services/gui/modules/variable_item_list.c +++ b/applications/services/gui/modules/variable_item_list.c @@ -5,6 +5,7 @@ #include #include #include +#include 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); diff --git a/lib/momentum/settings.c b/lib/momentum/settings.c index dcb798f3b..c3ad95aa4 100644 --- a/lib/momentum/settings.c +++ b/lib/momentum/settings.c @@ -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)}, diff --git a/lib/momentum/settings.h b/lib/momentum/settings.h index 6ba0f935c..4c202c26d 100644 --- a/lib/momentum/settings.h +++ b/lib/momentum/settings.h @@ -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; diff --git a/targets/f7/api_symbols.csv b/targets/f7/api_symbols.csv index 440e87080..d8ed76c05 100644 --- a/targets/f7/api_symbols.csv +++ b/targets/f7/api_symbols.csv @@ -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*"