using System.Collections.ObjectModel; using System.Windows.Input; namespace codelanguage; public class ObjectTreeViewModel : ViewModelBase { private readonly ObservableCollection _rootTypes = new(); private TypeNodeViewModel? _selectedType; private bool _showInheritedMembers = true; private bool _showPrivateMembers = true; private bool _showStaticMembers = true; private string _searchFilter = string.Empty; public ObservableCollection RootTypes => _rootTypes; public TypeNodeViewModel? SelectedType { get => _selectedType; set => Set(ref _selectedType, value); } public bool ShowInheritedMembers { get => _showInheritedMembers; set { _showInheritedMembers = value; OnPropertyChanged(); RefreshAll(); } } public bool ShowPrivateMembers { get => _showPrivateMembers; set { _showPrivateMembers = value; OnPropertyChanged(); RefreshAll(); } } public bool ShowStaticMembers { get => _showStaticMembers; set { _showStaticMembers = value; OnPropertyChanged(); RefreshAll(); } } public string SearchFilter { get => _searchFilter; set { _searchFilter = value; OnPropertyChanged(); ApplyFilter(value); } } public ICommand RefreshCommand { get; } public ICommand ExpandAllCommand { get; } public ICommand CollapseAllCommand { get; } public ICommand GoToDefinitionCommand { get; } public ICommand RenameCommand { get; } public ICommand DeleteCommand { get; } public ObjectTreeViewModel() { RefreshCommand = new RelayCommand(_ => RefreshAll()); ExpandAllCommand = new RelayCommand(_ => ExpandAll()); CollapseAllCommand = new RelayCommand(_ => CollapseAll()); GoToDefinitionCommand = new RelayCommand(_ => GoToDefinition()); RenameCommand = new RelayCommand(_ => Rename()); DeleteCommand = new RelayCommand(_ => Delete()); RefreshAll(); } public void RefreshAll() { _rootTypes.Clear(); var rootPaths = new HashSet(TypeRegistry.GetAllTypes()); var childPaths = new HashSet(); foreach (var path in rootPaths) { var def = TypeRegistry.Get(path); if (def == null) continue; if (!string.IsNullOrEmpty(def.ParentPath)) childPaths.Add(def.ParentPath); } foreach (var path in rootPaths) { if (!childPaths.Contains(path)) { var node = CreateTypeNode(path); if (node != null) _rootTypes.Add(node); } } } private TypeNodeViewModel? CreateTypeNode(string path) { var def = TypeRegistry.Get(path); if (def == null) return null; var node = new TypeNodeViewModel(path, def.ParentPath); foreach (var kvp in def.DefaultVars) { if (!_showPrivateMembers && kvp.Key.StartsWith("_")) continue; node.Variables.Add(new VariableNodeViewModel(kvp.Key, kvp.Value.Type, false)); } foreach (var kvp in def.Procs) { if (!_showPrivateMembers && kvp.Key.StartsWith("_")) continue; node.Procs.Add(new ProcNodeViewModel(kvp.Key, kvp.Value)); } foreach (var kvp in def.Verbs) { node.Verbs.Add(new VerbNodeViewModel(kvp.Key, kvp.Value)); } if (_showInheritedMembers && !string.IsNullOrEmpty(def.ParentPath)) { var parentDef = TypeRegistry.Get(def.ParentPath); if (parentDef != null) node.InheritedFrom = def.ParentPath; } return node; } private void ExpandAll() { foreach (var node in _rootTypes) node.IsExpanded = true; } private void CollapseAll() { foreach (var node in _rootTypes) node.IsExpanded = false; } private void GoToDefinition() { } private void Rename() { } private void Delete() { } private void ApplyFilter(string filter) { if (string.IsNullOrWhiteSpace(filter)) { RefreshAll(); return; } foreach (var node in _rootTypes) node.ApplyFilter(filter); } } public class TypeNodeViewModel : ViewModelBase { private bool _isExpanded; private bool _isSelected; public string Path { get; } public string? ParentPath { get; } public string Name => System.IO.Path.GetFileName(Path) ?? Path; public ObservableCollection Variables { get; } = new(); public ObservableCollection Procs { get; } = new(); public ObservableCollection Verbs { get; } = new(); public ObservableCollection Children { get; } = new(); public string? InheritedFrom { get; set; } public bool IsExpanded { get => _isExpanded; set => Set(ref _isExpanded, value); } public bool IsSelected { get => _isSelected; set => Set(ref _isSelected, value); } public TypeNodeViewModel(string path, string? parentPath) { Path = path; ParentPath = parentPath; } public void ApplyFilter(string filter) { foreach (var v in Variables) v.IsVisible = v.Name.Contains(filter, System.StringComparison.OrdinalIgnoreCase); foreach (var p in Procs) p.IsVisible = p.Name.Contains(filter, System.StringComparison.OrdinalIgnoreCase); foreach (var v in Verbs) v.IsVisible = v.Name.Contains(filter, System.StringComparison.OrdinalIgnoreCase); } } public class VariableNodeViewModel : ViewModelBase { private bool _isVisible = true; private bool _isConstant; private bool _isStatic; public string Name { get; } public string Type { get; } public bool IsVisible { get => _isVisible; set => Set(ref _isVisible, value); } public bool IsConstant { get => _isConstant; set => Set(ref _isConstant, value); } public bool IsStatic { get => _isStatic; set => Set(ref _isStatic, value); } public VariableNodeViewModel(string name, string type, bool isConstant) { Name = name; Type = type; IsConstant = isConstant; } } public class ProcNodeViewModel : ViewModelBase { private bool _isVisible = true; private bool _isOverride; private bool _isVerb; public string Name { get; } public bool IsVisible { get => _isVisible; set => Set(ref _isVisible, value); } public bool IsOverride { get => _isOverride; set => Set(ref _isOverride, value); } public bool IsVerb { get => _isVerb; set => Set(ref _isVerb, value); } public ProcNodeViewModel(string name, ProcStmt stmt) { Name = name; IsOverride = stmt.IsOverride; } } public class VerbNodeViewModel : ViewModelBase { private bool _isVisible = true; private string _category = string.Empty; private string _description = string.Empty; public string Name { get; } public bool IsVisible { get => _isVisible; set => Set(ref _isVisible, value); } public string Category { get => _category; set => Set(ref _category, value); } public string Description { get => _description; set => Set(ref _description, value); } public VerbNodeViewModel(string name, ProcStmt stmt) { Name = name; Category = stmt.VerbMetadata.GetValueOrDefault("category")?.ToString() ?? ""; } }