#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)
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) ) {
edl = 0;
icon = 0;
icon_vframe = 0;
+ vicon = 0;
in_use = 1;
id = 0;
persistent = 0;
//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__);
}
folderlist_menu = 0;
temp_picon = 0;
remove_plugin = 0;
+ vicon_thread = 0;
+ vicon_drawing = 1;
}
AWindowGUI::~AWindowGUI()
vtransitions.remove_all_objects();
displayed_assets[1].remove_all_objects();
+ delete vicon_thread;
delete file_icon;
delete audio_icon;
delete video_icon;
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,
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
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;
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;
}
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)
void AWindowGUI::update_folder_list()
{
+ stop_vicon_drawing();
//printf("AWindowGUI::update_folder_list 1\n");
for(int i = 0; i < folders.total; i++)
{
//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,
-
-
AWindowDivider::AWindowDivider(MWindow *mwindow, AWindowGUI *gui, int x, int y, int w, int h)
: BC_SubWindow(x, y, w, h)
{
{
mwindow->session->afolders_w = gui->get_relative_cursor_x();
gui->reposition_objects();
+ gui->flush();
}
return 0;
}
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();
//printf("AWindowFolders::selection_changed 1\n");
gui->asset_list->draw_background();
gui->update_assets();
+
+ gui->start_vicon_drawing();
}
return 1;
}
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;
}
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();
+}
+
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;
+}
+
#include "mwindow.inc"
#include "newfolder.inc"
#include "pluginserver.inc"
+#include "vicon.h"
class AWindowAssets;
class AWindowFolders;
class AddTools;
class AddPluginsMenu;
class AddPluginItem;
+class AVIconDrawing;
+class AssetPicon;
+class AssetVIcon;
class AWindowGUI;
class AssetPicon : public BC_ListBoxItem
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;
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;
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();
int drag_stop_event();
int button_press_event();
int column_resize_event();
+ int cursor_enter_event();
+ int cursor_leave_event();
MWindow *mwindow;
AWindowGUI *gui;
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
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;
}
#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)
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");
int DbWindowDeleteItems::
handle_event()
{
- gui->search_list->stop_view_popup();
+ gui->search_list->set_view_popup(0);
gui->delete_items();
return 1;
}
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);
DbWindowList::~DbWindowList()
{
- delete view_ticon;
- delete view_popup;
}
int DbWindowList::
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::
{
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()
{
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();
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;
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");
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;
{
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);
// 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;
}
}
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;
}
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)
delete_selection(mdb);
mdb->detach();
}
- start_drawing(1);
+ start_drawing();
}
void DbWindowGUI::
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: {
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);
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];
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);
}
}
-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();
-}
-
-
-
#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:
DbWindowCancel *cancel;
DbWindowList *search_list;
DbWindowCanvas *canvas;
- DbWindowTIconThread *ticon_thread;
+ DbWindowVIconThread *vicon_thread;
int title_text_enable;
int info_text_enable;
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();
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);
{
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);
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
{
#ifndef _DBWINDOW_INC_
#define _DBWINDOW_INC_
+class DbSearchItem;
class DbWindow;
class DbWindowGUI;
class DbWindowInfoText;
class DbWindowCancel;
class DbWindowList;
class DbWindowCanvas;
-class DbWindowTIcon;
-class DbWindowTIconThread;
+class DbWindowVIcon;
+class DbWindowVIconThread;
class DbWindowItem;
class DbWindowScan;
//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);
$(OBJDIR)/units.o \
$(OBJDIR)/vframe.o \
$(OBJDIR)/vframe3d.o \
+ $(OBJDIR)/vicon.o \
$(OBJDIR)/workarounds.o
OUTPUT = $(OBJDIR)/libguicast.a
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;
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 )
BC_BitmapImage *buffer = buffers[i];
if( buffer == active_bfr ) active_bfr = 0;
if( buffer->is_avail() ) {
- avail.remove_pointer(buffer);
delete buffer;
}
else {
++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();
}
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,
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);
}
}
+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);
+}
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();
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;
--- /dev/null
+#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");
+}
+
--- /dev/null
+#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
--- /dev/null
+#ifndef __VICON_INC__
+#define __VICON_INC__
+
+#define VICON_WIDTH 80
+#define VICON_HEIGHT 45
+
+class ViewWindow;
+class VIconThread;
+class VIcon;
+
+#endif