#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
+#include <ctype.h>
#include "pnd_conf.h"
#include "pnd_logger.h"
#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.
// 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 ) {
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;
}
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
}
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;
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;
}
{
//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++;
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 ) {
//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?
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 );
// 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 ) );
}
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 );
+}
#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;
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
// 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
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 ) {
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
}
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;
}
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
// 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
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" );
// 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 */ );
}
}
// dump categories
//category_dump();
+ // publish desired categories
+ category_publish ( CFNORMAL, NULL );
+
// let deferred icon cache go now
ui_post_scan();
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 );
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
// 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;
}
}
- 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;
// 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 );
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;
}
} else {
- ui_selected = g_categories [ ui_category ].refs;
+ ui_selected = g_categories [ ui_category ] -> refs;
}
ui_set_selected ( ui_selected );
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;
}
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++;
}
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;
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;
} // 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;
// 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" ) ) ) {
// 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 {
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;
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 ] );
}
}
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 ] );
}
}
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 ) {
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++;
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++;
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;
// 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;
} // 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;
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;