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(); }
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); } } }