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