remove filefork
[goodguy/history.git] / cinelerra-5.0 / cinelerra / mwindowgui.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 1997-2014 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 "androidcontrol.h"
23 #include "awindowgui.h"
24 #include "awindow.h"
25 #include "bcdisplayinfo.h"
26 #include "bchash.h"
27 #include "bcsignals.h"
28 #include "cwindowgui.h"
29 #include "cwindow.h"
30 #include "channelinfo.h"
31 #include "dbwindow.h"
32 #include "edit.h"
33 #include "editpopup.h"
34 #include "edits.h"
35 #include "edl.h"
36 #include "edlsession.h"
37 #include "filesystem.h"
38 #include "keyframepopup.h"
39 #include "keys.h"
40 #include "language.h"
41 #include "localsession.h"
42 #include "mainclock.h"
43 #include "maincursor.h"
44 #include "mainmenu.h"
45 #include "mainsession.h"
46 #include "mainundo.h"
47 #include "mbuttons.h"
48 #include "mtimebar.h"
49 #include "mwindowgui.h"
50 #include "mwindow.h"
51 #include "panedividers.h"
52 #include "patchbay.h"
53 #include "plugin.h"
54 #include "pluginpopup.h"
55 #include "pluginset.h"
56 #include "record.h"
57 #include "recordgui.h"
58 #include "renderengine.h"
59 #include "resourcethread.h"
60 #include "samplescroll.h"
61 #include "shbtnprefs.h"
62 #include "statusbar.h"
63 #include "swindow.h"
64 #include "theme.h"
65 #include "trackcanvas.h"
66 #include "trackscroll.h"
67 #include "tracks.h"
68 #include "transitionpopup.h"
69 #include "vwindowgui.h"
70 #include "vwindow.h"
71 #include "zoombar.h"
72
73 #define PANE_DRAG_MARGIN 50
74
75
76 // the main window uses its own private colormap for video
77 MWindowGUI::MWindowGUI(MWindow *mwindow)
78  : BC_Window(_(PROGRAM_NAME ": Program"), 
79                 mwindow->session->mwindow_x, 
80                 mwindow->session->mwindow_y, 
81                 mwindow->session->mwindow_w, 
82                 mwindow->session->mwindow_h, 
83                 100,
84                 100,
85                 1,
86                 1,
87                 1)
88 {
89         this->mwindow = mwindow;
90 //      samplescroll = 0;
91 //      trackscroll = 0;
92 //      cursor = 0;
93 //      patchbay = 0;
94 //      timebar = 0;
95 //      canvas = 0;
96         focused_pane = TOP_LEFT_PANE;
97         x_divider = 0;
98         y_divider = 0;
99         x_pane_drag = 0;
100         y_pane_drag = 0;
101         dragging_pane = 0;
102         drag_popup = 0;
103
104         render_engine = 0;
105         for(int i = 0; i < TOTAL_PANES; i++)
106                 pane[i] = 0;
107
108         record = 0;
109         channel_info = 0;
110         swindow = 0;
111         db_window = 0;
112 // subwindows
113         mbuttons = 0;
114         statusbar = 0;
115         zoombar = 0;
116         mainclock = 0;
117         edit_menu = 0;
118         plugin_menu = 0;
119         keyframe_menu = 0;
120         transition_menu = 0;
121         remote_control = 0;
122         cwindow_remote_handler = 0;
123         record_remote_handler = 0;
124         android_control = 0;
125 }
126
127
128 MWindowGUI::~MWindowGUI()
129 {
130         delete android_control;
131         delete cwindow_remote_handler;
132         delete record_remote_handler;
133         delete remote_control;
134 //      delete samplescroll;
135 //      delete trackscroll;
136         for(int i = 0; i < TOTAL_PANES; i++)
137                 if(pane[i]) delete pane[i];
138 //      delete cursor;
139         delete render_engine;
140         delete resource_thread;
141         resource_pixmaps.remove_all_objects();
142         delete swindow;
143         delete channel_info;
144         delete db_window;
145         delete x_divider;
146         delete y_divider;
147 }
148
149 #if 0
150 void MWindowGUI::get_scrollbars(int flush)
151 {
152         //int64_t h_needed = mwindow->edl->get_tracks_height(mwindow->theme);
153         //int64_t w_needed = mwindow->edl->get_tracks_width();
154         int need_xscroll = 0;
155         int need_yscroll = 0;
156         view_w = mwindow->theme->mcanvas_w;
157         view_h = mwindow->theme->mcanvas_h;
158
159 // Scrollbars are constitutive
160         need_xscroll = need_yscroll = 1;
161         view_h = mwindow->theme->mcanvas_h;
162         view_w = mwindow->theme->mcanvas_w;
163
164 //      for(int i = 0; i < 2; i++)
165 //      {
166 //              if(w_needed > view_w)
167 //              {
168 //                      need_xscroll = 1;
169 //                      view_h = mwindow->theme->mcanvas_h - SCROLL_SPAN;
170 //              }
171 //              else
172 //                      need_xscroll = 0;
173 // 
174 //              if(h_needed > view_h)
175 //              {
176 //                      need_yscroll = 1;
177 //                      view_w = mwindow->theme->mcanvas_w - SCROLL_SPAN;
178 //              }
179 //              else
180 //                      need_yscroll = 0;
181 //      }
182 //printf("MWindowGUI::get_scrollbars 1\n");
183
184         if(canvas && (view_w != canvas->get_w() || view_h != canvas->get_h()))
185         {
186                 canvas->reposition_window(mwindow->theme->mcanvas_x,
187                         mwindow->theme->mcanvas_y,
188                         view_w,
189                         view_h);
190         }
191
192         if(need_xscroll)
193         {
194                 if(!samplescroll)
195                         add_subwindow(samplescroll = new SampleScroll(mwindow, 
196                                 this, 
197                                 mwindow->theme->mhscroll_x, 
198                                 mwindow->theme->mhscroll_y, 
199                                 mwindow->theme->mhscroll_w));
200                 else
201                         samplescroll->resize_event();
202
203                 samplescroll->set_position(0);
204         }
205         else
206         {
207                 if(samplescroll) delete samplescroll;
208                 samplescroll = 0;
209                 mwindow->edl->local_session->view_start = 0;
210         }
211
212
213         if(need_yscroll)
214         {
215 //printf("MWindowGUI::get_scrollbars 1.1 %p %p\n", this, canvas);
216                 if(!trackscroll)
217                         add_subwindow(trackscroll = new TrackScroll(mwindow, 
218                                 this,
219                                 mwindow->theme->mvscroll_x,
220                                 mwindow->theme->mvscroll_y,
221                                 mwindow->theme->mvscroll_h));
222                 else
223                         trackscroll->resize_event();
224
225
226 //printf("MWindowGUI::get_scrollbars 1.2\n");
227                 trackscroll->update_length(mwindow->edl->get_tracks_height(mwindow->theme),
228                         mwindow->edl->local_session->track_start,
229                         view_h,
230                         0);
231 //printf("MWindowGUI::get_scrollbars 1.3\n");
232         }
233         else
234         {
235                 if(trackscroll) delete trackscroll;
236                 trackscroll = 0;
237                 mwindow->edl->local_session->track_start = 0;
238         }
239
240         if(flush) this->flush();
241
242 }
243 #endif // 0
244
245 void MWindowGUI::create_objects()
246 {
247         const int debug = 0;
248         
249         resource_thread = new ResourceThread(mwindow, this);
250         resource_thread->create_objects();
251
252         
253         if(debug) printf("MWindowGUI::create_objects %d\n", __LINE__);
254         set_icon(mwindow->theme->get_image("mwindow_icon"));
255         remote_control = new RemoteControl(this);
256         cwindow_remote_handler = new CWindowRemoteHandler(remote_control);
257         record_remote_handler = new RecordRemoteHandler(remote_control);
258         mwindow->reset_android_remote();
259         
260         if(debug) printf("MWindowGUI::create_objects %d\n", __LINE__);
261
262         int x = get_w() - MainShBtns::calculate_w(0);
263         add_subwindow(mainmenu = new MainMenu(mwindow, this, x));
264         add_subwindow(mainshbtns = new MainShBtns(mwindow, x, 0));
265         mainshbtns->load(mwindow->preferences);
266         mwindow->theme->get_mwindow_sizes(this, get_w(), get_h());
267         mwindow->theme->draw_mwindow_bg(this);
268         mainmenu->create_objects();
269         if(debug) printf("MWindowGUI::create_objects %d\n", __LINE__);
270
271         add_subwindow(mbuttons = new MButtons(mwindow, this));
272         mbuttons->create_objects();
273
274         pane[TOP_LEFT_PANE] = new TimelinePane(mwindow, 
275                 TOP_LEFT_PANE,
276                 mwindow->theme->mcanvas_x,
277                 mwindow->theme->mcanvas_y,
278                 mwindow->theme->mcanvas_w, 
279                 mwindow->theme->mcanvas_h);
280         pane[TOP_LEFT_PANE]->create_objects();
281
282 //      add_subwindow(timebar = new MTimeBar(mwindow, 
283 //              this,
284 //              mwindow->theme->mtimebar_x,
285 //              mwindow->theme->mtimebar_y,
286 //              mwindow->theme->mtimebar_w,
287 //              mwindow->theme->mtimebar_h));
288 //      timebar->create_objects();
289
290 //      if(debug) printf("MWindowGUI::create_objects %d\n", __LINE__);
291 //      add_subwindow(patchbay = new PatchBay(mwindow, this));
292 //      patchbay->create_objects();
293
294 //      if(debug) printf("MWindowGUI::create_objects %d\n", __LINE__);
295 //      get_scrollbars(0);
296
297 //      if(debug) printf("MWindowGUI::create_objects %d\n", __LINE__);
298 //      mwindow->gui->add_subwindow(canvas = new TrackCanvas(mwindow, this));
299 //      canvas->create_objects();
300
301
302         if(debug) printf("MWindowGUI::create_objects %d\n", __LINE__);
303         add_subwindow(zoombar = new ZoomBar(mwindow, this));
304         zoombar->create_objects();
305
306
307         if(debug) printf("MWindowGUI::create_objects %d\n", __LINE__);
308         add_subwindow(statusbar = new StatusBar(mwindow, this));
309         statusbar->create_objects();
310
311
312
313         if(debug) printf("MWindowGUI::create_objects %d\n", __LINE__);
314         add_subwindow(mainclock = new MainClock(mwindow, 
315                 mwindow->theme->mclock_x,
316                 mwindow->theme->mclock_y,
317                 mwindow->theme->mclock_w));
318         if(debug) printf("MWindowGUI::create_objects %d\n", __LINE__);
319         mainclock->update(0);
320
321
322
323 //      if(debug) printf("MWindowGUI::create_objects %d\n", __LINE__);
324 //      cursor = new MainCursor(mwindow, this);
325 //      cursor->create_objects();
326
327
328         if(debug) printf("MWindowGUI::create_objects %d\n", __LINE__);
329         add_subwindow(edit_menu = new EditPopup(mwindow, this));
330         edit_menu->create_objects();
331
332
333         if(debug) printf("MWindowGUI::create_objects %d\n", __LINE__);
334         add_subwindow(plugin_menu = new PluginPopup(mwindow, this));
335         plugin_menu->create_objects();
336
337
338         if(debug) printf("MWindowGUI::create_objects %d\n", __LINE__);
339         add_subwindow(keyframe_menu = new KeyframePopup(mwindow, this));
340         keyframe_menu->create_objects();
341
342
343         if(debug) printf("MWindowGUI::create_objects %d\n", __LINE__);
344         add_subwindow(transition_menu = new TransitionPopup(mwindow, this));
345         transition_menu->create_objects();
346
347         channel_info = new ChannelInfo(mwindow);
348         db_window = new DbWindow(mwindow);
349         swindow = new SWindow(mwindow);
350
351         if(debug) printf("MWindowGUI::create_objects %d\n", __LINE__);
352
353         add_subwindow(pane_button = new PaneButton(mwindow, 
354                 get_w() - mwindow->theme->get_image_set("pane")[0]->get_w(), 
355                 mwindow->theme->mzoom_y + 1 - mwindow->theme->get_image_set("pane")[0]->get_h()));
356
357         pane[TOP_LEFT_PANE]->canvas->activate();
358
359         if(debug) printf("MWindowGUI::create_objects %d\n", __LINE__);
360 }
361
362 void MWindowGUI::redraw_time_dependancies() 
363 {
364         zoombar->redraw_time_dependancies();
365         for(int i = 0; i < TOTAL_PANES; i++)
366                 if(pane[i] && pane[i]->timebar) pane[i]->timebar->update(0);
367         mainclock->update(mwindow->edl->local_session->get_selectionstart(1));
368 }
369
370 int MWindowGUI::focus_in_event()
371 {
372         for(int i = 0; i < TOTAL_PANES; i++)
373                 if(pane[i]) pane[i]->cursor->focus_in_event();
374         return 1;
375 }
376
377 int MWindowGUI::focus_out_event()
378 {
379         for(int i = 0; i < TOTAL_PANES; i++)
380                 if(pane[i]) pane[i]->cursor->focus_out_event();
381         return 1;
382 }
383
384
385 int MWindowGUI::resize_event(int w, int h)
386 {
387 //printf("MWindowGUI::resize_event %d\n", __LINE__);
388         mwindow->session->mwindow_w = w;
389         mwindow->session->mwindow_h = h;
390         mwindow->theme->get_mwindow_sizes(this, w, h);
391         mwindow->theme->draw_mwindow_bg(this);
392         mbuttons->resize_event();
393         statusbar->resize_event();
394         
395         resource_thread->stop_draw(1);
396         
397         
398         if(total_panes() == 1)
399         {
400                 pane[TOP_LEFT_PANE]->resize_event(
401                         mwindow->theme->mcanvas_x,
402                         mwindow->theme->mcanvas_y,
403                         mwindow->theme->mcanvas_w, 
404                         mwindow->theme->mcanvas_h);
405         }
406         else
407         if(horizontal_panes())
408         {
409                 pane[TOP_LEFT_PANE]->resize_event(
410                         pane[TOP_LEFT_PANE]->x,
411                         pane[TOP_LEFT_PANE]->y,
412                         pane[TOP_LEFT_PANE]->w, 
413                         mwindow->theme->mcanvas_h);
414                 pane[TOP_RIGHT_PANE]->resize_event(
415                         pane[TOP_RIGHT_PANE]->x,
416                         pane[TOP_RIGHT_PANE]->y,
417                         mwindow->theme->mcanvas_w - pane[TOP_RIGHT_PANE]->x, 
418                         mwindow->theme->mcanvas_h);
419         }
420         else
421         if(vertical_panes())
422         {
423                 pane[TOP_LEFT_PANE]->resize_event(
424                         pane[TOP_LEFT_PANE]->x,
425                         pane[TOP_LEFT_PANE]->y,
426                         mwindow->theme->mcanvas_w, 
427                         pane[TOP_LEFT_PANE]->h);
428                 pane[BOTTOM_LEFT_PANE]->resize_event(
429                         pane[BOTTOM_LEFT_PANE]->x,
430                         pane[BOTTOM_LEFT_PANE]->y,
431                         mwindow->theme->mcanvas_w, 
432                         mwindow->theme->mcanvas_y + 
433                                 mwindow->theme->mcanvas_h - 
434                                 pane[BOTTOM_LEFT_PANE]->y);
435         }
436         else
437         {
438                 pane[TOP_LEFT_PANE]->resize_event(
439                         pane[TOP_LEFT_PANE]->x,
440                         pane[TOP_LEFT_PANE]->y,
441                         pane[TOP_LEFT_PANE]->w, 
442                         pane[TOP_LEFT_PANE]->h);
443                 pane[TOP_RIGHT_PANE]->resize_event(
444                         pane[TOP_RIGHT_PANE]->x,
445                         pane[TOP_RIGHT_PANE]->y,
446                         mwindow->theme->mcanvas_w - pane[TOP_RIGHT_PANE]->x, 
447                         pane[TOP_RIGHT_PANE]->h);
448                 pane[BOTTOM_LEFT_PANE]->resize_event(
449                         pane[BOTTOM_LEFT_PANE]->x,
450                         pane[BOTTOM_LEFT_PANE]->y,
451                         pane[BOTTOM_LEFT_PANE]->w, 
452                         mwindow->theme->mcanvas_y + 
453                                 mwindow->theme->mcanvas_h - 
454                                 pane[BOTTOM_LEFT_PANE]->y);
455                 pane[BOTTOM_RIGHT_PANE]->resize_event(
456                         pane[BOTTOM_RIGHT_PANE]->x,
457                         pane[BOTTOM_RIGHT_PANE]->y,
458                         mwindow->theme->mcanvas_w - 
459                                 pane[BOTTOM_RIGHT_PANE]->x, 
460                         mwindow->theme->mcanvas_y + 
461                                 mwindow->theme->mcanvas_h - 
462                                 pane[BOTTOM_RIGHT_PANE]->y);
463         }
464         
465         resource_thread->start_draw();
466         
467         update_pane_dividers();
468         zoombar->resize_event();
469         pane_button->reposition_window(w - mwindow->theme->get_image_set("pane")[0]->get_w(), 
470                 mwindow->theme->mzoom_y + 1 - mwindow->theme->get_image_set("pane")[0]->get_h());
471         int x = get_w() - MainShBtns::calculate_w(0);
472         mainmenu->resize_event(x, mainmenu->get_h());
473         mainshbtns->reposition_window(x, 0);
474 //      get_scrollbars(0);
475 //      canvas->resize_event();
476 //printf("MWindowGUI::resize_event %d\n", __LINE__);
477         flash(0);
478         return 0;
479 }
480
481 int MWindowGUI::total_panes()
482 {
483         int total = 0;
484         for(int i = 0; i < TOTAL_PANES; i++)
485                 if(pane[i]) total++;
486         return total;
487 }
488
489 int MWindowGUI::vertical_panes()
490 {
491         return total_panes() == 2 &&
492                 pane[TOP_LEFT_PANE] &&
493                 pane[BOTTOM_LEFT_PANE];
494 }
495
496 int MWindowGUI::horizontal_panes()
497 {
498         return total_panes() == 2 &&
499                 pane[TOP_LEFT_PANE] &&
500                 pane[TOP_RIGHT_PANE];
501 }
502
503 TimelinePane* MWindowGUI::get_focused_pane()
504 {
505         if(pane[focused_pane]) return pane[focused_pane];
506         for(int i = 0; i < TOTAL_PANES; i++)
507         {
508                 if(pane[i]) return pane[i];
509         }
510         return 0;
511 }
512
513 void MWindowGUI::activate_timeline()
514 {
515         if(pane[focused_pane])
516         {
517                 pane[focused_pane]->activate();
518         }
519         else
520         {
521                 for(int i = 0; i < TOTAL_PANES; i++)
522                 {
523                         if(pane[i]) 
524                         {
525                                 pane[i]->activate();
526                                 return;
527                         }
528                 }
529         }
530 }
531
532 void MWindowGUI::deactivate_timeline()
533 {
534         for(int i = 0; i < TOTAL_PANES; i++)
535         {
536                 if(pane[i])
537                 {
538                         pane[i]->canvas->deactivate();
539                 }
540         }
541 }
542
543 void MWindowGUI::update_title(char *path)
544 {
545         FileSystem fs;
546         char filename[BCTEXTLEN], string[BCTEXTLEN];
547         fs.extract_name(filename, path);
548         sprintf(string, _(PROGRAM_NAME ": %s"), filename);
549         set_title(string);
550 //printf("MWindowGUI::update_title %s\n", string);
551         flush();
552 }
553
554 void MWindowGUI::draw_overlays(int flash_it)
555 {
556         for(int i = 0; i < TOTAL_PANES; i++)
557         {
558                 if(pane[i])
559                 {
560                         pane[i]->canvas->draw_overlays();
561                         if(flash_it) pane[i]->canvas->flash();
562                 }
563         }
564 }
565
566 void MWindowGUI::update_timebar(int flush_it)
567 {
568         for(int i = 0; i < TOTAL_PANES; i++)
569         {
570                 if(pane[i] && pane[i]->timebar)
571                 {
572                         pane[i]->timebar->update(flush_it);
573                 }
574         }
575 }
576
577 void MWindowGUI::update_timebar_highlights()
578 {
579         for(int i = 0; i < TOTAL_PANES; i++)
580         {
581                 if(pane[i] && pane[i]->timebar)
582                 {
583                         pane[i]->timebar->update_highlights();
584                 }
585         }
586 }
587
588
589 void MWindowGUI::update_patchbay()
590 {
591         for(int i = 0; i < TOTAL_PANES; i++)
592         {
593                 if(pane[i] && pane[i]->patchbay)
594                 {
595                         pane[i]->patchbay->update();
596                 }
597         }
598 }
599
600 void MWindowGUI::draw_indexes(Indexable *indexable)
601 {
602         for(int i = 0; i < TOTAL_PANES; i++)
603         {
604                 if(pane[i])
605                 {
606                         pane[i]->canvas->draw_indexes(indexable);
607                 }
608         }
609 }
610
611 void MWindowGUI::draw_canvas(int mode /* = 0 */, int hide_cursor /* = 1 */)
612 {
613         if(mode != IGNORE_THREAD)
614         {
615                 resource_thread->stop_draw(1);
616         }
617
618
619         for(int i = 0; i < TOTAL_PANES; i++)
620         {
621                 if(pane[i])
622                 {
623                         pane[i]->canvas->draw(mode, hide_cursor);
624                 }
625         }
626
627
628         if(mode != IGNORE_THREAD)
629         {
630                 resource_thread->start_draw();
631         }
632
633 }
634
635 void MWindowGUI::flash_canvas(int flush)
636 {
637         for(int i = 0; i < TOTAL_PANES; i++)
638         {
639                 if(pane[i])
640                 {
641                         pane[i]->canvas->flash(flush);
642                 }
643         }
644 }
645
646 void MWindowGUI::draw_cursor(int do_plugintoggles)
647 {
648         for(int i = 0; i < TOTAL_PANES; i++)
649         {
650                 if(pane[i])
651                 {
652                         pane[i]->cursor->draw(do_plugintoggles);
653                 }
654         }
655 }
656
657 void MWindowGUI::show_cursor(int do_plugintoggles)
658 {
659         for(int i = 0; i < TOTAL_PANES; i++)
660         {
661                 if(pane[i])
662                 {
663                         pane[i]->cursor->show(do_plugintoggles);
664                 }
665         }
666 }
667
668 void MWindowGUI::hide_cursor(int do_plugintoggles)
669 {
670         for(int i = 0; i < TOTAL_PANES; i++)
671         {
672                 if(pane[i])
673                 {
674                         pane[i]->cursor->hide(do_plugintoggles);
675                 }
676         }
677 }
678
679 void MWindowGUI::update_cursor()
680 {
681         for(int i = 0; i < TOTAL_PANES; i++)
682         {
683                 if(pane[i])
684                 {
685                         pane[i]->cursor->update();
686                 }
687         }
688 }
689
690 void MWindowGUI::set_playing_back(int value)
691 {
692         for(int i = 0; i < TOTAL_PANES; i++)
693         {
694                 if(pane[i])
695                 {
696                         pane[i]->cursor->playing_back = value;
697                 }
698         }
699 }
700
701 void MWindowGUI::update_plugintoggles()
702 {
703         for(int i = 0; i < TOTAL_PANES; i++)
704         {
705                 if(pane[i])
706                 {
707                         pane[i]->canvas->refresh_plugintoggles();
708                 }
709         }
710
711 }
712
713 void MWindowGUI::update_scrollbars(int flush)
714 {
715         for(int i = 0; i < TOTAL_PANES; i++)
716         {
717                 if(pane[i])
718                 {
719                         pane[i]->update(1, 0, 0, 0);
720                 }
721         }
722         if(flush) this->flush();
723 }
724
725 void MWindowGUI::reset_meters()
726 {
727         for(int i = 0; i < TOTAL_PANES; i++)
728         {
729                 if(pane[i] && pane[i]->patchbay)
730                 {
731                         pane[i]->patchbay->reset_meters();
732                 }
733         }
734 }
735
736 void MWindowGUI::stop_meters()
737 {
738         for(int i = 0; i < TOTAL_PANES; i++)
739         {
740                 if(pane[i] && pane[i]->patchbay)
741                 {
742                         pane[i]->patchbay->stop_meters();
743                 }
744         }
745 }
746
747 void MWindowGUI::update_meters(ArrayList<double> *module_levels)
748 {
749         for(int i = 0; i < TOTAL_PANES; i++)
750         {
751                 if(pane[i] && pane[i]->patchbay)
752                 {
753                         pane[i]->patchbay->update_meters(module_levels);
754                 }
755         }
756 }
757
758 void MWindowGUI::set_editing_mode(int flush)
759 {
760         for(int i = 0; i < TOTAL_PANES; i++)
761         {
762                 if(pane[i])
763                 {
764                         pane[i]->canvas->update_cursor(flush);
765                 }
766         }
767 }
768
769 void MWindowGUI::set_meter_format(int mode, int min, int max)
770 {
771         for(int i = 0; i < TOTAL_PANES; i++)
772         {
773                 if(pane[i] && pane[i]->patchbay)
774                 {
775                         pane[i]->patchbay->set_meter_format(mode, min, max);
776                 }
777         }
778 }
779
780 void MWindowGUI::update(int scrollbars,
781         int do_canvas,
782         int timebar,
783         int zoombar,
784         int patchbay, 
785         int clock,
786         int buttonbar)
787 {
788         const int debug = 0;
789         if(debug) PRINT_TRACE
790         
791         
792         
793         mwindow->edl->tracks->update_y_pixels(mwindow->theme);
794         
795         if(do_canvas && do_canvas != IGNORE_THREAD)
796         {
797                 resource_thread->stop_draw(1);
798         }
799         
800         for(int i = 0; i < TOTAL_PANES; i++)
801         {
802                 if(pane[i]) pane[i]->update(scrollbars,
803                         do_canvas,
804                         timebar,
805                         patchbay);
806         }
807         
808         if(do_canvas && do_canvas != IGNORE_THREAD)
809         {
810                 resource_thread->start_draw();
811         }
812         
813 //      if(scrollbars) this->get_scrollbars(0);
814 //      if(timebar) this->timebar->update(0);
815         if(zoombar) this->zoombar->update();
816 //      if(patchbay) this->patchbay->update();
817         if(clock) this->mainclock->update(
818                 mwindow->edl->local_session->get_selectionstart(1));
819         if(debug) PRINT_TRACE
820
821
822
823 //      if(do_canvas)
824 //      {
825 //              this->canvas->draw(do_canvas);
826 //              this->cursor->show();
827 //              this->canvas->flash(0);
828 // Activate causes the menubar to deactivate.  Don't want this for
829 // picon thread.
830 //              if(canvas != IGNORE_THREAD) this->canvas->activate();
831 //      }
832         if(debug) PRINT_TRACE
833
834
835
836         if(buttonbar) mbuttons->update();
837         if(debug) PRINT_TRACE
838
839 // Can't age if the cache called this to draw missing picons
840 // or the GUI is updating the status of the draw toggle.
841         if(do_canvas != FORCE_REDRAW && do_canvas != IGNORE_THREAD)
842         {
843                 unlock_window();
844                 mwindow->age_caches();
845                 lock_window("MWindowGUI::update");
846         }
847         
848         flush();
849         if(debug) PRINT_TRACE
850 }
851
852 int MWindowGUI::visible(int64_t x1, int64_t x2, int64_t view_x1, int64_t view_x2)
853 {
854         return (x1 >= view_x1 && x1 < view_x2) ||
855                 (x2 > view_x1 && x2 <= view_x2) ||
856                 (x1 <= view_x1 && x2 >= view_x2);
857 }
858
859
860 int MWindowGUI::show_message(char *message, int color)
861 {
862 // printf("MWindowGUI::show_message %d: %s 0x%08x 0x%08x\n", 
863 // __LINE__, message, color, mwindow->theme->message_normal);
864         if(color < 0) color = mwindow->theme->message_normal;
865         statusbar->status_text->set_color(color);
866         statusbar->status_text->update(message);
867         return 0;
868 }
869
870
871 // Drag motion called from other window
872 int MWindowGUI::drag_motion()
873 {
874         if(get_hidden()) return 0;
875
876         Track *over_track = 0;
877         Edit *over_edit = 0;
878         PluginSet *over_pluginset = 0;
879         Plugin *over_plugin = 0;
880         int redraw = 0;
881
882         if(drag_popup)
883         {
884                 drag_popup->cursor_motion_event();
885         }
886
887
888 // there's no point in drawing highlights has until drag operation has been set
889         if (!mwindow->session->current_operation)
890                 return 0;
891
892         if(mwindow->session->free_drag) redraw = 1;
893
894         if(ctrl_down()) 
895         {
896                 redraw = 1;
897                 mwindow->session->free_drag = 1;
898         }
899         else
900         {
901                 mwindow->session->free_drag = 0;
902         }
903
904
905         for(int i = 0; i < TOTAL_PANES; i++)
906         {
907                 if(pane[i]) pane[i]->canvas->drag_motion(
908                         &over_track,
909                         &over_edit,
910                         &over_pluginset,
911                         &over_plugin);
912         }
913         
914
915
916         if(mwindow->session->track_highlighted != over_track) 
917         {
918                 mwindow->session->track_highlighted = over_track;
919                 redraw = 1;
920         }
921
922         if(mwindow->session->edit_highlighted != over_edit)
923         {
924                 mwindow->session->edit_highlighted = over_edit;
925                 redraw = 1;
926         }
927
928         if(mwindow->session->pluginset_highlighted != over_pluginset)
929         {
930                 mwindow->session->pluginset_highlighted = over_pluginset;
931                 redraw = 1;
932         }
933
934         if(mwindow->session->plugin_highlighted != over_plugin)
935         {
936                 mwindow->session->plugin_highlighted = over_plugin;
937                 redraw = 1;
938         }
939
940 // printf("drag_motion %d %d over_track=%p over_edit=%p\n", 
941 // __LINE__,
942 // redraw,
943 // over_track,
944 // over_edit);
945         if(redraw)
946         {
947                 lock_window("MWindowGUI::drag_motion");
948                 draw_overlays(1);
949                 unlock_window();
950         }
951         return 0;
952 }
953
954 int MWindowGUI::drag_stop()
955 {
956         if(get_hidden()) return 0;
957         int result = 0, redraw = 0;
958
959         for(int i = 0; i < TOTAL_PANES; i++)
960         {
961                 if(pane[i]) result |= pane[i]->canvas->drag_stop(
962                         &redraw);
963         }
964
965
966 // since we don't have subwindows we have to terminate any drag operation
967         if(result)
968         {
969                 if (mwindow->session->track_highlighted
970                         || mwindow->session->edit_highlighted
971                         || mwindow->session->plugin_highlighted
972                         || mwindow->session->pluginset_highlighted) 
973                         redraw = 1;
974                 mwindow->session->track_highlighted = 0;
975                 mwindow->session->edit_highlighted = 0;
976                 mwindow->session->plugin_highlighted = 0;
977                 mwindow->session->pluginset_highlighted = 0;
978                 mwindow->session->current_operation = NO_OPERATION;
979         }
980
981
982 //printf("TrackCanvas::drag_stop %d %d\n", redraw, mwindow->session->current_operation);
983         if(redraw)
984         {
985                 mwindow->edl->tracks->update_y_pixels(mwindow->theme);
986                 update_scrollbars(0);
987                 update_patchbay();
988                 draw_canvas(1, 1);
989                 update_cursor();
990                 flash_canvas(1);
991         }
992
993         if(drag_popup)
994         {
995                 delete drag_popup;
996                 drag_popup = 0;
997         }
998         return result;
999 }
1000
1001 void MWindowGUI::default_positions()
1002 {
1003 //printf("MWindowGUI::default_positions 1\n");
1004         VWindow *vwindow = mwindow->vwindows.size() > DEFAULT_VWINDOW ?
1005                 mwindow->vwindows.get(0) : 0;
1006         if( vwindow ) vwindow->gui->lock_window("MWindowGUI::default_positions");
1007         mwindow->cwindow->gui->lock_window("MWindowGUI::default_positions");
1008         mwindow->awindow->gui->lock_window("MWindowGUI::default_positions");
1009
1010 // printf("MWindowGUI::default_positions 1 %d %d %d %d\n", mwindow->session->vwindow_x, 
1011 // mwindow->session->vwindow_y,
1012 // mwindow->session->vwindow_w, 
1013 // mwindow->session->vwindow_h);
1014         reposition_window(mwindow->session->mwindow_x, 
1015                 mwindow->session->mwindow_y,
1016                 mwindow->session->mwindow_w, 
1017                 mwindow->session->mwindow_h);
1018         if( vwindow ) vwindow->gui->reposition_window(mwindow->session->vwindow_x, 
1019                 mwindow->session->vwindow_y,
1020                 mwindow->session->vwindow_w, 
1021                 mwindow->session->vwindow_h);
1022         mwindow->cwindow->gui->reposition_window(mwindow->session->cwindow_x, 
1023                 mwindow->session->cwindow_y,
1024                 mwindow->session->cwindow_w, 
1025                 mwindow->session->cwindow_h);
1026         mwindow->awindow->gui->reposition_window(mwindow->session->awindow_x, 
1027                 mwindow->session->awindow_y,
1028                 mwindow->session->awindow_w, 
1029                 mwindow->session->awindow_h);
1030 //printf("MWindowGUI::default_positions 1\n");
1031
1032         resize_event(mwindow->session->mwindow_w, 
1033                 mwindow->session->mwindow_h);
1034 //printf("MWindowGUI::default_positions 1\n");
1035         if( vwindow ) vwindow->gui->resize_event(mwindow->session->vwindow_w, 
1036                 mwindow->session->vwindow_h);
1037 //printf("MWindowGUI::default_positions 1\n");
1038         mwindow->cwindow->gui->resize_event(mwindow->session->cwindow_w, 
1039                 mwindow->session->cwindow_h);
1040 //printf("MWindowGUI::default_positions 1\n");
1041         mwindow->awindow->gui->resize_event(mwindow->session->awindow_w, 
1042                 mwindow->session->awindow_h);
1043
1044 //printf("MWindowGUI::default_positions 1\n");
1045
1046         flush();
1047         if( vwindow ) vwindow->gui->flush();
1048         mwindow->cwindow->gui->flush();
1049         mwindow->awindow->gui->flush();
1050
1051         if( vwindow ) vwindow->gui->unlock_window();
1052         mwindow->cwindow->gui->unlock_window();
1053         mwindow->awindow->gui->unlock_window();
1054 //printf("MWindowGUI::default_positions 2\n");
1055 }
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073 int MWindowGUI::repeat_event(int64_t duration)
1074 {
1075 // if(duration == 100)
1076 // mwindow->sync_parameters(CHANGE_ALL);
1077         int result = 0;
1078         for(int i = 0; i < TOTAL_PANES; i++)
1079         {
1080                 if(pane[i]) result = pane[i]->cursor->repeat_event(duration);
1081         }
1082         return result;
1083 }
1084
1085
1086 int MWindowGUI::translation_event()
1087 {
1088 //printf("MWindowGUI::translation_event 1 %d %d\n", get_x(), get_y());
1089         mwindow->session->mwindow_x = get_x();
1090         mwindow->session->mwindow_y = get_y();
1091         return 0;
1092 }
1093
1094
1095 int MWindowGUI::save_defaults(BC_Hash *defaults)
1096 {
1097         defaults->update("MWINDOWWIDTH", get_w());
1098         defaults->update("MWINDOWHEIGHT", get_h());
1099         mainmenu->save_defaults(defaults);
1100         BC_WindowBase::save_defaults(defaults);
1101         return 0;
1102 }
1103
1104 int MWindowGUI::keypress_event()
1105 {
1106 //printf("MWindowGUI::keypress_event 1 %d\n", get_keypress());
1107         int result = 0;
1108         result = mbuttons->keypress_event();
1109
1110         if(!result)
1111         {
1112                 switch(get_keypress())
1113                 {
1114                         case '1': case '2': case '3': case '4':
1115                         case '5': case '6': case '7': case '8':
1116                         if( !alt_down() || shift_down() ) break;
1117                         if( !mwindow->select_asset(get_keypress()-'1',1) )
1118                                 result = 1;
1119                         break;
1120                         case LEFT:
1121                                 if(!ctrl_down()) 
1122                                 { 
1123                                         if (alt_down())
1124                                         {
1125                                                 unlock_window();
1126                                                 mbuttons->transport->handle_transport(STOP, 1, 0, 0);
1127                                                 lock_window("MWindowGUI::keypress_event 1");
1128                                                 mwindow->prev_edit_handle(shift_down());
1129                                         }
1130                                         else
1131                                                 mwindow->move_left(); 
1132                                         result = 1; 
1133                                 }
1134                                 break;
1135                         case RIGHT:
1136                                 if(!ctrl_down()) 
1137                                 { 
1138                                         if (alt_down())
1139                                         {
1140                                                 unlock_window();
1141                                                 mbuttons->transport->handle_transport(STOP, 1, 0, 0);
1142                                                 lock_window("MWindowGUI::keypress_event 2");
1143                                                 mwindow->next_edit_handle(shift_down());
1144                                         }
1145                                         else
1146                                                 mwindow->move_right(); 
1147                                         result = 1; 
1148                                 }
1149                                 break;
1150
1151                         case UP:
1152                                 if(ctrl_down())
1153                                 {
1154                                         mwindow->expand_y();
1155                                         result = 1;
1156                                 }
1157                                 else
1158                                 if(alt_down())
1159                                 {
1160                                         mwindow->expand_autos();
1161                                         result = 1;
1162                                 }
1163                                 else
1164                                 {
1165                                         mwindow->expand_sample();
1166                                         result = 1;
1167                                 }
1168                                 break;
1169
1170                         case DOWN:
1171                                 if(ctrl_down())
1172                                 {
1173                                         mwindow->zoom_in_y();
1174                                         result = 1;
1175                                 }
1176                                 else
1177                                 if(alt_down())
1178                                 {
1179                                         mwindow->shrink_autos();
1180                                         result = 1;
1181                                 }
1182                                 else
1183                                 {
1184                                         mwindow->zoom_in_sample();
1185                                         result = 1;
1186                                 }
1187                                 break;
1188
1189                         case PGUP:
1190                                 if(!ctrl_down())
1191                                 {
1192                                         mwindow->move_up();
1193                                         result = 1;
1194                                 }
1195                                 else
1196                                 {
1197                                         mwindow->expand_t();
1198                                         result = 1;
1199                                 }
1200                                 break;
1201
1202                         case PGDN:
1203                                 if(!ctrl_down())
1204                                 {
1205                                         mwindow->move_down();
1206                                         result = 1;
1207                                 }
1208                                 else
1209                                 {
1210                                         mwindow->zoom_in_t();
1211                                         result = 1;
1212                                 }
1213                                 break;
1214
1215 //                      case TAB:
1216 //                      case LEFTTAB:
1217 //                              //int cursor_x = 0;
1218 //                              int cursor_y = 0;
1219 //                              for(int i = 0; i < TOTAL_PANES; i++)
1220 //                              {
1221 //                                      if(pane[i])
1222 //                                      {
1223 //                                              //cursor_x = pane[i]->canvas->get_relative_cursor_x();
1224 //                                              cursor_y = pane[i]->canvas->get_relative_cursor_y();
1225 //                                      }
1226 //                              }
1227 //                              
1228 // 
1229 //                              if(get_keypress() == TAB)
1230 //                              {
1231 // // Switch the record button
1232 //                                      for(Track *track = mwindow->edl->tracks->first; track; track = track->next)
1233 //                                      {
1234 //                                              int64_t track_x, track_y, track_w, track_h;
1235 //                                              canvas->track_dimensions(track, track_x, track_y, track_w, track_h);
1236 // 
1237 //                                              if(cursor_y >= track_y && 
1238 //                                                      cursor_y < track_y + track_h)
1239 //                                              {
1240 //                                                      if (track->record)
1241 //                                                              track->record = 0;
1242 //                                                      else
1243 //                                                              track->record = 1;
1244 //                                                      result = 1; 
1245 //                                                      break;
1246 //                                              }
1247 //                                      }
1248 //                              } 
1249 //                              else 
1250 //                              {
1251 //                                      Track *this_track = 0;
1252 //                                      for(Track *track = mwindow->edl->tracks->first; track; track = track->next)
1253 //                                      {
1254 //                                              int64_t track_x, track_y, track_w, track_h;
1255 //                                              canvas->track_dimensions(track, track_x, track_y, track_w, track_h);
1256 // 
1257 //                                              if(cursor_y >= track_y && 
1258 //                                                      cursor_y < track_y + track_h)
1259 //                                              {
1260 //                                                      // This is our track
1261 //                                                      this_track = track;
1262 //                                                      break;
1263 //                                              }
1264 //                                      }
1265 // 
1266 //                                      int total_selected = mwindow->edl->tracks->total_of(Tracks::RECORD);
1267 // 
1268 //      // nothing previously selected
1269 //                                      if(total_selected == 0)
1270 //                                      {
1271 //                                              mwindow->edl->tracks->select_all(Tracks::RECORD,
1272 //                                                      1);
1273 //                                      }
1274 //                                      else
1275 //                                      if(total_selected == 1)
1276 //                                      {
1277 //      // this patch was previously the only one on
1278 //                                              if(this_track && this_track->record)
1279 //                                              {
1280 //                                                      mwindow->edl->tracks->select_all(Tracks::RECORD,
1281 //                                                              1);
1282 //                                              }
1283 //      // another patch was previously the only one on
1284 //                                              else
1285 //                                              {
1286 //                                                      mwindow->edl->tracks->select_all(Tracks::RECORD,
1287 //                                                              0);
1288 //                                                      if (this_track) 
1289 //                                                              this_track->record = 1;
1290 // 
1291 //                                              }
1292 //                                      }
1293 //                                      else
1294 //                                      if(total_selected > 1)
1295 //                                      {
1296 //                                              mwindow->edl->tracks->select_all(Tracks::RECORD,
1297 //                                                      0);
1298 //                                              if (this_track) 
1299 //                                                      this_track->record = 1;
1300 //                                      }
1301 // 
1302 //                              }
1303 // 
1304 //                              update (0,
1305 //                                              1,
1306 //                                              0,
1307 //                                              0,
1308 //                                              1,
1309 //                                              0,
1310 //                                              1);
1311 //                              unlock_window();
1312 //                              mwindow->cwindow->update(0, 1, 1);
1313 //                              lock_window("TrackCanvas::keypress_event 3");
1314 // 
1315 //                              result = 1;
1316 //                              break;
1317                 }
1318
1319 // since things under cursor have changed...
1320                 if(result) 
1321                         cursor_motion_event(); 
1322         }
1323
1324         return result;
1325 }
1326
1327
1328 int MWindowGUI::keyboard_listener(BC_WindowBase *wp)
1329 {
1330         return keyboard_listener(wp->get_keypress());
1331 }
1332
1333 int MWindowGUI::keyboard_listener(int key)
1334 {
1335         int result = 1;
1336         switch( key ) {
1337         case KPTV:
1338                 if( !record->running() )
1339                         record->start();
1340                 else
1341                         record->record_gui->interrupt_thread->start(0);
1342                 break;
1343         case KPHAND:
1344                 mwindow->quit(0);
1345                 break;
1346         case KPBOOK:
1347                 channel_info->toggle_scan();
1348                 break;
1349         case KPMENU:
1350                 if( !remote_control->deactivate() )
1351                         remote_control->activate();
1352                 break;
1353         default:
1354                 result = 0;
1355                 break;
1356         }
1357         return result;
1358 }
1359
1360
1361 void MWindowGUI::use_android_remote(int on)
1362 {
1363         if( !on ) {
1364                 delete android_control;
1365                 android_control = 0;
1366                 return;
1367         }
1368         if( android_control ) return;
1369         android_control = new AndroidControl(this);
1370 }
1371
1372 int MWindowGUI::close_event() 
1373
1374         mainmenu->quit(); 
1375         return 0;
1376 }
1377
1378 void MWindowGUI::stop_drawing()
1379 {
1380         resource_thread->stop_draw(1);
1381 }
1382
1383 int MWindowGUI::menu_h()
1384 {
1385         return mainmenu->get_h();
1386 }
1387
1388 void MWindowGUI::start_x_pane_drag()
1389 {
1390         if(!x_pane_drag)
1391         {
1392                 x_pane_drag = new BC_Popup(this, 
1393                         get_abs_cursor_x(0) - mwindow->theme->pane_w,
1394                         get_resources()->get_top_border() + 
1395                                 get_y() + 
1396                                 mwindow->theme->mcanvas_y,
1397                         mwindow->theme->pane_w,
1398                         mwindow->theme->mcanvas_h,
1399                         mwindow->theme->drag_pane_color);
1400                 x_pane_drag->draw_3segmentv(0, 
1401                         0, 
1402                         x_pane_drag->get_h(),
1403                         mwindow->theme->get_image_set("xpane")[BUTTON_DOWNHI]);
1404                 x_pane_drag->flash(1);
1405         }
1406         dragging_pane = 1;
1407 }
1408
1409 void MWindowGUI::start_y_pane_drag()
1410 {
1411         if(!y_pane_drag)
1412         {
1413 //printf("MWindowGUI::start_y_pane_drag %d %d %d\n", __LINE__, get_x(), get_y());
1414                 y_pane_drag = new BC_Popup(this, 
1415                         get_resources()->get_left_border() + 
1416                                 get_x() + 
1417                                 mwindow->theme->mcanvas_x,
1418                         get_abs_cursor_y(0) - mwindow->theme->pane_h,
1419                         mwindow->theme->mcanvas_w,
1420                         mwindow->theme->pane_h,
1421                         mwindow->theme->drag_pane_color);
1422                 y_pane_drag->draw_3segmenth(0, 
1423                         0, 
1424                         y_pane_drag->get_w(),
1425                         mwindow->theme->get_image_set("ypane")[BUTTON_DOWNHI]);
1426                 y_pane_drag->flash(1);
1427         }
1428         dragging_pane = 1;
1429 }
1430
1431 void MWindowGUI::handle_pane_drag()
1432 {
1433         if(dragging_pane)
1434         {
1435                 if(x_pane_drag)
1436                 {
1437                         x_pane_drag->reposition_window(
1438                                 get_abs_cursor_x(0) - mwindow->theme->pane_w,
1439                                 x_pane_drag->get_y());
1440                 }
1441                 
1442                 if(y_pane_drag)
1443                 {
1444                         y_pane_drag->reposition_window(
1445                                 y_pane_drag->get_x(),
1446                                 get_abs_cursor_y(0) - mwindow->theme->pane_h);
1447                 }
1448         }
1449 }
1450
1451
1452 void MWindowGUI::create_x_pane(int cursor_x)
1453 {
1454         if(total_panes() == 1)
1455         {
1456 // create a horizontal pane
1457 // do this 1st so the resize_event knows there are 2 panes
1458                 mwindow->edl->local_session->view_start[TOP_RIGHT_PANE] = 
1459                         mwindow->edl->local_session->view_start[TOP_LEFT_PANE] +
1460                         cursor_x - 
1461                         mwindow->theme->patchbay_w;
1462                 pane[TOP_RIGHT_PANE] = new TimelinePane(mwindow, 
1463                         TOP_RIGHT_PANE,
1464                         mwindow->theme->mcanvas_x + 
1465                                 cursor_x,
1466                         mwindow->theme->mcanvas_y,
1467                         mwindow->theme->mcanvas_x + 
1468                                 mwindow->theme->mcanvas_w - 
1469                                 cursor_x, 
1470                         mwindow->theme->mcanvas_h);
1471                 pane[TOP_LEFT_PANE]->resize_event(
1472                         mwindow->theme->mcanvas_x,
1473                         mwindow->theme->mcanvas_y,
1474                         cursor_x - mwindow->theme->pane_w,
1475                         mwindow->theme->mcanvas_h);
1476                 pane[TOP_RIGHT_PANE]->create_objects();
1477         }
1478         else
1479         if(vertical_panes())
1480         {
1481 // create 2 horizontal panes
1482                 mwindow->edl->local_session->track_start[TOP_RIGHT_PANE] = 
1483                         mwindow->edl->local_session->track_start[TOP_LEFT_PANE];
1484                 mwindow->edl->local_session->track_start[BOTTOM_RIGHT_PANE] = 
1485                         mwindow->edl->local_session->track_start[BOTTOM_LEFT_PANE];
1486                 mwindow->edl->local_session->view_start[TOP_RIGHT_PANE] = 
1487                         mwindow->edl->local_session->view_start[BOTTOM_RIGHT_PANE] = 
1488                         mwindow->edl->local_session->view_start[TOP_LEFT_PANE] +
1489                         cursor_x - 
1490                         mwindow->theme->patchbay_w;
1491                 pane[TOP_RIGHT_PANE] = new TimelinePane(mwindow, 
1492                         TOP_RIGHT_PANE,
1493                         mwindow->theme->mcanvas_x + 
1494                                 cursor_x,
1495                         pane[TOP_LEFT_PANE]->y,
1496                         mwindow->theme->mcanvas_x + 
1497                                 mwindow->theme->mcanvas_w - 
1498                                 cursor_x, 
1499                         pane[TOP_LEFT_PANE]->h);
1500                 pane[BOTTOM_RIGHT_PANE] = new TimelinePane(mwindow, 
1501                         BOTTOM_RIGHT_PANE,
1502                         mwindow->theme->mcanvas_x + 
1503                                 cursor_x,
1504                         pane[BOTTOM_LEFT_PANE]->y,
1505                         mwindow->theme->mcanvas_x + 
1506                                 mwindow->theme->mcanvas_w - 
1507                                 cursor_x, 
1508                         pane[BOTTOM_LEFT_PANE]->h);
1509                 pane[TOP_LEFT_PANE]->resize_event(
1510                         pane[TOP_LEFT_PANE]->x,
1511                         pane[TOP_LEFT_PANE]->y,
1512                         cursor_x - mwindow->theme->pane_w,
1513                         pane[TOP_LEFT_PANE]->h);
1514                 pane[BOTTOM_LEFT_PANE]->resize_event(
1515                         pane[BOTTOM_LEFT_PANE]->x,
1516                         pane[BOTTOM_LEFT_PANE]->y,
1517                         cursor_x - mwindow->theme->pane_w,
1518                         pane[BOTTOM_LEFT_PANE]->h);
1519                 pane[TOP_RIGHT_PANE]->create_objects();
1520                 pane[BOTTOM_RIGHT_PANE]->create_objects();
1521         }
1522         else
1523         if(horizontal_panes())
1524         {
1525 // resize a horizontal pane
1526                 mwindow->edl->local_session->view_start[TOP_RIGHT_PANE] += 
1527                         cursor_x -
1528                         pane[TOP_RIGHT_PANE]->x;
1529                 if(mwindow->edl->local_session->view_start[TOP_RIGHT_PANE] < 0)
1530                         mwindow->edl->local_session->view_start[TOP_RIGHT_PANE] = 0;
1531                 pane[TOP_LEFT_PANE]->resize_event(
1532                         mwindow->theme->mcanvas_x,
1533                         mwindow->theme->mcanvas_y,
1534                         cursor_x - mwindow->theme->pane_w,
1535                         mwindow->theme->mcanvas_h);
1536                 pane[TOP_RIGHT_PANE]->resize_event(
1537                         mwindow->theme->mcanvas_x + 
1538                                 cursor_x,
1539                         pane[TOP_RIGHT_PANE]->y,
1540                         mwindow->theme->mcanvas_x + 
1541                                 mwindow->theme->mcanvas_w - 
1542                                 cursor_x, 
1543                         mwindow->theme->mcanvas_h);
1544         }
1545         else
1546         {
1547 // resize 2 horizontal panes
1548                 mwindow->edl->local_session->view_start[TOP_RIGHT_PANE] += 
1549                         cursor_x -
1550                         pane[TOP_RIGHT_PANE]->x;
1551                 if(mwindow->edl->local_session->view_start[TOP_RIGHT_PANE] < 0)
1552                         mwindow->edl->local_session->view_start[TOP_RIGHT_PANE] = 0;
1553                 mwindow->edl->local_session->view_start[BOTTOM_RIGHT_PANE] =
1554                         mwindow->edl->local_session->view_start[TOP_RIGHT_PANE];
1555
1556                 pane[TOP_LEFT_PANE]->resize_event(
1557                         mwindow->theme->mcanvas_x,
1558                         pane[TOP_LEFT_PANE]->y,
1559                         cursor_x - mwindow->theme->pane_w,
1560                         pane[TOP_LEFT_PANE]->h);
1561                 pane[TOP_RIGHT_PANE]->resize_event(
1562                         mwindow->theme->mcanvas_x + 
1563                                 cursor_x,
1564                         pane[TOP_RIGHT_PANE]->y,
1565                         mwindow->theme->mcanvas_x + 
1566                                 mwindow->theme->mcanvas_w - 
1567                                 cursor_x, 
1568                         pane[TOP_RIGHT_PANE]->h);
1569                 pane[BOTTOM_LEFT_PANE]->resize_event(
1570                         mwindow->theme->mcanvas_x,
1571                         pane[BOTTOM_LEFT_PANE]->y,
1572                         cursor_x - mwindow->theme->pane_w,
1573                         pane[BOTTOM_LEFT_PANE]->h);
1574                 pane[BOTTOM_RIGHT_PANE]->resize_event(
1575                         mwindow->theme->mcanvas_x + 
1576                                 cursor_x,
1577                         pane[BOTTOM_RIGHT_PANE]->y,
1578                         mwindow->theme->mcanvas_x + 
1579                                 mwindow->theme->mcanvas_w - 
1580                                 cursor_x, 
1581                         pane[BOTTOM_RIGHT_PANE]->h);
1582
1583         }
1584 }
1585
1586
1587 void MWindowGUI::delete_x_pane(int cursor_x)
1588 {
1589 // give left panes coordinates of right pane
1590         if(cursor_x < mwindow->theme->patchbay_w + PANE_DRAG_MARGIN &&
1591                 pane[TOP_RIGHT_PANE])
1592         {
1593                 mwindow->edl->local_session->view_start[TOP_LEFT_PANE] = 
1594                         mwindow->edl->local_session->view_start[TOP_RIGHT_PANE] - 
1595                         pane[TOP_RIGHT_PANE]->x + mwindow->theme->patchbay_w;
1596                 if(mwindow->edl->local_session->view_start[TOP_LEFT_PANE] < 0)
1597                         mwindow->edl->local_session->view_start[TOP_LEFT_PANE] = 0;
1598                 mwindow->edl->local_session->view_start[BOTTOM_LEFT_PANE] = 
1599                         mwindow->edl->local_session->view_start[TOP_LEFT_PANE];
1600         }
1601
1602         switch(total_panes())
1603         {
1604                 case 2:
1605                         if(pane[TOP_LEFT_PANE] && pane[TOP_RIGHT_PANE])
1606                         {
1607 // delete right pane
1608                                 delete pane[TOP_RIGHT_PANE];
1609                                 pane[TOP_RIGHT_PANE] = 0;
1610                                 pane[TOP_LEFT_PANE]->resize_event(
1611                                         mwindow->theme->mcanvas_x,
1612                                         mwindow->theme->mcanvas_y,
1613                                         mwindow->theme->mcanvas_w,
1614                                         mwindow->theme->mcanvas_h);
1615
1616                         }
1617                         break;
1618
1619                 case 4:
1620 // delete right panes
1621                         delete pane[TOP_RIGHT_PANE];
1622                         pane[TOP_RIGHT_PANE] = 0;
1623                         delete pane[BOTTOM_RIGHT_PANE];
1624                         pane[BOTTOM_RIGHT_PANE] = 0;
1625                         pane[TOP_LEFT_PANE]->resize_event(
1626                                 mwindow->theme->mcanvas_x,
1627                                 pane[TOP_LEFT_PANE]->y,
1628                                 mwindow->theme->mcanvas_w,
1629                                 pane[TOP_LEFT_PANE]->h);
1630                         pane[BOTTOM_LEFT_PANE]->resize_event(
1631                                 mwindow->theme->mcanvas_x,
1632                                 pane[BOTTOM_LEFT_PANE]->y,
1633                                 mwindow->theme->mcanvas_w,
1634                                 pane[BOTTOM_LEFT_PANE]->h);
1635                         break;
1636         }
1637 }
1638
1639 void MWindowGUI::create_y_pane(int cursor_y)
1640 {
1641         if(total_panes() == 1)
1642         {
1643                 mwindow->edl->local_session->view_start[BOTTOM_LEFT_PANE] = 
1644                         mwindow->edl->local_session->view_start[TOP_LEFT_PANE];
1645                 mwindow->edl->local_session->track_start[BOTTOM_LEFT_PANE] = 
1646                         mwindow->edl->local_session->track_start[TOP_LEFT_PANE] +
1647                         cursor_y -
1648                         mwindow->theme->mtimebar_h;
1649 // do this 1st so the resize_event knows there are 2 panes
1650                 pane[BOTTOM_LEFT_PANE] = new TimelinePane(mwindow, 
1651                         BOTTOM_LEFT_PANE,
1652                         mwindow->theme->mcanvas_x,
1653                         mwindow->theme->mcanvas_y +
1654                                 cursor_y,
1655                         mwindow->theme->mcanvas_w, 
1656                         mwindow->theme->mcanvas_h - 
1657                                 cursor_y);
1658                 pane[TOP_LEFT_PANE]->resize_event(
1659                         mwindow->theme->mcanvas_x,
1660                         mwindow->theme->mcanvas_y,
1661                         mwindow->theme->mcanvas_w,
1662                         pane[BOTTOM_LEFT_PANE]->y -
1663                                 mwindow->theme->mcanvas_y -
1664                                 mwindow->theme->pane_h);
1665                 pane[BOTTOM_LEFT_PANE]->create_objects();
1666         }
1667         else
1668         if(horizontal_panes())
1669         {
1670 // create 2 panes
1671                 mwindow->edl->local_session->view_start[BOTTOM_LEFT_PANE] = 
1672                         mwindow->edl->local_session->view_start[TOP_LEFT_PANE];
1673                 mwindow->edl->local_session->view_start[BOTTOM_RIGHT_PANE] = 
1674                         mwindow->edl->local_session->view_start[TOP_RIGHT_PANE];
1675                 mwindow->edl->local_session->track_start[BOTTOM_LEFT_PANE] = 
1676                 mwindow->edl->local_session->track_start[BOTTOM_RIGHT_PANE] = 
1677                         mwindow->edl->local_session->track_start[TOP_LEFT_PANE] +
1678                         cursor_y -
1679                         mwindow->theme->mtimebar_h;
1680
1681                 pane[BOTTOM_LEFT_PANE] = new TimelinePane(mwindow, 
1682                         BOTTOM_LEFT_PANE,
1683                         pane[TOP_LEFT_PANE]->x,
1684                         mwindow->theme->mcanvas_y +
1685                                 cursor_y,
1686                         pane[TOP_LEFT_PANE]->w, 
1687                         mwindow->theme->mcanvas_h - 
1688                                 cursor_y);
1689                 pane[BOTTOM_RIGHT_PANE] = new TimelinePane(mwindow, 
1690                         BOTTOM_RIGHT_PANE,
1691                         pane[TOP_RIGHT_PANE]->x,
1692                         mwindow->theme->mcanvas_y +
1693                                 cursor_y,
1694                         pane[TOP_RIGHT_PANE]->w, 
1695                         mwindow->theme->mcanvas_h - 
1696                                 cursor_y);
1697
1698                 pane[TOP_LEFT_PANE]->resize_event(
1699                         pane[TOP_LEFT_PANE]->x,
1700                         pane[TOP_LEFT_PANE]->y,
1701                         pane[TOP_LEFT_PANE]->w,
1702                         pane[BOTTOM_LEFT_PANE]->y -
1703                                 mwindow->theme->mcanvas_y -
1704                                 mwindow->theme->pane_h);
1705                 pane[TOP_RIGHT_PANE]->resize_event(
1706                         pane[TOP_RIGHT_PANE]->x,
1707                         pane[TOP_RIGHT_PANE]->y,
1708                         pane[TOP_RIGHT_PANE]->w,
1709                         pane[BOTTOM_RIGHT_PANE]->y -
1710                                 mwindow->theme->mcanvas_y -
1711                                 mwindow->theme->pane_h);
1712
1713                 pane[BOTTOM_LEFT_PANE]->create_objects();
1714                 pane[BOTTOM_RIGHT_PANE]->create_objects();
1715         }
1716         else
1717         if(vertical_panes())
1718         {
1719 // resize a pane
1720                 mwindow->edl->local_session->track_start[BOTTOM_LEFT_PANE] +=
1721                         cursor_y -
1722                         (pane[BOTTOM_LEFT_PANE]->y - mwindow->theme->mcanvas_y);
1723                 if(mwindow->edl->local_session->track_start[BOTTOM_LEFT_PANE] < 0)
1724                         mwindow->edl->local_session->track_start[BOTTOM_LEFT_PANE] = 0;
1725                 pane[TOP_LEFT_PANE]->resize_event(
1726                         mwindow->theme->mcanvas_x,
1727                         mwindow->theme->mcanvas_y,
1728                         mwindow->theme->mcanvas_w,
1729                         cursor_y - mwindow->theme->pane_h);
1730                 pane[BOTTOM_LEFT_PANE]->resize_event(
1731                         pane[BOTTOM_LEFT_PANE]->x,
1732                         cursor_y + 
1733                                 mwindow->theme->mcanvas_y,
1734                         mwindow->theme->mcanvas_w,
1735                         mwindow->theme->mcanvas_h - 
1736                                 cursor_y);
1737         }
1738         else
1739         {
1740 // resize 2 panes
1741                 mwindow->edl->local_session->track_start[BOTTOM_LEFT_PANE] +=
1742                         cursor_y -
1743                         (pane[BOTTOM_LEFT_PANE]->y - mwindow->theme->mcanvas_y);
1744                 if(mwindow->edl->local_session->track_start[BOTTOM_LEFT_PANE] < 0)
1745                         mwindow->edl->local_session->track_start[BOTTOM_LEFT_PANE] = 0;
1746                 mwindow->edl->local_session->track_start[BOTTOM_RIGHT_PANE] = 
1747                         mwindow->edl->local_session->track_start[BOTTOM_LEFT_PANE];
1748                 pane[TOP_LEFT_PANE]->resize_event(
1749                         pane[TOP_LEFT_PANE]->x,
1750                         pane[TOP_LEFT_PANE]->y,
1751                         pane[TOP_LEFT_PANE]->w,
1752                         cursor_y - mwindow->theme->pane_h);
1753                 pane[BOTTOM_LEFT_PANE]->resize_event(
1754                         pane[BOTTOM_LEFT_PANE]->x,
1755                         cursor_y + 
1756                                 mwindow->theme->mcanvas_y,
1757                         pane[BOTTOM_LEFT_PANE]->w,
1758                         mwindow->theme->mcanvas_h - 
1759                                         cursor_y);
1760                 pane[TOP_RIGHT_PANE]->resize_event(
1761                         pane[TOP_RIGHT_PANE]->x,
1762                         pane[TOP_RIGHT_PANE]->y,
1763                         pane[TOP_RIGHT_PANE]->w,
1764                         cursor_y - mwindow->theme->pane_h);
1765                 pane[BOTTOM_RIGHT_PANE]->resize_event(
1766                         pane[BOTTOM_RIGHT_PANE]->x,
1767                         cursor_y + 
1768                                 mwindow->theme->mcanvas_y,
1769                         pane[BOTTOM_RIGHT_PANE]->w,
1770                         mwindow->theme->mcanvas_h - 
1771                                         cursor_y);
1772         }
1773 }
1774
1775 void MWindowGUI::delete_y_pane(int cursor_y)
1776 {
1777         if(cursor_y < mwindow->theme->mtimebar_h +
1778                 PANE_DRAG_MARGIN &&
1779                 pane[BOTTOM_LEFT_PANE])
1780         {
1781 // give top pane coordinates of bottom pane
1782                 mwindow->edl->local_session->track_start[TOP_LEFT_PANE] = 
1783                         mwindow->edl->local_session->track_start[BOTTOM_LEFT_PANE] -
1784                         pane[BOTTOM_LEFT_PANE]->y;
1785                 if(mwindow->edl->local_session->track_start[TOP_LEFT_PANE] < 0)
1786                         mwindow->edl->local_session->track_start[TOP_LEFT_PANE] = 0;
1787                 mwindow->edl->local_session->track_start[TOP_RIGHT_PANE] = 
1788                         mwindow->edl->local_session->track_start[TOP_LEFT_PANE];
1789         }
1790
1791 // delete a pane
1792         switch(total_panes())
1793         {
1794                 case 2:
1795                         delete pane[BOTTOM_LEFT_PANE];
1796                         pane[BOTTOM_LEFT_PANE] = 0;
1797                         pane[TOP_LEFT_PANE]->resize_event(
1798                                 mwindow->theme->mcanvas_x,
1799                                 mwindow->theme->mcanvas_y,
1800                                 mwindow->theme->mcanvas_w,
1801                                 mwindow->theme->mcanvas_h);
1802                         break;
1803
1804                 case 4:
1805 // delete bottom 2 panes
1806
1807                         delete pane[BOTTOM_LEFT_PANE];
1808                         pane[BOTTOM_LEFT_PANE] = 0;
1809                         delete pane[BOTTOM_RIGHT_PANE];
1810                         pane[BOTTOM_RIGHT_PANE] = 0;
1811                         pane[TOP_LEFT_PANE]->resize_event(
1812                                 pane[TOP_LEFT_PANE]->x,
1813                                 mwindow->theme->mcanvas_y,
1814                                 pane[TOP_LEFT_PANE]->w,
1815                                 mwindow->theme->mcanvas_h);
1816                         pane[TOP_RIGHT_PANE]->resize_event(
1817                                 pane[TOP_RIGHT_PANE]->x,
1818                                 mwindow->theme->mcanvas_y,
1819                                 pane[TOP_RIGHT_PANE]->w,
1820                                 mwindow->theme->mcanvas_h);
1821                         break;
1822         }
1823 }
1824
1825 void MWindowGUI::stop_pane_drag()
1826 {
1827         dragging_pane = 0;
1828         resource_thread->stop_draw(1);
1829         
1830         if(x_pane_drag)
1831         {
1832 // cursor position relative to canvas
1833                 int cursor_x = x_pane_drag->get_x() - 
1834                         get_x() - 
1835                         get_resources()->get_left_border() -
1836                         mwindow->theme->mcanvas_x +
1837                         mwindow->theme->pane_w;
1838                 delete x_pane_drag;
1839                 x_pane_drag = 0;
1840
1841
1842                 if(cursor_x >= mwindow->theme->patchbay_w + PANE_DRAG_MARGIN && 
1843                         cursor_x < mwindow->theme->mcanvas_w - 
1844                                 BC_ScrollBar::get_span(SCROLL_VERT) - 
1845                                 PANE_DRAG_MARGIN)
1846                 {
1847                         create_x_pane(cursor_x);
1848                         mwindow->edl->local_session->x_pane = cursor_x;
1849                 }
1850                 else
1851 // deleted a pane
1852                 {
1853                         delete_x_pane(cursor_x);
1854                         mwindow->edl->local_session->x_pane = -1;
1855                 }
1856                 
1857                 
1858         }
1859         
1860         if(y_pane_drag)
1861         {
1862 // cursor position relative to canvas
1863                 int cursor_y = y_pane_drag->get_y() - 
1864                         get_y() - 
1865                         get_resources()->get_top_border() -
1866                         mwindow->theme->mcanvas_y +
1867                         mwindow->theme->pane_h;
1868                 delete y_pane_drag;
1869                 y_pane_drag = 0;
1870                 
1871                 
1872
1873                 if(cursor_y >= mwindow->theme->mtimebar_h +
1874                                 PANE_DRAG_MARGIN &&
1875                         cursor_y < mwindow->theme->mcanvas_h -
1876                                 BC_ScrollBar::get_span(SCROLL_HORIZ) - 
1877                                 PANE_DRAG_MARGIN)
1878                 {
1879                         create_y_pane(cursor_y);
1880                         mwindow->edl->local_session->y_pane = cursor_y;
1881                 }
1882                 else
1883                 {
1884                         delete_y_pane(cursor_y);
1885                         mwindow->edl->local_session->y_pane = -1;
1886                 }
1887         }
1888         
1889         update_pane_dividers();
1890         update_cursor();
1891 // required to get new widgets to appear
1892         show_window();
1893         resource_thread->start_draw();
1894 }
1895
1896 // create panes from EDL
1897 void MWindowGUI::load_panes()
1898 {
1899         int need_x_panes = 0;
1900         int need_y_panes = 0;
1901 // use names from create functions
1902         int cursor_x = mwindow->edl->local_session->x_pane;
1903         int cursor_y = mwindow->edl->local_session->y_pane;
1904         
1905         resource_thread->stop_draw(1);
1906         if(cursor_x >= 
1907                 mwindow->theme->patchbay_w + PANE_DRAG_MARGIN &&
1908                 cursor_x < 
1909                 mwindow->theme->mcanvas_w - 
1910                                 BC_ScrollBar::get_span(SCROLL_VERT) - 
1911                                 PANE_DRAG_MARGIN)
1912         {
1913                 need_x_panes = 1;
1914         }
1915
1916         if(cursor_y >= 
1917                 mwindow->theme->mtimebar_h + PANE_DRAG_MARGIN &&
1918                 cursor_y < 
1919                 mwindow->theme->mcanvas_h -
1920                                 BC_ScrollBar::get_span(SCROLL_HORIZ) - 
1921                                 PANE_DRAG_MARGIN)
1922         {
1923                 need_y_panes = 1;
1924         }
1925
1926 //printf("MWindowGUI::load_panes %d %d %d\n", __LINE__, need_x_panes, need_y_panes);
1927
1928
1929         if(need_x_panes)
1930         {
1931                 if(need_y_panes)
1932                 {
1933 // 4 panes
1934                         if(total_panes() == 1)
1935                         {
1936 // create 4 panes
1937 //printf("MWindowGUI::load_panes %d\n", __LINE__);
1938                                 pane[TOP_RIGHT_PANE] = new TimelinePane(mwindow, 
1939                                         TOP_RIGHT_PANE,
1940                                         mwindow->theme->mcanvas_x + 
1941                                                 cursor_x,
1942                                         mwindow->theme->mcanvas_y,
1943                                         mwindow->theme->mcanvas_x + 
1944                                                 mwindow->theme->mcanvas_w - 
1945                                                 cursor_x, 
1946                                         cursor_y - mwindow->theme->pane_h);
1947                                 pane[BOTTOM_LEFT_PANE] = new TimelinePane(mwindow, 
1948                                         BOTTOM_LEFT_PANE,
1949                                         mwindow->theme->mcanvas_x,
1950                                         mwindow->theme->mcanvas_y +
1951                                                 cursor_y,
1952                                         cursor_x - mwindow->theme->pane_w, 
1953                                         mwindow->theme->mcanvas_h - 
1954                                                 cursor_y);
1955                                 pane[BOTTOM_RIGHT_PANE] = new TimelinePane(mwindow, 
1956                                         BOTTOM_RIGHT_PANE,
1957                                         pane[TOP_RIGHT_PANE]->x,
1958                                         mwindow->theme->mcanvas_y +
1959                                                 cursor_y,
1960                                         pane[TOP_RIGHT_PANE]->w, 
1961                                         mwindow->theme->mcanvas_h - 
1962                                                 cursor_y);
1963                                 pane[TOP_LEFT_PANE]->resize_event(
1964                                         pane[TOP_LEFT_PANE]->x,
1965                                         pane[TOP_LEFT_PANE]->y,
1966                                         cursor_x - mwindow->theme->pane_w,
1967                                         cursor_y - mwindow->theme->pane_h);
1968                                 pane[TOP_RIGHT_PANE]->create_objects();
1969                                 pane[BOTTOM_LEFT_PANE]->create_objects();
1970                                 pane[BOTTOM_RIGHT_PANE]->create_objects();
1971                         }
1972                         else
1973                         if(horizontal_panes())
1974                         {
1975 // create vertical panes
1976 //printf("MWindowGUI::load_panes %d\n", __LINE__);
1977                                 pane[BOTTOM_LEFT_PANE] = new TimelinePane(mwindow, 
1978                                         BOTTOM_LEFT_PANE,
1979                                         mwindow->theme->mcanvas_x,
1980                                         mwindow->theme->mcanvas_y +
1981                                                 cursor_y,
1982                                         cursor_x - mwindow->theme->pane_w, 
1983                                         mwindow->theme->mcanvas_h - 
1984                                                 cursor_y);
1985                                 pane[BOTTOM_RIGHT_PANE] = new TimelinePane(mwindow, 
1986                                         BOTTOM_RIGHT_PANE,
1987                                         pane[TOP_RIGHT_PANE]->x,
1988                                         mwindow->theme->mcanvas_y +
1989                                                 cursor_y,
1990                                         pane[TOP_RIGHT_PANE]->w, 
1991                                         mwindow->theme->mcanvas_h - 
1992                                                 cursor_y);
1993                                 pane[TOP_LEFT_PANE]->resize_event(
1994                                         pane[TOP_LEFT_PANE]->x,
1995                                         pane[TOP_LEFT_PANE]->y,
1996                                         cursor_x - mwindow->theme->pane_w,
1997                                         cursor_y - mwindow->theme->pane_h);
1998                                 pane[TOP_RIGHT_PANE]->resize_event(
1999                                         mwindow->theme->mcanvas_x + 
2000                                                 cursor_x,
2001                                         mwindow->theme->mcanvas_y,
2002                                         mwindow->theme->mcanvas_x + 
2003                                                 mwindow->theme->mcanvas_w - 
2004                                                 cursor_x, 
2005                                         cursor_y - mwindow->theme->pane_h);
2006                                 pane[BOTTOM_LEFT_PANE]->create_objects();
2007                                 pane[BOTTOM_RIGHT_PANE]->create_objects();
2008                         }
2009                         else
2010                         if(vertical_panes())
2011                         {
2012 // create horizontal panes
2013 //printf("MWindowGUI::load_panes %d\n", __LINE__);
2014                                 pane[TOP_RIGHT_PANE] = new TimelinePane(mwindow, 
2015                                         TOP_RIGHT_PANE,
2016                                         mwindow->theme->mcanvas_x + 
2017                                                 cursor_x,
2018                                         mwindow->theme->mcanvas_y,
2019                                         mwindow->theme->mcanvas_x + 
2020                                                 mwindow->theme->mcanvas_w - 
2021                                                 cursor_x, 
2022                                         cursor_y - mwindow->theme->pane_h);
2023                                 pane[BOTTOM_RIGHT_PANE] = new TimelinePane(mwindow, 
2024                                         BOTTOM_RIGHT_PANE,
2025                                         pane[TOP_RIGHT_PANE]->x,
2026                                         mwindow->theme->mcanvas_y +
2027                                                 cursor_y,
2028                                         pane[TOP_RIGHT_PANE]->w, 
2029                                         mwindow->theme->mcanvas_h - 
2030                                                 cursor_y);
2031                                 pane[TOP_LEFT_PANE]->resize_event(
2032                                         pane[TOP_LEFT_PANE]->x,
2033                                         pane[TOP_LEFT_PANE]->y,
2034                                         cursor_x - mwindow->theme->pane_w,
2035                                         cursor_y - mwindow->theme->pane_h);
2036                                 pane[BOTTOM_LEFT_PANE]->resize_event(
2037                                         pane[TOP_LEFT_PANE]->x,
2038                                         mwindow->theme->mcanvas_y +
2039                                                 cursor_y,
2040                                         mwindow->theme->mcanvas_x + 
2041                                                 mwindow->theme->mcanvas_w - 
2042                                                 cursor_x,
2043                                         mwindow->theme->mcanvas_h - 
2044                                                 cursor_y);
2045                                 pane[TOP_RIGHT_PANE]->create_objects();
2046                                 pane[BOTTOM_RIGHT_PANE]->create_objects();
2047                                 
2048
2049                         }
2050                         else
2051                         {
2052 // resize all panes
2053 //printf("MWindowGUI::load_panes %d\n", __LINE__);
2054                                 pane[TOP_LEFT_PANE]->resize_event(
2055                                         pane[TOP_LEFT_PANE]->x,
2056                                         pane[TOP_LEFT_PANE]->y,
2057                                         cursor_x - mwindow->theme->pane_w,
2058                                         cursor_y - mwindow->theme->pane_h);
2059                                 pane[TOP_RIGHT_PANE]->resize_event(
2060                                         mwindow->theme->mcanvas_x + 
2061                                                 cursor_x,
2062                                         mwindow->theme->mcanvas_y,
2063                                         mwindow->theme->mcanvas_x + 
2064                                                 mwindow->theme->mcanvas_w - 
2065                                                 cursor_x, 
2066                                         cursor_y - mwindow->theme->pane_h);
2067                                 pane[BOTTOM_LEFT_PANE]->resize_event(
2068                                         pane[TOP_LEFT_PANE]->x,
2069                                         mwindow->theme->mcanvas_y +
2070                                                 cursor_y,
2071                                         mwindow->theme->mcanvas_x + 
2072                                                 mwindow->theme->mcanvas_w - 
2073                                                 cursor_x,
2074                                         mwindow->theme->mcanvas_h - 
2075                                                 cursor_y);
2076                                 pane[BOTTOM_RIGHT_PANE]->resize_event(
2077                                         pane[TOP_RIGHT_PANE]->x,
2078                                         mwindow->theme->mcanvas_y +
2079                                                 cursor_y,
2080                                         pane[TOP_RIGHT_PANE]->w, 
2081                                         mwindow->theme->mcanvas_h - 
2082                                                 cursor_y);
2083                                 
2084                                 
2085                         }
2086                 }
2087                 else
2088                 {
2089 // 2 X panes
2090                         if(pane[BOTTOM_LEFT_PANE]) delete pane[BOTTOM_LEFT_PANE];
2091                         if(pane[BOTTOM_RIGHT_PANE]) delete pane[BOTTOM_RIGHT_PANE];
2092                         pane[BOTTOM_LEFT_PANE] = 0;
2093                         pane[BOTTOM_RIGHT_PANE] = 0;
2094                         
2095                         if(!pane[TOP_RIGHT_PANE])
2096                         {
2097                                 pane[TOP_RIGHT_PANE] = new TimelinePane(mwindow, 
2098                                         TOP_RIGHT_PANE,
2099                                         mwindow->theme->mcanvas_x + 
2100                                                 cursor_x,
2101                                         mwindow->theme->mcanvas_y,
2102                                         mwindow->theme->mcanvas_x + 
2103                                                 mwindow->theme->mcanvas_w - 
2104                                                 cursor_x, 
2105                                         mwindow->theme->mcanvas_h);
2106                                 pane[TOP_LEFT_PANE]->resize_event(
2107                                         mwindow->theme->mcanvas_x,
2108                                         mwindow->theme->mcanvas_y,
2109                                         cursor_x - mwindow->theme->pane_w,
2110                                         mwindow->theme->mcanvas_h);
2111                                 pane[TOP_RIGHT_PANE]->create_objects();
2112                         }
2113                         else
2114                         {
2115                                 pane[TOP_LEFT_PANE]->resize_event(
2116                                         mwindow->theme->mcanvas_x,
2117                                         mwindow->theme->mcanvas_y,
2118                                         cursor_x - mwindow->theme->pane_w,
2119                                         mwindow->theme->mcanvas_h);
2120                                 pane[TOP_RIGHT_PANE]->resize_event(
2121                                         mwindow->theme->mcanvas_x + 
2122                                                 cursor_x,
2123                                         pane[TOP_RIGHT_PANE]->y,
2124                                         mwindow->theme->mcanvas_x + 
2125                                                 mwindow->theme->mcanvas_w - 
2126                                                 cursor_x, 
2127                                         mwindow->theme->mcanvas_h);
2128                         }
2129                 }
2130         }
2131         else
2132         if(need_y_panes)
2133         {
2134 // 2 Y panes
2135                 if(pane[TOP_RIGHT_PANE]) delete pane[TOP_RIGHT_PANE];
2136                 if(pane[BOTTOM_RIGHT_PANE]) delete pane[BOTTOM_RIGHT_PANE];
2137                 pane[TOP_RIGHT_PANE] = 0;
2138                 pane[BOTTOM_RIGHT_PANE] = 0;
2139                 
2140                 if(!pane[BOTTOM_LEFT_PANE])
2141                 {
2142 //printf("MWindowGUI::load_panes %d\n", __LINE__);
2143                         pane[BOTTOM_LEFT_PANE] = new TimelinePane(mwindow, 
2144                                 BOTTOM_LEFT_PANE,
2145                                 mwindow->theme->mcanvas_x,
2146                                 mwindow->theme->mcanvas_y +
2147                                         cursor_y,
2148                                 mwindow->theme->mcanvas_w, 
2149                                 mwindow->theme->mcanvas_h - 
2150                                         cursor_y);
2151                         pane[TOP_LEFT_PANE]->resize_event(
2152                                 mwindow->theme->mcanvas_x,
2153                                 mwindow->theme->mcanvas_y,
2154                                 mwindow->theme->mcanvas_w,
2155                                 pane[BOTTOM_LEFT_PANE]->y -
2156                                         mwindow->theme->mcanvas_y -
2157                                         mwindow->theme->pane_h);
2158                         pane[BOTTOM_LEFT_PANE]->create_objects();
2159                 }
2160                 else
2161                 {
2162                         pane[TOP_LEFT_PANE]->resize_event(
2163                                 mwindow->theme->mcanvas_x,
2164                                 mwindow->theme->mcanvas_y,
2165                                 mwindow->theme->mcanvas_w,
2166                                 cursor_y - mwindow->theme->pane_h);
2167                         pane[BOTTOM_LEFT_PANE]->resize_event(
2168                                 pane[BOTTOM_LEFT_PANE]->x,
2169                                 cursor_y + 
2170                                         mwindow->theme->mcanvas_y,
2171                                 mwindow->theme->mcanvas_w,
2172                                 mwindow->theme->mcanvas_h - 
2173                                         cursor_y);
2174                 }
2175         }
2176         else
2177         {
2178 // 1 pane
2179                 if(pane[TOP_RIGHT_PANE]) delete pane[TOP_RIGHT_PANE];
2180                 if(pane[BOTTOM_RIGHT_PANE]) delete pane[BOTTOM_RIGHT_PANE];
2181                 if(pane[BOTTOM_LEFT_PANE]) delete pane[BOTTOM_LEFT_PANE];
2182                 pane[TOP_RIGHT_PANE] = 0;
2183                 pane[BOTTOM_RIGHT_PANE] = 0;
2184                 pane[BOTTOM_LEFT_PANE] = 0;
2185                 pane[TOP_LEFT_PANE]->resize_event(
2186                         mwindow->theme->mcanvas_x,
2187                         mwindow->theme->mcanvas_y,
2188                         mwindow->theme->mcanvas_w,
2189                         mwindow->theme->mcanvas_h);
2190         }
2191         
2192         update_pane_dividers();
2193         show_window();
2194         
2195         resource_thread->start_draw();
2196 }
2197
2198 void MWindowGUI::update_pane_dividers()
2199 {
2200
2201         if(horizontal_panes() || total_panes() == 4)
2202         {
2203                 int x = pane[TOP_RIGHT_PANE]->x - mwindow->theme->pane_w;
2204                 int y = mwindow->theme->mcanvas_y;
2205                 int h = mwindow->theme->mcanvas_h;
2206
2207                 if(!x_divider)
2208                 {
2209                         add_subwindow(x_divider = new PaneDivider(
2210                                 mwindow, x, y, h, 1));
2211                         x_divider->create_objects();
2212                 }
2213                 else
2214                 {
2215                         x_divider->reposition_window(x, y, h);
2216                         x_divider->draw(0);
2217                 }
2218         }
2219         else
2220         {
2221                 if(x_divider)
2222                 {
2223                         delete x_divider;
2224                         x_divider = 0;
2225                 }
2226         }
2227
2228         if(vertical_panes() || total_panes() == 4)
2229         {
2230                 int x = mwindow->theme->mcanvas_x;
2231                 int y = pane[BOTTOM_LEFT_PANE]->y -
2232                         mwindow->theme->pane_h;
2233                 int w = mwindow->theme->mcanvas_w;
2234                 if(!y_divider)
2235                 {
2236                         add_subwindow(y_divider = new PaneDivider(
2237                                 mwindow, x, y, w, 0));
2238                         y_divider->create_objects();
2239                 }
2240                 else
2241                 {
2242                         y_divider->reposition_window(x, y, w);
2243                         y_divider->draw(0);
2244                 }
2245         }
2246         else
2247         {
2248                 if(y_divider)
2249                 {
2250                         delete y_divider;
2251                         y_divider = 0;
2252                 }
2253         }
2254 }
2255
2256 void MWindowGUI::draw_samplemovement()
2257 {
2258         draw_canvas(0, 1);
2259         show_cursor(1);
2260         flash_canvas(0);
2261         update_timebar(0);
2262         zoombar->update();
2263         update_scrollbars(1);
2264 }
2265
2266 void MWindowGUI::draw_trackmovement()
2267 {
2268         update_scrollbars(0);
2269         draw_canvas(0, 0);
2270         update_patchbay();
2271         flash_canvas(1);
2272 }
2273
2274
2275
2276 PaneButton::PaneButton(MWindow *mwindow, int x, int y)
2277  : BC_Button(x, y, mwindow->theme->get_image_set("pane"))
2278 {
2279         this->mwindow = mwindow;
2280 }
2281
2282 int PaneButton::cursor_motion_event()
2283 {
2284         if(get_top_level()->get_button_down() && 
2285                 is_event_win() && 
2286                 get_status() == BUTTON_DOWNHI &&
2287                 !cursor_inside())
2288         {
2289 //              printf("PaneButton::cursor_motion_event %d\n", __LINE__);
2290 // create drag bar
2291                 if(get_cursor_x() < 0 && !mwindow->gui->dragging_pane)
2292                 {
2293                         mwindow->gui->start_x_pane_drag();
2294                 }
2295                 else
2296                 if(get_cursor_y() < 0 && !mwindow->gui->dragging_pane)
2297                 {
2298                         mwindow->gui->start_y_pane_drag();
2299                 }
2300         }
2301         
2302         mwindow->gui->handle_pane_drag();
2303
2304         int result = BC_Button::cursor_motion_event();
2305         return result;
2306 }
2307
2308 int PaneButton::button_release_event()
2309 {
2310         mwindow->gui->stop_pane_drag();
2311
2312
2313         int result = BC_Button::button_release_event();
2314         return result;
2315 }
2316
2317
2318