Просмотр исходного кода

GUI: Icons and IconsAnimation refactoring. Switch assets to new Icon Api (#566)

* GUI: Icons and IconsAnimation refactoring. Switch assets to new Icon API.
* Gui: icon and animation draw now do not accept null pointer
* Format Sources
* Fix no debug build
* Furi: stricter checks in memmgr
あく 4 лет назад
Родитель
Сommit
a7283280ef
82 измененных файлов с 716 добавлено и 663 удалено
  1. 7 7
      applications/app-loader/app-loader.c
  2. 59 53
      applications/applications.c
  3. 1 1
      applications/applications.h
  4. 13 13
      applications/archive/archive_views.c
  5. 2 2
      applications/bt/bt.c
  6. 1 1
      applications/bt/bt_i.h
  7. 18 13
      applications/dolphin/dolphin.c
  8. 1 4
      applications/dolphin/dolphin_i.h
  9. 13 13
      applications/dolphin/dolphin_views.c
  10. 1 1
      applications/dolphin/dolphin_views.h
  11. 16 16
      applications/dolphin/passport/passport.c
  12. 8 8
      applications/dolphin/scenes/assets/items.c
  13. 3 3
      applications/dolphin/scenes/scene.h
  14. 14 14
      applications/dolphin/scenes/scene_gfx.c
  15. 2 2
      applications/gui-test/gui-test.c
  16. 19 6
      applications/gui/canvas.c
  17. 18 8
      applications/gui/canvas.h
  18. 13 10
      applications/gui/elements.c
  19. 1 1
      applications/gui/gui.c
  20. 6 68
      applications/gui/icon.c
  21. 4 51
      applications/gui/icon.h
  22. 77 0
      applications/gui/icon_animation.c
  23. 67 0
      applications/gui/icon_animation.h
  24. 21 0
      applications/gui/icon_animation_i.h
  25. 1 21
      applications/gui/icon_i.h
  26. 2 2
      applications/gui/modules/button_menu.c
  27. 6 6
      applications/gui/modules/button_panel.c
  28. 2 2
      applications/gui/modules/button_panel.h
  29. 16 16
      applications/gui/modules/byte_input.c
  30. 6 6
      applications/gui/modules/dialog_ex.c
  31. 1 1
      applications/gui/modules/dialog_ex.h
  32. 6 6
      applications/gui/modules/popup.c
  33. 1 1
      applications/gui/modules/popup.h
  34. 8 8
      applications/gui/modules/text_input.c
  35. 1 1
      applications/gui/view_dispatcher.c
  36. 2 2
      applications/ibutton/scene/ibutton-scene-delete-success.cpp
  37. 2 2
      applications/ibutton/scene/ibutton-scene-emulate.cpp
  38. 2 2
      applications/ibutton/scene/ibutton-scene-read-success.cpp
  39. 2 2
      applications/ibutton/scene/ibutton-scene-read.cpp
  40. 2 2
      applications/ibutton/scene/ibutton-scene-save-success.cpp
  41. 2 2
      applications/ibutton/scene/ibutton-scene-write-success.cpp
  42. 2 2
      applications/ibutton/scene/ibutton-scene-write.cpp
  43. 1 2
      applications/irda/irda_app_old.c
  44. 1 1
      applications/irda/scene/irda-app-scene-edit-delete-done.cpp
  45. 1 1
      applications/irda/scene/irda-app-scene-edit-delete.cpp
  46. 1 1
      applications/irda/scene/irda-app-scene-edit-rename-done.cpp
  47. 1 1
      applications/irda/scene/irda-app-scene-learn-done-after.cpp
  48. 1 1
      applications/irda/scene/irda-app-scene-learn-done.cpp
  49. 1 1
      applications/irda/scene/irda-app-scene-learn-success.cpp
  50. 1 1
      applications/irda/scene/irda-app-scene-learn.cpp
  51. 35 8
      applications/irda/scene/irda-app-scene-universal-tv.cpp
  52. 1 1
      applications/irda/view/irda-app-brut-view.c
  53. 1 1
      applications/lfrfid/scene/lfrfid-app-scene-delete-success.cpp
  54. 1 1
      applications/lfrfid/scene/lfrfid-app-scene-emulate.cpp
  55. 1 1
      applications/lfrfid/scene/lfrfid-app-scene-read-success.cpp
  56. 1 1
      applications/lfrfid/scene/lfrfid-app-scene-read.cpp
  57. 1 1
      applications/lfrfid/scene/lfrfid-app-scene-save-success.cpp
  58. 1 1
      applications/lfrfid/scene/lfrfid-app-scene-write-success.cpp
  59. 2 2
      applications/lfrfid/scene/lfrfid-app-scene-write.cpp
  60. 4 4
      applications/lfrfid/view/elements/icon-element.cpp
  61. 2 2
      applications/lfrfid/view/elements/icon-element.h
  62. 7 7
      applications/menu/menu.c
  63. 5 5
      applications/menu/menu_item.c
  64. 5 5
      applications/menu/menu_item.h
  65. 2 2
      applications/nfc/scenes/nfc_scene_emulate_uid.c
  66. 2 2
      applications/nfc/scenes/nfc_scene_read_card.c
  67. 2 2
      applications/nfc/scenes/nfc_scene_read_card_success.c
  68. 2 2
      applications/nfc/scenes/nfc_scene_save_success.c
  69. 4 5
      applications/power/power.c
  70. 11 11
      applications/power/power_views.c
  71. 6 6
      applications/sd-filesystem/sd-filesystem.c
  72. 2 2
      applications/sd-filesystem/sd-filesystem.h
  73. 2 1
      assets/compiled/assets_icons.c
  74. 143 149
      assets/compiled/assets_icons.h
  75. 0 5
      assets/compiled/assets_icons_i.h
  76. BIN
      assets/icons/Common/Empty_1x1.png
  77. 3 4
      core/furi/memmgr_heap.c
  78. 3 3
      lib/app-scened-template/view-modules/dialog-ex-vm.cpp
  79. 1 1
      lib/app-scened-template/view-modules/dialog-ex-vm.h
  80. 3 3
      lib/app-scened-template/view-modules/popup-vm.cpp
  81. 1 1
      lib/app-scened-template/view-modules/popup-vm.h
  82. 5 36
      scripts/assets.py

+ 7 - 7
applications/app-loader/app-loader.c

@@ -140,7 +140,7 @@ int32_t app_loader(void* p) {
                     menu,
                     menu,
                     menu_item_alloc_function(
                     menu_item_alloc_function(
                         FLIPPER_APPS[i].name,
                         FLIPPER_APPS[i].name,
-                        assets_icons_get(FLIPPER_APPS[i].icon),
+                        icon_animation_alloc(FLIPPER_APPS[i].icon),
                         app_loader_menu_callback,
                         app_loader_menu_callback,
                         (void*)&FLIPPER_APPS[i]));
                         (void*)&FLIPPER_APPS[i]));
 
 
@@ -162,7 +162,7 @@ int32_t app_loader(void* p) {
     with_value_mutex(
     with_value_mutex(
         menu_mutex, (Menu * menu) {
         menu_mutex, (Menu * menu) {
             MenuItem* menu_plugins =
             MenuItem* menu_plugins =
-                menu_item_alloc_menu("Plugins", assets_icons_get(A_Plugins_14));
+                menu_item_alloc_menu("Plugins", icon_animation_alloc(&A_Plugins_14));
 
 
             for(size_t i = 0; i < FLIPPER_PLUGINS_COUNT; i++) {
             for(size_t i = 0; i < FLIPPER_PLUGINS_COUNT; i++) {
                 // Add menu item
                 // Add menu item
@@ -170,7 +170,7 @@ int32_t app_loader(void* p) {
                     menu_plugins,
                     menu_plugins,
                     menu_item_alloc_function(
                     menu_item_alloc_function(
                         FLIPPER_PLUGINS[i].name,
                         FLIPPER_PLUGINS[i].name,
-                        assets_icons_get(FLIPPER_PLUGINS[i].icon),
+                        icon_animation_alloc(FLIPPER_PLUGINS[i].icon),
                         app_loader_menu_callback,
                         app_loader_menu_callback,
                         (void*)&FLIPPER_PLUGINS[i]));
                         (void*)&FLIPPER_PLUGINS[i]));
 
 
@@ -194,7 +194,7 @@ int32_t app_loader(void* p) {
     with_value_mutex(
     with_value_mutex(
         menu_mutex, (Menu * menu) {
         menu_mutex, (Menu * menu) {
             MenuItem* menu_debug =
             MenuItem* menu_debug =
-                menu_item_alloc_menu("Debug tools", assets_icons_get(A_Settings_14));
+                menu_item_alloc_menu("Debug tools", icon_animation_alloc(&A_Settings_14));
 
 
             for(size_t i = 0; i < FLIPPER_DEBUG_APPS_COUNT; i++) {
             for(size_t i = 0; i < FLIPPER_DEBUG_APPS_COUNT; i++) {
                 // Add menu item
                 // Add menu item
@@ -202,7 +202,7 @@ int32_t app_loader(void* p) {
                     menu_debug,
                     menu_debug,
                     menu_item_alloc_function(
                     menu_item_alloc_function(
                         FLIPPER_DEBUG_APPS[i].name,
                         FLIPPER_DEBUG_APPS[i].name,
-                        assets_icons_get(FLIPPER_DEBUG_APPS[i].icon),
+                        icon_animation_alloc(FLIPPER_DEBUG_APPS[i].icon),
                         app_loader_menu_callback,
                         app_loader_menu_callback,
                         (void*)&FLIPPER_DEBUG_APPS[i]));
                         (void*)&FLIPPER_DEBUG_APPS[i]));
 
 
@@ -226,7 +226,7 @@ int32_t app_loader(void* p) {
     with_value_mutex(
     with_value_mutex(
         menu_mutex, (Menu * menu) {
         menu_mutex, (Menu * menu) {
             MenuItem* menu_debug =
             MenuItem* menu_debug =
-                menu_item_alloc_menu("Settings", assets_icons_get(A_Settings_14));
+                menu_item_alloc_menu("Settings", icon_animation_alloc(&A_Settings_14));
 
 
             for(size_t i = 0; i < FLIPPER_SETTINGS_APPS_COUNT; i++) {
             for(size_t i = 0; i < FLIPPER_SETTINGS_APPS_COUNT; i++) {
                 // Add menu item
                 // Add menu item
@@ -234,7 +234,7 @@ int32_t app_loader(void* p) {
                     menu_debug,
                     menu_debug,
                     menu_item_alloc_function(
                     menu_item_alloc_function(
                         FLIPPER_SETTINGS_APPS[i].name,
                         FLIPPER_SETTINGS_APPS[i].name,
-                        assets_icons_get(FLIPPER_SETTINGS_APPS[i].icon),
+                        icon_animation_alloc(FLIPPER_SETTINGS_APPS[i].icon),
                         app_loader_menu_callback,
                         app_loader_menu_callback,
                         (void*)&FLIPPER_SETTINGS_APPS[i]));
                         (void*)&FLIPPER_SETTINGS_APPS[i]));
             }
             }

+ 59 - 53
applications/applications.c

@@ -53,112 +53,115 @@ int32_t notification_app_settings(void* p);
 
 
 const FlipperApplication FLIPPER_SERVICES[] = {
 const FlipperApplication FLIPPER_SERVICES[] = {
 #ifdef SRV_CLI
 #ifdef SRV_CLI
-    {.app = cli_task, .name = "cli_task", .stack_size = 4096, .icon = A_Plugins_14},
+    {.app = cli_task, .name = "cli_task", .stack_size = 4096, .icon = &A_Plugins_14},
 #endif
 #endif
 
 
 #ifdef SRV_EXAMPLE_BLINK
 #ifdef SRV_EXAMPLE_BLINK
-    {.app = application_blink, .name = "blink", .stack_size = 1024, .icon = A_Plugins_14},
+    {.app = application_blink, .name = "blink", .stack_size = 1024, .icon = &A_Plugins_14},
 #endif
 #endif
 
 
 #ifdef SRV_INPUT
 #ifdef SRV_INPUT
-    {.app = input_task, .name = "input_task", .stack_size = 1024, .icon = A_Plugins_14},
+    {.app = input_task, .name = "input_task", .stack_size = 1024, .icon = &A_Plugins_14},
 #endif
 #endif
 
 
 #ifdef SRV_EXAMPLE_INPUT_DUMP
 #ifdef SRV_EXAMPLE_INPUT_DUMP
-    {.app = application_input_dump, .name = "input dump", .stack_size = 1024, .icon = A_Plugins_14},
+    {.app = application_input_dump,
+     .name = "input dump",
+     .stack_size = 1024,
+     .icon = &A_Plugins_14},
 #endif
 #endif
 
 
 #ifdef SRV_GUI
 #ifdef SRV_GUI
     // TODO: fix stack size when sd api will be in separate thread
     // TODO: fix stack size when sd api will be in separate thread
-    {.app = gui_task, .name = "gui_task", .stack_size = 8192, .icon = A_Plugins_14},
+    {.app = gui_task, .name = "gui_task", .stack_size = 8192, .icon = &A_Plugins_14},
 #endif
 #endif
 
 
 #ifdef SRV_MENU
 #ifdef SRV_MENU
-    {.app = menu_task, .name = "menu_task", .stack_size = 1024, .icon = A_Plugins_14},
-    {.app = app_loader, .name = "app_loader", .stack_size = 1024, .icon = A_Plugins_14},
+    {.app = menu_task, .name = "menu_task", .stack_size = 1024, .icon = &A_Plugins_14},
+    {.app = app_loader, .name = "app_loader", .stack_size = 1024, .icon = &A_Plugins_14},
 #endif
 #endif
 
 
 #ifdef SRV_SD_FILESYSTEM
 #ifdef SRV_SD_FILESYSTEM
-    {.app = sd_filesystem, .name = "sd_filesystem", .stack_size = 4096, .icon = A_Plugins_14},
+    {.app = sd_filesystem, .name = "sd_filesystem", .stack_size = 4096, .icon = &A_Plugins_14},
 #endif
 #endif
 
 
 #ifdef SRV_INTERNAL_STORAGE
 #ifdef SRV_INTERNAL_STORAGE
     {.app = internal_storage_task,
     {.app = internal_storage_task,
      .name = "internal_storage",
      .name = "internal_storage",
      .stack_size = 2048,
      .stack_size = 2048,
-     .icon = A_Plugins_14},
+     .icon = &A_Plugins_14},
 #endif
 #endif
 
 
 #ifdef SRV_DOLPHIN
 #ifdef SRV_DOLPHIN
-    {.app = dolphin_task, .name = "dolphin_task", .stack_size = 1024, .icon = A_Plugins_14},
+    {.app = dolphin_task, .name = "dolphin_task", .stack_size = 1024, .icon = &A_Plugins_14},
 #endif
 #endif
 
 
 #ifdef SRV_POWER
 #ifdef SRV_POWER
-    {.app = power_task, .name = "power_task", .stack_size = 1024, .icon = A_Plugins_14},
+    {.app = power_task, .name = "power_task", .stack_size = 1024, .icon = &A_Plugins_14},
 #endif
 #endif
 
 
 #ifdef SRV_BT
 #ifdef SRV_BT
-    {.app = bt_task, .name = "bt_task", .stack_size = 1024, .icon = A_Plugins_14},
+    {.app = bt_task, .name = "bt_task", .stack_size = 1024, .icon = &A_Plugins_14},
 #endif
 #endif
 
 
 #ifdef SRV_LF_RFID
 #ifdef SRV_LF_RFID
     // TODO: fix stack size when sd api will be in separate thread
     // TODO: fix stack size when sd api will be in separate thread
-    {.app = lfrfid_app, .name = "125 kHz RFID", .stack_size = 4096, .icon = A_Plugins_14},
+    {.app = lfrfid_app, .name = "125 kHz RFID", .stack_size = 4096, .icon = &A_Plugins_14},
 #endif
 #endif
 
 
 #ifdef SRV_IRDA
 #ifdef SRV_IRDA
-    {.app = irda, .name = "irda", .stack_size = 1024 * 3, .icon = A_Plugins_14},
+    {.app = irda, .name = "irda", .stack_size = 1024 * 3, .icon = &A_Plugins_14},
 #endif
 #endif
 
 
 #ifdef SRV_EXAMPLE_QRCODE
 #ifdef SRV_EXAMPLE_QRCODE
-    {.app = u8g2_qrcode, .name = "u8g2_qrcode", .stack_size = 1024, .icon = A_Plugins_14},
+    {.app = u8g2_qrcode, .name = "u8g2_qrcode", .stack_size = 1024, .icon = &A_Plugins_14},
 #endif
 #endif
 
 
 #ifdef SRV_EXAMPLE_DISPLAY
 #ifdef SRV_EXAMPLE_DISPLAY
-    {.app = u8g2_example, .name = "u8g2_example", .stack_size = 1024, .icon = A_Plugins_14},
+    {.app = u8g2_example, .name = "u8g2_example", .stack_size = 1024, .icon = &A_Plugins_14},
 #endif
 #endif
 
 
 #ifdef SRV_SPEAKER_DEMO
 #ifdef SRV_SPEAKER_DEMO
     {.app = coreglitch_demo_0,
     {.app = coreglitch_demo_0,
      .name = "coreglitch_demo_0",
      .name = "coreglitch_demo_0",
      .stack_size = 1024,
      .stack_size = 1024,
-     .icon = A_Plugins_14},
+     .icon = &A_Plugins_14},
 #endif
 #endif
 
 
 #ifdef SRV_SD_TEST
 #ifdef SRV_SD_TEST
-    {.app = sd_card_test, .name = "sd_card_test", .stack_size = 4096, .icon = A_Plugins_14},
+    {.app = sd_card_test, .name = "sd_card_test", .stack_size = 4096, .icon = &A_Plugins_14},
 #endif
 #endif
 
 
 #ifdef SRV_MUSIC_PLAYER
 #ifdef SRV_MUSIC_PLAYER
-    {.app = music_player, .name = "music player", .stack_size = 1024, .icon = A_Plugins_14},
+    {.app = music_player, .name = "music player", .stack_size = 1024, .icon = &A_Plugins_14},
 #endif
 #endif
 
 
 #ifdef SRV_IBUTTON
 #ifdef SRV_IBUTTON
-    {.app = app_ibutton, .name = "ibutton", .stack_size = 4096, .icon = A_Plugins_14},
+    {.app = app_ibutton, .name = "ibutton", .stack_size = 4096, .icon = &A_Plugins_14},
 #endif
 #endif
 
 
 #ifdef SRV_GPIO_DEMO
 #ifdef SRV_GPIO_DEMO
-    {.app = app_gpio_test, .name = "gpio test", .stack_size = 1024, .icon = A_Plugins_14},
+    {.app = app_gpio_test, .name = "gpio test", .stack_size = 1024, .icon = &A_Plugins_14},
 #endif
 #endif
 
 
 #ifdef SRV_SDNFC
 #ifdef SRV_SDNFC
-    {.app = sdnfc, .name = "sdnfc", .stack_size = 1024, .icon = A_Plugins_14},
+    {.app = sdnfc, .name = "sdnfc", .stack_size = 1024, .icon = &A_Plugins_14},
 #endif
 #endif
 
 
 #ifdef SRV_GUI_TEST
 #ifdef SRV_GUI_TEST
-    {.app = gui_test, .name = "gui_test", .stack_size = 1024, .icon = A_Plugins_14},
+    {.app = gui_test, .name = "gui_test", .stack_size = 1024, .icon = &A_Plugins_14},
 #endif
 #endif
 
 
 #ifdef SRV_KEYPAD_TEST
 #ifdef SRV_KEYPAD_TEST
-    {.app = keypad_test, .name = "keypad_test", .icon = A_Plugins_14},
+    {.app = keypad_test, .name = "keypad_test", .icon = &A_Plugins_14},
 #endif
 #endif
 
 
 #ifdef SRV_ACCESSOR
 #ifdef SRV_ACCESSOR
-    {.app = app_accessor, .name = "accessor", .stack_size = 4096, .icon = A_Plugins_14},
+    {.app = app_accessor, .name = "accessor", .stack_size = 4096, .icon = &A_Plugins_14},
 #endif
 #endif
 
 
 #ifdef SRV_NOTIFICATION
 #ifdef SRV_NOTIFICATION
-    {.app = notification_app, .name = "notification", .stack_size = 1024, .icon = A_Plugins_14},
+    {.app = notification_app, .name = "notification", .stack_size = 1024, .icon = &A_Plugins_14},
 #endif
 #endif
 
 
 };
 };
@@ -169,33 +172,33 @@ const size_t FLIPPER_SERVICES_COUNT = sizeof(FLIPPER_SERVICES) / sizeof(FlipperA
 const FlipperApplication FLIPPER_APPS[] = {
 const FlipperApplication FLIPPER_APPS[] = {
 
 
 #ifdef APP_IBUTTON
 #ifdef APP_IBUTTON
-    {.app = app_ibutton, .name = "iButton", .stack_size = 4096, .icon = A_iButton_14},
+    {.app = app_ibutton, .name = "iButton", .stack_size = 4096, .icon = &A_iButton_14},
 #endif
 #endif
 
 
 #ifdef APP_NFC
 #ifdef APP_NFC
-    {.app = nfc_task, .name = "NFC", .stack_size = 4096, .icon = A_NFC_14},
+    {.app = nfc_task, .name = "NFC", .stack_size = 4096, .icon = &A_NFC_14},
 #endif
 #endif
 
 
 #ifdef APP_SUBGHZ
 #ifdef APP_SUBGHZ
     // TODO: decrease stack after SD API refactoring
     // TODO: decrease stack after SD API refactoring
-    {.app = subghz_app, .name = "Sub-1 GHz", .stack_size = 4096, .icon = A_Sub1ghz_14},
+    {.app = subghz_app, .name = "Sub-1 GHz", .stack_size = 4096, .icon = &A_Sub1ghz_14},
 #endif
 #endif
 
 
 #ifdef APP_LF_RFID
 #ifdef APP_LF_RFID
     // TODO: fix stack size when sd api will be in separate thread
     // TODO: fix stack size when sd api will be in separate thread
-    {.app = lfrfid_app, .name = "125 kHz RFID", .stack_size = 4096, .icon = A_125khz_14},
+    {.app = lfrfid_app, .name = "125 kHz RFID", .stack_size = 4096, .icon = &A_125khz_14},
 #endif
 #endif
 
 
 #ifdef APP_IRDA
 #ifdef APP_IRDA
-    {.app = irda, .name = "Infrared", .stack_size = 1024 * 3, .icon = A_Infrared_14},
+    {.app = irda, .name = "Infrared", .stack_size = 1024 * 3, .icon = &A_Infrared_14},
 #endif
 #endif
 
 
 #ifdef APP_GPIO_DEMO
 #ifdef APP_GPIO_DEMO
-    {.app = app_gpio_test, .name = "GPIO", .stack_size = 1024, .icon = A_GPIO_14},
+    {.app = app_gpio_test, .name = "GPIO", .stack_size = 1024, .icon = &A_GPIO_14},
 #endif
 #endif
 
 
 #ifdef APP_ARCHIVE
 #ifdef APP_ARCHIVE
-    {.app = app_archive, .name = "Archive", .stack_size = 4096, .icon = A_FileManager_14},
+    {.app = app_archive, .name = "Archive", .stack_size = 4096, .icon = &A_FileManager_14},
 #endif
 #endif
 
 
 };
 };
@@ -229,14 +232,14 @@ const size_t FLIPPER_ON_SYSTEM_START_COUNT =
 const FlipperApplication FLIPPER_PLUGINS[] = {
 const FlipperApplication FLIPPER_PLUGINS[] = {
 
 
 #ifdef APP_MUSIC_PLAYER
 #ifdef APP_MUSIC_PLAYER
-    {.app = music_player, .name = "music player", .stack_size = 1024, .icon = A_Plugins_14},
+    {.app = music_player, .name = "music player", .stack_size = 1024, .icon = &A_Plugins_14},
 #endif
 #endif
 
 
 #ifdef APP_SPEAKER_DEMO
 #ifdef APP_SPEAKER_DEMO
     {.app = coreglitch_demo_0,
     {.app = coreglitch_demo_0,
      .name = "coreglitch_demo_0",
      .name = "coreglitch_demo_0",
      .stack_size = 1024,
      .stack_size = 1024,
-     .icon = A_Plugins_14},
+     .icon = &A_Plugins_14},
 #endif
 #endif
 
 
 };
 };
@@ -246,58 +249,61 @@ const size_t FLIPPER_PLUGINS_COUNT = sizeof(FLIPPER_PLUGINS) / sizeof(FlipperApp
 // Plugin menu
 // Plugin menu
 const FlipperApplication FLIPPER_DEBUG_APPS[] = {
 const FlipperApplication FLIPPER_DEBUG_APPS[] = {
 #ifdef APP_EXAMPLE_BLINK
 #ifdef APP_EXAMPLE_BLINK
-    {.app = application_blink, .name = "blink", .stack_size = 1024, .icon = A_Plugins_14},
+    {.app = application_blink, .name = "blink", .stack_size = 1024, .icon = &A_Plugins_14},
 #endif
 #endif
 
 
 #ifdef APP_EXAMPLE_INPUT_DUMP
 #ifdef APP_EXAMPLE_INPUT_DUMP
-    {.app = application_input_dump, .name = "input dump", .stack_size = 1024, .icon = A_Plugins_14},
+    {.app = application_input_dump,
+     .name = "input dump",
+     .stack_size = 1024,
+     .icon = &A_Plugins_14},
 #endif
 #endif
 
 
 #ifdef APP_SD_TEST
 #ifdef APP_SD_TEST
-    {.app = sd_card_test, .name = "sd_card_test", .stack_size = 4096, .icon = A_Plugins_14},
+    {.app = sd_card_test, .name = "sd_card_test", .stack_size = 4096, .icon = &A_Plugins_14},
 #endif
 #endif
 
 
 #ifdef APP_VIBRO_DEMO
 #ifdef APP_VIBRO_DEMO
-    {.app = application_vibro, .name = "vibro", .stack_size = 1024, .icon = A_Plugins_14},
+    {.app = application_vibro, .name = "vibro", .stack_size = 1024, .icon = &A_Plugins_14},
 #endif
 #endif
 
 
 #ifdef APP_SDNFC
 #ifdef APP_SDNFC
-    {.app = sdnfc, .name = "sdnfc", .stack_size = 1024, .icon = A_Plugins_14},
+    {.app = sdnfc, .name = "sdnfc", .stack_size = 1024, .icon = &A_Plugins_14},
 #endif
 #endif
 
 
 #ifdef APP_GUI_TEST
 #ifdef APP_GUI_TEST
-    {.app = gui_test, .name = "gui_test", .stack_size = 1024, .icon = A_Plugins_14},
+    {.app = gui_test, .name = "gui_test", .stack_size = 1024, .icon = &A_Plugins_14},
 #endif
 #endif
 
 
 #ifdef APP_KEYPAD_TEST
 #ifdef APP_KEYPAD_TEST
-    {.app = keypad_test, .name = "keypad_test", .icon = A_Plugins_14},
+    {.app = keypad_test, .name = "keypad_test", .icon = &A_Plugins_14},
 #endif
 #endif
 
 
 #ifdef APP_ACCESSOR
 #ifdef APP_ACCESSOR
-    {.app = app_accessor, .name = "accessor", .stack_size = 4096, .icon = A_Plugins_14},
+    {.app = app_accessor, .name = "accessor", .stack_size = 4096, .icon = &A_Plugins_14},
 #endif
 #endif
 
 
 #ifdef APP_UNIT_TESTS
 #ifdef APP_UNIT_TESTS
-    {.app = flipper_test_app, .name = "Unit Tests", .stack_size = 1024, .icon = A_Plugins_14},
+    {.app = flipper_test_app, .name = "Unit Tests", .stack_size = 1024, .icon = &A_Plugins_14},
 #endif
 #endif
 
 
 #ifdef APP_IRDA_MONITOR
 #ifdef APP_IRDA_MONITOR
-    {.app = irda_monitor_app, .name = "Irda Monitor", .stack_size = 1024, .icon = A_Plugins_14},
+    {.app = irda_monitor_app, .name = "Irda Monitor", .stack_size = 1024, .icon = &A_Plugins_14},
 #endif
 #endif
 
 
 #ifdef APP_VERTICAL_SCREEN
 #ifdef APP_VERTICAL_SCREEN
     {.app = application_vertical_screen,
     {.app = application_vertical_screen,
      .name = "Vertical Screen",
      .name = "Vertical Screen",
      .stack_size = 1024,
      .stack_size = 1024,
-     .icon = A_Plugins_14},
+     .icon = &A_Plugins_14},
 #endif
 #endif
 
 
 #ifdef APP_SCENED
 #ifdef APP_SCENED
-    {.app = scened_app, .name = "Templated Scene", .stack_size = 1024, .icon = A_Plugins_14},
+    {.app = scened_app, .name = "Templated Scene", .stack_size = 1024, .icon = &A_Plugins_14},
 #endif
 #endif
 
 
 #ifdef APP_LF_RFID
 #ifdef APP_LF_RFID
-    {.app = lfrfid_debug_app, .name = "LF-RFID Debug", .stack_size = 1024, .icon = A_125khz_14},
+    {.app = lfrfid_debug_app, .name = "LF-RFID Debug", .stack_size = 1024, .icon = &A_125khz_14},
 #endif
 #endif
 };
 };
 
 
@@ -305,16 +311,16 @@ const size_t FLIPPER_DEBUG_APPS_COUNT = sizeof(FLIPPER_DEBUG_APPS) / sizeof(Flip
 
 
 #ifdef APP_ARCHIVE
 #ifdef APP_ARCHIVE
 const FlipperApplication FLIPPER_ARCHIVE =
 const FlipperApplication FLIPPER_ARCHIVE =
-    {.app = app_archive, .name = "Archive", .stack_size = 4096, .icon = A_FileManager_14};
+    {.app = app_archive, .name = "Archive", .stack_size = 4096, .icon = &A_FileManager_14};
 #endif
 #endif
 
 
 #ifdef SRV_DOLPHIN
 #ifdef SRV_DOLPHIN
 const FlipperApplication FLIPPER_SCENE =
 const FlipperApplication FLIPPER_SCENE =
-    {.app = scene_app, .name = "Scenes", .stack_size = 1024, .icon = A_Games_14};
+    {.app = scene_app, .name = "Scenes", .stack_size = 1024, .icon = &A_Games_14};
 
 
 const FlipperApplication FLIPPER_SCENE_APPS[] = {
 const FlipperApplication FLIPPER_SCENE_APPS[] = {
-    {.app = passport, .name = "Passport", .stack_size = 1024, .icon = A_Games_14},
-    {.app = music_player, .name = "Music player", .stack_size = 1024, .icon = A_Plugins_14},
+    {.app = passport, .name = "Passport", .stack_size = 1024, .icon = &A_Games_14},
+    {.app = music_player, .name = "Music player", .stack_size = 1024, .icon = &A_Plugins_14},
 };
 };
 
 
 const size_t FLIPPER_SCENE_APPS_COUNT = sizeof(FLIPPER_SCENE_APPS) / sizeof(FlipperApplication);
 const size_t FLIPPER_SCENE_APPS_COUNT = sizeof(FLIPPER_SCENE_APPS) / sizeof(FlipperApplication);
@@ -327,7 +333,7 @@ const FlipperApplication FLIPPER_SETTINGS_APPS[] = {
     {.app = notification_app_settings,
     {.app = notification_app_settings,
      .name = "Notification",
      .name = "Notification",
      .stack_size = 1024,
      .stack_size = 1024,
-     .icon = A_Plugins_14},
+     .icon = &A_Plugins_14},
 #endif
 #endif
 };
 };
 
 

+ 1 - 1
applications/applications.h

@@ -7,7 +7,7 @@ typedef struct {
     const FuriThreadCallback app;
     const FuriThreadCallback app;
     const char* name;
     const char* name;
     const size_t stack_size;
     const size_t stack_size;
-    const IconName icon;
+    const Icon* icon;
 } FlipperApplication;
 } FlipperApplication;
 
 
 typedef void (*FlipperOnStartHook)(void);
 typedef void (*FlipperOnStartHook)(void);

+ 13 - 13
applications/archive/archive_views.c

@@ -9,14 +9,14 @@ static const char* ArchiveTabNames[] = {
     [ArchiveTabIrda] = "Infrared",
     [ArchiveTabIrda] = "Infrared",
     [ArchiveTabBrowser] = "Browser"};
     [ArchiveTabBrowser] = "Browser"};
 
 
-static const IconName ArchiveItemIcons[] = {
-    [ArchiveFileTypeIButton] = I_ibutt_10px,
-    [ArchiveFileTypeNFC] = I_Nfc_10px,
-    [ArchiveFileTypeSubOne] = I_sub1_10px,
-    [ArchiveFileTypeLFRFID] = I_125_10px,
-    [ArchiveFileTypeIrda] = I_ir_10px,
-    [ArchiveFileTypeFolder] = I_dir_10px,
-    [ArchiveFileTypeUnknown] = I_unknown_10px,
+static const Icon* ArchiveItemIcons[] = {
+    [ArchiveFileTypeIButton] = &I_ibutt_10px,
+    [ArchiveFileTypeNFC] = &I_Nfc_10px,
+    [ArchiveFileTypeSubOne] = &I_sub1_10px,
+    [ArchiveFileTypeLFRFID] = &I_125_10px,
+    [ArchiveFileTypeIrda] = &I_ir_10px,
+    [ArchiveFileTypeFolder] = &I_dir_10px,
+    [ArchiveFileTypeUnknown] = &I_unknown_10px,
 };
 };
 
 
 static void render_item_menu(Canvas* canvas, ArchiveViewModel* model) {
 static void render_item_menu(Canvas* canvas, ArchiveViewModel* model) {
@@ -47,7 +47,7 @@ static void render_item_menu(Canvas* canvas, ArchiveViewModel* model) {
         string_clear(menu[i]);
         string_clear(menu[i]);
     }
     }
 
 
-    canvas_draw_icon_name(canvas, 74, 20 + model->menu_idx * 11, I_ButtonRight_4x7);
+    canvas_draw_icon(canvas, 74, 20 + model->menu_idx * 11, &I_ButtonRight_4x7);
 }
 }
 
 
 void archive_trim_file_ext(char* name) {
 void archive_trim_file_ext(char* name) {
@@ -105,7 +105,7 @@ static void draw_list(Canvas* canvas, ArchiveViewModel* model) {
             canvas_set_color(canvas, ColorBlack);
             canvas_set_color(canvas, ColorBlack);
         }
         }
 
 
-        canvas_draw_icon_name(canvas, 2, 16 + i * FRAME_HEIGHT, ArchiveItemIcons[file->type]);
+        canvas_draw_icon(canvas, 2, 16 + i * FRAME_HEIGHT, ArchiveItemIcons[file->type]);
         canvas_draw_str(canvas, 15, 24 + i * FRAME_HEIGHT, string_get_cstr(str_buff));
         canvas_draw_str(canvas, 15, 24 + i * FRAME_HEIGHT, string_get_cstr(str_buff));
         string_clean(str_buff);
         string_clean(str_buff);
     }
     }
@@ -126,7 +126,7 @@ static void archive_render_status_bar(Canvas* canvas, ArchiveViewModel* model) {
 
 
     const char* tab_name = ArchiveTabNames[model->tab_idx];
     const char* tab_name = ArchiveTabNames[model->tab_idx];
 
 
-    canvas_draw_icon_name(canvas, 0, 0, I_Background_128x11);
+    canvas_draw_icon(canvas, 0, 0, &I_Background_128x11);
 
 
     canvas_set_color(canvas, ColorWhite);
     canvas_set_color(canvas, ColorWhite);
     canvas_draw_box(canvas, 0, 0, 50, 13);
     canvas_draw_box(canvas, 0, 0, 50, 13);
@@ -143,10 +143,10 @@ static void archive_render_status_bar(Canvas* canvas, ArchiveViewModel* model) {
     canvas_draw_line(canvas, 108, 12, 126, 12);
     canvas_draw_line(canvas, 108, 12, 126, 12);
 
 
     if(model->tab_idx > 0) {
     if(model->tab_idx > 0) {
-        canvas_draw_icon_name(canvas, 112, 2, I_ButtonLeft_4x7);
+        canvas_draw_icon(canvas, 112, 2, &I_ButtonLeft_4x7);
     }
     }
     if(model->tab_idx < SIZEOF_ARRAY(ArchiveTabNames) - 1) {
     if(model->tab_idx < SIZEOF_ARRAY(ArchiveTabNames) - 1) {
-        canvas_draw_icon_name(canvas, 120, 2, I_ButtonRight_4x7);
+        canvas_draw_icon(canvas, 120, 2, &I_ButtonRight_4x7);
     }
     }
 
 
     canvas_set_color(canvas, ColorWhite);
     canvas_set_color(canvas, ColorWhite);

+ 2 - 2
applications/bt/bt.c

@@ -45,7 +45,7 @@ Bt* bt_alloc() {
     view_port_enabled_set(bt->statusbar_view_port, false);
     view_port_enabled_set(bt->statusbar_view_port, false);
     gui_add_view_port(bt->gui, bt->statusbar_view_port, GuiLayerStatusBarLeft);
     gui_add_view_port(bt->gui, bt->statusbar_view_port, GuiLayerStatusBarLeft);
 
 
-    bt->menu_icon = assets_icons_get(A_Bluetooth_14);
+    bt->menu_icon = icon_animation_alloc(&A_Bluetooth_14);
     bt->menu_item = menu_item_alloc_menu("Bluetooth", bt->menu_icon);
     bt->menu_item = menu_item_alloc_menu("Bluetooth", bt->menu_icon);
     menu_item_subitem_add(
     menu_item_subitem_add(
         bt->menu_item, menu_item_alloc_function("Carrier test", NULL, bt_menu_test_carrier, bt));
         bt->menu_item, menu_item_alloc_function("Carrier test", NULL, bt_menu_test_carrier, bt));
@@ -104,7 +104,7 @@ Bt* bt_alloc() {
 }
 }
 
 
 void bt_draw_statusbar_callback(Canvas* canvas, void* context) {
 void bt_draw_statusbar_callback(Canvas* canvas, void* context) {
-    canvas_draw_icon_name(canvas, 0, 0, I_Bluetooth_5x8);
+    canvas_draw_icon(canvas, 0, 0, &I_Bluetooth_5x8);
 }
 }
 
 
 void bt_menu_test_carrier(void* context) {
 void bt_menu_test_carrier(void* context) {

+ 1 - 1
applications/bt/bt_i.h

@@ -27,7 +27,7 @@ struct Bt {
     // Status bar
     // Status bar
     ViewPort* statusbar_view_port;
     ViewPort* statusbar_view_port;
     // Menu
     // Menu
-    Icon* menu_icon;
+    IconAnimation* menu_icon;
     MenuItem* menu_item;
     MenuItem* menu_item;
     View* view_test_carrier;
     View* view_test_carrier;
     View* view_test_packet_tx;
     View* view_test_packet_tx;

+ 18 - 13
applications/dolphin/dolphin.c

@@ -2,6 +2,8 @@
 #include <stdlib.h>
 #include <stdlib.h>
 #include "applications.h"
 #include "applications.h"
 
 
+const Icon* idle_scenes[] = {&A_Wink_128x64, &A_WatchingTV_128x64};
+
 static void dolphin_switch_to_app(Dolphin* dolphin, const FlipperApplication* flipper_app) {
 static void dolphin_switch_to_app(Dolphin* dolphin, const FlipperApplication* flipper_app) {
     furi_assert(dolphin);
     furi_assert(dolphin);
     furi_assert(flipper_app);
     furi_assert(flipper_app);
@@ -15,11 +17,12 @@ static void dolphin_switch_to_app(Dolphin* dolphin, const FlipperApplication* fl
 }
 }
 
 
 // temporary main screen animation managment
 // temporary main screen animation managment
-void dolphin_scene_handler_set_scene(Dolphin* dolphin, IconName icon) {
+void dolphin_scene_handler_set_scene(Dolphin* dolphin, const Icon* icon_data) {
     with_view_model(
     with_view_model(
         dolphin->idle_view_main, (DolphinViewMainModel * model) {
         dolphin->idle_view_main, (DolphinViewMainModel * model) {
-            model->animation = assets_icons_get(icon);
-            icon_start_animation(model->animation);
+            if(model->animation) icon_animation_free(model->animation);
+            model->animation = icon_animation_alloc(icon_data);
+            icon_animation_start(model->animation);
             return true;
             return true;
         });
         });
 }
 }
@@ -27,10 +30,11 @@ void dolphin_scene_handler_set_scene(Dolphin* dolphin, IconName icon) {
 void dolphin_scene_handler_switch_scene(Dolphin* dolphin) {
 void dolphin_scene_handler_switch_scene(Dolphin* dolphin) {
     with_view_model(
     with_view_model(
         dolphin->idle_view_main, (DolphinViewMainModel * model) {
         dolphin->idle_view_main, (DolphinViewMainModel * model) {
-            if(icon_is_last_frame(model->animation)) {
-                model->animation = assets_icons_get(idle_scenes[model->scene_num]);
-                icon_start_animation(model->animation);
-                model->scene_num = random() % sizeof(idle_scenes);
+            if(icon_animation_is_last_frame(model->animation)) {
+                if(model->animation) icon_animation_free(model->animation);
+                model->animation = icon_animation_alloc(idle_scenes[model->scene_num]);
+                icon_animation_start(model->animation);
+                model->scene_num = random() % COUNT_OF(idle_scenes);
             }
             }
             return true;
             return true;
         });
         });
@@ -183,7 +187,7 @@ static void lock_menu_callback(void* context, uint8_t index) {
 static void lock_icon_callback(Canvas* canvas, void* context) {
 static void lock_icon_callback(Canvas* canvas, void* context) {
     furi_assert(context);
     furi_assert(context);
     Dolphin* dolphin = context;
     Dolphin* dolphin = context;
-    canvas_draw_icon(canvas, 0, 0, dolphin->lock_icon);
+    canvas_draw_icon_animation(canvas, 0, 0, dolphin->lock_icon);
 }
 }
 
 
 bool dolphin_view_lockmenu_input(InputEvent* event, void* context) {
 bool dolphin_view_lockmenu_input(InputEvent* event, void* context) {
@@ -206,7 +210,8 @@ bool dolphin_view_lockmenu_input(InputEvent* event, void* context) {
         view_dispatcher_switch_to_view(dolphin->idle_view_dispatcher, DolphinViewIdleMain);
         view_dispatcher_switch_to_view(dolphin->idle_view_dispatcher, DolphinViewIdleMain);
 
 
         if(random() % 100 > 50)
         if(random() % 100 > 50)
-            dolphin_scene_handler_set_scene(dolphin, idle_scenes[random() % sizeof(idle_scenes)]);
+            dolphin_scene_handler_set_scene(
+                dolphin, idle_scenes[random() % COUNT_OF(idle_scenes)]);
     }
     }
 
 
     view_commit_model(dolphin->view_lockmenu, true);
     view_commit_model(dolphin->view_lockmenu, true);
@@ -331,14 +336,14 @@ Dolphin* dolphin_alloc() {
         dolphin->idle_view_dispatcher, DolphinViewHwMismatch, dolphin->view_hw_mismatch);
         dolphin->idle_view_dispatcher, DolphinViewHwMismatch, dolphin->view_hw_mismatch);
 
 
     // Lock icon
     // Lock icon
-    dolphin->lock_icon = assets_icons_get(I_Lock_8x8);
+    dolphin->lock_icon = icon_animation_alloc(&I_Lock_8x8);
     dolphin->lock_viewport = view_port_alloc();
     dolphin->lock_viewport = view_port_alloc();
-    view_port_set_width(dolphin->lock_viewport, icon_get_width(dolphin->lock_icon));
+    view_port_set_width(dolphin->lock_viewport, icon_animation_get_width(dolphin->lock_icon));
     view_port_draw_callback_set(dolphin->lock_viewport, lock_icon_callback, dolphin);
     view_port_draw_callback_set(dolphin->lock_viewport, lock_icon_callback, dolphin);
     view_port_enabled_set(dolphin->lock_viewport, false);
     view_port_enabled_set(dolphin->lock_viewport, false);
 
 
     // Main screen animation
     // Main screen animation
-    dolphin_scene_handler_set_scene(dolphin, idle_scenes[random() % sizeof(idle_scenes)]);
+    dolphin_scene_handler_set_scene(dolphin, idle_scenes[random() % COUNT_OF(idle_scenes)]);
 
 
     view_dispatcher_attach_to_gui(
     view_dispatcher_attach_to_gui(
         dolphin->idle_view_dispatcher, dolphin->gui, ViewDispatcherTypeWindow);
         dolphin->idle_view_dispatcher, dolphin->gui, ViewDispatcherTypeWindow);
@@ -352,7 +357,7 @@ void dolphin_free(Dolphin* dolphin) {
 
 
     gui_remove_view_port(dolphin->gui, dolphin->lock_viewport);
     gui_remove_view_port(dolphin->gui, dolphin->lock_viewport);
     view_port_free(dolphin->lock_viewport);
     view_port_free(dolphin->lock_viewport);
-    icon_free(dolphin->lock_icon);
+    icon_animation_free(dolphin->lock_icon);
 
 
     osTimerDelete(dolphin->timeout_timer);
     osTimerDelete(dolphin->timeout_timer);
 
 

+ 1 - 4
applications/dolphin/dolphin_i.h

@@ -51,7 +51,7 @@ struct Dolphin {
     View* view_hw_mismatch;
     View* view_hw_mismatch;
     View* view_lockmenu;
     View* view_lockmenu;
     ViewPort* lock_viewport;
     ViewPort* lock_viewport;
-    Icon* lock_icon;
+    IconAnimation* lock_icon;
 
 
     bool locked;
     bool locked;
     uint8_t lock_count;
     uint8_t lock_count;
@@ -59,9 +59,6 @@ struct Dolphin {
     osTimerId_t timeout_timer;
     osTimerId_t timeout_timer;
 };
 };
 
 
-// Temporary
-const IconName idle_scenes[] = {A_Wink_128x64, A_WatchingTV_128x64};
-
 Dolphin* dolphin_alloc();
 Dolphin* dolphin_alloc();
 
 
 void dolphin_free(Dolphin* dolphin);
 void dolphin_free(Dolphin* dolphin);

+ 13 - 13
applications/dolphin/dolphin_views.c

@@ -17,19 +17,19 @@ void dolphin_view_first_start_draw(Canvas* canvas, void* model) {
     uint8_t height = canvas_height(canvas);
     uint8_t height = canvas_height(canvas);
     const char* my_name = api_hal_version_get_name_ptr();
     const char* my_name = api_hal_version_get_name_ptr();
     if(m->page == 0) {
     if(m->page == 0) {
-        canvas_draw_icon_name(canvas, 0, height - 48, I_DolphinFirstStart0_70x53);
+        canvas_draw_icon(canvas, 0, height - 48, &I_DolphinFirstStart0_70x53);
         elements_multiline_text_framed(canvas, 75, 20, "Hey m8,\npress > to\ncontinue");
         elements_multiline_text_framed(canvas, 75, 20, "Hey m8,\npress > to\ncontinue");
     } else if(m->page == 1) {
     } else if(m->page == 1) {
-        canvas_draw_icon_name(canvas, 0, height - 48, I_DolphinFirstStart1_59x53);
+        canvas_draw_icon(canvas, 0, height - 48, &I_DolphinFirstStart1_59x53);
         elements_multiline_text_framed(canvas, 64, 20, "First Of All,\n...      >");
         elements_multiline_text_framed(canvas, 64, 20, "First Of All,\n...      >");
     } else if(m->page == 2) {
     } else if(m->page == 2) {
-        canvas_draw_icon_name(canvas, 0, height - 48, I_DolphinFirstStart2_59x51);
+        canvas_draw_icon(canvas, 0, height - 48, &I_DolphinFirstStart2_59x51);
         elements_multiline_text_framed(canvas, 64, 20, "Thank you\nfor your\nsupport! >");
         elements_multiline_text_framed(canvas, 64, 20, "Thank you\nfor your\nsupport! >");
     } else if(m->page == 3) {
     } else if(m->page == 3) {
-        canvas_draw_icon_name(canvas, width - 57, height - 48, I_DolphinFirstStart3_57x48);
+        canvas_draw_icon(canvas, width - 57, height - 48, &I_DolphinFirstStart3_57x48);
         elements_multiline_text_framed(canvas, 0, 20, "Kickstarter\ncampaign\nwas INSANE! >");
         elements_multiline_text_framed(canvas, 0, 20, "Kickstarter\ncampaign\nwas INSANE! >");
     } else if(m->page == 4) {
     } else if(m->page == 4) {
-        canvas_draw_icon_name(canvas, width - 67, height - 50, I_DolphinFirstStart4_67x53);
+        canvas_draw_icon(canvas, width - 67, height - 50, &I_DolphinFirstStart4_67x53);
         elements_multiline_text_framed(canvas, 0, 17, "Now\nallow me\nto introduce\nmyself >");
         elements_multiline_text_framed(canvas, 0, 17, "Now\nallow me\nto introduce\nmyself >");
     } else if(m->page == 5) {
     } else if(m->page == 5) {
         char buf[64];
         char buf[64];
@@ -40,18 +40,18 @@ void dolphin_view_first_start_draw(Canvas* canvas, void* model) {
             "I am",
             "I am",
             my_name ? my_name : "Unknown",
             my_name ? my_name : "Unknown",
             ",\ncyberdolphin\nliving in your\npocket >");
             ",\ncyberdolphin\nliving in your\npocket >");
-        canvas_draw_icon_name(canvas, 0, height - 48, I_DolphinFirstStart5_45x53);
+        canvas_draw_icon(canvas, 0, height - 48, &I_DolphinFirstStart5_45x53);
         elements_multiline_text_framed(canvas, 60, 17, buf);
         elements_multiline_text_framed(canvas, 60, 17, buf);
     } else if(m->page == 6) {
     } else if(m->page == 6) {
-        canvas_draw_icon_name(canvas, 0, height - 48, I_DolphinFirstStart6_58x54);
+        canvas_draw_icon(canvas, 0, height - 48, &I_DolphinFirstStart6_58x54);
         elements_multiline_text_framed(
         elements_multiline_text_framed(
             canvas, 63, 17, "I can grow\nsmart'n'cool\nif you use me\noften >");
             canvas, 63, 17, "I can grow\nsmart'n'cool\nif you use me\noften >");
     } else if(m->page == 7) {
     } else if(m->page == 7) {
-        canvas_draw_icon_name(canvas, width - 61, height - 48, I_DolphinFirstStart7_61x51);
+        canvas_draw_icon(canvas, width - 61, height - 48, &I_DolphinFirstStart7_61x51);
         elements_multiline_text_framed(
         elements_multiline_text_framed(
             canvas, 0, 17, "As long as\nyou read, write\nand emulate >");
             canvas, 0, 17, "As long as\nyou read, write\nand emulate >");
     } else if(m->page == 8) {
     } else if(m->page == 8) {
-        canvas_draw_icon_name(canvas, width - 56, height - 48, I_DolphinFirstStart8_56x51);
+        canvas_draw_icon(canvas, width - 56, height - 48, &I_DolphinFirstStart8_56x51);
         elements_multiline_text_framed(
         elements_multiline_text_framed(
             canvas, 0, 17, "You can check\nmy level and\nmood in the\nPassport menu");
             canvas, 0, 17, "You can check\nmy level and\nmood in the\nPassport menu");
     }
     }
@@ -61,13 +61,13 @@ void dolphin_view_idle_main_draw(Canvas* canvas, void* model) {
     canvas_clear(canvas);
     canvas_clear(canvas);
     DolphinViewMainModel* m = model;
     DolphinViewMainModel* m = model;
     if(m->animation) {
     if(m->animation) {
-        canvas_draw_icon(canvas, 0, -3, m->animation);
+        canvas_draw_icon_animation(canvas, 0, -3, m->animation);
     }
     }
 
 
     if(m->hint_timeout > 0) {
     if(m->hint_timeout > 0) {
         m->hint_timeout--;
         m->hint_timeout--;
         if(m->locked) {
         if(m->locked) {
-            canvas_draw_icon_name(canvas, 13, 5, I_LockPopup_100x49);
+            canvas_draw_icon(canvas, 13, 5, &I_LockPopup_100x49);
             elements_multiline_text(canvas, 65, 20, "To unlock\npress:");
             elements_multiline_text(canvas, 65, 20, "To unlock\npress:");
         } else {
         } else {
             canvas_set_font(canvas, FontPrimary);
             canvas_set_font(canvas, FontPrimary);
@@ -80,8 +80,8 @@ void dolphin_view_lockmenu_draw(Canvas* canvas, void* model) {
     DolphinViewLockMenuModel* m = model;
     DolphinViewLockMenuModel* m = model;
     canvas_clear(canvas);
     canvas_clear(canvas);
     canvas_set_color(canvas, ColorBlack);
     canvas_set_color(canvas, ColorBlack);
-    canvas_draw_icon_name(canvas, m->door_left_x, 0, I_DoorLeft_70x55);
-    canvas_draw_icon_name(canvas, m->door_right_x, 0, I_DoorRight_70x55);
+    canvas_draw_icon(canvas, m->door_left_x, 0, &I_DoorLeft_70x55);
+    canvas_draw_icon(canvas, m->door_right_x, 0, &I_DoorRight_70x55);
     canvas_set_font(canvas, FontSecondary);
     canvas_set_font(canvas, FontSecondary);
 
 
     if(m->locked) {
     if(m->locked) {

+ 1 - 1
applications/dolphin/dolphin_views.h

@@ -45,7 +45,7 @@ typedef struct {
 } DolphinViewLockMenuModel;
 } DolphinViewLockMenuModel;
 
 
 typedef struct {
 typedef struct {
-    Icon* animation;
+    IconAnimation* animation;
     uint8_t scene_num;
     uint8_t scene_num;
     uint8_t hint_timeout;
     uint8_t hint_timeout;
     bool locked;
     bool locked;

+ 16 - 16
applications/dolphin/passport/passport.c

@@ -23,19 +23,19 @@ typedef struct {
 // Moods, corresponding to butthurt level. (temp, unclear about max level)
 // Moods, corresponding to butthurt level. (temp, unclear about max level)
 static const char* mood_strings[MOODS_TOTAL] = {[0] = "Happy", [1] = "Ok", [2] = "Bad"};
 static const char* mood_strings[MOODS_TOTAL] = {[0] = "Happy", [1] = "Ok", [2] = "Bad"};
 
 
-static const IconName portrait_happy[BUTTHURT_MAX] = {
-    I_passport_happy1_43x45,
-    I_passport_happy2_43x45,
-    I_passport_happy3_43x45};
-static const IconName portrait_ok[BUTTHURT_MAX] = {
-    I_passport_okay1_43x45,
-    I_passport_okay2_43x45,
-    I_passport_okay3_43x45};
-static const IconName portrait_bad[BUTTHURT_MAX] = {
-    I_passport_bad1_43x45,
-    I_passport_bad2_43x45,
-    I_passport_bad3_43x45};
-static const IconName* portraits[MOODS_TOTAL] = {portrait_happy, portrait_ok, portrait_bad};
+static const Icon* portrait_happy[BUTTHURT_MAX] = {
+    &I_passport_happy1_43x45,
+    &I_passport_happy2_43x45,
+    &I_passport_happy3_43x45};
+static const Icon* portrait_ok[BUTTHURT_MAX] = {
+    &I_passport_okay1_43x45,
+    &I_passport_okay2_43x45,
+    &I_passport_okay3_43x45};
+static const Icon* portrait_bad[BUTTHURT_MAX] = {
+    &I_passport_bad1_43x45,
+    &I_passport_bad2_43x45,
+    &I_passport_bad3_43x45};
+static const Icon** portraits[MOODS_TOTAL] = {portrait_happy, portrait_ok, portrait_bad};
 
 
 static void input_callback(InputEvent* input_event, void* ctx) {
 static void input_callback(InputEvent* input_event, void* ctx) {
     osMessageQueueId_t event_queue = ctx;
     osMessageQueueId_t event_queue = ctx;
@@ -61,8 +61,8 @@ static void render_callback(Canvas* canvas, void* ctx) {
     canvas_clear(canvas);
     canvas_clear(canvas);
 
 
     // multipass
     // multipass
-    canvas_draw_icon_name(canvas, 0, 0, I_PassportLeft_6x47);
-    canvas_draw_icon_name(canvas, 0, 47, I_PassportBottom_128x17);
+    canvas_draw_icon(canvas, 0, 0, &I_PassportLeft_6x47);
+    canvas_draw_icon(canvas, 0, 47, &I_PassportBottom_128x17);
     canvas_draw_line(canvas, 6, 0, 125, 0);
     canvas_draw_line(canvas, 6, 0, 125, 0);
     canvas_draw_line(canvas, 127, 2, 127, 47);
     canvas_draw_line(canvas, 127, 2, 127, 47);
     canvas_draw_dot(canvas, 126, 1);
     canvas_draw_dot(canvas, 126, 1);
@@ -75,7 +75,7 @@ static void render_callback(Canvas* canvas, void* ctx) {
     canvas_draw_line(canvas, 53, 5, 55, 7);
     canvas_draw_line(canvas, 53, 5, 55, 7);
 
 
     // portrait
     // portrait
-    canvas_draw_icon_name(canvas, 10, 9, portraits[butthurt][portrait_level]);
+    canvas_draw_icon(canvas, 10, 9, portraits[butthurt][portrait_level]);
     canvas_draw_line(canvas, 59, 18, 124, 18);
     canvas_draw_line(canvas, 59, 18, 124, 18);
     canvas_draw_line(canvas, 59, 31, 124, 31);
     canvas_draw_line(canvas, 59, 31, 124, 31);
     canvas_draw_line(canvas, 59, 44, 124, 44);
     canvas_draw_line(canvas, 59, 44, 124, 44);

+ 8 - 8
applications/dolphin/scenes/assets/items.c

@@ -7,7 +7,7 @@ const Item TV = {
     .timeout = 10,
     .timeout = 10,
     .x = 160,
     .x = 160,
     .y = 34,
     .y = 34,
-    .icon = I_TV_20x24,
+    .icon = &I_TV_20x24,
     .action_name = "Use",
     .action_name = "Use",
     .draw = draw_tv,
     .draw = draw_tv,
     .callback = smash_tv};
     .callback = smash_tv};
@@ -17,7 +17,7 @@ const Item Painting = {
     .timeout = 20,
     .timeout = 20,
     .x = 160,
     .x = 160,
     .y = 10,
     .y = 10,
-    .icon = I_Home_painting_17x20,
+    .icon = &I_Home_painting_17x20,
     .action_name = "Inspect",
     .action_name = "Inspect",
     .draw = NULL,
     .draw = NULL,
     .callback = inspect_painting};
     .callback = inspect_painting};
@@ -27,7 +27,7 @@ const Item Sofa = {
     .timeout = 100,
     .timeout = 100,
     .x = 250,
     .x = 250,
     .y = 34,
     .y = 34,
-    .icon = I_Sofa_40x13,
+    .icon = &I_Sofa_40x13,
     .action_name = "Sit",
     .action_name = "Sit",
     .draw = NULL,
     .draw = NULL,
     .callback = sofa_sit};
     .callback = sofa_sit};
@@ -37,7 +37,7 @@ const Item PC = {
     .timeout = 100,
     .timeout = 100,
     .x = 400,
     .x = 400,
     .y = 10,
     .y = 10,
-    .icon = I_PC_22x29,
+    .icon = &I_PC_22x29,
     .action_name = "Use",
     .action_name = "Use",
     .draw = NULL,
     .draw = NULL,
     .callback = pc_callback};
     .callback = pc_callback};
@@ -111,8 +111,8 @@ void smash_tv(Canvas* canvas, void* state) {
     SceneState* s = state;
     SceneState* s = state;
     s->player_flipped = true;
     s->player_flipped = true;
     canvas_set_bitmap_mode(canvas, true);
     canvas_set_bitmap_mode(canvas, true);
-    canvas_draw_icon_name(
-        canvas, ((TV.x - 5) - s->player_global.x) * PARALLAX(TV.layer), TV.y - 2, I_FX_Bang_32x6);
+    canvas_draw_icon(
+        canvas, ((TV.x - 5) - s->player_global.x) * PARALLAX(TV.layer), TV.y - 2, &I_FX_Bang_32x6);
     canvas_set_bitmap_mode(canvas, false);
     canvas_set_bitmap_mode(canvas, false);
     if(s->action_timeout < TV.timeout - 2) {
     if(s->action_timeout < TV.timeout - 2) {
         elements_multiline_text_framed(canvas, 80, 24, "Bang!");
         elements_multiline_text_framed(canvas, 80, 24, "Bang!");
@@ -124,8 +124,8 @@ void sofa_sit(Canvas* canvas, void* state) {
     SceneState* s = state;
     SceneState* s = state;
     // temp fix pos
     // temp fix pos
     s->player_global.x = 154;
     s->player_global.x = 154;
-    s->dolphin_gfx = A_FX_Sitting_40x27;
-    s->dolphin_gfx_b = I_FX_SittingB_40x27;
+    s->dolphin_gfx = &A_FX_Sitting_40x27;
+    s->dolphin_gfx_b = &I_FX_SittingB_40x27;
 }
 }
 
 
 void inspect_painting(Canvas* canvas, void* state) {
 void inspect_painting(Canvas* canvas, void* state) {

+ 3 - 3
applications/dolphin/scenes/scene.h

@@ -66,7 +66,7 @@ typedef struct {
     uint16_t timeout;
     uint16_t timeout;
     int32_t x;
     int32_t x;
     int32_t y;
     int32_t y;
-    IconName icon;
+    const Icon* icon;
     char action_name[16];
     char action_name[16];
     void (*draw)(Canvas* canvas, void* model);
     void (*draw)(Canvas* canvas, void* model);
     void (*callback)(Canvas* canvas, void* model);
     void (*callback)(Canvas* canvas, void* model);
@@ -79,8 +79,8 @@ typedef struct {
     Vec2 player_v;
     Vec2 player_v;
     Vec2 screen;
     Vec2 screen;
 
 
-    IconName dolphin_gfx;
-    IconName dolphin_gfx_b; // temp
+    const Icon* dolphin_gfx;
+    const Icon* dolphin_gfx_b; // temp
 
 
     bool player_flipped;
     bool player_flipped;
     bool use_pending;
     bool use_pending;

+ 14 - 14
applications/dolphin/scenes/scene_gfx.c

@@ -104,37 +104,37 @@ void dolphin_scene_render_dolphin(SceneState* state, Canvas* canvas) {
     furi_assert(canvas);
     furi_assert(canvas);
 
 
     if(state->scene_zoom == SCENE_ZOOM) {
     if(state->scene_zoom == SCENE_ZOOM) {
-        state->dolphin_gfx = I_DolphinExcited_64x63;
+        state->dolphin_gfx = &I_DolphinExcited_64x63;
     } else if(state->action == SLEEP && state->player_global.x == 154) { // 2do - sofa x pos getter
     } else if(state->action == SLEEP && state->player_global.x == 154) { // 2do - sofa x pos getter
-        state->dolphin_gfx = A_FX_Sitting_40x27;
-        state->dolphin_gfx_b = I_FX_SittingB_40x27;
+        state->dolphin_gfx = &A_FX_Sitting_40x27;
+        state->dolphin_gfx_b = &I_FX_SittingB_40x27;
     } else if(state->action != INTERACT) {
     } else if(state->action != INTERACT) {
         if(state->player_v.x < 0 || state->player_flipped) {
         if(state->player_v.x < 0 || state->player_flipped) {
             if(state->player_anim == 0) {
             if(state->player_anim == 0) {
-                state->dolphin_gfx = I_WalkL1_32x32;
-                state->dolphin_gfx_b = I_WalkLB1_32x32;
+                state->dolphin_gfx = &I_WalkL1_32x32;
+                state->dolphin_gfx_b = &I_WalkLB1_32x32;
 
 
             } else {
             } else {
-                state->dolphin_gfx = I_WalkL2_32x32;
-                state->dolphin_gfx_b = I_WalkLB2_32x32;
+                state->dolphin_gfx = &I_WalkL2_32x32;
+                state->dolphin_gfx_b = &I_WalkLB2_32x32;
             }
             }
         } else if(state->player_v.x > 0 || !state->player_flipped) {
         } else if(state->player_v.x > 0 || !state->player_flipped) {
             if(state->player_anim == 0) {
             if(state->player_anim == 0) {
-                state->dolphin_gfx = I_WalkR1_32x32;
-                state->dolphin_gfx_b = I_WalkRB1_32x32;
+                state->dolphin_gfx = &I_WalkR1_32x32;
+                state->dolphin_gfx_b = &I_WalkRB1_32x32;
 
 
             } else {
             } else {
-                state->dolphin_gfx = I_WalkR2_32x32;
-                state->dolphin_gfx_b = I_WalkRB2_32x32;
+                state->dolphin_gfx = &I_WalkR2_32x32;
+                state->dolphin_gfx_b = &I_WalkRB2_32x32;
             }
             }
         }
         }
     }
     }
 
 
     canvas_set_bitmap_mode(canvas, true);
     canvas_set_bitmap_mode(canvas, true);
     canvas_set_color(canvas, ColorWhite);
     canvas_set_color(canvas, ColorWhite);
-    canvas_draw_icon_name(canvas, state->player.x, state->player.y, state->dolphin_gfx_b);
+    canvas_draw_icon(canvas, state->player.x, state->player.y, state->dolphin_gfx_b);
     canvas_set_color(canvas, ColorBlack);
     canvas_set_color(canvas, ColorBlack);
-    canvas_draw_icon_name(canvas, state->player.x, state->player.y, state->dolphin_gfx);
+    canvas_draw_icon(canvas, state->player.x, state->player.y, state->dolphin_gfx);
     canvas_set_bitmap_mode(canvas, false);
     canvas_set_bitmap_mode(canvas, false);
 }
 }
 
 
@@ -158,7 +158,7 @@ void dolphin_scene_render(SceneState* state, Canvas* canvas, uint32_t t) {
                     if(current_scene[i]->draw) current_scene[i]->draw(canvas, state);
                     if(current_scene[i]->draw) current_scene[i]->draw(canvas, state);
 
 
                     if(l == current_scene[i]->layer) {
                     if(l == current_scene[i]->layer) {
-                        canvas_draw_icon_name(
+                        canvas_draw_icon(
                             canvas,
                             canvas,
                             item_pos * PARALLAX(l),
                             item_pos * PARALLAX(l),
                             current_scene[i]->y,
                             current_scene[i]->y,

+ 2 - 2
applications/gui-test/gui-test.c

@@ -170,14 +170,14 @@ int32_t gui_test(void* param) {
     dialog_ex_set_header(gui_tester->dialog_ex, "Dallas", 95, 12, AlignCenter, AlignCenter);
     dialog_ex_set_header(gui_tester->dialog_ex, "Dallas", 95, 12, AlignCenter, AlignCenter);
     dialog_ex_set_text(
     dialog_ex_set_text(
         gui_tester->dialog_ex, "F6 E5 D4\nC3 B2 A1", 95, 32, AlignCenter, AlignCenter);
         gui_tester->dialog_ex, "F6 E5 D4\nC3 B2 A1", 95, 32, AlignCenter, AlignCenter);
-    dialog_ex_set_icon(gui_tester->dialog_ex, 0, 1, I_DolphinExcited_64x63);
+    dialog_ex_set_icon(gui_tester->dialog_ex, 0, 1, &I_DolphinExcited_64x63);
     dialog_ex_set_left_button_text(gui_tester->dialog_ex, "More");
     dialog_ex_set_left_button_text(gui_tester->dialog_ex, "More");
     dialog_ex_set_right_button_text(gui_tester->dialog_ex, "Save");
     dialog_ex_set_right_button_text(gui_tester->dialog_ex, "Save");
 
 
     // Popup
     // Popup
     popup_set_callback(gui_tester->popup, popup_callback);
     popup_set_callback(gui_tester->popup, popup_callback);
     popup_set_context(gui_tester->popup, gui_tester);
     popup_set_context(gui_tester->popup, gui_tester);
-    popup_set_icon(gui_tester->popup, 0, 2, I_DolphinMafia_115x62);
+    popup_set_icon(gui_tester->popup, 0, 2, &I_DolphinMafia_115x62);
     popup_set_text(gui_tester->popup, "Deleted", 83, 19, AlignLeft, AlignBottom);
     popup_set_text(gui_tester->popup, "Deleted", 83, 19, AlignLeft, AlignBottom);
     popup_set_timeout(gui_tester->popup, 5000);
     popup_set_timeout(gui_tester->popup, 5000);
     popup_enable_timeout(gui_tester->popup);
     popup_enable_timeout(gui_tester->popup);

+ 19 - 6
applications/gui/canvas.c

@@ -1,5 +1,6 @@
 #include "canvas_i.h"
 #include "canvas_i.h"
 #include "icon_i.h"
 #include "icon_i.h"
+#include "icon_animation_i.h"
 
 
 #include <furi.h>
 #include <furi.h>
 #include <api-hal.h>
 #include <api-hal.h>
@@ -175,21 +176,33 @@ uint16_t canvas_string_width(Canvas* canvas, const char* str) {
     return u8g2_GetStrWidth(&canvas->fb, str);
     return u8g2_GetStrWidth(&canvas->fb, str);
 }
 }
 
 
-void canvas_draw_icon(Canvas* canvas, uint8_t x, uint8_t y, Icon* icon) {
+void canvas_draw_icon_animation(
+    Canvas* canvas,
+    uint8_t x,
+    uint8_t y,
+    IconAnimation* icon_animation) {
     furi_assert(canvas);
     furi_assert(canvas);
-    if(!icon) return;
+    furi_assert(icon_animation);
+
     x += canvas->offset_x;
     x += canvas->offset_x;
     y += canvas->offset_y;
     y += canvas->offset_y;
     u8g2_DrawXBM(
     u8g2_DrawXBM(
-        &canvas->fb, x, y, icon_get_width(icon), icon_get_height(icon), icon_get_data(icon));
+        &canvas->fb,
+        x,
+        y,
+        icon_animation_get_width(icon_animation),
+        icon_animation_get_height(icon_animation),
+        icon_animation_get_data(icon_animation));
 }
 }
 
 
-void canvas_draw_icon_name(Canvas* canvas, uint8_t x, uint8_t y, IconName name) {
+void canvas_draw_icon(Canvas* canvas, uint8_t x, uint8_t y, const Icon* icon) {
     furi_assert(canvas);
     furi_assert(canvas);
-    const IconData* data = assets_icons_get_data(name);
+    furi_assert(icon);
+
     x += canvas->offset_x;
     x += canvas->offset_x;
     y += canvas->offset_y;
     y += canvas->offset_y;
-    u8g2_DrawXBM(&canvas->fb, x, y, data->width, data->height, data->frames[0]);
+    u8g2_DrawXBM(
+        &canvas->fb, x, y, icon_get_width(icon), icon_get_height(icon), icon_get_data(icon));
 }
 }
 
 
 void canvas_draw_dot(Canvas* canvas, uint8_t x, uint8_t y) {
 void canvas_draw_dot(Canvas* canvas, uint8_t x, uint8_t y) {

+ 18 - 8
applications/gui/canvas.h

@@ -1,8 +1,8 @@
 #pragma once
 #pragma once
 
 
 #include <stdint.h>
 #include <stdint.h>
-#include <gui/icon.h>
-#include <assets_icons_i.h>
+#include <gui/icon_animation.h>
+#include <assets_icons.h>
 
 
 #ifdef __cplusplus
 #ifdef __cplusplus
 extern "C" {
 extern "C" {
@@ -91,15 +91,25 @@ void canvas_draw_str_aligned(
  */
  */
 uint16_t canvas_string_width(Canvas* canvas, const char* str);
 uint16_t canvas_string_width(Canvas* canvas, const char* str);
 
 
-/*
- * Draw stateful icon at position defined by x,y.
+/** Draw animation at position defined by x,y.
+ * @param canvas - canvas instance
+ * @param x - x coordinate
+ * @param y - y coordinate
+ * @param icon_animation - data pointer to IconAnimation
  */
  */
-void canvas_draw_icon(Canvas* canvas, uint8_t x, uint8_t y, Icon* icon);
+void canvas_draw_icon_animation(
+    Canvas* canvas,
+    uint8_t x,
+    uint8_t y,
+    IconAnimation* icon_animation);
 
 
-/*
- * Draw stateless icon at position defined by x,y.
+/** Draw icon at position defined by x,y.
+ * @param canvas - canvas instance
+ * @param x - x coordinate
+ * @param y - y coordinate
+ * @param icon - data pointer to Icon
  */
  */
-void canvas_draw_icon_name(Canvas* canvas, uint8_t x, uint8_t y, IconName name);
+void canvas_draw_icon(Canvas* canvas, uint8_t x, uint8_t y, const Icon* icon);
 
 
 /*
 /*
  * Draw xbm icon of width, height at position defined by x,y.
  * Draw xbm icon of width, height at position defined by x,y.

+ 13 - 10
applications/gui/elements.c

@@ -1,10 +1,13 @@
 #include "elements.h"
 #include "elements.h"
 #include "gui/canvas.h"
 #include "gui/canvas.h"
-#include <assets_icons.h>
+
 #include <gui/icon_i.h>
 #include <gui/icon_i.h>
+#include <gui/icon_animation_i.h>
+
 #include <m-string.h>
 #include <m-string.h>
 #include <furi.h>
 #include <furi.h>
 #include "canvas_i.h"
 #include "canvas_i.h"
+
 #include <string.h>
 #include <string.h>
 #include <stdint.h>
 #include <stdint.h>
 
 
@@ -106,7 +109,7 @@ void elements_button_left(Canvas* canvas, const char* str) {
     const uint8_t vertical_offset = 3;
     const uint8_t vertical_offset = 3;
     const uint8_t horizontal_offset = 3;
     const uint8_t horizontal_offset = 3;
     const uint8_t string_width = canvas_string_width(canvas, str);
     const uint8_t string_width = canvas_string_width(canvas, str);
-    const IconData* icon = assets_icons_get_data(I_ButtonLeft_4x7);
+    const Icon* icon = &I_ButtonLeft_4x7;
     const uint8_t icon_offset = 3;
     const uint8_t icon_offset = 3;
     const uint8_t icon_width_with_offset = icon->width + icon_offset;
     const uint8_t icon_width_with_offset = icon->width + icon_offset;
     const uint8_t button_width = string_width + horizontal_offset * 2 + icon_width_with_offset;
     const uint8_t button_width = string_width + horizontal_offset * 2 + icon_width_with_offset;
@@ -120,8 +123,8 @@ void elements_button_left(Canvas* canvas, const char* str) {
     canvas_draw_line(canvas, x + button_width + 2, y, x + button_width + 2, y - button_height + 2);
     canvas_draw_line(canvas, x + button_width + 2, y, x + button_width + 2, y - button_height + 2);
 
 
     canvas_invert_color(canvas);
     canvas_invert_color(canvas);
-    canvas_draw_icon_name(
-        canvas, x + horizontal_offset, y - button_height + vertical_offset, I_ButtonLeft_4x7);
+    canvas_draw_icon(
+        canvas, x + horizontal_offset, y - button_height + vertical_offset, &I_ButtonLeft_4x7);
     canvas_draw_str(
     canvas_draw_str(
         canvas, x + horizontal_offset + icon_width_with_offset, y - vertical_offset, str);
         canvas, x + horizontal_offset + icon_width_with_offset, y - vertical_offset, str);
     canvas_invert_color(canvas);
     canvas_invert_color(canvas);
@@ -132,7 +135,7 @@ void elements_button_right(Canvas* canvas, const char* str) {
     const uint8_t vertical_offset = 3;
     const uint8_t vertical_offset = 3;
     const uint8_t horizontal_offset = 3;
     const uint8_t horizontal_offset = 3;
     const uint8_t string_width = canvas_string_width(canvas, str);
     const uint8_t string_width = canvas_string_width(canvas, str);
-    const IconData* icon = assets_icons_get_data(I_ButtonRight_4x7);
+    const Icon* icon = &I_ButtonRight_4x7;
     const uint8_t icon_offset = 3;
     const uint8_t icon_offset = 3;
     const uint8_t icon_width_with_offset = icon->width + icon_offset;
     const uint8_t icon_width_with_offset = icon->width + icon_offset;
     const uint8_t button_width = string_width + horizontal_offset * 2 + icon_width_with_offset;
     const uint8_t button_width = string_width + horizontal_offset * 2 + icon_width_with_offset;
@@ -147,11 +150,11 @@ void elements_button_right(Canvas* canvas, const char* str) {
 
 
     canvas_invert_color(canvas);
     canvas_invert_color(canvas);
     canvas_draw_str(canvas, x - button_width + horizontal_offset, y - vertical_offset, str);
     canvas_draw_str(canvas, x - button_width + horizontal_offset, y - vertical_offset, str);
-    canvas_draw_icon_name(
+    canvas_draw_icon(
         canvas,
         canvas,
         x - horizontal_offset - icon->width,
         x - horizontal_offset - icon->width,
         y - button_height + vertical_offset,
         y - button_height + vertical_offset,
-        I_ButtonRight_4x7);
+        &I_ButtonRight_4x7);
     canvas_invert_color(canvas);
     canvas_invert_color(canvas);
 }
 }
 
 
@@ -160,7 +163,7 @@ void elements_button_center(Canvas* canvas, const char* str) {
     const uint8_t vertical_offset = 3;
     const uint8_t vertical_offset = 3;
     const uint8_t horizontal_offset = 1;
     const uint8_t horizontal_offset = 1;
     const uint8_t string_width = canvas_string_width(canvas, str);
     const uint8_t string_width = canvas_string_width(canvas, str);
-    const IconData* icon = assets_icons_get_data(I_ButtonCenter_7x7);
+    const Icon* icon = &I_ButtonCenter_7x7;
     const uint8_t icon_offset = 3;
     const uint8_t icon_offset = 3;
     const uint8_t icon_width_with_offset = icon->width + icon_offset;
     const uint8_t icon_width_with_offset = icon->width + icon_offset;
     const uint8_t button_width = string_width + horizontal_offset * 2 + icon_width_with_offset;
     const uint8_t button_width = string_width + horizontal_offset * 2 + icon_width_with_offset;
@@ -179,8 +182,8 @@ void elements_button_center(Canvas* canvas, const char* str) {
     canvas_draw_line(canvas, x + button_width + 2, y, x + button_width + 2, y - button_height + 2);
     canvas_draw_line(canvas, x + button_width + 2, y, x + button_width + 2, y - button_height + 2);
 
 
     canvas_invert_color(canvas);
     canvas_invert_color(canvas);
-    canvas_draw_icon_name(
-        canvas, x + horizontal_offset, y - button_height + vertical_offset, I_ButtonCenter_7x7);
+    canvas_draw_icon(
+        canvas, x + horizontal_offset, y - button_height + vertical_offset, &I_ButtonCenter_7x7);
     canvas_draw_str(
     canvas_draw_str(
         canvas, x + horizontal_offset + icon_width_with_offset, y - vertical_offset, str);
         canvas, x + horizontal_offset + icon_width_with_offset, y - vertical_offset, str);
     canvas_invert_color(canvas);
     canvas_invert_color(canvas);

+ 1 - 1
applications/gui/gui.c

@@ -85,7 +85,7 @@ void gui_redraw_status_bar(Gui* gui) {
     canvas_set_orientation(gui->canvas, CanvasOrientationHorizontal);
     canvas_set_orientation(gui->canvas, CanvasOrientationHorizontal);
     canvas_frame_set(
     canvas_frame_set(
         gui->canvas, GUI_STATUS_BAR_X, GUI_STATUS_BAR_Y, GUI_DISPLAY_WIDTH, GUI_STATUS_BAR_HEIGHT);
         gui->canvas, GUI_STATUS_BAR_X, GUI_STATUS_BAR_Y, GUI_DISPLAY_WIDTH, GUI_STATUS_BAR_HEIGHT);
-    canvas_draw_icon_name(gui->canvas, 0, 0, I_Background_128x11);
+    canvas_draw_icon(gui->canvas, 0, 0, &I_Background_128x11);
 
 
     // Right side
     // Right side
     x = GUI_DISPLAY_WIDTH;
     x = GUI_DISPLAY_WIDTH;

+ 6 - 68
applications/gui/icon.c

@@ -1,75 +1,13 @@
 #include "icon_i.h"
 #include "icon_i.h"
 
 
-#include <furi.h>
-
-Icon* icon_alloc(const IconData* data) {
-    Icon* icon = furi_alloc(sizeof(Icon));
-    icon->data = data;
-    return icon;
-}
-
-void icon_free(Icon* icon) {
-    furi_assert(icon);
-    free(icon);
-}
-
-const uint8_t* icon_get_data(Icon* icon) {
-    furi_assert(icon);
-    if(icon->tick) {
-        uint32_t now = osKernelGetTickCount();
-        if(now < icon->tick) {
-            icon->tick = now;
-            icon_next_frame(icon);
-        } else if(now - icon->tick > osKernelGetTickFreq() / icon->data->frame_rate) {
-            icon->tick = now;
-            icon_next_frame(icon);
-        }
-    }
-    return icon->data->frames[icon->frame];
-}
-
-void icon_next_frame(Icon* icon) {
-    furi_assert(icon);
-    icon->frame = (icon->frame + 1) % icon->data->frame_count;
-}
-
-uint8_t icon_get_width(Icon* icon) {
-    furi_assert(icon);
-    return icon->data->width;
-}
-
-uint8_t icon_get_height(Icon* icon) {
-    furi_assert(icon);
-    return icon->data->height;
-}
-
-bool icon_is_animated(Icon* icon) {
-    furi_assert(icon);
-    return icon->data->frame_count > 1;
-}
-
-bool icon_is_animating(Icon* icon) {
-    furi_assert(icon);
-    return icon->tick > 0;
-}
-
-void icon_start_animation(Icon* icon) {
-    furi_assert(icon);
-    icon->tick = osKernelGetTickCount();
-}
-
-void icon_stop_animation(Icon* icon) {
-    furi_assert(icon);
-    icon->tick = 0;
-    icon->frame = 0;
+uint8_t icon_get_width(const Icon* instance) {
+    return instance->width;
 }
 }
 
 
-uint8_t icon_get_current_frame(Icon* icon) {
-    furi_assert(icon);
-    return icon->frame;
+uint8_t icon_get_height(const Icon* instance) {
+    return instance->height;
 }
 }
 
 
-bool icon_is_last_frame(Icon* icon) {
-    furi_assert(icon);
-    return icon->data->frame_count - icon->frame <= 1;
+const uint8_t* icon_get_data(const Icon* instance) {
+    return instance->frames[0];
 }
 }

+ 4 - 51
applications/gui/icon.h

@@ -1,66 +1,19 @@
 #pragma once
 #pragma once
 
 
 #include <stdint.h>
 #include <stdint.h>
-#include <stdbool.h>
 
 
 #ifdef __cplusplus
 #ifdef __cplusplus
 extern "C" {
 extern "C" {
 #endif
 #endif
 
 
-typedef struct IconData IconData;
 typedef struct Icon Icon;
 typedef struct Icon Icon;
 
 
-/*
- * Allocate icon instance with const icon data.
- * always returns Icon or stops system if not enough memory
- */
-Icon* icon_alloc(const IconData* data);
+uint8_t icon_get_width(const Icon* instance);
 
 
-/*
- * Release icon instance
- */
-void icon_free(Icon* icon);
+uint8_t icon_get_height(const Icon* instance);
 
 
-/*
- * Get icon width
- */
-uint8_t icon_get_width(Icon* icon);
-
-/*
- * Get icon height
- */
-uint8_t icon_get_height(Icon* icon);
-
-/*
- * Check if icon is animated
- */
-bool icon_is_animated(Icon* icon);
-
-/*
- * Check if icon animation is active
- */
-bool icon_is_animating(Icon* icon);
-
-/*
- * Start icon animation
- */
-void icon_start_animation(Icon* icon);
-
-/*
- * Stop icon animation
- */
-void icon_stop_animation(Icon* icon);
-
-/*
- * Get current frame
- */
-uint8_t icon_get_current_frame(Icon* icon);
-
-/*
- * Returns true if current frame is a last one
- */
-bool icon_is_last_frame(Icon* icon);
+const uint8_t* icon_get_data(const Icon* instance);
 
 
 #ifdef __cplusplus
 #ifdef __cplusplus
 }
 }
-#endif
+#endif

+ 77 - 0
applications/gui/icon_animation.c

@@ -0,0 +1,77 @@
+#include "icon_animation_i.h"
+#include "icon_i.h"
+
+#include <furi.h>
+
+IconAnimation* icon_animation_alloc(const Icon* icon) {
+    furi_assert(icon);
+    IconAnimation* instance = furi_alloc(sizeof(IconAnimation));
+    instance->icon = icon;
+    return instance;
+}
+
+void icon_animation_free(IconAnimation* instance) {
+    furi_assert(instance);
+    free(instance);
+}
+
+const uint8_t* icon_animation_get_data(IconAnimation* instance) {
+    furi_assert(instance);
+    if(instance->tick) {
+        uint32_t now = osKernelGetTickCount();
+        if(now < instance->tick) {
+            instance->tick = now;
+            icon_animation_next_frame(instance);
+        } else if(now - instance->tick > osKernelGetTickFreq() / instance->icon->frame_rate) {
+            instance->tick = now;
+            icon_animation_next_frame(instance);
+        }
+    }
+    return instance->icon->frames[instance->frame];
+}
+
+void icon_animation_next_frame(IconAnimation* instance) {
+    furi_assert(instance);
+    instance->frame = (instance->frame + 1) % instance->icon->frame_count;
+}
+
+uint8_t icon_animation_get_width(IconAnimation* instance) {
+    furi_assert(instance);
+    return instance->icon->width;
+}
+
+uint8_t icon_animation_get_height(IconAnimation* instance) {
+    furi_assert(instance);
+    return instance->icon->height;
+}
+
+bool icon_animation_is_animated(IconAnimation* instance) {
+    furi_assert(instance);
+    return instance->icon->frame_count > 1;
+}
+
+bool icon_animation_is_animating(IconAnimation* instance) {
+    furi_assert(instance);
+    return instance->tick > 0;
+}
+
+void icon_animation_start(IconAnimation* instance) {
+    furi_assert(instance);
+    instance->tick = osKernelGetTickCount();
+}
+
+void icon_animation_stop(IconAnimation* instance) {
+    furi_assert(instance);
+    instance->tick = 0;
+    instance->frame = 0;
+}
+
+uint8_t icon_animation_get_current_frame(IconAnimation* instance) {
+    furi_assert(instance);
+    return instance->frame;
+}
+
+bool icon_animation_is_last_frame(IconAnimation* instance) {
+    furi_assert(instance);
+    return instance->icon->frame_count - instance->frame <= 1;
+}

+ 67 - 0
applications/gui/icon_animation.h

@@ -0,0 +1,67 @@
+#pragma once
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <assets_icons.h>
+
+typedef struct IconAnimation IconAnimation;
+
+/*
+ * Allocate icon animation instance with const icon data.
+ * always returns Icon or stops system if not enough memory
+ */
+IconAnimation* icon_animation_alloc(const Icon* icon);
+
+/*
+ * Release icon animation instance
+ */
+void icon_animation_free(IconAnimation* instance);
+
+/*
+ * Get icon animation width
+ */
+uint8_t icon_animation_get_width(IconAnimation* instance);
+
+/*
+ * Get icon animation height
+ */
+uint8_t icon_animation_get_height(IconAnimation* instance);
+
+/*
+ * Check if icon is animated
+ */
+bool icon_animation_is_animated(IconAnimation* instance);
+
+/*
+ * Check if icon animation is active
+ */
+bool icon_animation_is_animating(IconAnimation* instance);
+
+/*
+ * Start icon animation
+ */
+void icon_animation_start(IconAnimation* instance);
+
+/*
+ * Stop icon animation
+ */
+void icon_animation_stop(IconAnimation* instance);
+
+/*
+ * Get current frame
+ */
+uint8_t icon_animation_get_current_frame(IconAnimation* instance);
+
+/*
+ * Returns true if current frame is a last one
+ */
+bool icon_animation_is_last_frame(IconAnimation* instance);
+
+#ifdef __cplusplus
+}
+#endif

+ 21 - 0
applications/gui/icon_animation_i.h

@@ -0,0 +1,21 @@
+#pragma once
+
+#include "icon_animation.h"
+
+#include <stdint.h>
+
+struct IconAnimation {
+    const Icon* icon;
+    uint8_t frame;
+    uint32_t tick;
+};
+
+/*
+ * Get pointer to current frame data
+ */
+const uint8_t* icon_animation_get_data(IconAnimation* instance);
+
+/*
+ * Advance to next frame
+ */
+void icon_animation_next_frame(IconAnimation* instance);

+ 1 - 21
applications/gui/icon_i.h

@@ -1,29 +1,9 @@
-#pragma once
-
 #include "icon.h"
 #include "icon.h"
 
 
-#include <stdint.h>
-
-struct IconData {
+struct Icon {
     const uint8_t width;
     const uint8_t width;
     const uint8_t height;
     const uint8_t height;
     const uint8_t frame_count;
     const uint8_t frame_count;
     const uint8_t frame_rate;
     const uint8_t frame_rate;
     const uint8_t** frames;
     const uint8_t** frames;
 };
 };
-
-struct Icon {
-    const IconData* data;
-    uint8_t frame;
-    uint32_t tick;
-};
-
-/*
- * Get pointer to current frame data
- */
-const uint8_t* icon_get_data(Icon* icon);
-
-/*
- * Advance to next frame
- */
-void icon_next_frame(Icon* icon);

+ 2 - 2
applications/gui/modules/button_menu.c

@@ -101,11 +101,11 @@ static void button_menu_view_draw_callback(Canvas* canvas, void* _model) {
     ButtonMenuItemArray_it_t it;
     ButtonMenuItemArray_it_t it;
 
 
     if(active_screen > 0) {
     if(active_screen > 0) {
-        canvas_draw_icon_name(canvas, 28, 1, I_IrdaArrowUp_4x8);
+        canvas_draw_icon(canvas, 28, 1, &I_IrdaArrowUp_4x8);
     }
     }
 
 
     if(max_screen > active_screen) {
     if(max_screen > active_screen) {
-        canvas_draw_icon_name(canvas, 28, 123, I_IrdaArrowDown_4x8);
+        canvas_draw_icon(canvas, 28, 123, &I_IrdaArrowDown_4x8);
     }
     }
 
 
     canvas_draw_str_aligned(canvas, 32, 10, AlignCenter, AlignCenter, model->header);
     canvas_draw_str_aligned(canvas, 32, 10, AlignCenter, AlignCenter, model->header);

+ 6 - 6
applications/gui/modules/button_panel.c

@@ -22,8 +22,8 @@ LIST_DEF(LabelList, LabelElement, M_POD_OPLIST)
 typedef struct {
 typedef struct {
     uint16_t x;
     uint16_t x;
     uint16_t y;
     uint16_t y;
-    IconName name;
-    IconName name_selected;
+    const Icon* name;
+    const Icon* name_selected;
 } IconElement;
 } IconElement;
 
 
 typedef struct ButtonItem {
 typedef struct ButtonItem {
@@ -158,8 +158,8 @@ void button_panel_add_item(
     uint16_t matrix_place_y,
     uint16_t matrix_place_y,
     uint16_t x,
     uint16_t x,
     uint16_t y,
     uint16_t y,
-    IconName icon_name,
-    IconName icon_name_selected,
+    const Icon* icon_name,
+    const Icon* icon_name_selected,
     ButtonItemCallback callback,
     ButtonItemCallback callback,
     void* callback_context) {
     void* callback_context) {
     furi_assert(button_panel);
     furi_assert(button_panel);
@@ -199,11 +199,11 @@ static void button_panel_view_draw_callback(Canvas* canvas, void* _model) {
     for(size_t x = 0; x < model->reserve_x; ++x) {
     for(size_t x = 0; x < model->reserve_x; ++x) {
         for(size_t y = 0; y < model->reserve_y; ++y) {
         for(size_t y = 0; y < model->reserve_y; ++y) {
             ButtonItem* button_item = *button_panel_get_item(model, x, y);
             ButtonItem* button_item = *button_panel_get_item(model, x, y);
-            IconName icon_name = button_item->icon.name;
+            const Icon* icon_name = button_item->icon.name;
             if((model->selected_item_x == x) && (model->selected_item_y == y)) {
             if((model->selected_item_x == x) && (model->selected_item_y == y)) {
                 icon_name = button_item->icon.name_selected;
                 icon_name = button_item->icon.name_selected;
             }
             }
-            canvas_draw_icon_name(canvas, button_item->icon.x, button_item->icon.y, icon_name);
+            canvas_draw_icon(canvas, button_item->icon.x, button_item->icon.y, icon_name);
         }
         }
     }
     }
 
 

+ 2 - 2
applications/gui/modules/button_panel.h

@@ -70,8 +70,8 @@ void button_panel_add_item(
     uint16_t matrix_place_y,
     uint16_t matrix_place_y,
     uint16_t x,
     uint16_t x,
     uint16_t y,
     uint16_t y,
-    IconName icon_name,
-    IconName icon_name_selected,
+    const Icon* icon_name,
+    const Icon* icon_name_selected,
     ButtonItemCallback callback,
     ButtonItemCallback callback,
     void* callback_context);
     void* callback_context);
 
 

+ 16 - 16
applications/gui/modules/byte_input.c

@@ -155,8 +155,8 @@ static void byte_input_draw_input(Canvas* canvas, ByteInputModel* model) {
 
 
     elements_slightly_rounded_frame(canvas, 6, 14, 116, 15);
     elements_slightly_rounded_frame(canvas, 6, 14, 116, 15);
 
 
-    canvas_draw_icon_name(canvas, 2, 19, I_ButtonLeftSmall_3x5);
-    canvas_draw_icon_name(canvas, 123, 19, I_ButtonRightSmall_3x5);
+    canvas_draw_icon(canvas, 2, 19, &I_ButtonLeftSmall_3x5);
+    canvas_draw_icon(canvas, 123, 19, &I_ButtonRightSmall_3x5);
 
 
     for(uint8_t i = model->first_visible_byte;
     for(uint8_t i = model->first_visible_byte;
         i < model->first_visible_byte + MIN(model->bytes_count, max_drawable_bytes);
         i < model->first_visible_byte + MIN(model->bytes_count, max_drawable_bytes);
@@ -222,11 +222,11 @@ static void byte_input_draw_input(Canvas* canvas, ByteInputModel* model) {
     }
     }
 
 
     if(model->bytes_count - model->first_visible_byte > max_drawable_bytes) {
     if(model->bytes_count - model->first_visible_byte > max_drawable_bytes) {
-        canvas_draw_icon_name(canvas, 123, 21, I_ButtonRightSmall_3x5);
+        canvas_draw_icon(canvas, 123, 21, &I_ButtonRightSmall_3x5);
     }
     }
 
 
     if(model->first_visible_byte > 0) {
     if(model->first_visible_byte > 0) {
-        canvas_draw_icon_name(canvas, 1, 21, I_ButtonLeftSmall_3x5);
+        canvas_draw_icon(canvas, 1, 21, &I_ButtonLeftSmall_3x5);
     }
     }
 }
 }
 
 
@@ -244,8 +244,8 @@ static void byte_input_draw_input_selected(Canvas* canvas, ByteInputModel* model
     canvas_invert_color(canvas);
     canvas_invert_color(canvas);
 
 
     elements_slightly_rounded_frame(canvas, 6, 14, 115, 15);
     elements_slightly_rounded_frame(canvas, 6, 14, 115, 15);
-    canvas_draw_icon_name(canvas, 2, 19, I_ButtonLeftSmall_3x5);
-    canvas_draw_icon_name(canvas, 122, 19, I_ButtonRightSmall_3x5);
+    canvas_draw_icon(canvas, 2, 19, &I_ButtonLeftSmall_3x5);
+    canvas_draw_icon(canvas, 122, 19, &I_ButtonRightSmall_3x5);
 
 
     for(uint8_t i = model->first_visible_byte;
     for(uint8_t i = model->first_visible_byte;
         i < model->first_visible_byte + MIN(model->bytes_count, max_drawable_bytes);
         i < model->first_visible_byte + MIN(model->bytes_count, max_drawable_bytes);
@@ -281,11 +281,11 @@ static void byte_input_draw_input_selected(Canvas* canvas, ByteInputModel* model
     }
     }
 
 
     if(model->bytes_count - model->first_visible_byte > max_drawable_bytes) {
     if(model->bytes_count - model->first_visible_byte > max_drawable_bytes) {
-        canvas_draw_icon_name(canvas, 123, 21, I_ButtonRightSmall_3x5);
+        canvas_draw_icon(canvas, 123, 21, &I_ButtonRightSmall_3x5);
     }
     }
 
 
     if(model->first_visible_byte > 0) {
     if(model->first_visible_byte > 0) {
-        canvas_draw_icon_name(canvas, 1, 21, I_ButtonLeftSmall_3x5);
+        canvas_draw_icon(canvas, 1, 21, &I_ButtonLeftSmall_3x5);
     }
     }
 
 
     canvas_invert_color(canvas);
     canvas_invert_color(canvas);
@@ -542,32 +542,32 @@ static void byte_input_view_draw_callback(Canvas* canvas, void* _model) {
             if(keys[column].value == enter_symbol) {
             if(keys[column].value == enter_symbol) {
                 canvas_set_color(canvas, ColorBlack);
                 canvas_set_color(canvas, ColorBlack);
                 if(model->selected_row == row && model->selected_column == column) {
                 if(model->selected_row == row && model->selected_column == column) {
-                    canvas_draw_icon_name(
+                    canvas_draw_icon(
                         canvas,
                         canvas,
                         keyboard_origin_x + keys[column].x,
                         keyboard_origin_x + keys[column].x,
                         keyboard_origin_y + keys[column].y,
                         keyboard_origin_y + keys[column].y,
-                        I_KeySaveSelected_24x11);
+                        &I_KeySaveSelected_24x11);
                 } else {
                 } else {
-                    canvas_draw_icon_name(
+                    canvas_draw_icon(
                         canvas,
                         canvas,
                         keyboard_origin_x + keys[column].x,
                         keyboard_origin_x + keys[column].x,
                         keyboard_origin_y + keys[column].y,
                         keyboard_origin_y + keys[column].y,
-                        I_KeySave_24x11);
+                        &I_KeySave_24x11);
                 }
                 }
             } else if(keys[column].value == backspace_symbol) {
             } else if(keys[column].value == backspace_symbol) {
                 canvas_set_color(canvas, ColorBlack);
                 canvas_set_color(canvas, ColorBlack);
                 if(model->selected_row == row && model->selected_column == column) {
                 if(model->selected_row == row && model->selected_column == column) {
-                    canvas_draw_icon_name(
+                    canvas_draw_icon(
                         canvas,
                         canvas,
                         keyboard_origin_x + keys[column].x,
                         keyboard_origin_x + keys[column].x,
                         keyboard_origin_y + keys[column].y,
                         keyboard_origin_y + keys[column].y,
-                        I_KeyBackspaceSelected_16x9);
+                        &I_KeyBackspaceSelected_16x9);
                 } else {
                 } else {
-                    canvas_draw_icon_name(
+                    canvas_draw_icon(
                         canvas,
                         canvas,
                         keyboard_origin_x + keys[column].x,
                         keyboard_origin_x + keys[column].x,
                         keyboard_origin_y + keys[column].y,
                         keyboard_origin_y + keys[column].y,
-                        I_KeyBackspace_16x9);
+                        &I_KeyBackspace_16x9);
                 }
                 }
             } else {
             } else {
                 if(model->selected_row == row && model->selected_column == column) {
                 if(model->selected_row == row && model->selected_column == column) {

+ 6 - 6
applications/gui/modules/dialog_ex.c

@@ -19,7 +19,7 @@ typedef struct {
 typedef struct {
 typedef struct {
     int8_t x;
     int8_t x;
     int8_t y;
     int8_t y;
-    IconName name;
+    const Icon* icon;
 } IconElement;
 } IconElement;
 
 
 typedef struct {
 typedef struct {
@@ -39,8 +39,8 @@ static void dialog_ex_view_draw_callback(Canvas* canvas, void* _model) {
     canvas_clear(canvas);
     canvas_clear(canvas);
     canvas_set_color(canvas, ColorBlack);
     canvas_set_color(canvas, ColorBlack);
 
 
-    if(model->icon.name != I_Empty_1x1) {
-        canvas_draw_icon_name(canvas, model->icon.x, model->icon.y, model->icon.name);
+    if(model->icon.icon != NULL) {
+        canvas_draw_icon(canvas, model->icon.x, model->icon.y, model->icon.icon);
     }
     }
 
 
     // Draw header
     // Draw header
@@ -136,7 +136,7 @@ DialogEx* dialog_ex_alloc() {
 
 
             model->icon.x = 0;
             model->icon.x = 0;
             model->icon.y = 0;
             model->icon.y = 0;
-            model->icon.name = I_Empty_1x1;
+            model->icon.icon = NULL;
 
 
             model->left_text = NULL;
             model->left_text = NULL;
             model->center_text = NULL;
             model->center_text = NULL;
@@ -206,13 +206,13 @@ void dialog_ex_set_text(
         });
         });
 }
 }
 
 
-void dialog_ex_set_icon(DialogEx* dialog_ex, uint8_t x, uint8_t y, IconName name) {
+void dialog_ex_set_icon(DialogEx* dialog_ex, uint8_t x, uint8_t y, const Icon* icon) {
     furi_assert(dialog_ex);
     furi_assert(dialog_ex);
     with_view_model(
     with_view_model(
         dialog_ex->view, (DialogExModel * model) {
         dialog_ex->view, (DialogExModel * model) {
             model->icon.x = x;
             model->icon.x = x;
             model->icon.y = y;
             model->icon.y = y;
-            model->icon.name = name;
+            model->icon.icon = icon;
             return true;
             return true;
         });
         });
 }
 }

+ 1 - 1
applications/gui/modules/dialog_ex.h

@@ -84,7 +84,7 @@ void dialog_ex_set_text(
  * @param x, y - icon position
  * @param x, y - icon position
  * @param name - icon to be shown
  * @param name - icon to be shown
  */
  */
-void dialog_ex_set_icon(DialogEx* dialog_ex, uint8_t x, uint8_t y, IconName name);
+void dialog_ex_set_icon(DialogEx* dialog_ex, uint8_t x, uint8_t y, const Icon* icon);
 
 
 /* Set left button text
 /* Set left button text
  * If text is null, left button will not be rendered and processed
  * If text is null, left button will not be rendered and processed

+ 6 - 6
applications/gui/modules/popup.c

@@ -23,7 +23,7 @@ typedef struct {
 typedef struct {
 typedef struct {
     uint8_t x;
     uint8_t x;
     uint8_t y;
     uint8_t y;
-    IconName name;
+    const Icon* icon;
 } IconElement;
 } IconElement;
 
 
 typedef struct {
 typedef struct {
@@ -39,8 +39,8 @@ static void popup_view_draw_callback(Canvas* canvas, void* _model) {
     canvas_clear(canvas);
     canvas_clear(canvas);
     canvas_set_color(canvas, ColorBlack);
     canvas_set_color(canvas, ColorBlack);
 
 
-    if(model->icon.name != I_Empty_1x1) {
-        canvas_draw_icon_name(canvas, model->icon.x, model->icon.y, model->icon.name);
+    if(model->icon.icon != NULL) {
+        canvas_draw_icon(canvas, model->icon.x, model->icon.y, model->icon.icon);
     }
     }
 
 
     // Draw header
     // Draw header
@@ -138,7 +138,7 @@ Popup* popup_alloc() {
 
 
             model->icon.x = 0;
             model->icon.x = 0;
             model->icon.y = 0;
             model->icon.y = 0;
-            model->icon.name = I_Empty_1x1;
+            model->icon.icon = NULL;
             return true;
             return true;
         });
         });
     return popup;
     return popup;
@@ -204,13 +204,13 @@ void popup_set_text(
         });
         });
 }
 }
 
 
-void popup_set_icon(Popup* popup, uint8_t x, uint8_t y, IconName name) {
+void popup_set_icon(Popup* popup, uint8_t x, uint8_t y, const Icon* icon) {
     furi_assert(popup);
     furi_assert(popup);
     with_view_model(
     with_view_model(
         popup->view, (PopupModel * model) {
         popup->view, (PopupModel * model) {
             model->icon.x = x;
             model->icon.x = x;
             model->icon.y = y;
             model->icon.y = y;
-            model->icon.name = name;
+            model->icon.icon = icon;
             return true;
             return true;
         });
         });
 }
 }

+ 1 - 1
applications/gui/modules/popup.h

@@ -77,7 +77,7 @@ void popup_set_text(
  * @param x, y - icon position
  * @param x, y - icon position
  * @param name - icon to be shown
  * @param name - icon to be shown
  */
  */
-void popup_set_icon(Popup* popup, uint8_t x, uint8_t y, IconName name);
+void popup_set_icon(Popup* popup, uint8_t x, uint8_t y, const Icon* icon);
 
 
 /* Set popup timeout
 /* Set popup timeout
  * @param popup - Popup instance
  * @param popup - Popup instance

+ 8 - 8
applications/gui/modules/text_input.c

@@ -173,32 +173,32 @@ static void text_input_view_draw_callback(Canvas* canvas, void* _model) {
             if(keys[column].text == ENTER_KEY) {
             if(keys[column].text == ENTER_KEY) {
                 canvas_set_color(canvas, ColorBlack);
                 canvas_set_color(canvas, ColorBlack);
                 if(model->selected_row == row && model->selected_column == column) {
                 if(model->selected_row == row && model->selected_column == column) {
-                    canvas_draw_icon_name(
+                    canvas_draw_icon(
                         canvas,
                         canvas,
                         keyboard_origin_x + keys[column].x,
                         keyboard_origin_x + keys[column].x,
                         keyboard_origin_y + keys[column].y,
                         keyboard_origin_y + keys[column].y,
-                        I_KeySaveSelected_24x11);
+                        &I_KeySaveSelected_24x11);
                 } else {
                 } else {
-                    canvas_draw_icon_name(
+                    canvas_draw_icon(
                         canvas,
                         canvas,
                         keyboard_origin_x + keys[column].x,
                         keyboard_origin_x + keys[column].x,
                         keyboard_origin_y + keys[column].y,
                         keyboard_origin_y + keys[column].y,
-                        I_KeySave_24x11);
+                        &I_KeySave_24x11);
                 }
                 }
             } else if(keys[column].text == BACKSPACE_KEY) {
             } else if(keys[column].text == BACKSPACE_KEY) {
                 canvas_set_color(canvas, ColorBlack);
                 canvas_set_color(canvas, ColorBlack);
                 if(model->selected_row == row && model->selected_column == column) {
                 if(model->selected_row == row && model->selected_column == column) {
-                    canvas_draw_icon_name(
+                    canvas_draw_icon(
                         canvas,
                         canvas,
                         keyboard_origin_x + keys[column].x,
                         keyboard_origin_x + keys[column].x,
                         keyboard_origin_y + keys[column].y,
                         keyboard_origin_y + keys[column].y,
-                        I_KeyBackspaceSelected_16x9);
+                        &I_KeyBackspaceSelected_16x9);
                 } else {
                 } else {
-                    canvas_draw_icon_name(
+                    canvas_draw_icon(
                         canvas,
                         canvas,
                         keyboard_origin_x + keys[column].x,
                         keyboard_origin_x + keys[column].x,
                         keyboard_origin_y + keys[column].y,
                         keyboard_origin_y + keys[column].y,
-                        I_KeyBackspace_16x9);
+                        &I_KeyBackspace_16x9);
                 }
                 }
             } else {
             } else {
                 if(model->selected_row == row && model->selected_column == column) {
                 if(model->selected_row == row && model->selected_column == column) {

+ 1 - 1
applications/gui/view_dispatcher.c

@@ -26,7 +26,7 @@ void view_dispatcher_free(ViewDispatcher* view_dispatcher) {
     while(!ViewDict_end_p(it)) {
     while(!ViewDict_end_p(it)) {
         ViewDict_itref_t* ref = ViewDict_ref(it);
         ViewDict_itref_t* ref = ViewDict_ref(it);
         // Crash if view wasn't freed
         // Crash if view wasn't freed
-        furi_assert(ref->value);
+        furi_check(ref->value);
         ViewDict_next(it);
         ViewDict_next(it);
     }
     }
     ViewDict_clear(view_dispatcher->views);
     ViewDict_clear(view_dispatcher->views);

+ 2 - 2
applications/ibutton/scene/ibutton-scene-delete-success.cpp

@@ -10,7 +10,7 @@ void iButtonSceneDeleteSuccess::on_enter(iButtonApp* app) {
     Popup* popup = view_manager->get_popup();
     Popup* popup = view_manager->get_popup();
     auto callback = cbc::obtain_connector(this, &iButtonSceneDeleteSuccess::popup_callback);
     auto callback = cbc::obtain_connector(this, &iButtonSceneDeleteSuccess::popup_callback);
 
 
-    popup_set_icon(popup, 0, 2, I_DolphinMafia_115x62);
+    popup_set_icon(popup, 0, 2, &I_DolphinMafia_115x62);
     popup_set_text(popup, "Deleted", 83, 19, AlignLeft, AlignBottom);
     popup_set_text(popup, "Deleted", 83, 19, AlignLeft, AlignBottom);
 
 
     popup_set_callback(popup, callback);
     popup_set_callback(popup, callback);
@@ -36,7 +36,7 @@ void iButtonSceneDeleteSuccess::on_exit(iButtonApp* app) {
     Popup* popup = app->get_view_manager()->get_popup();
     Popup* popup = app->get_view_manager()->get_popup();
 
 
     popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop);
     popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop);
-    popup_set_icon(popup, 0, 0, I_Empty_1x1);
+    popup_set_icon(popup, 0, 0, NULL);
 
 
     popup_disable_timeout(popup);
     popup_disable_timeout(popup);
     popup_set_context(popup, NULL);
     popup_set_context(popup, NULL);

+ 2 - 2
applications/ibutton/scene/ibutton-scene-emulate.cpp

@@ -61,7 +61,7 @@ void iButtonSceneEmulate::on_enter(iButtonApp* app) {
         break;
         break;
     }
     }
 
 
-    popup_set_icon(popup, 2, 10, I_iButtonKey_49x44);
+    popup_set_icon(popup, 2, 10, &I_iButtonKey_49x44);
 
 
     view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewPopup);
     view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewPopup);
     app->get_key_worker()->start_emulate(app->get_key());
     app->get_key_worker()->start_emulate(app->get_key());
@@ -89,5 +89,5 @@ void iButtonSceneEmulate::on_exit(iButtonApp* app) {
 
 
     popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom);
     popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom);
     popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop);
     popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop);
-    popup_set_icon(popup, 0, 0, I_Empty_1x1);
+    popup_set_icon(popup, 0, 0, NULL);
 }
 }

+ 2 - 2
applications/ibutton/scene/ibutton-scene-read-success.cpp

@@ -37,7 +37,7 @@ void iButtonSceneReadSuccess::on_enter(iButtonApp* app) {
     dialog_ex_set_text(dialog_ex, app->get_text_store(), 95, 30, AlignCenter, AlignCenter);
     dialog_ex_set_text(dialog_ex, app->get_text_store(), 95, 30, AlignCenter, AlignCenter);
     dialog_ex_set_left_button_text(dialog_ex, "Retry");
     dialog_ex_set_left_button_text(dialog_ex, "Retry");
     dialog_ex_set_right_button_text(dialog_ex, "More");
     dialog_ex_set_right_button_text(dialog_ex, "More");
-    dialog_ex_set_icon(dialog_ex, 0, 1, I_DolphinExcited_64x63);
+    dialog_ex_set_icon(dialog_ex, 0, 1, &I_DolphinExcited_64x63);
     dialog_ex_set_result_callback(dialog_ex, callback);
     dialog_ex_set_result_callback(dialog_ex, callback);
     dialog_ex_set_context(dialog_ex, app);
     dialog_ex_set_context(dialog_ex, app);
 
 
@@ -74,7 +74,7 @@ void iButtonSceneReadSuccess::on_exit(iButtonApp* app) {
     dialog_ex_set_right_button_text(dialog_ex, NULL);
     dialog_ex_set_right_button_text(dialog_ex, NULL);
     dialog_ex_set_result_callback(dialog_ex, NULL);
     dialog_ex_set_result_callback(dialog_ex, NULL);
     dialog_ex_set_context(dialog_ex, NULL);
     dialog_ex_set_context(dialog_ex, NULL);
-    dialog_ex_set_icon(dialog_ex, 0, 0, I_Empty_1x1);
+    dialog_ex_set_icon(dialog_ex, 0, 0, NULL);
 
 
     app->notify_green_off();
     app->notify_green_off();
 }
 }

+ 2 - 2
applications/ibutton/scene/ibutton-scene-read.cpp

@@ -9,7 +9,7 @@ void iButtonSceneRead::on_enter(iButtonApp* app) {
 
 
     popup_set_header(popup, "iButton", 95, 26, AlignCenter, AlignBottom);
     popup_set_header(popup, "iButton", 95, 26, AlignCenter, AlignBottom);
     popup_set_text(popup, "waiting\nfor key ...", 95, 30, AlignCenter, AlignTop);
     popup_set_text(popup, "waiting\nfor key ...", 95, 30, AlignCenter, AlignTop);
-    popup_set_icon(popup, 0, 5, I_DolphinWait_61x59);
+    popup_set_icon(popup, 0, 5, &I_DolphinWait_61x59);
 
 
     view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewPopup);
     view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewPopup);
     app->get_key()->set_name("");
     app->get_key()->set_name("");
@@ -49,5 +49,5 @@ void iButtonSceneRead::on_exit(iButtonApp* app) {
 
 
     popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom);
     popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom);
     popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop);
     popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop);
-    popup_set_icon(popup, 0, 0, I_Empty_1x1);
+    popup_set_icon(popup, 0, 0, NULL);
 }
 }

+ 2 - 2
applications/ibutton/scene/ibutton-scene-save-success.cpp

@@ -10,7 +10,7 @@ void iButtonSceneSaveSuccess::on_enter(iButtonApp* app) {
     Popup* popup = view_manager->get_popup();
     Popup* popup = view_manager->get_popup();
     auto callback = cbc::obtain_connector(this, &iButtonSceneSaveSuccess::popup_callback);
     auto callback = cbc::obtain_connector(this, &iButtonSceneSaveSuccess::popup_callback);
 
 
-    popup_set_icon(popup, 32, 5, I_DolphinNice_96x59);
+    popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59);
     popup_set_text(popup, "Saved!", 13, 22, AlignLeft, AlignBottom);
     popup_set_text(popup, "Saved!", 13, 22, AlignLeft, AlignBottom);
 
 
     popup_set_callback(popup, callback);
     popup_set_callback(popup, callback);
@@ -39,7 +39,7 @@ void iButtonSceneSaveSuccess::on_exit(iButtonApp* app) {
     Popup* popup = app->get_view_manager()->get_popup();
     Popup* popup = app->get_view_manager()->get_popup();
 
 
     popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop);
     popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop);
-    popup_set_icon(popup, 0, 0, I_Empty_1x1);
+    popup_set_icon(popup, 0, 0, NULL);
 
 
     popup_disable_timeout(popup);
     popup_disable_timeout(popup);
     popup_set_context(popup, NULL);
     popup_set_context(popup, NULL);

+ 2 - 2
applications/ibutton/scene/ibutton-scene-write-success.cpp

@@ -10,7 +10,7 @@ void iButtonSceneWriteSuccess::on_enter(iButtonApp* app) {
     Popup* popup = view_manager->get_popup();
     Popup* popup = view_manager->get_popup();
     auto callback = cbc::obtain_connector(this, &iButtonSceneWriteSuccess::popup_callback);
     auto callback = cbc::obtain_connector(this, &iButtonSceneWriteSuccess::popup_callback);
 
 
-    popup_set_icon(popup, 0, 12, I_iButtonDolphinVerySuccess_108x52);
+    popup_set_icon(popup, 0, 12, &I_iButtonDolphinVerySuccess_108x52);
     popup_set_text(popup, "Successfully written!", 44, 14, AlignLeft, AlignBottom);
     popup_set_text(popup, "Successfully written!", 44, 14, AlignLeft, AlignBottom);
 
 
     popup_set_callback(popup, callback);
     popup_set_callback(popup, callback);
@@ -40,7 +40,7 @@ void iButtonSceneWriteSuccess::on_exit(iButtonApp* app) {
     Popup* popup = app->get_view_manager()->get_popup();
     Popup* popup = app->get_view_manager()->get_popup();
 
 
     popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop);
     popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop);
-    popup_set_icon(popup, 0, 0, I_Empty_1x1);
+    popup_set_icon(popup, 0, 0, NULL);
 
 
     popup_disable_timeout(popup);
     popup_disable_timeout(popup);
     popup_set_context(popup, NULL);
     popup_set_context(popup, NULL);

+ 2 - 2
applications/ibutton/scene/ibutton-scene-write.cpp

@@ -56,7 +56,7 @@ void iButtonSceneWrite::on_enter(iButtonApp* app) {
         break;
         break;
     }
     }
 
 
-    popup_set_icon(popup, 2, 10, I_iButtonKey_49x44);
+    popup_set_icon(popup, 2, 10, &I_iButtonKey_49x44);
 
 
     view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewPopup);
     view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewPopup);
 
 
@@ -92,7 +92,7 @@ void iButtonSceneWrite::on_exit(iButtonApp* app) {
 
 
     popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom);
     popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom);
     popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop);
     popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop);
-    popup_set_icon(popup, 0, 0, I_Empty_1x1);
+    popup_set_icon(popup, 0, 0, NULL);
 
 
     app->get_key_worker()->stop_write();
     app->get_key_worker()->stop_write();
 }
 }

+ 1 - 2
applications/irda/irda_app_old.c

@@ -285,8 +285,7 @@ void irda_rx_callback(void* ctx, bool level, uint32_t duration) {
 
 
     if(message) {
     if(message) {
         event.value.rx = *message;
         event.value.rx = *message;
-        osStatus_t result = osMessageQueuePut(isr_context->event_queue, &event, 0, 0);
-        furi_assert(osOK == result);
+        furi_check(osMessageQueuePut(isr_context->event_queue, &event, 0, 0) == osOK);
     }
     }
 }
 }
 
 

+ 1 - 1
applications/irda/scene/irda-app-scene-edit-delete-done.cpp

@@ -4,7 +4,7 @@ void IrdaAppSceneEditDeleteDone::on_enter(IrdaApp* app) {
     IrdaAppViewManager* view_manager = app->get_view_manager();
     IrdaAppViewManager* view_manager = app->get_view_manager();
     Popup* popup = view_manager->get_popup();
     Popup* popup = view_manager->get_popup();
 
 
-    popup_set_icon(popup, 0, 2, I_DolphinMafia_115x62);
+    popup_set_icon(popup, 0, 2, &I_DolphinMafia_115x62);
     popup_set_text(popup, "Deleted", 83, 19, AlignLeft, AlignBottom);
     popup_set_text(popup, "Deleted", 83, 19, AlignLeft, AlignBottom);
 
 
     popup_set_callback(popup, IrdaApp::popup_callback);
     popup_set_callback(popup, IrdaApp::popup_callback);

+ 1 - 1
applications/irda/scene/irda-app-scene-edit-delete.cpp

@@ -41,7 +41,7 @@ void IrdaAppSceneEditDelete::on_enter(IrdaApp* app) {
     }
     }
 
 
     dialog_ex_set_text(dialog_ex, app->get_text_store(0), 64, 32, AlignCenter, AlignCenter);
     dialog_ex_set_text(dialog_ex, app->get_text_store(0), 64, 32, AlignCenter, AlignCenter);
-    dialog_ex_set_icon(dialog_ex, 0, 0, I_Empty_1x1);
+    dialog_ex_set_icon(dialog_ex, 0, 0, NULL);
     dialog_ex_set_left_button_text(dialog_ex, "Back");
     dialog_ex_set_left_button_text(dialog_ex, "Back");
     dialog_ex_set_right_button_text(dialog_ex, "Delete");
     dialog_ex_set_right_button_text(dialog_ex, "Delete");
     dialog_ex_set_result_callback(dialog_ex, dialog_result_callback);
     dialog_ex_set_result_callback(dialog_ex, dialog_result_callback);

+ 1 - 1
applications/irda/scene/irda-app-scene-edit-rename-done.cpp

@@ -4,7 +4,7 @@ void IrdaAppSceneEditRenameDone::on_enter(IrdaApp* app) {
     IrdaAppViewManager* view_manager = app->get_view_manager();
     IrdaAppViewManager* view_manager = app->get_view_manager();
     Popup* popup = view_manager->get_popup();
     Popup* popup = view_manager->get_popup();
 
 
-    popup_set_icon(popup, 32, 5, I_DolphinNice_96x59);
+    popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59);
 
 
     popup_set_text(popup, "Saved!", 13, 22, AlignLeft, AlignTop);
     popup_set_text(popup, "Saved!", 13, 22, AlignLeft, AlignTop);
 
 

+ 1 - 1
applications/irda/scene/irda-app-scene-learn-done-after.cpp

@@ -5,7 +5,7 @@ void IrdaAppSceneLearnDoneAfter::on_enter(IrdaApp* app) {
     auto view_manager = app->get_view_manager();
     auto view_manager = app->get_view_manager();
     auto popup = view_manager->get_popup();
     auto popup = view_manager->get_popup();
 
 
-    popup_set_icon(popup, 0, 30, I_IrdaSendShort_128x34);
+    popup_set_icon(popup, 0, 30, &I_IrdaSendShort_128x34);
     popup_set_text(
     popup_set_text(
         popup, "Get ready!\nPoint flipper at target.", 64, 16, AlignCenter, AlignCenter);
         popup, "Get ready!\nPoint flipper at target.", 64, 16, AlignCenter, AlignCenter);
 
 

+ 1 - 1
applications/irda/scene/irda-app-scene-learn-done.cpp

@@ -4,7 +4,7 @@ void IrdaAppSceneLearnDone::on_enter(IrdaApp* app) {
     IrdaAppViewManager* view_manager = app->get_view_manager();
     IrdaAppViewManager* view_manager = app->get_view_manager();
     Popup* popup = view_manager->get_popup();
     Popup* popup = view_manager->get_popup();
 
 
-    popup_set_icon(popup, 32, 5, I_DolphinNice_96x59);
+    popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59);
 
 
     if(app->get_learn_new_remote()) {
     if(app->get_learn_new_remote()) {
         popup_set_text(popup, "New remote\ncreated!", 5, 7, AlignLeft, AlignTop);
         popup_set_text(popup, "New remote\ncreated!", 5, 7, AlignLeft, AlignTop);

+ 1 - 1
applications/irda/scene/irda-app-scene-learn-success.cpp

@@ -33,7 +33,7 @@ void IrdaAppSceneLearnSuccess::on_enter(IrdaApp* app) {
     dialog_ex_set_left_button_text(dialog_ex, "Retry");
     dialog_ex_set_left_button_text(dialog_ex, "Retry");
     dialog_ex_set_right_button_text(dialog_ex, "Save");
     dialog_ex_set_right_button_text(dialog_ex, "Save");
     dialog_ex_set_center_button_text(dialog_ex, "Send");
     dialog_ex_set_center_button_text(dialog_ex, "Send");
-    dialog_ex_set_icon(dialog_ex, 0, 1, I_DolphinExcited_64x63);
+    dialog_ex_set_icon(dialog_ex, 0, 1, &I_DolphinExcited_64x63);
     dialog_ex_set_result_callback(dialog_ex, dialog_result_callback);
     dialog_ex_set_result_callback(dialog_ex, dialog_result_callback);
     dialog_ex_set_context(dialog_ex, app);
     dialog_ex_set_context(dialog_ex, app);
 
 

+ 1 - 1
applications/irda/scene/irda-app-scene-learn.cpp

@@ -9,7 +9,7 @@ void IrdaAppSceneLearn::on_enter(IrdaApp* app) {
 
 
     auto popup = view_manager->get_popup();
     auto popup = view_manager->get_popup();
 
 
-    popup_set_icon(popup, 0, 32, I_IrdaLearnShort_128x31);
+    popup_set_icon(popup, 0, 32, &I_IrdaLearnShort_128x31);
     popup_set_text(
     popup_set_text(
         popup, "Point the remote at IR port\nand push the button", 5, 10, AlignLeft, AlignCenter);
         popup, "Point the remote at IR port\nand push the button", 5, 10, AlignLeft, AlignCenter);
     popup_set_callback(popup, NULL);
     popup_set_callback(popup, NULL);

+ 35 - 8
applications/irda/scene/irda-app-scene-universal-tv.cpp

@@ -8,11 +8,29 @@ void IrdaAppSceneUniversalTV::on_enter(IrdaApp* app) {
 
 
     int i = 0;
     int i = 0;
     button_panel_add_item(
     button_panel_add_item(
-        button_panel, i, 0, 0, 3, 19, I_Power_25x27, I_Power_hvr_25x27, irda_app_item_callback, app);
+        button_panel,
+        i,
+        0,
+        0,
+        3,
+        19,
+        &I_Power_25x27,
+        &I_Power_hvr_25x27,
+        irda_app_item_callback,
+        app);
     brute_force.add_record(i, "POWER");
     brute_force.add_record(i, "POWER");
     ++i;
     ++i;
     button_panel_add_item(
     button_panel_add_item(
-        button_panel, i, 1, 0, 36, 19, I_Mute_25x27, I_Mute_hvr_25x27, irda_app_item_callback, app);
+        button_panel,
+        i,
+        1,
+        0,
+        36,
+        19,
+        &I_Mute_25x27,
+        &I_Mute_hvr_25x27,
+        irda_app_item_callback,
+        app);
     brute_force.add_record(i, "MUTE");
     brute_force.add_record(i, "MUTE");
     ++i;
     ++i;
     button_panel_add_item(
     button_panel_add_item(
@@ -22,14 +40,14 @@ void IrdaAppSceneUniversalTV::on_enter(IrdaApp* app) {
         1,
         1,
         3,
         3,
         66,
         66,
-        I_Vol_up_25x27,
-        I_Vol_up_hvr_25x27,
+        &I_Vol_up_25x27,
+        &I_Vol_up_hvr_25x27,
         irda_app_item_callback,
         irda_app_item_callback,
         app);
         app);
     brute_force.add_record(i, "VOL+");
     brute_force.add_record(i, "VOL+");
     ++i;
     ++i;
     button_panel_add_item(
     button_panel_add_item(
-        button_panel, i, 1, 1, 36, 66, I_Up_25x27, I_Up_hvr_25x27, irda_app_item_callback, app);
+        button_panel, i, 1, 1, 36, 66, &I_Up_25x27, &I_Up_hvr_25x27, irda_app_item_callback, app);
     brute_force.add_record(i, "CH+");
     brute_force.add_record(i, "CH+");
     ++i;
     ++i;
     button_panel_add_item(
     button_panel_add_item(
@@ -39,14 +57,23 @@ void IrdaAppSceneUniversalTV::on_enter(IrdaApp* app) {
         2,
         2,
         3,
         3,
         98,
         98,
-        I_Vol_down_25x27,
-        I_Vol_down_hvr_25x27,
+        &I_Vol_down_25x27,
+        &I_Vol_down_hvr_25x27,
         irda_app_item_callback,
         irda_app_item_callback,
         app);
         app);
     brute_force.add_record(i, "VOL-");
     brute_force.add_record(i, "VOL-");
     ++i;
     ++i;
     button_panel_add_item(
     button_panel_add_item(
-        button_panel, i, 1, 2, 36, 98, I_Down_25x27, I_Down_hvr_25x27, irda_app_item_callback, app);
+        button_panel,
+        i,
+        1,
+        2,
+        36,
+        98,
+        &I_Down_25x27,
+        &I_Down_hvr_25x27,
+        irda_app_item_callback,
+        app);
     brute_force.add_record(i, "CH-");
     brute_force.add_record(i, "CH-");
 
 
     button_panel_add_label(button_panel, 6, 11, FontPrimary, "TV remote");
     button_panel_add_label(button_panel, 6, 11, FontPrimary, "TV remote");

+ 1 - 1
applications/irda/view/irda-app-brut-view.c

@@ -54,7 +54,7 @@ void popup_brut_draw_callback(Canvas* canvas, void* context) {
 
 
     canvas_set_font(canvas, FontSecondary);
     canvas_set_font(canvas, FontSecondary);
     canvas_draw_str(canvas, x + 15, y + 12, "Sending ...");
     canvas_draw_str(canvas, x + 15, y + 12, "Sending ...");
-    canvas_draw_icon_name(canvas, x + 11, y_max - 14, I_Back_15x10);
+    canvas_draw_icon(canvas, x + 11, y_max - 14, &I_Back_15x10);
 
 
     uint8_t percent_value = 100 * popup_brut->progress / popup_brut->progress_max;
     uint8_t percent_value = 100 * popup_brut->progress / popup_brut->progress_max;
     snprintf(
     snprintf(

+ 1 - 1
applications/lfrfid/scene/lfrfid-app-scene-delete-success.cpp

@@ -3,7 +3,7 @@
 void LfRfidAppSceneDeleteSuccess::on_enter(LfRfidApp* app, bool need_restore) {
 void LfRfidAppSceneDeleteSuccess::on_enter(LfRfidApp* app, bool need_restore) {
     auto popup = app->view_controller.get<PopupVM>();
     auto popup = app->view_controller.get<PopupVM>();
 
 
-    popup->set_icon(0, 2, I_DolphinMafia_115x62);
+    popup->set_icon(0, 2, &I_DolphinMafia_115x62);
     popup->set_text("Deleted", 83, 19, AlignLeft, AlignBottom);
     popup->set_text("Deleted", 83, 19, AlignLeft, AlignBottom);
     popup->set_context(app);
     popup->set_context(app);
     popup->set_callback(LfRfidAppSceneDeleteSuccess::timeout_callback);
     popup->set_callback(LfRfidAppSceneDeleteSuccess::timeout_callback);

+ 1 - 1
applications/lfrfid/scene/lfrfid-app-scene-emulate.cpp

@@ -17,7 +17,7 @@ void LfRfidAppSceneEmulate::on_enter(LfRfidApp* app, bool need_restore) {
     } else {
     } else {
         popup->set_text(string_get_cstr(data_string), 89, 43, AlignCenter, AlignTop);
         popup->set_text(string_get_cstr(data_string), 89, 43, AlignCenter, AlignTop);
     }
     }
-    popup->set_icon(0, 3, I_RFIDDolphinSend_97x61);
+    popup->set_icon(0, 3, &I_RFIDDolphinSend_97x61);
 
 
     app->view_controller.switch_to<PopupVM>();
     app->view_controller.switch_to<PopupVM>();
     app->worker.start_emulate();
     app->worker.start_emulate();

+ 1 - 1
applications/lfrfid/scene/lfrfid-app-scene-read-success.cpp

@@ -19,7 +19,7 @@ void LfRfidAppSceneReadSuccess::on_enter(LfRfidApp* app, bool need_restore) {
     button->set_callback(app, LfRfidAppSceneReadSuccess::more_callback);
     button->set_callback(app, LfRfidAppSceneReadSuccess::more_callback);
 
 
     auto icon = container->add<IconElement>();
     auto icon = container->add<IconElement>();
-    icon->set_icon(3, 12, I_RFIDBigChip_37x36);
+    icon->set_icon(3, 12, &I_RFIDBigChip_37x36);
 
 
     auto header = container->add<StringElement>();
     auto header = container->add<StringElement>();
     header->set_text(app->worker.key.get_type_text(), 89, 3, AlignCenter);
     header->set_text(app->worker.key.get_type_text(), 89, 3, AlignCenter);

+ 1 - 1
applications/lfrfid/scene/lfrfid-app-scene-read.cpp

@@ -4,7 +4,7 @@ void LfRfidAppSceneRead::on_enter(LfRfidApp* app, bool need_restore) {
     auto popup = app->view_controller.get<PopupVM>();
     auto popup = app->view_controller.get<PopupVM>();
 
 
     popup->set_header("Reading\nLF RFID", 89, 34, AlignCenter, AlignTop);
     popup->set_header("Reading\nLF RFID", 89, 34, AlignCenter, AlignTop);
-    popup->set_icon(0, 3, I_RFIDDolphinReceive_97x61);
+    popup->set_icon(0, 3, &I_RFIDDolphinReceive_97x61);
 
 
     app->view_controller.switch_to<PopupVM>();
     app->view_controller.switch_to<PopupVM>();
     app->worker.start_read();
     app->worker.start_read();

+ 1 - 1
applications/lfrfid/scene/lfrfid-app-scene-save-success.cpp

@@ -3,7 +3,7 @@
 void LfRfidAppSceneSaveSuccess::on_enter(LfRfidApp* app, bool need_restore) {
 void LfRfidAppSceneSaveSuccess::on_enter(LfRfidApp* app, bool need_restore) {
     auto popup = app->view_controller.get<PopupVM>();
     auto popup = app->view_controller.get<PopupVM>();
 
 
-    popup->set_icon(32, 5, I_DolphinNice_96x59);
+    popup->set_icon(32, 5, &I_DolphinNice_96x59);
     popup->set_text("Saved!", 13, 22, AlignLeft, AlignBottom);
     popup->set_text("Saved!", 13, 22, AlignLeft, AlignBottom);
     popup->set_context(app);
     popup->set_context(app);
     popup->set_callback(LfRfidAppSceneSaveSuccess::timeout_callback);
     popup->set_callback(LfRfidAppSceneSaveSuccess::timeout_callback);

+ 1 - 1
applications/lfrfid/scene/lfrfid-app-scene-write-success.cpp

@@ -3,7 +3,7 @@
 void LfRfidAppSceneWriteSuccess::on_enter(LfRfidApp* app, bool need_restore) {
 void LfRfidAppSceneWriteSuccess::on_enter(LfRfidApp* app, bool need_restore) {
     auto popup = app->view_controller.get<PopupVM>();
     auto popup = app->view_controller.get<PopupVM>();
     popup->set_header("Successfully\nwritten!", 94, 3, AlignCenter, AlignTop);
     popup->set_header("Successfully\nwritten!", 94, 3, AlignCenter, AlignTop);
-    popup->set_icon(0, 6, I_RFIDDolphinSuccess_108x57);
+    popup->set_icon(0, 6, &I_RFIDDolphinSuccess_108x57);
     popup->set_context(app);
     popup->set_context(app);
     popup->set_callback(LfRfidAppSceneWriteSuccess::timeout_callback);
     popup->set_callback(LfRfidAppSceneWriteSuccess::timeout_callback);
     popup->set_timeout(1500);
     popup->set_timeout(1500);

+ 2 - 2
applications/lfrfid/scene/lfrfid-app-scene-write.cpp

@@ -18,7 +18,7 @@ void LfRfidAppSceneWrite::on_enter(LfRfidApp* app, bool need_restore) {
     } else {
     } else {
         popup->set_text(string_get_cstr(data_string), 89, 43, AlignCenter, AlignTop);
         popup->set_text(string_get_cstr(data_string), 89, 43, AlignCenter, AlignTop);
     }
     }
-    popup->set_icon(0, 3, I_RFIDDolphinSend_97x61);
+    popup->set_icon(0, 3, &I_RFIDDolphinSend_97x61);
 
 
     app->view_controller.switch_to<PopupVM>();
     app->view_controller.switch_to<PopupVM>();
     app->worker.start_write();
     app->worker.start_write();
@@ -41,7 +41,7 @@ bool LfRfidAppSceneWrite::on_event(LfRfidApp* app, LfRfidApp::Event* event) {
         case RfidWorker::WriteResult::NotWritable:
         case RfidWorker::WriteResult::NotWritable:
             if(!card_not_supported) {
             if(!card_not_supported) {
                 auto popup = app->view_controller.get<PopupVM>();
                 auto popup = app->view_controller.get<PopupVM>();
-                popup->set_icon(0, 0, I_Empty_1x1);
+                popup->set_icon(0, 0, NULL);
                 popup->set_header("Still trying to write", 64, 7, AlignCenter, AlignTop);
                 popup->set_header("Still trying to write", 64, 7, AlignCenter, AlignTop);
                 popup->set_text(
                 popup->set_text(
                     "This card may be protected\nor does not support this\ntype of writing",
                     "This card may be protected\nor does not support this\ntype of writing",

+ 4 - 4
applications/lfrfid/view/elements/icon-element.cpp

@@ -7,8 +7,8 @@ IconElement::~IconElement() {
 }
 }
 
 
 void IconElement::draw(Canvas* canvas) {
 void IconElement::draw(Canvas* canvas) {
-    if(name != I_Empty_1x1) {
-        canvas_draw_icon_name(canvas, x, y, name);
+    if(icon != NULL) {
+        canvas_draw_icon(canvas, x, y, icon);
     }
     }
 }
 }
 
 
@@ -16,9 +16,9 @@ bool IconElement::input(InputEvent* event) {
     return false;
     return false;
 }
 }
 
 
-void IconElement::set_icon(uint8_t _x, uint8_t _y, IconName _name) {
+void IconElement::set_icon(uint8_t _x, uint8_t _y, const Icon* _icon) {
     lock_model();
     lock_model();
-    name = _name;
+    icon = _icon;
     x = _x;
     x = _x;
     y = _y;
     y = _y;
     unlock_model(true);
     unlock_model(true);

+ 2 - 2
applications/lfrfid/view/elements/icon-element.h

@@ -8,10 +8,10 @@ public:
     void draw(Canvas* canvas) final;
     void draw(Canvas* canvas) final;
     bool input(InputEvent* event) final;
     bool input(InputEvent* event) final;
 
 
-    void set_icon(uint8_t x = 0, uint8_t y = 0, IconName name = I_Empty_1x1);
+    void set_icon(uint8_t x = 0, uint8_t y = 0, const Icon* icon = NULL);
 
 
 private:
 private:
-    IconName name = I_Empty_1x1;
+    const Icon* icon = NULL;
     uint8_t x = 0;
     uint8_t x = 0;
     uint8_t y = 0;
     uint8_t y = 0;
 };
 };

+ 7 - 7
applications/menu/menu.c

@@ -16,7 +16,7 @@ struct Menu {
     // GUI
     // GUI
     Gui* gui;
     Gui* gui;
     ViewPort* view_port;
     ViewPort* view_port;
-    Icon* icon;
+    IconAnimation* icon;
 
 
     // State
     // State
     MenuItem* root;
     MenuItem* root;
@@ -79,19 +79,19 @@ void menu_draw_primary(Menu* menu, Canvas* canvas) {
         canvas_set_font(canvas, FontSecondary);
         canvas_set_font(canvas, FontSecondary);
         shift_position = (0 + position + items_count - 1) % (MenuItemArray_size(*items));
         shift_position = (0 + position + items_count - 1) % (MenuItemArray_size(*items));
         item = *MenuItemArray_get(*items, shift_position);
         item = *MenuItemArray_get(*items, shift_position);
-        canvas_draw_icon(canvas, 4, 3, menu_item_get_icon(item));
+        canvas_draw_icon_animation(canvas, 4, 3, menu_item_get_icon(item));
         canvas_draw_str(canvas, 22, 14, menu_item_get_label(item));
         canvas_draw_str(canvas, 22, 14, menu_item_get_label(item));
         // Second line main
         // Second line main
         canvas_set_font(canvas, FontPrimary);
         canvas_set_font(canvas, FontPrimary);
         shift_position = (1 + position + items_count - 1) % (MenuItemArray_size(*items));
         shift_position = (1 + position + items_count - 1) % (MenuItemArray_size(*items));
         item = *MenuItemArray_get(*items, shift_position);
         item = *MenuItemArray_get(*items, shift_position);
-        canvas_draw_icon(canvas, 4, 25, menu_item_get_icon(item));
+        canvas_draw_icon_animation(canvas, 4, 25, menu_item_get_icon(item));
         canvas_draw_str(canvas, 22, 36, menu_item_get_label(item));
         canvas_draw_str(canvas, 22, 36, menu_item_get_label(item));
         // Third line
         // Third line
         canvas_set_font(canvas, FontSecondary);
         canvas_set_font(canvas, FontSecondary);
         shift_position = (2 + position + items_count - 1) % (MenuItemArray_size(*items));
         shift_position = (2 + position + items_count - 1) % (MenuItemArray_size(*items));
         item = *MenuItemArray_get(*items, shift_position);
         item = *MenuItemArray_get(*items, shift_position);
-        canvas_draw_icon(canvas, 4, 47, menu_item_get_icon(item));
+        canvas_draw_icon_animation(canvas, 4, 47, menu_item_get_icon(item));
         canvas_draw_str(canvas, 22, 58, menu_item_get_label(item));
         canvas_draw_str(canvas, 22, 58, menu_item_get_label(item));
         // Frame and scrollbar
         // Frame and scrollbar
         // elements_frame(canvas, 0, 0, 128 - 5, 21);
         // elements_frame(canvas, 0, 0, 128 - 5, 21);
@@ -163,17 +163,17 @@ void menu_view_port_callback(Canvas* canvas, void* context) {
     release_mutex((ValueMutex*)context, menu);
     release_mutex((ValueMutex*)context, menu);
 }
 }
 
 
-void menu_set_icon(Menu* menu, Icon* icon) {
+void menu_set_icon(Menu* menu, IconAnimation* icon) {
     furi_assert(menu);
     furi_assert(menu);
 
 
     if(menu->icon) {
     if(menu->icon) {
-        icon_stop_animation(menu->icon);
+        icon_animation_stop(menu->icon);
     }
     }
 
 
     menu->icon = icon;
     menu->icon = icon;
 
 
     if(menu->icon) {
     if(menu->icon) {
-        icon_start_animation(menu->icon);
+        icon_animation_start(menu->icon);
     }
     }
 }
 }
 
 

+ 5 - 5
applications/menu/menu_item.c

@@ -7,7 +7,7 @@ struct MenuItem {
     MenuItemType type;
     MenuItemType type;
 
 
     const char* label;
     const char* label;
-    Icon* icon;
+    IconAnimation* icon;
 
 
     size_t position;
     size_t position;
     size_t window_position;
     size_t window_position;
@@ -24,7 +24,7 @@ MenuItem* menu_item_alloc() {
     return menu_item;
     return menu_item;
 }
 }
 
 
-MenuItem* menu_item_alloc_menu(const char* label, Icon* icon) {
+MenuItem* menu_item_alloc_menu(const char* label, IconAnimation* icon) {
     MenuItem* menu_item = menu_item_alloc();
     MenuItem* menu_item = menu_item_alloc();
 
 
     menu_item->type = MenuItemTypeMenu;
     menu_item->type = MenuItemTypeMenu;
@@ -40,7 +40,7 @@ MenuItem* menu_item_alloc_menu(const char* label, Icon* icon) {
 
 
 MenuItem* menu_item_alloc_function(
 MenuItem* menu_item_alloc_function(
     const char* label,
     const char* label,
-    Icon* icon,
+    IconAnimation* icon,
     MenuItemCallback callback,
     MenuItemCallback callback,
     void* context) {
     void* context) {
     MenuItem* menu_item = menu_item_alloc();
     MenuItem* menu_item = menu_item_alloc();
@@ -112,12 +112,12 @@ const char* menu_item_get_label(MenuItem* menu_item) {
     return menu_item->label;
     return menu_item->label;
 }
 }
 
 
-void menu_item_set_icon(MenuItem* menu_item, Icon* icon) {
+void menu_item_set_icon(MenuItem* menu_item, IconAnimation* icon) {
     furi_assert(menu_item);
     furi_assert(menu_item);
     menu_item->icon = icon;
     menu_item->icon = icon;
 }
 }
 
 
-Icon* menu_item_get_icon(MenuItem* menu_item) {
+IconAnimation* menu_item_get_icon(MenuItem* menu_item) {
     furi_assert(menu_item);
     furi_assert(menu_item);
     return menu_item->icon;
     return menu_item->icon;
 }
 }

+ 5 - 5
applications/menu/menu_item.h

@@ -2,7 +2,7 @@
 
 
 #include <stdint.h>
 #include <stdint.h>
 #include <m-array.h>
 #include <m-array.h>
-#include <gui/icon.h>
+#include <gui/icon_animation.h>
 
 
 typedef enum {
 typedef enum {
     MenuItemTypeMenu = 0x00,
     MenuItemTypeMenu = 0x00,
@@ -14,11 +14,11 @@ typedef void (*MenuItemCallback)(void* context);
 
 
 ARRAY_DEF(MenuItemArray, MenuItem*, M_PTR_OPLIST);
 ARRAY_DEF(MenuItemArray, MenuItem*, M_PTR_OPLIST);
 
 
-MenuItem* menu_item_alloc_menu(const char* label, Icon* icon);
+MenuItem* menu_item_alloc_menu(const char* label, IconAnimation* icon);
 
 
 MenuItem* menu_item_alloc_function(
 MenuItem* menu_item_alloc_function(
     const char* label,
     const char* label,
-    Icon* icon,
+    IconAnimation* icon,
     MenuItemCallback callback,
     MenuItemCallback callback,
     void* context);
     void* context);
 
 
@@ -39,8 +39,8 @@ size_t menu_item_get_window_position(MenuItem* menu_item);
 void menu_item_set_label(MenuItem* menu_item, const char* label);
 void menu_item_set_label(MenuItem* menu_item, const char* label);
 const char* menu_item_get_label(MenuItem* menu_item);
 const char* menu_item_get_label(MenuItem* menu_item);
 
 
-void menu_item_set_icon(MenuItem* menu_item, Icon* icon);
-Icon* menu_item_get_icon(MenuItem* menu_item);
+void menu_item_set_icon(MenuItem* menu_item, IconAnimation* icon);
+IconAnimation* menu_item_get_icon(MenuItem* menu_item);
 
 
 MenuItemArray_t* menu_item_get_subitems(MenuItem* menu_item);
 MenuItemArray_t* menu_item_get_subitems(MenuItem* menu_item);
 
 

+ 2 - 2
applications/nfc/scenes/nfc_scene_emulate_uid.c

@@ -29,7 +29,7 @@ const void nfc_scene_emulate_uid_on_enter(void* context) {
             data->uid[6]);
             data->uid[6]);
     }
     }
 
 
-    popup_set_icon(popup, 0, 3, I_RFIDDolphinSend_97x61);
+    popup_set_icon(popup, 0, 3, &I_RFIDDolphinSend_97x61);
     popup_set_header(popup, "Emulating UID", 56, 31, AlignLeft, AlignTop);
     popup_set_header(popup, "Emulating UID", 56, 31, AlignLeft, AlignTop);
     popup_set_text(popup, nfc->text_store, 56, 43, AlignLeft, AlignTop);
     popup_set_text(popup, nfc->text_store, 56, 43, AlignLeft, AlignTop);
 
 
@@ -55,7 +55,7 @@ const void nfc_scene_emulate_uid_on_exit(void* context) {
     Popup* popup = nfc->popup;
     Popup* popup = nfc->popup;
     popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom);
     popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom);
     popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop);
     popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop);
-    popup_set_icon(popup, 0, 0, I_Empty_1x1);
+    popup_set_icon(popup, 0, 0, NULL);
 }
 }
 
 
 AppScene* nfc_scene_emulate_uid_alloc() {
 AppScene* nfc_scene_emulate_uid_alloc() {

+ 2 - 2
applications/nfc/scenes/nfc_scene_read_card.c

@@ -18,7 +18,7 @@ const void nfc_scene_read_card_on_enter(void* context) {
     // Setup view
     // Setup view
     Popup* popup = nfc->popup;
     Popup* popup = nfc->popup;
     popup_set_header(popup, "Detecting\nNFC card", 70, 34, AlignLeft, AlignTop);
     popup_set_header(popup, "Detecting\nNFC card", 70, 34, AlignLeft, AlignTop);
-    popup_set_icon(popup, 0, 3, I_RFIDDolphinReceive_97x61);
+    popup_set_icon(popup, 0, 3, &I_RFIDDolphinReceive_97x61);
 
 
     // Start worker
     // Start worker
     nfc_worker_start(
     nfc_worker_start(
@@ -53,7 +53,7 @@ const void nfc_scene_read_card_on_exit(void* context) {
     Popup* popup = nfc->popup;
     Popup* popup = nfc->popup;
     popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom);
     popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom);
     popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop);
     popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop);
-    popup_set_icon(popup, 0, 0, I_Empty_1x1);
+    popup_set_icon(popup, 0, 0, NULL);
 }
 }
 
 
 AppScene* nfc_scene_read_card_alloc() {
 AppScene* nfc_scene_read_card_alloc() {

+ 2 - 2
applications/nfc/scenes/nfc_scene_read_card_success.c

@@ -28,7 +28,7 @@ const void nfc_scene_read_card_success_on_enter(void* context) {
     dialog_ex_set_left_button_text(dialog_ex, "Retry");
     dialog_ex_set_left_button_text(dialog_ex, "Retry");
     dialog_ex_set_right_button_text(dialog_ex, "More");
     dialog_ex_set_right_button_text(dialog_ex, "More");
     dialog_ex_set_header(dialog_ex, nfc_get_dev_type(data->device), 36, 8, AlignLeft, AlignCenter);
     dialog_ex_set_header(dialog_ex, nfc_get_dev_type(data->device), 36, 8, AlignLeft, AlignCenter);
-    dialog_ex_set_icon(dialog_ex, 8, 13, I_Medium_chip_22x21);
+    dialog_ex_set_icon(dialog_ex, 8, 13, &I_Medium_chip_22x21);
     // Display UID
     // Display UID
     if(data->uid_len == 4) {
     if(data->uid_len == 4) {
         nfc_set_text_store(
         nfc_set_text_store(
@@ -90,7 +90,7 @@ const void nfc_scene_read_card_success_on_exit(void* context) {
     DialogEx* dialog_ex = nfc->dialog_ex;
     DialogEx* dialog_ex = nfc->dialog_ex;
     dialog_ex_set_header(dialog_ex, NULL, 0, 0, AlignCenter, AlignCenter);
     dialog_ex_set_header(dialog_ex, NULL, 0, 0, AlignCenter, AlignCenter);
     dialog_ex_set_text(dialog_ex, NULL, 0, 0, AlignCenter, AlignTop);
     dialog_ex_set_text(dialog_ex, NULL, 0, 0, AlignCenter, AlignTop);
-    dialog_ex_set_icon(dialog_ex, 0, 0, I_Empty_1x1);
+    dialog_ex_set_icon(dialog_ex, 0, 0, NULL);
     dialog_ex_set_left_button_text(dialog_ex, NULL);
     dialog_ex_set_left_button_text(dialog_ex, NULL);
     dialog_ex_set_right_button_text(dialog_ex, NULL);
     dialog_ex_set_right_button_text(dialog_ex, NULL);
     dialog_ex_set_result_callback(dialog_ex, NULL);
     dialog_ex_set_result_callback(dialog_ex, NULL);

+ 2 - 2
applications/nfc/scenes/nfc_scene_save_success.c

@@ -17,7 +17,7 @@ const void nfc_scene_save_success_on_enter(void* context) {
 
 
     // Setup view
     // Setup view
     Popup* popup = nfc->popup;
     Popup* popup = nfc->popup;
-    popup_set_icon(popup, 32, 5, I_DolphinNice_96x59);
+    popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59);
     popup_set_header(popup, "Saved!", 13, 22, AlignLeft, AlignBottom);
     popup_set_header(popup, "Saved!", 13, 22, AlignLeft, AlignBottom);
     popup_set_timeout(popup, 1500);
     popup_set_timeout(popup, 1500);
     popup_set_context(popup, nfc);
     popup_set_context(popup, nfc);
@@ -44,7 +44,7 @@ const void nfc_scene_save_success_on_exit(void* context) {
     Popup* popup = nfc->popup;
     Popup* popup = nfc->popup;
     popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom);
     popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom);
     popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop);
     popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop);
-    popup_set_icon(popup, 0, 0, I_Empty_1x1);
+    popup_set_icon(popup, 0, 0, NULL);
     popup_set_callback(popup, NULL);
     popup_set_callback(popup, NULL);
     popup_set_context(popup, NULL);
     popup_set_context(popup, NULL);
     popup_set_timeout(popup, 0);
     popup_set_timeout(popup, 0);

+ 4 - 5
applications/power/power.c

@@ -9,6 +9,7 @@
 #include <menu/menu_item.h>
 #include <menu/menu_item.h>
 
 
 #include <gui/gui.h>
 #include <gui/gui.h>
+#include <gui/icon_animation.h>
 #include <gui/view_port.h>
 #include <gui/view_port.h>
 #include <gui/view.h>
 #include <gui/view.h>
 #include <gui/view_dispatcher.h>
 #include <gui/view_dispatcher.h>
@@ -32,7 +33,6 @@ struct Power {
     View* off_view;
     View* off_view;
     View* disconnect_view;
     View* disconnect_view;
 
 
-    Icon* battery_icon;
     ViewPort* battery_view_port;
     ViewPort* battery_view_port;
 
 
     Dialog* dialog;
     Dialog* dialog;
@@ -47,7 +47,7 @@ struct Power {
 void power_draw_battery_callback(Canvas* canvas, void* context) {
 void power_draw_battery_callback(Canvas* canvas, void* context) {
     furi_assert(context);
     furi_assert(context);
     Power* power = context;
     Power* power = context;
-    canvas_draw_icon(canvas, 0, 0, power->battery_icon);
+    canvas_draw_icon(canvas, 0, 0, &I_Battery_26x8);
     with_view_model(
     with_view_model(
         power->info_view, (PowerInfoModel * model) {
         power->info_view, (PowerInfoModel * model) {
             canvas_draw_box(canvas, 2, 2, (float)model->charge / 100 * 20, 4);
             canvas_draw_box(canvas, 2, 2, (float)model->charge / 100 * 20, 4);
@@ -108,7 +108,7 @@ Power* power_alloc() {
     power->cli = furi_record_open("cli");
     power->cli = furi_record_open("cli");
     power_cli_init(power->cli, power);
     power_cli_init(power->cli, power);
 
 
-    power->menu = menu_item_alloc_menu("Power", assets_icons_get(A_Power_14));
+    power->menu = menu_item_alloc_menu("Power", icon_animation_alloc(&A_Power_14));
     menu_item_subitem_add(
     menu_item_subitem_add(
         power->menu, menu_item_alloc_function("Off", NULL, power_menu_off_callback, power));
         power->menu, menu_item_alloc_function("Off", NULL, power_menu_off_callback, power));
     menu_item_subitem_add(
     menu_item_subitem_add(
@@ -143,10 +143,9 @@ Power* power_alloc() {
     view_dispatcher_add_view(
     view_dispatcher_add_view(
         power->view_dispatcher, PowerViewDialog, dialog_get_view(power->dialog));
         power->view_dispatcher, PowerViewDialog, dialog_get_view(power->dialog));
 
 
-    power->battery_icon = assets_icons_get(I_Battery_26x8);
     power->battery_view_port = view_port_alloc();
     power->battery_view_port = view_port_alloc();
 
 
-    view_port_set_width(power->battery_view_port, icon_get_width(power->battery_icon));
+    view_port_set_width(power->battery_view_port, icon_get_width(&I_Battery_26x8));
     view_port_draw_callback_set(power->battery_view_port, power_draw_battery_callback, power);
     view_port_draw_callback_set(power->battery_view_port, power_draw_battery_callback, power);
     return power;
     return power;
 }
 }

+ 11 - 11
applications/power/power_views.c

@@ -1,9 +1,9 @@
 #include "power_views.h"
 #include "power_views.h"
 #include <gui/elements.h>
 #include <gui/elements.h>
 
 
-static void draw_stat(Canvas* canvas, int x, int y, IconName icon, char* val) {
+static void draw_stat(Canvas* canvas, int x, int y, const Icon* icon, char* val) {
     canvas_draw_frame(canvas, x - 7, y + 7, 30, 13);
     canvas_draw_frame(canvas, x - 7, y + 7, 30, 13);
-    canvas_draw_icon_name(canvas, x, y, icon);
+    canvas_draw_icon(canvas, x, y, icon);
     canvas_set_color(canvas, ColorWhite);
     canvas_set_color(canvas, ColorWhite);
     canvas_draw_box(canvas, x - 4, y + 16, 24, 6);
     canvas_draw_box(canvas, x - 4, y + 16, 24, 6);
     canvas_set_color(canvas, ColorBlack);
     canvas_set_color(canvas, ColorBlack);
@@ -18,15 +18,15 @@ static void draw_battery(Canvas* canvas, PowerInfoModel* data, int x, int y) {
     int32_t drain_current = -data->current_gauge * 1000;
     int32_t drain_current = -data->current_gauge * 1000;
     uint32_t charge_current = data->current_gauge * 1000;
     uint32_t charge_current = data->current_gauge * 1000;
     // battery
     // battery
-    canvas_draw_icon_name(canvas, x, y, I_BatteryBody_52x28);
+    canvas_draw_icon(canvas, x, y, &I_BatteryBody_52x28);
     if(charge_current > 0) {
     if(charge_current > 0) {
-        canvas_draw_icon_name(canvas, x + 16, y + 7, I_FaceCharging_29x14);
+        canvas_draw_icon(canvas, x + 16, y + 7, &I_FaceCharging_29x14);
     } else if(drain_current > 100) {
     } else if(drain_current > 100) {
-        canvas_draw_icon_name(canvas, x + 16, y + 7, I_FaceConfused_29x14);
+        canvas_draw_icon(canvas, x + 16, y + 7, &I_FaceConfused_29x14);
     } else if(data->charge < 10) {
     } else if(data->charge < 10) {
-        canvas_draw_icon_name(canvas, x + 16, y + 7, I_FaceNopower_29x14);
+        canvas_draw_icon(canvas, x + 16, y + 7, &I_FaceNopower_29x14);
     } else {
     } else {
-        canvas_draw_icon_name(canvas, x + 16, y + 7, I_FaceNormal_29x14);
+        canvas_draw_icon(canvas, x + 16, y + 7, &I_FaceNormal_29x14);
     }
     }
 
 
     //bubble
     //bubble
@@ -99,10 +99,10 @@ void power_info_draw_callback(Canvas* canvas, void* context) {
         (uint32_t)(data->voltage_gauge * 10) % 10);
         (uint32_t)(data->voltage_gauge * 10) % 10);
     snprintf(health, sizeof(health), "%d%s", data->health, "%");
     snprintf(health, sizeof(health), "%d%s", data->health, "%");
 
 
-    draw_stat(canvas, 8, 42, I_Battery_16x16, batt_level);
-    draw_stat(canvas, 40, 42, I_Temperature_16x16, temperature);
-    draw_stat(canvas, 72, 42, I_Voltage_16x16, voltage);
-    draw_stat(canvas, 104, 42, I_Health_16x16, health);
+    draw_stat(canvas, 8, 42, &I_Battery_16x16, batt_level);
+    draw_stat(canvas, 40, 42, &I_Temperature_16x16, temperature);
+    draw_stat(canvas, 72, 42, &I_Voltage_16x16, voltage);
+    draw_stat(canvas, 104, 42, &I_Health_16x16, health);
 }
 }
 
 
 void power_off_draw_callback(Canvas* canvas, void* context) {
 void power_off_draw_callback(Canvas* canvas, void* context) {

+ 6 - 6
applications/sd-filesystem/sd-filesystem.c

@@ -118,8 +118,8 @@ SdApp* sd_app_alloc() {
 
 
     // init icon view_port
     // init icon view_port
     sd_app->icon.view_port = view_port_alloc();
     sd_app->icon.view_port = view_port_alloc();
-    sd_app->icon.mounted = assets_icons_get(I_SDcardMounted_11x8);
-    sd_app->icon.fail = assets_icons_get(I_SDcardFail_11x8);
+    sd_app->icon.mounted = &I_SDcardMounted_11x8;
+    sd_app->icon.fail = &I_SDcardFail_11x8;
     view_port_set_width(sd_app->icon.view_port, icon_get_width(sd_app->icon.mounted));
     view_port_set_width(sd_app->icon.view_port, icon_get_width(sd_app->icon.mounted));
     view_port_draw_callback_set(sd_app->icon.view_port, sd_icon_draw_callback, sd_app);
     view_port_draw_callback_set(sd_app->icon.view_port, sd_icon_draw_callback, sd_app);
     view_port_enabled_set(sd_app->icon.view_port, false);
     view_port_enabled_set(sd_app->icon.view_port, false);
@@ -657,7 +657,7 @@ int32_t sd_filesystem(void* p) {
     // init menu
     // init menu
     // TODO menu icon
     // TODO menu icon
     MenuItem* menu_item;
     MenuItem* menu_item;
-    menu_item = menu_item_alloc_menu("SD Card", assets_icons_get(I_SDcardMounted_11x8));
+    menu_item = menu_item_alloc_menu("SD Card", icon_animation_alloc(&I_SDcardMounted_11x8));
 
 
     menu_item_subitem_add(
     menu_item_subitem_add(
         menu_item, menu_item_alloc_function("Info", NULL, app_sd_info_callback, sd_app));
         menu_item, menu_item_alloc_function("Info", NULL, app_sd_info_callback, sd_app));
@@ -921,11 +921,11 @@ int32_t sd_filesystem(void* p) {
                                 y_1_line,
                                 y_1_line,
                                 AlignCenter,
                                 AlignCenter,
                                 AlignCenter);
                                 AlignCenter);
-                            dialog_ex_set_icon(dialog, 5, 6, I_SDQuestion_35x43);
+                            dialog_ex_set_icon(dialog, 5, 6, &I_SDQuestion_35x43);
                         } else {
                         } else {
                             dialog_ex_set_text(
                             dialog_ex_set_text(
                                 dialog, "SD card\nerror", 88, y_1_line, AlignCenter, AlignCenter);
                                 dialog, "SD card\nerror", 88, y_1_line, AlignCenter, AlignCenter);
-                            dialog_ex_set_icon(dialog, 5, 10, I_SDError_43x35);
+                            dialog_ex_set_icon(dialog, 5, 10, &I_SDError_43x35);
                         }
                         }
                         sd_app->sd_app_state = SdAppStateCheckError;
                         sd_app->sd_app_state = SdAppStateCheckError;
                         view_holder_start(sd_app->view_holder);
                         view_holder_start(sd_app->view_holder);
@@ -938,7 +938,7 @@ int32_t sd_filesystem(void* p) {
                     dialog_ex_set_left_button_text(dialog, "Back");
                     dialog_ex_set_left_button_text(dialog, "Back");
                     dialog_ex_set_text(
                     dialog_ex_set_text(
                         dialog, event.payload.error_text, 88, y_1_line, AlignCenter, AlignCenter);
                         dialog, event.payload.error_text, 88, y_1_line, AlignCenter, AlignCenter);
-                    dialog_ex_set_icon(dialog, 5, 6, I_SDQuestion_35x43);
+                    dialog_ex_set_icon(dialog, 5, 6, &I_SDQuestion_35x43);
                     sd_app->sd_app_state = SdAppStateShowError;
                     sd_app->sd_app_state = SdAppStateShowError;
                     view_holder_start(sd_app->view_holder);
                     view_holder_start(sd_app->view_holder);
                 }
                 }

+ 2 - 2
applications/sd-filesystem/sd-filesystem.h

@@ -65,8 +65,8 @@ typedef struct {
 /* application data */
 /* application data */
 typedef struct {
 typedef struct {
     ViewPort* view_port;
     ViewPort* view_port;
-    Icon* mounted;
-    Icon* fail;
+    const Icon* mounted;
+    const Icon* fail;
 } SdFsIcon;
 } SdFsIcon;
 
 
 typedef struct {
 typedef struct {

Разница между файлами не показана из-за своего большого размера
+ 2 - 1
assets/compiled/assets_icons.c


+ 143 - 149
assets/compiled/assets_icons.h

@@ -1,152 +1,146 @@
 #pragma once
 #pragma once
-
 #include <gui/icon.h>
 #include <gui/icon.h>
 
 
-typedef enum {
-	A_FX_Sitting_40x27,
-	A_MDIB_32x32,
-	A_MDI_32x32,
-	A_MDWLB_32x32,
-	A_MDWL_32x32,
-	A_MDWRB_32x32,
-	A_MDWR_32x32,
-	A_WatchingTV_128x64,
-	A_Wink_128x64,
-	I_125_10px,
-	I_ble_10px,
-	I_dir_10px,
-	I_ibutt_10px,
-	I_ir_10px,
-	I_Nfc_10px,
-	I_sub1_10px,
-	I_unknown_10px,
-	I_ButtonCenter_7x7,
-	I_ButtonLeftSmall_3x5,
-	I_ButtonLeft_4x7,
-	I_ButtonRightSmall_3x5,
-	I_ButtonRight_4x7,
-	I_Empty_1x1,
-	I_BigBurger_24x24,
-	I_BigGames_24x24,
-	I_BigProfile_24x24,
-	I_DolphinFirstStart0_70x53,
-	I_DolphinFirstStart1_59x53,
-	I_DolphinFirstStart2_59x51,
-	I_DolphinFirstStart3_57x48,
-	I_DolphinFirstStart4_67x53,
-	I_DolphinFirstStart5_45x53,
-	I_DolphinFirstStart6_58x54,
-	I_DolphinFirstStart7_61x51,
-	I_DolphinFirstStart8_56x51,
-	I_DolphinOkay_41x43,
-	I_Flipper_young_80x60,
-	I_FX_Bang_32x6,
-	I_FX_SittingB_40x27,
-	I_DolphinExcited_64x63,
-	I_DolphinMafia_115x62,
-	I_DolphinNice_96x59,
-	I_DolphinWait_61x59,
-	I_iButtonDolphinSuccess_109x60,
-	I_iButtonDolphinVerySuccess_108x52,
-	I_iButtonKey_49x44,
-	I_DoorLeft_70x55,
-	I_DoorLeft_8x56,
-	I_DoorLocked_10x56,
-	I_DoorRight_70x55,
-	I_DoorRight_8x56,
-	I_LockPopup_100x49,
-	I_PassportBottom_128x17,
-	I_PassportLeft_6x47,
-	I_Back_15x10,
-	I_Down_25x27,
-	I_Down_hvr_25x27,
-	I_Fill_marker_7x7,
-	I_IrdaArrowDown_4x8,
-	I_IrdaArrowUp_4x8,
-	I_IrdaLearnShort_128x31,
-	I_IrdaLearn_128x64,
-	I_IrdaSendShort_128x34,
-	I_IrdaSend_128x64,
-	I_Mute_25x27,
-	I_Mute_hvr_25x27,
-	I_Power_25x27,
-	I_Power_hvr_25x27,
-	I_Up_25x27,
-	I_Up_hvr_25x27,
-	I_Vol_down_25x27,
-	I_Vol_down_hvr_25x27,
-	I_Vol_up_25x27,
-	I_Vol_up_hvr_25x27,
-	I_KeyBackspaceSelected_16x9,
-	I_KeyBackspace_16x9,
-	I_KeySaveSelected_24x11,
-	I_KeySave_24x11,
-	A_125khz_14,
-	A_Bluetooth_14,
-	A_FileManager_14,
-	A_Games_14,
-	A_GPIO_14,
-	A_iButton_14,
-	A_Infrared_14,
-	A_NFC_14,
-	A_Passport_14,
-	A_Plugins_14,
-	A_Power_14,
-	A_Settings_14,
-	A_Sub1ghz_14,
-	A_Tamagotchi_14,
-	A_U2F_14,
-	I_EMV_Chip_14x11,
-	I_Medium_chip_22x21,
-	I_passport_bad1_43x45,
-	I_passport_bad2_43x45,
-	I_passport_bad3_43x45,
-	I_passport_happy1_43x45,
-	I_passport_happy2_43x45,
-	I_passport_happy3_43x45,
-	I_passport_okay1_43x45,
-	I_passport_okay2_43x45,
-	I_passport_okay3_43x45,
-	I_BatteryBody_52x28,
-	I_Battery_16x16,
-	I_FaceCharging_29x14,
-	I_FaceConfused_29x14,
-	I_FaceNopower_29x14,
-	I_FaceNormal_29x14,
-	I_Health_16x16,
-	I_Temperature_16x16,
-	I_Voltage_16x16,
-	I_RFIDBigChip_37x36,
-	I_RFIDDolphinReceive_97x61,
-	I_RFIDDolphinSend_97x61,
-	I_RFIDDolphinSuccess_108x57,
-	I_Home_painting_17x20,
-	I_PC_22x29,
-	I_Sofa_40x13,
-	I_TV_20x20,
-	I_TV_20x24,
-	I_WalkL1_32x32,
-	I_WalkL2_32x32,
-	I_WalkLB1_32x32,
-	I_WalkLB2_32x32,
-	I_WalkR1_32x32,
-	I_WalkR2_32x32,
-	I_WalkRB1_32x32,
-	I_WalkRB2_32x32,
-	I_SDError_43x35,
-	I_SDQuestion_35x43,
-	I_Background_128x11,
-	I_Background_128x8,
-	I_BadUsb_9x8,
-	I_Battery_19x8,
-	I_Battery_26x8,
-	I_Bluetooth_5x8,
-	I_Lock_8x8,
-	I_PlaceholderL_11x13,
-	I_PlaceholderR_30x13,
-	I_SDcardFail_11x8,
-	I_SDcardMounted_11x8,
-	I_USBConnected_15x8,
-} IconName;
-
-Icon * assets_icons_get(IconName name);
+extern const Icon A_FX_Sitting_40x27;
+extern const Icon A_MDIB_32x32;
+extern const Icon A_MDI_32x32;
+extern const Icon A_MDWLB_32x32;
+extern const Icon A_MDWL_32x32;
+extern const Icon A_MDWRB_32x32;
+extern const Icon A_MDWR_32x32;
+extern const Icon A_WatchingTV_128x64;
+extern const Icon A_Wink_128x64;
+extern const Icon I_dir_10px;
+extern const Icon I_Nfc_10px;
+extern const Icon I_sub1_10px;
+extern const Icon I_ir_10px;
+extern const Icon I_ibutt_10px;
+extern const Icon I_unknown_10px;
+extern const Icon I_ble_10px;
+extern const Icon I_125_10px;
+extern const Icon I_ButtonRightSmall_3x5;
+extern const Icon I_ButtonLeft_4x7;
+extern const Icon I_ButtonLeftSmall_3x5;
+extern const Icon I_ButtonRight_4x7;
+extern const Icon I_ButtonCenter_7x7;
+extern const Icon I_FX_SittingB_40x27;
+extern const Icon I_BigGames_24x24;
+extern const Icon I_BigProfile_24x24;
+extern const Icon I_DolphinOkay_41x43;
+extern const Icon I_DolphinFirstStart5_45x53;
+extern const Icon I_DolphinFirstStart4_67x53;
+extern const Icon I_DolphinFirstStart2_59x51;
+extern const Icon I_DolphinFirstStart0_70x53;
+extern const Icon I_DolphinFirstStart6_58x54;
+extern const Icon I_DolphinFirstStart1_59x53;
+extern const Icon I_DolphinFirstStart8_56x51;
+extern const Icon I_DolphinFirstStart7_61x51;
+extern const Icon I_Flipper_young_80x60;
+extern const Icon I_BigBurger_24x24;
+extern const Icon I_FX_Bang_32x6;
+extern const Icon I_DolphinFirstStart3_57x48;
+extern const Icon I_PassportBottom_128x17;
+extern const Icon I_DoorLeft_8x56;
+extern const Icon I_DoorLocked_10x56;
+extern const Icon I_DoorRight_8x56;
+extern const Icon I_DoorLeft_70x55;
+extern const Icon I_PassportLeft_6x47;
+extern const Icon I_DoorRight_70x55;
+extern const Icon I_LockPopup_100x49;
+extern const Icon I_Mute_25x27;
+extern const Icon I_IrdaArrowUp_4x8;
+extern const Icon I_Up_hvr_25x27;
+extern const Icon I_Mute_hvr_25x27;
+extern const Icon I_Vol_down_25x27;
+extern const Icon I_Down_25x27;
+extern const Icon I_Power_hvr_25x27;
+extern const Icon I_IrdaLearnShort_128x31;
+extern const Icon I_IrdaArrowDown_4x8;
+extern const Icon I_Vol_down_hvr_25x27;
+extern const Icon I_IrdaLearn_128x64;
+extern const Icon I_Down_hvr_25x27;
+extern const Icon I_Fill_marker_7x7;
+extern const Icon I_Power_25x27;
+extern const Icon I_Vol_up_25x27;
+extern const Icon I_Up_25x27;
+extern const Icon I_Back_15x10;
+extern const Icon I_IrdaSend_128x64;
+extern const Icon I_IrdaSendShort_128x34;
+extern const Icon I_Vol_up_hvr_25x27;
+extern const Icon I_KeySave_24x11;
+extern const Icon I_KeyBackspaceSelected_16x9;
+extern const Icon I_KeySaveSelected_24x11;
+extern const Icon I_KeyBackspace_16x9;
+extern const Icon A_125khz_14;
+extern const Icon A_Bluetooth_14;
+extern const Icon A_FileManager_14;
+extern const Icon A_GPIO_14;
+extern const Icon A_Games_14;
+extern const Icon A_Infrared_14;
+extern const Icon A_NFC_14;
+extern const Icon A_Passport_14;
+extern const Icon A_Plugins_14;
+extern const Icon A_Power_14;
+extern const Icon A_Settings_14;
+extern const Icon A_Sub1ghz_14;
+extern const Icon A_Tamagotchi_14;
+extern const Icon A_U2F_14;
+extern const Icon A_iButton_14;
+extern const Icon I_Medium_chip_22x21;
+extern const Icon I_EMV_Chip_14x11;
+extern const Icon I_passport_happy1_43x45;
+extern const Icon I_passport_bad3_43x45;
+extern const Icon I_passport_okay2_43x45;
+extern const Icon I_passport_bad2_43x45;
+extern const Icon I_passport_okay3_43x45;
+extern const Icon I_passport_bad1_43x45;
+extern const Icon I_passport_happy3_43x45;
+extern const Icon I_passport_happy2_43x45;
+extern const Icon I_passport_okay1_43x45;
+extern const Icon I_Health_16x16;
+extern const Icon I_FaceCharging_29x14;
+extern const Icon I_BatteryBody_52x28;
+extern const Icon I_Voltage_16x16;
+extern const Icon I_Temperature_16x16;
+extern const Icon I_FaceNopower_29x14;
+extern const Icon I_FaceNormal_29x14;
+extern const Icon I_Battery_16x16;
+extern const Icon I_FaceConfused_29x14;
+extern const Icon I_RFIDDolphinSuccess_108x57;
+extern const Icon I_RFIDBigChip_37x36;
+extern const Icon I_RFIDDolphinSend_97x61;
+extern const Icon I_RFIDDolphinReceive_97x61;
+extern const Icon I_SDQuestion_35x43;
+extern const Icon I_SDError_43x35;
+extern const Icon I_WalkR2_32x32;
+extern const Icon I_WalkL2_32x32;
+extern const Icon I_WalkRB1_32x32;
+extern const Icon I_Home_painting_17x20;
+extern const Icon I_WalkLB2_32x32;
+extern const Icon I_Sofa_40x13;
+extern const Icon I_WalkLB1_32x32;
+extern const Icon I_PC_22x29;
+extern const Icon I_WalkL1_32x32;
+extern const Icon I_TV_20x20;
+extern const Icon I_WalkR1_32x32;
+extern const Icon I_WalkRB2_32x32;
+extern const Icon I_TV_20x24;
+extern const Icon I_BadUsb_9x8;
+extern const Icon I_PlaceholderR_30x13;
+extern const Icon I_Background_128x8;
+extern const Icon I_Lock_8x8;
+extern const Icon I_Battery_26x8;
+extern const Icon I_PlaceholderL_11x13;
+extern const Icon I_Battery_19x8;
+extern const Icon I_SDcardMounted_11x8;
+extern const Icon I_SDcardFail_11x8;
+extern const Icon I_USBConnected_15x8;
+extern const Icon I_Bluetooth_5x8;
+extern const Icon I_Background_128x11;
+extern const Icon I_DolphinMafia_115x62;
+extern const Icon I_DolphinExcited_64x63;
+extern const Icon I_iButtonDolphinSuccess_109x60;
+extern const Icon I_iButtonDolphinVerySuccess_108x52;
+extern const Icon I_iButtonKey_49x44;
+extern const Icon I_DolphinNice_96x59;
+extern const Icon I_DolphinWait_61x59;

+ 0 - 5
assets/compiled/assets_icons_i.h

@@ -1,5 +0,0 @@
-#pragma once
-
-#include <assets_icons.h>
-
-const IconData * assets_icons_get_data(IconName name);

BIN
assets/icons/Common/Empty_1x1.png


+ 3 - 4
core/furi/memmgr_heap.c

@@ -137,8 +137,7 @@ void memmgr_heap_enable_thread_trace(osThreadId_t thread_id) {
     vTaskSuspendAll();
     vTaskSuspendAll();
     {
     {
         memmgr_heap_thread_trace_depth++;
         memmgr_heap_thread_trace_depth++;
-        furi_assert(
-            MemmgrHeapThreadDict_get(memmgr_heap_thread_dict, (uint32_t)thread_id) == NULL);
+        furi_check(MemmgrHeapThreadDict_get(memmgr_heap_thread_dict, (uint32_t)thread_id) == NULL);
         MemmgrHeapAllocDict_t alloc_dict;
         MemmgrHeapAllocDict_t alloc_dict;
         MemmgrHeapAllocDict_init(alloc_dict);
         MemmgrHeapAllocDict_init(alloc_dict);
         MemmgrHeapThreadDict_set_at(memmgr_heap_thread_dict, (uint32_t)thread_id, alloc_dict);
         MemmgrHeapThreadDict_set_at(memmgr_heap_thread_dict, (uint32_t)thread_id, alloc_dict);
@@ -152,8 +151,7 @@ void memmgr_heap_disable_thread_trace(osThreadId_t thread_id) {
     vTaskSuspendAll();
     vTaskSuspendAll();
     {
     {
         memmgr_heap_thread_trace_depth++;
         memmgr_heap_thread_trace_depth++;
-        furi_assert(
-            MemmgrHeapThreadDict_get(memmgr_heap_thread_dict, (uint32_t)thread_id) != NULL);
+        furi_check(MemmgrHeapThreadDict_get(memmgr_heap_thread_dict, (uint32_t)thread_id) != NULL);
         MemmgrHeapThreadDict_erase(memmgr_heap_thread_dict, (uint32_t)thread_id);
         MemmgrHeapThreadDict_erase(memmgr_heap_thread_dict, (uint32_t)thread_id);
         memmgr_heap_thread_trace_depth--;
         memmgr_heap_thread_trace_depth--;
     }
     }
@@ -167,6 +165,7 @@ size_t memmgr_heap_get_thread_memory(osThreadId_t thread_id) {
         memmgr_heap_thread_trace_depth++;
         memmgr_heap_thread_trace_depth++;
         MemmgrHeapAllocDict_t* alloc_dict =
         MemmgrHeapAllocDict_t* alloc_dict =
             MemmgrHeapThreadDict_get(memmgr_heap_thread_dict, (uint32_t)thread_id);
             MemmgrHeapThreadDict_get(memmgr_heap_thread_dict, (uint32_t)thread_id);
+        furi_check(alloc_dict);
         MemmgrHeapAllocDict_it_t alloc_dict_it;
         MemmgrHeapAllocDict_it_t alloc_dict_it;
         for(MemmgrHeapAllocDict_it(alloc_dict_it, *alloc_dict);
         for(MemmgrHeapAllocDict_it(alloc_dict_it, *alloc_dict);
             !MemmgrHeapAllocDict_end_p(alloc_dict_it);
             !MemmgrHeapAllocDict_end_p(alloc_dict_it);

+ 3 - 3
lib/app-scened-template/view-modules/dialog-ex-vm.cpp

@@ -17,7 +17,7 @@ void DialogExVM::clean() {
     set_context(NULL);
     set_context(NULL);
     set_header(NULL, 0, 0, AlignLeft, AlignBottom);
     set_header(NULL, 0, 0, AlignLeft, AlignBottom);
     set_text(NULL, 0, 0, AlignLeft, AlignBottom);
     set_text(NULL, 0, 0, AlignLeft, AlignBottom);
-    set_icon(0, 0, I_Empty_1x1);
+    set_icon(0, 0, NULL);
     set_left_button_text(NULL);
     set_left_button_text(NULL);
     set_center_button_text(NULL);
     set_center_button_text(NULL);
     set_right_button_text(NULL);
     set_right_button_text(NULL);
@@ -44,8 +44,8 @@ void DialogExVM::set_text(const char* text, uint8_t x, uint8_t y, Align horizont
     dialog_ex_set_text(dialog_ex, text, x, y, horizontal, vertical);
     dialog_ex_set_text(dialog_ex, text, x, y, horizontal, vertical);
 }
 }
 
 
-void DialogExVM::set_icon(uint8_t x, uint8_t y, IconName name) {
-    dialog_ex_set_icon(dialog_ex, x, y, name);
+void DialogExVM::set_icon(uint8_t x, uint8_t y, const Icon* icon) {
+    dialog_ex_set_icon(dialog_ex, x, y, icon);
 }
 }
 
 
 void DialogExVM::set_left_button_text(const char* text) {
 void DialogExVM::set_left_button_text(const char* text) {

+ 1 - 1
lib/app-scened-template/view-modules/dialog-ex-vm.h

@@ -45,7 +45,7 @@ public:
      * @param x, y - icon position
      * @param x, y - icon position
      * @param name - icon to be shown
      * @param name - icon to be shown
      */
      */
-    void set_icon(uint8_t x, uint8_t y, IconName name);
+    void set_icon(uint8_t x, uint8_t y, const Icon* icon);
 
 
     /**
     /**
      * Set left button text
      * Set left button text

+ 3 - 3
lib/app-scened-template/view-modules/popup-vm.cpp

@@ -16,7 +16,7 @@ void PopupVM::clean() {
     set_context(NULL);
     set_context(NULL);
     set_header(NULL, 0, 0, AlignLeft, AlignBottom);
     set_header(NULL, 0, 0, AlignLeft, AlignBottom);
     set_text(NULL, 0, 0, AlignLeft, AlignBottom);
     set_text(NULL, 0, 0, AlignLeft, AlignBottom);
-    set_icon(0, 0, I_Empty_1x1);
+    set_icon(0, 0, NULL);
     disable_timeout();
     disable_timeout();
     set_timeout(1000);
     set_timeout(1000);
 }
 }
@@ -37,8 +37,8 @@ void PopupVM::set_text(const char* text, uint8_t x, uint8_t y, Align horizontal,
     popup_set_text(popup, text, x, y, horizontal, vertical);
     popup_set_text(popup, text, x, y, horizontal, vertical);
 }
 }
 
 
-void PopupVM::set_icon(int8_t x, int8_t y, IconName name) {
-    popup_set_icon(popup, x, y, name);
+void PopupVM::set_icon(int8_t x, int8_t y, const Icon* icon) {
+    popup_set_icon(popup, x, y, icon);
 }
 }
 
 
 void PopupVM::set_timeout(uint32_t timeout_in_ms) {
 void PopupVM::set_timeout(uint32_t timeout_in_ms) {

+ 1 - 1
lib/app-scened-template/view-modules/popup-vm.h

@@ -45,7 +45,7 @@ public:
      * @param x, y - icon position
      * @param x, y - icon position
      * @param name - icon to be shown
      * @param name - icon to be shown
      */
      */
-    void set_icon(int8_t x, int8_t y, IconName name);
+    void set_icon(int8_t x, int8_t y, const Icon* icon);
 
 
     /** 
     /** 
      * Set popup timeout
      * Set popup timeout

+ 5 - 36
scripts/assets.py

@@ -10,42 +10,19 @@ import sys
 ICONS_SUPPORTED_FORMATS = ["png"]
 ICONS_SUPPORTED_FORMATS = ["png"]
 
 
 ICONS_TEMPLATE_H_HEADER = """#pragma once
 ICONS_TEMPLATE_H_HEADER = """#pragma once
-
 #include <gui/icon.h>
 #include <gui/icon.h>
 
 
-typedef enum {
-"""
-ICONS_TEMPLATE_H_ICON_NAME = "\t{name},\n"
-ICONS_TEMPLATE_H_FOOTER = """} IconName;
-
-Icon * assets_icons_get(IconName name);
 """
 """
+ICONS_TEMPLATE_H_ICON_NAME = "extern const Icon {name};\n"
 
 
-ICONS_TEMPLATE_H_I = """#pragma once
+ICONS_TEMPLATE_C_HEADER = """#include \"assets_icons.h\"
 
 
-#include <assets_icons.h>
-
-const IconData * assets_icons_get_data(IconName name);
-"""
-
-ICONS_TEMPLATE_C_HEADER = """#include \"assets_icons_i.h\"
 #include <gui/icon_i.h>
 #include <gui/icon_i.h>
 
 
 """
 """
 ICONS_TEMPLATE_C_FRAME = "const uint8_t {name}[] = {data};\n"
 ICONS_TEMPLATE_C_FRAME = "const uint8_t {name}[] = {data};\n"
 ICONS_TEMPLATE_C_DATA = "const uint8_t *{name}[] = {data};\n"
 ICONS_TEMPLATE_C_DATA = "const uint8_t *{name}[] = {data};\n"
-ICONS_TEMPLATE_C_ICONS_ARRAY_START = "const IconData icons[] = {\n"
-ICONS_TEMPLATE_C_ICONS_ITEM = "\t{{ .width={width}, .height={height}, .frame_count={frame_count}, .frame_rate={frame_rate}, .frames=_{name} }},\n"
-ICONS_TEMPLATE_C_ICONS_ARRAY_END = "};"
-ICONS_TEMPLATE_C_FOOTER = """
-const IconData * assets_icons_get_data(IconName name) {
-    return &icons[name];
-}
-
-Icon * assets_icons_get(IconName name) {
-    return icon_alloc(assets_icons_get_data(name));
-}
-"""
+ICONS_TEMPLATE_C_ICONS = "const Icon {name} = {{.width={width},.height={height},.frame_count={frame_count},.frame_rate={frame_rate},.frames=_{name}}};\n"
 
 
 
 
 class Main:
 class Main:
@@ -90,6 +67,7 @@ class Main:
         # Traverse icons tree, append image data to source file
         # Traverse icons tree, append image data to source file
         for dirpath, dirnames, filenames in os.walk(self.args.source_directory):
         for dirpath, dirnames, filenames in os.walk(self.args.source_directory):
             self.logger.debug(f"Processing directory {dirpath}")
             self.logger.debug(f"Processing directory {dirpath}")
+            dirnames.sort()
             if not filenames:
             if not filenames:
                 continue
                 continue
             if "frame_rate" in filenames:
             if "frame_rate" in filenames:
@@ -153,10 +131,9 @@ class Main:
                     icons.append((icon_name, width, height, 0, 1))
                     icons.append((icon_name, width, height, 0, 1))
         # Create array of images:
         # Create array of images:
         self.logger.debug(f"Finalizing source file")
         self.logger.debug(f"Finalizing source file")
-        icons_c.write(ICONS_TEMPLATE_C_ICONS_ARRAY_START)
         for name, width, height, frame_rate, frame_count in icons:
         for name, width, height, frame_rate, frame_count in icons:
             icons_c.write(
             icons_c.write(
-                ICONS_TEMPLATE_C_ICONS_ITEM.format(
+                ICONS_TEMPLATE_C_ICONS.format(
                     name=name,
                     name=name,
                     width=width,
                     width=width,
                     height=height,
                     height=height,
@@ -164,8 +141,6 @@ class Main:
                     frame_count=frame_count,
                     frame_count=frame_count,
                 )
                 )
             )
             )
-        icons_c.write(ICONS_TEMPLATE_C_ICONS_ARRAY_END)
-        icons_c.write(ICONS_TEMPLATE_C_FOOTER)
         icons_c.write("\n")
         icons_c.write("\n")
         # Create Public Header
         # Create Public Header
         self.logger.debug(f"Creating header")
         self.logger.debug(f"Creating header")
@@ -173,12 +148,6 @@ class Main:
         icons_h.write(ICONS_TEMPLATE_H_HEADER)
         icons_h.write(ICONS_TEMPLATE_H_HEADER)
         for name, width, height, frame_rate, frame_count in icons:
         for name, width, height, frame_rate, frame_count in icons:
             icons_h.write(ICONS_TEMPLATE_H_ICON_NAME.format(name=name))
             icons_h.write(ICONS_TEMPLATE_H_ICON_NAME.format(name=name))
-        icons_h.write(ICONS_TEMPLATE_H_FOOTER)
-        # Create Private Header
-        icons_h_i = open(
-            os.path.join(self.args.output_directory, "assets_icons_i.h"), "w"
-        )
-        icons_h_i.write(ICONS_TEMPLATE_H_I)
         self.logger.debug(f"Done")
         self.logger.debug(f"Done")
 
 
     def icon2header(self, file):
     def icon2header(self, file):

Некоторые файлы не были показаны из-за большого количества измененных файлов