diff 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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Chronosv2/source/Presentation/Windows/Controls/Desktop.cs	Tue Feb 21 17:25:44 2012 +0700
@@ -0,0 +1,330 @@
+/*
+The MIT License
+
+Copyright (c) 2009-2010. Carlos Guzmán Álvarez. http://chronoswpf.codeplex.com/
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+using System;
+using System.Diagnostics;
+using System.Linq;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Documents;
+using System.Windows.Input;
+using Chronos.Extensions.Windows;
+using Chronos.Presentation.Core.ViewModel;
+using Chronos.Presentation.ViewModel;
+
+namespace Chronos.Presentation.Windows.Controls
+{
+    /// <summary>
+    /// Virtual desktop representation using a <see cref="Canvas"/> control
+    /// </summary>
+    public class Desktop 
+        : Canvas
+    {
+        #region · Dependency Properties ·
+
+        /// <summary>
+        /// Identifies the Id dependency property.
+        /// </summary>
+        public static readonly DependencyProperty IdProperty =
+            DependencyProperty.Register("Id", typeof(Guid), typeof(Desktop),
+                new FrameworkPropertyMetadata(Guid.NewGuid()));
+
+        #endregion
+
+        #region · Routed Commands ·
+
+        public static RoutedCommand GroupCommand = new RoutedCommand();
+
+        #endregion
+
+        #region · Static Constructor ·
+
+        /// <summary>
+        /// Initializes the <see cref="Desktop"/> class.
+        /// </summary>
+        static Desktop()
+        {
+            Desktop.DefaultStyleKeyProperty.OverrideMetadata(typeof(Desktop),
+                new FrameworkPropertyMetadata(typeof(Desktop)));
+
+            KeyboardNavigation.ControlTabNavigationProperty.OverrideMetadata(
+                typeof(Desktop), new FrameworkPropertyMetadata(KeyboardNavigationMode.Cycle));
+        }
+
+        #endregion
+
+        #region · Fields ·
+
+        private Point?              rubberbandSelectionStartPoint;
+        private SelectionService    selectionService;
+
+        #endregion
+
+        #region · Properties ·
+
+        /// <summary>
+        /// Gets or sets the element id.
+        /// </summary>
+        /// <value>The id.</value>
+        public Guid Id
+        {
+            get { return (Guid)base.GetValue(IdProperty); }
+            set { base.SetValue(IdProperty, value); }
+        }
+
+        #endregion
+
+        #region · Internal Properties ·
+
+        internal SelectionService SelectionService
+        {
+            get
+            {
+                if (this.selectionService == null)
+                {
+                    this.selectionService = new SelectionService(this);
+                }
+
+                return this.selectionService;
+            }
+        }
+
+        #endregion
+
+        #region · Constructor ·
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="Desktop"/> class.
+        /// </summary>
+        public Desktop()
+            : base()
+        {
+            this.CommandBindings.Add(new CommandBinding(Desktop.GroupCommand, GroupExecuted, CanGroup));
+        }
+
+        #endregion
+
+        #region · Methods ·
+
+        /// <summary>
+        /// Adds the new desktop element.
+        /// </summary>
+        /// <param name="instance">The new desktop element.</param>
+        /// <param name="position">The position.</param>
+        public void AddElement(DesktopElement element)
+        {
+            element.Parent = this;
+
+            this.Children.Add(element);
+            
+            this.DeactivateAll();
+            element.Activate();
+        }
+
+        /// <summary>
+        /// Adds the new desktop element.
+        /// </summary>
+        /// <param name="instance">The new desktop element.</param>
+        /// <param name="position">The position.</param>
+        public void AddElement(DesktopElement element, Point position)
+        {
+            element.Parent = this;
+
+            this.Children.Add(element);
+
+            element.Move(Math.Max(0, position.X), Math.Max(0, position.Y));
+            element.SetZIndex(0);
+
+            this.DeactivateAll();
+            element.Activate();
+        }
+
+        /// <summary>
+        /// Removes the given element from the desktop.
+        /// </summary>
+        /// <param name="element">The element.</param>
+        public void RemoveElement(DesktopElement instance)
+        {
+            Debug.Assert(instance is UIElement, "instance");
+
+            this.Children.Remove(instance as UIElement);
+        }
+
+        public void Activate()
+        {
+            // Deactivate all Desktop elements
+            this.DeactivateAll();
+
+            this.SetFocus();
+        }
+
+        #endregion
+
+        #region  · Mouse Handling Methods ·
+
+        /// <summary>
+        /// Invoked when an unhandled <see cref="E:System.Windows.Input.Mouse.MouseDown"/> attached event 
+        /// reaches an element in its route that is derived from this class. 
+        /// Implement this method to add class handling for this event.
+        /// </summary>
+        /// <param name="e">The <see cref="T:System.Windows.Input.MouseButtonEventArgs"/> 
+        /// that contains the event data. This event data reports details about the mouse button that was pressed and the handled state.
+        /// </param>
+        protected override void OnMouseDown(MouseButtonEventArgs e)
+        {            
+            if (Object.ReferenceEquals(e.Source,  this))
+            {
+                this.Activate();
+
+                // in case that this click is the start of a 
+                // drag operation we cache the start point
+                this.rubberbandSelectionStartPoint = new Point?(e.GetPosition(this));
+
+                // if you click directly on the canvas all 
+                // selected items are 'de-selected'
+                SelectionService.ClearSelection();
+
+                e.Handled = true;
+            }
+
+            base.OnMouseDown(e);
+        }
+
+        /// <summary>
+        /// Invoked when an unhandled <see cref="E:System.Windows.Input.Mouse.MouseMove"/> attached event 
+        /// reaches an element in its route that is derived from this class. 
+        /// Implement this method to add class handling for this event.
+        /// </summary>
+        /// <param name="e">The <see cref="T:System.Windows.Input.MouseEventArgs"/> that contains the event data.</param>
+        protected override void OnMouseMove(MouseEventArgs e)
+        {
+            base.OnMouseMove(e);
+
+            // if mouse button is not pressed we have no drag operation, ...
+            if (e.LeftButton != MouseButtonState.Pressed)
+            {
+                this.rubberbandSelectionStartPoint = null;
+            }
+            else if (this.rubberbandSelectionStartPoint.HasValue)   // ... but if mouse button is pressed and start
+                                                                    // point value is set we do have one
+            {
+                // create rubberband adorner
+                AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(this);
+
+                if (adornerLayer != null)
+                {
+                    RubberbandAdorner adorner = new RubberbandAdorner(this, rubberbandSelectionStartPoint);
+
+                    if (adorner != null)
+                    {
+                        adornerLayer.Add(adorner);
+                    }
+                }
+
+                e.Handled = true;
+            }
+        }
+
+        #endregion
+
+        #region · Internal Methods ·
+
+        /// <summary>
+        /// Called when a <see cref="DesktopElement"/> gets activated.
+        /// </summary>
+        /// <param name="id">The id.</param>
+        internal void OnActivatedElement(Guid id)
+        {
+            this.InvokeAsynchronouslyInBackground
+            (
+                () =>
+                {
+                    this.Children.OfType<DesktopElement>()
+                        .Where(e => e.Id != id)
+                        .ToList()
+                        .ForEach(element => element.Deactivate());
+                }
+            );
+        }
+
+        #endregion
+
+        #region · Private Methods ·
+
+        private void GroupExecuted(object sender, ExecutedRoutedEventArgs e)
+        {
+            var items = from item in this.SelectionService.CurrentSelection.OfType<DesktopElement>()
+                        select item;
+
+            ShortcutGroupElement    group       = new ShortcutGroupElement();
+            ShortcutGroupViewModel  vm          = new ShortcutGroupViewModel();
+            Point                   position    = items.First().GetPosition();
+
+            foreach (DesktopElement item in items)
+            {
+                vm.Shortcuts.Add(item.DataContext as IShortcutViewModel);
+
+                this.RemoveElement(item);
+            }
+
+            group.DataContext = vm;
+
+            this.SelectionService.ClearSelection();
+
+            this.InvokeAsynchronouslyInBackground
+            (
+                () =>
+                {
+                    this.AddElement(group, position);
+                }
+            );
+        }
+
+        private void CanGroup(object sender, CanExecuteRoutedEventArgs e)
+        {
+            int count = (from item in this.SelectionService.CurrentSelection.OfType<ISelectable>()
+                         select item).Count();
+            
+            e.CanExecute = (count > 1);
+        }
+
+        private void DeactivateAll()
+        {
+            this.InvokeAsynchronouslyInBackground
+            (
+                () =>
+                {
+                    this.SelectionService.ClearSelection();
+
+                    this.Children
+                        .OfType<DesktopElement>()
+                        .ToList()
+                        .ForEach(element => element.Deactivate());
+                }
+            );
+        }
+
+        #endregion
+    }
+}