using CopaData.FileInspector.GUI.Models; using System.Collections.ObjectModel; using System.Collections.Specialized; namespace Qrakhen.TilingFrames.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 HostFrame? _activeFrame; public HostFrame? ActiveFrame { get => _activeFrame; set => SetField(ref _activeFrame, value); } public bool ShowTabs => Frames.Count > 1; public bool IsEmpty => Frames.Count == 0; public TilingHost(params HostFrame[] frames) { if (frames != null && frames.Length > 0) { Frames = new ObservableCollection(frames); ActiveFrame = Frames[^1]; } Frames.CollectionChanged += OnTabsChanged; } private void OnTabsChanged(object? sender, NotifyCollectionChangedEventArgs e) { if (e.NewItems != null && e.NewItems.Count > 0) { // Make the last item active ActiveFrame = e.NewItems[^1] as HostFrame; } 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 InsertHost(TilingPanel rootPanel, TilingHost targetHost, TilingHost newHost) { HostFrame? frame = newHost.ActiveFrame; if (frame == null) { throw new InvalidOperationException($"No active frame to be inserted could be found within {newHost}'s frames."); } if (newHost.Frames.Count == 1) { TilingPanel.Detach(rootPanel, newHost); } else { newHost.Frames.Remove(frame); } targetHost.Frames.Add(frame); } }