コード例 #1
0
            /// <summary>
            /// Used when moving a node, to create new parent (this) stack or tab for it and target.
            /// Also when moving a node, to create new parent (this) tab for it (target).
            /// </summary>
            _Node(_Node target, bool isTab, bool verticalStack = false)
            {
                _pm = target._pm;

                bool targetIsRoot = !isTab && target.Parent == null;

                if (targetIsRoot)
                {
                    _pm._rootStack = this;
                }
                else
                {
                    _index = target._index;
                    target.AddSibling(this, after: false);
                    target.Remove();
                    target._index = 0;
                }
                AddChild(target);

                if (isTab)
                {
                    _tab  = new();
                    _elem = _tab.tc = new _TabControl();
                }
                else
                {
                    _stack = new _StackFields {
                        isVertical = verticalStack
                    };
                    _elem = _stack.grid = new Grid();
                }
                _elem.Tag = this;

                if (targetIsRoot)
                {
                    //target._dockedSize = ...; //_AddToParentWhenMovingOrAddingLater will set it for target and this
                    _pm._setContainer(_stack.grid);
                }
                else
                {
                    _ReplaceInStack(target);
                    if (isTab)
                    {
                        _captionAt = target._captionAt;
                        _InitTabControl();
                    }
                }
            }
コード例 #2
0
            /// <summary>
            /// Used when creating new leaf node later (after loading).
            /// </summary>
            _Node(_Node target, bool after, LeafType type, string name, bool canClose)
            {
                _pm       = target._pm;
                _leaf     = new() { addedLater = true, name = name, canClose = canClose };
                _elem     = _leaf.panel = new() { Tag = this, UseLayoutRounding = true };
                _leafType = type;
                _dontSave = true;
                _Dictionary.Add(name, this);
                _AddToParentWhenMovingOrAddingLater(target, after);
            }

            public void Save(XmlWriter x)
            {
                if (Parent == null)                   //mark to not save stack/tab nodes without savable leaf descendants
                {
                    _Children(this);
コード例 #3
0
            /// <summary>
            /// Used to create nodes when loading from XML.
            /// </summary>
            _Node(KPanels pm, XElement x, _Node parent, int index)
            {
                _pm    = pm;
                _index = index;

                string tag = x.Name.LocalName;

                if (parent == null)                   //the root XML element
                {
                    if (tag != "stack")
                    {
                        throw new ArgumentException("XML root element must be 'stack'");
                    }
                    _pm._rootStack = this;
                }
                else
                {
                    parent.AddChild(this);
                }

                switch (tag)
                {
                case "stack":
                    _stack = new _StackFields {
                        isVertical = x.Attr("o") == "v"
                    };
                    _elem = _stack.grid = new Grid();
                    break;

                case "tab":
                    _tab  = new();
                    _elem = _tab.tc = new _TabControl();
                    break;

                case "panel":
                case "toolbar":
                case "document":
                    _leaf      = new();
                    _elem      = _leaf.panel = new();
                    _leafType  = tag[0] switch { 'p' => LeafType.Panel, 't' => LeafType.Toolbar, _ => LeafType.Document };
                    _leaf.name = x.Attr("name") ?? throw new ArgumentException("XML element without 'name'");
                    _Dictionary.Add(_leaf.name, this);
                    break;

                default: throw new ArgumentException("unknown XML tag");
                }
                _elem.UseLayoutRounding = true;
                _elem.Tag = this;

                if (parent != null)
                {
                    if (!_IsDocument)
                    {
                        _savedDockState = (_DockState)(x.Attr("state", 0) & 3);
                        _floatSavedRect = x.Attr("floatRect");
                    }
                    if (!_IsStack)
                    {
                        x.Attr(out _captionAt, "captionAt");
                    }

                    if (_ParentIsStack)
                    {
                        _dockedSize = _GridLengthFromString(x.Attr("z"));                         //height in vertical stack or width in horizontal stack
                        _AddToStack(moving: false, _index == 0 ? 0 : x.Attr("s", c_defaultSplitterSize));

                        var flags = (_Flags)x.Attr("flags", 0);
                        if (flags.Has(_Flags.Splitter_ResizeNearest) && _splitter != null)
                        {
                            _splitter.ResizeNearest = true;
                        }

                        if (_IsTab)
                        {
                            _InitTabControl();
                        }
                    }
                    else
                    {
                        _AddToTab(moving: false);
                    }
                }

                if (!_IsLeaf)                   //stack or tab
                {
                    if (_ParentIsTab)
                    {
                        throw new ArgumentException(tag + " in 'tab'");
                    }
                    int i = 0;
                    foreach (var e in x.Elements())
                    {
                        new _Node(_pm, e, this, i++);
                    }
                    Debug.Assert(i > 0);

                    if (_IsTab && i > 0)
                    {
                        _tab.tc.SelectedIndex = Math.Clamp(x.Attr("active", 0), 0, i - 1);
                    }
                }

                //print.it(new string('\t', parent?.Level ?? 0) + _ntype, _ptype, Name, _indexInParent);

                if (parent == null)                   //the root XML element
                {
                    int          nVisible = 0; _Node firstHidden = null;
                    List <_Node> aFloat = null;
                    foreach (var v in Descendants())
                    {
                        if (!v._IsStack)
                        {
                            if (v._IsVisibleReally(true))
                            {
                                nVisible++;
                            }
                            else
                            {
                                firstHidden ??= v;
                            }
                        }
                        var ds = v._savedDockState;
                        if (ds == _DockState.Float)
                        {
                            (aFloat ??= new()).Add(v);
                        }
                        else if (ds != 0)
                        {
                            v._SetDockState(ds);
                        }
                    }
                    if (nVisible == 0 && firstHidden != null)                       //if all non-stack hidden, unhide one, else user cannot unhide any because there are no captions to show the context menu
                    {
                        firstHidden._SetDockState(0);
                    }
                    if (aFloat != null)
                    {
                        DependencyPropertyChangedEventHandler eh = null;
                        eh = (_, e) => {
                            if (e.NewValue is bool visible && visible)
                            {
                                _stack.grid.IsVisibleChanged -= eh;
                                _stack.grid.Dispatcher.InvokeAsync(() => { foreach (var v in aFloat)
                                                                           {
                                                                               v._SetDockState(_DockState.Float);
                                                                           }
                                                                   });
                            }
                        };
                        _stack.grid.IsVisibleChanged += eh;
                    }

                    //timer.after(1000, _ => _Test(5));
                    ////timer.after(5000, _ => _Test(0));
                    //void _Test(int margin) {
                    //	foreach (var v in Descendants(true)) {
                    //		if (v._IsStack) v._stack.grid.Background = (v.Level & 3) switch { 0 => Brushes.CornflowerBlue, 1 => Brushes.Khaki, 2 => Brushes.YellowGreen, _ => Brushes.LightYellow };
                    //		if(v!=this) v._elem.Margin = new Thickness(margin);
                    //		if (v._splitter != null) v._splitter.Visibility = Visibility.Collapsed;
                    //	}
                    //}

                    ////_stack.grid.PreviewMouseMove += _RootGrid_PreviewMouseMove;
                }
            }
コード例 #4
0
 /// <summary>
 /// Used to create root node when loading from XML.
 /// </summary>
 public _Node(KPanels pm, XElement x) : this(pm, x, null, 0)
 {
 }