///////////////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Add pane.
        /// </summary>
        /// <param name="pane">Inserted pane.</param>
        public void Add(DockablePane pane)
        {
            if (null == _root)
            {
                _root = new Composition(null, pane); // first creation

                _ArrangeLayout();

                _RegisterDropService(pane);
            }
            else if (_root.IsInited && (null == _root.Find(pane)))
            {
                if (pane.UseSpecAllocation)
                    _root.AddSpec(pane, pane.DockType);
                else
                    _root.Add(pane, pane.DockType);

                _ArrangeLayout();

                _RegisterDropService(pane);
            }
        }
        /// <summary>
        /// Deserialize layout.
        /// </summary>
        /// <param name="manager">Dock manager for initing objects.</param>
        /// <param name="rootNode">Node to parse.</param>
        /// <param name="handlerObject">Delegate used to get user defined dockable contents.</param>
        public void Deserialize(DockManager manager,
                                XmlNode rootNode,
                                GetContentFromTypeString handlerObject)
        {
            if (null != _root)
            {
                Debug.Assert(_root.Type == CompositionType.Terminal);
                _root.AttachedPane.Close();
                _root = null;
            }

            if (0 == rootNode.ChildNodes.Count)
                _root = null;
            else
            {
                _root = new Composition();
                _root.Deserialize(manager, rootNode.ChildNodes[0], handlerObject);
                _ArrangeLayout();
            }
        }
        /// <summary>
        /// Remove pane.
        /// </summary>
        /// <param name="pane">Pane for identification.</param>
        public void Remove(DockablePane pane)
        {
            if (null != _root)
            {
                Debug.Assert(_root.IsInited);
                if (null != _root.Find(pane))
                {
                    bool isRemoved = false;
                    if (CompositionType.Terminal != _root.Type)
                        isRemoved = _root.Remove(pane);
                    else
                    {
                        if (_root.AttachedPane.Equals(pane))
                        {
                            _root = null;
                            isRemoved = true;
                        }
                        else
                        {
                            Debug.Assert(false); // not supported
                        }
                    }

                    if (isRemoved)
                        _ArrangeLayout();

                    _UnregisterDropService(pane);

                    // clearing margins
                    var margin = new Thickness(0);
                    pane.SetValue(FrameworkElement.MarginProperty, margin);
                }
            }
        }
        /// <summary>
        /// Create line composition
        /// </summary>
        private void _CreateLineComposition(Composition first, Composition second, Dock dockType)
        {
            _attachedPane = null;
            _type = _GetCompositionTypeByDock(dockType);

            _children.Add(first);
            _InsertElement2Line(second , dockType);
        }
 /// <summary>
 /// Insert new composition element by dock
 /// </summary>
 private void _InsertElement2Line(Composition newElement, Dock dockType)
 {
     if ((Dock.Left == dockType) || (Dock.Top == dockType))
         _children.Insert(0, newElement);
     else if ((Dock.Right == dockType) || (Dock.Bottom == dockType))
         _children.Add(newElement);
     else
     {
         Debug.Assert(false); // NOTE: not supported
     }
 }
        /// <summary>
        /// Add pane to composition
        /// </summary>
        private void _Add(DockablePane pane, Dock dockType)
        {
            Composition newElement = new Composition(this, pane);
            if (CompositionType.Terminal == _type)
            {   // change compostion from terminal to linear
                Debug.Assert(0 == _children.Count);

                Composition first = new Composition(this, _attachedPane);
                _CreateLineComposition(first, newElement, dockType);
            }
            else
            {
                if (_DoesAdding2Line(dockType))
                {   // add new element to linear composition

                    // update children space factors
                    // new child - requared 50% of all layout
                    for (int index = 0; index < _children.Count; ++index)
                        _children[index].SpaceFactor /= 2;

                    _InsertElement2Line(newElement, dockType);
                }
                else
                {
                    // do copy from current composition - it is linear composition
                    Composition compositionCopy = _CreateCopy();
                    // remove old composition elements
                    _children.Clear();
                    // do one linear composition:
                    // add old elements as one linear composition and
                    // add new element to linear composition
                    _CreateLineComposition(compositionCopy, newElement, dockType);
                }
            }

            Debug.Assert(_IsNormalized());
        }
        /// <summary>
        /// Do copy of this composition
        /// </summary>
        private Composition _CreateCopy()
        {
            Composition obj = new Composition();
            obj._children.AddRange(this._children);
            obj._type = this._type;
            obj._attachedPane = this._attachedPane;
            obj._isInited = this._isInited;

            return obj;
        }
        public void Add(DockablePane pane, DockablePane relativePane, Dock relativeDock)
        {
            if (!_isInited)
                return;

            _CalculateSpaceFactors();

            if (CompositionType.Terminal == _type)
            {
                if (_attachedPane.Equals(relativePane))
                    _Add(pane, relativeDock);
            }
            else
            {
                // find relative terminal element index
                int relativeIndex = -1;
                for (int index = 0; index < _children.Count; ++index)
                {
                    Composition currentComposition = _children[index];
                    if (CompositionType.Terminal == currentComposition.Type)
                    {
                        if (currentComposition.AttachedPane.Equals(relativePane))
                        {
                            relativeIndex = index;
                            break; // NOTE: founded
                        }
                    }
                    else
                        currentComposition.Add(pane, relativePane, relativeDock);
                }

                // add new item
                if (-1 != relativeIndex)
                {
                    if (_DoesAdding2Line(relativeDock))
                    {   // add new item to current linear composition
                        // left\top insert to relative position, other - insert after relive

                        Composition newComposition = new Composition(this, pane);

                        _children[relativeIndex].SpaceFactor *= DEFAULT_SPACE_FACTOR; // new child requared part of relative pane
                        newComposition.SpaceFactor = _children[relativeIndex].SpaceFactor;

                        int insertIndex = ((Dock.Left == relativeDock) || (Dock.Top == relativeDock)) ?
                                            relativeIndex : relativeIndex + 1;
                        _children.Insert(insertIndex, newComposition);
                    }
                    else
                    {   // add new pane to terminal composition
                        _children[relativeIndex].Add(pane, relativeDock);
                    }
                }

                Debug.Assert(_IsNormalized());
            }
        }
        /// <summary>
        /// Deserialize layout
        /// </summary>
        /// <param name="manager">Dock manager for initing objects</param>
        /// <param name="node">Node to parse</param>
        /// <param name="handlerObject">Delegate used to get user defined dockable contents</param>
        public void Deserialize(DockManager manager, XmlNode node, GetContentFromTypeString handlerObject)
        {
            _type = (CompositionType)Enum.Parse(typeof(CompositionType), node.Attributes[ATTRIBUTE_NAME_TYPE].Value);
            _spaceFactor = double.Parse(node.Attributes[ATTRIBUTE_NAME_SFACTOR].Value, CultureInfo.GetCultureInfo(STORAGE_CULTURE));

            if (_type == CompositionType.Terminal)
            {
                Debug.Assert(node.ChildNodes[0].Name == ELEMENT_NAME_DOCKPANE);

                DockablePane pane = new DockablePane();
                pane.Deserialize(manager, node.ChildNodes[0], handlerObject);
                _attachedPane = pane;

                if (pane.IsDragSupported)
                    manager.DragPaneServices.Register(pane);
            }
            else
            {
                Debug.Assert(node.ChildNodes[0].Name == ELEMENT_NAME_CHILDGROUPS);

                foreach (XmlNode nodeChild in node.ChildNodes[0].ChildNodes)
                {
                    Composition composition = new Composition();
                    composition.Deserialize(manager, nodeChild, handlerObject);
                    _children.Add(composition);
                }
            }

            _isInited = true;
        }
 public Composition(Composition parent, DockablePane pane)
 {
     _attachedPane = pane;
     _type = CompositionType.Terminal;
     _isInited = true;
 }
 public Composition(Composition parent, Composition first, Composition second, Dock dockType)
 {
     _CreateLineComposition(first, second, dockType);
     _isInited = true;
 }
Beispiel #12
0
 public Composition(Composition parent, Composition first, Composition second, Dock dockType)
 {
     _CreateLineComposition(first, second, dockType);
     _isInited = true;
 }
Beispiel #13
0
 public Composition(Composition parent, DockablePane pane)
 {
     _attachedPane = pane;
     _type         = CompositionType.Terminal;
     _isInited     = true;
 }
Beispiel #14
0
        /// <summary>
        /// Calculation space factors
        /// </summary>
        private void _CalculateSpaceFactors()
        {
            Size fullSize = _CalculateSpaceSize();

            if ((fullSize.Height <= 0.0) && (fullSize.Height == fullSize.Width))
            {
                return; // NOTE: exit
            }
            // minimal factor - page have min size
            double minFactor = (_type == CompositionType.Horizontal)?
                               (DockablePane.MIN_PANE_SIZE / Math.Max(fullSize.Height, 1)) :
                               (DockablePane.MIN_PANE_SIZE / Math.Max(fullSize.Width, 1));

            double increaseFactorValue = 0; // pages with min size increase with this value

            for (int index = 0; index < _children.Count; ++index)
            {
                Composition child     = _children[index];
                Size        childSize = child._CalculateSpaceSize();

                double newScale = (_type == CompositionType.Horizontal) ?
                                  (childSize.Height / Math.Max(fullSize.Height, 1)) :
                                  (childSize.Width / Math.Max(fullSize.Width, 1));
                // reset tinkle - 1%
                if (SPACE_FACTOR_TINKLE < Math.Abs(child.SpaceFactor - newScale))
                {
                    child.SpaceFactor = newScale;
                }

                if (child.SpaceFactor < minFactor)
                {
                    increaseFactorValue += minFactor - child.SpaceFactor;
                    child.SpaceFactor    = minFactor;
                }
            }

            // normalize factors - sum probably SPACE_FACTOR_FULL
            double sumFactor = 0.0;

            if (0 < increaseFactorValue)
            {
                // find count of pages for decreasing
                int decreaseCount = 0;
                for (int index = 0; index < _children.Count; ++index)
                {
                    if (minFactor + increaseFactorValue < _children[index].SpaceFactor)
                    {
                        ++decreaseCount;
                    }
                }

                // decrease big pages
                double decreaseFactor = increaseFactorValue / decreaseCount;
                for (int index = 0; index < _children.Count; ++index)
                {
                    Composition child = _children[index];
                    if (minFactor + decreaseFactor < child.SpaceFactor)
                    {
                        child.SpaceFactor -= decreaseFactor;
                    }

                    sumFactor += child.SpaceFactor;
                }
            }
            else
            {
                // callculate sum factors
                for (int index = 0; index < _children.Count; ++index)
                {
                    sumFactor += _children[index].SpaceFactor;
                }
            }

            _NormalizeSpaceFactors(sumFactor);
        }
Beispiel #15
0
        /// <summary>
        /// Remove pane
        /// </summary>
        public bool Remove(DockablePane pane)
        {
            if (!_isInited)
            {
                return(false);
            }

            Debug.Assert(CompositionType.Terminal != _type);

            _CalculateSpaceFactors();

            bool isRemoved = false;

            // find terminal element to deleting
            Composition terminalComposition2Delete = null;

            for (int index = 0; index < _children.Count; ++index)
            {
                Composition currentComposition = _children[index];
                if (CompositionType.Terminal == currentComposition.Type)
                {
                    if (currentComposition.AttachedPane.Equals(pane))
                    {
                        terminalComposition2Delete = currentComposition;
                        break; // NOTE: founded
                    }
                }
                else
                {   // remove from child composition
                    if (currentComposition.Remove(pane))
                    {
                        isRemoved = true;
                        break;
                    }
                }
            }

            // remove terminal element
            if (null != terminalComposition2Delete)
            {
                _children.Remove(terminalComposition2Delete);
                isRemoved = true;

                if (1 == _children.Count)
                {   // change state to terminal
                    Composition lastChield = _children[0];
                    _children.Clear();
                    if (CompositionType.Terminal == lastChield.Type)
                    {
                        _type         = CompositionType.Terminal;
                        _attachedPane = lastChield.AttachedPane;
                    }
                    else
                    {
                        _type = lastChield.Type;
                        ICollection <Composition> children = lastChield.Children;
                        foreach (Composition child in children)
                        {
                            _children.Add(child);
                        }
                    }
                }
                else
                {
                    // recalculate new space factors
                    Size   sz       = _CalculateSpaceSize();
                    double fullSize = (_type == CompositionType.Horizontal) ? sz.Height : sz.Width;
                    fullSize += SPLITTER_SIZE;

                    double splitterFree = SPLITTER_SIZE / _children.Count;

                    Size freeSize = terminalComposition2Delete._CalculateSpaceSize();
                    for (int index = 0; index < _children.Count; ++index)
                    {
                        Composition child     = _children[index];
                        Size        childSize = child._CalculateSpaceSize();
                        child.SpaceFactor = (_type == CompositionType.Horizontal) ?
                                            ((childSize.Height + freeSize.Height * child.SpaceFactor + splitterFree) / Math.Max(fullSize, 1)) :
                                            ((childSize.Width + freeSize.Width * child.SpaceFactor + splitterFree) / Math.Max(fullSize, 1));
                    }
                }
            }
            else if (isRemoved)
            {   // normalize composition - if child presented as one line
                for (int index = 0; index < _children.Count; ++index)
                {
                    Composition currentChild = _children[index];
                    if (currentChild.Type == _type)
                    {
                        ICollection <Composition> children = currentChild.Children;
                        Debug.Assert(currentChild.Type != CompositionType.Terminal);
                        Debug.Assert(1 < currentChild.Children.Count);

                        Collection <Composition> fromRemoved = new Collection <Composition> ();
                        foreach (Composition child in children)
                        {
                            fromRemoved.Add(child);
                        }

                        _children.Remove(currentChild);
                        _children.InsertRange(index, fromRemoved);
                    }
                }

                _CalculateSpaceFactors();
            }

            Debug.Assert(_IsNormalized());
            return(isRemoved);
        }
Beispiel #16
0
        public void Add(DockablePane pane, DockablePane relativePane, Dock relativeDock)
        {
            if (!_isInited)
            {
                return;
            }

            _CalculateSpaceFactors();

            if (CompositionType.Terminal == _type)
            {
                if (_attachedPane.Equals(relativePane))
                {
                    _Add(pane, relativeDock);
                }
            }
            else
            {
                // find relative terminal element index
                int relativeIndex = -1;
                for (int index = 0; index < _children.Count; ++index)
                {
                    Composition currentComposition = _children[index];
                    if (CompositionType.Terminal == currentComposition.Type)
                    {
                        if (currentComposition.AttachedPane.Equals(relativePane))
                        {
                            relativeIndex = index;
                            break; // NOTE: founded
                        }
                    }
                    else
                    {
                        currentComposition.Add(pane, relativePane, relativeDock);
                    }
                }

                // add new item
                if (-1 != relativeIndex)
                {
                    if (_DoesAdding2Line(relativeDock))
                    {   // add new item to current linear composition
                        // left\top insert to relative position, other - insert after relive

                        Composition newComposition = new Composition(this, pane);

                        _children[relativeIndex].SpaceFactor *= DEFAULT_SPACE_FACTOR; // new child requared part of relative pane
                        newComposition.SpaceFactor            = _children[relativeIndex].SpaceFactor;

                        int insertIndex = ((Dock.Left == relativeDock) || (Dock.Top == relativeDock)) ?
                                          relativeIndex : relativeIndex + 1;
                        _children.Insert(insertIndex, newComposition);
                    }
                    else
                    {   // add new pane to terminal composition
                        _children[relativeIndex].Add(pane, relativeDock);
                    }
                }

                Debug.Assert(_IsNormalized());
            }
        }