コード例 #1
0
        /// <summary> handle the drag of the splitter
        /// and update the org size
        /// </summary>
        /// <param name="event">
        /// </param>
        internal void onSplitterMoving(Splitter splitter, SplitterEventArgs e)
        {
            MgSplitContainer mgSplitContainer = (MgSplitContainer)splitter.Parent;

            mgSplitContainer.IgnoreLayout = true;

            int shift = 0;
            int beforeControlminimumSize = 0;
            int afterControlminimumSize  = 0;

            // Rectangle splitterBounds - get the bound of the selected splitter- the new bound after the resize
            Rectangle boundsSelectedSplitter = splitter.Bounds;
            // check only when there is movement in the Splitter place
            bool isHorizontal = mgSplitContainer.getOrientation() == MgSplitContainer.SPLITTER_STYLE_HORIZONTAL;

            if ((isHorizontal && e.SplitX == boundsSelectedSplitter.X) || (!isHorizontal && e.SplitY == boundsSelectedSplitter.Y))
            {
                mgSplitContainer.IgnoreLayout = false;
                return;
            }

            int SplitterIndex = -1;

            // found the Splitter that was selected in the array Splitter
            for (int i = 0; i < mgSplitContainer.Splitters.Count; i++)
            {
                if (mgSplitContainer.Splitters[i] == splitter)
                {
                    SplitterIndex = i;
                    break;
                }
            }
            // if not found return
            if (SplitterIndex == -1)
            {
                mgSplitContainer.IgnoreLayout = false;
                return;
            }
            Control[] controls = mgSplitContainer.getControls(true);

            // fixed bug#:769214
            if (controls.Length <= SplitterIndex + 1)
            {
                mgSplitContainer.IgnoreLayout = false;
                return;
            }

            // get the control BEFORE the selected Splitter from the control array
            Control controlBefore = controls[SplitterIndex];
            // get the control AFTER the selected Splitter from the control array
            Control controlAfter = controls[SplitterIndex + 1];

            // get the minimum size of the before\After control
            MinSizeInfo beforeControlMinSizeInfo = GuiUtils.getMinSizeInfo(controlBefore);
            MinSizeInfo afterControlMinSizeInfo  = GuiUtils.getMinSizeInfo(controlAfter);
            Point       minSize;

            if (beforeControlMinSizeInfo != null)
            {
                minSize = beforeControlMinSizeInfo.getMinSize(false);
                beforeControlminimumSize = isHorizontal ? minSize.X : minSize.Y;
            }
            if (afterControlMinSizeInfo != null)
            {
                minSize = afterControlMinSizeInfo.getMinSize(false);
                afterControlminimumSize = isHorizontal ? minSize.X : minSize.Y;
            }

            // get the bounds of the two controls
            Rectangle beforeControlBounds = new Rectangle(controlBefore.Bounds.Location.X,
                                                          controlBefore.Bounds.Location.Y,
                                                          controlBefore.Bounds.Size.Width,
                                                          controlBefore.Bounds.Size.Height);
            Rectangle afterControlBounds = new Rectangle(controlAfter.Bounds.Location.X,
                                                         controlAfter.Bounds.Location.Y,
                                                         controlAfter.Bounds.Size.Width,
                                                         controlAfter.Bounds.Size.Height);

            ////do the movement
            if (isHorizontal)
            {
                // found the allow shift until the minimum size
                shift = getShift(mgSplitContainer, e, boundsSelectedSplitter, beforeControlBounds, beforeControlminimumSize, afterControlBounds, afterControlminimumSize);
                if (shift == 0)
                {
                    return;
                }
                else
                {
                    // update the bounds of the Splitter control by the shift value
                    beforeControlBounds.Width += shift;
                    afterControlBounds.X      += shift;
                    afterControlBounds.Width  -= shift;

                    e.SplitX = beforeControlBounds.Width;

                    setOrgSize(mgSplitContainer, controlBefore, beforeControlBounds, controlAfter, afterControlBounds);
                }
            }
            else
            {
                // found the allow shift until the minimum size
                shift = getShift(mgSplitContainer, e, boundsSelectedSplitter, beforeControlBounds, beforeControlminimumSize, afterControlBounds, afterControlminimumSize);
                if (shift == 0)
                {
                    return;
                }
                else
                {
                    // update the bounds of the Splitter control by the shift value
                    beforeControlBounds.Height += shift;
                    afterControlBounds.Y       += shift;
                    afterControlBounds.Height  -= shift;

                    setOrgSize(mgSplitContainer, controlBefore, beforeControlBounds, controlAfter, afterControlBounds);
                }
            }
        }
コード例 #2
0
        /// <summary>
        /// </summary>
        /// <param name="container"></param>
        /// <param name="layoutEventArgs"></param>
        /// <returns></returns>
        public override bool Layout(object composite, LayoutEventArgs layoutEventArgs)
        {
            /// <summary> layout the MgSplitContainer and all his children</summary>
            //protected internal void layout(Composite composite, bool flushCache)
            //{
            MgSplitContainer mgSplitContainer = (MgSplitContainer)composite;

            //Sometime we need to ignore the layout, when we doing move to control
            if (mgSplitContainer.IgnoreLayout)
            {
                return(true);
            }

            double[] ratios       = null;
            int      totalOrgSize = 0;

            Rectangle clientArea = mgSplitContainer.ClientRectangle;

            if (clientArea.Width <= 1 || clientArea.Height <= 1)
            {
                return(false);
            }

            // get the controls on the mgSplitContainer (without the splitter, and only the visible)
            Control[] controls = mgSplitContainer.getControls(false);
            if (controls.Length == 0)
            {
                return(false);
            }
            //      if (allControlsHaveBounds(controls) == false)
            //         return;

            // check the splitter controls
            // checkSplitterControls(MgSplitContainer, controls);

            // check the direction shell was reduce or increased
            bool      parentReduced  = false;
            Rectangle lastClientArea = mgSplitContainer.LastClientArea;

            if (clientArea.Width < lastClientArea.Width || clientArea.Height < lastClientArea.Height)
            {
                parentReduced = true;
            }
            ((TagData)mgSplitContainer.Tag).RepaintRect = lastClientArea;

            // save the last client Area, for the next time
            mgSplitContainer.LastClientArea = GuiUtils.copyRect(clientArea);

            // get the array to the splitter controls
            Splitter[] splitters = new Splitter[mgSplitContainer.Splitters.Count];
            for (int i = 0; i < mgSplitContainer.Splitters.Count; i++)
            {
                Splitter s = mgSplitContainer.Splitters[i];
                splitters[i] = s;
            }

            //MOVE TO mgSplitContainer!!!
            // for the out most MgSplitContainer form we need to change the client rect, not to include the offset
            if (GuiUtils.isOutmostMgSplitContainer(mgSplitContainer))
            {
                clientArea.X      += (MgSplitContainer.SPLITTER_WIDTH / 2);
                clientArea.Y      += (MgSplitContainer.SPLITTER_WIDTH / 2);
                clientArea.Width  -= MgSplitContainer.SPLITTER_WIDTH;
                clientArea.Height -= MgSplitContainer.SPLITTER_WIDTH;
            }

            // check if we need to update the original size at the end of the method?
            bool saveSizeAtTheEnd = ratiosWillChange(parentReduced, mgSplitContainer.getOrientation(), controls);

            bool checkPlacement   = true;
            bool checkMinimumSize = parentReduced;
            bool calcByMinSize    = true;

            // get the dynamic client area by checking the placement & minimum size(only when we decrease)
            int areaS = calcAreaS(mgSplitContainer, clientArea, controls, splitters, checkPlacement, checkMinimumSize, false);

            // get the total minimum size by checking the placement & minimum size(only when we decrease)
            int totalMinimumSize = getTotalSizeOfControls(controls, mgSplitContainer.getOrientation(), true, calcByMinSize, checkPlacement, checkMinimumSize);

            // flag to set if we ignore the minimum size: Minimum size is ignored when
            // 1. increasing the size
            // or
            // 2. reducing the size and the total minimum size is greater than the dynamic client area
            //    and when we not on outmost MgSplitContainer
            bool ignoreMinSize = false;

            if (!GuiUtils.isOutmostMgSplitContainer(mgSplitContainer) && !GuiUtils.isDirectChildOfOutmostMgSplitContainer(mgSplitContainer))
            {
                ignoreMinSize = true;
            }

            checkPlacement   = false;
            checkMinimumSize = false;
            calcByMinSize    = false;
            if (areaS > 0)
            {
                if (!parentReduced)
                {
                    output(mgSplitContainer.getOrientation(), "Area ", "1");
                    // Check the placement property and ignore the minimum size
                    ignoreMinSize    = true;
                    checkPlacement   = true;
                    checkMinimumSize = false;
                }
                else if (areaS < totalMinimumSize)
                // parentReduced is true
                {
                    output(mgSplitContainer.getOrientation(), "Area ", "2");
                    // when reduce and the dynamic client area is > total minimum size we need to ignore also the
                    // placement and the minimum size, all the controls will be in the resize
                    ignoreMinSize    = true;
                    checkPlacement   = false;
                    checkMinimumSize = false;
                }
                else
                {
                    output(mgSplitContainer.getOrientation(), "Area ", "3");
                    // when parentReduced && areaS > totalMinimumSize, check the placement and minimum size
                    checkPlacement   = true;
                    checkMinimumSize = true;
                }
            }
            // If the dynamic client area is little than or equal to zero then
            // if (areaS <= 0)
            else
            {
                output(mgSplitContainer.getOrientation(), "Area ", "<0");
                output(mgSplitContainer.getOrientation(), "areaS < totalMinimumSize? ", " " + (areaS < totalMinimumSize));

                // when we on outmost MgSplitContainer :use the minimum sizes as the weights.
                if (GuiUtils.isOutmostMgSplitContainer(mgSplitContainer))
                {
                    Debug.Assert(false);
                    // output(mgSplitContainer.getOrientation(), "calByMinSize ", " " + calcByMinSize);
                    // checkPlacement = false;
                    // checkMinimumSize = false;
                    // calcByMinSize = true;
                }
                // when we not in outmost MgSplitContainer :save the size in the org size and cal with ignore all the
                // placemetn & min size
                // if (!GuiUtils.isOutmostMgSplitContainer(mgSplitContainer))
                else
                {
                    output(mgSplitContainer.getOrientation(), "calByMinSize ", " " + calcByMinSize);
                    checkPlacement   = false;
                    checkMinimumSize = false;
                    calcByMinSize    = false;
                }
            }

            // get the dynamic client area according to the init members
            areaS = calcAreaS(mgSplitContainer, clientArea, controls, splitters, checkPlacement, checkMinimumSize, calcByMinSize);
            // get the total size according to the init members
            totalOrgSize = getTotalSizeOfControls(controls, mgSplitContainer.getOrientation(), true, calcByMinSize, checkPlacement, checkMinimumSize);
            // get the ratios according to the init members
            ratios = calcRatios(controls, mgSplitContainer.getOrientation(), totalOrgSize, checkPlacement, checkMinimumSize, calcByMinSize, areaS, ref saveSizeAtTheEnd);

            output(mgSplitContainer.getOrientation(), "areaS ", " " + areaS);

            // 6. order the controls and splitters
            //TODOR: border is all the time 0 // int splitterWidth = splitters.Length > 0 ? MgSplitContainer.SPLITTER_WIDTH + splitters[0].getBorderWidth() * 2 : MgSplitContainer.SPLITTER_WIDTH;
            int splitterWidth = MgSplitContainer.SPLITTER_WIDTH;

            if (mgSplitContainer.getOrientation() == MgSplitContainer.SPLITTER_STYLE_HORIZONTAL)
            {
                int width = ratios[0] != -1 ? (int)(areaS * ratios[0]) : getOrgSize(controls[0]).X;
                if (!ignoreMinSize)
                {
                    width = Math.Max(width, getMinimunSize(controls[0]).X);
                }
                int x = clientArea.X;

                // fixed bug #:293109, while the user is do resize we need to save te bound
                GuiUtils.controlSetBounds(controls[0], x, clientArea.Y, (int)width, clientArea.Height);
                SetNewSaveBound(controls[0], x, clientArea.Y, (int)width, clientArea.Height);

                x += width;

                if (controls.Length > 1)
                {
                    ((TagData)splitters[splitters.Length - 1].Tag).RepaintRect = splitters[splitters.Length - 1].Bounds;
                    GuiUtils.controlSetBounds(splitters[splitters.Length - 1], x, clientArea.Y, splitterWidth, clientArea.Height);
                    x    += splitterWidth;
                    width = clientArea.Width - (x - clientArea.X);
                    if (!ignoreMinSize)
                    {
                        width = Math.Max(width, getMinimunSize(controls[controls.Length - 1]).X);
                    }

                    GuiUtils.controlSetBounds(controls[controls.Length - 1], x, clientArea.Y, width, clientArea.Height);
                    SetNewSaveBound(controls[controls.Length - 1], x, clientArea.Y, width, clientArea.Height);
                }
            }
            else if (mgSplitContainer.getOrientation() == MgSplitContainer.SPLITTER_STYLE_VERTICAL)
            {
                int height = ratios[0] != -1 ? (int)(areaS * ratios[0]) : getOrgSize(controls[0]).Y;
                if (!ignoreMinSize)
                {
                    height = Math.Max(height, getMinimunSize(controls[0]).Y);
                }

                int y = clientArea.Y;
                GuiUtils.controlSetBounds(controls[0], clientArea.X, clientArea.Y, clientArea.Width, height);
                SetNewSaveBound(controls[0], clientArea.X, clientArea.Y, clientArea.Width, height);
                y += height;

                if (controls.Length > 1)
                {
                    ((TagData)splitters[splitters.Length - 1].Tag).RepaintRect = splitters[splitters.Length - 1].Bounds;
                    GuiUtils.controlSetBounds(splitters[splitters.Length - 1], clientArea.X, y, clientArea.Width, splitterWidth);
                    SetNewSaveBound(splitters[splitters.Length - 1], clientArea.X, y, clientArea.Width, splitterWidth);

                    y     += splitterWidth;
                    height = clientArea.Height - (y - clientArea.Y);
                    if (!ignoreMinSize)
                    {
                        height = Math.Max(height, getMinimunSize(controls[controls.Length - 1]).Y);
                    }
                    GuiUtils.controlSetBounds(controls[controls.Length - 1], clientArea.X, y, clientArea.Width, height);
                    SetNewSaveBound(controls[controls.Length - 1], clientArea.X, y, clientArea.Width, height);
                }
            }

            if (saveSizeAtTheEnd)
            {
                for (int k = 0; k < controls.Length; k++)
                {
                    Rectangle rect = controls[k].Bounds;
                    setOrgSizeBy(controls[k], rect.Width, rect.Height);
                }
            }

            return(true);
        }