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 SetLimits(int32 minimum, int32 maximum);
|
||||||
|
|
||||||
|
virtual void InvalidateLayout(bool descendants = false);
|
||||||
|
|
||||||
|
virtual BSize MinSize();
|
||||||
|
virtual BSize MaxSize();
|
||||||
|
virtual BSize PreferredSize();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _DrawBlockThumb();
|
void _DrawBlockThumb();
|
||||||
void _DrawTriangleThumb();
|
void _DrawTriangleThumb();
|
||||||
@ -156,6 +162,8 @@ class BSlider : public BControl {
|
|||||||
float _MaxPosition() const;
|
float _MaxPosition() const;
|
||||||
bool _ConstrainPoint(BPoint& point, BPoint compare) const;
|
bool _ConstrainPoint(BPoint& point, BPoint compare) const;
|
||||||
|
|
||||||
|
BSize _ValidateMinSize();
|
||||||
|
|
||||||
virtual void _ReservedSlider5();
|
virtual void _ReservedSlider5();
|
||||||
virtual void _ReservedSlider6();
|
virtual void _ReservedSlider6();
|
||||||
virtual void _ReservedSlider7();
|
virtual void _ReservedSlider7();
|
||||||
@ -201,10 +209,12 @@ class BSlider : public BControl {
|
|||||||
orientation fOrientation;
|
orientation fOrientation;
|
||||||
float fBarThickness;
|
float fBarThickness;
|
||||||
|
|
||||||
|
BSize fMinSize;
|
||||||
|
|
||||||
#if USE_OFF_SCREEN_VIEW
|
#if USE_OFF_SCREEN_VIEW
|
||||||
uint32 _reserved[7];
|
uint32 _reserved[5];
|
||||||
#else
|
#else
|
||||||
uint32 _reserved[9];
|
uint32 _reserved[7];
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <Slider.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -16,12 +18,11 @@
|
|||||||
|
|
||||||
#include <Bitmap.h>
|
#include <Bitmap.h>
|
||||||
#include <Errors.h>
|
#include <Errors.h>
|
||||||
|
#include <LayoutUtils.h>
|
||||||
#include <Message.h>
|
#include <Message.h>
|
||||||
#include <Region.h>
|
#include <Region.h>
|
||||||
#include <Window.h>
|
#include <Window.h>
|
||||||
|
|
||||||
#include <Slider.h>
|
|
||||||
|
|
||||||
|
|
||||||
BSlider::BSlider(BRect frame, const char* name, const char* label,
|
BSlider::BSlider(BRect frame, const char* name, const char* label,
|
||||||
BMessage* message, int32 minValue, int32 maxValue,
|
BMessage* message, int32 minValue, int32 maxValue,
|
||||||
@ -223,6 +224,7 @@ BSlider::_InitObject()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
fUpdateText = NULL;
|
fUpdateText = NULL;
|
||||||
|
fMinSize.Set(-1, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -736,6 +738,9 @@ BSlider::GetLimits(int32 *minimum, int32 *maximum)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - drawing
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BSlider::Draw(BRect updateRect)
|
BSlider::Draw(BRect updateRect)
|
||||||
{
|
{
|
||||||
@ -743,9 +748,9 @@ BSlider::Draw(BRect updateRect)
|
|||||||
BRegion background(updateRect);
|
BRegion background(updateRect);
|
||||||
background.Exclude(BarFrame());
|
background.Exclude(BarFrame());
|
||||||
|
|
||||||
// ToDo: the triangle thumb doesn't delete its background, so we still have to do it
|
// ToDo: the triangle thumb doesn't delete its background, so we still have
|
||||||
// Note, this also creates a different behaviour for subclasses, depending on the
|
// to do it Note, this also creates a different behaviour for subclasses,
|
||||||
// thumb style - if possible this should be avoided.
|
// depending on the thumb style - if possible this should be avoided.
|
||||||
if (Style() == B_BLOCK_THUMB)
|
if (Style() == B_BLOCK_THUMB)
|
||||||
background.Exclude(ThumbFrame());
|
background.Exclude(ThumbFrame());
|
||||||
|
|
||||||
@ -1095,6 +1100,9 @@ BSlider::DrawText()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
char*
|
char*
|
||||||
BSlider::UpdateText() const
|
BSlider::UpdateText() const
|
||||||
{
|
{
|
||||||
@ -1229,86 +1237,13 @@ BSlider::SetResizingMode(uint32 mode)
|
|||||||
void
|
void
|
||||||
BSlider::GetPreferredSize(float* _width, float* _height)
|
BSlider::GetPreferredSize(float* _width, float* _height)
|
||||||
{
|
{
|
||||||
font_height fontHeight;
|
BSize preferredSize = PreferredSize();
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_width)
|
if (_width)
|
||||||
*_width = width;
|
*_width = preferredSize.width;
|
||||||
|
|
||||||
if (_height)
|
if (_height)
|
||||||
*_height = height;
|
*_height = preferredSize.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1412,6 +1347,7 @@ void
|
|||||||
BSlider::SetHashMarks(hash_mark_location where)
|
BSlider::SetHashMarks(hash_mark_location where)
|
||||||
{
|
{
|
||||||
fHashMarks = where;
|
fHashMarks = where;
|
||||||
|
InvalidateLayout();
|
||||||
Invalidate();
|
Invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1427,6 +1363,7 @@ void
|
|||||||
BSlider::SetStyle(thumb_style style)
|
BSlider::SetStyle(thumb_style style)
|
||||||
{
|
{
|
||||||
fStyle = style;
|
fStyle = style;
|
||||||
|
InvalidateLayout();
|
||||||
Invalidate();
|
Invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1497,6 +1434,7 @@ void
|
|||||||
BSlider::SetOrientation(orientation posture)
|
BSlider::SetOrientation(orientation posture)
|
||||||
{
|
{
|
||||||
fOrientation = posture;
|
fOrientation = posture;
|
||||||
|
InvalidateLayout();
|
||||||
Invalidate();
|
Invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1511,8 +1449,12 @@ BSlider::BarThickness() const
|
|||||||
void
|
void
|
||||||
BSlider::SetBarThickness(float thickness)
|
BSlider::SetBarThickness(float thickness)
|
||||||
{
|
{
|
||||||
if (thickness >= 1.0f)
|
if (thickness < 1.0)
|
||||||
|
thickness = 1.0;
|
||||||
|
if (thickness != fBarThickness) {
|
||||||
fBarThickness = thickness;
|
fBarThickness = thickness;
|
||||||
|
InvalidateLayout();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1529,6 +1471,8 @@ BSlider::SetFont(const BFont *font, uint32 properties)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
void
|
||||||
BSlider::_DrawBlockThumb()
|
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::_ReservedSlider5() {}
|
||||||
void BSlider::_ReservedSlider6() {}
|
void BSlider::_ReservedSlider6() {}
|
||||||
void BSlider::_ReservedSlider7() {}
|
void BSlider::_ReservedSlider7() {}
|
||||||
|
Loading…
Reference in New Issue
Block a user