11 VIcon(int vw, int vh, double rate)
15 this->period = 1000./rate;
28 add_image(VFrame *frm, int ww, int hh, int vcmdl)
30 VFrame *img = new VFrame(ww, hh, vcmdl);
31 img->transfer_from(frm);
36 draw_vframe(BC_WindowBase *wdw, int x, int y)
38 wdw->draw_vframe(frame(), x,y, vw,vh);
41 VIcon *VIconThread::low_vicon()
43 if( !t_heap.size() ) return 0;
44 VIcon *vip = t_heap[0];
49 void VIconThread::remove_vicon(int i)
51 int sz = t_heap.size();
52 for( int k; (k=2*(i+1)) < sz; i=k ) {
53 if( t_heap[k]->age > t_heap[k-1]->age ) --k;
54 t_heap[i] = t_heap[k];
56 VIcon *last = t_heap[--sz];
57 t_heap.remove_number(sz);
58 double age = last->age;
59 for( int k; i>0 && age<t_heap[k=(i-1)/2]->age; i=k )
60 t_heap[i] = t_heap[k];
66 VIconThread(BC_WindowBase *wdw, int vw, int vh)
70 this->view_win = 0; this->vicon = 0;
71 this->cur_view = 0; this->new_view = 0;
72 this->view_w = vw; this->view_h = vh;
73 this->viewing = 0; this->draw_flash = 0;
74 draw_lock = new Condition(0, "VIconThread::draw_lock", 1);
86 if( Thread::running() ) {
90 t_heap.remove_all_objects();
98 wdw->lock_window("VIconThread::stop_drawing");
101 wdw->unlock_window();
107 wdw->lock_window("VIconThread::stop_drawing");
109 wdw->unlock_window();
112 int VIconThread::keypress_event(int key)
114 if( !cur_view ) return 0;
115 if( key != ESC ) return 0;
121 visible(VIcon *vicon, int x, int y)
124 int my = y + vicon->vh;
125 if( my <= y0 ) return false;
126 int y1 = y0 + wdw->get_h();
127 if( y >= y1 ) return false;
129 int mx = x + vicon->vw;
130 if( mx <= x0 ) return false;
131 int x1 = x0 + wdw->get_w();
132 if( x >= x1 ) return false;
136 int ViewPopup::keypress_event()
138 int key = get_keypress();
139 return vt->keypress_event(key);
141 int ViewPopup::button_press_event()
143 return vt->keypress_event(ESC);
146 ViewPopup::ViewPopup(VIconThread *vt, VFrame *frame, int x, int y, int w, int h)
147 : BC_Popup(vt->wdw, x, y, w, h, BLACK)
152 ViewPopup::~ViewPopup()
154 vt->wdw->set_active_subwindow(0);
157 void ViewPopup::draw_vframe(VFrame *frame)
159 BC_WindowBase::draw_vframe(frame, 0,0, get_w(),get_h());
162 ViewPopup *VIconThread::new_view_window(VFrame *frame)
164 int wx = viewing->get_vx() - view_w, rx = 0;
165 int wy = viewing->get_vy() - view_h, ry = 0;
166 wdw->get_root_coordinates(wx, wy, &rx, &ry);
167 ViewPopup *vwin = new ViewPopup(this, frame, rx, ry, view_w, view_h);
168 wdw->set_active_subwindow(vwin);
175 for( int i=t_heap.size(); --i>=0; ) t_heap[i]->age = 0;
177 img_dirty = win_dirty = 0;
181 void VIconThread::add_vicon(VIcon *vip, double age)
184 int i = t_heap.size(); t_heap.append(vip);
185 for( int k; i>0 && age<t_heap[(k=(i-1)/2)]->age; i=k )
186 t_heap[i] = t_heap[k];
190 int VIconThread::del_vicon(VIcon *&vicon)
192 int i = t_heap.size();
193 while( --i >= 0 && t_heap[i] != vicon );
194 if( i < 0 ) return 0;
196 delete vicon; vicon = 0;
200 void VIconThread::set_view_popup(VIcon *vicon)
208 if( viewing == vicon && cur_view == new_view ) return 0;
209 wdw->lock_window("VIconThread::update_view");;
210 if( viewing && !vicon ) new_view = 0;
211 if( !viewing && vicon ) new_view = 1;
212 if( cur_view != new_view && !new_view ) vicon = 0;
213 viewing = vicon; cur_view = new_view;
214 delete view_win; view_win = 0;
216 VFrame *frame = viewing->frame();
217 view_win = new_view_window(frame);
218 view_win->show_window();
220 wdw->unlock_window();
228 for( int i=0; i<t_heap.size(); ++i )
235 if( !img_dirty && !win_dirty ) return;
236 if( img_dirty ) wdw->flash();
237 if( win_dirty ) view_win->flash();
238 win_dirty = img_dirty = 0;
244 int x = vicon->get_vx(), y = vicon->get_vy();
245 int draw_img = visible(vicon, x, y);
246 int draw_win = view_win && viewing == vicon ? 1 : 0;
247 if( !draw_img && !draw_win ) return 0;
249 vicon->draw_vframe(wdw, x, y);
253 view_win->draw_vframe(vicon->frame());
263 draw_lock->lock("VIconThread::run 0");
265 wdw->lock_window("BC_WindowBase::run 1");
269 while( !interrupted ) {
270 if( viewing != vicon || cur_view != new_view )
272 VIcon *next = low_vicon();
274 if( !next->frame() ) {
275 delete next; next = 0;
278 int64_t next_time = next->age;
279 int64_t this_time = timer->get_difference();
280 int64_t msec = this_time - next_time;
281 int count = msec / next->period;
282 int nfrms = count > 0 ? count : 1;
283 if( !next->next_frame(nfrms) )
284 next->age = this_time + 1000;
285 add_vicon(next, next->age);
286 if( msec < 1000 && draw(next) && !draw_flash )
287 draw_flash = next_time;
288 wdw->unlock_window();
289 msec = next_time - timer->get_difference();
290 if( msec < 1 ) msec = 1;
291 while( msec > 0 && !interrupted ) {
292 int ms = msec > 100 ? 100 : msec;
293 Timer::delay(ms); msec -= ms;
295 wdw->lock_window("BC_WindowBase::run 2");
296 if( interrupted ) break;
298 int64_t msec = timer->get_difference() - draw_flash;
299 if( msec < 1000 ) flash();
305 wdw->unlock_window();
309 void VIcon::dump(const char *dir)
312 for( int i=0; i<images.size(); ++i ) {
313 char fn[1024]; sprintf(fn,"%s/img%05d.png",dir,i);
315 images[i]->write_png(fn);