1 /* 2 * Copyright 2006, Ingo Weinhold <bonefish@cs.tu-berlin.de>. 3 * All rights reserved. Distributed under the terms of the MIT License. 4 */ 5 6 #include <CardLayout.h> 7 8 #include <LayoutItem.h> 9 #include <View.h> 10 11 // constructor 12 BCardLayout::BCardLayout() 13 : BLayout(), 14 fMin(0, 0), 15 fMax(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED), 16 fPreferred(0, 0), 17 fVisibleItem(NULL), 18 fMinMaxValid(false) 19 { 20 } 21 22 // destructor 23 BCardLayout::~BCardLayout() 24 { 25 } 26 27 // VisibleItem 28 BLayoutItem* 29 BCardLayout::VisibleItem() const 30 { 31 return fVisibleItem; 32 } 33 34 // VisibleIndex 35 int32 36 BCardLayout::VisibleIndex() const 37 { 38 return IndexOfItem(fVisibleItem); 39 } 40 41 // SetVisibleItem 42 void 43 BCardLayout::SetVisibleItem(int32 index) 44 { 45 SetVisibleItem(ItemAt(index)); 46 } 47 48 // SetVisibleItem 49 void 50 BCardLayout::SetVisibleItem(BLayoutItem* item) 51 { 52 if (item == fVisibleItem) 53 return; 54 55 if (item != NULL && IndexOfItem(item) < 0) 56 return; 57 58 if (fVisibleItem != NULL) 59 fVisibleItem->SetVisible(false); 60 61 fVisibleItem = item; 62 63 if (fVisibleItem != NULL) { 64 fVisibleItem->SetVisible(true); 65 66 LayoutView(); 67 } 68 } 69 70 // MinSize 71 BSize 72 BCardLayout::MinSize() 73 { 74 _ValidateMinMax(); 75 return fMin; 76 } 77 78 // MaxSize 79 BSize 80 BCardLayout::MaxSize() 81 { 82 _ValidateMinMax(); 83 return fMax; 84 } 85 86 // PreferredSize 87 BSize 88 BCardLayout::PreferredSize() 89 { 90 _ValidateMinMax(); 91 return fPreferred; 92 } 93 94 // Alignment 95 BAlignment 96 BCardLayout::Alignment() 97 { 98 return BAlignment(B_ALIGN_USE_FULL_WIDTH, B_ALIGN_USE_FULL_HEIGHT); 99 } 100 101 // HasHeightForWidth 102 bool 103 BCardLayout::HasHeightForWidth() 104 { 105 int32 count = CountItems(); 106 for (int32 i = 0; i < count; i++) { 107 if (ItemAt(i)->HasHeightForWidth()) 108 return true; 109 } 110 111 return false; 112 } 113 114 // GetHeightForWidth 115 void 116 BCardLayout::GetHeightForWidth(float width, float* min, float* max, 117 float* preferred) 118 { 119 _ValidateMinMax(); 120 121 // init with useful values 122 float minHeight = fMin.height; 123 float maxHeight = fMax.height; 124 float preferredHeight = fPreferred.height; 125 126 // apply the items' constraints 127 int32 count = CountItems(); 128 for (int32 i = 0; i < count; i++) { 129 BLayoutItem* item = ItemAt(i); 130 if (item->HasHeightForWidth()) { 131 float itemMinHeight; 132 float itemMaxHeight; 133 float itemPreferredHeight; 134 item->GetHeightForWidth(width, &itemMinHeight, &itemMaxHeight, 135 &itemPreferredHeight); 136 minHeight = max_c(minHeight, itemMinHeight); 137 maxHeight = min_c(maxHeight, itemMaxHeight); 138 preferredHeight = min_c(preferredHeight, itemPreferredHeight); 139 } 140 } 141 142 // adjust max and preferred, if necessary 143 maxHeight = max_c(maxHeight, minHeight); 144 preferredHeight = max_c(preferredHeight, minHeight); 145 preferredHeight = min_c(preferredHeight, maxHeight); 146 147 if (min) 148 *min = minHeight; 149 if (max) 150 *max = maxHeight; 151 if (preferred) 152 *preferred = preferredHeight; 153 } 154 155 // InvalidateLayout 156 void 157 BCardLayout::InvalidateLayout() 158 { 159 BLayout::InvalidateLayout(); 160 161 fMinMaxValid = false; 162 } 163 164 // LayoutView 165 void 166 BCardLayout::LayoutView() 167 { 168 _ValidateMinMax(); 169 170 BSize size = BSize(View()->Bounds()); 171 size.width = max_c(size.width, fMin.width); 172 size.height = max_c(size.height, fMin.height); 173 174 if (fVisibleItem != NULL) 175 fVisibleItem->AlignInFrame(BRect(0, 0, size.width, size.height)); 176 } 177 178 // ItemAdded 179 void 180 BCardLayout::ItemAdded(BLayoutItem* item) 181 { 182 item->SetVisible(false); 183 } 184 185 // ItemRemoved 186 void 187 BCardLayout::ItemRemoved(BLayoutItem* item) 188 { 189 if (fVisibleItem == item) { 190 BLayoutItem* newVisibleItem = NULL; 191 SetVisibleItem(newVisibleItem); 192 } 193 } 194 195 // _ValidateMinMax 196 void 197 BCardLayout::_ValidateMinMax() 198 { 199 if (fMinMaxValid) 200 return; 201 202 fMin.width = 0; 203 fMin.height = 0; 204 fMax.width = B_SIZE_UNLIMITED; 205 fMax.height = B_SIZE_UNLIMITED; 206 fPreferred.width = 0; 207 fPreferred.height = 0; 208 209 int32 itemCount = CountItems(); 210 for (int32 i = 0; i < itemCount; i++) { 211 BLayoutItem* item = ItemAt(i); 212 213 BSize min = item->MinSize(); 214 BSize max = item->MaxSize(); 215 BSize preferred = item->PreferredSize(); 216 217 fMin.width = max_c(fMin.width, min.width); 218 fMin.height = max_c(fMin.height, min.height); 219 220 fMax.width = min_c(fMax.width, max.width); 221 fMax.height = min_c(fMax.height, max.height); 222 223 fPreferred.width = max_c(fPreferred.width, preferred.width); 224 fPreferred.height = max_c(fPreferred.height, preferred.height); 225 } 226 227 fMax.width = max_c(fMax.width, fMin.width); 228 fMax.height = max_c(fMax.height, fMin.height); 229 230 fPreferred.width = max_c(fPreferred.width, fMin.width); 231 fPreferred.height = max_c(fPreferred.height, fMin.height); 232 fPreferred.width = min_c(fPreferred.width, fMax.width); 233 fPreferred.height = min_c(fPreferred.height, fMax.height); 234 235 fMinMaxValid = true; 236 } 237