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