another sketcher rework, awdw del key short cuts
authorGood Guy <good1.2guy@gmail.com>
Wed, 21 Nov 2018 01:35:38 +0000 (18:35 -0700)
committerGood Guy <good1.2guy@gmail.com>
Wed, 21 Nov 2018 01:35:38 +0000 (18:35 -0700)
cinelerra-5.1/cinelerra/awindowgui.C
cinelerra-5.1/cinelerra/colorpicker.C
cinelerra-5.1/plugins/sketcher/sketcher.C
cinelerra-5.1/plugins/sketcher/sketcher.h
cinelerra-5.1/plugins/sketcher/sketcherwindow.C
cinelerra-5.1/plugins/sketcher/sketcherwindow.h

index f4a2474b3c2d1c3b6581d2fd6417e15983ca2802..2ef637964754a6f119ea87ef384379e7e39aff65 100644 (file)
 #include "asset.h"
 #include "assetedit.h"
 #include "assetpopup.h"
 #include "asset.h"
 #include "assetedit.h"
 #include "assetpopup.h"
+#include "assetremove.h"
 #include "assets.h"
 #include "audiodevice.h"
 #include "assets.h"
 #include "audiodevice.h"
-#include "awindowgui.h"
 #include "awindow.h"
 #include "awindow.h"
+#include "awindowgui.h"
 #include "bccmodels.h"
 #include "bcsignals.h"
 #include "bchash.h"
 #include "bccmodels.h"
 #include "bcsignals.h"
 #include "bchash.h"
@@ -1467,14 +1468,26 @@ int AWindowGUI::keypress_event()
        case 'v':
                return cycle_assetlist_format();
        case DELETE:
        case 'v':
                return cycle_assetlist_format();
        case DELETE:
-               if( shift_down() ) {
+               if( shift_down() && ctrl_down() ) {
                        PluginServer* plugin = selected_plugin();
                        if( !plugin ) break;
                        remove_plugin = new AWindowRemovePlugin(awindow, plugin);
                        unlock_window();
                        remove_plugin->start();
                        PluginServer* plugin = selected_plugin();
                        if( !plugin ) break;
                        remove_plugin = new AWindowRemovePlugin(awindow, plugin);
                        unlock_window();
                        remove_plugin->start();
-                       lock_window();
+                       lock_window("AWindowGUI::keypress_event 1");
+                       return 1;
                }
                }
+               collect_assets();
+               if( shift_down() ) {
+                       mwindow->awindow->asset_remove->start();
+                       return 1;
+               }
+               unlock_window();
+               mwindow->remove_assets_from_project(1, 1,
+                       mwindow->session->drag_assets,
+                       mwindow->session->drag_clips);
+               lock_window("AWindowGUI::keypress_event 2");
+               return 1;
        }
        return 0;
 }
        }
        return 0;
 }
index 097bcec8949aa7bbc1b5b3f40a9ae5cf217a5f0d..f3e87b35fc42d586f9c39f03ef3424ac35b6f5ca 100644 (file)
@@ -302,8 +302,10 @@ void ColorWindow::update_display()
        yuv_v->update(yuv.v);
        hex_box->update();
 
        yuv_v->update(yuv.v);
        hex_box->update();
 
-       if( thread->do_alpha )
+       if( thread->do_alpha ) {
+               alpha->update(aph);
                aph_a->update(aph);
                aph_a->update(aph);
+       }
 }
 
 int ColorWindow::handle_event()
 }
 
 int ColorWindow::handle_event()
@@ -803,6 +805,7 @@ PaletteAlpha::~PaletteAlpha()
 int PaletteAlpha::handle_event()
 {
        window->aph = get_value();
 int PaletteAlpha::handle_event()
 {
        window->aph = get_value();
+       window->aph_a->update(window->aph);
        window->handle_event();
        return 1;
 }
        window->handle_event();
        return 1;
 }
index a954c7ca0c21d084668e48bd46267bccbd13835b..906980467729a76a626162aaa6d5fb840cd72c29 100644 (file)
@@ -37,7 +37,7 @@
 #include "language.h"
 #include "vframe.h"
 
 #include "language.h"
 #include "vframe.h"
 
-void SketcherPoint::init(int id, int pty, int x, int y)
+void SketcherPoint::init(int id, int pty, coord x, coord y)
 {
        this->id = id;  this->pty = pty;
        this->x = x;    this->y = y;
 {
        this->id = id;  this->pty = pty;
        this->x = x;    this->y = y;
@@ -46,7 +46,7 @@ SketcherPoint::SketcherPoint(int id)
 {
        init(id, PTY_LINE, 0, 0);
 }
 {
        init(id, PTY_LINE, 0, 0);
 }
-SketcherPoint::SketcherPoint(int id, int pty, int x, int y)
+SketcherPoint::SketcherPoint(int id, int pty, coord x, coord y)
 {
        init(id, pty, x, y);
 }
 {
        init(id, pty, x, y);
 }
@@ -61,8 +61,8 @@ int SketcherPoint::equivalent(SketcherPoint &that)
 {
        return this->id == that.id &&
                this->pty == that.pty &&
 {
        return this->id == that.id &&
                this->pty == that.pty &&
-               this->x == that.x &&
-               this->y == that.y ? 1 : 0;
+               EQUIV(this->x, that.x) &&
+               EQUIV(this->y, that.y) ? 1 : 0;
 }
 void SketcherPoint::copy_from(SketcherPoint &that)
 {
 }
 void SketcherPoint::copy_from(SketcherPoint &that)
 {
@@ -86,15 +86,15 @@ void SketcherPoint::read_data(FileXML &input)
 {
        id = atoi(input.tag.get_title() + 6);
        pty = input.tag.get_property("TYPE", PTY_OFF);
 {
        id = atoi(input.tag.get_title() + 6);
        pty = input.tag.get_property("TYPE", PTY_OFF);
-       x = input.tag.get_property("X", 0.f);
-       y = input.tag.get_property("Y", 0.f);
+       x = input.tag.get_property("X", (coord)0);
+       y = input.tag.get_property("Y", (coord)0);
        bclamp(pty, 0, PTY_SZ-1);
 }
 
        bclamp(pty, 0, PTY_SZ-1);
 }
 
-void SketcherCurve::init(int id, int pen, int radius, int color)
+void SketcherCurve::init(int id, int pen, int width, int color)
 {
        this->id = id;
 {
        this->id = id;
-       this->radius = radius;
+       this->width = width;
        this->pen = pen;
        this->color = color;
 }
        this->pen = pen;
        this->color = color;
 }
@@ -102,9 +102,9 @@ SketcherCurve::SketcherCurve(int id)
 {
        init(id, 1, PTY_LINE, CV_COLOR);
 }
 {
        init(id, 1, PTY_LINE, CV_COLOR);
 }
-SketcherCurve::SketcherCurve(int id, int pen, int radius, int color)
+SketcherCurve::SketcherCurve(int id, int pen, int width, int color)
 {
 {
-       init(id, pen, radius, color);
+       init(id, pen, width, color);
 }
 SketcherCurve::~SketcherCurve()
 {
 }
 SketcherCurve::~SketcherCurve()
 {
@@ -117,7 +117,7 @@ int SketcherCurve::equivalent(SketcherCurve &that)
 {
        if( this->id != that.id ) return 0;
        if( this->pen != that.pen ) return 0;
 {
        if( this->id != that.id ) return 0;
        if( this->pen != that.pen ) return 0;
-       if( this->radius != that.radius ) return 0;
+       if( this->width != that.width ) return 0;
        if( this->color != that.color ) return 0;
        int n = this->points.size();
        if( n != that.points.size() ) return 0;
        if( this->color != that.color ) return 0;
        int n = this->points.size();
        if( n != that.points.size() ) return 0;
@@ -130,7 +130,7 @@ void SketcherCurve::copy_from(SketcherCurve &that)
 {
        this->id = that.id;
        this->pen = that.pen;
 {
        this->id = that.id;
        this->pen = that.pen;
-       this->radius = that.radius;
+       this->width = that.width;
        this->color = that.color;
        int m = points.size(), n = that.points.size();
        while( m > n ) points.remove_object_number(--m);
        this->color = that.color;
        int m = points.size(), n = that.points.size();
        while( m > n ) points.remove_object_number(--m);
@@ -144,7 +144,7 @@ void SketcherCurve::save_data(FileXML &output)
        sprintf(curve,"/CURVE_%d",id);
        output.tag.set_title(curve+1);
        output.tag.set_property("PEN", pen);
        sprintf(curve,"/CURVE_%d",id);
        output.tag.set_title(curve+1);
        output.tag.set_property("PEN", pen);
-       output.tag.set_property("RADIUS", radius);
+       output.tag.set_property("RADIUS", width);
        output.tag.set_property("COLOR", color);
        output.append_tag();
        output.append_newline();
        output.tag.set_property("COLOR", color);
        output.append_tag();
        output.append_newline();
@@ -158,12 +158,12 @@ void SketcherCurve::read_data(FileXML &input)
 {
        id = atoi(input.tag.get_title() + 6);
        pen = input.tag.get_property("PEN", PTY_OFF);
 {
        id = atoi(input.tag.get_title() + 6);
        pen = input.tag.get_property("PEN", PTY_OFF);
-       radius = input.tag.get_property("RADIUS", 1.);
+       width = input.tag.get_property("RADIUS", 1.);
        color = input.tag.get_property("COLOR", CV_COLOR);
        bclamp(pen, 0, PEN_SZ-1);
 }
 
        color = input.tag.get_property("COLOR", CV_COLOR);
        bclamp(pen, 0, PEN_SZ-1);
 }
 
-int Sketcher::new_curve(int pen, int radius, int color)
+int Sketcher::new_curve(int pen, int width, int color)
 {
        SketcherCurves &curves = config.curves;
        int k = curves.size(), id = 1;
 {
        SketcherCurves &curves = config.curves;
        int k = curves.size(), id = 1;
@@ -171,7 +171,7 @@ int Sketcher::new_curve(int pen, int radius, int color)
                int n = config.curves[i]->id;
                if( n >= id ) id = n + 1;
        }
                int n = config.curves[i]->id;
                if( n >= id ) id = n + 1;
        }
-       SketcherCurve *cv = new SketcherCurve(id, pen, radius, color);
+       SketcherCurve *cv = new SketcherCurve(id, pen, width, color);
        curves.append(cv);
        config.cv_selected = k;
        return k;
        curves.append(cv);
        config.cv_selected = k;
        return k;
@@ -182,7 +182,7 @@ int Sketcher::new_curve()
        return new_curve(PEN_XLANT, 1, CV_COLOR);
 }
 
        return new_curve(PEN_XLANT, 1, CV_COLOR);
 }
 
-int Sketcher::new_point(SketcherCurve *cv, int pty, int x, int y, int idx)
+int Sketcher::new_point(SketcherCurve *cv, int pty, coord x, coord y, int idx)
 {
        int id = 1;
        for( int i=cv->points.size(); --i>=0; ) {
 {
        int id = 1;
        for( int i=cv->points.size(); --i>=0; ) {
@@ -203,12 +203,12 @@ int Sketcher::new_point(int idx)
                return -1;
        SketcherCurve *cv = config.curves[ci];
        EDLSession *session = get_edlsession();
                return -1;
        SketcherCurve *cv = config.curves[ci];
        EDLSession *session = get_edlsession();
-       int x = !session ? 0.f : session->output_w / 2.f;
-       int y = !session ? 0.f : session->output_h / 2.f;
+       coord x = !session ? 0.f : session->output_w / 2.f;
+       coord y = !session ? 0.f : session->output_h / 2.f;
        return new_point(cv, PTY_LINE, x, y, idx);
 }
 
        return new_point(cv, PTY_LINE, x, y, idx);
 }
 
-double SketcherCurve::nearest_point(int &pi, float x, float y)
+double SketcherCurve::nearest_point(int &pi, coord x, coord y)
 {
        pi = -1;
        double dist = DBL_MAX;
 {
        pi = -1;
        double dist = DBL_MAX;
@@ -220,7 +220,7 @@ double SketcherCurve::nearest_point(int &pi, float x, float y)
        return pi >= 0 ? dist : -1.;
 }
 
        return pi >= 0 ? dist : -1.;
 }
 
-double SketcherConfig::nearest_point(int &ci, int &pi, float x, float y)
+double SketcherConfig::nearest_point(int &ci, int &pi, coord x, coord y)
 {
        double dist = DBL_MAX;
        ci = -1;  pi = -1;
 {
        double dist = DBL_MAX;
        ci = -1;  pi = -1;
@@ -293,17 +293,29 @@ void SketcherConfig::interpolate(SketcherConfig &prev, SketcherConfig &next,
                if( k >= 0 ) {
                        cv->id = pcv->id;
                        cv->pen = pcv->pen;
                if( k >= 0 ) {
                        cv->id = pcv->id;
                        cv->pen = pcv->pen;
-                       cv->radius = pcv->radius;
-                       cv->color = pcv->color;
+                       cv->width = pcv->width == ncv->width ? pcv->width :
+                               pcv->width*prev_scale + ncv->width*next_scale + 0.5;
+                       int pr =  (pcv->color>>16)&0xff, nr =  (ncv->color>>16)&0xff;
+                       int pg =  (pcv->color>> 8)&0xff, ng =  (ncv->color>> 8)&0xff;
+                       int pb =  (pcv->color>> 0)&0xff, nb =  (ncv->color>> 0)&0xff;
+                       int pa = (~pcv->color>>24)&0xff, na = (~ncv->color>>24)&0xff;
+                       int r = pr == nr ? pr : pr*prev_scale + nr*next_scale + 0.5;
+                       int g = pg == ng ? pg : pg*prev_scale + ng*next_scale + 0.5;
+                       int b = pb == nb ? pb : pb*prev_scale + nb*next_scale + 0.5;
+                       int a = pa == na ? pa : pa*prev_scale + na*next_scale + 0.5;
+                       bclamp(r,0,255); bclamp(g,0,255); bclamp(b,0,255); bclamp(a,0,255);
+                       cv->color = (~a<<24) | (r<<16) | (g<<8) | (b<<0);
                        int prev_pt_sz = pcv->points.size(), next_pt_sz = ncv->points.size();
                        for( int j=0; j<prev_pt_sz; ++j ) {
                                SketcherPoint &pt = *pcv->points[j], *nt = 0;
                                k = next_pt_sz;  // associated by id in next
                                while( --k >= 0 && pt.id != (nt=ncv->points[k])->id );
                        int prev_pt_sz = pcv->points.size(), next_pt_sz = ncv->points.size();
                        for( int j=0; j<prev_pt_sz; ++j ) {
                                SketcherPoint &pt = *pcv->points[j], *nt = 0;
                                k = next_pt_sz;  // associated by id in next
                                while( --k >= 0 && pt.id != (nt=ncv->points[k])->id );
-                               int x = pt.x, y = pt.y;
+                               coord x = pt.x, y = pt.y;
                                if( k >= 0 ) {
                                if( k >= 0 ) {
-                                       x = x * prev_scale + nt->x * next_scale;
-                                       y = y * prev_scale + nt->y * next_scale;
+                                       if( x != nt->x )
+                                               x = x * prev_scale + nt->x * next_scale;
+                                       if( y != nt->y )
+                                               y = y * prev_scale + nt->y * next_scale;
                                }
                                cv->points.append(new SketcherPoint(pt.id, pt.pty, x, y));
                        }
                                }
                                cv->points.append(new SketcherPoint(pt.id, pt.pty, x, y));
                        }
@@ -472,10 +484,10 @@ int SketcherPenXlant::draw_pixel(int x, int y)
 SketcherVPen *SketcherCurve::new_vpen(VFrame *out)
 {
        switch( pen ) {
 SketcherVPen *SketcherCurve::new_vpen(VFrame *out)
 {
        switch( pen ) {
-       case PEN_SQUARE: return new SketcherPenSquare(out, radius);
-       case PEN_PLUS:   return new SketcherPenPlus(out, radius);
-       case PEN_SLANT:  return new SketcherPenSlant(out, radius);
-       case PEN_XLANT:  return new SketcherPenXlant(out, radius);
+       case PEN_SQUARE: return new SketcherPenSquare(out, width);
+       case PEN_PLUS:   return new SketcherPenPlus(out, width);
+       case PEN_SLANT:  return new SketcherPenSlant(out, width);
+       case PEN_XLANT:  return new SketcherPenXlant(out, width);
        }
        return 0;
 }
        }
        return 0;
 }
@@ -756,7 +768,7 @@ void SketcherPoints::dump()
 {
        for( int i=0; i<size(); ++i ) {
                SketcherPoint *pt = get(i);
 {
        for( int i=0; i<size(); ++i ) {
                SketcherPoint *pt = get(i);
-               printf("  Pt %d, id=%d, pty=%s, x=%d, y=%d\n",
+               printf("  Pt %d, id=%d, pty=%s, x=%0.1f, y=%0.1f\n",
                        i, pt->id, pt_type[pt->pty], pt->x, pt->y);
        }
 }
                        i, pt->id, pt_type[pt->pty], pt->x, pt->y);
        }
 }
@@ -764,8 +776,8 @@ void SketcherCurves::dump()
 {
        for( int i=0; i<size(); ++i ) {
                SketcherCurve *cv = get(i);
 {
        for( int i=0; i<size(); ++i ) {
                SketcherCurve *cv = get(i);
-               printf("Curve %d, id=%d, pen=%s, r=%d, color=%02x%02x%02x, %d points\n",
-                       i, cv->id, cv_pen[cv->pen], cv->radius,
+               printf("Curve %d, id=%d, pen=%s, r=%d, color=%02x%02x%02x%02x, %d points\n",
+                       i, cv->id, cv_pen[cv->pen], cv->width, (~cv->color>>24)&0xff,
                        (cv->color>>16)&0xff, (cv->color>>8)&0xff, (cv->color>>0)&0xff,
                        cv->points.size());
                cv->points.dump();
                        (cv->color>>16)&0xff, (cv->color>>8)&0xff, (cv->color>>0)&0xff,
                        cv->points.size());
                cv->points.dump();
index 443e8e9134abc8f25826566236a713233d7735a9..a40b17b068163faf9936572a0f1d665efe472867 100644 (file)
@@ -34,9 +34,10 @@ class Sketcher;
 #define CV_COLOR WHITE
 
 enum { PT_ID, PT_TY, PT_X, PT_Y, PT_SZ };
 #define CV_COLOR WHITE
 
 enum { PT_ID, PT_TY, PT_X, PT_Y, PT_SZ };
-enum { CV_ID, CV_RAD, CV_PEN, CV_CLR, CV_SZ };
+enum { CV_ID, CV_RAD, CV_PEN, CV_CLR, CV_ALP, CV_SZ };
 enum { PTY_OFF, PTY_LINE, PTY_CURVE, PTY_FILL, PTY_SZ };
 enum { PEN_OFF, PEN_SQUARE, PEN_PLUS, PEN_SLANT, PEN_XLANT, PEN_SZ };
 enum { PTY_OFF, PTY_LINE, PTY_CURVE, PTY_FILL, PTY_SZ };
 enum { PEN_OFF, PEN_SQUARE, PEN_PLUS, PEN_SLANT, PEN_XLANT, PEN_SZ };
+typedef float coord;
 
 class SketcherVPen : public VFrame
 {
 
 class SketcherVPen : public VFrame
 {
@@ -56,6 +57,14 @@ public:
        }
        ~SketcherVPen() { delete [] msk; }
 
        }
        ~SketcherVPen() { delete [] msk; }
 
+       void draw_line(float x1, float y1, float x2, float y2) {
+               VFrame::draw_line(int(x1+.5f),int(y1+.5f), int(x2+.5f),int(y2+.5f));
+       }
+       void draw_smooth(float x1, float y1, float x2, float y2, float x3, float y3) {
+               VFrame::draw_smooth(int(x1+.5f),int(y1+.5f),
+                       int(x2+.5f),int(y2+.5f), int(x3+.5f),int(y3+.5f));
+       }
+
        virtual int draw_pixel(int x, int y) = 0;
 };
 
        virtual int draw_pixel(int x, int y) = 0;
 };
 
@@ -89,10 +98,10 @@ class SketcherPoint
 {
 public:
        int id, pty;
 {
 public:
        int id, pty;
-       int x, y;
+       coord x, y;
 
 
-       void init(int id, int pty, int x, int y);
-       SketcherPoint(int id, int pty, int x, int y);
+       void init(int id, int pty, coord x, coord y);
+       SketcherPoint(int id, int pty, coord x, coord y);
        SketcherPoint(int id=-1);
        SketcherPoint(SketcherPoint &pt);
        ~SketcherPoint();
        SketcherPoint(int id=-1);
        SketcherPoint(SketcherPoint &pt);
        ~SketcherPoint();
@@ -114,13 +123,13 @@ public:
 class SketcherCurve
 {
 public:
 class SketcherCurve
 {
 public:
-       int id, pen, radius, color;
+       int id, pen, width, color;
        static const char *pens[PEN_SZ];
 
        SketcherPoints points;
 
        static const char *pens[PEN_SZ];
 
        SketcherPoints points;
 
-       void init(int id, int pen, int radius, int color);
-       SketcherCurve(int id, int pen, int radius, int color);
+       void init(int id, int pen, int width, int color);
+       SketcherCurve(int id, int pen, int width, int color);
        SketcherCurve(int id=-1);
        ~SketcherCurve();
        SketcherCurve(SketcherCurve &cv);
        SketcherCurve(int id=-1);
        ~SketcherCurve();
        SketcherCurve(SketcherCurve &cv);
@@ -128,7 +137,7 @@ public:
        void copy_from(SketcherCurve &that);
        void save_data(FileXML &output);
        void read_data(FileXML &input);
        void copy_from(SketcherCurve &that);
        void save_data(FileXML &output);
        void read_data(FileXML &input);
-       double nearest_point(int &pi, float x, float y);
+       double nearest_point(int &pi, coord x, coord y);
 
        SketcherVPen *new_vpen(VFrame *out);
        void draw(VFrame *img);
 
        SketcherVPen *new_vpen(VFrame *out);
        void draw(VFrame *img);
@@ -152,7 +161,7 @@ public:
        void copy_from(SketcherConfig &that);
        void interpolate(SketcherConfig &prev, SketcherConfig &next,
                long prev_frame, long next_frame, long current_frame);
        void copy_from(SketcherConfig &that);
        void interpolate(SketcherConfig &prev, SketcherConfig &next,
                long prev_frame, long next_frame, long current_frame);
-       double nearest_point(int &ci, int &pi, float x, float y);
+       double nearest_point(int &ci, int &pi, coord x, coord y);
        void limits();
        void dump();
 
        void limits();
        void dump();
 
@@ -170,9 +179,9 @@ public:
        void update_gui();
        void save_data(KeyFrame *keyframe);
        void read_data(KeyFrame *keyframe);
        void update_gui();
        void save_data(KeyFrame *keyframe);
        void read_data(KeyFrame *keyframe);
-       int new_curve(int pen, int radius, int color);
+       int new_curve(int pen, int width, int color);
        int new_curve();
        int new_curve();
-       int new_point(SketcherCurve *cv, int pty, int x, int y, int idx=-1);
+       int new_point(SketcherCurve *cv, int pty, coord x, coord y, int idx=-1);
        int new_point(int idx=-1);
        int process_realtime(VFrame *input, VFrame *output);
        static void draw_point(VFrame *vfrm, SketcherPoint *pt, int color, int d);
        int new_point(int idx=-1);
        int process_realtime(VFrame *input, VFrame *output);
        static void draw_point(VFrame *vfrm, SketcherPoint *pt, int color, int d);
index 76bd8d8fa5cf00a310c7dd40bad1b8fee91f0d19..bd2eaa9f58934a76a60b22372f90ce5deae6e25b 100644 (file)
@@ -164,7 +164,7 @@ SketcherCurveColorPicker::SketcherCurveColorPicker(SketcherWindow *gui, Sketcher
 {
        this->gui = gui;
        this->color_button = color_button;
 {
        this->gui = gui;
        this->color_button = color_button;
-       this->color = 0;
+       this->color = CV_COLOR;
        color_update = new SketcherCurveColorThread(this);
 }
 
        color_update = new SketcherCurveColorThread(this);
 }
 
@@ -175,7 +175,9 @@ SketcherCurveColorPicker::~SketcherCurveColorPicker()
 
 void SketcherCurveColorPicker::start(int color)
 {
 
 void SketcherCurveColorPicker::start(int color)
 {
-       start_window(color & 0xffffff, ((~color>>24)&0xff), 1);
+       this->color = color;
+       int alpha = (~color>>24) & 0xff;
+       start_window(color & 0xffffff, alpha, 1);
        color_update->start();
 }
 
        color_update->start();
 }
 
@@ -259,21 +261,31 @@ void SketcherCurveColorThread::run()
 }
 
 
 }
 
 
-SketcherNum::SketcherNum(SketcherWindow *gui, int x, int y, int output,
-               int mn, int mx)
- : BC_TumbleTextBox(gui, output, mn, mx, x, y, 64)
+SketcherCoord::SketcherCoord(SketcherWindow *gui, int x, int y,
+               coord output, coord mn, coord mx)
+ : BC_TumbleTextBox(gui, output, mn, mx, x, y, 64, 1)
 {
        this->gui = gui;
        set_increment(1);
 }
 {
        this->gui = gui;
        set_increment(1);
 }
+SketcherCoord::~SketcherCoord()
+{
+}
 
 
+SketcherNum::SketcherNum(SketcherWindow *gui, int x, int y,
+               int output, int mn, int mx)
+ : BC_TumbleTextBox(gui, output, mn, mx, x, y, 54)
+{
+       this->gui = gui;
+       set_increment(1);
+}
 SketcherNum::~SketcherNum()
 {
 }
 
 int SketcherPointX::handle_event()
 {
 SketcherNum::~SketcherNum()
 {
 }
 
 int SketcherPointX::handle_event()
 {
-       if( !SketcherNum::handle_event() ) return 0;
+       if( !SketcherCoord::handle_event() ) return 0;
        SketcherConfig &config = gui->plugin->config;
        int ci = config.cv_selected;
        if( ci >= 0 && ci < config.curves.size() ) {
        SketcherConfig &config = gui->plugin->config;
        int ci = config.cv_selected;
        if( ci >= 0 && ci < config.curves.size() ) {
@@ -282,7 +294,7 @@ int SketcherPointX::handle_event()
                int pi = config.pt_selected;
                SketcherPoints &points = cv->points;
                if( pi >= 0 && pi < points.size() ) {
                int pi = config.pt_selected;
                SketcherPoints &points = cv->points;
                if( pi >= 0 && pi < points.size() ) {
-                       int v = atoi(get_text());
+                       coord v = atof(get_text());
                        points[pi]->x = v;
                        point_list->set_point(pi, PT_X, v);
                        point_list->update_list(pi);
                        points[pi]->x = v;
                        point_list->set_point(pi, PT_X, v);
                        point_list->update_list(pi);
@@ -293,7 +305,7 @@ int SketcherPointX::handle_event()
 }
 int SketcherPointY::handle_event()
 {
 }
 int SketcherPointY::handle_event()
 {
-       if( !SketcherNum::handle_event() ) return 0;
+       if( !SketcherCoord::handle_event() ) return 0;
        SketcherConfig &config = gui->plugin->config;
        int ci = config.cv_selected;
        if( ci >= 0 && ci < config.curves.size() ) {
        SketcherConfig &config = gui->plugin->config;
        int ci = config.cv_selected;
        if( ci >= 0 && ci < config.curves.size() ) {
@@ -302,7 +314,7 @@ int SketcherPointY::handle_event()
                int pi = config.pt_selected;
                SketcherPoints &points = cv->points;
                if( pi >= 0 && pi < points.size() ) {
                int pi = config.pt_selected;
                SketcherPoints &points = cv->points;
                if( pi >= 0 && pi < points.size() ) {
-                       int v = atoi(get_text());
+                       coord v = atof(get_text());
                        points[pi]->y = v;
                        point_list->set_point(pi, PT_Y, v);
                        point_list->update_list(pi);
                        points[pi]->y = v;
                        point_list->set_point(pi, PT_Y, v);
                        point_list->update_list(pi);
@@ -312,7 +324,28 @@ int SketcherPointY::handle_event()
        return 1;
 }
 
        return 1;
 }
 
-int SketcherCurveRadius::handle_event()
+int SketcherPointId::handle_event()
+{
+       if( !SketcherNum::handle_event() ) return 0;
+       SketcherConfig &config = gui->plugin->config;
+       int ci = config.cv_selected;
+       if( ci >= 0 && ci < config.curves.size() ) {
+               SketcherCurve *cv = config.curves[ci];
+               SketcherPointList *point_list = gui->point_list;
+               int pi = config.pt_selected;
+               SketcherPoints &points = cv->points;
+               if( pi >= 0 && pi < points.size() ) {
+                       int id = atoi(get_text());
+                       points[pi]->id = id;
+                       point_list->set_point(pi, PT_ID, id);
+                       point_list->update_list(pi);
+                       gui->send_configure_change();
+               }
+       }
+       return 1;
+}
+
+int SketcherCurveWidth::handle_event()
 {
        if( !SketcherNum::handle_event() ) return 0;
        SketcherConfig &config = gui->plugin->config;
 {
        if( !SketcherNum::handle_event() ) return 0;
        SketcherConfig &config = gui->plugin->config;
@@ -320,7 +353,7 @@ int SketcherCurveRadius::handle_event()
        if( ci >= 0 && ci < config.curves.size() ) {
                SketcherCurve *cv = config.curves[ci];
                int v = atoi(get_text());
        if( ci >= 0 && ci < config.curves.size() ) {
                SketcherCurve *cv = config.curves[ci];
                int v = atoi(get_text());
-               cv->radius = v;
+               cv->width = v;
                gui->curve_list->update(ci);
                gui->send_configure_change();
        }
                gui->curve_list->update(ci);
                gui->send_configure_change();
        }
@@ -334,21 +367,32 @@ SketcherWindow::SketcherWindow(Sketcher *plugin)
        this->plugin = plugin;
        this->title_pen = 0;  this->curve_pen = 0;
        this->title_color = 0; this->curve_color = 0;
        this->plugin = plugin;
        this->title_pen = 0;  this->curve_pen = 0;
        this->title_color = 0; this->curve_color = 0;
-       this->color_picker = 0; this->new_points = 0;
+       this->color_picker = 0; this->drag = 0;
        this->new_curve = 0;  this->del_curve = 0;
        this->curve_up = 0;   this->curve_dn = 0;
        this->title_x = 0;    this->point_x = 0;
        this->title_y = 0;    this->point_y = 0;
        this->new_curve = 0;  this->del_curve = 0;
        this->curve_up = 0;   this->curve_dn = 0;
        this->title_x = 0;    this->point_x = 0;
        this->title_y = 0;    this->point_y = 0;
+       this->title_id = 0;   this->point_id = 0;
        this->new_point = 0;  this->del_point = 0;
        this->point_up = 0;   this->point_dn = 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->point_list = 0; this->pending_config = 0;
+       this->point_list = 0; this->notes0 = 0;
+       this->notes1 = 0;     this->notes2 = 0;
+
+       position = -1;
+       track_w = track_h -1;
+       cursor_x = cursor_y = -1;
+       output_x = output_y = -1;
+       last_x = last_y = -1;
+       projector_x = projector_y = projector_z = -1;
+       state = 0;  dragging = 0;
+       new_points = 0;
+       pending_motion = 0;
+       pending_config = 0;
 }
 
 SketcherWindow::~SketcherWindow()
 {
 }
 
 SketcherWindow::~SketcherWindow()
 {
-       delete curve_radius;
+       delete curve_width;
        delete point_x;
        delete point_y;
        delete color_picker;
        delete point_x;
        delete point_y;
        delete color_picker;
@@ -368,11 +412,11 @@ void SketcherWindow::create_objects()
        add_subwindow(reset_curves);    dy = bmax(dy,reset_curves->get_h());
        x1 += reset_curves->get_w() + 2*margin;
        const char *curve_text = _("Curve");
        add_subwindow(reset_curves);    dy = bmax(dy,reset_curves->get_h());
        x1 += reset_curves->get_w() + 2*margin;
        const char *curve_text = _("Curve");
-       title_radius = new BC_Title(x1, y, _("Width:"));
-       add_subwindow(title_radius);    dy = bmax(dy,title_radius->get_h());
-       x1 += title_radius->get_w() + margin;
-       curve_radius = new SketcherCurveRadius(this, x1, y, cv->radius);
-       curve_radius->create_objects();
+       title_width = new BC_Title(x1, y, _("Width:"));
+       add_subwindow(title_width);     dy = bmax(dy,title_width->get_h());
+       x1 += title_width->get_w() + margin;
+       curve_width = new SketcherCurveWidth(this, x1, y, cv->width);
+       curve_width->create_objects();
        y += dy + 2*margin;             dy = 0;
 
        x1 = get_w()-x - BC_Title::calculate_w(this, curve_text, LARGEFONT);
        y += dy + 2*margin;             dy = 0;
 
        x1 = get_w()-x - BC_Title::calculate_w(this, curve_text, LARGEFONT);
@@ -458,6 +502,9 @@ void SketcherWindow::create_objects()
        x1 += title_x->get_w() + margin;
        point_x = new SketcherPointX(this, x1, y, !pt ? 0.f : pt->x);
        point_x->create_objects();      dy = bmax(dy, point_x->get_h());
        x1 += title_x->get_w() + margin;
        point_x = new SketcherPointX(this, x1, y, !pt ? 0.f : pt->x);
        point_x->create_objects();      dy = bmax(dy, point_x->get_h());
+       x2 = x1 + point_x->get_w() + 2*margin;
+       title_id = new BC_Title(x2, y, _("ID:"));
+       add_subwindow(title_id);        dy = bmax(dy, title_id->get_h());
        y += dy + margin;  dy = 0;
 
        del_point = new SketcherDelPoint(this, plugin, x1=x, y);
        y += dy + margin;  dy = 0;
 
        del_point = new SketcherDelPoint(this, plugin, x1=x, y);
@@ -471,6 +518,8 @@ void SketcherWindow::create_objects()
        x1 += title_y->get_w() + margin;
        point_y = new SketcherPointY(this, x1, y, !pt ? 0.f : pt->y);
        point_y->create_objects();      dy = bmax(dy, point_y->get_h());
        x1 += title_y->get_w() + margin;
        point_y = new SketcherPointY(this, x1, y, !pt ? 0.f : pt->y);
        point_y->create_objects();      dy = bmax(dy, point_y->get_h());
+       point_id = new SketcherPointId(this, x2+10, y, !pt ? 0 : pt->id);
+       point_id->create_objects();     dy = bmax(dy, point_id->get_h());
        y += dy + margin + 5;
        point_list->update(pi);
 
        y += dy + margin + 5;
        point_list->update(pi);
 
@@ -504,11 +553,17 @@ void SketcherWindow::send_configure_change()
        plugin->send_configure_change();
 }
 
        plugin->send_configure_change();
 }
 
+
 int SketcherWindow::grab_event(XEvent *event)
 {
        int ret = do_grab_event(event);
 int SketcherWindow::grab_event(XEvent *event)
 {
        int ret = do_grab_event(event);
-       if( pending_config && !grab_event_count() )
-               send_configure_change();
+       if( !grab_event_count() ) {
+               if( pending_motion && grab_cursor_motion(&motion_event) )
+                       pending_config = 1;
+               if( pending_config )
+                       send_configure_change();
+       }
+       last_x = output_x;  last_y = output_y;
        return ret;
 }
 
        return ret;
 }
 
@@ -554,170 +609,195 @@ int SketcherWindow::do_grab_event(XEvent *event)
                dragging = 0;
                break;
        case MotionNotify:
                dragging = 0;
                break;
        case MotionNotify:
-               if( !dragging ) return 0;
-               break;
-       default:
+               if( dragging ) break;
+       default: // fall thru
                return 0;
        }
 
                return 0;
        }
 
-       SketcherConfig &config = plugin->config;
-       int ci = config.cv_selected;
-       if( ci < 0 || ci >= plugin->config.curves.size() )
-               return 1;
-
-       SketcherCurves &curves = config.curves;
-       SketcherCurve *cv = curves[ci];
-       SketcherPoints &points = cv->points;
-       int pi = config.pt_selected;
-
-       float cursor_x = cx, cursor_y = cy;
+       cursor_x = cx, cursor_y = cy;
        canvas->canvas_to_output(mwindow->edl, 0, cursor_x, cursor_y);
        canvas->canvas_to_output(mwindow->edl, 0, cursor_x, cursor_y);
-       int64_t position = plugin->get_source_position();
-       float projector_x, projector_y, projector_z;
+       position = plugin->get_source_position();
        Track *track = plugin->server->plugin->track;
        Track *track = plugin->server->plugin->track;
-       int track_w = track->track_w, track_h = track->track_h;
+       track_w = track->track_w;
+       track_h = track->track_h;
        track->automation->get_projector(
                &projector_x, &projector_y, &projector_z,
                position, PLAY_FORWARD);
        projector_x += mwindow->edl->session->output_w / 2;
        projector_y += mwindow->edl->session->output_h / 2;
        track->automation->get_projector(
                &projector_x, &projector_y, &projector_z,
                position, PLAY_FORWARD);
        projector_x += mwindow->edl->session->output_w / 2;
        projector_y += mwindow->edl->session->output_h / 2;
-       float output_x = (cursor_x - projector_x) / projector_z + track_w / 2;
-       float output_y = (cursor_y - projector_y) / projector_z + track_h / 2;
-       int state = event->xmotion.state;
+       output_x = (cursor_x - projector_x) / projector_z + track_w / 2;
+       output_y = (cursor_y - projector_y) / projector_z + track_h / 2;
+       state = event->xmotion.state;
 
        switch( event->type ) {
 
        switch( event->type ) {
-       case ButtonPress: {
-               int button_no = event->xbutton.button;
-               switch( button_no ) {
-               case LEFT_BUTTON: {
-                       if( (state & ShiftMask) ) { // create new point/string
-                               ++new_points;
-                               pi = plugin->new_point(cv, PTY_LINE, output_x, output_y, pi+1);
-                               point_list->update(pi);
-                               break;
-                       }
-                       SketcherPoint *pt = 0; // select point
-                       double dist = cv->nearest_point(pi, output_x,output_y);
-                       if( dist >= 0 ) {
-                               pt = points[pi];
-                               float px = (pt->x - track_w / 2) * projector_z + projector_x;
-                               float py = (pt->y - track_h / 2) * projector_z + projector_y;
-                               float pix = DISTANCE(px, py, cursor_x,cursor_y);
-                               if( (state & ControlMask) && pix >= HANDLE_W ) { pi = -1;  pt = 0; }
-                       }
-                       point_list->set_selected(pi);
-                       break; }
-               case RIGHT_BUTTON: {
-                       if( (state & ShiftMask) ) { // create new curve point
-                               ++new_points;
-                               pi = plugin->new_point(cv, PTY_CURVE,
-                                               output_x, output_y, pi+1);
-                               point_list->update(pi);
-                               break;
-                       }
-                       if( (state & AltMask) ) { // create new curve
-                               ci = plugin->new_curve(cv->pen, cv->radius, cv->color);
-                               curve_list->update(ci);
-                               point_list->update(-1);
-                               break;
-                       }
-                       SketcherPoint *pt = 0;
-                       double dist = config.nearest_point(ci, pi, output_x,output_y);
-                       if( dist >= 0 ) {
-                               pt = curves[ci]->points[pi];
-                               float px = (pt->x - track_w / 2) * projector_z + projector_x;
-                               float py = (pt->y - track_h / 2) * projector_z + projector_y;
-                               float pix = DISTANCE(px, py, cursor_x,cursor_y);
-                               if( (state & ControlMask) && pix >= HANDLE_W ) { ci = pi = -1;  pt = 0; }
-                       }
-                       if( pt ) {
-                               curve_list->update(ci);
-                               point_list->update(pi);
-                       }
-                       break; }
+       case ButtonPress:
+               pending_config = grab_button_press(event);
+               break;
+       case ButtonRelease:
+               new_points = 0;
+               break;
+       case MotionNotify:
+               memcpy(&motion_event, event, sizeof(motion_event));
+               pending_motion = 1;
+               break;
+       }
+
+       return 1;
+}
+
+int SketcherWindow::grab_button_press(XEvent *event)
+{
+       SketcherConfig &config = plugin->config;
+       int ci = config.cv_selected;
+       if( ci < 0 || ci >= plugin->config.curves.size() )
+               return 0;
+       SketcherCurves &curves = config.curves;
+       SketcherCurve *cv = curves[ci];
+       SketcherPoints &points = cv->points;
+       int pi = config.pt_selected;
+
+       int button_no = event->xbutton.button;
+       switch( button_no ) {
+       case LEFT_BUTTON: {
+               if( (state & ShiftMask) ) { // create new point/string
+                       ++new_points;
+                       pi = plugin->new_point(cv, PTY_LINE, output_x, output_y, pi+1);
+                       point_list->update(pi);
+                       break;
+               }
+               SketcherPoint *pt = 0; // select point
+               double dist = cv->nearest_point(pi, output_x,output_y);
+               if( dist >= 0 ) {
+                       pt = points[pi];
+                       Track *track = plugin->server->plugin->track;
+                       int track_w = track->track_w, track_h = track->track_h;
+                       float px = (pt->x - track_w / 2) * projector_z + projector_x;
+                       float py = (pt->y - track_h / 2) * projector_z + projector_y;
+                       float pix = DISTANCE(px, py, cursor_x,cursor_y);
+                       if( (state & ControlMask) && pix >= HANDLE_W ) { pi = -1;  pt = 0; }
                }
                }
+               point_list->set_selected(pi);
                break; }
                break; }
-       case MotionNotify: {
-               if( (state & ShiftMask) ) {  // string of points
-                       if( (state & (Button1Mask|Button3Mask)) ) {
-                               SketcherPoint *pt = pi >= 0 && pi < points.size() ? points[pi] : 0;
-                               if( pt ) {
-                                       float dist = DISTANCE(pt->x, pt->y, output_x, output_y);
-                                       if( dist < get_w()*0.1 ) break; // tolerance w/10
-                               }
-                               ++new_points;
-                               int pty = (state & Button1Mask) ? PTY_LINE : PTY_CURVE;
-                               pi = plugin->new_point(cv, pty, output_x, output_y, pi+1);
-                               point_list->update(pi);
-                       }
+       case RIGHT_BUTTON: {
+               if( (state & ShiftMask) ) { // create new curve point
+                       ++new_points;
+                       pi = plugin->new_point(cv, PTY_CURVE,
+                                       output_x, output_y, pi+1);
+                       point_list->update(pi);
                        break;
                }
                        break;
                }
-               if( (state & Button1Mask) ) {
-                       if( (state & ControlMask) ) { // drag selected point
-                               SketcherPoint *pt = pi >= 0 && pi < points.size() ? points[pi] : 0;
-                               if( pt ) {
-                                       point_list->set_point(pi, PT_X, pt->x = output_x);
-                                       point_list->set_point(pi, PT_Y, pt->y = output_y);
-                                       point_list->update_list(pi);
-                                       point_x->update(pt->x);
-                                       point_y->update(pt->y);
-                               }
-                               break;
+               if( (state & AltMask) ) { // create new curve
+                       ci = plugin->new_curve(cv->pen, cv->width, cv->color);
+                       curve_list->update(ci);
+                       point_list->update(-1);
+                       break;
+               }
+               SketcherPoint *pt = 0;
+               double dist = config.nearest_point(ci, pi, output_x,output_y);
+               if( dist >= 0 ) {
+                       pt = curves[ci]->points[pi];
+                       Track *track = plugin->server->plugin->track;
+                       int track_w = track->track_w, track_h = track->track_h;
+                       float px = (pt->x - track_w / 2) * projector_z + projector_x;
+                       float py = (pt->y - track_h / 2) * projector_z + projector_y;
+                       float pix = DISTANCE(px, py, cursor_x,cursor_y);
+                       if( (state & ControlMask) && pix >= HANDLE_W ) { ci = pi = -1;  pt = 0; }
+               }
+               if( pt ) {
+                       curve_list->update(ci);
+                       point_list->update(pi);
+               }
+               break; }
+       }
+       return 1;
+}
+
+int SketcherWindow::grab_cursor_motion(XEvent *event)
+{
+       pending_motion = 0;
+       SketcherConfig &config = plugin->config;
+       int ci = config.cv_selected;
+       if( ci < 0 || ci >= plugin->config.curves.size() )
+               return 0;
+       SketcherCurves &curves = config.curves;
+       SketcherCurve *cv = curves[ci];
+       SketcherPoints &points = cv->points;
+       int pi = config.pt_selected;
+
+       if( (state & ShiftMask) ) {  // string of points
+               if( (state & (Button1Mask|Button3Mask)) ) {
+                       SketcherPoint *pt = pi >= 0 && pi < points.size() ? points[pi] : 0;
+                       if( pt ) {
+                               float dist = DISTANCE(pt->x, pt->y, output_x, output_y);
+                               if( dist < get_w()*0.1 ) return 0; // tolerance w/10
                        }
                        }
-                       if( (state & AltMask) ) { // drag all curves
-                               int dx = round(output_x - last_x);
-                               int dy = round(output_y - last_y);
-                               for( int i=0; i<curves.size(); ++i ) {
-                                       SketcherCurve *crv = plugin->config.curves[i];
-                                       int pts = crv->points.size();
-                                       for( int k=0; k<pts; ++k ) {
-                                               SketcherPoint *pt = crv->points[k];
-                                               pt->x += dx;  pt->y += dy;
-                                       }
-                               }
-                               SketcherPoint *pt = pi >= 0 && pi < points.size() ?
-                                       points[pi] : 0;
-                               point_x->update(pt ? pt->x : 0.f);
-                               point_y->update(pt ? pt->y : 0.f);
-                               point_list->update(pi);
-                               break;
+                       ++new_points;
+                       int pty = (state & Button1Mask) ? PTY_LINE : PTY_CURVE;
+                       pi = plugin->new_point(cv, pty, output_x, output_y, pi+1);
+                       point_list->update(pi);
+               }
+               return 1;
+       }
+       if( (state & Button1Mask) ) {
+               if( (state & ControlMask) ) { // drag selected point
+                       SketcherPoint *pt = pi >= 0 && pi < points.size() ? points[pi] : 0;
+                       if( pt ) {
+                               point_list->set_point(pi, PT_X, pt->x = output_x);
+                               point_list->set_point(pi, PT_Y, pt->y = output_y);
+                               point_list->update_list(pi);
+                               point_x->update(pt->x);
+                               point_y->update(pt->y);
                        }
                        }
-                       double dist = cv->nearest_point(pi, output_x,output_y);
-                       if( dist >= 0 )
-                               point_list->set_selected(pi);
-                       break;
+                       return 1;
                }
                }
-               if( (state & Button3Mask) ) {
-                       if( (state & (ControlMask | AltMask)) ) { // drag selected curve(s)
-                               int dx = round(output_x - last_x);
-                               int dy = round(output_y - last_y);
-                               for( int i=0; i<points.size(); ++i ) {
-                                       SketcherPoint *pt = points[i];
+               if( (state & AltMask) ) { // drag all curves
+                       int dx = round(output_x - last_x);
+                       int dy = round(output_y - last_y);
+                       for( int i=0; i<curves.size(); ++i ) {
+                               SketcherCurve *crv = plugin->config.curves[i];
+                               int pts = crv->points.size();
+                               for( int k=0; k<pts; ++k ) {
+                                       SketcherPoint *pt = crv->points[k];
                                        pt->x += dx;  pt->y += dy;
                                }
                                        pt->x += dx;  pt->y += dy;
                                }
-                               SketcherPoint *pt = pi >= 0 && pi < points.size() ?
-                                       points[pi] : 0;
-                               point_x->update(pt ? pt->x : 0.f);
-                               point_y->update(pt ? pt->y : 0.f);
-                               point_list->update(pi);
-                               break;
                        }
                        }
-                       double dist = config.nearest_point(ci, pi, output_x,output_y);
-                       if( dist >= 0 ) {
-                               curve_list->update(ci);
-                               point_list->update(pi);
+                       SketcherPoint *pt = pi >= 0 && pi < points.size() ?
+                               points[pi] : 0;
+                       point_x->update(pt ? pt->x : 0.f);
+                       point_y->update(pt ? pt->y : 0.f);
+                       point_id->update(pt ? pt->id : 0);
+                       point_list->update(pi);
+                       return 1;
+               }
+               double dist = cv->nearest_point(pi, output_x,output_y);
+               if( dist >= 0 )
+                       point_list->set_selected(pi);
+               return 1;
+       }
+       if( (state & Button3Mask) ) {
+               if( (state & (ControlMask | AltMask)) ) { // drag selected curve(s)
+                       int dx = round(output_x - last_x);
+                       int dy = round(output_y - last_y);
+                       for( int i=0; i<points.size(); ++i ) {
+                               SketcherPoint *pt = points[i];
+                               pt->x += dx;  pt->y += dy;
                        }
                        }
-                       break;
+                       SketcherPoint *pt = pi >= 0 && pi < points.size() ?
+                               points[pi] : 0;
+                       point_x->update(pt ? pt->x : 0.f);
+                       point_y->update(pt ? pt->y : 0.f);
+                       point_id->update(pt ? pt->id : 0);
+                       point_list->update(pi);
+                       return 1;
                }
                }
-               break; }
-       case ButtonRelease: {
-               new_points = 0;
-               break; }
+               double dist = config.nearest_point(ci, pi, output_x,output_y);
+               if( dist >= 0 ) {
+                       curve_list->update(ci);
+                       point_list->update(pi);
+               }
+               return 1;
        }
        }
-
-       last_x = output_x;  last_y = output_y;
-       pending_config = 1;
-       return 1;
+       return 0;
 }
 
 int SketcherWindow::keypress_event()
 }
 
 int SketcherWindow::keypress_event()
@@ -756,10 +836,11 @@ SketcherCurveList::SketcherCurveList(SketcherWindow *gui, Sketcher *plugin, int
 {
        this->gui = gui;
        this->plugin = plugin;
 {
        this->gui = gui;
        this->plugin = plugin;
-       titles[CV_ID] = _("id");  widths[CV_ID] = 64;
-       titles[CV_RAD] = _("radius");  widths[CV_RAD] = 64;
-       titles[CV_PEN] = _("pen");  widths[CV_PEN] = 64;
-       titles[CV_CLR] = _("color");  widths[CV_CLR] = 64;
+       col_titles[CV_ID] = _("ID");      col_widths[CV_ID] = 64;
+       col_titles[CV_RAD] = _("width");  col_widths[CV_RAD] = 64;
+       col_titles[CV_PEN] = _("pen");    col_widths[CV_PEN] = 64;
+       col_titles[CV_CLR] = _("color");  col_widths[CV_CLR] = 80;
+       col_titles[CV_ALP] = _("alpha");  col_widths[CV_ALP] = 64;
 }
 SketcherCurveList::~SketcherCurveList()
 {
 }
 SketcherCurveList::~SketcherCurveList()
 {
@@ -774,7 +855,7 @@ void SketcherCurveList::clear()
 int SketcherCurveList::column_resize_event()
 {
        for( int i=CV_SZ; --i>=0; )
 int SketcherCurveList::column_resize_event()
 {
        for( int i=CV_SZ; --i>=0; )
-               widths[i] = get_column_width(i);
+               col_widths[i] = get_column_width(i);
        return 1;
 }
 
        return 1;
 }
 
@@ -793,17 +874,12 @@ int SketcherCurveList::selection_changed()
        return 1;
 }
 
        return 1;
 }
 
-void SketcherCurveList::set_curve(int i, int c, const char *cp)
-{
-       cols[c].get(i)->set_text(cp);
-}
-
 void SketcherCurveList::set_selected(int k)
 {
        int ci = -1;
        if( k >= 0 && k < plugin->config.curves.size() ) {
                SketcherCurve *cv = plugin->config.curves[k];
 void SketcherCurveList::set_selected(int k)
 {
        int ci = -1;
        if( k >= 0 && k < plugin->config.curves.size() ) {
                SketcherCurve *cv = plugin->config.curves[k];
-               gui->curve_radius->update(cv->radius);
+               gui->curve_width->update(cv->width);
                gui->curve_pen->update(cv->pen);
                gui->curve_color->update_gui(cv->color);
                ci = k;
                gui->curve_pen->update(cv->pen);
                gui->curve_color->update_gui(cv->color);
                ci = k;
@@ -816,7 +892,7 @@ void SketcherCurveList::update_list(int k)
 {
        int xpos = get_xposition(), ypos = get_yposition();
        if( k >= 0 ) update_selection(&cols[0], k);
 {
        int xpos = get_xposition(), ypos = get_yposition();
        if( k >= 0 ) update_selection(&cols[0], k);
-       BC_ListBox::update(&cols[0], &titles[0],&widths[0],CV_SZ, xpos,ypos,k);
+       BC_ListBox::update(&cols[0], &col_titles[0],&col_widths[0],CV_SZ, xpos,ypos,k);
        center_selection();
 }
 
        center_selection();
 }
 
@@ -829,22 +905,27 @@ void SketcherCurveList::update(int k)
                SketcherCurve *cv = curves[i];
                char itxt[BCSTRLEN];  sprintf(itxt,"%d", cv->id);
                char ptxt[BCSTRLEN];  sprintf(ptxt,"%s", cv_pen[cv->pen]);
                SketcherCurve *cv = curves[i];
                char itxt[BCSTRLEN];  sprintf(itxt,"%d", cv->id);
                char ptxt[BCSTRLEN];  sprintf(ptxt,"%s", cv_pen[cv->pen]);
-               char rtxt[BCSTRLEN];  sprintf(rtxt,"%d", cv->radius);
+               char rtxt[BCSTRLEN];  sprintf(rtxt,"%d", cv->width);
                int color = cv->color;
                int color = cv->color;
-               int r = (color>>16)&0xff, g = (color>>8)&0xff, b = (color>>0)&0xff;
+               int r = (color>>16)&0xff;
+               int g = (color>> 8)&0xff;
+               int b = (color>> 0)&0xff;
+               int a = (~color>>24)&0xff;
                char ctxt[BCSTRLEN];  sprintf(ctxt,"#%02x%02x%02x", r, g, b);
                char ctxt[BCSTRLEN];  sprintf(ctxt,"#%02x%02x%02x", r, g, b);
-               add_curve(itxt, ptxt, rtxt, ctxt);
+               char atxt[BCSTRLEN];  sprintf(atxt,"%5.3f", a/255.);
+               add_curve(itxt, ptxt, rtxt, ctxt, atxt);
        }
        set_selected(k);
 }
 
 void SketcherCurveList::add_curve(const char *id, const char *pen,
        }
        set_selected(k);
 }
 
 void SketcherCurveList::add_curve(const char *id, const char *pen,
-               const char *radius, const char *color)
+               const char *width, const char *color, const char *alpha)
 {
        cols[CV_ID].append(new BC_ListBoxItem(id));
 {
        cols[CV_ID].append(new BC_ListBoxItem(id));
-       cols[CV_RAD].append(new BC_ListBoxItem(radius));
+       cols[CV_RAD].append(new BC_ListBoxItem(width));
        cols[CV_PEN].append(new BC_ListBoxItem(pen));
        cols[CV_CLR].append(new BC_ListBoxItem(color));
        cols[CV_PEN].append(new BC_ListBoxItem(pen));
        cols[CV_CLR].append(new BC_ListBoxItem(color));
+       cols[CV_ALP].append(new BC_ListBoxItem(alpha));
 }
 
 SketcherNewCurve::SketcherNewCurve(SketcherWindow *gui, Sketcher *plugin, int x, int y)
 }
 
 SketcherNewCurve::SketcherNewCurve(SketcherWindow *gui, Sketcher *plugin, int x, int y)
@@ -858,13 +939,13 @@ SketcherNewCurve::~SketcherNewCurve()
 }
 int SketcherNewCurve::handle_event()
 {
 }
 int SketcherNewCurve::handle_event()
 {
-       int pen = PTY_LINE, radius = 1, color = CV_COLOR;
+       int pen = PTY_LINE, width = 1, color = CV_COLOR;
        int ci = plugin->config.cv_selected;
        if( ci >= 0 && ci < plugin->config.curves.size() ) {
                SketcherCurve *cv = plugin->config.curves[ci];
        int ci = plugin->config.cv_selected;
        if( ci >= 0 && ci < plugin->config.curves.size() ) {
                SketcherCurve *cv = plugin->config.curves[ci];
-               pen = cv->pen;  radius = cv->radius;  color = cv->color;
+               pen = cv->pen;  width = cv->width;  color = cv->color;
        }
        }
-       ci = plugin->new_curve(pen, radius, color);
+       ci = plugin->new_curve(pen, width, color);
        gui->curve_list->update(ci);
        gui->point_list->update(-1);
        gui->send_configure_change();
        gui->curve_list->update(ci);
        gui->point_list->update(-1);
        gui->send_configure_change();
@@ -1003,10 +1084,10 @@ SketcherPointList::SketcherPointList(SketcherWindow *gui, Sketcher *plugin, int
 {
        this->gui = gui;
        this->plugin = plugin;
 {
        this->gui = gui;
        this->plugin = plugin;
-       titles[PT_ID] = _("ID");    widths[PT_ID] = 50;
-       titles[PT_TY] = _("Type");  widths[PT_TY] = 80;
-       titles[PT_X] = _("X");      widths[PT_X] = 90;
-       titles[PT_Y] = _("Y");      widths[PT_Y] = 90;
+       col_titles[PT_ID] = _("ID");    col_widths[PT_ID] = 50;
+       col_titles[PT_TY] = _("Type");  col_widths[PT_TY] = 80;
+       col_titles[PT_X] = _("X");      col_widths[PT_X] = 90;
+       col_titles[PT_Y] = _("Y");      col_widths[PT_Y] = 90;
        set_selection_mode(LISTBOX_MULTIPLE);
 }
 SketcherPointList::~SketcherPointList()
        set_selection_mode(LISTBOX_MULTIPLE);
 }
 SketcherPointList::~SketcherPointList()
@@ -1022,7 +1103,7 @@ void SketcherPointList::clear()
 int SketcherPointList::column_resize_event()
 {
        for( int i=PT_SZ; --i>=0; )
 int SketcherPointList::column_resize_event()
 {
        for( int i=PT_SZ; --i>=0; )
-               widths[i] = get_column_width(i);
+               col_widths[i] = get_column_width(i);
        return 1;
 }
 
        return 1;
 }
 
@@ -1055,6 +1136,12 @@ void SketcherPointList::set_point(int i, int c, int v)
        sprintf(stxt,"%d",v);
        set_point(i,c,stxt);
 }
        sprintf(stxt,"%d",v);
        set_point(i,c,stxt);
 }
+void SketcherPointList::set_point(int i, int c, coord v)
+{
+       char stxt[BCSTRLEN];
+       sprintf(stxt,"%0.1f",v);
+       set_point(i,c,stxt);
+}
 void SketcherPointList::set_point(int i, int c, const char *cp)
 {
        cols[c].get(i)->set_text(cp);
 void SketcherPointList::set_point(int i, int c, const char *cp)
 {
        cols[c].get(i)->set_text(cp);
@@ -1071,6 +1158,7 @@ void SketcherPointList::set_selected(int k)
        gui->point_type->update(pt ? pt->pty : PTY_OFF);
        gui->point_x->update(pt ? pt->x : 0.f);
        gui->point_y->update(pt ? pt->y : 0.f);
        gui->point_type->update(pt ? pt->pty : PTY_OFF);
        gui->point_x->update(pt ? pt->x : 0.f);
        gui->point_y->update(pt ? pt->y : 0.f);
+       gui->point_id->update(pt ? pt->id : 0);
        plugin->config.pt_selected = pi;
        update_list(pi);
 }
        plugin->config.pt_selected = pi;
        update_list(pi);
 }
@@ -1078,7 +1166,7 @@ void SketcherPointList::update_list(int k)
 {
        int xpos = get_xposition(), ypos = get_yposition();
        if( k >= 0 ) update_selection(&cols[0], k);
 {
        int xpos = get_xposition(), ypos = get_yposition();
        if( k >= 0 ) update_selection(&cols[0], k);
-       BC_ListBox::update(&cols[0], &titles[0],&widths[0],PT_SZ, xpos,ypos,k);
+       BC_ListBox::update(&cols[0], &col_titles[0],&col_widths[0],PT_SZ, xpos,ypos,k);
        center_selection();
 }
 void SketcherPointList::update(int k)
        center_selection();
 }
 void SketcherPointList::update(int k)
@@ -1093,8 +1181,8 @@ void SketcherPointList::update(int k)
                        SketcherPoint *pt = points[i];
                        char itxt[BCSTRLEN];  sprintf(itxt,"%d", pt->id);
                        char ttxt[BCSTRLEN];  sprintf(ttxt,"%s", _(pt_type[pt->pty]));
                        SketcherPoint *pt = points[i];
                        char itxt[BCSTRLEN];  sprintf(itxt,"%d", pt->id);
                        char ttxt[BCSTRLEN];  sprintf(ttxt,"%s", _(pt_type[pt->pty]));
-                       char xtxt[BCSTRLEN];  sprintf(xtxt,"%d", pt->x);
-                       char ytxt[BCSTRLEN];  sprintf(ytxt,"%d", pt->y);
+                       char xtxt[BCSTRLEN];  sprintf(xtxt,"%0.1f", pt->x);
+                       char ytxt[BCSTRLEN];  sprintf(ytxt,"%0.1f", pt->y);
                        add_point(itxt, ttxt, xtxt, ytxt);
                }
        }
                        add_point(itxt, ttxt, xtxt, ytxt);
                }
        }
@@ -1109,12 +1197,13 @@ void SketcherWindow::update_gui()
        curve_list->update(ci);
        point_list->update(pi);
        SketcherCurve *cv = ci >= 0 ? config.curves[ci] : 0;
        curve_list->update(ci);
        point_list->update(pi);
        SketcherCurve *cv = ci >= 0 ? config.curves[ci] : 0;
-       curve_radius->update(cv ? cv->radius : 1);
+       curve_width->update(cv ? cv->width : 1);
        curve_pen->update(cv ? cv->pen : PEN_SQUARE);
        curve_color->set_color(cv ? cv->color : CV_COLOR);
        SketcherPoint *pt = pi >= 0 ? cv->points[pi] : 0;
        point_x->update(pt ? pt->x : 0);
        point_y->update(pt ? pt->y : 0);
        curve_pen->update(cv ? cv->pen : PEN_SQUARE);
        curve_color->set_color(cv ? cv->color : CV_COLOR);
        SketcherPoint *pt = pi >= 0 ? cv->points[pi] : 0;
        point_x->update(pt ? pt->x : 0);
        point_y->update(pt ? pt->y : 0);
+       point_id->update(pt ? pt->id : 0);
        drag->update(plugin->config.drag);
 }
 
        drag->update(plugin->config.drag);
 }
 
index 35e7e898346ef6feb712722d4a7bea4c8aee20ca..d15cf9c1776c31c5eb85244f9e1c8a488466909f 100644 (file)
 #ifndef __CRIKEYWINDOW_H__
 #define __CRIKEYWINDOW_H__
 
 #ifndef __CRIKEYWINDOW_H__
 #define __CRIKEYWINDOW_H__
 
+#include "sketcher.h"
 #include "guicast.h"
 #include "colorpicker.h"
 
 class Sketcher;
 #include "guicast.h"
 #include "colorpicker.h"
 
 class Sketcher;
+class SketcherCoord;
 class SketcherNum;
 class SketcherCurveTypeItem;
 class SketcherCurveType;
 class SketcherNum;
 class SketcherCurveTypeItem;
 class SketcherCurveType;
@@ -37,10 +39,11 @@ class SketcherNewCurve;
 class SketcherDelCurve;
 class SketcherCurveUp;
 class SketcherCurveDn;
 class SketcherDelCurve;
 class SketcherCurveUp;
 class SketcherCurveDn;
-class SketcherCurveRadius;
+class SketcherCurveWidth;
 class SketcherCurveList;
 class SketcherPointX;
 class SketcherPointY;
 class SketcherCurveList;
 class SketcherPointX;
 class SketcherPointY;
+class SketcherPointId;
 class SketcherDrag;
 class SketcherPointTypeItem;
 class SketcherPointType;
 class SketcherDrag;
 class SketcherPointTypeItem;
 class SketcherPointType;
@@ -54,6 +57,17 @@ class SketcherResetPoints;
 class SketcherWindow;
 
 
 class SketcherWindow;
 
 
+class SketcherCoord : public BC_TumbleTextBox
+{
+public:
+       SketcherWindow *gui;
+
+       SketcherCoord(SketcherWindow *gui, int x, int y, coord output,
+               coord mn=-32767, coord mx=32767);
+       ~SketcherCoord();
+       int update(coord v) { return BC_TumbleTextBox::update((coord)v); }
+};
+
 class SketcherNum : public BC_TumbleTextBox
 {
 public:
 class SketcherNum : public BC_TumbleTextBox
 {
 public:
@@ -175,12 +189,12 @@ public:
        SketcherWindow *gui;
 };
 
        SketcherWindow *gui;
 };
 
-class SketcherCurveRadius : public SketcherNum
+class SketcherCurveWidth : public SketcherNum
 {
 public:
 {
 public:
-       SketcherCurveRadius(SketcherWindow *gui, int x, int y, float output)
+       SketcherCurveWidth(SketcherWindow *gui, int x, int y, float output)
         : SketcherNum(gui, x, y, output, 0, 255) {}
         : SketcherNum(gui, x, y, output, 0, 255) {}
-       ~SketcherCurveRadius() {}
+       ~SketcherCurveWidth() {}
 
        int handle_event();
 };
 
        int handle_event();
 };
@@ -197,39 +211,48 @@ public:
        ArrayList<BC_ListBoxItem*> cols[CV_SZ];
        void clear();
        void add_curve(const char *id, const char *pen,
        ArrayList<BC_ListBoxItem*> cols[CV_SZ];
        void clear();
        void add_curve(const char *id, const char *pen,
-               const char *radius, const char *color);
+               const char *width, const char *color, const char *alpha);
        void del_curve(int i);
        void del_curve(int i);
-       void set_curve(int i, int c, const char *cp);
        void set_selected(int k);
        void update(int k);
        void update_list(int k);
 
        SketcherWindow *gui;
        Sketcher *plugin;
        void set_selected(int k);
        void update(int k);
        void update_list(int k);
 
        SketcherWindow *gui;
        Sketcher *plugin;
-       const char *titles[CV_SZ];
-       int widths[CV_SZ];
+       const char *col_titles[CV_SZ];
+       int col_widths[CV_SZ];
 };
 
 
 };
 
 
-class SketcherPointX : public SketcherNum
+class SketcherPointX : public SketcherCoord
 {
 public:
        SketcherPointX(SketcherWindow *gui, int x, int y, float output)
 {
 public:
        SketcherPointX(SketcherWindow *gui, int x, int y, float output)
-        : SketcherNum(gui, x, y, output) {}
+        : SketcherCoord(gui, x, y, output) {}
        ~SketcherPointX() {}
 
        int handle_event();
 };
        ~SketcherPointX() {}
 
        int handle_event();
 };
-class SketcherPointY : public SketcherNum
+class SketcherPointY : public SketcherCoord
 {
 public:
        SketcherPointY(SketcherWindow *gui, int x, int y, float output)
 {
 public:
        SketcherPointY(SketcherWindow *gui, int x, int y, float output)
-        : SketcherNum(gui, x, y, output) {}
+        : SketcherCoord(gui, x, y, output) {}
        ~SketcherPointY() {}
 
        int handle_event();
 };
 
        ~SketcherPointY() {}
 
        int handle_event();
 };
 
+class SketcherPointId : public SketcherNum
+{
+public:
+       SketcherPointId(SketcherWindow *gui, int x, int y, int output)
+        : SketcherNum(gui, x, y, output) {}
+       ~SketcherPointId() {}
+
+       int handle_event();
+};
+
 
 class SketcherDrag : public BC_CheckBox
 {
 
 class SketcherDrag : public BC_CheckBox
 {
@@ -272,6 +295,7 @@ public:
        void clear();
        void add_point(const char *id, const char *ty, const char *xp, const char *yp);
        void set_point(int i, int c, int v);
        void clear();
        void add_point(const char *id, const char *ty, const char *xp, const char *yp);
        void set_point(int i, int c, int v);
+       void set_point(int i, int c, coord v);
        void set_point(int i, int c, const char *cp);
        void set_selected(int k);
        void update(int k);
        void set_point(int i, int c, const char *cp);
        void set_selected(int k);
        void update(int k);
@@ -280,8 +304,8 @@ public:
 
        SketcherWindow *gui;
        Sketcher *plugin;
 
        SketcherWindow *gui;
        Sketcher *plugin;
-       const char *titles[PT_SZ];
-       int widths[PT_SZ];
+       const char *col_titles[PT_SZ];
+       int col_widths[PT_SZ];
 };
 
 class SketcherNewPoint : public BC_GenericButton
 };
 
 class SketcherNewPoint : public BC_GenericButton
@@ -365,6 +389,8 @@ public:
        void update_gui();
        void start_color_thread(SketcherCurveColor *curve_color);
        int grab_event(XEvent *event);
        void update_gui();
        void start_color_thread(SketcherCurveColor *curve_color);
        int grab_event(XEvent *event);
+       int grab_button_press(XEvent *event);
+       int grab_cursor_motion(XEvent *event);
        int do_grab_event(XEvent *event);
        void done_event(int result);
        void send_configure_change();
        int do_grab_event(XEvent *event);
        void done_event(int result);
        void send_configure_change();
@@ -372,7 +398,7 @@ public:
 
        Sketcher *plugin;
 
 
        Sketcher *plugin;
 
-       BC_Title *title_pen, *title_color, *title_radius;
+       BC_Title *title_pen, *title_color, *title_width;
        SketcherCurveType *curve_type;
        SketcherCurvePen *curve_pen;
        SketcherCurveColor *curve_color;
        SketcherCurveType *curve_type;
        SketcherCurvePen *curve_pen;
        SketcherCurveColor *curve_color;
@@ -381,7 +407,7 @@ public:
        SketcherDelCurve *del_curve;
        SketcherCurveUp *curve_up;
        SketcherCurveDn *curve_dn;
        SketcherDelCurve *del_curve;
        SketcherCurveUp *curve_up;
        SketcherCurveDn *curve_dn;
-       SketcherCurveRadius *curve_radius;
+       SketcherCurveWidth *curve_width;
        SketcherCurveList *curve_list;
        SketcherResetCurves *reset_curves;
 
        SketcherCurveList *curve_list;
        SketcherResetCurves *reset_curves;
 
@@ -389,15 +415,23 @@ public:
        SketcherDrag *drag;
        SketcherPointType *point_type;
        SketcherPointList *point_list;
        SketcherDrag *drag;
        SketcherPointType *point_type;
        SketcherPointList *point_list;
-       BC_Title *title_x, *title_y;
+       BC_Title *title_x, *title_y, *title_id;
        SketcherPointX *point_x;
        SketcherPointY *point_y;
        SketcherPointX *point_x;
        SketcherPointY *point_y;
+       SketcherPointId *point_id;
        SketcherNewPoint *new_point;
        SketcherDelPoint *del_point;
        SketcherPointUp *point_up;
        SketcherPointDn *point_dn;
        SketcherNewPoint *new_point;
        SketcherDelPoint *del_point;
        SketcherPointUp *point_up;
        SketcherPointDn *point_dn;
-       int dragging, pending_config;
+       int64_t position;
+       float projector_x, projector_y, projector_z;
+       int track_w, track_h;
        int new_points;
        int new_points;
+       float cursor_x, cursor_y;
+       float output_x, output_y;
+       int state, dragging;
+       int pending_motion, pending_config;
+       XEvent motion_event;
        float last_x, last_y;
        BC_Title *notes0, *notes1, *notes2;
 };
        float last_x, last_y;
        BC_Title *notes0, *notes1, *notes2;
 };