[gnome-builder/wip/slaf/spellcheck-sidebar: 4/33] spellchecker: use a match bubble
- From: Sébastien Lafargue <slafargue src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/slaf/spellcheck-sidebar: 4/33] spellchecker: use a match bubble
- Date: Wed, 11 Jan 2017 20:47:10 +0000 (UTC)
commit 8d7b7e06378ef8130465c5b84667e662a62b1cb1
Author: Sébastien Lafargue <slafargue gnome org>
Date: Fri Dec 16 20:59:14 2016 +0100
spellchecker: use a match bubble
Misspelled text selection is replaced by a
drawn bubble.
colors can be found in style schemes:
For example in Builder.xml:
<style name="misspelled-match" foreground="black" background="selection1"/>
data/style-schemes/builder-dark.xml | 3 +
data/style-schemes/builder.xml | 3 +
libide/editor/ide-editor-spell-navigator.c | 8 +-
libide/sourceview/ide-source-view.c | 162 ++++++++++++++++++++++++++++
libide/sourceview/ide-source-view.h | 3 +
5 files changed, 177 insertions(+), 2 deletions(-)
---
diff --git a/data/style-schemes/builder-dark.xml b/data/style-schemes/builder-dark.xml
index 668f085..ec0e382 100644
--- a/data/style-schemes/builder-dark.xml
+++ b/data/style-schemes/builder-dark.xml
@@ -96,6 +96,9 @@
<!-- Search Shadow -->
<style name="search-shadow" background="#rgba(0,0,0,0.4)"/>
+ <!-- Spellchecker Matching -->
+ <style name="misspelled-match" foreground="#000000" background="#b3d4fc"/>
+
<!-- Comments -->
<style name="def:comment" foreground="aluminium4"/>
<style name="def:shebang" foreground="aluminium4" bold="true"/>
diff --git a/data/style-schemes/builder.xml b/data/style-schemes/builder.xml
index 16578e5..4d0ffa0 100644
--- a/data/style-schemes/builder.xml
+++ b/data/style-schemes/builder.xml
@@ -107,6 +107,9 @@
<!-- Search Shadow -->
<style name="search-shadow" background="#rgba(0,0,0,0.2)"/>
+ <!-- Spellchecker Matching -->
+ <style name="misspelled-match" foreground="#000000" background="selection1"/>
+
<!-- Quick Highlight Plugin -->
<style name="quick-highlight" background="#rgba(221,74,104,.15)"/>
diff --git a/libide/editor/ide-editor-spell-navigator.c b/libide/editor/ide-editor-spell-navigator.c
index 916d953..e4a5fdd 100644
--- a/libide/editor/ide-editor-spell-navigator.c
+++ b/libide/editor/ide-editor-spell-navigator.c
@@ -143,6 +143,9 @@ ide_editor_spell_navigator_dispose (GObject *object)
{
IdeEditorSpellNavigator *self = (IdeEditorSpellNavigator *)object;
+ ide_source_view_set_misspelled_word (IDE_SOURCE_VIEW (self->view), NULL, NULL);
+ gtk_widget_queue_draw (GTK_WIDGET (self->view));
+
g_clear_object (&self->view);
g_hash_table_unref (self->words_count);
@@ -290,12 +293,13 @@ select_misspelled_word (IdeEditorSpellNavigator *self)
gtk_text_buffer_get_iter_at_mark (self->buffer, &word_start, self->word_start);
gtk_text_buffer_get_iter_at_mark (self->buffer, &word_end, self->word_end);
- gtk_text_buffer_select_range (self->buffer, &word_start, &word_end);
+ ide_source_view_set_misspelled_word (IDE_SOURCE_VIEW (self->view), &word_start, &word_end);
+ gtk_widget_queue_draw (GTK_WIDGET (self->view));
g_return_if_fail (gtk_text_view_get_buffer (self->view) == self->buffer);
gtk_text_view_scroll_to_mark (self->view,
- gtk_text_buffer_get_insert (self->buffer),
+ self->word_start,
0.25,
FALSE,
0.0,
diff --git a/libide/sourceview/ide-source-view.c b/libide/sourceview/ide-source-view.c
index 7d2c24a..0967cf7 100644
--- a/libide/sourceview/ide-source-view.c
+++ b/libide/sourceview/ide-source-view.c
@@ -152,6 +152,10 @@ typedef struct
GdkRGBA bubble_color2;
GdkRGBA search_shadow_rgba;
GdkRGBA snippet_area_background_rgba;
+ GdkRGBA spellchecker_bubble_bg_color1;
+ GdkRGBA spellchecker_bubble_bg_color2;
+ GdkRGBA spellchecker_bubble_fg;
+ GtkTextTag *spellchecker_bubble_tag;
guint font_scale;
@@ -164,6 +168,9 @@ typedef struct
GtkTextMark *definition_highlight_start_mark;
GtkTextMark *definition_highlight_end_mark;
+ GtkTextMark *misspelled_word_begin_mark;
+ GtkTextMark *misspelled_word_end_mark;
+
GRegex *include_regex;
guint auto_indent : 1;
@@ -987,8 +994,11 @@ ide_source_view__buffer_notify_style_scheme_cb (IdeSourceView *self,
GtkSourceStyle *search_match_style = NULL;
GtkSourceStyle *search_shadow_style = NULL;
GtkSourceStyle *snippet_area_style = NULL;
+ GtkSourceStyle *spellchecker_match_style = NULL;
g_autofree gchar *snippet_background = NULL;
g_autofree gchar *search_shadow_background = NULL;
+ GdkRGBA spellchecker_bubble_fg;
+ GdkRGBA spellchecker_bubble_bg;
g_assert (IDE_IS_SOURCE_VIEW (self));
g_assert (IDE_IS_BUFFER (buffer));
@@ -999,6 +1009,7 @@ ide_source_view__buffer_notify_style_scheme_cb (IdeSourceView *self,
search_match_style = gtk_source_style_scheme_get_style (scheme, "search-match");
search_shadow_style = gtk_source_style_scheme_get_style (scheme, "search-shadow");
snippet_area_style = gtk_source_style_scheme_get_style (scheme, "snippet::area");
+ spellchecker_match_style = gtk_source_style_scheme_get_style (scheme, "misspelled-match");
}
if (search_match_style)
@@ -1038,6 +1049,42 @@ ide_source_view__buffer_notify_style_scheme_cb (IdeSourceView *self,
gdk_rgba_parse (&priv->snippet_area_background_rgba, "#204a87");
priv->snippet_area_background_rgba.alpha = 0.1;
}
+
+ if (spellchecker_match_style)
+ {
+ g_autofree gchar *background = NULL;
+ g_autofree gchar *foreground = NULL;
+ gboolean ret = TRUE;
+
+ g_object_get (spellchecker_match_style, "background", &background, NULL);
+ g_object_get (spellchecker_match_style, "foreground", &foreground, NULL);
+
+ if (!ide_str_empty0 (background))
+ ret = gdk_rgba_parse (&spellchecker_bubble_bg, background);
+
+ if (!ret)
+ gdk_rgba_parse (&spellchecker_bubble_bg, "#ADD8E6");
+
+ ret = TRUE;
+ if (!ide_str_empty0 (foreground))
+ ret = gdk_rgba_parse (&spellchecker_bubble_fg, foreground);
+
+ if (!ret)
+ gdk_rgba_parse (&spellchecker_bubble_fg, "#0000FF");
+ }
+ else
+ {
+ gdk_rgba_parse (&spellchecker_bubble_bg, "#ADD8E6");
+ gdk_rgba_parse (&spellchecker_bubble_fg, "#0000000");
+ }
+
+ priv->spellchecker_bubble_bg_color1 = spellchecker_bubble_bg;
+ ide_rgba_shade (&spellchecker_bubble_bg, &priv->spellchecker_bubble_bg_color2, 0.8);
+
+ priv->spellchecker_bubble_tag = gtk_text_buffer_create_tag (GTK_TEXT_BUFFER (priv->buffer), NULL,
+ "foreground-rgba", &spellchecker_bubble_fg,
+ "background-rgba",
&priv->spellchecker_bubble_bg_color1,
+ NULL);
}
static void
@@ -4768,6 +4815,59 @@ ide_source_view_draw_search_bubbles (IdeSourceView *self,
cairo_region_destroy (match_region);
}
+void
+ide_source_view_draw_spellchecking_bubble (IdeSourceView *self,
+ cairo_t *cr)
+{
+ IdeSourceViewPrivate *priv = ide_source_view_get_instance_private (self);
+ GtkTextView *text_view = (GtkTextView *)self;
+ cairo_region_t *clip_region;
+ cairo_rectangle_int_t rect;
+ GdkRectangle area;
+ GdkRectangle begin_rect;
+ GdkRectangle end_rect;
+ GtkTextIter begin;
+ GtkTextIter end;
+
+ g_return_if_fail (IDE_IS_SOURCE_VIEW (self));
+ g_return_if_fail (GTK_IS_TEXT_VIEW (text_view));
+ g_return_if_fail (cr);
+
+ gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->buffer), &begin,
priv->misspelled_word_begin_mark);
+ gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->buffer), &end, priv->misspelled_word_end_mark);
+
+ if (gtk_text_iter_get_line (&begin) == gtk_text_iter_get_line (&end))
+ {
+ if (!gdk_cairo_get_clip_rectangle (cr, &area))
+ gtk_widget_get_allocation (GTK_WIDGET (self), &area);
+
+ clip_region = cairo_region_create_rectangle (&area);
+
+ gtk_text_view_get_iter_location (text_view, &begin, &begin_rect);
+ gtk_text_view_buffer_to_window_coords (text_view, GTK_TEXT_WINDOW_TEXT,
+ begin_rect.x, begin_rect.y,
+ &begin_rect.x, &begin_rect.y);
+ gtk_text_view_get_iter_location (text_view, &end, &end_rect);
+ gtk_text_view_buffer_to_window_coords (text_view, GTK_TEXT_WINDOW_TEXT,
+ end_rect.x, end_rect.y,
+ &end_rect.x, &end_rect.y);
+
+ rect.x = begin_rect.x;
+ rect.y = begin_rect.y;
+ rect.width = end_rect.x - begin_rect.x;
+ rect.height = MAX (begin_rect.height, end_rect.height);
+
+ cairo_region_subtract_rectangle (clip_region, &rect);
+ gdk_cairo_region (cr, clip_region);
+ cairo_clip (cr);
+
+ draw_bezel (cr, &rect, 3, &priv->spellchecker_bubble_bg_color2);
+ draw_bezel (cr, &rect, 2, &priv->spellchecker_bubble_bg_color1);
+
+ cairo_region_destroy (clip_region);
+ }
+}
+
static void
ide_source_view_real_draw_layer (GtkTextView *text_view,
GtkTextViewLayer layer,
@@ -4796,6 +4896,13 @@ ide_source_view_real_draw_layer (GtkTextView *text_view,
ide_source_view_draw_search_bubbles (self, cr);
cairo_restore (cr);
}
+
+ if (priv->misspelled_word_begin_mark != NULL && priv->misspelled_word_end_mark != NULL)
+ {
+ cairo_save (cr);
+ ide_source_view_draw_spellchecking_bubble (self, cr);
+ cairo_restore (cr);
+ }
}
}
@@ -5866,6 +5973,7 @@ ide_source_view_finalize (GObject *object)
g_clear_pointer (&priv->snippets, g_queue_free);
g_clear_pointer (&priv->include_regex, g_regex_unref);
g_clear_pointer (&priv->saved_search_text, g_free);
+ g_clear_object (&priv->spellchecker_bubble_tag);
EGG_COUNTER_DEC (instances);
@@ -8490,3 +8598,57 @@ ide_source_view_get_current_snippet (IdeSourceView *self)
return g_queue_peek_head (priv->snippets);
}
+
+/* Set begin and end to NULL to remove the misspelled word marks */
+void
+ide_source_view_set_misspelled_word (IdeSourceView *self,
+ GtkTextIter *begin,
+ GtkTextIter *end)
+{
+ IdeSourceViewPrivate *priv = ide_source_view_get_instance_private (self);
+
+ g_return_if_fail (IDE_IS_SOURCE_VIEW (self));
+ g_return_if_fail ((begin == NULL && end == NULL) || (begin != NULL && end != NULL));
+
+ if (priv->misspelled_word_begin_mark != NULL && priv->misspelled_word_end_mark != NULL)
+ {
+ GtkTextIter previous_begin;
+ GtkTextIter previous_end;
+
+ gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->buffer),
+ &previous_begin,
+ priv->misspelled_word_begin_mark);
+
+ gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->buffer),
+ &previous_end,
+ priv->misspelled_word_end_mark);
+
+ gtk_text_buffer_remove_tag (GTK_TEXT_BUFFER (priv->buffer),
+ priv->spellchecker_bubble_tag,
+ &previous_begin, &previous_end);
+ }
+
+ if (begin == NULL)
+ {
+ if (priv->misspelled_word_begin_mark != NULL)
+ {
+ gtk_text_buffer_delete_mark (GTK_TEXT_BUFFER (priv->buffer), priv->misspelled_word_begin_mark);
+ priv->misspelled_word_begin_mark = NULL;
+ }
+
+ if (priv->misspelled_word_end_mark != NULL)
+ {
+ gtk_text_buffer_delete_mark (GTK_TEXT_BUFFER (priv->buffer), priv->misspelled_word_end_mark);
+ priv->misspelled_word_end_mark = NULL;
+ }
+ }
+ else
+ {
+ priv->misspelled_word_begin_mark = gtk_text_buffer_create_mark (GTK_TEXT_BUFFER (priv->buffer),
+ NULL, begin, TRUE);
+ priv->misspelled_word_end_mark = gtk_text_buffer_create_mark (GTK_TEXT_BUFFER (priv->buffer),
+ NULL, end, TRUE);
+
+ gtk_text_buffer_apply_tag (GTK_TEXT_BUFFER (priv->buffer), priv->spellchecker_bubble_tag, begin, end);
+ }
+}
diff --git a/libide/sourceview/ide-source-view.h b/libide/sourceview/ide-source-view.h
index 7ea83c4..8684bfe 100644
--- a/libide/sourceview/ide-source-view.h
+++ b/libide/sourceview/ide-source-view.h
@@ -373,6 +373,9 @@ void ide_source_view_set_highlight_current_line(IdeSource
gboolean
highlight_current_line);
void ide_source_view_set_insert_matching_brace (IdeSourceView *self,
gboolean
insert_matching_brace);
+void ide_source_view_set_misspelled_word (IdeSourceView *self,
+ GtkTextIter *start,
+ GtkTextIter *end);
void ide_source_view_set_overwrite_braces (IdeSourceView *self,
gboolean
overwrite_braces);
void ide_source_view_set_rubberband_search (IdeSourceView *self,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]