+ for( int i=0; i<sz; ++i ) {
+ TracerPoint *pt = points[i];
+ float px = pt->x - track_x, py = pt->y - track_y;
+ float nx = shift_down ? px*s : px*ct + py*st;
+ float ny = shift_down ? py*s : py*ct - px*st;
+ point_list->set_point(i, PT_X, pt->x = nx + track_x);
+ point_list->set_point(i, PT_Y, pt->y = ny + track_y);
+ }
+ point_list->update(-1);
+ button_no = 0;
+ break; }
+ case RIGHT_BUTTON: {
+ // shift_down adds to end
+ int sz = !shift_down ? points.size() : 0;
+ int k = !shift_down ? -1 : points.size()-1;
+ float mx = FLT_MAX;
+ for( int i=0; i<sz; ++i ) {
+ // pt on line pt[i+0]..pt[i+1] nearest cursor_x,cursor_y
+ TracerPoint *pt0 = points[i+0];
+ TracerPoint *pt1 = i+1<sz ? points[i+1] : points[0];
+ float x0 = pt0->x, y0 = pt0->y;
+ float x1 = pt1->x, y1 = pt1->y;
+ float dx = x1-x0, dy = y1-y0;
+ float rr = dx*dx + dy*dy;
+ if( !rr ) continue;
+ float u = ((x1-track_x)*dx + (y1-track_y)*dy) / rr;
+ if( u < 0 || u > 1 ) continue; // past endpts
+ float x = x0*u + x1*(1-u);
+ float y = y0*u + y1*(1-u);
+ dx = track_x-x; dy = track_y-y;
+ float dd = dx*dx + dy*dy; // d**2 closest approach
+ if( mx > dd ) { mx = dd; k = i; }
+ }
+ TracerPoint *pt = points[sz=plugin->new_point()];
+ int hot_point = k+1;
+ for( int i=sz; i>hot_point; --i ) points[i] = points[i-1];
+ points[hot_point] = pt;
+ pt->x = track_x; pt->y = track_y;
+ point_list->update(hot_point);
+ break; }
+ case LEFT_BUTTON: {
+ int hot_point = -1, sz = points.size();
+ if( sz > 0 ) {