diff options
| author | LukePulverenti <luke.pulverenti@gmail.com> | 2013-02-20 20:33:05 -0500 |
|---|---|---|
| committer | LukePulverenti <luke.pulverenti@gmail.com> | 2013-02-20 20:33:05 -0500 |
| commit | 767cdc1f6f6a63ce997fc9476911e2c361f9d402 (patch) | |
| tree | 49add55976f895441167c66cfa95e5c7688d18ce /MediaBrowser.UI/Controls | |
| parent | 845554722efaed872948a9e0f7202e3ef52f1b6e (diff) | |
Pushing missing changes
Diffstat (limited to 'MediaBrowser.UI/Controls')
| -rw-r--r-- | MediaBrowser.UI/Controls/EnhancedScrollViewer.cs | 73 | ||||
| -rw-r--r-- | MediaBrowser.UI/Controls/ExtendedImage.cs | 92 | ||||
| -rw-r--r-- | MediaBrowser.UI/Controls/ModalWindow.xaml | 67 | ||||
| -rw-r--r-- | MediaBrowser.UI/Controls/ModalWindow.xaml.cs | 180 | ||||
| -rw-r--r-- | MediaBrowser.UI/Controls/NavigationBar.xaml | 55 | ||||
| -rw-r--r-- | MediaBrowser.UI/Controls/NavigationBar.xaml.cs | 318 | ||||
| -rw-r--r-- | MediaBrowser.UI/Controls/NotificationMessage.xaml | 33 | ||||
| -rw-r--r-- | MediaBrowser.UI/Controls/NotificationMessage.xaml.cs | 68 | ||||
| -rw-r--r-- | MediaBrowser.UI/Controls/TreeHelper.cs | 226 | ||||
| -rw-r--r-- | MediaBrowser.UI/Controls/WindowCommands.xaml | 191 | ||||
| -rw-r--r-- | MediaBrowser.UI/Controls/WindowCommands.xaml.cs | 132 |
11 files changed, 903 insertions, 532 deletions
diff --git a/MediaBrowser.UI/Controls/EnhancedScrollViewer.cs b/MediaBrowser.UI/Controls/EnhancedScrollViewer.cs deleted file mode 100644 index 188715e1e5..0000000000 --- a/MediaBrowser.UI/Controls/EnhancedScrollViewer.cs +++ /dev/null @@ -1,73 +0,0 @@ -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);
- }
- }
-}
diff --git a/MediaBrowser.UI/Controls/ExtendedImage.cs b/MediaBrowser.UI/Controls/ExtendedImage.cs deleted file mode 100644 index 9d6ee3a7ae..0000000000 --- a/MediaBrowser.UI/Controls/ExtendedImage.cs +++ /dev/null @@ -1,92 +0,0 @@ -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)));
- }
- }
-}
diff --git a/MediaBrowser.UI/Controls/ModalWindow.xaml b/MediaBrowser.UI/Controls/ModalWindow.xaml new file mode 100644 index 0000000000..c2afbe05e2 --- /dev/null +++ b/MediaBrowser.UI/Controls/ModalWindow.xaml @@ -0,0 +1,67 @@ +<controls:BaseModalWindow x:Class="MediaBrowser.UI.Controls.ModalWindow" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:Controls="clr-namespace:MediaBrowser.UI.Controls" + xmlns:controls="clr-namespace:MediaBrowser.UI.Controls;assembly=MediaBrowser.UI.Controls" + Title="ModalWindow" + AllowsTransparency="True" + Background="Transparent" + Style="{StaticResource ModalWindow}"> + + <Grid> + <Grid Style="{StaticResource ModalOverlayStyle}"> + + </Grid> + <Grid Style="{StaticResource ModalContentStyle}" RenderTransformOrigin="1,0"> + <Grid Style="{StaticResource ModalContentInnerStyle}"> + + <Grid.ColumnDefinitions> + <ColumnDefinition Width="auto"></ColumnDefinition> + <ColumnDefinition Width="*"></ColumnDefinition> + </Grid.ColumnDefinitions> + + <Grid.RowDefinitions> + <RowDefinition Height="auto"></RowDefinition> + <RowDefinition Height="auto"></RowDefinition> + <RowDefinition Height="auto"></RowDefinition> + </Grid.RowDefinitions> + + <Image Grid.Row="0" Grid.RowSpan="3" Grid.Column="0" Style="{StaticResource ModalButtonImage}"></Image> + + <TextBlock x:Name="txtCaption" Text="{Binding Caption}" Style="{StaticResource Heading2TextBlockStyle}" Grid.Row="0" Grid.Column="1" Margin="0 30 0 10"></TextBlock> + + <Grid x:Name="pnlContent" HorizontalAlignment="Stretch" Grid.Row="1" Grid.Column="1"> + + </Grid> + + <StackPanel x:Name="pnlButtons" Style="{StaticResource ModalButtonPanel}" Grid.Row="2" Grid.Column="1"> + <controls:ExtendedButton x:Name="btnYes" Content="Yes" Style="{StaticResource ModalButton}"></controls:ExtendedButton> + <controls:ExtendedButton x:Name="btnNo" Content="No" Style="{StaticResource ModalButton}"></controls:ExtendedButton> + <controls:ExtendedButton x:Name="btnOk" Content="OK" Style="{StaticResource ModalButton}"></controls:ExtendedButton> + <controls:ExtendedButton x:Name="btnCancel" Content="Cancel" Style="{StaticResource ModalButton}"></controls:ExtendedButton> + </StackPanel> + </Grid> + <!-- Animation --> + <Grid.Triggers> + <EventTrigger RoutedEvent="FrameworkElement.Loaded"> + <BeginStoryboard> + <Storyboard> + <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleX)"> + <SplineDoubleKeyFrame KeyTime="0:0:0" Value="0"/> + <SplineDoubleKeyFrame KeyTime="0:0:0.15" Value="1"/> + </DoubleAnimationUsingKeyFrames> + </Storyboard> + </BeginStoryboard> + </EventTrigger> + </Grid.Triggers> + + <Grid.RenderTransform> + <ScaleTransform ScaleX="1" /> + </Grid.RenderTransform> + </Grid> + + <Grid.LayoutTransform> + <ScaleTransform ScaleX="{Binding Path=ContentScale}" ScaleY="{Binding Path=ContentScale}" CenterX="0" CenterY="0" /> + </Grid.LayoutTransform> + + </Grid> +</controls:BaseModalWindow> diff --git a/MediaBrowser.UI/Controls/ModalWindow.xaml.cs b/MediaBrowser.UI/Controls/ModalWindow.xaml.cs new file mode 100644 index 0000000000..21f97b8ac0 --- /dev/null +++ b/MediaBrowser.UI/Controls/ModalWindow.xaml.cs @@ -0,0 +1,180 @@ +using System; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Media.Animation; + +namespace MediaBrowser.UI.Controls +{ + /// <summary> + /// Interaction logic for ModalWindow.xaml + /// </summary> + public partial class ModalWindow : BaseModalWindow + { + public MessageBoxResult MessageBoxResult { get; set; } + + public UIElement TextContent + { + set + { + pnlContent.Children.Clear(); + + var textBlock = value as TextBlock; + + if (textBlock != null) + { + textBlock.SetResourceReference(TextBlock.StyleProperty, "ModalTextStyle"); + } + pnlContent.Children.Add(value); + } + } + + public string Text + { + set { TextContent = new TextBlock { Text = value }; } + } + + private MessageBoxButton _button; + public MessageBoxButton Button + { + get { return _button; } + set + { + _button = value; + UpdateButtonVisibility(); + OnPropertyChanged("Button"); + } + } + + private MessageBoxIcon _messageBoxImage; + public MessageBoxIcon MessageBoxImage + { + get { return _messageBoxImage; } + set + { + _messageBoxImage = value; + OnPropertyChanged("MessageBoxImage"); + } + } + + private string _caption; + public string Caption + { + get { return _caption; } + set + { + _caption = value; + txtCaption.Visibility = string.IsNullOrEmpty(value) ? Visibility.Collapsed : Visibility.Visible; + OnPropertyChanged("Caption"); + } + } + + public ModalWindow() + : base() + { + InitializeComponent(); + } + + protected override void OnInitialized(EventArgs e) + { + base.OnInitialized(e); + + btnOk.Click += btnOk_Click; + btnCancel.Click += btnCancel_Click; + btnYes.Click += btnYes_Click; + btnNo.Click += btnNo_Click; + } + + void btnNo_Click(object sender, RoutedEventArgs e) + { + MessageBoxResult = MessageBoxResult.No; + CloseModal(); + } + + void btnYes_Click(object sender, RoutedEventArgs e) + { + MessageBoxResult = MessageBoxResult.Yes; + CloseModal(); + } + + void btnCancel_Click(object sender, RoutedEventArgs e) + { + MessageBoxResult = MessageBoxResult.Cancel; + CloseModal(); + } + + void btnOk_Click(object sender, RoutedEventArgs e) + { + MessageBoxResult = MessageBoxResult.OK; + CloseModal(); + } + + private void UpdateButtonVisibility() + { + btnYes.Visibility = Button == MessageBoxButton.YesNo || Button == MessageBoxButton.YesNoCancel + ? Visibility.Visible + : Visibility.Collapsed; + + btnNo.Visibility = Button == MessageBoxButton.YesNo || Button == MessageBoxButton.YesNoCancel + ? Visibility.Visible + : Visibility.Collapsed; + + btnOk.Visibility = Button == MessageBoxButton.OK || Button == MessageBoxButton.OKCancel + ? Visibility.Visible + : Visibility.Collapsed; + + btnCancel.Visibility = Button == MessageBoxButton.OKCancel || Button == MessageBoxButton.YesNoCancel + ? Visibility.Visible + : Visibility.Collapsed; + } + } + + /// <summary> + /// I had to make my own enum that essentially clones MessageBoxImage + /// Some of the options share the same enum int value, and this was preventing databinding from working properly. + /// </summary> + public enum MessageBoxIcon + { + // Summary: + // No icon is displayed. + None, + // + // Summary: + // The message box contains a symbol consisting of white X in a circle with + // a red background. + Error, + // + // Summary: + // The message box contains a symbol consisting of a white X in a circle with + // a red background. + Hand, + // + // Summary: + // The message box contains a symbol consisting of white X in a circle with + // a red background. + Stop, + // + // Summary: + // The message box contains a symbol consisting of a question mark in a circle. + Question, + // + // Summary: + // The message box contains a symbol consisting of an exclamation point in a + // triangle with a yellow background. + Exclamation, + // + // Summary: + // The message box contains a symbol consisting of an exclamation point in a + // triangle with a yellow background. + Warning, + // + // Summary: + // The message box contains a symbol consisting of a lowercase letter i in a + // circle. + Information, + // + // Summary: + // The message box contains a symbol consisting of a lowercase letter i in a + // circle. + Asterisk + } +} diff --git a/MediaBrowser.UI/Controls/NavigationBar.xaml b/MediaBrowser.UI/Controls/NavigationBar.xaml new file mode 100644 index 0000000000..020fecd6d5 --- /dev/null +++ b/MediaBrowser.UI/Controls/NavigationBar.xaml @@ -0,0 +1,55 @@ +<controls:BaseUserControl x:Class="MediaBrowser.UI.Controls.NavigationBar" + 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" + xmlns:controls="clr-namespace:MediaBrowser.UI.Controls;assembly=MediaBrowser.UI.Controls" + mc:Ignorable="d" + d:DesignHeight="300" d:DesignWidth="300"> + <Grid x:Name="NavBarGrid" Style="{StaticResource NavBarGrid}"> + + <Grid Style="{StaticResource NavBarBackgroundGrid}"></Grid> + + <Grid> + <Grid.RowDefinitions> + <RowDefinition Height="auto"></RowDefinition> + <RowDefinition Height="auto"></RowDefinition> + </Grid.RowDefinitions> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="1*"></ColumnDefinition> + <ColumnDefinition Width="1*"></ColumnDefinition> + <ColumnDefinition Width="1*"></ColumnDefinition> + </Grid.ColumnDefinitions> + + <Grid x:Name="SeekGrid" Grid.Row="0" Grid.ColumnSpan="3" Margin="150 15 150 5" Visibility="Collapsed"> + + <Grid.ColumnDefinitions> + <ColumnDefinition Width="auto"></ColumnDefinition> + <ColumnDefinition Width="*"></ColumnDefinition> + <ColumnDefinition Width="auto"></ColumnDefinition> + </Grid.ColumnDefinitions> + + <TextBlock x:Name="TxtCurrentPosition" Grid.Column="0" Style="{StaticResource TextBlockStyle}" Margin="0 0 10 0"></TextBlock> + <Slider x:Name="CurrentPositionSlider" Grid.Column="1" VerticalAlignment="Center" Minimum="0" Thumb.DragStarted="CurrentPositionSlider_DragStarted" Thumb.DragCompleted="CurrentPositionSlider_DragCompleted" IsMoveToPointEnabled="True"></Slider> + <TextBlock x:Name="TxtDuration" Grid.Column="2" Style="{StaticResource TextBlockStyle}" Margin="10 0 0 0"></TextBlock> + + </Grid> + + <StackPanel Style="{StaticResource NavBarGridLeftPanel}" Grid.Row="1"> + <Button x:Name="BackButton" Style="{StaticResource BackButton}"></Button> + </StackPanel> + <StackPanel Style="{StaticResource NavBarGridCenterPanel}" Grid.Row="1"> + <Button x:Name="PreviousChapterButton" Style="{StaticResource PreviousChapterButton}" Visibility="Collapsed"></Button> + <Button x:Name="PlayButton" Style="{StaticResource PlayButton}" Visibility="Collapsed"></Button> + <Button x:Name="PauseButton" Style="{StaticResource PauseButton}" Visibility="Collapsed"></Button> + <Button x:Name="StopButton" Style="{StaticResource StopButton}" Visibility="Collapsed"></Button> + <Button x:Name="NextChapterButton" Style="{StaticResource NextChapterButton}" Visibility="Collapsed"></Button> + </StackPanel> + <StackPanel Style="{StaticResource NavBarGridRightPanel}" Grid.Row="1"> + <Button x:Name="MuteButton" Style="{StaticResource MuteButton}" Visibility="Collapsed"></Button> + <Button x:Name="VolumeDownButton" Style="{StaticResource VolumeDownButton}" Visibility="Collapsed"></Button> + <Button x:Name="VolumeUpButton" Style="{StaticResource VolumeUpButton}" Visibility="Collapsed"></Button> + </StackPanel> + </Grid> + </Grid> +</controls:BaseUserControl> diff --git a/MediaBrowser.UI/Controls/NavigationBar.xaml.cs b/MediaBrowser.UI/Controls/NavigationBar.xaml.cs new file mode 100644 index 0000000000..6d59a7d3a3 --- /dev/null +++ b/MediaBrowser.UI/Controls/NavigationBar.xaml.cs @@ -0,0 +1,318 @@ +using MediaBrowser.UI.Controller; +using MediaBrowser.UI.Playback; +using MediaBrowser.UI.Playback.InternalPlayer; +using System; +using System.Threading; +using System.Windows; +using System.Windows.Controls.Primitives; +using System.Windows.Input; + +namespace MediaBrowser.UI.Controls +{ + /// <summary> + /// Interaction logic for NavigationBar.xaml + /// </summary> + public partial class NavigationBar : BaseUserControl + { + /// <summary> + /// Gets or sets the current player. + /// </summary> + /// <value>The current player.</value> + private BaseMediaPlayer CurrentPlayer { get; set; } + + /// <summary> + /// Gets or sets the current position timer. + /// </summary> + /// <value>The current position timer.</value> + private Timer CurrentPositionTimer { get; set; } + + /// <summary> + /// Initializes a new instance of the <see cref="NavigationBar" /> class. + /// </summary> + public NavigationBar() + { + InitializeComponent(); + + Loaded += NavigationBar_Loaded; + } + + /// <summary> + /// Handles the Loaded event of the NavigationBar control. + /// </summary> + /// <param name="sender">The source of the event.</param> + /// <param name="e">The <see cref="RoutedEventArgs" /> instance containing the event data.</param> + void NavigationBar_Loaded(object sender, RoutedEventArgs e) + { + BackButton.Click += BtnApplicationBackClick; + MuteButton.Click += MuteButton_Click; + + VolumeDownButton.PreviewMouseDown += VolumeDownButton_Click; + VolumeUpButton.PreviewMouseDown += VolumeUpButton_Click; + + StopButton.Click += StopButton_Click; + PlayButton.Click += PlayButton_Click; + PauseButton.Click += PauseButton_Click; + + NextChapterButton.Click += NextChapterButton_Click; + PreviousChapterButton.Click += PreviousChapterButton_Click; + + UIKernel.Instance.PlaybackManager.PlaybackStarted += PlaybackManager_PlaybackStarted; + UIKernel.Instance.PlaybackManager.PlaybackCompleted += PlaybackManager_PlaybackCompleted; + + CurrentPositionSlider.PreviewMouseUp += CurrentPositionSlider_PreviewMouseUp; + } + + /// <summary> + /// Handles the Click event of the PreviousChapterButton control. + /// </summary> + /// <param name="sender">The source of the event.</param> + /// <param name="e">The <see cref="RoutedEventArgs" /> instance containing the event data.</param> + async void PreviousChapterButton_Click(object sender, RoutedEventArgs e) + { + await CurrentPlayer.GoToPreviousChapter(); + } + + /// <summary> + /// Handles the Click event of the NextChapterButton control. + /// </summary> + /// <param name="sender">The source of the event.</param> + /// <param name="e">The <see cref="RoutedEventArgs" /> instance containing the event data.</param> + async void NextChapterButton_Click(object sender, RoutedEventArgs e) + { + await CurrentPlayer.GoToNextChapter(); + } + + /// <summary> + /// Handles the Click event of the PauseButton control. + /// </summary> + /// <param name="sender">The source of the event.</param> + /// <param name="e">The <see cref="RoutedEventArgs" /> instance containing the event data.</param> + async void PauseButton_Click(object sender, RoutedEventArgs e) + { + await CurrentPlayer.Pause(); + } + + /// <summary> + /// Handles the Click event of the PlayButton control. + /// </summary> + /// <param name="sender">The source of the event.</param> + /// <param name="e">The <see cref="RoutedEventArgs" /> instance containing the event data.</param> + async void PlayButton_Click(object sender, RoutedEventArgs e) + { + await CurrentPlayer.UnPause(); + } + + /// <summary> + /// Handles the Click event of the StopButton control. + /// </summary> + /// <param name="sender">The source of the event.</param> + /// <param name="e">The <see cref="RoutedEventArgs" /> instance containing the event data.</param> + async void StopButton_Click(object sender, RoutedEventArgs e) + { + await CurrentPlayer.Stop(); + } + + /// <summary> + /// Handles the PlaybackCompleted event of the PlaybackManager control. + /// </summary> + /// <param name="sender">The source of the event.</param> + /// <param name="e">The <see cref="PlaybackEventArgs" /> instance containing the event data.</param> + void PlaybackManager_PlaybackCompleted(object sender, PlaybackStopEventArgs e) + { + if (e.Player == CurrentPlayer) + { + if (CurrentPositionTimer != null) + { + CurrentPositionTimer.Dispose(); + } + + CurrentPlayer.PlayStateChanged -= CurrentPlayer_PlayStateChanged; + CurrentPlayer = null; + ResetButtonVisibilities(null); + + Dispatcher.InvokeAsync(() => TxtCurrentPosition.Text = string.Empty); + } + } + + /// <summary> + /// Handles the Click event of the VolumeUpButton control. + /// </summary> + /// <param name="sender">The source of the event.</param> + /// <param name="e">The <see cref="RoutedEventArgs" /> instance containing the event data.</param> + void VolumeUpButton_Click(object sender, RoutedEventArgs e) + { + CurrentPlayer.Volume += 3; + } + + /// <summary> + /// Handles the Click event of the VolumeDownButton control. + /// </summary> + /// <param name="sender">The source of the event.</param> + /// <param name="e">The <see cref="RoutedEventArgs" /> instance containing the event data.</param> + void VolumeDownButton_Click(object sender, RoutedEventArgs e) + { + CurrentPlayer.Volume -= 3; + } + + /// <summary> + /// Handles the Click event of the MuteButton control. + /// </summary> + /// <param name="sender">The source of the event.</param> + /// <param name="e">The <see cref="RoutedEventArgs" /> instance containing the event data.</param> + void MuteButton_Click(object sender, RoutedEventArgs e) + { + if (CurrentPlayer.CanMute) + { + CurrentPlayer.Mute = !CurrentPlayer.Mute; + } + } + + /// <summary> + /// Handles the PlaybackStarted event of the PlaybackManager control. + /// </summary> + /// <param name="sender">The source of the event.</param> + /// <param name="e">The <see cref="PlaybackEventArgs" /> instance containing the event data.</param> + void PlaybackManager_PlaybackStarted(object sender, PlaybackEventArgs e) + { + if (e.Player is BaseInternalMediaPlayer) + { + CurrentPlayer = e.Player; + CurrentPlayer.PlayStateChanged += CurrentPlayer_PlayStateChanged; + + ResetButtonVisibilities(e.Player); + + Dispatcher.InvokeAsync(() => + { + var runtime = e.Player.CurrentMedia.RunTimeTicks ?? 0; + CurrentPositionSlider.Maximum = runtime; + + TxtDuration.Text = GetTimeString(runtime); + + }); + + CurrentPositionTimer = new Timer(CurrentPositionTimerCallback, null, 250, 250); + } + } + + /// <summary> + /// Currents the position timer callback. + /// </summary> + /// <param name="state">The state.</param> + private void CurrentPositionTimerCallback(object state) + { + var time = string.Empty; + + var ticks = CurrentPlayer.CurrentPositionTicks; + + if (ticks.HasValue) + { + time = GetTimeString(ticks.Value); + } + + Dispatcher.InvokeAsync(() => + { + TxtCurrentPosition.Text = time; + + if (!_isPositionSliderDragging) + { + CurrentPositionSlider.Value = ticks ?? 0; + } + }); + } + + /// <summary> + /// Gets the time string. + /// </summary> + /// <param name="ticks">The ticks.</param> + /// <returns>System.String.</returns> + private string GetTimeString(long ticks) + { + var timespan = TimeSpan.FromTicks(ticks); + + return timespan.TotalHours >= 1 ? timespan.ToString("hh':'mm':'ss") : timespan.ToString("mm':'ss"); + } + + /// <summary> + /// Handles the PlayStateChanged event of the CurrentPlayer control. + /// </summary> + /// <param name="sender">The source of the event.</param> + /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param> + void CurrentPlayer_PlayStateChanged(object sender, EventArgs e) + { + ResetButtonVisibilities(CurrentPlayer); + } + + /// <summary> + /// Resets the button visibilities. + /// </summary> + /// <param name="player">The player.</param> + private void ResetButtonVisibilities(BaseMediaPlayer player) + { + Dispatcher.Invoke(() => + { + PlayButton.Visibility = player != null && player.PlayState == PlayState.Paused ? Visibility.Visible : Visibility.Collapsed; + PauseButton.Visibility = player != null && player.CanPause && player.PlayState == PlayState.Playing ? Visibility.Visible : Visibility.Collapsed; + + StopButton.Visibility = player != null ? Visibility.Visible : Visibility.Collapsed; + MuteButton.Visibility = player != null && player.CanMute ? Visibility.Visible : Visibility.Collapsed; + VolumeUpButton.Visibility = player != null && player.CanControlVolume ? Visibility.Visible : Visibility.Collapsed; + VolumeDownButton.Visibility = player != null && player.CanControlVolume ? Visibility.Visible : Visibility.Collapsed; + + var isSeekabke = player != null && player.CanSeek && player.CurrentMedia != null; + SeekGrid.Visibility = isSeekabke ? Visibility.Visible : Visibility.Collapsed; + + var canSeekChapters = isSeekabke && player.CurrentMedia.Chapters != null && player.CurrentMedia.Chapters.Count > 1; + + NextChapterButton.Visibility = canSeekChapters ? Visibility.Visible : Visibility.Collapsed; + PreviousChapterButton.Visibility = canSeekChapters ? Visibility.Visible : Visibility.Collapsed; + }); + } + + /// <summary> + /// BTNs the application back click. + /// </summary> + /// <param name="sender">The sender.</param> + /// <param name="e">The <see cref="RoutedEventArgs" /> instance containing the event data.</param> + void BtnApplicationBackClick(object sender, RoutedEventArgs e) + { + App.Instance.ApplicationWindow.NavigateBack(); + } + + /// <summary> + /// The is position slider dragging + /// </summary> + private bool _isPositionSliderDragging; + + /// <summary> + /// Handles the DragStarted event of the CurrentPositionSlider control. + /// </summary> + /// <param name="sender">The source of the event.</param> + /// <param name="e">The <see cref="DragStartedEventArgs" /> instance containing the event data.</param> + private void CurrentPositionSlider_DragStarted(object sender, DragStartedEventArgs e) + { + _isPositionSliderDragging = true; + } + + /// <summary> + /// Handles the DragCompleted event of the CurrentPositionSlider control. + /// </summary> + /// <param name="sender">The source of the event.</param> + /// <param name="e">The <see cref="DragCompletedEventArgs" /> instance containing the event data.</param> + private void CurrentPositionSlider_DragCompleted(object sender, DragCompletedEventArgs e) + { + _isPositionSliderDragging = false; + + //await CurrentPlayer.Seek(Convert.ToInt64(CurrentPositionSlider.Value)); + } + + /// <summary> + /// Handles the PreviewMouseUp event of the CurrentPositionSlider control. + /// </summary> + /// <param name="sender">The source of the event.</param> + /// <param name="e">The <see cref="MouseButtonEventArgs" /> instance containing the event data.</param> + async void CurrentPositionSlider_PreviewMouseUp(object sender, MouseButtonEventArgs e) + { + await CurrentPlayer.Seek(Convert.ToInt64(CurrentPositionSlider.Value)); + } + } +} diff --git a/MediaBrowser.UI/Controls/NotificationMessage.xaml b/MediaBrowser.UI/Controls/NotificationMessage.xaml new file mode 100644 index 0000000000..6411b6f57a --- /dev/null +++ b/MediaBrowser.UI/Controls/NotificationMessage.xaml @@ -0,0 +1,33 @@ +<controls:BaseUserControl x:Class="MediaBrowser.UI.Controls.NotificationMessage" + 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" + xmlns:Controls="clr-namespace:MediaBrowser.UI.Controls" + xmlns:controls="clr-namespace:MediaBrowser.UI.Controls;assembly=MediaBrowser.UI.Controls" + mc:Ignorable="d" + d:DesignHeight="300" d:DesignWidth="300"> + <Grid Style="{StaticResource NotificationContentStyle}"> + <Grid Style="{StaticResource NotificationContentInnerStyle}"> + + <Grid.ColumnDefinitions> + <ColumnDefinition Width="auto"></ColumnDefinition> + <ColumnDefinition Width="*"></ColumnDefinition> + </Grid.ColumnDefinitions> + + <Grid.RowDefinitions> + <RowDefinition Height="auto"></RowDefinition> + <RowDefinition Height="auto"></RowDefinition> + <RowDefinition Height="auto"></RowDefinition> + </Grid.RowDefinitions> + + <Image Grid.Row="0" Grid.RowSpan="3" Grid.Column="0" Style="{StaticResource NotificationButtonImage}"></Image> + + <TextBlock x:Name="txtCaption" Text="{Binding Caption}" Style="{StaticResource NotificationCaptionStyle}" Grid.Row="0" Grid.Column="1"></TextBlock> + + <Grid x:Name="pnlContent" HorizontalAlignment="Stretch" Grid.Row="1" Grid.Column="1"> + + </Grid> + </Grid> + </Grid> +</controls:BaseUserControl> diff --git a/MediaBrowser.UI/Controls/NotificationMessage.xaml.cs b/MediaBrowser.UI/Controls/NotificationMessage.xaml.cs new file mode 100644 index 0000000000..06ed513b13 --- /dev/null +++ b/MediaBrowser.UI/Controls/NotificationMessage.xaml.cs @@ -0,0 +1,68 @@ +using System; +using System.Windows; +using System.Windows.Controls; + +namespace MediaBrowser.UI.Controls +{ + /// <summary> + /// Interaction logic for NotificationMessage.xaml + /// </summary> + public partial class NotificationMessage : BaseUserControl + { + public NotificationMessage() + { + InitializeComponent(); + } + + public UIElement TextContent + { + set + { + pnlContent.Children.Clear(); + + var textBlock = value as TextBlock; + + if (textBlock != null) + { + textBlock.SetResourceReference(TextBlock.StyleProperty, "NotificationTextStyle"); + } + pnlContent.Children.Add(value); + } + } + + public string Text + { + set { TextContent = new TextBlock { Text = value }; } + } + + private MessageBoxIcon _messageBoxImage; + public MessageBoxIcon MessageBoxImage + { + get { return _messageBoxImage; } + set + { + _messageBoxImage = value; + OnPropertyChanged("MessageBoxImage"); + } + } + + private string _caption; + public string Caption + { + get { return _caption; } + set + { + _caption = value; + OnPropertyChanged("Caption"); + txtCaption.Visibility = string.IsNullOrEmpty(value) ? Visibility.Collapsed : Visibility.Visible; + } + } + + protected override void OnInitialized(EventArgs e) + { + base.OnInitialized(e); + + DataContext = this; + } + } +} diff --git a/MediaBrowser.UI/Controls/TreeHelper.cs b/MediaBrowser.UI/Controls/TreeHelper.cs deleted file mode 100644 index bbe4895727..0000000000 --- a/MediaBrowser.UI/Controls/TreeHelper.cs +++ /dev/null @@ -1,226 +0,0 @@ -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
- }
-}
diff --git a/MediaBrowser.UI/Controls/WindowCommands.xaml b/MediaBrowser.UI/Controls/WindowCommands.xaml index 9209549185..bca8812385 100644 --- a/MediaBrowser.UI/Controls/WindowCommands.xaml +++ b/MediaBrowser.UI/Controls/WindowCommands.xaml @@ -1,91 +1,100 @@ -<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>
+<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"> + <Setter Property="Margin" Value="0 0 15 0"/> + <Setter Property="KeyboardNavigation.IsTabStop" Value="false"/> + <Setter Property="Padding" Value="0"/> + <Setter Property="BorderThickness" Value="0"/> + <Style.Triggers> + <Trigger Property="IsMouseOver" Value="True"> + <Setter Property="Opacity" Value=".5" /> + </Trigger> + </Style.Triggers> + </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> diff --git a/MediaBrowser.UI/Controls/WindowCommands.xaml.cs b/MediaBrowser.UI/Controls/WindowCommands.xaml.cs index 1810c5bf3f..e285cced12 100644 --- a/MediaBrowser.UI/Controls/WindowCommands.xaml.cs +++ b/MediaBrowser.UI/Controls/WindowCommands.xaml.cs @@ -1,50 +1,82 @@ -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();
- }
- }
-}
+using System.Windows; +using System.Windows.Controls; + +namespace MediaBrowser.UI.Controls +{ + /// <summary> + /// Interaction logic for WindowCommands.xaml + /// </summary> + public partial class WindowCommands : UserControl + { + /// <summary> + /// Gets the parent window. + /// </summary> + /// <value>The parent window.</value> + public Window ParentWindow + { + get { return TreeHelper.TryFindParent<Window>(this); } + } + + /// <summary> + /// Initializes a new instance of the <see cref="WindowCommands" /> class. + /// </summary> + public WindowCommands() + { + InitializeComponent(); + Loaded += WindowCommandsLoaded; + } + + /// <summary> + /// Windows the commands loaded. + /// </summary> + /// <param name="sender">The sender.</param> + /// <param name="e">The <see cref="RoutedEventArgs" /> instance containing the event data.</param> + void WindowCommandsLoaded(object sender, RoutedEventArgs e) + { + CloseApplicationButton.Click += CloseApplicationButtonClick; + MinimizeApplicationButton.Click += MinimizeApplicationButtonClick; + MaximizeApplicationButton.Click += MaximizeApplicationButtonClick; + UndoMaximizeApplicationButton.Click += UndoMaximizeApplicationButtonClick; + } + + /// <summary> + /// Undoes the maximize application button click. + /// </summary> + /// <param name="sender">The sender.</param> + /// <param name="e">The <see cref="RoutedEventArgs" /> instance containing the event data.</param> + void UndoMaximizeApplicationButtonClick(object sender, RoutedEventArgs e) + { + ParentWindow.WindowState = WindowState.Normal; + } + + /// <summary> + /// Maximizes the application button click. + /// </summary> + /// <param name="sender">The sender.</param> + /// <param name="e">The <see cref="RoutedEventArgs" /> instance containing the event data.</param> + void MaximizeApplicationButtonClick(object sender, RoutedEventArgs e) + { + ParentWindow.WindowState = WindowState.Maximized; + } + + /// <summary> + /// Minimizes the application button click. + /// </summary> + /// <param name="sender">The sender.</param> + /// <param name="e">The <see cref="RoutedEventArgs" /> instance containing the event data.</param> + void MinimizeApplicationButtonClick(object sender, RoutedEventArgs e) + { + ParentWindow.WindowState = WindowState.Minimized; + } + + /// <summary> + /// Closes the application button click. + /// </summary> + /// <param name="sender">The sender.</param> + /// <param name="e">The <see cref="RoutedEventArgs" /> instance containing the event data.</param> + void CloseApplicationButtonClick(object sender, RoutedEventArgs e) + { + App.Instance.Shutdown(); + } + } +} |
