#include "condition.h"
VIcon::
-VIcon(int vw, int vh, double rate)
+VIcon(int w, int h, double rate)
{
- this->vw = vw;
- this->vh = vh;
+ this->w = w;
+ this->h = h;
this->frame_rate = rate;
cycle_start = 0;
{
VFrame *vfrm = frame();
if( !vfrm ) return;
- int sx0 = 0, sx1 = sx0 + vt->view_w;
- int sy0 = 0, sy1 = sy0 + vt->view_h;
- int dx0 = x, dx1 = dx0 + vw;
- int dy0 = y, dy1 = dy0 + vh;
- if( (x=vt->draw_x0-dx0) > 0 ) { sx0 += (x*vt->view_w)/vw; dx0 = vt->draw_x0; }
- if( (x=dx1-vt->draw_x1) > 0 ) { sx1 -= (x*vt->view_w)/vw; dx1 = vt->draw_x1; }
- if( (y=vt->draw_y0-dy0) > 0 ) { sy0 += (y*vt->view_h)/vh; dy0 = vt->draw_y0; }
- if( (y=dy1-vt->draw_y1) > 0 ) { sy1 -= (y*vt->view_h)/vh; dy1 = vt->draw_y1; }
+ int sx0 = 0, sx1 = sx0 + vt->vw;
+ int sy0 = 0, sy1 = sy0 + vt->vh;
+ int dx0 = x, dx1 = dx0 + w;
+ int dy0 = y, dy1 = dy0 + h;
+ if( (x=vt->draw_x0-dx0) > 0 ) { sx0 += (x*vt->vw)/w; dx0 = vt->draw_x0; }
+ if( (x=dx1-vt->draw_x1) > 0 ) { sx1 -= (x*vt->vw)/w; dx1 = vt->draw_x1; }
+ if( (y=vt->draw_y0-dy0) > 0 ) { sy0 += (y*vt->vh)/h; dy0 = vt->draw_y0; }
+ if( (y=dy1-vt->draw_y1) > 0 ) { sy1 -= (y*vt->vh)/h; dy1 = vt->draw_y1; }
int sw = sx1 - sx0, sh = sy1 - sy0;
int dw = dx1 - dx0, dh = dy1 - dy0;
if( dw > 0 && dh > 0 && sw > 0 && sh > 0 )
wdw->draw_vframe(vfrm, dx0,dy0, dw,dh, sx0,sy0, sw,sh);
}
+
+int VIconThread::cursor_inside(int x, int y)
+{
+ if( !viewing ) return 0;
+ int vx = viewing->get_vx();
+ if( x < vx || x >= vx+vw ) return 0;
+ int vy = viewing->get_vy();
+ if( y < vy || y >= vy+vh ) return 0;
+ return 1;
+}
+
void VIconThread::
set_drawing_area(int x0, int y0, int x1, int y1)
{
void VIconThread::remove_vicon(int i)
{
+ if( t_heap[i] == solo ) solo = 0;
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;
VIconThread::
-VIconThread(BC_WindowBase *wdw, int vw, int vh)
+VIconThread(BC_WindowBase *wdw, int vw, int vh, int view_w, int view_h)
: Thread(1, 0, 0)
{
this->wdw = wdw;
- this->view_win = 0; this->vicon = 0;
- this->view_w = vw; this->view_h = vh;
- this->viewing = 0;
- this->draw_x0 = 0; this->draw_x1 = wdw->get_w();
- this->draw_y0 = 0; this->draw_y1 = wdw->get_h();
+ this->vw = vw; this->vh = vh;
+ this->view_w = view_w; this->view_h = view_h;
+ this->view_win = 0; this->vicon = 0;
+ this->viewing = 0; this->solo = 0;
+ this->draw_x0 = 0; this->draw_x1 = wdw->get_w();
+ this->draw_y0 = 0; this->draw_y1 = wdw->get_h();
draw_lock = new Condition(0, "VIconThread::draw_lock", 1);
timer = new Timer();
this->refresh_rate = VICON_RATE;
+ this->draw_flash = 0;
+ this->seq_no = 0;
+ this->now = 0;
done = 0;
interrupted = -1;
stop_age = 0;
stop_drawing()
{
wdw->lock_window("VIconThread::stop_drawing");
- set_view_popup(0);
+ close_view_popup();
if( !interrupted )
interrupted = 1;
stop_age = timer->get_difference();
wdw->unlock_window();
}
+void VIconThread::
+stop_viewing()
+{
+ if( viewing ) {
+ viewing->stop_audio();
+ viewing = 0;
+ }
+}
+
int VIconThread::keypress_event(int key)
{
if( key != ESC ) return 0;
- set_view_popup(0);
+ close_view_popup();
return 1;
}
visible(VIcon *vicon, int x, int y)
{
if( vicon->hidden ) return false;
- if( y+vicon->vh <= draw_y0 ) return false;
+ if( y+vicon->h <= draw_y0 ) return false;
if( y >= draw_y1 ) return false;
- if( x+vicon->vw <= draw_x0 ) return false;
+ if( x+vicon->w <= draw_x0 ) return false;
if( x >= draw_x1 ) return false;
return true;
}
return vt->keypress_event(key);
}
-ViewPopup::ViewPopup(VIconThread *vt, VFrame *frame, int x, int y, int w, int h)
+
+ViewPopup::ViewPopup(VIconThread *vt, int x, int y, int w, int h)
: BC_Popup(vt->wdw, x, y, w, h, BLACK)
{
this->vt = vt;
vt->wdw->set_active_subwindow(0);
}
-void ViewPopup::draw_vframe(VFrame *frame)
-{
- if( !frame ) return;
- BC_WindowBase::draw_vframe(frame, 0,0, get_w(),get_h());
-}
-
-ViewPopup *VIconThread::new_view_window(VFrame *frame)
+ViewPopup *VIconThread::new_view_window(ViewPopup *vpopup)
{
BC_WindowBase *parent = wdw->get_parent();
XineramaScreenInfo *info = parent->get_xinerama_info(-1);
int vx = viewing->get_vx(), rx = 0;
int vy = viewing->get_vy(), ry = 0;
wdw->get_root_coordinates(vx, vy, &rx, &ry);
- rx += (rx >= cx ? -view_w : viewing->vw);
- ry += (ry >= cy ? -view_h : viewing->vh);
- ViewPopup *vwin = new ViewPopup(this, frame, rx, ry, view_w, view_h);
- wdw->set_active_subwindow(vwin);
- return vwin;
+ rx += (rx >= cx ? -view_w+viewing->w/4 : viewing->w-viewing->w/4);
+ ry += (ry >= cy ? -view_h+viewing->h/4 : viewing->h-viewing->h/4);
+ if( vpopup )
+ vpopup->reposition_window(rx, ry, view_w, view_h);
+ else
+ vpopup = new ViewPopup(this, rx, ry, view_w, view_h);
+ wdw->set_active_subwindow(vpopup);
+ return vpopup;
}
+
void VIconThread::
reset_images()
{
t_heap[i] = vip;
}
-int VIconThread::del_vicon(VIcon *&vicon)
+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 ViewPopup::draw_vframe(VFrame *frame)
+{
+ if( !frame ) return;
+ BC_WindowBase::draw_vframe(frame, 0,0, get_w(),get_h());
+}
+
void VIconThread::set_view_popup(VIcon *vicon)
{
+ if( viewing == vicon && !this->vicon ) return;
this->vicon = vicon;
+ if( interrupted ) update_view(vicon ? 1 : 0);
+
+}
+
+void VIconThread::close_view_popup()
+{
+ set_view_popup(0);
}
int VIconThread::
-update_view()
+update_view(int do_audio)
{
if( viewing ) viewing->stop_audio();
delete view_win; view_win = 0;
if( (viewing=vicon) != 0 ) {
- VFrame *frame = viewing->frame();
- view_win = new_view_window(frame);
+ view_win = new_view_window(0);
+ view_win->draw_vframe(viewing->frame());
+ view_win->flash(0);
view_win->show_window();
- vicon->start_audio();
+ if( do_audio ) vicon->start_audio();
}
wdw->set_active_subwindow(view_win);
return 1;
}
+int VIconThread::zoom_scale(int dir)
+{
+ if( !viewing || !view_win ) return 0;
+ int view_h = this->view_h;
+ view_h += dir*view_h/10 + dir;
+ bclamp(view_h, 16,512);
+ this->view_h = view_h;
+ this->view_w = view_h * vw/vh;
+ new_view_window(view_win);
+ view_win->draw_vframe(viewing->frame());
+ view_win->flash(1);
+ return 1;
+}
+
void VIconThread::
draw_images()
}
}
+int VIconThread::show_vicon(VIcon *next)
+{
+ now = timer->get_difference();
+ if( now >= draw_flash ) return 1;
+ draw(next);
+ if( !next->seq_no ) {
+ next->cycle_start = now;
+ if( next->playing_audio > 0 )
+ next->start_audio();
+ }
+ int64_t ref_no = (now - next->cycle_start) / 1000. * refresh_rate;
+ int count = ref_no - next->seq_no;
+ if( count < 1 ) count = 1;
+ ref_no = next->seq_no + count;
+ next->age = next->cycle_start + 1000. * ref_no / refresh_rate;
+ if( !next->set_seq_no(ref_no) )
+ next->age = now + 1000.;
+ return 0;
+}
+
void VIconThread::
run()
{
wdw->lock_window("BC_WindowBase::run 1");
drawing_started();
reset_images();
- int64_t seq_no = 0, now = 0;
- int64_t draw_flash = 1000 / refresh_rate;
+ draw_flash = 1000 / refresh_rate;
+ seq_no = 0; now = 0;
while( !interrupted ) {
if( viewing != vicon )
- update_view();
- VIcon *next = low_vicon();
- while( next && next->age < draw_flash ) {
- now = timer->get_difference();
- if( now >= draw_flash ) break;
- draw(next);
- if( !next->seq_no ) {
- next->cycle_start = now;
- if( next->playing_audio )
- next->start_audio();
+ update_view(1);
+ if( !solo ) {
+ VIcon *next = low_vicon();
+ while( next && next->age < draw_flash ) {
+ if( show_vicon(next) ) break;
+ add_vicon(next);
+ next = low_vicon();
}
- int64_t ref_no = (now - next->cycle_start) / 1000. * refresh_rate;
- int count = ref_no - next->seq_no;
- if( count < 1 ) count = 1;
- ref_no = next->seq_no + count;
- next->age = next->cycle_start + 1000. * ref_no / refresh_rate;
- if( !next->set_seq_no(ref_no) )
- next->age = now + 1000.;
+ if( !next ) break;
add_vicon(next);
- next = low_vicon();
+ if( draw_flash < now+1 )
+ draw_flash = now+1;
}
- if( !next ) break;
- add_vicon(next);
- if( draw_flash < now+1 )
- draw_flash = now+1;
+ else
+ show_vicon(solo);
wdw->unlock_window();
while( !interrupted ) {
now = timer->get_difference();
draw_flash = seq_no * 1000. / refresh_rate;
}
if( viewing != vicon )
- update_view();
+ update_view(1);
drawing_stopped();
interrupted = -1;
wdw->unlock_window();