mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-08 11:40:16 +00:00
entry: Convert to gsk
This introduces a new css node for block cursor styling.
This commit is contained in:
parent
1440bb25de
commit
8de8525b44
120
gtk/gtkentry.c
120
gtk/gtkentry.c
@ -125,6 +125,7 @@
|
|||||||
* ├── undershoot.left
|
* ├── undershoot.left
|
||||||
* ├── undershoot.right
|
* ├── undershoot.right
|
||||||
* ├── [selection]
|
* ├── [selection]
|
||||||
|
* ├── [block-cursor]
|
||||||
* ├── [progress[.pulse]]
|
* ├── [progress[.pulse]]
|
||||||
* ╰── [window.popup]
|
* ╰── [window.popup]
|
||||||
* ]|
|
* ]|
|
||||||
@ -138,6 +139,9 @@
|
|||||||
*
|
*
|
||||||
* When the entry has a selection, it adds a subnode with the name selection.
|
* When the entry has a selection, it adds a subnode with the name selection.
|
||||||
*
|
*
|
||||||
|
* When the entry is in overwrite mode, it adds a subnode with the name block-cursor
|
||||||
|
* that determines how the block cursor is drawn.
|
||||||
|
*
|
||||||
* When the entry shows progress, it adds a subnode with the name progress.
|
* When the entry shows progress, it adds a subnode with the name progress.
|
||||||
* The node has the style class .pulse when the shown progress is pulsing.
|
* The node has the style class .pulse when the shown progress is pulsing.
|
||||||
*
|
*
|
||||||
@ -204,6 +208,7 @@ struct _GtkEntryPrivate
|
|||||||
|
|
||||||
GtkWidget *progress_widget;
|
GtkWidget *progress_widget;
|
||||||
GtkCssNode *selection_node;
|
GtkCssNode *selection_node;
|
||||||
|
GtkCssNode *block_cursor_node;
|
||||||
GtkCssNode *undershoot_node[2];
|
GtkCssNode *undershoot_node[2];
|
||||||
|
|
||||||
int text_x;
|
int text_x;
|
||||||
@ -559,9 +564,9 @@ static void gtk_entry_set_positions (GtkEntry *entry,
|
|||||||
gint current_pos,
|
gint current_pos,
|
||||||
gint selection_bound);
|
gint selection_bound);
|
||||||
static void gtk_entry_draw_text (GtkEntry *entry,
|
static void gtk_entry_draw_text (GtkEntry *entry,
|
||||||
cairo_t *cr);
|
GtkSnapshot *snapshot);
|
||||||
static void gtk_entry_draw_cursor (GtkEntry *entry,
|
static void gtk_entry_draw_cursor (GtkEntry *entry,
|
||||||
cairo_t *cr,
|
GtkSnapshot *snapshot,
|
||||||
CursorType type);
|
CursorType type);
|
||||||
static PangoLayout *gtk_entry_ensure_layout (GtkEntry *entry,
|
static PangoLayout *gtk_entry_ensure_layout (GtkEntry *entry,
|
||||||
gboolean include_preedit);
|
gboolean include_preedit);
|
||||||
@ -2872,6 +2877,9 @@ update_node_state (GtkEntry *entry)
|
|||||||
if (priv->selection_node)
|
if (priv->selection_node)
|
||||||
gtk_css_node_set_state (priv->selection_node, state);
|
gtk_css_node_set_state (priv->selection_node, state);
|
||||||
|
|
||||||
|
if (priv->block_cursor_node)
|
||||||
|
gtk_css_node_set_state (priv->block_cursor_node, state);
|
||||||
|
|
||||||
gtk_css_node_set_state (priv->undershoot_node[0], state);
|
gtk_css_node_set_state (priv->undershoot_node[0], state);
|
||||||
gtk_css_node_set_state (priv->undershoot_node[1], state);
|
gtk_css_node_set_state (priv->undershoot_node[1], state);
|
||||||
}
|
}
|
||||||
@ -3272,7 +3280,6 @@ gtk_entry_snapshot (GtkWidget *widget,
|
|||||||
GtkEntry *entry = GTK_ENTRY (widget);
|
GtkEntry *entry = GTK_ENTRY (widget);
|
||||||
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
|
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
|
||||||
int width, height;
|
int width, height;
|
||||||
cairo_t *cr;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
gtk_widget_get_content_size (widget, &width, &height);
|
gtk_widget_get_content_size (widget, &width, &height);
|
||||||
@ -3282,27 +3289,17 @@ gtk_entry_snapshot (GtkWidget *widget,
|
|||||||
gtk_widget_snapshot_child (widget, priv->progress_widget, snapshot);
|
gtk_widget_snapshot_child (widget, priv->progress_widget, snapshot);
|
||||||
|
|
||||||
/* Draw text and cursor */
|
/* Draw text and cursor */
|
||||||
/* We add 1 to priv->text_width here simply because we might draw the
|
|
||||||
* cursor at the very right, one pixel after all the text. */
|
|
||||||
cr = gtk_snapshot_append_cairo (snapshot,
|
|
||||||
&GRAPHENE_RECT_INIT (priv->text_x,
|
|
||||||
0,
|
|
||||||
priv->text_width + 1,
|
|
||||||
height),
|
|
||||||
"Entry Text");
|
|
||||||
|
|
||||||
if (priv->dnd_position != -1)
|
if (priv->dnd_position != -1)
|
||||||
gtk_entry_draw_cursor (GTK_ENTRY (widget), cr, CURSOR_DND);
|
gtk_entry_draw_cursor (GTK_ENTRY (widget), snapshot, CURSOR_DND);
|
||||||
|
|
||||||
gtk_entry_draw_text (GTK_ENTRY (widget), cr);
|
gtk_entry_draw_text (GTK_ENTRY (widget), snapshot);
|
||||||
|
|
||||||
/* When no text is being displayed at all, don't show the cursor */
|
/* When no text is being displayed at all, don't show the cursor */
|
||||||
if (gtk_entry_get_display_mode (entry) != DISPLAY_BLANK &&
|
if (gtk_entry_get_display_mode (entry) != DISPLAY_BLANK &&
|
||||||
gtk_widget_has_focus (widget) &&
|
gtk_widget_has_focus (widget) &&
|
||||||
priv->selection_bound == priv->current_pos && priv->cursor_visible)
|
priv->selection_bound == priv->current_pos && priv->cursor_visible)
|
||||||
gtk_entry_draw_cursor (GTK_ENTRY (widget), cr, CURSOR_STANDARD);
|
gtk_entry_draw_cursor (GTK_ENTRY (widget), snapshot, CURSOR_STANDARD);
|
||||||
|
|
||||||
cairo_destroy (cr);
|
|
||||||
|
|
||||||
/* Draw icons */
|
/* Draw icons */
|
||||||
for (i = 0; i < MAX_ICONS; i++)
|
for (i = 0; i < MAX_ICONS; i++)
|
||||||
@ -5162,6 +5159,29 @@ gtk_entry_toggle_overwrite (GtkEntry *entry)
|
|||||||
GtkEntryPrivate *priv = entry->priv;
|
GtkEntryPrivate *priv = entry->priv;
|
||||||
|
|
||||||
priv->overwrite_mode = !priv->overwrite_mode;
|
priv->overwrite_mode = !priv->overwrite_mode;
|
||||||
|
|
||||||
|
if (priv->overwrite_mode)
|
||||||
|
{
|
||||||
|
if (!priv->block_cursor_node)
|
||||||
|
{
|
||||||
|
GtkCssNode *widget_node = gtk_widget_get_css_node (GTK_WIDGET (entry));
|
||||||
|
|
||||||
|
priv->block_cursor_node = gtk_css_node_new ();
|
||||||
|
gtk_css_node_set_name (priv->block_cursor_node, I_("block-cursor"));
|
||||||
|
gtk_css_node_set_parent (priv->block_cursor_node, widget_node);
|
||||||
|
gtk_css_node_set_state (priv->block_cursor_node, gtk_css_node_get_state (widget_node));
|
||||||
|
g_object_unref (priv->block_cursor_node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (priv->block_cursor_node)
|
||||||
|
{
|
||||||
|
gtk_css_node_set_parent (priv->block_cursor_node, NULL);
|
||||||
|
priv->block_cursor_node = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
gtk_entry_pend_cursor_blink (entry);
|
gtk_entry_pend_cursor_blink (entry);
|
||||||
gtk_widget_queue_draw (GTK_WIDGET (entry));
|
gtk_widget_queue_draw (GTK_WIDGET (entry));
|
||||||
}
|
}
|
||||||
@ -5653,9 +5673,11 @@ get_layout_position (GtkEntry *entry,
|
|||||||
*y = y_pos;
|
*y = y_pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define GRAPHENE_RECT_FROM_RECT(_r) (GRAPHENE_RECT_INIT ((_r)->x, (_r)->y, (_r)->width, (_r)->height))
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_entry_draw_text (GtkEntry *entry,
|
gtk_entry_draw_text (GtkEntry *entry,
|
||||||
cairo_t *cr)
|
GtkSnapshot *snapshot)
|
||||||
{
|
{
|
||||||
GtkEntryPrivate *priv = entry->priv;
|
GtkEntryPrivate *priv = entry->priv;
|
||||||
GtkWidget *widget = GTK_WIDGET (entry);
|
GtkWidget *widget = GTK_WIDGET (entry);
|
||||||
@ -5673,14 +5695,12 @@ gtk_entry_draw_text (GtkEntry *entry,
|
|||||||
gtk_widget_get_content_size (widget, &width, &height);
|
gtk_widget_get_content_size (widget, &width, &height);
|
||||||
layout = gtk_entry_ensure_layout (entry, TRUE);
|
layout = gtk_entry_ensure_layout (entry, TRUE);
|
||||||
|
|
||||||
cairo_save (cr);
|
|
||||||
|
|
||||||
gtk_entry_get_layout_offsets (entry, &x, &y);
|
gtk_entry_get_layout_offsets (entry, &x, &y);
|
||||||
|
|
||||||
if (show_placeholder_text (entry))
|
if (show_placeholder_text (entry))
|
||||||
pango_layout_set_width (layout, PANGO_SCALE * priv->text_width);
|
pango_layout_set_width (layout, PANGO_SCALE * priv->text_width);
|
||||||
|
|
||||||
gtk_render_layout (context, cr, x, y, layout);
|
gtk_snapshot_render_layout (snapshot, context, x, y, layout);
|
||||||
|
|
||||||
if (gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), &start_pos, &end_pos))
|
if (gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), &start_pos, &end_pos))
|
||||||
{
|
{
|
||||||
@ -5688,6 +5708,7 @@ gtk_entry_draw_text (GtkEntry *entry,
|
|||||||
gint start_index = g_utf8_offset_to_pointer (text, start_pos) - text;
|
gint start_index = g_utf8_offset_to_pointer (text, start_pos) - text;
|
||||||
gint end_index = g_utf8_offset_to_pointer (text, end_pos) - text;
|
gint end_index = g_utf8_offset_to_pointer (text, end_pos) - text;
|
||||||
cairo_region_t *clip;
|
cairo_region_t *clip;
|
||||||
|
cairo_rectangle_int_t clip_extents;
|
||||||
gint range[2];
|
gint range[2];
|
||||||
|
|
||||||
range[0] = MIN (start_index, end_index);
|
range[0] = MIN (start_index, end_index);
|
||||||
@ -5696,22 +5717,22 @@ gtk_entry_draw_text (GtkEntry *entry,
|
|||||||
gtk_style_context_save_to_node (context, priv->selection_node);
|
gtk_style_context_save_to_node (context, priv->selection_node);
|
||||||
|
|
||||||
clip = gdk_pango_layout_get_clip_region (layout, x, y, range, 1);
|
clip = gdk_pango_layout_get_clip_region (layout, x, y, range, 1);
|
||||||
gdk_cairo_region (cr, clip);
|
cairo_region_get_extents (clip, &clip_extents);
|
||||||
cairo_clip (cr);
|
|
||||||
cairo_region_destroy (clip);
|
|
||||||
|
|
||||||
gtk_render_background (context, cr, 0, 0, width, height);
|
gtk_snapshot_push_clip (snapshot, &GRAPHENE_RECT_FROM_RECT (&clip_extents), "Selected Text");
|
||||||
gtk_render_layout (context, cr, x, y, layout);
|
gtk_snapshot_render_background (snapshot, context, 0, 0, width, height);
|
||||||
|
gtk_snapshot_render_layout (snapshot, context, x, y, layout);
|
||||||
|
gtk_snapshot_pop (snapshot);
|
||||||
|
|
||||||
|
cairo_region_destroy (clip);
|
||||||
|
|
||||||
gtk_style_context_restore (context);
|
gtk_style_context_restore (context);
|
||||||
}
|
}
|
||||||
|
|
||||||
cairo_restore (cr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_entry_draw_cursor (GtkEntry *entry,
|
gtk_entry_draw_cursor (GtkEntry *entry,
|
||||||
cairo_t *cr,
|
GtkSnapshot *snapshot,
|
||||||
CursorType type)
|
CursorType type)
|
||||||
{
|
{
|
||||||
GtkEntryPrivate *priv = entry->priv;
|
GtkEntryPrivate *priv = entry->priv;
|
||||||
@ -5724,12 +5745,14 @@ gtk_entry_draw_cursor (GtkEntry *entry,
|
|||||||
PangoLayout *layout;
|
PangoLayout *layout;
|
||||||
const char *text;
|
const char *text;
|
||||||
gint x, y;
|
gint x, y;
|
||||||
|
int width, height;
|
||||||
|
|
||||||
context = gtk_widget_get_style_context (widget);
|
context = gtk_widget_get_style_context (widget);
|
||||||
|
|
||||||
layout = gtk_entry_ensure_layout (entry, TRUE);
|
layout = gtk_entry_ensure_layout (entry, TRUE);
|
||||||
text = pango_layout_get_text (layout);
|
text = pango_layout_get_text (layout);
|
||||||
gtk_entry_get_layout_offsets (entry, &x, &y);
|
gtk_entry_get_layout_offsets (entry, &x, &y);
|
||||||
|
gtk_widget_get_content_size (widget, &width, &height);
|
||||||
|
|
||||||
if (type == CURSOR_DND)
|
if (type == CURSOR_DND)
|
||||||
cursor_index = g_utf8_offset_to_pointer (text, priv->dnd_position) - text;
|
cursor_index = g_utf8_offset_to_pointer (text, priv->dnd_position) - text;
|
||||||
@ -5743,44 +5766,27 @@ gtk_entry_draw_cursor (GtkEntry *entry,
|
|||||||
cursor_index, &cursor_rect, &block_at_line_end);
|
cursor_index, &cursor_rect, &block_at_line_end);
|
||||||
if (!block)
|
if (!block)
|
||||||
{
|
{
|
||||||
gtk_render_insertion_cursor (context, cr,
|
gtk_snapshot_render_insertion_cursor (snapshot, context,
|
||||||
x, y,
|
x, y,
|
||||||
layout, cursor_index, priv->resolved_dir);
|
layout, cursor_index, priv->resolved_dir);
|
||||||
}
|
}
|
||||||
else /* overwrite_mode */
|
else /* overwrite_mode */
|
||||||
{
|
{
|
||||||
GdkRGBA cursor_color;
|
graphene_rect_t bounds;
|
||||||
GdkRectangle rect;
|
|
||||||
|
|
||||||
cairo_save (cr);
|
bounds.origin.x = PANGO_PIXELS (cursor_rect.x) + x;
|
||||||
|
bounds.origin.y = PANGO_PIXELS (cursor_rect.y) + y;
|
||||||
|
bounds.size.width = PANGO_PIXELS (cursor_rect.width);
|
||||||
|
bounds.size.height = PANGO_PIXELS (cursor_rect.height);
|
||||||
|
|
||||||
rect.x = PANGO_PIXELS (cursor_rect.x) + x;
|
gtk_style_context_save_to_node (context, priv->block_cursor_node);
|
||||||
rect.y = PANGO_PIXELS (cursor_rect.y) + y;
|
|
||||||
rect.width = PANGO_PIXELS (cursor_rect.width);
|
|
||||||
rect.height = PANGO_PIXELS (cursor_rect.height);
|
|
||||||
|
|
||||||
_gtk_style_context_get_cursor_color (context, &cursor_color, NULL);
|
gtk_snapshot_push_clip (snapshot, &bounds, "Block Cursor");
|
||||||
gdk_cairo_set_source_rgba (cr, &cursor_color);
|
gtk_snapshot_render_background (snapshot, context, 0, 0, width, height);
|
||||||
gdk_cairo_rectangle (cr, &rect);
|
gtk_snapshot_render_layout (snapshot, context, x, y, layout);
|
||||||
cairo_fill (cr);
|
gtk_snapshot_pop (snapshot);
|
||||||
|
|
||||||
if (!block_at_line_end)
|
gtk_style_context_restore (context);
|
||||||
{
|
|
||||||
GdkRGBA color;
|
|
||||||
|
|
||||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
|
||||||
gtk_style_context_get_background_color (context,
|
|
||||||
&color);
|
|
||||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
|
||||||
|
|
||||||
gdk_cairo_rectangle (cr, &rect);
|
|
||||||
cairo_clip (cr);
|
|
||||||
cairo_move_to (cr, x, y);
|
|
||||||
gdk_cairo_set_source_rgba (cr, &color);
|
|
||||||
pango_cairo_show_layout (cr, layout);
|
|
||||||
}
|
|
||||||
|
|
||||||
cairo_restore (cr);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user