rework crikey, fix uninited vars in listbox
authorGood Guy <good1.2guy@gmail.com>
Sun, 25 Feb 2018 01:22:41 +0000 (18:22 -0700)
committerGood Guy <good1.2guy@gmail.com>
Sun, 25 Feb 2018 01:22:41 +0000 (18:22 -0700)
cinelerra-5.1/guicast/bclistbox.C
cinelerra-5.1/guicast/bclistbox.h
cinelerra-5.1/guicast/bcscrollbar.C
cinelerra-5.1/plugins/crikey/crikey.C
cinelerra-5.1/plugins/crikey/crikey.h
cinelerra-5.1/plugins/crikey/crikeywindow.C
cinelerra-5.1/plugins/crikey/crikeywindow.h

index 0cea9d626cb9275cd7e21e5332d86b2d53873563..7c032b6a0bbb9b31cde88505fd9d8da70864c9e0 100644 (file)
@@ -287,8 +287,8 @@ BC_ListBox::BC_ListBox(int x, int y, int w, int h,
        yscrollbar = 0;
        current_cursor = ARROW_CURSOR;
        gui = 0;
-       view_h = 0;
-       view_w = 0;
+       view_w = items_w = 0;
+       view_h = items_h = 0;
        title_h = 0;
        active = 0;
        is_suggestions = 0;
@@ -300,20 +300,26 @@ BC_ListBox::BC_ListBox(int x, int y, int w, int h,
        bg_tile = 0;
        bg_draw = 1;
        drag_popup = 0;
+       dragged_title = 0;
        selection_number1 = -1;
        selection_number2 = -1;
        bg_surface = 0;
        bg_pixmap = 0;
        row_height = row_ascent = row_descent = 0;
-
+       selection_start = 0;
+       selection_center = 0;
+       selection_end = -1;
+       selection_number = -1;
        current_operation = NO_OPERATION;
        button_highlighted = 0;
+       button_releases = 0;
        list_highlighted = 0;
        disabled = 0;
 
        scroll_repeat = 0;
        allow_drag_scroll = 1;
        process_drag = 1;
+       for( int i=0; i<32; ++i ) default_column_width[i] = 0;
 
        sort_column = -1;
        sort_order = 0;
@@ -360,8 +366,11 @@ BC_ListBox::BC_ListBox(int x, int y, int w, int h,
 
        drag_icon_vframe = 0;
        drag_column_icon_vframe = 0;
-
-
+       drag_cursor_x = 0;
+       drag_column_w = 0;
+       temp_display_format = display_format;
+       rect_x1 = rect_x2 = 0;
+       rect_y1 = rect_y2 = 0;
 
 // reset the search engine
 //printf("BC_ListBox::BC_ListBox 4\n");
index 365ec488bb07119df32f8b4d705fe4834de0b27f..f5994d53aa935322c0f522aa98bcd541d9666c23 100644 (file)
@@ -507,7 +507,7 @@ private:
 // Size of the popup if there is one
        char **column_titles;
        int *column_width;
-       int default_column_width[1];
+       int default_column_width[32];
        int columns;
        int master_column;
        int search_column;
index 389cacf8bf4b5e97f8117f8e19a3969dbc180334..680341d0beebf0e990e1b74a5bf42c62670e9473 100644 (file)
@@ -117,30 +117,18 @@ int BC_ScrollBar::get_span(int orientation)
 
 int BC_ScrollBar::get_span()
 {
-       switch(orientation)
-       {
-               case SCROLL_HORIZ:
-                       return data[SCROLL_HANDLE_UP]->get_h();
-                       break;
-
-               case SCROLL_VERT:
-                       return data[SCROLL_HANDLE_UP]->get_w();
-                       break;
+       switch(orientation) {
+       case SCROLL_HORIZ: return data[SCROLL_HANDLE_UP]->get_h();
+       case SCROLL_VERT:  return data[SCROLL_HANDLE_UP]->get_w();
        }
        return 0;
 }
 
 int BC_ScrollBar::get_arrow_pixels()
 {
-       switch(orientation)
-       {
-               case SCROLL_HORIZ:
-                       return data[SCROLL_BACKARROW_UP]->get_w();
-                       break;
-
-               case SCROLL_VERT:
-                       return data[SCROLL_BACKARROW_UP]->get_h();
-                       break;
+       switch(orientation) {
+       case SCROLL_HORIZ: return data[SCROLL_BACKARROW_UP]->get_w();
+       case SCROLL_VERT:  return data[SCROLL_BACKARROW_UP]->get_h();
        }
        return 0;
 }
index 9ed221a5c6c36ca55d2f3df6c8330f88eff1a54d..92b7495849e13de91f429d031aa10434291ecef3 100644 (file)
@@ -49,9 +49,11 @@ void crikey_pgm(const char *fn,VFrame *vfrm)
 }
 #endif
 
-CriKeyPoint::CriKeyPoint(int t, int e, float x, float y)
+CriKeyPoint::CriKeyPoint(int tag, int e, float x, float y, float t)
 {
-       this->t = t;  this->e = e; this->x = x; this->y = y;
+       this->tag = tag;  this->e = e;
+       this->x = x;      this->y = y;
+       this->t = t;
 }
 CriKeyPoint::~CriKeyPoint()
 {
@@ -59,7 +61,6 @@ CriKeyPoint::~CriKeyPoint()
 
 CriKeyConfig::CriKeyConfig()
 {
-       color = 0x000000;
        threshold = 0.5f;
        draw_mode = DRAW_ALPHA;
        drag = 0;
@@ -67,29 +68,27 @@ CriKeyConfig::CriKeyConfig()
 }
 CriKeyConfig::~CriKeyConfig()
 {
-       points.remove_all_objects();
 }
 
 int CriKeyConfig::equivalent(CriKeyConfig &that)
 {
-       if( this->color != that.color ) return 0;
        if( !EQUIV(this->threshold, that.threshold) ) return 0;
        if( this->draw_mode != that.draw_mode ) return 0;
        if( this->drag != that.drag ) return 0;
        if( this->points.size() != that.points.size() ) return 0;
        for( int i=0, n=points.size(); i<n; ++i ) {
                CriKeyPoint *ap = this->points[i], *bp = that.points[i];
-               if( ap->t != bp->t ) return 0;
+               if( ap->tag != bp->tag ) return 0;
                if( ap->e != bp->e ) return 0;
                if( !EQUIV(ap->x, bp->x) ) return 0;
                if( !EQUIV(ap->y, bp->y) ) return 0;
+               if( !EQUIV(ap->t, bp->t) ) return 0;
        }
        return 1;
 }
 
 void CriKeyConfig::copy_from(CriKeyConfig &that)
 {
-       this->color = that.color;
        this->threshold = that.threshold;
        this->draw_mode = that.draw_mode;
        this->drag = that.drag;
@@ -98,28 +97,20 @@ void CriKeyConfig::copy_from(CriKeyConfig &that)
        points.remove_all_objects();
        for( int i=0,n=that.points.size(); i<n; ++i ) {
                CriKeyPoint *pt = that.points[i];
-               add_point(pt->t, pt->e, pt->x, pt->y);
+               add_point(pt->tag, pt->e, pt->x, pt->y, pt->t);
        }
 }
 
 void CriKeyConfig::interpolate(CriKeyConfig &prev, CriKeyConfig &next,
                long prev_frame, long next_frame, long current_frame)
 {
-       this->color = prev.color;
+       this->threshold = prev.threshold;
        this->draw_mode = prev.draw_mode;
        this->drag = prev.drag;
        this->selected = prev.selected;
 
        double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame);
        double prev_scale = (double)(next_frame - current_frame) / (next_frame - prev_frame);
-       this->threshold = prev.threshold * prev_scale + next.threshold * next_scale;
- // interpolate rgb components
-       float prev_target[3];  set_target(0, prev.color, prev_target);
-       float next_target[3];  set_target(0, next.color, next_target);
-       float target[3];
-       for( int i=0; i<3; ++i )
-               target[i] = prev_target[i] * prev_scale + next_target[i] * next_scale;
-       set_color(0, target, this->color);
 
        points.remove_all_objects();
        int prev_sz = prev.points.size(), next_sz = next.points.size();
@@ -127,12 +118,12 @@ void CriKeyConfig::interpolate(CriKeyConfig &prev, CriKeyConfig &next,
                CriKeyPoint *pt = prev.points[i], *nt = 0;
                float x = pt->x, y = pt->y;
                int k = next_sz;  // associated by tag id in next
-               while( --k >= 0 && pt->t != (nt=next.points[k])->t );
+               while( --k >= 0 && pt->tag != (nt=next.points[k])->tag );
                if( k >= 0 ) {
                        x = x * prev_scale + nt->x * next_scale;
                        y = y * prev_scale + nt->y * next_scale;
                }
-               add_point(pt->t, pt->e, x, y);
+               add_point(pt->tag, pt->e, x, y, pt->t);
        }
 }
 
@@ -142,17 +133,17 @@ void CriKeyConfig::limits()
        bclamp(draw_mode, 0, DRAW_MODES-1);
 }
 
-int CriKeyConfig::add_point(int t, int e, float x, float y)
+int CriKeyConfig::add_point(int tag, int e, float x, float y, float t)
 {
        int k = points.size();
-       if( t < 0 ) {
-               t = 0;
+       if( tag < 0 ) {
+               tag = 0;
                for( int i=k; --i>=0; ) {
-                       int n = points[i]->t;
-                       if( n >= t ) t = n + 1;
+                       int n = points[i]->tag;
+                       if( n >= tag ) tag = n + 1;
                }
        }
-       points.append(new CriKeyPoint(t, e, x, y));
+       points.append(new CriKeyPoint(tag, e, x, y, t));
        return k;
 }
 
@@ -178,22 +169,23 @@ class FillRegion
        }
  
        int w, h;
-       uint8_t *data, *mask;
-       bool edge_pixel(uint8_t *dp) { return *dp; }
+       float *edg;
+       uint8_t *msk;
+       bool edge_pixel(int i) { return edg[i] > 0; }
 
 public:
        void fill(int x, int y);
        void run();
 
-       FillRegion(VFrame *d, VFrame *m);
+       FillRegion(VFrame *edg, VFrame *msk);
 };
 
-FillRegion::FillRegion(VFrame *d, VFrame *m)
+FillRegion::FillRegion(VFrame *edg, VFrame *msk)
 {
-       w = d->get_w();
-       h = d->get_h();
-       data = d->get_data();
-       mask = m->get_data();
+       this->w = msk->get_w();
+       this->h = msk->get_h();
+       this->msk = (uint8_t*) msk->get_data();
+       this->edg = (float*) edg->get_data();
 }
 
 void FillRegion::fill(int x, int y)
@@ -207,24 +199,22 @@ void FillRegion::run()
                int y, ilt, irt;
                pop(y, ilt, irt);
                int ofs = y*w + ilt;
-               uint8_t *idp = data + ofs;
-               uint8_t *imp = mask + ofs;
-               for( int x=ilt; x<=irt; ++x,++imp,++idp ) {
-                       if( !*imp ) continue;
-                       *imp = 0;
-                       if( edge_pixel(idp) ) continue;
+               for( int x=ilt; x<=irt; ++x,++ofs ) {
+                       if( !msk[ofs] ) continue;
+                       msk[ofs] = 0;
+                       if( edge_pixel(ofs) ) continue;
                        int lt = x, rt = x;
-                       uint8_t *ldp = idp, *lmp = imp;
+                       int lofs = ofs;
                        for( int i=lt; --i>=0; ) {
-                               if( !*--lmp ) break;
-                               *lmp = 0;  lt = i;
-                               if( edge_pixel(--ldp) ) break;
+                               if( !msk[--lofs] ) break;
+                               msk[lofs] = 0;  lt = i;
+                               if( edge_pixel(lofs) ) break;
                        }
-                       uint8_t *rdp = idp, *rmp = imp;
-                       for( int i=rt; ++i< w; rt=i,*rmp=0 ) {
-                               if( !*++rmp ) break;
-                               *rmp = 0;  rt = i;
-                               if( edge_pixel(++rdp) ) break;
+                       int rofs = ofs;
+                       for( int i=rt; ++i< w; rt=i,msk[rofs]=0 ) {
+                               if( !msk[++rofs] ) break;
+                               msk[rofs] = 0;  rt = i;
+                               if( edge_pixel(rofs) ) break;
                        }
                        if( y+1 <  h ) push(y+1, lt, rt);
                        if( y-1 >= 0 ) push(y-1, lt, rt);
@@ -238,65 +228,30 @@ CriKey::CriKey(PluginServer *server)
 {
        engine = 0;
        msk = 0;
-       dst = 0;
+       edg = 0;
 }
 
 CriKey::~CriKey()
 {
        delete engine;
        delete msk;
-       delete dst;
+       delete edg;
 }
 
-void CriKeyConfig::set_target(int is_yuv, int color, float *target)
-{
-       float r = ((color>>16) & 0xff) / 255.0f;
-       float g = ((color>> 8) & 0xff) / 255.0f;
-       float b = ((color>> 0) & 0xff) / 255.0f;
-       if( is_yuv ) {
-               float y, u, v;
-               YUV::yuv.rgb_to_yuv_f(r,g,b, y,u,v);
-               target[0] = y;
-               target[1] = u + 0.5f;
-               target[2] = v + 0.5f;
-       }
-       else {
-               target[0] = r;
-               target[1] = g;
-               target[2] = b;
-       }
-}
-void CriKeyConfig::set_color(int is_yuv, float *target, int &color)
+int CriKey::set_target(float *color, int x, int y)
 {
-       float r = target[0];
-       float g = target[1];
-       float b = target[2];
-       if( is_yuv ) {
-               float y = r, u = g-0.5f, v = b-0.5f;
-               YUV::yuv.yuv_to_rgb_f(y,u,v, r,g,b);
-       }
-       int ir = r >= 1 ? 0xff : r < 0 ? 0 : (int)(r * 256);
-       int ig = g >= 1 ? 0xff : g < 0 ? 0 : (int)(g * 256);
-       int ib = b >= 1 ? 0xff : b < 0 ? 0 : (int)(b * 256);
-       color = (ir << 16) | (ig << 8) | (ib << 0);
-}
-
-void CriKey::get_color(int x, int y)
-{
-       if( x < 0 || x >= w ) return;
-       if( y < 0 || y >= h ) return;
+       if( x < 0 || x >= w ) return 1;
+       if( y < 0 || y >= h ) return 1;
        uint8_t **src_rows = src->get_rows();
-       uint8_t *sp = src_rows[y] + x*bpp;
        if( is_float ) {
-               float *fp = (float *)sp;
-               for( int i=0; i<comp; ++i,++fp )
-                       target[i] = *fp;
+               float *fp = (float*)(src_rows[y] + x*bpp);
+               for( int i=0; i<comp; ++i,++fp ) color[i] = *fp;
        }
        else {
-               float scale = 1./255;
-               for( int i=0; i<comp; ++i,++sp )
-                       target[i] = *sp * scale;
+               uint8_t *sp = src_rows[y] + x*bpp;
+               for( int i=0; i<comp; ++i,++sp ) color[i] = *sp;
        }
+       return 0;
 }
 
 const char* CriKey::plugin_title() { return N_("CriKey"); }
@@ -310,7 +265,7 @@ int CriKey::new_point()
        EDLSession *session = get_edlsession();
        float x = !session ? 0.f : session->output_w / 2.f;
        float y = !session ? 0.f : session->output_h / 2.f;
-       return config.add_point(-1, 0, x, y);
+       return config.add_point(-1, 0, x, y, 0.5f);
 }
 
 void CriKey::save_data(KeyFrame *keyframe)
@@ -321,7 +276,6 @@ void CriKey::save_data(KeyFrame *keyframe)
        output.set_shared_output(keyframe->get_data(), MESSAGESIZE);
 
        output.tag.set_title("CRIKEY");
-       output.tag.set_property("COLOR", config.color);
        output.tag.set_property("THRESHOLD", config.threshold);
        output.tag.set_property("DRAW_MODE", config.draw_mode);
        output.tag.set_property("DRAG", config.drag);
@@ -334,11 +288,12 @@ void CriKey::save_data(KeyFrame *keyframe)
        for( int i=0, n = config.points.size(); i<n; ++i ) {
                CriKeyPoint *pt = config.points[i];
                char point[BCSTRLEN];
-               sprintf(point,"/POINT_%d",pt->t);
+               sprintf(point,"/POINT_%d",pt->tag);
                output.tag.set_title(point+1);
                output.tag.set_property("E", pt->e);
                output.tag.set_property("X", pt->x);
                output.tag.set_property("Y", pt->y);
+               output.tag.set_property("T", pt->t);
                output.append_tag();
                output.tag.set_title(point+0);
                output.append_tag();
@@ -356,7 +311,6 @@ void CriKey::read_data(KeyFrame *keyframe)
 
        while( !(result=input.read_tag()) ) {
                if( input.tag.title_is("CRIKEY") ) {
-                       config.color = input.tag.get_property("COLOR", config.color);
                        config.threshold = input.tag.get_property("THRESHOLD", config.threshold);
                        config.draw_mode = input.tag.get_property("DRAW_MODE", config.draw_mode);
                        config.drag = input.tag.get_property("DRAG", config.drag);
@@ -364,11 +318,12 @@ void CriKey::read_data(KeyFrame *keyframe)
                        config.limits();
                }
                else if( !strncmp(input.tag.get_title(),"POINT_",6) ) {
-                       int t = atoi(input.tag.get_title() + 6);
+                       int tag = atoi(input.tag.get_title() + 6);
                        int e = input.tag.get_property("E", 0);
                        float x = input.tag.get_property("X", 0.f);
                        float y = input.tag.get_property("Y", 0.f);
-                       config.add_point(t, e, x, y);
+                       float t = input.tag.get_property("T", .5f);
+                       config.add_point(tag, e, x, y, t);
                }
        }
 
@@ -446,6 +401,79 @@ void CriKey::draw_alpha(VFrame *msk)
        }
 }
 
+void CriKey::draw_edge(VFrame *edg)
+{
+       uint8_t **src_rows = src->get_rows();
+       float **edg_rows = (float**) edg->get_rows(), gain = 10;
+       switch( color_model ) {
+       case BC_RGB_FLOAT:
+               for( int y=0; y<h; ++y ) {
+                       uint8_t *sp = src_rows[y];
+                       float *ap = edg_rows[y];
+                       for( int x=0; x<w; ++x,++ap,sp+=bpp ) {
+                               float *px = (float *)sp, v = *ap * gain;
+                               px[0] = px[1] = px[2] = v<1 ? v : 1;
+                       }
+               }
+               break;
+       case BC_RGBA_FLOAT:
+               for( int y=0; y<h; ++y ) {
+                       uint8_t *sp = src_rows[y];
+                       float *ap = edg_rows[y];
+                       for( int x=0; x<w; ++x,++ap,sp+=bpp ) {
+                               float *px = (float *)sp, v = *ap * gain;
+                               px[0] = px[1] = px[2] = v<1 ? v : 1;
+                               px[3] = 1.0f;
+                       }
+               }
+               break;
+       case BC_RGB888:
+               for( int y=0; y<h; ++y ) {
+                       uint8_t *sp = src_rows[y];
+                       float *ap = edg_rows[y];
+                       for( int x=0; x<w; ++x,++ap,sp+=bpp ) {
+                               uint8_t *px = sp;  float v = *ap * gain;
+                               px[0] = px[1] = px[2] = v<1 ? v*256 : 255;
+                       }
+               }
+               break;
+       case BC_RGBA8888:
+               for( int y=0; y<h; ++y ) {
+                       uint8_t *sp = src_rows[y];
+                       float *ap = edg_rows[y];
+                       for( int x=0; x<w; ++x,++ap,sp+=bpp ) {
+                               uint8_t *px = sp;  float v = *ap * gain;
+                               px[0] = px[1] = px[2] = v<1 ? v*256 : 255;
+                               px[3] = 0xff;
+                       }
+               }
+               break;
+       case BC_YUV888:
+               for( int y=0; y<h; ++y ) {
+                       uint8_t *sp = src_rows[y];
+                       float *ap = edg_rows[y];
+                       for( int x=0; x<w; ++x,++ap,sp+=bpp ) {
+                               uint8_t *px = sp;  float v = *ap * gain;
+                               px[0] = *ap<1 ? v*256 : 255;
+                               px[1] = px[2] = 0x80;
+                       }
+               }
+               break;
+       case BC_YUVA8888:
+               for( int y=0; y<h; ++y ) {
+                       uint8_t *sp = src_rows[y];
+                       float *ap = edg_rows[y];
+                       for( int x=0; x<w; ++x,++ap,sp+=bpp ) {
+                               uint8_t *px = sp;  float v = *ap * gain;
+                               px[0] = *ap<1 ? v*256 : 255;
+                               px[1] = px[2] = 0x80;
+                               px[3] = 0xff;
+                       }
+               }
+               break;
+       }
+}
+
 void CriKey::draw_mask(VFrame *msk)
 {
        uint8_t **src_rows = src->get_rows();
@@ -520,6 +548,7 @@ void CriKey::draw_mask(VFrame *msk)
        }
 }
 
+
 void CriKey::draw_point(VFrame *src, CriKeyPoint *pt)
 {
        int d = bmax(w,h) / 200 + 2;
@@ -538,6 +567,23 @@ void CriKey::draw_point(VFrame *src, CriKeyPoint *pt)
        }
 }
 
+
+static void get_vframe(VFrame *&vfrm, int w, int h, int color_model)
+{
+       if( vfrm && ( vfrm->get_w() != w || vfrm->get_h() != h ) ) {
+               delete vfrm;  vfrm = 0;
+       }
+       if( !vfrm ) vfrm = new VFrame(w, h, color_model, 0);
+}
+
+static void fill_edge(VFrame *vfrm, int w, int h)
+{
+       int w1 = w-1, h1 = h-1;
+       float *dp = (float*) vfrm->get_data();
+       if( w1 > 0 ) for( int y=0; y<h1; ++y,dp+=w ) dp[w1] = dp[w1-1];
+       if( h1 > 0 ) for( int x=0; x<w; ++x ) dp[x] = dp[x-w];
+}
+
 int CriKey::process_buffer(VFrame *frame, int64_t start_position, double frame_rate)
 {
        load_configuration();
@@ -545,61 +591,41 @@ int CriKey::process_buffer(VFrame *frame, int64_t start_position, double frame_r
        w = src->get_w(), h = src->get_h();
        color_model = src->get_color_model();
        bpp = BC_CModels::calculate_pixelsize(color_model);
-       comp = BC_CModels::components(color_model);
-        if( comp > 3 ) comp = 3;
-       is_yuv = BC_CModels::is_yuv(color_model);
        is_float = BC_CModels::is_float(color_model);
+       is_yuv = BC_CModels::is_yuv(color_model);
+       comp = BC_CModels::components(color_model);
+       if( comp > 3 ) comp = 3;
 
        read_frame(src, 0, start_position, frame_rate, 0);
-
-       set_target(is_yuv, config.color, target);
-
-        if( dst && ( dst->get_w() != w || src->get_h() != h ) ) {
-               delete dst;  dst = 0;
-        }
-        if( !dst )
-               dst = new VFrame(w, h, BC_A8, 0);
-       dst->clear_frame();
+       get_vframe(edg, w, h, BC_A_FLOAT);
 
        if( !engine )
                engine = new CriKeyEngine(this,
                        PluginClient::get_project_smp() + 1,
                        PluginClient::get_project_smp() + 1);
-       engine->process_packages();
-// copy fill btm/rt edges
-       int w1 = w-1, h1 = h-1;
-       uint8_t *dp = dst->get_data();
-       if( w1 > 0 ) for( int y=0; y<h1; ++y,dp+=w ) dp[w1] = dp[w1-1];
-       if( h1 > 0 ) for( int x=0; x<w; ++x ) dp[x] = dp[x-w];
-//crikey_pgm("/tmp/dst.pgm",dst);
 
-       if( config.draw_mode != DRAW_EDGE ) {
-               if( msk && ( msk->get_w() != w || msk->get_h() != h ) ) {
-                       delete msk;  msk = 0;
-               }
-               if( !msk )
-                       msk = new VFrame(w, h, BC_A8, 0);
-               memset(msk->get_data(), 0xff, msk->get_data_size());
+       get_vframe(msk, w, h, BC_A8);
+       memset(msk->get_data(), 0xff, msk->get_data_size());
 
-               FillRegion fill_region(dst, msk);
-               for( int i=0, n=config.points.size(); i<n; ++i ) {
-                       CriKeyPoint *pt = config.points[i];
-                       if( !pt->e ) continue;
-                       float x = pt->x, y = pt->y;
-                       if( x >= 0 && x < w && y >= 0 && y < h )
-                               fill_region.fill(x, y);
-               }
+       for( int i=0, n=config.points.size(); i<n; ++i ) {
+               CriKeyPoint *pt = config.points[i];
+               if( !pt->e ) continue;
+               if( set_target(engine->color, pt->x, pt->y) ) continue;
+               engine->threshold = pt->t;
+               edg->clear_frame();
+               engine->process_packages();
+               fill_edge(edg, w, h);
+               FillRegion fill_region(edg, msk);
+               fill_region.fill(pt->x, pt->y);
                fill_region.run();
+       }
 
 //crikey_pgm("/tmp/msk.pgm",msk);
-
-               if( config.draw_mode == DRAW_MASK )
-                       draw_mask(msk);
-               else
-                       draw_alpha(msk);
+       switch( config.draw_mode ) {
+       case DRAW_ALPHA: draw_alpha(msk);  break;
+       case DRAW_EDGE:  draw_edge(edg);   break;
+       case DRAW_MASK:  draw_mask(msk);   break;
        }
-       else
-               draw_mask(dst);
 
        if( config.drag ) {
                for( int i=0, n=config.points.size(); i<n; ++i ) {
@@ -633,30 +659,28 @@ LoadClient* CriKeyEngine::new_client()
        return new CriKeyUnit(this);
 }
 
-#define EDGE_MACRO(type, max, components, is_yuv) \
+#define EDGE_MACRO(type, components, is_yuv) \
 { \
        uint8_t **src_rows = src->get_rows(); \
        int comps = MIN(components, 3); \
-       float scale = 1.0f/max; \
        for( int y=y1; y<y2; ++y ) { \
                uint8_t *row0 = src_rows[y], *row1 = src_rows[y+1]; \
-               uint8_t *outp = dst_rows[y]; \
-               for( int v,x=x1; x<x2; *outp++=v,++x,row0+=bpp,row1+=bpp ) { \
+               float *edgp = edg_rows[y]; \
+               for( int x=x1; x<x2; ++edgp,++x,row0+=bpp,row1+=bpp ) { \
                        type *r0 = (type*)row0, *r1 = (type*)row1; \
                        float a00 = 0, a01 = 0, a10 = 0, a11 = 0; \
-                       for( int i=0; i<comps; ++i,++r0,++r1 ) { \
-                               float t = target[i]; \
-                               a00 += fabs(t - r0[0]*scale); \
-                               a01 += fabs(t - r0[components]*scale); \
-                               a10 += fabs(t - r1[0]*scale); \
-                               a11 += fabs(t - r1[components]*scale); \
+                       for( int c=0; c<comps; ++c,++r0,++r1 ) { \
+                               float t = target_color[c]; \
+                                a00 += fabs(t - r0[0]); \
+                               a01 += fabs(t - r0[components]); \
+                               a10 += fabs(t - r1[0]); \
+                               a11 += fabs(t - r1[components]); \
                        } \
-                       v = 0; \
-                       float a = bmin(bmin(a00, a01), bmin(a10, a11)); \
-                       if( a > threshold ) continue; \
-                       float b = bmax(bmax(a00, a01), bmax(a10, a11)); \
-                       if( threshold >= b ) continue; \
-                       v = 255; \
+                       float mx = scale * bmax(bmax(a00, a01), bmax(a10, a11)); \
+                       if( mx < threshold ) continue; \
+                        float mn = scale * bmin(bmin(a00, a01), bmin(a10, a11)); \
+                       if( mn >= threshold ) continue; \
+                       *edgp += (mx - mn); \
                } \
        } \
 } break
@@ -664,23 +688,25 @@ LoadClient* CriKeyEngine::new_client()
 
 void CriKeyUnit::process_package(LoadPackage *package)
 {
-       VFrame *src = server->plugin->src;
+       int color_model = server->plugin->color_model;
        int bpp = server->plugin->bpp;
-       VFrame *dst = server->plugin->dst;
-       uint8_t **dst_rows = dst->get_rows();
-       float *target = server->plugin->target;
-       float threshold = server->plugin->config.threshold;
+       VFrame *src = server->plugin->src;
+       VFrame *edg = server->plugin->edg;
+       float **edg_rows = (float**)edg->get_rows();
+       float *target_color = server->color;
+       float threshold = 2.f * server->threshold*server->threshold;
+       float scale = 1./BC_CModels::calculate_max(color_model);
        CriKeyPackage *pkg = (CriKeyPackage*)package;
        int x1 = 0, x2 = server->plugin->w-1;
        int y1 = pkg->y1, y2 = pkg->y2;
 
-       switch( src->get_color_model() ) {
-       case BC_RGB_FLOAT:  EDGE_MACRO(float, 1, 3, 0);
-       case BC_RGBA_FLOAT: EDGE_MACRO(float, 1, 4, 0);
-       case BC_RGB888:     EDGE_MACRO(unsigned char, 0xff, 3, 0);
-       case BC_YUV888:     EDGE_MACRO(unsigned char, 0xff, 3, 1);
-       case BC_RGBA8888:   EDGE_MACRO(unsigned char, 0xff, 4, 0);
-       case BC_YUVA8888:   EDGE_MACRO(unsigned char, 0xff, 4, 1);
+       switch( color_model ) {
+       case BC_RGB_FLOAT:  EDGE_MACRO(float, 3, 0);
+       case BC_RGBA_FLOAT: EDGE_MACRO(float, 4, 0);
+       case BC_RGB888:     EDGE_MACRO(unsigned char, 3, 0);
+       case BC_YUV888:     EDGE_MACRO(unsigned char, 3, 1);
+       case BC_RGBA8888:   EDGE_MACRO(unsigned char, 4, 0);
+       case BC_YUVA8888:   EDGE_MACRO(unsigned char, 4, 1);
        }
 }
 
index 6747e6449f18eb4e4f9126f7619ef00d87e3e9e1..21e602e7c669ff534484b5a21eaceb62f1469306 100644 (file)
@@ -34,17 +34,23 @@ class CriKey;
 #define DRAW_MASK       2
 #define DRAW_MODES      3
 
-enum { PT_E, PT_X, PT_Y, PT_T, PT_SZ }; // enable, x,y, tag
+enum { PT_E, PT_X, PT_Y, PT_T, PT_TAG, PT_SZ }; // enable, x,y,threshold, tag
 
 class CriKeyPoint
 {
 public:
-       int t, e;
-       float x, y;
+       int tag, e;
+       float x, y, t;
 
-       CriKeyPoint(int t, int e, float x, float y);
+       CriKeyPoint(int tag, int e, float x, float y, float t);
        ~CriKeyPoint();
 };
+class CriKeyPoints : public ArrayList<CriKeyPoint *>
+{
+public:
+       CriKeyPoints() {}
+       ~CriKeyPoints() { remove_all_objects(); }
+};
 
 class CriKeyConfig
 {
@@ -57,15 +63,12 @@ public:
        void interpolate(CriKeyConfig &prev, CriKeyConfig &next,
                long prev_frame, long next_frame, long current_frame);
        void limits();
-       static void set_target(int is_yuv, int color, float *target);
-       static void set_color(int is_yuv, float *target, int &color);
 
-       ArrayList<CriKeyPoint *> points;
-       int add_point(int t, int e, float x, float y);
+       CriKeyPoints points;
+       int add_point(int tag, int e, float x, float y, float t);
        int add_point();
        void del_point(int i);
 
-       int color;
        float threshold;
        int draw_mode;
        int drag, selected;
@@ -90,6 +93,8 @@ public:
        LoadClient* new_client();
 
        CriKey *plugin;
+       int set_color(int x, int y, float t);
+       float color[3], threshold;
 };
 
 class CriKeyUnit : public LoadClient
@@ -115,25 +120,19 @@ public:
        int is_realtime();
        void update_gui();
        int new_point();
+       int set_target(float *color, int x, int y);
        void save_data(KeyFrame *keyframe);
        void read_data(KeyFrame *keyframe);
        int process_buffer(VFrame *frame, int64_t start_position, double frame_rate);
        void draw_alpha(VFrame *msk);
+       void draw_edge(VFrame *frm);
        void draw_mask(VFrame *frm);
        void draw_point(VFrame *msk, CriKeyPoint *pt);
-       static void set_target(int is_yuv, int color, float *target) {
-               CriKeyConfig::set_target(is_yuv, color, target);
-       }
-       static void set_color(int is_yuv, float *target, int &color) {
-               CriKeyConfig::set_color(is_yuv, target, color);
-       }
 
        CriKeyEngine *engine;
-       VFrame *src, *dst, *msk;
-       int w, h, color_model, bpp, comp, is_yuv, is_float;
-
-       void get_color(int x, int y);
-       float target[3];
+       VFrame *src, *edg, *msk;
+       int w, h, color_model, bpp, comp;
+       int is_yuv, is_float;
 };
 
 #endif
index 2c8f6d86d8c554431c4d2aa8f8d9d21c81ef0406..ca8245a1a55fa9d5de597b77729eef1878554e6c 100644 (file)
@@ -54,28 +54,32 @@ CriKeyNum::~CriKeyNum()
 int CriKeyPointX::handle_event()
 {
        if( !CriKeyNum::handle_event() ) return 0;
-       CriKeyPoints *points = gui->points;
-       int hot_point = points->get_selection_number(0, 0);
-       if( hot_point >= 0 && hot_point < gui->plugin->config.points.size() ) {
+       CriKeyPointList *point_list = gui->point_list;
+       int hot_point = point_list->get_selection_number(0, 0);
+       CriKeyPoints &points = gui->plugin->config.points;
+       int sz = points.size();
+       if( hot_point >= 0 && hot_point < sz ) {
                float v = atof(get_text());
-               gui->plugin->config.points[hot_point]->x = v;
-               points->set_point(hot_point, PT_X, v);
+               points[hot_point]->x = v;
+               point_list->set_point(hot_point, PT_X, v);
        }
-       points->update_list();
+       point_list->update_list(hot_point);
        gui->send_configure_change();
        return 1;
 }
 int CriKeyPointY::handle_event()
 {
        if( !CriKeyNum::handle_event() ) return 0;
-       CriKeyPoints *points = gui->points;
-       int hot_point = points->get_selection_number(0, 0);
-       if( hot_point >= 0 && hot_point < gui->plugin->config.points.size() ) {
+       CriKeyPointList *point_list = gui->point_list;
+       int hot_point = point_list->get_selection_number(0, 0);
+       CriKeyPoints &points = gui->plugin->config.points;
+       int sz = points.size();
+       if( hot_point >= 0 && hot_point < sz ) {
                float v = atof(get_text());
-               gui->plugin->config.points[hot_point]->y = v;
-               points->set_point(hot_point, PT_Y, v);
+               points[hot_point]->y = v;
+               point_list->set_point(hot_point, PT_Y, v);
        }
-       points->update_list();
+       point_list->update_list(hot_point);
        gui->send_configure_change();
        return 1;
 }
@@ -109,83 +113,22 @@ void CriKeyDrawMode::update(int mode, int send)
        if( send ) gui->send_configure_change();
 }
 
-CriKeyColorButton::CriKeyColorButton(CriKeyWindow *gui, int x, int y)
- : BC_GenericButton(x, y, _("Color"))
-{
-       this->gui = gui;
-}
-int CriKeyColorButton::handle_event()
-{
-       gui->start_color_thread();
-       return 1;
-}
-
-CriKeyColorPicker::CriKeyColorPicker(CriKeyColorButton *color_button)
- : ColorPicker(0, _("Color"))
-{
-       this->color_button = color_button;
-}
-
-void CriKeyColorPicker::start(int color)
-{
-       orig_color = this->color = color;
-       start_window(color, 0, 1);
-}
-
-void CriKeyColorPicker::handle_done_event(int result)
-{
-       if( result ) color = orig_color;
-       CriKeyWindow *gui = color_button->gui;
-       gui->lock_window("CriKeyColorPicker::handle_done_event");
-       gui->update_color(color);
-       gui->plugin->config.color = color;
-       gui->send_configure_change();
-       gui->unlock_window();
-}
-
-int CriKeyColorPicker::handle_new_color(int color, int alpha)
-{
-       CriKeyWindow *gui = color_button->gui;
-       gui->lock_window("CriKeyColorPicker::handle_new_color");
-       gui->update_color(this->color = color);
-       gui->flush();
-       gui->plugin->config.color = color;
-       gui->send_configure_change();
-       gui->unlock_window();
-       return 1;
-}
-
-
-void CriKeyWindow::start_color_thread()
-{
-       unlock_window();
-       delete color_picker;
-       color_picker = new CriKeyColorPicker(color_button);
-       color_picker->start(plugin->config.color);
-       lock_window("CriKeyWindow::start_color_thread");
-}
-
 
 CriKeyWindow::CriKeyWindow(CriKey *plugin)
- : PluginClientWindow(plugin, 380, 360, 380, 360, 0)
+ : PluginClientWindow(plugin, 380, 400, 380, 400, 0)
 {
        this->plugin = plugin;
-       this->color_button = 0;
-       this->color_picker = 0;
        this->title_x = 0;    this->point_x = 0;
        this->title_y = 0;    this->point_y = 0;
        this->new_point = 0;  this->del_point = 0;
        this->point_up = 0;   this->point_dn = 0;
        this->drag = 0;       this->dragging = 0;
        this->last_x = 0;     this->last_y = 0;
-       this->points = 0;     this->cur_point = 0;
-       this->pending_config = 0;
+       this->point_list = 0; this->pending_config = 0;
 }
 
 CriKeyWindow::~CriKeyWindow()
 {
-       delete color_picker;
-       delete points;
 }
 
 void CriKeyWindow::create_objects()
@@ -193,17 +136,8 @@ void CriKeyWindow::create_objects()
        int x = 10, y = 10;
        int margin = plugin->get_theme()->widget_border;
        BC_Title *title;
-       add_subwindow(title = new BC_Title(x, y, _("Threshold:")));
-       y += title->get_h() + margin;
-       add_subwindow(threshold = new CriKeyThreshold(this, x, y, get_w() - x * 2));
-       y += threshold->get_h() + margin;
-       add_subwindow(color_button = new CriKeyColorButton(this, x, y));
-       int x1 = x + color_button->get_w() + margin;
-       color_x = x1;  color_y = y;
-       update_color(plugin->config.color);
-       y += COLOR_H + 10 + margin ;
        add_subwindow(title = new BC_Title(x, y+5, _("Draw mode:")));
-       x1 = x + title->get_w() + 10 + margin;
+       int x1 = x + title->get_w() + 10 + margin;
        add_subwindow(draw_mode = new CriKeyDrawMode(this, x1, y));
        draw_mode->create_objects();
        y += draw_mode->get_h() + 10 + margin;
@@ -227,20 +161,29 @@ void CriKeyWindow::create_objects()
        x1 += del_point->get_w() + margin;
        add_subwindow(point_dn = new CriKeyPointDn(this, x1, y));
        y += point_y->get_h() + margin + 10;
+       add_subwindow(title = new BC_Title(x, y, _("Threshold:")));
+       y += title->get_h() + margin;
+       add_subwindow(threshold = new CriKeyThreshold(this, x, y, get_w() - x * 2));
+       y += threshold->get_h() + margin;
 
        add_subwindow(drag = new CriKeyDrag(this, x, y));
        if( plugin->config.drag ) {
                if( !grab(plugin->server->mwindow->cwindow->gui) )
                        eprintf("drag enabled, but compositor already grabbed\n");
        }
-
-       x1 = x + drag->get_w() + margin + 20;
-       add_subwindow(cur_point = new CriKeyCurPoint(this, plugin, x1, y+3));
-       cur_point->update(plugin->config.selected);
+       x1 = x + drag->get_w() + margin + 32;
+       add_subwindow(reset = new CriKeyReset(this, plugin, x1, y+3));
        y += drag->get_h() + margin;
-       add_subwindow(points = new CriKeyPoints(this, plugin, x, y));
-       points->update(plugin->config.selected);
 
+       add_subwindow(point_list = new CriKeyPointList(this, plugin, x, y));
+       point_list->update(plugin->config.selected);
+
+       y += point_list->get_h() + 10;
+       add_subwindow(notes = new BC_Title(x, y,
+                _("Right click in composer: create new point\n"
+                  "Shift-left click in Enable field:\n"
+                  "  if any off, turns all on\n"
+                  "  if all on, turns rest off.")));
        show_window(1);
 }
 
@@ -310,42 +253,57 @@ int CriKeyWindow::grab_event(XEvent *event)
        float output_y = (cursor_y - projector_y) / projector_z + track_h / 2;
        point_x->update((int64_t)(output_x));
        point_y->update((int64_t)(output_y));
+       CriKeyPoints &points = plugin->config.points;
 
        if( dragging > 0 ) {
                switch( event->type ) {
                case ButtonPress: {
+                       int button_no = event->xbutton.button;
                        int hot_point = -1;
-                       int n = plugin->config.points.size();
-                       if( n > 0 ) {
-                               CriKeyPoint *pt = plugin->config.points[hot_point=0];
+                       if( button_no == RIGHT_BUTTON ) {
+                               hot_point = plugin->new_point();
+                               CriKeyPoint *pt = points[hot_point];
+                               pt->x = output_x;  pt->y = output_y;
+                               point_list->update(hot_point);
+                               break;
+                       }
+                       int sz = points.size();
+                       if( hot_point < 0 && sz > 0 ) {
+                               CriKeyPoint *pt = points[hot_point=0];
                                double dist = DISTANCE(output_x,output_y, pt->x,pt->y);
-                               for( int i=1; i<n; ++i ) {
-                                       pt = plugin->config.points[i];
+                               for( int i=1; i<sz; ++i ) {
+                                       pt = points[i];
                                        double d = DISTANCE(output_x,output_y, pt->x,pt->y);
                                        if( d >= dist ) continue;
                                        dist = d;  hot_point = i;
                                }
+                               pt = points[hot_point];
+                               float px = (pt->x - track_w / 2) * projector_z + projector_x;
+                               float py = (pt->y - track_h / 2) * projector_z + projector_y;
+                               dist = DISTANCE(px, py, cursor_x,cursor_y);
+                               if( dist >= HANDLE_W ) hot_point = -1;
                        }
-                       if( hot_point >= 0 ) {
-                               CriKeyPoint *pt = plugin->config.points[hot_point];
-                               if( pt->x == output_x && pt->y == output_y ) break;
-                               points->set_point(hot_point, PT_X, pt->x = output_x);
-                               points->set_point(hot_point, PT_Y, pt->y = output_y);
-                               plugin->config.selected = hot_point;
-                               points->set_selected(hot_point);
-                               points->update_list();
+                       if( hot_point >= 0 && sz > 0 ) {
+                               CriKeyPoint *pt = points[hot_point];
+                               point_list->set_point(hot_point, PT_X, pt->x = output_x);
+                               for( int i=0; i<sz; ++i ) {
+                                       pt = points[i];
+                                       pt->e = i==hot_point ? !pt->e : 0;
+                                       point_list->set_point(i, PT_E, pt->e ? "*" : "");
+                               }
+                               point_list->update_list(hot_point);
                        }
                        break; }
                case MotionNotify: {
-                       int hot_point = points->get_selection_number(0, 0);
-                       if( hot_point >= 0 && hot_point < plugin->config.points.size() ) {
-                               CriKeyPoint *pt = plugin->config.points[hot_point];
+                       int hot_point = point_list->get_selection_number(0, 0);
+                       if( hot_point >= 0 && hot_point < points.size() ) {
+                               CriKeyPoint *pt = points[hot_point];
                                if( pt->x == output_x && pt->y == output_y ) break;
-                               points->set_point(hot_point, PT_X, pt->x = output_x);
-                               points->set_point(hot_point, PT_Y, pt->y = output_y);
+                               point_list->set_point(hot_point, PT_X, pt->x = output_x);
+                               point_list->set_point(hot_point, PT_Y, pt->y = output_y);
                                point_x->update(pt->x);
                                point_y->update(pt->y);
-                               points->update_list();
+                               point_list->update_list(hot_point);
                        }
                        break; }
                }
@@ -354,18 +312,18 @@ int CriKeyWindow::grab_event(XEvent *event)
                switch( event->type ) {
                case MotionNotify: {
                        float dx = output_x - last_x, dy = output_y - last_y;
-                       int n = plugin->config.points.size();
-                       for( int i=0; i<n; ++i ) {
-                               CriKeyPoint *pt = plugin->config.points[i];
-                               points->set_point(i, PT_X, pt->x += dx);
-                               points->set_point(i, PT_Y, pt->y += dy);
+                       int sz = points.size();
+                       for( int i=0; i<sz; ++i ) {
+                               CriKeyPoint *pt = points[i];
+                               point_list->set_point(i, PT_X, pt->x += dx);
+                               point_list->set_point(i, PT_Y, pt->y += dy);
                        }
-                       int hot_point = points->get_selection_number(0, 0);
-                       if( hot_point >= 0 && hot_point < n ) {
-                               CriKeyPoint *pt = plugin->config.points[hot_point];
+                       int hot_point = point_list->get_selection_number(0, 0);
+                       if( hot_point >= 0 && hot_point < sz ) {
+                               CriKeyPoint *pt = points[hot_point];
                                point_x->update(pt->x);
                                point_y->update(pt->y);
-                               points->update_list();
+                               point_list->update_list(hot_point);
                        }
                        break; }
                }
@@ -382,153 +340,148 @@ int CriKeyWindow::grab_event(XEvent *event)
 void CriKeyWindow::done_event(int result)
 {
        ungrab(client->server->mwindow->cwindow->gui);
-       if( color_picker ) color_picker->close_window();
 }
 
-CriKeyPoints::CriKeyPoints(CriKeyWindow *gui, CriKey *plugin, int x, int y)
+CriKeyPointList::CriKeyPointList(CriKeyWindow *gui, CriKey *plugin, int x, int y)
  : BC_ListBox(x, y, 360, 130, LISTBOX_TEXT)
 {
        this->gui = gui;
        this->plugin = plugin;
-       titles[PT_E] = _("E");    widths[PT_E] = 40;
-       titles[PT_X] = _("X");    widths[PT_X] = 120;
-       titles[PT_Y] = _("Y");    widths[PT_Y] = 120;
-       titles[PT_T] = _("Tag");  widths[PT_T] = 60;
+       titles[PT_E] = _("E");    widths[PT_E] = 50;
+       titles[PT_X] = _("X");    widths[PT_X] = 90;
+       titles[PT_Y] = _("Y");    widths[PT_Y] = 90;
+       titles[PT_T] = _("T");    widths[PT_T] = 70;
+       titles[PT_TAG] = _("Tag");  widths[PT_TAG] = 50;
 }
-CriKeyPoints::~CriKeyPoints()
+CriKeyPointList::~CriKeyPointList()
 {
        clear();
 }
-void CriKeyPoints::clear()
+void CriKeyPointList::clear()
 {
        for( int i=PT_SZ; --i>=0; )
                cols[i].remove_all_objects();
 }
 
-int CriKeyPoints::column_resize_event()
+int CriKeyPointList::column_resize_event()
 {
        for( int i=PT_SZ; --i>=0; )
                widths[i] = get_column_width(i);
        return 1;
 }
 
-int CriKeyPoints::handle_event()
+int CriKeyPointList::handle_event()
 {
        int hot_point = get_selection_number(0, 0);
        const char *x_text = "", *y_text = "";
-       if( hot_point >= 0 && hot_point < plugin->config.points.size() ) {
+       float t = plugin->config.threshold;
+       CriKeyPoints &points = plugin->config.points;
+
+       int sz = points.size();
+       if( hot_point >= 0 && sz > 0 ) {
                if( get_cursor_x() < widths[0] ) {
-                       plugin->config.points[hot_point]->e =
-                               !plugin->config.points[hot_point]->e;
+                       if( shift_down() ) {
+                               int all_on = points[0]->e;
+                               for( int i=1; i<sz && all_on; ++i ) all_on = points[i]->e;
+                               int e = !all_on ? 1 : 0;
+                               for( int i=0; i<sz; ++i ) points[i]->e = e;
+                               points[hot_point]->e = 1;
+                       }
+                       else
+                               points[hot_point]->e = !points[hot_point]->e;
                }
-               x_text = gui->points->cols[PT_X].get(hot_point)->get_text();
-               y_text = gui->points->cols[PT_Y].get(hot_point)->get_text();
+               x_text = gui->point_list->cols[PT_X].get(hot_point)->get_text();
+               y_text = gui->point_list->cols[PT_Y].get(hot_point)->get_text();
+               t = points[hot_point]->t;
        }
-       else
-               hot_point = 0;
        gui->point_x->update(x_text);
        gui->point_y->update(y_text);
-       plugin->config.selected = hot_point;
+       gui->threshold->update(t);
        update(hot_point);
        gui->send_configure_change();
        return 1;
 }
 
-int CriKeyPoints::selection_changed()
+int CriKeyPointList::selection_changed()
 {
        handle_event();
        return 1;
 }
 
-void CriKeyPoints::new_point(const char *ep, const char *xp, const char *yp, const char *tp)
+void CriKeyPointList::new_point(const char *ep, const char *xp, const char *yp,
+               const char *tp, const char *tag)
 {
        cols[PT_E].append(new BC_ListBoxItem(ep));
        cols[PT_X].append(new BC_ListBoxItem(xp));
        cols[PT_Y].append(new BC_ListBoxItem(yp));
        cols[PT_T].append(new BC_ListBoxItem(tp));
+       cols[PT_TAG].append(new BC_ListBoxItem(tag));
 }
 
-void CriKeyPoints::del_point(int i)
+void CriKeyPointList::del_point(int i)
 {
-       for( int n=cols[0].size()-1, c=PT_SZ; --c>=0; )
-               cols[c].remove_object_number(n-i);
+       for( int sz1=cols[0].size()-1, c=PT_SZ; --c>=0; )
+               cols[c].remove_object_number(sz1-i);
 }
 
-void CriKeyPoints::set_point(int i, int c, float v)
+void CriKeyPointList::set_point(int i, int c, float v)
 {
        char s[BCSTRLEN]; sprintf(s,"%0.4f",v);
        set_point(i,c,s);
 }
-void CriKeyPoints::set_point(int i, int c, const char *cp)
+void CriKeyPointList::set_point(int i, int c, const char *cp)
 {
        cols[c].get(i)->set_text(cp);
 }
 
-int CriKeyPoints::set_selected(int k)
+int CriKeyPointList::set_selected(int k)
 {
-       int sz = gui->plugin->config.points.size();
+       CriKeyPoints &points = plugin->config.points;
+       int sz = points.size();
        if( !sz ) return -1;
        bclamp(k, 0, sz-1);
-       int n = gui->points->get_selection_number(0, 0);
-       if( n >= 0 ) {
-               for( int i=0; i<PT_SZ; ++i )
-                       cols[i].get(n)->set_selected(0);
-       }
-       for( int i=0; i<PT_SZ; ++i )
-               cols[i].get(k)->set_selected(1);
-       gui->cur_point->update(k);
+       for( int i=0; i<sz; ++i ) points[i]->e = 0;
+       points[k]->e = 1;
+       update_selection(&cols[0], k);
        return k;
 }
-void CriKeyPoints::update_list()
+void CriKeyPointList::update_list(int k)
 {
-       int xpos = get_xposition(), ypos = get_xposition();
-       int k =  get_selection_number(0, 0);
+       int xpos = get_xposition(), ypos = get_yposition();
+       if( k < 0 ) k = get_selection_number(0, 0);
+       update_selection(&cols[0], k);
        BC_ListBox::update(&cols[0], &titles[0],&widths[0],PT_SZ, xpos,ypos,k);
+       center_selection();
 }
-void CriKeyPoints::update(int k)
+void CriKeyPointList::update(int k)
 {
-       if( k < 0 ) k = get_selection_number(0, 0);
-       gui->cur_point->update(k);
-       int xpos = get_xposition(), ypos = get_xposition();
-
        clear();
-       ArrayList<CriKeyPoint*> &points = plugin->config.points;
-       int n = points.size();
-       for( int i=0; i<n; ++i ) {
+       CriKeyPoints &points = plugin->config.points;
+       int sz = points.size();
+       for( int i=0; i<sz; ++i ) {
                CriKeyPoint *pt = points[i];
                char etxt[BCSTRLEN];  sprintf(etxt,"%s", pt->e ? "*" : "");
                char xtxt[BCSTRLEN];  sprintf(xtxt,"%0.4f", pt->x);
                char ytxt[BCSTRLEN];  sprintf(ytxt,"%0.4f", pt->y);
-               char ttxt[BCSTRLEN];  sprintf(ttxt,"%d", pt->t);
-               new_point(etxt, xtxt, ytxt, ttxt);
+               char ttxt[BCSTRLEN];  sprintf(ttxt,"%0.4f", pt->t);
+               char ttag[BCSTRLEN];  sprintf(ttag,"%d", pt->tag);
+               new_point(etxt, xtxt, ytxt, ttxt, ttag);
        }
-       if( k < n ) {
-               for( int i=PT_SZ; --i>=0; )
-                       cols[i].get(k)->set_selected(1);
-               gui->point_x->update(gui->points->cols[PT_X].get(k)->get_text());
-               gui->point_y->update(gui->points->cols[PT_Y].get(k)->get_text());
+       if( k >= 0 && k < sz ) {
+               gui->point_x->update(gui->point_list->cols[PT_X].get(k)->get_text());
+               gui->point_y->update(gui->point_list->cols[PT_Y].get(k)->get_text());
+               plugin->config.selected = k;
        }
 
-       BC_ListBox::update(&cols[0], &titles[0],&widths[0],PT_SZ, xpos,ypos,k);
-}
-
-void CriKeyWindow::update_color(int color)
-{
-       set_color(color);
-       draw_box(color_x, color_y, COLOR_W, COLOR_H);
-       set_color(BLACK);
-       draw_rectangle(color_x, color_y, COLOR_W, COLOR_H);
-       flash(color_x, color_y, COLOR_W, COLOR_H);
+       update_list(k);
 }
 
 void CriKeyWindow::update_gui()
 {
        draw_mode->update(plugin->config.draw_mode);
-       update_color(plugin->config.color);
        threshold->update(plugin->config.threshold);
-       cur_point->update(plugin->config.selected);
        drag->update(plugin->config.drag);
-       points->update(plugin->config.selected);
+       point_list->update(-1);
 }
 
 
@@ -543,6 +496,13 @@ int CriKeyThreshold::handle_event()
 {
        float v = get_value();
        gui->plugin->config.threshold = v;
+       int hot_point = gui->point_list->get_selection_number(0, 0);
+       if( hot_point >= 0 ) {
+               CriKeyPoints &points = gui->plugin->config.points;
+               CriKeyPoint *pt = points[hot_point];
+               pt->t = v;  pt->e = 1;
+               gui->point_list->update(hot_point);
+       }
        gui->send_configure_change();
        return 1;
 }
@@ -559,15 +519,15 @@ CriKeyPointUp::~CriKeyPointUp()
 
 int CriKeyPointUp::handle_event()
 {
-       int n = gui->plugin->config.points.size();
-       int hot_point = gui->points->get_selection_number(0, 0);
+       CriKeyPoints &points = gui->plugin->config.points;
+       int sz = points.size();
+       int hot_point = gui->point_list->get_selection_number(0, 0);
 
-       if( n > 1 && hot_point > 0 ) {
-               CriKeyPoint *&pt0 = gui->plugin->config.points[hot_point];
-               CriKeyPoint *&pt1 = gui->plugin->config.points[--hot_point];
+       if( sz > 1 && hot_point > 0 ) {
+               CriKeyPoint *&pt0 = points[hot_point];
+               CriKeyPoint *&pt1 = points[--hot_point];
                CriKeyPoint *t = pt0;  pt0 = pt1;  pt1 = t;
-               gui->plugin->config.selected = hot_point;
-               gui->points->update(hot_point);
+               gui->point_list->update(hot_point);
        }
        gui->send_configure_change();
        return 1;
@@ -584,14 +544,14 @@ CriKeyPointDn::~CriKeyPointDn()
 
 int CriKeyPointDn::handle_event()
 {
-       int n = gui->plugin->config.points.size();
-       int hot_point = gui->points->get_selection_number(0, 0);
-       if( n > 1 && hot_point < n-1 ) {
-               CriKeyPoint *&pt0 = gui->plugin->config.points[hot_point];
-               CriKeyPoint *&pt1 = gui->plugin->config.points[++hot_point];
+       CriKeyPoints &points = gui->plugin->config.points;
+       int sz = points.size();
+       int hot_point = gui->point_list->get_selection_number(0, 0);
+       if( sz > 1 && hot_point < sz-1 ) {
+               CriKeyPoint *&pt0 = points[hot_point];
+               CriKeyPoint *&pt1 = points[++hot_point];
                CriKeyPoint *t = pt0;  pt0 = pt1;  pt1 = t;
-               gui->plugin->config.selected = hot_point;
-               gui->points->update(hot_point);
+               gui->point_list->update(hot_point);
        }
        gui->send_configure_change();
        return 1;
@@ -631,7 +591,7 @@ CriKeyNewPoint::~CriKeyNewPoint()
 int CriKeyNewPoint::handle_event()
 {
        int k = plugin->new_point();
-       gui->points->update(k);
+       gui->point_list->update(k);
        gui->send_configure_change();
        return 1;
 }
@@ -647,32 +607,35 @@ CriKeyDelPoint::~CriKeyDelPoint()
 }
 int CriKeyDelPoint::handle_event()
 {
-       int hot_point = gui->points->get_selection_number(0, 0);
-       if( hot_point >= 0 && hot_point < gui->plugin->config.points.size() ) {
+       int hot_point = gui->point_list->get_selection_number(0, 0);
+       CriKeyPoints &points = plugin->config.points;
+       if( hot_point >= 0 && hot_point < points.size() ) {
                plugin->config.del_point(hot_point);
-               if( !plugin->config.points.size() ) plugin->new_point();
-               int n = gui->plugin->config.points.size();
-               if( hot_point >= n && hot_point > 0 ) --hot_point;
-               gui->plugin->config.selected = hot_point;
-               gui->points->update(hot_point);
+               if( !points.size() ) plugin->new_point();
+               int sz = points.size();
+               if( hot_point >= sz && hot_point > 0 ) --hot_point;
+               gui->point_list->update(hot_point);
                gui->send_configure_change();
        }
        return 1;
 }
 
-CriKeyCurPoint::CriKeyCurPoint(CriKeyWindow *gui, CriKey *plugin, int x, int y)
- : BC_Title(x, y, "")
+CriKeyReset::CriKeyReset(CriKeyWindow *gui, CriKey *plugin, int x, int y)
+ : BC_GenericButton(x, y, _("Reset"))
 {
        this->gui = gui;
        this->plugin = plugin;
 }
-CriKeyCurPoint::~CriKeyCurPoint()
+CriKeyReset::~CriKeyReset()
 {
 }
-void CriKeyCurPoint::update(int n)
+int CriKeyReset::handle_event()
 {
-       char string[BCSTRLEN];
-       sprintf(string, _("Selected: %d   "), n);
-       BC_Title::update(string);
+       CriKeyPoints &points = plugin->config.points;
+       points.remove_all_objects();
+       plugin->new_point();
+       gui->point_list->update(0);
+       gui->send_configure_change();
+       return 1;
 }
 
index 01ab8d5a8b54ea13dacedd73c31e78e451e13a75..22188eec1bdd1fb60afd7e9d846dc424f7a64ec2 100644 (file)
 #define __CRIKEYWINDOW_H__
 
 #include "guicast.h"
-#include "colorpicker.h"
 
 class CriKey;
 class CriKeyWindow;
 class CriKeyNum;
 class CriKeyPointX;
 class CriKeyPointY;
-class CriKeyColorButton;
-class CriKeyColorPicker;
 class CriKeyDrawMode;
 class CriKeyDrawModeItem;
 class CriKeyThreshold;
 class CriKeyDrag;
-class CriKeyPoints;
+class CriKeyPointList;
 class CriKeyNewPoint;
 class CriKeyDelPoint;
 class CriKeyPointUp;
 class CriKeyPointDn;
-class CriKeyCurPoint;
+class CriKeyReset;
 
 
 class CriKeyNum : public BC_TumbleTextBox
@@ -70,28 +67,6 @@ public:
        int handle_event();
 };
 
-class CriKeyColorButton : public BC_GenericButton
-{
-public:
-       CriKeyColorButton(CriKeyWindow *gui, int x, int y);
-
-       int handle_event();
-       CriKeyWindow *gui;
-};
-
-class CriKeyColorPicker : public ColorPicker
-{
-public:
-       CriKeyColorPicker(CriKeyColorButton *color_button);
-
-       void start(int color);
-       int handle_new_color(int color, int alpha);
-       void handle_done_event(int result);
-
-       CriKeyColorButton *color_button;
-       int color, orig_color;
-};
-
 class CriKeyDrawMode : public BC_PopupMenu
 {
        const char *draw_modes[DRAW_MODES];
@@ -131,24 +106,25 @@ public:
        CriKeyWindow *gui;
 };
 
-class CriKeyPoints : public BC_ListBox
+class CriKeyPointList : public BC_ListBox
 {
 public:
-       CriKeyPoints(CriKeyWindow *gui, CriKey *plugin, int x, int y);
-       ~CriKeyPoints();
+       CriKeyPointList(CriKeyWindow *gui, CriKey *plugin, int x, int y);
+       ~CriKeyPointList();
 
        int handle_event();
        int selection_changed();
        int column_resize_event();
        ArrayList<BC_ListBoxItem*> cols[PT_SZ];
        void clear();
-       void new_point(const char *ep, const char *xp, const char *yp, const char *tp);
+       void new_point(const char *ep, const char *xp, const char *yp,
+               const char *tp, const char *tag);
        void del_point(int i);
        void set_point(int i, int c, float v);
        void set_point(int i, int c, const char *cp);
        int set_selected(int k);
-       void update_list();
        void update(int k);
+       void update_list(int k);
 
 
        CriKeyWindow *gui;
@@ -203,18 +179,19 @@ public:
        CriKeyWindow *gui;
 };
 
-class CriKeyCurPoint : public BC_Title
+class CriKeyReset : public BC_GenericButton
 {
 public:
-       CriKeyCurPoint(CriKeyWindow *gui, CriKey *plugin, int x, int y);
-       ~CriKeyCurPoint();
+       CriKeyReset(CriKeyWindow *gui, CriKey *plugin, int x, int y);
+       ~CriKeyReset();
 
-       void update(int n);
+       int handle_event();
 
        CriKey *plugin;
        CriKeyWindow *gui;
 };
 
+
 class CriKeyWindow : public PluginClientWindow
 {
 public:
@@ -222,7 +199,6 @@ public:
        ~CriKeyWindow();
 
        void create_objects();
-       void update_color(int color);
        void update_gui();
        void start_color_thread();
        int grab_event(XEvent *event);
@@ -234,9 +210,6 @@ public:
        CriKeyThreshold *threshold;
        CriKeyDrawMode *draw_mode;
 
-       CriKeyColorButton *color_button;
-       CriKeyColorPicker *color_picker;
-       int color_x, color_y;
        BC_Title *title_x, *title_y;
        CriKeyPointX *point_x;
        CriKeyPointY *point_y;
@@ -244,11 +217,12 @@ public:
        CriKeyDelPoint *del_point;
        CriKeyPointUp *point_up;
        CriKeyPointDn *point_dn;
-       CriKeyCurPoint *cur_point;
        int dragging, pending_config;
        float last_x, last_y;
        CriKeyDrag *drag;
-       CriKeyPoints *points;
+       CriKeyPointList *point_list;
+       CriKeyReset *reset;
+       BC_Title *notes;
 };
 
 #endif