sketcher rework, plugindialog selection fixes, new ffmpeg plugin.opts/plugin info...
authorGood Guy <good1.2guy@gmail.com>
Sun, 18 Nov 2018 03:01:09 +0000 (20:01 -0700)
committerGood Guy <good1.2guy@gmail.com>
Sun, 18 Nov 2018 03:01:09 +0000 (20:01 -0700)
cinelerra-5.1/cinelerra/plugindialog.C
cinelerra-5.1/cinelerra/track.C
cinelerra-5.1/cinelerra/vrender.C
cinelerra-5.1/expanders.txt
cinelerra-5.1/ffmpeg/plugin.opts
cinelerra-5.1/guicast/bclistbox.C
cinelerra-5.1/info/plugins.txt
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 439a6efb5d5feffb6d83f6b48bae9b94fd412dc7..ad964d52bbdef8801e530f21cf45d9d17b8599b9 100644 (file)
@@ -258,18 +258,19 @@ void PluginDialog::create_objects()
                thread->data_type);
 
 // Construct listbox items
                thread->data_type);
 
 // Construct listbox items
-       for(int i = 0; i < plugin_locations.total; i++)
+       for(int i = 0; i < plugin_locations.total; )
        {
                Track *track = mwindow->edl->tracks->number(plugin_locations.values[i]->module);
                char *track_title = track->title;
                int number = plugin_locations.values[i]->plugin;
                double start = mwindow->edl->local_session->get_selectionstart(1);
                Plugin *plugin = track->get_current_plugin(start, number, PLAY_FORWARD, 1, 0);
        {
                Track *track = mwindow->edl->tracks->number(plugin_locations.values[i]->module);
                char *track_title = track->title;
                int number = plugin_locations.values[i]->plugin;
                double start = mwindow->edl->local_session->get_selectionstart(1);
                Plugin *plugin = track->get_current_plugin(start, number, PLAY_FORWARD, 1, 0);
-               if( !plugin ) continue;
+               if( !plugin ) { plugin_locations.remove_object_number(i);  continue; }
                char string[BCTEXTLEN];
                const char *plugin_title = _(plugin->title);
                snprintf(string, sizeof(string), "%s: %s", track_title, plugin_title);
                shared_data.append(new BC_ListBoxItem(string));
                char string[BCTEXTLEN];
                const char *plugin_title = _(plugin->title);
                snprintf(string, sizeof(string), "%s: %s", track_title, plugin_title);
                shared_data.append(new BC_ListBoxItem(string));
+               ++i;
        }
        for(int i = 0; i < module_locations.total; i++)
        {
        }
        for(int i = 0; i < module_locations.total; i++)
        {
index bac9abd68050bed5c1f8908fa9e92e239f8e4b7d..4afeeab86d9a369a09549ab546aa66b201b88165 100644 (file)
@@ -517,7 +517,7 @@ Plugin* Track::insert_effect(const char *title,
                if(source_track)
                {
                        Plugin *source_plugin = source_track->get_current_plugin(
                if(source_track)
                {
                        Plugin *source_plugin = source_track->get_current_plugin(
-                               edl->local_session->get_selectionstart(),
+                               edl->local_session->get_selectionstart(1),
                                shared_location->plugin,
                                PLAY_FORWARD,
                                1,
                                shared_location->plugin,
                                PLAY_FORWARD,
                                1,
index 42f83ef87e7d86e57a2c84a8bf7b4781fad41984..770dfb8877e168e7f92be2e7123ce4f653801e06 100644 (file)
@@ -61,7 +61,7 @@ VRender::VRender(RenderEngine *renderengine)
 {
        data_type = TRACK_VIDEO;
        transition_temp = 0;
 {
        data_type = TRACK_VIDEO;
        transition_temp = 0;
-       overlayer = new OverlayFrame(renderengine->preferences->processors);
+       overlayer = new OverlayFrame(renderengine->preferences->project_smp);
        input_temp = 0;
        vmodule_render_fragment = 0;
        playback_buffer = 0;
        input_temp = 0;
        vmodule_render_fragment = 0;
        playback_buffer = 0;
index b4a2d6e90680c4b629cbda6cd4b7826ed74bb478..507b611cdd0b4719294855e55530d1d8e60110be 100644 (file)
@@ -42,6 +42,7 @@ Video Effects
                F_tlut2
                F_vectorscope
                F_vignette
                F_tlut2
                F_vectorscope
                F_vignette
+               F_vibrance
        - Motion
                Motion
                Motion 2 Point
        - Motion
                Motion
                Motion 2 Point
@@ -75,6 +76,7 @@ Video Effects
                F_atadenoise
                F_bitplanenoise
                F_dctdnoiz
                F_atadenoise
                F_bitplanenoise
                F_dctdnoiz
+               F_fftdnoiz
                F_hqdn3d
                F_nlmeans
                F_noise
                F_hqdn3d
                F_nlmeans
                F_noise
index 27fcfaed52d37d73f12771ee853a73df3636fe2d..e59ea6a3c81fa62829ea3e161343ae2e3b1c30b6 100644 (file)
@@ -13,7 +13,7 @@ aeval exprs=(sin(2*PI*t*440)+sin(2*PI*t*350))/2*mod(floor(2*t),2):channel_layout
 #aevalsrc 0
 afade
 #afftfilt 1-clip((b/nb)*b,0,1)
 #aevalsrc 0
 afade
 #afftfilt 1-clip((b/nb)*b,0,1)
-#afifo
+#afifo  ###will not work within cin
 aformat sample_fmts=u8|s16:channel_layouts=stereo
 agate
 #ahistogram dmode=single:r=25:s=hd720:scale=log:ascale=log:slide=replace
 aformat sample_fmts=u8|s16:channel_layouts=stereo
 agate
 #ahistogram dmode=single:r=25:s=hd720:scale=log:ascale=log:slide=replace
@@ -26,7 +26,7 @@ aloop
 #alphaextract
 #alphamerge
 #amerge
 #alphaextract
 #alphamerge
 #amerge
-#ametadata mode=print:file=ametadata.txt
+ametadata mode=print:file=/tmp/ametadata.txt
 #amix
 #amovie
 #anequalizer c0 f=200 w=100 g=-10 t=1|c1 f=200 w=100 g=-10 t=1
 #amix
 #amovie
 #anequalizer c0 f=200 w=100 g=-10 t=1|c1 f=200 w=100 g=-10 t=1
@@ -34,7 +34,7 @@ anoisesrc d=60:c=pink:r=48000:a=0.5
 #anull
 #anullsink
 #anullsrc
 #anull
 #anullsink
 #anullsrc
-#apad pad_len=1024
+#apad   ###not part of frame data
 aperms
 #aphasemeter r=25:s=800x400:rc=2:gc=7:bc=1
 aphaser
 aperms
 #aphasemeter r=25:s=800x400:rc=2:gc=7:bc=1
 aphaser
@@ -45,10 +45,10 @@ aresample sample_rate=48000
 #aselect
 #asendcmd
 #asetnsamples
 #aselect
 #asendcmd
 #asetnsamples
-#asetpts PTS-STARTPTS
+#asetpts   ###not part of frame data
 asetrate r=48000
 #asettb
 asetrate r=48000
 #asettb
-#ashowinfo
+#ashowinfo ###not part of frame data
 #asidedata
 #asplit
 astats
 #asidedata
 #asplit
 astats
@@ -125,7 +125,7 @@ field
 #fieldhint
 #fieldmatch
 fieldorder
 #fieldhint
 #fieldmatch
 fieldorder
-#fifo
+#fifo   ###will not work within cin
 fillborders
 #find_rect
 #firequalizer delay=0.1:fixed=on:zero_phase=on
 fillborders
 #find_rect
 #firequalizer delay=0.1:fixed=on:zero_phase=on
@@ -139,8 +139,8 @@ fspp
 gblur
 #geq
 gradfun
 gblur
 #geq
 gradfun
-#haldclut
-#haldclutsrc
+#haldclut ###not working due to need for multiple video streams
+haldclutsrc
 #hdcd
 hflip
 highpass
 #hdcd
 hflip
 highpass
@@ -177,7 +177,7 @@ mandelbrot
 mcdeint
 #mergeplanes 0x03010200:yuva444p
 mestimate
 mcdeint
 #mergeplanes 0x03010200:yuva444p
 mestimate
-#metadata mode=print:file=metadata.txt
+metadata mode=print:file=/tmp/metadata.txt
 #midequalizer
 #minterpolate
 #movie
 #midequalizer
 #minterpolate
 #movie
@@ -186,7 +186,7 @@ mptestsrc t=dc_luma
 negate
 nlmeans r=15:p=7:s=2
 #nnedi
 negate
 nlmeans r=15:p=7:s=2
 #nnedi
-#noformat pix_fmts=yuv420p
+#noformat ###not part of frame data
 noise
 #null
 #nullsink
 noise
 #null
 #nullsink
@@ -196,7 +196,7 @@ owdenoise
 pad
 #palettegen
 #paletteuse
 pad
 #palettegen
 #paletteuse
-#pan 1c|c0=0.9*c0+0.1*c1
+pan 1c|c0=0.9*c0+0.1*c1
 perms
 perspective
 phase
 perms
 perspective
 phase
@@ -207,7 +207,7 @@ pp7
 prewitt
 #psnr PSNR=10*log10(MAX^2/MSE)
 #pullup
 prewitt
 #psnr PSNR=10*log10(MAX^2/MSE)
 #pullup
-#qp 2+2*sin(PI*qp)
+#qp     ###not part of frame data
 #random seed=-1
 readeia608
 readvitc
 #random seed=-1
 readeia608
 readvitc
@@ -227,14 +227,14 @@ scale 200:100
 #selectivecolor greens=.5 0 -.33 0:blues=0 .27
 #sendcmd
 separatefields
 #selectivecolor greens=.5 0 -.33 0:blues=0 .27
 #sendcmd
 separatefields
-#setdar dar=16/9
-#setfield mode=auto
-#setpts PTS-STARTPTS
-#setsar sar=10/11
+#setdar   ###will not work because Format already set
+#setfield ###not part of frame data
+#setpts   ###not part of frame data
+#setsar   ###will not work because Format already set
 #settb
 #showcqt
 #showfreqs
 #settb
 #showcqt
 #showfreqs
-showinfo
+#showinfo ###not part of frame data
 showpalette s=30
 #showspectrum s=1280x480:scale=log
 #showspectrumpic
 showpalette s=30
 #showspectrum s=1280x480:scale=log
 #showspectrumpic
@@ -245,15 +245,15 @@ shuffleframes
 shuffleplanes
 #sidechaincompress
 #sidechaingate
 shuffleplanes
 #sidechaincompress
 #sidechaingate
-#sidedata mode=delete
+#sidedata mode=add
 signalstats
 #signature
 signalstats
 #signature
-#silencedetect n=0.001
+#silencedetect n=0.001  ###does not appear to work
 silenceremove
 sine
 smartblur
 silenceremove
 sine
 smartblur
-#smptebars
-#smptehdbars
+smptebars
+smptehdbars
 sobel
 #spectrumsynth
 #split
 sobel
 #spectrumsynth
 #split
@@ -318,7 +318,7 @@ tlut2
 #tonemap
 #vmafmotion
 ; new in 4.0
 #tonemap
 #vmafmotion
 ; new in 4.0
-#acontrast Contrast=33
+acontrast
 #afir
 #convolve
 #deconvolve
 #afir
 #convolve
 #deconvolve
@@ -338,14 +338,14 @@ acue
 #adeclick
 #adeclip
 aderivative
 #adeclick
 #adeclip
 aderivative
-afftdn
+#afftdn
 aintegral
 amplify
 chromahold
 aintegral
 amplify
 chromahold
-cue
+#cue    ###freeze
 deblock
 fttdnoiz
 deblock
 fttdnoiz
-#graphmonitor
+graphmonitor
 greyedge
 #highshelf
 #lowshelf
 greyedge
 #highshelf
 #lowshelf
@@ -353,14 +353,14 @@ lut1d
 pal75bars
 pal100bars
 setparams
 pal75bars
 pal100bars
 setparams
-#sinc
+#sinc   ###freeze
 tmix
 vibrance
 ; broken in 4.1
 #acrossover
 #aiir
 #amultiply
 tmix
 vibrance
 ; broken in 4.1
 #acrossover
 #aiir
 #amultiply
-#bm3d
+#bm3d sigma=3:block=4:bstep=2:group=1:estim=basic
 #sr
 #xstack
 #agraphmonitor
 #sr
 #xstack
 #agraphmonitor
index 2dd4283c990fc325d4caf6edc68068c882a4b035..4a55593fae1e2d23479905b3c8c3dd3c6e620919 100644 (file)
@@ -1643,6 +1643,7 @@ int BC_ListBox::center_selection(int selection,
                                        yposition = item->text_y - top_item->text_y - view_h / 2;
                                }
                        }
                                        yposition = item->text_y - top_item->text_y - view_h / 2;
                                }
                        }
+                       if( yposition < 0 ) yposition = 0;
                        return 1;
                }
 
                        return 1;
                }
 
@@ -2645,11 +2646,9 @@ int BC_ListBox::button_press_event()
                        }
 // Select single item
                        else {
                        }
 // Select single item
                        else {
-                               if( !current_item->selected ) {
+                               if( !current_item->selected || !new_value ) {
                                        set_all_selected(data, 0);
                                        set_all_selected(data, 0);
-                                       set_selected(data,
-                                               selection_number,
-                                               1);
+                                       set_selected(data, selection_number, 1);
                                }
                                new_value = 1;
                        }
                                }
                                new_value = 1;
                        }
@@ -3033,9 +3032,6 @@ int BC_ListBox::cursor_motion_event()
                        if( (display_format == LISTBOX_TEXT ||
                             display_format == LISTBOX_ICON_LIST) &&
                                shift_down() ) {
                        if( (display_format == LISTBOX_TEXT ||
                             display_format == LISTBOX_ICON_LIST) &&
                                shift_down() ) {
-// Deselect everything.
-                               set_all_selected(data, 0);
-
 // Select just the items
                                redraw = expand_selection(0, selection_number);
                        }
 // Select just the items
                                redraw = expand_selection(0, selection_number);
                        }
index 86e83395b0d0a83e55561dbe46af179cee3d7574..fc19135492f8118b2fbbf41aa2e2a22c76f20a64 100644 (file)
@@ -214,6 +214,7 @@ Zoom Blur:  Blur the video and use a zoom effect.
 #
 #  Description of FFmpeg Video Plugins
 #
 #
 #  Description of FFmpeg Video Plugins
 #
+F_amplify:     Amplify changes between successive video frames.
 F_atadenoise:  Apply an Adaptive Temporal Averaging Denoiser.
 F_avgblur:     Apply average blur filter.
 F_bbox:                Compute bounding box for each frame.
 F_atadenoise:  Apply an Adaptive Temporal Averaging Denoiser.
 F_avgblur:     Apply average blur filter.
 F_bbox:                Compute bounding box for each frame.
@@ -226,6 +227,7 @@ F_boxblur:  Blurs the input video.
                able to change the power and the
                radius of the boxblur applied to luma, chroma and alpha.
 F_bwdif:       Deinterlaces the input image.
                able to change the power and the
                radius of the boxblur applied to luma, chroma and alpha.
 F_bwdif:       Deinterlaces the input image.
+F_chromahold:  Turns a certain color range into gray.
 F_chromakey:   Turns a certain color into
                transparency.  Operates on YUV colors.
 F_ciescope:    Video CIE scope.
 F_chromakey:   Turns a certain color into
                transparency.  Operates on YUV colors.
 F_ciescope:    Video CIE scope.
@@ -243,6 +245,7 @@ F_curves:   Adjust components curves.
 F_datascope:   Video data analysis.
 F_dctdnoiz:    Denoise frames using 2D DCT.
 F_deband:      Debands video.
 F_datascope:   Video data analysis.
 F_dctdnoiz:    Denoise frames using 2D DCT.
 F_deband:      Debands video.
+F_deblock:     Deblock video.
 F_deflate:     Applies deflate effect.
 F_deflicker:   Remove temporal frame luminance variations.
 F_dejudder:    Removes judder produced by pullup.
 F_deflate:     Applies deflate effect.
 F_deflicker:   Remove temporal frame luminance variations.
 F_dejudder:    Removes judder produced by pullup.
@@ -276,6 +279,7 @@ F_eq:               Adjusts brightness, contrast, gamma and saturation.
 F_entropy:     Measure video frames entropy.
 F_erosion:     Applies erosion effect.
 F_fade:                Fade in/out input video.
 F_entropy:     Measure video frames entropy.
 F_erosion:     Applies erosion effect.
 F_fade:                Fade in/out input video.
+F_fftdnoiz:    Denoise rames using 3D FFT.
 F_fftfilt:     Apply arbitrary expressions to pixels in frequency domain.
 F_field:       Extract a field from the input video.
 F_fieldorder:  Set the field order.
 F_fftfilt:     Apply arbitrary expressions to pixels in frequency domain.
 F_field:       Extract a field from the input video.
 F_fieldorder:  Set the field order.
@@ -284,9 +288,13 @@ F_floodfill:       Fill area of the same color with another color.
 F_format:      Convert the input video to one of the specified pixel formats.
 F_framerate:   Upsamples or downsamples progressive
                source between specified frame rates.
 F_format:      Convert the input video to one of the specified pixel formats.
 F_framerate:   Upsamples or downsamples progressive
                source between specified frame rates.
+F_framestep:   Select one frame every N frames.
 F_fspp:                Applies Fast Simple Post-processing filter.
 F_gblur:       Apply Gaussian Blur filter.
 F_gradfun:     Debands video quickly using gradients.
 F_fspp:                Applies Fast Simple Post-processing filter.
 F_gblur:       Apply Gaussian Blur filter.
 F_gradfun:     Debands video quickly using gradients.
+F_graphmonitor:        Show various filtergraph stats.
+F_greyedge:    Estimates scene illumination by grey edge assumption.
+F_haldclutsrc: Provide an identity Hald CLUT.
 F_hflip:       Horizontally flips the input video.
 F_histeq:      Applies global color histogram equalization.
 F_histogram:   Computes and draws a histogram.
 F_hflip:       Horizontally flips the input video.
 F_histeq:      Applies global color histogram equalization.
 F_histogram:   Computes and draws a histogram.
@@ -300,18 +308,20 @@ F_inflate:        Applies inflate effect.
 F_interlace:   Convert progressive video into interlaced.
 F_kerndeint:   Applies kernel deinterlacing to the input.
 F_lenscorrection: Rectifies the image by correcting for lens distortion.
 F_interlace:   Convert progressive video into interlaced.
 F_kerndeint:   Applies kernel deinterlacing to the input.
 F_lenscorrection: Rectifies the image by correcting for lens distortion.
-F_Life:                Generate a life pattern.
+F_life:                Generate a life pattern.
 F_limiter:     Limit pixels components to the specified range.
 F_loop:                Loops video frames.
 F_lumakey:     Turns a certain luma into transparency.
 F_lut:         Compute and apply a lookup
                table to the RGB/YUV input video.
 F_limiter:     Limit pixels components to the specified range.
 F_loop:                Loops video frames.
 F_lumakey:     Turns a certain luma into transparency.
 F_lut:         Compute and apply a lookup
                table to the RGB/YUV input video.
+F_lut1d:       Adjust colors using a 1D LUT.
 F_lut3d:       Apply a 3D LUT (look up table) to an input video.
 F_lutrgb:      Compute and apply a lookup table to the RGB input video.
 F_lutyuv:      Combine and apply a lookup table to the YUV input video.
 F_mandelbrot:  Render a Mandelbrot fractal.
 F_mcdeint:     Applies motion compensating deinterlacing.
 F_mestimate:   Generate motion vectors.
 F_lut3d:       Apply a 3D LUT (look up table) to an input video.
 F_lutrgb:      Compute and apply a lookup table to the RGB input video.
 F_lutyuv:      Combine and apply a lookup table to the YUV input video.
 F_mandelbrot:  Render a Mandelbrot fractal.
 F_mcdeint:     Applies motion compensating deinterlacing.
 F_mestimate:   Generate motion vectors.
+F_metadata:    Manipulate video frame metadata.
 F_mpdecimate:  Remove near-duplicate frames.
 F_mptestsrc:   Generate various test pattern.
 F_negate:      Negates input video.
 F_mpdecimate:  Remove near-duplicate frames.
 F_mptestsrc:   Generate various test pattern.
 F_negate:      Negates input video.
@@ -326,8 +336,10 @@ F_owdenoise:       Denoises using wavelets.
 F_oscilloscope:        2D video oscilloscope.  Useful to measure spatial impulse,
                step responses, and chroma delays.
 F_owndenoise:  Denoises using wavelets.
 F_oscilloscope:        2D video oscilloscope.  Useful to measure spatial impulse,
                step responses, and chroma delays.
 F_owndenoise:  Denoises using wavelets.
-F_Pad:         Add paddings to the input image, and place the original
+F_pad:         Add paddings to the input image, and place the original
                input at the provided x, y coordinates.
                input at the provided x, y coordinates.
+F_pal100bars:  Generate PAL 100% color bars.
+F_pal75bars:   Generate PAL 75% color bars.
 F_perms:       Set permissions for the output video frame.
 F_perspective: Corrects the perspective of video.
 F_phase:       Phases shift fields.
 F_perms:       Set permissions for the output video frame.
 F_perspective: Corrects the perspective of video.
 F_phase:       Phases shift fields.
@@ -353,6 +365,7 @@ F_rotate:   Rotates the input image.
 F_sab:         Applies shape adaptive blur.
 F_scale:       Scale the input video size and/or convert the image format.
 F_separatefields: Split input video frames into fields.
 F_sab:         Applies shape adaptive blur.
 F_scale:       Scale the input video size and/or convert the image format.
 F_separatefields: Split input video frames into fields.
+F_setparams:   Force field, or color property for the output video frame.
 F_setrange:    Force color range for the output video frame.
 F_showinfo:    Show textual information for each video frame.
 F_showpalette: Display frame palette.
 F_setrange:    Force color range for the output video frame.
 F_showinfo:    Show textual information for each video frame.
 F_showpalette: Display frame palette.
@@ -363,6 +376,8 @@ F_smartblur:        Blurs the input video without impacting
                the outlines. Through the settings you can
                select the radius,
                the strength and the threshold of luma and chroma.
                the outlines. Through the settings you can
                select the radius,
                the strength and the threshold of luma and chroma.
+F_smptebars:   Generate SMPTE color bars.
+F_smptehdbars: Generate SMPTE HD color bars.
 F_sobel:       Applies sobel operator.
 F_spp:         Applies a simple post processing filter.
 F_stereo3d:    Converts video stereoscopic 3D view.
 F_sobel:       Applies sobel operator.
 F_spp:         Applies a simple post processing filter.
 F_stereo3d:    Converts video stereoscopic 3D view.
@@ -376,6 +391,7 @@ F_testsrc2: Generate another test pattern.
 F_tile:                Tile several successive frames together.
 F_tinterlace:  Performs temporal field interlacing.
 F_tlut2:       Compute and apply a lookup table from 2 successive frames.
 F_tile:                Tile several successive frames together.
 F_tinterlace:  Performs temporal field interlacing.
 F_tlut2:       Compute and apply a lookup table from 2 successive frames.
+F_tmix:                Mix successive video frames.
 F_transpose:   Transposes input video.
 F_unsharp:     Sharpen or blur the input video.
 F_uspp:                Applies Ultra Simple/Slow Post-processing filter.
 F_transpose:   Transposes input video.
 F_unsharp:     Sharpen or blur the input video.
 F_uspp:                Applies Ultra Simple/Slow Post-processing filter.
@@ -383,6 +399,7 @@ F_vaguedenoiser: Applies a Wavelet based Denoiser.
 F_vectorscope: Video vectorscope.
 F_vflip:       Flips the input video vertically.
 F_vfrdet:      Variable frame rate detect filter.
 F_vectorscope: Video vectorscope.
 F_vflip:       Flips the input video vertically.
 F_vfrdet:      Variable frame rate detect filter.
+F_vibrance:    Boost or alter saturation.
 F_vignette:    Makes or reverses a vignette effect.
                Through the settings you can set the circle center
                position on a X-Y axis,choose the angle,
 F_vignette:    Makes or reverses a vignette effect.
                Through the settings you can set the circle center
                position on a X-Y axis,choose the angle,
@@ -401,7 +418,9 @@ F_abench:   Benchmark part of a filtergraph.
 F_acompressor: Audio compressor.
 F_acontrast:   Simple audio dynamic range compression/expansion filter.
 F_acrusher:    Reduces audio bit resolution.
 F_acompressor: Audio compressor.
 F_acontrast:   Simple audio dynamic range compression/expansion filter.
 F_acrusher:    Reduces audio bit resolution.
+F_acue:                Delay filtering to match a cue.
 F_adelay:      Delays one or more audio channels.
 F_adelay:      Delays one or more audio channels.
+F_aderivative: Compute derivative of input audio.
 F_aecho:       Adds echoing to the audio.
 F_aemphasis:   Audio emphasis.
 F_aeval:       Filters audio signal according to a specific expression.
 F_aecho:       Adds echoing to the audio.
 F_aemphasis:   Audio emphasis.
 F_aeval:       Filters audio signal according to a specific expression.
@@ -410,8 +429,10 @@ F_aformat: Convert the input audio to one of the specified formats.
 F_agate:       Audio gate.
 F_aiir:                Apply infinite Impulse Response filter with supplied
                coefficients.
 F_agate:       Audio gate.
 F_aiir:                Apply infinite Impulse Response filter with supplied
                coefficients.
+F_aintegral:   Compute integral of input audio.
 F_allpass:     Applies a two-pole all-pass filter.
 F_aloop:       Loops audio samples.
 F_allpass:     Applies a two-pole all-pass filter.
 F_aloop:       Loops audio samples.
+F_ametadata:   Manipulate audio frame metadata.
 F_anoisesrc:   Generates a noise audio signal.
 F_aperms:      Set permissions for the output audio frame.
 F_aphaser:     Adds a phasing effect to the audio.
 F_anoisesrc:   Generates a noise audio signal.
 F_aperms:      Set permissions for the output audio frame.
 F_aphaser:     Adds a phasing effect to the audio.
@@ -466,6 +487,7 @@ F_lowpass:  Applies a low-pass filter with 3dB point frequency.
 F_mcompand:    Multiband compress or expand audiodynamic range. The input audio
                is divided into bands which is like the crossover of a loudspeaker,
                resulting in flat frequency response when absent compander action.
 F_mcompand:    Multiband compress or expand audiodynamic range. The input audio
                is divided into bands which is like the crossover of a loudspeaker,
                resulting in flat frequency response when absent compander action.
+F_pan:         Remix channels with coefficients (panning).
 F_silenceremove: Removes silence.
 F_sine:                Generate sine wave audio signal.
 F_stereotools: Applies various stereo tools.  When using this plugin,
 F_silenceremove: Removes silence.
 F_sine:                Generate sine wave audio signal.
 F_stereotools: Applies various stereo tools.  When using this plugin,
index a4ce51f9e55f215e0f682768e5eec4417c2a3a15..e3b61b192e15f85f030c4b69d80660c95a011ba0 100644 (file)
 #include "language.h"
 #include "vframe.h"
 
 #include "language.h"
 #include "vframe.h"
 
-void SketcherPoint::init(int id, int x, int y)
+void SketcherPoint::init(int id, int pty, int x, int y)
 {
 {
-       this->id = id;
+       this->id = id;  this->pty = pty;
        this->x = x;    this->y = y;
 }
 SketcherPoint::SketcherPoint(int id)
 {
        this->x = x;    this->y = y;
 }
 SketcherPoint::SketcherPoint(int id)
 {
-       init(id, 0, 0);
+       init(id, PTY_LINE, 0, 0);
 }
 }
-SketcherPoint::SketcherPoint(int id, int x, int y)
+SketcherPoint::SketcherPoint(int id, int pty, int x, int y)
 {
 {
-       init(id, x, y);
+       init(id, pty, x, y);
 }
 SketcherPoint::~SketcherPoint()
 {
 }
 SketcherPoint::~SketcherPoint()
 {
@@ -57,12 +57,13 @@ SketcherPoint::SketcherPoint(SketcherPoint &pt)
 int SketcherPoint::equivalent(SketcherPoint &that)
 {
        return this->id == that.id &&
 int SketcherPoint::equivalent(SketcherPoint &that)
 {
        return this->id == that.id &&
+               this->pty == that.pty &&
                this->x == that.x &&
                this->y == that.y ? 1 : 0;
 }
 void SketcherPoint::copy_from(SketcherPoint &that)
 {
                this->x == that.x &&
                this->y == that.y ? 1 : 0;
 }
 void SketcherPoint::copy_from(SketcherPoint &that)
 {
-       this->id = that.id;
+       this->id = that.id;  this->pty = that.pty;
        this->x = that.x;    this->y = that.y;
 }
 void SketcherPoint::save_data(FileXML &output)
        this->x = that.x;    this->y = that.y;
 }
 void SketcherPoint::save_data(FileXML &output)
@@ -70,6 +71,7 @@ void SketcherPoint::save_data(FileXML &output)
        char point[BCSTRLEN];
        sprintf(point,"/POINT_%d",id);
        output.tag.set_title(point+1);
        char point[BCSTRLEN];
        sprintf(point,"/POINT_%d",id);
        output.tag.set_title(point+1);
+       output.tag.set_property("TYPE", pty);
        output.tag.set_property("X", x);
        output.tag.set_property("Y", y);
        output.append_tag();
        output.tag.set_property("X", x);
        output.tag.set_property("Y", y);
        output.append_tag();
@@ -80,25 +82,26 @@ void SketcherPoint::save_data(FileXML &output)
 void SketcherPoint::read_data(FileXML &input)
 {
        id = atoi(input.tag.get_title() + 6);
 void SketcherPoint::read_data(FileXML &input)
 {
        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", 0.f);
        y = input.tag.get_property("Y", 0.f);
+       bclamp(pty, 0, PTY_SZ-1);
 }
 
 }
 
-void SketcherCurve::init(int id, int ty, int radius, int pen, int color)
+void SketcherCurve::init(int id, int pen, int radius, int color)
 {
        this->id = id;
 {
        this->id = id;
-       this->ty = ty;
        this->radius = radius;
        this->pen = pen;
        this->color = color;
 }
 SketcherCurve::SketcherCurve(int id)
 {
        this->radius = radius;
        this->pen = pen;
        this->color = color;
 }
 SketcherCurve::SketcherCurve(int id)
 {
-       init(id, 0, 1, 0, BLACK);
+       init(id, 1, PTY_LINE, CV_COLOR);
 }
 }
-SketcherCurve::SketcherCurve(int id, int ty,  int radius,int pen, int color)
+SketcherCurve::SketcherCurve(int id, int pen, int radius, int color)
 {
 {
-       init(id, ty, radius, pen, color);
+       init(id, pen, radius, color);
 }
 SketcherCurve::~SketcherCurve()
 {
 }
 SketcherCurve::~SketcherCurve()
 {
@@ -110,9 +113,8 @@ SketcherCurve::SketcherCurve(SketcherCurve &cv)
 int SketcherCurve::equivalent(SketcherCurve &that)
 {
        if( this->id != that.id ) return 0;
 int SketcherCurve::equivalent(SketcherCurve &that)
 {
        if( this->id != that.id ) return 0;
-       if( this->ty != that.ty ) return 0;
-       if( this->radius != that.radius ) return 0;
        if( this->pen != that.pen ) return 0;
        if( this->pen != that.pen ) return 0;
+       if( this->radius != that.radius ) 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;
@@ -124,9 +126,8 @@ int SketcherCurve::equivalent(SketcherCurve &that)
 void SketcherCurve::copy_from(SketcherCurve &that)
 {
        this->id = that.id;
 void SketcherCurve::copy_from(SketcherCurve &that)
 {
        this->id = that.id;
-       this->ty = that.ty;
-       this->radius = that.radius;
        this->pen = that.pen;
        this->pen = that.pen;
+       this->radius = that.radius;
        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);
@@ -135,14 +136,12 @@ void SketcherCurve::copy_from(SketcherCurve &that)
 }
 void SketcherCurve::save_data(FileXML &output)
 {
 }
 void SketcherCurve::save_data(FileXML &output)
 {
-       this->ty = ty;
        this->pen = pen;  this->color = color;
        char curve[BCSTRLEN];
        sprintf(curve,"/CURVE_%d",id);
        output.tag.set_title(curve+1);
        this->pen = pen;  this->color = color;
        char curve[BCSTRLEN];
        sprintf(curve,"/CURVE_%d",id);
        output.tag.set_title(curve+1);
-       output.tag.set_property("TYPE", ty);
-       output.tag.set_property("RADIUS", radius);
        output.tag.set_property("PEN", pen);
        output.tag.set_property("PEN", pen);
+       output.tag.set_property("RADIUS", radius);
        output.tag.set_property("COLOR", color);
        output.append_tag();
        output.append_newline();
        output.tag.set_property("COLOR", color);
        output.append_tag();
        output.append_newline();
@@ -155,13 +154,13 @@ void SketcherCurve::save_data(FileXML &output)
 void SketcherCurve::read_data(FileXML &input)
 {
        id = atoi(input.tag.get_title() + 6);
 void SketcherCurve::read_data(FileXML &input)
 {
        id = atoi(input.tag.get_title() + 6);
-       ty = input.tag.get_property("TYPE", 0);
+       pen = input.tag.get_property("PEN", PTY_OFF);
        radius = input.tag.get_property("RADIUS", 1.);
        radius = input.tag.get_property("RADIUS", 1.);
-       pen = input.tag.get_property("PEN", 0);
-       color = input.tag.get_property("COLOR", BLACK);
+       color = input.tag.get_property("COLOR", CV_COLOR);
+       bclamp(pen, 0, PEN_SZ-1);
 }
 
 }
 
-int Sketcher::new_curve(int ty, int radius, int pen, int color)
+int Sketcher::new_curve(int pen, int radius, int color)
 {
        SketcherCurves &curves = config.curves;
        int k = curves.size(), id = 1;
 {
        SketcherCurves &curves = config.curves;
        int k = curves.size(), id = 1;
@@ -169,7 +168,7 @@ int Sketcher::new_curve(int ty, int radius, int pen, 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, ty, radius, pen, color);
+       SketcherCurve *cv = new SketcherCurve(id, pen, radius, color);
        curves.append(cv);
        config.cv_selected = k;
        return k;
        curves.append(cv);
        config.cv_selected = k;
        return k;
@@ -177,22 +176,24 @@ int Sketcher::new_curve(int ty, int radius, int pen, int color)
 
 int Sketcher::new_curve()
 {
 
 int Sketcher::new_curve()
 {
-       return new_curve(0, 1, 0, BLACK);
+       return new_curve(PEN_XLANT, 1, CV_COLOR);
 }
 
 }
 
-int Sketcher::new_point(SketcherCurve *cv, int x, int y)
+int Sketcher::new_point(SketcherCurve *cv, int pty, int x, int y, int idx)
 {
 {
-       int k = cv->points.size(), id = 1;
-       for( int i=k; --i>=0; ) {
+       int id = 1;
+       for( int i=cv->points.size(); --i>=0; ) {
                int n = cv->points[i]->id;
                if( n >= id ) id = n + 1;
        }
                int n = cv->points[i]->id;
                if( n >= id ) id = n + 1;
        }
-       SketcherPoint *pt = new SketcherPoint(id, x, y);
-       cv->points.append(pt);
-       return k;
+       SketcherPoint *pt = new SketcherPoint(id, pty, x, y);
+       int n = cv->points.size();
+       if( idx < 0 || idx > n ) idx = n;
+       cv->points.insert(pt, idx);
+       return idx;
 }
 
 }
 
-int Sketcher::new_point()
+int Sketcher::new_point(int idx)
 {
        int ci = config.cv_selected;
        if( ci < 0 || ci >= config.curves.size() )
 {
        int ci = config.cv_selected;
        if( ci < 0 || ci >= config.curves.size() )
@@ -201,7 +202,7 @@ int Sketcher::new_point()
        EDLSession *session = get_edlsession();
        int x = !session ? 0.f : session->output_w / 2.f;
        int y = !session ? 0.f : session->output_h / 2.f;
        EDLSession *session = get_edlsession();
        int x = !session ? 0.f : session->output_w / 2.f;
        int y = !session ? 0.f : session->output_h / 2.f;
-       return new_point(cv, x, y);
+       return new_point(cv, PTY_LINE, x, y, idx);
 }
 
 REGISTER_PLUGIN(Sketcher)
 }
 
 REGISTER_PLUGIN(Sketcher)
@@ -259,9 +260,8 @@ void SketcherConfig::interpolate(SketcherConfig &prev, SketcherConfig &next,
                while( --k >= 0 && pcv->id != (ncv=next.curves[k])->id );
                if( k >= 0 ) {
                        cv->id = pcv->id;
                while( --k >= 0 && pcv->id != (ncv=next.curves[k])->id );
                if( k >= 0 ) {
                        cv->id = pcv->id;
-                       cv->ty = pcv->ty;
-                       cv->radius = pcv->radius;
                        cv->pen = pcv->pen;
                        cv->pen = pcv->pen;
+                       cv->radius = pcv->radius;
                        cv->color = pcv->color;
                        int prev_pt_sz = pcv->points.size(), next_pt_sz = ncv->points.size();
                        for( int j=0; j<prev_pt_sz; ++j ) {
                        cv->color = pcv->color;
                        int prev_pt_sz = pcv->points.size(), next_pt_sz = ncv->points.size();
                        for( int j=0; j<prev_pt_sz; ++j ) {
@@ -273,7 +273,7 @@ void SketcherConfig::interpolate(SketcherConfig &prev, SketcherConfig &next,
                                        x = x * prev_scale + nt->x * next_scale;
                                        y = y * prev_scale + nt->y * next_scale;
                                }
                                        x = x * prev_scale + nt->x * next_scale;
                                        y = y * prev_scale + nt->y * next_scale;
                                }
-                               cv->points.append(new SketcherPoint(pt.id, x, y));
+                               cv->points.append(new SketcherPoint(pt.id, pt.pty, x, y));
                        }
                }
                else
                        }
                }
                else
@@ -309,8 +309,8 @@ void Sketcher::save_data(KeyFrame *keyframe)
 
        output.tag.set_title("SKETCHER");
        output.tag.set_property("DRAG", config.drag);
 
        output.tag.set_title("SKETCHER");
        output.tag.set_property("DRAG", config.drag);
-       output.tag.set_property("CURVE_SELECTED", config.cv_selected);
-       output.tag.set_property("POINT_SELECTED", config.pt_selected);
+       output.tag.set_property("CV_SELECTED", config.cv_selected);
+       output.tag.set_property("PT_SELECTED", config.pt_selected);
        output.append_tag();
        output.append_newline();
        for( int i=0,n=config.curves.size(); i<n; ++i ) {
        output.append_tag();
        output.append_newline();
        for( int i=0,n=config.curves.size(); i<n; ++i ) {
@@ -354,9 +354,8 @@ void Sketcher::read_data(KeyFrame *keyframe)
                }
        }
 
                }
        }
 
-       if( !config.curves.size() ) {
-               new_curve(0, 1, 0, BLACK);
-       }
+       if( !config.curves.size() )
+               new_curve();
        config.limits();
 }
 
        config.limits();
 }
 
@@ -375,11 +374,11 @@ void Sketcher::update_gui()
 void Sketcher::draw_point(VFrame *vfrm, SketcherPoint *pt, int color, int d)
 {
        int r = d/2+1, x = pt->x, y = pt->y;
 void Sketcher::draw_point(VFrame *vfrm, SketcherPoint *pt, int color, int d)
 {
        int r = d/2+1, x = pt->x, y = pt->y;
+       vfrm->set_pixel_color(color);
        vfrm->draw_smooth(x-r,y+0, x-r, y-r, x+0,y-r);
        vfrm->draw_smooth(x+0,y-r, x+r, y-r, x+r,y+0);
        vfrm->draw_smooth(x+r,y+0, x+r, y+r, x+0,y+r);
        vfrm->draw_smooth(x+0,y+r, x-r, y+r, x-r,y+0);
        vfrm->draw_smooth(x-r,y+0, x-r, y-r, x+0,y-r);
        vfrm->draw_smooth(x+0,y-r, x+r, y-r, x+r,y+0);
        vfrm->draw_smooth(x+r,y+0, x+r, y+r, x+0,y+r);
        vfrm->draw_smooth(x+0,y+r, x-r, y+r, x-r,y+0);
-       vfrm->set_pixel_color(color);
        vfrm->draw_x(pt->x, pt->y, d);
 }
 void Sketcher::draw_point(VFrame *vfrm, SketcherPoint *pt, int color)
        vfrm->draw_x(pt->x, pt->y, d);
 }
 void Sketcher::draw_point(VFrame *vfrm, SketcherPoint *pt, int color)
@@ -435,156 +434,100 @@ VFrame *SketcherCurve::new_vpen(VFrame *out)
        return 0;
 }
 
        return 0;
 }
 
-void SketcherCurve::draw_line(VFrame *out)
+static int intersects_at(float &x, float &y,
+               float ax,float ay, float bx, float by, float cx,float cy,  // line slope ab thru c
+               float dx,float dy, float ex, float ey, float fx,float fy, // line slope de thru f
+               float mx=0)
 {
 {
-       SketcherPoint *pt0 = points[0];
-       VFrame *vpen = new_vpen(out);
-       out->set_pixel_color(color);
-       int n = points.size();
-       if( n >= 2 ) {
-               for( int pi=1; pi<n; ++pi ) {
-                       SketcherPoint *pt1 = points[pi];
-                       vpen->draw_line(pt0->x, pt0->y, pt1->x, pt1->y);
-                       pt0 = pt1;
-               }
-       }
-       else
-               vpen->draw_pixel(pt0->x, pt0->y);
-       delete vpen;
+       float badx = bx - ax, bady = by - ay;
+       float eddx = ex - dx, eddy = ey - dy;
+       float d = badx*eddy - bady*eddx;
+       int ret = 0;
+       if( fabsf(d) < 1 ) { ret = 1;  d = signbit(d) ? -1 : 1; }
+       x = (badx*cy*eddx - badx*eddx*fy + badx*eddy*fx - bady*cx*eddx) / d;
+       y = (badx*cy*eddy - bady*cx*eddy - bady*eddx*fy + bady*eddy*fx) / d;
+       if( mx > 0 ) { bclamp(x, -mx,mx);  bclamp(y, -mx,mx); }
+       return ret;
 }
 
 }
 
-/*
-# python
-from sympy import *
-var("x,y, ax,ay, bx,by, cx,cy, dx,dy")
-
-var("abdx,abdy, acdx,acdy, bddx,bddy, cddx,cddy");
-abdx = bx-ax;  abdy = by-ay;
-acdx = cx-ax;  acdy = cy-ay;
-bddx = dx-bx;  bddy = dy-by;
-cddx = dx-cx;  cddy = dy-cy;
-
-var("xc,yc, xd,yd, sx,sy");
-xc = (bx+dx)/2;  yc = (by+dy)/2;
-xd = cx-xc;      yd = cy-yc;
-ax = xc-xd;      ay = yc-yd;
-# line thru b with slope (c-a) intersects line thru c with slope (d-b)
-sx = solve(((x - bx) * acdy/acdx + by) - ((x - cx) * bddy/bddx + cy),x)
-sy = solve(((y - by) * acdx/acdy + bx) - ((y - cy) * bddx/bddy + cx),y)
-
-var("zx,zy, zdx,zdy, sx,sy, px,py, qx,qy");
-# point z = (b+c)/2
-zx = (bx+cx)/2;  zy = (by+cy)/2;
-zdx = (abdx+cddx)/2;  zdy = (abdy+cddy)/2;
-# line thru z with slope (d-a) intersects line thru b with slope (c-a)
-px = solve(((x-zx)*zdy/zdx + zy) - ((x-bx) * acdy/acdx + by),x);
-py = solve(((y-zy)*zdx/zdy + zx) - ((y-by) * acdx/acdy + bx),y);
-# line thru z with slope (c-a + d-b)/2 intersects line thru c with slope (d-b)
-qx = solve(((x-zx)*zdy/zdx + zy) - ((x-cx) * bddy/bddx + cy),x);
-qy = solve(((y-zy)*zdx/zdy + zx) - ((y-cy) * bddx/bddy + cx),y);
-*/
-
-static void smooth_sxy(
-       float ax, float ay, float bx, float by,
-       float cx, float cy, float dx, float dy,
-       float &sx, float &sy)
+static void smooth_axy(float &ax, float &ay,
+       float bx, float by, float cx, float cy, float dx, float dy)
 {
 {
-       float acdx = cx-ax, acdy = cy-ay;
-       float bddx = dx-bx, bddy = dy-by;
-       float d = acdx*bddy - acdy*bddx;
-       if( fabsf(d) < 1 ) d = 1;
-       sx = (acdx*bddx*by - acdx*bddx*cy + acdx*bddy*cx - acdy*bddx*bx) / d;
-       sy = (acdx*bddy*by - acdy*bddx*cy - acdy*bddy*bx + acdy*bddy*cx) / d;
-       bclamp(sx, -4095.f, 4095.f);
-       bclamp(sy, -4095.f, 4095.f);
-}
-
-static void smooth_pxy(
-       float ax, float ay, float bx, float by,
-       float cx, float cy, float dx, float dy,
-       float &px, float &py)
-{
-       float abdx = bx - ax, abdy = by - ay;
-       float acdx = cx - ax, acdy = cy - ay;
-       float cddx = dx - cx, cddy = dy - cy;
-       float d = (2*(abdx*acdy - abdy*acdx - acdx*cddy + acdy*cddx));
-       if( fabsf(d) < 1 ) d = 1;
-       px = (-abdx*acdx*by + abdx*acdx*cy + 2*abdx*acdy*bx - abdy*acdx*bx - abdy*acdx*cx -
-               acdx*bx*cddy - acdx*by*cddx + acdx*cddx*cy - acdx*cddy*cx + 2*acdy*bx*cddx) / d;
-       py = (abdx*acdy*by + abdx*acdy*cy - 2*abdy*acdx*by + abdy*acdy*bx - abdy*acdy*cx -
-                2*acdx*by*cddy + acdy*bx*cddy + acdy*by*cddx + acdy*cddx*cy - acdy*cddy*cx) / d;
-       bclamp(px, -4095.f, 4095.f);
-       bclamp(py, -4095.f, 4095.f);
-}
-static void smooth_qxy(
-       float ax, float ay, float bx, float by,
-       float cx, float cy, float dx, float dy,
-       float &qx, float &qy)
-{
-       float abdx = bx - ax, abdy = by - ay;
-       float bddx = dx - bx, bddy = dy - by;
-       float cddx = dx - cx, cddy = dy - cy;
-       float d = (2*(abdx*bddy - abdy*bddx - bddx*cddy + bddy*cddx));
-       if( fabsf(d) < 1 ) d = 1;
-       qx = (abdx*bddx*by - abdx*bddx*cy + 2*abdx*bddy*cx - abdy*bddx*bx - abdy*bddx*cx -
-               bddx*bx*cddy + bddx*by*cddx - bddx*cddx*cy - bddx*cddy*cx + 2*bddy*cddx*cx) / d;
-       qy = (abdx*bddy*by + abdx*bddy*cy - 2*abdy*bddx*cy - abdy*bddy*bx + abdy*bddy*cx -
-               2*bddx*cddy*cy - bddy*bx*cddy + bddy*by*cddx + bddy*cddx*cy + bddy*cddy*cx) / d;
-       bclamp(qx, -4095.f, 4095.f);
-       bclamp(qy, -4095.f, 4095.f);
+//middle of bd reflected around ctr
+// point ctr = b+d/2, dv=c-ctr, a=ctr-dv;
+       float xc = (bx+dx)*.5f, yc = (by+dy)*.5f;
+       float xd = cx - xc, yd = cy - yc;
+       ax = xc - xd;  ay = yc - yd;
+}
+static void smooth_dxy(float &dx, float &dy,
+       float ax, float ay, float bx, float by, float cx, float cy)
+{
+//middle of ac reflected around ctr
+// point ctr = a+c/2, dv=c-ctr, d=ctr-dv;
+       float xc = (ax+cx)*.5f, yc = (ay+cy)*.5f;
+       float xd = bx - xc, yd = by - yc;
+       dx = xc - xd;  dy = yc - yd;
 }
 
 }
 
-
+#if 0
 static int convex(float ax,float ay, float bx,float by,
                  float cx,float cy, float dx,float dy)
 {
 static int convex(float ax,float ay, float bx,float by,
                  float cx,float cy, float dx,float dy)
 {
-       float abdx = bx - ax, abdy = by - ay;
-       float acdx = cx - ax, acdy = cy - ay;
-       float bcdx = cx - bx, bcdy = cy - by;
-       float bddx = dx - bx, bddy = dy - by;
+       float abdx = bx-ax, abdy = by-ay;
+       float acdx = cx-ax, acdy = cy-ay;
+       float bcdx = cx-bx, bcdy = cy-by;
+       float bddx = dx-bx, bddy = dy-by;
        float abc = abdx*acdy - abdy*acdx;
        float bcd = bcdx*bddy - bcdy*bddx;
        float v = abc * bcd;
        return !v ? 0 : v>0 ? 1 : -1;
 }
        float abc = abdx*acdy - abdy*acdx;
        float bcd = bcdx*bddy - bcdy*bddx;
        float v = abc * bcd;
        return !v ? 0 : v>0 ? 1 : -1;
 }
+#endif
 
 
-void SketcherCurve::draw_smooth(VFrame *out)
+void SketcherCurve::draw(VFrame *out)
 {
 {
+       const float fmx = 16383;
        VFrame *vpen = new_vpen(out);
        out->set_pixel_color(color);
        int n = points.size();
        if( !n ) return;
        if( n > 2 ) {
        VFrame *vpen = new_vpen(out);
        out->set_pixel_color(color);
        int n = points.size();
        if( !n ) return;
        if( n > 2 ) {
-               SketcherPoint *pt0 = points[0], *pt1 = points[1], *pt2 = points[2];
-               float bx = pt0->x, by = pt0->y;
-               float cx = pt1->x, cy = pt1->y;
-               float dx = pt2->x, dy = pt2->y;
-               float xc = (bx+dx)/2.f, yc = (by+dy)/2.f;
-               float xd = cx - xc, yd = cy - yc;
-               float ax = xc - xd, ay = yc - yd;
-               float sx, sy;
-               for( int pi=0,n2=n-2; pi<n2; ++pi ) {
-                       float dx = points[pi+2]->x, dy = points[pi+2]->y;
-                       if( convex(ax,ay, bx,by, cx,cy, dx,dy) >= 0 ) {
-                               smooth_sxy(ax,ay, bx,by, cx,cy, dx,dy, sx, sy);
+               int n2 = n - 2;
+               SketcherPoint *pt0 = points[0];
+               SketcherPoint *pt1 = points[1];
+               SketcherPoint *pt2 = points[2];
+               float ax,ay, bx,by, cx,cy, dx,dy, sx,sy;
+               bx = pt0->x;  by = pt0->y;
+               cx = pt1->x;  cy = pt1->y;
+               dx = pt2->x;  dy = pt2->y;
+               smooth_axy(ax,ay, bx,by, cx,cy, dx,dy);
+               for( int pi=0; pi<n2; ++pi ) {
+                       int pty = points[pi]->pty;
+                       dx = points[pi+2]->x;  dy = points[pi+2]->y;
+                       switch( pty ) {
+                       case PTY_LINE:
+                               vpen->draw_line(bx, by, cx, cy);
+                               break;
+                       case PTY_CURVE: {
+                               // s = ac thru b x bd thru c
+                               intersects_at(sx,sy, ax,ay,cx,cy,bx,by, bx,by,dx,dy,cx,cy,fmx);
                                vpen->draw_smooth(bx,by, sx,sy, cx,cy);
                                vpen->draw_smooth(bx,by, sx,sy, cx,cy);
-                       }
-                       else {
-                               float zx = (bx+cx)/2.f, zy = (by+cy)/2.f;
-                               smooth_pxy(ax,ay, bx,by, cx,cy, dx,dy, sx,sy);
-                               vpen->draw_smooth(bx,by, sx,sy, zx,zy);
-                               smooth_qxy(ax,ay, bx,by, cx,cy, dx,dy, sx,sy);
-                               vpen->draw_smooth(zx,zy, sx,sy, cx,cy);
+                               break; }
                        }
                        ax = bx;  ay = by;
                        bx = cx;  by = cy;
                        cx = dx;  cy = dy;
                }
                        }
                        ax = bx;  ay = by;
                        bx = cx;  by = cy;
                        cx = dx;  cy = dy;
                }
-               xc = (ax+cx)/2.f; yc = (ay+cy)/2.f;
-               xd = bx - xc, yd = by - yc;
-               dx = xc - xd, dy = yc - yd;
-               smooth_sxy(ax, ay, bx, by, cx, cy, dx, dy, sx, sy);
-               vpen->draw_smooth(bx, by, sx, sy, cx, cy);
+               switch( points[n2]->pty ) {
+               case PTY_LINE:
+                       vpen->draw_line(bx, by, cx, cy);
+                       break;
+               case PTY_CURVE: {
+                       smooth_dxy(dx,dy, ax,ay, bx,by, cx,cy);
+                       intersects_at(sx,sy, ax,ay,cx,cy,bx,by, bx,by,dx,dy,cx,cy,fmx);
+                       vpen->draw_smooth(bx,by, sx,sy, cx,cy);
+                       break; }
+               }
        }
        else if( n == 2 ) {
                SketcherPoint *pt0 = points[0], *pt1 = points[1];
        }
        else if( n == 2 ) {
                SketcherPoint *pt0 = points[0], *pt1 = points[1];
@@ -608,24 +551,18 @@ int Sketcher::process_realtime(VFrame *input, VFrame *output)
        for( int ci=0, n=config.curves.size(); ci<n; ++ci ) {
                SketcherCurve *cv = config.curves[ci];
                int m = cv->points.size();
        for( int ci=0, n=config.curves.size(); ci<n; ++ci ) {
                SketcherCurve *cv = config.curves[ci];
                int m = cv->points.size();
-               if( !m ) continue;
-               switch( cv->ty ) {
-               case TYP_OFF:
-                       break;
-               case TYP_SKETCHER:
-                       cv->draw_line(output);
-                       break;
-               case TYP_SMOOTH:
-                       cv->draw_smooth(output);
-                       break;
-               }
+               if( !m || cv->pen == PTY_OFF ) continue;
+               cv->draw(output);
        }
 
        if( config.drag ) {
                for( int ci=0, n=config.curves.size(); ci<n; ++ci ) {
                        SketcherCurve *cv = config.curves[ci];
        }
 
        if( config.drag ) {
                for( int ci=0, n=config.curves.size(); ci<n; ++ci ) {
                        SketcherCurve *cv = config.curves[ci];
-                       for( int pi=0,m=cv->points.size(); pi<m; ++pi )
-                               draw_point(output, cv->points[pi], cv->color);
+                       for( int pi=0,m=cv->points.size(); pi<m; ++pi ) {
+                               int color = ci==config.cv_selected && pi==config.pt_selected ?
+                                       RED : cv->color ; 
+                               draw_point(output, cv->points[pi], color);
+                       }
                }
        }
 
                }
        }
 
@@ -636,8 +573,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, ty=%s, r=%d, pen=%s, color=%02x%02x%02x\n",
-                       i, cv->id, cv_type[cv->ty], cv->radius, cv_pen[cv->pen],
+               printf("Curve %d, id=%d, pen=%s, r=%d, color=%02x%02x%02x\n",
+                       i, cv->id, cv_pen[cv->pen], cv->radius,
                        (cv->color>>16)&0xff, (cv->color>>8)&0xff, (cv->color>>0)&0xff);
                cv->points.dump();
        }
                        (cv->color>>16)&0xff, (cv->color>>8)&0xff, (cv->color>>0)&0xff);
                cv->points.dump();
        }
@@ -646,7 +583,8 @@ 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, x=%d, y=%d\n", i, pt->id, pt->x, pt->y);
+               printf("  Pt %d, id=%d, pty=%s, x=%d, y=%d\n",
+                       i, pt->id, pt_type[pt->pty], pt->x, pt->y);
        }
 }
 
        }
 }
 
index d0429cb1ffcd0eb7c97f03ff0e6253e7ef3ca636..be0f46b9f1e478289f3d001f183d96a48a59852f 100644 (file)
 
 class Sketcher;
 
 
 class Sketcher;
 
-enum { PT_ID, PT_X, PT_Y, PT_SZ };
-enum { CV_ID, CV_TY, CV_RAD, CV_PEN, CV_CLR, CV_SZ };
-enum { TYP_OFF, TYP_SKETCHER, TYP_SMOOTH, TYP_SZ };
-enum { PEN_SQUARE, PEN_PLUS, PEN_SLANT, PEN_XLANT, PEN_SZ };
+#define pt_type SketcherPoint::types
+#define cv_pen SketcherCurve::pens
+#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 { PTY_OFF, PTY_LINE, PTY_CURVE, PTY_SZ };
+enum { PEN_OFF, PEN_SQUARE, PEN_PLUS, PEN_SLANT, PEN_XLANT, PEN_SZ };
 
 class SketcherVPen : public VFrame
 {
 
 class SketcherVPen : public VFrame
 {
@@ -76,11 +80,11 @@ public:
 class SketcherPoint
 {
 public:
 class SketcherPoint
 {
 public:
-       int id;
+       int id, pty;
        int x, y;
 
        int x, y;
 
-       void init(int id, int x, int y);
-       SketcherPoint(int id, int x, int y);
+       void init(int id, int pty, int x, int y);
+       SketcherPoint(int id, int pty, int x, int y);
        SketcherPoint(int id=-1);
        SketcherPoint(SketcherPoint &pt);
        ~SketcherPoint();
        SketcherPoint(int id=-1);
        SketcherPoint(SketcherPoint &pt);
        ~SketcherPoint();
@@ -88,6 +92,7 @@ public:
        void copy_from(SketcherPoint &that);
        void save_data(FileXML &output);
        void read_data(FileXML &input);
        void copy_from(SketcherPoint &that);
        void save_data(FileXML &output);
        void read_data(FileXML &input);
+       static const char *types[PTY_SZ];
 };
 class SketcherPoints : public ArrayList<SketcherPoint *>
 {
 };
 class SketcherPoints : public ArrayList<SketcherPoint *>
 {
@@ -97,20 +102,17 @@ public:
        void dump();
 };
 
        void dump();
 };
 
-#define cv_type SketcherCurve::types
-#define cv_pen SketcherCurve::pens
 
 class SketcherCurve
 {
 public:
 
 class SketcherCurve
 {
 public:
-       int id, ty, radius, pen, color;
-       static const char *types[TYP_SZ];
+       int id, pen, radius, color;
        static const char *pens[PEN_SZ];
 
        SketcherPoints points;
 
        static const char *pens[PEN_SZ];
 
        SketcherPoints points;
 
-       void init(int id, int ty, int radius, int pen, int color);
-       SketcherCurve(int id, int ty, int radius, int pen, int color);
+       void init(int id, int pen, int radius, int color);
+       SketcherCurve(int id, int pen, int radius, int color);
        SketcherCurve(int id=-1);
        ~SketcherCurve();
        SketcherCurve(SketcherCurve &cv);
        SketcherCurve(int id=-1);
        ~SketcherCurve();
        SketcherCurve(SketcherCurve &cv);
@@ -119,8 +121,7 @@ public:
        void save_data(FileXML &output);
        void read_data(FileXML &input);
        VFrame *new_vpen(VFrame *out);
        void save_data(FileXML &output);
        void read_data(FileXML &input);
        VFrame *new_vpen(VFrame *out);
-       void draw_line(VFrame *out);
-       void draw_smooth(VFrame *out);
+       void draw(VFrame *out);
 };
 class SketcherCurves : public ArrayList<SketcherCurve *>
 {
 };
 class SketcherCurves : public ArrayList<SketcherCurve *>
 {
@@ -152,16 +153,15 @@ class Sketcher : public PluginVClient
 public:
        Sketcher(PluginServer *server);
        ~Sketcher();
 public:
        Sketcher(PluginServer *server);
        ~Sketcher();
-// required for all realtime plugins
        PLUGIN_CLASS_MEMBERS2(SketcherConfig)
        int is_realtime();
        void update_gui();
        void save_data(KeyFrame *keyframe);
        void read_data(KeyFrame *keyframe);
        PLUGIN_CLASS_MEMBERS2(SketcherConfig)
        int is_realtime();
        void update_gui();
        void save_data(KeyFrame *keyframe);
        void read_data(KeyFrame *keyframe);
-       int new_curve(int ty, int radius, int pen, int color);
+       int new_curve(int pen, int radius, int color);
        int new_curve();
        int new_curve();
-       int new_point(SketcherCurve *cv, int x, int y);
-       int new_point();
+       int new_point(SketcherCurve *cv, int pty, int x, int 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);
        void draw_point(VFrame *vfrm, SketcherPoint *pt, int color);
        int process_realtime(VFrame *input, VFrame *output);
        static void draw_point(VFrame *vfrm, SketcherPoint *pt, int color, int d);
        void draw_point(VFrame *vfrm, SketcherPoint *pt, int color);
index 5e55f29e583b473277c3ba4a248ad2cf500c3419..2f984cddb372a9519a51a5427a0a56d12bcb7227 100644 (file)
 #include "theme.h"
 #include "track.h"
 
 #include "theme.h"
 #include "track.h"
 
-#define COLOR_W 30
-#define COLOR_H 30
+#define AltMask Mod1Mask
 
 
-const char *SketcherCurve::types[] = {
+#define COLOR_W 32
+#define COLOR_H 24
+
+const char *SketcherPoint::types[] = {
        N_("off"),
        N_("line"),
        N_("off"),
        N_("line"),
-       N_("smooth"),
+       N_("curve"),
 };
 const char *SketcherCurve::pens[] = {
 };
 const char *SketcherCurve::pens[] = {
+       N_("off"),
        N_("box"),
        N_("+"),
        N_("/"),
        N_("X"),
 };
 
        N_("box"),
        N_("+"),
        N_("/"),
        N_("X"),
 };
 
-SketcherCurveTypeItem::SketcherCurveTypeItem(int ty)
- : BC_MenuItem(_(cv_type[ty]))
-{
-       this->ty = ty;
-}
-int SketcherCurveTypeItem::handle_event()
-{
-       SketcherCurveType *popup = (SketcherCurveType*)get_popup_menu();
-       popup->update(ty);
-       SketcherWindow *gui = popup->gui;
-       SketcherConfig &config = gui->plugin->config;
-       int ci = config.cv_selected;
-       if( ci >= 0 && ci < config.curves.size() ) {
-               SketcherCurve *cv = config.curves[ci];
-               cv->ty = ty;
-               gui->curve_list->update(ci);
-               gui->send_configure_change();
-       }
-       return 1;
-}
-
-SketcherCurveType::SketcherCurveType(SketcherWindow *gui, int x, int y, int ty)
- : BC_PopupMenu(x,y,64,_(cv_type[ty]))
-{
-       this->gui = gui;
-}
-void SketcherCurveType::create_objects()
-{
-       int n = sizeof(cv_type)/sizeof(cv_type[0]);
-       for( int ty=0; ty<n; ++ty )
-               add_item(new SketcherCurveTypeItem(ty));
-}
-void SketcherCurveType::update(int ty)
-{
-       set_text(_(cv_type[ty]));
-}
-
 
 SketcherCurvePenItem::SketcherCurvePenItem(int pen)
 
 SketcherCurvePenItem::SketcherCurvePenItem(int pen)
- : BC_MenuItem(_(cv_pen[pen]))
+ : BC_MenuItem(_(SketcherCurve::pens[pen]))
 {
        this->pen = pen;
 }
 {
        this->pen = pen;
 }
@@ -128,13 +94,13 @@ void SketcherCurvePen::update(int pen)
 }
 
 
 }
 
 
-SketcherCurveColor::SketcherCurveColor(SketcherWindow *gui, int x, int y, int w)
+SketcherCurveColor::SketcherCurveColor(SketcherWindow *gui, int x, int y, int w, int h)
  : BC_Button(x, y, w, vframes)
 {
        this->gui = gui;
  : BC_Button(x, y, w, vframes)
 {
        this->gui = gui;
-       this->color = BLACK;
+       this->color = CV_COLOR;
        for( int i=0; i<3; ++i ) {
        for( int i=0; i<3; ++i ) {
-               vframes[i] = new VFrame(w, w, BC_RGBA8888);
+               vframes[i] = new VFrame(w, h, BC_RGB888);
                vframes[i]->clear_frame();
        }
 }
                vframes[i]->clear_frame();
        }
 }
@@ -154,12 +120,8 @@ void SketcherCurveColor::set_color(int color)
        for( int i=0; i<3; ++i ) {
                VFrame *vframe = vframes[i];
                int ww = vframe->get_w(), hh = vframe->get_h();
        for( int i=0; i<3; ++i ) {
                VFrame *vframe = vframes[i];
                int ww = vframe->get_w(), hh = vframe->get_h();
-               int cx = (ww+1)/2, cy = hh/2;
-               double cc = (cx*cx + cy*cy) / 4.;
-               uint8_t *bp = vframe->get_data(), *dp = bp;
-               uint8_t *ep = dp + vframe->get_data_size();
+               uint8_t **rows = vframe->get_rows();
                int rr = r, gg = g, bb = b;
                int rr = r, gg = g, bb = b;
-               int bpl = vframe->get_bytes_per_line();
                switch( i ) {
                case BUTTON_UP:
                        break;
                switch( i ) {
                case BUTTON_UP:
                        break;
@@ -174,13 +136,11 @@ void SketcherCurveColor::set_color(int color)
                        if( (bb-=48) < 0x00 ) bb = 0x00;
                        break;
                }
                        if( (bb-=48) < 0x00 ) bb = 0x00;
                        break;
                }
-               while( dp < ep ) {
-                       int yy = (dp-bp) / bpl, xx = ((dp-bp) % bpl) >> 2;
-                       int dy = cy - yy, dx = cx - xx;
-                       double s = dx*dx + dy*dy - cc;
-                       double ss = s < 0 ? 1 : s >= cc ? 0 : 1 - s/cc;
-                       int aa = ss * 0xff;
-                       *dp++ = rr; *dp++ = gg; *dp++ = bb; *dp++ = aa;
+               for( int y=0; y<hh; ++y ) {
+                       uint8_t *rp = rows[y];
+                       for( int x=0; x<ww; ++x ) {
+                               *rp++ = rr;  *rp++ = gg;  *rp++ = bb;
+                       }
                }
        }
        set_images(vframes);
                }
        }
        set_images(vframes);
@@ -318,13 +278,13 @@ int SketcherPointX::handle_event()
        if( ci >= 0 && ci < config.curves.size() ) {
                SketcherCurve *cv = config.curves[ci];
                SketcherPointList *point_list = gui->point_list;
        if( ci >= 0 && ci < config.curves.size() ) {
                SketcherCurve *cv = config.curves[ci];
                SketcherPointList *point_list = gui->point_list;
-               int hot_point = point_list->get_selection_number(0, 0);
+               int pi = config.pt_selected;
                SketcherPoints &points = cv->points;
                SketcherPoints &points = cv->points;
-               if( hot_point >= 0 && hot_point < points.size() ) {
+               if( pi >= 0 && pi < points.size() ) {
                        int v = atoi(get_text());
                        int v = atoi(get_text());
-                       points[hot_point]->x = v;
-                       point_list->set_point(hot_point, PT_X, v);
-                       point_list->update_list(hot_point);
+                       points[pi]->x = v;
+                       point_list->set_point(pi, PT_X, v);
+                       point_list->update_list(pi);
                        gui->send_configure_change();
                }
        }
                        gui->send_configure_change();
                }
        }
@@ -338,13 +298,13 @@ int SketcherPointY::handle_event()
        if( ci >= 0 && ci < config.curves.size() ) {
                SketcherCurve *cv = config.curves[ci];
                SketcherPointList *point_list = gui->point_list;
        if( ci >= 0 && ci < config.curves.size() ) {
                SketcherCurve *cv = config.curves[ci];
                SketcherPointList *point_list = gui->point_list;
-               int hot_point = point_list->get_selection_number(0, 0);
+               int pi = config.pt_selected;
                SketcherPoints &points = cv->points;
                SketcherPoints &points = cv->points;
-               if( hot_point >= 0 && hot_point < points.size() ) {
+               if( pi >= 0 && pi < points.size() ) {
                        int v = atoi(get_text());
                        int v = atoi(get_text());
-                       points[hot_point]->y = v;
-                       point_list->set_point(hot_point, PT_Y, v);
-                       point_list->update_list(hot_point);
+                       points[pi]->y = v;
+                       point_list->set_point(pi, PT_Y, v);
+                       point_list->update_list(pi);
                        gui->send_configure_change();
                }
        }
                        gui->send_configure_change();
                }
        }
@@ -371,7 +331,6 @@ SketcherWindow::SketcherWindow(Sketcher *plugin)
  : PluginClientWindow(plugin, 380, 580, 380, 580, 0)
 {
        this->plugin = plugin;
  : PluginClientWindow(plugin, 380, 580, 380, 580, 0)
 {
        this->plugin = plugin;
-       this->title_type = 0; this->curve_type = 0;
        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->title_pen = 0;  this->curve_pen = 0;
        this->title_color = 0; this->curve_color = 0;
        this->color_picker = 0; this->new_points = 0;
@@ -396,115 +355,145 @@ SketcherWindow::~SketcherWindow()
 
 void SketcherWindow::create_objects()
 {
 
 void SketcherWindow::create_objects()
 {
-       int x = 10, y = 10, x1, y1;
+       int x = 10, y = 10, dy = 0, x1, y1;
        int margin = plugin->get_theme()->widget_border;
        BC_Title *title;
        int ci = plugin->config.cv_selected;
        if( ci < 0 || ci >= plugin->config.curves.size() )
        int margin = plugin->get_theme()->widget_border;
        BC_Title *title;
        int ci = plugin->config.cv_selected;
        if( ci < 0 || ci >= plugin->config.curves.size() )
-               ci = plugin->new_curve(0, 1, 0, BLACK);
+               ci = plugin->new_curve();
        SketcherCurve *cv = plugin->config.curves[ci];
        SketcherCurve *cv = plugin->config.curves[ci];
-       add_subwindow(reset_curves = new SketcherResetCurves(this, plugin, x1=x, y+3));
+
+       reset_curves = new SketcherResetCurves(this, plugin, x1=x, y+3);
+       add_subwindow(reset_curves);    dy = bmax(dy,reset_curves->get_h());
        x1 += reset_curves->get_w() + 2*margin;
        const char *curve_text = _("Curve");
        x1 += reset_curves->get_w() + 2*margin;
        const char *curve_text = _("Curve");
-       add_subwindow(title_radius = new BC_Title(x1, y, _("Width:")));
+       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();
        x1 += title_radius->get_w() + margin;
        curve_radius = new SketcherCurveRadius(this, x1, y, cv->radius);
        curve_radius->create_objects();
-       y += reset_curves->get_h() + 2*margin;
+       y += dy + 2*margin;             dy = 0;
+
        x1 = get_w()-x - BC_Title::calculate_w(this, curve_text, LARGEFONT);
        y1 = y-margin - BC_Title::calculate_h(this, curve_text, LARGEFONT);
        x1 = get_w()-x - BC_Title::calculate_w(this, curve_text, LARGEFONT);
        y1 = y-margin - BC_Title::calculate_h(this, curve_text, LARGEFONT);
-       add_subwindow(title = new BC_Title(x1, y1, curve_text, LARGEFONT,
-               get_resources()->menu_highlighted_fontcolor));
-       add_subwindow(curve_list = new SketcherCurveList(this, plugin, x, y));
-       y += curve_list->get_h() + margin;
-       add_subwindow(title_type = new BC_Title(x, y, _("Type:")));
-       x1 = x + title_type->get_w() + margin;
-       add_subwindow(curve_type = new SketcherCurveType(this, x1, y, cv->ty));
-       curve_type->create_objects();
-       x1 += curve_type->get_w() + margin;
-       add_subwindow(new_curve = new SketcherNewCurve(this, plugin, x1, y));
+       title = new BC_Title(x1, y1, curve_text, LARGEFONT,
+               get_resources()->menu_highlighted_fontcolor);
+       add_subwindow(title);           dy = bmax(dy,title->get_h());
+       curve_list = new SketcherCurveList(this, plugin, x, y);
+       add_subwindow(curve_list);      dy = bmax(dy,curve_list->get_h());
+       y += dy + margin;               dy = 0;
+
+       new_curve = new SketcherNewCurve(this, plugin, x1=x, y);
+       add_subwindow(new_curve);       dy = bmax(dy,new_curve->get_h());
        x1 += new_curve->get_w() + margin;
        x1 += new_curve->get_w() + margin;
-       add_subwindow(curve_up = new SketcherCurveUp(this, x1, y));
-       x1 += curve_up->get_w() + 2*margin;
-       add_subwindow(title_color = new BC_Title(x1, y, _("Color:")));
-       y += curve_type->get_h() + margin;
-
-       add_subwindow(title_pen = new BC_Title(x, y, _("Pen:")));
-       x1 = x + title_pen->get_w() + margin;
-       add_subwindow(curve_pen = new SketcherCurvePen(this, x1, y, cv->pen));
-       curve_pen->create_objects();
-       x1 += curve_pen->get_w() + margin;
-       add_subwindow(del_curve = new SketcherDelCurve(this, plugin, x1, y));
+       curve_up = new SketcherCurveUp(this, x1, y);
+       add_subwindow(curve_up);        dy = bmax(dy,curve_up->get_h());
+       x1 += curve_up->get_w() + 4*margin;
+       title_pen = new BC_Title(x1+30, y, _("Pen:"));
+       add_subwindow(title_pen);       dy = bmax(dy,title_pen->get_h());
+       int x2 = (get_w()+x1)/2;
+       title_color = new BC_Title(x2+10, y, _("Color:"));
+       add_subwindow(title_color);     dy = bmax(dy,title_color->get_h());
+       y += dy + margin;               dy = 0;
+
+       del_curve = new SketcherDelCurve(this, plugin, x1=x, y);
+       add_subwindow(del_curve);       dy = bmax(dy,del_curve->get_h());
        x1 += del_curve->get_w() + margin;
        x1 += del_curve->get_w() + margin;
-       add_subwindow(curve_dn = new SketcherCurveDn(this, x1, y));
-       x1 += curve_dn->get_w() + 2*margin;
-       add_subwindow(curve_color = new SketcherCurveColor(this, x1, y, COLOR_W));
-       curve_color->create_objects();
+       curve_dn = new SketcherCurveDn(this, x1, y);
+       add_subwindow(curve_dn);        dy = bmax(dy,curve_dn->get_h());
+       x1 += curve_dn->get_w() + 4*margin;
+       curve_pen = new SketcherCurvePen(this, x1, y, cv->pen);
+       add_subwindow(curve_pen);       dy = bmax(dy,curve_pen->get_h());
+       curve_pen->create_objects();
+       curve_color = new SketcherCurveColor(this, x2+20, y, COLOR_W, COLOR_H);
+       add_subwindow(curve_color);     dy = bmax(dy,curve_color->get_h());
        curve_color->set_color(cv->color);
        curve_color->draw_face();
        curve_color->set_color(cv->color);
        curve_color->draw_face();
-       y += COLOR_H + margin;
+       y += dy + margin;  dy = 0;
        curve_list->update(ci);
 
        BC_Bar *bar;
        curve_list->update(ci);
 
        BC_Bar *bar;
-       add_subwindow(bar = new BC_Bar(x, y, get_w()-2*x));
-       y += bar->get_h() + 2*margin;
+       bar = new BC_Bar(x, y, get_w()-2*x);
+       add_subwindow(bar);             dy = bmax(dy,bar->get_h());
+       y += dy + 2*margin;
 
        int pi = plugin->config.pt_selected;
        SketcherPoint *pt = pi >= 0 && pi < cv->points.size() ? cv->points[pi] : 0;
 
        int pi = plugin->config.pt_selected;
        SketcherPoint *pt = pi >= 0 && pi < cv->points.size() ? cv->points[pi] : 0;
-       add_subwindow(reset_points = new SketcherResetPoints(this, plugin, x1=x, y+3));
-       x1 += reset_points->get_w() + 2*margin;
-       add_subwindow(drag = new SketcherDrag(this, x1, y));
-       y += drag->get_h() + margin;
+       reset_points = new SketcherResetPoints(this, plugin, x1=x, y+3);
+       add_subwindow(reset_points);    dy = bmax(dy,reset_points->get_h());
+       x1 += reset_points->get_w() + 2*margin; 
        if( plugin->config.drag ) {
        if( plugin->config.drag ) {
-               if( !grab(plugin->server->mwindow->cwindow->gui) )
+               if( !grab(plugin->server->mwindow->cwindow->gui) ) {
                        eprintf("drag enabled, but compositor already grabbed\n");
                        eprintf("drag enabled, but compositor already grabbed\n");
+                       plugin->config.drag = 0;
+               }
        }
        }
+       drag = new SketcherDrag(this, x1, y);
+       add_subwindow(drag);            dy = bmax(dy,drag->get_h());
+       x1 += drag->get_w() + 2*margin;
+       int pty = pt ? pt->pty : PTY_LINE;
+       point_type = new SketcherPointType(this, x1, y, pty);
+       add_subwindow(point_type);      dy = bmax(dy,point_type->get_h());
+       point_type->create_objects();
+       y += dy + margin;  dy = 0;
+
        const char *point_text = _("Point");
        x1 = get_w()-x - BC_Title::calculate_w(this, point_text, LARGEFONT);
        y1 = y-margin - BC_Title::calculate_h(this, point_text, LARGEFONT);
        add_subwindow(title = new BC_Title(x1, y1, point_text, LARGEFONT,
                get_resources()->menu_highlighted_fontcolor));
        const char *point_text = _("Point");
        x1 = get_w()-x - BC_Title::calculate_w(this, point_text, LARGEFONT);
        y1 = y-margin - BC_Title::calculate_h(this, point_text, LARGEFONT);
        add_subwindow(title = new BC_Title(x1, y1, point_text, LARGEFONT,
                get_resources()->menu_highlighted_fontcolor));
-       add_subwindow(point_list = new SketcherPointList(this, plugin, x, y));
+       point_list = new SketcherPointList(this, plugin, x, y);
+       add_subwindow(point_list);      dy = bmax(dy,point_list->get_h());
+       y += dy + margin;               dy = 0;
 
 
-       y += point_list->get_h() + margin;
-       add_subwindow(title_x = new BC_Title(x, y, _("X:")));
-       x1 = x + title_x->get_w() + margin;
-       point_x = new SketcherPointX(this, x1, y, !pt ? 0.f : pt->x);
-       point_x->create_objects();
-       x1 += point_x->get_w() + 2*margin;
-       add_subwindow(new_point = new SketcherNewPoint(this, plugin, x1, y));
+       new_point = new SketcherNewPoint(this, plugin, x1=x, y);
+       add_subwindow(new_point);       dy = bmax(dy,new_point->get_h());
        x1 += new_point->get_w() + margin;
        x1 += new_point->get_w() + margin;
-       add_subwindow(point_up = new SketcherPointUp(this, x1, y));
-       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 SketcherPointY(this, x1, y, !pt ? 0.f : pt->y);
-       point_y->create_objects();
-       x1 += point_y->get_w() + 2*margin;
-       add_subwindow(del_point = new SketcherDelPoint(this, plugin, x1, y));
+       point_up = new SketcherPointUp(this, x1, y);
+       add_subwindow(point_up);        dy = bmax(dy,point_up->get_h());
+       x1 += point_up->get_w() + 2*margin;
+       title_x = new BC_Title(x1, y, _("X:"));
+       add_subwindow(title_x);         dy = bmax(dy,title_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());
+       y += dy + margin;  dy = 0;
+
+       del_point = new SketcherDelPoint(this, plugin, x1=x, y);
+       add_subwindow(del_point);       dy = bmax(dy,del_point->get_h());
        x1 += del_point->get_w() + margin;
        x1 += del_point->get_w() + margin;
-       add_subwindow(point_dn = new SketcherPointDn(this, x1, y));
-       y += point_y->get_h() + margin + 10;
+       point_dn = new SketcherPointDn(this, x1, y);
+       add_subwindow(point_dn);        dy = bmax(dy,point_dn->get_h());
+       x1 += point_dn->get_w() + 2*margin;
+       title_y = new BC_Title(x1, y, _("Y:"));
+       add_subwindow(title_y);         dy = bmax(dy,title_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());
+       y += dy + margin + 5;
        point_list->update(pi);
 
        add_subwindow(notes0 = new BC_Title(x, y,
                 _("\n"
        point_list->update(pi);
 
        add_subwindow(notes0 = new BC_Title(x, y,
                 _("\n"
-                  "LMB=\n"
-                  "Alt+LMB=\n"
-                  "MMB=\n"
+                  "Shift=\n"
+                  "None=\n"
+                  "Ctrl=\n"
+                  "Alt=\n"
                   "DEL=\n")));
        add_subwindow(notes1 = new BC_Title(x+80, y,
                   "DEL=\n")));
        add_subwindow(notes1 = new BC_Title(x+80, y,
-                _("     No Shift\n"
+                _("     LMB\n"
+                  "new line point\n"
                   "select point\n"
                   "select point\n"
-                  "drag curve\n"
-                  "next curve type\n"
+                  "drag point\n"
+                  "new curve\n"
                   "deletes point\n")));
        add_subwindow(notes2 = new BC_Title(x+200, y,
                   "deletes point\n")));
        add_subwindow(notes2 = new BC_Title(x+200, y,
-                _("             Shift\n"
-                  "append new points\n"
-                  "drag image\n"
-                  "append new curve\n"
-                  "delete curve\n")));
+                _("      RMB\n"
+                  "new arc point\n"
+                  "select curve\n"
+                  "drag curve\n"
+                  "drag all curves\n"
+                  "deletes curve\n")));
        show_window(1);
 }
 
        show_window(1);
 }
 
@@ -532,6 +521,7 @@ int SketcherWindow::do_grab_event(XEvent *event)
                if( keysym_lookup(event) > 0 ) {
                        switch( get_keysym() ) {
                        case XK_Delete:
                if( keysym_lookup(event) > 0 ) {
                        switch( get_keysym() ) {
                        case XK_Delete:
+                               pending_config = 1;
                                return (event->xkey.state & ShiftMask) ?
                                        del_curve->handle_event() :
                                        del_point->handle_event() ;
                                return (event->xkey.state & ShiftMask) ?
                                        del_curve->handle_event() :
                                        del_point->handle_event() ;
@@ -557,7 +547,7 @@ int SketcherWindow::do_grab_event(XEvent *event)
        switch( event->type ) {
        case ButtonPress:
                if( dragging ) return 0;
        switch( event->type ) {
        case ButtonPress:
                if( dragging ) return 0;
-               dragging = event->xbutton.state & Mod1Mask ? -1 : 1; // alt_down
+               dragging = 1;
                break;
        case ButtonRelease:
        case MotionNotify:
                break;
        case ButtonRelease:
        case MotionNotify:
@@ -567,10 +557,13 @@ int SketcherWindow::do_grab_event(XEvent *event)
                return 0;
        }
 
                return 0;
        }
 
-
-       int ci = plugin->config.cv_selected;
+       SketcherConfig &config = plugin->config;
+       int ci = config.cv_selected;
        if( ci < 0 || ci >= plugin->config.curves.size() )
                return 1;
        if( ci < 0 || ci >= plugin->config.curves.size() )
                return 1;
+       SketcherCurves &curves = config.curves;
+       SketcherCurve *cv = curves[ci];
+       int pi = config.pt_selected;
 
        float cursor_x = cx, cursor_y = cy;
        canvas->canvas_to_output(mwindow->edl, 0, cursor_x, cursor_y);
 
        float cursor_x = cx, cursor_y = cy;
        canvas->canvas_to_output(mwindow->edl, 0, cursor_x, cursor_y);
@@ -585,113 +578,131 @@ int SketcherWindow::do_grab_event(XEvent *event)
        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;
        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;
-       SketcherCurve *cv = plugin->config.curves[ci];
        SketcherPoints &points = cv->points;
        int state = event->xmotion.state;
 
        switch( event->type ) {
        case ButtonPress: {
        SketcherPoints &points = cv->points;
        int state = event->xmotion.state;
 
        switch( event->type ) {
        case ButtonPress: {
-               if( dragging < 0 ) break;
-               int hot_point = -1;
                int button_no = event->xbutton.button;
                int button_no = event->xbutton.button;
-               if( button_no == LEFT_BUTTON ) {
-// create new point string
-                       if( (state & ShiftMask) ) {
+               switch( button_no ) {
+               case LEFT_BUTTON: {
+                       if( (state & ShiftMask) ) { // create new point/string
                                ++new_points;
                                ++new_points;
-                               hot_point = plugin->new_point(cv, output_x, output_y);
-                               point_list->update(hot_point);
+                               pi = plugin->new_point(cv, PTY_LINE, output_x, output_y, pi+1);
+                               point_list->update(pi);
+                               break;
                        }
                        }
-                       else {
-// select point
-                               int sz = points.size();
-                               int last_point = hot_point;
-                               if( sz > 0 ) {
-                                       SketcherPoint *pt = points[hot_point=0];
-                                       double dist = DISTANCE(output_x,output_y, pt->x,pt->y);
-                                       for( int i=1; i<sz; ++i ) {
-                                               pt = points[i];
-                                               double d = DISTANCE(output_x,output_y, pt->x,pt->y);
-                                               if( d >= dist ) continue;
-                                               dist = d;  hot_point = i;
-                                       }
-                                       pt = points[hot_point];
-                                       float px = (pt->x - track_w / 2) * projector_z + projector_x;
-                                       float py = (pt->y - track_h / 2) * projector_z + projector_y;
-                                       dist = DISTANCE(px, py, cursor_x,cursor_y);
-                                       if( dist >= HANDLE_W ) hot_point = -1;
-                               }
-                               if( hot_point != last_point ) {
-                                       SketcherPoint *pt = 0;
-                                       if( hot_point >= 0 && hot_point < sz ) {
-                                               pt = points[hot_point];
-                                               point_list->set_point(hot_point, PT_X, pt->x = output_x);
-                                               point_list->set_point(hot_point, PT_Y, pt->y = output_y);
+                       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; // select point
+                       int last_point = pi;  pi = -1;
+                       int n = points.size();
+                       double dist = DBL_MAX;
+                       for( int i=0; i<n; ++i ) {
+                               SketcherPoint *p = points[i];
+                               double d = DISTANCE(output_x,output_y, p->x,p->y);
+                               if( d < dist ) { dist = d;  pi = i;  pt = p; }
+                       }
+                       if( pt ) {
+                               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( pix >= HANDLE_W ) { pi = -1;  pt = 0; }
+                       }
+                       if( pi != last_point )
+                               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;
+                       }
+                       SketcherPoint *pt = 0; // select point
+                       double dist = DBL_MAX;
+                       ci = -1;
+                       for( int i=0; i<curves.size(); ++i ) {
+                               SketcherCurve *crv = curves[i];
+                               int pts = crv->points.size();
+                               for( int k=0; k<pts; ++k ) {
+                                       SketcherPoint *p = crv->points[k];
+                                       double d = DISTANCE(output_x,output_y, p->x,p->y);
+                                       if( d < dist ) {
+                                               dist = d;
+                                               pt = p;    pi = k;
+                                               cv = crv;  ci = i;
                                        }
                                        }
-                                       point_list->update_list(hot_point);
-                                       point_x->update(pt ? pt->x : 0.f);
-                                       point_y->update(pt ? pt->y : 0.f);
                                }
                        }
                                }
                        }
-               }
-               else if( button_no == MIDDLE_BUTTON ) {
-                       if( (state & ShiftMask) ) {
-                               int ci = plugin->new_curve(cv->ty, cv->radius, cv->pen, cv->color);
-                               curve_list->update(ci);
-                               point_list->update(-1);
+                       if( pt ) {
+                               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( pix >= HANDLE_W ) { pi = -1;  pt = 0; }
                        }
                        }
-                       else {
-                               int ty = cv->ty + 1;
-                               if( ty >= TYP_SZ ) ty = 0;
-                               cv->ty = ty;
-                               curve_type->update(ty);
+                       if( pi >= 0 ) {
                                curve_list->update(ci);
                                curve_list->update(ci);
+                               point_list->update(pi);
                        }
                        }
+                       break; }
                }
                break; }
        case MotionNotify: {
                }
                break; }
        case MotionNotify: {
-               int hot_point = point_list->get_selection_number(0, 0);
-               if( dragging < 0 ) {
-                       SketcherCurves &curves = plugin->config.curves;
-                       int dx = round(output_x - last_x);
-                       int dy = round(output_y - last_y);
-                       int mnc = (state & ShiftMask) || ci<0 ? 0 : ci;
-                       int mxc = (state & ShiftMask) ? curves.size() : ci+1;
-                       for( int i=mnc; i<mxc; ++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;
+               if( (state & ShiftMask) ) {  // string of points
+                   if( (state & (Button1Mask|Button3Mask)) ) {
+                               if( pi < 0 ) pi = points.size()-1;
+                               if( pi >= 0 ) {
+                                       SketcherPoint *pt = pi >= 0 && pi < points.size() ?  points[pi] : 0;
+                                       float frac_w = DISTANCE(pt->x, pt->y, output_x, output_y) / get_w();
+                                       if( frac_w < 0.01 ) break; // 1 percent w
                                }
                                }
+                               ++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);
+                               break;
                        }
                        }
-                       SketcherPoint *pt = hot_point >= 0 && hot_point < points.size() ?
-                               points[hot_point] : 0;
-                       point_x->update(pt ? pt->x : 0.f);
-                       point_y->update(pt ? pt->y : 0.f);
-                       point_list->update(hot_point);
-                       break;
                }
                if( (state & Button1Mask) ) {
                }
                if( (state & Button1Mask) ) {
-                       SketcherPoint *pt = hot_point >= 0 && hot_point < points.size() ?
-                               points[hot_point] : 0;
-                       if( pt && pt->x == output_x && pt->y == output_y ) break;
-                       if( new_points ) {
+                       if( (state & ControlMask) ) { // drag selected point
+                               SketcherPoint *pt = pi >= 0 && pi < points.size() ?  points[pi] : 0;
                                if( pt ) {
                                if( pt ) {
-                                       float frac_w = DISTANCE(pt->x, pt->y, output_x, output_y) / get_w();
-                                       if( frac_w < 0.01 ) break; // 1 percent w
-                               }
-                               if( (state & ShiftMask) ) {
-                                       ++new_points;
-                                       hot_point = plugin->new_point(cv, output_x, output_y);
-                                       point_list->update(hot_point);
+                                       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;
                        }
                        }
-                       else if( pt ) {
-                               point_list->set_point(hot_point, PT_X, pt->x = output_x);
-                               point_list->set_point(hot_point, PT_Y, pt->y = output_y);
-                               point_list->update_list(hot_point);
-                               point_x->update(pt->x);
-                               point_y->update(pt->y);
+               }
+               if( (state & Button3Mask) ) {
+                       if( (state & (ControlMask | AltMask)) ) { // drag selected curve(s)
+                               SketcherCurves &curves = plugin->config.curves;
+                               int dx = round(output_x - last_x);
+                               int dy = round(output_y - last_y);
+                               int mnc = (state & AltMask) || ci<0 ? 0 : ci;
+                               int mxc = (state & AltMask) ? curves.size() : ci+1;
+                               for( int i=mnc; i<mxc; ++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;
                        }
                }
                break; }
                        }
                }
                break; }
@@ -727,7 +738,7 @@ void SketcherWindow::start_color_thread(SketcherCurveColor *color_button)
        unlock_window();
        delete color_picker;
        color_picker = new SketcherCurveColorPicker(this, color_button);
        unlock_window();
        delete color_picker;
        color_picker = new SketcherCurveColorPicker(this, color_button);
-       int color = BLACK, ci = plugin->config.cv_selected;
+       int color = CV_COLOR, ci = plugin->config.cv_selected;
        if( ci >= 0 && ci < plugin->config.curves.size() ) {
                SketcherCurve *cv = plugin->config.curves[ci];
                color = cv->color;
        if( ci >= 0 && ci < plugin->config.curves.size() ) {
                SketcherCurve *cv = plugin->config.curves[ci];
                color = cv->color;
@@ -743,7 +754,6 @@ SketcherCurveList::SketcherCurveList(SketcherWindow *gui, Sketcher *plugin, int
        this->gui = gui;
        this->plugin = plugin;
        titles[CV_ID] = _("id");  widths[CV_ID] = 64;
        this->gui = gui;
        this->plugin = plugin;
        titles[CV_ID] = _("id");  widths[CV_ID] = 64;
-       titles[CV_TY] = _("type");  widths[CV_TY] = 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;
        titles[CV_RAD] = _("radius");  widths[CV_RAD] = 64;
        titles[CV_PEN] = _("pen");  widths[CV_PEN] = 64;
        titles[CV_CLR] = _("color");  widths[CV_CLR] = 64;
@@ -780,27 +790,29 @@ 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_type->update(cv->ty);
                gui->curve_radius->update(cv->radius);
                gui->curve_pen->update(cv->pen);
                gui->curve_color->update_gui(cv->color);
                ci = k;
        }
        plugin->config.cv_selected = ci;
                gui->curve_radius->update(cv->radius);
                gui->curve_pen->update(cv->pen);
                gui->curve_color->update_gui(cv->color);
                ci = k;
        }
        plugin->config.cv_selected = ci;
-       update_selection(&cols[0], ci);
-       update_list(-1);
+       update_list(ci);
 }
 
 void SketcherCurveList::update_list(int k)
 {
        int xpos = get_xposition(), ypos = get_yposition();
 }
 
 void SketcherCurveList::update_list(int k)
 {
        int xpos = get_xposition(), ypos = get_yposition();
-       if( k < 0 ) k = get_selection_number(0, 0);
-       update_selection(&cols[0], k);
+       if( k >= 0 ) update_selection(&cols[0], k);
        BC_ListBox::update(&cols[0], &titles[0],&widths[0],CV_SZ, xpos,ypos,k);
        center_selection();
 }
        BC_ListBox::update(&cols[0], &titles[0],&widths[0],CV_SZ, xpos,ypos,k);
        center_selection();
 }
@@ -813,22 +825,20 @@ void SketcherCurveList::update(int k)
        for( int i=0; i<sz; ++i ) {
                SketcherCurve *cv = curves[i];
                char itxt[BCSTRLEN];  sprintf(itxt,"%d", cv->id);
        for( int i=0; i<sz; ++i ) {
                SketcherCurve *cv = curves[i];
                char itxt[BCSTRLEN];  sprintf(itxt,"%d", cv->id);
-               char ttxt[BCSTRLEN];  sprintf(ttxt,"%s", cv_type[cv->ty]);
-               char rtxt[BCSTRLEN];  sprintf(rtxt,"%d", cv->radius);
                char ptxt[BCSTRLEN];  sprintf(ptxt,"%s", cv_pen[cv->pen]);
                char ptxt[BCSTRLEN];  sprintf(ptxt,"%s", cv_pen[cv->pen]);
+               char rtxt[BCSTRLEN];  sprintf(rtxt,"%d", cv->radius);
                int color = cv->color;
                int r = (color>>16)&0xff, g = (color>>8)&0xff, b = (color>>0)&0xff;
                char ctxt[BCSTRLEN];  sprintf(ctxt,"#%02x%02x%02x", r, g, b);
                int color = cv->color;
                int r = (color>>16)&0xff, g = (color>>8)&0xff, b = (color>>0)&0xff;
                char ctxt[BCSTRLEN];  sprintf(ctxt,"#%02x%02x%02x", r, g, b);
-               add_curve(itxt, ttxt, rtxt, ptxt, ctxt);
+               add_curve(itxt, ptxt, rtxt, ctxt);
        }
        set_selected(k);
 }
 
        }
        set_selected(k);
 }
 
-void SketcherCurveList::add_curve(const char *id, const char *type,
-               const char *radius, const char *pen, const char *color)
+void SketcherCurveList::add_curve(const char *id, const char *pen,
+               const char *radius, const char *color)
 {
        cols[CV_ID].append(new BC_ListBoxItem(id));
 {
        cols[CV_ID].append(new BC_ListBoxItem(id));
-       cols[CV_TY].append(new BC_ListBoxItem(type));
        cols[CV_RAD].append(new BC_ListBoxItem(radius));
        cols[CV_PEN].append(new BC_ListBoxItem(pen));
        cols[CV_CLR].append(new BC_ListBoxItem(color));
        cols[CV_RAD].append(new BC_ListBoxItem(radius));
        cols[CV_PEN].append(new BC_ListBoxItem(pen));
        cols[CV_CLR].append(new BC_ListBoxItem(color));
@@ -845,15 +855,14 @@ SketcherNewCurve::~SketcherNewCurve()
 }
 int SketcherNewCurve::handle_event()
 {
 }
 int SketcherNewCurve::handle_event()
 {
-       int ty = 1, pen = 0, color = 0, radius = 1;
+       int pen = PTY_LINE, radius = 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];
-               ty = cv->ty;  pen = cv->pen;
-               color = cv->color;  radius = cv->radius;
+               pen = cv->pen;  radius = cv->radius;  color = cv->color;
        }
        }
-       int k = plugin->new_curve(ty, radius, pen, color);
-       gui->curve_list->update(k);
+       ci = plugin->new_curve(pen, radius, color);
+       gui->curve_list->update(ci);
        gui->point_list->update(-1);
        gui->send_configure_change();
        return 1;
        gui->point_list->update(-1);
        gui->send_configure_change();
        return 1;
@@ -870,13 +879,15 @@ SketcherDelCurve::~SketcherDelCurve()
 }
 int SketcherDelCurve::handle_event()
 {
 }
 int SketcherDelCurve::handle_event()
 {
-       int hot_curve = gui->curve_list->get_selection_number(0, 0);
-       SketcherCurves &curves = plugin->config.curves;
-       if( hot_curve >= 0 && hot_curve < curves.size() ) {
-               curves.remove_object_number(hot_curve);
-               if( --hot_curve < 0 )
-                       hot_curve = plugin->new_curve(0, 1, 0, BLACK);
-               gui->curve_list->update(hot_curve);
+       SketcherConfig &config = plugin->config;
+       int ci = config.cv_selected;
+       SketcherCurves &curves = config.curves;
+       if( ci >= 0 && ci < curves.size() ) {
+               curves.remove_object_number(ci--);
+               if( ci < 0 ) ci = 0;
+               if( !curves.size() )
+                       ci = plugin->new_curve();
+               gui->curve_list->update(ci);
                gui->point_list->update(-1);
                gui->send_configure_change();
        }
                gui->point_list->update(-1);
                gui->send_configure_change();
        }
@@ -894,14 +905,14 @@ SketcherCurveUp::~SketcherCurveUp()
 
 int SketcherCurveUp::handle_event()
 {
 
 int SketcherCurveUp::handle_event()
 {
-       SketcherCurves &curves = gui->plugin->config.curves;
-       int hot_curve = gui->curve_list->get_selection_number(0, 0);
-
-       if( hot_curve > 0 && hot_curve < curves.size() ) {
-               SketcherCurve *&cv0 = curves[hot_curve];
-               SketcherCurve *&cv1 = curves[--hot_curve];
+       SketcherConfig &config = gui->plugin->config;
+       int ci = config.cv_selected;
+       SketcherCurves &curves = config.curves;
+       if( ci > 0 && ci < curves.size() ) {
+               SketcherCurve *&cv0 = curves[ci];
+               SketcherCurve *&cv1 = curves[--ci];
                SketcherCurve *t = cv0;  cv0 = cv1;  cv1 = t;
                SketcherCurve *t = cv0;  cv0 = cv1;  cv1 = t;
-               gui->curve_list->update(hot_curve);
+               gui->curve_list->update(ci);
        }
        gui->send_configure_change();
        return 1;
        }
        gui->send_configure_change();
        return 1;
@@ -918,28 +929,82 @@ SketcherCurveDn::~SketcherCurveDn()
 
 int SketcherCurveDn::handle_event()
 {
 
 int SketcherCurveDn::handle_event()
 {
-       SketcherCurves &curves = gui->plugin->config.curves;
-       int hot_curve = gui->curve_list->get_selection_number(0, 0);
-
-       if( hot_curve >= 0 && hot_curve < curves.size()-1 ) {
-               SketcherCurve *&cv0 = curves[hot_curve];
-               SketcherCurve *&cv1 = curves[++hot_curve];
+       SketcherConfig &config = gui->plugin->config;
+       int ci = config.cv_selected;
+       SketcherCurves &curves = config.curves;
+       if( ci >= 0 && ci < curves.size()-1 ) {
+               SketcherCurve *&cv0 = curves[ci];
+               SketcherCurve *&cv1 = curves[++ci];
                SketcherCurve *t = cv0;  cv0 = cv1;  cv1 = t;
                SketcherCurve *t = cv0;  cv0 = cv1;  cv1 = t;
-               gui->curve_list->update(hot_curve);
+               gui->curve_list->update(ci);
        }
        gui->send_configure_change();
        return 1;
 }
 
 
        }
        gui->send_configure_change();
        return 1;
 }
 
 
+SketcherPointTypeItem::SketcherPointTypeItem(int pty)
+ : BC_MenuItem(_(pt_type[pty]))
+{
+       this->pty = pty;
+}
+int SketcherPointTypeItem::handle_event()
+{
+       SketcherPointType *popup = (SketcherPointType*)get_popup_menu();
+       popup->update(pty);
+       SketcherWindow *gui = popup->gui;
+       SketcherConfig &config = gui->plugin->config;
+       SketcherCurves &curves = config.curves;
+       int ci = config.cv_selected;
+       if( ci < 0 || ci >= curves.size() )
+               return 1;
+       SketcherCurve *cv = curves[ci];
+       SketcherPoints &points = cv->points;
+       int pi = config.pt_selected;
+
+       ArrayList<int> selected;
+       for( int v,i=0; (v=gui->point_list->get_selection_number(0, i))>=0; ++i )
+               selected.append(v);
+
+       for( int i=selected.size(); --i>=0; ) {
+               int k = selected[i];
+               if( k < 0 || k >= points.size() ) continue;
+               SketcherPoint *pt = cv->points[k];
+               pt->pty = pty;
+               gui->point_list->set_point(k, PT_TY, _(pt_type[pty]));
+       }
+
+       gui->point_list->update_list(pi);
+       gui->send_configure_change();
+       return 1;
+}
+
+SketcherPointType::SketcherPointType(SketcherWindow *gui, int x, int y, int pty)
+ : BC_PopupMenu(x,y,64,_(pt_type[pty]))
+{
+       this->gui = gui;
+}
+void SketcherPointType::create_objects()
+{
+       for( int pty=0; pty<PT_SZ; ++pty )
+               add_item(new SketcherPointTypeItem(pty));
+}
+void SketcherPointType::update(int pty)
+{
+       set_text(_(pt_type[pty]));
+}
+
+
 SketcherPointList::SketcherPointList(SketcherWindow *gui, Sketcher *plugin, int x, int y)
  : BC_ListBox(x, y, 360, 130, LISTBOX_TEXT)
 {
        this->gui = gui;
        this->plugin = plugin;
 SketcherPointList::SketcherPointList(SketcherWindow *gui, Sketcher *plugin, int x, int y)
  : BC_ListBox(x, y, 360, 130, LISTBOX_TEXT)
 {
        this->gui = gui;
        this->plugin = plugin;
-       titles[PT_X] = _("X");    widths[PT_X] = 90;
-       titles[PT_Y] = _("Y");    widths[PT_Y] = 90;
-       titles[PT_ID] = _("ID");  widths[PT_ID] = 50;
+       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;
+       set_selection_mode(LISTBOX_MULTIPLE);
 }
 SketcherPointList::~SketcherPointList()
 {
 }
 SketcherPointList::~SketcherPointList()
 {
@@ -961,6 +1026,7 @@ int SketcherPointList::column_resize_event()
 int SketcherPointList::handle_event()
 {
        int pi = get_selection_number(0, 0);
 int SketcherPointList::handle_event()
 {
        int pi = get_selection_number(0, 0);
+       if( get_selection_number(0, 1) >= 0 ) pi = -1;
        set_selected(pi);
        gui->send_configure_change();
        return 1;
        set_selected(pi);
        gui->send_configure_change();
        return 1;
@@ -972,9 +1038,10 @@ int SketcherPointList::selection_changed()
        return 1;
 }
 
        return 1;
 }
 
-void SketcherPointList::add_point(const char *id, const char *xp, const char *yp)
+void SketcherPointList::add_point(const char *id, const char *ty, const char *xp, const char *yp)
 {
        cols[PT_ID].append(new BC_ListBoxItem(id));
 {
        cols[PT_ID].append(new BC_ListBoxItem(id));
+       cols[PT_TY].append(new BC_ListBoxItem(ty));
        cols[PT_X].append(new BC_ListBoxItem(xp));
        cols[PT_Y].append(new BC_ListBoxItem(yp));
 }
        cols[PT_X].append(new BC_ListBoxItem(xp));
        cols[PT_Y].append(new BC_ListBoxItem(yp));
 }
@@ -998,17 +1065,16 @@ void SketcherPointList::set_selected(int k)
                SketcherCurve *cv = plugin->config.curves[ci];
                pt = k >= 0 && k < cv->points.size() ? cv->points[pi=k] : 0;
        }
                SketcherCurve *cv = plugin->config.curves[ci];
                pt = k >= 0 && k < cv->points.size() ? cv->points[pi=k] : 0;
        }
+       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);
        plugin->config.pt_selected = pi;
        gui->point_x->update(pt ? pt->x : 0.f);
        gui->point_y->update(pt ? pt->y : 0.f);
        plugin->config.pt_selected = pi;
-       update_selection(&cols[0], pi);
-       update_list(k);
+       update_list(pi);
 }
 void SketcherPointList::update_list(int k)
 {
        int xpos = get_xposition(), ypos = get_yposition();
 }
 void SketcherPointList::update_list(int k)
 {
        int xpos = get_xposition(), ypos = get_yposition();
-       if( k < 0 ) k = get_selection_number(0, 0);
-       update_selection(&cols[0], k);
+       if( k >= 0 ) update_selection(&cols[0], k);
        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();
 }
@@ -1023,9 +1089,10 @@ void SketcherPointList::update(int k)
                for( int i=0; i<sz; ++i ) {
                        SketcherPoint *pt = points[i];
                        char itxt[BCSTRLEN];  sprintf(itxt,"%d", pt->id);
                for( int i=0; i<sz; ++i ) {
                        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,"%d", pt->x);
                        char ytxt[BCSTRLEN];  sprintf(ytxt,"%d", pt->y);
-                       add_point(itxt, xtxt, ytxt);
+                       add_point(itxt, ttxt, xtxt, ytxt);
                }
        }
        set_selected(k);
                }
        }
        set_selected(k);
@@ -1040,9 +1107,8 @@ void SketcherWindow::update_gui()
        point_list->update(pi);
        SketcherCurve *cv = ci >= 0 ? config.curves[ci] : 0;
        curve_radius->update(cv ? cv->radius : 1);
        point_list->update(pi);
        SketcherCurve *cv = ci >= 0 ? config.curves[ci] : 0;
        curve_radius->update(cv ? cv->radius : 1);
-       curve_type->update(cv ? cv->ty : TYP_OFF);
        curve_pen->update(cv ? cv->pen : PEN_SQUARE);
        curve_pen->update(cv ? cv->pen : PEN_SQUARE);
-       curve_color->set_color(cv ? cv->color : BLACK);
+       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);
        SketcherPoint *pt = pi >= 0 ? cv->points[pi] : 0;
        point_x->update(pt ? pt->x : 0);
        point_y->update(pt ? pt->y : 0);
@@ -1067,15 +1133,23 @@ int SketcherPointUp::handle_event()
                return 1;
        SketcherCurve *cv = config.curves[ci];
        SketcherPoints &points = cv->points;
                return 1;
        SketcherCurve *cv = config.curves[ci];
        SketcherPoints &points = cv->points;
-       int sz = points.size();
-       int hot_point = gui->point_list->get_selection_number(0, 0);
+       if( points.size() < 2 )
+               return 1;
+       int pi = config.pt_selected;
+
+       ArrayList<int> selected;
+       for( int v,i=0; (v=gui->point_list->get_selection_number(0, i))>=0; ++i )
+               selected.append(v);
 
 
-       if( sz > 1 && hot_point > 0 ) {
-               SketcherPoint *&pt0 = points[hot_point];
-               SketcherPoint *&pt1 = points[--hot_point];
+       for( int i=0; i<selected.size(); ++i ) {
+               int k = selected[i];
+               if( k <= 0 ) continue;
+               if( k == pi ) --pi;
+               SketcherPoint *&pt0 = points[k];
+               SketcherPoint *&pt1 = points[--k];
                SketcherPoint *t = pt0;  pt0 = pt1;  pt1 = t;
                SketcherPoint *t = pt0;  pt0 = pt1;  pt1 = t;
-               gui->point_list->update(hot_point);
        }
        }
+       gui->point_list->update(pi);
        gui->send_configure_change();
        return 1;
 }
        gui->send_configure_change();
        return 1;
 }
@@ -1097,14 +1171,24 @@ int SketcherPointDn::handle_event()
                return 1;
        SketcherCurve *cv = config.curves[ci];
        SketcherPoints &points = cv->points;
                return 1;
        SketcherCurve *cv = config.curves[ci];
        SketcherPoints &points = cv->points;
-       int sz = points.size();
-       int hot_point = gui->point_list->get_selection_number(0, 0);
-       if( sz > 1 && hot_point < sz-1 ) {
-               SketcherPoint *&pt0 = points[hot_point];
-               SketcherPoint *&pt1 = points[++hot_point];
+       int sz1 = points.size()-1;
+       if( sz1 < 1 )
+               return 1;
+       int pi = config.pt_selected;
+
+       ArrayList<int> selected;
+       for( int v,i=0; (v=gui->point_list->get_selection_number(0, i))>=0; ++i )
+               selected.append(v);
+
+       for( int i=selected.size(); --i>=0; ) {
+               int k = selected[i];
+               if( k >= sz1 ) continue;
+               if( k == pi ) ++pi;
+               SketcherPoint *&pt0 = points[k];
+               SketcherPoint *&pt1 = points[++k];
                SketcherPoint *t = pt0;  pt0 = pt1;  pt1 = t;
                SketcherPoint *t = pt0;  pt0 = pt1;  pt1 = t;
-               gui->point_list->update(hot_point);
        }
        }
+       gui->point_list->update(pi);
        gui->send_configure_change();
        return 1;
 }
        gui->send_configure_change();
        return 1;
 }
@@ -1142,7 +1226,8 @@ SketcherNewPoint::~SketcherNewPoint()
 }
 int SketcherNewPoint::handle_event()
 {
 }
 int SketcherNewPoint::handle_event()
 {
-       int k = plugin->new_point();
+       int pi = plugin->config.pt_selected;
+       int k = plugin->new_point(pi+1);
        gui->point_list->update(k);
        gui->send_configure_change();
        return 1;
        gui->point_list->update(k);
        gui->send_configure_change();
        return 1;
@@ -1160,17 +1245,26 @@ SketcherDelPoint::~SketcherDelPoint()
 int SketcherDelPoint::handle_event()
 {
        SketcherConfig &config = gui->plugin->config;
 int SketcherDelPoint::handle_event()
 {
        SketcherConfig &config = gui->plugin->config;
+       SketcherCurves &curves = config.curves;
        int ci = config.cv_selected;
        int ci = config.cv_selected;
-       if( ci >= 0 && ci < config.curves.size() ) {
-               SketcherCurve *cv = config.curves[ci];
-               SketcherPoints &points = cv->points;
-               int hot_point = gui->point_list->get_selection_number(0, 0);
-               if( hot_point >= 0 && hot_point < points.size() ) {
-                       points.remove_object_number(hot_point);
-                       gui->point_list->update(--hot_point);
-                       gui->send_configure_change();
-               }
+       if( ci < 0 || ci >= curves.size() )
+               return 1;
+       SketcherCurve *cv = curves[ci];
+       SketcherPoints &points = cv->points;
+       int pi = config.pt_selected;
+
+       ArrayList<int> selected;
+       for( int v,i=0; (v=gui->point_list->get_selection_number(0, i))>=0; ++i )
+               selected.append(v);
+
+       for( int i=selected.size(); --i>=0; ) {
+               int k = selected[i];
+               if( k < 0 || k >= points.size() ) continue;
+               points.remove_object_number(k);
+               if( k == pi && --pi < 0 && points.size() > 0 ) pi = 0;
        }
        }
+       gui->point_list->update(pi);
+       gui->send_configure_change();
        return 1;
 }
 
        return 1;
 }
 
@@ -1187,7 +1281,7 @@ int SketcherResetCurves::handle_event()
 {
        SketcherConfig &config = plugin->config;
        config.curves.remove_all_objects();
 {
        SketcherConfig &config = plugin->config;
        config.curves.remove_all_objects();
-       int ci = plugin->new_curve(0, 1, 0, BLACK);
+       int ci = plugin->new_curve();
        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();
index a0cc4ae21044ad6349e80e30f6a5d5031c38b436..35e7e898346ef6feb712722d4a7bea4c8aee20ca 100644 (file)
@@ -42,6 +42,8 @@ class SketcherCurveList;
 class SketcherPointX;
 class SketcherPointY;
 class SketcherDrag;
 class SketcherPointX;
 class SketcherPointY;
 class SketcherDrag;
+class SketcherPointTypeItem;
+class SketcherPointType;
 class SketcherPointList;
 class SketcherNewPoint;
 class SketcherDelPoint;
 class SketcherPointList;
 class SketcherNewPoint;
 class SketcherDelPoint;
@@ -51,6 +53,7 @@ class SketcherResetCurves;
 class SketcherResetPoints;
 class SketcherWindow;
 
 class SketcherResetPoints;
 class SketcherWindow;
 
+
 class SketcherNum : public BC_TumbleTextBox
 {
 public:
 class SketcherNum : public BC_TumbleTextBox
 {
 public:
@@ -62,24 +65,6 @@ public:
        int update(int v) { return BC_TumbleTextBox::update((int64_t)v); }
 };
 
        int update(int v) { return BC_TumbleTextBox::update((int64_t)v); }
 };
 
-class SketcherCurveTypeItem : public BC_MenuItem
-{
-public:
-       SketcherCurveTypeItem(int ty);
-       int handle_event();
-       int ty;
-};
-
-class SketcherCurveType : public BC_PopupMenu
-{
-public:
-       SketcherCurveType(SketcherWindow *gui, int x, int y, int ty);
-       void create_objects();
-       void update(int ty);
-
-       SketcherWindow *gui;
-};
-
 class SketcherCurvePenItem : public BC_MenuItem
 {
 public:
 class SketcherCurvePenItem : public BC_MenuItem
 {
 public:
@@ -93,7 +78,7 @@ class SketcherCurvePen : public BC_PopupMenu
 public:
        SketcherCurvePen(SketcherWindow *gui, int x, int y, int pen);
        void create_objects();
 public:
        SketcherCurvePen(SketcherWindow *gui, int x, int y, int pen);
        void create_objects();
-       void update(int ty);
+       void update(int pen);
 
        SketcherWindow *gui;
 };
 
        SketcherWindow *gui;
 };
@@ -101,7 +86,7 @@ public:
 class SketcherCurveColor : public BC_Button
 {
 public:
 class SketcherCurveColor : public BC_Button
 {
 public:
-       SketcherCurveColor(SketcherWindow *gui, int x, int y, int w);
+       SketcherCurveColor(SketcherWindow *gui, int x, int y, int w, int h);
        ~SketcherCurveColor();
 
        void set_color(int color);
        ~SketcherCurveColor();
 
        void set_color(int color);
@@ -211,9 +196,10 @@ public:
        int column_resize_event();
        ArrayList<BC_ListBoxItem*> cols[CV_SZ];
        void clear();
        int column_resize_event();
        ArrayList<BC_ListBoxItem*> cols[CV_SZ];
        void clear();
-       void add_curve(const char *id, const char *type,
-               const char *radius, const char *pen, const char *color);
+       void add_curve(const char *id, const char *pen,
+               const char *radius, const char *color);
        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);
        void set_selected(int k);
        void update(int k);
        void update_list(int k);
@@ -254,6 +240,24 @@ public:
        SketcherWindow *gui;
 };
 
        SketcherWindow *gui;
 };
 
+class SketcherPointTypeItem : public BC_MenuItem
+{
+public:
+       SketcherPointTypeItem(int pty);
+       int handle_event();
+       int pty;
+};
+
+class SketcherPointType : public BC_PopupMenu
+{
+public:
+       SketcherPointType(SketcherWindow *gui, int x, int y, int pty);
+       void create_objects();
+       void update(int pty);
+
+       SketcherWindow *gui;
+};
+
 
 class SketcherPointList : public BC_ListBox
 {
 
 class SketcherPointList : public BC_ListBox
 {
@@ -266,7 +270,7 @@ public:
        int column_resize_event();
        ArrayList<BC_ListBoxItem*> cols[PT_SZ];
        void clear();
        int column_resize_event();
        ArrayList<BC_ListBoxItem*> cols[PT_SZ];
        void clear();
-       void add_point(const char *id, const char *xp, const char *yp);
+       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, const char *cp);
        void set_selected(int k);
        void set_point(int i, int c, int v);
        void set_point(int i, int c, const char *cp);
        void set_selected(int k);
@@ -368,8 +372,7 @@ public:
 
        Sketcher *plugin;
 
 
        Sketcher *plugin;
 
-       BC_Title *title_type, *title_pen;
-       BC_Title *title_color, *title_radius;
+       BC_Title *title_pen, *title_color, *title_radius;
        SketcherCurveType *curve_type;
        SketcherCurvePen *curve_pen;
        SketcherCurveColor *curve_color;
        SketcherCurveType *curve_type;
        SketcherCurvePen *curve_pen;
        SketcherCurveColor *curve_color;
@@ -382,6 +385,10 @@ public:
        SketcherCurveList *curve_list;
        SketcherResetCurves *reset_curves;
 
        SketcherCurveList *curve_list;
        SketcherResetCurves *reset_curves;
 
+       SketcherResetPoints *reset_points;
+       SketcherDrag *drag;
+       SketcherPointType *point_type;
+       SketcherPointList *point_list;
        BC_Title *title_x, *title_y;
        SketcherPointX *point_x;
        SketcherPointY *point_y;
        BC_Title *title_x, *title_y;
        SketcherPointX *point_x;
        SketcherPointY *point_y;
@@ -392,9 +399,6 @@ public:
        int dragging, pending_config;
        int new_points;
        float last_x, last_y;
        int dragging, pending_config;
        int new_points;
        float last_x, last_y;
-       SketcherDrag *drag;
-       SketcherPointList *point_list;
-       SketcherResetPoints *reset_points;
        BC_Title *notes0, *notes1, *notes2;
 };
 #endif
        BC_Title *notes0, *notes1, *notes2;
 };
 #endif