[FL-1300] iButton app: save selected menu item and selected file position. (#489)
* GUI module submenu: fix documentation * GUI module submenu: add submenu_set_selected_item fn * App iButton: use submenu_set_selected_item to store and set selected item in submenu * App iButton: swap write and emulate in "saved key menu" scene * App iButton: file select can now switch to the previous selected file * App iButton: swap write and emulate indexes in "saved key menu" scene Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
		
							parent
							
								
									f49f30f8a7
								
							
						
					
					
						commit
						fc5c48edef
					
				| @ -388,3 +388,89 @@ bool file_select_fill_count(FileSelect* file_select) { | |||||||
|     free(name); |     free(name); | ||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | void file_select_set_selected_file_internal(FileSelect* file_select, const char* filename) { | ||||||
|  |     furi_assert(file_select); | ||||||
|  |     furi_assert(filename); | ||||||
|  |     furi_assert(file_select->fs_api); | ||||||
|  |     furi_assert(file_select->path); | ||||||
|  |     furi_assert(file_select->extension); | ||||||
|  | 
 | ||||||
|  |     if(strlen(filename) == 0) return; | ||||||
|  | 
 | ||||||
|  |     FileInfo file_info; | ||||||
|  |     File directory; | ||||||
|  |     bool result; | ||||||
|  |     FS_Dir_Api* dir_api = &file_select->fs_api->dir; | ||||||
|  |     const uint8_t name_length = 100; | ||||||
|  |     char* name = calloc(name_length, sizeof(char)); | ||||||
|  | 
 | ||||||
|  |     uint16_t file_position = 0; | ||||||
|  | 
 | ||||||
|  |     if(name == NULL) { | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     result = dir_api->open(&directory, file_select->path); | ||||||
|  | 
 | ||||||
|  |     if(!result) { | ||||||
|  |         dir_api->close(&directory); | ||||||
|  |         free(name); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     while(1) { | ||||||
|  |         result = dir_api->read(&directory, &file_info, name, name_length); | ||||||
|  | 
 | ||||||
|  |         if(directory.error_id == FSE_NOT_EXIST || name[0] == 0) { | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if(result) { | ||||||
|  |             if(directory.error_id == FSE_OK) { | ||||||
|  |                 if(filter_file(file_select, &file_info, name)) { | ||||||
|  |                     if(strcmp(filename, name) == 0) { | ||||||
|  |                         break; | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     file_position++; | ||||||
|  |                 } | ||||||
|  |             } else { | ||||||
|  |                 dir_api->close(&directory); | ||||||
|  |                 free(name); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     with_view_model( | ||||||
|  |         file_select->view, (FileSelectModel * model) { | ||||||
|  |             uint16_t max_first_file_index = | ||||||
|  |                 model->file_count > FILENAME_COUNT ? model->file_count - FILENAME_COUNT : 0; | ||||||
|  | 
 | ||||||
|  |             model->first_file_index = file_position; | ||||||
|  | 
 | ||||||
|  |             if(model->first_file_index > 0) { | ||||||
|  |                 model->first_file_index -= 1; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if(model->first_file_index >= max_first_file_index) { | ||||||
|  |                 model->first_file_index = max_first_file_index; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             model->position = file_position - model->first_file_index; | ||||||
|  | 
 | ||||||
|  |             return true; | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |     dir_api->close(&directory); | ||||||
|  |     free(name); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void file_select_set_selected_file(FileSelect* file_select, const char* filename) { | ||||||
|  |     file_select_set_selected_file_internal(file_select, filename); | ||||||
|  | 
 | ||||||
|  |     if(!file_select_fill_strings(file_select)) { | ||||||
|  |         file_select->callback(false, file_select->context); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -20,6 +20,7 @@ void file_select_set_callback(FileSelect* file_select, FileSelectCallback callba | |||||||
| void file_select_set_filter(FileSelect* file_select, const char* path, const char* extension); | void file_select_set_filter(FileSelect* file_select, const char* path, const char* extension); | ||||||
| void file_select_set_result_buffer(FileSelect* file_select, char* buffer, uint8_t buffer_size); | void file_select_set_result_buffer(FileSelect* file_select, char* buffer, uint8_t buffer_size); | ||||||
| bool file_select_init(FileSelect* file_select); | bool file_select_init(FileSelect* file_select); | ||||||
|  | void file_select_set_selected_file(FileSelect* file_select, const char* filename); | ||||||
| 
 | 
 | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| } | } | ||||||
|  | |||||||
| @ -168,6 +168,42 @@ void submenu_clean(Submenu* submenu) { | |||||||
|         }); |         }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void submenu_set_selected_item(Submenu* submenu, uint32_t index) { | ||||||
|  |     with_view_model( | ||||||
|  |         submenu->view, (SubmenuModel * model) { | ||||||
|  |             uint32_t position = 0; | ||||||
|  |             SubmenuItemArray_it_t it; | ||||||
|  |             for(SubmenuItemArray_it(it, model->items); !SubmenuItemArray_end_p(it); | ||||||
|  |                 SubmenuItemArray_next(it)) { | ||||||
|  |                 if(index == SubmenuItemArray_cref(it)->index) { | ||||||
|  |                     break; | ||||||
|  |                 } | ||||||
|  |                 position++; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if(position >= SubmenuItemArray_size(model->items)) { | ||||||
|  |                 position = 0; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             model->position = position; | ||||||
|  |             model->window_position = position; | ||||||
|  | 
 | ||||||
|  |             if(model->window_position > 0) { | ||||||
|  |                 model->window_position -= 1; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if(SubmenuItemArray_size(model->items) <= 4) { | ||||||
|  |                 model->window_position = 0; | ||||||
|  |             } else { | ||||||
|  |                 if(model->window_position >= (SubmenuItemArray_size(model->items) - 4)) { | ||||||
|  |                     model->window_position = (SubmenuItemArray_size(model->items) - 4); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             return true; | ||||||
|  |         }); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void submenu_process_up(Submenu* submenu) { | void submenu_process_up(Submenu* submenu) { | ||||||
|     with_view_model( |     with_view_model( | ||||||
|         submenu->view, (SubmenuModel * model) { |         submenu->view, (SubmenuModel * model) { | ||||||
|  | |||||||
| @ -10,23 +10,33 @@ typedef struct Submenu Submenu; | |||||||
| typedef struct SubmenuItem SubmenuItem; | typedef struct SubmenuItem SubmenuItem; | ||||||
| typedef void (*SubmenuItemCallback)(void* context, uint32_t index); | typedef void (*SubmenuItemCallback)(void* context, uint32_t index); | ||||||
| 
 | 
 | ||||||
| /* Allocate and initialize submenu
 | /**
 | ||||||
|  |  * @brief Allocate and initialize submenu | ||||||
|  * This submenu is used to select one option |  * This submenu is used to select one option | ||||||
|  */ |  */ | ||||||
| Submenu* submenu_alloc(); | Submenu* submenu_alloc(); | ||||||
| 
 | 
 | ||||||
| /* Deinitialize and free submenu
 | /**
 | ||||||
|  |  * @brief Allocate and initialize submenu for vertical display | ||||||
|  |  * This submenu is used to select one option | ||||||
|  |  */ | ||||||
|  | Submenu* submenu_vertical_alloc(); | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * @brief Deinitialize and free submenu | ||||||
|  * @param submenu - Submenu instance |  * @param submenu - Submenu instance | ||||||
|  */ |  */ | ||||||
| void submenu_free(Submenu* submenu); | void submenu_free(Submenu* submenu); | ||||||
| 
 | 
 | ||||||
| /* Get submenu view
 | /**
 | ||||||
|  |  * @brief Get submenu view | ||||||
|  * @param submenu - Submenu instance |  * @param submenu - Submenu instance | ||||||
|  * @return View instance that can be used for embedding |  * @return View instance that can be used for embedding | ||||||
|  */ |  */ | ||||||
| View* submenu_get_view(Submenu* submenu); | View* submenu_get_view(Submenu* submenu); | ||||||
| 
 | 
 | ||||||
| /* Add item to submenu
 | /**
 | ||||||
|  |  * @brief Add item to submenu | ||||||
|  * @param submenu - Submenu instance |  * @param submenu - Submenu instance | ||||||
|  * @param label - menu item label |  * @param label - menu item label | ||||||
|  * @param index - menu item index, used for callback, may be the same with other items |  * @param index - menu item index, used for callback, may be the same with other items | ||||||
| @ -41,12 +51,18 @@ SubmenuItem* submenu_add_item( | |||||||
|     SubmenuItemCallback callback, |     SubmenuItemCallback callback, | ||||||
|     void* callback_context); |     void* callback_context); | ||||||
| 
 | 
 | ||||||
| /* Remove all items from submenu
 | /**
 | ||||||
|  |  * @brief Remove all items from submenu | ||||||
|  * @param submenu - Submenu instance |  * @param submenu - Submenu instance | ||||||
|  */ |  */ | ||||||
| void submenu_clean(Submenu* submenu); | void submenu_clean(Submenu* submenu); | ||||||
| 
 | 
 | ||||||
| Submenu* submenu_vertical_alloc(); | /**
 | ||||||
|  |  * @brief Set submenu item selector | ||||||
|  |  * @param submenu  | ||||||
|  |  * @param index  | ||||||
|  |  */ | ||||||
|  | void submenu_set_selected_item(Submenu* submenu, uint32_t index); | ||||||
| 
 | 
 | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| } | } | ||||||
|  | |||||||
| @ -18,6 +18,7 @@ void iButtonSceneAddType::on_enter(iButtonApp* app) { | |||||||
|     submenu_add_item(submenu, "Cyfral", SubmenuIndexCyfral, callback, app); |     submenu_add_item(submenu, "Cyfral", SubmenuIndexCyfral, callback, app); | ||||||
|     submenu_add_item(submenu, "Dallas", SubmenuIndexDallas, callback, app); |     submenu_add_item(submenu, "Dallas", SubmenuIndexDallas, callback, app); | ||||||
|     submenu_add_item(submenu, "Metakom", SubmenuIndexMetakom, callback, app); |     submenu_add_item(submenu, "Metakom", SubmenuIndexMetakom, callback, app); | ||||||
|  |     submenu_set_selected_item(submenu, submenu_item_selected); | ||||||
| 
 | 
 | ||||||
|     view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewSubmenu); |     view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewSubmenu); | ||||||
| } | } | ||||||
| @ -26,6 +27,7 @@ bool iButtonSceneAddType::on_event(iButtonApp* app, iButtonEvent* event) { | |||||||
|     bool consumed = false; |     bool consumed = false; | ||||||
| 
 | 
 | ||||||
|     if(event->type == iButtonEvent::Type::EventTypeMenuSelected) { |     if(event->type == iButtonEvent::Type::EventTypeMenuSelected) { | ||||||
|  |         submenu_item_selected = event->payload.menu_index; | ||||||
|         switch(event->payload.menu_index) { |         switch(event->payload.menu_index) { | ||||||
|         case SubmenuIndexCyfral: |         case SubmenuIndexCyfral: | ||||||
|             app->get_key()->set_type(iButtonKeyType::KeyCyfral); |             app->get_key()->set_type(iButtonKeyType::KeyCyfral); | ||||||
|  | |||||||
| @ -9,4 +9,5 @@ public: | |||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     void submenu_callback(void* context, uint32_t index); |     void submenu_callback(void* context, uint32_t index); | ||||||
|  |     uint32_t submenu_item_selected = 0; | ||||||
| }; | }; | ||||||
| @ -20,6 +20,7 @@ void iButtonSceneReadedKeyMenu::on_enter(iButtonApp* app) { | |||||||
|     submenu_add_item(submenu, "Name and save", SubmenuIndexNameAndSave, callback, app); |     submenu_add_item(submenu, "Name and save", SubmenuIndexNameAndSave, callback, app); | ||||||
|     submenu_add_item(submenu, "Emulate", SubmenuIndexEmulate, callback, app); |     submenu_add_item(submenu, "Emulate", SubmenuIndexEmulate, callback, app); | ||||||
|     submenu_add_item(submenu, "Read new key", SubmenuIndexReadNewKey, callback, app); |     submenu_add_item(submenu, "Read new key", SubmenuIndexReadNewKey, callback, app); | ||||||
|  |     submenu_set_selected_item(submenu, submenu_item_selected); | ||||||
| 
 | 
 | ||||||
|     view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewSubmenu); |     view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewSubmenu); | ||||||
| } | } | ||||||
| @ -28,6 +29,7 @@ bool iButtonSceneReadedKeyMenu::on_event(iButtonApp* app, iButtonEvent* event) { | |||||||
|     bool consumed = false; |     bool consumed = false; | ||||||
| 
 | 
 | ||||||
|     if(event->type == iButtonEvent::Type::EventTypeMenuSelected) { |     if(event->type == iButtonEvent::Type::EventTypeMenuSelected) { | ||||||
|  |         submenu_item_selected = event->payload.menu_index; | ||||||
|         switch(event->payload.menu_index) { |         switch(event->payload.menu_index) { | ||||||
|         case SubmenuIndexWrite: |         case SubmenuIndexWrite: | ||||||
|             app->switch_to_next_scene(iButtonApp::Scene::SceneWrite); |             app->switch_to_next_scene(iButtonApp::Scene::SceneWrite); | ||||||
|  | |||||||
| @ -9,4 +9,5 @@ public: | |||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     void submenu_callback(void* context, uint32_t index); |     void submenu_callback(void* context, uint32_t index); | ||||||
|  |     uint32_t submenu_item_selected = 0; | ||||||
| }; | }; | ||||||
| @ -5,8 +5,8 @@ | |||||||
| #include <callback-connector.h> | #include <callback-connector.h> | ||||||
| 
 | 
 | ||||||
| typedef enum { | typedef enum { | ||||||
|     SubmenuIndexWrite, |  | ||||||
|     SubmenuIndexEmulate, |     SubmenuIndexEmulate, | ||||||
|  |     SubmenuIndexWrite, | ||||||
|     SubmenuIndexEdit, |     SubmenuIndexEdit, | ||||||
|     SubmenuIndexDelete, |     SubmenuIndexDelete, | ||||||
|     SubmenuIndexInfo, |     SubmenuIndexInfo, | ||||||
| @ -17,11 +17,12 @@ void iButtonSceneSavedKeyMenu::on_enter(iButtonApp* app) { | |||||||
|     Submenu* submenu = view_manager->get_submenu(); |     Submenu* submenu = view_manager->get_submenu(); | ||||||
|     auto callback = cbc::obtain_connector(this, &iButtonSceneSavedKeyMenu::submenu_callback); |     auto callback = cbc::obtain_connector(this, &iButtonSceneSavedKeyMenu::submenu_callback); | ||||||
| 
 | 
 | ||||||
|     submenu_add_item(submenu, "Write", SubmenuIndexWrite, callback, app); |  | ||||||
|     submenu_add_item(submenu, "Emulate", SubmenuIndexEmulate, callback, app); |     submenu_add_item(submenu, "Emulate", SubmenuIndexEmulate, callback, app); | ||||||
|  |     submenu_add_item(submenu, "Write", SubmenuIndexWrite, callback, app); | ||||||
|     submenu_add_item(submenu, "Edit", SubmenuIndexEdit, callback, app); |     submenu_add_item(submenu, "Edit", SubmenuIndexEdit, callback, app); | ||||||
|     submenu_add_item(submenu, "Delete", SubmenuIndexDelete, callback, app); |     submenu_add_item(submenu, "Delete", SubmenuIndexDelete, callback, app); | ||||||
|     submenu_add_item(submenu, "Info", SubmenuIndexInfo, callback, app); |     submenu_add_item(submenu, "Info", SubmenuIndexInfo, callback, app); | ||||||
|  |     submenu_set_selected_item(submenu, submenu_item_selected); | ||||||
| 
 | 
 | ||||||
|     view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewSubmenu); |     view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewSubmenu); | ||||||
| } | } | ||||||
| @ -30,6 +31,7 @@ bool iButtonSceneSavedKeyMenu::on_event(iButtonApp* app, iButtonEvent* event) { | |||||||
|     bool consumed = false; |     bool consumed = false; | ||||||
| 
 | 
 | ||||||
|     if(event->type == iButtonEvent::Type::EventTypeMenuSelected) { |     if(event->type == iButtonEvent::Type::EventTypeMenuSelected) { | ||||||
|  |         submenu_item_selected = event->payload.menu_index; | ||||||
|         switch(event->payload.menu_index) { |         switch(event->payload.menu_index) { | ||||||
|         case SubmenuIndexWrite: |         case SubmenuIndexWrite: | ||||||
|             app->switch_to_next_scene(iButtonApp::Scene::SceneWrite); |             app->switch_to_next_scene(iButtonApp::Scene::SceneWrite); | ||||||
|  | |||||||
| @ -9,4 +9,5 @@ public: | |||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     void submenu_callback(void* context, uint32_t index); |     void submenu_callback(void* context, uint32_t index); | ||||||
|  |     uint32_t submenu_item_selected = 0; | ||||||
| }; | }; | ||||||
| @ -10,7 +10,8 @@ void iButtonSceneSelectKey::on_enter(iButtonApp* app) { | |||||||
|         "ibutton", |         "ibutton", | ||||||
|         "*", |         "*", | ||||||
|         app->get_file_name(), |         app->get_file_name(), | ||||||
|         app->get_file_name_size()); |         app->get_file_name_size(), | ||||||
|  |         app->get_key()->get_name()); | ||||||
| 
 | 
 | ||||||
|     // Process file_select return
 |     // Process file_select return
 | ||||||
|     if(res) { |     if(res) { | ||||||
|  | |||||||
| @ -19,6 +19,7 @@ void iButtonSceneStart::on_enter(iButtonApp* app) { | |||||||
|     submenu_add_item(submenu, "Read", SubmenuIndexRead, callback, app); |     submenu_add_item(submenu, "Read", SubmenuIndexRead, callback, app); | ||||||
|     submenu_add_item(submenu, "Saved", SubmenuIndexSaved, callback, app); |     submenu_add_item(submenu, "Saved", SubmenuIndexSaved, callback, app); | ||||||
|     submenu_add_item(submenu, "Add manually", SubmenuIndexAdd, callback, app); |     submenu_add_item(submenu, "Add manually", SubmenuIndexAdd, callback, app); | ||||||
|  |     submenu_set_selected_item(submenu, submenu_item_selected); | ||||||
| 
 | 
 | ||||||
|     view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewSubmenu); |     view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewSubmenu); | ||||||
| } | } | ||||||
| @ -27,6 +28,7 @@ bool iButtonSceneStart::on_event(iButtonApp* app, iButtonEvent* event) { | |||||||
|     bool consumed = false; |     bool consumed = false; | ||||||
| 
 | 
 | ||||||
|     if(event->type == iButtonEvent::Type::EventTypeMenuSelected) { |     if(event->type == iButtonEvent::Type::EventTypeMenuSelected) { | ||||||
|  |         submenu_item_selected = event->payload.menu_index; | ||||||
|         switch(event->payload.menu_index) { |         switch(event->payload.menu_index) { | ||||||
|         case SubmenuIndexRead: |         case SubmenuIndexRead: | ||||||
|             app->switch_to_next_scene(iButtonApp::Scene::SceneRead); |             app->switch_to_next_scene(iButtonApp::Scene::SceneRead); | ||||||
|  | |||||||
| @ -9,4 +9,5 @@ public: | |||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     void submenu_callback(void* context, uint32_t index); |     void submenu_callback(void* context, uint32_t index); | ||||||
|  |     uint32_t submenu_item_selected = 0; | ||||||
| }; | }; | ||||||
| @ -41,6 +41,7 @@ typedef struct { | |||||||
|     const char* extension; |     const char* extension; | ||||||
|     char* result; |     char* result; | ||||||
|     uint8_t result_size; |     uint8_t result_size; | ||||||
|  |     char* selected_filename; | ||||||
| } SdAppFileSelectData; | } SdAppFileSelectData; | ||||||
| 
 | 
 | ||||||
| typedef struct { | typedef struct { | ||||||
| @ -60,7 +61,8 @@ bool sd_api_file_select( | |||||||
|     const char* path, |     const char* path, | ||||||
|     const char* extension, |     const char* extension, | ||||||
|     char* result, |     char* result, | ||||||
|     uint8_t result_size); |     uint8_t result_size, | ||||||
|  |     char* selected_filename); | ||||||
| void sd_api_check_error(SdApp* sd_app); | void sd_api_check_error(SdApp* sd_app); | ||||||
| 
 | 
 | ||||||
| /******************* Allocators *******************/ | /******************* Allocators *******************/ | ||||||
| @ -427,7 +429,8 @@ bool sd_api_file_select( | |||||||
|     const char* path, |     const char* path, | ||||||
|     const char* extension, |     const char* extension, | ||||||
|     char* result, |     char* result, | ||||||
|     uint8_t result_size) { |     uint8_t result_size, | ||||||
|  |     char* selected_filename) { | ||||||
|     bool retval = false; |     bool retval = false; | ||||||
| 
 | 
 | ||||||
|     SdAppEvent message = { |     SdAppEvent message = { | ||||||
| @ -437,7 +440,9 @@ bool sd_api_file_select( | |||||||
|                 .path = path, |                 .path = path, | ||||||
|                 .extension = extension, |                 .extension = extension, | ||||||
|                 .result = result, |                 .result = result, | ||||||
|                 .result_size = result_size}}}; |                 .result_size = result_size, | ||||||
|  |                 .selected_filename = selected_filename, | ||||||
|  |             }}}; | ||||||
| 
 | 
 | ||||||
|     furi_check(osMessageQueuePut(sd_app->event_queue, &message, 0, osWaitForever) == osOK); |     furi_check(osMessageQueuePut(sd_app->event_queue, &message, 0, osWaitForever) == osOK); | ||||||
| 
 | 
 | ||||||
| @ -859,15 +864,13 @@ int32_t sd_filesystem(void* p) { | |||||||
|                 } |                 } | ||||||
|                 if(try_to_alloc_view_holder(sd_app, gui)) { |                 if(try_to_alloc_view_holder(sd_app, gui)) { | ||||||
|                     FileSelect* file_select = alloc_and_attach_file_select(sd_app); |                     FileSelect* file_select = alloc_and_attach_file_select(sd_app); | ||||||
|  |                     SdAppFileSelectData* file_select_data = &event.payload.file_select_data; | ||||||
|  | 
 | ||||||
|                     file_select_set_api(file_select, fs_api); |                     file_select_set_api(file_select, fs_api); | ||||||
|                     file_select_set_filter( |                     file_select_set_filter( | ||||||
|                         file_select, |                         file_select, file_select_data->path, file_select_data->extension); | ||||||
|                         event.payload.file_select_data.path, |  | ||||||
|                         event.payload.file_select_data.extension); |  | ||||||
|                     file_select_set_result_buffer( |                     file_select_set_result_buffer( | ||||||
|                         file_select, |                         file_select, file_select_data->result, file_select_data->result_size); | ||||||
|                         event.payload.file_select_data.result, |  | ||||||
|                         event.payload.file_select_data.result_size); |  | ||||||
|                     if(!file_select_init(file_select)) { |                     if(!file_select_init(file_select)) { | ||||||
|                         SdAppFileSelectResultEvent retval = {.result = false}; |                         SdAppFileSelectResultEvent retval = {.result = false}; | ||||||
|                         furi_check( |                         furi_check( | ||||||
| @ -876,6 +879,10 @@ int32_t sd_filesystem(void* p) { | |||||||
|                         app_reset_state(sd_app); |                         app_reset_state(sd_app); | ||||||
|                     } else { |                     } else { | ||||||
|                         sd_app->sd_app_state = SdAppStateFileSelect; |                         sd_app->sd_app_state = SdAppStateFileSelect; | ||||||
|  |                         if(file_select_data->selected_filename != NULL) { | ||||||
|  |                             file_select_set_selected_file( | ||||||
|  |                                 file_select, file_select_data->selected_filename); | ||||||
|  |                         } | ||||||
|                         view_holder_start(sd_app->view_holder); |                         view_holder_start(sd_app->view_holder); | ||||||
|                     } |                     } | ||||||
|                 } else { |                 } else { | ||||||
|  | |||||||
| @ -14,7 +14,8 @@ typedef struct { | |||||||
|         const char* path, |         const char* path, | ||||||
|         const char* extension, |         const char* extension, | ||||||
|         char* result, |         char* result, | ||||||
|         uint8_t result_size); |         uint8_t result_size, | ||||||
|  |         char* selected_filename); | ||||||
|     void (*check_error)(SdApp* context); |     void (*check_error)(SdApp* context); | ||||||
| } SdCard_Api; | } SdCard_Api; | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 SG
						SG