[gtk+/rendering-cleanup: 49/75] label: Draw all text using gtk_paint_layout()
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/rendering-cleanup: 49/75] label: Draw all text using gtk_paint_layout()
- Date: Wed, 4 Aug 2010 22:11:02 +0000 (UTC)
commit d9652763f48fcd3449dcd9edacaa2233cfaaa775
Author: Benjamin Otte <otte redhat com>
Date: Wed Jul 21 14:23:22 2010 +0200
label: Draw all text using gtk_paint_layout()
Previously, selected areas were overdrawn gdk_draw_layout(). Now we
insert the proper Pango markup to modify foreground and background
colors of the selection or active anchors. This way, we can use
gtk_paint_layout() unconditionally.
https://bugzilla.gnome.org/show_bug.cgi?id=624917
gtk/gtklabel.c | 223 +++++++++++++++++++++++++++++++++++---------------------
1 files changed, 139 insertions(+), 84 deletions(-)
---
diff --git a/gtk/gtklabel.c b/gtk/gtklabel.c
index 07a1f4e..21d8518 100644
--- a/gtk/gtklabel.c
+++ b/gtk/gtklabel.c
@@ -223,6 +223,8 @@ static gboolean gtk_label_motion (GtkWidget *widget,
GdkEventMotion *event);
static gboolean gtk_label_leave_notify (GtkWidget *widget,
GdkEventCrossing *event);
+static gboolean gtk_label_focus_out (GtkWidget *widget,
+ GdkEventFocus *event);
static void gtk_label_grab_focus (GtkWidget *widget);
@@ -408,6 +410,7 @@ gtk_label_class_init (GtkLabelClass *class)
widget_class->button_release_event = gtk_label_button_release;
widget_class->motion_notify_event = gtk_label_motion;
widget_class->leave_notify_event = gtk_label_leave_notify;
+ widget_class->focus_out_event = gtk_label_focus_out;
widget_class->hierarchy_changed = gtk_label_hierarchy_changed;
widget_class->screen_changed = gtk_label_screen_changed;
widget_class->mnemonic_activate = gtk_label_mnemonic_activate;
@@ -3164,6 +3167,120 @@ get_label_wrap_width (GtkLabel *label)
}
static void
+gtk_label_update_color (PangoAttrList *attrs,
+ guint start,
+ guint end,
+ GdkColor *foreground,
+ GdkColor *background)
+{
+ PangoAttribute *attr;
+
+ attr = pango_attr_background_new (background->red,
+ background->green,
+ background->blue);
+ attr->start_index = start;
+ attr->end_index = end;
+ pango_attr_list_change (attrs, attr);
+
+ attr = pango_attr_foreground_new (foreground->red,
+ foreground->green,
+ foreground->blue);
+ attr->start_index = start;
+ attr->end_index = end;
+ pango_attr_list_change (attrs, attr);
+
+}
+
+static void
+gtk_label_update_layout_attributes (GtkLabel *label)
+{
+ GtkWidget *widget = GTK_WIDGET (label);
+ GtkLabelPriv *priv = label->priv;
+ GtkLabelSelectionInfo *info;
+ PangoAttrList *attrs;
+ GtkStateType state;
+ guint start, end;
+
+ if (priv->layout == NULL)
+ return;
+
+ if (priv->select_info == NULL)
+ {
+ if (priv->effective_attrs)
+ pango_layout_set_attributes (priv->layout, priv->effective_attrs);
+
+ return;
+ }
+
+ info = priv->select_info;
+
+ if (priv->effective_attrs)
+ attrs = pango_attr_list_copy (priv->effective_attrs);
+ else
+ attrs = pango_attr_list_new ();
+
+ if (info->selection_anchor != info->selection_end)
+ {
+
+ start = info->selection_anchor;
+ end = info->selection_end;
+
+ if (start > end)
+ {
+ guint tmp = start;
+ start = end;
+ end = tmp;
+ }
+
+ state = GTK_STATE_SELECTED;
+ if (!gtk_widget_has_focus (widget))
+ state = GTK_STATE_ACTIVE;
+
+ gtk_label_update_color (attrs,
+ start, end,
+ &widget->style->text[state],
+ &widget->style->base[state]);
+ }
+ else
+ {
+ GtkLabelLink *active_link;
+ GdkColor *text_color;
+ GdkColor *base_color;
+ GdkColor *link_color;
+ GdkColor *visited_link_color;
+
+ active_link = info->active_link;
+
+ if (active_link)
+ {
+ start = active_link->start;
+ end = active_link->end;
+
+ gtk_label_get_link_colors (widget, &link_color, &visited_link_color);
+ if (active_link->visited)
+ text_color = visited_link_color;
+ else
+ text_color = link_color;
+ if (info->link_clicked)
+ base_color = &widget->style->base[GTK_STATE_ACTIVE];
+ else
+ base_color = &widget->style->base[GTK_STATE_PRELIGHT];
+
+ gtk_label_update_color (attrs,
+ start, end,
+ text_color,
+ base_color);
+
+ gdk_color_free (link_color);
+ gdk_color_free (visited_link_color);
+ }
+ }
+
+ pango_layout_set_attributes (priv->layout, attrs);
+ pango_attr_list_unref (attrs);
+}
+
+static void
gtk_label_ensure_layout (GtkLabel *label, gboolean guess_wrap_width)
{
GtkLabelPriv *priv = label->priv;
@@ -3204,8 +3321,7 @@ gtk_label_ensure_layout (GtkLabel *label, gboolean guess_wrap_width)
priv->layout = gtk_widget_create_pango_layout (widget, priv->text);
- if (priv->effective_attrs)
- pango_layout_set_attributes (priv->layout, priv->effective_attrs);
+ gtk_label_update_layout_attributes (label);
gtk_label_rescan_links (label);
@@ -4098,99 +4214,18 @@ gtk_label_expose (GtkWidget *widget,
priv->layout);
if (info &&
- (info->selection_anchor != info->selection_end))
- {
- gint range[2];
- cairo_region_t *clip;
- GtkStateType state;
-
- range[0] = info->selection_anchor;
- range[1] = info->selection_end;
-
- if (range[0] > range[1])
- {
- gint tmp = range[0];
- range[0] = range[1];
- range[1] = tmp;
- }
-
- clip = gdk_pango_layout_get_clip_region (priv->layout,
- x, y,
- range,
- 1);
- cairo_region_intersect (clip, event->region);
-
- /* FIXME should use gtk_paint, but it can't use a clip
- * region
- */
-
- gdk_gc_set_clip_region (widget->style->black_gc, clip);
-
-
- state = GTK_STATE_SELECTED;
- if (!gtk_widget_has_focus (widget))
- state = GTK_STATE_ACTIVE;
-
- gdk_draw_layout_with_colors (widget->window,
- widget->style->black_gc,
- x, y,
- priv->layout,
- &widget->style->text[state],
- &widget->style->base[state]);
-
- gdk_gc_set_clip_region (widget->style->black_gc, NULL);
- cairo_region_destroy (clip);
- }
- else if (info)
+ (info->selection_anchor == info->selection_end))
{
GtkLabelLink *focus_link;
GtkLabelLink *active_link;
gint range[2];
cairo_region_t *clip;
GdkRectangle rect;
- GdkColor *text_color;
- GdkColor *base_color;
- GdkColor *link_color;
- GdkColor *visited_link_color;
if (info->selectable && gtk_widget_has_focus (widget))
gtk_label_draw_cursor (label, x, y);
focus_link = gtk_label_get_focus_link (label);
- active_link = info->active_link;
-
- if (active_link)
- {
- range[0] = active_link->start;
- range[1] = active_link->end;
-
- clip = gdk_pango_layout_get_clip_region (priv->layout,
- x, y,
- range,
- 1);
- gdk_gc_set_clip_region (widget->style->black_gc, clip);
-
- gtk_label_get_link_colors (widget, &link_color, &visited_link_color);
- if (active_link->visited)
- text_color = visited_link_color;
- else
- text_color = link_color;
- if (info->link_clicked)
- base_color = &widget->style->base[GTK_STATE_ACTIVE];
- else
- base_color = &widget->style->base[GTK_STATE_PRELIGHT];
- gdk_draw_layout_with_colors (widget->window,
- widget->style->black_gc,
- x, y,
- priv->layout,
- text_color,
- base_color);
- gdk_color_free (link_color);
- gdk_color_free (visited_link_color);
-
- gdk_gc_set_clip_region (widget->style->black_gc, NULL);
- cairo_region_destroy (clip);
- }
if (focus_link && gtk_widget_has_focus (widget))
{
@@ -4535,6 +4570,7 @@ gtk_label_grab_focus (GtkWidget *widget)
link = priv->select_info->links->data;
priv->select_info->selection_anchor = link->start;
priv->select_info->selection_end = link->start;
+ gtk_label_update_layout_attributes (label);
}
}
}
@@ -4561,6 +4597,7 @@ gtk_label_focus (GtkWidget *widget,
focus_link = l->data;
info->selection_anchor = focus_link->start;
info->selection_end = focus_link->start;
+ gtk_label_update_layout_attributes (label);
}
}
@@ -4638,6 +4675,7 @@ gtk_label_focus (GtkWidget *widget,
focus_link = l->data;
info->selection_anchor = focus_link->start;
info->selection_end = focus_link->start;
+ gtk_label_update_layout_attributes (label);
gtk_widget_queue_draw (widget);
return TRUE;
@@ -4756,6 +4794,20 @@ gtk_label_button_press (GtkWidget *widget,
}
static gboolean
+gtk_label_focus_out (GtkWidget *widget,
+ GdkEventFocus *event)
+{
+ GtkLabel *label = GTK_LABEL (widget);
+
+ gtk_label_update_layout_attributes (label);
+
+ if (GTK_WIDGET_CLASS (gtk_label_parent_class)->focus_out_event)
+ return GTK_WIDGET_CLASS (gtk_label_parent_class)->focus_out_event (widget, event);
+ else
+ return FALSE;
+}
+
+static gboolean
gtk_label_button_release (GtkWidget *widget,
GdkEventButton *event)
@@ -5350,6 +5402,7 @@ clear_text_callback (GtkClipboard *clipboard,
{
priv->select_info->selection_anchor = priv->select_info->selection_end;
+ gtk_label_update_layout_attributes (label);
gtk_widget_queue_draw (GTK_WIDGET (label));
}
}
@@ -5404,6 +5457,8 @@ gtk_label_select_region_index (GtkLabel *label,
gtk_clipboard_clear (clipboard);
}
+ gtk_label_update_layout_attributes (label);
+
gtk_widget_queue_draw (GTK_WIDGET (label));
g_object_freeze_notify (G_OBJECT (label));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]