Example #1
0
        public override bool Layout(object container, LayoutEventArgs args)
        {
            if (container is ToolStripPanel)
            {
                return(false);
            }

            if (container is ToolStrip)
            {
                return(LayoutToolStrip((ToolStrip)container));
            }

            Control parent = container as Control;

            FlowLayoutSettings settings;

            if (parent is FlowLayoutPanel)
            {
                settings = (parent as FlowLayoutPanel).LayoutSettings;
            }
            else
            {
                settings = default_settings;
            }

            // Nothing to layout, exit method
            if (parent.Controls.Count == 0)
            {
                return(false);
            }

            // Use DisplayRectangle so that parent.Padding is honored.
            Rectangle_ parentDisplayRectangle = parent.DisplayRectangle;

            Drawing.Point_ currentLocation;

            // Set our starting Point_ based on flow direction
            switch (settings.FlowDirection)
            {
            case FlowDirection.BottomUp:
                currentLocation = new Point_(parentDisplayRectangle.Left, parentDisplayRectangle.Bottom);
                break;

            case FlowDirection.LeftToRight:
            case FlowDirection.TopDown:
            default:
                currentLocation = parentDisplayRectangle.Location;
                break;

            case FlowDirection.RightToLeft:
                currentLocation = new Point_(parentDisplayRectangle.Right, parentDisplayRectangle.Top);
                break;
            }

            bool forceFlowBreak = false;

            List <Control> rowControls = new List <Control> ();

            foreach (Control c in parent.Controls)
            {
                // Only apply layout to visible controls.
                if (!c.Visible)
                {
                    continue;
                }

                // Resize any AutoSize controls to their preferred size
                if (c.AutoSize == true)
                {
                    Size_ new_size = c.GetPreferredSize(c.Size);
                    c.SetBoundsInternal(c.Left, c.Top, new_size.Width, new_size.Height, BoundsSpecified.None);
                }

                switch (settings.FlowDirection)
                {
                case FlowDirection.BottomUp:
                    // Decide if it's time to start a new column
                    // - Our settings must be WrapContents, and we ran out of room or the previous control's FlowBreak == true
                    if (settings.WrapContents)
                    {
                        if ((currentLocation.Y) < (c.Height + c.Margin.Top + c.Margin.Bottom) || forceFlowBreak)
                        {
                            currentLocation.X = FinishColumn(rowControls);
                            currentLocation.Y = parentDisplayRectangle.Bottom;

                            forceFlowBreak = false;
                            rowControls.Clear();
                        }
                    }

                    // Offset the right margin and set the control to our point
                    currentLocation.Offset(0, c.Margin.Bottom * -1);
                    c.SetBoundsInternal(currentLocation.X + c.Margin.Left, currentLocation.Y - c.Height, c.Width, c.Height, BoundsSpecified.None);

                    // Update our location pointer
                    currentLocation.Y -= (c.Height + c.Margin.Top);
                    break;

                case FlowDirection.LeftToRight:
                default:
                    // Decide if it's time to start a new row
                    // - Our settings must be WrapContents, and we ran out of room or the previous control's FlowBreak == true
                    if (settings.WrapContents && !(parent is ToolStripPanel))
                    {
                        if ((parentDisplayRectangle.Width + parentDisplayRectangle.Left - currentLocation.X) < (c.Width + c.Margin.Left + c.Margin.Right) || forceFlowBreak)
                        {
                            currentLocation.Y = FinishRow(rowControls);
                            currentLocation.X = parentDisplayRectangle.Left;

                            forceFlowBreak = false;
                            rowControls.Clear();
                        }
                    }

                    // Offset the left margin and set the control to our point
                    currentLocation.Offset(c.Margin.Left, 0);
                    c.SetBoundsInternal(currentLocation.X, currentLocation.Y + c.Margin.Top, c.Width, c.Height, BoundsSpecified.None);

                    // Update our location pointer
                    currentLocation.X += c.Width + c.Margin.Right;
                    break;

                case FlowDirection.RightToLeft:
                    // Decide if it's time to start a new row
                    // - Our settings must be WrapContents, and we ran out of room or the previous control's FlowBreak == true
                    if (settings.WrapContents)
                    {
                        if ((currentLocation.X) < (c.Width + c.Margin.Left + c.Margin.Right) || forceFlowBreak)
                        {
                            currentLocation.Y = FinishRow(rowControls);
                            currentLocation.X = parentDisplayRectangle.Right;

                            forceFlowBreak = false;
                            rowControls.Clear();
                        }
                    }

                    // Offset the right margin and set the control to our point
                    currentLocation.Offset(c.Margin.Right * -1, 0);
                    c.SetBoundsInternal(currentLocation.X - c.Width, currentLocation.Y + c.Margin.Top, c.Width, c.Height, BoundsSpecified.None);

                    // Update our location pointer
                    currentLocation.X -= (c.Width + c.Margin.Left);
                    break;

                case FlowDirection.TopDown:
                    // Decide if it's time to start a new column
                    // - Our settings must be WrapContents, and we ran out of room or the previous control's FlowBreak == true
                    if (settings.WrapContents)
                    {
                        if ((parentDisplayRectangle.Height + parentDisplayRectangle.Top - currentLocation.Y) < (c.Height + c.Margin.Top + c.Margin.Bottom) || forceFlowBreak)
                        {
                            currentLocation.X = FinishColumn(rowControls);
                            currentLocation.Y = parentDisplayRectangle.Top;

                            forceFlowBreak = false;
                            rowControls.Clear();
                        }
                    }

                    // Offset the top margin and set the control to our point
                    currentLocation.Offset(0, c.Margin.Top);
                    c.SetBoundsInternal(currentLocation.X + c.Margin.Left, currentLocation.Y, c.Width, c.Height, BoundsSpecified.None);

                    // Update our location pointer
                    currentLocation.Y += c.Height + c.Margin.Bottom;
                    break;
                }
                // Add it to our list of things to adjust the second dimension of
                rowControls.Add(c);

                // If user set a flowbreak on this control, it will be the last one in this row/column
                if (settings.GetFlowBreak(c))
                {
                    forceFlowBreak = true;
                }
            }

            // Set the control heights/widths for the last row/column
            if (settings.FlowDirection == FlowDirection.LeftToRight || settings.FlowDirection == FlowDirection.RightToLeft)
            {
                FinishRow(rowControls);
            }
            else
            {
                FinishColumn(rowControls);
            }

            return(false);
        }
Example #2
0
        private void LayoutControls(TableLayoutPanel panel)
        {
            TableLayoutSettings settings = panel.LayoutSettings;

            int border_width = TableLayoutPanel.GetCellBorderWidth(panel.CellBorderStyle);

            int columns = panel.actual_positions.GetLength(0);
            int rows    = panel.actual_positions.GetLength(1);

            Point_ current_pos = new Point_(panel.DisplayRectangle.Left + border_width, panel.DisplayRectangle.Top + border_width);

            for (int y = 0; y < rows; y++)
            {
                for (int x = 0; x < columns; x++)
                {
                    Control c = panel.actual_positions[x, y];

                    if (c != null && c != dummy_control)
                    {
                        Size_ preferred;

                        if (c.AutoSize)
                        {
                            preferred = c.PreferredSize;
                        }
                        else
                        {
                            preferred = c.ExplicitBounds.Size;
                        }

                        int new_x      = 0;
                        int new_y      = 0;
                        int new_width  = 0;
                        int new_height = 0;

                        // Figure out the width of the control
                        int column_width = panel.column_widths[x];

                        for (int i = 1; i < Math.Min(settings.GetColumnSpan(c), panel.column_widths.Length); i++)
                        {
                            column_width += panel.column_widths[x + i];
                        }

                        if (c.Dock == DockStyle.Fill || c.Dock == DockStyle.Top || c.Dock == DockStyle.Bottom || ((c.Anchor & AnchorStyles.Left) == AnchorStyles.Left && (c.Anchor & AnchorStyles.Right) == AnchorStyles.Right))
                        {
                            new_width = column_width - c.Margin.Left - c.Margin.Right;
                        }
                        else
                        {
                            new_width = Math.Min(preferred.Width, column_width - c.Margin.Left - c.Margin.Right);
                        }

                        // Figure out the height of the control
                        int column_height = panel.row_heights[y];

                        for (int i = 1; i < Math.Min(settings.GetRowSpan(c), panel.row_heights.Length); i++)
                        {
                            column_height += panel.row_heights[y + i];
                        }

                        if (c.Dock == DockStyle.Fill || c.Dock == DockStyle.Left || c.Dock == DockStyle.Right || ((c.Anchor & AnchorStyles.Top) == AnchorStyles.Top && (c.Anchor & AnchorStyles.Bottom) == AnchorStyles.Bottom))
                        {
                            new_height = column_height - c.Margin.Top - c.Margin.Bottom;
                        }
                        else
                        {
                            new_height = Math.Min(preferred.Height, column_height - c.Margin.Top - c.Margin.Bottom);
                        }

                        // Figure out the left location of the control
                        if (c.Dock == DockStyle.Left || c.Dock == DockStyle.Fill || (c.Anchor & AnchorStyles.Left) == AnchorStyles.Left)
                        {
                            new_x = current_pos.X + c.Margin.Left;
                        }
                        else if (c.Dock == DockStyle.Right || (c.Anchor & AnchorStyles.Right) == AnchorStyles.Right)
                        {
                            new_x = (current_pos.X + column_width) - new_width - c.Margin.Right;
                        }
                        else                            // (center control)
                        {
                            new_x = (current_pos.X + (column_width - c.Margin.Left - c.Margin.Right) / 2) + c.Margin.Left - (new_width / 2);
                        }

                        // Figure out the top location of the control
                        if (c.Dock == DockStyle.Top || c.Dock == DockStyle.Fill || (c.Anchor & AnchorStyles.Top) == AnchorStyles.Top)
                        {
                            new_y = current_pos.Y + c.Margin.Top;
                        }
                        else if (c.Dock == DockStyle.Bottom || (c.Anchor & AnchorStyles.Bottom) == AnchorStyles.Bottom)
                        {
                            new_y = (current_pos.Y + column_height) - new_height - c.Margin.Bottom;
                        }
                        else                            // (center control)
                        {
                            new_y = (current_pos.Y + (column_height - c.Margin.Top - c.Margin.Bottom) / 2) + c.Margin.Top - (new_height / 2);
                        }

                        c.SetBoundsInternal(new_x, new_y, new_width, new_height, BoundsSpecified.None);
                    }

                    current_pos.Offset(panel.column_widths[x] + border_width, 0);
                }

                current_pos.Offset((-1 * current_pos.X) + border_width + panel.DisplayRectangle.Left, panel.row_heights[y] + border_width);
            }
        }
Example #3
0
        // ToolStrips use the same FlowLayout, but is made up of ToolStripItems which
        // are Components instead of Controls, so we have to duplicate this login for
        // ToolStripItems.
        private bool LayoutToolStrip(ToolStrip parent)
        {
            FlowLayoutSettings settings;

            settings = (FlowLayoutSettings)parent.LayoutSettings;

            // Nothing to layout, exit method
            if (parent.Items.Count == 0)
            {
                return(false);
            }

            foreach (ToolStripItem tsi in parent.Items)
            {
                tsi.SetPlacement(ToolStripItemPlacement.Main);
            }

            // Use DisplayRectangle so that parent.Padding is honored.
            Rectangle_ parentDisplayRectangle = parent.DisplayRectangle;

            Drawing.Point_ currentLocation;

            // Set our starting Point_ based on flow direction
            switch (settings.FlowDirection)
            {
            case FlowDirection.BottomUp:
                currentLocation = new Point_(parentDisplayRectangle.Left, parentDisplayRectangle.Bottom);
                break;

            case FlowDirection.LeftToRight:
            case FlowDirection.TopDown:
            default:
                currentLocation = parentDisplayRectangle.Location;
                break;

            case FlowDirection.RightToLeft:
                currentLocation = new Point_(parentDisplayRectangle.Right, parentDisplayRectangle.Top);
                break;
            }

            bool forceFlowBreak = false;

            List <ToolStripItem> rowControls = new List <ToolStripItem> ();

            foreach (ToolStripItem c in parent.Items)
            {
                // Only apply layout to visible controls.
                if (!c.Available)
                {
                    continue;
                }

                // Resize any AutoSize controls to their preferred size
                if (c.AutoSize == true)
                {
                    c.SetBounds(new Rectangle_(c.Location, c.GetPreferredSize(c.Size)));
                }

                switch (settings.FlowDirection)
                {
                case FlowDirection.BottomUp:
                    // Decide if it's time to start a new column
                    // - Our settings must be WrapContents, and we ran out of room or the previous control's FlowBreak == true
                    if (settings.WrapContents)
                    {
                        if ((currentLocation.Y) < (c.Height + c.Margin.Top + c.Margin.Bottom) || forceFlowBreak)
                        {
                            currentLocation.X = FinishColumn(rowControls);
                            currentLocation.Y = parentDisplayRectangle.Bottom;

                            forceFlowBreak = false;
                            rowControls.Clear();
                        }
                    }

                    // Offset the right margin and set the control to our point
                    currentLocation.Offset(0, c.Margin.Bottom * -1);
                    c.Location = new Point_(currentLocation.X + c.Margin.Left, currentLocation.Y - c.Height);

                    // Update our location pointer
                    currentLocation.Y -= (c.Height + c.Margin.Top);
                    break;

                case FlowDirection.LeftToRight:
                default:
                    // Decide if it's time to start a new row
                    // - Our settings must be WrapContents, and we ran out of room or the previous control's FlowBreak == true
                    if (settings.WrapContents)
                    {
                        if ((parentDisplayRectangle.Width - currentLocation.X) < (c.Width + c.Margin.Left + c.Margin.Right) || forceFlowBreak)
                        {
                            currentLocation.Y = FinishRow(rowControls);
                            currentLocation.X = parentDisplayRectangle.Left;

                            forceFlowBreak = false;
                            rowControls.Clear();
                        }
                    }

                    // Offset the left margin and set the control to our point
                    currentLocation.Offset(c.Margin.Left, 0);
                    c.Location = new Point_(currentLocation.X, currentLocation.Y + c.Margin.Top);

                    // Update our location pointer
                    currentLocation.X += c.Width + c.Margin.Right;
                    break;

                case FlowDirection.RightToLeft:
                    // Decide if it's time to start a new row
                    // - Our settings must be WrapContents, and we ran out of room or the previous control's FlowBreak == true
                    if (settings.WrapContents)
                    {
                        if ((currentLocation.X) < (c.Width + c.Margin.Left + c.Margin.Right) || forceFlowBreak)
                        {
                            currentLocation.Y = FinishRow(rowControls);
                            currentLocation.X = parentDisplayRectangle.Right;

                            forceFlowBreak = false;
                            rowControls.Clear();
                        }
                    }

                    // Offset the right margin and set the control to our point
                    currentLocation.Offset(c.Margin.Right * -1, 0);
                    c.Location = new Point_(currentLocation.X - c.Width, currentLocation.Y + c.Margin.Top);

                    // Update our location pointer
                    currentLocation.X -= (c.Width + c.Margin.Left);
                    break;

                case FlowDirection.TopDown:
                    // Decide if it's time to start a new column
                    // - Our settings must be WrapContents, and we ran out of room or the previous control's FlowBreak == true
                    if (settings.WrapContents)
                    {
                        if ((parentDisplayRectangle.Height - currentLocation.Y) < (c.Height + c.Margin.Top + c.Margin.Bottom) || forceFlowBreak)
                        {
                            currentLocation.X = FinishColumn(rowControls);
                            currentLocation.Y = parentDisplayRectangle.Top;

                            forceFlowBreak = false;
                            rowControls.Clear();
                        }
                    }

                    // Offset the top margin and set the control to our point
                    currentLocation.Offset(0, c.Margin.Top);
                    c.Location = new Point_(currentLocation.X + c.Margin.Left, currentLocation.Y);

                    // Update our location pointer
                    currentLocation.Y += c.Height + c.Margin.Bottom;
                    break;
                }
                // Add it to our list of things to adjust the second dimension of
                rowControls.Add(c);

                // If user set a flowbreak on this control, it will be the last one in this row/column
                if (settings.GetFlowBreak(c))
                {
                    forceFlowBreak = true;
                }
            }

            int final_height = 0;

            // Set the control heights/widths for the last row/column
            if (settings.FlowDirection == FlowDirection.LeftToRight || settings.FlowDirection == FlowDirection.RightToLeft)
            {
                final_height = FinishRow(rowControls);
            }
            else
            {
                FinishColumn(rowControls);
            }

            if (final_height > 0)
            {
                parent.SetBoundsInternal(parent.Left, parent.Top, parent.Width, final_height + parent.Padding.Bottom, BoundsSpecified.None);
            }

            return(false);
        }