dotgnu-general
[Top][All Lists]
Advanced

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

[DotGNU]Patch for Review: Fix Some TextBox Issues for Single-Linefeed Li


From: Mohan Embar
Subject: [DotGNU]Patch for Review: Fix Some TextBox Issues for Single-Linefeed Lines
Date: Fri, 25 Jul 2003 04:27:39 -0500

Hi People,

>This is what I noticed too. I'm going to play with this at my own leisure,
>even if someone else works on it and does it 50 times better and faster
>than me. This looks like a fun piece of code and it's better to have loved
>and lost....

Here's a patch which attempts to fix issues with lines in a TextBox
containing only a single linefeed. What's currently in CVS has issues
when you try to single-click on a line containing a single linefeed in order
to move the cursor there and also moving past such lines with the
right and left arrow keys.

The patch attempts to resolve this by making linefeed characters
valid players in the LayoutInfo structure, giving them valid bounds
but ensuring that they don't get displayed. I replaced LayoutInfo.Item.visible
with an enum indicating whether a given character is visible, out of bounds,
or a (non-displayable) linefeed character whose bounds can now be
used for point-to-character computations.

Let me know if you have any questions or comments about this. I had
fun coding this, so you are welcome to do whatever you want with
this, including flush it down the toilet. Also let me know if you want
this in a different format (like diff -c3p instead of diff -u2).

-- Mohan
http://www.thisiscool.com/
http://www.animalsong.org/

ChangeLog
2003-07-25  Mohan Embar  <address@hidden>

        * System.Windows.Forms/TextBox.cs: corrected issues with right
        and left arrow keys past lines containing only a linefeed and
        single-clicking at the end of such lines. Replaced
        LayoutInfo.Item.visible with an enum and gave linefeed characters
        valid bounds and a special status within LayoutInfo.

Index: TextBox.cs
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnetlib/System.Windows.Forms/TextBox.cs,v
retrieving revision 1.3
diff -u -2 -r1.3 TextBox.cs
--- TextBox.cs  25 Jul 2003 03:04:37 -0000      1.3
+++ TextBox.cs  25 Jul 2003 09:05:02 -0000
@@ -441,12 +441,35 @@
                {
                        Region[] bounds = g.MeasureCharacterRanges(Text, Font, 
new Rectangle(2, 2, Width-4, Height-4), format);
+                       Rectangle prevBounds = new Rectangle(0, 0, 0, 
Font.Height);
                        for (int i=0; i<Text.Length;i++) 
                        {
                                LayoutInfo.Item item = new LayoutInfo.Item();
+                               char c = Text[i];
+                               if (c == (char) Keys.LineFeed)
+                               {
+                                       item.charVisibility = 
LayoutInfo.Item.CharVisibility.LineFeed;
+                                       // Linefeed. The bounds is to the right 
of the previous character.
+                                       // If the previous character was also a 
linefeed, we move down a line
+                                       // from the previous bounds.
+                                       if (i>0 && Text[i-1]==10)
+                                       {
+                                               bounds[i] = new Region(new 
Rectangle(2, prevBounds.Top+Font.Height, 0, Font.Height));
+                                       }
+                                       else
+                                       {
+                                               bounds[i] = new Region(new 
Rectangle(prevBounds.Right, prevBounds.Top, 0, prevBounds.Height));
+                                       }
+                               }
+                               else // c != 10
+                               {
+                                       item.charVisibility = 
LayoutInfo.Item.CharVisibility.Visible;
+                               }
                                RectangleF rect = bounds[i].GetBounds( g);
-                               item.visible = !rect.IsEmpty;
-                               if (item.visible)
+                               if (rect.IsEmpty)
+                                       item.charVisibility = 
LayoutInfo.Item.CharVisibility.OutOfBounds;
+                               else
                                        item.bounds = Rectangle.Truncate( rect);
                                layout.Items[i] = item;
+                               prevBounds = item.bounds;
                        }
                }       
@@ -460,7 +483,9 @@
                public class Item
                {
+                       public enum CharVisibility {OutOfBounds, Visible, 
LineFeed};
+               
+                       public CharVisibility charVisibility;
                        public Rectangle bounds;
                        public bool selected;
-                       public bool visible;
                }
 
@@ -553,5 +578,5 @@
                {
                        LayoutInfo.Item item = layout.Items[i];
-                       if (item.visible /*&& 
e.ClipRectangle.IntersectsWith(item.bounds)*/)
+                       if (item.charVisibility == 
LayoutInfo.Item.CharVisibility.Visible /*&& 
e.ClipRectangle.IntersectsWith(item.bounds)*/)
                        {
                                Brush back, fore;
@@ -628,6 +653,13 @@
                        if (position == Text.Length)
                        {
+                               // If the last character is a linefeed, 
position ourselves at the
+                               // beginning of the following line. Otherwise, 
position ourselves
+                               // immediately to the right of the last 
character.
+                               LayoutInfo.Item item = layout.Items[position 
-1];
                                newBounds = layout.Items[position -1].bounds;
-                               newBounds = new Rectangle(newBounds.Right, 
newBounds.Top, 0, newBounds.Height);
+                               if (item.charVisibility == 
LayoutInfo.Item.CharVisibility.LineFeed)
+                                       newBounds = new Rectangle(2, 
newBounds.Top + Font.Height, 0, Font.Height);
+                               else
+                                       newBounds = new 
Rectangle(newBounds.Right, newBounds.Top, 0, newBounds.Height);
                        }
                        else
@@ -662,5 +694,5 @@
                for (; i<Text.Length;i++) 
                {
-                       if (layout.Items[i].visible)
+                       if (layout.Items[i].charVisibility != 
LayoutInfo.Item.CharVisibility.OutOfBounds)
                        {
                                bounds = layout.Items[i].bounds;
@@ -668,5 +700,4 @@
                                if (pt.Y < bounds.Bottom && pt.X < bounds.Left 
+ bounds.Width/2 )
                                {
-                                       bounds = new Rectangle(bounds.Left, 
bounds.Top, 0, bounds.Height);
                                        break;
                                }
@@ -676,5 +707,4 @@
                                        if (pt.Y < prevY)
                                        {
-                                               bounds = new 
Rectangle(prevBounds.Right, prevBounds.Top, 0, prevBounds.Height);
                                                // Move position back to end of 
previous line
                                                caretPosition--;
@@ -686,13 +716,17 @@
                        }
                }
-       
-               // If at the end set the bounds to the last visible item.
+
                if (i == Text.Length)
                {
-                       bounds = new Rectangle(prevBounds.Right, 
prevBounds.Top, 0, prevBounds.Height);
-                       caretPosition = Text.Length;
+                       // If the last character is a linefeed, set the caret 
to Text.Length only
+                       // if they clicked underneath the linefeed.
+                       caretPosition = i;
+                       if (Text.Length > 0 &&
+                               layout.Items[i-1].charVisibility == 
LayoutInfo.Item.CharVisibility.LineFeed &&
+                               pt.Y <= prevBounds.Bottom)
+                               --caretPosition;
                }
-               
-               SetCaretInvalidate(bounds);
+
+               SetCaretPosition(caretPosition);
                return caretPosition;
        }






reply via email to

[Prev in Thread] Current Thread [Next in Thread]