private void DrawAnnotation(IAnnotation annotation, DiagramDrawingStyle style, D2dGraphics g, bool drawText, RectangleF graphBound)
        {
            // fill background
            Rectangle bounds = annotation.Bounds;

            Color backColor = m_coloringContext == null
                                  ? SystemColors.Info
                                  : (Color) m_coloringContext.GetColor(ColoringTypes.BackColor, annotation);
            // keep the width of border in 1 pixel after transformation to avoid D2d antialiasing away the line
            float borderThickness = 1.0f/m_scaleX;
            g.FillRectangle(bounds, backColor);
            g.DrawRectangle(bounds, ControlPaint.Dark(backColor), borderThickness, null);
       
            // draw titlebar
            if (style == DiagramDrawingStyle.LastSelected || style == DiagramDrawingStyle.Selected)
            {
                var titleBarRect = new RectangleF(bounds.X, bounds.Y, bounds.Width, Margin.Top - 1);
                g.FillRectangle(titleBarRect, ControlPaint.Dark(backColor));
            }
            // line seperate titlebar from text content     
            g.DrawLine(bounds.X, bounds.Y + Margin.Top-1, bounds.X + bounds.Width, bounds.Y + Margin.Top-1, ControlPaint.Dark(backColor), borderThickness);

            // draw content
            if (drawText)
            {
                var contentBounds = new RectangleF(bounds.X + Margin.Left, bounds.Y + Margin.Top,
                                               bounds.Width - Margin.Size.Width, bounds.Height - Margin.Size.Height);

                contentBounds.Width = Math.Max(contentBounds.Width, MinimumWidth);
                contentBounds.Height = Math.Max(contentBounds.Height, MinimumHeight);
                var textBounds = contentBounds;              
    
                int topLine = 0;
                D2dTextLayout textLayout = null;

                if (m_annotationEditors.ContainsKey(annotation))
                {
                                     
                    var annotationEditor = m_annotationEditors[annotation];
                    if (annotationEditor.TextLayout.Text != annotation.Text) // text content changed, for example, undo,redo
                    {
                        annotationEditor.ResetText(annotation.Text);
                    }
                    topLine = annotationEditor.TopLine;
                    textLayout = m_annotationEditors[annotation].TextLayout;
                    annotationEditor.VerticalScrollBarVisibe = textLayout.Height > textLayout.LayoutHeight;

                    if (m_annotationEditors[annotation].VerticalScrollBarVisibe)
                        textBounds.Width -= ScrollBarWidth + 2 * ScrollBarMargin;
                    textLayout.LayoutWidth = textBounds.Width;
                    textLayout.LayoutHeight = textBounds.Height;
                 
                }

                if (textLayout == null)
                {
                    // first assume no v-scroll bar needed
                    textLayout = D2dFactory.CreateTextLayout(annotation.Text, m_theme.TextFormat, contentBounds.Width, contentBounds.Height);
                    if (m_theme.TextFormat.Underlined)
                        textLayout.SetUnderline(true, 0, annotation.Text.Length);
                    if (m_theme.TextFormat.Strikeout)
                        textLayout.SetStrikethrough(true, 0, annotation.Text.Length);

                    if (textLayout.Height >  textLayout.LayoutHeight) // need v-scroll bar
                    {
                        textLayout.LayoutWidth = contentBounds.Width - ScrollBarWidth - 2*ScrollBarMargin;
                      
                    }
                    m_annotationEditors.Add(annotation, new TextEditor()
                        {
                            TextLayout = textLayout,
                            TextFormat = m_theme.TextFormat,
                            TopLine =  topLine,
                            VerticalScrollBarVisibe = textLayout.Height > textLayout.LayoutHeight
                        });
                }

                var annotationData = m_annotationEditors[annotation];
                PointF origin = new PointF(contentBounds.Location.X, contentBounds.Location.Y - topLine *  m_theme.TextFormat.FontHeight);

                g.PushAxisAlignedClip(contentBounds);

                // draw the selection range behind the text.
                if (annotationData.SelectionLength > 0)
                {
                    var hitTestMetrics = textLayout.HitTestTextRange(annotationData.SelectionStart, annotationData.SelectionLength, 0, 0);
                    for (int i = 0; i < hitTestMetrics.Length; ++i)
                    {

                        var highlightRect = new RectangleF(hitTestMetrics[i].Point.X, hitTestMetrics[i].Point.Y, hitTestMetrics[i].Width,
                                                           hitTestMetrics[i].Height);
                        highlightRect.Offset(origin);
                        g.FillRectangle(highlightRect, m_theme.TextHighlightBrush);
                    }               
                }

                // draw caret
                
                if ( style == DiagramDrawingStyle.Selected || style == DiagramDrawingStyle.LastSelected)
                {
                    textLayout = annotationData.TextLayout;
                    var caretRect = m_annotationEditors[annotation].GetCaretRect();
                    caretRect.Offset(origin);
                    //g.FillRectangle(caretRect, m_theme.HotBrush);

                    // set Windows caret position                  
                    if (m_editingText && contentBounds.IntersectsWith(caretRect) && graphBound.IntersectsWith(caretRect) && AdaptedControl.Focused)
                    {
                        var caretClientRect = GdiUtil.Transform(m_transformAdapter.Transform, caretRect);
                        float ratio = m_scaleX*m_theme.TextFormat.FontHeight/CaretHeight;                      
                        if (ratio > 1.1f || ratio < 0.9f) // adjust caret height
                        {
                            CaretHeight = (int)(m_scaleX*m_theme.TextFormat.FontHeight);
                            User32.DestroyCaret();
                            User32.CreateCaret(AdaptedControl.Handle, IntPtr.Zero, CaretWidth, CaretHeight);
                        }
                        // align bottom    
                        User32.SetCaretPos((int) caretClientRect.X, (int)(caretClientRect.Y + caretClientRect.Height - CaretHeight));
                        if (!m_rmbPressed)
                            AdaptedControl.HasKeyboardFocus = true;
                    }
                    else
                        HideCaret();
                }

                // draw text 
                g.DrawTextLayout(origin, textLayout, m_theme.TextBrush); 

                g.PopAxisAlignedClip();

                // draw v-scroll bar
                if (contentBounds.Height < textLayout.Height)
                {
                    float visibleLines = contentBounds.Height / m_theme.TextFormat.FontHeight;
                    float vMin = topLine * textLayout.LayoutHeight / textLayout.LineCount;
                    float vMax = (topLine + visibleLines-1) * textLayout.LayoutHeight / textLayout.LineCount;
                    if (m_scrolling)
                    {
                        var trackBounds = new RectangleF(contentBounds.Right - ScrollBarMargin - ScrollBarWidth, contentBounds.Y, ScrollBarWidth, contentBounds.Height);
                        g.FillRectangle(trackBounds, Color.Gainsboro);                    
                    }
                    var thumbBounds = new RectangleF(contentBounds.Right - ScrollBarMargin - ScrollBarWidth, contentBounds.Y + vMin, ScrollBarWidth, vMax - vMin);
                    g.FillRectangle(thumbBounds, Color.DimGray);
                }                
            }
            else
                HideCaret();
        }
Exemple #2
0
        private void DrawAnnotation(IAnnotation annotation, DiagramDrawingStyle style, D2dGraphics g, bool drawText, RectangleF graphBound)
        {
            // fill background
            Rectangle bounds = annotation.Bounds;

            Color backColor = m_coloringContext == null
                                  ? SystemColors.Info
                                  : m_coloringContext.GetColor(ColoringTypes.BackColor, annotation);
            Color foreColor = m_coloringContext == null
                        ? SystemColors.WindowText
                        : m_coloringContext.GetColor(ColoringTypes.ForeColor, annotation);

            // keep the width of border in 2 pixel after transformation to avoid D2d antialiasing away the line
            float borderThickness = 2.0f/m_scaleX;
            g.FillRectangle(bounds, backColor);

            g.DrawRectangle(bounds, m_theme.GetOutLineBrush(style), borderThickness);
       
            //// draw titlebar
            //if (style == DiagramDrawingStyle.LastSelected || style == DiagramDrawingStyle.Selected)
            //{
            //    var titleBarRect = new RectangleF(bounds.X, bounds.Y, bounds.Width, Margin.Top - 1);
            //    g.FillRectangle(titleBarRect, ControlPaint.Dark(backColor));
            //}
            //// line seperate titlebar from text content     
            //g.DrawLine(bounds.X, bounds.Y + Margin.Top-1, bounds.X + bounds.Width, bounds.Y + Margin.Top-1, ControlPaint.Dark(backColor), borderThickness);
            
            // draw content
            if (drawText)
            {
                var contentBounds = new RectangleF(bounds.X + Margin.Left, bounds.Y + Margin.Top,
                                               bounds.Width - Margin.Size.Width, bounds.Height - Margin.Size.Height);
                contentBounds.Width = Math.Max(contentBounds.Width, MinimumWidth);
                contentBounds.Height = Math.Max(contentBounds.Height, MinimumHeight);
                var textBounds = contentBounds;
                
                TextEditor textEditor;
                if (!m_annotationEditors.TryGetValue(annotation,out textEditor))
                {
                    // first assume no v-scroll bar needed
                    var textLayout = D2dFactory.CreateTextLayout(annotation.Text, m_theme.TextFormat, contentBounds.Width, contentBounds.Height);
                    if (m_theme.TextFormat.Underlined)
                        textLayout.SetUnderline(true, 0, annotation.Text.Length);
                    if (m_theme.TextFormat.Strikeout)
                        textLayout.SetStrikethrough(true, 0, annotation.Text.Length);

                    if (textLayout.Height >  textLayout.LayoutHeight) // need v-scroll bar
                    {
                        textLayout.LayoutWidth = contentBounds.Width - ScrollBarWidth - 2 * ScrollBarMargin;
                      
                    }

                    textEditor = new TextEditor
                    {
                        TextLayout = textLayout,
                        TextFormat = m_theme.TextFormat,
                        TopLine =  0,
                        VerticalScrollBarVisibe = textLayout.Height > textLayout.LayoutHeight
                    };
                    m_annotationEditors.Add(annotation, textEditor);                        
                }
                else if (textEditor.TextLayout.Text != annotation.Text) // text content changed, for example, undo,redo
                {                
                    textEditor.ResetText(annotation.Text);                    
                }

                int topLine = textEditor.TopLine;
                textEditor.VerticalScrollBarVisibe = textEditor.TextLayout.Height > textEditor.TextLayout.LayoutHeight;

                if (textEditor.VerticalScrollBarVisibe)
                    textBounds.Width -= ScrollBarWidth + 2 * ScrollBarMargin;
                if (Math.Abs(textEditor.TextLayout.LayoutWidth - textBounds.Width) +
                    Math.Abs(textEditor.TextLayout.LayoutHeight - textBounds.Height) > 1.0)
                {
                    textEditor.TextLayout.LayoutWidth = textBounds.Width; // layout width and height can be updated
                    textEditor.TextLayout.LayoutHeight = textBounds.Height;
                    textEditor.Validate();
                }

                float yOffset = textEditor.GetLineYOffset(topLine);                
                PointF origin = new PointF(contentBounds.Location.X, contentBounds.Location.Y - yOffset);

                g.PushAxisAlignedClip(contentBounds);

               

                // adjust caret.
                // pull out this code to the caller.
                if ( annotation == m_editingAnnotation  && m_caretCreated)
                {                    
                    var caretRect = textEditor.GetCaretRect();
                    caretRect.Offset(origin);                   
                    // set Windows caret position                  
                    if (contentBounds.IntersectsWith(caretRect) && AdaptedControl.Focused)
                    {
                        Matrix3x2F xform = m_transformAdapter != null ? m_transformAdapter.Transform
                            : g.Transform;
                        var caretClientRect = Matrix3x2F.Transform(xform, caretRect);
                        float ratio = m_scaleX*m_theme.TextFormat.FontHeight/CaretHeight;                      
                        if (ratio > 1.1f || ratio < 0.9f) // adjust caret height
                        {
                            CaretHeight = (int)(m_scaleX*m_theme.TextFormat.FontHeight);
                            User32.DestroyCaret();
                            User32.CreateCaret(AdaptedControl.Handle, IntPtr.Zero, CaretWidth, CaretHeight);
                        }
                        // align bottom    
                        User32.SetCaretPos((int) caretClientRect.X, (int)(caretClientRect.Y + caretClientRect.Height - CaretHeight));
                        if (!m_rmbPressed)
                            AdaptedControl.HasKeyboardFocus = true;
                    }
                    else
                        HideCaret();
                }

                // draw the selection range above the text.
                if (textEditor.SelectionLength > 0)
                {
                    D2dBrush hibrush = AdaptedControl.Focused ? m_theme.TextHighlightBrush : m_solidBrush;
                    var hitTestMetrics = textEditor.TextLayout.HitTestTextRange(textEditor.SelectionStart, textEditor.SelectionLength, 0, 0);
                    for (int i = 0; i < hitTestMetrics.Length; ++i)
                    {
                        var highlightRect = new RectangleF(hitTestMetrics[i].Point.X, hitTestMetrics[i].Point.Y, hitTestMetrics[i].Width,
                                                           hitTestMetrics[i].Height);
                        highlightRect.Offset(origin);
                        g.FillRectangle(highlightRect, hibrush);
                    }
                }
                
                // draw text 
                g.DrawTextLayout(origin, textEditor.TextLayout, foreColor);

                

                g.PopAxisAlignedClip();

                // draw v-scroll bar
               // if (contentBounds.Height < textEditor.TextLayout.Height)
                if(textEditor.VerticalScrollBarVisibe)
                {
                    float visibleLines = textEditor.GetVisibleLines();
                    float vMin = topLine * contentBounds.Height / textEditor.TextLayout.LineCount;
                    float vMax = (topLine + visibleLines - 1) * contentBounds.Height / textEditor.TextLayout.LineCount;
                   // if (m_scrolling)
                   // {
                        var trackBounds = new RectangleF(contentBounds.Right - ScrollBarMargin - ScrollBarWidth, contentBounds.Y, ScrollBarWidth, contentBounds.Height);
                        g.FillRectangle(trackBounds, Color.Gainsboro);                    
                   // }
                    var thumbBounds = new RectangleF(contentBounds.Right - ScrollBarMargin - ScrollBarWidth, contentBounds.Y + vMin, ScrollBarWidth, vMax - vMin);
                    g.FillRectangle(thumbBounds, Color.DimGray);
                }                
            }                
        }