void BSlider::GetPreferredSize(float* _width, float* _height) { BSize preferredSize = PreferredSize(); if (Orientation() == B_HORIZONTAL) { if (_width != NULL) { // NOTE: For compatibility reasons, a horizontal BSlider // never shrinks horizontally. This only affects applications // which do not use the new layout system. *_width = max_c(Bounds().Width(), preferredSize.width); } if (_height != NULL) *_height = preferredSize.height; } else { if (_width != NULL) *_width = preferredSize.width; if (_height != NULL) { // NOTE: Similarly, a vertical BSlider never shrinks // vertically. This only affects applications which do not // use the new layout system. *_height = max_c(Bounds().Height(), preferredSize.height); } } }
void ConfigView::AttachedToWindow() { BGroupView::AttachedToWindow(); fPresetsMenu->SetTargetForItems(this); fQualitySlider->SetTarget(this); fMethodSlider->SetTarget(this); fPreprocessingCheckBox->SetTarget(this); if (Parent() == NULL && Window()->GetLayout() == NULL) { Window()->SetLayout(new BGroupLayout(B_VERTICAL)); Window()->ResizeTo(PreferredSize().Width(), PreferredSize().Height()); } }
void Label::Layout() { if (m_preferredSize == Point()) PreferredSize(); const Point &size = GetSize(); SetActiveArea(Point(std::min(m_preferredSize.x,size.x), std::min(m_preferredSize.y,size.y))); }
IconView::IconView(const char* name, int32 iconSize) : BView(name, B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE), fIconBitmap(NULL) { fIconBitmap = new BBitmap(BRect(0, 0, iconSize - 1, iconSize - 1), B_RGBA32); SetExplicitMaxSize(PreferredSize()); }
void GIFView::AllAttached() { BMessenger messenger(this); fInterlacedCB->SetTarget(messenger); fUseDitheringCB->SetTarget(messenger); fUseTransparentCB->SetTarget(messenger); fUseTransparentAutoRB->SetTarget(messenger); fUseTransparentColorRB->SetTarget(messenger); fRedTextControl->SetTarget(messenger); fGreenTextControl->SetTarget(messenger); fBlueTextControl->SetTarget(messenger); fPaletteM->SetTargetForItems(messenger); fColorCountM->SetTargetForItems(messenger); BView::AllAttached(); if (Parent() == NULL && Window()->GetLayout() == NULL) { Window()->SetLayout(new BGroupLayout(B_VERTICAL)); Window()->ResizeTo(PreferredSize().Width(), PreferredSize().Height()); } }
void Box::Layout() { if (m_children.size() == 0) return; PreferredSize(); const Point boxSize = GetSize(); Point::Component vc, fc; GetComponentsForOrient(m_orient == BOX_HORIZONTAL, vc, fc); // fast path. we know the exact size that everything wants, so just // loop and hand it out if (m_numVariable == 0) { Point childPos(0), childSize(0); for (std::list<Child>::iterator i = m_children.begin(); i != m_children.end(); ++i) { childSize[fc] = boxSize[fc]; childSize[vc] = (*i).contribSize[vc]; const Point actualSize(CalcSize((*i).widget, childSize)); SetWidgetDimensions((*i).widget, childPos, actualSize); childPos[vc] += actualSize[vc] + m_spacing; } } // we have one or more children that have requested the maximum size // possible. each with a known size gets it, and any remaining space is // distributed evenly among the max-sized children. if there is no // remaining space, then we're already outside the bounds, so just give // them something else { const int sizeAvail = boxSize[vc]; const int sizeMin = sizeAvail/10; // 10%, as good as anything const int amount = m_minAllocation < sizeAvail ? std::max((sizeAvail-m_minAllocation-m_spacing*(int(m_children.size())-1))/m_numVariable, sizeMin) : sizeMin; Point childPos(0), childSize(0); for (std::list<Child>::iterator i = m_children.begin(); i != m_children.end(); ++i) { childSize[fc] = boxSize[fc]; childSize[vc] = (*i).contribSize[vc] == SIZE_EXPAND ? amount : (*i).contribSize[vc]; const Point actualSize(CalcSize((*i).widget, childSize)); SetWidgetDimensions((*i).widget, childPos, actualSize); childPos[vc] += actualSize[vc] + m_spacing; } } LayoutChildren(); }
Point Widget::CalcSize(const Point &avail) { if (!(GetSizeControlFlags() & PRESERVE_ASPECT)) return avail; const Point preferredSize = PreferredSize(); float wantRatio = float(preferredSize.x) / float(preferredSize.y); // more room on X than Y, use full X, scale Y if (avail.x > avail.y) return Point(float(avail.y) * wantRatio, avail.y); // more room on Y than X, use full Y, scale X else return Point(avail.x, float(avail.x) / wantRatio); }
Point Widget::CalcLayoutContribution() { Point preferredSize = PreferredSize(); const Uint32 flags = GetSizeControlFlags(); if (flags & NO_WIDTH) preferredSize.x = 0; if (flags & NO_HEIGHT) preferredSize.y = 0; if (flags & EXPAND_WIDTH) preferredSize.x = SIZE_EXPAND; if (flags & EXPAND_HEIGHT) preferredSize.y = SIZE_EXPAND; return preferredSize; }
Point Widget::CalcSize(const Point &avail) { if (!(GetSizeControlFlags() & PRESERVE_ASPECT)) return avail; const Point preferredSize = PreferredSize(); const float wantRatio = float(preferredSize.x) / float(preferredSize.y); const float haveRatio = float(avail.x) / float(avail.y); if (wantRatio > haveRatio) { // limited by width return Point(avail.x, float(avail.x) / wantRatio); } else { // limited by height return Point(float(avail.y) * wantRatio, avail.y); } }
void Button::Layout() { Widget *innerWidget = GetInnerWidget(); const Skin::BorderedRectElement &elem(GetContext()->GetSkin().ButtonNormal()); if (!innerWidget) { SetActiveArea(PreferredSize()); return; } const Point innerSize = GetSize() - Point(elem.paddingX*2, elem.paddingY*2); SetWidgetDimensions(innerWidget, Point(elem.paddingX, elem.paddingY), innerWidget->CalcSize(innerSize)); innerWidget->Layout(); Point innerActiveArea(innerWidget->GetActiveArea()); growToMinimum(innerActiveArea, GetContext()->GetSkin().ButtonMinInnerSize()); SetActiveArea(innerActiveArea + Point(elem.paddingX*2, elem.paddingY*2)); }
void TouchpadPrefView::AttachedToWindow() { fTouchpadView->SetTarget(this); fTwoFingerBox->SetTarget(this); fTwoFingerHorizontalBox->SetTarget(this); fScrollStepXSlider->SetTarget(this); fScrollStepYSlider->SetTarget(this); fScrollAccelSlider->SetTarget(this); fTapSlider->SetTarget(this); fDefaultButton->SetTarget(this); fRevertButton->SetTarget(this); BSize size = PreferredSize(); Window()->ResizeTo(size.width, size.height); BPoint position = fTouchpadPref.WindowPosition(); // center window on screen if it had a bad position if (position.x < 0 && position.y < 0) Window()->CenterOnScreen(); else Window()->MoveTo(position); }
void dng_host::ValidateSizes () { // The maximum size limits the other two sizes. if (MaximumSize ()) { SetMinimumSize (Min_uint32 (MinimumSize (), MaximumSize ())); SetPreferredSize (Min_uint32 (PreferredSize (), MaximumSize ())); } // If we have a preferred size, it limits the minimum size. if (PreferredSize ()) { SetMinimumSize (Min_uint32 (MinimumSize (), PreferredSize ())); } // Else find default value for preferred size. else { // If preferred size is zero, then we want the maximim // size image. if (MaximumSize ()) { SetPreferredSize (MaximumSize ()); } } // If we don't have a minimum size, find default. if (!MinimumSize ()) { // A common size for embedded thumbnails is 120 by 160 pixels, // So allow 120 by 160 pixels to be used for thumbnails when the // preferred size is 256 pixel. if (PreferredSize () >= 160 && PreferredSize () <= 256) { SetMinimumSize (160); } // Many sensors are near a multiple of 1024 pixels in size, but after // the default crop, they are a just under. We can get an extra factor // of size reduction if we allow a slight undershoot in the final size // when computing large previews. else if (PreferredSize () >= 490 && PreferredSize () <= 512) { SetMinimumSize (490); } else if (PreferredSize () >= 980 && PreferredSize () <= 1024) { SetMinimumSize (980); } else if (PreferredSize () >= 1470 && PreferredSize () <= 1536) { SetMinimumSize (1470); } else if (PreferredSize () >= 1960 && PreferredSize () <= 2048) { SetMinimumSize (1960); } // Else minimum size is same as preferred size. else { SetMinimumSize (PreferredSize ()); } } }
void SmallButton::Layout() { SetActiveArea(PreferredSize()); }
int WgTablePanel::HeightForWidth( int width ) const { //TODO: Implement, should recurse through lines and their widgets checking height needed. return PreferredSize().h; // No recommendation, for the moment }
/*! Tries to find the right frame to show the tool tip in, trying to use the alignment that the tool tip specifies. Makes sure the tool tip can be shown on screen in its entirety, ie. it will resize the window if necessary. */ void ToolTipView::ResetWindowFrame(BPoint where) { if (Window() == NULL) return; BSize size = PreferredSize(); BScreen screen(Window()); BRect screenFrame = screen.Frame().InsetBySelf(2, 2); BPoint offset = fToolTip->MouseRelativeLocation(); // Ensure that the tip can be placed on screen completely if (size.width > screenFrame.Width()) size.width = screenFrame.Width(); if (size.width > where.x - screenFrame.left && size.width > screenFrame.right - where.x) { // There is no space to put the tip to the left or the right of the // cursor, it can either be below or above it if (size.height > where.y - screenFrame.top && where.y - screenFrame.top > screenFrame.Height() / 2) { size.height = where.y - offset.y - screenFrame.top; } else if (size.height > screenFrame.bottom - where.y && screenFrame.bottom - where.y > screenFrame.Height() / 2) { size.height = screenFrame.bottom - where.y - offset.y; } } // Find best alignment, starting with the requested one BAlignment alignment = fToolTip->Alignment(); BPoint location = where; bool doesNotFit = false; switch (alignment.horizontal) { case B_ALIGN_LEFT: location.x -= size.width + offset.x; if (location.x < screenFrame.left) { location.x = screenFrame.left; doesNotFit = true; } break; case B_ALIGN_CENTER: location.x -= size.width / 2 - offset.x; if (location.x < screenFrame.left) { location.x = screenFrame.left; doesNotFit = true; } else if (location.x + size.width > screenFrame.right) { location.x = screenFrame.right - size.width; doesNotFit = true; } break; default: location.x += offset.x; if (location.x + size.width > screenFrame.right) { location.x = screenFrame.right - size.width; doesNotFit = true; } break; } if ((doesNotFit && alignment.vertical == B_ALIGN_MIDDLE) || (alignment.vertical == B_ALIGN_MIDDLE && alignment.horizontal == B_ALIGN_CENTER)) alignment.vertical = B_ALIGN_BOTTOM; // Adjust the tooltip position in cases where it would be partly out of the // screen frame. Try to fit the tooltip on the requested side of the // cursor, if that fails, try the opposite side, and if that fails again, // give up and leave the tooltip under the mouse cursor. bool firstTry = true; while (true) { switch (alignment.vertical) { case B_ALIGN_TOP: location.y = where.y - size.height - offset.y; if (location.y < screenFrame.top) { alignment.vertical = firstTry ? B_ALIGN_BOTTOM : B_ALIGN_MIDDLE; firstTry = false; continue; } break; case B_ALIGN_MIDDLE: location.y -= size.height / 2 - offset.y; if (location.y < screenFrame.top) location.y = screenFrame.top; else if (location.y + size.height > screenFrame.bottom) location.y = screenFrame.bottom - size.height; break; default: location.y = where.y + offset.y; if (location.y + size.height > screenFrame.bottom) { alignment.vertical = firstTry ? B_ALIGN_TOP : B_ALIGN_MIDDLE; firstTry = false; continue; } break; } break; } where = location; // Cut off any out-of-screen areas if (screenFrame.left > where.x) { size.width -= where.x - screenFrame.left; where.x = screenFrame.left; } else if (screenFrame.right < where.x + size.width) size.width = screenFrame.right - where.x; if (screenFrame.top > where.y) { size.height -= where.y - screenFrame.top; where.y = screenFrame.top; } else if (screenFrame.bottom < where.y + size.height) size.height -= screenFrame.bottom - where.y; // Change window frame Window()->ResizeTo(size.width, size.height); Window()->MoveTo(where); }
void Box::Layout() { if (m_children.size() == 0) return; PreferredSize(); const Point boxSize = GetSize(); Point::Component vc, fc; GetComponentsForOrient(m_orient == BOX_HORIZONTAL, vc, fc); float sizeRemaining = boxSize[vc] - (m_spacing * (m_children.size()-1)); Point childPos(0); // the largest equal share each child can have const float maxChildSize = boxSize[vc]/m_children.size(); for (std::list<Child>::iterator i = m_children.begin(); i != m_children.end(); ++i) { (*i).padding = 0; float childSize = 0; // if we have enough room to give _everyone_ what they want, do it if (boxSize[vc] >= m_preferredSize[vc]) childSize = (*i).preferredSize[vc]; // if this child wants less than their share, give it to them else if (maxChildSize >= (*i).preferredSize[vc]) childSize = (*i).preferredSize[vc]; // otherwise they get their share else childSize = maxChildSize; (*i).size[vc] = childSize; (*i).size[fc] = boxSize[fc]; sizeRemaining -= childSize; if (m_countExpanded == 0) { SetWidgetDimensions((*i).widget, childPos, (*i).size); childPos[vc] += childSize + m_spacing; } } if (m_countExpanded > 0) { int candidates = m_countExpanded; while (candidates > 0 && sizeRemaining > 0 && !is_zero_general(sizeRemaining)) { float allocation = sizeRemaining / candidates; for (std::list<Child>::iterator i = m_children.begin(); i != m_children.end(); ++i) { if (!((*i).flags & BOX_EXPAND)) continue; float amountAdded; if (!((*i).flags & BOX_FILL)) { (*i).padding += allocation * 0.5; amountAdded = allocation; } else { (*i).size[vc] += allocation; amountAdded = allocation; } sizeRemaining -= amountAdded; } } for (std::list<Child>::iterator i = m_children.begin(); i != m_children.end(); ++i) { Point pos = childPos; pos[vc] += (*i).padding; SetWidgetDimensions((*i).widget, pos, (*i).size); childPos[vc] = pos[vc] + (*i).size[vc] + (*i).padding + m_spacing; } } LayoutChildren(); }
void Box::Layout() { if (m_children.empty()) return; PreferredSize(); const Point& boxSize = GetSize(); Point::Component vc, fc; GetComponentsForOrient(m_orient == BOX_HORIZONTAL, vc, fc); // fast path. we know the exact size that everything wants, so just // loop and hand it out if (m_numVariable == 0) { // we got what we asked for so everyone can have what they want if (boxSize[vc] >= m_preferredSize[vc]) { for (std::list<Child>::iterator i = m_children.begin(); i != m_children.end(); ++i) { (*i).size[fc] = boxSize[fc]; (*i).size[vc] = (*i).contribSize[vc]; } } // didn't get enough, so we have share it around else { // we can certainly afford to give everyone this much int availSize = boxSize[vc] - (m_spacing * (m_children.size()-1)); int minSize = availSize / m_children.size(); int remaining = availSize; int wantMore = 0; // loop and hand it out for (std::list<Child>::iterator i = m_children.begin(); i != m_children.end(); ++i) { (*i).size[fc] = boxSize[fc]; (*i).size[vc] = std::min(minSize, (*i).contribSize[vc]); remaining -= (*i).size[vc]; // if this one didn't get us much as it wanted then count it // if we have any left over we can give it some more if ((*i).size[vc] < (*i).contribSize[vc]) wantMore++; } // if there's some remaining and not everyone got what they wanted, hand it out assert(remaining >= 0); if (remaining && wantMore) { int extra = remaining / wantMore; for (std::list<Child>::iterator i = m_children.begin(); i != m_children.end(); ++i) { if ((*i).size[vc] < (*i).contribSize[vc]) (*i).size[vc] += extra; } } } } // we have one or more children that have requested the maximum size possible else { int availSize = boxSize[vc] - (m_spacing * (m_children.size()-1)); int remaining = availSize; // fixed ones first if (m_children.size() > m_numVariable) { // distribute evenly among the fixed ones int minSize = availSize / (m_children.size() - m_numVariable); // loop and hand it out for (std::list<Child>::iterator i = m_children.begin(); i != m_children.end(); ++i) { // don't give any to expanding ones yet if ((*i).contribSize[vc] == SIZE_EXPAND) continue; (*i).size[fc] = boxSize[fc]; (*i).size[vc] = std::min(minSize, (*i).contribSize[vc]); remaining -= (*i).size[vc]; } } // if there's any space remaining, distribute it among the expanding widgets assert(remaining >= 0); if (remaining) { int extra = remaining / m_numVariable; for (std::list<Child>::iterator i = m_children.begin(); i != m_children.end(); ++i) { if ((*i).contribSize[vc] != SIZE_EXPAND) continue; (*i).size[fc] = boxSize[fc]; (*i).size[vc] = extra; } } } // now loop over them again and position Point childPos(0); for (std::list<Child>::iterator i = m_children.begin(); i != m_children.end(); ++i) { const Point actualSize((*i).widget->CalcSize((*i).size)); SetWidgetDimensions((*i).widget, childPos, actualSize); childPos[vc] += actualSize[vc] + m_spacing; } LayoutChildren(); }
PreferredSize TBImageWidget::OnCalculatePreferredContentSize(const SizeConstraints &constraints) { return PreferredSize(m_image.Width(), m_image.Height()); }
void CheckBox::Layout() { SetActiveArea(PreferredSize()); }