cursor-position, selection-bound



The following patch resolves:

 62148 Unable to detect cursor movement in selectable GtkLabel
 62636 Unable to get notification of selection change

Perhaps somewhat controversially, it makes the 
'cursor-position' and 'selection-bound' properties read-only.

The rational for this is that if we make them read-write,
we have the choice between two bad behaviors:
  
   a) setting cursor-position changes selection-bound.
   a) setting cursor-position does not change selection-bound.

(The selected region is the region between cursor-position
and selection-bound.)

So, I think they are useless from a GUI builder, since you
have to be careful to set things in the order:

 name, cursor-position, selection-bound

And when used from an application, the weird dependencies
or lack of will make using the GtkEditable functions easier.

Regards,
                                        Owen

Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gtk+/ChangeLog,v
retrieving revision 1.2413
diff -u -p -r1.2413 ChangeLog
--- ChangeLog	2001/10/22 14:31:04	1.2413
+++ ChangeLog	2001/10/22 16:30:31
@@ -1,3 +1,13 @@
+Mon Oct 22 11:47:47 2001  Owen Taylor  <otaylor redhat com>
+
+	* gtk/gtklabel.c: Add cursor-position, selection-bound 
+	properties.
+
+	* gtk/gtkentry.c (gtk_entry_class_init): Rename text_position
+	to cursor_position. (1.3.x addition, text_position is an awful
+	name.) Make cursor_position read-only to avoid sticky questions
+	of interaction with selection_bound.
+
 Sat Oct 20 18:58:25 2001  Owen Taylor  <otaylor redhat com>
 
 	* gtk/gtkentry.h: Deprecate gtk_entry_set_editable.
Index: gtk/gtkentry.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkentry.c,v
retrieving revision 1.158
diff -u -p -r1.158 gtkentry.c
--- gtk/gtkentry.c	2001/10/22 14:31:05	1.158
+++ gtk/gtkentry.c	2001/10/22 16:30:31
@@ -70,7 +70,8 @@ enum {
 
 enum {
   PROP_0,
-  PROP_TEXT_POSITION,
+  PROP_CURSOR_POSITION,
+  PROP_SELECTION_BOUND,
   PROP_EDITABLE,
   PROP_MAX_LENGTH,
   PROP_VISIBILITY,
@@ -402,14 +403,24 @@ gtk_entry_class_init (GtkEntryClass *cla
   class->activate = gtk_entry_real_activate;
   
   g_object_class_install_property (gobject_class,
-                                   PROP_TEXT_POSITION,
-                                   g_param_spec_int ("text_position",
-                                                     _("Text Position"),
-                                                     _("The current position of the insertion point"),
+                                   PROP_CURSOR_POSITION,
+                                   g_param_spec_int ("cursor_position",
+                                                     _("Cursor Position"),
+                                                     _("The current position of the insertion cursor in chars."),
                                                      0,
                                                      G_MAXINT,
                                                      0,
-                                                     G_PARAM_READABLE | G_PARAM_WRITABLE));
+                                                     G_PARAM_READABLE));
+  
+  g_object_class_install_property (gobject_class,
+                                   PROP_SELECTION_BOUND,
+                                   g_param_spec_int ("selection_bound",
+                                                     _("Selection Bound"),
+                                                     _("The position of the opposite end of the selection from the cursor in chars."),
+                                                     0,
+                                                     G_MAXINT,
+                                                     0,
+                                                     G_PARAM_READABLE));
   
   g_object_class_install_property (gobject_class,
                                    PROP_EDITABLE,
@@ -775,11 +786,6 @@ gtk_entry_set_property (GObject         
 
   switch (prop_id)
     {
-    case PROP_TEXT_POSITION:
-      gtk_editable_set_position (GTK_EDITABLE (object), 
-				 g_value_get_int (value));
-      break;
-
     case PROP_EDITABLE:
       {
         gboolean new_value = g_value_get_boolean (value);
@@ -821,6 +827,7 @@ gtk_entry_set_property (GObject         
       break;
 
     case PROP_SCROLL_OFFSET:
+    case PROP_CURSOR_POSITION:
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -839,9 +846,12 @@ gtk_entry_get_property (GObject         
 
   switch (prop_id)
     {
-    case PROP_TEXT_POSITION:
+    case PROP_CURSOR_POSITION:
       g_value_set_int (value, entry->current_pos);
       break;
+    case PROP_SELECTION_BOUND:
+      g_value_set_int (value, entry->selection_bound);
+      break;
     case PROP_EDITABLE:
       g_value_set_boolean (value, entry->editable);
       break;
@@ -2272,6 +2282,8 @@ gtk_entry_set_positions (GtkEntry *entry
 			 gint      selection_bound)
 {
   gboolean changed = FALSE;
+
+  g_object_freeze_notify (G_OBJECT (entry));
   
   if (current_pos != -1 &&
       entry->current_pos != current_pos)
@@ -2279,7 +2291,7 @@ gtk_entry_set_positions (GtkEntry *entry
       entry->current_pos = current_pos;
       changed = TRUE;
 
-      g_object_notify (G_OBJECT (entry), "text_position");
+      g_object_notify (G_OBJECT (entry), "cursor_position");
     }
 
   if (selection_bound != -1 &&
@@ -2287,7 +2299,11 @@ gtk_entry_set_positions (GtkEntry *entry
     {
       entry->selection_bound = selection_bound;
       changed = TRUE;
+      
+      g_object_notify (G_OBJECT (entry), "selection_bound");
     }
+
+  g_object_thaw_notify (G_OBJECT (entry));
 
   if (changed)
     gtk_entry_recompute (entry);
Index: gtk/gtklabel.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtklabel.c,v
retrieving revision 1.102
diff -u -p -r1.102 gtklabel.c
--- gtk/gtklabel.c	2001/10/22 14:31:05	1.102
+++ gtk/gtklabel.c	2001/10/22 16:30:31
@@ -66,7 +66,9 @@ enum {
   PROP_WRAP,
   PROP_SELECTABLE,
   PROP_MNEMONIC_KEYVAL,
-  PROP_MNEMONIC_WIDGET
+  PROP_MNEMONIC_WIDGET,
+  PROP_CURSOR_POSITION,
+  PROP_SELECTION_BOUND
 };
 
 static guint signals[LAST_SIGNAL] = { 0 };
@@ -351,6 +353,26 @@ gtk_label_class_init (GtkLabelClass *cla
 							GTK_TYPE_WIDGET,
 							G_PARAM_READWRITE));
 
+  g_object_class_install_property (gobject_class,
+                                   PROP_CURSOR_POSITION,
+                                   g_param_spec_int ("cursor_position",
+                                                     _("Cursor Position"),
+                                                     _("The current position of the insertion cursor in chars."),
+                                                     0,
+                                                     G_MAXINT,
+                                                     0,
+                                                     G_PARAM_READABLE));
+  
+  g_object_class_install_property (gobject_class,
+                                   PROP_SELECTION_BOUND,
+                                   g_param_spec_int ("selection_bound",
+                                                     _("Selection Bound"),
+                                                     _("The position of the opposite end of the selection from the cursor in chars."),
+                                                     0,
+                                                     G_MAXINT,
+                                                     0,
+                                                     G_PARAM_READABLE));
+  
   gtk_widget_class_install_style_property (widget_class,
 					   g_param_spec_boxed ("cursor_color",
 							       _("Cursor color"),
@@ -522,6 +544,26 @@ gtk_label_get_property (GObject     *obj
     case PROP_MNEMONIC_WIDGET:
       g_value_set_object (value, (GObject*) label->mnemonic_widget);
       break;
+    case PROP_CURSOR_POSITION:
+      if (label->select_info)
+	{
+	  gint offset = g_utf8_pointer_to_offset (label->label,
+						  label->label + label->select_info->selection_end);
+	  g_value_set_int (value, offset);
+	}
+      else
+	g_value_set_int (value, 0);
+      break;
+    case PROP_SELECTION_BOUND:
+      if (label->select_info)
+	{
+	  gint offset = g_utf8_pointer_to_offset (label->label,
+						  label->label + label->select_info->selection_anchor);
+	  g_value_set_int (value, offset);
+	}
+      else
+	g_value_set_int (value, 0);
+      break;
 
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -2139,17 +2181,15 @@ gtk_label_button_press (GtkWidget      *
 	  min = MIN (min, index);
 	  max = MAX (max, index);
 	  
-	  gtk_label_select_region_index (label,
-					 min,
-					 max);
-	  
 	  /* ensure the anchor is opposite index */
-	  if (index == label->select_info->selection_anchor)
+	  if (index == min)
 	    {
-	      gint tmp = label->select_info->selection_end;
-	      label->select_info->selection_end = label->select_info->selection_anchor;
-	      label->select_info->selection_anchor = tmp;
+	      gint tmp = min;
+	      min = max;
+	      max = tmp;
 	    }
+	  
+	  gtk_label_select_region_index (label, min, max);
 	}
       else
 	{
@@ -2332,8 +2372,12 @@ gtk_label_set_selectable (GtkLabel *labe
     }
   if (setting != old_setting)
     {
-       g_object_notify (G_OBJECT (label), "selectable");
-       gtk_widget_queue_draw (GTK_WIDGET (label));
+      g_object_freeze_notify (G_OBJECT (label));
+      g_object_notify (G_OBJECT (label), "selectable");
+      g_object_notify (G_OBJECT (label), "cursor_position");
+      g_object_notify (G_OBJECT (label), "selection_bound");
+      g_object_thaw_notify (G_OBJECT (label));
+      gtk_widget_queue_draw (GTK_WIDGET (label));
     }
 }
 
@@ -2451,6 +2495,11 @@ gtk_label_select_region_index (GtkLabel 
 
       gtk_label_clear_layout (label);
       gtk_widget_queue_draw (GTK_WIDGET (label));
+
+      g_object_freeze_notify (G_OBJECT (label));
+      g_object_notify (G_OBJECT (label), "cursor_position");
+      g_object_notify (G_OBJECT (label), "selection_bound");
+      g_object_thaw_notify (G_OBJECT (label));
     }
 }
 



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