public Size getPreferredSize()
        {
            float dy = 0;
            float dx = 0;

            for (int i = 0; i < constraints.Count; i++)
            {
                GridPanelConstraint c = (GridPanelConstraint)constraints[i];

                Size d = c.component.Size;

                dx = Math.Max(dx, d.Width / c.width);
                dy = Math.Max(dy, d.Height / c.height);
            }

            dx += hgap;
            dy += vgap;

            dx *= cols;
            dy *= rows;

            dx += insets.left + insets.right;
            dy += insets.top + insets.bottom;

            return(new Size((int)dx, (int)dy));
        }
        public void doLayout()
        {
            Size size = Size;

            size.Height -= insets.top + insets.bottom;
            size.Width  -= insets.left + insets.right;

            float cellWidth  = size.Width / cols;
            float cellHeight = size.Height / rows;

            for (int i = 0; i < constraints.Count; i++)
            {
                GridPanelConstraint c = (GridPanelConstraint)constraints[i];

                float x = cellWidth * c.x + insets.left + hgap / 2;
                float y = cellHeight * c.y + insets.right + vgap / 2;

                float width, height;

                if (c.handle == Handles.FILL)
                {
                    width  = (cellWidth - hgap) * c.width;
                    height = (cellHeight - vgap) * c.height;
                }
                else
                {
                    Size d = c.component.Size;
                    width  = d.Width;
                    height = d.Height;
                }

                switch (c.handle)
                {
                case Handles.TOP_CENTER:
                    x += (cellWidth + width) / 2;
                    break;

                case Handles.TOP_RIGHT:
                    x += cellWidth - width;
                    break;

                case Handles.CENTER_LEFT:
                    y += (cellHeight + height) / 2;
                    break;

                case Handles.CENTER:
                    x += (cellWidth + width) / 2;
                    y += (cellHeight + height) / 2;
                    break;

                case Handles.CENTER_RIGHT:
                    y += (cellHeight + height) / 2;
                    x += cellWidth - width;
                    break;

                case Handles.BOTTOM:
                    y += cellHeight - height;
                    break;

                case Handles.BOTTOM_CENTER:
                    x += (cellWidth + width) / 2;
                    y += cellHeight - height;
                    break;

                case Handles.BOTTOM_RIGHT:
                    y += cellHeight - height;
                    x += cellWidth - width;
                    break;
                }

                c.component.Bounds = new Rectangle((int)x, (int)y, (int)width, (int)height);
            }
        }