+ int pi = plugin->pt_selected;
+
+ float s = 1.001; // min scale
+ float th = 0.1 * M_PI/180.f; // min theta .1 deg per wheel_btn
+ int64_t ms = event->xbutton.time;
+ double dt = (ms - last_time) / 1000.; // seconds
+ last_time = ms;
+ double mx_accel = 100., r = mx_accel / exp(1.);
+ double mx_dt = 1./2., mn_dt = 1./15.; // mn..mx period in sec/xev
+ bclip(dt, mn_dt, mx_dt);
+ double accel = r * exp(-(dt-mn_dt)/(mx_dt-mn_dt));
+ int button_no = event->xbutton.button;
+ switch( button_no ) {
+ case WHEEL_DOWN:
+ s = 2 - s;
+ th = -th; // fall thru
+ case WHEEL_UP: { // shift_down scale, !shift_down rotate
+ s = 1 + (s-1)*accel;
+ th *= accel;
+ float st = sin(th), ct = cos(th);
+ int sz = points.size();
+ int shift_down = (state & ShiftMask) ? 1 : 0;
+ for( int i=0; i<sz; ++i ) {
+ SketcherPoint *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; }