From 17c1fd576057bdd2d6aea517d733fe8af6e6b2ba Mon Sep 17 00:00:00 2001 From: LukePulverenti Date: Sat, 23 Feb 2013 10:58:08 -0500 Subject: [PATCH] moved ui to it's own repo --- .../Controls/BaseItemTile.xaml | 23 - .../Controls/BaseItemTile.xaml.cs | 177 --- .../Controls/Details/BaseDetailsControl.cs | 44 - .../Controls/Details/ItemChapters.xaml | 23 - .../Controls/Details/ItemChapters.xaml.cs | 67 - .../Controls/Details/ItemGallery.xaml | 23 - .../Controls/Details/ItemGallery.xaml.cs | 163 -- .../Controls/Details/ItemMediaInfo.xaml | 22 - .../Controls/Details/ItemMediaInfo.xaml.cs | 49 - .../Controls/Details/ItemOverview.xaml | 68 - .../Controls/Details/ItemOverview.xaml.cs | 109 -- .../Controls/Details/ItemPerformers.xaml | 23 - .../Controls/Details/ItemPerformers.xaml.cs | 72 - .../Controls/Details/ItemSpecialFeatures.xaml | 23 - .../Details/ItemSpecialFeatures.xaml.cs | 77 - .../Controls/Details/ItemTrailers.xaml | 23 - .../Controls/Details/ItemTrailers.xaml.cs | 82 - .../Controls/Details/MediaStreamControl.xaml | 18 - .../Details/MediaStreamControl.xaml.cs | 142 -- .../Controls/HomePageTile.xaml | 22 - .../Controls/HomePageTile.xaml.cs | 128 -- .../Controls/MultiItemTile.xaml | 30 - .../Controls/MultiItemTile.xaml.cs | 219 --- .../Converters/WeatherImageConverter.cs | 48 - .../BaseDisplayPreferencesPage.cs | 25 - .../DisplayPreferencesMenu.xaml | 47 - .../DisplayPreferencesMenu.xaml.cs | 92 -- .../DisplayPreferences/IndexMenuPage.xaml | 21 - .../DisplayPreferences/IndexMenuPage.xaml.cs | 95 -- .../DisplayPreferences/MainPage.xaml | 54 - .../DisplayPreferences/MainPage.xaml.cs | 118 -- .../DisplayPreferences/SortMenuPage.xaml | 21 - .../DisplayPreferences/SortMenuPage.xaml.cs | 95 -- .../DisplayPreferences/ViewMenuPage.xaml | 30 - .../DisplayPreferences/ViewMenuPage.xaml.cs | 94 -- .../MediaBrowser.Plugins.DefaultTheme.csproj | 354 ----- .../Model/VirtualCollection.cs | 90 -- .../Pages/DetailPage.xaml | 102 -- .../Pages/DetailPage.xaml.cs | 268 ---- .../Pages/HomePage.xaml | 69 - .../Pages/HomePage.xaml.cs | 442 ------ .../Pages/InternalPlayerPage.xaml | 14 - .../Pages/InternalPlayerPage.xaml.cs | 41 - .../Pages/ListPage.xaml | 74 - .../Pages/ListPage.xaml.cs | 545 ------- .../Pages/LoginPage.xaml | 34 - .../Pages/LoginPage.xaml.cs | 43 - .../Pages/WeatherPage.xaml | 13 - .../Pages/WeatherPage.xaml.cs | 15 - .../Properties/AssemblyInfo.cs | 53 - .../Properties/DesignTimeResources.xaml | 5 - .../Properties/Resources.Designer.cs | 62 - .../Properties/Resources.resx | 117 -- .../Properties/Settings.Designer.cs | 30 - .../Properties/Settings.settings | 7 - .../Resources/AppResources.cs | 223 --- .../Resources/AppResources.xaml | 617 -------- .../Resources/Images/AudioDefault.png | Bin 4525 -> 0 bytes .../Resources/Images/ChapterDefault.png | Bin 4323 -> 0 bytes .../Resources/Images/CurrentUserDefault.png | Bin 818 -> 0 bytes .../Resources/Images/DislikeOverlay.png | Bin 1161 -> 0 bytes .../Resources/Images/FavoriteOverlay.png | Bin 1264 -> 0 bytes .../Resources/Images/LikeOverlay.png | Bin 1145 -> 0 bytes .../Resources/Images/NowPlayingButton.png | Bin 491 -> 0 bytes .../Resources/Images/SearchButton.png | Bin 957 -> 0 bytes .../Resources/Images/SettingsButton.png | Bin 1063 -> 0 bytes .../Resources/Images/UserLoginDefault.png | Bin 8360 -> 0 bytes .../Resources/Images/VideoDefault.png | Bin 2998 -> 0 bytes .../Resources/Images/ViewButton.png | Bin 650 -> 0 bytes .../Resources/Images/ViewMenu/Close.png | Bin 499 -> 0 bytes .../Resources/Images/ViewMenu/Decrease.png | Bin 541 -> 0 bytes .../Resources/Images/ViewMenu/Increase.png | Bin 472 -> 0 bytes .../Resources/Images/ViewMenu/Index.png | Bin 484 -> 0 bytes .../Resources/Images/ViewMenu/Scroll.png | Bin 416 -> 0 bytes .../Resources/Images/ViewMenu/Sort.png | Bin 654 -> 0 bytes .../Resources/Images/ViewMenu/View.png | Bin 531 -> 0 bytes .../Resources/Images/Watched.png | Bin 1253 -> 0 bytes .../Resources/Images/Weather/Cloudy.png | Bin 650 -> 0 bytes .../Resources/Images/Weather/Overcast.png | Bin 1050 -> 0 bytes .../Resources/Images/Weather/PartlyCloudy.png | Bin 943 -> 0 bytes .../Resources/Images/Weather/Rain.png | Bin 902 -> 0 bytes .../Resources/Images/Weather/Snow.png | Bin 1067 -> 0 bytes .../Resources/Images/Weather/Sunny.png | Bin 1181 -> 0 bytes .../Resources/Images/Weather/Thunder.png | Bin 949 -> 0 bytes .../Resources/Images/starEmpty.png | Bin 1799 -> 0 bytes .../Resources/Images/starFull.png | Bin 2498 -> 0 bytes .../Resources/Images/starHalf.png | Bin 2020 -> 0 bytes MediaBrowser.Plugins.DefaultTheme/Theme.cs | 81 - MediaBrowser.Plugins.DefaultTheme/app.config | 11 - MediaBrowser.UI.Controls/BaseModalWindow.cs | 62 - MediaBrowser.UI.Controls/BaseUserControl.cs | 21 - MediaBrowser.UI.Controls/BaseWindow.cs | 175 --- MediaBrowser.UI.Controls/ExtendedButton.cs | 49 - MediaBrowser.UI.Controls/ExtendedCheckbox.cs | 49 - MediaBrowser.UI.Controls/ExtendedListBox.cs | 260 ---- .../ExtendedRadioButton.cs | 49 - .../ExtendedScrollViewer.cs | 41 - MediaBrowser.UI.Controls/ItemEventArgs.cs | 17 - .../MediaBrowser.UI.Controls.csproj | 110 -- .../Properties/AssemblyInfo.cs | 55 - .../Properties/Resources.Designer.cs | 62 - .../Properties/Resources.resx | 117 -- .../Properties/Settings.Designer.cs | 30 - .../Properties/Settings.settings | 7 - MediaBrowser.UI.Controls/ScrollingPanel.cs | 404 ----- MediaBrowser.UI.Controls/Themes/Generic.xaml | 17 - MediaBrowser.UI.Controls/TransitionControl.cs | 147 -- MediaBrowser.UI.Controls/TransitionFrame.cs | 194 --- MediaBrowser.UI.Controls/TreeHelper.cs | 321 ---- .../VirtualizingWrapPanel.cs | 735 --------- MediaBrowser.UI.Uninstall/App.config | 6 - MediaBrowser.UI.Uninstall/Globals.cs | 24 - .../MediaBrowser.UI.Uninstall.csproj | 68 - MediaBrowser.UI.Uninstall/Program.cs | 30 - .../Properties/AssemblyInfo.cs | 36 - MediaBrowser.UI.sln | 150 -- MediaBrowser.UI/App.config | 28 - MediaBrowser.UI/App.xaml | 15 - MediaBrowser.UI/App.xaml.cs | 1098 -------------- .../Configuration/PlayerConfiguration.cs | 52 - .../UIApplicationConfiguration.cs | 72 - .../Configuration/UIApplicationPaths.cs | 37 - MediaBrowser.UI/Controller/BaseTheme.cs | 60 - MediaBrowser.UI/Controller/PluginUpdater.cs | 313 ---- MediaBrowser.UI/Controller/UIKernel.cs | 181 --- MediaBrowser.UI/Controls/ModalWindow.xaml | 67 - MediaBrowser.UI/Controls/ModalWindow.xaml.cs | 180 --- MediaBrowser.UI/Controls/NavigationBar.xaml | 55 - .../Controls/NavigationBar.xaml.cs | 318 ---- .../Controls/NotificationMessage.xaml | 33 - .../Controls/NotificationMessage.xaml.cs | 68 - MediaBrowser.UI/Controls/WindowCommands.xaml | 100 -- .../Controls/WindowCommands.xaml.cs | 82 - .../BaseItemImageVisibilityConverter.cs | 75 - .../CurrentUserVisibilityConverter.cs | 26 - .../Converters/DateTimeToStringConverter.cs | 41 - .../Converters/LastSeenTextConverter.cs | 86 -- .../MetroTileBackgroundConverter.cs | 51 - .../Converters/UserImageConverter.cs | 97 -- .../Converters/WatchedVisibilityConverter.cs | 117 -- .../Converters/WeatherTemperatureConverter.cs | 31 - .../Converters/WeatherVisibilityConverter.cs | 20 - MediaBrowser.UI/Extensions/Extensions.cs | 26 - MediaBrowser.UI/HiddenWindow.xaml | 9 - MediaBrowser.UI/HiddenWindow.xaml.cs | 31 - MediaBrowser.UI/ImageViewerWindow.xaml | 9 - MediaBrowser.UI/ImageViewerWindow.xaml.cs | 41 - MediaBrowser.UI/MainWindow.xaml | 55 - MediaBrowser.UI/MainWindow.xaml.cs | 507 ------- MediaBrowser.UI/MediaBrowser.UI.csproj | 1330 ----------------- .../MediaBrowser.UI_TemporaryKey.pfx | Bin 1676 -> 0 bytes MediaBrowser.UI/Pages/BaseDetailPage.cs | 159 -- MediaBrowser.UI/Pages/BaseFolderPage.cs | 502 ------- MediaBrowser.UI/Pages/BaseHomePage.cs | 17 - .../Pages/BaseInternalPlayerPage.cs | 49 - MediaBrowser.UI/Pages/BaseListPage.cs | 204 --- MediaBrowser.UI/Pages/BaseLoginPage.cs | 119 -- MediaBrowser.UI/Pages/BasePage.cs | 71 - MediaBrowser.UI/Pages/BaseWeatherPage.cs | 7 - MediaBrowser.UI/Pages/SettingsPage.xaml | 16 - MediaBrowser.UI/Pages/SettingsPage.xaml.cs | 14 - MediaBrowser.UI/Playback/BaseMediaPlayer.cs | 747 --------- .../ExternalPlayer/BaseExternalPlayer.cs | 243 --- .../ExternalPlayer/GenericExternalPlayer.cs | 35 - .../InternalPlayer/BaseInternalMediaPlayer.cs | 54 - .../Playback/NVlc/InternalMediaPlayerNVlc.cs | 426 ------ MediaBrowser.UI/Playback/PlayOptions.cs | 89 -- MediaBrowser.UI/Playback/PlayState.cs | 24 - MediaBrowser.UI/Playback/PlaybackEventArgs.cs | 49 - MediaBrowser.UI/Playback/PlaybackManager.cs | 301 ---- MediaBrowser.UI/Properties/AssemblyInfo.cs | 52 - .../Properties/Resources.Designer.cs | 71 - MediaBrowser.UI/Properties/Resources.resx | 117 -- .../Properties/Settings.Designer.cs | 30 - MediaBrowser.UI/Properties/Settings.settings | 7 - MediaBrowser.UI/Resources/AppResources.xaml | 383 ----- MediaBrowser.UI/Resources/Images/Icon.ico | Bin 137409 -> 0 bytes .../Resources/Images/MessageBox/Asterisk.png | Bin 1046 -> 0 bytes .../Resources/Images/MessageBox/Error.png | Bin 804 -> 0 bytes .../Images/MessageBox/Exclamation.png | Bin 804 -> 0 bytes .../Resources/Images/MessageBox/Hand.png | Bin 671 -> 0 bytes .../Images/MessageBox/Information.png | Bin 929 -> 0 bytes .../Resources/Images/MessageBox/Question.png | Bin 770 -> 0 bytes .../Resources/Images/MessageBox/Stop.png | Bin 978 -> 0 bytes .../Resources/Images/MessageBox/Warning.png | Bin 896 -> 0 bytes .../Resources/Images/NavBar/BackButton.png | Bin 1089 -> 0 bytes .../Resources/Images/NavBar/MediaBack.png | Bin 1224 -> 0 bytes .../Images/NavBar/MediaFastForward.png | Bin 1258 -> 0 bytes .../Resources/Images/NavBar/MediaForward.png | Bin 1197 -> 0 bytes .../Resources/Images/NavBar/MediaRewind.png | Bin 1265 -> 0 bytes .../Resources/Images/NavBar/MuteButton.png | Bin 1230 -> 0 bytes .../Resources/Images/NavBar/PauseButton.png | Bin 1056 -> 0 bytes .../Resources/Images/NavBar/PlayButton.png | Bin 1177 -> 0 bytes .../Resources/Images/NavBar/StopButton.png | Bin 1041 -> 0 bytes .../Images/NavBar/VolumeDownButton.png | Bin 1091 -> 0 bytes .../Images/NavBar/VolumeUpButton.png | Bin 1128 -> 0 bytes .../Resources/Images/mblogoblack.png | Bin 15432 -> 0 bytes .../Resources/Images/mblogoblackfull.png | Bin 59905 -> 0 bytes .../Resources/Images/mblogowhite.png | Bin 15487 -> 0 bytes .../Resources/Images/mblogowhitefull.png | Bin 59826 -> 0 bytes .../Resources/MainWindowResources.xaml | 58 - MediaBrowser.UI/Resources/ModalMessage.xaml | 136 -- .../Resources/NavBarResources.xaml | 149 -- .../Resources/NotificationMessage.xaml | 43 - MediaBrowser.UI/UserInput/KeyboardListener.cs | 210 --- .../ViewModels/BaseItemPersonViewModel.cs | 27 - MediaBrowser.UI/ViewModels/BaseViewModel.cs | 27 - .../ViewModels/ChapterInfoDtoViewModel.cs | 182 --- .../ViewModels/DtoBaseItemViewModel.cs | 183 --- .../ViewModels/ItemCollectionViewModel.cs | 158 -- .../ViewModels/SpecialFeatureViewModel.cs | 135 -- MediaBrowser.UI/packages.config | 7 - .../libavcodec_plugin.dll.REMOVED.git-id | 1 - .../gui/libqt4_plugin.dll.REMOVED.git-id | 1 - 214 files changed, 19327 deletions(-) delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Controls/BaseItemTile.xaml delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Controls/BaseItemTile.xaml.cs delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Controls/Details/BaseDetailsControl.cs delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemChapters.xaml delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemChapters.xaml.cs delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemGallery.xaml delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemGallery.xaml.cs delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemMediaInfo.xaml delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemMediaInfo.xaml.cs delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemOverview.xaml delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemOverview.xaml.cs delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemPerformers.xaml delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemPerformers.xaml.cs delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemSpecialFeatures.xaml delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemSpecialFeatures.xaml.cs delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemTrailers.xaml delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemTrailers.xaml.cs delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Controls/Details/MediaStreamControl.xaml delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Controls/Details/MediaStreamControl.xaml.cs delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Controls/HomePageTile.xaml delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Controls/HomePageTile.xaml.cs delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Controls/MultiItemTile.xaml delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Controls/MultiItemTile.xaml.cs delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Converters/WeatherImageConverter.cs delete mode 100644 MediaBrowser.Plugins.DefaultTheme/DisplayPreferences/BaseDisplayPreferencesPage.cs delete mode 100644 MediaBrowser.Plugins.DefaultTheme/DisplayPreferences/DisplayPreferencesMenu.xaml delete mode 100644 MediaBrowser.Plugins.DefaultTheme/DisplayPreferences/DisplayPreferencesMenu.xaml.cs delete mode 100644 MediaBrowser.Plugins.DefaultTheme/DisplayPreferences/IndexMenuPage.xaml delete mode 100644 MediaBrowser.Plugins.DefaultTheme/DisplayPreferences/IndexMenuPage.xaml.cs delete mode 100644 MediaBrowser.Plugins.DefaultTheme/DisplayPreferences/MainPage.xaml delete mode 100644 MediaBrowser.Plugins.DefaultTheme/DisplayPreferences/MainPage.xaml.cs delete mode 100644 MediaBrowser.Plugins.DefaultTheme/DisplayPreferences/SortMenuPage.xaml delete mode 100644 MediaBrowser.Plugins.DefaultTheme/DisplayPreferences/SortMenuPage.xaml.cs delete mode 100644 MediaBrowser.Plugins.DefaultTheme/DisplayPreferences/ViewMenuPage.xaml delete mode 100644 MediaBrowser.Plugins.DefaultTheme/DisplayPreferences/ViewMenuPage.xaml.cs delete mode 100644 MediaBrowser.Plugins.DefaultTheme/MediaBrowser.Plugins.DefaultTheme.csproj delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Model/VirtualCollection.cs delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Pages/DetailPage.xaml delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Pages/DetailPage.xaml.cs delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Pages/HomePage.xaml delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Pages/HomePage.xaml.cs delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Pages/InternalPlayerPage.xaml delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Pages/InternalPlayerPage.xaml.cs delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Pages/ListPage.xaml delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Pages/ListPage.xaml.cs delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Pages/LoginPage.xaml delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Pages/LoginPage.xaml.cs delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Pages/WeatherPage.xaml delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Pages/WeatherPage.xaml.cs delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Properties/AssemblyInfo.cs delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Properties/DesignTimeResources.xaml delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Properties/Resources.Designer.cs delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Properties/Resources.resx delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Properties/Settings.Designer.cs delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Properties/Settings.settings delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Resources/AppResources.cs delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Resources/AppResources.xaml delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Resources/Images/AudioDefault.png delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Resources/Images/ChapterDefault.png delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Resources/Images/CurrentUserDefault.png delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Resources/Images/DislikeOverlay.png delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Resources/Images/FavoriteOverlay.png delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Resources/Images/LikeOverlay.png delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Resources/Images/NowPlayingButton.png delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Resources/Images/SearchButton.png delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Resources/Images/SettingsButton.png delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Resources/Images/UserLoginDefault.png delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Resources/Images/VideoDefault.png delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Resources/Images/ViewButton.png delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Resources/Images/ViewMenu/Close.png delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Resources/Images/ViewMenu/Decrease.png delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Resources/Images/ViewMenu/Increase.png delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Resources/Images/ViewMenu/Index.png delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Resources/Images/ViewMenu/Scroll.png delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Resources/Images/ViewMenu/Sort.png delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Resources/Images/ViewMenu/View.png delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Resources/Images/Watched.png delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Resources/Images/Weather/Cloudy.png delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Resources/Images/Weather/Overcast.png delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Resources/Images/Weather/PartlyCloudy.png delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Resources/Images/Weather/Rain.png delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Resources/Images/Weather/Snow.png delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Resources/Images/Weather/Sunny.png delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Resources/Images/Weather/Thunder.png delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Resources/Images/starEmpty.png delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Resources/Images/starFull.png delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Resources/Images/starHalf.png delete mode 100644 MediaBrowser.Plugins.DefaultTheme/Theme.cs delete mode 100644 MediaBrowser.Plugins.DefaultTheme/app.config delete mode 100644 MediaBrowser.UI.Controls/BaseModalWindow.cs delete mode 100644 MediaBrowser.UI.Controls/BaseUserControl.cs delete mode 100644 MediaBrowser.UI.Controls/BaseWindow.cs delete mode 100644 MediaBrowser.UI.Controls/ExtendedButton.cs delete mode 100644 MediaBrowser.UI.Controls/ExtendedCheckbox.cs delete mode 100644 MediaBrowser.UI.Controls/ExtendedListBox.cs delete mode 100644 MediaBrowser.UI.Controls/ExtendedRadioButton.cs delete mode 100644 MediaBrowser.UI.Controls/ExtendedScrollViewer.cs delete mode 100644 MediaBrowser.UI.Controls/ItemEventArgs.cs delete mode 100644 MediaBrowser.UI.Controls/MediaBrowser.UI.Controls.csproj delete mode 100644 MediaBrowser.UI.Controls/Properties/AssemblyInfo.cs delete mode 100644 MediaBrowser.UI.Controls/Properties/Resources.Designer.cs delete mode 100644 MediaBrowser.UI.Controls/Properties/Resources.resx delete mode 100644 MediaBrowser.UI.Controls/Properties/Settings.Designer.cs delete mode 100644 MediaBrowser.UI.Controls/Properties/Settings.settings delete mode 100644 MediaBrowser.UI.Controls/ScrollingPanel.cs delete mode 100644 MediaBrowser.UI.Controls/Themes/Generic.xaml delete mode 100644 MediaBrowser.UI.Controls/TransitionControl.cs delete mode 100644 MediaBrowser.UI.Controls/TransitionFrame.cs delete mode 100644 MediaBrowser.UI.Controls/TreeHelper.cs delete mode 100644 MediaBrowser.UI.Controls/VirtualizingWrapPanel.cs delete mode 100644 MediaBrowser.UI.Uninstall/App.config delete mode 100644 MediaBrowser.UI.Uninstall/Globals.cs delete mode 100644 MediaBrowser.UI.Uninstall/MediaBrowser.UI.Uninstall.csproj delete mode 100644 MediaBrowser.UI.Uninstall/Program.cs delete mode 100644 MediaBrowser.UI.Uninstall/Properties/AssemblyInfo.cs delete mode 100644 MediaBrowser.UI.sln delete mode 100644 MediaBrowser.UI/App.config delete mode 100644 MediaBrowser.UI/App.xaml delete mode 100644 MediaBrowser.UI/App.xaml.cs delete mode 100644 MediaBrowser.UI/Configuration/PlayerConfiguration.cs delete mode 100644 MediaBrowser.UI/Configuration/UIApplicationConfiguration.cs delete mode 100644 MediaBrowser.UI/Configuration/UIApplicationPaths.cs delete mode 100644 MediaBrowser.UI/Controller/BaseTheme.cs delete mode 100644 MediaBrowser.UI/Controller/PluginUpdater.cs delete mode 100644 MediaBrowser.UI/Controller/UIKernel.cs delete mode 100644 MediaBrowser.UI/Controls/ModalWindow.xaml delete mode 100644 MediaBrowser.UI/Controls/ModalWindow.xaml.cs delete mode 100644 MediaBrowser.UI/Controls/NavigationBar.xaml delete mode 100644 MediaBrowser.UI/Controls/NavigationBar.xaml.cs delete mode 100644 MediaBrowser.UI/Controls/NotificationMessage.xaml delete mode 100644 MediaBrowser.UI/Controls/NotificationMessage.xaml.cs delete mode 100644 MediaBrowser.UI/Controls/WindowCommands.xaml delete mode 100644 MediaBrowser.UI/Controls/WindowCommands.xaml.cs delete mode 100644 MediaBrowser.UI/Converters/BaseItemImageVisibilityConverter.cs delete mode 100644 MediaBrowser.UI/Converters/CurrentUserVisibilityConverter.cs delete mode 100644 MediaBrowser.UI/Converters/DateTimeToStringConverter.cs delete mode 100644 MediaBrowser.UI/Converters/LastSeenTextConverter.cs delete mode 100644 MediaBrowser.UI/Converters/MetroTileBackgroundConverter.cs delete mode 100644 MediaBrowser.UI/Converters/UserImageConverter.cs delete mode 100644 MediaBrowser.UI/Converters/WatchedVisibilityConverter.cs delete mode 100644 MediaBrowser.UI/Converters/WeatherTemperatureConverter.cs delete mode 100644 MediaBrowser.UI/Converters/WeatherVisibilityConverter.cs delete mode 100644 MediaBrowser.UI/Extensions/Extensions.cs delete mode 100644 MediaBrowser.UI/HiddenWindow.xaml delete mode 100644 MediaBrowser.UI/HiddenWindow.xaml.cs delete mode 100644 MediaBrowser.UI/ImageViewerWindow.xaml delete mode 100644 MediaBrowser.UI/ImageViewerWindow.xaml.cs delete mode 100644 MediaBrowser.UI/MainWindow.xaml delete mode 100644 MediaBrowser.UI/MainWindow.xaml.cs delete mode 100644 MediaBrowser.UI/MediaBrowser.UI.csproj delete mode 100644 MediaBrowser.UI/MediaBrowser.UI_TemporaryKey.pfx delete mode 100644 MediaBrowser.UI/Pages/BaseDetailPage.cs delete mode 100644 MediaBrowser.UI/Pages/BaseFolderPage.cs delete mode 100644 MediaBrowser.UI/Pages/BaseHomePage.cs delete mode 100644 MediaBrowser.UI/Pages/BaseInternalPlayerPage.cs delete mode 100644 MediaBrowser.UI/Pages/BaseListPage.cs delete mode 100644 MediaBrowser.UI/Pages/BaseLoginPage.cs delete mode 100644 MediaBrowser.UI/Pages/BasePage.cs delete mode 100644 MediaBrowser.UI/Pages/BaseWeatherPage.cs delete mode 100644 MediaBrowser.UI/Pages/SettingsPage.xaml delete mode 100644 MediaBrowser.UI/Pages/SettingsPage.xaml.cs delete mode 100644 MediaBrowser.UI/Playback/BaseMediaPlayer.cs delete mode 100644 MediaBrowser.UI/Playback/ExternalPlayer/BaseExternalPlayer.cs delete mode 100644 MediaBrowser.UI/Playback/ExternalPlayer/GenericExternalPlayer.cs delete mode 100644 MediaBrowser.UI/Playback/InternalPlayer/BaseInternalMediaPlayer.cs delete mode 100644 MediaBrowser.UI/Playback/NVlc/InternalMediaPlayerNVlc.cs delete mode 100644 MediaBrowser.UI/Playback/PlayOptions.cs delete mode 100644 MediaBrowser.UI/Playback/PlayState.cs delete mode 100644 MediaBrowser.UI/Playback/PlaybackEventArgs.cs delete mode 100644 MediaBrowser.UI/Playback/PlaybackManager.cs delete mode 100644 MediaBrowser.UI/Properties/AssemblyInfo.cs delete mode 100644 MediaBrowser.UI/Properties/Resources.Designer.cs delete mode 100644 MediaBrowser.UI/Properties/Resources.resx delete mode 100644 MediaBrowser.UI/Properties/Settings.Designer.cs delete mode 100644 MediaBrowser.UI/Properties/Settings.settings delete mode 100644 MediaBrowser.UI/Resources/AppResources.xaml delete mode 100644 MediaBrowser.UI/Resources/Images/Icon.ico delete mode 100644 MediaBrowser.UI/Resources/Images/MessageBox/Asterisk.png delete mode 100644 MediaBrowser.UI/Resources/Images/MessageBox/Error.png delete mode 100644 MediaBrowser.UI/Resources/Images/MessageBox/Exclamation.png delete mode 100644 MediaBrowser.UI/Resources/Images/MessageBox/Hand.png delete mode 100644 MediaBrowser.UI/Resources/Images/MessageBox/Information.png delete mode 100644 MediaBrowser.UI/Resources/Images/MessageBox/Question.png delete mode 100644 MediaBrowser.UI/Resources/Images/MessageBox/Stop.png delete mode 100644 MediaBrowser.UI/Resources/Images/MessageBox/Warning.png delete mode 100644 MediaBrowser.UI/Resources/Images/NavBar/BackButton.png delete mode 100644 MediaBrowser.UI/Resources/Images/NavBar/MediaBack.png delete mode 100644 MediaBrowser.UI/Resources/Images/NavBar/MediaFastForward.png delete mode 100644 MediaBrowser.UI/Resources/Images/NavBar/MediaForward.png delete mode 100644 MediaBrowser.UI/Resources/Images/NavBar/MediaRewind.png delete mode 100644 MediaBrowser.UI/Resources/Images/NavBar/MuteButton.png delete mode 100644 MediaBrowser.UI/Resources/Images/NavBar/PauseButton.png delete mode 100644 MediaBrowser.UI/Resources/Images/NavBar/PlayButton.png delete mode 100644 MediaBrowser.UI/Resources/Images/NavBar/StopButton.png delete mode 100644 MediaBrowser.UI/Resources/Images/NavBar/VolumeDownButton.png delete mode 100644 MediaBrowser.UI/Resources/Images/NavBar/VolumeUpButton.png delete mode 100644 MediaBrowser.UI/Resources/Images/mblogoblack.png delete mode 100644 MediaBrowser.UI/Resources/Images/mblogoblackfull.png delete mode 100644 MediaBrowser.UI/Resources/Images/mblogowhite.png delete mode 100644 MediaBrowser.UI/Resources/Images/mblogowhitefull.png delete mode 100644 MediaBrowser.UI/Resources/MainWindowResources.xaml delete mode 100644 MediaBrowser.UI/Resources/ModalMessage.xaml delete mode 100644 MediaBrowser.UI/Resources/NavBarResources.xaml delete mode 100644 MediaBrowser.UI/Resources/NotificationMessage.xaml delete mode 100644 MediaBrowser.UI/UserInput/KeyboardListener.cs delete mode 100644 MediaBrowser.UI/ViewModels/BaseItemPersonViewModel.cs delete mode 100644 MediaBrowser.UI/ViewModels/BaseViewModel.cs delete mode 100644 MediaBrowser.UI/ViewModels/ChapterInfoDtoViewModel.cs delete mode 100644 MediaBrowser.UI/ViewModels/DtoBaseItemViewModel.cs delete mode 100644 MediaBrowser.UI/ViewModels/ItemCollectionViewModel.cs delete mode 100644 MediaBrowser.UI/ViewModels/SpecialFeatureViewModel.cs delete mode 100644 MediaBrowser.UI/packages.config delete mode 100644 MediaBrowser.UI/plugins/codec/libavcodec_plugin.dll.REMOVED.git-id delete mode 100644 MediaBrowser.UI/plugins/gui/libqt4_plugin.dll.REMOVED.git-id diff --git a/MediaBrowser.Plugins.DefaultTheme/Controls/BaseItemTile.xaml b/MediaBrowser.Plugins.DefaultTheme/Controls/BaseItemTile.xaml deleted file mode 100644 index a66b1c4030..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/Controls/BaseItemTile.xaml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/MediaBrowser.Plugins.DefaultTheme/Controls/BaseItemTile.xaml.cs b/MediaBrowser.Plugins.DefaultTheme/Controls/BaseItemTile.xaml.cs deleted file mode 100644 index 690a539f81..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/Controls/BaseItemTile.xaml.cs +++ /dev/null @@ -1,177 +0,0 @@ -using MediaBrowser.Model.Dto; -using MediaBrowser.Model.Net; -using MediaBrowser.UI; -using MediaBrowser.UI.Controls; -using MediaBrowser.UI.Converters; -using MediaBrowser.UI.ViewModels; -using System; -using System.ComponentModel; -using System.Windows; - -namespace MediaBrowser.Plugins.DefaultTheme.Controls -{ - /// - /// Interaction logic for BaseItemTile.xaml - /// - public partial class BaseItemTile : BaseUserControl - { - /// - /// Gets the view model. - /// - /// The view model. - public DtoBaseItemViewModel ViewModel - { - get { return DataContext as DtoBaseItemViewModel; } - } - - /// - /// Gets the item. - /// - /// The item. - private BaseItemDto Item - { - get { return ViewModel.Item; } - } - - /// - /// Initializes a new instance of the class. - /// - public BaseItemTile() - { - InitializeComponent(); - - DataContextChanged += BaseItemTile_DataContextChanged; - Loaded += BaseItemTile_Loaded; - Unloaded += BaseItemTile_Unloaded; - } - - /// - /// Handles the Unloaded event of the BaseItemTile control. - /// - /// The source of the event. - /// The instance containing the event data. - void BaseItemTile_Unloaded(object sender, RoutedEventArgs e) - { - if (ViewModel != null) - { - ViewModel.PropertyChanged -= ViewModel_PropertyChanged; - } - } - - /// - /// Handles the Loaded event of the BaseItemTile control. - /// - /// The source of the event. - /// The instance containing the event data. - void BaseItemTile_Loaded(object sender, RoutedEventArgs e) - { - if (ViewModel != null) - { - ViewModel.PropertyChanged -= ViewModel_PropertyChanged; - ViewModel.PropertyChanged += ViewModel_PropertyChanged; - } - } - - /// - /// Handles the DataContextChanged event of the BaseItemTile control. - /// - /// The source of the event. - /// The instance containing the event data. - void BaseItemTile_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e) - { - OnItemChanged(); - - if (ViewModel != null) - { - ViewModel.PropertyChanged -= ViewModel_PropertyChanged; - ViewModel.PropertyChanged += ViewModel_PropertyChanged; - } - } - - /// - /// Handles the PropertyChanged event of the ViewModel control. - /// - /// The source of the event. - /// The instance containing the event data. - void ViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e) - { - ReloadImage(); - } - - /// - /// Called when [item changed]. - /// - private void OnItemChanged() - { - ReloadImage(); - - var visibility = Item.HasPrimaryImage && !Item.IsType("Episode") ? Visibility.Collapsed : Visibility.Visible; - - if (Item.IsType("Person") || Item.IsType("IndexFolder")) - { - visibility = Visibility.Visible; - } - - txtName.Visibility = visibility; - - var name = Item.Name; - - if (Item.IndexNumber.HasValue) - { - name = Item.IndexNumber + " - " + name; - } - - txtName.Text = name; - } - - /// - /// Reloads the image. - /// - private async void ReloadImage() - { - mainGrid.Height = ViewModel.ParentDisplayPreferences.PrimaryImageHeight; - mainGrid.Width = ViewModel.ParentDisplayPreferences.PrimaryImageWidth; - - if (Item.HasPrimaryImage) - { - var url = ViewModel.GetImageUrl(ViewModel.ParentDisplayPreferences.PrimaryImageType); - - border.Background = null; - - try - { - image.Source = await App.Instance.GetRemoteBitmapAsync(url); - } - catch (HttpException) - { - SetDefaultImage(); - } - } - else - { - SetDefaultImage(); - } - } - - /// - /// Sets the default image. - /// - private void SetDefaultImage() - { - if (Item.IsAudio || Item.IsType("MusicAlbum") || Item.IsType("MusicArtist")) - { - var imageUri = new Uri("../Resources/Images/AudioDefault.png", UriKind.Relative); - - border.Background = MetroTileBackgroundConverter.GetRandomBackground(); - image.Source = App.Instance.GetBitmapImage(imageUri); - } - else - { - var imageUri = new Uri("../Resources/Images/VideoDefault.png", UriKind.Relative); - - border.Background = MetroTileBackgroundConverter.GetRandomBackground(); - image.Source = App.Instance.GetBitmapImage(imageUri); - } - } - } -} diff --git a/MediaBrowser.Plugins.DefaultTheme/Controls/Details/BaseDetailsControl.cs b/MediaBrowser.Plugins.DefaultTheme/Controls/Details/BaseDetailsControl.cs deleted file mode 100644 index 530788aead..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/Controls/Details/BaseDetailsControl.cs +++ /dev/null @@ -1,44 +0,0 @@ -using MediaBrowser.Model.Dto; -using MediaBrowser.UI.Controls; - -namespace MediaBrowser.Plugins.DefaultTheme.Controls.Details -{ - /// - /// Class BaseDetailsControl - /// - public abstract class BaseDetailsControl : BaseUserControl - { - /// - /// Initializes a new instance of the class. - /// - protected BaseDetailsControl() - { - DataContext = this; - } - - /// - /// The _item - /// - private BaseItemDto _item; - /// - /// Gets or sets the item. - /// - /// The item. - public BaseItemDto Item - { - get { return _item; } - - set - { - _item = value; - OnPropertyChanged("Item"); - OnItemChanged(); - } - } - - /// - /// Called when [item changed]. - /// - protected abstract void OnItemChanged(); - } -} diff --git a/MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemChapters.xaml b/MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemChapters.xaml deleted file mode 100644 index 4282316b41..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemChapters.xaml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemChapters.xaml.cs b/MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemChapters.xaml.cs deleted file mode 100644 index d9f40b0149..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemChapters.xaml.cs +++ /dev/null @@ -1,67 +0,0 @@ -using MediaBrowser.Model.Dto; -using MediaBrowser.UI.Controller; -using MediaBrowser.UI.Controls; -using MediaBrowser.UI.Playback; -using MediaBrowser.UI.ViewModels; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; - -namespace MediaBrowser.Plugins.DefaultTheme.Controls.Details -{ - /// - /// Interaction logic for ItemChapters.xaml - /// - public partial class ItemChapters : BaseDetailsControl - { - /// - /// Initializes a new instance of the class. - /// - public ItemChapters() - { - InitializeComponent(); - - lstItems.ItemInvoked += lstItems_ItemInvoked; - } - - /// - /// LSTs the items_ item invoked. - /// - /// The sender. - /// The e. - void lstItems_ItemInvoked(object sender, ItemEventArgs e) - { - var chapterViewModel = (ChapterInfoDtoViewModel) e.Argument; - - UIKernel.Instance.PlaybackManager.Play(new PlayOptions - { - Items = new List { Item }, - StartPositionTicks = chapterViewModel.Chapter.StartPositionTicks - }); - } - - /// - /// Called when [item changed]. - /// - protected override void OnItemChanged() - { - const double height = 297; - - var width = ChapterInfoDtoViewModel.GetChapterImageWidth(Item, height, 528); - - var chapters = Item.Chapters ?? new List { }; - - lstItems.ItemsSource = new ObservableCollection(chapters.Select(i => new ChapterInfoDtoViewModel - { - Item = Item, - Chapter = i, - ImageWidth = width, - ImageHeight = height, - ImageDownloadOptions = new ImageOptions - { - MaxHeight = 400 - } - })); - } - } -} diff --git a/MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemGallery.xaml b/MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemGallery.xaml deleted file mode 100644 index 3127425588..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemGallery.xaml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemGallery.xaml.cs b/MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemGallery.xaml.cs deleted file mode 100644 index c315a0f7fa..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemGallery.xaml.cs +++ /dev/null @@ -1,163 +0,0 @@ -using MediaBrowser.Model.Dto; -using MediaBrowser.Model.Entities; -using MediaBrowser.Model.Net; -using MediaBrowser.UI; -using MediaBrowser.UI.Controller; -using MediaBrowser.UI.Controls; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using System.Windows.Media.Imaging; - -namespace MediaBrowser.Plugins.DefaultTheme.Controls.Details -{ - /// - /// Interaction logic for ItemGallery.xaml - /// - public partial class ItemGallery : BaseDetailsControl - { - /// - /// Initializes a new instance of the class. - /// - public ItemGallery() - : base() - { - InitializeComponent(); - lstItems.ItemInvoked += lstItems_ItemInvoked; - } - - /// - /// LSTs the items_ item invoked. - /// - /// The sender. - /// The e. - void lstItems_ItemInvoked(object sender, ItemEventArgs e) - { - var img = (BitmapImage)e.Argument; - - var index = Images.IndexOf(img); - - //App.Instance.OpenImageViewer(new Uri(ImageUrls[index]), Item.Name); - } - - /// - /// The _images - /// - private List _images; - /// - /// Gets or sets the images. - /// - /// The images. - public List Images - { - get { return _images; } - set - { - _images = value; - lstItems.ItemsSource = value; - OnPropertyChanged("Images"); - } - } - - /// - /// Gets or sets the image urls. - /// - /// The image urls. - private List ImageUrls { get; set; } - - /// - /// Called when [item changed]. - /// - protected override async void OnItemChanged() - { - ImageUrls = GetImages(Item); - - var tasks = ImageUrls.Select(GetImage); - - var results = await Task.WhenAll(tasks); - - Images = results.Where(i => i != null).ToList(); - } - - /// - /// Gets the image. - /// - /// The URL. - /// Task{BitmapImage}. - private async Task GetImage(string url) - { - try - { - return await App.Instance.GetRemoteBitmapAsync(url); - } - catch (HttpException) - { - return null; - } - } - - /// - /// Gets the images. - /// - /// The item. - /// List{System.String}. - internal static List GetImages(BaseItemDto item) - { - var images = new List { }; - - if (item.BackdropCount > 0) - { - for (var i = 0; i < item.BackdropCount; i++) - { - images.Add(UIKernel.Instance.ApiClient.GetImageUrl(item, new ImageOptions - { - ImageType = ImageType.Backdrop, - ImageIndex = i - })); - } - } - - if (item.HasThumb) - { - images.Add(UIKernel.Instance.ApiClient.GetImageUrl(item, new ImageOptions - { - ImageType = ImageType.Thumb - })); - } - - if (item.HasArtImage) - { - images.Add(UIKernel.Instance.ApiClient.GetImageUrl(item, new ImageOptions - { - ImageType = ImageType.Art - })); - } - - if (item.HasDiscImage) - { - images.Add(UIKernel.Instance.ApiClient.GetImageUrl(item, new ImageOptions - { - ImageType = ImageType.Disc - })); - } - - if (item.HasMenuImage) - { - images.Add(UIKernel.Instance.ApiClient.GetImageUrl(item, new ImageOptions - { - ImageType = ImageType.Menu - })); - } - - if (item.HasBoxImage) - { - images.Add(UIKernel.Instance.ApiClient.GetImageUrl(item, new ImageOptions - { - ImageType = ImageType.Box - })); - } - - return images; - } - } -} diff --git a/MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemMediaInfo.xaml b/MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemMediaInfo.xaml deleted file mode 100644 index 0cae37a359..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemMediaInfo.xaml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemMediaInfo.xaml.cs b/MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemMediaInfo.xaml.cs deleted file mode 100644 index 3912093c76..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemMediaInfo.xaml.cs +++ /dev/null @@ -1,49 +0,0 @@ -using MediaBrowser.Model.Entities; -using System.Collections.Generic; -using System.Windows; - -namespace MediaBrowser.Plugins.DefaultTheme.Controls.Details -{ - /// - /// Interaction logic for ItemMediaInfo.xaml - /// - public partial class ItemMediaInfo : BaseDetailsControl - { - /// - /// Initializes a new instance of the class. - /// - public ItemMediaInfo() - { - InitializeComponent(); - } - - /// - /// Called when [item changed]. - /// - protected override void OnItemChanged() - { - MediaStreams.Children.Clear(); - - TxtPath.Text = Item.Path; - - if (Item.VideoFormat.HasValue && Item.VideoFormat.Value != VideoFormat.Standard) - { - TxtVideoFormat.Visibility = Visibility.Visible; - - TxtVideoFormat.Text = Item.VideoFormat.Value == VideoFormat.Digital3D ? "Digital 3D" : "SBS 3D"; - } - else - { - TxtVideoFormat.Visibility = Visibility.Collapsed; - } - - foreach (var stream in Item.MediaStreams ?? new List {}) - { - MediaStreams.Children.Add(new MediaStreamControl - { - MediaStream = stream - }); - } - } - } -} diff --git a/MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemOverview.xaml b/MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemOverview.xaml deleted file mode 100644 index 32e16ce9d2..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemOverview.xaml +++ /dev/null @@ -1,68 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemOverview.xaml.cs b/MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemOverview.xaml.cs deleted file mode 100644 index 3c1eb52ec3..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemOverview.xaml.cs +++ /dev/null @@ -1,109 +0,0 @@ -using MediaBrowser.Model.Dto; -using System; -using System.Linq; -using System.Windows; - -namespace MediaBrowser.Plugins.DefaultTheme.Controls.Details -{ - /// - /// Interaction logic for ItemOverview.xaml - /// - public partial class ItemOverview : BaseDetailsControl - { - /// - /// Initializes a new instance of the class. - /// - public ItemOverview() - : base() - { - InitializeComponent(); - } - - /// - /// Called when [item changed]. - /// - protected override void OnItemChanged() - { - var directors = (Item.People ?? new BaseItemPerson[] { }).Where(p => string.Equals(p.Type, "director", StringComparison.OrdinalIgnoreCase)).ToList(); - - if (directors.Count > 0) - { - PnlDirectors.Visibility = Visibility.Visible; - - Directors.Text = string.Join(" / ", directors.Take(3).Select(d => d.Name).ToArray()); - DirectorLabel.Text = directors.Count > 1 ? "directors" : "director"; - } - else - { - PnlDirectors.Visibility = Visibility.Collapsed; - } - - if (Item.Genres != null && Item.Genres.Count > 0) - { - PnlGenres.Visibility = Visibility.Visible; - - Genres.Text = string.Join(" / ", Item.Genres.Take(4).ToArray()); - GenreLabel.Text = Item.Genres.Count > 1 ? "genres" : "genre"; - } - else - { - PnlGenres.Visibility = Visibility.Collapsed; - } - - if (Item.Studios != null && Item.Studios.Count > 0) - { - PnlStudios.Visibility = Visibility.Visible; - - Studios.Text = string.Join(" / ", Item.Studios.Take(3).ToArray()); - StudiosLabel.Text = Item.Studios.Count > 1 ? "studios" : "studio"; - } - else - { - PnlStudios.Visibility = Visibility.Collapsed; - } - - if (Item.PremiereDate.HasValue) - { - PnlPremiereDate.Visibility = Visibility.Visible; - - PremiereDate.Text = Item.PremiereDate.Value.ToShortDateString(); - } - else - { - PnlPremiereDate.Visibility = Visibility.Collapsed; - } - - if (!string.IsNullOrEmpty(Item.Artist)) - { - PnlArtist.Visibility = Visibility.Visible; - Artist.Text = Item.Artist; - } - else - { - PnlArtist.Visibility = Visibility.Collapsed; - } - - if (!string.IsNullOrEmpty(Item.Album)) - { - PnlAlbum.Visibility = Visibility.Visible; - Album.Text = Item.Artist; - } - else - { - PnlAlbum.Visibility = Visibility.Collapsed; - } - - if (!string.IsNullOrEmpty(Item.AlbumArtist)) - { - PnlAlbumArtist.Visibility = Visibility.Visible; - AlbumArtist.Text = Item.Artist; - } - else - { - PnlAlbumArtist.Visibility = Visibility.Collapsed; - } - - Overview.Text = Item.Overview; - } - } -} diff --git a/MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemPerformers.xaml b/MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemPerformers.xaml deleted file mode 100644 index 6e2bc9f57a..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemPerformers.xaml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemPerformers.xaml.cs b/MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemPerformers.xaml.cs deleted file mode 100644 index 0ea9a052e7..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemPerformers.xaml.cs +++ /dev/null @@ -1,72 +0,0 @@ -using MediaBrowser.Model.Dto; -using MediaBrowser.UI; -using MediaBrowser.UI.Controller; -using MediaBrowser.UI.ViewModels; -using System.Collections.ObjectModel; - -namespace MediaBrowser.Plugins.DefaultTheme.Controls.Details -{ - /// - /// Interaction logic for ItemPerformers.xaml - /// - public partial class ItemPerformers : BaseDetailsControl - { - /// - /// Initializes a new instance of the class. - /// - public ItemPerformers() - { - InitializeComponent(); - } - - /// - /// The _itemsResult - /// - private ItemsResult _itemsResult; - /// - /// Gets or sets the children of the Folder being displayed - /// - /// The children. - public ItemsResult ItemsResult - { - get { return _itemsResult; } - - private set - { - _itemsResult = value; - OnPropertyChanged("ItemsResult"); - - Items = DtoBaseItemViewModel.GetObservableItems(ItemsResult.Items); - } - } - - /// - /// The _display children - /// - private ObservableCollection _items; - /// - /// Gets the actual children that should be displayed. - /// Subclasses should bind to this, not ItemsResult. - /// - /// The display children. - public ObservableCollection Items - { - get { return _items; } - - private set - { - _items = value; - //lstItems.ItemsSource = value; - OnPropertyChanged("Items"); - } - } - - /// - /// Called when [item changed]. - /// - protected override async void OnItemChanged() - { - ItemsResult = await UIKernel.Instance.ApiClient.GetAllPeopleAsync(App.Instance.CurrentUser.Id, itemId: Item.Id); - } - } -} diff --git a/MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemSpecialFeatures.xaml b/MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemSpecialFeatures.xaml deleted file mode 100644 index 09d64612e2..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemSpecialFeatures.xaml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemSpecialFeatures.xaml.cs b/MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemSpecialFeatures.xaml.cs deleted file mode 100644 index d62c6d157e..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemSpecialFeatures.xaml.cs +++ /dev/null @@ -1,77 +0,0 @@ -using MediaBrowser.Model.Dto; -using MediaBrowser.Model.Net; -using MediaBrowser.UI; -using MediaBrowser.UI.Controller; -using MediaBrowser.UI.Controls; -using MediaBrowser.UI.Playback; -using MediaBrowser.UI.ViewModels; -using System.Collections.Generic; -using System.Linq; - -namespace MediaBrowser.Plugins.DefaultTheme.Controls.Details -{ - /// - /// Interaction logic for ItemSpecialFeatures.xaml - /// - public partial class ItemSpecialFeatures : BaseDetailsControl - { - /// - /// Initializes a new instance of the class. - /// - public ItemSpecialFeatures() - { - InitializeComponent(); - - lstItems.ItemInvoked += lstItems_ItemInvoked; - } - - /// - /// LSTs the items_ item invoked. - /// - /// The sender. - /// The e. - void lstItems_ItemInvoked(object sender, ItemEventArgs e) - { - var viewModel = (SpecialFeatureViewModel) e.Argument; - - UIKernel.Instance.PlaybackManager.Play(new PlayOptions - { - Items = new List { viewModel.Item } - }); - } - - /// - /// Called when [item changed]. - /// - protected override async void OnItemChanged() - { - BaseItemDto[] result; - - try - { - result = await UIKernel.Instance.ApiClient.GetSpecialFeaturesAsync(App.Instance.CurrentUser.Id, Item.Id); - } - catch (HttpException) - { - App.Instance.ShowDefaultErrorMessage(); - - return; - } - - var resultItems = result ?? new BaseItemDto[] { }; - - const int height = 297; - var aspectRatio = DtoBaseItemViewModel.GetAveragePrimaryImageAspectRatio(resultItems); - - var width = aspectRatio == 0 ? 528 : height * aspectRatio; - - lstItems.ItemsSource = resultItems.Select(i => new SpecialFeatureViewModel - { - Item = i, - ImageHeight = height, - ImageWidth = width - - }).ToList(); - } - } -} diff --git a/MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemTrailers.xaml b/MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemTrailers.xaml deleted file mode 100644 index 1298852718..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemTrailers.xaml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemTrailers.xaml.cs b/MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemTrailers.xaml.cs deleted file mode 100644 index 9d92aafbb1..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/Controls/Details/ItemTrailers.xaml.cs +++ /dev/null @@ -1,82 +0,0 @@ -using MediaBrowser.Model.Dto; -using MediaBrowser.Model.Net; -using MediaBrowser.UI; -using MediaBrowser.UI.Controller; -using MediaBrowser.UI.Controls; -using MediaBrowser.UI.Playback; -using MediaBrowser.UI.ViewModels; -using System.Collections.Generic; -using System.Linq; - -namespace MediaBrowser.Plugins.DefaultTheme.Controls.Details -{ - /// - /// Interaction logic for ItemTrailers.xaml - /// - public partial class ItemTrailers : BaseDetailsControl - { - /// - /// Initializes a new instance of the class. - /// - public ItemTrailers() - { - InitializeComponent(); - - lstItems.ItemInvoked += lstItems_ItemInvoked; - } - - /// - /// LSTs the items_ item invoked. - /// - /// The sender. - /// The e. - void lstItems_ItemInvoked(object sender, ItemEventArgs e) - { - var viewModel = (SpecialFeatureViewModel)e.Argument; - - UIKernel.Instance.PlaybackManager.Play(new PlayOptions - { - Items = new List { viewModel.Item } - }); - } - - /// - /// Called when [item changed]. - /// - protected override async void OnItemChanged() - { - BaseItemDto[] result; - - try - { - result = await UIKernel.Instance.ApiClient.GetLocalTrailersAsync(App.Instance.CurrentUser.Id, Item.Id); - } - catch (HttpException) - { - App.Instance.ShowDefaultErrorMessage(); - - return; - } - - var resultItems = result ?? new BaseItemDto[] { }; - - const int height = 297; - var aspectRatio = DtoBaseItemViewModel.GetAveragePrimaryImageAspectRatio(resultItems); - - var width = aspectRatio == 0 ? 528 : height * aspectRatio; - - if (Item.TrailerUrls != null) - { - //resultItems.AddRange(Item.TrailerUrls.Select(i => UIKernel.Instance.PlaybackManager.GetPlayableItem(new Uri(i), "Trailer"))); - } - - lstItems.ItemsSource = resultItems.Select(i => new SpecialFeatureViewModel - { - Item = i, - ImageHeight = height, - ImageWidth = width - - }).ToList(); - } - } -} diff --git a/MediaBrowser.Plugins.DefaultTheme/Controls/Details/MediaStreamControl.xaml b/MediaBrowser.Plugins.DefaultTheme/Controls/Details/MediaStreamControl.xaml deleted file mode 100644 index e841693fed..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/Controls/Details/MediaStreamControl.xaml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - diff --git a/MediaBrowser.Plugins.DefaultTheme/Controls/Details/MediaStreamControl.xaml.cs b/MediaBrowser.Plugins.DefaultTheme/Controls/Details/MediaStreamControl.xaml.cs deleted file mode 100644 index c0271cdab3..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/Controls/Details/MediaStreamControl.xaml.cs +++ /dev/null @@ -1,142 +0,0 @@ -using MediaBrowser.Model.Entities; -using MediaBrowser.UI.Controls; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Windows.Controls; - -namespace MediaBrowser.Plugins.DefaultTheme.Controls.Details -{ - /// - /// Interaction logic for MediaStreamControl.xaml - /// - public partial class MediaStreamControl : BaseUserControl - { - private static readonly CultureInfo UsCulture = new CultureInfo("en-US"); - - /// - /// Initializes a new instance of the class. - /// - public MediaStreamControl() - { - InitializeComponent(); - } - - /// - /// The _media stream - /// - private MediaStream _mediaStream; - /// - /// Gets or sets the media stream. - /// - /// The media stream. - public MediaStream MediaStream - { - get { return _mediaStream; } - set - { - _mediaStream = value; - OnPropertyChanged("MediaStream"); - OnStreamChanged(); - } - } - - /// - /// Called when [stream changed]. - /// - private void OnStreamChanged() - { - if (MediaStream == null) - { - StreamName.Text = string.Empty; - StreamDetails.Children.Clear(); - return; - } - - var details = new List { }; - - if (MediaStream.Type != MediaStreamType.Video) - { - AddDetail(details, MediaStream.Language); - } - - if (!string.IsNullOrEmpty(MediaStream.Path)) - { - AddDetail(details, Path.GetFileName(MediaStream.Path)); - } - - if (MediaStream.Type == MediaStreamType.Video) - { - var resolution = string.Format("{0}*{1}", MediaStream.Width, MediaStream.Height); - - AddDetail(details, resolution); - } - - AddDetail(details, MediaStream.AspectRatio); - - if (MediaStream.Type != MediaStreamType.Video) - { - if (MediaStream.IsDefault) - { - //AddDetail(details, "default"); - } - if (MediaStream.IsForced) - { - AddDetail(details, "forced"); - } - } - - AddDetail(details, MediaStream.Codec); - - if (MediaStream.Channels.HasValue) - { - AddDetail(details, MediaStream.Channels.Value.ToString(UsCulture) + "ch"); - } - - if (MediaStream.BitRate.HasValue) - { - var text = (MediaStream.BitRate.Value / 1000).ToString(UsCulture) + "kbps"; - - AddDetail(details, text); - } - - var framerate = MediaStream.AverageFrameRate ?? MediaStream.RealFrameRate ?? 0; - - if (framerate > 0) - { - AddDetail(details, framerate.ToString(UsCulture)); - } - - if (MediaStream.SampleRate.HasValue) - { - AddDetail(details, MediaStream.SampleRate.Value.ToString(UsCulture) + "khz"); - } - - AddDetail(string.Join(" \u2022 ", details.ToArray())); - - StreamName.Text = MediaStream.Type.ToString(); - } - - private void AddDetail(string text) - { - if (string.IsNullOrEmpty(text)) - { - return; - } - - var control = new TextBlock() { Text = text }; - control.SetResourceReference(StyleProperty, "TextBlockStyle"); - StreamDetails.Children.Add(control); - } - - private void AddDetail(ICollection list, string text) - { - if (string.IsNullOrEmpty(text)) - { - return; - } - - list.Add(text); - } - } -} diff --git a/MediaBrowser.Plugins.DefaultTheme/Controls/HomePageTile.xaml b/MediaBrowser.Plugins.DefaultTheme/Controls/HomePageTile.xaml deleted file mode 100644 index 8de68eff9b..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/Controls/HomePageTile.xaml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/MediaBrowser.Plugins.DefaultTheme/Controls/HomePageTile.xaml.cs b/MediaBrowser.Plugins.DefaultTheme/Controls/HomePageTile.xaml.cs deleted file mode 100644 index 9753851fac..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/Controls/HomePageTile.xaml.cs +++ /dev/null @@ -1,128 +0,0 @@ -using MediaBrowser.Model.Dto; -using MediaBrowser.Model.Entities; -using MediaBrowser.Model.Net; -using MediaBrowser.UI; -using MediaBrowser.UI.Controls; -using MediaBrowser.UI.ViewModels; -using System; -using System.Windows; - -namespace MediaBrowser.Plugins.DefaultTheme.Controls -{ - /// - /// Interaction logic for BaseItemTile.xaml - /// - public partial class HomePageTile : BaseUserControl - { - /// - /// Gets the view model. - /// - /// The view model. - public DtoBaseItemViewModel ViewModel - { - get { return DataContext as DtoBaseItemViewModel; } - } - - /// - /// Gets the item. - /// - /// The item. - private BaseItemDto Item - { - get { return ViewModel.Item; } - } - - /// - /// Initializes a new instance of the class. - /// - public HomePageTile() - { - InitializeComponent(); - - DataContextChanged += BaseItemTile_DataContextChanged; - } - - /// - /// Handles the DataContextChanged event of the BaseItemTile control. - /// - /// The source of the event. - /// The instance containing the event data. - void BaseItemTile_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e) - { - OnItemChanged(); - } - - /// - /// Called when [item changed]. - /// - private void OnItemChanged() - { - ReloadImage(); - } - - /// - /// Reloads the image. - /// - private void ReloadImage() - { - if (Item.HasPrimaryImage) - { - var url = App.Instance.ApiClient.GetImageUrl(Item, new ImageOptions - { - ImageType = ImageType.Primary, - Height = 225 - }); - - SetImage(url); - } - else if (Item.BackdropCount > 0) - { - var url = App.Instance.ApiClient.GetImageUrl(Item, new ImageOptions - { - ImageType = ImageType.Backdrop, - Height = 225, - Width = 400 - }); - - SetImage(url); - } - else if (Item.HasThumb) - { - var url = App.Instance.ApiClient.GetImageUrl(Item, new ImageOptions - { - ImageType = ImageType.Thumb, - Height = 225, - Width = 400 - }); - - SetImage(url); - } - else - { - SetDefaultImage(); - } - } - - /// - /// Sets the image. - /// - /// The URL. - private async void SetImage(string url) - { - try - { - image.Source = await App.Instance.GetRemoteBitmapAsync(url); - } - catch (HttpException) - { - SetDefaultImage(); - } - } - - private void SetDefaultImage() - { - var imageUri = new Uri("../Resources/Images/VideoDefault.png", UriKind.Relative); - image.Source = App.Instance.GetBitmapImage(imageUri); - } - } -} diff --git a/MediaBrowser.Plugins.DefaultTheme/Controls/MultiItemTile.xaml b/MediaBrowser.Plugins.DefaultTheme/Controls/MultiItemTile.xaml deleted file mode 100644 index 000fc95845..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/Controls/MultiItemTile.xaml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - diff --git a/MediaBrowser.Plugins.DefaultTheme/Controls/MultiItemTile.xaml.cs b/MediaBrowser.Plugins.DefaultTheme/Controls/MultiItemTile.xaml.cs deleted file mode 100644 index 51339647a7..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/Controls/MultiItemTile.xaml.cs +++ /dev/null @@ -1,219 +0,0 @@ -using MediaBrowser.Model.Dto; -using MediaBrowser.Model.Entities; -using MediaBrowser.Model.Net; -using MediaBrowser.UI; -using MediaBrowser.UI.Controls; -using MediaBrowser.UI.ViewModels; -using Microsoft.Expression.Media.Effects; -using System; -using System.ComponentModel; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Media; - -namespace MediaBrowser.Plugins.DefaultTheme.Controls -{ - /// - /// Interaction logic for MultiItemTile.xaml - /// - public partial class MultiItemTile : BaseUserControl - { - /// - /// The _image width - /// - private int _imageWidth; - /// - /// Gets or sets the width of the image. - /// - /// The width of the image. - public int ImageWidth - { - get { return _imageWidth; } - set - { - _imageWidth = value; - mainGrid.Width = value; - } - } - - /// - /// The _image height - /// - private int _imageHeight; - /// - /// Gets or sets the height of the image. - /// - /// The height of the image. - public int ImageHeight - { - get { return _imageHeight; } - set - { - _imageHeight = value; - mainGrid.Height = value; - } - } - - /// - /// The _effects - /// - TransitionEffect[] _effects = new TransitionEffect[] - { - new BlindsTransitionEffect { Orientation = BlindOrientation.Horizontal }, - new BlindsTransitionEffect { Orientation = BlindOrientation.Vertical }, - new CircleRevealTransitionEffect { }, - new FadeTransitionEffect { }, - new SlideInTransitionEffect { SlideDirection= SlideDirection.TopToBottom}, - new SlideInTransitionEffect { SlideDirection= SlideDirection.RightToLeft}, - new WipeTransitionEffect { WipeDirection = WipeDirection.RightToLeft}, - new WipeTransitionEffect { WipeDirection = WipeDirection.TopLeftToBottomRight} - }; - - /// - /// Gets or sets the random. - /// - /// The random. - private Random Random { get; set; } - - /// - /// Gets the collection. - /// - /// The collection. - public ItemCollectionViewModel Collection - { - get { return DataContext as ItemCollectionViewModel; } - } - - /// - /// Initializes a new instance of the class. - /// - public MultiItemTile() - { - InitializeComponent(); - - Random = new Random(Guid.NewGuid().GetHashCode()); - - mainGrid.Width = ImageWidth; - mainGrid.Height = ImageHeight; - DataContextChanged += BaseItemTile_DataContextChanged; - } - - /// - /// Handles the DataContextChanged event of the BaseItemTile control. - /// - /// The source of the event. - /// The instance containing the event data. - void BaseItemTile_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e) - { - OnCurrentItemChanged(); - - if (Collection != null) - { - Collection.PropertyChanged += Collection_PropertyChanged; - } - } - - /// - /// Handles the PropertyChanged event of the Collection control. - /// - /// The source of the event. - /// The instance containing the event data. - void Collection_PropertyChanged(object sender, PropertyChangedEventArgs e) - { - if (e.PropertyName.Equals("CurrentItem")) - { - OnCurrentItemChanged(); - } - } - - /// - /// Called when [current item changed]. - /// - private async void OnCurrentItemChanged() - { - if (Collection == null) - { - // Setting this to null doesn't seem to clear out the content - transitionControl.Content = new FrameworkElement(); - txtName.Text = null; - return; - } - - var currentItem = Collection.CurrentItem; - - if (currentItem == null) - { - // Setting this to null doesn't seem to clear out the content - transitionControl.Content = new FrameworkElement(); - txtName.Text = Collection.Name; - return; - } - - var img = new Image - { - Stretch = Stretch.Uniform, - Width = ImageWidth, - Height = ImageHeight - }; - - var url = GetImageSource(currentItem); - - if (!string.IsNullOrEmpty(url)) - { - try - { - img.Source = await App.Instance.GetRemoteBitmapAsync(url); - txtName.Text = Collection.Name ?? currentItem.Name; - } - catch (HttpException) - { - } - } - - transitionControl.TransitionType = _effects[Random.Next(0, _effects.Length)]; - transitionControl.Content = img; - } - - /// - /// Gets the image source. - /// - /// The item. - /// Uri. - private string GetImageSource(BaseItemDto item) - { - if (item != null) - { - if (item.BackdropCount > 0) - { - return App.Instance.ApiClient.GetImageUrl(item, new ImageOptions - { - ImageType = ImageType.Backdrop, - Height = ImageHeight, - Width = ImageWidth - }); - } - - if (item.HasThumb) - { - return App.Instance.ApiClient.GetImageUrl(item, new ImageOptions - { - ImageType = ImageType.Thumb, - Height = ImageHeight, - Width = ImageWidth - }); - } - - if (item.HasPrimaryImage) - { - return App.Instance.ApiClient.GetImageUrl(item, new ImageOptions - { - ImageType = ImageType.Primary, - Height = ImageHeight - }); - } - } - - return null; - } - } -} diff --git a/MediaBrowser.Plugins.DefaultTheme/Converters/WeatherImageConverter.cs b/MediaBrowser.Plugins.DefaultTheme/Converters/WeatherImageConverter.cs deleted file mode 100644 index aeb8f60cef..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/Converters/WeatherImageConverter.cs +++ /dev/null @@ -1,48 +0,0 @@ -using MediaBrowser.Model.Weather; -using System; -using System.Globalization; -using System.Windows.Data; - -namespace MediaBrowser.Plugins.DefaultTheme.Converters -{ - /// - /// Generates a weather image based on the current forecast - /// - public class WeatherImageConverter : IValueConverter - { - public object Convert(object value, Type targetType, object parameter, CultureInfo culture) - { - var weather = value as WeatherInfo; - - if (weather != null && weather.CurrentWeather != null) - { - switch (weather.CurrentWeather.Condition) - { - case WeatherConditions.Thunderstorm: - return "../Resources/Images/Weather/Thunder.png"; - case WeatherConditions.Overcast: - return "../Resources/Images/Weather/Overcast.png"; - case WeatherConditions.Mist: - case WeatherConditions.Sleet: - case WeatherConditions.Rain: - return "../Resources/Images/Weather/Rain.png"; - case WeatherConditions.Blizzard: - case WeatherConditions.Snow: - return "../Resources/Images/Weather/Snow.png"; - case WeatherConditions.Cloudy: - return "../Resources/Images/Weather/Cloudy.png"; - case WeatherConditions.PartlyCloudy: - return "../Resources/Images/Weather/PartlyCloudy.png"; - default: - return "../Resources/Images/Weather/Sunny.png"; - } - } - return null; - } - - public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) - { - throw new NotImplementedException(); - } - } -} diff --git a/MediaBrowser.Plugins.DefaultTheme/DisplayPreferences/BaseDisplayPreferencesPage.cs b/MediaBrowser.Plugins.DefaultTheme/DisplayPreferences/BaseDisplayPreferencesPage.cs deleted file mode 100644 index b261ae0c2e..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/DisplayPreferences/BaseDisplayPreferencesPage.cs +++ /dev/null @@ -1,25 +0,0 @@ -using MediaBrowser.UI.Pages; - -namespace MediaBrowser.Plugins.DefaultTheme.DisplayPreferences -{ - /// - /// Class BaseDisplayPreferencesPage - /// - public class BaseDisplayPreferencesPage : BasePage - { - /// - /// Gets or sets the display preferences window. - /// - /// The display preferences window. - public DisplayPreferencesMenu DisplayPreferencesWindow { get; set; } - - /// - /// Gets the main page. - /// - /// The main page. - protected BaseListPage MainPage - { - get { return DisplayPreferencesWindow.MainPage; } - } - } -} diff --git a/MediaBrowser.Plugins.DefaultTheme/DisplayPreferences/DisplayPreferencesMenu.xaml b/MediaBrowser.Plugins.DefaultTheme/DisplayPreferences/DisplayPreferencesMenu.xaml deleted file mode 100644 index 62dea39cd7..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/DisplayPreferences/DisplayPreferencesMenu.xaml +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Close - - - - - - - - - - diff --git a/MediaBrowser.Plugins.DefaultTheme/DisplayPreferences/DisplayPreferencesMenu.xaml.cs b/MediaBrowser.Plugins.DefaultTheme/DisplayPreferences/DisplayPreferencesMenu.xaml.cs deleted file mode 100644 index 04e65cd429..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/DisplayPreferences/DisplayPreferencesMenu.xaml.cs +++ /dev/null @@ -1,92 +0,0 @@ -using MediaBrowser.UI.Controls; -using MediaBrowser.UI.Pages; -using System.Windows; - -namespace MediaBrowser.Plugins.DefaultTheme.DisplayPreferences -{ - /// - /// Interaction logic for DisplayPreferencesMenu.xaml - /// - public partial class DisplayPreferencesMenu : BaseModalWindow - { - /// - /// Gets or sets the main page. - /// - /// The main page. - public BaseListPage MainPage { get; set; } - /// - /// Gets or sets the folder id. - /// - /// The folder id. - public string FolderId { get; set; } - - /// - /// Initializes a new instance of the class. - /// - public DisplayPreferencesMenu() - { - InitializeComponent(); - - btnClose.Click += btnClose_Click; - } - - /// - /// Handles the Click event of the btnClose control. - /// - /// The source of the event. - /// The instance containing the event data. - void btnClose_Click(object sender, RoutedEventArgs e) - { - CloseModal(); - } - - /// - /// Closes the modal. - /// - protected override void CloseModal() - { - if (PageFrame.CanGoBack) - { - PageFrame.GoBackWithTransition(); - } - else - { - base.CloseModal(); - } - } - - /// - /// Called when [loaded]. - /// - protected override void OnLoaded() - { - base.OnLoaded(); - - PageFrame.Navigate(new MainPage { DisplayPreferencesWindow = this }); - } - - /// - /// Navigates to view menu. - /// - public void NavigateToViewMenu() - { - PageFrame.NavigateWithTransition(new ViewMenuPage { DisplayPreferencesWindow = this }); - } - - /// - /// Navigates to index menu. - /// - public void NavigateToIndexMenu() - { - PageFrame.NavigateWithTransition(new IndexMenuPage { DisplayPreferencesWindow = this }); - } - - /// - /// Navigates to sort menu. - /// - public void NavigateToSortMenu() - { - PageFrame.NavigateWithTransition(new SortMenuPage { DisplayPreferencesWindow = this }); - } - } -} diff --git a/MediaBrowser.Plugins.DefaultTheme/DisplayPreferences/IndexMenuPage.xaml b/MediaBrowser.Plugins.DefaultTheme/DisplayPreferences/IndexMenuPage.xaml deleted file mode 100644 index dc7f30ccda..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/DisplayPreferences/IndexMenuPage.xaml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - Index By - - - - - - - diff --git a/MediaBrowser.Plugins.DefaultTheme/DisplayPreferences/IndexMenuPage.xaml.cs b/MediaBrowser.Plugins.DefaultTheme/DisplayPreferences/IndexMenuPage.xaml.cs deleted file mode 100644 index 63fa1b84dd..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/DisplayPreferences/IndexMenuPage.xaml.cs +++ /dev/null @@ -1,95 +0,0 @@ -using MediaBrowser.Model.Net; -using MediaBrowser.UI; -using MediaBrowser.UI.Controls; -using System; -using System.Windows; -using System.Windows.Controls; - -namespace MediaBrowser.Plugins.DefaultTheme.DisplayPreferences -{ - /// - /// Interaction logic for IndexMenuPage.xaml - /// - public partial class IndexMenuPage : BaseDisplayPreferencesPage - { - /// - /// Initializes a new instance of the class. - /// - public IndexMenuPage() - { - InitializeComponent(); - - chkRememberIndex.Click += chkRememberIndex_Click; - } - - /// - /// Handles the Click event of the chkRememberIndex control. - /// - /// The source of the event. - /// The instance containing the event data. - async void chkRememberIndex_Click(object sender, RoutedEventArgs e) - { - try - { - await MainPage.UpdateRememberIndex(chkRememberIndex.IsChecked.HasValue && chkRememberIndex.IsChecked.Value); - } - catch (HttpException) - { - App.Instance.ShowDefaultErrorMessage(); - } - } - - /// - /// Called when [loaded]. - /// - protected override void OnLoaded() - { - chkRememberIndex.IsChecked = MainPage.DisplayPreferences.RememberIndexing; - - var index = 0; - - var currentValue = MainPage.IndexBy ?? string.Empty; - - foreach (var option in MainPage.Folder.IndexOptions) - { - var radio = new ExtendedRadioButton { GroupName = "Options" }; - - radio.SetResourceReference(StyleProperty, "ViewMenuRadioButton"); - - var textblock = new TextBlock { Text = option }; - - textblock.SetResourceReference(StyleProperty, "TextBlockStyle"); - - radio.Content = textblock; - - if (string.IsNullOrEmpty(MainPage.DisplayPreferences.IndexBy)) - { - radio.IsChecked = index == 0; - } - else - { - radio.IsChecked = currentValue.Equals(option, StringComparison.OrdinalIgnoreCase); - } - - radio.Tag = option; - radio.Click += radio_Click; - - pnlOptions.Children.Add(radio); - - index++; - } - - base.OnLoaded(); - } - - /// - /// Handles the Click event of the radio control. - /// - /// The source of the event. - /// The instance containing the event data. - async void radio_Click(object sender, RoutedEventArgs e) - { - await MainPage.UpdateIndexOption((sender as RadioButton).Tag.ToString()); - } - } -} diff --git a/MediaBrowser.Plugins.DefaultTheme/DisplayPreferences/MainPage.xaml b/MediaBrowser.Plugins.DefaultTheme/DisplayPreferences/MainPage.xaml deleted file mode 100644 index a8a8ca5770..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/DisplayPreferences/MainPage.xaml +++ /dev/null @@ -1,54 +0,0 @@ - - - - - Display Options - - - - - View Menu - - - - - - Sort Menu - - - - - - Index Menu - - - - - - Increase Image Size - - - - - - Decrease Image Size - - - - - - Scroll: Vertical - - - - - diff --git a/MediaBrowser.Plugins.DefaultTheme/DisplayPreferences/MainPage.xaml.cs b/MediaBrowser.Plugins.DefaultTheme/DisplayPreferences/MainPage.xaml.cs deleted file mode 100644 index ffe269f770..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/DisplayPreferences/MainPage.xaml.cs +++ /dev/null @@ -1,118 +0,0 @@ -using MediaBrowser.Model.Entities; -using System.Windows; - -namespace MediaBrowser.Plugins.DefaultTheme.DisplayPreferences -{ - /// - /// Interaction logic for MainPage.xaml - /// - public partial class MainPage : BaseDisplayPreferencesPage - { - /// - /// Initializes a new instance of the class. - /// - public MainPage() - { - InitializeComponent(); - - btnScroll.Click += btnScroll_Click; - btnIncrease.Click += btnIncrease_Click; - btnDecrease.Click += btnDecrease_Click; - ViewMenuButton.Click += ViewMenuButton_Click; - SortMenuButton.Click += SortMenuButton_Click; - IndexMenuButton.Click += IndexMenuButton_Click; - } - - /// - /// Handles the Click event of the IndexMenuButton control. - /// - /// The source of the event. - /// The instance containing the event data. - void IndexMenuButton_Click(object sender, RoutedEventArgs e) - { - DisplayPreferencesWindow.NavigateToIndexMenu(); - } - - /// - /// Handles the Click event of the SortMenuButton control. - /// - /// The source of the event. - /// The instance containing the event data. - void SortMenuButton_Click(object sender, RoutedEventArgs e) - { - DisplayPreferencesWindow.NavigateToSortMenu(); - } - - /// - /// Called when [loaded]. - /// - protected override void OnLoaded() - { - base.OnLoaded(); - - UpdateFields(); - } - - /// - /// Handles the Click event of the ViewMenuButton control. - /// - /// The source of the event. - /// The instance containing the event data. - void ViewMenuButton_Click(object sender, RoutedEventArgs e) - { - DisplayPreferencesWindow.NavigateToViewMenu(); - } - - /// - /// Handles the Click event of the btnDecrease control. - /// - /// The source of the event. - /// The instance containing the event data. - void btnDecrease_Click(object sender, RoutedEventArgs e) - { - MainPage.DisplayPreferences.DecreaseImageSize(); - MainPage.NotifyDisplayPreferencesChanged(); - } - - /// - /// Handles the Click event of the btnIncrease control. - /// - /// The source of the event. - /// The instance containing the event data. - void btnIncrease_Click(object sender, RoutedEventArgs e) - { - MainPage.DisplayPreferences.IncreaseImageSize(); - MainPage.NotifyDisplayPreferencesChanged(); - } - - /// - /// Handles the Click event of the btnScroll control. - /// - /// The source of the event. - /// The instance containing the event data. - void btnScroll_Click(object sender, RoutedEventArgs e) - { - MainPage.DisplayPreferences.ScrollDirection = MainPage.DisplayPreferences.ScrollDirection == ScrollDirection.Horizontal - ? ScrollDirection.Vertical - : ScrollDirection.Horizontal; - - MainPage.NotifyDisplayPreferencesChanged(); - - UpdateFields(); - } - - /// - /// Updates the fields. - /// - private void UpdateFields() - { - var displayPreferences = MainPage.DisplayPreferences; - - btnScroll.Visibility = displayPreferences.ViewType == ViewTypes.Poster - ? Visibility.Visible - : Visibility.Collapsed; - - txtScrollDirection.Text = displayPreferences.ScrollDirection == ScrollDirection.Horizontal ? "Scroll: Horizontal" : "Scroll: Vertical"; - } - } -} diff --git a/MediaBrowser.Plugins.DefaultTheme/DisplayPreferences/SortMenuPage.xaml b/MediaBrowser.Plugins.DefaultTheme/DisplayPreferences/SortMenuPage.xaml deleted file mode 100644 index 35ea6e13dc..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/DisplayPreferences/SortMenuPage.xaml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - Sort By - - - - - - - diff --git a/MediaBrowser.Plugins.DefaultTheme/DisplayPreferences/SortMenuPage.xaml.cs b/MediaBrowser.Plugins.DefaultTheme/DisplayPreferences/SortMenuPage.xaml.cs deleted file mode 100644 index 6d6068d167..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/DisplayPreferences/SortMenuPage.xaml.cs +++ /dev/null @@ -1,95 +0,0 @@ -using MediaBrowser.Model.Net; -using MediaBrowser.UI; -using MediaBrowser.UI.Controls; -using System; -using System.Windows; -using System.Windows.Controls; - -namespace MediaBrowser.Plugins.DefaultTheme.DisplayPreferences -{ - /// - /// Interaction logic for SortMenuPage.xaml - /// - public partial class SortMenuPage : BaseDisplayPreferencesPage - { - /// - /// Initializes a new instance of the class. - /// - public SortMenuPage() - { - InitializeComponent(); - - chkRemember.Click += chkRemember_Click; - } - - /// - /// Handles the Click event of the chkRemember control. - /// - /// The source of the event. - /// The instance containing the event data. - async void chkRemember_Click(object sender, RoutedEventArgs e) - { - try - { - await MainPage.UpdateRememberSort(chkRemember.IsChecked.HasValue && chkRemember.IsChecked.Value); - } - catch (HttpException) - { - App.Instance.ShowDefaultErrorMessage(); - } - } - - /// - /// Called when [loaded]. - /// - protected override void OnLoaded() - { - chkRemember.IsChecked = MainPage.DisplayPreferences.RememberSorting; - - var index = 0; - - var currentValue = MainPage.SortBy ?? string.Empty; - - foreach (var option in MainPage.Folder.SortOptions) - { - var radio = new ExtendedRadioButton { GroupName = "Options" }; - - radio.SetResourceReference(StyleProperty, "ViewMenuRadioButton"); - - var textblock = new TextBlock { Text = option }; - - textblock.SetResourceReference(StyleProperty, "TextBlockStyle"); - - radio.Content = textblock; - - if (string.IsNullOrEmpty(MainPage.DisplayPreferences.SortBy)) - { - radio.IsChecked = index == 0; - } - else - { - radio.IsChecked = currentValue.Equals(option, StringComparison.OrdinalIgnoreCase); - } - - radio.Tag = option; - radio.Click += radio_Click; - - pnlOptions.Children.Add(radio); - - index++; - } - - base.OnLoaded(); - } - - /// - /// Handles the Click event of the radio control. - /// - /// The source of the event. - /// The instance containing the event data. - async void radio_Click(object sender, RoutedEventArgs e) - { - await MainPage.UpdateSortOption((sender as RadioButton).Tag.ToString()); - } - } -} diff --git a/MediaBrowser.Plugins.DefaultTheme/DisplayPreferences/ViewMenuPage.xaml b/MediaBrowser.Plugins.DefaultTheme/DisplayPreferences/ViewMenuPage.xaml deleted file mode 100644 index cc4114e7af..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/DisplayPreferences/ViewMenuPage.xaml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - Select View - - Cover Flow - - - List - - - Poster - - - Thumbstrip - - - - diff --git a/MediaBrowser.Plugins.DefaultTheme/DisplayPreferences/ViewMenuPage.xaml.cs b/MediaBrowser.Plugins.DefaultTheme/DisplayPreferences/ViewMenuPage.xaml.cs deleted file mode 100644 index e164809cf1..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/DisplayPreferences/ViewMenuPage.xaml.cs +++ /dev/null @@ -1,94 +0,0 @@ -using MediaBrowser.Model.Entities; -using System.Windows; - -namespace MediaBrowser.Plugins.DefaultTheme.DisplayPreferences -{ - /// - /// Interaction logic for ViewMenuPage.xaml - /// - public partial class ViewMenuPage : BaseDisplayPreferencesPage - { - /// - /// Initializes a new instance of the class. - /// - public ViewMenuPage() - { - InitializeComponent(); - - radioCoverFlow.Click += radioCoverFlow_Click; - radioList.Click += radioList_Click; - radioPoster.Click += radioPoster_Click; - radioThumbstrip.Click += radioThumbstrip_Click; - } - - /// - /// Called when [loaded]. - /// - protected override void OnLoaded() - { - base.OnLoaded(); - - UpdateFields(); - } - - /// - /// Handles the Click event of the radioThumbstrip control. - /// - /// The source of the event. - /// The instance containing the event data. - void radioThumbstrip_Click(object sender, RoutedEventArgs e) - { - MainPage.DisplayPreferences.ScrollDirection = ScrollDirection.Horizontal; - MainPage.DisplayPreferences.ViewType = ViewTypes.ThumbStrip; - MainPage.NotifyDisplayPreferencesChanged(); - } - - /// - /// Handles the Click event of the radioPoster control. - /// - /// The source of the event. - /// The instance containing the event data. - void radioPoster_Click(object sender, RoutedEventArgs e) - { - MainPage.DisplayPreferences.ViewType = ViewTypes.Poster; - MainPage.NotifyDisplayPreferencesChanged(); - } - - /// - /// Handles the Click event of the radioList control. - /// - /// The source of the event. - /// The instance containing the event data. - void radioList_Click(object sender, RoutedEventArgs e) - { - MainPage.DisplayPreferences.ScrollDirection = ScrollDirection.Vertical; - MainPage.DisplayPreferences.ViewType = ViewTypes.List; - MainPage.NotifyDisplayPreferencesChanged(); - } - - /// - /// Handles the Click event of the radioCoverFlow control. - /// - /// The source of the event. - /// The instance containing the event data. - void radioCoverFlow_Click(object sender, RoutedEventArgs e) - { - MainPage.DisplayPreferences.ScrollDirection = ScrollDirection.Horizontal; - MainPage.DisplayPreferences.ViewType = ViewTypes.CoverFlow; - MainPage.NotifyDisplayPreferencesChanged(); - } - - /// - /// Updates the fields. - /// - private void UpdateFields() - { - var displayPreferences = MainPage.DisplayPreferences; - - radioCoverFlow.IsChecked = displayPreferences.ViewType == ViewTypes.CoverFlow; - radioList.IsChecked = displayPreferences.ViewType == ViewTypes.List; - radioPoster.IsChecked = displayPreferences.ViewType == ViewTypes.Poster; - radioThumbstrip.IsChecked = displayPreferences.ViewType == ViewTypes.ThumbStrip; - } - } -} diff --git a/MediaBrowser.Plugins.DefaultTheme/MediaBrowser.Plugins.DefaultTheme.csproj b/MediaBrowser.Plugins.DefaultTheme/MediaBrowser.Plugins.DefaultTheme.csproj deleted file mode 100644 index f0176049d3..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/MediaBrowser.Plugins.DefaultTheme.csproj +++ /dev/null @@ -1,354 +0,0 @@ - - - - - Debug - AnyCPU - {6E892999-711D-4E24-8BAC-DACF5BFA783A} - library - Properties - MediaBrowser.Plugins.DefaultTheme - MediaBrowser.Plugins.DefaultTheme - v4.5 - 512 - {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - 4 - 5.2.30810.0 - ..\ - true - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - Always - - - - False - ..\ThirdParty\Expression\Microsoft.Expression.Effects.dll - - - False - ..\ThirdParty\Expression\Microsoft.Expression.Interactions.dll - - - - - - - - - - - - 4.0 - - - - - - - - BaseItemTile.xaml - - - - ItemChapters.xaml - - - ItemGallery.xaml - - - ItemMediaInfo.xaml - - - ItemOverview.xaml - - - ItemPerformers.xaml - - - ItemSpecialFeatures.xaml - - - ItemTrailers.xaml - - - MediaStreamControl.xaml - - - HomePageTile.xaml - - - MultiItemTile.xaml - - - - DisplayPreferencesMenu.xaml - - - IndexMenuPage.xaml - - - MainPage.xaml - - - SortMenuPage.xaml - - - ViewMenuPage.xaml - - - DetailPage.xaml - - - HomePage.xaml - - - InternalPlayerPage.xaml - - - ListPage.xaml - - - LoginPage.xaml - - - WeatherPage.xaml - - - - - Code - - - True - True - Resources.resx - - - True - Settings.settings - True - - - - ResXFileCodeGenerator - Resources.Designer.cs - - - - SettingsSingleFileGenerator - Settings.Designer.cs - - - - - - {921c0f64-fda7-4e9f-9e73-0cb0eedb2422} - MediaBrowser.ApiInteraction - - - {9142eefa-7570-41e1-bfcc-468bb571af2f} - MediaBrowser.Common - - - {7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b} - MediaBrowser.Model - - - {1adfe460-fd95-46fa-8871-cccb4b62e2e8} - MediaBrowser.UI.Controls - - - {b5ece1fb-618e-420b-9a99-8e972d76920a} - MediaBrowser.UI - - - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - MSBuild:Compile - Designer - true - - - Designer - MSBuild:Compile - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - xcopy "$(TargetPath)" "$(SolutionDir)\MediaBrowser.UI\CorePlugins\" /y - - - - \ No newline at end of file diff --git a/MediaBrowser.Plugins.DefaultTheme/Model/VirtualCollection.cs b/MediaBrowser.Plugins.DefaultTheme/Model/VirtualCollection.cs deleted file mode 100644 index 9bdf611296..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/Model/VirtualCollection.cs +++ /dev/null @@ -1,90 +0,0 @@ -using MediaBrowser.Model.DTO; -using MediaBrowser.UI.Controls; -using System; -using System.Threading; -using System.Windows; - -namespace MediaBrowser.Plugins.DefaultTheme.Model -{ - public class VirtualCollection : ModelItem, IDisposable - { - private string _name; - public string Name - { - get { return _name; } - set - { - _name = value; - OnPropertyChanged("Name"); - } - } - - private DtoBaseItem[] _items; - public DtoBaseItem[] Items - { - get { return _items; } - set - { - _items = value; - OnPropertyChanged("Items"); - CurrentItemIndex = Items.Length == 0 ? -1 : 0; - - ReloadTimer(); - } - } - - private int _currentItemIndex; - public int CurrentItemIndex - { - get { return _currentItemIndex; } - set - { - _currentItemIndex = value; - OnPropertyChanged("CurrentItemIndex"); - OnPropertyChanged("CurrentItem"); - } - } - - public DtoBaseItem CurrentItem - { - get { return CurrentItemIndex == -1 ? null : Items[CurrentItemIndex]; } - } - - private Timer CurrentItemTimer { get; set; } - - private void DisposeTimer() - { - if (CurrentItemTimer != null) - { - CurrentItemTimer.Dispose(); - } - } - - private void ReloadTimer() - { - DisposeTimer(); - - if (Items.Length > 0) - { - CurrentItemTimer = new Timer(state => Application.Current.Dispatcher.InvokeAsync(() => IncrementCurrentItemIndex()), null, 5000, 5000); - } - } - - private void IncrementCurrentItemIndex() - { - var newIndex = CurrentItemIndex + 1; - - if (newIndex >= Items.Length) - { - newIndex = 0; - } - - CurrentItemIndex = newIndex; - } - - public void Dispose() - { - DisposeTimer(); - } - } -} diff --git a/MediaBrowser.Plugins.DefaultTheme/Pages/DetailPage.xaml b/MediaBrowser.Plugins.DefaultTheme/Pages/DetailPage.xaml deleted file mode 100644 index 1d554e8d94..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/Pages/DetailPage.xaml +++ /dev/null @@ -1,102 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - overview - - - - - media info - - - - - scenes - - - - - trailers - - - - - special features - - - - - performers - - - - - gallery - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/MediaBrowser.Plugins.DefaultTheme/Pages/DetailPage.xaml.cs b/MediaBrowser.Plugins.DefaultTheme/Pages/DetailPage.xaml.cs deleted file mode 100644 index e907ca6a05..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/Pages/DetailPage.xaml.cs +++ /dev/null @@ -1,268 +0,0 @@ -using MediaBrowser.Model.Dto; -using MediaBrowser.Model.Entities; -using MediaBrowser.Model.Net; -using MediaBrowser.Plugins.DefaultTheme.Controls.Details; -using MediaBrowser.Plugins.DefaultTheme.Resources; -using MediaBrowser.UI; -using MediaBrowser.UI.Controller; -using MediaBrowser.UI.Pages; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Media.Imaging; - -namespace MediaBrowser.Plugins.DefaultTheme.Pages -{ - /// - /// Interaction logic for DetailPage.xaml - /// - public partial class DetailPage : BaseDetailPage - { - /// - /// Initializes a new instance of the class. - /// - /// The item id. - public DetailPage(string itemId) - : base(itemId) - { - InitializeComponent(); - - BtnOverview.Click += BtnOverview_Click; - BtnChapters.Click += BtnChapters_Click; - BtnMediaInfo.Click += BtnDetails_Click; - BtnPerformers.Click += BtnPerformers_Click; - BtnTrailers.Click += BtnTrailers_Click; - BtnSpecialFeatures.Click += BtnSpecialFeatures_Click; - BtnGallery.Click += BtnGallery_Click; - } - - /// - /// Handles the Click event of the BtnGallery control. - /// - /// The source of the event. - /// The instance containing the event data. - void BtnGallery_Click(object sender, RoutedEventArgs e) - { - PrimaryImageGrid.Visibility = Visibility.Collapsed; - ShowDetailControl(BtnGallery, new ItemGallery { }); - } - - /// - /// Handles the Click event of the BtnSpecialFeatures control. - /// - /// The source of the event. - /// The instance containing the event data. - void BtnSpecialFeatures_Click(object sender, RoutedEventArgs e) - { - PrimaryImageGrid.Visibility = Visibility.Collapsed; - ShowDetailControl(BtnSpecialFeatures, new ItemSpecialFeatures { }); - } - - /// - /// Handles the Click event of the BtnTrailers control. - /// - /// The source of the event. - /// The instance containing the event data. - void BtnTrailers_Click(object sender, RoutedEventArgs e) - { - PrimaryImageGrid.Visibility = Visibility.Collapsed; - ShowDetailControl(BtnTrailers, new ItemTrailers { }); - } - - /// - /// Handles the Click event of the BtnDetails control. - /// - /// The source of the event. - /// The instance containing the event data. - void BtnDetails_Click(object sender, RoutedEventArgs e) - { - PrimaryImageGrid.Visibility = Visibility.Visible; - ShowDetailControl(BtnMediaInfo, new ItemMediaInfo { }); - } - - /// - /// Handles the Click event of the BtnChapters control. - /// - /// The source of the event. - /// The instance containing the event data. - void BtnChapters_Click(object sender, RoutedEventArgs e) - { - PrimaryImageGrid.Visibility = Visibility.Collapsed; - ShowDetailControl(BtnChapters, new ItemChapters { }); - } - - /// - /// Handles the Click event of the BtnOverview control. - /// - /// The source of the event. - /// The instance containing the event data. - void BtnOverview_Click(object sender, RoutedEventArgs e) - { - PrimaryImageGrid.Visibility = Visibility.Visible; - ShowDetailControl(BtnOverview, new ItemOverview { }); - } - - /// - /// Handles the Click event of the BtnPerformers control. - /// - /// The source of the event. - /// The instance containing the event data. - void BtnPerformers_Click(object sender, RoutedEventArgs e) - { - PrimaryImageGrid.Visibility = Visibility.Collapsed; - ShowDetailControl(BtnPerformers, new ItemPerformers { }); - } - - /// - /// Handles the Click event of the BtnQueue control. - /// - /// The source of the event. - /// The instance containing the event data. - void BtnQueue_Click(object sender, RoutedEventArgs e) - { - Queue(); - } - - /// - /// Called when [loaded]. - /// - protected override async void OnLoaded() - { - base.OnLoaded(); - - if (Item != null) - { - await AppResources.Instance.SetPageTitle(Item); - } - } - - /// - /// Called when [item changed]. - /// - protected override async void OnItemChanged() - { - base.OnItemChanged(); - - var pageTitleTask = AppResources.Instance.SetPageTitle(Item); - - BtnOverview_Click(null, null); - - RenderItem(); - - await pageTitleTask; - } - - /// - /// Renders the item. - /// - private async void RenderItem() - { - Task primaryImageTask = null; - - if (Item.HasPrimaryImage) - { - PrimaryImage.Visibility = Visibility.Visible; - - primaryImageTask = App.Instance.GetRemoteBitmapAsync(UIKernel.Instance.ApiClient.GetImageUrl(Item, new ImageOptions - { - ImageType = ImageType.Primary, - Quality = 100 - })); - } - else - { - SetDefaultImage(); - } - - if (Item.IsType("movie") || Item.IsType("trailer")) - { - TxtName.Visibility = Visibility.Collapsed; - } - else - { - var name = Item.Name; - - if (Item.IndexNumber.HasValue) - { - name = Item.IndexNumber.Value + " - " + name; - - if (Item.ParentIndexNumber.HasValue) - { - name = Item.ParentIndexNumber.Value + "." + name; - } - } - TxtName.Text = name; - - TxtName.Visibility = Visibility.Visible; - } - - if (Item.Taglines != null && Item.Taglines.Count > 0) - { - Tagline.Visibility = Visibility.Visible; - - Tagline.Text = Item.Taglines[0]; - } - else - { - Tagline.Visibility = Visibility.Collapsed; - } - - BtnGallery.Visibility = ItemGallery.GetImages(Item).Count > 0 ? Visibility.Visible : Visibility.Collapsed; - BtnTrailers.Visibility = Item.HasTrailer ? Visibility.Visible : Visibility.Collapsed; - BtnSpecialFeatures.Visibility = Item.SpecialFeatureCount > 0 ? Visibility.Visible : Visibility.Collapsed; - BtnPerformers.Visibility = Item.People != null && Item.People.Length > 0 ? Visibility.Visible : Visibility.Collapsed; - BtnChapters.Visibility = Item.Chapters != null && Item.Chapters.Count > 0 ? Visibility.Visible : Visibility.Collapsed; - - if (primaryImageTask != null) - { - try - { - PrimaryImage.Source = await primaryImageTask; - } - catch (HttpException) - { - SetDefaultImage(); - } - } - } - - /// - /// Sets the default image. - /// - private void SetDefaultImage() - { - PrimaryImage.Visibility = Visibility.Collapsed; - } - - /// - /// Handles the 1 event of the Button_Click control. - /// - /// The source of the event. - /// The instance containing the event data. - private void Button_Click_1(object sender, RoutedEventArgs e) - { - Play(); - } - - /// - /// Handles the 2 event of the Button_Click control. - /// - /// The source of the event. - /// The instance containing the event data. - private async void Button_Click_2(object sender, RoutedEventArgs e) - { - await UIKernel.Instance.PlaybackManager.StopAllPlayback(); - } - - /// - /// Shows the detail control. - /// - /// The button. - /// The element. - private void ShowDetailControl(Button button, BaseDetailsControl element) - { - DetailContent.Content = element; - element.Item = Item; - } - } -} diff --git a/MediaBrowser.Plugins.DefaultTheme/Pages/HomePage.xaml b/MediaBrowser.Plugins.DefaultTheme/Pages/HomePage.xaml deleted file mode 100644 index 5ac73b2b3b..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/Pages/HomePage.xaml +++ /dev/null @@ -1,69 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/MediaBrowser.Plugins.DefaultTheme/Pages/HomePage.xaml.cs b/MediaBrowser.Plugins.DefaultTheme/Pages/HomePage.xaml.cs deleted file mode 100644 index 719a31f34e..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/Pages/HomePage.xaml.cs +++ /dev/null @@ -1,442 +0,0 @@ -using MediaBrowser.Model.Dto; -using MediaBrowser.Model.Entities; -using MediaBrowser.Model.Net; -using MediaBrowser.Plugins.DefaultTheme.Resources; -using MediaBrowser.UI; -using MediaBrowser.UI.Controls; -using MediaBrowser.UI.Pages; -using MediaBrowser.UI.ViewModels; -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace MediaBrowser.Plugins.DefaultTheme.Pages -{ - /// - /// Interaction logic for HomePage.xaml - /// - public partial class HomePage : BaseHomePage - { - /// - /// Initializes a new instance of the class. - /// - public HomePage() - { - InitializeComponent(); - - lstCollectionFolders.ItemInvoked += lstCollectionFolders_ItemInvoked; - } - - /// - /// The _favorite items - /// - private ItemCollectionViewModel _favoriteItems; - /// - /// Gets or sets the favorite items. - /// - /// The favorite items. - public ItemCollectionViewModel FavoriteItems - { - get { return _favoriteItems; } - - set - { - _favoriteItems = value; - OnPropertyChanged("FavoriteItems"); - } - } - - /// - /// The _resumable items - /// - private ItemCollectionViewModel _resumableItems; - /// - /// Gets or sets the resumable items. - /// - /// The resumable items. - public ItemCollectionViewModel ResumableItems - { - get { return _resumableItems; } - - set - { - _resumableItems = value; - OnPropertyChanged("ResumableItems"); - } - } - - /// - /// The _recently added items - /// - private ItemCollectionViewModel _recentlyAddedItems; - /// - /// Gets or sets the recently added items. - /// - /// The recently added items. - public ItemCollectionViewModel RecentlyAddedItems - { - get { return _recentlyAddedItems; } - - set - { - _recentlyAddedItems = value; - OnPropertyChanged("RecentlyAddedItems"); - } - } - - /// - /// The _recently played items - /// - private ItemCollectionViewModel _recentlyPlayedItems; - /// - /// Gets or sets the recently played items. - /// - /// The recently played items. - public ItemCollectionViewModel RecentlyPlayedItems - { - get { return _recentlyPlayedItems; } - - set - { - _recentlyPlayedItems = value; - OnPropertyChanged("RecentlyPlayedItems"); - } - } - - /// - /// The _spotlight items - /// - private ItemCollectionViewModel _spotlightItems; - /// - /// Gets or sets the spotlight items. - /// - /// The spotlight items. - public ItemCollectionViewModel SpotlightItems - { - get { return _spotlightItems; } - - set - { - _spotlightItems = value; - OnPropertyChanged("SpotlightItems"); - } - } - - /// - /// The _top picks - /// - private ItemCollectionViewModel _topPicks; - /// - /// Gets or sets the top picks. - /// - /// The top picks. - public ItemCollectionViewModel TopPicks - { - get { return _topPicks; } - - set - { - _topPicks = value; - OnPropertyChanged("TopPicks"); - } - } - - /// - /// LSTs the collection folders_ item invoked. - /// - /// The sender. - /// The e. - void lstCollectionFolders_ItemInvoked(object sender, ItemEventArgs e) - { - var model = e.Argument as DtoBaseItemViewModel; - - if (model != null) - { - App.Instance.NavigateToItem(model.Item); - } - } - - /// - /// Called when [loaded]. - /// - protected override void OnLoaded() - { - base.OnLoaded(); - - AppResources.Instance.SetDefaultPageTitle(); - } - - /// - /// Gets called anytime the Folder gets refreshed - /// - protected override void OnFolderChanged() - { - base.OnFolderChanged(); - - Task.Run(() => RefreshSpecialItems()); - } - - /// - /// Refreshes the special items. - /// - /// Task. - private async Task RefreshSpecialItems() - { - var tasks = new List(); - - tasks.Add(RefreshFavoriteItemsAsync()); - - // In-Progress Items - if (Folder.ResumableItemCount > 0) - { - tasks.Add(RefreshResumableItemsAsync()); - } - else - { - SetResumableItems(new BaseItemDto[] { }); - } - - // Recently Added Items - if (Folder.RecentlyAddedItemCount > 0) - { - tasks.Add(RefreshRecentlyAddedItemsAsync()); - } - else - { - SetRecentlyAddedItems(new BaseItemDto[] { }); - } - - // Recently Played Items - if (Folder.RecentlyPlayedItemCount > 0) - { - tasks.Add(RefreshRecentlyPlayedItemsAsync()); - } - else - { - SetRecentlyPlayedItems(new BaseItemDto[] { }); - } - - tasks.Add(RefreshTopPicksAsync()); - tasks.Add(RefreshSpotlightItemsAsync()); - - await Task.WhenAll(tasks).ConfigureAwait(false); - } - - /// - /// Refreshes the favorite items async. - /// - /// Task. - private async Task RefreshFavoriteItemsAsync() - { - var query = new ItemQuery - { - Filters = new[] { ItemFilter.IsFavorite }, - ImageTypes = new[] { ImageType.Backdrop, ImageType.Thumb }, - UserId = App.Instance.CurrentUser.Id, - ParentId = Folder.Id, - Limit = 10, - SortBy = new[] { ItemSortBy.Random }, - Recursive = true - }; - - try - { - var result = await App.Instance.ApiClient.GetItemsAsync(query).ConfigureAwait(false); - - SetFavoriteItems(result.Items); - } - catch (HttpException) - { - // Already logged in lower levels - // Don't allow the entire screen to fail - } - } - - /// - /// Refreshes the resumable items async. - /// - /// Task. - private async Task RefreshResumableItemsAsync() - { - var query = new ItemQuery - { - Filters = new[] { ItemFilter.IsResumable }, - ImageTypes = new[] { ImageType.Backdrop, ImageType.Thumb }, - UserId = App.Instance.CurrentUser.Id, - ParentId = Folder.Id, - Limit = 10, - SortBy = new[] { ItemSortBy.DatePlayed }, - SortOrder = SortOrder.Descending, - Recursive = true - }; - - try - { - var result = await App.Instance.ApiClient.GetItemsAsync(query).ConfigureAwait(false); - - SetResumableItems(result.Items); - } - catch (HttpException) - { - // Already logged in lower levels - // Don't allow the entire screen to fail - } - } - - /// - /// Refreshes the recently played items async. - /// - /// Task. - private async Task RefreshRecentlyPlayedItemsAsync() - { - var query = new ItemQuery - { - Filters = new[] { ItemFilter.IsRecentlyPlayed }, - ImageTypes = new[] { ImageType.Backdrop, ImageType.Thumb }, - UserId = App.Instance.CurrentUser.Id, - ParentId = Folder.Id, - Limit = 10, - SortBy = new[] { ItemSortBy.DatePlayed }, - SortOrder = SortOrder.Descending, - Recursive = true - }; - - try - { - var result = await App.Instance.ApiClient.GetItemsAsync(query).ConfigureAwait(false); - SetRecentlyPlayedItems(result.Items); - } - catch (HttpException) - { - // Already logged in lower levels - // Don't allow the entire screen to fail - } - } - - /// - /// Refreshes the recently added items async. - /// - /// Task. - private async Task RefreshRecentlyAddedItemsAsync() - { - var query = new ItemQuery - { - Filters = new[] { ItemFilter.IsRecentlyAdded, ItemFilter.IsNotFolder }, - ImageTypes = new[] { ImageType.Backdrop, ImageType.Thumb }, - UserId = App.Instance.CurrentUser.Id, - ParentId = Folder.Id, - Limit = 10, - SortBy = new[] { ItemSortBy.DateCreated }, - SortOrder = SortOrder.Descending, - Recursive = true - }; - - try - { - var result = await App.Instance.ApiClient.GetItemsAsync(query).ConfigureAwait(false); - SetRecentlyAddedItems(result.Items); - } - catch (HttpException) - { - // Already logged in lower levels - // Don't allow the entire screen to fail - } - } - - /// - /// Refreshes the top picks async. - /// - /// Task. - private async Task RefreshTopPicksAsync() - { - var query = new ItemQuery - { - ImageTypes = new[] { ImageType.Backdrop, ImageType.Thumb }, - Filters = new[] { ItemFilter.IsRecentlyAdded, ItemFilter.IsNotFolder }, - UserId = App.Instance.CurrentUser.Id, - ParentId = Folder.Id, - Limit = 10, - SortBy = new[] { ItemSortBy.Random }, - SortOrder = SortOrder.Descending, - Recursive = true - }; - - try - { - var result = await App.Instance.ApiClient.GetItemsAsync(query).ConfigureAwait(false); - - TopPicks = new ItemCollectionViewModel { Items = result.Items, Name = "Top Picks" }; - } - catch (HttpException) - { - // Already logged in lower levels - // Don't allow the entire screen to fail - } - } - - /// - /// Refreshes the spotlight items async. - /// - /// Task. - private async Task RefreshSpotlightItemsAsync() - { - var query = new ItemQuery - { - ImageTypes = new[] { ImageType.Backdrop }, - ExcludeItemTypes = new[] { "Season" }, - UserId = App.Instance.CurrentUser.Id, - ParentId = Folder.Id, - Limit = 10, - SortBy = new[] { ItemSortBy.Random }, - Recursive = true - }; - - try - { - var result = await App.Instance.ApiClient.GetItemsAsync(query).ConfigureAwait(false); - - SpotlightItems = new ItemCollectionViewModel(rotationPeriodMs: 6000, rotationDevaiationMs: 1000) { Items = result.Items }; - } - catch (HttpException) - { - // Already logged in lower levels - // Don't allow the entire screen to fail - } - } - - /// - /// Sets the favorite items. - /// - /// The items. - private void SetFavoriteItems(BaseItemDto[] items) - { - FavoriteItems = new ItemCollectionViewModel { Items = items, Name = "Favorites" }; - } - - /// - /// Sets the resumable items. - /// - /// The items. - private void SetResumableItems(BaseItemDto[] items) - { - ResumableItems = new ItemCollectionViewModel { Items = items, Name = "Resume" }; - } - - /// - /// Sets the recently played items. - /// - /// The items. - private void SetRecentlyPlayedItems(BaseItemDto[] items) - { - RecentlyPlayedItems = new ItemCollectionViewModel { Items = items, Name = "Recently Played" }; - } - - /// - /// Sets the recently added items. - /// - /// The items. - private void SetRecentlyAddedItems(BaseItemDto[] items) - { - RecentlyAddedItems = new ItemCollectionViewModel { Items = items, Name = "Recently Added" }; - } - } -} diff --git a/MediaBrowser.Plugins.DefaultTheme/Pages/InternalPlayerPage.xaml b/MediaBrowser.Plugins.DefaultTheme/Pages/InternalPlayerPage.xaml deleted file mode 100644 index e8e4af2aa1..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/Pages/InternalPlayerPage.xaml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - diff --git a/MediaBrowser.Plugins.DefaultTheme/Pages/InternalPlayerPage.xaml.cs b/MediaBrowser.Plugins.DefaultTheme/Pages/InternalPlayerPage.xaml.cs deleted file mode 100644 index 82a1e9cf89..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/Pages/InternalPlayerPage.xaml.cs +++ /dev/null @@ -1,41 +0,0 @@ -using MediaBrowser.Plugins.DefaultTheme.Resources; -using MediaBrowser.UI.Pages; -using System.Windows; - -namespace MediaBrowser.Plugins.DefaultTheme.Pages -{ - /// - /// Interaction logic for InternalPlayerPage.xaml - /// - public partial class InternalPlayerPage : BaseInternalPlayerPage - { - /// - /// Initializes a new instance of the class. - /// - public InternalPlayerPage() - { - InitializeComponent(); - } - - /// - /// Called when [loaded]. - /// - protected override void OnLoaded() - { - base.OnLoaded(); - - AppResources.Instance.ClearPageTitle(); - AppResources.Instance.HeaderContent.Visibility = Visibility.Collapsed; - } - - /// - /// Called when [unloaded]. - /// - protected override void OnUnloaded() - { - base.OnUnloaded(); - - AppResources.Instance.HeaderContent.Visibility = Visibility.Visible; - } - } -} diff --git a/MediaBrowser.Plugins.DefaultTheme/Pages/ListPage.xaml b/MediaBrowser.Plugins.DefaultTheme/Pages/ListPage.xaml deleted file mode 100644 index 58f6db177d..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/Pages/ListPage.xaml +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/MediaBrowser.Plugins.DefaultTheme/Pages/ListPage.xaml.cs b/MediaBrowser.Plugins.DefaultTheme/Pages/ListPage.xaml.cs deleted file mode 100644 index 096ba9ea73..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/Pages/ListPage.xaml.cs +++ /dev/null @@ -1,545 +0,0 @@ -using MediaBrowser.Model.Entities; -using MediaBrowser.Model.Net; -using MediaBrowser.Plugins.DefaultTheme.DisplayPreferences; -using MediaBrowser.Plugins.DefaultTheme.Resources; -using MediaBrowser.UI; -using MediaBrowser.UI.Controls; -using MediaBrowser.UI.Pages; -using System; -using System.Windows; - -namespace MediaBrowser.Plugins.DefaultTheme.Pages -{ - /// - /// Interaction logic for ListPage.xaml - /// - public partial class ListPage : BaseListPage - { - /// - /// Initializes a new instance of the class. - /// - /// The item id. - public ListPage(string itemId) - : base(itemId) - { - InitializeComponent(); - } - - /// - /// Subclasses must provide the list box that holds the items - /// - /// The items list. - protected override ExtendedListBox ItemsList - { - get - { - return lstItems; - } - } - - /// - /// If the page is using it's own image type and not honoring the DisplayPreferences setting, it should return it here - /// - /// The type of the fixed image. - protected override ImageType? FixedImageType - { - get { return ImageType.Primary; } - } - - /// - /// Called when [loaded]. - /// - protected override async void OnLoaded() - { - base.OnLoaded(); - - if (Folder != null) - { - ShowViewButton(); - - await AppResources.Instance.SetPageTitle(Folder); - } - else - { - HideViewButton(); - } - } - - /// - /// Called when [unloaded]. - /// - protected override void OnUnloaded() - { - base.OnUnloaded(); - - HideViewButton(); - } - - /// - /// Called when [property changed]. - /// - /// The name. - public override void OnPropertyChanged(string name) - { - base.OnPropertyChanged(name); - - if (name.Equals("CurrentItemIndex", StringComparison.OrdinalIgnoreCase)) - { - UpdateCurrentItemIndex(); - } - } - - /// - /// Updates the index of the current item. - /// - private void UpdateCurrentItemIndex() - { - var index = CurrentItemIndex; - - currentItemIndex.Visibility = index == -1 ? Visibility.Collapsed : Visibility.Visible; - currentItemIndex.Text = (CurrentItemIndex + 1).ToString(); - - currentItemIndexDivider.Visibility = index == -1 ? Visibility.Collapsed : Visibility.Visible; - } - - /// - /// Gets called anytime the Folder gets refreshed - /// - protected override async void OnFolderChanged() - { - base.OnFolderChanged(); - - var pageTitleTask = AppResources.Instance.SetPageTitle(Folder); - - ShowViewButton(); - - if (Folder.IsType("Season")) - { - TxtName.Visibility = Visibility.Visible; - TxtName.Text = Folder.Name; - } - else - { - TxtName.Visibility = Visibility.Collapsed; - } - - if (!string.IsNullOrEmpty(Folder.Overview) || Folder.IsType("Series") || Folder.IsType("Season")) - { - sidebar.Visibility = Visibility.Collapsed; - - //RefreshSidebar(); - } - else - { - sidebar.Visibility = Visibility.Collapsed; - } - - await pageTitleTask; - } - - /// - /// Shows the view button. - /// - private void ShowViewButton() - { - var viewButton = AppResources.Instance.ViewButton; - viewButton.Visibility = Visibility.Visible; - viewButton.Click -= ViewButton_Click; - viewButton.Click += ViewButton_Click; - } - - /// - /// Hides the view button. - /// - private void HideViewButton() - { - var viewButton = AppResources.Instance.ViewButton; - viewButton.Visibility = Visibility.Collapsed; - viewButton.Click -= ViewButton_Click; - } - - /// - /// Handles the Click event of the ViewButton control. - /// - /// The source of the event. - /// The instance containing the event data. - async void ViewButton_Click(object sender, RoutedEventArgs e) - { - var menu = new DisplayPreferencesMenu - { - FolderId = Folder.Id, - MainPage = this - }; - - menu.ShowModal(this.GetWindow()); - - try - { - await App.Instance.ApiClient.UpdateDisplayPreferencesAsync(App.Instance.CurrentUser.Id, Folder.Id, DisplayPreferences); - } - catch (HttpException) - { - App.Instance.ShowDefaultErrorMessage(); - } - } - - /// - /// Refreshes the sidebar. - /// - private void RefreshSidebar() - { - //if (Folder.BackdropCount > 0) - //{ - // //backdropImage.Source = App.Instance.GetBitmapImage(ApiClient.GetImageUrl(Folder.Id, Model.Entities.ImageType.Backdrop, width: 560, height: 315)); - // backdropImage.Visibility = Visibility.Visible; - //} - //else - //{ - // backdropImage.Source = null; - // backdropImage.Visibility = Visibility.Collapsed; - //} - } - - /// - /// Handles current item selection changes - /// - protected override void OnCurrentItemChanged() - { - base.OnCurrentItemChanged(); - - // Name - /*if (CurrentItem != null) - { - txtName.Visibility = CurrentItem.HasLogo ? Visibility.Collapsed : Visibility.Visible; - currentItemLogo.Visibility = CurrentItem.HasLogo ? Visibility.Visible : Visibility.Collapsed; - - if (CurrentItem.HasLogo) - { - var uri = ApiClient.GetImageUrl(CurrentItem.Id, ImageType.Logo, maxWidth: 400, maxHeight: 125); - - Dispatcher.InvokeAsync(() => currentItemLogo.Source = App.Instance.GetBitmapImage(new Uri(uri, UriKind.Absolute))); - } - else - { - var name = CurrentItem.Name; - - if (!CurrentItem.IsType("Season") && CurrentItem.IndexNumber.HasValue) - { - name = CurrentItem.IndexNumber + " - " + name; - } - - if (CurrentItem.IsType("Movie") && CurrentItem.ProductionYear.HasValue) - { - name += " (" + CurrentItem.ProductionYear + ")"; - } - - txtName.Text = name; - } - } - else - { - txtName.Visibility = Visibility.Collapsed; - currentItemLogo.Visibility = Visibility.Collapsed; - } - - // PremiereDate - if (CurrentItem != null && CurrentItem.PremiereDate.HasValue && !CurrentItem.IsType("Series")) - { - pnlPremiereDate.Visibility = Visibility.Visible; - - var prefix = CurrentItem.IsType("Episode") ? "Aired" : CurrentItem.IsType("Series") ? "First Aired" : "Premiered"; - - txtPremiereDate.Text = string.Format("{0} {1}", prefix, CurrentItem.PremiereDate.Value.ToShortDateString()); - } - else - { - pnlPremiereDate.Visibility = Visibility.Collapsed; - } - - // Taglines - if (CurrentItem != null && CurrentItem.Taglines != null && CurrentItem.Taglines.Length > 0) - { - txtTagLine.Visibility = Visibility.Visible; - txtTagLine.Text = CurrentItem.Taglines[0]; - } - else - { - txtTagLine.Visibility = Visibility.Collapsed; - } - - // Genres - if (CurrentItem != null && CurrentItem.Genres != null && CurrentItem.Genres.Length > 0) - { - txtGenres.Visibility = Visibility.Visible; - - // Try to keep them on one line by limiting to three - txtGenres.Text = string.Join(" / ", CurrentItem.Genres.Take(3)); - } - else - { - txtGenres.Visibility = Visibility.Collapsed; - } - - // Season Number - if (CurrentItem != null && CurrentItem.ParentIndexNumber.HasValue && CurrentItem.IsType("Episode")) - { - txtSeasonHeader.Visibility = Visibility.Visible; - - txtSeasonHeader.Text = string.Format("Season {0}", CurrentItem.ParentIndexNumber); - } - else - { - txtSeasonHeader.Visibility = Visibility.Collapsed; - } - - UpdateSeriesAirTime(); - UpdateMiscellaneousFields(); - UpdateCommunityRating(); - UpdateVideoInfo(); - UpdateAudioInfo();*/ - } - - /// - /// Updates the series air time. - /// - private void UpdateSeriesAirTime() - { - /*if (CurrentItem != null && CurrentItem.SeriesInfo != null) - { - var series = CurrentItem.SeriesInfo; - - txtSeriesAirTime.Visibility = Visibility.Visible; - - if (series.Status.HasValue && series.Status.Value == SeriesStatus.Ended) - { - txtSeriesAirTime.Text = "Ended"; - } - else - { - string txt = "Airs"; - - if (series.AirDays.Length > 0) - { - if (series.AirDays.Length == 7) - { - txt += " Everyday"; - } - else - { - txt += " " + series.AirDays[0].ToString(); - } - } - - if (CurrentItem.Studios != null && CurrentItem.Studios.Length > 0) - { - txt += " on " + CurrentItem.Studios[0].Name; - } - - if (!string.IsNullOrEmpty(series.AirTime)) - { - txt += " at " + series.AirTime; - } - - txtSeriesAirTime.Text = txt; - } - } - else - { - txtSeriesAirTime.Visibility = Visibility.Collapsed; - }*/ - } - - /// - /// Updates the miscellaneous fields. - /// - private void UpdateMiscellaneousFields() - { - /*if (CurrentItem == null) - { - pnlRuntime.Visibility = Visibility.Collapsed; - pnlOfficialRating.Visibility = Visibility.Collapsed; - } - else - { - var runtimeTicks = CurrentItem.RunTimeTicks ?? 0; - - // Runtime - if (runtimeTicks > 0) - { - pnlRuntime.Visibility = Visibility.Visible; - txtRuntime.Text = string.Format("{0} minutes", Convert.ToInt32(TimeSpan.FromTicks(runtimeTicks).TotalMinutes)); - } - else - { - pnlRuntime.Visibility = Visibility.Collapsed; - } - - pnlOfficialRating.Visibility = string.IsNullOrEmpty(CurrentItem.OfficialRating) ? Visibility.Collapsed : Visibility.Visible; - } - - // Show the parent panel only if one of the children is visible - pnlMisc.Visibility = pnlRuntime.Visibility == Visibility.Visible || - pnlOfficialRating.Visibility == Visibility.Visible - ? Visibility.Visible - : Visibility.Collapsed;*/ - } - - /// - /// Updates the community rating. - /// - private void UpdateCommunityRating() - { - /*// Community Rating - if (CurrentItem != null && CurrentItem.CommunityRating.HasValue) - { - pnlRating.Visibility = Visibility.Visible; - } - else - { - pnlRating.Visibility = Visibility.Collapsed; - return; - } - - var rating = CurrentItem.CommunityRating.Value; - - for (var i = 0; i < 10; i++) - { - if (rating < i - 1) - { - TreeHelper.FindChild(this, "communityRatingImage" + i).SetResourceReference(Image.StyleProperty, "CommunityRatingImageEmpty"); - } - else if (rating < i) - { - TreeHelper.FindChild(this, "communityRatingImage" + i).SetResourceReference(Image.StyleProperty, "CommunityRatingImageHalf"); - } - else - { - TreeHelper.FindChild(this, "communityRatingImage" + i).SetResourceReference(Image.StyleProperty, "CommunityRatingImageFull"); - } - }*/ - } - - /// - /// Updates the video info. - /// - private void UpdateVideoInfo() - { - /*if (CurrentItem != null && CurrentItem.VideoInfo != null) - { - pnlVideoInfo.Visibility = Visibility.Visible; - } - else - { - pnlVideoInfo.Visibility = Visibility.Collapsed; - return; - } - - var videoInfo = CurrentItem.VideoInfo; - - if (videoInfo.VideoType == VideoType.VideoFile) - { - txtVideoType.Text = Path.GetExtension(CurrentItem.Path).Replace(".", string.Empty).ToLower(); - } - else - { - txtVideoType.Text = videoInfo.VideoType.ToString().ToLower(); - } - - txtVideoResolution.Text = GetResolutionText(videoInfo); - pnlVideoResolution.Visibility = string.IsNullOrEmpty(txtVideoResolution.Text) ? Visibility.Collapsed : Visibility.Visible; - - if (!string.IsNullOrEmpty(videoInfo.Codec)) - { - pnlVideoCodec.Visibility = Visibility.Visible; - txtVideoCodec.Text = videoInfo.Codec.ToLower(); - } - else - { - pnlVideoCodec.Visibility = Visibility.Collapsed; - } - - var audio = videoInfo.GetDefaultAudioStream(); - - if (audio == null || string.IsNullOrEmpty(audio.Codec)) - { - pnlAudioCodec.Visibility = Visibility.Collapsed; - } - else - { - pnlAudioCodec.Visibility = Visibility.Visible; - txtAudioCodec.Text = audio.Codec.ToLower(); - }*/ - } - - /// - /// Updates the audio info. - /// - private void UpdateAudioInfo() - { - /*if (CurrentItem != null && CurrentItem.AudioInfo != null) - { - pnlAudioInfo.Visibility = Visibility.Visible; - } - else - { - pnlAudioInfo.Visibility = Visibility.Collapsed; - return; - } - - var audioInfo = CurrentItem.AudioInfo; - - txtAudioType.Text = Path.GetExtension(CurrentItem.Path).Replace(".", string.Empty).ToLower(); - - if (audioInfo.BitRate > 0) - { - pnlAudioBitrate.Visibility = Visibility.Visible; - txtAudioBitrate.Text = (audioInfo.BitRate / 1000).ToString() + "kbps"; - } - else - { - pnlAudioBitrate.Visibility = Visibility.Collapsed; - }*/ - } - - /*private string GetResolutionText(VideoInfo info) - { - var scanType = info.ScanType ?? string.Empty; - - if (info.Height == 1080) - { - if (scanType.Equals("progressive", StringComparison.OrdinalIgnoreCase)) - { - return "1080p"; - } - if (scanType.Equals("interlaced", StringComparison.OrdinalIgnoreCase)) - { - return "1080i"; - } - } - if (info.Height == 720) - { - if (scanType.Equals("progressive", StringComparison.OrdinalIgnoreCase)) - { - return "720p"; - } - if (scanType.Equals("interlaced", StringComparison.OrdinalIgnoreCase)) - { - return "720i"; - } - } - if (info.Height == 480) - { - if (scanType.Equals("progressive", StringComparison.OrdinalIgnoreCase)) - { - return "480p"; - } - if (scanType.Equals("interlaced", StringComparison.OrdinalIgnoreCase)) - { - return "480i"; - } - } - - return info.Width == 0 || info.Height == 0 ? string.Empty : info.Width + "x" + info.Height; - }*/ - } -} diff --git a/MediaBrowser.Plugins.DefaultTheme/Pages/LoginPage.xaml b/MediaBrowser.Plugins.DefaultTheme/Pages/LoginPage.xaml deleted file mode 100644 index 6a9e796ee7..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/Pages/LoginPage.xaml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/MediaBrowser.Plugins.DefaultTheme/Pages/LoginPage.xaml.cs b/MediaBrowser.Plugins.DefaultTheme/Pages/LoginPage.xaml.cs deleted file mode 100644 index 35f2c1088e..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/Pages/LoginPage.xaml.cs +++ /dev/null @@ -1,43 +0,0 @@ -using MediaBrowser.Plugins.DefaultTheme.Resources; -using MediaBrowser.UI.Controls; -using MediaBrowser.UI.Pages; - -namespace MediaBrowser.Plugins.DefaultTheme.Pages -{ - /// - /// Interaction logic for LoginPage.xaml - /// - public partial class LoginPage : BaseLoginPage - { - /// - /// Initializes a new instance of the class. - /// - public LoginPage() - : base() - { - InitializeComponent(); - } - - /// - /// Subclasses must provide the list that holds the users - /// - /// The items list. - protected override ExtendedListBox ItemsList - { - get - { - return lstUsers; - } - } - - /// - /// Called when [loaded]. - /// - protected override void OnLoaded() - { - base.OnLoaded(); - - AppResources.Instance.SetDefaultPageTitle(); - } - } -} diff --git a/MediaBrowser.Plugins.DefaultTheme/Pages/WeatherPage.xaml b/MediaBrowser.Plugins.DefaultTheme/Pages/WeatherPage.xaml deleted file mode 100644 index 17a8239e5a..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/Pages/WeatherPage.xaml +++ /dev/null @@ -1,13 +0,0 @@ - - - - Weather Page - - diff --git a/MediaBrowser.Plugins.DefaultTheme/Pages/WeatherPage.xaml.cs b/MediaBrowser.Plugins.DefaultTheme/Pages/WeatherPage.xaml.cs deleted file mode 100644 index eae50befbc..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/Pages/WeatherPage.xaml.cs +++ /dev/null @@ -1,15 +0,0 @@ -using MediaBrowser.UI.Pages; - -namespace MediaBrowser.Plugins.DefaultTheme.Pages -{ - /// - /// Interaction logic for WeatherPage.xaml - /// - public partial class WeatherPage : BaseWeatherPage - { - public WeatherPage() - { - InitializeComponent(); - } - } -} diff --git a/MediaBrowser.Plugins.DefaultTheme/Properties/AssemblyInfo.cs b/MediaBrowser.Plugins.DefaultTheme/Properties/AssemblyInfo.cs deleted file mode 100644 index cc3fafdc9c..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,53 +0,0 @@ -using System.Reflection; -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("MediaBrowser.Plugins.DefaultTheme")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("MediaBrowser.Plugins.DefaultTheme")] -[assembly: AssemblyCopyright("Copyright © 2012")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -//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) -)] - -[assembly: Guid("411f938b-89d5-48f6-b6ab-a5d75036efcc")] - -// 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.*")] diff --git a/MediaBrowser.Plugins.DefaultTheme/Properties/DesignTimeResources.xaml b/MediaBrowser.Plugins.DefaultTheme/Properties/DesignTimeResources.xaml deleted file mode 100644 index 20f1556671..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/Properties/DesignTimeResources.xaml +++ /dev/null @@ -1,5 +0,0 @@ - - - \ No newline at end of file diff --git a/MediaBrowser.Plugins.DefaultTheme/Properties/Resources.Designer.cs b/MediaBrowser.Plugins.DefaultTheme/Properties/Resources.Designer.cs deleted file mode 100644 index da735391a8..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/Properties/Resources.Designer.cs +++ /dev/null @@ -1,62 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.17929 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace MediaBrowser.Plugins.DefaultTheme.Properties { - - - /// - /// 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 ((resourceMan == null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MediaBrowser.Plugins.DefaultTheme.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/MediaBrowser.Plugins.DefaultTheme/Properties/Resources.resx b/MediaBrowser.Plugins.DefaultTheme/Properties/Resources.resx deleted file mode 100644 index ffecec851a..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/Properties/Resources.resx +++ /dev/null @@ -1,117 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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/MediaBrowser.Plugins.DefaultTheme/Properties/Settings.Designer.cs b/MediaBrowser.Plugins.DefaultTheme/Properties/Settings.Designer.cs deleted file mode 100644 index b99760e3f4..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/Properties/Settings.Designer.cs +++ /dev/null @@ -1,30 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.17929 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace MediaBrowser.Plugins.DefaultTheme.Properties -{ - - - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.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/MediaBrowser.Plugins.DefaultTheme/Properties/Settings.settings b/MediaBrowser.Plugins.DefaultTheme/Properties/Settings.settings deleted file mode 100644 index 8f2fd95d62..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/Properties/Settings.settings +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/MediaBrowser.Plugins.DefaultTheme/Resources/AppResources.cs b/MediaBrowser.Plugins.DefaultTheme/Resources/AppResources.cs deleted file mode 100644 index 3ca6e8df2b..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/Resources/AppResources.cs +++ /dev/null @@ -1,223 +0,0 @@ -using MediaBrowser.Model.Dto; -using MediaBrowser.Model.Net; -using MediaBrowser.UI; -using MediaBrowser.UI.Controller; -using MediaBrowser.UI.Controls; -using MediaBrowser.UI.Playback; -using MediaBrowser.UI.Playback.InternalPlayer; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Controls; - -namespace MediaBrowser.Plugins.DefaultTheme.Resources -{ - /// - /// Class AppResources - /// - public partial class AppResources : ResourceDictionary - { - /// - /// Gets the instance. - /// - /// The instance. - public static AppResources Instance { get; private set; } - - /// - /// Initializes a new instance of the class. - /// - public AppResources() - { - InitializeComponent(); - - Instance = this; - - UIKernel.Instance.PlaybackManager.PlaybackStarted += PlaybackManager_PlaybackStarted; - UIKernel.Instance.PlaybackManager.PlaybackCompleted += PlaybackManager_PlaybackCompleted; - } - - /// - /// Handles the Click event of the NowPlayingButton control. - /// - /// The source of the event. - /// The instance containing the event data. - void NowPlaying_Click(object sender, RoutedEventArgs e) - { - App.Instance.NavigateToInternalPlayerPage(); - } - - /// - /// Handles the PlaybackCompleted event of the PlaybackManager control. - /// - /// The source of the event. - /// The instance containing the event data. - /// - void PlaybackManager_PlaybackCompleted(object sender, PlaybackStopEventArgs e) - { - App.Instance.ApplicationWindow.Dispatcher.Invoke(() => NowPlayingButton.Visibility = Visibility.Collapsed); - } - - /// - /// Handles the PlaybackStarted event of the PlaybackManager control. - /// - /// The source of the event. - /// The instance containing the event data. - void PlaybackManager_PlaybackStarted(object sender, PlaybackEventArgs e) - { - if (e.Player is BaseInternalMediaPlayer) - { - App.Instance.ApplicationWindow.Dispatcher.Invoke(() => NowPlayingButton.Visibility = Visibility.Visible); - } - } - - /// - /// Weathers the button click. - /// - /// The sender. - /// The instance containing the event data. - void WeatherButtonClick(object sender, RoutedEventArgs e) - { - App.Instance.DisplayWeather(); - } - - /// - /// Settingses the button click. - /// - /// The sender. - /// The instance containing the event data. - void SettingsButtonClick(object sender, RoutedEventArgs e) - { - App.Instance.NavigateToSettingsPage(); - } - - /// - /// This is a common element that appears on every page. - /// - /// The view button. - public Button ViewButton - { - get - { - return TreeHelper.FindChild - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/MediaBrowser.Plugins.DefaultTheme/Resources/Images/AudioDefault.png b/MediaBrowser.Plugins.DefaultTheme/Resources/Images/AudioDefault.png deleted file mode 100644 index 4c590845751098364cafc1befa5f858d08927dc0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4525 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 Jxti_U{{ym))Q$iE diff --git a/MediaBrowser.Plugins.DefaultTheme/Resources/Images/ChapterDefault.png b/MediaBrowser.Plugins.DefaultTheme/Resources/Images/ChapterDefault.png deleted file mode 100644 index 47b73752189917f45a02b7ce9f3a30bad10794da..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4323 zcmeHK`&W|b7B;iXXpVI#o64kdN>sdLbu>(L8ga@irlRHz&CJTsM9~P7nyJj}Xd|g( zDo%D8#Sl%A)RZn`gx4}bQ^8cgM3F)PQIPZ5%vt9TIP=4-S?62pUEhB9`>y>wd+%re z@Mih>9x~M5s;{G?W9V@h;jg2!!WvlEwW|RSQZ*q1etK~SeGcmA)aDwfqgMg@FU}r5 znyjPq<@4pWVv~jEMZmc=#XTe?An`;>S~NCR$1nO+LW-@gd*F`Ly|(|fwcova4tqyO zXFb{jaWL>)q=aX8^Gq9W_4~DYW1tOd^>jCExb*D~v-NBB%*=EzUHfbz5PB%!Xbc1# zU-}lYWBrC}YY~76oUR8f1Z76UA34*bDIgHEC1jY7REVeW2YGxLypZBz*BnRaRxfAu zr+!g*rF4YogxBy}2w(`fKKf!Ax_y!@5Z-#*%hDH-eqdPMW#sjc zv?ha-r|lYE=qL(%Rk-VubioTjv!F_V-h3hDZrb2Jor%Icycxc>-MnosR(3&lM8>)S z=b6r?v@V&0X($%heAWKKl#V*fLf2ho=B_)5NWL#Q-UyG#sq9^tdF|c5h&!Mc)qLxf z_THI{GIgSiCYTbm2=ddVY(>pBVJ!|mwRrk|m0*!Z&s;g|dwu-M9II^hQ?`J~W~dhA zf{*e13KJscl#l>!$kd&?54DwMEsVZ4HDb?)Nk$>;z~F+Qm&|yhm5*;G?4QY^pd}fP zAYv!{^ft_O(s7Cvb&$ZB9a8LmUr4#WW7m<*ti(D91XqO*iX5Ha+kxVd=P46aqesr zGH;?P&$%OBXK#NM`%b;=6VGAY@Gcl0eRwIak6dy70-pu@wV6=9M}cT1LcE~KeF^i( z!4fn*Iw}@7W=@BQN%!={+369*`_U(j8iP#3?xR@Vq=}*MP`sK1o5>f{(9J5f-1Bed z;#K6r4^OX)fAcY&&hl*a;3L0eis+dbf0l5bC>Y;|Z?&RM47uKc=HhL0D`nJv@X~=w z8{@>-PChgQRr=T?4H?*4jh^&vEs7A$!#t}}Yg{eL(j%E7jeR9`6AqGTB}m)5gdMZH zR8wA3f)pZJnXM;U@MxSz&L_^rlbOPbFGg_GuxTQJ0i|T;kg4c+1^#FVd z_6JiX;zB`qBgAT?D!V66b?Tes7NY%>$#Q?szv%6txjBa?drfEkfa0(LR0Jo?pBHLM zEcB|%@O=0$3J{|mn+L?;$cspT)aMTbgcdRR|5&1_`aZMi?dXqNihxLAvE5CrxB~QD z@yI#*smVRTk}Qhr`T@|Ys&+OWkL(li-hCr;mT!JR0%W^xM75W-U5RKZwUYqI!kutn zytX~zpc}>Is{BMuYo_zaTyOh0K#L<3Jb414D8AspZ=KG5>cs*%f@$gTvn>Kustxr9 zYReF46|{q`BEgSHerx%(IuY-!5#S2K8is?&(z^7oS}RIpauc7SnEdTCp!`1Y7a9Gg zx)04ECnZ_u_g12%Vi&$!@sZZIfGp)Qpxxu*@9}cua9m==pb<_uwf>TOJ%|xm zr-(uZx^QVBkg~_HjLP12r7g4aJ5Bw$0Z@KP>>7B@k0rkpqU#i|$Q3tG>=L1&V?5bm z1ehbYQ@iB4V;%j&fb7J#i{VFrdAQfJGjS&a&^oKMu3jv(c$@G`uq<8v-6YUk@@cI} z)GiooYRLn4=ZWnOBWYH9Z5))^DSuDxQs$|^z`T;>y}WZdEFIL~vj6agG1##0F`EWiBl2RBSa=sxFdp zRwWb4-zTN*AE*6fHcx@iZBX(1CDFm{G2Q;5MH5#9XAiwef4GR?e2)U|72eZ-?__z| zZqN<5*f%qq;|urJFEO{=Mk1J%?v9ou&IS zJdo|;?@5PHB6nku8_zazZQ@AB9zpa6Sa)K5Z(;%K=ezRmnp=H`Fjf~Y(D_>))LgXe zbwoz=bwA!1gh5sqlFb;t1>Hv@W7_Qw8+X-Za^D>>j>GJxHrt%>&7o#1o7rl4b6VnM<%$@4!=r5$y`m$ zn|`SoFwZ{0c-}ttaNEip+nMv!F*1`Ij$d=VSTN9ZY4lx!rKYA+6G@Q*@Z9^m* zYTdvte^*uG+vpPLI634ls%FTy^8Zy9Aqd*dQp@Z;@F+FZ0)rwA+-eysWf z=$!#HJ9&P=?@OBU(D3ZS>qSYWL&s?IlHBGh@k)2CG~7EWgL>ww(pxysM0d`u{XL(J zTm#GkkZfLmre_Wsm+hXfrc0wzu6Jspmy0mpvAHhAa+wn>J~}pu*!zHQ&2lN6PQ74Z z+HYgrjH&J#MqLi(a~GUo)k|yr+|xIGjvEJkXx-hUrN-%+PgpR|o7Vsh#_hH)E+A2LqBX4odgx7+5dK7)G!;9U8g z(XnN7uoqJS3Sf(iKHLR(RdY${s@Q)K?`1dW0%_EgPl$o`pQ#8Gf*vy zQ!>D-*D7X`M{b!kPk5a@y~x_8s$U#-+{NOHa0S1UIsaz6gI~xQk`~1EGEW^kyB017 zg^c-l4A@S^Ne%cPYetzaGK0dlyEQ-iMBAHZABwgwetyi`IQRK6hbwJATbo{KJENa% zf7Dq&``t$4m`CR}8rNA`zdZiQ!umu&$PM<`k&w;@HD8hbP62)m3sKJS7QY5ZZr@Dk30(X7c;`W?-pvw8nbh(){nXK3($dCEm) zFDj+k*M_rF*0>{rywm&;$J_pI{*CI;GOXojS2(&Fci9B4CNE3H!`&BA{aw@#{{|84 BDD?mU diff --git a/MediaBrowser.Plugins.DefaultTheme/Resources/Images/CurrentUserDefault.png b/MediaBrowser.Plugins.DefaultTheme/Resources/Images/CurrentUserDefault.png deleted file mode 100644 index 7a80db6e8dc26d6d2768624b1afd36cde058060b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 818 zcmV-21I_%2P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0>?>2K~#8N?U}!8 z6j2bzb4Q94DJ&vbq%dfaGDQlDfEIyRS_YCLg~fpu7D7^{v-A(J6e|l$l?W*)O`(x=b63r$luJ6e1p3 z0!@h}U4Y$AitQvD3jphgnbitu;t%}$P5jC}Y5)Xt*{)73Y)#%R5^XEZEC8%)1ZaHe zymi2m(PM2v`yL1Mjgw%i>G;QUCw|07*qoM6N<$g1dHO{r~^~ diff --git a/MediaBrowser.Plugins.DefaultTheme/Resources/Images/DislikeOverlay.png b/MediaBrowser.Plugins.DefaultTheme/Resources/Images/DislikeOverlay.png deleted file mode 100644 index da3af382171cad631a2b60946f08df86ab7b9c39..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1161 zcmV;41a|w0P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D1RhC5K~z{rwOCC^ zR8bVZ_swKJ9L2J1kVHYD5`@w57ZOLLg;XlIQrrkG652$D3Szi!AyVL`W!OeY&_z*_ zt|WC-Nc=;~g{XvrIOzU(3tw2?qxr zMbm14>SXXkDZPzh;CYKMwnYh9CzOu(9FC6_V`BlCDS#_Bz7-a_Y?}5QCVd2?WDyo% z_d(zn5Z7Di^^S^gOa*!K^0GBbU%@KWiUf>`VQe(W*o)$snW1vqHr7Q3%uU#$oOXjp%}laeuft% zmm=mQC}V6hM^vZ&xh79 zhOuRMni!=EA_jK2TqLQqlq3}ukt-=FJXp~0C;p`+av({10YFJ1#AaWcTzCH7iTXUPl`n2>bPi*)1=G`c2;d&VOV3OU z;xgLXrNsy-r_?p&cGnt$@CFtk9xN<~z${_l)Nu_8x*XGiSrlrsk!zKeW-!a|VTbO+ zD&0^pQHtay6oekS%mJ%ZtDIzQ^Lgxc67>1ZaTh~8L{mFOVkCP!#t|36Tftx%qhLKF zLOz_IC)(km2s8}iUtJ|XySl`9j5!s(xDsI;@9&Gi49x!QELm)7BKTKm;0i$jB~)6Z zwY2aXS9EAcN90FaoAjzGkS^9mCfVrgBZ0Lw5h%xO4-S$)J3GR74#e_TBxUGP@#w2} z?vVJ*OoGogRpq(rdQ}yJzz-a*D>hcCWvm3)IKq z@-kUyXpjyG2W(gYF`uNFCj=Cc(b*X$W@l)KthTmV3JDkEh=Q#O?+z@Cn{{<0Avc#Z z(ZncZt-G6GcDFJ#yL~|6eG|4S7RIf{(~=uaAFJju4G;b)nV4ArSHeQyWJ-tt@WSgP zx8bGv3w(6J!8LF}yjp|4NhaX&?yhmi>`hD%77WVJ!?0kP6=;p#8G`Tun>g8s+rz`$ zJA32fveZa?hu)`!wLx$NyoT+2deP`Id_3x~LyvV%SQ~^LrB#E=h%m5>&8dEWeJJ-# zqli@-s2+zG*_I{|C1ILitjs+#vl2=<(<*-a!3_-fUc6_beFYQK)Mk@$(?fRvD^>%a#tD9K!ZZI$59=BDy@fRvCQ8grm=4Th bhQ9v`?pc$W+3s6m00000NkvXXu0mjfl(7nC diff --git a/MediaBrowser.Plugins.DefaultTheme/Resources/Images/FavoriteOverlay.png b/MediaBrowser.Plugins.DefaultTheme/Resources/Images/FavoriteOverlay.png deleted file mode 100644 index f948ea11f98c3f4c8948f06bdc70d40b2217b283..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1264 zcmVPx#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D1cgaNK~z{ry;xsJ zQ(+W8_ue%(yIR>FrnR&`L>Y*4t}>F8sD}!&hlrrSdgviSs3&~oDY#oMUZ8yl%h>%=I+-yw{7gtz4yB_*9XeB?|07m-SeIA{J8>TxSnp@ zXqh=WS|cjT4it4T{1XIW5vjq?0bnd30DJ^N=m^U4!`f%h#xpU2vgX!HkEdKxlw)Xg zI||JE_r;uPBSuGLOz#kxgrQH=!H5n3Ux7zbw(IFzSi&WHqv8A$m@2W z78pB&PiXlkGKs>BwFdL@j^I&FYU$J@^s2N}9=F@CpupZ~Ba%#tj&V<=&o`W^KaCKP z3ESLuV06e`}dQG(SG5912C()8U#s#pUaqojY) zr03U@n6qgUEIE5tHITXnFI<4HH*Tmu7i`%ACC$xgI2MV(`%|ajdq;r6fi|sFYD5?BwDgKOvs02)Pg?fA8Q){ak@qmaqh)YOK z{Y_0U_WHFMrAZhf^QNHzl(8|cES;8!)%_6{iGax;KcIjAejwMIT~v7A96Dr*4C%zg z*dbu)u*sp&H}sTj)=k53)yM2SP(R0vU8FmtW7bfb43#KB z-EQ|hWc>m+mS>e0y(M9++U@thO|+9XDAIVVh+;K*sxxbZ&@)@ zB8C|l@t4r!ZF;X@41=0yObvRR4$xye@M#Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D1P)0=K~z{rwOC(B zlTj2u_iky^twxrL%rX)*A=E9)py7I`ml6d@F!Zg*AR-EcKqTlTC`LgqK`(&_^(I=B zWE4cru^^Ei6a;-3rBN*1B=_CU`P#Sk*Y94pT^Rdw&+pvd_dDm_bI%wkjyGLh*2?vD zAJ?=Vgw_gtF~(fv20w>Eh%f_K0mh~ycKeGnZ{NmLmO!lB_}J0WX3@0kxab80Ib~32 z`x^JQ!Tf^q)nD$V6?nS2)pG z5;6&=LWr-L#d79kAP`Pnhi5KI%9NT6t%*6=Y>CImXxHW?L^)HkFy%}b=Cem4lp4vA zRETzyp1?aC<@NQ@GCmIVH*YF=K&39D5IzHxBt%=gklp0)c))h#2vqm?gT>)cBPGQB zG(vRf6?)FtTU(PPNG+woSlg_}(@Pj#Av%GT9Ap@iI#u1>`mZ7$huG4RvOC;$ItNZ! zPUS$^LjpiyY8d&SdOs#7LEG3+c83u zi=IpL+H>Lr?5e6#a!uD57I3@YQT$Yp2m1Qp;P9{%Wc|w*SQ;IbOLQStxN*6X@{UHN zLd~Fj&8<9k3=Z9*0w6I^A&wU)rK<(yjmkL_k3`_x*q8*HeBLyB%LFUw)@`b!F>mH&K5BD3$@IXTBERaDMHFj5&$|RS0^T< z;1n&61@)zr^$v|lA+fnBg~o$%np3NycLyaJDrH2oTAy*fZ=zPEMC1GO=kRB3&D^^X zpF2N&!jRFxzR4W1GmE`muPjjKpcB%YIP9Bbk+ODl22p)88<;W+*cv_6wK0r8wznU* za3079rusz58C_fiR$dOfT`s6NdK7F;O;CyN#x0R*+Q$4m{CfW$)~2R_NSO^JbP+{) zmPUxa%(~qVFnm|c929dN$xI-bf44g$WX2cjC`*~(Sq~z_oGlt1Nc}ylQKVZNvi^V* zjm1G-c|@X+S-U8Hg;1!U#5f%AoWeus;J&BG4!9&ho8=we1E}g zo7841=t+;=0V>vmPg9Ev*5YUVFTKQ7CQMbE3MJJhDhFmhQ|JEz%F%dao1U|a00000 LNkvXXu0mjfEpi6L diff --git a/MediaBrowser.Plugins.DefaultTheme/Resources/Images/NowPlayingButton.png b/MediaBrowser.Plugins.DefaultTheme/Resources/Images/NowPlayingButton.png deleted file mode 100644 index b0a4f26f9538fed9e8c9d6f7a6342e1ddb92a1b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 491 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 diff --git a/MediaBrowser.Plugins.DefaultTheme/Resources/Images/VideoDefault.png b/MediaBrowser.Plugins.DefaultTheme/Resources/Images/VideoDefault.png deleted file mode 100644 index 9c5e0a4ce18106f169536c5083c4a885ea67fdfe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2998 zcmcImc{rQt7LQCy(uGJ=shz|=YH2HWvBp{|wxZM6Rf%0ib)-#6P^4s}MO$jG!h%4xIs3K`gh4YRDfrQ(>ErElo_Nlk&s(9=4mrK7FA5>o;K?bEfh!s5@LUMN<`6*CY^ z6NN&+WOI4=cT@Sz>7X41f?9AinB1TanFOBi2^w%5%74#)0x0B?dc&^k+Xq)}6hB#c z5@*OC^SCRX@ao9y;`H#!9ld7T?4>;dP;(F%o(h7SSwn&D7U&094B>b zs-pMj9j)=5-GxUtB9KyGDP*5K-}_iv4s+rd6rB_O0K)R|Zkv|HWs_Z4#26wO#H~3u~d)0uLe#qHwYF)#% zy27dyjnK?vna&^;5dkF^ORM3i1uyDb^bhbsVIB*Nu>C|+)wUWSUE7<%km7Bidejp-BnFt^&A+t1c8OY z*FH8;zJBF({Qi6JKJ7ZhhPtQc!`Ln-YQiX| zT1f%1qkAo4n913c%(vXl-X0jRZrkHf{?3e>`Xv08kfZ)i$m%+@nCs1Wpl+lt;%<7v zsg>Fe~C$1gCCtCQYlfPJh8pK6gXXuLFk*ji|7%n|I2x*dJQ_!&_4EqmI@# zDBoWw^@gVWzG?^aVr#u}vBob!vIU?r&;L$6>Z>V?srm5$Z3; z@asjRL{#S@vmsFKk?ZhDly4fP*T}S+#0aORphi%pDu2yTEo_9twS?o93VmxZ~{+;1=?6yhz!!+VB44- z7_=tIknF!Rbx;%*@COgI7xC;&uU$De(ZR>Q;NGH%q9Q?!4;!>?V+LYS#w#h~O|s`h zEKyl61M*aH5|>R>N-)F&VRq3(9i*@Vw_gV*k*AqX2}xt$+2So^&L7g7fHxrx1YrS) ziQL@l+JdWFrSb$v=U7DbWBnJ&ZA|GnsXefOlQX$X)?p5u?&!{-c(#}?ah0yE9AE%@ zUD#BJu2OqnHedJ~p1eju2da1+0%}dtwIjTZ=E7X#Gk0F>N07>$*}{ltsAozgPN!IF zLHy13xXU{wiGm{!(ES+Yn?4_1=-HYbb!q!hT}7te!LbK#Q+p^`IGvXgwvpzp&?ERqJ=O zuCrUi-)^3%r))3rZOiq%J}qpl-uR+Pzm5@r{4G0M;3g{=l=Q}J6>gB){|X4hj(lUu zPpX|B1?AJEFH>}AFYLTXYE5Groy}8?DC@RAyNC<0KmSX6zrv5RykQ)M;%oaHVC>fz zy^_;rW_QpsGbAz7zp@&YjC06%{M_-snbL@-TFof;?W#Dn!c~BCI+=SJb?!x7!@cwk_`KJJN;CfgWPzj{Jnzoe-WgnZgY| zzd^WGx~S)ikT5;! zXOQZ$oO=RZYc@nfA60MG&XnbSt>C@?=&9i583hOa=GZ*dLR`aS{qhW3?d$ae8It)0 zvwsY4!$;55k4)s&&`fo%+Sq@P)xqyqNu}tR9tHGf!t^MNN^x4Dg^9rmG00I>#IyB2 zKtIwp`%v|>K4<6UPIHHxT;9V68Y8{4I)lp rMFKJQ$MKl<#|B#s=A0J6ly-oVoOGn9$=M diff --git a/MediaBrowser.Plugins.DefaultTheme/Resources/Images/ViewButton.png b/MediaBrowser.Plugins.DefaultTheme/Resources/Images/ViewButton.png deleted file mode 100644 index c0a8611bf2adda3e01c318362a00bf1fcb587ac6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 650 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1qt-3{3K#E{-7;ac^hZ`W61Uj?>Cn_a--8fxrtX< zUy3lPOJbPi=KM*NcXrN;4_WES^+-By-R&9;AM30FsPLF|H>H)~uA=KOpc z&dRa7bK}}g+STjkG8sF^RV(h8X~MX6zF5PyzvupPF8HkX!h)f%q0f53nxEU>99*@k z>%coUv-_89w)|!YW?gpa*xF6$CVFq8`qqBq+-EJ@#_&M$_KT%veER>_q+dCiK6};5 zWz(uz;|!ijEm(Mc%KA$22F-&0>Zb+!4?SD8GQz8L_8g`Qa-q6)N1q2VEc9!<)^}_n z(}c1W+v6vs8rbta{w%fhLv3`}2FsSSnc>GDx}93U_#wXU@I7ZellFV-8Ce8wO~|pH zcdwrzRPu;dZTF|*asBqpeV2bTWNi8WIHR{SxC>j1HLygfe&D|SYVOAMv+ged PrXL1RS3j3^P6Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0ffGJ=Km;$E2e-!AtZqv5y5q52|;J~AQ$ErBT00{{-;Clg5NT>s!LP9P0SQ7p^-xm&kzyB@gxw@H3 zr$Djm0Uz@wyq#7b_*fDp(q_q}M`HgQ;~x_~PxO)LYg4O@mqJ+wz#`0J!4Fm-JtVkw zKKJZYMDan<{+#Fibv|XsE(+EU&M80Kq|}i}0Uxu(N-ssCHzonEhC~i{6(m5Qn&WK4 z)I=>xjTooErCxNl36a1YMKAUBoCmWp5+KmTh$$LF7jD>@RDzx6xPUtn^oJJ3Y+!p4 pICC-uOaW8C6fgx$0aGAdfe-sZkVA>5w%Gsx002ovPDHLkV1nv}%j*CD diff --git a/MediaBrowser.Plugins.DefaultTheme/Resources/Images/ViewMenu/Decrease.png b/MediaBrowser.Plugins.DefaultTheme/Resources/Images/ViewMenu/Decrease.png deleted file mode 100644 index 9b756c0a9451272ad700e95e91d2d7c9436ec88e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 541 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezpTC#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvI6;>1s;*b3=DjSL74G){)!Z!hE1L>jv*P&Z>Me4V+|B&d!Hx5#oBp@Swn=Y z)oEpjhHZ<}!VheV1o#&yd}NSwSO_G!CPinIsBj6jI&FGw{avoNW$w()yZvTN&Utt8 z?*I8epW9ncHkSBN#D0gd{D5o$hsa{i>{`8eOcs#~b#lA746Ux$c9u2i=z* zh{eQS*H4W+=dp9Ch(uwv*B+@p$KP3#+76_bw0h6gNxCms5wzI7SM_9(`YTSaH@sUF zxEo#6bHyFc6nBdWvwtjBsmWcojJD=&o$jocGy4B*xtVj^XI}K=*-PP^H z#BB@~>A6q+`-G2YWw>4JQor_fX+XI6qB56P$9t<6bl+pPGFhCmrm2$2`fjsIE!UB? z=5v{5_|`s=lYHp+IaYAb?tfo5-hAS^o*|VnL;bzYArE6SvO2C2<6q^4g bFw0+!lvI6;>1s;*b3=DjSL74G){)!Z!hFnh<$B+!?x6}6X9ZV28diz*{fdr2m^K5qm zDchEV4|sXpnh!Q_sOD)t=sY1pRb|q(l^IG+zyIzovGC0cnf3lo@%iijKDi3&s~upO z!62N#snZ|FLE3tlgW|hm_!uvtlOH_Ftb4%=x z-w~hnHSl8VL$g;=JRg3%U1@Szp!Mh1?w>W{W>R~bvJX}KzxwC$|HKb%imb&sN-ys& zXZ(<}zBhDzWkSIp)xVFL=T(|sjEYIPoX}8|^i^^;oAVUz)$$uO&j!k^*>`x^lYJ%; zqCnoq_%&WPrrc>iut#uT5O30Je&Kg{EEn&5t;)q9ePc4mZKIwU+Gfzz=_x~y|@8vl!KIbdusc)I$z JtaD0e0svs?$(sNG diff --git a/MediaBrowser.Plugins.DefaultTheme/Resources/Images/ViewMenu/Index.png b/MediaBrowser.Plugins.DefaultTheme/Resources/Images/ViewMenu/Index.png deleted file mode 100644 index 3e04dc6435c00a449495d1baceb29dae292fd2de..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 484 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezpTC#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvI6;>1s;*b3=DjSL74G){)!Z!hDuKt$B+!?x8b%~Oo0Mr;{1t;6Ym^WVmEa4 zOVA1CsAj3=mOjWFvBcnk;3Q^_WgZjt%D7JD?VGq=LGjVKJ&}nIs}1(l8hk!mbAONg zwyTd8FoiU51u$wku&!Vb%~-?Kx%JZ`4LJerXLgfRPTq0+&(!3=wmLPV%e-9S{O5EP zsf!wqptvfDn+c=L=^!6qNmDmGu-cC+VT%51VYy1=2qXh!yGm30wf1NM-`TyMA zJ9L*$4or6lbq}am%C+l3&9#jybW?1P$jQVQcpPv&#vxFq;AAsBpbW&GaIE~mC!zWW ztg>z$Wn4!WTd?~rujyP{k;Qb)W%{E$Uxn3;2gLp}C+EjJ3WNpSD diff --git a/MediaBrowser.Plugins.DefaultTheme/Resources/Images/ViewMenu/Scroll.png b/MediaBrowser.Plugins.DefaultTheme/Resources/Images/ViewMenu/Scroll.png deleted file mode 100644 index a52e85fbffa0ab8e4999c821b1defa11c2a94b0e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 416 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezpTC#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvI6;>1s;*b3=DjSL74G){)!Z!22)QL$B+!?x6=)|4mk+8Zca)}oY@>v#loup zKvri@yZeSMTQ+KSezGf?O1Wn#%ZC9Vmq&8 z%@R=%TeYt3y`7cNDkpKT6&D(>m+zRbm?xU6`HDqbSMch_3z=IkPwwrq_*GYEu+4SN zt(Di$8*L0Y!7_VGQP%;GoF`#fd|{eEfDHDk(u<|lSrO1qfW>U?p% zk@YxA^ukQ$2#53)w%i+;-!x2O&|Si^V%|Bv6@prbP0l+XkKbrz#3 diff --git a/MediaBrowser.Plugins.DefaultTheme/Resources/Images/ViewMenu/Sort.png b/MediaBrowser.Plugins.DefaultTheme/Resources/Images/ViewMenu/Sort.png deleted file mode 100644 index 45a9e58953d99351f8a0195b298308e6b827fae2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 654 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezpTC#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvI6;>1s;*b3=DjSL74G){)!X^1}0@s7srqc=eN@rdOH^i9N(U3pd-a2%*!pz zdd@v4S|2rt`gu7B*ec+?zcBt*o)8e910MtbcT6^2sNx zVg171p$>~LMyNlGn$se%pDAALobmbPD??VvsL$i_X4F^ty6=EEE^ipC?f!(T)@8*`f&(*rt`dM7w@^`?OrLRAA zuMc13*Q7A@sN8K)#pApmuNDOM3LG@vQqHK^$(65Rj* diff --git a/MediaBrowser.Plugins.DefaultTheme/Resources/Images/ViewMenu/View.png b/MediaBrowser.Plugins.DefaultTheme/Resources/Images/ViewMenu/View.png deleted file mode 100644 index d83fb70a391eeabd41f7321b55df0ae1f84a5a4d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 531 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezpTC#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvI6;>1s;*b3=DjSL74G){)!Z!h83PJjv*P&Z^Jiw9dQuY%fkJ3-G&W29vgl^k<=bL$!Aa=8jA!DBoNq^;Bt6h=(K$JLrg?r^`Q(!> z&RiahnhLB-8bl^A1to0ZQrVq0@A*%~q>8YP0^v4c3QhW;3*f9*{lo&e(8;n9);-=b~>6PwaJgs5tt3cUyfv=0!FudcQUCsF=ig8*^ zXleFBJ#7cwM`llcZkhO3ZP}*zTkf;;ggtx$Tbti>`KoZ8e2NoHG99x(_3YMj3JNrJq&&{SJD26(!5pIW3Gf1ED`hc;y6pxQoY?5uV*NoaC5z4OI4QQHOsIyx_8WfFFo@2 z%;!eqN8Iy;*f$#9VDS^M+0k#^XrJ&s<9%2C;|p>78Ovm6HxvXpAcdxK*aLP2&UBe* T-dasyL^61~`njxgN@xNAFge?N diff --git a/MediaBrowser.Plugins.DefaultTheme/Resources/Images/Watched.png b/MediaBrowser.Plugins.DefaultTheme/Resources/Images/Watched.png deleted file mode 100644 index f126059d7982a90c385016f045413f267ea895d2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1253 zcmVPx#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D1bRtCK~z{ry;y5( zR8T#S(NSu-iSyIcM3MZTE3+!@W$>?zTJg&9^gi z=FD7%35wC)Q-;C8W-jFtNLC9bYYD=yVI+&w-*I}^F9hpGI=Mgk!4u~v;)2;#Hr9sg zIoNZge?R?H*|L)|0fvZ>^37=Hs$M%bmV}Ho9|kz%+W;1_16V?*m!h^Q`u_4COW~9x zWVD1|<_zs%tn3oWk&?!o!wDcdR%) z9zTzeCUYV6HRb*eSIA^Rr937^Q$Z?vbqGx1q2pQ_Pg<(*%Ch*#fqgbRk7B+ZN1}>7(uFX|hK~X;C1yXSFpU)$|eq zPAb>vu|LnC?X5$l)5h3+T#pbAitm~!=xDtc4;VL?sGmhoQo6pvz+eAbdGb>|>v^WA zs8B!l;H_v~v%m@rchA38rzkL^TI(jxC9(OPZ?HZ51Cpt>Q+fAiabgTpRmw_^ z7W)pJLRv@-^30S*iWV)HWjgvKa!jA7_}~9oM`fG_Md;y2=rYZWpao>; zbOQWhAMtoN8g8n^{=>gvG%a+Uv^~{`n(9f~@@(P)w!C{7dk>y~%zTH5O59U7Zz+wW zY)&c5zLUeaB~XLuHIBrwj&)nU)UOUom!5}$Yr~(~z3o+B zTC{MMF6`{-bA*t@k)F;Kb9K{Ddy`#IMdFK`R$$l8N>8v12TkbWwAO27TxPNqipNxvDGccgz~3HcC2ik;_P`PgHo9<@(EC z6xZ#(nhU6g6L6VWT*!1&v~zVV*H7M}sMcGNN;Z*_n?>GNh|HLx&Sk0ATj8625A~*< zjz@`VMwEN+93Ppi9~+NjK5Eu`6DsO06Cy?(ST{ZD zGsPaklq_m1X9g8L-5DW@+7dnf>c@KKJQasT=8+yDd-wThL^!ceTy P00000NkvXXu0mjfsfb^y diff --git a/MediaBrowser.Plugins.DefaultTheme/Resources/Images/Weather/Cloudy.png b/MediaBrowser.Plugins.DefaultTheme/Resources/Images/Weather/Cloudy.png deleted file mode 100644 index cef9cb57429fdade27af4fb299cf4df408a55528..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 650 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1qt-3{3K#E{-7;ac^hXdNVtUxK2KLNU7DeON2{P z=Z%k|M73i#2czy^&Ts!%yji`q1vhTkC?KN4yJBkZgs_geO-)NDRj>(hOgfVC&9|(x z{K3Tjx!()VpE>s?M{Thhlac}s^kF_n%4Ct-IcDjbZ@wv8eKl%HpHkR?dmF0XG-gk~ z;XcWf?PTu*$s_NR<7?jE-tn*R?S(`w4@FNFS0BE>?aeL!_qqN5+}YSLV|L(?@?Ve2 zC6W#_tz{Ik@js~g?xD>5^AWs;(SPhdi#GlD5^>F|^~hg*g6YxwDxb$}|IKUM_GgR5 zL~5JQXY{jK9J5Vti!i@L@tG#^)juYNDu}axe64tNd-mFhYdKsEho-(IorN%fKRM4k=o%L^9&yMFo3ibrj4{qOnzT6e7V z!CvkOHvLy4zkDj}{_s`(zxh7tH(b~E8Sc5xFe!Yp$a|K__vZ@w-PwHn2IGW+v*s(8 z&X;Ckc=PMnmwAjTI=|F-AB2DHm1K8F`d-Js@!g(>S06Ea@S0(^+=5|Vkjk?|+oyFh z9B`_b!_p9Zf627EHw^3yDCh_v!jCXGu-!6USlHnD6(8YlT7jhE%!Dv=@WZUw%E#biQ!{F)a=d#Wz Gp$P!UxD=QG diff --git a/MediaBrowser.Plugins.DefaultTheme/Resources/Images/Weather/Overcast.png b/MediaBrowser.Plugins.DefaultTheme/Resources/Images/Weather/Overcast.png deleted file mode 100644 index 7ee2942e3ddf719a22b97532a3c6f32e6dd17e05..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1050 zcmV+#1m*jQP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D1FuO$K~#8N?V3Mm z6hRcmb4Q94DN>}ch@g-nf`wp;D^gelw6I8Fk+hg5aF1Ne0>mIy?$IQ;oym{X@Z{Ga58yoY-8E^)i z0cXG&a0Z+KXTTY72AlzBz!|6o1BZu)v&b7{xom@)Wp^-)et_OV*1O&Ar0O>sjRoWa z*~@WzBjx5W`bMq};9dY;Pg}H}HMszXHkAxw-B@FV{S$!V)rP`M&k}rdTme+ClCspU0-k+Q?l80ZPsBeVgO$ z0Ri!u#gC{8y6d|+Qh?J^HcWtv>rj7-`~>NTe(lTyCi!-qyjGBC_gKrvTsjN>cvM@7 z^eBODUmkfYE2?@OLP7s532kqWM z8k>kSr<={@=McIJU5IEtRt;XD>9g<|ASSO60T^;V#3H6)|8(*eyHE{PTOC4pNA2c-NBV@V<`dhNxYUndNn(qjDmc^-gh==?42MgRZ+ diff --git a/MediaBrowser.Plugins.DefaultTheme/Resources/Images/Weather/PartlyCloudy.png b/MediaBrowser.Plugins.DefaultTheme/Resources/Images/Weather/PartlyCloudy.png deleted file mode 100644 index d0e1cce56b8eab4c52844f1845e8fcb82baeaf3b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 943 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1qt-49qT`E{-7;ac^hZX9PRS9G`tb(V30?AfKd> zg@%QTNJ&9~pp2DRNx+E*D_%TMD$x)rED$IxC@3ficyVE)m!P=oLMK*kE})u_6&DsZ zUHb9Uu1?=3>1_79xLM&pWdH2=U%vnT^LKUS`ZH&Ic)&8JLAZd)?*OL-qdFSL%P}E6 z{khbqWw+m&c`v-6G4;TO?i0d2bG@D`{%_smWUZ@g>-qC$;47nP8x6A}rwQq&F_dg# zIP>HCwY(~wuD-0GwVNcDh1$=F{3!Kv*C#6>HkSolw^^qKN=`Lj$Fnv>%l?Yr>h3cW z>K(tyy!1Z8`-K0KRHgS__EYO8+Xbx+d;g?2{#Dgli`74({rD^s1zs%?zZCkee`U4b z&4p*)%}}y;|M@aVdiU%ijoQfPa*8hbxVxq0MVUtY1u@s1e)AsQ zth#mIc=-;)gyT6&>kh~yPSTG(5q**|A?k{1|Kht$kJm{wL|=KWrE~xEg)sY_tJ-)a zzTCLS=6m;ZQ{uVe%VB>416SK_n!ezi>iX>pu7;n)+2WS&&tqTuRp^gLjJm!5FU7*i z5l`*An*?q6j+ssP?NMdEe)2u3vZuu|^TYP%T08d@F-I<6Bf6$SP&T((ExOpA$xYv& zpW)1{!Wp`U`W6^|D@yNY;`)5gj3c~b^7^9}1l}-jc{{VD)%eEm8s5;P8+D(!&s59& zG|RdF@7vW5##@gK;(i(B_r9oUdAE0+A;US5g$^$y-ZTX-tlj)Ki9zN5$7G(fO3(Tj zH-xn?2`1O{zL2hGv1ota6`+vR6E0X=9owAGxcA6}PzRS-XGJ%I_v+7VJ71U|ULjD! zQo^cez9^0VMbF3VGt~<@9y2fdzrFk3pA-A`u*`gJ%urQ7PbAUdgWw6jy#7VAr@R!u zC1%vAVqfXr_GNjY<(=tke%%eK`Qsw>^zK}oDfgJ?1O3nb6EZ87{VE4$G6qjqKbLh* G2~7Z!I$f_h!_w=MMgz*O>JG;#nIK;)Y`--`bI~@g(spy;Goma&)-wN z&Csci`L=iFZNYnolE39WtNrue`17;m^t3;PY;zdX4@efEQOk}UD6p`xkl+!UkQ`hb z)uhajub4j}e!_?M5C5`%;)&E&Jf>sVP%PJQUi-phuUj^gwna9*IF-ThKUe5ShD*(( z+I6cdCjVkRky!QhZQVh4l|55zCYsF9>tXy?7X3kxGkkZ4}KMMdCvQ`%RZX+?Z@P)NmoU7ghp;MX}q(QVdINOzs)!099?)#{fD*~ zgJy~1gX9@?Su$F#bM(CUmoOx5b(DGaG-xlEz!%m@0h-cNgIC45c=|S^)U3VCQ}xOw zK~dr6r!>`;i59E3CMrJId@VD}cG=^;Ys*?2azQHAZ#BEhV(>;TYi`USdm1%P~&A6MMeU71QrB_)|yMQzY!_y{byGbV`wCJq+Z%|eqDLH@B8OJbum{z?{kjb^H%Qa z*4~AmzkPb^|Biq5wfujxm%dB7Y%~2V-=@gPx#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D1Hef{K~#8N?U_Gl z6hRcmb4Q945iBe$Qlz-@iWGt=B1BM(l_^q0M7Sb_WeSD#Vl85kLPSFZ1qH85nIeiQ zB1s{nFc2Yv78Zdh3QEr37iM9Jd%4@2*||G>1CP1eoq6wl-@JMAX9otX7z4(DF<=ZB z1IB09Bp0C)*dzjF|9K>KrrI~K!$<~(5b+6AAqqt9jx z{|dLEaLx-pMMB~Epzu`y0#?cFlbtXP5$p6@qW@XyPyF8~m&+eI(G{f+4o(92k-}GV z9{JMg=%27sZ1OHyKBM4jX#|Ic0sAC0*b_)lLanuQELH=+zm5eyl^+iHJsJyRQ#*j4 ziw!E>Xp89JcQGX{)FxeL+CoLBg883k6+rIg-BBFl5`#e+H7gpH>mlqBX<#G zcQipPU@(tix9U$Oer^XqTG$V?gs^W&(+&J*9A$C5;6j`9$&+`=OV#@pP|-K zc_^>9fK^}3`xhj=8AMy&Y3e0vkvf)FXIA^rtH3ah>4+-FMS>1XH@U`omB(3)FtVJ4 zKAY9kKM_mx3IQu&g-MbZu%OG-#^_mJ->V00Zki8GsjYMUeh3v`NDv7 zs@MUkxw)^9KPn=_U6?2*jAszA!1KjscD2Jqwvky8naT_3sHLVVbx2dq!$S%6ft~P6GpM{EdBS`P;{aaC=5Reh_S|UdQQ*nTksUk9}dMAQf z>F@dX8cEI93<8uVT9sPQ1N3z;H8u3{L=tp!lgGcH`+#-~yXZ)+vy~XNt5Y(plH4xD zPH;h1fp&nW+Gt0&1<W%eZxIm-{f)xBHwKIWW55_N28;n? lz!)$Fi~(c780bF+{sOnU^UG@yQf>eM002ovPDHLkV1jVw<1qjL diff --git a/MediaBrowser.Plugins.DefaultTheme/Resources/Images/Weather/Sunny.png b/MediaBrowser.Plugins.DefaultTheme/Resources/Images/Weather/Sunny.png deleted file mode 100644 index be36d84460298cf0dedabf16c65d2e3152c67bfa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1181 zcmV;O1Y-M%P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D1TslPK~#8N?ODG| z)ln4pJscby-cZos;Naj;;LzaU;NaMp5ai&{5)~M<I5;#o7&tgM7+5$Y7!)Wt zI21G#Ji`YC3I+uQiS_w>Irnkj?fbRo{hq52ITsG!U-y3QIiGXxxj(*LT~>?%W55_N z28;n?z!)$Fi~(c77%&Emfiq*^`1p7LvI=?HQBc%5+ReCj5<%O^6io>X zL*~T*X8VD_%iZ|aFVYi60EZ9>6d6vbXEJOUcLg%$I>7x144Q*{^gZnI1PO!OaP>Jo zLZ*@_r~ynPCELHj^;SVP=bXP18eQ~^x*J7n1GKrsAwnYAw}uU+FrdgnFkUzC+?@8r z>-+5*@8=AkP`vNK^EBkpt8@PA2Pm`@5WsPpt?a~jCco$ctUH3$kNXxZ4y97w(`YP1 zV8`>yyeK^Adn=X!nMp>8>CX<59Gm$ty-CAcP-4I5fCYq*sS=9h4s) z+3FGZpYZ-IuD>LIFq-BdyO{sSQ<9Jb8(w4xHw&Jp+wCYPd5*N(_O$ghl3-Dv6J9iM zqx9Ub2qUM!&Jzmn1CY=DGwR$stzqX{U#6_Ob3Z+rlg#|@Eq{m6j%R<(pC_CO&()xq z&Y1wA_*3z8UN$czKyn37m0h;a4ni(efpIHdglt|Yvx8 vUX8(fH7bU7z4&YIR^d$+|VfDpODcy00000NkvXXu0mjf*DDi3 diff --git a/MediaBrowser.Plugins.DefaultTheme/Resources/Images/Weather/Thunder.png b/MediaBrowser.Plugins.DefaultTheme/Resources/Images/Weather/Thunder.png deleted file mode 100644 index 1269cfd7754928f7d9b741c460556d843fdc0f66..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 949 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 M07*qoM6N<$f_U1$ylYrr*!f2 zE3y}58g{Ohou}vJ&vBz1f>4KGpF^j=%%q@IVAC zj)cWgumpvNCDHI;3_M7HrKng~8V5_`;UOYClmHK-zJ!O5!m>nImITXD$*?>HmLG!^ zsjz|sD^X-vnFg!UVb$?hvMjqQ8&;oy)fr$U6O8^9Xifr67SLn^?I|G71FC$R^2{q$ z2~ZZ<)j2?$1I8#|EEkNU^1ygL&=mk3)jn42(47Snr@=%am@ER5#Xyfb0}Lg=a28CV z&VlLDc}=xVQvs&S!1Q@wya0^lz(fO6myvNgqAx?HE`wP*GE;%fTtsFsA+wc;xeBpV zBXfU4=IF@FuMq1M7K_!@)x~DBIUG)RcXv-u50}g3@p!$xy?j2uudlEF8N;lonN`-m z)HVWR!>slWGG4PZ(SVp5mrOq*^EHbzHx|t|k-2)r+KAY`Mr_xXtp8kE_+iQVc+tvq z{>pTMj^AvZ&R0*J4vs(|=7lEJ}2sZ=^NG&DRsER)IPa=AjG zP%4!wl}fEvkBp3rj*eS+$Q4{U;DDHHq}@&mD-g>>hyLp+{MKMmYq1Ao{)543<90M-P2z zgcCGUDV27Ka-jf9p%k5?;gSgC9T)fFLUF-CLCy=U=tv18#zc`%#P#algprSJaW8ww z>d@ax&%kEJ6RPz-yLbDKVt!%OC+xlPny`}H%xIENP~%fq^A3S3RkwjNFLgTK6iDdS z6}s`@@|4R@*&S~xr`0PF*suQAtl0g7x#}j{yY#13+ijY(?Mb^Ge$6x&5Q)pn>F4Y6 z8_Z@|R#ujgeE4%L7UPYh)KxZoIj}!>#yc73mE!Lg9U`t2=2(`F;599v?^RJx0nu z(sy3heDUnm_5>nvQW3B#%&%wT%4}dkT?kVg9D4gk*JqV$7_>r{cWE^8X1%-wPmdXT z6nozftnb^&_8-K5>`ip-xVmxKjoexNv%QfU;=Wb9)-x~UVR2z0M{=o-dL|%%!pKl{ z`gs(Mol1NC-Nj3=P<@CRI_eq`xDfg=ncc5@rp2BMXtmn7$t{^&@qbj(i_)txIR7=# zhkDjpOg>>=o9n%E4raC`>oynABdBi|61{TGo37E?8MPt{kK?_)?{*`aZ_+FkT5rpU zrE0GIdO&lF*mdo%3wEjXd}USoEiI;)vc8^rjJvvXA&zh~Bva7&a0$~<8Q=8V-Kwk9 zGii*K)^KXVa#1}2O>At+Y{E0@Ls#AO)U~jdXw|UfT{L6tmZh{xG)i@*dxP%~u@%-qVb8Y1&ocwKq7&_L(E@Y{>fdrWc&; zL9TA!?!)mExrC1v|NgupXclZgAhA#|KE=O$^y%RjZ5uGLM%&L2bL<3j^CO{WM1*M* zwTkyafY8(AVSXMEa`jt-JRXsD3weQg?*3<@YH{BqYT!@i|}rAN#vp AdjJ3c diff --git a/MediaBrowser.Plugins.DefaultTheme/Theme.cs b/MediaBrowser.Plugins.DefaultTheme/Theme.cs deleted file mode 100644 index 5a730cf081..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/Theme.cs +++ /dev/null @@ -1,81 +0,0 @@ -using MediaBrowser.Model.Dto; -using MediaBrowser.Plugins.DefaultTheme.Pages; -using MediaBrowser.Plugins.DefaultTheme.Resources; -using MediaBrowser.UI; -using MediaBrowser.UI.Controller; -using System.Collections.Generic; -using System.Windows; -using System.Windows.Controls; - -namespace MediaBrowser.Plugins.DefaultTheme -{ - /// - /// Class Theme - /// - class Theme : BaseTheme - { - /// - /// Gets the detail page. - /// - /// The item. - /// Page. - public override Page GetDetailPage(BaseItemDto item) - { - return new DetailPage(item.Id); - } - - /// - /// Gets the list page. - /// - /// The item. - /// Page. - public override Page GetListPage(BaseItemDto item) - { - return new ListPage(item.Id); - } - - /// - /// Gets the home page. - /// - /// Page. - public override Page GetHomePage() - { - return new HomePage(); - } - - /// - /// Displays the weather. - /// - public override void DisplayWeather() - { - App.Instance.Navigate(new WeatherPage()); - } - - /// - /// Gets the login page. - /// - /// Page. - public override Page GetLoginPage() - { - return new LoginPage(); - } - - /// - /// Gets the internal player page. - /// - /// Page. - public override Page GetInternalPlayerPage() - { - return new InternalPlayerPage(); - } - - /// - /// Gets the global resources. - /// - /// IEnumerable{ResourceDictionary}. - public override IEnumerable GetGlobalResources() - { - return new[] { new AppResources() }; - } - } -} diff --git a/MediaBrowser.Plugins.DefaultTheme/app.config b/MediaBrowser.Plugins.DefaultTheme/app.config deleted file mode 100644 index 29abde1f69..0000000000 --- a/MediaBrowser.Plugins.DefaultTheme/app.config +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/MediaBrowser.UI.Controls/BaseModalWindow.cs b/MediaBrowser.UI.Controls/BaseModalWindow.cs deleted file mode 100644 index 90bd8114f6..0000000000 --- a/MediaBrowser.UI.Controls/BaseModalWindow.cs +++ /dev/null @@ -1,62 +0,0 @@ -using System; -using System.Windows; - -namespace MediaBrowser.UI.Controls -{ - /// - /// Class BaseModalWindow - /// - public class BaseModalWindow : BaseWindow - { - /// - /// Shows the modal. - /// - /// The owner. - public void ShowModal(Window owner) - { - WindowStyle = WindowStyle.None; - ResizeMode = ResizeMode.NoResize; - ShowInTaskbar = false; - WindowStartupLocation = WindowStartupLocation.Manual; - AllowsTransparency = true; - - Width = owner.Width; - Height = owner.Height; - Top = owner.Top; - Left = owner.Left; - WindowState = owner.WindowState; - Owner = owner; - - ShowDialog(); - } - - /// - /// Called when [browser back]. - /// - protected override void OnBrowserBack() - { - base.OnBrowserBack(); - - CloseModal(); - } - - /// - /// Raises the event. This method is invoked whenever is set to true internally. - /// - /// The that contains the event data. - protected override void OnInitialized(EventArgs e) - { - base.OnInitialized(e); - - DataContext = this; - } - - /// - /// Closes the modal. - /// - protected virtual void CloseModal() - { - Close(); - } - } -} diff --git a/MediaBrowser.UI.Controls/BaseUserControl.cs b/MediaBrowser.UI.Controls/BaseUserControl.cs deleted file mode 100644 index e47fc84cf2..0000000000 --- a/MediaBrowser.UI.Controls/BaseUserControl.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System.ComponentModel; -using System.Windows.Controls; - -namespace MediaBrowser.UI.Controls -{ - /// - /// Provides a base class for all user controls - /// - public abstract class BaseUserControl : UserControl - { - public event PropertyChangedEventHandler PropertyChanged; - - public virtual void OnPropertyChanged(string name) - { - if (PropertyChanged != null) - { - PropertyChanged(this, new PropertyChangedEventArgs(name)); - } - } - } -} diff --git a/MediaBrowser.UI.Controls/BaseWindow.cs b/MediaBrowser.UI.Controls/BaseWindow.cs deleted file mode 100644 index 0f3ff2874c..0000000000 --- a/MediaBrowser.UI.Controls/BaseWindow.cs +++ /dev/null @@ -1,175 +0,0 @@ -using System; -using System.ComponentModel; -using System.Windows; -using System.Windows.Input; - -namespace MediaBrowser.UI.Controls -{ - /// - /// Provides a base class for all Windows - /// - public abstract class BaseWindow : Window, INotifyPropertyChanged - { - /// - /// Occurs when [property changed]. - /// - public event PropertyChangedEventHandler PropertyChanged; - - /// - /// Called when [property changed]. - /// - /// The info. - public void OnPropertyChanged(String info) - { - if (PropertyChanged != null) - { - PropertyChanged(this, new PropertyChangedEventArgs(info)); - } - } - - /// - /// The _content scale - /// - private double _contentScale = 1; - /// - /// Gets the content scale. - /// - /// The content scale. - public double ContentScale - { - get { return _contentScale; } - private set - { - _contentScale = value; - OnPropertyChanged("ContentScale"); - } - } - - /// - /// Initializes a new instance of the class. - /// - protected BaseWindow() - : base() - { - SizeChanged += MainWindow_SizeChanged; - Loaded += BaseWindowLoaded; - } - - /// - /// Bases the window loaded. - /// - /// The sender. - /// The instance containing the event data. - void BaseWindowLoaded(object sender, RoutedEventArgs e) - { - OnLoaded(); - } - - /// - /// Called when [loaded]. - /// - protected virtual void OnLoaded() - { - MoveFocus(new TraversalRequest(FocusNavigationDirection.First)); - } - - /// - /// Handles the SizeChanged event of the MainWindow control. - /// - /// The source of the event. - /// The instance containing the event data. - void MainWindow_SizeChanged(object sender, SizeChangedEventArgs e) - { - ContentScale = e.NewSize.Height / 1080; - } - - /// - /// Called when [browser back]. - /// - protected virtual void OnBrowserBack() - { - - } - - /// - /// Called when [browser forward]. - /// - protected virtual void OnBrowserForward() - { - - } - - /// - /// Invoked when an unhandled  attached event reaches an element in its route that is derived from this class. Implement this method to add class handling for this event. - /// - /// The that contains the event data. - protected override void OnPreviewKeyDown(KeyEventArgs e) - { - if (IsBackPress(e)) - { - e.Handled = true; - - if (!e.IsRepeat) - { - OnBrowserBack(); - } - } - - else if (IsForwardPress(e)) - { - e.Handled = true; - - if (!e.IsRepeat) - { - OnBrowserForward(); - } - } - base.OnPreviewKeyDown(e); - } - - /// - /// Determines if a keypress should be treated as a backward press - /// - /// The instance containing the event data. - /// true if [is back press] [the specified e]; otherwise, false. - private bool IsBackPress(KeyEventArgs e) - { - if (e.Key == Key.Escape) - { - return true; - } - - if (e.Key == Key.BrowserBack || e.Key == Key.Back) - { - return true; - } - - if (e.SystemKey == Key.Left && e.KeyboardDevice.Modifiers.HasFlag(ModifierKeys.Alt)) - { - return true; - } - - return false; - } - - /// - /// Determines if a keypress should be treated as a forward press - /// - /// The instance containing the event data. - /// true if [is forward press] [the specified e]; otherwise, false. - private bool IsForwardPress(KeyEventArgs e) - { - if (e.Key == Key.BrowserForward) - { - return true; - } - - if (e.SystemKey == Key.RightAlt && e.KeyboardDevice.Modifiers.HasFlag(ModifierKeys.Alt)) - { - return true; - } - - return false; - } - } -} diff --git a/MediaBrowser.UI.Controls/ExtendedButton.cs b/MediaBrowser.UI.Controls/ExtendedButton.cs deleted file mode 100644 index 1b8e9039d4..0000000000 --- a/MediaBrowser.UI.Controls/ExtendedButton.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System.Windows; -using System.Windows.Controls; -using System.Windows.Input; - -namespace MediaBrowser.UI.Controls -{ - /// - /// This subclass simply autofocuses itself when the mouse moves over it - /// - public class ExtendedButton : Button - { - private Point? _lastMouseMovePoint; - - /// - /// Handles OnMouseMove to auto-select the item that's being moused over - /// - protected override void OnMouseMove(MouseEventArgs e) - { - base.OnMouseMove(e); - - var window = this.GetWindow(); - - // If the cursor is currently hidden, don't bother reacting to it - if (Cursor == Cursors.None || window.Cursor == Cursors.None) - { - return; - } - - // Store the last position for comparison purposes - // Even if the mouse is not moving this event will fire as elements are showing and hiding - var pos = e.GetPosition(window); - - if (!_lastMouseMovePoint.HasValue) - { - _lastMouseMovePoint = pos; - return; - } - - if (pos == _lastMouseMovePoint) - { - return; - } - - _lastMouseMovePoint = pos; - - Focus(); - } - } -} diff --git a/MediaBrowser.UI.Controls/ExtendedCheckbox.cs b/MediaBrowser.UI.Controls/ExtendedCheckbox.cs deleted file mode 100644 index 120fa3c24d..0000000000 --- a/MediaBrowser.UI.Controls/ExtendedCheckbox.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System.Windows; -using System.Windows.Controls; -using System.Windows.Input; - -namespace MediaBrowser.UI.Controls -{ - /// - /// Extends Checkbox to provide focus on mouse over - /// - public class ExtendedCheckbox : CheckBox - { - private Point? _lastMouseMovePoint; - - /// - /// Handles OnMouseMove to auto-select the item that's being moused over - /// - protected override void OnMouseMove(MouseEventArgs e) - { - base.OnMouseMove(e); - - var window = this.GetWindow(); - - // If the cursor is currently hidden, don't bother reacting to it - if (Cursor == Cursors.None || window.Cursor == Cursors.None) - { - return; - } - - // Store the last position for comparison purposes - // Even if the mouse is not moving this event will fire as elements are showing and hiding - var pos = e.GetPosition(window); - - if (!_lastMouseMovePoint.HasValue) - { - _lastMouseMovePoint = pos; - return; - } - - if (pos == _lastMouseMovePoint) - { - return; - } - - _lastMouseMovePoint = pos; - - Focus(); - } - } -} diff --git a/MediaBrowser.UI.Controls/ExtendedListBox.cs b/MediaBrowser.UI.Controls/ExtendedListBox.cs deleted file mode 100644 index fb6738939e..0000000000 --- a/MediaBrowser.UI.Controls/ExtendedListBox.cs +++ /dev/null @@ -1,260 +0,0 @@ -using System; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Controls.Primitives; -using System.Windows.Input; -using System.Windows.Media; - -namespace MediaBrowser.UI.Controls -{ - /// - /// Extends the ListBox to provide auto-focus behavior when items are moused over - /// This also adds an ItemInvoked event that is fired when an item is clicked or invoked using the enter key - /// - public class ExtendedListBox : ListBox - { - /// - /// Fired when an item is clicked or invoked using the enter key - /// - public event EventHandler> ItemInvoked; - - /// - /// Called when [item invoked]. - /// - /// The bound object. - protected virtual void OnItemInvoked(object boundObject) - { - if (ItemInvoked != null) - { - ItemInvoked(this, new ItemEventArgs { Argument = boundObject }); - } - } - - /// - /// The _auto focus - /// - private bool _autoFocus = true; - /// - /// Gets or sets a value indicating if the first list item should be auto-focused on load - /// - /// true if [auto focus]; otherwise, false. - public bool AutoFocus - { - get { return _autoFocus; } - set - { - _autoFocus = value; - } - } - - /// - /// Initializes a new instance of the class. - /// - public ExtendedListBox() - : base() - { - ItemContainerGenerator.StatusChanged += ItemContainerGeneratorStatusChanged; - } - - /// - /// The mouse down object - /// - private object mouseDownObject; - - /// - /// Invoked when an unhandled attached routed event reaches an element in its route that is derived from this class. Implement this method to add class handling for this event. - /// - /// The that contains the event data. The event data reports that one or more mouse buttons were pressed. - protected override void OnPreviewMouseDown(MouseButtonEventArgs e) - { - base.OnPreviewMouseDown(e); - - // Get the item that the mouse down event occurred on - mouseDownObject = GetBoundListItemObject((DependencyObject)e.OriginalSource); - } - - /// - /// Invoked when an unhandled  routed event reaches an element in its route that is derived from this class. Implement this method to add class handling for this event. - /// - /// The that contains the event data. The event data reports that the left mouse button was released. - protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e) - { - base.OnMouseLeftButtonUp(e); - - // If the mouse up event occurred on the same item as the mousedown event, then fire ItemInvoked - if (mouseDownObject != null) - { - var boundObject = GetBoundListItemObject((DependencyObject)e.OriginalSource); - - if (mouseDownObject == boundObject) - { - mouseDownObject = null; - OnItemInvoked(boundObject); - } - } - } - - /// - /// The key down object - /// - private object keyDownObject; - - /// - /// Responds to the event. - /// - /// Provides data for . - protected override void OnKeyDown(KeyEventArgs e) - { - if (e.Key == Key.Enter) - { - if (!e.IsRepeat) - { - // Get the item that the keydown event occurred on - keyDownObject = GetBoundListItemObject((DependencyObject)e.OriginalSource); - } - - e.Handled = true; - } - - base.OnKeyDown(e); - } - - /// - /// Invoked when an unhandled  attached event reaches an element in its route that is derived from this class. Implement this method to add class handling for this event. - /// - /// The that contains the event data. - protected override void OnKeyUp(KeyEventArgs e) - { - base.OnKeyUp(e); - - // Fire ItemInvoked when enter is pressed on an item - if (e.Key == Key.Enter) - { - if (!e.IsRepeat) - { - // If the keyup event occurred on the same item as the keydown event, then fire ItemInvoked - if (keyDownObject != null) - { - var boundObject = GetBoundListItemObject((DependencyObject)e.OriginalSource); - - if (keyDownObject == boundObject) - { - keyDownObject = null; - OnItemInvoked(boundObject); - } - } - } - - e.Handled = true; - } - } - - /// - /// The _last mouse move point - /// - private Point? _lastMouseMovePoint; - - /// - /// Handles OnMouseMove to auto-select the item that's being moused over - /// - /// Provides data for . - protected override void OnMouseMove(MouseEventArgs e) - { - base.OnMouseMove(e); - - var window = this.GetWindow(); - - // If the cursor is currently hidden, don't bother reacting to it - if (Cursor == Cursors.None || window.Cursor == Cursors.None) - { - return; - } - - // Store the last position for comparison purposes - // Even if the mouse is not moving this event will fire as elements are showing and hiding - var pos = e.GetPosition(window); - - if (!_lastMouseMovePoint.HasValue) - { - _lastMouseMovePoint = pos; - return; - } - - if (pos == _lastMouseMovePoint) - { - return; - } - - _lastMouseMovePoint = pos; - - var dep = (DependencyObject)e.OriginalSource; - - while ((dep != null) && !(dep is ListBoxItem)) - { - dep = VisualTreeHelper.GetParent(dep); - } - - if (dep != null) - { - var listBoxItem = dep as ListBoxItem; - - if (!listBoxItem.IsFocused) - { - listBoxItem.Focus(); - } - } - } - - /// - /// Gets the datacontext for a given ListBoxItem - /// - /// The dep. - /// System.Object. - private object GetBoundListItemObject(DependencyObject dep) - { - while ((dep != null) && !(dep is ListBoxItem)) - { - dep = VisualTreeHelper.GetParent(dep); - } - - if (dep == null) - { - return null; - } - - return ItemContainerGenerator.ItemFromContainer(dep); - } - - /// - /// Autofocuses the first list item when the list is loaded - /// - /// The sender. - /// The instance containing the event data. - void ItemContainerGeneratorStatusChanged(object sender, EventArgs e) - { - if (ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated && AutoFocus) - { - Dispatcher.InvokeAsync(OnContainersGenerated); - } - } - - /// - /// Called when [containers generated]. - /// - void OnContainersGenerated() - { - var index = 0; - - if (index >= 0) - { - var item = ItemContainerGenerator.ContainerFromIndex(index) as ListBoxItem; - - if (item != null) - { - item.Focus(); - ItemContainerGenerator.StatusChanged -= ItemContainerGeneratorStatusChanged; - } - } - } - } -} diff --git a/MediaBrowser.UI.Controls/ExtendedRadioButton.cs b/MediaBrowser.UI.Controls/ExtendedRadioButton.cs deleted file mode 100644 index 82aad7f098..0000000000 --- a/MediaBrowser.UI.Controls/ExtendedRadioButton.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System.Windows; -using System.Windows.Controls; -using System.Windows.Input; - -namespace MediaBrowser.UI.Controls -{ - /// - /// Extends RadioButton to provide focus on mouse over, and invoke on enter press - /// - public class ExtendedRadioButton : RadioButton - { - private Point? _lastMouseMovePoint; - - /// - /// Handles OnMouseMove to auto-select the item that's being moused over - /// - protected override void OnMouseMove(MouseEventArgs e) - { - base.OnMouseMove(e); - - var window = this.GetWindow(); - - // If the cursor is currently hidden, don't bother reacting to it - if (Cursor == Cursors.None || window.Cursor == Cursors.None) - { - return; - } - - // Store the last position for comparison purposes - // Even if the mouse is not moving this event will fire as elements are showing and hiding - var pos = e.GetPosition(window); - - if (!_lastMouseMovePoint.HasValue) - { - _lastMouseMovePoint = pos; - return; - } - - if (pos == _lastMouseMovePoint) - { - return; - } - - _lastMouseMovePoint = pos; - - Focus(); - } - } -} diff --git a/MediaBrowser.UI.Controls/ExtendedScrollViewer.cs b/MediaBrowser.UI.Controls/ExtendedScrollViewer.cs deleted file mode 100644 index c1a6f1c478..0000000000 --- a/MediaBrowser.UI.Controls/ExtendedScrollViewer.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System.Windows.Controls; -using System.Windows.Input; - -namespace MediaBrowser.UI.Controls -{ - /// - /// This subclass solves the problem of ScrollViewers eating KeyDown for all arrow keys - /// - public class ExtendedScrollViewer : ScrollViewer - { - protected override void OnKeyDown(KeyEventArgs e) - { - if (e.Handled || e.OriginalSource == this) - { - base.OnKeyDown(e); - return; - } - - // Don't eat left/right if horizontal scrolling is disabled - if (e.Key == Key.Left || e.Key == Key.Right) - { - if (HorizontalScrollBarVisibility == ScrollBarVisibility.Disabled) - { - return; - } - } - - // Don't eat up/down if vertical scrolling is disabled - if (e.Key == Key.Up || e.Key == Key.Down) - { - if (VerticalScrollBarVisibility == ScrollBarVisibility.Disabled) - { - return; - } - } - - // Let the base class do it's thing - base.OnKeyDown(e); - } - } -} diff --git a/MediaBrowser.UI.Controls/ItemEventArgs.cs b/MediaBrowser.UI.Controls/ItemEventArgs.cs deleted file mode 100644 index e0c24b2f59..0000000000 --- a/MediaBrowser.UI.Controls/ItemEventArgs.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; - -namespace MediaBrowser.UI.Controls -{ - /// - /// Provides a generic EventArgs subclass that can hold any kind of object - /// - /// - public class ItemEventArgs : EventArgs - { - /// - /// Gets or sets the argument. - /// - /// The argument. - public T Argument { get; set; } - } -} diff --git a/MediaBrowser.UI.Controls/MediaBrowser.UI.Controls.csproj b/MediaBrowser.UI.Controls/MediaBrowser.UI.Controls.csproj deleted file mode 100644 index ee8d2dca76..0000000000 --- a/MediaBrowser.UI.Controls/MediaBrowser.UI.Controls.csproj +++ /dev/null @@ -1,110 +0,0 @@ - - - - - Debug - AnyCPU - {1ADFE460-FD95-46FA-8871-CCCB4B62E2E8} - library - Properties - MediaBrowser.UI.Controls - MediaBrowser.UI.Controls - v4.5 - 512 - {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - 4 - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - ..\ThirdParty\Expression\Microsoft.Expression.Effects.dll - - - ..\ThirdParty\Expression\Microsoft.Expression.Interactions.dll - - - - - - - - - - 4.0 - - - - - - - - - - - - - - - - - Code - - - True - True - Resources.resx - - - True - Settings.settings - True - - - - - - - - ResXFileCodeGenerator - Resources.Designer.cs - - - SettingsSingleFileGenerator - Settings.Designer.cs - - - - - - MSBuild:Compile - Designer - - - - - xcopy "$(TargetPath)" "$(SolutionDir)\Nuget\dlls\" /y /d /r /i - - - \ No newline at end of file diff --git a/MediaBrowser.UI.Controls/Properties/AssemblyInfo.cs b/MediaBrowser.UI.Controls/Properties/AssemblyInfo.cs deleted file mode 100644 index 0d360004c1..0000000000 --- a/MediaBrowser.UI.Controls/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,55 +0,0 @@ -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("MediaBrowser.UI.Controls")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("MediaBrowser.UI.Controls")] -[assembly: AssemblyCopyright("Copyright © 2013")] -[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/MediaBrowser.UI.Controls/Properties/Resources.Designer.cs b/MediaBrowser.UI.Controls/Properties/Resources.Designer.cs deleted file mode 100644 index b03f1d59bd..0000000000 --- a/MediaBrowser.UI.Controls/Properties/Resources.Designer.cs +++ /dev/null @@ -1,62 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.18033 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace MediaBrowser.UI.Controls.Properties { - - - /// - /// 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 ((resourceMan == null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MediaBrowser.UI.Controls.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/MediaBrowser.UI.Controls/Properties/Resources.resx b/MediaBrowser.UI.Controls/Properties/Resources.resx deleted file mode 100644 index af7dbebbac..0000000000 --- a/MediaBrowser.UI.Controls/Properties/Resources.resx +++ /dev/null @@ -1,117 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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/MediaBrowser.UI.Controls/Properties/Settings.Designer.cs b/MediaBrowser.UI.Controls/Properties/Settings.Designer.cs deleted file mode 100644 index d256289c13..0000000000 --- a/MediaBrowser.UI.Controls/Properties/Settings.Designer.cs +++ /dev/null @@ -1,30 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.18033 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace MediaBrowser.UI.Controls.Properties -{ - - - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.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/MediaBrowser.UI.Controls/Properties/Settings.settings b/MediaBrowser.UI.Controls/Properties/Settings.settings deleted file mode 100644 index 033d7a5e9e..0000000000 --- a/MediaBrowser.UI.Controls/Properties/Settings.settings +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/MediaBrowser.UI.Controls/ScrollingPanel.cs b/MediaBrowser.UI.Controls/ScrollingPanel.cs deleted file mode 100644 index 636661f544..0000000000 --- a/MediaBrowser.UI.Controls/ScrollingPanel.cs +++ /dev/null @@ -1,404 +0,0 @@ -using System; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Controls.Primitives; -using System.Windows.Media; -using System.Windows.Media.Animation; - -namespace MediaBrowser.UI.Controls -{ - /// - /// This started from: - /// http://www.switchonthecode.com/tutorials/wpf-tutorial-implementing-iscrollinfo - /// Then, after implementing this, content was being displayed in stack panel like manner. - /// I then reviewed the source code of ScrollContentPresenter and updated MeasureOverride and ArrangeOverride to match. - /// - public class ScrollingPanel : Grid, IScrollInfo - { - /// - /// The infinite size - /// - private static Size InfiniteSize = new Size(double.PositiveInfinity, double.PositiveInfinity); - /// - /// The line size - /// - private const double LineSize = 16; - /// - /// The wheel size - /// - private const double WheelSize = 3 * LineSize; - - /// - /// The _ offset - /// - private Vector _Offset; - /// - /// The _ extent - /// - private Size _Extent; - /// - /// The _ viewport - /// - private Size _Viewport; - - /// - /// The _ animation length - /// - private TimeSpan _AnimationLength = TimeSpan.FromMilliseconds(125); - - /// - /// When overridden in a derived class, measures the size in layout required for child elements and determines a size for the -derived class. - /// - /// The available size that this element can give to child elements. Infinity can be specified as a value to indicate that the element will size to whatever content is available. - /// The size that this element determines it needs during layout, based on its calculations of child element sizes. - protected override Size MeasureOverride(Size availableSize) - { - if (Children == null || Children.Count == 0) - { - return availableSize; - } - - var constraint2 = availableSize; - if (CanHorizontallyScroll) - { - constraint2.Width = double.PositiveInfinity; - } - if (CanVerticallyScroll) - { - constraint2.Height = double.PositiveInfinity; - } - - var uiElement = Children[0]; - - uiElement.Measure(constraint2); - var size = uiElement.DesiredSize; - - VerifyScrollData(availableSize, size); - - size.Width = Math.Min(availableSize.Width, size.Width); - size.Height = Math.Min(availableSize.Height, size.Height); - - return size; - } - - /// - /// Arranges the content of a element. - /// - /// Specifies the size this element should use to arrange its child elements. - /// that represents the arranged size of this Grid element and its children. - protected override Size ArrangeOverride(Size arrangeSize) - { - this.VerifyScrollData(arrangeSize, _Extent); - - if (this.Children == null || this.Children.Count == 0) - { - return arrangeSize; - } - - TranslateTransform trans = null; - - var uiElement = Children[0]; - - var finalRect = new Rect(uiElement.DesiredSize); - - // ScrollContentPresenter sets these to 0 - current offset - // We need to set it to zero in order to make the animation work - finalRect.X = 0; - finalRect.Y = 0; - - finalRect.Width = Math.Max(finalRect.Width, arrangeSize.Width); - finalRect.Height = Math.Max(finalRect.Height, arrangeSize.Height); - - trans = uiElement.RenderTransform as TranslateTransform; - - if (trans == null) - { - uiElement.RenderTransformOrigin = new Point(0, 0); - trans = new TranslateTransform(); - uiElement.RenderTransform = trans; - } - - uiElement.Arrange(finalRect); - - trans.BeginAnimation(TranslateTransform.XProperty, - GetAnimation(0 - HorizontalOffset), - HandoffBehavior.Compose); - trans.BeginAnimation(TranslateTransform.YProperty, - GetAnimation(0 - VerticalOffset), - HandoffBehavior.Compose); - - return arrangeSize; - } - - /// - /// Gets the animation. - /// - /// To value. - /// DoubleAnimation. - private DoubleAnimation GetAnimation(double toValue) - { - var animation = new DoubleAnimation(toValue, _AnimationLength); - - animation.EasingFunction = new ExponentialEase { EasingMode = EasingMode.EaseInOut }; - - return animation; - } - - #region Movement Methods - /// - /// Scrolls down within content by one logical unit. - /// - public void LineDown() - { SetVerticalOffset(VerticalOffset + LineSize); } - - /// - /// Scrolls up within content by one logical unit. - /// - public void LineUp() - { SetVerticalOffset(VerticalOffset - LineSize); } - - /// - /// Scrolls left within content by one logical unit. - /// - public void LineLeft() - { SetHorizontalOffset(HorizontalOffset - LineSize); } - - /// - /// Scrolls right within content by one logical unit. - /// - public void LineRight() - { SetHorizontalOffset(HorizontalOffset + LineSize); } - - /// - /// Scrolls down within content after a user clicks the wheel button on a mouse. - /// - public void MouseWheelDown() - { SetVerticalOffset(VerticalOffset + WheelSize); } - - /// - /// Scrolls up within content after a user clicks the wheel button on a mouse. - /// - public void MouseWheelUp() - { SetVerticalOffset(VerticalOffset - WheelSize); } - - /// - /// Scrolls left within content after a user clicks the wheel button on a mouse. - /// - public void MouseWheelLeft() - { SetHorizontalOffset(HorizontalOffset - WheelSize); } - - /// - /// Scrolls right within content after a user clicks the wheel button on a mouse. - /// - public void MouseWheelRight() - { SetHorizontalOffset(HorizontalOffset + WheelSize); } - - /// - /// Scrolls down within content by one page. - /// - public void PageDown() - { SetVerticalOffset(VerticalOffset + ViewportHeight); } - - /// - /// Scrolls up within content by one page. - /// - public void PageUp() - { SetVerticalOffset(VerticalOffset - ViewportHeight); } - - /// - /// Scrolls left within content by one page. - /// - public void PageLeft() - { SetHorizontalOffset(HorizontalOffset - ViewportWidth); } - - /// - /// Scrolls right within content by one page. - /// - public void PageRight() - { SetHorizontalOffset(HorizontalOffset + ViewportWidth); } - #endregion - - /// - /// Gets or sets a element that controls scrolling behavior. - /// - /// The scroll owner. - /// A element that controls scrolling behavior. This property has no default value. - public ScrollViewer ScrollOwner { get; set; } - - /// - /// Gets or sets a value that indicates whether scrolling on the horizontal axis is possible. - /// - /// true if this instance can horizontally scroll; otherwise, false. - /// true if scrolling is possible; otherwise, false. This property has no default value. - public bool CanHorizontallyScroll { get; set; } - - /// - /// Gets or sets a value that indicates whether scrolling on the vertical axis is possible. - /// - /// true if this instance can vertically scroll; otherwise, false. - /// true if scrolling is possible; otherwise, false. This property has no default value. - public bool CanVerticallyScroll { get; set; } - - /// - /// Gets the vertical size of the extent. - /// - /// The height of the extent. - /// A that represents, in device independent pixels, the vertical size of the extent.This property has no default value. - public double ExtentHeight - { get { return _Extent.Height; } } - - /// - /// Gets the horizontal size of the extent. - /// - /// The width of the extent. - /// A that represents, in device independent pixels, the horizontal size of the extent. This property has no default value. - public double ExtentWidth - { get { return _Extent.Width; } } - - /// - /// Gets the horizontal offset of the scrolled content. - /// - /// The horizontal offset. - /// A that represents, in device independent pixels, the horizontal offset. This property has no default value. - public double HorizontalOffset - { get { return _Offset.X; } } - - /// - /// Gets the vertical offset of the scrolled content. - /// - /// The vertical offset. - /// A that represents, in device independent pixels, the vertical offset of the scrolled content. Valid values are between zero and the minus the . This property has no default value. - public double VerticalOffset - { get { return _Offset.Y; } } - - /// - /// Gets the vertical size of the viewport for this content. - /// - /// The height of the viewport. - /// A that represents, in device independent pixels, the vertical size of the viewport for this content. This property has no default value. - public double ViewportHeight - { get { return _Viewport.Height; } } - - /// - /// Gets the horizontal size of the viewport for this content. - /// - /// The width of the viewport. - /// A that represents, in device independent pixels, the horizontal size of the viewport for this content. This property has no default value. - public double ViewportWidth - { get { return _Viewport.Width; } } - - /// - /// Forces content to scroll until the coordinate space of a object is visible. - /// - /// A that becomes visible. - /// A bounding rectangle that identifies the coordinate space to make visible. - /// A that is visible. - public Rect MakeVisible(Visual visual, Rect rectangle) - { - if (rectangle.IsEmpty || visual == null - || visual == this || !base.IsAncestorOf(visual)) - { return Rect.Empty; } - - rectangle = visual.TransformToAncestor(this).TransformBounds(rectangle); - - //rectangle.Inflate(50, 50); - rectangle.Scale(1.2, 1.2); - - Rect viewRect = new Rect(HorizontalOffset, - VerticalOffset, ViewportWidth, ViewportHeight); - rectangle.X += viewRect.X; - rectangle.Y += viewRect.Y; - - viewRect.X = CalculateNewScrollOffset(viewRect.Left, - viewRect.Right, rectangle.Left, rectangle.Right); - viewRect.Y = CalculateNewScrollOffset(viewRect.Top, - viewRect.Bottom, rectangle.Top, rectangle.Bottom); - SetHorizontalOffset(viewRect.X); - SetVerticalOffset(viewRect.Y); - rectangle.Intersect(viewRect); - rectangle.X -= viewRect.X; - rectangle.Y -= viewRect.Y; - - return rectangle; - } - - /// - /// Calculates the new scroll offset. - /// - /// The top view. - /// The bottom view. - /// The top child. - /// The bottom child. - /// System.Double. - private static double CalculateNewScrollOffset(double topView, - double bottomView, double topChild, double bottomChild) - { - bool offBottom = topChild < topView && bottomChild < bottomView; - bool offTop = bottomChild > bottomView && topChild > topView; - bool tooLarge = (bottomChild - topChild) > (bottomView - topView); - - if (!offBottom && !offTop) - { return topView; } //Don't do anything, already in view - - if ((offBottom && !tooLarge) || (offTop && tooLarge)) - { return topChild; } - - return (bottomChild - (bottomView - topView)); - } - - /// - /// Verifies the scroll data. - /// - /// The viewport. - /// The extent. - protected void VerifyScrollData(Size viewport, Size extent) - { - if (double.IsInfinity(viewport.Width)) - { viewport.Width = extent.Width; } - - if (double.IsInfinity(viewport.Height)) - { viewport.Height = extent.Height; } - - _Extent = extent; - _Viewport = viewport; - - _Offset.X = Math.Max(0, - Math.Min(_Offset.X, ExtentWidth - ViewportWidth)); - _Offset.Y = Math.Max(0, - Math.Min(_Offset.Y, ExtentHeight - ViewportHeight)); - - if (ScrollOwner != null) - { ScrollOwner.InvalidateScrollInfo(); } - } - - /// - /// Sets the amount of horizontal offset. - /// - /// The degree to which content is horizontally offset from the containing viewport. - public void SetHorizontalOffset(double offset) - { - offset = Math.Max(0, - Math.Min(offset, ExtentWidth - ViewportWidth)); - if (!offset.Equals(_Offset.X)) - { - _Offset.X = offset; - InvalidateArrange(); - } - } - - /// - /// Sets the amount of vertical offset. - /// - /// The degree to which content is vertically offset from the containing viewport. - public void SetVerticalOffset(double offset) - { - offset = Math.Max(0, - Math.Min(offset, ExtentHeight - ViewportHeight)); - if (!offset.Equals(_Offset.Y)) - { - _Offset.Y = offset; - InvalidateArrange(); - } - } - } -} diff --git a/MediaBrowser.UI.Controls/Themes/Generic.xaml b/MediaBrowser.UI.Controls/Themes/Generic.xaml deleted file mode 100644 index 44e50a5596..0000000000 --- a/MediaBrowser.UI.Controls/Themes/Generic.xaml +++ /dev/null @@ -1,17 +0,0 @@ - - - - diff --git a/MediaBrowser.UI.Controls/TransitionControl.cs b/MediaBrowser.UI.Controls/TransitionControl.cs deleted file mode 100644 index d1e5ccf0ae..0000000000 --- a/MediaBrowser.UI.Controls/TransitionControl.cs +++ /dev/null @@ -1,147 +0,0 @@ -using Microsoft.Expression.Media.Effects; -using System.ComponentModel; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Media; -using System.Windows.Media.Animation; - -namespace MediaBrowser.UI.Controls -{ - /// - /// http://victorcher.blogspot.com/2012/02/wpf-transactions.html - /// - public class TransitionControl : ContentControl - { - /// - /// The _content presenter - /// - private ContentPresenter _contentPresenter; - - /// - /// Initializes static members of the class. - /// - static TransitionControl() - { - DefaultStyleKeyProperty.OverrideMetadata( - typeof(TransitionControl), new FrameworkPropertyMetadata(typeof(TransitionControl))); - - ContentProperty.OverrideMetadata( - typeof(TransitionControl), new FrameworkPropertyMetadata(OnContentPropertyChanged)); - } - - /// - /// When overridden in a derived class, is invoked whenever application code or internal processes call . - /// - public override void OnApplyTemplate() - { - base.OnApplyTemplate(); - _contentPresenter = (ContentPresenter)Template.FindName("ContentPresenter", this); - } - - #region DP TransitionType - - /// - /// Gets or sets the type of the transition. - /// - /// The type of the transition. - public TransitionEffect TransitionType - { - get { return (TransitionEffect)GetValue(TransitionTypeProperty); } - set { SetValue(TransitionTypeProperty, value); } - } - - // Using a DependencyProperty as the backing store for TransitionType. This enables animation, styling, binding, etc... - /// - /// The transition type property - /// - public static readonly DependencyProperty TransitionTypeProperty = - DependencyProperty.Register("TransitionType", typeof(TransitionEffect), typeof(TransitionControl), - new UIPropertyMetadata(new BlindsTransitionEffect())); - - #endregion DP TransitionType - - #region DP Transition Animation - - /// - /// Gets or sets the transition animation. - /// - /// The transition animation. - public DoubleAnimation TransitionAnimation - { - get { return (DoubleAnimation)GetValue(TransitionAnimationProperty); } - set { SetValue(TransitionAnimationProperty, value); } - } - - // Using a DependencyProperty as the backing store for TransitionAnimation. This enables animation, styling, binding, etc... - /// - /// The transition animation property - /// - public static readonly DependencyProperty TransitionAnimationProperty = - DependencyProperty.Register("TransitionAnimation", typeof(DoubleAnimation), typeof(TransitionControl), new UIPropertyMetadata(null)); - - #endregion DP Transition Animation - - /// - /// Called when [content property changed]. - /// - /// The dp. - /// The instance containing the event data. - private static void OnContentPropertyChanged(DependencyObject dp, DependencyPropertyChangedEventArgs args) - { - var oldContent = args.OldValue; - var newContent = args.NewValue; - - var transitionControl = (TransitionControl)dp; - - if (DesignerProperties.GetIsInDesignMode(transitionControl)) - return; - - if (oldContent != null && newContent != null && transitionControl.IsVisible) - { - transitionControl.AnimateContent(oldContent, newContent); - } - else if (newContent != null) - { - transitionControl.Content = newContent; - } - } - - /// - /// Animates the content. - /// - /// The old content. - /// The new content. - private void AnimateContent(object oldContent, object newContent) - { - FrameworkElement oldContentVisual; - - try - { - oldContentVisual = VisualTreeHelper.GetChild(_contentPresenter, 0) as FrameworkElement; - } - catch - { - return; - } - - var transitionEffect = TransitionType; - - if (transitionEffect == null) - { - _contentPresenter.Content = newContent; - return; - } - - var da = TransitionAnimation; - da.From = 0; - da.To = 1; - da.FillBehavior = FillBehavior.HoldEnd; - - transitionEffect.OldImage = new VisualBrush(oldContentVisual); - transitionEffect.BeginAnimation(TransitionEffect.ProgressProperty, da); - - _contentPresenter.Effect = transitionEffect; - _contentPresenter.Content = newContent; - } - } -} \ No newline at end of file diff --git a/MediaBrowser.UI.Controls/TransitionFrame.cs b/MediaBrowser.UI.Controls/TransitionFrame.cs deleted file mode 100644 index e6f8325cc8..0000000000 --- a/MediaBrowser.UI.Controls/TransitionFrame.cs +++ /dev/null @@ -1,194 +0,0 @@ -using Microsoft.Expression.Media.Effects; -using System; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Media; -using System.Windows.Media.Animation; - -namespace MediaBrowser.UI.Controls -{ - /// - /// Class TransitionFrame - /// - public class TransitionFrame : Frame - { - /// - /// The _content presenter - /// - private ContentPresenter _contentPresenter = null; - - #region DP TransitionType - - /// - /// Gets or sets the type of the transition. - /// - /// The type of the transition. - public TransitionEffect TransitionType - { - get { return (TransitionEffect)GetValue(TransitionTypeProperty); } - set { SetValue(TransitionTypeProperty, value); } - } - - // Using a DependencyProperty as the backing store for TransitionType. This enables animation, styling, binding, etc... - /// - /// The transition type property - /// - public static readonly DependencyProperty TransitionTypeProperty = - DependencyProperty.Register("TransitionType", typeof(TransitionEffect), typeof(TransitionFrame), - new UIPropertyMetadata(new BlindsTransitionEffect())); - - #endregion DP TransitionType - - #region DP Transition Animation - - /// - /// Gets or sets the transition animation. - /// - /// The transition animation. - public DoubleAnimation TransitionAnimation - { - get { return (DoubleAnimation)GetValue(TransitionAnimationProperty); } - set { SetValue(TransitionAnimationProperty, value); } - } - - // Using a DependencyProperty as the backing store for TransitionAnimation. This enables animation, styling, binding, etc... - /// - /// The transition animation property - /// - public static readonly DependencyProperty TransitionAnimationProperty = - DependencyProperty.Register("TransitionAnimation", typeof(DoubleAnimation), typeof(TransitionFrame), new UIPropertyMetadata(null)); - - #endregion DP Transition Animation - - /// - /// Called when the template generation for the visual tree is created. - /// - public override void OnApplyTemplate() - { - // get a reference to the frame's content presenter - // this is the element we will fade in and out - _contentPresenter = GetTemplateChild("PART_FrameCP") as ContentPresenter; - base.OnApplyTemplate(); - } - - /// - /// Animates the content. - /// - /// The navigation action. - /// if set to true [check content]. - /// if set to true [is back]. - private void AnimateContent(Action navigationAction, bool checkContent = true, bool isBack = false) - { - if (TransitionType == null || (checkContent && Content == null)) - { - CommandBindings.Clear(); - navigationAction(); - CommandBindings.Clear(); - return; - } - - var oldContentVisual = this as FrameworkElement; - - _contentPresenter.IsHitTestVisible = false; - - var da = TransitionAnimation.Clone(); - da.From = 0; - da.To = 1; - da.FillBehavior = FillBehavior.HoldEnd; - - var transitionEffect = TransitionType.Clone() as TransitionEffect; - - if (isBack) - { - ReverseDirection(transitionEffect); - } - - transitionEffect.OldImage = new VisualBrush(oldContentVisual); - transitionEffect.BeginAnimation(TransitionEffect.ProgressProperty, da); - - _contentPresenter.Effect = transitionEffect; - _contentPresenter.IsHitTestVisible = true; - - // Remove base class bindings to remote buttons - CommandBindings.Clear(); - - navigationAction(); - - CommandBindings.Clear(); - } - - /// - /// Navigates the with transition. - /// - /// The page. - public void NavigateWithTransition(Page page) - { - AnimateContent(() => Navigate(page)); - } - - /// - /// Navigates the with transition. - /// - /// The page. - public void NavigateWithTransition(Uri page) - { - AnimateContent(() => Navigate(page)); - } - - /// - /// Goes the back with transition. - /// - public void GoBackWithTransition() - { - if (CanGoBack) - { - AnimateContent(GoBack, false, true); - } - } - - /// - /// Goes the forward with transition. - /// - public void GoForwardWithTransition() - { - if (CanGoForward) - { - AnimateContent(GoForward, false); - } - } - - /// - /// Reverses the direction. - /// - /// The transition effect. - private void ReverseDirection(TransitionEffect transitionEffect) - { - var circleRevealTransitionEffect = transitionEffect as CircleRevealTransitionEffect; - - if (circleRevealTransitionEffect != null) - { - circleRevealTransitionEffect.Reverse = true; - return; - } - - var slideInTransitionEffect = transitionEffect as SlideInTransitionEffect; - if (slideInTransitionEffect != null) - { - if (slideInTransitionEffect.SlideDirection == SlideDirection.RightToLeft) - { - slideInTransitionEffect.SlideDirection = SlideDirection.LeftToRight; - } - return; - } - - var wipeTransitionEffect = transitionEffect as WipeTransitionEffect; - if (wipeTransitionEffect != null) - { - if (wipeTransitionEffect.WipeDirection == WipeDirection.RightToLeft) - { - wipeTransitionEffect.WipeDirection = WipeDirection.LeftToRight; - } - } - } - } -} diff --git a/MediaBrowser.UI.Controls/TreeHelper.cs b/MediaBrowser.UI.Controls/TreeHelper.cs deleted file mode 100644 index 0347f1eba4..0000000000 --- a/MediaBrowser.UI.Controls/TreeHelper.cs +++ /dev/null @@ -1,321 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Windows; -using System.Windows.Media; - -namespace MediaBrowser.UI.Controls -{ - /// - /// Helper methods for UI-related tasks. - /// - public static class TreeHelper - { - /// - /// Gets the window. - /// - /// The element. - /// Window. - /// The window. - public static Window GetWindow(this FrameworkElement element) - { - return element.ParentOfType(); - } - - /// - /// Gets the parent. - /// - /// The element. - /// DependencyObject. - private static DependencyObject GetParent(this DependencyObject element) - { - DependencyObject parent = VisualTreeHelper.GetParent(element); - if (parent == null) - { - FrameworkElement frameworkElement = element as FrameworkElement; - if (frameworkElement != null) - { - parent = frameworkElement.Parent; - } - } - return parent; - } - - /// - /// Gets the parents. - /// - /// The element. - /// IEnumerable{DependencyObject}. - /// element - public static IEnumerable GetParents(this DependencyObject element) - { - if (element == null) - { - throw new ArgumentNullException("element"); - } - while ((element = element.GetParent()) != null) - { - yield return element; - } - yield break; - } - - /// - /// Parents the type of the of. - /// - /// - /// The element. - /// ``0. - public static T ParentOfType(this DependencyObject element) where T : DependencyObject - { - if (element == null) - { - return default(T); - } - return element.GetParents().OfType().FirstOrDefault(); - } - - /// - /// Finds a Child of a given item in the visual tree. - /// - /// The type of the queried item. - /// A direct parent of the queried item. - /// x:Name or Name of child. - /// The first parent item that matches the submitted type parameter. - /// If not matching item can be found, - /// a null parent is being returned. - public static T FindChild(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(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; - } - - /// - /// Gets the visual child. - /// - /// - /// The reference visual. - /// ``0. - public static T GetVisualChild(this Visual referenceVisual) where T : Visual - { - Visual child = null; - for (Int32 i = 0; i < VisualTreeHelper.GetChildrenCount(referenceVisual); i++) - { - child = VisualTreeHelper.GetChild(referenceVisual, i) as Visual; - if (child != null && (child.GetType() == typeof(T))) - { - break; - } - else if (child != null) - { - child = GetVisualChild(child); - if (child != null && (child.GetType() == typeof(T))) - { - break; - } - } - } - return child as T; - } - - #region find parent - - /// - /// Finds a parent of a given item on the visual tree. - /// - /// The type of the queried item. - /// A direct or indirect child of the - /// queried item. - /// The first parent item that matches the submitted - /// type parameter. If not matching item can be found, a null - /// reference is being returned. - public static T TryFindParent(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(parentObject); - } - - /// - /// This method is an alternative to WPF's - /// method, which also - /// supports content elements. Keep in mind that for content element, - /// this method falls back to the logical tree of the element! - /// - /// The item to be processed. - /// The submitted item's parent, if available. Otherwise - /// null. - 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 - - /// - /// Analyzes both visual and logical tree in order to find all elements of a given - /// type that are descendants of the item. - /// - /// The type of the queried items. - /// 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. - /// All descendants of that match the requested type. - public static IEnumerable FindChildren(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(child)) - { - yield return descendant; - } - } - } - } - - - /// - /// This method is an alternative to WPF's - /// method, which also - /// supports content elements. Keep in mind that for content elements, - /// this method falls back to the logical tree of the element. - /// - /// The item to be processed. - /// The submitted item's child elements, if available. - public static IEnumerable 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 - - /// - /// Tries to locate a given item within the visual tree, - /// starting with the dependency object at a given position. - /// - /// The type of the element to be found - /// on the visual tree of the element at the given location. - /// The main element which is used to perform - /// hit testing. - /// The position to be evaluated on the origin. - /// ``0. - public static T TryFindFromPoint(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(element); - } - - #endregion - } -} diff --git a/MediaBrowser.UI.Controls/VirtualizingWrapPanel.cs b/MediaBrowser.UI.Controls/VirtualizingWrapPanel.cs deleted file mode 100644 index e9753ccea8..0000000000 --- a/MediaBrowser.UI.Controls/VirtualizingWrapPanel.cs +++ /dev/null @@ -1,735 +0,0 @@ -using System; -using System.Collections.Specialized; -using System.ComponentModel; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Controls.Primitives; -using System.Windows.Media; - -namespace MediaBrowser.UI.Controls -{ - /// - /// http://www.codeproject.com/Articles/75847/Virtualizing-WrapPanel - /// Positions child elements in sequential position from left to right, breaking content - /// to the next line at the edge of the containing box. Subsequent ordering happens - /// sequentially from top to bottom or from right to left, depending on the value of - /// the Orientation property. - /// - [DefaultProperty("Orientation")] - public class VirtualizingWrapPanel : VirtualizingPanel, IScrollInfo - { - /// - /// Identifies the ItemHeight dependency property. - /// - public static readonly DependencyProperty ItemHeightProperty = DependencyProperty.Register("ItemHeight", typeof(double), typeof(VirtualizingWrapPanel), new PropertyMetadata(100.0, new PropertyChangedCallback(VirtualizingWrapPanel.OnAppearancePropertyChanged))); - /// - /// Identifies the Orientation dependency property. - /// - public static readonly DependencyProperty OrientationProperty = DependencyProperty.Register("Orientation", typeof(Orientation), typeof(VirtualizingWrapPanel), new PropertyMetadata(Orientation.Horizontal, new PropertyChangedCallback(VirtualizingWrapPanel.OnAppearancePropertyChanged))); - /// - /// Identifies the ItemWidth dependency property. - /// - public static readonly DependencyProperty ItemWidthProperty = DependencyProperty.Register("ItemWidth", typeof(double), typeof(VirtualizingWrapPanel), new PropertyMetadata(100.0, new PropertyChangedCallback(VirtualizingWrapPanel.OnAppearancePropertyChanged))); - /// - /// Identifies the ScrollStep dependency property. - /// - public static readonly DependencyProperty ScrollStepProperty = DependencyProperty.Register("ScrollStep", typeof(double), typeof(VirtualizingWrapPanel), new PropertyMetadata(10.0, new PropertyChangedCallback(VirtualizingWrapPanel.OnAppearancePropertyChanged))); - private bool canHorizontallyScroll; - private bool canVerticallyScroll; - private Size contentExtent = new Size(0.0, 0.0); - private Point contentOffset = default(Point); - private ScrollViewer scrollOwner; - private Size viewport = new Size(0.0, 0.0); - private int previousItemCount; - /// - /// Gets or sets a value that specifies the height of all items that are - /// contained within a VirtualizingWrapPanel. This is a dependency property. - /// - public double ItemHeight - { - get - { - return (double)base.GetValue(VirtualizingWrapPanel.ItemHeightProperty); - } - set - { - base.SetValue(VirtualizingWrapPanel.ItemHeightProperty, value); - } - } - /// - /// Gets or sets a value that specifies the width of all items that are - /// contained within a VirtualizingWrapPanel. This is a dependency property. - /// - public double ItemWidth - { - get - { - return (double)base.GetValue(VirtualizingWrapPanel.ItemWidthProperty); - } - set - { - base.SetValue(VirtualizingWrapPanel.ItemWidthProperty, value); - } - } - /// - /// Gets or sets a value that specifies the dimension in which child - /// content is arranged. This is a dependency property. - /// - public Orientation Orientation - { - get - { - return (Orientation)base.GetValue(VirtualizingWrapPanel.OrientationProperty); - } - set - { - base.SetValue(VirtualizingWrapPanel.OrientationProperty, value); - } - } - /// - /// Gets or sets a value that indicates whether scrolling on the horizontal axis is possible. - /// - public bool CanHorizontallyScroll - { - get - { - return this.canHorizontallyScroll; - } - set - { - if (this.canHorizontallyScroll != value) - { - this.canHorizontallyScroll = value; - base.InvalidateMeasure(); - } - } - } - /// - /// Gets or sets a value that indicates whether scrolling on the vertical axis is possible. - /// - public bool CanVerticallyScroll - { - get - { - return this.canVerticallyScroll; - } - set - { - if (this.canVerticallyScroll != value) - { - this.canVerticallyScroll = value; - base.InvalidateMeasure(); - } - } - } - /// - /// Gets or sets a ScrollViewer element that controls scrolling behavior. - /// - public ScrollViewer ScrollOwner - { - get - { - return this.scrollOwner; - } - set - { - this.scrollOwner = value; - } - } - /// - /// Gets the vertical offset of the scrolled content. - /// - public double VerticalOffset - { - get - { - return this.contentOffset.Y; - } - } - /// - /// Gets the vertical size of the viewport for this content. - /// - public double ViewportHeight - { - get - { - return this.viewport.Height; - } - } - /// - /// Gets the horizontal size of the viewport for this content. - /// - public double ViewportWidth - { - get - { - return this.viewport.Width; - } - } - /// - /// Gets or sets a value for mouse wheel scroll step. - /// - public double ScrollStep - { - get - { - return (double)base.GetValue(VirtualizingWrapPanel.ScrollStepProperty); - } - set - { - base.SetValue(VirtualizingWrapPanel.ScrollStepProperty, value); - } - } - /// - /// Gets the vertical size of the extent. - /// - public double ExtentHeight - { - get - { - return this.contentExtent.Height; - } - } - /// - /// Gets the horizontal size of the extent. - /// - public double ExtentWidth - { - get - { - return this.contentExtent.Width; - } - } - /// - /// Gets the horizontal offset of the scrolled content. - /// - public double HorizontalOffset - { - get - { - return this.contentOffset.X; - } - } - /// - /// Scrolls down within content by one logical unit. - /// - public void LineDown() - { - this.SetVerticalOffset(this.VerticalOffset + this.ScrollStep); - } - /// - /// Scrolls left within content by one logical unit. - /// - public void LineLeft() - { - this.SetHorizontalOffset(this.HorizontalOffset - this.ScrollStep); - } - /// - /// Scrolls right within content by one logical unit. - /// - public void LineRight() - { - this.SetHorizontalOffset(this.HorizontalOffset + this.ScrollStep); - } - /// - /// Scrolls up within content by one logical unit. - /// - public void LineUp() - { - this.SetVerticalOffset(this.VerticalOffset - this.ScrollStep); - } - /// - /// Forces content to scroll until the coordinate space of a Visual object is visible. - /// - public Rect MakeVisible(Visual visual, Rect rectangle) - { - this.MakeVisible(visual as UIElement); - return rectangle; - } - /// - /// Scrolls down within content after a user clicks the wheel button on a mouse. - /// - public void MouseWheelDown() - { - this.SetVerticalOffset(this.VerticalOffset + this.ScrollStep); - } - /// - /// Scrolls left within content after a user clicks the wheel button on a mouse. - /// - public void MouseWheelLeft() - { - this.SetHorizontalOffset(this.HorizontalOffset - this.ScrollStep); - } - /// - /// Scrolls right within content after a user clicks the wheel button on a mouse. - /// - public void MouseWheelRight() - { - this.SetHorizontalOffset(this.HorizontalOffset + this.ScrollStep); - } - /// - /// Scrolls up within content after a user clicks the wheel button on a mouse. - /// - public void MouseWheelUp() - { - this.SetVerticalOffset(this.VerticalOffset - this.ScrollStep); - } - /// - /// Scrolls down within content by one page. - /// - public void PageDown() - { - this.SetVerticalOffset(this.VerticalOffset + this.ViewportHeight); - } - /// - /// Scrolls left within content by one page. - /// - public void PageLeft() - { - this.SetHorizontalOffset(this.HorizontalOffset - this.ViewportHeight); - } - /// - /// Scrolls right within content by one page. - /// - public void PageRight() - { - this.SetHorizontalOffset(this.HorizontalOffset + this.ViewportHeight); - } - /// - /// Scrolls up within content by one page. - /// - public void PageUp() - { - this.SetVerticalOffset(this.VerticalOffset - this.viewport.Height); - } - /// - /// Sets the amount of vertical offset. - /// - public void SetVerticalOffset(double offset) - { - if (offset < 0.0 || this.ViewportHeight >= this.ExtentHeight) - { - offset = 0.0; - } - else - { - if (offset + this.ViewportHeight >= this.ExtentHeight) - { - offset = this.ExtentHeight - this.ViewportHeight; - } - } - this.contentOffset.Y = offset; - if (this.ScrollOwner != null) - { - this.ScrollOwner.InvalidateScrollInfo(); - } - base.InvalidateMeasure(); - } - /// - /// Sets the amount of horizontal offset. - /// - public void SetHorizontalOffset(double offset) - { - if (offset < 0.0 || this.ViewportWidth >= this.ExtentWidth) - { - offset = 0.0; - } - else - { - if (offset + this.ViewportWidth >= this.ExtentWidth) - { - offset = this.ExtentWidth - this.ViewportWidth; - } - } - this.contentOffset.X = offset; - if (this.ScrollOwner != null) - { - this.ScrollOwner.InvalidateScrollInfo(); - } - base.InvalidateMeasure(); - } - /// - /// Note: Works only for vertical. - /// - internal void PageLast() - { - this.contentOffset.Y = this.ExtentHeight; - if (this.ScrollOwner != null) - { - this.ScrollOwner.InvalidateScrollInfo(); - } - base.InvalidateMeasure(); - } - /// - /// Note: Works only for vertical. - /// - internal void PageFirst() - { - this.contentOffset.Y = 0.0; - if (this.ScrollOwner != null) - { - this.ScrollOwner.InvalidateScrollInfo(); - } - base.InvalidateMeasure(); - } - /// - /// When items are removed, remove the corresponding UI if necessary. - /// - /// - /// - protected override void OnItemsChanged(object sender, ItemsChangedEventArgs args) - { - switch (args.Action) - { - case NotifyCollectionChangedAction.Remove: - case NotifyCollectionChangedAction.Replace: - case NotifyCollectionChangedAction.Move: - base.RemoveInternalChildRange(args.Position.Index, args.ItemUICount); - return; - case NotifyCollectionChangedAction.Reset: - { - ItemsControl itemsControl = ItemsControl.GetItemsOwner(this); - if (itemsControl != null) - { - if (this.previousItemCount != itemsControl.Items.Count) - { - if (this.Orientation == Orientation.Horizontal) - { - this.SetVerticalOffset(0.0); - } - else - { - this.SetHorizontalOffset(0.0); - } - } - this.previousItemCount = itemsControl.Items.Count; - } - return; - } - default: - return; - } - } - /// - /// Measure the children. - /// - /// The available size. - /// The desired size. - protected override Size MeasureOverride(Size availableSize) - { - this.InvalidateScrollInfo(availableSize); - int firstVisibleIndex; - int lastVisibleIndex; - if (this.Orientation == Orientation.Horizontal) - { - this.GetVerticalVisibleRange(out firstVisibleIndex, out lastVisibleIndex); - } - else - { - this.GetHorizontalVisibleRange(out firstVisibleIndex, out lastVisibleIndex); - } - UIElementCollection children = base.Children; - IItemContainerGenerator generator = base.ItemContainerGenerator; - if (generator != null) - { - GeneratorPosition startPos = generator.GeneratorPositionFromIndex(firstVisibleIndex); - int childIndex = (startPos.Offset == 0) ? startPos.Index : (startPos.Index + 1); - if (childIndex == -1) - { - this.RefreshOffset(); - } - using (generator.StartAt(startPos, GeneratorDirection.Forward, true)) - { - int itemIndex = firstVisibleIndex; - while (itemIndex <= lastVisibleIndex) - { - bool newlyRealized; - UIElement child = generator.GenerateNext(out newlyRealized) as UIElement; - if (newlyRealized) - { - if (childIndex >= children.Count) - { - base.AddInternalChild(child); - } - else - { - base.InsertInternalChild(childIndex, child); - } - generator.PrepareItemContainer(child); - } - if (child != null) - { - child.Measure(new Size(this.ItemWidth, this.ItemHeight)); - } - itemIndex++; - childIndex++; - } - } - this.CleanUpChildren(firstVisibleIndex, lastVisibleIndex); - } - if (IsCloseTo(availableSize.Height, double.PositiveInfinity) || IsCloseTo(availableSize.Width, double.PositiveInfinity)) - { - return base.MeasureOverride(availableSize); - } - - var itemsControl = ItemsControl.GetItemsOwner(this); - var numItems = itemsControl.Items.Count; - - var width = availableSize.Width; - var height = availableSize.Height; - - if (Orientation == Orientation.Vertical) - { - var numRows = Math.Floor(availableSize.Height / ItemHeight); - - height = numRows * ItemHeight; - - var requiredColumns = Math.Ceiling(numItems / numRows); - - width = Math.Min(requiredColumns * ItemWidth, width); - } - else - { - var numColumns = Math.Floor(availableSize.Width / ItemWidth); - - width = numColumns * ItemWidth; - - //if (numItems > 0 && numItems < numColumns) - //{ - // width = Math.Min(numColumns, numItems) * ItemWidth; - //} - - var requiredRows = Math.Ceiling(numItems / numColumns); - - height = Math.Min(requiredRows * ItemHeight, height); - } - - return new Size(width, height); - } - - /// - /// Arranges the children. - /// - /// The available size. - /// The used size. - protected override Size ArrangeOverride(Size finalSize) - { - bool isHorizontal = this.Orientation == Orientation.Horizontal; - this.InvalidateScrollInfo(finalSize); - int i = 0; - foreach (object item in base.Children) - { - this.ArrangeChild(isHorizontal, finalSize, i++, item as UIElement); - } - return finalSize; - } - private static void OnAppearancePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - UIElement panel = d as UIElement; - if (panel != null) - { - panel.InvalidateMeasure(); - } - } - private void MakeVisible(UIElement element) - { - ItemContainerGenerator generator = base.ItemContainerGenerator.GetItemContainerGeneratorForPanel(this); - if (element != null && generator != null) - { - for (int itemIndex = generator.IndexFromContainer(element); itemIndex == -1; itemIndex = generator.IndexFromContainer(element)) - { - element = element.ParentOfType(); - } - ScrollViewer scrollViewer = element.ParentOfType(); - if (scrollViewer != null) - { - GeneralTransform elementTransform = element.TransformToVisual(scrollViewer); - Rect elementRectangle = elementTransform.TransformBounds(new Rect(new Point(0.0, 0.0), element.RenderSize)); - - if (this.Orientation == Orientation.Horizontal) - { - var padding = ItemHeight / 3; - - if (elementRectangle.Bottom > this.ViewportHeight) - { - this.SetVerticalOffset(this.contentOffset.Y + elementRectangle.Bottom - this.ViewportHeight + padding); - return; - } - if (elementRectangle.Top < 0.0) - { - this.SetVerticalOffset(this.contentOffset.Y + elementRectangle.Top - padding); - return; - } - } - else - { - var padding = ItemWidth / 3; - - if (elementRectangle.Right > this.ViewportWidth) - { - this.SetHorizontalOffset(this.contentOffset.X + elementRectangle.Right - this.ViewportWidth + padding); - return; - } - if (elementRectangle.Left < 0.0) - { - this.SetHorizontalOffset(this.contentOffset.X + elementRectangle.Left - padding); - } - } - } - } - } - private void GetVerticalVisibleRange(out int firstVisibleItemIndex, out int lastVisibleItemIndex) - { - int childrenPerRow = this.GetVerticalChildrenCountPerRow(this.contentExtent); - firstVisibleItemIndex = (int)Math.Floor(this.VerticalOffset / this.ItemHeight) * childrenPerRow; - lastVisibleItemIndex = (int)Math.Ceiling((this.VerticalOffset + this.ViewportHeight) / this.ItemHeight) * childrenPerRow - 1; - this.AdjustVisibleRange(ref firstVisibleItemIndex, ref lastVisibleItemIndex); - } - private void GetHorizontalVisibleRange(out int firstVisibleItemIndex, out int lastVisibleItemIndex) - { - int childrenPerRow = this.GetHorizontalChildrenCountPerRow(this.contentExtent); - firstVisibleItemIndex = (int)Math.Floor(this.HorizontalOffset / this.ItemWidth) * childrenPerRow; - lastVisibleItemIndex = (int)Math.Ceiling((this.HorizontalOffset + this.ViewportWidth) / this.ItemWidth) * childrenPerRow - 1; - this.AdjustVisibleRange(ref firstVisibleItemIndex, ref lastVisibleItemIndex); - } - private void AdjustVisibleRange(ref int firstVisibleItemIndex, ref int lastVisibleItemIndex) - { - firstVisibleItemIndex--; - lastVisibleItemIndex++; - ItemsControl itemsControl = ItemsControl.GetItemsOwner(this); - if (itemsControl != null) - { - if (firstVisibleItemIndex < 0) - { - firstVisibleItemIndex = 0; - } - if (lastVisibleItemIndex >= itemsControl.Items.Count) - { - lastVisibleItemIndex = itemsControl.Items.Count - 1; - } - } - } - private void CleanUpChildren(int minIndex, int maxIndex) - { - UIElementCollection children = base.Children; - IItemContainerGenerator generator = base.ItemContainerGenerator; - for (int i = children.Count - 1; i >= 0; i--) - { - GeneratorPosition pos = new GeneratorPosition(i, 0); - int itemIndex = generator.IndexFromGeneratorPosition(pos); - if (itemIndex < minIndex || itemIndex > maxIndex) - { - generator.Remove(pos, 1); - base.RemoveInternalChildRange(i, 1); - } - } - } - private void ArrangeChild(bool isHorizontal, Size finalSize, int index, UIElement child) - { - if (child == null) - { - return; - } - int count = isHorizontal ? this.GetVerticalChildrenCountPerRow(finalSize) : this.GetHorizontalChildrenCountPerRow(finalSize); - int itemIndex = base.ItemContainerGenerator.IndexFromGeneratorPosition(new GeneratorPosition(index, 0)); - int row = isHorizontal ? (itemIndex / count) : (itemIndex % count); - int column = isHorizontal ? (itemIndex % count) : (itemIndex / count); - Rect rect = new Rect((double)column * this.ItemWidth, (double)row * this.ItemHeight, this.ItemWidth, this.ItemHeight); - if (isHorizontal) - { - rect.Y -= this.VerticalOffset; - } - else - { - rect.X -= this.HorizontalOffset; - } - child.Arrange(rect); - } - private void InvalidateScrollInfo(Size availableSize) - { - ItemsControl ownerItemsControl = ItemsControl.GetItemsOwner(this); - if (ownerItemsControl != null) - { - Size extent = this.GetExtent(availableSize, ownerItemsControl.Items.Count); - if (extent != this.contentExtent) - { - this.contentExtent = extent; - this.RefreshOffset(); - } - if (availableSize != this.viewport) - { - this.viewport = availableSize; - this.InvalidateScrollOwner(); - } - } - } - private void RefreshOffset() - { - if (this.Orientation == Orientation.Horizontal) - { - this.SetVerticalOffset(this.VerticalOffset); - return; - } - this.SetHorizontalOffset(this.HorizontalOffset); - } - private void InvalidateScrollOwner() - { - if (this.ScrollOwner != null) - { - this.ScrollOwner.InvalidateScrollInfo(); - } - } - private Size GetExtent(Size availableSize, int itemCount) - { - if (this.Orientation == Orientation.Horizontal) - { - int childrenPerRow = this.GetVerticalChildrenCountPerRow(availableSize); - return new Size((double)childrenPerRow * this.ItemWidth, this.ItemHeight * Math.Ceiling((double)itemCount / (double)childrenPerRow)); - } - int childrenPerRow2 = this.GetHorizontalChildrenCountPerRow(availableSize); - return new Size(this.ItemWidth * Math.Ceiling((double)itemCount / (double)childrenPerRow2), (double)childrenPerRow2 * this.ItemHeight); - } - private int GetVerticalChildrenCountPerRow(Size availableSize) - { - int childrenCountPerRow; - if (availableSize.Width == double.PositiveInfinity) - { - childrenCountPerRow = base.Children.Count; - } - else - { - childrenCountPerRow = Math.Max(1, (int)Math.Floor(availableSize.Width / this.ItemWidth)); - } - return childrenCountPerRow; - } - private int GetHorizontalChildrenCountPerRow(Size availableSize) - { - int childrenCountPerRow; - if (availableSize.Height == double.PositiveInfinity) - { - childrenCountPerRow = base.Children.Count; - } - else - { - childrenCountPerRow = Math.Max(1, (int)Math.Floor(availableSize.Height / this.ItemHeight)); - } - return childrenCountPerRow; - } - - private static bool IsCloseTo(double value1, double value2) - { - return AreClose(value1, value2); - } - - private static bool AreClose(double value1, double value2) - { - if (value1 == value2) - { - return true; - } - double num = (Math.Abs(value1) + Math.Abs(value2) + 10.0) * 2.2204460492503131E-16; - double num2 = value1 - value2; - return -num < num2 && num > num2; - } - } -} \ No newline at end of file diff --git a/MediaBrowser.UI.Uninstall/App.config b/MediaBrowser.UI.Uninstall/App.config deleted file mode 100644 index 8e15646352..0000000000 --- a/MediaBrowser.UI.Uninstall/App.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/MediaBrowser.UI.Uninstall/Globals.cs b/MediaBrowser.UI.Uninstall/Globals.cs deleted file mode 100644 index aa58e09840..0000000000 --- a/MediaBrowser.UI.Uninstall/Globals.cs +++ /dev/null @@ -1,24 +0,0 @@ - -namespace MediaBrowser.UI.Uninstall -{ - /// - /// Class Globals - /// - public static class Globals - { - /// - /// The product name - /// - public static string ProductName = "Media Browser Theater"; - - /// - /// The suite name - /// - public static string SuiteName = "Media Browser 3"; - - /// - /// The publisher name - /// - public static string PublisherName = "Media Browser Team"; - } -} diff --git a/MediaBrowser.UI.Uninstall/MediaBrowser.UI.Uninstall.csproj b/MediaBrowser.UI.Uninstall/MediaBrowser.UI.Uninstall.csproj deleted file mode 100644 index b54eabc489..0000000000 --- a/MediaBrowser.UI.Uninstall/MediaBrowser.UI.Uninstall.csproj +++ /dev/null @@ -1,68 +0,0 @@ - - - - - Debug - AnyCPU - {E4BE0659-4084-407B-B8A8-67802331CC9E} - Exe - Properties - MediaBrowser.UI.Uninstall - MediaBrowser.UI.Uninstall - v4.5 - 512 - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - true - - - - - - - - - - - - - - - - - - - - - {cc96bf3e-0bda-4809-bc4b-bb6d418f4a84} - MediaBrowser.ClickOnce - - - - - \ No newline at end of file diff --git a/MediaBrowser.UI.Uninstall/Program.cs b/MediaBrowser.UI.Uninstall/Program.cs deleted file mode 100644 index 14c3d3abfc..0000000000 --- a/MediaBrowser.UI.Uninstall/Program.cs +++ /dev/null @@ -1,30 +0,0 @@ -using MediaBrowser.ClickOnce; -using System; -using System.IO; - -namespace MediaBrowser.UI.Uninstall -{ - /// - /// Class Program - /// - class Program - { - /// - /// Defines the entry point of the application. - /// - /// The args. - static void Main(string[] args) - { - new ClickOnceHelper(Globals.PublisherName, Globals.ProductName, Globals.SuiteName).Uninstall(); - - // Delete all files from publisher folder and folder itself on uninstall - - var publisherFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), Globals.PublisherName); - - if (Directory.Exists(publisherFolder)) - { - Directory.Delete(publisherFolder, true); - } - } - } -} diff --git a/MediaBrowser.UI.Uninstall/Properties/AssemblyInfo.cs b/MediaBrowser.UI.Uninstall/Properties/AssemblyInfo.cs deleted file mode 100644 index 258e5d5d66..0000000000 --- a/MediaBrowser.UI.Uninstall/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("MediaBrowser.UI.Uninstall")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("MediaBrowser.UI.Uninstall")] -[assembly: AssemblyCopyright("Copyright © 2013")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("a01e166b-048e-4888-8075-0daf64480c79")] - -// 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/MediaBrowser.UI.sln b/MediaBrowser.UI.sln deleted file mode 100644 index 8b79d2c6bc..0000000000 --- a/MediaBrowser.UI.sln +++ /dev/null @@ -1,150 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2012 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.UI", "MediaBrowser.UI\MediaBrowser.UI.csproj", "{B5ECE1FB-618E-420B-9A99-8E972D76920A}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Common", "MediaBrowser.Common\MediaBrowser.Common.csproj", "{9142EEFA-7570-41E1-BFCC-468BB571AF2F}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Model", "MediaBrowser.Model\MediaBrowser.Model.csproj", "{7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.ApiInteraction", "MediaBrowser.ApiInteraction\MediaBrowser.ApiInteraction.csproj", "{921C0F64-FDA7-4E9F-9E73-0CB0EEDB2422}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Plugins.DefaultTheme", "MediaBrowser.Plugins.DefaultTheme\MediaBrowser.Plugins.DefaultTheme.csproj", "{6E892999-711D-4E24-8BAC-DACF5BFA783A}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.UI.Uninstall", "MediaBrowser.UI.Uninstall\MediaBrowser.UI.Uninstall.csproj", "{E4BE0659-4084-407B-B8A8-67802331CC9E}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.IsoMounter", "MediaBrowser.IsoMounter\MediaBrowser.IsoMounter.csproj", "{5356AE30-6A6E-4A64-81E3-F76C50595E64}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.UI.Controls", "MediaBrowser.UI.Controls\MediaBrowser.UI.Controls.csproj", "{1ADFE460-FD95-46FA-8871-CCCB4B62E2E8}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Logging.NLog", "MediaBrowser.Logging.NLog\MediaBrowser.Logging.NLog.csproj", "{67310740-0EC4-4DC2-9921-33DF38B20167}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.ClickOnce", "MediaBrowser.ClickOnce\MediaBrowser.ClickOnce.csproj", "{CC96BF3E-0BDA-4809-BC4B-BB6D418F4A84}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|Mixed Platforms = Debug|Mixed Platforms - Debug|x86 = Debug|x86 - Release|Any CPU = Release|Any CPU - Release|Mixed Platforms = Release|Mixed Platforms - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {B5ECE1FB-618E-420B-9A99-8E972D76920A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B5ECE1FB-618E-420B-9A99-8E972D76920A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B5ECE1FB-618E-420B-9A99-8E972D76920A}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 - {B5ECE1FB-618E-420B-9A99-8E972D76920A}.Debug|Mixed Platforms.Build.0 = Debug|x86 - {B5ECE1FB-618E-420B-9A99-8E972D76920A}.Debug|x86.ActiveCfg = Debug|Any CPU - {B5ECE1FB-618E-420B-9A99-8E972D76920A}.Debug|x86.Build.0 = Debug|Any CPU - {B5ECE1FB-618E-420B-9A99-8E972D76920A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B5ECE1FB-618E-420B-9A99-8E972D76920A}.Release|Any CPU.Build.0 = Release|Any CPU - {B5ECE1FB-618E-420B-9A99-8E972D76920A}.Release|Mixed Platforms.ActiveCfg = Release|x86 - {B5ECE1FB-618E-420B-9A99-8E972D76920A}.Release|Mixed Platforms.Build.0 = Release|x86 - {B5ECE1FB-618E-420B-9A99-8E972D76920A}.Release|x86.ActiveCfg = Release|Any CPU - {B5ECE1FB-618E-420B-9A99-8E972D76920A}.Release|x86.Build.0 = Release|Any CPU - {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Debug|x86.ActiveCfg = Debug|Any CPU - {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Debug|x86.Build.0 = Debug|Any CPU - {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release|Any CPU.Build.0 = Release|Any CPU - {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release|x86.ActiveCfg = Release|Any CPU - {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release|x86.Build.0 = Release|Any CPU - {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Debug|x86.ActiveCfg = Debug|Any CPU - {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Debug|x86.Build.0 = Debug|Any CPU - {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Release|Any CPU.Build.0 = Release|Any CPU - {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Release|x86.ActiveCfg = Release|Any CPU - {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Release|x86.Build.0 = Release|Any CPU - {921C0F64-FDA7-4E9F-9E73-0CB0EEDB2422}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {921C0F64-FDA7-4E9F-9E73-0CB0EEDB2422}.Debug|Any CPU.Build.0 = Debug|Any CPU - {921C0F64-FDA7-4E9F-9E73-0CB0EEDB2422}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {921C0F64-FDA7-4E9F-9E73-0CB0EEDB2422}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {921C0F64-FDA7-4E9F-9E73-0CB0EEDB2422}.Debug|x86.ActiveCfg = Debug|Any CPU - {921C0F64-FDA7-4E9F-9E73-0CB0EEDB2422}.Debug|x86.Build.0 = Debug|Any CPU - {921C0F64-FDA7-4E9F-9E73-0CB0EEDB2422}.Release|Any CPU.ActiveCfg = Release|Any CPU - {921C0F64-FDA7-4E9F-9E73-0CB0EEDB2422}.Release|Any CPU.Build.0 = Release|Any CPU - {921C0F64-FDA7-4E9F-9E73-0CB0EEDB2422}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {921C0F64-FDA7-4E9F-9E73-0CB0EEDB2422}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {921C0F64-FDA7-4E9F-9E73-0CB0EEDB2422}.Release|x86.ActiveCfg = Release|Any CPU - {921C0F64-FDA7-4E9F-9E73-0CB0EEDB2422}.Release|x86.Build.0 = Release|Any CPU - {6E892999-711D-4E24-8BAC-DACF5BFA783A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6E892999-711D-4E24-8BAC-DACF5BFA783A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6E892999-711D-4E24-8BAC-DACF5BFA783A}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {6E892999-711D-4E24-8BAC-DACF5BFA783A}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {6E892999-711D-4E24-8BAC-DACF5BFA783A}.Debug|x86.ActiveCfg = Debug|Any CPU - {6E892999-711D-4E24-8BAC-DACF5BFA783A}.Debug|x86.Build.0 = Debug|Any CPU - {6E892999-711D-4E24-8BAC-DACF5BFA783A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6E892999-711D-4E24-8BAC-DACF5BFA783A}.Release|Any CPU.Build.0 = Release|Any CPU - {6E892999-711D-4E24-8BAC-DACF5BFA783A}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {6E892999-711D-4E24-8BAC-DACF5BFA783A}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {6E892999-711D-4E24-8BAC-DACF5BFA783A}.Release|x86.ActiveCfg = Release|Any CPU - {6E892999-711D-4E24-8BAC-DACF5BFA783A}.Release|x86.Build.0 = Release|Any CPU - {E4BE0659-4084-407B-B8A8-67802331CC9E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E4BE0659-4084-407B-B8A8-67802331CC9E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E4BE0659-4084-407B-B8A8-67802331CC9E}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {E4BE0659-4084-407B-B8A8-67802331CC9E}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {E4BE0659-4084-407B-B8A8-67802331CC9E}.Debug|x86.ActiveCfg = Debug|Any CPU - {E4BE0659-4084-407B-B8A8-67802331CC9E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E4BE0659-4084-407B-B8A8-67802331CC9E}.Release|Any CPU.Build.0 = Release|Any CPU - {E4BE0659-4084-407B-B8A8-67802331CC9E}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {E4BE0659-4084-407B-B8A8-67802331CC9E}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {E4BE0659-4084-407B-B8A8-67802331CC9E}.Release|x86.ActiveCfg = Release|Any CPU - {5356AE30-6A6E-4A64-81E3-F76C50595E64}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5356AE30-6A6E-4A64-81E3-F76C50595E64}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5356AE30-6A6E-4A64-81E3-F76C50595E64}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 - {5356AE30-6A6E-4A64-81E3-F76C50595E64}.Debug|Mixed Platforms.Build.0 = Debug|x86 - {5356AE30-6A6E-4A64-81E3-F76C50595E64}.Debug|x86.ActiveCfg = Debug|x86 - {5356AE30-6A6E-4A64-81E3-F76C50595E64}.Debug|x86.Build.0 = Debug|x86 - {5356AE30-6A6E-4A64-81E3-F76C50595E64}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5356AE30-6A6E-4A64-81E3-F76C50595E64}.Release|Any CPU.Build.0 = Release|Any CPU - {5356AE30-6A6E-4A64-81E3-F76C50595E64}.Release|Mixed Platforms.ActiveCfg = Release|x86 - {5356AE30-6A6E-4A64-81E3-F76C50595E64}.Release|Mixed Platforms.Build.0 = Release|x86 - {5356AE30-6A6E-4A64-81E3-F76C50595E64}.Release|x86.ActiveCfg = Release|x86 - {5356AE30-6A6E-4A64-81E3-F76C50595E64}.Release|x86.Build.0 = Release|x86 - {1ADFE460-FD95-46FA-8871-CCCB4B62E2E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1ADFE460-FD95-46FA-8871-CCCB4B62E2E8}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1ADFE460-FD95-46FA-8871-CCCB4B62E2E8}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {1ADFE460-FD95-46FA-8871-CCCB4B62E2E8}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {1ADFE460-FD95-46FA-8871-CCCB4B62E2E8}.Debug|x86.ActiveCfg = Debug|Any CPU - {1ADFE460-FD95-46FA-8871-CCCB4B62E2E8}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1ADFE460-FD95-46FA-8871-CCCB4B62E2E8}.Release|Any CPU.Build.0 = Release|Any CPU - {1ADFE460-FD95-46FA-8871-CCCB4B62E2E8}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {1ADFE460-FD95-46FA-8871-CCCB4B62E2E8}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {1ADFE460-FD95-46FA-8871-CCCB4B62E2E8}.Release|x86.ActiveCfg = Release|Any CPU - {67310740-0EC4-4DC2-9921-33DF38B20167}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {67310740-0EC4-4DC2-9921-33DF38B20167}.Debug|Any CPU.Build.0 = Debug|Any CPU - {67310740-0EC4-4DC2-9921-33DF38B20167}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {67310740-0EC4-4DC2-9921-33DF38B20167}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {67310740-0EC4-4DC2-9921-33DF38B20167}.Debug|x86.ActiveCfg = Debug|Any CPU - {67310740-0EC4-4DC2-9921-33DF38B20167}.Release|Any CPU.ActiveCfg = Release|Any CPU - {67310740-0EC4-4DC2-9921-33DF38B20167}.Release|Any CPU.Build.0 = Release|Any CPU - {67310740-0EC4-4DC2-9921-33DF38B20167}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {67310740-0EC4-4DC2-9921-33DF38B20167}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {67310740-0EC4-4DC2-9921-33DF38B20167}.Release|x86.ActiveCfg = Release|Any CPU - {CC96BF3E-0BDA-4809-BC4B-BB6D418F4A84}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {CC96BF3E-0BDA-4809-BC4B-BB6D418F4A84}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CC96BF3E-0BDA-4809-BC4B-BB6D418F4A84}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {CC96BF3E-0BDA-4809-BC4B-BB6D418F4A84}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {CC96BF3E-0BDA-4809-BC4B-BB6D418F4A84}.Debug|x86.ActiveCfg = Debug|Any CPU - {CC96BF3E-0BDA-4809-BC4B-BB6D418F4A84}.Release|Any CPU.ActiveCfg = Release|Any CPU - {CC96BF3E-0BDA-4809-BC4B-BB6D418F4A84}.Release|Any CPU.Build.0 = Release|Any CPU - {CC96BF3E-0BDA-4809-BC4B-BB6D418F4A84}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {CC96BF3E-0BDA-4809-BC4B-BB6D418F4A84}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {CC96BF3E-0BDA-4809-BC4B-BB6D418F4A84}.Release|x86.ActiveCfg = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/MediaBrowser.UI/App.config b/MediaBrowser.UI/App.config deleted file mode 100644 index 72c2c8077e..0000000000 --- a/MediaBrowser.UI/App.config +++ /dev/null @@ -1,28 +0,0 @@ - - - -
- - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/MediaBrowser.UI/App.xaml b/MediaBrowser.UI/App.xaml deleted file mode 100644 index d8d7a80372..0000000000 --- a/MediaBrowser.UI/App.xaml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/MediaBrowser.UI/App.xaml.cs b/MediaBrowser.UI/App.xaml.cs deleted file mode 100644 index bcaa0529e6..0000000000 --- a/MediaBrowser.UI/App.xaml.cs +++ /dev/null @@ -1,1098 +0,0 @@ -using MediaBrowser.ApiInteraction; -using MediaBrowser.ClickOnce; -using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.IO; -using MediaBrowser.Common.Kernel; -using MediaBrowser.IsoMounter; -using MediaBrowser.Logging.Nlog; -using MediaBrowser.Model.Configuration; -using MediaBrowser.Model.Dto; -using MediaBrowser.Model.Logging; -using MediaBrowser.Model.Net; -using MediaBrowser.Model.Updates; -using MediaBrowser.Model.Weather; -using MediaBrowser.UI.Controller; -using MediaBrowser.UI.Controls; -using MediaBrowser.UI.Pages; -using MediaBrowser.UI.Uninstall; -using Microsoft.Win32; -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.IO; -using System.Linq; -using System.Net.Cache; -using System.Threading; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Media; -using System.Windows.Media.Imaging; - -namespace MediaBrowser.UI -{ - /// - /// Interaction logic for App.xaml - /// - public partial class App : Application, IApplicationHost - { - /// - /// Gets or sets a value indicating whether [last run at startup value]. - /// - /// null if [last run at startup value] contains no value, true if [last run at startup value]; otherwise, false. - private bool? LastRunAtStartupValue { get; set; } - - /// - /// Gets or sets the clock timer. - /// - /// The clock timer. - private Timer ClockTimer { get; set; } - /// - /// Gets or sets the server configuration timer. - /// - /// The server configuration timer. - private Timer ServerConfigurationTimer { get; set; } - - /// - /// The single instance mutex - /// - private Mutex SingleInstanceMutex; - - /// - /// Gets or sets the kernel. - /// - /// The kernel. - protected IKernel Kernel { get; set; } - - /// - /// Gets or sets the logger. - /// - /// The logger. - protected ILogger Logger { get; set; } - - /// - /// Gets or sets the log file path. - /// - /// The log file path. - public string LogFilePath { get; private set; } - - /// - /// Occurs when [property changed]. - /// - public event PropertyChangedEventHandler PropertyChanged; - - /// - /// Gets the name of the product. - /// - /// The name of the product. - protected string ProductName - { - get { return Globals.ProductName; } - } - - /// - /// Gets the name of the publisher. - /// - /// The name of the publisher. - protected string PublisherName - { - get { return Globals.PublisherName; } - } - - /// - /// Gets the name of the suite. - /// - /// The name of the suite. - protected string SuiteName - { - get { return Globals.SuiteName; } - } - - /// - /// Gets the name of the uninstaller file. - /// - /// The name of the uninstaller file. - protected string UninstallerFileName - { - get { return "MediaBrowser.UI.Uninstall.exe"; } - } - - /// - /// The container - /// - private SimpleInjector.Container _container = new SimpleInjector.Container(); - - /// - /// Gets or sets the iso manager. - /// - /// The iso manager. - private IIsoManager IsoManager { get; set; } - - /// - /// Gets the instance. - /// - /// The instance. - public static App Instance - { - get - { - return Current as App; - } - } - - /// - /// Gets the API client. - /// - /// The API client. - public ApiClient ApiClient - { - get { return UIKernel.Instance.ApiClient; } - } - - /// - /// Gets the application window. - /// - /// The application window. - public MainWindow ApplicationWindow { get; private set; } - - /// - /// Gets the hidden window. - /// - /// The hidden window. - public HiddenWindow HiddenWindow { get; private set; } - - /// - /// The _current user - /// - private UserDto _currentUser; - /// - /// Gets or sets the current user. - /// - /// The current user. - public UserDto CurrentUser - { - get - { - return _currentUser; - } - set - { - _currentUser = value; - - if (UIKernel.Instance.ApiClient != null) - { - if (value == null) - { - UIKernel.Instance.ApiClient.CurrentUserId = null; - } - else - { - UIKernel.Instance.ApiClient.CurrentUserId = value.Id; - } - } - - OnPropertyChanged("CurrentUser"); - } - } - - /// - /// The _server configuration - /// - private ServerConfiguration _serverConfiguration; - /// - /// Gets or sets the server configuration. - /// - /// The server configuration. - public ServerConfiguration ServerConfiguration - { - get - { - return _serverConfiguration; - } - set - { - _serverConfiguration = value; - OnPropertyChanged("ServerConfiguration"); - } - } - - /// - /// The _current time - /// - private DateTime _currentTime = DateTime.Now; - /// - /// Gets the current time. - /// - /// The current time. - public DateTime CurrentTime - { - get - { - return _currentTime; - } - private set - { - _currentTime = value; - OnPropertyChanged("CurrentTime"); - } - } - - /// - /// The _current weather - /// - private WeatherInfo _currentWeather; - /// - /// Gets the current weather. - /// - /// The current weather. - public WeatherInfo CurrentWeather - { - get - { - return _currentWeather; - } - private set - { - _currentWeather = value; - OnPropertyChanged("CurrentWeather"); - } - } - - /// - /// The _current theme - /// - private BaseTheme _currentTheme; - /// - /// Gets the current theme. - /// - /// The current theme. - public BaseTheme CurrentTheme - { - get - { - return _currentTheme; - } - private set - { - _currentTheme = value; - OnPropertyChanged("CurrentTheme"); - } - } - - /// - /// Defines the entry point of the application. - /// - [STAThread] - public static void Main() - { - var application = new App(new NLogger("App")); - application.InitializeComponent(); - - application.Run(); - } - - /// - /// Initializes a new instance of the class. - /// - /// The logger. - public App(ILogger logger) - { - Logger = logger; - - InitializeComponent(); - } - - /// - /// Instantiates the main window. - /// - /// Window. - protected Window InstantiateMainWindow() - { - HiddenWindow = new HiddenWindow { }; - - return HiddenWindow; - } - - /// - /// Shows the application window. - /// - private void ShowApplicationWindow() - { - var win = new MainWindow(Logger); - - var config = UIKernel.Instance.Configuration; - - // Restore window position/size - if (config.WindowState.HasValue) - { - // Set window state - win.WindowState = config.WindowState.Value; - - // Set position if not maximized - if (config.WindowState.Value != WindowState.Maximized) - { - double left = 0; - double top = 0; - - // Set left - if (config.WindowLeft.HasValue) - { - win.WindowStartupLocation = WindowStartupLocation.Manual; - win.Left = left = Math.Max(config.WindowLeft.Value, 0); - } - - // Set top - if (config.WindowTop.HasValue) - { - win.WindowStartupLocation = WindowStartupLocation.Manual; - win.Top = top = Math.Max(config.WindowTop.Value, 0); - } - - // Set width - if (config.WindowWidth.HasValue) - { - win.Width = Math.Min(config.WindowWidth.Value, SystemParameters.VirtualScreenWidth - left); - } - - // Set height - if (config.WindowHeight.HasValue) - { - win.Height = Math.Min(config.WindowHeight.Value, SystemParameters.VirtualScreenHeight - top); - } - } - } - - win.LocationChanged += ApplicationWindow_LocationChanged; - win.StateChanged += ApplicationWindow_LocationChanged; - win.SizeChanged += ApplicationWindow_LocationChanged; - - ApplicationWindow = win; - - ApplicationWindow.Show(); - - ApplicationWindow.Owner = HiddenWindow; - - SyncHiddenWindowLocation(); - } - - /// - /// Handles the LocationChanged event of the ApplicationWindow control. - /// - /// The source of the event. - /// The instance containing the event data. - void ApplicationWindow_LocationChanged(object sender, EventArgs e) - { - SyncHiddenWindowLocation(); - } - - /// - /// Syncs the hidden window location. - /// - public void SyncHiddenWindowLocation() - { - HiddenWindow.Width = ApplicationWindow.Width; - HiddenWindow.Height = ApplicationWindow.Height; - HiddenWindow.Top = ApplicationWindow.Top; - HiddenWindow.Left = ApplicationWindow.Left; - HiddenWindow.WindowState = ApplicationWindow.WindowState; - - ApplicationWindow.Activate(); - } - - /// - /// Loads the kernel. - /// - protected async void LoadKernel() - { - // Without this the app will shutdown after the splash screen closes - ShutdownMode = ShutdownMode.OnExplicitShutdown; - - RegisterResources(); - - Kernel = new UIKernel(this, Logger); - - try - { - var now = DateTime.UtcNow; - - await Kernel.Init(); - - Logger.Info("Kernel.Init completed in {0} seconds.", (DateTime.UtcNow - now).TotalSeconds); - - ShutdownMode = System.Windows.ShutdownMode.OnLastWindowClose; - - OnKernelLoaded(); - - InstantiateMainWindow().Show(); - - ShowApplicationWindow(); - - await ApplicationWindow.LoadInitialUI().ConfigureAwait(false); - } - catch (Exception ex) - { - Logger.ErrorException("Error launching application", ex); - - MessageBox.Show("There was an error launching Media Browser: " + ex.Message); - - // Shutdown the app with an error code - Shutdown(1); - } - } - - /// - /// Called when [kernel loaded]. - /// - /// Task. - protected void OnKernelLoaded() - { - Kernel.ConfigurationUpdated += Kernel_ConfigurationUpdated; - - ConfigureClickOnceStartup(); - - PropertyChanged += AppPropertyChanged; - - // Update every 10 seconds - ClockTimer = new Timer(ClockTimerCallback, null, 0, 10000); - - // Update every 30 minutes - ServerConfigurationTimer = new Timer(ServerConfigurationTimerCallback, null, 0, 1800000); - - CurrentTheme = UIKernel.Instance.Themes.First(); - - foreach (var resource in CurrentTheme.GetGlobalResources()) - { - Resources.MergedDictionaries.Add(resource); - } - } - - /// - /// Raises the event. - /// - /// A that contains the event data. - protected override void OnStartup(StartupEventArgs e) - { - bool createdNew; - SingleInstanceMutex = new Mutex(true, @"Local\" + GetType().Assembly.GetName().Name, out createdNew); - if (!createdNew) - { - SingleInstanceMutex = null; - Shutdown(); - return; - } - - AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; - LoadKernel(); - - SystemEvents.SessionEnding += SystemEvents_SessionEnding; - } - - /// - /// Handles the UnhandledException event of the CurrentDomain control. - /// - /// The source of the event. - /// The instance containing the event data. - void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) - { - var exception = (Exception)e.ExceptionObject; - - Logger.ErrorException("UnhandledException", exception); - - MessageBox.Show("Unhandled exception: " + exception.Message); - } - - /// - /// Called when [property changed]. - /// - /// The info. - public void OnPropertyChanged(String info) - { - if (PropertyChanged != null) - { - try - { - PropertyChanged(this, new PropertyChangedEventArgs(info)); - } - catch (Exception ex) - { - Logger.ErrorException("Error in event handler", ex); - } - } - } - - /// - /// Handles the SessionEnding event of the SystemEvents control. - /// - /// The source of the event. - /// The instance containing the event data. - void SystemEvents_SessionEnding(object sender, SessionEndingEventArgs e) - { - // Try to shut down gracefully - Shutdown(); - } - - /// - /// Raises the event. - /// - /// An that contains the event data. - protected override void OnExit(ExitEventArgs e) - { - var win = ApplicationWindow; - - if (win != null) - { - // Save window position - var config = UIKernel.Instance.Configuration; - config.WindowState = win.WindowState; - config.WindowTop = win.Top; - config.WindowLeft = win.Left; - config.WindowWidth = win.Width; - config.WindowHeight = win.Height; - UIKernel.Instance.SaveConfiguration(); - } - - ReleaseMutex(); - - base.OnExit(e); - - Kernel.Dispose(); - } - - /// - /// Releases the mutex. - /// - private void ReleaseMutex() - { - if (SingleInstanceMutex == null) - { - return; - } - - SingleInstanceMutex.ReleaseMutex(); - SingleInstanceMutex.Close(); - SingleInstanceMutex.Dispose(); - SingleInstanceMutex = null; - } - - /// - /// Apps the property changed. - /// - /// The sender. - /// The instance containing the event data. - async void AppPropertyChanged(object sender, PropertyChangedEventArgs e) - { - if (e.PropertyName.Equals("ServerConfiguration")) - { - if (string.IsNullOrEmpty(ServerConfiguration.WeatherLocation)) - { - CurrentWeather = null; - } - else - { - try - { - CurrentWeather = await ApiClient.GetWeatherInfoAsync(ServerConfiguration.WeatherLocation); - } - catch (HttpException ex) - { - Logger.ErrorException("Error downloading weather information", ex); - } - } - } - } - - /// - /// Clocks the timer callback. - /// - /// The state info. - private void ClockTimerCallback(object stateInfo) - { - CurrentTime = DateTime.Now; - } - - /// - /// Servers the configuration timer callback. - /// - /// The state info. - private async void ServerConfigurationTimerCallback(object stateInfo) - { - try - { - var b = Kernel; - //ServerConfiguration = await ApiClient.GetServerConfigurationAsync(); - } - catch (HttpException ex) - { - Logger.ErrorException("Error refreshing server configuration", ex); - } - } - - /// - /// Logouts the user. - /// - /// Task. - public async Task LogoutUser() - { - CurrentUser = null; - - await Dispatcher.InvokeAsync(() => Navigate(CurrentTheme.GetLoginPage())); - } - - /// - /// Navigates the specified page. - /// - /// The page. - public void Navigate(Page page) - { - _remoteImageCache = new FileSystemRepository(UIKernel.Instance.ApplicationPaths.RemoteImageCachePath); - - ApplicationWindow.Navigate(page); - } - - /// - /// Navigates to settings page. - /// - public void NavigateToSettingsPage() - { - Navigate(new SettingsPage()); - } - - /// - /// Navigates to internal player page. - /// - public void NavigateToInternalPlayerPage() - { - Navigate(CurrentTheme.GetInternalPlayerPage()); - } - - /// - /// Navigates to image viewer. - /// - /// The image URL. - /// The caption. - public void OpenImageViewer(Uri imageUrl, string caption) - { - var tuple = new Tuple(imageUrl, caption); - - OpenImageViewer(new[] { tuple }); - } - - /// - /// Navigates to image viewer. - /// - /// The images. - public void OpenImageViewer(IEnumerable> images) - { - new ImageViewerWindow(images).ShowModal(ApplicationWindow); - } - - /// - /// Navigates to item. - /// - /// The item. - public void NavigateToItem(BaseItemDto item) - { - if (item.IsRoot.HasValue && item.IsRoot.Value) - { - NavigateToHomePage(); - } - else if (item.IsFolder) - { - Navigate(CurrentTheme.GetListPage(item)); - } - else - { - Navigate(CurrentTheme.GetDetailPage(item)); - } - } - - /// - /// Displays the weather. - /// - public void DisplayWeather() - { - CurrentTheme.DisplayWeather(); - } - - /// - /// Navigates to home page. - /// - public void NavigateToHomePage() - { - Navigate(CurrentTheme.GetHomePage()); - } - - /// - /// Shows a notification message that will disappear on it's own - /// - /// The text. - /// The caption. - /// The icon. - public void ShowNotificationMessage(string text, string caption = null, MessageBoxIcon icon = MessageBoxIcon.None) - { - ApplicationWindow.ShowModalMessage(text, caption: caption, icon: icon); - } - - /// - /// Shows a notification message that will disappear on it's own - /// - /// The text. - /// The caption. - /// The icon. - public void ShowNotificationMessage(UIElement text, string caption = null, MessageBoxIcon icon = MessageBoxIcon.None) - { - ApplicationWindow.ShowModalMessage(text, caption: caption, icon: icon); - } - - /// - /// Shows a modal message box and asynchronously returns a MessageBoxResult - /// - /// The text. - /// The caption. - /// The button. - /// The icon. - /// MessageBoxResult. - public MessageBoxResult ShowModalMessage(string text, string caption = null, MessageBoxButton button = MessageBoxButton.OK, MessageBoxIcon icon = MessageBoxIcon.None) - { - return ApplicationWindow.ShowModalMessage(text, caption: caption, button: button, icon: icon); - } - - /// - /// Shows a modal message box and asynchronously returns a MessageBoxResult - /// - /// The text. - /// The caption. - /// The button. - /// The icon. - /// MessageBoxResult. - public MessageBoxResult ShowModalMessage(UIElement text, string caption = null, MessageBoxButton button = MessageBoxButton.OK, MessageBoxIcon icon = MessageBoxIcon.None) - { - return ApplicationWindow.ShowModalMessage(text, caption: caption, button: button, icon: icon); - } - - /// - /// Shows the error message. - /// - /// The message. - /// The caption. - public void ShowErrorMessage(string message, string caption = null) - { - caption = caption ?? "Error"; - ShowModalMessage(message, caption: caption, button: MessageBoxButton.OK, icon: MessageBoxIcon.Error); - } - - /// - /// Shows the default error message. - /// - public void ShowDefaultErrorMessage() - { - ShowErrorMessage("There was an error processing the request", "Error"); - } - - /// - /// The _remote image cache - /// - private FileSystemRepository _remoteImageCache; - - /// - /// Gets the remote image async. - /// - /// The URL. - /// Task{Image}. - public async Task GetRemoteImageAsync(string url) - { - var bitmap = await GetRemoteBitmapAsync(url); - - return new Image { Source = bitmap }; - } - - /// - /// Gets the remote image async. - /// - /// The URL. - /// Task{BitmapImage}. - /// url - public Task GetRemoteBitmapAsync(string url) - { - if (string.IsNullOrEmpty(url)) - { - throw new ArgumentNullException("url"); - } - - Logger.Info("Image url: " + url); - - return Task.Run(async () => - { - var cachePath = _remoteImageCache.GetResourcePath(url.GetMD5().ToString()); - - await _remoteImageCache.WaitForLockAsync(cachePath).ConfigureAwait(false); - - var releaseLock = true; - try - { - using (var stream = new FileStream(cachePath, FileMode.Open, FileAccess.Read, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, true)) - { - return await GetRemoteBitmapAsync(stream).ConfigureAwait(false); - } - } - catch (FileNotFoundException) - { - // Doesn't exist. No biggie - releaseLock = false; - } - finally - { - if (releaseLock) - { - _remoteImageCache.ReleaseLock(cachePath); - } - } - - try - { - using (var httpStream = await UIKernel.Instance.ApiClient.GetImageStreamAsync(url + "&x=1")) - { - return await GetRemoteBitmapAsync(httpStream, cachePath); - } - } - finally - { - _remoteImageCache.ReleaseLock(cachePath); - } - }); - } - - /// - /// Gets the image async. - /// - /// The source stream. - /// The cache path. - /// Task{BitmapImage}. - private async Task GetRemoteBitmapAsync(Stream sourceStream, string cachePath = null) - { - byte[] bytes; - - using (var ms = new MemoryStream()) - { - await sourceStream.CopyToAsync(ms).ConfigureAwait(false); - - bytes = ms.ToArray(); - } - - if (!string.IsNullOrEmpty(cachePath)) - { - using (var fileStream = new FileStream(cachePath, FileMode.Create, FileAccess.Write, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, true)) - { - await fileStream.WriteAsync(bytes, 0, bytes.Length).ConfigureAwait(false); - } - } - - using (Stream stream = new MemoryStream(bytes)) - { - var bitmapImage = new BitmapImage - { - CreateOptions = BitmapCreateOptions.DelayCreation - }; - - bitmapImage.BeginInit(); - bitmapImage.CacheOption = BitmapCacheOption.OnLoad; - bitmapImage.StreamSource = stream; - bitmapImage.EndInit(); - bitmapImage.Freeze(); - return bitmapImage; - } - } - - /// - /// Handles the ConfigurationUpdated event of the Kernel control. - /// - /// The source of the event. - /// The instance containing the event data. - void Kernel_ConfigurationUpdated(object sender, EventArgs e) - { - if (!LastRunAtStartupValue.HasValue || LastRunAtStartupValue.Value != Kernel.Configuration.RunAtStartup) - { - ConfigureClickOnceStartup(); - } - } - - /// - /// Configures the click once startup. - /// - private void ConfigureClickOnceStartup() - { - try - { - ClickOnceHelper.ConfigureClickOnceStartupIfInstalled(PublisherName, ProductName, SuiteName, Kernel.Configuration.RunAtStartup, UninstallerFileName); - - LastRunAtStartupValue = Kernel.Configuration.RunAtStartup; - } - catch (Exception ex) - { - Logger.ErrorException("Error configuring ClickOnce", ex); - } - } - - public void Restart() - { - Dispatcher.Invoke(ReleaseMutex); - - Kernel.Dispose(); - - System.Windows.Forms.Application.Restart(); - - Dispatcher.Invoke(Shutdown); - } - - public void ReloadLogger() - { - LogFilePath = Path.Combine(Kernel.ApplicationPaths.LogDirectoryPath, "Server-" + DateTime.Now.Ticks + ".log"); - - NlogManager.AddFileTarget(LogFilePath, Kernel.Configuration.EnableDebugLevelLogging); - } - - /// - /// Gets the bitmap image. - /// - /// The URI. - /// BitmapImage. - /// uri - public BitmapImage GetBitmapImage(string uri) - { - if (string.IsNullOrEmpty(uri)) - { - throw new ArgumentNullException("uri"); - } - - return GetBitmapImage(new Uri(uri)); - } - - /// - /// Gets the bitmap image. - /// - /// The URI. - /// BitmapImage. - /// uri - public BitmapImage GetBitmapImage(Uri uri) - { - if (uri == null) - { - throw new ArgumentNullException("uri"); - } - - var bitmap = new BitmapImage - { - CreateOptions = BitmapCreateOptions.DelayCreation, - CacheOption = BitmapCacheOption.OnDemand, - UriCachePolicy = new RequestCachePolicy(RequestCacheLevel.CacheIfAvailable) - }; - - bitmap.BeginInit(); - bitmap.UriSource = uri; - bitmap.EndInit(); - - RenderOptions.SetBitmapScalingMode(bitmap, BitmapScalingMode.Fant); - return bitmap; - } - - /// - /// Gets or sets a value indicating whether this instance can self update. - /// - /// true if this instance can self update; otherwise, false. - public bool CanSelfUpdate - { - get { return ClickOnceHelper.IsNetworkDeployed; } - } - - /// - /// Checks for update. - /// - /// The cancellation token. - /// The progress. - /// Task{CheckForUpdateResult}. - public Task CheckForApplicationUpdate(CancellationToken cancellationToken, IProgress progress) - { - return new ApplicationUpdateCheck().CheckForApplicationUpdate(cancellationToken, progress); - } - - /// - /// Registers resources that classes will depend on - /// - private void RegisterResources() - { - Register(this); - Register(Logger); - - IsoManager = new PismoIsoManager(Logger); - - Register(IsoManager); - } - - /// - /// Updates the application. - /// - /// The cancellation token. - /// The progress. - /// Task. - public Task UpdateApplication(CancellationToken cancellationToken, IProgress progress) - { - return new ApplicationUpdater().UpdateApplication(cancellationToken, progress); - } - - /// - /// Creates an instance of type and resolves all constructor dependancies - /// - /// The type. - /// System.Object. - public object CreateInstance(Type type) - { - try - { - return _container.GetInstance(type); - } - catch - { - Logger.Error("Error creating {0}", type.Name); - - throw; - } - } - - /// - /// Registers the specified obj. - /// - /// - /// The obj. - public void Register(T obj) - where T : class - { - _container.RegisterSingle(obj); - } - - /// - /// Resolves this instance. - /// - /// - /// ``0. - public T Resolve() - { - return (T)_container.GetRegistration(typeof(T), true).GetInstance(); - } - - /// - /// Resolves this instance. - /// - /// - /// ``0. - public T TryResolve() - { - var result = _container.GetRegistration(typeof(T), false); - - if (result == null) - { - return default(T); - } - return (T)result.GetInstance(); - } - } -} diff --git a/MediaBrowser.UI/Configuration/PlayerConfiguration.cs b/MediaBrowser.UI/Configuration/PlayerConfiguration.cs deleted file mode 100644 index c00f49b5e9..0000000000 --- a/MediaBrowser.UI/Configuration/PlayerConfiguration.cs +++ /dev/null @@ -1,52 +0,0 @@ -using MediaBrowser.Model.Entities; - -namespace MediaBrowser.UI.Configuration -{ - /// - /// Class PlayerConfiguration - /// - public class PlayerConfiguration - { - /// - /// Gets or sets the name of the player. - /// - /// The name of the player. - public string PlayerName { get; set; } - - /// - /// Gets or sets the item types. - /// - /// The item types. - public string[] ItemTypes { get; set; } - - /// - /// Gets or sets the file extensions. - /// - /// The file extensions. - public string[] FileExtensions { get; set; } - - /// - /// Gets or sets the video types. - /// - /// The video types. - public VideoType[] VideoTypes { get; set; } - - /// - /// Gets or sets the video formats. - /// - /// The video formats. - public VideoFormat[] VideoFormats { get; set; } - - /// - /// Gets or sets the command. - /// - /// The command. - public string Command { get; set; } - - /// - /// Gets or sets the args. - /// - /// The args. - public string Args { get; set; } - } -} diff --git a/MediaBrowser.UI/Configuration/UIApplicationConfiguration.cs b/MediaBrowser.UI/Configuration/UIApplicationConfiguration.cs deleted file mode 100644 index 7038339249..0000000000 --- a/MediaBrowser.UI/Configuration/UIApplicationConfiguration.cs +++ /dev/null @@ -1,72 +0,0 @@ -using MediaBrowser.Model.Configuration; -using System.Windows; - -namespace MediaBrowser.UI.Configuration -{ - /// - /// This is the UI's device configuration that applies regardless of which user is logged in. - /// - public class UIApplicationConfiguration : BaseApplicationConfiguration - { - /// - /// Gets or sets the server host name (myserver or 192.168.x.x) - /// - /// The name of the server host. - public string ServerHostName { get; set; } - - /// - /// Gets or sets the port number used by the API - /// - /// The server API port. - public int ServerApiPort { get; set; } - - /// - /// Gets or sets the player configurations. - /// - /// The player configurations. - public PlayerConfiguration[] MediaPlayers { get; set; } - - /// - /// Gets or sets the state of the window. - /// - /// The state of the window. - public WindowState? WindowState { get; set; } - - /// - /// Gets or sets the window top. - /// - /// The window top. - public double? WindowTop { get; set; } - - /// - /// Gets or sets the window left. - /// - /// The window left. - public double? WindowLeft { get; set; } - - /// - /// Gets or sets the width of the window. - /// - /// The width of the window. - public double? WindowWidth { get; set; } - - /// - /// Gets or sets the height of the window. - /// - /// The height of the window. - public double? WindowHeight { get; set; } - - /// - /// Initializes a new instance of the class. - /// - public UIApplicationConfiguration() - : base() - { - ServerHostName = "localhost"; - ServerApiPort = 8096; - - // Need a different default than the server - LegacyWebSocketPortNumber = 8946; - } - } -} diff --git a/MediaBrowser.UI/Configuration/UIApplicationPaths.cs b/MediaBrowser.UI/Configuration/UIApplicationPaths.cs deleted file mode 100644 index 313c310d3e..0000000000 --- a/MediaBrowser.UI/Configuration/UIApplicationPaths.cs +++ /dev/null @@ -1,37 +0,0 @@ -using MediaBrowser.Common.Kernel; -using System.IO; - -namespace MediaBrowser.UI.Configuration -{ - /// - /// Class UIApplicationPaths - /// - public class UIApplicationPaths : BaseApplicationPaths - { - /// - /// The _remote image cache path - /// - private string _remoteImageCachePath; - /// - /// Gets the remote image cache path. - /// - /// The remote image cache path. - public string RemoteImageCachePath - { - get - { - if (_remoteImageCachePath == null) - { - _remoteImageCachePath = Path.Combine(CachePath, "remote-images"); - - if (!Directory.Exists(_remoteImageCachePath)) - { - Directory.CreateDirectory(_remoteImageCachePath); - } - } - - return _remoteImageCachePath; - } - } - } -} diff --git a/MediaBrowser.UI/Controller/BaseTheme.cs b/MediaBrowser.UI/Controller/BaseTheme.cs deleted file mode 100644 index bcf882f689..0000000000 --- a/MediaBrowser.UI/Controller/BaseTheme.cs +++ /dev/null @@ -1,60 +0,0 @@ -using MediaBrowser.Model.Dto; -using System; -using System.Collections.Generic; -using System.Windows; -using System.Windows.Controls; - -namespace MediaBrowser.UI.Controller -{ - /// - /// Class BaseTheme - /// - public abstract class BaseTheme : IDisposable - { - /// - /// Gets the global resources. - /// - /// IEnumerable{ResourceDictionary}. - public abstract IEnumerable GetGlobalResources(); - - /// - /// Gets the list page. - /// - /// The item. - /// Page. - public abstract Page GetListPage(BaseItemDto item); - /// - /// Gets the detail page. - /// - /// The item. - /// Page. - public abstract Page GetDetailPage(BaseItemDto item); - /// - /// Gets the home page. - /// - /// Page. - public abstract Page GetHomePage(); - /// - /// Gets the login page. - /// - /// Page. - public abstract Page GetLoginPage(); - /// - /// Gets the internal player page. - /// - /// Page. - public abstract Page GetInternalPlayerPage(); - - /// - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// - public virtual void Dispose() - { - } - - /// - /// Displays the weather. - /// - public abstract void DisplayWeather(); - } -} diff --git a/MediaBrowser.UI/Controller/PluginUpdater.cs b/MediaBrowser.UI/Controller/PluginUpdater.cs deleted file mode 100644 index e56b6f54f2..0000000000 --- a/MediaBrowser.UI/Controller/PluginUpdater.cs +++ /dev/null @@ -1,313 +0,0 @@ -using MediaBrowser.Common.IO; -using MediaBrowser.Model.Logging; -using MediaBrowser.Model.Net; -using MediaBrowser.Model.Plugins; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Threading.Tasks; - -namespace MediaBrowser.UI.Controller -{ - /// - /// This keeps ui plugin assemblies in sync with plugins installed on the server - /// - public class PluginUpdater - { - private readonly ILogger _logger; - - public PluginUpdater(ILogger logger) - { - _logger = logger; - } - - /// - /// Updates the plugins. - /// - /// Task{PluginUpdateResult}. - public async Task UpdatePlugins() - { - _logger.Info("Downloading list of installed plugins"); - var allInstalledPlugins = await UIKernel.Instance.ApiClient.GetInstalledPluginsAsync().ConfigureAwait(false); - - var uiPlugins = allInstalledPlugins.Where(p => p.DownloadToUI).ToList(); - - var result = new PluginUpdateResult { }; - - result.DeletedPlugins = DeleteUninstalledPlugins(uiPlugins); - - await DownloadPluginAssemblies(uiPlugins, result).ConfigureAwait(false); - - result.UpdatedConfigurations = await DownloadPluginConfigurations(uiPlugins).ConfigureAwait(false); - - return result; - } - - /// - /// Downloads plugin assemblies from the server, if they need to be installed or updated. - /// - /// The UI plugins. - /// The result. - /// Task. - private async Task DownloadPluginAssemblies(IEnumerable uiPlugins, PluginUpdateResult result) - { - var newlyInstalledPlugins = new List(); - var updatedPlugins = new List(); - - // Loop through the list of plugins that are on the server - foreach (var pluginInfo in uiPlugins) - { - // See if it is already installed in the UI - var currentAssemblyPath = Path.Combine(UIKernel.Instance.ApplicationPaths.PluginsPath, pluginInfo.AssemblyFileName); - - var isPluginInstalled = File.Exists(currentAssemblyPath); - - // Download the plugin if it is not present, or if the current version is out of date - bool downloadPlugin; - - if (!isPluginInstalled) - { - downloadPlugin = true; - _logger.Info("{0} is not installed and needs to be downloaded.", pluginInfo.Name); - } - else - { - var serverVersion = Version.Parse(pluginInfo.Version); - - var fileVersion = FileVersionInfo.GetVersionInfo(currentAssemblyPath).FileVersion ?? string.Empty; - - downloadPlugin = string.IsNullOrEmpty(fileVersion) || Version.Parse(fileVersion) < serverVersion; - - if (downloadPlugin) - { - _logger.Info("{0} has an updated version on the server and needs to be downloaded. Server version: {1}, UI version: {2}", pluginInfo.Name, serverVersion, fileVersion); - } - } - - if (downloadPlugin) - { - if (UIKernel.Instance.ApplicationVersion < Version.Parse(pluginInfo.MinimumRequiredUIVersion)) - { - _logger.Warn("Can't download new version of {0} because the application needs to be updated first.", pluginInfo.Name); - continue; - } - - try - { - await DownloadPlugin(pluginInfo).ConfigureAwait(false); - - if (isPluginInstalled) - { - updatedPlugins.Add(pluginInfo); - } - else - { - newlyInstalledPlugins.Add(pluginInfo); - } - } - catch (HttpException ex) - { - _logger.ErrorException("Error downloading {0} configuration", ex, pluginInfo.Name); - } - catch (IOException ex) - { - _logger.ErrorException("Error saving plugin assembly for {0}", ex, pluginInfo.Name); - } - } - } - - result.NewlyInstalledPlugins = newlyInstalledPlugins; - result.UpdatedPlugins = updatedPlugins; - } - - /// - /// Downloads plugin configurations from the server. - /// - /// The UI plugins. - /// Task{List{PluginInfo}}. - private async Task> DownloadPluginConfigurations(IEnumerable uiPlugins) - { - var updatedPlugins = new List(); - - // Loop through the list of plugins that are on the server - foreach (var pluginInfo in uiPlugins - .Where(p => UIKernel.Instance.ApplicationVersion >= Version.Parse(p.MinimumRequiredUIVersion))) - { - // See if it is already installed in the UI - var path = Path.Combine(UIKernel.Instance.ApplicationPaths.PluginConfigurationsPath, pluginInfo.ConfigurationFileName); - - var download = false; - - if (!File.Exists(path)) - { - download = true; - _logger.Info("{0} configuration was not found needs to be downloaded.", pluginInfo.Name); - } - else if (File.GetLastWriteTimeUtc(path) < pluginInfo.ConfigurationDateLastModified) - { - download = true; - _logger.Info("{0} has an updated configuration on the server and needs to be downloaded.", pluginInfo.Name); - } - - if (download) - { - if (UIKernel.Instance.ApplicationVersion < Version.Parse(pluginInfo.MinimumRequiredUIVersion)) - { - _logger.Warn("Can't download updated configuration of {0} because the application needs to be updated first.", pluginInfo.Name); - continue; - } - - try - { - await DownloadPluginConfiguration(pluginInfo, path).ConfigureAwait(false); - - updatedPlugins.Add(pluginInfo); - } - catch (HttpException ex) - { - _logger.ErrorException("Error downloading {0} configuration", ex, pluginInfo.Name); - } - catch (IOException ex) - { - _logger.ErrorException("Error saving plugin configuration to {0}", ex, path); - } - } - } - - return updatedPlugins; - } - - /// - /// Downloads a plugin assembly from the server - /// - /// The plugin. - /// Task. - private async Task DownloadPlugin(PluginInfo plugin) - { - _logger.Info("Downloading {0} Plugin", plugin.Name); - - var path = Path.Combine(UIKernel.Instance.ApplicationPaths.PluginsPath, plugin.AssemblyFileName); - - // First download to a MemoryStream. This way if the download is cut off, we won't be left with a partial file - using (var memoryStream = new MemoryStream()) - { - var assemblyStream = await UIKernel.Instance.ApiClient.GetPluginAssemblyAsync(plugin).ConfigureAwait(false); - - await assemblyStream.CopyToAsync(memoryStream).ConfigureAwait(false); - - memoryStream.Position = 0; - - using (var fileStream = new FileStream(path, FileMode.Create)) - { - await memoryStream.CopyToAsync(fileStream).ConfigureAwait(false); - } - } - } - - /// - /// Downloads the latest configuration for a plugin - /// - /// The plugin info. - /// The path. - /// Task. - private async Task DownloadPluginConfiguration(PluginInfo pluginInfo, string path) - { - _logger.Info("Downloading {0} Configuration", pluginInfo.Name); - - // First download to a MemoryStream. This way if the download is cut off, we won't be left with a partial file - using (var stream = await UIKernel.Instance.ApiClient.GetPluginConfigurationFileAsync(pluginInfo.Id).ConfigureAwait(false)) - { - using (var memoryStream = new MemoryStream()) - { - await stream.CopyToAsync(memoryStream).ConfigureAwait(false); - - memoryStream.Position = 0; - - using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, true)) - { - await memoryStream.CopyToAsync(fs).ConfigureAwait(false); - } - } - } - - File.SetLastWriteTimeUtc(path, pluginInfo.ConfigurationDateLastModified); - } - - /// - /// Deletes any plugins that have been uninstalled from the server - /// - /// The UI plugins. - /// IEnumerable{System.String}. - private IEnumerable DeleteUninstalledPlugins(IEnumerable uiPlugins) - { - var deletedPlugins = new List(); - - foreach (var plugin in Directory.EnumerateFiles(UIKernel.Instance.ApplicationPaths.PluginsPath, "*.dll", SearchOption.TopDirectoryOnly) - .Select(Path.GetFileName) - .ToList()) - { - var serverPlugin = uiPlugins.FirstOrDefault(p => p.AssemblyFileName.Equals(plugin, StringComparison.OrdinalIgnoreCase)); - - if (serverPlugin == null) - { - try - { - DeletePlugin(plugin); - - deletedPlugins.Add(plugin); - } - catch (IOException ex) - { - _logger.ErrorException("Error deleting plugin assembly {0}", ex, plugin); - } - } - } - - return deletedPlugins; - } - - /// - /// Deletes an installed ui plugin. - /// Leaves config and data behind in the event it is later re-installed - /// - /// The plugin. - private void DeletePlugin(string plugin) - { - _logger.Info("Deleting {0} Plugin", plugin); - - if (File.Exists(plugin)) - { - File.Delete(plugin); - } - } - } - - /// - /// Class PluginUpdateResult - /// - public class PluginUpdateResult - { - /// - /// Gets or sets the deleted plugins. - /// - /// The deleted plugins. - public IEnumerable DeletedPlugins { get; set; } - /// - /// Gets or sets the newly installed plugins. - /// - /// The newly installed plugins. - public IEnumerable NewlyInstalledPlugins { get; set; } - /// - /// Gets or sets the updated plugins. - /// - /// The updated plugins. - public IEnumerable UpdatedPlugins { get; set; } - /// - /// Gets or sets the updated configurations. - /// - /// The updated configurations. - public IEnumerable UpdatedConfigurations { get; set; } - } -} diff --git a/MediaBrowser.UI/Controller/UIKernel.cs b/MediaBrowser.UI/Controller/UIKernel.cs deleted file mode 100644 index 118067140f..0000000000 --- a/MediaBrowser.UI/Controller/UIKernel.cs +++ /dev/null @@ -1,181 +0,0 @@ -using MediaBrowser.ApiInteraction; -using MediaBrowser.Common.Kernel; -using MediaBrowser.Model.Connectivity; -using MediaBrowser.Model.Logging; -using MediaBrowser.Model.Net; -using MediaBrowser.UI.Configuration; -using MediaBrowser.UI.Playback; -using System; -using System.Collections.Generic; -using System.Net; -using System.Net.Cache; -using System.Net.Http; -using System.Threading.Tasks; - -namespace MediaBrowser.UI.Controller -{ - /// - /// This controls application logic as well as server interaction within the UI. - /// - public class UIKernel : BaseKernel - { - /// - /// Gets the instance. - /// - /// The instance. - public static UIKernel Instance { get; private set; } - - /// - /// Gets the API client. - /// - /// The API client. - public ApiClient ApiClient { get; private set; } - - /// - /// Gets the playback manager. - /// - /// The playback manager. - public PlaybackManager PlaybackManager { get; private set; } - - /// - /// Initializes a new instance of the class. - /// - public UIKernel(IApplicationHost appHost, ILogger logger) - : base(appHost, logger) - { - Instance = this; - } - - /// - /// Gets the media players. - /// - /// The media players. - public IEnumerable MediaPlayers { get; private set; } - - /// - /// Gets the list of currently loaded themes - /// - /// The themes. - public IEnumerable Themes { get; private set; } - - /// - /// Gets the kernel context. - /// - /// The kernel context. - public override KernelContext KernelContext - { - get { return KernelContext.Ui; } - } - - /// - /// Gets the UDP server port number. - /// - /// The UDP server port number. - public override int UdpServerPortNumber - { - get { return 7360; } - } - - /// - /// Give the UI a different url prefix so that they can share the same port, in case they are installed on the same machine. - /// - /// The HTTP server URL prefix. - public override string HttpServerUrlPrefix - { - get - { - return "http://+:" + Configuration.HttpServerPortNumber + "/mediabrowserui/"; - } - } - - /// - /// Reload api client and update plugins after loading configuration - /// - /// Task. - protected override async Task OnConfigurationLoaded() - { - ReloadApiClient(); - - try - { - await new PluginUpdater(Logger).UpdatePlugins().ConfigureAwait(false); - } - catch (HttpException ex) - { - Logger.ErrorException("Error updating plugins from the server", ex); - } - } - - /// - /// Disposes the current ApiClient and creates a new one - /// - private void ReloadApiClient() - { - DisposeApiClient(); - - ApiClient = new ApiClient(Logger, new AsyncHttpClient(new WebRequestHandler - { - AutomaticDecompression = DecompressionMethods.Deflate, - CachePolicy = new RequestCachePolicy(RequestCacheLevel.Revalidate) - })) - { - ServerHostName = Configuration.ServerHostName, - ServerApiPort = Configuration.ServerApiPort, - ClientType = ClientType.Pc, - DeviceName = Environment.MachineName, - SerializationFormat = SerializationFormats.Json - }; - } - - /// - /// Finds the parts. - /// - /// All types. - protected override void FindParts(Type[] allTypes) - { - PlaybackManager = (PlaybackManager)ApplicationHost.CreateInstance(typeof(PlaybackManager)); - - base.FindParts(allTypes); - - Themes = GetExports(allTypes); - MediaPlayers = GetExports(allTypes); - } - - /// - /// Called when [composable parts loaded]. - /// - /// Task. - protected override async Task OnComposablePartsLoaded() - { - await base.OnComposablePartsLoaded().ConfigureAwait(false); - - // Once plugins have loaded give the api a reference to our protobuf serializer - DataSerializer.DynamicSerializer = ProtobufSerializer.TypeModel; - } - - /// - /// Disposes the current ApiClient - /// - private void DisposeApiClient() - { - if (ApiClient != null) - { - ApiClient.Dispose(); - } - } - - /// - /// Releases unmanaged and - optionally - managed resources. - /// - /// true to release both managed and unmanaged resources; false to release only unmanaged resources. - protected override void Dispose(bool dispose) - { - if (dispose) - { - DisposeApiClient(); - } - - base.Dispose(dispose); - } - } -} diff --git a/MediaBrowser.UI/Controls/ModalWindow.xaml b/MediaBrowser.UI/Controls/ModalWindow.xaml deleted file mode 100644 index c2afbe05e2..0000000000 --- a/MediaBrowser.UI/Controls/ModalWindow.xaml +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/MediaBrowser.UI/Controls/ModalWindow.xaml.cs b/MediaBrowser.UI/Controls/ModalWindow.xaml.cs deleted file mode 100644 index 21f97b8ac0..0000000000 --- a/MediaBrowser.UI/Controls/ModalWindow.xaml.cs +++ /dev/null @@ -1,180 +0,0 @@ -using System; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Media.Animation; - -namespace MediaBrowser.UI.Controls -{ - /// - /// Interaction logic for ModalWindow.xaml - /// - 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; - } - } - - /// - /// 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. - /// - 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 deleted file mode 100644 index 020fecd6d5..0000000000 --- a/MediaBrowser.UI/Controls/NavigationBar.xaml +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/MediaBrowser.UI/Controls/NavigationBar.xaml.cs b/MediaBrowser.UI/Controls/NavigationBar.xaml.cs deleted file mode 100644 index 6d59a7d3a3..0000000000 --- a/MediaBrowser.UI/Controls/NavigationBar.xaml.cs +++ /dev/null @@ -1,318 +0,0 @@ -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 -{ - /// - /// Interaction logic for NavigationBar.xaml - /// - public partial class NavigationBar : BaseUserControl - { - /// - /// Gets or sets the current player. - /// - /// The current player. - private BaseMediaPlayer CurrentPlayer { get; set; } - - /// - /// Gets or sets the current position timer. - /// - /// The current position timer. - private Timer CurrentPositionTimer { get; set; } - - /// - /// Initializes a new instance of the class. - /// - public NavigationBar() - { - InitializeComponent(); - - Loaded += NavigationBar_Loaded; - } - - /// - /// Handles the Loaded event of the NavigationBar control. - /// - /// The source of the event. - /// The instance containing the event data. - 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; - } - - /// - /// Handles the Click event of the PreviousChapterButton control. - /// - /// The source of the event. - /// The instance containing the event data. - async void PreviousChapterButton_Click(object sender, RoutedEventArgs e) - { - await CurrentPlayer.GoToPreviousChapter(); - } - - /// - /// Handles the Click event of the NextChapterButton control. - /// - /// The source of the event. - /// The instance containing the event data. - async void NextChapterButton_Click(object sender, RoutedEventArgs e) - { - await CurrentPlayer.GoToNextChapter(); - } - - /// - /// Handles the Click event of the PauseButton control. - /// - /// The source of the event. - /// The instance containing the event data. - async void PauseButton_Click(object sender, RoutedEventArgs e) - { - await CurrentPlayer.Pause(); - } - - /// - /// Handles the Click event of the PlayButton control. - /// - /// The source of the event. - /// The instance containing the event data. - async void PlayButton_Click(object sender, RoutedEventArgs e) - { - await CurrentPlayer.UnPause(); - } - - /// - /// Handles the Click event of the StopButton control. - /// - /// The source of the event. - /// The instance containing the event data. - async void StopButton_Click(object sender, RoutedEventArgs e) - { - await CurrentPlayer.Stop(); - } - - /// - /// Handles the PlaybackCompleted event of the PlaybackManager control. - /// - /// The source of the event. - /// The instance containing the event data. - 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); - } - } - - /// - /// Handles the Click event of the VolumeUpButton control. - /// - /// The source of the event. - /// The instance containing the event data. - void VolumeUpButton_Click(object sender, RoutedEventArgs e) - { - CurrentPlayer.Volume += 3; - } - - /// - /// Handles the Click event of the VolumeDownButton control. - /// - /// The source of the event. - /// The instance containing the event data. - void VolumeDownButton_Click(object sender, RoutedEventArgs e) - { - CurrentPlayer.Volume -= 3; - } - - /// - /// Handles the Click event of the MuteButton control. - /// - /// The source of the event. - /// The instance containing the event data. - void MuteButton_Click(object sender, RoutedEventArgs e) - { - if (CurrentPlayer.CanMute) - { - CurrentPlayer.Mute = !CurrentPlayer.Mute; - } - } - - /// - /// Handles the PlaybackStarted event of the PlaybackManager control. - /// - /// The source of the event. - /// The instance containing the event data. - 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); - } - } - - /// - /// Currents the position timer callback. - /// - /// The state. - 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; - } - }); - } - - /// - /// Gets the time string. - /// - /// The ticks. - /// System.String. - private string GetTimeString(long ticks) - { - var timespan = TimeSpan.FromTicks(ticks); - - return timespan.TotalHours >= 1 ? timespan.ToString("hh':'mm':'ss") : timespan.ToString("mm':'ss"); - } - - /// - /// Handles the PlayStateChanged event of the CurrentPlayer control. - /// - /// The source of the event. - /// The instance containing the event data. - void CurrentPlayer_PlayStateChanged(object sender, EventArgs e) - { - ResetButtonVisibilities(CurrentPlayer); - } - - /// - /// Resets the button visibilities. - /// - /// The player. - 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; - }); - } - - /// - /// BTNs the application back click. - /// - /// The sender. - /// The instance containing the event data. - void BtnApplicationBackClick(object sender, RoutedEventArgs e) - { - App.Instance.ApplicationWindow.NavigateBack(); - } - - /// - /// The is position slider dragging - /// - private bool _isPositionSliderDragging; - - /// - /// Handles the DragStarted event of the CurrentPositionSlider control. - /// - /// The source of the event. - /// The instance containing the event data. - private void CurrentPositionSlider_DragStarted(object sender, DragStartedEventArgs e) - { - _isPositionSliderDragging = true; - } - - /// - /// Handles the DragCompleted event of the CurrentPositionSlider control. - /// - /// The source of the event. - /// The instance containing the event data. - private void CurrentPositionSlider_DragCompleted(object sender, DragCompletedEventArgs e) - { - _isPositionSliderDragging = false; - - //await CurrentPlayer.Seek(Convert.ToInt64(CurrentPositionSlider.Value)); - } - - /// - /// Handles the PreviewMouseUp event of the CurrentPositionSlider control. - /// - /// The source of the event. - /// The instance containing the event data. - 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 deleted file mode 100644 index 6411b6f57a..0000000000 --- a/MediaBrowser.UI/Controls/NotificationMessage.xaml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/MediaBrowser.UI/Controls/NotificationMessage.xaml.cs b/MediaBrowser.UI/Controls/NotificationMessage.xaml.cs deleted file mode 100644 index 06ed513b13..0000000000 --- a/MediaBrowser.UI/Controls/NotificationMessage.xaml.cs +++ /dev/null @@ -1,68 +0,0 @@ -using System; -using System.Windows; -using System.Windows.Controls; - -namespace MediaBrowser.UI.Controls -{ - /// - /// Interaction logic for NotificationMessage.xaml - /// - 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/WindowCommands.xaml b/MediaBrowser.UI/Controls/WindowCommands.xaml deleted file mode 100644 index bca8812385..0000000000 --- a/MediaBrowser.UI/Controls/WindowCommands.xaml +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/MediaBrowser.UI/Controls/WindowCommands.xaml.cs b/MediaBrowser.UI/Controls/WindowCommands.xaml.cs deleted file mode 100644 index e285cced12..0000000000 --- a/MediaBrowser.UI/Controls/WindowCommands.xaml.cs +++ /dev/null @@ -1,82 +0,0 @@ -using System.Windows; -using System.Windows.Controls; - -namespace MediaBrowser.UI.Controls -{ - /// - /// Interaction logic for WindowCommands.xaml - /// - public partial class WindowCommands : UserControl - { - /// - /// Gets the parent window. - /// - /// The parent window. - public Window ParentWindow - { - get { return TreeHelper.TryFindParent(this); } - } - - /// - /// Initializes a new instance of the class. - /// - public WindowCommands() - { - InitializeComponent(); - Loaded += WindowCommandsLoaded; - } - - /// - /// Windows the commands loaded. - /// - /// The sender. - /// The instance containing the event data. - void WindowCommandsLoaded(object sender, RoutedEventArgs e) - { - CloseApplicationButton.Click += CloseApplicationButtonClick; - MinimizeApplicationButton.Click += MinimizeApplicationButtonClick; - MaximizeApplicationButton.Click += MaximizeApplicationButtonClick; - UndoMaximizeApplicationButton.Click += UndoMaximizeApplicationButtonClick; - } - - /// - /// Undoes the maximize application button click. - /// - /// The sender. - /// The instance containing the event data. - void UndoMaximizeApplicationButtonClick(object sender, RoutedEventArgs e) - { - ParentWindow.WindowState = WindowState.Normal; - } - - /// - /// Maximizes the application button click. - /// - /// The sender. - /// The instance containing the event data. - void MaximizeApplicationButtonClick(object sender, RoutedEventArgs e) - { - ParentWindow.WindowState = WindowState.Maximized; - } - - /// - /// Minimizes the application button click. - /// - /// The sender. - /// The instance containing the event data. - void MinimizeApplicationButtonClick(object sender, RoutedEventArgs e) - { - ParentWindow.WindowState = WindowState.Minimized; - } - - /// - /// Closes the application button click. - /// - /// The sender. - /// The instance containing the event data. - void CloseApplicationButtonClick(object sender, RoutedEventArgs e) - { - App.Instance.Shutdown(); - } - } -} diff --git a/MediaBrowser.UI/Converters/BaseItemImageVisibilityConverter.cs b/MediaBrowser.UI/Converters/BaseItemImageVisibilityConverter.cs deleted file mode 100644 index 6e69326fcf..0000000000 --- a/MediaBrowser.UI/Converters/BaseItemImageVisibilityConverter.cs +++ /dev/null @@ -1,75 +0,0 @@ -using MediaBrowser.Model.Dto; -using MediaBrowser.Model.Entities; -using System; -using System.Windows; -using System.Windows.Data; - -namespace MediaBrowser.UI.Converters -{ - /// - /// Class BaseItemImageVisibilityConverter - /// - class BaseItemImageVisibilityConverter : IValueConverter - { - /// - /// Converts a value. - /// - /// The value produced by the binding source. - /// The type of the binding target property. - /// The converter parameter to use. - /// The culture to use in the converter. - /// A converted value. If the method returns null, the valid null value is used. - public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) - { - var item = value as BaseItemDto; - - if (item != null) - { - var paramString = parameter as string; - - var vals = paramString.Split(','); - - var imageType = (ImageType)Enum.Parse(typeof(ImageType), vals[0], true); - bool reverse = vals.Length > 1 && vals[1].Equals("reverse", StringComparison.OrdinalIgnoreCase); - - return GetVisibility(item, imageType, reverse); - } - - return Visibility.Collapsed; - } - - /// - /// Gets the visibility. - /// - /// The item. - /// The type. - /// if set to true [reverse]. - /// Visibility. - private Visibility GetVisibility(BaseItemDto item, ImageType type, bool reverse) - { - var hasImageVisibility = reverse ? Visibility.Collapsed : Visibility.Visible; - var hasNoImageVisibility = reverse ? Visibility.Visible : Visibility.Collapsed; - - if (type == ImageType.Logo) - { - return item.HasLogo || !string.IsNullOrEmpty(item.ParentLogoItemId) ? hasImageVisibility : hasNoImageVisibility; - } - - return item.HasPrimaryImage ? hasImageVisibility : hasNoImageVisibility; - } - - /// - /// Converts a value. - /// - /// The value that is produced by the binding target. - /// The type to convert to. - /// The converter parameter to use. - /// The culture to use in the converter. - /// A converted value. If the method returns null, the valid null value is used. - /// - public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) - { - throw new NotImplementedException(); - } - } -} diff --git a/MediaBrowser.UI/Converters/CurrentUserVisibilityConverter.cs b/MediaBrowser.UI/Converters/CurrentUserVisibilityConverter.cs deleted file mode 100644 index c7853ea9c6..0000000000 --- a/MediaBrowser.UI/Converters/CurrentUserVisibilityConverter.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; -using System.Globalization; -using System.Windows; -using System.Windows.Data; - -namespace MediaBrowser.UI.Converters -{ - public class CurrentUserVisibilityConverter : IValueConverter - { - public object Convert(object value, Type targetType, object parameter, CultureInfo culture) - { - if (App.Instance.ServerConfiguration == null) - { - return Visibility.Collapsed; - } - - return value == null ? Visibility.Collapsed : Visibility.Visible; - } - - - public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) - { - throw new NotImplementedException(); - } - } -} diff --git a/MediaBrowser.UI/Converters/DateTimeToStringConverter.cs b/MediaBrowser.UI/Converters/DateTimeToStringConverter.cs deleted file mode 100644 index f0c93e7d5b..0000000000 --- a/MediaBrowser.UI/Converters/DateTimeToStringConverter.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System; -using System.Globalization; -using System.Windows.Data; - -namespace MediaBrowser.UI.Converters -{ - public class DateTimeToStringConverter : IValueConverter - { - public object Convert(object value, Type targetType, object parameter, CultureInfo culture) - { - var date = (DateTime)value; - - string format = parameter as string; - - if (string.IsNullOrEmpty(format)) - { - return date.ToString(); - } - - // If a theme asks for this, they know it's only going to work if the current culture is en-us - if (format.Equals("timesuffixlower", StringComparison.OrdinalIgnoreCase)) - { - if (CultureInfo.CurrentCulture.Name.Equals("en-US", StringComparison.OrdinalIgnoreCase)) - { - var time = date.ToString("t"); - var values = time.Split(' '); - return values[values.Length - 1].ToLower(); - } - return string.Empty; - } - - return date.ToString(format); - } - - - public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) - { - throw new NotImplementedException(); - } - } -} diff --git a/MediaBrowser.UI/Converters/LastSeenTextConverter.cs b/MediaBrowser.UI/Converters/LastSeenTextConverter.cs deleted file mode 100644 index 13e6c54b96..0000000000 --- a/MediaBrowser.UI/Converters/LastSeenTextConverter.cs +++ /dev/null @@ -1,86 +0,0 @@ -using MediaBrowser.Model.Dto; -using System; -using System.Globalization; -using System.Windows.Data; - -namespace MediaBrowser.UI.Converters -{ - public class LastSeenTextConverter : IValueConverter - { - public object Convert(object value, Type targetType, object parameter, CultureInfo culture) - { - var user = value as UserDto; - - if (user != null) - { - if (user.LastActivityDate.HasValue) - { - DateTime date = user.LastActivityDate.Value.ToLocalTime(); - - return "Last seen " + GetRelativeTimeText(date); - } - } - - return null; - } - - private static string GetRelativeTimeText(DateTime date) - { - TimeSpan ts = DateTime.Now - date; - - const int second = 1; - const int minute = 60 * second; - const int hour = 60 * minute; - const int day = 24 * hour; - const int month = 30 * day; - - int delta = System.Convert.ToInt32(ts.TotalSeconds); - - if (delta < 0) - { - return "not yet"; - } - if (delta < 1 * minute) - { - return ts.Seconds == 1 ? "one second ago" : ts.Seconds + " seconds ago"; - } - if (delta < 2 * minute) - { - return "a minute ago"; - } - if (delta < 45 * minute) - { - return ts.Minutes + " minutes ago"; - } - if (delta < 90 * minute) - { - return "an hour ago"; - } - if (delta < 24 * hour) - { - return ts.Hours == 1 ? "an hour ago" : ts.Hours + " hours ago"; - } - if (delta < 48 * hour) - { - return "yesterday"; - } - if (delta < 30 * day) - { - return ts.Days + " days ago"; - } - if (delta < 12 * month) - { - int months = System.Convert.ToInt32(Math.Floor((double)ts.Days / 30)); - return months <= 1 ? "one month ago" : months + " months ago"; - } - - int years = System.Convert.ToInt32(Math.Floor((double)ts.Days / 365)); - return years <= 1 ? "one year ago" : years + " years ago"; - } - - public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) - { - throw new NotImplementedException(); - } - } -} diff --git a/MediaBrowser.UI/Converters/MetroTileBackgroundConverter.cs b/MediaBrowser.UI/Converters/MetroTileBackgroundConverter.cs deleted file mode 100644 index 6279711e2a..0000000000 --- a/MediaBrowser.UI/Converters/MetroTileBackgroundConverter.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System; -using System.Globalization; -using System.Windows.Data; -using System.Windows.Media; - -namespace MediaBrowser.UI.Converters -{ - /// - /// Generates a random metro-friendly background color - /// - public class MetroTileBackgroundConverter : IValueConverter - { - private static readonly Brush[] TileColors = new Brush[] { - new SolidColorBrush(Color.FromRgb((byte)111,(byte)189,(byte)69)), - new SolidColorBrush(Color.FromRgb((byte)75,(byte)179,(byte)221)), - new SolidColorBrush(Color.FromRgb((byte)65,(byte)100,(byte)165)), - new SolidColorBrush(Color.FromRgb((byte)225,(byte)32,(byte)38)), - new SolidColorBrush(Color.FromRgb((byte)128,(byte)0,(byte)128)), - new SolidColorBrush(Color.FromRgb((byte)0,(byte)128,(byte)64)), - new SolidColorBrush(Color.FromRgb((byte)0,(byte)148,(byte)255)), - new SolidColorBrush(Color.FromRgb((byte)255,(byte)0,(byte)199)), - new SolidColorBrush(Color.FromRgb((byte)255,(byte)135,(byte)15)), - new SolidColorBrush(Color.FromRgb((byte)127,(byte)0,(byte)55)) - - }; - - private static int _currentIndex = new Random(DateTime.Now.Millisecond).Next(0, TileColors.Length); - - public object Convert(object value, Type targetType, object parameter, CultureInfo culture) - { - return GetRandomBackground(); - } - - public static Brush GetRandomBackground() - { - int index; - - lock (TileColors) - { - index = (_currentIndex++) % TileColors.Length; - } - - return TileColors[index++]; - } - - public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) - { - throw new System.NotImplementedException(); - } - } -} diff --git a/MediaBrowser.UI/Converters/UserImageConverter.cs b/MediaBrowser.UI/Converters/UserImageConverter.cs deleted file mode 100644 index f979107c88..0000000000 --- a/MediaBrowser.UI/Converters/UserImageConverter.cs +++ /dev/null @@ -1,97 +0,0 @@ -using MediaBrowser.Model.Dto; -using MediaBrowser.Model.Net; -using System; -using System.Globalization; -using System.Windows.Data; - -namespace MediaBrowser.UI.Converters -{ - /// - /// Class UserImageConverter - /// - public class UserImageConverter : IValueConverter - { - /// - /// Converts a value. - /// - /// The value produced by the binding source. - /// The type of the binding target property. - /// The converter parameter to use. - /// The culture to use in the converter. - /// A converted value. If the method returns null, the valid null value is used. - public object Convert(object value, Type targetType, object parameter, CultureInfo culture) - { - var user = value as UserDto; - - if (user != null && user.HasPrimaryImage) - { - var config = parameter as string; - - int? maxWidth = null; - int? maxHeight = null; - int? width = null; - int? height = null; - - if (!string.IsNullOrEmpty(config)) - { - var vals = config.Split(','); - - width = GetSize(vals[0]); - height = GetSize(vals[1]); - maxWidth = GetSize(vals[2]); - maxHeight = GetSize(vals[3]); - } - - var uri = App.Instance.ApiClient.GetUserImageUrl(user, new ImageOptions - { - Width = width, - Height = height, - MaxWidth = maxWidth, - MaxHeight = maxHeight, - Quality = 100 - }); - - try - { - return App.Instance.GetRemoteBitmapAsync(uri).Result; - } - catch (HttpException) - { - - } - } - - return null; - } - - /// - /// Gets the size. - /// - /// The val. - /// System.Nullable{System.Int32}. - private int? GetSize(string val) - { - if (string.IsNullOrEmpty(val) || val == "0") - { - return null; - } - - return int.Parse(val); - } - - - /// - /// Converts a value. - /// - /// The value that is produced by the binding target. - /// The type to convert to. - /// The converter parameter to use. - /// The culture to use in the converter. - /// A converted value. If the method returns null, the valid null value is used. - /// - public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) - { - throw new NotImplementedException(); - } - } -} diff --git a/MediaBrowser.UI/Converters/WatchedVisibilityConverter.cs b/MediaBrowser.UI/Converters/WatchedVisibilityConverter.cs deleted file mode 100644 index 797bb54880..0000000000 --- a/MediaBrowser.UI/Converters/WatchedVisibilityConverter.cs +++ /dev/null @@ -1,117 +0,0 @@ -using MediaBrowser.Model.Dto; -using System; -using System.Globalization; -using System.Windows; -using System.Windows.Data; - -namespace MediaBrowser.UI.Converters -{ - public class WatchedVisibilityConverter : IValueConverter - { - public object Convert(object value, Type targetType, object parameter, CultureInfo culture) - { - var item = value as BaseItemDto; - - if (item == null) - { - return null; - } - - if (item.IsFolder) - { - return item.PlayedPercentage.HasValue && item.PlayedPercentage.Value == 100 ? Visibility.Visible : Visibility.Collapsed; - } - - if (item.UserData == null) - { - return Visibility.Collapsed; - } - - return item.UserData.PlayCount == 0 ? Visibility.Collapsed : Visibility.Visible; - } - - public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) - { - throw new NotImplementedException(); - } - } - - public class FavoriteVisibilityConverter : IValueConverter - { - public object Convert(object value, Type targetType, object parameter, CultureInfo culture) - { - var item = value as BaseItemDto; - - if (item == null) - { - return null; - } - - if (item.UserData == null) - { - return Visibility.Collapsed; - } - - return item.UserData.IsFavorite ? Visibility.Visible : Visibility.Collapsed; - } - - public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) - { - throw new NotImplementedException(); - } - } - - public class LikeVisibilityConverter : IValueConverter - { - public object Convert(object value, Type targetType, object parameter, CultureInfo culture) - { - var item = value as BaseItemDto; - - if (item == null) - { - return null; - } - - if (item.UserData == null) - { - return Visibility.Collapsed; - } - - var userdata = item.UserData; - - return userdata.Likes.HasValue && userdata.Likes.Value && !userdata.IsFavorite ? Visibility.Visible : Visibility.Collapsed; - } - - public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) - { - throw new NotImplementedException(); - } - } - - public class DislikeVisibilityConverter : IValueConverter - { - public object Convert(object value, Type targetType, object parameter, CultureInfo culture) - { - var item = value as BaseItemDto; - - if (item == null) - { - return null; - } - - if (item.UserData == null) - { - return Visibility.Collapsed; - } - - var userdata = item.UserData; - - return userdata.Likes.HasValue && !userdata.Likes.Value && !userdata.IsFavorite ? Visibility.Visible : Visibility.Collapsed; - } - - public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) - { - throw new NotImplementedException(); - } - } -} diff --git a/MediaBrowser.UI/Converters/WeatherTemperatureConverter.cs b/MediaBrowser.UI/Converters/WeatherTemperatureConverter.cs deleted file mode 100644 index c297df4f0a..0000000000 --- a/MediaBrowser.UI/Converters/WeatherTemperatureConverter.cs +++ /dev/null @@ -1,31 +0,0 @@ -using MediaBrowser.Model.Weather; -using System; -using System.Globalization; -using System.Windows.Data; - -namespace MediaBrowser.UI.Converters -{ - public class WeatherTemperatureConverter : IValueConverter - { - public object Convert(object value, Type targetType, object parameter, CultureInfo culture) - { - var weather = value as WeatherInfo; - - if (weather != null && weather.CurrentWeather != null) - { - if (App.Instance.ServerConfiguration.WeatherUnit == WeatherUnits.Celsius) - { - return weather.CurrentWeather.TemperatureCelsius + "°C"; - } - - return weather.CurrentWeather.TemperatureFahrenheit + "°F"; - } - return null; - } - - public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) - { - throw new NotImplementedException(); - } - } -} diff --git a/MediaBrowser.UI/Converters/WeatherVisibilityConverter.cs b/MediaBrowser.UI/Converters/WeatherVisibilityConverter.cs deleted file mode 100644 index 5706ecec9e..0000000000 --- a/MediaBrowser.UI/Converters/WeatherVisibilityConverter.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using System.Globalization; -using System.Windows; -using System.Windows.Data; - -namespace MediaBrowser.UI.Converters -{ - public class WeatherVisibilityConverter : IValueConverter - { - public object Convert(object value, Type targetType, object parameter, CultureInfo culture) - { - return value == null ? Visibility.Collapsed : Visibility.Visible; - } - - public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) - { - throw new NotImplementedException(); - } - } -} diff --git a/MediaBrowser.UI/Extensions/Extensions.cs b/MediaBrowser.UI/Extensions/Extensions.cs deleted file mode 100644 index 1d0d7d1c2d..0000000000 --- a/MediaBrowser.UI/Extensions/Extensions.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; -using System.Windows.Threading; - -namespace MediaBrowser.UI.Extensions -{ - public static class Extensions - { - /// - /// Invokes an action after a specified delay - /// - /// The dispatcher. - /// The action. - /// The delay ms. - public static void InvokeWithDelay(this Dispatcher dispatcher, Action action, long delayMs) - { - var timer = new DispatcherTimer(DispatcherPriority.Normal, dispatcher); - timer.Interval = TimeSpan.FromMilliseconds(delayMs); - timer.Tick += (sender, args) => - { - timer.Stop(); - action(); - }; - timer.Start(); - } - } -} diff --git a/MediaBrowser.UI/HiddenWindow.xaml b/MediaBrowser.UI/HiddenWindow.xaml deleted file mode 100644 index 60afccbe76..0000000000 --- a/MediaBrowser.UI/HiddenWindow.xaml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - diff --git a/MediaBrowser.UI/HiddenWindow.xaml.cs b/MediaBrowser.UI/HiddenWindow.xaml.cs deleted file mode 100644 index e2f8f7a37e..0000000000 --- a/MediaBrowser.UI/HiddenWindow.xaml.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System.Windows; -using MediaBrowser.UI.Controller; - -namespace MediaBrowser.UI -{ - /// - /// Interaction logic for HiddenWindow.xaml - /// - public partial class HiddenWindow : Window - { - /// - /// Initializes a new instance of the class. - /// - public HiddenWindow() - { - InitializeComponent(); - - Loaded += HiddenWindow_Loaded; - } - - /// - /// Handles the Loaded event of the HiddenWindow control. - /// - /// The source of the event. - /// The instance containing the event data. - void HiddenWindow_Loaded(object sender, RoutedEventArgs e) - { - Title += " " + UIKernel.Instance.ApplicationVersion.ToString(); - } - } -} diff --git a/MediaBrowser.UI/ImageViewerWindow.xaml b/MediaBrowser.UI/ImageViewerWindow.xaml deleted file mode 100644 index a36bcf42fd..0000000000 --- a/MediaBrowser.UI/ImageViewerWindow.xaml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - diff --git a/MediaBrowser.UI/ImageViewerWindow.xaml.cs b/MediaBrowser.UI/ImageViewerWindow.xaml.cs deleted file mode 100644 index a8baa3e9f1..0000000000 --- a/MediaBrowser.UI/ImageViewerWindow.xaml.cs +++ /dev/null @@ -1,41 +0,0 @@ -using MediaBrowser.UI.Controls; -using System; -using System.Collections.Generic; -using System.Linq; - -namespace MediaBrowser.UI -{ - /// - /// Interaction logic for ImageViewerWindow.xaml - /// - public partial class ImageViewerWindow : BaseModalWindow - { - /// - /// Gets or sets the images. - /// - /// The images. - private IEnumerable> Images { get; set; } - - /// - /// Initializes a new instance of the class. - /// - /// The images. - public ImageViewerWindow(IEnumerable> images) - : base() - { - InitializeComponent(); - - Images = images; - } - - /// - /// Called when [loaded]. - /// - protected override void OnLoaded() - { - base.OnLoaded(); - - //Image.Source = App.Instance.GetBitmapImage(Images.First().Item1); - } - } -} diff --git a/MediaBrowser.UI/MainWindow.xaml b/MediaBrowser.UI/MainWindow.xaml deleted file mode 100644 index 6e8d494ef6..0000000000 --- a/MediaBrowser.UI/MainWindow.xaml +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/MediaBrowser.UI/MainWindow.xaml.cs b/MediaBrowser.UI/MainWindow.xaml.cs deleted file mode 100644 index d3307e9132..0000000000 --- a/MediaBrowser.UI/MainWindow.xaml.cs +++ /dev/null @@ -1,507 +0,0 @@ -using MediaBrowser.Common.Extensions; -using MediaBrowser.Model.Dto; -using MediaBrowser.Model.Logging; -using MediaBrowser.Model.Net; -using MediaBrowser.UI.Controller; -using MediaBrowser.UI.Controls; -using System; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Input; -using MediaBrowser.UI.Extensions; - -namespace MediaBrowser.UI -{ - /// - /// Interaction logic for MainWindow.xaml - /// - public partial class MainWindow : BaseWindow, IDisposable - { - /// - /// Gets or sets the mouse idle timer. - /// - /// The mouse idle timer. - private Timer MouseIdleTimer { get; set; } - /// - /// Gets or sets the backdrop timer. - /// - /// The backdrop timer. - private Timer BackdropTimer { get; set; } - /// - /// Gets or sets the current backdrops. - /// - /// The current backdrops. - private string[] CurrentBackdrops { get; set; } - - /// - /// The _current backdrop index - /// - private int _currentBackdropIndex; - /// - /// Gets or sets the index of the current backdrop. - /// - /// The index of the current backdrop. - public int CurrentBackdropIndex - { - get { return _currentBackdropIndex; } - set - { - _currentBackdropIndex = value; - OnPropertyChanged("CurrentBackdropIndex"); - Dispatcher.InvokeAsync(OnBackdropIndexChanged); - } - } - - /// - /// The _is mouse idle - /// - private bool _isMouseIdle = true; - /// - /// Gets or sets a value indicating whether this instance is mouse idle. - /// - /// true if this instance is mouse idle; otherwise, false. - public bool IsMouseIdle - { - get { return _isMouseIdle; } - set - { - _isMouseIdle = value; - - Dispatcher.InvokeAsync(() => Cursor = value ? Cursors.None : Cursors.Arrow); - - OnPropertyChanged("IsMouseIdle"); - } - } - - private readonly ILogger _logger; - - /// - /// Initializes a new instance of the class. - /// - public MainWindow(ILogger logger) - : base() - { - _logger = logger; - - InitializeComponent(); - } - - /// - /// Called when [loaded]. - /// - protected override void OnLoaded() - { - base.OnLoaded(); - - DragBar.MouseDown += DragableGridMouseDown; - - DataContext = App.Instance; - } - - /// - /// Loads the initial UI. - /// - /// Task. - internal Task LoadInitialUI() - { - return LoadInitialPage(); - } - - /// - /// Called when [backdrop index changed]. - /// - private async void OnBackdropIndexChanged() - { - var currentBackdropIndex = CurrentBackdropIndex; - - if (currentBackdropIndex == -1 ) - { - // Setting this to null doesn't seem to clear out the content - // Have to check it for null or get startup errors - if (BackdropContainer.Content != null) - { - BackdropContainer.Content = new FrameworkElement(); - } - return; - } - - try - { - var bitmap = await App.Instance.GetRemoteBitmapAsync(CurrentBackdrops[currentBackdropIndex]); - - var img = new Image - { - Source = bitmap - }; - - img.SetResourceReference(StyleProperty, "BackdropImage"); - - BackdropContainer.Content = img; - } - catch (HttpException) - { - if (currentBackdropIndex == 0) - { - BackdropContainer.Content = new FrameworkElement(); - } - } - } - - /// - /// Loads the initial page. - /// - /// Task. - private Task LoadInitialPage() - { - return App.Instance.LogoutUser(); - } - - /// - /// Dragables the grid mouse down. - /// - /// The sender. - /// The instance containing the event data. - private void DragableGridMouseDown(object sender, MouseButtonEventArgs e) - { - if (e.ClickCount == 2) - { - WindowState = WindowState == WindowState.Maximized ? WindowState.Normal : WindowState.Maximized; - } - else if (e.LeftButton == MouseButtonState.Pressed) - { - DragMove(); - } - } - - /// - /// Gets the page frame. - /// - /// The page frame. - private TransitionFrame PageFrame - { - get - { - // Finding the grid that is generated by the ControlTemplate of the Button - return TreeHelper.FindChild(PageContent, "PageFrame"); - } - } - - /// - /// Navigates the specified page. - /// - /// The page. - internal void Navigate(Page page) - { - _logger.Info("Navigating to " + page.GetType().Name); - - Dispatcher.InvokeAsync(() => PageFrame.NavigateWithTransition(page)); - } - - /// - /// Sets the backdrop based on a BaseItemDto - /// - /// The item. - public void SetBackdrops(BaseItemDto item) - { - var urls = App.Instance.ApiClient.GetBackdropImageUrls(item, new ImageOptions - { - MaxWidth = Convert.ToInt32(SystemParameters.VirtualScreenWidth), - MaxHeight = Convert.ToInt32(SystemParameters.VirtualScreenHeight) - }); - - SetBackdrops(urls); - } - - /// - /// Sets the backdrop based on a list of image files - /// - /// The backdrops. - public void SetBackdrops(string[] backdrops) - { - // Don't reload the same backdrops - if (CurrentBackdrops != null && backdrops.SequenceEqual(CurrentBackdrops)) - { - return; - } - - DisposeBackdropTimer(); - CurrentBackdrops = backdrops; - - if (backdrops == null || backdrops.Length == 0) - { - CurrentBackdropIndex = -1; - - // Setting this to null doesn't seem to clear out the content - // Have to check it for null or get startup errors - if (BackdropContainer.Content != null) - { - BackdropContainer.Content = new FrameworkElement(); - } - return; - } - - CurrentBackdropIndex = 0; - - // We only need the timer if there's more than one backdrop - if (backdrops != null && backdrops.Length > 1) - { - BackdropTimer = new Timer(state => - { - // Don't display backdrops during video playback - if (UIKernel.Instance.PlaybackManager.ActivePlayers.Any(p => p.CurrentMedia.IsVideo)) - { - return; - } - - var index = CurrentBackdropIndex + 1; - - if (index >= backdrops.Length) - { - index = 0; - } - - CurrentBackdropIndex = index; - - }, null, 5000, 5000); - } - } - - /// - /// Disposes the backdrop timer. - /// - public void DisposeBackdropTimer() - { - if (BackdropTimer != null) - { - BackdropTimer.Dispose(); - } - } - - /// - /// Disposes the mouse idle timer. - /// - public void DisposeMouseIdleTimer() - { - if (MouseIdleTimer != null) - { - MouseIdleTimer.Dispose(); - } - } - - /// - /// Clears the backdrops. - /// - public void ClearBackdrops() - { - SetBackdrops(new string[] { }); - } - - /// - /// Navigates the back. - /// - public void NavigateBack() - { - Dispatcher.InvokeAsync(() => - { - if (PageFrame.NavigationService.CanGoBack) - { - PageFrame.GoBackWithTransition(); - } - }); - } - - /// - /// Navigates the forward. - /// - public void NavigateForward() - { - Dispatcher.InvokeAsync(() => - { - if (PageFrame.NavigationService.CanGoForward) - { - PageFrame.GoForwardWithTransition(); - } - }); - } - - /// - /// Called when [browser back]. - /// - protected override void OnBrowserBack() - { - base.OnBrowserBack(); - - NavigateBack(); - } - - /// - /// Called when [browser forward]. - /// - protected override void OnBrowserForward() - { - base.OnBrowserForward(); - - NavigateForward(); - } - - /// - /// Shows the control bar then starts a timer to hide it - /// - private void StartMouseIdleTimer() - { - IsMouseIdle = false; - - const int duration = 4000; - - // Start the timer if it's null, otherwise reset it - if (MouseIdleTimer == null) - { - MouseIdleTimer = new Timer(MouseIdleTimerCallback, null, duration, Timeout.Infinite); - } - else - { - MouseIdleTimer.Change(duration, Timeout.Infinite); - } - } - - /// - /// This is the Timer callback method to hide the control bar - /// - /// The state info. - private void MouseIdleTimerCallback(object stateInfo) - { - IsMouseIdle = true; - - if (MouseIdleTimer != null) - { - MouseIdleTimer.Dispose(); - MouseIdleTimer = null; - } - } - - /// - /// The _last mouse move point - /// - private Point _lastMouseMovePoint; - - /// - /// Handles OnMouseMove to show the control box - /// - /// The that contains the event data. - protected override void OnMouseMove(MouseEventArgs e) - { - base.OnMouseMove(e); - - // Store the last position for comparison purposes - // Even if the mouse is not moving this event will fire as elements are showing and hiding - var pos = e.GetPosition(this); - - if (pos == _lastMouseMovePoint) - { - return; - } - - _lastMouseMovePoint = pos; - - StartMouseIdleTimer(); - } - - /// - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// - public void Dispose() - { - DisposeBackdropTimer(); - DisposeMouseIdleTimer(); - } - - /// - /// Shows a notification message that will disappear on it's own - /// - /// The text. - /// The caption. - /// The icon. - public void ShowNotificationMessage(string text, string caption = null, MessageBoxIcon icon = MessageBoxIcon.None) - { - var control = new NotificationMessage - { - Caption = caption, - Text = text, - MessageBoxImage = icon - }; - - mainGrid.Children.Add(control); - - Dispatcher.InvokeWithDelay(() => mainGrid.Children.Remove(control), 5000); - } - - /// - /// Shows a notification message that will disappear on it's own - /// - /// The text. - /// The caption. - /// The icon. - public void ShowNotificationMessage(UIElement text, string caption = null, MessageBoxIcon icon = MessageBoxIcon.None) - { - var control = new NotificationMessage - { - Caption = caption, - TextContent = text, - MessageBoxImage = icon - }; - - mainGrid.Children.Add(control); - - Dispatcher.InvokeWithDelay(() => mainGrid.Children.Remove(control), 5000); - } - - /// - /// Shows a modal message box and asynchronously returns a MessageBoxResult - /// - /// The text. - /// The caption. - /// The button. - /// The icon. - /// MessageBoxResult. - public MessageBoxResult ShowModalMessage(string text, string caption = null, MessageBoxButton button = MessageBoxButton.OK, MessageBoxIcon icon = MessageBoxIcon.None) - { - var win = new ModalWindow - { - Caption = caption, - Button = button, - MessageBoxImage = icon, - Text = text - }; - - win.ShowModal(this); - - return win.MessageBoxResult; - } - - /// - /// Shows a modal message box and asynchronously returns a MessageBoxResult - /// - /// The text. - /// The caption. - /// The button. - /// The icon. - /// MessageBoxResult. - public MessageBoxResult ShowModalMessage(UIElement text, string caption = null, MessageBoxButton button = MessageBoxButton.OK, MessageBoxIcon icon = MessageBoxIcon.None) - { - var win = new ModalWindow - { - Caption = caption, - Button = button, - MessageBoxImage = icon, - TextContent = text - }; - - win.ShowModal(this); - - return win.MessageBoxResult; - } - } -} diff --git a/MediaBrowser.UI/MediaBrowser.UI.csproj b/MediaBrowser.UI/MediaBrowser.UI.csproj deleted file mode 100644 index 1f8469cbcd..0000000000 --- a/MediaBrowser.UI/MediaBrowser.UI.csproj +++ /dev/null @@ -1,1330 +0,0 @@ - - - - - Debug - AnyCPU - {B5ECE1FB-618E-420B-9A99-8E972D76920A} - WinExe - Properties - MediaBrowser.UI - MediaBrowser.UI - v4.5 - 512 - {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - 4 - true - ..\ - true - http://www.mb3admin.com/downloads/stdui/ - true - Web - false - Background - 7 - Days - false - false - true - http://forum.mediabrowser3.com - Media Browser Theater - Media Browser Team - Media Browser 3 - 2646 - 2.9.4795.2646 - false - true - true - true - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - Resources\Images\Icon.ico - - - 9633DCDB4A07D3328EFB99299C6DFB1823EBC4BE - - - MediaBrowser.UI_TemporaryKey.pfx - - - true - - - true - - - http://timestamp.verisign.com/scripts/timstamp.dll - - - x86 - bin\x86\Debug\ - - - x86 - bin\x86\Release\ - - - - true - - - - ..\ThirdParty\Taygeta\Declarations.dll - - - ..\ThirdParty\Taygeta\Implementation.dll - - - ..\ThirdParty\Taygeta\LibVlcWrapper.dll - - - ..\packages\MahApps.Metro.0.10.1.21-ALPHA\lib\net40\MahApps.Metro.dll - - - False - ..\ThirdParty\Expression\Microsoft.Expression.Effects.dll - - - False - ..\ThirdParty\Expression\Microsoft.Expression.Interactions.dll - - - ..\packages\NLog.2.0.0.2000\lib\net40\NLog.dll - - - False - ..\packages\protobuf-net.2.0.0.621\lib\net40\protobuf-net.dll - - - ..\packages\SimpleInjector.2.0.0-beta5\lib\net40-client\SimpleInjector.dll - - - - - - - - - - ..\packages\MahApps.Metro.0.10.1.21-ALPHA\lib\net40\System.Windows.Interactivity.dll - - - - - - - - 4.0 - - - - - - - - - - - - - - NavigationBar.xaml - - - ModalWindow.xaml - - - NotificationMessage.xaml - - - - HiddenWindow.xaml - - - ImageViewerWindow.xaml - - - - - - - - - - - - - - - - WindowCommands.xaml - - - - - - - - - - - - - - - - - - - - - MSBuild:Compile - Designer - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - MSBuild:Compile - Designer - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - MSBuild:Compile - Designer - - - App.xaml - Code - - - - - MainWindow.xaml - Code - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - - - - SettingsPage.xaml - - - Code - - - True - True - Resources.resx - - - True - Settings.settings - True - - - ResXFileCodeGenerator - Resources.Designer.cs - - - - - SettingsSingleFileGenerator - Settings.Designer.cs - - - - - - Designer - - - - - {921c0f64-fda7-4e9f-9e73-0cb0eedb2422} - MediaBrowser.ApiInteraction - - - {cc96bf3e-0bda-4809-bc4b-bb6d418f4a84} - MediaBrowser.ClickOnce - - - {9142eefa-7570-41e1-bfcc-468bb571af2f} - MediaBrowser.Common - - - {5356ae30-6a6e-4a64-81e3-f76c50595e64} - MediaBrowser.IsoMounter - - - {67310740-0ec4-4dc2-9921-33df38b20167} - MediaBrowser.Logging.NLog - - - {7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b} - MediaBrowser.Model - - - {1adfe460-fd95-46fa-8871-cccb4b62e2e8} - MediaBrowser.UI.Controls - - - {e4be0659-4084-407b-b8a8-67802331cc9e} - MediaBrowser.UI.Uninstall - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - False - Microsoft .NET Framework 4.5 %28x86 and x64%29 - true - - - False - .NET Framework 3.5 SP1 Client Profile - false - - - False - .NET Framework 3.5 SP1 - false - - - False - Visual C++ 2010 Runtime Libraries %28x86%29 - true - - - - - - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - - - - - - - - - - False - - - - - Include - True - Assembly - - - - - - xcopy "$(TargetPath)" "$(SolutionDir)\Nuget\dlls\" /y /d /r /i - - - \ No newline at end of file diff --git a/MediaBrowser.UI/MediaBrowser.UI_TemporaryKey.pfx b/MediaBrowser.UI/MediaBrowser.UI_TemporaryKey.pfx deleted file mode 100644 index 8a983ab8cdbf8a500bce0d6ead68ccd520b3b6df..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1676 zcmY*Yc{tR082`>;#vCLDk%_em)o2D83|fkuxuT0H)82k#$hm|6u5G zWu#(Vjl1>SLeLN#j_yIS;W?6m^2LGU$-Fb^6CO+>LR5b*X-Z}3bUrcY8>Wl3-{nkE z0eVKQn56jfMQ1&J^p@Oh^^nX<@9Ey)^4 zbJP-=wIq~{MaRppHhw$jnzB5Qo2)U=OW1x3+Q=_kl0H-6Ahi^}JT=g*T8)xVD+N zUmHlVMHeIu`5_i&-m}@9K|?_y7OU{4#ZO9a+}?p$?Y}Lez5BMV$^0dc0+eYj-D0_I zu79Vf>0Rvj^KD%n^{GX(uQ3I>u z+m;%Ro~n}9yvdNZZ=f{h_vP+0^Ra)1aMLY57K;C?|L>r|jU}gEMcGIuj*dRe#04Hi zPsddPnFCXsx2F1Eb5~~k9vJw5QxCPqOL@? zxEN#*DBDyS{?{&)FjJ2F5ZUU1*A*Oa)`(Pp@~zbkg*I91Op4+8gvl+7P3P{r@H0k8 zz4G|H?4}nNGyHctZF@5xxEUMlQ&qiNcwdL?88VKidzo=&+N#bX1;ZWQH#Z=NHh+q6 z;lmEqdxm4R72NrAEMMI{dtIruFq5ohX=3U(`BRvG2!gYFoT*jr zwIGgLZ=tO`E|~UujjK{y612u_X?~UY>cd2T@lv1XV&nd#ViR#xoWW3i9Bq=PsiyFL zodOj$`-n^<>yptZg-yx`xHghtWKRS>@9fHUjV%uFDu<$<>%0DeB; - /// Provides a base class for detail pages - /// - public abstract class BaseDetailPage : BasePage - { - /// - /// The _item id - /// - private string _itemId; - /// - /// Gets or sets the id of the item being displayed - /// - /// The item id. - protected string ItemId - { - get { return _itemId; } - private set - { - _itemId = value; - OnPropertyChanged("ItemId"); - } - } - - /// - /// The _item - /// - private BaseItemDto _item; - /// - /// Gets or sets the item. - /// - /// The item. - public BaseItemDto Item - { - get { return _item; } - - set - { - _item = value; - OnPropertyChanged("Item"); - OnItemChanged(); - } - } - - /// - /// Gets a value indicating whether this instance can resume. - /// - /// true if this instance can resume; otherwise, false. - protected bool CanResume - { - get { return Item.CanResume; } - } - - /// - /// Gets a value indicating whether this instance can queue. - /// - /// true if this instance can queue; otherwise, false. - protected bool CanQueue - { - get { return true; } - } - - /// - /// Gets a value indicating whether this instance can play trailer. - /// - /// true if this instance can play trailer; otherwise, false. - protected bool CanPlayTrailer - { - get { return Item.HasTrailer; } - } - - /// - /// Initializes a new instance of the class. - /// - /// The item id. - protected BaseDetailPage(string itemId) - : base() - { - ItemId = itemId; - } - - /// - /// Called when [property changed]. - /// - /// The name. - public async override void OnPropertyChanged(string name) - { - base.OnPropertyChanged(name); - - // Reload the item when the itemId changes - if (name.Equals("ItemId")) - { - await ReloadItem(); - } - } - - /// - /// Reloads the item. - /// - /// Task. - private async Task ReloadItem() - { - try - { - Item = await App.Instance.ApiClient.GetItemAsync(ItemId, App.Instance.CurrentUser.Id); - } - catch (HttpException) - { - App.Instance.ShowDefaultErrorMessage(); - } - } - - /// - /// Called when [item changed]. - /// - protected virtual void OnItemChanged() - { - SetBackdrops(Item); - } - - /// - /// Plays this instance. - /// - public async void Play() - { - await UIKernel.Instance.PlaybackManager.Play(new PlayOptions - { - Items = new List { Item } - }); - } - - /// - /// Resumes this instance. - /// - public async void Resume() - { - await UIKernel.Instance.PlaybackManager.Play(new PlayOptions - { - Items = new List { Item }, - Resume = true - }); - } - - /// - /// Queues this instance. - /// - public void Queue() - { - } - } -} diff --git a/MediaBrowser.UI/Pages/BaseFolderPage.cs b/MediaBrowser.UI/Pages/BaseFolderPage.cs deleted file mode 100644 index 52bddcd90e..0000000000 --- a/MediaBrowser.UI/Pages/BaseFolderPage.cs +++ /dev/null @@ -1,502 +0,0 @@ -using MediaBrowser.Model.Dto; -using MediaBrowser.Model.Entities; -using MediaBrowser.Model.Net; -using MediaBrowser.UI.ViewModels; -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; -using System.Threading.Tasks; -using System.Windows.Controls; - -namespace MediaBrowser.UI.Pages -{ - /// - /// Provides a base class for pages based on a folder item (list, home) - /// - public abstract class BaseFolderPage : BasePage - { - /// - /// Initializes a new instance of the class. - /// - /// The item id. - protected BaseFolderPage(string itemId) - : base() - { - ItemId = itemId; - } - - /// - /// The _item id - /// - private string _itemId; - /// - /// Gets or sets the Id of the item being displayed - /// - /// The item id. - protected string ItemId - { - get { return _itemId; } - private set - { - _itemId = value; - OnPropertyChanged("ItemId"); - } - } - - /// - /// The _index by - /// - private string _indexBy; - /// - /// Gets or sets the name of the current index function - /// - /// The index by. - public string IndexBy - { - get { return _indexBy; } - private set - { - _indexBy = value; - OnPropertyChanged("IndexBy"); - } - } - - /// - /// The _sort by - /// - private string _sortBy; - /// - /// Gets or sets the name of the current sort function - /// - /// The sort by. - public string SortBy - { - get { return _sortBy; } - private set - { - _sortBy = value; - OnPropertyChanged("SortBy"); - } - } - - /// - /// The _folder - /// - private BaseItemDto _folder; - /// - /// Gets or sets the Folder being displayed - /// - /// The folder. - public BaseItemDto Folder - { - get { return _folder; } - - set - { - _folder = value; - OnPropertyChanged("Folder"); - OnFolderChanged(); - ReloadChildren(); - } - } - - /// - /// If wrap panels are being used this will get the orientation that should be used, based on scroll direction - /// - /// The wrap panel orientation. - public Orientation WrapPanelOrientation - { - get - { - return DisplayPreferences.ScrollDirection == ScrollDirection.Horizontal ? Orientation.Vertical : Orientation.Horizontal; - } - } - - /// - /// The _display preferences - /// - private DisplayPreferences _displayPreferences; - /// - /// Gets of sets the current DisplayPreferences - /// - /// The display preferences. - public DisplayPreferences DisplayPreferences - { - get { return _displayPreferences; } - - private set - { - _displayPreferences = value; - - // If the page is using it's own image type and not honoring the DisplayPreferences setting, set it now - if (_displayPreferences != null && FixedImageType.HasValue) - { - _displayPreferences.PrimaryImageType = FixedImageType.Value; - } - - NotifyDisplayPreferencesChanged(); - } - } - - /// - /// The _children - /// - private ItemsResult _children; - /// - /// Gets or sets the children of the Folder being displayed - /// - /// The children. - public ItemsResult Children - { - get { return _children; } - - private set - { - _children = value; - OnPropertyChanged("Children"); - ChildCount = _children.TotalRecordCount; - OnChildrenChanged(); - - DisplayChildren = DtoBaseItemViewModel.GetObservableItems(Children.Items, AveragePrimaryImageAspectRatio, DisplayPreferences); - } - } - - /// - /// The _display children - /// - private ObservableCollection _displayChildren; - /// - /// Gets the actual children that should be displayed. - /// Subclasses should bind to this, not Children. - /// - /// The display children. - public ObservableCollection DisplayChildren - { - get { return _displayChildren; } - - private set - { - _displayChildren = value; - OnPropertyChanged("DisplayChildren"); - } - } - - /// - /// The _child count - /// - private int _childCount; - /// - /// Gets or sets the number of children within the Folder - /// - /// The child count. - public int ChildCount - { - get { return _childCount; } - - private set - { - _childCount = value; - OnPropertyChanged("ChildCount"); - } - } - - /// - /// If the page is using it's own image type and not honoring the DisplayPreferences setting, it should return it here - /// - /// The type of the fixed image. - protected virtual ImageType? FixedImageType - { - get { return null; } - } - - /// - /// The _average primary image aspect ratio - /// - private double _averagePrimaryImageAspectRatio; - /// - /// Gets or sets the average primary image aspect ratio for all items - /// - /// The average primary image aspect ratio. - public double AveragePrimaryImageAspectRatio - { - get { return _averagePrimaryImageAspectRatio; } - - private set - { - _averagePrimaryImageAspectRatio = value; - OnPropertyChanged("AveragePrimaryImageAspectRatio"); - } - } - - /// - /// Gets the aspect ratio that should be used based on a given ImageType - /// - /// Type of the image. - /// System.Double. - public double GetAspectRatio(ImageType imageType) - { - return GetAspectRatio(imageType, AveragePrimaryImageAspectRatio); - } - - /// - /// Gets the aspect ratio that should be used based on a given ImageType - /// - /// Type of the image. - /// The average primary image aspect ratio. - /// System.Double. - public static double GetAspectRatio(ImageType imageType, double averagePrimaryImageAspectRatio) - { - switch (imageType) - { - case ImageType.Art: - return 1.777777777777778; - case ImageType.Backdrop: - return 1.777777777777778; - case ImageType.Banner: - return 5.414285714285714; - case ImageType.Disc: - return 1; - case ImageType.Logo: - return 1.777777777777778; - case ImageType.Primary: - return averagePrimaryImageAspectRatio; - case ImageType.Thumb: - return 1.777777777777778; - default: - return 1; - } - } - - /// - /// Called when [property changed]. - /// - /// The name. - public async override void OnPropertyChanged(string name) - { - base.OnPropertyChanged(name); - - // Reload the Folder when the itemId changes - if (name.Equals("ItemId")) - { - await ReloadFolder(); - } - } - - /// - /// Reloads the folder - /// - /// Task. - private async Task ReloadFolder() - { - try - { - if (string.IsNullOrEmpty(ItemId)) - { - Folder = await App.Instance.ApiClient.GetRootFolderAsync(App.Instance.CurrentUser.Id); - } - else - { - Folder = await App.Instance.ApiClient.GetItemAsync(ItemId, App.Instance.CurrentUser.Id); - } - } - catch (HttpException) - { - App.Instance.ShowDefaultErrorMessage(); - } - } - - /// - /// Gets called anytime the Folder gets refreshed - /// - protected virtual void OnFolderChanged() - { - SetBackdrops(Folder); - - DisplayPreferences = Folder.DisplayPreferences; - - if (DisplayPreferences.RememberIndexing) - { - IndexBy = DisplayPreferences.IndexBy; - } - - if (DisplayPreferences.RememberSorting) - { - SortBy = DisplayPreferences.SortBy ?? Folder.SortOptions.FirstOrDefault(); - } - else if (string.IsNullOrEmpty(SortBy)) - { - SortBy = Folder.SortOptions.FirstOrDefault(); - } - } - - /// - /// Gets called anytime the Children get refreshed - /// - protected virtual void OnChildrenChanged() - { - AveragePrimaryImageAspectRatio = DtoBaseItemViewModel.GetAveragePrimaryImageAspectRatio(Children.Items); - - if (DisplayPreferences != null) - { - DisplayPreferences.PrimaryImageWidth = Convert.ToInt32(DisplayPreferences.PrimaryImageHeight * GetAspectRatio(DisplayPreferences.PrimaryImageType)); - } - - NotifyDisplayPreferencesChanged(); - } - - /// - /// Reloads the Folder's children - /// - /// Task. - public async Task ReloadChildren() - { - var query = new ItemQuery - { - ParentId = Folder.Id, - - Fields = new[] { - ItemFields.UserData, - ItemFields.PrimaryImageAspectRatio - }, - - UserId = App.Instance.CurrentUser.Id, - - IndexBy = IndexBy, - - DynamicSortBy = SortBy - }; - - try - { - Children = await App.Instance.ApiClient.GetItemsAsync(query); - } - catch (HttpException) - { - App.Instance.ShowDefaultErrorMessage(); - } - } - - /// - /// Gets called anytime a DisplayPreferences property is updated - /// - public virtual void NotifyDisplayPreferencesChanged() - { - OnPropertyChanged("DisplayPreferences"); - - if (DisplayChildren != null) - { - // Notify all of the child view models - foreach (var child in DisplayChildren) - { - child.AveragePrimaryImageAspectRatio = AveragePrimaryImageAspectRatio; - child.NotifyDisplayPreferencesChanged(); - } - } - - OnPropertyChanged("WrapPanelOrientation"); - } - - /// - /// Changes the sort option on the page - /// - /// The option. - /// Task. - public async Task UpdateSortOption(string option) - { - var tasks = new List(); - - SortBy = option; - - if (DisplayPreferences.RememberSorting) - { - DisplayPreferences.SortBy = option; - NotifyDisplayPreferencesChanged(); - - tasks.Add(Task.Run(async () => - { - try - { - await App.Instance.ApiClient.UpdateDisplayPreferencesAsync(App.Instance.CurrentUser.Id, Folder.Id, DisplayPreferences); - } - catch - { - App.Instance.ShowDefaultErrorMessage(); - } - })); - } - - tasks.Add(ReloadChildren()); - - await Task.WhenAll(tasks); - } - - /// - /// Changes the index option on the page - /// - /// The option. - /// Task. - public async Task UpdateIndexOption(string option) - { - var tasks = new List(); - - IndexBy = option; - - if (DisplayPreferences.RememberIndexing) - { - DisplayPreferences.IndexBy = option; - NotifyDisplayPreferencesChanged(); - - tasks.Add(Task.Run(async () => - { - try - { - await App.Instance.ApiClient.UpdateDisplayPreferencesAsync(App.Instance.CurrentUser.Id, Folder.Id, DisplayPreferences); - } - catch - { - App.Instance.ShowDefaultErrorMessage(); - } - })); - } - - tasks.Add(ReloadChildren()); - - await Task.WhenAll(tasks); - } - - /// - /// Updates the index of the remember. - /// - /// if set to true [remember]. - /// Task. - public async Task UpdateRememberIndex(bool remember) - { - DisplayPreferences.RememberIndexing = remember; - - if (remember) - { - DisplayPreferences.IndexBy = IndexBy; - } - - await App.Instance.ApiClient.UpdateDisplayPreferencesAsync(App.Instance.CurrentUser.Id, Folder.Id, DisplayPreferences); - } - - /// - /// Updates the remember sort. - /// - /// if set to true [remember]. - /// Task. - public async Task UpdateRememberSort(bool remember) - { - DisplayPreferences.RememberSorting = remember; - - if (remember) - { - DisplayPreferences.SortBy = SortBy; - } - - await App.Instance.ApiClient.UpdateDisplayPreferencesAsync(App.Instance.CurrentUser.Id, Folder.Id, DisplayPreferences); - } - } -} diff --git a/MediaBrowser.UI/Pages/BaseHomePage.cs b/MediaBrowser.UI/Pages/BaseHomePage.cs deleted file mode 100644 index 6fb41b966a..0000000000 --- a/MediaBrowser.UI/Pages/BaseHomePage.cs +++ /dev/null @@ -1,17 +0,0 @@ - -namespace MediaBrowser.UI.Pages -{ - public abstract class BaseHomePage : BaseFolderPage - { - protected BaseHomePage() - : base(string.Empty) - { - } - - protected override void OnLoaded() - { - base.OnLoaded(); - ClearBackdrops(); - } - } -} diff --git a/MediaBrowser.UI/Pages/BaseInternalPlayerPage.cs b/MediaBrowser.UI/Pages/BaseInternalPlayerPage.cs deleted file mode 100644 index 3d651c4fa9..0000000000 --- a/MediaBrowser.UI/Pages/BaseInternalPlayerPage.cs +++ /dev/null @@ -1,49 +0,0 @@ -using MediaBrowser.UI.Controller; -using MediaBrowser.UI.Playback; -using System.Windows; - -namespace MediaBrowser.UI.Pages -{ - /// - /// Class BaseInternalPlayerPage - /// - public abstract class BaseInternalPlayerPage : BasePage - { - /// - /// Called when [loaded]. - /// - protected override void OnLoaded() - { - base.OnLoaded(); - - App.Instance.ApplicationWindow.WindowBackgroundContent.Visibility = Visibility.Collapsed; - App.Instance.ApplicationWindow.PageContent.Visibility = Visibility.Collapsed; - - UIKernel.Instance.PlaybackManager.PlaybackCompleted -= PlaybackManager_PlaybackCompleted; - UIKernel.Instance.PlaybackManager.PlaybackCompleted += PlaybackManager_PlaybackCompleted; - } - - /// - /// Handles the PlaybackCompleted event of the PlaybackManager control. - /// - /// The source of the event. - /// The instance containing the event data. - void PlaybackManager_PlaybackCompleted(object sender, PlaybackStopEventArgs e) - { - App.Instance.ApplicationWindow.NavigateBack(); - } - - /// - /// Called when [unloaded]. - /// - protected override void OnUnloaded() - { - UIKernel.Instance.PlaybackManager.PlaybackCompleted -= PlaybackManager_PlaybackCompleted; - - base.OnUnloaded(); - - App.Instance.ApplicationWindow.PageContent.Visibility = Visibility.Visible; - App.Instance.ApplicationWindow.WindowBackgroundContent.Visibility = Visibility.Visible; - } - } -} diff --git a/MediaBrowser.UI/Pages/BaseListPage.cs b/MediaBrowser.UI/Pages/BaseListPage.cs deleted file mode 100644 index 5196e2b32f..0000000000 --- a/MediaBrowser.UI/Pages/BaseListPage.cs +++ /dev/null @@ -1,204 +0,0 @@ -using MediaBrowser.Model.Dto; -using MediaBrowser.Model.Entities; -using MediaBrowser.UI.Controls; -using MediaBrowser.UI.ViewModels; -using System; -using System.Threading; -using System.Windows.Controls; - -namespace MediaBrowser.UI.Pages -{ - /// - /// Provides a base page for all list pages - /// - public abstract class BaseListPage : BaseFolderPage - { - /// - /// Gets or sets the current selection timer. - /// - /// The current selection timer. - private Timer CurrentSelectionTimer { get; set; } - - /// - /// Subclasses must provide the list box that holds the items - /// - /// The items list. - protected abstract ExtendedListBox ItemsList { get; } - - /// - /// Initializes a new instance of the class. - /// - /// The item id. - protected BaseListPage(string itemId) - : base(itemId) - { - } - - /// - /// Raises the event. - /// - /// The instance containing the event data. - protected override void OnInitialized(EventArgs e) - { - base.OnInitialized(e); - - ItemsList.SelectionChanged += ItemsList_SelectionChanged; - ItemsList.ItemInvoked += ItemsList_ItemInvoked; - } - - /// - /// The _current item - /// - private BaseItemDto _currentItem; - /// - /// Gets or sets the current selected item - /// - /// The current item. - public BaseItemDto CurrentItem - { - get { return _currentItem; } - - set - { - _currentItem = value; - - // Update the current item index immediately - UpdateCurrentItemIndex(value); - - // Fire notification events after a short delay - // We don't want backdrops and logos reloading while the user is navigating quickly - if (CurrentSelectionTimer != null) - { - CurrentSelectionTimer.Change(500, Timeout.Infinite); - } - else - { - CurrentSelectionTimer = new Timer(CurrentItemChangedTimerCallback, value, 500, Timeout.Infinite); - } - } - } - - /// - /// Fires when the current item selection timer expires - /// - /// The state. - private void CurrentItemChangedTimerCallback(object state) - { - Dispatcher.InvokeAsync(() => - { - // Fire notification events for the UI - OnPropertyChanged("CurrentItem"); - - // Alert subclasses - OnCurrentItemChanged(); - }); - - // Dispose the timer - CurrentSelectionTimer.Dispose(); - CurrentSelectionTimer = null; - } - - /// - /// Updates the current item index based on the current selection - /// - /// The value. - private void UpdateCurrentItemIndex(BaseItemDto value) - { - if (value == null) - { - CurrentItemIndex = -1; - } - else - { - CurrentItemIndex = ItemsList.SelectedIndex; - } - } - - /// - /// The _current item index - /// - private int _currentItemIndex; - /// - /// Gets of sets the index of the current item being displayed - /// - /// The index of the current item. - public int CurrentItemIndex - { - get { return _currentItemIndex; } - - set - { - _currentItemIndex = value; - OnPropertyChanged("CurrentItemIndex"); - } - } - - /// - /// Handles the list selection changed event to update the current item - /// - /// The source of the event. - /// The instance containing the event data. - void ItemsList_SelectionChanged(object sender, SelectionChangedEventArgs e) - { - if (e.AddedItems.Count > 0) - { - CurrentItem = (e.AddedItems[0] as DtoBaseItemViewModel).Item; - } - else - { - CurrentItem = null; - } - } - - /// - /// Itemses the list_ item invoked. - /// - /// The sender. - /// The e. - /// - void ItemsList_ItemInvoked(object sender, ItemEventArgs e) - { - var model = e.Argument as DtoBaseItemViewModel; - - if (model != null) - { - App.Instance.NavigateToItem(model.Item); - } - } - - /// - /// Handles current item selection changes - /// - protected virtual void OnCurrentItemChanged() - { - if (CurrentItem != null) - { - SetBackdrops(CurrentItem); - } - } - - /// - /// Gets called anytime a DisplayPreferences property is updated - /// - public override void NotifyDisplayPreferencesChanged() - { - base.NotifyDisplayPreferencesChanged(); - - // Make sure the items list has been initialized - if (ItemsList != null) - { - if (DisplayPreferences.ScrollDirection == ScrollDirection.Horizontal) - { - ScrollViewer.SetHorizontalScrollBarVisibility(ItemsList, ScrollBarVisibility.Hidden); - ScrollViewer.SetVerticalScrollBarVisibility(ItemsList, ScrollBarVisibility.Disabled); - } - else - { - ScrollViewer.SetHorizontalScrollBarVisibility(ItemsList, ScrollBarVisibility.Disabled); - ScrollViewer.SetVerticalScrollBarVisibility(ItemsList, ScrollBarVisibility.Hidden); - } - } - } - - } -} diff --git a/MediaBrowser.UI/Pages/BaseLoginPage.cs b/MediaBrowser.UI/Pages/BaseLoginPage.cs deleted file mode 100644 index cc8f96427a..0000000000 --- a/MediaBrowser.UI/Pages/BaseLoginPage.cs +++ /dev/null @@ -1,119 +0,0 @@ -using MediaBrowser.Model.Dto; -using MediaBrowser.Model.Net; -using MediaBrowser.UI.Controls; -using System; -using System.Threading.Tasks; - -namespace MediaBrowser.UI.Pages -{ - /// - /// Provides a base page for theme login pages - /// - public abstract class BaseLoginPage : BasePage - { - /// - /// The _users - /// - private UserDto[] _users; - /// - /// Gets or sets the users. - /// - /// The users. - public UserDto[] Users - { - get { return _users; } - - set - { - _users = value; - OnPropertyChanged("Users"); - } - } - - /// - /// Subclasses must provide the list that holds the users - /// - /// The items list. - protected abstract ExtendedListBox ItemsList { get; } - - /// - /// Raises the event. - /// - /// The instance containing the event data. - protected override async void OnInitialized(EventArgs e) - { - base.OnInitialized(e); - - ItemsList.ItemInvoked += ItemsList_ItemInvoked; - - try - { - Users = await App.Instance.ApiClient.GetAllUsersAsync(); - } - catch (HttpException) - { - App.Instance.ShowErrorMessage("There was an error retrieving the list of users from the server."); - } - } - - /// - /// Called when [loaded]. - /// - protected override void OnLoaded() - { - base.OnLoaded(); - ClearBackdrops(); - } - - /// - /// Logs in a user when one is selected - /// - /// The sender. - /// The e. - async void ItemsList_ItemInvoked(object sender, ItemEventArgs e) - { - var user = (UserDto)e.Argument; - - try - { - await LoginUser(user); - } - catch (HttpException ex) - { - if (ex.StatusCode.HasValue && ex.StatusCode.Value == System.Net.HttpStatusCode.Unauthorized) - { - App.Instance.ShowErrorMessage("Invalid username or password. Please try again.", caption: "Login Failure"); - } - else - { - App.Instance.ShowDefaultErrorMessage(); - } - } - } - - /// - /// Logs in a user and verifies their password - /// - /// The user. - /// The password. - /// Task{AuthenticationResult}. - protected async Task LoginUser(UserDto user, string password) - { - await App.Instance.ApiClient.AuthenticateUserAsync(user.Id, password); - - App.Instance.CurrentUser = user; - - App.Instance.NavigateToHomePage(); - } - - /// - /// Logs in a user who does not have a password - /// - /// The user. - /// Task{AuthenticationResult}. - protected Task LoginUser(UserDto user) - { - return LoginUser(user, null); - } - } -} diff --git a/MediaBrowser.UI/Pages/BasePage.cs b/MediaBrowser.UI/Pages/BasePage.cs deleted file mode 100644 index 667a29ff37..0000000000 --- a/MediaBrowser.UI/Pages/BasePage.cs +++ /dev/null @@ -1,71 +0,0 @@ -using MediaBrowser.Model.Dto; -using System; -using System.ComponentModel; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Input; - -namespace MediaBrowser.UI.Pages -{ - /// - /// Provides a common base page for all pages - /// - public abstract class BasePage : Page, INotifyPropertyChanged - { - public event PropertyChangedEventHandler PropertyChanged; - - public virtual void OnPropertyChanged(string name) - { - if (PropertyChanged != null) - { - PropertyChanged(this, new PropertyChangedEventArgs(name)); - } - } - - protected override void OnInitialized(EventArgs e) - { - Loaded += BasePageLoaded; - Unloaded += BasePage_Unloaded; - - base.OnInitialized(e); - - DataContext = this; - } - - void BasePage_Unloaded(object sender, RoutedEventArgs e) - { - OnUnloaded(); - } - - void BasePageLoaded(object sender, RoutedEventArgs e) - { - OnLoaded(); - } - - protected virtual void OnLoaded() - { - // Give focus to the first element - MoveFocus(new TraversalRequest(FocusNavigationDirection.First)); - } - - protected virtual void OnUnloaded() - { - } - - /// - /// Sets the backdrop based on a BaseItemDto - /// - public void SetBackdrops(BaseItemDto item) - { - App.Instance.ApplicationWindow.SetBackdrops(item); - } - - /// - /// Clears current backdrops - /// - public void ClearBackdrops() - { - App.Instance.ApplicationWindow.ClearBackdrops(); - } - } -} diff --git a/MediaBrowser.UI/Pages/BaseWeatherPage.cs b/MediaBrowser.UI/Pages/BaseWeatherPage.cs deleted file mode 100644 index 6497967de2..0000000000 --- a/MediaBrowser.UI/Pages/BaseWeatherPage.cs +++ /dev/null @@ -1,7 +0,0 @@ - -namespace MediaBrowser.UI.Pages -{ - public class BaseWeatherPage : BasePage - { - } -} diff --git a/MediaBrowser.UI/Pages/SettingsPage.xaml b/MediaBrowser.UI/Pages/SettingsPage.xaml deleted file mode 100644 index 27b4383515..0000000000 --- a/MediaBrowser.UI/Pages/SettingsPage.xaml +++ /dev/null @@ -1,16 +0,0 @@ - - - - Settings Page - - - - diff --git a/MediaBrowser.UI/Pages/SettingsPage.xaml.cs b/MediaBrowser.UI/Pages/SettingsPage.xaml.cs deleted file mode 100644 index db273bbe5a..0000000000 --- a/MediaBrowser.UI/Pages/SettingsPage.xaml.cs +++ /dev/null @@ -1,14 +0,0 @@ - -namespace MediaBrowser.UI.Pages -{ - /// - /// Interaction logic for SettingsPage.xaml - /// - public partial class SettingsPage : BasePage - { - public SettingsPage() - { - InitializeComponent(); - } - } -} diff --git a/MediaBrowser.UI/Playback/BaseMediaPlayer.cs b/MediaBrowser.UI/Playback/BaseMediaPlayer.cs deleted file mode 100644 index 6e3324b053..0000000000 --- a/MediaBrowser.UI/Playback/BaseMediaPlayer.cs +++ /dev/null @@ -1,747 +0,0 @@ -using MediaBrowser.Common.Events; -using MediaBrowser.Model.Dto; -using MediaBrowser.Model.Logging; -using MediaBrowser.Model.Net; -using MediaBrowser.UI.Configuration; -using MediaBrowser.UI.Controller; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; - -namespace MediaBrowser.UI.Playback -{ - /// - /// Class BaseMediaPlayer - /// - public abstract class BaseMediaPlayer : IDisposable - { - /// - /// Gets the logger. - /// - /// The logger. - protected ILogger Logger { get; private set; } - - #region VolumeChanged - /// - /// Occurs when [volume changed]. - /// - public event EventHandler VolumeChanged; - protected void OnVolumeChanged() - { - EventHelper.FireEventIfNotNull(VolumeChanged, this, EventArgs.Empty, Logger); - } - #endregion - - #region PlayStateChanged - /// - /// Occurs when [play state changed]. - /// - public event EventHandler PlayStateChanged; - protected void OnPlayStateChanged() - { - EventHelper.FireEventIfNotNull(PlayStateChanged, this, EventArgs.Empty, Logger); - } - #endregion - - /// - /// The null task result - /// - protected Task NullTaskResult = Task.FromResult(false); - - /// - /// Gets a value indicating whether [supports multi file playback]. - /// - /// true if [supports multi file playback]; otherwise, false. - public abstract bool SupportsMultiFilePlayback { get; } - - /// - /// The currently playing items - /// - public List Playlist = new List(); - - /// - /// The _play state - /// - private PlayState _playState; - /// - /// Gets or sets the state of the play. - /// - /// The state of the play. - public PlayState PlayState - { - get - { - return _playState; - } - set - { - _playState = value; - - OnPlayStateChanged(); - } - } - - /// - /// Gets or sets a value indicating whether this is mute. - /// - /// true if mute; otherwise, false. - public bool Mute - { - get { return IsMuted; } - set - { - SetMute(value); - OnVolumeChanged(); - } - } - - /// - /// Gets or sets the volume. - /// - /// The volume. - public int Volume - { - get { return GetVolume(); } - set - { - SetVolume(value); - OnVolumeChanged(); - } - } - - /// - /// Gets the current player configuration. - /// - /// The current player configuration. - public PlayerConfiguration CurrentPlayerConfiguration { get; private set; } - - /// - /// Gets the current play options. - /// - /// The current play options. - public PlayOptions CurrentPlayOptions { get; private set; } - - /// - /// Gets the name. - /// - /// The name. - public abstract string Name { get; } - - /// - /// Determines whether this instance can play the specified item. - /// - /// The item. - /// true if this instance can play the specified item; otherwise, false. - public abstract bool CanPlay(BaseItemDto item); - - /// - /// Gets a value indicating whether this instance can change volume. - /// - /// true if this instance can change volume; otherwise, false. - public abstract bool CanControlVolume { get; } - - /// - /// Gets a value indicating whether this instance can mute. - /// - /// true if this instance can mute; otherwise, false. - public abstract bool CanMute { get; } - - /// - /// Gets a value indicating whether this instance can queue. - /// - /// true if this instance can queue; otherwise, false. - public abstract bool CanQueue { get; } - - /// - /// Gets a value indicating whether this instance can pause. - /// - /// true if this instance can pause; otherwise, false. - public abstract bool CanPause { get; } - - /// - /// Gets a value indicating whether this instance can seek. - /// - /// true if this instance can seek; otherwise, false. - public abstract bool CanSeek { get; } - - /// - /// Gets the index of the current playlist. - /// - /// The index of the current playlist. - public virtual int CurrentPlaylistIndex - { - get { return 0; } - } - - /// - /// Gets the current media. - /// - /// The current media. - public BaseItemDto CurrentMedia - { - get - { - return CurrentPlaylistIndex == -1 ? null : Playlist[CurrentPlaylistIndex]; - } - } - - /// - /// Gets the current position ticks. - /// - /// The current position ticks. - public virtual long? CurrentPositionTicks - { - get - { - return null; - } - } - - /// - /// Gets a value indicating whether this instance is muted. - /// - /// true if this instance is muted; otherwise, false. - protected virtual bool IsMuted - { - get { return false; } - } - - /// - /// Initializes a new instance of the class. - /// - protected BaseMediaPlayer(ILogger logger) - { - Logger = logger; - } - - /// - /// Sets the mute. - /// - /// if set to true [mute]. - protected virtual void SetMute(bool mute) - { - } - - /// - /// Sets the volume, on a scale from 0-100 - /// - /// The value. - protected virtual void SetVolume(int value) - { - } - - /// - /// Gets the volume. - /// - /// System.Int32. - protected virtual int GetVolume() - { - return 0; - } - - /// - /// Plays the internal. - /// - /// The items. - /// The options. - /// The player configuration. - protected abstract void PlayInternal(List items, PlayOptions options, PlayerConfiguration playerConfiguration); - - /// - /// Queues the internal. - /// - /// The items. - protected virtual void QueueInternal(List items) - { - } - - /// - /// Stops the internal. - /// - /// Task. - protected abstract Task StopInternal(); - - /// - /// The play semaphore - /// - private readonly SemaphoreSlim PlaySemaphore = new SemaphoreSlim(1, 1); - - /// - /// Gets or sets the progress update timer. - /// - /// The progress update timer. - private Timer ProgressUpdateTimer { get; set; } - - /// - /// Gets a value indicating whether this instance can monitor progress. - /// - /// true if this instance can monitor progress; otherwise, false. - protected virtual bool CanMonitorProgress - { - get - { - return false; - } - } - - /// - /// Stops this instance. - /// - /// Task. - /// - public Task Stop() - { - var playstate = PlayState; - - if (playstate == PlayState.Playing || playstate == PlayState.Paused) - { - Logger.Info("Stopping"); - - return StopInternal(); - } - - throw new InvalidOperationException(string.Format("{0} is already {1}", Name, playstate)); - } - - /// - /// Plays the specified item. - /// - /// The options. - /// The player configuration. - /// Task. - /// items - internal async Task Play(PlayOptions options, PlayerConfiguration playerConfiguration) - { - if (options == null) - { - throw new ArgumentNullException("options"); - } - - await PlaySemaphore.WaitAsync(); - - PlayState = PlayState.Playing; - - lock (Playlist) - { - Playlist.Clear(); - Playlist.AddRange(options.Items); - } - - CurrentPlayerConfiguration = playerConfiguration; - CurrentPlayOptions = options; - - if (options.Items.Count > 1) - { - Logger.Info("Playing {0} items", options.Items.Count); - } - else - { - Logger.Info("Playing {0}", options.Items[0].Name); - } - - try - { - PlayInternal(options.Items, options, playerConfiguration); - } - catch (Exception ex) - { - Logger.Info("Error beginning playback", ex); - - CurrentPlayerConfiguration = null; - CurrentPlayOptions = null; - Playlist.Clear(); - - PlayState = PlayState.Idle; - PlaySemaphore.Release(); - - throw; - } - - SendPlaybackStartCheckIn(options.Items[0]); - - ReloadProgressUpdateTimer(); - } - - /// - /// Restarts the progress update timer. - /// - private void ReloadProgressUpdateTimer() - { - ProgressUpdateTimer = new Timer(OnProgressTimerStopped, null, TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(10)); - } - - /// - /// Called when [progress timer stopped]. - /// - /// The state. - private void OnProgressTimerStopped(object state) - { - var index = CurrentPlaylistIndex; - - if (index != -1) - { - SendPlaybackProgressCheckIn(Playlist[index], CurrentPositionTicks); - } - } - - /// - /// Queues the specified items. - /// - /// The items. - /// items - /// - internal void Queue(List items) - { - if (items == null) - { - throw new ArgumentNullException("items"); - } - - var playstate = PlayState; - - if (playstate != PlayState.Playing && playstate != PlayState.Paused) - { - throw new InvalidOperationException(string.Format("{0} cannot queue from playstate: {1}", Name, playstate)); - } - - lock (Playlist) - { - Playlist.AddRange(items); - } - - QueueInternal(items); - } - - /// - /// Called when [player stopped]. - /// - /// Last index of the playlist. - /// The position ticks. - protected void OnPlayerStopped(int? lastPlaylistIndex, long? positionTicks) - { - Logger.Info("Stopped"); - - if (positionTicks.HasValue && positionTicks.Value == 0) - { - positionTicks = null; - } - - var items = Playlist.ToList(); - - DisposeProgressUpdateTimer(); - - var index = lastPlaylistIndex ?? CurrentPlaylistIndex; - - var lastItem = items[index]; - SendPlaybackStopCheckIn(items[index], positionTicks); - - if (!CanMonitorProgress) - { - if (items.Count > 1) - { - MarkWatched(items.Except(new[] { lastItem })); - } - } - - OnPlayerStoppedInternal(); - - UIKernel.Instance.PlaybackManager.OnPlaybackCompleted(this, Playlist.ToList()); - - CurrentPlayerConfiguration = null; - CurrentPlayOptions = null; - Logger.Info("Clearing Playlist"); - Playlist.Clear(); - - PlayState = PlayState.Idle; - - PlaySemaphore.Release(); - } - - /// - /// Called when [player stopped internal]. - /// - protected virtual void OnPlayerStoppedInternal() - { - - } - - /// - /// Seeks the specified position ticks. - /// - /// The position ticks. - /// Task. - /// - public async Task Seek(long positionTicks) - { - var playState = PlayState; - - if (playState == PlayState.Playing || playState == PlayState.Paused) - { - await SeekInternal(positionTicks); - } - else - { - throw new InvalidOperationException(string.Format("Cannot seek {0} with playstate {1}", Name, PlayState)); - } - } - - /// - /// Seeks the internal. - /// - /// The position ticks. - /// Task. - protected virtual Task SeekInternal(long positionTicks) - { - return NullTaskResult; - } - - /// - /// The ten seconds - /// - private static readonly long TenSeconds = TimeSpan.FromSeconds(10).Ticks; - - /// - /// Goes to next chapter. - /// - /// Task. - public virtual Task GoToNextChapter() - { - var current = CurrentPositionTicks; - - var chapter = CurrentMedia.Chapters.FirstOrDefault(c => c.StartPositionTicks > current); - - return chapter != null ? Seek(chapter.StartPositionTicks) : NullTaskResult; - } - - /// - /// Goes to previous chapter. - /// - /// Task. - public virtual Task GoToPreviousChapter() - { - var current = CurrentPositionTicks; - - var chapter = CurrentMedia.Chapters.LastOrDefault(c => c.StartPositionTicks < current - TenSeconds); - - return chapter != null ? Seek(chapter.StartPositionTicks) : NullTaskResult; - } - - /// - /// Pauses this instance. - /// - /// Task. - /// - public async Task Pause() - { - if (PlayState == PlayState.Playing) - { - await PauseInternal(); - - PlayState = PlayState.Paused; - } - else - { - throw new InvalidOperationException(string.Format("Cannot pause {0} with playstate {1}", Name, PlayState)); - } - } - - /// - /// Pauses the internal. - /// - /// Task. - protected virtual Task PauseInternal() - { - return NullTaskResult; - } - - /// - /// Uns the pause. - /// - /// Task. - /// - public async Task UnPause() - { - if (PlayState == PlayState.Paused) - { - await UnPauseInternal(); - PlayState = PlayState.Playing; - } - else - { - throw new InvalidOperationException(string.Format("Cannot unpause {0} with playstate {1}", Name, PlayState)); - } - } - - /// - /// Uns the pause internal. - /// - /// Task. - protected virtual Task UnPauseInternal() - { - return NullTaskResult; - } - - /// - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// - public void Dispose() - { - Dispose(true); - } - - /// - /// Releases unmanaged and - optionally - managed resources. - /// - /// true to release both managed and unmanaged resources; false to release only unmanaged resources. - protected virtual void Dispose(bool dispose) - { - Logger.Info("Disposing"); - - DisposeProgressUpdateTimer(); - - if (PlayState == PlayState.Playing || PlayState == PlayState.Paused) - { - var index = CurrentPlaylistIndex; - - if (index != -1) - { - SendPlaybackStopCheckIn(Playlist[index], CurrentPositionTicks); - } - Task.Run(() => Stop()); - Thread.Sleep(1000); - } - - PlaySemaphore.Dispose(); - } - - /// - /// Disposes the progress update timer. - /// - private void DisposeProgressUpdateTimer() - { - if (ProgressUpdateTimer != null) - { - ProgressUpdateTimer.Dispose(); - } - } - - /// - /// Sends the playback start check in. - /// - /// The item. - protected async void SendPlaybackStartCheckIn(BaseItemDto item) - { - if (string.IsNullOrEmpty(item.Id)) - { - return; - } - - Logger.Info("Sending playback start checkin for {0}", item.Name); - - try - { - await UIKernel.Instance.ApiClient.ReportPlaybackStartAsync(item.Id, App.Instance.CurrentUser.Id); - } - catch (HttpException ex) - { - Logger.ErrorException("Error sending playback start checking for {0}", ex, item.Name); - } - } - - /// - /// Sends the playback progress check in. - /// - /// The item. - /// The position ticks. - protected async void SendPlaybackProgressCheckIn(BaseItemDto item, long? positionTicks) - { - if (string.IsNullOrEmpty(item.Id)) - { - return; - } - var position = positionTicks.HasValue ? TimeSpan.FromTicks(positionTicks.Value).ToString() : "unknown"; - - Logger.Info("Sending playback progress checkin for {0} at position {1}", item.Name, position); - - try - { - await UIKernel.Instance.ApiClient.ReportPlaybackProgressAsync(item.Id, App.Instance.CurrentUser.Id, positionTicks); - } - catch (HttpException ex) - { - Logger.ErrorException("Error sending playback progress checking for {0}", ex, item.Name); - } - } - - /// - /// Sends the playback stop check in. - /// - /// The item. - /// The position ticks. - protected async void SendPlaybackStopCheckIn(BaseItemDto item, long? positionTicks) - { - if (string.IsNullOrEmpty(item.Id)) - { - return; - } - var position = positionTicks.HasValue ? TimeSpan.FromTicks(positionTicks.Value).ToString() : "unknown"; - - Logger.Info("Sending playback stop checkin for {0} at position {1}", item.Name, position); - - try - { - await UIKernel.Instance.ApiClient.ReportPlaybackStoppedAsync(item.Id, App.Instance.CurrentUser.Id, positionTicks); - } - catch (HttpException ex) - { - Logger.ErrorException("Error sending playback stop checking for {0}", ex, item.Name); - } - } - - /// - /// Marks the watched. - /// - /// The items. - protected async void MarkWatched(IEnumerable items) - { - var idList = items.Where(i => !string.IsNullOrEmpty(i.Id)).Select(i => i.Id); - - try - { - await UIKernel.Instance.ApiClient.UpdatePlayedStatusAsync(idList.First(), App.Instance.CurrentUser.Id, true); - } - catch (HttpException ex) - { - Logger.ErrorException("Error marking items watched", ex); - } - } - - /// - /// Called when [media changed]. - /// - /// Old index of the playlist. - /// The ending position ticks. - /// New index of the playlist. - protected void OnMediaChanged(int oldPlaylistIndex, long? endingPositionTicks, int newPlaylistIndex) - { - DisposeProgressUpdateTimer(); - - Task.Run(() => - { - if (oldPlaylistIndex != -1) - { - SendPlaybackStopCheckIn(Playlist[oldPlaylistIndex], endingPositionTicks); - } - - if (newPlaylistIndex != -1) - { - SendPlaybackStartCheckIn(Playlist[newPlaylistIndex]); - } - }); - - ReloadProgressUpdateTimer(); - } - } -} diff --git a/MediaBrowser.UI/Playback/ExternalPlayer/BaseExternalPlayer.cs b/MediaBrowser.UI/Playback/ExternalPlayer/BaseExternalPlayer.cs deleted file mode 100644 index c50911d71c..0000000000 --- a/MediaBrowser.UI/Playback/ExternalPlayer/BaseExternalPlayer.cs +++ /dev/null @@ -1,243 +0,0 @@ -using MediaBrowser.Model.Dto; -using MediaBrowser.Model.Logging; -using MediaBrowser.UI.Configuration; -using MediaBrowser.UI.UserInput; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Threading.Tasks; -using System.Windows.Forms; - -namespace MediaBrowser.UI.Playback.ExternalPlayer -{ - /// - /// Class BaseExternalPlayer - /// - public abstract class BaseExternalPlayer : BaseMediaPlayer - { - protected BaseExternalPlayer(ILogger logger) : base(logger) - { - } - - /// - /// Gets a value indicating whether this instance can mute. - /// - /// true if this instance can mute; otherwise, false. - public override bool CanMute - { - get { return false; } - } - - /// - /// Gets a value indicating whether this instance can change volume. - /// - /// true if this instance can change volume; otherwise, false. - public override bool CanControlVolume - { - get { return false; } - } - - /// - /// Gets a value indicating whether this instance can close automatically. - /// - /// true if this instance can close automatically; otherwise, false. - protected virtual bool CanCloseAutomatically - { - get - { - return false; - } - } - - /// - /// Gets a value indicating whether [supports multi file playback]. - /// - /// true if [supports multi file playback]; otherwise, false. - public override bool SupportsMultiFilePlayback - { - get - { - return false; - } - } - - /// - /// Gets the current process. - /// - /// The current process. - protected Process CurrentProcess { get; private set; } - - /// - /// Gets the process start info. - /// - /// The items. - /// The options. - /// The player configuration. - /// ProcessStartInfo. - protected virtual ProcessStartInfo GetProcessStartInfo(List items, PlayOptions options, PlayerConfiguration playerConfiguration) - { - return new ProcessStartInfo - { - FileName = playerConfiguration.Command, - Arguments = GetCommandArguments(items, options, playerConfiguration) - }; - } - - /// - /// Gets the command arguments. - /// - /// The items. - /// The options. - /// The player configuration. - /// System.String. - protected virtual string GetCommandArguments(List items, PlayOptions options, PlayerConfiguration playerConfiguration) - { - var args = playerConfiguration.Args; - - if (string.IsNullOrEmpty(args)) - { - return string.Empty; - } - - return GetCommandArguments(items, args); - } - - /// - /// Gets the command arguments. - /// - /// The items. - /// The format string. - /// System.String. - protected string GetCommandArguments(List items, string formatString) - { - var paths = items.Select(i => "\"" + GetPathForCommandLine(i) + "\""); - - return string.Format(formatString, string.Join(" ", paths.ToArray())); - } - - /// - /// Gets the path for command line. - /// - /// The item. - /// System.String. - protected virtual string GetPathForCommandLine(BaseItemDto item) - { - return item.Path; - } - - /// - /// Gets a value indicating whether this instance can queue. - /// - /// true if this instance can queue; otherwise, false. - public override bool CanQueue - { - get { return false; } - } - - /// - /// Gets a value indicating whether this instance can pause. - /// - /// true if this instance can pause; otherwise, false. - public override bool CanPause - { - get { return false; } - } - - /// - /// Gets a value indicating whether this instance can seek. - /// - /// true if this instance can seek; otherwise, false. - public override bool CanSeek - { - get { return false; } - } - - /// - /// Plays the internal. - /// - /// The items. - /// The options. - /// The player configuration. - protected override void PlayInternal(List items, PlayOptions options, PlayerConfiguration playerConfiguration) - { - CurrentProcess = new Process - { - EnableRaisingEvents = true, - StartInfo = GetProcessStartInfo(items, options, playerConfiguration) - }; - - Logger.Info("{0} {1}", CurrentProcess.StartInfo.FileName, CurrentProcess.StartInfo.Arguments); - - CurrentProcess.Start(); - - OnExternalPlayerLaunched(); - - if (!CanCloseAutomatically) - { - KeyboardListener.KeyDown += KeyboardListener_KeyDown; - } - - CurrentProcess.Exited += CurrentProcess_Exited; - } - - /// - /// Handles the KeyDown event of the KeyboardListener control. - /// - /// The source of the event. - /// The instance containing the event data. - void KeyboardListener_KeyDown(object sender, KeyEventArgs e) - { - if (e.KeyCode == Keys.MediaStop) - { - var playstate = PlayState; - - if (playstate == PlayState.Paused || playstate == PlayState.Playing) - { - Stop(); - } - } - } - - /// - /// Handles the Exited event of the CurrentProcess control. - /// - /// The source of the event. - /// The instance containing the event data. - void CurrentProcess_Exited(object sender, EventArgs e) - { - var process = (Process)sender; - - process.Dispose(); - - OnPlayerStopped(CurrentPlaylistIndex, CurrentPositionTicks); - } - - /// - /// Stops the internal. - /// - /// Task. - protected override Task StopInternal() - { - return Task.Run(() => CurrentProcess.Kill()); - } - - /// - /// Called when [player stopped internal]. - /// - protected override void OnPlayerStoppedInternal() - { - KeyboardListener.KeyDown -= KeyboardListener_KeyDown; - - base.OnPlayerStoppedInternal(); - } - - /// - /// Called when [external player launched]. - /// - protected virtual void OnExternalPlayerLaunched() - { - - } - } -} diff --git a/MediaBrowser.UI/Playback/ExternalPlayer/GenericExternalPlayer.cs b/MediaBrowser.UI/Playback/ExternalPlayer/GenericExternalPlayer.cs deleted file mode 100644 index 9150280507..0000000000 --- a/MediaBrowser.UI/Playback/ExternalPlayer/GenericExternalPlayer.cs +++ /dev/null @@ -1,35 +0,0 @@ -using MediaBrowser.Model.Dto; -using MediaBrowser.Model.Logging; - -namespace MediaBrowser.UI.Playback.ExternalPlayer -{ - /// - /// Class GenericExternalPlayer - /// - public class GenericExternalPlayer : BaseExternalPlayer - { - public GenericExternalPlayer(ILogger logger) - : base(logger) - { - } - - /// - /// Gets the name. - /// - /// The name. - public override string Name - { - get { return "Generic Player"; } - } - - /// - /// Determines whether this instance can play the specified item. - /// - /// The item. - /// true if this instance can play the specified item; otherwise, false. - public override bool CanPlay(BaseItemDto item) - { - return false; - } - } -} diff --git a/MediaBrowser.UI/Playback/InternalPlayer/BaseInternalMediaPlayer.cs b/MediaBrowser.UI/Playback/InternalPlayer/BaseInternalMediaPlayer.cs deleted file mode 100644 index e9178d3f53..0000000000 --- a/MediaBrowser.UI/Playback/InternalPlayer/BaseInternalMediaPlayer.cs +++ /dev/null @@ -1,54 +0,0 @@ -using MediaBrowser.Model.Dto; -using MediaBrowser.Model.Logging; -using MediaBrowser.UI.Configuration; -using System.Collections.Generic; -using System.Windows; - -namespace MediaBrowser.UI.Playback.InternalPlayer -{ - /// - /// Class BaseInternalMediaPlayer - /// - public abstract class BaseInternalMediaPlayer : BaseMediaPlayer - { - protected BaseInternalMediaPlayer(ILogger logger) : base(logger) - { - } - - /// - /// Ensures the media player created. - /// - protected abstract void EnsureMediaPlayerCreated(); - - /// - /// Plays the internal. - /// - /// The items. - /// The options. - /// The player configuration. - protected override void PlayInternal(List items, PlayOptions options, PlayerConfiguration playerConfiguration) - { - App.Instance.ApplicationWindow.Dispatcher.Invoke(() => - { - App.Instance.ApplicationWindow.BackdropContainer.Visibility = Visibility.Collapsed; - App.Instance.ApplicationWindow.WindowBackgroundContent.SetResourceReference(FrameworkElement.StyleProperty, "WindowBackgroundContentDuringPlayback"); - }); - - App.Instance.NavigateToInternalPlayerPage(); - } - - /// - /// Called when [player stopped internal]. - /// - protected override void OnPlayerStoppedInternal() - { - App.Instance.ApplicationWindow.Dispatcher.Invoke(() => - { - App.Instance.ApplicationWindow.BackdropContainer.Visibility = Visibility.Visible; - App.Instance.ApplicationWindow.WindowBackgroundContent.SetResourceReference(FrameworkElement.StyleProperty, "WindowBackgroundContent"); - }); - - base.OnPlayerStoppedInternal(); - } - } -} diff --git a/MediaBrowser.UI/Playback/NVlc/InternalMediaPlayerNVlc.cs b/MediaBrowser.UI/Playback/NVlc/InternalMediaPlayerNVlc.cs deleted file mode 100644 index 2d596655b5..0000000000 --- a/MediaBrowser.UI/Playback/NVlc/InternalMediaPlayerNVlc.cs +++ /dev/null @@ -1,426 +0,0 @@ -using Declarations.Events; -using Declarations.Media; -using Declarations.Players; -using Implementation; -using MediaBrowser.Model.Dto; -using MediaBrowser.Model.Entities; -using MediaBrowser.Model.Logging; -using MediaBrowser.UI.Configuration; -using MediaBrowser.UI.Playback.InternalPlayer; -using System; -using System.Collections.Generic; -using System.Drawing; -using System.IO; -using System.Linq; -using System.Threading.Tasks; -using System.Windows.Forms; - -namespace MediaBrowser.UI.Playback.NVlc -{ - /// - /// Class InternalMediaPlayer - /// - public class InternalMediaPlayerNVlc : BaseInternalMediaPlayer - { - public InternalMediaPlayerNVlc(ILogger logger) - : base(logger) - { - } - - /// - /// Gets or sets the media player factory. - /// - /// The media player factory. - private MediaPlayerFactory MediaPlayerFactory { get; set; } - - /// - /// Gets or sets the video player. - /// - /// The video player. - private IMediaListPlayer VideoPlayer { get; set; } - - /// - /// Gets or sets the media list. - /// - /// The media list. - private IMediaList MediaList { get; set; } - - /// - /// Gets a value indicating whether [supports multi file playback]. - /// - /// true if [supports multi file playback]; otherwise, false. - public override bool SupportsMultiFilePlayback - { - get { return true; } - } - - /// - /// Gets a value indicating whether this instance can mute. - /// - /// true if this instance can mute; otherwise, false. - public override bool CanMute - { - get { return true; } - } - - /// - /// Gets a value indicating whether this instance can change volume. - /// - /// true if this instance can change volume; otherwise, false. - public override bool CanControlVolume - { - get { return true; } - } - - /// - /// Gets a value indicating whether this instance is muted. - /// - /// true if this instance is muted; otherwise, false. - protected override bool IsMuted - { - get { return VideoPlayer != null && VideoPlayer.InnerPlayer.Mute; } - } - - /// - /// The _current playlist index - /// - private int _currentPlaylistIndex; - - /// - /// Gets the index of the current playlist. - /// - /// The index of the current playlist. - public override int CurrentPlaylistIndex - { - get - { - return _currentPlaylistIndex; - } - } - - /// - /// Gets the current position ticks. - /// - /// The current position ticks. - public override long? CurrentPositionTicks - { - get - { - if (VideoPlayer != null) - { - return TimeSpan.FromMilliseconds(VideoPlayer.Time).Ticks; - } - - return base.CurrentPositionTicks; - } - } - - /// - /// Gets a value indicating whether this instance can monitor progress. - /// - /// true if this instance can monitor progress; otherwise, false. - protected override bool CanMonitorProgress - { - get - { - return true; - } - } - - /// - /// Gets or sets the windows forms panel. - /// - /// The windows forms panel. - private Panel WindowsFormsPanel { get; set; } - - /// - /// Ensures the player. - /// - protected override void EnsureMediaPlayerCreated() - { - if (MediaPlayerFactory != null) - { - return; - } - - WindowsFormsPanel = new Panel(); - WindowsFormsPanel.BackColor = Color.Black; - - App.Instance.HiddenWindow.WindowsFormsHost.Child = WindowsFormsPanel; - - MediaPlayerFactory = new MediaPlayerFactory(new[] - { - "-I", - "dummy", - "--ignore-config", - "--no-osd", - "--disable-screensaver", - //"--ffmpeg-hw", - "--plugin-path=./plugins" - }); - } - - /// - /// Events_s the media changed. - /// - /// The sender. - /// The e. - void Events_MediaChanged(object sender, MediaPlayerMediaChanged e) - { - //var current = MediaList.FirstOrDefault(i => i.Tag == e.NewMedia.Tag); - - //var newIndex = current != null ? MediaList.IndexOf(current) : -1; - - //var currentIndex = _currentPlaylistIndex; - - //if (newIndex != currentIndex) - //{ - // OnMediaChanged(currentIndex, null, newIndex); - //} - - //_currentPlaylistIndex = newIndex; - } - - /// - /// Determines whether this instance can play the specified item. - /// - /// The item. - /// true if this instance can play the specified item; otherwise, false. - public override bool CanPlay(BaseItemDto item) - { - return item.IsVideo || item.IsAudio; - } - - /// - /// Gets a value indicating whether this instance can queue. - /// - /// true if this instance can queue; otherwise, false. - public override bool CanQueue - { - get { return true; } - } - - /// - /// Plays the internal. - /// - /// The items. - /// The options. - /// The player configuration. - protected override void PlayInternal(List items, PlayOptions options, PlayerConfiguration playerConfiguration) - { - EnsureMediaPlayerCreated(); - - _currentPlaylistIndex = 0; - - MediaList = MediaPlayerFactory.CreateMediaList(items.Select(GetPlayablePath)); - VideoPlayer = MediaPlayerFactory.CreateMediaListPlayer(MediaList); - - VideoPlayer.InnerPlayer.WindowHandle = WindowsFormsPanel.Handle; - - VideoPlayer.InnerPlayer.Events.PlayerStopped += Events_PlayerStopped; - VideoPlayer.Play(); - - var position = options.StartPositionTicks; - - if (position > 0) - { - VideoPlayer.Time = Convert.ToInt64(TimeSpan.FromTicks(position).TotalMilliseconds); - } - - VideoPlayer.MediaListPlayerEvents.MediaListPlayerNextItemSet += MediaListPlayerEvents_MediaListPlayerNextItemSet; - - base.PlayInternal(items, options, playerConfiguration); - } - - /// - /// Gets the playable path. - /// - /// The item. - /// System.String. - private string GetPlayablePath(BaseItemDto item) - { - if (item.VideoType.HasValue && item.VideoType.Value == VideoType.BluRay) - { - var file = Directory.EnumerateFiles(item.Path, "*.m2ts", SearchOption.AllDirectories).OrderByDescending(f => new FileInfo(f).Length).FirstOrDefault(); - - if (!string.IsNullOrEmpty(file)) - { - return file; - } - } - - return item.Path; - } - - /// - /// Medias the list player events_ media list player next item set. - /// - /// The sender. - /// The e. - void MediaListPlayerEvents_MediaListPlayerNextItemSet(object sender, MediaListPlayerNextItemSet e) - { - } - - /// - /// Gets the name. - /// - /// The name. - public override string Name - { - get { return "Internal Player"; } - } - - /// - /// Gets a value indicating whether this instance can pause. - /// - /// true if this instance can pause; otherwise, false. - public override bool CanPause - { - get { return true; } - } - - /// - /// Gets a value indicating whether this instance can seek. - /// - /// true if this instance can seek; otherwise, false. - public override bool CanSeek - { - get { return true; } - } - - /// - /// Queues the internal. - /// - /// The items. - protected override void QueueInternal(List items) - { - } - - /// - /// Seeks the internal. - /// - /// The position ticks. - /// Task. - protected override Task SeekInternal(long positionTicks) - { - return Task.Run(() => VideoPlayer.Time = Convert.ToInt64(TimeSpan.FromTicks(positionTicks).TotalMilliseconds)); - } - - /// - /// Pauses the internal. - /// - /// Task. - protected override Task PauseInternal() - { - return Task.Run(() => VideoPlayer.Pause()); - } - - /// - /// Uns the pause internal. - /// - /// Task. - protected override Task UnPauseInternal() - { - return Task.Run(() => VideoPlayer.Pause()); - } - - /// - /// Stops the internal. - /// - /// Task. - protected override Task StopInternal() - { - return Task.Run(() => VideoPlayer.Stop()); - } - - /// - /// Handles the PlayerStopped event of the Events control. - /// - /// The source of the event. - /// The instance containing the event data. - void Events_PlayerStopped(object sender, EventArgs e) - { - OnPlayerStopped(CurrentPlaylistIndex, CurrentPositionTicks); - } - - /// - /// Called when [player stopped]. - /// - protected override void OnPlayerStoppedInternal() - { - VideoPlayer.MediaListPlayerEvents.MediaListPlayerNextItemSet -= MediaListPlayerEvents_MediaListPlayerNextItemSet; - - MediaList.Dispose(); - - VideoPlayer.InnerPlayer.Events.PlayerStopped -= Events_PlayerStopped; - VideoPlayer.InnerPlayer.Dispose(); - - //VideoPlayer.Dispose(); - VideoPlayer = null; - - _currentPlaylistIndex = 0; - - base.OnPlayerStoppedInternal(); - } - - /// - /// Gets the volume. - /// - /// System.Int32. - protected override int GetVolume() - { - return VideoPlayer.InnerPlayer.Volume; - } - - /// - /// Sets the volume, on a scale from 0-100 - /// - /// The value. - protected override void SetVolume(int value) - { - if (value > 0 && VideoPlayer.InnerPlayer.Mute) - { - VideoPlayer.InnerPlayer.Mute = false; - } - - VideoPlayer.InnerPlayer.Volume = value; - } - - /// - /// Sets the mute. - /// - /// if set to true [mute]. - protected override void SetMute(bool mute) - { - VideoPlayer.InnerPlayer.Mute = mute; - } - - /// - /// Releases unmanaged and - optionally - managed resources. - /// - /// true to release both managed and unmanaged resources; false to release only unmanaged resources. - protected override void Dispose(bool dispose) - { - base.Dispose(dispose); - - if (dispose) - { - if (MediaList != null) - { - MediaList.Dispose(); - } - if (VideoPlayer != null) - { - if (VideoPlayer.InnerPlayer != null) - { - VideoPlayer.InnerPlayer.Dispose(); - } - } - if (MediaPlayerFactory != null) - { - MediaPlayerFactory.Dispose(); - } - } - } - } -} diff --git a/MediaBrowser.UI/Playback/PlayOptions.cs b/MediaBrowser.UI/Playback/PlayOptions.cs deleted file mode 100644 index 276e611b9c..0000000000 --- a/MediaBrowser.UI/Playback/PlayOptions.cs +++ /dev/null @@ -1,89 +0,0 @@ -using MediaBrowser.Model.Dto; -using System; -using System.Collections.Generic; - -namespace MediaBrowser.UI.Playback -{ - /// - /// Class PlayOptions - /// - public class PlayOptions - { - /// - /// Gets or sets the items. - /// - /// The items. - public List Items { get; set; } - - /// - /// If true, the PlayableItems will be shuffled before playback - /// - /// true if shuffle; otherwise, false. - public bool Shuffle { get; set; } - - /// - /// If true, Playback will be resumed from the last known position - /// - /// true if resume; otherwise, false. - public bool Resume { get; set; } - - private long? _startPositionTicks; - /// - /// Gets or sets the start position ticks. - /// - /// The start position ticks. - public long StartPositionTicks - { - get - { - if (_startPositionTicks.HasValue) - { - return _startPositionTicks.Value; - } - - if (Resume && Items.Count > 0) - { - var item = Items[0]; - - if (item.UserData != null) - { - return item.UserData.PlaybackPositionTicks; - } - } - - return 0; - } - set - { - _startPositionTicks = value; - } - } - - /// - /// Holds the time that playback was started - /// - /// The playback start time. - public DateTime PlaybackStartTime { get; private set; } - - /// - /// The _show now playing view - /// - private bool _showNowPlayingView = true; - /// - /// Determines whether or not the PlaybackController should show the now playing view during playback - /// Note that this depends on PlaybackController implementation and support - /// - /// true if [show now playing view]; otherwise, false. - public bool ShowNowPlayingView { get { return _showNowPlayingView; } set { _showNowPlayingView = value; } } - - /// - /// The _go full screen - /// - private bool _goFullScreen = true; - /// - /// Determines whether or not the PlaybackController should go full screen upon beginning playback - /// - /// true if [go full screen]; otherwise, false. - public bool GoFullScreen { get { return _goFullScreen; } set { _goFullScreen = value; } } - } -} diff --git a/MediaBrowser.UI/Playback/PlayState.cs b/MediaBrowser.UI/Playback/PlayState.cs deleted file mode 100644 index d166c4a776..0000000000 --- a/MediaBrowser.UI/Playback/PlayState.cs +++ /dev/null @@ -1,24 +0,0 @@ - -namespace MediaBrowser.UI.Playback -{ - /// - /// Enum PlayState - /// - public enum PlayState - { - /// - /// The idle - /// - Idle, - - /// - /// The playing - /// - Playing, - - /// - /// The paused - /// - Paused - } -} diff --git a/MediaBrowser.UI/Playback/PlaybackEventArgs.cs b/MediaBrowser.UI/Playback/PlaybackEventArgs.cs deleted file mode 100644 index a2eef782a6..0000000000 --- a/MediaBrowser.UI/Playback/PlaybackEventArgs.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System.Collections.Generic; -using MediaBrowser.Model.Dto; -using MediaBrowser.UI.Configuration; -using System; - -namespace MediaBrowser.UI.Playback -{ - /// - /// Class PlaybackEventArgs - /// - public class PlaybackEventArgs : EventArgs - { - /// - /// Gets or sets the player. - /// - /// The player. - public BaseMediaPlayer Player { get; set; } - - /// - /// Gets or sets the options. - /// - /// The options. - public PlayOptions Options { get; set; } - - /// - /// Gets or sets the player configuration. - /// - /// The player configuration. - public PlayerConfiguration PlayerConfiguration { get; set; } - } - - /// - /// Class PlaybackStopEventArgs - /// - public class PlaybackStopEventArgs : EventArgs - { - /// - /// Gets or sets the player. - /// - /// The player. - public BaseMediaPlayer Player { get; set; } - - /// - /// Gets or sets the items. - /// - /// The items. - public List Items { get; set; } - } -} diff --git a/MediaBrowser.UI/Playback/PlaybackManager.cs b/MediaBrowser.UI/Playback/PlaybackManager.cs deleted file mode 100644 index eedcad9b35..0000000000 --- a/MediaBrowser.UI/Playback/PlaybackManager.cs +++ /dev/null @@ -1,301 +0,0 @@ -using MediaBrowser.Common.Events; -using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.Kernel; -using MediaBrowser.Model.Dto; -using MediaBrowser.Model.Entities; -using MediaBrowser.Model.Logging; -using MediaBrowser.Model.Net; -using MediaBrowser.UI.Configuration; -using MediaBrowser.UI.Controller; -using MediaBrowser.UI.Playback.InternalPlayer; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading.Tasks; - -namespace MediaBrowser.UI.Playback -{ - /// - /// Class PlaybackManager - /// - public class PlaybackManager : BaseManager - { - private readonly ILogger _logger; - - /// - /// Initializes a new instance of the class. - /// - /// The kernel. - public PlaybackManager(UIKernel kernel, ILogger logger) - : base(kernel) - { - _logger = logger; - } - - #region PlaybackStarted Event - /// - /// Occurs when [playback started]. - /// - public event EventHandler PlaybackStarted; - - /// - /// Called when [playback started]. - /// - /// The player. - /// The options. - /// The player configuration. - private void OnPlaybackStarted(BaseMediaPlayer player, PlayOptions options, PlayerConfiguration playerConfiguration) - { - EventHelper.QueueEventIfNotNull(PlaybackStarted, this, new PlaybackEventArgs - { - Options = options, - Player = player, - PlayerConfiguration = playerConfiguration - }, _logger); - } - #endregion - - #region PlaybackCompleted Event - /// - /// Occurs when [playback completed]. - /// - public event EventHandler PlaybackCompleted; - - /// - /// Called when [playback completed]. - /// - /// The player. - /// The items. - internal void OnPlaybackCompleted(BaseMediaPlayer player, List items) - { - EventHelper.QueueEventIfNotNull(PlaybackCompleted, this, new PlaybackStopEventArgs - { - Items = items, - Player = player - }, _logger); - } - #endregion - - /// - /// Gets the active players. - /// - /// The active players. - public IEnumerable ActivePlayers - { - get - { - return Kernel.MediaPlayers.Where(m => m.PlayState != PlayState.Idle); - } - } - - /// - /// Gets the active internal players. - /// - /// The active internal players. - public IEnumerable ActiveInternalPlayers - { - get { return ActivePlayers.Where(p => p is BaseInternalMediaPlayer); } - } - - /// - /// Plays the specified items. - /// - /// The options. - /// Task. - /// - /// - public async Task Play(PlayOptions options) - { - if (options == null) - { - throw new ArgumentNullException("options"); - } - - if (options.Items == null || options.Items.Count == 0) - { - throw new ArgumentNullException("options"); - } - - var player = GetPlayer(options.Items); - - if (player != null) - { - await StopAllPlayback(); - - await Play(player.Item1, options, player.Item2); - } - else - { - throw new InvalidOperationException(); - } - } - - /// - /// Plays the specified player. - /// - /// The player. - /// The options. - /// The player configuration. - /// Task. - private async Task Play(BaseMediaPlayer player, PlayOptions options, PlayerConfiguration playerConfiguration) - { - if (options.Shuffle) - { - options.Items = options.Items.Shuffle().ToList(); - } - - var firstItem = options.Items[0]; - - if (options.StartPositionTicks == 0 && player.SupportsMultiFilePlayback && firstItem.IsVideo && firstItem.LocationType == LocationType.FileSystem) - { - try - { - var intros = await UIKernel.Instance.ApiClient.GetIntrosAsync(firstItem.Id, App.Instance.CurrentUser.Id); - - options.Items.InsertRange(0, intros.Select(GetPlayableItem)); - } - catch (HttpException ex) - { - _logger.ErrorException("Error retrieving intros", ex); - } - } - - await player.Play(options, playerConfiguration); - - OnPlaybackStarted(player, options, playerConfiguration); - } - - /// - /// Gets the playable item. - /// - /// The path. - /// BaseItemDto. - public BaseItemDto GetPlayableItem(string path) - { - return new BaseItemDto - { - Path = path, - Name = Path.GetFileName(path), - Type = "Video", - VideoType = VideoType.VideoFile, - IsFolder = false - }; - } - - /// - /// Gets the playable item. - /// - /// The URI. - /// The name. - /// BaseItemDto. - public BaseItemDto GetPlayableItem(Uri uri, string name) - { - return new BaseItemDto - { - Path = uri.ToString(), - Name = name, - Type = "Video", - VideoType = VideoType.VideoFile, - IsFolder = false, - LocationType = LocationType.Remote - }; - } - - /// - /// Stops all playback. - /// - /// Task. - public async Task StopAllPlayback() - { - var tasks = Kernel.MediaPlayers.Where(p => p.PlayState == PlayState.Playing || p.PlayState == PlayState.Paused).Select(p => p.Stop()); - - await Task.WhenAll(tasks); - } - - /// - /// Gets the player. - /// - /// The items. - /// BaseMediaPlayer. - private Tuple GetPlayer(List items) - { - var player = GetConfiguredPlayer(items); - - if (player != null) - { - return player; - } - - // If there's no explicit configuration just find the first matching player - var mediaPlayer = Kernel.MediaPlayers.OfType().FirstOrDefault(p => items.All(p.CanPlay)); - - if (mediaPlayer != null) - { - return new Tuple(mediaPlayer, null); - } - - return null; - } - - /// - /// Gets the configured player. - /// - /// The items. - /// BaseMediaPlayer. - private Tuple GetConfiguredPlayer(List items) - { - if (UIKernel.Instance.Configuration.MediaPlayers == null) - { - return null; - } - - return UIKernel.Instance.Configuration.MediaPlayers.Where(p => IsConfiguredToPlay(p, items)) - .Select(p => new Tuple(UIKernel.Instance.MediaPlayers.FirstOrDefault(m => m.Name.Equals(p.PlayerName, StringComparison.OrdinalIgnoreCase)), p)) - .FirstOrDefault(p => p.Item1 != null); - } - - /// - /// Determines whether [is configured to play] [the specified configuration]. - /// - /// The configuration. - /// The items. - /// true if [is configured to play] [the specified configuration]; otherwise, false. - private bool IsConfiguredToPlay(PlayerConfiguration configuration, List items) - { - if (configuration.ItemTypes != null && configuration.ItemTypes.Length > 0) - { - if (items.Any(i => !configuration.ItemTypes.Contains(i.Type, StringComparer.OrdinalIgnoreCase))) - { - return false; - } - } - - if (configuration.FileExtensions != null && configuration.FileExtensions.Length > 0) - { - if (items.Any(i => !configuration.FileExtensions.Select(ext => ext.TrimStart('.')).Contains((Path.GetExtension(i.Path) ?? string.Empty).TrimStart('.'), StringComparer.OrdinalIgnoreCase))) - { - return false; - } - } - - if (configuration.VideoTypes != null && configuration.VideoTypes.Length > 0) - { - if (items.Any(i => i.VideoType.HasValue && !configuration.VideoTypes.Contains(i.VideoType.Value))) - { - return false; - } - } - - if (configuration.VideoFormats != null && configuration.VideoFormats.Length > 0) - { - if (items.Any(i => i.VideoFormat.HasValue && !configuration.VideoFormats.Contains(i.VideoFormat.Value))) - { - return false; - } - } - - return true; - } - } -} diff --git a/MediaBrowser.UI/Properties/AssemblyInfo.cs b/MediaBrowser.UI/Properties/AssemblyInfo.cs deleted file mode 100644 index 4203ef319b..0000000000 --- a/MediaBrowser.UI/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System.Reflection; -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("MediaBrowser.UI")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Media Browser Team")] -[assembly: AssemblyProduct("MediaBrowser.UI")] -[assembly: AssemblyCopyright("Copyright © 2012")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -//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("2.9.*")] diff --git a/MediaBrowser.UI/Properties/Resources.Designer.cs b/MediaBrowser.UI/Properties/Resources.Designer.cs deleted file mode 100644 index b9d7426209..0000000000 --- a/MediaBrowser.UI/Properties/Resources.Designer.cs +++ /dev/null @@ -1,71 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.17626 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace MediaBrowser.UI.Properties -{ - - - /// - /// 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 ((resourceMan == null)) - { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MediaBrowser.UI.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/MediaBrowser.UI/Properties/Resources.resx b/MediaBrowser.UI/Properties/Resources.resx deleted file mode 100644 index ffecec851a..0000000000 --- a/MediaBrowser.UI/Properties/Resources.resx +++ /dev/null @@ -1,117 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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/MediaBrowser.UI/Properties/Settings.Designer.cs b/MediaBrowser.UI/Properties/Settings.Designer.cs deleted file mode 100644 index 4d9ddf50d1..0000000000 --- a/MediaBrowser.UI/Properties/Settings.Designer.cs +++ /dev/null @@ -1,30 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.17626 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace MediaBrowser.UI.Properties -{ - - - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.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/MediaBrowser.UI/Properties/Settings.settings b/MediaBrowser.UI/Properties/Settings.settings deleted file mode 100644 index 8f2fd95d62..0000000000 --- a/MediaBrowser.UI/Properties/Settings.settings +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/MediaBrowser.UI/Resources/AppResources.xaml b/MediaBrowser.UI/Resources/AppResources.xaml deleted file mode 100644 index 9d59c2d966..0000000000 --- a/MediaBrowser.UI/Resources/AppResources.xaml +++ /dev/null @@ -1,383 +0,0 @@ - - - - Segoe UI, Lucida Sans Unicode, Verdana - Normal - #333 - 30 - - - Segoe UI, Lucida Sans Unicode, Verdana - Normal - #333 - 20 - - - 68 - Segoe UI, Lucida Sans Unicode, Verdana - Thin - #333 - - - 42 - Segoe UI, Lucida Sans Unicode, Verdana - Normal - #333 - - SkyBlue - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/MediaBrowser.UI/Resources/Images/Icon.ico b/MediaBrowser.UI/Resources/Images/Icon.ico deleted file mode 100644 index 0f7d8c95539014cbbc5f89453795a46a6380fd72..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 137409 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

*k{bbH2MHTImBD-z?Q+nTGdpA)dYtB zi3jMJhQLMJRWg0(lrIG+`h!fgWqNMpdV>8Dmh@#snrLq|PRd1{mLk}Pz|?YIcrzvAuf=ZPLvI;rgBZk&9+$z|fkYk{CltPu zg4l|=mUA(8jK=sq2qSokE>iNcnip^i@dbSxnLys-5KdEhP@0OcT!9#f7v}_!;sjD! zTJK5qjE%Xw%Ci-xktX*o*F2&dSJa!Anz6&~D6(gE2A+VwktW`^*715f8K1{K8)ud4 zND28iYnAfGTgr&|E>j{8ks=x>5wcvfQaY&%z34GRSVk;(Hu{5qXc!aTh&T%SbeKlY z{>j@ad)bp1M|M7?Li`p&BMtz&el4M2(BjcpBMLV1BEqTt_i+ z^>h_AtVSl3eT9)ujo0#NH9>*!fs22I1me&Yf1Z&k8a%;9$k1BqKC#>5IzV z-!5V4b+~`|VG--b6ZM4+Fx)g~i{bET@RH-QHpcl4_G-p6b08+eedC2$5kUo|fiMbG zJ~N*mVDhj54x4>B6NQii!I$et@}gJIHLt)+3{?dvf{)^v38&Q73qCU}cqVwNE6;Fy zsE+1n1}En6z)nDg%E_ef`|flDWfu2slXS`Mt4xjV!6i}v$U35U@usF#uuDO zEmap}4eqC3b9&^R)<}ON;FE?l6h5DrAar68AFp1KeX%piFFy#bWj3gIbZFje%+fZf zlvShlz7=&x>PCnRHsk&Z&^MTJDyI%+x03l@i{%4eHUU<4jd;VL?a2lyN=T1sVOUUj zZEFdR6eY5nhbn(q#d~TarLS{+#*Z#JnB$%3zdelArhO@woOo$^H?%jCir6>mlC8;l zFFTWOYCjY_HpnxDD5}2loafe*_GK~uxS>)=8m=w^8glu*`FN}xcNfl}TU zdmGO3xo)IFJ?o@Uib2oR2A92;**w=iQ~q!jnq(5XsVY z;{k!Z2G!B75U zh&AgA7fNt(e~A^n1<~gUX1Uynq$Z0|WG$}h)&a1z;Ot7cGhLh=H@&(=V^M+(YETFR z(snyQfVRx{qy!2x-Y|E+AZV^T)L{-3#5`oVZ=ZzXYIR!W#XUwkGLhJ*^vcH~lP4#O zoVbNVDz;R%aIY9zuEW%hWnEM)A#hN2BXyh!@a?=DueJ5e8xj)$ik_6=!hx^aelT$UOI7U_A~D8htfYH2=%Do{50ArWz9=Gv$gP}qpJ6y6eaP|4B!g+_p#j9y zjrkTZ;SSSteJu!&)+pYt4F07o`C0G7TsOK-p&2~++%8$l6Q^aK^*uSr_K%q;-pSq@ z(<3JPS!yE8DaU>j7^0AV`A5`dv?MEOxgj@5yf1nkp1uxCvqiB#p+G%L_js)j;e^`B z(S2<{dAQuRz(9Q7)IfD(;llB>m8PS=FpVDJ03US0}ww2uQR-hrbQeyg$sL#N=L*~x3($pbcSEk8!sLqmn;LtUey zy`elvmnq`(6K+ zOIf>q5qrD`T4n=uU26|A`rNz{%RRlliHVzkxAR^KM;lo9uc z2Ks4ogt;_M2g_*OGU>|{OuqG5dP>Ji(iBbXz79F#m8$>i+#4=X^j;y6*sO@jF_kXwHMBK7&P?0D3)f z-xfI5@HD;GntFW7sW?oCQtimgl9&@N@4lLr64F|Z@{F{(Bdpzp@*r2}Rym2)5?E*n zNa#FYMo-{TpkYotaXP!lF@}ctj+n&h&WG&^GEnhDwy(SRUBL`<+a2Z^#XxBz=E}x> zN-S{$=7rcoDE3+xrdLCe=8e}!qDzNj_$X1pNt8Is+_!$75M;)C2AbVtRQ5 ^p)* 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 diff --git a/MediaBrowser.UI/Resources/Images/MessageBox/Asterisk.png b/MediaBrowser.UI/Resources/Images/MessageBox/Asterisk.png deleted file mode 100644 index 0bc86ef4fa0a1cd79307956c4c2621920cc2e45b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1046 zcmV+x1nK*UP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D1FK0yK~#8N?U_Gl z6hRcmb4Q94DN+OsXkn4UB1H;8gcJc&q_9Y#ouGw9iWCYKDJ%pF3k!u5DJ(3aSXiXA zu!xXCK|w*mLLq`m0ufRus3?iQ@0>k0lfApW**|w1-omiEGjHa-?|X0FyxSWXu*(=Q z28;n?z!)$Fi~(c77%&Em0b{@zD2;)=y}c>gP-zNVD603+fEfsw>!JRJ>Yfn*_*3Y= zn1%pkhttSaN@jO=cZc?ecC4M@fS*C;LS?{V@MI@Yj87mJU5l;23AiI^yh;R&VDx9u zU1|gDa)ch)w@Gr0FG_~-jmm(J48`a>&iJR?kNW@^zZZ)Dfjk+>&_BrgQjDPGDiScR z&~+qy=XoIxLSFX>SkkzX9b=EhtR^Fhkdvio$HBSHx zpH2X(Xt?k9yGYqdkY5X8zh5Q+_H`22w0+FKUNn|kkqUH-)oQhsP#q9;x?ZopaQR`3 z_fggx<6X6b-j8s9h|H@{9fi(w8GSRY#}l@|OC5tPwv4t@<^m}=0x(LRn04M6#52u` zjy>{&Igni;rdDq`SFzV1o9cmD{x)LXSqb zl?vVOnIgbt<(p9U0}p(K1bJnPcX{rMYs2(!(;rm8F!w4ycJ6lPmOhe(q;px4f{U&o z^3u>y#{U9md_%NvlZ>PP8SU4;B=!G?RIa%t4KcaN;K2>ApwSVgYH?q`WYo{?1o!9O zob}ucDsv%$@qoOKsyYA2r2i*03z(2aFj~Le722!Z4jgCnuf+(u-6Ah28W!A<*d#E-o>J!kYzU+E zGj=%&ZQlUKn*R_XGuO^QMGW$dFHn`ZFnAh++kVwmRK)gqb-bI#1ArS%Bd5Ks6CsW4 zp_G9r{r&yuP=ZSfO4VXoS(7sci~(c77%&Em0b{@zFb0ePW55_N2C_5o516ZNz>f7a QDF6Tf07*qoM6N<$f-R`n{Qv*} diff --git a/MediaBrowser.UI/Resources/Images/MessageBox/Error.png b/MediaBrowser.UI/Resources/Images/MessageBox/Error.png deleted file mode 100644 index 039a864ea93507fcc1495a4e1ea50954f682c4bf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 804 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1qt-3`{#cT^vIy;@-~O?|s-o$HQr zqQ03Z{8_t6V!G|AHP;v;eCM#X*_5p0sgYRdrq0n6bX-j1NuzFn2uMA(K$qc#1bai*+Ie-KbQo5= zxwz`xg_lC%kx!Tc7M|J3B%r@&qIT^nx#tXzd~$b}i3vScb~6} zEa7U95@N%HSinHYID__dXY??ZeA`PJQmw_~oMS#8pzHHyHMAekjzkRWGI9 zKYRJ(1fiU{QPwir1)tag7B_8vSM*d~L?Ng4&^4QLvvfJs8753Lwpjc(SE)h#%>IzM z$8U%oTUNq+=#TUpvGCI8o6j!ZH2u!orF)<5+U>||doA^%tLTcTH{WuEgSXz*jbdDI zjOAc-`oSqoIpPctp0|q$+aAkyi1{XWHNLP!c0o|vPX5lHu9ICwcEu^0zuv2(^m}*a z{T1tg%XmXu9M2?i$HQr zqQ03Z{8_t6V!G|AHP;v;eCM#X*_5p0sgYRdrq0n6bX-j1NuzFn2uMA(K$qc#1bai*+Ie-KbQo5= zxwz`xg_lC%kx!Tc7M|J3B%r@&qIT^nx#tXzd~$b}i3vScb~6} zEa7U95@N%HSinHYID__dXY??ZeA`PJQmw_~oMS#8pzHHyHMAekjzkRWGI9 zKYRJ(1fiU{QPwir1)tag7B_8vSM*d~L?Ng4&^4QLvvfJs8753Lwpjc(SE)h#%>IzM z$8U%oTUNq+=#TUpvGCI8o6j!ZH2u!orF)<5+U>||doA^%tLTcTH{WuEgSXz*jbdDI zjOAc-`oSqoIpPctp0|q$+aAkyi1{XWHNLP!c0o|vPX5lHu9ICwcEu^0zuv2(^m}*a z{T1tg%XmXu9M2?idFpe`V+;-jFZ zCeXpjQp9vn+TftFgMfq#Ta%IvgLeSS!9Q{gj3-4nIXQ#`I8-=O9^bj3yI3=N`@PTQ zyvt9X-L>}b|KfesyKd*Dxy|P2Xh267I7_VN%J!HYi`;%Yc7gevWo!nqtuOzzeQ%F^ zJ$tK&0E?sUrS(}i?bl7$Y*=%a%YlbcH9;ylbEW2ImIP0YMAH=yOV3@ZP}`gENnsOD z-M4$phq%9muW3!4#h}yuH}ZI$Aj3DtBBkoxwBYRUbZK2UaT>#!n4_QjZ-wPC?6{$HD3@d3(SN)SYbpi&D~nQ8 z7u+!B5m?P|fvKZ+iU619`F`8EObpAU4gMN39Mmm;{v$`TwKImXqUqvd$IT5v2UaX+ zaIl;@iD9`&n!n-Wc#*4e-A0UioYF5Z4)fBKY6y6{)cxvtx$Ljrfs7A~GOG6Qy!*`Y zKz5PzycYY4Ri9V$m@+0VPxe2g$zYQy9mi(wsD60fAGg}}&v*Z`P5I3r%-3QTB7Snvm146oaa-~UQ=fQgF1)78&qol`;+03(13uK)l5 diff --git a/MediaBrowser.UI/Resources/Images/MessageBox/Information.png b/MediaBrowser.UI/Resources/Images/MessageBox/Information.png deleted file mode 100644 index 3fd09c1bcada97432ae17c21530a5c0fcde9d0da..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 929 zcmV;S177@zP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D12#!SK~#8N?V7)9 z6hRcnb4SV)DI#2v!XjYG1Z;&X1qHA056HhDB1ABqe}H0{B1Ht7fQ3y&B@qKD6)Y4K zYyt`q6ciMcyL?`F8^Y<`?7W%XtmX|o_Ktl&zTfZ8%+1W+#Dq6jz!h)>Tme_W6>tSy z0aw5ka0Og})2BeIF3N+!V3Jy0u2;Br)MmB*C$3_9tyb$9*G;ZJ>%vxP9SAS<`~7w7 z3!h6he7|82aqd<)n!+U@otwt|q)qZ0k;e90Pb7J!15)z}7vh4?i{ z?^r?qC9c?3N2jb?fQ!1jla<_ZG}_StmWOeeEk%H6)p_b2Oy&+b7&(_q0P;m+DQc$( zASXQkd`l5vuPN;5O>&%OYAFJki<*#*4>Dub0jRbq z3ma3_{6QPmlx6|+-2SPxaIQF6PP4G8e+UQxM7W!ah&4|t26GQk0k%^&GFIXeNA34q z?x*BP5a$VlObcSL&D? zzeo8PBxaJs5q)VfRs?+3LZ!qfq$EDC@tF$cDs$g_A~c*FKr`4bU2<+zVO_Gm4FH>$ zO;aF;Y^i1ZH>*LgBir536SUr!CojkF&0;--Mu$Vxo1QX)$e7R7?Q0Pbuw6N~FGFse z4>{gpS8D-XMG?sLWQLCwLd9E>9#sXdB4@TqFa%O3$sT@3e~~Fpa&&S${EG}G8yh)0 zG%s&MSp2>#;0m|`u7E4x3b+EUfGgk%xB{-gX;Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0+&fdK~#8N?U^A@ z96=O-xeEe;Kp+qZ8k!VQfy9A8R`drTibGUX)L}@F2o$M60D%O7XcHueCdD8~NT4aA z0zm=}5(G`!-1U3Oh7h=!d3!gz>>O{Cm)*Pf=Iwjmyq%ey?dh?@2p9n)U<8bS5ikNq zzz7%tBVYtx9)Vg}DL0$V0q!-$d6M&6WEkno?*EVT1#(ua)ef=Quh;AHJN<)X1{;mW zGIGte>cI9dvV%+{O@M5tN#atKbqk{m#3HKRV0&#$VXQ> z^ZyX~ZBKg{NS$D#CDE=Uf*%e%_a8#O1r9#;JP>9=KAufa;GaE#uWAFs$C$^@n%0lT zuC6i4VKeHo<=I`)`oZ=L05=Z%*IGXsyVwAZ2z(1UK<-y^T%VHEu_mAgHh&!UgE{>? zuX#2r$SAKqWH9tR0=sHQ3d7hH@Z^^C{JE60B9?m-lArh3pXTwEoNZtry_4!lE-6jG z+4T3tw}J%DlEznZHY7dZoBIU{`jbj8g4(5?t^R%mdS3M1SNgKxp=V!g^0HCl-77%< zLmrQItE_uPQ7oSe(lKi_s^72NQ-Y$?93IH}eE4^i{pJeT1U!WC$Y%1*D zo|hhzJp)hqzc0I23x5}QoDlB?zPGvWT@Qc+ozog{ZpsD_eN!})K=!etPx#07*qoM6N<$f}TlK Aod5s; diff --git a/MediaBrowser.UI/Resources/Images/MessageBox/Stop.png b/MediaBrowser.UI/Resources/Images/MessageBox/Stop.png deleted file mode 100644 index cdbcbacedb1166faccd73788f8b1d19daf947e15..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 978 zcmV;@11Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D17}G@K~#8N?OL&p z6EP6IL=+TPrbt0~1?3f2Qly}vx)glC6?_06z&}t>UP+5YaSakeDefdniYq86XikDI z1xO$vCA^31(`KX8(fH7bU7z4(D zG4TH}Fc}K+cDucUu@<bfbZ*cuNlyAL`1Hi|d&E_Tg8lP1S zvft2OLwM1vbA1{IfFlP&1v(}K8!PmaK7Flj8xB81|J4b3OBwcFxHPKnZ#9E(@Q~qN z6L`}WY`?|#Sv7}i8gk&@_XXbD1qmPVnMHJ5Ej9Bc>5$T4T^Ln5Fy|9R>^Yu2U}e`v zhm)lab%PDh&PNdfuG$9+9szhKwIq1(UN1$$D3;0CQr85pC7}&oA_4Lr_8JA4f#Xno zhQLcC#K21=VEpCYNC*`^-1`Bi?x&n;r-KBZwrJDY-r*egF84wJt1t#%MhmV^xO zv>9u|?+xI|!&FrVFck@m1|eEF^C|FKJbyBH6kt$pO_NPSLRau~fQ7h}fN7~B^u*m5 zjY8ZV`vfV{7+s}ob%_A}h9@>S{~dMU z5&D%V>;x!F9qKA|RKA34^-4eqc<*E;2{%fj>WKl|QrHOb_$zL5q$N_54oHEg^^hqo z!Lhq8xBucnlk>jXYgPw|1lTCv2Pol&#X?76cVH1`zPY{4Ab|(1ownB_F+AZP9ia$_ zhGcA=mq=ikM^f&r(=2vXhGQ!&3DPDfMnVic?tg;K-2F&b$h-P*;v`lKo5e{2?`^b6 zNX$GBL67UADYTY489D&sk+w;qCqV#zQRr@cHHIOa<)0S8hG*;8vl1QHyN2Glw##s6 z=5jI@YnD8t1O2G}G*++(B=cBN%t9HDr0daw_x!nZIIjV?RTnNs7xt;3fwK#4Qo0hs zv>HvdFUb-Rumph1Tp}EKXML~pL%t$2BN-s^_7xeN`2OtSasT!e8GPj{GOwo7>F_7K zk{LD~W55_N28;n?z!)$Fi~(c77%&Emfq#&J-!#J4BO~^7m;e9(07*qoM6N<$f>;Zu As{jB1 diff --git a/MediaBrowser.UI/Resources/Images/MessageBox/Warning.png b/MediaBrowser.UI/Resources/Images/MessageBox/Warning.png deleted file mode 100644 index 6467ed54b9c4d0d5e044b2764b475d50ce9d09f3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 896 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1qt-49udQE{-7;ac?7ZeUu$Vmhmz*S~NN+2yn1W z4^a^4;9_BFJTO5)Kz#zolTI}bAkPIV90*b+A>_jPsGvhwy(;s4_3@m~r902P$+fl) z{xr*H*V{dn?|<+6S)H%0_GK~G3Z_*JS_?2JSFHsn+j(#r+EL_~le5q71pC!YMc@2kx!v2#6EBLQaa*57W&e~INTW$BBL2_BjMCVlgI)u*|)yXODj$m^u$A0S}2 zFw(a4XTx8{o8~d!0>3w(uzCA>{+{(8|8qs1-lDrp@X4MEMZvH|YMIQ()vY=dp7#c_PEH!^x(To-tnUMrw>|u=oQ$tBVbaq;XfzN zC)+#rY(3_m#awef(j{xc{^pGIyKincvYy}HpzeLgjqAzrR zb)B*Ey||Pa#mii^(@nc?#N|FwQFkz1fAC&#ir$pG+T)vlvCk+uX#7@MAjxapM~6lE ze8QVe&LlAG)ST+Icl++cKTcVTIoU8C4&QRWvS!L>o=JurF}%KU1q{tH3z%Q?itoRp z?ci5uQGV~f9)t3$dfn-#Z!3RVnis+t>L41xibge_Uw1%WAjx6FzlRCUz+A)N>FVdQ I&MBb@02Ba!BLDyZ diff --git a/MediaBrowser.UI/Resources/Images/NavBar/BackButton.png b/MediaBrowser.UI/Resources/Images/NavBar/BackButton.png deleted file mode 100644 index f72f445636e1d115829c2eecf56759f87d721ee2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1089 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 rU8@j8jgR3z00000NkvXXu0mjf)!-jm diff --git a/MediaBrowser.UI/Resources/Images/NavBar/StopButton.png b/MediaBrowser.UI/Resources/Images/NavBar/StopButton.png deleted file mode 100644 index b394ddf600c0df2d78c7598864c9fb7b80671dd1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1041 zcmV+s1n&EZP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D1ExttK~z{r&6zDs zTtO6tcQ*(G0_K(q;> zO#oFZ%6kC_aQ$ zvj&Az^BC@z%jFO7Kov%5|%-5jp|NXNV;@?B;g^2J7%=uns71B4%9OGw7p$-@-q((}0>Hg98H#@WKYS z;k2s;1~w+(mTfB7C0F$hI_Z(FL?dv~Rk;D1PvNM$hAWQfzR-`!MxS2phEL5tX5>p zoRcmEY(4;=bJ8KTm5o|`4F%-}+g4?eJ_T$(1HQFb6vK*DO`y{W5jJ6D$5tYJ3fO!G ze2+m*F)?iX6@Ae58E2(-|96#2<%e|l0el}J-VlpUnU_H+5N$kLyPgoP%N;h~0*##N zkcUA*StA!FXHay3>QlhxJ3uTusz=r<$ao%pvMd5VTh3|@>U~c5XnF5o4#vTnQGoIN zOfQ#3ffkEUEo6X<;3-q@FU1gGcun^bFA|Ql^(nw1M_WiJz+)m+knzG(6lnW9Re-vE z355xez(#$VgaE_hDAEWLOT2&`E5Q9`x%9-c2zYF{r)bBaj+KU$9Z-D=*n9_wW!p`f zFU=@+t(XdmHn=W#*nA66SBXa#HC;J|^oWJ``atnKe7i>wgI@h~!&ADXx&5Kk#pTSA zPXy%+P@e=gp8=I#oI@OxTQ6)Vl{e8`+_EZz^eJHT8SuR-J#x*eYoH&d;!q7h%gxHV z++p(p_|}b5Pf)p=?pq#}O7^JHIh?dQITR57;+^RBECy|qc?#POBKhWxj}d%*x6jT; z+YK~~*FW9(lVumMt&xkteL?h=pP`}Vqta~ZsK8k#|O?K1#1Cr>*2?95Fo&javQ-5ToN5*W-!%Wd=J|T35_|NCdhQ zxK6RJMK|!@5ICzNW}&hX8o{dW5J>%yn}0*>q1To6TXwegj8f?zkqKq*E2P~$00000 LNkvXXu0mjfH;C0f diff --git a/MediaBrowser.UI/Resources/Images/NavBar/VolumeDownButton.png b/MediaBrowser.UI/Resources/Images/NavBar/VolumeDownButton.png deleted file mode 100644 index 0c8617a43af40f5faa2f00a01656016851a66e3a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1091 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 V3_pr`{Rsn*7MB+*6EXbx{{dT_wU7V+ diff --git a/MediaBrowser.UI/Resources/Images/mblogoblackfull.png b/MediaBrowser.UI/Resources/Images/mblogoblackfull.png deleted file mode 100644 index 340f12d9dfc646a6e340de5ae8cef8109fd8a90c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 59905 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]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 m8<_xrTc^{<=wj$BsCT7XJty3VgCa@c2Kzh diff --git a/MediaBrowser.UI/Resources/Images/mblogowhite.png b/MediaBrowser.UI/Resources/Images/mblogowhite.png deleted file mode 100644 index b6b0f158b42a3f00d295a486c5d90f2d45229719..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15487 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 I?~T9wADm(#mH+?% diff --git a/MediaBrowser.UI/Resources/Images/mblogowhitefull.png b/MediaBrowser.UI/Resources/Images/mblogowhitefull.png deleted file mode 100644 index 48c8f72d390a32a30235d3889903b5342b811105..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 59826 zcmZ6yWl&sQ&@DW;26wl?-7OGckip&ET@xIFySux)69^F8B{;#|<-vo0y!WlTAGtrK zPR*H9d++Yk-D|Z>xT3t|Cqx27008g_ECo^q0HBuu00=yI*!Mdz<}wcN7X(KsEf)X) z3G;tG5P*ye()(ik}U(QysP*pj?`Fy{A zBPtW-mn7q$j15nwEE?&D6;Dl1j({c|MxOr%Td4N>k|3a%R-IYo*?iOUbUT$BWTGjOPXaBG+O zi$5ZjBLEG)(Ujcfg%Ser*H=)Gfub9(3jpChiv$nomdosBB?^5*Jr+&Zh42f4=>8hd zD+BL`1^D6_BU%FZA_3u-okpz!$b$wLj+q$m02G-3hBV*zX90fMf787n06IzJ*bsT~ z05VLoFc82}08llh9w83UWCdWE%k=XBmY4vnU=4FAKwT@KdlC()0RWE-U{wkWrUO8G z0St#JDcu1<=>RN=D-FR*h8na3`gcvGHwd;-@rnEEz%x0)X=pH$&`yGJ8L+sGAdND< zF!y?-GJa^J>v+(5>-e``|11e1E&ywN2&EuIDca{dco>{6@BzXet3A$ar->R`R(O>Ft?# zmZBeQ+@?v7wWEaL6a&hLx@Iq?2p3JD8vxF{nQm_|K0yg>Z~^M9g&@4*nacD`pzdU7 z&@{hxZ{Gs|S3ezk=4j!e{44{vrrh2xgkL1{fB-*paDo#6pbw&ARvm2=9)bq|KzaW3 zbs~f}J$Q`WutYsDt3621hTK7-RQ_99#Po(Nb6rk$4w9ZOWq>|jS)#jHWG%V zL?IK;CB>#3p-QGEMSS(y8ImtlSE4;$U>Lw2@Ep=1$(H2bp!9hTxmm2OjE5jdq5$c) z=~uRlSe(4f-_A`0pQE_*4}Mo#qAte@i4C!KAL7Ar^xLvB5B7=H^D-hNnvB&`R3TRm z64a?zLH!KBHJPe+gU0X|??&K;b`vEtA`y|&l+~19k}4x3qT)nfM&Ln!3R3E&p-3!~ zX`*gNf9S_EW@ii4lwzb@z=*|ULGua|>*t}u2p40gX^Vpd*B7bIV9ZF&*eg>WF_vd? zN)b>djx3wnG{EsCF_JM12k&O@_U&@)67G^;=^$nse{m}MtFle2JZdeCzlXNRxd&^O z#x9~(n4!E@mamG=6{{^;o!_Eds}x#>$@wjVZz2!}EK^)vkUUFZiEDXpReSig9epjC zL_YPm#?07}166;LV6a}@`{p*^$H}lYqc@e*m8XppBf1@4wap9gt?STwTf)T z6BR-gi*kXo&nHwryVCzmdm;WA`MIJzpHGZKnnR;e`8vs57;Y!c>2KCod4vPn($s6;h;^(Bx@|hb z5>DARHZxtDij>q8%}S|CrAo<@PVSns((IB>@t;~x{wN|t(loj>k`}R(Fxdwxe^k~= z5leC8KJ(w!Fjv?V6XyQ}x&5*)Jx|N&()Y`ebtql;=sb8N@?m*VeX)Biy_H1Pgl$Bo zf?YwL#1kCga&izPW*J(!R1(wc`yy6slx&o`6%^k#Em$}&5iNllWi_a~L$zZ!Xg63$ z4NFZb*E1%w&V_vj zZc>g|EHtOkrj|H%S}@1x`mM56GG`?%a4p(g0bVVTsqMUaV^^cB{BIy1*5>6LQYo5!w;tS!Z9@G8pISZXIqNQ|NQZF$mre`%d|0 z`sVpI4Jh>kLRdhB`-}MNKtBET^d|omBh0^IcGvLdOe89=O$1vcHlR9Sucw;aa`-f^ zn*9DCZ8Cn+3ME+4_i*7ioYB5fWS=iGO>k(iMu>2XW0)qvG+Qc{+w`iK%LeEXlmc4M zv|v-p6PlPxjsfm*SK&V=(fke31>4=S})g1dYB7Ckl9l=?08J^ynq-wV+^`=AI5) z64Rw8k-w6nm-9?Gjql*{pc>#PX54EFqA8E-ko_dPmdT%kli^Bc$NrhWlPxeIKF&$B zf?O`K#p2jv-`sVq$}G6yb-+Hdm4zf3Zp5ZBt_ntr39&`A6ii_RL{rgQ{(>>k}CY}}K4;$L=+@~YZ`n=9Xd-db%Rl~|2rp6DAj9PvJyW_9N zg0G3Q3PV4$erD9P>DsiNdv-Q^ncp7~=I~6e-E?|f;=C=)=kR@A>%8`KxF5K`-N0G% zb*6cl9Q*mljpn?%L!raq=F6GLAF;L2d10N`)uoHo@7CRJdDqjclJ~H|fm5&Xx3Q>V zFtO>eVJvqUkhHxYH)E_eE-g$EKW|RP3Naxr6&He z^Dcfl?moevfMY`dfIkfYz;#G47?1z} z*4Mxw5moo)Qy;f1Q?=}u2le}}3JMC)=EDJgWFq0lkl0jsY{u4=!vT>85!e!@Dg z&2vQsoDlfdL>dFISo0{#47;;f{XqT@)b}^CZoe)rVl%t$yY7!WHT357)~-M2PJMBk z_qkv5+NeJEES(qtPoH=%}KAwyW%iL~n}dfg$yJ`YS!hby5U4}_Qp+XHLpX3hve!z4Bez^2%6NQpO(9P0FYyK*Fo`y5C4pW0_`JQU1{c$~S3HE2lCVn_?!K zv1%RZw<(RauvL#XL!xar`jej#2L(kkHFz}51{p~s1$TYS`k_fIHZpNIb>LTiCtpOl z+H5M)+1$!UaBccwAmJ&h=q*9B8fk*N-2c_}|52&t+`VC?j=^G3l*~wq{FnEKRP;wY zoU}FyyqoI~XoeQ`SePH0quZnRP<6YlN@Vdgva5`Z#^%D*7GntY#pwCCDp2H$E#dOX$i<kNAso)v0uDDYeSh z??U=wyy`HXbc-i@FWkyMZ%|9YzsAAg61!y@KYaB?!;D$(jU71MG`)73ltoA}f89o&Ha#*?WgrF>= z3YYVuuKJ3OdV9Ywdd9_JiWsp@mRm&UwtRq`apd z-m1lv*_?1CUnACDWGW?K(73EXWk(Pv`l&)w0BT-0HNNDr2no;q}{BOl6(RT(lD~JgrJi!J3Edl>`m{o;|X3jxP$^>XFGN7 zm2=Qn2wV{8DJzLuDm{sAG~K;ulwTIu91gKXQz2EPvAg|nIH6sei~YyQ#i2ME(3vP` z3KIG;Bq-=~Y%^A+vV$;^!b_C{CecNJR7UyMk@O42jxS|`-g$E6#w%9JU<2LlVhOHA zl!vc#y+!iOnsD^LhE*+UlRZw7CxUHGaqZdRRa5a9E=xX|q-dUNxMe(#hCE;Zcmyj> z-%7z=9>lqYA&$RCfb*=acCH2DPe$_$re~HxoJZ6uYlvk?`(D~pkU%E$Fr}UR<1ER5 z>Q1ZyMaipz&y-nn*7Zd5(!H}TD!?VVC>7(_KinMGtBWNUVg3g9^+?6c_oV zdvK4!%&sP!dy=f$`;R;nd0lWi=;TQz{q$K^#3R(1*h%;)521VRX%w|pL9$mw1_(wf zhyLnAfz{Dh<#re}S9_^#LS--Q*pr2f2#r!&gW`*5dr-6t2ouRI>}loRoy%wBHA}Xt zPM=o`aL;lJPSoaVqG~7fY?ABgKH@lhn*Oi|$P+K6FHy#f2wY*#pxEhjICnP{EL|Wv zphIY1W_ha1sb3yKpMjKLJyWIJp-!34K2)#tWYc};u^r)5Vpho2aq27$!m5R9Tb`D# z?FtB&@CskP=$osouFy^02Eg;AR3xY|Yd4m_2K*Dh_CIS+WVBuj7XHmo8m6<9KWoSJ zwFg<*QEGf$_onyNRQ?1!P);dB$d5^sZj888?AyYoZs4a-e4fN!RV}t4N+nk9bTtEZ zsk)pY5#j>7lzWz2S5Q~8uXJj>E`!V>R%t)@(tvDaHrj8D815!quU;h~_IC`P|OeM;*pH@S+ zETS)*fVrk(=ATWzhD{1CjXw86PvbZll^-P2DEwHW%{@jg7@QTCcxxe+Q6tFAPjY7G z`n>Io3fwgjn8(wgEB`SF1C}8iOZ!rwDUwzddhnlhqwi{4g-yG49lJwo1`W!wn0;f@ z>O48a$Ia3V4#xwlM?)hpAe6%ou#<-een_nkSQ@;g#Z2EO-=L#QV#T&{wvt_5(BJH^ zAY#y7AutfSC0A5NCq#~RT+o|(G48W0iksqKF`A>BEcrQCFhbZh4lUOp@%+J2N=<4R zWvjkb{eKWvc8+@K>X@U+f`CzGmboZFCJabVS-A`Zx8Mi96=&b4DY7bMs?MxF%(7v} zTg{mhM-HwkQeew9ig{qC>X{^|?JIw4uqaGy*+OeG)`LcnfGN_&%IJBZv3Z)NYy8I_ z3INRrE&SoxS4PJ{hjfVfwuwPnV0XnHmTv`8mHV1^ni)T|+=#~>&vEkmW`7KRLvhH6 z&=yTA-l{h9>VDH!C6LArEYf^hbY&@?icblp|ERm+!VE)(>P*lIC)obCfn8-iq+(`E zu#mBuS&~|5mOP~SpI%4s(@Ya2v+!r!8>`&BuSB}OzVrl&>1{en&ek&)Ix|h1o{n4Y zy*F)gnvluWM)9a*ty(7m2mEMw|Ll}@P)5CEO}k)C%s?s=hO{5zLl$ST8p6l`JUJc@ z6v(1T9iM-Z2c9iQGe~wQc{E}eaQPKP1#(6=r4ceF=3@)$m#`P1+=F{f*@hN7Z6QYK zQ^9CHtLEOSCKp!4|G*GpxO(EC`1*x-u_s@#>J6_(#)Ss`UYfu)k&W`UMq@tJ-?Eyw zjHhB|6_pgnKZdr!^leQ#qMcuUW9$(&XR2Us2x8Szj_?%|#xA3-KE0>~f5H6Bcn`l<2r%X>2xK*>8 zq0$k8rHr%PGScj9lU}hs{G%zpQ{NXq9kIxxCiZJI-FT-Z#BlC#O(32?BX69~ccUpP zWvP_K(7x4OI&o6QR;(GW_?=Qk*-Qb{e%^nMOpAOROvHO0CcXCGiwmQgFe6E10V&^B zwlaP~m6|M;W=-_d=hC3UfFX2vq4KJPh>E8ExLubKs{vLzVEQvFv=hxj*y$UeHV?Dx zA5MCaCvO4lY+a;%j7V+_Z|VavxYK&w3Y5l0W%_AnW6nEBZZeJo(>7w-ahlJq!Z4E7 z?5?|J_PSU#I?myd`y{Eg(#~A!oo#9nt!m*E%Ky+)NG|vm3W_MqUJ=CU;p7$cAw&k8 zxo|S}0(P-UOn2p%!En*=#3I?gF|#c)#G+4OFF(>TDdOVd>_$fLJsP>nyD^3uE+%vO zb5pOaGW(AV4a4Z#IDu6tW+Pna*Y%_P5`w-IF@He{n@+UrpSD46O{Tva$et;9U}K=* zcN^F;Pfl|W9En|QXeu=KOl+s((M)Ae$C6YaG6}i*YTi}Esx!$f23m;tETc4H?Yxy_ zsq&GllPhXbNH(${12xEU9waAAB{dXrDy5VKFnS~=!S9da zp)Wg98Gl-^S2@ zRZ^9NdygXzAPM(iavXDC7*z8*`p*~^(H5jZan800gO~>sOg6OG@(hA>bZtN^#=0~E z%YootS*n!;&7_S4_J8wYNb6vtI@)Q5204z{pUM*7v4}*llT@*=!y0T4GIr-|)Z>AW zh=NM}@$yLFy37yh387+tfQiKg1$;P3KBEaBHoV#>1`3;gJi0{#0C*lhbR!#sQA~~ z{X_nI0b)zvStfLjhQ#l;B4>ozRwBB18yazGF-XxjK?`m?t+B~6KW1Qri661DtV%Ob z6;Fqbp&o%Zo{-9790lF>)BLo-C#G3$SYfe`2fP0bmNt}z-Mb_5+Mc1`T;*f*C?_xY z7#C@k=g5}ulER9Jf+)3f{(?u3Xz6;8P2*U5SjwnOoqQKjBjW%G$2*s5-2>j9eLk-&dJhCqWitv)?8v9xEW@ny*(y zA4xh;y^}raD#u~rLVme%&vrN~f@LIZ*z1SWmQaKk^Gs(7%`OE5g>kbsQA>B%O;Wn^ z6Fv1rub_zm50%I#>Hmj#zGKDSW_3!&tr)ergjLEZDa{d5ip%r%@CMVB-SsGgJpHri zkr8ca6Nz2S>1gle%qPYx@5bWbSG<(~=s&#yw%fx{jQDVXQOzbKw$h%lu@)R)*{Pc0 z>Bx_-F$J#ZLiLHWyNdnb5_m-33z3v0wZX-JK#-iSK+8^QerXU@@~obNFltQac>>$O zq*pyph5=^V0^<-yY$|5$=kL_}ra9`K!~Qo^tp*LhL-_Cw621`BL@b2;gNg8E_|5>G z$DsuqWOQ`V-e2_5tN`PAwN0TS@$b9#`^jQdIpiYKc+Nq}ZCbqG-3^>s+v(qetrRjk z!NOXq74Xov$yC2}cbZndh9iz0yL5T=a78k~^}*mm_7m+`dLQg2 zn>bCF)`@nk$8^9bf#8%g&?^5)qx=bg1z-}Y8D|LzYAIrA?_W`ixZ*K3`0qOH$AS@! z5PdL{Di5j!QeD)W3C+^&!I;^Eb&$UeHFi$0L?%|5$#tQ&4*N1ByefUSy2 zKU0Xke4+5jCJp2G4r0A74bwEmdGQwk`Ilkoo2=_2JJkhf94a-K-wDdfD^Vwci@z$N z86`cSMW&r5>=tI{8}@Yc#?#_G{<)fP>|p3`0yg*J#`q9aQ=YPahb+f{4!;c_6<|`6 zFgjN{t0Z+J+TFtPpSf1}7tYE=>R<+vkm2H>lgYx#UWPYE(CE;m$Dn<{)I+019S7KO zgl9`NO*j;aep=&H zx;EPd9R0vbRm~EDT;Z)b3Z8D-%6TQI^dLFMz) zx6j%%euKc{ds}}h6A}a747f4P5tA#ezy3}0)Fu@U;>#e}(q`x+_dZ84tRzht0$}O~ite41zaCQd- z9}q~Ib!&;S_k1}AAh->)r@1K}eU~vOWDb_5`3NmC$~|tR&}lNzJ&>E(I?NIzE{(8IhI^ z#p5HEuClHh&J-OQL`t&@TuFb^YYl|y<||-Ek{5T`^wN2J(Bmgjp{=)lmb9!?r8hPu zEY>ZVy!oJy)s2W6L&u3x>WN$wL*b`uKD*^=D94(=56=xDiIt1479`0`v~=M&Mesp9 z8VU2@UWLe!vNA(DOr?ZjaD2H{(u476)|#-2Xu-g%_RP>&oX&gVeo3*z2_nx4eW?BK zEn<*f6cSBJLh=w4lmLXJEI?))#W3mfVWv$*-pWbnAA8A4GWBw%#fgRk-Ul#>CGWI!xy5)zv8ZfP`aIa-95Ndu;0s=dow`ef(8c+z>SN06 z_F~xRZ%JUCB_~xzbH*9x$fg5l8}fEcP6TkH4*tRU8xjXdM^5B6bzBBCOveL=A1K|y ztfnjN_NWaZ0Zhf-;|l&&QfD_R zlfZ$kznU<6{G+xW2JSJMk9j?*sIaK)U{7~3o?WKVrQFkKwc>c7t z?;vPl#i5NgEm5a6IAE6KA~-Ytt!ulIJXpc;=xMu+%P}2!7^Z1=R_z&1iZg@Hho7;S ze42fzP~O?09+H=WBrf`%L;GnTjSA7DxRXFx7fGuI-+LqAO$SYK@E~#B-n=8FX$MVK zB)~QJrVVr5Jw7)to2AWEX+Mq347m95T^*9g!2W0VbP+|8b8rOkg)Ou_L99>#(cRr& znZ=MF&&VWdmZ*$E3c@bf5%mo+>DYPXo@9%F0xX?qL=u?OzqpPwsrb?v<6b4Q!oG&c zQ_&eAzTG=BM8ulV=eUW8S|9l(`l;3t%kVpFx$I->Q2886fefi_#9`XttX5VDBCgSG ze*l2a98M$&5xsLa)tiE%Ww^<<>~N@Dh`w&q4-v4ZGU9YR3dURbG_l5mn_rLwm<*x@ zkU|Hzc4?)P=vZsJ`qKgYXl zSK%v)L|{MwBO-{9l`Y-K)*CWb=o(6V)Noz)mG z^HYz*WohO`|J8K-wqMYaDr*qeaDcM9^*^4@+*iJ!K0fns5A|PT4;O<%j&A2&guFmG z)sm^Q*>P3K4Ubh7tf6&8y~hdfr2Fxu`@vXFSdV{-J>fvrCSUA#R{iJNH`HJ4uj-71 zdTD9vBSnf>=WbNsrhiyld%y`m*Z+|m_5kWf4~a?V-Kx~Gs|iHN zN7Jxdw-z~5U&%je@=$0}^vQJU8bS~%q?jM`3<`1K&%qQ-ov@$D>7|+`gjmD3qM}M{ zXS6W*h+#O_B0{I#%M0YKp;o)0oJw`Wt>2Jq^buM^B2VWL!AP(@S>p6uxUNQm5L&jz z8&u56=4$`YyJ_)NfLK;BFK)N|T^o|X=@Y-#^T?gxSske#&o}1;=>R4J#Ehgs?JIKJ zIWFHAcVvT+2XseUN99`M|0l@U~ys z`{=+H_4AK? zQA0w{tc?1crz|11mrbk;m0Jc;bR6Z&f)y0v=XU7+vY-cQi3`dxUj!mkkK^2U11KOcFPgxJDi z0?qZp;4_C>wuYZBqC-jXYsVa3y$Nfc|J+V%vYXqk2>B0@+yhqKrs|kgv_c$S4)1?l zw)|vka2&4P`Fn?O+VmAm!Fz5?v&oTGJGJ)v+v1WCUog2aj^Xu^E0OP8r=xd+0Tp|# z5GDGu(W}fBE`vSN$PX%96zSTJx!5#i7L1r*_D13BVoy@WEAp8bb`DBmPGvL!U4i@` zF>;gX;-CO=tuhY3)VEq{O8br%`wpK8;8L9jLx>%nRSFxo?RtQQ(8)Akz*(m7Bk_9u zzA>W?dxZK}l-0@|0x}AU;jd1031~u&|H4@eqGf7dxm>lnmdtY@GlvG94qv@C`%Nxl zgT*3!o-*HjQP*FmBkP^UxEYB^p#9_gou=9++$UTVCedv-o<>M7_un4r-#xlH5@5T* z?H`5jRillLZmTu;cUPlk5V-Ni<*F}atsV+b$Q`@$AJlz+AnH#CP~F<|y_eHnMx@h4 z2pgjo=jr0*yV-1iV&UbItn+!w*x0E;^~L{r-Z3Z4-Q@#0-krmcDh|D(${qanaE$6W zlKiXxs<`m=GCFhUKffn@3MC9%o|hMrj@v$io_C{oH%wQpdd;8q9QtnoDlX6~sNXMf zJFeDpheq{M0)|Z|<>lp!W>cI_o2^UJ3^R?rkGDy;3oc%Js|vFZL*#TE4rot9PcRlDou(d{+y@#-*HR3T2>FY`64dJ1ey(ll_>;Ma_Z1d7xPOdeH;^a4 z1)L|gVDTs}I=JmTztnkrL#43|e8^^pO_b6wO>G_)a;rZBXfwUrb(AfA-|sqndG3MX zhH|O4J=P9GfQ*D>ox3S~H3TFc9uXBI9#Q|MAp_5yI1;YmNP$rlGZ7?y3mo*|Vc3hF zVV*c1u~t|VexDf9m)#_dzF-r4ZPqYgVP6Rg-nw}Y074dz7XBNa7H?2-AyQyNq+b-r z`vRg2_(;v#@2cwU-%V26NWa@z!AXfSd*3;<-hDdmmtbHZ)6<*3?o)7Ipr#;y6p*sy z^GZFVwq_GEQxr3SL<$=Y6VcW4TtfJW6vSbjVGls!R8v+XXoL>amn}}05|Wj@2_Uno zdCHxU!G0~jXl9rfJV4pE#JmuUztrN6frLA^G+Fai%QOH3Z7$8PG+&k1)-E2(^vhrb*dnYefAM=NpAVZGnlCLsby-NvFb{TlX} zL^)G%GVhKcn9?4a!}>h^`gJ3p?oO;?t(qeibH5l>f$qG|1wD|vn_*zXSOG4wm!Q3j zIO5C~zF&RM+L+{3k)LY}B{N*_=BiU3B+X31W1`%w;7`Kt1$thP^aH>&A8mtnpSwa7 zGsb@AkKs#6P19tYg~*%9_ifrVB~voT>MnfzZYX$YDRn7xJgCRA-l~E50co?j20c`0C(-5L!49KeH86l1j@b%m?TN3W|i&=P(mBwfO{gi;%jAsE66f zwdG-yiIGtWQlOQxbH3T4EtZjaXEq}v15t;{)E*R@^sp8+=-kTntgMGSrH2UmPNeNz z*p{V)j`Z8X*t0I@53vs^WCULKU}0I4*~tAZiAk;G zp9Xc;;HS0Issuw9pbHr&#u|j52BvL2{a!^8*+Ed|^M;wIqS@+%#BGn?_g{dBsjT5- zozW~_OH}m1vIFr(jMt*W;2f4o_W~%!A+!6x-(=J+3VX{AtAZi7Cp_s1!YA0RR;%r&>IM>G%@JDcG69$-Pj@5k z#1OWt4cI5%UYO|h9@o6wwj_P3II(8V)`%xOQCsWLnf30@`9@^`Tiss>COZ%HQFd!F z(I-46b@Nw&__=8SytFi_#epohwUCJbG*jE9ChT{1B$9$%J%(eu+JU{&D)-lO{Pv_3 zt9Ii7`hT~!8|)+;tn)FR zarpU-klUonkP%~dF3?mh!uFn%uQ(%ef81BFx82_Lot1Wv%`dTncjwKB z;$`y3Ctnq}BdP112aE-e`YBnv>>!a~;Q(m7Cbp~mF@-4WG>flwPf z#SYY^CEeqiKn%`L@Ugs)WQ_R4Jq-g$(emMVIzu#di!}^&j_x9Jo(Fr8mr0nhy?^h( z$SipOHE#ScV~FA76i#`%_(}M>#fIA30HhR3cQ$s$&`L3y(lg2Jz(FT*n)BBbWREJ2 zlziSXF8gusdPK_`9f)47rn&E3NaK@#8R3WslTb=@DfvcVNGBlCDuz2RZ{P% z`4ifJS;6-AuFo{F|5PK>5_!ufTo&bO^jC%ptJUVa6Rp<`<%+nR=M>ZW#^C-B$(BW~ zBwG@tC{NXESY08Ci61)2QUB0MF=pPee5ys(;5@5q2dPry)+Id$9b|u2BcnKmA)>|N zK+rhHPv(^L%0y#eA8Dm|>#(=^$j|qAC(GPlpG$}rRO*Vs1@gC0TGqI)Q-HWOgXCz% z8#r4kII`>oTLjKV_>2Gc^31=(38n9td{n67I2Td$9rVh>d!D!cyJ?ny#MTeYIB(JB!@9){L_8x2KkE$@<~zj9`J(P{P6Q{T~&s-{S8=LwvaL#g6o22{0rAdu&2)(a_NrPQ{~kZ?w1_r4Y%#v_({ zX7``jzI_UHz+dCcgGC75*2EYF1a1v^Nn}>GFeF-3b5_hS%_8RZHy+AAHNP%h|A%$; z6l{?zMlxzyNTH|i!}CT&C%Cj*D2sVYK0OG|ndan+(*lz^+pd*w1jFNp?}%Pn%Tm8) z@1;eAapKsOZ9Y5cQ0){X`0BBnx7R#0n|@~^Q_s&bWuy__>7sROrd=dWIKZ=6wCk-$ zT_TMYcy&ZZ<|142J}T9_MNZ+Bsp*pGOa4j6#PH7?8=J=FaP!M@6JIOlEx~Ux@g(qX z>YDZ#UBYfUzcA>|1%LAA&29irEV7BIJA`(%I_T#x=?Gm+Scjkdj5u3hH?`EE>bKgA@ZA|kTIDjdvNcn>0J4L3i z6^@>=qwB(dMe(?J%2oV9Is&j|W{Y#uGy8o1B#+gm?czgQt^(#BU~`_}(l9wTpmZ&v-`;fCA;=rG%_OdQL+tykjAvcYuy?9Je8OvpB zO5S@RiS$TfN#K#1vhqBC_2f zU*imPaHtAr{u%rmC(nY~l*6{0%zdv*R2^j%NrcmWNy2aN-`SqhEH*`mA14J8atBa~ zEJ@E&d`lv$0Eo>Giw;Zu8ra3w@(oK0VqFTy$6$jRaaK?gI-GJC+DSGNRl^bdi7YbU zXoTkEUvcvoaYepbp|roKrVdP?^d0Z+cJ;=JHznGWuFGsRMM|f<`h7b_gymyvP16Uj zNo9)xm?YEGaDSi(YDY6Zd+`uEs>)0w6|QIDX^A3S1sX>*M?qENv?$1KrU;x51oYrg zloN?AGxfwZBf-Kt9;^}eHV0CYarE!iE5n6-X$eG;fw9ekPkEY-mbp;Q*) z9y_EJ#;h(CJJO^WJA*}G=O2xrr%N}BfQGh&R42pjmL04+SZROLVTl# zZcaTbH$4Ara=o8F-do>v5fO)}se*GhCj95G4Fkua_N3~eF9w38_WFoze4u;KfdECa&TgmQ z5NJdZhM$2$Kp8=s(-8p;t zTy9D)%)aIYHjQ7&q*r)EGx{ha_lnFN&JEx<_str zFWDgdqQ!rDV*|Q9_^cJpFTc%h2^3{|V4>Gkf0uxTkf^K(5n(m8OlLO$;S5^at)!Cb z?Jhwb(&RRn;F6gHQ^A^6YYZMe?#?c2}<{eY!J=)~} z49HK6$d7#Zv5a=6ph*Wt8PWlFbV;jG&XM6UWcED2mo(9Eqjp)dQ;k)NmA#2-nB}`a zcYMr;6_Ur)$4z$V(_GodV_%sf!)n^8-rLb8%o%DwU&S$O_m0Nkg(}+CdkI;1G;0nE ziQ9&gEj9`+raq+LX(pNwn;q{ZgxEqFtfoB7gvKB!e@_$S2$EJq!&^o(Ar0~=!)V7m?xqKB4JDh2G zD6QT8B4o8K@!%4+5pkkHY{nyWbW2}Itx;++^&9wP0;jZ6noVWbKpFTDX%%LyyJ>Z@ z{`zKJ{P>ioZ1h@<`Nu^(i=$cbq8M7z{R+(Fvi}IKxmRC}O1Lpo>Fb+TlWb1cU~Lv$ z`F`vVSQSQ9x%kS5am_r#eqg!dc3BLs=zcFo!!6&qV)P(3SF+=5lc6&&MaF{IKk2Vw zgG|DEqc~VC3X+xO~rE$Lyn0I_6Nl6UKNzKY}*2&B1xIEZ1_`L#i;3pa5csip7l$X z3fhBo10Hi)t6UV>X3ZNjDL=)#qe(FeTZ1W9D;PfFO%qt}=4kADle;h79o zYSL4hwukX!;Xe8y5ngr;LXzeh4N}nZbelq+tm3Z<6tKT~wFI!EOOf?qHSo&z{HJC* zm^!d-D{;7wWi9eD$k)IcXH`E$XiWM8`3zeNhMry?3|~Pew0xr@ZI5+_B~wrP=pT`+ z-{7M*LWxV1iFe7f3}Lo!Nhg+$0saQx#*M)ytWJNhQ4un>YVLEaFF^l8Ufe6MDkUw! zgdRJ7F6GTNp1PT(z_ac{RlDG=9;JJvjQURuiEiUnRD1SI zRVc8azEoRr*n>O+SrtG5%vMQfE6k%(eKtr+kT@y;=Mq`MdZ{kx$0w%^AGn8>#Ak}H z8$Q6u_~ODTiK{$74II#^gblc$)0c4{R0wZ14AK5#UTr$rhQLveQ%`ckppkClF3$~) zTo3VPI7?mDgS%vakfZco@vLp83s#r^*z9t_qJjERQ!tTv?7C3lqkSQ4PNhpF&FlkH z{66(ktYra=68$Ver1~|-9mx(4*)$zhl`NfN6keLEGJp~fh6FE9mUf?gtCo69jzgrW z{;)FayQM{q!7l0`44fL3?tYj6{ohXOiIt>E9Qvu{23l1j=UGn_SR}2CtdehbCfQheZQ&MHe=iF zhBM3X)R&229%VYM0(sPbD5|cT_hEG$WH2d3Phuun>9^qkvqoK0N@Vs$Q;2TJ5oH4u z#s0GptG7@qKMs$-hZ~D0Orl{Om5RfdEIhrx5dzu(KQrmJVqz3xi#UAMtNW=h4m{3BOQ6Z-)%m|9J24UAa0GK9*i zC5YS%V5F!WF7|w!n;2jJ?xsv({k`Fsx76@D2!3ccwRDuX(PA95T^6Tm#zuaa4>dsLi;yWijz(^)Jilt}dO1G>b`?T6KJEfeDAaqIK=ol+DH|fSJ|$i`o`5;z<2il8M?upSDAp-q zB|MvKPiS=dX@sf4IQJ|v+?9hWq8Lfw!G;7rXSH9KD$^b1+7Buf>WMRKHEaROV4X*f z2sI5DM2-v;@XRCwBSlG>ouSB96K&h>*|1>6FF`YKW>(sRif8BS|3}qZ2DHI#OT)q4 zU5W>nAVrG1ySqb+OR=KG-CYY5cPQ?zg(Ag^OVQvKOVSD-N67ug@k9 zQ&d*ed1B${F1AcXr~YN%H?uV-#(Q=*^+o7Y#7ZWnCnLCqU@(gEZnCd?oT7FxfbdcT z(NdyXVjq8KQfQ~ydj2>twi`;_)9UD0||cSj&006BbP$d>flGFro$b^UkiBFQ~AVn;_W0GtWCh8 z+;T52D(=xvcnyK*r@8u_wh8hXtx`V)xw=R}h2IKi#C+_g8z0q-uJvk(11nimViob~ zT8jwwAKu!7;3_li_KQ-d(pHfV_|@?}vrAWMd0Ul+^>9rL?R@moQIgYZi!y)w%u6|O z_J<-B#y(fT;?i@gOorlra26+ACT~BlUWTj76UeLSXFgeE7D>x^xDn%gB?`5=W&IhJ z&Tx9d_s{r7#6U3zYgs2D^x~jhI)vHELLsl+aq+7&^HDP{yeoH__?HdgR=QMifr1*T zFlk1)7l&)#y<*@~QPCmlcmi)_1J`htkx;9Xo3MLD>9|1j>hM~%BPlbHd&d4~jGF>` zj{Azh{+l#eYl0Y$aKFyB4;rs@zhZIhSW)tOX61l5g*>L#{Bw`N_Liq<=zA%BS+Ugr z*%D*pQ{4&U%^X{CHVrt3xj+M$!n#D5DEu!hdrn--N2)K$I=8(JMCH3)Oo`=(3RE2w zWT+=WIc`{1^08Cc){R)xLceXxd3B%U&12IMK3l;zIG#~lSiYZer8&4NDeL)>8p_O( z=!R@$6knbqB;|2rf}pO2Am3FIY7nnwp2}sceOQ8RD9<*KUb9y3?}jQF5&~T+qS|Y@ zY5TjR6~;Y#ezTGlK`^|!cyX{7>QRdUa2^Zs&K&BFCmD^6Dax`^wKi};Wr zLY&3gwa~ouxE*5-fAaHQFmttWD@o1Q5A=4q_a-bKvuMfNl|%M$Cq2q|?MJnVhAGzV zaLx@{Ng_^L$u=J6MlFWtaJV;h^c>jpFq=E!lQwhkUw&Wluvk%7cz3Gjyr`9?DkcC^ z%etYIdiWUz<^es(t1#0j#Q)h5q|gFm%=JI_3th%lrv9qL4uz^!r!PdAnt3W~r|hjW z`LFDDj#8uCY+inUcaTZ6lLA#2&;f~u=yKQiX}HIbKzhpAXlmawXQ{v+Rb|o+6=1rP z6QakFdUY#yHChB`PyJ7Cve1X%xliV&- z{l2^6NZ`1#?nmx6+d*PagAU|e;Hgdrvb8(2I*i+_Uimkp#w|bT{f@^=e3qlJ{J;4a zhV^UHikAg-0l1iJfnMYuzfAad|Csh+v~I@y@ifu!n`_*gZ=5r(6pwW6cd76LhaK{R zZ`04Set z2Ku=S@?~CHi}B{glD$}=U*~96N3oyqywFjAer-y#QWx!E>~l@NWb09HXO8(oEDu zzbn%bu)dEMpnUaMGbVFc5cl1k1p89Q3wS#N`jYN9(GGj}kM#I?A~AAWgAF`VU5%Cl z&8va|h)%6G3m0A-)G-$)_XjQ zFA?^FHFWK`d-vK6$h8%4C(2f*8!#&L7x;FTbY}V6BDbI=Il4Uohj^eGWdm6Z%>17j z!U1o5tvA#Kr~{o2mXNYNyMHIJ&JEm1c8OIHT2|t!P-MX1gK$dH-P(QS54pD~Hv0MP zIpdK8+v{_pDV6^t&<54UHrIw+mm-GxgV(WSJ0?tfJWl2_ka zHDWp{DoiTa39gV?L#mv{YN2rBhK~XP&*m3A8jO&5hRXjGcMFx>@6m^KRmb0w&8|g0 zZa`u!aWa6-R9cQIjxz5`BfmVw7jI%eHn?s`viv>dclE-OGMp}q27YB!kbfzZ=-0Ir zSvZe^eUCSO7)%GMi)W$YuSD!S!jiVDJnyz>1JGRQDstn%PlAl6l>x4 zy~jL4XR}zWxnK&GjO`e(zexUdW-(`)b!P5_o8fmV_m=uSt_I}l){4pn%QJJRJP@Jywe1@5ckVx2Yf2ftR^JDA)wkZ5ul>u}jiQu*dNt=-sH&`+x*4)k zvIR0K$U$2(`Da>AN5Kl7@m_4JRa-F2p_TgT5rM6Q_TeMXd>Oi$8J`NSf{>@Xi=-<$ zZ7Z-{f*)=oOSbh z0ZaW;74bA>ej|jw-}YosSfnB~>EzO7*146YFn5$^CPc{!J;T#%^ZjGfb>zda>%w27rx()_yZfzoZuH2&@Z!?>qP69dag!#f8~=Gf+JEHdK{2!( zxZ@SSqiB`*@4Zj&C=<+>>XoJFU*txG$u<05L%zRqI*T z)Em4ARF`V2o$sMMS0*7?e34J)wOYq6g3dKRSW^{rzZrRGy}0zR>^5pLJ7$3Wpqn74 zwlj*ZGs}#njxWwHWho6$N2A-|dxxQg1uZ9KW`?BmoZR3_jKT#c6a^wS*0H?>{C^66 zozEieWjay5k$sPCftP?&hvhp$Oty=FpmuwPsK(STyWKw-iq&j1&P+*Z&6i(T42jrd zk=O#QwQD<}uX{>)eQn#->-fJnET0>CeD&-4{ZM-UUSj)jloN+3n|+q=BxjkKAA zlI`hF3neiXItIqhAdyiRR=_KynSEP;BM??abo*2ER}&Rk#ufiZ0v zA#E{KcLv=Q?|vV=JpY|g$2X%Ih(!51piOK7iu_8LmZGnfWT{@nGua(nso*OJ>`Y!* znYd-`c7n1i&N5fWh|w3d|Nq*|5rVFnS949vgz(EH>&J2BD_EJW5u_k3UWf0ebFP0z zOXBZbX1#%kKyZzz*a*Av_?id_iiH%eoR^7oel6O$1gVN#OI9+gdHD*ZT8B>^cNW6? zC8qp80G-u(v0i>VIS)h9zwaqS;Mkt;*YcxAMNZAueP&9p&iWo3GI05fEHR~fJ4ef{ zwjK5_-`zV5;Kd8#Q;MFDG_wysnsy_CU#1B3n&)xRu`p!1+>c7^bt@GJI7$$GX}iPQ zJ&k&7*4gn3joT~!xiSA|{60!j3U|05md{83VZo(w+%^w>rttNq(mC!Yp3q*DuDWGa z=&+lsz`EJPw9_N7#HTPFVHLY`uXHEf-u}>jfGd0EJ=emhW9^DisBZOKkW9QVjae1? z>tmw7n(gB?Fmwv43K$x@pxU^aRdjt!s051=8U!{<-mMV?_WD{@MAsyqFj+8Hb?pt2 zYKC}F!JfDI(qf9bVEOG~lv#Rztao$DFuFDDy0y$OpBg0yb3 zS@~6AX2*c9Ulxu;K6QGfeS)?acM6iAjJ3BV$2Ts(n#X^?T-b}*f>j{G#SIDn(u|rh z>6gX5<7U2vvmf;R^v?NV)LmL0KDbP542~l6xp7)a4Z_DF^gQlW3E$jKwaq+NgefiyUPIwI3D@Gih=rc^fbvaE&w$(-M_e^T|-Q~@U!1#iLJC~frtI|FzJmL*!#G}?$tq1wMw+vWo&_jwxF4T#s_xxkC z?p&b#u-+>|1XUM)cT>?dxhLv6%|+wn7t`bY;1D8w1&N!$cYojN!qh;YslZ-2z|K6Y za)*T18rWV&CZemE3!nKT?GRdRhjRzKV7iF=q@+7h035IvZ2tvjpLWS1Z!c!4)|)c# zVHQy~;3aq78PA?~KrzXT!7PIbSv~jx5bSkCZ|9XDv~uVBN#4+TiT?w!|7()L>!>bh^iD0k_cz27F+&PU?o+ zmscKtT%dLRYpN0GhS$1BBTq^!-CD23o0`{YBbw;t1flKK*-P7G4i4OeTkw<-IFu|s zsMi^ws3f${9M58BFMrP2j%cKGp}-Yyc3X zvY5(+m-_Y*T`V02`YPbetZ<7|7+ z-nR4O4D0R6hQAsWe?H@<&yBoVLZ|r{f{ol4>G5M!y|Gmfdlfm9b7hGU@(mL;T0VNR zA`2%XBk_Wiu6<_yVQ!CKfI}l3I;osuc_!{d0o);8&;dB$T}XqvPj^MCO9CwN<))r$x%2nnEJq*1Ia%5lSt z^w$F!`e0eaH3ua+QUhWm*tH1Bzk-JgLJ>r z@KW~5b?_B&^0nvEuhucKbSd;MOPeUUr2Fl|YzL0}4^fM9=d@SBBAcStcZbQO<`P^K zk6$8mpnk^a$7sVd(f=@M>5P9U21z+4smosvgFd`}!{yYy|UxPyABmKIX^2)63zwN1*6%C);#0 zh^Xf}kdxQs?9%TkDq?p%Llh^c)oHNhEQN~3XIN+!zknUHO-pHJ7k__NkO(5f7rVl==z7!Y2>_-SX|ruTY@@v*eC%0<7beK2}=b^?dA!tr;`>gEh|7-zXNlGK!pqj9hO= zB@U8*pUbeCxUxI2uAj^UjOM_l3-e zvC@9s0gC)Qyju+SRTBQRXOhcrH(PWEQ+@Hi!-RC{TfYmghbUxZ(pw|_A>kJnYs4ivY>uVMGslDi6oafDy}! zxiVpNuZf9FBw}MfP7ggaF zB79v(Cd-(D{A||XHAF}ltX|k`)s8r9RsHXg@q1U1pgce>!d3^#hr@P2{8uKFvk8GJ zl$J5u{F+w%gFuEBQNyMt7s`BTrsB9Qj0fsemvc;$r+9>&uP>G|VdXS3bdcf zvBc%V8b1^%rJB-bGiSLljYZ1+q<`6oVT__HOr49+ON};233MkPrno_1MMJp?#dEIx z3r|N(*h(1Om%QJBy%Yum)sgm9<`M1=nm&k#+yrjcd1P(ARhDg4FbH9{ZZuOrL`u_} zR`k9@6+VKc995Thpt43G30hmM9i6B2hoAP}|I|EkZ~Ep1oQ7N_)I+8f>&?U`&&#YD zn3NMR%;C(#*e(x{*~d^fmSYlz0xVqRrQ+N;$*Ec7mWmei6c*{93eeBLZT*&&pk}f^QIB`#_5nbgLbGq@A#m!Afw{HPobO-t&ZQZj)e0Pl%Q^`rmj1wRuw(BN2i(+Ak@oq3gAZ!$-R!Yqb$+xxuWi5Zolnl=(j6b*)31IZt~q9U$$+?>BE57IVsV%+U1dgGGi!V*Jji27p0EeG)=W zbUlt&oF`SXkD@Xi40C7z84qFqE_1zM+HH{7*w9dZ-xIA>F(TW?c8MwAa`bIQ{^xbrvTlDJJ& z1J|?)_%a$b5>dqYNImjBvegES zxkKxeUVcPRS(=*eE2C}|QP*LxbIx}*Vf7UF?{2sqq%nUq!pNvCp-w2|T+WS){yK|8 z>zIqs-L(j0R&tY|w?`;So1b~2d_Gof%?X`mz3kZa4jj)TIV_e@2c!dNpmQPNe+Est z_lvd`-s11e{KoGCL-+z8aQ`utNDrbVx;}paB%-NA-a92@qb9YngRE?en+WvQb*a!kiHW#85+pJPlNm$#sPXjK2pk*%Y} zP4rx8gbf(i8lfAW72b^^)GZ>Fz_6g?y90Xni0-uE<24Tbz7<#3p!d-(;HN(_9AU4| z#9B_8 zHzIZcXUVtGis9C7rAmbF;s37s@|nMNd-fl0ya-jVev;qUtL-|U(es}s0{wtmZ3r=F zCx<**eQCTCT=BEFpP#;aQJprU?pe#NgcaE05)Pb3Daso(bs^3^m)Irm(#m-Q-Ihsu z&^)5jPNI7 zu*$;^g-VnMp~ENs0CUYoWQoQz;f=?p5AC#_sv>@HN#$ksTY;~@owymgSa+ZMh~|I+ zw(M-;A!sz)e(BI$t(2q49NT4-r?FPiVA-XXVHOn-%c5YGr<4s&YCUVDBeT_O_zb_h z*0Ku(KZ!nH{saE+Ag4XBZ~k{p_4CO%)lkf&6EhGHO;3FDRoo}j2#ITNwVSNPZ2wB# z@AzzH#NYEzg&TVBai(^3_lzokH#a9YNX=--YQ~t4ZGo2_XG0r)OL9P8D zUniUq8zTio67P#zQb<0bQcwwFFe0^~!bD#51L_n5VEP%hh5a&%BWuF@JIaOtcDEqip0uYaED3D4$b4Wog+2bO4^0c z!Zg*|)Rm0XgGej4Z$PVZ~IMczAuEQP&Gbr76X<)Da+1v z-*J|{aa7hU|9$?mzTR+Xk$tRTM)_-syoZCn@2G=aFp>V@JQKJl*=sO zNmx`@xUr1I5PYi^x zF3~8_kf`%7>Q9ezCi6Qp^C%%Gm=|NT5Pa!~x7_F<7>TU&Of-E$pgmW`!N|y$;5axmgfDWjTDF}eOR45F4K=!KLm!|} zZSN;GPvZvoTx*HU^!;lZ8Y^Tv$|7t;cDX-FDSG<`PZ2Na8O)OLTCqM1ZS{QQFhs~* znFsMkXbAEujdKEj5LkuRqL(C&-v94%3tE~^%gYPRCVvM5OI$U6OD8gy$2+&Z`zjrb zBd2AiUSs$T8GD$-jf#ZkD$3$k?{tR}q5$+LyI_7VZc(q*<67NCOW8g?p6#kNA*+)& ztigG>AeEnmW8!kU$e=SNV8L~@?KZQ9E0b;=Mst})Q$+7QlVlb?N2fT}024ffz7#l< zHhB?Z`iw9m3gIT+6w&v2EP%9Gx=ypG4n8Rx{^M&|koe)Whbu#?O;IS_w|IuPT>pvX z_2s?lu&Btv-wAiejSh^NFOy{##ioCPgmu~9Tj$6B0>+QAT}3q_yavA}BTxz_UKlEB z#hbuP%y}uZS1xl)P}8GqEO3CX^keX2#kGl(k~hFJIJ@L!L$FD`RKPuEnoU8K37>xn z2n&~8)s*W|dV#cmqfq$L5g+ss@zXx?27{`uo`chF_Y|bK;ltDkunstc#ZPajLxqmNE!qZiXqH)bEAV$%Kj*fcIRGi1+(D&`?#Cg9Gooh2Lm*PTw~ zYZtrs5yRd$ty^`68xH?Y@`?=W*lr!R(GuM^!aAY*m}bv@#R5+ull%1)m!%G6sNa@J zPEOoZhMdK6?M{BZ+X-*u<~ik3RrQNp&2`t6KhaLk(ld;2t&t6`y}(K@ohfVurIFiN zRPmlRACJOs$JgYMB~la^`UKZ#-cO`*14O?}KkUfm{T&sTr*5X(c<%qoA7jEoBN{SK zuFa{g6Yy_&k04`q82MhR1Ab)DP~cBI#5^jR&Z_{s-0Ui}0h&YvY$@YvPe}#bZ*$DojI%g}H9XlFpHiIu&@?AyA~j*3 zBMcXCFD0bfCEdS+ob;1tWS3UfK!;Cj6V?x>OSQv>B7Uwlju+DzA{12x0YXl__QIw7 zXtB6x1ciA}&0v_|`9_eg&^3In|A?ji?OQ3-U@H>1qS`PzVNLw8xyViFsCN`))@m_t z=zZEGuJ6h)MeqfMKbW%tJNKP2iYo6AB*o3+r+GpmotMB3C9>!VB@q**WwL;W z3Egzrc%xGCzugcPNK(SVags&0N_5D(Y^bxD2jLH8kq%Um(`v6|Lp2ZSy0jJ z;c~%eT@g*)qn;C$nP60V{CUIh{OJ1h3r zFkc2LEo(*KyO`bi7iXm8OF#8`oS=Qc9iW~isKo!nv@}2musj;?Rro4kA0ytW;=A^S zb(Fj?AOR4BS$@}tYaH)`b^pq+X?WA|A85|gc2pkJ9>!4j-A%-nPL2h_XiKFw4eEVl z5ULs~`q8Dy=*PCXGD?!B@#JILU%n{rF$+CK;?d z7E}ah$~TgpP2?0=`<)`J{&9|74bwhkyf+%GLlJ{VmR1GV^mLwO%bNb5bH^;r#d z!-2gaWuT*hamk8CeNeFh_>G0HWH0-PRE@-wMSrT^Ye0Na771*UB_{_F!lv~l-O7u<`oA;Ojv0IOx``ZZmPg=V1? zutPGHtyx4r;GkzC#f*~2JFaO!T{ zQ&`pA76R^C!M>fv&uGy9>hS`!5%d+Ddc0+sc>QPT9uA-L{Y%k}t&e+>su9ST=mcQT_6B^dckYe4sKf;|uQ9 zG}Kl9H{^a~bn}Tdmc5d&#K>>I?qUQhfIv}}$l~)hb|Y&HqJrFwDS8msxZkjSF7+K{ zjFpi-%qLO>-<5`;+|+RTI#LVvUpZ-@??w1L6??G?r2A{HD$<1nfZ?0YFEql{oLNbL(7cEzMoI zhToF+6ct7NnVLO$){6x2&h~eB7gPs$a8~S?^0+yEvE>E9UP}+`!U)0k^}oB}1emEp z!2N)Hd&*6~78&4`a*7BmE1>#6_C9z+vbG$E+@MUMR;=7cE>aps^4i_gp20(Zg@Xkb z8#X}&P8Wl>5sk$V0y0pAPOvdFRMQ|zEJREML0cpKBO?{jIwyIY_>b)|fz9!3n*9`A zl#)@IU25?kz$!MOOa3wgJf387H1&KJbMXc@oN?HG5YCn7D-)a4Rt35u5yo!*ttJ2U zrbt9xfZ2PB&woW6?}ziN(szUJdyva|Uxn5`L%Nq8e{-z|9DX_NU1ERez3(CRtv1qW zZwfMPAgpl)Fvg&iivhM0Rrk^sa65B>KDvd3L)?%xZ%HVra`AxDijlO!MNc)bQ z8TJ}-d#7azj(}hJFKIU7W&b42EmdW~ zYS;@m2)Grnfg#!U6Y0v#tJBmJSrc)Ytr~Da0|AplK0r3eP0E~l-==sB02FYNLZX;` z9}}jVl)8GKG5UOAp0PZQwAa3Z>~@RId;Yd1`2Un2zLWu20-RtkY>9z?vCJZmF5f-p zTft0ayh{jCciO}XpYmD;Y9R^FD%|KRX$OQZS+WBZi4K!LgS)su1)=^!R8Z|K#dZRxf1=lQnifYul2h+X*Fj7_J{ z4=0dribxY_^_GMnP_q?o8P%-DAL9+7&)F>XrFRtbsbqdDJ1uT=@*j7SyGf1syMY** zfqs&ylr2|&E`D3x!7-nKn&e;C{>T+sx|;d}ah8g=kqjZ|yN)w7rS0UfJL?XMBx?M5dpY_b+SjM%+K;QbRTqPVLn+RMC`!DigR~Y5ya@SeU zSiJIaah2K0391t)1!*UPjCEpnYCUo;x>^HJO`j6Dp@|-yt$)an)@=!1A@62}xlO!8 zoO-O;JPn)43%nuj4fjsJ@1uGlCua|3fsd^84BXX5J7x2=(8ekK_1qNMSfKue+3;`?R#SB1ajjT9}o@lzs_Y`<1 zc^xlN*^S-D4LH@kZf?UbWxem;xpV~dz-`R~*c*DmjKmFKf;t%pM_>9%AktvDElD4e z?c?noJaNe*G>2qSTye_Ui&#QuhXSCxdjCuD45Le87A^6G^%kEv?OGfo{?GWUAmEWB z>(=TTg$KXSUNBsqwzrgG+@uZYOpivnK@6fOGg6l=vsjjnJZ^cOON zDB*GKxW7-uSlufqZ8K6g!p;uUO&@5(`r}w(NZ%CSd^qwUi>f>Jlux#&?Ulm%ci$xM zhLJWd(7Rs!P5Wdwu2{+4$3)V6k4M(dN18UC<)H(ncb;q3S=39JXx_BCh_TDpwLhMd z{IV>53;f;a6-hc~k&uM!p^~;egY2seqBe{j(8K{C7Xofx)l)~q! z4UfMp+#dg`4RG;>3%c)1<-f&!GkYTz9S^Ag7@Wcy)ijA-GwIGMe+y5HFlnaYH{rna=Gx9 zOc&la2WT;QXOM%VyQe^uJ|we+M()63=*|bt%z^%ROB3+=DZTcm>gh=%Dx~kBZh8-L z-H}}&sS0<|OhP>G2H*&PwD5kTxCyL(xhEwqnJY8v32HAV&@Jo6c`m!#^Rvo0C z)C-Vl@WYH9@a^o$m~UsA548rjGtE+#Iwl*=sZ-M7+$-@wR7#m4_78uj_d)`D!0@0OlqQFsj@@|@(Uh{#tb}-T9J419vuqh2VESJoIA)k0XBd9_e(llfwWXc zhJ(xm2b^u9rDuwSfN><3euzmhE#_+H*}3;slwMkR__7;1hpeo`4=+Z$`bt~AK)ejem5PBia>(Y2Y(-W2u+ z#&0v((R4P!NVt6^5Hsk$u;+^nJqVzA+*8;6H78rvzK3Os@2p#k42&+R(t}&N{-l{1 zC}oY-CkWH!h}pfEZ#U{Ygr4t(-*)$@CSY7<>X@4EsftNy>^D;{rG#n5!LCf zWtDRI+BmqjqESnI^#sUJP$&@%k_+d3HIn&wPKTi6)Zp_tnbe^DnWHFz zU&-Yum8$lm;leeBZFCu;tDfkAz!e6szU|n-s1o|Qq99oJQ?tQ869(vjN>yYVncV%a zh+e%JHdn#dl-{fO=V%J6A({?cOpr=(5PDdgDpf&@+#q8)SFiDL{HUn&;^#9cE9cRf z3I2}RjtDSpaT-)q5vAzt`s+%i&^0=DNrTHb;$CM!mNgXJ`N6AAs&$|HoYV#zJA^oA(<%zMOUY&70Bg%I&~236E4CU zX#_yi7OerMzY~m&hsn&e@?N5e)a`s(?P-J{w%@y@xe-6q2)2e-;*_HP8(}5fiKDSc&KKg=tl|1v{8ulY^ zgfE7eez398rvXo8cyJ(b8QYl)+erxEfh)ESob`8IM`m*pLf&kZIF+T_6uNd&9Yg?# zGWe)F!aGw-{9Q^%f||TPZ(Kfgq$X2QZg041WUV{#c~95 z`o7KxbWOt-yJgngpN_&lWW99Woe1>Ujwh43Z-+a;C_OId|Ly)Mg=ew#8&op%2H48r z{=A{6R$wNCz^z&@Tp_-ea{6IW^AV`;CbR3*{G>meCA23lSI8`5crLU0nIcc%^Q4G z|C=Q5Gk4X26C3sM@ZgSW-r=^l-u7u9v5*F0xgXGO2$9c*H( zJep@(rAO7?Eq-F4QtvkT4Z}Yt8yf{a_va~110Cf>+-!fr=r2F^{AwXP*bb`r?2ZEm z5Q$lNlh_jh*=%Fw@A__=nkfw(4k$lpgA^LRijWsH`8-6Bd@#kkI!q-oi5Uh(g?Ti< zKAJ_Dm^&|EVYdB{4fN`@GWAlZ&EncQ0d?+W55j;@=CFRGDQ>Brl~YT-=`jdh${bUp38R}ebeEB4@H{t|DSdqw5sZx>ro_@uKq^u}k|4{W5DeDCAj56Zqi8~VMNf7JzN)6g{ zqxcYanTxXZ2J=wpeF{_VOo*P@c3lVaz@#*O^o5xBb35?~r)TxNyu3eI>=hX7->AI_ zyQMtOAMj3zvHv${_L6U+Jcx7Bo)=Z};T`B_ zfKv#QcKdYgpG`A`q?SI$59up8;c(^(g{opNLlb|@m0U!>gGZX8(Phlt*rr+!`T8h4xx$p!Y9%x;E0 z9^QrIX>zF^nHDs$r46z!79NBu+wJNCv1dPl*Ny%!?VVO6C_K2_q zUGwoGY5wD{NaouY*amFLCeL@aKK2E_7Zg z9FQkdj|#|r(^teB%&3jp|3ZbQgdC(J)02cJPFgqQ(CHd_F|A}~ZnhNT^#Nm-7Ow5V zd%Bx~sjqY@T%ookf@@@jo)3W_h3Lk)u-iNO>kp8^-~PV>@M3d2Q$FRR6=R3I^gT*1 zT>CzV5~r;>uf^Uv-@)y?t&UOvQs^GYdEQ3+@#&TSPKhj+&V*f-oxpEKa8mW6@5?Kn zoFT1j0@}tzT3D2>R!&Y$?1Cd!u}GUfT_|`4QvTk)Gz9ozj+~s^5;!gmBzA9xT)I;e zOFSuMYJ5c?7!^gh9#ynsH_z*Ce_#$`fpMsIoiZR!zU6{sucP&yz*N_|=4p~UZpw0G zO4@s}KSdb1>!DhH2trXAyF(0bk zCE(_HoBzOnfDd@%g|if_=wH3FFlB7Fx!{NRIEz!pI}$<1Pmnm@+it&rZ`o$o9V&HE4*>JLC6M7Hnuc~tsA$A3-BZF>xFHr8g%DY z`aAd@1cU?2deAJ9JUIzjwoPn&G!8zhVs&ojTYkg9Gje?kAALiMz5i+S@ax)Pfg^9z z>Hh8BTxjkUcFPGKYg!t#zlJn`9mmj@%IxuE>&|!6>SeRyyC>o=G7{0p2wzt0k`?s0 zbHbd-as7(Ag$W=#?Q!l;^y*xh!HXCuFQ*JWU}lZNTD!mCxO4Gm7Z(o30HHQyQ7t0^ zgnB}DDeUS7M=0WJ!d9+Led(u&sPndFKq9qEs|Db%j}~*?OVvS-8g8n@g3*KK&ySwq z`K4P|kV22jc=O2_WZ?Z>(}5%M@sv6-!rNC*3<|X33+HG^pH@;XFVd^XblClszAUi+ zV2rjxN3n`aGP?+vXp~)cOKE?jA^-{+E`B*%W06GF^X_YCTcetm`T+Z=wIGDkpBZ>` z5*>ihbiw|^`Wt&+Xbo0j*<9{h_VPf#Ws+EG7`%!2z)#q9$_E<1wT)Bf%maY{z^?!N z(BGwP>$}166XsQ8jIGZ~1zS&1-Rf=R;q{d<=9xcwSFVH&ot!bVH>~{7>F@juiAL(j zH^ltNWTe}^_ixT6^rbre(>IO#mE-aY}9F7}>^Z}t*c zNu}IphM4z!eh@FH`vaBcW@$gbq5Js2td{lHAh`$znf7C+0O~oE07EQh6SacvpZvI$ z9wd4#2`a}Ym=wp1U^Usj@RZuGzWGyb5RHt2lhV~lj<1NZe$-__&(;3acZ0~@Z=;P! z<}3TAZ$|(3;r!W)_rOaMMZj~T?9!!OXU0iaT|scxrKd1vUdaNN)KL&YPm~1oB>3dl88F|qowYRV-z^KJ+6jJVRF?I$ML2zk@xA&>OlAX^Mwnk(kJcC#-HF7(OOGm(vxn_>ZQUJKINJIQyd4%PyCDM zrL32|zMynP^B$j9!s86oJhQs(CEEw*2Zq__oE7l$l1yDscQ3Nc_%$1ku0L~WM8QDf zqwf8K5ZP(KTf2W?Rm@>=0!j-si~`AQqDFR&rxT%%>z#2uSf`5nX<4awJcbt?9o4X^7Z z_@-&C-ySDs^b?cKR!rz>41hR=A>XybELM>xk)oti#1$yJQ2tGaSI7i=AZ z6td5Z&%NNLTBi(2$+=NA=?%g+SFxi0yu!IBbZ0pROR9-pR_1u4$7WZKM`YR-^FiTL z!kNb>H#q-A^t!dIkLR79DCmzJ4WpKwFfug@V7|9&1VeL$Fv{qS6njj27@@jtPE~PR zaTM;bj6#2nLt8UgYj!a&ShB_b@@16<@QN}h=v7CsZzDD>Ep!v5`00fqHO1aKFk%y9 z3(uHzcl1}+x(^xp_>-AZfsx`R1~I|fnpv<<_7;E`+-I_#jOeJE|MkUV6?)*!qn0^w zSHIFe9+W`vh()1b-{)MkxnLGEOdhKM7fLQQ$3tZ~Lv9_!gkU}N2^Jfrh~T(7Dhg%2$%!_T zgsp!>8Jc^0`Im;(kTmDbc|#~1Bd5j8oxO%4D&-ijvAszAs;pfMkrs8#F)h^Cb2t?se9#(Sd9K` zmM{%*glt?Y^Jre>TfK$*)u=9AGcmGnL*Aj!243HY{8A!Qm2Tqj0_;|Jl2$4nm4?U@ z<6hc=6vpWb(Kz5P^fNi4I^vv{8-AmV3l7H@>+<8zYs!Ib-~RjxX^8vwLR5vh`?ps2 z&(X&^P;%R!^Ia3t6I18W8)9P9wyc41fXV8&7afSnZ^uSIHuNNjM<#Q`hX+~6D!5f^ zHorRq8kHyrj!ZOQD(e3$r1L$glgaD;jD46}((z(24*E1Tsmu>lAfJJB^f zj*NGAMKw@p<6(kG>P+-4ZSr#V?Ug2-odh9iHo&nUQ!EA<{I;~TQ#eXNfdM(a_rupU zg`idI^(-X#PcHM{ZF+I!-WNCzURn2B96pJ@Vbpogw-b|5jt*>7t47us_M*(ZM2zmn z)p?6k(M*NnFl1|ZujArMElx)7HtKJhC`u7D!B&0yzN|Rg-56y|(pEB;MU_W1E;7Uw z-5QvhSr=UK2nLE+%rxEeKzvA)D%3b!*|TvRup%zEGnu*o2Zr|@{8%!sAWi;ezec>3R#yFnr`mi$CN6`EDV-f$hPO@!az zi%m{|wGq@)wc<^P05m>1(%7_{f7YvGtgjdVv)! zB->A`6^R>ak$Zxc-Z}~4-dW8=Jx?zZZLk0zY@4%mj;8O8&kp~BVr=g~vf!VABaGD^ zm;=T7tUkV9{#TXgXk;eyu9+OLy_?0Cu`4rTOa0g#9wxnYt%2@0-G1>!PlN18+Jp!p zr7p7Pdu;JWmejG^c9bnp>b}z&_`nU#hJ_}}BA9X6{ZJ<3+g2Zamtr3{n&-8<)cXjR z&Tb5A*DOXAo8Ub7>jKtcohuzZ&vj6_b*HuW6)yd(YaNjTkkcA#ZUKR(r?=R@O>d}q zIHPnxjZ$W zE?qpNnN%%nsKx5IHX{GE;IDyFU27aZbivYH~@b9Gmv1e@%c@8Go&;6`WK}M+frZZ z!U9{9phbMmwY}|MFshjXP&I_RM?rdenXx4E#=ZC`@=49&Ix$TW97>Q!8{H{<@DL9;2& z6he<8b|Dh>M9sI)RbSq-5tH{dmc%stf7R_nv~`SZgTpvuI=f-8^#20^LH@pr@+#Mn z;bAOUx)@8BEXJ~>qgcAc9Jh4ID24_HbMG`uMn^HabP1L&8O74Yqgb-Uv|YM%5n8QS zaWgnL7{;>1wOx$SrHiq6(Maw+f+G@rXV5vTIE9%diY{!>c2~??Ip4F%RmnXvP8W$yD6d$zko?c zoGILi&W&NefSL6<`$og|2hPyA&TP15vz0!`FeFu7^x8c6g$>$n>EOn!7np$gMpiLD z(L@1ozd16en_$$avw?G968Y-l$@b>5pYd(XoD#4KuSWZ%*c4}>H=brq@b73AVDcy! zpR%rEa`oC9QQse`R|MM=(O#ag3C8<#eMLV@0X(G3V_SuKD&3z0xUGxl-MvBE>oGs^ za?~%c|J5vfHhLH8e@Xl-eJ`K8s3h1ZDsq&BnMfIA@mOZt5ZBg`aN%!d$CDp}Q_VSY zk1Ef@1%6X$qd<5$5+Y|HAjk;e1@BdUH+sbh-$$rvOp(7EQ>9MQCQ)K3g~wz~)&x_auxDPhBiTGatO!_|)<0J{ijb z055LP{wL^{$2YTsuM)fZ4$8V-~Vp=CN_Cb z-H!Q(0T@+PllS+@86M-`QQsQo!2tHs_wu=kS|y?cif*8pSyVQL5=T!Q316|QzXDTP zhOw>V7~8Vd{M)(}Tegg0^OkXJ+dh$NKQS?ZEn{0THa3p2v8~uLK8CTet=PJC98*(y zwd?r!HrswHwr&~6*0FJH8QY4jTes!H1+pnSmN7Gqv8|@xE!MM5?kyIoA7Vi~y0zg@ zibq!AW{l%GDA{}(gfeW38GL6HC7tZ|qAg*T3QIN~gpPD}&pXwdKTbS1%O5;vBMQ8e zZ?t~};Fq(oKEG1l!47Uc1o0ETp%nqmwM z<%c)4U;!2{UWCPqM=;Q8fx#FWT!4Xr7Fw-5UpO?h0E2tE=vc38=>ms(F0=R1y&fAH3@Bhux8vPo;BWkwYWd_Fc#0G88>yww_ zl>iQ}+4d;(CL#9m4ccCW{xhJx5Wsu&WJ3m7&Kj4EW|rV^>5QF!7P{@ub$H%cYw*2me~*O= z7hu8QK)7n6e3l7d_q)HC6a6H`+d-!_5&yYxr+)O*gvZo71Pf8q$<%l{>?vvem@}=s)}wCWY@l`Vnm2p~;sV3;TE;KZgk#=m%T~U`@^S+6BO2 zs2|8OQ}`X~DT!tRivgU_pnX4n8SrZu&%;MHAf&oVuuZOBn+>j6c`1Mw)I5JTQB@xL z8}WJPDwss?kv8pHmK3|N3u8MN^;A@sqWeVn-3{748o&_dPpRlA>U-Z_JuXoJ)ri0_ug|??7e4wW%pqRA5j0V z?&u;s_~<%gVG$O}xqt_@LUJlf4D~D55(Gx)@3H^(v9I8}*Zdau-Fp=VS}kOpnJZDm z1EtrL0|^EWd=LcX5(^aBD)St#MW#%U@;XN2?Pb_DPj)doPA}e1cJFXRG#S!Ha$I5T z;!Ku#W6_K2I}nB(iL#<`BI4a5RTs&zak4-KuaBT&B%c9;t%b?`ANPGveS+;&0B84L440rD!FCXgZNg1m zIOhPWQ@Sq_Kaa!su~jL*PwCP=ovrdvpqXNRg}rv?V}78?>$)Gz`G10X1l#^Fo~2{@ zUOu-_FXVtFNh8Aqf-;9W&@zUoU~raUV4yYc7LA1eR4{{26Bw;0o%5%1>L9k{ob|S1 z=8gqyx7=|LuKe-uuyW@mR(a)ov&2~Z`QW|c$opmmvc;>XSbAv%zc`XaqAhPFWZrwr z`O7&^IzupJR=vh%zQobkLVKG`>6bB-;5v^m65e$z{+Z)4QOeAIongnoF06v2A09-C zCZbeLipH0P&EN|{YRfVB((y^S8* zpzU}2Xxz6nXuE$8&i{x8ZLfy;=Dr^>UlYuBbTm;zjP&t5F7C7OG)c#PKp(E>C4DrO z$2DmCxjx>bUqO9exTEb&dbjZ{0NZM|?Ust|I8>L`U6lO(jTszY9fEBfz!g2X9-9ID zsX_bq0@!<={Ozgxx}F5^)jk;SZyWG5{Z!6-2^6(2T>IN`r=~$n!pM*V7Kx&cP+PJ~Di2*_aC;OXZ~`NL-l&R+yS7YI8*LD+GU zeCe)R6#L4NqODzEN2qRfM*s1~aB9!!F^C{q=~>9^m3-vZQ&bQ;(sp2gkWDe}T)UyO z{VRSVh95Wi@PhdIfkTCGv_?ple0CLVH_YO>o5=EiJB#CN;xDqK$74CVLE9goe{g4m zw!JWMe_(^QSM~9q(OaOH%NT$O@pv?Vm%^kXe-*|&ey-ye=%3VGhbtSjJ+#lpz5&fj z>wArdH)#9SKHjHyHCWdcOzCh}F}Zr}7S#U&?9?uuw(33R7W*2OsH5b*PZx-cx`7T? zpm$$>eXl{=o$T7I#N0<+HRq3E{Lf|^P3~C^*7x$chsqLBBF>Q?o>)sf*}NYa6PSQy z%a-7mzy2dGx%^6;_Si?wn?+;JqH?;ZERy3?Rq|eCg5B_TU_qVL(Z!<{s72t6!PW%d zUk68qSXPuMCas7JDZdCgK z=+l#9X>ph7(_KG%UY3*|6*v|%1_&4!piVb1Bk zdy2!+8!L@V06exvyGM8F?_m|ec5%U{(Hme?(+5=?dkTO*PGf8jsrlL9Ydzc(Uj}ey zgZ78PcxpX$4wENK8hobwexHo__6BYD>XR||(|dW}qehCTRPRuHQ||2J*^wi*tz}6T zE*!>|&0~1&ThGNUx89DE9`#TV5vHc*=JgpEXkl#YHjIsJvr0V#SAP~7KjCSgFPjUF zTa@@)H3p@u2FJo9Asu6u=40Y2vNZc5PmYmgTO0|-iEs%-f(WvVnIp+qc%FHNFOXxN zrgh973%4_&=8MQS9~9vBSh8sLI=Jg%`ies++zLrYG?Iy~(iM%v{tkN`Ug^g2yeYrr z0}4oZ6x#XAiyh}Kc$Fh1sk~yz!NRSs<4xnsQ-N?1$t(GMxC2RM&HY5Sj5Qs@tOl3O z_Rad125s-0#c^)vlef|XQQt@GcGUYucqY*#rg;^*r-s=Z&B8SL&4)>1Tt9yG1r{QZ zW{x;J&^~q_^pVO8V6R>a;8iu- zKCnk)_&R`()o8aI#u{Qe1ok2JeX1QUDtY`eR1<6`1NhK1##h&W?b06Zi7QZ#OqAHq zk|*y4a4!1STA~a`HuzlDFNwe#8?@cEPsaR9C~Bj2$bl!&3Jltvca#rFbRJq+hQ*5) zVZ-`Oc=Nyh7v6F1$726<$(@wEG&tocC^fhbH~v&m%0~r+Q<1s64hAazA^wAI3q#2NdiogMwYbkZ5=sg|L@8$3ld_9 zr5-Db2qyDr2Ct2ZN(e(8p)YszC9^W6G7G~gx*i$4FIhf@H1lbu=9o+nd~!}PQ|P;~ z>NlY`3&*q&%hmj{i3HAq`FQU&NJSdQ8!p75ddey)Go_%WGuJGO%2qqvG*19H)OZ=$+-K;Z?Or}tpMvQTY*p!@>rifua2bHtR2+XIrkAW)hhY0TdRxiB0Nw%M{~8`Q z1mNv3>bDQTBo}YS+`!=t+V;~Ik9Dgd_UM!Gs&{S!4Ayz2BIPn1M?sJ)<(qXq=pT zoYU(x-93`*7nXBQBSE?3I_CBh>pN;SrgRDBjj3)ObkobO$%m{z>o!vWc(A=GeLQ-n zV3}{|SAW2!{*V1au-(u{Yq-xGy%BGB!<(U=DsT55j^k^nPq4jn8t17h54{ZKUwB>( zlf>9A>|qg%M_(sj>McjT@TRZNz`pnbfEU3eYc|DhFe+EB;F!ra1LcrW1yzT=^ZNML>%P1FaSY23lwhv@qBrP^*PjtA!Ss z$Eel9fPHMB)xyBwfO)>vLaRk+4Nz#`YGI%?fPogF)gn;K_V1r}=M#MlP&miHfNwuw z`yLn=F#c98d!82jcv@u67iga(DKblg1Vq{;B}t=c`e>(QNmkHb+3&f>5kD@*kBks0 zoqQT@G5NpgTJJ?BdULlUL$%D*3&2Z>`<6v-$>@2SPURE}K@ zAyJfR>QX1;@;r(O4o@;5QRvZBIQz&W$qvn#BxF;f@Jk8CWZhW=I7DkGLlnBRW$bG$-6Zk;apkXtqCSxx zT%NP4Q1tDGg_*$OF7~xsgSKmRo9%E|0^nT$ZUXRr^q<-NTtUB<@i!@}UfxIJzPpdc z(&S5u+vmuBtxKY;>fsoEiF##^EtoRQPVhvuFK6Ed;2RZvTwdcmkLhrHb%?n;0Q_u* z_QmZm;S=3>KRXe?mjK)hQ+~QfpS=d=dsRfg*f`t`MQv0PY%J3#6JCZW&=MruNh>gK zoSsx;S}!M4&KZ~1v3uT6w@Zsmc zuR2dP7X5J`UD*>eS;6@rRApIwz1f~$?llf&m~7|aw_KzS%j_O;Dy$5k%oAE+s`fF2 zbtA8AgI}Yt$1-6x#(r)5btZEi0_n%moXq-Xet&wECufG3wrgSb1qpSXoWGbOb)JmD zer{5!X7(_1tX`vNKH)kOi?R7VuWzV|T3EOP&9$4~_%2@HAEaYgeG!GptUy zz!5Nhl}&LX*Oi>!9c!!4|83 zVup>Kk(MBn$Sb@g-z7>2#f^TbQk3O?u07@4q9O+_4oV+S9JMK%3HLXm@M4lFv^o6`qdCsULFjdy&jN7C>Nh-XGRBvIi zISXpCC|n_3|18hklDE*0%M&R*nmK9}_2Y>*;g2Rrqg3%1vPF|?QlOHHr)5)Dvk<4? z`Uy(PSi6{()_Ss!EuqU<@|uZDu)AV+#&IBt?2wYRNnbhXUSdyHE5oL!g(bQK9id5J zf_nY!7+3`3lXC%j>#vY4&WGcS2;HTQ!@G;0KWq8Ow4ZL^r-%M z*x}yG`yMsw#knwvl1lFKql!uSfN-_<#8`4mPbj#Tk4T=BtcdUVU3dbCGC|X|PZ15^WM2b10GF3(eU$-p2wuvts!ObBdE=9k{m9EP3x@(yF1iHS- zm%nnsKe>n5E4PA*(W@=R^DKTQ;lIZm%1N1nUm--l1feYRYcG^{qHV|f#j68@G*I^K z=b7veaC{x9sBBoFsQ2Ma(HWUi7n^mt<~>#d_&$K=&EPpFU;;EQ1Mm@;RKC+-Qb`vA z__$t{o}mfBu4&cN``a^@QjVLD+P(D9`YwPiHQMb9;J}7`pMv(vcLs1t&Az@-qfJwl zU7aw2aRA?*r9E;pfQJG2w;qrr4}eK5y&k}eF*`nOBl^~+n1cjcAf-sKU~yt(P)L#V zXA?Kv6#16{MTYP}n?#XpE~wThq%nr5QghQ!1vXwu874=`h%x=<6-Sg%icEqSk#m=% zi6HqLnOEpXCMx?J5hc`0o$@7wKlPpOE$9qK( zh<;rhX_X1Du?%62kx3Uk@i-C{U?4xe600mB)m4JVGs`D`qM%>5s#(&X42clq1sgS6 z{^i4gTtn>Z7P^epek8^hsrO3Cq3eQtiL4BZXo;vo(OV2PXsh2e z&Ts4tL#`dugT6Pxcq)Ab!21B4VQ(P!wKp;c!laVE0>B4hlqa|S>q^1N`Re9(&0Pd>U*JU-@G*z(GQRRIXvs>mp0pMR?2(in0 z(Et7bJ^`Z;e8LRRZ5RqgpP>fRY{@JyLdyiv6$lB>IkC~@XY z-8_*&Bya0U5JQ z(nl}yKj6Z02Cmee|Un*A_LdCzqKeq(?B9n`DxAb@{mjHNjO#LD*c>V2nS2QFyltAlls$QNO9tU)|t_ul31(`6J91 zBoBcJEI75x{U2!O`V{~#Lw({?q1eF)HcwVi(G!+vK;E2;8AMc|wjo2NNf8=LA)LLz zcMnAJFcQQ@T9Fpob41t#0x79fjR^|>7)9MhBnt<&$NyI_B;*M!*?sEx7Tm>Xx+$XW z*bG4-l?h^oBr}yiICn)|0E8v1*oDAKiIOKGDN?8TpO|wxx1#0F?+J@clBt0Z@?0c` z6j<`>7)pbK&Wcm}H<=+TS;RnWC1Z~EWUe0;>aDOAOk9xk$^LTq5DmXplndP8OkO+k z`zkKgo)#;c>_xz{k$x_LSSJS13MH=L)Fg;;m9HrpZ@@Y@55P-x$pAF__Ip8}&qYf* zI>);KJha1OH`|-h%VE?eN~X;n?9!m^gf3Sh>iXEtr7tL&jJ4OLuU{{?8!W+x_H#cn%X)Nl`c8^BX4+MR-W1l!R7cB;8H{e){_5>p=n;LWH`X>E$9!jz>x8%Dj? zOKgFL`zZPh)dZVo1p>hpWI=)fu{Y^a@}{goE4sV#shsf>F_A#Bjx9cAs{RrxAx|PX zokW_1r zCC*}X9zi5`3Pm0T(#xsK*w0<6^*AC|eQK^F{d|(Blp?xr$tRMUCU(wt&q`92z&F5j(0`U3{j{7Ts_XGGW=58A0j*e9g+Nx@#7Fea`wQC30th^T0UjU5SHs7z&?P(Ry{~pE{vI#CjHNkc&fd8n`SDkXwUjn$bPxsHY zFeSMA19&-rf9m4ruH6893r5NIi5||O?iUJM0PHmf-?uchY7U}?f{hcuHKbCYh!x4H zwgfpKJ*SXz1~IFXkVwh-b9JYJ2#6Fo(rS$h`Kh42qF5!wB6(Ak%5l+r3CLIMWkKDS zTMzc6pEttq3OKm}_Ef|%sm3Lj52AdOWk^JlB3fi+$1**WlDg4wZ8(`L6@_AQl8)*g z&RDRRG9rV8h^%-I#XezNVkeg*p2jk^q^;a{V*SJ#OJX>zVA%9h`5E=$x4Tpba`Kv- zu7WL#OKru(0;v{{w6bQqduM1om!O`)_Egj(*sA>3F6v;6b%G9#hY3~~ zuV{C2%{A$F{1qm&=4=4Z1#l*S!@JP$0D$u?-|(?neqE2E*%!PDMaO7$d?Yt)%!O5o zId8U3&s{`NH0zSvpF|P}j=;;Tr&=b$8eDLIQyL}dm0o?s3}hKN;~eSKY-L?vaVS9; zv`GM!V+*s*V2GA1Nqco+12TjH@!TD$X2S|dl98evyLHNB077i|56+_Xas32!Ulu)w zOr()!?8{l*dN3mnUC83F3lce}GAUIioU%yjB$0ATax9S-Ul!6hB@4%h&kwe$$8>z~ zKZiZRQJ=&`*SN#iF2`%dVsHBW=u=@cyB;xl9gTk)o^XmC4tF$YySFZvM-x@bZhbzN zUG#D`#_=%aQgv}BOo`5aVCKj*b>i$D>LxF4g$b%qP(PK5%DKV zrdh6&7!xP!5Un@oN~EJ}QZQ~JPE>2%VAz0sA}R{9L<@*DP6;)Q5mhw8Z4KJ)tIOr_ z_Xch6*XMKDOD|_*yrMzd?EoGNQ<^lBP{nC)umHe5HQU~-%TPBE0-cGT30S7 z4>?udNyQ%$5g+I01hFnMsUS;8I7z$8aa$!}9J*oKkn#Hq++&9B5Nw&ho>7UcpO#cR z%5#dfcI!0lJ*?Ql(By;u67;_sYo^eInA`)v@;;u+{q%A+!U(F9^d#N~;1{zn&N=U` zH@IfyP#+HK{xGFhb?`@hxs;*_`FQvon9l*IA80d^#A_WD8=<53f`_Qwe@g6e@qh#wgnhf4}VCeW7zTfe>&Q94Sg4wK3% zP#_(c385aEM#zCoSuIe2Mb(m!zW;)lOUhSc&#gQ`L=fl6ij;Be6EYzJ2=dCY zR2|30FRpOii%ioBlzXW>+%NF_db(&JepY@)IpOk9}k2= zF$1VYu&Jp=OfLjZK@tm@NYM-=6FJ40`(1ioS?@FIkeu*hF#7{ZHJ$KPBdfGCm5)LN zCaWO@8OU}np4bvZp!X(=e7v%dh#GjR$TQ3kca%FeBA-Z*Su6t-G8;g_1sMiezFadc zX%%IVA>2Xw(1q*b!Z@OIQmNMR99jPQMk+TO8OoBt^x+;tHOH|BU0CY;T1yW(uYT-c z)0mXp%x@qnAU?^3JfuXW*lUq+QKYFV6cv~N@P`KNAFN9Tz@()$Nt1eHpUz`64y`$7cc~285d7N zriU`5$}0(a5PgIM-6W}0^h#naDB3fzif&q57KyctN?paZ;jovHhBicd%U%oCkOM_y zG*MZcs>=ny_-g&BLHkGb={z2*m$EUMDE_XPr7^C={0JrKxANsWrF0TM)0ayreu?^D zQXGx`H$<;X0!{(=)eMen0`)x3c85_z72&jsV=u+@!&~Zl z&lyes<~#|eT(n#GO@p>duqkE)Gg2ZtZxnEnwBb;4$jk|0;e4}PyWmB}KA{pKX|&UI zC3}1p`gJ3)(~g&8m6cSqIhrs8HHi7!ag#_3B^D`^83*B$KUE-#C{53V zAleFo2xO|LTzBu?hVXp8Y!g8Nmz2c@ahUDX4^}3Ja+D+*2+O#1lf)W_AK41lL{h0e z2l;&y);YGmlj{*H6&ce^o)yKm$}Hm+^Z_86!Sn?n;~ z@^}EN`fv_U(#zNw`}b&%bQ2GqCu`krirFJkzx4Jd0DsY!ODVRZzQV7C{{AvxSp%}* z=jcunWE0d)6D=aJ7NMHJy0{Bt{6>v7CzsqSpVY-Qn9CTmf76@%-5Kig-;3K&KOy+O zP!Cwe44^jz8x`_W^9CfV{nA--C~=JJ(L^~OMGs&l!jYnC+Av;s z9a(PrXt%~M0%A;y^i%9`Xj(S$Y+W({z*PH)wmMzEmpl-3D!+-^cSf4fO*KE}ez(U5GV;Af<$``aC{~O) zA|@@Vl!~+vJHTQ)2{KZwnfsjtiANlic%GJG&gCRfVKQj&%Hxz_6D7IKQnd!5T#G{q zSd>q460|_co{%az&H~{W5??#_>&tB!uY{9Cnqb>9L7>7Y+oVTaycZG@SD~oJ^=M|= ze+JYJ6lh+G@v=S}|BD;k6e!@Y*ly!@&PVY?X47A%I*QER@MI!&4Y>NGX4PI z!UpZT{T}Jxgeo(@hPy|ZO5-FUraL%aAQCe|{$Gp0Z1u>VVQ${vk9QmXudg8QGNB+uAS@v~`#33=Rwz0^lW(981n^{CGW@CGhxP}eUMb5=U@?H#>LqN9 zp*b+dr(%AUalfEX#_{9^>$(j)MoHRqaW#NVHQN$^H}~Nj4nTdy=q)fMqO*ZZYP1?JpVYK757T^wVbGSQS^JE==^pKrLJLECQIS2Q8m4u^(kDSC|7OrC7M$Pc_4i-a;u zXn2S$0g^M6m*tOwlQFR;AgO^!#9U_wFW)rE-t!=yTlDfJXfh%}*GlpbkC zK5!_#-W-on?iFHD_A9TUm$+fh6RH3Ma|JShnyX}YX z9UWh8*#2MpXNYF~Q`L7qg&X;%OMxGeAtCU$o5C0oss)pd<@PpP3Yz#p#}cXbOI2S+pcx$|u%~eNcj3ClRiY-!b_BfSivT zi84_H&$TFVl)^cJt(Y*)OG`QhvFAepI1U{sR>fJh8_VBi+brS_4YJ4=ErdE`sq`&Z z@!I@_DE6$_ztWpd7Bhz=)Ub~!X|Md6q9J|&;Kl~+4~8nB0N{Tcwtpyqf1KqpAEX~> zJI1z#?PuD+`B`X|ayl2V(vldniD#lbVX+9G*Oy9de5^s+1pq$OM`J$_z)NbjodWQQ zSsd$MVM+(9APK9g^w1vz_br1l9JG7x)u#X${}#2}FHAfw2Sj0-NL^b?cim2MDmID{;< zjmvyfg%*qQPOJWkLMB{uijE6JB_|ezaW-oj3X!Y*&CRblq*9N>@5I3^&k?geDV5`6 z{ncX5za|ul`ft7e)9{#o18~R={`d5!Fr}hR@Ie5(&(gXK0r(6|DUhN$#v0y?96y6& zTM6I;^K{+cjM?+wS^?lc8??U}-APs4QScK0zi80@i7X8w7Vll&dlP)sP{qLNKB z78#a6B#E-16k{1kAks%!5Opj(+aQ!!Ldd?IPFaY4wc5lr`ES|;J%zpvcwc-20q`piV;hcu;KY`i*a%VM~r7*v%57xP^ zFW|8-B-@b{?JnxU7%#8!sro_o|Hswn@9R70YiiF1ZSU;C`F{^n@>>^&!dQeSqljq0?zf&brIE5_Jl**^bh@WK%XG#)E4=~X&lP8FL za;BZ9?-MfULHg1OAy$?c>8GSyRF0VXlCep#^vXJsm}=Xz@WGSixD=H*S_YEib(bnY z!A{244@j<6Jbq^9WoFN96@HYGVzOM9!#c`7Bkwg|u8KsxH?7TU_Y4USI?4wi5X2sW zm>);`4#-i?3PoM42k`NR$Lt5=H?*t|#=jIsh4=Xx9?z#c_<(vcfRE1b`kZBN3Ki4C z9~-ni3^Nl5@_y7eTA!Z25IpQx9>8A+i zWKJ?T({+zl1VWIvm&t_rWIi6=6x)6_%9T66Jv>|ycv*XEZNP_e+b85hXa#oHB zGj{XJ;xGY6$gzy4?P%j9VA zVL$A@a2C$Jwc*W{!z?=GHoijW3D%=M~QPd6>^>Cb3 zWui;%b+1y`eGjIre>U(^`*(M?!l0TERX^#`7%m6!%ZA5%5+(_IHgPbFFY&*iS*fj} zPq9N2Y}}2ba|Zdb+ACGCaYRN?cjmyUj~AkpOy81{6wa7^i%BdlQeN4=mDXd7;>3hl z{w93fVsb8wGa{=}ueS6eQ4&HRpNq;?WpXJ+^NZFZIzhqjvRsqnX{LQT?l4Y}K(r_1 znneE+3p-bSnOD%I%DHK681aw%P=gFHuWZcicXv&q=kyI#(Gl*pA1a#SXqa#4kDKA~ zJ_P0)>MvmSe9Zt;M)sEuj(Z(|&!TrJiNgTS1Mt2!ZT_I!z7eiy*nVHTKZm+Jjv*M| znm6rW>;I7s$e5;hGK}h|$<5Ut?bsBZ;oEl2o8T}QAI!sNXpF}LxDw40nBNKDhCW*7 zI=*Rp!Kl;Q;i4Xn@$wpN4g#=SMVr|y4_#>g?*16S!)N&1j|Ff-&9>L~@G}4dcx%IB z7QiT4Up5QZYzcsWhf(yYmBu`RmWXx&O4CCV;)2QeZLv@uMgP)7$!Wfo0PyN4iaDK- zteN-s$_E{||7S_(LcQfp#GL;YA$XDr!YJ}1L!7iJ{mf$4%KOr>AeqXDEw8$=k4x2C zyy%i>Lo#Qfth4=bdMR@ev21P6JZh!cwg62K{A$2syagj7JN%mlI7@t&c09KlU3 zzCN6V&&HVR^hlz$3ENBAhrw|7mkJAm&4SOZ|EUcT$w50Bq~Q4^ii2Wz$sz$-dD z_BjBq18`KA$8?PC_l!1eZruS1n(5-_9o#UV3gdsYqDy0V0DvE%Ji(CByRx5tz}%l_J-m+^fJw6b4w{i`KZH>!_Y=Mi zV0%TILlAt&UsEI)8DnxQ6~Z zWSqM;(hE;yJ0#QMq*PR)X#TDW;05R`S*iu|&EpLK&IPb{7ss`){qXZg0N=HwML*#i zXckQ`aWH_N!Km2|oaQ(VvLBj%g6cA#mjT$MTfQ;Q@8FnI0Q?H3^srOh2SzRVb9>`f zhVx*`qvkr=5dqHw@H=$RBj+KO5P4e%A6-9z9oOrro4C_n*QUN3ivWDc5*d%`@|Ye4 zL*V@Co; z9*f?Tjy@4aF;_S2W(#J<3-+aGZao43&xRqrUWVQzj2-~sJpld&W3{jw6!Q}El3?SR zI0K84%P1k!rAa1117s34Ss3?oq%7-nq9OUwtJT0D&TOcGBvzy$za&>=5CVM3Wu&}v z=KJ34Ef6py%TWaxC6i1^KF1t9>qwAnEX?&ul1Xvjk@FXa)KVmgqft~UhoA>PF7KDe z!O+f@Xu9wQSz1cAjTZpQb8)^8d5ygKFDkJN{lw?X;u7CfDHhGOvyDSG;T0myHQfu0 z_?k%t9woBOIAv9#=m>x9@J7dB8GttexCy}3Fdk9IHoQUE1ICNvT>D}9Mi}}2fqlGg zFSl#g2?)kF<$4&U#2KhA({Z>zj5pN}UzK5!ve)w>m@?#7qWw4QH(~y$607F1FN{j%T6+WA^d_tY;4zjkxCWh-1^pIA-K6La zz5(Fu4v&2(46*zJ053x4-iJ#7JRiVSw!dQ=9zOx2u)3vB*Lb?hu8U@9AI#<)dxghZ zlI>O)f6kL(%1JxLfPD}9rhOl4qWF3r>V;lR7q_8YZC!<(Vbp9l0eFY~tTP=P2xHB0 z6@Whjcr%)*QWbL$DoLCMw?%^B3ZNJSEfbVmw4VKO}u zfxrsYjZ(WM`d~M1jw>}02)w*+8iykUk>u9MC3@znE8(g#MQJ7>wt53XVki(Lv@!=z zF}CxTUTSGVC#5R5h$XU_nbu2#+$ow7q}QCg*7AAwYZOg0q=j-c(jEU7+livTBMjr&@%jUeG)0i~dL^ZHf&r{!KrGF=Fl%C)$62DVe(7uGtotWV8{OvWETb2gatQhd;rNV~pRc z>wGqhYNit$4WlxHeLeia-f(TTubE{4_O#dcz76`Fg!$Hg<2+gC4+D5QfQMDIdoWB1 z)_NFn`YHgww>M??zufLIyYDAV7>&{qA!WA;yrfXzqrHWA8!AB z%)ZxM4MT+f)&AYtfbbRaGMIp#{b3Zp$JzbVsbVIB`Eu&}eZ0P3L+8q+O{iADbpzkP z^bE4U*5`YCH~TmE)%Jb=Iv5|@U)jF}H{17d_ujGqz^MIdRYphEe|rn#@0uQB?Bj6Bx;na_qhL$r3I^ofoxoqA)WY7AK?)$6_(7!eU3Z*)fqN zz}#@0(v2uC6eVG8#!T^AxUxq-M=~X%L_T~0Nnei6ljL9^Faw7}j_o2r?nMCu2qYK> zk2NYvP4JHgYKb#(ZA3@|3G2CpdNPC_h3ia$SR=7El9=*@r8{59z=*~qLmx)WKF4*I%8l;^;> ze0d}!*%d3Ih(ZV^9H|D806I-eElxyNu3Rsi4}tiCBiaIcC53k^f(_i*!>qGV#wg|z z7N)>|O_apCM@R-gL@s2A%Q3}TNiA2A2N@UnoXMVj1tiCh`)ilwNg_{pCFGba|D{kO zDVK_hf)K=>fS4C0-fWH#WyHR6p2qA#04?Xrh3(_yN=L<5#a#T}p+MaFvR_rODY}Pu zz$n=i_3>>Ol5KmRjq7hP-gS5CC7L#-VANH2^~ret9W&#nGt;;MrbIUDqcLr@ukWk$ zWzf^t*YnVs-{EXvyWOXsog?GDq{HJbp20C*-r;eV_SySIKVcip7ZBIa!nvKl@0av4 zC}t9xBHAfEAwmm?LpfqF>37~-6!~dMZ?aG($$j=-(NHP_Y zVvn%MqbuUBSai#xJTUJXGK*C;B1jcPB_KF7h{n zC70ZKkoo6>2n0FDiT9dQ>;)jY2!;&Bj)FXii`~`~0sQ$TlXE={k+FV)8z3 zp_Eqc$%r(Q^WjkL%hunIM47Nc(Pg|Jz%wv6N}+xO;M09_19K`mGxzNUehc7ubnX$S z$m3Q3kH_qnWS$G-c{pG3O&CwDe!zMFkAv}1QuG#60M3N@f~TJelfMIaB!CO&(AsuF zuuWR>YNpVsN9fn|rBjG4_Py)7vp5DvM9&rCT$TRw07|fROj4NtvmlHDX%gB+&qH{C zaiU1-bR6PLY2Rc&8>Ht6WS=Y*MJVCS?8k~|9%(gZs@h8uD1}N-RFndU6=WQ#xrACP zQQ*aA2t*}k$-D}aNsF!>dv%td4~KcXfCx^KKuPpLzJxRrzH?c8O{5acPK<;noFpcN za7-xR#F|Q?aC*VBVniHW7kOHeglvXbVOW$KszjTj`?wIs$Ktv^9p4yCDeKWN_(3d~>(o6p(-*7?&gB|)>9%J_R2BmFCN+s`Q8 z592j;TOW??GMG}!Yv=>lVCw+HadM(mL=nppz*xDICSk%Unx?^)Fc`>$cNT&wO{%}#d03=+ zl2DkjC>!u^6CSXeA4gm14JzaMo zTVM2#8bw>QW>LP{(%NcoZB<))2a(!aY^wIAc3Wc4wq``E*fEO|tF~B0(HgZAMEIe< z-!K2=ym#*ToOAEF_niCQJ2%b8^rJL8Br!sHGsE89OfF9QNEiRxci@#IA}_tUx8+vb z7jyqR-gN#9Tu-*=jU;i*e(~qUGXcPzfHa!Wi((L_9P^~Qf3fclG}GUWYUZg!O&AAu zm_$T1X$bwgg?tf2Bo3+rr<37RNs5R{B zuRTDFmfdk4>pjZuQ!b7ZW>E6xGggXu)Kg9pF(DdFVYI{qrH=XZLV@f*;nG)SX6}J@ z!rz0tBnwQ_7mdPwdp|zW8CcW3w%PFhi;gk_#pjT3mFL0<6ung zjWVDtyM}(m(;ZhdQ}PO0o%=9e)qhFSXw7b4roeds_*Od=af%F@tjq1?7JjBQOn=Bj?cg;c^70nK-+xAEec_4F@$ z-%1B79Q*q0^=In-X%nomhTh(=MhIRZ9` zesT&u(~9wlY-e_Q=_mKz2*sZ}*c;ICkfI<72gg0y$)eLv7M-TI`KV~m_G;we^TFdd ztNP%(iEB+dUChzH)G9Sv3~H&IO;TRY|6ZVuFU!q@)@Vo8qoBoZe?!AXnyNHE=tXId zOn`~4@{M0MwrJe4xkd_>E$BnvdEjVK0o#&#kEi=+MeFZ{t#?QHh97lBsXmF!xUs2+@8a+E8*) z=DouM;9sE{5I|Z8*>b}k9vA`?M}KciV7(4nv1<*%&gE<1&TXPo+PKD@U7^)Ki6j-O zj3x9lXr4MIL6Sp0|k$T>KWc?w|&}f`Uf9ZV9>NVf%q%`4Z3Zbfpce_YH{~10O z@TTvf{bUw=u=f7EN=1P3p_x@_uE;(k*$FFcXnQ0dRx9jb)+fN&Z`(VL%aZLiWfO8_ z3AEgs=S%$tA4|CtQhUDy3evnvO+P&*w*C&j&HNPnp%g=7E)x06IOU;f%}{4xf{tY@ z+3V4%o`Ot20;|ufDTnhzg3Kfo)BQ0=Hj~Tcpg91YJS69Z^oFPyQ(+v zHTZ@umunJ1Vxb_-Qb?YCaKn-@t!j|i?0c^gcHxd{Iiz~SQzlqpnx+5Grw2&^EsSe> zj@H+>yoNZp`Jh?Dogwv`j z5S{)M0r%s4mqUcC{n12x$Ze?##Fr;cgF%rTyFoV;b%wgC@|+QC;BUaR5kG^#pbvAz zQ8BG@O*1$hpP`Db@;MaNW%8ELdiq5j6|%O~duCg!p%QD6J{5yEe?G!47;h~cJOHp# z=%&0g1^CSjU7X3oq>-=yIma&85`2xZ8~S1#_15NX#uLus0VpRaj!!b54Y4ybAJ zE!#g5pA$X%z|*yq7goFULi(^oQkypvq$;z^0nM{(P{wd6x!`)*&*aMv=kVTtrSRT^ z+p?Ru8}8dutx<$5E%`SK$QGOZ^SeHoMaBCIdzq9|^GEBZr{t;J_#e5)&>kD?r&OL? zx-a$(h8nS29gMoK6HkV0oj)*KE7RHi1>)lCqt}P0qoV9Tw#*tx(~pAOE%}kLi@M~S zRQ#@G^bS&NdQ(MpoS#s`gHd3_5a*$A+0%K1PnO+!tSDMlQXKq+n9*b<$Ofjz)u;2v zqQ7KfNSi?#c4%9i_>8Iafo1Td4=sx;TpD)V*IxseR2Ymiu=q1>INPZf&fvpAn89!oNC~xJ-kg=LX=IBHz(f zo)JM;?usr&fp!Lt#}1rtIIoq)A57|e#CjEQe(kw}PT=(&Uo zCvwB|Cg*Q_a_0G74wH5n38KF0ywMzvL6Se{GcT-8#7 zu%};#RJ{~iWo~VJo;wyK23-8iatG^4SZb1Or%z3u2zkh~R=u(jzc*QKVo$cR&S3<* zdqc@azFW_W@7FMkhTE(Sk4uc|{hoV~w@Xd@M!L3GTOQ{4#;rK5D$2-;jrGKq2@QII zu^28JD#CcA`awa7imJP=CaSUs%nUI1@wA&wm=?}s9h93_P+0reIJH0Hx5Z8JNnTbK zghF&4Ck)A7Vgks#Af4d?9eZsW6w)n?sgwij$K)lZu{B@)U8G%arr_93nT(5$-?1@t zrW&>sc21h}2k$PzD@zBdO#9qJe7}fh^AB2X#YV+8b$h&@!5-W_PUfNZP%Y9Xn+^bKY7Nuf0Lv$Hz-=wfwf|9RwE3@26xSEy_>r#Yb*jVkg`SS;vF6 z=fs`;ShMop&Vrg+c=K~RXu?<440v#Se0QB(Zq2PuP_EXV(X2UO{miKt3UeE^%OEC~MVI#=-6d(WxF@dNAcasH64W{3!aU z8R~*UP3xbb7)ij!7ZrG7k7y<=Pt6JNEO%5(F}Z=-NH!a|uo7GAw@I!{IpraGZq0)HXBxho5q?<#Mj6q_ne#$`S?U9Q2u1c1l?7--k%Wbl~)95I<$5h6hV>_R#+G*0U zwr>9TW>zuIDArv<#2E2;KR?FR(3&+;ly!Hw*d%v^-TCG?xYKj`Wa2dYZ4P%fD=*!Z zU8fj%ro^?#b4G-Q_Y`l8jwvEcLPQHnc@?TQi(az0xtH{O{2-h(G;S*Q_)o4IbXm4~ z3^ow8Zy(UrXEh9#1)hXQ43{vzEFldPxJ8&RyZP)l6eLHxsmgEsdTpL}e=HHE4=+(` zJYaiw0&;0~<;yrZKpTEDFm>~}J1pcPGUtNO56;KHp*8WUJmcO%YFm)IxkHoBkoWs7 zI4%B!PPn(lt53;-Bi}BRnGWssWA7^*j!Lm`Em7f;xIbSSHyHIf)QMP7|CL){QRE~X zRn8V;NL`@k8*x#~zOlbD`6*1#7CFq#8cPiYH)LpVYH3Tiz6C$2xuN?+j?{O;)F20d z84TjwS;r$}bjT0sD5oQPY0UBbS(FQC+NYiAsjj>RE?rI~aDe`-X2yLGZ*OvHOQhu} z-BPmB1Tw`I2&=9Y#BGdn!VmQ~IHHZ!a8{jzuupX3Je6$a zy|XBGQz;2Sw5Fq^2vtg)zMWifl_*hlgxhZHx|i!bm8pHNH34$3^yih(+wjqsEdQv3n1P!9T_waA0%tZ^N1J6$c)A2kWWeL6x7AutSUE zi)RCxcl1kIU>s$BY$$CQ*4I?B;LMw!EO|xV>%Q65thq@`G(*Pylt%$tNrW=9*D)Hg zE9psvWNG;L(~9?c)M|(2(*RZr%K8+kMSCn-fMIlG*WQt@gNCGHJFh#mjVIccamg?} zPT=KH)S9qWN*1ct?>zLCGli6AA@}URk!JI6#Rk>dXXJ$HX@;>hFLc%1oEn{T3YZmD zBZo$^ ze5#h5UR%npQl6tGz|+aTu;9#MCX52Pk_)E@%4Tw~v>WOCz>re2_|XGV3EC2SDZz&B z|0?b(4D^hsg14}Gey?oCYA1ns1rrJ1AyayA@|#H%7DJ6d4#vKA&@)p*9ZXSDWD*Zr zaxOJVZrN(|h`>~C^jke8iuwRn=J}E%Pql}Z2kStZ-(|VY{#KWTdE?beRf{2rCHI3Q zXWg#?xO7!Hy;FK6;+FHjQDXYLy*32MgR*i=qKl$?h>(S#$r59@xR7ls@DWIsUg^9p zA8v|Tm!oJ*raXp#q2qjO!9o< zyDpTf7bb#}oc#}&>T@HmS&i1IJrSn@WAo%5Ye0%@Z2Ogwt8Q)c8@L$B2y_)XP7v3z z-8mezhEob2@QO^z>Q|p`#-M5OmED2n;(TwndXn+g1@?u9Ve>_HwVYWifs^wPUddO;&yHE5zX28u9dX zU-mBx(xk`_JUN~BTXY1X9b@k!%OYbMKr_`RUSk-N$Wu}@_aIYQ*O{yQe7V0`XW_}% z@UF8Omk*l-C{?3&8=HhP-$%pBYJS!Hm3SFuBlfy~JsFe=$!M`16?O9S@6@itze%}) zi>{uJ@(5oOmAlQHN~zoVZv}aDt(L#fs+TFZW_5f15f4v7ymGR5#oo-fa9)5vJY z9Mj9c;3h2))fi)qlpxD}xRzVK9l@ zPOY%dD6C@NKx9JJ8Ih-AP>=NIUeltv=2C+te~V6KBZlpSq5B5&sjE&k0AA5V-3>Uf zm8Cqk%cJz-8ztva|Ff0Q*T;<*QKS>rvi8iU8jE_XzLE4J!BW0oxyqZZ)v5JhU%`>x zf91NkT%DZCO|PbF67w|*gpq}*FR!S#Hv9R#2{=7^1}d>;=M;3uL}{NaimvVnwGq?A`;4w$ zGV`&bliK9fNC5@JyXH=}LgMHisVr5zA%d?)ufV$GX}|GM-IPIpXYFY54|%6iIlcQ- zs&AIv;#AH2q8CGkaB%gE&GQ`DO4G9=!6}!s6NGb+-E;P)x8*hkli*qV@+?@-T}MK9 z5BVkZV7dDjOH{1Ju?;dB+HI6Iq9O!Meb1(QvcHaIuTVJNbeUlf+8x?tZ`t!ova+>J z6;zYePdq{YT`TlkGqpLN^eGz^ot~afCyYe}&6=Daz1nIIyZ%bP)khizwH32T-L?O# zAC9(7asB6n-WN_-tatAiWQogP4%*NZ#|i6hzOmueH)WCaJs6hXJ?Yt`MFhq9h3$8- zK?;W%E3hH^U6v5@J{ZHe|Gc>B@IMdXz3>o+(IDfyS~Q;`>zB&KD_znvmROZPQDnVl z>i_{m9HcmE_?s6$Nm$vii@+Ce$s*cF}99SpV=P1R} zK%zmonTZ)25wFkR9h0t*TV7u{9N)eQw<AAl1)t&3{wj~hT4jRrYiu8w zcPg{b)17o%^of6e%0rld7&#erBD-1vV9=$wwm|LnS|ul}KzdVMbS&~VbaF&2aa`U; zOv7Vjv;N>I7pDPaesoDIEXZF_YFk_-Nx#MoJP(NRn&|C#$1oQK|}>IE+$Oc2fK%Zf7ir=8BJS z5zL1v#pTT_!)@urq;<&`7{r{xYO~*IWf5fh2vDX)v^Crimgr3tj*|bAgh1XUx#TnR zCZ7`Dp_Bh*o-ZIm9Y5ZD#xaoVC6d|?;mLgjZHtD|88YO)D!5<6K<;QlC6`D)@T0;Z zqOiF0ihGlVXoev_2()p-B_r&;Iej)}Gi+W`-sy|L0I|jqpeHBTV|bN!yZ6_qmYWpv z%xNDI&aL0{uZvzCn9aP%zXdI$KMG&Tb^8O(W(L{Bq;S41kTYJlCCz$?4&B&W5w6K2 zb=;cfZ}kZ>TkEYi$yxPryeV~w9I$zp9>VfzGEYzs-J%7opktA-Dc$U>E!mw&h`~@fZub{83vCAP-adsrl=34PnvFAy8Xl> z38(zULuj!e^!@u=MgIP(3QtS;_78y23E0%^EJ_Z&&%3gXc?-v~l#M%;d0qL$Cfx;& zG0yx-W;pPuX515=0Z$=asfVAv7^imDfpvR|L@ctdQ@i=C;%P{z9o6=$sW0KTv0V-| z{t0_xN)^vS!|x*JI(|K{lm;Z#p4?Zn505oYjvCWv^w`v@eF*MM?pkbplJ~r`XxCQ; zut!P%vbDEyl(n~NjyOnYxb2v9qcEeT122wd2s zN#p+NyuY!Zh}zCu-<~L1`j;WUx^U@Xu5jOCGhUa2Kl$^je^nNyZ*=k0U zcY}er(cEfHLi^h09IgdT+6~2Hz2}h&$AlqF(fLl|CP7fvg?g~rptL|czf%NbQjWq{ zW$Yb+AA$en1zA03X7y?8XT6E?;?=1br5ff6XbaH9AxtH)mc}|wHD7E{>-wI_UH!?f+U_GHU+Fof)i|g(2?!mmX|?_1Er=IbEW-I!LfREJJK+n} zp3aNR5tEq1T1lxoYQAf>C0I(i|{iR^MJ7s{W40eO1ZBlY)kF-U=0jv^Jwzm)Vq+r!YcsbFSx`C3%Ps z+v-M-LucTORQaaMR`bj&|AJXwoT%fPROF`{jtKl72mg%USp;qxhG@2W`_?9@(6x8( ziBE}M(qvvenUjW1BGs%x03&Qw@&EJ0Oe{}^VA6-ve zrfQ4goebh^o!p5?eg{;U?RWE4vkpZc;|&3J`E?(enDaO^b}W^uJAjAPl<*5f@_j53 zoszGdmX{H`6uC9|@(6CD>2qu;{kKANbf1Iwjjo7?3!)$zzGx_>mj+*vkC93So+K3D z&Hv1=rUul*`-0X+x&k%qgIbP2GGe{6_)O4OXQwau((VyCSd(|)6W`SgBY_3h)N>3b z)aKIhE}WUNmfzz0lUfND)nxx-EuHP?RR+aUYXpD6`V*OYH9a_8f2yVGN@p$dxBEmV zY!7o^Z-dhrUI)6hiAh973OHBeD2-E|*^`g=kAc#;3k~H-QYiyEx($m^?5bO18M}3q zjqWbVq5P)UbPpFam!(3}@m3(=m*VhO=)9AowLRQUy@6RU+@)0CN337Bgrt8ZU~!ry z1=DR^!)uMHX0ZNrY-`?7g-Ax6>ZuaB9rrP z5?U~}9XrIg#563)lA2c5go?v~F^g|z7eXxc`R1fO1(v-eT|QeM1PQl2=h z#5!D`Pml@Pe43qR@zBfe&RR&3@|uEU;L)95Jj(W7wrqna!sgnR;g;uEN-CS=j^WbF z|JyuEd2dp(e}_K%{0Be(l2-_4khCp+jZ+5JQ)hmhpS$DE?!lkiLA}+3u*hxviP&ZP z-O)6@r0M5-R8%C}*@C_KBkW(KsYwE>v zKEI!J+s}6PHU6ppkOVT>i}>~6`X9=~WpR_trl*tjw-x?81LL`_0)_fI@~QG9$pnwY zKLX*9K#!(o4-Q67=w+k9+4s$w%$I&ib>sKcw6OmoRPJlyKU3TjuA~ObgaqHJ=jw^n zsVn&}Zb|f#2|)G0jCcb4tT)B^oa4$pgL$8}k(HJFNn1EmoDFrQy1XeErr7p2@n{h1 zcSo8KeG;vCOGnxgw(p2CDx#8}3SM=4D`Z@Bc1h@2Gimy-sUd6JFWmflb8YUX9diu-Glk!2D|a zRiLr?QMHWdUyui=wTQmTKL7w%l565uq5(h2&lLa#bY& - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/MediaBrowser.UI/Resources/ModalMessage.xaml b/MediaBrowser.UI/Resources/ModalMessage.xaml deleted file mode 100644 index 9ae288c1d0..0000000000 --- a/MediaBrowser.UI/Resources/ModalMessage.xaml +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/MediaBrowser.UI/Resources/NavBarResources.xaml b/MediaBrowser.UI/Resources/NavBarResources.xaml deleted file mode 100644 index 771c037a7a..0000000000 --- a/MediaBrowser.UI/Resources/NavBarResources.xaml +++ /dev/null @@ -1,149 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/MediaBrowser.UI/Resources/NotificationMessage.xaml b/MediaBrowser.UI/Resources/NotificationMessage.xaml deleted file mode 100644 index 5591e9e0d0..0000000000 --- a/MediaBrowser.UI/Resources/NotificationMessage.xaml +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/MediaBrowser.UI/UserInput/KeyboardListener.cs b/MediaBrowser.UI/UserInput/KeyboardListener.cs deleted file mode 100644 index 76ce8e15ab..0000000000 --- a/MediaBrowser.UI/UserInput/KeyboardListener.cs +++ /dev/null @@ -1,210 +0,0 @@ -using System; -using System.Diagnostics; -using System.Runtime.InteropServices; -using System.Windows.Forms; - -namespace MediaBrowser.UI.UserInput -{ - ///

- /// Provides a basic low-level keyboard listener - /// Inspired by http://blogs.msdn.com/b/toub/archive/2006/05/03/589423.aspx - /// Use the KeyDown event to listen for keys. - /// Make sure to detach from the event when not needed. - /// - public static class KeyboardListener - { - #region KeyDown EventHandler - /// - /// The _ key down - /// - static volatile EventHandler _KeyDown; - /// - /// Fires whenever CurrentItem changes - /// - public static event EventHandler KeyDown - { - add - { - if (_KeyDown == null) - { - StartListening(); - } - - _KeyDown += value; - } - remove - { - _KeyDown -= value; - - if (_KeyDown == null && _hookID != IntPtr.Zero) - { - StopListening(); - } - } - } - - /// - /// Raises the event. - /// - /// The instance containing the event data. - private static void OnKeyDown(KeyEventArgs e) - { - e.SuppressKeyPress = false; - - if (_KeyDown != null) - { - // For now, don't async this - // This will give listeners a chance to modify SuppressKeyPress if they want - try - { - _KeyDown(null, e); - } - catch (Exception ex) - { - } - } - } - #endregion - - /// - /// The W h_ KEYBOAR d_ LL - /// - private const int WH_KEYBOARD_LL = 13; - /// - /// The W m_ KEYDOWN - /// - private const int WM_KEYDOWN = 0x0100; - /// - /// The W m_ SYSKEYDOWN - /// - private const int WM_SYSKEYDOWN = 0x0104; - - /// - /// The _hook ID - /// - private static IntPtr _hookID = IntPtr.Zero; - /// - /// The _proc - /// - private static LowLevelKeyboardProc _proc = HookCallback; - - /// - /// Starts the listening. - /// - private static void StartListening() - { - _hookID = SetHook(_proc); - } - - /// - /// Stops the listening. - /// - private static void StopListening() - { - UnhookWindowsHookEx(_hookID); - _hookID = IntPtr.Zero; - } - - /// - /// Sets the hook. - /// - /// The proc. - /// IntPtr. - private static IntPtr SetHook(LowLevelKeyboardProc proc) - { - using (var curProcess = Process.GetCurrentProcess()) - using (var curModule = curProcess.MainModule) - { - return SetWindowsHookEx(WH_KEYBOARD_LL, proc, - GetModuleHandle(curModule.ModuleName), 0); - } - } - - /// - /// Hooks the callback. - /// - /// The n code. - /// The w param. - /// The l param. - /// IntPtr. - private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) - { - var suppressKeyPress = false; - - if (nCode >= 0) - { - if (wParam == (IntPtr)WM_KEYDOWN || wParam == (IntPtr)WM_SYSKEYDOWN) - { - var vkCode = Marshal.ReadInt32(lParam); - - var keyData = (Keys)vkCode; - - var e = new KeyEventArgs(keyData); - - OnKeyDown(e); - - suppressKeyPress = e.SuppressKeyPress; - } - } - - if (suppressKeyPress) - { - return IntPtr.Zero; - } - - return CallNextHookEx(_hookID, nCode, wParam, lParam); - } - - /// - /// Delegate LowLevelKeyboardProc - /// - /// The n code. - /// The w param. - /// The l param. - /// IntPtr. - private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam); - - #region Imports - /// - /// Sets the windows hook ex. - /// - /// The id hook. - /// The LPFN. - /// The h mod. - /// The dw thread id. - /// IntPtr. - [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] - private static extern IntPtr SetWindowsHookEx(int idHook, - LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId); - - /// - /// Unhooks the windows hook ex. - /// - /// The HHK. - /// true if XXXX, false otherwise - [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] - [return: MarshalAs(UnmanagedType.Bool)] - private static extern bool UnhookWindowsHookEx(IntPtr hhk); - - /// - /// Calls the next hook ex. - /// - /// The HHK. - /// The n code. - /// The w param. - /// The l param. - /// IntPtr. - [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] - private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, - IntPtr wParam, IntPtr lParam); - - /// - /// Gets the module handle. - /// - /// Name of the lp module. - /// IntPtr. - [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] - private static extern IntPtr GetModuleHandle(string lpModuleName); - #endregion - } -} diff --git a/MediaBrowser.UI/ViewModels/BaseItemPersonViewModel.cs b/MediaBrowser.UI/ViewModels/BaseItemPersonViewModel.cs deleted file mode 100644 index 3de9d72cf1..0000000000 --- a/MediaBrowser.UI/ViewModels/BaseItemPersonViewModel.cs +++ /dev/null @@ -1,27 +0,0 @@ -using MediaBrowser.Model.Dto; - -namespace MediaBrowser.UI.ViewModels -{ - public class BaseItemPersonViewModel : BaseViewModel - { - /// - /// The _item - /// - private BaseItemPerson _item; - /// - /// Gets or sets the item. - /// - /// The item. - public BaseItemPerson Item - { - get { return _item; } - - set - { - _item = value; - OnPropertyChanged("Item"); - OnPropertyChanged("Image"); - } - } - } -} diff --git a/MediaBrowser.UI/ViewModels/BaseViewModel.cs b/MediaBrowser.UI/ViewModels/BaseViewModel.cs deleted file mode 100644 index 03ac9d18a0..0000000000 --- a/MediaBrowser.UI/ViewModels/BaseViewModel.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.ComponentModel; - -namespace MediaBrowser.UI.ViewModels -{ - /// - /// Represents a base ViewModel - /// - public abstract class BaseViewModel : INotifyPropertyChanged - { - /// - /// Occurs when [property changed]. - /// - public event PropertyChangedEventHandler PropertyChanged; - - /// - /// Called when [property changed]. - /// - /// The name. - public virtual void OnPropertyChanged(string name) - { - if (PropertyChanged != null) - { - PropertyChanged(this, new PropertyChangedEventArgs(name)); - } - } - } -} diff --git a/MediaBrowser.UI/ViewModels/ChapterInfoDtoViewModel.cs b/MediaBrowser.UI/ViewModels/ChapterInfoDtoViewModel.cs deleted file mode 100644 index 131294ff25..0000000000 --- a/MediaBrowser.UI/ViewModels/ChapterInfoDtoViewModel.cs +++ /dev/null @@ -1,182 +0,0 @@ -using MediaBrowser.Model.Dto; -using MediaBrowser.Model.Entities; -using MediaBrowser.Model.Net; -using System; -using System.Linq; -using System.Windows.Media.Imaging; - -namespace MediaBrowser.UI.ViewModels -{ - /// - /// Class ChapterInfoDtoViewModel - /// - public class ChapterInfoDtoViewModel : BaseViewModel - { - /// - /// Gets or sets the image download options. - /// - /// The image download options. - public ImageOptions ImageDownloadOptions { get; set; } - - /// - /// The _image width - /// - private double _imageWidth; - /// - /// Gets or sets the width of the image. - /// - /// The width of the image. - public double ImageWidth - { - get { return _imageWidth; } - - set - { - _imageWidth = value; - OnPropertyChanged("ImageWidth"); - } - } - - /// - /// The _image height - /// - private double _imageHeight; - /// - /// Gets or sets the height of the image. - /// - /// The height of the image. - public double ImageHeight - { - get { return _imageHeight; } - - set - { - _imageHeight = value; - OnPropertyChanged("ImageHeight"); - } - } - - /// - /// The _item - /// - private ChapterInfoDto _chapter; - /// - /// Gets or sets the item. - /// - /// The item. - public ChapterInfoDto Chapter - { - get { return _chapter; } - - set - { - _chapter = value; - OnPropertyChanged("Chapter"); - OnPropertyChanged("TimeString"); - OnChapterChanged(); - } - } - - /// - /// The _item - /// - private BaseItemDto _item; - /// - /// Gets or sets the item. - /// - /// The item. - public BaseItemDto Item - { - get { return _item; } - - set - { - _item = value; - OnPropertyChanged("Item"); - } - } - - /// - /// Gets the time string. - /// - /// The time string. - public string TimeString - { - get - { - var time = TimeSpan.FromTicks(Chapter.StartPositionTicks); - - return time.ToString(time.TotalHours < 1 ? "m':'ss" : "h':'mm':'ss"); - } - } - - /// - /// The _image - /// - private BitmapImage _image; - /// - /// Gets the image. - /// - /// The image. - public BitmapImage Image - { - get { return _image; } - set - { - _image = value; - OnPropertyChanged("Image"); - } - } - - /// - /// Called when [item changed]. - /// - private async void OnChapterChanged() - { - var options = ImageDownloadOptions ?? new ImageOptions { }; - - options.ImageType = ImageType.ChapterImage; - options.ImageIndex = Item.Chapters.IndexOf(Chapter); - - try - { - Image = await App.Instance.GetRemoteBitmapAsync(App.Instance.ApiClient.GetImageUrl(Item, options)); - } - catch (HttpException) - { - } - } - - /// - /// Gets the height of the chapter image. - /// - /// The item. - /// The height. - /// The default width. - /// System.Double. - public static double GetChapterImageWidth(BaseItemDto item, double height, double defaultWidth) - { - var width = defaultWidth; - - if (item.MediaStreams != null) - { - var videoStream = item.MediaStreams.FirstOrDefault(s => s.Type == MediaStreamType.Video); - - if (videoStream != null) - { - double streamHeight = videoStream.Height ?? 0; - double streamWidth = videoStream.Width ?? 0; - - if (streamHeight > 0 && streamWidth > 0) - { - var aspectRatio = streamWidth / streamHeight; - - width = height * aspectRatio; - } - } - } - - return width; - } - } -} diff --git a/MediaBrowser.UI/ViewModels/DtoBaseItemViewModel.cs b/MediaBrowser.UI/ViewModels/DtoBaseItemViewModel.cs deleted file mode 100644 index f8194e04b8..0000000000 --- a/MediaBrowser.UI/ViewModels/DtoBaseItemViewModel.cs +++ /dev/null @@ -1,183 +0,0 @@ -using MediaBrowser.Model.Dto; -using MediaBrowser.Model.Entities; -using MediaBrowser.UI.Pages; -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; - -namespace MediaBrowser.UI.ViewModels -{ - /// - /// Class DtoBaseItemViewModel - /// - public class DtoBaseItemViewModel : BaseViewModel - { - /// - /// The _average primary image aspect ratio - /// - private double _averagePrimaryImageAspectRatio; - /// - /// Gets the aspect ratio that should be used if displaying the primary image - /// - /// The average primary image aspect ratio. - public double AveragePrimaryImageAspectRatio - { - get { return _averagePrimaryImageAspectRatio; } - - set - { - _averagePrimaryImageAspectRatio = value; - OnPropertyChanged("AveragePrimaryImageAspectRatio"); - } - } - - /// - /// The _parent display preferences - /// - private DisplayPreferences _parentDisplayPreferences; - /// - /// Gets of sets the current DisplayPreferences - /// - /// The parent display preferences. - public DisplayPreferences ParentDisplayPreferences - { - get { return _parentDisplayPreferences; } - - set - { - _parentDisplayPreferences = value; - NotifyDisplayPreferencesChanged(); - } - } - - /// - /// The _item - /// - private BaseItemDto _item; - /// - /// Gets or sets the item. - /// - /// The item. - public BaseItemDto Item - { - get { return _item; } - - set - { - _item = value; - OnPropertyChanged("Item"); - } - } - - /// - /// Notifies the display preferences changed. - /// - public void NotifyDisplayPreferencesChanged() - { - OnPropertyChanged("DisplayPreferences"); - } - - /// - /// Gets an image url that can be used to download an image from the api - /// - /// The type of image requested - /// The image index, if there are multiple. Currently only applies to backdrops. Supply null or 0 for first backdrop. - /// System.String. - public string GetImageUrl(ImageType imageType, int? imageIndex = null) - { - var height = ParentDisplayPreferences.PrimaryImageHeight; - - var averageAspectRatio = BaseFolderPage.GetAspectRatio(imageType, AveragePrimaryImageAspectRatio); - - var width = height * averageAspectRatio; - - var imageOptions = new ImageOptions - { - ImageType = imageType, - ImageIndex = imageIndex, - Height = height - }; - - if (imageType == ImageType.Primary) - { - var currentAspectRatio = imageType == ImageType.Primary ? Item.PrimaryImageAspectRatio ?? width / height : width / height; - - // Preserve the exact AR if it deviates from the average significantly - var preserveExactAspectRatio = Math.Abs(currentAspectRatio - averageAspectRatio) > .10; - - if (!preserveExactAspectRatio) - { - imageOptions.Width = Convert.ToInt32(width); - } - } - - return App.Instance.ApiClient.GetImageUrl(Item, imageOptions); - } - - /// - /// Gets the average primary image aspect ratio. - /// - /// The items. - /// System.Double. - /// items - public static double GetAveragePrimaryImageAspectRatio(IEnumerable items) - { - if (items == null) - { - throw new ArgumentNullException("items"); - } - - double total = 0; - var count = 0; - - foreach (var child in items) - { - var ratio = child.PrimaryImageAspectRatio ?? 0; - - if (ratio.Equals(0)) - { - continue; - } - - total += ratio; - count++; - } - - return count == 0 ? 1 : total / count; - } - - /// - /// Gets the observable items. - /// - /// The items. - /// ObservableCollection{DtoBaseItemViewModel}. - public static ObservableCollection GetObservableItems(BaseItemDto[] items) - { - return GetObservableItems(items, GetAveragePrimaryImageAspectRatio(items)); - } - - /// - /// Gets the observable items. - /// - /// The items. - /// The average primary image aspect ratio. - /// The parent display preferences. - /// ObservableCollection{DtoBaseItemViewModel}. - /// items - public static ObservableCollection GetObservableItems(IEnumerable items, double averagePrimaryImageAspectRatio, DisplayPreferences parentDisplayPreferences = null) - { - if (items == null) - { - throw new ArgumentNullException("items"); - } - - return new ObservableCollection(items.Select(i => new DtoBaseItemViewModel - { - Item = i, - ParentDisplayPreferences = parentDisplayPreferences, - AveragePrimaryImageAspectRatio = averagePrimaryImageAspectRatio - })); - } - } -} diff --git a/MediaBrowser.UI/ViewModels/ItemCollectionViewModel.cs b/MediaBrowser.UI/ViewModels/ItemCollectionViewModel.cs deleted file mode 100644 index 3e7f6b8413..0000000000 --- a/MediaBrowser.UI/ViewModels/ItemCollectionViewModel.cs +++ /dev/null @@ -1,158 +0,0 @@ -using MediaBrowser.Model.Dto; -using System; -using System.Threading; -using System.Windows; - -namespace MediaBrowser.UI.ViewModels -{ - /// - /// Represents a view model that contains multiple items. - /// This should be used if you want to display a button or list item that holds more than one item, - /// and cycle through them periodically. - /// - public class ItemCollectionViewModel : BaseViewModel, IDisposable - { - private int RotationPeriodMs { get; set; } - - public ItemCollectionViewModel(int rotationPeriodMs = 10000, int rotationDevaiationMs = 2000) - : base() - { - if (rotationDevaiationMs > 0) - { - rotationPeriodMs += new Random(Guid.NewGuid().GetHashCode()).Next(0 - rotationDevaiationMs, rotationDevaiationMs); - } - - RotationPeriodMs = rotationPeriodMs; - } - - /// - /// Gets the timer that updates the current item - /// - private Timer CurrentItemTimer { get; set; } - - private string _name; - /// - /// Gets or sets the name of the collection - /// - public string Name - { - get { return _name; } - set - { - _name = value; - OnPropertyChanged("Name"); - } - } - - private BaseItemDto[] _items; - /// - /// Gets or sets the list of items - /// - public BaseItemDto[] Items - { - get { return _items; } - set - { - _items = value ?? new BaseItemDto[] { }; - OnPropertyChanged("Items"); - CurrentItemIndex = Items.Length == 0 ? -1 : 0; - - ReloadTimer(); - } - } - - private int _currentItemIndex; - /// - /// Gets or sets the index of the current item - /// - public int CurrentItemIndex - { - get { return _currentItemIndex; } - set - { - _currentItemIndex = value; - OnPropertyChanged("CurrentItemIndex"); - OnPropertyChanged("CurrentItem"); - OnPropertyChanged("NextItem"); - } - } - - /// - /// Gets the current item - /// - public BaseItemDto CurrentItem - { - get { return CurrentItemIndex == -1 ? null : Items[CurrentItemIndex]; } - } - - /// - /// Gets the next item - /// - public BaseItemDto NextItem - { - get - { - if (CurrentItem == null || CurrentItemIndex == -1) - { - return null; - } - var index = CurrentItemIndex + 1; - - if (index >= Items.Length) - { - index = 0; - } - - return Items[index]; - } - } - - /// - /// Disposes the timer - /// - private void DisposeTimer() - { - if (CurrentItemTimer != null) - { - CurrentItemTimer.Dispose(); - } - } - - /// - /// Reloads the timer - /// - private void ReloadTimer() - { - DisposeTimer(); - - // Don't bother unless there's at least two items - if (Items.Length > 1) - { - CurrentItemTimer = new Timer(state => Application.Current.Dispatcher.InvokeAsync(IncrementCurrentItemIndex), null, RotationPeriodMs, RotationPeriodMs); - } - } - - /// - /// Increments current item index, or resets it back to zero if we're at the end of the list - /// - private void IncrementCurrentItemIndex() - { - var newIndex = CurrentItemIndex + 1; - - if (newIndex >= Items.Length) - { - newIndex = 0; - } - - CurrentItemIndex = newIndex; - } - - /// - /// Disposes the collection - /// - public void Dispose() - { - DisposeTimer(); - } - } -} diff --git a/MediaBrowser.UI/ViewModels/SpecialFeatureViewModel.cs b/MediaBrowser.UI/ViewModels/SpecialFeatureViewModel.cs deleted file mode 100644 index f6d51d6dbf..0000000000 --- a/MediaBrowser.UI/ViewModels/SpecialFeatureViewModel.cs +++ /dev/null @@ -1,135 +0,0 @@ -using MediaBrowser.Model.Dto; -using MediaBrowser.Model.Entities; -using MediaBrowser.Model.Net; -using System; -using System.Windows.Media.Imaging; - -namespace MediaBrowser.UI.ViewModels -{ - /// - /// Class SpecialFeatureViewModel - /// - public class SpecialFeatureViewModel : BaseViewModel - { - /// - /// Gets or sets the image download options. - /// - /// The image download options. - public ImageOptions ImageDownloadOptions { get; set; } - - /// - /// The _image width - /// - private double _imageWidth; - /// - /// Gets or sets the width of the image. - /// - /// The width of the image. - public double ImageWidth - { - get { return _imageWidth; } - - set - { - _imageWidth = value; - OnPropertyChanged("ImageWidth"); - } - } - - /// - /// The _image height - /// - private double _imageHeight; - /// - /// Gets or sets the height of the image. - /// - /// The height of the image. - public double ImageHeight - { - get { return _imageHeight; } - - set - { - _imageHeight = value; - OnPropertyChanged("ImageHeight"); - } - } - - /// - /// The _item - /// - private BaseItemDto _item; - /// - /// Gets or sets the item. - /// - /// The item. - public BaseItemDto Item - { - get { return _item; } - - set - { - _item = value; - OnPropertyChanged("Item"); - OnItemChanged(); - } - } - - /// - /// Gets the time string. - /// - /// The time string. - public string MinutesString - { - get - { - var time = TimeSpan.FromTicks(Item.RunTimeTicks ?? 0); - - var minutes = Math.Round(time.TotalMinutes); - - if (minutes <= 1) - { - return "1 minute"; - } - - return string.Format("{0} minutes", minutes); - } - } - - /// - /// The _image - /// - private BitmapImage _image; - /// - /// Gets the image. - /// - /// The image. - public BitmapImage Image - { - get { return _image; } - set - { - _image = value; - OnPropertyChanged("Image"); - } - } - - /// - /// Called when [item changed]. - /// - private async void OnItemChanged() - { - var options = ImageDownloadOptions ?? new ImageOptions { }; - - options.ImageType = ImageType.Primary; - - try - { - Image = await App.Instance.GetRemoteBitmapAsync(App.Instance.ApiClient.GetImageUrl(Item, options)); - } - catch (HttpException) - { - } - } - } -} diff --git a/MediaBrowser.UI/packages.config b/MediaBrowser.UI/packages.config deleted file mode 100644 index 3de1bc355b..0000000000 --- a/MediaBrowser.UI/packages.config +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/MediaBrowser.UI/plugins/codec/libavcodec_plugin.dll.REMOVED.git-id b/MediaBrowser.UI/plugins/codec/libavcodec_plugin.dll.REMOVED.git-id deleted file mode 100644 index 8aaa732062..0000000000 --- a/MediaBrowser.UI/plugins/codec/libavcodec_plugin.dll.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b4c5b79372014383488c16e359974e2fbbae5a89 \ No newline at end of file diff --git a/MediaBrowser.UI/plugins/gui/libqt4_plugin.dll.REMOVED.git-id b/MediaBrowser.UI/plugins/gui/libqt4_plugin.dll.REMOVED.git-id deleted file mode 100644 index c1c323a92d..0000000000 --- a/MediaBrowser.UI/plugins/gui/libqt4_plugin.dll.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a70729e8d25a1f2260a18d4cb0e202895d6df263 \ No newline at end of file