2929
3030#include "e-image-chooser.h"
3131
32+ typedef struct _EImageChooserPrivate EImageChooserPrivate ;
3233struct _EImageChooserPrivate {
3334
3435 GtkWidget * image ;
35- GtkWidget * browse_button ;
3636
3737 char * image_buf ;
3838 int image_buf_size ;
39- int image_width ;
40- int image_height ;
39+ int width ;
40+ int height ;
4141
4242 gboolean editable ;
43+ gboolean scaleable ;
4344};
4445
4546enum {
4647 CHANGED ,
4748 LAST_SIGNAL
4849};
4950
51+ enum {
52+ PROP_0 ,
53+ PROP_WIDTH ,
54+ PROP_HEIGHT ,
55+ NUM_PROPERTIES
56+ };
5057
58+ static GParamSpec * properties [NUM_PROPERTIES ] = { NULL , };
5159static guint image_chooser_signals [LAST_SIGNAL ] = { 0 };
52-
5360static void e_image_chooser_init (EImageChooser * chooser );
5461static void e_image_chooser_class_init (EImageChooserClass * klass );
5562static void e_image_chooser_dispose (GObject * object );
@@ -66,8 +73,7 @@ static void image_drag_data_received_cb (GtkWidget *widget,
6673 GtkSelectionData * selection_data ,
6774 guint info , guint time , EImageChooser * chooser );
6875
69- static GObjectClass * parent_class = NULL ;
70- #define PARENT_TYPE GTK_TYPE_BOX
76+ G_DEFINE_TYPE_WITH_PRIVATE (EImageChooser , e_image_chooser , GTK_TYPE_BOX );
7177
7278enum DndTargetType {
7379 DND_TARGET_TYPE_URI_LIST
@@ -85,37 +91,69 @@ e_image_chooser_new (void)
8591 return g_object_new (E_TYPE_IMAGE_CHOOSER , "orientation" , GTK_ORIENTATION_VERTICAL , NULL );
8692}
8793
88- GType
89- e_image_chooser_get_type (void )
94+ GtkWidget * e_image_chooser_new_with_size (int width , int height )
9095{
91- static GType eic_type = 0 ;
92-
93- if (!eic_type ) {
94- static const GTypeInfo eic_info = {
95- sizeof (EImageChooserClass ),
96- NULL , /* base_init */
97- NULL , /* base_finalize */
98- (GClassInitFunc ) e_image_chooser_class_init ,
99- NULL , /* class_finalize */
100- NULL , /* class_data */
101- sizeof (EImageChooser ),
102- 0 , /* n_preallocs */
103- (GInstanceInitFunc ) e_image_chooser_init ,
104- };
105-
106- eic_type = g_type_register_static (PARENT_TYPE , "EImageChooser" , & eic_info , 0 );
107- }
96+ return g_object_new (E_TYPE_IMAGE_CHOOSER ,
97+ "width" , width ,
98+ "height" , height ,
99+ "orientation" , GTK_ORIENTATION_VERTICAL , NULL );
100+ }
108101
109- return eic_type ;
102+ static void
103+ e_image_chooser_set_property (GObject * object ,
104+ guint prop_id ,
105+ const GValue * value ,
106+ GParamSpec * pspec )
107+ {
108+ EImageChooserPrivate * priv ;
109+
110+ priv = e_image_chooser_get_instance_private (E_IMAGE_CHOOSER (object ));
111+
112+ switch (prop_id )
113+ {
114+ case PROP_WIDTH :
115+ priv -> width = g_value_get_int (value );
116+ priv -> scaleable = FALSE;
117+ break ;
118+ case PROP_HEIGHT :
119+ priv -> height = g_value_get_int (value );
120+ priv -> scaleable = FALSE;
121+ break ;
122+ default :
123+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object , prop_id , pspec );
124+ break ;
125+ }
110126}
111127
128+ static void
129+ e_image_chooser_get_property (GObject * object , guint prop_id , GValue * value , GParamSpec * pspec )
130+ {
131+ EImageChooserPrivate * priv ;
132+
133+ priv = e_image_chooser_get_instance_private (E_IMAGE_CHOOSER (object ));
134+
135+ switch (prop_id )
136+ {
137+ case PROP_WIDTH :
138+ g_value_set_int (value , priv -> width );
139+ break ;
140+ case PROP_HEIGHT :
141+ g_value_set_int (value , priv -> height );
142+ break ;
143+ default :
144+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object , prop_id , pspec );
145+ break ;
146+ }
147+ }
112148
113149static void
114150e_image_chooser_class_init (EImageChooserClass * klass )
115151{
116152 GObjectClass * object_class = G_OBJECT_CLASS (klass );
117153
118- parent_class = g_type_class_ref (PARENT_TYPE );
154+ object_class -> dispose = e_image_chooser_dispose ;
155+ object_class -> set_property = e_image_chooser_set_property ;
156+ object_class -> get_property = e_image_chooser_get_property ;
119157
120158 image_chooser_signals [CHANGED ] =
121159 g_signal_new ("changed" ,
@@ -125,18 +163,33 @@ e_image_chooser_class_init (EImageChooserClass *klass)
125163 NULL , NULL ,
126164 g_cclosure_marshal_VOID__VOID ,
127165 G_TYPE_NONE , 0 );
128-
129- object_class -> dispose = e_image_chooser_dispose ;
166+ properties [PROP_WIDTH ] =
167+ g_param_spec_int ("width" ,
168+ "Chooser width" ,
169+ "Chooser width to show image" ,
170+ 0 , G_MAXINT ,
171+ 32 ,
172+ G_PARAM_READWRITE );
173+ properties [PROP_HEIGHT ] =
174+ g_param_spec_int ("height" ,
175+ "Chooser height" ,
176+ "Chooser height to show image" ,
177+ 0 , G_MAXINT ,
178+ 32 ,
179+ G_PARAM_READWRITE );
180+
181+ g_object_class_install_properties (object_class , NUM_PROPERTIES , properties );
130182}
131183
132184static void
133185e_image_chooser_init (EImageChooser * chooser )
134186{
135187 EImageChooserPrivate * priv ;
136188
137- priv = chooser -> priv = g_new0 ( EImageChooserPrivate , 1 );
189+ priv = e_image_chooser_get_instance_private ( chooser );
138190
139191 priv -> image = gtk_image_new ();
192+ priv -> scaleable = TRUE;
140193
141194 gtk_box_set_homogeneous (GTK_BOX (chooser ), FALSE);
142195 gtk_box_pack_start (GTK_BOX (chooser ), priv -> image , TRUE, TRUE, 0 );
@@ -158,22 +211,18 @@ e_image_chooser_init (EImageChooser *chooser)
158211static void
159212e_image_chooser_dispose (GObject * object )
160213{
161- EImageChooser * eic = E_IMAGE_CHOOSER ( object ) ;
214+ EImageChooserPrivate * priv ;
162215
163- if (eic -> priv ) {
164- EImageChooserPrivate * priv = eic -> priv ;
216+ priv = e_image_chooser_get_instance_private (E_IMAGE_CHOOSER (object ));
165217
166- if (priv -> image_buf ) {
167- g_free (priv -> image_buf );
168- priv -> image_buf = NULL ;
169- }
170218
171- g_free (eic -> priv );
172- eic -> priv = NULL ;
219+ if (priv -> image_buf ) {
220+ g_free (priv -> image_buf );
221+ priv -> image_buf = NULL ;
173222 }
174223
175- if (G_OBJECT_CLASS (parent_class )-> dispose )
176- (* G_OBJECT_CLASS (parent_class )-> dispose ) (object );
224+ if (G_OBJECT_CLASS (e_image_chooser_parent_class )-> dispose )
225+ (* G_OBJECT_CLASS (e_image_chooser_parent_class )-> dispose ) (object );
177226}
178227
179228
@@ -184,6 +233,9 @@ set_image_from_data (EImageChooser *chooser,
184233 gboolean rv = FALSE;
185234 GdkPixbufLoader * loader = gdk_pixbuf_loader_new ();
186235 GdkPixbuf * pixbuf ;
236+ EImageChooserPrivate * priv ;
237+
238+ priv = e_image_chooser_get_instance_private (chooser );
187239
188240 gdk_pixbuf_loader_write (loader , (guchar * ) data , length , NULL );
189241 gdk_pixbuf_loader_close (loader , NULL );
@@ -195,64 +247,22 @@ set_image_from_data (EImageChooser *chooser,
195247
196248 if (pixbuf ) {
197249 GdkPixbuf * scaled ;
198- GtkRequisition chooser_size ;
199-
200- float scale ;
201- int new_height , new_width ;
202-
203- gtk_widget_get_preferred_size (gtk_widget_get_parent (GTK_WIDGET (chooser )),
204- & chooser_size , NULL );
205- chooser_size .width -= 5 ;
206- chooser_size .height -= 5 ;
207-
208- new_height = gdk_pixbuf_get_height (pixbuf );
209- new_width = gdk_pixbuf_get_width (pixbuf );
210-
211- if (chooser -> priv -> image_height == 0
212- && chooser -> priv -> image_width == 0 ) {
213- scale = 1.0 ;
214- }
215- else if (chooser -> priv -> image_height < new_height
216- || chooser -> priv -> image_width < new_width ) {
217- /* we need to scale down */
218- if (new_height > new_width )
219- scale = (float )chooser_size .height / new_height ;
220- else
221- scale = (float )chooser_size .width / new_width ;
222- }
223- else {
224- /* we need to scale up */
225- if (new_height > new_width )
226- scale = (float )new_height / chooser_size .height ;
227- else
228- scale = (float )new_width / chooser_size .width ;
229- }
230-
231- if (scale == 1.0 ) {
232- gtk_image_set_from_pixbuf (GTK_IMAGE (chooser -> priv -> image ), pixbuf );
233-
234- chooser -> priv -> image_width = new_width ;
235- chooser -> priv -> image_height = new_height ;
236- }
237- else {
238- new_width *= scale ;
239- new_height *= scale ;
240- new_width = MIN (new_width , chooser_size .width );
241- new_height = MIN (new_height , chooser_size .height );
242-
250+ if (priv -> scaleable ) {
251+ gtk_image_set_from_pixbuf (GTK_IMAGE (priv -> image ), pixbuf );
252+ } else {
243253 scaled = gdk_pixbuf_scale_simple (pixbuf ,
244- new_width , new_height ,
254+ priv -> width , priv -> height ,
245255 GDK_INTERP_BILINEAR );
246256
247- gtk_image_set_from_pixbuf (GTK_IMAGE (chooser -> priv -> image ), scaled );
257+ gtk_image_set_from_pixbuf (GTK_IMAGE (priv -> image ), scaled );
248258 g_object_unref (scaled );
249259 }
250260
251261 g_object_unref (pixbuf );
252262
253- g_free (chooser -> priv -> image_buf );
254- chooser -> priv -> image_buf = data ;
255- chooser -> priv -> image_buf_size = length ;
263+ g_free (priv -> image_buf );
264+ priv -> image_buf = data ;
265+ priv -> image_buf_size = length ;
256266
257267 g_signal_emit (chooser ,
258268 image_chooser_signals [CHANGED ], 0 );
@@ -269,8 +279,11 @@ image_drag_motion_cb (GtkWidget *widget,
269279 gint x , gint y , guint time , EImageChooser * chooser )
270280{
271281 GList * p ;
282+ EImageChooserPrivate * priv ;
283+
284+ priv = e_image_chooser_get_instance_private (chooser );
272285
273- if (!chooser -> priv -> editable )
286+ if (!priv -> editable )
274287 return FALSE;
275288
276289 for (p = gdk_drag_context_list_targets (context ); p ; p = p -> next ) {
@@ -295,8 +308,11 @@ image_drag_drop_cb (GtkWidget *widget,
295308 gint x , gint y , guint time , EImageChooser * chooser )
296309{
297310 GList * p ;
311+ EImageChooserPrivate * priv ;
298312
299- if (!chooser -> priv -> editable )
313+ priv = e_image_chooser_get_instance_private (chooser );
314+
315+ if (!priv -> editable )
300316 return FALSE;
301317
302318 if (gdk_drag_context_list_targets (context ) == NULL ) {
@@ -414,10 +430,22 @@ void
414430e_image_chooser_set_editable (EImageChooser * chooser , gboolean editable )
415431{
416432 g_return_if_fail (E_IS_IMAGE_CHOOSER (chooser ));
433+ EImageChooserPrivate * priv ;
434+
435+ priv = e_image_chooser_get_instance_private (chooser );
436+
437+ priv -> editable = editable ;
438+ }
439+
440+ void
441+ e_image_chooser_set_scaleable (EImageChooser * chooser , gboolean scaleable )
442+ {
443+ g_return_if_fail (E_IS_IMAGE_CHOOSER (chooser ));
444+ EImageChooserPrivate * priv ;
417445
418- chooser -> priv -> editable = editable ;
446+ priv = e_image_chooser_get_instance_private ( chooser ) ;
419447
420- gtk_widget_set_sensitive ( chooser -> priv -> browse_button , editable ) ;
448+ priv -> scaleable = scaleable ;
421449}
422450
423451gboolean
@@ -426,10 +454,13 @@ e_image_chooser_get_image_data (EImageChooser *chooser, char **data, gsize *data
426454 g_return_val_if_fail (E_IS_IMAGE_CHOOSER (chooser ), FALSE);
427455 g_return_val_if_fail (data != NULL , FALSE);
428456 g_return_val_if_fail (data_length != NULL , FALSE);
457+ EImageChooserPrivate * priv ;
458+
459+ priv = e_image_chooser_get_instance_private (chooser );
429460
430- * data_length = chooser -> priv -> image_buf_size ;
461+ * data_length = priv -> image_buf_size ;
431462 * data = g_malloc (* data_length );
432- memcpy (* data , chooser -> priv -> image_buf , * data_length );
463+ memcpy (* data , priv -> image_buf , * data_length );
433464
434465 return TRUE;
435466}
0 commit comments