Adding the UI to the same repo. Made some default theme progress

This commit is contained in:
LukePulverenti Luke Pulverenti luke pulverenti
2012-09-20 11:25:22 -04:00
parent d8c01ded6e
commit 119dfc3ac7
70 changed files with 3384 additions and 30 deletions

View File

@@ -0,0 +1,73 @@
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace MediaBrowser.UI.Controls
{
/// <summary>
/// Provides a ScrollViewer that can be scrolled by dragging the mouse
/// </summary>
public class EnhancedScrollViewer : ScrollViewer
{
private Point _scrollTarget;
private Point _scrollStartPoint;
private Point _scrollStartOffset;
private const int PixelsToMoveToBeConsideredScroll = 5;
protected override void OnPreviewMouseDown(MouseButtonEventArgs e)
{
if (IsMouseOver)
{
// Save starting point, used later when determining how much to scroll.
_scrollStartPoint = e.GetPosition(this);
_scrollStartOffset.X = HorizontalOffset;
_scrollStartOffset.Y = VerticalOffset;
// Update the cursor if can scroll or not.
Cursor = (ExtentWidth > ViewportWidth) ||
(ExtentHeight > ViewportHeight) ?
Cursors.ScrollAll : Cursors.Arrow;
CaptureMouse();
}
base.OnPreviewMouseDown(e);
}
protected override void OnPreviewMouseMove(MouseEventArgs e)
{
if (IsMouseCaptured)
{
Point currentPoint = e.GetPosition(this);
// Determine the new amount to scroll.
var delta = new Point(_scrollStartPoint.X - currentPoint.X, _scrollStartPoint.Y - currentPoint.Y);
if (Math.Abs(delta.X) < PixelsToMoveToBeConsideredScroll &&
Math.Abs(delta.Y) < PixelsToMoveToBeConsideredScroll)
return;
_scrollTarget.X = _scrollStartOffset.X + delta.X;
_scrollTarget.Y = _scrollStartOffset.Y + delta.Y;
// Scroll to the new position.
ScrollToHorizontalOffset(_scrollTarget.X);
ScrollToVerticalOffset(_scrollTarget.Y);
}
base.OnPreviewMouseMove(e);
}
protected override void OnPreviewMouseUp(MouseButtonEventArgs e)
{
if (IsMouseCaptured)
{
Cursor = Cursors.Arrow;
ReleaseMouseCapture();
}
base.OnPreviewMouseUp(e);
}
}
}

View File

@@ -0,0 +1,92 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace MediaBrowser.UI.Controls
{
/// <summary>
/// Follow steps 1a or 1b and then 2 to use this custom control in a XAML file.
///
/// Step 1a) Using this custom control in a XAML file that exists in the current project.
/// Add this XmlNamespace attribute to the root element of the markup file where it is
/// to be used:
///
/// xmlns:MyNamespace="clr-namespace:MediaBrowser.UI.Controls"
///
///
/// Step 1b) Using this custom control in a XAML file that exists in a different project.
/// Add this XmlNamespace attribute to the root element of the markup file where it is
/// to be used:
///
/// xmlns:MyNamespace="clr-namespace:MediaBrowser.UI.Controls;assembly=MediaBrowser.UI.Controls"
///
/// You will also need to add a project reference from the project where the XAML file lives
/// to this project and Rebuild to avoid compilation errors:
///
/// Right click on the target project in the Solution Explorer and
/// "Add Reference"->"Projects"->[Browse to and select this project]
///
///
/// Step 2)
/// Go ahead and use your control in the XAML file.
///
/// <MyNamespace:ExtendedImage/>
///
/// </summary>
public class ExtendedImage : Control
{
public static readonly DependencyProperty HasImageProperty = DependencyProperty.Register(
"HasImage",
typeof (bool),
typeof (ExtendedImage),
new PropertyMetadata(default(bool)));
public bool HasImage
{
get { return (bool)GetValue(HasImageProperty); }
set { SetValue(HasImageProperty, value); }
}
public static readonly DependencyProperty SourceProperty = DependencyProperty.Register(
"Source",
typeof(ImageSource),
typeof(ExtendedImage),
new PropertyMetadata(default(ImageBrush)));
public ImageSource Source
{
get { return (ImageSource)GetValue(SourceProperty); }
set { SetValue(SourceProperty, value); }
}
public static readonly DependencyProperty StretchProperty = DependencyProperty.Register(
"Stretch",
typeof (Stretch),
typeof (ExtendedImage),
new PropertyMetadata(default(Stretch)));
public Stretch Stretch
{
get { return (Stretch) GetValue(StretchProperty); }
set { SetValue(StretchProperty, value); }
}
public static readonly DependencyProperty PlaceHolderSourceProperty = DependencyProperty.Register(
"PlaceHolderSource",
typeof(ImageSource),
typeof(ExtendedImage),
new PropertyMetadata(default(ImageBrush)));
public ImageSource PlaceHolderSource
{
get { return (ImageSource)GetValue(PlaceHolderSourceProperty); }
set { SetValue(PlaceHolderSourceProperty, value); }
}
static ExtendedImage()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(ExtendedImage),
new FrameworkPropertyMetadata(typeof(ExtendedImage)));
}
}
}

View File

@@ -0,0 +1,226 @@
using System.Collections.Generic;
using System.Windows;
using System.Windows.Media;
namespace MediaBrowser.UI.Controls
{
/// <summary>
/// Helper methods for UI-related tasks.
/// </summary>
public static class TreeHelper
{
/// <summary>
/// Finds a Child of a given item in the visual tree.
/// </summary>
/// <param name="parent">A direct parent of the queried item.</param>
/// <typeparam name="T">The type of the queried item.</typeparam>
/// <param name="childName">x:Name or Name of child. </param>
/// <returns>The first parent item that matches the submitted type parameter.
/// If not matching item can be found,
/// a null parent is being returned.</returns>
public static T FindChild<T>(DependencyObject parent, string childName)
where T : DependencyObject
{
// Confirm parent and childName are valid.
if (parent == null) return null;
T foundChild = null;
int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < childrenCount; i++)
{
var child = VisualTreeHelper.GetChild(parent, i);
// If the child is not of the request child type child
T childType = child as T;
if (childType == null)
{
// recursively drill down the tree
foundChild = FindChild<T>(child, childName);
// If the child is found, break so we do not overwrite the found child.
if (foundChild != null) break;
}
else if (!string.IsNullOrEmpty(childName))
{
var frameworkElement = child as FrameworkElement;
// If the child's name is set for search
if (frameworkElement != null && frameworkElement.Name == childName)
{
// if the child's name is of the request name
foundChild = (T)child;
break;
}
}
else
{
// child element found.
foundChild = (T)child;
break;
}
}
return foundChild;
}
#region find parent
/// <summary>
/// Finds a parent of a given item on the visual tree.
/// </summary>
/// <typeparam name="T">The type of the queried item.</typeparam>
/// <param name="child">A direct or indirect child of the
/// queried item.</param>
/// <returns>The first parent item that matches the submitted
/// type parameter. If not matching item can be found, a null
/// reference is being returned.</returns>
public static T TryFindParent<T>(this DependencyObject child)
where T : DependencyObject
{
//get parent item
DependencyObject parentObject = GetParentObject(child);
//we've reached the end of the tree
if (parentObject == null) return null;
//check if the parent matches the type we're looking for
T parent = parentObject as T;
if (parent != null)
{
return parent;
}
//use recursion to proceed with next level
return TryFindParent<T>(parentObject);
}
/// <summary>
/// This method is an alternative to WPF's
/// <see cref="VisualTreeHelper.GetParent"/> method, which also
/// supports content elements. Keep in mind that for content element,
/// this method falls back to the logical tree of the element!
/// </summary>
/// <param name="child">The item to be processed.</param>
/// <returns>The submitted item's parent, if available. Otherwise
/// null.</returns>
public static DependencyObject GetParentObject(this DependencyObject child)
{
if (child == null) return null;
//handle content elements separately
ContentElement contentElement = child as ContentElement;
if (contentElement != null)
{
DependencyObject parent = ContentOperations.GetParent(contentElement);
if (parent != null) return parent;
FrameworkContentElement fce = contentElement as FrameworkContentElement;
return fce != null ? fce.Parent : null;
}
//also try searching for parent in framework elements (such as DockPanel, etc)
FrameworkElement frameworkElement = child as FrameworkElement;
if (frameworkElement != null)
{
DependencyObject parent = frameworkElement.Parent;
if (parent != null) return parent;
}
//if it's not a ContentElement/FrameworkElement, rely on VisualTreeHelper
return VisualTreeHelper.GetParent(child);
}
#endregion
#region find children
/// <summary>
/// Analyzes both visual and logical tree in order to find all elements of a given
/// type that are descendants of the <paramref name="source"/> item.
/// </summary>
/// <typeparam name="T">The type of the queried items.</typeparam>
/// <param name="source">The root element that marks the source of the search. If the
/// source is already of the requested type, it will not be included in the result.</param>
/// <returns>All descendants of <paramref name="source"/> that match the requested type.</returns>
public static IEnumerable<T> FindChildren<T>(this DependencyObject source) where T : DependencyObject
{
if (source != null)
{
var childs = GetChildObjects(source);
foreach (DependencyObject child in childs)
{
//analyze if children match the requested type
if (child is T)
{
yield return (T)child;
}
//recurse tree
foreach (T descendant in FindChildren<T>(child))
{
yield return descendant;
}
}
}
}
/// <summary>
/// This method is an alternative to WPF's
/// <see cref="VisualTreeHelper.GetChild"/> method, which also
/// supports content elements. Keep in mind that for content elements,
/// this method falls back to the logical tree of the element.
/// </summary>
/// <param name="parent">The item to be processed.</param>
/// <returns>The submitted item's child elements, if available.</returns>
public static IEnumerable<DependencyObject> GetChildObjects(this DependencyObject parent)
{
if (parent == null) yield break;
if (parent is ContentElement || parent is FrameworkElement)
{
//use the logical tree for content / framework elements
foreach (object obj in LogicalTreeHelper.GetChildren(parent))
{
var depObj = obj as DependencyObject;
if (depObj != null) yield return (DependencyObject)obj;
}
}
else
{
//use the visual tree per default
int count = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < count; i++)
{
yield return VisualTreeHelper.GetChild(parent, i);
}
}
}
#endregion
#region find from point
/// <summary>
/// Tries to locate a given item within the visual tree,
/// starting with the dependency object at a given position.
/// </summary>
/// <typeparam name="T">The type of the element to be found
/// on the visual tree of the element at the given location.</typeparam>
/// <param name="reference">The main element which is used to perform
/// hit testing.</param>
/// <param name="point">The position to be evaluated on the origin.</param>
public static T TryFindFromPoint<T>(UIElement reference, Point point)
where T : DependencyObject
{
DependencyObject element = reference.InputHitTest(point) as DependencyObject;
if (element == null) return null;
if (element is T) return (T)element;
return TryFindParent<T>(element);
}
#endregion
}
}

View File

@@ -0,0 +1,91 @@
<UserControl x:Class="MediaBrowser.UI.Controls.WindowCommands"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
<Style TargetType="StackPanel" x:Key="WindowCommandsPanel">
<Setter Property="Orientation" Value="Horizontal"/>
<Setter Property="HorizontalAlignment" Value="Right"/>
</Style>
<Style TargetType="Button" x:Key="WebdingsButton" BasedOn="{StaticResource ImageButton}">
<Setter Property="Margin" Value="0 0 15 0"/>
<Setter Property="KeyboardNavigation.IsTabStop" Value="false"/>
</Style>
<Style TargetType="TextBlock" x:Key="WebdingsTextBlock">
<Setter Property="FontFamily" Value="Webdings"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="Foreground" Value="{StaticResource DefaultForeground}"/>
</Style>
<Style TargetType="Button" x:Key="MinimizeApplicationButton" BasedOn="{StaticResource WebdingsButton}">
<Setter Property="ToolTip" Value="Minimize"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<TextBlock Style="{StaticResource WebdingsTextBlock}">0</TextBlock>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="Button" x:Key="MaximizeApplicationButton" BasedOn="{StaticResource WebdingsButton}">
<Setter Property="ToolTip" Value="Maximize"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<TextBlock Style="{StaticResource WebdingsTextBlock}">1</TextBlock>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=WindowState, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" Value="Maximized">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
</Style.Triggers>
</Style>
<Style TargetType="Button" x:Key="UndoMaximizeApplicationButton" BasedOn="{StaticResource WebdingsButton}">
<Setter Property="Visibility" Value="Collapsed"/>
<Setter Property="ToolTip" Value="Restore"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<TextBlock Style="{StaticResource WebdingsTextBlock}">2</TextBlock>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=WindowState, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" Value="Maximized">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
<Style TargetType="Button" x:Key="CloseApplicationButton" BasedOn="{StaticResource WebdingsButton}">
<Setter Property="ToolTip" Value="Close"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<TextBlock Style="{StaticResource WebdingsTextBlock}">r</TextBlock>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<StackPanel Style="{StaticResource WindowCommandsPanel}">
<Button x:Name="MinimizeApplicationButton" Style="{StaticResource MinimizeApplicationButton}"></Button>
<Button x:Name="MaximizeApplicationButton" Style="{StaticResource MaximizeApplicationButton}"></Button>
<Button x:Name="UndoMaximizeApplicationButton" Style="{StaticResource UndoMaximizeApplicationButton}"></Button>
<Button x:Name="CloseApplicationButton" Style="{StaticResource CloseApplicationButton}"></Button>
</StackPanel>
</UserControl>

View File

@@ -0,0 +1,50 @@
using System.Windows;
using System.Windows.Controls;
namespace MediaBrowser.UI.Controls
{
/// <summary>
/// Interaction logic for WindowCommands.xaml
/// </summary>
public partial class WindowCommands : UserControl
{
public Window ParentWindow
{
get { return TreeHelper.TryFindParent<Window>(this); }
}
public WindowCommands()
{
InitializeComponent();
Loaded += WindowCommandsLoaded;
}
void WindowCommandsLoaded(object sender, RoutedEventArgs e)
{
CloseApplicationButton.Click += CloseApplicationButtonClick;
MinimizeApplicationButton.Click += MinimizeApplicationButtonClick;
MaximizeApplicationButton.Click += MaximizeApplicationButtonClick;
UndoMaximizeApplicationButton.Click += UndoMaximizeApplicationButtonClick;
}
void UndoMaximizeApplicationButtonClick(object sender, RoutedEventArgs e)
{
ParentWindow.WindowState = WindowState.Normal;
}
void MaximizeApplicationButtonClick(object sender, RoutedEventArgs e)
{
ParentWindow.WindowState = WindowState.Maximized;
}
void MinimizeApplicationButtonClick(object sender, RoutedEventArgs e)
{
ParentWindow.WindowState = WindowState.Minimized;
}
void CloseApplicationButtonClick(object sender, RoutedEventArgs e)
{
ParentWindow.Close();
}
}
}