X-Git-Url: http://git.cinelerra-gg.org/git/?a=blobdiff_plain;f=cinelerra-5.1%2Fguicast%2Fbctheme.C;h=c206f258af27131ab8e8dd0a3e1d12a3812444ef;hb=HEAD;hp=8268620fec8e6da95d73a2b6ac3a7891c8518428;hpb=30bdb85eb33a8ee7ba675038a86c6be59c43d7bd;p=goodguy%2Fhistory.git diff --git a/cinelerra-5.1/guicast/bctheme.C b/cinelerra-5.1/guicast/bctheme.C index 8268620f..c206f258 100644 --- a/cinelerra-5.1/guicast/bctheme.C +++ b/cinelerra-5.1/guicast/bctheme.C @@ -32,24 +32,29 @@ BC_Theme::BC_Theme() { - data_ptr = 0; - contents_ptr = 0; - last_image = 0; - last_pointer = 0; + last_image_data = 0; + last_image_set = 0; + image_sets_start = -1; } BC_Theme::~BC_Theme() { image_sets.remove_all_objects(); + images.remove_all_objects(); } void BC_Theme::dump() { - printf("BC_Theme::dump 1 image_sets=%d contents=%d\n", - image_sets.total, - contents.total); - for(int i = 0; i < contents.total; i++) - printf(" %s %p\n", contents.values[i], pointers.values[i]); + printf("BC_Theme::dump 1 images=%d\n", images.size()); + for( int i=0; iname, image_data->data); + } + printf("BC_Theme::dump 2 image_sets=%d\n", image_sets.size()); + for( int i=0; ititle, image_set->data[0]); + } } BC_Resources* BC_Theme::get_resources() @@ -61,11 +66,11 @@ BC_Resources* BC_Theme::get_resources() VFrame* BC_Theme::new_image(const char *title, const char *path) { VFrame *existing_image = title[0] ? get_image(title, 0) : 0; - if(existing_image) return existing_image; + if( existing_image ) return existing_image; BC_ThemeSet *result = new BC_ThemeSet(1, 0, title); result->data[0] = new VFramePng(get_image_data(path)); - image_sets.append(result); + add_image_set(result); return result->data[0]; } @@ -74,25 +79,20 @@ VFrame* BC_Theme::new_image(const char *path) return new_image("", path); } - - // These create image sets which are stored in the image_sets table. VFrame** BC_Theme::new_image_set(const char *title, int total, va_list *args) { - if(!total) - { + if( !total ) { printf("BC_Theme::new_image_set %d %s zero number of images\n", - __LINE__, - title); + __LINE__, title); } VFrame **existing_image_set = title[0] ? get_image_set(title, 0) : 0; - if(existing_image_set) return existing_image_set; + if( existing_image_set ) return existing_image_set; BC_ThemeSet *result = new BC_ThemeSet(total, 1, title); - image_sets.append(result); - for(int i = 0; i < total; i++) - { + add_image_set(result); + for( int i=0; idata[i] = new_image(path); } @@ -104,15 +104,15 @@ VFrame** BC_Theme::new_image_set_images(const char *title, int total, ...) va_list list; va_start(list, total); BC_ThemeSet *existing_image_set = title[0] ? get_image_set_object(title) : 0; - if(existing_image_set) - { + if( existing_image_set ) { image_sets.remove_object(existing_image_set); + last_image_set = 0; + last_image_data = 0; } BC_ThemeSet *result = new BC_ThemeSet(total, 0, title); - image_sets.append(result); - for(int i = 0; i < total; i++) - { + add_image_set(result); + for( int i=0; idata[i] = va_arg(list, VFrame*); } va_end(list); @@ -139,21 +139,64 @@ VFrame** BC_Theme::new_image_set(int total, ...) return result; } +void BC_Theme::add_image_set(BC_ThemeSet *image_set) +{ + image_sets.append(image_set); + if( image_sets_start >= 0 ) { + printf("BC_Theme::add_image_set image_sets unsorted, lookups degraded\n"); + image_sets_start = -1; + } +} + +int BC_Theme::image_set_cmpr(const void *ap, const void *bp) +{ + BC_ThemeSet*a = *(BC_ThemeSet**)ap, *b = *(BC_ThemeSet**)bp; + return strcmp(a->title, b->title); +} + +void BC_Theme::sort_image_sets() +{ + if( image_sets_start >= 0 ) return; + qsort(&image_sets[0], image_sets.size(), sizeof(image_sets[0]), image_set_cmpr); +// skip over un-titled image sets + int i = 0, n = image_sets.size(); + while( ititle[0] ) ++i; + image_sets_start = i; +} + BC_ThemeSet* BC_Theme::get_image_set_object(const char *title) { + if( last_image_set && !strcmp(title,last_image_set->title) ) + return last_image_set; + + if( image_sets_start >= 0 ) { +// binary search for image set + int r = image_sets.size(), l = image_sets_start-1; + int m = 0, v = -1; + while( r-l > 1 ) { + m = (l + r) / 2; + BC_ThemeSet *image_set = image_sets[m]; + if( !(v=strcmp(title, image_set->title)) ) + return last_image_set = image_set; + if( v > 0 ) l = m; else r = m; + } + } + else { // compare title[0],title[1] for faster prefix test - const unsigned char *bp = (const unsigned char*)title; - unsigned short tval = bp[0]; - if( tval ) tval |= (bp[1] << 8); - - for( int i=0; i < image_sets.total; ++i ) { - const char *tp = image_sets[i]->title; - bp = (const unsigned char *) tp; - unsigned short val = bp[0]; - if( val ) val |= (bp[1] << 8); - if( val != tval ) continue; - if( !strcmp(tp, title) ) return image_sets[i]; + const unsigned char *tp = (const unsigned char*)title; + unsigned short tval = tp[0]; + if( tval ) tval |= (tp[1] << 8); + + for( int i=0; ititle; + unsigned short val = tp[0]; + if( val ) val |= (tp[1] << 8); + if( val != tval ) continue; + if( !strcmp((const char *)tp, title) ) + return last_image_set = image_sets[i]; + } } + return 0; } @@ -164,10 +207,10 @@ VFrame* BC_Theme::get_image(const char *title, int use_default) // Return the first image it can find. This should always work. - if(use_default) { + if( use_default ) { printf("BC_Theme::get_image: image \"%s\" not found.\n", title); - if(image_sets.total) + if( image_sets.size() ) return image_sets[0]->data[0]; } @@ -181,22 +224,19 @@ VFrame** BC_Theme::get_image_set(const char *title, int use_default) if( tsp ) return tsp->data; // Get the image set with the largest number of images. - if(use_default) - { + if( use_default ) { printf("BC_Theme::get_image_set: image set \"%s\" not found.\n", title); int max_total = 0; int max_number = -1; - for(int i = 0; i < image_sets.total; i++) - { - if(image_sets[i]->total > max_total) - { + for( int i=0; itotal > max_total ) { max_total = image_sets[i]->total; max_number = i; } } - if(max_number >= 0) + if( max_number >= 0 ) return image_sets[max_number]->data; } @@ -214,51 +254,49 @@ VFrame** BC_Theme::get_image_set(const char *title, int use_default) -VFrame** BC_Theme::new_button(const char *overlay_path, - const char *up_path, - const char *hi_path, +VFrame** BC_Theme::new_button(const char *overlay_path, + const char *up_path, + const char *hi_path, const char *dn_path, const char *title) { VFramePng default_data(get_image_data(overlay_path)); BC_ThemeSet *result = new BC_ThemeSet(3, 1, title ? title : ""); - if(title) image_sets.append(result); + if( title ) add_image_set(result); result->data[0] = new_image(up_path); result->data[1] = new_image(hi_path); result->data[2] = new_image(dn_path); - for(int i = 0; i < 3; i++) - { + for( int i=0; i<3; ++i ) { overlay(result->data[i], &default_data, -1, -1, (i == 2)); } return result->data; } -VFrame** BC_Theme::new_button4(const char *overlay_path, - const char *up_path, - const char *hi_path, +VFrame** BC_Theme::new_button4(const char *overlay_path, + const char *up_path, + const char *hi_path, const char *dn_path, const char *disabled_path, const char *title) { VFramePng default_data(get_image_data(overlay_path)); BC_ThemeSet *result = new BC_ThemeSet(4, 1, title ? title : ""); - if(title) image_sets.append(result); + if( title ) add_image_set(result); result->data[0] = new_image(up_path); result->data[1] = new_image(hi_path); result->data[2] = new_image(dn_path); result->data[3] = new_image(disabled_path); - for(int i = 0; i < 4; i++) - { + for( int i=0; i<4; ++i ) { overlay(result->data[i], &default_data, -1, -1, (i == 2)); } return result->data; } -VFrame** BC_Theme::new_button(const char *overlay_path, +VFrame** BC_Theme::new_button(const char *overlay_path, VFrame *up, VFrame *hi, VFrame *dn, @@ -266,18 +304,18 @@ VFrame** BC_Theme::new_button(const char *overlay_path, { VFramePng default_data(get_image_data(overlay_path)); BC_ThemeSet *result = new BC_ThemeSet(3, 0, title ? title : ""); - if(title) image_sets.append(result); + if( title ) add_image_set(result); result->data[0] = new VFrame(*up); result->data[1] = new VFrame(*hi); result->data[2] = new VFrame(*dn); - for(int i = 0; i < 3; i++) + for( int i=0; i<3; ++i ) overlay(result->data[i], &default_data, -1, -1, (i == 2)); return result->data; } -VFrame** BC_Theme::new_toggle(const char *overlay_path, +VFrame** BC_Theme::new_toggle(const char *overlay_path, const char *up_path, const char *hi_path, const char *checked_path, @@ -287,19 +325,19 @@ VFrame** BC_Theme::new_toggle(const char *overlay_path, { VFramePng default_data(get_image_data(overlay_path)); BC_ThemeSet *result = new BC_ThemeSet(5, 1, title ? title : ""); - if(title) image_sets.append(result); + if( title ) add_image_set(result); result->data[0] = new_image(up_path); result->data[1] = new_image(hi_path); result->data[2] = new_image(checked_path); result->data[3] = new_image(dn_path); result->data[4] = new_image(checkedhi_path); - for(int i = 0; i < 5; i++) + for( int i=0; i<5; ++i ) overlay(result->data[i], &default_data, -1, -1, (i == 3)); return result->data; } -VFrame** BC_Theme::new_toggle(const char *overlay_path, +VFrame** BC_Theme::new_toggle(const char *overlay_path, VFrame *up, VFrame *hi, VFrame *checked, @@ -309,14 +347,14 @@ VFrame** BC_Theme::new_toggle(const char *overlay_path, { VFramePng default_data(get_image_data(overlay_path)); BC_ThemeSet *result = new BC_ThemeSet(5, 0, title ? title : ""); - if(title) image_sets.append(result); + if( title ) add_image_set(result); result->data[0] = new VFrame(*up); result->data[1] = new VFrame(*hi); result->data[2] = new VFrame(*checked); result->data[3] = new VFrame(*dn); result->data[4] = new VFrame(*checkedhi); - for(int i = 0; i < 5; i++) + for( int i=0; i<5; ++i ) overlay(result->data[i], &default_data, -1, -1, (i == 3)); return result->data; } @@ -328,45 +366,39 @@ void BC_Theme::overlay(VFrame *dst, VFrame *src, int in_x1, int in_x2, int shift unsigned char **in_rows; unsigned char **out_rows; - if(in_x1 < 0) - { + if( in_x1 < 0 ) { w = MIN(src->get_w(), dst->get_w()); h = MIN(dst->get_h(), src->get_h()); in_x1 = 0; in_x2 = w; } - else - { + else { w = in_x2 - in_x1; h = MIN(dst->get_h(), src->get_h()); } in_rows = src->get_rows(); out_rows = dst->get_rows(); - switch(src->get_color_model()) + switch( src->get_color_model() ) { case BC_RGBA8888: - switch(dst->get_color_model()) + switch( dst->get_color_model() ) { case BC_RGBA8888: - for(int i = shift; i < h; i++) - { + for( int i=shift; i dp ) break; + unsigned ofs = 0; + for( int i=sizeof(unsigned); --i>=0; ofs|=cp[i] ) ofs <<= 8; + images.append(new BC_ImageData(nm, dp+ofs)); + cp += sizeof(unsigned); } + + int items = images.size() - start_item; + data_items.append(items); + qsort(&images[start_item], items, sizeof(images[0]), images_cmpr); } -unsigned char* BC_Theme::get_image_data(const char *title) +int BC_Theme::images_cmpr(const void *ap, const void *bp) { - if(!data_ptr) - { - fprintf(stderr, "BC_Theme::get_image_data: no data set\n"); - return 0; - } + BC_ImageData *a = *(BC_ImageData**)ap, *b = *(BC_ImageData**)bp; + return strcmp(a->name, b->name); +} +unsigned char* BC_Theme::get_image_data(const char *name, int log_errs) +{ // Image is the same as the last one - if(last_image && !strcasecmp(last_image, title)) - { - return last_pointer; - } - else -// Search for image anew. - for(int i = 0; i < contents.total; i++) - { - if(!strcasecmp(contents.values[i], title)) - { - last_pointer = pointers.values[i]; - last_image = contents.values[i]; - used.values[i] = 1; - return pointers.values[i]; + if( last_image_data && !strcmp(last_image_data->name, name) ) + return last_image_data->data; + +// look forwards thru data sets for name + int start_item = 0; + for( int i=0,n=data_items.size(); i 1 ) { + m = (l + r) / 2; + BC_ImageData *image_data = images[m]; + if( !(v=strcmp(name, image_data->name)) ) { + image_data->used = 1; + last_image_data = image_data; + return image_data->data; + } + if( v > 0 ) l = m; else r = m; } + start_item = end_item; } - fprintf(stderr, _("Theme::get_image: %s not found.\n"), title); + if( log_errs ) + fprintf(stderr, _("Theme::get_image: %s not found.\n"), name); return 0; } @@ -476,30 +506,17 @@ void BC_Theme::check_used() // Can't use because some images are gotten the old fashioned way. return; int got_it = 0; - for(int i = 0; i < used.total; i++) - { - if(!used.values[i]) - { - if(!got_it) - printf(_("BC_Theme::check_used: Images aren't used.\n")); - printf("%s ", contents.values[i]); + for( int i=0; iused ) { + if( !got_it ) printf(_("BC_Theme::check_used: Images aren't used.\n")); + printf("%s ", images[i]->name); got_it = 1; } } - if(got_it) printf("\n"); + if( got_it ) printf("\n"); } - - - - - - - - - - BC_ThemeSet::BC_ThemeSet(int total, int is_reference, const char *title) { this->total = total; @@ -511,11 +528,9 @@ BC_ThemeSet::BC_ThemeSet(int total, int is_reference, const char *title) BC_ThemeSet::~BC_ThemeSet() { - if(data) - { - if(!is_reference) - { - for(int i = 0; i < total; i++) + if( data ) { + if( !is_reference ) { + for( int i = 0; i < total; i++ ) delete data[i]; } @@ -525,7 +540,3 @@ BC_ThemeSet::~BC_ThemeSet() delete [] title; } - - - -