[gtk+] Improve selection/arrow key behaviour in GtkTextView



commit c0d8b71bc5d4b404727b03053d27eaf35e7309b7
Author: Matthias Clasen <mclasen redhat com>
Date:   Mon Dec 21 11:29:12 2009 -0500

    Improve selection/arrow key behaviour in GtkTextView
    
    This patch makes the text view behave more similar to entries.
    Patch by Michael Natterer, see bug 50942

 gtk/gtktextview.c |   52 ++++++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 44 insertions(+), 8 deletions(-)
---
diff --git a/gtk/gtktextview.c b/gtk/gtktextview.c
index f7f3218..9a0f05b 100644
--- a/gtk/gtktextview.c
+++ b/gtk/gtktextview.c
@@ -337,6 +337,7 @@ static void gtk_text_view_paste_done_handler     (GtkTextBuffer     *buffer,
 static void gtk_text_view_get_cursor_location    (GtkTextView       *text_view,
 						  GdkRectangle      *pos);
 static void gtk_text_view_get_virtual_cursor_pos (GtkTextView       *text_view,
+                                                  GtkTextIter       *cursor,
                                                   gint              *x,
                                                   gint              *y);
 static void gtk_text_view_set_virtual_cursor_pos (GtkTextView       *text_view,
@@ -5035,6 +5036,7 @@ gtk_text_view_move_cursor_internal (GtkTextView     *text_view,
 {
   GtkTextIter insert;
   GtkTextIter newplace;
+  gboolean cancel_selection = FALSE;
   gint cursor_x_pos = 0;
   GtkDirectionType leave_direction = -1;
 
@@ -5111,20 +5113,46 @@ gtk_text_view_move_cursor_internal (GtkTextView     *text_view,
 
   gtk_text_buffer_get_iter_at_mark (get_buffer (text_view), &insert,
                                     gtk_text_buffer_get_insert (get_buffer (text_view)));
+
+  if (! extend_selection)
+    {
+      GtkTextIter sel_bound;
+
+      gtk_text_buffer_get_iter_at_mark (get_buffer (text_view), &sel_bound,
+                                        gtk_text_buffer_get_selection_bound (get_buffer (text_view)));
+
+      /* if we move forward, assume the cursor is at the end of the selection;
+       * if we move backward, assume the cursor is at the start
+       */
+      if (count > 0)
+        gtk_text_iter_order (&sel_bound, &insert);
+      else
+        gtk_text_iter_order (&insert, &sel_bound);
+
+      /* if we actually have a selection, just move *to* the beginning/end
+       * of the selection and not *from* there on LOGICAL_POSITIONS
+       * and VISUAL_POSITIONS movement
+       */
+      if (! gtk_text_iter_equal (&sel_bound, &insert))
+        cancel_selection = TRUE;
+    }
+
   newplace = insert;
 
   if (step == GTK_MOVEMENT_DISPLAY_LINES)
-    gtk_text_view_get_virtual_cursor_pos (text_view, &cursor_x_pos, NULL);
+    gtk_text_view_get_virtual_cursor_pos (text_view, &insert, &cursor_x_pos, NULL);
 
   switch (step)
     {
     case GTK_MOVEMENT_LOGICAL_POSITIONS:
-      gtk_text_iter_forward_visible_cursor_positions (&newplace, count);
+      if (! cancel_selection)
+        gtk_text_iter_forward_visible_cursor_positions (&newplace, count);
       break;
 
     case GTK_MOVEMENT_VISUAL_POSITIONS:
-      gtk_text_layout_move_iter_visually (text_view->layout,
-                                          &newplace, count);
+      if (! cancel_selection)
+        gtk_text_layout_move_iter_visually (text_view->layout,
+                                            &newplace, count);
       break;
 
     case GTK_MOVEMENT_WORDS:
@@ -5233,7 +5261,7 @@ gtk_text_view_move_cursor_internal (GtkTextView     *text_view,
           g_signal_emit_by_name (text_view, "move-focus", leave_direction);
         }
     }
-  else
+  else if (! cancel_selection)
     {
       gtk_widget_error_bell (GTK_WIDGET (text_view));
     }
@@ -5386,7 +5414,7 @@ gtk_text_view_scroll_pages (GtkTextView *text_view,
     }
   else
     {
-      gtk_text_view_get_virtual_cursor_pos (text_view, &cursor_x_pos, &cursor_y_pos);
+      gtk_text_view_get_virtual_cursor_pos (text_view, NULL, &cursor_x_pos, &cursor_y_pos);
 
       oldval = adj->value;
       newval = adj->value;
@@ -5467,7 +5495,7 @@ gtk_text_view_scroll_hpages (GtkTextView *text_view,
     }
   else
     {
-      gtk_text_view_get_virtual_cursor_pos (text_view, &cursor_x_pos, &cursor_y_pos);
+      gtk_text_view_get_virtual_cursor_pos (text_view, NULL, &cursor_x_pos, &cursor_y_pos);
 
       oldval = adj->value;
       newval = adj->value;
@@ -7484,14 +7512,22 @@ gtk_text_view_get_cursor_location  (GtkTextView   *text_view,
 
 static void
 gtk_text_view_get_virtual_cursor_pos (GtkTextView *text_view,
+                                      GtkTextIter *cursor,
                                       gint        *x,
                                       gint        *y)
 {
+  GtkTextIter insert;
   GdkRectangle pos;
 
+  if (cursor)
+    insert = *cursor;
+  else
+    gtk_text_buffer_get_iter_at_mark (get_buffer (text_view), &insert,
+                                      gtk_text_buffer_get_insert (get_buffer (text_view)));
+
   if ((x && text_view->virtual_cursor_x == -1) ||
       (y && text_view->virtual_cursor_y == -1))
-    gtk_text_view_get_cursor_location (text_view, &pos);
+    gtk_text_layout_get_cursor_locations (text_view->layout, &insert, &pos, NULL);
 
   if (x)
     {



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]