1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
3
* Copyright (C) 2009-2011 Red Hat, Inc.
5
* This library is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU Lesser General Public
7
* License as published by the Free Software Foundation; either
8
* version 2 of the License, or (at your option) any later version.
10
* This library is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
* Lesser General Public License for more details.
15
* You should have received a copy of the GNU Lesser General
16
* Public License along with this library; if not, write to the
17
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18
* Boston, MA 02111-1307, USA.
20
* Based on panels/user-accounts/um-editable-entry.c from
21
* gnome-control-center by Matthias Clasen <mclasen@redhat.com>.
22
* Relicensed to LGPLv2 after obtaining permission.
25
#include <gdk/gdkkeysyms.h>
26
#include "goaeditablelabel.h"
28
#define EMPTY_TEXT "\xe2\x80\x94"
30
struct _GoaEditableLabelPrivate {
31
GtkNotebook *notebook;
44
#define GOA_EDITABLE_LABEL_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GOA_TYPE_EDITABLE_LABEL, GoaEditableLabelPrivate))
61
static guint signals [LAST_SIGNAL] = { 0, };
63
G_DEFINE_TYPE (GoaEditableLabel, goa_editable_label, GTK_TYPE_ALIGNMENT);
66
goa_editable_label_set_text (GoaEditableLabel *e,
69
GoaEditableLabelPrivate *priv;
71
const gchar *label_text;
76
tmp = g_strdup (text);
80
gtk_entry_set_text (priv->entry, tmp);
83
if (label_text == NULL || label_text[0] == '\0')
84
label_text = EMPTY_TEXT;
86
gtk_label_set_text (priv->label, label_text);
87
label = gtk_bin_get_child (GTK_BIN (priv->button));
88
gtk_label_set_text (GTK_LABEL (label), label_text);
90
g_object_notify (G_OBJECT (e), "text");
94
goa_editable_label_get_text (GoaEditableLabel *e)
100
goa_editable_label_set_editable (GoaEditableLabel *e,
103
GoaEditableLabelPrivate *priv;
107
if (priv->editable != editable) {
108
priv->editable = editable;
110
gtk_notebook_set_current_page (priv->notebook, editable ? 1 : 0);
112
g_object_notify (G_OBJECT (e), "editable");
117
goa_editable_label_get_editable (GoaEditableLabel *e)
119
return e->priv->editable;
123
update_entry_font (GtkWidget *widget,
126
GoaEditableLabelPrivate *priv = e->priv;
127
PangoFontDescription *desc;
128
GtkStyleContext *style;
131
if (!priv->weight_set && !priv->scale_set)
134
g_signal_handlers_block_by_func (widget, update_entry_font, e);
136
gtk_widget_override_font (widget, NULL);
138
style = gtk_widget_get_style_context (widget);
139
desc = pango_font_description_copy
140
(gtk_style_context_get_font (style, gtk_widget_get_state_flags (widget)));
142
if (priv->weight_set)
143
pango_font_description_set_weight (desc, priv->weight);
144
if (priv->scale_set) {
145
size = pango_font_description_get_size (desc);
146
pango_font_description_set_size (desc, priv->scale * size);
148
gtk_widget_override_font (widget, desc);
150
pango_font_description_free (desc);
152
g_signal_handlers_unblock_by_func (widget, update_entry_font, e);
156
update_fonts (GoaEditableLabel *e)
158
PangoAttrList *attrs;
159
PangoAttribute *attr;
162
GoaEditableLabelPrivate *priv = e->priv;
164
attrs = pango_attr_list_new ();
165
if (priv->scale_set) {
166
attr = pango_attr_scale_new (priv->scale);
167
pango_attr_list_insert (attrs, attr);
169
if (priv->weight_set) {
170
attr = pango_attr_weight_new (priv->weight);
171
pango_attr_list_insert (attrs, attr);
174
gtk_label_set_attributes (priv->label, attrs);
176
label = gtk_bin_get_child (GTK_BIN (priv->button));
177
gtk_label_set_attributes (GTK_LABEL (label), attrs);
179
pango_attr_list_unref (attrs);
181
update_entry_font ((GtkWidget *)priv->entry, e);
185
goa_editable_label_set_weight (GoaEditableLabel *e,
188
GoaEditableLabelPrivate *priv = e->priv;
190
if (priv->weight == weight && priv->weight_set)
193
priv->weight = weight;
194
priv->weight_set = TRUE;
198
g_object_notify (G_OBJECT (e), "weight");
199
g_object_notify (G_OBJECT (e), "weight-set");
203
goa_editable_label_get_weight (GoaEditableLabel *e)
205
return e->priv->weight;
209
goa_editable_label_set_scale (GoaEditableLabel *e,
212
GoaEditableLabelPrivate *priv = e->priv;
214
if (priv->scale == scale && priv->scale_set)
218
priv->scale_set = TRUE;
222
g_object_notify (G_OBJECT (e), "scale");
223
g_object_notify (G_OBJECT (e), "scale-set");
227
goa_editable_label_get_scale (GoaEditableLabel *e)
229
return e->priv->scale;
233
goa_editable_label_set_property (GObject *object,
238
GoaEditableLabel *e = GOA_EDITABLE_LABEL (object);
242
goa_editable_label_set_text (e, g_value_get_string (value));
245
goa_editable_label_set_editable (e, g_value_get_boolean (value));
248
goa_editable_label_set_weight (e, g_value_get_int (value));
250
case PROP_WEIGHT_SET:
251
e->priv->weight_set = g_value_get_boolean (value);
254
goa_editable_label_set_scale (e, g_value_get_double (value));
257
e->priv->scale_set = g_value_get_boolean (value);
260
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
266
goa_editable_label_get_property (GObject *object,
271
GoaEditableLabel *e = GOA_EDITABLE_LABEL (object);
275
g_value_set_string (value,
276
goa_editable_label_get_text (e));
279
g_value_set_boolean (value,
280
goa_editable_label_get_editable (e));
283
g_value_set_int (value,
284
goa_editable_label_get_weight (e));
286
case PROP_WEIGHT_SET:
287
g_value_set_boolean (value, e->priv->weight_set);
290
g_value_set_double (value,
291
goa_editable_label_get_scale (e));
294
g_value_set_boolean (value, e->priv->scale_set);
297
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
303
goa_editable_label_finalize (GObject *object)
305
GoaEditableLabel *e = (GoaEditableLabel*)object;
307
g_free (e->priv->text);
309
G_OBJECT_CLASS (goa_editable_label_parent_class)->finalize (object);
313
goa_editable_label_class_init (GoaEditableLabelClass *class)
315
GObjectClass *object_class;
317
object_class = G_OBJECT_CLASS (class);
319
object_class->set_property = goa_editable_label_set_property;
320
object_class->get_property = goa_editable_label_get_property;
321
object_class->finalize = goa_editable_label_finalize;
323
signals[EDITING_DONE] =
324
g_signal_new ("editing-done",
325
G_TYPE_FROM_CLASS (class),
327
G_STRUCT_OFFSET (GoaEditableLabelClass, editing_done),
329
g_cclosure_marshal_VOID__VOID,
332
g_object_class_install_property (object_class, PROP_TEXT,
333
g_param_spec_string ("text",
334
"Text", "The text of the button",
338
g_object_class_install_property (object_class, PROP_EDITABLE,
339
g_param_spec_boolean ("editable",
340
"Editable", "Whether the text can be edited",
344
g_object_class_install_property (object_class, PROP_WEIGHT,
345
g_param_spec_int ("weight",
346
"Font Weight", "The font weight to use",
347
0, G_MAXINT, PANGO_WEIGHT_NORMAL,
350
g_object_class_install_property (object_class, PROP_WEIGHT_SET,
351
g_param_spec_boolean ("weight-set",
352
"Font Weight Set", "Whether a font weight is set",
356
g_object_class_install_property (object_class, PROP_SCALE,
357
g_param_spec_double ("scale",
358
"Font Scale", "The font scale to use",
359
0.0, G_MAXDOUBLE, 1.0,
362
g_object_class_install_property (object_class, PROP_SCALE_SET,
363
g_param_spec_boolean ("scale-set",
364
"Font Scale Set", "Whether a font scale is set",
368
g_type_class_add_private (class, sizeof (GoaEditableLabelPrivate));
372
start_editing (GoaEditableLabel *e)
374
gtk_notebook_set_current_page (e->priv->notebook, 2);
378
stop_editing (GoaEditableLabel *e)
380
goa_editable_label_set_text (e, gtk_entry_get_text (e->priv->entry));
381
gtk_notebook_set_current_page (e->priv->notebook, 1);
382
g_signal_emit (e, signals[EDITING_DONE], 0);
386
cancel_editing (GoaEditableLabel *e)
388
gtk_entry_set_text (e->priv->entry, goa_editable_label_get_text (e));
389
gtk_notebook_set_current_page (e->priv->notebook, 1);
393
button_clicked (GtkWidget *widget,
400
entry_activated (GtkWidget *widget,
407
entry_focus_out (GtkWidget *widget,
408
GdkEventFocus *event,
416
entry_key_press (GtkWidget *widget,
420
if (event->keyval == GDK_KEY_Escape) {
427
update_button_padding (GtkWidget *widget,
428
GtkAllocation *allocation,
431
GoaEditableLabelPrivate *priv = e->priv;
436
gtk_widget_get_allocation (gtk_widget_get_parent (widget), &alloc);
438
offset = allocation->x - alloc.x;
440
gtk_misc_get_padding (GTK_MISC (priv->label), &pad, NULL);
442
gtk_misc_set_padding (GTK_MISC (priv->label), offset, 0);
446
goa_editable_label_init (GoaEditableLabel *e)
448
GoaEditableLabelPrivate *priv;
450
priv = e->priv = GOA_EDITABLE_LABEL_GET_PRIVATE (e);
452
priv->weight = PANGO_WEIGHT_NORMAL;
453
priv->weight_set = FALSE;
455
priv->scale_set = FALSE;
457
priv->notebook = (GtkNotebook*)gtk_notebook_new ();
458
gtk_notebook_set_show_tabs (priv->notebook, FALSE);
459
gtk_notebook_set_show_border (priv->notebook, FALSE);
461
priv->label = (GtkLabel*)gtk_label_new (EMPTY_TEXT);
462
gtk_misc_set_alignment (GTK_MISC (priv->label), 0.0, 0.5);
463
gtk_notebook_append_page (priv->notebook, (GtkWidget*)priv->label, NULL);
465
priv->button = (GtkButton*)gtk_button_new_with_label (EMPTY_TEXT);
466
gtk_widget_set_receives_default ((GtkWidget*)priv->button, TRUE);
467
gtk_button_set_relief (priv->button, GTK_RELIEF_NONE);
468
gtk_button_set_alignment (priv->button, 0.0, 0.5);
469
gtk_notebook_append_page (priv->notebook, (GtkWidget*)priv->button, NULL);
470
g_signal_connect (priv->button, "clicked", G_CALLBACK (button_clicked), e);
472
priv->entry = (GtkEntry*)gtk_entry_new ();
473
gtk_notebook_append_page (priv->notebook, (GtkWidget*)priv->entry, NULL);
475
g_signal_connect (priv->entry, "activate", G_CALLBACK (entry_activated), e);
476
g_signal_connect (priv->entry, "focus-out-event", G_CALLBACK (entry_focus_out), e);
477
g_signal_connect (priv->entry, "key-press-event", G_CALLBACK (entry_key_press), e);
478
g_signal_connect (priv->entry, "style-updated", G_CALLBACK (update_entry_font), e);
479
g_signal_connect (gtk_bin_get_child (GTK_BIN (priv->button)), "size-allocate", G_CALLBACK (update_button_padding), e);
481
gtk_container_add (GTK_CONTAINER (e), (GtkWidget*)priv->notebook);
483
gtk_widget_show ((GtkWidget*)priv->notebook);
484
gtk_widget_show ((GtkWidget*)priv->label);
485
gtk_widget_show ((GtkWidget*)priv->button);
486
gtk_widget_show ((GtkWidget*)priv->entry);
488
gtk_notebook_set_current_page (priv->notebook, 0);
492
goa_editable_label_new (void)
494
return (GtkWidget *) g_object_new (GOA_TYPE_EDITABLE_LABEL, NULL);