コード例 #1
0
        /// <summary>
        /// update the movement value according the dimension placement value.
        ///  copies from ctrl.cpp updateMoveValue
        /// </summary>
        /// <param name="placementData"></param>
        /// <param name="actualMove"></param>
        /// <param name="placementDim"></param>
        /// <returns></returns>
        static int updateMoveValue(PlacementData placementData, int actualMove, PlacementDim placementDim, int prevAxeMove, bool containerRightToLeft)
        {
            float remainder;
            float result;
            int   move;
            int   place   = placementData.getPlacement(placementDim, containerRightToLeft);
            float accMove = placementData.getAccCtrlMove(placementDim);

            if (place > 0 && place < 100)
            {
                result    = (float)(actualMove * place) / 100;
                move      = (int)((actualMove * place) / 100);
                remainder = result - move;
                accMove  += remainder;
                if (accMove >= 1 || accMove <= -1)
                {
                    move += (int)accMove;
                    if (move > 0)
                    {
                        accMove -= 1;
                    }
                    else
                    {
                        accMove += 1;
                    }
                }
            }
            else
            if (place == 0)   // no placement
            {
                move = 0;
            }
            else
            {
                move = actualMove;  // placement is 100%
            }
            placementData.setAccCtrlMove(placementDim, accMove);

            return(move);
        }
コード例 #2
0
        /// <summary> limit placement check if one of the ctrl's caused the scrollbar to be shown or removed, if so limit the
        /// movement. dx & dy are the actual window movement. Will return the allowed movement before scrollbars.
        /// this code is based on GUI::LimitPlacement method in gui.cpp
        /// </summary>
        /// <param name="composite"></param>
        /// <param name="dx">delta X</param>
        /// <param name="dy">delta Y</param>
        /// <param name="newContainerRect">new Recatngle of container</param>
        /// <returns> new dx,dy</returns>
        private Point limitPlacement(Control containerControl, int dx, int dy, Rectangle newContainerRect)
        {
            int       totalPlaceX, totalPlaceY;
            int       fromPrevToCtrlX, fromPrevToCtrlY;
            int       bottom;
            Rectangle place = new Rectangle(0, 0, 0, 0);
            ArrayList controlsList;
            bool      containerRightToLeft = isRTL(containerControl);
            bool      canHaveScrollbar     = (containerControl is ScrollableControl && ((ScrollableControl)containerControl).AutoScroll);

            if (!canHaveScrollbar) //QCR #982071, if control does not support scrollbars - tab, group - we should not limit placement
            {
                return(new Point(dx, dy));
            }

            if (CanLimitPlacement(containerControl) && (dx < 0 || dy < 0))
            {
                controlsList = GetControlsList(containerControl);

                foreach (Object obj in controlsList)
                {
#if PocketPC
                    if (containerControl is Panel && obj == ((Panel)containerControl).dummy)
                    {
                        continue;
                    }
#endif
                    //ignore editors, they will be handled by logical controls
                    Control control = obj as Control;
                    if (!ShouldLimitPlacement(control)) //it will be handled by its logicalcontrol
                    {
                        continue;
                    }

                    Rectangle     rect          = Bounds(obj);
                    PlacementData placementData = PlacementData(obj);
                    if (placementData != null)
                    {
                        place = placementData.Placement;
                    }
                    else
                    {
                        place = new Rectangle(0, 0, 0, 0);
                    }
                    if (containerRightToLeft)
                    {
                        totalPlaceX = (100 - place.X) + place.Width;
                    }
                    else
                    {
                        totalPlaceX = place.X + place.Width;
                    }
                    totalPlaceY = place.Y + place.Height;

                    if (obj is TableControl)
                    {
                        GetTableTotalPlaceX((TableControl)obj, place, dx, ref totalPlaceX);
                    }

                    int childRight  = rect.X + rect.Width;
                    int childBottom = rect.Y + rect.Height;

                    fromPrevToCtrlX = _prevRect.Width - childRight;
                    fromPrevToCtrlY = _prevRect.Height - childBottom;

                    int right = 0;
                    // Checks which of the controls will be the closest one to the right border of the form
                    if (dx < 0 && totalPlaceX < 100 && fromPrevToCtrlX >= 0 && newContainerRect.Width < childRight)
                    {
                        right = -((fromPrevToCtrlX * 100) / (100 - totalPlaceX));
                        dx    = Math.Max(dx, right);
                    }

                    if (containerRightToLeft && dx < 0) //QCR #974011, 805098
                    {
                        long totalPlaceXLeft = (100 - place.X) - place.Width;
                        long left            = rect.X + (dx * totalPlaceXLeft / 100); //new left coordinate of control

                        if (left < right /* not hidden*/ && left < 0)
                        {
                            dx = Math.Max(-rect.Left, dx);
                        }
                    }

                    // Checks which of the controls will be the closest one to the bottom border of the form
                    if (dy < 0 && totalPlaceY < 100 && fromPrevToCtrlY >= 0 && newContainerRect.Height < childBottom)
                    {
                        bottom = -((fromPrevToCtrlY * 100) / (100 - totalPlaceY));
                        dy     = Math.Max(dy, bottom);
                    }
                }
            }

            if (dx > 0)
            {
                // if there was a horizontal scrollbar and after the current resizing it might won't be
                if (_prevRect.Width < _prevLogicalSize.X && newContainerRect.Width >= _prevLogicalSize.X)
                {
                    dx = newContainerRect.Width - _prevLogicalSize.X;
                }
            }

            if (dy > 0)
            {
                // if there was a vertical scrollbar and after the current resizing it might won't be
                if (_prevRect.Height < _prevLogicalSize.Y && newContainerRect.Height >= _prevLogicalSize.Y)
                {
                    dy = newContainerRect.Height - _prevLogicalSize.Y;
                }
            }

            return(new Point(dx, dy));
        }
コード例 #3
0
        /// <summary>
        /// Fix Rounding mistakes caused by placement calculations
        /// </summary>
        /// <param name="originPlacement"> placement of the origine (x or y placement) </param>
        /// <param name="lengthPlacement"> widht or height placement (dx or dy placement)</param>
        /// <param name="totalChange"> total change for control</param>
        /// <param name="axe"> X or Y axe</param>
        /// <param name="placementData"> placement data</param>
        /// <param name="containerRightToLeft">RightToLeft</param>
        /// <returns></returns>
        static int fixRounding(int originPlacement, int lengthPlacement, int totalChange, Axe axe, PlacementData placementData, bool containerRightToLeft)
        {
            PlacementDim originPlacementDim = axe == Axe.X ? PlacementDim.PLACE_X : PlacementDim.PLACE_Y;
            PlacementDim lengthPlacementDim = axe == Axe.X ? PlacementDim.PLACE_DX : PlacementDim.PLACE_DY;

            if (placementData.getPlacement(originPlacementDim, containerRightToLeft) + placementData.getPlacement(lengthPlacementDim, containerRightToLeft) == 100)
            {
                //total placement is 100% this means that originPlacement + lengthPlacement MUST BE EQUAL to totalChange
                //there are may be some mistakes caused by rounding of float numbers to integer, we must fix them
                //If these small mistakes are not fix - scroll bar might be created when it is not needed
                if (Math.Abs(originPlacement + lengthPlacement) != Math.Abs(totalChange))
                {
                    int   diff    = totalChange - (originPlacement + lengthPlacement);
                    float accMove = placementData.getAccCtrlMove(lengthPlacementDim);
                    //recalculate length placement
                    lengthPlacement += diff;
                    //update AccCtrlMove for future placement
                    placementData.setAccCtrlMove(lengthPlacementDim, accMove + diff);
                }
            }
            return(lengthPlacement);
        }
コード例 #4
0
        /// <summary>
        /// controls placement
        /// </summary>
        /// <param name="control"></param>
        /// <param name="actualPlacement"></param>
        public void ControlPlacement(Object obj, Point actualPlacement)
        {
            if (obj is Control)
            {
                Control control = (Control)obj;
                if (!ShouldApplyPlacement(control))
                {
                    return;
                }
                int       dx, dy;
                Rectangle rect = Bounds(control);
#if !PocketPC //tmp
                bool containerRightToLeft = control.Parent.RightToLeft == RightToLeft.Yes;
#else
                bool containerRightToLeft = false;
#endif
                PlacementData placementData = PlacementData(control);

                if (placementData == null)
                {
                    return;
                }

                // process placement for all children
                int xChange = updateMoveValue(placementData, actualPlacement.X, PlacementDim.PLACE_X, 0, containerRightToLeft);
                rect.X += xChange;

                int yChange = updateMoveValue(placementData, actualPlacement.Y, PlacementDim.PLACE_Y, 0, containerRightToLeft);
                rect.Y += yChange;

                // compute width and height placement
                // compute width and height placement
                dx = updateMoveValue(placementData, actualPlacement.X, PlacementDim.PLACE_DX, xChange, containerRightToLeft);
                dy = updateMoveValue(placementData, actualPlacement.Y, PlacementDim.PLACE_DY, yChange, containerRightToLeft);

                //QCR #288201, due to calculation problems caused by rounding float to int sometimes scrollbar is shown
                //This is fix for the case when total placement is 100 %
                dx = fixRounding(xChange, dx, actualPlacement.X, Axe.X, placementData, containerRightToLeft);
                dy = fixRounding(yChange, dy, actualPlacement.Y, Axe.Y, placementData, containerRightToLeft);

                if (control is TableControl)
                {
                    ExecuteTableControlPlacement((TableControl)control, dx, dy, rect);
                }
                else
                {
                    //QCR #933614, negative width and height turned to 0 in setBounds,
                    //so we must save then on the control's data
                    Rectangle?savedRect = GetSavedBounds(control);
                    if (savedRect != null)
                    {
                        rect.Width  = ((Rectangle)savedRect).Width;
                        rect.Height = ((Rectangle)savedRect).Height;
                    }

                    rect.Width += dx;
                    if (containerRightToLeft)
                    {
                        rect.X -= dx;
                    }

                    rect.Height += dy;
                    SetBounds(control, rect);
                }
            }
            else if (obj is PlacementDrivenLogicalControl)
            {
                ReCalculateAndRefresh(obj);
            }
        }