If you have comments or questions concerning this source file, discuss them in the forum.
/*
Copyright (c) 2002 Nicolai Haehnle

See the license.txt for details. If that file was not included in the
source distributions, please email <prefect@rtts.org>
*/
// gui_grid.cpp - arrange child panels horizontally and/or vertically

#include "library.h"
#include "hal.h"

#include "gui_grid.h"

/*
TODO:
This is really a rather broken concept. What I need are two different
layout class trees:

HBox / VBox / Grid
    - HBox and VBox are basically onedimensional versions of Grid,
      so one class could be enough

ListBox (what the hell should that be called?)
    - does what GGrid does right now

Current GGrid behaviour deviates from what Grid should be:
Grid should put each child into a 'cell', just like we know it from
spreadsheet apps. That means that columns are consistent in width.
Furthermore, you'd have to (more or less) manually specify the
(column,row) where each child should be placed.

GGrid::Arrange doesn't now consistent column width (would be non-trivial
to implement because of back-and-forth wrapping when row length changes,
so Grid really would need explicit placement)
and rows can differ in length, etc...

I really don't have the nerves to implement such a system right now.
*/

/*
==============
GGrid::GGrid

Sometimes, C++ is just stupid
==============
*/
GGrid::GGrid(GPanel *pParent, int x, int y, int w, int h, bool bOverlap)
    : GPanel(pParent, x, y, w, h, bOverlap)
{
}

/*
==============
GGrid::Arrange

Worker function
==============
*/
void GGrid::Arrange(bool horiz, bool vert)
{
    int x, y;
    int maxh;

    x = 0;
    y = 0;
    maxh = 0;

    for(GPanel_rlit panel = m_Children.rbegin(); panel != m_Children.rend(); panel++) {
        GPanel *pPanel = *panel;
        int w, h;

        if (!pPanel->m_bVisible || pPanel->m_bTopLevel)
            continue;

        pPanel->GetSize(&w, &h);

        if (vert && x && x+w > GetWidth()) {
            x = 0;
            y += maxh;
            maxh = 0;
        }

        pPanel->SetPos(x, y);

        if (horiz) {
            x += w;
            if (h > maxh)
                maxh = h;
        } else
            y += h;
    }
}