refresh frame fix, dblclk proxy viewer fix, vicon refresh fix for awdw resize, fix...
[goodguy/history.git] / cinelerra-5.1 / guicast / vicon.C
index e9a71b154fae09ee47ef23992ce11d84d571d679..9c41ccf1ea915d20548a0f755f6676ea92249abe 100644 (file)
@@ -13,16 +13,22 @@ VIcon(int vw, int vh, double rate)
        this->vw = vw;
        this->vh = vh;
        this->frame_rate = rate;
        this->vw = vw;
        this->vh = vh;
        this->frame_rate = rate;
-       this->cycle_start = 0;
-       this->age = 0;
-       this->seq_no = 0;
-       this->in_use = 1;
+
+       cycle_start = 0;
+       age = 0;
+       seq_no = 0;
+       in_use = 1;
+       hidden = 0;
+       audio_data = 0;
+       audio_size = 0;
+       playing_audio = 0;
 }
 
 VIcon::
 ~VIcon()
 {
        clear_images();
 }
 
 VIcon::
 ~VIcon()
 {
        clear_images();
+       delete [] audio_data;
 }
 
 void VIcon::
 }
 
 void VIcon::
@@ -35,9 +41,29 @@ add_image(VFrame *frm, int ww, int hh, int vcmdl)
 }
 
 void VIcon::
 }
 
 void VIcon::
-draw_vframe(BC_WindowBase *wdw, int x, int y)
+draw_vframe(VIconThread *vt, BC_WindowBase *wdw, int x, int y)
 {
 {
-       wdw->draw_vframe(frame(), x,y, vw,vh);
+       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 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);
+}
+
+void VIconThread::
+set_drawing_area(int x0, int y0, int x1, int y1)
+{
+       draw_x0 = x0;  draw_y0 = y0;
+       draw_x1 = x1;  draw_y1 = y1;
 }
 
 VIcon *VIconThread::low_vicon()
 }
 
 VIcon *VIconThread::low_vicon()
@@ -72,6 +98,8 @@ VIconThread(BC_WindowBase *wdw, int vw, int vh)
        this->view_win = 0;  this->vicon = 0;
        this->view_w = vw;   this->view_h = vh;
        this->viewing = 0;
        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();
        draw_lock = new Condition(0, "VIconThread::draw_lock", 1);
        timer = new Timer();
        this->refresh_rate = VICON_RATE;
        draw_lock = new Condition(0, "VIconThread::draw_lock", 1);
        timer = new Timer();
        this->refresh_rate = VICON_RATE;
@@ -132,16 +160,11 @@ int ViewPopup::button_press_event()
 bool VIconThread::
 visible(VIcon *vicon, int x, int y)
 {
 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;
+       if( vicon->hidden ) return false;
+       if( y+vicon->vh <= draw_y0 ) return false;
+       if( y >= draw_y1 ) return false;
+       if( x+vicon->vw <= draw_x0 ) return false;
+       if( x >= draw_x1 ) return false;
        return true;
 }
 
        return true;
 }
 
@@ -163,14 +186,21 @@ ViewPopup::~ViewPopup()
 
 void ViewPopup::draw_vframe(VFrame *frame)
 {
 
 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)
 {
        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);
+       BC_WindowBase *parent = wdw->get_parent();
+       XineramaScreenInfo *info = parent->get_xinerama_info(-1);
+       int cx = info ? info->x_org + info->width/2 : parent->get_root_w(0)/2;
+       int cy = info ? info->y_org + info->height/2 : parent->get_root_h(0)/2;
+       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;
        ViewPopup *vwin = new ViewPopup(this, frame, rx, ry, view_w, view_h);
        wdw->set_active_subwindow(vwin);
        return vwin;
@@ -205,6 +235,8 @@ int VIconThread::del_vicon(VIcon *&vicon)
 
 void VIconThread::set_view_popup(VIcon *vicon)
 {
 
 void VIconThread::set_view_popup(VIcon *vicon)
 {
+       if( !vicon && this->vicon )
+               this->vicon->stop_audio();
        this->vicon = vicon;
 }
 
        this->vicon = vicon;
 }
 
@@ -216,6 +248,7 @@ update_view()
                VFrame *frame = viewing->frame();
                view_win = new_view_window(frame);
                view_win->show_window();
                VFrame *frame = viewing->frame();
                view_win = new_view_window(frame);
                view_win->show_window();
+               vicon->start_audio();
        }
        wdw->set_active_subwindow(view_win);
        return 1;
        }
        wdw->set_active_subwindow(view_win);
        return 1;
@@ -247,7 +280,7 @@ draw(VIcon *vicon)
        if( !draw_img && !draw_win ) return 0;
        if( !vicon->frame() ) return 0;
        if( draw_img ) {
        if( !draw_img && !draw_win ) return 0;
        if( !vicon->frame() ) return 0;
        if( draw_img ) {
-               vicon->draw_vframe(wdw, x, y);
+               vicon->draw_vframe(this, wdw, x, y);
                img_dirty = 1;
        }
        if( draw_win ) {
                img_dirty = 1;
        }
        if( draw_win ) {
@@ -257,6 +290,14 @@ draw(VIcon *vicon)
        return 1;
 }
 
        return 1;
 }
 
+void VIconThread::hide_vicons(int v)
+{
+       for( int i=0; i<t_heap.size(); ++i ) {
+               t_heap[i]->hidden = v;
+               t_heap[i]->age = 0;
+       }
+}
+
 void VIconThread::
 run()
 {
 void VIconThread::
 run()
 {
@@ -276,7 +317,11 @@ run()
                                now = timer->get_difference();
                                if( now >= draw_flash ) break;
                                draw(next);
                                now = timer->get_difference();
                                if( now >= draw_flash ) break;
                                draw(next);
-                               if( !next->seq_no ) next->cycle_start = now;
+                               if( !next->seq_no ) {
+                                       next->cycle_start = now;
+                                       if( next->playing_audio )
+                                               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;
                                int64_t ref_no = (now - next->cycle_start) / 1000. * refresh_rate;
                                int count = ref_no - next->seq_no;
                                if( count < 1 ) count = 1;
@@ -317,6 +362,14 @@ run()
        }
 }
 
        }
 }
 
+
+void VIcon::init_audio(int audio_size)
+{
+       this->audio_size = audio_size;
+       audio_data = new uint8_t[audio_size];
+       memset(audio_data, 0, audio_size);
+}
+
 void VIcon::dump(const char *dir)
 {
        mkdir(dir,0777);
 void VIcon::dump(const char *dir)
 {
        mkdir(dir,0777);