From 39d4e483b6daeb2d0eb2a6eec5b2e96552e22c5b Mon Sep 17 00:00:00 2001 From: Good Guy Date: Thu, 3 Dec 2015 10:33:11 -0700 Subject: [PATCH] add vicons --- cinelerra-5.0/cinelerra/awindowgui.C | 205 ++++++++--- cinelerra-5.0/cinelerra/awindowgui.h | 39 ++ cinelerra-5.0/cinelerra/awindowmenu.C | 33 +- cinelerra-5.0/cinelerra/dbwindow.C | 507 ++++++++++---------------- cinelerra-5.0/cinelerra/dbwindow.h | 85 ++--- cinelerra-5.0/cinelerra/dbwindow.inc | 5 +- cinelerra-5.0/cinelerra/mainsession.C | 2 +- cinelerra-5.0/guicast/Makefile | 1 + cinelerra-5.0/guicast/bcbitmap.C | 11 +- cinelerra-5.0/guicast/bclistbox.h | 20 +- cinelerra-5.0/guicast/bcwindowbase.C | 9 + cinelerra-5.0/guicast/bcwindowbase.h | 10 +- cinelerra-5.0/guicast/vicon.C | 319 ++++++++++++++++ cinelerra-5.0/guicast/vicon.h | 91 +++++ cinelerra-5.0/guicast/vicon.inc | 11 + 15 files changed, 888 insertions(+), 460 deletions(-) create mode 100644 cinelerra-5.0/guicast/vicon.C create mode 100644 cinelerra-5.0/guicast/vicon.h create mode 100644 cinelerra-5.0/guicast/vicon.inc diff --git a/cinelerra-5.0/cinelerra/awindowgui.C b/cinelerra-5.0/cinelerra/awindowgui.C index 81e8760b..5b8d9f77 100644 --- a/cinelerra-5.0/cinelerra/awindowgui.C +++ b/cinelerra-5.0/cinelerra/awindowgui.C @@ -51,6 +51,7 @@ #include "preferences.h" #include "theme.h" #include "vframe.h" +#include "vicon.h" #include "vwindowgui.h" #include "vwindow.h" @@ -62,6 +63,59 @@ #include #include + + +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 *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; +} + diff --git a/cinelerra-5.0/cinelerra/awindowgui.h b/cinelerra-5.0/cinelerra/awindowgui.h index 8958fbf7..fc03cbc8 100644 --- a/cinelerra-5.0/cinelerra/awindowgui.h +++ b/cinelerra-5.0/cinelerra/awindowgui.h @@ -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 diff --git a/cinelerra-5.0/cinelerra/awindowmenu.C b/cinelerra-5.0/cinelerra/awindowmenu.C index e5d7e580..3a5f6a9d 100644 --- a/cinelerra-5.0/cinelerra/awindowmenu.C +++ b/cinelerra-5.0/cinelerra/awindowmenu.C @@ -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; } diff --git a/cinelerra-5.0/cinelerra/dbwindow.C b/cinelerra-5.0/cinelerra/dbwindow.C index f29c137a..5c876bf1 100644 --- a/cinelerra-5.0/cinelerra/dbwindow.C +++ b/cinelerra-5.0/cinelerra/dbwindow.C @@ -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 *) &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; isearch_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*)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; ireposition_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; kset_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 && ageage; 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 && ageage; 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(); -} - - - diff --git a/cinelerra-5.0/cinelerra/dbwindow.h b/cinelerra-5.0/cinelerra/dbwindow.h index d4caa842..4fcd2f0a 100644 --- a/cinelerra-5.0/cinelerra/dbwindow.h +++ b/cinelerra-5.0/cinelerra/dbwindow.h @@ -11,14 +11,22 @@ #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 search_items[sizeof_col]; + ArrayList search_items[sizeof_col]; ArrayList 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; - - ArrayListticons; - ArrayListt_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 vicons; + DbWindowVIcon *get_vicon(int i, DbSearchItem *item); + void drawing_started(); + DbWindowVIconThread(DbWindowGUI *gui); + ~DbWindowVIconThread(); +}; class DbWindowItem { diff --git a/cinelerra-5.0/cinelerra/dbwindow.inc b/cinelerra-5.0/cinelerra/dbwindow.inc index 3aebcd54..5134d3c1 100644 --- a/cinelerra-5.0/cinelerra/dbwindow.inc +++ b/cinelerra-5.0/cinelerra/dbwindow.inc @@ -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; diff --git a/cinelerra-5.0/cinelerra/mainsession.C b/cinelerra-5.0/cinelerra/mainsession.C index 44fda393..287c973f 100644 --- a/cinelerra-5.0/cinelerra/mainsession.C +++ b/cinelerra-5.0/cinelerra/mainsession.C @@ -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); diff --git a/cinelerra-5.0/guicast/Makefile b/cinelerra-5.0/guicast/Makefile index 475370f7..0167de27 100644 --- a/cinelerra-5.0/guicast/Makefile +++ b/cinelerra-5.0/guicast/Makefile @@ -84,6 +84,7 @@ OBJS = \ $(OBJDIR)/units.o \ $(OBJDIR)/vframe.o \ $(OBJDIR)/vframe3d.o \ + $(OBJDIR)/vicon.o \ $(OBJDIR)/workarounds.o OUTPUT = $(OBJDIR)/libguicast.a diff --git a/cinelerra-5.0/guicast/bcbitmap.C b/cinelerra-5.0/guicast/bcbitmap.C index c508de5c..dedb03b4 100644 --- a/cinelerra-5.0/guicast/bcbitmap.C +++ b/cinelerra-5.0/guicast/bcbitmap.C @@ -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; iis_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(); } diff --git a/cinelerra-5.0/guicast/bclistbox.h b/cinelerra-5.0/guicast/bclistbox.h index e270c13c..8100adfd 100644 --- a/cinelerra-5.0/guicast/bclistbox.h +++ b/cinelerra-5.0/guicast/bclistbox.h @@ -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 *data, int column, int item); int get_item_color(ArrayList *data, int column, int item); int get_icon_mask(BC_ListBoxItem *item, int &x, int &y, int &w, int &h); diff --git a/cinelerra-5.0/guicast/bcwindowbase.C b/cinelerra-5.0/guicast/bcwindowbase.C index 59963d6d..602934b1 100644 --- a/cinelerra-5.0/guicast/bcwindowbase.C +++ b/cinelerra-5.0/guicast/bcwindowbase.C @@ -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); +} diff --git a/cinelerra-5.0/guicast/bcwindowbase.h b/cinelerra-5.0/guicast/bcwindowbase.h index f2314753..af271e49 100644 --- a/cinelerra-5.0/guicast/bcwindowbase.h +++ b/cinelerra-5.0/guicast/bcwindowbase.h @@ -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 index 00000000..05f56dfe --- /dev/null +++ b/cinelerra-5.0/guicast/vicon.C @@ -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 && ageage; 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 && ageage; 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; iflash(); + 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; iwrite_png(fn); + } + printf("\n"); +} + diff --git a/cinelerra-5.0/guicast/vicon.h b/cinelerra-5.0/guicast/vicon.h new file mode 100644 index 00000000..fb315289 --- /dev/null +++ b/cinelerra-5.0/guicast/vicon.h @@ -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 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; + + ArrayListt_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 index 00000000..77b9ca87 --- /dev/null +++ b/cinelerra-5.0/guicast/vicon.inc @@ -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 -- 2.26.2