From 15299adae60c2c3c1ff2c980d0462cb93390eece Mon Sep 17 00:00:00 2001 From: skeezix Date: Mon, 5 Apr 2010 16:38:08 -0400 Subject: [PATCH] minimenu: - mmcatmap.conf may be stuck into /pandora/mmenu on SD cards, in order to specify category mapping conf stuff (or random conf overrides) - now includes a directory browser/launcher - default is on (shows a tab for each non-empty dir in /media) - could just make one tab for /media .. *shrug* - may be disabled - may specify all sorts of tabs to open by using a searchpath - can run pnd-files (will work in the normal way) - can run non-pnd files (will set CWD and run them without exiting minimenu) - can browse up and down the dir tree --- deployment/etc/pandora/conf/mmenu.conf | 27 ++--- include/pnd_discovery.h | 2 + lib/pnd_discovery.c | 31 +++++ minimenu/mmcache.c | 13 +- minimenu/mmcat.c | 160 ++++++++++++++++++++++++- minimenu/mmcat.h | 10 +- minimenu/mmcatmap.conf | 21 ++++ minimenu/mmenu.c | 77 +++++++++++- minimenu/mmenu.conf | 27 ++--- minimenu/mmui.c | 124 +++++++++++++++++-- minimenu/mmui.h | 2 + minimenu/skin/default/mmskin.conf | 2 + 12 files changed, 441 insertions(+), 55 deletions(-) create mode 100644 minimenu/mmcatmap.conf diff --git a/deployment/etc/pandora/conf/mmenu.conf b/deployment/etc/pandora/conf/mmenu.conf index b5aa584..d4165ff 100644 --- a/deployment/etc/pandora/conf/mmenu.conf +++ b/deployment/etc/pandora/conf/mmenu.conf @@ -58,19 +58,14 @@ cache_path /pandora/appdata/mmenu.pvwcache # where to write cached ima cache_findpath /media/mmcblk[12]p?/pandora/appdata/mmenu.pvwcache # where to look for cached preview pics [categories] -do_all_cat 1 # if >0, will show an All category; if 0, skip it, just your cats. -# Normally for mmenu, an encountered category is just used as is. 5 cats exist, you get 5 tabs. -# If map_on is >0, then category transforms will occur -# @NEWCAT oldcat1:oldcat2 <- means oldcat1, if found, will map to NEWCAT. "@" is discarded. -# NOTE: FreeDesktop rules do not allow categories with spaces in the name; if needed, I can add it with quoting. -# If map_default_on is set (>0), then any unmapped categories will be forced into the default category bucket (map_default_cat.) -# If map_default_on is off (=0), then unmapped categories will become their own categories as normal. -# Should probably still have an @ line to create the default category, since creating the cats comes before assigning defaults -# NOTE: Individual app overrides occur at the time of app scanning, so before this category mapping occurs and thus is effected -map_on 0 # if >0, will do category mapping at all; if 0, don't do any of this. -map_default_on 0 # if >0, any unmapped category will get forced to map_default_cat; set to 0 to leave unmapped cats alone -map_default_cat Spam # see map_default_on -# NOTE: List the categories in reverse order to how you wish them in the tab list; last one shows up as first tab -@Woogle Audio -@Jimmy Game -@Spam +catmap_searchpath /media/*/pandora/mmenu:/etc/pandora/mmenu:./minimenu +catmap_confname mmcatmap.conf +do_all_cat 1 # if >0, will show an All category; if 0, skip it, just your cats. + +[filesystem] +do_browser 1 # if >0, will allow filesystem browsing somehow +tab_searchpaths /media/* # for each chunk in searchpath, show a tab (if not empty). +# example: +# /media -> show /media as a single tab +# /media/* -> show a tab for each dir in /media +# /media/mmcblk1p1:/media/mmcblk2p1 -> show 2 tabs, one for first partition on each SD diff --git a/include/pnd_discovery.h b/include/pnd_discovery.h index 5f8734f..f5dae7a 100644 --- a/include/pnd_discovery.h +++ b/include/pnd_discovery.h @@ -16,6 +16,7 @@ extern "C" { * overridespath may be NULL if you do not wish to search for pxml overrides */ pnd_box_handle pnd_disco_search ( char *searchpath, char *overridespath ); +pnd_box_handle pnd_disco_file ( char *path, char *filename ); // should you wish to 'discover' one .pnd-file /* pnd_disco_t describes a given entry found by the discovery code; ie: the containers key is the path to * the PXML file (since this is relatively unique), with the fields below detailing the executable path, @@ -44,6 +45,7 @@ typedef enum { // NOTE: We really need to rework disco-t so it can include non-english titles/desc; perhaps more info as optional, // or a name/value pairing system so it can have extra data in it, without a complex structure. #define PND_DISCO_FLAG_OVR 1 // An ovr file was found for this app (not per subapp, just per .pnd) +#define PND_DISCO_GENERATED 2 // This disco is 'faux', made up and not reflecting a real 'pnd file' typedef struct { // base unsigned char object_type; // see enum above diff --git a/lib/pnd_discovery.c b/lib/pnd_discovery.c index 1e41ead..07cde30 100644 --- a/lib/pnd_discovery.c +++ b/lib/pnd_discovery.c @@ -420,3 +420,34 @@ pnd_box_handle pnd_disco_search ( char *searchpath, char *overridespath ) { return ( disco_box ); } + +pnd_box_handle pnd_disco_file ( char *path, char *filename ) { + struct stat statbuf; + + // set up container + disco_overrides = NULL; + disco_box = pnd_box_new ( "discovery" ); + + // path + char fullpath [ PATH_MAX ]; + sprintf ( fullpath, "%s/%s", path, filename ); + + // fake it + if ( stat ( fullpath, &statbuf ) < 0 ) { + return ( 0 ); + } + + struct FTW ftw; + ftw.base = strlen ( path ); + ftw.level = 0; + + pnd_disco_callback ( fullpath, &statbuf, FTW_F, &ftw ); + + // return whatever we found, or NULL if nada + if ( ! pnd_box_get_head ( disco_box ) ) { + pnd_box_delete ( disco_box ); + disco_box = NULL; + } + + return ( disco_box ); +} diff --git a/minimenu/mmcache.c b/minimenu/mmcache.c index d8ba65e..c5682f2 100644 --- a/minimenu/mmcache.c +++ b/minimenu/mmcache.c @@ -239,10 +239,15 @@ unsigned char cache_icon ( pnd_disco_t *app, unsigned char maxwidth, unsigned ch } // stat } // ovr? - // pull icon into buffer from .pnd - if ( ! iconbuf ) { - iconbuf = pnd_emit_icon_to_buffer ( app, &buflen ); - } + // if this is a real pnd file (dir-app or pnd-file-app), then try to pull icon from there + if ( ! ( app -> object_flags & PND_DISCO_GENERATED ) ) { + + // pull icon into buffer from .pnd if not already found an icon + if ( ! iconbuf ) { + iconbuf = pnd_emit_icon_to_buffer ( app, &buflen ); + } + + } // generated? if ( ! iconbuf ) { return ( 0 ); diff --git a/minimenu/mmcat.c b/minimenu/mmcat.c index 1c666ee..db8d986 100644 --- a/minimenu/mmcat.c +++ b/minimenu/mmcat.c @@ -2,6 +2,10 @@ #include #include #include +#include +#include +#include +#include #include "pnd_conf.h" #include "pnd_logger.h" @@ -22,7 +26,7 @@ unsigned char g_catmapcount = 0; extern pnd_conf_handle g_conf; -unsigned char category_push ( char *catname, pnd_disco_t *app, pnd_conf_handle ovrh ) { +unsigned char category_push ( char *catname, pnd_disco_t *app, pnd_conf_handle ovrh, char *fspath ) { mm_category_t *c; // check category list; if found, append app to the end of it. @@ -42,6 +46,11 @@ unsigned char category_push ( char *catname, pnd_disco_t *app, pnd_conf_handle o g_categories [ g_categorycount ].catname = strdup ( catname ); g_categories [ g_categorycount ].refs = NULL; c = &(g_categories [ g_categorycount ]); + + if ( fspath ) { + g_categories [ g_categorycount ].fspath = strdup ( fspath );; + } + g_categorycount++; } @@ -75,7 +84,7 @@ unsigned char category_push ( char *catname, pnd_disco_t *app, pnd_conf_handle o while ( iter ) { if ( iter -> ref -> title_en ) { - if ( strcmp ( ar -> ref -> title_en, iter -> ref -> title_en ) < 0 ) { + if ( cat_sort_score ( ar, iter ) < 0 ) { // new guy is smaller than the current guy! break; } @@ -126,6 +135,41 @@ mm_category_t *category_query ( char *catname ) { return ( NULL ); } +int cat_sort_score ( mm_appref_t *s1, mm_appref_t *s2 ) { + + extern mm_category_t g_categories [ MAX_CATS ]; + extern unsigned char g_categorycount; + extern unsigned char ui_category; + + // are we in a directory browser, or looking at pnd-files? + if ( g_categories [ ui_category ].fspath ) { + + if ( s1 == s2 ) { + return ( 0 ); // equal + + } else if ( s1 -> ref -> object_type == pnd_object_type_directory && + s2 -> ref -> object_type == pnd_object_type_directory ) + { + // both are directories, be nice + return ( strcmp ( s1 -> ref -> title_en, s2 -> ref -> title_en ) ); + } else if ( s1 -> ref -> object_type == pnd_object_type_directory && + s2 -> ref -> object_type != pnd_object_type_directory ) + { + return ( -1 ); // dir on the left is earlier than file on the right + } else if ( s1 -> ref -> object_type != pnd_object_type_directory && + s2 -> ref -> object_type == pnd_object_type_directory ) + { + return ( 1 ); // dir on the right is earlier than file on the left + } else { + // file on file + return ( strcmp ( s1 -> ref -> title_en, s2 -> ref -> title_en ) ); + } + + } + + return ( strcmp ( s1 -> ref -> title_en, s2 -> ref -> title_en ) ); +} + void category_dump ( void ) { unsigned int i; @@ -190,7 +234,7 @@ unsigned char category_map_setup ( void ) { { //pnd_log ( pndn_debug, "target(%s) from(%s)\n", k, buffer ); - category_push ( k, NULL, 0 ); + category_push ( k, NULL, 0, NULL /* fspath */ ); g_catmaps [ g_catmapcount ].target = category_query ( k ); g_catmaps [ g_catmapcount ].from = strdup ( buffer ); g_catmapcount++; @@ -228,19 +272,123 @@ unsigned char category_meta_push ( char *catname, pnd_disco_t *app, pnd_conf_han cat = category_map_query ( catname ); if ( cat ) { - return ( category_push ( cat -> catname, app, ovrh ) ); + return ( category_push ( cat -> catname, app, ovrh, NULL /* fspath */ ) ); } // not mapped.. but default? if ( pnd_conf_get_as_int_d ( g_conf, "categories.map_default_on", 0 ) ) { char *def = pnd_conf_get_as_char ( g_conf, "categories.map_default_cat" ); if ( def ) { - return ( category_push ( def, app, ovrh ) ); + return ( category_push ( def, app, ovrh, NULL /* fspath */ ) ); } } } // cat map is desired? // not default, just do it - return ( category_push ( catname, app, ovrh ) ); + return ( category_push ( catname, app, ovrh, NULL /* fspath */ ) ); +} + +unsigned char category_fs_restock ( mm_category_t *cat ) { + + if ( ! cat -> fspath ) { + return ( 1 ); // not a filesystem browser tab + } + + // clear any existing baggage + // + + // apprefs + mm_appref_t *iter = cat -> refs, *next; + while ( iter ) { + next = iter -> next; + free ( iter ); + iter = next; + } + cat -> refs = NULL; + + // discos + if ( cat -> disco ) { + pnd_disco_t *p = pnd_box_get_head ( cat -> disco ); + pnd_disco_t *n; + while ( p ) { + n = pnd_box_get_next ( p ); + pnd_disco_destroy ( p ); + p = n; + } + pnd_box_delete ( cat -> disco ); + } + + // rescan the filesystem + // + + //pnd_log ( pndn_debug, "Restocking cat %s with path %s\n", cat -> catname, cat -> fspath ); + DIR *d; + + if ( ( d = opendir ( cat -> fspath ) ) ) { + struct dirent *de = readdir ( d ); + + pnd_disco_t *disco; + char uid [ 100 ]; + + cat -> disco = pnd_box_new ( cat -> catname ); + + while ( de ) { + + struct stat buffy; + char fullpath [ PATH_MAX ]; + sprintf ( fullpath, "%s/%s", cat -> fspath, de -> d_name ); + int statret = stat ( fullpath, &buffy ); + + // if file is executable somehow or another + if ( statret == 0 && + buffy.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH) + ) + { + // determine unique-id + sprintf ( uid, "%d", (int) de -> d_ino ); + disco = NULL; + + switch ( de -> d_type ) { + + case DT_DIR: + if ( strcmp ( de -> d_name, "." ) == 0 ) { + // ignore ".", but ".." is fine + } else { + disco = pnd_box_allocinsert ( cat -> disco, uid, sizeof(pnd_disco_t) ); + disco -> object_type = pnd_object_type_directory; // suggest to Grid that its a dir + } + break; + case DT_UNKNOWN: + case DT_REG: + disco = pnd_box_allocinsert ( cat -> disco, uid, sizeof(pnd_disco_t) ); + disco -> object_type = pnd_object_type_unknown; // suggest to Grid that its a file + break; + + } // switch + + // found a directory or executable? + if ( disco ) { + // register with this category + disco -> unique_id = strdup ( uid ); + disco -> title_en = strdup ( de -> d_name ); + disco -> object_flags = PND_DISCO_GENERATED; + disco -> object_path = strdup ( cat -> fspath ); + disco -> object_filename = strdup ( de -> d_name ); + category_push ( cat -> catname, disco, 0, NULL /* fspath already set */ ); + // if a override icon exists, cache it up + cache_icon ( disco, pnd_conf_get_as_int_d ( g_conf, "grid.icon_max_width", 50 ), + pnd_conf_get_as_int_d ( g_conf, "grid.icon_max_height", 50 ) ); + } + + } // stat + + // next + de = readdir ( d ); + } + + closedir ( d ); + } + + return ( 1 ); } diff --git a/minimenu/mmcat.h b/minimenu/mmcat.h index 0c679cb..db3c638 100644 --- a/minimenu/mmcat.h +++ b/minimenu/mmcat.h @@ -11,8 +11,12 @@ typedef struct _mm_appref_t { typedef struct { char *catname; // name of the category + // current applications mm_appref_t *refs; // apps (from g_active_apps) that are in this category unsigned int refcount; // how many apps in this category + // if a directory browser category, additional info is needed + char *fspath; // NULL if a pnd-category (not a filesystem category) + pnd_box_handle disco; // faux-applications generated from filesystem } mm_category_t; #define MAX_CATS 100 @@ -20,10 +24,11 @@ typedef struct { #define CATEGORY_ALL "All" // try to populate as many cats as necessary -unsigned char category_push ( char *catname, pnd_disco_t *app, pnd_conf_handle ovrh ); // catname is not pulled from app, so we can make them up on the fly (ie: "All") +unsigned char category_push ( char *catname, pnd_disco_t *app, pnd_conf_handle ovrh, char *fspath ); // catname is not pulled from app, so we can make them up on the fly (ie: "All"); mm_category_t *category_query ( char *catname ); void category_dump ( void ); // sort the apprefs void category_freeall ( void ); +int cat_sort_score ( mm_appref_t *s1, mm_appref_t *s2 ); // like strcmp, but used to sort apps by title // category mapping hack typedef struct { @@ -35,4 +40,7 @@ unsigned char category_map_setup ( void ); // set up the mappings mm_category_t *category_map_query ( char *cat ); unsigned char category_meta_push ( char *catname, pnd_disco_t *app, pnd_conf_handle ovrh ); +// filesystem browser +unsigned char category_fs_restock ( mm_category_t *cat ); + #endif diff --git a/minimenu/mmcatmap.conf b/minimenu/mmcatmap.conf new file mode 100644 index 0000000..416bef6 --- /dev/null +++ b/minimenu/mmcatmap.conf @@ -0,0 +1,21 @@ + +# +# mmcatmap.conf -- allows merging or renaming or mapping of categories from one name to another, for minimenu. +# + +[categories] +# Normally for mmenu, an encountered category is just used as is. 5 cats exist, you get 5 tabs. +# If map_on is >0, then category transforms will occur +# @NEWCAT oldcat1:oldcat2 <- means oldcat1, if found, will map to NEWCAT. "@" is discarded. +# NOTE: FreeDesktop rules do not allow categories with spaces in the name; if needed, I can add it with quoting. +# If map_default_on is set (>0), then any unmapped categories will be forced into the default category bucket (map_default_cat.) +# If map_default_on is off (=0), then unmapped categories will become their own categories as normal. +# Should probably still have an @ line to create the default category, since creating the cats comes before assigning defaults +# NOTE: Individual app overrides occur at the time of app scanning, so before this category mapping occurs and thus is effected +map_on 0 # if >0, will do category mapping at all; if 0, don't do any of this. +map_default_on 0 # if >0, any unmapped category will get forced to map_default_cat; set to 0 to leave unmapped cats alone +map_default_cat Spam # see map_default_on +# NOTE: List the categories in reverse order to how you wish them in the tab list; last one shows up as first tab +@Woogle Audio +@Jimmy Game +@Spam diff --git a/minimenu/mmenu.c b/minimenu/mmenu.c index d0f1280..95a8b4b 100644 --- a/minimenu/mmenu.c +++ b/minimenu/mmenu.c @@ -35,6 +35,7 @@ #include #include #include +#include #include "pnd_logger.h" #include "pnd_pxml.h" @@ -45,6 +46,7 @@ #include "pnd_locate.h" #include "pnd_device.h" #include "pnd_pndfiles.h" +#include "../lib/pnd_pathiter.h" #include "mmenu.h" #include "mmwrapcmd.h" @@ -171,6 +173,25 @@ int main ( int argc, char *argv[] ) { emit_and_quit ( MM_QUIT ); } + /* category conf file + */ + { + char *locater = pnd_locate_filename ( pnd_conf_get_as_char ( g_conf, "categories.catmap_searchpath" ), + pnd_conf_get_as_char ( g_conf, "categories.catmap_confname" ) ); + + if ( locater ) { + pnd_log ( pndn_rem, "Found category conf at '%s'\n", locater ); + pnd_conf_handle h = pnd_conf_fetch_by_path ( locater ); + if ( h ) { + // lets just merge the skin conf onto the regular conf, so it just magicly works + pnd_box_append ( g_conf, h ); + } + } else { + pnd_log ( pndn_debug, "No additional category conf file found.\n" ); + } + + } // cat conf + // redo log filter pnd_log_set_filter ( pnd_conf_get_as_int_d ( g_conf, "minimenu.loglevel", pndn_error ) ); @@ -288,7 +309,7 @@ int main ( int argc, char *argv[] ) { // create all cat if ( pnd_conf_get_as_int_d ( g_conf, "categories.do_all_cat", 1 ) ) { - category_push ( g_x11_present ? CATEGORY_ALL " (X11)" : CATEGORY_ALL " (No X11)", NULL, 0 ); + category_push ( g_x11_present ? CATEGORY_ALL " (X11)" : CATEGORY_ALL " (No X11)", NULL /*app*/, 0, NULL /* fspath */ ); } // set up category mappings @@ -325,6 +346,34 @@ void emit_and_quit ( char *s ) { exit ( 0 ); } +static unsigned int is_dir_empty ( char *fullpath ) { + DIR *d = opendir ( fullpath ); + + if ( ! d ) { + return ( 0 ); // not empty, since we don't know + } + + struct dirent *de = readdir ( d ); + + while ( de ) { + + if ( strcmp ( de -> d_name, "." ) == 0 ) { + // irrelevent + } else if ( strcmp ( de -> d_name, ".." ) == 0 ) { + // irrelevent + } else { + // something else came in, so dir must not be empty + return ( 0 ); + } + + de = readdir ( d ); + } + + closedir ( d ); + + return ( 1 ); // dir is empty +} + void applications_free ( void ) { // free up all our category apprefs, but keep the preview and icon cache's.. @@ -470,7 +519,7 @@ void applications_scan ( void ) { // push to All category // we do this first, so first category is always All if ( pnd_conf_get_as_int_d ( g_conf, "categories.do_all_cat", 1 ) ) { - if ( ! category_push ( g_x11_present ? CATEGORY_ALL " (X11)" : CATEGORY_ALL " (No X11)", iter, ovrh ) ) { + if ( ! category_push ( g_x11_present ? CATEGORY_ALL " (X11)" : CATEGORY_ALL " (No X11)", iter, ovrh, NULL /* fspath */ ) ) { pnd_log ( pndn_warning, " Couldn't categorize to All: '%s'\n", IFNULL(iter -> title_en, "No Name") ); } } // all? @@ -520,6 +569,30 @@ void applications_scan ( void ) { itercount++; } // while + // set up filesystem browser tabs + if ( pnd_conf_get_as_int_d ( g_conf, "filesystem.do_browser", 0 ) ) { + char *searchpath = pnd_conf_get_as_char ( g_conf, "filesystem.tab_searchpaths" ); + + SEARCHPATH_PRE + { + char *c, *tabname; + c = strrchr ( buffer, '/' ); + if ( c && (*(c+1)!='\0') ) { + tabname = c; + } else { + tabname = buffer; + } + + // check if dir is empty; if so, skip it. + if ( ! is_dir_empty ( buffer ) ) { + category_push ( tabname /* tab name */, NULL /* app */, 0 /* override */, buffer /* fspath */ ); + } + + } + SEARCHPATH_POST + + } // set up fs browser tabs + // dump categories //category_dump(); diff --git a/minimenu/mmenu.conf b/minimenu/mmenu.conf index a4937d7..df6e06e 100644 --- a/minimenu/mmenu.conf +++ b/minimenu/mmenu.conf @@ -58,19 +58,14 @@ cache_path /pandora/appdata/mmenu.pvwcache # where to write cached ima cache_findpath /media/mmcblk[12]p?/pandora/appdata/mmenu.pvwcache # where to look for cached preview pics [categories] -do_all_cat 1 # if >0, will show an All category; if 0, skip it, just your cats. -# Normally for mmenu, an encountered category is just used as is. 5 cats exist, you get 5 tabs. -# If map_on is >0, then category transforms will occur -# @NEWCAT oldcat1:oldcat2 <- means oldcat1, if found, will map to NEWCAT. "@" is discarded. -# NOTE: FreeDesktop rules do not allow categories with spaces in the name; if needed, I can add it with quoting. -# If map_default_on is set (>0), then any unmapped categories will be forced into the default category bucket (map_default_cat.) -# If map_default_on is off (=0), then unmapped categories will become their own categories as normal. -# Should probably still have an @ line to create the default category, since creating the cats comes before assigning defaults -# NOTE: Individual app overrides occur at the time of app scanning, so before this category mapping occurs and thus is effected -map_on 0 # if >0, will do category mapping at all; if 0, don't do any of this. -map_default_on 0 # if >0, any unmapped category will get forced to map_default_cat; set to 0 to leave unmapped cats alone -map_default_cat Spam # see map_default_on -# NOTE: List the categories in reverse order to how you wish them in the tab list; last one shows up as first tab -@Woogle Audio -@Jimmy Game -@Spam +catmap_searchpath /media/*/pandora/mmenu:/etc/pandora/mmenu:./minimenu +catmap_confname mmcatmap.conf +do_all_cat 1 # if >0, will show an All category; if 0, skip it, just your cats. + +[filesystem] +do_browser 1 # if >0, will allow filesystem browsing somehow +tab_searchpaths /media/* # for each chunk in searchpath, show a tab (if not empty). +# example: +# /media -> show /media as a single tab +# /media/* -> show a tab for each dir in /media +# /media/mmcblk1p1:/media/mmcblk2p1 -> show 2 tabs, one for first partition on each SD diff --git a/minimenu/mmui.c b/minimenu/mmui.c index 954e50e..b922800 100644 --- a/minimenu/mmui.c +++ b/minimenu/mmui.c @@ -1,9 +1,14 @@ -#include -#include -#include +#include /* for FILE etc */ +#include /* for malloc */ +#include /* for unlink */ +#include /* for PATH_MAX */ +#include +#include +#define __USE_GNU /* for strcasestr */ +#include /* for making ftw.h happy */ #include -#include +#include #include "SDL.h" #include "SDL_audio.h" #include "SDL_image.h" @@ -11,7 +16,6 @@ #include "SDL_gfxPrimitives.h" #include "SDL_rotozoom.h" #include "SDL_thread.h" -#include #include #include "pnd_conf.h" @@ -23,6 +27,7 @@ #include "pnd_device.h" #include "../lib/pnd_pathiter.h" #include "pnd_utility.h" +#include "pnd_pndfiles.h" #include "mmenu.h" #include "mmcat.h" @@ -210,6 +215,8 @@ mm_imgcache_t g_imagecache [ IMG_TRUEMAX ] = { { IMG_ARROW_DOWN, "graphics.IMG_ARROW_DOWN", }, { IMG_ARROW_SCROLLBAR, "graphics.IMG_ARROW_SCROLLBAR", }, { IMG_HOURGLASS, "graphics.IMG_HOURGLASS", }, + { IMG_FOLDER, "graphics.IMG_FOLDER", }, + { IMG_EXECBIN, "graphics.IMG_EXECBIN", }, { IMG_MAX, NULL }, }; @@ -365,8 +372,6 @@ void ui_render ( void ) { int topleft = col_max * ui_rows_scrolled_down; int botright = ( col_max * ( ui_rows_scrolled_down + row_max ) - 1 ); - pnd_log ( PND_LOG_DEFAULT, "index %u tl %u br %u\n", index, topleft, botright ); - if ( index < topleft ) { ui_rows_scrolled_down -= pnd_conf_get_as_int_d ( g_conf, "grid.scroll_increment", 1 ); render_jobs_b |= R_ALL; @@ -411,7 +416,7 @@ void ui_render ( void ) { if ( g_imagecache [ IMG_TAB_SEL ].i && g_imagecache [ IMG_TAB_UNSEL ].i ) { unsigned int tab_width = pnd_conf_get_as_int ( g_conf, "tabs.tab_width" ); unsigned int tab_height = pnd_conf_get_as_int ( g_conf, "tabs.tab_height" ); - unsigned int tab_selheight = pnd_conf_get_as_int ( g_conf, "tabs.tab_selheight" ); + //unsigned int tab_selheight = pnd_conf_get_as_int ( g_conf, "tabs.tab_selheight" ); unsigned int tab_offset_x = pnd_conf_get_as_int ( g_conf, "tabs.tab_offset_x" ); unsigned int tab_offset_y = pnd_conf_get_as_int ( g_conf, "tabs.tab_offset_y" ); unsigned int text_offset_x = pnd_conf_get_as_int ( g_conf, "tabs.text_offset_x" ); @@ -668,8 +673,22 @@ void ui_render ( void ) { iconsurface = ic -> i; } else { //pnd_log ( pndn_warning, "WARNING: TBD: Need Missin-icon icon for '%s'\n", IFNULL(appiter -> ref -> title_en,"No Name") ); - iconsurface = g_imagecache [ IMG_ICON_MISSING ].i; + + // no icon override; was this a pnd-file (show the unknown icon then), or was this generated from + // filesystem (file or directory icon) + if ( appiter -> ref -> object_flags & PND_DISCO_GENERATED ) { + if ( appiter -> ref -> object_type == pnd_object_type_directory ) { + iconsurface = g_imagecache [ IMG_FOLDER ].i; + } else { + iconsurface = g_imagecache [ IMG_EXECBIN ].i; + } + } else { + iconsurface = g_imagecache [ IMG_ICON_MISSING ].i; + } + } + + // got an icon I hope? if ( iconsurface ) { //pnd_log ( pndn_debug, "Got an icon for '%s'\n", IFNULL(appiter -> ref -> title_en,"No Name") ); @@ -1511,7 +1530,88 @@ void ui_push_down ( void ) { void ui_push_exec ( void ) { - if ( ui_selected ) { + if ( ! ui_selected ) { + return; + } + + // was this icon generated from filesystem, or from pnd-file? + if ( ui_selected -> ref -> object_flags & PND_DISCO_GENERATED ) { + + if ( ! ui_selected -> ref -> title_en ) { + return; // no filename + } + + if ( ui_selected -> ref -> object_type == pnd_object_type_directory ) { + // delve up/down the dir tree + + if ( strcmp ( ui_selected -> ref -> title_en, ".." ) == 0 ) { + // go up + char *c; + + // lop off last word; if the thing ends with /, lop that one, then the next word. + while ( ( c = strrchr ( g_categories [ ui_category].fspath, '/' ) ) ) { + *c = '\0'; // lop off the last hunk + if ( *(c+1) != '\0' ) { + break; + } + } // while + + // nothing left? + if ( g_categories [ ui_category].fspath [ 0 ] == '\0' ) { + strcpy ( g_categories [ ui_category].fspath, "/" ); + } + + } else { + // go down + strcat ( g_categories [ ui_category].fspath, "/" ); + strcat ( g_categories [ ui_category].fspath, ui_selected -> ref -> title_en ); + } + + pnd_log ( pndn_debug, "Cat %s is now in path %s\n", g_categories [ ui_category ].catname, g_categories [ ui_category ].fspath ); + + // rescan the dir + category_fs_restock ( &(g_categories [ ui_category]) ); + // forget the selection, nolonger applies + ui_selected = NULL; + ui_set_selected ( ui_selected ); + // redraw the grid + render_mask |= CHANGED_SELECTION; + + } else { + // just run it arbitrarily? + + // if this a pnd-file, or just some executable? + if ( strcasestr ( ui_selected -> ref -> object_filename, PND_PACKAGE_FILEEXT ) ) { + // looks like a pnd, now what do we do.. + pnd_box_handle h = pnd_disco_file ( ui_selected -> ref -> object_path, ui_selected -> ref -> object_filename ); + + if ( h ) { + pnd_disco_t *d = pnd_box_get_head ( h ); + pnd_apps_exec_disco ( pnd_run_script, d, PND_EXEC_OPTION_NORUN, NULL ); + char buffer [ PATH_MAX ]; + sprintf ( buffer, "%s %s\n", MM_RUN, pnd_apps_exec_runline() ); + emit_and_quit ( buffer ); + } + + } else { + // random bin file +#if 1 + char cwd [ PATH_MAX ]; + getcwd ( cwd, PATH_MAX ); + + chdir ( g_categories [ ui_category ].fspath ); + pnd_exec_no_wait_1 ( ui_selected -> ref -> title_en, NULL ); + chdir ( cwd ); +#else + char buffer [ PATH_MAX ]; + sprintf ( buffer, "%s %s/%s\n", MM_RUN, g_categories [ ui_category ].fspath, ui_selected -> ref -> title_en ); + emit_and_quit ( buffer ); +#endif + } // pnd or bin? + + } // dir or file? + + } else { pnd_apps_exec_disco ( pnd_run_script, ui_selected -> ref, PND_EXEC_OPTION_NORUN, NULL ); char buffer [ PATH_MAX ]; sprintf ( buffer, "%s %s\n", MM_RUN, pnd_apps_exec_runline() ); @@ -1526,9 +1626,11 @@ void ui_push_ltrigger ( void ) { if ( ui_category > 0 ) { ui_category--; + category_fs_restock ( &(g_categories [ ui_category ]) ); } else { if ( pnd_conf_get_as_int_d ( g_conf, "tabs.wraparound", 0 ) > 0 ) { ui_category = g_categorycount - 1; + category_fs_restock ( &(g_categories [ ui_category ]) ); } } @@ -1558,9 +1660,11 @@ void ui_push_rtrigger ( void ) { if ( ui_category < ( g_categorycount - 1 ) ) { ui_category++; + category_fs_restock ( &(g_categories [ ui_category ]) ); } else { if ( pnd_conf_get_as_int_d ( g_conf, "tabs.wraparound", 0 ) > 0 ) { ui_category = 0; + category_fs_restock ( &(g_categories [ ui_category ]) ); } } diff --git a/minimenu/mmui.h b/minimenu/mmui.h index d662b50..6afb734 100644 --- a/minimenu/mmui.h +++ b/minimenu/mmui.h @@ -32,6 +32,8 @@ typedef enum { IMG_ARROW_DOWN, IMG_ARROW_SCROLLBAR, IMG_HOURGLASS, + IMG_FOLDER, + IMG_EXECBIN, IMG_MAX, // before this point is loaded; after is generated IMG_TRUEMAX } mm_imgcache_e; diff --git a/minimenu/skin/default/mmskin.conf b/minimenu/skin/default/mmskin.conf index 7e19220..796f465 100644 --- a/minimenu/skin/default/mmskin.conf +++ b/minimenu/skin/default/mmskin.conf @@ -106,3 +106,5 @@ IMG_ARROW_UP arrowup.png IMG_ARROW_DOWN arrowdown.png IMG_ARROW_SCROLLBAR arrowscroller.png IMG_HOURGLASS hourglass.png +IMG_FOLDER /usr/share/icons/gnome/32x32/places/folder.png # in dirbrowser mode +IMG_EXECBIN /usr/share/icons/gnome/32x32/categories/applications-other.png # in dirbrowser mode -- 2.39.2