* Applied Stefano's patch to fix bug #1241; BScrollBar::SetValue() did not work
correctly for out of bounds values. * BView::ScrollBy() now limits itself to what eventually attached scroll bars allow; this fixes the problem Stefano was observing after having applied his patch. * Reenabled the limit check in BScrollBar::SetProportion(); after the above fix, I could not see any misbehaviour of Tracker anymore; IOW Tracker did not rely on this before, it was just hiding another bug :) * Minor cleanup in ScrollBar.cpp git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21336 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -9,16 +9,17 @@
|
|||||||
* Stephan Aßmus <[email protected]>
|
* Stephan Aßmus <[email protected]>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
#include <ScrollBar.h>
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <Message.h>
|
#include <Message.h>
|
||||||
#include <OS.h>
|
#include <OS.h>
|
||||||
#include <Shape.h>
|
#include <Shape.h>
|
||||||
#include <Window.h>
|
#include <Window.h>
|
||||||
|
|
||||||
#include <ScrollBar.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
//#define TEST_MODE
|
//#define TEST_MODE
|
||||||
|
|
||||||
@@ -163,9 +164,13 @@ BScrollBar::Private::ButtonRepeaterThread()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
BScrollBar::BScrollBar(BRect frame, const char* name, BView *target,
|
BScrollBar::BScrollBar(BRect frame, const char* name, BView *target,
|
||||||
float min, float max, orientation direction)
|
float min, float max, orientation direction)
|
||||||
: BView(frame, name, B_FOLLOW_NONE, B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE | B_FRAME_EVENTS),
|
: BView(frame, name, B_FOLLOW_NONE, B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE
|
||||||
|
| B_FRAME_EVENTS),
|
||||||
fMin(min),
|
fMin(min),
|
||||||
fMax(max),
|
fMax(max),
|
||||||
fSmallStep(1),
|
fSmallStep(1),
|
||||||
@@ -185,10 +190,9 @@ BScrollBar::BScrollBar(BRect frame, const char* name, BView *target,
|
|||||||
_UpdateThumbFrame();
|
_UpdateThumbFrame();
|
||||||
_UpdateArrowButtons();
|
_UpdateArrowButtons();
|
||||||
|
|
||||||
SetResizingMode((direction == B_VERTICAL) ?
|
SetResizingMode(direction == B_VERTICAL
|
||||||
B_FOLLOW_TOP_BOTTOM | B_FOLLOW_RIGHT :
|
? B_FOLLOW_TOP_BOTTOM | B_FOLLOW_RIGHT
|
||||||
B_FOLLOW_LEFT_RIGHT | B_FOLLOW_BOTTOM );
|
: B_FOLLOW_LEFT_RIGHT | B_FOLLOW_BOTTOM);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -223,28 +227,28 @@ BScrollBar::Instantiate(BMessage *data)
|
|||||||
status_t
|
status_t
|
||||||
BScrollBar::Archive(BMessage *data, bool deep) const
|
BScrollBar::Archive(BMessage *data, bool deep) const
|
||||||
{
|
{
|
||||||
status_t err = BView::Archive(data,deep);
|
status_t err = BView::Archive(data, deep);
|
||||||
if (err != B_OK)
|
if (err != B_OK)
|
||||||
return err;
|
return err;
|
||||||
err = data->AddFloat("_range",fMin);
|
err = data->AddFloat("_range", fMin);
|
||||||
if (err != B_OK)
|
if (err != B_OK)
|
||||||
return err;
|
return err;
|
||||||
err = data->AddFloat("_range",fMax);
|
err = data->AddFloat("_range", fMax);
|
||||||
if (err != B_OK)
|
if (err != B_OK)
|
||||||
return err;
|
return err;
|
||||||
err = data->AddFloat("_steps",fSmallStep);
|
err = data->AddFloat("_steps", fSmallStep);
|
||||||
if (err != B_OK)
|
if (err != B_OK)
|
||||||
return err;
|
return err;
|
||||||
err = data->AddFloat("_steps",fLargeStep);
|
err = data->AddFloat("_steps", fLargeStep);
|
||||||
if (err != B_OK)
|
if (err != B_OK)
|
||||||
return err;
|
return err;
|
||||||
err = data->AddFloat("_val",fValue);
|
err = data->AddFloat("_val", fValue);
|
||||||
if (err != B_OK)
|
if (err != B_OK)
|
||||||
return err;
|
return err;
|
||||||
err = data->AddInt32("_orient",(int32)fOrientation);
|
err = data->AddInt32("_orient", (int32)fOrientation);
|
||||||
if (err != B_OK)
|
if (err != B_OK)
|
||||||
return err;
|
return err;
|
||||||
err = data->AddInt32("_prop",(int32)fProportion);
|
err = data->AddInt32("_prop", (int32)fProportion);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -253,7 +257,6 @@ BScrollBar::Archive(BMessage *data, bool deep) const
|
|||||||
void
|
void
|
||||||
BScrollBar::AttachedToWindow()
|
BScrollBar::AttachedToWindow()
|
||||||
{
|
{
|
||||||
// R5's SB contacts the server if fValue!=0. I *think* we don't need to do anything here...
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -291,15 +294,17 @@ an actual BView within the scroll bar's window.
|
|||||||
void
|
void
|
||||||
BScrollBar::SetValue(float value)
|
BScrollBar::SetValue(float value)
|
||||||
{
|
{
|
||||||
|
if (value > fMax)
|
||||||
|
value = fMax;
|
||||||
|
else if (value < fMin)
|
||||||
|
value = fMin;
|
||||||
|
|
||||||
|
value = roundf(value);
|
||||||
|
|
||||||
if (value == fValue)
|
if (value == fValue)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (value > fMax)
|
fValue = value;
|
||||||
value = fMax;
|
|
||||||
if (value < fMin)
|
|
||||||
value = fMin;
|
|
||||||
|
|
||||||
fValue = roundf(value);
|
|
||||||
|
|
||||||
_UpdateThumbFrame();
|
_UpdateThumbFrame();
|
||||||
_UpdateArrowButtons();
|
_UpdateArrowButtons();
|
||||||
@@ -338,20 +343,19 @@ BScrollBar::ValueChanged(float newValue)
|
|||||||
void
|
void
|
||||||
BScrollBar::SetProportion(float value)
|
BScrollBar::SetProportion(float value)
|
||||||
{
|
{
|
||||||
// NOTE: The Tracker depends on the broken
|
if (value < 0.0)
|
||||||
// behaviour to allow a proportion less than
|
|
||||||
// 0 or greater than 1
|
|
||||||
/* if (value < 0.0)
|
|
||||||
value = 0.0;
|
value = 0.0;
|
||||||
if (value > 1.0)
|
if (value > 1.0)
|
||||||
value = 1.0;*/
|
value = 1.0;
|
||||||
|
|
||||||
if (value != fProportion) {
|
if (value != fProportion) {
|
||||||
bool oldEnabled = fPrivateData->fEnabled && fMin < fMax && fProportion < 1.0 && fProportion >= 0.0;
|
bool oldEnabled = fPrivateData->fEnabled && fMin < fMax
|
||||||
|
&& fProportion < 1.0 && fProportion >= 0.0;
|
||||||
|
|
||||||
fProportion = value;
|
fProportion = value;
|
||||||
|
|
||||||
bool newEnabled = fPrivateData->fEnabled && fMin < fMax && fProportion < 1.0 && fProportion >= 0.0;
|
bool newEnabled = fPrivateData->fEnabled && fMin < fMax
|
||||||
|
&& fProportion < 1.0 && fProportion >= 0.0;
|
||||||
|
|
||||||
_UpdateThumbFrame();
|
_UpdateThumbFrame();
|
||||||
|
|
||||||
@@ -641,7 +645,8 @@ BScrollBar::Draw(BRect updateRect)
|
|||||||
StrokeRect(bounds);
|
StrokeRect(bounds);
|
||||||
bounds.InsetBy(1.0, 1.0);
|
bounds.InsetBy(1.0, 1.0);
|
||||||
|
|
||||||
bool enabled = fPrivateData->fEnabled && fMin < fMax && fProportion < 1.0 && fProportion >= 0.0;
|
bool enabled = fPrivateData->fEnabled && fMin < fMax
|
||||||
|
&& fProportion < 1.0 && fProportion >= 0.0;
|
||||||
|
|
||||||
rgb_color light, light1, dark, dark1, dark2, dark4;
|
rgb_color light, light1, dark, dark1, dark2, dark4;
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
@@ -1032,10 +1037,13 @@ BScrollBar::_DoubleArrows() const
|
|||||||
|
|
||||||
// if there is not enough room, switch to single arrows even though
|
// if there is not enough room, switch to single arrows even though
|
||||||
// double arrows is specified
|
// double arrows is specified
|
||||||
if (fOrientation == B_HORIZONTAL)
|
if (fOrientation == B_HORIZONTAL) {
|
||||||
return Bounds().Width() > (Bounds().Height() + 1) * 4 + fPrivateData->fScrollBarInfo.min_knob_size * 2;
|
return Bounds().Width() > (Bounds().Height() + 1) * 4
|
||||||
else
|
+ fPrivateData->fScrollBarInfo.min_knob_size * 2;
|
||||||
return Bounds().Height() > (Bounds().Width() + 1) * 4 + fPrivateData->fScrollBarInfo.min_knob_size * 2;
|
} else {
|
||||||
|
return Bounds().Height() > (Bounds().Width() + 1) * 4
|
||||||
|
+ fPrivateData->fScrollBarInfo.min_knob_size * 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// _UpdateThumbFrame
|
// _UpdateThumbFrame
|
||||||
@@ -1099,7 +1107,8 @@ BScrollBar::_UpdateThumbFrame()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (Window()) {
|
if (Window()) {
|
||||||
BRect invalid = oldFrame.IsValid() ? oldFrame | fPrivateData->fThumbFrame : fPrivateData->fThumbFrame;
|
BRect invalid = oldFrame.IsValid() ? oldFrame | fPrivateData->fThumbFrame
|
||||||
|
: fPrivateData->fThumbFrame;
|
||||||
// account for those two dark lines
|
// account for those two dark lines
|
||||||
if (fOrientation == B_HORIZONTAL)
|
if (fOrientation == B_HORIZONTAL)
|
||||||
invalid.InsetBy(-2.0, 0.0);
|
invalid.InsetBy(-2.0, 0.0);
|
||||||
|
|||||||
@@ -1499,31 +1499,51 @@ BView::ScrollBar(orientation posture) const
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BView::ScrollBy(float dh, float dv)
|
BView::ScrollBy(float deltaX, float deltaY)
|
||||||
{
|
{
|
||||||
// scrolling by fractional values is not supported, is it?
|
// scrolling by fractional values is not supported
|
||||||
dh = roundf(dh);
|
deltaX = roundf(deltaX);
|
||||||
dv = roundf(dv);
|
deltaY = roundf(deltaY);
|
||||||
|
|
||||||
// no reason to process this further if no scroll is intended.
|
// no reason to process this further if no scroll is intended.
|
||||||
if (dh == 0 && dv == 0)
|
if (deltaX == 0 && deltaY == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// make sure scrolling is within valid bounds
|
||||||
|
if (fHorScroller) {
|
||||||
|
float min, max;
|
||||||
|
fHorScroller->GetRange(&min, &max);
|
||||||
|
|
||||||
|
if (deltaX + fBounds.left < min)
|
||||||
|
deltaX = min - fBounds.left;
|
||||||
|
else if (deltaX + fBounds.left > max)
|
||||||
|
deltaX = max - fBounds.left;
|
||||||
|
}
|
||||||
|
if (fVerScroller) {
|
||||||
|
float min, max;
|
||||||
|
fVerScroller->GetRange(&min, &max);
|
||||||
|
|
||||||
|
if (deltaY + fBounds.top < min)
|
||||||
|
deltaY = min - fBounds.top;
|
||||||
|
else if (deltaY + fBounds.top > max)
|
||||||
|
deltaY = max - fBounds.top;
|
||||||
|
}
|
||||||
|
|
||||||
check_lock();
|
check_lock();
|
||||||
|
|
||||||
// if we're attached to a window tell app_server about this change
|
// if we're attached to a window tell app_server about this change
|
||||||
if (fOwner) {
|
if (fOwner) {
|
||||||
fOwner->fLink->StartMessage(AS_LAYER_SCROLL);
|
fOwner->fLink->StartMessage(AS_LAYER_SCROLL);
|
||||||
fOwner->fLink->Attach<float>(dh);
|
fOwner->fLink->Attach<float>(deltaX);
|
||||||
fOwner->fLink->Attach<float>(dv);
|
fOwner->fLink->Attach<float>(deltaY);
|
||||||
|
|
||||||
fOwner->fLink->Flush();
|
fOwner->fLink->Flush();
|
||||||
|
|
||||||
fState->valid_flags &= ~(B_VIEW_FRAME_BIT | B_VIEW_ORIGIN_BIT);
|
fState->valid_flags &= ~(B_VIEW_FRAME_BIT | B_VIEW_ORIGIN_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
// we modify our bounds rectangle by dh/dv coord units hor/ver.
|
// we modify our bounds rectangle by deltaX/deltaY coord units hor/ver.
|
||||||
fBounds.OffsetBy(dh, dv);
|
fBounds.OffsetBy(deltaX, deltaY);
|
||||||
|
|
||||||
// then set the new values of the scrollbars
|
// then set the new values of the scrollbars
|
||||||
if (fHorScroller)
|
if (fHorScroller)
|
||||||
|
|||||||
Reference in New Issue
Block a user