Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Problems.GrammaticalOptimization/SharpVectorConverters/LinkVisitor.cs @ 13834

Last change on this file since 13834 was 12762, checked in by aballeit, 9 years ago

#2283 GUI updates, Tree-chart, MCTS Version 2 (prune leaves)

File size: 13.7 KB
Line 
1using System;
2using System.Xml;
3using System.Text;
4using System.Collections.Generic;
5
6using System.Windows;
7using System.Windows.Media;
8
9using SharpVectors.Dom.Svg;
10using SharpVectors.Runtime;
11using SharpVectors.Renderers.Wpf; 
12
13namespace SharpVectors.Converters
14{
15    public sealed class LinkVisitor : WpfLinkVisitor
16    {
17        #region Private Fields
18
19        private bool                _isAggregated;
20        private GeometryCollection  _aggregatedGeom;
21
22        private SvgStyleableElement _aggregatedFill;
23
24        private Dictionary<string, bool> _dicLinks;
25
26        #endregion
27
28        #region Constructors and Destructor
29
30        public LinkVisitor()
31        {
32            _dicLinks = new Dictionary<string, bool>();
33        }
34
35        #endregion
36
37        #region Public Properties
38
39        public override bool Aggregates
40        {
41            get
42            {
43                return true;
44            }
45        }
46
47        public override bool IsAggregate
48        {
49            get
50            {
51                return _isAggregated;
52            }
53        }
54
55        public override string AggregatedLayerName
56        {
57            get
58            {
59                return SvgObject.LinksLayer;
60            }
61        }
62
63        #endregion
64
65        #region Public Methods
66
67        public override bool Exists(string linkId)
68        {
69            if (String.IsNullOrEmpty(linkId))
70            {
71                return false;
72            }
73
74            if (_dicLinks != null && _dicLinks.Count != 0)
75            {
76                return _dicLinks.ContainsKey(linkId);
77            }
78
79            return false;
80        }
81
82        public override void Initialize(DrawingGroup linkGroup, WpfDrawingContext context)
83        {
84            if (linkGroup != null)
85            {
86                SvgLink.SetKey(linkGroup, SvgObject.LinksLayer);
87            }
88        }
89
90        public override void Visit(DrawingGroup group, SvgAElement element,
91            WpfDrawingContext context, float opacity)
92        {
93            _isAggregated = false;
94
95            if (group == null || element == null || context == null)
96            {
97                return;
98            }
99
100            AddExtraLinkInformation(group, element);
101
102            //string linkId = element.GetAttribute("id");
103            string linkId = GetElementName(element);
104            if (String.IsNullOrEmpty(linkId))
105            {
106                return;
107            }
108            SvgLink.SetKey(group, linkId);
109
110            if (_dicLinks.ContainsKey(linkId))
111            {
112                _isAggregated = _dicLinks[linkId];
113                return;
114            }
115
116            string linkAction = element.GetAttribute("onclick");
117            if (String.IsNullOrEmpty(linkAction))
118            {
119                linkAction = element.GetAttribute("onmouseover");
120                if (!String.IsNullOrEmpty(linkAction) &&
121                    linkAction.StartsWith("parent.svgMouseOverName", StringComparison.OrdinalIgnoreCase))
122                {
123                    SvgLink.SetAction(group, SvgLinkAction.LinkTooltip);
124                }
125                else
126                {
127                    SvgLink.SetAction(group, SvgLinkAction.LinkNone);
128                }
129            }
130            else
131            {
132                if (linkAction.StartsWith("parent.svgClick", StringComparison.OrdinalIgnoreCase))
133                {
134                    SvgLink.SetAction(group, SvgLinkAction.LinkPage);
135                }
136                else if (linkAction.StartsWith("parent.svgOpenHtml", StringComparison.OrdinalIgnoreCase))
137                {
138                    SvgLink.SetAction(group, SvgLinkAction.LinkHtml);
139                }
140                else
141                {
142                    SvgLink.SetAction(group, SvgLinkAction.LinkNone);
143                }
144            }
145
146            if (!String.IsNullOrEmpty(linkAction))
147            {   
148                if (linkAction.IndexOf("'Top'") > 0)
149                {
150                    SvgLink.SetLocation(group, "Top");
151                }
152                else if (linkAction.IndexOf("'Bottom'") > 0)
153                {
154                    SvgLink.SetLocation(group, "Bottom");
155                }
156                else
157                {
158                    SvgLink.SetLocation(group, "Top");
159                }
160            }
161
162            this.AggregateChildren(element, context, opacity);
163            if (_isAggregated)
164            {
165                Geometry drawGeometry = null;
166                if (_aggregatedGeom.Count == 1)
167                {
168                    drawGeometry = _aggregatedGeom[0];
169                }
170                else
171                {
172                    GeometryGroup geomGroup = new GeometryGroup();
173                    geomGroup.FillRule = FillRule.Nonzero;
174                   
175                    for (int i = 0; i < _aggregatedGeom.Count; i++)
176                    {
177                        geomGroup.Children.Add(_aggregatedGeom[i]);
178                    }
179
180                    drawGeometry = geomGroup;
181                }
182
183                WpfSvgPaint fillPaint = new WpfSvgPaint(context, _aggregatedFill, "fill");
184                Brush brush = fillPaint.GetBrush(false);
185
186                brush.SetValue(FrameworkElement.NameProperty, linkId + "_Brush");
187
188                GeometryDrawing drawing = new GeometryDrawing(brush, null, drawGeometry);
189
190                group.Children.Add(drawing);               
191            }
192
193            _dicLinks.Add(linkId, _isAggregated);
194        }
195
196        public static string GetElementName(SvgElement element)
197        {
198            if (element == null)
199            {
200                return String.Empty;
201            }
202            string elementId = element.Id;
203            if (elementId != null)
204            {
205                elementId = elementId.Trim();
206            }
207            if (String.IsNullOrEmpty(elementId))
208            {
209                return String.Empty;
210            }
211            elementId = elementId.Replace(':', '_');
212            elementId = elementId.Replace(" ", String.Empty);
213            elementId = elementId.Replace('.', '_');
214            elementId = elementId.Replace('-', '_');
215
216            return elementId;
217        }
218
219        #endregion
220
221        #region Private Methods
222
223        private void AddExtraLinkInformation(DrawingGroup group, SvgElement element)
224        {
225            string linkColor = element.GetAttribute("color");
226            if (!String.IsNullOrEmpty(linkColor))
227            {
228                SvgLink.SetColor(group, linkColor);
229            }
230            string linkPartsId = element.GetAttribute("partsid");
231            if (!String.IsNullOrEmpty(linkPartsId))
232            {
233                SvgLink.SetPartsId(group, linkPartsId);
234            }
235            string linkType = element.GetAttribute("type");
236            if (!String.IsNullOrEmpty(linkType))
237            {
238                SvgLink.SetPartsId(group, linkType);
239            }
240            string linkNumber = element.GetAttribute("num");
241            if (!String.IsNullOrEmpty(linkNumber))
242            {
243                SvgLink.SetPartsId(group, linkNumber);
244            }
245            string linkPin = element.GetAttribute("pin");
246            if (!String.IsNullOrEmpty(linkPin))
247            {
248                SvgLink.SetPartsId(group, linkPin);
249            }
250            string linkLineId = element.GetAttribute("lineid");
251            if (!String.IsNullOrEmpty(linkLineId))
252            {
253                SvgLink.SetPartsId(group, linkLineId);
254            }
255        }
256
257        private void AggregateChildren(SvgAElement aElement, WpfDrawingContext context, float opacity)
258        {
259            _isAggregated = false;
260
261            if (aElement == null || aElement.ChildNodes == null)
262            {
263                return;
264            }
265
266            string aggregatedFill = aElement.GetAttribute("fill");
267            bool isFillFound = !String.IsNullOrEmpty(aggregatedFill);
268
269            SvgStyleableElement paintElement = null;
270            if (isFillFound)
271            {
272                paintElement = aElement;
273            }
274
275            XmlNode targetNode = aElement;
276            // Check if the children of the link are wrapped in a Group Element...
277            if (aElement.ChildNodes.Count == 1)
278            {
279                SvgGElement groupElement = aElement.ChildNodes[0] as SvgGElement;
280                if (groupElement != null)
281                {
282                    targetNode = groupElement;
283                }
284            }
285
286            WpfDrawingSettings settings = context.Settings;
287
288            GeometryCollection geomColl = new GeometryCollection();
289
290            foreach (XmlNode node in targetNode.ChildNodes)
291            {
292                if (node.NodeType != XmlNodeType.Element)
293                {
294                    continue;
295                }
296
297                // Handle a case where the clip element has "use" element as a child...
298                if (String.Equals(node.LocalName, "use"))
299                {
300                    SvgUseElement useElement = (SvgUseElement)node;
301
302                    XmlElement refEl = useElement.ReferencedElement;
303                    if (refEl != null)
304                    {
305                        XmlElement refElParent = (XmlElement)refEl.ParentNode;
306                        useElement.OwnerDocument.Static = true;
307                        useElement.CopyToReferencedElement(refEl);
308                        refElParent.RemoveChild(refEl);
309                        useElement.AppendChild(refEl);
310
311                        foreach (XmlNode useChild in useElement.ChildNodes)
312                        {
313                            if (useChild.NodeType != XmlNodeType.Element)
314                            {
315                                continue;
316                            }
317
318                            SvgStyleableElement element = useChild as SvgStyleableElement;
319                            if (element != null && element.RenderingHint == SvgRenderingHint.Shape)
320                            {
321                                Geometry childPath = WpfRendering.CreateGeometry(element,
322                                    settings.OptimizePath);
323
324                                if (childPath != null)
325                                {
326                                    if (isFillFound)
327                                    {
328                                        string elementFill = element.GetAttribute("fill");
329                                        if (!String.IsNullOrEmpty(elementFill) &&
330                                            !String.Equals(elementFill, aggregatedFill, StringComparison.OrdinalIgnoreCase))
331                                        {
332                                            return;
333                                        }
334                                    }
335                                    else
336                                    {
337                                        aggregatedFill = element.GetAttribute("fill");
338                                        isFillFound = !String.IsNullOrEmpty(aggregatedFill);
339                                        if (isFillFound)
340                                        {
341                                            paintElement = element;
342                                        }
343                                    }
344
345                                    geomColl.Add(childPath);
346                                }
347                            }
348                        }
349
350                        useElement.RemoveChild(refEl);
351                        useElement.RestoreReferencedElement(refEl);
352                        refElParent.AppendChild(refEl);
353                        useElement.OwnerDocument.Static = false;
354                    }
355                }
356                //else if (String.Equals(node.LocalName, "g"))
357                //{   
358                //}
359                else
360                {
361                    SvgStyleableElement element = node as SvgStyleableElement;
362                    if (element != null && element.RenderingHint == SvgRenderingHint.Shape)
363                    {
364                        Geometry childPath = WpfRendering.CreateGeometry(element,
365                            settings.OptimizePath);
366
367                        if (childPath != null)
368                        {
369                            if (isFillFound)
370                            {
371                                string elementFill = element.GetAttribute("fill");
372                                if (!String.IsNullOrEmpty(elementFill) &&
373                                    !String.Equals(elementFill, aggregatedFill, StringComparison.OrdinalIgnoreCase))
374                                {
375                                    return;
376                                }
377                            }
378                            else
379                            {
380                                aggregatedFill = element.GetAttribute("fill");
381                                isFillFound = !String.IsNullOrEmpty(aggregatedFill);
382                                if (isFillFound)
383                                {
384                                    paintElement = element;
385                                }
386                            }
387
388                            geomColl.Add(childPath);
389                        }
390                    }
391                }
392            }
393
394            if (geomColl.Count == 0 || paintElement == null)
395            {
396                return;
397            }
398
399            _aggregatedFill = paintElement;
400            _aggregatedGeom = geomColl;
401
402            _isAggregated = true;
403        }
404
405        #endregion
406    }
407}
Note: See TracBrowser for help on using the repository browser.