Skip to content

Commit db9cbfd

Browse files
committed
put region snap back
snap to hguide and vguide
1 parent 4da1c3e commit db9cbfd

File tree

4 files changed

+191
-4
lines changed

4 files changed

+191
-4
lines changed

TODO

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
the keyboard focus is somewhere else, and left-click on rowview
66
buttons or on workspace background does not grab the focus
77

8-
- put region snap back?
9-
108
- maxpos, then create mark from coordinate should be two clicks
119

1210
- try:

src/imageui.c

Lines changed: 183 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@
4646
*/
4747
#define ZOOM_DURATION (0.5)
4848

49+
/* Snap if closer than this.
50+
*/
51+
const int imageui_snap_threshold = 10;
52+
4953
/* Drag state machine.
5054
*/
5155
typedef enum {
@@ -484,6 +488,145 @@ imageui_get_position(Imageui *imageui,
484488
#endif /*DEBUG_VERBOSE*/
485489
}
486490

491+
/* Track this during a snap.
492+
*/
493+
typedef struct {
494+
Imageui *imageui;
495+
496+
int x; /* Start point */
497+
int y;
498+
int off_x; /* Current snap offset */
499+
int off_y;
500+
int best_x; /* 'Closeness' of best snap so far */
501+
int best_y;
502+
} ImageuiSnap;
503+
504+
static void *
505+
imageui_snap_sub(Regionview *regionview, ImageuiSnap *snap, gboolean *snapped)
506+
{
507+
Imageui *imageui = snap->imageui;
508+
509+
/* Only static h/v guides.
510+
*/
511+
if (regionview->type != REGIONVIEW_HGUIDE &&
512+
regionview->type != REGIONVIEW_VGUIDE)
513+
return NULL;
514+
515+
if (regionview->type == REGIONVIEW_HGUIDE) {
516+
int y = regionview->our_area.top;
517+
int score = abs(y - snap->y);
518+
519+
if (score < snap->best_y) {
520+
snap->off_y = y - snap->y;
521+
snap->best_y = score;
522+
*snapped = TRUE;
523+
}
524+
}
525+
else {
526+
int x = regionview->our_area.left;
527+
int score = abs(x - snap->x);
528+
529+
if (score < snap->best_x) {
530+
snap->off_x = x - snap->x;
531+
snap->best_x = score;
532+
*snapped = TRUE;
533+
}
534+
}
535+
536+
return NULL;
537+
}
538+
539+
static gboolean
540+
imageui_snap(Imageui *imageui, ImageuiSnap *snap)
541+
{
542+
gboolean snapped;
543+
544+
// scale the snap threshold by the zoom factor
545+
snap->imageui = imageui;
546+
snap->off_x = 0;
547+
snap->off_y = 0;
548+
snap->best_x =
549+
VIPS_MAX(1, imageui_snap_threshold / imageui_get_zoom(imageui));
550+
snap->best_y =
551+
VIPS_MAX(1, imageui_snap_threshold / imageui_get_zoom(imageui));
552+
553+
snapped = FALSE;
554+
slist_map2(imageui->regionviews,
555+
(SListMap2Fn) imageui_snap_sub, snap, &snapped);
556+
557+
return snapped;
558+
}
559+
560+
gboolean
561+
imageui_snap_point(Imageui *imageui, int x, int y, int *sx, int *sy)
562+
{
563+
ImageuiSnap snap;
564+
gboolean snapped;
565+
566+
snap.x = x;
567+
snap.y = y;
568+
snapped = imageui_snap(imageui, &snap);
569+
570+
*sx = x + snap.off_x;
571+
*sy = y + snap.off_y;
572+
573+
return snapped;
574+
}
575+
576+
gboolean
577+
imageui_snap_rect(Imageui *imageui, VipsRect *in, VipsRect *out)
578+
{
579+
/* Snap the corners plus the edge centres, take the best score.
580+
*/
581+
ImageuiSnap snap[8];
582+
snap[0].x = in->left;
583+
snap[0].y = in->top;
584+
snap[1].x = in->left + in->width;
585+
snap[1].y = in->top;
586+
snap[2].x = in->left + in->width;
587+
snap[2].y = in->top + in->height;
588+
snap[3].x = in->left;
589+
snap[3].y = in->top + in->height;
590+
snap[4].x = in->left + in->width / 2;
591+
snap[4].y = in->top;
592+
snap[5].x = in->left + in->width;
593+
snap[5].y = in->top + in->height / 2;
594+
snap[6].x = in->left + in->width / 2;
595+
snap[6].y = in->top + in->height;
596+
snap[7].x = in->left;
597+
snap[7].y = in->top + in->height / 2;
598+
599+
gboolean snapped;
600+
snapped = FALSE;
601+
for (int i = 0; i < 8; i++)
602+
snapped |= imageui_snap(imageui, &snap[i]);
603+
604+
int best;
605+
int best_score;
606+
best = 0;
607+
best_score = snap[0].best_x;
608+
for (int i = 1; i < 7; i++)
609+
if (snap[i].best_x < best_score) {
610+
best = i;
611+
best_score = snap[i].best_x;
612+
}
613+
out->left = in->left + snap[best].off_x;
614+
615+
best = 0;
616+
best_score = snap[0].best_y;
617+
for (int i = 1; i < 7; i++)
618+
if (snap[i].best_y < best_score) {
619+
best = i;
620+
best_score = snap[i].best_y;
621+
}
622+
out->top = in->top + snap[best].off_y;
623+
624+
out->width = in->width;
625+
out->height = in->height;
626+
627+
return snapped;
628+
}
629+
487630
static void
488631
imageui_set_position(Imageui *imageui, double x, double y)
489632
{
@@ -1300,8 +1443,8 @@ imageui_init(Imageui *imageui)
13001443
G_CALLBACK(imageui_overlay_snapshot), imageui, 0);
13011444

13021445
/* Uncomment to test our animation disable
1303-
g_object_set( gtk_widget_get_settings( GTK_WIDGET( win ) ),
1304-
"gtk-enable-animations", FALSE, NULL );
1446+
g_object_set(gtk_widget_get_settings(GTK_WIDGET(win)),
1447+
"gtk-enable-animations", FALSE, NULL);
13051448
*/
13061449

13071450
// read the gtk animation setting preference
@@ -1446,3 +1589,41 @@ imageui_gtk_to_image(Imageui *imageui,
14461589
imagedisplay_gtk_to_image(IMAGEDISPLAY(imageui->imagedisplay),
14471590
x_gtk, y_gtk, x_image, y_image);
14481591
}
1592+
1593+
void
1594+
imageui_image_to_gtk_rect(Imageui *imageui, VipsRect *in, VipsRect *out)
1595+
{
1596+
VipsRect rect;
1597+
double x_gtk;
1598+
double y_gtk;
1599+
1600+
imageui_image_to_gtk(imageui, in->left, in->top, &x_gtk, &y_gtk);
1601+
rect.left = x_gtk;
1602+
rect.top = y_gtk;
1603+
1604+
imageui_image_to_gtk(imageui,
1605+
VIPS_RECT_RIGHT(in), VIPS_RECT_BOTTOM(in), &x_gtk, &y_gtk);
1606+
rect.width = ceil(x_gtk) - rect.left;
1607+
rect.height = ceil(y_gtk) - rect.top;
1608+
1609+
*out = rect;
1610+
}
1611+
1612+
void
1613+
imageui_gtk_to_image_rect(Imageui *imageui, VipsRect *in, VipsRect *out)
1614+
{
1615+
VipsRect rect;
1616+
double x_image;
1617+
double y_image;
1618+
1619+
imageui_gtk_to_image(imageui, in->left, in->top, &x_image, &y_image);
1620+
rect.left = x_image;
1621+
rect.top = y_image;
1622+
1623+
imageui_gtk_to_image(imageui,
1624+
VIPS_RECT_RIGHT(in), VIPS_RECT_BOTTOM(in), &x_image, &y_image);
1625+
rect.width = ceil(x_image) - rect.left;
1626+
rect.height = ceil(y_image) - rect.top;
1627+
1628+
*out = rect;
1629+
}

src/imageui.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ double imageui_get_scale(Imageui *imageui);
5353
void imageui_get_mouse_position(Imageui *imageui,
5454
double *image_x, double *image_y);
5555

56+
gboolean imageui_snap_point(Imageui *imageui, int x, int y, int *sx, int *sy);
57+
gboolean imageui_snap_rect( Imageui *imageui, Rect *in, Rect *out );
58+
5659
Regionview *imageui_pick_regionview(Imageui *imageui, int x, int y);
5760
double imageui_get_zoom(Imageui *imageui);
5861
void imageui_bestfit(Imageui *imageui);
@@ -68,5 +71,7 @@ void imageui_image_to_gtk(Imageui *imageui,
6871
double x_image, double y_image, double *x_gtk, double *y_gtk);
6972
void imageui_gtk_to_image(Imageui *imageui,
7073
double x_gtk, double y_gtk, double *x_image, double *y_image);
74+
void imageui_image_to_gtk_rect(Imageui *imageui, VipsRect *in, VipsRect *out);
75+
void imageui_gtk_to_image_rect(Imageui *imageui, VipsRect *in, VipsRect *out);
7176

7277
#endif /* __IMAGEUI_H */

src/regionview.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -763,13 +763,15 @@ void
763763
regionview_resize(Regionview *regionview, guint modifiers,
764764
int width, int height, int x, int y)
765765
{
766+
Imageui *imageui = regionview->imageui;
766767
VipsRect *our_area = &regionview->our_area;
767768
VipsRect *start_area = &regionview->start_area;
768769

769770
switch (regionview->resize) {
770771
case REGIONVIEW_RESIZE_MOVE:
771772
our_area->left = x + start_area->left;
772773
our_area->top = y + start_area->top;
774+
imageui_snap_rect(imageui, our_area, our_area);
773775
break;
774776

775777
case REGIONVIEW_RESIZE_RIGHT:
@@ -869,6 +871,7 @@ regionview_resize(Regionview *regionview, guint modifiers,
869871
default:
870872
break;
871873
}
874+
872875
}
873876

874877
static void

0 commit comments

Comments
 (0)