forked from AuroraMiddleware/gtk
entry: Turn progress node into a gadget
This commit is contained in:
parent
3316d69abb
commit
429bec54e5
202
gtk/gtkentry.c
202
gtk/gtkentry.c
@ -213,8 +213,8 @@ struct _GtkEntryPrivate
|
||||
GtkGesture *multipress_gesture;
|
||||
|
||||
GtkCssGadget *gadget;
|
||||
GtkCssGadget *progress_gadget;
|
||||
GtkCssNode *selection_node;
|
||||
GtkCssNode *progress_node;
|
||||
GtkCssNode *undershoot_node[2];
|
||||
|
||||
gfloat xalign;
|
||||
@ -427,8 +427,6 @@ static void gtk_entry_get_preferred_height_and_baseline_for_width (GtkWidget *w
|
||||
gint *natural_baseline);
|
||||
static void gtk_entry_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *allocation);
|
||||
static void gtk_entry_draw_progress (GtkWidget *widget,
|
||||
cairo_t *cr);
|
||||
static gint gtk_entry_draw (GtkWidget *widget,
|
||||
cairo_t *cr);
|
||||
static gboolean gtk_entry_event (GtkWidget *widget,
|
||||
@ -2978,6 +2976,7 @@ gtk_entry_finalize (GObject *object)
|
||||
if (priv->attrs)
|
||||
pango_attr_list_unref (priv->attrs);
|
||||
|
||||
g_clear_object (&priv->progress_gadget);
|
||||
g_clear_object (&priv->gadget);
|
||||
|
||||
G_OBJECT_CLASS (gtk_entry_parent_class)->finalize (object);
|
||||
@ -3192,8 +3191,8 @@ update_node_state (GtkEntry *entry)
|
||||
|
||||
state = gtk_widget_get_state_flags (GTK_WIDGET (entry));
|
||||
|
||||
if (priv->progress_node)
|
||||
gtk_css_node_set_state (priv->progress_node, state);
|
||||
if (priv->progress_gadget)
|
||||
gtk_css_gadget_set_state (priv->progress_gadget, state);
|
||||
if (priv->selection_node)
|
||||
gtk_css_node_set_state (priv->selection_node, state);
|
||||
}
|
||||
@ -3206,12 +3205,11 @@ update_node_ordering (GtkEntry *entry)
|
||||
GtkEntryIconPosition icon_pos;
|
||||
GtkCssNode *sibling, *parent;
|
||||
|
||||
if (priv->progress_node)
|
||||
if (priv->progress_gadget)
|
||||
{
|
||||
parent = gtk_css_node_get_parent (priv->progress_node);
|
||||
sibling = gtk_css_node_get_last_child (parent);
|
||||
if (priv->progress_node != sibling)
|
||||
gtk_css_node_insert_after (parent, priv->progress_node, sibling);
|
||||
gtk_css_node_insert_before (gtk_css_gadget_get_node (priv->gadget),
|
||||
gtk_css_gadget_get_node (priv->progress_gadget),
|
||||
NULL);
|
||||
}
|
||||
|
||||
if (gtk_widget_get_direction (GTK_WIDGET (entry)) == GTK_TEXT_DIR_RTL)
|
||||
@ -3575,6 +3573,20 @@ gtk_entry_measure (GtkCssGadget *gadget,
|
||||
}
|
||||
|
||||
pango_font_metrics_unref (metrics);
|
||||
|
||||
if (priv->progress_gadget && gtk_css_gadget_get_visible (priv->progress_gadget))
|
||||
{
|
||||
int prog_min, prog_nat;
|
||||
|
||||
gtk_css_gadget_get_preferred_size (priv->progress_gadget,
|
||||
orientation,
|
||||
for_size,
|
||||
&prog_min, &prog_nat,
|
||||
NULL, NULL);
|
||||
|
||||
*minimum = MAX (*minimum, prog_min);
|
||||
*natural = MAX (*natural, prog_nat);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -3777,6 +3789,42 @@ gtk_entry_allocate (GtkCssGadget *gadget,
|
||||
gdk_rectangle_union (out_clip, &clip, out_clip);
|
||||
}
|
||||
|
||||
if (priv->progress_gadget && gtk_css_gadget_get_visible (priv->progress_gadget))
|
||||
{
|
||||
int extra_width, req_width;
|
||||
GtkAllocation progress_alloc;
|
||||
GdkRectangle clip;
|
||||
|
||||
gtk_css_gadget_get_preferred_size (priv->progress_gadget,
|
||||
GTK_ORIENTATION_HORIZONTAL,
|
||||
allocation->height,
|
||||
&req_width, NULL,
|
||||
NULL, NULL);
|
||||
extra_width = allocation->width - req_width;
|
||||
|
||||
progress_alloc = *allocation;
|
||||
|
||||
if (priv->progress_pulse_mode)
|
||||
{
|
||||
gdouble value = priv->progress_pulse_current;
|
||||
|
||||
progress_alloc.x += (gint) floor (value * extra_width);
|
||||
progress_alloc.width = req_width + (gint) ceil (priv->progress_pulse_fraction * extra_width);
|
||||
}
|
||||
else
|
||||
{
|
||||
gdouble value = priv->progress_fraction;
|
||||
|
||||
progress_alloc.width = req_width + (gint) nearbyint (value * extra_width);
|
||||
if (gtk_widget_get_direction (GTK_WIDGET (entry)) == GTK_TEXT_DIR_RTL)
|
||||
progress_alloc.x += allocation->width - progress_alloc.width;
|
||||
}
|
||||
|
||||
gtk_css_gadget_allocate (priv->progress_gadget, &progress_alloc, baseline, &clip);
|
||||
|
||||
gdk_rectangle_union (out_clip, &clip, out_clip);
|
||||
}
|
||||
|
||||
/* Do this here instead of gtk_entry_size_allocate() so it works
|
||||
* inside spinbuttons, which don't chain up.
|
||||
*/
|
||||
@ -3812,78 +3860,6 @@ should_prelight (GtkEntry *entry,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
get_progress_area (GtkWidget *widget,
|
||||
gint *x,
|
||||
gint *y,
|
||||
gint *width,
|
||||
gint *height)
|
||||
{
|
||||
GtkEntry *entry = GTK_ENTRY (widget);
|
||||
GtkEntryPrivate *private = entry->priv;
|
||||
GtkAllocation allocation;
|
||||
|
||||
gtk_css_gadget_get_content_allocation (private->gadget, &allocation, NULL);
|
||||
*x = allocation.x;
|
||||
*y = allocation.y;
|
||||
*width = allocation.width;
|
||||
*height = allocation.height;
|
||||
|
||||
if (private->progress_pulse_mode)
|
||||
{
|
||||
gdouble value = private->progress_pulse_current;
|
||||
|
||||
*x += (gint) floor(value * (*width));
|
||||
*width = (gint) ceil(private->progress_pulse_fraction * (*width));
|
||||
}
|
||||
else if (private->progress_fraction > 0)
|
||||
{
|
||||
gdouble value = private->progress_fraction;
|
||||
|
||||
if (gtk_widget_get_direction (GTK_WIDGET (entry)) == GTK_TEXT_DIR_RTL)
|
||||
{
|
||||
gint bar_width;
|
||||
|
||||
bar_width = floor(value * (*width) + 0.5);
|
||||
*x += *width - bar_width;
|
||||
*width = bar_width;
|
||||
}
|
||||
else
|
||||
{
|
||||
*width = (gint) floor(value * (*width) + 0.5);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*width = 0;
|
||||
*height = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_entry_draw_progress (GtkWidget *widget,
|
||||
cairo_t *cr)
|
||||
{
|
||||
GtkEntry *entry = GTK_ENTRY (widget);
|
||||
GtkStyleContext *context;
|
||||
GtkAllocation allocation;
|
||||
gint x, y, width, height;
|
||||
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
get_progress_area (widget, &x, &y, &width, &height);
|
||||
gtk_widget_get_allocation (widget, &allocation);
|
||||
x -= allocation.x;
|
||||
y -= allocation.y;
|
||||
|
||||
if ((width <= 0) || (height <= 0))
|
||||
return;
|
||||
|
||||
gtk_style_context_save_to_node (context, entry->priv->progress_node);
|
||||
gtk_render_background (context, cr, x, y, width, height);
|
||||
gtk_render_frame (context, cr, x, y, width, height);
|
||||
gtk_style_context_restore (context);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_entry_draw (GtkWidget *widget,
|
||||
cairo_t *cr)
|
||||
@ -3950,7 +3926,8 @@ gtk_entry_render (GtkCssGadget *gadget,
|
||||
priv = entry->priv;
|
||||
|
||||
/* Draw progress */
|
||||
gtk_entry_draw_progress (widget, cr);
|
||||
if (priv->progress_gadget && gtk_css_gadget_get_visible (priv->progress_gadget))
|
||||
gtk_css_gadget_draw (priv->progress_gadget, cr);
|
||||
|
||||
/* Draw text and cursor */
|
||||
cairo_save (cr);
|
||||
@ -10458,20 +10435,24 @@ tick_cb (GtkWidget *widget,
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_entry_ensure_progress_node (GtkEntry *entry)
|
||||
gtk_entry_ensure_progress_gadget (GtkEntry *entry)
|
||||
{
|
||||
GtkEntryPrivate *priv = entry->priv;
|
||||
GtkCssNode *widget_node;
|
||||
|
||||
if (priv->progress_node)
|
||||
if (priv->progress_gadget)
|
||||
return;
|
||||
|
||||
widget_node = gtk_css_gadget_get_node (priv->gadget);
|
||||
priv->progress_node = gtk_css_node_new ();
|
||||
gtk_css_node_set_name (priv->progress_node, I_("progress"));
|
||||
gtk_css_node_set_parent (priv->progress_node, widget_node);
|
||||
gtk_css_node_set_state (priv->progress_node, gtk_css_node_get_state (widget_node));
|
||||
g_object_unref (priv->progress_node);
|
||||
priv->progress_gadget = gtk_css_custom_gadget_new ("progress",
|
||||
GTK_WIDGET (entry),
|
||||
priv->gadget,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
gtk_css_gadget_set_state (priv->progress_gadget,
|
||||
gtk_css_node_get_state (gtk_widget_get_css_node (GTK_WIDGET (entry))));
|
||||
|
||||
update_node_ordering (entry);
|
||||
}
|
||||
@ -10484,9 +10465,9 @@ gtk_entry_start_pulse_mode (GtkEntry *entry)
|
||||
if (priv->progress_pulse_mode)
|
||||
return;
|
||||
|
||||
gtk_entry_ensure_progress_node (entry);
|
||||
gtk_css_node_set_visible (priv->progress_node, TRUE);
|
||||
gtk_css_node_add_class (priv->progress_node, g_quark_from_static_string (GTK_STYLE_CLASS_PULSE));
|
||||
gtk_entry_ensure_progress_gadget (entry);
|
||||
gtk_css_gadget_set_visible (priv->progress_gadget, TRUE);
|
||||
gtk_css_gadget_add_class (priv->progress_gadget, GTK_STYLE_CLASS_PULSE);
|
||||
|
||||
priv->progress_pulse_mode = TRUE;
|
||||
priv->tick_id = gtk_widget_add_tick_callback (GTK_WIDGET (entry), tick_cb, NULL, NULL);
|
||||
@ -10507,8 +10488,8 @@ gtk_entry_stop_pulse_mode (GtkEntry *entry)
|
||||
|
||||
if (priv->progress_pulse_mode)
|
||||
{
|
||||
gtk_css_node_set_visible (priv->progress_node, FALSE);
|
||||
gtk_css_node_remove_class (priv->progress_node, g_quark_from_static_string (GTK_STYLE_CLASS_PULSE));
|
||||
gtk_css_gadget_set_visible (priv->progress_gadget, FALSE);
|
||||
gtk_css_gadget_remove_class (priv->progress_gadget, GTK_STYLE_CLASS_PULSE);
|
||||
|
||||
priv->progress_pulse_mode = FALSE;
|
||||
gtk_widget_remove_tick_callback (GTK_WIDGET (entry), priv->tick_id);
|
||||
@ -10543,21 +10524,12 @@ gtk_entry_set_progress_fraction (GtkEntry *entry,
|
||||
GtkWidget *widget;
|
||||
GtkEntryPrivate *private;
|
||||
gdouble old_fraction;
|
||||
gint x, y, width, height;
|
||||
gint old_x = 0, old_y = 0, old_width = 0, old_height = 0;
|
||||
gboolean was_pulse;
|
||||
|
||||
g_return_if_fail (GTK_IS_ENTRY (entry));
|
||||
|
||||
widget = GTK_WIDGET (entry);
|
||||
private = entry->priv;
|
||||
|
||||
gtk_entry_ensure_progress_node (entry);
|
||||
gtk_css_node_set_visible (private->progress_node, TRUE);
|
||||
gtk_css_node_remove_class (private->progress_node, g_quark_from_static_string (GTK_STYLE_CLASS_PULSE));
|
||||
|
||||
was_pulse = private->progress_pulse_mode;
|
||||
|
||||
if (private->progress_pulse_mode)
|
||||
old_fraction = -1;
|
||||
else
|
||||
@ -10565,24 +10537,18 @@ gtk_entry_set_progress_fraction (GtkEntry *entry,
|
||||
|
||||
gtk_entry_stop_pulse_mode (entry);
|
||||
|
||||
if (gtk_widget_is_drawable (widget))
|
||||
get_progress_area (widget, &old_x, &old_y, &old_width, &old_height);
|
||||
gtk_entry_ensure_progress_gadget (entry);
|
||||
gtk_css_gadget_set_visible (private->progress_gadget, TRUE);
|
||||
|
||||
fraction = CLAMP (fraction, 0.0, 1.0);
|
||||
private->progress_fraction = fraction;
|
||||
private->progress_pulse_current = 0.0;
|
||||
|
||||
if (gtk_widget_is_drawable (widget))
|
||||
{
|
||||
get_progress_area (widget, &x, &y, &width, &height);
|
||||
|
||||
if (was_pulse ||
|
||||
x != old_x || y != old_y || width != old_width || height != old_height)
|
||||
gtk_widget_queue_draw (widget);
|
||||
}
|
||||
|
||||
if (fraction != old_fraction)
|
||||
g_object_notify_by_pspec (G_OBJECT (entry), entry_props[PROP_PROGRESS_FRACTION]);
|
||||
{
|
||||
g_object_notify_by_pspec (G_OBJECT (entry), entry_props[PROP_PROGRESS_FRACTION]);
|
||||
gtk_widget_queue_allocate (widget);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user