]> git.sur5r.net Git - glabels/blob - glabels2/src/font-combo.c
44dfc396280857a54d7013540d76dec431068f6e
[glabels] / glabels2 / src / font-combo.c
1 /*
2  *  font-combo.c
3  *  Copyright (C) 2009  Jim Evins <evins@snaught.com>.
4  *
5  *  This file is part of gLabels.
6  *
7  *  gLabels is free software: you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation, either version 3 of the License, or
10  *  (at your option) any later version.
11  *
12  *  gLabels is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with gLabels.  If not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include <config.h>
22
23 #include "font-combo.h"
24
25 #include "font-combo-menu.h"
26 #include <glib/gi18n.h>
27 #include <gtk/gtkhbox.h>
28 #include <gtk/gtklabel.h>
29 #include <gtk/gtkarrow.h>
30 #include "marshal.h"
31
32
33
34 /*========================================================*/
35 /* Private types.                                         */
36 /*========================================================*/
37
38 /** GL_FONT_COMBO Private fields */
39 struct _glFontComboPrivate {
40
41         gchar      *font_family;
42
43         GtkWidget  *label;
44
45         GtkWidget  *menu;
46 };
47
48 enum {
49         CHANGED,
50         LAST_SIGNAL
51 };
52
53
54 /*========================================================*/
55 /* Private globals.                                       */
56 /*========================================================*/
57
58 static guint signals[LAST_SIGNAL] = {0};
59
60
61 /*========================================================*/
62 /* Private function prototypes.                           */
63 /*========================================================*/
64
65 static void gl_font_combo_finalize      (GObject             *object);
66
67 static gboolean
68 button_press_event_cb (GtkWidget      *widget,
69                        GdkEventButton *event,
70                        glFontCombo    *this);
71
72 static void
73 menu_font_changed_cb   (glFontComboMenu  *menu,
74                         glFontCombo      *this);
75
76 static void
77 menu_selection_done_cb (GtkMenuShell     *object,
78                         glFontCombo      *this);
79
80
81 /*****************************************************************************/
82 /* Object infrastructure.                                                    */
83 /*****************************************************************************/
84 G_DEFINE_TYPE (glFontCombo, gl_font_combo, GTK_TYPE_TOGGLE_BUTTON);
85
86
87 /*****************************************************************************/
88 /* Class Init Function.                                                      */
89 /*****************************************************************************/
90 static void
91 gl_font_combo_class_init (glFontComboClass *class)
92 {
93         GObjectClass      *gobject_class = (GObjectClass *) class;
94         GtkWidgetClass    *widget_class  = (GtkWidgetClass *) class;
95         glFontComboClass  *object_class  = (glFontComboClass *) class;
96
97         gl_font_combo_parent_class = g_type_class_peek_parent (class);
98
99         gobject_class->finalize = gl_font_combo_finalize;
100
101         signals[CHANGED] =
102                 g_signal_new ("changed",
103                               G_OBJECT_CLASS_TYPE (gobject_class),
104                               G_SIGNAL_RUN_LAST,
105                               G_STRUCT_OFFSET (glFontComboClass, changed),
106                               NULL, NULL,
107                               gl_marshal_VOID__VOID,
108                               G_TYPE_NONE, 0);
109 }
110
111
112 /*****************************************************************************/
113 /* Object Instance Init Function.                                            */
114 /*****************************************************************************/
115 static void
116 gl_font_combo_init (glFontCombo *this)
117 {
118         GtkWidget *hbox;
119         GtkWidget *arrow;
120
121         this->priv = g_new0 (glFontComboPrivate, 1);
122
123         hbox = gtk_hbox_new (FALSE, 3);
124         gtk_container_add (GTK_CONTAINER (this), hbox);
125         
126         this->priv->label = gtk_label_new ("");
127         gtk_misc_set_alignment (GTK_MISC (this->priv->label), 0.0, 0.5);
128         gtk_widget_set_size_request (this->priv->label, 180, -1);
129         gtk_box_pack_start (GTK_BOX (hbox), this->priv->label, TRUE, TRUE, 0);
130
131         arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_IN);
132         gtk_box_pack_end (GTK_BOX (hbox), arrow, FALSE, FALSE, 0);
133
134         g_signal_connect (this, "button_press_event",
135                           G_CALLBACK(button_press_event_cb), this);
136 }
137
138
139 /*****************************************************************************/
140 /* Finalize Method.                                                          */
141 /*****************************************************************************/
142 static void
143 gl_font_combo_finalize (GObject *object)
144 {
145         glFontCombo    *this;
146
147         g_return_if_fail (object && IS_GL_FONT_COMBO (object));
148         this = GL_FONT_COMBO (object);
149
150         g_free (this->priv->font_family);
151         g_object_ref_sink (this->priv->menu);
152         g_free (this->priv);
153
154         G_OBJECT_CLASS (gl_font_combo_parent_class)->finalize (object);
155 }
156
157
158 /*****************************************************************************/
159 /** New Object Generator.                                                    */
160 /*****************************************************************************/
161 GtkWidget *
162 gl_font_combo_new (const gchar  *font_family)
163 {
164         glFontCombo  *this;
165
166         this = g_object_new (TYPE_GL_FONT_COMBO, NULL);
167
168         this->priv->font_family = g_strdup (font_family);
169
170         gtk_label_set_text (GTK_LABEL (this->priv->label), font_family);
171
172         this->priv->menu = gl_font_combo_menu_new ();
173
174         gtk_widget_show_all (this->priv->menu);
175
176         g_signal_connect (this->priv->menu, "font_changed",
177                           G_CALLBACK (menu_font_changed_cb), this);
178         g_signal_connect (this->priv->menu, "selection_done",
179                           G_CALLBACK (menu_selection_done_cb), this);
180
181         return GTK_WIDGET (this);
182 }
183
184
185 /*****************************************************************************/
186 /** Set relief style.                                                        */
187 /*****************************************************************************/
188 void
189 gl_font_combo_set_relief( glFontCombo    *this,
190                           GtkReliefStyle  relief )
191 {
192         gtk_button_set_relief (GTK_BUTTON (this), relief);
193 }
194
195
196 /*****************************************************************************/
197 /* Set font family.                                                          */
198 /*****************************************************************************/
199 void
200 gl_font_combo_set_family (glFontCombo  *this,
201                           const gchar  *font_family)
202 {
203
204         this->priv->font_family = g_strdup (font_family);
205
206         gtk_label_set_text (GTK_LABEL (this->priv->label), font_family);
207 }
208
209
210 /*****************************************************************************/
211 /* Get font family.                                                          */
212 /*****************************************************************************/
213 gchar *
214 gl_font_combo_get_family (glFontCombo  *this)
215 {
216         return g_strdup (this->priv->font_family);
217 }
218
219
220 /*****************************************************************************/
221 /* Menu positioning function.                                                */
222 /*****************************************************************************/
223 static void
224 menu_position_function (GtkMenu  *menu,
225                         gint     *x,
226                         gint     *y,
227                         gboolean *push_in,
228                         gpointer  user_data)
229 {
230         glFontCombo *this = GL_FONT_COMBO (user_data);
231         gint          x1, y1;
232         gint          menu_h, menu_w;
233
234         gdk_window_get_origin (GTK_WIDGET (this)->window, &x1, &y1);
235         *x = x1 + GTK_WIDGET (this)->allocation.x;
236         *y = y1 + GTK_WIDGET (this)->allocation.y +
237                 GTK_WIDGET (this)->allocation.height;
238                 
239         menu_h = this->priv->menu->allocation.height;
240         menu_w = this->priv->menu->allocation.width;
241
242         if ((*y + menu_h) > gdk_screen_height ())
243         {
244                 *y = y1 + GTK_WIDGET (this)->allocation.y - menu_h;
245                 if ( *y < 0 )
246                 {
247                         *y = gdk_screen_height () - menu_h;
248                 }
249         }
250
251         if ((*x + menu_w) > gdk_screen_width ())
252         {
253                 *x = gdk_screen_width () - menu_w;
254         }
255
256         *push_in = TRUE;
257 }
258
259
260 /*****************************************************************************/
261 /* Button "button_press_event" callback.                                     */
262 /*****************************************************************************/
263 static gboolean
264 button_press_event_cb (GtkWidget      *widget,
265                        GdkEventButton *event,
266                        glFontCombo   *this)
267 {
268         switch (event->button)
269         {
270
271         case 1:
272                 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (this), TRUE);
273
274                 gtk_menu_popup (GTK_MENU (this->priv->menu),
275                                 NULL, NULL,
276                                 menu_position_function, this,
277                                 event->button, event->time);
278                 break;
279
280         default:
281                 break;
282
283         }
284
285         return FALSE;
286 }
287
288
289 /*****************************************************************************/
290 /* Menu "font changed" callback.                                             */
291 /*****************************************************************************/
292 static void
293 menu_font_changed_cb (glFontComboMenu     *menu,
294                       glFontCombo         *this)
295 {
296         this->priv->font_family = gl_font_combo_menu_get_family (menu);
297
298         gtk_label_set_text (GTK_LABEL (this->priv->label), this->priv->font_family);
299
300         g_signal_emit (this, signals[CHANGED], 0);
301 }
302
303
304 /*****************************************************************************/
305 /* Menu "selection done" callback.                                           */
306 /*****************************************************************************/
307 static void
308 menu_selection_done_cb (GtkMenuShell         *object,
309                         glFontCombo         *this)
310 {
311         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (this), FALSE);
312 }
313
314
315
316 /*
317  * Local Variables:       -- emacs
318  * mode: C                -- emacs
319  * c-basic-offset: 8      -- emacs
320  * tab-width: 8           -- emacs
321  * indent-tabs-mode: nil  -- emacs
322  * End:                   -- emacs
323  */