Mercurial > silverbladetech
changeset 69:a0bcd783e612
Latest work
line wrap: on
line diff
--- a/SilverlightGlimpse/FloatableWindow/FloatableWindow.cs Mon Apr 23 11:05:11 2012 +0100 +++ b/SilverlightGlimpse/FloatableWindow/FloatableWindow.cs Mon Apr 23 11:06:10 2012 +0100 @@ -25,7 +25,6 @@ [TemplatePart(Name = PART_ContentRoot, Type = typeof(FrameworkElement))] [TemplatePart(Name = PART_Overlay, Type = typeof(Panel))] [TemplatePart(Name = PART_Root, Type = typeof(FrameworkElement))] - [TemplatePart(Name = PART_Resizer, Type = typeof(FrameworkElement))] [TemplateVisualState(Name = VSMSTATE_StateClosed, GroupName = VSMGROUP_Window)] [TemplateVisualState(Name = VSMSTATE_StateOpen, GroupName = VSMGROUP_Window)] public class FloatableWindow : ContentControl @@ -38,11 +37,6 @@ private const string PART_Chrome = "Chrome"; /// <summary> - /// The name of the Resizer template part. - /// </summary> - private const string PART_Resizer = "Resizer"; - - /// <summary> /// The name of the CloseButton template part. /// </summary> private const string PART_CloseButton = "CloseButton"; @@ -414,7 +408,6 @@ { this.DefaultStyleKey = typeof(FloatableWindow); this.InteractionState = WindowInteractionState.NotResponding; - this.ResizeMode = ResizeMode.CanResize; } #endregion Constructors @@ -437,10 +430,11 @@ #region Properties + private Panel _parentLayoutRoot; public Panel ParentLayoutRoot { - get; - set; + get { return _parentLayoutRoot; } + set { _parentLayoutRoot = value; } } /// <summary> @@ -572,12 +566,6 @@ private set; } - public ResizeMode ResizeMode - { - get; - set; - } - #endregion Properties #region Static Methods @@ -979,34 +967,6 @@ } /// <summary> - /// Executed when the ContentPresenter size changes. - /// </summary> - /// <param name="sender">Content Presenter object.</param> - /// <param name="e">SizeChanged event args.</param> - private void ContentPresenter_SizeChanged(object sender, SizeChangedEventArgs e) - { - // timheuer: not sure really why this is here? - //if (this.ContentRoot != null && Application.Current != null && Application.Current.RootVisual != null && _isOpen) - //{ - // GeneralTransform gt = this.ContentRoot.TransformToVisual(Application.Current.RootVisual); - - // if (gt != null) - // { - // Point p = gt.Transform(new Point(0, 0)); - - // double x = this._windowPosition.X - p.X; - // double y = this._windowPosition.Y - p.Y; - // UpdateContentRootTransform(x, y); - // } - //} - - //RectangleGeometry rg = new RectangleGeometry(); - //rg.Rect = new Rect(0, 0, this._contentPresenter.ActualWidth, this._contentPresenter.ActualHeight); - //this._contentPresenter.Clip = rg; - //this.UpdatePosition(); - } - - /// <summary> /// Finds the X coordinate of a point that is defined by a line. /// </summary> /// <param name="p1">Starting point of the line.</param> @@ -1081,7 +1041,6 @@ } this._root = GetTemplateChild(PART_Root) as FrameworkElement; - this._resizer = GetTemplateChild(PART_Resizer) as FrameworkElement; if (this._root != null) { @@ -1118,19 +1077,6 @@ } //TODO: Figure out why I can't wire up the event below in SubscribeToTemplatePartEvents this._root.MouseLeftButtonDown += new MouseButtonEventHandler(this.ContentRoot_MouseLeftButtonDown); - - if (this.ResizeMode == ResizeMode.CanResize) - { - this._resizer.MouseLeftButtonDown += new System.Windows.Input.MouseButtonEventHandler(Resizer_MouseLeftButtonDown); - this._resizer.MouseLeftButtonUp += new System.Windows.Input.MouseButtonEventHandler(Resizer_MouseLeftButtonUp); - this._resizer.MouseMove += new System.Windows.Input.MouseEventHandler(Resizer_MouseMove); - this._resizer.MouseEnter += new MouseEventHandler(Resizer_MouseEnter); - this._resizer.MouseLeave += new MouseEventHandler(Resizer_MouseLeave); - } - else - { - this._resizer.Opacity = 0; - } } this.ContentRoot = GetTemplateChild(PART_ContentRoot) as FrameworkElement; @@ -1157,21 +1103,6 @@ } } - void Resizer_MouseLeave(object sender, MouseEventArgs e) - { - if (!this._isMouseCaptured) - { - this._resizer.Opacity = .25; - } - } - - void Resizer_MouseEnter(object sender, MouseEventArgs e) - { - if (!this._isMouseCaptured) - { - this._resizer.Opacity = 1; - } - } /// <summary> /// Raises the @@ -1453,10 +1384,6 @@ this._chrome.MouseMove += new MouseEventHandler(this.Chrome_MouseMove); } - if (this._contentPresenter != null) - { - this._contentPresenter.SizeChanged += new SizeChangedEventHandler(this.ContentPresenter_SizeChanged); - } } /// <summary> @@ -1494,11 +1421,6 @@ this._chrome.MouseLeftButtonUp -= new MouseButtonEventHandler(this.Chrome_MouseLeftButtonUp); this._chrome.MouseMove -= new MouseEventHandler(this.Chrome_MouseMove); } - - if (this._contentPresenter != null) - { - this._contentPresenter.SizeChanged -= new SizeChangedEventHandler(this.ContentPresenter_SizeChanged); - } } /// <summary>
--- a/SilverlightGlimpse/FloatableWindow/FloatableWindow.csproj Mon Apr 23 11:05:11 2012 +0100 +++ b/SilverlightGlimpse/FloatableWindow/FloatableWindow.csproj Mon Apr 23 11:06:10 2012 +0100 @@ -14,12 +14,13 @@ <AppDesignerFolder>Properties</AppDesignerFolder> <RootNamespace>FloatableWindow</RootNamespace> <AssemblyName>FloatableWindow</AssemblyName> - <TargetFrameworkVersion>v3.0</TargetFrameworkVersion> + <TargetFrameworkVersion>v5.0</TargetFrameworkVersion> <SilverlightApplication>false</SilverlightApplication> <ValidateXaml>true</ValidateXaml> <ThrowErrorsInValidation>true</ThrowErrorsInValidation> - <SignAssembly>true</SignAssembly> - <AssemblyOriginatorKeyFile>FloatableWindowStrongNameKey.snk</AssemblyOriginatorKeyFile> + <SignAssembly>false</SignAssembly> + <AssemblyOriginatorKeyFile> + </AssemblyOriginatorKeyFile> <SccProjectName> </SccProjectName> <SccLocalPath> @@ -34,7 +35,7 @@ </FileUpgradeFlags> <UpgradeBackupLocation> </UpgradeBackupLocation> - <OldToolsVersion>3.5</OldToolsVersion> + <OldToolsVersion>4.0</OldToolsVersion> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <DebugSymbols>true</DebugSymbols> @@ -72,10 +73,8 @@ <ItemGroup> <Compile Include="FloatableWindow.cs" /> <Compile Include="FloatableWindowAutomationPeer.cs" /> - <Compile Include="GlobalSuppressions.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\Resources.Designer.cs" /> - <Compile Include="ResizeMode.cs" /> </ItemGroup> <ItemGroup> <Page Include="themes\generic.xaml"> @@ -83,15 +82,11 @@ <Generator>MSBuild:MarkupCompilePass1</Generator> <Generator>MSBuild:Compile</Generator> <SubType>Designer</SubType> + <Generator>MSBuild:Compile</Generator> + <SubType>Designer</SubType> </Page> </ItemGroup> <ItemGroup> - <Content Include="README.txt" /> - </ItemGroup> - <ItemGroup> - <None Include="FloatableWindowStrongNameKey.snk" /> - </ItemGroup> - <ItemGroup> <EmbeddedResource Include="Properties\Resources.resx" /> </ItemGroup> <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Silverlight\$(SilverlightVersion)\Microsoft.Silverlight.CSharp.targets" />
--- a/SilverlightGlimpse/FloatableWindow/FloatableWindowAutomationPeer.cs Mon Apr 23 11:05:11 2012 +0100 +++ b/SilverlightGlimpse/FloatableWindow/FloatableWindowAutomationPeer.cs Mon Apr 23 11:06:10 2012 +0100 @@ -9,11 +9,6 @@ namespace System.Windows.Automation.Peers { - /// <summary> - /// Exposes <see cref="T:System.Windows.Controls.FloatableWindow" /> types to UI - /// automation. - /// </summary> - /// <QualityBand>Preview</QualityBand> public class FloatableWindowAutomationPeer : FrameworkElementAutomationPeer, IWindowProvider, ITransformProvider { #region Data @@ -59,16 +54,6 @@ #endregion Properties - /// <summary> - /// Initializes a new instance of the - /// <see cref="T:System.Windows.Automation.Peers.FloatableWindowAutomationPeer" /> - /// class. - /// </summary> - /// <param name="owner"> - /// The <see cref="T:System.Windows.Controls.FloatableWindow" /> to - /// associate with this - /// <see cref="T:System.Windows.Automation.Peers.FloatableWindowAutomationPeer" />. - /// </param> public FloatableWindowAutomationPeer(FloatableWindow owner) : base(owner) {
--- a/SilverlightGlimpse/FloatableWindow/GlobalSuppressions.cs Mon Apr 23 11:05:11 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,3 +0,0 @@ -// This source is subject to the Microsoft Public License (Ms-PL). -// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details. -using System.Diagnostics.CodeAnalysis; \ No newline at end of file
--- a/SilverlightGlimpse/FloatableWindow/README.txt Mon Apr 23 11:05:11 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,7 +0,0 @@ -This is an adaptation of the ChildWindow control for Silverlight in the -Microsoft Silverlight SDK. The ChildWindow control is licensed under the -Ms-PL license, and as-such, FloatableWindow is also licensed under Ms-PL. - -This was build as a proof of concept and no warranties are provided, -implied or otherwise. The author who adapted this control is -Tim Heuer, who may be contacted at http://timheuer.com/blog/. \ No newline at end of file
--- a/SilverlightGlimpse/FloatableWindow/ResizeMode.cs Mon Apr 23 11:05:11 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,12 +0,0 @@ -using System; - -namespace System.Windows -{ - public enum ResizeMode - { - NoResize = 0, - CanMinimize = 1, - CanResize = 2, - CanResizeWithGrip = 3, - } -}
--- a/SilverlightGlimpse/FloatableWindow/themes/generic.xaml Mon Apr 23 11:05:11 2012 +0100 +++ b/SilverlightGlimpse/FloatableWindow/themes/generic.xaml Mon Apr 23 11:06:10 2012 +0100 @@ -1,105 +1,64 @@ -<ResourceDictionary - xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" - xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" - xmlns:controls="clr-namespace:System.Windows.Controls" - xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows"> +<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:controls="clr-namespace:System.Windows.Controls" + xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows"> - <Storyboard x:Name="ResizerEnter"> - <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="Resizer" Storyboard.TargetProperty="(UIElement.Opacity)"> - <EasingDoubleKeyFrame KeyTime="00:00:00" Value="1"/> - </DoubleAnimationUsingKeyFrames> - </Storyboard> - <Storyboard x:Name="ResizerLeave"> - <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="Resizer" Storyboard.TargetProperty="(UIElement.Opacity)"> - <EasingDoubleKeyFrame KeyTime="00:00:00" Value="0"/> - </DoubleAnimationUsingKeyFrames> - </Storyboard> - <Style x:Key="ResizerStyle" TargetType="Thumb"> - <Setter Property="Background" Value="#FF1F3B53"/> - <Setter Property="BorderThickness" Value="1"/> - <Setter Property="IsTabStop" Value="False"/> - <Setter Property="BorderBrush"> - <Setter.Value> - <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> - <GradientStop Color="#FFA3AEB9" Offset="0"/> - <GradientStop Color="#FF8399A9" Offset="0.375"/> - <GradientStop Color="#FF718597" Offset="0.375"/> - <GradientStop Color="#FF617584" Offset="1"/> - </LinearGradientBrush> - </Setter.Value> - </Setter> - <Setter Property="Template"> - <Setter.Value> - <ControlTemplate TargetType="Thumb"> - <Path Fill="#FFB1B1B1" Stretch="Fill" Height="20" Width="20" UseLayoutRounding="False" Data="M15.499995,0.5 L15.499995,15.5 L0.5,15.5 z"> - <VisualStateManager.VisualStateGroups> - <VisualStateGroup x:Name="CommonStates"> - <VisualState x:Name="Normal"/> - <VisualState x:Name="MouseOver"/> - <VisualState x:Name="Pressed"/> - <VisualState x:Name="Disabled"/> - </VisualStateGroup> - <VisualStateGroup x:Name="FocusStates"> - <VisualState x:Name="Unfocused"/> - <VisualState x:Name="Focused"/> - </VisualStateGroup> - </VisualStateManager.VisualStateGroups> - </Path> - </ControlTemplate> - </Setter.Value> - </Setter> - </Style> <Style TargetType="controls:FloatableWindow"> - <Setter Property="IsTabStop" Value="false"/> - <Setter Property="TabNavigation" Value="Cycle"/> - <Setter Property="HorizontalAlignment" Value="Center"/> - <Setter Property="VerticalAlignment" Value="Center"/> - <Setter Property="HorizontalContentAlignment" Value="Stretch"/> - <Setter Property="VerticalContentAlignment" Value="Stretch"/> - <Setter Property="BorderThickness" Value="1"/> + <Setter Property="IsTabStop" Value="false" /> + <Setter Property="TabNavigation" Value="Cycle" /> + <Setter Property="HorizontalAlignment" Value="Center" /> + <Setter Property="VerticalAlignment" Value="Center" /> + <Setter Property="HorizontalContentAlignment" Value="Stretch" /> + <Setter Property="VerticalContentAlignment" Value="Stretch" /> + <Setter Property="BorderThickness" Value="1" /> <Setter Property="BorderBrush"> <Setter.Value> <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1"> - <GradientStop Color="#FFA3AEB9" Offset="0"/> - <GradientStop Color="#FF8399A9" Offset="0.375"/> - <GradientStop Color="#FF718597" Offset="0.375"/> - <GradientStop Color="#FF617584" Offset="1"/> + <GradientStop Offset="0" Color="#FFA3AEB9" /> + <GradientStop Offset="0.375" Color="#FF8399A9" /> + <GradientStop Offset="0.375" Color="#FF718597" /> + <GradientStop Offset="1" Color="#FF617584" /> </LinearGradientBrush> </Setter.Value> </Setter> <Setter Property="OverlayBrush"> <Setter.Value> - <SolidColorBrush Color="#7F000000"/> + <SolidColorBrush Color="#7F000000" /> </Setter.Value> </Setter> - <Setter Property="OverlayOpacity" Value="1"/> + <Setter Property="OverlayOpacity" Value="1" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="controls:FloatableWindow"> <Grid x:Name="Root"> <Grid.Resources> <Style x:Key="ButtonStyle" TargetType="Button"> - <Setter Property="Background" Value="#FF1F3B53"/> - <Setter Property="Foreground" Value="#FF000000"/> - <Setter Property="Padding" Value="3"/> - <Setter Property="BorderThickness" Value="1"/> + <Setter Property="Background" Value="#FF1F3B53" /> + <Setter Property="Foreground" Value="#FF000000" /> + <Setter Property="Padding" Value="3" /> + <Setter Property="BorderThickness" Value="1" /> <Setter Property="BorderBrush"> <Setter.Value> - <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> - <GradientStop Color="#FFA3AEB9" Offset="0"/> - <GradientStop Color="#FF8399A9" Offset="0.375"/> - <GradientStop Color="#FF718597" Offset="0.375"/> - <GradientStop Color="#FF617584" Offset="1"/> + <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1"> + <GradientStop Offset="0" Color="#FFA3AEB9" /> + <GradientStop Offset="0.375" Color="#FF8399A9" /> + <GradientStop Offset="0.375" Color="#FF718597" /> + <GradientStop Offset="1" Color="#FF617584" /> </LinearGradientBrush> </Setter.Value> </Setter> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Button"> - <Grid HorizontalAlignment="Center" VerticalAlignment="Center" Width="15" Height="14" Background="#02FFFFFF" x:Name="grid"> + <Grid x:Name="grid" + Width="15" + Height="14" + HorizontalAlignment="Center" + VerticalAlignment="Center" + Background="#02FFFFFF"> <vsm:VisualStateManager.VisualStateGroups> <vsm:VisualStateGroup x:Name="CommonStates"> - <vsm:VisualState x:Name="Normal"/> + <vsm:VisualState x:Name="Normal" /> <vsm:VisualState x:Name="MouseOver"> <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="X_Fuzz2" Storyboard.TargetProperty="Visibility"> @@ -111,12 +70,18 @@ <ObjectAnimationUsingKeyFrames Storyboard.TargetName="X_Fuzz0" Storyboard.TargetProperty="Visibility"> <DiscreteObjectKeyFrame KeyTime="0" Value="Visible" /> </ObjectAnimationUsingKeyFrames> - <DoubleAnimation Duration="0" Storyboard.TargetName="X" Storyboard.TargetProperty="Opacity" To="0.95"/> + <DoubleAnimation Duration="0" + Storyboard.TargetName="X" + Storyboard.TargetProperty="Opacity" + To="0.95" /> </Storyboard> </vsm:VisualState> <vsm:VisualState x:Name="Pressed"> <Storyboard> - <DoubleAnimation Duration="0" Storyboard.TargetName="X" Storyboard.TargetProperty="Opacity" To="0.85"/> + <DoubleAnimation Duration="0" + Storyboard.TargetName="X" + Storyboard.TargetProperty="Opacity" + To="0.85" /> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="X_Fuzz2" Storyboard.TargetProperty="Visibility"> <DiscreteObjectKeyFrame KeyTime="0" Value="Visible" /> </ObjectAnimationUsingKeyFrames> @@ -130,31 +95,78 @@ </vsm:VisualState> <vsm:VisualState x:Name="Disabled"> <Storyboard> - <DoubleAnimation Duration="0" Storyboard.TargetName="X" Storyboard.TargetProperty="Opacity" To="0.5"/> + <DoubleAnimation Duration="0" + Storyboard.TargetName="X" + Storyboard.TargetProperty="Opacity" + To="0.5" /> </Storyboard> </vsm:VisualState> </vsm:VisualStateGroup> </vsm:VisualStateManager.VisualStateGroups> - <Path HorizontalAlignment="Center" Margin="0,-1,0,0" Width="9" Fill="#14C51900" Stretch="Fill" Data="F1 M 6.742676,3.852539 L 9.110840,1.559570 L 8.910645,0.500000 L 6.838379,0.500000 L 4.902832,2.435547 L 2.967285,0.500000 L 0.895020,0.500000 L 0.694824,1.559570 L 3.062988,3.852539 L 0.527832,6.351563 L 0.689941,7.600586 L 2.967285,7.600586 L 4.897949,5.575195 L 6.854004,7.600586 L 9.115723,7.600586 L 9.277832,6.351563 L 6.742676,3.852539 Z" x:Name="X_Fuzz2" Stroke="#14C51900" Height="8" VerticalAlignment="Center" Opacity="1" RenderTransformOrigin="0.5,0.5" Visibility="Collapsed"> + <Path x:Name="X_Fuzz2" + Width="9" + Height="8" + Margin="0,-1,0,0" + HorizontalAlignment="Center" + VerticalAlignment="Center" + Data="F1 M 6.742676,3.852539 L 9.110840,1.559570 L 8.910645,0.500000 L 6.838379,0.500000 L 4.902832,2.435547 L 2.967285,0.500000 L 0.895020,0.500000 L 0.694824,1.559570 L 3.062988,3.852539 L 0.527832,6.351563 L 0.689941,7.600586 L 2.967285,7.600586 L 4.897949,5.575195 L 6.854004,7.600586 L 9.115723,7.600586 L 9.277832,6.351563 L 6.742676,3.852539 Z" + Fill="#14C51900" + Opacity="1" + RenderTransformOrigin="0.5,0.5" + Stretch="Fill" + Stroke="#14C51900" + Visibility="Collapsed"> <Path.RenderTransform> <TransformGroup> - <ScaleTransform ScaleX="1.3" ScaleY="1.3"/> + <ScaleTransform ScaleX="1.3" ScaleY="1.3" /> </TransformGroup> </Path.RenderTransform> </Path> - <Path HorizontalAlignment="Center" Margin="0,-1,0,0" Width="9" Fill="#1EC51900" Stretch="Fill" Data="F1 M 6.742676,3.852539 L 9.110840,1.559570 L 8.910645,0.500000 L 6.838379,0.500000 L 4.902832,2.435547 L 2.967285,0.500000 L 0.895020,0.500000 L 0.694824,1.559570 L 3.062988,3.852539 L 0.527832,6.351563 L 0.689941,7.600586 L 2.967285,7.600586 L 4.897949,5.575195 L 6.854004,7.600586 L 9.115723,7.600586 L 9.277832,6.351563 L 6.742676,3.852539 Z" x:Name="X_Fuzz1" Stroke="#1EC51900" Height="8" VerticalAlignment="Center" Opacity="1" RenderTransformOrigin="0.5,0.5" Visibility="Collapsed"> + <Path x:Name="X_Fuzz1" + Width="9" + Height="8" + Margin="0,-1,0,0" + HorizontalAlignment="Center" + VerticalAlignment="Center" + Data="F1 M 6.742676,3.852539 L 9.110840,1.559570 L 8.910645,0.500000 L 6.838379,0.500000 L 4.902832,2.435547 L 2.967285,0.500000 L 0.895020,0.500000 L 0.694824,1.559570 L 3.062988,3.852539 L 0.527832,6.351563 L 0.689941,7.600586 L 2.967285,7.600586 L 4.897949,5.575195 L 6.854004,7.600586 L 9.115723,7.600586 L 9.277832,6.351563 L 6.742676,3.852539 Z" + Fill="#1EC51900" + Opacity="1" + RenderTransformOrigin="0.5,0.5" + Stretch="Fill" + Stroke="#1EC51900" + Visibility="Collapsed"> <Path.RenderTransform> <TransformGroup> - <ScaleTransform ScaleX="1.1" ScaleY="1.1"/> + <ScaleTransform ScaleX="1.1" ScaleY="1.1" /> </TransformGroup> </Path.RenderTransform> </Path> - <Path HorizontalAlignment="Center" Margin="0,-1,0,0" Width="9" Fill="#FFC51900" Stretch="Fill" Data="F1 M 6.742676,3.852539 L 9.110840,1.559570 L 8.910645,0.500000 L 6.838379,0.500000 L 4.902832,2.435547 L 2.967285,0.500000 L 0.895020,0.500000 L 0.694824,1.559570 L 3.062988,3.852539 L 0.527832,6.351563 L 0.689941,7.600586 L 2.967285,7.600586 L 4.897949,5.575195 L 6.854004,7.600586 L 9.115723,7.600586 L 9.277832,6.351563 L 6.742676,3.852539 Z" x:Name="X_Fuzz0" Stroke="#FFC51900" Height="8" VerticalAlignment="Center" Opacity="1" Visibility="Collapsed"/> - <Path HorizontalAlignment="Center" Margin="0,-1,0,0" Width="9" Fill="#FFFFFFFF" Stretch="Fill" Data="F1 M 6.742676,3.852539 L 9.110840,1.559570 L 8.910645,0.500000 L 6.838379,0.500000 L 4.902832,2.435547 L 2.967285,0.500000 L 0.895020,0.500000 L 0.694824,1.559570 L 3.062988,3.852539 L 0.527832,6.351563 L 0.689941,7.600586 L 2.967285,7.600586 L 4.897949,5.575195 L 6.854004,7.600586 L 9.115723,7.600586 L 9.277832,6.351563 L 6.742676,3.852539 Z" x:Name="X" Height="8" VerticalAlignment="Center" Opacity="0.7"> + <Path x:Name="X_Fuzz0" + Width="9" + Height="8" + Margin="0,-1,0,0" + HorizontalAlignment="Center" + VerticalAlignment="Center" + Data="F1 M 6.742676,3.852539 L 9.110840,1.559570 L 8.910645,0.500000 L 6.838379,0.500000 L 4.902832,2.435547 L 2.967285,0.500000 L 0.895020,0.500000 L 0.694824,1.559570 L 3.062988,3.852539 L 0.527832,6.351563 L 0.689941,7.600586 L 2.967285,7.600586 L 4.897949,5.575195 L 6.854004,7.600586 L 9.115723,7.600586 L 9.277832,6.351563 L 6.742676,3.852539 Z" + Fill="#FFC51900" + Opacity="1" + Stretch="Fill" + Stroke="#FFC51900" + Visibility="Collapsed" /> + <Path x:Name="X" + Width="9" + Height="8" + Margin="0,-1,0,0" + HorizontalAlignment="Center" + VerticalAlignment="Center" + Data="F1 M 6.742676,3.852539 L 9.110840,1.559570 L 8.910645,0.500000 L 6.838379,0.500000 L 4.902832,2.435547 L 2.967285,0.500000 L 0.895020,0.500000 L 0.694824,1.559570 L 3.062988,3.852539 L 0.527832,6.351563 L 0.689941,7.600586 L 2.967285,7.600586 L 4.897949,5.575195 L 6.854004,7.600586 L 9.115723,7.600586 L 9.277832,6.351563 L 6.742676,3.852539 Z" + Fill="#FFFFFFFF" + Opacity="0.7" + Stretch="Fill"> <Path.Stroke> - <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> - <GradientStop Color="#FF313131" Offset="1"/> - <GradientStop Color="#FF8E9092" Offset="0"/> + <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1"> + <GradientStop Offset="1" Color="#FF313131" /> + <GradientStop Offset="0" Color="#FF8E9092" /> </LinearGradientBrush> </Path.Stroke> </Path> @@ -168,48 +180,74 @@ <vsm:VisualStateGroup x:Name="WindowStates"> <vsm:VisualState x:Name="Open"> <Storyboard> - <DoubleAnimationUsingKeyFrames BeginTime="0" Storyboard.TargetName="Overlay" Storyboard.TargetProperty="Opacity"> - <EasingDoubleKeyFrame KeyTime="0" Value="0"/> - <EasingDoubleKeyFrame KeyTime="00:00:00.3" Value="1"/> + <DoubleAnimationUsingKeyFrames BeginTime="0" + Storyboard.TargetName="Overlay" + Storyboard.TargetProperty="Opacity"> + <EasingDoubleKeyFrame KeyTime="0" Value="0" /> + <EasingDoubleKeyFrame KeyTime="00:00:00.3" Value="1" /> </DoubleAnimationUsingKeyFrames> - <DoubleAnimationUsingKeyFrames BeginTime="0" Storyboard.TargetName="ContentRoot" Storyboard.TargetProperty="(RenderTransform).(Children)[0].ScaleX"> - <SplineDoubleKeyFrame KeyTime="0" Value="0"/> - <SplineDoubleKeyFrame KeyTime="00:00:00.25" Value="0"/> - <SplineDoubleKeyFrame KeyTime="00:00:00.4" Value="1"/> - <SplineDoubleKeyFrame KeySpline="0,0,0.5,1" KeyTime="00:00:00.45" Value="1.05"/> - <SplineDoubleKeyFrame KeyTime="00:00:00.55" Value="1"/> + <DoubleAnimationUsingKeyFrames BeginTime="0" + Storyboard.TargetName="ContentRoot" + Storyboard.TargetProperty="(RenderTransform).(Children)[0].ScaleX"> + <SplineDoubleKeyFrame KeyTime="0" Value="0" /> + <SplineDoubleKeyFrame KeyTime="00:00:00.25" Value="0" /> + <SplineDoubleKeyFrame KeyTime="00:00:00.4" Value="1" /> + <SplineDoubleKeyFrame KeySpline="0,0,0.5,1" + KeyTime="00:00:00.45" + Value="1.05" /> + <SplineDoubleKeyFrame KeyTime="00:00:00.55" Value="1" /> </DoubleAnimationUsingKeyFrames> - <DoubleAnimationUsingKeyFrames BeginTime="0" Storyboard.TargetName="ContentRoot" Storyboard.TargetProperty="(RenderTransform).(Children)[0].ScaleY"> - <SplineDoubleKeyFrame KeyTime="0" Value="0"/> - <SplineDoubleKeyFrame KeyTime="00:00:00.25" Value="0"/> - <SplineDoubleKeyFrame KeyTime="00:00:00.4" Value="1"/> - <SplineDoubleKeyFrame KeySpline="0,0,0.5,1" KeyTime="00:00:00.45" Value="1.05"/> - <SplineDoubleKeyFrame KeyTime="00:00:00.55" Value="1"/> + <DoubleAnimationUsingKeyFrames BeginTime="0" + Storyboard.TargetName="ContentRoot" + Storyboard.TargetProperty="(RenderTransform).(Children)[0].ScaleY"> + <SplineDoubleKeyFrame KeyTime="0" Value="0" /> + <SplineDoubleKeyFrame KeyTime="00:00:00.25" Value="0" /> + <SplineDoubleKeyFrame KeyTime="00:00:00.4" Value="1" /> + <SplineDoubleKeyFrame KeySpline="0,0,0.5,1" + KeyTime="00:00:00.45" + Value="1.05" /> + <SplineDoubleKeyFrame KeyTime="00:00:00.55" Value="1" /> </DoubleAnimationUsingKeyFrames> </Storyboard> </vsm:VisualState> <vsm:VisualState x:Name="Closed"> <Storyboard> - <DoubleAnimationUsingKeyFrames BeginTime="0" Storyboard.TargetName="Overlay" Storyboard.TargetProperty="Opacity"> - <EasingDoubleKeyFrame KeyTime="0" Value="1"/> - <EasingDoubleKeyFrame KeyTime="00:00:00.3" Value="0"/> + <DoubleAnimationUsingKeyFrames BeginTime="0" + Storyboard.TargetName="Overlay" + Storyboard.TargetProperty="Opacity"> + <EasingDoubleKeyFrame KeyTime="0" Value="1" /> + <EasingDoubleKeyFrame KeyTime="00:00:00.3" Value="0" /> </DoubleAnimationUsingKeyFrames> - <DoubleAnimationUsingKeyFrames BeginTime="0" Storyboard.TargetName="ContentRoot" Storyboard.TargetProperty="(RenderTransform).(Children)[0].ScaleX"> - <SplineDoubleKeyFrame KeyTime="00:00:00.2" Value="1"/> - <SplineDoubleKeyFrame KeyTime="00:00:00.25" Value="1.05"/> - <SplineDoubleKeyFrame KeyTime="00:00:00.45" Value="0"/> + <DoubleAnimationUsingKeyFrames BeginTime="0" + Storyboard.TargetName="ContentRoot" + Storyboard.TargetProperty="(RenderTransform).(Children)[0].ScaleX"> + <SplineDoubleKeyFrame KeyTime="00:00:00.2" Value="1" /> + <SplineDoubleKeyFrame KeyTime="00:00:00.25" Value="1.05" /> + <SplineDoubleKeyFrame KeyTime="00:00:00.45" Value="0" /> </DoubleAnimationUsingKeyFrames> - <DoubleAnimationUsingKeyFrames BeginTime="0" Storyboard.TargetName="ContentRoot" Storyboard.TargetProperty="(RenderTransform).(Children)[0].ScaleY"> - <SplineDoubleKeyFrame KeyTime="00:00:00.2" Value="1"/> - <SplineDoubleKeyFrame KeyTime="00:00:00.25" Value="1.05"/> - <SplineDoubleKeyFrame KeyTime="00:00:00.45" Value="0"/> + <DoubleAnimationUsingKeyFrames BeginTime="0" + Storyboard.TargetName="ContentRoot" + Storyboard.TargetProperty="(RenderTransform).(Children)[0].ScaleY"> + <SplineDoubleKeyFrame KeyTime="00:00:00.2" Value="1" /> + <SplineDoubleKeyFrame KeyTime="00:00:00.25" Value="1.05" /> + <SplineDoubleKeyFrame KeyTime="00:00:00.45" Value="0" /> </DoubleAnimationUsingKeyFrames> </Storyboard> </vsm:VisualState> </vsm:VisualStateGroup> </vsm:VisualStateManager.VisualStateGroups> - <Grid x:Name="Overlay" HorizontalAlignment="Stretch" VerticalAlignment="Top" Margin="0" Background="{TemplateBinding OverlayBrush}" Opacity="{TemplateBinding OverlayOpacity}"/> - <Grid x:Name="ContentRoot" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}" RenderTransformOrigin="0.5,0.5" Height="{TemplateBinding Height}" Width="{TemplateBinding Width}"> + <Grid x:Name="Overlay" + Margin="0" + HorizontalAlignment="Stretch" + VerticalAlignment="Top" + Background="{TemplateBinding OverlayBrush}" + Opacity="{TemplateBinding OverlayOpacity}" /> + <Grid x:Name="ContentRoot" + Width="{TemplateBinding Width}" + Height="{TemplateBinding Height}" + HorizontalAlignment="{TemplateBinding HorizontalAlignment}" + VerticalAlignment="{TemplateBinding VerticalAlignment}" + RenderTransformOrigin="0.5,0.5"> <Grid.RenderTransform> <TransformGroup> <ScaleTransform /> @@ -218,51 +256,90 @@ <TranslateTransform /> </TransformGroup> </Grid.RenderTransform> - <Border BorderThickness="1" CornerRadius="2" BorderBrush="#14000000" Background="#14000000" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="-1"/> - <Border BorderThickness="1" CornerRadius="2.25" BorderBrush="#0F000000" Background="#0F000000" HorizontalAlignment="Stretch" Margin="-2" VerticalAlignment="Stretch"/> - <Border BorderThickness="1" CornerRadius="2.5" BorderBrush="#0C000000" Background="#0C000000" HorizontalAlignment="Stretch" Margin="-3" VerticalAlignment="Stretch"/> - <Border BorderThickness="1" CornerRadius="2.75" BorderBrush="#0A000000" Background="#0A000000" HorizontalAlignment="Stretch" Margin="-4" VerticalAlignment="Stretch"/> - <Border Background="#FFFFFFFF" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" CornerRadius="2"> - <Border CornerRadius="1.5" Margin="1"> + <Border Margin="-1" + HorizontalAlignment="Stretch" + VerticalAlignment="Stretch" + Background="#14000000" + BorderBrush="#14000000" + BorderThickness="1" + CornerRadius="2" /> + <Border Margin="-2" + HorizontalAlignment="Stretch" + VerticalAlignment="Stretch" + Background="#0F000000" + BorderBrush="#0F000000" + BorderThickness="1" + CornerRadius="2.25" /> + <Border Margin="-3" + HorizontalAlignment="Stretch" + VerticalAlignment="Stretch" + Background="#0C000000" + BorderBrush="#0C000000" + BorderThickness="1" + CornerRadius="2.5" /> + <Border Margin="-4" + HorizontalAlignment="Stretch" + VerticalAlignment="Stretch" + Background="#0A000000" + BorderBrush="#0A000000" + BorderThickness="1" + CornerRadius="2.75" /> + <Border Background="#FFFFFFFF" + BorderBrush="{TemplateBinding BorderBrush}" + BorderThickness="{TemplateBinding BorderThickness}" + CornerRadius="2"> + <Border Margin="1" CornerRadius="1.5"> <Border.Background> - <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> - <GradientStop Color="#FFE5E8EB" Offset="1"/> - <GradientStop Color="#FFF6F8F9" Offset="0"/> + <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1"> + <GradientStop Offset="1" Color="#FFE5E8EB" /> + <GradientStop Offset="0" Color="#FFF6F8F9" /> </LinearGradientBrush> </Border.Background> <Grid> <Grid.RowDefinitions> - <RowDefinition Height="Auto"/> - <RowDefinition/> + <RowDefinition Height="Auto" /> + <RowDefinition /> </Grid.RowDefinitions> - <Border x:Name="Chrome" Width="Auto" BorderBrush="#FFFFFFFF" BorderThickness="0,0,0,1"> + <Border x:Name="Chrome" + Width="Auto" + BorderBrush="#FFFFFFFF" + BorderThickness="0,0,0,1"> <Border.Background> - <LinearGradientBrush EndPoint="0.5,0.528" StartPoint="0.5,0"> - <GradientStop Color="#FFE5E8EB" Offset="1"/> - <GradientStop Color="#FFFEFEFE" Offset="0"/> + <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,0.528"> + <GradientStop Offset="1" Color="#FFE5E8EB" /> + <GradientStop Offset="0" Color="#FFFEFEFE" /> </LinearGradientBrush> </Border.Background> - <Grid Height="Auto" Width="Auto"> + <Grid Width="Auto" Height="Auto"> <Grid.ColumnDefinitions> - <ColumnDefinition/> - <ColumnDefinition Width="30"/> + <ColumnDefinition /> + <ColumnDefinition Width="30" /> </Grid.ColumnDefinitions> - <ContentControl Content="{TemplateBinding Title}" - IsTabStop="False" - FontWeight="Bold" + <ContentControl Margin="6,0,6,0" HorizontalAlignment="Stretch" VerticalAlignment="Center" - Margin="6,0,6,0"/> - <Button x:Name="CloseButton" Grid.Column="1" IsTabStop="False" HorizontalAlignment="Center" VerticalAlignment="Center" Width="15" Height="14" Style="{StaticResource ButtonStyle}"/> + Content="{TemplateBinding Title}" + FontWeight="Bold" + IsTabStop="False" /> + <Button x:Name="CloseButton" + Grid.Column="1" + Width="15" + Height="14" + HorizontalAlignment="Center" + VerticalAlignment="Center" + IsTabStop="False" + Style="{StaticResource ButtonStyle}" /> </Grid> </Border> - <Border Background="{TemplateBinding Background}" Margin="7" Grid.Row="1"> - <ContentPresenter x:Name="ContentPresenter" Content="{TemplateBinding Content}" - ContentTemplate="{TemplateBinding ContentTemplate}" - HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" - VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/> + <Border Grid.Row="1" + Margin="7" + Background="{TemplateBinding Background}"> + <ContentPresenter x:Name="ContentPresenter" + HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" + VerticalAlignment="{TemplateBinding VerticalContentAlignment}" + Content="{TemplateBinding Content}" + ContentTemplate="{TemplateBinding ContentTemplate}" /> </Border> - <Path x:Name="Resizer" Opacity=".25" Fill="#FFB1B1B1" Stretch="Fill" Height="20" Width="20" UseLayoutRounding="False" Grid.Row="1" Data="M15.499995,0.5 L15.499995,15.5 L0.5,15.5 z" HorizontalAlignment="Right" VerticalAlignment="Bottom"/> </Grid> </Border> </Border> @@ -272,5 +349,4 @@ </Setter.Value> </Setter> </Style> - </ResourceDictionary> \ No newline at end of file
--- a/SilverlightGlimpse/SilverFlow.Controls/Controllers/IResizableElement.cs Mon Apr 23 11:05:11 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,82 +0,0 @@ -using System.Windows; -using System.Windows.Input; - -namespace SilverFlow.Controls.Controllers -{ - /// <summary> - /// This interface shall be implemented by an element to be resized. - /// </summary> - public interface IResizableElement - { - /// <summary> - /// Gets or sets the width of the element. - /// </summary> - /// <value>The width.</value> - double Width { get; set; } - - /// <summary> - /// Gets or sets the height of the element. - /// </summary> - /// <value>The height.</value> - double Height { get; set; } - - /// <summary> - /// Gets or sets minimal width of the element. - /// </summary> - /// <value>Minimal width.</value> - double MinWidth { get; set; } - - /// <summary> - /// Gets or sets minimal height of the element. - /// </summary> - /// <value>Minimal height.</value> - double MinHeight { get; set; } - - /// <summary> - /// Gets or sets maximal width of the element. - /// </summary> - /// <value>Maximal width.</value> - double MaxWidth { get; set; } - - /// <summary> - /// Gets or sets maximal height of the element. - /// </summary> - /// <value>Maximal height.</value> - double MaxHeight { get; set; } - - /// <summary> - /// Gets the actual width. - /// </summary> - /// <value>The actual width.</value> - double ActualWidth { get; } - - /// <summary> - /// Gets the actual height. - /// </summary> - /// <value>The actual height.</value> - double ActualHeight { get; } - - /// <summary> - /// Gets or sets the position of the element. - /// </summary> - /// <value>The position.</value> - Point Position { get; set; } - - /// <summary> - /// Gets the parent of the element. - /// </summary> - /// <value>The parent object.</value> - DependencyObject Parent { get; } - - /// <summary> - /// Gets or sets the cursor of the element. - /// </summary> - /// <value>The cursor of the element.</value> - Cursor Cursor { get; set; } - - /// <summary> - /// Snapin controller. - /// </summary> - ISnapinController SnapinController { get; } - } -}
--- a/SilverlightGlimpse/SilverFlow.Controls/Controllers/ISnapinController.cs Mon Apr 23 11:05:11 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,68 +0,0 @@ -using System.Collections.Generic; -using System.Windows; - -namespace SilverFlow.Controls.Controllers -{ - public interface ISnapinController - { - /// <summary> - /// Gets or sets a value indicating whether snap in is enabled. - /// </summary> - /// <value><c>true</c> if snap in is enabled; otherwise, <c>false</c>.</value> - bool SnapinEnabled { get; set; } - - /// <summary> - /// Gets or sets snap in bounds. - /// </summary> - /// <value>Snap in bounds.</value> - IEnumerable<Rect> SnapinBounds { get; set; } - - /// <summary> - /// Gets or sets snap in distance. - /// </summary> - /// <value>Snap in distance.</value> - double SnapinDistance { get; set; } - - /// <summary> - /// Gets or sets a value snap in margin - distance between adjacent edges. - /// </summary> - /// <value>Snap in margin.</value> - double SnapinMargin { get; set; } - - /// <summary> - /// Returns new position of the specified rectangle - /// taking into account bounds the rectangle can be attracted to. - /// </summary> - /// <param name="rect">The rectangle.</param> - /// <returns>New position.</returns> - Point SnapRectangle(Rect rect); - - /// <summary> - /// Snaps the bottom right corner of the specified rectangle to the nearest bounds. - /// </summary> - /// <param name="rect">The rectangle.</param> - /// <returns>New position.</returns> - Point SnapBottomRightCorner(Rect rect); - - /// <summary> - /// Snaps the upper left corner of the specified rectangle to the nearest bounds. - /// </summary> - /// <param name="rect">The rectangle.</param> - /// <returns>New position.</returns> - Point SnapTopLeftCorner(Rect rect); - - /// <summary> - /// Snaps the lower left corner of the specified rectangle to the nearest bounds. - /// </summary> - /// <param name="rect">The rectangle.</param> - /// <returns>New position.</returns> - Point SnapBottomLeftCorner(Rect rect); - - /// <summary> - /// Snaps the upper right corner of the specified rectangle to the nearest bounds. - /// </summary> - /// <param name="rect">The rectangle.</param> - /// <returns>New position.</returns> - Point SnapTopRightCorner(Rect rect); - } -}
--- a/SilverlightGlimpse/SilverFlow.Controls/Controllers/InertiaController.cs Mon Apr 23 11:05:11 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,165 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Windows; -using System.Windows.Media.Animation; -using SilverFlow.Controls.Extensions; -using SilverFlow.Geometry; - -namespace SilverFlow.Controls.Controllers -{ - /// <summary> - /// Calculates inertial motion of a dragged element. - /// </summary> - public class InertiaController - { - private const double SCREEN_DPI = 96; - private const double INCH = 0.0254; - private const double GRAVITATIONAL_ACCELERATION = 9.81; - private const double COEFFICIENT_OF_SLIDING_FRICTION = 0.015; - private const double MIN_DELTA = 0.001; - private const double DELAY_BEFORE_MOUSE_UP_IN_MILLISECONDS = 100; - private const int MAX_LAST_POINTS_TO_COUNT = 4; - - private double pixelsPerMeter = SCREEN_DPI / INCH; - - private Queue<Trail> mouseTrails = new Queue<Trail>(); - - /// <summary> - /// An element starts its motion. - /// </summary> - /// <param name="point">The starting point of the motion.</param> - public void StartMotion(Point point) - { - mouseTrails.Clear(); - mouseTrails.Enqueue(new Trail(point, DateTime.Now)); - } - - /// <summary> - /// Saves the last position of the moved element. - /// </summary> - /// <param name="point">Current position.</param> - public void MoveToPoint(Point point) - { - while (mouseTrails.Count >= MAX_LAST_POINTS_TO_COUNT) - { - // Remove all points except the last ones - mouseTrails.Dequeue(); - } - - mouseTrails.Enqueue(new Trail(point, DateTime.Now)); - } - - /// <summary> - /// Gets inertial motion parameters: distance and duration. - /// </summary> - /// <param name="hostBounds">The host bounds.</param> - /// <param name="windowBounds">The window bounds.</param> - /// <returns> - /// The inertial motion parameters: distance and duration. - /// </returns> - public InertialMotion GetInertialMotionParameters(Rect hostBounds, Rect windowBounds) - { - if (mouseTrails.Count < 2) return null; - - var mouseTrailsArray = mouseTrails.ToArray(); - - Point startPosition = mouseTrailsArray[0].Position; - DateTime startTime = mouseTrailsArray[0].Timestamp; - Point endPosition = mouseTrailsArray[mouseTrails.Count - 1].Position; - DateTime endTime = mouseTrailsArray[mouseTrails.Count - 1].Timestamp; - - double timeBetweenNowAndLastMove = (DateTime.Now - endTime).TotalMilliseconds; - Vector2 vector = new Vector2(startPosition, endPosition); - - if (timeBetweenNowAndLastMove < DELAY_BEFORE_MOUSE_UP_IN_MILLISECONDS && !vector.IsZero) - { - double time = (endTime - startTime).TotalSeconds; - time = (time == 0) ? 0.001 : time; - - double distance = vector.Length / pixelsPerMeter; - - double intialVelocity = distance / time; - - double expectedDistance = ((intialVelocity * intialVelocity) / (2 * COEFFICIENT_OF_SLIDING_FRICTION * GRAVITATIONAL_ACCELERATION)); - double expectedTime = (2 * expectedDistance) / intialVelocity; - - double shiftX = Math.Round(vector.LengthX * expectedDistance / distance); - double shiftY = Math.Round(vector.LengthY * expectedDistance / distance); - - // New Inertial Motion Vector - Vector2 imVector = new Vector2(endPosition, shiftX, shiftY).Round(); - double expectedLength = imVector.Length; - - Rect bounds = hostBounds.Add(-windowBounds.Width, -windowBounds.Height); - - if (bounds.Contains(endPosition)) - { - imVector = EnsureEndPointInBounds(imVector, bounds).Round(); - } - else if (hostBounds.Contains(endPosition)) - { - imVector = EnsureEndPointInBounds(imVector, hostBounds).Round(); - } - - // Reduce expected time if the Inertial Motion Vector was truncated by the bounds - double realTime = (expectedLength == 0) ? 0 : (expectedTime * imVector.Length / expectedLength); - - var motion = new InertialMotion() - { - Seconds = realTime, - EndPosition = imVector.End, - EasingFunction = new CubicEase() - { - EasingMode = EasingMode.EaseOut - } - }; - - return motion; - } - - return null; - } - - /// <summary> - /// Ensures the end point is in bounds. - /// </summary> - /// <param name="vector">The vector to check its ending point.</param> - /// <param name="bounds">The bounds.</param> - /// <returns>A vector with the ending point within specified bounds.</returns> - private Vector2 EnsureEndPointInBounds(Vector2 vector, Rect bounds) - { - if (!vector.IsZero && !bounds.Contains(vector.End)) - { - if (vector.IsVertical) - { - vector.End = vector.End.EnsureInVerticalBounds(bounds); - } - else if (vector.IsHorizontal) - { - vector.End = vector.End.EnsureInHorizontalBounds(bounds); - } - else - { - double k = (vector.LengthY) / (vector.LengthX); - Point point = vector.End; - - if (vector.End.X < bounds.Left || vector.End.X > bounds.Right) - { - point = point.EnsureInHorizontalBounds(bounds); - point.Y = (k * (point.X - vector.Start.X)) + vector.Start.Y; - } - - if (point.Y < bounds.Top || point.Y > bounds.Bottom) - { - point = point.EnsureInVerticalBounds(bounds); - point.X = ((point.Y - vector.Start.Y) / k) + vector.Start.X; - } - - vector.End = point.EnsureInBounds(bounds); - } - } - - return vector; - } - } -}
--- a/SilverlightGlimpse/SilverFlow.Controls/Controllers/InertialMotion.cs Mon Apr 23 11:05:11 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -using System.Windows; -using System.Windows.Media.Animation; - -namespace SilverFlow.Controls.Controllers -{ - /// <summary> - /// Represents a vector and duration of the inertial motion, calculated by the InertiaController. - /// </summary> - public class InertialMotion - { - /// <summary> - /// Gets or sets ending position of the displaced element. - /// </summary> - /// <value>The ending position.</value> - public Point EndPosition { get; set; } - - /// <summary> - /// Gets or sets duration of the inertial motion in seconds. - /// </summary> - /// <value>Duration of the inertial motion in seconds.</value> - public double Seconds { get; set; } - - /// <summary> - /// Gets or sets the Easing Function applied to the animation. - /// </summary> - /// <value>The Easing Function.</value> - public IEasingFunction EasingFunction { get; set; } - - /// <summary> - /// Initializes a new instance of the <see cref="InertialMotion"/> class. - /// </summary> - public InertialMotion() - { - this.Seconds = 0; - } - } -}
--- a/SilverlightGlimpse/SilverFlow.Controls/Controllers/ResizeController.cs Mon Apr 23 11:05:11 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,453 +0,0 @@ -using System; -using System.Windows; -using System.Windows.Input; -using SilverFlow.Controls.Enums; -using SilverFlow.Controls.Extensions; - -namespace SilverFlow.Controls.Controllers -{ - /// <summary> - /// Calculates resizing element position and size. - /// </summary> - public class ResizeController - { - /// <summary> - /// Thickness of resizing area. - /// </summary> - private const double ResizingAreaDefaultValue = 6; - - /// <summary> - /// Minimal width of the resized window if MinWidth is set to 0. - /// </summary> - private const double MinResizedWidth = 20; - - /// <summary> - /// Resizing bounds, i.e. an area within which the resizing cursor can move. - /// </summary> - private Rect bounds; - - /// <summary> - /// Initial element size when resizing started. - /// </summary> - private Size initialSize; - - /// <summary> - /// Initial position of the element when resizing started. - /// </summary> - private Point initialPosition; - - /// <summary> - /// A corner or edge of the element used for resizing. - /// </summary> - private ResizeAnchor anchor; - - /// <summary> - /// An element implementing IResizableElement interface. - /// </summary> - private IResizableElement element; - - /// <summary> - /// Gets a framework element hosting resizing element. - /// </summary> - /// <value>The host.</value> - private FrameworkElement Host - { - get - { - return element.Parent as FrameworkElement; - } - } - - /// <summary> - /// Gets a value indicating whether the resizing can be started. - /// </summary> - /// <value> - /// <c>true</c> if resizing can be started; otherwise, <c>false</c>. - /// </value> - public bool CanResize - { - get - { - return anchor != ResizeAnchor.None; - } - } - - /// <summary> - /// Gets or sets the width of the resizing area. - /// </summary> - /// <value>The width of the resizing area. Default value is 6.</value> - public double ResizingArea { get; set; } - - /// <summary> - /// Gets a value indicating whether this instance can be resized horizontally. - /// </summary> - /// <value> - /// <c>true</c> if this instance can be resized horizontally; otherwise, <c>false</c>. - /// </value> - private bool CanResizeHorizontally - { - get - { - return !(element.MinWidth == element.MaxWidth && element.MinWidth != 0); - } - } - - /// <summary> - /// Gets a value indicating whether this instance can be resized vertically. - /// </summary> - /// <value> - /// <c>true</c> if this instance can be resized vertically; otherwise, <c>false</c>. - /// </value> - private bool CanResizeVertically - { - get - { - return !(element.MinHeight == element.MaxHeight && element.MinHeight != 0); - } - } - - /// <summary> - /// Initializes a new instance of the <see cref="ResizeController"/> class. - /// </summary> - /// <param name="resizableElement">The resizable element.</param> - public ResizeController(IResizableElement resizableElement) - { - if (resizableElement == null) - throw new ArgumentNullException("resizableElement"); - - element = resizableElement; - anchor = ResizeAnchor.None; - ResizingArea = ResizingAreaDefaultValue; - } - - /// <summary> - /// Starts resizing of the element. - /// </summary> - public void StartResizing() - { - initialSize = new Size(element.ActualWidth, element.ActualHeight); - initialPosition = element.Position; - - CalculateBoundsForResizing(); - } - - /// <summary> - /// Resizes the element. - /// </summary> - /// <param name="dx">Displacement by X-coordinate.</param> - /// <param name="dy">Displacement by Y-coordinate.</param> - public void Resize(double dx, double dy) - { - switch (anchor) - { - case ResizeAnchor.BottomRight: - ResizeBottomRight(dx, dy); - break; - - case ResizeAnchor.Right: - ResizeBottomRight(dx, 0); - break; - - case ResizeAnchor.Bottom: - ResizeBottomRight(0, dy); - break; - - case ResizeAnchor.TopLeft: - ResizeTopLeft(dx, dy); - break; - - case ResizeAnchor.Top: - ResizeTopLeft(0, dy); - break; - - case ResizeAnchor.Left: - ResizeTopLeft(dx, 0); - break; - - case ResizeAnchor.BottomLeft: - ResizeBottomLeft(dx, dy); - break; - - case ResizeAnchor.TopRight: - ResizeTopRight(dx, dy); - break; - } - } - - /// <summary> - /// Determines resizing anchor and sets appropriate Cursor. - /// </summary> - /// <param name="p">Coordinates of the mouse pointer.</param> - public void SetCursor(Point p) - { - if (p.Y < ResizingArea && p.X < ResizingArea) - { - anchor = ResizeAnchor.TopLeft; - element.Cursor = Cursors.SizeNWSE; - } - else if (p.Y < ResizingArea && p.X >= (element.ActualWidth - ResizingArea)) - { - anchor = ResizeAnchor.TopRight; - element.Cursor = Cursors.SizeNESW; - } - else if (p.Y < ResizingArea) - { - if (CanResizeVertically) - { - anchor = ResizeAnchor.Top; - element.Cursor = Cursors.SizeNS; - } - } - else if (p.X < ResizingArea && p.Y >= (element.ActualHeight - ResizingArea)) - { - anchor = ResizeAnchor.BottomLeft; - element.Cursor = Cursors.SizeNESW; - } - else if (p.X < ResizingArea) - { - if (CanResizeHorizontally) - { - anchor = ResizeAnchor.Left; - element.Cursor = Cursors.SizeWE; - } - } - else if (p.X >= (element.ActualWidth - ResizingArea) && p.Y >= (element.ActualHeight - ResizingArea)) - { - anchor = ResizeAnchor.BottomRight; - element.Cursor = Cursors.SizeNWSE; - } - else if (p.X >= (element.ActualWidth - ResizingArea)) - { - if (CanResizeHorizontally) - { - anchor = ResizeAnchor.Right; - element.Cursor = Cursors.SizeWE; - } - } - else if (p.Y >= (element.ActualHeight - ResizingArea)) - { - if (CanResizeVertically) - { - anchor = ResizeAnchor.Bottom; - element.Cursor = Cursors.SizeNS; - } - } - else - { - anchor = ResizeAnchor.None; - element.Cursor = null; - } - } - - /// <summary> - /// Calculates bounds for resizing. - /// </summary> - private void CalculateBoundsForResizing() - { - switch (anchor) - { - case ResizeAnchor.BottomRight: - case ResizeAnchor.Right: - case ResizeAnchor.Bottom: - bounds = GetBoundsForLowerRightCorner(); - break; - - case ResizeAnchor.TopLeft: - case ResizeAnchor.Top: - case ResizeAnchor.Left: - bounds = GetBoundsForUpperLeftCorner(); - break; - - case ResizeAnchor.BottomLeft: - bounds = GetBoundsForLowerLeftCorner(); - break; - - case ResizeAnchor.TopRight: - bounds = GetBoundsForUpperRightCorner(); - break; - } - } - - /// <summary> - /// Calculates bounds for resizing by the lower right corner. - /// </summary> - /// <returns>Bounding rectangle.</returns> - private Rect GetBoundsForLowerRightCorner() - { - double minWidth = (element.MinWidth != 0) ? element.MinWidth : MinResizedWidth; - double minHeight = element.MinHeight; - - double maxWidth = Host.ActualWidth - initialPosition.X; - - if (!element.MaxWidth.IsNotSet() && element.MaxWidth > 0) - maxWidth = Math.Min(maxWidth, element.MaxWidth); - - double maxHeight = Host.ActualHeight - initialPosition.Y; - if (!element.MaxHeight.IsNotSet() && element.MaxHeight > 0) - maxHeight = Math.Min(maxHeight, element.MaxHeight); - - Point p1 = initialPosition.Add(minWidth, minHeight); - Point p2 = initialPosition.Add(maxWidth, maxHeight); - - return new Rect(p1, p2); - } - - /// <summary> - /// Calculates bounds for resizing by the upper left corner. - /// </summary> - /// <returns>Bounding rectangle.</returns> - private Rect GetBoundsForUpperLeftCorner() - { - double minWidth = (element.MinWidth != 0) ? element.MinWidth : MinResizedWidth; - double minHeight = element.MinHeight; - - Point point = initialPosition.Add(initialSize); - double maxWidth = point.X; - double maxHeight = point.Y; - - if (!element.MaxWidth.IsNotSet() && element.MaxWidth > 0) - maxWidth = Math.Min(maxWidth, element.MaxWidth); - - if (!element.MaxHeight.IsNotSet() && element.MaxHeight > 0) - maxHeight = Math.Min(maxHeight, element.MaxHeight); - - Point p1 = point.Add(-maxWidth, -maxHeight); - Point p2 = point.Add(-minWidth, -minHeight); - - return new Rect(p1, p2); - } - - /// <summary> - /// Calculates bounds for resizing by the lower left corner. - /// </summary> - /// <returns>Bounding rectangle.</returns> - private Rect GetBoundsForLowerLeftCorner() - { - double minWidth = (element.MinWidth != 0) ? element.MinWidth : MinResizedWidth; - double minHeight = element.MinHeight; - - Point point = initialPosition.Add(initialSize.Width, 0); - double maxWidth = point.X; - - if (!element.MaxWidth.IsNotSet() && element.MaxWidth > 0) - maxWidth = Math.Min(maxWidth, element.MaxWidth); - - double maxHeight = Host.ActualHeight - initialPosition.Y; - if (!element.MaxHeight.IsNotSet() && element.MaxHeight > 0) - maxHeight = Math.Min(maxHeight, element.MaxHeight); - - Point p1 = point.Add(-maxWidth, minHeight); - Point p2 = point.Add(-minWidth, maxHeight); - - return new Rect(p1, p2); - } - - /// <summary> - /// Calculates bounds for resizing by the upper right corner. - /// </summary> - /// <returns>Bounding rectangle.</returns> - private Rect GetBoundsForUpperRightCorner() - { - double minWidth = (element.MinWidth != 0) ? element.MinWidth : MinResizedWidth; - double minHeight = element.MinHeight; - - Point point = initialPosition.Add(0, initialSize.Height); - double maxWidth = Host.ActualWidth - initialPosition.X; - - if (!element.MaxWidth.IsNotSet() && element.MaxWidth > 0) - maxWidth = Math.Min(maxWidth, element.MaxWidth); - - double maxHeight = point.Y; - if (!element.MaxHeight.IsNotSet() && element.MaxHeight > 0) - maxHeight = Math.Min(maxHeight, element.MaxHeight); - - Point p1 = point.Add(minWidth, -maxHeight); - Point p2 = point.Add(maxWidth, -minHeight); - - return new Rect(p1, p2); - } - - /// <summary> - /// Resizes the window by the bottom right corner of the window. - /// </summary> - /// <param name="dx">Increment by X-coordinate.</param> - /// <param name="dy">Increment by Y-coordinate.</param> - private void ResizeBottomRight(double dx, double dy) - { - Rect newBounds = new Rect(initialPosition, initialSize.Add(dx, dy)); - Point point = element.SnapinController.SnapBottomRightCorner(newBounds); - - // If only one coordinate was changed - restore the other after snap in - if (dx == 0) - point.X = newBounds.BottomRight().X; - - if (dy == 0) - point.Y = newBounds.BottomRight().Y; - - point = point.EnsureInBounds(bounds); - - element.Width = point.X - initialPosition.X; - element.Height = point.Y - initialPosition.Y; - } - - /// <summary> - /// Resizes the window by the top left corner of the window. - /// </summary> - /// <param name="dx">Increment by X-coordinate.</param> - /// <param name="dy">Increment by Y-coordinate.</param> - private void ResizeTopLeft(double dx, double dy) - { - Rect newBounds = new Rect(initialPosition.Add(dx, dy), initialSize); - Point point = element.SnapinController.SnapTopLeftCorner(newBounds).EnsureInBounds(bounds); - - // If only one coordinate was changed - restore the other after snap in - if (dx == 0) - point.X = newBounds.Position().X; - - if (dy == 0) - point.Y = newBounds.Position().Y; - - element.Position = point; - - Point lowerRight = initialPosition.Add(initialSize); - element.Width = lowerRight.X - point.X; - element.Height = lowerRight.Y - point.Y; - } - - /// <summary> - /// Resizes the window by the lower left corner of the window. - /// </summary> - /// <param name="dx">Increment by X-coordinate.</param> - /// <param name="dy">Increment by Y-coordinate.</param> - private void ResizeBottomLeft(double dx, double dy) - { - Rect newBounds = new Rect(initialPosition.Add(dx, 0), initialSize.Add(-dx, dy)); - - Point lowerLeft = element.SnapinController.SnapBottomLeftCorner(newBounds).EnsureInBounds(bounds); - Point topLeft = new Point(lowerLeft.X, initialPosition.Y); - - element.Position = topLeft; - - element.Width = initialSize.Width + initialPosition.X - topLeft.X; - element.Height = lowerLeft.Y - initialPosition.Y; - } - - /// <summary> - /// Resizes the window by the top right corner of the window. - /// </summary> - /// <param name="dx">Increment by X-coordinate.</param> - /// <param name="dy">Increment by Y-coordinate.</param> - private void ResizeTopRight(double dx, double dy) - { - Rect newBounds = new Rect(initialPosition.Add(0, dy), initialSize.Add(dx, -dy)); - - Point topRight = element.SnapinController.SnapTopRightCorner(newBounds).EnsureInBounds(bounds); - Point topLeft = new Point(initialPosition.X, topRight.Y); - - element.Position = topLeft; - - element.Width = topRight.X - initialPosition.X; - element.Height = initialSize.Height + initialPosition.Y - topRight.Y; - } - } -}
--- a/SilverlightGlimpse/SilverFlow.Controls/Controllers/SnapinController.cs Mon Apr 23 11:05:11 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,333 +0,0 @@ -using System.Collections.Generic; -using System.Windows; -using SilverFlow.Controls.Extensions; -using SilverFlow.Geometry; - -namespace SilverFlow.Controls.Controllers -{ - /// <summary> - /// Provides helpers methods for calculating window position - /// during movement and resizing. - /// </summary> - public class SnapinController : ISnapinController - { - /// <summary> - /// Distance on which snapping works. - /// </summary> - private const double SnapinDistanceDefaultValue = 5; - - /// <summary> - /// Gets or sets a value indicating whether snap in is enabled. - /// </summary> - /// <value><c>true</c> if snap in is enabled; otherwise, <c>false</c>.</value> - public bool SnapinEnabled { get; set; } - - /// <summary> - /// Gets or sets snap in bounds. - /// </summary> - /// <value>Snap in bounds.</value> - public IEnumerable<Rect> SnapinBounds { get; set; } - - /// <summary> - /// Gets or sets snap in distance. - /// </summary> - /// <value>Snap in distance.</value> - public double SnapinDistance { get; set; } - - /// <summary> - /// Gets or sets a value snap in margin - distance between adjacent edges. - /// </summary> - /// <value>Snap in margin.</value> - public double SnapinMargin { get; set; } - - /// <summary> - /// Gets calculations accuracy. - /// </summary> - /// <value>Accuracy.</value> - private double Accuracy - { - get { return SnapinDistance + SnapinMargin; } - } - - /// <summary> - /// Returns new position of the specified rectangle - /// taking into account bounds the rectangle can be attracted to. - /// </summary> - /// <param name="rect">The rectangle.</param> - /// <returns>New position.</returns> - public Point SnapRectangle(Rect rect) - { - Point point = rect.Position(); - - if (SnapinEnabled) - { - Distance minDistance = new Distance(); - foreach (var bound in SnapinBounds) - { - Distance distance = DistanceBetweenRectangles(rect, bound); - minDistance = Distance.Min(distance, minDistance); - } - - point = point.Add(minDistance); - } - - return point; - } - - /// <summary> - /// Snaps the bottom right corner of the specified rectangle to the nearest bounds. - /// </summary> - /// <param name="rect">The rectangle.</param> - /// <returns>New position.</returns> - public Point SnapBottomRightCorner(Rect rect) - { - Point point = rect.BottomRight(); - - if (SnapinEnabled) - { - Distance minDistance = new Distance(); - foreach (var bound in SnapinBounds) - { - Distance distance = new Distance() - { - X = DistanceBetweenRightEdgeAndRectangle(rect, bound), - Y = DistanceBetweenBottomEdgeAndRectangle(rect, bound) - }; - - minDistance = Distance.Min(distance, minDistance); - } - - point = point.Add(minDistance); - } - - return point; - } - - /// <summary> - /// Snaps the upper left corner of the specified rectangle to the nearest bounds. - /// </summary> - /// <param name="rect">The rectangle.</param> - /// <returns>New position.</returns> - public Point SnapTopLeftCorner(Rect rect) - { - Point point = rect.Position(); - - if (SnapinEnabled) - { - Distance minDistance = new Distance(); - foreach (var bound in SnapinBounds) - { - Distance distance = new Distance() - { - X = DistanceBetweenLeftEdgeAndRectangle(rect, bound), - Y = DistanceBetweenTopEdgeAndRectangle(rect, bound) - }; - - minDistance = Distance.Min(distance, minDistance); - } - - point = point.Add(minDistance); - } - - return point; - } - - /// <summary> - /// Snaps the lower left corner of the specified rectangle to the nearest bounds. - /// </summary> - /// <param name="rect">The rectangle.</param> - /// <returns>New position.</returns> - public Point SnapBottomLeftCorner(Rect rect) - { - Point point = rect.BottomLeft(); - - if (SnapinEnabled) - { - Distance minDistance = new Distance(); - foreach (var bound in SnapinBounds) - { - Distance distance = new Distance() - { - X = DistanceBetweenLeftEdgeAndRectangle(rect, bound), - Y = DistanceBetweenBottomEdgeAndRectangle(rect, bound) - }; - - minDistance = Distance.Min(distance, minDistance); - } - - point = point.Add(minDistance); - } - - return point; - } - - /// <summary> - /// Snaps the upper right corner of the specified rectangle to the nearest bounds. - /// </summary> - /// <param name="rect">The rectangle.</param> - /// <returns>New position.</returns> - public Point SnapTopRightCorner(Rect rect) - { - Point point = rect.TopRight(); - - if (SnapinEnabled) - { - Distance minDistance = new Distance(); - foreach (var bound in SnapinBounds) - { - Distance distance = new Distance() - { - X = DistanceBetweenRightEdgeAndRectangle(rect, bound), - Y = DistanceBetweenTopEdgeAndRectangle(rect, bound) - }; - - minDistance = Distance.Min(distance, minDistance); - } - - point = point.Add(minDistance); - } - - return point; - } - - /// <summary> - /// Returns mininal distance between two rectangles. - /// </summary> - /// <param name="first">First rectangle.</param> - /// <param name="second">Second rectangle.</param> - /// <returns>Minimal distance.</returns> - private Distance DistanceBetweenRectangles(Rect first, Rect second) - { - double x1 = DistanceBetweenRightEdgeAndRectangle(first, second); - double x2 = DistanceBetweenLeftEdgeAndRectangle(first, second); - double y1 = DistanceBetweenBottomEdgeAndRectangle(first, second); - double y2 = DistanceBetweenTopEdgeAndRectangle(first, second); - - Distance distance = new Distance() - { - X = MathExtensions.AbsMin(x1, x2), - Y = MathExtensions.AbsMin(y1, y2) - }; - - return distance; - } - - /// <summary> - /// Returns distance between the right edge of the rectangle and another rectangle. - /// </summary> - /// <param name="first">First rectangle.</param> - /// <param name="second">Second rectangle.</param> - /// <returns>Minimal distance.</returns> - private double DistanceBetweenRightEdgeAndRectangle(Rect first, Rect second) - { - double snap; - double distance = double.NaN; - double x = first.X + first.Width - 1; - - if (first.OverlapsVertically(second, Accuracy)) - { - snap = second.X - 1 - SnapinMargin; - if (x.IsNear(snap, SnapinDistance)) - { - distance = MathExtensions.AbsMin(snap - x, distance); - } - - snap = second.X + second.Width - 1; - if (x.IsNear(snap, SnapinDistance)) - { - distance = MathExtensions.AbsMin(snap - x, distance); - } - } - - return distance; - } - - /// <summary> - /// Returns distance between the left edge of the rectangle and another rectangle. - /// </summary> - /// <param name="first">First rectangle.</param> - /// <param name="second">Second rectangle.</param> - /// <returns>Minimal distance.</returns> - private double DistanceBetweenLeftEdgeAndRectangle(Rect first, Rect second) - { - double snap; - double distance = double.NaN; - - if (first.OverlapsVertically(second, Accuracy)) - { - snap = second.X; - if (first.X.IsNear(snap, SnapinDistance)) - { - distance = MathExtensions.AbsMin(snap - first.X, distance); - } - - snap = second.X + second.Width + SnapinMargin; - if (first.X.IsNear(snap, SnapinDistance)) - { - distance = MathExtensions.AbsMin(snap - first.X, distance); - } - } - - return distance; - } - - /// <summary> - /// Returns distance between the bottom edge of the rectangle and another rectangle. - /// </summary> - /// <param name="first">First rectangle.</param> - /// <param name="second">Second rectangle.</param> - /// <returns>Minimal distance.</returns> - private double DistanceBetweenBottomEdgeAndRectangle(Rect first, Rect second) - { - double snap; - double distance = double.NaN; - double y = first.Y + first.Height - 1; - - if (first.OverlapsHorizontally(second, Accuracy)) - { - snap = second.Y - 1 - SnapinMargin; - if (y.IsNear(snap, SnapinDistance)) - { - distance = MathExtensions.AbsMin(snap - y, distance); - } - - snap = second.Y + second.Height - 1; - if (y.IsNear(snap, SnapinDistance)) - { - distance = MathExtensions.AbsMin(snap - y, distance); - } - } - - return distance; - } - - /// <summary> - /// Returns distance between the top edge of the rectangle and another rectangle. - /// </summary> - /// <param name="first">First rectangle.</param> - /// <param name="second">Second rectangle.</param> - /// <returns>Minimal distance.</returns> - private double DistanceBetweenTopEdgeAndRectangle(Rect first, Rect second) - { - double snap; - double distance = double.NaN; - - if (first.OverlapsHorizontally(second, Accuracy)) - { - snap = second.Y; - if (first.Y.IsNear(snap, SnapinDistance)) - { - distance = MathExtensions.AbsMin(snap - first.Y, distance); - } - - snap = second.Y + second.Height + SnapinMargin; - if (first.Y.IsNear(snap, SnapinDistance)) - { - distance = MathExtensions.AbsMin(snap - first.Y, distance); - } - } - - return distance; - } - } -}
--- a/SilverlightGlimpse/SilverFlow.Controls/Converters/BooleanToVisibilityConverter.cs Mon Apr 23 11:05:11 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +0,0 @@ -using System; -using System.Windows; -using System.Windows.Data; - -namespace SilverFlow.Controls.Converters -{ - public class BooleanToVisibilityConverter : IValueConverter - { - /// <summary> - /// Converts a boolean value to the display state of an element. - /// </summary> - /// <param name="value">The source data being passed to the target.</param> - /// <param name="targetType">The <see cref="T:System.Type"/> of data expected by the target dependency property.</param> - /// <param name="parameter">An optional parameter to be used in the converter logic.</param> - /// <param name="culture">The culture of the conversion.</param> - /// <returns> - /// The value to be passed to the target dependency property. - /// </returns> - public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) - { - if (value == null) - throw new ArgumentNullException("value"); - - return (bool)value ? Visibility.Visible : Visibility.Collapsed; - } - - public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) - { - throw new NotImplementedException(); - } - } -}
--- a/SilverlightGlimpse/SilverFlow.Controls/Enums/ResizeAnchor.cs Mon Apr 23 11:05:11 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,19 +0,0 @@ -namespace SilverFlow.Controls.Enums -{ - /// <summary> - /// Defines window's border or a corner where the user - /// clicked the mouse to start resizing. - /// </summary> - public enum ResizeAnchor - { - None = 0, - TopLeft = 1, - Top = 2, - TopRight = 3, - Right = 4, - BottomRight = 5, - Bottom = 6, - BottomLeft = 7, - Left = 9 - } -}
--- a/SilverlightGlimpse/SilverFlow.Controls/Enums/WindowAction.cs Mon Apr 23 11:05:11 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,23 +0,0 @@ -namespace SilverFlow.Controls.Enums -{ - /// <summary> - /// Defines mouse action. - /// </summary> - internal enum WindowAction - { - /// <summary> - /// Default - /// </summary> - None = 0, - - /// <summary> - /// Moving the window - /// </summary> - Move = 1, - - /// <summary> - /// Resizing the window - /// </summary> - Resize = 2 - } -}
--- a/SilverlightGlimpse/SilverFlow.Controls/Extensions/AnimationExtensions.cs Mon Apr 23 11:05:11 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,163 +0,0 @@ -using System; -using System.Windows; -using System.Windows.Media.Animation; - -namespace SilverFlow.Controls.Extensions -{ - /// <summary> - /// Useful Silverlight animation extensions - /// </summary> - public static class AnimationExtensions - { - /// <summary> - /// Animates specified property of the object. - /// </summary> - /// <param name="target">The target object to animate.</param> - /// <param name="propertyPath">Property path, e.g. Canvas.Top.</param> - /// <param name="from">Animation's starting value.</param> - /// <param name="to">Animation's ending value.</param> - /// <param name="milliseconds">Duration of the animation in milliseconds.</param> - /// <param name="easingFunction">Easing function applied to the animation.</param> - /// <param name="completed">Event handler called when animation completed.</param> - /// <returns>Returns started storyboard.</returns> - public static Storyboard AnimateDoubleProperty(this DependencyObject target, string propertyPath, double? from, double? to, double milliseconds, - IEasingFunction easingFunction = null, EventHandler completed = null) - { - Duration duration = new Duration(TimeSpan.FromMilliseconds(milliseconds)); - DoubleAnimation doubleAnimation = new DoubleAnimation() - { - From = from, - To = to, - Duration = duration, - EasingFunction = easingFunction - }; - - Storyboard storyboard = new Storyboard(); - storyboard.Duration = duration; - storyboard.Children.Add(doubleAnimation); - - Storyboard.SetTarget(doubleAnimation, target); - Storyboard.SetTargetProperty(doubleAnimation, new PropertyPath(propertyPath)); - - if (completed != null) - storyboard.Completed += completed; - - storyboard.Begin(); - - return storyboard; - } - - /// <summary> - /// Fade in the specified object. - /// </summary> - /// <param name="target">The target object.</param> - /// <param name="milliseconds">Duration of the animation in milliseconds.</param> - /// <param name="completed">Event handler called when animation completed.</param> - /// <returns>Returns started storyboard.</returns> - public static Storyboard FadeIn(this DependencyObject target, double milliseconds, EventHandler completed = null) - { - return AnimateDoubleProperty(target, "Opacity", 0, 1, milliseconds, null, completed); - } - - /// <summary> - /// Fade out the specified object. - /// </summary> - /// <param name="target">The target object.</param> - /// <param name="milliseconds">Duration of the animation in milliseconds.</param> - /// <param name="completed">Event handler called when animation completed.</param> - /// <returns>Returns started storyboard.</returns> - public static Storyboard FadeOut(this DependencyObject target, double milliseconds, EventHandler completed = null) - { - return AnimateDoubleProperty(target, "Opacity", 1, 0, milliseconds, null, completed); - } - - /// <summary> - /// Moves and resizes the object. - /// </summary> - /// <param name="target">The target object.</param> - /// <param name="position">Ending position.</param> - /// <param name="width">New width.</param> - /// <param name="height">New height.</param> - /// <param name="milliseconds">Duration of the animation in milliseconds.</param> - /// <param name="completed">Event handler called when animation completed.</param> - public static void MoveAndResize(this DependencyObject target, Point position, double width, double height, - double milliseconds, EventHandler completed = null) - { - Duration duration = new Duration(TimeSpan.FromMilliseconds(milliseconds)); - DoubleAnimation doubleAnimation1 = new DoubleAnimation(); - DoubleAnimation doubleAnimation2 = new DoubleAnimation(); - PointAnimation pointAnimation = new PointAnimation(); - - doubleAnimation1.Duration = duration; - doubleAnimation2.Duration = duration; - pointAnimation.Duration = duration; - - Storyboard storyboard = new Storyboard(); - storyboard.Duration = duration; - - storyboard.Children.Add(doubleAnimation1); - storyboard.Children.Add(doubleAnimation2); - storyboard.Children.Add(pointAnimation); - - Storyboard.SetTarget(doubleAnimation1, target); - Storyboard.SetTarget(doubleAnimation2, target); - Storyboard.SetTarget(pointAnimation, target); - - Storyboard.SetTargetProperty(doubleAnimation1, new PropertyPath("(Width)")); - Storyboard.SetTargetProperty(doubleAnimation2, new PropertyPath("(Height)")); - Storyboard.SetTargetProperty(pointAnimation, new PropertyPath("(Position)")); - - doubleAnimation1.To = width; - if (!height.IsNotSet()) - doubleAnimation2.To = height; - - pointAnimation.To = position; - - if (completed != null) - storyboard.Completed += completed; - - storyboard.Begin(); - } - - /// <summary> - /// Animates the translate transform object, responsible for displacement of the target. - /// </summary> - /// <param name="target">The target object.</param> - /// <param name="storyboard">The storyboard.</param> - /// <param name="to">Animation's ending value.</param> - /// <param name="seconds">Duration of the animation in seconds.</param> - /// <param name="easingFunction">Easing function applied to the animation.</param> - public static void AnimateTranslateTransform(this DependencyObject target, Storyboard storyboard, Point to, - double seconds, IEasingFunction easingFunction = null) - { - Duration duration = new Duration(TimeSpan.FromSeconds(seconds)); - - DoubleAnimation doubleAnimationX = new DoubleAnimation() - { - To = to.X, - Duration = duration, - EasingFunction = easingFunction - }; - - DoubleAnimation doubleAnimationY = new DoubleAnimation() - { - To = to.Y, - Duration = duration, - EasingFunction = easingFunction - }; - - storyboard.Stop(); - storyboard.Children.Clear(); - storyboard.Duration = duration; - storyboard.Children.Add(doubleAnimationX); - storyboard.Children.Add(doubleAnimationY); - - Storyboard.SetTarget(doubleAnimationX, target); - Storyboard.SetTarget(doubleAnimationY, target); - Storyboard.SetTargetProperty(doubleAnimationX, (target as UIElement).GetPropertyPathForTranslateTransformX()); - Storyboard.SetTargetProperty(doubleAnimationY, (target as UIElement).GetPropertyPathForTranslateTransformY()); - - storyboard.Begin(); - } - } -}
--- a/SilverlightGlimpse/SilverFlow.Controls/Extensions/ControlExtensions.cs Mon Apr 23 11:05:11 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,230 +0,0 @@ -using System; -using System.Linq; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Media; - -namespace SilverFlow.Controls.Extensions -{ - /// <summary> - /// Useful Silverlight controls extensions - /// </summary> - public static class ControlExtensions - { - /// <summary> - /// Sets the visible of the UIElement. - /// </summary> - /// <param name="uiElement">The UI element.</param> - /// <param name="visible">Set Visible if <c>true</c>; otherwise - Collapsed.</param> - public static void SetVisible(this UIElement uiElement, bool visible = true) - { - if (uiElement != null) - { - uiElement.Visibility = (visible) ? Visibility.Visible : Visibility.Collapsed; - } - } - - /// <summary> - /// Determines whether the specified UI element is visible. - /// </summary> - /// <param name="uiElement">The UI element.</param> - /// <returns><c>true</c> if the specified UI element is visible; otherwise, <c>false</c>.</returns> - public static bool IsVisible(this UIElement uiElement) - { - return uiElement != null && uiElement.Visibility == Visibility.Visible; - } - - /// <summary> - /// Determines whether the specified element contains the point. - /// </summary> - /// <param name="element">This FrameworkElement.</param> - /// <param name="point">The point to check.</param> - /// <param name="origin">Relative origin (optional).</param> - /// <returns><c>true</c> if the specified element contains the point; otherwise, <c>false</c>.</returns> - public static bool ContainsPoint(this FrameworkElement element, Point point, UIElement origin = null) - { - bool result = false; - - if (element != null) - { - Point elementOrigin = (origin == null) ? new Point(0, 0) : element.GetRelativePosition(origin); - Rect rect = new Rect(elementOrigin, new Size(element.ActualWidth, element.ActualHeight)); - result = rect.Contains(point); - } - - return result; - } - - /// <summary> - /// Gets position of the element relative to another specified (root) element. - /// </summary> - /// <param name="element">The element.</param> - /// <param name="rootElement">The root element.</param> - /// <returns>Relative position.</returns> - /// <exception cref="ArgumentNullException">Input parameter is null.</exception> - public static Point GetRelativePosition(this UIElement element, UIElement rootElement) - { - if (element == null) - throw new ArgumentNullException("element"); - - if (rootElement == null) - throw new ArgumentNullException("rootElement"); - - var transformFromClientToRoot = element.TransformToVisual(rootElement); - return transformFromClientToRoot.Transform(new Point(0, 0)); - } - - /// <summary> - /// Gets total horizontal value of the specified thickness. - /// </summary> - /// <param name="thickness">The thickness.</param> - /// <returns>Horizontal thickness.</returns> - /// <exception cref="ArgumentNullException">Input parameter is null.</exception> - public static double Horizontal(this Thickness thickness) - { - if (thickness == null) - throw new ArgumentNullException("thickness"); - - return thickness.Left + thickness.Right; - } - - /// <summary> - /// Gets total vertical value of the specified thickness. - /// </summary> - /// <param name="thickness">The thickness.</param> - /// <returns>Vertical thickness.</returns> - /// <exception cref="ArgumentNullException">Input parameter is null.</exception> - public static double Vertical(this Thickness thickness) - { - if (thickness == null) - throw new ArgumentNullException("thickness"); - - return thickness.Top + thickness.Bottom; - } - - /// <summary> - /// Gets the actual bounding rectangle of the FrameworkElement. - /// </summary> - /// <param name="element">The element.</param> - /// <returns>Actual bounding rectangle.</returns> - public static Rect GetActualBoundingRectangle(this FrameworkElement element) - { - if (element == null) - throw new ArgumentNullException("element"); - - return new Rect(0, 0, element.ActualWidth, element.ActualHeight); - } - - /// <summary> - /// Gets a PropertyPath for the TranslateTransform.X property. - /// </summary> - /// <param name="element">The element.</param> - /// <returns>A path to the property.</returns> - public static PropertyPath GetPropertyPathForTranslateTransformX(this UIElement element) - { - return element.GetPropertyPathForTranslateTransform("X"); - } - - /// <summary> - /// Gets a PropertyPath for the TranslateTransform.Y property. - /// </summary> - /// <param name="element">The element.</param> - /// <returns>A path to the property.</returns> - public static PropertyPath GetPropertyPathForTranslateTransformY(this UIElement element) - { - return element.GetPropertyPathForTranslateTransform("Y"); - } - - /// <summary> - /// Gets scale factor to fit the element to the specified size. - /// </summary> - /// <param name="element">The element to scale.</param> - /// <param name="maxWidth">Maximal width of the element.</param> - /// <param name="maxHeight">Maximal height of the element.</param> - /// <returns>Scale factor required to fit the element to the specified size.</returns> - public static double GetScaleFactorToFit(this FrameworkElement element, double maxWidth, double maxHeight) - { - if (element == null) - throw new ArgumentNullException("element"); - - double width = element.Width.IsNotSet() ? element.ActualWidth : element.Width; - double height = element.Height.IsNotSet() ? element.ActualHeight : element.Height; - - double scaleX = maxWidth / width; - double scaleY = maxHeight / height; - double minScale = Math.Min(scaleX, scaleY); - - return minScale; - } - - /// <summary> - /// Moves the element to the new container. The container can be a Panel or a Border derived class. - /// </summary> - /// <param name="element">The element.</param> - /// <param name="newContainer">The new container of the element.</param> - /// <exception cref="ArgumentNullException">New Container is null.</exception> - public static void MoveToContainer(this FrameworkElement element, FrameworkElement newContainer) - { - if (element == null) - throw new ArgumentNullException("element"); - - if (newContainer == null) - throw new ArgumentNullException("newContainer"); - - // Remove the element from the old container - element.RemoveFromContainer(); - - if (newContainer is Panel) - { - var container = newContainer as Panel; - if (!container.Children.Contains(element)) - container.Children.Add(element); - } - else if (newContainer is Border) - { - (newContainer as Border).Child = element; - } - } - - /// <summary> - /// Removes the element from its container. The container can be a Panel or a Border derived class. - /// </summary> - /// <param name="element">The element.</param> - public static void RemoveFromContainer(this FrameworkElement element) - { - if (element != null && element.Parent != null) - { - // Remove the element from the old container - if (element.Parent is Panel) - { - (element.Parent as Panel).Children.Remove(element); - } - else if (element.Parent is Border) - { - (element.Parent as Border).Child = null; - } - } - } - - /// <summary> - /// Gets a PropertyPath for the TranslateTransform property. - /// </summary> - /// <param name="element">The element.</param> - /// <param name="translateBy">"X" or "Y" TranslateTransform property.</param> - /// <returns>A path to the property.</returns> - private static PropertyPath GetPropertyPathForTranslateTransform(this UIElement element, string translateBy) - { - if (element == null) - throw new ArgumentNullException("element"); - - var transformGroup = element.RenderTransform as TransformGroup; - var translateTransform = transformGroup.Children.OfType<TranslateTransform>().FirstOrDefault(); - int translateTransformIndex = transformGroup.Children.IndexOf(translateTransform); - - string path = string.Format("(FrameworkElement.RenderTransform).(TransformGroup.Children)[{0}].(TranslateTransform.{1})", - translateTransformIndex, translateBy); - - return new PropertyPath(path); - } - } -}
--- a/SilverlightGlimpse/SilverFlow.Controls/Extensions/GeometryExtensions.cs Mon Apr 23 11:05:11 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,292 +0,0 @@ -using System; -using System.Windows; -using SilverFlow.Geometry; - -namespace SilverFlow.Controls.Extensions -{ - /// <summary> - /// Geometry extensions - /// </summary> - public static class GeometryExtensions - { - /// <summary> - /// Rounds the specified point to the nearest integer coordinates. - /// </summary> - /// <param name="point">The point to round coordinates.</param> - /// <returns>New point with rounded coordinates.</returns> - public static Point Round(this Point point) - { - return new Point(Math.Round(point.X), Math.Round(point.Y)); - } - - /// <summary> - /// Ensures that coordinates are positive. - /// </summary> - /// <param name="point">The point.</param> - /// <returns>Point with positive coordinates.</returns> - public static Point EnsurePositive(this Point point) - { - return new Point() - { - X = (point.X < 0) ? 0 : point.X, - Y = (point.Y < 0) ? 0 : point.Y - }; - } - - /// <summary> - /// Gets position of the specified rectangle. - /// </summary> - /// <param name="rect">Rectangle.</param> - /// <returns>Upper left corner of the rectangle.</returns> - public static Point Position(this Rect rect) - { - return new Point(rect.X, rect.Y); - } - - /// <summary> - /// Gets position the lower right corner of the rectangle. - /// </summary> - /// <param name="rect">Rectangle.</param> - /// <returns>Lower right corner of the rectangle.</returns> - public static Point BottomRight(this Rect rect) - { - return new Point(rect.Right, rect.Bottom); - } - - /// <summary> - /// Gets position the lower left corner of the rectangle. - /// </summary> - /// <param name="rect">Rectangle.</param> - /// <returns>Lower left corner of the rectangle.</returns> - public static Point BottomLeft(this Rect rect) - { - return new Point(rect.X, rect.Bottom); - } - - /// <summary> - /// Gets position the upper right corner of the rectangle. - /// </summary> - /// <param name="rect">Rectangle.</param> - /// <returns>Upper right corner of the rectangle.</returns> - public static Point TopRight(this Rect rect) - { - return new Point(rect.Right, rect.Y); - } - - /// <summary> - /// Ensures that coordinates of the point are in the specified bounds. - /// </summary> - /// <param name="point">The point.</param> - /// <param name="bounds">The bounds.</param> - /// <returns>Point within the boinds.</returns> - public static Point EnsureInBounds(this Point point, Rect bounds) - { - return new Point() - { - X = point.X.EnsureInRange(bounds.X, bounds.Right), - Y = point.Y.EnsureInRange(bounds.Y, bounds.Bottom) - }; - } - - /// <summary> - /// Ensures that the X-coordinate of the point is in the specified horizontal bounds. - /// </summary> - /// <param name="point">The point.</param> - /// <param name="bounds">The bounds.</param> - /// <returns>Point with the X-coordinate within the boinds.</returns> - public static Point EnsureInHorizontalBounds(this Point point, Rect bounds) - { - return new Point() - { - X = point.X.EnsureInRange(bounds.X, bounds.Right), - Y = point.Y - }; - } - - /// <summary> - /// Ensures that the Y-coordinate of the point is in the specified vertical bounds. - /// </summary> - /// <param name="point">The point.</param> - /// <param name="bounds">The bounds.</param> - /// <returns>Point with the Y-coordinate within the boinds.</returns> - public static Point EnsureInVerticalBounds(this Point point, Rect bounds) - { - return new Point() - { - X = point.X, - Y = point.Y.EnsureInRange(bounds.Y, bounds.Bottom) - }; - } - - /// <summary> - /// Determines whether coordinates of the point are Not a Number (NaN). - /// </summary> - /// <param name="point">The point.</param> - /// <returns> - /// <c>true</c> if coordinates are not specified; otherwise, <c>false</c>. - /// </returns> - public static bool IsNotSet(this Point point) - { - return double.IsNaN(point.X) || double.IsNaN(point.Y); - } - - /// <summary> - /// Adds an offset to the specified point. - /// </summary> - /// <param name="point">The point.</param> - /// <param name="x">Distance along X-coordinate.</param> - /// <param name="y">Distance along Y-coordinate.</param> - /// <returns>New point.</returns> - public static Point Add(this Point point, double x, double y) - { - return new Point(point.X + x, point.Y + y); - } - - /// <summary> - /// Adds an offset specified by the Size to the specified point. - /// </summary> - /// <param name="point">The point.</param> - /// <param name="size">Distance to add.</param> - /// <returns>New point</returns> - public static Point Add(this Point point, Size size) - { - return new Point(point.X + size.Width, point.Y + size.Height); - } - - /// <summary> - /// Determines whether dimensions are Not a Number (NaN). - /// </summary> - /// <param name="size">The size.</param> - /// <returns> - /// <c>true</c> if dimensions are not specified; otherwise, <c>false</c>. - /// </returns> - public static bool IsNotSet(this Size size) - { - return double.IsNaN(size.Width) || double.IsNaN(size.Height); - } - - /// <summary> - /// Increments size to the specified values. - /// </summary> - /// <param name="size">The size.</param> - /// <param name="x">Increment by X-coordinate.</param> - /// <param name="y">Increment by Y-coordinate.</param> - /// <returns>New size.</returns> - public static Size Add(this Size size, double x, double y) - { - double width = size.Width + x; - double height = size.Height + y; - - return new Size() - { - Width = width < 0 ? 0 : width, - Height = height < 0 ? 0 : height - }; - } - - /// <summary> - /// Increases size if the rectangle to the specified width and height. - /// </summary> - /// <param name="rect">The rectangle.</param> - /// <param name="width">Value to add to the width of the rectangle.</param> - /// <param name="height">Value to add to the height of the rectangle.</param> - /// <returns>New rectangle.</returns> - public static Rect Add(this Rect rect, double width, double height) - { - return new Rect - { - X = rect.X, - Y = rect.Y, - Width = Math.Max(0, rect.Width + width), - Height = Math.Max(0, rect.Height + height) - }; - } - - /// <summary> - /// Shifts the point to the specified distance. - /// </summary> - /// <param name="point">The point.</param> - /// <param name="distance">The distance.</param> - /// <returns>Point shifted to the specified distance.</returns> - public static Point Add(this Point point, Distance distance) - { - return new Point() - { - X = distance.X.IsNotSet() ? point.X : point.X + distance.X, - Y = distance.Y.IsNotSet() ? point.Y : point.Y + distance.Y - }; - } - - /// <summary> - /// Tests whether the rectangle overlaps with another one vertically. - /// </summary> - /// <param name="rect">The rectangle.</param> - /// <param name="testRect">Test rectangle.</param> - /// <param name="accuracy">Accuracy.</param> - /// <returns><c>true</c> if overlaps vertically; otherwise, <c>false</c>.</returns> - public static bool OverlapsVertically(this Rect rect, Rect testRect, double accuracy = 0) - { - double y1 = rect.Y + rect.Height - 1; - double y2 = testRect.Y + testRect.Height - 1; - - if (rect.Y <= testRect.Y) - { - return y1 >= (testRect.Y - accuracy); - } - else if (rect.Y <= (y2 + accuracy)) - { - return true; - } - - return false; - } - - /// <summary> - /// Tests whether the rectangle overlaps with another one horizontally. - /// </summary> - /// <param name="rect">The rectangle.</param> - /// <param name="testRect">Test rectangle.</param> - /// <param name="accuracy">Accuracy.</param> - /// <returns><c>true</c> if overlaps horizontally; otherwise, <c>false</c>.</returns> - public static bool OverlapsHorizontally(this Rect rect, Rect testRect, double accuracy = 0) - { - double x1 = rect.X + rect.Width - 1; - double x2 = testRect.X + testRect.Width - 1; - - if (rect.X <= testRect.X) - { - return x1 >= (testRect.X - accuracy); - } - else if (rect.X <= (x2 + accuracy)) - { - return true; - } - - return false; - } - - /// <summary> - /// Tests whether the point overlaps with the rectangle vertically. - /// </summary> - /// <param name="point">Test point.</param> - /// <param name="rect">Test rectangle.</param> - /// <param name="accuracy">Accuracy.</param> - /// <returns><c>true</c> if overlaps vertically; otherwise, <c>false</c>.</returns> - public static bool OverlapsVertically(this Point point, Rect rect, double accuracy = 0) - { - return (point.Y >= (rect.Y - accuracy) && point.Y <= (rect.Y + rect.Height - 1 + accuracy)); - } - - /// <summary> - /// Tests whether the point overlaps with the rectangle horizontally. - /// </summary> - /// <param name="point">Test point.</param> - /// <param name="rect">Test rectangle.</param> - /// <param name="accuracy">Accuracy.</param> - /// <returns><c>true</c> if overlaps horizontally; otherwise, <c>false</c>.</returns> - public static bool OverlapsHorizontally(this Point point, Rect rect, double accuracy = 0) - { - return (point.X >= (rect.X - accuracy) && point.X <= (rect.X + rect.Width - 1 + accuracy)); - } - } -}
--- a/SilverlightGlimpse/SilverFlow.Controls/Extensions/MathExtensions.cs Mon Apr 23 11:05:11 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,85 +0,0 @@ -using System; - -namespace SilverFlow.Controls.Extensions -{ - /// <summary> - /// Math extensions - /// </summary> - public static class MathExtensions - { - /// <summary> - /// Determines whether the number is NaN. - /// </summary> - /// <param name="number">The number.</param> - /// <returns> - /// <c>true</c> if is NaN; otherwise, <c>false</c>. - /// </returns> - public static bool IsNotSet(this double number) - { - return double.IsNaN(number); - } - - /// <summary> - /// Determines whether the specified number is near the test number. - /// </summary> - /// <param name="number">The number.</param> - /// <param name="testNumber">The test number.</param> - /// <param name="accuracy">Accuracy.</param> - /// <returns> - /// <c>true</c> if the specified number is near the testing one; otherwise, <c>false</c>. - /// </returns> - public static bool IsNear(this double number, double testNumber, double accuracy) - { - return number >= (testNumber - accuracy) && number <= (testNumber + accuracy); - } - - /// <summary> - /// Compares two numbers without their signs and gets absolutely minimal value. - /// </summary> - /// <param name="num1">First number.</param> - /// <param name="num2">Second number.</param> - /// <returns>Absolutely minimal value.</returns> - public static double AbsMin(double num1, double num2) - { - if (num1.IsNotSet() && num2.IsNotSet()) - return double.NaN; - - if (num1.IsNotSet()) return num2; - if (num2.IsNotSet()) return num1; - - double abs1 = Math.Abs(num1); - double abs2 = Math.Abs(num2); - - if (abs1 < abs2) return num1; - if (abs2 < abs1) return num2; - - // Abs. values are equal. Return first number - return num1; - } - - /// <summary> - /// Ensures the given number is in the specified range. - /// </summary> - /// <param name="number">The number.</param> - /// <param name="low">The lower limit.</param> - /// <param name="high">The upper limit.</param> - /// <returns>A number in the specified range.</returns> - public static double EnsureInRange(this double number, double low, double high) - { - if (number.IsNotSet()) return double.NaN; - - double result = Math.Max(number, low); - return Math.Min(result, high); - } - - /// <summary> - /// Returns a double value if it is not a NAN, or zero. - /// </summary> - /// <param name="number">The number.</param> - /// <returns>Double value if it is not a NAN, or zero.</returns> - public static double ValueOrZero(this double number) - { - return double.IsNaN(number) ? 0 : number; - } - } -}
--- a/SilverlightGlimpse/SilverFlow.Controls/FloatingWindow/ActiveWindowChangedEventArgs.cs Mon Apr 23 11:05:11 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -using System; - -namespace SilverFlow.Controls -{ - /// <summary> - /// ActiveWindowChanged event arguments class. - /// </summary> - public class ActiveWindowChangedEventArgs : EventArgs - { - public FloatingWindow Old { get; set; } - public FloatingWindow New { get; set; } - - /// <summary> - /// Initializes a new instance of the <see cref="ActiveWindowChangedEventArgs"/> class. - /// </summary> - public ActiveWindowChangedEventArgs() - { - } - - /// <summary> - /// Initializes a new instance of the <see cref="ActiveWindowChangedEventArgs"/> class. - /// </summary> - /// <param name="oldWindow">The old active FloatingWindow.</param> - /// <param name="newWindow">The new active FloatingWindow.</param> - public ActiveWindowChangedEventArgs(FloatingWindow oldWindow, FloatingWindow newWindow) - { - this.Old = oldWindow; - this.New = newWindow; - } - } -}
--- a/SilverlightGlimpse/SilverFlow.Controls/FloatingWindow/BootstrapButton.cs Mon Apr 23 11:05:11 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,72 +0,0 @@ -using System.Windows; -using System.Windows.Controls; - -namespace SilverFlow.Controls -{ - /// <summary> - /// Two-state button with an up/down arrow. - /// </summary> - [TemplateVisualState(Name = VSMSTATE_StateClose, GroupName = VSMGROUP_ButtonStates)] - [TemplateVisualState(Name = VSMSTATE_StateOpen, GroupName = VSMGROUP_ButtonStates)] - public class BootstrapButton : Button - { - // VSM groups - private const string VSMGROUP_ButtonStates = "ButtonStates"; - - // VSM states - private const string VSMSTATE_StateOpen = "Open"; - private const string VSMSTATE_StateClose = "Close"; - - #region public bool IsOpen - - /// <summary> - /// Gets or sets a value indicating whether the bootstrap button is in the "Open" state. - /// </summary> - /// <value><c>true</c> if the bootstrap button is in the "Open" state; otherwise, <c>false</c>.</value> - public bool IsOpen - { - get { return (bool)GetValue(IsOpenProperty); } - set { SetValue(IsOpenProperty, value); } - } - - /// <summary> - /// Identifies the <see cref="BootstrapButton.IsOpen" /> dependency property. - /// </summary> - /// <value> - /// The identifier for the <see cref="BootstrapButton.IsOpen" /> dependency property. - /// </value> - public static readonly DependencyProperty IsOpenProperty = - DependencyProperty.Register( - "IsOpen", - typeof(bool), - typeof(BootstrapButton), - new PropertyMetadata(false, IsOpenPropertyChanged)); - - /// <summary> - /// IsOpenProperty PropertyChangedCallback call back static function. - /// </summary> - /// <param name="d">BootstrapButton object whose IsOpenProperty property is changed.</param> - /// <param name="e">DependencyPropertyChangedEventArgs which contains the old and new values.</param> - private static void IsOpenPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - BootstrapButton button = (BootstrapButton)d; - VisualStateManager.GoToState( - button, - (bool)e.NewValue ? VSMSTATE_StateClose : VSMSTATE_StateOpen, - true); - } - - #endregion - - /// <summary> - /// Raises the <see cref="E:System.Windows.Controls.Primitives.ButtonBase.Click"/> event. - /// </summary> - protected override void OnClick() - { - // Toggle open/closed state - IsOpen = !IsOpen; - - base.OnClick(); - } - } -}
--- a/SilverlightGlimpse/SilverFlow.Controls/FloatingWindow/FloatingWindow.cs Mon Apr 23 11:05:11 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2210 +0,0 @@ -using System; -using System.Collections.ObjectModel; -using System.ComponentModel; -using System.Linq; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Controls.Primitives; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Animation; -using SilverFlow.Controls.Controllers; -using SilverFlow.Controls.Enums; -using SilverFlow.Controls.Extensions; -using SilverFlow.Controls.Helpers; - -namespace SilverFlow.Controls -{ - /// <summary> - /// Provides a window that can be displayed over a parent window not blocking - /// interaction with the parent window. - /// </summary> - [TemplatePart(Name = PART_Chrome, Type = typeof(FrameworkElement))] - [TemplatePart(Name = PART_TitleContent, Type = typeof(ContentControl))] - [TemplatePart(Name = PART_CloseButton, Type = typeof(ButtonBase))] - [TemplatePart(Name = PART_ContentPresenter, Type = typeof(FrameworkElement))] - [TemplatePart(Name = PART_ContentRoot, Type = typeof(FrameworkElement))] - [TemplatePart(Name = PART_ContentBorder, Type = typeof(FrameworkElement))] - [TemplatePart(Name = PART_Root, Type = typeof(FrameworkElement))] - [TemplateVisualState(Name = VSMSTATE_StateClosed, GroupName = VSMGROUP_Window)] - [TemplateVisualState(Name = VSMSTATE_StateOpen, GroupName = VSMGROUP_Window)] - [TemplateVisualState(Name = VSMSTATE_StateMinimized, GroupName = VSMGROUP_Window)] - [TemplateVisualState(Name = VSMSTATE_StateRestored, GroupName = VSMGROUP_Window)] - [TemplateVisualState(Name = VSMSTATE_StateNormal, GroupName = VSMGROUP_Button)] - [StyleTypedProperty(Property = PROPERTY_TitleStyle, StyleTargetType = typeof(ContentControl))] - [StyleTypedProperty(Property = PROPERTY_CloseButtonStyle, StyleTargetType = typeof(Button))] - [StyleTypedProperty(Property = PROPERTY_MinimizeButtonStyle, StyleTargetType = typeof(Button))] - [StyleTypedProperty(Property = PROPERTY_MaximizeButtonStyle, StyleTargetType = typeof(Button))] - [StyleTypedProperty(Property = PROPERTY_RestoreButtonStyle, StyleTargetType = typeof(Button))] - public class FloatingWindow : ContentControl, IResizableElement, IDisposable - { - #region Constants - - // Template parts - private const string PART_Chrome = "Chrome"; - private const string PART_TitleContent = "TitleContent"; - private const string PART_CloseButton = "CloseButton"; - private const string PART_MaximizeButton = "MaximizeButton"; - private const string PART_RestoreButton = "RestoreButton"; - private const string PART_MinimizeButton = "MinimizeButton"; - private const string PART_ContentPresenter = "ContentPresenter"; - private const string PART_ContentRoot = "ContentRoot"; - private const string PART_ContentBorder = "ContentBorder"; - private const string PART_Root = "Root"; - - // VSM groups - private const string VSMGROUP_Window = "WindowStates"; - private const string VSMGROUP_Button = "CommonStates"; - - // VSM states - private const string VSMSTATE_StateNormal = "Normal"; - private const string VSMSTATE_StateClosed = "Closed"; - private const string VSMSTATE_StateOpen = "Open"; - private const string VSMSTATE_StateMinimized = "Minimized"; - private const string VSMSTATE_StateRestored = "Restored"; - - // Style typed properties - private const string PROPERTY_TitleStyle = "TitleStyle"; - private const string PROPERTY_CloseButtonStyle = "CloseButtonStyle"; - private const string PROPERTY_MinimizeButtonStyle = "MinimizeButtonStyle"; - private const string PROPERTY_MaximizeButtonStyle = "MaximizeButtonStyle"; - private const string PROPERTY_RestoreButtonStyle = "RestoreButtonStyle"; - - // Thickness of resizing area - private const double ResizingAreaDefaultValue = 6; - - // Animation duration in milliseconds - private const double MaximizingDurationInMilliseconds = 20; - private const double MinimizingDurationInMilliseconds = 200; - private const double RestoringDurationInMilliseconds = 20; - - #endregion - - #region public bool ShowCloseButton - - /// <summary> - /// Gets or sets a value indicating whether to show Close button. - /// </summary> - /// <value><c>true</c> if to show Close button; otherwise, <c>false</c>.</value> - public bool ShowCloseButton - { - get { return (bool)GetValue(ShowCloseButtonProperty); } - set { SetValue(ShowCloseButtonProperty, value); } - } - - /// <summary> - /// Identifies the <see cref="FloatingWindow.ShowCloseButton" /> dependency property. - /// </summary> - /// <value> - /// The identifier for the <see cref="FloatingWindow.ShowCloseButton" /> dependency property. - /// </value> - public static readonly DependencyProperty ShowCloseButtonProperty = - DependencyProperty.Register( - "ShowCloseButton", - typeof(bool), - typeof(FloatingWindow), - new PropertyMetadata(true, OnShowCloseButtonPropertyChanged)); - - /// <summary> - /// ShowCloseButtonProperty PropertyChangedCallback call back static function. - /// </summary> - /// <param name="d">FloatingWindow object whose ShowCloseButton property is changed.</param> - /// <param name="e">DependencyPropertyChangedEventArgs which contains the old and new values.</param> - private static void OnShowCloseButtonPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - FloatingWindow window = (FloatingWindow)d; - - if (window.closeButton != null) - window.closeButton.SetVisible((bool)e.NewValue); - } - - #endregion - - #region public bool ShowMaximizeButton - - /// <summary> - /// Gets or sets a value indicating whether to show Maximize button. - /// </summary> - /// <value><c>true</c> if to show Maximize button; otherwise, <c>false</c>.</value> - public bool ShowMaximizeButton - { - get { return (bool)GetValue(ShowMaximizeButtonProperty); } - set { SetValue(ShowMaximizeButtonProperty, value); } - } - - /// <summary> - /// Identifies the <see cref="FloatingWindow.ShowMaximizeButton" /> dependency property. - /// </summary> - /// <value> - /// The identifier for the <see cref="FloatingWindow.ShowMaximizeButton" /> dependency property. - /// </value> - public static readonly DependencyProperty ShowMaximizeButtonProperty = - DependencyProperty.Register( - "ShowMaximizeButton", - typeof(bool), - typeof(FloatingWindow), - new PropertyMetadata(true, ShowMaximizeButtonPropertyChanged)); - - /// <summary> - /// ShowMaximizeButtonProperty PropertyChangedCallback call back static function. - /// </summary> - /// <param name="d">FloatingWindow object whose ShowMaximizeButton property is changed.</param> - /// <param name="e">DependencyPropertyChangedEventArgs which contains the old and new values.</param> - private static void ShowMaximizeButtonPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - FloatingWindow window = (FloatingWindow)d; - bool visible = window.IsModal ? false : (bool)e.NewValue; - - if (window.maximizeButton != null) - window.maximizeButton.SetVisible(visible); - } - - #endregion - - #region public bool ShowMinimizeButton - - /// <summary> - /// Gets or sets a value indicating whether to show Minimize button. - /// </summary> - /// <value><c>true</c> if to show Minimize button; otherwise, <c>false</c>.</value> - public bool ShowMinimizeButton - { - get { return (bool)GetValue(ShowMinimizeButtonProperty); } - set { SetValue(ShowMinimizeButtonProperty, value); } - } - - /// <summary> - /// Identifies the <see cref="FloatingWindow.ShowMinimizeButton" /> dependency property. - /// </summary> - /// <value> - /// The identifier for the <see cref="FloatingWindow.ShowMinimizeButton" /> dependency property. - /// </value> - public static readonly DependencyProperty ShowMinimizeButtonProperty = - DependencyProperty.Register( - "ShowMinimizeButton", - typeof(bool), - typeof(FloatingWindow), - new PropertyMetadata(true, ShowMinimizeButtonPropertyChanged)); - - /// <summary> - /// ShowMinimizeButtonProperty PropertyChangedCallback call back static function. - /// </summary> - /// <param name="d">FloatingWindow object whose ShowMinimizeButton property is changed.</param> - /// <param name="e">DependencyPropertyChangedEventArgs which contains the old and new values.</param> - private static void ShowMinimizeButtonPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - FloatingWindow window = (FloatingWindow)d; - bool visible = window.IsModal ? false : (bool)e.NewValue; - - if (window.minimizeButton != null) - window.minimizeButton.SetVisible(visible); - } - - #endregion - - #region public bool ShowRestoreButton - - /// <summary> - /// Gets or sets a value indicating whether to show Restore button. - /// </summary> - /// <value><c>true</c> if to show Restore button; otherwise, <c>false</c>.</value> - public bool ShowRestoreButton - { - get { return (bool)GetValue(ShowRestoreButtonProperty); } - set { SetValue(ShowRestoreButtonProperty, value); } - } - - /// <summary> - /// Identifies the <see cref="FloatingWindow.ShowRestoreButton" /> dependency property. - /// </summary> - /// <value> - /// The identifier for the <see cref="FloatingWindow.ShowRestoreButton" /> dependency property. - /// </value> - public static readonly DependencyProperty ShowRestoreButtonProperty = - DependencyProperty.Register( - "ShowRestoreButton", - typeof(bool), - typeof(FloatingWindow), - new PropertyMetadata(true, ShowRestoreButtonPropertyChanged)); - - /// <summary> - /// ShowRestoreButtonProperty PropertyChangedCallback call back static function. - /// </summary> - /// <param name="d">FloatingWindow object whose ShowRestoreButton property is changed.</param> - /// <param name="e">DependencyPropertyChangedEventArgs which contains the old and new values.</param> - private static void ShowRestoreButtonPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - FloatingWindow window = (FloatingWindow)d; - bool visible = window.IsModal ? false : (bool)e.NewValue; - - if (window.restoreButton != null) - window.restoreButton.SetVisible(visible); - } - - #endregion - - #region public object Title - - /// <summary> - /// Gets or sets title content that is displayed on the top of the window. - /// Can contain any UI elements - not only a text. - /// </summary> - /// <value> - /// The title displayed at the top of the window. The default is null. - /// </value> - public object Title - { - get { return GetValue(TitleProperty); } - set { SetValue(TitleProperty, value); } - } - - /// <summary> - /// Identifies the <see cref="FloatingWindow.Title" /> dependency property. - /// </summary> - /// <value> - /// The identifier for the <see cref="FloatingWindow.Title" /> dependency property. - /// </value> - public static readonly DependencyProperty TitleProperty = - DependencyProperty.Register( - "Title", - typeof(object), - typeof(FloatingWindow), - null); - - #endregion - - #region public object Icon - - /// <summary> - /// Gets or sets content that is displayed as an icon of the window on the iconbar. - /// </summary> - /// <value> - /// The content displayed as an icon of the window on the iconbar. The default is null. - /// </value> - public object Icon - { - get { return GetValue(IconProperty); } - set { SetValue(IconProperty, value); } - } - - /// <summary> - /// Identifies the <see cref="FloatingWindow.Icon" /> dependency property. - /// </summary> - /// <value> - /// The identifier for the <see cref="FloatingWindow.Icon" /> dependency property. - /// </value> - public static readonly DependencyProperty IconProperty = - DependencyProperty.Register( - "Icon", - typeof(object), - typeof(FloatingWindow), - null); - - #endregion - - #region public string IconText - - /// <summary> - /// Gets or sets a text displayed on the icon of the minimized window. - /// </summary> - /// <value> - /// The text displayed on the icon. - /// </value> - public string IconText - { - get { return (string)GetValue(IconTextProperty); } - set { SetValue(IconTextProperty, value); } - } - - /// <summary> - /// Identifies the <see cref="FloatingWindow.IconText" /> dependency property. - /// </summary> - /// <value> - /// The identifier for the <see cref="FloatingWindow.IconText" /> dependency property. - /// </value> - public static readonly DependencyProperty IconTextProperty = - DependencyProperty.Register( - "IconText", - typeof(string), - typeof(FloatingWindow), - null); - - #endregion - - #region public Brush TitleBackground - - /// <summary> - /// Gets or sets the title background. - /// </summary> - /// <value>The title background.</value> - public Brush TitleBackground - { - get { return (Brush)GetValue(TitleBackgroundProperty); } - set { SetValue(TitleBackgroundProperty, value); } - } - - /// <summary> - /// Identifies the <see cref="FloatingWindow.TitleBackground" /> dependency property. - /// </summary> - /// <value> - /// The identifier for the <see cref="FloatingWindow.TitleBackground" /> dependency property. - /// </value> - public static readonly DependencyProperty TitleBackgroundProperty = - DependencyProperty.Register( - "TitleBackground", - typeof(Brush), - typeof(FloatingWindow), - new PropertyMetadata(new SolidColorBrush(Colors.Transparent), null)); - - #endregion - - #region public bool ResizeEnabled - - /// <summary> - /// Gets or sets a value indicating whether resizing is enabled. - /// </summary> - /// <value><c>true</c> if resizing is enabled; otherwise, <c>false</c>.</value> - public bool ResizeEnabled - { - get { return (bool)GetValue(ResizeEnabledProperty); } - set { SetValue(ResizeEnabledProperty, value); } - } - - /// <summary> - /// Identifies the <see cref="FloatingWindow.ResizeEnabled" /> dependency property. - /// </summary> - /// <value> - /// The identifier for the <see cref="FloatingWindow.ResizeEnabled" /> dependency property. - /// </value> - public static readonly DependencyProperty ResizeEnabledProperty = - DependencyProperty.Register( - "ResizeEnabled", - typeof(bool), - typeof(FloatingWindow), - new PropertyMetadata(true, null)); - - #endregion - - #region public double ResizingAreaThickness - - /// <summary> - /// Gets or sets the width of the resizing area. - /// </summary> - /// <value>The width of the resizing area.</value> - public double ResizingAreaThickness - { - get { return (double)GetValue(ResizingAreaThicknessProperty); } - set { SetValue(ResizingAreaThicknessProperty, value); } - } - - /// <summary> - /// Identifies the <see cref="FloatingWindow.ResizingAreaThickness" /> dependency property. - /// </summary> - /// <value> - /// The identifier for the <see cref="FloatingWindow.ResizingAreaThickness" /> dependency property. - /// </value> - public static readonly DependencyProperty ResizingAreaThicknessProperty = - DependencyProperty.Register( - "ResizingAreaThickness", - typeof(double), - typeof(FloatingWindow), - new PropertyMetadata(ResizingAreaDefaultValue, OnResizingAreaThicknessPropertyChanged)); - - /// <summary> - /// ResizingAreaThicknessProperty PropertyChangedCallback call back static function. - /// </summary> - /// <param name="d">FloatingWindow object whose ResizingAreaThickness property is changed.</param> - /// <param name="e">DependencyPropertyChangedEventArgs which contains the old and new values.</param> - private static void OnResizingAreaThicknessPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - FloatingWindow window = (FloatingWindow)d; - window.resizeController.ResizingArea = (double)e.NewValue; - } - - #endregion - - #region public Point Position - - /// <summary> - /// Gets or sets current window position. - /// </summary> - /// <value>Current position.</value> - public Point Position - { - get { return (Point)GetValue(PositionProperty); } - set { SetValue(PositionProperty, value); } - } - - /// <summary> - /// Identifies the <see cref="FloatingWindow.Position" /> dependency property. - /// </summary> - /// <value> - /// The identifier for the <see cref="FloatingWindow.Position" /> dependency property. - /// </value> - public static readonly DependencyProperty PositionProperty = - DependencyProperty.Register( - "Position", - typeof(Point), - typeof(FloatingWindow), - new PropertyMetadata(new Point(double.NaN, double.NaN), OnPositionPropertyChanged)); - - /// <summary> - /// PositionProperty PropertyChangedCallback call back static function. - /// </summary> - /// <param name="d">FloatingWindow object whose Position property is changed.</param> - /// <param name="e">DependencyPropertyChangedEventArgs which contains the old and new values.</param> - private static void OnPositionPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - FloatingWindow window = (FloatingWindow)d; - - if (window != null) - { - if (window.FloatingWindowHost.IsLayoutUpdated) - window.MoveWindow((Point)e.NewValue); - } - } - - #endregion - - #region public bool ShowInIconbar - - /// <summary> - /// Gets or sets a value indicating whether to show minimized window in the iconbar. - /// </summary> - /// <value><c>true</c> if to show minimized window in the iconbar; otherwise, <c>false</c>.</value> - public bool ShowInIconbar - { - get { return (bool)GetValue(ShowInIconbarProperty); } - set { SetValue(ShowInIconbarProperty, value); } - } - - /// <summary> - /// Identifies the <see cref="FloatingWindow.ShowInIconbar" /> dependency property. - /// </summary> - /// <value> - /// The identifier for the <see cref="FloatingWindow.ShowInIconbar" /> dependency property. - /// </value> - public static readonly DependencyProperty ShowInIconbarProperty = - DependencyProperty.Register( - "ShowInIconbar", - typeof(bool), - typeof(FloatingWindow), - new PropertyMetadata(true, null)); - - #endregion - - #region public FlowDirection FlowDirection - - /// <summary> - /// Gets or sets the direction that title text flows within window's icon. - /// </summary> - /// <value>A constant name from the FlowDirection enumeration, either LeftToRight or RightToLeft.</value> - public FlowDirection FlowDirection - { - get { return (FlowDirection)GetValue(FlowDirectionProperty); } - set { SetValue(FlowDirectionProperty, value); } - } - - /// <summary> - /// Identifies the <see cref="FloatingWindow.FlowDirection" /> dependency property. - /// </summary> - /// <value> - /// The identifier for the <see cref="FloatingWindow.FlowDirection" /> dependency property. - /// </value> - public static readonly DependencyProperty FlowDirectionProperty = - DependencyProperty.Register( - "FlowDirection", - typeof(FlowDirection), - typeof(FloatingWindow), - new PropertyMetadata(FlowDirection.LeftToRight, null)); - - #endregion - - #region public Style TitleStyle - - /// <summary> - /// Gets or sets the style that is used when rendering the Title of the window. - /// </summary> - public Style TitleStyle - { - get { return GetValue(TitleStyleProperty) as Style; } - set { SetValue(TitleStyleProperty, value); } - } - - /// <summary> - /// Identifies the <see cref="FloatingWindow.TitleStyleProperty" /> dependency property. - /// </summary> - public static readonly DependencyProperty TitleStyleProperty = - DependencyProperty.Register( - "TitleStyle", - typeof(Style), - typeof(FloatingWindow), - new PropertyMetadata(OnTitleStylePropertyChanged)); - - /// <summary> - /// TitleStyle PropertyChangedCallback call back static function. - /// </summary> - /// <param name="d">FloatingWindow object whose TitleStyle property is changed.</param> - /// <param name="e">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param> - private static void OnTitleStylePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - FloatingWindow window = (FloatingWindow)d; - if (window != null && window.titleContent != null) - { - Style style = e.NewValue as Style; - window.titleContent.Style = style; - } - } - - #endregion - - #region public Style CloseButtonStyle - - /// <summary> - /// Gets or sets the style of the Close button. - /// </summary> - public Style CloseButtonStyle - { - get { return GetValue(CloseButtonStyleProperty) as Style; } - set { SetValue(CloseButtonStyleProperty, value); } - } - - /// <summary> - /// Identifies the <see cref="FloatingWindow.CloseButtonStyleProperty" /> dependency property. - /// </summary> - public static readonly DependencyProperty CloseButtonStyleProperty = - DependencyProperty.Register( - "CloseButtonStyle", - typeof(Style), - typeof(FloatingWindow), - new PropertyMetadata(OnCloseButtonStylePropertyChanged)); - - /// <summary> - /// CloseButtonStyle PropertyChangedCallback call back static function. - /// </summary> - /// <param name="d">FloatingWindow object whose CloseButtonStyle property is changed.</param> - /// <param name="e">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param> - private static void OnCloseButtonStylePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - var window = (FloatingWindow)d; - if (window != null) - { - Style style = e.NewValue as Style; - window.CloseButtonStyle = style; - - if (window.closeButton != null) - window.closeButton.Style = style; - } - } - - #endregion - - #region public Style MinimizeButtonStyle - - /// <summary> - /// Gets or sets the style of the Minimize button. - /// </summary> - public Style MinimizeButtonStyle - { - get { return GetValue(MinimizeButtonStyleProperty) as Style; } - set { SetValue(MinimizeButtonStyleProperty, value); } - } - - /// <summary> - /// Identifies the <see cref="FloatingWindow.MinimizeButtonStyleProperty" /> dependency property. - /// </summary> - public static readonly DependencyProperty MinimizeButtonStyleProperty = - DependencyProperty.Register( - "MinimizeButtonStyle", - typeof(Style), - typeof(FloatingWindow), - new PropertyMetadata(OnMinimizeButtonStylePropertyChanged)); - - /// <summary> - /// CloseButtonStyle PropertyChangedCallback call back static function. - /// </summary> - /// <param name="d">FloatingWindow object whose MinimizeButtonStyle property is changed.</param> - /// <param name="e">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param> - private static void OnMinimizeButtonStylePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - var window = (FloatingWindow)d; - if (window != null) - { - Style style = e.NewValue as Style; - window.CloseButtonStyle = style; - - if (window.minimizeButton != null) - window.minimizeButton.Style = style; - } - } - - #endregion - - #region public Style MaximizeButtonStyle - - /// <summary> - /// Gets or sets the style of the Maximize button. - /// </summary> - public Style MaximizeButtonStyle - { - get { return GetValue(MaximizeButtonStyleProperty) as Style; } - set { SetValue(MaximizeButtonStyleProperty, value); } - } - - /// <summary> - /// Identifies the <see cref="FloatingWindow.MaximizeButtonStyleProperty" /> dependency property. - /// </summary> - public static readonly DependencyProperty MaximizeButtonStyleProperty = - DependencyProperty.Register( - "MaximizeButtonStyle", - typeof(Style), - typeof(FloatingWindow), - new PropertyMetadata(OnMaximizeButtonStylePropertyChanged)); - - /// <summary> - /// MaximizeButtonStyle PropertyChangedCallback call back static function. - /// </summary> - /// <param name="d">FloatingWindow object whose MaximizeButtonStyle property is changed.</param> - /// <param name="e">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param> - private static void OnMaximizeButtonStylePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - var window = (FloatingWindow)d; - if (window != null) - { - Style style = e.NewValue as Style; - window.CloseButtonStyle = style; - - if (window.maximizeButton != null) - window.maximizeButton.Style = style; - } - } - - #endregion - - #region public Style RestoreButtonStyle - - /// <summary> - /// Gets or sets the style of the Restore button. - /// </summary> - public Style RestoreButtonStyle - { - get { return GetValue(RestoreButtonStyleProperty) as Style; } - set { SetValue(RestoreButtonStyleProperty, value); } - } - - /// <summary> - /// Identifies the <see cref="FloatingWindow.RestoreButtonStyleProperty" /> dependency property. - /// </summary> - public static readonly DependencyProperty RestoreButtonStyleProperty = - DependencyProperty.Register( - "RestoreButtonStyle", - typeof(Style), - typeof(FloatingWindow), - new PropertyMetadata(OnRestoreButtonStylePropertyChanged)); - - /// <summary> - /// RestoreButtonStyle PropertyChangedCallback call back static function. - /// </summary> - /// <param name="d">FloatingWindow object whose RestoreButtonStyle property is changed.</param> - /// <param name="e">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param> - private static void OnRestoreButtonStylePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - var window = (FloatingWindow)d; - if (window != null) - { - Style style = e.NewValue as Style; - window.CloseButtonStyle = style; - - if (window.restoreButton != null) - window.restoreButton.Style = style; - } - } - - #endregion - - #region public bool? DialogResult - - /// <summary> - /// Gets or sets a value that indicates whether the FloatingWindow was accepted or canceled. - /// </summary> - /// <value>true if the FloatingWindow was accepted; false - if canceled. The default is null.</value> - [TypeConverter(typeof(NullableBoolConverter))] - public bool? DialogResult { get; set; } - - #endregion - - #region Member Fields - - // Mouse click point - private Point clickPoint; - - // Window position when the mouse was clicked - private Point clickWindowPosition; - - // Window position, size and state when it was maximized or minimized - private Point previousPosition; - private Size previousSize; - private WindowState previousWindowState; - - private Thickness contentBorderThickness; - private CornerRadius contentBorderCornerRadius; - private CornerRadius chromeBorderCornerRadius; - - private Storyboard openingStoryboard; - private Storyboard closingStoryboard; - private Storyboard inertialMotionStoryboard; - - private FrameworkElement root; - private FrameworkElement contentPresenter; - private FrameworkElement contentRoot; - private FrameworkElement chrome; - private ContentControl titleContent; - private Border contentBorder; - - private ButtonBase closeButton; - private ButtonBase maximizeButton; - private ButtonBase restoreButton; - private ButtonBase minimizeButton; - - private bool isAppExit; - private bool isMouseCaptured; - - private ResizeController resizeController; - private ISnapinController snapinController; - private InertiaController inertiaController; - private ILocalStorage localStorage; - private IBitmapHelper bitmapHelper; - - // Current window state - private WindowState windowState = WindowState.Normal; - - // Specifies whether the window is moving or resizing - private WindowAction windowAction; - - // Bitmap containing thumbnail image - private ImageSource minimizedWindowThumbnail; - - #endregion Member Fields - - /// <summary> - /// Initializes a new instance of the <see cref="FloatingWindow" /> class. - /// </summary> - public FloatingWindow() - { - DefaultStyleKey = typeof(FloatingWindow); - - resizeController = new ResizeController(this); - resizeController.ResizingArea = ResizingAreaThickness; - snapinController = new SnapinController(); - inertiaController = new InertiaController(); - localStorage = new LocalStorage(); - bitmapHelper = new BitmapHelper(); - - this.SetVisible(false); - } - - #region Events - - /// <summary> - /// Occurs when the <see cref="FloatingWindow" /> is activated. - /// </summary> - /// <remarks>Not visible <see cref="FloatingWindow" /> cannot be the active. </remarks> - public event EventHandler Activated; - - /// <summary> - /// Occurs when the <see cref="FloatingWindow" /> is deactivated. - /// </summary> - public event EventHandler Deactivated; - - /// <summary> - /// Occurs when the <see cref="FloatingWindow" /> is closed. - /// </summary> - public event EventHandler Closed; - - /// <summary> - /// Occurs when the <see cref="FloatingWindow" /> is maximized. - /// </summary> - public event EventHandler Maximized; - - /// <summary> - /// Occurs when the <see cref="FloatingWindow" /> is minimized. - /// </summary> - public event EventHandler Minimized; - - /// <summary> - /// Occurs when the <see cref="FloatingWindow" /> is restored. - /// </summary> - public event EventHandler Restored; - - /// <summary> - /// Occurs when the <see cref="FloatingWindow" /> is closing. - /// </summary> - public event EventHandler<CancelEventArgs> Closing; - - #endregion Events - - #region Properties - - /// <summary> - /// Gets or sets a reference to the FloatingWindowHost, containing the window. - /// </summary> - /// <value>The floating window host.</value> - public FloatingWindowHost FloatingWindowHost { get; set; } - - /// <summary> - /// Gets or sets a value indicating whether the window is always displayed in front of other windows. - /// </summary> - /// <value><c>true</c> if top most; otherwise, <c>false</c>.</value> - public bool TopMost { get; set; } - - /// <summary> - /// Gets or sets a value indicating whether this window is open. - /// </summary> - /// <value><c>true</c> if this window is open; otherwise, <c>false</c>.</value> - public bool IsOpen { get; private set; } - - /// <summary> - /// Gets or sets a value indicating whether this window is modal. - /// </summary> - /// <value><c>true</c> if this window is modal; otherwise, <c>false</c>.</value> - public bool IsModal { get; private set; } - - /// <summary> - /// Gets the window thumbnail. - /// </summary> - /// <value>The window thumbnail.</value> - public ImageSource WindowThumbnail - { - get - { - return (windowState == WindowState.Minimized) ? minimizedWindowThumbnail : GetThumbnailImage(); - } - } - - /// <summary> - /// Gets the state of the window. - /// </summary> - /// <value>Current state of the window.</value> - public WindowState WindowState - { - get { return windowState; } - } - - /// <summary> - /// Gets or sets the minimum height constraint of a <see cref="T:System.Windows.FrameworkElement"/>. - /// </summary> - /// <value>he minimum height of the window.</value> - /// <returns>The minimum height of the window, in pixels. The default is 0. - /// This value can be any value equal to or greater than 0. - /// However, <see cref="F:System.Double.PositiveInfinity"/> is not valid.</returns> - public new double MinHeight - { - get - { - double minHeight = base.MinHeight; - - if ((base.MinHeight.IsNotSet() || base.MinHeight == 0) && - (chrome != null && contentRoot != null)) - { - // Set minimal height to the height of the chrome element of the window - minHeight = chrome.GetRelativePosition(contentRoot).Y + chrome.ActualHeight; - } - - return minHeight; - } - - set - { - base.MinHeight = value; - } - } - - /// <summary> - /// Gets a bounding rectangle of the window. - /// </summary> - /// <value>Bounding rectangle.</value> - public Rect BoundingRectangle - { - get { return new Rect(Position.X, Position.Y, ActualWidth, ActualHeight); } - } - - /// <summary> - /// Gets a Snapin controller. - /// </summary> - /// <value>Snapin controller.</value> - public ISnapinController SnapinController - { - get { return snapinController; } - } - - /// <summary> - /// Gets the host panel, containing the floating windows. - /// </summary> - /// <value>The host panel.</value> - public Panel HostPanel - { - get { return this.FloatingWindowHost == null ? null : this.FloatingWindowHost.HostPanel; } - } - - /// <summary> - /// Gets a value indicating whether window size is explicitly set. - /// </summary> - /// <value><c>true</c> if window size is set; otherwise, <c>false</c>.</value> - private bool IsWindowSizeSet - { - get { return !Width.IsNotSet() && !Height.IsNotSet(); } - } - - /// <summary> - /// Gets a value indicating whether the window Tag property is set. - /// </summary> - /// <value><c>true</c> if the Tag set; otherwise, <c>false</c>.</value> - private bool IsWindowTagSet - { - get - { - string tag = this.Tag as string; - return !string.IsNullOrWhiteSpace(tag); - } - } - - /// <summary> - /// Gets coordinates of the window placed in the center of its host. - /// </summary> - /// <value>The centered window position.</value> - private Point CenteredWindowPosition - { - get - { - return new Point((HostPanel.ActualWidth - Width.ValueOrZero()) / 2, (HostPanel.ActualHeight - Height.ValueOrZero()) / 2); - } - } - - #endregion Properties - - /// <summary> - /// Shows the window as a modal one. - /// </summary> - public void ShowModal() - { - IsModal = true; - Position = new Point(double.NaN, double.NaN); - ShowMaximizeButton = false; - ShowMinimizeButton = false; - - Show(); - } - - /// <summary> - /// Opens the <see cref="FloatingWindow" /> in previously saved position or - /// in the center of the <see cref="FloatingWindowHost" />. - /// </summary> - public void Show() - { - Show(Position); - } - - /// <summary> - /// Shows the window in the specified coordinates, relative to the window's Host. - /// </summary> - /// <param name="x">X-coordinate.</param> - /// <param name="y">Y-coordinate.</param> - public void Show(double x, double y) - { - Show(new Point(x, y)); - } - - /// <summary> - /// Shows a <see cref="FloatingWindow"/> at maximal size taking into account - /// specified margins and current <see cref="FloatingWindowHost"/> size. - /// </summary> - /// <param name="margins">Window margins.</param> - public void Show(Thickness margins) - { - CheckHost(); - Action<Thickness> action = new Action<Thickness>(ShowWindow); - this.FloatingWindowHost.ShowWindow(action, margins); - } - - /// <summary> - /// Shows the window in the specified coordinates, relative to the window's Host. - /// </summary> - /// <param name="point">Coordinates of the upper-left corner of the window.</param> - public void Show(Point point) - { - CheckHost(); - Action<Point> action = new Action<Point>(ShowWindow); - this.FloatingWindowHost.ShowWindow(action, point); - } - - /// <summary> - /// Shows a <see cref="FloatingWindow"/> at maximal size taking into account - /// specified margins and current <see cref="FloatingWindowHost"/> size. - /// </summary> - /// <param name="margins">Window margins.</param> - private void ShowWindow(Thickness margins) - { - Width = Math.Max(MinWidth, HostPanel.ActualWidth - margins.Horizontal()); - Height = Math.Max(MinHeight, HostPanel.ActualHeight - margins.Vertical()); - - ShowWindow(new Point(margins.Left, margins.Top)); - } - - /// <summary> - /// Shows the window in the specified coordinates, relative to the window's Host. - /// </summary> - /// <param name="point">Coordinates of the upper-left corner of the window.</param> - /// <exception cref="System.InvalidOperationException">"The FloatingWindow was not added to the host.</exception> - private void ShowWindow(Point point) - { - if (!IsOpen) - { - if (IsModal) - this.FloatingWindowHost.ShowWindowAsModal(this); - - SubscribeToEvents(); - SubscribeToTemplatePartEvents(); - SubscribeToStoryBoardEvents(); - - // Guarantee that the visual tree of an element is complete - ApplyTemplate(); - - // Brings current window to the front - SetTopmost(); - - Point position = point; - - if (point.IsNotSet()) - position = CenteredWindowPosition; - - MoveWindow(position); - this.SetVisible(true); - - if (!IsWindowSizeSet && point.IsNotSet()) - { - // If window size is not set explicitly we should wait - // when the window layout is updated and update its position - contentRoot.SizeChanged += new SizeChangedEventHandler(ContentRoot_SizeChanged); - } - - VisualStateManager.GoToState(this, VSMSTATE_StateOpen, true); - IsOpen = true; - } - else - { - MoveWindow(point); - this.SetVisible(true); - } - } - - /// <summary> - /// Handles the SizeChanged event of the ContentRoot control to update window position - /// only once when the window is opened. - /// </summary> - /// <param name="sender">The source of the event.</param> - /// <param name="e">The <see cref="System.Windows.SizeChangedEventArgs"/> instance containing the event data.</param> - private void ContentRoot_SizeChanged(object sender, SizeChangedEventArgs e) - { - contentRoot.SizeChanged -= new SizeChangedEventHandler(ContentRoot_SizeChanged); - double dx = -(e.NewSize.Width.ValueOrZero() - e.PreviousSize.Width.ValueOrZero()) / 2; - double dy = -(e.NewSize.Height.ValueOrZero() - e.PreviousSize.Height.ValueOrZero()) / 2; - Point point = Position.Add(dx, dy); - MoveWindow(point); - } - - /// <summary> - /// Restores window state, size and its position. - /// </summary> - public void RestoreWindow() - { - switch (windowState) - { - case WindowState.Minimized: - if (previousWindowState == WindowState.Maximized) - { - Width = HostPanel.ActualWidth; - Height = HostPanel.ActualHeight; - } - - SetTopmost(); - windowState = previousWindowState; - VisualStateManager.GoToState(this, VSMSTATE_StateRestored, true); - OnRestored(EventArgs.Empty); - break; - - case WindowState.Normal: - SetTopmost(); - EnsureVisible(); - break; - - case WindowState.Maximized: - SetTopmost(); - break; - } - - Focus(); - } - - /// <summary> - /// Makes the window topmost and tries to set focus on it. - /// </summary> - public void Activate() - { - SetTopmost(); - } - - /// <summary> - /// Brings current window to the front. - /// </summary> - private void SetTopmost() - { - if (this.FloatingWindowHost != null) - this.FloatingWindowHost.SetTopmostWindow(this); - } - - /// <summary> - /// Ensures the window is visible. - /// </summary> - private void EnsureVisible() - { - if (HostPanel != null && (Position.X >= HostPanel.ActualWidth || Position.Y >= HostPanel.ActualHeight)) - { - Position = CenteredWindowPosition; - } - } - - /// <summary> - /// Executed when the application is exited. - /// </summary> - /// <param name="sender">The sender.</param> - /// <param name="e">Event args.</param> - private void Application_Exit(object sender, EventArgs e) - { - if (IsOpen) - { - isAppExit = true; - try - { - Close(); - } - finally - { - isAppExit = false; - } - } - } - - /// <summary> - /// Closes a <see cref="FloatingWindow" />. - /// </summary> - public void Close() - { - SaveSizeAndPosition(); - - CancelEventArgs e = new CancelEventArgs(); - OnClosing(e); - - // On ApplicationExit, Close() cannot be cancelled - if (IsOpen && (!e.Cancel || isAppExit)) - { - IsOpen = false; - - if (IsModal) - this.FloatingWindowHost.RemoveOverlay(); - - if (closingStoryboard != null) - { - VisualStateManager.GoToState(this, VSMSTATE_StateClosed, true); - } - else - { - this.Visibility = Visibility.Collapsed; - OnClosed(EventArgs.Empty); - } - - UnSubscribeFromEvents(); - UnsubscribeFromTemplatePartEvents(); - } - } - - /// <summary> - /// Restores the size and position stored in the IsolatedStorage on closing. - /// </summary> - public void RestoreSizeAndPosition() - { - if (IsWindowTagSet) - { - string positionKey = GetAppSettingsKey("Position"); - string sizeKey = GetAppSettingsKey("Size"); - - if (localStorage.Contains(positionKey)) - Position = (Point)localStorage[positionKey]; - - if (localStorage.Contains(sizeKey)) - { - Size size = (Size)localStorage[sizeKey]; - Width = size.Width == 0 ? double.NaN : size.Width; - Height = size.Height == 0 ? double.NaN : size.Height; - } - } - } - - /// <summary> - /// Executed when the Close button is clicked. - /// </summary> - /// <param name="sender">Sender object.</param> - /// <param name="e">Routed event args.</param> - private void CloseButton_Click(object sender, RoutedEventArgs e) - { - Close(); - } - - /// <summary> - /// Executed when the Closing storyboard ends. - /// </summary> - /// <param name="sender">Sender object.</param> - /// <param name="e">Event args.</param> - private void Closing_Completed(object sender, EventArgs e) - { - if (closingStoryboard != null) - closingStoryboard.Completed -= new EventHandler(Closing_Completed); - - this.Visibility = Visibility.Collapsed; - OnClosed(EventArgs.Empty); - } - - /// <summary> - /// Builds the visual tree for the <see cref="FloatingWindow" /> control - /// when a new template is applied. - /// </summary> - public override void OnApplyTemplate() - { - UnsubscribeFromTemplatePartEvents(); - UnsubscribeFromStoryBoardEvents(); - - base.OnApplyTemplate(); - - root = GetTemplateChild(PART_Root) as FrameworkElement; - contentRoot = GetTemplateChild(PART_ContentRoot) as FrameworkElement; - contentBorder = GetTemplateChild(PART_ContentBorder) as Border; - chrome = GetTemplateChild(PART_Chrome) as FrameworkElement; - titleContent = GetTemplateChild(PART_TitleContent) as ContentControl; - contentPresenter = GetTemplateChild(PART_ContentPresenter) as FrameworkElement; - closeButton = GetTemplateChild(PART_CloseButton) as ButtonBase; - maximizeButton = GetTemplateChild(PART_MaximizeButton) as ButtonBase; - minimizeButton = GetTemplateChild(PART_MinimizeButton) as ButtonBase; - restoreButton = GetTemplateChild(PART_RestoreButton) as ButtonBase; - - if (root == null) - throw new NotImplementedException("Template Part PART_Root is required to display FloatingWindow."); - - if (contentRoot == null) - throw new NotImplementedException("Template Part PART_ContentRoot is required to display FloatingWindow."); - - if (contentPresenter == null) - throw new NotImplementedException("Template Part PART_ContentPresenter is required to display FloatingWindow."); - - SetStyles(); - GetStoryboards(); - SetInitialRootPosition(); - InitializeContentRootTransformGroup(); - - if (closeButton != null) - closeButton.SetVisible(ShowCloseButton); - - if (minimizeButton != null) - minimizeButton.SetVisible(ShowMinimizeButton); - - if (maximizeButton != null) - maximizeButton.SetVisible(ShowMaximizeButton); - - SubscribeToTemplatePartEvents(); - SubscribeToStoryBoardEvents(); - } - - /// <summary> - /// Sets styles that are applied for different template parts. - /// </summary> - private void SetStyles() - { - if (titleContent != null && this.TitleStyle != null) - titleContent.Style = this.TitleStyle; - - if (minimizeButton != null && this.MinimizeButtonStyle != null) - minimizeButton.Style = this.MinimizeButtonStyle; - - if (maximizeButton != null && this.MaximizeButtonStyle != null) - maximizeButton.Style = this.MaximizeButtonStyle; - - if (restoreButton != null && this.RestoreButtonStyle != null) - restoreButton.Style = this.RestoreButtonStyle; - - if (closeButton != null && this.CloseButtonStyle != null) - closeButton.Style = this.CloseButtonStyle; - } - - /// <summary> - /// Gets the storyboards defined in the <see cref="FloatingWindow" /> style. - /// </summary> - private void GetStoryboards() - { - if (root != null) - { - var groups = VisualStateManager.GetVisualStateGroups(root) as Collection<VisualStateGroup>; - if (groups != null) - { - var states = (from stategroup in groups - where stategroup.Name == FloatingWindow.VSMGROUP_Window - select stategroup.States).FirstOrDefault() as Collection<VisualState>; - - if (states != null) - { - closingStoryboard = (from state in states - where state.Name == FloatingWindow.VSMSTATE_StateClosed - select state.Storyboard).FirstOrDefault(); - - openingStoryboard = (from state in states - where state.Name == FloatingWindow.VSMSTATE_StateOpen - select state.Storyboard).FirstOrDefault(); - } - } - - if (inertialMotionStoryboard == null) - inertialMotionStoryboard = new Storyboard(); - } - } - - /// <summary> - /// Shift the root of the window to compensate its margins. - /// </summary> - private void SetInitialRootPosition() - { - double x = Math.Round(-this.Margin.Left); - double y = Math.Round(-this.Margin.Top); - - var transformGroup = root.RenderTransform as TransformGroup; - if (transformGroup == null) - { - transformGroup = new TransformGroup(); - transformGroup.Children.Add(root.RenderTransform); - root.RenderTransform = transformGroup; - } - - var translateTransform = transformGroup.Children.OfType<TranslateTransform>().FirstOrDefault(); - if (translateTransform == null) - { - transformGroup.Children.Add(new TranslateTransform() { X = x, Y = y }); - } - else - { - translateTransform.X = x; - translateTransform.Y = y; - } - } - - /// <summary> - /// Checks the TransformGroup of the content root or creates it if necesary. - /// </summary> - private void InitializeContentRootTransformGroup() - { - var transformGroup = contentRoot.RenderTransform as TransformGroup; - if (transformGroup == null) - { - transformGroup = new TransformGroup(); - transformGroup.Children.Add(contentRoot.RenderTransform); - contentRoot.RenderTransform = transformGroup; - } - - // Check that ScaleTransform exists in the TransformGroup - // ScaleTransform is used as a target in Storyboards - var scaleTransform = transformGroup.Children.OfType<ScaleTransform>().FirstOrDefault(); - - if (scaleTransform == null) - transformGroup.Children.Insert(0, new ScaleTransform()); - - var translateTransform = transformGroup.Children.OfType<TranslateTransform>().FirstOrDefault(); - - if (translateTransform == null) - transformGroup.Children.Add(new TranslateTransform()); - } - - /// <summary> - /// Raises the <see cref="FloatingWindow.Activated" /> event. - /// </summary> - /// <param name="e">The event data.</param> - protected virtual void OnActivated(EventArgs e) - { - EventHandler handler = Activated; - if (handler != null) - { - handler(this, e); - } - } - - /// <summary> - /// Raises the <see cref="FloatingWindow.Deactivated" /> event. - /// </summary> - /// <param name="e">The event data.</param> - protected virtual void OnDeactivated(EventArgs e) - { - EventHandler handler = Deactivated; - if (handler != null) - { - handler(this, e); - } - } - - /// <summary> - /// Raises the <see cref="FloatingWindow.Closed" /> event. - /// </summary> - /// <param name="e">The event data.</param> - protected virtual void OnClosed(EventArgs e) - { - this.FloatingWindowHost.Remove(this); - this.FloatingWindowHost.ActivateTopmostWindow(); - UnsubscribeFromStoryBoardEvents(); - - EventHandler handler = Closed; - if (handler != null) - { - handler(this, e); - } - - Dispose(); - } - - /// <summary> - /// Raises the <see cref="FloatingWindow.Closing" /> event. - /// </summary> - /// <param name="e">The event data.</param> - protected virtual void OnClosing(CancelEventArgs e) - { - EventHandler<CancelEventArgs> handler = Closing; - if (handler != null) - { - handler(this, e); - } - } - - /// <summary> - /// Raises the <see cref="FloatingWindow.Maximized" /> event. - /// </summary> - /// <param name="e">The event data.</param> - protected virtual void OnMaximized(EventArgs e) - { - EventHandler handler = Maximized; - if (handler != null) - { - handler(this, e); - } - } - - /// <summary> - /// Raises the <see cref="FloatingWindow.Minimized" /> event. - /// </summary> - /// <param name="e">The event data.</param> - protected virtual void OnMinimized(EventArgs e) - { - EventHandler handler = Minimized; - if (handler != null) - { - handler(this, e); - } - } - - /// <summary> - /// Raises the <see cref="FloatingWindow.Restored" /> event. - /// </summary> - /// <param name="e">The event data.</param> - protected virtual void OnRestored(EventArgs e) - { - EventHandler handler = Restored; - if (handler != null) - { - handler(this, e); - } - } - - /// <summary> - /// This method is called every time a <see cref="FloatingWindow" /> is displayed. - /// </summary> - protected virtual void OnOpened() - { - if (!Focus()) - { - // If the Focus() fails it means there is no focusable element in the window. - // In this case we set IsTabStop to true to have the keyboard functionality - IsTabStop = true; - Focus(); - } - } - - /// <summary> - /// Executed when the opening storyboard finishes. - /// </summary> - /// <param name="sender">Sender object.</param> - /// <param name="e">Event args.</param> - private void Opening_Completed(object sender, EventArgs e) - { - if (openingStoryboard != null) - openingStoryboard.Completed -= new EventHandler(Opening_Completed); - - this.FloatingWindowHost.UpdateIconBar(); - IsOpen = true; - OnOpened(); - } - - /// <summary> - /// Subscribes to events when the window is opened. - /// </summary> - private void SubscribeToEvents() - { - if (Application.Current != null) - Application.Current.Exit += new EventHandler(Application_Exit); - - if (this.FloatingWindowHost != null) - { - this.FloatingWindowHost.SizeChanged += new SizeChangedEventHandler(Host_SizeChanged); - this.FloatingWindowHost.ActiveWindowChanged += new EventHandler<ActiveWindowChangedEventArgs>(ActiveWindowChanged); - } - - // Attach Mouse event handler to catch already handled events to bring the window to the front - this.AddHandler(UIElement.MouseLeftButtonDownEvent, new MouseButtonEventHandler(FloatingWindow_MouseLeftButtonDown), true); - } - - /// <summary> - /// Handles the MouseLeftButtonDown event to bring the window to the front. - /// </summary> - /// <param name="sender">The source of the event.</param> - /// <param name="e">The <see cref="System.Windows.Input.MouseButtonEventArgs"/> instance containing the event data.</param> - private void FloatingWindow_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) - { - // Gets the element with keyboard focus - Control elementWithFocus = FocusManager.GetFocusedElement() as Control; - - // Brings current window to the front - SetTopmost(); - - if (elementWithFocus != null) - { - if (IsControlInVisualTree(elementWithFocus)) - { - elementWithFocus.Focus(); - } - else - { - // Try to set focus on the window - Focus(); - } - } - - // Stop any inertial motion - StopInertialMotion(); - } - - /// <summary> - /// Determines whether the control is in the visual tree of the window. - /// </summary> - /// <param name="control">The control to test.</param> - /// <returns> - /// <c>true</c> if the control is in the visual tree; otherwise, <c>false</c>. - /// </returns> - private bool IsControlInVisualTree(Control control) - { - if (control != null) - { - DependencyObject parent = control; - do - { - parent = VisualTreeHelper.GetParent(parent); - FloatingWindow window = parent as FloatingWindow; - - if (window != null && window == this) - return true; - } - while (parent != null); - } - - return false; - } - - /// <summary> - /// Unsubscribe from events when the ChildWindow is closed. - /// </summary> - private void UnSubscribeFromEvents() - { - if (Application.Current != null) - Application.Current.Exit -= new EventHandler(Application_Exit); - - if (this.FloatingWindowHost != null) - { - this.FloatingWindowHost.SizeChanged -= new SizeChangedEventHandler(Host_SizeChanged); - this.FloatingWindowHost.ActiveWindowChanged -= new EventHandler<ActiveWindowChangedEventArgs>(ActiveWindowChanged); - } - - this.RemoveHandler(UIElement.MouseLeftButtonDownEvent, new MouseButtonEventHandler(FloatingWindow_MouseLeftButtonDown)); - } - - /// <summary> - /// Subscribes to the events on the storyboards. - /// </summary> - private void SubscribeToStoryBoardEvents() - { - if (closingStoryboard != null) - closingStoryboard.Completed += new EventHandler(Closing_Completed); - - if (openingStoryboard != null) - openingStoryboard.Completed += new EventHandler(Opening_Completed); - - if (inertialMotionStoryboard != null) - inertialMotionStoryboard.Completed += new EventHandler(InertialMotion_Completed); - } - - /// <summary> - /// Unsubscribe from events that are subscribed on the storyboards. - /// </summary> - private void UnsubscribeFromStoryBoardEvents() - { - if (closingStoryboard != null) - closingStoryboard.Completed -= new EventHandler(Closing_Completed); - - if (openingStoryboard != null) - openingStoryboard.Completed -= new EventHandler(Opening_Completed); - - if (inertialMotionStoryboard != null) - inertialMotionStoryboard.Completed -= new EventHandler(InertialMotion_Completed); - } - - /// <summary> - /// Subscribes to the events on the template parts. - /// </summary> - private void SubscribeToTemplatePartEvents() - { - if (closeButton != null) - closeButton.Click += new RoutedEventHandler(CloseButton_Click); - - if (maximizeButton != null) - maximizeButton.Click += new RoutedEventHandler(MaximizeButton_Click); - - if (restoreButton != null) - restoreButton.Click += new RoutedEventHandler(RestoreButton_Click); - - if (minimizeButton != null) - minimizeButton.Click += new RoutedEventHandler(MinimizeButton_Click); - } - - /// <summary> - /// Unsubscribe from the events that are subscribed on the template part elements. - /// </summary> - private void UnsubscribeFromTemplatePartEvents() - { - if (closeButton != null) - closeButton.Click -= new RoutedEventHandler(CloseButton_Click); - - if (maximizeButton != null) - maximizeButton.Click -= new RoutedEventHandler(MaximizeButton_Click); - - if (restoreButton != null) - restoreButton.Click -= new RoutedEventHandler(RestoreButton_Click); - - if (minimizeButton != null) - minimizeButton.Click -= new RoutedEventHandler(MinimizeButton_Click); - } - - /// <summary> - /// Handles the ActiveWindowChanged event of the Host control. - /// </summary> - /// <param name="sender">The sender.</param> - /// <param name="e">The <see cref="SilverFlow.Controls.ActiveWindowChangedEventArgs"/> instance containing the event data.</param> - private void ActiveWindowChanged(object sender, ActiveWindowChangedEventArgs e) - { - if (e.Old == this) - OnDeactivated(EventArgs.Empty); - - if (e.New == this) - OnActivated(EventArgs.Empty); - } - - /// <summary> - /// Handles the Click event of the MaximizeButton control. - /// </summary> - /// <param name="sender">The source of the event.</param> - /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param> - private void MaximizeButton_Click(object sender, RoutedEventArgs e) - { - MaximizeWindow(); - } - - /// <summary> - /// Handles the Click event of the RestoreButton control. - /// </summary> - /// <param name="sender">The source of the event.</param> - /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param> - private void RestoreButton_Click(object sender, RoutedEventArgs e) - { - RestoreMaximizedWindow(); - } - - /// <summary> - /// Handles the Click event of the MinimizeButton control. - /// </summary> - /// <param name="sender">The source of the event.</param> - /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param> - private void MinimizeButton_Click(object sender, RoutedEventArgs e) - { - MinimizeWindow(); - } - - /// <summary> - /// Minimizes the window. - /// </summary> - private void MinimizeWindow() - { - if (windowState != WindowState.Minimized) - { - if (minimizeButton != null) - VisualStateManager.GoToState(minimizeButton, VSMSTATE_StateNormal, true); - - if (windowState == WindowState.Normal) - { - // Store previous coordinates - previousPosition = Position; - previousSize = new Size(ActualWidth, ActualHeight); - } - - minimizedWindowThumbnail = GetThumbnailImage(); - - previousWindowState = windowState; - VisualStateManager.GoToState(this, VSMSTATE_StateMinimized, true); - OnMinimized(EventArgs.Empty); - } - - windowState = WindowState.Minimized; - OnDeactivated(EventArgs.Empty); - - this.FloatingWindowHost.ActivateTopmostWindow(); - } - - /// <summary> - /// Creates a thumbnail of the window. - /// </summary> - /// <returns>Bitmap containing thumbnail image.</returns> - private ImageSource GetThumbnailImage() - { - // If an Icon is specified - use it as a thumbnail displayed on the iconbar - // Otherwise, display the window itself - FrameworkElement icon = (Icon as FrameworkElement) ?? contentRoot; - ImageSource bitmap = bitmapHelper.RenderVisual(icon, FloatingWindowHost.IconWidth, FloatingWindowHost.IconHeight); - - return bitmap; - } - - /// <summary> - /// Maximizes the window. - /// </summary> - public void MaximizeWindow() - { - if (windowState != WindowState.Maximized) - { - if (maximizeButton != null && restoreButton != null && HostPanel != null) - { - if (this.ShowMaximizeButton) - maximizeButton.SetVisible(false); - - if (this.ShowRestoreButton) - restoreButton.SetVisible(true); - - VisualStateManager.GoToState(restoreButton, VSMSTATE_StateNormal, true); - - // Store previous coordinates - previousPosition = Position; - previousSize = new Size(ActualWidth, ActualHeight); - - // Hide the outer border - if (contentBorder != null) - { - contentBorderThickness = contentBorder.BorderThickness; - contentBorderCornerRadius = contentBorder.CornerRadius; - contentBorder.BorderThickness = new Thickness(0); - contentBorder.CornerRadius = new CornerRadius(0); - } - - Border border = chrome as Border; - if (border != null) - { - chromeBorderCornerRadius = border.CornerRadius; - border.CornerRadius = new CornerRadius(0); - } - - StartMaximizingAnimation(); - } - - previousWindowState = windowState; - windowState = WindowState.Maximized; - } - } - - /// <summary> - /// Checks if the floating window was added to the FloatingWindowHost. - /// </summary> - private void CheckHost() - { - if (this.FloatingWindowHost == null) - throw new InvalidOperationException("The FloatingWindow was not added to the FloatingWindowHost."); - } - - /// <summary> - /// Starts maximizing animation. - /// </summary> - private void StartMaximizingAnimation() - { - SaveActualSize(); - - this.MoveAndResize(new Point(0, 0), HostPanel.ActualWidth, HostPanel.ActualHeight, - MaximizingDurationInMilliseconds, Maximizing_Completed); - } - - /// <summary> - /// Saves the actual size if it was not set explicitly set. - /// E.g. the Width can be NaN, that means "Auto". - /// </summary> - private void SaveActualSize() - { - if (Width.IsNotSet()) - Width = ActualWidth; - - if (Height.IsNotSet()) - Height = ActualHeight; - } - - /// <summary> - /// Handles the Completed event of the Maximizing animation. - /// </summary> - /// <param name="sender">The source of the event.</param> - /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param> - private void Maximizing_Completed(object sender, EventArgs e) - { - OnMaximized(EventArgs.Empty); - } - - /// <summary> - /// Restores maximized window position and size. - /// </summary> - private void RestoreMaximizedWindow() - { - if (windowState != WindowState.Normal) - { - if (maximizeButton != null && restoreButton != null && HostPanel != null) - { - if (this.ShowMaximizeButton) - maximizeButton.SetVisible(true); - - if (this.ShowRestoreButton) - restoreButton.SetVisible(false); - - VisualStateManager.GoToState(maximizeButton, VSMSTATE_StateNormal, true); - } - - // Restore the outer border - if (contentBorder != null) - { - contentBorder.BorderThickness = contentBorderThickness; - contentBorder.CornerRadius = contentBorderCornerRadius; - } - - Border border = chrome as Border; - - if (border != null) - border.CornerRadius = chromeBorderCornerRadius; - - StartRestoringAnimation(); - windowState = WindowState.Normal; - } - else - { - Show(Position); - } - } - - /// <summary> - /// Starts restoring animation. - /// </summary> - private void StartRestoringAnimation() - { - SaveActualSize(); - - this.MoveAndResize(previousPosition, previousSize.Width, previousSize.Height, - RestoringDurationInMilliseconds, Restoring_Completed); - } - - /// <summary> - /// Handles the Completed event of the Restoring animation. - /// </summary> - /// <param name="sender">The source of the event.</param> - /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param> - private void Restoring_Completed(object sender, EventArgs e) - { - OnRestored(EventArgs.Empty); - } - - /// <summary> - /// Updates clipping region on host SizeChanged event. - /// </summary> - /// <param name="sender">The source of the event.</param> - /// <param name="e">The <see cref="System.Windows.SizeChangedEventArgs"/> instance containing the event data.</param> - private void Host_SizeChanged(object sender, SizeChangedEventArgs e) - { - if (windowState == WindowState.Maximized) - { - Width = HostPanel.ActualWidth; - Height = double.IsInfinity(MaxHeight) ? HostPanel.ActualHeight : MaxHeight; - } - } - - /// <summary> - /// Executed when mouse left button is down. - /// </summary> - /// <param name="e">The data for the event.</param> - protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) - { - base.OnMouseLeftButtonDown(e); - - if (windowState == WindowState.Normal) - { - // Stop inertial motion before the mouse is captured - StopInertialMotion(); - - clickPoint = e.GetPosition(HostPanel); - clickWindowPosition = Position; - snapinController.SnapinDistance = this.FloatingWindowHost.SnapinDistance; - snapinController.SnapinMargin = this.FloatingWindowHost.SnapinMargin; - snapinController.SnapinEnabled = this.FloatingWindowHost.SnapinEnabled; - - if (ResizeEnabled && resizeController.CanResize) - { - snapinController.SnapinBounds = this.FloatingWindowHost.GetSnapinBounds(this); - resizeController.StartResizing(); - CaptureMouseCursor(); - windowAction = WindowAction.Resize; - } - else if (chrome != null) - { - // If the mouse was clicked on the chrome - start dragging the window - Point point = e.GetPosition(chrome); - - if (chrome.ContainsPoint(point)) - { - snapinController.SnapinBounds = this.FloatingWindowHost.GetSnapinBounds(this); - CaptureMouseCursor(); - windowAction = WindowAction.Move; - inertiaController.StartMotion(Position); - } - } - } - } - - /// <summary> - /// Executed when mouse left button is up. - /// </summary> - /// <param name="e">The data for the event.</param> - protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e) - { - base.OnMouseLeftButtonUp(e); - - if (windowAction == WindowAction.Move) - { - InertialMotion motion = inertiaController.GetInertialMotionParameters( - this.FloatingWindowHost.HostPanel.GetActualBoundingRectangle(), this.BoundingRectangle); - - if (motion != null) - { - contentRoot.AnimateTranslateTransform(inertialMotionStoryboard, motion.EndPosition, motion.Seconds, motion.EasingFunction); - } - } - - if (isMouseCaptured) - { - contentRoot.ReleaseMouseCapture(); - isMouseCaptured = false; - } - - windowAction = WindowAction.None; - } - - /// <summary> - /// Handles the Completed event of the InertialMotionStoryboard. - /// </summary> - /// <param name="sender">The source of the event.</param> - /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param> - private void InertialMotion_Completed(object sender, EventArgs e) - { - // Save current window position reading it from the TranslateTransform object - Position = GetCurrentWindowPosition(); - } - - /// <summary> - /// Stops current inertial motion. - /// </summary> - private void StopInertialMotion() - { - if (inertialMotionStoryboard.GetCurrentState() != ClockState.Stopped) - { - inertialMotionStoryboard.Pause(); - - // The Position has rounded coordinates now, but real X and Y coordinates are fractional - Position = GetCurrentWindowPosition(); - - // Move the window to the rounded coordinates - MoveWindow(Position); - - inertialMotionStoryboard.Stop(); - inertialMotionStoryboard.Children.Clear(); - } - } - - /// <summary> - /// Gets current window position taking into account animation effects. - /// </summary> - /// <returns>Current window position.</returns> - private Point GetCurrentWindowPosition() - { - var transformGroup = contentRoot.RenderTransform as TransformGroup; - var translateTransform = transformGroup.Children.OfType<TranslateTransform>().FirstOrDefault(); - var position = new Point(translateTransform.X, translateTransform.Y); - - // Round coordinates to avoid blured window - return position.Round(); - } - - /// <summary> - /// Captures the mouse cursor. - /// </summary> - private void CaptureMouseCursor() - { - contentRoot.CaptureMouse(); - isMouseCaptured = true; - } - - /// <summary> - /// Executed when mouse moves. - /// </summary> - /// <param name="e">The data for the event.</param> - protected override void OnMouseMove(MouseEventArgs e) - { - base.OnMouseMove(e); - - if (windowState == WindowState.Normal && ResizeEnabled && windowAction == WindowAction.None) - { - Point mousePosition = e.GetPosition(contentRoot); - - if (IsMouseOverButtons(mousePosition, contentRoot)) - this.Cursor = Cursors.Arrow; - else - resizeController.SetCursor(mousePosition); - } - - Point p = e.GetPosition(HostPanel); - double dx = p.X - clickPoint.X; - double dy = p.Y - clickPoint.Y; - - if (windowAction == WindowAction.Resize) - resizeController.Resize(dx, dy); - - if (windowAction == WindowAction.Move) - { - Point point = clickWindowPosition.Add(dx, dy); - Rect rect = new Rect(point.X, point.Y, ActualWidth, ActualHeight); - - point = snapinController.SnapRectangle(rect); - MoveWindow(point); - - inertiaController.MoveToPoint(Position); - } - } - - /// <summary> - /// Determines whether the mouse is over buttons in the the specified mouse position. - /// </summary> - /// <param name="position">The mouse position.</param> - /// <param name="origin">Relative origin.</param> - /// <returns><c>true</c> if mouse is mouse over buttons.</returns> - private bool IsMouseOverButtons(Point position, UIElement origin) - { - return (minimizeButton.IsVisible() && minimizeButton.ContainsPoint(position, origin)) || - (maximizeButton.IsVisible() && maximizeButton.ContainsPoint(position, origin)) || - (restoreButton.IsVisible() && restoreButton.ContainsPoint(position, origin)) || - (closeButton.IsVisible() && closeButton.ContainsPoint(position, origin)); - } - - /// <summary> - /// Moves the window to the specified coordinates. - /// </summary> - /// <param name="point">Coordinates of the window.</param> - private void MoveWindow(Point point) - { - if (contentRoot != null && !point.IsNotSet()) - { - // Round coordinates to avoid blured window - double x = Math.Round(Math.Max(0, point.X)); - double y = Math.Round(Math.Max(0, point.Y)); - - var transformGroup = contentRoot.RenderTransform as TransformGroup; - var translateTransform = transformGroup.Children.OfType<TranslateTransform>().FirstOrDefault(); - if (translateTransform == null) - { - transformGroup.Children.Add(new TranslateTransform() { X = x, Y = y }); - } - else - { - translateTransform.X = x; - translateTransform.Y = y; - } - - Point newPosition = new Point(x, y); - - if (Position != newPosition) - Position = newPosition; - } - } - - /// <summary> - /// Saves current size and position of the window in the IsolatedStorage. - /// The key of the settings is the Tag of the window (if not null). - /// </summary> - private void SaveSizeAndPosition() - { - if (IsWindowTagSet) - { - string positionKey = GetAppSettingsKey("Position"); - string sizeKey = GetAppSettingsKey("Size"); - - Point point = windowState == WindowState.Normal ? Position : previousPosition; - localStorage[positionKey] = point; - - Size size = windowState == WindowState.Normal ? new Size(ActualWidth, ActualHeight) : previousSize; - localStorage[sizeKey] = size; - } - } - - /// <summary> - /// Gets the application settings key used to store properties in the IsolatedStorage. - /// </summary> - /// <param name="key">The key of the property, e.g. "Position".</param> - /// <returns>Combined settings key or empty string.</returns> - private string GetAppSettingsKey(string key) - { - string tag = this.Tag as string; - return tag + ":" + key; - } - - /// <summary> - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// </summary> - public void Dispose() - { - GC.Collect(); - GC.WaitForPendingFinalizers(); - GC.Collect(); - } - } -}
--- a/SilverlightGlimpse/SilverFlow.Controls/FloatingWindow/FloatingWindowHost.cs Mon Apr 23 11:05:11 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1032 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Input; -using System.Windows.Media; -using SilverFlow.Controls.Extensions; - -namespace SilverFlow.Controls -{ - /// <summary> - /// A Content Control containing floating windows. - /// </summary> - [TemplatePart(Name = PART_Root, Type = typeof(Grid))] - [TemplatePart(Name = PART_ContentRoot, Type = typeof(FrameworkElement))] - [TemplatePart(Name = PART_HostCanvas, Type = typeof(Canvas))] - [TemplatePart(Name = PART_ModalCanvas, Type = typeof(Canvas))] - [TemplatePart(Name = PART_IconBarContainer, Type = typeof(FrameworkElement))] - [TemplatePart(Name = PART_Overlay, Type = typeof(Grid))] - [TemplatePart(Name = PART_IconBar, Type = typeof(IconBar))] - [TemplatePart(Name = PART_BottomBar, Type = typeof(FrameworkElement))] - [TemplatePart(Name = PART_BootstrapButton, Type = typeof(BootstrapButton))] - [TemplatePart(Name = PART_BarContent, Type = typeof(ContentControl))] - [TemplateVisualState(Name = VSMSTATE_VisibleOverlay, GroupName = VSMGROUP_Overlay)] - [TemplateVisualState(Name = VSMSTATE_HiddenOverlay, GroupName = VSMGROUP_Overlay)] - [StyleTypedProperty(Property = PROPERTY_BottomBarStyle, StyleTargetType = typeof(Border))] - [StyleTypedProperty(Property = PROPERTY_BootstrapButtonStyle, StyleTargetType = typeof(BootstrapButton))] - [StyleTypedProperty(Property = PROPERTY_WindowIconStyle, StyleTargetType = typeof(WindowIcon))] - public class FloatingWindowHost : ContentControl - { - #region Constants - - // Template parts - private const string PART_Root = "PART_Root"; - private const string PART_ContentRoot = "PART_ContentRoot"; - private const string PART_HostCanvas = "PART_HostCanvas"; - private const string PART_ModalCanvas = "PART_ModalCanvas"; - private const string PART_IconBarContainer = "PART_IconBarContainer"; - private const string PART_Overlay = "PART_Overlay"; - private const string PART_IconBar = "PART_IconBar"; - private const string PART_BottomBar = "PART_BottomBar"; - private const string PART_BootstrapButton = "PART_BootstrapButton"; - private const string PART_BarContent = "PART_BarContent"; - - // VSM groups - private const string VSMGROUP_Overlay = "OverlayStates"; - - // VSM states - private const string VSMSTATE_VisibleOverlay = "VisibleOverlay"; - private const string VSMSTATE_HiddenOverlay = "HiddenOverlay"; - - // Style typed properties - private const string PROPERTY_BottomBarStyle = "BottomBarStyle"; - private const string PROPERTY_BootstrapButtonStyle = "BootstrapButtonStyle"; - private const string PROPERTY_WindowIconStyle = "WindowIconStyle"; - - // Thickness of resizing area. - private const double SnapinDistanceDefaultValue = 5.0; - - // Default icon size - private const double DefaultIconWidth = 120; - private const double DefaultIconHeight = 70; - - #endregion - - #region Member Fields - - /// <summary> - /// Current ZIndex of a child element - /// </summary> - private static int zIndex = 1; - - private Grid root; - private FrameworkElement contentRoot; - private Canvas hostCanvas; - private Canvas modalCanvas; - private FrameworkElement iconBarContainer; - private Grid overlay; - private IconBar iconBar; - private FrameworkElement bottomBar; - private BootstrapButton bootstrapButton; - private ContentControl barContent; - - private bool templateIsApplied; - - #endregion Member Fields - - #region public Style BottomBarStyle - - /// <summary> - /// Gets or sets the style of the BottomBar. - /// </summary> - public Style BottomBarStyle - { - get { return GetValue(BottomBarStyleProperty) as Style; } - set { SetValue(BottomBarStyleProperty, value); } - } - - /// <summary> - /// Identifies the <see cref="FloatingWindowHost.BottomBarStyleProperty" /> dependency property. - /// </summary> - public static readonly DependencyProperty BottomBarStyleProperty = - DependencyProperty.Register( - "BottomBarStyle", - typeof(Style), - typeof(FloatingWindowHost), - new PropertyMetadata(BottomBarStylePropertyChanged)); - - /// <summary> - /// BottomBarStyle PropertyChangedCallback call back static function. - /// </summary> - /// <param name="d">FloatingWindowHost object whose BottomBarStyle property is changed.</param> - /// <param name="e">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param> - private static void BottomBarStylePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - FloatingWindowHost host = (FloatingWindowHost)d; - if (host != null && host.bottomBar != null) - { - host.bottomBar.Style = e.NewValue as Style; - } - } - - #endregion - - #region public Style BootstrapButtonStyle - - /// <summary> - /// Gets or sets the style of the BootstrapButton. - /// </summary> - public Style BootstrapButtonStyle - { - get { return GetValue(BootstrapButtonStyleProperty) as Style; } - set { SetValue(BootstrapButtonStyleProperty, value); } - } - - /// <summary> - /// Identifies the <see cref="FloatingWindowHost.BootstrapButtonStyleProperty" /> dependency property. - /// </summary> - public static readonly DependencyProperty BootstrapButtonStyleProperty = - DependencyProperty.Register( - "BootstrapButtonStyle", - typeof(Style), - typeof(FloatingWindowHost), - new PropertyMetadata(BootstrapButtonStylePropertyChanged)); - - /// <summary> - /// BootstrapButtonStyle PropertyChangedCallback call back static function. - /// </summary> - /// <param name="d">FloatingWindowHost object whose BootstrapButtonStyle property is changed.</param> - /// <param name="e">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param> - private static void BootstrapButtonStylePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - FloatingWindowHost host = (FloatingWindowHost)d; - if (host != null && host.bottomBar != null) - { - host.bootstrapButton.Style = e.NewValue as Style; - } - } - - #endregion - - #region public Style WindowIconStyle - - /// <summary> - /// Gets or sets the style of the WindowIcon. - /// </summary> - public Style WindowIconStyle - { - get { return GetValue(WindowIconStyleProperty) as Style; } - set { SetValue(WindowIconStyleProperty, value); } - } - - /// <summary> - /// Identifies the <see cref="FloatingWindowHost.WindowIconStyleProperty" /> dependency property. - /// </summary> - public static readonly DependencyProperty WindowIconStyleProperty = - DependencyProperty.Register( - "WindowIconStyle", - typeof(Style), - typeof(FloatingWindowHost), - new PropertyMetadata(WindowIconStylePropertyChanged)); - - /// <summary> - /// WindowIconStyle PropertyChangedCallback call back static function. - /// </summary> - /// <param name="d">FloatingWindowHost object whose WindowIconStyle property is changed.</param> - /// <param name="e">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param> - private static void WindowIconStylePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - FloatingWindowHost host = (FloatingWindowHost)d; - if (host != null && host.iconBar != null) - { - host.iconBar.WindowIconStyle = e.NewValue as Style; - } - } - - #endregion - - #region public bool SnapinEnabled - - /// <summary> - /// Gets or sets a value indicating whether snap in is enabled. - /// </summary> - /// <value><c>true</c> if snap in is enabled; otherwise, <c>false</c>.</value> - public bool SnapinEnabled - { - get { return (bool)GetValue(SnapinEnabledProperty); } - set { SetValue(SnapinEnabledProperty, value); } - } - - /// <summary> - /// Identifies the <see cref="FloatingWindowHost.SnapinEnabled" /> dependency property. - /// </summary> - /// <value> - /// The identifier for the <see cref="FloatingWindowHost.SnapinEnabled" /> dependency property. - /// </value> - public static readonly DependencyProperty SnapinEnabledProperty = - DependencyProperty.Register( - "SnapinEnabled", - typeof(bool), - typeof(FloatingWindowHost), - new PropertyMetadata(true, null)); - - #endregion - - #region public double SnapinDistance - - /// <summary> - /// Gets or sets a value of the snap in distance. - /// </summary> - /// <value>Snap in distance.</value> - public double SnapinDistance - { - get { return (double)GetValue(SnapinDistanceProperty); } - set { SetValue(SnapinDistanceProperty, value); } - } - - /// <summary> - /// Identifies the <see cref="FloatingWindowHost.SnapinDistance" /> dependency property. - /// </summary> - /// <value> - /// The identifier for the <see cref="FloatingWindowHost.SnapinDistance" /> dependency property. - /// </value> - public static readonly DependencyProperty SnapinDistanceProperty = - DependencyProperty.Register( - "SnapinDistance", - typeof(double), - typeof(FloatingWindowHost), - new PropertyMetadata(SnapinDistanceDefaultValue, null)); - - #endregion - - #region public double SnapinMargin - - /// <summary> - /// Gets or sets a value of the snap in margin - distance between adjacent edges. - /// </summary> - /// <value>Snap in margin.</value> - public double SnapinMargin - { - get { return (double)GetValue(SnapinMarginProperty); } - set { SetValue(SnapinMarginProperty, value); } - } - - /// <summary> - /// Identifies the <see cref="FloatingWindowHost.SnapinMargin" /> dependency property. - /// </summary> - /// <value> - /// The identifier for the <see cref="FloatingWindowHost.SnapinMargin" /> dependency property. - /// </value> - public static readonly DependencyProperty SnapinMarginProperty = - DependencyProperty.Register( - "SnapinMargin", - typeof(double), - typeof(FloatingWindowHost), - new PropertyMetadata(0.0, null)); - - #endregion - - #region public bool ShowMinimizedOnlyInIconbar - - /// <summary> - /// Gets or sets a value indicating whether to show only minimized windows in the iconbar. - /// </summary> - /// <value><c>true</c> if to show only minimized windows in the iconbar; otherwise, <c>false</c>.</value> - public bool ShowMinimizedOnlyInIconbar - { - get { return (bool)GetValue(ShowMinimizedOnlyInIconbarProperty); } - set { SetValue(ShowMinimizedOnlyInIconbarProperty, value); } - } - - /// <summary> - /// Identifies the <see cref="FloatingWindowHost.ShowMinimizedOnlyInIconbarProperty" /> dependency property. - /// </summary> - /// <value> - /// The identifier for the <see cref="FloatingWindowHost.ShowMinimizedOnlyInIconbarProperty" /> dependency property. - /// </value> - public static readonly DependencyProperty ShowMinimizedOnlyInIconbarProperty = - DependencyProperty.Register( - "ShowMinimizedOnlyInIconbar", - typeof(bool), - typeof(FloatingWindowHost), - new PropertyMetadata(false, null)); - - #endregion - - #region public Brush OverlayBrush - - /// <summary> - /// Gets or sets the overlay color. - /// </summary> - /// <value>The overlay color.</value> - public Brush OverlayBrush - { - get { return (Brush)GetValue(OverlayBrushProperty); } - set { SetValue(OverlayBrushProperty, value); } - } - - /// <summary> - /// Identifies the <see cref="FloatingWindowHost.OverlayBrush" /> dependency property. - /// </summary> - /// <value> - /// The identifier for the <see cref="FloatingWindowHost.OverlayBrush" /> dependency property. - /// </value> - public static readonly DependencyProperty OverlayBrushProperty = - DependencyProperty.Register( - "OverlayBrush", - typeof(Brush), - typeof(FloatingWindowHost), - new PropertyMetadata(new SolidColorBrush(Color.FromArgb(0x90, 0x20, 0x20, 0x30)), OnOverlayBrushPropertyChanged)); - - /// <summary> - /// OverlayBrushProperty PropertyChangedCallback call back static function. - /// </summary> - /// <param name="d">FloatingWindowHost object whose OverlayBrush property is changed.</param> - /// <param name="e">DependencyPropertyChangedEventArgs which contains the old and new values.</param> - private static void OnOverlayBrushPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - FloatingWindowHost host = (FloatingWindowHost)d; - - if (host != null && host.overlay != null) - host.overlay.Background = (Brush)e.NewValue; - } - - #endregion - - #region public double IconWidth - - /// <summary> - /// Gets or sets the width of the window's icon. - /// </summary> - /// <value>The width of the window's icon.</value> - public double IconWidth - { - get { return (double)GetValue(IconWidthProperty); } - set { SetValue(IconWidthProperty, value); } - } - - /// <summary> - /// Identifies the <see cref="FloatingWindowHost.IconWidth" /> dependency property. - /// </summary> - /// <value> - /// The identifier for the <see cref="FloatingWindowHost.IconWidth" /> dependency property. - /// </value> - public static readonly DependencyProperty IconWidthProperty = - DependencyProperty.Register( - "IconWidth", - typeof(double), - typeof(FloatingWindowHost), - new PropertyMetadata(DefaultIconWidth, null)); - - #endregion - - #region public double IconHeight - - /// <summary> - /// Gets or sets the height of the window's icon. - /// </summary> - /// <value>The height of the window's icon.</value> - public double IconHeight - { - get { return (double)GetValue(IconHeightProperty); } - set { SetValue(IconHeightProperty, value); } - } - - /// <summary> - /// Identifies the <see cref="FloatingWindowHost.IconHeight" /> dependency property. - /// </summary> - /// <value> - /// The identifier for the <see cref="FloatingWindowHost.IconHeight" /> dependency property. - /// </value> - public static readonly DependencyProperty IconHeightProperty = - DependencyProperty.Register( - "IconHeight", - typeof(double), - typeof(FloatingWindowHost), - new PropertyMetadata(DefaultIconHeight, null)); - - #endregion - - #region public object Bar - - /// <summary> - /// Gets or sets a control displayed in the BottomBar. - /// </summary> - /// <value>The control displayed in the BottomBar. The default is null.</value> - public object Bar - { - get { return (double)GetValue(BarProperty); } - set { SetValue(BarProperty, value); } - } - - /// <summary> - /// Identifies the <see cref="FloatingWindowHost.Bar" /> dependency property. - /// </summary> - /// <value> - /// The identifier for the <see cref="FloatingWindowHost.Bar" /> dependency property. - /// </value> - public static readonly DependencyProperty BarProperty = - DependencyProperty.Register( - "Bar", - typeof(object), - typeof(FloatingWindowHost), - null); - - #endregion - - /// <summary> - /// Gets a collection of windows shown in the IconBar. - /// </summary> - /// <value>Collection of windows shown in the IconBar.</value> - public IOrderedEnumerable<FloatingWindow> WindowsInIconBar - { - get - { - var windows = from window in this.FloatingWindows - where window.IsOpen && window.ShowInIconbar && - !(ShowMinimizedOnlyInIconbar && window.WindowState != WindowState.Minimized) - orderby window.IconText - select window; - - return windows; - } - } - - /// <summary> - /// Gets the host panel, containing the floating windows. - /// </summary> - /// <value>The host panel.</value> - public Canvas HostPanel - { - get { return hostCanvas; } - } - - /// <summary> - /// Gets the floating windows collection. - /// </summary> - /// <value>The floating windows collection.</value> - public IEnumerable<FloatingWindow> FloatingWindows - { - get { return hostCanvas.Children.OfType<FloatingWindow>(); } - } - - /// <summary> - /// Gets or sets a value indicating whether the layout of the FloatingWindowHost is updated. - /// </summary> - /// <value> - /// <c>true</c> if the layout of the FloatingWindowHost is updated; otherwise, <c>false</c>. - /// </value> - internal bool IsLayoutUpdated { get; private set; } - - /// <summary> - /// Gets current modal window. - /// </summary> - /// <value>The modal window.</value> - private FloatingWindow ModalWindow - { - get { return modalCanvas.Children.OfType<FloatingWindow>().FirstOrDefault(); } - } - - /// <summary> - /// Initializes a new instance of the <see cref="FloatingWindowHost"/> class. - /// </summary> - public FloatingWindowHost() - { - DefaultStyleKey = typeof(FloatingWindowHost); - } - - /// <summary> - /// Builds the visual tree for the <see cref="FloatingWindowHost" /> control - /// when a new template is applied. - /// </summary> - public override void OnApplyTemplate() - { - UnsubscribeFromEvents(); - UnsubscribeFromTemplatePartEvents(); - - base.OnApplyTemplate(); - - root = GetTemplatePart<Grid>(PART_Root); - contentRoot = GetTemplatePart<FrameworkElement>(PART_ContentRoot); - hostCanvas = GetTemplatePart<Canvas>(PART_HostCanvas); - modalCanvas = GetTemplatePart<Canvas>(PART_ModalCanvas); - iconBarContainer = GetTemplatePart<FrameworkElement>(PART_IconBarContainer); - overlay = GetTemplatePart<Grid>(PART_Overlay); - iconBar = GetTemplatePart<IconBar>(PART_IconBar); - bottomBar = GetTemplatePart<FrameworkElement>(PART_BottomBar); - bootstrapButton = GetTemplatePart<BootstrapButton>(PART_BootstrapButton); - barContent = GetTemplatePart<ContentControl>(PART_BarContent); - - iconBar.FloatingWindowHost = this; - - SetStyles(); - SubscribeToTemplatePartEvents(); - SubscribeToEvents(); - - templateIsApplied = true; - } - - #region Events - - /// <summary> - /// Occurs when the <see cref="FloatingWindowHost" /> is loaded and its template is applied. - /// </summary> - public event EventHandler Rendered; - - /// <summary> - /// Occurs when the active <see cref="FloatingWindow" /> is changed. - /// </summary> - public event EventHandler<ActiveWindowChangedEventArgs> ActiveWindowChanged; - - #endregion Events - - /// <summary> - /// Adds the specified floating window to the collection of child elements of the host. - /// </summary> - /// <param name="window">The floating window.</param> - /// <exception cref="ArgumentNullException">Floating window is null.</exception> - public void Add(FloatingWindow window) - { - if (window == null) - throw new ArgumentNullException("window"); - - // Guarantee that the visual tree of the control is complete - if (!templateIsApplied) - templateIsApplied = ApplyTemplate(); - - if (!hostCanvas.Children.Contains(window)) - { - hostCanvas.Children.Add(window); - window.FloatingWindowHost = this; - } - } - - /// <summary> - /// Removes the specified floating window from the collection of child elements of the host. - /// </summary> - /// <param name="window">The floating window.</param> - public void Remove(FloatingWindow window) - { - if (window != null) - { - hostCanvas.Children.Remove(window); - modalCanvas.Children.Remove(window); - iconBar.Remove(window); - } - } - - /// <summary> - /// Closes all floating windows. - /// </summary> - public void CloseAllWindows() - { - HideIconBar(); - FloatingWindows.ToList().ForEach(x => x.Close()); - } - - /// <summary> - /// Shows the IconBar. - /// </summary> - public void ShowIconBar() - { - iconBar.Show(); - } - - /// <summary> - /// Hides the IconBar. - /// </summary> - public void HideIconBar() - { - iconBar.Hide(); - } - - /// <summary> - /// Updates the IconBar if it is open. - /// </summary> - public void UpdateIconBar() - { - iconBar.Update(); - } - - /// <summary> - /// Sets the specified floating window topmost, and set Focus on it. - /// </summary> - /// <param name="window">FloatingWindow to set topmost.</param> - /// <exception cref="ArgumentNullException">FloatingWindow is null.</exception> - public void SetTopmostWindow(FloatingWindow window) - { - if (window == null) - throw new ArgumentNullException("window"); - - FloatingWindow topmostWindow = GetTopmostWindow(); - if (topmostWindow == null || window != topmostWindow) - { - SetTopmost(window); - SetFocusToActiveWindow(window); - - if (!window.TopMost && !window.IsModal) - ShowTopmostWindows(); - - ActiveWindowChangedEventArgs e = new ActiveWindowChangedEventArgs(topmostWindow, window); - OnActiveWindowChanged(e); - } - } - - /// <summary> - /// Activates the topmost window and sets focus on it. - /// </summary> - public void ActivateTopmostWindow() - { - // First, try to activate a modal window, if exists - var topmostWindow = this.ModalWindow; - - if (topmostWindow == null) - topmostWindow = GetTopmostWindow(); - - SetFocusToActiveWindow(topmostWindow); - - ActiveWindowChangedEventArgs e = new ActiveWindowChangedEventArgs(null, topmostWindow); - OnActiveWindowChanged(e); - } - - /// <summary> - /// Gets Snap In bounds as bounds of the host and all open windows except the specified one. - /// </summary> - /// <param name="windowToExclude">The window to exclude from the list.</param> - /// <returns>List of bounding rectangles.</returns> - internal IEnumerable<Rect> GetSnapinBounds(FloatingWindow windowToExclude) - { - List<Rect> bounds = new List<Rect>(); - - // Add host bounds - bounds.Add(hostCanvas.GetActualBoundingRectangle()); - - if (!overlay.IsVisible()) - { - foreach (var window in FloatingWindows) - { - if (window != windowToExclude && window.IsOpen) - bounds.Add(window.BoundingRectangle); - } - } - - return bounds; - } - - /// <summary> - /// Shows the overlay, moves the window to the "modal" layer and hides the IconBar. - /// </summary> - /// <param name="modalWindow">The modal window.</param> - internal void ShowWindowAsModal(FloatingWindow modalWindow) - { - HideIconBar(); - VisualStateManager.GoToState(this, VSMSTATE_VisibleOverlay, true); - - MoveWindowToModalLayer(modalWindow); - } - - /// <summary> - /// Removes the overlay under the modal window. - /// </summary> - internal void RemoveOverlay() - { - if (overlay.IsVisible()) - { - FloatingWindow topmostWindow = null; - - if (FloatingWindows.Count(x => x.IsOpen && x.IsModal) == 0) - { - // If there are no more modal windows - remove the overlay - VisualStateManager.GoToState(this, VSMSTATE_HiddenOverlay, true); - - topmostWindow = GetTopmostWindow(); - } - else - { - topmostWindow = GetTopmostModalWindow(); - - if (topmostWindow != null) - topmostWindow.MoveToContainer(modalCanvas); - } - - SetFocusToActiveWindow(topmostWindow); - } - } - - /// <summary> - /// Moves the window to the "modal" layer. - /// </summary> - /// <param name="modalWindow">The modal window.</param> - private void MoveWindowToModalLayer(FloatingWindow modalWindow) - { - FloatingWindow window = this.ModalWindow; - if (window != null && window != modalWindow) - { - // If there is already a modal window - move it to the HostCanvas - window.MoveToContainer(hostCanvas); - SetTopmost(window); - } - - modalWindow.MoveToContainer(modalCanvas); - } - - /// <summary> - /// Raises the <see cref="FloatingWindowHost.ActiveWindowChanged" /> event. - /// </summary> - /// <param name="e">The event data.</param> - protected virtual void OnActiveWindowChanged(ActiveWindowChangedEventArgs e) - { - EventHandler<ActiveWindowChangedEventArgs> handler = ActiveWindowChanged; - - if (handler != null) - handler(this, e); - } - - /// <summary> - /// Shows a floating window when the layout is updated. - /// </summary> - /// <param name="action">A method that displays a window in the specified coordinates.</param> - /// <param name="point">Coordinates of the upper-left corner of the window.</param> - internal void ShowWindow(Action<Point> action, Point point) - { - if (IsLayoutUpdated) - { - action(point); - } - else - { - this.Rendered += (s, e) => { action(point); }; - } - } - - /// <summary> - /// Shows a floating window when the layout is updated. - /// </summary> - /// <param name="action">A method that displays a window taking into account specified margins.</param> - /// <param name="margins">Window margins.</param> - internal void ShowWindow(Action<Thickness> action, Thickness margins) - { - if (IsLayoutUpdated) - { - action(margins); - } - else - { - this.Rendered += (s, e) => { action(margins); }; - - } - } - - /// <summary> - /// Subscribes to the events on the template parts. - /// </summary> - private void SubscribeToTemplatePartEvents() - { - bootstrapButton.Click += new RoutedEventHandler(BootstrapButton_Click); - iconBar.Opened += new EventHandler(IconBarVisibilityChanged); - iconBar.Closed += new EventHandler(IconBarVisibilityChanged); - hostCanvas.SizeChanged += new SizeChangedEventHandler(HostCanvas_SizeChanged); - modalCanvas.SizeChanged += new SizeChangedEventHandler(ModalCanvas_SizeChanged); - iconBarContainer.SizeChanged += new SizeChangedEventHandler(IconBarContainer_SizeChanged); - } - - /// <summary> - /// Unsubscribe from the events that are subscribed on the template part elements. - /// </summary> - private void UnsubscribeFromTemplatePartEvents() - { - if (bootstrapButton != null) - bootstrapButton.Click -= new RoutedEventHandler(BootstrapButton_Click); - - if (iconBar != null) - iconBar.Opened -= new EventHandler(IconBarVisibilityChanged); - - if (iconBar != null) - iconBar.Closed -= new EventHandler(IconBarVisibilityChanged); - - if (hostCanvas != null) - hostCanvas.SizeChanged -= new SizeChangedEventHandler(HostCanvas_SizeChanged); - - if (modalCanvas != null) - modalCanvas.SizeChanged -= new SizeChangedEventHandler(ModalCanvas_SizeChanged); - - if (iconBarContainer != null) - iconBarContainer.SizeChanged -= new SizeChangedEventHandler(IconBarContainer_SizeChanged); - } - - /// <summary> - /// Subscribes to the events the control shall handle. - /// </summary> - private void SubscribeToEvents() - { - this.MouseLeftButtonDown += new MouseButtonEventHandler(FloatingWindowHost_MouseLeftButtonDown); - this.LayoutUpdated += new EventHandler(FloatingWindowHost_LayoutUpdated); - } - - /// <summary> - /// Unsubscribes from the subscribed events. - /// </summary> - private void UnsubscribeFromEvents() - { - this.MouseLeftButtonDown -= new MouseButtonEventHandler(FloatingWindowHost_MouseLeftButtonDown); - this.LayoutUpdated -= new EventHandler(FloatingWindowHost_LayoutUpdated); - } - - /// <summary> - /// Handles the first LayoutUpdated event of the FloatingWindowHost control to raise the OnRendered event. - /// </summary> - /// <param name="sender">The source of the event.</param> - /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param> - private void FloatingWindowHost_LayoutUpdated(object sender, EventArgs e) - { - if (!IsLayoutUpdated) - { - this.LayoutUpdated -= new EventHandler(FloatingWindowHost_LayoutUpdated); - IsLayoutUpdated = true; - OnRendered(EventArgs.Empty); - } - } - - /// <summary> - /// Raises the <see cref="E:Rendered"/> event. - /// Occures when the control template is applied and the control can be rendered. - /// </summary> - /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param> - protected virtual void OnRendered(EventArgs e) - { - EventHandler handler = Rendered; - - if (handler != null) - handler(this, e); - } - - /// <summary> - /// Gets the topmost open FloatingWindow. - /// </summary> - /// <returns>The topmost open FloatingWindow.</returns> - private FloatingWindow GetTopmostWindow() - { - var topmost = (from window in FloatingWindows - where !window.TopMost && window.IsOpen && window.WindowState != WindowState.Minimized - select new - { - Window = window, - ZIndex = Canvas.GetZIndex(window) - } - ).ToList().OrderBy(x => x.ZIndex).LastOrDefault(); - - return topmost != null ? topmost.Window : null; - } - - /// <summary> - /// Gets the topmost modal FloatingWindow on the HostCanvas. - /// </summary> - /// <returns>The topmost modal FloatingWindow.</returns> - private FloatingWindow GetTopmostModalWindow() - { - var topmost = (from window in FloatingWindows - where window.IsModal && window.IsOpen - select new - { - Window = window, - ZIndex = Canvas.GetZIndex(window) - } - ).ToList().OrderBy(x => x.ZIndex).LastOrDefault(); - - return topmost != null ? topmost.Window : null; - } - - /// <summary> - /// Shows the topmost windows in front of other windows. - /// </summary> - private void ShowTopmostWindows() - { - FloatingWindows - .Where(x => x.IsOpen && x.TopMost).ToList() - .ForEach(x => SetTopmost(x)); - } - - /// <summary> - /// Sets the specified UIElement topmost. - /// </summary> - /// <param name="element">UIElement to set topmost.</param> - /// <exception cref="ArgumentNullException">UIElement is null.</exception> - private void SetTopmost(UIElement element) - { - if (element == null) - throw new ArgumentNullException("element"); - - zIndex++; - Canvas.SetZIndex(element, zIndex); - } - - /// <summary> - /// Attempts to set the focus on the FloatingWindow. - /// </summary> - /// <param name="window">The window.</param> - private void SetFocusToActiveWindow(FloatingWindow window) - { - if (window != null && !window.TopMost) - window.Focus(); - } - - /// <summary> - /// Handles the MouseLeftButtonDown event of the FloatingWindowHost control. - /// Closes the IconBar on mouse left click. - /// </summary> - /// <param name="sender">The source of the event.</param> - /// <param name="e">The <see cref="System.Windows.Input.MouseButtonEventArgs"/> instance containing the event data.</param> - private void FloatingWindowHost_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) - { - e.Handled = false; - HideIconBar(); - } - - /// <summary> - /// Handles the Click event of the BootstrapButton. - /// </summary> - /// <param name="sender">The source of the event.</param> - /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param> - private void BootstrapButton_Click(object sender, RoutedEventArgs e) - { - if (bootstrapButton.IsOpen) - ShowIconBar(); - else - HideIconBar(); - } - - /// <summary> - /// Handles the IconBar Visibility Changed event. - /// </summary> - /// <param name="sender">The sender.</param> - /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param> - private void IconBarVisibilityChanged(object sender, EventArgs e) - { - bootstrapButton.IsOpen = iconBar.IsOpen; - } - - /// <summary> - /// Handles the SizeChanged event of the HostCanvas control to set its clipping region. - /// </summary> - /// <param name="sender">The source of the event.</param> - /// <param name="e">The <see cref="System.Windows.SizeChangedEventArgs"/> instance containing the event data.</param> - private void HostCanvas_SizeChanged(object sender, SizeChangedEventArgs e) - { - hostCanvas.Clip = new RectangleGeometry() - { - Rect = hostCanvas.GetActualBoundingRectangle() - }; - } - - /// <summary> - /// Handles the SizeChanged event of the ModalCanvas control to set its clipping region. - /// </summary> - /// <param name="sender">The source of the event.</param> - /// <param name="e">The <see cref="System.Windows.SizeChangedEventArgs"/> instance containing the event data.</param> - private void ModalCanvas_SizeChanged(object sender, SizeChangedEventArgs e) - { - modalCanvas.Clip = new RectangleGeometry() - { - Rect = modalCanvas.GetActualBoundingRectangle() - }; - } - - /// <summary> - /// Handles the SizeChanged event of the IconBarContainer control to set its clipping region. - /// </summary> - /// <param name="sender">The source of the event.</param> - /// <param name="e">The <see cref="System.Windows.SizeChangedEventArgs"/> instance containing the event data.</param> - private void IconBarContainer_SizeChanged(object sender, SizeChangedEventArgs e) - { - iconBarContainer.Clip = new RectangleGeometry() - { - Rect = iconBarContainer.GetActualBoundingRectangle() - }; - } - - /// <summary> - /// Sets styles that are applied for different template parts. - /// </summary> - private void SetStyles() - { - if (bottomBar != null && this.BottomBarStyle != null) - bottomBar.Style = this.BottomBarStyle; - - if (bootstrapButton != null && this.BootstrapButtonStyle != null) - bootstrapButton.Style = this.BootstrapButtonStyle; - - if (iconBar != null && this.WindowIconStyle != null) - iconBar.WindowIconStyle = this.WindowIconStyle; - } - - /// <summary> - /// Gets the FrameworkElement template part with the specified name. - /// </summary> - /// <typeparam name="T">The template part type.</typeparam> - /// <param name="partName">The template part name.</param> - /// <returns>The requested element.</returns> - /// <exception cref="NotImplementedException">The template part not found.</exception> - private T GetTemplatePart<T>(string partName) where T : class - { - T part = this.GetTemplateChild(partName) as T; - - if (part == null) - throw new NotImplementedException(string.Format(CultureInfo.InvariantCulture, "Template Part {0} is required.", partName)); - - return part; - } - } -}
--- a/SilverlightGlimpse/SilverFlow.Controls/FloatingWindow/IconBar.cs Mon Apr 23 11:05:11 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,527 +0,0 @@ -using System; -using System.Collections.ObjectModel; -using System.ComponentModel; -using System.Globalization; -using System.Linq; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Input; -using System.Windows.Media.Animation; -using SilverFlow.Controls.Extensions; -using SilverFlow.Controls.Helpers; - -namespace SilverFlow.Controls -{ - /// <summary> - /// IconBar containing window icons. - /// </summary> - [TemplatePart(Name = PART_LayoutRoot, Type = typeof(FrameworkElement))] - [TemplatePart(Name = PART_FixedBar, Type = typeof(Border))] - [TemplatePart(Name = PART_SlidingBar, Type = typeof(Border))] - [TemplatePart(Name = PART_Carousel, Type = typeof(StackPanel))] - [TemplateVisualState(Name = VSMSTATE_StateOpen, GroupName = VSMGROUP_States)] - [TemplateVisualState(Name = VSMSTATE_StateClosed, GroupName = VSMGROUP_States)] - [StyleTypedProperty(Property = PROPERTY_TitleStyle, StyleTargetType = typeof(Border))] - [StyleTypedProperty(Property = PROPERTY_WindowIconStyle, StyleTargetType = typeof(WindowIcon))] - public class IconBar : ContentControl, INotifyPropertyChanged - { - // Template parts - private const string PART_LayoutRoot = "PART_LayoutRoot"; - private const string PART_FixedBar = "PART_FixedBar"; - private const string PART_SlidingBar = "PART_SlidingBar"; - private const string PART_Carousel = "PART_Carousel"; - - // VSM groups - private const string VSMGROUP_States = "VisualStateGroup"; - - // VSM states - private const string VSMSTATE_StateOpen = "Open"; - private const string VSMSTATE_StateClosed = "Closed"; - - // Style typed properties - private const string PROPERTY_TitleStyle = "IconBarStyle"; - private const string PROPERTY_WindowIconStyle = "WindowIconStyle"; - - // Animation duration in milliseconds - private const double SlidingDurationInMilliseconds = 200; - - #region public Style IconBarStyle - - /// <summary> - /// Gets or sets the style of the IconBar. - /// </summary> - public Style IconBarStyle - { - get { return GetValue(IconBarStyleProperty) as Style; } - set { SetValue(IconBarStyleProperty, value); } - } - - /// <summary> - /// Identifies the <see cref="IconBar.IconBarStyleProperty" /> dependency property. - /// </summary> - public static readonly DependencyProperty IconBarStyleProperty = - DependencyProperty.Register( - "IconBarStyle", - typeof(Style), - typeof(IconBar), - new PropertyMetadata(IconBarStylePropertyChanged)); - - /// <summary> - /// IconBarStyle PropertyChangedCallback call back static function. - /// </summary> - /// <param name="d">IconBar object whose IconBarStyle property is changed.</param> - /// <param name="e">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param> - private static void IconBarStylePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - IconBar iconBar = (IconBar)d; - if (iconBar != null && iconBar.fixedBar != null) - { - iconBar.fixedBar.Style = e.NewValue as Style; - } - } - - #endregion - - #region public Style WindowIconStyle - - /// <summary> - /// Gets or sets the style of the WindowIcon. - /// </summary> - public Style WindowIconStyle - { - get { return GetValue(WindowIconStyleProperty) as Style; } - set { SetValue(WindowIconStyleProperty, value); } - } - - /// <summary> - /// Identifies the <see cref="IconBar.WindowIconStyleProperty" /> dependency property. - /// </summary> - public static readonly DependencyProperty WindowIconStyleProperty = - DependencyProperty.Register( - "WindowIconStyle", - typeof(Style), - typeof(IconBar), - null); - - #endregion - - private FrameworkElement layoutRoot; - private Border fixedBar; - private Border slidingBar; - private StackPanel carousel; - private Storyboard closingStoryboard; - private Storyboard openingStoryboard; - private bool isOpen; - private double slidingBarPosition; - private IVisualHelper visualHelper; - - /// <summary> - /// Gets or sets a value indicating whether the IconBar is open. - /// </summary> - /// <value><c>true</c> if the IconBar is open; otherwise, <c>false</c>.</value> - public bool IsOpen - { - get { return isOpen; } - private set - { - if (value != isOpen) - { - isOpen = value; - OnPropertyChanged(new PropertyChangedEventArgs("IsOpen")); - } - } - } - - /// <summary> - /// Gets or sets the FloatingWindowHost containing the IconBar. - /// </summary> - /// <value>FloatingWindowHost containing the IconBar.</value> - public FloatingWindowHost FloatingWindowHost { get; set; } - - /// <summary> - /// Initializes a new instance of the <see cref="IconBar"/> class. - /// </summary> - public IconBar() - { - DefaultStyleKey = typeof(IconBar); - visualHelper = new VisualHelper(); - } - - /// <summary> - /// Occurs when the <see cref="IconBar" /> is opened. - /// </summary> - public event EventHandler Opened; - - /// <summary> - /// Occurs when the <see cref="IconBar" /> is closed. - /// </summary> - public event EventHandler Closed; - - #region INotifyPropertyChanged implementation - /// <summary> - /// Occurs when a property changed. - /// </summary> - public event PropertyChangedEventHandler PropertyChanged; - - /// <summary> - /// Raises the <see cref="E:PropertyChanged"/> event. - /// </summary> - /// <param name="e">The <see cref="System.ComponentModel.PropertyChangedEventArgs"/> instance containing the event data.</param> - public void OnPropertyChanged(PropertyChangedEventArgs e) - { - if (PropertyChanged != null) - PropertyChanged(this, e); - } - #endregion - - /// <summary> - /// Builds the visual tree for the <see cref="IconBar" /> control - /// when a new template is applied. - /// </summary> - public override void OnApplyTemplate() - { - UnsubscribeFromEvents(); - - base.OnApplyTemplate(); - - layoutRoot = GetTemplatePart<FrameworkElement>(PART_LayoutRoot); - fixedBar = GetTemplatePart<Border>(PART_FixedBar); - slidingBar = GetTemplatePart<Border>(PART_SlidingBar); - carousel = GetTemplatePart<StackPanel>(PART_Carousel); - - SetStyles(); - GetStoryboards(); - SubscribeToEvents(); - } - - /// <summary> - /// Shows the IconBar. - /// </summary> - public void Show() - { - if (!IsOpen) - { - FillCarousel(); - SetSlidingBarPosition(0); - VisualStateManager.GoToState(this, VSMSTATE_StateOpen, true); - } - } - - /// <summary> - /// Hides the IconBar. - /// </summary> - public void Hide() - { - if (IsOpen) - { - VisualStateManager.GoToState(this, VSMSTATE_StateClosed, true); - } - } - - /// <summary> - /// Updates the IconBar if it is open. - /// </summary> - public void Update() - { - if (IsOpen) - { - FillCarousel(); - } - } - - /// <summary> - /// Removes the specified window from the IconBar. - /// </summary> - /// <param name="window">The window to remove from the IconBar.</param> - public void Remove(FloatingWindow window) - { - if (window != null) - { - var icon = (from windowIcon in carousel.Children.OfType<WindowIcon>() - where windowIcon.Window == window - select windowIcon).FirstOrDefault(); - - if (icon != null) - { - icon.Click -= new RoutedEventHandler(Icon_Click); - carousel.Children.Remove(icon); - } - } - } - - /// <summary> - /// Gets the storyboards defined in the <see cref="IconBar" /> style. - /// </summary> - private void GetStoryboards() - { - var groups = VisualStateManager.GetVisualStateGroups(layoutRoot) as Collection<VisualStateGroup>; - if (groups != null) - { - var states = (from stategroup in groups - where stategroup.Name == IconBar.VSMGROUP_States - select stategroup.States).FirstOrDefault() as Collection<VisualState>; - - if (states != null) - { - openingStoryboard = (from state in states - where state.Name == IconBar.VSMSTATE_StateOpen - select state.Storyboard).FirstOrDefault(); - - closingStoryboard = (from state in states - where state.Name == IconBar.VSMSTATE_StateClosed - select state.Storyboard).FirstOrDefault(); - } - } - } - - /// <summary> - /// Subscribes to the events after new template is applied. - /// </summary> - private void SubscribeToEvents() - { - if (closingStoryboard != null) - closingStoryboard.Completed += new EventHandler(Closing_Completed); - - if (openingStoryboard != null) - openingStoryboard.Completed += new EventHandler(Opening_Completed); - - if (fixedBar != null) - fixedBar.MouseMove += new MouseEventHandler(Bar_MouseMove); - - if (fixedBar != null) - fixedBar.SizeChanged += new SizeChangedEventHandler(FixedBar_SizeChanged); - } - - /// <summary> - /// Unsubscribe from events. - /// </summary> - private void UnsubscribeFromEvents() - { - if (closingStoryboard != null) - closingStoryboard.Completed -= new EventHandler(Closing_Completed); - - if (openingStoryboard != null) - openingStoryboard.Completed -= new EventHandler(Opening_Completed); - - if (fixedBar != null) - fixedBar.MouseMove += new MouseEventHandler(Bar_MouseMove); - - if (fixedBar != null) - fixedBar.SizeChanged -= new SizeChangedEventHandler(FixedBar_SizeChanged); - } - - /// <summary> - /// Sets styles that are applied for different template parts. - /// </summary> - private void SetStyles() - { - if (fixedBar != null && this.IconBarStyle != null) - fixedBar.Style = this.IconBarStyle; - } - - /// <summary> - /// Executed when the Closing storyboard ends. - /// </summary> - /// <param name="sender">Sender object.</param> - /// <param name="e">Event args.</param> - private void Closing_Completed(object sender, EventArgs e) - { - IsOpen = false; - ClearCarousel(); - OnClosed(EventArgs.Empty); - } - - /// <summary> - /// Executed when the Opening storyboard finishes. - /// </summary> - /// <param name="sender">Sender object.</param> - /// <param name="e">Event args.</param> - private void Opening_Completed(object sender, EventArgs e) - { - IsOpen = true; - OnOpened(EventArgs.Empty); - } - - /// <summary> - /// Raises the <see cref="E:Opened"/> event. - /// </summary> - /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param> - protected virtual void OnOpened(EventArgs e) - { - EventHandler handler = Opened; - - if (handler != null) - handler(this, e); - } - - /// <summary> - /// Raises the <see cref="E:Closed"/> event. - /// </summary> - /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param> - protected virtual void OnClosed(EventArgs e) - { - EventHandler handler = Closed; - - if (handler != null) - handler(this, e); - } - - /// <summary> - /// Add windows icons to the carousel. - /// </summary> - private void FillCarousel() - { - ClearCarousel(); - - Style style = this.WindowIconStyle ?? Application.Current.Resources["WindowIconStyle"] as Style; - foreach (var window in this.FloatingWindowHost.WindowsInIconBar) - { - WindowIcon icon = new WindowIcon() - { - Style = style, - Title = window.IconText, - Thumbnail = window.WindowThumbnail, - FlowDirection = window.FlowDirection, - Window = window, - IconWidth = this.FloatingWindowHost.IconWidth, - IconHeight = this.FloatingWindowHost.IconHeight - }; - - icon.Click += new RoutedEventHandler(Icon_Click); - carousel.Children.Add(icon); - } - } - - /// <summary> - /// Remove Icon Click event handlers and clear the carousel. - /// </summary> - private void ClearCarousel() - { - foreach (var icon in carousel.Children.OfType<WindowIcon>()) - { - icon.Click -= new RoutedEventHandler(Icon_Click); - } - - carousel.Children.Clear(); - } - - /// <summary> - /// Handles the Click event of the Icon control. - /// </summary> - /// <param name="sender">The source of the event.</param> - /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param> - private void Icon_Click(object sender, RoutedEventArgs e) - { - WindowIcon icon = sender as WindowIcon; - - if (icon != null && icon.Window != null) - { - this.Hide(); - icon.Window.RestoreWindow(); - } - } - - /// <summary> - /// Handles the MouseMove event of the Bar control. It implements "Carousel" logic. - /// </summary> - /// <param name="sender">The source of the event.</param> - /// <param name="e">The <see cref="System.Windows.Input.MouseEventArgs"/> instance containing the event data.</param> - private void Bar_MouseMove(object sender, MouseEventArgs e) - { - // Get absolute mouse position - Point mousePosition = e.GetPosition(null); - - var icon = carousel.Children.OfType<WindowIcon>().FirstOrDefault(); - - // If there is at least one icon on the bar - if (icon != null) - { - double a = e.GetPosition(fixedBar).X; - double b = fixedBar.ActualWidth - fixedBar.Padding.Horizontal(); - double c = slidingBar.ActualWidth; - - // If sliding bar does not fit into the bar, shift the sliding bar - if (c > b) - { - double width = b - icon.ActualWidth; - if (width != 0) - { - a -= icon.ActualWidth / 2; - if (a < 0) a = 0; - if (a > width) a = width; - - double x = Math.Round((a / width) * (b - c)); - - if (x != slidingBarPosition) - { - Storyboard storyboard = slidingBar.AnimateDoubleProperty("(Canvas.Left)", null, x, SlidingDurationInMilliseconds); - storyboard.Completed += (s, args) => - { - // Select an icon on storyboard completion - // That is necessary because MouseOver state won't be proceeded correctly - SlidingBarStoryboardCompleted(mousePosition); - slidingBarPosition = x; - }; - } - } - } - } - } - - /// <summary> - /// Handles the Completed event of the SlidingBarStoryboard control. - /// </summary> - /// <param name="mousePosition">Absolute mouse position.</param> - private void SlidingBarStoryboardCompleted(Point mousePosition) - { - // Find selected icon - var selectedIcon = (from item in visualHelper.FindElementsInCoordinates(mousePosition, carousel).OfType<WindowIcon>() - select item).FirstOrDefault(); - - // Select an icon in mouse position - foreach (var icon in carousel.Children.OfType<WindowIcon>()) - { - icon.Selected = selectedIcon != null && icon == selectedIcon; - } - } - - /// <summary> - /// Handles the SizeChanged event of the FixedBar control. - /// Sets the initial position of the sliding bar. - /// </summary> - /// <param name="sender">The source of the event.</param> - /// <param name="e">The <see cref="System.Windows.SizeChangedEventArgs"/> instance containing the event data.</param> - private void FixedBar_SizeChanged(object sender, SizeChangedEventArgs e) - { - if (slidingBarPosition != 0) - SetSlidingBarPosition(0); - } - - /// <summary> - /// Sets the sliding bar position. - /// </summary> - /// <param name="position">X-coordinate of the sliding bar.</param> - private void SetSlidingBarPosition(double x) - { - slidingBarPosition = x; - Canvas.SetLeft(slidingBar, slidingBarPosition); - } - - /// <summary> - /// Gets the FrameworkElement template part with the specified name. - /// </summary> - /// <typeparam name="T">The template part type.</typeparam> - /// <param name="partName">The template part name.</param> - /// <returns>The requested element.</returns> - /// <exception cref="NotImplementedException">The template part not found.</exception> - private T GetTemplatePart<T>(string partName) where T : class - { - T part = this.GetTemplateChild(partName) as T; - - if (part == null) - throw new NotImplementedException(string.Format(CultureInfo.InvariantCulture, "Template Part {0} is required.", partName)); - - return part; - } - } -}
--- a/SilverlightGlimpse/SilverFlow.Controls/FloatingWindow/WindowIcon.cs Mon Apr 23 11:05:11 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,210 +0,0 @@ -using System; -using System.Globalization; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Media; -using SilverFlow.Controls.Extensions; - -namespace SilverFlow.Controls -{ - /// <summary> - /// Window icon containing a thumbnail and title of the windows. - /// </summary> - [TemplatePart(Name = PART_Border, Type = typeof(Border))] - [TemplatePart(Name = PART_Title, Type = typeof(TextBlock))] - [TemplatePart(Name = PART_Thumbnail, Type = typeof(Image))] - [StyleTypedProperty(Property = PROPERTY_IconBorderStyle, StyleTargetType = typeof(Border))] - public class WindowIcon : Button - { - // Template parts - private const string PART_Border = "PART_Border"; - private const string PART_Title = "PART_Title"; - private const string PART_Thumbnail = "PART_Thumbnail"; - - // VSM states - private const string VSMSTATE_StateNormal = "Normal"; - private const string VSMSTATE_StateMouseOver = "MouseOver"; - - // Style typed properties - private const string PROPERTY_IconBorderStyle = "IconBorderStyle"; - - #region public Style IconBorderStyle - - /// <summary> - /// Gets or sets the style of the WindowIcon. - /// </summary> - public Style IconBorderStyle - { - get { return GetValue(IconBorderStyleProperty) as Style; } - set { SetValue(IconBorderStyleProperty, value); } - } - - /// <summary> - /// Identifies the <see cref="IconBar.IconBorderStyleProperty" /> dependency property. - /// </summary> - public static readonly DependencyProperty IconBorderStyleProperty = - DependencyProperty.Register( - "IconBorderStyle", - typeof(Style), - typeof(WindowIcon), - new PropertyMetadata(IconBorderStylePropertyChanged)); - - /// <summary> - /// IconBorderStyle PropertyChangedCallback call back static function. - /// </summary> - /// <param name="d">WindowIcon object whose IconBorderStyle property is changed.</param> - /// <param name="e">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param> - private static void IconBorderStylePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - WindowIcon windowIcon = (WindowIcon)d; - if (windowIcon != null && windowIcon.border != null) - { - windowIcon.border.Style = e.NewValue as Style; - } - } - - #endregion - - #region public double IconWidth - - /// <summary> - /// Gets or sets the width of the window's icon. - /// </summary> - /// <value>The width of the window's icon.</value> - public double IconWidth - { - get { return (double)GetValue(IconWidthProperty); } - set { SetValue(IconWidthProperty, value); } - } - - /// <summary> - /// Identifies the <see cref="WindowIcon.IconWidth" /> dependency property. - /// </summary> - /// <value> - /// The identifier for the <see cref="WindowIcon.IconWidth" /> dependency property. - /// </value> - public static readonly DependencyProperty IconWidthProperty = - DependencyProperty.Register( - "IconWidth", - typeof(double), - typeof(WindowIcon), - null); - - #endregion - - #region public double IconHeight - - /// <summary> - /// Gets or sets the height of the window's icon. - /// </summary> - /// <value>The height of the window's icon.</value> - public double IconHeight - { - get { return (double)GetValue(IconHeightProperty); } - set { SetValue(IconHeightProperty, value); } - } - - /// <summary> - /// Identifies the <see cref="WindowIcon.IconHeight" /> dependency property. - /// </summary> - /// <value> - /// The identifier for the <see cref="WindowIcon.IconHeight" /> dependency property. - /// </value> - public static readonly DependencyProperty IconHeightProperty = - DependencyProperty.Register( - "IconHeight", - typeof(double), - typeof(WindowIcon), - null); - - #endregion - - private Border border; - private TextBlock title; - private Image thumbnail; - private bool selected; - - /// <summary> - /// Gets or sets the window title that is displayed on the icon />. - /// </summary> - /// <value>The title displayed on the icon.</value> - public string Title { get; set; } - - /// <summary> - /// Gets or sets the thumbnail. - /// </summary> - /// <value>The thumbnail.</value> - public ImageSource Thumbnail { get; set; } - - /// <summary> - /// Gets or sets the FloatingWindow associated with the icon. - /// </summary> - /// <value>Floating window.</value> - public FloatingWindow Window { get; set; } - - /// <summary> - /// Gets or sets a value indicating whether this <see cref="WindowIcon"/> is selected. - /// </summary> - /// <value><c>true</c> if selected; otherwise, <c>false</c>.</value> - public bool Selected - { - get { return selected; } - set - { - if (value != selected) - { - selected = value; - VisualStateManager.GoToState( - this, - value ? VSMSTATE_StateMouseOver : VSMSTATE_StateNormal, - true); - } - } - } - - /// <summary> - /// Builds the visual tree for the <see cref="WindowIcon" /> control - /// when a new template is applied. - /// </summary> - public override void OnApplyTemplate() - { - base.OnApplyTemplate(); - - border = GetTemplatePart<Border>(PART_Border); - title = GetTemplatePart<TextBlock>(PART_Title); - thumbnail = GetTemplatePart<Image>(PART_Thumbnail); - - SetStyles(); - - title.Text = Title; - title.FlowDirection = this.FlowDirection; - thumbnail.Source = Thumbnail; - } - - /// <summary> - /// Sets styles that are applied for different template parts. - /// </summary> - private void SetStyles() - { - if (border != null && this.IconBorderStyle != null) - border.Style = this.IconBorderStyle; - } - - /// <summary> - /// Gets the FrameworkElement template part with the specified name. - /// </summary> - /// <typeparam name="T">The template part type.</typeparam> - /// <param name="partName">The template part name.</param> - /// <returns>The requested element.</returns> - /// <exception cref="NotImplementedException">The template part not found.</exception> - private T GetTemplatePart<T>(string partName) where T : class - { - T part = this.GetTemplateChild(partName) as T; - - if (part == null) - throw new NotImplementedException(string.Format(CultureInfo.InvariantCulture, "Template Part {0} is required.", partName)); - - return part; - } - } -}
--- a/SilverlightGlimpse/SilverFlow.Controls/Geometry/Distance.cs Mon Apr 23 11:05:11 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -using SilverFlow.Controls.Extensions; - -namespace SilverFlow.Geometry -{ - /// <summary> - /// Defines displacement used for correction of window position or size. - /// </summary> - public class Distance - { - /// <summary> - /// Gets or sets displacement by X coordinate. - /// </summary> - /// <value>Displacement by X coordinate.</value> - public double X { get; set; } - - /// <summary> - /// Gets or sets displacement by Y coordinate. - /// </summary> - /// <value>Displacement by Y coordinate.</value> - public double Y { get; set; } - - /// <summary> - /// Gets a value indicating whether this instance is nonzero. - /// </summary> - /// <value> - /// <c>true</c> if this instance is nonzero; otherwise, <c>false</c>. - /// </value> - public bool IsNonzero - { - get - { - return !double.IsNaN(X) && !double.IsNaN(Y) && (X != 0 || Y != 0); - } - } - - /// <summary> - /// Initializes a new instance of the <see cref="Distance"/> class. - /// </summary> - public Distance() - { - X = double.NaN; - Y = double.NaN; - } - - /// <summary> - /// Initializes a new instance of the <see cref="Distance"/> class. - /// </summary> - /// <param name="x">Displacement by X coordinate.</param> - /// <param name="y">Displacement by Y coordinate.</param> - public Distance(double x, double y) - { - X = x; - Y = y; - } - - /// <summary> - /// Gets the smallest of two distances. - /// </summary> - /// <param name="first">First distance.</param> - /// <param name="second">Second distance.</param> - /// <returns>Smallest distance.</returns> - public static Distance Min(Distance first, Distance second) - { - Distance distance = new Distance - { - X = MathExtensions.AbsMin(first.X, second.X), - Y = MathExtensions.AbsMin(first.Y, second.Y) - }; - - return distance; - } - } -}
--- a/SilverlightGlimpse/SilverFlow.Controls/Geometry/Trail.cs Mon Apr 23 11:05:11 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -using System; -using System.Windows; - -namespace SilverFlow.Geometry -{ - /// <summary> - /// Mouse pointer trail. - /// </summary> - public class Trail - { - /// <summary> - /// Gets or sets mouse position. - /// </summary> - /// <value>The position.</value> - public Point Position { get; set; } - - /// <summary> - /// Gets or sets the timestamp. - /// </summary> - /// <value>The timestamp.</value> - public DateTime Timestamp { get; set; } - - /// <summary> - /// Initializes a new instance of the <see cref="Trail"/> class. - /// </summary> - public Trail() - { - } - - /// <summary> - /// Initializes a new instance of the <see cref="Trail"/> class. - /// </summary> - /// <param name="point">Point.</param> - /// <param name="time">Time.</param> - public Trail(Point point, DateTime time) - { - this.Position = point; - this.Timestamp = time; - } - } -}
--- a/SilverlightGlimpse/SilverFlow.Controls/Geometry/Vector2.cs Mon Apr 23 11:05:11 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,156 +0,0 @@ -using System; -using System.Windows; -using SilverFlow.Controls.Extensions; - -namespace SilverFlow.Geometry -{ - /// <summary> - /// Defines two-dimensional vector. - /// </summary> - public class Vector2 - { - /// <summary> - /// Gets or sets the starting point of the vector. - /// </summary> - /// <value>The starting point.</value> - public Point Start { get; set; } - - /// <summary> - /// Gets or sets the ending point of the vector. - /// </summary> - /// <value>The ending point.</value> - public Point End { get; set; } - - /// <summary> - /// Gets a value indicating whether this instance is not set. - /// </summary> - /// <value><c>true</c> if this instance is not set; otherwise, <c>false</c>.</value> - public bool IsNaN - { - get - { - return this.Start.IsNotSet() || this.End.IsNotSet(); - } - } - - /// <summary> - /// Gets a value indicating whether the vector is of zero length. - /// </summary> - /// <value><c>true</c> if the vector is of zero length; otherwise, <c>false</c>.</value> - public bool IsZero - { - get - { - return this.IsNaN ? true : this.Start == this.End; - } - } - - /// <summary> - /// Gets a value indicating whether the vector is vertical. - /// </summary> - /// <value> - /// <c>true</c> if the vector is vertical; otherwise, <c>false</c>. - /// </value> - public bool IsVertical - { - get - { - return !this.IsZero && (this.Start.X == this.End.X); - } - } - - /// <summary> - /// Gets a value indicating whether the vector is horizontal. - /// </summary> - /// <value> - /// <c>true</c> if the vector is horizontal; otherwise, <c>false</c>. - /// </value> - public bool IsHorizontal - { - get - { - return !this.IsZero && (this.Start.Y == this.End.Y); - } - } - - /// <summary> - /// Gets the length of the vector by X-coordinate. - /// </summary> - /// <value>The length by X-coordinate.</value> - public double LengthX - { - get - { - return this.IsNaN ? 0 : (this.End.X - this.Start.X); - } - } - - /// <summary> - /// Gets the length of the vector by Y-coordinate. - /// </summary> - /// <value>The length by Y-coordinate.</value> - public double LengthY - { - get - { - return this.IsNaN ? 0 : (this.End.Y - this.Start.Y); - } - } - - /// <summary> - /// Gets the length of the vector. - /// </summary> - /// <value>The length of the vector.</value> - public double Length - { - get - { - if (this.IsNaN) - return 0; - - return Math.Sqrt(LengthX * LengthX + LengthY * LengthY); - } - } - - /// <summary> - /// Initializes a new instance of the <see cref="Vector2"/> class. - /// </summary> - public Vector2() - { - } - - /// <summary> - /// Initializes a new instance of the <see cref="Vector2"/> class. - /// </summary> - /// <param name="start">The starting point.</param> - /// <param name="end">The ending point.</param> - public Vector2(Point start, Point end) - { - this.Start = start; - this.End = end; - } - - /// <summary> - /// Initializes a new instance of the <see cref="Vector2"/> class. - /// </summary> - /// <param name="start">The starting point.</param> - /// <param name="lengthX">The length by X-coordinate.</param> - /// <param name="lengthY">The length by Y-coordinate.</param> - public Vector2(Point start, double lengthX, double lengthY) - { - this.Start = start; - this.End = start.Add(lengthX, lengthY); - } - - /// <summary> - /// Rounds starting and ending points to the nearest integer coordinates. - /// </summary> - /// <returns>Vector with rounded coordinates.</returns> - public Vector2 Round() - { - this.Start = this.Start.Round(); - this.End = this.End.Round(); - return this; - } - } -}
--- a/SilverlightGlimpse/SilverFlow.Controls/Helpers/BitmapHelper.cs Mon Apr 23 11:05:11 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +0,0 @@ -using System; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using SilverFlow.Controls.Extensions; - -namespace SilverFlow.Controls.Helpers -{ - /// <summary> - /// Bitmap helper. - /// </summary> - public class BitmapHelper : IBitmapHelper - { - /// <summary> - /// Renders the visual element and returns a bitmap, containing bitmap image of the element. - /// </summary> - /// <param name="element">The visual element.</param> - /// <param name="imageWidth">Image width.</param> - /// <param name="imageHeight">Image height.</param> - /// <returns>Bitmap image of the element.</returns> - public ImageSource RenderVisual(FrameworkElement element, double imageWidth, double imageHeight) - { - int width = element.Width.IsNotSet() ? (int)element.ActualWidth : (int)element.Width; - int height = element.Height.IsNotSet() ? (int)element.ActualHeight : (int)element.Height; - - ScaleTransform transform = null; - - // If the element is an image - do not scale it - if (!(element is Image)) - { - // Scale down the element to fit it into the window's thumbnail - double scaleX = imageWidth / width; - double scaleY = imageHeight / height; - double minScale = Math.Min(scaleX, scaleY); - - if (minScale < 1) - { - transform = new ScaleTransform - { - ScaleX = minScale, - ScaleY = minScale - }; - - width = (int)(width * minScale); - height = (int)(height * minScale); - } - } - - WriteableBitmap bitmap = new WriteableBitmap(width, height); - bitmap.Render(element, transform); - bitmap.Invalidate(); - - return bitmap; - } - } -}
--- a/SilverlightGlimpse/SilverFlow.Controls/Helpers/IBitmapHelper.cs Mon Apr 23 11:05:11 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,20 +0,0 @@ -using System.Windows; -using System.Windows.Media; - -namespace SilverFlow.Controls.Helpers -{ - /// <summary> - /// This interface defines methods used the create bitmap images. - /// </summary> - public interface IBitmapHelper - { - /// <summary> - /// Renders the visual element and returns a bitmap, containing bitmap image of the element. - /// </summary> - /// <param name="element">The visual element.</param> - /// <param name="imageWidth">Image width.</param> - /// <param name="imageHeight">Image height.</param> - /// <returns>Bitmap image of the element.</returns> - ImageSource RenderVisual(FrameworkElement element, double imageWidth, double imageHeight); - } -}
--- a/SilverlightGlimpse/SilverFlow.Controls/Helpers/ILocalStorage.cs Mon Apr 23 11:05:11 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,21 +0,0 @@ -namespace SilverFlow.Controls.Helpers -{ - /// <summary> - /// This interface defines isolated storage methods and properties. - /// </summary> - public interface ILocalStorage - { - /// <summary> - /// Gets or saves the value associated with the specified key. - /// </summary> - /// <value>The value associated with the specified key.</value> - object this[string key] { get; set; } - - /// <summary> - /// Determines if the local storage contains the specified key. - /// </summary> - /// <param name="key">The key for the entry to be located.</param> - /// <returns>True if the local storage contains the specified key; otherwise, false.</returns> - bool Contains(string key); - } -}
--- a/SilverlightGlimpse/SilverFlow.Controls/Helpers/IVisualHelper.cs Mon Apr 23 11:05:11 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,24 +0,0 @@ -using System.Collections.Generic; -using System.Windows; - -namespace SilverFlow.Controls.Helpers -{ - /// <summary> - /// This interface defines methods used to traverse object relationships - /// in the visual tree. - /// </summary> - public interface IVisualHelper - { - /// <summary> - /// Retrieves a set of objects that are located within a specified point of an object's coordinate space. - /// </summary> - /// <param name="intersectingPoint">The point to use as the determination point.</param> - /// <param name="subtree">The object to search within.</param> - /// <returns> - /// An enumerable set of System.Windows.UIElement objects that are determined - /// to be located in the visual tree composition at the specified point and within - /// the specified subtee. - /// </returns> - IEnumerable<UIElement> FindElementsInCoordinates(Point intersectingPoint, UIElement subtree); - } -}
--- a/SilverlightGlimpse/SilverFlow.Controls/Helpers/LocalStorage.cs Mon Apr 23 11:05:11 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +0,0 @@ -using System.IO.IsolatedStorage; - -namespace SilverFlow.Controls.Helpers -{ - /// <summary> - /// Local isolated storage. - /// </summary> - public class LocalStorage : ILocalStorage - { - /// <summary> - /// Gets or saves the value associated with the specified key. - /// </summary> - /// <value>The value associated with the specified key.</value> - public object this[string key] - { - get - { - return IsolatedStorageSettings.ApplicationSettings[key]; - } - set - { - IsolatedStorageSettings.ApplicationSettings[key] = value; - } - } - - /// <summary> - /// Determines if the local storage contains the specified key. - /// </summary> - /// <param name="key">The key for the entry to be located.</param> - /// <returns> - /// True if the local storage contains the specified key; otherwise, false. - /// </returns> - public bool Contains(string key) - { - return IsolatedStorageSettings.ApplicationSettings.Contains(key); - } - } -}
--- a/SilverlightGlimpse/SilverFlow.Controls/Helpers/VisualHelper.cs Mon Apr 23 11:05:11 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,24 +0,0 @@ -using System.Collections.Generic; -using System.Windows; -using System.Windows.Media; - -namespace SilverFlow.Controls.Helpers -{ - public class VisualHelper : IVisualHelper - { - /// <summary> - /// Retrieves a set of objects that are located within a specified point of an object's coordinate space. - /// </summary> - /// <param name="intersectingPoint">The point to use as the determination point.</param> - /// <param name="subtree">The object to search within.</param> - /// <returns> - /// An enumerable set of System.Windows.UIElement objects that are determined - /// to be located in the visual tree composition at the specified point and within - /// the specified subtee. - /// </returns> - public IEnumerable<UIElement> FindElementsInCoordinates(Point intersectingPoint, UIElement subtree) - { - return VisualTreeHelper.FindElementsInHostCoordinates(intersectingPoint, subtree); - } - } -}
--- a/SilverlightGlimpse/SilverFlow.Controls/Properties/AssemblyInfo.cs Mon Apr 23 11:05:11 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -using System; -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("SilverFlow.Controls")] -[assembly: AssemblyDescription("FloatingWindow Control Library for Silverlight")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Jevgenij Pankov")] -[assembly: AssemblyProduct("SilverFlow.Controls")] -[assembly: AssemblyCopyright("Copyright © 2011")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] -[assembly: CLSCompliant(true)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("00b61972-c1f0-47b6-8507-872060367303")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Revision and Build Numbers -// by using the '*' as shown below: -[assembly: AssemblyVersion("2.0.2")] -[assembly: AssemblyFileVersion("2.0.2")]
--- a/SilverlightGlimpse/SilverFlow.Controls/SilverFlow.Controls.csproj Mon Apr 23 11:05:11 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,117 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <PropertyGroup> - <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> - <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> - <ProductVersion>8.0.50727</ProductVersion> - <SchemaVersion>2.0</SchemaVersion> - <ProjectGuid>{3F3D3C8C-9724-4531-A04D-B92049F64686}</ProjectGuid> - <ProjectTypeGuids>{A1591282-1198-4647-A2B1-27E5FF5F6F3B};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids> - <OutputType>Library</OutputType> - <AppDesignerFolder>Properties</AppDesignerFolder> - <RootNamespace>SilverFlow.Controls</RootNamespace> - <AssemblyName>SilverFlow.Controls</AssemblyName> - <TargetFrameworkIdentifier>Silverlight</TargetFrameworkIdentifier> - <TargetFrameworkVersion>v4.0</TargetFrameworkVersion> - <SilverlightVersion>$(TargetFrameworkVersion)</SilverlightVersion> - <SilverlightApplication>false</SilverlightApplication> - <ValidateXaml>true</ValidateXaml> - <ThrowErrorsInValidation>true</ThrowErrorsInValidation> - <Utf8Output>true</Utf8Output> - <ExpressionBlendVersion>4.0.20525.0</ExpressionBlendVersion> - </PropertyGroup> - <!-- This property group is only here to support building this project using the - MSBuild 3.5 toolset. In order to work correctly with this older toolset, it needs - to set the TargetFrameworkVersion to v3.5 --> - <PropertyGroup Condition="'$(MSBuildToolsVersion)' == '3.5'"> - <TargetFrameworkVersion>v3.5</TargetFrameworkVersion> - </PropertyGroup> - <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> - <DebugSymbols>true</DebugSymbols> - <DebugType>full</DebugType> - <Optimize>false</Optimize> - <OutputPath>Bin\Debug</OutputPath> - <DefineConstants>DEBUG;TRACE;SILVERLIGHT</DefineConstants> - <NoStdLib>true</NoStdLib> - <NoConfig>true</NoConfig> - <ErrorReport>prompt</ErrorReport> - <WarningLevel>4</WarningLevel> - <RunCodeAnalysis>false</RunCodeAnalysis> - <CodeAnalysisRuleSet>BasicCorrectnessRules.ruleset</CodeAnalysisRuleSet> - </PropertyGroup> - <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> - <DebugType>pdbonly</DebugType> - <Optimize>true</Optimize> - <OutputPath>Bin\Release</OutputPath> - <DefineConstants>TRACE;SILVERLIGHT</DefineConstants> - <NoStdLib>true</NoStdLib> - <NoConfig>true</NoConfig> - <ErrorReport>prompt</ErrorReport> - <WarningLevel>4</WarningLevel> - </PropertyGroup> - <ItemGroup> - <Reference Include="mscorlib" /> - <Reference Include="System.Windows" /> - <Reference Include="system" /> - <Reference Include="System.Core" /> - <Reference Include="System.Windows.Controls, Version=2.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" /> - <Reference Include="System.Xml" /> - <Reference Include="System.Net" /> - <Reference Include="System.Windows.Browser" /> - </ItemGroup> - <ItemGroup> - <Compile Include="Converters\BooleanToVisibilityConverter.cs" /> - <Compile Include="Extensions\AnimationExtensions.cs" /> - <Compile Include="Extensions\ControlExtensions.cs" /> - <Compile Include="Extensions\GeometryExtensions.cs" /> - <Compile Include="Extensions\MathExtensions.cs" /> - <Compile Include="FloatingWindow\ActiveWindowChangedEventArgs.cs" /> - <Compile Include="FloatingWindow\BootstrapButton.cs" /> - <Compile Include="FloatingWindow\FloatingWindow.cs" /> - <Compile Include="FloatingWindow\FloatingWindowHost.cs" /> - <Compile Include="Controllers\InertiaController.cs" /> - <Compile Include="Controllers\IResizableElement.cs" /> - <Compile Include="Controllers\ISnapinController.cs" /> - <Compile Include="Controllers\SnapinController.cs" /> - <Compile Include="Controllers\InertialMotion.cs" /> - <Compile Include="Enums\WindowAction.cs" /> - <Compile Include="Geometry\Distance.cs" /> - <Compile Include="Enums\ResizeAnchor.cs" /> - <Compile Include="Controllers\ResizeController.cs"> - <SubType>Code</SubType> - </Compile> - <Compile Include="Geometry\Trail.cs" /> - <Compile Include="Geometry\Vector2.cs" /> - <Compile Include="Helpers\BitmapHelper.cs" /> - <Compile Include="Helpers\IBitmapHelper.cs" /> - <Compile Include="Helpers\ILocalStorage.cs" /> - <Compile Include="Helpers\IVisualHelper.cs" /> - <Compile Include="Helpers\LocalStorage.cs" /> - <Compile Include="Helpers\VisualHelper.cs" /> - <Compile Include="Properties\AssemblyInfo.cs" /> - <Compile Include="FloatingWindow\IconBar.cs" /> - <Compile Include="FloatingWindow\WindowIcon.cs" /> - </ItemGroup> - <ItemGroup> - <Resource Include="Themes\generic.xaml"> - <Generator>MSBuild:Compile</Generator> - <SubType>Designer</SubType> - </Resource> - </ItemGroup> - <ItemGroup /> - <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Silverlight\$(SilverlightVersion)\Microsoft.Silverlight.CSharp.targets" /> - <ProjectExtensions> - <VisualStudio> - <FlavorProperties GUID="{A1591282-1198-4647-A2B1-27E5FF5F6F3B}"> - <SilverlightProjectProperties /> - </FlavorProperties> - </VisualStudio> - </ProjectExtensions> - <!-- To modify your build process, add your task inside one of the targets below and uncomment it. - Other similar extension points exist, see Microsoft.Common.targets. - <Target Name="BeforeBuild"> - </Target> - <Target Name="AfterBuild"> - </Target> - --> -</Project> \ No newline at end of file
--- a/SilverlightGlimpse/SilverFlow.Controls/Themes/generic.xaml Mon Apr 23 11:05:11 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,787 +0,0 @@ -<ResourceDictionary - xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" - xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" - xmlns:controls="clr-namespace:SilverFlow.Controls" - xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows" - xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:System="clr-namespace:System;assembly=mscorlib"> - - <!-- Window Button Brushes --> - <SolidColorBrush x:Key="WindowButtonForeground">#FF9E9E9E</SolidColorBrush> - <SolidColorBrush x:Key="WindowButtonBorderBrush">#FFd1d9e1</SolidColorBrush> - <Color x:Key="WindowButtonOverColor">White</Color> - <Color x:Key="WindowButtonPressedColor">White</Color> - <Color x:Key="WindowButtonBorderOverColor">#FF899199</Color> - <Color x:Key="WindowButtonBorderPressedColor">#FF0667D4</Color> - - <!-- FloatingWindow Brushes --> - <LinearGradientBrush x:Key="FloatingWindowTitleBackgroundBrush" StartPoint="0.5,0" EndPoint="0.5,1"> - <GradientStop Color="White" Offset="0"/> - <GradientStop Color="#FFe7ebed" Offset="1"/> - </LinearGradientBrush> - - <Style x:Key="CloseButtonStyle" TargetType="Button"> - <Setter Property="Foreground" Value="{StaticResource WindowButtonForeground}"/> - <Setter Property="BorderBrush" Value="{StaticResource WindowButtonBorderBrush}"/> - <Setter Property="BorderThickness" Value="1,0,1,1"/> - <Setter Property="Width" Value="25"/> - <Setter Property="Height" Value="15"/> - <Setter Property="IsTabStop" Value="False"/> - <Setter Property="VerticalAlignment" Value="Top"/> - <Setter Property="VerticalContentAlignment" Value="Top"/> - <Setter Property="Template"> - <Setter.Value> - <ControlTemplate TargetType="Button"> - <Grid x:Name="Root" Background="Transparent" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" > - <VisualStateManager.VisualStateGroups> - <VisualStateGroup x:Name="CommonStates"> - <VisualState x:Name="Normal" /> - <VisualState x:Name="MouseOver"> - <Storyboard> - <ColorAnimation Duration="0" To="{StaticResource WindowButtonOverColor}" Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="ButtonPath" /> - <ColorAnimation Duration="0" To="{StaticResource WindowButtonOverColor}" Storyboard.TargetProperty="(Path.Stroke).(SolidColorBrush.Color)" Storyboard.TargetName="ButtonPath" /> - <ColorAnimation Duration="0" To="#FFf9acaf" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[0].(GradientStop.Color)" Storyboard.TargetName="ButtonBorder" /> - <ColorAnimation Duration="0" To="#FFf64c4c" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[1].(GradientStop.Color)" Storyboard.TargetName="ButtonBorder" /> - </Storyboard> - </VisualState> - <VisualState x:Name="Pressed"> - <Storyboard> - <ColorAnimation Duration="0" To="{StaticResource WindowButtonPressedColor}" Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="ButtonPath" /> - <ColorAnimation Duration="0" To="{StaticResource WindowButtonPressedColor}" Storyboard.TargetProperty="(Path.Stroke).(SolidColorBrush.Color)" Storyboard.TargetName="ButtonPath" /> - <ColorAnimation Duration="0" To="#FFfa8980" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[0].(GradientStop.Color)" Storyboard.TargetName="ButtonBorder" /> - <ColorAnimation Duration="0" To="#FF9a0000" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[1].(GradientStop.Color)" Storyboard.TargetName="ButtonBorder" /> - </Storyboard> - </VisualState> - <VisualState x:Name="Disabled"> - <Storyboard> - <DoubleAnimation Duration="0" Storyboard.TargetName="Root" Storyboard.TargetProperty="Opacity" To="0.5"/> - </Storyboard> - </VisualState> - </VisualStateGroup> - </VisualStateManager.VisualStateGroups> - <Border x:Name="ButtonBorder" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" UseLayoutRounding="True"> - <Border.Background> - <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> - <GradientStop Offset="0"/> - <GradientStop Offset="1"/> - </LinearGradientBrush> - </Border.Background> - <Canvas Width="8" Height="8"> - <Path x:Name="ButtonPath" Data="M0,0 L0.9371469,0 L4,3.0628543 L7.0628557,0 L8,0 L8,1.073151 L5.0731506,4 L8,6.9268494 L8,8 L6.9278555,8 L4,5.0721459 L1.0721471,8 L0,8 L0,7.0948515 L3.0948515,4 L0,0.90514863 z" - Fill="{TemplateBinding Foreground}" Stretch="None" StrokeThickness="0.5" Stroke="{TemplateBinding Foreground}" - UseLayoutRounding="True" Width="8" Height="8" VerticalAlignment="Center" HorizontalAlignment="Center" /> - </Canvas> - </Border> - </Grid> - </ControlTemplate> - </Setter.Value> - </Setter> - </Style> - - <Style x:Key="MinimizeButtonStyle" TargetType="Button"> - <Setter Property="Foreground" Value="{StaticResource WindowButtonForeground}"/> - <Setter Property="BorderBrush" Value="{StaticResource WindowButtonBorderBrush}"/> - <Setter Property="BorderThickness" Value="1,0,1,1"/> - <Setter Property="Margin" Value="0,0,-1,0"/> - <Setter Property="Width" Value="21"/> - <Setter Property="Height" Value="15"/> - <Setter Property="IsTabStop" Value="False"/> - <Setter Property="VerticalAlignment" Value="Top"/> - <Setter Property="VerticalContentAlignment" Value="Top"/> - <Setter Property="Template"> - <Setter.Value> - <ControlTemplate TargetType="Button"> - <Grid x:Name="Root" Background="Transparent" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" > - <VisualStateManager.VisualStateGroups> - <VisualStateGroup x:Name="CommonStates"> - <VisualState x:Name="Normal" /> - <VisualState x:Name="MouseOver"> - <Storyboard> - <ColorAnimation Duration="0" To="{StaticResource WindowButtonOverColor}" Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="ButtonContent" /> - <ColorAnimation Duration="0" To="#FFbfeefd" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[0].(GradientStop.Color)" Storyboard.TargetName="ButtonBorder" /> - <ColorAnimation Duration="0" To="#FF10a4e1" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[1].(GradientStop.Color)" Storyboard.TargetName="ButtonBorder" /> - </Storyboard> - </VisualState> - <VisualState x:Name="Pressed"> - <Storyboard> - <ColorAnimation Duration="0" To="{StaticResource WindowButtonPressedColor}" Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="ButtonContent" /> - <ColorAnimation Duration="0" To="#FF85EBFF" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[0].(GradientStop.Color)" Storyboard.TargetName="ButtonBorder" /> - <ColorAnimation Duration="0" To="#FF003D80" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[1].(GradientStop.Color)" Storyboard.TargetName="ButtonBorder" /> - </Storyboard> - </VisualState> - <VisualState x:Name="Disabled"> - <Storyboard> - <DoubleAnimation Duration="0" Storyboard.TargetName="Root" Storyboard.TargetProperty="Opacity" To="0.5"/> - </Storyboard> - </VisualState> - </VisualStateGroup> - </VisualStateManager.VisualStateGroups> - <Border x:Name="ButtonBorder" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" UseLayoutRounding="True"> - <Border.Background> - <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> - <GradientStop Offset="0"/> - <GradientStop Offset="1"/> - </LinearGradientBrush> - </Border.Background> - <Canvas Width="9" Height="8" VerticalAlignment="Center" HorizontalAlignment="Center"> - <Rectangle x:Name="ButtonContent" StrokeThickness="0" Width="9" Height="2" Fill="{TemplateBinding Foreground}" Canvas.Top="6" /> - </Canvas> - </Border> - </Grid> - </ControlTemplate> - </Setter.Value> - </Setter> - </Style> - - <Style x:Key="MaximizeButtonStyle" TargetType="Button"> - <Setter Property="Foreground" Value="{StaticResource WindowButtonForeground}"/> - <Setter Property="BorderBrush" Value="{StaticResource WindowButtonBorderBrush}"/> - <Setter Property="BorderThickness" Value="1,0,1,1"/> - <Setter Property="Margin" Value="0,0,-1,0"/> - <Setter Property="Width" Value="21"/> - <Setter Property="Height" Value="15"/> - <Setter Property="IsTabStop" Value="False"/> - <Setter Property="VerticalAlignment" Value="Top"/> - <Setter Property="VerticalContentAlignment" Value="Top"/> - <Setter Property="Template"> - <Setter.Value> - <ControlTemplate TargetType="Button"> - <Grid x:Name="Root" Background="Transparent" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" > - <VisualStateManager.VisualStateGroups> - <VisualStateGroup x:Name="CommonStates"> - <VisualState x:Name="Normal" /> - <VisualState x:Name="MouseOver"> - <Storyboard> - <ColorAnimation Duration="0" To="{StaticResource WindowButtonOverColor}" Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="ButtonContent1" /> - <ColorAnimation Duration="0" To="{StaticResource WindowButtonOverColor}" Storyboard.TargetProperty="(Path.Stroke).(SolidColorBrush.Color)" Storyboard.TargetName="ButtonContent2" /> - <ColorAnimation Duration="0" To="#FFbfeefd" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[0].(GradientStop.Color)" Storyboard.TargetName="ButtonBorder" /> - <ColorAnimation Duration="0" To="#FF10a4e1" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[1].(GradientStop.Color)" Storyboard.TargetName="ButtonBorder" /> - </Storyboard> - </VisualState> - <VisualState x:Name="Pressed"> - <Storyboard> - <ColorAnimation Duration="0" To="{StaticResource WindowButtonPressedColor}" Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="ButtonContent1" /> - <ColorAnimation Duration="0" To="{StaticResource WindowButtonPressedColor}" Storyboard.TargetProperty="(Path.Stroke).(SolidColorBrush.Color)" Storyboard.TargetName="ButtonContent2" /> - <ColorAnimation Duration="0" To="#FF85EBFF" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[0].(GradientStop.Color)" Storyboard.TargetName="ButtonBorder" /> - <ColorAnimation Duration="0" To="#FF003D80" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[1].(GradientStop.Color)" Storyboard.TargetName="ButtonBorder" /> - </Storyboard> - </VisualState> - <VisualState x:Name="Disabled"> - <Storyboard> - <DoubleAnimation Duration="0" Storyboard.TargetName="Root" Storyboard.TargetProperty="Opacity" To="0.5"/> - </Storyboard> - </VisualState> - </VisualStateGroup> - </VisualStateManager.VisualStateGroups> - <Border x:Name="ButtonBorder" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" UseLayoutRounding="True"> - <Border.Background> - <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> - <GradientStop Offset="0"/> - <GradientStop Offset="1"/> - </LinearGradientBrush> - </Border.Background> - <Canvas Width="9" Height="8"> - <Rectangle x:Name="ButtonContent1" StrokeThickness="0" Width="9" Height="2" Fill="{TemplateBinding Foreground}" /> - <Rectangle x:Name="ButtonContent2" StrokeThickness="1" Width="9" Height="8" Stroke="{TemplateBinding Foreground}" /> - </Canvas> - </Border> - </Grid> - </ControlTemplate> - </Setter.Value> - </Setter> - </Style> - - <Style x:Key="RestoreButtonStyle" TargetType="Button"> - <Setter Property="Foreground" Value="{StaticResource WindowButtonForeground}"/> - <Setter Property="BorderBrush" Value="{StaticResource WindowButtonBorderBrush}"/> - <Setter Property="BorderThickness" Value="1,0,1,1"/> - <Setter Property="Margin" Value="0,0,-1,0"/> - <Setter Property="Width" Value="21"/> - <Setter Property="Height" Value="15"/> - <Setter Property="IsTabStop" Value="False"/> - <Setter Property="VerticalAlignment" Value="Top"/> - <Setter Property="VerticalContentAlignment" Value="Top"/> - <Setter Property="Template"> - <Setter.Value> - <ControlTemplate TargetType="Button"> - <Grid x:Name="Root" Background="Transparent" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" > - <VisualStateManager.VisualStateGroups> - <VisualStateGroup x:Name="CommonStates"> - <VisualState x:Name="Normal" /> - <VisualState x:Name="MouseOver"> - <Storyboard> - <ColorAnimation Duration="0" To="{StaticResource WindowButtonOverColor}" Storyboard.TargetProperty="(Rectangle.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="Content1" /> - <ColorAnimation Duration="0" To="{StaticResource WindowButtonOverColor}" Storyboard.TargetProperty="(Rectangle.Stroke).(SolidColorBrush.Color)" Storyboard.TargetName="Content2" /> - <ColorAnimation Duration="0" To="{StaticResource WindowButtonOverColor}" Storyboard.TargetProperty="(Rectangle.Stroke).(SolidColorBrush.Color)" Storyboard.TargetName="Content3" /> - <ColorAnimation Duration="0" To="{StaticResource WindowButtonOverColor}" Storyboard.TargetProperty="(Rectangle.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="Content4" /> - <ColorAnimation Duration="0" To="#FFbfeefd" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[0].(GradientStop.Color)" Storyboard.TargetName="ButtonBorder" /> - <ColorAnimation Duration="0" To="#FF10a4e1" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[1].(GradientStop.Color)" Storyboard.TargetName="ButtonBorder" /> - </Storyboard> - </VisualState> - <VisualState x:Name="Pressed"> - <Storyboard> - <ColorAnimation Duration="0" To="{StaticResource WindowButtonPressedColor}" Storyboard.TargetProperty="(Rectangle.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="Content1" /> - <ColorAnimation Duration="0" To="{StaticResource WindowButtonPressedColor}" Storyboard.TargetProperty="(Rectangle.Stroke).(SolidColorBrush.Color)" Storyboard.TargetName="Content2" /> - <ColorAnimation Duration="0" To="{StaticResource WindowButtonPressedColor}" Storyboard.TargetProperty="(Rectangle.Stroke).(SolidColorBrush.Color)" Storyboard.TargetName="Content3" /> - <ColorAnimation Duration="0" To="{StaticResource WindowButtonPressedColor}" Storyboard.TargetProperty="(Rectangle.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="Content4" /> - <ColorAnimation Duration="0" To="#FF85EBFF" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[0].(GradientStop.Color)" Storyboard.TargetName="ButtonBorder" /> - <ColorAnimation Duration="0" To="#FF003D80" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[1].(GradientStop.Color)" Storyboard.TargetName="ButtonBorder" /> - </Storyboard> - </VisualState> - <VisualState x:Name="Disabled"> - <Storyboard> - <DoubleAnimation Duration="0" Storyboard.TargetName="Root" Storyboard.TargetProperty="Opacity" To="0.5"/> - </Storyboard> - </VisualState> - </VisualStateGroup> - </VisualStateManager.VisualStateGroups> - <Border x:Name="ButtonBorder" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" UseLayoutRounding="True"> - <Border.Background> - <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> - <GradientStop Offset="0"/> - <GradientStop Offset="1"/> - </LinearGradientBrush> - </Border.Background> - <Canvas Width="9" Height="8"> - <Rectangle x:Name="Content1" StrokeThickness="0" Width="7" Height="1" Fill="{TemplateBinding Foreground}" Canvas.Top="3" /> - <Rectangle x:Name="Content2" StrokeThickness="1" Width="7" Height="5" Stroke="{TemplateBinding Foreground}" Canvas.Top="3" /> - <Path x:Name="Content3" Data="M0.35,0.345 L6.65,0.35 L6.65,5.65 L4.65,5.65 L4.65,3.65625 L0.35,3.65625 z" Width="7" Height="6" - Stretch="Fill" Stroke="{TemplateBinding Foreground}" StrokeThickness="1" Canvas.Left="2" /> - <Rectangle x:Name="Content4" StrokeThickness="0" Width="7" Height="2" Fill="{TemplateBinding Foreground}" Canvas.Left="2" /> - </Canvas> - </Border> - </Grid> - </ControlTemplate> - </Setter.Value> - </Setter> - </Style> - - <Style x:Key="WindowButtonToolTipStyle" TargetType="ToolTip"> - <Setter Property="Template"> - <Setter.Value> - <ControlTemplate TargetType="ToolTip"> - <Border Background="#FFf7f8fa" BorderThickness="1" CornerRadius="2" Padding="7,1"> - <Border.BorderBrush> - <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1"> - <GradientStop Color="#F09EBFCE" Offset="0" /> - <GradientStop Color="#F0698795" Offset="1" /> - </LinearGradientBrush> - </Border.BorderBrush> - <Border.Effect> - <DropShadowEffect ShadowDepth="0.5" Opacity="0.3" BlurRadius="3" /> - </Border.Effect> - <ContentPresenter Content="{TemplateBinding Content}" - ContentTemplate="{TemplateBinding ContentTemplate}" /> - </Border> - </ControlTemplate> - </Setter.Value> - </Setter> - </Style> - - <Style x:Key="FloatingWindowTitleStyle" TargetType="ContentControl"> - <Setter Property="IsTabStop" Value="False"/> - <Setter Property="HorizontalAlignment" Value="Stretch"/> - <Setter Property="VerticalAlignment" Value="Center"/> - <Setter Property="Margin" Value="6,3,6,3"/> - <Setter Property="UseLayoutRounding" Value="True"/> - <Setter Property="FontWeight" Value="Bold"/> - <Setter Property="Foreground" Value="#FF67676C"/> - <Setter Property="FontSize" Value="10"/> - </Style> - - <Style x:Key="BottomBarStyle" TargetType="Border"> - <Setter Property="Height" Value="24" /> - <Setter Property="Background" Value="#FFE7EBED" /> - <Setter Property="BorderThickness" Value="0,1,0,0" /> - <Setter Property="BorderBrush" Value="#FFFEFEFE" /> - </Style> - - <Style x:Key="IconBarStyle" TargetType="Border"> - <Setter Property="VerticalAlignment" Value="Top" /> - <Setter Property="Height" Value="104" /> - <Setter Property="Padding" Value="2,2" /> - <Setter Property="Background" Value="#FF202F50" /> - </Style> - - <Style x:Key="IconBorderStyle" TargetType="Border"> - <Setter Property="Width" Value="140" /> - <Setter Property="Height" Value="100" /> - <Setter Property="Margin" Value="0,0,1,0" /> - <Setter Property="Padding" Value="2" /> - <Setter Property="VerticalAlignment" Value="Bottom" /> - <Setter Property="CornerRadius" Value="2" /> - <Setter Property="BorderThickness" Value="0.7" /> - <Setter Property="BorderBrush" Value="Transparent" /> - <Setter Property="Background"> - <Setter.Value> - <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> - <GradientStop Color="Transparent" Offset="0"/> - <GradientStop Color="Transparent" Offset="1"/> - </LinearGradientBrush> - </Setter.Value> - </Setter> - </Style> - - <Style TargetType="controls:FloatingWindow"> - <Setter Property="Width" Value="300"/> - <Setter Property="Height" Value="200"/> - <Setter Property="IsTabStop" Value="False"/> - <Setter Property="TabNavigation" Value="Cycle"/> - <Setter Property="HorizontalAlignment" Value="Center"/> - <Setter Property="VerticalAlignment" Value="Center"/> - <Setter Property="HorizontalContentAlignment" Value="Stretch"/> - <Setter Property="VerticalContentAlignment" Value="Stretch"/> - <Setter Property="BorderThickness" Value="1"/> - <Setter Property="BorderBrush" Value="#FFA2ADB8"/> - <Setter Property="Background" Value="#FFE7EBED" /> - <Setter Property="TitleBackground" Value="{StaticResource FloatingWindowTitleBackgroundBrush}" /> - - <Setter Property="Template"> - <Setter.Value> - <ControlTemplate TargetType="controls:FloatingWindow"> - <Grid x:Name="Root" RenderTransformOrigin="0.5,0.5"> - <Grid.RenderTransform> - <CompositeTransform/> - </Grid.RenderTransform> - <VisualStateManager.VisualStateGroups> - <VisualStateGroup x:Name="WindowStates"> - <VisualState x:Name="Open"> - <Storyboard> - <DoubleAnimationUsingKeyFrames BeginTime="0" Storyboard.TargetName="ContentRoot" Storyboard.TargetProperty="Opacity"> - <SplineDoubleKeyFrame KeyTime="0" Value="0"/> - <SplineDoubleKeyFrame KeyTime="00:00:00.3" Value="1"/> - </DoubleAnimationUsingKeyFrames> - <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetName="ContentRoot" Storyboard.TargetProperty="Visibility"> - <DiscreteObjectKeyFrame KeyTime="0"> - <DiscreteObjectKeyFrame.Value> - <Visibility>Visible</Visibility> - </DiscreteObjectKeyFrame.Value> - </DiscreteObjectKeyFrame> - </ObjectAnimationUsingKeyFrames> - </Storyboard> - </VisualState> - <VisualState x:Name="Closed"> - <Storyboard> - <DoubleAnimationUsingKeyFrames BeginTime="0" Storyboard.TargetName="ContentRoot" Storyboard.TargetProperty="Opacity"> - <SplineDoubleKeyFrame KeyTime="0" Value="1"/> - <SplineDoubleKeyFrame KeyTime="00:00:00.2" Value="0"/> - </DoubleAnimationUsingKeyFrames> - </Storyboard> - </VisualState> - <VisualState x:Name="Minimized"> - <Storyboard> - <PointAnimation Duration="0" To="0,1" Storyboard.TargetProperty="(UIElement.RenderTransformOrigin)" Storyboard.TargetName="ContentRoot" /> - <DoubleAnimationUsingKeyFrames BeginTime="0" Storyboard.TargetName="ContentRoot" Storyboard.TargetProperty="(UIElement.RenderTransform).(Children)[0].ScaleX"> - <SplineDoubleKeyFrame KeyTime="0" Value="1"/> - <SplineDoubleKeyFrame KeyTime="00:00:0.2" Value="0"/> - </DoubleAnimationUsingKeyFrames> - <DoubleAnimationUsingKeyFrames BeginTime="0" Storyboard.TargetName="ContentRoot" Storyboard.TargetProperty="(UIElement.RenderTransform).(Children)[0].ScaleY"> - <SplineDoubleKeyFrame KeyTime="00:00:00" Value="1"/> - <SplineDoubleKeyFrame KeyTime="00:00:0.2" Value="0"/> - </DoubleAnimationUsingKeyFrames> - <DoubleAnimationUsingKeyFrames Storyboard.TargetName="ContentRoot" Storyboard.TargetProperty="Opacity"> - <EasingDoubleKeyFrame KeyTime="0" Value="1"/> - <EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="0"/> - </DoubleAnimationUsingKeyFrames> - <ObjectAnimationUsingKeyFrames BeginTime="0" Duration="00:00:0.2" Storyboard.TargetName="ContentRoot" Storyboard.TargetProperty="Visibility"> - <DiscreteObjectKeyFrame KeyTime="00:00:0.2"> - <DiscreteObjectKeyFrame.Value> - <Visibility>Collapsed</Visibility> - </DiscreteObjectKeyFrame.Value> - </DiscreteObjectKeyFrame> - </ObjectAnimationUsingKeyFrames> - </Storyboard> - </VisualState> - <VisualState x:Name="Restored"> - <Storyboard> - <PointAnimation Duration="0" To="0,1" Storyboard.TargetProperty="(UIElement.RenderTransformOrigin)" Storyboard.TargetName="ContentRoot" /> - <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Opacity" Storyboard.TargetName="ContentRoot"> - <EasingDoubleKeyFrame KeyTime="0" Value="0"/> - <EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="1"/> - </DoubleAnimationUsingKeyFrames> - <ObjectAnimationUsingKeyFrames BeginTime="0" Duration="0" Storyboard.TargetName="ContentRoot" Storyboard.TargetProperty="Visibility"> - <DiscreteObjectKeyFrame KeyTime="00:00:00"> - <DiscreteObjectKeyFrame.Value> - <Visibility>Visible</Visibility> - </DiscreteObjectKeyFrame.Value> - </DiscreteObjectKeyFrame> - </ObjectAnimationUsingKeyFrames> - <DoubleAnimationUsingKeyFrames BeginTime="0" Storyboard.TargetName="ContentRoot" Storyboard.TargetProperty="(UIElement.RenderTransform).(Children)[0].ScaleX"> - <SplineDoubleKeyFrame KeyTime="0" Value="0"/> - <SplineDoubleKeyFrame KeyTime="00:00:0.3" Value="1" KeySpline="0,0.86,0.19,1"/> - </DoubleAnimationUsingKeyFrames> - <DoubleAnimationUsingKeyFrames BeginTime="0" Storyboard.TargetName="ContentRoot" Storyboard.TargetProperty="(UIElement.RenderTransform).(Children)[0].ScaleY"> - <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/> - <SplineDoubleKeyFrame KeyTime="00:00:0.3" Value="1" KeySpline="0,0.86,0.19,1"/> - </DoubleAnimationUsingKeyFrames> - </Storyboard> - </VisualState> - </VisualStateGroup> - </VisualStateManager.VisualStateGroups> - <Grid x:Name="ContentRoot" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}" - RenderTransformOrigin="0,0" Height="{TemplateBinding Height}" Width="{TemplateBinding Width}"> - <Grid.Effect> - <DropShadowEffect ShadowDepth="0.5" Opacity="0.35" BlurRadius="12" /> - </Grid.Effect> - <Grid.RenderTransform> - <TransformGroup> - <ScaleTransform /> - <SkewTransform /> - <RotateTransform /> - <TranslateTransform /> - </TransformGroup> - </Grid.RenderTransform> - - <Border x:Name="ContentBorder" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" - BorderBrush="{TemplateBinding BorderBrush}" CornerRadius="3"> - <Grid> - <Grid.RowDefinitions> - <RowDefinition Height="Auto"/> - <RowDefinition/> - </Grid.RowDefinitions> - - <Border x:Name="Chrome" Width="Auto" Background="{TemplateBinding TitleBackground}" UseLayoutRounding="False" CornerRadius="2,2,0,0"> - <Grid Height="Auto" Width="Auto"> - <Grid.ColumnDefinitions> - <ColumnDefinition/> - <ColumnDefinition Width="Auto"/> - <ColumnDefinition Width="Auto"/> - <ColumnDefinition Width="6"/> - </Grid.ColumnDefinitions> - - <ContentControl x:Name="TitleContent" Content="{TemplateBinding Title}" Style="{StaticResource FloatingWindowTitleStyle}" /> - - <StackPanel x:Name="MenuPanel" Orientation="Horizontal" Grid.Column="1" VerticalAlignment="Top"> - <Button x:Name="MinimizeButton" Style="{StaticResource MinimizeButtonStyle}"> - <ToolTipService.ToolTip> - <ToolTip Style="{StaticResource WindowButtonToolTipStyle}" Content="Minimize" /> - </ToolTipService.ToolTip> - </Button> - <Button x:Name="MaximizeButton" Style="{StaticResource MaximizeButtonStyle}"> - <ToolTipService.ToolTip> - <ToolTip Style="{StaticResource WindowButtonToolTipStyle}" Content="Maximize" /> - </ToolTipService.ToolTip> - </Button> - <Button x:Name="RestoreButton" Style="{StaticResource RestoreButtonStyle}" Visibility="Collapsed"> - <ToolTipService.ToolTip> - <ToolTip Style="{StaticResource WindowButtonToolTipStyle}" Content="Restore" /> - </ToolTipService.ToolTip> - </Button> - </StackPanel> - <Button x:Name="CloseButton" Style="{StaticResource CloseButtonStyle}" Grid.Column="2"> - <ToolTipService.ToolTip> - <ToolTip Style="{StaticResource WindowButtonToolTipStyle}" Content="Close" /> - </ToolTipService.ToolTip> - </Button> - </Grid> - </Border> - <Border Grid.Row="1"> - <ContentPresenter x:Name="ContentPresenter" Content="{TemplateBinding Content}" - ContentTemplate="{TemplateBinding ContentTemplate}" - HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" - VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/> - </Border> - </Grid> - </Border> - </Grid> - </Grid> - </ControlTemplate> - </Setter.Value> - </Setter> - </Style> - - <Style x:Key="BootstrapButtonStyle" TargetType="controls:BootstrapButton"> - <Setter Property="Width" Value="24"/> - <Setter Property="Height" Value="24"/> - <Setter Property="BorderBrush" Value="#FFA2ADB8"/> - <Setter Property="Background" Value="#FF4E4E4E"/> - <Setter Property="VerticalAlignment" Value="Top"/> - <Setter Property="IsTabStop" Value="false"/> - <Setter Property="Template"> - <Setter.Value> - <ControlTemplate TargetType="controls:BootstrapButton"> - <Grid Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" RenderTransformOrigin="0.5,0.5"> - <Grid.RenderTransform> - <CompositeTransform/> - </Grid.RenderTransform> - <VisualStateManager.VisualStateGroups> - <VisualStateGroup x:Name="CommonStates"> - <VisualStateGroup.Transitions> - <VisualTransition GeneratedDuration="0"/> - </VisualStateGroup.Transitions> - <VisualState x:Name="Disabled"> - <Storyboard> - <ColorAnimation Duration="0" To="LightGray" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="PART_Arrow" /> - </Storyboard> - </VisualState> - <VisualState x:Name="Normal"/> - <VisualState x:Name="MouseOver"> - <Storyboard> - <ColorAnimation Duration="0" To="Black" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="PART_Arrow" /> - </Storyboard> - </VisualState> - <VisualState x:Name="Pressed"> - <Storyboard> - <ColorAnimation Duration="0" To="Black" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="PART_Arrow" /> - <DoubleAnimation Duration="0" By="1" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="PART_Arrow"/> - </Storyboard> - </VisualState> - </VisualStateGroup> - <VisualStateGroup x:Name="ButtonStates"> - <VisualState x:Name="Open"> - <Storyboard> - <DoubleAnimation Duration="0:0:0.4" To="0" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.Rotation)" Storyboard.TargetName="PART_Arrow"> - <DoubleAnimation.EasingFunction> - <CubicEase EasingMode="EaseOut"/> - </DoubleAnimation.EasingFunction> - </DoubleAnimation> - </Storyboard> - </VisualState> - <VisualState x:Name="Close"> - <Storyboard> - <DoubleAnimation Duration="0:0:0.4" To="180" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.Rotation)" Storyboard.TargetName="PART_Arrow"> - <DoubleAnimation.EasingFunction> - <CubicEase EasingMode="EaseOut"/> - </DoubleAnimation.EasingFunction> - </DoubleAnimation> - <DoubleAnimation Duration="0:0:0.4" To="0" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="PART_Arrow"/> - </Storyboard> - </VisualState> - </VisualStateGroup> - </VisualStateManager.VisualStateGroups> - - <Ellipse> - <Ellipse.Fill> - <LinearGradientBrush EndPoint="0.691,0.972" StartPoint="0.307,0.037"> - <GradientStop Color="#FFA2ADB8"/> - <GradientStop Color="White" Offset="1"/> - </LinearGradientBrush> - </Ellipse.Fill> - </Ellipse> - <Ellipse Margin="1"> - <Ellipse.Fill> - <LinearGradientBrush EndPoint="0.631,1" MappingMode="RelativeToBoundingBox" StartPoint="0.29,0.045"> - <GradientStop Color="#FFB8C3C8" Offset="1"/> - <GradientStop Color="#FFE7EBED" Offset="0.27"/> - </LinearGradientBrush> - </Ellipse.Fill> - </Ellipse> - <Path x:Name="PART_Arrow" Data="M27.671843,6 L31.333334,2 L35.02343,6 z" - HorizontalAlignment="Center" Width="8" Height="4" Stretch="Fill" UseLayoutRounding="False" - VerticalAlignment="Center" Fill="#FF686D76" RenderTransformOrigin="0.5,0.5"> - <Path.RenderTransform> - <CompositeTransform TranslateY="-1"/> - </Path.RenderTransform> - </Path> - </Grid> - </ControlTemplate> - </Setter.Value> - </Setter> - </Style> - - <Style TargetType="controls:FloatingWindowHost"> - <Setter Property="Width" Value="Auto" /> - <Setter Property="Height" Value="Auto" /> - <Setter Property="SnapinEnabled" Value="True" /> - <Setter Property="SnapinDistance" Value="5" /> - <Setter Property="SnapinMargin" Value="0" /> - <Setter Property="ShowMinimizedOnlyInIconbar" Value="False" /> - <Setter Property="HorizontalAlignment" Value="Stretch" /> - <Setter Property="VerticalAlignment" Value="Stretch" /> - <Setter Property="OverlayBrush" Value="#90202030" /> - <Setter Property="Background" Value="#FF7ED2E9" /> - - <Setter Property="Template"> - <Setter.Value> - <ControlTemplate TargetType="controls:FloatingWindowHost"> - <Grid x:Name="PART_Root" Background="{TemplateBinding Background}" - Width="{TemplateBinding Width}" Height="{TemplateBinding Height}"> - <VisualStateManager.VisualStateGroups> - <VisualStateGroup x:Name="OverlayStates"> - <VisualState x:Name="VisibleOverlay"> - <Storyboard> - <DoubleAnimationUsingKeyFrames BeginTime="0" Storyboard.TargetName="PART_Overlay" Storyboard.TargetProperty="Opacity"> - <SplineDoubleKeyFrame KeyTime="0:0:0.3" Value="1"/> - </DoubleAnimationUsingKeyFrames> - <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetName="PART_Overlay" Storyboard.TargetProperty="Visibility"> - <DiscreteObjectKeyFrame KeyTime="0"> - <DiscreteObjectKeyFrame.Value> - <Visibility>Visible</Visibility> - </DiscreteObjectKeyFrame.Value> - </DiscreteObjectKeyFrame> - </ObjectAnimationUsingKeyFrames> - </Storyboard> - </VisualState> - <VisualState x:Name="HiddenOverlay"> - <Storyboard> - <DoubleAnimationUsingKeyFrames BeginTime="0" Storyboard.TargetName="PART_Overlay" Storyboard.TargetProperty="Opacity"> - <SplineDoubleKeyFrame KeyTime="0:0:0.3" Value="0"/> - </DoubleAnimationUsingKeyFrames> - <ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_Overlay" Storyboard.TargetProperty="Visibility"> - <DiscreteObjectKeyFrame KeyTime="0:0:0.3"> - <DiscreteObjectKeyFrame.Value> - <Visibility>Collapsed</Visibility> - </DiscreteObjectKeyFrame.Value> - </DiscreteObjectKeyFrame> - </ObjectAnimationUsingKeyFrames> - </Storyboard> - </VisualState> - </VisualStateGroup> - </VisualStateManager.VisualStateGroups> - - <Grid x:Name="PART_ContentRoot"> - <Grid.RowDefinitions> - <RowDefinition Height="*" /> - <RowDefinition Height="Auto" /> - </Grid.RowDefinitions> - - <Canvas x:Name="PART_HostCanvas" /> - - <Grid x:Name="PART_IconBarContainer" VerticalAlignment="Bottom"> - <controls:IconBar x:Name="PART_IconBar"/> - </Grid> - - <Border x:Name="PART_BottomBar" Grid.Row="1" Style="{StaticResource BottomBarStyle}"> - <Grid> - <Grid.ColumnDefinitions> - <ColumnDefinition Width="Auto" /> - <ColumnDefinition Width="*" /> - </Grid.ColumnDefinitions> - - <controls:BootstrapButton x:Name="PART_BootstrapButton" Style="{StaticResource BootstrapButtonStyle}" - Margin="10,-4,10,0" IsOpen="{Binding IsOpen, ElementName=PART_IconBar}" /> - - <Border Grid.Column="1"> - <ContentControl x:Name="PART_BarContent" Content="{TemplateBinding Bar}" - VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" /> - </Border> - </Grid> - </Border> - </Grid> - - <Grid x:Name="PART_Overlay" Background="{TemplateBinding OverlayBrush}" Opacity="0" Visibility="Collapsed" /> - <Canvas x:Name="PART_ModalCanvas" /> - </Grid> - </ControlTemplate> - </Setter.Value> - </Setter> - </Style> - - <Style TargetType="controls:IconBar"> - <Setter Property="IsTabStop" Value="false"/> - <Setter Property="HorizontalAlignment" Value="Stretch"/> - <Setter Property="VerticalAlignment" Value="Bottom"/> - <Setter Property="Template"> - <Setter.Value> - <ControlTemplate TargetType="controls:IconBar"> - <Grid x:Name="PART_LayoutRoot"> - <VisualStateManager.VisualStateGroups> - <VisualStateGroup x:Name="VisualStateGroup"> - <VisualState x:Name="Open"> - <Storyboard> - <DoubleAnimation Duration="0:0:0.2" To="0" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="PART_FixedBar"> - <DoubleAnimation.EasingFunction> - <CubicEase EasingMode="EaseOut"/> - </DoubleAnimation.EasingFunction> - </DoubleAnimation> - <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetProperty="Visibility" Storyboard.TargetName="PART_FixedBar"> - <DiscreteObjectKeyFrame KeyTime="0"> - <DiscreteObjectKeyFrame.Value> - <Visibility>Visible</Visibility> - </DiscreteObjectKeyFrame.Value> - </DiscreteObjectKeyFrame> - </ObjectAnimationUsingKeyFrames> - </Storyboard> - </VisualState> - <VisualState x:Name="Closed"> - <Storyboard> - <DoubleAnimation Duration="0:0:0.2" To="104" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="PART_FixedBar"> - <DoubleAnimation.EasingFunction> - <CubicEase EasingMode="EaseOut"/> - </DoubleAnimation.EasingFunction> - </DoubleAnimation> - <ObjectAnimationUsingKeyFrames Duration="0:0:0.2" Storyboard.TargetProperty="Visibility" Storyboard.TargetName="PART_FixedBar"> - <DiscreteObjectKeyFrame KeyTime="0:0:0.2"> - <DiscreteObjectKeyFrame.Value> - <Visibility>Collapsed</Visibility> - </DiscreteObjectKeyFrame.Value> - </DiscreteObjectKeyFrame> - </ObjectAnimationUsingKeyFrames> - </Storyboard> - </VisualState> - </VisualStateGroup> - </VisualStateManager.VisualStateGroups> - - <Border x:Name="PART_FixedBar" RenderTransformOrigin="0.5,1" Style="{StaticResource IconBarStyle}"> - <Border.RenderTransform> - <!-- Hide the IconBar --> - <CompositeTransform TranslateY="104" /> - </Border.RenderTransform> - - <Canvas> - <Border x:Name="PART_SlidingBar" Canvas.Left="0" VerticalAlignment="Bottom"> - <StackPanel x:Name="PART_Carousel" RenderTransformOrigin="0.5,1" Orientation="Horizontal" - HorizontalAlignment="Left" VerticalAlignment="Bottom"/> - </Border> - </Canvas> - </Border> - </Grid> - </ControlTemplate> - </Setter.Value> - </Setter> - </Style> - - <Style x:Key="WindowIconStyle" TargetType="controls:WindowIcon"> - <Setter Property="IsTabStop" Value="false"/> - <Setter Property="Template"> - <Setter.Value> - <ControlTemplate TargetType="controls:WindowIcon"> - <Border x:Name="PART_Border" Style="{StaticResource IconBorderStyle}"> - <VisualStateManager.VisualStateGroups> - <VisualStateGroup x:Name="CommonStates"> - <VisualStateGroup.Transitions> - <VisualTransition From="MouseOver" GeneratedDuration="0:0:0.2" To="Normal"> - <VisualTransition.GeneratedEasingFunction> - <QuadraticEase EasingMode="EaseOut"/> - </VisualTransition.GeneratedEasingFunction> - </VisualTransition> - </VisualStateGroup.Transitions> - <VisualState x:Name="Disabled"/> - <VisualState x:Name="Normal" /> - <VisualState x:Name="MouseOver"> - <Storyboard> - <ColorAnimation Duration="0" To="White" Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)" Storyboard.TargetName="PART_Title" /> - <ColorAnimation Duration="0" To="#40F0F0FF" Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" Storyboard.TargetName="PART_Border" /> - <ColorAnimation Duration="0" To="#40F0F0FF" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[0].(GradientStop.Color)" Storyboard.TargetName="PART_Border" /> - <ColorAnimation Duration="0" To="#40F0F0FF" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[1].(GradientStop.Color)" Storyboard.TargetName="PART_Border" /> - </Storyboard> - </VisualState> - <VisualState x:Name="Pressed"> - <Storyboard> - <ColorAnimation Duration="0" To="White" Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)" Storyboard.TargetName="PART_Title" /> - <ColorAnimation Duration="0" To="#A0FFFFFF" Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" Storyboard.TargetName="PART_Border" /> - <ColorAnimation Duration="0" To="#90D0D0E0" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[0].(GradientStop.Color)" Storyboard.TargetName="PART_Border" /> - <ColorAnimation Duration="0" To="#80B0B0F0" Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[1].(GradientStop.Color)" Storyboard.TargetName="PART_Border" /> - </Storyboard> - </VisualState> - </VisualStateGroup> - </VisualStateManager.VisualStateGroups> - <Grid> - <Grid.RowDefinitions> - <RowDefinition Height="*" /> - <RowDefinition Height="Auto" /> - </Grid.RowDefinitions> - <Border Grid.Row="0" Padding="2"> - <Image x:Name="PART_Thumbnail" Stretch="None" /> - </Border> - <Border Grid.Row="1" HorizontalAlignment="Center"> - <TextBlock x:Name="PART_Title" Foreground="LightGray" VerticalAlignment="Center" Margin="5,2" TextTrimming="WordEllipsis" FontSize="10.667" /> - </Border> - </Grid> - </Border> - </ControlTemplate> - </Setter.Value> - </Setter> - </Style> - -</ResourceDictionary>
--- a/SilverlightGlimpse/SilverlightGlimpse.Test/App.xaml.cs Mon Apr 23 11:05:11 2012 +0100 +++ b/SilverlightGlimpse/SilverlightGlimpse.Test/App.xaml.cs Mon Apr 23 11:06:10 2012 +0100 @@ -1,8 +1,6 @@ using System; using System.Windows; using SilverlightGlimpse.Services; -//using Glimpse; -using System.Reflection; namespace SilverlightGlimpse.Test { @@ -19,14 +17,15 @@ private void Application_Startup(object sender, StartupEventArgs e) { + var appName = "Silverlight Glimpse"; try { RootVisual = new MainPage(); - GlimpseService.CreateInstance.Load(this, "Silverlight Glimpse"); + Glimpse.Service.Load(this, appName); } catch (Exception ex) { - GlimpseService.CreateInstance.DisplayLoadFailure(this, ex); + Glimpse.Service.DisplayLoadFailure(this, ex, appName); } } @@ -67,4 +66,4 @@ } } } -} +} \ No newline at end of file
--- a/SilverlightGlimpse/SilverlightGlimpse.Test/MainPage.xaml.cs Mon Apr 23 11:05:11 2012 +0100 +++ b/SilverlightGlimpse/SilverlightGlimpse.Test/MainPage.xaml.cs Mon Apr 23 11:06:10 2012 +0100 @@ -1,6 +1,14 @@ using System; -using System.Collections.Generic; +using System.Linq; +using System.Net; using System.Windows; +using System.Windows.Controls; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Animation; +using System.Windows.Shapes; +using System.Windows.Navigation; namespace SilverlightGlimpse.Test { @@ -9,7 +17,6 @@ public MainPage() { InitializeComponent(); - // uncomment this exception to view exception on startup //ThrowNestedException(); @@ -21,7 +28,7 @@ new Person { Id = 4 , Name = "Rich"}, new Person { Id = 5 , Name = "Clare"} }; - + listbox1.ItemsSource = list; }
--- a/SilverlightGlimpse/SilverlightGlimpse.Test/SilverlightGlimpse.Test.csproj Mon Apr 23 11:05:11 2012 +0100 +++ b/SilverlightGlimpse/SilverlightGlimpse.Test/SilverlightGlimpse.Test.csproj Mon Apr 23 11:06:10 2012 +0100 @@ -67,6 +67,7 @@ <Reference Include="system" /> <Reference Include="System.Core" /> <Reference Include="System.Windows.Controls, Version=5.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" /> + <Reference Include="System.Windows.Controls.Navigation, Version=5.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" /> <Reference Include="System.Xml" /> <Reference Include="System.Windows.Browser" /> </ItemGroup> @@ -84,10 +85,6 @@ <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> </ApplicationDefinition> - <Page Include="MainPage.xaml"> - <SubType>Designer</SubType> - <Generator>MSBuild:Compile</Generator> - </Page> </ItemGroup> <ItemGroup> <None Include="Properties\AppManifest.xml" /> @@ -101,6 +98,12 @@ <ItemGroup> <WCFMetadata Include="Service References\" /> </ItemGroup> + <ItemGroup> + <Page Include="MainPage.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:Compile</Generator> + </Page> + </ItemGroup> <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Silverlight\$(SilverlightVersion)\Microsoft.Silverlight.CSharp.targets" /> <!-- To modify your build process, add your task inside one of the targets below and uncomment it. Other similar extension points exist, see Microsoft.Common.targets.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SilverlightGlimpse/SilverlightGlimpse/Bugs.txt Mon Apr 23 11:06:10 2012 +0100 @@ -0,0 +1,2 @@ +Mutex for silverlight in debugmonitor +Refactor out the ValidationWrapper \ No newline at end of file
--- a/SilverlightGlimpse/SilverlightGlimpse/Controls/BrokenBindingsViewer.xaml Mon Apr 23 11:05:11 2012 +0100 +++ b/SilverlightGlimpse/SilverlightGlimpse/Controls/BrokenBindingsViewer.xaml Mon Apr 23 11:06:10 2012 +0100 @@ -11,12 +11,13 @@ </Grid.RowDefinitions> <StackPanel Grid.Row="0" Orientation="Horizontal"> - <TextBlock Width="125" + <TextBlock Width="145" Margin="7,0,0,0" Text="Control Name" /> - <TextBlock Width="100" Text="Type" /> - <TextBlock Width="100" Text="Property" /> - <TextBlock Width="100" Text="Path" /> + <TextBlock Width="120" Text="Type" /> + <TextBlock Width="120" Text="Property" /> + <TextBlock Width="150" Text="Path" /> + <TextBlock Width="50" Text="Quantity" /> </StackPanel> <ScrollViewer Grid.Row="1"> @@ -24,15 +25,15 @@ <ListBox.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal" ToolTipService.ToolTip="{Binding ToStringProperty}"> - <TextBlock Width="125" Text="{Binding ControlName}" /> - <TextBlock Width="100" Text="{Binding ControlTypeName}" /> - <TextBlock Width="100" Text="{Binding PropertyName}" /> - <TextBlock Text="{Binding Path}" /> + <TextBlock Width="145" Text="{Binding ControlName}" /> + <TextBlock Width="120" Text="{Binding ControlTypeName}" /> + <TextBlock Width="120" Text="{Binding PropertyName}" /> + <TextBlock Width="150" Text="{Binding Path}" /> + <TextBlock Width="50" Text="{Binding Quantity}" /> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox> - <!-- <ItemsControl x:Name="icBrokenBindings" /> --> </ScrollViewer> </Grid> </UserControl>
--- a/SilverlightGlimpse/SilverlightGlimpse/Controls/BrokenBindingsViewer.xaml.cs Mon Apr 23 11:05:11 2012 +0100 +++ b/SilverlightGlimpse/SilverlightGlimpse/Controls/BrokenBindingsViewer.xaml.cs Mon Apr 23 11:06:10 2012 +0100 @@ -16,9 +16,8 @@ private void BrokenBindings_Loaded(object sender, RoutedEventArgs e) { - //icBrokenBindings.Items.Clear(); lbBindings.Items.Clear(); - LoadBrokenBindings(GlimpseService.CreateInstance.RootVisual); + LoadBrokenBindings(Glimpse.Service.RootVisual); } private void LoadBrokenBindings(UIElement uiElement) @@ -44,14 +43,14 @@ if (string.Compare(propertyInfo.Name, bindingExpression.ParentBinding.Path.Path) == 0) { isInherited = true; - break; // TODO: might not be correct. Was : Exit For + break; } } } if (isInherited) { - break; // TODO: might not be correct. Was : Exit For + break; } //this code handles empty bindings on the Button controls @@ -61,7 +60,7 @@ && fieldInfo.Name == "TextProperty" && string.IsNullOrEmpty(bindingExpression.ParentBinding.Path.Path)) { - break; // TODO: might not be correct. Was : Exit For + break; } var brokenBinding = new BrokenBinding( @@ -70,7 +69,6 @@ fieldInfo.Name, bindingExpression.ParentBinding.Path.Path); - //icBrokenBindings.Items.Add(brokenBinding); lbBindings.Items.Add(brokenBinding); Debug.WriteLine("Broken Binding: {0}", brokenBinding); }
--- a/SilverlightGlimpse/SilverlightGlimpse/Controls/ExceptionsViewer.xaml Mon Apr 23 11:05:11 2012 +0100 +++ b/SilverlightGlimpse/SilverlightGlimpse/Controls/ExceptionsViewer.xaml Mon Apr 23 11:06:10 2012 +0100 @@ -37,60 +37,58 @@ Margin="3.5" DataContext="{Binding ElementName=lbExceptions, Path=SelectedItem}"> - <Grid> + <Grid x:Name="gridExceptionDetail"> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> - <RowDefinition Height="Auto" /> - <RowDefinition Height="Auto" /> - <RowDefinition Height="Auto" /> - <RowDefinition Height="Auto" /> </Grid.RowDefinitions> - <TextBlock x:Name="tbAction" - Text="Action" - TextDecorations="Underline" - Visibility="Collapsed" /> - - <TextBlock Grid.Row="1" - FontSize="11" - Text="{Binding Path=Action}" - TextWrapping="Wrap" - Visibility="{Binding ElementName=tbAction, - Path=Visibility}" /> + <!-- + <TextBlock x:Name="tbAction" + Text="Action" + TextDecorations="Underline" + Visibility="Collapsed" /> + + <TextBlock Grid.Row="1" + FontSize="11" + Text="{Binding Path=Action}" + TextWrapping="Wrap" + Visibility="{Binding ElementName=tbAction, + Path=Visibility}" /> + + <TextBlock Grid.Row="2" + Margin="0,7,0,0" + Text="Control Name" + TextDecorations="Underline" + Visibility="{Binding ElementName=tbAction, + Path=Visibility}" /> + <TextBlock Grid.Row="3" + FontSize="11" + Text="{Binding Path=ControlName}" + TextWrapping="Wrap" + Visibility="{Binding ElementName=tbAction, + Path=Visibility}" /> + --> - <TextBlock Grid.Row="2" - Margin="0,7,0,0" - Text="Control Name" - TextDecorations="Underline" - Visibility="{Binding ElementName=tbAction, - Path=Visibility}" /> - <TextBlock Grid.Row="3" - FontSize="11" - Text="{Binding Path=ControlName}" - TextWrapping="Wrap" - Visibility="{Binding ElementName=tbAction, - Path=Visibility}" /> - - <TextBlock Grid.Row="4" + <TextBlock Grid.Row="0" Margin="0,7,0,0" Text="Message" TextDecorations="Underline" /> - <TextBlock Grid.Row="5" + <TextBlock Grid.Row="1" FontSize="11" - Text="{Binding Path=Exception.Message}" + Text="{Binding Path=Message}" TextWrapping="Wrap" /> - <TextBlock Grid.Row="6" + <TextBlock Grid.Row="2" Margin="0,7,0,0" Text="Stack Trace" TextDecorations="Underline" /> - <TextBlock Grid.Row="7" + <TextBlock Grid.Row="3" FontSize="11" - Text="{Binding Path=Exception.StackTrace}" + Text="{Binding Path=StackTrace}" TextWrapping="Wrap" /> </Grid>
--- a/SilverlightGlimpse/SilverlightGlimpse/Controls/ExceptionsViewer.xaml.cs Mon Apr 23 11:05:11 2012 +0100 +++ b/SilverlightGlimpse/SilverlightGlimpse/Controls/ExceptionsViewer.xaml.cs Mon Apr 23 11:06:10 2012 +0100 @@ -14,24 +14,21 @@ private void ClearExceptions_Click(object sender, RoutedEventArgs e) { - GlimpseService.CreateInstance.HostExceptions.Clear(); + Glimpse.Service.Exceptions.Clear(); } private void ExceptionsViewer_Loaded(object sender, RoutedEventArgs e) { - DataContext = GlimpseService.CreateInstance.HostExceptions; - if (GlimpseService.CreateInstance.HostExceptions.Count > 0) + DataContext = Glimpse.Service.Exceptions; + if (Glimpse.Service.Exceptions.Count > 0) lbExceptions.SelectedIndex = 0; } private void lbExceptions_SelectionChanged(object sender, SelectionChangedEventArgs e) { - if (lbExceptions.SelectedItem == null || !(lbExceptions.SelectedItem is ExceptionWrapper)) - return; - - tbAction.Visibility = ((ExceptionWrapper)lbExceptions.SelectedItem).IsValidationException - ? Visibility.Visible - : Visibility.Collapsed; + gridExceptionDetail.Visibility = lbExceptions.SelectedItem == null + ? Visibility.Collapsed + : Visibility.Visible; } } } \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SilverlightGlimpse/SilverlightGlimpse/Controls/FloatableWindow/FloatableWindow.cs Mon Apr 23 11:06:10 2012 +0100 @@ -0,0 +1,1623 @@ +// Original code: http://floatablewindow.codeplex.com/ +// Author: Tim Heuer http://timheuer.com/blog/ + +// This source is subject to the Microsoft Public License (Ms-PL). +// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details. +// All other rights reserved. + +using System.Collections; +using System.ComponentModel; +using System.Diagnostics; +using System.Windows.Automation; +using System.Windows.Automation.Peers; +using System.Windows.Controls.Primitives; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Animation; + +namespace System.Windows.Controls +{ + /// <summary> + /// Provides a window that can be displayed over a parent window and blocks + /// interaction with the parent window. + /// </summary> + /// <QualityBand>Preview</QualityBand> + [TemplatePart(Name = PART_Chrome, Type = typeof(FrameworkElement))] + [TemplatePart(Name = PART_CloseButton, Type = typeof(ButtonBase))] + [TemplatePart(Name = PART_ContentPresenter, Type = typeof(FrameworkElement))] + [TemplatePart(Name = PART_ContentRoot, Type = typeof(FrameworkElement))] + [TemplatePart(Name = PART_Overlay, Type = typeof(Panel))] + [TemplatePart(Name = PART_Root, Type = typeof(FrameworkElement))] + [TemplateVisualState(Name = VSMSTATE_StateClosed, GroupName = VSMGROUP_Window)] + [TemplateVisualState(Name = VSMSTATE_StateOpen, GroupName = VSMGROUP_Window)] + public class FloatableWindow : ContentControl + { + #region Static Fields and Constants + + /// <summary> + /// The name of the Chrome template part. + /// </summary> + private const string PART_Chrome = "Chrome"; + + /// <summary> + /// The name of the CloseButton template part. + /// </summary> + private const string PART_CloseButton = "CloseButton"; + + /// <summary> + /// The name of the ContentPresenter template part. + /// </summary> + private const string PART_ContentPresenter = "ContentPresenter"; + + /// <summary> + /// The name of the ContentRoot template part. + /// </summary> + private const string PART_ContentRoot = "ContentRoot"; + + /// <summary> + /// The name of the Overlay template part. + /// </summary> + private const string PART_Overlay = "Overlay"; + + /// <summary> + /// The name of the Root template part. + /// </summary> + private const string PART_Root = "Root"; + + /// <summary> + /// The name of the WindowStates VSM group. + /// </summary> + private const string VSMGROUP_Window = "WindowStates"; + + /// <summary> + /// The name of the Closing VSM state. + /// </summary> + private const string VSMSTATE_StateClosed = "Closed"; + + /// <summary> + /// The name of the Opening VSM state. + /// </summary> + private const string VSMSTATE_StateOpen = "Open"; + + #region public bool HasCloseButton + + /// <summary> + /// Gets or sets a value indicating whether the + /// <see cref="T:System.Windows.Controls.FloatableWindow" /> has a close + /// button. + /// </summary> + /// <value> + /// True if the child window has a close button; otherwise, false. The + /// default is true. + /// </value> + public bool HasCloseButton + { + get { return (bool)GetValue(HasCloseButtonProperty); } + set { SetValue(HasCloseButtonProperty, value); } + } + + /// <summary> + /// Identifies the + /// <see cref="P:System.Windows.Controls.FloatableWindow.HasCloseButton" /> + /// dependency property. + /// </summary> + /// <value> + /// The identifier for the + /// <see cref="P:System.Windows.Controls.FloatableWindow.HasCloseButton" /> + /// dependency property. + /// </value> + public static readonly DependencyProperty HasCloseButtonProperty = + DependencyProperty.Register( + "HasCloseButton", + typeof(bool), + typeof(FloatableWindow), + new PropertyMetadata(true, OnHasCloseButtonPropertyChanged)); + + /// <summary> + /// HasCloseButtonProperty PropertyChangedCallback call back static function. + /// </summary> + /// <param name="d">FloatableWindow object whose HasCloseButton property is changed.</param> + /// <param name="e">DependencyPropertyChangedEventArgs which contains the old and new values.</param> + private static void OnHasCloseButtonPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + FloatableWindow cw = (FloatableWindow)d; + + if (cw.CloseButton != null) + { + if ((bool)e.NewValue) + { + cw.CloseButton.Visibility = Visibility.Visible; + } + else + { + cw.CloseButton.Visibility = Visibility.Collapsed; + } + } + } + + #endregion public bool HasCloseButton + + #region public Brush OverlayBrush + + /// <summary> + /// Gets or sets the visual brush that is used to cover the parent + /// window when the child window is open. + /// </summary> + /// <value> + /// The visual brush that is used to cover the parent window when the + /// <see cref="T:System.Windows.Controls.FloatableWindow" /> is open. The + /// default is null. + /// </value> + public Brush OverlayBrush + { + get { return (Brush)GetValue(OverlayBrushProperty); } + set { SetValue(OverlayBrushProperty, value); } + } + + /// <summary> + /// Identifies the + /// <see cref="P:System.Windows.Controls.FloatableWindow.OverlayBrush" /> + /// dependency property. + /// </summary> + /// <value> + /// The identifier for the + /// <see cref="P:System.Windows.Controls.FloatableWindow.OverlayBrush" /> + /// dependency property. + /// </value> + public static readonly DependencyProperty OverlayBrushProperty = + DependencyProperty.Register( + "OverlayBrush", + typeof(Brush), + typeof(FloatableWindow), + new PropertyMetadata(OnOverlayBrushPropertyChanged)); + + /// <summary> + /// OverlayBrushProperty PropertyChangedCallback call back static function. + /// </summary> + /// <param name="d">FloatableWindow object whose OverlayBrush property is changed.</param> + /// <param name="e">DependencyPropertyChangedEventArgs which contains the old and new values.</param> + private static void OnOverlayBrushPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + FloatableWindow cw = (FloatableWindow)d; + + if (cw.Overlay != null) + { + cw.Overlay.Background = (Brush)e.NewValue; + } + } + + #endregion public Brush OverlayBrush + + #region public double OverlayOpacity + + /// <summary> + /// Gets or sets the opacity of the overlay brush that is used to cover + /// the parent window when the child window is open. + /// </summary> + /// <value> + /// The opacity of the overlay brush that is used to cover the parent + /// window when the <see cref="T:System.Windows.Controls.FloatableWindow" /> + /// is open. The default is 1.0. + /// </value> + public double OverlayOpacity + { + get { return (double)GetValue(OverlayOpacityProperty); } + set { SetValue(OverlayOpacityProperty, value); } + } + + /// <summary> + /// Identifies the + /// <see cref="P:System.Windows.Controls.FloatableWindow.OverlayOpacity" /> + /// dependency property. + /// </summary> + /// <value> + /// The identifier for the + /// <see cref="P:System.Windows.Controls.FloatableWindow.OverlayOpacity" /> + /// dependency property. + /// </value> + public static readonly DependencyProperty OverlayOpacityProperty = + DependencyProperty.Register( + "OverlayOpacity", + typeof(double), + typeof(FloatableWindow), + new PropertyMetadata(OnOverlayOpacityPropertyChanged)); + + /// <summary> + /// OverlayOpacityProperty PropertyChangedCallback call back static function. + /// </summary> + /// <param name="d">FloatableWindow object whose OverlayOpacity property is changed.</param> + /// <param name="e">DependencyPropertyChangedEventArgs which contains the old and new values.</param> + private static void OnOverlayOpacityPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + FloatableWindow cw = (FloatableWindow)d; + + if (cw.Overlay != null) + { + cw.Overlay.Opacity = (double)e.NewValue; + } + } + + #endregion public double OverlayOpacity + + #region private static Control RootVisual + + /// <summary> + /// Gets the root visual element. + /// </summary> + private static Control RootVisual + { + get + { + return Application.Current == null ? null : (Application.Current.RootVisual as Control); + } + } + + #endregion private static Control RootVisual + + #region public object Title + + /// <summary> + /// Gets or sets the title that is displayed in the frame of the + /// <see cref="T:System.Windows.Controls.FloatableWindow" />. + /// </summary> + /// <value> + /// The title displayed at the top of the window. The default is null. + /// </value> + public object Title + { + get { return GetValue(TitleProperty); } + set { SetValue(TitleProperty, value); } + } + + /// <summary> + /// Identifies the + /// <see cref="P:System.Windows.Controls.FloatableWindow.Title" /> + /// dependency property. + /// </summary> + /// <value> + /// The identifier for the + /// <see cref="P:System.Windows.Controls.FloatableWindow.Title" /> + /// dependency property. + /// </value> + public static readonly DependencyProperty TitleProperty = + DependencyProperty.Register( + "Title", + typeof(object), + typeof(FloatableWindow), + null); + + #endregion public object Title + + #endregion Static Fields and Constants + + #region Member Fields + /// <summary> + /// Set in the overloaded Show method. Offsets the Popup vertically from the top left corner of the browser window by this amount. + /// </summary> + private double _verticalOffset; + + /// <summary> + /// Set in the overloaded Show method. Offsets the Popup horizontally from the top left corner of the browser window by this amount. + /// </summary> + private double _horizontalOffset; + + /// <summary> + /// Private accessor for the Resizer. + /// </summary> + private FrameworkElement _resizer; + + /// <summary> + /// Private accessor for the IsModal + /// </summary> + [DefaultValue(false)] + private bool _modal; + + /// <summary> + /// Private accessor for the Chrome. + /// </summary> + private FrameworkElement _chrome; + + /// <summary> + /// Private accessor for the click point on the chrome. + /// </summary> + private Point _clickPoint; + + /// <summary> + /// Private accessor for the Closing storyboard. + /// </summary> + private Storyboard _closed; + + /// <summary> + /// Private accessor for the ContentPresenter. + /// </summary> + private FrameworkElement _contentPresenter; + + /// <summary> + /// Private accessor for the translate transform that needs to be applied on to the ContentRoot. + /// </summary> + private TranslateTransform _contentRootTransform; + + /// <summary> + /// Content area desired width. + /// </summary> + private double _desiredContentWidth; + + /// <summary> + /// Content area desired height. + /// </summary> + private double _desiredContentHeight; + + /// <summary> + /// Desired margin for the window. + /// </summary> + private Thickness _desiredMargin; + + /// <summary> + /// Private accessor for the Dialog Result property. + /// </summary> + private bool? _dialogresult; + + /// <summary> + /// Private accessor for the FloatableWindow InteractionState. + /// </summary> + private WindowInteractionState _interactionState; + + /// <summary> + /// Boolean value that specifies whether the application is exit or not. + /// </summary> + private bool _isAppExit; + + /// <summary> + /// Boolean value that specifies whether the window is in closing state or not. + /// </summary> + private bool _isClosing; + + /// <summary> + /// Boolean value that specifies whether the window is opened. + /// </summary> + private bool _isOpen; + + /// <summary> + /// Private accessor for the Opening storyboard. + /// </summary> + private Storyboard _opened; + + /// <summary> + /// Boolean value that specifies whether the mouse is captured or not. + /// </summary> + private bool _isMouseCaptured; + + /// <summary> + /// Private accessor for the Root of the window. + /// </summary> + private FrameworkElement _root; + + /// <summary> + /// Private accessor for the position of the window with respect to RootVisual. + /// </summary> + private Point _windowPosition; + + private static int z; + + #endregion Member Fields + + #region Constructors + + /// <summary> + /// Initializes a new instance of the + /// <see cref="T:System.Windows.Controls.FloatableWindow" /> class. + /// </summary> + public FloatableWindow() + { + this.DefaultStyleKey = typeof(FloatableWindow); + this.InteractionState = WindowInteractionState.NotResponding; + } + + #endregion Constructors + + #region Events + + /// <summary> + /// Occurs when the <see cref="T:System.Windows.Controls.FloatableWindow" /> + /// is closed. + /// </summary> + public event EventHandler Closed; + + /// <summary> + /// Occurs when the <see cref="T:System.Windows.Controls.FloatableWindow" /> + /// is closing. + /// </summary> + public event EventHandler<CancelEventArgs> Closing; + + #endregion Events + + #region Properties + + private Panel _parentLayoutRoot; + public Panel ParentLayoutRoot + { + get { return _parentLayoutRoot; } + set { _parentLayoutRoot = value; } + } + + /// <summary> + /// Gets the internal accessor for the ContentRoot of the window. + /// </summary> + internal FrameworkElement ContentRoot + { + get; + private set; + } + + /// <summary> + /// Setting for the horizontal positioning offset for start position + /// </summary> + public double HorizontalOffset + { + get { return _horizontalOffset; } + set { _horizontalOffset = value; } + } + + /// <summary> + /// Setting for the vertical positioning offset for start position + /// </summary> + public double VerticalOffset + { + get { return _verticalOffset; } + set { _verticalOffset = value; } + } + + /// <summary> + /// Gets the internal accessor for the modal of the window. + /// </summary> + public bool IsModal + { + get + { + return _modal; + } + } + + /// <summary> + /// Gets or sets a value indicating whether the + /// <see cref="T:System.Windows.Controls.FloatableWindow" /> was accepted or + /// canceled. + /// </summary> + /// <value> + /// True if the child window was accepted; false if the child window was + /// canceled. The default is null. + /// </value> + [TypeConverter(typeof(NullableBoolConverter))] + public bool? DialogResult + { + get + { + return this._dialogresult; + } + + set + { + if (this._dialogresult != value) + { + this._dialogresult = value; + this.Close(); + } + } + } + + /// <summary> + /// Gets the internal accessor for the PopUp of the window. + /// </summary> + internal Popup ChildWindowPopup + { + get; + private set; + } + + /// <summary> + /// Gets the internal accessor for the close button of the window. + /// </summary> + internal ButtonBase CloseButton + { + get; + private set; + } + + /// <summary> + /// Gets the InteractionState for the FloatableWindow. + /// </summary> + internal WindowInteractionState InteractionState + { + get + { + return this._interactionState; + } + private set + { + if (this._interactionState != value) + { + WindowInteractionState oldValue = this._interactionState; + this._interactionState = value; + FloatableWindowAutomationPeer peer = FloatableWindowAutomationPeer.FromElement(this) as FloatableWindowAutomationPeer; + + if (peer != null) + { + peer.RaiseInteractionStatePropertyChangedEvent(oldValue, this._interactionState); + } + } + } + } + + /// <summary> + /// Gets a value indicating whether the PopUp is open or not. + /// </summary> + private bool IsOpen + { + get + { + return (this.ChildWindowPopup != null && this.ChildWindowPopup.IsOpen) || + ((ParentLayoutRoot != null) && (ParentLayoutRoot.Children.Contains(this))); + } + } + + /// <summary> + /// Gets the internal accessor for the overlay of the window. + /// </summary> + internal Panel Overlay + { + get; + private set; + } + + #endregion Properties + + #region Static Methods + + /// <summary> + /// Inverts the input matrix. + /// </summary> + /// <param name="matrix">The matrix values that is to be inverted.</param> + /// <returns>Returns a value indicating whether the inversion was successful or not.</returns> + private static bool InvertMatrix(ref Matrix matrix) + { + double determinant = (matrix.M11 * matrix.M22) - (matrix.M12 * matrix.M21); + + if (determinant == 0.0) + { + return false; + } + + Matrix matCopy = matrix; + matrix.M11 = matCopy.M22 / determinant; + matrix.M12 = -1 * matCopy.M12 / determinant; + matrix.M21 = -1 * matCopy.M21 / determinant; + matrix.M22 = matCopy.M11 / determinant; + matrix.OffsetX = ((matCopy.OffsetY * matCopy.M21) - (matCopy.OffsetX * matCopy.M22)) / determinant; + matrix.OffsetY = ((matCopy.OffsetX * matCopy.M12) - (matCopy.OffsetY * matCopy.M11)) / determinant; + + return true; + } + + #endregion Static Methods + + #region Methods + + /// <summary> + /// Executed when the application is exited. + /// </summary> + /// <param name="sender">The sender.</param> + /// <param name="e">Event args.</param> + internal void Application_Exit(object sender, EventArgs e) + { + if (this.IsOpen) + { + this._isAppExit = true; + try + { + this.Close(); + } + finally + { + this._isAppExit = false; + } + } + } + + /// <summary> + /// Executed when focus is given to the window via a click. Attempts to bring current + /// window to the front in the event there are more windows. + /// </summary> + internal void BringToFront() + { + z++; + Canvas.SetZIndex(this, z); +#if DEBUG + this.Title = z.ToString(); +#endif + } + + /// <summary> + /// Changes the visual state of the FloatableWindow. + /// </summary> + private void ChangeVisualState() + { + if (this._isClosing) + { + VisualStateManager.GoToState(this, VSMSTATE_StateClosed, true); + } + else + { + VisualStateManager.GoToState(this, VSMSTATE_StateOpen, true); + BringToFront(); + } + } + + /// <summary> + /// Executed when FloatableWindow size is changed. + /// </summary> + /// <param name="sender">Sender object.</param> + /// <param name="e">Size changed event args.</param> + private void ChildWindow_SizeChanged(object sender, SizeChangedEventArgs e) + { + if (_modal) + { + if (this.Overlay != null) + { + if (e.NewSize.Height != this.Overlay.Height) + { + this._desiredContentHeight = e.NewSize.Height; + } + + if (e.NewSize.Width != this.Overlay.Width) + { + this._desiredContentWidth = e.NewSize.Width; + } + } + + if (this.IsOpen) + { + this.UpdateOverlaySize(); + } + } + } + + /// <summary> + /// Closes a <see cref="T:System.Windows.Controls.FloatableWindow" />. + /// </summary> + public void Close() + { + // AutomationPeer returns "Closing" when Close() is called + // but the window is not closed completely: + this.InteractionState = WindowInteractionState.Closing; + CancelEventArgs e = new CancelEventArgs(); + this.OnClosing(e); + + // On ApplicationExit, close() cannot be cancelled + if (!e.Cancel || this._isAppExit) + { + if (RootVisual != null) + { + RootVisual.IsEnabled = true; + } + + // Close Popup + if (this.IsOpen) + { + if (this._closed != null) + { + // Popup will be closed when the storyboard ends + this._isClosing = true; + try + { + var sb = GetVisualStateStoryboard("WindowStates", "Closed"); + sb.Completed += (s, args) => + { + this.ParentLayoutRoot.Children.Remove(this); + this.OnClosed(EventArgs.Empty); + this.UnSubscribeFromEvents(); + this.UnsubscribeFromTemplatePartEvents(); + + if (Application.Current.RootVisual != null) + { + Application.Current.RootVisual.GotFocus -= new RoutedEventHandler(this.RootVisual_GotFocus); + } + }; + this.ChangeVisualState(); + } + finally + { + this._isClosing = false; + } + } + else + { + // If no closing storyboard is defined, close the Popup + this.ChildWindowPopup.IsOpen = false; + } + + if (!this._dialogresult.HasValue) + { + // If close action is not happening because of DialogResult property change action, + // Dialogresult is always false: + this._dialogresult = false; + } + + //this.OnClosed(EventArgs.Empty); + //this.UnSubscribeFromEvents(); + //this.UnsubscribeFromTemplatePartEvents(); + + //if (Application.Current.RootVisual != null) + //{ + // Application.Current.RootVisual.GotFocus -= new RoutedEventHandler(this.RootVisual_GotFocus); + //} + } + } + else + { + // If the Close is cancelled, DialogResult should always be NULL: + this._dialogresult = null; + this.InteractionState = WindowInteractionState.Running; + } + } + + /// <summary> + /// Brings the window to the front of others + /// </summary> + /// <param name="sender"></param> + /// <param name="e"></param> + internal void ContentRoot_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) + { + BringToFront(); + } + + /// <summary> + /// Executed when the CloseButton is clicked. + /// </summary> + /// <param name="sender">Sender object.</param> + /// <param name="e">Routed event args.</param> + internal void CloseButton_Click(object sender, RoutedEventArgs e) + { + this.Close(); + } + + /// <summary> + /// Executed when the Closing storyboard ends. + /// </summary> + /// <param name="sender">Sender object.</param> + /// <param name="e">Event args.</param> + private void Closing_Completed(object sender, EventArgs e) + { + if (this.ChildWindowPopup != null) + { + this.ChildWindowPopup.IsOpen = false; + } + + // AutomationPeer returns "NotResponding" when the FloatableWindow is closed: + this.InteractionState = WindowInteractionState.NotResponding; + + if (this._closed != null) + { + this._closed.Completed -= new EventHandler(this.Closing_Completed); + } + } + + /// <summary> + /// Executed when the a key is presses when the window is open. + /// </summary> + /// <param name="sender">Sender object.</param> + /// <param name="e">Key event args.</param> + private void ChildWindow_KeyDown(object sender, KeyEventArgs e) + { + FloatableWindow ew = sender as FloatableWindow; + Debug.Assert(ew != null, "FloatableWindow instance is null."); + + // Ctrl+Shift+F4 closes the FloatableWindow + if (e != null && !e.Handled && e.Key == Key.F4 && + ((Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control) && + ((Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift)) + { + ew.Close(); + e.Handled = true; + } + } + + /// <summary> + /// Executed when the window loses focus. + /// </summary> + /// <param name="sender">Sender object.</param> + /// <param name="e">Routed event args.</param> + private void ChildWindow_LostFocus(object sender, RoutedEventArgs e) + { + // If the FloatableWindow loses focus but the popup is still open, + // it means another popup is opened. To get the focus back when the + // popup is closed, we handle GotFocus on the RootVisual + // TODO: Something else could get focus and handle the GotFocus event right. + // Try listening to routed events that were Handled (new SL 3 feature) + // Blocked by Jolt bug #29419 + if (this.IsOpen && Application.Current != null && Application.Current.RootVisual != null) + { + this.InteractionState = WindowInteractionState.BlockedByModalWindow; + Application.Current.RootVisual.GotFocus += new RoutedEventHandler(this.RootVisual_GotFocus); + } + } + + /// <summary> + /// Executed when mouse left button is down on the chrome. + /// </summary> + /// <param name="sender">Sender object.</param> + /// <param name="e">Mouse button event args.</param> + private void Chrome_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) + { + if (this._chrome != null) + { + e.Handled = true; + + if (this.CloseButton != null && !this.CloseButton.IsTabStop) + { + this.CloseButton.IsTabStop = true; + try + { + this.Focus(); + } + finally + { + this.CloseButton.IsTabStop = false; + } + } + else + { + this.Focus(); + } + this._chrome.CaptureMouse(); + this._isMouseCaptured = true; + this._clickPoint = e.GetPosition(sender as UIElement); +#if DEBUG + this.Title = string.Format("X:{0},Y:{1}", this._clickPoint.X.ToString(), this._clickPoint.Y.ToString()); +#endif + } + } + + /// <summary> + /// Executed when mouse left button is up on the chrome. + /// </summary> + /// <param name="sender">Sender object.</param> + /// <param name="e">Mouse button event args.</param> + private void Chrome_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) + { + if (this._chrome != null) + { + //e.Handled = true; + this._chrome.ReleaseMouseCapture(); + this._isMouseCaptured = false; + } + } + + /// <summary> + /// Executed when mouse moves on the chrome. + /// </summary> + /// <param name="sender">Sender object.</param> + /// <param name="e">Mouse event args.</param> + private void Chrome_MouseMove(object sender, MouseEventArgs e) + { + #region New ChildWindow Code not working + //if (this._isMouseCaptured && this.ContentRoot != null && Application.Current != null && Application.Current.RootVisual != null) + //{ + // Point position = e.GetPosition(Application.Current.RootVisual); + + // GeneralTransform gt = this.ContentRoot.TransformToVisual(Application.Current.RootVisual); + + // if (gt != null) + // { + // Point p = gt.Transform(this._clickPoint); + // this._windowPosition = gt.Transform(new Point(0, 0)); + + // if (position.X < 0) + // { + // double Y = FindPositionY(p, position, 0); + // position = new Point(0, Y); + // } + + // if (position.X > this.Width) + // { + // double Y = FindPositionY(p, position, this.Width); + // position = new Point(this.Width, Y); + // } + + // if (position.Y < 0) + // { + // double X = FindPositionX(p, position, 0); + // position = new Point(X, 0); + // } + + // if (position.Y > this.Height) + // { + // double X = FindPositionX(p, position, this.Height); + // position = new Point(X, this.Height); + // } + + // double x = position.X - p.X; + // double y = position.Y - p.Y; + // UpdateContentRootTransform(x, y); + // } + //} + #endregion + if (this._isMouseCaptured && this.ContentRoot != null) + { + // If the child window is dragged out of the page, return + if (Application.Current != null && Application.Current.RootVisual != null && + (e.GetPosition(Application.Current.RootVisual).X < 0 || e.GetPosition(Application.Current.RootVisual).Y < 0)) + { + return; + } + + TransformGroup transformGroup = this.ContentRoot.RenderTransform as TransformGroup; + + if (transformGroup == null) + { + transformGroup = new TransformGroup(); + transformGroup.Children.Add(this.ContentRoot.RenderTransform); + } + + TranslateTransform t = new TranslateTransform(); + t.X = e.GetPosition(this.ContentRoot).X - this._clickPoint.X; + t.Y = e.GetPosition(this.ContentRoot).Y - this._clickPoint.Y; + if (transformGroup != null) + { + transformGroup.Children.Add(t); + this.ContentRoot.RenderTransform = transformGroup; + } + } + } + + /// <summary> + /// Finds the X coordinate of a point that is defined by a line. + /// </summary> + /// <param name="p1">Starting point of the line.</param> + /// <param name="p2">Ending point of the line.</param> + /// <param name="y">Y coordinate of the point.</param> + /// <returns>X coordinate of the point.</returns> + private static double FindPositionX(Point p1, Point p2, double y) + { + if (y == p1.Y || p1.X == p2.X) + { + return p2.X; + } + + Debug.Assert(p1.Y != p2.Y, "Unexpected equal Y coordinates"); + + return (((y - p1.Y) * (p1.X - p2.X)) / (p1.Y - p2.Y)) + p1.X; + } + + /// <summary> + /// Finds the Y coordinate of a point that is defined by a line. + /// </summary> + /// <param name="p1">Starting point of the line.</param> + /// <param name="p2">Ending point of the line.</param> + /// <param name="x">X coordinate of the point.</param> + /// <returns>Y coordinate of the point.</returns> + private static double FindPositionY(Point p1, Point p2, double x) + { + if (p1.Y == p2.Y || x == p1.X) + { + return p2.Y; + } + + Debug.Assert(p1.X != p2.X, "Unexpected equal X coordinates"); + + return (((p1.Y - p2.Y) * (x - p1.X)) / (p1.X - p2.X)) + p1.Y; + } + + /// <summary> + /// Builds the visual tree for the + /// <see cref="T:System.Windows.Controls.FloatableWindow" /> control when a + /// new template is applied. + /// </summary> + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Justification = "No need to split the code into two parts.")] + public override void OnApplyTemplate() + { + this.UnsubscribeFromTemplatePartEvents(); + + base.OnApplyTemplate(); + + this.CloseButton = GetTemplateChild(PART_CloseButton) as ButtonBase; + + if (this.CloseButton != null) + { + if (this.HasCloseButton) + { + this.CloseButton.Visibility = Visibility.Visible; + } + else + { + this.CloseButton.Visibility = Visibility.Collapsed; + } + } + + if (this._closed != null) + { + this._closed.Completed -= new EventHandler(this.Closing_Completed); + } + + if (this._opened != null) + { + this._opened.Completed -= new EventHandler(this.Opening_Completed); + } + + this._root = GetTemplateChild(PART_Root) as FrameworkElement; + + if (this._root != null) + { + IList groups = VisualStateManager.GetVisualStateGroups(this._root); + + if (groups != null) + { + IList states = null; + + foreach (VisualStateGroup vsg in groups) + { + if (vsg.Name == FloatableWindow.VSMGROUP_Window) + { + states = vsg.States; + break; + } + } + + if (states != null) + { + foreach (VisualState state in states) + { + if (state.Name == FloatableWindow.VSMSTATE_StateClosed) + { + this._closed = state.Storyboard; + } + + if (state.Name == FloatableWindow.VSMSTATE_StateOpen) + { + this._opened = state.Storyboard; + } + } + } + } + //TODO: Figure out why I can't wire up the event below in SubscribeToTemplatePartEvents + this._root.MouseLeftButtonDown += new MouseButtonEventHandler(this.ContentRoot_MouseLeftButtonDown); + } + + this.ContentRoot = GetTemplateChild(PART_ContentRoot) as FrameworkElement; + + this._chrome = GetTemplateChild(PART_Chrome) as FrameworkElement; + + this.Overlay = GetTemplateChild(PART_Overlay) as Panel; + + this._contentPresenter = GetTemplateChild(PART_ContentPresenter) as FrameworkElement; + + this.SubscribeToTemplatePartEvents(); + this.SubscribeToStoryBoardEvents(); + this._desiredMargin = this.Margin; + this.Margin = new Thickness(0); + + // Update overlay size + if (this.IsOpen && (this.ChildWindowPopup != null)) + { + this._desiredContentHeight = this.Height; + this._desiredContentWidth = this.Width; + this.UpdateOverlaySize(); + this.UpdateRenderTransform(); + this.ChangeVisualState(); + } + } + + + /// <summary> + /// Raises the + /// <see cref="E:System.Windows.Controls.FloatableWindow.Closed" /> event. + /// </summary> + /// <param name="e">The event data.</param> + protected virtual void OnClosed(EventArgs e) + { + EventHandler handler = this.Closed; + + if (null != handler) + { + handler(this, e); + } + + this._isOpen = false; + if (!_modal) + { + this.ParentLayoutRoot.Children.Remove(this); + } + } + + /// <summary> + /// Raises the + /// <see cref="E:System.Windows.Controls.FloatableWindow.Closing" /> event. + /// </summary> + /// <param name="e">The event data.</param> + protected virtual void OnClosing(CancelEventArgs e) + { + EventHandler<CancelEventArgs> handler = this.Closing; + + if (null != handler) + { + handler(this, e); + } + } + + /// <summary> + /// Returns a + /// <see cref="T:System.Windows.Automation.Peers.FloatableWindowAutomationPeer" /> + /// for use by the Silverlight automation infrastructure. + /// </summary> + /// <returns> + /// <see cref="T:System.Windows.Automation.Peers.FloatableWindowAutomationPeer" /> + /// for the <see cref="T:System.Windows.Controls.FloatableWindow" /> object. + /// </returns> + protected override AutomationPeer OnCreateAutomationPeer() + { + return new FloatableWindowAutomationPeer(this); + } + + /// <summary> + /// This method is called every time a + /// <see cref="T:System.Windows.Controls.FloatableWindow" /> is displayed. + /// </summary> + protected virtual void OnOpened() + { + this.UpdatePosition(); + this._isOpen = true; + + if (this.Overlay != null) + { + this.Overlay.Opacity = this.OverlayOpacity; + this.Overlay.Background = this.OverlayBrush; + } + + if (!this.Focus()) + { + // If the Focus() fails it means there is no focusable element in the + // FloatableWindow. In this case we set IsTabStop to true to have the keyboard functionality + this.IsTabStop = true; + this.Focus(); + } + } + + /// <summary> + /// Executed when the opening storyboard finishes. + /// </summary> + /// <param name="sender">Sender object.</param> + /// <param name="e">Event args.</param> + private void Opening_Completed(object sender, EventArgs e) + { + if (this._opened != null) + { + this._opened.Completed -= new EventHandler(this.Opening_Completed); + } + // AutomationPeer returns "ReadyForUserInteraction" when the FloatableWindow + // is open and all animations have been completed. + this.InteractionState = WindowInteractionState.ReadyForUserInteraction; + this.OnOpened(); + } + + /// <summary> + /// Executed when the page resizes. + /// </summary> + /// <param name="sender">Sender object.</param> + /// <param name="e">Event args.</param> + private void Page_Resized(object sender, EventArgs e) + { + if (this.ChildWindowPopup != null) + { + this.UpdateOverlaySize(); + } + } + + /// <summary> + /// Executed when the root visual gets focus. + /// </summary> + /// <param name="sender">Sender object.</param> + /// <param name="e">Routed event args.</param> + private void RootVisual_GotFocus(object sender, RoutedEventArgs e) + { + this.Focus(); + this.InteractionState = WindowInteractionState.ReadyForUserInteraction; + } + + public void Show() + { + ShowWindow(false); + } + + public void ShowDialog() + { + _verticalOffset = 0; + _horizontalOffset = 0; + ShowWindow(true); + } + + public void Show(double horizontalOffset, double verticalOffset) + { + _horizontalOffset = horizontalOffset; + _verticalOffset = verticalOffset; + ShowWindow(false); + } + + /// <summary> + /// Opens a <see cref="T:System.Windows.Controls.FloatableWindow" /> and + /// returns without waiting for the + /// <see cref="T:System.Windows.Controls.FloatableWindow" /> to close. + /// </summary> + /// <exception cref="T:System.InvalidOperationException"> + /// The child window is already in the visual tree. + /// </exception> + internal void ShowWindow(bool isModal) + { + _modal = isModal; + + // AutomationPeer returns "Running" when Show() is called + // but the FloatableWindow is not ready for user interaction: + this.InteractionState = WindowInteractionState.Running; + + this.SubscribeToEvents(); + this.SubscribeToTemplatePartEvents(); + this.SubscribeToStoryBoardEvents(); + + + // MaxHeight and MinHeight properties should not be overwritten: + this.MaxHeight = double.PositiveInfinity; + this.MaxWidth = double.PositiveInfinity; + + if (_modal) + { + if (this.ChildWindowPopup == null) + { + this.ChildWindowPopup = new Popup(); + + try + { + this.ChildWindowPopup.Child = this; + } + catch (ArgumentException) + { + // If the FloatableWindow is already in the visualtree, we cannot set it to be the child of the popup + // we are throwing a friendlier exception for this case: + this.InteractionState = WindowInteractionState.NotResponding; + throw new InvalidOperationException("Cannot call Show() on a ChildWindow that is in the visual tree. ChildWindow should be the top-most element in the .xaml file."); + } + } + + if (this.ChildWindowPopup != null && Application.Current.RootVisual != null) + { + this.ChildWindowPopup.IsOpen = true; + + this.ChildWindowPopup.HorizontalOffset = _horizontalOffset; + this.ChildWindowPopup.VerticalOffset = _verticalOffset; + + // while the FloatableWindow is open, the DialogResult is always NULL: + this._dialogresult = null; + } + } + else + { + if (ParentLayoutRoot != null) + { + this.SetValue(Canvas.TopProperty, _verticalOffset); + this.SetValue(Canvas.LeftProperty, _horizontalOffset); + this.ParentLayoutRoot.Children.Add(this); + this.BringToFront(); + } + else + { + throw new ArgumentNullException("ParentLayoutRoot", "You need to specify a root Panel element to add the window elements to."); + } + } + + // disable the underlying UI + if (RootVisual != null && _modal) + { + RootVisual.IsEnabled = false; + } + + // if the template is already loaded, display loading visuals animation + if (this.ContentRoot == null) + { + this.Loaded += (s, args) => + { + if (this.ContentRoot != null) + { + this.ChangeVisualState(); + } + }; + } + else + { + this.ChangeVisualState(); + } + } + + /// <summary> + /// Subscribes to events when the FloatableWindow is opened. + /// </summary> + private void SubscribeToEvents() + { + if (Application.Current != null && Application.Current.Host != null && Application.Current.Host.Content != null) + { + Application.Current.Exit += new EventHandler(this.Application_Exit); + Application.Current.Host.Content.Resized += new EventHandler(this.Page_Resized); + } + + this.KeyDown += new KeyEventHandler(this.ChildWindow_KeyDown); + if (_modal) + { + this.LostFocus += new RoutedEventHandler(this.ChildWindow_LostFocus); + } + this.SizeChanged += new SizeChangedEventHandler(this.ChildWindow_SizeChanged); + } + + /// <summary> + /// Subscribes to events that are on the storyboards. + /// Unsubscribing from these events happen in the event handlers individually. + /// </summary> + private void SubscribeToStoryBoardEvents() + { + if (this._closed != null) + { + this._closed.Completed += new EventHandler(this.Closing_Completed); + } + + if (this._opened != null) + { + this._opened.Completed += new EventHandler(this.Opening_Completed); + } + } + + /// <summary> + /// Subscribes to events on the template parts. + /// </summary> + private void SubscribeToTemplatePartEvents() + { + if (this.CloseButton != null) + { + this.CloseButton.Click += new RoutedEventHandler(this.CloseButton_Click); + } + + if (this._chrome != null) + { + this._chrome.MouseLeftButtonDown += new MouseButtonEventHandler(this.Chrome_MouseLeftButtonDown); + this._chrome.MouseLeftButtonUp += new MouseButtonEventHandler(this.Chrome_MouseLeftButtonUp); + this._chrome.MouseMove += new MouseEventHandler(this.Chrome_MouseMove); + } + + } + + /// <summary> + /// Unsubscribe from events when the FloatableWindow is closed. + /// </summary> + private void UnSubscribeFromEvents() + { + if (Application.Current != null && Application.Current.Host != null && Application.Current.Host.Content != null) + { + Application.Current.Exit -= new EventHandler(this.Application_Exit); + Application.Current.Host.Content.Resized -= new EventHandler(this.Page_Resized); + } + + this.KeyDown -= new KeyEventHandler(this.ChildWindow_KeyDown); + if (_modal) + { + this.LostFocus -= new RoutedEventHandler(this.ChildWindow_LostFocus); + } + this.SizeChanged -= new SizeChangedEventHandler(this.ChildWindow_SizeChanged); + } + + /// <summary> + /// Unsubscribe from the events that are subscribed on the template part elements. + /// </summary> + private void UnsubscribeFromTemplatePartEvents() + { + if (this.CloseButton != null) + { + this.CloseButton.Click -= new RoutedEventHandler(this.CloseButton_Click); + } + + if (this._chrome != null) + { + this._chrome.MouseLeftButtonDown -= new MouseButtonEventHandler(this.Chrome_MouseLeftButtonDown); + this._chrome.MouseLeftButtonUp -= new MouseButtonEventHandler(this.Chrome_MouseLeftButtonUp); + this._chrome.MouseMove -= new MouseEventHandler(this.Chrome_MouseMove); + } + } + + /// <summary> + /// Updates the size of the overlay of the window. + /// </summary> + private void UpdateOverlaySize() + { + if (_modal) + { + if (this.Overlay != null && Application.Current != null && Application.Current.Host != null && Application.Current.Host.Content != null) + { + this.Height = Application.Current.Host.Content.ActualHeight; + this.Width = Application.Current.Host.Content.ActualWidth; + this.Overlay.Height = this.Height; + this.Overlay.Width = this.Width; + + if (this.ContentRoot != null) + { + this.ContentRoot.Width = this._desiredContentWidth; + this.ContentRoot.Height = this._desiredContentHeight; + this.ContentRoot.Margin = this._desiredMargin; + } + } + } + else + { + if (this.Overlay != null) + { + this.Overlay.Visibility = Visibility.Collapsed; + } + } + } + + /// <summary> + /// Updates the position of the window in case the size of the content changes. + /// This allows FloatableWindow only scale from right and bottom. + /// </summary> + private void UpdatePosition() + { + if (this.ContentRoot != null && Application.Current != null && Application.Current.RootVisual != null) + { + GeneralTransform gt = this.ContentRoot.TransformToVisual(Application.Current.RootVisual); + + if (gt != null) + { + this._windowPosition = gt.Transform(new Point(0, 0)); + } + } + } + + /// <summary> + /// Updates the render transform applied on the overlay. + /// </summary> + private void UpdateRenderTransform() + { + if (this._root != null && this.ContentRoot != null) + { + // The Overlay part should not be affected by the render transform applied on the + // FloatableWindow. In order to achieve this, we adjust an identity matrix to represent + // the _root's transformation, invert it, apply the inverted matrix on the _root, so that + // nothing is affected by the rendertransform, and apply the original transform only on the Content + GeneralTransform gt = this._root.TransformToVisual(null); + if (gt != null) + { + Point p10 = new Point(1, 0); + Point p01 = new Point(0, 1); + Point transform10 = gt.Transform(p10); + Point transform01 = gt.Transform(p01); + + Matrix transformToRootMatrix = Matrix.Identity; + transformToRootMatrix.M11 = transform10.X; + transformToRootMatrix.M12 = transform10.Y; + transformToRootMatrix.M21 = transform01.X; + transformToRootMatrix.M22 = transform01.Y; + + MatrixTransform original = new MatrixTransform(); + original.Matrix = transformToRootMatrix; + + InvertMatrix(ref transformToRootMatrix); + MatrixTransform mt = new MatrixTransform(); + mt.Matrix = transformToRootMatrix; + + TransformGroup tg = this._root.RenderTransform as TransformGroup; + + if (tg != null) + { + tg.Children.Add(mt); + } + else + { + this._root.RenderTransform = mt; + } + + tg = this.ContentRoot.RenderTransform as TransformGroup; + + if (tg != null) + { + tg.Children.Add(original); + } + else + { + this.ContentRoot.RenderTransform = original; + } + } + } + } + + /// <summary> + /// Updates the ContentRootTranslateTransform. + /// </summary> + /// <param name="X">X coordinate of the transform.</param> + /// <param name="Y">Y coordinate of the transform.</param> + private void UpdateContentRootTransform(double X, double Y) + { + if (this._contentRootTransform == null) + { + this._contentRootTransform = new TranslateTransform(); + this._contentRootTransform.X = X; + this._contentRootTransform.Y = Y; + + TransformGroup transformGroup = this.ContentRoot.RenderTransform as TransformGroup; + + if (transformGroup == null) + { + transformGroup = new TransformGroup(); + transformGroup.Children.Add(this.ContentRoot.RenderTransform); + } + transformGroup.Children.Add(this._contentRootTransform); + this.ContentRoot.RenderTransform = transformGroup; + } + else + { + this._contentRootTransform.X += X; + this._contentRootTransform.Y += Y; + } + } + + private void Resizer_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e) + { + this._resizer.CaptureMouse(); + this._isMouseCaptured = true; + this._clickPoint = e.GetPosition(sender as UIElement); + +#if DEBUG + this.Title = string.Format("X:{0},Y:{1}", this._clickPoint.X.ToString(), this._clickPoint.Y.ToString()); +#endif + } + + private void Resizer_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e) + { + this._resizer.ReleaseMouseCapture(); + this._isMouseCaptured = false; + this._resizer.Opacity = 0.25; + } + + private void Resizer_MouseMove(object sender, System.Windows.Input.MouseEventArgs e) + { + if (this._isMouseCaptured && this.ContentRoot != null) + { + // If the child window is dragged out of the page, return + if (Application.Current != null && Application.Current.RootVisual != null && + (e.GetPosition(Application.Current.RootVisual).X < 0 || e.GetPosition(Application.Current.RootVisual).Y < 0)) + { + return; + } + +#if DEBUG + this.Title = string.Format("X:{0},Y:{1}", this._clickPoint.X.ToString(), this._clickPoint.Y.ToString()); +#endif + + Point p = e.GetPosition(this.ContentRoot); + + if ((p.X > this._clickPoint.X) && (p.Y > this._clickPoint.Y)) + { + this.Width = (double)(p.X - (12 - this._clickPoint.X)); + this.Height = (double)(p.Y - (12 - this._clickPoint.Y)); + } + } + } + + private Storyboard GetVisualStateStoryboard(string visualStateGroupName, string visualStateName) + { + foreach (VisualStateGroup g in VisualStateManager.GetVisualStateGroups((FrameworkElement)this.ContentRoot.Parent)) + { + if (g.Name != visualStateGroupName) continue; + foreach (VisualState s in g.States) + { + if (s.Name != visualStateName) continue; + return s.Storyboard; + } + } + return null; + } + + #endregion Methods + } +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SilverlightGlimpse/SilverlightGlimpse/Controls/FloatableWindow/FloatableWindowAutomationPeer.cs Mon Apr 23 11:06:10 2012 +0100 @@ -0,0 +1,414 @@ +// (c) Copyright Microsoft Corporation. +// This source is subject to the Microsoft Public License (Ms-PL). +// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details. +// All other rights reserved. + +using System.Windows.Automation.Provider; +using System.Windows.Controls; +using System.Windows.Media; + +namespace System.Windows.Automation.Peers +{ + public class FloatableWindowAutomationPeer : FrameworkElementAutomationPeer, IWindowProvider, ITransformProvider + { + #region Data + + /// <summary> + /// Specifies whether the FloatableWindow is the top most element. + /// </summary> + private bool _isTopMost; + + #endregion Data + + #region Properties + + /// <summary> + /// Gets or sets a value indicating whether the FloatableWindow is the top most element. + /// </summary> + private bool IsTopMostPrivate + { + get + { + return this._isTopMost; + } + set + { + if (this._isTopMost != value) + { + this._isTopMost = value; + this.RaisePropertyChangedEvent(WindowPatternIdentifiers.IsTopmostProperty, !this._isTopMost, this._isTopMost); + } + } + } + + /// <summary> + /// Gets the owning FloatableWindow. + /// </summary> + private FloatableWindow OwningFloatableWindow + { + get + { + return (FloatableWindow)Owner; + } + } + + #endregion Properties + + public FloatableWindowAutomationPeer(FloatableWindow owner) + : base(owner) + { + if (owner == null) + { + throw new ArgumentNullException("owner"); + } + this.RefreshIsTopMostProperty(); + } + + #region AutomationPeer overrides + + /// <summary> + /// Gets the control pattern for this + /// <see cref="T:System.Windows.Automation.Peers.FloatableWindowAutomationPeer" />. + /// </summary> + /// <param name="patternInterface"> + /// One of the enumeration values. + /// </param> + /// <returns> + /// The object that implements the pattern interface, or null if the + /// specified pattern interface is not implemented by this peer. + /// </returns> + public override object GetPattern(PatternInterface patternInterface) + { + if (patternInterface == PatternInterface.Transform || patternInterface == PatternInterface.Window) + { + return this; + } + + return base.GetPattern(patternInterface); + } + + /// <summary> + /// Gets the + /// <see cref="T:System.Windows.Automation.Peers.AutomationControlType" /> + /// for the element associated with this + /// <see cref="T:System.Windows.Automation.Peers.FloatableWindowAutomationPeer" />. + /// Called by + /// <see cref="M:System.Windows.Automation.Peers.AutomationPeer.GetAutomationControlType" />. + /// </summary> + /// <returns>A value of the enumeration.</returns> + protected override AutomationControlType GetAutomationControlTypeCore() + { + return AutomationControlType.Window; + } + + /// <summary> + /// Gets the name of the class for the object associated with this + /// <see cref="T:System.Windows.Automation.Peers.FloatableWindowAutomationPeer" />. + /// Called by + /// <see cref="M:System.Windows.Automation.Peers.AutomationPeer.GetClassName" />. + /// </summary> + /// <returns> + /// A string value that represents the type of the child window. + /// </returns> + protected override string GetClassNameCore() + { + return this.Owner.GetType().Name; + } + + /// <summary> + /// Gets the text label of the + /// <see cref="T:System.Windows.Controls.FloatableWindow" /> that is + /// associated with this + /// <see cref="T:System.Windows.Automation.Peers.FloatableWindowAutomationPeer" />. + /// Called by + /// <see cref="M:System.Windows.Automation.Peers.AutomationPeer.GetName" />. + /// </summary> + /// <returns> + /// The text label of the element that is associated with this + /// automation peer. + /// </returns> + protected override string GetNameCore() + { + string name = base.GetNameCore(); + if (string.IsNullOrEmpty(name)) + { + AutomationPeer labeledBy = GetLabeledByCore(); + if (labeledBy != null) + { + name = labeledBy.GetName(); + } + + if (string.IsNullOrEmpty(name) && this.OwningFloatableWindow.Title != null) + { + name = this.OwningFloatableWindow.Title.ToString(); + } + } + return name; + } + + #endregion AutomationPeer overrides + + #region IWindowProvider + + /// <summary> + /// Gets the interaction state of the window. + /// </summary> + /// <value> + /// The interaction state of the control, as a value of the enumeration. + /// </value> + WindowInteractionState IWindowProvider.InteractionState + { + get + { + return this.OwningFloatableWindow.InteractionState; + } + } + + /// <summary> + /// Gets a value indicating whether the window is modal. + /// </summary> + /// <value> + /// True in all cases. + /// </value> + bool IWindowProvider.IsModal + { + get { return true; } + } + + /// <summary> + /// Gets a value indicating whether the window is the topmost + /// element in the z-order of layout. + /// </summary> + /// <value> + /// True if the window is topmost; otherwise, false. + /// </value> + bool IWindowProvider.IsTopmost + { + get + { + return this.IsTopMostPrivate; + } + } + + /// <summary> + /// Gets a value indicating whether the window can be maximized. + /// </summary> + /// <value>False in all cases.</value> + bool IWindowProvider.Maximizable + { + get { return false; } + } + + /// <summary> + /// Gets a value indicating whether the window can be minimized. + /// </summary> + /// <value>False in all cases.</value> + bool IWindowProvider.Minimizable + { + get { return false; } + } + + /// <summary> + /// Gets the visual state of the window. + /// </summary> + /// <value> + /// <see cref="F:System.Windows.Automation.WindowVisualState.Normal" /> + /// in all cases. + /// </value> + WindowVisualState IWindowProvider.VisualState + { + get + { + return WindowVisualState.Normal; + } + } + + /// <summary> + /// Closes the window. + /// </summary> + void IWindowProvider.Close() + { + this.OwningFloatableWindow.Close(); + } + + /// <summary> + /// Changes the visual state of the window (such as minimizing or + /// maximizing it). + /// </summary> + /// <param name="state"> + /// The visual state of the window to change to, as a value of the + /// enumeration. + /// </param> + void IWindowProvider.SetVisualState(WindowVisualState state) + { + } + + /// <summary> + /// Blocks the calling code for the specified time or until the + /// associated process enters an idle state, whichever completes first. + /// </summary> + /// <param name="milliseconds"> + /// The amount of time, in milliseconds, to wait for the associated + /// process to become idle. + /// </param> + /// <returns> + /// True if the window has entered the idle state; false if the timeout + /// occurred. + /// </returns> + bool IWindowProvider.WaitForInputIdle(int milliseconds) + { + return false; + } + + #endregion IWindowProvider + + #region ITransformProvider + + /// <summary> + /// Moves the control. + /// </summary> + /// <param name="x"> + /// The absolute screen coordinates of the left side of the control. + /// </param> + /// <param name="y"> + /// The absolute screen coordinates of the top of the control. + /// </param> + void ITransformProvider.Move(double x, double y) + { + if (x < 0) + { + x = 0; + } + + if (y < 0) + { + y = 0; + } + + if (x > this.OwningFloatableWindow.Width) + { + x = this.OwningFloatableWindow.Width; + } + + if (y > this.OwningFloatableWindow.Height) + { + y = this.OwningFloatableWindow.Height; + } + + FrameworkElement contentRoot = this.OwningFloatableWindow.ContentRoot; + + if (contentRoot != null) + { + GeneralTransform gt = contentRoot.TransformToVisual(null); + + if (gt != null) + { + Point p = gt.Transform(new Point(0, 0)); + + TransformGroup transformGroup = contentRoot.RenderTransform as TransformGroup; + + if (transformGroup == null) + { + transformGroup = new TransformGroup(); + transformGroup.Children.Add(contentRoot.RenderTransform); + } + + TranslateTransform t = new TranslateTransform(); + t.X = x - p.X; + t.Y = y - p.Y; + + if (transformGroup != null) + { + transformGroup.Children.Add(t); + contentRoot.RenderTransform = transformGroup; + } + } + } + } + + /// <summary> + /// Resizes the control. + /// </summary> + /// <param name="width">The new width of the window, in pixels.</param> + /// <param name="height"> + /// The new height of the window, in pixels. + /// </param> + void ITransformProvider.Resize(double width, double height) + { + } + + /// <summary> + /// Rotates the control. + /// </summary> + /// <param name="degrees"> + /// The number of degrees to rotate the control. A positive number + /// rotates the control clockwise. A negative number rotates the + /// control counterclockwise. + /// </param> + void ITransformProvider.Rotate(double degrees) + { + } + + /// <summary> + /// Gets a value indicating whether the element can be moved. + /// </summary> + /// <value>True in all cases.</value> + bool ITransformProvider.CanMove + { + get { return true; } + } + + /// <summary> + /// Gets a value indicating whether the element can be resized. + /// </summary> + /// <value>False in all cases.</value> + bool ITransformProvider.CanResize + { + get { return false; } + } + + /// <summary> + /// Gets a value indicating whether the element can be rotated. + /// </summary> + /// <value>False in all cases.</value> + bool ITransformProvider.CanRotate + { + get { return false; } + } + + #endregion ITransformProvider + + #region Methods + + /// <summary> + /// Returns if the FloatableWindow is the top most element. + /// </summary> + /// <returns>Bool value.</returns> + private bool GetIsTopMostCore() + { + return !(this.OwningFloatableWindow.InteractionState == WindowInteractionState.BlockedByModalWindow); + } + + /// <summary> + /// Raises PropertyChangedEvent for WindowInteractionStateProperty. + /// </summary> + /// <param name="oldValue">Old WindowInteractionStateProperty.</param> + /// <param name="newValue">New WindowInteractionStateProperty.</param> + internal void RaiseInteractionStatePropertyChangedEvent(WindowInteractionState oldValue, WindowInteractionState newValue) + { + this.RaisePropertyChangedEvent(WindowPatternIdentifiers.WindowInteractionStateProperty, oldValue, newValue); + this.RefreshIsTopMostProperty(); + } + + /// <summary> + /// Updates the IsTopMostPrivate property. + /// </summary> + private void RefreshIsTopMostProperty() + { + this.IsTopMostPrivate = this.GetIsTopMostCore(); + } + + #endregion Methods + } +} +
--- a/SilverlightGlimpse/SilverlightGlimpse/Controls/GlimpseViewer.xaml Mon Apr 23 11:05:11 2012 +0100 +++ b/SilverlightGlimpse/SilverlightGlimpse/Controls/GlimpseViewer.xaml Mon Apr 23 11:06:10 2012 +0100 @@ -2,6 +2,7 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:c="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls" + xmlns:local="clr-namespace:SilverlightGlimpse.Converters" xmlns:localc="clr-namespace:SilverlightGlimpse.Controls"> <UserControl.Resources> <SolidColorBrush x:Name="noExceptionsFill" Color="SteelBlue" /> @@ -12,6 +13,9 @@ <Grid x:Name="LayoutRoot"> <Grid x:Name="layoutInstrumentPanel"> <Grid.Resources> + <local:BoolToVisibilityConverter x:Key="InverseVisibility" + FalseValue="Visible" + TrueValue="Collapsed" /> <Style TargetType="Ellipse"> <Setter Property="Width" Value="40" /> <Setter Property="Height" Value="40" /> @@ -66,13 +70,19 @@ Width="800" Height="450"> + <c:TabItem Header="Bindings"> + <localc:BrokenBindingsViewer /> + </c:TabItem> + <c:TabItem Header="Validation"> + <localc:ExceptionsViewer /> + </c:TabItem> <c:TabItem Header="Exceptions"> <localc:ExceptionsViewer /> </c:TabItem> + <c:TabItem Header="Debug Info" Visibility="{Binding IsInDebugMode, Converter={StaticResource InverseVisibility}}"> + <localc:ExceptionsViewer /> + </c:TabItem> - <c:TabItem Header="Bindings with no Source"> - <localc:BrokenBindingsViewer /> - </c:TabItem> </c:TabControl> </Grid>
--- a/SilverlightGlimpse/SilverlightGlimpse/Controls/GlimpseViewer.xaml.cs Mon Apr 23 11:05:11 2012 +0100 +++ b/SilverlightGlimpse/SilverlightGlimpse/Controls/GlimpseViewer.xaml.cs Mon Apr 23 11:06:10 2012 +0100 @@ -10,8 +10,8 @@ public GlimpseViewer() { InitializeComponent(); - DataContext = GlimpseService.CreateInstance; - GlimpseService.CreateInstance.HostExceptions.CollectionChanged += HostExceptions_CollectionChanged; + DataContext = Glimpse.Service; + Glimpse.Service.Exceptions.CollectionChanged += HostExceptions_CollectionChanged; } private void btnContract_Click(object sender, RoutedEventArgs e) @@ -24,20 +24,21 @@ layoutViewer.Visibility = Visibility.Visible; } + // TODO: Sort this mess out :) private void HostExceptions_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { int unhandledExceptionCount = 0; int validationExceptionCount = 0; - foreach (var ex in GlimpseService.CreateInstance.HostExceptions) - { - if (ex.IsValidationException) - validationExceptionCount++; - else - unhandledExceptionCount++; - } + //foreach (var ex in Glimpse.Service.Exceptions) + //{ + // if (ex.IsValidationException) + // validationExceptionCount++; + // else + // unhandledExceptionCount++; + //} - tbValidationExceptions.Text = validationExceptionCount.ToString(); + //tbValidationExceptions.Text = validationExceptionCount.ToString(); //if (validationExceptionCount == 0) //{
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SilverlightGlimpse/SilverlightGlimpse/Converters/BoolToValueConverter.cs Mon Apr 23 11:06:10 2012 +0100 @@ -0,0 +1,27 @@ +// original code: http://geekswithblogs.net/codingbloke/archive/2010/05/28/a-generic-boolean-value-converter.aspx + +using System; +using System.Globalization; +using System.Windows.Data; + +namespace SilverlightGlimpse.Converters +{ + public class BoolToValueConverter<T> : IValueConverter + { + public T FalseValue { get; set; } + public T TrueValue { get; set; } + + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value == null) + return FalseValue; + else + return (bool)value ? TrueValue : FalseValue; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + return value != null && value.Equals(TrueValue); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SilverlightGlimpse/SilverlightGlimpse/Converters/BoolToVisibilityConverter.cs Mon Apr 23 11:06:10 2012 +0100 @@ -0,0 +1,6 @@ +using System.Windows; + +namespace SilverlightGlimpse.Converters +{ + public class BoolToVisibilityConverter : BoolToValueConverter<Visibility> { } +}
--- a/SilverlightGlimpse/SilverlightGlimpse/Models/BrokenBinding.cs Mon Apr 23 11:05:11 2012 +0100 +++ b/SilverlightGlimpse/SilverlightGlimpse/Models/BrokenBinding.cs Mon Apr 23 11:06:10 2012 +0100 @@ -27,6 +27,7 @@ public string Path { get; private set; } public string PropertyName { get; private set; } public string ToStringProperty { get { return ToString(); } } + #endregion #region Methods
--- a/SilverlightGlimpse/SilverlightGlimpse/Models/ExceptionWrapper.cs Mon Apr 23 11:05:11 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,51 +0,0 @@ -using System; -using System.Windows.Controls; - -namespace SilverlightGlimpse.Models -{ - public class ExceptionWrapper - { - #region Fields - - private readonly ValidationErrorEventAction _enumAction = ValidationErrorEventAction.Added; - - #endregion - - #region Constructor - - public ExceptionWrapper(Exception e) - { - Exception = e; - } - - #endregion - - #region Properties - - public ExceptionWrapper(ValidationErrorEventAction enumAction, string controlName, Exception validationException) - { - _enumAction = enumAction; - ControlName = controlName; - Exception = validationException; - IsValidationException = true; - } - - public ValidationErrorEventAction Action { get { return _enumAction; } } - public string ControlName { get; private set; } - public Exception Exception { get; private set; } - public bool IsValidationException { get; private set; } - - #endregion - - #region Methods - - public override string ToString() - { - return IsValidationException - ? string.Format("({0}) - {1}", Action, Exception.Message) - : Exception.Message; - } - - #endregion - } -} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SilverlightGlimpse/SilverlightGlimpse/Models/ObservableQueue.cs Mon Apr 23 11:06:10 2012 +0100 @@ -0,0 +1,441 @@ +//Original code: http://baboon.eu/post/2011/10/02/Using-a-decompiler-to-make-an-ObservableQueuelt;Tgt;.aspx +//Author: Baboon http://baboon.eu/ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics; +using System.Runtime.InteropServices; +using System.Threading; +using System.Collections.Specialized; +using System.ComponentModel; + +namespace SilverlightGlimpse.Models +{ + /// <summary>Represents a first-in, first-out collection of objects.</summary> + /// <typeparam name="T">Specifies the type of elements in the queue.</typeparam> + /// <filterpriority>1</filterpriority> + [DebuggerTypeProxy(typeof(System_QueueDebugView<>)), ComVisible(false), DebuggerDisplay("Count = {Count}")] + public class ObservableQueue<T> : IEnumerable<T>, ICollection, INotifyCollectionChanged, INotifyPropertyChanged where T : class + { + /// <summary>Enumerates the elements of a ObservableQueue.</summary> + + public struct Enumerator : IEnumerator<T> + { + private ObservableQueue<T> _q; + private int _index; + private int _version; + private T _currentElement; + /// <summary>Gets the element at the current position of the enumerator.</summary> + /// <returns>The element in the ObservableQueue at the current position of the enumerator.</returns> + /// <exception cref="T:System.InvalidOperationException">The enumerator is positioned before the first element of the collection or after + /// the last element. </exception> + public T Current + { + get + { + if (this._index < 0) + { + if (this._index == -1) + { + throw new InvalidOperationException("Enumerator not started"); + } + throw new InvalidOperationException("Enumeration ended"); + } + return this._currentElement; + } + } + object IEnumerator.Current + { + get + { + if (this._index < 0) + { + if (this._index == -1) + { + throw new InvalidOperationException("Enumerator not started"); + } + + throw new InvalidOperationException("Enumeration ended"); + } + return this._currentElement; + } + } + internal Enumerator(ObservableQueue<T> q) + { + this._q = q; + this._version = this._q._version; + this._index = -1; + this._currentElement = default(T); + } + /// <summary>Releases all resources used by the <see cref="T:System.Collections.Generic.Queue`1.Enumerator" />.</summary> + public void Dispose() + { + this._index = -2; + this._currentElement = default(T); + } + /// <summary>Advances the enumerator to the next element of the ObservableQueue.</summary> + /// <returns>true if the enumerator was successfully advanced to the next element; false if the enumerator has passed the end of the collection.</returns> + /// <exception cref="T:System.InvalidOperationException">The collection was modified after the enumerator was created. </exception> + public bool MoveNext() + { + if (this._version != this._q._version) throw new InvalidOperationException("Enumerator version mismatch"); + if (this._index == -2) return false; + + this._index++; + if (this._index == this._q._size) + { + this._index = -2; + this._currentElement = default(T); + return false; + } + this._currentElement = this._q.GetElement(this._index); + return true; + } + void IEnumerator.Reset() + { + if (this._version != this._q._version) throw new InvalidOperationException("Enumerator version mismatch"); + + this._index = -1; + this._currentElement = default(T); + } + } + private const int _MinimumGrow = 4; + private const int _ShrinkThreshold = 32; + private const int _GrowFactor = 200; + private const int _DefaultCapacity = 4; + + private T[] _arrayBackupField; + private T[] _array + { + get { return _arrayBackupField; } + set + { + if (_arrayBackupField != value) + { + _arrayBackupField = value; + RaiseCollectionChanged(NotifyCollectionChangedAction.Reset); + } + } + } + + private int _head; + private int _tail; + + private int _sizeBackupField; + private int _size + { + get { return _sizeBackupField; } + set + { + if (_sizeBackupField == value) return; + _sizeBackupField = value; + RaisePropertyChanged("Count"); + } + } + + private int _version; + private object _syncRoot; + private static T[] _emptyArray = new T[0]; + /// <summary>Gets the number of elements contained in the ObservableQueue.</summary> + /// <returns>The number of elements contained in the ObservableQueue.</returns> + public int Count { get { return this._size; } } + + bool ICollection.IsSynchronized { get { return false; } } + + object ICollection.SyncRoot + { + get + { + if (this._syncRoot == null) + { + Interlocked.CompareExchange<object>(ref this._syncRoot, new object(), null); + } + return this._syncRoot; + } + } + /// <summary>Initializes a new instance of the ObservableQueue class that is empty and has the default + /// initial capacity.</summary> + public ObservableQueue() + { + this._array = _emptyArray; + } + /// <summary>Initializes a new instance of the ObservableQueue class that is empty and has + /// the specified initial capacity.</summary> + /// <param name="capacity">The initial number of elements that the ObservableQueue can contain.</param> + /// <exception cref="T:System.ArgumentOutOfRangeException"> + /// <paramref name="capacity" /> is less than zero.</exception> + public ObservableQueue(int capacity) + { + if (capacity < 0) throw new ArgumentOutOfRangeException("capacity", "Capacity cannot be negative"); + + this._array = new T[capacity]; + this._head = 0; + this._tail = 0; + this._size = 0; + } + /// <summary>Initializes a new instance of the ObservableQueue class that contains elements copied from + /// the specified collection and has sufficient capacity to accommodate the number of elements copied.</summary> + /// <param name="collection">The collection whose elements are copied to the new ObservableQueue.</param> + /// <exception cref="T:System.ArgumentNullException"> + /// <paramref name="collection" /> is null.</exception> + public ObservableQueue(IEnumerable<T> collection) + { + if (collection == null) throw new ArgumentNullException("collection"); + this._array = new T[4]; + this._size = 0; + this._version = 0; + using (var enumerator = collection.GetEnumerator()) + { + while (enumerator.MoveNext()) + { + this.Enqueue(enumerator.Current); + } + } + } + /// <summary>Removes all objects from the ObservableQueue.</summary> + /// <filterpriority>1</filterpriority> + public void Clear() + { + if (this._head < this._tail) + { + Array.Clear(this._array, this._head, this._size); + } + else + { + Array.Clear(this._array, this._head, this._array.Length - this._head); + Array.Clear(this._array, 0, this._tail); + } + this._head = 0; + this._tail = 0; + this._size = 0; + this._version++; + RaiseCollectionChanged(NotifyCollectionChangedAction.Reset); + } + /// <summary>Copies the ObservableQueue elements to an existing one-dimensional <see cref="T:System.Array" />, + /// starting at the specified array index.</summary> + /// <param name="array">The one-dimensional <see cref="T:System.Array" /> that is the destination of the elements copied from + /// ObservableQueue. The <see cref="T:System.Array" /> must have zero-based indexing.</param> + /// <param name="arrayIndex">The zero-based index in <paramref name="array" /> at which copying begins.</param> + /// <exception cref="T:System.ArgumentNullException"> + /// <paramref name="array" /> is null.</exception> + /// <exception cref="T:System.ArgumentOutOfRangeException"> + /// <paramref name="arrayIndex" /> is less than zero.</exception>B + /// <exception cref="T:System.ArgumentException">The number of elements in the source ObservableQueue + /// is greater than the available space from <paramref name="arrayIndex" /> to the end of the destination <paramref name="array" />.</exception> + public void CopyTo(T[] array, int arrayIndex) + { + if (array == null) throw new ArgumentNullException("array"); + if (arrayIndex < 0 || arrayIndex > array.Length) throw new ArgumentOutOfRangeException("arrayIndex", "Index is out of range"); + int num = array.Length; + if (num - arrayIndex < this._size) throw new ArgumentException("Invalid offset length"); + + int num2 = (num - arrayIndex < this._size) ? (num - arrayIndex) : this._size; + if (num2 == 0) + { + return; + } + int num3 = (this._array.Length - this._head < num2) ? (this._array.Length - this._head) : num2; + Array.Copy(this._array, this._head, array, arrayIndex, num3); + num2 -= num3; + if (num2 > 0) + { + Array.Copy(this._array, 0, array, arrayIndex + this._array.Length - this._head, num2); + } + } + void ICollection.CopyTo(Array array, int index) + { + if (array == null) throw new ArgumentNullException("array"); + if (array.Rank != 1) throw new ArgumentException("Multidimension ranks are not supported"); + if (array.GetLowerBound(0) != 0) throw new ArgumentException("Lower bound cannot be zero"); + int length = array.Length; + if (index < 0 || index > length) throw new ArgumentOutOfRangeException("index", "Index is out of range"); + if (length - index < this._size) throw new ArgumentException("Invalid offset length"); + + int num = (length - index < this._size) ? (length - index) : this._size; + if (num == 0) return; + + try + { + int num2 = (this._array.Length - this._head < num) ? (this._array.Length - this._head) : num; + Array.Copy(this._array, this._head, array, index, num2); + num -= num2; + if (num > 0) + { + Array.Copy(this._array, 0, array, index + this._array.Length - this._head, num); + } + } + catch (ArrayTypeMismatchException) + { + throw new ArgumentException("Invalid array type"); + } + } + /// <summary>Adds an object to the end of the ObservableQueue.</summary> + /// <param name="item">The object to add to the ObservableQueue. The value can be null for reference types.</param> + public void Enqueue(T item) + { + if (this._size == this._array.Length) + { + int num = (int)(this._array.Length * 200L / 100L); + if (num < this._array.Length + 4) + { + num = this._array.Length + 4; + } + this.SetCapacity(num); + } + this._array[this._tail] = item; + this._tail = (this._tail + 1) % this._array.Length; + this._size++; + this._version++; + RaiseCollectionChanged(NotifyCollectionChangedAction.Add); + } + /// <summary>Returns an enumerator that iterates through the ObservableQueue.</summary> + /// <returns>An <see cref="T:System.Collections.Generic.Queue`1.Enumerator" /> for the ObservableQueue.</returns> + public Enumerator GetEnumerator() + { + return new Enumerator(this); + } + IEnumerator<T> IEnumerable<T>.GetEnumerator() + { + return new Enumerator(this); + } + IEnumerator IEnumerable.GetEnumerator() + { + return new Enumerator(this); + } + /// <summary>Removes and returns the object at the beginning of the ObservableQueue.</summary> + /// <returns>The object that is removed from the beginning of the ObservableQueue.</returns> + /// <exception cref="T:System.InvalidOperationException">The ObservableQueue is empty.</exception> + public T Dequeue() + { + if (this._size == 0) throw new InvalidOperationException("Cannot dequeue from an empty queue!"); + T result = this._array[this._head]; + this._array[this._head] = default(T); + this._head = (this._head + 1) % this._array.Length; + this._size--; + this._version++; + RaiseCollectionChanged(NotifyCollectionChangedAction.Remove); + return result; + } + /// <summary>Returns the object at the beginning of the ObservableQueue without removing it.</summary> + /// <returns>The object at the beginning of the ObservableQueue.</returns> + /// <exception cref="T:System.InvalidOperationException">The ObservableQueue is empty.</exception> + public T Peek() + { + if (this._size == 0) throw new InvalidOperationException("Cannot peek at en empty queue!"); + + return this._array[this._head]; + } + /// <summary>Determines whether an element is in the ObservableQueue.</summary> + /// <returns>true if <paramref name="item" /> is found in the ObservableQueue; otherwise, false.</returns> + /// <param name="item">The object to locate in the ObservableQueue. The value can be null for reference types.</param> + public bool Contains(T item) + { + int num = this._head; + int size = this._size; + EqualityComparer<T> @default = EqualityComparer<T>.Default; + while (size-- > 0) + { + if (item == null) + { + if (this._array[num] == null) + { + return true; + } + } + else + { + if (this._array[num] != null && @default.Equals(this._array[num], item)) + { + return true; + } + } + num = (num + 1) % this._array.Length; + } + return false; + } + internal T GetElement(int i) + { + return this._array[(this._head + i) % this._array.Length]; + } + /// <summary>Copies the ObservableQueue elements to a new array.</summary> + /// <returns>A new array containing elements copied from the ObservableQueue.</returns> + public T[] ToArray() + { + T[] array = new T[this._size]; + if (this._size == 0) + { + return array; + } + if (this._head < this._tail) + { + Array.Copy(this._array, this._head, array, 0, this._size); + } + else + { + Array.Copy(this._array, this._head, array, 0, this._array.Length - this._head); + Array.Copy(this._array, 0, array, this._array.Length - this._head, this._tail); + } + return array; + } + private void SetCapacity(int capacity) + { + T[] array = new T[capacity]; + if (this._size > 0) + { + if (this._head < this._tail) + { + Array.Copy(this._array, this._head, array, 0, this._size); + } + else + { + Array.Copy(this._array, this._head, array, 0, this._array.Length - this._head); + Array.Copy(this._array, 0, array, this._array.Length - this._head, this._tail); + } + } + this._array = array; + this._head = 0; + this._tail = ((this._size == capacity) ? 0 : this._size); + this._version++; + } + /// <summary>Sets the capacity to the actual number of elements in the ObservableQueue, + /// if that number is less than 90 percent of current capacity.</summary> + public void TrimExcess() + { + int num = (int)(this._array.Length * 0.9); + if (this._size < num) + { + this.SetCapacity(this._size); + } + } + + public event NotifyCollectionChangedEventHandler CollectionChanged = delegate { }; + private void RaiseCollectionChanged(NotifyCollectionChangedAction action) + { + CollectionChanged(this, new NotifyCollectionChangedEventArgs(action)); + } + + public event PropertyChangedEventHandler PropertyChanged = delegate { }; + private void RaisePropertyChanged(string property) + { + PropertyChanged(this, new PropertyChangedEventArgs(property)); + } + } + + internal sealed class System_QueueDebugView<T> + { + private ObservableQueue<T> queue; + [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] + public T[] Items + { + get + { + return this.queue.ToArray(); + } + } + public System_QueueDebugView(ObservableQueue<T> queue) + { + if (queue == null) throw new ArgumentNullException("queue"); + this.queue = queue; + } + } +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SilverlightGlimpse/SilverlightGlimpse/Models/ValidationWrapper.cs Mon Apr 23 11:06:10 2012 +0100 @@ -0,0 +1,38 @@ +using System.Windows.Controls; + +namespace SilverlightGlimpse.Models +{ + public class ValidationWrapper + { + #region Constructor + + public ValidationWrapper( + ValidationErrorEventAction enumAction, + string controlName, + string errorContent) + { + Action = enumAction; + ControlName = controlName; + Message = errorContent; + } + + #endregion + + #region Properties + + public ValidationErrorEventAction Action { get; private set; } + public string ControlName { get; private set; } + public string Message { get; private set; } + + #endregion + + #region Methods + + public override string ToString() + { + return string.Format("({0}) - {1}", Action, Message); + } + + #endregion + } +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SilverlightGlimpse/SilverlightGlimpse/Services/DebugMonitor.cs Mon Apr 23 11:06:10 2012 +0100 @@ -0,0 +1,404 @@ +//Original code: http://www.codeproject.com/Articles/13345/DbMon-NET-A-simple-NET-OutputDebugString-capturer +//Author: Christian Birkl http://stackoverflow.com/users/144377/christian-birkl + +using System; +using System.Threading; +using System.Runtime.InteropServices; + +namespace SilverlightGlimpse.Services +{ + /// <summary> + /// Delegate used when firing DebugMonitor.OnOutputDebug event + /// </summary> + public delegate void OnOutputDebugStringHandler(int pid, string text); + + /// <summary> + /// This class captures all strings passed to <c>OutputDebugString</c> when + /// the application is not debugged. + /// </summary> + /// <remarks> + /// This class is a port of Microsofts Visual Studio's C++ example "dbmon", which + /// can be found at <c>http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcsample98/html/vcsmpdbmon.asp</c>. + /// </remarks> + /// <remarks> + /// <code> + /// public static void Main(string[] args) { + /// DebugMonitor.Start(); + /// DebugMonitor.OnOutputDebugString += new OnOutputDebugStringHandler(OnOutputDebugString); + /// Console.WriteLine("Press 'Enter' to exit."); + /// Console.ReadLine(); + /// DebugMonitor.Stop(); + /// } + /// + /// private static void OnOutputDebugString(int pid, string text) { + /// Console.WriteLine(DateTime.Now + ": " + text); + /// } + /// </code> + /// </remarks> + public sealed class DebugMonitor + { + + /// <summary> + /// Private constructor so no one can create a instance + /// of this static class + /// </summary> + private DebugMonitor() + { + } + + #region Win32 API Imports + + [StructLayout(LayoutKind.Sequential)] + private struct SECURITY_DESCRIPTOR + { + public byte revision; + public byte size; + public short control; + public IntPtr owner; + public IntPtr group; + public IntPtr sacl; + public IntPtr dacl; + } + + [StructLayout(LayoutKind.Sequential)] + private struct SECURITY_ATTRIBUTES + { + public int nLength; + public IntPtr lpSecurityDescriptor; + public int bInheritHandle; + } + + [Flags] + private enum PageProtection : uint + { + NoAccess = 0x01, + Readonly = 0x02, + ReadWrite = 0x04, + WriteCopy = 0x08, + Execute = 0x10, + ExecuteRead = 0x20, + ExecuteReadWrite = 0x40, + ExecuteWriteCopy = 0x80, + Guard = 0x100, + NoCache = 0x200, + WriteCombine = 0x400, + } + + + private const int WAIT_OBJECT_0 = 0; + private const uint INFINITE = 0xFFFFFFFF; + private const int ERROR_ALREADY_EXISTS = 183; + + private const uint SECURITY_DESCRIPTOR_REVISION = 1; + + private const uint SECTION_MAP_READ = 0x0004; + + [DllImport("kernel32.dll", SetLastError = true)] + private static extern IntPtr MapViewOfFile(IntPtr hFileMappingObject, uint + dwDesiredAccess, uint dwFileOffsetHigh, uint dwFileOffsetLow, + uint dwNumberOfBytesToMap); + + [DllImport("kernel32.dll", SetLastError = true)] + private static extern bool UnmapViewOfFile(IntPtr lpBaseAddress); + + [DllImport("advapi32.dll", SetLastError = true)] + private static extern bool InitializeSecurityDescriptor(ref SECURITY_DESCRIPTOR sd, uint dwRevision); + + [DllImport("advapi32.dll", SetLastError = true)] + private static extern bool SetSecurityDescriptorDacl(ref SECURITY_DESCRIPTOR sd, bool daclPresent, IntPtr dacl, bool daclDefaulted); + + [DllImport("kernel32.dll")] + private static extern IntPtr CreateEvent(ref SECURITY_ATTRIBUTES sa, bool bManualReset, bool bInitialState, string lpName); + + [DllImport("kernel32.dll")] + private static extern bool PulseEvent(IntPtr hEvent); + + [DllImport("kernel32.dll")] + private static extern bool SetEvent(IntPtr hEvent); + + [DllImport("kernel32.dll", SetLastError = true)] + private static extern IntPtr CreateFileMapping(IntPtr hFile, + ref SECURITY_ATTRIBUTES lpFileMappingAttributes, PageProtection flProtect, uint dwMaximumSizeHigh, + uint dwMaximumSizeLow, string lpName); + + [DllImport("kernel32.dll", SetLastError = true)] + private static extern bool CloseHandle(IntPtr hHandle); + + [DllImport("kernel32", SetLastError = true, ExactSpelling = true)] + private static extern Int32 WaitForSingleObject(IntPtr handle, uint milliseconds); + #endregion + + /// <summary> + /// Fired if an application calls <c>OutputDebugString</c> + /// </summary> + public static event OnOutputDebugStringHandler OnOutputDebugString; + + /// <summary> + /// Event handle for slot 'DBWIN_BUFFER_READY' + /// </summary> + private static IntPtr m_AckEvent = IntPtr.Zero; + + /// <summary> + /// Event handle for slot 'DBWIN_DATA_READY' + /// </summary> + private static IntPtr m_ReadyEvent = IntPtr.Zero; + + /// <summary> + /// Handle for our shared file + /// </summary> + private static IntPtr m_SharedFile = IntPtr.Zero; + + /// <summary> + /// Handle for our shared memory + /// </summary> + private static IntPtr m_SharedMem = IntPtr.Zero; + + /// <summary> + /// Our capturing thread + /// </summary> + private static Thread m_Capturer = null; + + /// <summary> + /// Our synchronization root + /// </summary> + private static object m_SyncRoot = new object(); + + /// <summary> + /// Mutex for singleton check + /// </summary> + /// TODO: Work out a mutex equivalent for Silverlight + //private static Mutex m_Mutex = null; + + /// <summary> + /// Starts this debug monitor + /// </summary> + public static void Start() + { + lock (m_SyncRoot) + { + if (m_Capturer != null) + throw new Exception("This DebugMonitor is already started."); + + // Check for supported operating system. Mono (at least with *nix) won't support + // our P/Invoke calls. + if (Environment.OSVersion.ToString().IndexOf("Microsoft") == -1) + throw new NotSupportedException("This DebugMonitor is only supported on Microsoft operating systems."); + + // Check for multiple instances. As the README.TXT of the msdn + // example notes it is possible to have multiple debug monitors + // listen on OutputDebugString, but the message will be randomly + // distributed among all running instances so this won't be + // such a good idea. + // TODO: Work out a mutex equivalent for Silverlight + //bool createdNew = false; + //m_Mutex = new Mutex(false, typeof(DebugMonitor).Namespace, out createdNew); + //if (!createdNew) + // throw new Exception("There is already an instance of 'DbMon.NET' running."); + + SECURITY_DESCRIPTOR sd = new SECURITY_DESCRIPTOR(); + + // Initialize the security descriptor. + if (!InitializeSecurityDescriptor(ref sd, SECURITY_DESCRIPTOR_REVISION)) + { + throw CreateApplicationException("Failed to initializes the security descriptor."); + } + + // Set information in a discretionary access control list + if (!SetSecurityDescriptorDacl(ref sd, true, IntPtr.Zero, false)) + { + throw CreateApplicationException("Failed to initializes the security descriptor"); + } + + SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES(); + + // Create the event for slot 'DBWIN_BUFFER_READY' + m_AckEvent = CreateEvent(ref sa, false, false, "DBWIN_BUFFER_READY"); + if (m_AckEvent == IntPtr.Zero) + { + throw CreateApplicationException("Failed to create event 'DBWIN_BUFFER_READY'"); + } + + // Create the event for slot 'DBWIN_DATA_READY' + m_ReadyEvent = CreateEvent(ref sa, false, false, "DBWIN_DATA_READY"); + if (m_ReadyEvent == IntPtr.Zero) + { + throw CreateApplicationException("Failed to create event 'DBWIN_DATA_READY'"); + } + + // Get a handle to the readable shared memory at slot 'DBWIN_BUFFER'. + m_SharedFile = CreateFileMapping(new IntPtr(-1), ref sa, PageProtection.ReadWrite, 0, 4096, "DBWIN_BUFFER"); + if (m_SharedFile == IntPtr.Zero) + { + throw CreateApplicationException("Failed to create a file mapping to slot 'DBWIN_BUFFER'"); + } + + // Create a view for this file mapping so we can access it + m_SharedMem = MapViewOfFile(m_SharedFile, SECTION_MAP_READ, 0, 0, 512); + if (m_SharedMem == IntPtr.Zero) + { + throw CreateApplicationException("Failed to create a mapping view for slot 'DBWIN_BUFFER'"); + } + + // Start a new thread where we can capture the output + // of OutputDebugString calls so we don't block here. + m_Capturer = new Thread(new ThreadStart(Capture)); + m_Capturer.Start(); + } + } + + /// <summary> + /// Captures + /// </summary> + private static void Capture() + { + try + { + // Everything after the first DWORD is our debugging text + IntPtr pString = new IntPtr( + m_SharedMem.ToInt32() + Marshal.SizeOf(typeof(int)) + ); + + while (true) + { + SetEvent(m_AckEvent); + + int ret = WaitForSingleObject(m_ReadyEvent, INFINITE); + + // if we have no capture set it means that someone + // called 'Stop()' and is now waiting for us to exit + // this endless loop. + if (m_Capturer == null) + break; + + if (ret == WAIT_OBJECT_0) + { + // The first DWORD of the shared memory buffer contains + // the process ID of the client that sent the debug string. + FireOnOutputDebugString( + Marshal.ReadInt32(m_SharedMem), + Marshal.PtrToStringAnsi(pString)); + } + } + + } + catch + { + throw; + + // Cleanup + } + finally + { + Dispose(); + } + } + + private static void FireOnOutputDebugString(int pid, string text) + { + // Raise event if we have any listeners + if (OnOutputDebugString == null) + return; + +#if !DEBUG + try + { +#endif + OnOutputDebugString(pid, text); +#if !DEBUG + } + catch (Exception ex) + { + Console.WriteLine("An 'OnOutputDebugString' handler failed to execute: " + ex.ToString()); + } +#endif + } + + /// <summary> + /// Dispose all resources + /// </summary> + private static void Dispose() + { + // Close AckEvent + if (m_AckEvent != IntPtr.Zero) + { + if (!CloseHandle(m_AckEvent)) + { + throw CreateApplicationException("Failed to close handle for 'AckEvent'"); + } + m_AckEvent = IntPtr.Zero; + } + + // Close ReadyEvent + if (m_ReadyEvent != IntPtr.Zero) + { + if (!CloseHandle(m_ReadyEvent)) + { + throw CreateApplicationException("Failed to close handle for 'ReadyEvent'"); + } + m_ReadyEvent = IntPtr.Zero; + } + + // Close SharedFile + if (m_SharedFile != IntPtr.Zero) + { + if (!CloseHandle(m_SharedFile)) + { + throw CreateApplicationException("Failed to close handle for 'SharedFile'"); + } + m_SharedFile = IntPtr.Zero; + } + + + // Unmap SharedMem + if (m_SharedMem != IntPtr.Zero) + { + if (!UnmapViewOfFile(m_SharedMem)) + { + throw CreateApplicationException("Failed to unmap view for slot 'DBWIN_BUFFER'"); + } + m_SharedMem = IntPtr.Zero; + } + + //TODO: Work out replacement for Mutex in Silverlight + // Close our mutex + //if (m_Mutex != null) + //{ + // m_Mutex.Close(); + // m_Mutex = null; + //} + } + + /// <summary> + /// Stops this debug monitor. This call we block the executing thread + /// until this debug monitor is stopped. + /// </summary> + public static void Stop() + { + lock (m_SyncRoot) + { + if (m_Capturer == null) + throw new ObjectDisposedException("DebugMonitor", "This DebugMonitor is not running."); + m_Capturer = null; + PulseEvent(m_ReadyEvent); + while (m_AckEvent != IntPtr.Zero) + ; + } + } + + /// <summary> + /// Helper to create a new exception, which has automaticly the + /// last win 32 error code appended. + /// </summary> + /// <param name="text">text</param> + private static Exception CreateApplicationException(string text) + { + if (string.IsNullOrEmpty(text)) throw new ArgumentNullException("text", "'text' may not be empty or null."); + + return new Exception( + string.Format("{0}. Last Win32 Error was {1}", + text, + Marshal.GetLastWin32Error())); + } + + } +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SilverlightGlimpse/SilverlightGlimpse/Services/Glimpse.cs Mon Apr 23 11:06:10 2012 +0100 @@ -0,0 +1,273 @@ +using System; +using System.Collections.ObjectModel; +using System.Diagnostics; +using System.Reflection; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Threading; +using SilverlightGlimpse.Controls; +using SilverlightGlimpse.Models; +using System.Windows.Media; + +namespace SilverlightGlimpse.Services +{ + public class Glimpse + { + #region Fields + + private static Glimpse _instance; + private DispatcherTimer _refreshBindingCountTimer; + private static readonly TimeSpan _fiveSeconds = new TimeSpan(0, 0, 0, 5); + Queue<string> _log = new Queue<string>(); + + #endregion + + #region Private constructor + + private Glimpse() + { + BrokenBindings = new ObservableCollection<BrokenBinding>(); + ValidationErrors = new ObservableCollection<ValidationWrapper>(); + Exceptions = new ObservableCollection<Exception>(); + + InitialiseDebugMonitor(); + } + + private static void InitialiseDebugMonitor() + { + DebugMonitor.OnOutputDebugString += DebugMonitor_OnOutputDebugString; + try + { + DebugMonitor.Start(); + } + catch (Exception ex) + { + Debug.WriteLine(ex.Message, "Failed to start DebugMonitor"); + return; + } + + if (Debugger.IsAttached) + { + AppendText(-1, "You are currently debugging DbMon.NET so you won't get any 'Debug.WriteLine's from it."); + } + else + { + Debug.WriteLine("DbMon.NET loaded."); + } + } + + #endregion + + #region Properties + + public static Glimpse Service + { + get { return _instance ?? (_instance = new Glimpse()); } + } + + internal Application App { get; private set; } + internal FloatableWindow GlimpseWindow { get; set;} + internal string Title { get; set; } + internal ObservableCollection<BrokenBinding> BrokenBindings { get; private set; } + internal ObservableCollection<ValidationWrapper> ValidationErrors { get; private set; } + internal ObservableCollection<Exception> Exceptions { get; private set; } + internal FrameworkElement RootVisual { get; private set; } + internal TimeSpan BindingsRefreshRate { get; private set; } + internal bool IsInDebugMode + { + get { +#if DEBUG + return true; +#endif + return false; + } + } + + + public void WriteLog(string value) + { + _items.Enqueue(value); + if (_items.Count > 100) + _items.Dequeue(); + } + + #endregion + + private static void DebugMonitor_OnOutputDebugString(int pid, string text) + { + AppendText(pid, text); + } + + private static void AppendText(int pid, string text) + { + //DateTime.Now.ToString("HH:mm:ss") + } + + #region Creation and Loading + + public void DisplayLoadFailure(Application app, Exception ex, string title) + { + var source = ex.StackTrace.Substring(0, ex.StackTrace.IndexOf(Environment.NewLine, StringComparison.Ordinal)); + + App = app; + App.RootVisual = new LoadExceptionViewer(ex, source); + Title = title; + Debug.WriteLine("{0} had exception. {1}", Title, ex); + } + + public void Load(Application app, string title, TimeSpan bindingsRefreshRate = default(TimeSpan)) + { + App = app; + RootVisual = App.RootVisual as FrameworkElement; + if (RootVisual == null) throw new NullReferenceException("The Application provided did not have a valid RootVisual object"); + Title = title; + BindingsRefreshRate = (bindingsRefreshRate == default(TimeSpan)) ? _fiveSeconds : bindingsRefreshRate; + + RootVisual.BindingValidationError += HostRootVisual_BindingValidationError; + App.UnhandledException += Application_UnhandledException; + _refreshBindingCountTimer.Tick += RefreshBindingCountTimer_Tick; + _refreshBindingCountTimer.Interval = BindingsRefreshRate; + + GlimpseWindow = new FloatableWindow + { + Title = Title, + Content = new GlimpseViewer(), + ParentLayoutRoot = (Panel) VisualTreeHelper.GetChild(RootVisual, 0) + }; + + if (Double.IsNaN(RootVisual.Width)) + { + //if the host control is autosized (consumes the browser window) then locate Glimpse in the top, left + GlimpseWindow.Show(50,10); + } + else + { + //if the host is fixed size then attempt to locate the popup control in the upper right corner + var dblLeft = RootVisual.Width - 200; + + if (dblLeft < 0) + dblLeft = 0; + + GlimpseWindow.Show(dblLeft, 10); + } + + _refreshBindingCountTimer.Start(); + } + + #endregion + + //#region Update broken bindings list + + //private void LoadBrokenBindings(UIElement uiElement) + //{ + // var frameworkElement = uiElement as FrameworkElement; + // if (frameworkElement == null) return; + + // foreach (var fieldInfo in frameworkElement.GetType().GetFields(BindingFlags.Public | BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.Static)) + // { + // if (!ReferenceEquals(fieldInfo.FieldType, typeof(DependencyProperty))) continue; + + // var bindingExpression = frameworkElement.GetBindingExpression((DependencyProperty)fieldInfo.GetValue(null)); + + // if (bindingExpression == null || bindingExpression.ParentBinding.Source != null || + // bindingExpression.ParentBinding.RelativeSource != null) continue; + + // var isInherited = false; + + // if (frameworkElement.DataContext != null && !string.IsNullOrEmpty(bindingExpression.ParentBinding.Path.Path)) + // { + // foreach (var propertyInfo in frameworkElement.DataContext.GetType().GetProperties(BindingFlags.Public | BindingFlags.FlattenHierarchy | BindingFlags.Static | BindingFlags.Instance)) + // { + // if (string.Compare(propertyInfo.Name, bindingExpression.ParentBinding.Path.Path) == 0) + // { + // isInherited = true; + // break; + // } + // } + // } + + // if (isInherited) + // { + // break; + // } + + // //this code handles empty bindings on the Button controls + // //I'll have to look into why the Button has an empty or unresolved binding + // if (string.IsNullOrEmpty(frameworkElement.Name) + // && frameworkElement.GetType().Name == "TextBlock" + // && fieldInfo.Name == "TextProperty" + // && string.IsNullOrEmpty(bindingExpression.ParentBinding.Path.Path)) + // { + // break; + // } + + // var brokenBinding = new BrokenBinding( + // frameworkElement.Name, + // frameworkElement.GetType().Name, + // fieldInfo.Name, + // bindingExpression.ParentBinding.Path.Path); + + // //TODO: lbBindings.Items.Add(brokenBinding); + // Debug.WriteLine("Broken Binding: {0}", brokenBinding); + // } + + // int children = VisualTreeHelper.GetChildrenCount(frameworkElement); + + // for (int j = 0; j <= children - 1; j++) + // { + // var child = VisualTreeHelper.GetChild(frameworkElement, j) as FrameworkElement; + + // if (child != null) + // { + // LoadBrokenBindings(child); + // } + // } + //} + //#endregion + + #region Events handlers + + // Bindings + private void RefreshBindingCountTimer_Tick(object sender, EventArgs e) + { + LoadBrokenBindings(RootVisual); + } + + // Validation + private void HostRootVisual_BindingValidationError(object sender, ValidationErrorEventArgs e) + { + var controlName = "(none)"; + var control = e.OriginalSource as Control; + + if (control != null && !string.IsNullOrEmpty(control.Name)) + { + controlName = control.Name; + } + + ValidationErrors.Add( + new ValidationWrapper( + e.Action, + controlName, + e.Error.ErrorContent.ToString())); + } + + // Exceptions + private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e) + { + Debug.WriteLine("{0} had exception. {1}", Title, e.ExceptionObject); + + Exception ex = e.ExceptionObject; + + while (ex != null) + { + // TODO: Decide whether inner exceptions should be viewable separately + this.Exceptions.Add(ex); + ex = ex.InnerException; + } + + e.Handled = true; + } + + #endregion + } +} \ No newline at end of file
--- a/SilverlightGlimpse/SilverlightGlimpse/Services/GlimpseService.cs Mon Apr 23 11:05:11 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,126 +0,0 @@ -using System; -using System.Collections.ObjectModel; -using System.Diagnostics; -using System.Windows; -using System.Windows.Controls; -using SilverlightGlimpse.Controls; -using SilverlightGlimpse.Models; -using System.Windows.Media; - -namespace SilverlightGlimpse.Services -{ - public class GlimpseService - { - #region Fields - - private static GlimpseService _instance; - - #endregion - - #region Private constructor - - private GlimpseService() - { - HostExceptions = new ObservableCollection<ExceptionWrapper>(); - } - - #endregion - - #region Properties - - public static GlimpseService CreateInstance - { - get { return _instance ?? (_instance = new GlimpseService()); } - } - - internal Application App { get; private set; } - internal FloatableWindow GlimpseWindow { get; set;} - internal string HostApplicationName { get; set; } - internal ObservableCollection<ExceptionWrapper> HostExceptions { get; private set; } - internal FrameworkElement RootVisual { get; private set; } - - #endregion - - #region Creation and Loading - - public void DisplayLoadFailure(Application app, Exception ex) - { - var source = ex.StackTrace.Substring(0, ex.StackTrace.IndexOf(Environment.NewLine, StringComparison.Ordinal)); - Debug.WriteLine("{0} had exception. {1}", HostApplicationName, ex); - App = app; - App.RootVisual = new LoadExceptionViewer(ex, source); - } - - public void Load(Application app, string hostApplicationName) - { - App = app; - RootVisual = App.RootVisual as FrameworkElement; - HostApplicationName = hostApplicationName; - - RootVisual.BindingValidationError += HostRootVisual_BindingValidationError; - App.UnhandledException += Application_UnhandledException; - - GlimpseWindow = new FloatableWindow - { - Title = this.HostApplicationName, - Content = new GlimpseViewer(), - ParentLayoutRoot = (Panel) VisualTreeHelper.GetChild(RootVisual, 0), - ResizeMode = ResizeMode.NoResize - }; - if (Double.IsNaN(RootVisual.Width)) - { - //if the host control is autosized (consumes the browser window) then locate Glimpse in the top, left - GlimpseWindow.Show(10,10); - } - else - { - //if the host is fixed size then attempt to locate the popup control in the upper right corner - var dblLeft = RootVisual.Width - 200; - - if (dblLeft < 0) - dblLeft = 0; - - GlimpseWindow.Show(dblLeft, 10); - } - } - #endregion - - #region Events handlers - - private void HostRootVisual_BindingValidationError(object sender, ValidationErrorEventArgs e) - { - string controlName = "(none)"; - Control control = e.OriginalSource as Control; - - if (control != null && !string.IsNullOrEmpty(control.Name)) - { - controlName = control.Name; - } - - Exception ex = e.Error.Exception; - - while (ex != null) - { - this.HostExceptions.Add(new ExceptionWrapper(e.Action, controlName, e.Error.Exception)); - ex = ex.InnerException; - } - } - - private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e) - { - Debug.WriteLine("{0} had exception. {1}", this.HostApplicationName, e.ExceptionObject.ToString()); - - Exception ex = e.ExceptionObject; - - while (ex != null) - { - this.HostExceptions.Add(new ExceptionWrapper(ex)); - ex = ex.InnerException; - } - - e.Handled = true; - } - - #endregion - } -} \ No newline at end of file
--- a/SilverlightGlimpse/SilverlightGlimpse/SilverlightGlimpse.csproj Mon Apr 23 11:05:11 2012 +0100 +++ b/SilverlightGlimpse/SilverlightGlimpse/SilverlightGlimpse.csproj Mon Apr 23 11:06:10 2012 +0100 @@ -82,10 +82,16 @@ <Compile Include="Controls\ExceptionsViewer.xaml.cs"> <DependentUpon>ExceptionsViewer.xaml</DependentUpon> </Compile> + <Compile Include="Controls\FloatableWindow\FloatableWindow.cs" /> + <Compile Include="Controls\FloatableWindow\FloatableWindowAutomationPeer.cs" /> + <Compile Include="Converters\BoolToValueConverter.cs" /> + <Compile Include="Converters\BoolToVisibilityConverter.cs" /> <Compile Include="Models\BrokenBinding.cs" /> - <Compile Include="Models\ExceptionWrapper.cs" /> + <Compile Include="Models\ObservableQueue.cs" /> + <Compile Include="Models\ValidationWrapper.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> - <Compile Include="Services\GlimpseService.cs" /> + <Compile Include="Services\DebugMonitor.cs" /> + <Compile Include="Services\Glimpse.cs" /> </ItemGroup> <ItemGroup> <Page Include="Controls\BrokenBindingsViewer.xaml"> @@ -104,15 +110,16 @@ <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> </Page> + <Page Include="Themes\generic.xaml"> + <Generator>MSBuild:Compile</Generator> + <SubType>Designer</SubType> + </Page> </ItemGroup> <ItemGroup> <None Include="Properties\AppManifest.xml" /> </ItemGroup> <ItemGroup> - <ProjectReference Include="..\FloatableWindow\FloatableWindow.csproj"> - <Project>{D47E6045-91BB-4CD0-942F-FF015F10F7F2}</Project> - <Name>FloatableWindow</Name> - </ProjectReference> + <Content Include="Bugs.txt" /> </ItemGroup> <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Silverlight\$(SilverlightVersion)\Microsoft.Silverlight.CSharp.targets" /> <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SilverlightGlimpse/SilverlightGlimpse/themes/generic.xaml Mon Apr 23 11:06:10 2012 +0100 @@ -0,0 +1,352 @@ +<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:controls="clr-namespace:System.Windows.Controls" + xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows"> + + <Style TargetType="controls:FloatableWindow"> + <Setter Property="IsTabStop" Value="false" /> + <Setter Property="TabNavigation" Value="Cycle" /> + <Setter Property="HorizontalAlignment" Value="Center" /> + <Setter Property="VerticalAlignment" Value="Center" /> + <Setter Property="HorizontalContentAlignment" Value="Stretch" /> + <Setter Property="VerticalContentAlignment" Value="Stretch" /> + <Setter Property="BorderThickness" Value="1" /> + <Setter Property="BorderBrush"> + <Setter.Value> + <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1"> + <GradientStop Offset="0" Color="#FFA3AEB9" /> + <GradientStop Offset="0.375" Color="#FF8399A9" /> + <GradientStop Offset="0.375" Color="#FF718597" /> + <GradientStop Offset="1" Color="#FF617584" /> + </LinearGradientBrush> + </Setter.Value> + </Setter> + <Setter Property="OverlayBrush"> + <Setter.Value> + <SolidColorBrush Color="#7F000000" /> + </Setter.Value> + </Setter> + <Setter Property="OverlayOpacity" Value="1" /> + <Setter Property="Template"> + <Setter.Value> + <ControlTemplate TargetType="controls:FloatableWindow"> + <Grid x:Name="Root"> + <Grid.Resources> + <Style x:Key="ButtonStyle" TargetType="Button"> + <Setter Property="Background" Value="#FF1F3B53" /> + <Setter Property="Foreground" Value="#FF000000" /> + <Setter Property="Padding" Value="3" /> + <Setter Property="BorderThickness" Value="1" /> + <Setter Property="BorderBrush"> + <Setter.Value> + <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1"> + <GradientStop Offset="0" Color="#FFA3AEB9" /> + <GradientStop Offset="0.375" Color="#FF8399A9" /> + <GradientStop Offset="0.375" Color="#FF718597" /> + <GradientStop Offset="1" Color="#FF617584" /> + </LinearGradientBrush> + </Setter.Value> + </Setter> + <Setter Property="Template"> + <Setter.Value> + <ControlTemplate TargetType="Button"> + <Grid x:Name="grid" + Width="15" + Height="14" + HorizontalAlignment="Center" + VerticalAlignment="Center" + Background="#02FFFFFF"> + <vsm:VisualStateManager.VisualStateGroups> + <vsm:VisualStateGroup x:Name="CommonStates"> + <vsm:VisualState x:Name="Normal" /> + <vsm:VisualState x:Name="MouseOver"> + <Storyboard> + <ObjectAnimationUsingKeyFrames Storyboard.TargetName="X_Fuzz2" Storyboard.TargetProperty="Visibility"> + <DiscreteObjectKeyFrame KeyTime="0" Value="Visible" /> + </ObjectAnimationUsingKeyFrames> + <ObjectAnimationUsingKeyFrames Storyboard.TargetName="X_Fuzz1" Storyboard.TargetProperty="Visibility"> + <DiscreteObjectKeyFrame KeyTime="0" Value="Visible" /> + </ObjectAnimationUsingKeyFrames> + <ObjectAnimationUsingKeyFrames Storyboard.TargetName="X_Fuzz0" Storyboard.TargetProperty="Visibility"> + <DiscreteObjectKeyFrame KeyTime="0" Value="Visible" /> + </ObjectAnimationUsingKeyFrames> + <DoubleAnimation Duration="0" + Storyboard.TargetName="X" + Storyboard.TargetProperty="Opacity" + To="0.95" /> + </Storyboard> + </vsm:VisualState> + <vsm:VisualState x:Name="Pressed"> + <Storyboard> + <DoubleAnimation Duration="0" + Storyboard.TargetName="X" + Storyboard.TargetProperty="Opacity" + To="0.85" /> + <ObjectAnimationUsingKeyFrames Storyboard.TargetName="X_Fuzz2" Storyboard.TargetProperty="Visibility"> + <DiscreteObjectKeyFrame KeyTime="0" Value="Visible" /> + </ObjectAnimationUsingKeyFrames> + <ObjectAnimationUsingKeyFrames Storyboard.TargetName="X_Fuzz1" Storyboard.TargetProperty="Visibility"> + <DiscreteObjectKeyFrame KeyTime="0" Value="Visible" /> + </ObjectAnimationUsingKeyFrames> + <ObjectAnimationUsingKeyFrames Storyboard.TargetName="X_Fuzz0" Storyboard.TargetProperty="Visibility"> + <DiscreteObjectKeyFrame KeyTime="0" Value="Visible" /> + </ObjectAnimationUsingKeyFrames> + </Storyboard> + </vsm:VisualState> + <vsm:VisualState x:Name="Disabled"> + <Storyboard> + <DoubleAnimation Duration="0" + Storyboard.TargetName="X" + Storyboard.TargetProperty="Opacity" + To="0.5" /> + </Storyboard> + </vsm:VisualState> + </vsm:VisualStateGroup> + </vsm:VisualStateManager.VisualStateGroups> + <Path x:Name="X_Fuzz2" + Width="9" + Height="8" + Margin="0,-1,0,0" + HorizontalAlignment="Center" + VerticalAlignment="Center" + Data="F1 M 6.742676,3.852539 L 9.110840,1.559570 L 8.910645,0.500000 L 6.838379,0.500000 L 4.902832,2.435547 L 2.967285,0.500000 L 0.895020,0.500000 L 0.694824,1.559570 L 3.062988,3.852539 L 0.527832,6.351563 L 0.689941,7.600586 L 2.967285,7.600586 L 4.897949,5.575195 L 6.854004,7.600586 L 9.115723,7.600586 L 9.277832,6.351563 L 6.742676,3.852539 Z" + Fill="#14C51900" + Opacity="1" + RenderTransformOrigin="0.5,0.5" + Stretch="Fill" + Stroke="#14C51900" + Visibility="Collapsed"> + <Path.RenderTransform> + <TransformGroup> + <ScaleTransform ScaleX="1.3" ScaleY="1.3" /> + </TransformGroup> + </Path.RenderTransform> + </Path> + <Path x:Name="X_Fuzz1" + Width="9" + Height="8" + Margin="0,-1,0,0" + HorizontalAlignment="Center" + VerticalAlignment="Center" + Data="F1 M 6.742676,3.852539 L 9.110840,1.559570 L 8.910645,0.500000 L 6.838379,0.500000 L 4.902832,2.435547 L 2.967285,0.500000 L 0.895020,0.500000 L 0.694824,1.559570 L 3.062988,3.852539 L 0.527832,6.351563 L 0.689941,7.600586 L 2.967285,7.600586 L 4.897949,5.575195 L 6.854004,7.600586 L 9.115723,7.600586 L 9.277832,6.351563 L 6.742676,3.852539 Z" + Fill="#1EC51900" + Opacity="1" + RenderTransformOrigin="0.5,0.5" + Stretch="Fill" + Stroke="#1EC51900" + Visibility="Collapsed"> + <Path.RenderTransform> + <TransformGroup> + <ScaleTransform ScaleX="1.1" ScaleY="1.1" /> + </TransformGroup> + </Path.RenderTransform> + </Path> + <Path x:Name="X_Fuzz0" + Width="9" + Height="8" + Margin="0,-1,0,0" + HorizontalAlignment="Center" + VerticalAlignment="Center" + Data="F1 M 6.742676,3.852539 L 9.110840,1.559570 L 8.910645,0.500000 L 6.838379,0.500000 L 4.902832,2.435547 L 2.967285,0.500000 L 0.895020,0.500000 L 0.694824,1.559570 L 3.062988,3.852539 L 0.527832,6.351563 L 0.689941,7.600586 L 2.967285,7.600586 L 4.897949,5.575195 L 6.854004,7.600586 L 9.115723,7.600586 L 9.277832,6.351563 L 6.742676,3.852539 Z" + Fill="#FFC51900" + Opacity="1" + Stretch="Fill" + Stroke="#FFC51900" + Visibility="Collapsed" /> + <Path x:Name="X" + Width="9" + Height="8" + Margin="0,-1,0,0" + HorizontalAlignment="Center" + VerticalAlignment="Center" + Data="F1 M 6.742676,3.852539 L 9.110840,1.559570 L 8.910645,0.500000 L 6.838379,0.500000 L 4.902832,2.435547 L 2.967285,0.500000 L 0.895020,0.500000 L 0.694824,1.559570 L 3.062988,3.852539 L 0.527832,6.351563 L 0.689941,7.600586 L 2.967285,7.600586 L 4.897949,5.575195 L 6.854004,7.600586 L 9.115723,7.600586 L 9.277832,6.351563 L 6.742676,3.852539 Z" + Fill="#FFFFFFFF" + Opacity="0.7" + Stretch="Fill"> + <Path.Stroke> + <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1"> + <GradientStop Offset="1" Color="#FF313131" /> + <GradientStop Offset="0" Color="#FF8E9092" /> + </LinearGradientBrush> + </Path.Stroke> + </Path> + </Grid> + </ControlTemplate> + </Setter.Value> + </Setter> + </Style> + </Grid.Resources> + <vsm:VisualStateManager.VisualStateGroups> + <vsm:VisualStateGroup x:Name="WindowStates"> + <vsm:VisualState x:Name="Open"> + <Storyboard> + <DoubleAnimationUsingKeyFrames BeginTime="0" + Storyboard.TargetName="Overlay" + Storyboard.TargetProperty="Opacity"> + <EasingDoubleKeyFrame KeyTime="0" Value="0" /> + <EasingDoubleKeyFrame KeyTime="00:00:00.3" Value="1" /> + </DoubleAnimationUsingKeyFrames> + <DoubleAnimationUsingKeyFrames BeginTime="0" + Storyboard.TargetName="ContentRoot" + Storyboard.TargetProperty="(RenderTransform).(Children)[0].ScaleX"> + <SplineDoubleKeyFrame KeyTime="0" Value="0" /> + <SplineDoubleKeyFrame KeyTime="00:00:00.25" Value="0" /> + <SplineDoubleKeyFrame KeyTime="00:00:00.4" Value="1" /> + <SplineDoubleKeyFrame KeySpline="0,0,0.5,1" + KeyTime="00:00:00.45" + Value="1.05" /> + <SplineDoubleKeyFrame KeyTime="00:00:00.55" Value="1" /> + </DoubleAnimationUsingKeyFrames> + <DoubleAnimationUsingKeyFrames BeginTime="0" + Storyboard.TargetName="ContentRoot" + Storyboard.TargetProperty="(RenderTransform).(Children)[0].ScaleY"> + <SplineDoubleKeyFrame KeyTime="0" Value="0" /> + <SplineDoubleKeyFrame KeyTime="00:00:00.25" Value="0" /> + <SplineDoubleKeyFrame KeyTime="00:00:00.4" Value="1" /> + <SplineDoubleKeyFrame KeySpline="0,0,0.5,1" + KeyTime="00:00:00.45" + Value="1.05" /> + <SplineDoubleKeyFrame KeyTime="00:00:00.55" Value="1" /> + </DoubleAnimationUsingKeyFrames> + </Storyboard> + </vsm:VisualState> + <vsm:VisualState x:Name="Closed"> + <Storyboard> + <DoubleAnimationUsingKeyFrames BeginTime="0" + Storyboard.TargetName="Overlay" + Storyboard.TargetProperty="Opacity"> + <EasingDoubleKeyFrame KeyTime="0" Value="1" /> + <EasingDoubleKeyFrame KeyTime="00:00:00.3" Value="0" /> + </DoubleAnimationUsingKeyFrames> + <DoubleAnimationUsingKeyFrames BeginTime="0" + Storyboard.TargetName="ContentRoot" + Storyboard.TargetProperty="(RenderTransform).(Children)[0].ScaleX"> + <SplineDoubleKeyFrame KeyTime="00:00:00.2" Value="1" /> + <SplineDoubleKeyFrame KeyTime="00:00:00.25" Value="1.05" /> + <SplineDoubleKeyFrame KeyTime="00:00:00.45" Value="0" /> + </DoubleAnimationUsingKeyFrames> + <DoubleAnimationUsingKeyFrames BeginTime="0" + Storyboard.TargetName="ContentRoot" + Storyboard.TargetProperty="(RenderTransform).(Children)[0].ScaleY"> + <SplineDoubleKeyFrame KeyTime="00:00:00.2" Value="1" /> + <SplineDoubleKeyFrame KeyTime="00:00:00.25" Value="1.05" /> + <SplineDoubleKeyFrame KeyTime="00:00:00.45" Value="0" /> + </DoubleAnimationUsingKeyFrames> + </Storyboard> + </vsm:VisualState> + </vsm:VisualStateGroup> + </vsm:VisualStateManager.VisualStateGroups> + <Grid x:Name="Overlay" + Margin="0" + HorizontalAlignment="Stretch" + VerticalAlignment="Top" + Background="{TemplateBinding OverlayBrush}" + Opacity="{TemplateBinding OverlayOpacity}" /> + <Grid x:Name="ContentRoot" + Width="{TemplateBinding Width}" + Height="{TemplateBinding Height}" + HorizontalAlignment="{TemplateBinding HorizontalAlignment}" + VerticalAlignment="{TemplateBinding VerticalAlignment}" + RenderTransformOrigin="0.5,0.5"> + <Grid.RenderTransform> + <TransformGroup> + <ScaleTransform /> + <SkewTransform /> + <RotateTransform /> + <TranslateTransform /> + </TransformGroup> + </Grid.RenderTransform> + <Border Margin="-1" + HorizontalAlignment="Stretch" + VerticalAlignment="Stretch" + Background="#14000000" + BorderBrush="#14000000" + BorderThickness="1" + CornerRadius="2" /> + <Border Margin="-2" + HorizontalAlignment="Stretch" + VerticalAlignment="Stretch" + Background="#0F000000" + BorderBrush="#0F000000" + BorderThickness="1" + CornerRadius="2.25" /> + <Border Margin="-3" + HorizontalAlignment="Stretch" + VerticalAlignment="Stretch" + Background="#0C000000" + BorderBrush="#0C000000" + BorderThickness="1" + CornerRadius="2.5" /> + <Border Margin="-4" + HorizontalAlignment="Stretch" + VerticalAlignment="Stretch" + Background="#0A000000" + BorderBrush="#0A000000" + BorderThickness="1" + CornerRadius="2.75" /> + <Border Background="#FFFFFFFF" + BorderBrush="{TemplateBinding BorderBrush}" + BorderThickness="{TemplateBinding BorderThickness}" + CornerRadius="2"> + <Border Margin="1" CornerRadius="1.5"> + <Border.Background> + <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1"> + <GradientStop Offset="1" Color="#FFE5E8EB" /> + <GradientStop Offset="0" Color="#FFF6F8F9" /> + </LinearGradientBrush> + </Border.Background> + <Grid> + <Grid.RowDefinitions> + <RowDefinition Height="Auto" /> + <RowDefinition /> + </Grid.RowDefinitions> + <Border x:Name="Chrome" + Width="Auto" + BorderBrush="#FFFFFFFF" + BorderThickness="0,0,0,1"> + <Border.Background> + <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,0.528"> + <GradientStop Offset="1" Color="#FFE5E8EB" /> + <GradientStop Offset="0" Color="#FFFEFEFE" /> + </LinearGradientBrush> + </Border.Background> + <Grid Width="Auto" Height="Auto"> + <Grid.ColumnDefinitions> + <ColumnDefinition /> + <ColumnDefinition Width="30" /> + </Grid.ColumnDefinitions> + <ContentControl Margin="6,0,6,0" + HorizontalAlignment="Stretch" + VerticalAlignment="Center" + Content="{TemplateBinding Title}" + FontWeight="Bold" + IsTabStop="False" /> + <Button x:Name="CloseButton" + Grid.Column="1" + Width="15" + Height="14" + HorizontalAlignment="Center" + VerticalAlignment="Center" + IsTabStop="False" + Style="{StaticResource ButtonStyle}" /> + </Grid> + </Border> + <Border Grid.Row="1" + Margin="7" + Background="{TemplateBinding Background}"> + <ContentPresenter x:Name="ContentPresenter" + HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" + VerticalAlignment="{TemplateBinding VerticalContentAlignment}" + Content="{TemplateBinding Content}" + ContentTemplate="{TemplateBinding ContentTemplate}" /> + </Border> + </Grid> + </Border> + </Border> + </Grid> + </Grid> + </ControlTemplate> + </Setter.Value> + </Setter> + </Style> +</ResourceDictionary> \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SilverlightGlimpse/SilverlightValidation/App.xaml Mon Apr 23 11:06:10 2012 +0100 @@ -0,0 +1,997 @@ +<Application x:Class="SilverlightValidation.App" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:p="clr-namespace:System.Windows.Controls.Primitives;assembly=System.Windows.Controls" + xmlns:s="clr-namespace:System;assembly=mscorlib" + xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"> + <Application.Resources> + <ControlTemplate x:Key="ValidationToolTipTemplate"> + <Grid x:Name="Root" + Margin="5,0" + Opacity="0" + RenderTransformOrigin="0,0"> + <Grid.RenderTransform> + <TranslateTransform x:Name="xform" X="-25" /> + </Grid.RenderTransform> + <VisualStateManager.VisualStateGroups> + <VisualStateGroup x:Name="OpenStates"> + <VisualStateGroup.Transitions> + <VisualTransition GeneratedDuration="0" /> + <VisualTransition GeneratedDuration="0:0:0.2" To="Open"> + <Storyboard> + <DoubleAnimation Duration="0:0:0.2" + Storyboard.TargetName="xform" + Storyboard.TargetProperty="X" + To="0"> + <DoubleAnimation.EasingFunction> + <BackEase Amplitude=".3" EasingMode="EaseOut" /> + </DoubleAnimation.EasingFunction> + </DoubleAnimation> + <DoubleAnimation Duration="0:0:0.2" + Storyboard.TargetName="Root" + Storyboard.TargetProperty="Opacity" + To="1" /> + </Storyboard> + </VisualTransition> + </VisualStateGroup.Transitions> + <VisualState x:Name="Closed"> + <Storyboard> + <DoubleAnimation Duration="0" + Storyboard.TargetName="Root" + Storyboard.TargetProperty="Opacity" + To="0" /> + </Storyboard> + </VisualState> + <VisualState x:Name="Open"> + <Storyboard> + <DoubleAnimation Duration="0" + Storyboard.TargetName="xform" + Storyboard.TargetProperty="X" + To="0" /> + <DoubleAnimation Duration="0" + Storyboard.TargetName="Root" + Storyboard.TargetProperty="Opacity" + To="1" /> + </Storyboard> + </VisualState> + </VisualStateGroup> + </VisualStateManager.VisualStateGroups> + <Border Margin="4,4,-4,-4" + Background="#052A2E31" + CornerRadius="5" /> + <Border Margin="3,3,-3,-3" + Background="#152A2E31" + CornerRadius="4" /> + <Border Margin="2,2,-2,-2" + Background="#252A2E31" + CornerRadius="3" /> + <Border Margin="1,1,-1,-1" + Background="#352A2E31" + CornerRadius="2" /> + <Border Background="#FFDC000C" CornerRadius="2" /> + <Border CornerRadius="2"> + <TextBlock MaxWidth="250" + Margin="8,4,8,4" + Foreground="White" + Text="{Binding (Validation.Errors)[0].ErrorContent}" + TextWrapping="Wrap" + UseLayoutRounding="false" /> + </Border> + </Grid> + </ControlTemplate> + + <Style x:Key="LabelStyle" TargetType="TextBlock"> + <Setter Property="Height" Value="18" /> + <Setter Property="FontFamily" Value="Segoe UI Light" /> + <Setter Property="FontSize" Value="14" /> + <Setter Property="VerticalAlignment" Value="Center" /> + </Style> + + <Style x:Key="TextBoxStyle" TargetType="TextBox"> + <Setter Property="BorderThickness" Value="1" /> + <Setter Property="Background" Value="#FFFFFFFF" /> + <Setter Property="FontFamily" Value="Segoe UI Light" /> + <Setter Property="FontSize" Value="12" /> + <Setter Property="Height" Value="24" /> + <Setter Property="VerticalAlignment" Value="Center" /> + <Setter Property="Foreground" Value="#FF000000" /> + <Setter Property="Padding" Value="2" /> + <Setter Property="BorderBrush"> + <Setter.Value> + <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1"> + <GradientStop Offset="0" Color="#FFA3AEB9" /> + <GradientStop Offset="0.375" Color="#FF8399A9" /> + <GradientStop Offset="0.375" Color="#FF718597" /> + <GradientStop Offset="1" Color="#FF617584" /> + </LinearGradientBrush> + </Setter.Value> + </Setter> + <Setter Property="Template"> + <Setter.Value> + <ControlTemplate TargetType="TextBox"> + <Grid x:Name="RootElement"> + <VisualStateManager.VisualStateGroups> + <VisualStateGroup x:Name="CommonStates"> + <VisualState x:Name="Normal" /> + <VisualState x:Name="MouseOver"> + <Storyboard> + <ColorAnimation Duration="0" + Storyboard.TargetName="MouseOverBorder" + Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" + To="#FF99C1E2" /> + </Storyboard> + </VisualState> + <VisualState x:Name="Disabled"> + <Storyboard> + <DoubleAnimation Duration="0" + Storyboard.TargetName="DisabledVisualElement" + Storyboard.TargetProperty="Opacity" + To="1" /> + </Storyboard> + </VisualState> + <VisualState x:Name="ReadOnly"> + <Storyboard> + <DoubleAnimation Duration="0" + Storyboard.TargetName="ReadOnlyVisualElement" + Storyboard.TargetProperty="Opacity" + To="1" /> + </Storyboard> + </VisualState> + </VisualStateGroup> + <VisualStateGroup x:Name="FocusStates"> + <VisualState x:Name="Focused"> + <Storyboard> + <DoubleAnimation Duration="0" + Storyboard.TargetName="FocusVisualElement" + Storyboard.TargetProperty="Opacity" + To="1" /> + </Storyboard> + </VisualState> + <VisualState x:Name="Unfocused"> + <Storyboard> + <DoubleAnimation Duration="0" + Storyboard.TargetName="FocusVisualElement" + Storyboard.TargetProperty="Opacity" + To="0" /> + </Storyboard> + </VisualState> + </VisualStateGroup> + <VisualStateGroup x:Name="ValidationStates"> + <VisualState x:Name="Valid" /> + <VisualState x:Name="InvalidUnfocused"> + <Storyboard> + <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ValidationErrorElement" Storyboard.TargetProperty="Visibility"> + <DiscreteObjectKeyFrame KeyTime="0"> + <DiscreteObjectKeyFrame.Value> + <Visibility>Visible</Visibility> + </DiscreteObjectKeyFrame.Value> + </DiscreteObjectKeyFrame> + </ObjectAnimationUsingKeyFrames> + </Storyboard> + </VisualState> + <VisualState x:Name="InvalidFocused"> + <Storyboard> + <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ValidationErrorElement" Storyboard.TargetProperty="Visibility"> + <DiscreteObjectKeyFrame KeyTime="0"> + <DiscreteObjectKeyFrame.Value> + <Visibility>Visible</Visibility> + </DiscreteObjectKeyFrame.Value> + </DiscreteObjectKeyFrame> + </ObjectAnimationUsingKeyFrames> + <ObjectAnimationUsingKeyFrames Storyboard.TargetName="validationTooltip" Storyboard.TargetProperty="IsOpen"> + <DiscreteObjectKeyFrame KeyTime="0"> + <DiscreteObjectKeyFrame.Value> + <s:Boolean>True</s:Boolean> + </DiscreteObjectKeyFrame.Value> + </DiscreteObjectKeyFrame> + </ObjectAnimationUsingKeyFrames> + </Storyboard> + </VisualState> + </VisualStateGroup> + </VisualStateManager.VisualStateGroups> + <Border x:Name="Border" + Background="{TemplateBinding Background}" + BorderBrush="{TemplateBinding BorderBrush}" + BorderThickness="{TemplateBinding BorderThickness}" + CornerRadius="1" + Opacity="1"> + <Grid> + <Border x:Name="ReadOnlyVisualElement" + Background="#5EC9C9C9" + Opacity="0" /> + <Border x:Name="MouseOverBorder" + BorderBrush="Transparent" + BorderThickness="1"> + <ScrollViewer x:Name="ContentElement" + BorderThickness="0" + IsTabStop="False" + Padding="{TemplateBinding Padding}" /> + </Border> + </Grid> + </Border> + <Border x:Name="DisabledVisualElement" + Background="#A5F7F7F7" + BorderBrush="#A5F7F7F7" + BorderThickness="{TemplateBinding BorderThickness}" + IsHitTestVisible="False" + Opacity="0" /> + <Border x:Name="FocusVisualElement" + Margin="1" + BorderBrush="#FF6DBDD1" + BorderThickness="{TemplateBinding BorderThickness}" + IsHitTestVisible="False" + Opacity="0" /> + <Border x:Name="ValidationErrorElement" + BorderBrush="#FFDC000C" + BorderThickness="1" + CornerRadius="1" + Visibility="Collapsed"> + <ToolTipService.ToolTip> + <ToolTip x:Name="validationTooltip" + DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}" + Placement="Right" + PlacementTarget="{Binding RelativeSource={RelativeSource TemplatedParent}}" + Template="{StaticResource ValidationToolTipTemplate}"> + <ToolTip.Triggers> + <EventTrigger RoutedEvent="Canvas.Loaded"> + <EventTrigger.Actions> + <BeginStoryboard> + <Storyboard> + <ObjectAnimationUsingKeyFrames Storyboard.TargetName="validationTooltip" Storyboard.TargetProperty="IsHitTestVisible"> + <DiscreteObjectKeyFrame KeyTime="0"> + <DiscreteObjectKeyFrame.Value> + <s:Boolean>true</s:Boolean> + </DiscreteObjectKeyFrame.Value> + </DiscreteObjectKeyFrame> + </ObjectAnimationUsingKeyFrames> + </Storyboard> + </BeginStoryboard> + </EventTrigger.Actions> + </EventTrigger> + </ToolTip.Triggers> + </ToolTip> + </ToolTipService.ToolTip> + <Grid Width="12" + Height="12" + Margin="1,-4,-4,0" + HorizontalAlignment="Right" + VerticalAlignment="Top" + Background="Transparent"> + <Path Margin="1,3,0,0" + Data="M 1,0 L6,0 A 2,2 90 0 1 8,2 L8,7 z" + Fill="#FFDC000C" /> + <Path Margin="1,3,0,0" + Data="M 0,0 L2,0 L 8,6 L8,8" + Fill="#ffffff" /> + </Grid> + </Border> + </Grid> + </ControlTemplate> + </Setter.Value> + </Setter> + </Style> + + <Style x:Key="DatePickerStyle" TargetType="sdk:DatePicker"> + <Setter Property="FontFamily" Value="Segoe UI Light" /> + <Setter Property="FontSize" Value="14" /> + <Setter Property="Height" Value="24" /> + <Setter Property="VerticalAlignment" Value="Center" /> + <Setter Property="IsTabStop" Value="False" /> + <Setter Property="Background" Value="#FFFFFFFF" /> + <Setter Property="Padding" Value="2" /> + <Setter Property="SelectionBackground" Value="#FF444444" /> + <Setter Property="BorderBrush"> + <Setter.Value> + <LinearGradientBrush StartPoint=".5,1" EndPoint=".5,0"> + <GradientStop Offset="0" Color="#FF617584" /> + <GradientStop Offset="0.375" Color="#FF718597" /> + <GradientStop Offset="0.375" Color="#FF8399A9" /> + <GradientStop Offset="1" Color="#FFA3AEB9" /> + </LinearGradientBrush> + </Setter.Value> + </Setter> + <Setter Property="BorderThickness" Value="1" /> + <Setter Property="Template"> + <Setter.Value> + <ControlTemplate TargetType="sdk:DatePicker"> + <Grid x:Name="Root"> + <Grid.Resources> + <SolidColorBrush x:Key="DisabledBrush" Color="#8CFFFFFF" /> + <ControlTemplate x:Key="DropDownButtonTemplate" TargetType="Button"> + <Grid> + <VisualStateManager.VisualStateGroups> + <VisualStateGroup x:Name="CommonStates"> + <VisualStateGroup.Transitions> + <VisualTransition GeneratedDuration="0" /> + <VisualTransition GeneratedDuration="0:0:0.1" To="MouseOver" /> + <VisualTransition GeneratedDuration="0:0:0.1" To="Pressed" /> + </VisualStateGroup.Transitions> + <VisualState x:Name="Normal" /> + <VisualState x:Name="MouseOver"> + <Storyboard> + <ColorAnimation Duration="0" + Storyboard.TargetName="Background" + Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" + To="#FF448DCA" /> + <ColorAnimationUsingKeyFrames BeginTime="0" + Duration="00:00:00.001" + Storyboard.TargetName="BackgroundGradient" + Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[3].(GradientStop.Color)"> + <SplineColorKeyFrame KeyTime="0" Value="#7FFFFFFF" /> + </ColorAnimationUsingKeyFrames> + <ColorAnimationUsingKeyFrames BeginTime="0" + Duration="00:00:00.001" + Storyboard.TargetName="BackgroundGradient" + Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[2].(GradientStop.Color)"> + <SplineColorKeyFrame KeyTime="0" Value="#CCFFFFFF" /> + </ColorAnimationUsingKeyFrames> + <ColorAnimationUsingKeyFrames BeginTime="0" + Duration="00:00:00.001" + Storyboard.TargetName="BackgroundGradient" + Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[1].(GradientStop.Color)"> + <SplineColorKeyFrame KeyTime="0" Value="#F2FFFFFF" /> + </ColorAnimationUsingKeyFrames> + </Storyboard> + </VisualState> + <VisualState x:Name="Pressed"> + <Storyboard> + <ColorAnimationUsingKeyFrames BeginTime="0" + Duration="00:00:00.001" + Storyboard.TargetName="Background" + Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)"> + <SplineColorKeyFrame KeyTime="0" Value="#FF448DCA" /> + </ColorAnimationUsingKeyFrames> + <DoubleAnimationUsingKeyFrames BeginTime="0" + Duration="00:00:00.001" + Storyboard.TargetName="Highlight" + Storyboard.TargetProperty="(UIElement.Opacity)"> + <SplineDoubleKeyFrame KeyTime="0" Value="1" /> + </DoubleAnimationUsingKeyFrames> + <ColorAnimationUsingKeyFrames BeginTime="0" + Duration="00:00:00.001" + Storyboard.TargetName="BackgroundGradient" + Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[1].(GradientStop.Color)"> + <SplineColorKeyFrame KeyTime="0" Value="#EAFFFFFF" /> + </ColorAnimationUsingKeyFrames> + <ColorAnimationUsingKeyFrames BeginTime="0" + Duration="00:00:00.001" + Storyboard.TargetName="BackgroundGradient" + Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[2].(GradientStop.Color)"> + <SplineColorKeyFrame KeyTime="0" Value="#C6FFFFFF" /> + </ColorAnimationUsingKeyFrames> + <ColorAnimationUsingKeyFrames BeginTime="0" + Duration="00:00:00.001" + Storyboard.TargetName="BackgroundGradient" + Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[3].(GradientStop.Color)"> + <SplineColorKeyFrame KeyTime="0" Value="#6BFFFFFF" /> + </ColorAnimationUsingKeyFrames> + <ColorAnimationUsingKeyFrames BeginTime="0" + Duration="00:00:00.001" + Storyboard.TargetName="BackgroundGradient" + Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[0].(GradientStop.Color)"> + <SplineColorKeyFrame KeyTime="0" Value="#F4FFFFFF" /> + </ColorAnimationUsingKeyFrames> + </Storyboard> + </VisualState> + <VisualState x:Name="Disabled"> + <Storyboard> + <DoubleAnimationUsingKeyFrames BeginTime="0" + Duration="00:00:00.001" + Storyboard.TargetName="DisabledVisual" + Storyboard.TargetProperty="(UIElement.Opacity)"> + <SplineDoubleKeyFrame KeyTime="0" Value="1" /> + </DoubleAnimationUsingKeyFrames> + </Storyboard> + </VisualState> + </VisualStateGroup> + </VisualStateManager.VisualStateGroups> + <Grid Width="19" + Height="18" + Margin="0" + HorizontalAlignment="Center" + VerticalAlignment="Center" + Background="#11FFFFFF"> + <Grid.RowDefinitions> + <RowDefinition Height="23*" /> + <RowDefinition Height="19*" /> + <RowDefinition Height="19*" /> + <RowDefinition Height="19*" /> + </Grid.RowDefinitions> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="20*" /> + <ColumnDefinition Width="20*" /> + <ColumnDefinition Width="20*" /> + <ColumnDefinition Width="20*" /> + </Grid.ColumnDefinitions> + <Border x:Name="Highlight" + Grid.Row="0" + Grid.RowSpan="4" + Grid.ColumnSpan="4" + Margin="-1" + BorderBrush="#FF6DBDD1" + BorderThickness="1" + CornerRadius="0,0,1,1" + Opacity="0" /> + <Border x:Name="Background" + Grid.Row="1" + Grid.RowSpan="3" + Grid.ColumnSpan="4" + Margin="0,-1,0,0" + Background="#FF1F3B53" + BorderBrush="#FFFFFFFF" + BorderThickness="1" + CornerRadius=".5" + Opacity="1" /> + <Border x:Name="BackgroundGradient" + Grid.Row="1" + Grid.RowSpan="3" + Grid.ColumnSpan="4" + Margin="0,-1,0,0" + BorderBrush="#BF000000" + BorderThickness="1" + CornerRadius=".5" + Opacity="1"> + <Border.Background> + <LinearGradientBrush StartPoint=".7,0" EndPoint=".7,1"> + <GradientStop Offset="0" Color="#FFFFFFFF" /> + <GradientStop Offset="0.375" Color="#F9FFFFFF" /> + <GradientStop Offset="0.625" Color="#E5FFFFFF" /> + <GradientStop Offset="1" Color="#C6FFFFFF" /> + </LinearGradientBrush> + </Border.Background> + </Border> + <Rectangle Grid.RowSpan="1" + Grid.ColumnSpan="4" + StrokeThickness="1"> + <Rectangle.Stroke> + <LinearGradientBrush StartPoint="0.48,1.25" EndPoint="0.48,-1"> + <GradientStop Color="#FF494949" /> + <GradientStop Offset="1" Color="#FF9F9F9F" /> + </LinearGradientBrush> + </Rectangle.Stroke> + <Rectangle.Fill> + <LinearGradientBrush StartPoint="0.46,1.6" EndPoint="0.3,-1.1"> + <GradientStop Color="#FF4084BD" /> + <GradientStop Offset="1" Color="#FFAFCFEA" /> + </LinearGradientBrush> + </Rectangle.Fill> + </Rectangle> + <Path Grid.Row="1" + Grid.RowSpan="3" + Grid.Column="0" + Grid.ColumnSpan="4" + Margin="4,3,4,3" + HorizontalAlignment="Center" + VerticalAlignment="Center" + Data="M11.426758,8.4305077 L11.749023,8.4305077 L11.749023,16.331387 L10.674805,16.331387 L10.674805,10.299648 L9.0742188,11.298672 L9.0742188,10.294277 C9.4788408,10.090176 9.9094238,9.8090878 10.365967,9.4510155 C10.82251,9.0929432 11.176106,8.7527733 11.426758,8.4305077 z M14.65086,8.4305077 L18.566387,8.4305077 L18.566387,9.3435936 L15.671368,9.3435936 L15.671368,11.255703 C15.936341,11.058764 16.27293,10.960293 16.681133,10.960293 C17.411602,10.960293 17.969301,11.178717 18.354229,11.615566 C18.739157,12.052416 18.931622,12.673672 18.931622,13.479336 C18.931622,15.452317 18.052553,16.438808 16.294415,16.438808 C15.560365,16.438808 14.951641,16.234707 14.468243,15.826504 L14.881817,14.929531 C15.368796,15.326992 15.837872,15.525723 16.289043,15.525723 C17.298809,15.525723 17.803692,14.895514 17.803692,13.635098 C17.803692,12.460618 17.305971,11.873379 16.310528,11.873379 C15.83071,11.873379 15.399232,12.079271 15.016094,12.491055 L14.65086,12.238613 z" + Fill="#FF2F2F2F" + RenderTransformOrigin="0.5,0.5" + Stretch="Fill" /> + <Ellipse Grid.ColumnSpan="4" + Width="3" + Height="3" + HorizontalAlignment="Center" + VerticalAlignment="Center" + Fill="#FFFFFFFF" + StrokeThickness="0" /> + <Border x:Name="DisabledVisual" + Grid.Row="0" + Grid.RowSpan="4" + Grid.ColumnSpan="4" + BorderBrush="#B2FFFFFF" + BorderThickness="1" + CornerRadius="0,0,.5,.5" + Opacity="0" /> + </Grid> + </Grid> + </ControlTemplate> + </Grid.Resources> + <VisualStateManager.VisualStateGroups> + <VisualStateGroup x:Name="CommonStates"> + <VisualState x:Name="Normal" /> + <VisualState x:Name="Disabled"> + <Storyboard> + <DoubleAnimation Duration="0" + Storyboard.TargetName="DisabledVisual" + Storyboard.TargetProperty="Opacity" + To="1" /> + </Storyboard> + </VisualState> + </VisualStateGroup> + <VisualStateGroup x:Name="ValidationStates"> + <VisualState x:Name="Valid" /> + <VisualState x:Name="InvalidUnfocused"> + <Storyboard> + <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ValidationErrorElement" Storyboard.TargetProperty="Visibility"> + <DiscreteObjectKeyFrame KeyTime="0"> + <DiscreteObjectKeyFrame.Value> + <Visibility>Visible</Visibility> + </DiscreteObjectKeyFrame.Value> + </DiscreteObjectKeyFrame> + </ObjectAnimationUsingKeyFrames> + </Storyboard> + </VisualState> + <VisualState x:Name="InvalidFocused"> + <Storyboard> + <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ValidationErrorElement" Storyboard.TargetProperty="Visibility"> + <DiscreteObjectKeyFrame KeyTime="0"> + <DiscreteObjectKeyFrame.Value> + <Visibility>Visible</Visibility> + </DiscreteObjectKeyFrame.Value> + </DiscreteObjectKeyFrame> + </ObjectAnimationUsingKeyFrames> + <ObjectAnimationUsingKeyFrames Storyboard.TargetName="validationTooltip" Storyboard.TargetProperty="IsOpen"> + <DiscreteObjectKeyFrame KeyTime="0"> + <DiscreteObjectKeyFrame.Value> + <s:Boolean>True</s:Boolean> + </DiscreteObjectKeyFrame.Value> + </DiscreteObjectKeyFrame> + </ObjectAnimationUsingKeyFrames> + </Storyboard> + </VisualState> + </VisualStateGroup> + </VisualStateManager.VisualStateGroups> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="*" /> + <ColumnDefinition Width="Auto" /> + </Grid.ColumnDefinitions> + <p:DatePickerTextBox x:Name="TextBox" + Grid.Column="0" + Background="{TemplateBinding Background}" + BorderBrush="{TemplateBinding BorderBrush}" + BorderThickness="{TemplateBinding BorderThickness}" + Padding="{TemplateBinding Padding}" + SelectionBackground="{TemplateBinding SelectionBackground}" /> + <Button x:Name="Button" + Grid.Column="1" + Width="20" + Margin="2,0,2,0" + BorderBrush="{TemplateBinding BorderBrush}" + BorderThickness="{TemplateBinding BorderThickness}" + Foreground="{TemplateBinding Foreground}" + Template="{StaticResource DropDownButtonTemplate}" /> + <Grid x:Name="DisabledVisual" + Grid.ColumnSpan="2" + IsHitTestVisible="False" + Opacity="0"> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="*" /> + <ColumnDefinition Width="Auto" /> + </Grid.ColumnDefinitions> + <Rectangle Fill="#8CFFFFFF" + RadiusX="1" + RadiusY="1" /> + <Rectangle Grid.Column="1" + Width="19" + Height="18" + Margin="2,0,2,0" + Fill="#8CFFFFFF" + RadiusX="1" + RadiusY="1" /> + </Grid> + <Popup x:Name="Popup" /> + <Border x:Name="ValidationErrorElement" + BorderBrush="#FFDC000C" + BorderThickness="1" + CornerRadius="1" + Visibility="Collapsed"> + <ToolTipService.ToolTip> + <ToolTip x:Name="validationTooltip" + DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}" + Placement="Right" + PlacementTarget="{Binding RelativeSource={RelativeSource TemplatedParent}}" + Template="{StaticResource ValidationToolTipTemplate}"> + <ToolTip.Triggers> + <EventTrigger RoutedEvent="Canvas.Loaded"> + <BeginStoryboard> + <Storyboard> + <ObjectAnimationUsingKeyFrames Storyboard.TargetName="validationTooltip" Storyboard.TargetProperty="IsHitTestVisible"> + <DiscreteObjectKeyFrame KeyTime="0"> + <DiscreteObjectKeyFrame.Value> + <s:Boolean>true</s:Boolean> + </DiscreteObjectKeyFrame.Value> + </DiscreteObjectKeyFrame> + </ObjectAnimationUsingKeyFrames> + </Storyboard> + </BeginStoryboard> + </EventTrigger> + </ToolTip.Triggers> + </ToolTip> + </ToolTipService.ToolTip> + <Grid Width="12" + Height="12" + Margin="1,-4,-4,0" + HorizontalAlignment="Right" + VerticalAlignment="Top" + Background="Transparent"> + <Path Margin="1,3,0,0" + Data="M 1,0 L6,0 A 2,2 90 0 1 8,2 L8,7 z" + Fill="#FFDC000C" /> + <Path Margin="1,3,0,0" + Data="M 0,0 L2,0 L 8,6 L8,8" + Fill="#ffffff" /> + </Grid> + </Border> + </Grid> + </ControlTemplate> + </Setter.Value> + </Setter> + </Style> + + <Style x:Key="ButtonStyle" TargetType="Button"> + <Setter Property="Height" Value="22" /> + <Setter Property="Margin" Value="5,0,0,0" /> + <Setter Property="VerticalAlignment" Value="Center" /> + <Setter Property="Width" Value="60" /> + </Style> + + <Style x:Key="ValidationSummaryStyle" TargetType="sdk:ValidationSummary"> + <Setter Property="IsTabStop" Value="False" /> + <Setter Property="Background" Value="#FFEFEFEA" /> + <Setter Property="BorderBrush" Value="#FFCECEC7" /> + <Setter Property="BorderThickness" Value="1" /> + <Setter Property="Padding" Value="0" /> + + <Setter Property="HeaderTemplate"> + <Setter.Value> + <DataTemplate> + <Border x:Name="Header" + Margin="-1,-1,-1,0" + Background="#FFDC000C" + CornerRadius="2"> + <StackPanel Margin="6,2,6,4" + VerticalAlignment="Top" + Orientation="Horizontal"> + <Grid Width="13" Height="13"> + <Ellipse Margin="0" RenderTransformOrigin="0.5,0.5"> + <Ellipse.Fill> + <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1"> + <GradientStop Offset="0" Color="#FFFFFFFF" /> + <GradientStop Offset="1" Color="#FFFDC8C8" /> + </LinearGradientBrush> + </Ellipse.Fill> + <Ellipse.Stroke> + <LinearGradientBrush StartPoint="0.505,0.65" EndPoint="0.5,0.058"> + <GradientStop Offset="0" Color="#FFDC000C" /> + <GradientStop Offset="0.991" Color="#FFFF9298" /> + </LinearGradientBrush> + </Ellipse.Stroke> + </Ellipse> + <Path Data="M5.5,2.5 L7.5,2.5 L7.5,8 L5.5,8 M5.5,9.5 L7.5,9.5 L7.5,10.5 L5.5,10.5" Fill="#DDD43940" /> + </Grid> + <TextBlock FontWeight="Bold" + Foreground="#FFFFFFFF" + Padding="4,1,0,0" + Text="{Binding}" /> + </StackPanel> + </Border> + </DataTemplate> + </Setter.Value> + </Setter> + <Setter Property="ErrorStyle"> + <Setter.Value> + <Style TargetType="ListBoxItem"> + <Setter Property="Template"> + <Setter.Value> + <ControlTemplate TargetType="ListBoxItem"> + <Grid Background="{TemplateBinding Background}"> + <VisualStateManager.VisualStateGroups> + <VisualStateGroup x:Name="CommonStates"> + <VisualState x:Name="Normal" /> + <VisualState x:Name="MouseOver"> + <Storyboard> + <DoubleAnimation Duration="0" + Storyboard.TargetName="FillColor" + Storyboard.TargetProperty="Opacity" + To=".35" /> + </Storyboard> + </VisualState> + <VisualState x:Name="Disabled"> + <Storyboard> + <DoubleAnimation Duration="0" + Storyboard.TargetName="ContentPresenter" + Storyboard.TargetProperty="Opacity" + To=".55" /> + </Storyboard> + </VisualState> + </VisualStateGroup> + <VisualStateGroup x:Name="SelectionStates"> + <VisualState x:Name="Unselected" /> + <VisualState x:Name="Selected"> + <Storyboard> + <DoubleAnimation Duration="0" + Storyboard.TargetName="FillColor2" + Storyboard.TargetProperty="Opacity" + To=".75" /> + </Storyboard> + </VisualState> + </VisualStateGroup> + <VisualStateGroup x:Name="FocusStates"> + <VisualState x:Name="Focused"> + <Storyboard> + <ObjectAnimationUsingKeyFrames Duration="0" + Storyboard.TargetName="FocusVisualElement" + Storyboard.TargetProperty="Visibility"> + <DiscreteObjectKeyFrame KeyTime="0" Value="Visible" /> + </ObjectAnimationUsingKeyFrames> + </Storyboard> + </VisualState> + <VisualState x:Name="Unfocused" /> + </VisualStateGroup> + </VisualStateManager.VisualStateGroups> + <Rectangle x:Name="FillColor" + Fill="#59F7D8DB" + IsHitTestVisible="False" + Opacity="0" + RadiusX="1" + RadiusY="1" /> + <Rectangle x:Name="FillColor2" + Fill="#FFF7D8DB" + IsHitTestVisible="False" + Opacity="0" + RadiusX="1" + RadiusY="1" /> + <ContentPresenter x:Name="ContentPresenter" + Margin="{TemplateBinding Padding}" + HorizontalAlignment="Left" + Content="{TemplateBinding Content}" + ContentTemplate="{TemplateBinding ContentTemplate}" /> + <Rectangle x:Name="FocusVisualElement" + RadiusX="1" + RadiusY="1" + Stroke="#FFF7D8DB" + StrokeThickness="1" + Visibility="Collapsed" /> + </Grid> + </ControlTemplate> + </Setter.Value> + </Setter> + </Style> + </Setter.Value> + </Setter> + <Setter Property="Template"> + <Setter.Value> + <ControlTemplate TargetType="sdk:ValidationSummary"> + <Grid x:Name="ValidationSummary"> + <VisualStateManager.VisualStateGroups> + <VisualStateGroup x:Name="CommonStates"> + <VisualState x:Name="Normal" /> + <VisualState x:Name="Disabled"> + <Storyboard> + <ObjectAnimationUsingKeyFrames Duration="0" + Storyboard.TargetName="DisabledVisual" + Storyboard.TargetProperty="Visibility"> + <DiscreteObjectKeyFrame KeyTime="0" Value="Visible" /> + </ObjectAnimationUsingKeyFrames> + </Storyboard> + </VisualState> + </VisualStateGroup> + <VisualStateGroup x:Name="ValidationStates"> + <VisualState x:Name="Empty"> + <Storyboard> + <ObjectAnimationUsingKeyFrames Duration="0" + Storyboard.TargetName="Content" + Storyboard.TargetProperty="Visibility"> + <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed" /> + </ObjectAnimationUsingKeyFrames> + </Storyboard> + </VisualState> + <VisualState x:Name="HasErrors" /> + </VisualStateGroup> + </VisualStateManager.VisualStateGroups> + <Border x:Name="Content" + Background="{TemplateBinding Background}" + BorderBrush="{TemplateBinding BorderBrush}" + BorderThickness="{TemplateBinding BorderThickness}" + CornerRadius="0,0,2,2"> + <Grid> + <Grid.RowDefinitions> + <RowDefinition Height="Auto" /> + <RowDefinition Height="*" /> + </Grid.RowDefinitions> + <ListBox x:Name="SummaryListBox" + Grid.Row="1" + Height="Auto" + Background="{x:Null}" + BorderThickness="0" + Foreground="{TemplateBinding Foreground}" + ItemContainerStyle="{TemplateBinding ErrorStyle}" + Padding="{TemplateBinding Padding}" + Style="{TemplateBinding SummaryListBoxStyle}"> + <ListBox.ItemTemplate> + <DataTemplate> + <StackPanel Orientation="Horizontal"> + <TextBlock Margin="4,0,0,0" + FontWeight="Bold" + Text="{Binding MessageHeader}" /> + <TextBlock Margin="4,0,0,0" Text="{Binding Message}" /> + </StackPanel> + </DataTemplate> + </ListBox.ItemTemplate> + </ListBox> + <Border x:Name="DisabledVisual" + Grid.RowSpan="2" + Background="#80FFFFFF" + IsHitTestVisible="True" + Visibility="Collapsed" /> + <ContentControl x:Name="HeaderContentControl" + HorizontalContentAlignment="Stretch" + VerticalContentAlignment="Center" + Content="{TemplateBinding Header}" + ContentTemplate="{TemplateBinding HeaderTemplate}" + IsTabStop="False" /> + </Grid> + </Border> + </Grid> + </ControlTemplate> + </Setter.Value> + </Setter> + </Style> + + <Style x:Key="PasswordBoxStyle" TargetType="PasswordBox"> + <Setter Property="FontFamily" Value="Segoe UI Light" /> + <Setter Property="FontSize" Value="12" /> + <Setter Property="Height" Value="24" /> + <Setter Property="VerticalAlignment" Value="Center" /> + <Setter Property="BorderThickness" Value="1" /> + <Setter Property="Background" Value="#FFFFFFFF" /> + <Setter Property="Foreground" Value="#FF000000" /> + <Setter Property="Padding" Value="2" /> + <Setter Property="BorderBrush"> + <Setter.Value> + <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1"> + <GradientStop Offset="0" Color="#FFA3AEB9" /> + <GradientStop Offset="0.375" Color="#FF8399A9" /> + <GradientStop Offset="0.375" Color="#FF718597" /> + <GradientStop Offset="1" Color="#FF617584" /> + </LinearGradientBrush> + </Setter.Value> + </Setter> + <Setter Property="Template"> + <Setter.Value> + <ControlTemplate TargetType="PasswordBox"> + <Grid x:Name="RootElement"> + <VisualStateManager.VisualStateGroups> + <VisualStateGroup x:Name="CommonStates"> + <VisualState x:Name="Normal" /> + <VisualState x:Name="MouseOver"> + <Storyboard> + <ColorAnimation Duration="0" + Storyboard.TargetName="MouseOverBorder" + Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" + To="#FF99C1E2" /> + </Storyboard> + </VisualState> + <VisualState x:Name="Disabled"> + <Storyboard> + <DoubleAnimation Duration="0" + Storyboard.TargetName="DisabledVisualElement" + Storyboard.TargetProperty="Opacity" + To="1" /> + </Storyboard> + </VisualState> + </VisualStateGroup> + <VisualStateGroup x:Name="FocusStates"> + <VisualState x:Name="Focused"> + <Storyboard> + <DoubleAnimation Duration="0" + Storyboard.TargetName="FocusVisualElement" + Storyboard.TargetProperty="Opacity" + To="1" /> + </Storyboard> + </VisualState> + <VisualState x:Name="Unfocused"> + <Storyboard> + <DoubleAnimation Duration="0" + Storyboard.TargetName="FocusVisualElement" + Storyboard.TargetProperty="Opacity" + To="0" /> + </Storyboard> + </VisualState> + </VisualStateGroup> + <VisualStateGroup x:Name="ValidationStates"> + <VisualState x:Name="Valid" /> + <VisualState x:Name="InvalidUnfocused"> + <Storyboard> + <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ValidationErrorElement" Storyboard.TargetProperty="Visibility"> + <DiscreteObjectKeyFrame KeyTime="0"> + <DiscreteObjectKeyFrame.Value> + <Visibility>Visible</Visibility> + </DiscreteObjectKeyFrame.Value> + </DiscreteObjectKeyFrame> + </ObjectAnimationUsingKeyFrames> + </Storyboard> + </VisualState> + <VisualState x:Name="InvalidFocused"> + <Storyboard> + <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ValidationErrorElement" Storyboard.TargetProperty="Visibility"> + <DiscreteObjectKeyFrame KeyTime="0"> + <DiscreteObjectKeyFrame.Value> + <Visibility>Visible</Visibility> + </DiscreteObjectKeyFrame.Value> + </DiscreteObjectKeyFrame> + </ObjectAnimationUsingKeyFrames> + <ObjectAnimationUsingKeyFrames Storyboard.TargetName="validationTooltip" Storyboard.TargetProperty="IsOpen"> + <DiscreteObjectKeyFrame KeyTime="0"> + <DiscreteObjectKeyFrame.Value> + <s:Boolean>True</s:Boolean> + </DiscreteObjectKeyFrame.Value> + </DiscreteObjectKeyFrame> + </ObjectAnimationUsingKeyFrames> + </Storyboard> + </VisualState> + </VisualStateGroup> + </VisualStateManager.VisualStateGroups> + <Border x:Name="Border" + Background="{TemplateBinding Background}" + BorderBrush="{TemplateBinding BorderBrush}" + BorderThickness="{TemplateBinding BorderThickness}" + CornerRadius="1" + Opacity="1"> + <Border x:Name="MouseOverBorder" + BorderBrush="Transparent" + BorderThickness="1"> + <Border x:Name="ContentElement" Margin="{TemplateBinding Padding}" /> + </Border> + </Border> + <Border x:Name="DisabledVisualElement" + Background="#A5F7F7F7" + BorderBrush="#A5F7F7F7" + BorderThickness="{TemplateBinding BorderThickness}" + IsHitTestVisible="False" + Opacity="0" /> + <Border x:Name="FocusVisualElement" + Margin="1" + BorderBrush="#FF6DBDD1" + BorderThickness="{TemplateBinding BorderThickness}" + IsHitTestVisible="False" + Opacity="0" /> + <Border x:Name="ValidationErrorElement" + BorderBrush="#FFDC000C" + BorderThickness="1" + CornerRadius="1" + Visibility="Collapsed"> + <ToolTipService.ToolTip> + <ToolTip x:Name="validationTooltip" + DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}" + Placement="Right" + PlacementTarget="{Binding RelativeSource={RelativeSource TemplatedParent}}" + Template="{StaticResource ValidationToolTipTemplate}"> + <ToolTip.Triggers> + <EventTrigger RoutedEvent="Canvas.Loaded"> + <BeginStoryboard> + <Storyboard> + <ObjectAnimationUsingKeyFrames Storyboard.TargetName="validationTooltip" Storyboard.TargetProperty="IsHitTestVisible"> + <DiscreteObjectKeyFrame KeyTime="0"> + <DiscreteObjectKeyFrame.Value> + <s:Boolean>true</s:Boolean> + </DiscreteObjectKeyFrame.Value> + </DiscreteObjectKeyFrame> + </ObjectAnimationUsingKeyFrames> + </Storyboard> + </BeginStoryboard> + </EventTrigger> + </ToolTip.Triggers> + </ToolTip> + </ToolTipService.ToolTip> + <Grid Width="12" + Height="12" + Margin="1,-4,-4,0" + HorizontalAlignment="Right" + VerticalAlignment="Top" + Background="Transparent"> + <Path Margin="1,3,0,0" + Data="M 1,0 L6,0 A 2,2 90 0 1 8,2 L8,7 z" + Fill="#FFDC000C" /> + <Path Margin="1,3,0,0" + Data="M 0,0 L2,0 L 8,6 L8,8" + Fill="#ffffff" /> + </Grid> + </Border> + </Grid> + </ControlTemplate> + </Setter.Value> + </Setter> + </Style> + </Application.Resources> +</Application>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SilverlightGlimpse/SilverlightValidation/App.xaml.cs Mon Apr 23 11:06:10 2012 +0100 @@ -0,0 +1,71 @@ +using System; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Navigation; +using SilverlightGlimpse.Services; +using System.Diagnostics; + +namespace SilverlightValidation +{ + public partial class App : Application + { + public App() + { + this.Startup += this.Application_Startup; + this.Exit += this.Application_Exit; + this.UnhandledException += this.Application_UnhandledException; + + InitializeComponent(); + } + + private void Application_Startup(object sender, StartupEventArgs e) + { + string appName = "Silverlight Glimpse"; + try + { + this.RootVisual = new Views.UserListView(); + Glimpse.Service.Load(this, appName); + } + catch (Exception ex) + { + Glimpse.Service.DisplayLoadFailure(this, ex, appName); + } + } + + private void Application_Exit(object sender, EventArgs e) + { + + } + + private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e) + { + // If the app is running outside of the debugger then report the exception using + // the browser's exception mechanism. On IE this will display it a yellow alert + // icon in the status bar and Firefox will display a script error. + if (!System.Diagnostics.Debugger.IsAttached) + { + + // NOTE: This will allow the application to continue running after an exception has been thrown + // but not handled. + // For production applications this error handling should be replaced with something that will + // report the error to the website and stop the application. + e.Handled = true; + Deployment.Current.Dispatcher.BeginInvoke(delegate { ReportErrorToDOM(e); }); + } + } + + private void ReportErrorToDOM(ApplicationUnhandledExceptionEventArgs e) + { + try + { + string errorMsg = e.ExceptionObject.Message + e.ExceptionObject.StackTrace; + errorMsg = errorMsg.Replace('"', '\'').Replace("\r\n", @"\n"); + + System.Windows.Browser.HtmlPage.Window.Eval("throw new Error(\"Unhandled Error in Silverlight Application " + errorMsg + "\");"); + } + catch (Exception) + { + } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SilverlightGlimpse/SilverlightValidation/Commands/RelayCommand.cs Mon Apr 23 11:06:10 2012 +0100 @@ -0,0 +1,40 @@ +using System; +using System.Windows.Input; + +namespace SilverlightValidation.Commands +{ + public class RelayCommand : ICommand + { + public event EventHandler CanExecuteChanged = delegate { }; + + readonly Action<object> _execute; + readonly Predicate<object> _canExecute; + + public RelayCommand(Action<object> execute, + Predicate<object> canExecute = null) + { + if (execute == null) throw new ArgumentNullException("execute"); + + _execute = execute; + _canExecute = canExecute; + } + + + public void UpdateCanExecuteCommand() + { + CanExecuteChanged(this, new EventArgs()); + } + + + public bool CanExecute(object parameter) + { + return _canExecute == null || _canExecute(parameter); + } + + + public void Execute(object parameter) + { + _execute(parameter); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SilverlightGlimpse/SilverlightValidation/Data/Factory.cs Mon Apr 23 11:06:10 2012 +0100 @@ -0,0 +1,20 @@ +using System; +using SilverlightValidation.Models; + +namespace SilverlightValidation.Data +{ + public class Factory + { + public static IList<UserModel> CreateUserModels() + { + return new List<UserModel>(5) + { + new UserModel() { Username = "StevenH", Password = "Password1", Email = "steven@hotmail.com", DateOfBirth = new DateTime(1977, 09, 01), Description = ""}, + new UserModel() { Username = "RichardJ", Password = "12N456a", Email = "dicky@gmail.com", DateOfBirth = new DateTime(1983, 03, 13), Description = "Loves .Net!"}, + new UserModel() { Username = "BobbyP", Password = "pa33Word", Email = "bob@yahoo.co.uk", DateOfBirth = new DateTime(1992, 08, 30), Description = ""}, + new UserModel() { Username = "DavidM", Password = "poIu789", Email = "daveyboy@marsh.com", DateOfBirth = new DateTime(1965, 06, 21), Description = "Java fan boy"}, + new UserModel() { Username = "JessieJ", Password = "jlkJh567", Email = "jj@apple.co.uk", DateOfBirth = new DateTime(1990, 10, 15), Description = ""} + }; + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SilverlightGlimpse/SilverlightValidation/Diagrams/Overview.cd Mon Apr 23 11:06:10 2012 +0100 @@ -0,0 +1,63 @@ +<?xml version="1.0" encoding="utf-8"?> +<ClassDiagram MajorVersion="1" MinorVersion="1"> + <Class Name="SilverlightValidation.Models.UserModel"> + <Position X="2.5" Y="1.75" Width="1.5" /> + <TypeIdentifier> + <HashCode>AAAAAAAAACAgAAAAAQAAAAAAAAAQAEACAAAAAAAAABA=</HashCode> + <FileName>Models\UserModel.cs</FileName> + </TypeIdentifier> + <Lollipop Position="0.2" /> + </Class> + <Class Name="SilverlightValidation.Validators.UserModelValidator" Collapsed="true"> + <Position X="2" Y="7.75" Width="2" /> + <TypeIdentifier> + <HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAA=</HashCode> + <FileName>Validators\UserModelValidator.cs</FileName> + </TypeIdentifier> + </Class> + <Class Name="SilverlightValidation.ViewModels.UserListViewModel"> + <Position X="6.25" Y="5.5" Width="2.75" /> + <TypeIdentifier> + <HashCode>AAAAAAAAAAAAAAECAAAAAAAAAAAAABAYABEACAAAAAA=</HashCode> + <FileName>ViewModels\UserListViewModel.cs</FileName> + </TypeIdentifier> + </Class> + <Class Name="SilverlightValidation.ViewModels.UserViewModel"> + <Position X="4.25" Y="1.75" Width="1.75" /> + <TypeIdentifier> + <HashCode>UAAAoIAADCIgAAAAMYAACAAAAAAQABAKQEAAAAAgIAA=</HashCode> + <FileName>ViewModels\UserViewModel.cs</FileName> + </TypeIdentifier> + <Lollipop Position="0.2" /> + </Class> + <Class Name="SilverlightValidation.ViewModels.ViewModelBase"> + <Position X="6.25" Y="1.75" Width="2.75" /> + <TypeIdentifier> + <HashCode>AAAAAAACAABQAAABAAAAAgAAgAAAAACIAAAAAAARAAA=</HashCode> + <FileName>ViewModels\ViewModelBase.cs</FileName> + </TypeIdentifier> + <Lollipop Position="0.2" /> + </Class> + <Class Name="SilverlightValidation.Messages.UserViewResponseMessage"> + <Position X="9.25" Y="5" Width="2.25" /> + <TypeIdentifier> + <HashCode>AAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAA=</HashCode> + <FileName>Messages\UserViewResponseMessage.cs</FileName> + </TypeIdentifier> + </Class> + <Interface Name="SilverlightValidation.Interfaces.ICloneable<T>"> + <Position X="2.5" Y="4.5" Width="1.5" /> + <TypeIdentifier> + <HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABA=</HashCode> + <FileName>Interfaces\ICloneable.cs</FileName> + </TypeIdentifier> + </Interface> + <Interface Name="SilverlightValidation.Interfaces.IUserModel"> + <Position X="2.5" Y="5.75" Width="1.5" /> + <TypeIdentifier> + <HashCode>AAAAAAAAACAgAAAAAQAAAAAAAAAQAAACAAAAAAAAAAA=</HashCode> + <FileName>Interfaces\IUserModel.cs</FileName> + </TypeIdentifier> + </Interface> + <Font Name="Segoe UI" Size="9" /> +</ClassDiagram> \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SilverlightGlimpse/SilverlightValidation/Interfaces/ICloneable.cs Mon Apr 23 11:06:10 2012 +0100 @@ -0,0 +1,7 @@ +namespace SilverlightValidation.Interfaces +{ + public interface ICloneable<T> + { + T Clone(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SilverlightGlimpse/SilverlightValidation/Interfaces/IUserModel.cs Mon Apr 23 11:06:10 2012 +0100 @@ -0,0 +1,12 @@ +using System; +namespace SilverlightValidation.Interfaces +{ + public interface IUserModel + { + string Username { get; set; } + string Email { get; set; } + string Password { get; set; } + DateTime? DateOfBirth { get; set; } + string Description { get; set; } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SilverlightGlimpse/SilverlightValidation/Messages/UserViewResponseMessage.cs Mon Apr 23 11:06:10 2012 +0100 @@ -0,0 +1,10 @@ +using GalaSoft.MvvmLight.Messaging; +using SilverlightValidation.ViewModels; + +namespace SilverlightValidation.Messages +{ + public class UserViewResponseMessage : MessageBase + { + public UserViewModel UserViewModel { get; set; } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SilverlightGlimpse/SilverlightValidation/Models/UserModel.cs Mon Apr 23 11:06:10 2012 +0100 @@ -0,0 +1,25 @@ +using System; +using System.ComponentModel; +using SilverlightValidation.Interfaces; + +namespace SilverlightValidation.Models +{ + public class UserModel : IUserModel, ICloneable<UserModel> + { + public string Username { get; set; } + public string Email { get; set; } + public string Password { get; set; } + public DateTime? DateOfBirth { get; set; } + public string Description { get; set; } + + public static UserModel Create() + { + return new UserModel() { Username = "", Email = "", Password = "", DateOfBirth = null, Description = "" }; + } + + public UserModel Clone() + { + return (UserModel) this.MemberwiseClone(); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SilverlightGlimpse/SilverlightValidation/Properties/AppManifest.xml Mon Apr 23 11:06:10 2012 +0100 @@ -0,0 +1,6 @@ +<Deployment xmlns="http://schemas.microsoft.com/client/2007/deployment" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" +> + <Deployment.Parts> + </Deployment.Parts> +</Deployment>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SilverlightGlimpse/SilverlightValidation/Properties/AssemblyInfo.cs Mon Apr 23 11:06:10 2012 +0100 @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("SilverlightValidation")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("SilverlightValidation")] +[assembly: AssemblyCopyright("Copyright © 2012")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("3f5a4c47-8fbd-4568-8728-e26ee6a51945")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SilverlightGlimpse/SilverlightValidation/SilverlightValidation.csproj Mon Apr 23 11:06:10 2012 +0100 @@ -0,0 +1,150 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProductVersion>8.0.50727</ProductVersion> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{0C1CC1FC-915A-4428-8952-CDC79EABC3F4}</ProjectGuid> + <ProjectTypeGuids>{A1591282-1198-4647-A2B1-27E5FF5F6F3B};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids> + <OutputType>Library</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>SilverlightValidation</RootNamespace> + <AssemblyName>SilverlightValidation</AssemblyName> + <TargetFrameworkIdentifier>Silverlight</TargetFrameworkIdentifier> + <TargetFrameworkVersion>v5.0</TargetFrameworkVersion> + <SilverlightVersion>$(TargetFrameworkVersion)</SilverlightVersion> + <SilverlightApplication>true</SilverlightApplication> + <SupportedCultures> + </SupportedCultures> + <XapOutputs>true</XapOutputs> + <GenerateSilverlightManifest>true</GenerateSilverlightManifest> + <XapFilename>SilverlightValidation.xap</XapFilename> + <SilverlightManifestTemplate>Properties\AppManifest.xml</SilverlightManifestTemplate> + <SilverlightAppEntry>SilverlightValidation.App</SilverlightAppEntry> + <TestPageFileName>SilverlightValidationTestPage.html</TestPageFileName> + <CreateTestPage>true</CreateTestPage> + <ValidateXaml>true</ValidateXaml> + <EnableOutOfBrowser>false</EnableOutOfBrowser> + <OutOfBrowserSettingsFile>Properties\OutOfBrowserSettings.xml</OutOfBrowserSettingsFile> + <UsePlatformExtensions>false</UsePlatformExtensions> + <ThrowErrorsInValidation>true</ThrowErrorsInValidation> + <LinkedServerProject> + </LinkedServerProject> + </PropertyGroup> + <!-- This property group is only here to support building this project using the + MSBuild 3.5 toolset. In order to work correctly with this older toolset, it needs + to set the TargetFrameworkVersion to v3.5 --> + <PropertyGroup Condition="'$(MSBuildToolsVersion)' == '3.5'"> + <TargetFrameworkVersion>v3.5</TargetFrameworkVersion> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>Bin\Debug</OutputPath> + <DefineConstants>DEBUG;TRACE;SILVERLIGHT</DefineConstants> + <NoStdLib>true</NoStdLib> + <NoConfig>true</NoConfig> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <DebugType>pdbonly</DebugType> + <Optimize>true</Optimize> + <OutputPath>Bin\Release</OutputPath> + <DefineConstants>TRACE;SILVERLIGHT</DefineConstants> + <NoStdLib>true</NoStdLib> + <NoConfig>true</NoConfig> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <ItemGroup> + <Reference Include="FluentValidation"> + <HintPath>..\Libs\FluentValidation.dll</HintPath> + </Reference> + <Reference Include="GalaSoft.MvvmLight.SL5, Version=4.0.21.32885, Culture=neutral, PublicKeyToken=c114982fcf1a3a2e, processorArchitecture=MSIL"> + <SpecificVersion>False</SpecificVersion> + <HintPath>..\Libs\GalaSoft.MvvmLight.SL5.dll</HintPath> + </Reference> + <Reference Include="mscorlib" /> + <Reference Include="System.Windows" /> + <Reference Include="system" /> + <Reference Include="System.Core" /> + <Reference Include="System.Windows.Controls, Version=5.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> + <HintPath>..\Libs\System.Windows.Controls.dll</HintPath> + </Reference> + <Reference Include="System.Windows.Controls.Data, Version=5.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> + <HintPath>..\Libs\System.Windows.Controls.Data.dll</HintPath> + </Reference> + <Reference Include="System.Windows.Controls.Data.Input, Version=5.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> + <HintPath>..\Libs\System.Windows.Controls.Data.Input.dll</HintPath> + </Reference> + <Reference Include="System.Windows.Controls.Navigation, Version=5.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> + <HintPath>..\Libs\System.Windows.Controls.Navigation.dll</HintPath> + </Reference> + <Reference Include="System.Xml" /> + <Reference Include="System.Windows.Browser" /> + </ItemGroup> + <ItemGroup> + <Compile Include="App.xaml.cs"> + <DependentUpon>App.xaml</DependentUpon> + </Compile> + <Compile Include="Data\Factory.cs" /> + <Compile Include="Interfaces\ICloneable.cs" /> + <Compile Include="Interfaces\IUserModel.cs" /> + <Compile Include="Messages\UserViewResponseMessage.cs" /> + <Compile Include="Properties\AssemblyInfo.cs" /> + <Compile Include="Commands\RelayCommand.cs" /> + <Compile Include="ViewModels\UserListViewModel.cs" /> + <Compile Include="Models\UserModel.cs" /> + <Compile Include="Validators\UserModelValidator.cs" /> + <Compile Include="Views\UserListView.xaml.cs"> + <DependentUpon>UserListView.xaml</DependentUpon> + </Compile> + <Compile Include="Views\UserView.xaml.cs"> + <DependentUpon>UserView.xaml</DependentUpon> + </Compile> + <Compile Include="ViewModels\UserViewModel.cs" /> + <Compile Include="ViewModels\ViewModelBase.cs" /> + </ItemGroup> + <ItemGroup> + <ApplicationDefinition Include="App.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:Compile</Generator> + </ApplicationDefinition> + <Page Include="Views\UserListView.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:Compile</Generator> + </Page> + <Page Include="Views\UserView.xaml"> + <Generator>MSBuild:Compile</Generator> + <SubType>Designer</SubType> + </Page> + </ItemGroup> + <ItemGroup> + <None Include="Diagrams\Overview.cd" /> + <None Include="Properties\AppManifest.xml" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\SilverlightGlimpse\SilverlightGlimpse.csproj"> + <Project>{bb51026b-2864-4389-aaca-0bbdf1926e46}</Project> + <Name>SilverlightGlimpse</Name> + </ProjectReference> + </ItemGroup> + <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Silverlight\$(SilverlightVersion)\Microsoft.Silverlight.CSharp.targets" /> + <!-- To modify your build process, add your task inside one of the targets below and uncomment it. + Other similar extension points exist, see Microsoft.Common.targets. + <Target Name="BeforeBuild"> + </Target> + <Target Name="AfterBuild"> + </Target> + --> + <ProjectExtensions> + <VisualStudio> + <FlavorProperties GUID="{A1591282-1198-4647-A2B1-27E5FF5F6F3B}"> + <SilverlightProjectProperties /> + </FlavorProperties> + </VisualStudio> + </ProjectExtensions> +</Project> \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SilverlightGlimpse/SilverlightValidation/Validators/UserModelValidator.cs Mon Apr 23 11:06:10 2012 +0100 @@ -0,0 +1,36 @@ +using System; +using FluentValidation; +using SilverlightValidation.Interfaces; + +namespace SilverlightValidation.Validators +{ + public class UserModelValidator : AbstractValidator<IUserModel> + { + public UserModelValidator() + { + RuleFor(x => x.Username) + .Length(3, 8) + .WithMessage("Must be between 3-8 characters."); + + RuleFor(x => x.Password) + .Matches(@"^\w*(?=\w*\d)(?=\w*[a-z])(?=\w*[A-Z])\w*$") + .WithMessage("Must contain lower, upper and numeric chars."); + + RuleFor(x => x.Email) + .EmailAddress() + .WithMessage("A valid email address is required."); + + RuleFor(x => x.DateOfBirth) + .Must(BeAValidDateOfBirth) + .WithMessage("Must be within 100 years of today."); + } + + private bool BeAValidDateOfBirth(DateTime? dateOfBirth) + { + if (dateOfBirth == null) return false; + if (dateOfBirth.Value > DateTime.Today || dateOfBirth < DateTime.Today.AddYears(-100)) + return false; + return true; + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SilverlightGlimpse/SilverlightValidation/ViewModels/UserListViewModel.cs Mon Apr 23 11:06:10 2012 +0100 @@ -0,0 +1,63 @@ +using System.Collections.ObjectModel; +using System.Windows.Input; +using SilverlightValidation.Commands; +using SilverlightValidation.Models; +using SilverlightValidation.Validators; +using SilverlightValidation.Views; +using GalaSoft.MvvmLight.Messaging; +using SilverlightValidation.Messages; + +namespace SilverlightValidation.ViewModels +{ + public class UserListViewModel + { + UserView window; + + public UserListViewModel(IList<UserModel> models, UserModelValidator validator) + { + Data = new ObservableCollection<UserViewModel>(); + + foreach (var model in models) + Data.Add(new UserViewModel(model, validator)); + + AddCommand = new RelayCommand(AddCommandExecute); + DeleteCommand = new RelayCommand(DeleteCommandExecute); + + Messenger.Default.Register<UserViewResponseMessage>(this, UserViewResponseMessageReceived); + } + + private void UserViewResponseMessageReceived(UserViewResponseMessage userViewResponseMessage) + { + if (userViewResponseMessage.UserViewModel != null) + Data.Add(userViewResponseMessage.UserViewModel); + window.Close(); + } + + #region Properties + + public ObservableCollection<UserViewModel> Data { get; set; } + + public UserViewModel SelectedItem { get; set; } + + #endregion + + #region Commands + + public ICommand AddCommand { get; set; } + public ICommand DeleteCommand { get; set; } + + private void AddCommandExecute(object obj) + { + window = new UserView(); + window.Show(); + } + + private void DeleteCommandExecute(object obj) + { + if (SelectedItem!=null) + Data.Remove(SelectedItem); + } + + #endregion + } +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SilverlightGlimpse/SilverlightValidation/ViewModels/UserViewModel.cs Mon Apr 23 11:06:10 2012 +0100 @@ -0,0 +1,223 @@ +using System; +using System.ComponentModel; +using System.Linq; +using System.Windows; +using System.Windows.Input; +using FluentValidation; +using SilverlightValidation.Interfaces; +using SilverlightValidation.Validators; +using SilverlightValidation.Models; +using SilverlightValidation.Commands; +using GalaSoft.MvvmLight.Messaging; +using SilverlightValidation.Messages; + +namespace SilverlightValidation.ViewModels +{ + public class UserViewModel : ViewModelBase, IUserModel, IEditableObject + { + #region Fields + + private readonly UserModelValidator _validator; + private UserModel _data; + private UserModel _backup; + + #endregion + + #region Constructor + + public UserViewModel(UserModel model, UserModelValidator validator) + { + _validator = validator; + _data = model; + _backup = model.Clone(); + + OkCommand = new RelayCommand(OkCommandExecute); + CancelCommand = new RelayCommand(CancelCommandExecute); + } + + #endregion + + #region Methods + + private void SetProperties(IUserModel source) + { + _data.Username = source.Username; + _data.Password = source.Password; + _data.Email = source.Email; + _data.DateOfBirth = source.DateOfBirth; + _data.Description = source.Description; + } + + #endregion + + #region Properties + + private const string UsernameProperty = "Username"; + public string Username + { + get { return _data.Username; } + set + { + if (_data.Username != value) + { + _data.Username = value; + RaisePropertyChanged(UsernameProperty); + IsChanged = true; + } + + ClearError(UsernameProperty); + var validationResult = _validator.Validate(this, UsernameProperty); + if (!validationResult.IsValid) + validationResult.Errors.ToList().ForEach(x => SetError(UsernameProperty, x.ErrorMessage)); + } + } + + private const string PasswordProperty = "Password"; + public string Password + { + get { return _data.Password; } + set + { + if (_data.Password != value) + { + _data.Password = value; + RaisePropertyChanged(PasswordProperty); + IsChanged = true; + } + + ClearError(PasswordProperty); + var validationResult = _validator.Validate(this, PasswordProperty); + if (!validationResult.IsValid) + validationResult.Errors.ToList().ForEach(x => SetError(PasswordProperty, x.ErrorMessage)); + } + } + + private const string EmailProperty = "Email"; + public string Email + { + get { return _data.Email; } + set + { + if (_data.Email != value) + { + _data.Email = value; + RaisePropertyChanged(EmailProperty); + IsChanged = true; + } + + ClearError(EmailProperty); + var validationResult = _validator.Validate(this, EmailProperty); + if (!validationResult.IsValid) + validationResult.Errors.ToList().ForEach(x => SetError(EmailProperty, x.ErrorMessage)); + } + } + + private const string DateOfBirthProperty = "DateOfBirth"; + public DateTime? DateOfBirth + { + get { return _data.DateOfBirth; } + set + { + if (_data.DateOfBirth != value) + { + _data.DateOfBirth = value; + RaisePropertyChanged(DateOfBirthProperty); + IsChanged = true; + } + + ClearError(DateOfBirthProperty); + var validationResult = _validator.Validate(this, DateOfBirthProperty); + if (!validationResult.IsValid) + validationResult.Errors.ToList().ForEach(x => SetError(DateOfBirthProperty, x.ErrorMessage)); + } + } + + private const string DescriptionProperty = "Description"; + public string Description + { + get { return _data.Description; } + set + { + if (_data.Description != value) + { + _data.Description = value; + RaisePropertyChanged(DescriptionProperty); + IsChanged = true; + } + + ClearError(DescriptionProperty); + var validationResult = _validator.Validate(this, DescriptionProperty); + if (!validationResult.IsValid) + validationResult.Errors.ToList().ForEach(x => SetError(DescriptionProperty, x.ErrorMessage)); + } + } + + #endregion + + #region Commands + + public ICommand OkCommand { get; set; } + public ICommand CancelCommand { get; set; } + + private void OkCommandExecute(object obj) + { + RefreshToViewErrors(); + + if (IsChanged && !HasErrors) + { + // save here + Messenger.Default.Send<UserViewResponseMessage>( + new UserViewResponseMessage() { UserViewModel = this }); + } + } + + // in case user hasn't touched the form + private void RefreshToViewErrors() + { + Username = _data.Username; + Password = _data.Password; + Email = _data.Email; + DateOfBirth = _data.DateOfBirth; + } + + private void CancelCommandExecute(object obj) + { + Messenger.Default.Send<UserViewResponseMessage>( + new UserViewResponseMessage() { UserViewModel = null }); + } + + #endregion + + private void ResetFormData() + { + SetProperties(_backup); + ClearAllErrors(); + IsChanged = false; + } + + public bool IsChanged { get; private set; } + + #region IEditableObject for datagrid + + private bool inEdit; + public void BeginEdit() + { + if (inEdit) return; + inEdit = true; + } + + public void CancelEdit() + { + if (!inEdit) return; + inEdit = false; + ResetFormData(); + } + + public void EndEdit() + { + if (!inEdit) return; + } + + #endregion + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SilverlightGlimpse/SilverlightValidation/ViewModels/ViewModelBase.cs Mon Apr 23 11:06:10 2012 +0100 @@ -0,0 +1,72 @@ +using System; +using System.Collections; +using System.ComponentModel; +using System.Linq; + +namespace SilverlightValidation.ViewModels +{ + public class ViewModelBase : INotifyPropertyChanged, INotifyDataErrorInfo + { + #region INotifyPropertyChanged method plus event + + public event PropertyChangedEventHandler PropertyChanged = delegate { }; + + protected void RaisePropertyChanged(string propertyName) + { + PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + } + + #endregion + + #region INotifyDataErrorInfo methods and helpers + + private readonly Dictionary<string, List<string>> _errors = new Dictionary<string, List<string>>(); + + public void SetError(string propertyName, string errorMessage) + { + if (!_errors.ContainsKey(propertyName)) + _errors.Add(propertyName, new List<string> { errorMessage }); + + RaiseErrorsChanged(propertyName); + } + + protected void ClearError(string propertyName) + { + if (_errors.ContainsKey(propertyName)) + { + _errors.Remove(propertyName); + RaiseErrorsChanged(propertyName); + } + } + + protected void ClearAllErrors() + { + var errors = _errors.Select(error => error.Key).ToList(); + + foreach (var propertyName in errors) + ClearError(propertyName); + } + + public void RaiseErrorsChanged(string propertyName) + { + ErrorsChanged(this, new DataErrorsChangedEventArgs(propertyName)); + } + + public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged = delegate { }; + + public IEnumerable GetErrors(string propertyName) + { + if (propertyName == null) return null; + return _errors.ContainsKey(propertyName) + ? _errors[propertyName] + : null; + } + + public bool HasErrors + { + get { return _errors.Count > 0; } + } + + #endregion + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SilverlightGlimpse/SilverlightValidation/Views/UserListView.xaml Mon Apr 23 11:06:10 2012 +0100 @@ -0,0 +1,82 @@ +<UserControl x:Class="SilverlightValidation.Views.UserListView" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" + d:DesignHeight="400" + d:DesignWidth="725" + mc:Ignorable="d"> + + <Grid x:Name="LayoutRoot"> + <Grid.RowDefinitions> + <RowDefinition Height="auto" /> + <RowDefinition Height="40" /> + <RowDefinition Height="300" /> + </Grid.RowDefinitions> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="auto" /> + <ColumnDefinition Width="725" /> + <ColumnDefinition Width="*" /> + </Grid.ColumnDefinitions> + + <StackPanel Grid.Row="1" + Grid.Column="1" + HorizontalAlignment="Right" + Orientation="Horizontal"> + <Button Width="60" + Command="{Binding AddCommand}" + Content="Add" + Style="{StaticResource ButtonStyle}" /> + <Button Width="60" + Command="{Binding DeleteCommand}" + Content="Delete" + Style="{StaticResource ButtonStyle}" /> + </StackPanel> + + <controls:DataGrid Grid.Row="2" + Grid.Column="1" + AutoGenerateColumns="False" + ItemsSource="{Binding Data}" + SelectedItem="{Binding SelectedItem, + Mode=TwoWay}" + SelectionMode="Single"> + <controls:DataGrid.Columns> + <controls:DataGridTextColumn Width="125" + Binding="{Binding Username, + Mode=TwoWay, + ValidatesOnNotifyDataErrors=True, + NotifyOnValidationError=True}" + Header="Username" /> + <controls:DataGridTemplateColumn Width="125" Header="Password"> + <sdk:DataGridTemplateColumn.CellTemplate> + <DataTemplate> + <PasswordBox Password="{Binding Password, Mode=TwoWay, ValidatesOnNotifyDataErrors=True, NotifyOnValidationError=True}" /> + </DataTemplate> + </sdk:DataGridTemplateColumn.CellTemplate> + </controls:DataGridTemplateColumn> + <controls:DataGridTextColumn Width="150" + Binding="{Binding Email, + Mode=TwoWay, + ValidatesOnNotifyDataErrors=True, + NotifyOnValidationError=True}" + Header="Email" /> + + <controls:DataGridTemplateColumn Width="150" Header="Date of Birth"> + <sdk:DataGridTemplateColumn.CellTemplate> + <DataTemplate> + <sdk:DatePicker KeyDown="DatePicker_KeyDown" SelectedDate="{Binding DateOfBirth, Mode=TwoWay, ValidatesOnNotifyDataErrors=True, NotifyOnValidationError=True}" /> + </DataTemplate> + </sdk:DataGridTemplateColumn.CellTemplate> + </controls:DataGridTemplateColumn> + <controls:DataGridTextColumn Width="150" + Binding="{Binding Description, + Mode=TwoWay, + ValidatesOnNotifyDataErrors=True, + NotifyOnValidationError=True}" + Header="Description" /> + </controls:DataGrid.Columns> + </controls:DataGrid> + </Grid> +</UserControl>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SilverlightGlimpse/SilverlightValidation/Views/UserListView.xaml.cs Mon Apr 23 11:06:10 2012 +0100 @@ -0,0 +1,28 @@ +using System.Windows.Browser; +using System.Windows.Input; +using SilverlightValidation.Data; +using SilverlightValidation.ViewModels; +using SilverlightValidation.Validators; + +namespace SilverlightValidation.Views +{ + public partial class UserListView + { + private UserListViewModel vm; + + public UserListView() + { + InitializeComponent(); + HtmlPage.Document.SetProperty("title", "Silverlight Validation"); + + vm = new UserListViewModel(Factory.CreateUserModels(), new UserModelValidator()); + this.DataContext = vm; + } + + private void DatePicker_KeyDown(object sender, KeyEventArgs e) + { + if (e.Key != Key.Tab) + e.Handled = true; + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SilverlightGlimpse/SilverlightValidation/Views/UserView.xaml Mon Apr 23 11:06:10 2012 +0100 @@ -0,0 +1,142 @@ +<c:ChildWindow x:Class="SilverlightValidation.Views.UserView" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:c="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:p="clr-namespace:System.Windows.Controls.Primitives;assembly=System.Windows.Controls" + xmlns:s="clr-namespace:System;assembly=mscorlib" + xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" + Title="Add User" + Width="500" + Height="400"> + + <Grid x:Name="LayoutRoot" Background="White"> + + <Grid.RowDefinitions> + <RowDefinition Height="30" /> + <RowDefinition Height="30" /> + <RowDefinition Height="30" /> + <RowDefinition Height="30" /> + <RowDefinition Height="30" /> + <RowDefinition Height="30" /> + <RowDefinition Height="50" /> + <RowDefinition Height="120" /> + </Grid.RowDefinitions> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="30" /> + <ColumnDefinition Width="100" /> + <ColumnDefinition Width="300" /> + <ColumnDefinition Width="30" /> + <ColumnDefinition Width="30" /> + </Grid.ColumnDefinitions> + + <TextBlock Grid.Row="1" + Grid.Column="1" + Style="{StaticResource LabelStyle}" + Text="Username:" /> + + <TextBox x:Name="tbUsername" + Grid.Row="1" + Grid.Column="2" + Style="{StaticResource TextBoxStyle}" + Text="{Binding Username, + Mode=TwoWay, + ValidatesOnNotifyDataErrors=True, + NotifyOnValidationError=True}" /> + + <sdk:DescriptionViewer Grid.Row="1" + Grid.Column="3" + Width="20" + Description="Required" + Target="{Binding ElementName=tbUsername}" /> + + <TextBlock Grid.Row="2" + Grid.Column="1" + Style="{StaticResource LabelStyle}" + Text="Password:" /> + + <PasswordBox x:Name="tbPassword" + Grid.Row="2" + Grid.Column="2" + Password="{Binding Password, + Mode=TwoWay, + ValidatesOnNotifyDataErrors=True, + NotifyOnValidationError=True}" + Style="{StaticResource PasswordBoxStyle}" /> + + <sdk:DescriptionViewer Grid.Row="2" + Grid.Column="3" + Width="20" + Description="Required" + Target="{Binding ElementName=tbPassword}" /> + + <TextBlock Grid.Row="3" + Grid.Column="1" + Style="{StaticResource LabelStyle}" + Text="Email:" /> + + <TextBox x:Name="tbEmail" + Grid.Row="3" + Grid.Column="2" + Style="{StaticResource TextBoxStyle}" + Text="{Binding Email, + Mode=TwoWay, + ValidatesOnNotifyDataErrors=True, + NotifyOnValidationError=True}" /> + + <sdk:DescriptionViewer Grid.Row="3" + Grid.Column="3" + Width="20" + Description="Required" + Target="{Binding ElementName=tbEmail}" /> + + <TextBlock Grid.Row="4" + Grid.Column="1" + Style="{StaticResource LabelStyle}" + Text="Date of Birth:" /> + + <sdk:DatePicker x:Name="dpDateOfBirth" + Grid.Row="4" + Grid.Column="2" + KeyDown="DatePicker_KeyDown" + SelectedDate="{Binding DateOfBirth, + Mode=TwoWay, + ValidatesOnNotifyDataErrors=True, + NotifyOnValidationError=True}" + Style="{StaticResource DatePickerStyle}" /> + <sdk:DescriptionViewer Grid.Row="4" + Grid.Column="3" + Width="20" + Description="Required" + Target="{Binding ElementName=dpDateOfBirth}" /> + + <TextBlock x:Name="tbDescription" + Grid.Row="5" + Grid.Column="1" + Style="{StaticResource LabelStyle}" + Text="Description:" /> + + <TextBox Grid.Row="5" + Grid.Column="2" + Style="{StaticResource TextBoxStyle}" + Text="{Binding Description}" /> + <StackPanel Grid.Row="6" + Grid.Column="2" + HorizontalAlignment="Right" + Orientation="Horizontal"> + <Button Command="{Binding OkCommand}" + Content="OK" + Style="{StaticResource ButtonStyle}" /> + <Button Command="{Binding CancelCommand}" + Content="Cancel" + Style="{StaticResource ButtonStyle}" /> + </StackPanel> + + <sdk:ValidationSummary Grid.Row="7" + Grid.Column="1" + Grid.ColumnSpan="2" + Style="{StaticResource ValidationSummaryStyle}" /> + + </Grid> +</c:ChildWindow> \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SilverlightGlimpse/SilverlightValidation/Views/UserView.xaml.cs Mon Apr 23 11:06:10 2012 +0100 @@ -0,0 +1,28 @@ +using System.Windows.Browser; +using System.Windows.Input; +using SilverlightValidation.Models; +using SilverlightValidation.Validators; +using SilverlightValidation.ViewModels; + +namespace SilverlightValidation.Views +{ + public partial class UserView + { + private UserViewModel vm; + + public UserView() + { + InitializeComponent(); + HtmlPage.Document.SetProperty("title", "Silverlight Validation"); + + vm = new UserViewModel(UserModel.Create(), new UserModelValidator()); + this.DataContext = vm; + } + + private void DatePicker_KeyDown(object sender, KeyEventArgs e) + { + if (e.Key != Key.Tab) + e.Handled = true; + } + } +} \ No newline at end of file