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