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