]> git.sur5r.net Git - glabels/blob - src/font-combo-menu.c
2a0a7c59fa80b94ee851b86969d720debf25a77b
[glabels] / src / font-combo-menu.c
1 /*
2  *  font-combo-menu.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-menu.h"
24
25 #include <glib/gi18n.h>
26 #include <gtk/gtk.h>
27
28 #include "font-combo-menu-item.h"
29 #include "font-util.h"
30 #include "font-history.h"
31 #include "marshal.h"
32
33
34 /*===========================================*/
35 /* Private macros and constants.             */
36 /*===========================================*/
37
38
39 /*===========================================*/
40 /* Private types                             */
41 /*===========================================*/
42
43 struct _glFontComboMenuPrivate {
44
45         gchar     *font_family;
46
47         GtkWidget *recent_menu_item;
48         GtkWidget *recent_sub_menu;
49
50 };
51
52 enum {
53         FONT_CHANGED,
54         LAST_SIGNAL
55 };
56
57 gchar *standard_families[] = { "Sans", "Serif", "Monospace", NULL };
58
59 /*===========================================*/
60 /* Private globals                           */
61 /*===========================================*/
62
63 static guint signals[LAST_SIGNAL] = {0};
64
65
66 /*===========================================*/
67 /* Local function prototypes                 */
68 /*===========================================*/
69
70 static void       gl_font_combo_menu_finalize (GObject             *object);
71
72 static void       menu_item_activate_cb       (glFontComboMenuItem *item,
73                                                glFontComboMenu     *this);
74
75 static GtkWidget *new_font_sub_menu           (glFontComboMenu     *this,
76                                                const GList         *list);
77
78 static void       font_history_changed_cb     (glFontComboMenu     *this);
79
80
81
82 /****************************************************************************/
83 /* Boilerplate Object stuff.                                                */
84 /****************************************************************************/
85 G_DEFINE_TYPE (glFontComboMenu, gl_font_combo_menu, GTK_TYPE_MENU);
86
87
88 /*****************************************************************************/
89 /* Class Init Function.                                                      */
90 /*****************************************************************************/
91 static void
92 gl_font_combo_menu_class_init (glFontComboMenuClass *class)
93 {
94         GObjectClass   *gobject_class = G_OBJECT_CLASS (class);
95
96         gl_font_combo_menu_parent_class = g_type_class_peek_parent (class);
97
98         gobject_class->finalize = gl_font_combo_menu_finalize;
99
100         signals[FONT_CHANGED] =
101                 g_signal_new ("font_changed",
102                               G_OBJECT_CLASS_TYPE (gobject_class),
103                               G_SIGNAL_RUN_LAST,
104                               G_STRUCT_OFFSET (glFontComboMenuClass, font_changed),
105                               NULL, NULL,
106                               gl_marshal_VOID__VOID,
107                               G_TYPE_NONE, 0);
108 }
109
110
111 /*****************************************************************************/
112 /* Object Instance Init Function.                                            */
113 /*****************************************************************************/
114 static void
115 gl_font_combo_menu_init (glFontComboMenu *this)
116 {
117         gint          i;
118         GtkWidget    *menu_item;
119         GtkWidget    *sub_menu;
120         const GList  *list;
121         GList        *p;
122
123         this->priv = g_new0 (glFontComboMenuPrivate, 1);
124
125
126         for ( i = 0; standard_families[i] != NULL; i++ )
127         {
128                 menu_item = gl_font_combo_menu_item_new (standard_families[i]);
129                 gtk_menu_shell_append (GTK_MENU_SHELL (this), menu_item);
130                 g_signal_connect (menu_item, "activate",
131                                   G_CALLBACK (menu_item_activate_cb), this);
132         }
133
134         menu_item = gtk_separator_menu_item_new ();
135         gtk_menu_shell_append (GTK_MENU_SHELL (this), menu_item);
136
137
138         menu_item = gtk_menu_item_new_with_label (_("Recent fonts"));
139         gtk_menu_shell_append (GTK_MENU_SHELL (this), menu_item);
140
141         list = gl_font_history_model_get_family_list (gl_font_history);
142         sub_menu = new_font_sub_menu (this, list);
143         gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), sub_menu);
144         gtk_widget_set_sensitive (menu_item, list != NULL);
145
146         this->priv->recent_menu_item = menu_item;
147         this->priv->recent_sub_menu  = sub_menu;
148
149         menu_item = gtk_separator_menu_item_new ();
150         gtk_menu_shell_append (GTK_MENU_SHELL (this), menu_item);
151
152
153         menu_item = gtk_menu_item_new_with_label (_("Proportional fonts"));
154         gtk_menu_shell_append (GTK_MENU_SHELL (this), menu_item);
155
156         list = gl_font_util_get_proportional_families ();
157         sub_menu = new_font_sub_menu (this, list);
158         gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), sub_menu);
159         gtk_widget_set_sensitive (menu_item, list != NULL);
160
161         menu_item = gtk_menu_item_new_with_label (_("Fixed-width fonts"));
162         gtk_menu_shell_append (GTK_MENU_SHELL (this), menu_item);
163
164         list = gl_font_util_get_fixed_width_families ();
165         sub_menu = new_font_sub_menu (this, list);
166         gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), sub_menu);
167         gtk_widget_set_sensitive (menu_item, list != NULL);
168
169         menu_item = gtk_menu_item_new_with_label (_("All fonts"));
170         gtk_menu_shell_append (GTK_MENU_SHELL (this), menu_item);
171
172         list = gl_font_util_get_all_families ();
173         sub_menu = new_font_sub_menu (this, list);
174         gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), sub_menu);
175         gtk_widget_set_sensitive (menu_item, list != NULL);
176
177
178         gtk_widget_show_all (GTK_WIDGET (this));
179
180
181         g_signal_connect_swapped (gl_font_history, "changed",
182                                   G_CALLBACK (font_history_changed_cb), this);
183
184 }
185
186
187 /*****************************************************************************/
188 /* Finalize Method.                                                          */
189 /*****************************************************************************/
190 static void
191 gl_font_combo_menu_finalize (GObject *object)
192 {
193         glFontComboMenu *this = GL_FONT_COMBO_MENU (object);
194
195         g_return_if_fail (object != NULL);
196         g_return_if_fail (GL_IS_FONT_COMBO_MENU (object));
197
198         g_free (this->priv);
199
200         G_OBJECT_CLASS (gl_font_combo_menu_parent_class)->finalize (object);
201 }
202
203
204 /*****************************************************************************/
205 /** New Object Generator.                                                    */
206 /*****************************************************************************/
207 GtkWidget *
208 gl_font_combo_menu_new (void)
209 {
210         glFontComboMenu *this;
211
212         this = g_object_new (gl_font_combo_menu_get_type (), NULL);
213
214         return GTK_WIDGET (this);
215 }
216
217
218 /*****************************************************************************/
219 /* menu_item activate callback.                                              */
220 /*****************************************************************************/
221 static void menu_item_activate_cb (glFontComboMenuItem *item,
222                                    glFontComboMenu     *this)
223 {
224         this->priv->font_family = gl_font_combo_menu_item_get_family (item);
225
226         g_signal_emit (this, signals[FONT_CHANGED], 0);
227
228         gtk_widget_hide (GTK_WIDGET (this));
229 }
230
231
232 /*****************************************************************************/
233 /* Get font family name.                                                     */
234 /*****************************************************************************/
235 gchar *
236 gl_font_combo_menu_get_family (glFontComboMenu *this)
237 {
238         return g_strdup (this->priv->font_family);
239 }
240
241
242 /*****************************************************************************/
243 /* Create a new font sub menu from font list.                                */
244 /*****************************************************************************/
245 static GtkWidget *
246 new_font_sub_menu (glFontComboMenu *this,
247                    const GList     *list)
248 {
249         GtkWidget   *menu;
250         GtkWidget   *menu_item;
251         GList       *p;
252
253         menu = gtk_menu_new ();
254
255         for ( p = (GList *)list; p != NULL; p = p->next )
256         {
257                 menu_item = gl_font_combo_menu_item_new (p->data);
258                 gtk_widget_show_all (menu_item);
259                 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
260                 g_signal_connect (menu_item, "activate",
261                                   G_CALLBACK (menu_item_activate_cb), this);
262         }
263
264         gtk_widget_show (menu);
265         return menu;
266 }
267
268
269 /*****************************************************************************/
270 /* Font history changed callback.                                            */
271 /*****************************************************************************/
272 static void
273 font_history_changed_cb (glFontComboMenu     *this)
274 {
275         GList *list;
276
277         /*
278          * Remove old sub menu
279          */
280         gtk_menu_item_set_submenu (GTK_MENU_ITEM (this->priv->recent_menu_item),
281                                    NULL);
282
283         /*
284          * Build new sub menu
285          */
286         list = gl_font_history_model_get_family_list (gl_font_history);
287         this->priv->recent_sub_menu = new_font_sub_menu (this, list);
288
289         /*
290          * Attach to top-level menu item
291          */
292         gtk_menu_item_set_submenu (GTK_MENU_ITEM (this->priv->recent_menu_item),
293                                    this->priv->recent_sub_menu);
294         gtk_widget_set_sensitive (this->priv->recent_menu_item, list != NULL);
295
296         gl_font_history_model_free_family_list (list);
297 }
298
299
300
301
302 /*
303  * Local Variables:       -- emacs
304  * mode: C                -- emacs
305  * c-basic-offset: 8      -- emacs
306  * tab-width: 8           -- emacs
307  * indent-tabs-mode: nil  -- emacs
308  * End:                   -- emacs
309  */