3 * Copyright (C) 2009 Jim Evins <evins@snaught.com>.
5 * This file is part of gLabels.
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.
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.
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/>.
23 #include "font-combo.h"
25 #include <glib/gi18n.h>
28 #include "font-combo-menu.h"
29 #include "font-util.h"
34 /*========================================================*/
36 /*========================================================*/
38 /** GL_FONT_COMBO Private fields */
39 struct _glFontComboPrivate {
54 /*========================================================*/
55 /* Private globals. */
56 /*========================================================*/
58 static guint signals[LAST_SIGNAL] = {0};
61 /*========================================================*/
62 /* Private function prototypes. */
63 /*========================================================*/
65 static void gl_font_combo_finalize (GObject *object);
68 button_press_event_cb (GtkWidget *widget,
69 GdkEventButton *event,
73 menu_font_changed_cb (glFontComboMenu *menu,
77 menu_selection_done_cb (GtkMenuShell *object,
81 /*****************************************************************************/
82 /* Object infrastructure. */
83 /*****************************************************************************/
84 G_DEFINE_TYPE (glFontCombo, gl_font_combo, GTK_TYPE_TOGGLE_BUTTON)
87 /*****************************************************************************/
88 /* Class Init Function. */
89 /*****************************************************************************/
91 gl_font_combo_class_init (glFontComboClass *class)
93 GObjectClass *gobject_class = (GObjectClass *) class;
95 gl_font_combo_parent_class = g_type_class_peek_parent (class);
97 gobject_class->finalize = gl_font_combo_finalize;
100 g_signal_new ("changed",
101 G_OBJECT_CLASS_TYPE (gobject_class),
103 G_STRUCT_OFFSET (glFontComboClass, changed),
105 gl_marshal_VOID__VOID,
110 /*****************************************************************************/
111 /* Object Instance Init Function. */
112 /*****************************************************************************/
114 gl_font_combo_init (glFontCombo *this)
119 this->priv = g_new0 (glFontComboPrivate, 1);
121 hbox = gtk_hbox_new (FALSE, 3);
122 gtk_container_add (GTK_CONTAINER (this), hbox);
124 this->priv->label = gtk_label_new ("");
125 gtk_misc_set_alignment (GTK_MISC (this->priv->label), 0.0, 0.5);
126 gtk_widget_set_size_request (this->priv->label, 180, -1);
127 gtk_box_pack_start (GTK_BOX (hbox), this->priv->label, TRUE, TRUE, 0);
129 arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_IN);
130 gtk_box_pack_end (GTK_BOX (hbox), arrow, FALSE, FALSE, 0);
132 g_signal_connect (this, "button_press_event",
133 G_CALLBACK(button_press_event_cb), this);
137 /*****************************************************************************/
138 /* Finalize Method. */
139 /*****************************************************************************/
141 gl_font_combo_finalize (GObject *object)
145 g_return_if_fail (object && IS_GL_FONT_COMBO (object));
146 this = GL_FONT_COMBO (object);
148 g_free (this->priv->font_family);
149 g_object_ref_sink (this->priv->menu);
152 G_OBJECT_CLASS (gl_font_combo_parent_class)->finalize (object);
156 /*****************************************************************************/
157 /** New Object Generator. */
158 /*****************************************************************************/
160 gl_font_combo_new (const gchar *font_family)
164 this = g_object_new (TYPE_GL_FONT_COMBO, NULL);
166 this->priv->font_family = gl_font_util_validate_family (font_family);
168 gtk_label_set_text (GTK_LABEL (this->priv->label), this->priv->font_family);
170 this->priv->menu = gl_font_combo_menu_new ();
172 gtk_widget_show_all (this->priv->menu);
174 g_signal_connect (this->priv->menu, "font_changed",
175 G_CALLBACK (menu_font_changed_cb), this);
176 g_signal_connect (this->priv->menu, "selection_done",
177 G_CALLBACK (menu_selection_done_cb), this);
179 return GTK_WIDGET (this);
183 /*****************************************************************************/
184 /** Set relief style. */
185 /*****************************************************************************/
187 gl_font_combo_set_relief( glFontCombo *this,
188 GtkReliefStyle relief )
190 gtk_button_set_relief (GTK_BUTTON (this), relief);
194 /*****************************************************************************/
195 /* Set font family. */
196 /*****************************************************************************/
198 gl_font_combo_set_family (glFontCombo *this,
199 const gchar *font_family)
202 this->priv->font_family = gl_font_util_validate_family (font_family);
204 gtk_label_set_text (GTK_LABEL (this->priv->label), this->priv->font_family);
208 /*****************************************************************************/
209 /* Get font family. */
210 /*****************************************************************************/
212 gl_font_combo_get_family (glFontCombo *this)
214 return g_strdup (this->priv->font_family);
218 /*****************************************************************************/
219 /* Menu positioning function. */
220 /*****************************************************************************/
222 menu_position_function (GtkMenu *menu,
229 gint w_screen, h_screen;
231 gint x_window, y_window;
232 GtkAllocation allocation;
233 gint x_this, y_this, h_this;
234 GtkRequisition menu_requisition;
240 screen = gtk_widget_get_screen (GTK_WIDGET (this));
241 w_screen = gdk_screen_get_width (screen);
242 h_screen = gdk_screen_get_height (screen);
245 * Absolute position of "this" window on screen.
247 window = gtk_widget_get_window (GTK_WIDGET (this));
248 gdk_window_get_origin (window, &x_window, &y_window);
251 * Position and size of "this" inside window
253 gtk_widget_get_allocation (GTK_WIDGET (this), &allocation);
254 x_this = allocation.x;
255 y_this = allocation.y;
256 h_this = allocation.height;
261 gtk_widget_size_request (this->priv->menu, &menu_requisition);
262 h_menu = menu_requisition.height;
263 w_menu = menu_requisition.width;
266 * Default position anchored to lower left corner of "this".
268 *x = x_window + x_this;
269 *y = y_window + y_this + h_this;
272 * Adjust vertical position if menu if extends past bottom of screen.
274 if ( (*y + h_menu) > h_screen )
276 *y = y_window + y_this - h_menu;
280 *y = h_screen - h_menu;
285 * Adjust horizontal position if menu if extends past edge of screen.
287 if ( (*x + w_menu) > w_screen )
289 *x = w_screen - w_menu;
297 /*****************************************************************************/
298 /* Button "button_press_event" callback. */
299 /*****************************************************************************/
301 button_press_event_cb (GtkWidget *widget,
302 GdkEventButton *event,
305 switch (event->button)
309 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (this), TRUE);
311 gtk_menu_popup (GTK_MENU (this->priv->menu),
313 (GtkMenuPositionFunc)menu_position_function, this,
314 event->button, event->time);
326 /*****************************************************************************/
327 /* Menu "font changed" callback. */
328 /*****************************************************************************/
330 menu_font_changed_cb (glFontComboMenu *menu,
333 this->priv->font_family = gl_font_combo_menu_get_family (menu);
335 gtk_label_set_text (GTK_LABEL (this->priv->label), this->priv->font_family);
337 g_signal_emit (this, signals[CHANGED], 0);
341 /*****************************************************************************/
342 /* Menu "selection done" callback. */
343 /*****************************************************************************/
345 menu_selection_done_cb (GtkMenuShell *object,
348 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (this), FALSE);
354 * Local Variables: -- emacs
356 * c-basic-offset: 8 -- emacs
357 * tab-width: 8 -- emacs
358 * indent-tabs-mode: nil -- emacs