BSize BButton::_ValidatePreferredSize() { if (fPreferredSize.width < 0) { // width float width = 20.0f + (float)ceil(StringWidth(Label())); if (width < 75.0f) width = 75.0f; if (fDrawAsDefault) width += 6.0f; fPreferredSize.width = width; // height font_height fontHeight; GetFontHeight(&fontHeight); fPreferredSize.height = ceilf((fontHeight.ascent + fontHeight.descent) * 1.8) + (fDrawAsDefault ? 6.0f : 0); ResetLayoutInvalidation(); } return fPreferredSize; }
BSize BButton::_ValidatePreferredSize() { if (fPreferredSize.width < 0) { BControlLook::background_type backgroundType = fBehavior == B_POP_UP_BEHAVIOR ? BControlLook::B_BUTTON_WITH_POP_UP_BACKGROUND : BControlLook::B_BUTTON_BACKGROUND; float left, top, right, bottom; be_control_look->GetInsets(BControlLook::B_BUTTON_FRAME, backgroundType, IsDefault() ? BControlLook::B_DEFAULT_BUTTON : 0, left, top, right, bottom); // width float width = left + right + 2 * kLabelMargin - 1; const char* label = Label(); if (label != NULL) { width = std::max(width, 20.0f); width += (float)ceil(StringWidth(label)); } const BBitmap* icon = IconBitmap(B_INACTIVE_ICON_BITMAP); if (icon != NULL) width += icon->Bounds().Width() + 1; if (label != NULL && icon != NULL) width += be_control_look->DefaultLabelSpacing(); // height float minHorizontalMargins = top + bottom + 2 * kLabelMargin; float height = -1; if (label != NULL) { font_height fontHeight; GetFontHeight(&fontHeight); float textHeight = fontHeight.ascent + fontHeight.descent; height = ceilf(textHeight * 1.8); float margins = height - ceilf(textHeight); if (margins < minHorizontalMargins) height += minHorizontalMargins - margins; } if (icon != NULL) { height = std::max(height, icon->Bounds().Height() + minHorizontalMargins); } // force some minimum width/height values width = std::max(width, label != NULL ? 75.0f : 5.0f); height = std::max(height, 5.0f); fPreferredSize.Set(width, height); ResetLayoutInvalidation(); } return fPreferredSize; }
void BMenuField::_ValidateLayoutData() { CALLED(); if (fLayoutData->valid) return; // cache font height font_height& fh = fLayoutData->font_info; GetFontHeight(&fh); if (Label() != NULL) { fLayoutData->label_width = ceilf(StringWidth(Label())); fLayoutData->label_height = ceilf(fh.ascent) + ceilf(fh.descent); } else { fLayoutData->label_width = 0; fLayoutData->label_height = 0; } // compute the minimal divider float divider = 0; if (fLayoutData->label_width > 0) divider = fLayoutData->label_width + 5; // If we shan't do real layout, we let the current divider take influence. if (!(Flags() & B_SUPPORTS_LAYOUT)) divider = max_c(divider, fDivider); // get the minimal (== preferred) menu bar size // TODO: BMenu::MinSize() is using the ResizeMode() to decide the // minimum width. If the mode is B_FOLLOW_LEFT_RIGHT, it will use the // parent's frame width or window's frame width. So at least the returned // size is wrong, but apparantly it doesn't have much bad effect. fLayoutData->menu_bar_min = fMenuBar->MinSize(); TRACE("menu bar min width: %.2f\n", fLayoutData->menu_bar_min.width); // compute our minimal (== preferred) size BSize min(fLayoutData->menu_bar_min); min.width += 2 * kVMargin; min.height += 2 * kVMargin; if (divider > 0) min.width += divider; if (fLayoutData->label_height > min.height) min.height = fLayoutData->label_height; fLayoutData->min = min; fLayoutData->valid = true; ResetLayoutInvalidation(); TRACE("width: %.2f, height: %.2f\n", min.width, min.height); }
void BTextControl::_ValidateLayoutData() { CALLED(); if (fLayoutData->valid) return; // cache font height font_height& fh = fLayoutData->font_info; GetFontHeight(&fh); if (Label() != NULL) { fLayoutData->label_width = ceilf(StringWidth(Label())); fLayoutData->label_height = ceilf(fh.ascent) + ceilf(fh.descent); } else { fLayoutData->label_width = 0; fLayoutData->label_height = 0; } // compute the minimal divider float divider = 0; if (fLayoutData->label_width > 0) { divider = fLayoutData->label_width + be_control_look->DefaultLabelSpacing(); } // If we shan't do real layout, we let the current divider take influence. if (!(Flags() & B_SUPPORTS_LAYOUT)) divider = max_c(divider, fDivider); // get the minimal (== preferred) text view size fLayoutData->text_view_min = fText->MinSize(); TRACE("text view min width: %.2f\n", fLayoutData->text_view_min.width); // compute our minimal (== preferred) size BSize min(fLayoutData->text_view_min); min.width += 2 * kFrameMargin; min.height += 2 * kFrameMargin; if (divider > 0) min.width += divider; if (fLayoutData->label_height > min.height) min.height = fLayoutData->label_height; fLayoutData->min = min; fLayoutData->valid = true; ResetLayoutInvalidation(); TRACE("width: %.2f, height: %.2f\n", min.width, min.height); }
BSize BStringView::_ValidatePreferredSize() { if (fPreferredSize.height < 0) { // height font_height fontHeight; GetFontHeight(&fontHeight); fPreferredSize.height = ceilf(fontHeight.ascent + fontHeight.descent + fontHeight.leading); ResetLayoutInvalidation(); } return fPreferredSize; }
void BAbstractSpinner::_ValidateLayoutData() { if (fLayoutData->valid) return; font_height fontHeight = fLayoutData->font_info; GetFontHeight(&fontHeight); if (Label() != NULL) { fLayoutData->label_width = StringWidth(Label()); fLayoutData->label_height = ceilf(fontHeight.ascent + fontHeight.descent + fontHeight.leading); } else { fLayoutData->label_width = 0; fLayoutData->label_height = 0; } float divider = 0; if (fLayoutData->label_width > 0) { divider = ceilf(fLayoutData->label_width + be_control_look->DefaultLabelSpacing()); } if ((Flags() & B_SUPPORTS_LAYOUT) == 0) divider = std::max(divider, fDivider); float minTextWidth = fTextView->StringWidth("99999"); float textViewHeight = fTextView->LineHeight(0) + kFrameMargin * 2; float textViewWidth = minTextWidth + textViewHeight * 2; fLayoutData->text_view_width = textViewWidth; fLayoutData->text_view_height = textViewHeight; BSize min(textViewWidth, textViewHeight); if (divider > 0.0f) min.width += divider; if (fLayoutData->label_height > min.height) min.height = fLayoutData->label_height; fLayoutData->min = min; fLayoutData->valid = true; ResetLayoutInvalidation(); }
void BBox::_ValidateLayoutData() { if (fLayoutData->valid) return; // compute the label box, width and height bool label = true; float labelHeight = 0; // height of the label (pixel count) if (fLabel) { // leave 6 pixels of the frame, and have a gap of 4 pixels between // the frame and the text on either side font_height fontHeight; GetFontHeight(&fontHeight); fLayoutData->label_box.Set(6.0f, 0, 14.0f + StringWidth(fLabel), ceilf(fontHeight.ascent)); labelHeight = ceilf(fontHeight.ascent + fontHeight.descent) + 1; } else if (fLabelView) { // the label view is placed at (0, 10) at its preferred size BSize size = fLabelView->PreferredSize(); fLayoutData->label_box.Set(10, 0, 10 + size.width, size.height); labelHeight = size.height + 1; } else { label = false; } // border switch (fStyle) { case B_PLAIN_BORDER: fLayoutData->insets.Set(1, 1, 1, 1); break; case B_FANCY_BORDER: fLayoutData->insets.Set(3, 3, 3, 3); break; case B_NO_BORDER: default: fLayoutData->insets.Set(0, 0, 0, 0); break; } // if there's a label, the top inset will be dictated by the label if (label && labelHeight > fLayoutData->insets.top) fLayoutData->insets.top = labelHeight; // total number of pixel the border adds float addWidth = fLayoutData->insets.left + fLayoutData->insets.right; float addHeight = fLayoutData->insets.top + fLayoutData->insets.bottom; // compute the minimal width induced by the label float minWidth; if (label) minWidth = fLayoutData->label_box.right + fLayoutData->insets.right; else minWidth = addWidth - 1; // finally consider the child constraints, if we shall support layout BView* child = _Child(); if (child && (Flags() & B_SUPPORTS_LAYOUT)) { BSize min = child->MinSize(); BSize max = child->MaxSize(); BSize preferred = child->PreferredSize(); min.width += addWidth; min.height += addHeight; preferred.width += addWidth; preferred.height += addHeight; max.width = BLayoutUtils::AddDistances(max.width, addWidth - 1); max.height = BLayoutUtils::AddDistances(max.height, addHeight - 1); if (min.width < minWidth) min.width = minWidth; BLayoutUtils::FixSizeConstraints(min, max, preferred); fLayoutData->min = min; fLayoutData->max = max; fLayoutData->preferred = preferred; } else { fLayoutData->min.Set(minWidth, addHeight - 1); fLayoutData->max.Set(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED); fLayoutData->preferred = fLayoutData->min; } fLayoutData->valid = true; ResetLayoutInvalidation(); }
BSize BSlider::_ValidateMinSize() { if (fMinSize.width >= 0) { // the preferred size is up to date return fMinSize; } font_height fontHeight; GetFontHeight(&fontHeight); float width = 0.0; float height = 0.0; if (fMaxUpdateTextWidth < 0.0) fMaxUpdateTextWidth = MaxUpdateTextWidth(); if (Orientation() == B_HORIZONTAL) { height = 12.0 + fBarThickness; int32 rows = 0; float labelWidth = 0; int32 labelRows = 0; float labelSpacing = StringWidth("M") * 2; if (Label()) { labelWidth = StringWidth(Label()); labelRows = 1; } if (fMaxUpdateTextWidth > 0.0) { if (labelWidth > 0) labelWidth += labelSpacing; labelWidth += fMaxUpdateTextWidth; labelRows = 1; } rows += labelRows; if (MinLimitLabel()) width = StringWidth(MinLimitLabel()); if (MaxLimitLabel()) { // some space between the labels if (MinLimitLabel()) width += labelSpacing; width += StringWidth(MaxLimitLabel()); } if (labelWidth > width) width = labelWidth; if (width < 32.0) width = 32.0; if (MinLimitLabel() || MaxLimitLabel()) rows++; height += rows * (ceilf(fontHeight.ascent) + ceilf(fontHeight.descent) + 4.0); } else { // B_VERTICAL width = 12.0 + fBarThickness; height = 32.0; float lineHeightNoLeading = ceilf(fontHeight.ascent) + ceilf(fontHeight.descent); float lineHeight = lineHeightNoLeading + ceilf(fontHeight.leading); // find largest label float labelWidth = 0; if (Label()) { labelWidth = StringWidth(Label()); height += lineHeightNoLeading; } if (MaxLimitLabel()) { labelWidth = max_c(labelWidth, StringWidth(MaxLimitLabel())); height += Label() ? lineHeight : lineHeightNoLeading; } if (MinLimitLabel()) { labelWidth = max_c(labelWidth, StringWidth(MinLimitLabel())); height += lineHeightNoLeading; } if (fMaxUpdateTextWidth > 0.0) { labelWidth = max_c(labelWidth, fMaxUpdateTextWidth); height += MinLimitLabel() ? lineHeight : lineHeightNoLeading; } width = max_c(labelWidth, width); } fMinSize.width = width; fMinSize.height = height; ResetLayoutInvalidation(); return fMinSize; }