[gspell/wip/entry-context-menu: 2/3] EntryUtils: add function to get char position at GdkEventButton
- From: Sébastien Wilmet <swilmet src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gspell/wip/entry-context-menu: 2/3] EntryUtils: add function to get char position at GdkEventButton
- Date: Fri, 25 Nov 2016 21:40:02 +0000 (UTC)
commit ec81d3b28078744a590d107ed33ed50e56e8cd3b
Author: Sébastien Wilmet <swilmet gnome org>
Date: Fri Nov 25 18:45:05 2016 +0100
EntryUtils: add function to get char position at GdkEventButton
gspell/gspell-entry-utils.c | 72 +++++++++++++++++++++++++++++++++++++++++++
gspell/gspell-entry-utils.h | 10 ++++--
2 files changed, 79 insertions(+), 3 deletions(-)
---
diff --git a/gspell/gspell-entry-utils.c b/gspell/gspell-entry-utils.c
index 5ab8342..7b9eb86 100644
--- a/gspell/gspell-entry-utils.c
+++ b/gspell/gspell-entry-utils.c
@@ -149,4 +149,76 @@ _gspell_entry_utils_get_words (GtkEntry *entry)
return g_slist_reverse (list);
}
+static gint
+get_layout_index (GtkEntry *entry,
+ gint x)
+{
+ PangoLayout *layout;
+ PangoLayoutLine *line;
+ gint layout_index; /* in bytes */
+ gint trailing_chars;
+ const gchar *layout_text;
+ const gchar *pos_in_layout_text;
+ gint layout_text_byte_length;
+ gint max_trailing_chars;
+
+ layout = gtk_entry_get_layout (entry);
+ line = pango_layout_get_line_readonly (layout, 0);
+
+ pango_layout_line_x_to_index (line,
+ x * PANGO_SCALE,
+ &layout_index,
+ &trailing_chars);
+
+ layout_text = pango_layout_get_text (layout);
+
+ /* Performance should not be a problem here, it's better too much
+ * security than not enough.
+ */
+ layout_text_byte_length = strlen (layout_text);
+ if (layout_index >= layout_text_byte_length)
+ {
+ return layout_text_byte_length;
+ }
+
+ if (trailing_chars == 0)
+ {
+ return layout_index;
+ }
+
+ pos_in_layout_text = layout_text + layout_index;
+ max_trailing_chars = g_utf8_strlen (pos_in_layout_text, -1);
+ trailing_chars = MIN (trailing_chars, max_trailing_chars);
+
+ pos_in_layout_text = g_utf8_offset_to_pointer (pos_in_layout_text, trailing_chars);
+
+ return pos_in_layout_text - layout_text;
+}
+
+/* The return value is in characters, not bytes. And a position suitable for the
+ * text in the GtkEntryBuffer, i.e. without the preedit string.
+ */
+gint
+_gspell_entry_utils_get_char_position_at_event (GtkEntry *entry,
+ GdkEventButton *event)
+{
+ gint scroll_offset;
+ gint x;
+ gint layout_index; /* in bytes */
+ gint text_index; /* in bytes */
+ const gchar *buffer_text;
+
+ g_object_get (entry,
+ "scroll-offset", &scroll_offset,
+ NULL);
+
+ x = event->x + scroll_offset;
+
+ layout_index = get_layout_index (entry, x);
+ text_index = gtk_entry_layout_index_to_text_index (entry, layout_index);
+
+ buffer_text = gtk_entry_get_text (entry);
+ return g_utf8_pointer_to_offset (buffer_text, buffer_text + text_index);
+}
+
/* ex:set ts=8 noet: */
diff --git a/gspell/gspell-entry-utils.h b/gspell/gspell-entry-utils.h
index 813b5b2..7370f81 100644
--- a/gspell/gspell-entry-utils.h
+++ b/gspell/gspell-entry-utils.h
@@ -43,13 +43,17 @@ struct _GspellEntryWord
};
G_GNUC_INTERNAL
-GspellEntryWord *_gspell_entry_word_new (void);
+GspellEntryWord *_gspell_entry_word_new (void);
G_GNUC_INTERNAL
-void _gspell_entry_word_free (gpointer data);
+void _gspell_entry_word_free (gpointer data);
G_GNUC_INTERNAL
-GSList * _gspell_entry_utils_get_words (GtkEntry *entry);
+GSList * _gspell_entry_utils_get_words (GtkEntry *entry);
+
+G_GNUC_INTERNAL
+gint _gspell_entry_utils_get_char_position_at_event (GtkEntry *entry,
+ GdkEventButton *event);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]