stunning improvements to drawing, completely removed flickering, only minor visual problems remain, maybe needs testing with regard to targeted views being removed or the scrollbar being removed etc

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@14736 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2005-11-07 01:26:13 +00:00
parent 0118ad76e1
commit 5083a8d56d
2 changed files with 220 additions and 193 deletions
+13 -38
View File
@@ -1,30 +1,13 @@
//------------------------------------------------------------------------------ /*
// Copyright (c) 2001-2002, OpenBeOS * Copyright (c) 2001-2005, Haiku, Inc.
// * Distributed under the terms of the MIT license.
// Permission is hereby granted, free of charge, to any person obtaining a *
// copy of this software and associated documentation files (the "Software"), * Authors:
// to deal in the Software without restriction, including without limitation * Marc Flerackers ([email protected])
// the rights to use, copy, modify, merge, publish, distribute, sublicense, * DarkWyrm ([email protected])
// and/or sell copies of the Software, and to permit persons to whom the * Stephan Aßmus <[email protected]>
// Software is furnished to do so, subject to the following conditions: */
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// File Name: ScrollBar.h
// Author: Marc Flerackers ([email protected])
// DarkWyrm ([email protected])
// Description: Client-side class for scrolling
//
//------------------------------------------------------------------------------
#ifndef _SCROLL_BAR_H #ifndef _SCROLL_BAR_H
#define _SCROLL_BAR_H #define _SCROLL_BAR_H
@@ -120,17 +103,9 @@ virtual void _ReservedScrollBar4();
void _UpdateTargetValue(BPoint where); void _UpdateTargetValue(BPoint where);
void _UpdateArrowButtons(); void _UpdateArrowButtons();
void _DrawArrowButton(int32 direction, void _DrawArrowButton(int32 direction,
BRect frame, bool down); BRect frame,
const BRect& updateRect,
bool down);
/* void DrawButtons(BRect updateRect);
void DrawArrow(BPoint pos, int32 which, bool pressed = false);
void DrawButton(BRect frame, int32 arrowType, bool pressed = false);
BRect BarFrame() const;
BRect KnobFrame() const;
float ValueToPosition(float val) const;
float PositionToValue(float pos) const;*/
float fMin; float fMin;
float fMax; float fMax;
+207 -155
View File
@@ -1,30 +1,12 @@
//------------------------------------------------------------------------------ /*
// Copyright (c) 2001-2005 Haiku * Copyright (c) 2001-2005, Haiku, Inc.
// * Distributed under the terms of the MIT license.
// Permission is hereby granted, free of charge, to any person obtaining a *
// copy of this software and associated documentation files (the "Software"), * Authors:
// to deal in the Software without restriction, including without limitation * Marc Flerackers ([email protected])
// the rights to use, copy, modify, merge, publish, distribute, sublicense, * DarkWyrm ([email protected])
// and/or sell copies of the Software, and to permit persons to whom the * Stephan Aßmus <[email protected]>
// Software is furnished to do so, subject to the following conditions: */
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// File Name: ScrollBar.cpp
// Author: Marc Flerackers ([email protected])
// DarkWyrm ([email protected])
// Description: Client-side class for scrolling
//
//------------------------------------------------------------------------------
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -32,6 +14,7 @@
#include <Message.h> #include <Message.h>
#include <OS.h> #include <OS.h>
#include <Shape.h>
#include <Window.h> #include <Window.h>
#include <ScrollBar.h> #include <ScrollBar.h>
@@ -181,7 +164,7 @@ BScrollBar::Private::ButtonRepeaterThread()
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), : 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),
@@ -192,7 +175,7 @@ BScrollBar::BScrollBar(BRect frame, const char* name, BView *target,
fOrientation(direction), fOrientation(direction),
fTargetName(NULL) fTargetName(NULL)
{ {
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); SetViewColor(B_TRANSPARENT_COLOR);
fPrivateData = new BScrollBar::Private(this); fPrivateData = new BScrollBar::Private(this);
@@ -218,19 +201,19 @@ BScrollBar::~BScrollBar()
{ {
delete fPrivateData; delete fPrivateData;
free(fTargetName); free(fTargetName);
// TODO: detaching from target is currently done in DetachedFromWindow(),
// TODO: Disconnect from target // maybe it should be done here instead?
} }
// Instantiate
BArchivable * BArchivable*
BScrollBar::Instantiate(BMessage *data) BScrollBar::Instantiate(BMessage *data)
{ {
// TODO: Implement // TODO: Implement
return NULL; return NULL;
} }
// Archive
status_t status_t
BScrollBar::Archive(BMessage *data, bool deep) const BScrollBar::Archive(BMessage *data, bool deep) const
{ {
@@ -246,14 +229,14 @@ BScrollBar::Archive(BMessage *data, bool deep) const
return B_OK; return B_OK;
} }
// AttachedToWindow
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... // R5's SB contacts the server if fValue!=0. I *think* we don't need to do anything here...
} }
// SetValue
void void
BScrollBar::SetValue(float value) BScrollBar::SetValue(float value)
{ {
@@ -291,14 +274,14 @@ BScrollBar::SetProportion(float value)
} }
} }
// Proportion
float float
BScrollBar::Proportion() const BScrollBar::Proportion() const
{ {
return fProportion; return fProportion;
} }
// ValueChanged
void void
BScrollBar::ValueChanged(float newValue) BScrollBar::ValueChanged(float newValue)
{ {
@@ -348,7 +331,7 @@ an actual BView within the scroll bar's window.
_UpdateArrowButtons(); _UpdateArrowButtons();
} }
// SetRange
void void
BScrollBar::SetRange(float min, float max) BScrollBar::SetRange(float min, float max)
{ {
@@ -367,7 +350,7 @@ BScrollBar::SetRange(float min, float max)
ValueChanged(fValue); ValueChanged(fValue);
} }
// GetRange
void void
BScrollBar::GetRange(float *min, float *max) const BScrollBar::GetRange(float *min, float *max) const
{ {
@@ -377,7 +360,7 @@ BScrollBar::GetRange(float *min, float *max) const
*max = fMax; *max = fMax;
} }
// SetSteps
void void
BScrollBar::SetSteps(float smallStep, float largeStep) BScrollBar::SetSteps(float smallStep, float largeStep)
{ {
@@ -392,17 +375,17 @@ BScrollBar::SetSteps(float smallStep, float largeStep)
// TODO: test use of fractional values and make them work properly if they don't // TODO: test use of fractional values and make them work properly if they don't
} }
// GetSteps
void void
BScrollBar::GetSteps(float *smallStep, float *largeStep) const BScrollBar::GetSteps(float *smallStep, float *largeStep) const
{ {
if (smallStep != NULL) if (smallStep)
*smallStep = fSmallStep; *smallStep = fSmallStep;
if (largeStep) if (largeStep)
*largeStep = fLargeStep; *largeStep = fLargeStep;
} }
// SetTarget
void void
BScrollBar::SetTarget(BView *target) BScrollBar::SetTarget(BView *target)
{ {
@@ -420,7 +403,7 @@ BScrollBar::SetTarget(BView *target)
fTargetName = NULL; fTargetName = NULL;
} }
// SetTarget
void void
BScrollBar::SetTarget(const char *targetName) BScrollBar::SetTarget(const char *targetName)
{ {
@@ -435,21 +418,21 @@ BScrollBar::SetTarget(const char *targetName)
SetTarget(target); SetTarget(target);
} }
// Target
BView * BView *
BScrollBar::Target() const BScrollBar::Target() const
{ {
return fTarget; return fTarget;
} }
// Orientation
orientation orientation
BScrollBar::Orientation() const BScrollBar::Orientation() const
{ {
return fOrientation; return fOrientation;
} }
// MessageReceived
void void
BScrollBar::MessageReceived(BMessage *msg) BScrollBar::MessageReceived(BMessage *msg)
{ {
@@ -467,7 +450,7 @@ BScrollBar::MessageReceived(BMessage *msg)
} }
} }
// MouseDown
void void
BScrollBar::MouseDown(BPoint where) BScrollBar::MouseDown(BPoint where)
{ {
@@ -480,7 +463,7 @@ BScrollBar::MouseDown(BPoint where)
if (fPrivateData->fThumbFrame.Contains(where)) { if (fPrivateData->fThumbFrame.Contains(where)) {
fPrivateData->fButtonDown = THUMB; fPrivateData->fButtonDown = THUMB;
fPrivateData->fClickOffset = fPrivateData->fThumbFrame.LeftTop() - where; fPrivateData->fClickOffset = fPrivateData->fThumbFrame.LeftTop() - where;
// Invalidate(fPrivateData->fThumbFrame); Invalidate(fPrivateData->fThumbFrame);
return; return;
} }
@@ -536,11 +519,14 @@ BScrollBar::MouseDown(BPoint where)
void void
BScrollBar::MouseUp(BPoint pt) BScrollBar::MouseUp(BPoint pt)
{ {
if (fPrivateData->fButtonDown == THUMB)
Invalidate(fPrivateData->fThumbFrame);
else
Invalidate(_ButtonRectFor(fPrivateData->fButtonDown));
fPrivateData->fButtonDown = NOARROW; fPrivateData->fButtonDown = NOARROW;
fPrivateData->fExitRepeater = true; fPrivateData->fExitRepeater = true;
fPrivateData->fDoRepeat = false; fPrivateData->fDoRepeat = false;
Invalidate();
} }
// MouseMoved // MouseMoved
@@ -577,6 +563,13 @@ BScrollBar::MouseMoved(BPoint where, uint32 transit, const BMessage* message)
void void
BScrollBar::DetachedFromWindow() BScrollBar::DetachedFromWindow()
{ {
if (fTarget) {
if (fOrientation == B_VERTICAL)
fTarget->fVerScroller = NULL;
else
fTarget->fHorScroller = NULL;
}
fTarget = NULL; fTarget = NULL;
free(fTargetName); free(fTargetName);
fTargetName = NULL; fTargetName = NULL;
@@ -595,19 +588,21 @@ BScrollBar::Draw(BRect updateRect)
StrokeRect(bounds); StrokeRect(bounds);
bounds.InsetBy(1.0, 1.0); bounds.InsetBy(1.0, 1.0);
rgb_color light, light1, dark, dark1, dark2; rgb_color light, light1, dark, dark1, dark2, dark4;
if (fPrivateData->fEnabled) { if (fPrivateData->fEnabled) {
light = tint_color(normal, B_LIGHTEN_MAX_TINT); light = tint_color(normal, B_LIGHTEN_MAX_TINT);
light1 = tint_color(normal, B_LIGHTEN_1_TINT); light1 = tint_color(normal, B_LIGHTEN_1_TINT);
dark = tint_color(normal, B_DARKEN_3_TINT); dark = tint_color(normal, B_DARKEN_3_TINT);
dark1 = tint_color(normal, B_DARKEN_1_TINT); dark1 = tint_color(normal, B_DARKEN_1_TINT);
dark2 = tint_color(normal, B_DARKEN_2_TINT); dark2 = tint_color(normal, B_DARKEN_2_TINT);
dark4 = tint_color(normal, B_DARKEN_4_TINT);
} else { } else {
light = tint_color(normal, B_LIGHTEN_1_TINT); light = tint_color(normal, B_LIGHTEN_1_TINT);
light1 = normal; light1 = normal;
dark = tint_color(normal, B_DARKEN_2_TINT); dark = tint_color(normal, B_DARKEN_2_TINT);
dark1 = normal; dark1 = normal;
dark2 = tint_color(normal, B_DARKEN_1_TINT); dark2 = tint_color(normal, B_DARKEN_1_TINT);
dark4 = tint_color(normal, B_DARKEN_3_TINT);
} }
SetDrawingMode(B_OP_OVER); SetDrawingMode(B_OP_OVER);
@@ -618,16 +613,16 @@ BScrollBar::Draw(BRect updateRect)
if (fOrientation == B_HORIZONTAL) { if (fOrientation == B_HORIZONTAL) {
BRect buttonFrame(bounds.left, bounds.top, bounds.left + bounds.Height(), bounds.bottom); BRect buttonFrame(bounds.left, bounds.top, bounds.left + bounds.Height(), bounds.bottom);
_DrawArrowButton(ARROW_LEFT, buttonFrame, _DrawArrowButton(ARROW_LEFT, buttonFrame, updateRect,
fPrivateData->fButtonDown == ARROW1); fPrivateData->fButtonDown == ARROW1);
if (_DoubleArrows()) { if (_DoubleArrows()) {
buttonFrame.OffsetBy(bounds.Height() + 1, 0.0); buttonFrame.OffsetBy(bounds.Height() + 1, 0.0);
_DrawArrowButton(ARROW_RIGHT, buttonFrame, _DrawArrowButton(ARROW_RIGHT, buttonFrame, updateRect,
fPrivateData->fButtonDown == ARROW2); fPrivateData->fButtonDown == ARROW2);
buttonFrame.OffsetTo(bounds.right - ((bounds.Height() * 2) + 1), bounds.top); buttonFrame.OffsetTo(bounds.right - ((bounds.Height() * 2) + 1), bounds.top);
_DrawArrowButton(ARROW_LEFT, buttonFrame, _DrawArrowButton(ARROW_LEFT, buttonFrame, updateRect,
fPrivateData->fButtonDown == ARROW3); fPrivateData->fButtonDown == ARROW3);
thumbBG.left += bounds.Height() * 2 + 2; thumbBG.left += bounds.Height() * 2 + 2;
@@ -638,21 +633,21 @@ BScrollBar::Draw(BRect updateRect)
} }
buttonFrame.OffsetTo(bounds.right - bounds.Height(), bounds.top); buttonFrame.OffsetTo(bounds.right - bounds.Height(), bounds.top);
_DrawArrowButton(ARROW_RIGHT, buttonFrame, _DrawArrowButton(ARROW_RIGHT, buttonFrame, updateRect,
fPrivateData->fButtonDown == ARROW4); fPrivateData->fButtonDown == ARROW4);
} else { } else {
BRect buttonFrame(bounds.left, bounds.top, bounds.right, bounds.top + bounds.Width()); BRect buttonFrame(bounds.left, bounds.top, bounds.right, bounds.top + bounds.Width());
_DrawArrowButton(ARROW_UP, buttonFrame, _DrawArrowButton(ARROW_UP, buttonFrame, updateRect,
fPrivateData->fButtonDown == ARROW1); fPrivateData->fButtonDown == ARROW1);
if (_DoubleArrows()) { if (_DoubleArrows()) {
buttonFrame.OffsetBy(0.0, bounds.Width() + 1); buttonFrame.OffsetBy(0.0, bounds.Width() + 1);
_DrawArrowButton(ARROW_DOWN, buttonFrame, _DrawArrowButton(ARROW_DOWN, buttonFrame, updateRect,
fPrivateData->fButtonDown == ARROW2); fPrivateData->fButtonDown == ARROW2);
buttonFrame.OffsetTo(bounds.left, bounds.bottom - ((bounds.Width() * 2) + 1)); buttonFrame.OffsetTo(bounds.left, bounds.bottom - ((bounds.Width() * 2) + 1));
_DrawArrowButton(ARROW_UP, buttonFrame, _DrawArrowButton(ARROW_UP, buttonFrame, updateRect,
fPrivateData->fButtonDown == ARROW3); fPrivateData->fButtonDown == ARROW3);
thumbBG.top += bounds.Width() * 2 + 2; thumbBG.top += bounds.Width() * 2 + 2;
@@ -663,91 +658,142 @@ BScrollBar::Draw(BRect updateRect)
} }
buttonFrame.OffsetTo(bounds.left, bounds.bottom - bounds.Width()); buttonFrame.OffsetTo(bounds.left, bounds.bottom - bounds.Width());
_DrawArrowButton(ARROW_DOWN, buttonFrame, _DrawArrowButton(ARROW_DOWN, buttonFrame, updateRect,
fPrivateData->fButtonDown == ARROW4); fPrivateData->fButtonDown == ARROW4);
} }
SetDrawingMode(B_OP_COPY); SetDrawingMode(B_OP_COPY);
// background for thumb area // background for thumb area
BRect rect(fPrivateData->fThumbFrame);
// frame // frame
BeginLineArray(4);
if (fOrientation == B_HORIZONTAL) { if (fOrientation == B_HORIZONTAL) {
AddLine(BPoint(thumbBG.left, thumbBG.bottom), int32 totalLines = 0;
BPoint(thumbBG.left, thumbBG.top), dark); if (rect.left > thumbBG.left)
AddLine(BPoint(thumbBG.left + 1, thumbBG.top), totalLines += 1;
BPoint(thumbBG.right - 1, thumbBG.top), dark2); if (rect.left > thumbBG.left + 1)
AddLine(BPoint(thumbBG.right, thumbBG.top), totalLines += 3;
BPoint(thumbBG.right, thumbBG.bottom), dark); if (rect.right < thumbBG.right - 1)
AddLine(BPoint(thumbBG.right - 1, thumbBG.bottom), totalLines += 3;
BPoint(thumbBG.left + 1, thumbBG.bottom), normal); if (rect.right < thumbBG.right)
totalLines += 1;
if (totalLines > 0) {
BeginLineArray(totalLines);
if (rect.left > thumbBG.left) {
AddLine(BPoint(thumbBG.left, thumbBG.bottom),
BPoint(thumbBG.left, thumbBG.top),
rect.left > thumbBG.left + 1 ? dark4 : dark);
}
if (rect.left > thumbBG.left + 1) {
AddLine(BPoint(thumbBG.left + 1, thumbBG.top + 1),
BPoint(thumbBG.left + 1, thumbBG.bottom), dark2);
AddLine(BPoint(thumbBG.left + 1, thumbBG.top),
BPoint(rect.left - 1, thumbBG.top), dark2);
AddLine(BPoint(rect.left - 1, thumbBG.bottom),
BPoint(thumbBG.left + 2, thumbBG.bottom), normal);
}
if (rect.right < thumbBG.right - 1) {
AddLine(BPoint(rect.right + 2, thumbBG.top + 1),
BPoint(rect.right + 2, thumbBG.bottom), dark2);
AddLine(BPoint(rect.right + 1, thumbBG.top),
BPoint(thumbBG.right, thumbBG.top), dark2);
AddLine(BPoint(thumbBG.right - 1, thumbBG.bottom),
BPoint(rect.right + 3, thumbBG.bottom), normal);
}
if (rect.right < thumbBG.right) {
AddLine(BPoint(thumbBG.right, thumbBG.top),
BPoint(thumbBG.right, thumbBG.bottom), dark);
}
EndLineArray();
}
} else { } else {
AddLine(BPoint(thumbBG.left, thumbBG.bottom - 1), int32 totalLines = 0;
BPoint(thumbBG.left, thumbBG.top - 1), dark2); if (rect.top > thumbBG.top)
AddLine(BPoint(thumbBG.left, thumbBG.top), totalLines += 1;
BPoint(thumbBG.right, thumbBG.top), dark); if (rect.top > thumbBG.top + 1)
AddLine(BPoint(thumbBG.right, thumbBG.top + 1), totalLines += 3;
BPoint(thumbBG.right, thumbBG.bottom - 1), normal); if (rect.bottom < thumbBG.bottom - 1)
AddLine(BPoint(thumbBG.right, thumbBG.bottom), totalLines += 3;
BPoint(thumbBG.left, thumbBG.bottom), dark); if (rect.bottom < thumbBG.bottom)
totalLines += 1;
if (totalLines > 0) {
BeginLineArray(totalLines);
if (rect.top > thumbBG.top) {
AddLine(BPoint(thumbBG.left, thumbBG.top),
BPoint(thumbBG.right, thumbBG.top),
rect.top > thumbBG.top + 1 ? dark4 : dark);
}
if (rect.top > thumbBG.top + 1) {
AddLine(BPoint(thumbBG.left + 1, thumbBG.top + 1),
BPoint(thumbBG.right, thumbBG.top + 1), dark2);
AddLine(BPoint(thumbBG.left, rect.top - 1),
BPoint(thumbBG.left, thumbBG.top + 1), dark2);
AddLine(BPoint(thumbBG.right, rect.top - 1),
BPoint(thumbBG.right, thumbBG.top + 2), normal);
}
if (rect.bottom < thumbBG.bottom - 1) {
AddLine(BPoint(thumbBG.left + 1, rect.bottom + 2),
BPoint(thumbBG.right, rect.bottom + 2), dark2);
AddLine(BPoint(thumbBG.left, rect.bottom + 1),
BPoint(thumbBG.left, thumbBG.bottom - 1), dark2);
AddLine(BPoint(thumbBG.right, rect.bottom + 3),
BPoint(thumbBG.right, thumbBG.bottom - 1), normal);
}
if (rect.bottom < thumbBG.bottom) {
AddLine(BPoint(thumbBG.left, thumbBG.bottom),
BPoint(thumbBG.right, thumbBG.bottom), dark);
}
EndLineArray();
}
} }
EndLineArray();
thumbBG.InsetBy(1.0, 1.0); thumbBG.InsetBy(1.0, 1.0);
SetHighColor(dark1); SetHighColor(dark1);
// Draw scroll thumb // Draw scroll thumb
if (fPrivateData->fEnabled) { if (fPrivateData->fEnabled) {
// fill and additional dark lines // fill and additional dark lines
BRect rect(fPrivateData->fThumbFrame);
if (fOrientation == B_HORIZONTAL) { if (fOrientation == B_HORIZONTAL) {
BRect leftOfThumb(thumbBG.left, thumbBG.top, rect.left - 1, thumbBG.bottom); BRect leftOfThumb(thumbBG.left + 1, thumbBG.top, rect.left - 1, thumbBG.bottom);
if (leftOfThumb.IsValid()) if (leftOfThumb.IsValid())
FillRect(leftOfThumb); FillRect(leftOfThumb);
BRect rightOfThumb(rect.right + 1, thumbBG.top, thumbBG.right, thumbBG.bottom); BRect rightOfThumb(rect.right + 3, thumbBG.top, thumbBG.right, thumbBG.bottom);
if (rightOfThumb.IsValid()) if (rightOfThumb.IsValid())
FillRect(rightOfThumb); FillRect(rightOfThumb);
// dark lines before and after thumb
if (rect.left > thumbBG.left) { if (rect.left > thumbBG.left) {
// dark line before thumb
SetHighColor(dark); SetHighColor(dark);
StrokeLine(BPoint(rect.left - 1, rect.top), BPoint(rect.left - 1, rect.bottom)); StrokeLine(BPoint(rect.left - 1, rect.top), BPoint(rect.left - 1, rect.bottom));
/* if (rect.left > thumbBG.left + 1) {
// shadow line behind left arrows
SetHighColor(dark2);
StrokeLine(BPoint(thumbBG.left + 1, thumbBG.top), BPoint(thumbBG.left + 1, thumbBG.bottom));
}*/
} }
if (rect.right < thumbBG.right) { if (rect.right < thumbBG.right) {
// dark line behind thumb SetHighColor(dark4);
SetHighColor(dark);
StrokeLine(BPoint(rect.right + 1, rect.top), BPoint(rect.right + 1, rect.bottom)); StrokeLine(BPoint(rect.right + 1, rect.top), BPoint(rect.right + 1, rect.bottom));
/* if (rect.right < thumbBG.right - 1) {
// shadow line behind thumb
SetHighColor(dark2);
StrokeLine(BPoint(rect.right + 2, rect.top), BPoint(rect.right + 2, rect.bottom));
}*/
} }
} else { } else {
BRect topOfThumb(thumbBG.left, thumbBG.top, thumbBG.right, rect.top - 1); BRect topOfThumb(thumbBG.left, thumbBG.top + 1, thumbBG.right, rect.top - 1);
if (topOfThumb.IsValid()) if (topOfThumb.IsValid())
FillRect(topOfThumb); FillRect(topOfThumb);
BRect bottomOfThumb(thumbBG.left, rect.bottom + 1, thumbBG.right, thumbBG.bottom); BRect bottomOfThumb(thumbBG.left, rect.bottom + 3, thumbBG.right, thumbBG.bottom);
if (bottomOfThumb.IsValid()) if (bottomOfThumb.IsValid())
FillRect(bottomOfThumb); FillRect(bottomOfThumb);
// dark lines before and after thumb // dark lines before and after thumb
SetHighColor(dark); if (rect.top > thumbBG.top) {
if (rect.top > thumbBG.top) SetHighColor(dark);
StrokeLine(BPoint(rect.left, rect.top - 1), BPoint(rect.right, rect.top - 1)); StrokeLine(BPoint(rect.left, rect.top - 1), BPoint(rect.right, rect.top - 1));
if (rect.bottom < thumbBG.bottom) }
if (rect.bottom < thumbBG.bottom) {
SetHighColor(dark4);
StrokeLine(BPoint(rect.left, rect.bottom + 1), BPoint(rect.right, rect.bottom + 1)); StrokeLine(BPoint(rect.left, rect.bottom + 1), BPoint(rect.right, rect.bottom + 1));
}
} }
BeginLineArray(4); BeginLineArray(4);
@@ -764,7 +810,7 @@ BScrollBar::Draw(BRect updateRect)
// fill // fill
rect.InsetBy(1.0, 1.0); rect.InsetBy(1.0, 1.0);
/*if (fPrivateData->fButtonDown == THUMB) /*if (fPrivateData->fButtonDown == THUMB)
SetHighColor(tint_color(normal, B_DARKEN_1_TINT)); SetHighColor(tint_color(normal, (B_NO_TINT + B_DARKEN_1_TINT) / 2));
else*/ else*/
SetHighColor(normal); SetHighColor(normal);
@@ -776,22 +822,21 @@ BScrollBar::Draw(BRect updateRect)
} }
} }
// FrameMoved
void void
BScrollBar::FrameMoved(BPoint new_position) BScrollBar::FrameMoved(BPoint new_position)
{ {
} }
// FrameResized
void void
BScrollBar::FrameResized(float new_width, float new_height) BScrollBar::FrameResized(float new_width, float new_height)
{ {
_UpdateThumbFrame(); _UpdateThumbFrame();
Invalidate();
} }
// ResolveSpecifier
BHandler * BHandler*
BScrollBar::ResolveSpecifier(BMessage *msg,int32 index, BScrollBar::ResolveSpecifier(BMessage *msg,int32 index,
BMessage *specifier,int32 form,const char *property) BMessage *specifier,int32 form,const char *property)
{ {
@@ -799,24 +844,27 @@ BScrollBar::ResolveSpecifier(BMessage *msg,int32 index,
return NULL; return NULL;
} }
// ResizeToPreferred
void void
BScrollBar::ResizeToPreferred() BScrollBar::ResizeToPreferred()
{ {
// TODO: Implement // TODO: Implement
} }
// GetPreferredSize
void void
BScrollBar::GetPreferredSize(float *width, float *height) BScrollBar::GetPreferredSize(float *width, float *height)
{ {
if (fOrientation == B_VERTICAL) if (fOrientation == B_VERTICAL) {
*width = B_V_SCROLL_BAR_WIDTH; *width = B_V_SCROLL_BAR_WIDTH;
else if (fOrientation == B_HORIZONTAL) *height = Bounds().Height();
} else if (fOrientation == B_HORIZONTAL) {
*width = Bounds().Width();
*height = B_H_SCROLL_BAR_HEIGHT; *height = B_H_SCROLL_BAR_HEIGHT;
}
} }
// MakeFocus
void void
BScrollBar::MakeFocus(bool state) BScrollBar::MakeFocus(bool state)
{ {
@@ -825,26 +873,26 @@ BScrollBar::MakeFocus(bool state)
fTarget->MakeFocus(state); fTarget->MakeFocus(state);
} }
// AllAttached
void void
BScrollBar::AllAttached() BScrollBar::AllAttached()
{ {
} }
// AllDetached
void void
BScrollBar::AllDetached() BScrollBar::AllDetached()
{ {
} }
// GetSupportedSuites
status_t status_t
BScrollBar::GetSupportedSuites(BMessage *data) BScrollBar::GetSupportedSuites(BMessage *data)
{ {
return B_ERROR; return B_ERROR;
} }
// Perform
status_t status_t
BScrollBar::Perform(perform_code d, void *arg) BScrollBar::Perform(perform_code d, void *arg)
{ {
@@ -857,7 +905,7 @@ void BScrollBar::_ReservedScrollBar2() {}
void BScrollBar::_ReservedScrollBar3() {} void BScrollBar::_ReservedScrollBar3() {}
void BScrollBar::_ReservedScrollBar4() {} void BScrollBar::_ReservedScrollBar4() {}
// operator=
BScrollBar & BScrollBar &
BScrollBar::operator=(const BScrollBar &) BScrollBar::operator=(const BScrollBar &)
{ {
@@ -908,19 +956,24 @@ BScrollBar::_UpdateThumbFrame()
// subtract the size of two buttons // subtract the size of two buttons
maxSize -= buttonSize * 2; maxSize -= buttonSize * 2;
} }
// visual adjustments (room for darker line between thumb and buttons)
maxSize--;
float thumbSize = minSize; float thumbSize = minSize;
if (fPrivateData->fScrollBarInfo.proportional) if (fPrivateData->fScrollBarInfo.proportional)
thumbSize += (maxSize - minSize) * fProportion; thumbSize += (maxSize - minSize) * fProportion;
thumbSize = floorf(thumbSize + 0.5);
// the thumb can be scrolled within the remaining area "maxSize - thumbSize" // the thumb can be scrolled within the remaining area "maxSize - thumbSize"
float offset = floorf(((fValue - fMin) / (fMax - fMin + 1.0)) * (maxSize - thumbSize) + 0.5); float offset = floorf(((fValue - fMin) / (fMax - fMin + 1.0)) * (maxSize - thumbSize));
if (_DoubleArrows()) { if (_DoubleArrows()) {
offset += buttonSize * 2; offset += buttonSize * 2;
} else { } else {
offset += buttonSize; offset += buttonSize;
} }
// visual adjustments (room for darker line between thumb and buttons)
offset++;
if (fOrientation == B_VERTICAL) { if (fOrientation == B_VERTICAL) {
fPrivateData->fThumbFrame.bottom = fPrivateData->fThumbFrame.top + thumbSize; fPrivateData->fThumbFrame.bottom = fPrivateData->fThumbFrame.top + thumbSize;
@@ -934,9 +987,9 @@ BScrollBar::_UpdateThumbFrame()
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(-1.0, 0.0); invalid.InsetBy(-2.0, 0.0);
else else
invalid.InsetBy(0.0, -1.0); invalid.InsetBy(0.0, -2.0);
Invalidate(invalid); Invalidate(invalid);
} }
} }
@@ -976,6 +1029,9 @@ BScrollBar::_ValueFor(BPoint where) const
// convert point to inside of area between buttons // convert point to inside of area between buttons
offset -= buttonSize; offset -= buttonSize;
} }
// visual adjustments (room for darker line between thumb and buttons)
maxSize--;
offset++;
float value = fMin + (offset / (maxSize - thumbSize) * (fMax - fMin + 1.0)); float value = fMin + (offset / (maxSize - thumbSize) * (fMax - fMin + 1.0));
if (value >= 0.0) if (value >= 0.0)
@@ -1152,18 +1208,19 @@ control_scrollbar(scroll_bar_info *info, BScrollBar *bar)
return B_OK; return B_OK;
} }
// _DrawArrowButton
void void
BScrollBar::_DrawArrowButton(int32 direction, BRect r, bool down) BScrollBar::_DrawArrowButton(int32 direction, BRect r, const BRect& updateRect, bool down)
{ {
// Another hack for code size if (!updateRect.Intersects(r))
return;
rgb_color c = ui_color(B_PANEL_BACKGROUND_COLOR); rgb_color c = ui_color(B_PANEL_BACKGROUND_COLOR);
rgb_color light, dark, normal,arrow,arrow2; rgb_color light, dark, normal,arrow,arrow2;
if (down && fPrivateData->fDoRepeat) { if (down && fPrivateData->fDoRepeat) {
light = tint_color(c, (B_DARKEN_1_TINT + B_DARKEN_2_TINT) / 2.0); light = tint_color(c, (B_DARKEN_1_TINT + B_DARKEN_2_TINT) / 2.0);
arrow2 = dark = tint_color(c, B_LIGHTEN_MAX_TINT); arrow2 = dark = tint_color(c, B_LIGHTEN_1_TINT);
normal = tint_color(c, B_DARKEN_1_TINT); normal = tint_color(c, B_DARKEN_1_TINT);
arrow = tint_color(c, B_DARKEN_MAX_TINT); arrow = tint_color(c, B_DARKEN_MAX_TINT);
@@ -1192,36 +1249,29 @@ BScrollBar::_DrawArrowButton(int32 direction, BRect r, bool down)
} }
BPoint tri1, tri2, tri3; BPoint tri1, tri2, tri3;
r.InsetBy(4, 4);
switch (direction) { switch (direction) {
case ARROW_LEFT: case ARROW_LEFT:
{ tri1.Set(r.right, r.top);
tri1.Set(r.left + 3, (r.top + r.bottom) /2 ); tri2.Set(r.left + 1, (r.top + r.bottom + 1) /2 );
tri2.Set(r.right - 3, r.top + 3); tri3.Set(r.right, r.bottom + 1);
tri3.Set(r.right - 3, r.bottom - 3);
break; break;
}
case ARROW_RIGHT: case ARROW_RIGHT:
{ tri1.Set(r.left, r.bottom + 1);
tri1.Set(r.left + 3, r.bottom - 3); tri2.Set(r.right - 1, (r.top + r.bottom + 1) / 2);
tri2.Set(r.left + 3, r.top + 3); tri3.Set(r.left, r.top);
tri3.Set(r.right-3, (r.top + r.bottom) / 2);
break; break;
}
case ARROW_UP: case ARROW_UP:
{ tri1.Set(r.left, r.bottom);
tri1.Set(r.left + 3, r.bottom - 3); tri2.Set((r.left + r.right + 1) / 2, r.top + 1);
tri2.Set((r.left + r.right) / 2, r.top + 3); tri3.Set(r.right + 1, r.bottom);
tri3.Set(r.right - 3, r.bottom - 3);
break; break;
}
default: default:
{ tri1.Set(r.left, r.top);
tri1.Set(r.left + 3, r.top + 3); tri2.Set((r.left + r.right + 1) / 2, r.bottom - 1);
tri2.Set(r.right - 3, r.top + 3); tri3.Set(r.right + 1, r.top);
tri3.Set((r.left + r.right) / 2, r.bottom - 3);
break; break;
}
} }
// offset triangle if down // offset triangle if down
if (down && fPrivateData->fDoRepeat) { if (down && fPrivateData->fDoRepeat) {
@@ -1231,23 +1281,24 @@ BScrollBar::_DrawArrowButton(int32 direction, BRect r, bool down)
tri3 = tri3 + offset; tri3 = tri3 + offset;
} }
r.InsetBy(1, 1); r.InsetBy(-3, -3);
SetHighColor(normal); SetHighColor(normal);
FillRect(r); FillRect(r);
BShape arrowShape;
arrowShape.MoveTo(tri1);
arrowShape.LineTo(tri2);
arrowShape.LineTo(tri3);
SetHighColor(arrow); SetHighColor(arrow);
FillTriangle(tri1, tri2, tri3); SetPenSize(2.0);
StrokeShape(&arrowShape);
/* SetHighColor(dark); SetPenSize(1.0);
StrokeLine(tri2, tri3);
StrokeLine(tri1, tri3);
SetHighColor(arrow2);
StrokeLine(tri1, tri2);*/
r.InsetBy(-1, -1); r.InsetBy(-1, -1);
BeginLineArray(4); BeginLineArray(4);
if (direction == ARROW_LEFT || direction == ARROW_RIGHT) { if (direction == ARROW_LEFT || direction == ARROW_RIGHT) {
// horizontal
AddLine(BPoint(r.left, r.bottom), AddLine(BPoint(r.left, r.bottom),
BPoint(r.left, r.top), light); BPoint(r.left, r.top), light);
AddLine(BPoint(r.left + 1, r.top), AddLine(BPoint(r.left + 1, r.top),
@@ -1257,6 +1308,7 @@ BScrollBar::_DrawArrowButton(int32 direction, BRect r, bool down)
AddLine(BPoint(r.right - 1, r.bottom), AddLine(BPoint(r.right - 1, r.bottom),
BPoint(r.left + 1, r.bottom), dark); BPoint(r.left + 1, r.bottom), dark);
} else { } else {
// vertical
AddLine(BPoint(r.left, r.bottom - 1), AddLine(BPoint(r.left, r.bottom - 1),
BPoint(r.left, r.top), light); BPoint(r.left, r.top), light);
AddLine(BPoint(r.left + 1, r.top), AddLine(BPoint(r.left + 1, r.top),