make kfrm operator= illegal, use copy_from instead
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / gwindowgui.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 "autoconf.h"
23 #include "bchash.h"
24 #include "bcsignals.h"
25 #include "clip.h"
26 #include "condition.h"
27 #include "edl.h"
28 #include "edlsession.h"
29 #include "gwindowgui.h"
30 #include "keys.h"
31 #include "language.h"
32 #include "localsession.h"
33 #include "mainmenu.h"
34 #include "mainsession.h"
35 #include "mwindow.h"
36 #include "mwindowgui.h"
37 #include "theme.h"
38 #include "tracks.h"
39 #include "trackcanvas.h"
40 #include "zoombar.h"
41
42 #include <math.h>
43
44
45
46 GWindowGUI::GWindowGUI(MWindow *mwindow, int w, int h)
47  : BC_Window(_(PROGRAM_NAME ": Overlays"),
48         mwindow->session->gwindow_x, mwindow->session->gwindow_y,
49         w, h, w, h, 0, 0, 1)
50 {
51         this->mwindow = mwindow;
52         color_thread = 0;
53         camera_xyz = 0;
54         projector_xyz = 0;
55 }
56
57 GWindowGUI::~GWindowGUI()
58 {
59         delete color_thread;
60 }
61
62 void GWindowGUI::start_color_thread(GWindowColorButton *color_button)
63 {
64         unlock_window();
65         delete color_thread;
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");
70 }
71
72 const char *GWindowGUI::non_auto_text[NON_AUTOMATION_TOTAL] =
73 {
74         N_("Assets"),
75         N_("Titles"),
76         N_("Transitions"),
77         N_("Plugin Keyframes"),
78 };
79
80 const char *GWindowGUI::auto_text[AUTOMATION_TOTAL] =
81 {
82         N_("Mute"),
83         N_("Camera X"),
84         N_("Camera Y"),
85         N_("Camera Z"),
86         N_("Projector X"),
87         N_("Projector Y"),
88         N_("Projector Z"),
89         N_("Fade"),
90         N_("Pan"),
91         N_("Mode"),
92         N_("Mask"),
93         N_("Speed")
94 };
95
96 int GWindowGUI::auto_colors[AUTOMATION_TOTAL] =
97 {
98         PINK,
99         RED,
100         GREEN,
101         BLUE,
102         LTPINK,
103         LTGREEN,
104         LTBLUE,
105         LTPURPLE,
106         0,
107         0,
108         0,
109         ORANGE,
110 };
111
112 void GWindowGUI::load_defaults()
113 {
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]);
124 }
125
126 void GWindowGUI::save_defaults()
127 {
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]);
138 }
139
140 static toggleinfo toggle_order[] =
141 {
142         {0, NON_AUTOMATION_ASSETS},
143         {0, NON_AUTOMATION_TITLES},
144         {0, NON_AUTOMATION_TRANSITIONS},
145         {0, NON_AUTOMATION_PLUGIN_AUTOS},
146         {0, -1}, // bar
147         {1, AUTOMATION_FADE},
148         {1, AUTOMATION_MUTE},
149         {1, AUTOMATION_SPEED},
150         {1, AUTOMATION_MODE},
151         {1, AUTOMATION_PAN},
152         {1, AUTOMATION_MASK},
153         {0, -1}, // bar
154         {1, AUTOMATION_CAMERA_X},
155         {1, AUTOMATION_CAMERA_Y},
156         {1, AUTOMATION_CAMERA_Z},
157         {-1, NONAUTOTOGGLES_CAMERA_XYZ},
158         {0, -1}, // bar
159         {1, AUTOMATION_PROJECTOR_X},
160         {1, AUTOMATION_PROJECTOR_Y},
161         {1, AUTOMATION_PROJECTOR_Z},
162         {-1, NONAUTOTOGGLES_PROJECTOR_XYZ},
163 };
164
165 const char *GWindowGUI::toggle_text(toggleinfo *tp)
166 {
167         if( tp->isauto > 0 ) return _(auto_text[tp->ref]);
168         if( !tp->isauto ) return _(non_auto_text[tp->ref]);
169         return _("XYZ");
170 }
171
172 void GWindowGUI::calculate_extents(BC_WindowBase *gui, int *w, int *h)
173 {
174         int temp1, temp2, temp3, temp4, temp5, temp6, temp7;
175         int current_w, current_h;
176         *w = 10;
177         *h = 10;
178
179         for( int i=0; i<(int)(sizeof(toggle_order)/sizeof(toggle_order[0])); ++i ) {
180                 toggleinfo *tp = &toggle_order[i];
181                 int ref = tp->ref;
182                 if( ref < 0 ) {
183                         *h += get_resources()->bar_data->get_h() + 5;
184                         continue;
185                 }
186                 BC_Toggle::calculate_extents(gui,
187                         BC_WindowBase::get_resources()->checkbox_images,
188                         0, &temp1, &current_w, &current_h,
189                         &temp2, &temp3, &temp4, &temp5, &temp6, &temp7,
190                         toggle_text(tp), MEDIUMFONT);
191                 current_w += current_h;
192                 *w = MAX(current_w, *w);
193                 *h += current_h + 5;
194         }
195
196         *h += 10;
197         *w += 20;
198 }
199
200 GWindowColorButton::GWindowColorButton(GWindowToggle *auto_toggle, int x, int y, int w)
201  : BC_Button(x, y, w, vframes)
202 {
203         this->auto_toggle = auto_toggle;
204         this->color = 0;
205         for( int i=0; i<3; ++i ) {
206                 vframes[i] = new VFrame(w, w, BC_RGBA8888);
207                 vframes[i]->clear_frame();
208         }
209 }
210
211 GWindowColorButton::~GWindowColorButton()
212 {
213         for( int i=0; i<3; ++i )
214                 delete vframes[i];
215 }
216
217 void GWindowColorButton::set_color(int color)
218 {
219         this->color = 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();
232                 switch( i ) {
233                 case BUTTON_UP:
234                         break;
235                 case BUTTON_UPHI:
236                         if( (rr+=48) > 0xff ) rr = 0xff;
237                         if( (gg+=48) > 0xff ) gg = 0xff;
238                         if( (bb+=48) > 0xff ) bb = 0xff;
239                         break;
240                 case BUTTON_DOWNHI:
241                         if( (rr-=48) < 0x00 ) rr = 0x00;
242                         if( (gg-=48) < 0x00 ) gg = 0x00;
243                         if( (bb-=48) < 0x00 ) bb = 0x00;
244                         break;
245                 }
246                 while( dp < ep ) {
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;
251                         int aa = ss * 0xff;
252                         *dp++ = rr; *dp++ = gg; *dp++ = bb; *dp++ = aa;
253                 }
254         }
255         set_images(vframes);
256 }
257
258 void GWindowColorButton::update_gui(int color)
259 {
260         set_color(color);
261         draw_face();
262 }
263
264 GWindowColorThread::GWindowColorThread(GWindowGUI *gui, GWindowColorButton *color_button)
265  : ColorPicker(0, color_button->auto_toggle->caption)
266 {
267         this->gui = gui;
268         this->color_button = color_button;
269         this->color = 0;
270         color_update = new GWindowColorUpdate(this);
271 }
272
273 GWindowColorThread::~GWindowColorThread()
274 {
275         delete color_update;
276 }
277
278 void GWindowColorThread::start(int color)
279 {
280         start_window(color, 0, 1);
281         color_update->start();
282 }
283
284 void GWindowColorThread::handle_done_event(int result)
285 {
286         color_update->stop();
287         int ref = color_button->auto_toggle->info->ref;
288         gui->lock_window("GWindowColorThread::handle_done_event");
289         if( !result ) {
290                 GWindowGUI::auto_colors[ref] = color;
291                 color_button->auto_toggle->update_gui(color);
292                 gui->save_defaults();
293         }
294         else {
295                 color = GWindowGUI::auto_colors[ref];
296                 color_button->update_gui(color);
297         }
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();
303 }
304
305 int GWindowColorThread::handle_new_color(int color, int alpha)
306 {
307         this->color = color;
308         color_update->update_lock->unlock();
309         return 1;
310 }
311
312 void GWindowColorThread::update_gui()
313 {
314         gui->lock_window("GWindowColorThread::update_gui");
315         color_button->update_gui(color);
316         gui->unlock_window();
317 }
318
319 GWindowColorUpdate::GWindowColorUpdate(GWindowColorThread *color_thread)
320  : Thread(1, 0, 0)
321 {
322         this->color_thread = color_thread;
323         this->update_lock = new Condition(0,"GWindowColorUpdate::update_lock");
324         done = 1;
325 }
326
327 GWindowColorUpdate::~GWindowColorUpdate()
328 {
329         stop();
330         delete update_lock;
331 }
332
333 void GWindowColorUpdate::start()
334 {
335         if( done ) {
336                 done = 0;
337                 Thread::start();
338         }
339 }
340
341 void GWindowColorUpdate::stop()
342 {
343         if( !done ) {
344                 done = 1;
345                 update_lock->unlock();
346                 join();
347         }
348 }
349
350 void GWindowColorUpdate::run()
351 {
352         while( !done ) {
353                 update_lock->lock("GWindowColorUpdate::run");
354                 if( done ) break;
355                 color_thread->update_gui();
356         }
357 }
358
359
360 int GWindowColorButton::handle_event()
361 {
362         GWindowGUI *gui = auto_toggle->gui;
363         gui->start_color_thread(this);
364         return 1;
365 }
366
367 void GWindowGUI::create_objects()
368 {
369         int x = 10, y = 10;
370         lock_window("GWindowGUI::create_objects");
371
372         for( int i=0; i<(int)(sizeof(toggle_order)/sizeof(toggle_order[0])); ++i ) {
373                 toggleinfo *tp = &toggle_order[i];
374                 int ref = tp->ref;
375                 if( ref < 0 ) {
376                         BC_Bar *bar = new BC_Bar(x,y,get_w()-x-10);
377                         add_tool(bar);
378                         toggles[i] = 0;
379                         y += bar->get_h() + 5;
380                         continue;
381                 }
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 ) {
387                         VFrame *vframe = 0;
388                         switch( ref ) {
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;
392                         }
393                         if( !vframe ) {
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();
400                         }
401                         else
402                                 draw_vframe(vframe, get_w()-vframe->get_w()-10, y);
403                 }
404                 else if( tp->isauto < 0 ) {
405                         const char *accel = 0;
406                         switch( ref ) {
407                         case NONAUTOTOGGLES_CAMERA_XYZ:
408                                 camera_xyz = toggle;
409                                 accel = _("Shift-F1");
410                                 break;
411                         case NONAUTOTOGGLES_PROJECTOR_XYZ:
412                                 projector_xyz = toggle;
413                                 accel = _("Shift-F2");
414                                 break;
415                         }
416                          if( accel ) {
417                                 int x1 = get_w() - BC_Title::calculate_w(this, accel) - 10;
418                                 add_subwindow(new BC_Title(x1, y, accel));
419                         }
420                 }
421                 y += toggles[i]->get_h() + 5;
422         }
423         update_toggles(0);
424         unlock_window();
425 }
426
427 void GWindowGUI::update_mwindow(int toggles, int overlays)
428 {
429         unlock_window();
430         mwindow->gui->lock_window("GWindowGUI::update_mwindow");
431         if( toggles )
432                 mwindow->gui->mainmenu->update_toggles(0);
433         if( overlays )
434                 mwindow->gui->draw_overlays(1);
435         mwindow->gui->unlock_window();
436         lock_window("GWindowGUI::update_mwindow");
437 }
438
439 void GWindowGUI::update_toggles(int use_lock)
440 {
441         if(use_lock) {
442                 lock_window("GWindowGUI::update_toggles");
443                 set_cool(0);
444         }
445
446         for( int i=0; i<(int)(sizeof(toggle_order)/sizeof(toggle_order[0])); ++i ) {
447                 if( toggles[i] ) toggles[i]->update();
448         }
449
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);
452
453         if(use_lock) unlock_window();
454 }
455
456 void GWindowGUI::toggle_camera_xyz()
457 {
458         int v = camera_xyz->get_value() ? 0 : 1;
459         camera_xyz->set_value(v);
460         xyz_check(AUTOMATION_CAMERA_X, v);
461         update_toggles(0);
462         update_mwindow(1, 1);
463 }
464
465 void GWindowGUI::toggle_projector_xyz()
466 {
467         int v = projector_xyz->get_value() ? 0 : 1;
468         projector_xyz->set_value(v);
469         xyz_check(AUTOMATION_PROJECTOR_X, v);
470         update_toggles(0);
471         update_mwindow(1, 1);
472 }
473
474 int GWindowGUI::translation_event()
475 {
476         mwindow->session->gwindow_x = get_x();
477         mwindow->session->gwindow_y = get_y();
478         return 0;
479 }
480
481 int GWindowGUI::close_event()
482 {
483         delete color_thread;  color_thread = 0;
484         hide_window();
485         mwindow->session->show_gwindow = 0;
486         unlock_window();
487
488         mwindow->gui->lock_window("GWindowGUI::close_event");
489         mwindow->gui->mainmenu->show_gwindow->set_checked(0);
490         mwindow->gui->unlock_window();
491
492         lock_window("GWindowGUI::close_event");
493         mwindow->save_defaults();
494         return 1;
495 }
496
497 int GWindowGUI::keypress_event()
498 {
499         switch(get_keypress()) {
500         case KEY_F1:
501                 if( shift_down() )
502                         toggle_camera_xyz();
503                 break;
504         case KEY_F2:
505                 if( shift_down() )
506                         toggle_projector_xyz();
507                 break;
508         case 'w':
509         case 'W':
510         case '0':
511                 if( ctrl_down() ) {
512                         close_event();
513                         return 1;
514                 }
515                 break;
516         }
517         return 0;
518 }
519
520 int GWindowGUI::check_xyz(int group)
521 {
522 // returns 1=all set, -1=all clear, 0=mixed
523         int *autos = mwindow->edl->session->auto_conf->autos;
524         int v = autos[group], ret = v ? 1 : -1;
525         if( autos[group+1] != v || autos[group+2] != v ) ret = 0;
526         return ret;
527 }
528 void GWindowGUI::xyz_check(int group, int v)
529 {
530         int *autos = mwindow->edl->session->auto_conf->autos;
531         autos[group+0] = v;
532         autos[group+1] = v;
533         autos[group+2] = v;
534 }
535
536 int* GWindowGUI::get_main_value(toggleinfo *info)
537 {
538         if( info->isauto > 0 )
539                 return &mwindow->edl->session->auto_conf->autos[info->ref];
540         if( !info->isauto ) {
541                 switch( info->ref ) {
542                 case NON_AUTOMATION_ASSETS: return &mwindow->edl->session->show_assets;
543                 case NON_AUTOMATION_TITLES: return &mwindow->edl->session->show_titles;
544                 case NON_AUTOMATION_TRANSITIONS: return &mwindow->edl->session->auto_conf->transitions;
545                 case NON_AUTOMATION_PLUGIN_AUTOS: return &mwindow->edl->session->auto_conf->plugins;
546                 }
547         }
548         return 0;
549 }
550
551
552 GWindowToggle::GWindowToggle(GWindowGUI *gui, int x, int y,
553         const char *text, int color, toggleinfo *info)
554  : BC_CheckBox(x, y, 0, text, MEDIUMFONT, color)
555 {
556         this->gui = gui;
557         this->info = info;
558         this->color = color;
559         this->color_button = 0;
560         hot = hot_value = 0;
561 }
562
563 GWindowToggle::~GWindowToggle()
564 {
565         delete color_button;
566 }
567
568 int GWindowToggle::handle_event()
569 {
570         int value = get_value();
571         if( shift_down() ) {
572                 if( !hot ) {
573                         gui->set_hot(this);
574                         value = 1;
575                 }
576                 else {
577                         gui->set_cool(1);
578                         value = hot_value;
579                 }
580         }
581         else
582                 gui->set_cool(0);
583         if( info->isauto >= 0 ) {
584                 *gui->get_main_value(info) = value;
585                 switch( info->ref ) {
586                 case AUTOMATION_CAMERA_X:
587                 case AUTOMATION_CAMERA_Y:
588                 case AUTOMATION_CAMERA_Z: {
589                         int v = gui->check_xyz(AUTOMATION_CAMERA_X);
590                         gui->camera_xyz->set_value(v > 0 ? 1 : 0);
591                         break; }
592                 case AUTOMATION_PROJECTOR_X:
593                 case AUTOMATION_PROJECTOR_Y:
594                 case AUTOMATION_PROJECTOR_Z: {
595                         int v = gui->check_xyz(AUTOMATION_PROJECTOR_X);
596                         gui->projector_xyz->set_value(v > 0 ? 1 : 0);
597                         break; }
598                 }
599         }
600         else {
601                 int group = -1;
602                 switch( info->ref ) {
603                 case NONAUTOTOGGLES_CAMERA_XYZ:     group = AUTOMATION_CAMERA_X;     break;
604                 case NONAUTOTOGGLES_PROJECTOR_XYZ:  group = AUTOMATION_PROJECTOR_X;  break;
605                 }
606                 if( group >= 0 ) {
607                         gui->xyz_check(group, value);
608                         gui->update_toggles(0);
609                 }
610         }
611         gui->update_mwindow(1, 0);
612
613 // Update stuff in MWindow
614         unlock_window();
615         MWindow *mwindow = gui->mwindow;
616         mwindow->gui->lock_window("GWindowToggle::handle_event");
617
618         mwindow->gui->update(1, 1, 0, 0, 1, 0, 0);
619         mwindow->gui->draw_overlays(1);
620
621         if( value && info->isauto > 0 ) {
622                 int autogroup_type = -1;
623                 switch( info->ref ) {
624                 case AUTOMATION_FADE:
625                         autogroup_type = mwindow->edl->tracks->recordable_video_tracks() ?
626                                 AUTOGROUPTYPE_VIDEO_FADE : AUTOGROUPTYPE_AUDIO_FADE ;
627                         break;
628                 case AUTOMATION_SPEED:
629                         autogroup_type = AUTOGROUPTYPE_SPEED;
630                         break;
631                 case AUTOMATION_CAMERA_X:
632                 case AUTOMATION_PROJECTOR_X:
633                         autogroup_type = AUTOGROUPTYPE_X;
634                         break;
635                 case AUTOMATION_CAMERA_Y:
636                 case AUTOMATION_PROJECTOR_Y:
637                         autogroup_type = AUTOGROUPTYPE_Y;
638                         break;
639                 case AUTOMATION_CAMERA_Z:
640                 case AUTOMATION_PROJECTOR_Z:
641                         autogroup_type = AUTOGROUPTYPE_ZOOM;
642                         break;
643                 }
644                 if( autogroup_type >= 0 ) {
645                         mwindow->edl->local_session->zoombar_showautotype = autogroup_type;
646                         mwindow->gui->zoombar->update_autozoom();
647                 }
648         }
649
650         mwindow->gui->unlock_window();
651         lock_window("GWindowToggle::handle_event");
652
653         return 1;
654 }
655
656 void GWindowToggle::update()
657 {
658         int *vp = gui->get_main_value(info);
659         if( vp ) set_value(*vp);
660 }
661
662 void GWindowToggle::update_gui(int color)
663 {
664         BC_Toggle::color = color;
665         draw_face(1,0);
666 }
667
668 int GWindowToggle::draw_face(int flash, int flush)
669 {
670         int ret = BC_Toggle::draw_face(flash, flush);
671         if( hot ) {
672                 set_color(color);
673                 set_opaque();
674                 draw_rectangle(text_x-1, text_y-1, text_w+1, text_h+1);
675                 if( flash ) this->flash(0);
676                 if( flush ) this->flush();
677         }
678         return ret;
679 }
680
681 void GWindowGUI::set_cool(int reset, int all)
682 {
683         for( int i=0; i<(int)(sizeof(toggles)/sizeof(toggles[0])); ++i ) {
684                 GWindowToggle* toggle = toggles[i];
685                 if( !toggle ) continue;
686                 int *vp = get_main_value(toggle->info);
687                 if( !vp ) continue;
688                 if( toggle->hot ) {
689                         toggle->hot = 0;
690                         toggle->draw_face(1, 0);
691                 }
692                 if( reset > 0 )
693                         *vp = toggle->hot_value;
694                 else {
695                         toggle->hot_value = *vp;
696                         if( reset < 0 ) {
697                                 if ( all || toggle->info->isauto > 0 )
698                                         *vp = 0;
699                         }
700                 }
701         }
702         if( reset )
703                 update_toggles(0);
704 }
705
706 void GWindowGUI::set_hot(GWindowToggle *toggle)
707 {
708         int *vp = get_main_value(toggle->info);
709         if( !vp ) return;
710         set_cool(-1, !toggle->info->isauto ? 1 : 0);
711         toggle->hot = 1;
712         toggle->set_value(*vp = 1);
713 }
714