From f2744e2d45331ee10d8a3bf639cd07f8acff3898 Mon Sep 17 00:00:00 2001 From: Johnny Westlake Date: Tue, 30 Apr 2024 17:32:38 +0100 Subject: [PATCH 01/15] Minor refactoring --- CharacterMap/CharacterMap/CharacterMap.csproj | 1 + .../Controls/CreateCollectionDialog.xaml.cs | 2 +- .../CharacterMap/Helpers/FlyoutHelper.cs | 12 ++--- .../Models/AddToCollectionResult.cs | 4 +- CharacterMap/CharacterMap/Models/Messages.cs | 48 ++----------------- CharacterMap/CharacterMap/Models/Records.cs | 3 ++ .../Services/UserCollectionsService.cs | 4 +- 7 files changed, 20 insertions(+), 54 deletions(-) create mode 100644 CharacterMap/CharacterMap/Models/Records.cs diff --git a/CharacterMap/CharacterMap/CharacterMap.csproj b/CharacterMap/CharacterMap/CharacterMap.csproj index 482c8868..19d76ae6 100644 --- a/CharacterMap/CharacterMap/CharacterMap.csproj +++ b/CharacterMap/CharacterMap/CharacterMap.csproj @@ -249,6 +249,7 @@ + diff --git a/CharacterMap/CharacterMap/Controls/CreateCollectionDialog.xaml.cs b/CharacterMap/CharacterMap/Controls/CreateCollectionDialog.xaml.cs index 855758e8..a2216482 100644 --- a/CharacterMap/CharacterMap/Controls/CreateCollectionDialog.xaml.cs +++ b/CharacterMap/CharacterMap/Controls/CreateCollectionDialog.xaml.cs @@ -76,7 +76,7 @@ private async void ContentDialog_PrimaryButtonClick(ContentDialog sender, Conten if (this.DataContext is InstalledFont font) result = await collections.AddToCollectionAsync(font, collection); - else if (this.DataContext is IList fonts) + else if (this.DataContext is IReadOnlyList fonts) result = await collections.AddToCollectionAsync(fonts, collection); else if (this.DataContext is null) result = new AddToCollectionResult(true, null, collection); diff --git a/CharacterMap/CharacterMap/Helpers/FlyoutHelper.cs b/CharacterMap/CharacterMap/Helpers/FlyoutHelper.cs index cd86bb12..da813f4a 100644 --- a/CharacterMap/CharacterMap/Helpers/FlyoutHelper.cs +++ b/CharacterMap/CharacterMap/Helpers/FlyoutHelper.cs @@ -354,7 +354,7 @@ async void RemoveFrom_Click(object sender, RoutedEventArgs e) await _collections.RemoveFromCollectionAsync(fnt, collection); WeakReferenceMessenger.Default.Send( new AppNotificationMessage(true, - new CollectionUpdatedArgs(new List { fnt }, collection, false))); + new CollectionUpdatedArgs([fnt], collection, false))); WeakReferenceMessenger.Default.Send(new CollectionsUpdatedMessage { SourceCollection = collection }); } } @@ -368,13 +368,13 @@ async void RemoveFrom_Click(object sender, RoutedEventArgs e) /// /// /// - public static MenuFlyoutSubItem AddCollectionItems(MenuFlyout menu, InstalledFont font, IList fonts, string key = null, FlyoutArgs args = null) + public static MenuFlyoutSubItem AddCollectionItems(MenuFlyout menu, InstalledFont font, IReadOnlyList fonts, string key = null, FlyoutArgs args = null) { #region Event Handlers static async void AddToSymbolFonts_Click(object sender, RoutedEventArgs e) { - if (sender is FrameworkElement f && f.DataContext is IList fnts) + if (sender is FrameworkElement f && f.DataContext is IReadOnlyList fnts) { var result = await _collections.AddToCollectionAsync( fnts, @@ -391,7 +391,7 @@ static async void AddToSymbolFonts_Click(object sender, RoutedEventArgs e) static void CreateCollection_Click(object sender, RoutedEventArgs e) { - var d = new CreateCollectionDialog + CreateCollectionDialog d = new () { DataContext = (sender as FrameworkElement)?.DataContext }; @@ -402,7 +402,7 @@ static void CreateCollection_Click(object sender, RoutedEventArgs e) #endregion bool multiMode = font is null && fonts is not null; - IList items = fonts ?? new List { font }; + IReadOnlyList items = fonts ?? [font]; Style style = ResourceHelper.Get - - @@ -695,6 +623,8 @@ Padding="{TemplateBinding Padding}" AutomationProperties.AccessibilityView="Raw" CornerRadius="{TemplateBinding CornerRadius}" + FontStretch="{TemplateBinding FontStretch}" + FontStyle="{TemplateBinding FontStyle}" HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}" HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}" IsDeferredScrollingEnabled="{TemplateBinding ScrollViewer.IsDeferredScrollingEnabled}" diff --git a/CharacterMap/CharacterMap/Themes/FluentThemeStyles.xaml b/CharacterMap/CharacterMap/Themes/FluentThemeStyles.xaml index 03d310c9..f2a45508 100644 --- a/CharacterMap/CharacterMap/Themes/FluentThemeStyles.xaml +++ b/CharacterMap/CharacterMap/Themes/FluentThemeStyles.xaml @@ -2181,6 +2181,7 @@ x:Name="SuggestionsList" MaxHeight="{TemplateBinding MaxSuggestionListHeight}" Margin="{ThemeResource AutoSuggestListPadding}" + core:Properties.ToolTipMemberPath="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=(core:Properties.ToolTipMemberPath)}" DisplayMemberPath="{TemplateBinding DisplayMemberPath}" Footer="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=(core:Properties.Footer)}" IsItemClickEnabled="True" diff --git a/CharacterMap/CharacterMap/Views/FontMapView.xaml b/CharacterMap/CharacterMap/Views/FontMapView.xaml index 253abcac..b640f42d 100644 --- a/CharacterMap/CharacterMap/Views/FontMapView.xaml +++ b/CharacterMap/CharacterMap/Views/FontMapView.xaml @@ -576,6 +576,11 @@ Width="290" Margin="6 0 6 0" VerticalAlignment="Center" + core:Properties.FontFamily="{x:Bind ViewModel.FontFamily, Mode=OneWay}" + core:Properties.FontStretch="{x:Bind ViewModel.SelectedVariant.FontFace.Stretch, Mode=OneWay}" + core:Properties.FontStyle="{x:Bind ViewModel.SelectedVariant.FontFace.Style, Mode=OneWay}" + core:Properties.FontWeight="{x:Bind ViewModel.SelectedVariant.FontFace.Weight, Mode=OneWay}" + core:Properties.ToolTipMemberPath="Description" GotFocus="SearchBox_GotFocus" ItemTemplate="{StaticResource SearchResultTemplate}" ItemsSource="{Binding Source={StaticResource SearchResultsSource}}" From 35c30cf76751460567b6aab3a905c92be2700ae0 Mon Sep 17 00:00:00 2001 From: Johnny Westlake Date: Sat, 18 May 2024 23:50:02 +0100 Subject: [PATCH 08/15] Smart collections UI work --- .../Readers/DependencyPropertyReader.cs | 3 + .../Controls/CreateCollectionDialog.xaml | 7 +- .../Controls/CreateCollectionDialog.xaml.cs | 16 +- CharacterMap/CharacterMap/Core/AppSettings.cs | 2 +- .../CharacterMap/Core/InstalledFont.cs | 2 +- .../Helpers/CompositionFactory.cs | 4 +- .../CharacterMap/Helpers/FlyoutHelper.cs | 9 +- .../Themes/ClassicThemeStyles.xaml | 161 +++++++++++++++++- .../Themes/DefaultThemeStyles.xaml | 161 +++++++++++++++++- .../Themes/FluentThemeStyles.xaml | 1 + .../CharacterMap/Themes/ZuneThemeStyles.xaml | 158 +++++++++++++++++ .../ViewModels/SettingsViewModel.cs | 1 + .../Views/CollectionManagementView.xaml.cs | 1 + 13 files changed, 509 insertions(+), 17 deletions(-) diff --git a/CharacterMap/CharacterMap.Generators/Readers/DependencyPropertyReader.cs b/CharacterMap/CharacterMap.Generators/Readers/DependencyPropertyReader.cs index caf5f54d..ef2625c9 100644 --- a/CharacterMap/CharacterMap.Generators/Readers/DependencyPropertyReader.cs +++ b/CharacterMap/CharacterMap.Generators/Readers/DependencyPropertyReader.cs @@ -147,6 +147,9 @@ public override void Write(GeneratorExecutionContext context) string target = group.First().ParentClass; List usings = group.First().Usings; + if (usings.Contains("using Windows.UI.Xaml;") is false) + usings.Add("using Windows.UI.Xaml;"); + StringBuilder sb = new(); foreach (DPData dp in group) diff --git a/CharacterMap/CharacterMap/Controls/CreateCollectionDialog.xaml b/CharacterMap/CharacterMap/Controls/CreateCollectionDialog.xaml index 03c5c600..96d8a8d8 100644 --- a/CharacterMap/CharacterMap/Controls/CreateCollectionDialog.xaml +++ b/CharacterMap/CharacterMap/Controls/CreateCollectionDialog.xaml @@ -23,15 +23,16 @@ diff --git a/CharacterMap/CharacterMap/Controls/CreateCollectionDialog.xaml.cs b/CharacterMap/CharacterMap/Controls/CreateCollectionDialog.xaml.cs index 77da15c5..b02f8409 100644 --- a/CharacterMap/CharacterMap/Controls/CreateCollectionDialog.xaml.cs +++ b/CharacterMap/CharacterMap/Controls/CreateCollectionDialog.xaml.cs @@ -1,4 +1,5 @@ -using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; namespace CharacterMap.Controls; @@ -63,12 +64,15 @@ void Add(string id, string field) } } +//[DependencyProperty("AllowSmartCollection")] public sealed partial class CreateCollectionDialog : ContentDialog { public CreateCollectionDialogTemplateSettings TemplateSettings { get; } public bool IsEditMode { get; } + public bool AllowSmartCollection { get; private set; } + public object Result { get; private set; } @@ -77,7 +81,7 @@ public sealed partial class CreateCollectionDialog : ContentDialog public CreateCollectionDialog(IFontCollection collection = null) { _collection = collection; - TemplateSettings = new CreateCollectionDialogTemplateSettings(); + TemplateSettings = new (); this.InitializeComponent(); if (_collection != null) @@ -89,6 +93,14 @@ public CreateCollectionDialog(IFontCollection collection = null) } } + public CreateCollectionDialog SetDataContext(object o) + { + this.DataContext = o; + if (o is null) + AllowSmartCollection = IsEditMode is false; + return this; + } + private async void ContentDialog_PrimaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args) { diff --git a/CharacterMap/CharacterMap/Core/AppSettings.cs b/CharacterMap/CharacterMap/Core/AppSettings.cs index dee5ae7e..85cec14f 100644 --- a/CharacterMap/CharacterMap/Core/AppSettings.cs +++ b/CharacterMap/CharacterMap/Core/AppSettings.cs @@ -101,7 +101,7 @@ public int ApplicationDesignTheme public int MaxSearchResult { - get => Get(51, "MSR"); + get => Get(101, "MSR"); set => Set(value, "MSR"); } diff --git a/CharacterMap/CharacterMap/Core/InstalledFont.cs b/CharacterMap/CharacterMap/Core/InstalledFont.cs index f589f2c5..1b7341e2 100644 --- a/CharacterMap/CharacterMap/Core/InstalledFont.cs +++ b/CharacterMap/CharacterMap/Core/InstalledFont.cs @@ -59,7 +59,7 @@ public InstalledFont Clone() public static InstalledFont CreateDefault(DWriteFontFace face) { - var font = new InstalledFont(""); + InstalledFont font = new ("Segoe UI"); font._variants.Add(FontVariant.CreateDefault(face)); return font; } diff --git a/CharacterMap/CharacterMap/Helpers/CompositionFactory.cs b/CharacterMap/CharacterMap/Helpers/CompositionFactory.cs index 9f9702cd..e4f62078 100644 --- a/CharacterMap/CharacterMap/Helpers/CompositionFactory.cs +++ b/CharacterMap/CharacterMap/Helpers/CompositionFactory.cs @@ -109,7 +109,7 @@ public static ImplicitAnimationCollection GetRepositionCollection(Compositor c) var g = c.CreateAnimationGroup(); g.Add(c.CreateVector3KeyFrameAnimation() .SetTarget(nameof(Visual.Offset)) - .AddKeyFrame(1f, "this.FinalValue") + .AddKeyFrame(1f, FINAL_VALUE) .SetDuration(CompositionFactory.DefaultOffsetDuration)); var s = c.CreateImplicitAnimationCollection(); @@ -123,7 +123,7 @@ public static ICompositionAnimationBase CreateScaleAnimation(Compositor c) return c.GetCached("ScaleAni", () => { return c.CreateVector3KeyFrameAnimation() - .AddKeyFrame(1f, "this.FinalValue") + .AddKeyFrame(1f, FINAL_VALUE) .SetDuration(CompositionFactory.DefaultOffsetDuration) .SetTarget(nameof(Visual.Scale)); }); diff --git a/CharacterMap/CharacterMap/Helpers/FlyoutHelper.cs b/CharacterMap/CharacterMap/Helpers/FlyoutHelper.cs index d2cd0f00..2f6eb7a9 100644 --- a/CharacterMap/CharacterMap/Helpers/FlyoutHelper.cs +++ b/CharacterMap/CharacterMap/Helpers/FlyoutHelper.cs @@ -391,12 +391,9 @@ static async void AddToSymbolFonts_Click(object sender, RoutedEventArgs e) static void CreateCollection_Click(object sender, RoutedEventArgs e) { - CreateCollectionDialog d = new () - { - DataContext = (sender as FrameworkElement)?.DataContext - }; - - _ = d.ShowAsync(); + _ = new CreateCollectionDialog() + .SetDataContext(((FrameworkElement)sender).DataContext) + .ShowAsync(); } #endregion diff --git a/CharacterMap/CharacterMap/Themes/ClassicThemeStyles.xaml b/CharacterMap/CharacterMap/Themes/ClassicThemeStyles.xaml index 1d30f2c2..a97c1032 100644 --- a/CharacterMap/CharacterMap/Themes/ClassicThemeStyles.xaml +++ b/CharacterMap/CharacterMap/Themes/ClassicThemeStyles.xaml @@ -407,7 +407,165 @@ - - @@ -2541,6 +2699,7 @@ x:Name="SuggestionsList" MaxHeight="{ThemeResource AutoSuggestListMaxHeight}" Margin="{ThemeResource AutoSuggestListPadding}" + core:Properties.ToolTipMemberPath="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=(core:Properties.ToolTipMemberPath)}" DisplayMemberPath="{TemplateBinding DisplayMemberPath}" Footer="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=(core:Properties.Footer)}" IsItemClickEnabled="True" diff --git a/CharacterMap/CharacterMap/Themes/FluentThemeStyles.xaml b/CharacterMap/CharacterMap/Themes/FluentThemeStyles.xaml index f2a45508..6530d8b8 100644 --- a/CharacterMap/CharacterMap/Themes/FluentThemeStyles.xaml +++ b/CharacterMap/CharacterMap/Themes/FluentThemeStyles.xaml @@ -958,6 +958,7 @@ TextTrimming="{ThemeResource MenuFlyoutItemTextTrimming}" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CharacterMap/CharacterMap/Controls/AutoGrid.cs b/CharacterMap/CharacterMap/Controls/AutoGrid.cs index 4c411418..f9a10b79 100644 --- a/CharacterMap/CharacterMap/Controls/AutoGrid.cs +++ b/CharacterMap/CharacterMap/Controls/AutoGrid.cs @@ -4,7 +4,7 @@ namespace CharacterMap.Controls; [DependencyProperty("Definitions")] -[DependencyProperty("Orientation", Orientation.Horizontal, nameof(InvalidateArrange))] +[DependencyProperty("Orientation", Orientation.Vertical, nameof(InvalidateArrange))] public partial class AutoGrid : Grid { partial void OnDefinitionsChanged(string o, string n) => Properties.SetGridDefinitions(this, n); @@ -43,7 +43,8 @@ protected override Size ArrangeOverride(Size finalSize) if (Grid.GetRow(child) == 0) col++; - Grid.SetColumn(child, col); + if (child.ReadLocalValue(Grid.ColumnProperty) == DependencyProperty.UnsetValue) + Grid.SetColumn(child, col); } } diff --git a/CharacterMap/CharacterMap/Controls/DirectTextBlock.cs b/CharacterMap/CharacterMap/Controls/DirectTextBlock.cs index 5f7a51af..b4fe46a5 100644 --- a/CharacterMap/CharacterMap/Controls/DirectTextBlock.cs +++ b/CharacterMap/CharacterMap/Controls/DirectTextBlock.cs @@ -7,45 +7,11 @@ namespace CharacterMap.Controls; -public sealed class DirectTextBlock : Control +[DependencyProperty("Text", null, nameof(Update))] +[DependencyProperty("FontFace", null, nameof(Update))] +[DependencyProperty("Typography", null, nameof(Update))] +public sealed partial class DirectTextBlock : Control { - public CanvasFontFace FontFace - { - get { return (CanvasFontFace)GetValue(FontFaceProperty); } - set { SetValue(FontFaceProperty, value); } - } - - public static readonly DependencyProperty FontFaceProperty = - DependencyProperty.Register(nameof(FontFace), typeof(CanvasFontFace), typeof(DirectTextBlock), new PropertyMetadata(null, (d, e) => - { - ((DirectTextBlock)d).Update(); - })); - - - public TypographyFeatureInfo Typography - { - get { return (TypographyFeatureInfo)GetValue(TypographyProperty); } - set { SetValue(TypographyProperty, value); } - } - - public static readonly DependencyProperty TypographyProperty = - DependencyProperty.Register(nameof(Typography), typeof(TypographyFeatureInfo), typeof(DirectTextBlock), new PropertyMetadata(null, (d, e) => - { - ((DirectTextBlock)d).Update(); - })); - - public string Text - { - get { return (string)GetValue(TextProperty); } - set { SetValue(TextProperty, value); } - } - - public static readonly DependencyProperty TextProperty = - DependencyProperty.Register(nameof(Text), typeof(string), typeof(DirectTextBlock), new PropertyMetadata(null, (d, e) => - { - ((DirectTextBlock)d).Update(); - })); - private CanvasControl m_canvas = null; private CanvasTextLayout m_layout = null; bool m_isStale = true; diff --git a/CharacterMap/CharacterMap/Core/Properties.cs b/CharacterMap/CharacterMap/Core/Properties.cs index f3496cad..9fd53c5e 100644 --- a/CharacterMap/CharacterMap/Core/Properties.cs +++ b/CharacterMap/CharacterMap/Core/Properties.cs @@ -1028,8 +1028,6 @@ static partial void OnFontWeightChanged(DependencyObject d, DependencyPropertyCh UpdateFormat(r); } - static FontFamily __BLANK { get; } = new FontFamily("ms-appx:///Assets/AdobeBlank.otf"); - public static Dictionary Cursors => _cursors; static void UpdateFormat(RichEditBox r) @@ -1042,7 +1040,7 @@ static void UpdateFormat(RichEditBox r) r.TextDocument.BatchDisplayUpdates(); - r.FontFamily = __BLANK; + r.FontFamily = ResourceHelper.Get("BLANK"); ITextCharacterFormat format = r.TextDocument.GetDefaultCharacterFormat(); format.FontStyle = GetFontStyle(r); From 228fcb87ce98152d2844f3e1b8165db9de49bfc9 Mon Sep 17 00:00:00 2001 From: Johnny Westlake Date: Thu, 23 May 2024 22:46:00 +0100 Subject: [PATCH 12/15] Allow editing Symbol font collection --- .../Controls/CreateCollectionDialog.xaml.cs | 4 +- .../Controls/OpenFolderDialog.xaml.cs | 1 - .../CharacterMap/Core/ExportManager.Font.cs | 7 ++-- .../Services/UserFontCollection.cs | 11 +++++- .../CharacterMap/Strings/en-US/Resources.resw | 12 ++++++ .../CollectionManagementViewModel.cs | 39 +++++++++++++------ .../CharacterMap/ViewModels/MainViewModel.cs | 3 +- .../Views/CollectionManagementView.xaml | 10 ++--- .../Views/CollectionManagementView.xaml.cs | 2 +- CharacterMap/CharacterMap/Views/MainPage.xaml | 2 +- 10 files changed, 63 insertions(+), 28 deletions(-) diff --git a/CharacterMap/CharacterMap/Controls/CreateCollectionDialog.xaml.cs b/CharacterMap/CharacterMap/Controls/CreateCollectionDialog.xaml.cs index b02f8409..eeed7d4d 100644 --- a/CharacterMap/CharacterMap/Controls/CreateCollectionDialog.xaml.cs +++ b/CharacterMap/CharacterMap/Controls/CreateCollectionDialog.xaml.cs @@ -87,8 +87,8 @@ public CreateCollectionDialog(IFontCollection collection = null) if (_collection != null) { IsEditMode = true; - this.Title = Localization.Get("DigRenameCollection/Title"); - this.PrimaryButtonText = Localization.Get("DigRenameCollection/PrimaryButtonText"); + this.Title = Localization.Get("DigEditCollection/Title"); + this.PrimaryButtonText = Localization.Get("DigEditCollection/PrimaryButtonText"); TemplateSettings.Populate(_collection); } } diff --git a/CharacterMap/CharacterMap/Controls/OpenFolderDialog.xaml.cs b/CharacterMap/CharacterMap/Controls/OpenFolderDialog.xaml.cs index 6d0077de..0001efbe 100644 --- a/CharacterMap/CharacterMap/Controls/OpenFolderDialog.xaml.cs +++ b/CharacterMap/CharacterMap/Controls/OpenFolderDialog.xaml.cs @@ -60,7 +60,6 @@ public void Cancel() } } - public sealed partial class OpenFolderDialog : ContentDialog { public OpenFolderDialogTemplateSettings TemplateSettings { get; } diff --git a/CharacterMap/CharacterMap/Core/ExportManager.Font.cs b/CharacterMap/CharacterMap/Core/ExportManager.Font.cs index 2546a6ae..1b702296 100644 --- a/CharacterMap/CharacterMap/Core/ExportManager.Font.cs +++ b/CharacterMap/CharacterMap/Core/ExportManager.Font.cs @@ -39,11 +39,10 @@ static List> GetGrouped(IList fonts) } internal static Task ExportCollectionAsZipAsync( - IList fontList, IFontCollection selectedCollection, Action callback = null) { - var fonts = fontList.SelectMany(f => f.Variants).ToList(); + var fonts = selectedCollection.GetFontFamilies().SelectMany(f => f.Variants).ToList(); return ExportFontsAsZipAsync(fonts, selectedCollection.Name, callback); } @@ -86,10 +85,10 @@ await Task.Run(async () => } internal static Task ExportCollectionToFolderAsync( - IList fontList, + IFontCollection selectedCollection, Action callback = null) { - var fonts = fontList.SelectMany(f => f.Variants).ToList(); + var fonts = selectedCollection.GetFontFamilies().SelectMany(f => f.Variants).ToList(); return ExportFontsToFolderAsync(fonts, callback); } diff --git a/CharacterMap/CharacterMap/Services/UserFontCollection.cs b/CharacterMap/CharacterMap/Services/UserFontCollection.cs index ab0de2cb..284274a6 100644 --- a/CharacterMap/CharacterMap/Services/UserFontCollection.cs +++ b/CharacterMap/CharacterMap/Services/UserFontCollection.cs @@ -1,4 +1,6 @@ -namespace CharacterMap.Models; +using System.Collections.ObjectModel; + +namespace CharacterMap.Models; public interface IFontCollection { @@ -11,6 +13,8 @@ public interface IFontCollection bool ContainsFamily(string fontName); string Icon { get; } + + IReadOnlyList GetFontFamilies(); } public class SQLiteFontCollection @@ -61,6 +65,9 @@ public class UserFontCollection : IFontCollection public bool ContainsFamily(string fontName) => Fonts.Contains(fontName); public string Icon => null; + + public IReadOnlyList GetFontFamilies() => + FontFinder.Fonts.Where(f => Fonts.Contains(f.Name)).ToList(); } [DebuggerDisplay("({Id}) Name: {Name}, {Filters.Count} Filters")] @@ -87,6 +94,8 @@ public IReadOnlyList UpdateFonts() return Fonts; } + public IReadOnlyList GetFontFamilies() => UpdateFonts(); + public string GetFlatArgs() => string.Join("\r\n", Filters); public bool ContainsFamily(string fontName) diff --git a/CharacterMap/CharacterMap/Strings/en-US/Resources.resw b/CharacterMap/CharacterMap/Strings/en-US/Resources.resw index 785ce1c6..512434ac 100644 --- a/CharacterMap/CharacterMap/Strings/en-US/Resources.resw +++ b/CharacterMap/CharacterMap/Strings/en-US/Resources.resw @@ -1749,4 +1749,16 @@ Otherwise, "All Fonts" is selected by default on every launch. Foundry Filter + + Edit + + + Edit Collection + + + Edit + + + Edit Collection + \ No newline at end of file diff --git a/CharacterMap/CharacterMap/ViewModels/CollectionManagementViewModel.cs b/CharacterMap/CharacterMap/ViewModels/CollectionManagementViewModel.cs index a66cbffd..65471eac 100644 --- a/CharacterMap/CharacterMap/ViewModels/CollectionManagementViewModel.cs +++ b/CharacterMap/CharacterMap/ViewModels/CollectionManagementViewModel.cs @@ -11,24 +11,37 @@ public partial class CollectionManagementViewModel : ViewModelBase [ObservableProperty] bool _isSaving = false; [ObservableProperty] bool _isExporting = false; + [ObservableProperty] string _query = null; - [ObservableProperty] List _collections; + [ObservableProperty] List _collections; [ObservableProperty] ObservableCollection _fontList; [ObservableProperty] ObservableCollection _collectionFonts; + public bool IsSmartCollection => _selectedCollection is SmartFontCollection; + public bool IsUserCollection => _selectedCollection is UserFontCollection; + + public bool IsSelectedEditable => SelectedCollection is not null && SelectedCollection != CollectionService.SymbolCollection; + public ObservableCollection SelectedFonts = new(); public ObservableCollection SelectedCollectionFonts = new(); public UserCollectionsService CollectionService { get; private set; } = null; - private UserFontCollection _selectedCollection; - public UserFontCollection SelectedCollection + private IFontCollection _selectedCollection; + public IFontCollection SelectedCollection { get => _selectedCollection; set { if (Set(ref _selectedCollection, value) && value != null) - RefreshFontLists(); + { + OnPropertyChanged(nameof(IsSelectedEditable)); + OnPropertyChanged(nameof(IsSmartCollection)); + OnPropertyChanged(nameof(IsUserCollection)); + + if (IsSmartCollection is false) + RefreshFontLists(); + } } } @@ -63,13 +76,15 @@ public void RefreshCollections() // the same collection every time we need to // make sure we call .ToList() or UI bindings will // not work correctly. - Collections = CollectionService.Items.ToList(); + var collections = CollectionService.All.ToList(); + collections.Add(CollectionService.SymbolCollection); + Collections = collections.OrderBy(c => c.Name).ToList(); OnPropertyChanged(nameof(Collections)); } public void RefreshFontLists() { - if (SelectedCollection is null) + if (SelectedCollection is not UserFontCollection collection) { // clear all the things CollectionFonts = new(); @@ -80,7 +95,7 @@ public void RefreshFontLists() Query = null; // 1. Get list of fonts in and not in the collection - var collectionFonts = FontFinder.Fonts.Where(f => SelectedCollection.Fonts.Contains(f.Name)).ToList(); + var collectionFonts = collection.GetFontFamilies(); var systemFonts = FontFinder.Fonts.Except(collectionFonts).ToList(); // 2. Create binding lists @@ -136,14 +151,17 @@ public void StartSave() async Task SaveAsync() { - if (SelectedCollection is null || IsSaving) + if (SelectedCollection is null || IsSaving) return; IsSaving = true; try { - SelectedCollection.Fonts = new HashSet(CollectionFonts.Select(c => c.Name)); + if (SelectedCollection is UserFontCollection user) + { + user.Fonts = [..CollectionFonts.Select(c => c.Name)]; + } await CollectionService.SaveCollectionAsync(SelectedCollection); } finally @@ -159,7 +177,6 @@ internal async void ExportAsZip() try { await ExportManager.ExportCollectionAsZipAsync( - CollectionFonts, SelectedCollection, p => OnSyncContext(() => CollectionExportProgress = p)); } @@ -176,7 +193,7 @@ internal async void ExportAsFolder() try { await ExportManager.ExportCollectionToFolderAsync( - CollectionFonts, + SelectedCollection, p => OnSyncContext(() => CollectionExportProgress = p)); } finally diff --git a/CharacterMap/CharacterMap/ViewModels/MainViewModel.cs b/CharacterMap/CharacterMap/ViewModels/MainViewModel.cs index 2ad5d730..b56f23c1 100644 --- a/CharacterMap/CharacterMap/ViewModels/MainViewModel.cs +++ b/CharacterMap/CharacterMap/ViewModels/MainViewModel.cs @@ -646,7 +646,6 @@ internal async void ExportAsZip() try { await ExportManager.ExportCollectionAsZipAsync( - FontList, SelectedCollection, p => OnSyncContext(() => CollectionExportProgress = p)); } @@ -663,7 +662,7 @@ internal async void ExportAsFolder() try { await ExportManager.ExportCollectionToFolderAsync( - FontList, + SelectedCollection, p => OnSyncContext(() => CollectionExportProgress = p)); } finally diff --git a/CharacterMap/CharacterMap/Views/CollectionManagementView.xaml b/CharacterMap/CharacterMap/Views/CollectionManagementView.xaml index 1a437cbd..14549abf 100644 --- a/CharacterMap/CharacterMap/Views/CollectionManagementView.xaml +++ b/CharacterMap/CharacterMap/Views/CollectionManagementView.xaml @@ -42,7 +42,7 @@ DisplayMemberPath="Name" ItemsSource="{x:Bind ViewModel.Collections, Mode=OneWay}" SelectedItem="{x:Bind ViewModel.SelectedCollection, Mode=TwoWay}" - SelectionChanged="CollectionSelector_SelectionChanged" + SelectionChanged="{x:Bind ViewModel.RefreshFontLists}" d:PlaceholderText="Select exisiting" /> @@ -80,7 +80,7 @@ VerticalAlignment="Stretch" Click="DeleteCollection_Click" Foreground="{ThemeResource AppBarItemForegroundThemeBrush}" - IsEnabled="{x:Bind core:Converters.IsNotNull(ViewModel.SelectedCollection), Mode=OneWay}" + IsEnabled="{x:Bind ViewModel.IsSelectedEditable, Mode=OneWay}" Style="{StaticResource MapInfoButtonStyle}" ToolTipService.Placement="Bottom" d:Label="Delete"> @@ -154,7 +154,7 @@ diff --git a/CharacterMap/CharacterMap/Views/CollectionManagementView.xaml.cs b/CharacterMap/CharacterMap/Views/CollectionManagementView.xaml.cs index f5a04811..68e00c1f 100644 --- a/CharacterMap/CharacterMap/Views/CollectionManagementView.xaml.cs +++ b/CharacterMap/CharacterMap/Views/CollectionManagementView.xaml.cs @@ -48,7 +48,7 @@ async void NewCollection_Click(object sender, RoutedEventArgs e) } } - void SelectCollection(UserFontCollection collection) + void SelectCollection(IFontCollection collection) { ViewModel.Activate(); ViewModel.SelectedCollection = collection; diff --git a/CharacterMap/CharacterMap/Views/MainPage.xaml b/CharacterMap/CharacterMap/Views/MainPage.xaml index b0717910..d27bb683 100644 --- a/CharacterMap/CharacterMap/Views/MainPage.xaml +++ b/CharacterMap/CharacterMap/Views/MainPage.xaml @@ -623,7 +623,7 @@ From 075e29f80c5f0e94c66a0c3dd5794fb1b160e1cc Mon Sep 17 00:00:00 2001 From: Johnny Westlake Date: Fri, 24 May 2024 06:31:38 +0100 Subject: [PATCH 13/15] Smart collection edit hint --- .../Services/UserFontCollection.cs | 3 +- .../CharacterMap/Strings/en-US/Resources.resw | 3 ++ .../ViewModels/SettingsViewModel.cs | 12 ++++---- .../Views/CollectionManagementView.xaml | 28 +++++++++++++++++-- 4 files changed, 37 insertions(+), 9 deletions(-) diff --git a/CharacterMap/CharacterMap/Services/UserFontCollection.cs b/CharacterMap/CharacterMap/Services/UserFontCollection.cs index 284274a6..fb68d220 100644 --- a/CharacterMap/CharacterMap/Services/UserFontCollection.cs +++ b/CharacterMap/CharacterMap/Services/UserFontCollection.cs @@ -51,7 +51,6 @@ public SmartFontCollection AsSmartFontCollection() } } - [DebuggerDisplay("({Id}) Name: {Name}, {Fonts.Count} Fonts")] public class UserFontCollection : IFontCollection { @@ -73,7 +72,7 @@ public IReadOnlyList GetFontFamilies() => [DebuggerDisplay("({Id}) Name: {Name}, {Filters.Count} Filters")] public class SmartFontCollection : IFontCollection { - static string ICON { get; } = new string('\uE945', 1); + static string ICON { get; } = new ('\uE945', 1); public long Id { get; set; } public string Name { get; set; } diff --git a/CharacterMap/CharacterMap/Strings/en-US/Resources.resw b/CharacterMap/CharacterMap/Strings/en-US/Resources.resw index 512434ac..fe989c9e 100644 --- a/CharacterMap/CharacterMap/Strings/en-US/Resources.resw +++ b/CharacterMap/CharacterMap/Strings/en-US/Resources.resw @@ -1761,4 +1761,7 @@ Otherwise, "All Fonts" is selected by default on every launch. Edit Collection + + To modify smart collections use the edit button above. + \ No newline at end of file diff --git a/CharacterMap/CharacterMap/ViewModels/SettingsViewModel.cs b/CharacterMap/CharacterMap/ViewModels/SettingsViewModel.cs index 6c3636c6..0c9c1000 100644 --- a/CharacterMap/CharacterMap/ViewModels/SettingsViewModel.cs +++ b/CharacterMap/CharacterMap/ViewModels/SettingsViewModel.cs @@ -12,14 +12,14 @@ public partial class SettingsViewModel : ViewModelBase protected override bool TrackAnimation => true; - public List Annotations { get; } = + public IReadOnlyList Annotations { get; } = [ GlyphAnnotation.None, GlyphAnnotation.UnicodeHex, GlyphAnnotation.UnicodeIndex ]; - public List Themes { get; } = + public IReadOnlyList Themes { get; } = [ "Windows 10", "Windows 11", @@ -124,13 +124,15 @@ public void ResetFontPreview() private List CreateChangelog() { // Could read this from a text file, but that's a waste of performance. - // Naught wrong with this :P - // Not including bug fixes in here, just key features. The main idea // is to expose features people may not be aware exist inside the // application rather than bug-fixes or visual changes. return [ - new("Latest Update (April 2024)", // April 2024 + new("Latest Update (June 2024)", // June 2024 + "- Added ability to create automatically updating Smart Collections in Settings->Collections\n" + + "- Added support for managing fonts in Symbol font collection in Settings->Collections\n" + + "- The Unicode character search box now supports searching Unihan descriptions"), + new("2024.2.0.0 (April 2024)", // April 2024 "- Support searching font families in Settings->Collections\n" + "- Added option to restore last selected font filter / collection on app launch in Settings->Advanced\n" + "- Added option to define how exported glyph files are named by default in Settings->Export"), diff --git a/CharacterMap/CharacterMap/Views/CollectionManagementView.xaml b/CharacterMap/CharacterMap/Views/CollectionManagementView.xaml index 14549abf..7eb2c181 100644 --- a/CharacterMap/CharacterMap/Views/CollectionManagementView.xaml +++ b/CharacterMap/CharacterMap/Views/CollectionManagementView.xaml @@ -39,11 +39,28 @@ x:Name="CollectionSelector" x:Uid="CollectionSelector" Width="200" - DisplayMemberPath="Name" ItemsSource="{x:Bind ViewModel.Collections, Mode=OneWay}" SelectedItem="{x:Bind ViewModel.SelectedCollection, Mode=TwoWay}" SelectionChanged="{x:Bind ViewModel.RefreshFontLists}" - d:PlaceholderText="Select exisiting" /> + d:PlaceholderText="Select exisiting"> + + + + + + + + + + From bce943c5e1e2550126f29d3eb06b99b24493033f Mon Sep 17 00:00:00 2001 From: Johnny Westlake Date: Fri, 24 May 2024 06:34:00 +0100 Subject: [PATCH 14/15] Add button to Wiki --- CharacterMap/CharacterMap/Strings/en-US/Resources.resw | 3 +++ CharacterMap/CharacterMap/ViewModels/SettingsViewModel.cs | 4 +++- .../CharacterMap/Views/CollectionManagementView.xaml | 2 +- CharacterMap/CharacterMap/Views/SettingsView.xaml | 6 ++++++ 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/CharacterMap/CharacterMap/Strings/en-US/Resources.resw b/CharacterMap/CharacterMap/Strings/en-US/Resources.resw index fe989c9e..957e7f96 100644 --- a/CharacterMap/CharacterMap/Strings/en-US/Resources.resw +++ b/CharacterMap/CharacterMap/Strings/en-US/Resources.resw @@ -1761,6 +1761,9 @@ Otherwise, "All Fonts" is selected by default on every launch. Edit Collection + + Help & Tips + To modify smart collections use the edit button above. diff --git a/CharacterMap/CharacterMap/ViewModels/SettingsViewModel.cs b/CharacterMap/CharacterMap/ViewModels/SettingsViewModel.cs index 0c9c1000..d174f318 100644 --- a/CharacterMap/CharacterMap/ViewModels/SettingsViewModel.cs +++ b/CharacterMap/CharacterMap/ViewModels/SettingsViewModel.cs @@ -131,7 +131,9 @@ private List CreateChangelog() new("Latest Update (June 2024)", // June 2024 "- Added ability to create automatically updating Smart Collections in Settings->Collections\n" + "- Added support for managing fonts in Symbol font collection in Settings->Collections\n" + - "- The Unicode character search box now supports searching Unihan descriptions"), + "- Added additional search filters to \"Find a font family\" search box - \"filepath:\", \"foundry\", \"designer:\"\n" + + "- The Unicode character search box now supports searching Unihan descriptions\n" + + "- Added a link for Helps and Tips at our Wiki in Settings->About"), new("2024.2.0.0 (April 2024)", // April 2024 "- Support searching font families in Settings->Collections\n" + "- Added option to restore last selected font filter / collection on app launch in Settings->Advanced\n" + diff --git a/CharacterMap/CharacterMap/Views/CollectionManagementView.xaml b/CharacterMap/CharacterMap/Views/CollectionManagementView.xaml index 7eb2c181..45a5960b 100644 --- a/CharacterMap/CharacterMap/Views/CollectionManagementView.xaml +++ b/CharacterMap/CharacterMap/Views/CollectionManagementView.xaml @@ -48,7 +48,7 @@ + + Date: Fri, 24 May 2024 07:31:31 +0100 Subject: [PATCH 15/15] Fix flyout icons --- CharacterMap/CharacterMap/Themes/ClassicThemeStyles.xaml | 4 ++-- CharacterMap/CharacterMap/Themes/DefaultThemeStyles.xaml | 4 ++-- CharacterMap/CharacterMap/Themes/ZuneThemeStyles.xaml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/CharacterMap/CharacterMap/Themes/ClassicThemeStyles.xaml b/CharacterMap/CharacterMap/Themes/ClassicThemeStyles.xaml index a97c1032..99c61e6d 100644 --- a/CharacterMap/CharacterMap/Themes/ClassicThemeStyles.xaml +++ b/CharacterMap/CharacterMap/Themes/ClassicThemeStyles.xaml @@ -521,8 +521,8 @@ diff --git a/CharacterMap/CharacterMap/Themes/DefaultThemeStyles.xaml b/CharacterMap/CharacterMap/Themes/DefaultThemeStyles.xaml index abe06d67..d9198d19 100644 --- a/CharacterMap/CharacterMap/Themes/DefaultThemeStyles.xaml +++ b/CharacterMap/CharacterMap/Themes/DefaultThemeStyles.xaml @@ -184,8 +184,8 @@ diff --git a/CharacterMap/CharacterMap/Themes/ZuneThemeStyles.xaml b/CharacterMap/CharacterMap/Themes/ZuneThemeStyles.xaml index 74874c6d..6df8e9c7 100644 --- a/CharacterMap/CharacterMap/Themes/ZuneThemeStyles.xaml +++ b/CharacterMap/CharacterMap/Themes/ZuneThemeStyles.xaml @@ -3452,8 +3452,8 @@