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 VIFrame *vifrm = new VIFrame(ww, hh, vcmdl);
32 img->transfer_from(frm);
37 draw_vframe(BC_WindowBase *wdw, int x, int y)
39 wdw->draw_vframe(frame(), x,y, vw,vh);
42 VIcon *VIconThread::low_vicon()
44 if( !t_heap.size() ) return 0;
45 VIcon *vip = t_heap[0];
50 void VIconThread::remove_vicon(int i)
52 int sz = t_heap.size();
53 for( int k; (k=2*(i+1)) < sz; i=k ) {
54 if( t_heap[k]->age > t_heap[k-1]->age ) --k;
55 t_heap[i] = t_heap[k];
57 VIcon *last = t_heap[--sz];
58 t_heap.remove_number(sz);
59 double age = last->age;
60 for( int k; i>0 && age<t_heap[k=(i-1)/2]->age; i=k )
61 t_heap[i] = t_heap[k];
67 VIconThread(BC_WindowBase *wdw, int vw, int vh)
71 this->view_win = 0; this->vicon = 0;
72 this->view_w = vw; this->view_h = vh;
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::start_drawing");
100 wdw->set_active_subwindow(view_win);
103 wdw->unlock_window();
109 wdw->lock_window("VIconThread::stop_drawing");
112 wdw->unlock_window();
115 int VIconThread::keypress_event(int key)
117 if( key != ESC ) return 0;
122 int ViewPopup::button_press_event()
124 vt->set_view_popup(0);
129 visible(VIcon *vicon, int x, int y)
132 int my = y + vicon->vh;
133 if( my <= y0 ) return false;
134 int y1 = y0 + wdw->get_h();
135 if( y >= y1 ) return false;
137 int mx = x + vicon->vw;
138 if( mx <= x0 ) return false;
139 int x1 = x0 + wdw->get_w();
140 if( x >= x1 ) return false;
144 int ViewPopup::keypress_event()
146 int key = get_keypress();
147 return vt->keypress_event(key);
149 ViewPopup::ViewPopup(VIconThread *vt, VFrame *frame, int x, int y, int w, int h)
150 : BC_Popup(vt->wdw, x, y, w, h, BLACK)
155 ViewPopup::~ViewPopup()
157 vt->wdw->set_active_subwindow(0);
160 void ViewPopup::draw_vframe(VFrame *frame)
162 BC_WindowBase::draw_vframe(frame, 0,0, get_w(),get_h());
165 ViewPopup *VIconThread::new_view_window(VFrame *frame)
167 int wx = viewing->get_vx() - view_w, rx = 0;
168 int wy = viewing->get_vy() - view_h, ry = 0;
169 wdw->get_root_coordinates(wx, wy, &rx, &ry);
170 ViewPopup *vwin = new ViewPopup(this, frame, rx, ry, view_w, view_h);
171 wdw->set_active_subwindow(vwin);
178 for( int i=t_heap.size(); --i>=0; ) t_heap[i]->age = 0;
180 img_dirty = win_dirty = 0;
183 void VIconThread::add_vicon(VIcon *vip, double age)
186 int i = t_heap.size(); t_heap.append(vip);
187 for( int k; i>0 && age<t_heap[(k=(i-1)/2)]->age; i=k )
188 t_heap[i] = t_heap[k];
192 int VIconThread::del_vicon(VIcon *&vicon)
194 int i = t_heap.size();
195 while( --i >= 0 && t_heap[i] != vicon );
196 if( i < 0 ) return 0;
198 delete vicon; vicon = 0;
202 void VIconThread::set_view_popup(VIcon *vicon)
210 delete view_win; view_win = 0;
211 if( (viewing=vicon) != 0 ) {
212 VFrame *frame = viewing->frame();
213 view_win = new_view_window(frame);
214 view_win->show_window();
216 wdw->set_active_subwindow(view_win);
224 for( int i=0; i<t_heap.size(); ++i )
231 if( !img_dirty && !win_dirty ) return;
232 if( img_dirty ) wdw->flash();
233 if( win_dirty && view_win ) view_win->flash();
234 win_dirty = img_dirty = 0;
240 int x = vicon->get_vx(), y = vicon->get_vy();
241 int draw_img = visible(vicon, x, y);
242 int draw_win = view_win && viewing == vicon ? 1 : 0;
243 if( !draw_img && !draw_win ) return 0;
244 if( !vicon->frame() ) return 0;
246 vicon->draw_vframe(wdw, x, y);
250 view_win->draw_vframe(vicon->frame());
260 draw_lock->lock("VIconThread::run 0");
262 wdw->lock_window("BC_WindowBase::run 1");
266 int64_t draw_flash = 0;
268 while( !interrupted ) {
269 if( viewing != vicon )
271 VIcon *next = low_vicon();
273 int64_t now = timer->get_difference();
274 if( next == first || (draw_flash && now >= draw_flash) ) {
275 add_vicon(next, next->age);
276 if( !draw_flash ) draw_flash = now + 100;
277 else if( now >= draw_flash ) draw_flash = now + 1;
278 wdw->unlock_window();
279 while( !interrupted ) {
280 now = timer->get_difference();
281 int64_t ms = draw_flash - now;
283 if( ms > 100 ) ms = 100;
286 wdw->lock_window("BC_WindowBase::run 2");
287 now = timer->get_difference();
288 int64_t late = now - draw_flash;
289 if( late < 1000 ) flash();
294 if( !first ) first = next;
295 if( draw(next) && !draw_flash )
296 draw_flash = next->age;
297 now = timer->get_difference();
298 int64_t late = now - next->age;
299 int count = late / next->period;
300 int nfrms = count > 0 ? count : 1;
301 if( !next->next_frame(nfrms) )
302 next->age = now + 1000;
303 add_vicon(next, next->age);
305 if( viewing != vicon )
309 wdw->unlock_window();
313 void VIcon::dump(const char *dir)
316 for( int i=0; i<images.size(); ++i ) {
317 char fn[1024]; sprintf(fn,"%s/img%05d.png",dir,i);
319 VFrame *img = *images[i];