Ticket #5525: gridLayout.patch

File gridLayout.patch, 14.3 KB (added by yourpalal, 14 years ago)

implement archiving of BGridLayout class.

  • src/kits/interface/GridLayout.cpp

     
    11/*
     2 * Copyright 2010, Haiku Inc.
    23 * Copyright 2006, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
    34 * All rights reserved. Distributed under the terms of the MIT License.
    45 */
     
    1112
    1213#include <LayoutItem.h>
    1314#include <List.h>
     15#include <Message.h>
    1416
    1517#include "ViewLayoutItem.h"
    1618
     
    2123    MAX_COLUMN_ROW_COUNT    = 1024,
    2224};
    2325
    24 // a placeholder we put in our grid array to make a cell occupied
    25 static BLayoutItem* const OCCUPIED_GRID_CELL = (BLayoutItem*)0x1;
     26namespace {
     27    // a placeholder we put in our grid array to make a cell occupied
     28    BLayoutItem* const OCCUPIED_GRID_CELL = (BLayoutItem*)0x1;
    2629
     30    const char* kRowCountField = "gridlayout:rowcount";
     31    const char* kRowMinSizeField = "gridlayout:rowminsize";
     32    const char* kRowMaxSizeField = "gridlayout:rowmaxsize";
     33    const char* kRowWeightField = "gridlayout:rowweight";
     34    const char* kColumnCountField = "gridlayout:columncount";
     35    const char* kColumnMinSizeField = "gridlayout:columnminsize";
     36    const char* kColumnMaxSizeField = "gridlayout:columnmaxsize";
     37    const char* kColumnWeightField = "gridlayout:columnweight";
     38    const char* kItemHeight = "gridlayout:item:height";
     39    const char* kItemWidth = "gridlayout:item:width";
     40    const char* kItemX = "gridlayout:item:x";
     41    const char* kItemY = "gridlayout:item:y";
     42}
    2743
    28 // ItemLayoutData
     44
    2945struct BGridLayout::ItemLayoutData {
    3046    Dimensions  dimensions;
    3147
     
    3854    }
    3955};
    4056
    41 // RowInfoArray
     57
    4258class BGridLayout::RowInfoArray {
    4359public:
    4460
     
    135151};
    136152
    137153
    138 // constructor
     154
    139155BGridLayout::BGridLayout(float horizontal, float vertical)
    140     : fGrid(NULL),
    141       fColumnCount(0),
    142       fRowCount(0),
    143       fRowInfos(new RowInfoArray),
    144       fColumnInfos(new RowInfoArray),
    145       fMultiColumnItems(0),
    146       fMultiRowItems(0)
     156    :
     157    fGrid(NULL),
     158    fColumnCount(0),
     159    fRowCount(0),
     160    fRowInfos(new RowInfoArray),
     161    fColumnInfos(new RowInfoArray),
     162    fMultiColumnItems(0),
     163    fMultiRowItems(0)
    147164{
    148165    SetSpacing(horizontal, vertical);
    149166}
    150167
    151 // destructor
     168
     169BGridLayout::BGridLayout(BMessage* from)
     170    :
     171    BTwoDimensionalLayout(BUnarchiver::PrepareArchive(from)),
     172    fGrid(NULL),
     173    fColumnCount(0),
     174    fRowCount(0),
     175    fRowInfos(new RowInfoArray),
     176    fColumnInfos(new RowInfoArray),
     177    fMultiColumnItems(0),
     178    fMultiRowItems(0)
     179{
     180    int32 rows;
     181    int32 columns;
     182    BUnarchiver unarchiver(from);
     183
     184    if (from->FindInt32(kRowCountField, &rows) != B_OK)
     185        fRowCount = 0;
     186
     187    if (from->FindInt32(kColumnCountField, &columns) != B_OK)
     188        fColumnCount = 0;
     189
     190    // sets fColumnCount && fRowCount on success
     191    if (!_ResizeGrid(columns, rows)) {
     192        unarchiver.Finish(B_NO_MEMORY);
     193        return;
     194    }
     195
     196    for (int32 i = 0; i < fRowCount; i++) {
     197        float getter;
     198        if (from->FindFloat(kRowWeightField, i, &getter) == B_OK)
     199            fRowInfos->SetWeight(i, getter);
     200
     201        if (from->FindFloat(kRowMinSizeField, i, &getter) == B_OK)
     202            fRowInfos->SetMinSize(i, getter);
     203
     204        if (from->FindFloat(kRowMaxSizeField, i, &getter) == B_OK)
     205            fRowInfos->SetMaxSize(i, getter);
     206    }
     207
     208
     209    for (int32 i = 0; i < fColumnCount; i++) {
     210        float getter;
     211        if (from->FindFloat(kColumnWeightField, i, &getter) == B_OK)
     212            fColumnInfos->SetWeight(i, getter);
     213
     214        if (from->FindFloat(kColumnMinSizeField, i, &getter) == B_OK)
     215            fColumnInfos->SetMinSize(i, getter);
     216
     217        if (from->FindFloat(kColumnMaxSizeField, i, &getter) == B_OK)
     218            fColumnInfos->SetMaxSize(i, getter);
     219    }
     220}
     221
     222
    152223BGridLayout::~BGridLayout()
    153224{
    154225    delete fRowInfos;
     
    156227}
    157228
    158229
    159 // CountColumns
    160230int32
    161231BGridLayout::CountColumns() const
    162232{
     
    164234}
    165235
    166236
    167 // CountRows
    168237int32
    169238BGridLayout::CountRows() const
    170239{
     
    172241}
    173242
    174243
    175 // HorizontalSpacing
    176244float
    177245BGridLayout::HorizontalSpacing() const
    178246{
    179247    return fHSpacing;
    180248}
    181249
    182 // VerticalSpacing
     250
    183251float
    184252BGridLayout::VerticalSpacing() const
    185253{
    186254    return fVSpacing;
    187255}
    188256
    189 // SetHorizontalSpacing
     257
    190258void
    191259BGridLayout::SetHorizontalSpacing(float spacing)
    192260{
     
    197265    }
    198266}
    199267
    200 // SetVerticalSpacing
     268
    201269void
    202270BGridLayout::SetVerticalSpacing(float spacing)
    203271{
     
    208276    }
    209277}
    210278
    211 // SetSpacing
     279
    212280void
    213281BGridLayout::SetSpacing(float horizontal, float vertical)
    214282{
     
    220288    }
    221289}
    222290
    223 // ColumnWeight
     291
    224292float
    225293BGridLayout::ColumnWeight(int32 column) const
    226294{
    227295    return fColumnInfos->Weight(column);
    228296}
    229297
    230 // SetColumnWeight
     298
    231299void
    232300BGridLayout::SetColumnWeight(int32 column, float weight)
    233301{
    234302    fColumnInfos->SetWeight(column, weight);
    235303}
    236304
    237 // MinColumnWidth
     305
    238306float
    239307BGridLayout::MinColumnWidth(int32 column) const
    240308{
    241309    return fColumnInfos->MinSize(column);
    242310}
    243311
    244 // SetMinColumnWidth
     312
    245313void
    246314BGridLayout::SetMinColumnWidth(int32 column, float width)
    247315{
    248316    fColumnInfos->SetMinSize(column, width);
    249317}
    250318
    251 // MaxColumnWidth
     319
    252320float
    253321BGridLayout::MaxColumnWidth(int32 column) const
    254322{
    255323    return fColumnInfos->MaxSize(column);
    256324}
    257325   
    258 // SetMaxColumnWidth
     326
    259327void
    260328BGridLayout::SetMaxColumnWidth(int32 column, float width)
    261329{
    262330    fColumnInfos->SetMaxSize(column, width);
    263331}
    264332
    265 // RowWeight
     333
    266334float
    267335BGridLayout::RowWeight(int32 row) const
    268336{
    269337    return fRowInfos->Weight(row);
    270338}
    271339
    272 // SetRowWeight
     340
    273341void
    274342BGridLayout::SetRowWeight(int32 row, float weight)
    275343{
    276344    fRowInfos->SetWeight(row, weight);
    277345}
    278346
    279 // MinRowHeight
     347
    280348float
    281349BGridLayout::MinRowHeight(int row) const
    282350{
    283351    return fRowInfos->MinSize(row);
    284352}
    285353
    286 // SetMinRowHeight
     354
    287355void
    288356BGridLayout::SetMinRowHeight(int32 row, float height)
    289357{
    290358    fRowInfos->SetMinSize(row, height);
    291359}
    292360
    293 // MaxRowHeight
     361
    294362float
    295363BGridLayout::MaxRowHeight(int32 row) const
    296364{
    297365    return fRowInfos->MaxSize(row);
    298366}
    299367
    300 // SetMaxRowHeight
     368
    301369void
    302370BGridLayout::SetMaxRowHeight(int32 row, float height)
    303371{
    304372    fRowInfos->SetMaxSize(row, height);
    305373}
    306374
    307 // AddView
     375
    308376BLayoutItem*
    309377BGridLayout::AddView(BView* child)
    310378{
    311379    return BTwoDimensionalLayout::AddView(child);
    312380}
    313381
    314 // AddView
     382
    315383BLayoutItem*
    316384BGridLayout::AddView(int32 index, BView* child)
    317385{
    318386    return BTwoDimensionalLayout::AddView(index, child);
    319387}
    320388
    321 // AddView
     389
    322390BLayoutItem*
    323391BGridLayout::AddView(BView* child, int32 column, int32 row, int32 columnCount,
    324392    int32 rowCount)
     
    335403    return item;
    336404}
    337405
    338 // AddItem
     406
    339407bool
    340408BGridLayout::AddItem(BLayoutItem* item)
    341409{
     
    351419    return AddItem(item, fColumnCount, 0, 1, 1);
    352420}
    353421
    354 // AddItem
     422
    355423bool
    356424BGridLayout::AddItem(int32 index, BLayoutItem* item)
    357425{
    358426    return AddItem(item);
    359427}
    360428
    361 // AddItem
     429
    362430bool
    363431BGridLayout::AddItem(BLayoutItem* item, int32 column, int32 row,
    364432    int32 columnCount, int32 rowCount)
     
    378446        data->dimensions.height = rowCount;
    379447    }
    380448
    381     // resize the grid, if necessary
    382     int32 newColumnCount = max_c(fColumnCount, column + columnCount);
    383     int32 newRowCount = max_c(fRowCount, row + rowCount);
    384     if (newColumnCount > fColumnCount || newRowCount > fRowCount) {
    385         if (!_ResizeGrid(newColumnCount, newRowCount)) {
    386             RemoveItem(item);
    387             return false;
    388         }
     449    if (!_InsertItemIntoGrid(item)) {
     450        RemoveItem(item);
     451        return false;
    389452    }
    390453
    391     // enter the item in the grid
    392     for (int32 x = 0; x < columnCount; x++) {
    393         for (int32 y = 0; y < rowCount; y++) {
    394             if (x == 0 && y == 0)
    395                 fGrid[column + x][row + y] = item;
    396             else
    397                 fGrid[column + x][row + y] = OCCUPIED_GRID_CELL;
    398         }
    399     }
    400 
    401454    if (columnCount > 1)
    402455        fMultiColumnItems++;
    403456    if (rowCount > 1)
     
    406459    return success;
    407460}
    408461
    409 // ItemAdded
     462
     463status_t
     464BGridLayout::Archive(BMessage* into, bool deep) const
     465{
     466    BArchiver archiver(into);
     467    status_t err = BTwoDimensionalLayout::Archive(into, deep);
     468
     469    if (err == B_OK)
     470        err = into->AddInt32(kRowCountField, fRowCount);
     471    if (err == B_OK)
     472        err = into->AddInt32(kColumnCountField, fColumnCount);
     473
     474    for (int32 i = 0; i < fRowCount && err == B_OK; i++) {
     475        err = into->AddFloat(kRowWeightField, fRowInfos->Weight(i));
     476        if (err == B_OK)
     477            err = into->AddFloat(kRowMinSizeField, fRowInfos->MinSize(i));
     478        if (err == B_OK)
     479            err = into->AddFloat(kRowMaxSizeField, fRowInfos->MaxSize(i));
     480    }
     481
     482    for (int32 i = 0; i < fColumnCount && err == B_OK; i++) {
     483        err = into->AddFloat(kColumnWeightField, fRowInfos->Weight(i));
     484        if (err == B_OK)
     485            err = into->AddFloat(kColumnMinSizeField, fRowInfos->MinSize(i));
     486        if (err == B_OK)
     487            err = into->AddFloat(kColumnMaxSizeField, fRowInfos->MaxSize(i));
     488    }
     489
     490    return archiver.Finish(err);
     491}
     492
     493
     494BArchivable*
     495BGridLayout::Instantiate(BMessage* from)
     496{
     497    if (validate_instantiation(from, "BGridLayout"))
     498        return new BGridLayout(from);
     499    return NULL;
     500}
     501
     502
     503status_t
     504BGridLayout::ItemArchived(BMessage* into, BLayoutItem* item, int32 index) const
     505{
     506    ItemLayoutData* data =  _LayoutDataForItem(item);
     507    if (!data) // TODO: remove this check once AddItem() returns a bool
     508        return B_ERROR;
     509
     510    status_t err = into->AddInt32(kItemX, data->dimensions.x);
     511    if (err == B_OK)
     512        err = into->AddInt32(kItemY, data->dimensions.y);
     513    if (err == B_OK)
     514        err = into->AddInt32(kItemWidth, data->dimensions.width);
     515    if (err == B_OK)
     516        err = into->AddInt32(kItemHeight, data->dimensions.height);
     517
     518    return err;
     519}
     520
     521
     522status_t
     523BGridLayout::ItemUnarchived(const BMessage* from,
     524    BLayoutItem* item, int32 index)
     525{
     526    ItemLayoutData* data = _LayoutDataForItem(item);
     527    if (!data) { // TODO: remove this check once AddItem() returns a bool
     528        data = new ItemLayoutData();
     529        item->SetLayoutData(data);
     530    }
     531
     532    Dimensions& dimensions = data->dimensions;
     533    status_t err = from->FindInt32(kItemX, index, &dimensions.x);
     534    if (err == B_OK)
     535        err = from->FindInt32(kItemY, index, &dimensions.y);
     536
     537    if (err == B_OK)
     538        err = from->FindInt32(kItemWidth, index, &dimensions.width);
     539
     540    if (err == B_OK)
     541        err = from->FindInt32(kItemHeight, index, &dimensions.height);
     542
     543    if (err == B_OK && !_AreGridCellsEmpty(dimensions.x, dimensions.y,
     544        dimensions.width, dimensions.height))
     545        err = B_BAD_DATA;
     546
     547    if (err == B_OK && !_InsertItemIntoGrid(item))
     548        err = B_NO_MEMORY;
     549
     550    if (err == B_OK && dimensions.width > 1)
     551        fMultiColumnItems++;
     552    if (err == B_OK && dimensions.height > 1)
     553        fMultiRowItems++;
     554   
     555    return err;
     556}
     557
     558
    410559void
    411560BGridLayout::ItemAdded(BLayoutItem* item)
    412561{
    413562    item->SetLayoutData(new ItemLayoutData);
    414563}
    415564
    416 // ItemRemoved
     565
    417566void
    418567BGridLayout::ItemRemoved(BLayoutItem* item)
    419568{
     
    469618    }
    470619}
    471620
    472 // HasMultiColumnItems
     621
    473622bool
    474623BGridLayout::HasMultiColumnItems()
    475624{
    476625    return (fMultiColumnItems > 0);
    477626}
    478627
    479 // HasMultiRowItems
     628
    480629bool
    481630BGridLayout::HasMultiRowItems()
    482631{
    483632    return (fMultiRowItems > 0);
    484633}
    485634
    486 // InternalCountColumns
     635
    487636int32
    488637BGridLayout::InternalCountColumns()
    489638{
    490639    return fColumnCount;
    491640}
    492641
    493 // InternalCountRows
     642
    494643int32
    495644BGridLayout::InternalCountRows()
    496645{
    497646    return fRowCount;
    498647}
    499648
    500 // GetColumnRowConstraints
     649
    501650void
    502651BGridLayout::GetColumnRowConstraints(enum orientation orientation, int32 index,
    503652    ColumnRowConstraints* constraints)
     
    513662    }
    514663}
    515664
    516 // GetItemDimensions
     665
    517666void
    518667BGridLayout::GetItemDimensions(BLayoutItem* item, Dimensions* dimensions)
    519668{
     
    521670        *dimensions = data->dimensions;
    522671}
    523672
    524 // _IsGridCellEmpty
     673
    525674bool
    526675BGridLayout::_IsGridCellEmpty(int32 column, int32 row)
    527676{
     
    533682    return (fGrid[column][row] == NULL);
    534683}
    535684
    536 // _AreGridCellsEmpty
     685
    537686bool
    538687BGridLayout::_AreGridCellsEmpty(int32 column, int32 row, int32 columnCount,
    539688    int32 rowCount)
     
    553702    return true;
    554703}
    555704
    556 // _ResizeGrid
     705
    557706bool
     707BGridLayout::_InsertItemIntoGrid(BLayoutItem* item)
     708{
     709    BGridLayout::ItemLayoutData* data = _LayoutDataForItem(item);
     710    int32 column = data->dimensions.x;
     711    int32 columnCount = data->dimensions.width;
     712    int32 row = data->dimensions.y;
     713    int32 rowCount = data->dimensions.height;
     714   
     715    // resize the grid, if necessary
     716    int32 newColumnCount = max_c(fColumnCount, column + columnCount);
     717    int32 newRowCount = max_c(fRowCount, row + rowCount);
     718    if (newColumnCount > fColumnCount || newRowCount > fRowCount) {
     719        if (!_ResizeGrid(newColumnCount, newRowCount))
     720            return false;
     721    }
     722
     723    // enter the item in the grid
     724    for (int32 x = 0; x < columnCount; x++) {
     725        for (int32 y = 0; y < rowCount; y++) {
     726            if (x == 0 && y == 0)
     727                fGrid[column + x][row + y] = item;
     728            else
     729                fGrid[column + x][row + y] = OCCUPIED_GRID_CELL;
     730        }
     731    }
     732    return true;
     733}
     734
     735
     736bool
    558737BGridLayout::_ResizeGrid(int32 columnCount, int32 rowCount)
    559738{
    560739    if (columnCount == fColumnCount && rowCount == fRowCount)
     
    597776    return success;
    598777}
    599778
    600 // _LayoutDataForItem
     779
    601780BGridLayout::ItemLayoutData*
    602781BGridLayout::_LayoutDataForItem(BLayoutItem* item) const
    603782{
  • headers/os/interface/GridLayout.h

     
    11/*
    2  * Copyright 2006, Haiku, Inc. All rights reserved.
     2 * Copyright 2006-2010, Haiku, Inc. All rights reserved.
    33 * Distributed under the terms of the MIT License.
    44 */
    55#ifndef _GRID_LAYOUT_H
     
    88#include <TwoDimensionalLayout.h>
    99
    1010
    11 
    1211class BGridLayout : public BTwoDimensionalLayout {
    1312public:
    1413                                BGridLayout(float horizontal = 0.0f,
    1514                                    float vertical = 0.0f);
     15                                BGridLayout(BMessage* from);
    1616    virtual                     ~BGridLayout();
    1717
    1818            int32               CountColumns() const;
     
    5454                                    int32 row, int32 columnCount = 1,
    5555                                    int32 rowCount = 1);
    5656
     57    virtual status_t            Archive(BMessage* into, bool deep = true) const;
     58    static  BArchivable*        Instantiate(BMessage* from);
     59
     60    virtual status_t            ItemArchived(BMessage* into,
     61                                    BLayoutItem* item, int32 index) const;
     62    virtual status_t            ItemUnarchived(const BMessage* from,
     63                                    BLayoutItem* item, int32 index);
     64
    5765protected: 
    5866    virtual void                ItemAdded(BLayoutItem* item);
    5967    virtual void                ItemRemoved(BLayoutItem* item);
     
    6775                                    enum orientation orientation,
    6876                                    int32 index,
    6977                                    ColumnRowConstraints* constraints);
    70     virtual void                GetItemDimensions(BLayoutItem* item,
     78    virtual void                GetItemDimensions(BLayoutItem* item,
    7179                                    Dimensions* dimensions);
    7280
    7381private:   
     
    7886            bool                _IsGridCellEmpty(int32 column, int32 row);
    7987            bool                _AreGridCellsEmpty(int32 column, int32 row,
    8088                                    int32 columnCount, int32 rowCount);
    81    
     89
     90            bool                _InsertItemIntoGrid(BLayoutItem* item);
    8291            bool                _ResizeGrid(int32 columnCount, int32 rowCount);
    8392
    8493            ItemLayoutData*     _LayoutDataForItem(BLayoutItem* item) const;