From 713c281594e1931cdb82bfe10424d2a9e0300738 Mon Sep 17 00:00:00 2001 From: MeltyPlayer Date: Mon, 13 May 2024 20:26:41 -0500 Subject: [PATCH] Set up a control that's essentially the same as ngIf in Angular. --- .../common/controls/If.cs | 69 +++++++++++++++ .../treeViews/FileBundleTreeViewModels.cs | 86 +++++++++++++++++++ .../common/treeViews/FilterTreeView.axaml | 13 +-- .../common/treeViews/FilterTreeView.axaml.cs | 65 -------------- 4 files changed, 163 insertions(+), 70 deletions(-) create mode 100644 FinModelUtility/UniversalAssetTool/UniversalAssetTool.Ui.Avalonia/common/controls/If.cs create mode 100644 FinModelUtility/UniversalAssetTool/UniversalAssetTool.Ui.Avalonia/common/treeViews/FileBundleTreeViewModels.cs diff --git a/FinModelUtility/UniversalAssetTool/UniversalAssetTool.Ui.Avalonia/common/controls/If.cs b/FinModelUtility/UniversalAssetTool/UniversalAssetTool.Ui.Avalonia/common/controls/If.cs new file mode 100644 index 000000000..39a32b34e --- /dev/null +++ b/FinModelUtility/UniversalAssetTool/UniversalAssetTool.Ui.Avalonia/common/controls/If.cs @@ -0,0 +1,69 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Layout; +using Avalonia.Markup.Xaml.Templates; +using Avalonia.Metadata; + +namespace uni.ui.avalonia.common.controls; + +public class If : Control { + private object deferredContent_; + private Control control_; + + public static readonly StyledProperty ConditionProperty + = AvaloniaProperty.Register( + "Condition"); + + public bool Condition { + get => this.GetValue(ConditionProperty); + set => this.SetValue(ConditionProperty, value); + } + + [Content, TemplateContent] + public object DeferredContent { + get => this.deferredContent_; + set { + this.deferredContent_ = value; + if (this.Condition) { + this.DoLoad_(true); + } + } + } + + public Control Control => this.control_; + + static If() { + ConditionProperty.Changed.AddClassHandler( + (c, e) => { + if (e.NewValue is bool v) { + c.DoLoad_(v); + } + }); + } + + protected override Size MeasureOverride(Size availableSize) + => LayoutHelper.MeasureChild(this.control_, availableSize, default); + + protected override Size ArrangeOverride(Size finalSize) + => LayoutHelper.ArrangeChild(this.control_, finalSize, default); + + + private void DoLoad_(bool load) { + if ((this.control_ != null) == load) + return; + + if (load) { + this.control_ = TemplateContent.Load(this.DeferredContent).Result; + ((ISetLogicalParent) this.control_).SetParent(this); + this.VisualChildren.Add(this.control_); + this.LogicalChildren.Add(this.control_); + } else { + ((ISetLogicalParent) this.control_).SetParent(null); + this.LogicalChildren.Clear(); + this.VisualChildren.Remove(this.control_); + this.control_ = null; + } + + this.InvalidateMeasure(); + } +} \ No newline at end of file diff --git a/FinModelUtility/UniversalAssetTool/UniversalAssetTool.Ui.Avalonia/common/treeViews/FileBundleTreeViewModels.cs b/FinModelUtility/UniversalAssetTool/UniversalAssetTool.Ui.Avalonia/common/treeViews/FileBundleTreeViewModels.cs new file mode 100644 index 000000000..acf7c9dd5 --- /dev/null +++ b/FinModelUtility/UniversalAssetTool/UniversalAssetTool.Ui.Avalonia/common/treeViews/FileBundleTreeViewModels.cs @@ -0,0 +1,86 @@ +using System; +using System.Collections.ObjectModel; + +using fin.audio.io; +using fin.audio.io.importers.ogg; +using fin.image; +using fin.io; +using fin.io.bundles; +using fin.model.io; +using fin.scene; +using fin.util.asserts; + +using grezzo.api; + +using uni.ui.avalonia.resources; +using uni.ui.avalonia.ViewModels; + +using IImage = Avalonia.Media.IImage; + +namespace uni.ui.avalonia.common.treeViews { + + // Top-level view model types + public class FileBundleTreeViewModel + : ViewModelBase, IFilterTreeViewViewModel { + public ObservableCollection> Nodes { get; protected set; } + + public event EventHandler>? NodeSelected; + + public void ChangeSelection(INode node) + => this.NodeSelected?.Invoke(this, Asserts.AsA>(node)); + } + + public class FileBundleTreeViewModel : FileBundleTreeViewModel { + public FileBundleTreeViewModel() { + this.Nodes = [ + new FileBundleDirectoryNode("Animals", + [ + new FileBundleDirectoryNode("Mammals", + [ + new FileBundleLeafNode("Lion", new CmbModelFileBundle("foo", new FinFile()).Annotate(null)), + new FileBundleLeafNode("Cat", new OggAudioFileBundle(new FinFile()).Annotate(null)) + ]) + ]) + ]; + } + } + + // Node types + public class FileBundleDirectoryNode( + string label, + ObservableCollection>? subNodes = null) + : ViewModelBase, INode { + public ObservableCollection>? SubNodes { get; } + = subNodes; + + public IImage? Icon => null; + + public string Label { get; } = label; + } + + public class FileBundleLeafNode(string label, IAnnotatedFileBundle data) + : ViewModelBase, INode { + public ObservableCollection>? SubNodes => null; + + public static readonly IImage MUSIC_ICON + = EmbeddedResourceUtil.LoadAvaloniaImage("music"); + + public static readonly IImage PICTURE_ICON + = EmbeddedResourceUtil.LoadAvaloniaImage("picture"); + + public static readonly IImage MODEL_ICON + = EmbeddedResourceUtil.LoadAvaloniaImage("model"); + + public static readonly IImage SCENE_ICON + = EmbeddedResourceUtil.LoadAvaloniaImage("scene"); + + public IImage Icon => data.FileBundle switch { + IAudioFileBundle => MUSIC_ICON, + IImageFileBundle => PICTURE_ICON, + IModelFileBundle => MODEL_ICON, + ISceneFileBundle => SCENE_ICON, + }; + + public string Label { get; } = label; + } +} diff --git a/FinModelUtility/UniversalAssetTool/UniversalAssetTool.Ui.Avalonia/common/treeViews/FilterTreeView.axaml b/FinModelUtility/UniversalAssetTool/UniversalAssetTool.Ui.Avalonia/common/treeViews/FilterTreeView.axaml index 6ad886937..311c1ac3d 100644 --- a/FinModelUtility/UniversalAssetTool/UniversalAssetTool.Ui.Avalonia/common/treeViews/FilterTreeView.axaml +++ b/FinModelUtility/UniversalAssetTool/UniversalAssetTool.Ui.Avalonia/common/treeViews/FilterTreeView.axaml @@ -4,6 +4,8 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:textboxes="clr-namespace:uni.ui.avalonia.common.textboxes" xmlns:treeViews="clr-namespace:uni.ui.avalonia.common.treeViews" + xmlns:global="clr-namespace:" + xmlns:controls="clr-namespace:uni.ui.avalonia.common.controls" mc:Ignorable="d" d:DesignWidth="300" d:DesignHeight="450" x:Class="uni.ui.avalonia.common.treeViews.FilterTreeView" x:DataType="treeViews:FileBundleTreeViewModel"> @@ -45,11 +47,12 @@ - + + + diff --git a/FinModelUtility/UniversalAssetTool/UniversalAssetTool.Ui.Avalonia/common/treeViews/FilterTreeView.axaml.cs b/FinModelUtility/UniversalAssetTool/UniversalAssetTool.Ui.Avalonia/common/treeViews/FilterTreeView.axaml.cs index d85dc97b7..7e4cc1d84 100644 --- a/FinModelUtility/UniversalAssetTool/UniversalAssetTool.Ui.Avalonia/common/treeViews/FilterTreeView.axaml.cs +++ b/FinModelUtility/UniversalAssetTool/UniversalAssetTool.Ui.Avalonia/common/treeViews/FilterTreeView.axaml.cs @@ -43,69 +43,4 @@ private void TreeView_OnSelectionChanged_( filterTreeViewViewModel.ChangeSelection(selectedNode); } } - - // Top-level view model types - public class FileBundleTreeViewModel - : ViewModelBase, IFilterTreeViewViewModel { - public ObservableCollection> Nodes { get; protected set; } - - public event EventHandler>? NodeSelected; - - public void ChangeSelection(INode node) - => this.NodeSelected?.Invoke(this, Asserts.AsA>(node)); - } - - public class FileBundleTreeViewModel : FileBundleTreeViewModel { - public FileBundleTreeViewModel() { - this.Nodes = [ - new ParentNode("Animals", - [ - new ParentNode("Mammals", - [ - new LeafNode("Lion", new CmbModelFileBundle("foo", new FinFile()).Annotate(null)), - new LeafNode("Cat", new OggAudioFileBundle(new FinFile()).Annotate(null)) - ]) - ]) - ]; - } - } - - // Node types - public class ParentNode( - string label, - ObservableCollection>? subNodes = null) - : ViewModelBase, INode { - public ObservableCollection>? SubNodes { get; } - = subNodes; - - public IImage? Icon => null; - - public string Label { get; } = label; - } - - public class LeafNode(string label, IAnnotatedFileBundle data) - : ViewModelBase, INode { - public ObservableCollection>? SubNodes => null; - - public static readonly IImage MUSIC_ICON - = EmbeddedResourceUtil.LoadAvaloniaImage("music"); - - public static readonly IImage PICTURE_ICON - = EmbeddedResourceUtil.LoadAvaloniaImage("picture"); - - public static readonly IImage MODEL_ICON - = EmbeddedResourceUtil.LoadAvaloniaImage("model"); - - public static readonly IImage SCENE_ICON - = EmbeddedResourceUtil.LoadAvaloniaImage("scene"); - - public IImage? Icon => data.FileBundle switch { - IAudioFileBundle => MUSIC_ICON, - IImageFileBundle => PICTURE_ICON, - IModelFileBundle => MODEL_ICON, - ISceneFileBundle => SCENE_ICON, - }; - - public string Label { get; } = label; - } } \ No newline at end of file