2011-03-28 21:22:11 +03:00
parent a4c09735f0
commit 00f97e41d6
130 changed files with 13440 additions and 0 deletions
@@ -0,0 +1,19 @@
<UserControl x:Class="WindowsPhone.Recipes.Push.Client.Controls.NotificationBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
d:DesignHeight="189" d:DesignWidth="480">
<StackPanel Background="Black">
<TextBlock Margin="4" Text="{Binding Title}" />
<TextBlock Margin="4" Text="{Binding Message}" TextWrapping="Wrap" />
<CheckBox IsChecked="{Binding ShowAgain, Mode=TwoWay}" Content="Show this message again" />
<Button Margin="4" HorizontalAlignment="Right" Width="200" Content="OK" Click="buttonOk_Click" />
</StackPanel>
</UserControl>
@@ -0,0 +1,91 @@
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.IO.IsolatedStorage;
using System.Windows.Controls.Primitives;
using Microsoft.Phone.Controls;
namespace WindowsPhone.Recipes.Push.Client.Controls
{
public partial class NotificationBox : UserControl
{
#region Fields
private readonly IsolatedStorageSettings Settings = IsolatedStorageSettings.ApplicationSettings;
private static Popup _popup;
#endregion
public string Title { get; set; }
public string Message { get; set; }
public bool ShowAgain
{
get
{
bool showAgain;
if (!Settings.TryGetValue("NotificationBox.ShowAgain", out showAgain))
{
showAgain = true;
ShowAgain = showAgain;
}
return showAgain;
}
set
{
Settings["NotificationBox.ShowAgain"] = value;
}
}
private NotificationBox()
{
DataContext = this;
InitializeComponent();
}
public static void Show(string title, string message)
{
if (_popup != null)
{
return;
}
var root = Application.Current.RootVisual as PhoneApplicationFrame;
var notificationBox = new NotificationBox
{
Title = title,
Message = message,
Width = root.ActualWidth,
MaxHeight = root.ActualHeight,
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center
};
if (!notificationBox.ShowAgain)
return;
_popup = new Popup
{
Child = notificationBox,
IsOpen = true,
};
}
private void buttonOk_Click(object sender, RoutedEventArgs e)
{
_popup.IsOpen = false;
_popup = null;
}
}
}
@@ -0,0 +1,61 @@
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Data;
using System.Globalization;
namespace WindowsPhone.Recipes.Push.Client.Controls
{
public sealed class BooleanToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var flag = false;
if (value is bool)
{
flag = (bool)value;
}
else if (value is bool?)
{
var nullable = (bool?)value;
flag = nullable.GetValueOrDefault();
}
if (parameter != null)
{
if (bool.Parse((string)parameter))
{
flag = !flag;
}
}
if (flag)
{
return Visibility.Visible;
}
else
{
return Visibility.Collapsed;
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
var back = ((value is Visibility) && (((Visibility)value) == Visibility.Visible));
if (parameter != null)
{
if ((bool)parameter)
{
back = !back;
}
}
return back;
}
}
}
@@ -0,0 +1,161 @@
<UserControl x:Class="WindowsPhone.Recipes.Push.Client.Controls.ProgressBarWithText"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:localHelpers="clr-namespace:WindowsPhone.Recipes.Push.Client.Controls"
xmlns:unsupported="clr-namespace:WindowsPhone.Recipes.Push.Client.Controls"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
d:DesignHeight="480" d:DesignWidth="480"
>
<UserControl.Resources>
<localHelpers:BooleanToVisibilityConverter x:Key="booleanToVisibilityConverter" />
<Style x:Key="PerformanceProgressBar" TargetType="ProgressBar">
<Setter Property="Foreground" Value="{StaticResource PhoneAccentBrush}"/>
<Setter Property="Background" Value="{StaticResource PhoneAccentBrush}"/>
<Setter Property="Maximum" Value="100"/>
<Setter Property="IsHitTestVisible" Value="False"/>
<Setter Property="Padding" Value="{StaticResource PhoneHorizontalMargin}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ProgressBar">
<unsupported:RelativeAnimatingContentControl HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch">
<unsupported:RelativeAnimatingContentControl.Resources>
<ExponentialEase EasingMode="EaseOut" Exponent="1" x:Key="ProgressBarEaseOut"/>
<ExponentialEase EasingMode="EaseOut" Exponent="1" x:Key="ProgressBarEaseIn"/>
</unsupported:RelativeAnimatingContentControl.Resources>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Determinate"/>
<VisualState x:Name="Indeterminate">
<Storyboard RepeatBehavior="Forever" Duration="00:00:04.4">
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="IndeterminateRoot">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="DeterminateRoot">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Collapsed</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00.0" Storyboard.TargetProperty="X" Storyboard.TargetName="R1TT">
<LinearDoubleKeyFrame KeyTime="00:00:00.0" Value="0.1"/>
<EasingDoubleKeyFrame KeyTime="00:00:00.5" Value="33.1" EasingFunction="{StaticResource ProgressBarEaseOut}"/>
<LinearDoubleKeyFrame KeyTime="00:00:02.0" Value="66.1"/>
<EasingDoubleKeyFrame KeyTime="00:00:02.5" Value="100.1" EasingFunction="{StaticResource ProgressBarEaseIn}"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00.2" Storyboard.TargetProperty="X" Storyboard.TargetName="R2TT">
<LinearDoubleKeyFrame KeyTime="00:00:00.0" Value="0.1"/>
<EasingDoubleKeyFrame KeyTime="00:00:00.5" Value="33.1" EasingFunction="{StaticResource ProgressBarEaseOut}"/>
<LinearDoubleKeyFrame KeyTime="00:00:02.0" Value="66.1"/>
<EasingDoubleKeyFrame KeyTime="00:00:02.5" Value="100.1" EasingFunction="{StaticResource ProgressBarEaseIn}"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00.4" Storyboard.TargetProperty="X" Storyboard.TargetName="R3TT">
<LinearDoubleKeyFrame KeyTime="00:00:00.0" Value="0.1"/>
<EasingDoubleKeyFrame KeyTime="00:00:00.5" Value="33.1" EasingFunction="{StaticResource ProgressBarEaseOut}"/>
<LinearDoubleKeyFrame KeyTime="00:00:02.0" Value="66.1"/>
<EasingDoubleKeyFrame KeyTime="00:00:02.5" Value="100.1" EasingFunction="{StaticResource ProgressBarEaseIn}"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00.6" Storyboard.TargetProperty="X" Storyboard.TargetName="R4TT">
<LinearDoubleKeyFrame KeyTime="00:00:00.0" Value="0.1"/>
<EasingDoubleKeyFrame KeyTime="00:00:00.5" Value="33.1" EasingFunction="{StaticResource ProgressBarEaseOut}"/>
<LinearDoubleKeyFrame KeyTime="00:00:02.0" Value="66.1"/>
<EasingDoubleKeyFrame KeyTime="00:00:02.5" Value="100.1" EasingFunction="{StaticResource ProgressBarEaseIn}"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00.8" Storyboard.TargetProperty="X" Storyboard.TargetName="R5TT">
<LinearDoubleKeyFrame KeyTime="00:00:00.0" Value="0.1"/>
<EasingDoubleKeyFrame KeyTime="00:00:00.5" Value="33.1" EasingFunction="{StaticResource ProgressBarEaseOut}"/>
<LinearDoubleKeyFrame KeyTime="00:00:02.0" Value="66.1"/>
<EasingDoubleKeyFrame KeyTime="00:00:02.5" Value="100.1" EasingFunction="{StaticResource ProgressBarEaseIn}"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00.0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="R1">
<DiscreteDoubleKeyFrame KeyTime="0" Value="1"/>
<DiscreteDoubleKeyFrame KeyTime="00:00:02.5" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00.2" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="R2">
<DiscreteDoubleKeyFrame KeyTime="0" Value="1"/>
<DiscreteDoubleKeyFrame KeyTime="00:00:02.5" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00.4" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="R3">
<DiscreteDoubleKeyFrame KeyTime="0" Value="1"/>
<DiscreteDoubleKeyFrame KeyTime="00:00:02.5" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00.6" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="R4">
<DiscreteDoubleKeyFrame KeyTime="0" Value="1"/>
<DiscreteDoubleKeyFrame KeyTime="00:00:02.5" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00.8" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="R5">
<DiscreteDoubleKeyFrame KeyTime="0" Value="1"/>
<DiscreteDoubleKeyFrame KeyTime="00:00:02.5" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid>
<Grid x:Name="DeterminateRoot" Margin="{TemplateBinding Padding}" Visibility="Visible">
<Rectangle x:Name="ProgressBarTrack" Fill="{TemplateBinding Background}" Height="4" Opacity="0.1"/>
<Rectangle x:Name="ProgressBarIndicator" Fill="{TemplateBinding Foreground}" HorizontalAlignment="Left" Height="4"/>
</Grid>
<Border x:Name="IndeterminateRoot" Margin="{TemplateBinding Padding}" Visibility="Collapsed">
<Grid HorizontalAlignment="Left">
<Rectangle Fill="{TemplateBinding Foreground}" Height="4" IsHitTestVisible="False" Width="4" x:Name="R1" Opacity="0" CacheMode="BitmapCache">
<Rectangle.RenderTransform>
<TranslateTransform x:Name="R1TT"/>
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle Fill="{TemplateBinding Foreground}" Height="4" IsHitTestVisible="False" Width="4" x:Name="R2" Opacity="0" CacheMode="BitmapCache">
<Rectangle.RenderTransform>
<TranslateTransform x:Name="R2TT"/>
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle Fill="{TemplateBinding Foreground}" Height="4" IsHitTestVisible="False" Width="4" x:Name="R3" Opacity="0" CacheMode="BitmapCache">
<Rectangle.RenderTransform>
<TranslateTransform x:Name="R3TT"/>
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle Fill="{TemplateBinding Foreground}" Height="4" IsHitTestVisible="False" Width="4" x:Name="R4" Opacity="0" CacheMode="BitmapCache">
<Rectangle.RenderTransform>
<TranslateTransform x:Name="R4TT"/>
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle Fill="{TemplateBinding Foreground}" Height="4" IsHitTestVisible="False" Width="4" x:Name="R5" Opacity="0" CacheMode="BitmapCache">
<Rectangle.RenderTransform>
<TranslateTransform x:Name="R5TT"/>
</Rectangle.RenderTransform>
</Rectangle>
</Grid>
</Border>
</Grid>
</unsupported:RelativeAnimatingContentControl>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<StackPanel x:Name="stackPanel"
Visibility="{Binding ShowProgress, Converter={StaticResource booleanToVisibilityConverter}}"
VerticalAlignment="Center"
>
<TextBlock
Text="{Binding Text}"
HorizontalAlignment="Center"
/>
<ProgressBar
Foreground="White"
IsIndeterminate="{Binding ShowProgress}"
Style="{StaticResource PerformanceProgressBar}"
Margin="0,5,0,0"
/>
</StackPanel>
</UserControl>
@@ -0,0 +1,69 @@
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;
namespace WindowsPhone.Recipes.Push.Client.Controls
{
public partial class ProgressBarWithText : UserControl
{
public ProgressBarWithText()
{
InitializeComponent();
stackPanel.DataContext = this;
}
#region ShowProgress
/// <summary>
/// ShowProgress Dependency Property
/// </summary>
public static readonly DependencyProperty ShowProgressProperty =
DependencyProperty.Register("ShowProgress", typeof(bool), typeof(ProgressBarWithText),
new PropertyMetadata((bool)false));
/// <summary>
/// Gets or sets the ShowProgress property. This dependency property
/// indicates whether to show the progress bar.
/// </summary>
public bool ShowProgress
{
get { return (bool)GetValue(ShowProgressProperty); }
set { SetValue(ShowProgressProperty, value); }
}
#endregion
#region Text
/// <summary>
/// Text Dependency Property
/// </summary>
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text", typeof(string), typeof(ProgressBarWithText),
new PropertyMetadata((string)""));
/// <summary>
/// Gets or sets the Text property. This dependency property
/// indicates what is the text that appears above the progress bar.
/// </summary>
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
#endregion
}
}
@@ -0,0 +1,625 @@
// (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;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;
// This is a very special primitive control that works around a limitation in
// the core animation subsystem of Silverlight: there is no way to declare in
// VSM states relative properties, such as animating from 0 to 33% the width of
// the control, using double animations for translation.
//
// It's a tough problem to solve property, but this primitive, unsupported
// control does offer a solution based on magic numbers that still allows a
// designer to make alterations to their animation values to present their
// vision for custom templates.
//
// This is instrumental in offering a Windows Phone ProgressBar implementation
// that uses the render thread instead of animating UI thread-only properties.
//
// For questions, please see
// http://www.jeff.wilcox.name/performanceprogressbar/
//
// This control is licensed Ms-PL and as such comes with no warranties or
// official support.
//
// Style Note
// - - -
// The style that must be used with this is present at the bottom of this file.
//
namespace WindowsPhone.Recipes.Push.Client.Controls
{
/// <summary>
/// A very specialized primitive control that works around a specific visual
/// state manager issue. The platform does not support relative sized
/// translation values, and this special control walks through visual state
/// animation storyboards looking for magic numbers to use as percentages.
/// This control is not supported, unofficial, and is a hack in many ways.
/// It is used to enable a Windows Phone native platform-style progress bar
/// experience in indeterminate mode that remains performant.
/// </summary>
public class RelativeAnimatingContentControl : ContentControl
{
/// <summary>
/// A simple Epsilon-style value used for trying to determine the magic
/// state, if any, of a double.
/// </summary>
private const double SimpleDoubleComparisonEpsilon = 0.000009;
/// <summary>
/// The last known width of the control.
/// </summary>
private double _knownWidth;
/// <summary>
/// The last known height of the control.
/// </summary>
private double _knownHeight;
/// <summary>
/// A set of custom animation adapters used to update the animation
/// storyboards when the size of the control changes.
/// </summary>
private List<AnimationValueAdapter> _specialAnimations;
/// <summary>
/// Initializes a new instance of the RelativeAnimatingContentControl
/// type.
/// </summary>
public RelativeAnimatingContentControl()
{
SizeChanged += OnSizeChanged;
}
/// <summary>
/// Handles the size changed event.
/// </summary>
/// <param name="sender">The source object.</param>
/// <param name="e">The event arguments.</param>
private void OnSizeChanged(object sender, SizeChangedEventArgs e)
{
if (e != null && e.NewSize.Height > 0 && e.NewSize.Width > 0)
{
_knownWidth = e.NewSize.Width;
_knownHeight = e.NewSize.Height;
Clip = new RectangleGeometry { Rect = new Rect(0, 0, _knownWidth, _knownHeight), };
UpdateAnyAnimationValues();
}
}
/// <summary>
/// Walks through the known storyboards in the control's template that
/// may contain magic double animation values, storing them for future
/// use and updates.
/// </summary>
private void UpdateAnyAnimationValues()
{
if (_knownHeight > 0 && _knownWidth > 0)
{
// Initially, before any special animations have been found,
// the visual state groups of the control must be explored.
// By definition they must be at the implementation root of the
// control, and this is designed to not walk into any other
// depth.
if (_specialAnimations == null)
{
_specialAnimations = new List<AnimationValueAdapter>();
foreach (VisualStateGroup group in VisualStateManager.GetVisualStateGroups(this))
{
if (group == null)
{
continue;
}
foreach (VisualState state in group.States)
{
if (state != null)
{
Storyboard sb = state.Storyboard;
if (sb != null)
{
// Examine all children of the storyboards,
// looking for either type of double
// animation.
foreach (Timeline timeline in sb.Children)
{
DoubleAnimation da = timeline as DoubleAnimation;
DoubleAnimationUsingKeyFrames dakeys = timeline as DoubleAnimationUsingKeyFrames;
if (da != null)
{
ProcessDoubleAnimation(da);
}
else if (dakeys != null)
{
ProcessDoubleAnimationWithKeys(dakeys);
}
}
}
}
}
}
}
// Update special animation values relative to the current size.
UpdateKnownAnimations();
}
}
/// <summary>
/// Walks through all special animations, updating based on the current
/// size of the control.
/// </summary>
private void UpdateKnownAnimations()
{
foreach (AnimationValueAdapter adapter in _specialAnimations)
{
adapter.UpdateWithNewDimension(_knownWidth, _knownHeight);
}
}
/// <summary>
/// Processes a double animation with keyframes, looking for known
/// special values to store with an adapter.
/// </summary>
/// <param name="da">The double animation using key frames instance.</param>
private void ProcessDoubleAnimationWithKeys(DoubleAnimationUsingKeyFrames da)
{
// Look through all keyframes in the instance.
foreach (DoubleKeyFrame frame in da.KeyFrames)
{
var d = DoubleAnimationFrameAdapter.GetDimensionFromMagicNumber(frame.Value);
if (d.HasValue)
{
_specialAnimations.Add(new DoubleAnimationFrameAdapter(d.Value, frame));
}
}
}
/// <summary>
/// Processes a double animation looking for special values.
/// </summary>
/// <param name="da">The double animation instance.</param>
private void ProcessDoubleAnimation(DoubleAnimation da)
{
// Look for a special value in the To property.
if (da.To.HasValue)
{
var d = DoubleAnimationToAdapter.GetDimensionFromMagicNumber(da.To.Value);
if (d.HasValue)
{
_specialAnimations.Add(new DoubleAnimationToAdapter(d.Value, da));
}
}
// Look for a special value in the From property.
if (da.From.HasValue)
{
var d = DoubleAnimationFromAdapter.GetDimensionFromMagicNumber(da.To.Value);
if (d.HasValue)
{
_specialAnimations.Add(new DoubleAnimationFromAdapter(d.Value, da));
}
}
}
#region Private animation updating system
/// <summary>
/// A selection of dimensions of interest for updating an animation.
/// </summary>
private enum DoubleAnimationDimension
{
/// <summary>
/// The width (horizontal) dimension.
/// </summary>
Width,
/// <summary>
/// The height (vertical) dimension.
/// </summary>
Height,
}
/// <summary>
/// A simple class designed to store information about a specific
/// animation instance and its properties. Able to update the values at
/// runtime.
/// </summary>
private abstract class AnimationValueAdapter
{
/// <summary>
/// Gets or sets the original double value.
/// </summary>
protected double OriginalValue { get; set; }
/// <summary>
/// Initializes a new instance of the AnimationValueAdapter type.
/// </summary>
/// <param name="dimension">The dimension of interest for updates.</param>
public AnimationValueAdapter(DoubleAnimationDimension dimension)
{
Dimension = dimension;
}
/// <summary>
/// Gets the dimension of interest for the control.
/// </summary>
public DoubleAnimationDimension Dimension { get; private set; }
/// <summary>
/// Updates the original instance based on new dimension information
/// from the control. Takes both and allows the subclass to make the
/// decision on which ratio, values, and dimension to use.
/// </summary>
/// <param name="width">The width of the control.</param>
/// <param name="height">The height of the control.</param>
public abstract void UpdateWithNewDimension(double width, double height);
}
private abstract class GeneralAnimationValueAdapter<T> : AnimationValueAdapter
{
/// <summary>
/// Stores the animation instance.
/// </summary>
protected T Instance { get; set; }
/// <summary>
/// Gets the value of the underlying property of interest.
/// </summary>
/// <returns>Returns the value of the property.</returns>
protected abstract double GetValue();
/// <summary>
/// Sets the value for the underlying property of interest.
/// </summary>
/// <param name="newValue">The new value for the property.</param>
protected abstract void SetValue(double newValue);
/// <summary>
/// Gets the initial value (minus the magic number portion) that the
/// designer stored within the visual state animation property.
/// </summary>
protected double InitialValue { get; private set; }
/// <summary>
/// The ratio based on the original magic value, used for computing
/// the updated animation property of interest when the size of the
/// control changes.
/// </summary>
private double _ratio;
/// <summary>
/// Initializes a new instance of the GeneralAnimationValueAdapter
/// type.
/// </summary>
/// <param name="d">The dimension of interest.</param>
/// <param name="instance">The animation type instance.</param>
public GeneralAnimationValueAdapter(DoubleAnimationDimension d, T instance)
: base(d)
{
Instance = instance;
InitialValue = StripMagicNumberOff(GetValue());
_ratio = InitialValue / 100;
}
/// <summary>
/// Approximately removes the magic number state from a value.
/// </summary>
/// <param name="number">The initial number.</param>
/// <returns>Returns a double with an adjustment for the magic
/// portion of the number.</returns>
public double StripMagicNumberOff(double number)
{
return Dimension == DoubleAnimationDimension.Width ? number - .1 : number - .2;
}
/// <summary>
/// Retrieves the dimension, if any, from the number. If the number
/// is not magic, null is returned instead.
/// </summary>
/// <param name="number">The double value.</param>
/// <returns>Returs a double animation dimension, if the number was
/// partially magic; otherwise, returns null.</returns>
public static DoubleAnimationDimension? GetDimensionFromMagicNumber(double number)
{
double floor = Math.Floor(number);
double remainder = number - floor;
if (remainder >= .1 - SimpleDoubleComparisonEpsilon && remainder <= .1 + SimpleDoubleComparisonEpsilon)
{
return DoubleAnimationDimension.Width;
}
if (remainder >= .2 - SimpleDoubleComparisonEpsilon && remainder <= .2 + SimpleDoubleComparisonEpsilon)
{
return DoubleAnimationDimension.Height;
}
return null;
}
/// <summary>
/// Updates the animation instance based on the dimensions of the
/// control.
/// </summary>
/// <param name="width">The width of the control.</param>
/// <param name="height">The height of the control.</param>
public override void UpdateWithNewDimension(double width, double height)
{
double size = Dimension == DoubleAnimationDimension.Width ? width : height;
UpdateValue(size);
}
/// <summary>
/// Updates the value of the property.
/// </summary>
/// <param name="sizeToUse">The size of interest to use with a ratio
/// computation.</param>
private void UpdateValue(double sizeToUse)
{
SetValue(sizeToUse * _ratio);
}
}
/// <summary>
/// Adapter for DoubleAnimation's To property.
/// </summary>
private class DoubleAnimationToAdapter : GeneralAnimationValueAdapter<DoubleAnimation>
{
/// <summary>
/// Gets the value of the underlying property of interest.
/// </summary>
/// <returns>Returns the value of the property.</returns>
protected override double GetValue()
{
return (double)Instance.To;
}
/// <summary>
/// Sets the value for the underlying property of interest.
/// </summary>
/// <param name="newValue">The new value for the property.</param>
protected override void SetValue(double newValue)
{
Instance.To = newValue;
}
/// <summary>
/// Initializes a new instance of the DoubleAnimationToAdapter type.
/// </summary>
/// <param name="dimension">The dimension of interest.</param>
/// <param name="instance">The instance of the animation type.</param>
public DoubleAnimationToAdapter(DoubleAnimationDimension dimension, DoubleAnimation instance)
: base(dimension, instance)
{
}
}
/// <summary>
/// Adapter for DoubleAnimation's From property.
/// </summary>
private class DoubleAnimationFromAdapter : GeneralAnimationValueAdapter<DoubleAnimation>
{
/// <summary>
/// Gets the value of the underlying property of interest.
/// </summary>
/// <returns>Returns the value of the property.</returns>
protected override double GetValue()
{
return (double)Instance.From;
}
/// <summary>
/// Sets the value for the underlying property of interest.
/// </summary>
/// <param name="newValue">The new value for the property.</param>
protected override void SetValue(double newValue)
{
Instance.From = newValue;
}
/// <summary>
/// Initializes a new instance of the DoubleAnimationFromAdapter
/// type.
/// </summary>
/// <param name="dimension">The dimension of interest.</param>
/// <param name="instance">The instance of the animation type.</param>
public DoubleAnimationFromAdapter(DoubleAnimationDimension dimension, DoubleAnimation instance)
: base(dimension, instance)
{
}
}
/// <summary>
/// Adapter for double key frames.
/// </summary>
private class DoubleAnimationFrameAdapter : GeneralAnimationValueAdapter<DoubleKeyFrame>
{
/// <summary>
/// Gets the value of the underlying property of interest.
/// </summary>
/// <returns>Returns the value of the property.</returns>
protected override double GetValue()
{
return Instance.Value;
}
/// <summary>
/// Sets the value for the underlying property of interest.
/// </summary>
/// <param name="newValue">The new value for the property.</param>
protected override void SetValue(double newValue)
{
Instance.Value = newValue;
}
/// <summary>
/// Initializes a new instance of the DoubleAnimationFrameAdapter
/// type.
/// </summary>
/// <param name="dimension">The dimension of interest.</param>
/// <param name="instance">The instance of the animation type.</param>
public DoubleAnimationFrameAdapter(DoubleAnimationDimension dimension, DoubleKeyFrame frame)
: base(dimension, frame)
{
}
}
#endregion
}
/*
This is the style that should be used with the control. Make sure to define
the XMLNS at the top of the style file similar to this:
xmlns:unsupported="clr-namespace:WindowsPhone.Recipes.Push.Client.Controls"
<!--
// Performance Progress Bar
// - - -
// To use this progress bar at runtime, make sure to set the Style
// value to this key. Since the control visually is identical to control
// in the Windows Phone runtime, you will not be able to visually tell
// the difference: except this style will not use the UI thread at
// runtime when IsIndeterminate=true.
//
// <ProgressBar Style="{StaticResource PerformanceProgressBar}"
// IsIndeterminate="true"/>
//
-->
<Style x:Key="PerformanceProgressBar" TargetType="ProgressBar">
<Setter Property="Foreground" Value="{StaticResource PhoneAccentBrush}"/>
<Setter Property="Background" Value="{StaticResource PhoneAccentBrush}"/>
<Setter Property="Maximum" Value="100"/>
<Setter Property="IsHitTestVisible" Value="False"/>
<Setter Property="Padding" Value="{StaticResource PhoneHorizontalMargin}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ProgressBar">
<unsupported:RelativeAnimatingContentControl HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch">
<unsupported:RelativeAnimatingContentControl.Resources>
<ExponentialEase EasingMode="EaseOut" Exponent="1" x:Key="ProgressBarEaseOut"/>
<ExponentialEase EasingMode="EaseOut" Exponent="1" x:Key="ProgressBarEaseIn"/>
</unsupported:RelativeAnimatingContentControl.Resources>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Determinate"/>
<VisualState x:Name="Indeterminate">
<Storyboard RepeatBehavior="Forever" Duration="00:00:04.4">
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="IndeterminateRoot">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="DeterminateRoot">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Collapsed</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00.0" Storyboard.TargetProperty="X" Storyboard.TargetName="R1TT">
<LinearDoubleKeyFrame KeyTime="00:00:00.0" Value="0.1"/>
<EasingDoubleKeyFrame KeyTime="00:00:00.5" Value="33.1" EasingFunction="{StaticResource ProgressBarEaseOut}"/>
<LinearDoubleKeyFrame KeyTime="00:00:02.0" Value="66.1"/>
<EasingDoubleKeyFrame KeyTime="00:00:02.5" Value="100.1" EasingFunction="{StaticResource ProgressBarEaseIn}"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00.2" Storyboard.TargetProperty="X" Storyboard.TargetName="R2TT">
<LinearDoubleKeyFrame KeyTime="00:00:00.0" Value="0.1"/>
<EasingDoubleKeyFrame KeyTime="00:00:00.5" Value="33.1" EasingFunction="{StaticResource ProgressBarEaseOut}"/>
<LinearDoubleKeyFrame KeyTime="00:00:02.0" Value="66.1"/>
<EasingDoubleKeyFrame KeyTime="00:00:02.5" Value="100.1" EasingFunction="{StaticResource ProgressBarEaseIn}"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00.4" Storyboard.TargetProperty="X" Storyboard.TargetName="R3TT">
<LinearDoubleKeyFrame KeyTime="00:00:00.0" Value="0.1"/>
<EasingDoubleKeyFrame KeyTime="00:00:00.5" Value="33.1" EasingFunction="{StaticResource ProgressBarEaseOut}"/>
<LinearDoubleKeyFrame KeyTime="00:00:02.0" Value="66.1"/>
<EasingDoubleKeyFrame KeyTime="00:00:02.5" Value="100.1" EasingFunction="{StaticResource ProgressBarEaseIn}"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00.6" Storyboard.TargetProperty="X" Storyboard.TargetName="R4TT">
<LinearDoubleKeyFrame KeyTime="00:00:00.0" Value="0.1"/>
<EasingDoubleKeyFrame KeyTime="00:00:00.5" Value="33.1" EasingFunction="{StaticResource ProgressBarEaseOut}"/>
<LinearDoubleKeyFrame KeyTime="00:00:02.0" Value="66.1"/>
<EasingDoubleKeyFrame KeyTime="00:00:02.5" Value="100.1" EasingFunction="{StaticResource ProgressBarEaseIn}"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00.8" Storyboard.TargetProperty="X" Storyboard.TargetName="R5TT">
<LinearDoubleKeyFrame KeyTime="00:00:00.0" Value="0.1"/>
<EasingDoubleKeyFrame KeyTime="00:00:00.5" Value="33.1" EasingFunction="{StaticResource ProgressBarEaseOut}"/>
<LinearDoubleKeyFrame KeyTime="00:00:02.0" Value="66.1"/>
<EasingDoubleKeyFrame KeyTime="00:00:02.5" Value="100.1" EasingFunction="{StaticResource ProgressBarEaseIn}"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00.0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="R1">
<DiscreteDoubleKeyFrame KeyTime="0" Value="1"/>
<DiscreteDoubleKeyFrame KeyTime="00:00:02.5" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00.2" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="R2">
<DiscreteDoubleKeyFrame KeyTime="0" Value="1"/>
<DiscreteDoubleKeyFrame KeyTime="00:00:02.5" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00.4" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="R3">
<DiscreteDoubleKeyFrame KeyTime="0" Value="1"/>
<DiscreteDoubleKeyFrame KeyTime="00:00:02.5" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00.6" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="R4">
<DiscreteDoubleKeyFrame KeyTime="0" Value="1"/>
<DiscreteDoubleKeyFrame KeyTime="00:00:02.5" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00.8" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="R5">
<DiscreteDoubleKeyFrame KeyTime="0" Value="1"/>
<DiscreteDoubleKeyFrame KeyTime="00:00:02.5" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid>
<Grid x:Name="DeterminateRoot" Margin="{TemplateBinding Padding}" Visibility="Visible">
<Rectangle x:Name="ProgressBarTrack" Fill="{TemplateBinding Background}" Height="4" Opacity="0.1"/>
<Rectangle x:Name="ProgressBarIndicator" Fill="{TemplateBinding Foreground}" HorizontalAlignment="Left" Height="4"/>
</Grid>
<Border x:Name="IndeterminateRoot" Margin="{TemplateBinding Padding}" Visibility="Collapsed">
<Grid HorizontalAlignment="Left">
<Rectangle Fill="{TemplateBinding Foreground}" Height="4" IsHitTestVisible="False" Width="4" x:Name="R1" Opacity="0" CacheMode="BitmapCache">
<Rectangle.RenderTransform>
<TranslateTransform x:Name="R1TT"/>
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle Fill="{TemplateBinding Foreground}" Height="4" IsHitTestVisible="False" Width="4" x:Name="R2" Opacity="0" CacheMode="BitmapCache">
<Rectangle.RenderTransform>
<TranslateTransform x:Name="R2TT"/>
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle Fill="{TemplateBinding Foreground}" Height="4" IsHitTestVisible="False" Width="4" x:Name="R3" Opacity="0" CacheMode="BitmapCache">
<Rectangle.RenderTransform>
<TranslateTransform x:Name="R3TT"/>
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle Fill="{TemplateBinding Foreground}" Height="4" IsHitTestVisible="False" Width="4" x:Name="R4" Opacity="0" CacheMode="BitmapCache">
<Rectangle.RenderTransform>
<TranslateTransform x:Name="R4TT"/>
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle Fill="{TemplateBinding Foreground}" Height="4" IsHitTestVisible="False" Width="4" x:Name="R5" Opacity="0" CacheMode="BitmapCache">
<Rectangle.RenderTransform>
<TranslateTransform x:Name="R5TT"/>
</Rectangle.RenderTransform>
</Rectangle>
</Grid>
</Border>
</Grid>
</unsupported:RelativeAnimatingContentControl>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
*/
}
@@ -0,0 +1,59 @@
<UserControl x:Class="WindowsPhone.Recipes.Push.Client.Controls.PushSettingsControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:tk="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"
xmlns:converters="clr-namespace:WindowsPhone.Recipes.Push.Client.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
d:DesignHeight="640" d:DesignWidth="480">
<UserControl.Resources>
<converters:BoolBrushConverter x:Key="BoolBrushConverter" />
<Style x:Key="DescTextStyle" TargetType="TextBlock">
<Setter Property="FontSize" Value="14" />
<Setter Property="Foreground" Value="Silver" />
<Setter Property="TextWrapping" Value="Wrap" />
<Setter Property="Margin" Value="16,-38,16,24" />
</Style>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="{StaticResource PhoneChromeBrush}">
<StackPanel>
<StackPanel>
<tk:ToggleSwitch Header="Push Notifications"
IsChecked="{Binding IsPushEnabled, Mode=TwoWay}" />
<TextBlock Style="{StaticResource DescTextStyle}"
Text="Turn on/off push notifications." />
</StackPanel>
<Grid>
<StackPanel Margin="16,0,0,0">
<tk:ToggleSwitch Header="Tile Notifications"
IsChecked="{Binding IsTileEnabled, Mode=TwoWay}" />
<TextBlock Style="{StaticResource DescTextStyle}"
Text="Tile push notifications update the application's tile displayed in the Start Screen. The application must be pinned by the user first." />
<tk:ToggleSwitch Header="Toast Notifications"
IsChecked="{Binding IsToastEnabled, Mode=TwoWay}" />
<TextBlock Style="{StaticResource DescTextStyle}"
Text="Toast push notifications are system-wide notifications that do not disrupt the user workflow or require intervention to resolve and are displayed in the top of the screen for ten seconds." />
<tk:ToggleSwitch Header="Raw Notifications"
IsChecked="{Binding IsRawEnabled, Mode=TwoWay}" />
<TextBlock Style="{StaticResource DescTextStyle}"
Text="Raw push notifications are used to send application specific information. The application must be running first." />
</StackPanel>
<Border Background="{Binding IsPushEnabled, Converter={StaticResource BoolBrushConverter}}" />
</Grid>
</StackPanel>
</Grid>
</UserControl>
@@ -0,0 +1,26 @@
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.IO.IsolatedStorage;
using System.Xml.Linq;
namespace WindowsPhone.Recipes.Push.Client.Controls
{
public partial class PushSettingsControl : UserControl
{
public PushSettingsControl()
{
DataContext = PushContext.Current;
InitializeComponent();
}
}
}
@@ -0,0 +1,43 @@
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;
namespace WindowsPhone.Recipes.Push.Client.Controls
{
public class ViewTransitions<T>
{
private class ViewTransition
{
public T To { get; set; }
public Action Action { get; set; }
}
public T _viewState;
private readonly Dictionary<T, ViewTransition> _transitions = new Dictionary<T, ViewTransition>();
public ViewTransitions(T initialState)
{
_viewState = initialState;
}
public void AddTransition(T from, T to, Action action)
{
_transitions[from] = new ViewTransition { To = to, Action = action };
}
public void Transition()
{
var transition = _transitions[_viewState];
_viewState = transition.To;
transition.Action();
}
}
}