Ejemplo n.º 1
0
 /// <summary>
 /// Set a custom style that overrides default one during graph rendering </summary>
 /// <param name="node">Graph node to use the custom style</param>
 /// <param name="style">Custom style</param>
 public void SetCustomStyle(object node, DiagramDrawingStyle style)
 {
     if (node != null)
     {
         m_customStyles[node] = style;
     }
 }
Ejemplo n.º 2
0
        private void DrawAnnotation(IAnnotation annotation, DiagramDrawingStyle style, Graphics g)
        {
            Rectangle bounds = annotation.Bounds;

            if (bounds.Size.IsEmpty)
            {
                // calculate size of text block
                SizeF textSizeF = g.MeasureString(annotation.Text, m_theme.Font);
                Size  textSize  = new Size((int)Math.Ceiling(textSizeF.Width), (int)Math.Ceiling(textSizeF.Height));
                bounds.Size = textSize;
                annotation.SetTextSize(textSize);
            }
            g.FillRectangle(SystemBrushes.Info, bounds);
            if ((style & DiagramDrawingStyle.Ghosted) == 0)
            {
                g.DrawString(annotation.Text, m_theme.Font, SystemBrushes.WindowText, bounds);

                Pen pen = null;
                if ((style & DiagramDrawingStyle.LastSelected) != 0)
                {
                    pen = m_theme.LastHighlightPen;
                }
                else if ((style & DiagramDrawingStyle.Selected) != 0)
                {
                    pen = m_theme.HighlightPen;
                }

                if (pen != null)
                {
                    g.DrawRectangle(pen, bounds);
                }
            }
        }
Ejemplo n.º 3
0
        private void control_Paint(object sender, PaintEventArgs e)
        {
            Matrix transform    = m_transformAdapter.Transform;
            Matrix oldTransform = e.Graphics.Transform;
            Region oldClip      = e.Graphics.Clip;

            e.Graphics.Transform = transform;
            Rectangle clip = GdiUtil.InverseTransform(e.Graphics.Transform, e.ClipRectangle);

            e.Graphics.SetClip(clip);

            e.Graphics.SmoothingMode     = SmoothingMode.AntiAlias;
            e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;

            foreach (TNode node in m_graph.Nodes)
            {
                DiagramDrawingStyle style = GetStyle(node);
                m_renderer.Draw(node, style, e.Graphics);
            }

            foreach (TEdge edge in m_graph.Edges)
            {
                DiagramDrawingStyle style = GetStyle(edge);
                m_renderer.Draw(edge, style, e.Graphics);
            }

            e.Graphics.Transform = oldTransform;
            e.Graphics.Clip      = oldClip;
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Gets the theme's pen for the given drawing style</summary>
        /// <param name="style">Drawing style</param>
        /// <returns>Pen for the given drawing style</returns>
        public Pen GetPen(DiagramDrawingStyle style)
        {
            switch (style)
            {
            case DiagramDrawingStyle.Normal:
                return(m_outlinePen);

            case DiagramDrawingStyle.Selected:
                return(m_highlightPen);

            case DiagramDrawingStyle.LastSelected:
                return(m_lastHighlightPen);

            case DiagramDrawingStyle.Hot:
                return(m_hotPen);

            case DiagramDrawingStyle.Ghosted:
                return(m_ghostPen);

            case DiagramDrawingStyle.Hidden:
                return(m_hiddenPen);

            case DiagramDrawingStyle.Error:
            default:
                return(m_errorPen);
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Renders entire graph</summary>
        protected override void OnRender()
        {
            if (m_graph == s_emptyGraph)
            {
                return;
            }
            base.OnRender();

            m_renderer.VisibleWorldBounds = GdiUtil.InverseTransform(m_transformAdapter.Transform, AdaptedControl.ClientRectangle);

            // render group pins
            var group = m_graph.Cast <ICircuitGroupType <TNode, TEdge, TEdgeRoute> >();

            foreach (var pin in group.Inputs.Concat(group.Info.HiddenInputPins))
            {
                var grpPin = pin.Cast <ICircuitGroupPin <TNode> >();
                DiagramDrawingStyle style = GetStyle(grpPin);
                m_renderer.DrawFloatingGroupPin(grpPin, true, style, m_d2dGraphics);
            }

            foreach (var pin in group.Outputs.Concat(group.Info.HiddenOutputPins))
            {
                var grpPin = pin.Cast <ICircuitGroupPin <TNode> >();
                DiagramDrawingStyle style = GetStyle(grpPin);
                m_renderer.DrawFloatingGroupPin(grpPin, false, style, m_d2dGraphics);
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Gets the theme's brush for the given drawing style</summary>
        /// <param name="style">Drawing style</param>
        /// <returns>Brush for the given drawing style</returns>
        public Brush GetBrush(DiagramDrawingStyle style)
        {
            switch (style)
            {
            case DiagramDrawingStyle.Normal:
                return(m_fillBrush);

            case DiagramDrawingStyle.Selected:
                return(m_highlightBrush);

            case DiagramDrawingStyle.LastSelected:
                return(m_lastHighlightBrush);

            case DiagramDrawingStyle.Hot:
                return(m_hotBrush);

            case DiagramDrawingStyle.Ghosted:
                return(m_ghostBrush);

            case DiagramDrawingStyle.Hidden:
                return(m_hiddenBrush);

            case DiagramDrawingStyle.Error:
            default:
                return(m_errorBrush);
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Draws a graph edge</summary>
        /// <param name="edge">Edge to draw</param>
        /// <param name="style">Diagram drawing style</param>
        /// <param name="g">Graphics object</param>
        public override void Draw(TWire edge, DiagramDrawingStyle style, Graphics g)
        {
            TPin inputPin  = edge.ToRoute;
            TPin outputPin = edge.FromRoute;
            Pen  pen       = (style == DiagramDrawingStyle.Normal) ? GetPen(inputPin) : m_theme.GetPen(style);

            DrawWire(edge.FromNode, outputPin, edge.ToNode, inputPin, g, pen);
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Draws a graph node</summary>
        /// <param name="element">Element to draw</param>
        /// <param name="style">Diagram drawing style</param>
        /// <param name="g">Graphics object</param>
        public override void Draw(ScriptNode element, DiagramDrawingStyle style, D2dGraphics g)
        {
            // Use the "disabled" theme when drawing disabled circuit elements.
            if (!((ScriptNodeElementInfo)element.ElementInfo).Enabled)
            {
                D2dDiagramTheme defaultTheme = Theme;
                Theme = m_disabledTheme;
                base.Draw(element, style, g);
                Theme = defaultTheme;
                return;
            }

            base.Draw(element, style, g);
        }
Ejemplo n.º 9
0
        private void DrawEdge(TEdge edge, RectangleF clipBounds)
        {
            if (edge == m_hiddenEdge)
            {
                return;
            }

            RectangleF edgeBounds = m_renderer.GetBounds(edge, m_d2dGraphics);

            if (!clipBounds.IntersectsWith(edgeBounds))
            {
                return;
            }

            DiagramDrawingStyle style = GetStyle(edge);

            m_renderer.Draw(edge, style, m_d2dGraphics);
        }
Ejemplo n.º 10
0
        private void DrawAssociatedEdges(TNode node, RectangleF clipBounds)
        {
            var edges = m_nodeEdges.Find(node);

            foreach (var edge in edges)
            {
                int edgeVisit = m_edgeNodeEncounter[edge] + 1;
                m_edgeNodeEncounter[edge] = edgeVisit;
                if (edgeVisit == 2)
                {
                    RectangleF          bounds = m_renderer.GetBounds(edge, m_d2dGraphics);
                    DiagramDrawingStyle style  = GetStyle(edge);
                    if (clipBounds.IntersectsWith(bounds) && style != DiagramDrawingStyle.Hidden)
                    {
                        m_renderer.Draw(edge, style, m_d2dGraphics);
                    }
                }
            }
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Gets the theme's brush (pen) for the given drawing style</summary>
        /// <param name="style">Drawing style</param>
        /// <returns>Brush for the given drawing style</returns>
        public D2dBrush GetOutLineBrush(DiagramDrawingStyle style)
        {
            switch (style)
            {
            case DiagramDrawingStyle.Normal:
                return(m_outlineBrush);

            case DiagramDrawingStyle.Selected:
                return(m_highlightBrush);

            case DiagramDrawingStyle.LastSelected:
                return(m_lastHighlightBrush);

            case DiagramDrawingStyle.Hot:
                return(m_hotBrush);

            case DiagramDrawingStyle.DragSource:
                return(m_dragSourceBrush);

            case DiagramDrawingStyle.DropTarget:
                return(m_dropTargetBrush);

            case DiagramDrawingStyle.Ghosted:
                return(m_ghostBrush);

            case DiagramDrawingStyle.Hidden:
                return(m_hiddenBrush);

            case DiagramDrawingStyle.TemplatedInstance:
                return(m_templatedInstance);

            case DiagramDrawingStyle.CopyInstance:
                return(m_copyInstance);

            case DiagramDrawingStyle.Error:
            default:
                return(m_errorBrush);
            }
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Draws a graph node</summary>
        /// <param name="element">Element to draw</param>
        /// <param name="style">Diagram drawing style</param>
        /// <param name="g">Graphics object</param>
        public override void Draw(TElement element, DiagramDrawingStyle style, Graphics g)
        {
            switch (style)
            {
            case DiagramDrawingStyle.Normal:
                Draw(element, g);
                break;

            case DiagramDrawingStyle.Selected:
            case DiagramDrawingStyle.LastSelected:
            case DiagramDrawingStyle.Hot:
            default:
                Draw(element, g);
                DrawOutline(element, m_theme.GetPen(style), g);
                break;

            case DiagramDrawingStyle.Ghosted:
            case DiagramDrawingStyle.Hidden:
                DrawGhost(element, g);
                break;
            }
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Draws a graph, using an optional selection to determine which nodes should be
        /// highlighted</summary>
        /// <param name="graph">Graph to render</param>
        /// <param name="selection">Selection containing graph nodes and edges, or null</param>
        /// <param name="g">Graphics device</param>
        public void Draw(IGraph <TNode, TEdge, TEdgeRoute> graph, Selection <object> selection, Graphics g)
        {
            foreach (TNode node in graph.Nodes)
            {
                DiagramDrawingStyle style = DiagramDrawingStyle.Normal;
                if (selection != null && selection.Contains(node))
                {
                    if (selection.LastSelected.Equals(node))
                    {
                        style = DiagramDrawingStyle.LastSelected;
                    }
                    else
                    {
                        style = DiagramDrawingStyle.Selected;
                    }
                }

                Draw(node, style, g);
            }

            foreach (TEdge edge in graph.Edges)
            {
                DiagramDrawingStyle style = DiagramDrawingStyle.Normal;
                if (selection != null && selection.Contains(edge))
                {
                    if (selection.LastSelected.Equals(edge))
                    {
                        style = DiagramDrawingStyle.LastSelected;
                    }
                    else
                    {
                        style = DiagramDrawingStyle.Selected;
                    }
                }

                Draw(edge, style, g);
            }
        }
Ejemplo n.º 14
0
            /// <summary>
            /// Renders entire graph</summary>
            protected override void OnRender()
            {
                D2dGraphics.AntialiasMode = D2dAntialiasMode.PerPrimitive;
                Matrix3x2F invMtrx = D2dGraphics.Transform;

                invMtrx.Invert();
                RectangleF boundsGr = Matrix3x2F.Transform(invMtrx, this.AdaptedControl.ClientRectangle);

                // Draw normal nodes on top of edges
                foreach (StateBase node in Graph.Nodes)
                {
                    RectangleF nodeBounds = Renderer.GetBounds(node, D2dGraphics);
                    if (!boundsGr.IntersectsWith(nodeBounds))
                    {
                        continue;
                    }
                    DiagramDrawingStyle style = GetStyle(node);
                    Renderer.Draw(node, style, D2dGraphics);
                }

                // Draw edges last for now. Todo: draw in layers, with edges and then nodes for each layer
                foreach (Transition edge in Graph.Edges)
                {
                    if (edge == HiddenEdge)
                    {
                        continue;
                    }

                    RectangleF edgeBounds = Renderer.GetBounds(edge, D2dGraphics);
                    if (!boundsGr.IntersectsWith(edgeBounds))
                    {
                        continue;
                    }

                    DiagramDrawingStyle style = GetStyle(edge);
                    Renderer.Draw(edge, style, D2dGraphics);
                }
            }
Ejemplo n.º 15
0
        /// <summary>
        /// Draws a graph node</summary>
        /// <param name="node">Node to draw</param>
        /// <param name="style">Diagram drawing style</param>
        /// <param name="g">Graphics object</param>
        public override void Draw(TNode node, DiagramDrawingStyle style, Graphics g)
        {
            switch (style)
            {
            case DiagramDrawingStyle.Normal:
                Draw(node, g);
                break;

            case DiagramDrawingStyle.Selected:
            case DiagramDrawingStyle.LastSelected:
            case DiagramDrawingStyle.Hot:
            case DiagramDrawingStyle.Error:
                Draw(node, g);
                DrawOutline(node, m_theme.GetPen(style), g);
                break;

            case DiagramDrawingStyle.Ghosted:
            case DiagramDrawingStyle.Hidden:
            default:
                DrawGhost(node, g);
                break;
            }
        }
Ejemplo n.º 16
0
 /// <summary>
 /// Draws a graph edge</summary>
 /// <param name="edge">Edge to draw</param>
 /// <param name="style">Diagram drawing style</param>
 /// <param name="g">Graphics object</param>
 public abstract void Draw(TEdge edge, DiagramDrawingStyle style, Graphics g);
Ejemplo n.º 17
0
 /// <summary>
 /// Draws a graph node</summary>
 /// <param name="node">Node to draw</param>
 /// <param name="style">Diagram drawing style</param>
 /// <param name="g">Graphics object</param>
 public abstract void Draw(TNode node, DiagramDrawingStyle style, Graphics g);
Ejemplo n.º 18
0
 /// <summary>
 /// Sets the rendering style for a diagram item. This style will override the
 /// normal style used by the graph adapter.</summary>
 /// <param name="item">Rendered item</param>
 /// <param name="style">Diagram style to use for item</param>
 public void SetStyle(object item, DiagramDrawingStyle style)
 {
     m_styles[item] = style;
 }
Ejemplo n.º 19
0
        private void DrawAnnotation(IAnnotation annotation, DiagramDrawingStyle style, Graphics g)
        {
            Rectangle bounds = annotation.Bounds;
            if (bounds.Size.IsEmpty)
            {
                // calculate size of text block
                SizeF textSizeF = g.MeasureString(annotation.Text, m_theme.Font);
                Size textSize = new Size((int)Math.Ceiling(textSizeF.Width), (int)Math.Ceiling(textSizeF.Height));
                bounds.Size = textSize;
                annotation.SetTextSize(textSize);
            }
            g.FillRectangle(SystemBrushes.Info, bounds);
            if ((style & DiagramDrawingStyle.Ghosted) == 0)
            {
                g.DrawString(annotation.Text, m_theme.Font, SystemBrushes.WindowText, bounds);

                Pen pen = null;
                if ((style & DiagramDrawingStyle.LastSelected) != 0)
                    pen = m_theme.LastHighlightPen;
                else if ((style & DiagramDrawingStyle.Selected) != 0)
                    pen = m_theme.HighlightPen;

                if (pen != null)
                    g.DrawRectangle(pen, bounds);
            }
        }
Ejemplo n.º 20
0
        /// <summary>
        /// Gets the current rendering style for an item</summary>
        /// <param name="item">Rendered item</param>
        /// <returns>Rendering style set by SetStyle, Normal if no override is set</returns>
        public virtual DiagramDrawingStyle GetStyle(object item)
        {
            DiagramDrawingStyle result = DiagramDrawingStyle.Normal;

            // no override
            if (m_visibilityContext != null && !m_visibilityContext.IsVisible(item))
            {
                result = DiagramDrawingStyle.Hidden;
            }
            else if (item == m_hoverObject || item == m_hoverSubObject)
            {
                if (CircuitUtil.IsGroupTemplateInstance(item))
                {
                    result = DiagramDrawingStyle.TemplatedInstance;
                }
                else if (item.Is <Group>())
                {
                    result = DiagramDrawingStyle.CopyInstance;
                }
                else
                {
                    result = DiagramDrawingStyle.Hot;
                }
            }
            else if (m_selectionContext != null && m_selectionContext.SelectionContains(item))
            {
                if (m_selectionContext.LastSelected.Equals(item))
                {
                    result = DiagramDrawingStyle.LastSelected;
                }
                else
                {
                    result = DiagramDrawingStyle.Selected;
                }
            }
            else if (m_selectionPathProvider != null && m_selectionPathProvider.IncludedPath(item) != null)
            {
                if (CircuitUtil.IsGroupTemplateInstance(item))
                {
                    result = DiagramDrawingStyle.TemplatedInstance;
                }
                else if (item.Is <Group>())
                {
                    result = DiagramDrawingStyle.CopyInstance;
                }
                else
                {
                    result = DiagramDrawingStyle.Hot;
                }
            }
            else if (m_renderer.RouteConnecting != null)
            {
                // connection context cue: highlight edges that connect to the starting node
                if (item.Is <TEdge>())
                {
                    var edge = item.Cast <TEdge>();
                    if (m_renderer.RouteConnecting.StartNode.Equals(edge.FromNode) ||
                        m_renderer.RouteConnecting.StartNode.Equals(edge.ToNode))
                    {
                        result = DiagramDrawingStyle.Hot;
                    }
                }
            }
            return(result);
        }
Ejemplo n.º 21
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
                                  : (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();
        }
Ejemplo n.º 22
0
 /// <summary>
 /// Draws a graph edge</summary>
 /// <param name="edge">Edge to draw</param>
 /// <param name="style">Diagram drawing style</param>
 /// <param name="g">Graphics object</param>
 public override void Draw(TEdge edge, DiagramDrawingStyle style, Graphics g)
 {
     Draw(edge, m_theme.GetPen(style), g);
 }
Ejemplo n.º 23
0
        /// <summary>
        /// Draws floating group pin</summary>
        /// <param name="grpPin">Group pin</param>
        /// <param name="inputSide">True for input pin, false for output pin</param>
        /// <param name="style">DiagramDrawingStyle</param>
        /// <param name="g">Graphics object</param>
        public void DrawFloatingGroupPin(ICircuitGroupPin <TElement> grpPin, bool inputSide, DiagramDrawingStyle style, D2dGraphics g)
        {
            SizeF  pinNameSize = g.MeasureText(grpPin.Name, Theme.TextFormat);
            PointF p;

            if (inputSide)
            {
                p = GetGroupPinLocation(grpPin, true);

                RectangleF pinRect = new RectangleF(p.X + CircuitGroupPinInfo.FloatingPinBoxWidth - Theme.PinSize,
                                                    grpPin.Bounds.Location.Y + Theme.PinMargin + Theme.PinOffset,
                                                    Theme.PinSize, Theme.PinSize);
                // draw output pin for input floating pins
                g.DrawRectangle(pinRect, m_subGraphPinPen);
                if (grpPin.Info.Pinned)
                {
                    D2dUtil.DrawPin((int)(p.X + CircuitGroupPinInfo.FloatingPinBoxWidth), (int)p.Y, true, true, m_pinBrush, g);
                }
                else
                {
                    D2dUtil.DrawPin((int)(p.X + CircuitGroupPinInfo.FloatingPinBoxWidth), (int)p.Y + Theme.PinSize / 2, false, true, m_pinBrush, g);
                }

                RectangleF bounds    = new RectangleF(p.X, p.Y, CircuitGroupPinInfo.FloatingPinBoxWidth, CircuitGroupPinInfo.FloatingPinBoxHeight);
                RectangleF alignRect = new RectangleF(
                    bounds.Left, bounds.Bottom + Theme.PinMargin, pinNameSize.Width, Theme.RowSpacing);
                var textAlignment = Theme.TextFormat.TextAlignment;
                Theme.TextFormat.TextAlignment = D2dTextAlignment.Leading;
                g.DrawText(grpPin.Name, Theme.TextFormat, alignRect.Location, Theme.TextBrush);
                Theme.TextFormat.TextAlignment = textAlignment;
            }
            else
            {
                // assume vertical scroll bar width = 16
                p = GetGroupPinLocation(grpPin, false);

                RectangleF pinRect = new RectangleF(p.X + 1, grpPin.Bounds.Location.Y + Theme.PinMargin + Theme.PinOffset,
                                                    Theme.PinSize, Theme.PinSize);
                // draw input pin for output floating pins
                g.DrawRectangle(pinRect, m_subGraphPinPen);
                // draw pin icon
                if (grpPin.Info.Pinned)
                {
                    D2dUtil.DrawPin((int)p.X, (int)p.Y, true, false, m_pinBrush, g);
                }
                else
                {
                    D2dUtil.DrawPin((int)p.X, (int)p.Y + Theme.PinSize / 2, false, false, m_pinBrush, g);
                }

                // draw label
                RectangleF bounds     = new RectangleF(p.X, p.Y, CircuitGroupPinInfo.FloatingPinBoxWidth, CircuitGroupPinInfo.FloatingPinBoxHeight);
                RectangleF alignRectF = new RectangleF(bounds.Right - pinNameSize.Width, bounds.Bottom + Theme.PinMargin,
                                                       pinNameSize.Width, Theme.RowSpacing);

                var textAlignment = Theme.TextFormat.TextAlignment;
                Theme.TextFormat.TextAlignment = D2dTextAlignment.Trailing;
                g.DrawText(grpPin.Name, Theme.TextFormat, alignRectF, Theme.TextBrush);
                Theme.TextFormat.TextAlignment = textAlignment;
            }

            // draw the fake pin node itself
            float savedStrokeWidth = Theme.StrokeWidth;

            Theme.StrokeWidth = 2.0f;
            if (style == DiagramDrawingStyle.Normal)
            {
                g.DrawRectangle(new RectangleF(p.X, p.Y, CircuitGroupPinInfo.FloatingPinBoxWidth, CircuitGroupPinInfo.FloatingPinBoxHeight), m_subGraphPinNodePen);
            }
            else
            {
                g.DrawRectangle(new RectangleF(p.X, p.Y, CircuitGroupPinInfo.FloatingPinBoxWidth, CircuitGroupPinInfo.FloatingPinBoxHeight), Theme.HotBrush);
            }
            Theme.StrokeWidth = savedStrokeWidth;


            if (!grpPin.Info.ExternalConnected)
            {
                RectangleF eyeRect = GetVisibilityCheckRect(grpPin, inputSide);
                g.DrawEyeIcon(eyeRect, grpPin.Info.Visible ? m_visiblePinBrush : m_hiddrenPinBrush, 1.0f);
            }

            // draw fake edge that connects group pin fake node
            DrawGroupPinNodeFakeEdge(grpPin, p, inputSide, style, g);
        }
Ejemplo n.º 24
0
        /// <summary>
        /// Renders entire graph</summary>
        protected virtual void OnRender()
        {
            try
            {
                m_renderer.GetStyle         = GetStyle;
                m_d2dGraphics.AntialiasMode = D2dAntialiasMode.PerPrimitive;
                Matrix3x2F invMtrx = m_d2dGraphics.Transform;
                invMtrx.Invert();
                RectangleF boundsGr = Matrix3x2F.Transform(invMtrx, this.AdaptedControl.ClientRectangle);

                // Either draw (most) edges first or prepare multimaps for draw-as-we-go edges.
                if (EdgeRenderPolicy == DrawEdgePolicy.AllFirst)
                {
                    foreach (var edge in m_graph.Edges)
                    {
                        if (edge == m_hiddenEdge)
                        {
                            continue;
                        }
                        RectangleF bounds = m_renderer.GetBounds(edge, m_d2dGraphics);
                        if (!boundsGr.IntersectsWith(bounds))
                        {
                            continue;
                        }

                        var group = edge.FromNode.As <ICircuitGroupType <TNode, TEdge, TEdgeRoute> >();
                        if (group == null || !group.Expanded)
                        {
                            group = edge.ToNode.As <ICircuitGroupType <TNode, TEdge, TEdgeRoute> >();
                        }
                        if (group != null && group.Expanded)
                        {
                            m_edgesOnGroups.Add(edge);
                        }
                        else
                        {
                            DiagramDrawingStyle style = GetStyle(edge);
                            m_renderer.Draw(edge, style, m_d2dGraphics);
                        }
                    }
                }
                else
                {
                    // build node to edge maps
                    foreach (TEdge edge in m_graph.Edges)
                    {
                        m_nodeEdges.Add(edge.FromNode, edge);
                        m_nodeEdges.Add(edge.ToNode, edge);
                        m_edgeNodeEncounter.Add(edge, 0);
                    }
                }

                // Draw normal nodes first
                TNode containerOfSelectedNode = null;

                foreach (var node in m_graph.Nodes)
                {
                    RectangleF nodeBounds = m_renderer.GetBounds(node, m_d2dGraphics);
                    if (boundsGr.IntersectsWith(nodeBounds))
                    {
                        DiagramDrawingStyle drawStyle = GetStyle(node);

                        // Draw all dragged nodes (even expanded groups) last.
                        if (drawStyle == DiagramDrawingStyle.DragSource)
                        {
                            m_draggingNodes.Add(node);
                        }
                        else
                        {
                            // Draw selected nodes after normal nodes. If the node
                            //  is hot, check if it's selected.
                            if (drawStyle == DiagramDrawingStyle.Selected ||
                                drawStyle == DiagramDrawingStyle.LastSelected ||
                                (drawStyle == DiagramDrawingStyle.Hot && m_selectionContext != null &&
                                 m_selectionContext.SelectionContains(node)))
                            {
                                m_selectedNodes.Add(node);
                            }
                            else
                            {
                                // Expanded groups are drawn after normal nodes.
                                bool expandedGroup = false;
                                var  group         = node.As <ICircuitGroupType <TNode, TEdge, TEdgeRoute> >();
                                if (group != null)
                                {
                                    group.Info.PickingPriority = 0;
                                    if (group.Expanded)
                                    {
                                        if (node == ActiveContainer())
                                        {
                                            containerOfSelectedNode = node;
                                        }
                                        else
                                        {
                                            m_expandedGroups.Add(node);
                                        }
                                        expandedGroup = true;
                                    }
                                }

                                // Draw normal nodes and collapsed groups.
                                if (!expandedGroup)
                                {
                                    m_renderer.Draw(node, drawStyle, m_d2dGraphics);
                                    if (EdgeRenderPolicy == DrawEdgePolicy.Associated)
                                    {
                                        DrawAssociatedEdges(node, boundsGr);
                                    }
                                }
                            }
                        }
                    }
                    else if (EdgeRenderPolicy == DrawEdgePolicy.Associated)
                    {
                        DrawAssociatedEdges(node, boundsGr);
                    }
                }

                // Draw expanded groups on top of normal sibling nodes, so that normal nodes that overlap
                //  these groups don't appear as if they are in the groups.
                int pickPriority = 0;
                foreach (var node in m_expandedGroups)
                {
                    var group = node.Cast <ICircuitGroupType <TNode, TEdge, TEdgeRoute> >();
                    group.Info.PickingPriority = pickPriority++;
                    m_renderer.Draw(node, GetStyle(node), m_d2dGraphics);
                    if (EdgeRenderPolicy == DrawEdgePolicy.Associated)
                    {
                        DrawAssociatedEdges(node, boundsGr);
                    }
                }

                // Draw the expanded group that contains a selected or dragged child node, so that
                //  if multiple expanded groups overlap, that the user can see the owning group.
                if (containerOfSelectedNode != null)
                {
                    var group = containerOfSelectedNode.Cast <ICircuitGroupType <TNode, TEdge, TEdgeRoute> >();
                    group.Info.PickingPriority = pickPriority++;
                    m_renderer.Draw(containerOfSelectedNode, GetStyle(containerOfSelectedNode), m_d2dGraphics);
                    if (EdgeRenderPolicy == DrawEdgePolicy.Associated)
                    {
                        DrawAssociatedEdges(containerOfSelectedNode, boundsGr);
                    }
                }

                // Draw selected nodes.
                foreach (var node in m_selectedNodes)
                {
                    var group = node.As <ICircuitGroupType <TNode, TEdge, TEdgeRoute> >();
                    if (group != null)
                    {
                        group.Info.PickingPriority = pickPriority++;
                    }
                    m_renderer.Draw(node, GetStyle(node), m_d2dGraphics);
                    if (EdgeRenderPolicy == DrawEdgePolicy.Associated)
                    {
                        DrawAssociatedEdges(node, boundsGr);
                    }
                }


                // Draw dragging nodes last to ensure they are visible (necessary for container-crossing move operation)
                foreach (var node in m_draggingNodes)
                {
                    m_renderer.Draw(node, DiagramDrawingStyle.DragSource, m_d2dGraphics);
                    if (EdgeRenderPolicy == DrawEdgePolicy.Associated)
                    {
                        DrawAssociatedEdges(node, boundsGr);
                    }
                }

                // Draw "all first" edges that connect to expanded groups.
                foreach (var edge in m_edgesOnGroups)
                {
                    DiagramDrawingStyle style = GetStyle(edge);
                    m_renderer.Draw(edge, style, m_d2dGraphics);
                }
            }
            finally
            {
                m_nodeEdges.Clear();
                m_edgeNodeEncounter.Clear();
                m_draggingNodes.Clear();
                m_selectedNodes.Clear();
                m_expandedGroups.Clear();
                m_edgesOnGroups.Clear();
            }
        }
Ejemplo n.º 25
0
        private void control_Paint(object sender, PaintEventArgs e)
        {
            if (m_annotatedDiagram == null)
            {
                return;
            }

            Graphics g            = e.Graphics;
            Matrix   oldTransform = null;
            PointF   delta        = Delta;

            if (m_transformAdapter != null)
            {
                // modify the transform so it is only a translation and uniform scale
                oldTransform = e.Graphics.Transform;
                float[] m            = m_transformAdapter.Transform.Elements;
                float   scale        = Math.Min(m[0], m[3]);
                Matrix  newTransform = new Matrix(scale, m[1], m[2], scale, m[4], m[5]);
                g.Transform = newTransform;

                delta = GdiUtil.InverseTransformVector(newTransform, delta);
            }

            // draw all annotations in their current position, ghosting those which are dragging
            foreach (IAnnotation annotation in m_annotatedDiagram.Annotations)
            {
                DiagramDrawingStyle style = DiagramDrawingStyle.Normal;
                if (m_annotationSet != null &&
                    m_annotationSet.Contains(annotation))
                {
                    style = DiagramDrawingStyle.Ghosted;
                }
                else if (m_selectionContext.SelectionContains(annotation))
                {
                    style = DiagramDrawingStyle.Selected;
                    if (m_selectionContext.GetLastSelected <IAnnotation>() == annotation)
                    {
                        style = DiagramDrawingStyle.LastSelected;
                    }
                }
                DrawAnnotation(annotation, style, g);
            }

            if (m_draggingAnnotations != null)
            {
                // set dragged nodes' positions, offsetting by drag delta and applying layout constraints
                for (int i = 0; i < m_draggingAnnotations.Length; i++)
                {
                    IAnnotation annotation = m_draggingAnnotations[i];
                    Rectangle   oldBounds  = GetBounds(annotation);
                    Rectangle   newBounds  = oldBounds;
                    newBounds.X      += (int)delta.X;
                    newBounds.Y      += (int)delta.Y;
                    m_newPositions[i] = newBounds.Location;
                    m_layoutContext.SetBounds(annotation, newBounds, BoundsSpecified.Location);

                    DrawAnnotation(annotation, DiagramDrawingStyle.Normal, g);

                    m_layoutContext.SetBounds(annotation, oldBounds, BoundsSpecified.Location);
                }
            }

            if (m_transformAdapter != null)
            {
                g.Transform = oldTransform;
            }
        }
Ejemplo n.º 26
0
 /// <summary>
 /// Draws a graph edge</summary>
 /// <param name="edge">Edge to draw</param>
 /// <param name="style">Diagram drawing style</param>
 /// <param name="g">Graphics object</param>
 public override void Draw(TEdge edge, DiagramDrawingStyle style, D2dGraphics g)
 {
     Draw(edge, m_theme.GetOutLineBrush(style), g);
 }
Ejemplo n.º 27
0
        private void DrawGroupPinNodeFakeEdge(ICircuitGroupPin <TElement> grpPin, PointF grpPinPos, bool inputSide, DiagramDrawingStyle style, D2dGraphics g)
        {
            ElementTypeInfo info = GetElementTypeInfo(grpPin.InternalElement, g);

            if (inputSide)
            {
                PointF op = grpPinPos;
                float  x1 = op.X + CircuitGroupPinInfo.FloatingPinBoxWidth;
                float  y1 = op.Y + CircuitGroupPinInfo.FloatingPinBoxHeight / 2;

                Point ip = grpPin.InternalElement.Bounds.Location;
                float x2 = ip.X;
                float y2 = ip.Y + GetPinOffset(grpPin.InternalElement, grpPin.InternalPinIndex, true);

                DrawWire(g, m_fakeInputLinkPen, x1, y1, x2, y2, 1.0f, m_VirtualLinkStrokeStyle);
            }
            else
            {
                Point op = grpPin.InternalElement.Bounds.Location;
                float x1 = op.X + info.Size.Width;
                float y1 = op.Y + GetPinOffset(grpPin.InternalElement, grpPin.InternalPinIndex, false);

                PointF ip = grpPinPos;
                float  x2 = ip.X;
                float  y2 = ip.Y + CircuitGroupPinInfo.FloatingPinBoxHeight / 2;
                DrawWire(g, m_fakeOutputLinkPen, x1, y1, x2, y2, 1.0f, m_VirtualLinkStrokeStyle);
            }
        }
Ejemplo n.º 28
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);
                }                
            }                
        }