diff options
author | Carlos Garnacho <carlos@imendio.com> | 2008-09-19 13:45:07 +0000 |
---|---|---|
committer | Carlos Garnacho <carlosg@src.gnome.org> | 2008-09-19 13:45:07 +0000 |
commit | ee06ce951b9ede937ca9676dc1b750cf65f3ecbe (patch) | |
tree | e78a281550944be32345c1e5b89ca3ae84d2c6e9 /gtk/gtkentry.c | |
parent | 34b3bb8c5f19d2d6ab68375b5cc9d57483816df3 (diff) | |
download | gtk+-ee06ce951b9ede937ca9676dc1b750cf65f3ecbe.tar.gz |
Bug 83935 – GtkEntry's default invisible char should be U+25CF
2008-09-19 Carlos Garnacho <carlos@imendio.com>
Bug 83935 – GtkEntry's default invisible char should be U+25CF
* gtk/gtkentry.c (find_invisible_char) (gtk_entry_init): Find a
more suitable invisible char than '*' based on the used font.
(gtk_entry_class_init) (gtk_entry_set_property)
(gtk_entry_get_property): Add a "invisible-char-set" property.
(gtk_entry_unset_invisible_char): New function, needed now that the
default invisible char isn't fixed.
* gtk/gtkentry.h:
* gtk/gtk.symbols:
* docs/reference/gtk/gtk-sections.txt: Add the new function.
svn path=/trunk/; revision=21446
Diffstat (limited to 'gtk/gtkentry.c')
-rw-r--r-- | gtk/gtkentry.c | 137 |
1 files changed, 127 insertions, 10 deletions
diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c index 76d17b64ab..7aed86e312 100644 --- a/gtk/gtkentry.c +++ b/gtk/gtkentry.c @@ -87,6 +87,7 @@ struct _GtkEntryPrivate guint blink_time; /* time in msec the cursor has blinked since last user event */ guint interior_focus : 1; guint real_changed : 1; + guint invisible_char_set : 1; guint change_count : 8; gint focus_width; @@ -135,7 +136,8 @@ enum { PROP_TRUNCATE_MULTILINE, PROP_SHADOW_TYPE, PROP_OVERWRITE_MODE, - PROP_TEXT_LENGTH + PROP_TEXT_LENGTH, + PROP_INVISIBLE_CHAR_SET }; static guint signals[LAST_SIGNAL] = { 0 }; @@ -664,6 +666,20 @@ gtk_entry_class_init (GtkEntryClass *class) G_MAXUINT16, 0, GTK_PARAM_READABLE)); + /** + * GtkEntry:invisible-char-set: + * + * Whether the invisible char has been set for the #GtkEntry. + * + * Since: 2.16 + */ + g_object_class_install_property (gobject_class, + PROP_INVISIBLE_CHAR_SET, + g_param_spec_boolean ("invisible-char-set", + P_("Invisible char set"), + P_("Whether the invisible char has been set"), + FALSE, + GTK_PARAM_READWRITE)); signals[POPULATE_POPUP] = g_signal_new (I_("populate-popup"), @@ -1063,6 +1079,13 @@ gtk_entry_set_property (GObject *object, gtk_entry_set_overwrite_mode (entry, g_value_get_boolean (value)); break; + case PROP_INVISIBLE_CHAR_SET: + if (g_value_get_boolean (value)) + priv->invisible_char_set = TRUE; + else + gtk_entry_unset_invisible_char (entry); + break; + case PROP_SCROLL_OFFSET: case PROP_CURSOR_POSITION: default: @@ -1133,13 +1156,57 @@ gtk_entry_get_property (GObject *object, case PROP_TEXT_LENGTH: g_value_set_uint (value, entry->text_length); break; - + case PROP_INVISIBLE_CHAR_SET: + g_value_set_boolean (value, priv->invisible_char_set); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } +static gunichar +find_invisible_char (GtkWidget *widget) +{ + PangoLayout *layout; + PangoAttrList *attr_list; + gint i; + gunichar invisible_chars [] = { + 0x25cf, /* BLACK CIRCLE */ + 0x2022, /* BULLET */ + 0x2731, /* HEAVY ASTERISK */ + 0x273a /* SIXTEEN POINTED ASTERISK */ + }; + + layout = gtk_widget_create_pango_layout (widget, NULL); + + attr_list = pango_attr_list_new (); + pango_attr_list_insert (attr_list, pango_attr_fallback_new (FALSE)); + + pango_layout_set_attributes (layout, attr_list); + pango_attr_list_unref (attr_list); + + for (i = 0; i < G_N_ELEMENTS (invisible_chars); i++) + { + gchar text[7] = { 0, }; + gint len, count; + + len = g_unichar_to_utf8 (invisible_chars[i], text); + pango_layout_set_text (layout, text, len); + + count = pango_layout_get_unknown_glyphs_count (layout); + + if (count == 0) + { + g_object_unref (layout); + return invisible_chars[i]; + } + } + + g_object_unref (layout); + return '*'; +} + static void gtk_entry_init (GtkEntry *entry) { @@ -1153,7 +1220,7 @@ gtk_entry_init (GtkEntry *entry) entry->editable = TRUE; entry->visible = TRUE; - entry->invisible_char = '*'; + entry->invisible_char = find_invisible_char (GTK_WIDGET (entry)); entry->dnd_position = -1; entry->width_chars = -1; entry->is_cell_renderer = FALSE; @@ -2441,7 +2508,10 @@ gtk_entry_style_set (GtkWidget *widget, priv->focus_width = focus_width; priv->interior_focus = interior_focus; - + + if (!priv->invisible_char_set) + entry->invisible_char = find_invisible_char (GTK_WIDGET (entry)); + gtk_entry_recompute (entry); if (previous_style && GTK_WIDGET_REALIZED (widget)) @@ -4548,8 +4618,9 @@ gtk_entry_set_position (GtkEntry *entry, * as the invisible char, and will also appear that way when * the text in the entry widget is copied elsewhere. * - * The default invisible char is the asterisk '*', but it can - * be changed with gtk_entry_set_invisible_char(). + * By default, GTK+ picks the best invisible character available + * in the current font, but it can be changed with + * gtk_entry_set_invisible_char(). */ void gtk_entry_set_visibility (GtkEntry *entry, @@ -4615,17 +4686,27 @@ gtk_entry_get_visibility (GtkEntry *entry) * Sets the character to use in place of the actual text when * gtk_entry_set_visibility() has been called to set text visibility * to %FALSE. i.e. this is the character used in "password mode" to - * show the user how many characters have been typed. The default - * invisible char is an asterisk ('*'). If you set the invisible char - * to 0, then the user will get no feedback at all; there will be - * no text on the screen as they type. + * show the user how many characters have been typed. By default, GTK+ + * picks the best invisible char available in the current font. If you + * set the invisible char to 0, then the user will get no feedback + * at all; there will be no text on the screen as they type. **/ void gtk_entry_set_invisible_char (GtkEntry *entry, gunichar ch) { + GtkEntryPrivate *priv; + g_return_if_fail (GTK_IS_ENTRY (entry)); + priv = GTK_ENTRY_GET_PRIVATE (entry); + + if (!priv->invisible_char_set) + { + priv->invisible_char_set = TRUE; + g_object_notify (G_OBJECT (entry), "invisible-char-set"); + } + if (ch == entry->invisible_char) return; @@ -4653,6 +4734,42 @@ gtk_entry_get_invisible_char (GtkEntry *entry) } /** + * gtk_entry_unset_invisible_char: + * @entry: a #GtkEntry + * + * Unsets the invisible char previously set with + * gtk_entry_set_invisible_char(). So that the + * default invisible char is used again. + * + * Since: 2.16 + **/ +void +gtk_entry_unset_invisible_char (GtkEntry *entry) +{ + GtkEntryPrivate *priv; + gunichar ch; + + g_return_if_fail (GTK_IS_ENTRY (entry)); + + priv = GTK_ENTRY_GET_PRIVATE (entry); + + if (!priv->invisible_char_set) + return; + + priv->invisible_char_set = FALSE; + ch = find_invisible_char (GTK_WIDGET (entry)); + + if (entry->invisible_char != ch) + { + entry->invisible_char = ch; + g_object_notify (G_OBJECT (entry), "invisible-char"); + } + + g_object_notify (G_OBJECT (entry), "invisible-char-set"); + gtk_entry_recompute (entry); +} + +/** * gtk_entry_set_editable: * @entry: a #GtkEntry * @editable: %TRUE if the user is allowed to edit the text |