- case ButtonPress: {
- int button_no = event->xbutton.button;
- switch( button_no ) {
- case LEFT_BUTTON: {
- if( (state & ShiftMask) ) { // create new point/string
- ++new_points;
- pi = plugin->new_point(cv, PTY_LINE, output_x, output_y, pi+1);
- point_list->update(pi);
- break;
- }
- 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; }
- }
+ case ButtonPress:
+ pending_config = grab_button_press(event);
+ break;
+ case ButtonRelease:
+ new_points = 0;
+ break;
+ }
+
+ return 1;
+}
+
+int SketcherWindow::grab_button_press(XEvent *event)
+{
+ SketcherConfig &config = plugin->config;
+ int ci = config.cv_selected;
+ if( ci < 0 || ci >= plugin->config.curves.size() )
+ return 0;
+ SketcherCurves &curves = config.curves;
+ SketcherCurve *cv = curves[ci];
+ SketcherPoints &points = cv->points;
+ int pi = config.pt_selected;
+
+ int button_no = event->xbutton.button;
+ switch( button_no ) {
+ case LEFT_BUTTON: {
+ if( (state & ShiftMask) ) { // create new point/string
+ ++new_points;
+ pi = plugin->new_point(cv,
+ !(state & ControlMask) ? ARC_LINE : ARC_FILL,
+ output_x, output_y, pi+1);
+ point_list->update(pi);
+ break;
+ }
+ SketcherPoint *pt = 0; // select point
+ double dist = cv->nearest_point(pi, output_x,output_y);
+ if( dist >= 0 ) {
+ pt = points[pi];
+ Track *track = plugin->server->plugin->track;
+ int track_w = track->track_w, track_h = track->track_h;
+ float px = (pt->x - track_w / 2) * projector_z + projector_x;
+ float py = (pt->y - track_h / 2) * projector_z + projector_y;
+ float pix = DISTANCE(px, py, cursor_x,cursor_y);
+ if( (state & ControlMask) && pix >= HANDLE_W ) { pi = -1; pt = 0; }
+ }
+ point_list->set_selected(pi);
+ break; }
+ case RIGHT_BUTTON: {
+ if( (state & ShiftMask) ) { // create new curve point
+ ++new_points;
+ pi = plugin->new_point(cv,
+ !(state & ControlMask) ? ARC_CURVE : ARC_OFF,
+ output_x, output_y, pi+1);
+ point_list->update(pi);
+ break;
+ }
+ if( (state & AltMask) ) { // create new curve
+ ci = plugin->new_curve(cv->pen, cv->width, curve_color->color);
+ curve_list->update(ci);
+ point_list->update(-1);
+ break;
+ }
+ SketcherPoint *pt = 0;
+ double dist = config.nearest_point(ci, pi, output_x,output_y);
+ if( dist >= 0 ) {
+ pt = curves[ci]->points[pi];
+ Track *track = plugin->server->plugin->track;
+ int track_w = track->track_w, track_h = track->track_h;
+ float px = (pt->x - track_w / 2) * projector_z + projector_x;
+ float py = (pt->y - track_h / 2) * projector_z + projector_y;
+ float pix = DISTANCE(px, py, cursor_x,cursor_y);
+ if( (state & ControlMask) && pix >= HANDLE_W ) { ci = pi = -1; pt = 0; }
+ }
+ if( pt ) {
+ curve_list->update(ci);
+ point_list->update(pi);
+ }
+ break; }
+ }
+ return 1;
+}
+
+int SketcherWindow::grab_cursor_motion()
+{
+ if( !pending_motion )
+ return 0;
+ pending_motion = 0;
+ SketcherConfig &config = plugin->config;
+ int ci = config.cv_selected;
+ if( ci < 0 || ci >= plugin->config.curves.size() )
+ return 0;
+ SketcherCurves &curves = config.curves;
+ SketcherCurve *cv = curves[ci];
+ SketcherPoints &points = cv->points;
+ int pi = config.pt_selected;
+
+ if( (state & ShiftMask) ) { // string of points
+ if( (state & (Button1Mask|Button3Mask)) ) {
+ SketcherPoint *pt = pi >= 0 && pi < points.size() ? points[pi] : 0;