* 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:
Axel Dörfler 2007-06-05 23:58:21 +00:00
parent 2a72b9fead
commit 96726e7e24
2 changed files with 79 additions and 50 deletions

View File

@ -9,16 +9,17 @@
* Stephan Aßmus <superstippi@gmx.de>
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ScrollBar.h>
#include <Message.h>
#include <OS.h>
#include <Shape.h>
#include <Window.h>
#include <ScrollBar.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//#define TEST_MODE
@ -163,9 +164,13 @@ BScrollBar::Private::ButtonRepeaterThread()
}
// #pragma mark -
BScrollBar::BScrollBar(BRect frame, const char* name, BView *target,
float min, float max, orientation direction)
: BView(frame, name, B_FOLLOW_NONE, B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE | B_FRAME_EVENTS),
float min, float max, orientation direction)
: BView(frame, name, B_FOLLOW_NONE, B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE
| B_FRAME_EVENTS),
fMin(min),
fMax(max),
fSmallStep(1),
@ -177,18 +182,17 @@ BScrollBar::BScrollBar(BRect frame, const char* name, BView *target,
fTargetName(NULL)
{
SetViewColor(B_TRANSPARENT_COLOR);
fPrivateData = new BScrollBar::Private(this);
SetTarget(target);
_UpdateThumbFrame();
_UpdateArrowButtons();
SetResizingMode((direction == B_VERTICAL) ?
B_FOLLOW_TOP_BOTTOM | B_FOLLOW_RIGHT :
B_FOLLOW_LEFT_RIGHT | B_FOLLOW_BOTTOM );
SetResizingMode(direction == B_VERTICAL
? B_FOLLOW_TOP_BOTTOM | B_FOLLOW_RIGHT
: B_FOLLOW_LEFT_RIGHT | B_FOLLOW_BOTTOM);
}
@ -223,29 +227,29 @@ BScrollBar::Instantiate(BMessage *data)
status_t
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)
return err;
err = data->AddFloat("_range",fMin);
err = data->AddFloat("_range", fMin);
if (err != B_OK)
return err;
err = data->AddFloat("_range",fMax);
err = data->AddFloat("_range", fMax);
if (err != B_OK)
return err;
err = data->AddFloat("_steps",fSmallStep);
err = data->AddFloat("_steps", fSmallStep);
if (err != B_OK)
return err;
err = data->AddFloat("_steps",fLargeStep);
err = data->AddFloat("_steps", fLargeStep);
if (err != B_OK)
return err;
err = data->AddFloat("_val",fValue);
err = data->AddFloat("_val", fValue);
if (err != B_OK)
return err;
err = data->AddInt32("_orient",(int32)fOrientation);
err = data->AddInt32("_orient", (int32)fOrientation);
if (err != B_OK)
return err;
err = data->AddInt32("_prop",(int32)fProportion);
err = data->AddInt32("_prop", (int32)fProportion);
return err;
}
@ -253,7 +257,6 @@ BScrollBar::Archive(BMessage *data, bool deep) const
void
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
BScrollBar::SetValue(float value)
{
if (value > fMax)
value = fMax;
else if (value < fMin)
value = fMin;
value = roundf(value);
if (value == fValue)
return;
if (value > fMax)
value = fMax;
if (value < fMin)
value = fMin;
fValue = roundf(value);
fValue = value;
_UpdateThumbFrame();
_UpdateArrowButtons();
@ -338,20 +343,19 @@ BScrollBar::ValueChanged(float newValue)
void
BScrollBar::SetProportion(float value)
{
// NOTE: The Tracker depends on the broken
// behaviour to allow a proportion less than
// 0 or greater than 1
/* if (value < 0.0)
if (value < 0.0)
value = 0.0;
if (value > 1.0)
value = 1.0;*/
value = 1.0;
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;
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();
@ -641,7 +645,8 @@ BScrollBar::Draw(BRect updateRect)
StrokeRect(bounds);
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;
if (enabled) {
@ -1032,10 +1037,13 @@ BScrollBar::_DoubleArrows() const
// if there is not enough room, switch to single arrows even though
// double arrows is specified
if (fOrientation == B_HORIZONTAL)
return Bounds().Width() > (Bounds().Height() + 1) * 4 + fPrivateData->fScrollBarInfo.min_knob_size * 2;
else
return Bounds().Height() > (Bounds().Width() + 1) * 4 + fPrivateData->fScrollBarInfo.min_knob_size * 2;
if (fOrientation == B_HORIZONTAL) {
return Bounds().Width() > (Bounds().Height() + 1) * 4
+ fPrivateData->fScrollBarInfo.min_knob_size * 2;
} else {
return Bounds().Height() > (Bounds().Width() + 1) * 4
+ fPrivateData->fScrollBarInfo.min_knob_size * 2;
}
}
// _UpdateThumbFrame
@ -1099,7 +1107,8 @@ BScrollBar::_UpdateThumbFrame()
}
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
if (fOrientation == B_HORIZONTAL)
invalid.InsetBy(-2.0, 0.0);

View File

@ -1499,31 +1499,51 @@ BView::ScrollBar(orientation posture) const
void
BView::ScrollBy(float dh, float dv)
BView::ScrollBy(float deltaX, float deltaY)
{
// scrolling by fractional values is not supported, is it?
dh = roundf(dh);
dv = roundf(dv);
// scrolling by fractional values is not supported
deltaX = roundf(deltaX);
deltaY = roundf(deltaY);
// no reason to process this further if no scroll is intended.
if (dh == 0 && dv == 0)
if (deltaX == 0 && deltaY == 0)
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();
// if we're attached to a window tell app_server about this change
if (fOwner) {
fOwner->fLink->StartMessage(AS_LAYER_SCROLL);
fOwner->fLink->Attach<float>(dh);
fOwner->fLink->Attach<float>(dv);
fOwner->fLink->Attach<float>(deltaX);
fOwner->fLink->Attach<float>(deltaY);
fOwner->fLink->Flush();
fState->valid_flags &= ~(B_VIEW_FRAME_BIT | B_VIEW_ORIGIN_BIT);
}
// we modify our bounds rectangle by dh/dv coord units hor/ver.
fBounds.OffsetBy(dh, dv);
// we modify our bounds rectangle by deltaX/deltaY coord units hor/ver.
fBounds.OffsetBy(deltaX, deltaY);
// then set the new values of the scrollbars
if (fHorScroller)