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 18 BLayoutItem::BLayoutItem() 19 : 20 fLayout(NULL), 21 fLayoutData(NULL) 22 { 23 } 24 25 26 BLayoutItem::BLayoutItem(BMessage* from) 27 : 28 BArchivable(BUnarchiver::PrepareArchive(from)), 29 fLayout(NULL), 30 fLayoutData(NULL) 31 { 32 BUnarchiver(from).Finish(); 33 } 34 35 36 BLayoutItem::~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 45 BLayout* 46 BLayoutItem::Layout() const 47 { 48 return fLayout; 49 } 50 51 52 bool 53 BLayoutItem::RemoveSelf() 54 { 55 return Layout() != NULL && Layout()->RemoveItem(this); 56 } 57 58 59 void 60 BLayoutItem::SetExplicitSize(BSize size) 61 { 62 SetExplicitMinSize(size); 63 SetExplicitMaxSize(size); 64 SetExplicitPreferredSize(size); 65 } 66 67 68 bool 69 BLayoutItem::HasHeightForWidth() 70 { 71 // no "height for width" by default 72 return false; 73 } 74 75 76 void 77 BLayoutItem::GetHeightForWidth(float width, float* min, float* max, 78 float* preferred) 79 { 80 // no "height for width" by default 81 } 82 83 84 BView* 85 BLayoutItem::View() 86 { 87 return NULL; 88 } 89 90 91 void 92 BLayoutItem::InvalidateLayout(bool children) 93 { 94 LayoutInvalidated(children); 95 if (fLayout) 96 fLayout->InvalidateLayout(children); 97 } 98 99 100 void 101 BLayoutItem::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 111 void* 112 BLayoutItem::LayoutData() const 113 { 114 return fLayoutData; 115 } 116 117 118 void 119 BLayoutItem::SetLayoutData(void* data) 120 { 121 fLayoutData = data; 122 } 123 124 125 void 126 BLayoutItem::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 153 status_t 154 BLayoutItem::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 166 status_t 167 BLayoutItem::AllArchived(BMessage* into) const 168 { 169 BArchiver archiver(into); 170 return BArchivable::AllArchived(into); 171 } 172 173 174 status_t 175 BLayoutItem::AllUnarchived(const BMessage* from) 176 { 177 return BArchivable::AllUnarchived(from); 178 } 179 180 181 void 182 BLayoutItem::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 206 status_t 207 BLayoutItem::Perform(perform_code code, void* _data) 208 { 209 return BArchivable::Perform(code, _data); 210 } 211 212 213 void 214 BLayoutItem::LayoutInvalidated(bool children) 215 { 216 // hook method 217 } 218 219 220 void 221 BLayoutItem::AttachedToLayout() 222 { 223 // hook method 224 } 225 226 227 void 228 BLayoutItem::DetachedFromLayout(BLayout* oldLayout) 229 { 230 // hook method 231 } 232 233 234 void 235 BLayoutItem::AncestorVisibilityChanged(bool shown) 236 { 237 // hook method 238 } 239 240 241 // Binary compatibility stuff 242 243 244 void BLayoutItem::_ReservedLayoutItem1() {} 245 void BLayoutItem::_ReservedLayoutItem2() {} 246 void BLayoutItem::_ReservedLayoutItem3() {} 247 void BLayoutItem::_ReservedLayoutItem4() {} 248 void BLayoutItem::_ReservedLayoutItem5() {} 249 void BLayoutItem::_ReservedLayoutItem6() {} 250 void BLayoutItem::_ReservedLayoutItem7() {} 251 void BLayoutItem::_ReservedLayoutItem8() {} 252 void BLayoutItem::_ReservedLayoutItem9() {} 253 void BLayoutItem::_ReservedLayoutItem10() {} 254 255