add vicons
authorGood Guy <[email protected]>
Thu, 3 Dec 2015 17:33:11 +0000 (10:33 -0700)
committerGood Guy <[email protected]>
Thu, 3 Dec 2015 17:33:11 +0000 (10:33 -0700)
15 files changed:
cinelerra-5.0/cinelerra/awindowgui.C
cinelerra-5.0/cinelerra/awindowgui.h
cinelerra-5.0/cinelerra/awindowmenu.C
cinelerra-5.0/cinelerra/dbwindow.C
cinelerra-5.0/cinelerra/dbwindow.h
cinelerra-5.0/cinelerra/dbwindow.inc
cinelerra-5.0/cinelerra/mainsession.C
cinelerra-5.0/guicast/Makefile
cinelerra-5.0/guicast/bcbitmap.C
cinelerra-5.0/guicast/bclistbox.h
cinelerra-5.0/guicast/bcwindowbase.C
cinelerra-5.0/guicast/bcwindowbase.h
cinelerra-5.0/guicast/vicon.C [new file with mode: 0644]
cinelerra-5.0/guicast/vicon.h [new file with mode: 0644]
cinelerra-5.0/guicast/vicon.inc [new file with mode: 0644]

index 81e8760b9794c971be7a3cbcdb52d93f52b504c6..5b8d9f77cc38617f247c3747313d539fb8d2802c 100644 (file)
@@ -51,6 +51,7 @@
 #include "preferences.h"
 #include "theme.h"
 #include "vframe.h"
+#include "vicon.h"
 #include "vwindowgui.h"
 #include "vwindow.h"
 
 #include<unistd.h>
 #include<fcntl.h>
 
+
+
+AssetVIcon::AssetVIcon(AssetPicon *picon, int w, int h, double framerate, int64_t length)
+ : VIcon(w, h, framerate)
+{
+       this->picon = picon;
+       this->length = length;
+}
+
+AssetVIcon::~AssetVIcon()
+{
+}
+
+VFrame *AssetVIcon::frame()
+{
+       if( seq_no >= images.size() ) {
+               MWindow *mwindow = picon->mwindow;
+               Asset *asset = (Asset *)picon->indexable;
+               File *file = mwindow->video_cache->check_out(asset, mwindow->edl, 1);
+               if( !file ) return 0;           
+               VFrame frame(asset->width, asset->height, BC_RGB888);
+               file->set_layer(0);
+               file->set_video_position(images.size(),0);
+               VFrame *vfrm0 = images[0];
+               int ww = vfrm0->get_w(), hh = vfrm0->get_h();
+               int cmdl = vfrm0->get_color_model();
+               while( seq_no >= images.size() ) {
+                       file->read_frame(&frame);
+                       add_image(&frame, ww, hh, cmdl);
+               }
+               mwindow->video_cache->check_in(asset);
+       }
+       return images[seq_no];
+}
+
+int64_t AssetVIcon::next_frame(int n)
+{
+       age += n * period;
+       if( (seq_no+=n) >= length ) seq_no = 0;
+       return seq_no;
+}
+
+int AssetVIcon::get_vx()
+{
+       BC_ListBox *lbox = picon->gui->asset_list;
+       return lbox->get_item_x(picon);
+}
+int AssetVIcon::get_vy()
+{
+       BC_ListBox *lbox = picon->gui->asset_list;
+       return lbox->get_item_y(picon) + lbox->get_title_h();
+}
+
 AssetPicon::AssetPicon(MWindow *mwindow, 
        AWindowGUI *gui, 
        Indexable *indexable)
@@ -112,6 +166,8 @@ AssetPicon::AssetPicon(MWindow *mwindow,
 
 AssetPicon::~AssetPicon()
 {
+       if( vicon )
+               gui->vicon_thread->del_vicon(vicon);
        if(indexable) indexable->remove_user();
        if(edl) edl->remove_user();
        if( icon && !gui->protected_pixmap(icon) ) {
@@ -127,6 +183,7 @@ void AssetPicon::reset()
        edl = 0;
        icon = 0;
        icon_vframe = 0;
+       vicon = 0;
        in_use = 1;
        id = 0;
        persistent = 0;
@@ -197,16 +254,17 @@ void AssetPicon::create_objects()
 //printf("%d %d\n", gui->temp_picon->get_w(), gui->temp_picon->get_h());
                                        icon_vframe = new VFrame(0,
                                                -1, pixmap_w, pixmap_h, BC_RGB888, -1);
-                                       BC_CModels::transfer(
-                                               icon_vframe->get_rows(),
-                                               gui->temp_picon->get_rows(),
-                                               0, 0, 0, 0, 0, 0, 0, 0, 
-                                               gui->temp_picon->get_w(), 
-                                               gui->temp_picon->get_h(),
-                                               0, 0, pixmap_w, pixmap_h,
-                                               BC_RGB888, BC_RGB888,
-                                               0, 0, 0);
-
+                                       icon_vframe->transfer_from(gui->temp_picon);
+// vicon images
+                                       double framerate = asset->get_frame_rate();
+                                       if( !framerate ) framerate = 24;
+                                       int64_t length = framerate * 5;
+                                       int64_t vframes = asset->get_video_frames();
+                                       if( length > vframes ) length = vframes;
+                                       vicon = new AssetVIcon(this, pixmap_w, pixmap_h, framerate, length);
+                                       int ww = gui->vicon_thread->view_w, hh = gui->vicon_thread->view_h;
+                                       vicon->add_image(gui->temp_picon, ww, hh, BC_RGB8);
+                                       gui->vicon_thread->add_vicon(vicon);
                                        if(debug) printf("AssetPicon::create_objects %d\n", __LINE__);
 
                                }
@@ -341,6 +399,8 @@ AWindowGUI::AWindowGUI(MWindow *mwindow, AWindow *awindow)
        folderlist_menu = 0;
        temp_picon = 0;
        remove_plugin = 0;
+       vicon_thread = 0;
+       vicon_drawing = 1;
 }
 
 AWindowGUI::~AWindowGUI()
@@ -353,6 +413,7 @@ AWindowGUI::~AWindowGUI()
        vtransitions.remove_all_objects();
        displayed_assets[1].remove_all_objects();
 
+       delete vicon_thread;
        delete file_icon;
        delete audio_icon;
        delete video_icon;
@@ -472,6 +533,9 @@ SET_TRACE
                mwindow->theme->alist_w, 
                mwindow->theme->alist_h));
 
+       vicon_thread = new VIconThread(asset_list);
+       vicon_thread->start();
+
 SET_TRACE
        add_subwindow(divider = new AWindowDivider(mwindow,
                this,
@@ -484,9 +548,12 @@ SET_TRACE
        divider->set_cursor(HSEPARATE_CURSOR, 0, 0);
 
 SET_TRACE
-       int fx = mwindow->theme->afolders_x, fy = mwindow->theme->afolders_y; 
-       int fw = mwindow->theme->afolders_w, fh = mwindow->theme->afolders_h; 
-       add_subwindow(add_tools = new AddTools(mwindow, this, fx, fy, fw));
+       int fx = mwindow->theme->afolders_x, fy = mwindow->theme->afolders_y;
+       int fw = mwindow->theme->afolders_w, fh = mwindow->theme->afolders_h;
+       VFrame **images = mwindow->theme->get_image_set("playpatch_data");
+       AVIconDrawing::calculate_geometry(this, images, &avicon_w, &avicon_h);
+       add_subwindow(avicon_drawing = new AVIconDrawing(this, fw-avicon_w, fy, images));
+       add_subwindow(add_tools = new AddTools(mwindow, this, fx, fy, fw-avicon_w));
        add_tools->create_objects();
        fy += add_tools->get_h();  fh -= add_tools->get_h();
 SET_TRACE
@@ -532,21 +599,7 @@ int AWindowGUI::resize_event(int w, int h)
 
        mwindow->theme->get_awindow_sizes(this);
        mwindow->theme->draw_awindow_bg(this);
-
-       asset_list->reposition_window(mwindow->theme->alist_x, 
-       mwindow->theme->alist_y, 
-       mwindow->theme->alist_w, 
-       mwindow->theme->alist_h);
-       divider->reposition_window(mwindow->theme->adivider_x,
-               mwindow->theme->adivider_y,
-               mwindow->theme->adivider_w,
-               mwindow->theme->adivider_h);
-
-       int fx = mwindow->theme->afolders_x, fy = mwindow->theme->afolders_y; 
-       int fw = mwindow->theme->afolders_w, fh = mwindow->theme->afolders_h; 
-       add_tools->reposition_window(fx, fy, fw, add_tools->get_h());
-       fy += add_tools->get_h();  fh -= add_tools->get_h();
-       folder_list->reposition_window(fx, fy, fw, fh);
+       reposition_objects();
        
 //     int x = mwindow->theme->abuttons_x;
 //     int y = mwindow->theme->abuttons_y;
@@ -584,30 +637,31 @@ int AWindowGUI::translation_event()
 void AWindowGUI::reposition_objects()
 {
        mwindow->theme->get_awindow_sizes(this);
-       asset_list->reposition_window(mwindow->theme->alist_x, 
-       mwindow->theme->alist_y, 
-       mwindow->theme->alist_w, 
-       mwindow->theme->alist_h);
-       divider->reposition_window(mwindow->theme->adivider_x,
-               mwindow->theme->adivider_y,
-               mwindow->theme->adivider_w,
-               mwindow->theme->adivider_h);
-       folder_list->reposition_window(mwindow->theme->afolders_x, 
-       mwindow->theme->afolders_y, 
-       mwindow->theme->afolders_w, 
-       mwindow->theme->afolders_h);
-       flush();
+       asset_list->reposition_window(
+               mwindow->theme->alist_x, mwindow->theme->alist_y, 
+               mwindow->theme->alist_w, mwindow->theme->alist_h);
+       divider->reposition_window(
+               mwindow->theme->adivider_x, mwindow->theme->adivider_y,
+               mwindow->theme->adivider_w, mwindow->theme->adivider_h);
+       int fx = mwindow->theme->afolders_x, fy = mwindow->theme->afolders_y;
+       int fw = mwindow->theme->afolders_w, fh = mwindow->theme->afolders_h;
+       add_tools->resize_event(fw-avicon_w, add_tools->get_h());
+       avicon_drawing->reposition_window(fw-avicon_w, fy);
+       fy += add_tools->get_h();  fh -= add_tools->get_h();
+       folder_list->reposition_window(fx, fy, fw, fh);
 }
 
 int AWindowGUI::save_defaults(BC_Hash *defaults)
 {
        defaults->update("PLUGIN_VISIBILTY", plugin_visibility);
+       defaults->update("VICON_DRAWING", vicon_drawing);
        return 0;
 }
 
 int AWindowGUI::load_defaults(BC_Hash *defaults)
 {
        plugin_visibility = defaults->get("PLUGIN_VISIBILTY", plugin_visibility);
+       vicon_drawing = defaults->get("VICON_DRAWING", vicon_drawing);
        return 0;
 }
 
@@ -628,6 +682,19 @@ int AWindowGUI::close_event()
        return 1;
 }
 
+void AWindowGUI::start_vicon_drawing()
+{
+       if( !vicon_drawing ) return;
+       if( strcmp(mwindow->edl->session->current_folder, MEDIA_FOLDER) ) return;
+       if( mwindow->edl->session->assetlist_format != ASSETS_ICONS ) return;
+       vicon_thread->start_drawing();
+}
+
+void AWindowGUI::stop_vicon_drawing()
+{
+       vicon_thread->stop_drawing();
+}
+
 AWindowRemovePluginGUI::
 AWindowRemovePluginGUI(AWindow *awindow, AWindowRemovePlugin *thread,
        int x, int y, PluginServer *plugin)
@@ -755,6 +822,7 @@ int AWindowGUI::keypress_event()
 
 void AWindowGUI::update_folder_list()
 {
+       stop_vicon_drawing();
 //printf("AWindowGUI::update_folder_list 1\n");
        for(int i = 0; i < folders.total; i++)
        {
@@ -806,6 +874,7 @@ void AWindowGUI::update_folder_list()
 //for(int i = 0; i < folders.total; i++)
 //     printf("AWindowGUI::update_folder_list %s\n", folders.values[i]->get_text());
 //printf("AWindowGUI::update_folder_list 2\n");
+       start_vicon_drawing();
 }
 
 void AWindowGUI::create_persistent_folder(ArrayList<BC_ListBoxItem*> *output, 
@@ -1220,8 +1289,6 @@ AssetPicon* AWindowGUI::selected_folder()
 
 
 
-
-
 AWindowDivider::AWindowDivider(MWindow *mwindow, AWindowGUI *gui, int x, int y, int w, int h)
  : BC_SubWindow(x, y, w, h)
 {
@@ -1248,6 +1315,7 @@ int AWindowDivider::cursor_motion_event()
        {
                mwindow->session->afolders_w = gui->get_relative_cursor_x();
                gui->reposition_objects();
+               gui->flush();
        }
        return 0;
 }
@@ -1298,6 +1366,8 @@ int AWindowFolders::selection_changed()
        AssetPicon *picon = (AssetPicon*)get_selection(0, 0);
        if(picon)
        {
+               gui->stop_vicon_drawing();
+
                if(get_button_down() && get_buttonpress() == 3)
                {
                        gui->folderlist_menu->update_titles();
@@ -1308,6 +1378,8 @@ int AWindowFolders::selection_changed()
 //printf("AWindowFolders::selection_changed 1\n");
                gui->asset_list->draw_background();
                gui->update_assets();
+
+               gui->start_vicon_drawing();
        }
        return 1;
 }
@@ -1452,6 +1524,10 @@ int AWindowAssets::selection_changed()
                BC_ListBox::deactivate_selection();
                return 1;
        }
+       else if(get_button_down() && get_buttonpress() == 1 && get_selection(0, 0)) {
+               AssetPicon *picon = (AssetPicon*)get_selection(0, 0);
+               gui->vicon_thread->set_view_popup(picon->vicon);
+       }
        return 0;
 }
 
@@ -1602,6 +1678,19 @@ int AWindowAssets::column_resize_event()
        return 1;
 }
 
+int AWindowAssets::cursor_enter_event()
+{
+       int ret = BC_ListBox::cursor_enter_event();
+       gui->start_vicon_drawing();
+       return ret;
+}
+
+int AWindowAssets::cursor_leave_event()
+{
+       gui->stop_vicon_drawing();
+       return BC_ListBox::cursor_leave_event();
+}
+
 
 
 
@@ -1815,3 +1904,33 @@ int AddPluginItem::handle_event()
        return 1;
 }
 
+AVIconDrawing::AVIconDrawing(AWindowGUI *agui, int x, int y, VFrame **images)
+ : BC_Toggle(x, y, images, agui->vicon_drawing)
+{
+       this->agui = agui;
+       set_tooltip(_("draw vicons"));
+}
+
+void AVIconDrawing::calculate_geometry(AWindowGUI *agui, VFrame **images, int *ww, int *hh)
+{
+       int text_line = -1, toggle_x = -1, toggle_y = -1;
+       int text_x = -1, text_y = -1, text_w = -1, text_h = -1;
+       BC_Toggle::calculate_extents(agui, images, 1, 
+               &text_line, ww, hh, &toggle_x, &toggle_y,
+               &text_x, &text_y, &text_w, &text_h, "", MEDIUMFONT);
+}
+
+AVIconDrawing::~AVIconDrawing()
+{
+}
+
+int AVIconDrawing::handle_event()
+{
+       agui->vicon_drawing = get_value();
+       if( agui->vicon_drawing )
+               agui->start_vicon_drawing();
+       else
+               agui->stop_vicon_drawing();
+       return 1;
+}
+
index 8958fbf7dd19698fd7ad84836415f4bd5bf088d2..fc03cbc87d0c14d50a3f9912b97443d673dadab9 100644 (file)
@@ -35,6 +35,7 @@
 #include "mwindow.inc"
 #include "newfolder.inc"
 #include "pluginserver.inc"
+#include "vicon.h"
 
 class AWindowAssets;
 class AWindowFolders;
@@ -52,7 +53,10 @@ class AWindowView;
 class AddTools;
 class AddPluginsMenu;
 class AddPluginItem;
+class AVIconDrawing;
 
+class AssetPicon;
+class AssetVIcon;
 class AWindowGUI;
 
 class AssetPicon : public BC_ListBoxItem
@@ -85,6 +89,21 @@ public:
 
        int persistent;
        PluginServer *plugin;
+       VIcon *vicon;
+};
+
+class AssetVIcon : public VIcon {
+public:
+       AssetPicon *picon;
+       int64_t length;
+
+       VFrame *frame();
+       int64_t next_frame(int n);
+       int get_vx();
+       int get_vy();
+
+       AssetVIcon(AssetPicon *picon, int w, int h, double framerate, int64_t length);
+       ~AssetVIcon();
 };
 
 class AWindowRemovePlugin;
@@ -156,6 +175,8 @@ public:
        bool protected_pixmap(BC_Pixmap *pixmap);
        int save_defaults(BC_Hash *defaults);
        int load_defaults(BC_Hash *defaults);
+       void start_vicon_drawing();
+       void stop_vicon_drawing();
 
        MWindow *mwindow;
        AWindow *awindow;
@@ -203,9 +224,13 @@ public:
        AddTools *add_tools;
 // Temporary for reading picons from files
        VFrame *temp_picon;
+       VIconThread *vicon_thread;
 
        int64_t plugin_visibility;
        AWindowRemovePlugin *remove_plugin;
+
+       AVIconDrawing *avicon_drawing;
+       int avicon_w, avicon_h, vicon_drawing;
 private:
        void update_folder_list();
        void update_asset_list();
@@ -226,6 +251,8 @@ public:
        int drag_stop_event();
        int button_press_event();
        int column_resize_event();
+       int cursor_enter_event();
+       int cursor_leave_event();
 
        MWindow *mwindow;
        AWindowGUI *gui;
@@ -389,4 +416,16 @@ public:
        int idx;
 };
 
+class AVIconDrawing : public BC_Toggle
+{
+public:
+       AWindowGUI *agui;
+
+       int handle_event();
+       static void calculate_geometry(AWindowGUI *agui, VFrame **images, int *ww, int *hh);
+
+       AVIconDrawing(AWindowGUI *agui, int x, int y, VFrame **images);
+       ~AVIconDrawing();
+};
+
 #endif
index e5d7e580164bcaeab4f881fa54095da508b11c51..3a5f6a9d1e77babb72d6c5e6bedfd065d50fcd97 100644 (file)
@@ -79,25 +79,24 @@ void AssetListFormat::update()
 
 int AssetListFormat::handle_event()
 {
-       switch(mwindow->edl->session->assetlist_format)
-       {
-               case ASSETS_TEXT:
-                       mwindow->edl->session->assetlist_format = ASSETS_ICONS;
-                       mwindow->edl->session->folderlist_format = ASSETS_ICONS;
-                       break;
-               case ASSETS_ICONS:
-                       mwindow->edl->session->assetlist_format = ASSETS_TEXT;
-                       mwindow->edl->session->folderlist_format = ASSETS_TEXT;
-                       break;
+       AWindowGUI *agui = mwindow->awindow->gui;
+       agui->stop_vicon_drawing();
+
+       EDLSession *session = mwindow->edl->session;
+       switch(session->assetlist_format) {
+       case ASSETS_TEXT:
+               session->assetlist_format = ASSETS_ICONS;
+               session->folderlist_format = ASSETS_ICONS;
+               break;
+       case ASSETS_ICONS:
+               session->assetlist_format = ASSETS_TEXT;
+               session->folderlist_format = ASSETS_TEXT;
+               break;
        }
 
-       mwindow->awindow->gui->asset_list->update_format(
-               mwindow->edl->session->assetlist_format, 
-               1);
-       mwindow->awindow->gui->folder_list->update_format(
-               mwindow->edl->session->assetlist_format, 
-               1);
-
+       agui->asset_list->update_format(session->assetlist_format, 1);
+       agui->folder_list->update_format(session->folderlist_format, 1);
+       agui->start_vicon_drawing();
        return 1;
 }
 
index f29c137a7bfce59ff37695c18397c07757d52f60..5c876bf1f692e36d3fc2baddb1aa078fa16877a5 100644 (file)
@@ -19,6 +19,16 @@ static inline int max(int a,int b) { return a>b ? a : b; }
 
 #define MAX_SEARCH 100
 
+DbSearchItem::DbSearchItem(const char *text, int color)
+ : BC_ListBoxItem(text, color)
+{
+       vicon = 0;
+}
+
+DbSearchItem::~DbSearchItem()
+{
+}
+
 DbWindow::
 DbWindow(MWindow *mwindow)
  : Thread(1, 0, 0)
@@ -87,7 +97,7 @@ run()
        gui->lock_window("DbWindow::run");
        gui->create_objects();
        gui->search(MAX_SEARCH,"");
-       gui->start_drawing();
+       gui->start_drawing(0);
        gui->unlock_window();
        gui->run_window();
        window_lock->lock("DbWindow::stop");
@@ -239,7 +249,7 @@ DbWindowDeleteItems::~DbWindowDeleteItems()
 int DbWindowDeleteItems::
 handle_event()
 {
-       gui->search_list->stop_view_popup();
+       gui->search_list->set_view_popup(0);
        gui->delete_items();
        return 1;
 }
@@ -266,15 +276,12 @@ handle_event()
 
 DbWindowList::
 DbWindowList(DbWindowGUI *gui, int x, int y, int w, int h)
- : BC_ListBox(x, y, w, h, LISTBOX_TEXT, &gui->search_items[0],
+ : BC_ListBox(x, y, w, h, LISTBOX_TEXT,
+       (ArrayList<BC_ListBoxItem*> *) &gui->search_items[0],
        &gui->search_column_titles[0], &gui->search_column_widths[0],
        sizeof_col, 0, 0, LISTBOX_MULTIPLE)
 {
        this->gui = gui;
-       this->thread = gui->ticon_thread;
-       this->view_popup = 0;
-       this->view_idx = -1;
-       view_ticon = new DbWindowTIcon(gui, &DbWindowTIcon::draw_popup);
        set_sort_column(gui->sort_column);
        set_sort_order(gui->sort_order);
        set_allow_drag_column(1);
@@ -282,8 +289,6 @@ DbWindowList(DbWindowGUI *gui, int x, int y, int w, int h)
 
 DbWindowList::~DbWindowList()
 {
-       delete view_ticon;
-       delete view_popup;
 }
 
 int DbWindowList::
@@ -292,15 +297,10 @@ handle_event()
        return 1;
 }
 
-int DbWindowList::
-stop_view_popup()
+void DbWindowList::
+set_view_popup(DbWindowVIcon *vicon)
 {
-       if( !view_popup ) return 0;
-       BC_Popup *vp = view_popup;
-       view_popup = 0;
-       delete vp;
-       view_idx = -1;
-       return 1;
+       gui->vicon_thread->set_view_popup(vicon);
 }
 
 int DbWindowList::
@@ -308,77 +308,199 @@ keypress_event()
 {
        switch(get_keypress()) {
        case ESC:
-               if( stop_view_popup() ) return 1;
+               set_view_popup(0);
                break;
        case DELETE:
                gui->del_items->handle_event();
                break;
+       default:
+               return 0;
        }
-       return 0;
+       return 1;
 }
 
 int DbWindowList::
 sort_order_event()
 {
-       gui->stop_drawing(1);
+       gui->stop_drawing();
        gui->sort_events(get_sort_column(), get_sort_order());
-       gui->start_drawing(1);
+       gui->start_drawing();
        return 1;
 }
 
 int DbWindowList::
 move_column_event()
 {
-       gui->stop_drawing(1);
+       gui->stop_drawing();
        gui->move_column(get_from_column(), get_to_column());
-       gui->start_drawing(1);
+       gui->start_drawing();
        return 1;
 }
 
+DbWindowVIcon::DbWindowVIcon()
+ : VIcon(SWIDTH, SHEIGHT, 24)
+{
+       lbox = 0;
+       item = 0;
+}
+
+DbWindowVIcon::~DbWindowVIcon()
+{
+}
+
+DbWindowVIconThread::
+DbWindowVIconThread(DbWindowGUI *gui)
+ : VIconThread(gui->search_list, 4*SWIDTH, 4*SHEIGHT)
+{
+       this->gui = gui;
+       list_update = 0;
+}
+
+DbWindowVIconThread::
+~DbWindowVIconThread()
+{
+       t_heap.remove_all();
+       vicons.remove_all_objects();
+}
+
+DbWindowVIcon *DbWindowVIconThread::get_vicon(int i, DbSearchItem *item)
+{
+        while( i >= vicons.size() ) {
+                DbWindowVIcon *vicon = new DbWindowVIcon();
+                vicons.append(vicon);
+        }
+       DbWindowVIcon *vicon = vicons[i];
+        vicon->lbox = gui->search_list;
+        vicon->item = item;
+       item->vicon = vicon;
+        return vicon;
+}
+
+void DbWindowVIconThread::drawing_started()
+{
+       if( !list_update ) return;
+       list_update = 0;
+       gui->update();
+       gui->search_list->update_images();
+       reset_images();
+}
+
+VFrame *DbWindowVIcon::frame()
+{
+       if( seq_no >= images.size() )
+               load_frames(lbox->gui->dwindow->mdb);
+       return images[seq_no];
+}
+
+int64_t DbWindowVIcon::next_frame(int n)
+{
+       age += n * period;
+       if( (seq_no+=n) >= clip_size ) seq_no = 0;
+       return seq_no;
+}
+
+
+void DbWindowVIcon::load_frames(DbWindow::MDb *mdb)
+{
+       if( !mdb->attach_rd() ) {
+               read_frames(mdb);
+               mdb->detach();
+       }
+}
+
+void DbWindowVIcon::read_frames(DbWindow::MDb *mdb)
+{
+       while( seq_no >= images.size() ) {
+               int no = images.size();
+               if( no >= prefix_size ) no += suffix_offset;
+               if( mdb->get_sequences(clip_id, no) ) continue;
+               if( mdb->timeline_sequence_no() != no ) continue;
+               int frame_id = mdb->timeline_frame_id();
+               if( frame_id < 0 ) continue;
+               int swidth = (SWIDTH+1) & ~1, sheight = (SHEIGHT+1) & ~1;
+               VFrame *frame = new VFrame(swidth, sheight, BC_YUV420P);
+               memset(frame->get_y(),0x00,swidth * sheight);
+               memset(frame->get_u(),0x80,swidth/2 * sheight/2);
+               memset(frame->get_v(),0x80,swidth/2 * sheight/2);
+               uint8_t *yp = frame->get_y();  int sw = -1, sh = -1;
+               mdb->get_image(frame_id, yp, sw, sh);
+               images.append(frame);
+       }
+}
+
+int DbWindowVIcon::get_vx()
+{
+        return lbox->get_item_x(item);
+}
+int DbWindowVIcon::get_vy()
+{
+        return lbox->get_item_y(item);
+}
+
+void DbWindowVIcon::
+update_image(DbWindowGUI *gui, int clip_id)
+{
+       DbWindow::MDb *mdb = gui->dwindow->mdb;
+       if( !mdb->attach_rd() ) {
+               if( !mdb->clip_id(clip_id) ) {
+                       this->clip_id = clip_id;
+                       this->clip_size = mdb->clip_size();;
+                       this->prefix_size = mdb->clip_prefix_size();
+                       this->suffix_offset = mdb->clip_frames() - clip_size;
+                       double framerate = mdb->clip_framerate();
+                       this->period = 1000. / (framerate > 0 ? framerate : 24);
+                       gui->vicon_thread->add_vicon(this);
+               }
+               mdb->detach();
+       }
+}
+
+
 int DbWindowList::update_images()
 {
+       DbWindowVIconThread *thread = gui->vicon_thread;
        thread->t_heap.remove_all();
-       if( view_popup ) {
-               view_ticon->age = 0;
-               thread->t_heap.append(view_ticon);
-       }
 
        int i = get_first_visible();
        int k = sizeof_col;
-       while( --k >= 0 && gui->search_columns[k] != col_ticon );
+       while( --k >= 0 && gui->search_columns[k] != col_vicon );
        if( k >= 0 && i >= 0 ) {
                int sz = gui->search_results.size();
                int last = get_last_visible();
                if( last < sz ) sz = last+1;
                for( int n=0; i<sz; ++i, ++n ) {
-                       BC_ListBoxItem *item = gui->search_items[k][i];
-                       int x = item->get_text_x() - get_xposition() + 7;
-                       int y = item->get_text_y() + get_title_h() - get_yposition() + 5;
-                       DbWindowTIcon *ticon = thread->get_ticon(n);
-                       ticon->update_image(gui->search_results[i]->id, x, y);
+                       DbSearchItem *item = gui->search_items[k][i];
+                       DbWindowVIcon *vicon = thread->get_vicon(n, item);
+                       vicon->update_image(gui, gui->search_results[i]->id);
                }
        }
        return 0;
 }
 
-int DbWindowList::draw_images()
+int DbWindowList::
+update()
 {
-       DbWindowTIconThread *thread = gui->ticon_thread;
-       thread->image_update = 1;
-       thread->start_drawing();
+       BC_ListBox::update((ArrayList<BC_ListBoxItem*>*)gui->search_items,
+                       &gui->search_column_titles[0], &gui->search_column_widths[0],
+                       sizeof_col);
        return 0;
 }
 
 int DbWindowList::
-update()
+selection_changed()
 {
-       BC_ListBox::update(gui->search_items, &gui->search_column_titles[0],
-                       &gui->search_column_widths[0], sizeof_col);
+       gui->stop_drawing();
+       set_view_popup(0);
+       int idx = get_selection_number(0, 0);
+       if( idx >= 0 && get_selection_number(0, 1) < 0 ) {
+               DbSearchItem *item = gui->search_items[0][idx];
+               set_view_popup(item->vicon);
+       }
+       gui->start_drawing(0);
        return 0;
 }
 
 
-
 void DbWindowGUI::
 create_objects()
 {
@@ -412,12 +534,13 @@ create_objects()
        cancel_y = get_h() - cancel_h - 10;
        cancel = new DbWindowCancel(this, cancel_x, cancel_y);
        add_subwindow(cancel);
-       ticon_thread = new DbWindowTIconThread(this);
        list_x = x;  list_y = y;
        int list_w = get_w()-10 - list_x;
        int list_h = min(search_y, cancel_y)-10 - list_y;
        search_list = new DbWindowList(this, list_x, list_y, list_w, list_h);
        add_subwindow(search_list);
+       vicon_thread = new DbWindowVIconThread(this);
+       vicon_thread->start();
        search_list->show_window();
        canvas_x = 0;
        canvas_y = search_list->get_title_h();
@@ -453,7 +576,7 @@ DbWindowGUI(DbWindow *dwindow)
        info_text_enable = 1;
        match_case_enable = 1;
 
-       search_columns[col_ticon] = col_ticon;
+       search_columns[col_vicon] = col_vicon;
        search_columns[col_id] = col_id;
        search_columns[col_length] = col_length;
        search_columns[col_source] = col_source;
@@ -461,7 +584,7 @@ DbWindowGUI(DbWindow *dwindow)
        search_columns[col_start_time] = col_start_time;
        search_columns[col_access_time] = col_access_time;
        search_columns[col_access_count] = col_access_count;
-       search_column_titles[col_ticon] = _("ticon");
+       search_column_titles[col_vicon] = _("vicon");
        search_column_titles[col_id] = _("Id");
        search_column_titles[col_length] = _("length");
        search_column_titles[col_source] = _("Source");
@@ -469,7 +592,7 @@ DbWindowGUI(DbWindow *dwindow)
        search_column_titles[col_start_time] = _("Start time");
        search_column_titles[col_access_time] = _("Access time");
        search_column_titles[col_access_count] = _("count");
-       search_column_widths[col_ticon] = 90;
+       search_column_widths[col_vicon] = 90;
        search_column_widths[col_id] = 60;
        search_column_widths[col_length] = 80;
        search_column_widths[col_source] = 50;
@@ -487,14 +610,14 @@ DbWindowGUI::~DbWindowGUI()
 {
        for( int i=0; i<sizeof_col; ++i )
                search_items[i].remove_all_objects();
-       delete ticon_thread;
+       delete vicon_thread;
        delete canvas;
 }
 
 int DbWindowGUI::
 resize_event(int w, int h)
 {
-       stop_drawing(1);
+       stop_drawing();
        int cancel_x = w - BC_CancelButton::calculate_w() - 10;
        int cancel_y = h - BC_CancelButton::calculate_h() - 10;
        cancel->reposition_window(cancel_x, cancel_y);
@@ -515,7 +638,7 @@ resize_event(int w, int h)
 //             if( i != col_title ) wd += search_column_widths[i];
 //     search_column_widths[col_title] = w - wd - 40;
        search_list->reposition_window(list_x, list_y, list_w, list_h);
-       start_drawing(1);
+       start_drawing();
        return 1;
 }
 
@@ -527,19 +650,18 @@ close_event()
 }
 
 int DbWindowGUI::
-stop_drawing(int locked)
+stop_drawing()
 {
-       if( locked ) unlock_window();
-       ticon_thread->stop_drawing();
-       if( locked ) lock_window("DbWindowGUI::");
+       vicon_thread->stop_drawing();
        return 0;
 }
 
 int DbWindowGUI::
 start_drawing(int update)
 {
-       if( update ) ticon_thread->list_update = 1;
-       ticon_thread->start_drawing();
+       if( update )
+               vicon_thread->list_update = 1;
+       vicon_thread->start_drawing();
        return 0;
 }
 
@@ -580,14 +702,14 @@ void DbWindowGUI::search_clips(MediaDb *mdb, int n, const char *text)
 
 void DbWindowGUI::search(int n, const char *text)
 {
-       stop_drawing(1);
+       stop_drawing();
         search_results.remove_all();
        DbWindow::MDb *mdb = dwindow->mdb;
        if( !mdb->attach_rd() ) {
                search_clips(mdb, n, text);
                mdb->detach();
        }
-       start_drawing(1);
+       start_drawing();
 }
 
 int DbWindowGUI::delete_selection(MediaDb *mdb)
@@ -617,7 +739,7 @@ void DbWindowGUI::delete_items()
                delete_selection(mdb);
                mdb->detach();
        }
-       start_drawing(1);
+       start_drawing();
 }
 
 void DbWindowGUI::
@@ -634,7 +756,7 @@ update()
                for( int k=0; k<sizeof_col; ++k ) {
                        const char *cp = 0;  text[0] = 0;
                        switch( search_columns[k] ) {
-                       case col_ticon:
+                       case col_vicon:
                                cp = "";
                                break;
                        case col_id: {
@@ -677,8 +799,8 @@ update()
                                break; }
                        }
                        if( !cp ) continue;
-                       BC_ListBoxItem *item = new BC_ListBoxItem(cp, LTYELLOW);
-                       if( search_columns[k] == col_ticon ) {
+                       DbSearchItem *item = new DbSearchItem(cp, LTYELLOW);
+                       if( search_columns[k] == col_vicon ) {
                                item->set_text_w(SWIDTH+10);
                                item->set_text_h(SHEIGHT+5);
                                item->set_searchable(0);
@@ -750,7 +872,7 @@ void DbWindowGUI::
 sort_events(int column, int order)
 {
        sort_column = column;  sort_order = order;
-       if( search_columns[sort_column] == col_ticon ) return;
+       if( search_columns[sort_column] == col_vicon ) return;
        int n = search_results.size();
        if( !n ) return;
        DbWindowItem **items = &search_results[0];
@@ -813,7 +935,7 @@ move_column(int src, int dst)
        search_column_titles[dst] = src_column_title;
        search_column_widths[dst] = src_column_width;
        int k = sizeof_col;
-       while( --k >= 0 && search_columns[k] != col_ticon );
+       while( --k >= 0 && search_columns[k] != col_vicon );
        if( k >= 0 ) search_list->set_master_column(k,0);
 }
 
@@ -861,264 +983,3 @@ draw_frame(VFrame *frame, int x, int y, int w, int h)
 }
 
 
-DbWindowTIconThread::
-DbWindowTIconThread(DbWindowGUI *gui)
- : Thread(1, 0, 0)
-{
-       this->gui = gui;
-       mdb = gui->dwindow->mdb;
-       mdb->add_user();
-       ticon_lock = new Mutex("DbWindowTIconThread::ticon_lock");
-       draw_lock = new Condition(0, "DbWindowTIconThread::draw_lock", 0);
-       stop_lock = new Condition(0, "DbWindowTIconThread::stop_lock", 0);
-       timer = new Timer();
-       done = 0;  interrupted = 1;
-       list_update = image_update = 0;
-       Thread::start();
-}
-
-DbWindowTIconThread::
-~DbWindowTIconThread()
-{
-       stop_drawing();
-       done = 1;
-       draw_lock->unlock();
-       if( Thread::running() ) {
-               Thread::cancel();
-               Thread::join();
-       }
-       mdb->remove_user();
-       t_heap.remove_all();
-       ticons.remove_all_objects();
-       delete draw_lock;
-       delete stop_lock;
-}
-
-void DbWindowTIconThread::start_drawing()
-{
-        if( interrupted ) {
-               interrupted = 0;
-               draw_lock->unlock();
-       }
-}
-
-void DbWindowTIconThread::stop_drawing()
-{
-        if( !interrupted ) {
-                interrupted = 1;
-                stop_lock->lock("DbWindowTIconThread::stop_draw");
-        }
-}
-
-
-DbWindowTIcon::
-DbWindowTIcon(DbWindowGUI *gui, int (DbWindowTIcon::*draw)() )
-{
-       this->gui = gui;
-       this->draw = draw;
-       age = 0;  x = y = 0;
-        swidth = (SWIDTH+1) & ~1;
-        sheight = (SHEIGHT+1) & ~1;
-       frame = new VFrame(swidth, sheight, BC_YUV420P);
-       memset(frame->get_y(),0,swidth * sheight);
-       memset(frame->get_u(),0x80,swidth/2 * sheight/2);
-       memset(frame->get_v(),0x80,swidth/2 * sheight/2);
-        clip_id = -1;  clip_size = 0;
-        frame_id = frames = -1;
-        seq_no = 0;
-        prefix_size = suffix_offset = -1;
-       framerate = frame_period = 0;
-}
-
-DbWindowTIcon::
-~DbWindowTIcon()
-{
-       delete frame;
-}
-
-
-void DbWindowTIcon::
-update_image(int clip_id, int x, int y)
-{
-       DbWindowTIconThread *thread = gui->ticon_thread;
-       DbWindow::MDb *mdb = gui->dwindow->mdb;
-       if( !mdb->attach_rd() ) {
-               if( !mdb->clip_id(clip_id) ) {
-                       this->clip_id = clip_id;
-                       this->x = x;  this->y = y;
-                       this->clip_size = mdb->clip_size();;
-                       this->prefix_size = mdb->clip_prefix_size();
-                       this->suffix_offset = mdb->clip_frames() - clip_size;
-                       this->framerate = mdb->clip_framerate();;
-                       this->frame_period = 1000. / framerate;
-                       thread->add_ticon(this, 0);
-               }
-               mdb->detach();
-       }
-}
-
-int DbWindowTIcon::
-get_seq_frame()
-{
-       int ret, no = seq_no++;
-       if( seq_no >= clip_size ) seq_no = 0;
-       DbWindow::MDb *mdb = gui->dwindow->mdb;
-       if( !mdb->attach_rd() ) {
-               if( !no ) frame_id = -1;
-               else if( no >= prefix_size ) no += suffix_offset;
-               if( !(ret=mdb->get_sequences(clip_id, no)) ) {
-                       if( mdb->timeline_sequence_no() == no )
-                               frame_id = mdb->timeline_frame_id();
-                       uint8_t *yp = frame->get_y();
-                       if( frame_id >= 0 ) {
-                               int sw, sh;
-                               ret = mdb->get_image(frame_id, yp, sw, sh);
-                       }
-                       else
-                               memset(yp,0,swidth*sheight);
-               }
-               else if( no > 0 ) ret = 0;
-               mdb->detach();
-       }
-       return ret;
-}
-
-int DbWindowTIcon::
-draw_frame()
-{
-       gui->canvas->draw_frame(frame, x, y, swidth, sheight);
-       return 0;
-}
-
-int DbWindowTIcon::
-draw_popup()
-{
-       BC_Popup *vpopup = gui->search_list->view_popup;
-       if( !vpopup ) return 1;
-       vpopup->lock_window("DbWindowTIcon::draw_popup");
-       vpopup->draw_vframe(frame, 0,0,vpopup->get_w(),vpopup->get_h(), 0,0,swidth,sheight, 0);
-       vpopup->flash();
-       vpopup->unlock_window();
-       return 0;
-}
-
-DbWindowTIcon *DbWindowTIconThread::get_ticon(int i)
-{
-       while( i >= ticons.size() ) {
-               DbWindowTIcon *ticon = new DbWindowTIcon(gui, &DbWindowTIcon::draw_frame);
-               ticons.append(ticon);
-       }
-       return ticons[i];
-}
-
-DbWindowTIcon *DbWindowTIconThread::low_ticon()
-{
-       mLock by(ticon_lock);
-       int sz = t_heap.size();
-       if( !sz ) return 0;
-       DbWindowTIcon *ticon = t_heap[0];
-       int i = 0;
-       for( int k; (k=2*(i+1)) < sz; i=k ) {
-               if( t_heap[k]->age > t_heap[k-1]->age ) --k;
-               t_heap[i] = t_heap[k];
-       }
-       DbWindowTIcon *last = t_heap[--sz];
-       t_heap.remove_number(sz);
-       double age = last->age;
-       for( int k; i>0 && age<t_heap[k=(i-1)/2]->age; i=k )
-               t_heap[i] = t_heap[k];
-       t_heap[i] = last;
-       return ticon;
-}
-
-void DbWindowTIconThread::add_ticon(DbWindowTIcon *ticon, double age)
-{
-       mLock by(ticon_lock);
-       ticon->age = age;
-       int i = t_heap.size();  t_heap.append(ticon);
-       for( int k; i>0 && age<t_heap[(k=(i-1)/2)]->age; i=k )
-               t_heap[i] = t_heap[k];
-       t_heap[i] = ticon;
-}
-
-int DbWindowList::
-selection_changed()
-{
-       gui->stop_drawing(1);
-       delete view_popup;
-       view_popup = 0;
-       int idx = get_selection_number(0, 0);
-       if( idx >= 0 && get_selection_number(0, 1) < 0 ) {
-               if( view_idx != idx ) {
-                       view_idx = idx;
-                       BC_ListBoxItem *item = gui->search_items[0][idx];
-                       int x = item->get_text_x() - get_xposition();
-                       int y = item->get_text_y() + get_title_h() - get_yposition();
-                       int w = 4*SWIDTH, h = 4*SHEIGHT;
-                       x += gui->get_x() - 2*SWIDTH;
-                       y += gui->get_y() - 4*SHEIGHT;
-                       view_popup = new BC_Popup(this, x, y, w, h, BLACK);
-                       view_ticon->update_image(gui->search_results[idx]->id, 0, 0);
-               }
-       }
-       else
-               view_idx = -1;
-       gui->start_drawing(0);
-       return 0;
-}
-
-void DbWindowTIconThread::
-run()
-{
-
-       while(!done) {
-               draw_lock->lock("DbWindowTIcon::run");
-               if( done ) break;
-               int do_flash = 0;
-               int64_t last_flash = 0;
-               while( !interrupted && !done ) {
-                       double period = 0;
-                       gui->lock_window("DbWindowTIconThread::run");
-                       if( list_update ) {
-                               list_update = 0;
-                               gui->update();
-                       }
-                       if( image_update ) {
-                               image_update = 0;
-                               gui->search_list->update_images();
-                               timer->update();
-                               do_flash = 0;  last_flash = 0;
-
-                       }
-                       gui->unlock_window();
-                       DbWindowTIcon *ticon = low_ticon();
-                       if( !ticon ) interrupted = 1;
-                       if( interrupted ) break;
-                       int64_t past = timer->get_difference();
-                       int64_t delay = ticon->age - past;
-//printf("delay %6ld  clip %3d  seq %d\n",delay,ticon->clip_id, ticon->seq_no);
-                       if( delay < 10 ) {
-                               if( !ticon->get_seq_frame() ) ticon->draw_image();
-                               period = !ticon->seq_no ? 2000 : ticon->frame_period;
-                               if( past > last_flash + 100 ) do_flash = 1;
-                       }
-                       else
-                               do_flash = 1;
-                       if( do_flash ) {
-                               do_flash = 0;
-                               last_flash = past;
-                               gui->canvas->flash_canvas();
-                       }
-                       add_ticon(ticon, ticon->age + period);
-                       if( delay > 0 )
-                               Timer::delay(delay > 333 ? 333 : delay);
-               }
-               stop_lock->unlock();
-       }
-
-       t_heap.remove_all();
-       ticons.remove_all_objects();
-}
-
-
-
index d4caa842fdfefd516ce90af3ee0e8b20aaa1a045..4fcd2f0ad0bf6bd90ed43ff3393cb39537cc004b 100644 (file)
 #include "guicast.h"
 #include "mediadb.h"
 #include "mwindow.inc"
-
+#include "vicon.h"
 
 enum {
-       col_ticon, col_id, col_length, col_source,
+       col_vicon, col_id, col_length, col_source,
        col_title, col_start_time, col_access_time,
        col_access_count, sizeof_col
 };
 
+class DbSearchItem : public BC_ListBoxItem {
+public:
+       DbWindowVIcon *vicon;
+
+       DbSearchItem(const char *text, int color=-1);
+       ~DbSearchItem();
+};
+
 class DbWindow : public Thread
 {
 public:
@@ -59,7 +67,7 @@ public:
        DbWindowCancel *cancel;
        DbWindowList *search_list;
        DbWindowCanvas *canvas;
-       DbWindowTIconThread *ticon_thread;
+       DbWindowVIconThread *vicon_thread;
 
        int title_text_enable;
        int info_text_enable;
@@ -75,7 +83,7 @@ public:
        const char *search_column_titles[sizeof_col];
        int search_column_widths[sizeof_col];
        int search_columns[sizeof_col];
-       ArrayList<BC_ListBoxItem*> search_items[sizeof_col];
+       ArrayList<DbSearchItem*> search_items[sizeof_col];
        ArrayList<DbWindowItem*> search_results;
 
        void create_objects();
@@ -83,8 +91,8 @@ public:
        void delete_items();
        int close_event();
        int resize_event(int x, int y);
-       int stop_drawing(int locked=0);
-       int start_drawing(int update=0);
+       int stop_drawing();
+       int start_drawing(int update=1);
        void update();
        static int cmpr_id_dn(const void *a, const void *b);
        static int cmpr_id_up(const void *a, const void *b);
@@ -199,20 +207,15 @@ class DbWindowList : public BC_ListBox
 {
 public:
        DbWindowGUI *gui;
-       DbWindowTIconThread *thread;
-       BC_Popup *view_popup;
-       DbWindowTIcon *view_ticon;
-       int view_idx;
 
        int handle_event();
        int sort_order_event();
        int keypress_event();
        int move_column_event();
        int selection_changed();
-       int stop_view_popup();
+       void set_view_popup(DbWindowVIcon *vicon);
 
        int update_images();
-       int draw_images();
        int update();
 
        DbWindowList(DbWindowGUI *gui, int x, int y, int w, int h);
@@ -235,55 +238,41 @@ public:
        void set_fullscreen(int value) { is_fullscreen = value; }
 };
 
-class DbWindowTIcon
+class DbWindowVIcon : public VIcon
 {
 public:
-       DbWindowGUI *gui;
-       VFrame *frame;
-       double age;
-        int x, y, swidth, sheight;
+       DbWindowList *lbox;
+       DbSearchItem *item;
+
        int clip_id, clip_size;
-        int frame_id, frames, seq_no;
+        int frame_id, frames;
         int prefix_size, suffix_offset;
-        double framerate, frame_period;
 
-       void update_image(int clip_id, int x, int y);
-       int get_seq_frame();
-       int draw_frame();
-       int draw_popup();
-       int (DbWindowTIcon::*draw)();
-       int draw_image() { return (this->*draw)(); }
+       VFrame *frame();
+       int64_t next_frame(int n);
+       void load_frames(DbWindow::MDb *mdb);
+       void read_frames(DbWindow::MDb *mdb);
 
+       int get_vx();
+       int get_vy();
 
-       DbWindowTIcon(DbWindowGUI *gui, int (DbWindowTIcon::*draw)());
-       ~DbWindowTIcon();
+       void update_image(DbWindowGUI *gui, int clip_id);
+       DbWindowVIcon();
+       ~DbWindowVIcon();
 };
 
-class DbWindowTIconThread : public Thread
-{
+class DbWindowVIconThread : public VIconThread {
 public:
-       int done, interrupted;
-       int list_update, image_update;
        DbWindowGUI *gui;
-       DbWindow::MDb *mdb;
-       Mutex *ticon_lock;
-       Timer *timer;
-       Condition *draw_lock;
-       Condition *stop_lock;
-
-       ArrayList<DbWindowTIcon *>ticons;
-       ArrayList<DbWindowTIcon *>t_heap;
-       DbWindowTIcon *get_ticon(int i);
-       DbWindowTIcon *low_ticon();
-       void add_ticon(DbWindowTIcon *ticon, double age);
-       void run();
-       void start_drawing();
-       void stop_drawing();
+       int list_update;
 
-       DbWindowTIconThread(DbWindowGUI *gui);
-       ~DbWindowTIconThread();
-};
+       ArrayList <DbWindowVIcon *> vicons;
+       DbWindowVIcon *get_vicon(int i, DbSearchItem *item);
+       void drawing_started();
 
+       DbWindowVIconThread(DbWindowGUI *gui);
+       ~DbWindowVIconThread();
+};
 
 class DbWindowItem
 {
index 3aebcd546546fe91fd7366527f0cbb4d0653cff7..5134d3c11b3ba9a059b7b47e626fd22d681b6fa7 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef _DBWINDOW_INC_
 #define _DBWINDOW_INC_
 
+class DbSearchItem;
 class DbWindow;
 class DbWindowGUI;
 class DbWindowInfoText;
@@ -12,8 +13,8 @@ class DbWindowDeleteItems;
 class DbWindowCancel;
 class DbWindowList;
 class DbWindowCanvas;
-class DbWindowTIcon;
-class DbWindowTIconThread;
+class DbWindowVIcon;
+class DbWindowVIconThread;
 class DbWindowItem;
 class DbWindowScan;
 
index 44fda39382ff0c49b86ca511ad4b1a9277925370..287c973f3ef7bd8e9c633045582d6210753350dc 100644 (file)
@@ -387,7 +387,7 @@ int MainSession::load_defaults(BC_Hash *defaults)
 //printf("MainSession::load_defaults 1\n");
 
 // Other windows
-       afolders_w = defaults->get("ABINS_W", 100);
+       afolders_w = defaults->get("ABINS_W", 140);
        rwindow_x = defaults->get("RWINDOW_X", rwindow_x);
        rwindow_y = defaults->get("RWINDOW_Y", rwindow_y);
        rwindow_w = defaults->get("RWINDOW_W", rwindow_w);
index 475370f7a4b337a94e833701a602ca6038ae888a..0167de27367ed60e1bd812c76f6d8b9cd38fdcc6 100644 (file)
@@ -84,6 +84,7 @@ OBJS = \
        $(OBJDIR)/units.o \
        $(OBJDIR)/vframe.o \
        $(OBJDIR)/vframe3d.o \
+       $(OBJDIR)/vicon.o \
        $(OBJDIR)/workarounds.o
 
 OUTPUT = $(OBJDIR)/libguicast.a
index c508de5c00edcbffa56113a375a533408689e5c9..dedb03b49ec6f56a01362619ab4df399947edf28 100644 (file)
@@ -219,7 +219,9 @@ BC_XvImage::BC_XvImage(BC_Bitmap *bitmap, int index,
        int id = BC_CModels::bc_to_x(color_model);
        xv_image = XvCreateImage(display, bitmap->xv_portid, id, 0, w, h);
        dataSize = xv_image->data_size;
-       data = new unsigned char[dataSize + 8];
+       long data_sz = dataSize + 8;
+       data = new unsigned char[data_sz];
+       memset(data, 0, data_sz);
        xv_image->data = (char *) data;
        w = xv_image->width;
        h = xv_image->height;
@@ -250,7 +252,9 @@ BC_XImage::BC_XImage(BC_Bitmap *bitmap, int index,
        bytesPerLine = ximage->bytes_per_line;
        bitsPerPixel = ximage->bits_per_pixel;
        dataSize = h * bytesPerLine;
-       data = new unsigned char[dataSize + 8];
+       long data_sz = dataSize + 8;
+       data = new unsigned char[data_sz];
+       memset(data, 0, data_sz);
        ximage->data = (char*) data;
        row_data = new unsigned char*[h];
        for( int i=0; i<h; ++i )
@@ -419,7 +423,6 @@ update_buffers(int count, int lock_avail)
                        BC_BitmapImage *buffer = buffers[i];
                        if( buffer == active_bfr ) active_bfr = 0;
                        if( buffer->is_avail() ) {
-                               avail.remove_pointer(buffer);
                                delete buffer;
                        }
                        else {
@@ -429,10 +432,10 @@ update_buffers(int count, int lock_avail)
                        ++i;
                }
        }
-       if( lock_avail ) avail_lock->unlock();
        delete [] buffers;
        buffers = new_buffers;
        buffer_count = count;
+       if( lock_avail ) avail_lock->unlock();
        //top_level->unlock_window();
 }
 
index e270c13c2082c6e765fc47856a755f0e733a4a75..8100adfdd25c1a6fd3e513d744af680a917c906c 100644 (file)
@@ -318,22 +318,14 @@ public:
                int indent /* = 0 */,
                int master_column);
 
-
-
-
+       int get_item_x(BC_ListBoxItem *item);
+       int get_item_y(BC_ListBoxItem *item);
+       int get_item_w(BC_ListBoxItem *item);
+       int get_item_h(BC_ListBoxItem *item);
 
 // Draw the list items
        int draw_items(int flash, int bg_draw=0);
 
-
-
-
-
-
-
-
-
-
 private:
        void delete_columns();
        void set_columns(const char **column_titles,
@@ -418,10 +410,6 @@ private:
        int get_text_w(BC_ListBoxItem *item);
        int get_text_h(BC_ListBoxItem *item);
        int get_baseline(BC_ListBoxItem *item);
-       int get_item_x(BC_ListBoxItem *item);
-       int get_item_y(BC_ListBoxItem *item);
-       int get_item_w(BC_ListBoxItem *item);
-       int get_item_h(BC_ListBoxItem *item);
        int get_item_highlight(ArrayList<BC_ListBoxItem*> *data, int column, int item);
        int get_item_color(ArrayList<BC_ListBoxItem*> *data, int column, int item);
        int get_icon_mask(BC_ListBoxItem *item, int &x, int &y, int &w, int &h);
index 59963d6d4b5dd31ea511a6a287fa9b31ab4d4044..602934b1967aad840bfde338492e0812c1546273 100644 (file)
@@ -4199,6 +4199,15 @@ void BC_WindowBase::translate_coordinates(Window src_w,
        }
 }
 
+void BC_WindowBase::get_root_coordinates(int x, int y, int *abs_x, int *abs_y)
+{
+       translate_coordinates(win, top_level->rootwin, x, y, abs_x, abs_y);
+}
+
+void BC_WindowBase::get_win_coordinates(int abs_x, int abs_y, int *x, int *y)
+{
+       translate_coordinates(top_level->rootwin, win, abs_x, abs_y, x, y);
+}
 
 
 
index f2314753599f6a11beb3d63cd40cc9d76ac39b5f..af271e49bf82103c6391ecfafe376eae8c140419 100644 (file)
@@ -287,6 +287,8 @@ public:
        int get_abs_cursor_y(int lock_window);
        int get_relative_cursor_x();
        int get_relative_cursor_y();
+       void get_root_coordinates(int x, int y, int *abs_x, int *abs_y);
+       void get_win_coordinates(int abs_x, int abs_y, int *x, int *y);
 // Return 1 if cursor is over an unobscured part of this window.
 // An argument is provided for excluding a drag popup
        int get_cursor_over_window();
@@ -606,12 +608,8 @@ private:
        int find_prev_textbox(BC_WindowBase **last_textbox, BC_WindowBase **prev_textbox, int &result);
 
 
-       void translate_coordinates(Window src_w,
-               Window dest_w,
-               int src_x,
-               int src_y,
-               int *dest_x_return,
-               int *dest_y_return);
+       void translate_coordinates(Window src_w, Window dest_w,
+               int src_x, int src_y, int *dest_x_return, int *dest_y_return);
 
 // Top level window above this window
        BC_WindowBase* top_level;
diff --git a/cinelerra-5.0/guicast/vicon.C b/cinelerra-5.0/guicast/vicon.C
new file mode 100644 (file)
index 0000000..05f56df
--- /dev/null
@@ -0,0 +1,319 @@
+#include "vicon.h"
+
+#include "bctimer.h"
+#include "bcwindow.h"
+#include "colors.h"
+#include "keys.h"
+#include "mutex.h"
+#include "condition.h"
+
+VIcon::
+VIcon(int vw, int vh, double rate)
+{
+       this->vw = vw;
+       this->vh = vh;
+       this->period = 1000./rate;
+       this->age = 0;
+        this->seq_no = 0;
+       this->in_use = 1;
+}
+
+VIcon::
+~VIcon()
+{
+       clear_images();
+}
+
+void VIcon::
+add_image(VFrame *frm, int ww, int hh, int vcmdl)
+{
+       VFrame *img = new VFrame(ww, hh, vcmdl);
+       img->transfer_from(frm);
+       images.append(img);
+}
+
+void VIcon::
+draw_vframe(BC_WindowBase *wdw, int x, int y)
+{
+       wdw->draw_vframe(frame(), x,y, vw,vh);
+}
+
+VIcon *VIconThread::low_vicon()
+{
+       if( !t_heap.size() ) return 0;
+       VIcon *vip = t_heap[0];
+       remove_vicon(0);
+       return vip;
+}
+
+void VIconThread::remove_vicon(int i)
+{
+       int sz = t_heap.size();
+       for( int k; (k=2*(i+1)) < sz; i=k ) {
+               if( t_heap[k]->age > t_heap[k-1]->age ) --k;
+               t_heap[i] = t_heap[k];
+       }
+       VIcon *last = t_heap[--sz];
+       t_heap.remove_number(sz);
+       double age = last->age;
+       for( int k; i>0 && age<t_heap[k=(i-1)/2]->age; i=k )
+               t_heap[i] = t_heap[k];
+       t_heap[i] = last;
+}
+
+
+VIconThread::
+VIconThread(BC_WindowBase *wdw, int vw, int vh)
+ : Thread(1, 0, 0)
+{
+       this->wdw = wdw;
+       this->view_win = 0;  this->vicon = 0;
+       this->cur_view = 0;  this->new_view = 0;
+       this->view_w = vw;   this->view_h = vh;
+       this->viewing = 0;   this->draw_flash = 0;
+       draw_lock = new Condition(0, "VIconThread::draw_lock", 1);
+       timer = new Timer();
+       done = 0;
+       interrupted = 1;
+}
+
+VIconThread::
+~VIconThread()
+{
+       stop_drawing();
+       done = 1;
+       draw_lock->unlock();
+       if( Thread::running() ) {
+               Thread::cancel();
+               Thread::join();
+       }
+       t_heap.remove_all_objects();
+       delete timer;
+       delete draw_lock;
+}
+
+void VIconThread::
+start_drawing()
+{
+       wdw->lock_window("VIconThread::stop_drawing");
+        if( interrupted )
+               draw_lock->unlock();
+       wdw->unlock_window();
+}
+
+void VIconThread::
+stop_drawing()
+{
+       wdw->lock_window("VIconThread::stop_drawing");
+       interrupted = 1;
+       wdw->unlock_window();
+}
+
+int VIconThread::keypress_event(int key)
+{
+       if( !cur_view ) return 0;
+       if( key != ESC ) return 0;
+       set_view_popup(0);
+       return 1;
+}
+
+bool VIconThread::
+visible(VIcon *vicon, int x, int y)
+{
+       int y0 = 0;
+       int my = y + vicon->vh;
+       if( my <= y0 ) return false;
+       int y1 = y0 + wdw->get_h();
+       if( y >= y1 ) return false;
+       int x0 = 0;
+       int mx = x + vicon->vw;
+       if( mx <= x0 ) return false;
+       int x1 = x0 + wdw->get_w();
+       if( x >= x1 ) return false;
+       return true;
+}
+
+int ViewPopup::keypress_event()
+{
+       int key = get_keypress();
+       return vt->keypress_event(key);
+}
+int ViewPopup::button_press_event()
+{
+       return vt->keypress_event(ESC);
+}
+
+ViewPopup::ViewPopup(VIconThread *vt, VFrame *frame, int x, int y, int w, int h)
+ : BC_Popup(vt->wdw, x, y, w, h, BLACK)
+{
+       this->vt = vt;
+}
+
+ViewPopup::~ViewPopup()
+{
+       vt->wdw->set_active_subwindow(0);
+}
+
+void ViewPopup::draw_vframe(VFrame *frame)
+{
+       BC_WindowBase::draw_vframe(frame, 0,0, get_w(),get_h());
+}
+
+ViewPopup *VIconThread::new_view_window(VFrame *frame)
+{
+       int wx = viewing->get_vx() - view_w, rx = 0;
+       int wy = viewing->get_vy() - view_h, ry = 0;
+       wdw->get_root_coordinates(wx, wy, &rx, &ry);
+       ViewPopup *vwin = new ViewPopup(this, frame, rx, ry, view_w, view_h);
+       wdw->set_active_subwindow(vwin);
+       return vwin;
+}
+
+void VIconThread::
+reset_images()
+{
+       for( int i=t_heap.size(); --i>=0; ) t_heap[i]->age = 0;
+       timer->update();
+       img_dirty = win_dirty = 0;
+       draw_flash = 0;
+}
+
+void VIconThread::add_vicon(VIcon *vip, double age)
+{
+       vip->age = age;
+       int i = t_heap.size();  t_heap.append(vip);
+       for( int k; i>0 && age<t_heap[(k=(i-1)/2)]->age; i=k )
+               t_heap[i] = t_heap[k];
+       t_heap[i] = vip;
+}
+
+int VIconThread::del_vicon(VIcon *&vicon)
+{
+       int i = t_heap.size();
+       while( --i >= 0 && t_heap[i] != vicon );
+       if( i < 0 ) return 0;
+       remove_vicon(i);
+       delete vicon;  vicon = 0;
+       return 1;
+}
+
+void VIconThread::set_view_popup(VIcon *vicon)
+{
+       this->vicon = vicon;
+}
+
+int VIconThread::
+update_view()
+{
+       if( viewing == vicon && cur_view == new_view ) return 0;
+       wdw->lock_window("VIconThread::update_view");;
+       if( viewing && !vicon ) new_view = 0;
+       if( !viewing && vicon ) new_view = 1;
+       if( cur_view != new_view && !new_view ) vicon = 0;
+       viewing = vicon;  cur_view = new_view;
+       delete view_win;  view_win = 0;
+       if( cur_view ) {
+               VFrame *frame = viewing->frame();
+               view_win = new_view_window(frame);
+               view_win->show_window();
+        }
+       wdw->unlock_window();
+       return 1;
+}
+
+
+void VIconThread::
+draw_images()
+{
+       for( int i=0; i<t_heap.size(); ++i )
+               draw(t_heap[i]);
+}
+
+void VIconThread::
+flash()
+{
+       if( !img_dirty && !win_dirty ) return;
+       if( img_dirty ) wdw->flash();
+       if( win_dirty ) view_win->flash();
+       win_dirty = img_dirty = 0;
+}
+
+int VIconThread::
+draw(VIcon *vicon)
+{
+       int x = vicon->get_vx(), y = vicon->get_vy();
+       int draw_img = visible(vicon, x, y);
+       int draw_win = view_win && viewing == vicon ? 1 : 0;
+       if( !draw_img && !draw_win ) return 0;
+       if( draw_img ) {
+               vicon->draw_vframe(wdw, x, y);
+               img_dirty = 1;
+       }
+       if( draw_win ) {
+               view_win->draw_vframe(vicon->frame());
+               win_dirty = 1;
+       }
+       return 1;
+}
+
+void VIconThread::
+run()
+{
+       while(!done) {
+               draw_lock->lock("VIconThread::run 0");
+               if( done ) break;;
+               wdw->lock_window("BC_WindowBase::run 1");
+               reset_images();
+               interrupted = 0;
+               drawing_started();
+               while( !interrupted ) {
+                       if( viewing != vicon || cur_view != new_view )
+                               update_view();
+                       VIcon *next = low_vicon();
+                       if( !next ) break;
+                       if( !next->frame() ) {
+                               delete next;  next = 0;
+                               continue;
+                       }
+                       int64_t next_time = next->age;
+                       int64_t this_time = timer->get_difference();
+                       int64_t msec = this_time - next_time;
+                       int count = msec / next->period;
+                       int nfrms = count > 0 ? count : 1;
+                       if( !next->next_frame(nfrms) )
+                               next->age = this_time + 1000;
+                       add_vicon(next, next->age);
+                       if( msec < 1000 && draw(next) && !draw_flash )
+                               draw_flash = next_time;
+                       wdw->unlock_window();
+                       msec = next_time - timer->get_difference();
+                       if( msec < 1 ) msec = 1;
+                       while( msec > 0 && !interrupted ) {
+                               int ms = msec > 100 ? 100 : msec;
+                               Timer::delay(ms);  msec -= ms;
+                       }
+                       wdw->lock_window("BC_WindowBase::run 2");
+                       if( interrupted ) break;
+                       if( draw_flash ) {
+                               int64_t msec = timer->get_difference() - draw_flash;
+                               if( msec < 1000 ) flash();
+                               draw_flash = 0;
+                       }
+               }
+               drawing_stopped();
+               interrupted = -1;
+               wdw->unlock_window();
+       }
+}
+
+void VIcon::dump(const char *dir)
+{
+       mkdir(dir,0777);
+       for( int i=0; i<images.size(); ++i ) {
+               char fn[1024];  sprintf(fn,"%s/img%05d.png",dir,i);
+               printf("\r%s",fn);
+               images[i]->write_png(fn);
+       }
+       printf("\n");
+}
+
diff --git a/cinelerra-5.0/guicast/vicon.h b/cinelerra-5.0/guicast/vicon.h
new file mode 100644 (file)
index 0000000..fb31528
--- /dev/null
@@ -0,0 +1,91 @@
+#ifndef __VICON_H__
+#define __VICON_H__
+
+#include "arraylist.h"
+#include "bcpopup.h"
+#include "bcwindowbase.h"
+#include "thread.h"
+#include "vicon.inc"
+#include "vframe.h"
+
+class ViewPopup : public BC_Popup {
+public:
+       VIconThread *vt;
+       int keypress_event();
+       int button_press_event();
+       void draw_vframe(VFrame *frame);
+
+       ViewPopup(VIconThread *vt, VFrame *frame, int x, int y, int w, int h);
+       ~ViewPopup();
+};
+
+class VIcon
+{
+public:
+       int vw, vh, vcmdl, in_use;
+       ArrayList<VFrame *> images;
+        int64_t seq_no;
+        double age, period;
+
+       double frame_rate() { return 1000/period; }
+       void frame_rate(double r) { period = 1000/r; }
+       int64_t vframes() { return images.size(); }
+       void clear_images() { images.remove_all_objects(); }
+
+       virtual VFrame *frame() { return images[seq_no]; }
+       virtual int64_t next_frame(int n) {
+               age += n * period;
+               if( (seq_no+=n) >= images.size() ) seq_no = 0;
+               return seq_no;
+       }
+       virtual int get_vx() { return 0; }
+       virtual int get_vy() { return 0; }
+
+       void add_image(VFrame *frm, int ww, int hh, int vcmdl);
+       void draw_vframe(BC_WindowBase *wdw, int x, int y);
+       void dump(const char *dir);
+
+       VIcon(int vw=VICON_WIDTH, int vh=VICON_HEIGHT, double rate=24);
+       virtual ~VIcon();
+};
+
+class VIconThread : public Thread
+{
+public:
+       int done, interrupted;
+       BC_WindowBase *wdw;
+       Timer *timer;
+       Condition *draw_lock;
+       ViewPopup *view_win;
+       VIcon *viewing, *vicon;
+       int view_w, view_h;
+       int cur_view, new_view;
+       int img_dirty, win_dirty;
+       int64_t draw_flash;
+
+       ArrayList<VIcon *>t_heap;
+       VIcon *low_vicon();
+       void add_vicon(VIcon *vicon, double age=0);
+       int del_vicon(VIcon *&vicon);
+       void run();
+       void flash();
+       int draw(VIcon *vicon);
+       int update_view();
+       void draw_images();
+       void start_drawing();
+       void stop_drawing();
+       void reset_images();
+       void remove_vicon(int i);
+       int keypress_event(int key);
+       void set_view_popup(VIcon *vicon);
+
+       ViewPopup *new_view_window(VFrame *frame);
+       virtual bool visible(VIcon *vicon, int x, int y);
+       virtual void drawing_started() {}
+       virtual void drawing_stopped() {}
+
+       VIconThread(BC_WindowBase *wdw, int vw=4*VICON_WIDTH, int vh=4*VICON_HEIGHT);
+       ~VIconThread();
+};
+
+#endif
diff --git a/cinelerra-5.0/guicast/vicon.inc b/cinelerra-5.0/guicast/vicon.inc
new file mode 100644 (file)
index 0000000..77b9ca8
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef __VICON_INC__
+#define __VICON_INC__
+
+#define VICON_WIDTH 80
+#define VICON_HEIGHT 45
+
+class ViewWindow;
+class VIconThread;
+class VIcon;
+
+#endif