24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
26 * POSSIBILITY OF SUCH DAMAGE. |
26 * POSSIBILITY OF SUCH DAMAGE. |
27 */ |
27 */ |
28 |
28 |
29 #include <stdio.h> |
29 #include "image.h" |
30 #include <stdlib.h> |
|
31 #include <string.h> |
|
32 #include <ucx/map.h> |
|
33 |
30 |
34 #include "toolkit.h" |
31 #include "container.h" |
35 #include "image.h" |
32 #include "menu.h" |
36 #include "../common/properties.h" |
33 #include "../common/context.h" |
|
34 #include "../common/object.h" |
37 |
35 |
38 static UcxMap *image_map; |
|
39 |
36 |
40 static GtkIconTheme *icon_theme; |
37 UIWIDGET ui_imageviewer_create(UiObject *obj, UiImageViewerArgs args) { |
41 |
38 UiObject *current = uic_current_obj(obj); |
42 void ui_image_init(void) { |
|
43 image_map = ucx_map_new(8); |
|
44 |
39 |
45 icon_theme = gtk_icon_theme_get_default(); |
40 GtkWidget *scrolledwindow = SCROLLEDWINDOW_NEW(); |
|
41 #if GTK_CHECK_VERSION(4, 0, 0) |
|
42 GtkWidget *image = gtk_picture_new(); |
|
43 #else |
|
44 GtkWidget *image = gtk_image_new(); |
|
45 #endif |
|
46 |
|
47 ui_set_name_and_style(image, args.name, args.style_class); |
|
48 |
|
49 #if GTK_MAJOR_VERSION < 4 |
|
50 GtkWidget *eventbox = gtk_event_box_new(); |
|
51 SCROLLEDWINDOW_SET_CHILD(scrolledwindow, eventbox); |
|
52 gtk_container_add(GTK_CONTAINER(eventbox), image); |
|
53 #else |
|
54 SCROLLEDWINDOW_SET_CHILD(scrolledwindow, image); |
|
55 GtkWidget *eventbox = image; |
|
56 #endif |
|
57 |
|
58 UI_APPLY_LAYOUT1(current, args); |
|
59 current->container->add(current->container, scrolledwindow, TRUE); |
|
60 |
|
61 UiVar *var = uic_widget_var(obj->ctx, current->ctx, args.value, args.varname, UI_VAR_GENERIC); |
|
62 if(var) { |
|
63 UiGeneric *value = var->value; |
|
64 value->get = ui_imageviewer_get; |
|
65 value->get_type = ui_imageviewer_get_type; |
|
66 value->set = ui_imageviewer_set; |
|
67 value->obj = image; |
|
68 if(value->value && value->type && !strcmp(value->type, UI_IMAGE_OBJECT_TYPE)) { |
|
69 GdkPixbuf *pixbuf = value->value; |
|
70 value->value = NULL; |
|
71 ui_imageviewer_set(value, pixbuf, UI_IMAGE_OBJECT_TYPE); |
|
72 } |
|
73 } |
|
74 |
|
75 if(args.contextmenu) { |
|
76 UIMENU menu = ui_contextmenu_create(args.contextmenu, obj, eventbox); |
|
77 ui_widget_set_contextmenu(eventbox, menu); |
|
78 } |
|
79 |
|
80 return scrolledwindow; |
46 } |
81 } |
47 |
82 |
48 // **** deprecated functions **** |
83 void* ui_imageviewer_get(UiGeneric *g) { |
49 |
84 return g->value; |
50 GdkPixbuf* ui_get_image(const char *name) { |
|
51 UiImage *img = ucx_map_cstr_get(image_map, name); |
|
52 if(img) { |
|
53 return img->pixbuf; |
|
54 } else { |
|
55 //ui_add_image(name, name); |
|
56 //return ucx_map_cstr_get(image_map, name); |
|
57 // TODO |
|
58 return NULL; |
|
59 } |
|
60 } |
85 } |
61 |
86 |
62 // **** new functions **** |
87 const char* ui_imageviewer_get_type(UiGeneric *g) { |
63 |
88 |
64 static UiIcon* get_icon(const char *name, int size, int scale) { |
|
65 #ifdef UI_SUPPORTS_SCALE |
|
66 GtkIconInfo *info = gtk_icon_theme_lookup_icon_for_scale(icon_theme, name, size, scale, 0); |
|
67 #else |
|
68 GtkIconInfo *info = gtk_icon_theme_lookup_icon(icon_theme, name, size, 0); |
|
69 #endif |
|
70 if(info) { |
|
71 UiIcon *icon = malloc(sizeof(UiIcon)); |
|
72 icon->info = info; |
|
73 return icon; |
|
74 } |
|
75 return NULL; |
|
76 } |
89 } |
77 |
90 |
78 UiIcon* ui_icon(const char *name, int size) { |
91 int ui_imageviewer_set(UiGeneric *g, void *value, const char *type) { |
79 return get_icon(name, size, ui_get_scalefactor()); |
92 if(!type || strcmp(type, UI_IMAGE_OBJECT_TYPE)) { |
|
93 return 1; |
|
94 } |
|
95 |
|
96 // TODO: do we need to free the previous value here? |
|
97 |
|
98 g->value = value; |
|
99 g->type = type; |
|
100 GdkPixbuf *pixbuf = value; |
|
101 |
|
102 if(pixbuf) { |
|
103 int width = gdk_pixbuf_get_width(pixbuf); |
|
104 int height = gdk_pixbuf_get_height(pixbuf); |
|
105 |
|
106 #if GTK_CHECK_VERSION(4, 0, 0) |
|
107 GdkTexture *texture = gdk_texture_new_for_pixbuf(pixbuf); |
|
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 |
|
116 return 0; |
80 } |
117 } |
81 |
118 |
82 UiIcon* ui_icon_unscaled(const char *name, int size) { |
|
83 return get_icon(name, size, 1); |
|
84 } |
|
85 |
119 |
86 void ui_free_icon(UiIcon *icon) { |
|
87 g_object_unref(icon->info); |
|
88 free(icon); |
|
89 } |
|
90 |
120 |
91 UiImage* ui_icon_image(UiIcon *icon) { |
121 int ui_image_load_file(UiGeneric *obj, const char *path) { |
92 GError *error = NULL; |
|
93 GdkPixbuf *pixbuf = gtk_icon_info_load_icon(icon->info, &error); |
|
94 if(pixbuf) { |
|
95 UiImage *img = malloc(sizeof(UiImage)); |
|
96 img->pixbuf = pixbuf; |
|
97 return img; |
|
98 } |
|
99 return NULL; |
|
100 } |
|
101 |
|
102 UiImage* ui_image(const char *filename) { |
|
103 return ui_named_image(filename, NULL); |
|
104 } |
|
105 |
|
106 UiImage* ui_named_image(const char *filename, const char *name) { |
|
107 char *path = uic_get_image_path(filename); |
|
108 if(!path) { |
|
109 fprintf(stderr, "UiError: pixmaps directory not set\n"); |
|
110 return NULL; |
|
111 } |
|
112 UiImage *img = ui_load_image_from_path(path, name); |
|
113 free(path); |
|
114 return img; |
|
115 } |
|
116 |
|
117 UiImage* ui_load_image_from_path(const char *path, const char *name) { |
|
118 GError *error = NULL; |
122 GError *error = NULL; |
119 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(path, &error); |
123 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(path, &error); |
120 if(!pixbuf) { |
124 if(!pixbuf) { |
121 fprintf(stderr, "UiError: Cannot load image: %s\n", path); |
125 return 1; |
122 return NULL; |
|
123 } |
126 } |
124 |
127 |
125 UiImage *img = malloc(sizeof(UiImage)); |
128 if(obj->set) { |
126 img->pixbuf = pixbuf; |
129 obj->set(obj, pixbuf, UI_IMAGE_OBJECT_TYPE); |
127 if(name) { |
130 } else { |
128 ucx_map_cstr_put(image_map, name, img); |
131 obj->value = pixbuf; |
129 } |
132 } |
130 return img; |
133 |
|
134 return 0; |
131 } |
135 } |
132 |
|
133 void ui_free_image(UiImage *img) { |
|
134 g_object_unref(img->pixbuf); |
|
135 free(img); |
|
136 } |
|