1/* 2 * Copyright 2010-2012, Haiku, Inc. 3 * Copyright 2006, Ingo Weinhold <bonefish@cs.tu-berlin.de>. 4 * All rights reserved. Distributed under the terms of the MIT License. 5 */ 6 7 8#include <LayoutItem.h> 9 10#include <Layout.h> 11#include <LayoutUtils.h> 12#include <View.h> 13#include <ViewPrivate.h> 14 15#include <algorithm> 16 17 18BLayoutItem::BLayoutItem() 19 : 20 fLayout(NULL), 21 fLayoutData(NULL) 22{ 23} 24 25 26BLayoutItem::BLayoutItem(BMessage* from) 27 : 28 BArchivable(BUnarchiver::PrepareArchive(from)), 29 fLayout(NULL), 30 fLayoutData(NULL) 31{ 32 BUnarchiver(from).Finish(); 33} 34 35 36BLayoutItem::~BLayoutItem() 37{ 38 if (fLayout != NULL) { 39 debugger("Deleting a BLayoutItem that is still attached to a layout. " 40 "Call RemoveSelf first."); 41 } 42} 43 44 45BLayout* 46BLayoutItem::Layout() const 47{ 48 return fLayout; 49} 50 51 52bool 53BLayoutItem::RemoveSelf() 54{ 55 return Layout() != NULL && Layout()->RemoveItem(this); 56} 57 58 59void 60BLayoutItem::SetExplicitSize(BSize size) 61{ 62 SetExplicitMinSize(size); 63 SetExplicitMaxSize(size); 64 SetExplicitPreferredSize(size); 65} 66 67 68bool 69BLayoutItem::HasHeightForWidth() 70{ 71 // no "height for width" by default 72 return false; 73} 74 75 76void 77BLayoutItem::GetHeightForWidth(float width, float* min, float* max, 78 float* preferred) 79{ 80 // no "height for width" by default 81} 82 83 84BView* 85BLayoutItem::View() 86{ 87 return NULL; 88} 89 90 91void 92BLayoutItem::InvalidateLayout(bool children) 93{ 94 LayoutInvalidated(children); 95 if (fLayout) 96 fLayout->InvalidateLayout(children); 97} 98 99 100void 101BLayoutItem::Relayout(bool immediate) 102{ 103 BView* view = View(); 104 if (view && !immediate) 105 view->Relayout(); 106 else if (view && immediate) 107 view->Layout(false); 108} 109 110 111void* 112BLayoutItem::LayoutData() const 113{ 114 return fLayoutData; 115} 116 117 118void 119BLayoutItem::SetLayoutData(void* data) 120{ 121 fLayoutData = data; 122} 123 124 125void 126BLayoutItem::AlignInFrame(BRect frame) 127{ 128 BSize maxSize = MaxSize(); 129 BAlignment alignment = Alignment(); 130 131 if (HasHeightForWidth()) { 132 // The item has height for width, so we do the horizontal alignment 133 // ourselves and restrict the height max constraint respectively. 134 if (maxSize.width < frame.Width() 135 && alignment.horizontal != B_ALIGN_USE_FULL_WIDTH) { 136 frame.left += (int)((frame.Width() - maxSize.width) 137 * alignment.horizontal); 138 frame.right = frame.left + maxSize.width; 139 } 140 alignment.horizontal = B_ALIGN_USE_FULL_WIDTH; 141 142 float minHeight; 143 GetHeightForWidth(frame.Width(), &minHeight, NULL, NULL); 144 145 frame.bottom = frame.top + max_c(frame.Height(), minHeight); 146 maxSize.height = minHeight; 147 } 148 149 SetFrame(BLayoutUtils::AlignInFrame(frame, maxSize, alignment)); 150} 151 152 153status_t 154BLayoutItem::Archive(BMessage* into, bool deep) const 155{ 156 BArchiver archiver(into); 157 status_t err = BArchivable::Archive(into, deep); 158 159 if (err == B_OK) 160 err = archiver.Finish(); 161 162 return err; 163} 164 165 166status_t 167BLayoutItem::AllArchived(BMessage* into) const 168{ 169 BArchiver archiver(into); 170 return BArchivable::AllArchived(into); 171} 172 173 174status_t 175BLayoutItem::AllUnarchived(const BMessage* from) 176{ 177 return BArchivable::AllUnarchived(from); 178} 179 180 181void 182BLayoutItem::SetLayout(BLayout* layout) 183{ 184 if (layout == fLayout) 185 return; 186 187 BLayout* oldLayout = fLayout; 188 fLayout = layout; 189 190 if (oldLayout) 191 DetachedFromLayout(oldLayout); 192 193 if (BView* view = View()) { 194 if (oldLayout && !fLayout) { 195 BView::Private(view).DeregisterLayoutItem(this); 196 } else if (fLayout && !oldLayout) { 197 BView::Private(view).RegisterLayoutItem(this); 198 } 199 } 200 201 if (fLayout) 202 AttachedToLayout(); 203} 204 205 206status_t 207BLayoutItem::Perform(perform_code code, void* _data) 208{ 209 return BArchivable::Perform(code, _data); 210} 211 212 213void 214BLayoutItem::LayoutInvalidated(bool children) 215{ 216 // hook method 217} 218 219 220void 221BLayoutItem::AttachedToLayout() 222{ 223 // hook method 224} 225 226 227void 228BLayoutItem::DetachedFromLayout(BLayout* oldLayout) 229{ 230 // hook method 231} 232 233 234void 235BLayoutItem::AncestorVisibilityChanged(bool shown) 236{ 237 // hook method 238} 239 240 241// Binary compatibility stuff 242 243 244void BLayoutItem::_ReservedLayoutItem1() {} 245void BLayoutItem::_ReservedLayoutItem2() {} 246void BLayoutItem::_ReservedLayoutItem3() {} 247void BLayoutItem::_ReservedLayoutItem4() {} 248void BLayoutItem::_ReservedLayoutItem5() {} 249void BLayoutItem::_ReservedLayoutItem6() {} 250void BLayoutItem::_ReservedLayoutItem7() {} 251void BLayoutItem::_ReservedLayoutItem8() {} 252void BLayoutItem::_ReservedLayoutItem9() {} 253void BLayoutItem::_ReservedLayoutItem10() {} 254 255