Example #1
0
            internal bool HasToolbar;            //small caption, maybe no splitter etc

            /// <summary>
            /// This ctor is used at startup, when adding from XML.
            /// </summary>
            internal _Panel(AuDockPanel manager, _Split parentSplit, XElement x, _Tab parentTab = null) : base(manager, parentSplit)
            {
                var name = x.Attr("name");
                var c    = manager._initControls[name];

                _manager._aPanel.Add(this);

                this.Content = c;
                Debug.Assert(c.Name == name);
                this.Name      = name;
                this.ParentTab = parentTab;

                if (c is ToolStrip ts)
                {
                    _InitToolstrip(ts);
                }
                else if (x.HasAttr("doc"))
                {
                    this.HasDocument = true;
                    //	c.AccessibleRole = AccessibleRole.Document; //no, its child is DOCUMENT
                    //} else {
                    //	c.AccessibleRole = AccessibleRole.Pane;
                }
                c.AccessibleRole = AccessibleRole.Pane;

                this.InitDockStateFromXML(x);
            }
Example #2
0
File: _Tab.cs Project: alexfordc/Au
            /// <summary>
            /// This ctor is used when a floating _Panel dropped on a docked non-tabbed _Panel caption.
            /// item1 or item2 must be docked, but not both.
            /// </summary>
            internal _Tab(AuDockPanel manager, _Split parentSplit, _Panel item1, _Panel item2) : base(manager, parentSplit)
            {
                manager._aTab.Add(this);

                this.Items = new List <_Panel>()
                {
                    item1, item2
                };
                item1.ParentTab = item2.ParentTab = this;
                Debug.Assert(item1.IsDocked != item2.IsDocked);
                _dockedItemCount = 1;
                this.SetActiveItem(item1.IsDocked ? item1 : item2);
            }
Example #3
0
            /// <summary>
            /// This ctor is used when a floating _ContentNode dropped on a docked _ContentNode.
            /// child1 or child2 must be docked, but not both.
            /// </summary>
            internal _Split(AuDockPanel manager, _Split parentSplit, _Node child1, _Node child2, bool isVertical) : base(manager, parentSplit)
            {
                manager._aSplit.Add(this);

                Child1             = child1;
                Child2             = child2;
                child1.ParentSplit = child2.ParentSplit = this;
                Debug.Assert(child1.IsDocked != child2.IsDocked);
                _dockedChildCount = 1;
                IsVerticalSplit   = isVertical;
                SplitterWidth     = _splitterWidth;
                _isFraction       = true;
                _fraction         = 0.5F;
            }
Example #4
0
File: _Tab.cs Project: alexfordc/Au
            bool _onlyIcons;              //display only icons in tab buttons (too small to display text)

            /// <summary>
            /// This ctor is used at startup, when adding from XML.
            /// </summary>
            internal _Tab(AuDockPanel manager, _Split parentSplit, XElement x) : base(manager, parentSplit)
            {
                manager._aTab.Add(this);

                int iAct    = x.Attr("active", 0);
                var xPanels = x.Elements("panel");

                this.Items = new List <_Panel>();

                int i = 0;

                foreach (var xx in xPanels)
                {
                    var gp = new _Panel(manager, parentSplit, xx, this);
                    this.Items.Add(gp);
                    if (gp.IsDocked)
                    {
                        _dockedItemCount++;
                        if (i == iAct || this.ActiveItem == null)
                        {
                            this.ActiveItem = gp;                                                              //if iAct invalid, let the first docked panel be active
                        }
                    }
                    i++;
                }

                foreach (var gp in this.Items)
                {
                    if (gp.IsDocked && gp != this.ActiveItem)
                    {
                        gp.Content.Visible = false;
                    }
                }

                this.InitDockStateFromXML(x);
            }
Example #5
0
 internal _Node(AuDockPanel manager, _Split parentSplit)
 {
     _manager    = manager;
     ParentSplit = parentSplit;
     //manager._nodes.Add(this);
 }
Example #6
0
            /// <summary>
            /// Docks this _Panel or _Tab in an existing or new _Tab or _Split.
            /// If need, creates new _Tab or _Split in gcTarget place and adds gcTarget and this to it. Else reorders if need.
            /// This can be a new _Panel, with null ParentSplit and ParentTab, dock state not Docked.
            /// </summary>
            /// <param name="gcTarget">New sibling _Panel (side can be any) or sibling _Tab (when side is SplitX) or parent _Tab (when side is TabX).</param>
            /// <param name="side">Specifies whether to add on a _Tab or _Split, and at which side of gcTarget.</param>
            internal void DockBy(_ContentNode gcTarget, _DockHow side)
            {
                var gpThis         = this as _Panel;
                var gtThisParent   = gpThis?.ParentTab;
                var gsThisParent   = this.ParentSplit;
                var gsTargetParent = gcTarget.ParentSplit;

                if (side == _DockHow.TabBefore || side == _DockHow.TabAfter)
                {
                    var  gpTarget       = gcTarget as _Panel;
                    _Tab gtTargetParent = (gpTarget != null) ? gpTarget.ParentTab : gcTarget as _Tab;
                    bool after          = side == _DockHow.TabAfter;
                    bool sameTargetTab  = false;

                    if (gtTargetParent != null)
                    {
                        gtTargetParent.AddOrReorderItem(gpThis, gpTarget, after);
                        if (gtThisParent == gtTargetParent)
                        {
                            sameTargetTab = true;
                        }
                    }
                    else
                    {
                        var gtNew = new _Tab(_manager, gsTargetParent, after ? gpTarget : gpThis, after ? gpThis : gpTarget);
                        gsTargetParent.ReplaceChild(gpTarget, gtNew);
                        gtNew.Bounds    = gpTarget.Bounds;
                        gtNew.CaptionAt = gpTarget.CaptionAt;
                    }

                    if (!sameTargetTab)
                    {
                        this.ParentSplit = gsTargetParent;
                        if (gtThisParent != null)
                        {
                            gtThisParent.OnItemRemoved(gpThis);
                        }
                        else
                        {
                            gsThisParent?.OnChildRemoved(this);
                        }
                    }
                }
                else
                {
                    if (gcTarget.IsTabbedPanel)
                    {
                        gcTarget = (gcTarget as _Panel).ParentTab;
                    }
                    bool after         = side == _DockHow.SplitRight || side == _DockHow.SplitBelow;
                    bool verticalSplit = side == _DockHow.SplitLeft || side == _DockHow.SplitRight;

                    if (gsTargetParent == gsThisParent && gtThisParent == null)
                    {
                        //just change vertical/horizontal or/and swap with sibling
                        gsThisParent.RepositionChild(this, verticalSplit, after);
                    }
                    else
                    {
                        var gsNew = new _Split(_manager, gsTargetParent, after ? gcTarget : this, after ? this : gcTarget, verticalSplit);
                        gsTargetParent.ReplaceChild(gcTarget, gsNew);
                        gsNew.Bounds = gcTarget.Bounds;

                        if (gtThisParent != null)
                        {
                            gpThis.ParentTab = null;
                            gtThisParent.OnItemRemoved(gpThis);
                        }
                        else
                        {
                            gsThisParent?.OnChildRemoved(this);
                        }
                    }
                }

                SetDockState(_DockState.Docked, false);
            }
Example #7
0
            internal _DockState SavedVisibleDockState;                 //when hidden, in what state to show

            internal _ContentNode(AuDockPanel manager, _Split parentSplit) : base(manager, parentSplit)
            {
                _parentControl = manager;
            }
Example #8
0
 internal _DummyNode(AuDockPanel manager, _Split parentSplit) : base(manager, parentSplit)
 {
     this.DockState = _DockState.Hidden;
 }
Example #9
0
        //Loads and parses XML. Creates the _aX lists, _firstSplit and the tree structure.
        void _LoadXmlAndCreateLayout(string xmlFileDefault, string xmlFileCustomized)
        {
            //We have 1 or 2 XML files containing panel/toolbar layout.
            //xmlFileDefault contains default XML. It eg can be in AFolders.ThisApp.
            //xmlFileCustomized contains previously saved XML (user-modified layout).
            //At first try to load xmlFileCustomized. If it does not exist or is invalid, load xmlFileDefault; or get missing data from xmlFileDefault, if possible.
            //Also loads xmlFileDefault when xmlFileCustomized XML does not match panels of new app version and cannot resolve it (eg some panels removed).
            bool   usesDefaultXML = false;
            string xmlFile = xmlFileCustomized, xmlVersion = null, outInfo = null;

            for (int i = 0; i < 2; i++)
            {
                if (i == 0)
                {
                    if (!AFile.ExistsAsFile(xmlFile))
                    {
                        continue;
                    }
                }
                else
                {
                    usesDefaultXML = true;
                    xmlFile        = xmlFileDefault;
                }

                bool fileLoaded = false;
                try {
                    var x = AExtXml.LoadElem(xmlFile);
                    fileLoaded = true;
                    if (!usesDefaultXML)
                    {
                        xmlVersion = x.Attr("version");
                    }
                    x = x.Element("split");

                    //THIS DOES THE MAIN JOB
                    _firstSplit = new _Split(this, null, x);

                    if (_aPanel.Count < _initControls.Count)                      //more panels added in this app version
                    {
                        if (usesDefaultXML)
                        {
                            throw new Exception("debug1");
                        }
                        _GetPanelXmlFromDefaultFile(xmlFileDefault);
                    }

                    break;

                    //speed: xml.Load takes 170 microseconds.
                    //tested: XML can be added to Application Settings, but var xml=Properties.Settings.Default.PanelsXML takes 61 MILLIseconds.
                }
                catch (Exception e) {
                    var sErr = $"Failed to load file '{xmlFile}'.\r\n\t{e.ToStringWithoutStack()}";
                    if (usesDefaultXML)
                    {
                        _xmlFile = null;
                        ADialog.ShowError("Cannot load panel/toolbar layout.", $"{sErr}\r\n\r\nReinstall the application.");
                        Environment.Exit(1);
                    }
                    else
                    {
                        //probably in this version there are less panels, most likely when downgraded. Or the file is corrupt.
                        if (fileLoaded && xmlVersion != _asmVersion)
                        {
                            outInfo = "Info: this application version resets the panel/toolbar layout, sorry.";
                        }
                        else
                        {
                            AWarning.Write(sErr, -1);
                        }
                    }
                    _aSplit.Clear(); _aTab.Clear(); _aPanel.Clear();
                }
            }

            //if(usesDefaultXML || xmlVersion == _asmVersion) return;
            if (outInfo != null)
            {
                AOutput.Write(outInfo);
            }
        }
Example #10
0
            int _width;             //used if !_isFraction; if _isWidth1, it is Child1 width, else Child2 with

            /// <summary>
            /// This ctor is used at startup, when adding from XML.
            /// </summary>
            internal _Split(AuDockPanel manager, _Split parentSplit, XElement x) : base(manager, parentSplit)
            {
                manager._aSplit.Add(this);

                if (!x.HasAttr("hor"))
                {
                    IsVerticalSplit = true;
                }
                int k = x.Attr("splitter", -1); if (k < 0 || k > 20)

                {
                    k = _splitterWidth;
                }

                this.SplitterWidth = k;

                //SHOULDDO: use DPI-dependent units, not pixels. Especially if form size depends on DPI.
                if (!(_isFraction = x.Attr(out _fraction, "f")) && !(_isWidth1 = x.Attr(out _width, "w1")))
                {
                    _width = x.Attr("w2", 1);
                }

                foreach (var xe in x.Elements())
                {
                    _Node gn = null;
                    switch (xe.Name.LocalName)
                    {
                    case "panel":
                        gn = new _Panel(manager, this, xe);
                        break;

                    case "split":
                        gn = new _Split(manager, this, xe);
                        break;

                    case "tab":
                        gn = new _Tab(manager, this, xe);
                        break;

                    case "dummy":
                        gn = new _DummyNode(_manager, this);
                        break;

                    default: continue;
                    }

                    if (gn.IsDocked)
                    {
                        _dockedChildCount++;
                    }

                    if (Child1 == null)
                    {
                        Child1 = gn;
                    }
                    else
                    {
                        Child2 = gn; break;
                    }
                }
                if (Child2 == null)
                {
                    throw new Exception();
                }

                if (_dockedChildCount == 0)
                {
                    this.DockState = _DockState.Hidden;
                }
            }