Example #1
0
File: _Tab.cs Project: alexfordc/Au
 /// <summary>
 /// Sets ActiveItem, shows its contents, hides previous ActiveItem contents, invalidate caption, calls DockedDocumentPanelActivated event.
 /// </summary>
 /// <param name="gp">Can be null to deactivate all.</param>
 /// <param name="focusControl"></param>
 internal void SetActiveItem(_Panel gp, bool focusControl = false)
 {
     _AssertIsDockedChildOrNull(gp);
     if (focusControl)
     {
         focusControl = gp.Focusable;
     }
     if (gp != this.ActiveItem)
     {
         var ai = this.ActiveItem;
         this.ActiveItem = gp;
         gp?.Content.Show();
         var oldCont = ai?.Content;
         if (focusControl)
         {
             gp.Content?.Focus();
         }
         else if (_manager.ZFocusControlOnUndockEtc != null && (oldCont?.ContainsFocus ?? false))
         {
             _manager.ZFocusControlOnUndockEtc.Focus();
         }
         oldCont?.Hide();
         this.InvalidateCaption();
     }
     else if (focusControl)
     {
         gp.Content?.Focus();
     }
 }
Example #2
0
File: _Tab.cs Project: alexfordc/Au
 void _AssertIsDockedChildOrNull(_Panel gp)
 {
     if (gp != null)
     {
         _AssertIsDockedChild(gp);
     }
 }
Example #3
0
File: _Tab.cs Project: alexfordc/Au
            internal void OnItemUndocked(_Panel gp, out Action postAction)
            {
                postAction = null;
                _AssertIsChild(gp);
                Debug.Assert(_dockedItemCount > 0);

                if (--_dockedItemCount < 1)
                {
                    this.SetActiveItem(null);
                    postAction = () => SetDockState(_DockState.Hidden);
                    return;
                }

                if (gp == this.ActiveItem)
                {
                    this.SetActiveItem(this.Items.Find(v => v != gp && v.IsDocked));
                }

                //if this is floating, and just 1 other docked item left, dock this. Else would be problems.
                if (_dockedItemCount == 1 && this.IsFloating)
                {
                    postAction = () => SetDockState(_DockState.Docked);                     //because this func is called by SetDockState, it must execute postAction later
                    return;
                }

                this.InvalidateCaption();
            }
Example #4
0
File: _Tab.cs Project: alexfordc/Au
            internal int IndexOf(_Panel gp)
            {
                int i = this.Items.IndexOf(gp);

                Debug.Assert(i >= 0);
                return(i);
            }
Example #5
0
            void _ChangeParent(_Panel panel, Control parent)
            {
                panel._parentControl = parent;
                var content = panel.Content;

                content.Parent = parent;

                //restore tooltips
                if ((content is UserControl uc) && (uc.GetType().GetField("components", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(uc) is IContainer co))
                {
                    foreach (var tt in co.Components.OfType <ToolTip>())
                    {
                        _Controls(uc);
                        void _Controls(Control parent)
                        {
                            foreach (Control c in parent.Controls)
                            {
                                var s = tt.GetToolTip(c);
                                if (!s.NE())
                                {
                                    //AOutput.Write($"<>{c}, <c blue>{s}<>");
                                    tt.SetToolTip(c, null);
                                    tt.SetToolTip(c, s);
                                }
                                _Controls(c);
                            }
                        }
                    }
                }
            }
Example #6
0
File: _Tab.cs Project: alexfordc/Au
            /// <summary>
            /// If gp is child of this, moves it to the place before or after target (a child of this).
            /// Else just inserts gp there.
            /// If target is null, adds to the end (does nothing if gp is child).
            /// Does not update layout.
            /// </summary>
            internal void AddOrReorderItem(_Panel gp, _Panel target, bool after)
            {
                bool gpIsChild = _IsChild(gp);

                if (target == null)
                {
                    if (!gpIsChild)
                    {
                        this.Items.Add(gp);
                    }
                }
                else
                {
                    _AssertIsChild(target);
                    int iTo = this.IndexOf(target);
                    if (after)
                    {
                        iTo++;
                    }
                    if (gpIsChild)
                    {
                        int iFrom = this.IndexOf(gp);
                        if (iFrom < iTo)
                        {
                            iTo--;
                        }
                        this.Items.RemoveAt(iFrom);
                    }
                    this.Items.Insert(iTo, gp);
                }
                gp.ParentTab = this;
            }
Example #7
0
                /// <summary>
                /// Returns a half of r (gp full caption, not just tab button), depending on where p is (even if not in r).
                /// Sets _target.side.
                /// </summary>
                RECT _CalcNewTabButtonRectInFullCaption(_Panel gp, RECT r, Point p)
                {
                    bool after;

                    if (gp.IsVerticalCaption)
                    {
                        int mid = (r.top + r.bottom) / 2;
                        if (after = (p.Y >= mid))
                        {
                            r.top = mid;
                        }
                        else
                        {
                            r.bottom = mid;
                        }
                    }
                    else
                    {
                        int mid = (r.left + r.right) / 2;
                        if (after = (p.X >= mid))
                        {
                            r.left = mid;
                        }
                        else
                        {
                            r.right = mid;
                        }
                    }
                    _target.side = after ? _DockHow.TabAfter : _DockHow.TabBefore;
                    return(r);
                }
Example #8
0
 void _UnhiliteTabButton()
 {
     if (_hilitedTabButton == null)
     {
         return;
     }
     _hilitedTabButton.InvalidateCaption();
     _hilitedTabButton = null;
 }
Example #9
0
File: _Tab.cs Project: alexfordc/Au
 internal void OnMouseDownTabButton(_Panel gp, MouseButtons mb)
 {
     _AssertIsChild(gp);
     if (!gp.IsDocked)
     {
         return;
     }
     //if(mb == MouseButtons.Left)
     SetActiveItem(gp, true);
 }
Example #10
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 #11
0
File: _Tab.cs Project: alexfordc/Au
 internal void OnItemDocked(_Panel gp, bool setActive = true)
 {
     _AssertIsChild(gp);
     if (this.IsHidden)
     {
         SetDockState(_DockState.Docked);
     }
     _dockedItemCount++;
     UpdateLayout();
     if (setActive || _dockedItemCount == 1)
     {
         SetActiveItem(gp);
     }
 }
Example #12
0
File: _Tab.cs Project: alexfordc/Au
            /// <summary>
            /// Removes a child panel from Items.
            /// If single item left, moves it to this parent and invalidates/removes this.
            /// </summary>
            internal void OnItemRemoved(_Panel gp)
            {
                _AssertIsChild(gp);
                Debug.Assert(this.Items.Count > 1);
                this.Items.Remove(gp);
                if (this.Items.Count > 1)
                {
                    return;
                }

                var gpLast = this.Items[0];

                gpLast.ParentTab = null;
                this.ParentSplit.ReplaceChild(this, gpLast);
#if DEBUG
                this.Items = null;                 //to catch invalid usage of this after calling this function
#endif
                _manager._aTab.Remove(this);
            }
Example #13
0
        void _GetPanelXmlFromDefaultFile(string defFile)
        {
            var xml = AExtXml.LoadElem(defFile);

            foreach (var c in _initControls.Values)
            {
                if (_aPanel.Exists(v => v.Content == c))
                {
                    continue;
                }
                var x  = xml.Desc("panel", "name", c.Name);
                var gp = new _Panel(this, null, x)
                {
                    DockState             = _DockState.Hidden,
                    SavedVisibleDockState = _DockState.Floating
                };
                c.Visible = false;
                AOutput.Write($"Info: new {(gp.HasToolbar ? "toolbar" : "panel")} '{gp.Text}' added in this aplication version. Currently it is hidden.");
            }
        }
Example #14
0
        //This worked, but better don't use.
        //Instead, if panels added/removed/changed in new version, now automatically uses data from the default XML file.
        /// <summary>
        /// Creates new _Panel and adds it by the panel of control cBy, to an existing or new tab group or split.
        /// Does nothing if c is already added.
        /// The new panel settings will be saved to the XML file.
        /// Call this ater Create() when the new version of your app wants to add more panels without replacing the old XML (user-modified).
        /// You can simply always call this function for all panels added in new versions (it does nothing if called not first time). Or call it once, eg if FindPanel() returns false for that control.
        /// Also in new versions always pass the control to Create() too; it just ignores it if there is still no XML element for it.
        /// </summary>
        /// <param name="c">Control of the new _Panel.</param>
        /// <param name="cBy">Add the new panel by the panel of this control.</param>
        /// <param name="side">Specifies whether to add in a tab group or split, and at which side of cBy.</param>
        /// <param name="xml">XML containing single element that stores panel settings, eg "&lt;panel text='Results' tooltip='Find results' image='15' hide='' /&gt;".</param>
        public void ZAddPanel(Control c, Control cBy, DockSide side, string xml)
        {
            if (_FindPanel(c) != null)
            {
                return;
            }

            this.Controls.Add(c);

            var  xdoc = XElement.Load(xml);
            var  gp   = new _Panel(c, this, null, xdoc);
            bool hide = gp.IsHidden; gp.DockState = DockState.Hidden;
            var  gpBy = _FindPanel(cBy);

            gp.DockBy(gpBy, side, true);
            if (hide)
            {
                gp.Hide();
            }

            //not tested when cBy panel is hidden or floating
        }
Example #15
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 #16
0
File: _Tab.cs Project: alexfordc/Au
 void _AssertIsDockedChild(_Panel gp)
 {
     Debug.Assert(_IsChild(gp));
     Debug.Assert(gp.IsDocked);
 }
Example #17
0
File: _Tab.cs Project: alexfordc/Au
 void _AssertIsChild(_Panel gp)
 {
     Debug.Assert(_IsChild(gp));
 }
Example #18
0
File: _Tab.cs Project: alexfordc/Au
 bool _IsChild(_Panel gp)
 {
     return(this.Items.IndexOf(gp) >= 0);
 }
Example #19
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;
                }
            }