[gtksourceview/wip/search] search: async highlighting
- From: Sébastien Wilmet <swilmet src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtksourceview/wip/search] search: async highlighting
- Date: Wed, 19 Jun 2013 16:47:43 +0000 (UTC)
commit fe936ebf28ca33479a11b21cfc79c6168cc584a6
Author: Sébastien Wilmet <swilmet gnome org>
Date: Wed Jun 19 18:33:49 2013 +0200
search: async highlighting
gtksourceview/gtksourcesearch.c | 156 ++++++++++++++++++++++++++++-----------
1 files changed, 112 insertions(+), 44 deletions(-)
---
diff --git a/gtksourceview/gtksourcesearch.c b/gtksourceview/gtksourcesearch.c
index ad2e84f..7aa2beb 100644
--- a/gtksourceview/gtksourcesearch.c
+++ b/gtksourceview/gtksourcesearch.c
@@ -36,8 +36,16 @@ struct _GtkSourceSearchPrivate
gint text_nb_lines;
GtkTextSearchFlags flags;
- /* Contains the remaining region to highlight */
- GtkTextRegion *region;
+ /* The search occurrences are highlighted when they become visible. It
+ * would be useless to highlight all the buffer, if only a small part is
+ * visible, which is usually the case.
+ * region_not_highlighted is NULL if the search is disabled.
+ * region_to_highlight contains the region to highlight later (in an
+ * idle callback), so the highlighting is asynchronous.
+ */
+ GtkTextRegion *region_not_highlighted;
+ GtkTextRegion *region_to_highlight;
+ gulong idle_highlight_id;
GtkTextTag *found_tag;
};
@@ -115,10 +123,22 @@ text_tag_set_highest_priority (GtkTextTag *tag,
static void
clear_search (GtkSourceSearch *search)
{
- if (search->priv->region != NULL)
+ if (search->priv->region_not_highlighted != NULL)
+ {
+ gtk_text_region_destroy (search->priv->region_not_highlighted, TRUE);
+ search->priv->region_not_highlighted = NULL;
+ }
+
+ if (search->priv->region_to_highlight != NULL)
+ {
+ gtk_text_region_destroy (search->priv->region_to_highlight, TRUE);
+ search->priv->region_to_highlight = NULL;
+ }
+
+ if (search->priv->idle_highlight_id != 0)
{
- gtk_text_region_destroy (search->priv->region, TRUE);
- search->priv->region = NULL;
+ g_source_remove (search->priv->idle_highlight_id);
+ search->priv->idle_highlight_id = 0;
}
if (search->priv->found_tag != NULL)
@@ -136,14 +156,14 @@ clear_search (GtkSourceSearch *search)
}
static void
-add_subregion (GtkSourceSearch *search,
- GtkTextIter *subregion_start,
- GtkTextIter *subregion_end)
+add_not_highlighted_subregion (GtkSourceSearch *search,
+ GtkTextIter *subregion_start,
+ GtkTextIter *subregion_end)
{
GtkTextIter start = *subregion_start;
GtkTextIter end = *subregion_end;
- if (search->priv->region == NULL)
+ if (search->priv->region_not_highlighted == NULL)
{
return;
}
@@ -158,7 +178,7 @@ add_subregion (GtkSourceSearch *search,
gtk_text_iter_forward_to_line_end (&end);
}
- gtk_text_region_add (search->priv->region, &start, &end);
+ gtk_text_region_add (search->priv->region_not_highlighted, &start, &end);
gtk_text_iter_backward_lines (&start, search->priv->text_nb_lines);
gtk_text_iter_forward_lines (&end, search->priv->text_nb_lines);
@@ -184,10 +204,10 @@ update (GtkSourceSearch *search)
return;
}
- search->priv->region = gtk_text_region_new (search->priv->buffer);
+ search->priv->region_not_highlighted = gtk_text_region_new (search->priv->buffer);
gtk_text_buffer_get_bounds (search->priv->buffer, &start, &end);
- add_subregion (search, &start, &end);
+ add_not_highlighted_subregion (search, &start, &end);
}
static void
@@ -204,7 +224,7 @@ insert_text_after_cb (GtkSourceSearch *search,
gtk_text_iter_backward_chars (&start,
g_utf8_strlen (text, length));
- add_subregion (search, &start, &end);
+ add_not_highlighted_subregion (search, &start, &end);
}
static void
@@ -212,7 +232,7 @@ delete_range_after_cb (GtkSourceSearch *search,
GtkTextIter *start,
GtkTextIter *end)
{
- add_subregion (search, start, end);
+ add_not_highlighted_subregion (search, start, end);
}
static void
@@ -242,12 +262,7 @@ _gtk_source_search_dispose (GObject *object)
{
GtkSourceSearch *search = GTK_SOURCE_SEARCH (object);
- if (search->priv->region != NULL)
- {
- gtk_text_region_destroy (search->priv->region, TRUE);
- search->priv->region = NULL;
- }
-
+ clear_search (search);
g_clear_object (&search->priv->buffer);
G_OBJECT_CLASS (_gtk_source_search_parent_class)->dispose (object);
@@ -425,6 +440,15 @@ highlight_subregion (GtkSourceSearch *search,
iter = *start;
+ if (search->priv->region_not_highlighted != NULL)
+ {
+ gtk_text_region_subtract (search->priv->region_not_highlighted, start, end);
+ }
+ else
+ {
+ g_warning ("search: region_not_highlighted is NULL");
+ }
+
if (gtk_text_iter_is_end (end))
{
end = NULL;
@@ -455,6 +479,50 @@ highlight_subregion (GtkSourceSearch *search,
} while (found);
}
+static void
+highlight_region (GtkSourceSearch *search,
+ GtkTextRegion *region_to_highlight)
+{
+ gint nb_subregions = gtk_text_region_subregions (region_to_highlight);
+ GtkTextIter start_search;
+ GtkTextIter end_search;
+
+ if (nb_subregions == 0)
+ {
+ return;
+ }
+
+ gtk_text_region_nth_subregion (region_to_highlight,
+ 0,
+ &start_search,
+ NULL);
+
+ gtk_text_region_nth_subregion (region_to_highlight,
+ nb_subregions - 1,
+ NULL,
+ &end_search);
+
+ gtk_text_iter_order (&start_search, &end_search);
+
+ highlight_subregion (search, &start_search, &end_search);
+}
+
+static gboolean
+idle_highlight_cb (GtkSourceSearch *search)
+{
+ search->priv->idle_highlight_id = 0;
+
+ if (search->priv->region_to_highlight != NULL)
+ {
+ highlight_region (search, search->priv->region_to_highlight);
+
+ gtk_text_region_destroy (search->priv->region_to_highlight, TRUE);
+ search->priv->region_to_highlight = NULL;
+ }
+
+ return FALSE;
+}
+
void
_gtk_source_search_update_highlight (GtkSourceSearch *search,
const GtkTextIter *start,
@@ -462,20 +530,17 @@ _gtk_source_search_update_highlight (GtkSourceSearch *search,
gboolean synchronous)
{
GtkTextRegion *region_to_highlight;
- GtkTextIter start_search;
- GtkTextIter end_search;
- gint nb_subregions;
g_return_if_fail (GTK_SOURCE_IS_SEARCH (search));
g_return_if_fail (start != NULL);
g_return_if_fail (end != NULL);
- if (dispose_has_run (search) || search->priv->region == NULL)
+ if (dispose_has_run (search) || search->priv->region_not_highlighted == NULL)
{
return;
}
- region_to_highlight = gtk_text_region_intersect (search->priv->region,
+ region_to_highlight = gtk_text_region_intersect (search->priv->region_not_highlighted,
start,
end);
@@ -484,25 +549,28 @@ _gtk_source_search_update_highlight (GtkSourceSearch *search,
return;
}
- nb_subregions = gtk_text_region_subregions (region_to_highlight);
- g_assert (nb_subregions >= 1);
-
- gtk_text_region_nth_subregion (region_to_highlight,
- 0,
- &start_search,
- NULL);
-
- gtk_text_region_nth_subregion (region_to_highlight,
- nb_subregions - 1,
- NULL,
- &end_search);
-
- gtk_text_iter_order (&start_search, &end_search);
-
- highlight_subregion (search, &start_search, &end_search);
+ if (synchronous)
+ {
+ highlight_region (search, region_to_highlight);
+ gtk_text_region_destroy (region_to_highlight, TRUE);
+ }
+ else
+ {
+ if (search->priv->region_to_highlight != NULL)
+ {
+ /* We destroy the old region to highlight, because it is
+ * now useless to highlight it, the visible region on
+ * the screen is the new region.
+ */
+ gtk_text_region_destroy (search->priv->region_to_highlight, TRUE);
+ }
- /* Remove the just highlighted region */
- gtk_text_region_subtract (search->priv->region, start, end);
+ search->priv->region_to_highlight = region_to_highlight;
- gtk_text_region_destroy (region_to_highlight, TRUE);
+ if (search->priv->idle_highlight_id == 0)
+ {
+ search->priv->idle_highlight_id =
+ g_idle_add ((GSourceFunc)idle_highlight_cb, search);
+ }
+ }
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]