BScrollView: Automatically update the scrollbar proportions in layout mode.
Since we know what size the target view is / wants to be, we can automatically set the range, steps, and proportion trivially. In non-layout mode, we retain the old behavior. Applications or views that need custom scrolling behavior almost certainly will be using BScrollBars directly and not this, so this should not be "wasted computation" in pretty much any case. Greatly improves the appearance and UX of the default case of a layouted view inside a BScrollView. Change-Id: Ia6ff6ee14df96799c579e15d274fd4c849675577 Reviewed-on: https://review.haiku-os.org/c/892 Reviewed-by: waddlesplash <waddlesplash@gmail.com>
This commit is contained in:
parent
2502d45aca
commit
5b0e5c0ac6
|
@ -1,13 +1,13 @@
|
|||
/*
|
||||
* Copyright 2014 Haiku, Inc. All rights reserved.
|
||||
* Copyright 2014-2019, Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* John Scipione, jscipione@gmail.com
|
||||
*
|
||||
* Corresponds to:
|
||||
* headers/os/interface/ScrollView.h hrev47312
|
||||
* src/kits/interface/ScrollView.cpp hrev47312
|
||||
* headers/os/interface/ScrollView.h hrev52792
|
||||
* src/kits/interface/ScrollView.cpp hrev52792
|
||||
*/
|
||||
|
||||
|
||||
|
@ -216,7 +216,8 @@
|
|||
\fn void BScrollView::FrameResized(float newWidth, float newHeight)
|
||||
\brief Hook method called when the scroll view is resized.
|
||||
|
||||
\copydetails BView::FrameResized()
|
||||
If the scroll view is part of a layout, the default implementation will
|
||||
re-proportion the attached scrollbars relative to the new size.
|
||||
*/
|
||||
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ BScrollView::BScrollView(const char* name, BView* target, uint32 resizingMode,
|
|||
BScrollView::BScrollView(const char* name, BView* target, uint32 flags,
|
||||
bool horizontal, bool vertical, border_style border)
|
||||
:
|
||||
BView(name, _ModifyFlags(flags, border)),
|
||||
BView(name, _ModifyFlags(flags | B_SUPPORTS_LAYOUT, border)),
|
||||
fTarget(target),
|
||||
fBorder(border)
|
||||
{
|
||||
|
@ -271,10 +271,37 @@ BScrollView::FrameResized(float newWidth, float newHeight)
|
|||
{
|
||||
BView::FrameResized(newWidth, newHeight);
|
||||
|
||||
const BRect bounds = Bounds();
|
||||
|
||||
if ((Flags() & B_SUPPORTS_LAYOUT) != 0) {
|
||||
BSize size = fTarget != NULL ? fTarget->PreferredSize() : BSize();
|
||||
if (fHorizontalScrollBar != NULL) {
|
||||
float delta = size.Width() - bounds.Width(),
|
||||
proportion = bounds.Width() / size.Width();
|
||||
if (delta < 0)
|
||||
delta = 0;
|
||||
|
||||
fHorizontalScrollBar->SetRange(0, delta);
|
||||
fHorizontalScrollBar->SetSteps(be_plain_font->Size() * 1.33,
|
||||
bounds.Width());
|
||||
fHorizontalScrollBar->SetProportion(proportion);
|
||||
}
|
||||
if (fVerticalScrollBar != NULL) {
|
||||
float delta = size.Height() - bounds.Height(),
|
||||
proportion = bounds.Height() / size.Height();
|
||||
if (delta < 0)
|
||||
delta = 0;
|
||||
|
||||
fVerticalScrollBar->SetRange(0, delta);
|
||||
fVerticalScrollBar->SetSteps(be_plain_font->Size() * 1.33,
|
||||
bounds.Height());
|
||||
fVerticalScrollBar->SetProportion(proportion);
|
||||
}
|
||||
}
|
||||
|
||||
if (fBorder == B_NO_BORDER)
|
||||
return;
|
||||
|
||||
BRect bounds = Bounds();
|
||||
float border = _BorderSize() - 1;
|
||||
|
||||
if (fHorizontalScrollBar != NULL && fVerticalScrollBar != NULL) {
|
||||
|
@ -443,7 +470,7 @@ BScrollView::SetBorder(border_style border)
|
|||
if (fBorder == border)
|
||||
return;
|
||||
|
||||
if (Flags() & B_SUPPORTS_LAYOUT) {
|
||||
if ((Flags() & B_SUPPORTS_LAYOUT) != 0) {
|
||||
fBorder = border;
|
||||
SetFlags(_ModifyFlags(Flags(), border));
|
||||
|
||||
|
@ -928,12 +955,17 @@ BScrollView::_BorderSize(border_style border)
|
|||
/*static*/ int32
|
||||
BScrollView::_ModifyFlags(int32 flags, border_style border)
|
||||
{
|
||||
// We either need B_FULL_UPDATE_ON_RESIZE or
|
||||
// B_FRAME_EVENTS if we have to draw a border
|
||||
if (border != B_NO_BORDER)
|
||||
return flags | B_WILL_DRAW | (flags & B_FULL_UPDATE_ON_RESIZE ? 0 : B_FRAME_EVENTS);
|
||||
if ((flags & B_SUPPORTS_LAYOUT) != 0)
|
||||
flags |= B_FRAME_EVENTS;
|
||||
|
||||
return flags & ~(B_WILL_DRAW | B_FRAME_EVENTS | B_FULL_UPDATE_ON_RESIZE);
|
||||
// We either need B_FULL_UPDATE_ON_RESIZE or B_FRAME_EVENTS if we have
|
||||
// to draw a border.
|
||||
if (border != B_NO_BORDER) {
|
||||
flags |= B_WILL_DRAW | ((flags & B_FULL_UPDATE_ON_RESIZE) != 0 ?
|
||||
0 : B_FRAME_EVENTS);
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue