aboutsummaryrefslogtreecommitdiff
path: root/src/ui/send_file.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/send_file.c')
-rw-r--r--src/ui/send_file.c176
1 files changed, 172 insertions, 4 deletions
diff --git a/src/ui/send_file.c b/src/ui/send_file.c
index cde2c4d..2d3f4a6 100644
--- a/src/ui/send_file.c
+++ b/src/ui/send_file.c
@@ -71,6 +71,146 @@ handle_dialog_destroy(UNUSED GtkWidget *window,
71 ui_send_file_dialog_cleanup((UI_SEND_FILE_Handle*) user_data); 71 ui_send_file_dialog_cleanup((UI_SEND_FILE_Handle*) user_data);
72} 72}
73 73
74static int
75handle_file_redraw_animation(gpointer user_data)
76{
77 UI_SEND_FILE_Handle *handle = (UI_SEND_FILE_Handle*) user_data;
78
79 handle->redraw_animation = 0;
80
81 if (handle->file_drawing_area)
82 gtk_widget_queue_draw(GTK_WIDGET(handle->file_drawing_area));
83
84 return FALSE;
85}
86
87static gboolean
88handle_file_drawing_area_draw(GtkWidget* drawing_area,
89 cairo_t* cairo,
90 gpointer user_data)
91{
92 UI_SEND_FILE_Handle *handle = (UI_SEND_FILE_Handle*) user_data;
93
94 GtkStyleContext* context = gtk_widget_get_style_context(drawing_area);
95
96 const guint width = gtk_widget_get_allocated_width(drawing_area);
97 const guint height = gtk_widget_get_allocated_height(drawing_area);
98
99 gtk_render_background(context, cairo, 0, 0, width, height);
100
101 GdkPixbuf *image = handle->image;
102
103 if (!handle->animation)
104 goto render_image;
105
106 if (handle->animation_iter)
107 gdk_pixbuf_animation_iter_advance(handle->animation_iter, NULL);
108 else
109 handle->animation_iter = gdk_pixbuf_animation_get_iter(
110 handle->animation, NULL
111 );
112
113 image = gdk_pixbuf_animation_iter_get_pixbuf(handle->animation_iter);
114
115 const int delay = gdk_pixbuf_animation_iter_get_delay_time(
116 handle->animation_iter
117 );
118
119 handle->redraw_animation = g_timeout_add(
120 delay, handle_file_redraw_animation, handle
121 );
122
123render_image:
124 if (!image)
125 return FALSE;
126
127 int dwidth = gdk_pixbuf_get_width(image);
128 int dheight = gdk_pixbuf_get_height(image);
129
130 double ratio_width = 1.0 * width / dwidth;
131 double ratio_height = 1.0 * height / dheight;
132
133 const double ratio = ratio_width < ratio_height? ratio_width : ratio_height;
134
135 dwidth = (int) (dwidth * ratio);
136 dheight = (int) (dheight * ratio);
137
138 double dx = (width - dwidth) * 0.5;
139 double dy = (height - dheight) * 0.5;
140
141 const int interp_type = (ratio >= 1.0?
142 GDK_INTERP_NEAREST :
143 GDK_INTERP_BILINEAR
144 );
145
146 GdkPixbuf* scaled = gdk_pixbuf_scale_simple(
147 image,
148 dwidth,
149 dheight,
150 interp_type
151 );
152
153 gtk_render_icon(context, cairo, scaled, dx, dy);
154
155 cairo_fill(cairo);
156
157 g_object_unref(scaled);
158 return FALSE;
159}
160
161static void
162_clear_file_preview_data(UI_SEND_FILE_Handle *handle)
163{
164 if (handle->image)
165 {
166 g_object_unref(handle->image);
167 handle->image = NULL;
168 }
169
170 if (handle->redraw_animation)
171 {
172 g_source_remove(handle->redraw_animation);
173 handle->redraw_animation = 0;
174 }
175
176 if (handle->animation_iter)
177 {
178 g_object_unref(handle->animation_iter);
179 handle->animation_iter = NULL;
180 }
181
182 if (handle->animation)
183 {
184 g_object_unref(handle->animation);
185 handle->animation = NULL;
186 }
187}
188
189static void
190handle_file_chooser_button_file_set(GtkFileChooserButton *file_chooser_button,
191 gpointer user_data)
192{
193 UI_SEND_FILE_Handle *handle = (UI_SEND_FILE_Handle*) user_data;
194
195 _clear_file_preview_data(handle);
196
197 char *filename = gtk_file_chooser_get_filename(
198 GTK_FILE_CHOOSER(file_chooser_button)
199 );
200
201 if (filename)
202 {
203 handle->animation = gdk_pixbuf_animation_new_from_file(filename, NULL);
204
205 if (!handle->animation)
206 handle->image = gdk_pixbuf_new_from_file(filename, NULL);
207
208 g_free(filename);
209 }
210
211 gtk_widget_queue_draw(GTK_WIDGET(handle->file_drawing_area));
212}
213
74void 214void
75ui_send_file_dialog_init(MESSENGER_Application *app, 215ui_send_file_dialog_init(MESSENGER_Application *app,
76 UI_SEND_FILE_Handle *handle) 216 UI_SEND_FILE_Handle *handle)
@@ -99,6 +239,20 @@ ui_send_file_dialog_init(MESSENGER_Application *app,
99 gtk_builder_get_object(handle->builder, "file_chooser_button") 239 gtk_builder_get_object(handle->builder, "file_chooser_button")
100 ); 240 );
101 241
242 g_signal_connect(
243 handle->file_drawing_area,
244 "draw",
245 G_CALLBACK(handle_file_drawing_area_draw),
246 handle
247 );
248
249 g_signal_connect(
250 handle->file_chooser_button,
251 "file-set",
252 G_CALLBACK(handle_file_chooser_button_file_set),
253 handle
254 );
255
102 handle->cancel_button = GTK_BUTTON( 256 handle->cancel_button = GTK_BUTTON(
103 gtk_builder_get_object(handle->builder, "cancel_button") 257 gtk_builder_get_object(handle->builder, "cancel_button")
104 ); 258 );
@@ -127,22 +281,36 @@ ui_send_file_dialog_init(MESSENGER_Application *app,
127 G_CALLBACK(handle_dialog_destroy), 281 G_CALLBACK(handle_dialog_destroy),
128 handle 282 handle
129 ); 283 );
284
285 handle->image = NULL;
286 handle->animation = NULL;
287 handle->animation_iter = NULL;
288
289 handle->redraw_animation = 0;
130} 290}
131 291
132void 292void
133ui_send_file_dialog_update(UI_SEND_FILE_Handle *handle, 293ui_send_file_dialog_update(UI_SEND_FILE_Handle *handle,
134 const gchar *filename) 294 const gchar *filename)
135{ 295{
136 if ((!filename) || (!gtk_file_chooser_set_filename( 296 if (!handle->file_chooser_button)
137 GTK_FILE_CHOOSER(handle->file_chooser_button),
138 filename)))
139 return; 297 return;
140 298
141 // TODO: update preview 299 gtk_file_chooser_set_filename(
300 GTK_FILE_CHOOSER(handle->file_chooser_button),
301 filename
302 );
303
304 handle_file_chooser_button_file_set(
305 handle->file_chooser_button,
306 handle
307 );
142} 308}
143 309
144void 310void
145ui_send_file_dialog_cleanup(UI_SEND_FILE_Handle *handle) 311ui_send_file_dialog_cleanup(UI_SEND_FILE_Handle *handle)
146{ 312{
313 _clear_file_preview_data(handle);
314
147 g_object_unref(handle->builder); 315 g_object_unref(handle->builder);
148} 316}