~halega/+junk/sharpdevelop

« back to all changes in this revision

Viewing changes to src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/DesignPanel.cs

  • Committer: sk
  • Date: 2011-09-10 05:17:57 UTC
  • Revision ID: halega@halega.com-20110910051757-qfouz1llya9m6boy
4.1.0.7915 Release Candidate 1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
 
2
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
 
3
 
 
4
using System;
 
5
using System.Collections.Generic;
 
6
using System.ComponentModel;
 
7
using System.Diagnostics;
 
8
using System.Windows;
 
9
using System.Windows.Controls;
 
10
using System.Windows.Input;
 
11
using System.Windows.Media;
 
12
using System.Windows.Threading;
 
13
 
 
14
using ICSharpCode.WpfDesign.Adorners;
 
15
using ICSharpCode.WpfDesign.Designer.Controls;
 
16
 
 
17
namespace ICSharpCode.WpfDesign.Designer
 
18
{
 
19
        sealed class DesignPanel : Decorator, IDesignPanel
 
20
        {
 
21
                #region Hit Testing
 
22
                /// <summary>
 
23
                /// this element is always hit (unless HitTestVisible is set to false)
 
24
                /// </summary>
 
25
                sealed class EatAllHitTestRequests : UIElement
 
26
                {
 
27
                        protected override GeometryHitTestResult HitTestCore(GeometryHitTestParameters hitTestParameters)
 
28
                        {
 
29
                                return new GeometryHitTestResult(this, IntersectionDetail.FullyContains);
 
30
                        }
 
31
                        
 
32
                        protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters)
 
33
                        {
 
34
                                return new PointHitTestResult(this, hitTestParameters.HitPoint);
 
35
                        }
 
36
                }
 
37
                
 
38
                static void RunHitTest(Visual reference, Point point, HitTestFilterCallback filterCallback, HitTestResultCallback resultCallback)
 
39
                {
 
40
                        VisualTreeHelper.HitTest(reference, filterCallback, resultCallback,
 
41
                                                 new PointHitTestParameters(point));
 
42
                }
 
43
                
 
44
                static HitTestFilterBehavior FilterHitTestInvisibleElements(DependencyObject potentialHitTestTarget)
 
45
                {
 
46
                        UIElement element = potentialHitTestTarget as UIElement;
 
47
                        if (element != null) {
 
48
                                if (!(element.IsHitTestVisible && element.Visibility == Visibility.Visible)) {
 
49
                                        return HitTestFilterBehavior.ContinueSkipSelfAndChildren;
 
50
                                }
 
51
                        }
 
52
                        return HitTestFilterBehavior.Continue;
 
53
                }
 
54
                
 
55
                /// <summary>
 
56
                /// Performs a custom hit testing lookup for the specified mouse event args.
 
57
                /// </summary>
 
58
                public DesignPanelHitTestResult HitTest(Point mousePosition, bool testAdorners, bool testDesignSurface)
 
59
                {
 
60
                        DesignPanelHitTestResult result = DesignPanelHitTestResult.NoHit;
 
61
                        HitTest(mousePosition, testAdorners, testDesignSurface,
 
62
                                delegate(DesignPanelHitTestResult r) {
 
63
                                        result = r;
 
64
                                        return false;
 
65
                                });
 
66
                        return result;
 
67
                }
 
68
                
 
69
                /// <summary>
 
70
                /// Performs a hit test on the design surface, raising <paramref name="callback"/> for each match.
 
71
                /// Hit testing continues while the callback returns true.
 
72
                /// </summary>
 
73
                public void HitTest(Point mousePosition, bool testAdorners, bool testDesignSurface, Predicate<DesignPanelHitTestResult> callback)
 
74
                {
 
75
                        if (mousePosition.X < 0 || mousePosition.Y < 0 || mousePosition.X > this.RenderSize.Width || mousePosition.Y > this.RenderSize.Height) {
 
76
                                return;
 
77
                        }
 
78
                        // First try hit-testing on the adorner layer.
 
79
                        
 
80
                        bool continueHitTest = true;
 
81
                        
 
82
                        if (testAdorners) {
 
83
                                RunHitTest(
 
84
                                        _adornerLayer, mousePosition, FilterHitTestInvisibleElements,
 
85
                                        delegate(HitTestResult result) {
 
86
                                                if (result != null && result.VisualHit != null && result.VisualHit is Visual) {
 
87
                                                        DesignPanelHitTestResult customResult = new DesignPanelHitTestResult((Visual)result.VisualHit);
 
88
                                                        DependencyObject obj = result.VisualHit;
 
89
                                                        while (obj != null && obj != _adornerLayer) {
 
90
                                                                AdornerPanel adorner = obj as AdornerPanel;
 
91
                                                                if (adorner != null) {
 
92
                                                                        customResult.AdornerHit = adorner;
 
93
                                                                }
 
94
                                                                obj = VisualTreeHelper.GetParent(obj);
 
95
                                                        }
 
96
                                                        continueHitTest = callback(customResult);
 
97
                                                        return continueHitTest ? HitTestResultBehavior.Continue : HitTestResultBehavior.Stop;
 
98
                                                } else {
 
99
                                                        return HitTestResultBehavior.Continue;
 
100
                                                }
 
101
                                        });
 
102
                        }
 
103
                        
 
104
                        if (continueHitTest && testDesignSurface) {
 
105
                                RunHitTest(
 
106
                                        this.Child, mousePosition, delegate { return HitTestFilterBehavior.Continue; },
 
107
                                        delegate(HitTestResult result) {
 
108
                                                if (result != null && result.VisualHit != null && result.VisualHit is Visual) {
 
109
                                                        DesignPanelHitTestResult customResult = new DesignPanelHitTestResult((Visual)result.VisualHit);
 
110
                                                        
 
111
                                                        ViewService viewService = _context.Services.View;
 
112
                                                        DependencyObject obj = result.VisualHit;
 
113
                                                        while (obj != null) {
 
114
                                                                if ((customResult.ModelHit = viewService.GetModel(obj)) != null)
 
115
                                                                        break;
 
116
                                                                obj = VisualTreeHelper.GetParent(obj);
 
117
                                                        }
 
118
                                                        if (customResult.ModelHit == null) {
 
119
                                                                customResult.ModelHit = _context.RootItem;
 
120
                                                        }
 
121
                                                        continueHitTest = callback(customResult);
 
122
                                                        return continueHitTest ? HitTestResultBehavior.Continue : HitTestResultBehavior.Stop;
 
123
                                                } else {
 
124
                                                        return HitTestResultBehavior.Continue;
 
125
                                                }
 
126
                                        }
 
127
                                );
 
128
                        }
 
129
                }
 
130
                #endregion
 
131
                
 
132
                #region Fields + Constructor
 
133
                DesignContext _context;
 
134
                readonly EatAllHitTestRequests _eatAllHitTestRequests;
 
135
                readonly AdornerLayer _adornerLayer;
 
136
                
 
137
                public DesignPanel()
 
138
                {
 
139
                        this.Focusable = true;
 
140
                        this.Margin = new Thickness(16);
 
141
                        DesignerProperties.SetIsInDesignMode(this, true);
 
142
                        
 
143
                        _eatAllHitTestRequests = new EatAllHitTestRequests();
 
144
                        _eatAllHitTestRequests.MouseDown += delegate {
 
145
                                // ensure the design panel has focus while the user is interacting with it
 
146
                                this.Focus();
 
147
                        };
 
148
                        _eatAllHitTestRequests.AllowDrop = true;
 
149
                        _adornerLayer = new AdornerLayer(this);
 
150
                }
 
151
                #endregion
 
152
                
 
153
                #region Properties
 
154
                
 
155
                /// <summary>
 
156
                /// Gets/Sets the design context.
 
157
                /// </summary>
 
158
                public DesignContext Context {
 
159
                        get { return _context; }
 
160
                        set { _context = value; }
 
161
                }
 
162
                
 
163
                public ICollection<AdornerPanel> Adorners {
 
164
                        get {
 
165
                                return _adornerLayer.Adorners;
 
166
                        }
 
167
                }
 
168
                
 
169
                /// <summary>
 
170
                /// Gets/Sets if the design content is visible for hit-testing purposes.
 
171
                /// </summary>
 
172
                public bool IsContentHitTestVisible {
 
173
                        get { return !_eatAllHitTestRequests.IsHitTestVisible; }
 
174
                        set { _eatAllHitTestRequests.IsHitTestVisible = !value; }
 
175
                }
 
176
                
 
177
                /// <summary>
 
178
                /// Gets/Sets if the adorner layer is visible for hit-testing purposes.
 
179
                /// </summary>
 
180
                public bool IsAdornerLayerHitTestVisible {
 
181
                        get { return _adornerLayer.IsHitTestVisible; }
 
182
                        set { _adornerLayer.IsHitTestVisible = value; }
 
183
                }
 
184
                
 
185
                #endregion
 
186
                
 
187
                #region Visual Child Management
 
188
                public override UIElement Child {
 
189
                        get { return base.Child; }
 
190
                        set {
 
191
                                if (base.Child == value)
 
192
                                        return;
 
193
                                if (value == null) {
 
194
                                        // Child is being set from some value to null
 
195
                                        
 
196
                                        // remove _adornerLayer and _eatAllHitTestRequests
 
197
                                        RemoveVisualChild(_adornerLayer);
 
198
                                        RemoveVisualChild(_eatAllHitTestRequests);
 
199
                                } else if (base.Child == null) {
 
200
                                        // Child is being set from null to some value
 
201
                                        AddVisualChild(_adornerLayer);
 
202
                                        AddVisualChild(_eatAllHitTestRequests);
 
203
                                }
 
204
                                base.Child = value;
 
205
                        }
 
206
                }
 
207
                
 
208
                protected override Visual GetVisualChild(int index)
 
209
                {
 
210
                        if (base.Child != null) {
 
211
                                if (index == 0)
 
212
                                        return base.Child;
 
213
                                else if (index == 1)
 
214
                                        return _eatAllHitTestRequests;
 
215
                                else if (index == 2)
 
216
                                        return _adornerLayer;
 
217
                        }
 
218
                        return base.GetVisualChild(index);
 
219
                }
 
220
                
 
221
                protected override int VisualChildrenCount {
 
222
                        get {
 
223
                                if (base.Child != null)
 
224
                                        return 3;
 
225
                                else
 
226
                                        return base.VisualChildrenCount;
 
227
                        }
 
228
                }
 
229
                
 
230
                protected override Size MeasureOverride(Size constraint)
 
231
                {
 
232
                        Size result = base.MeasureOverride(constraint);
 
233
                        if (this.Child != null) {
 
234
                                _adornerLayer.Measure(constraint);
 
235
                                _eatAllHitTestRequests.Measure(constraint);
 
236
                        }
 
237
                        return result;
 
238
                }
 
239
                
 
240
                protected override Size ArrangeOverride(Size arrangeSize)
 
241
                {
 
242
                        Size result = base.ArrangeOverride(arrangeSize);
 
243
                        if (this.Child != null) {
 
244
                                Rect r = new Rect(new Point(0, 0), arrangeSize);
 
245
                                _adornerLayer.Arrange(r);
 
246
                                _eatAllHitTestRequests.Arrange(r);
 
247
                        }
 
248
                        return result;
 
249
                }
 
250
                #endregion
 
251
                
 
252
                protected override void OnQueryCursor(QueryCursorEventArgs e)
 
253
                {
 
254
                        base.OnQueryCursor(e);
 
255
                        if (_context != null) {
 
256
                                Cursor cursor = _context.Services.Tool.CurrentTool.Cursor;
 
257
                                if (cursor != null) {
 
258
                                        e.Cursor = cursor;
 
259
                                        e.Handled = true;
 
260
                                }
 
261
                        }
 
262
                }
 
263
        }
 
264
}