Пример #1
0
        /// <summary>
        /// 绘制行
        /// </summary>
        public void Draw(TextBoxControl editor, Graphics g, Font f, Point ptPos)
        {
            Point      ptTemp = ptPos;
            RectangleF rcClip = g.ClipBounds;

            // 绘制行号
            //_nLineNumber = editor.LineCount;
            if (editor.ShowLineNumber && (ptTemp.Y + editor.FontHeight > rcClip.Top && ptTemp.Y < rcClip.Bottom && ptTemp.X < rcClip.Right))
            {
                g.ResetClip();
                int numWidth = editor.DrawHelper.MeasureStringWidth(g, _nLineNumber.ToString(), f);

                Point ptNum = new Point(editor.Padding.Left + editor.GetBarWidth() - editor.Margin.Right - numWidth, ptPos.Y);

                editor.DrawHelper.DrawString(g, _nLineNumber.ToString(), f, editor.LineNumberColor, ptNum);
                g.SetClip(rcClip);
            }

            // 绘制元素
            foreach (Block seg in Blocks)
            {
                if (ptTemp.Y + editor.FontHeight > rcClip.Top && ptTemp.Y < rcClip.Bottom && ptTemp.X < rcClip.Right)
                {
                    seg.Draw(editor, g, f, ref ptTemp, _nLineNumber);
                }
            }
        }
Пример #2
0
        /// <summary>
        /// 绘制
        /// </summary>
        public void Draw(TextBoxControl editor, Graphics g, Font f, ref Point ptTemp, int lineNumber)
        {
            TextLocation start = editor.SelectionManager.SelectionStart;
            TextLocation end   = editor.SelectionManager.SelectionEnd;

            // 若未被选中的状态(起始位置等于结束位置时),则直接按照原来的逻辑进行计算
            if (start.X == end.X && start.Y == end.Y)
            {
                if (BlockType == BlockType.Space)
                {
                    ptTemp.X += editor.SpaceWidth;
                }
                else if (BlockType == BlockType.Tab)
                {
                    ptTemp.X += editor.SpaceWidth * Length;
                }
                else
                {
                    int iWidth = editor.DrawHelper.MeasureStringWidth(g, Text, f);

                    editor.DrawHelper.DrawString(g, Text, f, Color, ptTemp);
                    ptTemp.X += iWidth;
                }
                return;
            }


            // 是否被选中
            bool isSelected = false;
            // 绘制的起始位置
            int startPos = -1;
            // 绘制的结束位置
            int endPos = -1;

            // 计算元素中选中部分和未选中部分
            // 若元素的类型为空格或者是Tab键时,计算它们所占的宽度

            int wordWidth = 0;

            if (BlockType == BlockType.Space)
            {
                wordWidth = editor.SpaceWidth;
            }
            else if (BlockType == BlockType.Tab)
            {
                wordWidth = editor.SpaceWidth * Length;
            }
            else
            {
                wordWidth = editor.DrawHelper.MeasureStringWidth(g, Text, f);
            }

            // 计算开始节点和结束节点坐标的位置
            int startColLocation = editor.CalColumnLocation(start.Y, start.X)
                                   + editor.Padding.Left
                                   + editor.Margin.Left
                                   + editor.GetBarWidth()
                                   - editor.HorizontalScroll.Value;
            int endColLocation = editor.CalColumnLocation(end.Y, end.X)
                                 + editor.Padding.Left
                                 + editor.Margin.Left
                                 + editor.GetBarWidth()
                                 - editor.HorizontalScroll.Value;

            if (start.Y == end.Y && start.Y == lineNumber)
            {
                int minX = startColLocation > endColLocation ? endColLocation : startColLocation;
                int maxX = startColLocation > endColLocation ? startColLocation : endColLocation;
                // 元素在选中范围内
                if (minX <= ptTemp.X && ptTemp.X + wordWidth <= maxX)
                {
                    isSelected = true;
                }
                // 元素与选中范围左侧有交集
                else if (ptTemp.X < minX && minX < ptTemp.X + wordWidth && ptTemp.X + wordWidth <= maxX)
                {
                    isSelected = true;
                    startPos   = minX;
                    endPos     = ptTemp.X + wordWidth;
                }
                // 元素与选中范围的右侧有交集
                else if (ptTemp.X >= minX && ptTemp.X < maxX && ptTemp.X + wordWidth > maxX)
                {
                    isSelected = true;
                    startPos   = ptTemp.X;
                    endPos     = maxX;
                }
                // 选中范围在元素中
                else if (ptTemp.X < minX && ptTemp.X + wordWidth > maxX)
                {
                    isSelected = true;
                    startPos   = minX;
                    endPos     = maxX;
                }
            }
            else
            {
                TextLocation minY            = start.Y < end.Y ? start : end;
                TextLocation maxY            = start.Y < end.Y ? end : start;
                int          minYColLocation = start.Y < end.Y ? startColLocation : endColLocation;
                int          maxYColLocation = start.Y < end.Y ? endColLocation : startColLocation;

                // 所在行在选择行之间时
                if (minY.Y < lineNumber && lineNumber < maxY.Y)
                {
                    isSelected = true;
                }
                // 所在行在首行
                else if (minY.Y == lineNumber)
                {
                    if (minYColLocation <= ptTemp.X)
                    {
                        isSelected = true;
                    }
                    else if (ptTemp.X <= minYColLocation && minYColLocation < ptTemp.X + wordWidth)
                    {
                        isSelected = true;
                        startPos   = minYColLocation;
                        endPos     = ptTemp.X + wordWidth;
                    }
                }
                // 所在行在尾行
                else if (maxY.Y == lineNumber)
                {
                    if (maxYColLocation >= ptTemp.X + wordWidth)
                    {
                        isSelected = true;
                    }
                    else if (ptTemp.X < maxYColLocation && maxYColLocation <= ptTemp.X + wordWidth)
                    {
                        isSelected = true;
                        startPos   = ptTemp.X;
                        endPos     = maxYColLocation;
                    }
                }
            }
            Brush selectionBackgroundBrush = new SolidBrush(SystemColors.Highlight);

            if (BlockType == BlockType.Space)
            {
                if (isSelected)
                {
                    g.FillRectangle(selectionBackgroundBrush, new RectangleF(ptTemp.X, ptTemp.Y, editor.SpaceWidth, editor.FontHeight));
                }
                ptTemp.X += editor.SpaceWidth;
            }
            else if (BlockType == BlockType.Tab)
            {
                if (isSelected)
                {
                    g.FillRectangle(selectionBackgroundBrush, new RectangleF(ptTemp.X, ptTemp.Y, editor.SpaceWidth * 4, editor.FontHeight));
                }
                ptTemp.X += editor.SpaceWidth * editor.TabIndent;
            }
            else
            {
                if (isSelected && startPos != -1 && endPos != -1)
                {
                    StringBuilder leftWords   = new StringBuilder();
                    StringBuilder middleWords = new StringBuilder();
                    StringBuilder rightWords  = new StringBuilder();
                    int           length      = ptTemp.X;
                    for (int i = 0; i < Text.Length; i++)
                    {
                        int word = editor.DrawHelper.MeasureStringWidth(g, Text[i].ToString(), editor.Font);
                        // 小于等于起始位置的文本设置为左部分文本(可有可无)
                        if (length + word <= startPos)
                        {
                            leftWords.Append(Text[i].ToString());
                        }
                        // 大于起始位置而小于等于结束位置的文本设置为中间文本(也就是选中部分)
                        else if (length + word > startPos && length + word <= endPos)
                        {
                            middleWords.Append(Text[i].ToString());
                        }
                        // 大于结束位置的文本定义为右侧文本(可有可无)
                        else if (length + word > endPos)
                        {
                            rightWords.Append(Text[i].ToString());
                        }
                        length += word;
                    }
                    // 按段去绘制一个元素,最多可分为三部分(非选中、选中、非选中)
                    editor.DrawHelper.DrawString(g, leftWords.ToString(), f, GetSegmentColor(editor), ptTemp);
                    int leftWidth = string.IsNullOrEmpty(leftWords.ToString()) ? 0 : editor.DrawHelper.MeasureStringWidth(g, leftWords.ToString(), editor.Font);

                    // 对高亮的绘制完全采用颜色填充的形式,而不采用直接设置背景色(直接设置背景色时,背景色和字体不是等宽的,而引起了背景色对前一个元素的尾字母产生了部分遮挡)
                    int middleWidth = string.IsNullOrEmpty(middleWords.ToString()) ? 0 : editor.DrawHelper.MeasureStringWidth(g, middleWords.ToString(), editor.Font);
                    g.FillRectangle(selectionBackgroundBrush, new RectangleF(ptTemp.X + leftWidth, ptTemp.Y, middleWidth, editor.FontHeight));
                    editor.DrawHelper.DrawString(g, middleWords.ToString(), f, editor.HighLightTextColor, new Point(ptTemp.X + leftWidth, ptTemp.Y));

                    editor.DrawHelper.DrawString(g, rightWords.ToString(), f, GetSegmentColor(editor), new Point(ptTemp.X + middleWidth + leftWidth, ptTemp.Y));
                }
                else if (isSelected && startPos == -1 && endPos == -1)
                {
                    g.FillRectangle(selectionBackgroundBrush, new RectangleF(ptTemp.X, ptTemp.Y, wordWidth, editor.FontHeight));
                    editor.DrawHelper.DrawString(g, Text, f, editor.HighLightTextColor, ptTemp);
                }
                else
                {
                    editor.DrawHelper.DrawString(g, Text, f, GetSegmentColor(editor), ptTemp);
                }
                ptTemp.X += wordWidth;
            }
        }