Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(44)

Side by Side Diff: ui/views/controls/scrollbar/cocoa_scroll_bar.mm

Issue 1671313002: MacViews: Overlay Scrollbars with Show/Hide Animations (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ui/views/controls/scrollbar/cocoa_scroll_bar.h"
6
7 #import "base/mac/sdk_forward_declarations.h"
8 #include "third_party/skia/include/core/SkColor.h"
9 #include "ui/compositor/layer.h"
10 #include "ui/compositor/layer_animator.h"
11 #include "ui/gfx/canvas.h"
12 #include "ui/views/controls/scrollbar/base_scroll_bar_thumb.h"
13
14 namespace views {
15
16 namespace {
17
18 // How long we should wait before hiding the scrollbar.
19 const int kScrollbarHideTimeoutMs = 500;
20
21 // The width of the scrollbar.
22 const int kScrollbarWidth = 15;
23
24 // The width of the scrollbar thumb.
25 const int kScrollbarThumbWidth = 10;
26
27 // The width of the scroller track border.
28 const int kScrollerTrackBorderWidth = 1;
29
30 // The amount the thumb is inset from both the ends and the sides of the track.
31 const int kScrollbarThumbInset = 3;
32
33 // Scrollbar thumb color.
34 const SkColor kScrollerThumbColor = SkColorSetARGB(0x38, 0, 0, 0);
35
36 // Scroller track colors.
37 const SkColor kScrollerTrackColor = SkColorSetRGB(0xF9, 0xF9, 0xF9);
38 const SkColor kScrollerTrackInnerBorderColor = SkColorSetRGB(0xE4, 0xE4, 0xE4);
39 const SkColor kScrollerTrackOuterBorderColor = SkColorSetRGB(0xEF, 0xEF, 0xEF);
40
41 // The length of the fade animation.
42 static const int kFadeDurationMs = 240;
tapted 2016/02/16 06:47:58 nit: not static Also perhaps move this up next to
spqchan 2016/02/16 23:18:19 Done.
43
44 //////////////////////////////////////////////////////////////////
45 // CocoaScrollBarThumb
46
47 class CocoaScrollBarThumb : public BaseScrollBarThumb {
48 public:
49 explicit CocoaScrollBarThumb(CocoaScrollBar* scroll_bar);
50 ~CocoaScrollBarThumb() override;
51
52 protected:
53 // View overrides:
54 gfx::Size GetPreferredSize() const override;
55 void OnPaint(gfx::Canvas* canvas) override;
56 void OnMouseEntered(const ui::MouseEvent& event) override;
57 void OnMouseExited(const ui::MouseEvent& event) override;
58
59 private:
60 DISALLOW_COPY_AND_ASSIGN(CocoaScrollBarThumb);
61 };
62
63 CocoaScrollBarThumb::CocoaScrollBarThumb(CocoaScrollBar* scroll_bar)
64 : BaseScrollBarThumb(scroll_bar) {
65 // This is necessary, otherwise the thumb will be rendered below the views if
66 // those views paint to their own layers.
67 SetPaintToLayer(true);
68 SetFillsBoundsOpaquely(false);
69 }
70
71 CocoaScrollBarThumb::~CocoaScrollBarThumb() {}
72
73 gfx::Size CocoaScrollBarThumb::GetPreferredSize() const {
74 return gfx::Size(kScrollbarThumbWidth, kScrollbarThumbWidth);
75 }
76
77 void CocoaScrollBarThumb::OnPaint(gfx::Canvas* canvas) {
78 gfx::Rect local_bounds(GetLocalBounds());
79 SkPaint paint;
80 paint.setStyle(SkPaint::kFill_Style);
81 paint.setColor(kScrollerThumbColor);
82 const SkScalar radius = std::min(local_bounds.width(), local_bounds.height());
83 canvas->DrawRoundRect(local_bounds, radius, paint);
84 }
85
86 void CocoaScrollBarThumb::OnMouseEntered(const ui::MouseEvent& event) {
87 BaseScrollBarThumb::OnMouseEntered(event);
88 CocoaScrollBar* scrollbar = static_cast<CocoaScrollBar*>(scroll_bar());
89 scrollbar->OnMouseEnteredScrollbarThumb(event);
90 }
91
92 void CocoaScrollBarThumb::OnMouseExited(const ui::MouseEvent& event) {
93 BaseScrollBarThumb::OnMouseExited(event);
94 CocoaScrollBar* scrollbar = static_cast<CocoaScrollBar*>(scroll_bar());
95 scrollbar->OnMouseExitedScrollbarThumb(event);
96 }
97
98 } // namespace
99
100 //////////////////////////////////////////////////////////////////
101 // CocoaScrollBar class
102
103 CocoaScrollBar::CocoaScrollBar(bool horizontal)
104 : BaseScrollBar(horizontal, new CocoaScrollBarThumb(this)),
105 is_hovering_(false) {
106 bridge_.reset([[ViewsScrollbarBridge alloc] init]);
107 [bridge_ setDelegate:this];
108
109 scroller_style_ = [ViewsScrollbarBridge getPreferredScrollerStyle];
110
111 SetPaintToLayer(true);
112 has_scrolltrack_ = scroller_style_ == NSScrollerStyleLegacy;
113 layer()->SetOpacity(scroller_style_ == NSScrollerStyleOverlay ? 0.0 : 1.0);
114 }
115
116 CocoaScrollBar::~CocoaScrollBar() {
117 [bridge_ setDelegate:nullptr];
118 }
119
120 //////////////////////////////////////////////////////////////////
121 // CocoaScrollBar, BaseScrollBar:
122
123 gfx::Rect CocoaScrollBar::GetTrackBounds() const {
124 gfx::Rect local_bounds(GetLocalBounds());
125 local_bounds.Inset(kScrollbarThumbInset, kScrollbarThumbInset);
126
127 gfx::Size track_size = local_bounds.size();
128 track_size.SetToMax(GetThumb()->size());
129 local_bounds.set_size(track_size);
130 return local_bounds;
131 }
132
133 //////////////////////////////////////////////////////////////////
134 // CocoaScrollBar, ScrollBar:
135
136 int CocoaScrollBar::GetLayoutSize() const {
137 return 0;
138 }
139
140 int CocoaScrollBar::GetContentOverlapSize() const {
141 // TODO: (spqchan) Figure out what to do when we have a corner.
142 return kScrollbarWidth;
143 }
144
145 //////////////////////////////////////////////////////////////////
146 // CocoaScrollBar::Views:
147
148 gfx::Size CocoaScrollBar::GetPreferredSize() const {
149 return gfx::Size();
tapted 2016/02/16 06:47:58 Does this need to change based on scroller_style_?
spqchan 2016/02/16 23:18:18 This most likely will have to change later, especi
spqchan 2016/02/16 23:22:49 Oh shoot, I see what you mean. I'll look into this
150 }
151
152 void CocoaScrollBar::Layout() {
tapted 2016/02/16 06:47:58 I wonder if this could go in BaseScrollBar.... Of
spqchan 2016/02/16 23:18:18 Yeah, that would work.
153 gfx::Rect thumb_bounds = GetTrackBounds();
154 BaseScrollBarThumb* thumb = GetThumb();
155 if (IsHorizontal()) {
156 thumb_bounds.set_x(thumb->x());
157 thumb_bounds.set_width(thumb->width());
158 } else {
159 thumb_bounds.set_y(thumb->y());
160 thumb_bounds.set_height(thumb->height());
161 }
162 thumb->SetBoundsRect(thumb_bounds);
163 }
164
165 void CocoaScrollBar::OnPaint(gfx::Canvas* canvas) {
166 if (!has_scrolltrack_)
167 return;
168
169 // Paint the scrollbar track background.
170 gfx::Rect track_rect = GetLocalBounds();
171 SkPaint paint;
172 paint.setColor(kScrollerTrackColor);
173 canvas->DrawRect(track_rect, paint);
174
175 // Paint the inner and outer borders.
176 // Note: Unless there's a possibility of wanting borders
177 // to be more than 1px wide, we might want to use drawLine
178 if (IsHorizontal()) {
179 // Draw the top border.
180 SkPaint paint;
181 paint.setColor(kScrollerTrackInnerBorderColor);
182 gfx::Rect top_border(track_rect);
183 top_border.set_height(kScrollerTrackBorderWidth);
184 canvas->DrawRect(top_border, paint);
185
186 // Draw the bottom border.
187 paint.setColor(kScrollerTrackOuterBorderColor);
188 gfx::Rect bottom_border(top_border);
189 bottom_border.set_y(track_rect.bottom());
190 canvas->DrawRect(bottom_border, paint);
191 } else {
192 // Draw the left border.
193 SkPaint paint;
194 paint.setColor(kScrollerTrackInnerBorderColor);
195 gfx::Rect left_border(track_rect);
196 left_border.set_width(kScrollerTrackBorderWidth);
tapted 2016/02/16 06:47:58 do these look any better merged? I think only the
spqchan 2016/02/16 23:18:18 I kept it separate because I thought it would be e
197 canvas->DrawRect(left_border, paint);
198
199 // Draw the right border.
200 paint.setColor(kScrollerTrackOuterBorderColor);
201 gfx::Rect right_border(left_border);
202 right_border.set_x(track_rect.right());
203 canvas->DrawRect(right_border, paint);
204 }
205 }
206
207 void CocoaScrollBar::OnMouseEnteredScrollbarThumb(const ui::MouseEvent& event) {
208 if (scroller_style_ != NSScrollerStyleOverlay)
209 return;
210
211 hide_scrollbar_timer_.Stop();
212 is_hovering_ = true;
213 if (layer()->opacity()) {
214 ShowScrollbar();
215 }
216 }
217
218 void CocoaScrollBar::OnMouseExitedScrollbarThumb(const ui::MouseEvent& event) {
219 if (scroller_style_ != NSScrollerStyleOverlay)
220 return;
tapted 2016/02/16 06:47:58 nit: blank line after return
spqchan 2016/02/16 23:18:18 We can't have blank lines after return? TIL, I'll
tapted 2016/02/16 23:32:57 Ah, no the opposite :). There *should* be a line b
221 is_hovering_ = false;
222 ResetTimer();
223 }
224
225 //////////////////////////////////////////////////////////////////
226 // CocoaScrollBar::ScrollDelegate:
227
228 bool CocoaScrollBar::OnScroll(float dx, float dy) {
229 bool did_scroll = BaseScrollBar::OnScroll(dx, dy);
230 if (did_scroll && scroller_style_ == NSScrollerStyleOverlay) {
231 if (layer()->opacity() < 1.0)
232 ShowScrollbar();
233 ResetTimer();
234 }
235 return did_scroll;
236 }
237
238 //////////////////////////////////////////////////////////////////
239 // CocoaScrollBar::ViewsScrollbarBridge:
240
241 void CocoaScrollBar::OnScrollerStyleChanged() {
242 NSScrollerStyle scroller_style =
243 [ViewsScrollbarBridge getPreferredScrollerStyle];
244 if (scroller_style_ == scroller_style)
245 return;
246
247 scroller_style_ = scroller_style;
248 if (scroller_style_ == NSScrollerStyleOverlay) {
249 HideScrollbar();
250 } else {
251 ShowScrollbar();
252 }
253 }
254
255 //////////////////////////////////////////////////////////////////
256 // CocoaScrollBar, private:
257
258 void CocoaScrollBar::HideScrollbar() {
259 layer()->GetAnimator()->SetTransitionDuration(
260 base::TimeDelta::FromMilliseconds(kFadeDurationMs));
261 layer()->SetOpacity(0.0);
262 }
263
264 void CocoaScrollBar::ShowScrollbar() {
265 // Updates the scrolltrack and repaint it, if necessary.
266 bool has_scrolltrack =
267 scroller_style_ == NSScrollerStyleLegacy || is_hovering_;
268 if (has_scrolltrack_ != has_scrolltrack) {
269 has_scrolltrack_ = has_scrolltrack;
270 SchedulePaint();
271 }
272
273 layer()->GetAnimator()->SetTransitionDuration(
274 base::TimeDelta::FromMilliseconds(0));
tapted 2016/02/16 06:47:58 this line probably won't be needed with the Scoped
spqchan 2016/02/16 23:18:18 Done.
275 layer()->SetOpacity(1.0);
276 }
277
278 void CocoaScrollBar::ResetTimer() {
279 if (hide_scrollbar_timer_.IsRunning()) {
280 hide_scrollbar_timer_.Reset();
281 } else {
282 hide_scrollbar_timer_.Start(
283 FROM_HERE, base::TimeDelta::FromMilliseconds(kScrollbarHideTimeoutMs),
284 this, &CocoaScrollBar::HideScrollbar);
285 }
286 }
287
288 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698