using CopaData.FileInspector.GUI.Models; using System.Collections.ObjectModel; using System.Collections.Specialized; namespace CopaData.FileInspector.GUI.TilingPanels.Models; /// /// Host node that by paradigm is located only at the very end of the tree's branches.
/// Hosts may contain at least one central control, or multiple tabs of controls.
/// Note that tab contents must _not_ be any tiling controls, as that would break hierarchy and branching logic.
/// Everything above a will be a by definition. ///
public class TilingHost : TilingNode { public ObservableCollection Frames { get; } = []; private TilingFrame? _activeFrame; public TilingFrame? ActiveFrame { get => _activeFrame; set => SetField(ref _activeFrame, value); } public bool ShowTabs => Frames.Count > 1; public bool IsEmpty => Frames.Count == 0; public TilingHost(params TilingFrame[] frames) { if (frames != null && frames.Length > 0) { Frames = new ObservableCollection(frames); ActiveFrame = Frames[^1]; foreach (var frame in Frames) { frame.Parent = this; } } Frames.CollectionChanged += OnFramesItemsChanged; } private void OnFramesItemsChanged(object? sender, NotifyCollectionChangedEventArgs e) { if (e.NewItems != null && e.NewItems.Count > 0) { // Make the last item active ActiveFrame = e.NewItems[^1] as TilingFrame; foreach (var item in e.NewItems) { if (item is TilingFrame frame) { // We're using a reference here as this is the only place that always listens to updates. frame.Parent = this; } } } else if (e.OldItems != null && e.OldItems.Count > 0) { if (ActiveFrame != null && !Frames.Contains(ActiveFrame)) { // Previous active tab got removed, revert back to the most recent tab or set ActiveTab to null if tabs are empty. if (Frames.Count > 0) { ActiveFrame = Frames[^1]; } else { ActiveFrame = null; } } } } /// /// Inserts into as a new tab /// after being dropped in the center region by the user.
/// If the previous host only had one frame inside it, it will be detached from its parent. /// Otherwise, only the frame will be removed and inserted into 's frames. ///
public static void Insert(TilingPanel rootPanel, TilingHost targetHost, TilingFrame frame) { if (frame.Parent?.Frames.Count < 2) { TilingPanel.Detach(rootPanel, frame.Parent); } else { frame.Parent?.Frames.Remove(frame); } targetHost.Frames.Add(frame); } }