Ticket #5525: splitLayout.patch

File splitLayout.patch, 15.3 KB (added by yourpalal, 14 years ago)

implement archiving of BSplitLayout class

  • src/kits/interface/SplitLayout.cpp

     
    55
    66#include "SplitLayout.h"
    77
     8#include <new>
    89#include <stdio.h>
    910
    1011#include <LayoutItem.h>
    1112#include <LayoutUtils.h>
     13#include <Message.h>
    1214#include <View.h>
    1315
    1416#include "OneElementLayouter.h"
    1517#include "SimpleLayouter.h"
    1618
    17 // ItemLayoutInfo
     19// archivng constants
     20namespace {
     21    const char* kInfoCollapsibleField = "BSplitLayout::info::collapsible";
     22    const char* kInfoWeightField = "BSplitLayout::info::weight";
     23    const char* kSpacingField = "BSplitLayout::spacing";
     24    const char* kSplitterSizeField = "BSplitLayout::splitterSize";
     25    const char* kIsVerticalField = "BSplitLayout::vertical";
     26    const char* kTopInsetField = "BSplitLayout::TopInset";
     27    const char* kBottomInsetField = "BSplitLayout::BottomInset";
     28    const char* kLeftInsetField = "BSplitLayout::LeftInset";
     29    const char* kRightInsetField = "BSplitLayout::RightInset";
     30}
     31
     32
    1833class BSplitLayout::ItemLayoutInfo {
    1934public:
    2035    float       weight;
     
    2540    bool        isCollapsible;
    2641
    2742    ItemLayoutInfo()
    28         : weight(1.0f),
    29           layoutFrame(0, 0, -1, -1),
    30           min(),
    31           max(),
    32           isVisible(true),
    33           isCollapsible(true)
     43        :
     44        weight(1.0f),
     45        layoutFrame(0, 0, -1, -1),
     46        min(),
     47        max(),
     48        isVisible(true),
     49        isCollapsible(true)
    3450    {
    3551    }
    3652};
    3753
    38 // ValueRange
     54
    3955class BSplitLayout::ValueRange {
    4056public:
    4157    int32 sumValue; // including spacing
     
    4763    int32 nextSize;
    4864};
    4965
    50 // SplitterItem
     66
    5167class BSplitLayout::SplitterItem : public BLayoutItem {
    5268public:
    5369    SplitterItem(BSplitLayout* layout)
    54         : fLayout(layout),
    55           fFrame()
     70        :
     71        fLayout(layout),
     72        fFrame()
    5673    {
    5774    }
    5875
     76
    5977    virtual BSize MinSize()
    6078    {
    6179        if (fLayout->Orientation() == B_HORIZONTAL)
     
    128146    BRect           fFrame;
    129147};
    130148
    131 
    132149// #pragma mark -
    133150
    134151
    135 // constructor
     152
    136153BSplitLayout::BSplitLayout(enum orientation orientation,
    137154        float spacing)
    138     : fOrientation(orientation),
    139       fLeftInset(0),
    140       fRightInset(0),
    141       fTopInset(0),
    142       fBottomInset(0),
    143       fSplitterSize(6),
    144       fSpacing(spacing),
     155    :
     156    fOrientation(orientation),
     157    fLeftInset(0),
     158    fRightInset(0),
     159    fTopInset(0),
     160    fBottomInset(0),
     161    fSplitterSize(6),
     162    fSpacing(spacing),
    145163
    146       fSplitterItems(),
    147       fVisibleItems(),
    148       fMin(),
    149       fMax(),
    150       fPreferred(),
     164    fSplitterItems(),
     165    fVisibleItems(),
     166    fMin(),
     167    fMax(),
     168    fPreferred(),
    151169
    152       fHorizontalLayouter(NULL),
    153       fVerticalLayouter(NULL),
    154       fHorizontalLayoutInfo(NULL),
    155       fVerticalLayoutInfo(NULL),
     170    fHorizontalLayouter(NULL),
     171    fVerticalLayouter(NULL),
     172    fHorizontalLayoutInfo(NULL),
     173    fVerticalLayoutInfo(NULL),
    156174
    157       fHeightForWidthItems(),
    158       fHeightForWidthVerticalLayouter(NULL),
    159       fHeightForWidthHorizontalLayoutInfo(NULL),
     175    fHeightForWidthItems(),
     176    fHeightForWidthVerticalLayouter(NULL),
     177    fHeightForWidthHorizontalLayoutInfo(NULL),
    160178
    161       fLayoutValid(false),
     179    fLayoutValid(false),
    162180
    163       fCachedHeightForWidthWidth(-2),
    164       fHeightForWidthVerticalLayouterWidth(-2),
    165       fCachedMinHeightForWidth(-1),
    166       fCachedMaxHeightForWidth(-1),
    167       fCachedPreferredHeightForWidth(-1),
     181    fCachedHeightForWidthWidth(-2),
     182    fHeightForWidthVerticalLayouterWidth(-2),
     183    fCachedMinHeightForWidth(-1),
     184    fCachedMaxHeightForWidth(-1),
     185    fCachedPreferredHeightForWidth(-1),
    168186
    169       fDraggingStartPoint(),
    170       fDraggingStartValue(0),
    171       fDraggingCurrentValue(0),
    172       fDraggingSplitterIndex(-1)
     187    fDraggingStartPoint(),
     188    fDraggingStartValue(0),
     189    fDraggingCurrentValue(0),
     190    fDraggingSplitterIndex(-1)
    173191{
    174192}
    175193
    176 // destructor
     194
     195BSplitLayout::BSplitLayout(BMessage* from)
     196    :
     197    BLayout(from),
     198    fSplitterItems(),
     199    fVisibleItems(),
     200    fMin(),
     201    fMax(),
     202    fPreferred(),
     203   
     204    fHorizontalLayouter(NULL),
     205    fVerticalLayouter(NULL),
     206    fHorizontalLayoutInfo(NULL),
     207    fVerticalLayoutInfo(NULL),
     208   
     209    fHeightForWidthItems(),
     210    fHeightForWidthVerticalLayouter(NULL),
     211    fHeightForWidthHorizontalLayoutInfo(NULL),
     212   
     213    fLayoutValid(false),
     214   
     215    fCachedHeightForWidthWidth(-2),
     216    fHeightForWidthVerticalLayouterWidth(-2),
     217    fCachedMinHeightForWidth(-1),
     218    fCachedMaxHeightForWidth(-1),
     219    fCachedPreferredHeightForWidth(-1),
     220   
     221    fDraggingStartPoint(),
     222    fDraggingStartValue(0),
     223    fDraggingCurrentValue(0),
     224    fDraggingSplitterIndex(-1)
     225{
     226    bool isVertical;
     227    from->FindBool(kIsVerticalField, &isVertical);
     228    fOrientation = (isVertical) ? B_VERTICAL : B_HORIZONTAL ;
     229
     230    from->FindFloat(kLeftInsetField, &fLeftInset);
     231    from->FindFloat(kRightInsetField, &fRightInset);
     232    from->FindFloat(kTopInsetField, &fTopInset);
     233    from->FindFloat(kBottomInsetField, &fBottomInset);
     234    from->FindFloat(kSplitterSizeField, &fSplitterSize);
     235    from->FindFloat(kSpacingField, &fSpacing);
     236}
     237
     238
    177239BSplitLayout::~BSplitLayout()
    178240{
    179241}
    180242
    181 // SetInsets
     243
    182244void
    183245BSplitLayout::SetInsets(float left, float top, float right, float bottom)
    184246{
     
    190252    InvalidateLayout();
    191253}
    192254
    193 // GetInsets
     255
    194256void
    195257BSplitLayout::GetInsets(float* left, float* top, float* right,
    196258    float* bottom) const
     
    205267        *bottom = fBottomInset;
    206268}
    207269
    208 // Spacing
     270
    209271float
    210272BSplitLayout::Spacing() const
    211273{
    212274    return fSpacing;
    213275}
    214276
    215 // SetSpacing
     277
    216278void
    217279BSplitLayout::SetSpacing(float spacing)
    218280{
     
    223285    }
    224286}
    225287
    226 // Orientation
     288
    227289orientation
    228290BSplitLayout::Orientation() const
    229291{
    230292    return fOrientation;
    231293}
    232294
    233 // SetOrientation
     295
    234296void
    235297BSplitLayout::SetOrientation(enum orientation orientation)
    236298{
     
    241303    }
    242304}
    243305
    244 // SplitterSize
     306
    245307float
    246308BSplitLayout::SplitterSize() const
    247309{
    248310    return fSplitterSize;
    249311}
    250312
    251 // SetSplitterSize
     313
    252314void
    253315BSplitLayout::SetSplitterSize(float size)
    254316{
     
    259321    }
    260322}
    261323
    262 // AddView
     324
    263325BLayoutItem*
    264326BSplitLayout::AddView(BView* child)
    265327{
    266328    return BLayout::AddView(child);
    267329}
    268330
    269 // AddView
     331
    270332BLayoutItem*
    271333BSplitLayout::AddView(int32 index, BView* child)
    272334{
    273335    return BLayout::AddView(index, child);
    274336}
    275337
    276 // AddView
     338
    277339BLayoutItem*
    278340BSplitLayout::AddView(BView* child, float weight)
    279341{
    280342    return AddView(-1, child, weight);
    281343}
    282344
    283 // AddView
     345
    284346BLayoutItem*
    285347BSplitLayout::AddView(int32 index, BView* child, float weight)
    286348{
     
    291353    return item;
    292354}
    293355
    294 // AddItem
     356
    295357bool
    296358BSplitLayout::AddItem(BLayoutItem* item)
    297359{
    298360    return BLayout::AddItem(item);
    299361}
    300362
    301 // AddItem
     363
    302364bool
    303365BSplitLayout::AddItem(int32 index, BLayoutItem* item)
    304366{
    305367    return BLayout::AddItem(index, item);
    306368}
    307369
    308 // AddItem
     370
    309371bool
    310372BSplitLayout::AddItem(BLayoutItem* item, float weight)
    311373{
    312374    return AddItem(-1, item, weight);
    313375}
    314376
    315 // AddItem
     377
    316378bool
    317379BSplitLayout::AddItem(int32 index, BLayoutItem* item, float weight)
    318380{
     
    323385    return success;
    324386}
    325387
    326 // ItemWeight
     388
    327389float
    328390BSplitLayout::ItemWeight(int32 index) const
    329391{
     
    333395    return ItemWeight(ItemAt(index));
    334396}
    335397
    336 // ItemWeight
     398
    337399float
    338400BSplitLayout::ItemWeight(BLayoutItem* item) const
    339401{
     
    342404    return 0;
    343405}
    344406
    345 // SetItemWeight
     407
    346408void
    347409BSplitLayout::SetItemWeight(int32 index, float weight, bool invalidateLayout)
    348410{
     
    366428        InvalidateLayout();
    367429}
    368430
    369 // SetItemWeight
     431
    370432void
    371433BSplitLayout::SetItemWeight(BLayoutItem* item, float weight)
    372434{
     
    374436        info->weight = weight;
    375437}
    376438
    377 // SetCollapsible
     439
    378440void
    379441BSplitLayout::SetCollapsible(bool collapsible)
    380442{
    381443    SetCollapsible(0, CountItems() - 1, collapsible);
    382444}
    383445
    384 // SetCollapsible
     446
    385447void
    386448BSplitLayout::SetCollapsible(int32 index, bool collapsible)
    387449{
    388450    SetCollapsible(index, index, collapsible);
    389451}
    390452
    391 // SetCollapsible
     453
    392454void
    393455BSplitLayout::SetCollapsible(int32 first, int32 last, bool collapsible)
    394456{
     
    401463        _ItemLayoutInfo(ItemAt(i))->isCollapsible = collapsible;
    402464}
    403465
    404 // MinSize
     466
    405467BSize
    406468BSplitLayout::MinSize()
    407469{
     
    410472    return _AddInsets(fMin);
    411473}
    412474
    413 // MaxSize
     475
    414476BSize
    415477BSplitLayout::MaxSize()
    416478{
     
    419481    return _AddInsets(fMax);
    420482}
    421483
    422 // PreferredSize
     484
    423485BSize
    424486BSplitLayout::PreferredSize()
    425487{
     
    428490    return _AddInsets(fPreferred);
    429491}
    430492
    431 // Alignment
     493
    432494BAlignment
    433495BSplitLayout::Alignment()
    434496{
    435497    return BAlignment(B_ALIGN_USE_FULL_WIDTH, B_ALIGN_USE_FULL_HEIGHT);
    436498}
    437499
    438 // HasHeightForWidth
     500
    439501bool
    440502BSplitLayout::HasHeightForWidth()
    441503{
     
    444506    return !fHeightForWidthItems.IsEmpty();
    445507}
    446508
    447 // GetHeightForWidth
     509
    448510void
    449511BSplitLayout::GetHeightForWidth(float width, float* min, float* max,
    450512    float* preferred)
     
    457519    _AddInsets(min, max, preferred);
    458520}
    459521
    460 // InvalidateLayout
     522
    461523void
    462524BSplitLayout::InvalidateLayout()
    463525{
    464526    _InvalidateLayout(true);
    465527}
    466528
    467 // LayoutView
     529
    468530void
    469531BSplitLayout::LayoutView()
    470532{
     
    543605    fLayoutValid = true;
    544606}
    545607
    546 // SplitterItemFrame
     608
    547609BRect
    548610BSplitLayout::SplitterItemFrame(int32 index) const
    549611{
     
    552614    return BRect();
    553615}
    554616
    555 // IsAboveSplitter
     617
    556618bool
    557619BSplitLayout::IsAboveSplitter(const BPoint& point) const
    558620{
    559621    return _SplitterItemAt(point) != NULL;
    560622}
    561623
    562 // StartDraggingSplitter
     624
    563625bool
    564626BSplitLayout::StartDraggingSplitter(BPoint point)
    565627{
     
    589651    return false;
    590652}
    591653
    592 // DragSplitter
     654
    593655bool
    594656BSplitLayout::DragSplitter(BPoint point)
    595657{
     
    608670        fDraggingStartValue + valueDiff);
    609671}
    610672
    611 // StopDraggingSplitter
     673
    612674bool
    613675BSplitLayout::StopDraggingSplitter()
    614676{
     
    623685    return true;
    624686}
    625687
    626 // DraggedSplitter
     688
    627689int32
    628690BSplitLayout::DraggedSplitter() const
    629691{
    630692    return fDraggingSplitterIndex;
    631693}
    632694
    633 // ItemAdded
     695
     696status_t
     697BSplitLayout::Archive(BMessage* into, bool deep) const
     698{
     699    BArchiver archiver(into);
     700    status_t err = BLayout::Archive(into, deep);
     701
     702    if (err == B_OK)
     703        into->AddBool(kIsVerticalField, fOrientation == B_VERTICAL);
     704
     705    if (err == B_OK)
     706        err = into->AddFloat(kLeftInsetField, fLeftInset);
     707
     708    if (err == B_OK)
     709        err = into->AddFloat(kRightInsetField, fRightInset);
     710
     711    if (err == B_OK)
     712        err = into->AddFloat(kTopInsetField, fTopInset);
     713
     714    if (err == B_OK)
     715        err = into->AddFloat(kBottomInsetField, fBottomInset);
     716
     717    if (err == B_OK)
     718        err = into->AddFloat(kSplitterSizeField, fSplitterSize);
     719
     720    if (err == B_OK)
     721        err = into->AddFloat(kSpacingField, fSpacing);
     722
     723    return archiver.Finish(err);
     724}
     725
     726
     727BArchivable*
     728BSplitLayout::Instantiate(BMessage* from)
     729{
     730    if (validate_instantiation(from, "BSplitLayout"))
     731        return new(std::nothrow) BSplitLayout(from);
     732    return NULL;
     733}
     734
     735
     736status_t
     737BSplitLayout::ItemArchived(BMessage* into, BLayoutItem* item, int32 index) const
     738{
     739    ItemLayoutInfo* info = (ItemLayoutInfo*)item->LayoutData();
     740   
     741    if (!info) // TODO: remove this check when AddItem() returns a bool
     742        return B_ERROR;
     743
     744    status_t err = into->AddFloat(kInfoWeightField, info->weight);
     745    if (err == B_OK)
     746        err = into->AddBool(kInfoCollapsibleField, info->isCollapsible);
     747
     748    return err;
     749}
     750
     751
     752status_t
     753BSplitLayout::ItemUnarchived(const BMessage* from,
     754    BLayoutItem* item, int32 index)
     755{
     756    ItemLayoutInfo* info = _ItemLayoutInfo(item);
     757    status_t err = from->FindFloat(kInfoWeightField, index, &info->weight);
     758
     759    if (err == B_OK) {
     760        bool* collapsible = &info->isCollapsible;
     761        err = from->FindBool(kInfoCollapsibleField, index, collapsible);
     762    }
     763    return err;
     764}
     765
     766
    634767void
    635768BSplitLayout::ItemAdded(BLayoutItem* item)
    636769{
     
    643776    SetItemWeight(item, 1);
    644777}
    645778
    646 // ItemRemoved
     779
    647780void
    648781BSplitLayout::ItemRemoved(BLayoutItem* item)
    649782{
     
    658791    item->SetLayoutData(NULL);
    659792}
    660793
    661 // _InvalidateLayout
     794
    662795void
    663796BSplitLayout::_InvalidateLayout(bool invalidateView)
    664797{
     
    680813    fLayoutValid = false;
    681814}
    682815
    683 // _InvalidateCachedHeightForWidth
     816
    684817void
    685818BSplitLayout::_InvalidateCachedHeightForWidth()
    686819{
     
    694827    fHeightForWidthVerticalLayouterWidth = -2;
    695828}
    696829
    697 // _SplitterItemAt
     830
    698831BSplitLayout::SplitterItem*
    699832BSplitLayout::_SplitterItemAt(const BPoint& point, int32* index) const
    700833{
     
    711844    return NULL;
    712845}
    713846
    714 // _SplitterItemAt
     847
    715848BSplitLayout::SplitterItem*
    716849BSplitLayout::_SplitterItemAt(int32 index) const
    717850{
    718851    return (SplitterItem*)fSplitterItems.ItemAt(index);
    719852}
    720853
    721 // _GetSplitterValueRange
     854
    722855void
    723856BSplitLayout::_GetSplitterValueRange(int32 index, ValueRange& range)
    724857{
     
    747880        range.sumValue += (int32)fSpacing;
    748881}
    749882
    750 // _SplitterValue
     883
    751884int32
    752885BSplitLayout::_SplitterValue(int32 index) const
    753886{
     
    761894        return 0;
    762895}
    763896
    764 // _LayoutItem
     897
    765898void
    766899BSplitLayout::_LayoutItem(BLayoutItem* item, BRect frame, bool visible)
    767900{
     
    790923        item->AlignInFrame(frame);
    791924}
    792925
    793 // _LayoutItem
     926
    794927void
    795928BSplitLayout::_LayoutItem(BLayoutItem* item, ItemLayoutInfo* info)
    796929{
     
    806939
    807940    item->AlignInFrame(info->layoutFrame);
    808941
     942    // TODO: shouldn't this be done (as needed) by item->SetVisible();
    809943    // if the item became visible, we need to update its internal layout
    810944    if (visibilityChanged) {
    811945        if (BView* itemView = item->View())
     
    813947    }
    814948}
    815949
    816 // _SetSplitterValue
     950
    817951bool
    818952BSplitLayout::_SetSplitterValue(int32 index, int32 value)
    819953{
     
    10421176    return true;
    10431177}
    10441178
    1045 // _ItemLayoutInfo
     1179
    10461180BSplitLayout::ItemLayoutInfo*
    10471181BSplitLayout::_ItemLayoutInfo(BLayoutItem* item) const
    10481182{
     
    10551189    return info;
    10561190}
    10571191
    1058 // _UpdateSplitterWeights
     1192
    10591193void
    10601194BSplitLayout::_UpdateSplitterWeights()
    10611195{
     
    10781212        _InvalidateCachedHeightForWidth();
    10791213}
    10801214
    1081 // _ValidateMinMax
     1215
    10821216void
    10831217BSplitLayout::_ValidateMinMax()
    10841218{
     
    11521286        view->ResetLayoutInvalidation();
    11531287}
    11541288
    1155 // _InternalGetHeightForWidth
     1289
    11561290void
    11571291BSplitLayout::_InternalGetHeightForWidth(float width, bool realLayout,
    11581292    float* minHeight, float* maxHeight, float* preferredHeight)
     
    12211355        *preferredHeight = fCachedPreferredHeightForWidth;
    12221356}
    12231357
    1224 // _SplitterSpace
     1358
    12251359float
    12261360BSplitLayout::_SplitterSpace() const
    12271361{
     
    12351369    return space;
    12361370}
    12371371
    1238 // _AddInsets
     1372
    12391373BSize
    12401374BSplitLayout::_AddInsets(BSize size)
    12411375{
     
    12531387    return size;
    12541388}
    12551389
    1256 // _AddInsets
     1390
    12571391void
    12581392BSplitLayout::_AddInsets(float* minHeight, float* maxHeight,
    12591393    float* preferredHeight)
     
    12691403        *preferredHeight = BLayoutUtils::AddDistances(*preferredHeight, insets);
    12701404}
    12711405
    1272 // _SubtractInsets
     1406
    12731407BSize
    12741408BSplitLayout::_SubtractInsets(BSize size)
    12751409{
  • src/kits/interface/SplitLayout.h

     
    11/*
    2  * Copyright 2006, Haiku Inc.
     2 * Copyright 2006-2010, Haiku Inc.
    33 * Distributed under the terms of the MIT License.
    44 */
    55#ifndef _SPLIT_LAYOUT_H
     
    2525public:
    2626                                BSplitLayout(enum orientation orientation,
    2727                                    float spacing = 0.0f);
     28                                BSplitLayout(BMessage* from);
    2829    virtual                     ~BSplitLayout();
    2930
    3031            void                SetInsets(float left, float top, float right,
     
    8788            bool                StopDraggingSplitter();
    8889            int32               DraggedSplitter() const;
    8990
     91    // archiving methods
     92    virtual status_t            Archive(BMessage* into, bool deep = true) const;
     93    static  BArchivable*        Instantiate(BMessage* from);
     94
     95    virtual status_t            ItemArchived(BMessage* into, BLayoutItem* item,
     96                                    int32 index) const;
     97    virtual status_t            ItemUnarchived(const BMessage* from,
     98                                    BLayoutItem* item, int32 index);
     99
    90100protected:
    91101    virtual void                ItemAdded(BLayoutItem* item);
    92102    virtual void                ItemRemoved(BLayoutItem* item);
     
    121131
    122132            void                _ValidateMinMax();
    123133
    124             void                 _InternalGetHeightForWidth(float width,
     134            void                _InternalGetHeightForWidth(float width,
    125135                                    bool realLayout, float* minHeight,
    126136                                    float* maxHeight, float* preferredHeight);
    127137