diff --git a/Wino.Core.Domain/Interfaces/INativeAppService.cs b/Wino.Core.Domain/Interfaces/INativeAppService.cs index 4abd1dc6..f5c507fc 100644 --- a/Wino.Core.Domain/Interfaces/INativeAppService.cs +++ b/Wino.Core.Domain/Interfaces/INativeAppService.cs @@ -15,7 +15,7 @@ public interface INativeAppService string GetFullAppVersion(); - Task PinAppToTaskbarAsync(); + //Task PinAppToTaskbarAsync(); /// /// Some cryptographic shit is needed for requesting Google authentication in UWP. diff --git a/Wino.Core/Authenticators/OutlookAuthenticator.cs b/Wino.Core/Authenticators/OutlookAuthenticator.cs index 878d1c91..0f8aa6d6 100644 --- a/Wino.Core/Authenticators/OutlookAuthenticator.cs +++ b/Wino.Core/Authenticators/OutlookAuthenticator.cs @@ -17,7 +17,7 @@ public class OutlookAuthenticator : BaseAuthenticator, IAuthenticator // Outlook private const string Authority = "https://login.microsoftonline.com/common"; - public string ClientId { get; } = "b19c2035-d740-49ff-b297-de6ec561b208"; + public string ClientId { get; } = "d26be8d1-9975-4654-aa42-35b398759196"; private readonly string[] MailScope = new string[] { "email", "mail.readwrite", "offline_access", "mail.send" }; @@ -27,11 +27,11 @@ public class OutlookAuthenticator : BaseAuthenticator, IAuthenticator public OutlookAuthenticator(ITokenService tokenService, INativeAppService nativeAppService) : base(tokenService) { - var authenticationRedirectUri = nativeAppService.GetWebAuthenticationBrokerUri(); + // var authenticationRedirectUri = nativeAppService.GetWebAuthenticationBrokerUri(); _publicClientApplication = PublicClientApplicationBuilder.Create(ClientId) .WithAuthority(Authority) - .WithRedirectUri(authenticationRedirectUri) + .WithRedirectUri("https://login.microsoftonline.com/common/oauth2/nativeclient") .Build(); } diff --git a/Wino.Core/Services/FolderService.cs b/Wino.Core/Services/FolderService.cs index c5afbcb4..30a1f060 100644 --- a/Wino.Core/Services/FolderService.cs +++ b/Wino.Core/Services/FolderService.cs @@ -127,11 +127,13 @@ public async Task GetFolderStructureForAccountAsync(Guid acco if (nonStickyFolders.Any()) { - var virtualMoreFolder = new MailItemFolder() - { - FolderName = Translator.More, - SpecialFolderType = SpecialFolderType.More - }; + //var virtualMoreFolder = new MailItemFolder() + //{ + // FolderName = Translator.More, + // SpecialFolderType = SpecialFolderType.More + //}; + + var moreFolders = new List(); foreach (var unstickyItem in nonStickyFolders) { @@ -156,12 +158,14 @@ public async Task GetFolderStructureForAccountAsync(Guid acco var structure = await GetChildFolderItemsRecursiveAsync(unstickyItem.Id, accountId); - virtualMoreFolder.ChildFolders.Add(structure); + moreFolders.Add(structure); } // Only add more if there are any. - if (virtualMoreFolder.ChildFolders.Count > 0) - accountTree.Folders.Add(virtualMoreFolder); + if (moreFolders.Count > 0) + { + accountTree.Folders.AddRange(moreFolders); + } } } diff --git a/Wino.Mail.ViewModels/AppShellViewModel.cs b/Wino.Mail.ViewModels/AppShellViewModel.cs index 90a7d9b8..76786ab6 100644 --- a/Wino.Mail.ViewModels/AppShellViewModel.cs +++ b/Wino.Mail.ViewModels/AppShellViewModel.cs @@ -873,7 +873,7 @@ protected override async void OnAccountCreated(MailAccount createdAccount) Messenger.Send(new NewSynchronizationRequested(options)); - await _nativeAppService.PinAppToTaskbarAsync(); + //await _nativeAppService.PinAppToTaskbarAsync(); } /// diff --git a/Wino.Mail/AppShell.xaml b/Wino.Mail/AppShell.xaml index 1cc75798..97fbe15c 100644 --- a/Wino.Mail/AppShell.xaml +++ b/Wino.Mail/AppShell.xaml @@ -255,7 +255,8 @@ + RowSpacing="0" + > @@ -528,7 +531,16 @@ PaneOpening="NavigationPaneOpening" ScrollViewer.VerticalScrollBarVisibility="Hidden" SelectedItem="{x:Bind ViewModel.SelectedMenuItem, Mode=TwoWay}" - SelectionChanged="MenuSelectionChanged"> + SelectionChanged="MenuSelectionChanged" + Background="#08FFFFFF" + > + + + + + @@ -542,7 +554,7 @@ - + @@ -608,5 +620,6 @@ OpenPaneLength="{x:Bind ViewModel.StatePersistenceService.OpenPaneLength, Mode=OneWay}" ReadingPaneLength="{x:Bind ViewModel.StatePersistenceService.MailListPaneLength, Mode=OneWay}" SystemReserved="180" /> + diff --git a/Wino.Mail/Assets/BadgeLogo.scale-100.png b/Wino.Mail/Assets/BadgeLogo.scale-100.png index ae8a28a3..6357bb2a 100644 Binary files a/Wino.Mail/Assets/BadgeLogo.scale-100.png and b/Wino.Mail/Assets/BadgeLogo.scale-100.png differ diff --git a/Wino.Mail/Assets/BadgeLogo.scale-125.png b/Wino.Mail/Assets/BadgeLogo.scale-125.png index 53fafc0d..16e2b770 100644 Binary files a/Wino.Mail/Assets/BadgeLogo.scale-125.png and b/Wino.Mail/Assets/BadgeLogo.scale-125.png differ diff --git a/Wino.Mail/Assets/BadgeLogo.scale-150.png b/Wino.Mail/Assets/BadgeLogo.scale-150.png index bfcd6b8d..f617835a 100644 Binary files a/Wino.Mail/Assets/BadgeLogo.scale-150.png and b/Wino.Mail/Assets/BadgeLogo.scale-150.png differ diff --git a/Wino.Mail/Assets/BadgeLogo.scale-200.png b/Wino.Mail/Assets/BadgeLogo.scale-200.png index 8e7b9e08..d9d08091 100644 Binary files a/Wino.Mail/Assets/BadgeLogo.scale-200.png and b/Wino.Mail/Assets/BadgeLogo.scale-200.png differ diff --git a/Wino.Mail/Assets/BadgeLogo.scale-400.png b/Wino.Mail/Assets/BadgeLogo.scale-400.png index 55f300a9..22441256 100644 Binary files a/Wino.Mail/Assets/BadgeLogo.scale-400.png and b/Wino.Mail/Assets/BadgeLogo.scale-400.png differ diff --git a/Wino.Mail/Assets/LargeTile.scale-100.png b/Wino.Mail/Assets/LargeTile.scale-100.png index bf83e51b..36dd9f9f 100644 Binary files a/Wino.Mail/Assets/LargeTile.scale-100.png and b/Wino.Mail/Assets/LargeTile.scale-100.png differ diff --git a/Wino.Mail/Assets/LargeTile.scale-125.png b/Wino.Mail/Assets/LargeTile.scale-125.png index 06dbbaeb..ad139dc2 100644 Binary files a/Wino.Mail/Assets/LargeTile.scale-125.png and b/Wino.Mail/Assets/LargeTile.scale-125.png differ diff --git a/Wino.Mail/Assets/LargeTile.scale-150.png b/Wino.Mail/Assets/LargeTile.scale-150.png index a5a24dd8..4c908425 100644 Binary files a/Wino.Mail/Assets/LargeTile.scale-150.png and b/Wino.Mail/Assets/LargeTile.scale-150.png differ diff --git a/Wino.Mail/Assets/LargeTile.scale-200.png b/Wino.Mail/Assets/LargeTile.scale-200.png index 213bc118..5dc087b5 100644 Binary files a/Wino.Mail/Assets/LargeTile.scale-200.png and b/Wino.Mail/Assets/LargeTile.scale-200.png differ diff --git a/Wino.Mail/Assets/LargeTile.scale-400.png b/Wino.Mail/Assets/LargeTile.scale-400.png index 5bbe0abb..1b46e2c8 100644 Binary files a/Wino.Mail/Assets/LargeTile.scale-400.png and b/Wino.Mail/Assets/LargeTile.scale-400.png differ diff --git a/Wino.Mail/Assets/Rectangle17.png b/Wino.Mail/Assets/Rectangle17.png new file mode 100644 index 00000000..6a2cbd0c Binary files /dev/null and b/Wino.Mail/Assets/Rectangle17.png differ diff --git a/Wino.Mail/Assets/SmallTile.scale-100.png b/Wino.Mail/Assets/SmallTile.scale-100.png index cc4fce7c..216ba6dc 100644 Binary files a/Wino.Mail/Assets/SmallTile.scale-100.png and b/Wino.Mail/Assets/SmallTile.scale-100.png differ diff --git a/Wino.Mail/Assets/SmallTile.scale-125.png b/Wino.Mail/Assets/SmallTile.scale-125.png index 29829897..ba489e36 100644 Binary files a/Wino.Mail/Assets/SmallTile.scale-125.png and b/Wino.Mail/Assets/SmallTile.scale-125.png differ diff --git a/Wino.Mail/Assets/SmallTile.scale-150.png b/Wino.Mail/Assets/SmallTile.scale-150.png index f3769431..b4b57f2e 100644 Binary files a/Wino.Mail/Assets/SmallTile.scale-150.png and b/Wino.Mail/Assets/SmallTile.scale-150.png differ diff --git a/Wino.Mail/Assets/SmallTile.scale-200.png b/Wino.Mail/Assets/SmallTile.scale-200.png index 852517b5..1ca14a48 100644 Binary files a/Wino.Mail/Assets/SmallTile.scale-200.png and b/Wino.Mail/Assets/SmallTile.scale-200.png differ diff --git a/Wino.Mail/Assets/SmallTile.scale-400.png b/Wino.Mail/Assets/SmallTile.scale-400.png index f3047502..8905c080 100644 Binary files a/Wino.Mail/Assets/SmallTile.scale-400.png and b/Wino.Mail/Assets/SmallTile.scale-400.png differ diff --git a/Wino.Mail/Assets/SplashScreen.scale-100.png b/Wino.Mail/Assets/SplashScreen.scale-100.png index 0283361d..28a30b7c 100644 Binary files a/Wino.Mail/Assets/SplashScreen.scale-100.png and b/Wino.Mail/Assets/SplashScreen.scale-100.png differ diff --git a/Wino.Mail/Assets/SplashScreen.scale-125.png b/Wino.Mail/Assets/SplashScreen.scale-125.png index d84f59a5..1aaff72c 100644 Binary files a/Wino.Mail/Assets/SplashScreen.scale-125.png and b/Wino.Mail/Assets/SplashScreen.scale-125.png differ diff --git a/Wino.Mail/Assets/SplashScreen.scale-150.png b/Wino.Mail/Assets/SplashScreen.scale-150.png index f9449b85..2a9bb315 100644 Binary files a/Wino.Mail/Assets/SplashScreen.scale-150.png and b/Wino.Mail/Assets/SplashScreen.scale-150.png differ diff --git a/Wino.Mail/Assets/SplashScreen.scale-200.png b/Wino.Mail/Assets/SplashScreen.scale-200.png index 9782abaa..62aac5e8 100644 Binary files a/Wino.Mail/Assets/SplashScreen.scale-200.png and b/Wino.Mail/Assets/SplashScreen.scale-200.png differ diff --git a/Wino.Mail/Assets/SplashScreen.scale-400.png b/Wino.Mail/Assets/SplashScreen.scale-400.png index 58e5483e..711d753b 100644 Binary files a/Wino.Mail/Assets/SplashScreen.scale-400.png and b/Wino.Mail/Assets/SplashScreen.scale-400.png differ diff --git a/Wino.Mail/Assets/Square150x150Logo.scale-100.png b/Wino.Mail/Assets/Square150x150Logo.scale-100.png index d45248a3..8f27c3b3 100644 Binary files a/Wino.Mail/Assets/Square150x150Logo.scale-100.png and b/Wino.Mail/Assets/Square150x150Logo.scale-100.png differ diff --git a/Wino.Mail/Assets/Square150x150Logo.scale-125.png b/Wino.Mail/Assets/Square150x150Logo.scale-125.png index 74dc2515..7c6aae4a 100644 Binary files a/Wino.Mail/Assets/Square150x150Logo.scale-125.png and b/Wino.Mail/Assets/Square150x150Logo.scale-125.png differ diff --git a/Wino.Mail/Assets/Square150x150Logo.scale-150.png b/Wino.Mail/Assets/Square150x150Logo.scale-150.png index 5a07de0c..9a2884ed 100644 Binary files a/Wino.Mail/Assets/Square150x150Logo.scale-150.png and b/Wino.Mail/Assets/Square150x150Logo.scale-150.png differ diff --git a/Wino.Mail/Assets/Square150x150Logo.scale-200.png b/Wino.Mail/Assets/Square150x150Logo.scale-200.png index a7c7a181..02ef4baf 100644 Binary files a/Wino.Mail/Assets/Square150x150Logo.scale-200.png and b/Wino.Mail/Assets/Square150x150Logo.scale-200.png differ diff --git a/Wino.Mail/Assets/Square150x150Logo.scale-400.png b/Wino.Mail/Assets/Square150x150Logo.scale-400.png index 14530295..b8d7ffee 100644 Binary files a/Wino.Mail/Assets/Square150x150Logo.scale-400.png and b/Wino.Mail/Assets/Square150x150Logo.scale-400.png differ diff --git a/Wino.Mail/Assets/Square44x44Logo.altform-lightunplated_targetsize-16.png b/Wino.Mail/Assets/Square44x44Logo.altform-lightunplated_targetsize-16.png index cad729ce..49d106ee 100644 Binary files a/Wino.Mail/Assets/Square44x44Logo.altform-lightunplated_targetsize-16.png and b/Wino.Mail/Assets/Square44x44Logo.altform-lightunplated_targetsize-16.png differ diff --git a/Wino.Mail/Assets/Square44x44Logo.altform-lightunplated_targetsize-24.png b/Wino.Mail/Assets/Square44x44Logo.altform-lightunplated_targetsize-24.png index 0d699618..35b692e3 100644 Binary files a/Wino.Mail/Assets/Square44x44Logo.altform-lightunplated_targetsize-24.png and b/Wino.Mail/Assets/Square44x44Logo.altform-lightunplated_targetsize-24.png differ diff --git a/Wino.Mail/Assets/Square44x44Logo.altform-lightunplated_targetsize-256.png b/Wino.Mail/Assets/Square44x44Logo.altform-lightunplated_targetsize-256.png index 02b23248..b470ad1c 100644 Binary files a/Wino.Mail/Assets/Square44x44Logo.altform-lightunplated_targetsize-256.png and b/Wino.Mail/Assets/Square44x44Logo.altform-lightunplated_targetsize-256.png differ diff --git a/Wino.Mail/Assets/Square44x44Logo.altform-lightunplated_targetsize-32.png b/Wino.Mail/Assets/Square44x44Logo.altform-lightunplated_targetsize-32.png index 90a2077c..6185a510 100644 Binary files a/Wino.Mail/Assets/Square44x44Logo.altform-lightunplated_targetsize-32.png and b/Wino.Mail/Assets/Square44x44Logo.altform-lightunplated_targetsize-32.png differ diff --git a/Wino.Mail/Assets/Square44x44Logo.altform-lightunplated_targetsize-48.png b/Wino.Mail/Assets/Square44x44Logo.altform-lightunplated_targetsize-48.png index 0ed92a7e..312023ab 100644 Binary files a/Wino.Mail/Assets/Square44x44Logo.altform-lightunplated_targetsize-48.png and b/Wino.Mail/Assets/Square44x44Logo.altform-lightunplated_targetsize-48.png differ diff --git a/Wino.Mail/Assets/Square44x44Logo.altform-unplated_targetsize-16.png b/Wino.Mail/Assets/Square44x44Logo.altform-unplated_targetsize-16.png index cad729ce..49d106ee 100644 Binary files a/Wino.Mail/Assets/Square44x44Logo.altform-unplated_targetsize-16.png and b/Wino.Mail/Assets/Square44x44Logo.altform-unplated_targetsize-16.png differ diff --git a/Wino.Mail/Assets/Square44x44Logo.altform-unplated_targetsize-256.png b/Wino.Mail/Assets/Square44x44Logo.altform-unplated_targetsize-256.png index 02b23248..b470ad1c 100644 Binary files a/Wino.Mail/Assets/Square44x44Logo.altform-unplated_targetsize-256.png and b/Wino.Mail/Assets/Square44x44Logo.altform-unplated_targetsize-256.png differ diff --git a/Wino.Mail/Assets/Square44x44Logo.altform-unplated_targetsize-32.png b/Wino.Mail/Assets/Square44x44Logo.altform-unplated_targetsize-32.png index 90a2077c..6185a510 100644 Binary files a/Wino.Mail/Assets/Square44x44Logo.altform-unplated_targetsize-32.png and b/Wino.Mail/Assets/Square44x44Logo.altform-unplated_targetsize-32.png differ diff --git a/Wino.Mail/Assets/Square44x44Logo.altform-unplated_targetsize-48.png b/Wino.Mail/Assets/Square44x44Logo.altform-unplated_targetsize-48.png index 0ed92a7e..312023ab 100644 Binary files a/Wino.Mail/Assets/Square44x44Logo.altform-unplated_targetsize-48.png and b/Wino.Mail/Assets/Square44x44Logo.altform-unplated_targetsize-48.png differ diff --git a/Wino.Mail/Assets/Square44x44Logo.scale-100.png b/Wino.Mail/Assets/Square44x44Logo.scale-100.png index d58fd9fc..51729df8 100644 Binary files a/Wino.Mail/Assets/Square44x44Logo.scale-100.png and b/Wino.Mail/Assets/Square44x44Logo.scale-100.png differ diff --git a/Wino.Mail/Assets/Square44x44Logo.scale-125.png b/Wino.Mail/Assets/Square44x44Logo.scale-125.png index a6bff2df..d4f5819d 100644 Binary files a/Wino.Mail/Assets/Square44x44Logo.scale-125.png and b/Wino.Mail/Assets/Square44x44Logo.scale-125.png differ diff --git a/Wino.Mail/Assets/Square44x44Logo.scale-150.png b/Wino.Mail/Assets/Square44x44Logo.scale-150.png index 0151282b..777169fb 100644 Binary files a/Wino.Mail/Assets/Square44x44Logo.scale-150.png and b/Wino.Mail/Assets/Square44x44Logo.scale-150.png differ diff --git a/Wino.Mail/Assets/Square44x44Logo.scale-200.png b/Wino.Mail/Assets/Square44x44Logo.scale-200.png index 2368352c..c2bf54b9 100644 Binary files a/Wino.Mail/Assets/Square44x44Logo.scale-200.png and b/Wino.Mail/Assets/Square44x44Logo.scale-200.png differ diff --git a/Wino.Mail/Assets/Square44x44Logo.scale-400.png b/Wino.Mail/Assets/Square44x44Logo.scale-400.png index 59055316..b30a294c 100644 Binary files a/Wino.Mail/Assets/Square44x44Logo.scale-400.png and b/Wino.Mail/Assets/Square44x44Logo.scale-400.png differ diff --git a/Wino.Mail/Assets/Square44x44Logo.targetsize-16.png b/Wino.Mail/Assets/Square44x44Logo.targetsize-16.png index de43ce90..e0f1b800 100644 Binary files a/Wino.Mail/Assets/Square44x44Logo.targetsize-16.png and b/Wino.Mail/Assets/Square44x44Logo.targetsize-16.png differ diff --git a/Wino.Mail/Assets/Square44x44Logo.targetsize-24.png b/Wino.Mail/Assets/Square44x44Logo.targetsize-24.png index 976f5e52..0b4be0a9 100644 Binary files a/Wino.Mail/Assets/Square44x44Logo.targetsize-24.png and b/Wino.Mail/Assets/Square44x44Logo.targetsize-24.png differ diff --git a/Wino.Mail/Assets/Square44x44Logo.targetsize-24_altform-unplated.png b/Wino.Mail/Assets/Square44x44Logo.targetsize-24_altform-unplated.png index 0d699618..35b692e3 100644 Binary files a/Wino.Mail/Assets/Square44x44Logo.targetsize-24_altform-unplated.png and b/Wino.Mail/Assets/Square44x44Logo.targetsize-24_altform-unplated.png differ diff --git a/Wino.Mail/Assets/Square44x44Logo.targetsize-256.png b/Wino.Mail/Assets/Square44x44Logo.targetsize-256.png index c6f762e0..41e5e43d 100644 Binary files a/Wino.Mail/Assets/Square44x44Logo.targetsize-256.png and b/Wino.Mail/Assets/Square44x44Logo.targetsize-256.png differ diff --git a/Wino.Mail/Assets/Square44x44Logo.targetsize-32.png b/Wino.Mail/Assets/Square44x44Logo.targetsize-32.png index 30341066..22f01015 100644 Binary files a/Wino.Mail/Assets/Square44x44Logo.targetsize-32.png and b/Wino.Mail/Assets/Square44x44Logo.targetsize-32.png differ diff --git a/Wino.Mail/Assets/Square44x44Logo.targetsize-48.png b/Wino.Mail/Assets/Square44x44Logo.targetsize-48.png index cb1aaf03..18934f74 100644 Binary files a/Wino.Mail/Assets/Square44x44Logo.targetsize-48.png and b/Wino.Mail/Assets/Square44x44Logo.targetsize-48.png differ diff --git a/Wino.Mail/Assets/StoreLogo.scale-100.png b/Wino.Mail/Assets/StoreLogo.scale-100.png index 303a7ff2..234d0104 100644 Binary files a/Wino.Mail/Assets/StoreLogo.scale-100.png and b/Wino.Mail/Assets/StoreLogo.scale-100.png differ diff --git a/Wino.Mail/Assets/StoreLogo.scale-125.png b/Wino.Mail/Assets/StoreLogo.scale-125.png index 849b69a2..8440e77e 100644 Binary files a/Wino.Mail/Assets/StoreLogo.scale-125.png and b/Wino.Mail/Assets/StoreLogo.scale-125.png differ diff --git a/Wino.Mail/Assets/StoreLogo.scale-150.png b/Wino.Mail/Assets/StoreLogo.scale-150.png index 90d52577..dd014596 100644 Binary files a/Wino.Mail/Assets/StoreLogo.scale-150.png and b/Wino.Mail/Assets/StoreLogo.scale-150.png differ diff --git a/Wino.Mail/Assets/StoreLogo.scale-200.png b/Wino.Mail/Assets/StoreLogo.scale-200.png index 393052ea..824d1010 100644 Binary files a/Wino.Mail/Assets/StoreLogo.scale-200.png and b/Wino.Mail/Assets/StoreLogo.scale-200.png differ diff --git a/Wino.Mail/Assets/StoreLogo.scale-400.png b/Wino.Mail/Assets/StoreLogo.scale-400.png index d3f01397..394f5573 100644 Binary files a/Wino.Mail/Assets/StoreLogo.scale-400.png and b/Wino.Mail/Assets/StoreLogo.scale-400.png differ diff --git a/Wino.Mail/Assets/Wide310x150Logo.scale-100.png b/Wino.Mail/Assets/Wide310x150Logo.scale-100.png index 7cf08614..b840c3c2 100644 Binary files a/Wino.Mail/Assets/Wide310x150Logo.scale-100.png and b/Wino.Mail/Assets/Wide310x150Logo.scale-100.png differ diff --git a/Wino.Mail/Assets/Wide310x150Logo.scale-125.png b/Wino.Mail/Assets/Wide310x150Logo.scale-125.png index 23246be6..50a5947d 100644 Binary files a/Wino.Mail/Assets/Wide310x150Logo.scale-125.png and b/Wino.Mail/Assets/Wide310x150Logo.scale-125.png differ diff --git a/Wino.Mail/Assets/Wide310x150Logo.scale-150.png b/Wino.Mail/Assets/Wide310x150Logo.scale-150.png index 33238ff7..062e2e56 100644 Binary files a/Wino.Mail/Assets/Wide310x150Logo.scale-150.png and b/Wino.Mail/Assets/Wide310x150Logo.scale-150.png differ diff --git a/Wino.Mail/Assets/Wide310x150Logo.scale-200.png b/Wino.Mail/Assets/Wide310x150Logo.scale-200.png index 0283361d..28a30b7c 100644 Binary files a/Wino.Mail/Assets/Wide310x150Logo.scale-200.png and b/Wino.Mail/Assets/Wide310x150Logo.scale-200.png differ diff --git a/Wino.Mail/Assets/Wide310x150Logo.scale-400.png b/Wino.Mail/Assets/Wide310x150Logo.scale-400.png index 9782abaa..62aac5e8 100644 Binary files a/Wino.Mail/Assets/Wide310x150Logo.scale-400.png and b/Wino.Mail/Assets/Wide310x150Logo.scale-400.png differ diff --git a/Wino.Mail/Controls/Advanced/WinoAppTitleBar.xaml b/Wino.Mail/Controls/Advanced/WinoAppTitleBar.xaml index 3f58942f..80e2b042 100644 --- a/Wino.Mail/Controls/Advanced/WinoAppTitleBar.xaml +++ b/Wino.Mail/Controls/Advanced/WinoAppTitleBar.xaml @@ -96,8 +96,10 @@ + HorizontalAlignment="Stretch" + Content="{x:Bind ShellFrameContent, Mode=OneWay}" RenderTransformOrigin="0.5,0.5"> diff --git a/Wino.Mail/Controls/Advanced/WinoAppTitleBar.xaml.cs b/Wino.Mail/Controls/Advanced/WinoAppTitleBar.xaml.cs index 66415a64..b742d5c4 100644 --- a/Wino.Mail/Controls/Advanced/WinoAppTitleBar.xaml.cs +++ b/Wino.Mail/Controls/Advanced/WinoAppTitleBar.xaml.cs @@ -101,9 +101,9 @@ private void DrawTitleBar() UpdateLayout(); CoreWindowTitleTextBlock.Visibility = Visibility.Collapsed; - ShellContentContainer.Width = double.NaN; - ShellContentContainer.Margin = new Thickness(0, 0, 0, 0); - ShellContentContainer.HorizontalAlignment = HorizontalAlignment.Stretch; + //ShellContentContainer.Width = double.NaN; + //ShellContentContainer.Margin = new Thickness(0, 0, 0, 0); + //ShellContentContainer.HorizontalAlignment = HorizontalAlignment.Stretch; EmptySpaceWidth.Width = new GridLength(1, GridUnitType.Star); @@ -118,8 +118,9 @@ private void DrawTitleBar() if (!IsReaderNarrowed) { - ShellContentContainer.HorizontalAlignment = HorizontalAlignment.Left; - ShellContentContainer.Width = ReadingPaneLength; + //ShellContentContainer.HorizontalAlignment = HorizontalAlignment.Left; + //ShellContentContainer.Width = ReadingPaneLength; + ShellContentContainer.Margin = new Thickness(10, 0, 0, 0); } } else if (NavigationViewDisplayMode == Microsoft.UI.Xaml.Controls.NavigationViewDisplayMode.Expanded) @@ -129,19 +130,30 @@ private void DrawTitleBar() CoreWindowTitleTextBlock.Visibility = Visibility.Visible; // LMargin = OpenPaneLength - LeftMenuStackPanel - ShellContentContainer.Margin = new Thickness(OpenPaneLength - LeftMenuStackPanel.ActualSize.X, 0, 0, 0); + // ShellContentContainer.Margin = new Thickness(OpenPaneLength - LeftMenuStackPanel.ActualSize.X, 0, 0, 0); if (!IsReaderNarrowed) { - ShellContentContainer.HorizontalAlignment = HorizontalAlignment.Left; - ShellContentContainer.Width = ReadingPaneLength; + //ShellContentContainer.HorizontalAlignment = HorizontalAlignment.Left; + //ShellContentContainer.Width = ReadingPaneLength; } } else { - EmptySpaceWidth.Width = new GridLength(ReadingPaneLength, GridUnitType.Pixel); + //EmptySpaceWidth.Width = new GridLength(ReadingPaneLength, GridUnitType.Pixel); } } + + if(this.ActualWidth >= 720) + { + ShellContentContainer.Margin = new Thickness(125, 0, 0, 0); + ShellContentContainer.MaxWidth = 400; + } + else + { + ShellContentContainer.Margin = new Thickness(60, 0, -40, 0); + ShellContentContainer.MaxWidth = double.PositiveInfinity; + } } public WinoAppTitleBar() diff --git a/Wino.Mail/Extensions/ColorExtensions.cs b/Wino.Mail/Extensions/ColorExtensions.cs new file mode 100644 index 00000000..f460ec62 --- /dev/null +++ b/Wino.Mail/Extensions/ColorExtensions.cs @@ -0,0 +1,1908 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.ComponentModel; +using Windows.UI.Xaml.Media; +using System.Collections; +using System.Collections.Specialized; +using System.Diagnostics; +using System.Globalization; +using System.Windows; +using Windows.UI; +using Microsoft.Toolkit.Uwp; + + +namespace Wino.Extensions +{ + public static class ColorExtensions + { + private const int s_zeroChar = (int)'0'; + private const int s_aLower = (int)'a'; + private const int s_aUpper = (int)'A'; + + static private int ParseHexChar(char c) + { + int intChar = (int)c; + + if ((intChar >= s_zeroChar) && (intChar <= (s_zeroChar + 9))) + { + return (intChar - s_zeroChar); + } + + if ((intChar >= s_aLower) && (intChar <= (s_aLower + 5))) + { + return (intChar - s_aLower + 10); + } + + if ((intChar >= s_aUpper) && (intChar <= (s_aUpper + 5))) + { + return (intChar - s_aUpper + 10); + } + + throw new FormatException(); + } + + public static Color HslToRgb(HslColor hsl) + { + double R = 0, G = 0, B = 0; + double S = hsl.S * 1.0f / 255; + double L = hsl.L * 1.0f / 255; + double temp1, temp2, temp3; + if (S == 0f) // 灰色 + { + R = L; + G = L; + B = L; + } + else + { + if (L < 0.5f) + { + temp2 = L * (1.0f + S); + } + else + { + temp2 = L + S - L * S; + } + temp1 = 2.0f * L - temp2; + double H = hsl.H * 1.0f / 360; + // R + temp3 = H + 1.0f / 3.0f; + if (temp3 < 0) temp3 += 1.0f; + if (temp3 > 1) temp3 -= 1.0f; + R = temp3; + // G + temp3 = H; + if (temp3 < 0) temp3 += 1.0f; + if (temp3 > 1) temp3 -= 1.0f; + G = temp3; + // B + temp3 = H - 1.0f / 3.0f; + if (temp3 < 0) temp3 += 1.0f; + if (temp3 > 1) temp3 -= 1.0f; + B = temp3; + } + R = R * 255; + G = G * 255; + B = B * 255; + return Color.FromArgb((byte)hsl.A, (byte)R, (byte)G, (byte)B); + } + + static private Color ParseHexColor(string trimmedColor) + { + int a, r, g, b; + a = 255; + + if (trimmedColor.Length > 7) + { + a = ParseHexChar(trimmedColor[1]) * 16 + ParseHexChar(trimmedColor[2]); + r = ParseHexChar(trimmedColor[3]) * 16 + ParseHexChar(trimmedColor[4]); + g = ParseHexChar(trimmedColor[5]) * 16 + ParseHexChar(trimmedColor[6]); + b = ParseHexChar(trimmedColor[7]) * 16 + ParseHexChar(trimmedColor[8]); + } + else if (trimmedColor.Length > 5) + { + r = ParseHexChar(trimmedColor[1]) * 16 + ParseHexChar(trimmedColor[2]); + g = ParseHexChar(trimmedColor[3]) * 16 + ParseHexChar(trimmedColor[4]); + b = ParseHexChar(trimmedColor[5]) * 16 + ParseHexChar(trimmedColor[6]); + } + else if (trimmedColor.Length > 4) + { + a = ParseHexChar(trimmedColor[1]); + a = a + a * 16; + r = ParseHexChar(trimmedColor[2]); + r = r + r * 16; + g = ParseHexChar(trimmedColor[3]); + g = g + g * 16; + b = ParseHexChar(trimmedColor[4]); + b = b + b * 16; + } + else + { + r = ParseHexChar(trimmedColor[1]); + r = r + r * 16; + g = ParseHexChar(trimmedColor[2]); + g = g + g * 16; + b = ParseHexChar(trimmedColor[3]); + b = b + b * 16; + } + + return (Color.FromArgb((byte)a, (byte)r, (byte)g, (byte)b)); + } + + internal const string s_ContextColor = "ContextColor "; + internal const string s_ContextColorNoSpace = "ContextColor"; + + /// + /// ParseColor + /// string with color description + /// IFormatProvider for processing string + /// + internal static Color ParseColor(string color, IFormatProvider formatProvider) + { + return ParseColor(color, formatProvider, null); + } + + /// + /// ParseColor + /// string with color description + /// IFormatProvider for processing string + /// ITypeDescriptorContext + /// + internal static Color ParseColor(string color, IFormatProvider formatProvider, ITypeDescriptorContext context) + { + bool isPossibleKnowColor; + bool isNumericColor; + bool isScRgbColor; + bool isContextColor; + string trimmedColor = KnownColors.MatchColor(color, out isPossibleKnowColor, out isNumericColor, + out isContextColor, out isScRgbColor); + + if ((isPossibleKnowColor == false) && + (isNumericColor == false) && + (isScRgbColor == false) && + (isContextColor == false)) + { + throw new FormatException(); + } + + //Is it a number? + if (isNumericColor) + { + return ParseHexColor(trimmedColor); + } + else + { + KnownColor kc = KnownColors.ColorStringToKnownColor(trimmedColor); + + if (kc == KnownColor.UnknownColor) + { + throw new FormatException(); + } + + return WellkownColors.FromUInt32((uint)kc); + } + } + + } + + internal class TokenizerHelper + { + /// + /// Constructor for TokenizerHelper which accepts an IFormatProvider. + /// If the IFormatProvider is null, we use the thread's IFormatProvider info. + /// We will use ',' as the list separator, unless it's the same as the + /// decimal separator. If it *is*, then we can't determine if, say, "23,5" is one + /// number or two. In this case, we will use ";" as the separator. + /// + /// The string which will be tokenized. + /// The IFormatProvider which controls this tokenization. + internal TokenizerHelper(string str, IFormatProvider formatProvider) + { + char numberSeparator = GetNumericListSeparator(formatProvider); + + Initialize(str, '\'', numberSeparator); + } + + /// + /// Initialize the TokenizerHelper with the string to tokenize, + /// the char which represents quotes and the list separator. + /// + /// The string to tokenize. + /// The quote char. + /// The list separator. + internal TokenizerHelper(string str, + char quoteChar, + char separator) + { + Initialize(str, quoteChar, separator); + } + + /// + /// Initialize the TokenizerHelper with the string to tokenize, + /// the char which represents quotes and the list separator. + /// + /// The string to tokenize. + /// The quote char. + /// The list separator. + private void Initialize(string str, + char quoteChar, + char separator) + { + _str = str; + _strLen = str == null ? 0 : str.Length; + _currentTokenIndex = -1; + _quoteChar = quoteChar; + _argSeparator = separator; + + // immediately forward past any whitespace so + // NextToken() logic always starts on the first + // character of the next token. + while (_charIndex < _strLen) + { + if (!Char.IsWhiteSpace(_str, _charIndex)) + { + break; + } + + ++_charIndex; + } + } + + internal string GetCurrentToken() + { + // if no current token, return null + if (_currentTokenIndex < 0) + { + return null; + } + + return _str.Substring(_currentTokenIndex, _currentTokenLength); + } + + /// + /// Throws an exception if there is any non-whitespace left un-parsed. + /// + internal void LastTokenRequired() + { + if (_charIndex != _strLen) + { + throw new System.InvalidOperationException(); + } + } + + /// + /// Advances to the NextToken + /// + /// true if next token was found, false if at end of string + internal bool NextToken() + { + return NextToken(false); + } + + /// + /// Advances to the NextToken, throwing an exception if not present + /// + /// The next token found + internal string NextTokenRequired() + { + if (!NextToken(false)) + { + throw new System.InvalidOperationException(); + } + + return GetCurrentToken(); + } + + /// + /// Advances to the NextToken, throwing an exception if not present + /// + /// The next token found + internal string NextTokenRequired(bool allowQuotedToken) + { + if (!NextToken(allowQuotedToken)) + { + throw new System.InvalidOperationException(); + } + + return GetCurrentToken(); + } + + /// + /// Advances to the NextToken + /// + /// true if next token was found, false if at end of string + internal bool NextToken(bool allowQuotedToken) + { + // use the currently-set separator character. + return NextToken(allowQuotedToken, _argSeparator); + } + + /// + /// Advances to the NextToken. A separator character can be specified + /// which overrides the one previously set. + /// + /// true if next token was found, false if at end of string + internal bool NextToken(bool allowQuotedToken, char separator) + { + _currentTokenIndex = -1; // reset the currentTokenIndex + _foundSeparator = false; // reset + + // If we're at end of the string, just return false. + if (_charIndex >= _strLen) + { + return false; + } + + char currentChar = _str[_charIndex]; + + Debug.Assert(!Char.IsWhiteSpace(currentChar), "Token started on Whitespace"); + + // setup the quoteCount + int quoteCount = 0; + + // If we are allowing a quoted token and this token begins with a quote, + // set up the quote count and skip the initial quote + if (allowQuotedToken && + currentChar == _quoteChar) + { + quoteCount++; // increment quote count + ++_charIndex; // move to next character + } + + int newTokenIndex = _charIndex; + int newTokenLength = 0; + + // loop until hit end of string or hit a , or whitespace + // if at end of string ust return false. + while (_charIndex < _strLen) + { + currentChar = _str[_charIndex]; + + // if have a QuoteCount and this is a quote + // decrement the quoteCount + if (quoteCount > 0) + { + // if anything but a quoteChar we move on + if (currentChar == _quoteChar) + { + --quoteCount; + + // if at zero which it always should for now + // break out of the loop + if (0 == quoteCount) + { + ++_charIndex; // move past the quote + break; + } + } + } + else if ((Char.IsWhiteSpace(currentChar)) || (currentChar == separator)) + { + if (currentChar == separator) + { + _foundSeparator = true; + } + break; + } + + ++_charIndex; + ++newTokenLength; + } + + // if quoteCount isn't zero we hit the end of the string + // before the ending quote + if (quoteCount > 0) + { + throw new System.InvalidOperationException(); + } + + ScanToNextToken(separator); // move so at the start of the nextToken for next call + + // finally made it, update the _currentToken values + _currentTokenIndex = newTokenIndex; + _currentTokenLength = newTokenLength; + + if (_currentTokenLength < 1) + { + throw new System.InvalidOperationException(); + } + + return true; + } + + // helper to move the _charIndex to the next token or to the end of the string + void ScanToNextToken(char separator) + { + // if already at end of the string don't bother + if (_charIndex < _strLen) + { + char currentChar = _str[_charIndex]; + + // check that the currentChar is a space or the separator. If not + // we have an error. this can happen in the quote case + // that the char after the quotes string isn't a char. + if (!(currentChar == separator) && + !Char.IsWhiteSpace(currentChar)) + { + throw new System.InvalidOperationException(); + } + + // loop until hit a character that isn't + // an argument separator or whitespace. + int argSepCount = 0; + while (_charIndex < _strLen) + { + currentChar = _str[_charIndex]; + + if (currentChar == separator) + { + _foundSeparator = true; + ++argSepCount; + _charIndex++; + + if (argSepCount > 1) + { + throw new System.InvalidOperationException(); + } + } + else if (Char.IsWhiteSpace(currentChar)) + { + ++_charIndex; + } + else + { + break; + } + } + + // if there was a separatorChar then we shouldn't be + // at the end of string or means there was a separator + // but there isn't an arg + + if (argSepCount > 0 && _charIndex >= _strLen) + { + throw new System.InvalidOperationException(); + } + } + } + + // Helper to get the numeric list separator for a given IFormatProvider. + // Separator is a comma [,] if the decimal separator is not a comma, or a semicolon [;] otherwise. + static internal char GetNumericListSeparator(IFormatProvider provider) + { + char numericSeparator = ','; + + // Get the NumberFormatInfo out of the provider, if possible + // If the IFormatProvider doesn't not contain a NumberFormatInfo, then + // this method returns the current culture's NumberFormatInfo. + NumberFormatInfo numberFormat = NumberFormatInfo.GetInstance(provider); + + Debug.Assert(null != numberFormat); + + // Is the decimal separator is the same as the list separator? + // If so, we use the ";". + if ((numberFormat.NumberDecimalSeparator.Length > 0) && (numericSeparator == numberFormat.NumberDecimalSeparator[0])) + { + numericSeparator = ';'; + } + + return numericSeparator; + } + + internal bool FoundSeparator => _foundSeparator; + + char _quoteChar; + char _argSeparator; + string _str; + int _strLen; + int _charIndex; + internal int _currentTokenIndex; + internal int _currentTokenLength; + bool _foundSeparator; + }/// Enum containing handles to all known colors + /// Since the first element is 0, second is 1, etc, we can use this to index + /// directly into an array + internal enum KnownColor : uint + { + // We've reserved the value "1" as unknown. If for some odd reason "1" is added to the + // list, redefined UnknownColor + + AliceBlue = 0xFFF0F8FF, + AntiqueWhite = 0xFFFAEBD7, + Aqua = 0xFF00FFFF, + Aquamarine = 0xFF7FFFD4, + Azure = 0xFFF0FFFF, + Beige = 0xFFF5F5DC, + Bisque = 0xFFFFE4C4, + Black = 0xFF000000, + BlanchedAlmond = 0xFFFFEBCD, + Blue = 0xFF0000FF, + BlueViolet = 0xFF8A2BE2, + Brown = 0xFFA52A2A, + BurlyWood = 0xFFDEB887, + CadetBlue = 0xFF5F9EA0, + Chartreuse = 0xFF7FFF00, + Chocolate = 0xFFD2691E, + Coral = 0xFFFF7F50, + CornflowerBlue = 0xFF6495ED, + Cornsilk = 0xFFFFF8DC, + Crimson = 0xFFDC143C, + Cyan = 0xFF00FFFF, + DarkBlue = 0xFF00008B, + DarkCyan = 0xFF008B8B, + DarkGoldenrod = 0xFFB8860B, + DarkGray = 0xFFA9A9A9, + DarkGreen = 0xFF006400, + DarkKhaki = 0xFFBDB76B, + DarkMagenta = 0xFF8B008B, + DarkOliveGreen = 0xFF556B2F, + DarkOrange = 0xFFFF8C00, + DarkOrchid = 0xFF9932CC, + DarkRed = 0xFF8B0000, + DarkSalmon = 0xFFE9967A, + DarkSeaGreen = 0xFF8FBC8F, + DarkSlateBlue = 0xFF483D8B, + DarkSlateGray = 0xFF2F4F4F, + DarkTurquoise = 0xFF00CED1, + DarkViolet = 0xFF9400D3, + DeepPink = 0xFFFF1493, + DeepSkyBlue = 0xFF00BFFF, + DimGray = 0xFF696969, + DodgerBlue = 0xFF1E90FF, + Firebrick = 0xFFB22222, + FloralWhite = 0xFFFFFAF0, + ForestGreen = 0xFF228B22, + Fuchsia = 0xFFFF00FF, + Gainsboro = 0xFFDCDCDC, + GhostWhite = 0xFFF8F8FF, + Gold = 0xFFFFD700, + Goldenrod = 0xFFDAA520, + Gray = 0xFF808080, + Green = 0xFF008000, + GreenYellow = 0xFFADFF2F, + Honeydew = 0xFFF0FFF0, + HotPink = 0xFFFF69B4, + IndianRed = 0xFFCD5C5C, + Indigo = 0xFF4B0082, + Ivory = 0xFFFFFFF0, + Khaki = 0xFFF0E68C, + Lavender = 0xFFE6E6FA, + LavenderBlush = 0xFFFFF0F5, + LawnGreen = 0xFF7CFC00, + LemonChiffon = 0xFFFFFACD, + LightBlue = 0xFFADD8E6, + LightCoral = 0xFFF08080, + LightCyan = 0xFFE0FFFF, + LightGoldenrodYellow = 0xFFFAFAD2, + LightGreen = 0xFF90EE90, + LightGray = 0xFFD3D3D3, + LightPink = 0xFFFFB6C1, + LightSalmon = 0xFFFFA07A, + LightSeaGreen = 0xFF20B2AA, + LightSkyBlue = 0xFF87CEFA, + LightSlateGray = 0xFF778899, + LightSteelBlue = 0xFFB0C4DE, + LightYellow = 0xFFFFFFE0, + Lime = 0xFF00FF00, + LimeGreen = 0xFF32CD32, + Linen = 0xFFFAF0E6, + Magenta = 0xFFFF00FF, + Maroon = 0xFF800000, + MediumAquamarine = 0xFF66CDAA, + MediumBlue = 0xFF0000CD, + MediumOrchid = 0xFFBA55D3, + MediumPurple = 0xFF9370DB, + MediumSeaGreen = 0xFF3CB371, + MediumSlateBlue = 0xFF7B68EE, + MediumSpringGreen = 0xFF00FA9A, + MediumTurquoise = 0xFF48D1CC, + MediumVioletRed = 0xFFC71585, + MidnightBlue = 0xFF191970, + MintCream = 0xFFF5FFFA, + MistyRose = 0xFFFFE4E1, + Moccasin = 0xFFFFE4B5, + NavajoWhite = 0xFFFFDEAD, + Navy = 0xFF000080, + OldLace = 0xFFFDF5E6, + Olive = 0xFF808000, + OliveDrab = 0xFF6B8E23, + Orange = 0xFFFFA500, + OrangeRed = 0xFFFF4500, + Orchid = 0xFFDA70D6, + PaleGoldenrod = 0xFFEEE8AA, + PaleGreen = 0xFF98FB98, + PaleTurquoise = 0xFFAFEEEE, + PaleVioletRed = 0xFFDB7093, + PapayaWhip = 0xFFFFEFD5, + PeachPuff = 0xFFFFDAB9, + Peru = 0xFFCD853F, + Pink = 0xFFFFC0CB, + Plum = 0xFFDDA0DD, + PowderBlue = 0xFFB0E0E6, + Purple = 0xFF800080, + Red = 0xFFFF0000, + RosyBrown = 0xFFBC8F8F, + RoyalBlue = 0xFF4169E1, + SaddleBrown = 0xFF8B4513, + Salmon = 0xFFFA8072, + SandyBrown = 0xFFF4A460, + SeaGreen = 0xFF2E8B57, + SeaShell = 0xFFFFF5EE, + Sienna = 0xFFA0522D, + Silver = 0xFFC0C0C0, + SkyBlue = 0xFF87CEEB, + SlateBlue = 0xFF6A5ACD, + SlateGray = 0xFF708090, + Snow = 0xFFFFFAFA, + SpringGreen = 0xFF00FF7F, + SteelBlue = 0xFF4682B4, + Tan = 0xFFD2B48C, + Teal = 0xFF008080, + Thistle = 0xFFD8BFD8, + Tomato = 0xFFFF6347, + Transparent = 0x00FFFFFF, + Turquoise = 0xFF40E0D0, + Violet = 0xFFEE82EE, + Wheat = 0xFFF5DEB3, + White = 0xFFFFFFFF, + WhiteSmoke = 0xFFF5F5F5, + Yellow = 0xFFFFFF00, + YellowGreen = 0xFF9ACD32, + UnknownColor = 0x00000001 + } + + internal static class KnownColors + { +#if !PBTCOMPILER + + static KnownColors() + { + Array knownColorValues = Enum.GetValues(typeof(KnownColor)); + foreach (KnownColor colorValue in knownColorValues) + { + string aRGBString = String.Format("#{0,8:X8}", (uint)colorValue); + s_knownArgbColors[aRGBString] = colorValue; + } + } + + /// Return the solid color brush from a color string. If there's no match, null + public static SolidColorBrush ColorStringToKnownBrush(string s) + { + if (null != s) + { + KnownColor result = ColorStringToKnownColor(s); + + // If the result is UnknownColor, that means this string wasn't found + if (result != KnownColor.UnknownColor) + { + // Otherwise, return the appropriate SolidColorBrush + return SolidColorBrushFromUint((uint)result); + } + } + return null; + } + + public static bool IsKnownSolidColorBrush(SolidColorBrush scp) + { + lock (s_solidColorBrushCache) + { + return s_solidColorBrushCache.ContainsValue(scp); + } + } + + public static SolidColorBrush SolidColorBrushFromUint(uint argb) + { + SolidColorBrush scp = null; + + lock (s_solidColorBrushCache) + { + // Attempt to retrieve the color. If it fails create it. + if (!s_solidColorBrushCache.TryGetValue(argb, out scp)) + { + scp = new SolidColorBrush(WellkownColors.FromUInt32(argb)); + s_solidColorBrushCache[argb] = scp; + } +#if DEBUG + else + { + s_count++; + } +#endif + } + + return scp; + } + + static internal string MatchColor(string colorString, out bool isKnownColor, out bool isNumericColor, out bool isContextColor, out bool isScRgbColor) + { + string trimmedString = colorString.Trim(); + + if (((trimmedString.Length == 4) || + (trimmedString.Length == 5) || + (trimmedString.Length == 7) || + (trimmedString.Length == 9)) && + (trimmedString[0] == '#')) + { + isNumericColor = true; + isScRgbColor = false; + isKnownColor = false; + isContextColor = false; + return trimmedString; + } + else + isNumericColor = false; + + if ((trimmedString.StartsWith("sc#", StringComparison.Ordinal) == true)) + { + isNumericColor = false; + isScRgbColor = true; + isKnownColor = false; + isContextColor = false; + } + else + { + isScRgbColor = false; + } + + { + isContextColor = false; + isKnownColor = true; + } + + return trimmedString; + } +#endif + + /// Return the KnownColor from a color string. If there's no match, KnownColor.UnknownColor + internal static KnownColor ColorStringToKnownColor(string colorString) + { + if (null != colorString) + { + // We use invariant culture because we don't globalize our color names + string colorUpper = colorString.ToUpper(System.Globalization.CultureInfo.InvariantCulture); + + // Use String.Equals because it does explicit equality + // StartsWith/EndsWith are culture sensitive and are 4-7 times slower than Equals + + switch (colorUpper.Length) + { + case 3: + if (colorUpper.Equals("RED")) return KnownColor.Red; + if (colorUpper.Equals("TAN")) return KnownColor.Tan; + break; + case 4: + switch (colorUpper[0]) + { + case 'A': + if (colorUpper.Equals("AQUA")) return KnownColor.Aqua; + break; + case 'B': + if (colorUpper.Equals("BLUE")) return KnownColor.Blue; + break; + case 'C': + if (colorUpper.Equals("CYAN")) return KnownColor.Cyan; + break; + case 'G': + if (colorUpper.Equals("GOLD")) return KnownColor.Gold; + if (colorUpper.Equals("GRAY")) return KnownColor.Gray; + break; + case 'L': + if (colorUpper.Equals("LIME")) return KnownColor.Lime; + break; + case 'N': + if (colorUpper.Equals("NAVY")) return KnownColor.Navy; + break; + case 'P': + if (colorUpper.Equals("PERU")) return KnownColor.Peru; + if (colorUpper.Equals("PINK")) return KnownColor.Pink; + if (colorUpper.Equals("PLUM")) return KnownColor.Plum; + break; + case 'S': + if (colorUpper.Equals("SNOW")) return KnownColor.Snow; + break; + case 'T': + if (colorUpper.Equals("TEAL")) return KnownColor.Teal; + break; + } + break; + case 5: + switch (colorUpper[0]) + { + case 'A': + if (colorUpper.Equals("AZURE")) return KnownColor.Azure; + break; + case 'B': + if (colorUpper.Equals("BEIGE")) return KnownColor.Beige; + if (colorUpper.Equals("BLACK")) return KnownColor.Black; + if (colorUpper.Equals("BROWN")) return KnownColor.Brown; + break; + case 'C': + if (colorUpper.Equals("CORAL")) return KnownColor.Coral; + break; + case 'G': + if (colorUpper.Equals("GREEN")) return KnownColor.Green; + break; + case 'I': + if (colorUpper.Equals("IVORY")) return KnownColor.Ivory; + break; + case 'K': + if (colorUpper.Equals("KHAKI")) return KnownColor.Khaki; + break; + case 'L': + if (colorUpper.Equals("LINEN")) return KnownColor.Linen; + break; + case 'O': + if (colorUpper.Equals("OLIVE")) return KnownColor.Olive; + break; + case 'W': + if (colorUpper.Equals("WHEAT")) return KnownColor.Wheat; + if (colorUpper.Equals("WHITE")) return KnownColor.White; + break; + } + break; + case 6: + switch (colorUpper[0]) + { + case 'B': + if (colorUpper.Equals("BISQUE")) return KnownColor.Bisque; + break; + case 'I': + if (colorUpper.Equals("INDIGO")) return KnownColor.Indigo; + break; + case 'M': + if (colorUpper.Equals("MAROON")) return KnownColor.Maroon; + break; + case 'O': + if (colorUpper.Equals("ORANGE")) return KnownColor.Orange; + if (colorUpper.Equals("ORCHID")) return KnownColor.Orchid; + break; + case 'P': + if (colorUpper.Equals("PURPLE")) return KnownColor.Purple; + break; + case 'S': + if (colorUpper.Equals("SALMON")) return KnownColor.Salmon; + if (colorUpper.Equals("SIENNA")) return KnownColor.Sienna; + if (colorUpper.Equals("SILVER")) return KnownColor.Silver; + break; + case 'T': + if (colorUpper.Equals("TOMATO")) return KnownColor.Tomato; + break; + case 'V': + if (colorUpper.Equals("VIOLET")) return KnownColor.Violet; + break; + case 'Y': + if (colorUpper.Equals("YELLOW")) return KnownColor.Yellow; + break; + } + break; + case 7: + switch (colorUpper[0]) + { + case 'C': + if (colorUpper.Equals("CRIMSON")) return KnownColor.Crimson; + break; + case 'D': + if (colorUpper.Equals("DARKRED")) return KnownColor.DarkRed; + if (colorUpper.Equals("DIMGRAY")) return KnownColor.DimGray; + break; + case 'F': + if (colorUpper.Equals("FUCHSIA")) return KnownColor.Fuchsia; + break; + case 'H': + if (colorUpper.Equals("HOTPINK")) return KnownColor.HotPink; + break; + case 'M': + if (colorUpper.Equals("MAGENTA")) return KnownColor.Magenta; + break; + case 'O': + if (colorUpper.Equals("OLDLACE")) return KnownColor.OldLace; + break; + case 'S': + if (colorUpper.Equals("SKYBLUE")) return KnownColor.SkyBlue; + break; + case 'T': + if (colorUpper.Equals("THISTLE")) return KnownColor.Thistle; + break; + } + break; + case 8: + switch (colorUpper[0]) + { + case 'C': + if (colorUpper.Equals("CORNSILK")) return KnownColor.Cornsilk; + break; + case 'D': + if (colorUpper.Equals("DARKBLUE")) return KnownColor.DarkBlue; + if (colorUpper.Equals("DARKCYAN")) return KnownColor.DarkCyan; + if (colorUpper.Equals("DARKGRAY")) return KnownColor.DarkGray; + if (colorUpper.Equals("DEEPPINK")) return KnownColor.DeepPink; + break; + case 'H': + if (colorUpper.Equals("HONEYDEW")) return KnownColor.Honeydew; + break; + case 'L': + if (colorUpper.Equals("LAVENDER")) return KnownColor.Lavender; + break; + case 'M': + if (colorUpper.Equals("MOCCASIN")) return KnownColor.Moccasin; + break; + case 'S': + if (colorUpper.Equals("SEAGREEN")) return KnownColor.SeaGreen; + if (colorUpper.Equals("SEASHELL")) return KnownColor.SeaShell; + break; + } + break; + case 9: + switch (colorUpper[0]) + { + case 'A': + if (colorUpper.Equals("ALICEBLUE")) return KnownColor.AliceBlue; + break; + case 'B': + if (colorUpper.Equals("BURLYWOOD")) return KnownColor.BurlyWood; + break; + case 'C': + if (colorUpper.Equals("CADETBLUE")) return KnownColor.CadetBlue; + if (colorUpper.Equals("CHOCOLATE")) return KnownColor.Chocolate; + break; + case 'D': + if (colorUpper.Equals("DARKGREEN")) return KnownColor.DarkGreen; + if (colorUpper.Equals("DARKKHAKI")) return KnownColor.DarkKhaki; + break; + case 'F': + if (colorUpper.Equals("FIREBRICK")) return KnownColor.Firebrick; + break; + case 'G': + if (colorUpper.Equals("GAINSBORO")) return KnownColor.Gainsboro; + if (colorUpper.Equals("GOLDENROD")) return KnownColor.Goldenrod; + break; + case 'I': + if (colorUpper.Equals("INDIANRED")) return KnownColor.IndianRed; + break; + case 'L': + if (colorUpper.Equals("LAWNGREEN")) return KnownColor.LawnGreen; + if (colorUpper.Equals("LIGHTBLUE")) return KnownColor.LightBlue; + if (colorUpper.Equals("LIGHTCYAN")) return KnownColor.LightCyan; + if (colorUpper.Equals("LIGHTGRAY")) return KnownColor.LightGray; + if (colorUpper.Equals("LIGHTPINK")) return KnownColor.LightPink; + if (colorUpper.Equals("LIMEGREEN")) return KnownColor.LimeGreen; + break; + case 'M': + if (colorUpper.Equals("MINTCREAM")) return KnownColor.MintCream; + if (colorUpper.Equals("MISTYROSE")) return KnownColor.MistyRose; + break; + case 'O': + if (colorUpper.Equals("OLIVEDRAB")) return KnownColor.OliveDrab; + if (colorUpper.Equals("ORANGERED")) return KnownColor.OrangeRed; + break; + case 'P': + if (colorUpper.Equals("PALEGREEN")) return KnownColor.PaleGreen; + if (colorUpper.Equals("PEACHPUFF")) return KnownColor.PeachPuff; + break; + case 'R': + if (colorUpper.Equals("ROSYBROWN")) return KnownColor.RosyBrown; + if (colorUpper.Equals("ROYALBLUE")) return KnownColor.RoyalBlue; + break; + case 'S': + if (colorUpper.Equals("SLATEBLUE")) return KnownColor.SlateBlue; + if (colorUpper.Equals("SLATEGRAY")) return KnownColor.SlateGray; + if (colorUpper.Equals("STEELBLUE")) return KnownColor.SteelBlue; + break; + case 'T': + if (colorUpper.Equals("TURQUOISE")) return KnownColor.Turquoise; + break; + } + break; + case 10: + switch (colorUpper[0]) + { + case 'A': + if (colorUpper.Equals("AQUAMARINE")) return KnownColor.Aquamarine; + break; + case 'B': + if (colorUpper.Equals("BLUEVIOLET")) return KnownColor.BlueViolet; + break; + case 'C': + if (colorUpper.Equals("CHARTREUSE")) return KnownColor.Chartreuse; + break; + case 'D': + if (colorUpper.Equals("DARKORANGE")) return KnownColor.DarkOrange; + if (colorUpper.Equals("DARKORCHID")) return KnownColor.DarkOrchid; + if (colorUpper.Equals("DARKSALMON")) return KnownColor.DarkSalmon; + if (colorUpper.Equals("DARKVIOLET")) return KnownColor.DarkViolet; + if (colorUpper.Equals("DODGERBLUE")) return KnownColor.DodgerBlue; + break; + case 'G': + if (colorUpper.Equals("GHOSTWHITE")) return KnownColor.GhostWhite; + break; + case 'L': + if (colorUpper.Equals("LIGHTCORAL")) return KnownColor.LightCoral; + if (colorUpper.Equals("LIGHTGREEN")) return KnownColor.LightGreen; + break; + case 'M': + if (colorUpper.Equals("MEDIUMBLUE")) return KnownColor.MediumBlue; + break; + case 'P': + if (colorUpper.Equals("PAPAYAWHIP")) return KnownColor.PapayaWhip; + if (colorUpper.Equals("POWDERBLUE")) return KnownColor.PowderBlue; + break; + case 'S': + if (colorUpper.Equals("SANDYBROWN")) return KnownColor.SandyBrown; + break; + case 'W': + if (colorUpper.Equals("WHITESMOKE")) return KnownColor.WhiteSmoke; + break; + } + break; + case 11: + switch (colorUpper[0]) + { + case 'D': + if (colorUpper.Equals("DARKMAGENTA")) return KnownColor.DarkMagenta; + if (colorUpper.Equals("DEEPSKYBLUE")) return KnownColor.DeepSkyBlue; + break; + case 'F': + if (colorUpper.Equals("FLORALWHITE")) return KnownColor.FloralWhite; + if (colorUpper.Equals("FORESTGREEN")) return KnownColor.ForestGreen; + break; + case 'G': + if (colorUpper.Equals("GREENYELLOW")) return KnownColor.GreenYellow; + break; + case 'L': + if (colorUpper.Equals("LIGHTSALMON")) return KnownColor.LightSalmon; + if (colorUpper.Equals("LIGHTYELLOW")) return KnownColor.LightYellow; + break; + case 'N': + if (colorUpper.Equals("NAVAJOWHITE")) return KnownColor.NavajoWhite; + break; + case 'S': + if (colorUpper.Equals("SADDLEBROWN")) return KnownColor.SaddleBrown; + if (colorUpper.Equals("SPRINGGREEN")) return KnownColor.SpringGreen; + break; + case 'T': + if (colorUpper.Equals("TRANSPARENT")) return KnownColor.Transparent; + break; + case 'Y': + if (colorUpper.Equals("YELLOWGREEN")) return KnownColor.YellowGreen; + break; + } + break; + case 12: + switch (colorUpper[0]) + { + case 'A': + if (colorUpper.Equals("ANTIQUEWHITE")) return KnownColor.AntiqueWhite; + break; + case 'D': + if (colorUpper.Equals("DARKSEAGREEN")) return KnownColor.DarkSeaGreen; + break; + case 'L': + if (colorUpper.Equals("LIGHTSKYBLUE")) return KnownColor.LightSkyBlue; + if (colorUpper.Equals("LEMONCHIFFON")) return KnownColor.LemonChiffon; + break; + case 'M': + if (colorUpper.Equals("MEDIUMORCHID")) return KnownColor.MediumOrchid; + if (colorUpper.Equals("MEDIUMPURPLE")) return KnownColor.MediumPurple; + if (colorUpper.Equals("MIDNIGHTBLUE")) return KnownColor.MidnightBlue; + break; + } + break; + case 13: + switch (colorUpper[0]) + { + case 'D': + if (colorUpper.Equals("DARKSLATEBLUE")) return KnownColor.DarkSlateBlue; + if (colorUpper.Equals("DARKSLATEGRAY")) return KnownColor.DarkSlateGray; + if (colorUpper.Equals("DARKGOLDENROD")) return KnownColor.DarkGoldenrod; + if (colorUpper.Equals("DARKTURQUOISE")) return KnownColor.DarkTurquoise; + break; + case 'L': + if (colorUpper.Equals("LIGHTSEAGREEN")) return KnownColor.LightSeaGreen; + if (colorUpper.Equals("LAVENDERBLUSH")) return KnownColor.LavenderBlush; + break; + case 'P': + if (colorUpper.Equals("PALEGOLDENROD")) return KnownColor.PaleGoldenrod; + if (colorUpper.Equals("PALETURQUOISE")) return KnownColor.PaleTurquoise; + if (colorUpper.Equals("PALEVIOLETRED")) return KnownColor.PaleVioletRed; + break; + } + break; + case 14: + switch (colorUpper[0]) + { + case 'B': + if (colorUpper.Equals("BLANCHEDALMOND")) return KnownColor.BlanchedAlmond; + break; + case 'C': + if (colorUpper.Equals("CORNFLOWERBLUE")) return KnownColor.CornflowerBlue; + break; + case 'D': + if (colorUpper.Equals("DARKOLIVEGREEN")) return KnownColor.DarkOliveGreen; + break; + case 'L': + if (colorUpper.Equals("LIGHTSLATEGRAY")) return KnownColor.LightSlateGray; + if (colorUpper.Equals("LIGHTSTEELBLUE")) return KnownColor.LightSteelBlue; + break; + case 'M': + if (colorUpper.Equals("MEDIUMSEAGREEN")) return KnownColor.MediumSeaGreen; + break; + } + break; + case 15: + if (colorUpper.Equals("MEDIUMSLATEBLUE")) return KnownColor.MediumSlateBlue; + if (colorUpper.Equals("MEDIUMTURQUOISE")) return KnownColor.MediumTurquoise; + if (colorUpper.Equals("MEDIUMVIOLETRED")) return KnownColor.MediumVioletRed; + break; + case 16: + if (colorUpper.Equals("MEDIUMAQUAMARINE")) return KnownColor.MediumAquamarine; + break; + case 17: + if (colorUpper.Equals("MEDIUMSPRINGGREEN")) return KnownColor.MediumSpringGreen; + break; + case 20: + if (colorUpper.Equals("LIGHTGOLDENRODYELLOW")) return KnownColor.LightGoldenrodYellow; + break; + } + } + // colorString was null or not found + return KnownColor.UnknownColor; + } + +#if !PBTCOMPILER + internal static KnownColor ArgbStringToKnownColor(string argbString) + { + string argbUpper = argbString.Trim().ToUpper(System.Globalization.CultureInfo.InvariantCulture); + + KnownColor color; + if (s_knownArgbColors.TryGetValue(argbUpper, out color)) + return color; + + return KnownColor.UnknownColor; + } +#if DEBUG + private static int s_count = 0; +#endif + + private static Dictionary s_solidColorBrushCache = new Dictionary(); + private static Dictionary s_knownArgbColors = new Dictionary(); +#endif + } + +#if !PBTCOMPILER + /// + /// Colors - A collection of well-known Colors + /// + public sealed class WellkownColors + { + #region Constructors + + // Colors only has static members, so it shouldn't be constructable. + private WellkownColors() + { + } + + #endregion Constructors + + public static Color FromUInt32(uint colorCode) + { + uint alpha = (colorCode & 0xFF000000) >> 24; + var red = (colorCode & 0x00FF0000) >> 16; + var green = (colorCode & 0x0000FF00) >> 8; + var blue = (colorCode & 0x000000FF) >> 0; + return Color.FromArgb((byte)alpha, (byte)red, (byte)green, (byte)blue); + } + + #region static Known Colors + + /// + /// Well-known color: AliceBlue + /// + public static Color AliceBlue => FromUInt32((uint)KnownColor.AliceBlue); + + /// + /// Well-known color: AntiqueWhite + /// + public static Color AntiqueWhite => FromUInt32((uint)KnownColor.AntiqueWhite); + + /// + /// Well-known color: Aqua + /// + public static Color Aqua => FromUInt32((uint)KnownColor.Aqua); + + /// + /// Well-known color: Aquamarine + /// + public static Color Aquamarine => FromUInt32((uint)KnownColor.Aquamarine); + + /// + /// Well-known color: Azure + /// + public static Color Azure => FromUInt32((uint)KnownColor.Azure); + + /// + /// Well-known color: Beige + /// + public static Color Beige => FromUInt32((uint)KnownColor.Beige); + + /// + /// Well-known color: Bisque + /// + public static Color Bisque => FromUInt32((uint)KnownColor.Bisque); + + /// + /// Well-known color: Black + /// + public static Color Black => FromUInt32((uint)KnownColor.Black); + + /// + /// Well-known color: BlanchedAlmond + /// + public static Color BlanchedAlmond => FromUInt32((uint)KnownColor.BlanchedAlmond); + + /// + /// Well-known color: Blue + /// + public static Color Blue => FromUInt32((uint)KnownColor.Blue); + + /// + /// Well-known color: BlueViolet + /// + public static Color BlueViolet => FromUInt32((uint)KnownColor.BlueViolet); + + /// + /// Well-known color: Brown + /// + public static Color Brown => FromUInt32((uint)KnownColor.Brown); + + /// + /// Well-known color: BurlyWood + /// + public static Color BurlyWood => FromUInt32((uint)KnownColor.BurlyWood); + + /// + /// Well-known color: CadetBlue + /// + public static Color CadetBlue => FromUInt32((uint)KnownColor.CadetBlue); + + /// + /// Well-known color: Chartreuse + /// + public static Color Chartreuse => FromUInt32((uint)KnownColor.Chartreuse); + + /// + /// Well-known color: Chocolate + /// + public static Color Chocolate => FromUInt32((uint)KnownColor.Chocolate); + + /// + /// Well-known color: Coral + /// + public static Color Coral => FromUInt32((uint)KnownColor.Coral); + + /// + /// Well-known color: CornflowerBlue + /// + public static Color CornflowerBlue => FromUInt32((uint)KnownColor.CornflowerBlue); + + /// + /// Well-known color: Cornsilk + /// + public static Color Cornsilk => FromUInt32((uint)KnownColor.Cornsilk); + + /// + /// Well-known color: Crimson + /// + public static Color Crimson => FromUInt32((uint)KnownColor.Crimson); + + /// + /// Well-known color: Cyan + /// + public static Color Cyan => FromUInt32((uint)KnownColor.Cyan); + + /// + /// Well-known color: DarkBlue + /// + public static Color DarkBlue => FromUInt32((uint)KnownColor.DarkBlue); + + /// + /// Well-known color: DarkCyan + /// + public static Color DarkCyan => FromUInt32((uint)KnownColor.DarkCyan); + + /// + /// Well-known color: DarkGoldenrod + /// + public static Color DarkGoldenrod => FromUInt32((uint)KnownColor.DarkGoldenrod); + + /// + /// Well-known color: DarkGray + /// + public static Color DarkGray => FromUInt32((uint)KnownColor.DarkGray); + + /// + /// Well-known color: DarkGreen + /// + public static Color DarkGreen => FromUInt32((uint)KnownColor.DarkGreen); + + /// + /// Well-known color: DarkKhaki + /// + public static Color DarkKhaki => FromUInt32((uint)KnownColor.DarkKhaki); + + /// + /// Well-known color: DarkMagenta + /// + public static Color DarkMagenta => FromUInt32((uint)KnownColor.DarkMagenta); + + /// + /// Well-known color: DarkOliveGreen + /// + public static Color DarkOliveGreen => FromUInt32((uint)KnownColor.DarkOliveGreen); + + /// + /// Well-known color: DarkOrange + /// + public static Color DarkOrange => FromUInt32((uint)KnownColor.DarkOrange); + + /// + /// Well-known color: DarkOrchid + /// + public static Color DarkOrchid => FromUInt32((uint)KnownColor.DarkOrchid); + + /// + /// Well-known color: DarkRed + /// + public static Color DarkRed => FromUInt32((uint)KnownColor.DarkRed); + + /// + /// Well-known color: DarkSalmon + /// + public static Color DarkSalmon => FromUInt32((uint)KnownColor.DarkSalmon); + + /// + /// Well-known color: DarkSeaGreen + /// + public static Color DarkSeaGreen => FromUInt32((uint)KnownColor.DarkSeaGreen); + + /// + /// Well-known color: DarkSlateBlue + /// + public static Color DarkSlateBlue => FromUInt32((uint)KnownColor.DarkSlateBlue); + + /// + /// Well-known color: DarkSlateGray + /// + public static Color DarkSlateGray => FromUInt32((uint)KnownColor.DarkSlateGray); + + /// + /// Well-known color: DarkTurquoise + /// + public static Color DarkTurquoise => FromUInt32((uint)KnownColor.DarkTurquoise); + + /// + /// Well-known color: DarkViolet + /// + public static Color DarkViolet => FromUInt32((uint)KnownColor.DarkViolet); + + /// + /// Well-known color: DeepPink + /// + public static Color DeepPink => FromUInt32((uint)KnownColor.DeepPink); + + /// + /// Well-known color: DeepSkyBlue + /// + public static Color DeepSkyBlue => FromUInt32((uint)KnownColor.DeepSkyBlue); + + /// + /// Well-known color: DimGray + /// + public static Color DimGray => FromUInt32((uint)KnownColor.DimGray); + + /// + /// Well-known color: DodgerBlue + /// + public static Color DodgerBlue => FromUInt32((uint)KnownColor.DodgerBlue); + + /// + /// Well-known color: Firebrick + /// + public static Color Firebrick => FromUInt32((uint)KnownColor.Firebrick); + + /// + /// Well-known color: FloralWhite + /// + public static Color FloralWhite => FromUInt32((uint)KnownColor.FloralWhite); + + /// + /// Well-known color: ForestGreen + /// + public static Color ForestGreen => FromUInt32((uint)KnownColor.ForestGreen); + + /// + /// Well-known color: Fuchsia + /// + public static Color Fuchsia => FromUInt32((uint)KnownColor.Fuchsia); + + /// + /// Well-known color: Gainsboro + /// + public static Color Gainsboro => FromUInt32((uint)KnownColor.Gainsboro); + + /// + /// Well-known color: GhostWhite + /// + public static Color GhostWhite => FromUInt32((uint)KnownColor.GhostWhite); + + /// + /// Well-known color: Gold + /// + public static Color Gold => FromUInt32((uint)KnownColor.Gold); + + /// + /// Well-known color: Goldenrod + /// + public static Color Goldenrod => FromUInt32((uint)KnownColor.Goldenrod); + + /// + /// Well-known color: Gray + /// + public static Color Gray => FromUInt32((uint)KnownColor.Gray); + + /// + /// Well-known color: Green + /// + public static Color Green => FromUInt32((uint)KnownColor.Green); + + /// + /// Well-known color: GreenYellow + /// + public static Color GreenYellow => FromUInt32((uint)KnownColor.GreenYellow); + + /// + /// Well-known color: Honeydew + /// + public static Color Honeydew => FromUInt32((uint)KnownColor.Honeydew); + + /// + /// Well-known color: HotPink + /// + public static Color HotPink => FromUInt32((uint)KnownColor.HotPink); + + /// + /// Well-known color: IndianRed + /// + public static Color IndianRed => FromUInt32((uint)KnownColor.IndianRed); + + /// + /// Well-known color: Indigo + /// + public static Color Indigo => FromUInt32((uint)KnownColor.Indigo); + + /// + /// Well-known color: Ivory + /// + public static Color Ivory => FromUInt32((uint)KnownColor.Ivory); + + /// + /// Well-known color: Khaki + /// + public static Color Khaki => FromUInt32((uint)KnownColor.Khaki); + + /// + /// Well-known color: Lavender + /// + public static Color Lavender => FromUInt32((uint)KnownColor.Lavender); + + /// + /// Well-known color: LavenderBlush + /// + public static Color LavenderBlush => FromUInt32((uint)KnownColor.LavenderBlush); + + /// + /// Well-known color: LawnGreen + /// + public static Color LawnGreen => FromUInt32((uint)KnownColor.LawnGreen); + + /// + /// Well-known color: LemonChiffon + /// + public static Color LemonChiffon => FromUInt32((uint)KnownColor.LemonChiffon); + + /// + /// Well-known color: LightBlue + /// + public static Color LightBlue => FromUInt32((uint)KnownColor.LightBlue); + + /// + /// Well-known color: LightCoral + /// + public static Color LightCoral => FromUInt32((uint)KnownColor.LightCoral); + + /// + /// Well-known color: LightCyan + /// + public static Color LightCyan => FromUInt32((uint)KnownColor.LightCyan); + + /// + /// Well-known color: LightGoldenrodYellow + /// + public static Color LightGoldenrodYellow => FromUInt32((uint)KnownColor.LightGoldenrodYellow); + + /// + /// Well-known color: LightGray + /// + public static Color LightGray => FromUInt32((uint)KnownColor.LightGray); + + /// + /// Well-known color: LightGreen + /// + public static Color LightGreen => FromUInt32((uint)KnownColor.LightGreen); + + /// + /// Well-known color: LightPink + /// + public static Color LightPink => FromUInt32((uint)KnownColor.LightPink); + + /// + /// Well-known color: LightSalmon + /// + public static Color LightSalmon => FromUInt32((uint)KnownColor.LightSalmon); + + /// + /// Well-known color: LightSeaGreen + /// + public static Color LightSeaGreen => FromUInt32((uint)KnownColor.LightSeaGreen); + + /// + /// Well-known color: LightSkyBlue + /// + public static Color LightSkyBlue => FromUInt32((uint)KnownColor.LightSkyBlue); + + /// + /// Well-known color: LightSlateGray + /// + public static Color LightSlateGray => FromUInt32((uint)KnownColor.LightSlateGray); + + /// + /// Well-known color: LightSteelBlue + /// + public static Color LightSteelBlue => FromUInt32((uint)KnownColor.LightSteelBlue); + + /// + /// Well-known color: LightYellow + /// + public static Color LightYellow => FromUInt32((uint)KnownColor.LightYellow); + + /// + /// Well-known color: Lime + /// + public static Color Lime => FromUInt32((uint)KnownColor.Lime); + + /// + /// Well-known color: LimeGreen + /// + public static Color LimeGreen => FromUInt32((uint)KnownColor.LimeGreen); + + /// + /// Well-known color: Linen + /// + public static Color Linen => FromUInt32((uint)KnownColor.Linen); + + /// + /// Well-known color: Magenta + /// + public static Color Magenta => FromUInt32((uint)KnownColor.Magenta); + + /// + /// Well-known color: Maroon + /// + public static Color Maroon => FromUInt32((uint)KnownColor.Maroon); + + /// + /// Well-known color: MediumAquamarine + /// + public static Color MediumAquamarine => FromUInt32((uint)KnownColor.MediumAquamarine); + + /// + /// Well-known color: MediumBlue + /// + public static Color MediumBlue => FromUInt32((uint)KnownColor.MediumBlue); + + /// + /// Well-known color: MediumOrchid + /// + public static Color MediumOrchid => FromUInt32((uint)KnownColor.MediumOrchid); + + /// + /// Well-known color: MediumPurple + /// + public static Color MediumPurple => FromUInt32((uint)KnownColor.MediumPurple); + + /// + /// Well-known color: MediumSeaGreen + /// + public static Color MediumSeaGreen => FromUInt32((uint)KnownColor.MediumSeaGreen); + + /// + /// Well-known color: MediumSlateBlue + /// + public static Color MediumSlateBlue => FromUInt32((uint)KnownColor.MediumSlateBlue); + + /// + /// Well-known color: MediumSpringGreen + /// + public static Color MediumSpringGreen => FromUInt32((uint)KnownColor.MediumSpringGreen); + + /// + /// Well-known color: MediumTurquoise + /// + public static Color MediumTurquoise => FromUInt32((uint)KnownColor.MediumTurquoise); + + /// + /// Well-known color: MediumVioletRed + /// + public static Color MediumVioletRed => FromUInt32((uint)KnownColor.MediumVioletRed); + + /// + /// Well-known color: MidnightBlue + /// + public static Color MidnightBlue => FromUInt32((uint)KnownColor.MidnightBlue); + + /// + /// Well-known color: MintCream + /// + public static Color MintCream => FromUInt32((uint)KnownColor.MintCream); + + /// + /// Well-known color: MistyRose + /// + public static Color MistyRose => FromUInt32((uint)KnownColor.MistyRose); + + /// + /// Well-known color: Moccasin + /// + public static Color Moccasin => FromUInt32((uint)KnownColor.Moccasin); + + /// + /// Well-known color: NavajoWhite + /// + public static Color NavajoWhite => FromUInt32((uint)KnownColor.NavajoWhite); + + /// + /// Well-known color: Navy + /// + public static Color Navy => FromUInt32((uint)KnownColor.Navy); + + /// + /// Well-known color: OldLace + /// + public static Color OldLace => FromUInt32((uint)KnownColor.OldLace); + + /// + /// Well-known color: Olive + /// + public static Color Olive => FromUInt32((uint)KnownColor.Olive); + + /// + /// Well-known color: OliveDrab + /// + public static Color OliveDrab => FromUInt32((uint)KnownColor.OliveDrab); + + /// + /// Well-known color: Orange + /// + public static Color Orange => FromUInt32((uint)KnownColor.Orange); + + /// + /// Well-known color: OrangeRed + /// + public static Color OrangeRed => FromUInt32((uint)KnownColor.OrangeRed); + + /// + /// Well-known color: Orchid + /// + public static Color Orchid => FromUInt32((uint)KnownColor.Orchid); + + /// + /// Well-known color: PaleGoldenrod + /// + public static Color PaleGoldenrod => FromUInt32((uint)KnownColor.PaleGoldenrod); + + /// + /// Well-known color: PaleGreen + /// + public static Color PaleGreen => FromUInt32((uint)KnownColor.PaleGreen); + + /// + /// Well-known color: PaleTurquoise + /// + public static Color PaleTurquoise => FromUInt32((uint)KnownColor.PaleTurquoise); + + /// + /// Well-known color: PaleVioletRed + /// + public static Color PaleVioletRed => FromUInt32((uint)KnownColor.PaleVioletRed); + + /// + /// Well-known color: PapayaWhip + /// + public static Color PapayaWhip => FromUInt32((uint)KnownColor.PapayaWhip); + + /// + /// Well-known color: PeachPuff + /// + public static Color PeachPuff => FromUInt32((uint)KnownColor.PeachPuff); + + /// + /// Well-known color: Peru + /// + public static Color Peru => FromUInt32((uint)KnownColor.Peru); + + /// + /// Well-known color: Pink + /// + public static Color Pink => FromUInt32((uint)KnownColor.Pink); + + /// + /// Well-known color: Plum + /// + public static Color Plum => FromUInt32((uint)KnownColor.Plum); + + /// + /// Well-known color: PowderBlue + /// + public static Color PowderBlue => FromUInt32((uint)KnownColor.PowderBlue); + + /// + /// Well-known color: Purple + /// + public static Color Purple => FromUInt32((uint)KnownColor.Purple); + + /// + /// Well-known color: Red + /// + public static Color Red => FromUInt32((uint)KnownColor.Red); + + /// + /// Well-known color: RosyBrown + /// + public static Color RosyBrown => FromUInt32((uint)KnownColor.RosyBrown); + + /// + /// Well-known color: RoyalBlue + /// + public static Color RoyalBlue => FromUInt32((uint)KnownColor.RoyalBlue); + + /// + /// Well-known color: SaddleBrown + /// + public static Color SaddleBrown => FromUInt32((uint)KnownColor.SaddleBrown); + + /// + /// Well-known color: Salmon + /// + public static Color Salmon => FromUInt32((uint)KnownColor.Salmon); + + /// + /// Well-known color: SandyBrown + /// + public static Color SandyBrown => FromUInt32((uint)KnownColor.SandyBrown); + + /// + /// Well-known color: SeaGreen + /// + public static Color SeaGreen => FromUInt32((uint)KnownColor.SeaGreen); + + /// + /// Well-known color: SeaShell + /// + public static Color SeaShell => FromUInt32((uint)KnownColor.SeaShell); + + /// + /// Well-known color: Sienna + /// + public static Color Sienna => FromUInt32((uint)KnownColor.Sienna); + + /// + /// Well-known color: Silver + /// + public static Color Silver => FromUInt32((uint)KnownColor.Silver); + + /// + /// Well-known color: SkyBlue + /// + public static Color SkyBlue => FromUInt32((uint)KnownColor.SkyBlue); + + /// + /// Well-known color: SlateBlue + /// + public static Color SlateBlue => FromUInt32((uint)KnownColor.SlateBlue); + + /// + /// Well-known color: SlateGray + /// + public static Color SlateGray => FromUInt32((uint)KnownColor.SlateGray); + + /// + /// Well-known color: Snow + /// + public static Color Snow => FromUInt32((uint)KnownColor.Snow); + + /// + /// Well-known color: SpringGreen + /// + public static Color SpringGreen => FromUInt32((uint)KnownColor.SpringGreen); + + /// + /// Well-known color: SteelBlue + /// + public static Color SteelBlue => FromUInt32((uint)KnownColor.SteelBlue); + + /// + /// Well-known color: Tan + /// + public static Color Tan => FromUInt32((uint)KnownColor.Tan); + + /// + /// Well-known color: Teal + /// + public static Color Teal => FromUInt32((uint)KnownColor.Teal); + + /// + /// Well-known color: Thistle + /// + public static Color Thistle => FromUInt32((uint)KnownColor.Thistle); + + /// + /// Well-known color: Tomato + /// + public static Color Tomato => FromUInt32((uint)KnownColor.Tomato); + + /// + /// Well-known color: Transparent + /// + public static Color Transparent => FromUInt32((uint)KnownColor.Transparent); + + /// + /// Well-known color: Turquoise + /// + public static Color Turquoise => FromUInt32((uint)KnownColor.Turquoise); + + /// + /// Well-known color: Violet + /// + public static Color Violet => FromUInt32((uint)KnownColor.Violet); + + /// + /// Well-known color: Wheat + /// + public static Color Wheat => FromUInt32((uint)KnownColor.Wheat); + + /// + /// Well-known color: White + /// + public static Color White => FromUInt32((uint)KnownColor.White); + + /// + /// Well-known color: WhiteSmoke + /// + public static Color WhiteSmoke => FromUInt32((uint)KnownColor.WhiteSmoke); + + /// + /// Well-known color: Yellow + /// + public static Color Yellow => FromUInt32((uint)KnownColor.Yellow); + + /// + /// Well-known color: YellowGreen + /// + public static Color YellowGreen => FromUInt32((uint)KnownColor.YellowGreen); + + #endregion static Known Colors + } +} +#endif diff --git a/Wino.Mail/ImageLoader.cs b/Wino.Mail/ImageLoader.cs new file mode 100644 index 00000000..8a29cae8 --- /dev/null +++ b/Wino.Mail/ImageLoader.cs @@ -0,0 +1,479 @@ +using System; +using System.Diagnostics; +using System.Numerics; +using System.Threading.Tasks; +using Microsoft.Graphics.Canvas; +using Microsoft.Graphics.Canvas.Text; +using Microsoft.Graphics.Canvas.UI.Composition; +using Windows.Foundation; +using Windows.Graphics.DirectX; +using Windows.Graphics.Imaging; +using Windows.Storage; +using Windows.Storage.Streams; +using Windows.UI; +using Windows.UI.Composition; + +public class DeviceReplacedEventArgs : EventArgs +{ + internal DeviceReplacedEventArgs(CompositionGraphicsDevice device, Object drawingLock) + { + GraphicsDevce = device; + DrawingLock = drawingLock; + } + + public CompositionGraphicsDevice GraphicsDevce { get; set; } + public Object DrawingLock { get; set; } +} + +public interface IContentDrawer +{ + Task Draw(CompositionGraphicsDevice device, Object drawingLock, CompositionDrawingSurface surface, Size size); +} + +public delegate void LoadTimeEffectHandler(CompositionDrawingSurface surface, CanvasBitmap bitmap, CompositionGraphicsDevice device); + +public class ManagedSurface +{ + private CompositionDrawingSurface _surface; + private IContentDrawer _drawer; + private CompositionSurfaceBrush _brush; + + public ManagedSurface(CompositionDrawingSurface surface) + { + Debug.Assert(surface != null); + _surface = surface; + + ImageLoader.Instance.RegisterSurface(this); + } + + public void Dispose() + { + if (_surface != null) + { + _surface.Dispose(); + _surface = null; + } + + if (_brush != null) + { + _brush.Dispose(); + _brush = null; + } + + _drawer = null; + + ImageLoader.Instance.UnregisterSurface(this); + } + + public CompositionDrawingSurface Surface + { + get { return _surface; } + } + + public CompositionSurfaceBrush Brush + { + get + { + if (_brush == null) + { + _brush = _surface.Compositor.CreateSurfaceBrush(_surface); + } + + return _brush; + } + } + + public Size Size + { + get + { + return (_surface != null) ? _surface.Size : Size.Empty; + } + } + + public async Task Draw(CompositionGraphicsDevice device, Object drawingLock, IContentDrawer drawer) + { + Debug.Assert(_surface != null); + + _drawer = drawer; + await _drawer.Draw(device, drawingLock, _surface, _surface.Size); + } + + public async void OnDeviceReplaced(object sender, object e) + { + DeviceReplacedEventArgs args = (DeviceReplacedEventArgs)e; + await ReloadContent(args.GraphicsDevce, args.DrawingLock); + } + + private async Task ReloadContent(CompositionGraphicsDevice device, Object drawingLock) + { + await _drawer.Draw(device, drawingLock, _surface, _surface.Size); + } +} + +public class BitmapDrawer : IContentDrawer +{ + readonly Uri _uri; + LoadTimeEffectHandler _handler; + StorageFile _file; + + public BitmapDrawer(Uri uri, LoadTimeEffectHandler handler) + { + _uri = uri; + _handler = handler; + } + + public BitmapDrawer(StorageFile file, LoadTimeEffectHandler handler) + { + _file = file; + _handler = handler; + } + + public Uri Uri + { + get { return _uri; } + } + + + private async Task LoadFromFile(StorageFile file) + { + SoftwareBitmap softwareBitmap; + + using (IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.Read)) + { + BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream); + + softwareBitmap = await decoder.GetSoftwareBitmapAsync(BitmapPixelFormat.Rgba8, BitmapAlphaMode.Premultiplied); + } + + return softwareBitmap; + } + + public async Task Draw(CompositionGraphicsDevice device, Object drawingLock, CompositionDrawingSurface surface, Size size) + { + var canvasDevice = CanvasComposition.GetCanvasDevice(device); + + CanvasBitmap canvasBitmap; + if (_file != null) + { + SoftwareBitmap softwareBitmap = await LoadFromFile(_file); + + canvasBitmap = CanvasBitmap.CreateFromSoftwareBitmap(canvasDevice, softwareBitmap); + } + else + { + canvasBitmap = await CanvasBitmap.LoadAsync(canvasDevice, _uri); + } + + var bitmapSize = canvasBitmap.Size; + + // + // Because the drawing is done asynchronously and multiple threads could + // be trying to get access to the device/surface at the same time, we need + // to do any device/surface work under a lock. + // + lock (drawingLock) + { + Size surfaceSize = size; + if (surface.Size != size || surface.Size == new Size(0, 0)) + { + // Resize the surface to the size of the image + CanvasComposition.Resize(surface, bitmapSize); + surfaceSize = bitmapSize; + } + + // Allow the app to process the bitmap if requested + if (_handler != null) + { + _handler(surface, canvasBitmap, device); + } + else + { + // Draw the image to the surface + + using (var session = CanvasComposition.CreateDrawingSession(surface)) + { + session.Clear(Windows.UI.Color.FromArgb(0, 0, 0, 0)); + session.DrawImage(canvasBitmap, new Rect(0, 0, surfaceSize.Width, surfaceSize.Height), new Rect(0, 0, bitmapSize.Width, bitmapSize.Height)); + } + } + } + } +} + +class CircleDrawer : IContentDrawer +{ + private float _radius; + private Color _color; + + public CircleDrawer(float radius, Color color) + { + _radius = radius; + _color = color; + } + + public float Radius + { + get { return _radius; } + } + + public Color Color + { + get { return _color; } + } + +#pragma warning disable 1998 + public async Task Draw(CompositionGraphicsDevice device, Object drawingLock, CompositionDrawingSurface surface, Size size) + { + using (var ds = CanvasComposition.CreateDrawingSession(surface)) + { + ds.Clear(Colors.Transparent); + ds.FillCircle(new Vector2(_radius, _radius), _radius, _color); + } + } +} +class TextDrawer : IContentDrawer +{ + private string _text; + private CanvasTextFormat _textFormat; + private Color _textColor; + private Color _backgroundColor; + + public TextDrawer(string text, CanvasTextFormat textFormat, Color textColor, Color bgColor) + { + _text = text; + _textFormat = textFormat; + _textColor = textColor; + _backgroundColor = bgColor; + } + +#pragma warning disable 1998 + public async Task Draw(CompositionGraphicsDevice device, Object drawingLock, CompositionDrawingSurface surface, Size size) + { + using (var ds = CanvasComposition.CreateDrawingSession(surface)) + { + ds.Clear(_backgroundColor); + ds.DrawText(_text, new Rect(0, 0, surface.Size.Width, surface.Size.Height), _textColor, _textFormat); + } + } +} + +public class ImageLoader +{ + private static bool _intialized; + private static ImageLoader _imageLoader; + +#if SampleNative_TODO + private DeviceLostHelper _deviceLostHelper; +#endif + + private Compositor _compositor; + private CanvasDevice _canvasDevice; + private CompositionGraphicsDevice _graphicsDevice; + private Object _drawingLock; + private event EventHandler _deviceReplacedEvent; + + public ImageLoader(Compositor compositor) + { + Debug.Assert(compositor != null && _compositor == null); + + _compositor = compositor; + _drawingLock = new object(); + +#if SampleNative_TODO + _deviceLostHelper = new DeviceLostHelper(); +#endif + + _canvasDevice = new CanvasDevice(); +#if !USING_CSWINRT // TODO: Define IDirect3DDevice for Win32 + _canvasDevice.DeviceLost += DeviceLost; +#endif + +#if SampleNative_TODO + _deviceLostHelper.WatchDevice(_canvasDevice); + _deviceLostHelper.DeviceLost += DeviceRemoved; +#endif + + _graphicsDevice = (CompositionGraphicsDevice)CanvasComposition.CreateCompositionGraphicsDevice(_compositor, _canvasDevice); + _graphicsDevice.RenderingDeviceReplaced += RenderingDeviceReplaced; + } + + public void Dispose() + { + lock (_drawingLock) + { + _compositor = null; + + if (_canvasDevice != null) + { +#if !USING_CSWINRT // TODO: Define IDirect3DDevice for Win32 + _canvasDevice.DeviceLost -= DeviceLost; + _canvasDevice.Dispose(); +#endif + _canvasDevice = null; + } + + if (_graphicsDevice != null) + { + _graphicsDevice.RenderingDeviceReplaced -= RenderingDeviceReplaced; + _graphicsDevice.Dispose(); + _graphicsDevice = null; + } + } + } + + static public void Initialize(Compositor compositor) + { + Debug.Assert(!_intialized); + + if (!_intialized) + { + _imageLoader = new ImageLoader(compositor); + _intialized = true; + } + } + + static public ImageLoader Instance + { + get + { + Debug.Assert(_intialized); + return _imageLoader; + } + } + + public void RegisterSurface(ManagedSurface surface) + { + _deviceReplacedEvent += surface.OnDeviceReplaced; + } + + public void UnregisterSurface(ManagedSurface surface) + { + _deviceReplacedEvent -= surface.OnDeviceReplaced; + } + + + private void RaiseDeviceReplacedEvent() + { + _deviceReplacedEvent?.Invoke(this, new DeviceReplacedEventArgs(_graphicsDevice, _drawingLock)); + } + + public ManagedSurface LoadFromUri(Uri uri) + { + return LoadFromUri(uri, Size.Empty); + } + + public ManagedSurface LoadFromUri(Uri uri, Size size) + { + return LoadFromUri(uri, size, null); + } + + public ManagedSurface LoadFromUri(Uri uri, Size size, LoadTimeEffectHandler handler) + { + ManagedSurface surface = new ManagedSurface(CreateSurface(size)); + var ignored = surface.Draw(_graphicsDevice, _drawingLock, new BitmapDrawer(uri, handler)); + + return surface; + } + + public ManagedSurface LoadFromFile(StorageFile file, Size size, LoadTimeEffectHandler handler) + { + ManagedSurface surface = new ManagedSurface(CreateSurface(size)); + + var ignored = surface.Draw(_graphicsDevice, _drawingLock, new BitmapDrawer(file, handler)); + + return surface; + } + + public IAsyncOperation LoadFromUriAsync(Uri uri) + { + return LoadFromUriAsyncWorker(uri, Size.Empty, null).AsAsyncOperation(); + } + + public IAsyncOperation LoadFromUriAsync(Uri uri, Size size) + { + return LoadFromUriAsyncWorker(uri, size, null).AsAsyncOperation(); + } + + public IAsyncOperation LoadFromUriAsync(Uri uri, Size size, LoadTimeEffectHandler handler) + { + return LoadFromUriAsyncWorker(uri, size, handler).AsAsyncOperation(); + } + + public ManagedSurface LoadCircle(float radius, Color color) + { + ManagedSurface surface = new ManagedSurface(CreateSurface(new Size(radius * 2, radius * 2))); + var ignored = surface.Draw(_graphicsDevice, _drawingLock, new CircleDrawer(radius, color)); + + return surface; + } + + public ManagedSurface LoadText(string text, Size size, CanvasTextFormat textFormat, Color textColor, Color bgColor) + { + ManagedSurface surface = new ManagedSurface(CreateSurface(size)); + var ignored = surface.Draw(_graphicsDevice, _drawingLock, new TextDrawer(text, textFormat, textColor, bgColor)); + + return surface; + } + + private async Task LoadFromUriAsyncWorker(Uri uri, Size size, LoadTimeEffectHandler handler) + { + ManagedSurface surface = new ManagedSurface(CreateSurface(size)); + await surface.Draw(_graphicsDevice, _drawingLock, new BitmapDrawer(uri, handler)); + + return surface; + } + + private CompositionDrawingSurface CreateSurface(Size size) + { + Size surfaceSize = size; + if (surfaceSize.IsEmpty) + { + // + // We start out with a size of 0,0 for the surface, because we don't know + // the size of the image at this time. We resize the surface later. + // + surfaceSize = default(Size); + } + + var surface = _graphicsDevice.CreateDrawingSurface(surfaceSize, DirectXPixelFormat.B8G8R8A8UIntNormalized, DirectXAlphaMode.Premultiplied); + + return surface; + } + +#if SampleNative_TODO + private void DeviceRemoved(DeviceLostHelper sender, object args) + { + _canvasDevice.RaiseDeviceLost(); + } +#endif + + private void DeviceLost(CanvasDevice sender, object args) + { +#if !USING_CSWINRT // TODO: Define IDirect3DDevice for Win32 + sender.DeviceLost -= DeviceLost; +#endif + + _canvasDevice = new CanvasDevice(); +#if !USING_CSWINRT // TODO: Define IDirect3DDevice for Win32 + _canvasDevice.DeviceLost += DeviceLost; +#endif + +#if SampleNative_TODO + _deviceLostHelper.WatchDevice(_canvasDevice); +#endif + + CanvasComposition.SetCanvasDevice(_graphicsDevice, _canvasDevice); + } + + private void RenderingDeviceReplaced(CompositionGraphicsDevice sender, RenderingDeviceReplacedEventArgs args) + { + Task.Run(() => + { + if (_deviceReplacedEvent != null) + { + RaiseDeviceReplacedEvent(); + } + }); + } +} diff --git a/Wino.Mail/JS/Quill/darkreader.js b/Wino.Mail/JS/Quill/darkreader.js index 6e45c600..2d4fe903 100644 --- a/Wino.Mail/JS/Quill/darkreader.js +++ b/Wino.Mail/JS/Quill/darkreader.js @@ -891,7 +891,8 @@ ActiveBorder: 0x3b99fc, ActiveCaption: 0x000000, AppWorkspace: 0xaaaaaa, - Background: 0x6363ce, + /*Background: 0x6363ce,*/ + Background: 0x000000, ButtonFace: 0xffffff, ButtonHighlight: 0xe9e9e9, ButtonShadow: 0x9fa09f, @@ -1437,11 +1438,11 @@ var lines = []; if (!isIFrame) { lines.push('html {'); - lines.push(" background-color: " + modifyBackgroundColor({ r: 255, g: 255, b: 255 }, filter) + " !important;"); + lines.push(" background-color: " + modifyBackgroundColor({ r: 10, g: 255, b: 255, a: 0 }, filter) + " !important;"); lines.push('}'); } lines.push((isIFrame ? '' : 'html, body, ') + "input, textarea, select, button {"); - lines.push(" background-color: " + modifyBackgroundColor({ r: 255, g: 255, b: 255 }, filter) + ";"); + lines.push(" background-color: " + modifyBackgroundColor({ r: 10, g: 255, b: 255, a: 0 }, filter) + ";"); lines.push('}'); lines.push('html, body, input, textarea, select, button {'); lines.push(" border-color: " + modifyBorderColor({ r: 76, g: 76, b: 76 }, filter) + ";"); @@ -2809,7 +2810,7 @@ var userAgentStyle = createOrUpdateStyle('darkreader--user-agent'); document.head.insertBefore(userAgentStyle, fallbackStyle.nextSibling); userAgentStyle.textContent = getModifiedUserAgentStyle(filter, isIFrame); - setupStylePositionWatcher(userAgentStyle, 'user-agent'); + //setupStylePositionWatcher(userAgentStyle, 'user-agent'); var textStyle = createOrUpdateStyle('darkreader--text'); document.head.insertBefore(textStyle, fallbackStyle.nextSibling); if (filter.useFont || filter.textStroke > 0) { diff --git a/Wino.Mail/Package.appxmanifest b/Wino.Mail/Package.appxmanifest index 2ac01f3f..7628292e 100644 --- a/Wino.Mail/Package.appxmanifest +++ b/Wino.Mail/Package.appxmanifest @@ -19,15 +19,16 @@ - + Name="49014Shompinice.50918299FB257" + Publisher="CN=8136FD48-8D5A-4FB2-8DF9-A606C867768F" + Version="1.7.0.0" /> + + - Wino Mail - Burak KÖSE + Mail Universal + Shompinice Assets\StoreLogo.png @@ -44,7 +45,7 @@ Executable="$targetnametoken$.exe" EntryPoint="Wino.App"> + + + + \ No newline at end of file diff --git a/Wino.Mail/Views/ComposePage.xaml b/Wino.Mail/Views/ComposePage.xaml index f965662a..c2ec4aa3 100644 --- a/Wino.Mail/Views/ComposePage.xaml +++ b/Wino.Mail/Views/ComposePage.xaml @@ -118,7 +118,7 @@ - + @@ -179,123 +179,145 @@ - + - - - + + + + + - - + - - - - + + - - - - - - - + + + + + + - - - - - - - + + + + + + - - - - - - + + + + + + - + - - - - - - - - - + + + + + + + - - - - - - + + + + + + - + + + + + + - + + + + + + - + - - - - - - - + + + + + + + + + x:Name="AlignmentListView" + Width="120" + Height="32" + VerticalAlignment="Center" + SelectionChanged="AlignmentChanged"> @@ -333,6 +355,8 @@ + + @@ -515,6 +539,7 @@ - + + + + + + + + + + + + + + + + + + + + + + diff --git a/Wino.Mail/Views/MailListPage.xaml b/Wino.Mail/Views/MailListPage.xaml index 1cad33f7..52440fad 100644 --- a/Wino.Mail/Views/MailListPage.xaml +++ b/Wino.Mail/Views/MailListPage.xaml @@ -20,6 +20,7 @@ xmlns:ui="using:Microsoft.Toolkit.Uwp.UI" xmlns:wino="using:Wino" xmlns:viewModelData="using:Wino.Mail.ViewModels.Data" + xmlns:views="using:Wino.Views" x:Name="root" Loaded="MailListPageLoaded" mc:Ignorable="d"> @@ -62,7 +63,7 @@ + @@ -409,6 +410,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -793,8 +639,185 @@ Message="{x:Bind ViewModel.BarMessage, Mode=OneWay}" Severity="{x:Bind helpers:XamlHelpers.InfoBarSeverityConverter(ViewModel.BarSeverity), Mode=OneWay}" /> + + + + + + + + + + #ffffff + + + #272727 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Archive + + + + + + + + + UnArchive + + + + + + SoftDelete + + + + + + + Move + + + + + + + + + + + + + SetFlag + + + + + + + + ClearFlag + + + + + + + + MarkAsRead + + + + + + + + MarkAsUnread + + + + + + + + + + + + + + + CompositionBrush; } + } + public sealed partial class MailListPage : MailListPageAbstract, IRecipient, IRecipient, @@ -534,12 +544,53 @@ private void PullToRefreshRequested(Microsoft.UI.Xaml.Controls.RefreshContainer ViewModel.SyncFolderCommand?.Execute(null); } - private async void SearchBar_TextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs args) + + private void BlurLayer_Loaded(object sender, RoutedEventArgs e) { - if(args.Reason == AutoSuggestionBoxTextChangeReason.UserInput && string.IsNullOrWhiteSpace(sender.Text)) + var hostElement = sender as UIElement; + var compositor = ElementCompositionPreview.GetElementVisual(hostElement).Compositor; + var spriteVisual = compositor.CreateSpriteVisual(); + spriteVisual.Size = hostElement.ActualSize; + + var blurEffect = new GaussianBlurEffect() { - await ViewModel.PerformSearchAsync(); - } + BlurAmount = 10, + Source = new CompositionEffectSourceParameter("blur") + }; + var brush = compositor.CreateEffectFactory(blurEffect).CreateBrush(); + brush.SetSourceParameter("blur", compositor.CreateBackdropBrush()); + spriteVisual.Brush = brush; + ElementCompositionPreview.SetElementChildVisual(hostElement, spriteVisual); + } + + ManagedSurface surface; + private CompositionSurfaceBrush createGradientSurface(Compositor compositor, Size size) + { + ImageLoader.Initialize(compositor); + surface = ImageLoader.Instance.LoadFromUri(new Uri("ms-appx:///Assets/Rectangle17.png"), size); + return surface.Brush; + } + + private void MicaLayer_Loaded(object sender, RoutedEventArgs e) + { + + var hostElement = sender as UIElement; + var compositor = ElementCompositionPreview.GetElementVisual(hostElement).Compositor; + var spriteVisual = compositor.CreateSpriteVisual(); + spriteVisual.Size = hostElement.ActualSize; + + var maskEffect = new AlphaMaskEffect() + { + AlphaMask = new CompositionEffectSourceParameter("mask"), + Source = new CompositionEffectSourceParameter("source") + }; + var maskEffectBrush = compositor.CreateEffectFactory(maskEffect).CreateBrush(); + maskEffectBrush.SetSourceParameter("mask", createGradientSurface(compositor, new Size(spriteVisual.Size.X, spriteVisual.Size.Y))); + maskEffectBrush.SetSourceParameter("source", MyMicaBrush.Brush); + + spriteVisual.Brush = maskEffectBrush; + ElementCompositionPreview.SetElementChildVisual(hostElement, spriteVisual); + } } } diff --git a/Wino.Mail/Views/MailRenderingPage.xaml b/Wino.Mail/Views/MailRenderingPage.xaml index b91faf81..d86e861c 100644 --- a/Wino.Mail/Views/MailRenderingPage.xaml +++ b/Wino.Mail/Views/MailRenderingPage.xaml @@ -356,12 +356,13 @@ CornerRadius="3" Padding="0"> - + + Background="Transparent" + FontFamily="Segoe UI"/> ExecuteScriptFunctionAsync(string functionName, params return await Chromium.ExecuteScriptAsync(script); } - private async Task RenderInternalAsync(string htmlBody) + string _htmlContent = ""; + + private async Task RenderInternalAsync(string? htmlBody = null) { isRenderingInProgress = true; await DOMLoadedTask.Task; - await UpdateEditorThemeAsync(); - await UpdateReaderFontPropertiesAsync(); + //await UpdateEditorThemeAsync(); + //await UpdateReaderFontPropertiesAsync(); - if (string.IsNullOrEmpty(htmlBody)) - { - await ExecuteScriptFunctionAsync("RenderHTML", " "); - } - else + if (htmlBody != null) { - await ExecuteScriptFunctionAsync("RenderHTML", htmlBody); + _htmlContent = htmlBody; } + Chromium.NavigateToString(ConvertContentTheme("" + htmlBody + "", ViewModel.IsDarkWebviewRenderer)); + + //if (string.IsNullOrEmpty(htmlBody)) + //{ + // await ExecuteScriptFunctionAsync("RenderHTML", " "); + //} + //else + //{ + // await ExecuteScriptFunctionAsync("RenderHTML", ConvertContentTheme("" + htmlBody + "", ViewModel.IsDarkWebviewRenderer)); + //} + isRenderingInProgress = false; } @@ -134,6 +156,102 @@ protected override void OnNavigatedFrom(NavigationEventArgs e) base.OnNavigatedFrom(e); } + private string ConvertContentTheme(string original, bool isDarkMode, bool rawText = false) + { + if (isDarkMode) + { + if (rawText) + { + return original; + } + else + { + const string darkCss = + ""; + const string regexPattern = + """(bgcolor|background|color|background-color)\s*(\:|\=\")\s*(\S*)([\;\"])"""; + + var matches = Regex.Matches(original, regexPattern); + foreach (Match match in matches) + { + try + { + Color originalColor; + if (match.Groups[3].Value.StartsWith("rgba")) + { + var rgbaStr = match.Groups[3].Value.Substring(5).TrimEnd(')'); + var rgbaArr = rgbaStr.Split(','); + originalColor = Color.FromArgb((byte)(double.Parse(rgbaArr[3]) * 255), + Byte.Parse(rgbaArr[0]), + Byte.Parse(rgbaArr[1]), Byte.Parse(rgbaArr[2])); + } + else if (match.Groups[3].Value.StartsWith("rgb")) + { + var rgbStr = match.Groups[3].Value.Substring(4).TrimEnd(')'); + var rgbArr = rgbStr.Split(','); + originalColor = Color.FromArgb(255, Byte.Parse(rgbArr[0]), + Byte.Parse(rgbArr[1]), Byte.Parse(rgbArr[2])); + } + else + { + originalColor = ColorExtensions.ParseColor(match.Groups[3].Value, null); + } + + + var hslColor = originalColor.ToHsl(); + + // 合理调整此处区间以便正常拉取色调 + if (hslColor.L >= 0.70) + { + hslColor.L = 1 - hslColor.L; + } + else if (hslColor.L <= 0.30) + { + hslColor.L = 1 - hslColor.L; + } + + var color = Microsoft.Toolkit.Uwp.Helpers.ColorHelper.FromHsl( + hslColor.H, hslColor.S, hslColor.L, hslColor.A); + + if (match.Groups[1].Value.StartsWith('b') && hslColor.L is > 0.90 or < 0.10) + { + original = original.Replace(match.Value, + match.Groups[1].Value + match.Groups[2].Value + "transparent" + + match.Groups[4].Value); + continue; + } + + original = original.Replace(match.Value, + match.Groups[1].Value + match.Groups[2].Value + $"#{color.R:X2}{color.G:X2}{color.B:X2}" + + match.Groups[4].Value); + } + catch + { + //ignore + } + } + + + if (original.Contains("")) + { + original = original.Insert(original.IndexOf("", StringComparison.Ordinal) + 6, darkCss); + } + + if (original.Contains("")) + { + original = original.Insert(original.IndexOf("", StringComparison.Ordinal) + 6, darkCss); + } + } + + // 处理表格 + original = Regex.Replace(original, @"border(-left|-right|-top|-bottom)*:(\S*)\s*windowtext", + "border$1:$2 white"); + } + + return original; + } + + protected override void OnNavigatedTo(NavigationEventArgs e) { base.OnNavigatedTo(e); @@ -229,17 +347,23 @@ private async Task UpdateEditorThemeAsync() { await DOMLoadedTask.Task; + await InvokeScriptSafeAsync("ChangePrefferedTheme('light')"); + await InvokeScriptSafeAsync("DarkReader.disable();"); + if (ViewModel.IsDarkWebviewRenderer) { - Chromium.CoreWebView2.Profile.PreferredColorScheme = CoreWebView2PreferredColorScheme.Dark; + //Chromium.CoreWebView2.Profile.PreferredColorScheme = CoreWebView2PreferredColorScheme.Dark; - await InvokeScriptSafeAsync("SetDarkEditor();"); + //await InvokeScriptSafeAsync("ChangePrefferedTheme('dark')"); + //await InvokeScriptSafeAsync("DarkReader.enable();"); } else { - Chromium.CoreWebView2.Profile.PreferredColorScheme = CoreWebView2PreferredColorScheme.Light; + //Chromium.CoreWebView2.Profile.PreferredColorScheme = CoreWebView2PreferredColorScheme.Light; + await InvokeScriptSafeAsync("SetLightEditor();"); + } } diff --git a/Wino.Mail/Wino.Mail.csproj b/Wino.Mail/Wino.Mail.csproj index 8796dfd4..1ede54cd 100644 --- a/Wino.Mail/Wino.Mail.csproj +++ b/Wino.Mail/Wino.Mail.csproj @@ -2,7 +2,7 @@ - 8.0 + 11.0 @@ -181,6 +181,9 @@ 1.2.0 + + 0.1.10 + 5.0.4 @@ -280,9 +283,11 @@ TextInputDialog.xaml + + @@ -539,6 +544,10 @@ Designer MSBuild:Compile + + MSBuild:Compile + Designer + Designer MSBuild:Compile @@ -701,6 +710,9 @@ + + Always +