void BTwoDimensionalLayout::LocalLayouter::AddConstraints( CompoundLayouter* compoundLayouter, Layouter* layouter) { enum orientation orientation = compoundLayouter->Orientation(); int itemCount = fLayout->CountItems(); if (itemCount > 0) { for (int i = 0; i < itemCount; i++) { BLayoutItem* item = fLayout->ItemAt(i); if (item->IsVisible()) { Dimensions itemDimensions; fLayout->GetItemDimensions(item, &itemDimensions); BSize min = item->MinSize(); BSize max = item->MaxSize(); BSize preferred = item->PreferredSize(); if (orientation == B_HORIZONTAL) { layouter->AddConstraints( itemDimensions.x, itemDimensions.width, min.width, max.width, preferred.width); if (item->HasHeightForWidth()) fHeightForWidthItems.AddItem(item); } else { layouter->AddConstraints( itemDimensions.y, itemDimensions.height, min.height, max.height, preferred.height); } } } // add column/row constraints ColumnRowConstraints constraints; int elementCount = CountElements(compoundLayouter); for (int element = 0; element < elementCount; element++) { fLayout->GetColumnRowConstraints(orientation, element, &constraints); layouter->SetWeight(element, constraints.weight); layouter->AddConstraints(element, 1, constraints.min, constraints.max, constraints.min); } } }
// GetHeightForWidth void BCardLayout::GetHeightForWidth(float width, float* min, float* max, float* preferred) { _ValidateMinMax(); // init with useful values float minHeight = fMin.height; float maxHeight = fMax.height; float preferredHeight = fPreferred.height; // apply the items' constraints int32 count = CountItems(); for (int32 i = 0; i < count; i++) { BLayoutItem* item = ItemAt(i); if (item->HasHeightForWidth()) { float itemMinHeight; float itemMaxHeight; float itemPreferredHeight; item->GetHeightForWidth(width, &itemMinHeight, &itemMaxHeight, &itemPreferredHeight); minHeight = max_c(minHeight, itemMinHeight); maxHeight = min_c(maxHeight, itemMaxHeight); preferredHeight = min_c(preferredHeight, itemPreferredHeight); } } // adjust max and preferred, if necessary maxHeight = max_c(maxHeight, minHeight); preferredHeight = max_c(preferredHeight, minHeight); preferredHeight = min_c(preferredHeight, maxHeight); if (min) *min = minHeight; if (max) *max = maxHeight; if (preferred) *preferred = preferredHeight; }
void BSplitLayout::_ValidateMinMax() { if (fHorizontalLayouter != NULL) return; fLayoutValid = false; fVisibleItems.MakeEmpty(); fHeightForWidthItems.MakeEmpty(); _InvalidateCachedHeightForWidth(); // filter the visible items int32 itemCount = CountItems(); for (int32 i = 0; i < itemCount; i++) { BLayoutItem* item = ItemAt(i); if (item->IsVisible()) fVisibleItems.AddItem(item); // Add "height for width" items even, if they aren't visible. Otherwise // we may get our parent into trouble, since we could change from // "height for width" to "not height for width". if (item->HasHeightForWidth()) fHeightForWidthItems.AddItem(item); } itemCount = fVisibleItems.CountItems(); // create the layouters Layouter* itemLayouter = new SimpleLayouter(itemCount, 0); if (fOrientation == B_HORIZONTAL) { fHorizontalLayouter = itemLayouter; fVerticalLayouter = new OneElementLayouter(); } else { fHorizontalLayouter = new OneElementLayouter(); fVerticalLayouter = itemLayouter; } // tell the layouters about our constraints if (itemCount > 0) { for (int32 i = 0; i < itemCount; i++) { BLayoutItem* item = (BLayoutItem*)fVisibleItems.ItemAt(i); BSize min = item->MinSize(); BSize max = item->MaxSize(); BSize preferred = item->PreferredSize(); fHorizontalLayouter->AddConstraints(i, 1, min.width, max.width, preferred.width); fVerticalLayouter->AddConstraints(i, 1, min.height, max.height, preferred.height); float weight = ItemWeight(item); fHorizontalLayouter->SetWeight(i, weight); fVerticalLayouter->SetWeight(i, weight); } } fMin.width = fHorizontalLayouter->MinSize(); fMin.height = fVerticalLayouter->MinSize(); fMax.width = fHorizontalLayouter->MaxSize(); fMax.height = fVerticalLayouter->MaxSize(); fPreferred.width = fHorizontalLayouter->PreferredSize(); fPreferred.height = fVerticalLayouter->PreferredSize(); fHorizontalLayoutInfo = fHorizontalLayouter->CreateLayoutInfo(); if (fHeightForWidthItems.IsEmpty()) fVerticalLayoutInfo = fVerticalLayouter->CreateLayoutInfo(); ResetLayoutInvalidation(); }