// This Source Code Form is subject to the terms of the MIT License. // If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT. // Copyright (C) Leszek Pomianowski and WPF UI Contributors. // All Rights Reserved. using System.Runtime; using System.Windows.Controls; namespace WPFluent.Gallery.Controls; public class PageControlDocumentation : Control { public static readonly DependencyProperty ShowProperty = DependencyProperty.RegisterAttached( "Show", typeof(bool), typeof(PageControlDocumentation), new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.AffectsRender) ); public static readonly DependencyProperty DocumentationTypeProperty = DependencyProperty.RegisterAttached( "DocumentationType", typeof(Type), typeof(PageControlDocumentation), new FrameworkPropertyMetadata(null) ); /// Helper for getting from . /// to read from. /// Show property value. [AttachedPropertyBrowsableForType(typeof(FrameworkElement))] public static bool GetShow(FrameworkElement target) => (bool)target.GetValue(ShowProperty); /// Helper for setting on . /// to set on. /// Show property value. public static void SetShow(FrameworkElement target, bool show) => target.SetValue(ShowProperty, show); /// Helper for getting from . /// to read from. /// DocumentationType property value. [AttachedPropertyBrowsableForType(typeof(FrameworkElement))] public static Type? GetDocumentationType(FrameworkElement target) => (Type?)target.GetValue(DocumentationTypeProperty); /// Helper for setting on . /// to set on. /// DocumentationType property value. public static void SetDocumentationType(FrameworkElement target, Type? type) => target.SetValue(DocumentationTypeProperty, type); /// Identifies the dependency property. public static readonly DependencyProperty NavigationViewProperty = DependencyProperty.Register( nameof(NavigationView), typeof(INavigationView), typeof(PageControlDocumentation), new FrameworkPropertyMetadata(null) ); /// Identifies the dependency property. public static readonly DependencyProperty IsDocumentationLinkVisibleProperty = DependencyProperty.Register( nameof(IsDocumentationLinkVisible), typeof(Visibility), typeof(PageControlDocumentation), new FrameworkPropertyMetadata(Visibility.Collapsed) ); /// Identifies the dependency property. public static readonly DependencyProperty TemplateButtonCommandProperty = DependencyProperty.Register( nameof(TemplateButtonCommand), typeof(ICommand), typeof(PageControlDocumentation), new PropertyMetadata(null) ); public INavigationView? NavigationView { get => (INavigationView?)GetValue(NavigationViewProperty); set => SetValue(NavigationViewProperty, value); } public Visibility IsDocumentationLinkVisible { get => (Visibility)GetValue(IsDocumentationLinkVisibleProperty); set => SetValue(IsDocumentationLinkVisibleProperty, value); } public ICommand TemplateButtonCommand => (ICommand)GetValue(TemplateButtonCommandProperty); public PageControlDocumentation() { Loaded += static (sender, _) => ((PageControlDocumentation)sender).OnLoaded(); Unloaded += static (sender, _) => ((PageControlDocumentation)sender).OnUnloaded(); SetValue( TemplateButtonCommandProperty, new CommunityToolkit.Mvvm.Input.RelayCommand(OnClick) ); } private FrameworkElement? _page; private void OnLoaded() { if (NavigationView is null) { throw new ArgumentNullException(nameof(NavigationView)); } NavigationView.Navigated += NavigationViewOnNavigated; } private void OnUnloaded() { NavigationView!.Navigated -= NavigationViewOnNavigated; _page = null; } private void NavigationViewOnNavigated(NavigationView sender, NavigatedEventArgs args) { SetCurrentValue(IsDocumentationLinkVisibleProperty, Visibility.Collapsed); if (args.Page is not FrameworkElement page || !GetShow(page)) { SetCurrentValue(VisibilityProperty, Visibility.Collapsed); return; } _page = page; SetCurrentValue(VisibilityProperty, Visibility.Visible); if (GetDocumentationType(page) is not null) { SetCurrentValue(IsDocumentationLinkVisibleProperty, Visibility.Visible); } } private void OnClick(string? param) { if (string.IsNullOrWhiteSpace(param) || _page is null) { return; } // TODO: Refactor switch if (param == "theme") { SwitchThemes(); return; } string navigationUrl = param switch { "doc" when GetDocumentationType(_page) is { } documentationType => CreateUrlForDocumentation( documentationType ), //"xaml" => CreateUrlForGithub(_page.GetType(), ".xaml"), //"c#" => CreateUrlForGithub(_page.GetType(), ".xaml.cs"), _ => string.Empty, }; if (string.IsNullOrEmpty(navigationUrl)) { return; } try { ProcessStartInfo sInfo = new(navigationUrl) { UseShellExecute = true }; _ = Process.Start(sInfo); } catch (Exception e) { Debug.WriteLine(e); } } //private static string CreateUrlForGithub(Type pageType, System.ReadOnlySpan fileExtension) //{ // const string baseUrl = "https://github.com/lepoco/wpfui/tree/main/src/WPFluent.Gallery/"; // const string baseNamespace = "WPFluent.Gallery"; // ReadOnlySpan pageFullNameWithoutBaseNamespace = pageType.FullName.AsSpan()[ // (baseNamespace.Length + 1).. // ]; // Span pageUrl = stackalloc char[pageFullNameWithoutBaseNamespace.Length]; // pageFullNameWithoutBaseNamespace.CopyTo(pageUrl); // for (int i = 0; i < pageUrl.Length; i++) // { // if (pageUrl[i] == '.') // { // pageUrl[i] = '/'; // } // } // return string.Concat(baseUrl, pageUrl, fileExtension); //} private static string CreateUrlForDocumentation(Type type) { const string baseUrl = "https://wpfui.lepo.co/api/"; return string.Concat(baseUrl, type.FullName, ".html"); } private static void SwitchThemes() { Appearance.ApplicationTheme currentTheme = WPFluent.Appearance.ApplicationThemeManager.GetAppTheme(); WPFluent.Appearance.ApplicationThemeManager.Apply( currentTheme == WPFluent.Appearance.ApplicationTheme.Light ? WPFluent.Appearance.ApplicationTheme.Dark : WPFluent.Appearance.ApplicationTheme.Light ); } }