From af57eb99afb35e737a9cfabe88ba812be46723f0 Mon Sep 17 00:00:00 2001 From: Nice3point Date: Fri, 1 Dec 2023 21:48:40 +0300 Subject: [PATCH 01/40] Fix compare url --- Build/Build.CI.GitHub.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Build/Build.CI.GitHub.cs b/Build/Build.CI.GitHub.cs index caf3f935f..50f4e016a 100644 --- a/Build/Build.CI.GitHub.cs +++ b/Build/Build.CI.GitHub.cs @@ -28,7 +28,7 @@ sealed partial class Build Assert.False(tags.Select(tag => tag.Name).Contains(version), $"A Release with the specified tag already exists in the repository: {version}"); Log.Information("Version: {Version}", version); - var changelog = CreateChangelog(tags[^1].Name, version); + var changelog = CreateChangelog(tags[0].Name, version); var newRelease = new NewRelease(version) { Name = version, @@ -96,6 +96,6 @@ string CreateChangelog(string previousVersion, string version) void AppendCompareUrl(StringBuilder logBuilder, string previousVersion, string version) { logBuilder.Append("Full changelog: "); - logBuilder.Append(GitRepository.GetGitHubCompareTagsUrl(previousVersion, version)); + logBuilder.Append(GitRepository.GetGitHubCompareTagsUrl(version, previousVersion)); } } \ No newline at end of file From b65685f5088b730f52d560e5bf064699979c3d37 Mon Sep 17 00:00:00 2001 From: Nice3point Date: Fri, 1 Dec 2023 22:09:58 +0300 Subject: [PATCH 02/40] Add clean data --- RevitLookup/Services/SnoopVisualService.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/RevitLookup/Services/SnoopVisualService.cs b/RevitLookup/Services/SnoopVisualService.cs index c479a1c39..86889581d 100644 --- a/RevitLookup/Services/SnoopVisualService.cs +++ b/RevitLookup/Services/SnoopVisualService.cs @@ -43,6 +43,8 @@ public void Snoop(SnoopableObject snoopableObject) { viewModel.SnoopableObjects = new[] {snoopableObject}; } + + viewModel.SnoopableData = Array.Empty(); } catch (Exception exception) { From ecf6435aa6656c0995e2c3afc7f88ddad93391ae Mon Sep 17 00:00:00 2001 From: Nice3point Date: Sat, 2 Dec 2023 21:11:30 +0300 Subject: [PATCH 03/40] Add Background effects --- RevitLookup.UI/Resources/Theme/HC1.xaml | 24 +++--- RevitLookup.UI/Resources/Theme/HC2.xaml | 24 +++--- RevitLookup.UI/Resources/Theme/HCBlack.xaml | 24 +++--- RevitLookup.UI/Resources/Theme/HCWhite.xaml | 24 +++--- .../ViewModels/Converters/ThemeConverters.cs | 82 +++++++++++++++++++ .../ViewModels/Converters/ValueConterters.cs | 57 ------------- .../ViewModels/Pages/SettingsViewModel.cs | 3 + 7 files changed, 133 insertions(+), 105 deletions(-) create mode 100644 RevitLookup/ViewModels/Converters/ThemeConverters.cs diff --git a/RevitLookup.UI/Resources/Theme/HC1.xaml b/RevitLookup.UI/Resources/Theme/HC1.xaml index 32244999b..dd46c9827 100644 --- a/RevitLookup.UI/Resources/Theme/HC1.xaml +++ b/RevitLookup.UI/Resources/Theme/HC1.xaml @@ -133,18 +133,18 @@ - - - - - - - - - - - - + + + + + + + + + + + + diff --git a/RevitLookup.UI/Resources/Theme/HC2.xaml b/RevitLookup.UI/Resources/Theme/HC2.xaml index 18ebade4b..af59975b6 100644 --- a/RevitLookup.UI/Resources/Theme/HC2.xaml +++ b/RevitLookup.UI/Resources/Theme/HC2.xaml @@ -132,18 +132,18 @@ - - - - - - - - - - - - + + + + + + + + + + + + diff --git a/RevitLookup.UI/Resources/Theme/HCBlack.xaml b/RevitLookup.UI/Resources/Theme/HCBlack.xaml index 8cd3859ba..6b0570440 100644 --- a/RevitLookup.UI/Resources/Theme/HCBlack.xaml +++ b/RevitLookup.UI/Resources/Theme/HCBlack.xaml @@ -132,18 +132,18 @@ - - - - - - - - - - - - + + + + + + + + + + + + diff --git a/RevitLookup.UI/Resources/Theme/HCWhite.xaml b/RevitLookup.UI/Resources/Theme/HCWhite.xaml index 70e3ac852..a8a98dd04 100644 --- a/RevitLookup.UI/Resources/Theme/HCWhite.xaml +++ b/RevitLookup.UI/Resources/Theme/HCWhite.xaml @@ -132,18 +132,18 @@ - - - - - - - - - - - - + + + + + + + + + + + + diff --git a/RevitLookup/ViewModels/Converters/ThemeConverters.cs b/RevitLookup/ViewModels/Converters/ThemeConverters.cs new file mode 100644 index 000000000..161465ee4 --- /dev/null +++ b/RevitLookup/ViewModels/Converters/ThemeConverters.cs @@ -0,0 +1,82 @@ +// Copyright 2003-2023 by Autodesk, Inc. +// +// Permission to use, copy, modify, and distribute this software in +// object code form for any purpose and without fee is hereby granted, +// provided that the above copyright notice appears in all copies and +// that both that copyright notice and the limited warranty and +// restricted rights notice below appear in all supporting +// documentation. +// +// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS. +// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF +// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC. +// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE +// UNINTERRUPTED OR ERROR FREE. +// +// Use, duplication, or disclosure by the U.S. Government is subject to +// restrictions set forth in FAR 52.227-19 (Commercial Computer +// Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii) +// (Rights in Technical Data and Computer Software), as applicable. + +using System.Globalization; +using System.Windows.Data; +using System.Windows.Markup; +using Wpf.Ui.Appearance; +using Wpf.Ui.Controls; + +namespace RevitLookup.ViewModels.Converters; + +[ValueConversion(typeof(WindowBackdropType), typeof(string))] +public sealed class BackgroundTypeConverter : MarkupExtension, IValueConverter +{ + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + var backgroundType = (WindowBackdropType) value!; + return backgroundType switch + { + WindowBackdropType.None => "Disabled", + WindowBackdropType.Acrylic => "Acrylic", + WindowBackdropType.Tabbed => "Blur", + WindowBackdropType.Mica => "Mica", + WindowBackdropType.Auto => "Windows default", + _ => throw new ArgumentOutOfRangeException() + }; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotSupportedException(); + } + + public override object ProvideValue(IServiceProvider serviceProvider) + { + return this; + } +} + +[ValueConversion(typeof(ApplicationTheme), typeof(string))] +public sealed class ApplicationThemeConverter : MarkupExtension, IValueConverter +{ + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + var applicationTheme = (ApplicationTheme) value!; + return applicationTheme switch + { + ApplicationTheme.Light => "Light", + ApplicationTheme.Dark => "Dark", + ApplicationTheme.HighContrast => "High contrast", + ApplicationTheme.Unknown => throw new NotSupportedException(), + _ => throw new ArgumentOutOfRangeException() + }; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotSupportedException(); + } + + public override object ProvideValue(IServiceProvider serviceProvider) + { + return this; + } +} \ No newline at end of file diff --git a/RevitLookup/ViewModels/Converters/ValueConterters.cs b/RevitLookup/ViewModels/Converters/ValueConterters.cs index 856c8b5f8..8c81f19ee 100644 --- a/RevitLookup/ViewModels/Converters/ValueConterters.cs +++ b/RevitLookup/ViewModels/Converters/ValueConterters.cs @@ -22,66 +22,9 @@ using System.Windows; using System.Windows.Data; using System.Windows.Markup; -using Wpf.Ui.Appearance; -using Wpf.Ui.Controls; namespace RevitLookup.ViewModels.Converters; -[ValueConversion(typeof(WindowBackdropType), typeof(string))] -public sealed class BackgroundTypeConverter : MarkupExtension, IValueConverter -{ - public object Convert(object value, Type targetType, object parameter, CultureInfo culture) - { - var backgroundType = (WindowBackdropType) value!; - return backgroundType switch - { - WindowBackdropType.None => "Disabled", - WindowBackdropType.Auto => "Windows default", - WindowBackdropType.Mica => "Mica", - WindowBackdropType.Acrylic => "Acrylic", - WindowBackdropType.Tabbed => "Tabbed", - _ => throw new ArgumentOutOfRangeException() - }; - } - - public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) - { - throw new NotSupportedException(); - } - - public override object ProvideValue(IServiceProvider serviceProvider) - { - return this; - } -} - -[ValueConversion(typeof(ApplicationTheme), typeof(string))] -public sealed class ApplicationThemeConverter : MarkupExtension, IValueConverter -{ - public object Convert(object value, Type targetType, object parameter, CultureInfo culture) - { - var applicationTheme = (ApplicationTheme) value!; - return applicationTheme switch - { - ApplicationTheme.Dark => "Dark", - ApplicationTheme.Light => "Light", - ApplicationTheme.Unknown => "Invalid", - ApplicationTheme.HighContrast => "High contrast", - _ => throw new ArgumentOutOfRangeException() - }; - } - - public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) - { - throw new NotSupportedException(); - } - - public override object ProvideValue(IServiceProvider serviceProvider) - { - return this; - } -} - [ValueConversion(typeof(bool), typeof(bool))] public sealed class InverseBooleanConverter : MarkupExtension, IValueConverter { diff --git a/RevitLookup/ViewModels/Pages/SettingsViewModel.cs b/RevitLookup/ViewModels/Pages/SettingsViewModel.cs index 1e77cab52..ca24518e3 100644 --- a/RevitLookup/ViewModels/Pages/SettingsViewModel.cs +++ b/RevitLookup/ViewModels/Pages/SettingsViewModel.cs @@ -40,11 +40,14 @@ public sealed partial class SettingsViewModel(ISettingsService settingsService, [ ApplicationTheme.Light, ApplicationTheme.Dark + // ApplicationTheme.HighContrast ]; public List BackgroundEffects { get; } = [ WindowBackdropType.None, + WindowBackdropType.Acrylic, + WindowBackdropType.Tabbed, WindowBackdropType.Mica ]; From 2124a643de3b63c1e2eef692ac6d74c371020201 Mon Sep 17 00:00:00 2001 From: Nice3point Date: Sat, 2 Dec 2023 21:45:01 +0300 Subject: [PATCH 04/40] Merge fork --- RevitLookup.UI/Controls/Badge/Badge.xaml | 18 +---- .../Controls/CardColor/CardColor.xaml | 7 +- .../Controls/ComboBox/ComboBox.xaml | 7 +- .../Controls/Expander/Expander.xaml | 1 + .../NavigationView/NavigationCache.cs | 18 +++++ .../NavigationView/NavigationCacheMode.cs | 2 +- .../NavigationView.Navigation.cs | 69 ++++++++++++++----- .../NavigationView/NavigationViewTop.xaml | 4 +- RevitLookup.UI/Controls/TextBox/TextBox.xaml | 1 + .../Controls/TitleBar/TitleBar.xaml | 1 + .../Controls/ToggleButton/ToggleButton.xaml | 3 +- RevitLookup.UI/Interop/UnsafeNativeMethods.cs | 39 +++++++---- RevitLookup.UI/Interop/User32.cs | 15 ++-- RevitLookup.UI/Resources/Theme/Dark.xaml | 8 ++- RevitLookup.UI/Resources/Theme/HC1.xaml | 4 +- RevitLookup.UI/Resources/Theme/HC2.xaml | 4 +- RevitLookup.UI/Resources/Theme/HCBlack.xaml | 4 +- RevitLookup.UI/Resources/Theme/HCWhite.xaml | 4 +- RevitLookup.UI/Resources/Theme/Light.xaml | 8 ++- 19 files changed, 131 insertions(+), 86 deletions(-) diff --git a/RevitLookup.UI/Controls/Badge/Badge.xaml b/RevitLookup.UI/Controls/Badge/Badge.xaml index 4d2d1544c..d1f1271fc 100644 --- a/RevitLookup.UI/Controls/Badge/Badge.xaml +++ b/RevitLookup.UI/Controls/Badge/Badge.xaml @@ -11,16 +11,8 @@ xmlns:controls="clr-namespace:Wpf.Ui.Controls"> - - + + \ No newline at end of file diff --git a/RevitLookup/Views/Resources/Menus.xaml.cs b/RevitLookup/Views/Controls/DataGrid/DataGridGroupStyle.xaml.cs similarity index 86% rename from RevitLookup/Views/Resources/Menus.xaml.cs rename to RevitLookup/Views/Controls/DataGrid/DataGridGroupStyle.xaml.cs index 48e64f44e..8aef8d09d 100644 --- a/RevitLookup/Views/Resources/Menus.xaml.cs +++ b/RevitLookup/Views/Controls/DataGrid/DataGridGroupStyle.xaml.cs @@ -18,11 +18,12 @@ // Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii) // (Rights in Technical Data and Computer Software), as applicable. -namespace RevitLookup.Views.Resources; +// ReSharper disable once CheckNamespace +namespace RevitLookup.Views.Controls; -sealed partial class Menus +public partial class DataGridGroupStyle { - public Menus() + public DataGridGroupStyle() { InitializeComponent(); } diff --git a/RevitLookup/Views/Controls/DataGrid/DataGridRowStyle.xaml b/RevitLookup/Views/Controls/DataGrid/DataGridRowStyle.xaml new file mode 100644 index 000000000..73a3475ab --- /dev/null +++ b/RevitLookup/Views/Controls/DataGrid/DataGridRowStyle.xaml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/RevitLookup/Views/Converters/DescriptorLabelConverters.cs b/RevitLookup/Views/Converters/DescriptorLabelConverters.cs new file mode 100644 index 000000000..586424820 --- /dev/null +++ b/RevitLookup/Views/Converters/DescriptorLabelConverters.cs @@ -0,0 +1,79 @@ +// Copyright 2003-2023 by Autodesk, Inc. +// +// Permission to use, copy, modify, and distribute this software in +// object code form for any purpose and without fee is hereby granted, +// provided that the above copyright notice appears in all copies and +// that both that copyright notice and the limited warranty and +// restricted rights notice below appear in all supporting +// documentation. +// +// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS. +// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF +// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC. +// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE +// UNINTERRUPTED OR ERROR FREE. +// +// Use, duplication, or disclosure by the U.S. Government is subject to +// restrictions set forth in FAR 52.227-19 (Commercial Computer +// Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii) +// (Rights in Technical Data and Computer Software), as applicable. + +using System.Globalization; +using System.Windows.Data; +using System.Windows.Markup; +using RevitLookup.Core.Objects; + +namespace RevitLookup.Views.Converters; + +public abstract class DescriptorConverter : MarkupExtension, IValueConverter +{ + protected string ConvertInvalidNames(string text) + { + return text switch + { + null => "", + "" => "", + _ => text + }; + } + + protected static string CreateCombinedName(Descriptor descriptor) + { + if (string.IsNullOrEmpty(descriptor.Name)) return descriptor.Name; + return string.IsNullOrEmpty(descriptor.Description) ? descriptor.Name : $"{descriptor.Description}: {descriptor.Name}"; + } + + protected static string CreateSingleName(Descriptor descriptor) + { + if (string.IsNullOrEmpty(descriptor.Name)) return descriptor.Name; + return string.IsNullOrEmpty(descriptor.Description) ? descriptor.Name : descriptor.Description; + } + + public abstract object Convert(object value, Type targetType, object parameter, CultureInfo culture); + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotSupportedException(); + } + + public override object ProvideValue(IServiceProvider serviceProvider) + { + return this; + } +} + +public sealed class SingleDescriptorConverter : DescriptorConverter +{ + public override object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + return ConvertInvalidNames(CreateSingleName((Descriptor) value!)); + } +} + +public sealed class CombinedDescriptorConverter : DescriptorConverter +{ + public override object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + return ConvertInvalidNames(CreateCombinedName((Descriptor) value!)); + } +} \ No newline at end of file diff --git a/RevitLookup/Views/Converters/DescriptorConverters.cs b/RevitLookup/Views/Converters/IconDescriptorConverter.cs similarity index 55% rename from RevitLookup/Views/Converters/DescriptorConverters.cs rename to RevitLookup/Views/Converters/IconDescriptorConverter.cs index 7a98cfbbd..3683484ac 100644 --- a/RevitLookup/Views/Converters/DescriptorConverters.cs +++ b/RevitLookup/Views/Converters/IconDescriptorConverter.cs @@ -22,106 +22,11 @@ using System.Globalization; using System.Windows.Data; using System.Windows.Markup; -using RevitLookup.Core.ComponentModel.Descriptors; -using RevitLookup.Core.Contracts; using RevitLookup.Core.Enums; -using RevitLookup.Core.Objects; using Wpf.Ui.Controls; namespace RevitLookup.Views.Converters; -public abstract class DescriptorConverter : MarkupExtension, IValueConverter -{ - public abstract object Convert(object value, Type targetType, object parameter, CultureInfo culture); - - public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) - { - throw new NotSupportedException(); - } - - protected static string CreateCombinedName(Descriptor descriptor) - { - if (string.IsNullOrEmpty(descriptor.Name)) return descriptor.Name; - return string.IsNullOrEmpty(descriptor.Description) ? descriptor.Name : $"{descriptor.Description}: {descriptor.Name}"; - } - - protected static string CreateSingleName(Descriptor descriptor) - { - if (string.IsNullOrEmpty(descriptor.Name)) return descriptor.Name; - return string.IsNullOrEmpty(descriptor.Description) ? descriptor.Name : descriptor.Description; - } - - protected string ConvertInvalidNames(string text) - { - return text switch - { - null => "", - "" => "", - _ => text - }; - } - - public override object ProvideValue(IServiceProvider serviceProvider) - { - return this; - } -} - -public sealed class SingleDescriptorConverter : DescriptorConverter -{ - public override object Convert(object value, Type targetType, object parameter, CultureInfo culture) - { - return ConvertInvalidNames(CreateSingleName((Descriptor) value!)); - } -} - -public sealed class CombinedDescriptorConverter : DescriptorConverter -{ - public override object Convert(object value, Type targetType, object parameter, CultureInfo culture) - { - return ConvertInvalidNames(CreateCombinedName((Descriptor) value!)); - } -} - -public sealed class HandledDescriptorConverter : MarkupExtension, IValueConverter -{ - public object Convert(object value, Type targetType, object parameter, CultureInfo culture) - { - var descriptor = (Descriptor) value!; - if (descriptor is IDescriptorEnumerator enumerator) return !enumerator.IsEmpty; - return descriptor is IDescriptorCollector; - } - - public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) - { - throw new NotSupportedException(); - } - - public override object ProvideValue(IServiceProvider serviceProvider) - { - return this; - } -} - -public sealed class ExceptionDescriptorConverter : MarkupExtension, IValueConverter -{ - public object Convert(object value, Type targetType, object parameter, CultureInfo culture) - { - var descriptor = (Descriptor) value!; - return descriptor is ExceptionDescriptor; - } - - public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) - { - throw new NotSupportedException(); - } - - public override object ProvideValue(IServiceProvider serviceProvider) - { - return this; - } -} - public sealed class IconDescriptorConverter : MarkupExtension, IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) diff --git a/RevitLookup/Views/Converters/ObjectColorConverter.cs b/RevitLookup/Views/Converters/ObjectColorConverter.cs new file mode 100644 index 000000000..49616ea04 --- /dev/null +++ b/RevitLookup/Views/Converters/ObjectColorConverter.cs @@ -0,0 +1,49 @@ +// Copyright 2003-2023 by Autodesk, Inc. +// +// Permission to use, copy, modify, and distribute this software in +// object code form for any purpose and without fee is hereby granted, +// provided that the above copyright notice appears in all copies and +// that both that copyright notice and the limited warranty and +// restricted rights notice below appear in all supporting +// documentation. +// +// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS. +// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF +// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC. +// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE +// UNINTERRUPTED OR ERROR FREE. +// +// Use, duplication, or disclosure by the U.S. Government is subject to +// restrictions set forth in FAR 52.227-19 (Commercial Computer +// Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii) +// (Rights in Technical Data and Computer Software), as applicable. + +using System.Globalization; +using System.Windows.Data; +using System.Windows.Markup; +using Autodesk.Revit.DB; + +namespace RevitLookup.Views.Converters; + +public class ObjectColorConverter : MarkupExtension, IValueConverter +{ + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + return value switch + { + Color color => System.Windows.Media.Color.FromArgb(byte.MaxValue, color.Red, color.Green, color.Blue), + System.Windows.Media.Color color => color, + _ => throw new ArgumentOutOfRangeException(nameof(value), value, null) + }; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotSupportedException(); + } + + public override object ProvideValue(IServiceProvider serviceProvider) + { + return this; + } +} \ No newline at end of file diff --git a/RevitLookup/Views/Markup/MenusDictionary.cs b/RevitLookup/Views/Markup/MenusDictionary.cs new file mode 100644 index 000000000..9d67a0052 --- /dev/null +++ b/RevitLookup/Views/Markup/MenusDictionary.cs @@ -0,0 +1,41 @@ +// Copyright 2003-2023 by Autodesk, Inc. +// +// Permission to use, copy, modify, and distribute this software in +// object code form for any purpose and without fee is hereby granted, +// provided that the above copyright notice appears in all copies and +// that both that copyright notice and the limited warranty and +// restricted rights notice below appear in all supporting +// documentation. +// +// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS. +// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF +// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC. +// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE +// UNINTERRUPTED OR ERROR FREE. +// +// Use, duplication, or disclosure by the U.S. Government is subject to +// restrictions set forth in FAR 52.227-19 (Commercial Computer +// Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii) +// (Rights in Technical Data and Computer Software), as applicable. + +using System.Windows; +using System.Windows.Markup; + +namespace RevitLookup.Views.Markup; + +[Localizability(LocalizationCategory.Ignore)] +[Ambient] +[UsableDuringInitialization(true)] +public class MenusDictionary : ResourceDictionary +{ + private const string DictionaryUri = "pack://application:,,,/RevitLookup;component/Views/Resources/Menus.xaml"; + + /// + /// Initializes a new instance of the class. + /// Default constructor defining of the RevitLookup UI controls dictionary. + /// + public MenusDictionary() + { + Source = new Uri(DictionaryUri, UriKind.Absolute); + } +} diff --git a/RevitLookup/Views/Markup/StylesDictionary.cs b/RevitLookup/Views/Markup/StylesDictionary.cs new file mode 100644 index 000000000..33effa8d1 --- /dev/null +++ b/RevitLookup/Views/Markup/StylesDictionary.cs @@ -0,0 +1,41 @@ +// Copyright 2003-2023 by Autodesk, Inc. +// +// Permission to use, copy, modify, and distribute this software in +// object code form for any purpose and without fee is hereby granted, +// provided that the above copyright notice appears in all copies and +// that both that copyright notice and the limited warranty and +// restricted rights notice below appear in all supporting +// documentation. +// +// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS. +// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF +// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC. +// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE +// UNINTERRUPTED OR ERROR FREE. +// +// Use, duplication, or disclosure by the U.S. Government is subject to +// restrictions set forth in FAR 52.227-19 (Commercial Computer +// Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii) +// (Rights in Technical Data and Computer Software), as applicable. + +using System.Windows; +using System.Windows.Markup; + +namespace RevitLookup.Views.Markup; + +[Localizability(LocalizationCategory.Ignore)] +[Ambient] +[UsableDuringInitialization(true)] +public class StylesDictionary : ResourceDictionary +{ + private const string DictionaryUri = "pack://application:,,,/RevitLookup;component/Views/Resources/RevitLookup.Ui.xaml"; + + /// + /// Initializes a new instance of the class. + /// Default constructor defining of the RevitLookup UI controls dictionary. + /// + public StylesDictionary() + { + Source = new Uri(DictionaryUri, UriKind.Absolute); + } +} diff --git a/RevitLookup/Views/Pages/AboutView.xaml b/RevitLookup/Views/Pages/AboutView.xaml index 69489e511..12177ca22 100644 --- a/RevitLookup/Views/Pages/AboutView.xaml +++ b/RevitLookup/Views/Pages/AboutView.xaml @@ -9,6 +9,7 @@ xmlns:pages="clr-namespace:RevitLookup.Views.Pages" mc:Ignorable="d" d:DataContext="{d:DesignInstance pages:AboutView}"> + @@ -213,4 +214,5 @@ + \ No newline at end of file diff --git a/RevitLookup/Views/Pages/Abstraction/SnoopViewBase.Styles.cs b/RevitLookup/Views/Pages/Abstraction/SnoopViewBase.Styles.cs new file mode 100644 index 000000000..29172d9c0 --- /dev/null +++ b/RevitLookup/Views/Pages/Abstraction/SnoopViewBase.Styles.cs @@ -0,0 +1,64 @@ +// Copyright 2003-2023 by Autodesk, Inc. +// +// Permission to use, copy, modify, and distribute this software in +// object code form for any purpose and without fee is hereby granted, +// provided that the above copyright notice appears in all copies and +// that both that copyright notice and the limited warranty and +// restricted rights notice below appear in all supporting +// documentation. +// +// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS. +// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF +// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC. +// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE +// UNINTERRUPTED OR ERROR FREE. +// +// Use, duplication, or disclosure by the U.S. Government is subject to +// restrictions set forth in FAR 52.227-19 (Commercial Computer +// Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii) +// (Rights in Technical Data and Computer Software), as applicable. + +using System.Windows; +using System.Windows.Controls; +using RevitLookup.Core.ComponentModel.Descriptors; +using RevitLookup.Core.Contracts; +using RevitLookup.Core.Objects; + +namespace RevitLookup.Views.Pages.Abstraction; + +public partial class SnoopViewBase +{ + private void SelectDataGridRowStyle(DataGridRow row) + { + var rowDescriptor = (Descriptor) row.DataContext; + var styleName = rowDescriptor.Value.Descriptor switch + { + ExceptionDescriptor => "ExceptionDataGridRowStyle", + IDescriptorEnumerator {IsEmpty: false} => "HandleDataGridRowStyle", + IDescriptorEnumerator => "DefaultLookupDataGridRowStyle", + IDescriptorCollector => "HandleDataGridRowStyle", + _ => "DefaultLookupDataGridRowStyle" + }; + + row.Style = (Style) FindResource(styleName); + } +} + +public class DataGridCellStyleSelector : DataTemplateSelector +{ + public override DataTemplate SelectTemplate(object item, DependencyObject container) + { + if (item is null) return null; + + var descriptor = (Descriptor) item; + var presenter = (ContentPresenter) container; + var templateName = descriptor.Value.Descriptor switch + { + ColorDescriptor => "ColorCellTemplate", + ColorMediaDescriptor => "ColorCellTemplate", + _ => "DefaultLookupDataGridCellTemplate" + }; + + return (DataTemplate) presenter.FindResource(templateName); + } +} \ No newline at end of file diff --git a/RevitLookup/Views/Pages/Abstraction/SnoopViewBase.xaml.cs b/RevitLookup/Views/Pages/Abstraction/SnoopViewBase.xaml.cs index acac39aee..9b6e3a881 100644 --- a/RevitLookup/Views/Pages/Abstraction/SnoopViewBase.xaml.cs +++ b/RevitLookup/Views/Pages/Abstraction/SnoopViewBase.xaml.cs @@ -20,7 +20,6 @@ using System.Collections; using System.ComponentModel; -using System.Diagnostics; using System.Windows; using System.Windows.Controls; using System.Windows.Data; @@ -55,7 +54,7 @@ protected DataGrid DataGridControl init { _dataGridControl = value; - OnDataGridChanged(value); + OnGridChanged(value); } } @@ -79,7 +78,7 @@ void OnLoaded(object o, RoutedEventArgs args) } } - private async void OnDataGridChanged(DataGrid control) + private async void OnGridChanged(DataGrid control) { //Lazy init. 1 ms is enough to display data and start initialising components await Task.Delay(1); @@ -126,9 +125,20 @@ protected async void OnHeaderLoaded(object sender, RoutedEventArgs routedEventAr } /// - /// Create tooltip, menu + /// Pre setup dataGrid row /// - protected async void OnRowLoaded(object sender, RoutedEventArgs routedEventArgs) + protected void OnGridRowLoading(object sender, DataGridRowEventArgs args) + { + var row = args.Row; + row.Loaded += OnGridRowLoaded; + row.PreviewMouseLeftButtonUp += OnGridRowClicked; + SelectDataGridRowStyle(row); + } + + /// + /// Post setup dataGrid row + /// + protected async void OnGridRowLoaded(object sender, RoutedEventArgs routedEventArgs) { //Lazy init. 1 ms is enough to display data and start initialising components await Task.Delay(1); diff --git a/RevitLookup/Views/Pages/DashboardView.xaml b/RevitLookup/Views/Pages/DashboardView.xaml index 091abc247..eb57854ef 100644 --- a/RevitLookup/Views/Pages/DashboardView.xaml +++ b/RevitLookup/Views/Pages/DashboardView.xaml @@ -8,6 +8,7 @@ xmlns:pages="clr-namespace:RevitLookup.Views.Pages" mc:Ignorable="d" d:DataContext="{d:DesignInstance pages:DashboardView}"> + + \ No newline at end of file diff --git a/RevitLookup/Views/Pages/EventsView.xaml b/RevitLookup/Views/Pages/EventsView.xaml index 2cabdae9b..7e90b1c4a 100644 --- a/RevitLookup/Views/Pages/EventsView.xaml +++ b/RevitLookup/Views/Pages/EventsView.xaml @@ -6,14 +6,23 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:rl="http://revitlookup.com/xaml" xmlns:pages="clr-namespace:RevitLookup.Views.Pages" - xmlns:objects="clr-namespace:RevitLookup.Core.Objects" xmlns:converters="clr-namespace:RevitLookup.Views.Converters" xmlns:abstraction="clr-namespace:RevitLookup.Views.Pages.Abstraction" xmlns:controls="clr-namespace:RevitLookup.Views.Controls" + xmlns:markup="clr-namespace:RevitLookup.Views.Markup" mc:Ignorable="d" d:DesignHeight="500" d:DesignWidth="700" d:DataContext="{d:DesignInstance pages:EventsView}"> + + + + + + + + + @@ -76,7 +85,8 @@ CanUserReorderColumns="False" HorizontalScrollBarVisibility="Disabled" ItemsSource="{Binding ViewModel.FilteredSnoopableData}" - MouseMove="OnPresenterCursorInteracted"> + MouseMove="OnPresenterCursorInteracted" + LoadingRow="OnGridRowLoading"> - + + Header="Value" + CellTemplateSelector="{StaticResource DataGridCellStyleSelector}"/> + - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/RevitLookup/Views/Pages/SettingsView.xaml b/RevitLookup/Views/Pages/SettingsView.xaml index 0306a93dc..43a987a65 100644 --- a/RevitLookup/Views/Pages/SettingsView.xaml +++ b/RevitLookup/Views/Pages/SettingsView.xaml @@ -11,6 +11,7 @@ d:DesignHeight="1100" d:DesignWidth="500" d:DataContext="{d:DesignInstance pages:SettingsView}"> + @@ -93,4 +94,5 @@ + \ No newline at end of file diff --git a/RevitLookup/Views/Pages/SnoopView.xaml b/RevitLookup/Views/Pages/SnoopView.xaml index e66dc0d1c..b40cfc359 100644 --- a/RevitLookup/Views/Pages/SnoopView.xaml +++ b/RevitLookup/Views/Pages/SnoopView.xaml @@ -6,14 +6,23 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:rl="http://revitlookup.com/xaml" xmlns:pages="clr-namespace:RevitLookup.Views.Pages" - xmlns:objects="clr-namespace:RevitLookup.Core.Objects" xmlns:converters="clr-namespace:RevitLookup.Views.Converters" xmlns:abstraction="clr-namespace:RevitLookup.Views.Pages.Abstraction" xmlns:controls="clr-namespace:RevitLookup.Views.Controls" + xmlns:markup="clr-namespace:RevitLookup.Views.Markup" mc:Ignorable="d" d:DesignHeight="500" d:DesignWidth="700" d:DataContext="{d:DesignInstance pages:SnoopView}"> + + + + + + + + + @@ -87,7 +96,8 @@ CanUserReorderColumns="False" HorizontalScrollBarVisibility="Disabled" ItemsSource="{Binding ViewModel.FilteredSnoopableData}" - MouseMove="OnPresenterCursorInteracted"> + MouseMove="OnPresenterCursorInteracted" + LoadingRow="OnGridRowLoading"> - + + Header="Value" + CellTemplateSelector="{StaticResource DataGridCellStyleSelector}"/> + - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/RevitLookup/Views/Resources/Menus.xaml b/RevitLookup/Views/Resources/Menus.xaml index f214b95fc..5a36cea1b 100644 --- a/RevitLookup/Views/Resources/Menus.xaml +++ b/RevitLookup/Views/Resources/Menus.xaml @@ -1,8 +1,7 @@  + xmlns:rl="http://revitlookup.com/xaml"> + + + + + + + + + \ No newline at end of file diff --git a/RevitLookup/Views/RevitLookupView.xaml b/RevitLookup/Views/RevitLookupView.xaml index 072402b0e..942bc7aad 100644 --- a/RevitLookup/Views/RevitLookupView.xaml +++ b/RevitLookup/Views/RevitLookupView.xaml @@ -7,7 +7,6 @@ xmlns:rl="http://revitlookup.com/xaml" xmlns:pages="clr-namespace:RevitLookup.Views.Pages" xmlns:ml="clr-namespace:RevitLookup.Views.Markup" - xmlns:resources="clr-namespace:RevitLookup.Views.Resources" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="200" @@ -17,15 +16,18 @@ Height="555" ExtendsContentIntoTitleBar="True" Icon="../Resources/Images/ShellIcon.ico"> + - + + + + \ No newline at end of file From 0ff3287e9e7157a2b674cdd1eff8868cd6d0f57e Mon Sep 17 00:00:00 2001 From: Nice3point Date: Mon, 25 Dec 2023 17:27:24 +0300 Subject: [PATCH 26/40] Tree view templates support --- .../DataGrid/DataGridCellTemplate.xaml | 11 +- .../TreeView/TreeViewItemTemplate.xaml | 69 ++++++ .../Abstraction/SnoopViewBase.ContextMenu.cs | 9 + .../Abstraction/SnoopViewBase.Gestures.cs | 19 +- .../Abstraction/SnoopViewBase.Navigation.cs | 60 +++--- .../Pages/Abstraction/SnoopViewBase.Styles.cs | 40 +++- .../Abstraction/SnoopViewBase.ToolTips.cs | 6 + .../Pages/Abstraction/SnoopViewBase.xaml.cs | 202 ++++++++++++------ RevitLookup/Views/Pages/EventsView.xaml | 18 +- RevitLookup/Views/Pages/EventsView.xaml.cs | 3 +- RevitLookup/Views/Pages/SnoopView.xaml | 23 +- RevitLookup/Views/Pages/SnoopView.xaml.cs | 2 +- .../Views/Resources/RevitLookup.Ui.xaml | 2 + 13 files changed, 332 insertions(+), 132 deletions(-) create mode 100644 RevitLookup/Views/Controls/TreeView/TreeViewItemTemplate.xaml diff --git a/RevitLookup/Views/Controls/DataGrid/DataGridCellTemplate.xaml b/RevitLookup/Views/Controls/DataGrid/DataGridCellTemplate.xaml index b48e9197a..0cc65880e 100644 --- a/RevitLookup/Views/Controls/DataGrid/DataGridCellTemplate.xaml +++ b/RevitLookup/Views/Controls/DataGrid/DataGridCellTemplate.xaml @@ -17,7 +17,7 @@ + x:Key="DataGridColorCellTemplate"> + Mode=OneTime}" /> + VerticalAlignment="Center" + d:DataContext="{d:DesignInstance objects:Descriptor}"> + Height="10"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/RevitLookup/Views/Pages/Abstraction/SnoopViewBase.ContextMenu.cs b/RevitLookup/Views/Pages/Abstraction/SnoopViewBase.ContextMenu.cs index 6b5201488..d6f04a538 100644 --- a/RevitLookup/Views/Pages/Abstraction/SnoopViewBase.ContextMenu.cs +++ b/RevitLookup/Views/Pages/Abstraction/SnoopViewBase.ContextMenu.cs @@ -30,6 +30,9 @@ namespace RevitLookup.Views.Pages.Abstraction; public partial class SnoopViewBase { + /// + /// Tree view context menu + /// private void CreateTreeContextMenu(Descriptor descriptor, FrameworkElement row) { var contextMenu = new ContextMenu @@ -48,6 +51,9 @@ private void CreateTreeContextMenu(Descriptor descriptor, FrameworkElement row) row.ContextMenu = contextMenu; } + /// + /// Data grid context menu + /// private void CreateGridContextMenu(DataGrid dataGrid) { var contextMenu = new ContextMenu @@ -126,6 +132,9 @@ private void CreateGridContextMenu(DataGrid dataGrid) dataGrid.ContextMenu = contextMenu; } + /// + /// Data grid row context menu + /// private void CreateGridRowContextMenu(Descriptor descriptor, FrameworkElement row) { var contextMenu = new ContextMenu diff --git a/RevitLookup/Views/Pages/Abstraction/SnoopViewBase.Gestures.cs b/RevitLookup/Views/Pages/Abstraction/SnoopViewBase.Gestures.cs index 9dbd5fbd5..5a9db2f5e 100644 --- a/RevitLookup/Views/Pages/Abstraction/SnoopViewBase.Gestures.cs +++ b/RevitLookup/Views/Pages/Abstraction/SnoopViewBase.Gestures.cs @@ -20,21 +20,38 @@ using System.Windows.Input; using CommunityToolkit.Mvvm.Input; +using Wpf.Ui.Controls; namespace RevitLookup.Views.Pages.Abstraction; -public partial class SnoopViewBase +public partial class SnoopViewBase : INavigationAware { + /// + /// Page shortcuts + /// private void AddShortcuts() { var command = new AsyncRelayCommand(() => ViewModel.RefreshMembersCommand.ExecuteAsync(null)); InputBindings.Add(new KeyBinding(command, new KeyGesture(Key.F5))); } + /// + /// Window shortcuts + /// private void OnPageKeyPressed(object sender, KeyEventArgs e) { if (SearchBoxControl.IsKeyboardFocused) return; if (e.KeyboardDevice.Modifiers != ModifierKeys.None) return; if (e.Key is >= Key.D0 and <= Key.Z or >= Key.NumPad0 and <= Key.NumPad9) SearchBoxControl.Focus(); } + + public void OnNavigatedTo() + { + Wpf.Ui.Application.MainWindow.PreviewKeyDown += OnPageKeyPressed; + } + + public void OnNavigatedFrom() + { + Wpf.Ui.Application.MainWindow.PreviewKeyDown -= OnPageKeyPressed; + } } \ No newline at end of file diff --git a/RevitLookup/Views/Pages/Abstraction/SnoopViewBase.Navigation.cs b/RevitLookup/Views/Pages/Abstraction/SnoopViewBase.Navigation.cs index 99bbbbcf2..83476e3a5 100644 --- a/RevitLookup/Views/Pages/Abstraction/SnoopViewBase.Navigation.cs +++ b/RevitLookup/Views/Pages/Abstraction/SnoopViewBase.Navigation.cs @@ -31,11 +31,14 @@ namespace RevitLookup.Views.Pages.Abstraction; public partial class SnoopViewBase { /// - /// Execute collector for selection + /// Handle tree view select event /// - protected void OnTreeItemSelected(object sender, RoutedPropertyChangedEventArgs e) + /// + /// Collect data for selected item + /// + protected void OnTreeItemSelected(object sender, RoutedPropertyChangedEventArgs args) { - switch (e.NewValue) + switch (args.NewValue) { case SnoopableObject snoopableObject: ViewModel.SelectedObject = snoopableObject; @@ -50,33 +53,20 @@ protected void OnTreeItemSelected(object sender, RoutedPropertyChangedEventArgs< ViewModel.FetchMembersCommand.Execute(null); } - + /// - /// Navigate selection in new window + /// Handle tree view click event /// - protected void OnGridRowClicked(object sender, RoutedEventArgs routedEventArgs) - { - if (DataGridControl.SelectedItem is null) return; - - var selectedItem = (Descriptor) DataGridControl.SelectedItem; - if ((Keyboard.Modifiers & ModifierKeys.Control) == 0) - { - if (selectedItem.Value.Descriptor is not IDescriptorCollector) return; - if (selectedItem.Value.Descriptor is IDescriptorEnumerator {IsEmpty: true}) return; - } - - ViewModel.Navigate(selectedItem.Value); - } - - /// - /// Navigate selection in new window - /// - protected void OnTreeItemClicked(object sender, RoutedEventArgs args) + /// + /// Open new window for navigation on Ctrl pressed + /// + private void OnTreeItemClicked(object sender, RoutedEventArgs args) { if ((Keyboard.Modifiers & ModifierKeys.Control) == 0) return; args.Handled = true; - switch (TreeViewControl.SelectedItem) + var element = (FrameworkElement) args.OriginalSource; + switch (element.DataContext) { case SnoopableObject item: ViewModel.Navigate(item); @@ -87,6 +77,28 @@ protected void OnTreeItemClicked(object sender, RoutedEventArgs args) } } + /// + /// Handle data grid click event + /// + /// + /// Open new window for navigation + /// + private void OnGridRowClicked(object sender, RoutedEventArgs args) + { + var row = (DataGridRow) sender; + var context = (Descriptor) row.DataContext; + if ((Keyboard.Modifiers & ModifierKeys.Control) == 0) + { + if (context.Value.Descriptor is not IDescriptorCollector) return; + if (context.Value.Descriptor is IDescriptorEnumerator {IsEmpty: true}) return; + } + + ViewModel.Navigate(context.Value); + } + + /// + /// Handle cursor interaction + /// protected void OnPresenterCursorInteracted(object sender, MouseEventArgs args) { var presenter = (FrameworkElement) sender; diff --git a/RevitLookup/Views/Pages/Abstraction/SnoopViewBase.Styles.cs b/RevitLookup/Views/Pages/Abstraction/SnoopViewBase.Styles.cs index 29172d9c0..0f7c9542e 100644 --- a/RevitLookup/Views/Pages/Abstraction/SnoopViewBase.Styles.cs +++ b/RevitLookup/Views/Pages/Abstraction/SnoopViewBase.Styles.cs @@ -20,6 +20,7 @@ using System.Windows; using System.Windows.Controls; +using System.Windows.Data; using RevitLookup.Core.ComponentModel.Descriptors; using RevitLookup.Core.Contracts; using RevitLookup.Core.Objects; @@ -28,6 +29,9 @@ namespace RevitLookup.Views.Pages.Abstraction; public partial class SnoopViewBase { + /// + /// Data grid row style selector + /// private void SelectDataGridRowStyle(DataGridRow row) { var rowDescriptor = (Descriptor) row.DataContext; @@ -46,19 +50,49 @@ private void SelectDataGridRowStyle(DataGridRow row) public class DataGridCellStyleSelector : DataTemplateSelector { + /// + /// Data grid cell style selector + /// public override DataTemplate SelectTemplate(object item, DependencyObject container) { if (item is null) return null; var descriptor = (Descriptor) item; - var presenter = (ContentPresenter) container; + var presenter = (FrameworkElement) container; var templateName = descriptor.Value.Descriptor switch { - ColorDescriptor => "ColorCellTemplate", - ColorMediaDescriptor => "ColorCellTemplate", + ColorDescriptor => "DataGridColorCellTemplate", + ColorMediaDescriptor => "DataGridColorCellTemplate", _ => "DefaultLookupDataGridCellTemplate" }; + return (DataTemplate) presenter.FindResource(templateName); + } +} + +public class TreeViewItemTemplateSelector : DataTemplateSelector +{ + /// + /// Tree view row style selector + /// + public override DataTemplate SelectTemplate(object item, DependencyObject container) + { + if (item is null) return null; + + var presenter = (FrameworkElement) container; + var templateName = item switch + { + CollectionViewGroup => "DefaultLookupTreeViewGroupTemplate", + SnoopableObject snoopableObject => snoopableObject.Descriptor switch + { + ColorDescriptor => "TreeViewColorItemTemplate", + ColorMediaDescriptor => "TreeViewColorItemTemplate", + _ => "DefaultLookupTreeViewItemTemplate" + }, + + _ => "DefaultLookupTreeViewItemTemplate" + }; + return (DataTemplate) presenter.FindResource(templateName); } } \ No newline at end of file diff --git a/RevitLookup/Views/Pages/Abstraction/SnoopViewBase.ToolTips.cs b/RevitLookup/Views/Pages/Abstraction/SnoopViewBase.ToolTips.cs index 75223ba22..ce9d235a5 100644 --- a/RevitLookup/Views/Pages/Abstraction/SnoopViewBase.ToolTips.cs +++ b/RevitLookup/Views/Pages/Abstraction/SnoopViewBase.ToolTips.cs @@ -28,6 +28,9 @@ namespace RevitLookup.Views.Pages.Abstraction; public partial class SnoopViewBase { + /// + /// Create tree view tooltips + /// private void CreateTreeTooltip(Descriptor descriptor, FrameworkElement row) { row.ToolTip = new ToolTip @@ -41,6 +44,9 @@ private void CreateTreeTooltip(Descriptor descriptor, FrameworkElement row) }; } + /// + /// Create data grid tooltips + /// private void CreateGridRowTooltip(Descriptor descriptor, FrameworkElement row) { var builder = new StringBuilder(); diff --git a/RevitLookup/Views/Pages/Abstraction/SnoopViewBase.xaml.cs b/RevitLookup/Views/Pages/Abstraction/SnoopViewBase.xaml.cs index 9b6e3a881..55a040317 100644 --- a/RevitLookup/Views/Pages/Abstraction/SnoopViewBase.xaml.cs +++ b/RevitLookup/Views/Pages/Abstraction/SnoopViewBase.xaml.cs @@ -22,6 +22,7 @@ using System.ComponentModel; using System.Windows; using System.Windows.Controls; +using System.Windows.Controls.Primitives; using System.Windows.Data; using RevitLookup.Core.Objects; using RevitLookup.Services.Contracts; @@ -30,14 +31,14 @@ using Wpf.Ui.Controls; using DataGrid = Wpf.Ui.Controls.DataGrid; using TreeView = Wpf.Ui.Controls.TreeView; -using TreeViewItem = System.Windows.Controls.TreeViewItem; namespace RevitLookup.Views.Pages.Abstraction; -public partial class SnoopViewBase : Page, INavigableView, INavigationAware +public partial class SnoopViewBase : Page, INavigableView { - private readonly ISettingsService _settingsService; + private readonly TreeView _treeViewControl; private readonly DataGrid _dataGridControl; + private readonly ISettingsService _settingsService; protected SnoopViewBase(ISettingsService settingsService) { @@ -45,8 +46,15 @@ protected SnoopViewBase(ISettingsService settingsService) AddShortcuts(); } - protected UIElement SearchBoxControl { get; init; } - protected TreeView TreeViewControl { get; init; } + protected TreeView TreeViewControl + { + get => _treeViewControl; + init + { + _treeViewControl = value; + OnTreeChanged(value); + } + } protected DataGrid DataGridControl { @@ -58,8 +66,26 @@ protected DataGrid DataGridControl } } + protected UIElement SearchBoxControl { get; init; } public ISnoopViewModel ViewModel { get; protected init; } + /// + /// Handle data grid reference changed event + /// + /// + /// Data grid initialization + /// + private void OnTreeChanged(TreeView control) + { + control.ItemContainerGenerator.StatusChanged += OnTreeViewItemGenerated; + } + + /// + /// Handle tree view source changed + /// + /// + /// Tree view initialization, apply transition + /// protected void OnTreeSourceChanged(object sender, IEnumerable enumerable) { if (IsLoaded) @@ -78,55 +104,112 @@ void OnLoaded(object o, RoutedEventArgs args) } } - private async void OnGridChanged(DataGrid control) + /// + /// Handle tree view item loaded + /// + /// + /// TreeView item customization after loading + /// + private void OnTreeViewItemGenerated(object sender, EventArgs _) { - //Lazy init. 1 ms is enough to display data and start initialising components - await Task.Delay(1); - - ValidateTimeColumn(control); - CreateGridContextMenu(control); - control.ItemsSourceChanged += OnGridItemsSourceChanged; + var generator = (ItemContainerGenerator) sender; + if (generator.Status == GeneratorStatus.ContainersGenerated) + { + foreach (var item in generator.Items) + { + var treeItem = (ItemsControl) generator.ContainerFromItem(item); + if (treeItem is null) continue; + + treeItem.Loaded -= OnTreeItemLoaded; + treeItem.PreviewMouseLeftButtonUp -= OnTreeItemClicked; + + treeItem.Loaded += OnTreeItemLoaded; + treeItem.PreviewMouseLeftButtonUp += OnTreeItemClicked; + + if (treeItem.Items.Count > 0) + { + treeItem.ItemContainerGenerator.StatusChanged -= OnTreeViewItemGenerated; + treeItem.ItemContainerGenerator.StatusChanged += OnTreeViewItemGenerated; + } + } + } } - private void OnGridItemsSourceChanged(object sender, EventArgs _) + /// + /// Handle tree view loaded event + /// + /// + /// Create tree view tooltips, menus + /// + private void OnTreeItemLoaded(object sender, RoutedEventArgs args) { - var dataGrid = (DataGrid) sender; - - //Clear shapingStorage for remove duplications. WpfBug? - dataGrid.Items.GroupDescriptions!.Clear(); - dataGrid.Items.SortDescriptions.Add(new SortDescription(nameof(Descriptor.Depth), ListSortDirection.Descending)); - dataGrid.Items.SortDescriptions.Add(new SortDescription(nameof(Descriptor.MemberAttributes), ListSortDirection.Ascending)); - dataGrid.Items.SortDescriptions.Add(new SortDescription(nameof(Descriptor.Name), ListSortDirection.Ascending)); - dataGrid.Items.GroupDescriptions.Add(new PropertyGroupDescription(nameof(Descriptor.Type))); + var element = (FrameworkElement) sender; + switch (element.DataContext) + { + case SnoopableObject context: + CreateTreeTooltip(context.Descriptor, element); + CreateTreeContextMenu(context.Descriptor, element); + break; + } } - public void OnNavigatedTo() + /// + /// Handle tree view reference changed event + /// + /// + /// Tree view initialization, apply transition + /// + private async void SetupTreeView() { - Wpf.Ui.Application.MainWindow.PreviewKeyDown += OnPageKeyPressed; + // Await Frame transition. GetMembers freezes the thread and breaks the animation + await Task.Delay(_settingsService.TransitionDuration); + + // if (TryRestoreSelection()) return; + + ExpandFirstTreeGroup(); } - public void OnNavigatedFrom() + /// + /// Handle data grid reference changed event + /// + /// + /// Data grid initialization, validation + /// + private void OnGridChanged(DataGrid control) { - Wpf.Ui.Application.MainWindow.PreviewKeyDown -= OnPageKeyPressed; + control.Loaded += (sender, _) => + { + var dataGrid = (DataGrid) sender; + ValidateTimeColumn(dataGrid); + CreateGridContextMenu(dataGrid); + }; + control.ItemsSourceChanged += OnGridItemsSourceChanged; } /// - /// Enable navigation + /// Handle data grid source changed /// - protected async void OnHeaderLoaded(object sender, RoutedEventArgs routedEventArgs) + /// + /// Group and sort items + /// + private void OnGridItemsSourceChanged(object sender, EventArgs _) { - //Lazy init. 1 ms is enough to display data and start initialising components - await Task.Delay(1); - - var treeItem = VisualUtils.FindVisualParent((DependencyObject) sender); - if (treeItem is null) return; + var dataGrid = (DataGrid) sender; - treeItem.PreviewMouseLeftButtonUp += OnTreeItemClicked; + //Clear shapingStorage for remove duplications. WpfBug? + dataGrid.Items.GroupDescriptions!.Clear(); + dataGrid.Items.SortDescriptions.Add(new SortDescription(nameof(Descriptor.Depth), ListSortDirection.Descending)); + dataGrid.Items.SortDescriptions.Add(new SortDescription(nameof(Descriptor.MemberAttributes), ListSortDirection.Ascending)); + dataGrid.Items.SortDescriptions.Add(new SortDescription(nameof(Descriptor.Name), ListSortDirection.Ascending)); + dataGrid.Items.GroupDescriptions.Add(new PropertyGroupDescription(nameof(Descriptor.Type))); } /// - /// Pre setup dataGrid row + /// Handle data grid row loading event /// + /// + /// Select row style + /// protected void OnGridRowLoading(object sender, DataGridRowEventArgs args) { var row = args.Row; @@ -136,40 +219,22 @@ protected void OnGridRowLoading(object sender, DataGridRowEventArgs args) } /// - /// Post setup dataGrid row + /// Handle data grid row loaded event /// - protected async void OnGridRowLoaded(object sender, RoutedEventArgs routedEventArgs) + /// + /// Create tooltips, context menu + /// + protected void OnGridRowLoaded(object sender, RoutedEventArgs args) { - //Lazy init. 1 ms is enough to display data and start initialising components - await Task.Delay(1); - var element = (FrameworkElement) sender; - switch (element.DataContext) - { - case SnoopableObject context: - var treeItem = VisualUtils.FindVisualParent((DependencyObject) sender); - CreateTreeTooltip(context.Descriptor, treeItem); - CreateTreeContextMenu(context.Descriptor, treeItem); - break; - case Descriptor context: - CreateGridRowTooltip(context, element); - CreateGridRowContextMenu(context, element); - break; - default: - return; - } - } - - private async void SetupTreeView() - { - // Await Frame transition. GetMembers freezes the thread and breaks the animation - await Task.Delay(_settingsService.TransitionDuration); - - // if (TryRestoreSelection()) return; - - ExpandFirstGroup(); + var context = (Descriptor) element.DataContext; + CreateGridRowTooltip(context, element); + CreateGridRowContextMenu(context, element); } + /// + /// Restore the previous selection when cancelling a search + /// [Obsolete("Low performance")] private bool TryRestoreSelection() { @@ -184,7 +249,10 @@ private bool TryRestoreSelection() return true; } - private void ExpandFirstGroup() + /// + /// Expand first tree view group after navigation + /// + private void ExpandFirstTreeGroup() { if (TreeViewControl.Items.Count > 3) return; @@ -197,11 +265,17 @@ private void ExpandFirstGroup() nestedItem.IsSelected = true; } + /// + /// Show/hide time column + /// private void ValidateTimeColumn(System.Windows.Controls.DataGrid control) { control.Columns[2].Visibility = _settingsService.ShowTimeColumn ? Visibility.Visible : Visibility.Collapsed; } + /// + /// Recollect all data on the selected item + /// private Task RefreshGridAsync() { return ViewModel.RefreshMembersCommand.ExecuteAsync(null); diff --git a/RevitLookup/Views/Pages/EventsView.xaml b/RevitLookup/Views/Pages/EventsView.xaml index 7e90b1c4a..144af4248 100644 --- a/RevitLookup/Views/Pages/EventsView.xaml +++ b/RevitLookup/Views/Pages/EventsView.xaml @@ -53,21 +53,15 @@ Text="{Binding ViewModel.SearchText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> + - - - - - - + ItemsSource="{Binding ViewModel.FilteredSnoopableObjects}" + MouseMove="OnPresenterCursorInteracted" + ItemTemplateSelector="{StaticResource TreeViewItemTemplateSelector}" /> + + CellTemplateSelector="{StaticResource DataGridCellStyleSelector}" /> + - - - - - - - - - - - + MouseMove="OnPresenterCursorInteracted" + ItemTemplateSelector="{StaticResource TreeViewItemTemplateSelector}" /> + + + \ No newline at end of file From 4420439fee84abf923e28bc3fe1a066a1ecf39e7 Mon Sep 17 00:00:00 2001 From: Nice3point Date: Mon, 25 Dec 2023 17:47:48 +0300 Subject: [PATCH 27/40] Fix invalid color support --- RevitLookup/Views/Converters/ObjectColorConverter.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/RevitLookup/Views/Converters/ObjectColorConverter.cs b/RevitLookup/Views/Converters/ObjectColorConverter.cs index 49616ea04..d20a9d786 100644 --- a/RevitLookup/Views/Converters/ObjectColorConverter.cs +++ b/RevitLookup/Views/Converters/ObjectColorConverter.cs @@ -31,6 +31,7 @@ public object Convert(object value, Type targetType, object parameter, CultureIn { return value switch { + Color {IsValid: false} => System.Windows.Media.Colors.Transparent, Color color => System.Windows.Media.Color.FromArgb(byte.MaxValue, color.Red, color.Green, color.Blue), System.Windows.Media.Color color => color, _ => throw new ArgumentOutOfRangeException(nameof(value), value, null) From 9e8b34c766c2d89b349dc6679b82c00023d975d0 Mon Sep 17 00:00:00 2001 From: Nice3point Date: Mon, 25 Dec 2023 18:22:29 +0300 Subject: [PATCH 28/40] Apply Patch --- RevitLookup.UI/Controls/Badge/Badge.xaml | 6 +- .../Controls/Expander/Expander.xaml | 4 +- .../Controls/InfoBadge/InfoBadge.cs | 88 +++++++- .../Controls/InfoBadge/InfoBadge.xaml | 192 +++++++++++++++++- .../Controls/InfoBadge/InfoBadgeSeverity.cs | 35 ++++ .../NavigationView/INavigationViewItem.cs | 3 + .../NavigationView/NavigationLeftFluent.xaml | 14 +- .../NavigationView/NavigationViewBottom.xaml | 34 +++- .../NavigationView/NavigationViewCompact.xaml | 28 ++- .../NavigationView/NavigationViewItem.cs | 53 ++++- .../NavigationViewLeftMinimalCompact.xaml | 27 ++- .../NavigationView/NavigationViewTop.xaml | 35 ++-- .../Controls/NumberBox/NumberBox.xaml | 4 +- .../Controls/TitleBar/TitleBar.xaml | 2 +- .../Controls/ToggleButton/ToggleButton.xaml | 4 +- .../Controls/ToggleSwitch/ToggleSwitch.xaml | 12 +- RevitLookup.UI/Resources/Theme/Dark.xaml | 14 +- RevitLookup.UI/Resources/Theme/HC1.xaml | 14 +- RevitLookup.UI/Resources/Theme/HC2.xaml | 14 +- RevitLookup.UI/Resources/Theme/HCBlack.xaml | 14 +- RevitLookup.UI/Resources/Theme/HCWhite.xaml | 10 +- RevitLookup.UI/Resources/Theme/Light.xaml | 11 +- RevitLookup.UI/Resources/Wpf.Ui.xaml | 1 + RevitLookup.UI/VisualStudioToolsManifest.xml | 1 + 24 files changed, 557 insertions(+), 63 deletions(-) create mode 100644 RevitLookup.UI/Controls/InfoBadge/InfoBadgeSeverity.cs diff --git a/RevitLookup.UI/Controls/Badge/Badge.xaml b/RevitLookup.UI/Controls/Badge/Badge.xaml index d1f1271fc..54118fc91 100644 --- a/RevitLookup.UI/Controls/Badge/Badge.xaml +++ b/RevitLookup.UI/Controls/Badge/Badge.xaml @@ -11,8 +11,8 @@ xmlns:controls="clr-namespace:Wpf.Ui.Controls"> + + + + + +