Patch by Alex Wilson:

* Implemented archiving/unarchiving support.
* Coding style cleanup (some more by myself).


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@37542 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2010-07-17 00:09:06 +00:00
parent 80c2bbd8ae
commit d1535a45df
2 changed files with 270 additions and 81 deletions
+12 -3
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2006, Haiku, Inc. All rights reserved. * Copyright 2006-2010, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#ifndef _GRID_LAYOUT_H #ifndef _GRID_LAYOUT_H
@@ -8,11 +8,11 @@
#include <TwoDimensionalLayout.h> #include <TwoDimensionalLayout.h>
class BGridLayout : public BTwoDimensionalLayout { class BGridLayout : public BTwoDimensionalLayout {
public: public:
BGridLayout(float horizontal = 0.0f, BGridLayout(float horizontal = 0.0f,
float vertical = 0.0f); float vertical = 0.0f);
BGridLayout(BMessage* from);
virtual ~BGridLayout(); virtual ~BGridLayout();
int32 CountColumns() const; int32 CountColumns() const;
@@ -54,6 +54,14 @@ public:
int32 row, int32 columnCount = 1, int32 row, int32 columnCount = 1,
int32 rowCount = 1); int32 rowCount = 1);
virtual status_t Archive(BMessage* into, bool deep = true) const;
static BArchivable* Instantiate(BMessage* from);
virtual status_t ItemArchived(BMessage* into,
BLayoutItem* item, int32 index) const;
virtual status_t ItemUnarchived(const BMessage* from,
BLayoutItem* item, int32 index);
protected: protected:
virtual void ItemAdded(BLayoutItem* item); virtual void ItemAdded(BLayoutItem* item);
virtual void ItemRemoved(BLayoutItem* item); virtual void ItemRemoved(BLayoutItem* item);
@@ -67,7 +75,7 @@ protected:
enum orientation orientation, enum orientation orientation,
int32 index, int32 index,
ColumnRowConstraints* constraints); ColumnRowConstraints* constraints);
virtual void GetItemDimensions(BLayoutItem* item, virtual void GetItemDimensions(BLayoutItem* item,
Dimensions* dimensions); Dimensions* dimensions);
private: private:
@@ -79,6 +87,7 @@ private:
bool _AreGridCellsEmpty(int32 column, int32 row, bool _AreGridCellsEmpty(int32 column, int32 row,
int32 columnCount, int32 rowCount); int32 columnCount, int32 rowCount);
bool _InsertItemIntoGrid(BLayoutItem* item);
bool _ResizeGrid(int32 columnCount, int32 rowCount); bool _ResizeGrid(int32 columnCount, int32 rowCount);
ItemLayoutData* _LayoutDataForItem(BLayoutItem* item) const; ItemLayoutData* _LayoutDataForItem(BLayoutItem* item) const;
+249 -69
View File
@@ -1,8 +1,10 @@
/* /*
* Copyright 2010, Haiku Inc.
* Copyright 2006, Ingo Weinhold <[email protected]>. * Copyright 2006, Ingo Weinhold <[email protected]>.
* All rights reserved. Distributed under the terms of the MIT License. * All rights reserved. Distributed under the terms of the MIT License.
*/ */
#include <GridLayout.h> #include <GridLayout.h>
#include <algorithm> #include <algorithm>
@@ -11,21 +13,39 @@
#include <LayoutItem.h> #include <LayoutItem.h>
#include <List.h> #include <List.h>
#include <Message.h>
#include "ViewLayoutItem.h" #include "ViewLayoutItem.h"
using std::nothrow; using std::nothrow;
using std::swap; using std::swap;
enum { enum {
MAX_COLUMN_ROW_COUNT = 1024, MAX_COLUMN_ROW_COUNT = 1024,
}; };
// a placeholder we put in our grid array to make a cell occupied
static BLayoutItem* const OCCUPIED_GRID_CELL = (BLayoutItem*)0x1; namespace {
// a placeholder we put in our grid array to make a cell occupied
BLayoutItem* const OCCUPIED_GRID_CELL = (BLayoutItem*)0x1;
const char* kRowCountField = "gridlayout:rowcount";
const char* kRowMinSizeField = "gridlayout:rowminsize";
const char* kRowMaxSizeField = "gridlayout:rowmaxsize";
const char* kRowWeightField = "gridlayout:rowweight";
const char* kColumnCountField = "gridlayout:columncount";
const char* kColumnMinSizeField = "gridlayout:columnminsize";
const char* kColumnMaxSizeField = "gridlayout:columnmaxsize";
const char* kColumnWeightField = "gridlayout:columnweight";
const char* kItemHeight = "gridlayout:item:height";
const char* kItemWidth = "gridlayout:item:width";
const char* kItemX = "gridlayout:item:x";
const char* kItemY = "gridlayout:item:y";
}
// ItemLayoutData
struct BGridLayout::ItemLayoutData { struct BGridLayout::ItemLayoutData {
Dimensions dimensions; Dimensions dimensions;
@@ -38,10 +58,9 @@ struct BGridLayout::ItemLayoutData {
} }
}; };
// RowInfoArray
class BGridLayout::RowInfoArray { class BGridLayout::RowInfoArray {
public: public:
RowInfoArray() RowInfoArray()
{ {
} }
@@ -135,20 +154,73 @@ private:
}; };
// constructor
BGridLayout::BGridLayout(float horizontal, float vertical) BGridLayout::BGridLayout(float horizontal, float vertical)
: fGrid(NULL), :
fColumnCount(0), fGrid(NULL),
fRowCount(0), fColumnCount(0),
fRowInfos(new RowInfoArray), fRowCount(0),
fColumnInfos(new RowInfoArray), fRowInfos(new RowInfoArray),
fMultiColumnItems(0), fColumnInfos(new RowInfoArray),
fMultiRowItems(0) fMultiColumnItems(0),
fMultiRowItems(0)
{ {
SetSpacing(horizontal, vertical); SetSpacing(horizontal, vertical);
} }
// destructor
BGridLayout::BGridLayout(BMessage* from)
:
BTwoDimensionalLayout(BUnarchiver::PrepareArchive(from)),
fGrid(NULL),
fColumnCount(0),
fRowCount(0),
fRowInfos(new RowInfoArray),
fColumnInfos(new RowInfoArray),
fMultiColumnItems(0),
fMultiRowItems(0)
{
int32 rows;
int32 columns;
BUnarchiver unarchiver(from);
if (from->FindInt32(kRowCountField, &rows) != B_OK)
fRowCount = 0;
if (from->FindInt32(kColumnCountField, &columns) != B_OK)
fColumnCount = 0;
// sets fColumnCount && fRowCount on success
if (!_ResizeGrid(columns, rows)) {
unarchiver.Finish(B_NO_MEMORY);
return;
}
for (int32 i = 0; i < fRowCount; i++) {
float getter;
if (from->FindFloat(kRowWeightField, i, &getter) == B_OK)
fRowInfos->SetWeight(i, getter);
if (from->FindFloat(kRowMinSizeField, i, &getter) == B_OK)
fRowInfos->SetMinSize(i, getter);
if (from->FindFloat(kRowMaxSizeField, i, &getter) == B_OK)
fRowInfos->SetMaxSize(i, getter);
}
for (int32 i = 0; i < fColumnCount; i++) {
float getter;
if (from->FindFloat(kColumnWeightField, i, &getter) == B_OK)
fColumnInfos->SetWeight(i, getter);
if (from->FindFloat(kColumnMinSizeField, i, &getter) == B_OK)
fColumnInfos->SetMinSize(i, getter);
if (from->FindFloat(kColumnMaxSizeField, i, &getter) == B_OK)
fColumnInfos->SetMaxSize(i, getter);
}
}
BGridLayout::~BGridLayout() BGridLayout::~BGridLayout()
{ {
delete fRowInfos; delete fRowInfos;
@@ -156,7 +228,6 @@ BGridLayout::~BGridLayout()
} }
// CountColumns
int32 int32
BGridLayout::CountColumns() const BGridLayout::CountColumns() const
{ {
@@ -164,7 +235,6 @@ BGridLayout::CountColumns() const
} }
// CountRows
int32 int32
BGridLayout::CountRows() const BGridLayout::CountRows() const
{ {
@@ -172,21 +242,20 @@ BGridLayout::CountRows() const
} }
// HorizontalSpacing
float float
BGridLayout::HorizontalSpacing() const BGridLayout::HorizontalSpacing() const
{ {
return fHSpacing; return fHSpacing;
} }
// VerticalSpacing
float float
BGridLayout::VerticalSpacing() const BGridLayout::VerticalSpacing() const
{ {
return fVSpacing; return fVSpacing;
} }
// SetHorizontalSpacing
void void
BGridLayout::SetHorizontalSpacing(float spacing) BGridLayout::SetHorizontalSpacing(float spacing)
{ {
@@ -197,7 +266,7 @@ BGridLayout::SetHorizontalSpacing(float spacing)
} }
} }
// SetVerticalSpacing
void void
BGridLayout::SetVerticalSpacing(float spacing) BGridLayout::SetVerticalSpacing(float spacing)
{ {
@@ -208,7 +277,7 @@ BGridLayout::SetVerticalSpacing(float spacing)
} }
} }
// SetSpacing
void void
BGridLayout::SetSpacing(float horizontal, float vertical) BGridLayout::SetSpacing(float horizontal, float vertical)
{ {
@@ -220,105 +289,105 @@ BGridLayout::SetSpacing(float horizontal, float vertical)
} }
} }
// ColumnWeight
float float
BGridLayout::ColumnWeight(int32 column) const BGridLayout::ColumnWeight(int32 column) const
{ {
return fColumnInfos->Weight(column); return fColumnInfos->Weight(column);
} }
// SetColumnWeight
void void
BGridLayout::SetColumnWeight(int32 column, float weight) BGridLayout::SetColumnWeight(int32 column, float weight)
{ {
fColumnInfos->SetWeight(column, weight); fColumnInfos->SetWeight(column, weight);
} }
// MinColumnWidth
float float
BGridLayout::MinColumnWidth(int32 column) const BGridLayout::MinColumnWidth(int32 column) const
{ {
return fColumnInfos->MinSize(column); return fColumnInfos->MinSize(column);
} }
// SetMinColumnWidth
void void
BGridLayout::SetMinColumnWidth(int32 column, float width) BGridLayout::SetMinColumnWidth(int32 column, float width)
{ {
fColumnInfos->SetMinSize(column, width); fColumnInfos->SetMinSize(column, width);
} }
// MaxColumnWidth
float float
BGridLayout::MaxColumnWidth(int32 column) const BGridLayout::MaxColumnWidth(int32 column) const
{ {
return fColumnInfos->MaxSize(column); return fColumnInfos->MaxSize(column);
} }
// SetMaxColumnWidth
void void
BGridLayout::SetMaxColumnWidth(int32 column, float width) BGridLayout::SetMaxColumnWidth(int32 column, float width)
{ {
fColumnInfos->SetMaxSize(column, width); fColumnInfos->SetMaxSize(column, width);
} }
// RowWeight
float float
BGridLayout::RowWeight(int32 row) const BGridLayout::RowWeight(int32 row) const
{ {
return fRowInfos->Weight(row); return fRowInfos->Weight(row);
} }
// SetRowWeight
void void
BGridLayout::SetRowWeight(int32 row, float weight) BGridLayout::SetRowWeight(int32 row, float weight)
{ {
fRowInfos->SetWeight(row, weight); fRowInfos->SetWeight(row, weight);
} }
// MinRowHeight
float float
BGridLayout::MinRowHeight(int row) const BGridLayout::MinRowHeight(int row) const
{ {
return fRowInfos->MinSize(row); return fRowInfos->MinSize(row);
} }
// SetMinRowHeight
void void
BGridLayout::SetMinRowHeight(int32 row, float height) BGridLayout::SetMinRowHeight(int32 row, float height)
{ {
fRowInfos->SetMinSize(row, height); fRowInfos->SetMinSize(row, height);
} }
// MaxRowHeight
float float
BGridLayout::MaxRowHeight(int32 row) const BGridLayout::MaxRowHeight(int32 row) const
{ {
return fRowInfos->MaxSize(row); return fRowInfos->MaxSize(row);
} }
// SetMaxRowHeight
void void
BGridLayout::SetMaxRowHeight(int32 row, float height) BGridLayout::SetMaxRowHeight(int32 row, float height)
{ {
fRowInfos->SetMaxSize(row, height); fRowInfos->SetMaxSize(row, height);
} }
// AddView
BLayoutItem* BLayoutItem*
BGridLayout::AddView(BView* child) BGridLayout::AddView(BView* child)
{ {
return BTwoDimensionalLayout::AddView(child); return BTwoDimensionalLayout::AddView(child);
} }
// AddView
BLayoutItem* BLayoutItem*
BGridLayout::AddView(int32 index, BView* child) BGridLayout::AddView(int32 index, BView* child)
{ {
return BTwoDimensionalLayout::AddView(index, child); return BTwoDimensionalLayout::AddView(index, child);
} }
// AddView
BLayoutItem* BLayoutItem*
BGridLayout::AddView(BView* child, int32 column, int32 row, int32 columnCount, BGridLayout::AddView(BView* child, int32 column, int32 row, int32 columnCount,
int32 rowCount) int32 rowCount)
@@ -335,7 +404,7 @@ BGridLayout::AddView(BView* child, int32 column, int32 row, int32 columnCount,
return item; return item;
} }
// AddItem
bool bool
BGridLayout::AddItem(BLayoutItem* item) BGridLayout::AddItem(BLayoutItem* item)
{ {
@@ -351,14 +420,14 @@ BGridLayout::AddItem(BLayoutItem* item)
return AddItem(item, fColumnCount, 0, 1, 1); return AddItem(item, fColumnCount, 0, 1, 1);
} }
// AddItem
bool bool
BGridLayout::AddItem(int32 index, BLayoutItem* item) BGridLayout::AddItem(int32 index, BLayoutItem* item)
{ {
return AddItem(item); return AddItem(item);
} }
// AddItem
bool bool
BGridLayout::AddItem(BLayoutItem* item, int32 column, int32 row, BGridLayout::AddItem(BLayoutItem* item, int32 column, int32 row,
int32 columnCount, int32 rowCount) int32 columnCount, int32 rowCount)
@@ -378,24 +447,9 @@ BGridLayout::AddItem(BLayoutItem* item, int32 column, int32 row,
data->dimensions.height = rowCount; data->dimensions.height = rowCount;
} }
// resize the grid, if necessary if (!_InsertItemIntoGrid(item)) {
int32 newColumnCount = max_c(fColumnCount, column + columnCount); RemoveItem(item);
int32 newRowCount = max_c(fRowCount, row + rowCount); return false;
if (newColumnCount > fColumnCount || newRowCount > fRowCount) {
if (!_ResizeGrid(newColumnCount, newRowCount)) {
RemoveItem(item);
return false;
}
}
// enter the item in the grid
for (int32 x = 0; x < columnCount; x++) {
for (int32 y = 0; y < rowCount; y++) {
if (x == 0 && y == 0)
fGrid[column + x][row + y] = item;
else
fGrid[column + x][row + y] = OCCUPIED_GRID_CELL;
}
} }
if (columnCount > 1) if (columnCount > 1)
@@ -406,14 +460,110 @@ BGridLayout::AddItem(BLayoutItem* item, int32 column, int32 row,
return success; return success;
} }
// ItemAdded
status_t
BGridLayout::Archive(BMessage* into, bool deep) const
{
BArchiver archiver(into);
status_t err = BTwoDimensionalLayout::Archive(into, deep);
if (err == B_OK)
err = into->AddInt32(kRowCountField, fRowCount);
if (err == B_OK)
err = into->AddInt32(kColumnCountField, fColumnCount);
for (int32 i = 0; i < fRowCount && err == B_OK; i++) {
err = into->AddFloat(kRowWeightField, fRowInfos->Weight(i));
if (err == B_OK)
err = into->AddFloat(kRowMinSizeField, fRowInfos->MinSize(i));
if (err == B_OK)
err = into->AddFloat(kRowMaxSizeField, fRowInfos->MaxSize(i));
}
for (int32 i = 0; i < fColumnCount && err == B_OK; i++) {
err = into->AddFloat(kColumnWeightField, fRowInfos->Weight(i));
if (err == B_OK)
err = into->AddFloat(kColumnMinSizeField, fRowInfos->MinSize(i));
if (err == B_OK)
err = into->AddFloat(kColumnMaxSizeField, fRowInfos->MaxSize(i));
}
return archiver.Finish(err);
}
BArchivable*
BGridLayout::Instantiate(BMessage* from)
{
if (validate_instantiation(from, "BGridLayout"))
return new BGridLayout(from);
return NULL;
}
status_t
BGridLayout::ItemArchived(BMessage* into, BLayoutItem* item, int32 index) const
{
ItemLayoutData* data = _LayoutDataForItem(item);
if (!data) // TODO: remove this check once AddItem() returns a bool
return B_ERROR;
status_t err = into->AddInt32(kItemX, data->dimensions.x);
if (err == B_OK)
err = into->AddInt32(kItemY, data->dimensions.y);
if (err == B_OK)
err = into->AddInt32(kItemWidth, data->dimensions.width);
if (err == B_OK)
err = into->AddInt32(kItemHeight, data->dimensions.height);
return err;
}
status_t
BGridLayout::ItemUnarchived(const BMessage* from,
BLayoutItem* item, int32 index)
{
ItemLayoutData* data = _LayoutDataForItem(item);
if (!data) { // TODO: remove this check once AddItem() returns a bool
data = new ItemLayoutData();
item->SetLayoutData(data);
}
Dimensions& dimensions = data->dimensions;
status_t err = from->FindInt32(kItemX, index, &dimensions.x);
if (err == B_OK)
err = from->FindInt32(kItemY, index, &dimensions.y);
if (err == B_OK)
err = from->FindInt32(kItemWidth, index, &dimensions.width);
if (err == B_OK)
err = from->FindInt32(kItemHeight, index, &dimensions.height);
if (err == B_OK && !_AreGridCellsEmpty(dimensions.x, dimensions.y,
dimensions.width, dimensions.height))
err = B_BAD_DATA;
if (err == B_OK && !_InsertItemIntoGrid(item))
err = B_NO_MEMORY;
if (err == B_OK && dimensions.width > 1)
fMultiColumnItems++;
if (err == B_OK && dimensions.height > 1)
fMultiRowItems++;
return err;
}
void void
BGridLayout::ItemAdded(BLayoutItem* item) BGridLayout::ItemAdded(BLayoutItem* item)
{ {
item->SetLayoutData(new ItemLayoutData); item->SetLayoutData(new ItemLayoutData);
} }
// ItemRemoved
void void
BGridLayout::ItemRemoved(BLayoutItem* item) BGridLayout::ItemRemoved(BLayoutItem* item)
{ {
@@ -469,35 +619,35 @@ BGridLayout::ItemRemoved(BLayoutItem* item)
} }
} }
// HasMultiColumnItems
bool bool
BGridLayout::HasMultiColumnItems() BGridLayout::HasMultiColumnItems()
{ {
return (fMultiColumnItems > 0); return (fMultiColumnItems > 0);
} }
// HasMultiRowItems
bool bool
BGridLayout::HasMultiRowItems() BGridLayout::HasMultiRowItems()
{ {
return (fMultiRowItems > 0); return (fMultiRowItems > 0);
} }
// InternalCountColumns
int32 int32
BGridLayout::InternalCountColumns() BGridLayout::InternalCountColumns()
{ {
return fColumnCount; return fColumnCount;
} }
// InternalCountRows
int32 int32
BGridLayout::InternalCountRows() BGridLayout::InternalCountRows()
{ {
return fRowCount; return fRowCount;
} }
// GetColumnRowConstraints
void void
BGridLayout::GetColumnRowConstraints(enum orientation orientation, int32 index, BGridLayout::GetColumnRowConstraints(enum orientation orientation, int32 index,
ColumnRowConstraints* constraints) ColumnRowConstraints* constraints)
@@ -513,7 +663,7 @@ BGridLayout::GetColumnRowConstraints(enum orientation orientation, int32 index,
} }
} }
// GetItemDimensions
void void
BGridLayout::GetItemDimensions(BLayoutItem* item, Dimensions* dimensions) BGridLayout::GetItemDimensions(BLayoutItem* item, Dimensions* dimensions)
{ {
@@ -521,7 +671,7 @@ BGridLayout::GetItemDimensions(BLayoutItem* item, Dimensions* dimensions)
*dimensions = data->dimensions; *dimensions = data->dimensions;
} }
// _IsGridCellEmpty
bool bool
BGridLayout::_IsGridCellEmpty(int32 column, int32 row) BGridLayout::_IsGridCellEmpty(int32 column, int32 row)
{ {
@@ -533,7 +683,7 @@ BGridLayout::_IsGridCellEmpty(int32 column, int32 row)
return (fGrid[column][row] == NULL); return (fGrid[column][row] == NULL);
} }
// _AreGridCellsEmpty
bool bool
BGridLayout::_AreGridCellsEmpty(int32 column, int32 row, int32 columnCount, BGridLayout::_AreGridCellsEmpty(int32 column, int32 row, int32 columnCount,
int32 rowCount) int32 rowCount)
@@ -553,7 +703,37 @@ BGridLayout::_AreGridCellsEmpty(int32 column, int32 row, int32 columnCount,
return true; return true;
} }
// _ResizeGrid
bool
BGridLayout::_InsertItemIntoGrid(BLayoutItem* item)
{
BGridLayout::ItemLayoutData* data = _LayoutDataForItem(item);
int32 column = data->dimensions.x;
int32 columnCount = data->dimensions.width;
int32 row = data->dimensions.y;
int32 rowCount = data->dimensions.height;
// resize the grid, if necessary
int32 newColumnCount = max_c(fColumnCount, column + columnCount);
int32 newRowCount = max_c(fRowCount, row + rowCount);
if (newColumnCount > fColumnCount || newRowCount > fRowCount) {
if (!_ResizeGrid(newColumnCount, newRowCount))
return false;
}
// enter the item in the grid
for (int32 x = 0; x < columnCount; x++) {
for (int32 y = 0; y < rowCount; y++) {
if (x == 0 && y == 0)
fGrid[column + x][row + y] = item;
else
fGrid[column + x][row + y] = OCCUPIED_GRID_CELL;
}
}
return true;
}
bool bool
BGridLayout::_ResizeGrid(int32 columnCount, int32 rowCount) BGridLayout::_ResizeGrid(int32 columnCount, int32 rowCount)
{ {
@@ -597,7 +777,7 @@ BGridLayout::_ResizeGrid(int32 columnCount, int32 rowCount)
return success; return success;
} }
// _LayoutDataForItem
BGridLayout::ItemLayoutData* BGridLayout::ItemLayoutData*
BGridLayout::_LayoutDataForItem(BLayoutItem* item) const BGridLayout::_LayoutDataForItem(BLayoutItem* item) const
{ {