Skip to content

Commit f1d7225

Browse files
committed
update from nip4
1 parent bb2a83c commit f1d7225

File tree

10 files changed

+513
-382
lines changed

10 files changed

+513
-382
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ master
55
- much better performance for images which are very tall and thin or very wide
66
and narrow
77
- better antialiasing [Linden6]
8-
- copy over improvements from nip4 development
8+
- copy over improvements from nip4 development, including OME handling
99

1010
## 3.1.0 28/10/24
1111

src/gtk/imagewindow.ui

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -222,18 +222,28 @@
222222
</child>
223223

224224
<child>
225-
<object class="GtkInfoBar" id="error_bar">
226-
<property name="message-type">error</property>
227-
<property name="show-close-button">true</property>
225+
<object class="GtkActionBar" id="error_bar">
228226
<property name="revealed">false</property>
229-
<child>
227+
228+
<child type="center">
230229
<object class="GtkLabel" id="error_label">
230+
<property name="hexpand">true</property>
231231
<property name="ellipsize">middle</property>
232+
<property name="xalign">0.0</property>
232233
<attributes>
233234
<attribute name="weight" value="bold"/>
234235
</attributes>
236+
235237
</object>
236238
</child>
239+
240+
<child type="end">
241+
<object class="GtkButton">
242+
<property name="label">OK</property>
243+
<signal name="clicked" handler="imagewindow_error_clicked"/>
244+
</object>
245+
</child>
246+
237247
</object>
238248
</child>
239249

src/imagedisplay.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -353,11 +353,13 @@ imagedisplay_tilecache_changed(Tilecache *tilecache,
353353
Imagedisplay *imagedisplay)
354354
{
355355
#ifdef DEBUG
356-
printf("imagedisplay_tilecache_changed:\n");
356+
printf("imagedisplay_tilecache_changed: %d x %d\n",
357+
tilecache->tilesource->image_width,
358+
tilecache->tilesource->image_height);
357359
#endif /*DEBUG*/
358360

359-
imagedisplay->image_rect.width = tilecache->tilesource->display_width;
360-
imagedisplay->image_rect.height = tilecache->tilesource->display_height;
361+
imagedisplay->image_rect.width = tilecache->tilesource->image_width;
362+
imagedisplay->image_rect.height = tilecache->tilesource->image_height;
361363
imagedisplay_layout(imagedisplay);
362364

363365
gtk_widget_queue_draw(GTK_WIDGET(imagedisplay));
@@ -647,6 +649,8 @@ imagedisplay_snapshot(GtkWidget *widget, GtkSnapshot *snapshot)
647649
printf("imagedisplay_snapshot:\n");
648650
#endif /*DEBUG*/
649651

652+
GTK_WIDGET_CLASS(imagedisplay_parent_class)->snapshot(widget, snapshot);
653+
650654
/* Clip to the widget area, or we may paint over the display control
651655
* bar.
652656
*/
@@ -668,7 +672,6 @@ imagedisplay_snapshot(GtkWidget *widget, GtkSnapshot *snapshot)
668672

669673
/* It's unclear how to do this :( maybe we're supposed to get the base
670674
* widget class to do it? Draw it ourselves for now.
671-
*/
672675
if (gtk_widget_has_focus(widget)) {
673676
GskRoundedRect outline;
674677
@@ -685,6 +688,7 @@ imagedisplay_snapshot(GtkWidget *widget, GtkSnapshot *snapshot)
685688
(float[4]){ 2, 2, 2, 2 },
686689
(GdkRGBA[4]){ BORDER, BORDER, BORDER, BORDER });
687690
}
691+
*/
688692
}
689693

690694
static void

src/imageui.c

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

49+
/* Snap if closer than this.
50+
*/
51+
const int imageui_snap_threshold = 10;
52+
53+
/* Drag state machine.
54+
*/
55+
typedef enum {
56+
IMAGEUI_WAIT, /* Waiting for left down */
57+
IMAGEUI_SELECT, /* Manipulating a selected region */
58+
IMAGEUI_SCROLL, /* Drag-scrolling the iamge */
59+
IMAGEUI_CREATE, /* Dragging out a new region */
60+
} ImageuiState;
61+
4962
struct _Imageui {
5063
GtkWidget parent_instance;
5164

@@ -81,16 +94,18 @@ struct _Imageui {
8194
double zoom_x;
8295
double zoom_y;
8396

97+
/* Interaction state.
98+
*/
99+
ImageuiState state;
100+
84101
/* TRUE for an eased zoom (eg. magin), FALSE for a continuous zoom (eg.
85102
* 'i').
86103
*/
87104
gboolean eased;
88105

89-
/* Drag scroll.
90-
*/
91-
int window_left; /* Window position at start of scroll */
106+
int window_left; /* Window position at start of scroll */
92107
int window_top;
93-
int start_x; /* Mouse position at start of scroll */
108+
int start_x; /* Mouse position at start of scroll */
94109
int start_y;
95110

96111
GtkWidget *scrolled_window;
@@ -514,10 +529,8 @@ imageui_bestfit(Imageui *imageui)
514529
int widget_width = gtk_widget_get_width(imageui->scrolled_window);
515530
int widget_height = gtk_widget_get_height(imageui->scrolled_window);
516531

517-
double hzoom = (double) widget_width /
518-
imageui->tilesource->display_width;
519-
double vzoom = (double) widget_height /
520-
imageui->tilesource->display_height;
532+
double hzoom = (double) widget_width / imageui->tilesource->image_width;
533+
double vzoom = (double) widget_height / imageui->tilesource->image_height;
521534
double zoom = VIPS_MIN(hzoom, vzoom);
522535

523536
imageui_zoom_to_eased(imageui, zoom * imageui->tilesource->zoom);
@@ -592,21 +605,30 @@ imageui_scale(Imageui *imageui)
592605
VipsImage *image;
593606

594607
if ((image = tilesource_get_image(imageui->tilesource))) {
595-
double image_zoom;
608+
/* Get the view rect in level0 coordinates.
609+
*/
610+
double image_zoom = imageui_get_zoom(imageui);
596611
int left, top, width, height;
597-
double scale, offset;
598-
599-
image_zoom = imageui_get_zoom(imageui);
600612
imageui_get_position(imageui, &left, &top, &width, &height);
613+
601614
left /= image_zoom;
602615
top /= image_zoom;
603616
width /= image_zoom;
604617
height /= image_zoom;
605618

619+
/* image is scaled down by current_z, so we must scale the rect by
620+
* that.
621+
*/
622+
left /= 1 << imageui->tilesource->current_z;
623+
top /= 1 << imageui->tilesource->current_z;
624+
width /= 1 << imageui->tilesource->current_z;
625+
height /= 1 << imageui->tilesource->current_z;
626+
606627
/* FIXME ... this will be incredibly slow, esp. for large
607628
* images. Instead, it would be better to just search the
608629
* cached tiles we have.
609630
*/
631+
double scale, offset;
610632
if (imageui_find_scale(image,
611633
left, top, width, height, &scale, &offset))
612634
return FALSE;
@@ -834,8 +856,35 @@ imageui_drag_update(GtkEventControllerMotion *self,
834856
offset_x, offset_y);
835857
#endif /*DEBUG_VERBOSE*/
836858

837-
imageui_set_position(imageui,
838-
imageui->window_left - offset_x, imageui->window_top - offset_y);
859+
switch (imageui->state) {
860+
case IMAGEUI_WAIT:
861+
if (fabs(offset_x) > 5 ||
862+
fabs(offset_y) > 5)
863+
imageui->state = IMAGEUI_SCROLL;
864+
break;
865+
866+
case IMAGEUI_SCROLL:
867+
imageui_set_position(imageui,
868+
imageui->window_left - offset_x, imageui->window_top - offset_y);
869+
break;
870+
871+
default:
872+
break;
873+
}
874+
}
875+
876+
static void
877+
imageui_drag_end(GtkEventControllerMotion *self,
878+
gdouble offset_x, gdouble offset_y, gpointer user_data)
879+
{
880+
Imageui *imageui = IMAGEUI(user_data);
881+
882+
#ifdef DEBUG_VERBOSE
883+
printf("imageui_drag_end: offset_x = %g, offset_y = %g\n",
884+
offset_x, offset_y);
885+
#endif /*DEBUG_VERBOSE*/
886+
887+
imageui->state = IMAGEUI_WAIT;
839888
}
840889

841890
static void
@@ -916,6 +965,7 @@ imageui_class_init(ImageuiClass *class)
916965

917966
BIND_CALLBACK(imageui_drag_begin);
918967
BIND_CALLBACK(imageui_drag_update);
968+
BIND_CALLBACK(imageui_drag_end);
919969
BIND_CALLBACK(imageui_key_pressed);
920970
BIND_CALLBACK(imageui_key_released);
921971
BIND_CALLBACK(imageui_motion);
@@ -968,6 +1018,7 @@ imageui_class_init(ImageuiClass *class)
9681018
NULL, NULL,
9691019
g_cclosure_marshal_VOID__VOID,
9701020
G_TYPE_NONE, 0);
1021+
9711022
}
9721023

9731024
Imageui *

src/imageui.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,6 @@ double imageui_get_scale(Imageui *imageui);
5151
void imageui_get_mouse_position(Imageui *imageui,
5252
double *image_x, double *image_y);
5353

54-
gboolean imageui_snap_point(Imageui *imageui, int x, int y, int *sx, int *sy);
55-
gboolean imageui_snap_rect(Imageui *imageui, VipsRect *in, VipsRect *out);
56-
5754
double imageui_get_zoom(Imageui *imageui);
5855
void imageui_bestfit(Imageui *imageui);
5956
void imageui_magin(Imageui *imageui);

src/imagewindow.c

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ imagewindow_set_error(Imagewindow *win, const char *message)
136136
err[i - 1] = '\0';
137137
gtk_label_set_text(GTK_LABEL(win->error_label), err);
138138

139-
gtk_info_bar_set_revealed(GTK_INFO_BAR(win->error_bar), TRUE);
139+
gtk_action_bar_set_revealed(GTK_ACTION_BAR(win->error_bar), TRUE);
140140
}
141141

142142
static void
@@ -162,7 +162,7 @@ imagewindow_error_hide(Imagewindow *win)
162162
printf("imagewindow_error_hide:\n");
163163
#endif /*DEBUG*/
164164

165-
gtk_info_bar_set_revealed(GTK_INFO_BAR(win->error_bar), FALSE);
165+
gtk_action_bar_set_revealed(GTK_ACTION_BAR(win->error_bar), FALSE);
166166
}
167167

168168
/* Manage the set of active views.
@@ -841,12 +841,6 @@ imagewindow_cancel_clicked(GtkWidget *button, Imagewindow *win)
841841
vips_image_set_kill(image, TRUE);
842842
}
843843

844-
static void
845-
imagewindow_error_response(GtkWidget *button, int response, Imagewindow *win)
846-
{
847-
imagewindow_error_hide(win);
848-
}
849-
850844
static GdkTexture *
851845
texture_new_from_image(VipsImage *image)
852846
{
@@ -1549,8 +1543,6 @@ imagewindow_init(Imagewindow *win)
15491543

15501544
g_signal_connect_object(win->progress_cancel, "clicked",
15511545
G_CALLBACK(imagewindow_cancel_clicked), win, 0);
1552-
g_signal_connect_object(win->error_bar, "response",
1553-
G_CALLBACK(imagewindow_error_response), win, 0);
15541546

15551547
g_action_map_add_action_entries(G_ACTION_MAP(win),
15561548
imagewindow_entries, G_N_ELEMENTS(imagewindow_entries),
@@ -1620,6 +1612,12 @@ imagewindow_pressed_cb(GtkGestureClick *gesture,
16201612
gtk_popover_popup(GTK_POPOVER(win->right_click_menu));
16211613
}
16221614

1615+
static void
1616+
imagewindow_error_clicked(GtkWidget *button, Imagewindow *win)
1617+
{
1618+
imagewindow_error_hide(win);
1619+
}
1620+
16231621
#define BIND(field) \
16241622
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), \
16251623
Imagewindow, field);
@@ -1647,8 +1645,8 @@ imagewindow_class_init(ImagewindowClass *class)
16471645
BIND(display_bar);
16481646
BIND(info_bar);
16491647

1650-
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class),
1651-
imagewindow_pressed_cb);
1648+
BIND_CALLBACK(imagewindow_pressed_cb);
1649+
BIND_CALLBACK(imagewindow_error_clicked);
16521650

16531651
gobject_class->dispose = imagewindow_dispose;
16541652

0 commit comments

Comments
 (0)