mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-06 00:30:08 +00:00
gtkentry: Add hinting to GtkEntry
gtk_entry_set_placeholder_text() makes the entry display the given text when it is empty and unfocused. Based on previous patch by Alberto Garcia. https://bugzilla.gnome.org/show_bug.cgi?id=440963
This commit is contained in:
parent
c8350821e9
commit
ef061c4e96
@ -1028,6 +1028,8 @@ gtk_entry_set_width_chars
|
|||||||
gtk_entry_get_invisible_char
|
gtk_entry_get_invisible_char
|
||||||
gtk_entry_set_alignment
|
gtk_entry_set_alignment
|
||||||
gtk_entry_get_alignment
|
gtk_entry_get_alignment
|
||||||
|
gtk_entry_set_placeholder_text
|
||||||
|
gtk_entry_get_placeholder_text
|
||||||
gtk_entry_set_overwrite_mode
|
gtk_entry_set_overwrite_mode
|
||||||
gtk_entry_get_overwrite_mode
|
gtk_entry_get_overwrite_mode
|
||||||
gtk_entry_get_layout
|
gtk_entry_get_layout
|
||||||
|
@ -828,6 +828,7 @@ gtk_entry_get_completion
|
|||||||
gtk_entry_get_current_icon_drag_source
|
gtk_entry_get_current_icon_drag_source
|
||||||
gtk_entry_get_cursor_hadjustment
|
gtk_entry_get_cursor_hadjustment
|
||||||
gtk_entry_get_has_frame
|
gtk_entry_get_has_frame
|
||||||
|
gtk_entry_get_placeholder_text
|
||||||
gtk_entry_get_icon_activatable
|
gtk_entry_get_icon_activatable
|
||||||
gtk_entry_get_icon_area
|
gtk_entry_get_icon_area
|
||||||
gtk_entry_get_icon_at_pos
|
gtk_entry_get_icon_at_pos
|
||||||
@ -866,6 +867,7 @@ gtk_entry_set_buffer
|
|||||||
gtk_entry_set_completion
|
gtk_entry_set_completion
|
||||||
gtk_entry_set_cursor_hadjustment
|
gtk_entry_set_cursor_hadjustment
|
||||||
gtk_entry_set_has_frame
|
gtk_entry_set_has_frame
|
||||||
|
gtk_entry_set_placeholder_text
|
||||||
gtk_entry_set_icon_activatable
|
gtk_entry_set_icon_activatable
|
||||||
gtk_entry_set_icon_drag_source
|
gtk_entry_set_icon_drag_source
|
||||||
gtk_entry_set_icon_from_gicon
|
gtk_entry_set_icon_from_gicon
|
||||||
|
@ -3772,6 +3772,7 @@ gtk_css_provider_get_default (void)
|
|||||||
"@define-color selected_fg_color #fff; \n"
|
"@define-color selected_fg_color #fff; \n"
|
||||||
"@define-color tooltip_bg_color #eee1b3; \n"
|
"@define-color tooltip_bg_color #eee1b3; \n"
|
||||||
"@define-color tooltip_fg_color #000; \n"
|
"@define-color tooltip_fg_color #000; \n"
|
||||||
|
"@define-color placeholder_text_color #808080; \n"
|
||||||
"\n"
|
"\n"
|
||||||
"@define-color info_fg_color rgb (181, 171, 156);\n"
|
"@define-color info_fg_color rgb (181, 171, 156);\n"
|
||||||
"@define-color info_bg_color rgb (252, 252, 189);\n"
|
"@define-color info_bg_color rgb (252, 252, 189);\n"
|
||||||
|
156
gtk/gtkentry.c
156
gtk/gtkentry.c
@ -155,6 +155,8 @@ struct _GtkEntryPrivate
|
|||||||
gdouble progress_pulse_fraction;
|
gdouble progress_pulse_fraction;
|
||||||
gdouble progress_pulse_current;
|
gdouble progress_pulse_current;
|
||||||
|
|
||||||
|
gchar *placeholder_text;
|
||||||
|
|
||||||
gfloat xalign;
|
gfloat xalign;
|
||||||
|
|
||||||
gint ascent; /* font ascent in pango units */
|
gint ascent; /* font ascent in pango units */
|
||||||
@ -306,7 +308,8 @@ enum {
|
|||||||
PROP_TOOLTIP_MARKUP_PRIMARY,
|
PROP_TOOLTIP_MARKUP_PRIMARY,
|
||||||
PROP_TOOLTIP_MARKUP_SECONDARY,
|
PROP_TOOLTIP_MARKUP_SECONDARY,
|
||||||
PROP_IM_MODULE,
|
PROP_IM_MODULE,
|
||||||
PROP_EDITING_CANCELED
|
PROP_EDITING_CANCELED,
|
||||||
|
PROP_PLACEHOLDER_TEXT
|
||||||
};
|
};
|
||||||
|
|
||||||
static guint signals[LAST_SIGNAL] = { 0 };
|
static guint signals[LAST_SIGNAL] = { 0 };
|
||||||
@ -596,7 +599,6 @@ static void begin_change (GtkEntry *entry);
|
|||||||
static void end_change (GtkEntry *entry);
|
static void end_change (GtkEntry *entry);
|
||||||
static void emit_changed (GtkEntry *entry);
|
static void emit_changed (GtkEntry *entry);
|
||||||
|
|
||||||
|
|
||||||
static void buffer_inserted_text (GtkEntryBuffer *buffer,
|
static void buffer_inserted_text (GtkEntryBuffer *buffer,
|
||||||
guint position,
|
guint position,
|
||||||
const gchar *chars,
|
const gchar *chars,
|
||||||
@ -619,7 +621,6 @@ static void buffer_connect_signals (GtkEntry *entry);
|
|||||||
static void buffer_disconnect_signals (GtkEntry *entry);
|
static void buffer_disconnect_signals (GtkEntry *entry);
|
||||||
static GtkEntryBuffer *get_buffer (GtkEntry *entry);
|
static GtkEntryBuffer *get_buffer (GtkEntry *entry);
|
||||||
|
|
||||||
|
|
||||||
G_DEFINE_TYPE_WITH_CODE (GtkEntry, gtk_entry, GTK_TYPE_WIDGET,
|
G_DEFINE_TYPE_WITH_CODE (GtkEntry, gtk_entry, GTK_TYPE_WIDGET,
|
||||||
G_IMPLEMENT_INTERFACE (GTK_TYPE_EDITABLE,
|
G_IMPLEMENT_INTERFACE (GTK_TYPE_EDITABLE,
|
||||||
gtk_entry_editable_init)
|
gtk_entry_editable_init)
|
||||||
@ -983,6 +984,21 @@ gtk_entry_class_init (GtkEntryClass *class)
|
|||||||
GTK_PARAM_READWRITE));
|
GTK_PARAM_READWRITE));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* GtkEntry:placeholder-text:
|
||||||
|
*
|
||||||
|
* The text that will be displayed in the #GtkEntry when it is empty and unfocused.
|
||||||
|
*
|
||||||
|
* Since: 3.2
|
||||||
|
*/
|
||||||
|
g_object_class_install_property (gobject_class,
|
||||||
|
PROP_PLACEHOLDER_TEXT,
|
||||||
|
g_param_spec_string ("placeholder-text",
|
||||||
|
P_("Placeholder text"),
|
||||||
|
P_("Show text in the entry when it's empty and unfocused"),
|
||||||
|
NULL,
|
||||||
|
GTK_PARAM_READWRITE));
|
||||||
|
|
||||||
|
/**
|
||||||
* GtkEntry:primary-icon-pixbuf:
|
* GtkEntry:primary-icon-pixbuf:
|
||||||
*
|
*
|
||||||
* A pixbuf to use as the primary icon for the entry.
|
* A pixbuf to use as the primary icon for the entry.
|
||||||
@ -1967,6 +1983,10 @@ gtk_entry_set_property (GObject *object,
|
|||||||
gtk_entry_set_progress_pulse_step (entry, g_value_get_double (value));
|
gtk_entry_set_progress_pulse_step (entry, g_value_get_double (value));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PROP_PLACEHOLDER_TEXT:
|
||||||
|
gtk_entry_set_placeholder_text (entry, g_value_get_string (value));
|
||||||
|
break;
|
||||||
|
|
||||||
case PROP_PIXBUF_PRIMARY:
|
case PROP_PIXBUF_PRIMARY:
|
||||||
gtk_entry_set_icon_from_pixbuf (entry,
|
gtk_entry_set_icon_from_pixbuf (entry,
|
||||||
GTK_ENTRY_ICON_PRIMARY,
|
GTK_ENTRY_ICON_PRIMARY,
|
||||||
@ -2185,6 +2205,10 @@ gtk_entry_get_property (GObject *object,
|
|||||||
g_value_set_double (value, priv->progress_pulse_fraction);
|
g_value_set_double (value, priv->progress_pulse_fraction);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PROP_PLACEHOLDER_TEXT:
|
||||||
|
g_value_set_string (value, gtk_entry_get_placeholder_text (entry));
|
||||||
|
break;
|
||||||
|
|
||||||
case PROP_PIXBUF_PRIMARY:
|
case PROP_PIXBUF_PRIMARY:
|
||||||
g_value_set_object (value,
|
g_value_set_object (value,
|
||||||
gtk_entry_get_icon_pixbuf (entry,
|
gtk_entry_get_icon_pixbuf (entry,
|
||||||
@ -2581,6 +2605,7 @@ gtk_entry_finalize (GObject *object)
|
|||||||
if (priv->recompute_idle)
|
if (priv->recompute_idle)
|
||||||
g_source_remove (priv->recompute_idle);
|
g_source_remove (priv->recompute_idle);
|
||||||
|
|
||||||
|
g_free (priv->placeholder_text);
|
||||||
g_free (priv->im_module);
|
g_free (priv->im_module);
|
||||||
|
|
||||||
G_OBJECT_CLASS (gtk_entry_parent_class)->finalize (object);
|
G_OBJECT_CLASS (gtk_entry_parent_class)->finalize (object);
|
||||||
@ -2667,7 +2692,6 @@ gtk_entry_get_display_text (GtkEntry *entry,
|
|||||||
|
|
||||||
return g_string_free (str, FALSE);
|
return g_string_free (str, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -4191,8 +4215,16 @@ gtk_entry_focus_in (GtkWidget *widget,
|
|||||||
g_signal_connect (keymap, "direction-changed",
|
g_signal_connect (keymap, "direction-changed",
|
||||||
G_CALLBACK (keymap_direction_changed), entry);
|
G_CALLBACK (keymap_direction_changed), entry);
|
||||||
|
|
||||||
gtk_entry_reset_blink_time (entry);
|
if (gtk_entry_buffer_get_bytes (get_buffer (entry)) == 0 &&
|
||||||
gtk_entry_check_cursor_blink (entry);
|
priv->placeholder_text != NULL)
|
||||||
|
{
|
||||||
|
gtk_entry_recompute (entry);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gtk_entry_reset_blink_time (entry);
|
||||||
|
gtk_entry_check_cursor_blink (entry);
|
||||||
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@ -4217,8 +4249,16 @@ gtk_entry_focus_out (GtkWidget *widget,
|
|||||||
remove_capslock_feedback (entry);
|
remove_capslock_feedback (entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
gtk_entry_check_cursor_blink (entry);
|
if (gtk_entry_buffer_get_bytes (get_buffer (entry)) == 0 &&
|
||||||
|
priv->placeholder_text != NULL)
|
||||||
|
{
|
||||||
|
gtk_entry_recompute (entry);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gtk_entry_check_cursor_blink (entry);
|
||||||
|
}
|
||||||
|
|
||||||
g_signal_handlers_disconnect_by_func (keymap, keymap_state_changed, entry);
|
g_signal_handlers_disconnect_by_func (keymap, keymap_state_changed, entry);
|
||||||
g_signal_handlers_disconnect_by_func (keymap, keymap_direction_changed, entry);
|
g_signal_handlers_disconnect_by_func (keymap, keymap_direction_changed, entry);
|
||||||
|
|
||||||
@ -5394,6 +5434,35 @@ gtk_entry_recompute (GtkEntry *entry)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_entry_get_placeholder_text_color (GtkEntry *entry,
|
||||||
|
PangoColor *color)
|
||||||
|
{
|
||||||
|
GtkWidget *widget = GTK_WIDGET (entry);
|
||||||
|
GtkStyleContext *context;
|
||||||
|
GdkRGBA fg = { 0.5, 0.5, 0.5 };
|
||||||
|
|
||||||
|
context = gtk_widget_get_style_context (widget);
|
||||||
|
gtk_style_context_lookup_color (context, "placeholder_text_color", &fg);
|
||||||
|
|
||||||
|
color->red = CLAMP (fg.red * 65535. + 0.5, 0, 65535);
|
||||||
|
color->green = CLAMP (fg.green * 65535. + 0.5, 0, 65535);
|
||||||
|
color->blue = CLAMP (fg.blue * 65535. + 0.5, 0, 65535);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline gboolean
|
||||||
|
show_placeholder_text (GtkEntry *entry)
|
||||||
|
{
|
||||||
|
GtkEntryPrivate *priv = entry->priv;
|
||||||
|
|
||||||
|
if (!gtk_widget_has_focus (GTK_WIDGET (entry)) &&
|
||||||
|
gtk_entry_buffer_get_bytes (get_buffer (entry)) == 0 &&
|
||||||
|
priv->placeholder_text != NULL)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static PangoLayout *
|
static PangoLayout *
|
||||||
gtk_entry_create_layout (GtkEntry *entry,
|
gtk_entry_create_layout (GtkEntry *entry,
|
||||||
gboolean include_preedit)
|
gboolean include_preedit)
|
||||||
@ -5402,6 +5471,7 @@ gtk_entry_create_layout (GtkEntry *entry,
|
|||||||
GtkWidget *widget = GTK_WIDGET (entry);
|
GtkWidget *widget = GTK_WIDGET (entry);
|
||||||
PangoLayout *layout = gtk_widget_create_pango_layout (widget, NULL);
|
PangoLayout *layout = gtk_widget_create_pango_layout (widget, NULL);
|
||||||
PangoAttrList *tmp_attrs = pango_attr_list_new ();
|
PangoAttrList *tmp_attrs = pango_attr_list_new ();
|
||||||
|
gboolean placeholder_layout = show_placeholder_text (entry);
|
||||||
|
|
||||||
gchar *preedit_string = NULL;
|
gchar *preedit_string = NULL;
|
||||||
gint preedit_length = 0;
|
gint preedit_length = 0;
|
||||||
@ -5412,15 +5482,26 @@ gtk_entry_create_layout (GtkEntry *entry,
|
|||||||
|
|
||||||
pango_layout_set_single_paragraph_mode (layout, TRUE);
|
pango_layout_set_single_paragraph_mode (layout, TRUE);
|
||||||
|
|
||||||
display = gtk_entry_get_display_text (entry, 0, -1);
|
display = placeholder_layout ? g_strdup (priv->placeholder_text) : gtk_entry_get_display_text (entry, 0, -1);
|
||||||
n_bytes = strlen (display);
|
n_bytes = strlen (display);
|
||||||
|
|
||||||
if (include_preedit)
|
if (!placeholder_layout && include_preedit)
|
||||||
{
|
{
|
||||||
gtk_im_context_get_preedit_string (priv->im_context,
|
gtk_im_context_get_preedit_string (priv->im_context,
|
||||||
&preedit_string, &preedit_attrs, NULL);
|
&preedit_string, &preedit_attrs, NULL);
|
||||||
preedit_length = priv->preedit_length;
|
preedit_length = priv->preedit_length;
|
||||||
}
|
}
|
||||||
|
else if (placeholder_layout)
|
||||||
|
{
|
||||||
|
PangoColor color;
|
||||||
|
PangoAttribute *attr;
|
||||||
|
|
||||||
|
gtk_entry_get_placeholder_text_color (entry, &color);
|
||||||
|
attr = pango_attr_foreground_new (color.red, color.green, color.blue);
|
||||||
|
attr->start_index = 0;
|
||||||
|
attr->end_index = G_MAXINT;
|
||||||
|
pango_attr_list_insert (tmp_attrs, attr);
|
||||||
|
}
|
||||||
|
|
||||||
if (preedit_length)
|
if (preedit_length)
|
||||||
{
|
{
|
||||||
@ -10132,6 +10213,61 @@ gtk_entry_progress_pulse (GtkEntry *entry)
|
|||||||
gtk_widget_queue_draw (GTK_WIDGET (entry));
|
gtk_widget_queue_draw (GTK_WIDGET (entry));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gtk_entry_set_placeholder_text:
|
||||||
|
* @entry: a #GtkEntry
|
||||||
|
* @text: a string to be displayed when @entry is empty an unfocused, or %NULL
|
||||||
|
*
|
||||||
|
* Sets text to be displayed in @entry when
|
||||||
|
* it is empty and unfocused. This can be used to give a visual hint
|
||||||
|
* of the expected contents of the #GtkEntry.
|
||||||
|
*
|
||||||
|
* Since: 3.2
|
||||||
|
**/
|
||||||
|
void
|
||||||
|
gtk_entry_set_placeholder_text (GtkEntry *entry,
|
||||||
|
const gchar *text)
|
||||||
|
{
|
||||||
|
GtkEntryPrivate *priv;
|
||||||
|
|
||||||
|
g_return_if_fail (GTK_IS_ENTRY (entry));
|
||||||
|
|
||||||
|
priv = entry->priv;
|
||||||
|
|
||||||
|
if (g_strcmp0 (priv->placeholder_text, text) == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_free (priv->placeholder_text);
|
||||||
|
priv->placeholder_text = g_strdup (text);
|
||||||
|
|
||||||
|
gtk_entry_recompute (entry);
|
||||||
|
|
||||||
|
g_object_notify (G_OBJECT (entry), "placeholder-text");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gtk_entry_get_placeholder_text:
|
||||||
|
* @entry: a #GtkEntry
|
||||||
|
*
|
||||||
|
* Retrieves the text that will be displayed when @entry is empty and unfocused
|
||||||
|
*
|
||||||
|
* Returns: a pointer to the placeholder text as a string. This string points to internally allocated
|
||||||
|
* storage in the widget and must not be freed, modified or stored.
|
||||||
|
*
|
||||||
|
* Since: 3.2
|
||||||
|
**/
|
||||||
|
G_CONST_RETURN gchar *
|
||||||
|
gtk_entry_get_placeholder_text (GtkEntry *entry)
|
||||||
|
{
|
||||||
|
GtkEntryPrivate *priv;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL);
|
||||||
|
|
||||||
|
priv = entry->priv;
|
||||||
|
|
||||||
|
return priv->placeholder_text;
|
||||||
|
}
|
||||||
|
|
||||||
/* Caps Lock warning for password entries */
|
/* Caps Lock warning for password entries */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -213,6 +213,10 @@ gdouble gtk_entry_get_progress_pulse_step (GtkEntry *entry);
|
|||||||
|
|
||||||
void gtk_entry_progress_pulse (GtkEntry *entry);
|
void gtk_entry_progress_pulse (GtkEntry *entry);
|
||||||
|
|
||||||
|
G_CONST_RETURN gchar* gtk_entry_get_placeholder_text (GtkEntry *entry);
|
||||||
|
|
||||||
|
void gtk_entry_set_placeholder_text (GtkEntry *entry,
|
||||||
|
const gchar *text);
|
||||||
/* Setting and managing icons
|
/* Setting and managing icons
|
||||||
*/
|
*/
|
||||||
void gtk_entry_set_icon_from_pixbuf (GtkEntry *entry,
|
void gtk_entry_set_icon_from_pixbuf (GtkEntry *entry,
|
||||||
|
Loading…
Reference in New Issue
Block a user