[gtk+/touch-selections: 3/7] texthandle: Set a bigger input shape, covering the line height



commit cb37fa5b807948fa554fd84ed8068fbdb0cb604e
Author: Carlos Garnacho <carlos lanedo com>
Date:   Fri Jan 11 17:22:02 2013 +0100

    texthandle: Set a bigger input shape, covering the line height
    
    Now, even if the handles being rendered are small, the handle touch
    input shape will be as wide as the visible part of the rendered asset, and
    high enough to cover both the handle and the height of the line where
    the selection bound is.
    
    Also, make handles have the same virtual distance to the line top/bottom
    when a drag starts, so the handle doesn't jump to another line after a
    too short threshold.

 gtk/gtktexthandle.c |   33 ++++++++++++++++++++++++++++++---
 1 files changed, 30 insertions(+), 3 deletions(-)
---
diff --git a/gtk/gtktexthandle.c b/gtk/gtktexthandle.c
index d1d5798..ddc520c 100644
--- a/gtk/gtktexthandle.c
+++ b/gtk/gtktexthandle.c
@@ -106,6 +106,9 @@ _gtk_text_handle_draw (GtkTextHandle         *handle,
   cairo_set_source_rgba (cr, 0, 0, 0, 0);
   cairo_paint (cr);
 
+  if (pos == GTK_TEXT_HANDLE_POSITION_SELECTION_END)
+    cairo_translate (cr, 0, priv->windows[pos].pointing_to.height);
+
   gtk_style_context_save (priv->style_context);
   gtk_style_context_add_class (priv->style_context,
                                GTK_STYLE_CLASS_CURSOR_HANDLE);
@@ -136,6 +139,7 @@ _gtk_text_handle_update_shape (GtkTextHandle         *handle,
                                GtkTextHandlePosition  pos)
 {
   GtkTextHandlePrivate *priv;
+  cairo_rectangle_int_t rect;
   cairo_surface_t *surface;
   cairo_region_t *region;
   cairo_t *cr;
@@ -159,6 +163,15 @@ _gtk_text_handle_update_shape (GtkTextHandle         *handle,
   else
     gdk_window_shape_combine_region (window, region, 0, 0);
 
+  cairo_region_get_extents (region, &rect);
+  cairo_region_destroy (region);
+
+  /* Preserve x/width, but extend input shape
+   * vertically to all window height */
+  rect.y = 0;
+  rect.height = gdk_window_get_height (window);
+  region = cairo_region_create_rectangle (&rect);
+
   gdk_window_input_shape_combine_region (window, region, 0, 0);
 
   cairo_surface_destroy (surface);
@@ -274,6 +287,8 @@ gtk_text_handle_widget_event (GtkWidget     *widget,
       if (pos == GTK_TEXT_HANDLE_POSITION_SELECTION_START)
         y += height;
 
+      y += priv->windows[pos].pointing_to.height / 2;
+
       g_signal_emit (handle, signals[HANDLE_DRAGGED], 0, pos, x, y);
     }
 
@@ -302,11 +317,10 @@ _gtk_text_handle_update_window_state (GtkTextHandle         *handle,
       y = handle_window->pointing_to.y;
       _gtk_text_handle_get_size (handle, &width, &height);
 
-      if (pos == GTK_TEXT_HANDLE_POSITION_CURSOR)
-        y += handle_window->pointing_to.height;
-      else
+      if (pos != GTK_TEXT_HANDLE_POSITION_CURSOR)
         y -= height;
 
+      height += handle_window->pointing_to.height;
       x -= width / 2;
 
       gdk_window_move_resize (handle_window->window, x, y, width, height);
@@ -611,6 +625,9 @@ _gtk_text_handle_set_mode (GtkTextHandle     *handle,
   _gtk_text_handle_update_shape (handle,
                                  priv->windows[GTK_TEXT_HANDLE_POSITION_CURSOR].window,
                                  GTK_TEXT_HANDLE_POSITION_CURSOR);
+  _gtk_text_handle_update_shape (handle,
+                                 priv->windows[GTK_TEXT_HANDLE_POSITION_SELECTION_START].window,
+                                 GTK_TEXT_HANDLE_POSITION_SELECTION_START);
 
   _gtk_text_handle_update_window_state (handle, GTK_TEXT_HANDLE_POSITION_SELECTION_START);
   _gtk_text_handle_update_window_state (handle, GTK_TEXT_HANDLE_POSITION_SELECTION_END);
@@ -634,6 +651,7 @@ _gtk_text_handle_set_position (GtkTextHandle         *handle,
 {
   GtkTextHandlePrivate *priv;
   HandleWindow *handle_window;
+  gboolean size_changed;
 
   g_return_if_fail (GTK_IS_TEXT_HANDLE (handle));
 
@@ -650,6 +668,9 @@ _gtk_text_handle_set_position (GtkTextHandle         *handle,
        pos != GTK_TEXT_HANDLE_POSITION_CURSOR))
     return;
 
+  size_changed = (rect->width != handle_window->pointing_to.width ||
+                  rect->height != handle_window->pointing_to.height);
+
   handle_window->pointing_to = *rect;
   handle_window->has_point = TRUE;
   gdk_window_get_root_coords (priv->relative_to,
@@ -658,6 +679,9 @@ _gtk_text_handle_set_position (GtkTextHandle         *handle,
                               &handle_window->pointing_to.y);
 
   _gtk_text_handle_update_window_state (handle, pos);
+
+  if (size_changed)
+    _gtk_text_handle_update_shape (handle, handle_window->window, pos);
 }
 
 void
@@ -682,6 +706,9 @@ _gtk_text_handle_set_visible (GtkTextHandle         *handle,
   if (!window)
     return;
 
+  if (!gdk_window_is_visible (window))
+    _gtk_text_handle_update_shape (handle, window, pos);
+
   priv->windows[pos].user_visible = visible;
   _gtk_text_handle_update_window_state (handle, pos);
 }



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