Credit Andrew fix Alpha Bug of BT558 + small cleanup
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / loadmode.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21
22 #include "clip.h"
23 #include "language.h"
24 #include "loadmode.h"
25 #include "mwindow.h"
26 #include "theme.h"
27
28 #define LOADMODE_LOAD_TEXT _("Load strategy:")
29 #define LOADMODE_EDL_TEXT _("EDL strategy:")
30
31 // Must match macros
32 static const char *mode_images[] =
33 {
34         "loadmode_none",
35         "loadmode_new",
36         "loadmode_newcat",
37         "loadmode_newtracks",
38         "loadmode_cat",
39         "loadmode_paste",
40         "loadmode_resource",
41         "loadmode_edl_clip",
42         "loadmode_edl_nested",
43         "loadmode_edl_fileref",
44 };
45
46 static const char *mode_text[] =
47 {
48         N_("Insert nothing"),
49         N_("Replace current project"),
50         N_("Replace current project and concatenate tracks"),
51         N_("Append in new tracks"),
52         N_("Concatenate to existing tracks"),
53         N_("Paste over selection/at insertion point"),
54         N_("Create new resources only"),
55         N_("EDL"),
56         N_("Nested"),
57         N_("Reference"),
58 };
59
60
61 LoadModeItem::LoadModeItem(const char *text, int value)
62  : BC_ListBoxItem(text)
63 {
64         this->value = value;
65 }
66
67
68 LoadModeToggle::LoadModeToggle(int x, int y, LoadMode *window, int id,
69                 int *output, const char *images, const char *tooltip)
70  : BC_Toggle(x, y, window->mwindow->theme->get_image_set(images), *output)
71 {
72         this->window = window;
73         this->id = id;
74         this->output = output;
75         set_tooltip(tooltip);
76 }
77
78 int LoadModeToggle::handle_event()
79 {
80         *output = id;
81         window->update();
82         return 1;
83 }
84
85
86
87 LoadMode::LoadMode(MWindow *mwindow, BC_WindowBase *window,
88                 int x, int y, int *load_mode, int *edl_mode,
89                 int use_nothing, int line_wrap)
90 {
91         this->mwindow = mwindow;
92         this->window = window;
93         this->x = x;
94         this->y = y;
95         this->load_mode = load_mode;
96         this->edl_mode = edl_mode;
97         this->use_nothing = use_nothing;
98         this->line_wrap = line_wrap;
99         for( int i=0; i<TOTAL_LOADMODES; ++i ) mode[i] = 0;
100         load_title = 0;
101         edl_title = 0;
102 }
103
104 LoadMode::~LoadMode()
105 {
106         load_modes.remove_all_objects();
107         for( int i=0; i<TOTAL_LOADMODES; ++i ) delete mode[i];
108 }
109
110 const char *LoadMode::mode_to_text(int mode)
111 {
112         for( int i=0; i<load_modes.total; ++i ) {
113                 if( load_modes[i]->value == mode )
114                         return load_modes[i]->get_text();
115         }
116         return _("Unknown");
117 }
118
119 void LoadMode::load_mode_geometry(BC_WindowBase *gui, Theme *theme,
120                 int use_nothing, int use_nested, int line_wrap,
121                 int *pw, int *ph)
122 {
123         int pad = 5;
124         const char *load_text = LOADMODE_LOAD_TEXT;
125         int mw = BC_Title::calculate_w(gui, load_text);
126         int mh = BC_Title::calculate_h(gui, load_text);
127         int ix = mw + 2*pad, iy = 0, x1 = ix;
128         int ww = theme->loadmode_w + 24;
129         if( mw < ww ) mw = ww;
130
131         for( int i=0; i<TOTAL_LOADMODES; ++i ) {
132                 switch( i ) {
133                 case LOADMODE_NOTHING:
134                         if( !use_nothing) continue;
135                         break;
136                 case LOADMODE_EDL_CLIP:
137                 case LOADMODE_EDL_NESTED:
138                 case LOADMODE_EDL_FILEREF:
139                         if( !use_nested ) continue;
140                         if( iy ) break;
141                         ix = 0;  iy = mh + pad;
142                         const char *edl_text = LOADMODE_EDL_TEXT;
143                         ix += bmax(BC_Title::calculate_w(gui, load_text),
144                                    BC_Title::calculate_w(gui, edl_text)) + 2*pad;
145                         break;
146                 }
147                 int text_line, w, h, toggle_x, toggle_y;
148                 int text_x, text_y, text_w, text_h;
149                 BC_Toggle::calculate_extents(gui,
150                         theme->get_image_set(mode_images[i]), 0,
151                         &text_line, &w, &h, &toggle_x, &toggle_y,
152                         &text_x, &text_y, &text_w, &text_h, 0, MEDIUMFONT);
153                 if( line_wrap && ix+w > ww ) { ix = x1;  iy += h+pad; }
154                 if( (ix+=w) > mw ) mw = ix;
155                 if( (h+=iy) > mh ) mh = h;
156                 ix += pad;
157         }
158
159         ix = 0;  iy = mh+pad;
160         mh = iy + BC_TextBox::calculate_h(gui, MEDIUMFONT, 1, 1);
161         if( pw ) *pw = mw;
162         if( ph ) *ph = mh;
163 }
164
165 int LoadMode::calculate_w(BC_WindowBase *gui, Theme *theme,
166                 int use_nothing, int use_nested, int line_wrap)
167 {
168         int result = 0;
169         load_mode_geometry(gui, theme, use_nothing, use_nested, line_wrap,
170                         &result, 0);
171         return result;
172 }
173
174 int LoadMode::calculate_h(BC_WindowBase *gui, Theme *theme,
175                 int use_nothing, int use_nested, int line_wrap)
176 {
177         int result = 0;
178         load_mode_geometry(gui, theme, use_nothing, use_nested, line_wrap,
179                         0, &result);
180         return result;
181 }
182
183 void LoadMode::create_objects()
184 {
185         int pad = 5;
186         load_title = new BC_Title(x, y, LOADMODE_LOAD_TEXT);
187         window->add_subwindow(load_title);
188         int mw = load_title->get_w(), mh = load_title->get_h();
189         int ix = mw + 2*pad, iy = 0, x1 = ix;
190         int ww = mwindow->theme->loadmode_w + 24;
191         if( mw < ww ) mw = ww;
192
193         for( int i=0; i<TOTAL_LOADMODES; ++i ) {
194                 int *mode_set = load_mode;
195                 switch( i ) {
196                 case LOADMODE_NOTHING:
197                         if( !use_nothing) continue;
198                         break;
199                 case LOADMODE_EDL_CLIP:
200                 case LOADMODE_EDL_NESTED:
201                 case LOADMODE_EDL_FILEREF:
202                         if( !edl_mode ) continue;
203                         mode_set = edl_mode;
204                         if( iy ) break;
205                         ix = 0;  iy = mh + pad;
206                         edl_title = new BC_Title(x+ix, y+iy, LOADMODE_EDL_TEXT);
207                         window->add_subwindow(edl_title);
208                         ix += bmax(load_title->get_w(), edl_title->get_w()) + 2*pad;
209                         break;
210                 }
211                 load_modes.append(new LoadModeItem(_(mode_text[i]), i));
212                 int text_line, w, h, toggle_x, toggle_y;
213                 int text_x, text_y, text_w, text_h;
214                 BC_Toggle::calculate_extents(window,
215                         mwindow->theme->get_image_set(mode_images[i]), 0,
216                         &text_line, &w, &h, &toggle_x, &toggle_y,
217                         &text_x, &text_y, &text_w, &text_h, 0, MEDIUMFONT);
218                 if( line_wrap && ix+w > ww ) { ix = x1;  iy += h+pad; }
219                 mode[i] = new LoadModeToggle(x+ix, y+iy, this, i,
220                         mode_set, mode_images[i], _(mode_text[i]));
221                 window->add_subwindow(mode[i]);
222                 if( (ix+=w) > mw ) mw = ix;
223                 if( (h+=iy) > mh ) mh = h;
224                 ix += pad;
225         }
226
227         ix = xS(25);  iy = mh+pad;
228         const char *mode_text = mode_to_text(*load_mode);
229         textbox = new BC_TextBox(x+ix, y+iy,
230                 mwindow->theme->loadmode_w-2*ix, 1, mode_text);
231         window->add_subwindow(textbox);
232         ix += textbox->get_w();
233         listbox = new LoadModeListBox(window, this, x+ix, y+iy);
234         window->add_subwindow(listbox);
235         mh = iy + textbox->get_h();
236         update();
237 }
238
239 int LoadMode::reposition_window(int x, int y)
240 {
241         this->x = x;  this->y = y;
242         load_title->reposition_window(x, y);
243         int mw = load_title->get_w(), mh = load_title->get_h();
244         int pad = xS(5);
245         int ix = mw + 2*pad, iy = 0, x1 = ix;
246         int ww = mwindow->theme->loadmode_w + xS(24);
247         if( mw < ww ) mw = ww;
248
249         for( int i=0; i<TOTAL_LOADMODES; ++i ) {
250                 switch( i ) {
251                 case LOADMODE_NOTHING:
252                         if( !use_nothing) continue;
253                         break;
254                 case LOADMODE_EDL_CLIP:
255                 case LOADMODE_EDL_NESTED:
256                 case LOADMODE_EDL_FILEREF:
257                         if( !edl_mode ) continue;
258                         if( iy ) break;
259                         ix = 0;  iy = mh + pad;
260                         edl_title->reposition_window(x+ix, y+iy);
261                         ix += bmax(load_title->get_w(), edl_title->get_w()) + 2*pad;
262                         break;
263                 }
264                 int text_line, w, h, toggle_x, toggle_y;
265                 int text_x, text_y, text_w, text_h;
266                 BC_Toggle::calculate_extents(window,
267                         mwindow->theme->get_image_set(mode_images[i]), 0,
268                         &text_line, &w, &h, &toggle_x, &toggle_y,
269                         &text_x, &text_y, &text_w, &text_h, 0, MEDIUMFONT);
270                 if( line_wrap && ix+w > ww ) { ix = x1;  iy += h+pad; }
271                 mode[i]->reposition_window(x+ix, y+iy);
272                 if( (ix+=w) > mw ) mw = ix;
273                 if( (h+=iy) > mh ) mh = h;
274                 ix += pad;
275         }
276
277         ix = xS(25);  iy = mh+pad;
278         textbox->reposition_window(x+ix, y+iy);
279         ix += textbox->get_w();
280         listbox->reposition_window(x+ix, y+iy);
281         return 0;
282 }
283
284 int LoadMode::get_h()
285 {
286         int result = 0;
287         load_mode_geometry(window, mwindow->theme,
288                         use_nothing, edl_mode!=0, line_wrap, 0, &result);
289         return result;
290 }
291
292 int LoadMode::get_x()
293 {
294         return x;
295 }
296
297 int LoadMode::get_y()
298 {
299         return y;
300 }
301
302 void LoadMode::update()
303 {
304         for( int i=0; i<TOTAL_LOADMODES; ++i ) {
305                 if( !mode[i] ) continue;
306                 int v = 0;
307                 if( *load_mode == i ) v = 1;
308                 if( edl_mode && *edl_mode == i ) v = 1;
309                 mode[i]->set_value(v);
310         }
311         for( int k=0; k<load_modes.total; ++k ) {
312                 int i = load_modes[k]->value, v = 0;
313                 if( *load_mode == i ) v = 1;
314                 if( edl_mode && *edl_mode == i ) v = 1;
315                 load_modes[k]->set_selected(v);
316         }
317         textbox->update(mode_to_text(*load_mode));
318 }
319
320 int LoadMode::set_line_wrap(int v)
321 {
322         int ret = line_wrap;
323         line_wrap = v;
324         return ret;
325 }
326
327 LoadModeListBox::LoadModeListBox(BC_WindowBase *window, LoadMode *loadmode,
328                 int x, int y)
329  : BC_ListBox(x, y, loadmode->mwindow->theme->loadmode_w, yS(150), LISTBOX_TEXT,
330         (ArrayList<BC_ListBoxItem *>*)&loadmode->load_modes, 0, 0, 1, 0, 1)
331 {
332         this->window = window;
333         this->loadmode = loadmode;
334 }
335
336 LoadModeListBox::~LoadModeListBox()
337 {
338 }
339
340 int LoadModeListBox::handle_event()
341 {
342         LoadModeItem *item = (LoadModeItem *)get_selection(0, 0);
343         if( !item ) return 1;
344         int mode = item->value;
345         if( mode < LOADMODE_EDL_CLIP )
346                 *loadmode->load_mode = mode;
347         else if( loadmode->edl_mode )
348                 *loadmode->edl_mode = mode;
349         loadmode->update();
350         return 1;
351 }
352