d1b3abc1dae91e1fd11ab78cb05c29b5d12daf3b
[mono.git] / mcs / class / referencesource / System.Activities.Presentation / System.Activities.Core.Presentation / System / Activities / Core / Presentation / FlowchartConnectionPointsAdorner.cs
1 //----------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation.  All rights reserved.
3 //----------------------------------------------------------------
4
5 namespace System.Activities.Core.Presentation
6 {
7     using System.Activities.Presentation;
8     using System.Activities.Presentation.FreeFormEditing;
9     using System.Activities.Presentation.View;
10     using System.Collections.Generic;
11     using System.Diagnostics;
12     using System.Windows;
13     using System.Windows.Documents;
14     using System.Windows.Input;
15     using System.Windows.Media;
16     using System.Runtime;
17
18     internal class FlowchartConnectionPointsAdorner : ConnectionPointsAdorner
19     {
20         private bool isTextRightToLeft;
21
22         public FlowchartConnectionPointsAdorner(UIElement adornedElement, List<ConnectionPoint> connectionPointsToShow, bool isParentShapeSelected, bool isTextRightToLeft)
23             : base(adornedElement, connectionPointsToShow, isParentShapeSelected)
24         {
25             this.isTextRightToLeft = isTextRightToLeft;
26             this.FlowDirection = isTextRightToLeft ? FlowDirection.RightToLeft : FlowDirection.LeftToRight;
27         }
28
29         protected override void OnRender(DrawingContext drawingContext)
30         {
31             const int textCulture = 9;
32
33             ConnectionPoint trueConnectionPoint = null;
34             ConnectionPoint falseConnectionPoint = null;
35
36             if (this.connectionPoints.Contains(FlowchartDesigner.GetTrueConnectionPoint(this.AdornedElement)))
37             {
38                 trueConnectionPoint = FlowchartDesigner.GetTrueConnectionPoint(this.AdornedElement);
39             }
40             if (this.connectionPoints.Contains(FlowchartDesigner.GetFalseConnectionPoint(this.AdornedElement)))
41             {
42                 falseConnectionPoint = FlowchartDesigner.GetFalseConnectionPoint(this.AdornedElement);
43             }
44             Point actualPoint;
45             Point origin = FreeFormPanel.GetLocation(AdornedElement);
46             Thickness margin = ((FrameworkElement)AdornedElement).Margin;
47             origin.X += margin.Left;
48             origin.Y += margin.Top;
49
50             foreach (ConnectionPoint connPoint in this.connectionPoints)
51             {
52                 actualPoint = new Point(connPoint.Location.X - origin.X, connPoint.Location.Y - origin.Y);
53                 this.DrawConnectionPoint(connPoint, actualPoint, drawingContext);
54             }
55             
56             if (trueConnectionPoint != null)
57             {
58                 string trueLabelText = String.Empty;
59
60                 VirtualizedContainerService.VirtualizingContainer virtualizingContainer = (VirtualizedContainerService.VirtualizingContainer)trueConnectionPoint.ParentDesigner;
61                 if (virtualizingContainer != null && virtualizingContainer.ModelItem != null)
62                 {
63                     trueLabelText = (string)virtualizingContainer.ModelItem.Properties["TrueLabel"].ComputedValue;
64                 }
65
66                 actualPoint = new Point(trueConnectionPoint.Location.X - origin.X, trueConnectionPoint.Location.Y - origin.Y);
67                 FormattedText trueMarkerFormattedText = new FormattedText(trueLabelText, new System.Globalization.CultureInfo(textCulture),
68                     this.FlowDirection, FlowchartDesigner.FlowElementCaptionTypeface, FlowchartDesigner.FlowNodeCaptionFontSize,
69                     new SolidColorBrush(WorkflowDesignerColors.WorkflowViewElementCaptionColor));
70                 actualPoint.Y += ConnectionPoint.DrawingLargeSide / 2;
71                 actualPoint.X -= trueMarkerFormattedText.WidthIncludingTrailingWhitespace;
72
73                 DrawtWithTransform(
74                     drawingContext,
75                     this.isTextRightToLeft,
76                     // Mirror the left side text to the right side by using this axis when RTL.
77                     actualPoint.X,
78                     () =>
79                     {
80                         drawingContext.DrawText(trueMarkerFormattedText, actualPoint);
81                     });
82                 
83             }
84             if (falseConnectionPoint != null)
85             {
86                 string falseLabelText = String.Empty;
87
88                 VirtualizedContainerService.VirtualizingContainer virtualizingContainer = (VirtualizedContainerService.VirtualizingContainer)falseConnectionPoint.ParentDesigner;
89                 if (virtualizingContainer != null && virtualizingContainer.ModelItem != null)
90                 {
91                     falseLabelText = (string)virtualizingContainer.ModelItem.Properties["FalseLabel"].ComputedValue;
92                 }
93
94                 actualPoint = new Point(falseConnectionPoint.Location.X - origin.X, falseConnectionPoint.Location.Y - origin.Y);
95                 actualPoint.Y += ConnectionPoint.DrawingLargeSide / 2;
96
97                 FormattedText falseMarkerFormattedText = new FormattedText(falseLabelText, new System.Globalization.CultureInfo(textCulture),
98                     this.FlowDirection, FlowchartDesigner.FlowElementCaptionTypeface, FlowchartDesigner.FlowNodeCaptionFontSize,
99                     new SolidColorBrush(WorkflowDesignerColors.WorkflowViewElementCaptionColor));
100
101                 DrawtWithTransform(
102                     drawingContext,
103                     this.isTextRightToLeft,
104                     // Mirror the left side text to the right side by using this axis when RTL.
105                     actualPoint.X,
106                     () =>
107                     {
108                         drawingContext.DrawText(falseMarkerFormattedText, actualPoint);
109                     });
110             }
111
112             base.OnRender(drawingContext);
113         }
114
115         private static void DrawtWithTransform(DrawingContext drawingContext, bool isRightToLeft, double axis, Action doDraw)
116         {
117             if (isRightToLeft)
118             {
119                 /* We hope to mirror the Text using yAxis as axis, like from (a) to (b)
120                  * |                                 |
121                  * |    ==>= =>==>                   |     <==<= =<==
122                  * |--------|------> x               |----------|--------> x
123                  * y       axis    (a)              y           axis      (b)
124                  *  
125                  * So we do it in three steps:
126                  * 1) move text so that axis and y are coincident
127                  * |                                            | 
128                  * |    ==>= =>==>                          ==>=|=>==>
129                  * |--------|------> x                ----------|---------> x
130                  * y       axis                                y(axis)
131                  * 
132                  * 2) mirror
133                  *         |                                   | 
134                  *     ==>=|=>==>                          <=<=|=<==
135                  * --------|------> x                ----------|---------> x
136                  *       y(axis)                              y(axis)
137                  * 
138                  * 3) move back
139                  *         |                         |           
140                  *     <=<=|=<==                     |     <=<= =<==
141                  * --------|------> x                |---------|----------> x
142                  *         y                         y        axis 
143                  *         
144                  * 
145                  *              |  1   0   0 |   | -1 0 0 |   |   1    0   0 |   |  -1     0    0 |
146                  *  transform = |  0   1   0 | x |  0 1 0 | x |   0    1   0 | = |   0     1    0 |
147                  *              | axis 0   1 |   |  0 0 1 |   | -axis  0   0 |   | 2*axis  0    1 |
148                  */
149
150                 MatrixTransform transform = new MatrixTransform(-1, 0, 0, 1, 2 * axis, 0);
151                 drawingContext.PushTransform(transform);
152                 doDraw();
153                 drawingContext.Pop();
154             }
155             else
156             {
157                 doDraw();
158             }
159         }
160     }
161 }