add resource wdw folder expanders, fix plugin close deadlock detect
authorGood Guy <good1.2guy@gmail.com>
Wed, 17 Oct 2018 22:16:35 +0000 (16:16 -0600)
committerGood Guy <good1.2guy@gmail.com>
Wed, 17 Oct 2018 22:16:35 +0000 (16:16 -0600)
14 files changed:
cinelerra-5.1/Makefile.am
cinelerra-5.1/cinelerra/awindowgui.C
cinelerra-5.1/cinelerra/awindowgui.h
cinelerra-5.1/cinelerra/awindowgui.inc
cinelerra-5.1/cinelerra/mwindow.inc
cinelerra-5.1/cinelerra/pluginclient.C
cinelerra-5.1/expanders.txt [new file with mode: 0644]
cinelerra-5.1/guicast/bclistbox.C
cinelerra-5.1/guicast/bclistbox.h
cinelerra-5.1/guicast/bclistboxitem.C
cinelerra-5.1/guicast/bclistboxitem.h
cinelerra-5.1/guicast/bcresources.C
cinelerra-5.1/guicast/bcresources.h
cinelerra-5.1/info/plugins.txt

index 99124da13fca1a16a9151978f3de5d0b137d0437..a61379cf3528f160d035ffe7c7ee21d139baf7b0 100644 (file)
@@ -32,8 +32,8 @@ export mkinstalldirs install_sh inst_sh
 
 # install to bin
 bin_install:   install-recursive
-       cp -a COPYING README models Cinelerra_factory ffmpeg msg info tips \
-               lv2_blacklist.txt bin/.
+       cp -a COPYING README models Cinelerra_factory expanders.txt \
+               ffmpeg msg info tips lv2_blacklist.txt bin/.
        sed -e 's/\<cin\>/$(WANT_CIN)/g' < image/cin.desktop \
                > "bin/applications/$(WANT_CIN).desktop"
        cp -a image/cin.svg "bin/pixmaps/$(WANT_CIN)".svg
@@ -52,7 +52,8 @@ bin_uninstall:
 sys_install: $(CIN_INSTALLS)
        cd bin; $(inst_sh) "$(DESTDIR)$(bindir)" "$(WANT_CIN)" bdwrite
        cd bin; $(inst_sh) "$(DESTDIR)$(datadir)/$(WANT_CIN)" \
-               COPYING README models Cinelerra_factory ffmpeg msg info tips doc
+               COPYING README models Cinelerra_factory expanders.txt \
+               ffmpeg msg info tips doc
        cd bin/locale; $(inst_sh) "$(DESTDIR)$(localedir)" .
        cd bin/plugins; $(inst_sh) "$(DESTDIR)$(WANT_PLUGIN_DIR)" .
        cd bin/applications; $(inst_sh) "$(DESTDIR)$(datadir)/applications" .
index e3271ccdbd456c8a65b8ecc8d4ac0f46457fb628..218523974a544449663271b79888c6afc7163c59 100644 (file)
@@ -300,9 +300,51 @@ void AssetVIcon::stop_audio()
        playing_audio = 0;
 }
 
+
+AWindowFolderItem::AWindowFolderItem()
+ : BC_ListBoxItem()
+{
+       parent = 0;
+}
+
+AWindowFolderItem::AWindowFolderItem(const char *text, int color)
+ : BC_ListBoxItem(text, color)
+{
+       parent = 0;
+}
+
+AWindowFolderItem::AWindowFolderItem(const char *text, BC_Pixmap *icon, int color)
+ : BC_ListBoxItem(text, icon, color)
+{
+       parent = 0;
+}
+
+AssetPicon *AWindowFolderItem::get_picon()
+{
+       AWindowFolderItem *item = this;
+       while( item->parent ) { item = (AWindowFolderItem*)item->parent; }
+       return (AssetPicon*)item;
+}
+
+int AWindowFolderSubItems::matches(const char *text)
+{
+       int i = names.size();
+       while( --i >= 0 && strcmp(names[i], text) );
+       if( i < 0 ) {
+               ArrayList<BC_ListBoxItem *> *sublist = get_sublist();
+               i = sublist ? sublist->size() : 0;
+               while( --i >= 0 ) {
+                       AWindowFolderSubItems *item = (AWindowFolderSubItems *)sublist->get(i);
+                       if( item->matches(text) ) break;
+               }
+       }
+       return i >= 0 ? 1 : 0;
+}
+
+
 AssetPicon::AssetPicon(MWindow *mwindow,
        AWindowGUI *gui, Indexable *indexable)
- : BC_ListBoxItem()
+ : AWindowFolderItem()
 {
        reset();
        this->mwindow = mwindow;
@@ -314,7 +356,7 @@ AssetPicon::AssetPicon(MWindow *mwindow,
 
 AssetPicon::AssetPicon(MWindow *mwindow,
        AWindowGUI *gui, EDL *edl)
- : BC_ListBoxItem()
+ : AWindowFolderItem()
 {
        reset();
        this->mwindow = mwindow;
@@ -326,9 +368,9 @@ AssetPicon::AssetPicon(MWindow *mwindow,
 
 AssetPicon::AssetPicon(MWindow *mwindow,
        AWindowGUI *gui, int folder, int persist)
- : BC_ListBoxItem(_(AWindowGUI::folder_names[folder]),
+ : AWindowFolderItem(_(AWindowGUI::folder_names[folder]),
        folder>=0 && folder<AWINDOW_FOLDERS ?
-               gui->folder_icons[folder]: gui->folder_icon)
+               gui->folder_icons[folder] : gui->folder_icon)
 {
        reset();
        foldernum = folder;
@@ -339,7 +381,7 @@ AssetPicon::AssetPicon(MWindow *mwindow,
 
 AssetPicon::AssetPicon(MWindow *mwindow,
        AWindowGUI *gui, int folder, const char *title)
- : BC_ListBoxItem(title, gui->folder_icon)
+ : AWindowFolderItem(title, gui->folder_icon)
 {
        reset();
        foldernum = folder;
@@ -350,7 +392,7 @@ AssetPicon::AssetPicon(MWindow *mwindow,
 
 AssetPicon::AssetPicon(MWindow *mwindow,
        AWindowGUI *gui, PluginServer *plugin)
- : BC_ListBoxItem()
+ : AWindowFolderItem()
 {
        reset();
        this->mwindow = mwindow;
@@ -360,7 +402,7 @@ AssetPicon::AssetPicon(MWindow *mwindow,
 
 AssetPicon::AssetPicon(MWindow *mwindow,
        AWindowGUI *gui, Label *label)
- : BC_ListBoxItem()
+ : AWindowFolderItem()
 {
        reset();
        this->mwindow = mwindow;
@@ -436,6 +478,8 @@ void AssetPicon::reset()
        label = 0;
        indexable = 0;
        edl = 0;
+       parent = 0;
+       sub_items = 0;
        foldernum = AW_NO_FOLDER;
        sort_key = -1;
        icon = 0;
@@ -1076,6 +1120,7 @@ void AWindowGUI::create_objects()
        add_subwindow(folder_list = new AWindowFolders(mwindow,
                this, fx, fy, fw, fh));
        update_effects();
+       folder_list->load_expanders();
 
        //int x = mwindow->theme->abuttons_x;
        //int y = mwindow->theme->abuttons_y;
@@ -1751,6 +1796,17 @@ void AWindowGUI::copy_picons(ArrayList<BC_ListBoxItem*> *dst,
 // Remove current pointers
        dst[0].remove_all();
        dst[1].remove_all_objects();
+       AWindowFolderSubItems *sub_items = 0;
+       if( folder >= 0 && folder < AW_LABEL_FOLDER ) {
+               AssetPicon *picon = 0;
+               for( int k=folders.size(); --k>=0; ) {
+                       picon = (AssetPicon*)folders[k];
+                       if( picon->foldernum == folder ) break;
+               }
+               if( picon )
+                       sub_items = picon->sub_items;
+               folder = AW_NO_FOLDER;
+       }
        BinFolder *bin_folder = folder < AWINDOW_USER_FOLDERS ? 0 :
                mwindow->edl->get_folder(folder);
 
@@ -1773,6 +1829,10 @@ void AWindowGUI::copy_picons(ArrayList<BC_ListBoxItem*> *dst,
                        visible = 1;
                if( !visible && picon->edl && picon->edl->local_session->folder == folder )
                        visible = 1;
+               if( visible && sub_items ) {
+                       if( !sub_items->matches(picon->get_text()) )
+                               visible = 0;
+               }
                if( visible ) {
                        const char *text = search_text->get_text();
                        if( text && text[0] )
@@ -1842,19 +1902,20 @@ void AWindowGUI::filter_displayed_assets()
        //allow_iconlisting = 1;
        asset_titles[0] = C_("Title");
        asset_titles[1] = _("Comments");
+       int folder = mwindow->edl->session->awindow_folder;
 
-       switch( mwindow->edl->session->awindow_folder ) {
+       switch( folder ) {
        case AW_AEFFECT_FOLDER:
-               copy_picons(displayed_assets, &aeffects, AW_NO_FOLDER);
+               copy_picons(displayed_assets, &aeffects, folder);
                break;
        case AW_VEFFECT_FOLDER:
-               copy_picons(displayed_assets, &veffects, AW_NO_FOLDER);
+               copy_picons(displayed_assets, &veffects, folder);
                break;
        case AW_ATRANSITION_FOLDER:
-               copy_picons(displayed_assets, &atransitions, AW_NO_FOLDER);
+               copy_picons(displayed_assets, &atransitions, folder);
                break;
        case AW_VTRANSITION_FOLDER:
-               copy_picons(displayed_assets, &vtransitions, AW_NO_FOLDER);
+               copy_picons(displayed_assets, &vtransitions, folder);
                break;
        case AW_LABEL_FOLDER:
                copy_picons(displayed_assets, &labellist, AW_NO_FOLDER);
@@ -2035,6 +2096,8 @@ AWindowFolders::AWindowFolders(MWindow *mwindow, AWindowGUI *gui, int x, int y,
        this->mwindow = mwindow;
        this->gui = gui;
        set_drag_scroll(0);
+       last_item0 = 0;
+       last_item1 = 0;
 }
 
 AWindowFolders::~AWindowFolders()
@@ -2043,8 +2106,21 @@ AWindowFolders::~AWindowFolders()
 
 int AWindowFolders::selection_changed()
 {
-       AssetPicon *picon = (AssetPicon*)get_selection(0, 0);
-       if( picon ) {
+       AWindowFolderItem *item0 = (AWindowFolderItem*)get_selection(0, 0);
+       AWindowFolderItem *item1 = (AWindowFolderItem*)get_selection(0, 1);
+// prefer expanded entry
+       AWindowFolderItem *item = item1 ? item1 : item0;
+       if( item0 && item1 && last_item0 == item0 && last_item1 == item1 ) {
+               item1->set_selected(0);
+               item1 = 0;
+               item = item0;
+       }
+       last_item0 = item0;
+       last_item1 = item1;
+       if( item ) {
+               AssetPicon *picon = item->get_picon();
+               picon->sub_items = (AWindowFolderSubItems*)(!item->parent ? 0 : item);
+
                gui->stop_vicon_drawing();
 
                if( get_button_down() && get_buttonpress() == 3 ) {
@@ -2101,6 +2177,72 @@ int AWindowFolders::drag_stop()
        return result;
 }
 
+AWindowFolderSubItems::AWindowFolderSubItems(AWindowFolderItem *parent, const char *text)
+ : AWindowFolderItem(text)
+{
+       this->parent = parent;
+}
+
+int AWindowFolders::load_expanders()
+{
+       char expanders_path[BCTEXTLEN];
+       mwindow->create_defaults_path(expanders_path, EXPANDERS_FILE);
+       FILE *fp = fopen(expanders_path, "r");
+       if( !fp ) {
+               snprintf(expanders_path, sizeof(expanders_path), "%s/%s",
+                       File::get_cindat_path(), EXPANDERS_FILE);
+               fp = fopen(expanders_path, "r");
+       }
+
+       if( !fp ) return 1;
+       const char tab = '\t';
+       char line[BCTEXTLEN];   line[0] = 0;
+       AWindowFolderItem *item = 0, *parent;
+       AWindowFolderSubItems *sub_items = 0;
+       int k = 0;
+       while( fgets(line,sizeof(line),fp) ) {
+               if( line[0] == '#' ) continue;
+               int i = strlen(line);
+               if( i > 0 && line[i-1] == '\n' ) line[--i] = 0;
+               if( i == 0 ) continue;
+               i = 0;
+               for( char *cp=line; *cp==tab; ++cp ) ++i;
+               if( i == 0 ) {
+                       int i = gui->folders.size();
+                       while( --i >= 0 ) {
+                               AssetPicon *folder = (AssetPicon *)gui->folders[i];
+                               if( !strcmp(folder->get_text(),_(line)) ) break;
+                       }
+                       item = (AWindowFolderItem*)(i >= 0 ? gui->folders[i] : 0);
+                       sub_items = 0;
+                       k = 0;
+                       continue;
+               }
+               if( i > k+1 ) continue;
+               if( i == k+1 ) {
+                       if( line[i] != '-' && sub_items ) {
+                               sub_items->names.append(cstrdup(_(&line[i])));
+                               continue;
+                       }
+                       parent = item;
+                       k = i;
+               }
+               else {
+                       while( i < k ) {
+                               item = item->parent;
+                               --k;
+                       }
+                       parent = item->parent;
+               }
+               ArrayList<BC_ListBoxItem*> *sublist = parent->get_sublist();
+               if( !sublist ) sublist = parent->new_sublist(1);
+               sub_items = new AWindowFolderSubItems(parent, &line[i]);
+               sublist->append(item = sub_items);
+       }
+       fclose(fp);
+       return 0;
+}
+
 
 AWindowAssets::AWindowAssets(MWindow *mwindow, AWindowGUI *gui, int x, int y, int w, int h)
  : BC_ListBox(x, y, w, h, !gui->allow_iconlisting ? LISTBOX_TEXT :
index c26d4e87dc2e809a124e7fc23c4040c58fc4b6ea..6cab2a6d2c45bd3b432c44b86e436e7b0a6f0c9c 100644 (file)
 #include "samples.inc"
 #include "vicon.h"
 
-class AssetPicon : public BC_ListBoxItem
+class AWindowFolderItem : public BC_ListBoxItem
+{
+public:
+       AWindowFolderItem();
+       AWindowFolderItem(const char *text, int color = -1);
+       AWindowFolderItem(const char *text, BC_Pixmap *icon, int color = -1);
+
+       AssetPicon *get_picon();
+       int matches(const char *text);
+
+       AWindowFolderItem *parent;
+};
+
+class AssetPicon : public AWindowFolderItem
 {
 public:
        AssetPicon(MWindow *mwindow, AWindowGUI *gui, Indexable *indexable);
@@ -76,6 +89,9 @@ public:
        VFrame *icon_vframe;
        VFrame *vicon_frame;
        int foldernum;
+// sublist items if set
+       AWindowFolderSubItems *sub_items;
+
 // ID of thing pointed to
        int id;
 
@@ -344,6 +360,22 @@ public:
        AWindowGUI *gui;
 };
 
+class AWindowSubFolderNames : public ArrayList<const char *>
+{
+public:
+       AWindowSubFolderNames() { set_array_delete(); }
+       ~AWindowSubFolderNames() { remove_all_objects(); }
+};
+
+class AWindowFolderSubItems : public AWindowFolderItem
+{
+public:
+       AWindowFolderSubItems(AWindowFolderItem *parent, const char *text);
+       int matches(const char *text);
+
+       AWindowSubFolderNames names;
+};
+
 class AWindowFolders : public BC_ListBox
 {
 public:
@@ -353,9 +385,12 @@ public:
        int selection_changed();
        int button_press_event();
        int drag_stop();
+       int load_expanders();
 
        MWindow *mwindow;
        AWindowGUI *gui;
+// last selection
+       AWindowFolderItem *last_item0, *last_item1;
 };
 
 class AWindowSearchTextBox : public BC_TextBox
index 0fb16fbc3f31ffe5127aff0a875a59627bb6a4b6..fdb7525cf1a6eb954b4daa3d961222dca1de6f9d 100644 (file)
@@ -22,7 +22,9 @@
 #ifndef AWINDOWGUI_INC
 #define AWINDOWGUI_INC
 
+class AWindowFolderItem;
 class AssetPicon;
+class AssetVIconAudio;
 class AssetVIcon;
 class AWindowRemovePlugin;
 class AWindowRemovePluginGUI;
@@ -30,12 +32,11 @@ class AWindowRemovePlugin;
 class AWindowGUI;
 class AWindowAssets;
 class AWindowDivider;
+class AWindowSubFolderNames;
+class AWindowFolderSubItems;
+class AWindowFolders;
 class AWindowSearchTextBox;
 class AWindowSearchText;
-class AWindowFolders;
-class AWindowNewFolder;
-class AWindowDeleteFolder;
-class AWindowRenameFolder;
 class AWindowDeleteDisk;
 class AWindowDeleteProject;
 class AWindowInfo;
index beb4e4ede578883b05a77b7570b869a6e5bba3b7..017ca2e2cddfec00ea0d9a247c0757049fe9f8e6 100644 (file)
@@ -28,6 +28,7 @@
 #define CONFIG_FILE "Cinelerra_rc"
 // user presets
 #define PRESETS_FILE "Cinelerra_presets"
+#define EXPANDERS_FILE "expanders.txt"
 #define PERPETUAL_FILE "perpetual.dat"
 // factory presets
 #define FACTORY_FILE "Cinelerra_factory"
index 0a690b2e673868d3e65700da5c323022f90abc91..f1fe25b9f9e90581756f5668bc12ca18c104368e 100644 (file)
@@ -201,8 +201,11 @@ PluginClient::PluginClient(PluginServer *server)
 
 PluginClient::~PluginClient()
 {
-// Delete the GUI thread.  The GUI must be hidden with hide_gui first.
-       delete thread;
+       if( thread ) {
+               hide_gui();
+               thread->join();
+               delete thread;
+       }
 
 // Virtual functions don't work here.
        if(defaults) delete defaults;
@@ -245,8 +248,6 @@ void PluginClient::hide_gui()
                thread->window->set_done(0);
 //printf("PluginClient::hide_gui %d thread->window=%p\n", __LINE__, thread->window);
                thread->window->unlock_window();
-//printf("PluginClient::delete_thread %d\n", __LINE__);
-               thread->join();
        }
 }
 
diff --git a/cinelerra-5.1/expanders.txt b/cinelerra-5.1/expanders.txt
new file mode 100644 (file)
index 0000000..7445d4d
--- /dev/null
@@ -0,0 +1,108 @@
+Video Effects
+       - Color_Correction
+               Blue Banana
+               Brightness/Contrast
+               Color 3 Way
+               Color Balance
+               Gamma
+               HistEq
+               Histogram
+               Histogram Bezier
+               Hue saturation
+               VideoScope
+       - FF_Color_Correction
+               F_color
+               F_colorbalance
+               F_colorchannelmixer
+               F_colorkey
+               F_colorlevels
+               F_eq
+               F_floodfill
+               F_histeq
+               F_histogram
+               F_lut
+               F_lut3d
+               F_lutrgb
+               F_lutyuv
+               F_normalize
+               F_pseudocolor
+               F_tlut2
+               F_vectorscope
+       - Motion
+               Motion
+               Motion 2 Point
+               Motion51
+               MotionCV
+               MotionHV
+               F_deshake
+       - Blur
+               Blur
+               Linear Blur
+               Motion Blur
+               Radial Blur
+               Zoom Blur
+               F_avgblur
+               F_boxblur
+               F_gblur
+               F_smartblur
+               F_unsharp
+Audio Effects
+       - Calf
+               - Instruments / Generators
+                       L2_Calf Organ
+                       L2_Calf Monosynth
+                       L2_Calf Fluidsynth
+                       L2_Calf Wavetable
+               - Modulation Effects
+                       L2_Calf Multi Chorus
+                       L2_Calf Phaser
+                       L2_Calf Flanger
+                       L2_Calf Rotary Speaker
+                       L2_Calf Pulsator
+                       L2_Calf Ring Modulator
+               - Delay Effects
+                       L2_Calf Reverb
+                       L2_Calf Vintage Delay
+                       L2_Calf Compensation Delay Line
+                       L2_Calf Reverse Delay
+               - Dynamic Processors
+                       L2_Calf Compressor
+                       L2_Calf Sidechain Compressor
+                       L2_Calf Multiband Compressor
+                       L2_Calf Mono Compressor
+                       L2_Calf Deeser
+                       L2_Calf Gate
+                       L2_Calf Sidechain Gate
+                       L2_Calf Multiband Gate
+                       L2_Calf Limiter
+                       L2_Calf Multiband Limiter
+                       L2_Calf Sidechain Limiter
+                       L2_Calf Transient Designer
+               - Filters and Equalizers
+                       L2_Calf Filter
+                       L2_Calf Filterclavier
+                       L2_Calf Envelope Filter
+                       L2_Calf Emphasis
+                       L2_Calf Vocoder
+                       L2_Calf 5-Band Equalizer
+                       L2_Calf 8-Band Equalizer
+                       L2_Calf 12-Band Equalizer
+                       L2_Calf 30-Band Equalizer
+               - Distortion Effects
+                       L2_Calf Saturator
+                       L2_Calf Exciter
+                       L2_Calf Bass Enhancer
+                       L2_Calf Tape Simulator
+                       L2_Calf Vinyl
+                       L2_Calf Crusher
+               - Tools
+                       L2_Calf Mono Input
+                       L2_Calf Pitch Tools
+                       L2_Calf Stereo Tools
+                       L2_Calf Haas Stereo Enhancer
+                       L2_Calf Multi Spread
+                       L2_Calf Multiband Enhancer
+                       L2_Calf X-Over 2 Band
+                       L2_Calf X-Over 3 Band
+                       L2_Calf X-Over 4 Band
+                       L2_Calf Analyzer
index 54bab352a6f7a6b12db02067a4b21c36b5831db3..31bcb1412cf40ad43ef64322f422c2413d0b2eaf 100644 (file)
@@ -618,8 +618,7 @@ void BC_ListBox::calculate_last_coords_recursive(
                                *next_text_y = current_text_y;
 
 // Add sublist depth if it is expanded
-                       if( item->get_sublist() && item->get_columns() &&
-                           item->get_expand() ) {
+                       if( item->sublist_active() && item->get_columns() ) {
                                calculate_last_coords_recursive(item->get_sublist(),
                                        icon_x, next_icon_x, next_icon_y, next_text_y, 0);
                        }
@@ -712,7 +711,7 @@ void BC_ListBox::calculate_item_coords_recursive(
                                if( dt > row_descent ) row_descent = dt;
 
 // printf("BC_ListBox::calculate_item_coords_recursive %p %d %d %d %d %s \n",
-// item->get_sublist(), item->get_columns(), item->get_expand(),
+// item->sublist, item->get_columns(), item->get_expand(),
 // next_text_x, *next_text_y, item->get_text());
 // Increment position of next column
                                if( j < columns - 1 ) {
@@ -743,8 +742,7 @@ void BC_ListBox::calculate_item_coords_recursive(
 
 // Set up a sublist
                BC_ListBoxItem *item = data[master_column].values[i];
-               if( item->get_sublist() && item->get_columns() &&
-                   item->get_expand() ) {
+               if( item->sublist_active() && item->get_columns() ) {
                        calculate_item_coords_recursive( item->get_sublist(),
                                icon_x, next_icon_x, next_icon_y, next_text_y, 0);
                }
@@ -1010,11 +1008,8 @@ int BC_ListBox::get_items_height(ArrayList<BC_ListBoxItem*> *data, int columns,
                        get_text_mask(item, x, y, w, h);
                        *result += h;
 // Descend into sublist
-                       if( item->get_sublist() && item->get_expand() ) {
-                               get_items_height(item->get_sublist(),
-                                       item->get_columns(),
-                                       result);
-                       }
+                       if( item->sublist_active() )
+                               get_items_height(item->get_sublist(), item->get_columns(), result);
                        break;
                case LISTBOX_ICONS:
                case LISTBOX_ICONS_PACKED:
@@ -1076,7 +1071,7 @@ void BC_ListBox::collapse_recursive(ArrayList<BC_ListBoxItem*> *data,
 {
        for( int i=0; i<data[master_column].total; ++i ) {
                BC_ListBoxItem *item = data[master_column].values[i];
-               if( item->get_sublist() && item->expand ) {
+               if( item->sublist_active() ) {
                        item->expand = 0;
                        collapse_recursive(item->get_sublist(), master_column);
                }
@@ -1094,7 +1089,7 @@ void BC_ListBox::set_autoplacement(ArrayList<BC_ListBoxItem*> *data,
                }
 
                BC_ListBoxItem *item = data[master_column].values[i];
-               if( item->get_sublist() ) {
+               if( item->sublist_active() ) {
                        set_autoplacement(item->get_sublist(), do_icons, do_text);
                }
        }
@@ -1293,7 +1288,7 @@ BC_ListBoxItem* BC_ListBox::get_selection_recursive(ArrayList<BC_ListBoxItem*> *
                        }
                }
 
-               if( item->get_sublist() ) {
+               if( item->sublist_active() ) {
                        BC_ListBoxItem *result = get_selection_recursive(item->get_sublist(),
                                column,
                                selection_number);
@@ -1326,7 +1321,7 @@ int BC_ListBox::get_selection_number_recursive(ArrayList<BC_ListBoxItem*> *data,
                                return (*counter);
                        }
                }
-               if( item->get_sublist() ) {
+               if( item->sublist_active() ) {
                        int result = get_selection_number_recursive(item->get_sublist(),
                                column, selection_number, counter);
                        if( result >= 0 ) return result;
@@ -1457,8 +1452,7 @@ int BC_ListBox::select_previous(int skip, BC_ListBoxItem *selected_item, int *co
        do {
                for( int i=data[master_column].total-1; i>=0; --i ) {
                        BC_ListBoxItem *current_item = data[master_column].values[i];
-                       if( current_item->get_sublist() &&
-                           current_item->get_expand() ) {
+                       if( current_item->sublist_active() ) {
                                int result = select_previous(skip, selected_item, counter,
                                        current_item->get_sublist(), got_first, got_second);
                                if( *got_second )
@@ -1549,8 +1543,7 @@ int BC_ListBox::select_next(int skip, BC_ListBoxItem *selected_item, int *counte
                        }
 
 // Descend into expanded level
-                       if( current_item->get_sublist() &&
-                           current_item->get_expand() ) {
+                       if( current_item->sublist_active() ) {
                                int result = select_next(skip, selected_item, counter,
                                        current_item->get_sublist(), got_first, got_second);
                                if( *got_second ) {
@@ -1654,10 +1647,8 @@ int BC_ListBox::center_selection(int selection,
                }
 
 // Descend
-               if( item->get_sublist() ) {
-                       int result = center_selection(selection,
-                               item->get_sublist(),
-                               counter);
+               if( item->sublist_active() ) {
+                       int result = center_selection(selection, item->get_sublist(), counter);
                        if( result ) return result;
                }
        }
@@ -1943,10 +1934,10 @@ int BC_ListBox::select_rectangle(ArrayList<BC_ListBoxItem*> *data,
                }
 
                BC_ListBoxItem *item = data[master_column].values[i];
-               if( item->get_sublist() &&
-                   item->get_expand() )
+               if( item->sublist_active() ) {
                        result |= select_rectangle(item->get_sublist(),
                                x1, y1, x2, y2);
+               }
        }
        return result;
 }
@@ -1985,9 +1976,8 @@ void BC_ListBox::move_selection(ArrayList<BC_ListBoxItem*> *dst,
                        continue;
                }
 // Descend into sublist
-               if( item->get_sublist() ) {
-                       move_selection(dst,
-                               item->get_sublist());
+               if( item->sublist_active() ) {
+                       move_selection(dst, item->get_sublist());
                }
                ++i;
        }
@@ -2020,11 +2010,8 @@ int BC_ListBox::put_selection(ArrayList<BC_ListBoxItem*> *data,
                }
 
                BC_ListBoxItem *item = data[master_column].values[i];
-               if( item->get_sublist() ) {
-                       if( put_selection(item->get_sublist(),
-                               src,
-                               destination,
-                               counter) )
+               if( item->sublist_active() ) {
+                       if( put_selection(item->get_sublist(), src, destination, counter) )
                                return 1;
                }
        }
@@ -2050,10 +2037,8 @@ int BC_ListBox::item_to_index(ArrayList<BC_ListBoxItem*> *data,
                }
 
                BC_ListBoxItem *new_item = data[master_column].values[i];
-               if( new_item->get_sublist() ) {
-                       if( item_to_index(new_item->get_sublist(),
-                               item,
-                               counter) >= 0 )
+               if( new_item->sublist_active() ) {
+                       if( item_to_index(new_item->get_sublist(), item, counter) >= 0 )
                                return (*counter);
                }
        }
@@ -2072,7 +2057,7 @@ BC_ListBoxItem* BC_ListBox::index_to_item(ArrayList<BC_ListBoxItem*> *data,
                        return data[column].values[i];
                }
                BC_ListBoxItem *item = data[master_column].values[i];
-               if( item->get_sublist() ) {
+               if( item->sublist_active() ) {
                        BC_ListBoxItem *result = index_to_item(item->get_sublist(),
                                number, column, counter);
                        if( result ) return result;
@@ -2136,7 +2121,7 @@ int BC_ListBox::get_cursor_item(ArrayList<BC_ListBoxItem*> *data, int cursor_x,
                                }
 
 // Descend into sublist
-                               if( item->get_sublist() ) {
+                               if( item->sublist_active() ) {
                                        if( get_cursor_item(item->get_sublist(),
                                              cursor_x, cursor_y, item_return, counter,
                                              item->get_expand()) >= 0 )
@@ -2260,7 +2245,7 @@ int BC_ListBox::get_first_selection(ArrayList<BC_ListBoxItem*> *data, int *resul
                BC_ListBoxItem *item = data[master_column].values[i];
                (*result)++;
                if( item->selected ) return (*result);
-               if( item->get_sublist() ) {
+               if( item->sublist_active() ) {
                        if( get_first_selection(item->get_sublist(), result) >= 0 )
                                return (*result);
                }
@@ -2277,7 +2262,7 @@ int BC_ListBox::get_total_items(ArrayList<BC_ListBoxItem*> *data,
 
        for( int i=0; i<data[master_column].total; ++i ) {
                (*result)++;
-               if( data[master_column].values[i]->get_sublist() )
+               if( data[master_column].values[i]->sublist_active() )
                        get_total_items(data[master_column].values[i]->get_sublist(),
                                result,
                                master_column);
@@ -2307,7 +2292,7 @@ int BC_ListBox::get_last_selection(ArrayList<BC_ListBoxItem*> *data,
                                return (*result);
                }
 
-               if( item->get_sublist() ) {
+               if( item->sublist_active() ) {
                        if( get_last_selection(item->get_sublist(), result) >= 0 ) {
                                if( top_level )
                                        return get_total_items(data, 0, master_column) - (*result) /* - 1 */;
@@ -2332,7 +2317,7 @@ void BC_ListBox::select_range(ArrayList<BC_ListBoxItem*> *data,
                                data[j].values[i]->selected = 1;
                }
                BC_ListBoxItem *item = data[master_column].values[i];
-               if( item->get_sublist() )
+               if( item->sublist_active() )
                        select_range(item->get_sublist(), start, end, current);
        }
 }
@@ -2384,7 +2369,7 @@ int BC_ListBox::toggle_item_selection(ArrayList<BC_ListBoxItem*> *data,
                }
 
 // Descend into sublist
-               if( item->get_sublist() ) {
+               if( item->sublist_active() ) {
                        if( toggle_item_selection(item->get_sublist(),
                              selection_number, counter) )
                                return 1;
@@ -2425,7 +2410,7 @@ void BC_ListBox::set_selected(ArrayList<BC_ListBoxItem*> *data,
                }
 
                BC_ListBoxItem *item = data[master_column].values[i];
-               if( item->get_sublist() ) {
+               if( item->sublist_active() ) {
                        set_selected(item->get_sublist(), item_number, value, counter);
                }
        }
@@ -2452,7 +2437,7 @@ int BC_ListBox::update_selection(ArrayList<BC_ListBoxItem*> *data,
                        for( int j=0; j<columns; ++j )
                                data[j].values[i]->selected = 0;
                }
-               if( item->get_sublist() )
+               if( item->sublist_active() )
                        result |= update_selection(item->get_sublist(),
                                selection_number,
                                counter);
@@ -2469,7 +2454,7 @@ void BC_ListBox::promote_selections(ArrayList<BC_ListBoxItem*> *data,
                        if( item->selected == old_value ) item->selected = new_value;
                }
                BC_ListBoxItem *item = data[master_column].values[i];
-               if( item->get_sublist() )
+               if( item->sublist_active() )
                        promote_selections(item->get_sublist(), old_value, new_value);
        }
 }
@@ -3200,6 +3185,7 @@ int BC_ListBox::drag_start_event()
 {
        switch( current_operation ) {
        case SELECT:
+               if( expander_active() ) break;
                if( gui && gui->is_event_win() && allow_drag ) {
                        BC_ListBoxItem *item_return = 0;
                        selection_number = get_cursor_item(data,
@@ -3473,6 +3459,14 @@ int BC_ListBox::is_active()
        return active;
 }
 
+int BC_ListBox::expander_active()
+{
+       for( int i=0; i<expanders.total; ++i ) {
+               if( expanders.values[i]->value ) return 1;
+       }
+       return 0 ;
+}
+
 int BC_ListBox::keypress_event()
 {
        if( !active ) return 0;
@@ -3889,7 +3883,7 @@ void BC_ListBox::draw_text_recursive(ArrayList<BC_ListBoxItem*> *data,
                        item->set_in_view(0);
 
 // Descend into sublist
-               if( first_item->get_expand() ) {
+               if( first_item->sublist_active() ) {
                        draw_text_recursive(first_item->get_sublist(),
                                column,
                                indent + LISTBOX_INDENT,
index ce867ef88ecc196efd0dfd3b6d9f2c79a881a11f..ba3819ae1b173bc9e0094bdb5bc9a205101bc0d0 100644 (file)
@@ -191,6 +191,7 @@ public:
        int activate(int x, int y, int w=-1, int h=-1);
        int deactivate();
        int is_active();
+       int expander_active();
 
        int translation_event();
        int repeat_event(int64_t duration);
index 88ba5a2b125ef62b0258e8b67b3e5475f5d0828a..c5d9d145638979080de61fdd04a913e1f10e213a 100644 (file)
@@ -72,7 +72,7 @@ BC_ListBoxItem::~BC_ListBoxItem()
        {
                for(int i = 0; i < columns; i++)
                        sublist[i].remove_all_objects();
-               delete sublist;
+               delete [] sublist;
        }
 }
 
index 78db9d663e68f8b4f9afe838baf4c24eef54f90c..229b31ef3dcb25d40fddbe3d53341ec3f6cbffaf 100644 (file)
@@ -92,6 +92,7 @@ public:
 
 // The item with the sublist must be in column 0.  Only this is searched by
 // BC_ListBox.
+       int sublist_active() { return sublist && expand ? 1 : 0; }
 // Mind you, sublists are ignored in icon mode.
        ArrayList<BC_ListBoxItem*>* new_sublist(int columns);
        ArrayList<BC_ListBoxItem*>* get_sublist() { return sublist; }
index 955aa5f5281a05b7ec2912c759253f78a3a53748..5746e6c20ff895fad571e8fc994a408e4bd5ff21 100644 (file)
@@ -358,6 +358,8 @@ VFrame *BC_Resources::default_listbox_dn = 0;
 VFrame *BC_Resources::default_pot_images[3] = { 0, };
 VFrame *BC_Resources::default_progress_images[2] = { 0, };
 VFrame *BC_Resources::default_medium_7segment[20] = { 0, };
+VFrame *BC_Resources::default_vscroll_data[10] = { 0, };
+VFrame *BC_Resources::default_hscroll_data[10] = { 0, };
 
 BC_Resources::BC_Resources()
 {
@@ -666,6 +668,50 @@ new_vframes(20,default_medium_7segment,
        new VFramePng(space_png),
        new VFramePng(dash_png));
 
+#include "images/hscroll_handle_up_png.h"
+#include "images/hscroll_handle_hi_png.h"
+#include "images/hscroll_handle_dn_png.h"
+#include "images/hscroll_handle_bg_png.h"
+#include "images/hscroll_left_up_png.h"
+#include "images/hscroll_left_hi_png.h"
+#include "images/hscroll_left_dn_png.h"
+#include "images/hscroll_right_up_png.h"
+#include "images/hscroll_right_hi_png.h"
+#include "images/hscroll_right_dn_png.h"
+new_vframes(10,default_hscroll_data,
+       new VFramePng(hscroll_handle_up_png),
+       new VFramePng(hscroll_handle_hi_png),
+       new VFramePng(hscroll_handle_dn_png),
+       new VFramePng(hscroll_handle_bg_png),
+       new VFramePng(hscroll_left_up_png),
+       new VFramePng(hscroll_left_hi_png),
+       new VFramePng(hscroll_left_dn_png),
+       new VFramePng(hscroll_right_up_png),
+       new VFramePng(hscroll_right_hi_png),
+       new VFramePng(hscroll_right_dn_png));
+
+#include "images/vscroll_handle_up_png.h"
+#include "images/vscroll_handle_hi_png.h"
+#include "images/vscroll_handle_dn_png.h"
+#include "images/vscroll_handle_bg_png.h"
+#include "images/vscroll_left_up_png.h"
+#include "images/vscroll_left_hi_png.h"
+#include "images/vscroll_left_dn_png.h"
+#include "images/vscroll_right_up_png.h"
+#include "images/vscroll_right_hi_png.h"
+#include "images/vscroll_right_dn_png.h"
+new_vframes(10,default_vscroll_data,
+       new VFramePng(vscroll_handle_up_png),
+       new VFramePng(vscroll_handle_hi_png),
+       new VFramePng(vscroll_handle_dn_png),
+       new VFramePng(vscroll_handle_bg_png),
+       new VFramePng(vscroll_left_up_png),
+       new VFramePng(vscroll_left_hi_png),
+       new VFramePng(vscroll_left_dn_png),
+       new VFramePng(vscroll_right_up_png),
+       new VFramePng(vscroll_right_hi_png),
+       new VFramePng(vscroll_right_dn_png));
+
        type_to_icon = default_type_to_icon;
        bar_data = default_bar;
        check = default_check_image;
@@ -675,6 +721,9 @@ new_vframes(20,default_medium_7segment,
        listbox_column = default_listbox_column;
        listbox_up = default_listbox_up;
        listbox_dn = default_listbox_dn;
+       hscroll_data = default_hscroll_data;
+       vscroll_data = default_vscroll_data;
+
        listbox_title_overlap = 0;
        listbox_title_margin = 0;
        listbox_title_color = BLACK;
index feca1095043be5ebdb31c95cad86e1b851421932..f2339ed05be716fd1a718adcd24226abb6d5c984 100644 (file)
@@ -400,6 +400,8 @@ public:
        static VFrame *default_pot_images[3];
        static VFrame *default_progress_images[2];
        static VFrame *default_medium_7segment[20];
+       static VFrame *default_vscroll_data[10];
+       static VFrame *default_hscroll_data[10];
 
 // Make VFrame use shm
        int vframe_shm;
index da578dd4d11d8c8aca70c92247e211b2bd602dbd..8054ae49937178a1ea06e0bae1b15dae28dae4a9 100644 (file)
@@ -768,7 +768,7 @@ L2_Calf Multiband Compressor: Based on Thor's compressions routine; 4
 L2_Calf Multiband Gate:        Flexible 4 channels with separate gate stages.
 L2_Calf Multiband Limiter: Brings presence, punch, and loudness to
        your mix.
-L2_Calf Organ: An organ synthesizer which produces different sounds.   
+L2_Calf Organ: An organ synthesizer which produces different sounds.
 L2_Calf Phaser:        Basic stereo phaser with all typical settings.
 L2_Calf Pulsator: In between an autopanner and a tremolo; also produces
        funny stereo effects.