* 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:
parent
2a72b9fead
commit
96726e7e24
@ -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);
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user