ctrl_toggle preference, dblclk select single group/edit, update shortcuts
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / channelpicker.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2011 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 "batch.h"
23 #include "bcsignals.h"
24 #include "channel.h"
25 #include "channeldb.h"
26 #include "channeledit.h"
27 #include "channelpicker.h"
28 #include "chantables.h"
29 #include "clip.h"
30 #include "edl.h"
31 #include "edlsession.h"
32 #include "keys.h"
33 #include "language.h"
34 #include "mwindow.h"
35 #include "picture.h"
36 #include "playbackconfig.h"
37 #include "preferencesthread.h"
38 #include "record.h"
39 #include "recordgui.h"
40 #include "recordmonitor.h"
41 #include "theme.h"
42 #include "vdeviceprefs.h"
43 #include "videodevice.h"
44
45 RecordChannelPicker::RecordChannelPicker(MWindow *mwindow,
46         Record *record,
47         RecordMonitor *record_monitor,
48         BC_WindowBase *parent_window,
49         ChannelDB *channeldb,
50         int x,
51         int y)
52  : ChannelPicker(mwindow,
53                 channeldb,
54                 x,
55                 y,
56                 parent_window)
57 {
58         this->record = record;
59         this->record_monitor = record_monitor;
60 }
61
62 RecordChannelPicker::~RecordChannelPicker()
63 {
64 }
65
66 int RecordChannelPicker::use_select()
67 {
68         return 1;
69 }
70
71 Channel* RecordChannelPicker::get_master_channel()
72 {
73         return record->master_channel;
74 }
75
76 void RecordChannelPicker::handle_channel_edit(int result)
77 {
78         if(!result)
79         {
80                 record->record_gui->lock_window("RecordChannelPicker::handle_channel_edit 1");
81                 record->record_gui->update_batch_sources();
82                 record->set_channel(get_master_channel());
83                 record->record_gui->unlock_window();
84                 record->save_defaults();
85                 VideoDevice::save_channeldb(record->channeldb,
86                         mwindow->edl->session->vconfig_in);
87         }
88         else
89         {
90                 record->record_gui->lock_window("RecordChannelPicker::handle_channel_edit 2");
91                 record->set_channel(record->get_current_channel());
92                 record->record_gui->unlock_window();
93         }
94
95         mwindow->save_defaults();
96 }
97
98 void RecordChannelPicker::load_scan_defaults(Channel *scan_params)
99 {
100         scan_params->load_defaults(mwindow->defaults);
101 }
102
103 void RecordChannelPicker::save_scan_defaults(Channel *scan_params)
104 {
105         scan_params->save_defaults(mwindow->defaults);
106 }
107
108 BC_Theme* RecordChannelPicker::get_theme()
109 {
110         return mwindow->theme;
111 }
112
113
114 Channel* RecordChannelPicker::get_current_channel()
115 {
116         return record->get_current_channel();
117 }
118
119 Channel *RecordChannelPicker::get_editing_channel()
120 {
121         return record->get_editing_channel();
122 }
123
124 ArrayList<Channel*>* RecordChannelPicker::get_video_inputs()
125 {
126         return record->get_video_inputs();
127 }
128
129 Channel* RecordChannelPicker::get_channel_usage()
130 {
131         return record->master_channel;
132 }
133
134 void RecordChannelPicker::set_channel_number(int number)
135 {
136         if( number < 0 || number >= channeldb->size() ) return;
137         Channel *channel = channeldb->get(number);
138         if( channel ) record->set_channel(channel);
139 }
140
141 void RecordChannelPicker::set_brightness(int value)
142 {
143         if(record)
144         {
145                 record->picture->brightness = value;
146                 record->set_video_picture();
147         }
148 }
149
150 void RecordChannelPicker::set_hue(int value)
151 {
152         if(record)
153         {
154                 record->picture->hue = value;
155                 record->set_video_picture();
156         }
157 }
158
159 void RecordChannelPicker::set_color(int value)
160 {
161         if(record)
162         {
163                 record->picture->color = value;
164                 record->set_video_picture();
165         }
166 }
167
168 void RecordChannelPicker::set_contrast(int value)
169 {
170         if(record)
171         {
172                 record->picture->contrast = value;
173                 record->set_video_picture();
174         }
175 }
176
177 void RecordChannelPicker::set_whiteness(int value)
178 {
179         if(record)
180         {
181                 record->picture->whiteness = value;
182                 record->set_video_picture();
183         }
184 }
185
186 int RecordChannelPicker::set_picture(int device_id, int value)
187 {
188         if(record)
189         {
190                 if(record->picture->set_item(device_id, value))
191                         record->set_video_picture();
192         }
193         return 0;
194 }
195
196
197 int RecordChannelPicker::get_brightness()
198 {
199         if(record) return record->picture->brightness;
200         return 0;
201 }
202
203 int RecordChannelPicker::get_hue()
204 {
205         if(record) return record->picture->hue;
206         return 0;
207 }
208
209 int RecordChannelPicker::get_color()
210 {
211         if(record) return record->picture->color;
212         return 0;
213 }
214
215 int RecordChannelPicker::get_contrast()
216 {
217         if(record) return record->picture->contrast;
218         return 0;
219 }
220
221 int RecordChannelPicker::get_whiteness()
222 {
223         if(record) return record->picture->whiteness;
224         return 0;
225 }
226
227 int RecordChannelPicker::get_controls()
228 {
229         if(record) return record->picture->controls.total;
230         return 0;
231 }
232
233 PictureItem* RecordChannelPicker::get_control(int i)
234 {
235         if(record) return record->picture->controls.values[i];
236         return 0;
237 }
238
239 PictureConfig* RecordChannelPicker::get_picture_usage()
240 {
241         if(record) return record->picture;
242         return 0;
243 }
244
245
246
247 void RecordChannelPicker::set_channel(Channel *channel)
248 {
249         record->set_channel(channel);
250 }
251
252 int RecordChannelPicker::has_signal()
253 {
254         return record->has_signal();
255 }
256
257 int RecordChannelPicker::create_channeldb(ArrayList<Channel*> *channeldb)
258 {
259         return record->create_channeldb(channeldb);
260 }
261
262
263
264
265
266
267
268
269
270 PrefsChannelPicker::PrefsChannelPicker(MWindow *mwindow,
271                 VDevicePrefs *prefs,
272                 ChannelDB *channeldb,
273                 int x,
274                 int y)
275  : ChannelPicker(mwindow,
276                 channeldb,
277                 x,
278                 y,
279                 prefs->dialog)
280 {
281 //      printf("PrefsChannelPicker::PrefsChannelPicker 1\n");
282         this->prefs = prefs;
283 }
284
285 PrefsChannelPicker::~PrefsChannelPicker()
286 {
287         input_sources.remove_all_objects();
288 }
289
290 void PrefsChannelPicker::load_scan_defaults(Channel *scan_params)
291 {
292         scan_params->load_defaults(mwindow->defaults);
293 }
294
295 void PrefsChannelPicker::save_scan_defaults(Channel *scan_params)
296 {
297         scan_params->save_defaults(mwindow->defaults);
298 }
299
300 void PrefsChannelPicker::handle_channel_edit(int result)
301 {
302         mwindow->save_defaults();
303 }
304
305 BC_Theme* PrefsChannelPicker::get_theme()
306 {
307         return mwindow->theme;
308 }
309
310
311 ArrayList<Channel*>* PrefsChannelPicker::get_video_inputs()
312 {
313         return &input_sources;
314 }
315
316 Channel* PrefsChannelPicker::get_channel_usage()
317 {
318         return 0;
319 }
320
321
322 void PrefsChannelPicker::set_channel(Channel *channel)
323 {
324         if(channel)
325                 channel_text->update(channel->title);
326 }
327
328 Channel *PrefsChannelPicker::get_current_channel()
329 {
330         int number = prefs->out_config->out_channel;
331         return channeldb->get(number);
332 }
333
334 void PrefsChannelPicker::set_channel_number(int number)
335 {
336         CLAMP(number, 0, channeldb->size() - 1);
337         prefs->out_config->out_channel = number;
338         set_channel(get_current_channel());
339 }
340
341 int PrefsChannelPicker::has_signal()
342 {
343         return 0;
344 }
345
346 void PrefsChannelPicker::set_brightness(int value)
347 {
348         prefs->out_config->brightness = value;
349 }
350
351 void PrefsChannelPicker::set_hue(int value)
352 {
353         prefs->out_config->hue = value;
354 }
355
356 void PrefsChannelPicker::set_color(int value)
357 {
358         prefs->out_config->color = value;
359 }
360
361 void PrefsChannelPicker::set_contrast(int value)
362 {
363         prefs->out_config->contrast = value;
364 }
365
366 void PrefsChannelPicker::set_whiteness(int value)
367 {
368         prefs->out_config->whiteness = value;
369 }
370
371 int PrefsChannelPicker::get_brightness()
372 {
373         return prefs->out_config->brightness;
374 }
375
376 int PrefsChannelPicker::get_hue()
377 {
378         return prefs->out_config->hue;
379 }
380
381 int PrefsChannelPicker::get_color()
382 {
383         return prefs->out_config->color;
384 }
385
386 int PrefsChannelPicker::get_contrast()
387 {
388         return prefs->out_config->contrast;
389 }
390
391 int PrefsChannelPicker::get_whiteness()
392 {
393         return prefs->out_config->whiteness;
394 }
395
396
397
398
399
400
401 ChannelPicker::ChannelPicker(MWindow *mwindow,
402                 ChannelDB *channeldb,
403                 int x,
404                 int y,
405                 BC_WindowBase *parent_window)
406 {
407         this->mwindow = mwindow;
408         this->parent_window = parent_window;
409         this->x = x;
410         this->y = y;
411         this->channeldb = channeldb;
412         channel_text = 0;
413         channel_select = 0;
414         channel_button = 0;
415         update_channel_list();
416 }
417
418 ChannelPicker::~ChannelPicker()
419 {
420         delete channel_text;
421         delete channel_select;
422         delete channel_button;
423         channel_listitems.remove_all_objects();
424 }
425
426 void ChannelPicker::update_channel_list()
427 {
428         channel_listitems.remove_all_objects();
429         for(int i = 0; i < channeldb->size(); i++)
430         {
431                 channel_listitems.append(new BC_ListBoxItem(channeldb->get(i)->title));
432         }
433
434         if(channel_text)
435                 channel_text->update_list(&channel_listitems);
436 }
437
438 int ChannelPicker::get_w()
439 {
440         return channel_text->get_w() +
441                 channel_select->get_w() +
442                 channel_button->get_w() +
443                 picture_button->get_w() +
444                 ((Theme*)get_theme())->widget_border * 4;
445 }
446
447
448
449
450
451
452 BC_WindowBase* ChannelPicker::get_subwindow()
453 {
454         return parent_window;
455         return 0;
456 }
457
458
459
460
461
462
463
464 void ChannelPicker::create_objects()
465 {
466         channel_text = 0;
467         update_channel_list();
468
469
470         channel_text = new ChannelText(this, x, y);
471         channel_text->create_objects();
472
473
474         x += channel_text->get_w() + ((Theme*)get_theme())->widget_border;
475         get_subwindow()->add_subwindow(channel_select = new ChannelTumbler(this,
476                 x,
477                 y));
478
479
480         x += channel_select->get_w() + ((Theme*)get_theme())->widget_border;
481         get_subwindow()->add_subwindow(channel_button = new ChannelButton(this,
482                 x,
483                 y - 1));
484
485 //PRINT_TRACE
486         x += channel_button->get_w() + ((Theme*)get_theme())->widget_border;
487         get_subwindow()->add_subwindow(picture_button = new PictureButton(this,
488                 x,
489                 y - 1));
490 //PRINT_TRACE
491
492 }
493
494 int ChannelPicker::reposition()
495 {
496         channel_text->reposition_window(channel_text->get_x(),
497                 channel_text->get_y());
498         channel_select->reposition_window(channel_select->get_x(),
499                 channel_select->get_y());
500         channel_button->reposition_window(channel_button->get_x(),
501                 channel_button->get_y());
502         return 0;
503 }
504
505 void ChannelPicker::close_threads()
506 {
507         channel_button->thread->close_threads();
508 }
509
510 const char* ChannelPicker::get_source_name(Channel *channel)
511 {
512         if(channel->entry < chanlists[channel->freqtable].count)
513                 return chanlists[channel->freqtable].list[channel->entry].name;
514         else
515                 return chanlists[channel->freqtable].list[0].name;
516 }
517
518 const char* ChannelPicker::current_channel_name()
519 {
520         if(get_current_channel())
521                 return get_current_channel()->title;
522         return _("Channel");
523 }
524
525 int ChannelPicker::channel_down()
526 {
527         Channel *channel = get_current_channel();
528         if( !channel ) return 1;
529         int number = channeldb->number_of(channel);
530         if( number < 0 ) return 1;
531         if( --number < 0 ) number = 0;
532         set_channel_number(number);
533         return 0;
534 }
535
536 int ChannelPicker::channel_up()
537 {
538         Channel *channel = get_current_channel();
539         if( !channel ) return 1;
540         int number = channeldb->number_of(channel);
541         if( number < 0 ) return 1;
542         if( ++number >= channeldb->size() ) number = channeldb->size()-1;
543         set_channel_number(number);
544         return 0;
545 }
546
547
548
549
550
551 PictureButton::PictureButton(ChannelPicker *channel_picker, int x, int y)
552  : BC_Button(x,
553         y,
554         channel_picker->get_theme() ?
555                 channel_picker->get_theme()->get_image_set("picture") :
556                 0)
557 {
558         this->channel_picker = channel_picker;
559         thread = new ChannelEditPictureThread(channel_picker);
560         set_tooltip(_("Edit picture"));
561 }
562
563 PictureButton::~PictureButton()
564 {
565 //printf("PictureButton::PictureButton %d\n", __LINE__);
566         delete thread;
567 //printf("PictureButton::PictureButton %d\n", __LINE__);
568 }
569
570 int PictureButton::handle_event()
571 {
572         unlock_window();
573         thread->edit_picture();
574         lock_window("PictureButton::handle_event");
575         return 1;
576 }
577
578
579
580
581 ChannelButton::ChannelButton(ChannelPicker *channel_picker, int x, int y)
582  : BC_Button(x, y, channel_picker->get_theme() ?
583                 channel_picker->get_theme()->get_image_set("channel") :
584                 0)
585 {
586         this->channel_picker = channel_picker;
587         thread = new ChannelEditThread(channel_picker,
588                 channel_picker->channeldb);
589         set_tooltip(_("Edit channels"));
590 }
591
592 ChannelButton::~ChannelButton()
593 {
594         delete thread;
595 }
596
597 int ChannelButton::handle_event()
598 {
599         thread->start();
600         return 1;
601 }
602
603
604 ChannelText::ChannelText(ChannelPicker *channel_picker, int x, int y)
605  : BC_PopupTextBox(channel_picker->get_subwindow(),
606         &channel_picker->channel_listitems,
607         channel_picker->current_channel_name(),
608         x, y, 200, 300)
609 {
610
611         this->channel_picker = channel_picker;
612 }
613
614 ChannelText::~ChannelText()
615 {
616 }
617
618 int ChannelText::handle_event()
619 {
620         channel_picker->set_channel_number(get_number());
621         return 0;
622 }
623
624
625
626
627 ChannelList::ChannelList(ChannelPicker *channel_picker, int x, int y)
628  : BC_ListBox(x, y, 100, 200,
629         LISTBOX_TEXT,  // Display text list or icons
630         &channel_picker->channel_listitems, // Each column has an ArrayList of BC_ListBoxItems.
631         0,    // Titles for columns.  Set to 0 for no titles
632         0,    // width of each column
633         1,    // Total columns.
634         0,    // Pixel of top of window.
635         1)    // If this listbox is a popup window
636 {
637         this->channel_picker = channel_picker;
638 }
639
640 ChannelList::~ChannelList()
641 {
642 }
643
644 int ChannelList::handle_event()
645 {
646         return 0;
647 }
648
649
650
651 ChannelTumbler::ChannelTumbler(ChannelPicker *channel_picker,
652         int x,
653         int y)
654  : BC_Tumbler(x, y)
655 {
656         this->channel_picker = channel_picker;
657 }
658 ChannelTumbler::~ChannelTumbler()
659 {
660 }
661 int ChannelTumbler::handle_up_event()
662 {
663         channel_picker->channel_up();
664         return 1;
665 }
666 int ChannelTumbler::handle_down_event()
667 {
668         channel_picker->channel_down();
669         return 1;
670 }
671 int ChannelTumbler::keypress_event()
672 {
673         if(get_keypress() == PGUP)
674         {
675                 handle_up_event();
676                 return 1;
677         }
678         else
679         if(get_keypress() == PGDN)
680         {
681                 handle_down_event();
682                 return 1;
683         }
684         else
685         return 0;
686 }
687
688