For the Mac port of views, we need to draw the corner part to connect the

vertical and horizontal tracks together.
Update ScrollView to allow the native theme to paint the corner square when
both horizontal and vertical scrollbars are showing.
This is done by installing a view at the corner and have it call
NativeTheme::Paint(..).

BUG=401346

Review URL: https://codereview.chromium.org/462373002

Cr-Commit-Position: refs/heads/master@{#289483}
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@289483 0039d316-1c4b-4281-b951-d872f2087c98
parent d4423632
...@@ -519,11 +519,6 @@ void NativeThemeBase::PaintScrollbarThumb(SkCanvas* canvas, ...@@ -519,11 +519,6 @@ void NativeThemeBase::PaintScrollbarThumb(SkCanvas* canvas,
void NativeThemeBase::PaintScrollbarCorner(SkCanvas* canvas, void NativeThemeBase::PaintScrollbarCorner(SkCanvas* canvas,
State state, State state,
const gfx::Rect& rect) const { const gfx::Rect& rect) const {
SkPaint paint;
paint.setColor(SK_ColorWHITE);
paint.setStyle(SkPaint::kFill_Style);
paint.setXfermodeMode(SkXfermode::kSrc_Mode);
canvas->drawIRect(RectToSkIRect(rect), paint);
} }
void NativeThemeBase::PaintCheckbox(SkCanvas* canvas, void NativeThemeBase::PaintCheckbox(SkCanvas* canvas,
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "base/logging.h" #include "base/logging.h"
#include "ui/events/event.h" #include "ui/events/event.h"
#include "ui/gfx/canvas.h"
#include "ui/native_theme/native_theme.h" #include "ui/native_theme/native_theme.h"
#include "ui/views/border.h" #include "ui/views/border.h"
#include "ui/views/controls/scrollbar/native_scroll_bar.h" #include "ui/views/controls/scrollbar/native_scroll_bar.h"
...@@ -33,6 +34,23 @@ class ScrollViewWithBorder : public views::ScrollView { ...@@ -33,6 +34,23 @@ class ScrollViewWithBorder : public views::ScrollView {
DISALLOW_COPY_AND_ASSIGN(ScrollViewWithBorder); DISALLOW_COPY_AND_ASSIGN(ScrollViewWithBorder);
}; };
class ScrollCornerView : public views::View {
public:
ScrollCornerView() {}
virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
ui::NativeTheme::ExtraParams ignored;
GetNativeTheme()->Paint(canvas->sk_canvas(),
ui::NativeTheme::kScrollbarCorner,
ui::NativeTheme::kNormal,
GetLocalBounds(),
ignored);
}
private:
DISALLOW_COPY_AND_ASSIGN(ScrollCornerView);
};
// Returns the position for the view so that it isn't scrolled off the visible // Returns the position for the view so that it isn't scrolled off the visible
// region. // region.
int CheckScrollBounds(int viewport_size, int content_size, int current_pos) { int CheckScrollBounds(int viewport_size, int content_size, int current_pos) {
...@@ -109,7 +127,7 @@ ScrollView::ScrollView() ...@@ -109,7 +127,7 @@ ScrollView::ScrollView()
header_viewport_(new Viewport()), header_viewport_(new Viewport()),
horiz_sb_(new NativeScrollBar(true)), horiz_sb_(new NativeScrollBar(true)),
vert_sb_(new NativeScrollBar(false)), vert_sb_(new NativeScrollBar(false)),
resize_corner_(NULL), corner_view_(new ScrollCornerView()),
min_height_(-1), min_height_(-1),
max_height_(-1), max_height_(-1),
hide_horizontal_scrollbar_(false) { hide_horizontal_scrollbar_(false) {
...@@ -124,8 +142,7 @@ ScrollView::ScrollView() ...@@ -124,8 +142,7 @@ ScrollView::ScrollView()
horiz_sb_->set_controller(this); horiz_sb_->set_controller(this);
vert_sb_->SetVisible(false); vert_sb_->SetVisible(false);
vert_sb_->set_controller(this); vert_sb_->set_controller(this);
if (resize_corner_) corner_view_->SetVisible(false);
resize_corner_->SetVisible(false);
} }
ScrollView::~ScrollView() { ScrollView::~ScrollView() {
...@@ -133,9 +150,7 @@ ScrollView::~ScrollView() { ...@@ -133,9 +150,7 @@ ScrollView::~ScrollView() {
// deleted. // deleted.
delete horiz_sb_; delete horiz_sb_;
delete vert_sb_; delete vert_sb_;
delete corner_view_;
if (resize_corner_ && !resize_corner_->parent())
delete resize_corner_;
} }
// static // static
...@@ -268,12 +283,11 @@ void ScrollView::Layout() { ...@@ -268,12 +283,11 @@ void ScrollView::Layout() {
&horiz_sb_required, &horiz_sb_required,
&vert_sb_required); &vert_sb_required);
} }
bool resize_corner_required = resize_corner_ && horiz_sb_required && bool corner_view_required = horiz_sb_required && vert_sb_required;
vert_sb_required;
// Take action. // Take action.
SetControlVisibility(horiz_sb_, horiz_sb_required); SetControlVisibility(horiz_sb_, horiz_sb_required);
SetControlVisibility(vert_sb_, vert_sb_required); SetControlVisibility(vert_sb_, vert_sb_required);
SetControlVisibility(resize_corner_, resize_corner_required); SetControlVisibility(corner_view_, corner_view_required);
// Non-default. // Non-default.
if (horiz_sb_required) { if (horiz_sb_required) {
...@@ -301,12 +315,12 @@ void ScrollView::Layout() { ...@@ -301,12 +315,12 @@ void ScrollView::Layout() {
vert_sb_width + width_offset, vert_sb_width + width_offset,
viewport_bounds.bottom()); viewport_bounds.bottom());
} }
if (resize_corner_required) { if (corner_view_required) {
// Show the resize corner. // Show the resize corner.
resize_corner_->SetBounds(viewport_bounds.right(), corner_view_->SetBounds(viewport_bounds.right(),
viewport_bounds.bottom(), viewport_bounds.bottom(),
vert_sb_width, vert_sb_width,
horiz_sb_height); horiz_sb_height);
} }
// Update to the real client size with the visible scrollbars. // Update to the real client size with the visible scrollbars.
......
...@@ -92,6 +92,7 @@ class VIEWS_EXPORT ScrollView : public View, public ScrollBarController { ...@@ -92,6 +92,7 @@ class VIEWS_EXPORT ScrollView : public View, public ScrollBarController {
bool is_positive) OVERRIDE; bool is_positive) OVERRIDE;
private: private:
FRIEND_TEST_ALL_PREFIXES(ScrollViewTest, CornerViewVisibility);
class Viewport; class Viewport;
// Used internally by SetHeader() and SetContents() to reset the view. Sets // Used internally by SetHeader() and SetContents() to reset the view. Sets
...@@ -111,7 +112,7 @@ class VIEWS_EXPORT ScrollView : public View, public ScrollBarController { ...@@ -111,7 +112,7 @@ class VIEWS_EXPORT ScrollView : public View, public ScrollBarController {
bool* horiz_is_shown, bool* horiz_is_shown,
bool* vert_is_shown) const; bool* vert_is_shown) const;
// Shows or hides the scrollbar/resize_corner based on the value of // Shows or hides the scrollbar/corner_view based on the value of
// |should_show|. // |should_show|.
void SetControlVisibility(View* control, bool should_show); void SetControlVisibility(View* control, bool should_show);
...@@ -134,8 +135,8 @@ class VIEWS_EXPORT ScrollView : public View, public ScrollBarController { ...@@ -134,8 +135,8 @@ class VIEWS_EXPORT ScrollView : public View, public ScrollBarController {
// Vertical scrollbar. // Vertical scrollbar.
ScrollBar* vert_sb_; ScrollBar* vert_sb_;
// Resize corner. // Corner view.
View* resize_corner_; View* corner_view_;
// The min and max height for the bounded scroll view. These are negative // The min and max height for the bounded scroll view. These are negative
// values if the view is not bounded. // values if the view is not bounded.
......
...@@ -334,4 +334,45 @@ TEST(ScrollViewTest, ClipHeightToScrollbarUsesWidth) { ...@@ -334,4 +334,45 @@ TEST(ScrollViewTest, ClipHeightToScrollbarUsesWidth) {
EXPECT_EQ(gfx::Size(kWidth, kMaxHeight), scroll_view.size()); EXPECT_EQ(gfx::Size(kWidth, kMaxHeight), scroll_view.size());
} }
TEST(ScrollViewTest, CornerViewVisibility) {
ScrollView scroll_view;
View* contents = new View;
scroll_view.SetContents(contents);
scroll_view.SetBoundsRect(gfx::Rect(0, 0, 100, 100));
View* corner_view = scroll_view.corner_view_;
// Corner view should be visible when both scrollbars are visible.
contents->SetBounds(0, 0, 200, 200);
scroll_view.Layout();
EXPECT_EQ(&scroll_view, corner_view->parent());
EXPECT_TRUE(corner_view->visible());
// Corner view should be aligned to the scrollbars.
EXPECT_EQ(scroll_view.vertical_scroll_bar()->x(), corner_view->x());
EXPECT_EQ(scroll_view.horizontal_scroll_bar()->y(), corner_view->y());
EXPECT_EQ(scroll_view.GetScrollBarWidth(), corner_view->width());
EXPECT_EQ(scroll_view.GetScrollBarHeight(), corner_view->height());
// Corner view should be removed when only the vertical scrollbar is visible.
contents->SetBounds(0, 0, 50, 200);
scroll_view.Layout();
EXPECT_FALSE(corner_view->parent());
// ... or when only the horizontal scrollbar is visible.
contents->SetBounds(0, 0, 200, 50);
scroll_view.Layout();
EXPECT_FALSE(corner_view->parent());
// ... or when no scrollbar is visible.
contents->SetBounds(0, 0, 50, 50);
scroll_view.Layout();
EXPECT_FALSE(corner_view->parent());
// Corner view should reappear when both scrollbars reappear.
contents->SetBounds(0, 0, 200, 200);
scroll_view.Layout();
EXPECT_EQ(&scroll_view, corner_view->parent());
EXPECT_TRUE(corner_view->visible());
}
} // namespace views } // namespace views
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment