diff --git a/solidify/overlap.c b/solidify/overlap.c index a9dd805..c2f045b 100644 --- a/solidify/overlap.c +++ b/solidify/overlap.c @@ -180,25 +180,51 @@ static void rotate(struct matrix *m, double r) } +static void do_shift(struct matrix *m, int dx, int dy) +{ + m->b[0] -= dx; + m->b[1] += dy; +} + + +static void shift(struct matrix *m, int dx, int dy, int dir) +{ + if (dx > 0 && dy < dx && dy > -dx) + do_shift(m, dir, 0); + if (dx < 0 && dy < -dx && dy > dx) + do_shift(m, -dir, 0); + if (dy > 0 && dx < dy && dx > -dy) + do_shift(m, 0, dir); + if (dy < 0 && dx < -dy && dx > dy) + do_shift(m, 0, -dir); +} + + static gboolean scroll_event(GtkWidget *widget, GdkEventScroll *event, gpointer data) { GtkWidget *da = gtk_bin_get_child(GTK_BIN(widget)); struct solid *s = data; - struct face *f = s->a; - int dx = event->x-f->sx/2; - int dy = event->y-f->sy/2; + int dx = event->x-sx(s)/2; + int dy = event->y-sy(s)/2; double r = hypot(dx, dy); + int center = r/hypot(sx(s), sy(s)) < 0.25; if (r < 1) return TRUE; switch (event->direction) { case GDK_SCROLL_UP: - rotate(&f->m, r); + if (center) + shift(&s->a->m, dx, dy, 1); + else + rotate(&s->a->m, r); draw_image(da, s); break; case GDK_SCROLL_DOWN: - rotate(&f->m, -r); + if (center) + shift(&s->a->m, dx, dy, -1); + else + rotate(&s->a->m, -r); draw_image(da, s); break; default: