add new boxblur plugin, mods to videoscope, fix segv for menu btns kfrm-tweak/kfrm...
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / loadmode.C
index b32292ea0118c5c9b7cd617893be208875653c8d..6e12593da63f633af82858eec9418611b76e2299 100644 (file)
 #include "mwindow.h"
 #include "theme.h"
 
+#define LOADMODE_LOAD_TEXT _("Load strategy:")
+#define LOADMODE_EDL_TEXT _("EDL strategy:")
 
 // Must match macros
+static const char *mode_images[] =
+{
+       "loadmode_none",
+       "loadmode_new",
+       "loadmode_newcat",
+       "loadmode_newtracks",
+       "loadmode_cat",
+       "loadmode_paste",
+       "loadmode_resource",
+       "loadmode_edl_clip",
+       "loadmode_edl_nested",
+       "loadmode_edl_fileref",
+};
+
 static const char *mode_text[] =
 {
        N_("Insert nothing"),
@@ -36,7 +52,9 @@ static const char *mode_text[] =
        N_("Concatenate to existing tracks"),
        N_("Paste over selection/at insertion point"),
        N_("Create new resources only"),
-       N_("Nest sequence")
+       N_("EDL"),
+       N_("Nested"),
+       N_("Reference"),
 };
 
 
@@ -47,73 +65,227 @@ LoadModeItem::LoadModeItem(const char *text, int value)
 }
 
 
+LoadModeToggle::LoadModeToggle(int x, int y, LoadMode *window, int id,
+               int *output, const char *images, const char *tooltip)
+ : BC_Toggle(x, y, window->mwindow->theme->get_image_set(images), *output)
+{
+       this->window = window;
+       this->id = id;
+       this->output = output;
+       set_tooltip(tooltip);
+}
+
+int LoadModeToggle::handle_event()
+{
+       *output = id;
+       window->update();
+       return 1;
+}
+
+
+
 LoadMode::LoadMode(MWindow *mwindow, BC_WindowBase *window,
-       int x, int y, int *output, int use_nothing)
+               int x, int y, int *load_mode, int *edl_mode,
+               int use_nothing, int line_wrap)
 {
        this->mwindow = mwindow;
        this->window = window;
        this->x = x;
        this->y = y;
-       this->output = output;
+       this->load_mode = load_mode;
+       this->edl_mode = edl_mode;
        this->use_nothing = use_nothing;
-       int mode = LOADMODE_NOTHING;
-       if(use_nothing)
-               load_modes.append(new LoadModeItem(_(mode_text[mode]), mode));
-       while( ++mode < TOTAL_LOADMODES )
-               load_modes.append(new LoadModeItem(_(mode_text[mode]), mode));
+       this->line_wrap = line_wrap;
+       for( int i=0; i<TOTAL_LOADMODES; ++i ) mode[i] = 0;
+       load_title = 0;
+       edl_title = 0;
 }
 
 LoadMode::~LoadMode()
 {
-       delete title;
-       delete textbox;
-       delete listbox;
-       for(int i = 0; i < load_modes.total; i++)
-               delete load_modes.values[i];
+       load_modes.remove_all_objects();
+       for( int i=0; i<TOTAL_LOADMODES; ++i ) delete mode[i];
+}
+
+const char *LoadMode::mode_to_text(int mode)
+{
+       for( int i=0; i<load_modes.total; ++i ) {
+               if( load_modes[i]->value == mode )
+                       return load_modes[i]->get_text();
+       }
+       return _("Unknown");
+}
+
+void LoadMode::load_mode_geometry(BC_WindowBase *gui, Theme *theme,
+               int use_nothing, int use_nested, int line_wrap,
+               int *pw, int *ph)
+{
+       int pad = 5;
+       const char *load_text = LOADMODE_LOAD_TEXT;
+       int mw = BC_Title::calculate_w(gui, load_text);
+       int mh = BC_Title::calculate_h(gui, load_text);
+       int ix = mw + 2*pad, iy = 0, x1 = ix;
+       int ww = theme->loadmode_w + 24;
+       if( mw < ww ) mw = ww;
+
+       for( int i=0; i<TOTAL_LOADMODES; ++i ) {
+               switch( i ) {
+               case LOADMODE_NOTHING:
+                       if( !use_nothing) continue;
+                       break;
+               case LOADMODE_EDL_CLIP:
+               case LOADMODE_EDL_NESTED:
+               case LOADMODE_EDL_FILEREF:
+                       if( !use_nested ) continue;
+                       if( iy ) break;
+                       ix = 0;  iy = mh + pad;
+                       const char *edl_text = LOADMODE_EDL_TEXT;
+                       ix += bmax(BC_Title::calculate_w(gui, load_text),
+                                  BC_Title::calculate_w(gui, edl_text)) + 2*pad;
+                       break;
+               }
+               int text_line, w, h, toggle_x, toggle_y;
+               int text_x, text_y, text_w, text_h;
+               BC_Toggle::calculate_extents(gui,
+                       theme->get_image_set(mode_images[i]), 0,
+                       &text_line, &w, &h, &toggle_x, &toggle_y,
+                       &text_x, &text_y, &text_w, &text_h, 0, MEDIUMFONT);
+               if( line_wrap && ix+w > ww ) { ix = x1;  iy += h+pad; }
+               if( (ix+=w) > mw ) mw = ix;
+               if( (h+=iy) > mh ) mh = h;
+               ix += pad;
+       }
+
+       ix = 0;  iy = mh+pad;
+       mh = iy + BC_TextBox::calculate_h(gui, MEDIUMFONT, 1, 1);
+       if( pw ) *pw = mw;
+       if( ph ) *ph = mh;
 }
 
-int LoadMode::calculate_w(BC_WindowBase *gui, Theme *theme)
+int LoadMode::calculate_w(BC_WindowBase *gui, Theme *theme,
+               int use_nothing, int use_nested, int line_wrap)
 {
-       return theme->loadmode_w + 24;
+       int result = 0;
+       load_mode_geometry(gui, theme, use_nothing, use_nested, line_wrap,
+                       &result, 0);
+       return result;
 }
 
-int LoadMode::calculate_h(BC_WindowBase *gui, Theme *theme)
+int LoadMode::calculate_h(BC_WindowBase *gui, Theme *theme,
+               int use_nothing, int use_nested, int line_wrap)
 {
-       return BC_Title::calculate_h(gui, _("Insertion strategy:"), MEDIUMFONT) +
-               BC_TextBox::calculate_h(gui, MEDIUMFONT, 1, 1);
+       int result = 0;
+       load_mode_geometry(gui, theme, use_nothing, use_nested, line_wrap,
+                       0, &result);
+       return result;
 }
 
-char* LoadMode::mode_to_text()
+void LoadMode::create_objects()
 {
-       for(int i = 0; i < load_modes.total; i++)
-       {
-               if(load_modes.values[i]->value == *output)
-                       return load_modes.values[i]->get_text();
+       int pad = 5;
+       load_title = new BC_Title(x, y, LOADMODE_LOAD_TEXT);
+       window->add_subwindow(load_title);
+       int mw = load_title->get_w(), mh = load_title->get_h();
+       int ix = mw + 2*pad, iy = 0, x1 = ix;
+       int ww = mwindow->theme->loadmode_w + 24;
+       if( mw < ww ) mw = ww;
+
+       for( int i=0; i<TOTAL_LOADMODES; ++i ) {
+               int *mode_set = load_mode;
+               switch( i ) {
+               case LOADMODE_NOTHING:
+                       if( !use_nothing) continue;
+                       break;
+               case LOADMODE_EDL_CLIP:
+               case LOADMODE_EDL_NESTED:
+               case LOADMODE_EDL_FILEREF:
+                       if( !edl_mode ) continue;
+                       mode_set = edl_mode;
+                       if( iy ) break;
+                       ix = 0;  iy = mh + pad;
+                       edl_title = new BC_Title(x+ix, y+iy, LOADMODE_EDL_TEXT);
+                       window->add_subwindow(edl_title);
+                       ix += bmax(load_title->get_w(), edl_title->get_w()) + 2*pad;
+                       break;
+               }
+               load_modes.append(new LoadModeItem(_(mode_text[i]), i));
+               int text_line, w, h, toggle_x, toggle_y;
+               int text_x, text_y, text_w, text_h;
+               BC_Toggle::calculate_extents(window,
+                       mwindow->theme->get_image_set(mode_images[i]), 0,
+                       &text_line, &w, &h, &toggle_x, &toggle_y,
+                       &text_x, &text_y, &text_w, &text_h, 0, MEDIUMFONT);
+               if( line_wrap && ix+w > ww ) { ix = x1;  iy += h+pad; }
+               mode[i] = new LoadModeToggle(x+ix, y+iy, this, i,
+                       mode_set, mode_images[i], _(mode_text[i]));
+               window->add_subwindow(mode[i]);
+               if( (ix+=w) > mw ) mw = ix;
+               if( (h+=iy) > mh ) mh = h;
+               ix += pad;
        }
-       return _("Unknown");
+
+       ix = xS(25);  iy = mh+pad;
+       const char *mode_text = mode_to_text(*load_mode);
+       textbox = new BC_TextBox(x+ix, y+iy,
+               mwindow->theme->loadmode_w-2*ix, 1, mode_text);
+       window->add_subwindow(textbox);
+       ix += textbox->get_w();
+       listbox = new LoadModeListBox(window, this, x+ix, y+iy);
+       window->add_subwindow(listbox);
+       mh = iy + textbox->get_h();
+       update();
 }
 
-int LoadMode::create_objects()
+int LoadMode::reposition_window(int x, int y)
 {
-       int x = this->x, y = this->y;
-       char *default_text;
-       default_text = mode_to_text();
+       this->x = x;  this->y = y;
+       load_title->reposition_window(x, y);
+       int mw = load_title->get_w(), mh = load_title->get_h();
+       int pad = xS(5);
+       int ix = mw + 2*pad, iy = 0, x1 = ix;
+       int ww = mwindow->theme->loadmode_w + xS(24);
+       if( mw < ww ) mw = ww;
 
-       window->add_subwindow(title = new BC_Title(x, y, _("Insertion strategy:")));
-       y += title->get_h();
-       window->add_subwindow(textbox = new BC_TextBox(x, y,
-               mwindow->theme->loadmode_w, 1, default_text));
-       x += textbox->get_w();
-       window->add_subwindow(listbox = new LoadModeListBox(window, this, x, y));
+       for( int i=0; i<TOTAL_LOADMODES; ++i ) {
+               switch( i ) {
+               case LOADMODE_NOTHING:
+                       if( !use_nothing) continue;
+                       break;
+               case LOADMODE_EDL_CLIP:
+               case LOADMODE_EDL_NESTED:
+               case LOADMODE_EDL_FILEREF:
+                       if( !edl_mode ) continue;
+                       if( iy ) break;
+                       ix = 0;  iy = mh + pad;
+                       edl_title->reposition_window(x+ix, y+iy);
+                       ix += bmax(load_title->get_w(), edl_title->get_w()) + 2*pad;
+                       break;
+               }
+               int text_line, w, h, toggle_x, toggle_y;
+               int text_x, text_y, text_w, text_h;
+               BC_Toggle::calculate_extents(window,
+                       mwindow->theme->get_image_set(mode_images[i]), 0,
+                       &text_line, &w, &h, &toggle_x, &toggle_y,
+                       &text_x, &text_y, &text_w, &text_h, 0, MEDIUMFONT);
+               if( line_wrap && ix+w > ww ) { ix = x1;  iy += h+pad; }
+               mode[i]->reposition_window(x+ix, y+iy);
+               if( (ix+=w) > mw ) mw = ix;
+               if( (h+=iy) > mh ) mh = h;
+               ix += pad;
+       }
 
+       ix = xS(25);  iy = mh+pad;
+       textbox->reposition_window(x+ix, y+iy);
+       ix += textbox->get_w();
+       listbox->reposition_window(x+ix, y+iy);
        return 0;
 }
 
 int LoadMode::get_h()
 {
        int result = 0;
-       result = MAX(result, title->get_h());
-       result = MAX(result, textbox->get_h());
+       load_mode_geometry(window, mwindow->theme,
+                       use_nothing, edl_mode!=0, line_wrap, 0, &result);
        return result;
 }
 
@@ -127,36 +299,35 @@ int LoadMode::get_y()
        return y;
 }
 
-int LoadMode::reposition_window(int x, int y)
+void LoadMode::update()
 {
-       this->x = x;
-       this->y = y;
-       title->reposition_window(x, y);
-       y += 20;
-       textbox->reposition_window(x, y);
-       x += textbox->get_w();
-       listbox->reposition_window(x,
-               y,
-               mwindow->theme->loadmode_w);
-       return 0;
+       for( int i=0; i<TOTAL_LOADMODES; ++i ) {
+               if( !mode[i] ) continue;
+               int v = 0;
+               if( *load_mode == i ) v = 1;
+               if( edl_mode && *edl_mode == i ) v = 1;
+               mode[i]->set_value(v);
+       }
+       for( int k=0; k<load_modes.total; ++k ) {
+               int i = load_modes[k]->value, v = 0;
+               if( *load_mode == i ) v = 1;
+               if( edl_mode && *edl_mode == i ) v = 1;
+               load_modes[k]->set_selected(v);
+       }
+       textbox->update(mode_to_text(*load_mode));
 }
 
+int LoadMode::set_line_wrap(int v)
+{
+       int ret = line_wrap;
+       line_wrap = v;
+       return ret;
+}
 
-LoadModeListBox::LoadModeListBox(BC_WindowBase *window,
-       LoadMode *loadmode,
-       int x,
-       int y)
- : BC_ListBox(x,
-       y,
-       loadmode->mwindow->theme->loadmode_w,
-       150,
-       LISTBOX_TEXT,
-       (ArrayList<BC_ListBoxItem *>*)&loadmode->load_modes,
-       0,
-       0,
-       1,
-       0,
-       1)
+LoadModeListBox::LoadModeListBox(BC_WindowBase *window, LoadMode *loadmode,
+               int x, int y)
+ : BC_ListBox(x, y, loadmode->mwindow->theme->loadmode_w, yS(150), LISTBOX_TEXT,
+       (ArrayList<BC_ListBoxItem *>*)&loadmode->load_modes, 0, 0, 1, 0, 1)
 {
        this->window = window;
        this->loadmode = loadmode;
@@ -169,14 +340,13 @@ LoadModeListBox::~LoadModeListBox()
 int LoadModeListBox::handle_event()
 {
        LoadModeItem *item = (LoadModeItem *)get_selection(0, 0);
-       if( item ) {
-               loadmode->textbox->update(item->get_text());
-               *(loadmode->output) = item->value;
-       }
+       if( !item ) return 1;
+       int mode = item->value;
+       if( mode < LOADMODE_EDL_CLIP )
+               *loadmode->load_mode = mode;
+       else if( loadmode->edl_mode )
+               *loadmode->edl_mode = mode;
+       loadmode->update();
        return 1;
 }
 
-
-
-
-