1 /* 2 * Copyright 2010, 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 #include <LayoutItem.h> 8 9 #include <Layout.h> 10 #include <LayoutUtils.h> 11 #include <View.h> 12 13 #include <algorithm> 14 15 16 BLayoutItem::BLayoutItem() 17 : 18 fLayout(NULL), 19 fLayoutData(NULL) 20 { 21 } 22 23 24 BLayoutItem::BLayoutItem(BMessage* from) 25 : 26 BArchivable(BUnarchiver::PrepareArchive(from)), 27 fLayout(NULL), 28 fLayoutData(NULL) 29 { 30 BUnarchiver(from).Finish(); 31 } 32 33 34 BLayoutItem::~BLayoutItem() 35 { 36 if (fLayout) 37 fLayout->RemoveItem(this); 38 } 39 40 41 BLayout* 42 BLayoutItem::Layout() const 43 { 44 return fLayout; 45 } 46 47 48 bool 49 BLayoutItem::HasHeightForWidth() 50 { 51 // no "height for width" by default 52 return false; 53 } 54 55 56 void 57 BLayoutItem::GetHeightForWidth(float width, float* min, float* max, 58 float* preferred) 59 { 60 // no "height for width" by default 61 } 62 63 64 BView* 65 BLayoutItem::View() 66 { 67 return NULL; 68 } 69 70 71 void 72 BLayoutItem::InvalidateLayout(bool children) 73 { 74 if (fLayout) 75 fLayout->InvalidateLayout(children); 76 } 77 78 79 void 80 BLayoutItem::Relayout(bool immediate) 81 { 82 BView* view = View(); 83 if (view && !immediate) 84 view->Relayout(); 85 else if (view && immediate) 86 view->Layout(false); 87 } 88 89 90 void* 91 BLayoutItem::LayoutData() const 92 { 93 return fLayoutData; 94 } 95 96 97 void 98 BLayoutItem::SetLayoutData(void* data) 99 { 100 fLayoutData = data; 101 } 102 103 104 void 105 BLayoutItem::AlignInFrame(BRect frame) 106 { 107 BSize maxSize = MaxSize(); 108 BAlignment alignment = Alignment(); 109 110 if (HasHeightForWidth()) { 111 // The item has height for width, so we do the horizontal alignment 112 // ourselves and restrict the height max constraint respectively. 113 if (maxSize.width < frame.Width() 114 && alignment.horizontal != B_ALIGN_USE_FULL_WIDTH) { 115 frame.left += (int)((frame.Width() - maxSize.width) 116 * alignment.horizontal); 117 frame.right = frame.left + maxSize.width; 118 } 119 alignment.horizontal = B_ALIGN_USE_FULL_WIDTH; 120 121 float minHeight; 122 GetHeightForWidth(frame.Width(), &minHeight, NULL, NULL); 123 124 frame.bottom = frame.top + max_c(frame.Height(), minHeight); 125 maxSize.height = minHeight; 126 } 127 128 SetFrame(BLayoutUtils::AlignInFrame(frame, maxSize, alignment)); 129 } 130 131 132 status_t 133 BLayoutItem::Archive(BMessage* into, bool deep) const 134 { 135 BArchiver archiver(into); 136 status_t err = BArchivable::Archive(into, deep); 137 138 if (err == B_OK) 139 err = archiver.Finish(); 140 141 return err; 142 } 143 144 145 status_t 146 BLayoutItem::AllArchived(BMessage* into) const 147 { 148 BArchiver archiver(into); 149 return BArchivable::AllArchived(into); 150 } 151 152 153 status_t 154 BLayoutItem::AllUnarchived(const BMessage* from) 155 { 156 return BArchivable::AllUnarchived(from); 157 } 158 159 160 void 161 BLayoutItem::SetLayout(BLayout* layout) 162 { 163 if (layout == fLayout) 164 return; 165 166 std::swap(fLayout, layout); 167 if (layout) 168 DetachedFromLayout(layout); 169 170 if (fLayout) 171 AttachedToLayout(); 172 } 173 174 175 void 176 BLayoutItem::AttachedToLayout() 177 { 178 // hook method 179 } 180 181 182 void 183 BLayoutItem::DetachedFromLayout(BLayout* oldLayout) 184 { 185 // hook method 186 } 187 188 189 void 190 BLayoutItem::AncestorVisibilityChanged(bool shown) 191 { 192 // hook method 193 } 194 195