add refresh rate to vicons + a bunch of bug fixes
[goodguy/history.git] / cinelerra-5.0 / cinelerra / awindowgui.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 1997-2012 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 "asset.h"
23 #include "assetedit.h"
24 #include "assetpopup.h"
25 #include "assets.h"
26 #include "awindowgui.h"
27 #include "awindowgui.inc"
28 #include "awindow.h"
29 #include "awindowmenu.h"
30 #include "bcsignals.h"
31 #include "bchash.h"
32 #include "cache.h"
33 #include "bccmodels.h"
34 #include "cursors.h"
35 #include "cwindowgui.h"
36 #include "cwindow.h"
37 #include "edl.h"
38 #include "edlsession.h"
39 #include "file.h"
40 #include "filesystem.h"
41 #include "indexable.h"
42 #include "keys.h"
43 #include "language.h"
44 #include "localsession.h"
45 #include "mainmenu.h"
46 #include "mainsession.h"
47 #include "mwindowgui.h"
48 #include "mwindow.h"
49 #include "nestededls.h"
50 #include "newfolder.h"
51 #include "preferences.h"
52 #include "theme.h"
53 #include "vframe.h"
54 #include "vicon.h"
55 #include "vwindowgui.h"
56 #include "vwindow.h"
57
58 #include "data/lad_picon_png.h"
59 #include "data/ff_audio_png.h"
60 #include "data/ff_video_png.h"
61
62 #include<stdio.h>
63 #include<unistd.h>
64 #include<fcntl.h>
65
66
67
68 AssetVIcon::AssetVIcon(AssetPicon *picon, int w, int h, double framerate, int64_t length)
69  : VIcon(w, h, framerate)
70 {
71         this->picon = picon;
72         this->length = length;
73         temp = 0;
74 }
75
76 AssetVIcon::~AssetVIcon()
77 {
78         delete temp;
79 }
80
81 VFrame *AssetVIcon::frame()
82 {
83         if( seq_no >= images.size() ) {
84                 MWindow *mwindow = picon->mwindow;
85                 Asset *asset = (Asset *)picon->indexable;
86                 File *file = mwindow->video_cache->check_out(asset, mwindow->edl, 1);
87                 if( !file ) return 0;
88                 if( temp && (temp->get_w() != asset->width || temp->get_h() != asset->height) ) {
89                         delete temp;  temp = 0;
90                 }
91                 if( !temp )
92                         temp = new VFrame(asset->width, asset->height, BC_RGB888);
93                 file->set_layer(0);
94                 int64_t pos = seq_no / picon->gui->vicon_thread->refresh_rate * frame_rate;
95                 file->set_video_position(pos,0);
96                 int ww = picon->gui->vicon_thread->view_w;
97                 int hh = picon->gui->vicon_thread->view_h;
98                 while( seq_no >= images.size() ) {
99                         file->read_frame(temp);
100                         add_image(temp, ww, hh, BC_RGB8);
101                 }
102                 mwindow->video_cache->check_in(asset);
103         }
104         return *images[seq_no];
105 }
106
107 int64_t AssetVIcon::set_seq_no(int64_t no)
108 {
109         if( no >= length ) no = 0;
110         return seq_no = no;
111 }
112
113 int AssetVIcon::get_vx()
114 {
115         BC_ListBox *lbox = picon->gui->asset_list;
116         return lbox->get_item_x(picon);
117 }
118 int AssetVIcon::get_vy()
119 {
120         BC_ListBox *lbox = picon->gui->asset_list;
121         return lbox->get_item_y(picon) + lbox->get_title_h();
122 }
123
124 AssetPicon::AssetPicon(MWindow *mwindow, 
125         AWindowGUI *gui, 
126         Indexable *indexable)
127  : BC_ListBoxItem()
128 {
129         reset();
130         this->mwindow = mwindow;
131         this->gui = gui;
132         this->indexable = indexable;
133         indexable->add_user();
134         this->id = indexable->id;
135 }
136
137 AssetPicon::AssetPicon(MWindow *mwindow, 
138         AWindowGUI *gui, 
139         EDL *edl)
140  : BC_ListBoxItem()
141 {
142         reset();
143         this->mwindow = mwindow;
144         this->gui = gui;
145         this->edl = edl;
146         edl->add_user();
147         this->id = edl->id;
148 }
149
150 AssetPicon::AssetPicon(MWindow *mwindow, 
151         AWindowGUI *gui, 
152         const char *folder)
153  : BC_ListBoxItem(folder, gui->folder_icon)
154 {
155         reset();
156         this->mwindow = mwindow;
157         this->gui = gui;
158 }
159
160 AssetPicon::AssetPicon(MWindow *mwindow, 
161         AWindowGUI *gui, 
162         PluginServer *plugin)
163  : BC_ListBoxItem()
164 {
165         reset();
166         this->mwindow = mwindow;
167         this->gui = gui;
168         this->plugin = plugin;
169 }
170
171
172 AssetPicon::~AssetPicon()
173 {
174         if( vicon )
175                 gui->vicon_thread->del_vicon(vicon);
176         if(indexable) indexable->remove_user();
177         if(edl) edl->remove_user();
178         if( icon && !gui->protected_pixmap(icon) ) {
179                 delete icon;
180                 if( !plugin ) delete icon_vframe;
181         }
182 }
183
184 void AssetPicon::reset()
185 {
186         plugin = 0;
187         indexable = 0;
188         edl = 0;
189         icon = 0;
190         icon_vframe = 0;
191         vicon = 0;
192         in_use = 1;
193         id = 0;
194         persistent = 0;
195 }
196
197 void AssetPicon::create_objects()
198 {
199         FileSystem fs;
200         char name[BCTEXTLEN];
201         int pixmap_w, pixmap_h;
202         const int debug = 0;
203
204         pixmap_h = 50;
205
206         if(debug) printf("AssetPicon::create_objects %d\n", __LINE__);
207         if(indexable)
208         {
209                 fs.extract_name(name, indexable->path);
210                 set_text(name);
211         }
212         
213         if(indexable && indexable->is_asset)
214         {
215                 if(debug) printf("AssetPicon::create_objects %d\n", __LINE__);
216                 Asset *asset = (Asset*)indexable;
217                 if(asset->video_data)
218                 {
219                         if(mwindow->preferences->use_thumbnails)
220                         {
221                                 gui->unlock_window();
222                                 if(debug) printf("AssetPicon::create_objects %d\n", __LINE__);
223                                 File *file = mwindow->video_cache->check_out(asset, 
224                                         mwindow->edl,
225                                         1);
226                                 if(debug) printf("AssetPicon::create_objects %d\n", __LINE__);
227
228                                 if(file)
229                                 {
230                                         int height = asset->height > 0 ? asset->height : 1;
231                                         pixmap_w = pixmap_h * asset->width / height;
232
233                                         file->set_layer(0);
234                                         file->set_video_position(0, 0);
235
236                                         if(gui->temp_picon && 
237                                                 (gui->temp_picon->get_w() != asset->width ||
238                                                 gui->temp_picon->get_h() != asset->height))
239                                         {
240                                                 delete gui->temp_picon;
241                                                 gui->temp_picon = 0;
242                                         }
243
244                                         if(!gui->temp_picon)
245                                         {
246                                                 gui->temp_picon = new VFrame(0, -1,
247                                                         asset->width, asset->height, 
248                                                         BC_RGB888, -1);
249                                         }
250
251                                         file->read_frame(gui->temp_picon);
252                                         if(debug) printf("AssetPicon::create_objects %d\n", __LINE__);
253                                         mwindow->video_cache->check_in(asset);
254
255                                         gui->lock_window("AssetPicon::create_objects 1");
256                                         icon = new BC_Pixmap(gui, pixmap_w, pixmap_h);
257                                         icon->draw_vframe(gui->temp_picon,
258                                                 0, 0, pixmap_w, pixmap_h, 0, 0);
259 //printf("%d %d\n", gui->temp_picon->get_w(), gui->temp_picon->get_h());
260                                         icon_vframe = new VFrame(0,
261                                                 -1, pixmap_w, pixmap_h, BC_RGB888, -1);
262                                         icon_vframe->transfer_from(gui->temp_picon);
263 // vicon images
264                                         double framerate = asset->get_frame_rate();
265                                         if( !framerate ) framerate = 24;
266                                         int64_t length = framerate * 5;
267                                         int64_t vframes = asset->get_video_frames();
268                                         if( length > vframes ) length = vframes;
269                                         vicon = new AssetVIcon(this, pixmap_w, pixmap_h, framerate, length);
270                                         gui->vicon_thread->add_vicon(vicon);
271                                         if(debug) printf("AssetPicon::create_objects %d\n", __LINE__);
272
273                                 }
274                                 else
275                                 {
276                                         gui->lock_window("AssetPicon::create_objects 2");
277                                         icon = gui->video_icon;
278                                         icon_vframe = BC_WindowBase::get_resources()->type_to_icon[ICON_FILM];
279                                 }
280                         }
281                         else
282                         {
283                                 icon = gui->video_icon;
284                                 icon_vframe = BC_WindowBase::get_resources()->type_to_icon[ICON_FILM];                  
285                         }
286                 }
287                 else
288                 if(asset->audio_data)
289                 {
290                         icon = gui->audio_icon;
291                         icon_vframe = BC_WindowBase::get_resources()->type_to_icon[ICON_SOUND];
292                 }
293 //printf("AssetPicon::create_objects 2\n");
294
295                 if(debug) printf("AssetPicon::create_objects %d\n", __LINE__);
296         }
297         else
298         if(indexable && !indexable->is_asset)
299         {
300                 icon = gui->video_icon;
301                 icon_vframe = BC_WindowBase::get_resources()->type_to_icon[ICON_FILM];
302         }
303         else
304         if(edl)
305         {
306 //printf("AssetPicon::create_objects 4 %s\n", edl->local_session->clip_title);
307                 set_text(strcpy(name, edl->local_session->clip_title));
308                 icon = gui->clip_icon;
309                 icon_vframe = mwindow->theme->get_image("clip_icon");
310         }
311         else
312         if(plugin)
313         {
314                 strcpy(name, _(plugin->title));
315                 set_text(name);
316                 icon_vframe = plugin->get_picon();
317                 if( icon_vframe )
318                         icon = gui->create_pixmap(icon_vframe);
319                 else if( plugin->audio ) {
320                         if( plugin->transition ) {
321                                 icon = gui->atransition_icon;
322                                 icon_vframe = gui->atransition_vframe;
323                         }
324                         else if( plugin->is_ffmpeg() ) {
325                                 icon = gui->ff_aud_icon;
326                                 icon_vframe = gui->ff_aud_vframe;
327                         }
328                         else if( plugin->is_ladspa() ) {
329                                 icon = gui->ladspa_icon;
330                                 icon_vframe = gui->ladspa_vframe;
331                         }
332                         else {
333                                 icon = gui->aeffect_icon;
334                                 icon_vframe = gui->aeffect_vframe;
335                         }
336                 }
337                 else if( plugin->video ) {
338                         if( plugin->transition ) {
339                                 icon = gui->vtransition_icon;
340                                 icon_vframe = gui->vtransition_vframe;
341                         }
342                         else if( plugin->is_ffmpeg() ) {
343                                 icon = gui->ff_vid_icon;
344                                 icon_vframe = gui->ff_vid_vframe;
345                         }
346                         else {
347                                 icon = gui->veffect_icon;
348                                 icon_vframe = gui->veffect_vframe;
349                         }
350                 }
351         }
352         if( !icon ) {
353                 icon = gui->file_icon;
354                 icon_vframe = BC_WindowBase::get_resources()->type_to_icon[ICON_UNKNOWN];
355         }
356         set_icon(icon);
357         set_icon_vframe(icon_vframe);
358
359         if(debug) printf("AssetPicon::create_objects %d\n", __LINE__);
360 }
361
362
363
364
365
366
367 AWindowGUI::AWindowGUI(MWindow *mwindow, AWindow *awindow)
368  : BC_Window(PROGRAM_NAME ": Resources",
369         mwindow->session->awindow_x, 
370     mwindow->session->awindow_y, 
371     mwindow->session->awindow_w, 
372     mwindow->session->awindow_h,
373     100,
374     100,
375     1,
376     1,
377     1)
378 {
379 // printf("AWindowGUI::AWindowGUI %d %d %d %d\n",
380 // mwindow->session->awindow_x, 
381 // mwindow->session->awindow_y, 
382 // mwindow->session->awindow_w, 
383 // mwindow->session->awindow_h);
384         this->mwindow = mwindow;
385         this->awindow = awindow;
386         file_icon = 0;
387         audio_icon = 0;
388         video_icon = 0;
389         folder_icon = 0;
390         clip_icon = 0;
391         atransition_icon = 0;  atransition_vframe = 0;
392         vtransition_icon = 0;  vtransition_vframe = 0;
393         aeffect_icon = 0;      aeffect_vframe = 0;
394         ladspa_icon = 0;       ladspa_vframe = 0;
395         veffect_icon = 0;      veffect_vframe = 0;
396         ff_aud_icon = 0;       ff_aud_vframe = 0;
397         ff_vid_icon = 0;       ff_vid_vframe = 0;
398         plugin_visibility = ((uint64_t)1<<(8*sizeof(uint64_t)-1))-1;
399         newfolder_thread = 0;
400         asset_menu = 0;
401         assetlist_menu = 0;
402         folderlist_menu = 0;
403         temp_picon = 0;
404         remove_plugin = 0;
405         vicon_thread = 0;
406         vicon_drawing = 1;
407 }
408
409 AWindowGUI::~AWindowGUI()
410 {
411         assets.remove_all_objects();
412         folders.remove_all_objects();
413         aeffects.remove_all_objects();
414         veffects.remove_all_objects();
415         atransitions.remove_all_objects();
416         vtransitions.remove_all_objects();
417         displayed_assets[1].remove_all_objects();
418
419         delete vicon_thread;
420         delete file_icon;
421         delete audio_icon;
422         delete video_icon;
423         delete folder_icon;
424         delete clip_icon;
425         delete atransition_icon;
426         delete vtransition_icon;
427         delete aeffect_icon;
428         delete ladspa_icon;
429         delete ladspa_vframe;
430         delete ff_aud_icon;
431         delete ff_aud_vframe;
432         delete ff_vid_icon;
433         delete ff_vid_vframe;
434         delete veffect_icon;
435         delete newfolder_thread;
436         delete asset_menu;
437         delete assetlist_menu;
438         delete folderlist_menu;
439         if(temp_picon) delete temp_picon;
440         delete remove_plugin;
441 }
442
443 bool AWindowGUI::protected_pixmap(BC_Pixmap *icon)
444 {
445         return  icon == file_icon ||
446                 icon == folder_icon ||
447                 icon == audio_icon ||
448                 icon == video_icon ||
449                 icon == clip_icon ||
450                 icon == vtransition_icon ||
451                 icon == atransition_icon ||
452                 icon == veffect_icon ||
453                 icon == aeffect_icon ||
454                 icon == ladspa_icon ||
455                 icon == ff_aud_icon ||
456                 icon == ff_vid_icon;
457 }
458
459 void AWindowGUI::create_objects()
460 {
461         AssetPicon *picon;
462
463         lock_window("AWindowGUI::create_objects");
464 SET_TRACE
465 //printf("AWindowGUI::create_objects 1\n");
466         asset_titles[0] = _("Title");
467         asset_titles[1] = _("Comments");
468
469 SET_TRACE
470
471         set_icon(mwindow->theme->get_image("awindow_icon"));
472         file_icon = new BC_Pixmap(this, 
473                 BC_WindowBase::get_resources()->type_to_icon[ICON_UNKNOWN],
474                 PIXMAP_ALPHA);
475
476         folder_icon = new BC_Pixmap(this, 
477                 BC_WindowBase::get_resources()->type_to_icon[ICON_FOLDER],
478                 PIXMAP_ALPHA);
479
480         audio_icon = new BC_Pixmap(this, 
481                 BC_WindowBase::get_resources()->type_to_icon[ICON_SOUND],
482                 PIXMAP_ALPHA);
483
484         video_icon = new BC_Pixmap(this, 
485                 BC_WindowBase::get_resources()->type_to_icon[ICON_FILM],
486                 PIXMAP_ALPHA);
487
488 SET_TRACE
489
490         clip_vframe = mwindow->theme->get_image("clip_icon");
491         clip_icon = new BC_Pixmap(this, clip_vframe, PIXMAP_ALPHA);
492         atransition_vframe = mwindow->theme->get_image("atransition_icon");
493         atransition_icon = new BC_Pixmap(this, atransition_vframe, PIXMAP_ALPHA);
494         vtransition_vframe = mwindow->theme->get_image("vtransition_icon");
495         vtransition_icon = new BC_Pixmap(this, vtransition_vframe, PIXMAP_ALPHA);
496         aeffect_vframe = mwindow->theme->get_image("aeffect_icon");
497         aeffect_icon = new BC_Pixmap(this, aeffect_vframe, PIXMAP_ALPHA);
498         ladspa_vframe = new VFrame(lad_picon_png);
499         ladspa_icon = new BC_Pixmap(this, ladspa_vframe, PIXMAP_ALPHA);
500         ff_aud_vframe = new VFrame(ff_audio_png);
501         ff_aud_icon = new BC_Pixmap(this, ff_aud_vframe, PIXMAP_ALPHA);
502         ff_vid_vframe = new VFrame(ff_video_png);
503         ff_vid_icon = new BC_Pixmap(this, ff_vid_vframe, PIXMAP_ALPHA);
504         veffect_vframe = mwindow->theme->get_image("veffect_icon");
505         veffect_icon = new BC_Pixmap(this, veffect_vframe, PIXMAP_ALPHA);
506
507 SET_TRACE
508
509 // Mandatory folders
510         folders.append(picon = new AssetPicon(mwindow,
511                 this,
512                 AEFFECT_FOLDER));
513         picon->persistent = 1;
514         folders.append(picon = new AssetPicon(mwindow,
515                 this,
516                 VEFFECT_FOLDER));
517         picon->persistent = 1;
518         folders.append(picon = new AssetPicon(mwindow,
519                 this,
520                 ATRANSITION_FOLDER));
521         picon->persistent = 1;
522         folders.append(picon = new AssetPicon(mwindow,
523                 this,
524                 VTRANSITION_FOLDER));
525         picon->persistent = 1;
526 SET_TRACE
527
528         mwindow->theme->get_awindow_sizes(this);
529         load_defaults(mwindow->defaults);
530
531 SET_TRACE
532         add_subwindow(asset_list = new AWindowAssets(mwindow,
533                 this,
534                 mwindow->theme->alist_x, 
535                 mwindow->theme->alist_y, 
536                 mwindow->theme->alist_w, 
537                 mwindow->theme->alist_h));
538
539         vicon_thread = new VIconThread(asset_list);
540         vicon_thread->start();
541
542 SET_TRACE
543         add_subwindow(divider = new AWindowDivider(mwindow,
544                 this,
545                 mwindow->theme->adivider_x,
546                 mwindow->theme->adivider_y,
547                 mwindow->theme->adivider_w,
548                 mwindow->theme->adivider_h));
549
550 SET_TRACE
551         divider->set_cursor(HSEPARATE_CURSOR, 0, 0);
552
553 SET_TRACE
554         int fx = mwindow->theme->afolders_x, fy = mwindow->theme->afolders_y;
555         int fw = mwindow->theme->afolders_w, fh = mwindow->theme->afolders_h;
556         VFrame **images = mwindow->theme->get_image_set("playpatch_data");
557         AVIconDrawing::calculate_geometry(this, images, &avicon_w, &avicon_h);
558         add_subwindow(avicon_drawing = new AVIconDrawing(this, fw-avicon_w, fy, images));
559         add_subwindow(add_tools = new AddTools(mwindow, this, fx, fy, fw-avicon_w));
560         add_tools->create_objects();
561         fy += add_tools->get_h();  fh -= add_tools->get_h();
562 SET_TRACE
563         add_subwindow(folder_list = new AWindowFolders(mwindow,
564                 this, fx, fy, fw, fh));
565 SET_TRACE
566         update_effects();
567 SET_TRACE
568
569         //int x = mwindow->theme->abuttons_x;
570         //int y = mwindow->theme->abuttons_y;
571
572 SET_TRACE
573
574         newfolder_thread = new NewFolderThread(mwindow, this);
575
576         add_subwindow(asset_menu = new AssetPopup(mwindow, this));
577         asset_menu->create_objects();
578
579 SET_TRACE
580
581         add_subwindow(assetlist_menu = new AssetListMenu(mwindow, this));
582
583 SET_TRACE
584         assetlist_menu->create_objects();
585
586 SET_TRACE
587
588         add_subwindow(folderlist_menu = new FolderListMenu(mwindow, this));
589         folderlist_menu->create_objects();
590 //printf("AWindowGUI::create_objects 2\n");
591
592 SET_TRACE
593         unlock_window();
594 }
595
596 int AWindowGUI::resize_event(int w, int h)
597 {
598         mwindow->session->awindow_x = get_x();
599         mwindow->session->awindow_y = get_y();
600         mwindow->session->awindow_w = w;
601         mwindow->session->awindow_h = h;
602
603         mwindow->theme->get_awindow_sizes(this);
604         mwindow->theme->draw_awindow_bg(this);
605         reposition_objects();
606         
607 //      int x = mwindow->theme->abuttons_x;
608 //      int y = mwindow->theme->abuttons_y;
609 //      new_bin->reposition_window(x, y);
610 //      x += new_bin->get_w();
611 //      delete_bin->reposition_window(x, y);
612 //      x += delete_bin->get_w();
613 //      rename_bin->reposition_window(x, y);
614 //      x += rename_bin->get_w();
615 //      delete_disk->reposition_window(x, y);
616 //      x += delete_disk->get_w();
617 //      delete_project->reposition_window(x, y);
618 //      x += delete_project->get_w();
619 //      info->reposition_window(x, y);
620 //      x += info->get_w();
621 //      redraw_index->reposition_window(x, y);
622 //      x += redraw_index->get_w();
623 //      paste->reposition_window(x, y);
624 //      x += paste->get_w();
625 //      append->reposition_window(x, y);
626 //      x += append->get_w();
627 //      view->reposition_window(x, y);
628
629         BC_WindowBase::resize_event(w, h);
630         return 1;
631 }
632
633 int AWindowGUI::translation_event()
634 {
635         mwindow->session->awindow_x = get_x();
636         mwindow->session->awindow_y = get_y();
637         return 0;
638 }
639
640 void AWindowGUI::reposition_objects()
641 {
642         mwindow->theme->get_awindow_sizes(this);
643         asset_list->reposition_window(
644                 mwindow->theme->alist_x, mwindow->theme->alist_y, 
645                 mwindow->theme->alist_w, mwindow->theme->alist_h);
646         divider->reposition_window(
647                 mwindow->theme->adivider_x, mwindow->theme->adivider_y,
648                 mwindow->theme->adivider_w, mwindow->theme->adivider_h);
649         int fx = mwindow->theme->afolders_x, fy = mwindow->theme->afolders_y;
650         int fw = mwindow->theme->afolders_w, fh = mwindow->theme->afolders_h;
651         add_tools->resize_event(fw-avicon_w, add_tools->get_h());
652         avicon_drawing->reposition_window(fw-avicon_w, fy);
653         fy += add_tools->get_h();  fh -= add_tools->get_h();
654         folder_list->reposition_window(fx, fy, fw, fh);
655 }
656
657 int AWindowGUI::save_defaults(BC_Hash *defaults)
658 {
659         defaults->update("PLUGIN_VISIBILTY", plugin_visibility);
660         defaults->update("VICON_DRAWING", vicon_drawing);
661         return 0;
662 }
663
664 int AWindowGUI::load_defaults(BC_Hash *defaults)
665 {
666         plugin_visibility = defaults->get("PLUGIN_VISIBILTY", plugin_visibility);
667         vicon_drawing = defaults->get("VICON_DRAWING", vicon_drawing);
668         return 0;
669 }
670
671
672 int AWindowGUI::close_event()
673 {
674         hide_window();
675         mwindow->session->show_awindow = 0;
676         unlock_window();
677
678         mwindow->gui->lock_window("AWindowGUI::close_event");
679         mwindow->gui->mainmenu->show_awindow->set_checked(0);
680         mwindow->gui->unlock_window();
681
682         lock_window("AWindowGUI::close_event");
683         save_defaults(mwindow->defaults);
684         mwindow->save_defaults();
685         return 1;
686 }
687
688 void AWindowGUI::start_vicon_drawing()
689 {
690         if( !vicon_drawing ) return;
691         if( strcmp(mwindow->edl->session->current_folder, MEDIA_FOLDER) ) return;
692         if( mwindow->edl->session->assetlist_format != ASSETS_ICONS ) return;
693         vicon_thread->start_drawing();
694 }
695
696 void AWindowGUI::stop_vicon_drawing()
697 {
698         vicon_thread->stop_drawing();
699 }
700
701 AWindowRemovePluginGUI::
702 AWindowRemovePluginGUI(AWindow *awindow, AWindowRemovePlugin *thread,
703         int x, int y, PluginServer *plugin)
704  : BC_Window(PROGRAM_NAME ": Remove plugin", x,y, 500,200, 50, 50, 1, 0, 1, -1, "", 1)
705 {
706         this->awindow = awindow;
707         this->thread = thread;
708         this->plugin = plugin;
709         VFrame *vframe = plugin->get_picon();
710         icon = vframe ? create_pixmap(vframe) : 0;
711         plugin_list.append(new BC_ListBoxItem(plugin->title, icon));
712 }
713
714 AWindowRemovePluginGUI::
715 ~AWindowRemovePluginGUI()
716 {
717         if( !awindow->gui->protected_pixmap(icon) )
718                 delete icon;
719         plugin_list.remove_all();
720 }
721
722 void AWindowRemovePluginGUI::create_objects()
723 {
724         BC_Button *ok_button = new BC_OKButton(this);
725         add_subwindow(ok_button);
726         BC_Button *cancel_button = new BC_CancelButton(this);
727         add_subwindow(cancel_button);
728         int x = 10, y = 10;
729         BC_Title *title = new BC_Title(x, y, _("remove plugin?"));
730         add_subwindow(title);
731         y += title->get_h() + 5;
732         list = new BC_ListBox(x, y,
733                 get_w() - 20, ok_button->get_y() - y - 5, LISTBOX_TEXT, &plugin_list,
734                 0, 0, 1, 0, 0, LISTBOX_SINGLE, ICON_LEFT, 0);
735         add_subwindow(list);
736         show_window();
737 }
738
739 int AWindowRemovePlugin::remove_plugin(PluginServer *plugin, ArrayList<BC_ListBoxItem*> &folder)
740 {
741         int ret = 0;
742         for( int i=0; i<folder.size(); ) {
743                 AssetPicon *picon = (AssetPicon *)folder[i];
744                 if( picon->plugin == plugin ) {
745                         folder.remove_object_number(i);
746                         ++ret;
747                         continue;
748                 }
749                 ++i;
750         }
751         return ret;
752 }
753
754 void AWindowRemovePlugin::handle_close_event(int result)
755 {
756         if( !result ) {
757                 printf("remove %s\n", plugin->path);
758                 ArrayList<BC_ListBoxItem*> *folder = 
759                         plugin->audio ? plugin->transition ?
760                                 &awindow->gui->atransitions :
761                                 &awindow->gui->aeffects :
762                         plugin->video ?  plugin->transition ?
763                                 &awindow->gui->vtransitions :
764                                 &awindow->gui->veffects :
765                         0;
766                 if( folder ) remove_plugin(plugin, *folder);
767                 awindow->gui->update_assets();
768                 char png_path[BCTEXTLEN], plugin_path[BCTEXTLEN], index_path[BCTEXTLEN];
769                 strcpy(plugin_path, plugin->path);
770                 if( !plugin->get_plugin_png_path(png_path) ) png_path[0] = 0;
771                 MWindow *mwindow = awindow->mwindow;
772                 sprintf(index_path, "%s/%s", mwindow->preferences->plugin_dir, PLUGIN_FILE);
773                 mwindow->plugindb->remove(plugin);
774                 plugin->delete_this();
775                 remove(plugin_path);
776                 if( png_path[0] ) remove(png_path);
777                 remove(index_path);
778         }
779 }
780
781 AWindowRemovePlugin::
782 AWindowRemovePlugin(AWindow *awindow, PluginServer *plugin)
783  : BC_DialogThread()
784 {
785         this->awindow = awindow;
786         this->plugin = plugin;
787 }
788
789 AWindowRemovePlugin::
790 ~AWindowRemovePlugin()
791 {
792         close_window();
793 }
794
795 BC_Window* AWindowRemovePlugin::new_gui()
796 {
797         int x = awindow->gui->get_abs_cursor_x(0);
798         int y = awindow->gui->get_abs_cursor_y(0);
799         AWindowRemovePluginGUI *gui = new AWindowRemovePluginGUI(awindow, this, x, y, plugin);
800         gui->create_objects();
801         return gui;
802 }
803
804 int AWindowGUI::keypress_event()
805 {
806         switch(get_keypress()) {
807         case 'w': case 'W':
808                 if(ctrl_down()) {
809                         close_event();
810                         return 1;
811                 }
812                 break;
813         case DELETE:
814                 if(shift_down()) {
815                         PluginServer* plugin = selected_plugin();
816                         if( !plugin ) break;
817                         remove_plugin = new AWindowRemovePlugin(awindow, plugin);
818                         unlock_window();
819                         remove_plugin->start();
820                         lock_window();
821                 }
822         }
823         return 0;
824 }
825
826 void AWindowGUI::update_folder_list()
827 {
828         stop_vicon_drawing();
829 //printf("AWindowGUI::update_folder_list 1\n");
830         for(int i = 0; i < folders.total; i++)
831         {
832                 AssetPicon *picon = (AssetPicon*)folders.values[i];
833                 picon->in_use--;
834         }
835 //printf("AWindowGUI::update_folder_list 1\n");
836
837 // Search assets for folders
838         for(int i = 0; i < mwindow->edl->folders.total; i++)
839         {
840                 char *folder = mwindow->edl->folders.values[i];
841                 int exists = 0;
842 //printf("AWindowGUI::update_folder_list 1.1\n");
843
844                 for(int j = 0; j < folders.total; j++)
845                 {
846                         AssetPicon *picon = (AssetPicon*)folders.values[j];
847                         if(!strcasecmp(picon->get_text(), folder))
848                         {
849                                 exists = 1;
850                                 picon->in_use = 1;
851                                 break;
852                         }
853                 }
854
855                 if(!exists)
856                 {
857                         AssetPicon *picon = new AssetPicon(mwindow, this, folder);
858                         picon->create_objects();
859                         folders.append(picon);
860                 }
861 //printf("AWindowGUI::update_folder_list 1.3\n");
862         }
863 //printf("AWindowGUI::update_folder_list 1\n");
864 //for(int i = 0; i < folders.total; i++)
865 //      printf("AWindowGUI::update_folder_list %s\n", folders.values[i]->get_text());
866
867 // Delete excess
868         for(int i = folders.total - 1; i >= 0; i--)
869         {
870                 AssetPicon *picon = (AssetPicon*)folders.values[i];
871                 if(!picon->in_use && !picon->persistent)
872                 {
873                         delete picon;
874                         folders.remove_number(i);
875                 }
876         }
877 //for(int i = 0; i < folders.total; i++)
878 //      printf("AWindowGUI::update_folder_list %s\n", folders.values[i]->get_text());
879 //printf("AWindowGUI::update_folder_list 2\n");
880         start_vicon_drawing();
881 }
882
883 void AWindowGUI::create_persistent_folder(ArrayList<BC_ListBoxItem*> *output, 
884         int do_audio, int do_video, int is_realtime, int is_transition)
885 {
886         ArrayList<PluginServer*> plugin_list;
887 // Get pointers to plugindb entries
888         mwindow->search_plugindb(do_audio, do_video, is_realtime, is_transition,
889                         0, plugin_list);
890
891         for(int i = 0; i < plugin_list.total; i++) {
892                 PluginServer *server = plugin_list.values[i];
893                 int visible = plugin_visibility & (1<<server->dir_idx);
894                 if(!visible) continue;
895 // Create new listitem
896                 AssetPicon *picon = new AssetPicon(mwindow, this, server);
897                 picon->create_objects();
898                 output->append(picon);
899         }
900 }
901
902 void AWindowGUI::update_asset_list()
903 {
904 //printf("AWindowGUI::update_asset_list 1\n");
905         for(int i = 0; i < assets.total; i++)
906         {
907                 AssetPicon *picon = (AssetPicon*)assets.values[i];
908                 picon->in_use--;
909         }
910
911
912
913
914
915 //printf("AWindowGUI::update_asset_list 2\n");
916
917
918 // Synchronize EDL clips
919         for(int i = 0; i < mwindow->edl->clips.total; i++)
920         {
921                 int exists = 0;
922                 
923 // Look for clip in existing listitems
924                 for(int j = 0; j < assets.total && !exists; j++)
925                 {
926                         AssetPicon *picon = (AssetPicon*)assets.values[j];
927                         
928                         if(picon->id == mwindow->edl->clips.values[i]->id)
929                         {
930                                 picon->edl = mwindow->edl->clips.values[i];
931                                 picon->set_text(mwindow->edl->clips.values[i]->local_session->clip_title);
932                                 exists = 1;
933                                 picon->in_use = 1;
934                         }
935                 }
936
937 // Create new listitem
938                 if(!exists)
939                 {
940                         AssetPicon *picon = new AssetPicon(mwindow, 
941                                 this, 
942                                 mwindow->edl->clips.values[i]);
943                         picon->create_objects();
944                         assets.append(picon);
945                 }
946         }
947
948
949
950
951
952 //printf("AWindowGUI::update_asset_list %d\n", __LINE__);
953
954
955 // Synchronize EDL assets
956         for(Asset *current = mwindow->edl->assets->first; 
957                 current; 
958                 current = NEXT)
959         {
960                 int exists = 0;
961
962 // Look for asset in existing listitems
963                 for(int j = 0; j < assets.total && !exists; j++)
964                 {
965                         AssetPicon *picon = (AssetPicon*)assets.values[j];
966
967                         if(picon->id == current->id)
968                         {
969                                 picon->indexable = current;
970                                 exists = 1;
971                                 picon->in_use = 1;
972                                 break;
973                         }
974                 }
975
976 // Create new listitem
977                 if(!exists)
978                 {
979 //printf("AWindowGUI::update_asset_list %d\n", __LINE__);
980                         AssetPicon *picon = new AssetPicon(mwindow, this, current);
981 //printf("AWindowGUI::update_asset_list %d\n", __LINE__);
982                         picon->create_objects();
983 //printf("AWindowGUI::update_asset_list %d\n", __LINE__);
984                         assets.append(picon);
985                 }
986         }
987
988
989
990 //printf("AWindowGUI::update_asset_list %d\n", __LINE__);
991
992
993 // Synchronize nested EDLs
994         for(int i = 0; i < mwindow->edl->nested_edls->size(); i++)
995         {
996                 int exists = 0;
997                 Indexable *indexable = mwindow->edl->nested_edls->get(i);
998
999 // Look for asset in existing listitems
1000                 for(int j = 0; j < assets.total && !exists; j++)
1001                 {
1002                         AssetPicon *picon = (AssetPicon*)assets.values[j];
1003
1004                         if(picon->id == indexable->id)
1005                         {
1006                                 picon->indexable = indexable;
1007                                 exists = 1;
1008                                 picon->in_use = 1;
1009                                 break;
1010                         }
1011                 }
1012
1013 // Create new listitem
1014                 if(!exists)
1015                 {
1016                         AssetPicon *picon = new AssetPicon(mwindow, 
1017                                 this, 
1018                                 indexable);
1019                         picon->create_objects();
1020                         assets.append(picon);
1021                 }
1022         }
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032 //printf("AWindowGUI::update_asset_list %d\n", __LINE__);
1033         for(int i = assets.size() - 1; i >= 0; i--)
1034         {
1035                 AssetPicon *picon = (AssetPicon*)assets.get(i);
1036 //printf("AWindowGUI::update_asset_list %s %d\n", picon->asset->path, picon->in_use);
1037                 if(!picon->in_use)
1038                 {
1039                         delete picon;
1040                         assets.remove_number(i);
1041                 }
1042         }
1043 //printf("AWindowGUI::update_asset_list 7 %d\n", assets.total);
1044 }
1045
1046
1047
1048
1049
1050 void AWindowGUI::sort_assets()
1051 {
1052 //printf("AWindowGUI::sort_assets 1 %s\n", mwindow->edl->session->current_folder);
1053         if(!strcasecmp(mwindow->edl->session->current_folder, AEFFECT_FOLDER))
1054                 sort_picons(&aeffects, 
1055                         0);
1056         else
1057         if(!strcasecmp(mwindow->edl->session->current_folder, VEFFECT_FOLDER))
1058                 sort_picons(&veffects, 
1059                         0);
1060         else
1061         if(!strcasecmp(mwindow->edl->session->current_folder, ATRANSITION_FOLDER))
1062                 sort_picons(&atransitions, 
1063                         0);
1064         else
1065         if(!strcasecmp(mwindow->edl->session->current_folder, VTRANSITION_FOLDER))
1066                 sort_picons(&vtransitions, 
1067                         0);
1068         else
1069                 sort_picons(&assets, 
1070                         mwindow->edl->session->current_folder);
1071
1072         update_assets();
1073 }
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085 void AWindowGUI::collect_assets()
1086 {
1087         int i = 0;
1088         mwindow->session->drag_assets->remove_all();
1089         mwindow->session->drag_clips->remove_all();
1090         while(1)
1091         {
1092                 AssetPicon *result = (AssetPicon*)asset_list->get_selection(0, i++);
1093                 if(!result) break;
1094
1095                 if(result->indexable) mwindow->session->drag_assets->append(result->indexable);
1096                 if(result->edl) mwindow->session->drag_clips->append(result->edl);
1097         }
1098 }
1099
1100 void AWindowGUI::copy_picons(ArrayList<BC_ListBoxItem*> *dst, 
1101         ArrayList<BC_ListBoxItem*> *src, 
1102         char *folder)
1103 {
1104 // Remove current pointers
1105         dst[0].remove_all();
1106         dst[1].remove_all_objects();
1107
1108 // Create new pointers
1109 //if(folder) printf("AWindowGUI::copy_picons 1 %s\n", folder);
1110         for(int i = 0; i < src->total; i++)
1111         {
1112                 AssetPicon *picon = (AssetPicon*)src->values[i];
1113 //printf("AWindowGUI::copy_picons 2 %s\n", picon->asset->folder);
1114                 if(!folder ||
1115                         (folder && picon->indexable && !strcasecmp(picon->indexable->folder, folder)) ||
1116                         (folder && picon->edl && !strcasecmp(picon->edl->local_session->folder, folder)))
1117                 {
1118                         BC_ListBoxItem *item2, *item1;
1119                         dst[0].append(item1 = picon);
1120                         if(picon->edl)
1121                                 dst[1].append(item2 = new BC_ListBoxItem(picon->edl->local_session->clip_notes));
1122                         else
1123                                 dst[1].append(item2 = new BC_ListBoxItem(""));
1124                         item1->set_autoplace_text(1);
1125                         item2->set_autoplace_text(1);
1126 //printf("AWindowGUI::copy_picons 3 %s\n", picon->get_text());
1127                 }
1128         }
1129 }
1130
1131 void AWindowGUI::sort_picons(ArrayList<BC_ListBoxItem*> *src, 
1132                 char *folder)
1133 {
1134 //printf("AWindowGUI::sort_picons 1\n")
1135         int done = 0;
1136         while(!done)
1137         {
1138                 done = 1;
1139                 for(int i = 0; i < src->total - 1; i++)
1140                 {
1141                         BC_ListBoxItem *item1 = src->values[i];
1142                         BC_ListBoxItem *item2 = src->values[i + 1];
1143                         item1->set_autoplace_icon(1);
1144                         item2->set_autoplace_icon(1);
1145                         item1->set_autoplace_text(1);
1146                         item2->set_autoplace_text(1);
1147                         if(strcmp(item1->get_text(), item2->get_text()) > 0)
1148                         {
1149                                 src->values[i + 1] = item1;
1150                                 src->values[i] = item2;
1151                                 done = 0;
1152                         }
1153                 }
1154         }
1155 }
1156
1157
1158 void AWindowGUI::filter_displayed_assets()
1159 {
1160         if(!strcasecmp(mwindow->edl->session->current_folder, AEFFECT_FOLDER))
1161                 copy_picons(displayed_assets, 
1162                         &aeffects, 
1163                         0);
1164         else
1165         if(!strcasecmp(mwindow->edl->session->current_folder, VEFFECT_FOLDER))
1166                 copy_picons(displayed_assets, 
1167                         &veffects, 
1168                         0);
1169         else
1170         if(!strcasecmp(mwindow->edl->session->current_folder, ATRANSITION_FOLDER))
1171                 copy_picons(displayed_assets, 
1172                         &atransitions, 
1173                         0);
1174         else
1175         if(!strcasecmp(mwindow->edl->session->current_folder, VTRANSITION_FOLDER))
1176                 copy_picons(displayed_assets, 
1177                         &vtransitions, 
1178                         0);
1179         else
1180                 copy_picons(displayed_assets, 
1181                         &assets, 
1182                         mwindow->edl->session->current_folder);
1183 }
1184
1185
1186 void AWindowGUI::update_assets()
1187 {
1188 //printf("AWindowGUI::update_assets 1\n");
1189         update_folder_list();
1190 //printf("AWindowGUI::update_assets 2\n");
1191         update_asset_list();
1192 //printf("AWindowGUI::update_assets 3\n");
1193         filter_displayed_assets();
1194
1195 //for(int i = 0; i < folders.total; i++)
1196 //printf("AWindowGUI::update_assets 4\n");
1197 //      printf("AWindowGUI::update_assets %s\n", folders.values[i]->get_text());
1198         if(mwindow->edl->session->folderlist_format != folder_list->get_format())
1199                 folder_list->update_format(mwindow->edl->session->folderlist_format, 0);
1200         folder_list->update(&folders,
1201                 0,
1202                 0,
1203                 1,
1204                 folder_list->get_xposition(),
1205                 folder_list->get_yposition(),
1206                 -1);
1207 //printf("AWindowGUI::update_assets 5\n");
1208
1209         if(mwindow->edl->session->assetlist_format != asset_list->get_format())
1210                 asset_list->update_format(mwindow->edl->session->assetlist_format, 0);
1211
1212
1213 //printf("AWindowGUI::update_assets 6 %d\n", displayed_assets[0].total);
1214         asset_list->update(displayed_assets,
1215                 asset_titles,
1216                 mwindow->edl->session->asset_columns,
1217                 ASSET_COLUMNS, 
1218                 asset_list->get_xposition(),
1219                 asset_list->get_yposition(),
1220                 -1,
1221                 0);
1222 //printf("AWindowGUI::update_assets 7\n");
1223
1224         flush();
1225 //printf("AWindowGUI::update_assets 8\n");
1226         return;
1227 }
1228
1229 void AWindowGUI::update_effects()
1230 {
1231         aeffects.remove_all_objects();
1232         create_persistent_folder(&aeffects, 1, 0, 1, 0);
1233         veffects.remove_all_objects();
1234         create_persistent_folder(&veffects, 0, 1, 1, 0);
1235         atransitions.remove_all_objects();
1236         create_persistent_folder(&atransitions, 1, 0, 0, 1);
1237         vtransitions.remove_all_objects();
1238         create_persistent_folder(&vtransitions, 0, 1, 0, 1);
1239 }
1240
1241 int AWindowGUI::current_folder_number()
1242 {
1243         int result = -1;
1244         for(int i = 0; i < folders.total; i++)
1245         {
1246                 if(!strcasecmp(folders.values[i]->get_text(), mwindow->edl->session->current_folder))
1247                 {
1248                         result = i;
1249                         break;
1250                 }
1251         }
1252         return result;
1253 }
1254
1255 int AWindowGUI::drag_motion()
1256 {
1257         if(get_hidden()) return 0;
1258
1259         int result = 0;
1260         return result;
1261 }
1262
1263 int AWindowGUI::drag_stop()
1264 {
1265         if(get_hidden()) return 0;
1266
1267         return 0;
1268 }
1269
1270 Indexable* AWindowGUI::selected_asset()
1271 {
1272         AssetPicon *picon = (AssetPicon*)asset_list->get_selection(0, 0);
1273         return picon ? picon->indexable : 0;
1274 }
1275
1276 PluginServer* AWindowGUI::selected_plugin()
1277 {
1278         AssetPicon *picon = (AssetPicon*)asset_list->get_selection(0, 0);
1279         return picon ? picon->plugin : 0;
1280 }
1281
1282 AssetPicon* AWindowGUI::selected_folder()
1283 {
1284         AssetPicon *picon = (AssetPicon*)folder_list->get_selection(0, 0);
1285         return picon;
1286 }
1287
1288
1289
1290
1291
1292
1293
1294
1295 AWindowDivider::AWindowDivider(MWindow *mwindow, AWindowGUI *gui, int x, int y, int w, int h)
1296  : BC_SubWindow(x, y, w, h)
1297 {
1298         this->mwindow = mwindow;
1299         this->gui = gui;
1300 }
1301 AWindowDivider::~AWindowDivider()
1302 {
1303 }
1304
1305 int AWindowDivider::button_press_event()
1306 {
1307         if(is_event_win() && cursor_inside())
1308         {
1309                 mwindow->session->current_operation = DRAG_PARTITION;
1310                 return 1;
1311         }
1312         return 0;
1313 }
1314
1315 int AWindowDivider::cursor_motion_event()
1316 {
1317         if(mwindow->session->current_operation == DRAG_PARTITION)
1318         {
1319                 mwindow->session->afolders_w = gui->get_relative_cursor_x();
1320                 gui->reposition_objects();
1321                 gui->flush();
1322         }
1323         return 0;
1324 }
1325
1326 int AWindowDivider::button_release_event()
1327 {
1328         if(mwindow->session->current_operation == DRAG_PARTITION)
1329         {
1330                 mwindow->session->current_operation = NO_OPERATION;
1331                 return 1;
1332         }
1333         return 0;
1334 }
1335
1336
1337
1338
1339
1340
1341 AWindowFolders::AWindowFolders(MWindow *mwindow, AWindowGUI *gui, int x, int y, int w, int h)
1342  : BC_ListBox(x, 
1343                 y, 
1344                 w, 
1345                 h,
1346                 mwindow->edl->session->folderlist_format == FOLDERS_ICONS ? 
1347                         LISTBOX_ICONS : LISTBOX_TEXT, 
1348                 &gui->folders, // Each column has an ArrayList of BC_ListBoxItems.
1349                 0,             // Titles for columns.  Set to 0 for no titles
1350                 0,                // width of each column
1351                 1,                      // Total columns.
1352                 0,                    // Pixel of top of window.
1353                 0,                        // If this listbox is a popup window
1354                 LISTBOX_SINGLE,  // Select one item or multiple items
1355                 ICON_TOP,        // Position of icon relative to text of each item
1356                 1)               // Allow drags
1357 {
1358         this->mwindow = mwindow;
1359         this->gui = gui;
1360         set_drag_scroll(0);
1361 }
1362
1363 AWindowFolders::~AWindowFolders()
1364 {
1365 }
1366         
1367 int AWindowFolders::selection_changed()
1368 {
1369         AssetPicon *picon = (AssetPicon*)get_selection(0, 0);
1370         if(picon)
1371         {
1372                 gui->stop_vicon_drawing();
1373
1374                 if(get_button_down() && get_buttonpress() == 3)
1375                 {
1376                         gui->folderlist_menu->update_titles();
1377                         gui->folderlist_menu->activate_menu();
1378                 }
1379
1380                 strcpy(mwindow->edl->session->current_folder, picon->get_text());
1381 //printf("AWindowFolders::selection_changed 1\n");
1382                 gui->asset_list->draw_background();
1383                 gui->update_assets();
1384
1385                 gui->start_vicon_drawing();
1386         }
1387         return 1;
1388 }
1389
1390 int AWindowFolders::button_press_event()
1391 {
1392         int result = 0;
1393
1394         result = BC_ListBox::button_press_event();
1395
1396         if(!result)
1397         {
1398                 if(get_buttonpress() == 3 && is_event_win() && cursor_inside())
1399                 {
1400                         gui->folderlist_menu->update_titles();
1401                         gui->folderlist_menu->activate_menu();
1402                         result = 1;
1403                 }
1404         }
1405
1406
1407         return result;
1408 }
1409
1410
1411
1412
1413
1414
1415
1416 AWindowAssets::AWindowAssets(MWindow *mwindow, AWindowGUI *gui, int x, int y, int w, int h)
1417  : BC_ListBox(x, 
1418                 y, 
1419                 w, 
1420                 h,
1421                 mwindow->edl->session->assetlist_format == ASSETS_ICONS ? 
1422                         LISTBOX_ICONS : LISTBOX_TEXT,
1423                 &gui->assets,     // Each column has an ArrayList of BC_ListBoxItems.
1424                 gui->asset_titles,             // Titles for columns.  Set to 0 for no titles
1425                 mwindow->edl->session->asset_columns,                // width of each column
1426                 1,                      // Total columns.
1427                 0,                    // Pixel of top of window.
1428                 0,                        // If this listbox is a popup window
1429                 LISTBOX_MULTIPLE,  // Select one item or multiple items
1430                 ICON_TOP,        // Position of icon relative to text of each item
1431                 1)               // Allow drag
1432 {
1433         this->mwindow = mwindow;
1434         this->gui = gui;
1435         set_drag_scroll(0);
1436 }
1437
1438 AWindowAssets::~AWindowAssets()
1439 {
1440 }
1441
1442 int AWindowAssets::button_press_event()
1443 {
1444         int result = 0;
1445
1446         result = BC_ListBox::button_press_event();
1447
1448         if(!result && get_buttonpress() == 3 && is_event_win() && cursor_inside())
1449         {
1450                 BC_ListBox::deactivate_selection();
1451                 gui->assetlist_menu->update_titles();
1452                 gui->assetlist_menu->activate_menu();
1453                 result = 1;
1454         }
1455
1456
1457         return result;
1458 }
1459
1460
1461 int AWindowAssets::handle_event()
1462 {
1463 //printf("AWindowAssets::handle_event 1 %d %d\n", get_buttonpress(), get_selection(0, 0));
1464         if(get_selection(0, 0))
1465         {
1466                 if(!strcasecmp(mwindow->edl->session->current_folder, AEFFECT_FOLDER))
1467                 {
1468                 }
1469                 else
1470                 if(!strcasecmp(mwindow->edl->session->current_folder, VEFFECT_FOLDER))
1471                 {
1472                 }
1473                 else
1474                 if(!strcasecmp(mwindow->edl->session->current_folder, ATRANSITION_FOLDER))
1475                 {
1476                 }
1477                 else
1478                 if(!strcasecmp(mwindow->edl->session->current_folder, VTRANSITION_FOLDER))
1479                 {
1480                 }
1481                 else
1482                 if(mwindow->vwindows.size())
1483                 {
1484 //printf("AWindowAssets::handle_event 2 %d %d\n", get_buttonpress(), get_selection(0, 0));
1485                         mwindow->vwindows.get(DEFAULT_VWINDOW)->gui->lock_window("AWindowAssets::handle_event");
1486                         
1487                         if(((AssetPicon*)get_selection(0, 0))->indexable)
1488                                 mwindow->vwindows.get(DEFAULT_VWINDOW)->change_source(((AssetPicon*)get_selection(0, 0))->indexable);
1489                         else
1490                         if(((AssetPicon*)get_selection(0, 0))->edl)
1491                                 mwindow->vwindows.get(DEFAULT_VWINDOW)->change_source(((AssetPicon*)get_selection(0, 0))->edl);
1492
1493                         mwindow->vwindows.get(DEFAULT_VWINDOW)->gui->unlock_window();
1494                 }
1495                 return 1;
1496         }
1497
1498         return 0;
1499 }
1500
1501 int AWindowAssets::selection_changed()
1502 {
1503 // Show popup window
1504         if(get_button_down() && get_buttonpress() == 3 && get_selection(0, 0))
1505         {
1506                 if(!strcasecmp(mwindow->edl->session->current_folder, AEFFECT_FOLDER) || 
1507                         !strcasecmp(mwindow->edl->session->current_folder, VEFFECT_FOLDER) ||
1508                         !strcasecmp(mwindow->edl->session->current_folder, ATRANSITION_FOLDER) ||
1509                         !strcasecmp(mwindow->edl->session->current_folder, VTRANSITION_FOLDER))
1510                 {
1511                         gui->assetlist_menu->update_titles();
1512                         gui->assetlist_menu->activate_menu();
1513                 }
1514                 else
1515                 {
1516                         if(((AssetPicon*)get_selection(0, 0))->indexable)
1517                                 gui->asset_menu->update();
1518                         else
1519                         if(((AssetPicon*)get_selection(0, 0))->edl)
1520                                 gui->asset_menu->update();
1521
1522
1523
1524                         gui->asset_menu->activate_menu();
1525                 }
1526
1527                 BC_ListBox::deactivate_selection();
1528                 return 1;
1529         }
1530         else if( get_button_down() && get_buttonpress() == 1 && get_selection(0, 0) ) {
1531                 VIcon *vicon = 0;
1532                 if( !gui->vicon_thread->viewing ) {
1533                         AssetPicon *picon = (AssetPicon*)get_selection(0, 0);
1534                         vicon = picon->vicon;
1535                 }
1536                 gui->vicon_thread->set_view_popup(vicon);
1537
1538         }
1539         return 0;
1540 }
1541
1542 void AWindowAssets::draw_background()
1543 {
1544         clear_box(0,0,get_w(),get_h(),get_bg_surface());
1545         set_color(RED);
1546         set_font(LARGEFONT);
1547         draw_text(get_w() - 
1548                         get_text_width(LARGEFONT, mwindow->edl->session->current_folder) - 4, 
1549                 30, 
1550                 mwindow->edl->session->current_folder, 
1551                 -1, 
1552                 get_bg_surface());
1553 }
1554
1555 int AWindowAssets::drag_start_event()
1556 {
1557         int collect_pluginservers = 0;
1558         int collect_assets = 0;
1559
1560         if(BC_ListBox::drag_start_event())
1561         {
1562                 if(!strcasecmp(mwindow->edl->session->current_folder, AEFFECT_FOLDER))
1563                 {
1564                         mwindow->session->current_operation = DRAG_AEFFECT;
1565                         collect_pluginservers = 1;
1566                 }
1567                 else
1568                 if(!strcasecmp(mwindow->edl->session->current_folder, VEFFECT_FOLDER))
1569                 {
1570                         mwindow->session->current_operation = DRAG_VEFFECT;
1571                         collect_pluginservers = 1;
1572                 }
1573                 else
1574                 if(!strcasecmp(mwindow->edl->session->current_folder, ATRANSITION_FOLDER))
1575                 {
1576                         mwindow->session->current_operation = DRAG_ATRANSITION;
1577                         collect_pluginservers = 1;
1578                 }
1579                 else
1580                 if(!strcasecmp(mwindow->edl->session->current_folder, VTRANSITION_FOLDER))
1581                 {
1582                         mwindow->session->current_operation = DRAG_VTRANSITION;
1583                         collect_pluginservers = 1;
1584                 }
1585                 else
1586                 {
1587                         mwindow->session->current_operation = DRAG_ASSET;
1588                         collect_assets = 1;
1589                 }
1590                 
1591                 
1592                 if(collect_pluginservers)
1593                 {
1594                         int i = 0;
1595                         mwindow->session->drag_pluginservers->remove_all();
1596                         while(1)
1597                         {
1598                                 AssetPicon *result = (AssetPicon*)get_selection(0, i++);
1599                                 if(!result) break;
1600                                 
1601                                 mwindow->session->drag_pluginservers->append(result->plugin);
1602                         }
1603                 }
1604                 
1605                 if(collect_assets)
1606                 {
1607                         gui->collect_assets();
1608                 }
1609
1610                 return 1;
1611         }
1612         return 0;
1613 }
1614
1615 int AWindowAssets::drag_motion_event()
1616 {
1617         BC_ListBox::drag_motion_event();
1618         unlock_window();
1619
1620         mwindow->gui->lock_window("AWindowAssets::drag_motion_event");
1621         mwindow->gui->drag_motion();
1622         mwindow->gui->unlock_window();
1623
1624         for(int i = 0; i < mwindow->vwindows.size(); i++)
1625         {
1626                 VWindow *vwindow = mwindow->vwindows.get(i);
1627                 vwindow->gui->lock_window("AWindowAssets::drag_motion_event");
1628                 vwindow->gui->drag_motion();
1629                 vwindow->gui->unlock_window();
1630         }
1631
1632         mwindow->cwindow->gui->lock_window("AWindowAssets::drag_motion_event");
1633         mwindow->cwindow->gui->drag_motion();
1634         mwindow->cwindow->gui->unlock_window();
1635
1636         lock_window("AWindowAssets::drag_motion_event");
1637         return 0;
1638 }
1639
1640 int AWindowAssets::drag_stop_event()
1641 {
1642         int result = 0;
1643
1644         result = gui->drag_stop();
1645
1646         unlock_window();
1647
1648         if(!result)
1649         {
1650                 mwindow->gui->lock_window("AWindowAssets::drag_stop_event");
1651                 result = mwindow->gui->drag_stop();
1652                 mwindow->gui->unlock_window();
1653         }
1654
1655         if(!result) 
1656         {
1657                 for(int i = 0; i < mwindow->vwindows.size(); i++)
1658                 {
1659                         VWindow *vwindow = mwindow->vwindows.get(i);
1660                         vwindow->gui->lock_window("AWindowAssets::drag_stop_event");
1661                         result = vwindow->gui->drag_stop();
1662                         vwindow->gui->unlock_window();
1663                 }
1664         }
1665
1666         if(!result) 
1667         {
1668                 mwindow->cwindow->gui->lock_window("AWindowAssets::drag_stop_event");
1669                 result = mwindow->cwindow->gui->drag_stop();
1670                 mwindow->cwindow->gui->unlock_window();
1671         }
1672
1673         lock_window("AWindowAssets::drag_stop_event");
1674
1675         if(result) get_drag_popup()->set_animation(0);
1676
1677         BC_ListBox::drag_stop_event();
1678         mwindow->session->current_operation = ::NO_OPERATION; // since NO_OPERATION is also defined in listbox, we have to reach for global scope...
1679         return 0;
1680 }
1681
1682 int AWindowAssets::column_resize_event()
1683 {
1684         mwindow->edl->session->asset_columns[0] = get_column_width(0);
1685         mwindow->edl->session->asset_columns[1] = get_column_width(1);
1686         return 1;
1687 }
1688
1689 int AWindowAssets::cursor_enter_event()
1690 {
1691         int ret = BC_ListBox::cursor_enter_event();
1692         gui->start_vicon_drawing();
1693         return ret;
1694 }
1695
1696 int AWindowAssets::cursor_leave_event()
1697 {
1698         gui->stop_vicon_drawing();
1699         return BC_ListBox::cursor_leave_event();
1700 }
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713 AWindowNewFolder::AWindowNewFolder(MWindow *mwindow, AWindowGUI *gui, int x, int y)
1714  : BC_Button(x, y, mwindow->theme->newbin_data)
1715 {
1716         this->mwindow = mwindow;
1717         this->gui = gui;
1718         set_tooltip(_("New bin"));
1719 }
1720
1721 int AWindowNewFolder::handle_event()
1722 {
1723         gui->newfolder_thread->start_new_folder();
1724         return 1;
1725 }
1726
1727 AWindowDeleteFolder::AWindowDeleteFolder(MWindow *mwindow, AWindowGUI *gui, int x, int y)
1728  : BC_Button(x, y, mwindow->theme->deletebin_data)
1729 {
1730         this->mwindow = mwindow;
1731         this->gui = gui;
1732         set_tooltip(_("Delete bin"));
1733 }
1734
1735 int AWindowDeleteFolder::handle_event()
1736 {
1737         if(gui->folder_list->get_selection(0, 0))
1738         {
1739                 BC_ListBoxItem *folder = gui->folder_list->get_selection(0, 0);
1740                 mwindow->delete_folder(folder->get_text());
1741         }
1742         return 1;
1743 }
1744
1745 AWindowRenameFolder::AWindowRenameFolder(MWindow *mwindow, AWindowGUI *gui, int x, int y)
1746  : BC_Button(x, y, mwindow->theme->renamebin_data)
1747 {
1748         this->mwindow = mwindow;
1749         this->gui = gui;
1750         set_tooltip(_("Rename bin"));
1751 }
1752
1753 int AWindowRenameFolder::handle_event()
1754 {
1755         return 1;
1756 }
1757
1758 AWindowDeleteDisk::AWindowDeleteDisk(MWindow *mwindow, AWindowGUI *gui, int x, int y)
1759  : BC_Button(x, y, mwindow->theme->deletedisk_data)
1760 {
1761         this->mwindow = mwindow;
1762         this->gui = gui;
1763         set_tooltip(_("Delete asset from disk"));
1764 }
1765
1766 int AWindowDeleteDisk::handle_event()
1767 {
1768         return 1;
1769 }
1770
1771 AWindowDeleteProject::AWindowDeleteProject(MWindow *mwindow, AWindowGUI *gui, int x, int y)
1772  : BC_Button(x, y, mwindow->theme->deleteproject_data)
1773 {
1774         this->mwindow = mwindow;
1775         this->gui = gui;
1776         set_tooltip(_("Delete asset from project"));
1777 }
1778
1779 int AWindowDeleteProject::handle_event()
1780 {
1781         return 1;
1782 }
1783
1784 AWindowInfo::AWindowInfo(MWindow *mwindow, AWindowGUI *gui, int x, int y)
1785  : BC_Button(x, y, mwindow->theme->infoasset_data)
1786 {
1787         this->mwindow = mwindow;
1788         this->gui = gui;
1789         set_tooltip(_("Edit information on asset"));
1790 }
1791
1792 int AWindowInfo::handle_event()
1793 {
1794         gui->awindow->asset_edit->edit_asset(gui->selected_asset());
1795         return 1;
1796 }
1797
1798 AWindowRedrawIndex::AWindowRedrawIndex(MWindow *mwindow, AWindowGUI *gui, int x, int y)
1799  : BC_Button(x, y, mwindow->theme->redrawindex_data)
1800 {
1801         this->mwindow = mwindow;
1802         this->gui = gui;
1803         set_tooltip(_("Redraw index"));
1804 }
1805
1806 int AWindowRedrawIndex::handle_event()
1807 {
1808         return 1;
1809 }
1810
1811 AWindowPaste::AWindowPaste(MWindow *mwindow, AWindowGUI *gui, int x, int y)
1812  : BC_Button(x, y, mwindow->theme->pasteasset_data)
1813 {
1814         this->mwindow = mwindow;
1815         this->gui = gui;
1816         set_tooltip(_("Paste asset on recordable tracks"));
1817 }
1818
1819 int AWindowPaste::handle_event()
1820 {
1821         return 1;
1822 }
1823
1824 AWindowAppend::AWindowAppend(MWindow *mwindow, AWindowGUI *gui, int x, int y)
1825  : BC_Button(x, y, mwindow->theme->appendasset_data)
1826 {
1827         this->mwindow = mwindow;
1828         this->gui = gui;
1829         set_tooltip(_("Append asset in new tracks"));
1830 }
1831
1832 int AWindowAppend::handle_event()
1833 {
1834         return 1;
1835 }
1836
1837 AWindowView::AWindowView(MWindow *mwindow, AWindowGUI *gui, int x, int y)
1838  : BC_Button(x, y, mwindow->theme->viewasset_data)
1839 {
1840         this->mwindow = mwindow;
1841         this->gui = gui;
1842         set_tooltip(_("View asset"));
1843 }
1844
1845 int AWindowView::handle_event()
1846 {
1847         return 1;
1848 }
1849
1850 AddTools::AddTools(MWindow *mwindow, AWindowGUI *gui, int x, int y, int w)
1851  : BC_MenuBar(x, y, w)
1852 {
1853         this->mwindow = mwindow;
1854         this->gui = gui;
1855 }
1856
1857 void AddTools::create_objects()
1858 {
1859         add_menu(add_plugins = new AddPluginsMenu(mwindow, gui));
1860         add_plugins->create_objects();
1861 }
1862
1863 AddPluginsMenu::AddPluginsMenu(MWindow *mwindow, AWindowGUI *gui)
1864  : BC_Menu("Add Tools")
1865 {
1866         this->mwindow = mwindow;
1867         this->gui = gui;
1868 }
1869
1870 void AddPluginsMenu::create_objects()
1871 {
1872         uint64_t vis = 0;
1873         add_item(new AddPluginItem(this, "ladspa", PLUGIN_LADSPA_ID));
1874         vis |= 1 << PLUGIN_LADSPA_ID;
1875         add_item(new AddPluginItem(this, "ffmpeg", PLUGIN_FFMPEG_ID));
1876         vis |= 1 << PLUGIN_FFMPEG_ID;
1877         for( int i=0; i<MWindow::plugindb->size(); ++i ) {
1878                 PluginServer *plugin = MWindow::plugindb->get(i);
1879                 if( !plugin->audio && !plugin->video ) continue;
1880                 int idx = plugin->dir_idx;
1881                 uint32_t msk = 1 << idx;
1882                 if( (msk & vis) != 0 ) continue;
1883                 vis |= msk;
1884                 char parent[BCTEXTLEN];
1885                 strcpy(parent, plugin->path);
1886                 char *bp = strrchr(parent, '/');
1887                 if( bp ) { *bp = 0;  bp = strrchr(parent, '/'); }
1888                 if( !bp ) bp = parent; else ++bp;
1889                 add_item(new AddPluginItem(this, bp, idx));
1890         }
1891 }
1892
1893 AddPluginItem::AddPluginItem(AddPluginsMenu *menu, char const *text, int idx)
1894  : BC_MenuItem(text)
1895 {
1896         this->menu = menu;
1897         this->idx = idx;
1898         uint64_t msk = (uint64_t)1 << idx, vis = menu->gui->plugin_visibility;
1899         int chk = (msk & vis) ? 1 : 0;
1900         set_checked(chk);
1901 }
1902
1903 int AddPluginItem::handle_event()
1904 {
1905         int chk = get_checked() ^ 1;
1906         set_checked(chk);
1907         uint64_t msk = (uint64_t)1 << idx, vis = menu->gui->plugin_visibility;
1908         menu->gui->plugin_visibility = chk ? vis | msk : vis & ~msk;
1909         menu->gui->update_effects();
1910         menu->gui->update_assets();
1911         menu->gui->save_defaults(menu->mwindow->defaults);
1912         return 1;
1913 }
1914
1915 AVIconDrawing::AVIconDrawing(AWindowGUI *agui, int x, int y, VFrame **images)
1916  : BC_Toggle(x, y, images, agui->vicon_drawing)
1917 {
1918         this->agui = agui;
1919         set_tooltip(_("draw vicons"));
1920 }
1921
1922 void AVIconDrawing::calculate_geometry(AWindowGUI *agui, VFrame **images, int *ww, int *hh)
1923 {
1924         int text_line = -1, toggle_x = -1, toggle_y = -1;
1925         int text_x = -1, text_y = -1, text_w = -1, text_h = -1;
1926         BC_Toggle::calculate_extents(agui, images, 1, 
1927                 &text_line, ww, hh, &toggle_x, &toggle_y,
1928                 &text_x, &text_y, &text_w, &text_h, "", MEDIUMFONT);
1929 }
1930
1931 AVIconDrawing::~AVIconDrawing()
1932 {
1933 }
1934
1935 int AVIconDrawing::handle_event()
1936 {
1937         agui->vicon_drawing = get_value();
1938         if( agui->vicon_drawing )
1939                 agui->start_vicon_drawing();
1940         else
1941                 agui->stop_vicon_drawing();
1942         return 1;
1943 }
1944