Author: jpobst
Date: 2007-10-12 10:29:06 -0400 (Fri, 12 Oct 2007)
New Revision: 87395

Modified:
   trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ChangeLog
   trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Line.cs
   trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/LineTag.cs
   trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/TextControl.cs
Log:
2007-10-12  Jonathan Pobst  <[EMAIL PROTECTED]>

        * Line.cs: Add a method that finds the tag that contains an x-coord.
        * LineTag.cs: Add a method that finds the character at an x-coord using
        a binary search, the old way was a linear search.
        * TextControl.cs: Change FindCursor to use the above new methods.

Modified: trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ChangeLog
===================================================================
--- trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ChangeLog        
2007-10-12 14:02:52 UTC (rev 87394)
+++ trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ChangeLog        
2007-10-12 14:29:06 UTC (rev 87395)
@@ -1,3 +1,10 @@
+2007-10-12  Jonathan Pobst  <[EMAIL PROTECTED]>
+
+       * Line.cs: Add a method that finds the tag that contains an x-coord.
+       * LineTag.cs: Add a method that finds the character at an x-coord using
+       a binary search, the old way was a linear search.
+       * TextControl.cs: Change FindCursor to use the above new methods.
+
 2007-10-11  Carlos Alberto Cortez <[EMAIL PROTECTED]>
 
        * DragEventArgs.cs: Allow Effect to have a non allowed value (a

Modified: trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Line.cs
===================================================================
--- trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Line.cs  
2007-10-12 14:02:52 UTC (rev 87394)
+++ trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Line.cs  
2007-10-12 14:29:06 UTC (rev 87395)
@@ -256,6 +256,29 @@
                        return base.GetHashCode ();
                }
                
+               // Get the tag that contains this x coordinate
+               public LineTag GetTag (int x)
+               {
+                       LineTag tag = tags;
+                       
+                       // Coord is to the left of the first character
+                       if (x < tag.X)
+                               return LineTag.GetFinalTag (tag);
+                       
+                       // All we have is a linked-list of tags, so we have
+                       // to do a linear search.  But there shouldn't be
+                       // too many tags per line in general.
+                       while (true) {
+                               if (x >= tag.X && x < (tag.X + tag.Width))
+                                       return tag;
+                                       
+                               if (tag.Next != null)
+                                       tag = tag.Next;
+                               else
+                                       return LineTag.GetFinalTag (tag);       
                
+                       }
+               }
+                                       
                // Make sure we always have enoughs space in text and widths
                internal void Grow (int minimum) {
                        int     length;

Modified: trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/LineTag.cs
===================================================================
--- trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/LineTag.cs       
2007-10-12 14:02:52 UTC (rev 87394)
+++ trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/LineTag.cs       
2007-10-12 14:29:06 UTC (rev 87395)
@@ -343,6 +343,34 @@
                        return retval;
                }
 
+               // Gets the character at the x-coordinate.  Index is based from 
the
+               // line, not the start of the tag.
+               public int GetCharIndex (int x)
+               {
+                       int low = start;
+                       int high = low + Length;
+
+                       if (x > line.widths[line.TextLengthWithoutEnding ()])
+                               return line.TextWithoutEnding ().Length;
+                               
+                       while (low < high - 1) {
+                               int mid = (high + low) / 2;
+                               float width = line.widths[mid];
+
+                               if (width < x)
+                                       low = mid;
+                               else
+                                       high = mid;
+                       }
+
+                       float char_width = line.widths[high] - line.widths[low];
+
+                       if ((x - line.widths[low]) >= (char_width / 2))
+                               return high;
+                       else
+                               return low;     
+               }
+               
                // There can be multiple tags at the same position, we want to 
make
                // sure we are using the very last tag at the given position
                internal static LineTag GetFinalTag (LineTag tag)

Modified: 
trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/TextControl.cs
===================================================================
--- trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/TextControl.cs   
2007-10-12 14:02:52 UTC (rev 87394)
+++ trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/TextControl.cs   
2007-10-12 14:29:06 UTC (rev 87395)
@@ -3257,43 +3257,16 @@
                }
 
                // Give it x/y pixel coordinates and it returns the Tag at that 
position; optionally the char position is returned in index
-               internal LineTag FindCursor(int x, int y, out int index) {
-                       Line    line;
-                       LineTag tag;
+               internal LineTag FindCursor (int x, int y, out int index)
+               {
+                       Line line;
 
-                       line = GetLineByPixel(multiline ? y : x, false);
-                       tag = line.tags;
+                       line = GetLineByPixel (multiline ? y : x, false);
 
-                       /// Special case going leftwards of the first tag
-                       if (x < tag.X) {
-                               index = 0;
-                               return LineTag.GetFinalTag (tag);
-                       }
-
-                       while (true) {
-                               if (x >= tag.X && x < (tag.X+tag.Width)) {
-                                       int     end;
-
-                                       end = tag.TextEnd;
-
-                                       for (int pos = tag.Start - 1; pos < 
end; pos++) {
-                                               // When clicking on a 
character, we position the cursor to whatever edge
-                                               // of the character the click 
was closer
-                                               if (x < (line.X + 
line.widths[pos] + ((line.widths[pos+1]-line.widths[pos])/2))) {
-                                                       index = pos;
-                                                       return 
LineTag.GetFinalTag (tag);
-                                               }
-                                       }
-                                       index=end;
-                                       return LineTag.GetFinalTag (tag);
-                               }
-                               if (tag.Next != null) {
-                                       tag = tag.Next;
-                               } else {
-                                       index = line.TextLengthWithoutEnding ();
-                                       return LineTag.GetFinalTag (tag);
-                               }
-                       }
+                       LineTag tag = line.GetTag (x);
+                       index = tag.GetCharIndex (x);
+                       
+                       return tag;
                }
 
                /// <summary>Format area of document in specified font and 
color</summary>

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to