diff options
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | ChangeLog.pre-2-0 | 9 | ||||
-rw-r--r-- | ChangeLog.pre-2-10 | 9 | ||||
-rw-r--r-- | ChangeLog.pre-2-2 | 9 | ||||
-rw-r--r-- | ChangeLog.pre-2-4 | 9 | ||||
-rw-r--r-- | ChangeLog.pre-2-6 | 9 | ||||
-rw-r--r-- | ChangeLog.pre-2-8 | 9 | ||||
-rw-r--r-- | gtk/gtkentry.c | 137 | ||||
-rw-r--r-- | gtk/gtkentry.h | 6 | ||||
-rw-r--r-- | gtk/testgtk.c | 19 | ||||
-rw-r--r-- | tests/testgtk.c | 19 |
11 files changed, 226 insertions, 18 deletions
@@ -1,3 +1,12 @@ +2000-11-09 Havoc Pennington <hp@pobox.com> + + * gtk/gtkentry.c (gtk_entry_class_init): Add an "invisible_char" + argument to set the char displayed when visibility == FALSE + (gtk_entry_create_layout): If !entry->visible, replace + all chars with the "invisible char" + + * gtk/testgtk.c: Test the invisible_char deal + Mon Nov 13 02:16:33 2000 Robert Brady <robert@suse.co.uk> * gtk/gtkstyle.c (gtk_style_init): Fall back to "fixed" if we diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index 06a49220fc..382608bd82 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -1,3 +1,12 @@ +2000-11-09 Havoc Pennington <hp@pobox.com> + + * gtk/gtkentry.c (gtk_entry_class_init): Add an "invisible_char" + argument to set the char displayed when visibility == FALSE + (gtk_entry_create_layout): If !entry->visible, replace + all chars with the "invisible char" + + * gtk/testgtk.c: Test the invisible_char deal + Mon Nov 13 02:16:33 2000 Robert Brady <robert@suse.co.uk> * gtk/gtkstyle.c (gtk_style_init): Fall back to "fixed" if we diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 06a49220fc..382608bd82 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,12 @@ +2000-11-09 Havoc Pennington <hp@pobox.com> + + * gtk/gtkentry.c (gtk_entry_class_init): Add an "invisible_char" + argument to set the char displayed when visibility == FALSE + (gtk_entry_create_layout): If !entry->visible, replace + all chars with the "invisible char" + + * gtk/testgtk.c: Test the invisible_char deal + Mon Nov 13 02:16:33 2000 Robert Brady <robert@suse.co.uk> * gtk/gtkstyle.c (gtk_style_init): Fall back to "fixed" if we diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index 06a49220fc..382608bd82 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,3 +1,12 @@ +2000-11-09 Havoc Pennington <hp@pobox.com> + + * gtk/gtkentry.c (gtk_entry_class_init): Add an "invisible_char" + argument to set the char displayed when visibility == FALSE + (gtk_entry_create_layout): If !entry->visible, replace + all chars with the "invisible char" + + * gtk/testgtk.c: Test the invisible_char deal + Mon Nov 13 02:16:33 2000 Robert Brady <robert@suse.co.uk> * gtk/gtkstyle.c (gtk_style_init): Fall back to "fixed" if we diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index 06a49220fc..382608bd82 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,12 @@ +2000-11-09 Havoc Pennington <hp@pobox.com> + + * gtk/gtkentry.c (gtk_entry_class_init): Add an "invisible_char" + argument to set the char displayed when visibility == FALSE + (gtk_entry_create_layout): If !entry->visible, replace + all chars with the "invisible char" + + * gtk/testgtk.c: Test the invisible_char deal + Mon Nov 13 02:16:33 2000 Robert Brady <robert@suse.co.uk> * gtk/gtkstyle.c (gtk_style_init): Fall back to "fixed" if we diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 06a49220fc..382608bd82 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,12 @@ +2000-11-09 Havoc Pennington <hp@pobox.com> + + * gtk/gtkentry.c (gtk_entry_class_init): Add an "invisible_char" + argument to set the char displayed when visibility == FALSE + (gtk_entry_create_layout): If !entry->visible, replace + all chars with the "invisible char" + + * gtk/testgtk.c: Test the invisible_char deal + Mon Nov 13 02:16:33 2000 Robert Brady <robert@suse.co.uk> * gtk/gtkstyle.c (gtk_style_init): Fall back to "fixed" if we diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 06a49220fc..382608bd82 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,12 @@ +2000-11-09 Havoc Pennington <hp@pobox.com> + + * gtk/gtkentry.c (gtk_entry_class_init): Add an "invisible_char" + argument to set the char displayed when visibility == FALSE + (gtk_entry_create_layout): If !entry->visible, replace + all chars with the "invisible char" + + * gtk/testgtk.c: Test the invisible_char deal + Mon Nov 13 02:16:33 2000 Robert Brady <robert@suse.co.uk> * gtk/gtkstyle.c (gtk_style_init): Fall back to "fixed" if we diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c index 9996cdd9bb..2bfc433439 100644 --- a/gtk/gtkentry.c +++ b/gtk/gtkentry.c @@ -70,7 +70,8 @@ enum { ARG_TEXT_POSITION, ARG_EDITABLE, ARG_MAX_LENGTH, - ARG_VISIBILITY + ARG_VISIBILITY, + ARG_INVISIBLE_CHAR }; static guint signals[LAST_SIGNAL] = { 0 }; @@ -285,7 +286,8 @@ gtk_entry_class_init (GtkEntryClass *class) gtk_object_add_arg_type ("GtkEntry::editable", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_EDITABLE); gtk_object_add_arg_type ("GtkEntry::max_length", GTK_TYPE_UINT, GTK_ARG_READWRITE, ARG_MAX_LENGTH); gtk_object_add_arg_type ("GtkEntry::visibility", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_VISIBILITY); - + gtk_object_add_arg_type ("GtkEntry::invisible_char", GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_INVISIBLE_CHAR); + signals[INSERT_TEXT] = gtk_signal_new ("insert_text", GTK_RUN_LAST, @@ -582,6 +584,9 @@ gtk_entry_set_arg (GtkObject *object, case ARG_VISIBILITY: gtk_entry_set_visibility (entry, GTK_VALUE_BOOL (*arg)); break; + case ARG_INVISIBLE_CHAR: + gtk_entry_set_invisible_char (entry, GTK_VALUE_INT (*arg)); + break; default: break; } @@ -610,6 +615,9 @@ gtk_entry_get_arg (GtkObject *object, case ARG_VISIBILITY: GTK_VALUE_BOOL (*arg) = entry->visible; break; + case ARG_INVISIBLE_CHAR: + GTK_VALUE_INT (*arg) = entry->invisible_char; + break; default: arg->type = GTK_TYPE_INVALID; break; @@ -627,7 +635,8 @@ gtk_entry_init (GtkEntry *entry) entry->editable = TRUE; entry->visible = TRUE; - + entry->invisible_char = '*'; + /* This object is completely private. No external entity can gain a reference * to it; so we create it here and destroy it in finalize(). */ @@ -1571,7 +1580,7 @@ gtk_entry_preedit_changed_cb (GtkIMContext *context, &cursor_pos); entry->preedit_length = strlen (preedit_string); cursor_pos = CLAMP (cursor_pos, 0, g_utf8_strlen (preedit_string, -1)); - entry->preedit_cursor = g_utf8_offset_to_pointer (preedit_string, cursor_pos) - preedit_string; + entry->preedit_cursor = cursor_pos; g_free (preedit_string); gtk_entry_recompute (entry); @@ -1615,6 +1624,25 @@ gtk_entry_recompute (GtkEntry *entry) } } +static void +append_char (GString *str, + gunichar ch, + gint count) +{ + gint i; + gint char_len; + gchar buf[7]; + + char_len = g_unichar_to_utf8 (ch, buf); + + i = 0; + while (i < count) + { + g_string_append_len (str, buf, char_len); + ++i; + } +} + static PangoLayout * gtk_entry_create_layout (GtkEntry *entry, gboolean include_preedit) @@ -1639,19 +1667,69 @@ gtk_entry_create_layout (GtkEntry *entry, gint cursor_index = g_utf8_offset_to_pointer (entry->text, entry->current_pos) - entry->text; - g_string_prepend_len (tmp_string, entry->text, entry->n_bytes); - g_string_insert (tmp_string, cursor_index, preedit_string); + if (entry->visible) + { + g_string_prepend_len (tmp_string, entry->text, entry->n_bytes); + g_string_insert (tmp_string, cursor_index, preedit_string); + } + else + { + gint ch_len; + gint preedit_len_chars; + gunichar invisible_char; + + ch_len = g_utf8_strlen (entry->text, entry->n_bytes); + preedit_len_chars = g_utf8_strlen (preedit_string, -1); + ch_len += preedit_len_chars; + + if (entry->invisible_char != 0) + invisible_char = entry->invisible_char; + else + invisible_char = ' '; /* just pick a char */ + + append_char (tmp_string, invisible_char, ch_len); + + /* Fix cursor index to point to invisible char corresponding + * to the preedit, fix preedit_length to be the length of + * the invisible chars representing the preedit + */ + cursor_index = + g_utf8_offset_to_pointer (tmp_string->str, entry->current_pos) - + tmp_string->str; + preedit_length = + preedit_len_chars * + g_unichar_to_utf8 (invisible_char, NULL); + } + pango_layout_set_text (layout, tmp_string->str, tmp_string->len); pango_attr_list_splice (tmp_attrs, preedit_attrs, - cursor_index, entry->preedit_length); + cursor_index, preedit_length); g_string_free (tmp_string, TRUE); - } else - pango_layout_set_text (layout, entry->text, entry->n_bytes); - + { + if (entry->visible) + { + pango_layout_set_text (layout, entry->text, entry->n_bytes); + } + else + { + GString *str = g_string_new (NULL); + gunichar invisible_char; + + if (entry->invisible_char != 0) + invisible_char = entry->invisible_char; + else + invisible_char = ' '; /* just pick a char */ + + append_char (str, invisible_char, entry->text_length); + pango_layout_set_text (layout, str->str, str->len); + g_string_free (str, TRUE); + } + } + pango_layout_set_attributes (layout, tmp_attrs); if (preedit_string) @@ -1691,6 +1769,9 @@ gtk_entry_draw_text (GtkEntry *entry) g_return_if_fail (entry != NULL); g_return_if_fail (GTK_IS_ENTRY (entry)); + if (!entry->visible && entry->invisible_char == 0) + return; + if (GTK_WIDGET_DRAWABLE (entry)) { PangoLayout *layout = gtk_entry_get_layout (entry, TRUE); @@ -1775,6 +1856,9 @@ gtk_entry_draw_cursor (GtkEntry *entry) g_return_if_fail (entry != NULL); g_return_if_fail (GTK_IS_ENTRY (entry)); + if (!entry->visible && entry->invisible_char == 0) + return; + if (GTK_WIDGET_DRAWABLE (entry)) { GtkWidget *widget = GTK_WIDGET (entry); @@ -1870,11 +1954,17 @@ gtk_entry_get_cursor_locations (GtkEntry *entry, gint *weak_x) { PangoLayout *layout = gtk_entry_get_layout (entry, TRUE); - gint index = g_utf8_offset_to_pointer (entry->text, entry->current_pos) - entry->text; - + const gchar *text; PangoRectangle strong_pos, weak_pos; + gint index; + + text = pango_layout_get_text (layout); - index += entry->preedit_cursor; + index = + g_utf8_offset_to_pointer (text, + entry->current_pos + + entry->preedit_cursor) - text; + pango_layout_get_cursor_pos (layout, index, &strong_pos, &weak_pos); g_object_unref (G_OBJECT (layout)); @@ -1978,8 +2068,11 @@ gtk_entry_move_visually (GtkEntry *entry, { gint index; PangoLayout *layout = gtk_entry_get_layout (entry, FALSE); + const gchar *text; - index = g_utf8_offset_to_pointer (entry->text, start) - entry->text; + text = pango_layout_get_text (layout); + + index = g_utf8_offset_to_pointer (text, start) - text; while (count != 0) { @@ -2007,7 +2100,7 @@ gtk_entry_move_visually (GtkEntry *entry, g_object_unref (G_OBJECT (layout)); - return g_utf8_pointer_to_offset (entry->text, entry->text + index); + return g_utf8_pointer_to_offset (text, text + index); } static gint @@ -2324,6 +2417,20 @@ gtk_entry_set_visibility (GtkEntry *entry, } void +gtk_entry_set_invisible_char (GtkEntry *entry, + gunichar ch) +{ + g_return_if_fail (GTK_IS_ENTRY (entry)); + + if (ch == entry->invisible_char) + return; + + entry->invisible_char = ch; + + gtk_entry_recompute (entry); +} + +void gtk_entry_set_editable(GtkEntry *entry, gboolean editable) { diff --git a/gtk/gtkentry.h b/gtk/gtkentry.h index 33f26baaff..6099ac13bc 100644 --- a/gtk/gtkentry.h +++ b/gtk/gtkentry.h @@ -86,7 +86,9 @@ struct _GtkEntry guint16 n_bytes; /* length in use, in bytes */ guint16 preedit_length; /* length of preedit string, in bytes */ - guint16 preedit_cursor; /* offset of cursor within preedit string, in bytes */ + guint16 preedit_cursor; /* offset of cursor within preedit string, in chars */ + + gunichar invisible_char; }; struct _GtkEntryClass @@ -126,6 +128,8 @@ GtkType gtk_entry_get_type (void) G_GNUC_CONST; GtkWidget* gtk_entry_new (void); void gtk_entry_set_visibility (GtkEntry *entry, gboolean visible); +void gtk_entry_set_invisible_char (GtkEntry *entry, + gunichar ch); void gtk_entry_set_editable (GtkEntry *entry, gboolean editable); /* text is truncated if needed */ diff --git a/gtk/testgtk.c b/gtk/testgtk.c index cfcbaf1300..aefa384ee5 100644 --- a/gtk/testgtk.c +++ b/gtk/testgtk.c @@ -3282,7 +3282,17 @@ entry_toggle_visibility (GtkWidget *checkbutton, GtkWidget *entry) { gtk_entry_set_visibility(GTK_ENTRY(entry), - GTK_TOGGLE_BUTTON(checkbutton)->active); + GTK_TOGGLE_BUTTON(checkbutton)->active); +} + +static void +entry_toggle_invisible_char (GtkWidget *checkbutton, + GtkWidget *entry) +{ + if (GTK_TOGGLE_BUTTON (checkbutton)->active) + gtk_entry_set_invisible_char (GTK_ENTRY (entry), 0); + else + gtk_entry_set_invisible_char (GTK_ENTRY (entry), '*'); } static void @@ -3293,6 +3303,7 @@ create_entry (void) GtkWidget *box2; GtkWidget *editable_check; GtkWidget *sensitive_check; + GtkWidget *invisible_char_check; GtkWidget *entry, *cb; GtkWidget *button; GtkWidget *separator; @@ -3366,6 +3377,12 @@ create_entry (void) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(sensitive_check), TRUE); gtk_widget_show (sensitive_check); + invisible_char_check = gtk_check_button_new_with_label("invisible_char = 0"); + gtk_box_pack_start (GTK_BOX (box2), invisible_char_check, FALSE, TRUE, 0); + gtk_signal_connect (GTK_OBJECT(invisible_char_check), "toggled", + GTK_SIGNAL_FUNC(entry_toggle_invisible_char), entry); + gtk_widget_show (invisible_char_check); + separator = gtk_hseparator_new (); gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0); gtk_widget_show (separator); diff --git a/tests/testgtk.c b/tests/testgtk.c index cfcbaf1300..aefa384ee5 100644 --- a/tests/testgtk.c +++ b/tests/testgtk.c @@ -3282,7 +3282,17 @@ entry_toggle_visibility (GtkWidget *checkbutton, GtkWidget *entry) { gtk_entry_set_visibility(GTK_ENTRY(entry), - GTK_TOGGLE_BUTTON(checkbutton)->active); + GTK_TOGGLE_BUTTON(checkbutton)->active); +} + +static void +entry_toggle_invisible_char (GtkWidget *checkbutton, + GtkWidget *entry) +{ + if (GTK_TOGGLE_BUTTON (checkbutton)->active) + gtk_entry_set_invisible_char (GTK_ENTRY (entry), 0); + else + gtk_entry_set_invisible_char (GTK_ENTRY (entry), '*'); } static void @@ -3293,6 +3303,7 @@ create_entry (void) GtkWidget *box2; GtkWidget *editable_check; GtkWidget *sensitive_check; + GtkWidget *invisible_char_check; GtkWidget *entry, *cb; GtkWidget *button; GtkWidget *separator; @@ -3366,6 +3377,12 @@ create_entry (void) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(sensitive_check), TRUE); gtk_widget_show (sensitive_check); + invisible_char_check = gtk_check_button_new_with_label("invisible_char = 0"); + gtk_box_pack_start (GTK_BOX (box2), invisible_char_check, FALSE, TRUE, 0); + gtk_signal_connect (GTK_OBJECT(invisible_char_check), "toggled", + GTK_SIGNAL_FUNC(entry_toggle_invisible_char), entry); + gtk_widget_show (invisible_char_check); + separator = gtk_hseparator_new (); gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0); gtk_widget_show (separator); |