1.3.x gtkentry UI enhancements[+patch]



Hello,

I have some modifications to the gtkentry widget I'd like to suggest that I think
make it much more pleasant to use. [patch included]

Proposed improvements:

	1. When hitting a L/R arrow key while text is selected move the
	cursor to either the start or end of the selection and deselect.

	2. Allow the user to <shift> click to add to the selection.

	3. Allow the user to easily select either the beginning or ending
	portion of the text by dragging the mouse vertically.

All of these features are standard in one or more other widget sets (mac, motif
etc.)

I believe their usefulness to be self evident, but I can provide some
logical backing if necessary :)

If these changes are accepted there are several other widgets that should have
the same functionality added to them for consistency.

What do you all think?

Thanks,
Jay Cox,
jaycox gimp org

PS:  Bonus bugfix for triple clicking is now included free with every patch!


---------------------------------------------------------------------

--- gtk/gtkentry.c	2001/01/26 21:11:59	1.102
+++ gtk/gtkentry.c	2001/01/30 08:16:43
@@ -1020,8 +1020,40 @@
     
   if (event->button == 1)
     {
-      switch (event->type)
+      if (event->state & GDK_SHIFT_MASK)
+      {
+	if (gtk_editable_get_selection_bounds (editable, &sel_start, &sel_end))
 	{
+	  if (tmp_pos >= sel_start && tmp_pos <= sel_end)
+	  { /* clicked inside selection */
+	    entry->current_pos = tmp_pos;
+	  }
+	  else
+	  { /* clicked outside selection */
+	    if (abs(tmp_pos - entry->selection_bound) < 
+		abs(tmp_pos - entry->current_pos))
+	    {/* closer to bound than current */
+	      entry->selection_bound = entry->current_pos;
+	      entry->current_pos = tmp_pos;
+	    }
+	    else
+	    {/* closer to current than bound */
+	      entry->current_pos = tmp_pos;
+	    }
+	  }
+	}
+	else
+	{ /* select from the current position to the clicked position */
+	  entry->selection_bound = entry->current_pos;
+	  entry->current_pos = tmp_pos;
+	}
+	entry->drag_start_x = event->x + entry->scroll_offset;
+	entry->drag_start_y = event->y + entry->scroll_offset;
+	gtk_entry_recompute (entry);
+      }
+      else /* no shift key */
+      switch (event->type)
+      {
 	case GDK_BUTTON_PRESS:
 	  if (gtk_editable_get_selection_bounds (editable, &sel_start, &sel_end) &&
 	      tmp_pos >= sel_start && tmp_pos <= sel_end)
@@ -1047,10 +1079,18 @@
 	  break;
 
 	case GDK_2BUTTON_PRESS:
+	  /* We ALWAYS recieve a GDK_BUTTON_PRESS immediatly before */
+	  /* receiving a GDK_2BUTTON_PRESS so we need to reset      */
+	  /* entry->in_drag which may have been set above           */
+	  entry->in_drag = FALSE;
 	  gtk_entry_select_word (entry);
 	  break;
 
 	case GDK_3BUTTON_PRESS:
+	  /* We ALWAYS recieve a GDK_BUTTON_PRESS immediatly before */
+	  /* receiving a GDK_3BUTTON_PRESS so we need to reset      */
+	  /* entry->in_drag which may have been set above           */
+	  entry->in_drag = FALSE;
 	  gtk_entry_select_line (entry);
 	  break;
 
@@ -1143,8 +1183,20 @@
     }
   else
     {
+      int width, height;
       tmp_pos = gtk_entry_find_position (entry, event->x +
entry->scroll_offset);
+      gdk_window_get_size (entry->text_area, &width, &height);
 
+      if ((event->y - entry->drag_start_y) <= -height)
+      { /* user has dragged up so select to begining of line */
+	/* possibly pango problems? */
+	tmp_pos = 0;
+      }
+      if ((event->y - entry->drag_start_y) >= height)
+      { /* user has dragged down so select to end of line   */
+	/* possibly pango problems? */
+	tmp_pos = entry->text_length;
+      }
       if (tmp_pos != entry->current_pos)
 	{
 	  entry->current_pos = tmp_pos;
@@ -1560,7 +1612,6 @@
 		       gboolean        extend_selection)
 {
   gint new_pos = entry->current_pos;
-
   gtk_entry_reset_im_context (entry);
   
   switch (step)
@@ -1569,6 +1620,21 @@
       new_pos = CLAMP (new_pos + count, 0, entry->text_length);
       break;
     case GTK_MOVEMENT_VISUAL_POSITIONS:
+      if (entry->current_pos != entry->selection_bound && !extend_selection)
+      {
+	if (count > 0) /* move cursor to right edge of selection */
+	  new_pos = MAX(entry->current_pos, entry->selection_bound);
+	else           /* move cursor to left  edge of selection */
+	  new_pos = MIN(entry->current_pos, entry->selection_bound);
+
+	gtk_entry_reset_im_context (entry);
+
+	entry->current_pos = entry->selection_bound = new_pos;
+
+	gtk_entry_recompute (entry);
+
+	return;
+      }
       new_pos = gtk_entry_move_visually (entry, new_pos, count);
       break;
     case GTK_MOVEMENT_WORDS:




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