upgrades/fixes for tracer plugin, add vdpau,vaapi build depends
authorGood Guy <good1.2guy@gmail.com>
Sat, 27 Apr 2019 20:09:10 +0000 (14:09 -0600)
committerGood Guy <good1.2guy@gmail.com>
Sat, 27 Apr 2019 20:09:10 +0000 (14:09 -0600)
cinelerra-5.1/blds/PKGBUILD
cinelerra-5.1/blds/bsd.bld
cinelerra-5.1/blds/cin.SlackBuild
cinelerra-5.1/blds/cinelerra.spec
cinelerra-5.1/blds/debian/control
cinelerra-5.1/plugins/tracer/tracer.C
cinelerra-5.1/plugins/tracer/tracer.h
cinelerra-5.1/plugins/tracer/tracerwindow.C
cinelerra-5.1/plugins/tracer/tracerwindow.h

index 3cddc5a03d81822352b402e38443435d5c0b2893..70d20d81725109dc78036f02989ce6a44b2132d4 100644 (file)
@@ -11,7 +11,7 @@ DEPENDS=( 'alsa-lib' 'atk' 'bzip2' 'cairo' 'expat' 'fftw' 'flac'
  'glib2' 'glibc' 'glu' 'graphite' 'gtk2' 'harfbuzz' 'libavc1394'
  'libdatrie' 'libdv' 'libffi' 'libglvnd' 'libiec61883' 'libjpeg-turbo'
  'libogg' 'libpng' 'libraw1394' 'libsndfile' 'libthai' 'libusb'
  'glib2' 'glibc' 'glu' 'graphite' 'gtk2' 'harfbuzz' 'libavc1394'
  'libdatrie' 'libdv' 'libffi' 'libglvnd' 'libiec61883' 'libjpeg-turbo'
  'libogg' 'libpng' 'libraw1394' 'libsndfile' 'libthai' 'libusb'
- 'libtheora' 'libtiff' 'libutil-linux' 'libvdpau' 'libvorbis'
+ 'libtheora' 'libtiff' 'libutil-linux' 'libvdpau' 'libva' 'libvorbis'
  'libvpx' 'libx11' 'libxau' 'libxcb' 'libxcomposite' 'libxcursor'
  'libxdamage' 'libxdmcp' 'libxext' 'libxfixes' 'libxft' 'libxi'
  'libxinerama' 'libxrandr' 'libxrender' 'libxv' 'numactl' 'opus'
  'libvpx' 'libx11' 'libxau' 'libxcb' 'libxcomposite' 'libxcursor'
  'libxdamage' 'libxdmcp' 'libxext' 'libxfixes' 'libxft' 'libxi'
  'libxinerama' 'libxrandr' 'libxrender' 'libxv' 'numactl' 'opus'
@@ -34,7 +34,6 @@ prepare() {
 build() {
   cd "$srcdir/cinelerra-$pkgver"
   ./autogen.sh
 build() {
   cd "$srcdir/cinelerra-$pkgver"
   ./autogen.sh
-  export FFMPEG_EXTRA_CFG=" --disable-vdpau"
   ./configure --prefix=/usr --with-exec-name=$pkgname
 CFG_VARS="\
 CFLAGS+=' -Wno-narrowing -O2 -g -fno-omit-frame-pointer' \
   ./configure --prefix=/usr --with-exec-name=$pkgname
 CFG_VARS="\
 CFLAGS+=' -Wno-narrowing -O2 -g -fno-omit-frame-pointer' \
index 072a9ca78f5c8bd72ffbb146ba9fb2afe552c37a..82155896627ddd48e8507b5115f9487926b75fab 100755 (executable)
@@ -11,6 +11,7 @@ alias make=gmake
     --disable-static-build --with-lv2=auto --disable-lame --disable-twolame \
     --with-oss --without-alsa --without-firewire --without-dv --without-dvb \
     --without-video4linux2 --without-xxf86vm --without-ladspa-build \
     --disable-static-build --with-lv2=auto --disable-lame --disable-twolame \
     --with-oss --without-alsa --without-firewire --without-dv --without-dvb \
     --without-video4linux2 --without-xxf86vm --without-ladspa-build \
-    --without-libzmpeg --without-commercial --without-thirdparty
+    --without-libzmpeg --without-commercial --without-thirdparty \
+    --disable-vaapi --disable-vdpau
   gmake
   gmake install ) 2>&1 | tee log
   gmake
   gmake install ) 2>&1 | tee log
index 8555bb43fd172db203e787ca3dff39980d92c520..f05f658b9dec693232977c2b78d711c95f91da1b 100644 (file)
@@ -69,9 +69,6 @@ git clone --depth 1 $GITURL $PRGNAM-$VERSION
 cd $PRGNAM-$VERSION/cinelerra-5.1
 chown -R root:root .
 
 cd $PRGNAM-$VERSION/cinelerra-5.1
 chown -R root:root .
 
-# disable vdpau or ffmpeg won't build on Slackware 14.2
-export FFMPEG_EXTRA_CFG=" --disable-vdpau"
-
 # configure the build
 ./autogen.sh
 
 # configure the build
 ./autogen.sh
 
index 6c8353a9c42ec5da7920584c2f82eb728835c745..2e28e105d1278422140b0bdffcfa8d1a37f26e1b 100644 (file)
@@ -50,6 +50,8 @@ BuildRequires: ncurses-devel
 BuildRequires: texinfo
 BuildRequires: udftools
 BuildRequires: gtk2-devel
 BuildRequires: texinfo
 BuildRequires: udftools
 BuildRequires: gtk2-devel
+BuildRequires: va-devel
+BuildRequires: vdpau-devel
 %{?rhat:BuildRequires: alsa-lib-devel}
 %{?rhat:BuildRequires: bzip2-devel}
 %{?rhat:BuildRequires: xorg-x11-fonts-cyrillic}
 %{?rhat:BuildRequires: alsa-lib-devel}
 %{?rhat:BuildRequires: bzip2-devel}
 %{?rhat:BuildRequires: xorg-x11-fonts-cyrillic}
index 74672f66cef56e48e570209980a324c08d94e429..ef41478a0c3931dcb5d16e5d70500dc3b8b7878f 100644 (file)
@@ -10,7 +10,7 @@ Build-Depends: nasm, yasm, g++, gdb, build-essential, e2fsprogs,
  freeglut3-dev, libxv-dev, libasound2-dev,
  libncurses5-dev, libxinerama-dev, libfreetype6-dev, libxft-dev,
  ttf-bitstream-vera, xfonts-75dpi, xfonts-100dpi, fonts-dejavu,
  freeglut3-dev, libxv-dev, libasound2-dev,
  libncurses5-dev, libxinerama-dev, libfreetype6-dev, libxft-dev,
  ttf-bitstream-vera, xfonts-75dpi, xfonts-100dpi, fonts-dejavu,
- libflac-dev, inkscape, texinfo, libpng-dev,
+ libflac-dev, inkscape, texinfo, libpng-dev, libvdpau-dev, libva-dev,
  cmake, udftools, libxml2-utils, git, gettext, libtool,
  autoconf, automake
 
  cmake, udftools, libxml2-utils, git, gettext, libtool,
  autoconf, automake
 
index be58496d7c29d346acf22e79d42e457eb16de706..a40d0c27e8bd4f161a0407bab8c95883e6b21897 100644 (file)
@@ -56,9 +56,9 @@ TracerPoint::~TracerPoint()
 
 TracerConfig::TracerConfig()
 {
 
 TracerConfig::TracerConfig()
 {
-       drag = draw = fill = 0;
-       radius = 0;  scale = 1;
-       selected = 0;
+       drag = draw = 1;  fill = 0;
+       feather = 0;  radius = 1;
+       invert = 0;  selected = -1;
 }
 TracerConfig::~TracerConfig()
 {
 }
 TracerConfig::~TracerConfig()
 {
@@ -69,8 +69,9 @@ int TracerConfig::equivalent(TracerConfig &that)
        if( this->drag != that.drag ) return 0;
        if( this->draw != that.draw ) return 0;
        if( this->fill != that.fill ) return 0;
        if( this->drag != that.drag ) return 0;
        if( this->draw != that.draw ) return 0;
        if( this->fill != that.fill ) return 0;
+       if( this->feather != that.feather ) return 0;
+       if( this->invert != that.invert ) return 0;
        if( this->radius != that.radius ) return 0;
        if( this->radius != that.radius ) return 0;
-       if( this->scale != that.scale ) return 0;
        if( this->points.size() != that.points.size() ) return 0;
        for( int i=0, n=points.size(); i<n; ++i ) {
                TracerPoint *ap = this->points[i], *bp = that.points[i];
        if( this->points.size() != that.points.size() ) return 0;
        for( int i=0, n=points.size(); i<n; ++i ) {
                TracerPoint *ap = this->points[i], *bp = that.points[i];
@@ -86,8 +87,9 @@ void TracerConfig::copy_from(TracerConfig &that)
        this->draw = that.draw;
        this->fill = that.fill;
        this->selected = that.selected;
        this->draw = that.draw;
        this->fill = that.fill;
        this->selected = that.selected;
+       this->feather = that.feather;
+       this->invert = that.invert;
        this->radius = that.radius;
        this->radius = that.radius;
-       this->scale = that.scale;
        points.remove_all_objects();
        for( int i=0,n=that.points.size(); i<n; ++i ) {
                TracerPoint *pt = that.points[i];
        points.remove_all_objects();
        for( int i=0,n=that.points.size(); i<n; ++i ) {
                TracerPoint *pt = that.points[i];
@@ -175,8 +177,9 @@ void Tracer::save_data(KeyFrame *keyframe)
        output.tag.set_property("DRAG", config.drag);
        output.tag.set_property("DRAW", config.draw);
        output.tag.set_property("FILL", config.fill);
        output.tag.set_property("DRAG", config.drag);
        output.tag.set_property("DRAW", config.draw);
        output.tag.set_property("FILL", config.fill);
+       output.tag.set_property("FEATHER", config.feather);
        output.tag.set_property("RADIUS", config.radius);
        output.tag.set_property("RADIUS", config.radius);
-       output.tag.set_property("SCALE", config.scale);
+       output.tag.set_property("INVERT", config.invert);
        output.tag.set_property("SELECTED", config.selected);
        output.append_tag();
        output.append_newline();
        output.tag.set_property("SELECTED", config.selected);
        output.append_tag();
        output.append_newline();
@@ -210,8 +213,9 @@ void Tracer::read_data(KeyFrame *keyframe)
                        config.drag = input.tag.get_property("DRAG", config.drag);
                        config.draw = input.tag.get_property("DRAW", config.draw);
                        config.fill = input.tag.get_property("FILL", config.fill);
                        config.drag = input.tag.get_property("DRAG", config.drag);
                        config.draw = input.tag.get_property("DRAW", config.draw);
                        config.fill = input.tag.get_property("FILL", config.fill);
+                       config.feather = input.tag.get_property("FEATHER", config.feather);
                        config.radius = input.tag.get_property("RADIUS", config.radius);
                        config.radius = input.tag.get_property("RADIUS", config.radius);
-                       config.scale = input.tag.get_property("SCALE", config.scale);
+                       config.invert = input.tag.get_property("INVERT", config.invert);
                        config.selected = input.tag.get_property("SELECTED", 0);
                        config.limits();
                }
                        config.selected = input.tag.get_property("SELECTED", 0);
                        config.limits();
                }
@@ -221,8 +225,6 @@ void Tracer::read_data(KeyFrame *keyframe)
                        config.add_point(x, y);
                }
        }
                        config.add_point(x, y);
                }
        }
-
-       if( !config.points.size() ) new_point();
 }
 
 void Tracer::update_gui()
 }
 
 void Tracer::update_gui()
@@ -538,15 +540,18 @@ void FillRegion::run()
 
 void Tracer::feather(int r, double s)
 {
 
 void Tracer::feather(int r, double s)
 {
-       if( !r || !s ) return;
-       int dir = r<0 ? (r=-r, -1) : 1;
-       if( dir < 0 ) s = 1./s;
+       if( !r ) return;
+       int dir = r < 0 ? (r=-r, -1) : 1;
        int rr = r * r;
        int psf[rr];  // pt spot fn
        int rr = r * r;
        int psf[rr];  // pt spot fn
-       int k = dir>=0 ? 0 : rr-1;
-       for( int i=0; i<rr; ++i,k+=dir )
-               psf[k] = 255*exp(-s*((double)i/rr));
-       int mx = dir > 0 ? 0xff : 0;
+       float p = powf(10.f, s/2);
+       for( int i=0; i<rr; ++i ) {
+               float v = powf((float)i/rr,p);
+               if( dir < 0 ) v = 1-v;
+               int vv = v*256;
+               if( vv > 255 ) vv = 255;
+               psf[i] = vv;
+       }
        for( int i=0,n=points.size(); i<n; ++i ) {
                TracePoint *pt = &points[i];
                int xs = pt->x-r, xn=pt->x+r;
        for( int i=0,n=points.size(); i<n; ++i ) {
                TracePoint *pt = &points[i];
                int xs = pt->x-r, xn=pt->x+r;
@@ -557,12 +562,11 @@ void Tracer::feather(int r, double s)
                bclamp(yn, 0, h);
                for( int y=ys ; y<yn; ++y ) {
                        for( int x=xs; x<xn; ++x ) {
                bclamp(yn, 0, h);
                for( int y=ys ; y<yn; ++y ) {
                        for( int x=xs; x<xn; ++x ) {
-                               if( msk_rows[y][x] == mx ) continue;
                                int dx = x-pt->x, dy = y-pt->y;
                                int dd = dx*dx + dy*dy;
                                if( dd >= rr ) continue;
                                int dx = x-pt->x, dy = y-pt->y;
                                int dd = dx*dx + dy*dy;
                                if( dd >= rr ) continue;
-                               int pix = msk_rows[y][x], v = psf[dd];
-                               msk_rows[y][x] = dir >= 0 ? pix+v-(pix*v)/255 : (pix*v)/255;
+                               int v = psf[dd], px = msk_rows[y][x];
+                               if( dir < 0 ? px<v : px>v ) msk_rows[y][x] = v;
                        }
                }
        }
                        }
                }
        }
@@ -576,8 +580,7 @@ void Tracer::draw_mask()
                        uint8_t *mp = msk_rows[y];
                        uint8_t *rp = frm_rows[y];
                        for( int x=0; x<w; rp+=bpp,++x ) {
                        uint8_t *mp = msk_rows[y];
                        uint8_t *rp = frm_rows[y];
                        for( int x=0; x<w; rp+=bpp,++x ) {
-                               if( !mp[x] ) continue;
-                               int a = 0xff - mp[x];
+                               int a = !config.invert ? 0xff-mp[x] : mp[x];
                                rp[0] = a*rp[0] / 0xff;
                                rp[1] = a*rp[1] / 0xff;
                                rp[2] = a*rp[2] / 0xff;
                                rp[0] = a*rp[0] / 0xff;
                                rp[1] = a*rp[1] / 0xff;
                                rp[2] = a*rp[2] / 0xff;
@@ -589,8 +592,7 @@ void Tracer::draw_mask()
                        uint8_t *mp = msk_rows[y];
                        uint8_t *rp = frm_rows[y];
                        for( int x=0; x<w; rp+=bpp,++x ) {
                        uint8_t *mp = msk_rows[y];
                        uint8_t *rp = frm_rows[y];
                        for( int x=0; x<w; rp+=bpp,++x ) {
-                               if( !mp[x] ) continue;
-                               int a = 0xff - mp[x];
+                               int a = !config.invert ? 0xff-mp[x] : mp[x];
                                rp[0] = a*rp[0] / 0xff;
                                rp[1] = a*(rp[1]-0x80)/0xff + 0x80;
                                rp[2] = a*(rp[2]-0x80)/0xff + 0x80;
                                rp[0] = a*rp[0] / 0xff;
                                rp[1] = a*(rp[1]-0x80)/0xff + 0x80;
                                rp[2] = a*(rp[2]-0x80)/0xff + 0x80;
@@ -602,8 +604,7 @@ void Tracer::draw_mask()
                        uint8_t *mp = msk_rows[y];
                        uint8_t *rp = frm_rows[y];
                        for( int x=0; x<w; rp+=bpp,++x ) {
                        uint8_t *mp = msk_rows[y];
                        uint8_t *rp = frm_rows[y];
                        for( int x=0; x<w; rp+=bpp,++x ) {
-                               if( !mp[x] ) continue;
-                               float a = 1 - mp[x]/255.f;
+                               float a = !config.invert ? 1-mp[x]/255.f : mp[x]/255.f;
                                float *fp = (float*)rp;
                                fp[0] *= a;  fp[1] *= a;  fp[2] *= a;
                        }
                                float *fp = (float*)rp;
                                fp[0] *= a;  fp[1] *= a;  fp[2] *= a;
                        }
@@ -615,7 +616,7 @@ void Tracer::draw_mask()
                        uint8_t *mp = msk_rows[y];
                        uint8_t *rp = frm_rows[y];
                        for( int x=0; x<w; rp+=bpp,++x ) {
                        uint8_t *mp = msk_rows[y];
                        uint8_t *rp = frm_rows[y];
                        for( int x=0; x<w; rp+=bpp,++x ) {
-                               rp[3] = 0xff - mp[x];
+                               rp[3] = !config.invert ? 0xff-mp[x] : mp[x];
                        }
                }
                break;
                        }
                }
                break;
@@ -625,7 +626,7 @@ void Tracer::draw_mask()
                        uint8_t *rp = frm_rows[y];
                        for( int x=0; x<w; rp+=bpp,++x ) {
                                float *fp = (float*)rp;
                        uint8_t *rp = frm_rows[y];
                        for( int x=0; x<w; rp+=bpp,++x ) {
                                float *fp = (float*)rp;
-                               fp[3] = 1 - mp[x]/255.f;
+                               fp[3] = !config.invert ? 1-mp[x]/255.f : mp[x]/255.f;
                        }
                }
                break;
                        }
                }
                break;
@@ -673,12 +674,12 @@ int Tracer::process_buffer(VFrame *frame, int64_t start_position, double frame_r
                        fill_region.fill(cx, cy);
                        fill_region.run();
 
                        fill_region.fill(cx, cy);
                        fill_region.run();
 
-                       feather(config.radius, config.scale);
+                       feather(config.feather, config.radius);
                }
        }
                }
        }
-       if( config.fill )
+       if( config.fill && msk )
                draw_mask();
                draw_mask();
-       if( config.draw )
+       if( config.draw && edg )
                draw_edge();
        if( config.drag )
                draw_points();
                draw_edge();
        if( config.drag )
                draw_points();
index cc2364e5edc36b97b4744e99c71e5096e3403e9b..e9918719cdefd365b162eb066ad4be1cf8df7c22 100644 (file)
@@ -63,8 +63,8 @@ public:
        void del_point(int i);
 
        int drag, draw, fill;
        void del_point(int i);
 
        int drag, draw, fill;
-       int radius;
-       double scale
+       int invert, feather;
+       float radius
        int selected;
 };
 
        int selected;
 };
 
index af0ec2f2cc81500d25cb172f4caa4bc1c2e01baa..ee3669beebbf22ee1366af72960b0943f73629e0 100644 (file)
@@ -85,7 +85,7 @@ int TracerPointY::handle_event()
 }
 
 TracerWindow::TracerWindow(Tracer *plugin)
 }
 
 TracerWindow::TracerWindow(Tracer *plugin)
- : PluginClientWindow(plugin, 400, 300, 400, 300, 0)
+ : PluginClientWindow(plugin, 400, 420, 400, 420, 0)
 {
        this->plugin = plugin;
        this->title_x = 0;    this->point_x = 0;
 {
        this->plugin = plugin;
        this->title_x = 0;    this->point_x = 0;
@@ -93,9 +93,9 @@ TracerWindow::TracerWindow(Tracer *plugin)
        this->new_point = 0;  this->del_point = 0;
        this->point_up = 0;   this->point_dn = 0;
        this->drag = 0;       this->draw = 0;
        this->new_point = 0;  this->del_point = 0;
        this->point_up = 0;   this->point_dn = 0;
        this->drag = 0;       this->draw = 0;
-       this->dragging = 0;
+       this->button_no = 0;  this->invert = 0;
        this->title_r = 0;    this->title_s = 0;
        this->title_r = 0;    this->title_s = 0;
-       this->radius = 0;     this->scale = 0;
+       this->feather = 0;    this->radius = 0;
        this->last_x = 0;     this->last_y = 0;
        this->point_list = 0; this->pending_config = 0;
 }
        this->last_x = 0;     this->last_y = 0;
        this->point_list = 0; this->pending_config = 0;
 }
@@ -110,10 +110,11 @@ void TracerWindow::create_objects()
 {
        int x = 10, y = 10;
        int margin = plugin->get_theme()->widget_border;
 {
        int x = 10, y = 10;
        int margin = plugin->get_theme()->widget_border;
-       TracerPoint *pt = plugin->config.points[plugin->config.selected];
+       int hot_point = plugin->config.selected;
        add_subwindow(title_x = new BC_Title(x, y, _("X:")));
        int x1 = x + title_x->get_w() + margin;
        add_subwindow(title_x = new BC_Title(x, y, _("X:")));
        int x1 = x + title_x->get_w() + margin;
-       point_x = new TracerPointX(this, x1, y, pt->x);
+       TracerPoint *pt = hot_point >= 0 ? plugin->config.points[hot_point] : 0;
+       point_x = new TracerPointX(this, x1, y, !pt ? 0 : pt->x);
        point_x->create_objects();
        x1 += point_x->get_w() + margin;
        add_subwindow(new_point = new TracerNewPoint(this, plugin, x1, y));
        point_x->create_objects();
        x1 += point_x->get_w() + margin;
        add_subwindow(new_point = new TracerNewPoint(this, plugin, x1, y));
@@ -122,7 +123,7 @@ void TracerWindow::create_objects()
        y += point_x->get_h() + margin;
        add_subwindow(title_y = new BC_Title(x, y, _("Y:")));
        x1 = x + title_y->get_w() + margin;
        y += point_x->get_h() + margin;
        add_subwindow(title_y = new BC_Title(x, y, _("Y:")));
        x1 = x + title_y->get_w() + margin;
-       point_y = new TracerPointY(this, x1, y, pt->y);
+       point_y = new TracerPointY(this, x1, y, !pt ? 0 : pt->y);
        point_y->create_objects();
        x1 += point_y->get_w() + margin;
        add_subwindow(del_point = new TracerDelPoint(this, plugin, x1, y));
        point_y->create_objects();
        x1 += point_y->get_w() + margin;
        add_subwindow(del_point = new TracerDelPoint(this, plugin, x1, y));
@@ -140,22 +141,31 @@ void TracerWindow::create_objects()
        x1 += draw->get_w() + margin + 20;
        add_subwindow(fill = new TracerFill(this, x1, y));
        x1 += drag->get_w() + margin + 20;
        x1 += draw->get_w() + margin + 20;
        add_subwindow(fill = new TracerFill(this, x1, y));
        x1 += drag->get_w() + margin + 20;
-       add_subwindow(reset = new TracerReset(this, plugin, x1, y+3));
-       y += drag->get_h() + margin;
-
-       add_subwindow(title_r = new BC_Title(x1=x, y, _("Radius:")));
-       x1 += title_r->get_w() + margin;
-       add_subwindow(radius = new TracerRadius(this, x1, y, 100));
-       x1 += radius->get_w() + margin + 20;
-       add_subwindow(title_s = new BC_Title(x1, y, _("Scale:")));
-       x1 += title_s->get_w() + margin;
-       add_subwindow(scale = new TracerScale(this, x1, y, 100));
-       y += radius->get_h() + margin + 20;
+       int y1 = y + 3;
+       add_subwindow(reset = new TracerReset(this, plugin, x1, y1));
+       y1 += reset->get_h() + margin;
+       add_subwindow(invert = new TracerInvert(this, plugin, x1, y1));
+       y += drag->get_h() + margin + 15;
+
+       x1 = x + 80;
+       add_subwindow(title_r = new BC_Title(x, y, _("Feather:")));
+       add_subwindow(feather = new TracerFeather(this, x1, y, 150));
+       y += feather->get_h() + margin;
+       add_subwindow(title_s = new BC_Title(x, y, _("Radius:")));
+       add_subwindow(radius = new TracerRadius(this, x1, y, 150));
+       y += radius->get_h() + margin + 5;
 
        add_subwindow(point_list = new TracerPointList(this, plugin, x, y));
        point_list->update(plugin->config.selected);
 
        add_subwindow(point_list = new TracerPointList(this, plugin, x, y));
        point_list->update(plugin->config.selected);
-//     y += point_list->get_h() + 10;
-
+       y += point_list->get_h() + 10;
+
+       add_subwindow(new BC_Title(x, y, _(
+               "Btn1: select/drag point\n"
+               "Btn2: drag all points\n"
+               "Btn3: add point on nearest line\n"
+               "Btn3: shift: append point to end\n"
+               "Wheel: rotate, centered on cursor\n"
+               "Wheel: shift: scale, centered on cursor\n")));
        show_window(1);
 }
 
        show_window(1);
 }
 
@@ -190,7 +200,7 @@ int TracerWindow::do_grab_event(XEvent *event)
        cx -= canvas->view_x;
        cy -= canvas->view_y;
 
        cx -= canvas->view_x;
        cy -= canvas->view_y;
 
-       if( !dragging ) {
+       if( !button_no ) {
                if( cx < 0 || cx >= canvas->view_w ||
                    cy < 0 || cy >= canvas->view_h )
                        return 0;
                if( cx < 0 || cx >= canvas->view_w ||
                    cy < 0 || cy >= canvas->view_h )
                        return 0;
@@ -198,15 +208,15 @@ int TracerWindow::do_grab_event(XEvent *event)
 
        switch( event->type ) {
        case ButtonPress:
 
        switch( event->type ) {
        case ButtonPress:
-               if( dragging ) return 0;
-               dragging = event->xbutton.state & ShiftMask ? -1 : 1;
+               if( button_no ) return 0;
+               button_no = event->xbutton.button;
                break;
        case ButtonRelease:
                break;
        case ButtonRelease:
-               if( !dragging ) return 0;
-               dragging = 0;
+               if( !button_no ) return 0;
+               button_no = 0;
                return 1;
        case MotionNotify:
                return 1;
        case MotionNotify:
-               if( !dragging ) return 0;
+               if( !button_no ) return 0;
                break;
        default:
                return 0;
                break;
        default:
                return 0;
@@ -229,20 +239,62 @@ int TracerWindow::do_grab_event(XEvent *event)
        point_y->update((int64_t)(output_y));
        TracerPoints &points = plugin->config.points;
 
        point_y->update((int64_t)(output_y));
        TracerPoints &points = plugin->config.points;
 
-       if( dragging > 0 ) {
-               switch( event->type ) {
-               case ButtonPress: {
-                       int button_no = event->xbutton.button;
-                       int hot_point = -1;
-                       if( button_no == RIGHT_BUTTON ) {
-                               hot_point = plugin->new_point();
-                               TracerPoint *pt = points[hot_point];
-                               pt->x = output_x;  pt->y = output_y;
-                               point_list->update(hot_point);
-                               break;
-                       }
+       switch( event->type ) {
+       case ButtonPress: {
+               float s = 1.02;
+               float th = M_PI/360.f; // .5 deg per wheel_btn
+               int shift_down = event->xbutton.state & ShiftMask;
+               switch( button_no ) {
+               case WHEEL_DOWN:
+                       s = 0.98;
+                       th = -th;  // fall thru
+               case WHEEL_UP: {
+                       // shift_down scale, !shift_down rotate
+                       float st = sin(th), ct = cos(th);
                        int sz = points.size();
                        int sz = points.size();
-                       if( hot_point < 0 && sz > 0 ) {
+                       for( int i=0; i<sz; ++i ) {
+                               TracerPoint *pt = points[i];
+                               float px = pt->x - output_x, py = pt->y - output_y;
+                               float nx = shift_down ? px*s : px*ct + py*st;
+                               float ny = shift_down ? py*s : py*ct - px*st;
+                               point_list->set_point(i, PT_X, pt->x = nx + output_x);
+                               point_list->set_point(i, PT_Y, pt->y = ny + output_y);
+                       }
+                       point_list->update(-1);
+                       button_no = 0;
+                       break; }
+               case RIGHT_BUTTON: {
+                       // shift_down adds to end
+                       int sz = !shift_down ? points.size() : 0;
+                       int k = !shift_down ? -1 : points.size()-1;
+                       float mx = FLT_MAX;
+                       for( int i=0; i<sz; ++i ) {
+                               // pt on line pt[i+0]..pt[i+1] nearest cx,cy
+                               TracerPoint *pt0 = points[i+0];
+                               TracerPoint *pt1 = i+1<sz ? points[i+1] : points[0];
+                               float x0 = pt0->x, y0 = pt0->y;
+                               float x1 = pt1->x, y1 = pt1->y;
+                               float dx = x1-x0, dy = y1-y0;
+                               float rr = dx*dx + dy*dy;
+                               if( !rr ) continue;
+                               float u = ((x1-output_x)*dx + (y1-output_y)*dy) / rr;
+                               if( u < 0 || u > 1 ) continue;  // past endpts
+                               float x = x0*u + x1*(1-u);
+                               float y = y0*u + y1*(1-u);
+                               dx = output_x-x;  dy = output_y-y;
+                               float dd = dx*dx + dy*dy;       // d**2 closest approach
+                               if( mx > dd ) { mx = dd;  k = i; }
+                       }
+                       TracerPoint *pt = points[sz=plugin->new_point()];
+                       int hot_point = k+1;
+                       for( int i=sz; i>hot_point; --i ) points[i] = points[i-1];
+                       points[hot_point] = pt;
+                       pt->x = output_x;  pt->y = output_y;
+                       point_list->update(hot_point);
+                       break; }
+               case LEFT_BUTTON: {
+                       int hot_point = -1, sz = points.size();
+                       if( sz > 0 ) {
                                TracerPoint *pt = points[hot_point=0];
                                double dist = DISTANCE(output_x,output_y, pt->x,pt->y);
                                for( int i=1; i<sz; ++i ) {
                                TracerPoint *pt = points[hot_point=0];
                                double dist = DISTANCE(output_x,output_y, pt->x,pt->y);
                                for( int i=1; i<sz; ++i ) {
@@ -264,7 +316,11 @@ int TracerWindow::do_grab_event(XEvent *event)
                                point_list->update_list(hot_point);
                        }
                        break; }
                                point_list->update_list(hot_point);
                        }
                        break; }
-               case MotionNotify: {
+               }
+               break; }
+       case MotionNotify: {
+               switch( button_no ) {
+               case LEFT_BUTTON: {
                        int hot_point = point_list->get_selection_number(0, 0);
                        if( hot_point >= 0 && hot_point < points.size() ) {
                                TracerPoint *pt = points[hot_point];
                        int hot_point = point_list->get_selection_number(0, 0);
                        if( hot_point >= 0 && hot_point < points.size() ) {
                                TracerPoint *pt = points[hot_point];
@@ -276,11 +332,7 @@ int TracerWindow::do_grab_event(XEvent *event)
                                point_list->update_list(hot_point);
                        }
                        break; }
                                point_list->update_list(hot_point);
                        }
                        break; }
-               }
-       }
-       else {
-               switch( event->type ) {
-               case MotionNotify: {
+               case MIDDLE_BUTTON: {
                        float dx = output_x - last_x, dy = output_y - last_y;
                        int sz = points.size();
                        for( int i=0; i<sz; ++i ) {
                        float dx = output_x - last_x, dy = output_y - last_y;
                        int sz = points.size();
                        for( int i=0; i<sz; ++i ) {
@@ -297,6 +349,7 @@ int TracerWindow::do_grab_event(XEvent *event)
                        }
                        break; }
                }
                        }
                        break; }
                }
+               break; }
        }
 
        last_x = output_x;  last_y = output_y;
        }
 
        last_x = output_x;  last_y = output_y;
@@ -391,9 +444,11 @@ int TracerPointList::set_selected(int k)
 }
 void TracerPointList::update_list(int k)
 {
 }
 void TracerPointList::update_list(int k)
 {
-       int xpos = get_xposition(), ypos = get_yposition();
-       if( k < 0 ) k = get_selection_number(0, 0);
+       int sz = plugin->config.points.size();
+       if( k < 0 || k >= sz ) k = -1;
+       plugin->config.selected = k;
        update_selection(&cols[0], k);
        update_selection(&cols[0], k);
+       int xpos = get_xposition(), ypos = get_yposition();
        BC_ListBox::update(&cols[0], &titles[0],&widths[0],PT_SZ, xpos,ypos,k);
        center_selection();
 }
        BC_ListBox::update(&cols[0], &titles[0],&widths[0],PT_SZ, xpos,ypos,k);
        center_selection();
 }
@@ -411,9 +466,7 @@ void TracerPointList::update(int k)
        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());
        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;
        }
        }
-
        update_list(k);
 }
 
        update_list(k);
 }
 
@@ -423,9 +476,9 @@ void TracerWindow::update_gui()
        drag->update(config.drag);
        draw->update(config.draw);
        fill->update(config.fill);
        drag->update(config.drag);
        draw->update(config.draw);
        fill->update(config.fill);
+       feather->update(config.feather);
        radius->update(config.radius);
        radius->update(config.radius);
-       scale->update(config.scale);
-       drag->update(config.drag);
+       invert->update(config.invert);
        point_list->update(-1);
 }
 
        point_list->update(-1);
 }
 
@@ -525,26 +578,26 @@ int TracerFill::handle_event()
        return 1;
 }
 
        return 1;
 }
 
-TracerRadius::TracerRadius(TracerWindow *gui, int x, int y, int w)
- : BC_ISlider(x,y,0,w,w, -50,50, gui->plugin->config.radius)
+TracerFeather::TracerFeather(TracerWindow *gui, int x, int y, int w)
+ : BC_ISlider(x,y,0,w,w, -50,50, gui->plugin->config.feather)
 {
        this->gui = gui;
 }
 {
        this->gui = gui;
 }
-int TracerRadius::handle_event()
+int TracerFeather::handle_event()
 {
 {
-       gui->plugin->config.radius = get_value();
+       gui->plugin->config.feather = get_value();
        gui->send_configure_change();
        return 1;
 }
 
        gui->send_configure_change();
        return 1;
 }
 
-TracerScale::TracerScale(TracerWindow *gui, int x, int y, int w)
- : BC_FSlider(x,y, 0,w,w, 1.f,10.f, gui->plugin->config.scale)
+TracerRadius::TracerRadius(TracerWindow *gui, int x, int y, int w)
+ : BC_FSlider(x,y, 0,w,w, -5.f,5.f, gui->plugin->config.radius)
 {
        this->gui = gui;
 }
 {
        this->gui = gui;
 }
-int TracerScale::handle_event()
+int TracerRadius::handle_event()
 {
 {
-       gui->plugin->config.scale = get_value();
+       gui->plugin->config.radius = get_value();
        gui->send_configure_change();
        return 1;
 }
        gui->send_configure_change();
        return 1;
 }
@@ -581,10 +634,7 @@ int TracerDelPoint::handle_event()
        TracerPoints &points = plugin->config.points;
        if( hot_point >= 0 && hot_point < points.size() ) {
                plugin->config.del_point(hot_point);
        TracerPoints &points = plugin->config.points;
        if( hot_point >= 0 && hot_point < points.size() ) {
                plugin->config.del_point(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->point_list->update(--hot_point);
                gui->send_configure_change();
        }
        return 1;
                gui->send_configure_change();
        }
        return 1;
@@ -602,18 +652,41 @@ TracerReset::~TracerReset()
 int TracerReset::handle_event()
 {
        TracerConfig &config = plugin->config;
 int TracerReset::handle_event()
 {
        TracerConfig &config = plugin->config;
-       config.drag = 0;
-       config.draw = 0;
+       if( !config.drag ) {
+               MWindow *mwindow = plugin->server->mwindow;
+               CWindowGUI *cwindow_gui = mwindow->cwindow->gui;
+               if( gui->grab(cwindow_gui) )
+                       config.drag = 1;
+               else
+                       gui->drag->flicker(10,50);
+       }
+       config.draw = 1;
        config.fill = 0;
        config.fill = 0;
-       config.radius = 0;
-       config.scale = 1;
-       config.selected = 0;
+       config.invert = 0;
+       config.feather = 0;
+       config.radius = 1;
+       config.selected = -1;
        TracerPoints &points = plugin->config.points;
        points.remove_all_objects();
        TracerPoints &points = plugin->config.points;
        points.remove_all_objects();
-       plugin->new_point();
-       gui->point_list->update(0);
+       gui->point_list->update(-1);
        gui->update_gui();
        gui->send_configure_change();
        return 1;
 }
 
        gui->update_gui();
        gui->send_configure_change();
        return 1;
 }
 
+TracerInvert::TracerInvert(TracerWindow *gui, Tracer *plugin, int x, int y)
+ : BC_CheckBox(x, y, gui->plugin->config.invert, _("Invert"))
+{
+       this->gui = gui;
+       this->plugin = plugin;
+}
+TracerInvert::~TracerInvert()
+{
+}
+int TracerInvert::handle_event()
+{
+       plugin->config.invert = get_value();
+       gui->send_configure_change();
+       return 1;
+}
+
index b6231cf7757baaefc9dd1f1be110664c193f6605..7553282297fa08b961e861c39ff456d3a3eade80 100644 (file)
@@ -31,14 +31,15 @@ class TracerPointY;
 class TracerDrag;
 class TracerDraw;
 class TracerFill;
 class TracerDrag;
 class TracerDraw;
 class TracerFill;
+class TracerFeather;
 class TracerRadius;
 class TracerRadius;
-class TracerScale;
 class TracerPointList;
 class TracerNewPoint;
 class TracerDelPoint;
 class TracerPointUp;
 class TracerPointDn;
 class TracerReset;
 class TracerPointList;
 class TracerNewPoint;
 class TracerDelPoint;
 class TracerPointUp;
 class TracerPointDn;
 class TracerReset;
+class TracerInvert;
 
 
 class TracerNum : public BC_TumbleTextBox
 
 
 class TracerNum : public BC_TumbleTextBox
@@ -104,19 +105,19 @@ public:
        TracerWindow *gui;
 };
 
        TracerWindow *gui;
 };
 
-class TracerRadius : public BC_ISlider
+class TracerFeather : public BC_ISlider
 {
 public:
 {
 public:
-       TracerRadius(TracerWindow *gui, int x, int y, int w);
+       TracerFeather(TracerWindow *gui, int x, int y, int w);
 
        int handle_event();
        TracerWindow *gui;
 };
 
 
        int handle_event();
        TracerWindow *gui;
 };
 
-class TracerScale : public BC_FSlider
+class TracerRadius : public BC_FSlider
 {
 public:
 {
 public:
-       TracerScale(TracerWindow *gui, int x, int y, int w);
+       TracerRadius(TracerWindow *gui, int x, int y, int w);
 
        int handle_event();
        TracerWindow *gui;
 
        int handle_event();
        TracerWindow *gui;
@@ -206,6 +207,18 @@ public:
        TracerWindow *gui;
 };
 
        TracerWindow *gui;
 };
 
+class TracerInvert : public BC_CheckBox
+{
+public:
+       TracerInvert(TracerWindow *gui, Tracer *plugin, int x, int y);
+       ~TracerInvert();
+
+       int handle_event();
+
+       Tracer *plugin;
+       TracerWindow *gui;
+};
+
 
 class TracerWindow : public PluginClientWindow
 {
 
 class TracerWindow : public PluginClientWindow
 {
@@ -229,16 +242,17 @@ public:
        TracerDelPoint *del_point;
        TracerPointUp *point_up;
        TracerPointDn *point_dn;
        TracerDelPoint *del_point;
        TracerPointUp *point_up;
        TracerPointDn *point_dn;
-       int dragging, pending_config;
+       int button_no, pending_config;
        float last_x, last_y;
        TracerDrag *drag;
        TracerDraw *draw;
        TracerFill *fill;
        BC_Title *title_r, *title_s;
        float last_x, last_y;
        TracerDrag *drag;
        TracerDraw *draw;
        TracerFill *fill;
        BC_Title *title_r, *title_s;
+       TracerFeather *feather;
        TracerRadius *radius;
        TracerRadius *radius;
-       TracerScale *scale;
        TracerPointList *point_list;
        TracerReset *reset;
        TracerPointList *point_list;
        TracerReset *reset;
+       TracerInvert *invert;
 };
 
 #endif
 };
 
 #endif