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) 39 fLayout->RemoveItem(this); 40 } 41 42 43 BLayout* 44 BLayoutItem::Layout() const 45 { 46 return fLayout; 47 } 48 49 50 void 51 BLayoutItem::SetExplicitSize(BSize size) 52 { 53 SetExplicitMinSize(size); 54 SetExplicitMaxSize(size); 55 SetExplicitPreferredSize(size); 56 } 57 58 59 bool 60 BLayoutItem::HasHeightForWidth() 61 { 62 // no "height for width" by default 63 return false; 64 } 65 66 67 void 68 BLayoutItem::GetHeightForWidth(float width, float* min, float* max, 69 float* preferred) 70 { 71 // no "height for width" by default 72 } 73 74 75 BView* 76 BLayoutItem::View() 77 { 78 return NULL; 79 } 80 81 82 void 83 BLayoutItem::InvalidateLayout(bool children) 84 { 85 LayoutInvalidated(children); 86 if (fLayout) 87 fLayout->InvalidateLayout(children); 88 } 89 90 91 void 92 BLayoutItem::Relayout(bool immediate) 93 { 94 BView* view = View(); 95 if (view && !immediate) 96 view->Relayout(); 97 else if (view && immediate) 98 view->Layout(false); 99 } 100 101 102 void* 103 BLayoutItem::LayoutData() const 104 { 105 return fLayoutData; 106 } 107 108 109 void 110 BLayoutItem::SetLayoutData(void* data) 111 { 112 fLayoutData = data; 113 } 114 115 116 void 117 BLayoutItem::AlignInFrame(BRect frame) 118 { 119 BSize maxSize = MaxSize(); 120 BAlignment alignment = Alignment(); 121 122 if (HasHeightForWidth()) { 123 // The item has height for width, so we do the horizontal alignment 124 // ourselves and restrict the height max constraint respectively. 125 if (maxSize.width < frame.Width() 126 && alignment.horizontal != B_ALIGN_USE_FULL_WIDTH) { 127 frame.left += (int)((frame.Width() - maxSize.width) 128 * alignment.horizontal); 129 frame.right = frame.left + maxSize.width; 130 } 131 alignment.horizontal = B_ALIGN_USE_FULL_WIDTH; 132 133 float minHeight; 134 GetHeightForWidth(frame.Width(), &minHeight, NULL, NULL); 135 136 frame.bottom = frame.top + max_c(frame.Height(), minHeight); 137 maxSize.height = minHeight; 138 } 139 140 SetFrame(BLayoutUtils::AlignInFrame(frame, maxSize, alignment)); 141 } 142 143 144 status_t 145 BLayoutItem::Archive(BMessage* into, bool deep) const 146 { 147 BArchiver archiver(into); 148 status_t err = BArchivable::Archive(into, deep); 149 150 if (err == B_OK) 151 err = archiver.Finish(); 152 153 return err; 154 } 155 156 157 status_t 158 BLayoutItem::AllArchived(BMessage* into) const 159 { 160 BArchiver archiver(into); 161 return BArchivable::AllArchived(into); 162 } 163 164 165 status_t 166 BLayoutItem::AllUnarchived(const BMessage* from) 167 { 168 return BArchivable::AllUnarchived(from); 169 } 170 171 172 void 173 BLayoutItem::SetLayout(BLayout* layout) 174 { 175 if (layout == fLayout) 176 return; 177 178 BLayout* oldLayout = fLayout; 179 fLayout = layout; 180 181 if (oldLayout) 182 DetachedFromLayout(oldLayout); 183 184 if (BView* view = View()) { 185 if (oldLayout && !fLayout) { 186 BView::Private(view).DeregisterLayoutItem(this); 187 } else if (fLayout && !oldLayout) { 188 BView::Private(view).RegisterLayoutItem(this); 189 } 190 } 191 192 if (fLayout) 193 AttachedToLayout(); 194 } 195 196 197 status_t 198 BLayoutItem::Perform(perform_code code, void* _data) 199 { 200 return BArchivable::Perform(code, _data); 201 } 202 203 204 void 205 BLayoutItem::LayoutInvalidated(bool children) 206 { 207 // hook method 208 } 209 210 211 void 212 BLayoutItem::AttachedToLayout() 213 { 214 // hook method 215 } 216 217 218 void 219 BLayoutItem::DetachedFromLayout(BLayout* oldLayout) 220 { 221 // hook method 222 } 223 224 225 void 226 BLayoutItem::AncestorVisibilityChanged(bool shown) 227 { 228 // hook method 229 } 230 231 232 // Binary compatibility stuff 233 234 235 void BLayoutItem::_ReservedLayoutItem1() {} 236 void BLayoutItem::_ReservedLayoutItem2() {} 237 void BLayoutItem::_ReservedLayoutItem3() {} 238 void BLayoutItem::_ReservedLayoutItem4() {} 239 void BLayoutItem::_ReservedLayoutItem5() {} 240 void BLayoutItem::_ReservedLayoutItem6() {} 241 void BLayoutItem::_ReservedLayoutItem7() {} 242 void BLayoutItem::_ReservedLayoutItem8() {} 243 void BLayoutItem::_ReservedLayoutItem9() {} 244 void BLayoutItem::_ReservedLayoutItem10() {} 245 246