forked from AuroraMiddleware/gtk
entry: give a visual clue that content is scrolled
This has been requested long ago, and we now have the machinery to implement it easily.
This commit is contained in:
parent
8991f17d49
commit
a9222146d3
@ -122,6 +122,8 @@
|
||||
* entry
|
||||
* ├── image.left
|
||||
* ├── image.right
|
||||
* ├── undershoot.left
|
||||
* ├── undershoot.right
|
||||
* ├── [selection]
|
||||
* ├── [progress[.pulse]]
|
||||
* ╰── [window.popup]
|
||||
@ -141,6 +143,10 @@
|
||||
*
|
||||
* The CSS node for a context menu is added as a subnode below entry as well.
|
||||
*
|
||||
* The undrshoot nodes are used to draw the underflow indication when content
|
||||
* is scrolled out of view. These nodes get the .left and .right style classes
|
||||
* added depending on where the indication is drawn.
|
||||
*
|
||||
* When touch is used and touch selection handles are shown, they are using
|
||||
* CSS nodes with name cursor-handle. They get the .top or .bottom style class
|
||||
* depending on where they are shown in relation to the selection. If there is
|
||||
@ -209,6 +215,7 @@ struct _GtkEntryPrivate
|
||||
GtkCssGadget *gadget;
|
||||
GtkCssNode *selection_node;
|
||||
GtkCssNode *progress_node;
|
||||
GtkCssNode *undershoot_node[2];
|
||||
|
||||
gfloat xalign;
|
||||
|
||||
@ -647,6 +654,9 @@ static void get_frame_size (GtkEntry *entry,
|
||||
static void gtk_entry_move_adjustments (GtkEntry *entry);
|
||||
static void gtk_entry_update_cached_style_values(GtkEntry *entry);
|
||||
static gboolean get_middle_click_paste (GtkEntry *entry);
|
||||
static void gtk_entry_get_scroll_limits (GtkEntry *entry,
|
||||
gint *min_offset,
|
||||
gint *max_offset);
|
||||
|
||||
/* GtkTextHandle handlers */
|
||||
static void gtk_entry_handle_drag_started (GtkTextHandle *handle,
|
||||
@ -2694,6 +2704,7 @@ gtk_entry_init (GtkEntry *entry)
|
||||
{
|
||||
GtkEntryPrivate *priv;
|
||||
GtkCssNode *widget_node;
|
||||
gint i;
|
||||
|
||||
entry->priv = gtk_entry_get_instance_private (entry);
|
||||
priv = entry->priv;
|
||||
@ -2757,6 +2768,16 @@ gtk_entry_init (GtkEntry *entry)
|
||||
gtk_entry_render,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
priv->undershoot_node[i] = gtk_css_node_new ();
|
||||
gtk_css_node_set_name (priv->undershoot_node[i], I_("undershoot"));
|
||||
gtk_css_node_add_class (priv->undershoot_node[i], g_quark_from_static_string (i == 0 ? GTK_STYLE_CLASS_LEFT : GTK_STYLE_CLASS_RIGHT));
|
||||
gtk_css_node_set_parent (priv->undershoot_node[i], widget_node);
|
||||
gtk_css_node_set_state (priv->undershoot_node[i], gtk_css_node_get_state (widget_node));
|
||||
g_object_unref (priv->undershoot_node[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -3901,6 +3922,44 @@ gtk_entry_draw (GtkWidget *widget,
|
||||
return GDK_EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
#define UNDERSHOOT_SIZE 20
|
||||
|
||||
static void
|
||||
gtk_entry_draw_undershoot (GtkEntry *entry,
|
||||
cairo_t *cr)
|
||||
{
|
||||
GtkEntryPrivate *priv = entry->priv;
|
||||
GtkStyleContext *context;
|
||||
gint min_offset, max_offset;
|
||||
GtkAllocation allocation;
|
||||
GdkRectangle rect;
|
||||
|
||||
context = gtk_widget_get_style_context (GTK_WIDGET (entry));
|
||||
|
||||
gtk_entry_get_scroll_limits (entry, &min_offset, &max_offset);
|
||||
|
||||
gtk_css_gadget_get_content_allocation (priv->gadget, &rect, NULL);
|
||||
gtk_widget_get_allocation (GTK_WIDGET (entry), &allocation);
|
||||
rect.x -= allocation.x;
|
||||
rect.y -= allocation.y;
|
||||
|
||||
if (priv->scroll_offset > min_offset)
|
||||
{
|
||||
gtk_style_context_save_to_node (context, priv->undershoot_node[0]);
|
||||
gtk_render_background (context, cr, rect.x, rect.y, UNDERSHOOT_SIZE, rect.height);
|
||||
gtk_render_frame (context, cr, rect.x, rect.y, UNDERSHOOT_SIZE, rect.height);
|
||||
gtk_style_context_restore (context);
|
||||
}
|
||||
|
||||
if (priv->scroll_offset < max_offset)
|
||||
{
|
||||
gtk_style_context_save_to_node (context, priv->undershoot_node[1]);
|
||||
gtk_render_background (context, cr, rect.x + rect.width - UNDERSHOOT_SIZE, rect.y, UNDERSHOOT_SIZE, rect.height);
|
||||
gtk_render_frame (context, cr, rect.x + rect.width - UNDERSHOOT_SIZE, rect.y, UNDERSHOOT_SIZE, rect.height);
|
||||
gtk_style_context_restore (context);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_entry_render (GtkCssGadget *gadget,
|
||||
cairo_t *cr,
|
||||
@ -3951,6 +4010,8 @@ gtk_entry_render (GtkCssGadget *gadget,
|
||||
if (icon_info != NULL)
|
||||
gtk_css_gadget_draw (icon_info->gadget, cr);
|
||||
}
|
||||
|
||||
gtk_entry_draw_undershoot (entry, cr);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
@ -6773,21 +6834,16 @@ gtk_entry_get_is_selection_handle_dragged (GtkEntry *entry)
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_entry_adjust_scroll (GtkEntry *entry)
|
||||
gtk_entry_get_scroll_limits (GtkEntry *entry,
|
||||
gint *min_offset,
|
||||
gint *max_offset)
|
||||
{
|
||||
GtkEntryPrivate *priv = entry->priv;
|
||||
gint min_offset, max_offset;
|
||||
gint text_width;
|
||||
gint strong_x, weak_x;
|
||||
gint strong_xoffset, weak_xoffset;
|
||||
gfloat xalign;
|
||||
PangoLayout *layout;
|
||||
PangoLayoutLine *line;
|
||||
PangoRectangle logical_rect;
|
||||
GtkTextHandleMode handle_mode;
|
||||
|
||||
if (!gtk_widget_get_realized (GTK_WIDGET (entry)))
|
||||
return;
|
||||
gint text_width;
|
||||
|
||||
layout = gtk_entry_ensure_layout (entry, TRUE);
|
||||
line = pango_layout_get_lines_readonly (layout)->data;
|
||||
@ -6805,14 +6861,29 @@ gtk_entry_adjust_scroll (GtkEntry *entry)
|
||||
|
||||
if (text_width > priv->text_allocation.width)
|
||||
{
|
||||
min_offset = 0;
|
||||
max_offset = text_width - priv->text_allocation.width;
|
||||
*min_offset = 0;
|
||||
*max_offset = text_width - priv->text_allocation.width;
|
||||
}
|
||||
else
|
||||
{
|
||||
min_offset = (text_width - priv->text_allocation.width) * xalign;
|
||||
max_offset = min_offset;
|
||||
*min_offset = (text_width - priv->text_allocation.width) * xalign;
|
||||
*max_offset = *min_offset;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_entry_adjust_scroll (GtkEntry *entry)
|
||||
{
|
||||
GtkEntryPrivate *priv = entry->priv;
|
||||
gint min_offset, max_offset;
|
||||
gint strong_x, weak_x;
|
||||
gint strong_xoffset, weak_xoffset;
|
||||
GtkTextHandleMode handle_mode;
|
||||
|
||||
if (!gtk_widget_get_realized (GTK_WIDGET (entry)))
|
||||
return;
|
||||
|
||||
gtk_entry_get_scroll_limits (entry, &min_offset, &max_offset);
|
||||
|
||||
priv->scroll_offset = CLAMP (priv->scroll_offset, min_offset, max_offset);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user