/************************************************************************************* Extended WPF Toolkit Copyright (C) 2007-2013 Xceed Software Inc. This program is provided to you under the terms of the Microsoft Public License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license For more features, controls, and fast professional support, pick up the Plus Edition at http://xceed.com/wpf_toolkit Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids ***********************************************************************************/ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Controls; using System.Windows; using System.Windows.Media; using System.Windows.Controls.Primitives; using System.Windows.Input; using System.IO; using Tango.ColorPicker.Core; using System.ComponentModel; namespace Tango.ColorPicker.Primitives { [TemplatePart(Name = PART_HeaderThumb, Type = typeof(Thumb))] [TemplatePart(Name = PART_Icon, Type = typeof(Image))] [TemplatePart(Name = PART_CloseButton, Type = typeof(Button))] [TemplatePart(Name = PART_ToolWindowCloseButton, Type = typeof(Button))] [TemplatePart(Name = PART_BlockMouseInputsBorder, Type = typeof(Border))] [TemplatePart(Name = PART_HeaderGrid, Type = typeof(Grid))] internal class WindowControl : ContentControl { public static readonly ComponentResourceKey DefaultCloseButtonStyleKey = new ComponentResourceKey(typeof(WindowControl), "DefaultCloseButtonStyle"); private const string PART_HeaderThumb = "PART_HeaderThumb"; private const string PART_Icon = "PART_Icon"; private const string PART_CloseButton = "PART_CloseButton"; private const string PART_ToolWindowCloseButton = "PART_ToolWindowCloseButton"; private const string PART_BlockMouseInputsBorder = "PART_BlockMouseInputsBorder"; private const string PART_HeaderGrid = "PART_HeaderGrid"; #region Members private Thumb _headerThumb; private Image _icon; private Button _closeButton; private Button _windowToolboxCloseButton; private bool _setIsActiveInternal; internal Border _windowBlockMouseInputsPanel; #endregion #region Constructors static WindowControl() { DefaultStyleKeyProperty.OverrideMetadata(typeof(WindowControl), new FrameworkPropertyMetadata(typeof(WindowControl))); } public WindowControl() { } #endregion //Constructors #region Dependency Properties #region Public DP #region Caption public static readonly DependencyProperty CaptionProperty = DependencyProperty.Register("Caption", typeof(string), typeof(WindowControl), new UIPropertyMetadata(String.Empty)); public string Caption { get { return (string)GetValue(CaptionProperty); } set { SetValue(CaptionProperty, value); } } #endregion //Caption #region CaptionFontSize public static readonly DependencyProperty CaptionFontSizeProperty = DependencyProperty.Register("CaptionFontSize", typeof(double), typeof(WindowControl), new UIPropertyMetadata(15d)); public double CaptionFontSize { get { return (double)GetValue(CaptionFontSizeProperty); } set { SetValue(CaptionFontSizeProperty, value); } } #endregion //CaptionFontSize #region CaptionForeground public static readonly DependencyProperty CaptionForegroundProperty = DependencyProperty.Register("CaptionForeground", typeof(Brush), typeof(WindowControl), new UIPropertyMetadata(null)); public Brush CaptionForeground { get { return (Brush)GetValue(CaptionForegroundProperty); } set { SetValue(CaptionForegroundProperty, value); } } #endregion //CaptionForeground #region CaptionShadowBrush public static readonly DependencyProperty CaptionShadowBrushProperty = DependencyProperty.Register("CaptionShadowBrush", typeof(Brush), typeof(WindowControl), new UIPropertyMetadata(new SolidColorBrush(Color.FromArgb(179, 255, 255, 255)))); public Brush CaptionShadowBrush { get { return (Brush)GetValue(CaptionShadowBrushProperty); } set { SetValue(CaptionShadowBrushProperty, value); } } #endregion //CaptionShadowBrush #region CaptionIcon public static readonly DependencyProperty CaptionIconProperty = DependencyProperty.Register("CaptionIcon", typeof(ImageSource), typeof(WindowControl), new UIPropertyMetadata(null)); public ImageSource CaptionIcon { get { return (ImageSource)GetValue(CaptionIconProperty); } set { SetValue(CaptionIconProperty, value); } } #endregion //CaptionIcon #region CloseButtonStyle public static readonly DependencyProperty CloseButtonStyleProperty = DependencyProperty.Register("CloseButtonStyle", typeof(Style), typeof(WindowControl), new UIPropertyMetadata(null)); public Style CloseButtonStyle { get { return (Style)GetValue(CloseButtonStyleProperty); } set { SetValue(CloseButtonStyleProperty, value); } } #endregion //CloseButtonStyle #region CloseButtonVisibility public static readonly DependencyProperty CloseButtonVisibilityProperty = DependencyProperty.Register("CloseButtonVisibility", typeof(Visibility), typeof(WindowControl), new PropertyMetadata(Visibility.Visible, null, OnCoerceCloseButtonVisibility)); public Visibility CloseButtonVisibility { get { return (Visibility)GetValue(CloseButtonVisibilityProperty); } set { SetValue(CloseButtonVisibilityProperty, value); } } private static object OnCoerceCloseButtonVisibility(DependencyObject d, object basevalue) { if (basevalue == DependencyProperty.UnsetValue) return basevalue; WindowControl windowControl = d as WindowControl; if (windowControl == null) return basevalue; return windowControl.OnCoerceCloseButtonVisibility((Visibility)basevalue); } protected virtual object OnCoerceCloseButtonVisibility(Visibility newValue) { return newValue; } #endregion //CloseButtonVisibility #region IsActive public static readonly DependencyProperty IsActiveProperty = DependencyProperty.Register("IsActive", typeof(bool), typeof(WindowControl), new UIPropertyMetadata(true, null, OnCoerceIsActive)); public bool IsActive { get { return (bool)GetValue(IsActiveProperty); } set { SetValue(IsActiveProperty, value); } } private static object OnCoerceIsActive(DependencyObject d, object basevalue) { WindowControl w = d as WindowControl; if (w != null && !w._setIsActiveInternal && !w.AllowPublicIsActiveChange) throw new InvalidOperationException("Cannot set IsActive directly. This is handled by the underlying system"); return basevalue; } internal void SetIsActiveInternal(bool isActive) { _setIsActiveInternal = true; this.IsActive = isActive; _setIsActiveInternal = false; } #endregion //IsActive #region Left public static readonly DependencyProperty LeftProperty = DependencyProperty.Register("Left", typeof(double), typeof(WindowControl), new PropertyMetadata(0.0, new PropertyChangedCallback(OnLeftPropertyChanged), OnCoerceLeft)); public double Left { get { return (double)GetValue(LeftProperty); } set { SetValue(LeftProperty, value); } } private static object OnCoerceLeft(DependencyObject d, object basevalue) { if (basevalue == DependencyProperty.UnsetValue) return basevalue; var windowControl = (WindowControl)d; if (windowControl == null) return basevalue; return windowControl.OnCoerceLeft(basevalue); } private object OnCoerceLeft(object newValue) { var value = (double)newValue; if (object.Equals(value, double.NaN)) return 0.0; return newValue; } private static void OnLeftPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) { WindowControl windowControl = obj as WindowControl; if (windowControl != null) windowControl.OnLeftPropertyChanged((double)e.OldValue, (double)e.NewValue); } internal event EventHandler LeftChanged; protected virtual void OnLeftPropertyChanged(double oldValue, double newValue) { EventHandler handler = LeftChanged; if (handler != null) { handler(this, EventArgs.Empty); } } #endregion //Left #region Top public static readonly DependencyProperty TopProperty = DependencyProperty.Register("Top", typeof(double), typeof(WindowControl), new PropertyMetadata(0.0, new PropertyChangedCallback(OnTopPropertyChanged), OnCoerceTop)); public double Top { get { return (double)GetValue(TopProperty); } set { SetValue(TopProperty, value); } } private static object OnCoerceTop(DependencyObject d, object basevalue) { if (basevalue == DependencyProperty.UnsetValue) return basevalue; var windowControl = (WindowControl)d; if (windowControl == null) return basevalue; return windowControl.OnCoerceTop(basevalue); } private object OnCoerceTop(object newValue) { var value = (double)newValue; if (object.Equals(value, double.NaN)) return 0.0; return newValue; } private static void OnTopPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) { WindowControl windowControl = obj as WindowControl; if (windowControl != null) windowControl.OnTopPropertyChanged((double)e.OldValue, (double)e.NewValue); } internal event EventHandler TopChanged; protected virtual void OnTopPropertyChanged(double oldValue, double newValue) { EventHandler handler = TopChanged; if (handler != null) { handler(this, EventArgs.Empty); } } #endregion //TopProperty #region WindowBackground public static readonly DependencyProperty WindowBackgroundProperty = DependencyProperty.Register("WindowBackground", typeof(Brush), typeof(WindowControl), new PropertyMetadata(null)); public Brush WindowBackground { get { return (Brush)GetValue(WindowBackgroundProperty); } set { SetValue(WindowBackgroundProperty, value); } } #endregion // WindowBackground #region WindowBorderBrush public static readonly DependencyProperty WindowBorderBrushProperty = DependencyProperty.Register("WindowBorderBrush", typeof(Brush), typeof(WindowControl), new PropertyMetadata(null)); public Brush WindowBorderBrush { get { return (Brush)GetValue(WindowBorderBrushProperty); } set { SetValue(WindowBorderBrushProperty, value); } } #endregion //WindowBorderBrush #region WindowBorderThickness public static readonly DependencyProperty WindowBorderThicknessProperty = DependencyProperty.Register("WindowBorderThickness", typeof(Thickness), typeof(WindowControl), new PropertyMetadata(new Thickness(0))); public Thickness WindowBorderThickness { get { return (Thickness)GetValue(WindowBorderThicknessProperty); } set { SetValue(WindowBorderThicknessProperty, value); } } #endregion //WindowBorderThickness #region WindowInactiveBackground public static readonly DependencyProperty WindowInactiveBackgroundProperty = DependencyProperty.Register("WindowInactiveBackground", typeof(Brush), typeof(WindowControl), new PropertyMetadata(null)); public Brush WindowInactiveBackground { get { return (Brush)GetValue(WindowInactiveBackgroundProperty); } set { SetValue(WindowInactiveBackgroundProperty, value); } } #endregion // WindowInactiveBackground #region WindowOpacity public static readonly DependencyProperty WindowOpacityProperty = DependencyProperty.Register("WindowOpacity", typeof(double), typeof(WindowControl), new PropertyMetadata(1d)); public double WindowOpacity { get { return (double)GetValue(WindowOpacityProperty); } set { SetValue(WindowOpacityProperty, value); } } #endregion //WindowOpacity #region WindowStyle public static readonly DependencyProperty WindowStyleProperty = DependencyProperty.Register("WindowStyle", typeof(WindowStyle), typeof(WindowControl), new PropertyMetadata(WindowStyle.SingleBorderWindow, null, OnCoerceWindowStyle)); public WindowStyle WindowStyle { get { return (WindowStyle)GetValue(WindowStyleProperty); } set { SetValue(WindowStyleProperty, value); } } private static object OnCoerceWindowStyle(DependencyObject d, object basevalue) { if (basevalue == DependencyProperty.UnsetValue) return basevalue; WindowControl windowControl = d as WindowControl; if (windowControl == null) return basevalue; return windowControl.OnCoerceWindowStyle((WindowStyle)basevalue); } protected virtual object OnCoerceWindowStyle(WindowStyle newValue) { return newValue; } private static void OnWindowStyleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { WindowControl window = (WindowControl)d; if (window != null) window.OnWindowStyleChanged((WindowStyle)e.OldValue, (WindowStyle)e.NewValue); } protected virtual void OnWindowStyleChanged(WindowStyle oldValue, WindowStyle newValue) { } #endregion //WindowStyle #region WindowThickness public static readonly DependencyProperty WindowThicknessProperty = DependencyProperty.Register("WindowThickness", typeof(Thickness), typeof(WindowControl), new PropertyMetadata(new Thickness(SystemParameters.ResizeFrameVerticalBorderWidth - 3, SystemParameters.ResizeFrameHorizontalBorderHeight - 3, SystemParameters.ResizeFrameVerticalBorderWidth - 3, SystemParameters.ResizeFrameHorizontalBorderHeight - 3))); public Thickness WindowThickness { get { return (Thickness)GetValue(WindowThicknessProperty); } set { SetValue(WindowThicknessProperty, value); } } #endregion //WindowThickness #endregion //Public DP #endregion //Dependency Properties #region Internal Properties internal bool IsStartupPositionInitialized { get; set; } #region IsBlockMouseInputsPanelActive (Internal) internal bool IsBlockMouseInputsPanelActive { get { return _IsBlockMouseInputsPanelActive; } set { if (value != _IsBlockMouseInputsPanelActive) { _IsBlockMouseInputsPanelActive = value; this.UpdateBlockMouseInputsPanel(); } } } private bool _IsBlockMouseInputsPanelActive; #endregion internal virtual bool AllowPublicIsActiveChange { get { return true; } } #endregion //Internal Properties #region Base Class Overrides public override void OnApplyTemplate() { base.OnApplyTemplate(); if (_headerThumb != null) { _headerThumb.PreviewMouseLeftButtonDown -= new MouseButtonEventHandler(this.HeaderPreviewMouseLeftButtonDown); _headerThumb.PreviewMouseRightButtonDown -= new MouseButtonEventHandler(this.HeaderPreviewMouseRightButtonDown); _headerThumb.DragDelta -= new DragDeltaEventHandler(this.HeaderThumbDragDelta); } _headerThumb = this.Template.FindName(PART_HeaderThumb, this) as Thumb; if (_headerThumb != null) { _headerThumb.PreviewMouseLeftButtonDown += new MouseButtonEventHandler(this.HeaderPreviewMouseLeftButtonDown); _headerThumb.PreviewMouseRightButtonDown += new MouseButtonEventHandler(this.HeaderPreviewMouseRightButtonDown); _headerThumb.DragDelta += new DragDeltaEventHandler(this.HeaderThumbDragDelta); } if (_icon != null) { _icon.MouseLeftButtonDown -= new MouseButtonEventHandler(this.IconMouseLeftButtonDown); } _icon = this.Template.FindName(PART_Icon, this) as Image; if (_icon != null) { _icon.MouseLeftButtonDown += new MouseButtonEventHandler(this.IconMouseLeftButtonDown); } if (_closeButton != null) { _closeButton.Click -= new RoutedEventHandler(this.Close); } _closeButton = this.Template.FindName(PART_CloseButton, this) as Button; if (_closeButton != null) { _closeButton.Click += new RoutedEventHandler(this.Close); } if (_windowToolboxCloseButton != null) { _windowToolboxCloseButton.Click -= new RoutedEventHandler(this.Close); } _windowToolboxCloseButton = this.Template.FindName(PART_ToolWindowCloseButton, this) as Button; if (_windowToolboxCloseButton != null) { _windowToolboxCloseButton.Click += new RoutedEventHandler(this.Close); } _windowBlockMouseInputsPanel = this.Template.FindName(PART_BlockMouseInputsBorder, this) as Border; this.UpdateBlockMouseInputsPanel(); } #endregion //Base Class Overrides #region Events #region HeaderMouseLeftButtonClickedEvent public static readonly RoutedEvent HeaderMouseLeftButtonClickedEvent = EventManager.RegisterRoutedEvent("HeaderMouseLeftButtonClicked", RoutingStrategy.Bubble, typeof(MouseButtonEventHandler), typeof(WindowControl)); public event MouseButtonEventHandler HeaderMouseLeftButtonClicked { add { AddHandler(HeaderMouseLeftButtonClickedEvent, value); } remove { RemoveHandler(HeaderMouseLeftButtonClickedEvent, value); } } #endregion //HeaderMouseLeftButtonClickedEvent #region HeaderMouseRightButtonClickedEvent public static readonly RoutedEvent HeaderMouseRightButtonClickedEvent = EventManager.RegisterRoutedEvent("HeaderMouseRightButtonClicked", RoutingStrategy.Bubble, typeof(MouseButtonEventHandler), typeof(WindowControl)); public event MouseButtonEventHandler HeaderMouseRightButtonClicked { add { AddHandler(HeaderMouseRightButtonClickedEvent, value); } remove { RemoveHandler(HeaderMouseRightButtonClickedEvent, value); } } #endregion //HeaderMouseRightButtonClickedEvent #region HeaderMouseLeftButtonDoubleClickedEvent public static readonly RoutedEvent HeaderMouseLeftButtonDoubleClickedEvent = EventManager.RegisterRoutedEvent("HeaderMouseLeftButtonDoubleClicked", RoutingStrategy.Bubble, typeof(MouseButtonEventHandler), typeof(WindowControl)); public event MouseButtonEventHandler HeaderMouseLeftButtonDoubleClicked { add { AddHandler(HeaderMouseLeftButtonDoubleClickedEvent, value); } remove { RemoveHandler(HeaderMouseLeftButtonDoubleClickedEvent, value); } } #endregion //HeaderMouseLeftButtonDoubleClickedEvent #region HeaderDragDeltaEvent public static readonly RoutedEvent HeaderDragDeltaEvent = EventManager.RegisterRoutedEvent("HeaderDragDelta", RoutingStrategy.Bubble, typeof(DragDeltaEventHandler), typeof(WindowControl)); public event DragDeltaEventHandler HeaderDragDelta { add { AddHandler(HeaderDragDeltaEvent, value); } remove { RemoveHandler(HeaderDragDeltaEvent, value); } } #endregion //HeaderDragDeltaEvent #region HeaderIconClickedEvent public static readonly RoutedEvent HeaderIconClickedEvent = EventManager.RegisterRoutedEvent("HeaderIconClicked", RoutingStrategy.Bubble, typeof(MouseButtonEventHandler), typeof(WindowControl)); public event MouseButtonEventHandler HeaderIconClicked { add { AddHandler(HeaderIconClickedEvent, value); } remove { RemoveHandler(HeaderIconClickedEvent, value); } } #endregion //HeaderIconClickedEvent #region HeaderIconDoubleClickedEvent public static readonly RoutedEvent HeaderIconDoubleClickedEvent = EventManager.RegisterRoutedEvent("HeaderIconDoubleClicked", RoutingStrategy.Bubble, typeof(MouseButtonEventHandler), typeof(WindowControl)); public event MouseButtonEventHandler HeaderIconDoubleClicked { add { AddHandler(HeaderIconDoubleClickedEvent, value); } remove { RemoveHandler(HeaderIconDoubleClickedEvent, value); } } #endregion //HeaderIconDoubleClickedEvent #region CloseButtonClickedEvent public static readonly RoutedEvent CloseButtonClickedEvent = EventManager.RegisterRoutedEvent("CloseButtonClicked", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(WindowControl)); public event RoutedEventHandler CloseButtonClicked { add { AddHandler(CloseButtonClickedEvent, value); } remove { RemoveHandler(CloseButtonClickedEvent, value); } } #endregion //CloseButtonClickedEvent #endregion //Events #region Event Handler private void HeaderPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { MouseButtonEventArgs args = new MouseButtonEventArgs(Mouse.PrimaryDevice, 0, MouseButton.Left); args.RoutedEvent = (e.ClickCount == 2) ? HeaderMouseLeftButtonDoubleClickedEvent : HeaderMouseLeftButtonClickedEvent; args.Source = this; this.RaiseEvent(args); } private void HeaderPreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e) { MouseButtonEventArgs args = new MouseButtonEventArgs(Mouse.PrimaryDevice, 0, MouseButton.Right); args.RoutedEvent = HeaderMouseRightButtonClickedEvent; args.Source = this; this.RaiseEvent(args); } private void HeaderThumbDragDelta(object sender, DragDeltaEventArgs e) { DragDeltaEventArgs args = new DragDeltaEventArgs(e.HorizontalChange, e.VerticalChange); args.RoutedEvent = HeaderDragDeltaEvent; args.Source = this; this.RaiseEvent(args); } private void IconMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { MouseButtonEventArgs args = new MouseButtonEventArgs(Mouse.PrimaryDevice, 0, MouseButton.Left); args.RoutedEvent = (e.ClickCount == 2) ? HeaderIconDoubleClickedEvent : HeaderIconClickedEvent; args.Source = this; this.RaiseEvent(args); } private void Close(object sender, RoutedEventArgs e) { this.RaiseEvent(new RoutedEventArgs(CloseButtonClickedEvent, this)); } #endregion // Event Handler #region Internal Methods internal virtual void UpdateBlockMouseInputsPanel() { if (_windowBlockMouseInputsPanel != null) { _windowBlockMouseInputsPanel.Visibility = this.IsBlockMouseInputsPanelActive ? Visibility.Visible : Visibility.Collapsed; } } internal double GetHeaderHeight() { Grid headerGrid = this.Template.FindName(PART_HeaderGrid, this) as Grid; if (headerGrid != null) return headerGrid.ActualHeight; return 0; } #endregion #region Private Methods #endregion //Private Methods } }