From: skeezix Date: Wed, 26 Jan 2011 16:31:49 +0000 (-0500) Subject: Rebuilt mmenu 'category' internals so its much more pleasant to work with (internally) X-Git-Tag: sz_beta3~105 X-Git-Url: https://git.openpandora.org/cgi-bin/gitweb.cgi?p=pandora-libraries.git;a=commitdiff_plain;h=3617e64d8e47accd9fcac8270240e90545609000;hp=93dd1323cfea1ac42c9141b22d98361b2c66879b Rebuilt mmenu 'category' internals so its much more pleasant to work with (internally) --- diff --git a/minimenu/mmcat.c b/minimenu/mmcat.c index 241d65a..3a72d46 100644 --- a/minimenu/mmcat.c +++ b/minimenu/mmcat.c @@ -6,6 +6,7 @@ #include #include #include +#include #include "pnd_conf.h" #include "pnd_logger.h" @@ -18,19 +19,26 @@ #include "mmcache.h" #include "mmcat.h" -mm_category_t _categories [ MAX_CATS ]; -mm_category_t *g_categories = _categories; -unsigned char g_categorycount = 0; +// all categories known -- visible, hidden, subcats, whatever. +pnd_box_handle m_categories = NULL; +unsigned int m_categorycount = 0; -mm_category_t _categories_invis [ MAX_CATS ]; -unsigned char _categories_inviscount = 0; +// all categories being published right now -- a subset copied from m_categories +mm_category_t *g_categories [ MAX_CATS ]; +unsigned char g_categorycount; +// category mappings mm_catmap_t g_catmaps [ MAX_CATS ]; 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, char *fspath ) { +void category_init ( void ) { + m_categories = pnd_box_new ( "Schrodinger's cat" ); + return; +} + +unsigned char category_push ( char *catname, pnd_disco_t *app, pnd_conf_handle ovrh, char *fspath, unsigned char visiblep ) { mm_category_t *c; // check category list; if found, append app to the end of it. @@ -42,20 +50,25 @@ unsigned char category_push ( char *catname, pnd_disco_t *app, pnd_conf_handle o // find or create category // - if ( ( c = category_query ( catname ) ) ) { + if ( ( c = pnd_box_find_by_key ( m_categories, catname ) ) ) { // category was found.. } else { // category wasn't found.. //pnd_log ( PND_LOG_DEFAULT, "New category '%s'\n", catname ); - g_categories [ g_categorycount ].catname = strdup ( catname ); - g_categories [ g_categorycount ].refs = NULL; - c = &(g_categories [ g_categorycount ]); + c = pnd_box_allocinsert ( m_categories, catname, sizeof(mm_category_t) ); + c -> catname = strdup ( catname ); + if ( visiblep ) { + c -> catflags = CFNORMAL; + } else { + c -> catflags = CFHIDDEN; + } + c -> refs = NULL; if ( fspath ) { - g_categories [ g_categorycount ].fspath = strdup ( fspath );; + c -> fspath = strdup ( fspath ); } - g_categorycount++; + m_categorycount++; } if ( ! app ) { @@ -88,7 +101,7 @@ unsigned char category_push ( char *catname, pnd_disco_t *app, pnd_conf_handle o while ( iter ) { if ( iter -> ref -> title_en ) { - if ( cat_sort_score ( ar, iter ) < 0 ) { + if ( cat_sort_score ( c, ar, iter ) < 0 ) { // new guy is smaller than the current guy! break; } @@ -125,26 +138,10 @@ unsigned char category_push ( char *catname, pnd_disco_t *app, pnd_conf_handle o return ( 1 ); } -mm_category_t *category_query ( char *catname ) { - unsigned char i; - - for ( i = 0; i < g_categorycount; i++ ) { - - if ( strcasecmp ( g_categories [ i ].catname, catname ) == 0 ) { - return ( &(g_categories [ i ]) ); - } - - } - - return ( NULL ); -} - -int cat_sort_score ( mm_appref_t *s1, mm_appref_t *s2 ) { - - extern unsigned char ui_category; +int cat_sort_score ( mm_category_t *cat, mm_appref_t *s1, mm_appref_t *s2 ) { // are we in a directory browser, or looking at pnd-files? - if ( g_categories [ ui_category ].fspath ) { + if ( cat -> fspath ) { if ( s1 == s2 ) { return ( 0 ); // equal @@ -173,32 +170,41 @@ int cat_sort_score ( mm_appref_t *s1, mm_appref_t *s2 ) { } void category_dump ( void ) { - unsigned int i; // WHY AREN'T I SORTING ON INSERT? // dump - for ( i = 0; i < g_categorycount; i++ ) { - pnd_log ( PND_LOG_DEFAULT, "Category %u: '%s' * %u\n", i, g_categories [ i ].catname, g_categories [ i ].refcount ); - mm_appref_t *ar = g_categories [ i ].refs; + mm_category_t *iter = pnd_box_get_head ( m_categories ); + unsigned int counter = 0; + + while ( iter ) { + + pnd_log ( PND_LOG_DEFAULT, "Category %u: '%s' * %u\n", counter, iter -> catname, iter -> refcount ); + mm_appref_t *ar = iter -> refs; while ( ar ) { pnd_log ( PND_LOG_DEFAULT, " Appref %s\n", IFNULL(ar -> ref -> title_en,"No Name") ); ar = ar -> next; } - } // for + iter = pnd_box_get_next ( iter ); + counter++; + } return; } -static void _category_freeall ( mm_category_t *p, unsigned int c ) { - unsigned int i; +void category_freeall ( void ) { + mm_category_t *c, *cnext; mm_appref_t *iter, *next; - for ( i = 0; i < c; i++ ) { + c = pnd_box_get_head ( m_categories ); + + while ( c ) { + cnext = pnd_box_get_next ( c ); - iter = p [ i ].refs; + // wipe 'em + iter = c -> refs; while ( iter ) { next = iter -> next; @@ -206,30 +212,23 @@ static void _category_freeall ( mm_category_t *p, unsigned int c ) { iter = next; } - p [ i ].refs = NULL; + c -> refs = NULL; - if ( p [ i ].catname ) { - free ( p [ i ].catname ); - p [ i ].catname = NULL; + if ( c -> catname ) { + free ( c -> catname ); + c -> catname = NULL; } - if ( p [ i ].fspath ) { - free ( p [ i ].fspath ); - p [ i ].fspath = NULL; + if ( c -> fspath ) { + free ( c -> fspath ); + c -> fspath = NULL; } - } // for - - return; -} - -void category_freeall ( void ) { - - _category_freeall ( g_categories, g_categorycount ); - _category_freeall ( _categories_invis, _categories_inviscount ); + pnd_box_delete_node ( m_categories, c ); - g_categorycount = 0; - _categories_inviscount = 0; + // next + c = cnext; + } return; } @@ -255,8 +254,8 @@ unsigned char category_map_setup ( void ) { { //pnd_log ( pndn_debug, "target(%s) from(%s)\n", k, buffer ); - category_push ( k, NULL, 0, NULL /* fspath */ ); - g_catmaps [ g_catmapcount ].target = category_query ( k ); + category_push ( k, NULL, 0, NULL /* fspath */, 1 ); + g_catmaps [ g_catmapcount ].target = pnd_box_find_by_key ( m_categories, k ); g_catmaps [ g_catmapcount ].from = strdup ( buffer ); g_catmapcount++; @@ -285,7 +284,6 @@ mm_category_t *category_map_query ( char *cat ) { unsigned char category_meta_push ( char *catname, char *parentcatname, pnd_disco_t *app, pnd_conf_handle ovrh, unsigned char visiblep ) { mm_category_t *cat; - unsigned char catcount = g_categorycount; char catnamebuffer [ 512 ] = ""; if ( ! catname ) { @@ -294,19 +292,10 @@ unsigned char category_meta_push ( char *catname, char *parentcatname, pnd_disco //fprintf ( stderr, "meta push: '%s'\n", catname ); - if ( ! visiblep ) { - //return ( 1 ); // fine, suppress it - - // serious evidence this was a rushed program - g_categories = _categories_invis; - g_categorycount = _categories_inviscount; - - // if invisible, and a parent category name is known, prepend it for ease of use - if ( parentcatname ) { - snprintf ( catnamebuffer, 500, "%s.%s", parentcatname, catname ); - catname = catnamebuffer; - } - + // if invisible, and a parent category name is known, prepend it for ease of use + if ( ! visiblep && parentcatname ) { + snprintf ( catnamebuffer, 500, "%s.%s", parentcatname, catname ); + catname = catnamebuffer; } // do we honour cat mapping at all? @@ -316,31 +305,26 @@ unsigned char category_meta_push ( char *catname, char *parentcatname, pnd_disco cat = category_map_query ( catname ); if ( cat ) { - category_push ( cat -> catname, app, ovrh, NULL /* fspath */ ); - goto visibility_hack_cleanup; + category_push ( cat -> catname, app, ovrh, NULL /* fspath */, visiblep ); + goto meta_done; } // 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 ) { - category_push ( def, app, ovrh, NULL /* fspath */ ); - goto visibility_hack_cleanup; + category_push ( def, app, ovrh, NULL /* fspath */, visiblep ); + goto meta_done; } } } // cat map is desired? // not default, just do it - category_push ( catname, app, ovrh, NULL /* fspath */ ); + category_push ( catname, app, ovrh, NULL /* fspath */, visiblep ); // hack :( - visibility_hack_cleanup: - if ( ! visiblep ) { - _categories_inviscount = g_categorycount; - g_categories = _categories; - g_categorycount = catcount; - } + meta_done: //fprintf ( stderr, "cat meta-push : vis[%30s,%d b] : tally; vis %d invis %d\n", catname, visiblep, g_categorycount, _categories_inviscount ); @@ -427,13 +411,13 @@ unsigned char category_fs_restock ( mm_category_t *cat ) { // found a directory or executable? if ( disco ) { - // register with this category + // register with current 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 */ ); + category_push ( cat -> catname, disco, 0 /* no ovr */, NULL /* fspath already set */, 1 /* visible */ ); // 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 ) ); @@ -452,16 +436,116 @@ unsigned char category_fs_restock ( mm_category_t *cat ) { } static int catname_cmp ( const void *p1, const void *p2 ) { - mm_category_t *c1 = (mm_category_t*) p1; - mm_category_t *c2 = (mm_category_t*) p2; - return ( strcasecmp ( c1 -> catname, c2 -> catname ) ); + //mm_category_t *c1 = (mm_category_t*) p1; + //mm_category_t *c2 = (mm_category_t*) p2; + mm_category_t *c1 = *( (mm_category_t**) p1 ); + mm_category_t *c2 = *( (mm_category_t**) p2 ); + + if ( ( isalnum ( c1 -> catname [ 0 ] ) ) && ( ! isalnum ( c1 -> catname [ 1 ] ) ) ) { + return ( -1 ); + } else if ( ( ! isalnum ( c1 -> catname [ 0 ] ) ) && ( isalnum ( c1 -> catname [ 1 ] ) ) ) { + return ( 1 ); + } else if ( ( ! isalnum ( c1 -> catname [ 0 ] ) ) && ( ! isalnum ( c1 -> catname [ 1 ] ) ) ) { + return ( 0 ); + } + + int i = strcasecmp ( c1 -> catname, c2 -> catname ); + //printf ( "cat name compare %p %s to %p %s = %d\n", p1, c1 -> catname, p2, c2 -> catname, i ); + + return ( i ); } void category_sort ( void ) { // we probably don't want to sort tab categories, since the user may have specified an ordering // But we can sort invisi-cats, to make them easier to find, and ordered by parent category +#if 0 qsort ( _categories_invis, _categories_inviscount, sizeof(mm_category_t), catname_cmp ); +#endif + +#if 1 + qsort ( g_categories, g_categorycount, sizeof(mm_category_t*), catname_cmp ); +#endif return; } + +void category_publish ( unsigned int filter_mask, char *param ) { + unsigned char interested; + + // clear published categories + memset ( g_categories, '\0', sizeof(mm_category_t*) * MAX_CATS ); + g_categorycount = 0; + + // figure out the start + mm_category_t *iter = pnd_box_get_head ( m_categories ); + + // for each category we know... + while ( iter ) { + + interested = 0; + + // is this category desired? + if ( filter_mask == CFALL ) { + interested = 1; + } else if ( iter -> catflags == filter_mask ) { + interested = 1; + } // if + + if ( interested ) { + // set us up the bomb; notice that we're just duplicating the pointers, not making + // any new data here; none of this should ever be free'd! + g_categories [ g_categorycount ] = iter; + g_categorycount++; + } + + // next + iter = pnd_box_get_next ( iter ); + } + + // dump +#if 0 + unsigned int i; + for ( i = 0; i < g_categorycount; i++ ) { + printf ( "Unsorted cat %d %p: %s\n", i, &(g_categories [ i ]), g_categories [ i ] -> catname ); + } +#endif + + // sort published categories + category_sort(); + + return; +} + +unsigned int category_count ( unsigned int filter_mask ) { + mm_category_t *iter = pnd_box_get_head ( m_categories ); + unsigned int count = 0; + + // for each category we know... + while ( iter ) { + + // is this category desired? + if ( iter -> catflags == filter_mask ) { + count++; + } // if + + // next + iter = pnd_box_get_next ( iter ); + } + + return ( count ); +} + +int category_index ( char *catname ) { + unsigned char i; + + for ( i = 0; i < g_categorycount; i++ ) { + + if ( strcasecmp ( g_categories [ i ] -> catname, catname ) == 0 ) { + return ( i ); + } + + } + + return ( -1 ); +} diff --git a/minimenu/mmcat.h b/minimenu/mmcat.h index a1f8142..c886f2d 100644 --- a/minimenu/mmcat.h +++ b/minimenu/mmcat.h @@ -2,6 +2,11 @@ #ifndef h_mmcat_h #define h_mmcat_h +/* code for storing/retrieving/messing with 'categories' (ie: tabs, more or less) + */ + +// an appreg is a minimenu registered app, that in turn points to the libpnd disco-t entry, but also stores anything +// minimenu specific about it. typedef struct _mm_appref_t { pnd_disco_t *ref; pnd_conf_handle ovrh; @@ -9,26 +14,38 @@ typedef struct _mm_appref_t { struct _mm_appref_t *next; } mm_appref_t; -typedef struct { +// an actual category reference; points to a list of appref's and supplies a tabname, a filesystem mountpoint, etc. +typedef struct _mm_category_t { char *catname; // name of the category + unsigned int catflags; // flags + // 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 (so that refs can point to here) + } mm_category_t; -#define MAX_CATS 200 +// the flags available for the above mm_category_t.catflags +#define CFNORMAL 1 // catflag +#define CFHIDDEN 2 // catflag: 1, 2, 4,... +#define CFSUBCAT 4 // catflag + +// how many cats can we handle? +#define MAX_CATS 250 +// what do we call the "All" tab, if present #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, 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_init ( void ); // set up; call first! +unsigned char category_push ( char *catname, pnd_disco_t *app, pnd_conf_handle ovrh, char *fspath, unsigned char visiblep ); // catname is not pulled from app, so we can make them up on the fly (ie: "All"); 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 +int cat_sort_score ( mm_category_t *cat, mm_appref_t *s1, mm_appref_t *s2 ); // like strcmp, but used to sort apps by title void category_sort ( void ); // for sorting categories // category mapping hack @@ -44,4 +61,14 @@ unsigned char category_meta_push ( char *catname, char *parentcatname, pnd_disco // filesystem browser unsigned char category_fs_restock ( mm_category_t *cat ); +// advertising to rest of the system +// +extern mm_category_t *g_categories [ MAX_CATS ]; +extern unsigned char g_categorycount; +#define CFALL 0xFF // filter mask +#define CFBYNAME 0xFE // filter mask; the name param is used to pick a single category to populate +void category_publish ( unsigned int filter_mask, char *param ); // populates g_categories and g_categorycount; pass in CFNORMAL or CFHIDDEN or CFALL or whatever +unsigned int category_count ( unsigned int filter_mask ); +int category_index ( char *catname ); // figure out index in g_categories of named cat + #endif diff --git a/minimenu/mmconf.c b/minimenu/mmconf.c index 0923a34..b25ec9c 100644 --- a/minimenu/mmconf.c +++ b/minimenu/mmconf.c @@ -70,10 +70,6 @@ confitem_t pages[] = { extern pnd_conf_handle g_conf; extern SDL_Surface *sdl_realscreen; extern mm_imgcache_t g_imagecache [ IMG_TRUEMAX ]; -extern mm_category_t *g_categories; -extern unsigned char g_categorycount; -extern mm_category_t _categories_invis [ MAX_CATS ]; -extern unsigned char _categories_inviscount; extern pnd_box_handle g_active_apps; unsigned char conf_run_menu ( confitem_t *toplevel ) { @@ -179,21 +175,21 @@ unsigned char conf_run_menu ( confitem_t *toplevel ) { if ( v ) { unsigned char n = 0; for ( n = 0; n < g_categorycount; n++ ) { - if ( strcmp ( v, g_categories [ n ].catname ) == 0 ) { + if ( strcmp ( v, g_categories [ n ] -> catname ) == 0 ) { break; } } if ( n < g_categorycount ) { if ( left && n ) { - pnd_conf_set_char ( g_conf, page [ sel ].key, g_categories [ n - 1 ].catname ); + pnd_conf_set_char ( g_conf, page [ sel ].key, g_categories [ n - 1 ] -> catname ); } else if ( ! left && n + 1 < g_categorycount ) { - pnd_conf_set_char ( g_conf, page [ sel ].key, g_categories [ n + 1 ].catname ); + pnd_conf_set_char ( g_conf, page [ sel ].key, g_categories [ n + 1 ] -> catname ); } } else { - pnd_conf_set_char ( g_conf, page [ sel ].key, g_categories [ 0 ].catname ); + pnd_conf_set_char ( g_conf, page [ sel ].key, g_categories [ 0 ] -> catname ); } } else { - pnd_conf_set_char ( g_conf, page [ sel ].key, g_categories [ 0 ].catname ); + pnd_conf_set_char ( g_conf, page [ sel ].key, g_categories [ 0 ] -> catname ); } } // if category count } @@ -564,60 +560,52 @@ unsigned char conf_prepare_page ( confitem_t *page ) { template -> text = ""; // so it won't get repopulated again later - typedef struct { - mm_category_t *cat; - unsigned char n; - } _foo; - _foo cats [ 2 ]; - cats [ 0 ].cat = g_categories; - cats [ 0 ].n = g_categorycount; - cats [ 1 ].cat = _categories_invis; - cats [ 1 ].n = _categories_inviscount; + // switch categories being published + category_publish ( CFALL, NULL ); // for each tab - unsigned int i, j; - for ( j = 0; j < 2; j++ ) { - mm_category_t *cc = cats [ j ].cat; - unsigned char cn = cats [ j ].n; - char catname [ 512 ]; - char *actual_catname; - - for ( i = 0; i < cn; i++ ) { - - // if this is an invisi-guy, it has parent-cat prepended; we want the real cat name. - strncpy ( catname, cc [ i ].catname, 500 ); - if ( ( actual_catname = strchr ( catname, '.' ) ) ) { - actual_catname++; // skip the period - } else { - actual_catname = catname; - } - //fprintf ( stderr, "conf ui; got '%s' but showing '%s'\n", cc [ i ].catname, actual_catname ); + unsigned int i; + char catname [ 512 ]; + char *actual_catname; - if ( strncmp ( cc [ i ].catname, "All ", 4 ) == 0 ) { - // skip All tab, since it is generated, and managed by another config item - continue; - } + for ( i = 0; i < g_categorycount; i++ ) { - p -> text = strndup ( actual_catname, 40 ); - p -> desc = NULL; - p -> def = NULL; + // if this is an invisi-guy, it has parent-cat prepended; we want the real cat name. + strncpy ( catname, g_categories [ i ] -> catname, 500 ); - sprintf ( buffer, "%s.%s", template -> key, actual_catname ); - p -> key = strdup ( buffer ); - p -> type = ct_boolean; - p -> newhead = NULL; + if ( ( actual_catname = strchr ( catname, '.' ) ) ) { + actual_catname++; // skip the period + } else { + actual_catname = catname; + } + //fprintf ( stderr, "conf ui; got '%s' but showing '%s'\n", cc [ i ].catname, actual_catname ); - // create to positive if not existant - if ( ! pnd_conf_get_as_char ( g_conf, buffer ) ) { - pnd_conf_set_char ( g_conf, buffer, "1" ); - } + if ( strncmp ( g_categories [ i ] -> catname, "All ", 4 ) == 0 ) { + // skip All tab, since it is generated, and managed by another config item + continue; + } + + p -> text = strndup ( actual_catname, 40 ); + p -> desc = NULL; + p -> def = NULL; - //fprintf ( stderr, "Created tabshow entry '%s'\n", cc [ i ].catname ); + sprintf ( buffer, "%s.%s", template -> key, actual_catname ); + p -> key = strdup ( buffer ); + p -> type = ct_boolean; + p -> newhead = NULL; - p++; + // create to positive if not existant + if ( ! pnd_conf_get_as_char ( g_conf, buffer ) ) { + pnd_conf_set_char ( g_conf, buffer, "1" ); } - } + //fprintf ( stderr, "Created tabshow entry '%s'\n", cc [ i ].catname ); + + p++; + } // for + + // switch categories being published + category_publish ( CFNORMAL, NULL ); break; } diff --git a/minimenu/mmenu.c b/minimenu/mmenu.c index 0d427a9..0709a31 100644 --- a/minimenu/mmenu.c +++ b/minimenu/mmenu.c @@ -355,9 +355,12 @@ int main ( int argc, char *argv[] ) { emit_and_quit ( MM_QUIT ); } + // init categories + category_init(); + // 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 /*app*/, 0, NULL /* fspath */ ); + category_push ( g_x11_present ? CATEGORY_ALL " (X11)" : CATEGORY_ALL " (No X11)", NULL /*app*/, 0, NULL /* fspath */, 1 /* visible */ ); } // set up category mappings @@ -670,7 +673,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 ) ) { - category_push ( g_x11_present ? CATEGORY_ALL " (X11)" : CATEGORY_ALL " (No X11)", iter, ovrh, NULL /* fspath */ ); + category_push ( g_x11_present ? CATEGORY_ALL " (X11)" : CATEGORY_ALL " (No X11)", iter, ovrh, NULL /* fspath */, 1 /* visible */ ); } // all? // is this app suppressed? if not, show it in whatever categories the user is allowing @@ -696,9 +699,6 @@ void applications_scan ( void ) { itercount++; } // while - // sort (some) categories - category_sort(); - // 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" ); @@ -715,7 +715,7 @@ void applications_scan ( void ) { // 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 */ ); + category_push ( tabname /* tab name */, NULL /* app */, 0 /* override */, buffer /* fspath */, 1 /* visible */ ); } } @@ -726,6 +726,9 @@ void applications_scan ( void ) { // dump categories //category_dump(); + // publish desired categories + category_publish ( CFNORMAL, NULL ); + // let deferred icon cache go now ui_post_scan(); diff --git a/minimenu/mmui.c b/minimenu/mmui.c index a43797a..ebfe706 100644 --- a/minimenu/mmui.c +++ b/minimenu/mmui.c @@ -81,11 +81,6 @@ ui_context_t ui_display_context; // display paramaters: see mmui_context. unsigned char ui_detail_hidden = 0; // if >0, detail panel is hidden // FUTURE: If multiple panels can be shown/hidden, convert ui_detail_hidden to a bitmask -extern mm_category_t *g_categories; -extern unsigned char g_categorycount; -extern mm_category_t _categories_invis [ MAX_CATS ]; -extern unsigned char _categories_inviscount; - static SDL_Surface *ui_scale_image ( SDL_Surface *s, unsigned int maxwidth, int maxheight ); // height -1 means ignore static int ui_selected_index ( void ); @@ -344,15 +339,15 @@ void ui_render ( void ) { ui_context_t *c = &ui_display_context; // for convenience and shorthand // how many total rows do we need? - icon_rows = g_categories [ ui_category ].refcount / c -> col_max; - if ( g_categories [ ui_category ].refcount % c -> col_max > 0 ) { + icon_rows = g_categories [ ui_category ] -> refcount / c -> col_max; + if ( g_categories [ ui_category ] -> refcount % c -> col_max > 0 ) { icon_rows++; } #if 1 // if no selected app yet, select the first one if ( ! ui_selected && pnd_conf_get_as_int_d ( g_conf, "minimenu.start_selected", 0 ) ) { - ui_selected = g_categories [ ui_category ].refs; + ui_selected = g_categories [ ui_category ] -> refs; } #endif @@ -518,7 +513,7 @@ void ui_render ( void ) { // draw text SDL_Surface *rtext; - rtext = TTF_RenderText_Blended ( g_tab_font, g_categories [ col ].catname, c -> fontcolor ); + rtext = TTF_RenderText_Blended ( g_tab_font, g_categories [ col ] -> catname, c -> fontcolor ); src.x = 0; src.y = 0; src.w = rtext -> w < text_width ? rtext -> w : text_width; @@ -646,9 +641,9 @@ void ui_render ( void ) { } } - if ( g_categories [ ui_category ].refs ) { + if ( g_categories [ ui_category ] -> refs ) { - appiter = g_categories [ ui_category ].refs; + appiter = g_categories [ ui_category ] -> refs; row = 0; displayrow = 0; @@ -1343,8 +1338,8 @@ void ui_process_input ( unsigned char block_p ) { // many SDLK_keycodes map to ASCII ("a" is ascii(a)), so try to jump to a filename of that name, in this category? // and if already there, try to jump to next, maybe? // future: look for sequence typing? ie: user types 'm' then 'a', look for 'ma*' instead of 'm' then 'a' matching - if ( isalpha ( event.key.keysym.sym ) && g_categories [ ui_category ].refcount > 0 ) { - mm_appref_t *app = g_categories [ ui_category ].refs; + if ( isalpha ( event.key.keysym.sym ) && g_categories [ ui_category ] -> refcount > 0 ) { + mm_appref_t *app = g_categories [ ui_category ] -> refs; //fprintf ( stderr, "sel %s next %s\n", ui_selected -> ref -> title_en, ui_selected -> next -> ref -> title_en ); @@ -1447,12 +1442,12 @@ void ui_push_left ( unsigned char forcecoil ) { i--; } - } else if ( g_categories [ ui_category ].refs == ui_selected ) { + } else if ( g_categories [ ui_category ] -> refs == ui_selected ) { // can't go any more left, we're at the head } else { // figure out the previous item; yay for singly linked list :/ - mm_appref_t *i = g_categories [ ui_category ].refs; + mm_appref_t *i = g_categories [ ui_category ] -> refs; while ( i ) { if ( i -> next == ui_selected ) { ui_selected = i; @@ -1499,7 +1494,7 @@ void ui_push_right ( unsigned char forcecoil ) { } } else { - ui_selected = g_categories [ ui_category ].refs; + ui_selected = g_categories [ ui_category ] -> refs; } ui_set_selected ( ui_selected ); @@ -1525,7 +1520,7 @@ void ui_push_up ( void ) { unsigned int col = ui_determine_screen_col ( ui_selected ); // go to end - ui_selected = g_categories [ ui_category ].refs; + ui_selected = g_categories [ ui_category ] -> refs; while ( ui_selected -> next ) { ui_selected = ui_selected -> next; } @@ -1568,8 +1563,8 @@ void ui_push_down ( void ) { unsigned int row = ui_determine_row ( ui_selected ); // max rows? - unsigned int icon_rows = g_categories [ ui_category ].refcount / col_max; - if ( g_categories [ ui_category ].refcount % col_max > 0 ) { + unsigned int icon_rows = g_categories [ ui_category ] -> refcount / col_max; + if ( g_categories [ ui_category ] -> refcount % col_max > 0 ) { icon_rows++; } @@ -1580,7 +1575,7 @@ void ui_push_down ( void ) { unsigned char col = ui_determine_screen_col ( ui_selected ); - ui_selected = g_categories [ ui_category ].refs; + ui_selected = g_categories [ ui_category ] -> refs; while ( col ) { ui_selected = ui_selected -> next; @@ -1628,7 +1623,7 @@ void ui_push_exec ( void ) { 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, '/' ) ) ) { + while ( ( c = strrchr ( g_categories [ ui_category] -> fspath, '/' ) ) ) { *c = '\0'; // lop off the last hunk if ( *(c+1) != '\0' ) { break; @@ -1636,27 +1631,26 @@ void ui_push_exec ( void ) { } // while // nothing left? - if ( g_categories [ ui_category].fspath [ 0 ] == '\0' ) { - strcpy ( g_categories [ ui_category].fspath, "/" ); + if ( g_categories [ ui_category] -> fspath [ 0 ] == '\0' ) { + free ( g_categories [ ui_category] -> fspath ); + g_categories [ ui_category] -> fspath = strdup ( "/" ); } } else { // go down - char *temp = malloc ( strlen ( g_categories [ ui_category].fspath ) + strlen ( ui_selected -> ref -> title_en ) + 1 + 1 ); - sprintf ( temp, "%s/%s", g_categories [ ui_category].fspath, ui_selected -> ref -> title_en ); - free ( g_categories [ ui_category].fspath ); - g_categories [ ui_category].fspath = temp; - //strcat ( g_categories [ ui_category].fspath, "/" ); - //strcat ( g_categories [ ui_category].fspath, ui_selected -> ref -> title_en ); + char *temp = malloc ( strlen ( g_categories [ ui_category] -> fspath ) + strlen ( ui_selected -> ref -> title_en ) + 1 + 1 ); + sprintf ( temp, "%s/%s", g_categories [ ui_category] -> fspath, ui_selected -> ref -> title_en ); + free ( g_categories [ ui_category] -> fspath ); + g_categories [ ui_category] -> fspath = temp; } - pnd_log ( pndn_debug, "Cat %s is now in path %s\n", g_categories [ ui_category ].catname, g_categories [ ui_category ].fspath ); + pnd_log ( pndn_debug, "Cat %s is now in path %s\n", g_categories [ ui_category ] -> catname, g_categories [ ui_category ]-> fspath ); // forget the selection, nolonger applies ui_selected = NULL; ui_set_selected ( ui_selected ); // rescan the dir - category_fs_restock ( &(g_categories [ ui_category ]) ); + category_fs_restock ( g_categories [ ui_category ] ); // redraw the grid render_mask |= CHANGED_SELECTION; @@ -1695,7 +1689,7 @@ void ui_push_exec ( void ) { // popen test { char popenbuf [ FILENAME_MAX ]; - snprintf ( popenbuf, FILENAME_MAX, "%s %s/%s", MIMETYPE_EXE, g_categories [ ui_category ].fspath, ui_selected -> ref -> title_en ); + snprintf ( popenbuf, FILENAME_MAX, "%s %s/%s", MIMETYPE_EXE, g_categories [ ui_category ] -> fspath, ui_selected -> ref -> title_en ); FILE *marceau; if ( ! ( marceau = popen ( popenbuf, "r" ) ) ) { @@ -1738,17 +1732,17 @@ void ui_push_exec ( void ) { // full path to executable so we don't rely on implicit "./" char execbuf [ FILENAME_MAX ]; - snprintf ( execbuf, FILENAME_MAX, "%s/%s", g_categories [ ui_category ].fspath, ui_selected -> ref -> title_en ); + snprintf ( execbuf, FILENAME_MAX, "%s/%s", g_categories [ ui_category ] -> fspath, ui_selected -> ref -> title_en ); // do it! - chdir ( g_categories [ ui_category ].fspath ); + chdir ( g_categories [ ui_category ] -> fspath ); exec_raw_binary ( execbuf /*ui_selected -> ref -> title_en*/ ); chdir ( cwd ); #else // DEPRECATED / NOT TESTED // get mmwrapper to run it char buffer [ PATH_MAX ]; - sprintf ( buffer, "%s %s/%s\n", MM_RUN, g_categories [ ui_category ].fspath, ui_selected -> ref -> title_en ); + sprintf ( buffer, "%s %s/%s\n", MM_RUN, g_categories [ ui_category ] -> fspath, ui_selected -> ref -> title_en ); if ( pnd_conf_get_as_int_d ( g_conf, "minimenu.live_on_run", 0 ) == 0 ) { emit_and_quit ( buffer ); } else { @@ -1797,7 +1791,7 @@ void ui_push_ltrigger ( void ) { if ( ui_category > 0 ) { ui_category--; - category_fs_restock ( &(g_categories [ 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; @@ -1805,7 +1799,7 @@ void ui_push_ltrigger ( void ) { if ( ui_category >= ( screen_width / tab_width ) ) { ui_catshift = ui_category - ( screen_width / tab_width ) + 1; } - category_fs_restock ( &(g_categories [ ui_category ]) ); + category_fs_restock ( g_categories [ ui_category ] ); } } @@ -1839,12 +1833,12 @@ void ui_push_rtrigger ( void ) { if ( ui_category < ( g_categorycount - 1 ) ) { ui_category++; - category_fs_restock ( &(g_categories [ 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; ui_catshift = 0; - category_fs_restock ( &(g_categories [ ui_category ]) ); + category_fs_restock ( g_categories [ ui_category ] ); } } @@ -2050,7 +2044,7 @@ int ui_selected_index ( void ) { return ( -1 ); // no index } - mm_appref_t *r = g_categories [ ui_category ].refs; + mm_appref_t *r = g_categories [ ui_category ] -> refs; int counter = 0; while ( r ) { if ( r == ui_selected ) { @@ -2257,7 +2251,7 @@ int ui_modal_single_menu ( char *argv[], unsigned int argc, char *title, char *f unsigned char ui_determine_row ( mm_appref_t *a ) { unsigned int row = 0; - mm_appref_t *i = g_categories [ ui_category ].refs; + mm_appref_t *i = g_categories [ ui_category ] -> refs; while ( i != a ) { i = i -> next; row++; @@ -2274,7 +2268,7 @@ unsigned char ui_determine_screen_row ( mm_appref_t *a ) { unsigned char ui_determine_screen_col ( mm_appref_t *a ) { unsigned int col = 0; - mm_appref_t *i = g_categories [ ui_category ].refs; + mm_appref_t *i = g_categories [ ui_category ] -> refs; while ( i != a ) { i = i -> next; col++; @@ -2435,7 +2429,7 @@ void ui_touch_act ( unsigned int x, unsigned int y ) { ui_category = t -> catnum; render_mask |= CHANGED_CATEGORY; // rescan the dir - category_fs_restock ( &(g_categories [ ui_category ]) ); + category_fs_restock ( g_categories [ ui_category ] ); } break; @@ -2515,7 +2509,7 @@ void ui_post_scan ( void ) { // default behaviour will pick first cat (ie: usually All) unsigned int i; for ( i = 0; i < g_categorycount; i++ ) { - if ( strcasecmp ( g_categories [ i ].catname, dc ) == 0 ) { + if ( strcasecmp ( g_categories [ i ] -> catname, dc ) == 0 ) { ui_category = i; // ensure visibility unsigned int screen_width = ui_display_context.screen_width; @@ -2533,6 +2527,12 @@ void ui_post_scan ( void ) { } // default cat + // if we're sent right to a dirbrowser tab, restock it now (normally we restock on entry) + if ( g_categories [ ui_category ] -> fspath ) { + printf ( "Restock on start: '%s'\n", g_categories [ ui_category ] -> fspath ); + category_fs_restock ( g_categories [ ui_category ] ); + } + // redraw all render_mask |= CHANGED_EVERYTHING; @@ -2894,40 +2894,43 @@ void ui_revealscreen ( void ) { unsigned int labelmax = 0; unsigned int i; - if ( ! _categories_inviscount ) { + if ( ! category_count ( CFHIDDEN ) ) { return; // nothing to do } - for ( i = 0; i < _categories_inviscount; i++ ) { - labels [ labelmax++ ] = _categories_invis [ i ].catname; + // switch to hidden categories + category_publish ( CFHIDDEN, NULL ); + + // build up labels to show in menu + for ( i = 0; i < g_categorycount; i++ ) { + labels [ labelmax++ ] = g_categories [ i ] -> catname; } + // show menu int sel = ui_modal_single_menu ( labels, labelmax, "Temporary Category Reveal", "Enter to select; other to return." ); + // if selected, try to set this guy to visible if ( sel >= 0 ) { - if ( category_query ( _categories_invis [ sel ].catname ) ) { - // already present - return; - } - // fix up category name, if its been hacked - if ( strchr ( _categories_invis [ sel ].catname, '.' ) ) { - char *t = _categories_invis [ sel ].catname; - _categories_invis [ sel ].catname = strdup ( strchr ( _categories_invis [ sel ].catname, '.' ) + 1 ); + if ( strchr ( g_categories [ sel ] -> catname, '.' ) ) { + char *t = g_categories [ sel ] -> catname; + g_categories [ sel ] -> catname = strdup ( strchr ( g_categories [ sel ] -> catname, '.' ) + 1 ); free ( t ); } - // copy invisi-cat into live-cat - memmove ( &(g_categories [ g_categorycount ]), &(_categories_invis [ sel ]), sizeof(mm_category_t) ); - g_categorycount++; - // move subsequent invisi-cats up, so the selected invisi-cat is nolonger existing in invisi-list at - // all (avoid double-free() later) - memmove ( &(_categories_invis [ sel ]), &(_categories_invis [ sel + 1 ]), sizeof(mm_category_t) * ( _categories_inviscount - sel - 1 ) ); - _categories_inviscount--; - - // switch to the new category - ui_category = g_categorycount - 1; + + // reflag this guy to be visible + g_categories [ sel ] -> catflags = CFNORMAL; + + // switch to the new category.. cache name. + char *switch_to_name = g_categories [ sel ] -> catname; + + // republish categories + category_publish ( CFNORMAL, NULL ); + + // switch to the new category.. with the cached name! + ui_category = category_index ( switch_to_name ); // ensure visibility unsigned int screen_width = ui_display_context.screen_width;