mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-11 03:10:09 +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_set_alignment
|
||||
gtk_entry_get_alignment
|
||||
gtk_entry_set_placeholder_text
|
||||
gtk_entry_get_placeholder_text
|
||||
gtk_entry_set_overwrite_mode
|
||||
gtk_entry_get_overwrite_mode
|
||||
gtk_entry_get_layout
|
||||
|
@ -828,6 +828,7 @@ gtk_entry_get_completion
|
||||
gtk_entry_get_current_icon_drag_source
|
||||
gtk_entry_get_cursor_hadjustment
|
||||
gtk_entry_get_has_frame
|
||||
gtk_entry_get_placeholder_text
|
||||
gtk_entry_get_icon_activatable
|
||||
gtk_entry_get_icon_area
|
||||
gtk_entry_get_icon_at_pos
|
||||
@ -866,6 +867,7 @@ gtk_entry_set_buffer
|
||||
gtk_entry_set_completion
|
||||
gtk_entry_set_cursor_hadjustment
|
||||
gtk_entry_set_has_frame
|
||||
gtk_entry_set_placeholder_text
|
||||
gtk_entry_set_icon_activatable
|
||||
gtk_entry_set_icon_drag_source
|
||||
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 tooltip_bg_color #eee1b3; \n"
|
||||
"@define-color tooltip_fg_color #000; \n"
|
||||
"@define-color placeholder_text_color #808080; \n"
|
||||
"\n"
|
||||
"@define-color info_fg_color rgb (181, 171, 156);\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_current;
|
||||
|
||||
gchar *placeholder_text;
|
||||
|
||||
gfloat xalign;
|
||||
|
||||
gint ascent; /* font ascent in pango units */
|
||||
@ -306,7 +308,8 @@ enum {
|
||||
PROP_TOOLTIP_MARKUP_PRIMARY,
|
||||
PROP_TOOLTIP_MARKUP_SECONDARY,
|
||||
PROP_IM_MODULE,
|
||||
PROP_EDITING_CANCELED
|
||||
PROP_EDITING_CANCELED,
|
||||
PROP_PLACEHOLDER_TEXT
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
@ -596,7 +599,6 @@ static void begin_change (GtkEntry *entry);
|
||||
static void end_change (GtkEntry *entry);
|
||||
static void emit_changed (GtkEntry *entry);
|
||||
|
||||
|
||||
static void buffer_inserted_text (GtkEntryBuffer *buffer,
|
||||
guint position,
|
||||
const gchar *chars,
|
||||
@ -619,7 +621,6 @@ static void buffer_connect_signals (GtkEntry *entry);
|
||||
static void buffer_disconnect_signals (GtkEntry *entry);
|
||||
static GtkEntryBuffer *get_buffer (GtkEntry *entry);
|
||||
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GtkEntry, gtk_entry, GTK_TYPE_WIDGET,
|
||||
G_IMPLEMENT_INTERFACE (GTK_TYPE_EDITABLE,
|
||||
gtk_entry_editable_init)
|
||||
@ -983,6 +984,21 @@ gtk_entry_class_init (GtkEntryClass *class)
|
||||
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:
|
||||
*
|
||||
* 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));
|
||||
break;
|
||||
|
||||
case PROP_PLACEHOLDER_TEXT:
|
||||
gtk_entry_set_placeholder_text (entry, g_value_get_string (value));
|
||||
break;
|
||||
|
||||
case PROP_PIXBUF_PRIMARY:
|
||||
gtk_entry_set_icon_from_pixbuf (entry,
|
||||
GTK_ENTRY_ICON_PRIMARY,
|
||||
@ -2185,6 +2205,10 @@ gtk_entry_get_property (GObject *object,
|
||||
g_value_set_double (value, priv->progress_pulse_fraction);
|
||||
break;
|
||||
|
||||
case PROP_PLACEHOLDER_TEXT:
|
||||
g_value_set_string (value, gtk_entry_get_placeholder_text (entry));
|
||||
break;
|
||||
|
||||
case PROP_PIXBUF_PRIMARY:
|
||||
g_value_set_object (value,
|
||||
gtk_entry_get_icon_pixbuf (entry,
|
||||
@ -2581,6 +2605,7 @@ gtk_entry_finalize (GObject *object)
|
||||
if (priv->recompute_idle)
|
||||
g_source_remove (priv->recompute_idle);
|
||||
|
||||
g_free (priv->placeholder_text);
|
||||
g_free (priv->im_module);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
@ -4191,8 +4215,16 @@ gtk_entry_focus_in (GtkWidget *widget,
|
||||
g_signal_connect (keymap, "direction-changed",
|
||||
G_CALLBACK (keymap_direction_changed), entry);
|
||||
|
||||
gtk_entry_reset_blink_time (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_reset_blink_time (entry);
|
||||
gtk_entry_check_cursor_blink (entry);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
@ -4217,8 +4249,16 @@ gtk_entry_focus_out (GtkWidget *widget,
|
||||
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_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 *
|
||||
gtk_entry_create_layout (GtkEntry *entry,
|
||||
gboolean include_preedit)
|
||||
@ -5402,6 +5471,7 @@ gtk_entry_create_layout (GtkEntry *entry,
|
||||
GtkWidget *widget = GTK_WIDGET (entry);
|
||||
PangoLayout *layout = gtk_widget_create_pango_layout (widget, NULL);
|
||||
PangoAttrList *tmp_attrs = pango_attr_list_new ();
|
||||
gboolean placeholder_layout = show_placeholder_text (entry);
|
||||
|
||||
gchar *preedit_string = NULL;
|
||||
gint preedit_length = 0;
|
||||
@ -5412,15 +5482,26 @@ gtk_entry_create_layout (GtkEntry *entry,
|
||||
|
||||
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);
|
||||
|
||||
if (include_preedit)
|
||||
if (!placeholder_layout && include_preedit)
|
||||
{
|
||||
gtk_im_context_get_preedit_string (priv->im_context,
|
||||
&preedit_string, &preedit_attrs, NULL);
|
||||
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)
|
||||
{
|
||||
@ -10132,6 +10213,61 @@ gtk_entry_progress_pulse (GtkEntry *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 */
|
||||
|
||||
static void
|
||||
|
@ -213,6 +213,10 @@ gdouble gtk_entry_get_progress_pulse_step (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
|
||||
*/
|
||||
void gtk_entry_set_icon_from_pixbuf (GtkEntry *entry,
|
||||
|
Loading…
Reference in New Issue
Block a user