ui/gtk/image.c

changeset 529
0a4a6b0d1c82
parent 390
b130f80ec7f9
child 530
7992a44fe719
equal deleted inserted replaced
528:fb1dca7d83da 529:0a4a6b0d1c82
31 #include "container.h" 31 #include "container.h"
32 #include "menu.h" 32 #include "menu.h"
33 #include "../common/context.h" 33 #include "../common/context.h"
34 #include "../common/object.h" 34 #include "../common/object.h"
35 35
36 static void imageviewer_destroy(UiImageViewer *iv) {
37 if(iv->pixbuf) {
38 g_object_unref(iv->pixbuf);
39 }
40 free(iv);
41 }
42
43 #if GTK_MAJOR_VERSION >= 4
44
45 static void imageviewer_draw(
46 GtkDrawingArea *drawingarea,
47 cairo_t *cr,
48 int width,
49 int height,
50 gpointer userdata)
51 {
52 ui_cairo_draw_image(userdata, cr, width, height);
53 }
54
55 #else
56
57 static gboolean imageviewer_draw(GtkWidget *widget, cairo_t *cr, gpointer userdata) {
58 int width = gtk_widget_get_allocated_width(widget);
59 int height = gtk_widget_get_allocated_height(widget);
60 ui_cairo_draw_image(userdata, cr, width, height);
61 return FALSE;
62 }
63
64 #endif
36 65
37 UIWIDGET ui_imageviewer_create(UiObject *obj, UiImageViewerArgs args) { 66 UIWIDGET ui_imageviewer_create(UiObject *obj, UiImageViewerArgs args) {
38 UiObject *current = uic_current_obj(obj); 67 UiObject *current = uic_current_obj(obj);
39 68
40 GtkWidget *scrolledwindow = SCROLLEDWINDOW_NEW(); 69 GtkWidget *drawingarea = gtk_drawing_area_new();
41 #if GTK_CHECK_VERSION(4, 0, 0) 70 GtkWidget *toplevel;
42 GtkWidget *image = gtk_picture_new(); 71 GtkWidget *widget = drawingarea;
43 #else 72
44 GtkWidget *image = gtk_image_new(); 73 gtk_widget_set_size_request(drawingarea, 100, 100);
45 #endif
46
47 ui_set_name_and_style(image, args.name, args.style_class);
48 74
49 #if GTK_MAJOR_VERSION < 4 75 #if GTK_MAJOR_VERSION < 4
50 GtkWidget *eventbox = gtk_event_box_new(); 76 GtkWidget *eventbox = gtk_event_box_new();
51 SCROLLEDWINDOW_SET_CHILD(scrolledwindow, eventbox); 77 gtk_container_add(GTK_CONTAINER(eventbox), drawingarea);
52 gtk_container_add(GTK_CONTAINER(eventbox), image); 78 widget = eventbox;
53 #else
54 SCROLLEDWINDOW_SET_CHILD(scrolledwindow, image);
55 GtkWidget *eventbox = image;
56 #endif 79 #endif
57 80
58 UI_APPLY_LAYOUT1(current, args); 81 if(args.scrollarea) {
59 current->container->add(current->container, scrolledwindow, TRUE); 82 toplevel = SCROLLEDWINDOW_NEW();
83 SCROLLEDWINDOW_SET_CHILD(toplevel, widget);
84 args.adjustsize = TRUE;
85 } else {
86 toplevel = widget;
87 }
88
89 UiImageViewer *imgviewer = malloc(sizeof(UiImageViewer));
90 memset(imgviewer, 0, sizeof(UiImageViewer));
91 if(args.image_padding > 0) {
92 imgviewer->padding_left = args.image_padding;
93 imgviewer->padding_right = args.image_padding;
94 imgviewer->padding_top = args.image_padding;
95 imgviewer->padding_bottom = args.image_padding;
96 } else {
97 imgviewer->padding_left = args.image_padding_left;
98 imgviewer->padding_right = args.image_padding_right;
99 imgviewer->padding_top = args.image_padding_top;
100 imgviewer->padding_bottom = args.image_padding_bottom;
101 }
102 imgviewer->adjustsize = args.adjustsize;
103 imgviewer->autoscale = args.autoscale;
104 imgviewer->useradjustable = args.useradjustable;
105
106 g_object_set_data_full(G_OBJECT(drawingarea), "uiimageviewer", imgviewer, (GDestroyNotify)imageviewer_destroy);
60 107
61 UiVar *var = uic_widget_var(obj->ctx, current->ctx, args.value, args.varname, UI_VAR_GENERIC); 108 UiVar *var = uic_widget_var(obj->ctx, current->ctx, args.value, args.varname, UI_VAR_GENERIC);
109 imgviewer->var = var;
110 imgviewer->widget = drawingarea;
111
62 if(var) { 112 if(var) {
63 UiGeneric *value = var->value; 113 UiGeneric *value = var->value;
64 value->get = ui_imageviewer_get; 114 value->get = ui_imageviewer_get;
65 value->get_type = ui_imageviewer_get_type; 115 value->get_type = ui_imageviewer_get_type;
66 value->set = ui_imageviewer_set; 116 value->set = ui_imageviewer_set;
67 value->obj = image; 117 value->obj = imgviewer;
68 if(value->value && value->type && !strcmp(value->type, UI_IMAGE_OBJECT_TYPE)) { 118 if(value->value && value->type && !strcmp(value->type, UI_IMAGE_OBJECT_TYPE)) {
69 GdkPixbuf *pixbuf = value->value; 119 GdkPixbuf *pixbuf = value->value;
70 value->value = NULL; 120 value->value = NULL;
71 ui_imageviewer_set(value, pixbuf, UI_IMAGE_OBJECT_TYPE); 121 ui_imageviewer_set(value, pixbuf, UI_IMAGE_OBJECT_TYPE);
72 } 122 }
73 } 123 }
74 124
125 #if GTK_MAJOR_VERSION >= 4
126 gtk_drawing_area_set_draw_func(
127 GTK_DRAWING_AREA(drawingarea),
128 imageviewer_draw,
129 imgviewer,
130 NULL);
131 #elif GTK_MAJOR_VERSION == 3
132 g_signal_connect(
133 drawingarea,
134 "draw",
135 G_CALLBACK(imageviewer_draw),
136 imgviewer);
137
138 #endif
139
75 if(args.contextmenu) { 140 if(args.contextmenu) {
76 UIMENU menu = ui_contextmenu_create(args.contextmenu, obj, eventbox); 141 UIMENU menu = ui_contextmenu_create(args.contextmenu, obj, widget);
77 ui_widget_set_contextmenu(eventbox, menu); 142 ui_widget_set_contextmenu(widget, menu);
78 } 143 }
79 144
80 return scrolledwindow; 145 UI_APPLY_LAYOUT1(current, args);
146 current->container->add(current->container, toplevel, TRUE);
147
148 return toplevel;
149 }
150
151
152 void ui_cairo_draw_image(UiImageViewer *imgviewer, cairo_t *cr, int width, int height) {
153 if(!imgviewer->pixbuf) {
154 return;
155 }
156
157 GdkPixbuf *pixbuf = imgviewer->pixbuf;
158 double dpixwidth = (double)gdk_pixbuf_get_width(pixbuf);
159 double dpixheight = (double)gdk_pixbuf_get_height(pixbuf);
160
161 double dwidth = width;
162 double dheight = height;
163 if(imgviewer->autoscale) {
164 double scale = dwidth / dpixwidth;
165 if(dpixheight * scale > dheight) {
166 scale = dheight / dpixheight;
167 }
168
169 dpixwidth *= scale;
170 dpixheight *= scale;
171 double x = (dwidth - dpixwidth) / 2;
172 double y = (dheight - dpixheight) / 2;
173 cairo_translate(cr, x, y);
174 cairo_scale(cr, scale, scale);
175 } else {
176 double x = (dwidth - dpixwidth) / 2;
177 double y = (dheight - dpixheight) / 2;
178 if(x < 0) {
179 x = 0;
180 }
181 if(y < 0) {
182 y = 0;
183 }
184 cairo_translate(cr, (int)x, (int)y);
185 }
186
187 gdk_cairo_set_source_pixbuf(cr, pixbuf, 0, 0);
188 cairo_paint(cr);
81 } 189 }
82 190
83 void* ui_imageviewer_get(UiGeneric *g) { 191 void* ui_imageviewer_get(UiGeneric *g) {
192 UiImageViewer *imgviewer = g->obj;
193 g->value = imgviewer->pixbuf;
84 return g->value; 194 return g->value;
85 } 195 }
86 196
87 const char* ui_imageviewer_get_type(UiGeneric *g) { 197 const char* ui_imageviewer_get_type(UiGeneric *g) {
88 198 return UI_IMAGE_OBJECT_TYPE;
89 } 199 }
90 200
91 int ui_imageviewer_set(UiGeneric *g, void *value, const char *type) { 201 int ui_imageviewer_set(UiGeneric *g, void *value, const char *type) {
92 if(!type || strcmp(type, UI_IMAGE_OBJECT_TYPE)) { 202 if(!type || strcmp(type, UI_IMAGE_OBJECT_TYPE)) {
93 return 1; 203 return 1;
94 } 204 }
95 205
96 // TODO: do we need to free the previous value here?
97
98 g->value = value;
99 g->type = type;
100 GdkPixbuf *pixbuf = value; 206 GdkPixbuf *pixbuf = value;
101 207
102 if(pixbuf) { 208 UiImageViewer *imgviewer = g->obj;
209 g->value = pixbuf;
210
211 if(imgviewer->pixbuf) {
212 g_object_unref(imgviewer->pixbuf);
213 }
214 imgviewer->pixbuf = pixbuf;
215
216 if(imgviewer->adjustsize) {
103 int width = gdk_pixbuf_get_width(pixbuf); 217 int width = gdk_pixbuf_get_width(pixbuf);
104 int height = gdk_pixbuf_get_height(pixbuf); 218 int height = gdk_pixbuf_get_height(pixbuf);
105 219 gtk_widget_set_size_request(imgviewer->widget, width, height);
106 #if GTK_CHECK_VERSION(4, 0, 0) 220 }
107 GdkTexture *texture = gdk_texture_new_for_pixbuf(pixbuf); 221 gtk_widget_queue_draw(imgviewer->widget);
108 gtk_picture_set_paintable(GTK_PICTURE(g->obj), GDK_PAINTABLE(texture));
109 #else
110 gtk_image_set_from_pixbuf(GTK_IMAGE(g->obj), pixbuf);
111 #endif
112 gtk_widget_set_size_request(g->obj, width, height);
113 }
114
115 222
116 return 0; 223 return 0;
117 } 224 }
118 225
119 226
128 if(obj->set) { 235 if(obj->set) {
129 obj->set(obj, pixbuf, UI_IMAGE_OBJECT_TYPE); 236 obj->set(obj, pixbuf, UI_IMAGE_OBJECT_TYPE);
130 } else { 237 } else {
131 obj->value = pixbuf; 238 obj->value = pixbuf;
132 } 239 }
133 240
134 return 0; 241 return 0;
135 } 242 }

mercurial