root/src/kits/interface/GroupLayoutBuilder.cpp
/*
 * Copyright 2006, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
 * All rights reserved. Distributed under the terms of the MIT License.
 */

#include <GroupLayoutBuilder.h>

#include <new>

#include <SpaceLayoutItem.h>


using std::nothrow;


// constructor
BGroupLayoutBuilder::BGroupLayoutBuilder(orientation orientation,
        float spacing)
        : fRootLayout((new BGroupView(orientation, spacing))->GroupLayout())
{
        _PushLayout(fRootLayout);
}

// constructor
BGroupLayoutBuilder::BGroupLayoutBuilder(BGroupLayout* layout)
        : fRootLayout(layout)
{
        _PushLayout(fRootLayout);
}

// constructor
BGroupLayoutBuilder::BGroupLayoutBuilder(BGroupView* view)
        : fRootLayout(view->GroupLayout())
{
        _PushLayout(fRootLayout);
}

// RootLayout
BGroupLayout*
BGroupLayoutBuilder::RootLayout() const
{
        return fRootLayout;
}

// TopLayout
BGroupLayout*
BGroupLayoutBuilder::TopLayout() const
{
        int32 count = fLayoutStack.CountItems();
        return (count > 0
                ? (BGroupLayout*)fLayoutStack.ItemAt(count - 1) : NULL);
}

// GetTopLayout
BGroupLayoutBuilder&
BGroupLayoutBuilder::GetTopLayout(BGroupLayout** _layout)
{
        *_layout = TopLayout();
        return *this;
}

// TopView
BView*
BGroupLayoutBuilder::TopView() const
{
        if (BGroupLayout* layout = TopLayout())
                return layout->Owner();
        return NULL;
}

// GetTopView
BGroupLayoutBuilder&
BGroupLayoutBuilder::GetTopView(BView** _view)
{
        if (BGroupLayout* layout = TopLayout())
                *_view = layout->Owner();
        else
                *_view = NULL;

        return *this;
}

// Add
BGroupLayoutBuilder&
BGroupLayoutBuilder::Add(BView* view)
{
        if (BGroupLayout* layout = TopLayout())
                layout->AddView(view);
        return *this;
}

// Add
BGroupLayoutBuilder&
BGroupLayoutBuilder::Add(BView* view, float weight)
{
        if (BGroupLayout* layout = TopLayout())
                layout->AddView(view, weight);
        return *this;
}

// Add
BGroupLayoutBuilder&
BGroupLayoutBuilder::Add(BLayoutItem* item)
{
        if (BGroupLayout* layout = TopLayout())
                layout->AddItem(item);
        return *this;
}

// Add
BGroupLayoutBuilder&
BGroupLayoutBuilder::Add(BLayoutItem* item, float weight)
{
        if (BGroupLayout* layout = TopLayout())
                layout->AddItem(item, weight);
        return *this;
}

// AddGroup
BGroupLayoutBuilder&
BGroupLayoutBuilder::AddGroup(orientation orientation, float spacing,
        float weight)
{
        if (BGroupLayout* layout = TopLayout()) {
                BGroupView* group = new(nothrow) BGroupView(orientation, spacing);
                if (group) {
                        if (layout->AddView(group, weight))
                                _PushLayout(group->GroupLayout());
                        else
                                delete group;
                }
        }

        return *this;
}

// End
BGroupLayoutBuilder&
BGroupLayoutBuilder::End()
{
        _PopLayout();
        return *this;
}

// AddGlue
BGroupLayoutBuilder&
BGroupLayoutBuilder::AddGlue(float weight)
{
        if (BGroupLayout* layout = TopLayout())
                layout->AddItem(BSpaceLayoutItem::CreateGlue(), weight);

        return *this;
}

// AddStrut
BGroupLayoutBuilder&
BGroupLayoutBuilder::AddStrut(float size)
{
        if (BGroupLayout* layout = TopLayout()) {
                if (layout->Orientation() == B_HORIZONTAL)
                        layout->AddItem(BSpaceLayoutItem::CreateHorizontalStrut(size));
                else
                        layout->AddItem(BSpaceLayoutItem::CreateVerticalStrut(size));
        }

        return *this;
}

// SetInsets
BGroupLayoutBuilder& 
BGroupLayoutBuilder::SetInsets(float left, float top, float right, float bottom)
{
        if (BGroupLayout* layout = TopLayout())
                layout->SetInsets(left, top, right, bottom);

        return *this;
}
        
// cast operator BGroupLayout*
BGroupLayoutBuilder::operator BGroupLayout*()
{
        return fRootLayout;
}

// _PushLayout
bool
BGroupLayoutBuilder::_PushLayout(BGroupLayout* layout)
{
        return fLayoutStack.AddItem(layout);
}

// _PopLayout
void
BGroupLayoutBuilder::_PopLayout()
{
        int32 count = fLayoutStack.CountItems();
        if (count > 0)
                fLayoutStack.RemoveItem(count - 1);
}