comparison Chronosv2/source/Presentation/Windows/Controls/Desktop.cs @ 10:443821e55f06

Initial cleaned up add from Codeplex files
author stevenh7776 stevenhollidge@hotmail.com
date Tue, 21 Feb 2012 17:25:44 +0700
parents
children
comparison
equal deleted inserted replaced
9:904a9faadf8b 10:443821e55f06
1 /*
2 The MIT License
3
4 Copyright (c) 2009-2010. Carlos Guzmán Álvarez. http://chronoswpf.codeplex.com/
5
6 Permission is hereby granted, free of charge, to any person obtaining a copy
7 of this software and associated documentation files (the "Software"), to deal
8 in the Software without restriction, including without limitation the rights
9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 copies of the Software, and to permit persons to whom the Software is
11 furnished to do so, subject to the following conditions:
12
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 THE SOFTWARE.
23 */
24
25 using System;
26 using System.Diagnostics;
27 using System.Linq;
28 using System.Windows;
29 using System.Windows.Controls;
30 using System.Windows.Documents;
31 using System.Windows.Input;
32 using Chronos.Extensions.Windows;
33 using Chronos.Presentation.Core.ViewModel;
34 using Chronos.Presentation.ViewModel;
35
36 namespace Chronos.Presentation.Windows.Controls
37 {
38 /// <summary>
39 /// Virtual desktop representation using a <see cref="Canvas"/> control
40 /// </summary>
41 public class Desktop
42 : Canvas
43 {
44 #region · Dependency Properties ·
45
46 /// <summary>
47 /// Identifies the Id dependency property.
48 /// </summary>
49 public static readonly DependencyProperty IdProperty =
50 DependencyProperty.Register("Id", typeof(Guid), typeof(Desktop),
51 new FrameworkPropertyMetadata(Guid.NewGuid()));
52
53 #endregion
54
55 #region · Routed Commands ·
56
57 public static RoutedCommand GroupCommand = new RoutedCommand();
58
59 #endregion
60
61 #region · Static Constructor ·
62
63 /// <summary>
64 /// Initializes the <see cref="Desktop"/> class.
65 /// </summary>
66 static Desktop()
67 {
68 Desktop.DefaultStyleKeyProperty.OverrideMetadata(typeof(Desktop),
69 new FrameworkPropertyMetadata(typeof(Desktop)));
70
71 KeyboardNavigation.ControlTabNavigationProperty.OverrideMetadata(
72 typeof(Desktop), new FrameworkPropertyMetadata(KeyboardNavigationMode.Cycle));
73 }
74
75 #endregion
76
77 #region · Fields ·
78
79 private Point? rubberbandSelectionStartPoint;
80 private SelectionService selectionService;
81
82 #endregion
83
84 #region · Properties ·
85
86 /// <summary>
87 /// Gets or sets the element id.
88 /// </summary>
89 /// <value>The id.</value>
90 public Guid Id
91 {
92 get { return (Guid)base.GetValue(IdProperty); }
93 set { base.SetValue(IdProperty, value); }
94 }
95
96 #endregion
97
98 #region · Internal Properties ·
99
100 internal SelectionService SelectionService
101 {
102 get
103 {
104 if (this.selectionService == null)
105 {
106 this.selectionService = new SelectionService(this);
107 }
108
109 return this.selectionService;
110 }
111 }
112
113 #endregion
114
115 #region · Constructor ·
116
117 /// <summary>
118 /// Initializes a new instance of the <see cref="Desktop"/> class.
119 /// </summary>
120 public Desktop()
121 : base()
122 {
123 this.CommandBindings.Add(new CommandBinding(Desktop.GroupCommand, GroupExecuted, CanGroup));
124 }
125
126 #endregion
127
128 #region · Methods ·
129
130 /// <summary>
131 /// Adds the new desktop element.
132 /// </summary>
133 /// <param name="instance">The new desktop element.</param>
134 /// <param name="position">The position.</param>
135 public void AddElement(DesktopElement element)
136 {
137 element.Parent = this;
138
139 this.Children.Add(element);
140
141 this.DeactivateAll();
142 element.Activate();
143 }
144
145 /// <summary>
146 /// Adds the new desktop element.
147 /// </summary>
148 /// <param name="instance">The new desktop element.</param>
149 /// <param name="position">The position.</param>
150 public void AddElement(DesktopElement element, Point position)
151 {
152 element.Parent = this;
153
154 this.Children.Add(element);
155
156 element.Move(Math.Max(0, position.X), Math.Max(0, position.Y));
157 element.SetZIndex(0);
158
159 this.DeactivateAll();
160 element.Activate();
161 }
162
163 /// <summary>
164 /// Removes the given element from the desktop.
165 /// </summary>
166 /// <param name="element">The element.</param>
167 public void RemoveElement(DesktopElement instance)
168 {
169 Debug.Assert(instance is UIElement, "instance");
170
171 this.Children.Remove(instance as UIElement);
172 }
173
174 public void Activate()
175 {
176 // Deactivate all Desktop elements
177 this.DeactivateAll();
178
179 this.SetFocus();
180 }
181
182 #endregion
183
184 #region · Mouse Handling Methods ·
185
186 /// <summary>
187 /// Invoked when an unhandled <see cref="E:System.Windows.Input.Mouse.MouseDown"/> attached event
188 /// reaches an element in its route that is derived from this class.
189 /// Implement this method to add class handling for this event.
190 /// </summary>
191 /// <param name="e">The <see cref="T:System.Windows.Input.MouseButtonEventArgs"/>
192 /// that contains the event data. This event data reports details about the mouse button that was pressed and the handled state.
193 /// </param>
194 protected override void OnMouseDown(MouseButtonEventArgs e)
195 {
196 if (Object.ReferenceEquals(e.Source, this))
197 {
198 this.Activate();
199
200 // in case that this click is the start of a
201 // drag operation we cache the start point
202 this.rubberbandSelectionStartPoint = new Point?(e.GetPosition(this));
203
204 // if you click directly on the canvas all
205 // selected items are 'de-selected'
206 SelectionService.ClearSelection();
207
208 e.Handled = true;
209 }
210
211 base.OnMouseDown(e);
212 }
213
214 /// <summary>
215 /// Invoked when an unhandled <see cref="E:System.Windows.Input.Mouse.MouseMove"/> attached event
216 /// reaches an element in its route that is derived from this class.
217 /// Implement this method to add class handling for this event.
218 /// </summary>
219 /// <param name="e">The <see cref="T:System.Windows.Input.MouseEventArgs"/> that contains the event data.</param>
220 protected override void OnMouseMove(MouseEventArgs e)
221 {
222 base.OnMouseMove(e);
223
224 // if mouse button is not pressed we have no drag operation, ...
225 if (e.LeftButton != MouseButtonState.Pressed)
226 {
227 this.rubberbandSelectionStartPoint = null;
228 }
229 else if (this.rubberbandSelectionStartPoint.HasValue) // ... but if mouse button is pressed and start
230 // point value is set we do have one
231 {
232 // create rubberband adorner
233 AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(this);
234
235 if (adornerLayer != null)
236 {
237 RubberbandAdorner adorner = new RubberbandAdorner(this, rubberbandSelectionStartPoint);
238
239 if (adorner != null)
240 {
241 adornerLayer.Add(adorner);
242 }
243 }
244
245 e.Handled = true;
246 }
247 }
248
249 #endregion
250
251 #region · Internal Methods ·
252
253 /// <summary>
254 /// Called when a <see cref="DesktopElement"/> gets activated.
255 /// </summary>
256 /// <param name="id">The id.</param>
257 internal void OnActivatedElement(Guid id)
258 {
259 this.InvokeAsynchronouslyInBackground
260 (
261 () =>
262 {
263 this.Children.OfType<DesktopElement>()
264 .Where(e => e.Id != id)
265 .ToList()
266 .ForEach(element => element.Deactivate());
267 }
268 );
269 }
270
271 #endregion
272
273 #region · Private Methods ·
274
275 private void GroupExecuted(object sender, ExecutedRoutedEventArgs e)
276 {
277 var items = from item in this.SelectionService.CurrentSelection.OfType<DesktopElement>()
278 select item;
279
280 ShortcutGroupElement group = new ShortcutGroupElement();
281 ShortcutGroupViewModel vm = new ShortcutGroupViewModel();
282 Point position = items.First().GetPosition();
283
284 foreach (DesktopElement item in items)
285 {
286 vm.Shortcuts.Add(item.DataContext as IShortcutViewModel);
287
288 this.RemoveElement(item);
289 }
290
291 group.DataContext = vm;
292
293 this.SelectionService.ClearSelection();
294
295 this.InvokeAsynchronouslyInBackground
296 (
297 () =>
298 {
299 this.AddElement(group, position);
300 }
301 );
302 }
303
304 private void CanGroup(object sender, CanExecuteRoutedEventArgs e)
305 {
306 int count = (from item in this.SelectionService.CurrentSelection.OfType<ISelectable>()
307 select item).Count();
308
309 e.CanExecute = (count > 1);
310 }
311
312 private void DeactivateAll()
313 {
314 this.InvokeAsynchronouslyInBackground
315 (
316 () =>
317 {
318 this.SelectionService.ClearSelection();
319
320 this.Children
321 .OfType<DesktopElement>()
322 .ToList()
323 .ForEach(element => element.Deactivate());
324 }
325 );
326 }
327
328 #endregion
329 }
330 }