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


#include <SpaceLayoutItem.h>

#include <new>

#include <ControlLook.h>
#include <Message.h>


namespace {
        const char* const kSizesField = "BSpaceLayoutItem:sizes";
                // kSizesField = {min, max, preferred}
        const char* const kAlignmentField = "BSpaceLayoutItem:alignment";
        const char* const kFrameField = "BSpaceLayoutItem:frame";
        const char* const kVisibleField = "BSpaceLayoutItem:visible";

        BSize& ComposeSpacingInPlace(BSize& size)
        {
                size.width = BControlLook::ComposeSpacing(size.width);
                size.height = BControlLook::ComposeSpacing(size.height);
                return size;
        }
}


BSpaceLayoutItem::BSpaceLayoutItem(BSize minSize, BSize maxSize,
        BSize preferredSize, BAlignment alignment)
        :
        fFrame(),
        fMinSize(ComposeSpacingInPlace(minSize)),
        fMaxSize(ComposeSpacingInPlace(maxSize)),
        fPreferredSize(ComposeSpacingInPlace(preferredSize)),
        fAlignment(alignment),
        fVisible(true)
{
}


BSpaceLayoutItem::BSpaceLayoutItem(BMessage* archive)
        :
        BLayoutItem(archive)
{
        archive->FindSize(kSizesField, 0, &fMinSize);
        archive->FindSize(kSizesField, 1, &fMaxSize);
        archive->FindSize(kSizesField, 2, &fPreferredSize);

        archive->FindAlignment(kAlignmentField, &fAlignment);

        archive->FindRect(kFrameField, &fFrame);
        archive->FindBool(kVisibleField, &fVisible);
}


BSpaceLayoutItem::~BSpaceLayoutItem()
{
}


BSpaceLayoutItem*
BSpaceLayoutItem::CreateGlue()
{
        return new BSpaceLayoutItem(
                BSize(-1, -1),
                BSize(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED),
                BSize(-1, -1),
                BAlignment(B_ALIGN_HORIZONTAL_CENTER, B_ALIGN_VERTICAL_CENTER));
}


BSpaceLayoutItem*
BSpaceLayoutItem::CreateHorizontalStrut(float width)
{
        return new BSpaceLayoutItem(
                BSize(width, -1),
                BSize(width, B_SIZE_UNLIMITED),
                BSize(width, -1),
                BAlignment(B_ALIGN_HORIZONTAL_CENTER, B_ALIGN_VERTICAL_CENTER));
}


BSpaceLayoutItem*
BSpaceLayoutItem::CreateVerticalStrut(float height)
{
        return new BSpaceLayoutItem(
                BSize(-1, height),
                BSize(B_SIZE_UNLIMITED, height),
                BSize(-1, height),
                BAlignment(B_ALIGN_HORIZONTAL_CENTER, B_ALIGN_VERTICAL_CENTER));
}


BSize
BSpaceLayoutItem::MinSize()
{
        return fMinSize;
}


BSize
BSpaceLayoutItem::MaxSize()
{
        return fMaxSize;
}


BSize
BSpaceLayoutItem::PreferredSize()
{
        return fPreferredSize;
}


BAlignment
BSpaceLayoutItem::Alignment()
{
        return fAlignment;
}


void
BSpaceLayoutItem::SetExplicitMinSize(BSize size)
{
        if (size.IsWidthSet())
                fMinSize.width = size.width;
        if (size.IsHeightSet())
                fMinSize.height = size.height;

        InvalidateLayout();
}


void
BSpaceLayoutItem::SetExplicitMaxSize(BSize size)
{
        if (size.IsWidthSet())
                fMaxSize.width = size.width;
        if (size.IsHeightSet())
                fMaxSize.height = size.height;

        InvalidateLayout();
}


void
BSpaceLayoutItem::SetExplicitPreferredSize(BSize size)
{
        if (size.IsWidthSet())
                fPreferredSize.width = size.width;
        if (size.IsHeightSet())
                fPreferredSize.height = size.height;

        InvalidateLayout();
}


void
BSpaceLayoutItem::SetExplicitAlignment(BAlignment alignment)
{
        if (alignment.IsHorizontalSet())
                fAlignment.horizontal = alignment.horizontal;
        if (alignment.IsVerticalSet())
                fAlignment.vertical = alignment.vertical;

        InvalidateLayout();
}


bool
BSpaceLayoutItem::IsVisible()
{
        return fVisible;
}


void
BSpaceLayoutItem::SetVisible(bool visible)
{
        fVisible = visible;
}


BRect
BSpaceLayoutItem::Frame()
{
        return fFrame;
}


void
BSpaceLayoutItem::SetFrame(BRect frame)
{
        fFrame = frame;
}


status_t
BSpaceLayoutItem::Archive(BMessage* into, bool deep) const
{
        status_t err = BLayoutItem::Archive(into, deep);

        if (err == B_OK)
                err = into->AddRect(kFrameField, fFrame);

        if (err == B_OK)
                err = into->AddSize(kSizesField, fMinSize);

        if (err == B_OK)
                err = into->AddSize(kSizesField, fMaxSize);

        if (err == B_OK)
                err = into->AddSize(kSizesField, fPreferredSize);

        if (err == B_OK)
                err = into->AddAlignment(kAlignmentField, fAlignment);

        if (err == B_OK)
                err = into->AddBool(kVisibleField, fVisible);

        return err;
}


BArchivable*
BSpaceLayoutItem::Instantiate(BMessage* from)
{
        if (validate_instantiation(from, "BSpaceLayoutItem"))
                return new(std::nothrow) BSpaceLayoutItem(from);
        return NULL;
}


void BSpaceLayoutItem::_ReservedSpaceLayoutItem1() {}
void BSpaceLayoutItem::_ReservedSpaceLayoutItem2() {}
void BSpaceLayoutItem::_ReservedSpaceLayoutItem3() {}
void BSpaceLayoutItem::_ReservedSpaceLayoutItem4() {}
void BSpaceLayoutItem::_ReservedSpaceLayoutItem5() {}
void BSpaceLayoutItem::_ReservedSpaceLayoutItem6() {}
void BSpaceLayoutItem::_ReservedSpaceLayoutItem7() {}
void BSpaceLayoutItem::_ReservedSpaceLayoutItem8() {}
void BSpaceLayoutItem::_ReservedSpaceLayoutItem9() {}
void BSpaceLayoutItem::_ReservedSpaceLayoutItem10() {}