From 0d60ce37bd3b689d8325a4fd07863682935170b4 Mon Sep 17 00:00:00 2001 From: martinivanoff Date: Thu, 24 Aug 2017 18:21:40 +0300 Subject: [PATCH] Examples update --- ComboBox/DropDownWithHeaders/App.xaml | 10 +- Common/Common_WPF.sln | 18 +- .../IconSourceDemo/IconSourceDemo_WPF.csproj | 3 + Common/IconSourceDemo/README.md | 2 +- Common/MediaPlayer.Example/App.config | 6 + Common/MediaPlayer.Example/App.xaml | 9 + Common/MediaPlayer.Example/App.xaml.cs | 17 ++ Common/MediaPlayer.Example/MainWindow.xaml | 30 ++ Common/MediaPlayer.Example/MainWindow.xaml.cs | 12 + .../MediaPlayer.Example.csproj | 125 +++++++++ .../Properties/AssemblyInfo.cs | 55 ++++ .../Properties/Resources.Designer.cs | 63 +++++ .../Properties/Resources.resx | 117 ++++++++ .../Properties/Settings.Designer.cs | 26 ++ .../Properties/Settings.settings | 7 + Common/MediaPlayer.Example/Readme.md | 4 + .../Buttons/GlyphButton.cs | 73 +++++ .../Buttons/GlyphToggleButton.cs | 79 ++++++ .../Commands/AdditionalMediaCommands.cs | 14 + Common/MediaPlayer.Library/MediaItem.cs | 64 +++++ .../MediaPlayer.Commands.cs | 67 +++++ .../MediaPlayer.Library.csproj | 116 ++++++++ .../MediaPlayer.Properties.cs | 260 ++++++++++++++++++ Common/MediaPlayer.Library/MediaPlayer.cs | 244 ++++++++++++++++ .../MediaPlayerFullscreenWrapper.cs | 186 +++++++++++++ .../Properties/AssemblyInfo.cs | 55 ++++ .../Properties/Resources.Designer.cs | 63 +++++ .../Properties/Resources.resx | 117 ++++++++ .../Properties/Settings.Designer.cs | 26 ++ .../Properties/Settings.settings | 7 + Common/MediaPlayer.Library/Readme.md | 5 + .../MediaPlayer.Library/Themes/Generic.xaml | 256 +++++++++++++++++ .../Themes/GlyphButtonsStyles.xaml | 121 ++++++++ Common/MediaPlayer.Library/TrackInfoMode.cs | 9 + 34 files changed, 2257 insertions(+), 9 deletions(-) create mode 100644 Common/MediaPlayer.Example/App.config create mode 100644 Common/MediaPlayer.Example/App.xaml create mode 100644 Common/MediaPlayer.Example/App.xaml.cs create mode 100644 Common/MediaPlayer.Example/MainWindow.xaml create mode 100644 Common/MediaPlayer.Example/MainWindow.xaml.cs create mode 100644 Common/MediaPlayer.Example/MediaPlayer.Example.csproj create mode 100644 Common/MediaPlayer.Example/Properties/AssemblyInfo.cs create mode 100644 Common/MediaPlayer.Example/Properties/Resources.Designer.cs create mode 100644 Common/MediaPlayer.Example/Properties/Resources.resx create mode 100644 Common/MediaPlayer.Example/Properties/Settings.Designer.cs create mode 100644 Common/MediaPlayer.Example/Properties/Settings.settings create mode 100644 Common/MediaPlayer.Example/Readme.md create mode 100644 Common/MediaPlayer.Library/Buttons/GlyphButton.cs create mode 100644 Common/MediaPlayer.Library/Buttons/GlyphToggleButton.cs create mode 100644 Common/MediaPlayer.Library/Commands/AdditionalMediaCommands.cs create mode 100644 Common/MediaPlayer.Library/MediaItem.cs create mode 100644 Common/MediaPlayer.Library/MediaPlayer.Commands.cs create mode 100644 Common/MediaPlayer.Library/MediaPlayer.Library.csproj create mode 100644 Common/MediaPlayer.Library/MediaPlayer.Properties.cs create mode 100644 Common/MediaPlayer.Library/MediaPlayer.cs create mode 100644 Common/MediaPlayer.Library/MediaPlayerFullscreenWrapper.cs create mode 100644 Common/MediaPlayer.Library/Properties/AssemblyInfo.cs create mode 100644 Common/MediaPlayer.Library/Properties/Resources.Designer.cs create mode 100644 Common/MediaPlayer.Library/Properties/Resources.resx create mode 100644 Common/MediaPlayer.Library/Properties/Settings.Designer.cs create mode 100644 Common/MediaPlayer.Library/Properties/Settings.settings create mode 100644 Common/MediaPlayer.Library/Readme.md create mode 100644 Common/MediaPlayer.Library/Themes/Generic.xaml create mode 100644 Common/MediaPlayer.Library/Themes/GlyphButtonsStyles.xaml create mode 100644 Common/MediaPlayer.Library/TrackInfoMode.cs diff --git a/ComboBox/DropDownWithHeaders/App.xaml b/ComboBox/DropDownWithHeaders/App.xaml index 45e68dce..62f2fd49 100644 --- a/ComboBox/DropDownWithHeaders/App.xaml +++ b/ComboBox/DropDownWithHeaders/App.xaml @@ -283,11 +283,10 @@ Foreground="{TemplateBinding Foreground}" CanContentScroll="True"> - @@ -438,11 +437,10 @@ VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}" CanContentScroll="True"> - diff --git a/Common/Common_WPF.sln b/Common/Common_WPF.sln index 48a2d6b6..3982266d 100644 --- a/Common/Common_WPF.sln +++ b/Common/Common_WPF.sln @@ -1,10 +1,15 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2012 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IconSourceDemo_WPF", "IconSourceDemo\IconSourceDemo_WPF.csproj", "{5CCA6BEC-3B2F-401F-93B3-8353E3976FA4}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaPlayer.Example", "MediaPlayer.Example\MediaPlayer.Example.csproj", "{4D7BB387-757E-4628-B074-8001F2C50BF0}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaPlayer.Library", "MediaPlayer.Library\MediaPlayer.Library.csproj", "{F489A6B0-5281-4615-B293-6AAA53FC5F99}" +EndProject Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU @@ -14,8 +19,17 @@ Global {5CCA6BEC-3B2F-401F-93B3-8353E3976FA4}.Debug|Any CPU.Build.0 = Debug|Any CPU {5CCA6BEC-3B2F-401F-93B3-8353E3976FA4}.Release|Any CPU.ActiveCfg = Release|Any CPU {5CCA6BEC-3B2F-401F-93B3-8353E3976FA4}.Release|Any CPU.Build.0 = Release|Any CPU + {4D7BB387-757E-4628-B074-8001F2C50BF0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4D7BB387-757E-4628-B074-8001F2C50BF0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4D7BB387-757E-4628-B074-8001F2C50BF0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4D7BB387-757E-4628-B074-8001F2C50BF0}.Release|Any CPU.Build.0 = Release|Any CPU + {F489A6B0-5281-4615-B293-6AAA53FC5F99}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F489A6B0-5281-4615-B293-6AAA53FC5F99}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F489A6B0-5281-4615-B293-6AAA53FC5F99}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F489A6B0-5281-4615-B293-6AAA53FC5F99}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + EndGlobal diff --git a/Common/IconSourceDemo/IconSourceDemo_WPF.csproj b/Common/IconSourceDemo/IconSourceDemo_WPF.csproj index 33bff817..244621d7 100644 --- a/Common/IconSourceDemo/IconSourceDemo_WPF.csproj +++ b/Common/IconSourceDemo/IconSourceDemo_WPF.csproj @@ -92,6 +92,9 @@ + + + + \ No newline at end of file diff --git a/Common/MediaPlayer.Example/Properties/AssemblyInfo.cs b/Common/MediaPlayer.Example/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..4d3e4a04 --- /dev/null +++ b/Common/MediaPlayer.Example/Properties/AssemblyInfo.cs @@ -0,0 +1,55 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Windows; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("MediaPlayer.Example")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("MediaPlayer.Example")] +[assembly: AssemblyCopyright("Copyright © 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +//In order to begin building localizable applications, set +//CultureYouAreCodingWith in your .csproj file +//inside a . For example, if you are using US english +//in your source files, set the to en-US. Then uncomment +//the NeutralResourceLanguage attribute below. Update the "en-US" in +//the line below to match the UICulture setting in the project file. + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] + + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Common/MediaPlayer.Example/Properties/Resources.Designer.cs b/Common/MediaPlayer.Example/Properties/Resources.Designer.cs new file mode 100644 index 00000000..e4ce7090 --- /dev/null +++ b/Common/MediaPlayer.Example/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace MediaPlayer.Example.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MediaPlayer.Example.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/Common/MediaPlayer.Example/Properties/Resources.resx b/Common/MediaPlayer.Example/Properties/Resources.resx new file mode 100644 index 00000000..af7dbebb --- /dev/null +++ b/Common/MediaPlayer.Example/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Common/MediaPlayer.Example/Properties/Settings.Designer.cs b/Common/MediaPlayer.Example/Properties/Settings.Designer.cs new file mode 100644 index 00000000..d6ad7fc8 --- /dev/null +++ b/Common/MediaPlayer.Example/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace MediaPlayer.Example.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff --git a/Common/MediaPlayer.Example/Properties/Settings.settings b/Common/MediaPlayer.Example/Properties/Settings.settings new file mode 100644 index 00000000..033d7a5e --- /dev/null +++ b/Common/MediaPlayer.Example/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/Common/MediaPlayer.Example/Readme.md b/Common/MediaPlayer.Example/Readme.md new file mode 100644 index 00000000..d856d199 --- /dev/null +++ b/Common/MediaPlayer.Example/Readme.md @@ -0,0 +1,4 @@ +## Media Player ## +This example shows how to create and use MediaPlayer custom control using the WPF native controls and customized RadButtons. See the MediaPlayer.Library project for the MediaPlayer implementation. + + \ No newline at end of file diff --git a/Common/MediaPlayer.Library/Buttons/GlyphButton.cs b/Common/MediaPlayer.Library/Buttons/GlyphButton.cs new file mode 100644 index 00000000..f900c48e --- /dev/null +++ b/Common/MediaPlayer.Library/Buttons/GlyphButton.cs @@ -0,0 +1,73 @@ +using System; +using System.Windows; +using System.Windows.Media; +using Telerik.Windows.Controls; + +namespace MediaPlayer.Library +{ + public class GlyphButton : RadButton + { + static GlyphButton() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(GlyphButton), new FrameworkPropertyMetadata(typeof(GlyphButton))); + } + + public static readonly DependencyProperty GlyphValueProperty = + DependencyProperty.Register( + "GlyphValue", + typeof(string), + typeof(GlyphButton), + new PropertyMetadata(null)); + + public static readonly DependencyProperty GlyphSizeProperty = + DependencyProperty.Register( + "GlyphSize", + typeof(double), + typeof(GlyphButton), + new PropertyMetadata(0d)); + + public static readonly DependencyProperty GlyphMarginProperty = + DependencyProperty.Register( + "GlyphMargin", + typeof(Thickness), + typeof(GlyphButton), + new PropertyMetadata(new Thickness())); + + public static readonly DependencyProperty GlyphBrushProperty = + DependencyProperty.Register( + "GlyphBrush", + typeof(Brush), + typeof(GlyphButton), + new PropertyMetadata(null)); + + public string GlyphValue + { + get { return (string)GetValue(GlyphValueProperty); } + set { SetValue(GlyphValueProperty, value); } + } + + public double GlyphSize + { + get { return (double)GetValue(GlyphSizeProperty); } + set { SetValue(GlyphSizeProperty, value); } + } + + public Thickness GlyphMargin + { + get { return (Thickness)GetValue(GlyphMarginProperty); } + set { SetValue(GlyphMarginProperty, value); } + } + + public Brush GlyphBrush + { + get { return (Brush)GetValue(GlyphBrushProperty); } + set { SetValue(GlyphBrushProperty, value); } + } + + protected override void OnInitialized(EventArgs e) + { + base.OnInitialized(e); + StyleManager.SetDefaultStyleKey(this, typeof(GlyphButton)); + } + } +} diff --git a/Common/MediaPlayer.Library/Buttons/GlyphToggleButton.cs b/Common/MediaPlayer.Library/Buttons/GlyphToggleButton.cs new file mode 100644 index 00000000..c348fee8 --- /dev/null +++ b/Common/MediaPlayer.Library/Buttons/GlyphToggleButton.cs @@ -0,0 +1,79 @@ +using System.Windows; +using System.Windows.Media; +using Telerik.Windows.Controls; + +namespace MediaPlayer.Library +{ + public class GlyphToggleButton : RadToggleButton + { + static GlyphToggleButton() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(GlyphToggleButton), new FrameworkPropertyMetadata(typeof(GlyphToggleButton))); + } + + public static readonly DependencyProperty GlyphValueProperty = + DependencyProperty.Register( + "GlyphValue", + typeof(string), + typeof(GlyphToggleButton), + new PropertyMetadata(null)); + + public static readonly DependencyProperty ToggledGlyphValueProperty = + DependencyProperty.Register( + "ToggledGlyphValue", + typeof(string), + typeof(GlyphToggleButton), + new PropertyMetadata(string.Empty)); + + public static readonly DependencyProperty GlyphSizeProperty = + DependencyProperty.Register( + "GlyphSize", + typeof(double), + typeof(GlyphToggleButton), + new PropertyMetadata(0d)); + + public static readonly DependencyProperty GlyphMarginProperty = + DependencyProperty.Register( + "GlyphMargin", + typeof(Thickness), + typeof(GlyphToggleButton), + new PropertyMetadata(new Thickness())); + + public static readonly DependencyProperty GlyphBrushProperty = + DependencyProperty.Register( + "GlyphBrush", + typeof(Brush), + typeof(GlyphToggleButton), + new PropertyMetadata(null)); + + public string GlyphValue + { + get { return (string)GetValue(GlyphValueProperty); } + set { SetValue(GlyphValueProperty, value); } + } + + public string ToggledGlyphValue + { + get { return (string)GetValue(ToggledGlyphValueProperty); } + set { SetValue(ToggledGlyphValueProperty, value); } + } + + public double GlyphSize + { + get { return (double)GetValue(GlyphSizeProperty); } + set { SetValue(GlyphSizeProperty, value); } + } + + public Thickness GlyphMargin + { + get { return (Thickness)GetValue(GlyphMarginProperty); } + set { SetValue(GlyphMarginProperty, value); } + } + + public Brush GlyphBrush + { + get { return (Brush)GetValue(GlyphBrushProperty); } + set { SetValue(GlyphBrushProperty, value); } + } + } +} diff --git a/Common/MediaPlayer.Library/Commands/AdditionalMediaCommands.cs b/Common/MediaPlayer.Library/Commands/AdditionalMediaCommands.cs new file mode 100644 index 00000000..38d720fe --- /dev/null +++ b/Common/MediaPlayer.Library/Commands/AdditionalMediaCommands.cs @@ -0,0 +1,14 @@ +using System.Windows.Input; + +namespace MediaPlayer.Library +{ + public static class AdditionalMediaCommands + { + public static RoutedUICommand ToggleFullscreenCommand { get; set; } + + static AdditionalMediaCommands() + { + ToggleFullscreenCommand = new RoutedUICommand("Toggle full screen", "ToggleFullscreenCommand", typeof(AdditionalMediaCommands)); + } + } +} diff --git a/Common/MediaPlayer.Library/MediaItem.cs b/Common/MediaPlayer.Library/MediaItem.cs new file mode 100644 index 00000000..65423b85 --- /dev/null +++ b/Common/MediaPlayer.Library/MediaItem.cs @@ -0,0 +1,64 @@ +using System; +using System.ComponentModel; +using System.IO; +using System.Runtime.CompilerServices; + +namespace MediaPlayer.Library +{ + public class MediaItem + { + private static string[] videoExtensions = { ".AVI", ".MP4", ".DIVX", ".WMV", ".MKV" }; + + private Uri source; + private string mediaName; + + public Uri Source + { + get { return source; } + set + { + if (this.source != value) + { + this.source = value; + this.OnPropertyChanged("Source"); + } + } + } + + public string MediaName + { + get { return mediaName; } + set + { + if (this.mediaName != value) + { + this.mediaName = value; + this.OnPropertyChanged("MediaName"); + } + } + } + + public bool IsVideo + { + get + { + return IsVideoFile(this.source.AbsoluteUri); + } + } + + private static bool IsVideoFile(string path) + { + return -1 != Array.IndexOf(videoExtensions, Path.GetExtension(path).ToUpperInvariant()); + } + + public event PropertyChangedEventHandler PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] String propertyName = "") + { + if (PropertyChanged != null) + { + PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + } + } + } +} diff --git a/Common/MediaPlayer.Library/MediaPlayer.Commands.cs b/Common/MediaPlayer.Library/MediaPlayer.Commands.cs new file mode 100644 index 00000000..1bafe290 --- /dev/null +++ b/Common/MediaPlayer.Library/MediaPlayer.Commands.cs @@ -0,0 +1,67 @@ +using System; +using System.Windows.Input; + +namespace MediaPlayer.Library +{ + public partial class MediaPlayer + { + private void RegisterCommandBindings() + { + CommandBinding playCommandBinding = new CommandBinding(MediaCommands.Play, OnPlayCommandExecuted, OnPlayCommandCanExecute); + this.CommandBindings.Add(playCommandBinding); + + CommandBinding stopCommandBinding = new CommandBinding(MediaCommands.Stop, OnStopCommandExecuted, OnStopCommandCanExecute); + this.CommandBindings.Add(stopCommandBinding); + + CommandBinding togglePlayPauseCommandBinding = new CommandBinding(MediaCommands.TogglePlayPause, OnTogglePlayPauseCommandExecuted); + this.CommandBindings.Add(togglePlayPauseCommandBinding); + + CommandBinding muteVolumeCommandBinding = new CommandBinding(MediaCommands.MuteVolume, OnMuteVolumeCommandExecuted); + this.CommandBindings.Add(muteVolumeCommandBinding); + + CommandBinding selectCommandBinding = new CommandBinding(MediaCommands.Select, OnSelectCommandExecuted); + this.CommandBindings.Add(selectCommandBinding); + } + + private void OnPlayCommandCanExecute(object sender, CanExecuteRoutedEventArgs e) + { + e.CanExecute = !this.IsPlaying; + } + + private void OnPlayCommandExecuted(object sender, ExecutedRoutedEventArgs e) + { + this.Play(); + } + + private void OnStopCommandCanExecute(object sender, CanExecuteRoutedEventArgs e) + { + e.CanExecute = this.IsPlaying; + } + + private void OnStopCommandExecuted(object sender, ExecutedRoutedEventArgs e) + { + this.Stop(); + } + + private void OnTogglePlayPauseCommandExecuted(object sender, ExecutedRoutedEventArgs e) + { + this.TogglePlayPause(); + } + + private void OnMuteVolumeCommandExecuted(object sender, ExecutedRoutedEventArgs e) + { + this.IsMuted ^= true; + } + + private void OnSelectCommandExecuted(object sender, ExecutedRoutedEventArgs e) + { + MediaItem selectedItem = e.Parameter as MediaItem; + if (selectedItem != null) + { + this.CurrentPlaylistItem = selectedItem; + this.Position = TimeSpan.Zero; + this.Play(); + } + } + } +} diff --git a/Common/MediaPlayer.Library/MediaPlayer.Library.csproj b/Common/MediaPlayer.Library/MediaPlayer.Library.csproj new file mode 100644 index 00000000..80269c8b --- /dev/null +++ b/Common/MediaPlayer.Library/MediaPlayer.Library.csproj @@ -0,0 +1,116 @@ + + + + + Debug + AnyCPU + {F489A6B0-5281-4615-B293-6AAA53FC5F99} + library + Properties + MediaPlayer.Library + MediaPlayer.Library + v4.5 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + + + + + + + + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + 4.0 + + + False + $(TELERIKWPFDIR)\Binaries\WPF40\Telerik.Windows.Controls.dll + + + + + + + + + + + MSBuild:Compile + Designer + + + + + + + + + MSBuild:Compile + Designer + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + ResXFileCodeGenerator + Resources.Designer.cs + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + + + \ No newline at end of file diff --git a/Common/MediaPlayer.Library/MediaPlayer.Properties.cs b/Common/MediaPlayer.Library/MediaPlayer.Properties.cs new file mode 100644 index 00000000..1c0a0ff6 --- /dev/null +++ b/Common/MediaPlayer.Library/MediaPlayer.Properties.cs @@ -0,0 +1,260 @@ +using System; +using System.Collections.ObjectModel; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Media; + +namespace MediaPlayer.Library +{ + public partial class MediaPlayer + { + private ObservableCollection playlist; + + public static readonly DependencyProperty CurrentPlaylistItemProperty = + DependencyProperty.Register( + "CurrentPlaylistItem", + typeof(MediaItem), + typeof(MediaPlayer), + new PropertyMetadata(null, OnCurrentPlaylistItemChanged)); + + public static readonly DependencyProperty PositionProperty = + DependencyProperty.Register( + "Position", + typeof(TimeSpan), + typeof(MediaPlayer), + new PropertyMetadata(TimeSpan.Zero, OnPositionChanged)); + + public static readonly DependencyProperty VolumeProperty = + DependencyProperty.Register( + "Volume", + typeof(double), + typeof(MediaPlayer), + new PropertyMetadata(0.5, OnVolumeChanged)); + + public static readonly DependencyProperty IsPlayingProperty = + DependencyProperty.Register( + "IsPlaying", + typeof(bool), + typeof(MediaPlayer), + new PropertyMetadata(false)); + + public static readonly DependencyProperty IsMutedProperty = + DependencyProperty.Register( + "IsMuted", + typeof(bool), + typeof(MediaPlayer), + new PropertyMetadata(false, OnIsMutedChanged)); + + public static readonly DependencyProperty IsPlaylistOpenProperty = + DependencyProperty.Register( + "IsPlaylistOpen", + typeof(bool), + typeof(MediaPlayer), + new PropertyMetadata(false)); + + public static readonly DependencyProperty PlaylistItemTemplateProperty = + DependencyProperty.Register( + "PlaylistItemTemplate", + typeof(DataTemplate), + typeof(MediaPlayer), + new PropertyMetadata(null)); + + public static readonly DependencyProperty AdditionalMediaControlContentProperty = + DependencyProperty.Register( + "AdditionalMediaControlContent", + typeof(object), + typeof(MediaPlayer), + new PropertyMetadata(null)); + + public static readonly DependencyProperty AdditionalSettingsContentProperty = + DependencyProperty.Register( + "AdditionalSettingsContent", + typeof(object), + typeof(MediaPlayer), + new PropertyMetadata(null)); + + public static readonly DependencyProperty TrackInfoModeProperty = + DependencyProperty.Register( + "TrackInfoMode", + typeof(TrackInfoMode), + typeof(MediaPlayer), + new PropertyMetadata(TrackInfoMode.CurrentAndEndTime, OnTrackInfoModeChanged)); + + public static readonly DependencyProperty VideoControlsPanelVisibilityProperty = + DependencyProperty.Register( + "VideoControlsPanelVisibility", + typeof(Visibility), + typeof(MediaPlayer), + new PropertyMetadata(Visibility.Visible)); + + public static readonly DependencyProperty MediaStretchProperty = + DependencyProperty.Register( + "MediaStretch", + typeof(Stretch), + typeof(MediaPlayer), + new PropertyMetadata(Stretch.Uniform)); + + public static readonly DependencyProperty MediaStretchDirectionProperty = + DependencyProperty.Register( + "MediaStretchDirection", + typeof(StretchDirection), + typeof(MediaPlayer), + new PropertyMetadata(StretchDirection.Both)); + + public MediaItem CurrentPlaylistItem + { + get { return (MediaItem)GetValue(CurrentPlaylistItemProperty); } + set { SetValue(CurrentPlaylistItemProperty, value); } + } + + public TimeSpan Position + { + get { return (TimeSpan)GetValue(PositionProperty); } + set { SetValue(PositionProperty, value); } + } + + public double Volume + { + get { return (double)GetValue(VolumeProperty); } + set { SetValue(VolumeProperty, value); } + } + + public bool IsPlaying + { + get { return (bool)GetValue(IsPlayingProperty); } + private set { SetValue(IsPlayingProperty, value); } + } + + public bool IsMuted + { + get { return (bool)GetValue(IsMutedProperty); } + set { SetValue(IsMutedProperty, value); } + } + + public bool IsPlaylistOpen + { + get { return (bool)GetValue(IsPlaylistOpenProperty); } + set { SetValue(IsPlaylistOpenProperty, value); } + } + + public DataTemplate PlaylistItemTemplate + { + get { return (DataTemplate)GetValue(PlaylistItemTemplateProperty); } + set { SetValue(PlaylistItemTemplateProperty, value); } + } + + public object AdditionalMediaControlContent + { + get { return (object)GetValue(AdditionalMediaControlContentProperty); } + set { SetValue(AdditionalMediaControlContentProperty, value); } + } + + public object AdditionalSettingsContent + { + get { return (object)GetValue(AdditionalSettingsContentProperty); } + set { SetValue(AdditionalSettingsContentProperty, value); } + } + + public TrackInfoMode TrackInfoMode + { + get { return (TrackInfoMode)GetValue(TrackInfoModeProperty); } + set { SetValue(TrackInfoModeProperty, value); } + } + + public Visibility VideoControlsPanelVisibility + { + get { return (Visibility)GetValue(VideoControlsPanelVisibilityProperty); } + set { SetValue(VideoControlsPanelVisibilityProperty, value); } + } + + public Stretch MediaStretch + { + get { return (Stretch)GetValue(MediaStretchProperty); } + set { SetValue(MediaStretchProperty, value); } + } + + public StretchDirection MediaStretchDirection + { + get { return (StretchDirection)GetValue(MediaStretchDirectionProperty); } + set { SetValue(MediaStretchDirectionProperty, value); } + } + + public ObservableCollection Playlist + { + get + { + if (this.playlist == null) + { + this.playlist = new ObservableCollection(); + } + return this.playlist; + } + } + + private static void OnPositionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var mediaPlayer = (MediaPlayer)d; + if (mediaPlayer.mediaElement != null) + { + var newPosition = (TimeSpan)e.NewValue; + mediaPlayer.UpdateTrackBarValue(newPosition.TotalSeconds); + mediaPlayer.mediaElement.Position = newPosition; + mediaPlayer.UpdateTrackBarInfo(); + + if (mediaPlayer.mediaElement.NaturalDuration.HasTimeSpan && + newPosition == mediaPlayer.mediaElement.NaturalDuration.TimeSpan) + { + mediaPlayer.Stop(); + } + } + } + + private static void OnCurrentPlaylistItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var mediaPlayer = (MediaPlayer)d; + if (e.NewValue != null) + { + if (mediaPlayer.IsPlaying) + { + mediaPlayer.Stop(); + } + mediaPlayer.IsPlaylistOpen = false; + } + } + + private static void OnVolumeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var mediaPlayer = (MediaPlayer)d; + double newVolume = (double)e.NewValue; + if (newVolume > 0) + { + mediaPlayer.IsMuted = false; + } + } + + private static void OnIsMutedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var mediaPlayer = (MediaPlayer)d; + bool isMuted = (bool)e.NewValue; + if (isMuted) + { + mediaPlayer.cachedVolume = mediaPlayer.Volume; + mediaPlayer.Volume = 0; + } + else + { + if (mediaPlayer.Volume == 0) + { + mediaPlayer.Volume = mediaPlayer.cachedVolume; + } + mediaPlayer.cachedVolume = -1; + } + } + + private static void OnTrackInfoModeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var mediaPlayer = (MediaPlayer)d; + mediaPlayer.UpdateTrackBarInfo(); + } + } +} diff --git a/Common/MediaPlayer.Library/MediaPlayer.cs b/Common/MediaPlayer.Library/MediaPlayer.cs new file mode 100644 index 00000000..5d014fa3 --- /dev/null +++ b/Common/MediaPlayer.Library/MediaPlayer.cs @@ -0,0 +1,244 @@ +using System; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Input; +using System.Windows.Threading; +using Telerik.Windows.Controls; + +namespace MediaPlayer.Library +{ + public partial class MediaPlayer : ContentControl + { + private const string DefaultTrackInfoValueFormatString = "hh\\:mm\\:ss"; + private const string DefaultTrackInfoLayoutFormatString = "{0} / {1}"; + + private DispatcherTimer trackBarMediaPositionSyncTimer; + private MediaElement mediaElement; + private TextBlock trackInfo; + private RadSlider trackBar; + + private double cachedVolume = -1; + private bool isTrackbarValueUpdating = false; + private bool shouldNormalizeTrackBarValue = false; + + static MediaPlayer() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(MediaPlayer), new FrameworkPropertyMetadata(typeof(MediaPlayer))); + } + + public MediaPlayer() + { + this.RegisterCommandBindings(); + this.Unloaded += OnUnloaded; + this.Loaded += OnLoaded; + } + + public override void OnApplyTemplate() + { + base.OnApplyTemplate(); + + this.mediaElement = GetTemplateChild("PART_MediaElement") as MediaElement; + this.trackInfo = GetTemplateChild("PART_TrackInfo") as TextBlock; + this.trackBar = GetTemplateChild("PART_ProgressTrackBar") as RadSlider; + this.UpdateTrackBarInfo(); + + this.shouldNormalizeTrackBarValue = true; + } + + public void Play() + { + if (this.mediaElement != null && this.CurrentPlaylistItem != null) + { + this.mediaElement.Play(); + this.trackBarMediaPositionSyncTimer.Start(); + this.IsPlaying = true; + } + } + + public void Pause() + { + if (this.mediaElement != null && this.mediaElement.CanPause) + { + this.mediaElement.Pause(); + this.trackBarMediaPositionSyncTimer.Stop(); + this.IsPlaying = false; + } + } + + public void TogglePlayPause() + { + if (this.IsPlaying) + { + this.Pause(); + } + else + { + this.Play(); + } + } + + public void Stop() + { + if (this.mediaElement != null) + { + this.mediaElement.Stop(); + this.trackBarMediaPositionSyncTimer.Stop(); + this.Position = TimeSpan.Zero; + this.IsPlaying = false; + } + } + + protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) + { + this.Focus(); + } + + protected override void OnKeyDown(KeyEventArgs e) + { + if (e.Key == Key.Space) + { + this.TogglePlayPause(); + } + } + + protected virtual string GetProgressTrackInfo(Duration naturalDuration, TimeSpan currentPosition, TrackInfoMode mode) + { + if (mode == TrackInfoMode.CurrentAndEndTime) + { + if (naturalDuration == Duration.Automatic) + { + return string.Format(DefaultTrackInfoLayoutFormatString, TimeSpan.Zero.ToString(DefaultTrackInfoValueFormatString), TimeSpan.Zero.ToString(DefaultTrackInfoValueFormatString)); + } + return string.Format(DefaultTrackInfoLayoutFormatString, currentPosition.ToString(DefaultTrackInfoValueFormatString), naturalDuration.TimeSpan.ToString(DefaultTrackInfoValueFormatString)); + } + else if (mode == TrackInfoMode.CurrentTime) + { + if (naturalDuration == Duration.Automatic) + { + return TimeSpan.Zero.ToString(DefaultTrackInfoValueFormatString); + } + return currentPosition.ToString(DefaultTrackInfoValueFormatString); + } + else + { + if (naturalDuration == Duration.Automatic) + { + return TimeSpan.Zero.ToString(DefaultTrackInfoValueFormatString); + } + return (naturalDuration.TimeSpan - currentPosition).ToString(DefaultTrackInfoValueFormatString); + } + } + + protected virtual void OnMediaFailed(object sender, ExceptionRoutedEventArgs e) + { + MessageBox.Show(e.ErrorException.Message); + } + + private void OnTrackBarMediaPositionSyncTimerTick(object sender, EventArgs e) + { + if (this.trackBarMediaPositionSyncTimer.IsEnabled) + { + this.Position = this.mediaElement.Position; + } + } + + private void OnMediaElementMediaOpened(object sender, RoutedEventArgs e) + { + this.UpdateTrackBarMaximum(); + this.TryNormalizeTrackBarValue(); + } + + private void OnTrackBarValueChanged(object sender, RoutedPropertyChangedEventArgs e) + { + if (!this.isTrackbarValueUpdating) + { + this.Position = TimeSpan.FromSeconds(e.NewValue); + } + } + + private void OnLoaded(object sender, RoutedEventArgs e) + { + this.SetupSyncTimer(); + + if (this.mediaElement != null) + { + this.mediaElement.MediaOpened += OnMediaElementMediaOpened; + this.mediaElement.MediaFailed += OnMediaFailed; + } + + if (this.trackBar != null) + { + this.trackBar.ValueChanged += OnTrackBarValueChanged; + } + + if (this.trackInfo != null) + { + this.trackInfo.MouseLeftButtonDown += OnTrackInfoMouseLeftButtonDown; + } + + if (this.CurrentPlaylistItem == null && this.Playlist.Count > 0) + { + this.CurrentPlaylistItem = this.Playlist[0]; + } + } + + private void OnUnloaded(object sender, RoutedEventArgs e) + { + this.Stop(); + this.trackBarMediaPositionSyncTimer.Tick -= OnTrackBarMediaPositionSyncTimerTick; + this.mediaElement.MediaOpened -= OnMediaElementMediaOpened; + this.mediaElement.MediaFailed -= OnMediaFailed; + this.trackBar.ValueChanged -= OnTrackBarValueChanged; + this.trackInfo.MouseLeftButtonDown -= OnTrackInfoMouseLeftButtonDown; + this.Unloaded -= OnUnloaded; + } + + private void OnTrackInfoMouseLeftButtonDown(object sender, MouseButtonEventArgs e) + { + var values = (TrackInfoMode[])Enum.GetValues(typeof(TrackInfoMode)); + var currentIndex = Array.IndexOf(values, this.TrackInfoMode) + 1; + TrackInfoMode newMode = (values.Length == currentIndex) ? values[0] : values[currentIndex]; + this.TrackInfoMode = newMode; + } + + private void SetupSyncTimer() + { + this.trackBarMediaPositionSyncTimer = new DispatcherTimer(); + this.trackBarMediaPositionSyncTimer.Interval = TimeSpan.FromSeconds(1); + this.trackBarMediaPositionSyncTimer.Tick += OnTrackBarMediaPositionSyncTimerTick; + } + + private void UpdateTrackBarValue(double value) + { + this.isTrackbarValueUpdating = true; + this.trackBar.Value = value; + this.isTrackbarValueUpdating = false; + } + + private void UpdateTrackBarInfo() + { + if (this.trackInfo != null && this.mediaElement != null) + { + this.trackInfo.Text = GetProgressTrackInfo(this.mediaElement.NaturalDuration, this.mediaElement.Position, this.TrackInfoMode); + } + } + + private void UpdateTrackBarMaximum() + { + if (this.mediaElement.NaturalDuration != Duration.Automatic) + { + this.trackBar.Maximum = this.mediaElement.NaturalDuration.TimeSpan.TotalSeconds; + } + } + + private void TryNormalizeTrackBarValue() + { + if (this.shouldNormalizeTrackBarValue) + { + double normalizedValue = this.trackBar.Value * this.trackBar.Maximum; + this.Position = TimeSpan.FromSeconds(normalizedValue); + this.shouldNormalizeTrackBarValue = false; + } + } + } +} diff --git a/Common/MediaPlayer.Library/MediaPlayerFullscreenWrapper.cs b/Common/MediaPlayer.Library/MediaPlayerFullscreenWrapper.cs new file mode 100644 index 00000000..953c819a --- /dev/null +++ b/Common/MediaPlayer.Library/MediaPlayerFullscreenWrapper.cs @@ -0,0 +1,186 @@ +using System.Windows; +using System.Windows.Controls; +using System.Windows.Input; +using System.Windows.Markup; + +namespace MediaPlayer.Library +{ + /// + /// A control that allows you to display the MediaPlayer control in a fullscreen mode. + /// + [ContentProperty("MediaPlayer")] + public class MediaPlayerFullscreenWrapper : Control + { + private const double ShowVideoControlsPanelOffset = 50; + + private bool requestToggleFullscreen = false; + private Window fullscreenPresenter; + private ContentControl contentPresenter; + + static MediaPlayerFullscreenWrapper() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(MediaPlayerFullscreenWrapper), new FrameworkPropertyMetadata(typeof(MediaPlayerFullscreenWrapper))); + } + + public static readonly DependencyProperty MediaPlayerProperty = + DependencyProperty.Register( + "MediaPlayer", + typeof(MediaPlayer), + typeof(MediaPlayerFullscreenWrapper), + new PropertyMetadata(null, OnMediaPlayerChanged)); + + public static readonly DependencyProperty IsFullscreenProperty = + DependencyProperty.Register( + "IsFullscreen", + typeof(bool), + typeof(MediaPlayerFullscreenWrapper), + new PropertyMetadata(false, OnIsFullscreenChanged)); + + public MediaPlayer MediaPlayer + { + get { return (MediaPlayer)GetValue(MediaPlayerProperty); } + set { SetValue(MediaPlayerProperty, value); } + } + + public bool IsFullscreen + { + get { return (bool)GetValue(IsFullscreenProperty); } + set { SetValue(IsFullscreenProperty, value); } + } + + public MediaPlayerFullscreenWrapper() + { + this.Unloaded += OnUnloaded; + } + + public override void OnApplyTemplate() + { + base.OnApplyTemplate(); + this.contentPresenter = this.GetTemplateChild("PART_MediaPlayerPresenter") as ContentControl; + + if (this.requestToggleFullscreen) + { + this.GoToFullscreen(); + } + } + + private void OnUnloaded(object sender, RoutedEventArgs e) + { + this.CloseFullscreen(); + } + + private static void OnMediaPlayerChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + if (e.NewValue != null) + { + MediaPlayerFullscreenWrapper wrapper = (MediaPlayerFullscreenWrapper)d; + MediaPlayer mediaPlayer = (MediaPlayer)e.NewValue; + + CommandBinding fullscreenCommandBinding = new CommandBinding(AdditionalMediaCommands.ToggleFullscreenCommand, wrapper.OnToggleFullscreenExecuted); + mediaPlayer.CommandBindings.Add(fullscreenCommandBinding); + } + } + + private static void OnIsFullscreenChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var wrapper = (MediaPlayerFullscreenWrapper)d; + if (wrapper. MediaPlayer == null) + { + wrapper.requestToggleFullscreen = true; + return; + } + + if ((bool)e.NewValue) + { + wrapper.GoToFullscreen(); + } + else + { + wrapper.CloseFullscreen(); + } + } + + private void OnToggleFullscreenExecuted(object sender, ExecutedRoutedEventArgs e) + { + this.IsFullscreen = (this.fullscreenPresenter == null); + } + + private void OnFullscreenPresenterKeyDown(object sender, KeyEventArgs e) + { + if (e.Key == Key.Escape) + { + this.IsFullscreen = false; + } + } + + private void OnFullscreenPresenterMouseMove(object sender, MouseEventArgs e) + { + this.UpdateVideoControlsPanelVisibility(e.GetPosition(this.fullscreenPresenter)); + } + + private Window CreateFullscreenPresenter(MediaPlayer mediaPlayer) + { + var presenter = new Window(); + presenter.Content = mediaPlayer; + presenter.WindowStartupLocation = WindowStartupLocation.Manual; + presenter.WindowStyle = WindowStyle.None; + presenter.KeyDown += OnFullscreenPresenterKeyDown; + presenter.MouseMove += OnFullscreenPresenterMouseMove; + + + return presenter; + } + + private void MaximizeFullscreenPresenter() + { + if (this.fullscreenPresenter != null && this.fullscreenPresenter.IsLoaded) + { + this.fullscreenPresenter.Left = Window.GetWindow(this).Left; + this.fullscreenPresenter.Top = Window.GetWindow(this).Top; + this.fullscreenPresenter.Topmost = true; + this.fullscreenPresenter.WindowState = WindowState.Maximized; + } + } + + private void GoToFullscreen() + { + var isPlaying = this.MediaPlayer.IsPlaying; + var playerPosition = this.MediaPlayer.Position; + this.contentPresenter.Content = null; + this.fullscreenPresenter = this.CreateFullscreenPresenter(this.MediaPlayer); + this.fullscreenPresenter.Show(); + this.fullscreenPresenter.Activate(); + this.MaximizeFullscreenPresenter(); + this.MediaPlayer.Position = playerPosition; + if (isPlaying) + { + this.MediaPlayer.Play(); + } + } + + private void CloseFullscreen() + { + this.fullscreenPresenter.Content = null; + this.fullscreenPresenter.Close(); + this.contentPresenter.Content = this.MediaPlayer; + this.fullscreenPresenter.KeyDown -= OnFullscreenPresenterKeyDown; + this.fullscreenPresenter.MouseMove -= OnFullscreenPresenterMouseMove; + this.fullscreenPresenter = null; + + this.MediaPlayer.VideoControlsPanelVisibility = Visibility.Visible; + } + + private void UpdateVideoControlsPanelVisibility(Point mousePosition) + { + double delta = (this.fullscreenPresenter.ActualHeight - mousePosition.Y); + if (delta <= ShowVideoControlsPanelOffset) + { + this.MediaPlayer.VideoControlsPanelVisibility = Visibility.Visible; + } + else if (delta > ShowVideoControlsPanelOffset && this.MediaPlayer.VideoControlsPanelVisibility == Visibility.Visible) + { + this.MediaPlayer.VideoControlsPanelVisibility = Visibility.Collapsed; + } + } + } +} diff --git a/Common/MediaPlayer.Library/Properties/AssemblyInfo.cs b/Common/MediaPlayer.Library/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..dfd4b700 --- /dev/null +++ b/Common/MediaPlayer.Library/Properties/AssemblyInfo.cs @@ -0,0 +1,55 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Windows; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("MediaPlayer.Library")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("MediaPlayer.Library")] +[assembly: AssemblyCopyright("Copyright © 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +//In order to begin building localizable applications, set +//CultureYouAreCodingWith in your .csproj file +//inside a . For example, if you are using US english +//in your source files, set the to en-US. Then uncomment +//the NeutralResourceLanguage attribute below. Update the "en-US" in +//the line below to match the UICulture setting in the project file. + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly:ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] + + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Common/MediaPlayer.Library/Properties/Resources.Designer.cs b/Common/MediaPlayer.Library/Properties/Resources.Designer.cs new file mode 100644 index 00000000..6d08ad23 --- /dev/null +++ b/Common/MediaPlayer.Library/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace MediaPlayer.Library.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MediaPlayer.Library.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/Common/MediaPlayer.Library/Properties/Resources.resx b/Common/MediaPlayer.Library/Properties/Resources.resx new file mode 100644 index 00000000..af7dbebb --- /dev/null +++ b/Common/MediaPlayer.Library/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Common/MediaPlayer.Library/Properties/Settings.Designer.cs b/Common/MediaPlayer.Library/Properties/Settings.Designer.cs new file mode 100644 index 00000000..83934b9b --- /dev/null +++ b/Common/MediaPlayer.Library/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace MediaPlayer.Library.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff --git a/Common/MediaPlayer.Library/Properties/Settings.settings b/Common/MediaPlayer.Library/Properties/Settings.settings new file mode 100644 index 00000000..033d7a5e --- /dev/null +++ b/Common/MediaPlayer.Library/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/Common/MediaPlayer.Library/Readme.md b/Common/MediaPlayer.Library/Readme.md new file mode 100644 index 00000000..0e99f435 --- /dev/null +++ b/Common/MediaPlayer.Library/Readme.md @@ -0,0 +1,5 @@ +## Media Player ## +This example shows how to create a MediaPlayer custom control using the WPF native controls and customized RadButtons. The MediaPlayerFullscreenWrapper control allows you to show the MediaPlayer in a fullscreen mode, but it is not a mandatory to use it. +See the MediaPlayer.Example project for an example usage of the control. + + \ No newline at end of file diff --git a/Common/MediaPlayer.Library/Themes/Generic.xaml b/Common/MediaPlayer.Library/Themes/Generic.xaml new file mode 100644 index 00000000..395c0281 --- /dev/null +++ b/Common/MediaPlayer.Library/Themes/Generic.xaml @@ -0,0 +1,256 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Common/MediaPlayer.Library/Themes/GlyphButtonsStyles.xaml b/Common/MediaPlayer.Library/Themes/GlyphButtonsStyles.xaml new file mode 100644 index 00000000..f991e0bd --- /dev/null +++ b/Common/MediaPlayer.Library/Themes/GlyphButtonsStyles.xaml @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +