4 * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
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.
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.
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
24 #include "bcsignals.h"
26 #include "condition.h"
28 #include "edlsession.h"
29 #include "gwindowgui.h"
32 #include "localsession.h"
34 #include "mainsession.h"
36 #include "mwindowgui.h"
39 #include "trackcanvas.h"
46 GWindowGUI::GWindowGUI(MWindow *mwindow, int w, int h)
47 : BC_Window(_(PROGRAM_NAME ": Overlays"),
48 mwindow->session->gwindow_x, mwindow->session->gwindow_y,
51 this->mwindow = mwindow;
57 GWindowGUI::~GWindowGUI()
62 void GWindowGUI::start_color_thread(GWindowColorButton *color_button)
66 color_thread = new GWindowColorThread(this, color_button);
67 int color = auto_colors[color_button->auto_toggle->info->ref];
68 color_thread->start(color);
69 lock_window("GWindowGUI::start_color_thread");
72 const char *GWindowGUI::non_auto_text[NON_AUTOMATION_TOTAL] =
77 N_("Plugin Keyframes"),
80 const char *GWindowGUI::auto_text[AUTOMATION_TOTAL] =
96 int GWindowGUI::auto_colors[AUTOMATION_TOTAL] =
112 void GWindowGUI::load_defaults()
114 BC_Hash *defaults = mwindow->defaults;
115 auto_colors[AUTOMATION_MUTE] = defaults->get("AUTO_COLOR_MUTE", auto_colors[AUTOMATION_MUTE]);
116 auto_colors[AUTOMATION_CAMERA_X] = defaults->get("AUTO_COLOR_CAMERA_X", auto_colors[AUTOMATION_CAMERA_X]);
117 auto_colors[AUTOMATION_CAMERA_Y] = defaults->get("AUTO_COLOR_CAMERA_Y", auto_colors[AUTOMATION_CAMERA_Y]);
118 auto_colors[AUTOMATION_CAMERA_Z] = defaults->get("AUTO_COLOR_CAMERA_Z", auto_colors[AUTOMATION_CAMERA_Z]);
119 auto_colors[AUTOMATION_PROJECTOR_X] = defaults->get("AUTO_COLOR_PROJECTOR_X", auto_colors[AUTOMATION_PROJECTOR_X]);
120 auto_colors[AUTOMATION_PROJECTOR_Y] = defaults->get("AUTO_COLOR_PROJECTOR_Y", auto_colors[AUTOMATION_PROJECTOR_Y]);
121 auto_colors[AUTOMATION_PROJECTOR_Z] = defaults->get("AUTO_COLOR_PROJECTOR_Z", auto_colors[AUTOMATION_PROJECTOR_Z]);
122 auto_colors[AUTOMATION_FADE] = defaults->get("AUTO_COLOR_FADE", auto_colors[AUTOMATION_FADE]);
123 auto_colors[AUTOMATION_SPEED] = defaults->get("AUTO_COLOR_SPEED", auto_colors[AUTOMATION_SPEED]);
126 void GWindowGUI::save_defaults()
128 BC_Hash *defaults = mwindow->defaults;
129 defaults->update("AUTO_COLOR_MUTE", auto_colors[AUTOMATION_MUTE]);
130 defaults->update("AUTO_COLOR_CAMERA_X", auto_colors[AUTOMATION_CAMERA_X]);
131 defaults->update("AUTO_COLOR_CAMERA_Y", auto_colors[AUTOMATION_CAMERA_Y]);
132 defaults->update("AUTO_COLOR_CAMERA_Z", auto_colors[AUTOMATION_CAMERA_Z]);
133 defaults->update("AUTO_COLOR_PROJECTOR_X", auto_colors[AUTOMATION_PROJECTOR_X]);
134 defaults->update("AUTO_COLOR_PROJECTOR_Y", auto_colors[AUTOMATION_PROJECTOR_Y]);
135 defaults->update("AUTO_COLOR_PROJECTOR_Z", auto_colors[AUTOMATION_PROJECTOR_Z]);
136 defaults->update("AUTO_COLOR_FADE", auto_colors[AUTOMATION_FADE]);
137 defaults->update("AUTO_COLOR_SPEED", auto_colors[AUTOMATION_SPEED]);
140 static toggleinfo toggle_order[] =
142 {0, NON_AUTOMATION_ASSETS},
143 {0, NON_AUTOMATION_TITLES},
144 {0, NON_AUTOMATION_TRANSITIONS},
145 {0, NON_AUTOMATION_PLUGIN_AUTOS},
147 {1, AUTOMATION_FADE},
148 {1, AUTOMATION_MUTE},
149 {1, AUTOMATION_SPEED},
150 {1, AUTOMATION_MODE},
152 {1, AUTOMATION_MASK},
154 {1, AUTOMATION_CAMERA_X},
155 {1, AUTOMATION_CAMERA_Y},
156 {1, AUTOMATION_CAMERA_Z},
157 {-1, NONAUTOTOGGLES_CAMERA_XYZ},
159 {1, AUTOMATION_PROJECTOR_X},
160 {1, AUTOMATION_PROJECTOR_Y},
161 {1, AUTOMATION_PROJECTOR_Z},
162 {-1, NONAUTOTOGGLES_PROJECTOR_XYZ},
165 const char *GWindowGUI::toggle_text(toggleinfo *tp)
167 if( tp->isauto > 0 ) return _(auto_text[tp->ref]);
168 if( !tp->isauto ) return _(non_auto_text[tp->ref]);
172 void GWindowGUI::calculate_extents(BC_WindowBase *gui, int *w, int *h)
174 int temp1, temp2, temp3, temp4, temp5, temp6, temp7;
175 int current_w, current_h;
179 for( int i=0; i<(int)(sizeof(toggle_order)/sizeof(toggle_order[0])); ++i ) {
180 toggleinfo *tp = &toggle_order[i];
183 *h += get_resources()->bar_data->get_h() + 5;
186 BC_Toggle::calculate_extents(gui,
187 BC_WindowBase::get_resources()->checkbox_images,
188 0, &temp1, ¤t_w, ¤t_h,
189 &temp2, &temp3, &temp4, &temp5, &temp6, &temp7,
190 toggle_text(tp), MEDIUMFONT);
191 current_w += current_h;
192 *w = MAX(current_w, *w);
200 GWindowColorButton::GWindowColorButton(GWindowToggle *auto_toggle, int x, int y, int w)
201 : BC_Button(x, y, w, vframes)
203 this->auto_toggle = auto_toggle;
205 for( int i=0; i<3; ++i ) {
206 vframes[i] = new VFrame(w, w, BC_RGBA8888);
207 vframes[i]->clear_frame();
211 GWindowColorButton::~GWindowColorButton()
213 for( int i=0; i<3; ++i )
217 void GWindowColorButton::set_color(int color)
220 int r = (color>>16) & 0xff;
221 int g = (color>>8) & 0xff;
222 int b = (color>>0) & 0xff;
223 for( int i=0; i<3; ++i ) {
224 VFrame *vframe = vframes[i];
225 int ww = vframe->get_w(), hh = vframe->get_h();
226 int cx = (ww+1)/2, cy = hh/2;
227 double cc = (cx*cx + cy*cy) / 4.;
228 uint8_t *bp = vframe->get_data(), *dp = bp;
229 uint8_t *ep = dp + vframe->get_data_size();
230 int rr = r, gg = g, bb = b;
231 int bpl = vframe->get_bytes_per_line();
236 if( (rr+=48) > 0xff ) rr = 0xff;
237 if( (gg+=48) > 0xff ) gg = 0xff;
238 if( (bb+=48) > 0xff ) bb = 0xff;
241 if( (rr-=48) < 0x00 ) rr = 0x00;
242 if( (gg-=48) < 0x00 ) gg = 0x00;
243 if( (bb-=48) < 0x00 ) bb = 0x00;
247 int yy = (dp-bp) / bpl, xx = ((dp-bp) % bpl) >> 2;
248 int dy = cy - yy, dx = cx - xx;
249 double s = dx*dx + dy*dy - cc;
250 double ss = s < 0 ? 1 : s >= cc ? 0 : 1 - s/cc;
252 *dp++ = rr; *dp++ = gg; *dp++ = bb; *dp++ = aa;
258 void GWindowColorButton::update_gui(int color)
264 GWindowColorThread::GWindowColorThread(GWindowGUI *gui, GWindowColorButton *color_button)
265 : ColorPicker(0, color_button->auto_toggle->caption)
268 this->color_button = color_button;
270 color_update = new GWindowColorUpdate(this);
273 GWindowColorThread::~GWindowColorThread()
278 void GWindowColorThread::start(int color)
280 start_window(color, 0, 1);
281 color_update->start();
284 void GWindowColorThread::handle_done_event(int result)
286 color_update->stop();
287 int ref = color_button->auto_toggle->info->ref;
288 gui->lock_window("GWindowColorThread::handle_done_event");
290 GWindowGUI::auto_colors[ref] = color;
291 color_button->auto_toggle->update_gui(color);
292 gui->save_defaults();
295 color = GWindowGUI::auto_colors[ref];
296 color_button->update_gui(color);
298 gui->unlock_window();
299 MWindowGUI *mwindow_gui = gui->mwindow->gui;
300 mwindow_gui->lock_window("GWindowColorUpdate::run");
301 mwindow_gui->draw_overlays(1);
302 mwindow_gui->unlock_window();
305 int GWindowColorThread::handle_new_color(int color, int alpha)
308 color_update->update_lock->unlock();
312 void GWindowColorThread::update_gui()
314 gui->lock_window("GWindowColorThread::update_gui");
315 color_button->update_gui(color);
316 gui->unlock_window();
319 GWindowColorUpdate::GWindowColorUpdate(GWindowColorThread *color_thread)
322 this->color_thread = color_thread;
323 this->update_lock = new Condition(0,"GWindowColorUpdate::update_lock");
327 GWindowColorUpdate::~GWindowColorUpdate()
333 void GWindowColorUpdate::start()
341 void GWindowColorUpdate::stop()
345 update_lock->unlock();
350 void GWindowColorUpdate::run()
353 update_lock->lock("GWindowColorUpdate::run");
355 color_thread->update_gui();
360 int GWindowColorButton::handle_event()
362 GWindowGUI *gui = auto_toggle->gui;
363 gui->start_color_thread(this);
367 void GWindowGUI::create_objects()
370 lock_window("GWindowGUI::create_objects");
372 for( int i=0; i<(int)(sizeof(toggle_order)/sizeof(toggle_order[0])); ++i ) {
373 toggleinfo *tp = &toggle_order[i];
376 BC_Bar *bar = new BC_Bar(x,y,get_w()-x-10);
379 y += bar->get_h() + 5;
382 const char *label = toggle_text(tp);
383 int color = tp->isauto > 0 ? auto_colors[tp->ref] : WHITE;
384 GWindowToggle *toggle = new GWindowToggle(this, x, y, label, color, tp);
385 add_tool(toggles[i] = toggle);
386 if( tp->isauto > 0 ) {
389 case AUTOMATION_MODE: vframe = mwindow->theme->modekeyframe_data; break;
390 case AUTOMATION_PAN: vframe = mwindow->theme->pankeyframe_data; break;
391 case AUTOMATION_MASK: vframe = mwindow->theme->maskkeyframe_data; break;
394 int wh = toggle->get_h() - 4;
395 GWindowColorButton *color_button =
396 new GWindowColorButton(toggle, get_w()-wh-10, y+2, wh);
397 add_tool(color_button);
398 color_button->set_color(color);
399 color_button->draw_face();
402 draw_vframe(vframe, get_w()-vframe->get_w()-10, y);
404 else if( tp->isauto < 0 ) {
405 const char *accel = 0;
407 case NONAUTOTOGGLES_CAMERA_XYZ:
409 accel = _("Shift-F1");
411 case NONAUTOTOGGLES_PROJECTOR_XYZ:
412 projector_xyz = toggle;
413 accel = _("Shift-F2");
417 int x1 = get_w() - BC_Title::calculate_w(this, accel) - 10;
418 add_subwindow(new BC_Title(x1, y, accel));
421 y += toggles[i]->get_h() + 5;
427 void GWindowGUI::update_mwindow(int toggles, int overlays)
430 mwindow->gui->lock_window("GWindowGUI::update_mwindow");
432 mwindow->gui->mainmenu->update_toggles(0);
434 mwindow->gui->draw_overlays(1);
435 mwindow->gui->unlock_window();
436 lock_window("GWindowGUI::update_mwindow");
439 void GWindowGUI::update_toggles(int use_lock)
442 lock_window("GWindowGUI::update_toggles");
446 for( int i=0; i<(int)(sizeof(toggle_order)/sizeof(toggle_order[0])); ++i ) {
447 if( toggles[i] ) toggles[i]->update();
450 camera_xyz->set_value(check_xyz(AUTOMATION_CAMERA_X) > 0 ? 1 : 0);
451 projector_xyz->set_value(check_xyz(AUTOMATION_PROJECTOR_X) > 0 ? 1 : 0);
453 if(use_lock) unlock_window();
456 void GWindowGUI::toggle_camera_xyz()
458 int v = camera_xyz->get_value() ? 0 : 1;
459 camera_xyz->set_value(v);
460 xyz_check(AUTOMATION_CAMERA_X, v);
462 update_mwindow(1, 1);
465 void GWindowGUI::toggle_projector_xyz()
467 int v = projector_xyz->get_value() ? 0 : 1;
468 projector_xyz->set_value(v);
469 xyz_check(AUTOMATION_PROJECTOR_X, v);
471 update_mwindow(1, 1);
474 int GWindowGUI::translation_event()
476 mwindow->session->gwindow_x = get_x();
477 mwindow->session->gwindow_y = get_y();
481 int GWindowGUI::close_event()
483 delete color_thread; color_thread = 0;
485 mwindow->session->show_gwindow = 0;
488 mwindow->gui->lock_window("GWindowGUI::close_event");
489 mwindow->gui->mainmenu->show_gwindow->set_checked(0);
490 mwindow->gui->unlock_window();
492 lock_window("GWindowGUI::close_event");
493 mwindow->save_defaults();
497 int GWindowGUI::keypress_event()
499 if( ctrl_down() && shift_down() ) {
500 switch(get_keypress()) {
505 if( ctrl_down() && shift_down() ) {
506 resend_event(mwindow->gui);
511 else if( !ctrl_down() && shift_down() ) {
512 switch(get_keypress()) {
517 toggle_projector_xyz();
521 switch(get_keypress()) {
534 int GWindowGUI::check_xyz(int group)
536 // returns 1=all set, -1=all clear, 0=mixed
537 int *autos = mwindow->edl->session->auto_conf->autos;
538 int v = autos[group], ret = v ? 1 : -1;
539 if( autos[group+1] != v || autos[group+2] != v ) ret = 0;
542 void GWindowGUI::xyz_check(int group, int v)
544 int *autos = mwindow->edl->session->auto_conf->autos;
550 int* GWindowGUI::get_main_value(toggleinfo *info)
552 if( info->isauto > 0 )
553 return &mwindow->edl->session->auto_conf->autos[info->ref];
554 if( !info->isauto ) {
555 switch( info->ref ) {
556 case NON_AUTOMATION_ASSETS: return &mwindow->edl->session->show_assets;
557 case NON_AUTOMATION_TITLES: return &mwindow->edl->session->show_titles;
558 case NON_AUTOMATION_TRANSITIONS: return &mwindow->edl->session->auto_conf->transitions;
559 case NON_AUTOMATION_PLUGIN_AUTOS: return &mwindow->edl->session->auto_conf->plugins;
566 GWindowToggle::GWindowToggle(GWindowGUI *gui, int x, int y,
567 const char *text, int color, toggleinfo *info)
568 : BC_CheckBox(x, y, 0, text, MEDIUMFONT, color)
573 this->color_button = 0;
577 GWindowToggle::~GWindowToggle()
582 int GWindowToggle::handle_event()
584 int value = get_value();
597 if( info->isauto >= 0 ) {
598 *gui->get_main_value(info) = value;
599 switch( info->ref ) {
600 case AUTOMATION_CAMERA_X:
601 case AUTOMATION_CAMERA_Y:
602 case AUTOMATION_CAMERA_Z: {
603 int v = gui->check_xyz(AUTOMATION_CAMERA_X);
604 gui->camera_xyz->set_value(v > 0 ? 1 : 0);
606 case AUTOMATION_PROJECTOR_X:
607 case AUTOMATION_PROJECTOR_Y:
608 case AUTOMATION_PROJECTOR_Z: {
609 int v = gui->check_xyz(AUTOMATION_PROJECTOR_X);
610 gui->projector_xyz->set_value(v > 0 ? 1 : 0);
616 switch( info->ref ) {
617 case NONAUTOTOGGLES_CAMERA_XYZ: group = AUTOMATION_CAMERA_X; break;
618 case NONAUTOTOGGLES_PROJECTOR_XYZ: group = AUTOMATION_PROJECTOR_X; break;
621 gui->xyz_check(group, value);
622 gui->update_toggles(0);
625 gui->update_mwindow(1, 0);
627 // Update stuff in MWindow
629 MWindow *mwindow = gui->mwindow;
630 mwindow->gui->lock_window("GWindowToggle::handle_event");
632 mwindow->gui->update(1, 1, 0, 0, 1, 0, 0);
633 mwindow->gui->draw_overlays(1);
635 if( value && info->isauto > 0 ) {
636 int autogroup_type = -1;
637 switch( info->ref ) {
638 case AUTOMATION_FADE:
639 autogroup_type = mwindow->edl->tracks->recordable_video_tracks() ?
640 AUTOGROUPTYPE_VIDEO_FADE : AUTOGROUPTYPE_AUDIO_FADE ;
642 case AUTOMATION_SPEED:
643 autogroup_type = AUTOGROUPTYPE_SPEED;
645 case AUTOMATION_CAMERA_X:
646 case AUTOMATION_PROJECTOR_X:
647 autogroup_type = AUTOGROUPTYPE_X;
649 case AUTOMATION_CAMERA_Y:
650 case AUTOMATION_PROJECTOR_Y:
651 autogroup_type = AUTOGROUPTYPE_Y;
653 case AUTOMATION_CAMERA_Z:
654 case AUTOMATION_PROJECTOR_Z:
655 autogroup_type = AUTOGROUPTYPE_ZOOM;
658 if( autogroup_type >= 0 ) {
659 mwindow->edl->local_session->zoombar_showautotype = autogroup_type;
660 mwindow->gui->zoombar->update_autozoom();
664 mwindow->gui->unlock_window();
665 lock_window("GWindowToggle::handle_event");
670 void GWindowToggle::update()
672 int *vp = gui->get_main_value(info);
673 if( vp ) set_value(*vp);
676 void GWindowToggle::update_gui(int color)
678 BC_Toggle::color = color;
682 int GWindowToggle::draw_face(int flash, int flush)
684 int ret = BC_Toggle::draw_face(flash, flush);
688 draw_rectangle(text_x-1, text_y-1, text_w+1, text_h+1);
689 if( flash ) this->flash(0);
690 if( flush ) this->flush();
695 void GWindowGUI::set_cool(int reset, int all)
697 for( int i=0; i<(int)(sizeof(toggles)/sizeof(toggles[0])); ++i ) {
698 GWindowToggle* toggle = toggles[i];
699 if( !toggle ) continue;
700 int *vp = get_main_value(toggle->info);
704 toggle->draw_face(1, 0);
707 *vp = toggle->hot_value;
709 toggle->hot_value = *vp;
711 if ( all || toggle->info->isauto > 0 )
720 void GWindowGUI::set_hot(GWindowToggle *toggle)
722 int *vp = get_main_value(toggle->info);
724 set_cool(-1, !toggle->info->isauto ? 1 : 0);
726 toggle->set_value(*vp = 1);