First round of BSlider fixes to be more layout friendly:
* Improve the minimum size calculation and cache it. * Invalidate the layout on various property changes that require it. Vertical BSliders are very broken... that's up next. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26441 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
cdcfa5945d
commit
423b124450
@ -145,6 +145,12 @@ class BSlider : public BControl {
|
||||
|
||||
virtual void SetLimits(int32 minimum, int32 maximum);
|
||||
|
||||
virtual void InvalidateLayout(bool descendants = false);
|
||||
|
||||
virtual BSize MinSize();
|
||||
virtual BSize MaxSize();
|
||||
virtual BSize PreferredSize();
|
||||
|
||||
private:
|
||||
void _DrawBlockThumb();
|
||||
void _DrawTriangleThumb();
|
||||
@ -156,6 +162,8 @@ class BSlider : public BControl {
|
||||
float _MaxPosition() const;
|
||||
bool _ConstrainPoint(BPoint& point, BPoint compare) const;
|
||||
|
||||
BSize _ValidateMinSize();
|
||||
|
||||
virtual void _ReservedSlider5();
|
||||
virtual void _ReservedSlider6();
|
||||
virtual void _ReservedSlider7();
|
||||
@ -201,10 +209,12 @@ class BSlider : public BControl {
|
||||
orientation fOrientation;
|
||||
float fBarThickness;
|
||||
|
||||
BSize fMinSize;
|
||||
|
||||
#if USE_OFF_SCREEN_VIEW
|
||||
uint32 _reserved[7];
|
||||
uint32 _reserved[5];
|
||||
#else
|
||||
uint32 _reserved[9];
|
||||
uint32 _reserved[7];
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -9,6 +9,8 @@
|
||||
*/
|
||||
|
||||
|
||||
#include <Slider.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
@ -16,12 +18,11 @@
|
||||
|
||||
#include <Bitmap.h>
|
||||
#include <Errors.h>
|
||||
#include <LayoutUtils.h>
|
||||
#include <Message.h>
|
||||
#include <Region.h>
|
||||
#include <Window.h>
|
||||
|
||||
#include <Slider.h>
|
||||
|
||||
|
||||
BSlider::BSlider(BRect frame, const char* name, const char* label,
|
||||
BMessage* message, int32 minValue, int32 maxValue,
|
||||
@ -223,6 +224,7 @@ BSlider::_InitObject()
|
||||
#endif
|
||||
|
||||
fUpdateText = NULL;
|
||||
fMinSize.Set(-1, -1);
|
||||
}
|
||||
|
||||
|
||||
@ -736,6 +738,9 @@ BSlider::GetLimits(int32 *minimum, int32 *maximum)
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - drawing
|
||||
|
||||
|
||||
void
|
||||
BSlider::Draw(BRect updateRect)
|
||||
{
|
||||
@ -743,9 +748,9 @@ BSlider::Draw(BRect updateRect)
|
||||
BRegion background(updateRect);
|
||||
background.Exclude(BarFrame());
|
||||
|
||||
// ToDo: the triangle thumb doesn't delete its background, so we still have to do it
|
||||
// Note, this also creates a different behaviour for subclasses, depending on the
|
||||
// thumb style - if possible this should be avoided.
|
||||
// ToDo: the triangle thumb doesn't delete its background, so we still have
|
||||
// to do it Note, this also creates a different behaviour for subclasses,
|
||||
// depending on the thumb style - if possible this should be avoided.
|
||||
if (Style() == B_BLOCK_THUMB)
|
||||
background.Exclude(ThumbFrame());
|
||||
|
||||
@ -1095,6 +1100,9 @@ BSlider::DrawText()
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
char*
|
||||
BSlider::UpdateText() const
|
||||
{
|
||||
@ -1229,86 +1237,13 @@ BSlider::SetResizingMode(uint32 mode)
|
||||
void
|
||||
BSlider::GetPreferredSize(float* _width, float* _height)
|
||||
{
|
||||
font_height fontHeight;
|
||||
GetFontHeight(&fontHeight);
|
||||
|
||||
float width, height;
|
||||
int32 rows = 0;
|
||||
|
||||
if (Orientation() == B_HORIZONTAL) {
|
||||
width = Frame().Width();
|
||||
height = 12.0f + fBarThickness;
|
||||
|
||||
float labelWidth = 0;
|
||||
if (Label()) {
|
||||
labelWidth = StringWidth(Label());
|
||||
rows++;
|
||||
}
|
||||
|
||||
float minWidth = 0;
|
||||
if (MinLimitLabel())
|
||||
minWidth = StringWidth(MinLimitLabel());
|
||||
if (MaxLimitLabel()) {
|
||||
// some space between the labels
|
||||
if (MinLimitLabel())
|
||||
minWidth += 8.0f;
|
||||
|
||||
minWidth += StringWidth(MaxLimitLabel());
|
||||
}
|
||||
|
||||
if (minWidth > width)
|
||||
width = minWidth;
|
||||
if (labelWidth > width)
|
||||
width = labelWidth;
|
||||
if (width < 32.0f)
|
||||
width = 32.0f;
|
||||
|
||||
if (MinLimitLabel() || MaxLimitLabel())
|
||||
rows++;
|
||||
|
||||
height += rows * ((float)ceil(fontHeight.ascent + fontHeight.descent) + 4.0f);
|
||||
} else {
|
||||
// B_VERTICAL
|
||||
width = 12.0f + fBarThickness;
|
||||
height = Frame().Height();
|
||||
|
||||
// find largest label
|
||||
|
||||
float minWidth = 0;
|
||||
if (Label()) {
|
||||
minWidth = StringWidth(Label());
|
||||
rows++;
|
||||
}
|
||||
if (MinLimitLabel()) {
|
||||
float width = StringWidth(MinLimitLabel());
|
||||
if (width > minWidth)
|
||||
minWidth = width;
|
||||
rows++;
|
||||
}
|
||||
if (MaxLimitLabel()) {
|
||||
float width = StringWidth(MaxLimitLabel());
|
||||
if (width > minWidth)
|
||||
minWidth = width;
|
||||
rows++;
|
||||
}
|
||||
|
||||
if (minWidth > width)
|
||||
width = minWidth;
|
||||
|
||||
float minHeight = 32.0f + rows
|
||||
* ((float)ceil(fontHeight.ascent + fontHeight.descent) + 4.0f);
|
||||
|
||||
if (Label() && MaxLimitLabel())
|
||||
minHeight -= 4.0f;
|
||||
|
||||
if (minHeight > height)
|
||||
height = minHeight;
|
||||
}
|
||||
BSize preferredSize = PreferredSize();
|
||||
|
||||
if (_width)
|
||||
*_width = width;
|
||||
*_width = preferredSize.width;
|
||||
|
||||
if (_height)
|
||||
*_height = height;
|
||||
*_height = preferredSize.height;
|
||||
}
|
||||
|
||||
|
||||
@ -1412,6 +1347,7 @@ void
|
||||
BSlider::SetHashMarks(hash_mark_location where)
|
||||
{
|
||||
fHashMarks = where;
|
||||
InvalidateLayout();
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
@ -1427,6 +1363,7 @@ void
|
||||
BSlider::SetStyle(thumb_style style)
|
||||
{
|
||||
fStyle = style;
|
||||
InvalidateLayout();
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
@ -1497,6 +1434,7 @@ void
|
||||
BSlider::SetOrientation(orientation posture)
|
||||
{
|
||||
fOrientation = posture;
|
||||
InvalidateLayout();
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
@ -1511,8 +1449,12 @@ BSlider::BarThickness() const
|
||||
void
|
||||
BSlider::SetBarThickness(float thickness)
|
||||
{
|
||||
if (thickness >= 1.0f)
|
||||
if (thickness < 1.0)
|
||||
thickness = 1.0;
|
||||
if (thickness != fBarThickness) {
|
||||
fBarThickness = thickness;
|
||||
InvalidateLayout();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1529,6 +1471,8 @@ BSlider::SetFont(const BFont *font, uint32 properties)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
InvalidateLayout();
|
||||
}
|
||||
|
||||
|
||||
@ -1550,6 +1494,53 @@ BSlider::SetLimits(int32 minimum, int32 maximum)
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - layout related
|
||||
|
||||
|
||||
void
|
||||
BSlider::InvalidateLayout(bool descendants)
|
||||
{
|
||||
// invalidate cached preferred size
|
||||
fMinSize.Set(-1, -1);
|
||||
|
||||
BControl::InvalidateLayout(descendants);
|
||||
}
|
||||
|
||||
|
||||
BSize
|
||||
BSlider::MinSize()
|
||||
{
|
||||
return BLayoutUtils::ComposeSize(ExplicitMinSize(),
|
||||
_ValidateMinSize());
|
||||
}
|
||||
|
||||
|
||||
BSize
|
||||
BSlider::MaxSize()
|
||||
{
|
||||
BSize maxSize = _ValidateMinSize();
|
||||
if (fOrientation == B_HORIZONTAL)
|
||||
maxSize.width = B_SIZE_UNLIMITED;
|
||||
else
|
||||
maxSize.height = B_SIZE_UNLIMITED;
|
||||
return BLayoutUtils::ComposeSize(ExplicitMaxSize(), maxSize);
|
||||
}
|
||||
|
||||
|
||||
BSize
|
||||
BSlider::PreferredSize()
|
||||
{
|
||||
BSize preferredSize = _ValidateMinSize();
|
||||
if (fOrientation == B_HORIZONTAL)
|
||||
preferredSize.width = max_c(100.0, preferredSize.width);
|
||||
else
|
||||
preferredSize.height = max_c(100.0, preferredSize.height);
|
||||
return BLayoutUtils::ComposeSize(ExplicitPreferredSize(), preferredSize);
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - private
|
||||
|
||||
void
|
||||
BSlider::_DrawBlockThumb()
|
||||
{
|
||||
@ -1794,6 +1785,87 @@ BSlider::_MaxPosition() const
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
int32 rows = 0;
|
||||
|
||||
if (Orientation() == B_HORIZONTAL) {
|
||||
height = 12.0 + fBarThickness;
|
||||
|
||||
float labelWidth = 0;
|
||||
if (Label()) {
|
||||
labelWidth = StringWidth(Label());
|
||||
rows++;
|
||||
}
|
||||
|
||||
if (MinLimitLabel())
|
||||
width = StringWidth(MinLimitLabel());
|
||||
if (MaxLimitLabel()) {
|
||||
// some space between the labels
|
||||
if (MinLimitLabel())
|
||||
width += 8.0;
|
||||
|
||||
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;
|
||||
|
||||
// find largest label
|
||||
float labelWidth = 0;
|
||||
if (Label()) {
|
||||
labelWidth = StringWidth(Label());
|
||||
rows++;
|
||||
}
|
||||
if (MinLimitLabel()) {
|
||||
labelWidth = max_c(labelWidth, StringWidth(MinLimitLabel()));
|
||||
rows++;
|
||||
}
|
||||
if (MaxLimitLabel()) {
|
||||
labelWidth = max_c(labelWidth, StringWidth(MaxLimitLabel()));
|
||||
rows++;
|
||||
}
|
||||
|
||||
width = max_c(labelWidth, width);
|
||||
|
||||
height = 32.0 + rows * (ceilf(fontHeight.ascent)
|
||||
+ ceilf(fontHeight.descent) + 4.0);
|
||||
|
||||
if (Label() && MaxLimitLabel())
|
||||
height -= 4.0f;
|
||||
}
|
||||
|
||||
fMinSize.width = width;
|
||||
fMinSize.height = height;
|
||||
|
||||
return fMinSize;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - FBC padding
|
||||
|
||||
void BSlider::_ReservedSlider5() {}
|
||||
void BSlider::_ReservedSlider6() {}
|
||||
void BSlider::_ReservedSlider7() {}
|
||||
|
Loading…
Reference in New Issue
Block a user