fileselectbox - olikraus/m2tklib GitHub Wiki
Specification
- File selection box implemented with M2_STRLIST
- Extended (left) column for directory and file icons
- Limited to (about) 250 items per directory (restriction of M2_STRLIST)
- Selected file is returned as current element in the mass storage API
File selection box without icons:
File selection box with icons:
Code Pattern
Software Structure
The code pattern will use the M2_STRLIST element. All important tasks are done inside the callback procedure of the M2_STRLIST element:
- Calculate and assign the total number of entries for M2_STRLIST element. This is done at startup of M2_STRLIST and for any directory change (
M2_STRLIST_MSG_NEW_DIALOG
message). - Return the string and optional icon for each line line of the M2_STRLIST element (
M2_STRLIST_MSG_GET_STR
andM2_STRLIST_MSG_GET_EXTENDED_STR
message). - Change directory or return the selected file (
M2_STRLIST_MSG_SELECT
message)
The mass storage subsystem can be used by the M2_STRLIST
callback procedure. The mass storage subsystem is an interface to a mass storage library:
Code
/* Show selected file */
const char *fs_show_file_label_cb(m2_rom_void_p element)
{
return mas_GetFilename();
}
M2_LABEL(el_show_file_label, NULL, "Selected file:");
M2_LABELFN(el_show_filename, NULL, fs_show_file_label_cb);
M2_ROOT(el_show_file_ok, NULL, "ok", &top_el_tlsm);
M2_LIST(list_show_file) = { &el_show_file_label, &el_show_filename, &el_show_file_ok };
M2_VLIST(el_show_file_Vlist, NULL, list_show_file);
M2_ALIGN(top_el_show_file, "-1|1W64H64", &el_show_file_Vlist);
/* File selection dialog */
/* defines the number of additional buttons at the beginning of the STRLIST lines */
#define FS_EXTRA_MENUES 1
/* helper variables for the strlist element */
uint8_t fs_m2tk_first = 0;
uint8_t fs_m2tk_cnt = 0;
const char *fs_strlist_getstr(uint8_t idx, uint8_t msg) {
if (msg == M2_STRLIST_MSG_GET_STR) {
/* Check for the extra button: Return string for this extra button */
if ( idx == 0 )
return "..";
/* Not the extra button: Return file/directory name */
mas_GetDirEntry(idx - FS_EXTRA_MENUES);
return mas_GetFilename();
} else if ( msg == M2_STRLIST_MSG_GET_EXTENDED_STR ) {
/* Check for the extra button: Return icon for this extra button */
if ( idx == 0 )
return "a"; /* arrow left of the m2icon font */
/* Not the extra button: Return file or directory icon */
mas_GetDirEntry(idx - FS_EXTRA_MENUES);
if ( mas_IsDir() )
return "A"; /* folder icon of the m2icon font */
return "B"; /* file icon of the m2icon font */
} else if ( msg == M2_STRLIST_MSG_SELECT ) {
/* Check for the extra button: Execute button action */
if ( idx == 0 ) {
if ( mas_GetPath()[0] == '\0' )
m2_SetRoot(&top_el_tlsm);
else {
mas_ChDirUp();
m2_SetRoot(m2_GetRoot()); /* reset menu to first element, send NEW_DIALOG and force recount */
}
/* Not the extra button: Goto subdir or return (with selected file) */
} else {
mas_GetDirEntry(idx - FS_EXTRA_MENUES);
if ( mas_IsDir() ) {
mas_ChDir(mas_GetFilename());
m2_SetRoot(m2_GetRoot()); /* reset menu to first element, send NEW_DIALOG and force recount */
} else {
/* File has been selected. Here: Show the file to the user */
m2_SetRoot(&top_el_show_file);
}
}
} else if ( msg == M2_STRLIST_MSG_NEW_DIALOG ) {
/* (re-) calculate number of entries, limit no of entries to 250 */
if ( mas_GetDirEntryCnt() < 250-FS_EXTRA_MENUES )
fs_m2tk_cnt = mas_GetDirEntryCnt()+FS_EXTRA_MENUES;
else
fs_m2tk_cnt = 250;
}
return NULL;
}
M2_STRLIST(el_fs_strlist, "l5F3e15W47", &fs_m2tk_first, &fs_m2tk_cnt, fs_strlist_getstr);
M2_SPACE(el_fs_space, "W1h1");
M2_VSB(el_fs_strlist_vsb, "l5W4r1", &fs_m2tk_first, &fs_m2tk_cnt);
M2_LIST(list_fs_strlist) = { &el_fs_strlist, &el_fs_space, &el_fs_strlist_vsb };
M2_HLIST(el_top_fs, NULL, list_fs_strlist);