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

Side by Side Diff: views/controls/scrollbar/bitmap_scroll_bar.cc

Issue 7669028: Adding a Views scrollbar implementation. (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Refactored the bitmap code to be shared with the native_scroll_bar_views Created 9 years, 4 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "views/controls/scrollbar/bitmap_scroll_bar.h" 5 #include "views/controls/scrollbar/bitmap_scroll_bar.h"
6 6
7 #if defined(OS_LINUX) 7 #if defined(OS_LINUX)
8 #include "views/screen.h" 8 #include "views/screen.h"
9 #endif 9 #endif
10 10
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 }; 90 };
91 91
92 /////////////////////////////////////////////////////////////////////////////// 92 ///////////////////////////////////////////////////////////////////////////////
93 // 93 //
94 // BitmapScrollBarThumb 94 // BitmapScrollBarThumb
95 // 95 //
96 // A view that acts as the thumb in the scroll bar track that the user can 96 // A view that acts as the thumb in the scroll bar track that the user can
97 // drag to scroll the associated contents view within the viewport. 97 // drag to scroll the associated contents view within the viewport.
98 // 98 //
99 /////////////////////////////////////////////////////////////////////////////// 99 ///////////////////////////////////////////////////////////////////////////////
100 class BitmapScrollBarThumb : public View { 100 class BitmapScrollBarThumb : public BaseScrollBarThumb {
101 public: 101 public:
102 explicit BitmapScrollBarThumb(BitmapScrollBar* scroll_bar) 102 explicit BitmapScrollBarThumb(BitmapScrollBar* scroll_bar)
103 : scroll_bar_(scroll_bar), 103 : BaseScrollBarThumb(scroll_bar),
104 drag_start_position_(-1), 104 scroll_bar_(scroll_bar) {
105 mouse_offset_(-1),
106 state_(CustomButton::BS_NORMAL) {
107 } 105 }
108 virtual ~BitmapScrollBarThumb() { } 106 virtual ~BitmapScrollBarThumb() { }
109 107
110 // Sets the size (width or height) of the thumb to the specified value.
111 void SetSize(int size) {
112 // Make sure the thumb is never sized smaller than its minimum possible
113 // display size.
114 gfx::Size prefsize = GetPreferredSize();
115 size = std::max(size, scroll_bar_->IsHorizontal() ? prefsize.width() :
116 prefsize.height());
117 gfx::Rect thumb_bounds = bounds();
118 if (scroll_bar_->IsHorizontal()) {
119 thumb_bounds.set_width(size);
120 } else {
121 thumb_bounds.set_height(size);
122 }
123 SetBoundsRect(thumb_bounds);
124 }
125
126 // Retrieves the size (width or height) of the thumb.
127 int GetSize() const {
128 if (scroll_bar_->IsHorizontal())
129 return width();
130 return height();
131 }
132
133 // Sets the position of the thumb on the x or y axis.
134 void SetPosition(int position) {
135 gfx::Rect thumb_bounds = bounds();
136 gfx::Rect track_bounds = scroll_bar_->GetTrackBounds();
137 if (scroll_bar_->IsHorizontal()) {
138 thumb_bounds.set_x(track_bounds.x() + position);
139 } else {
140 thumb_bounds.set_y(track_bounds.y() + position);
141 }
142 SetBoundsRect(thumb_bounds);
143 }
144
145 // Gets the position of the thumb on the x or y axis.
146 int GetPosition() const {
147 gfx::Rect track_bounds = scroll_bar_->GetTrackBounds();
148 if (scroll_bar_->IsHorizontal())
149 return x() - track_bounds.x();
150 return y() - track_bounds.y();
151 }
152
153 // View overrides: 108 // View overrides:
154 virtual gfx::Size GetPreferredSize() OVERRIDE { 109 virtual gfx::Size GetPreferredSize() OVERRIDE {
155 return gfx::Size(background_bitmap()->width(), 110 return gfx::Size(background_bitmap()->width(),
156 start_cap_bitmap()->height() + 111 start_cap_bitmap()->height() +
157 end_cap_bitmap()->height() + 112 end_cap_bitmap()->height() +
158 grippy_bitmap()->height()); 113 grippy_bitmap()->height());
159 } 114 }
160 115
161 protected: 116 protected:
162 // View overrides: 117 // View overrides:
163 virtual void Paint(gfx::Canvas* canvas) OVERRIDE { 118 virtual void Paint(gfx::Canvas* canvas) OVERRIDE {
164 canvas->DrawBitmapInt(*start_cap_bitmap(), 0, 0); 119 canvas->DrawBitmapInt(*start_cap_bitmap(), 0, 0);
165 int top_cap_height = start_cap_bitmap()->height(); 120 int top_cap_height = start_cap_bitmap()->height();
166 int bottom_cap_height = end_cap_bitmap()->height(); 121 int bottom_cap_height = end_cap_bitmap()->height();
167 int thumb_body_height = height() - top_cap_height - bottom_cap_height; 122 int thumb_body_height = height() - top_cap_height - bottom_cap_height;
168 canvas->TileImageInt(*background_bitmap(), 0, top_cap_height, 123 canvas->TileImageInt(*background_bitmap(), 0, top_cap_height,
169 background_bitmap()->width(), thumb_body_height); 124 background_bitmap()->width(), thumb_body_height);
170 canvas->DrawBitmapInt(*end_cap_bitmap(), 0, 125 canvas->DrawBitmapInt(*end_cap_bitmap(), 0,
171 height() - bottom_cap_height); 126 height() - bottom_cap_height);
172 127
173 // Paint the grippy over the track. 128 // Paint the grippy over the track.
174 int grippy_x = (width() - grippy_bitmap()->width()) / 2; 129 int grippy_x = (width() - grippy_bitmap()->width()) / 2;
175 int grippy_y = (thumb_body_height - grippy_bitmap()->height()) / 2; 130 int grippy_y = (thumb_body_height - grippy_bitmap()->height()) / 2;
176 canvas->DrawBitmapInt(*grippy_bitmap(), grippy_x, grippy_y); 131 canvas->DrawBitmapInt(*grippy_bitmap(), grippy_x, grippy_y);
177 } 132 }
178 133
179 virtual void OnMouseEntered(const MouseEvent& event) OVERRIDE {
180 SetState(CustomButton::BS_HOT);
181 }
182
183 virtual void OnMouseExited(const MouseEvent& event) OVERRIDE {
184 SetState(CustomButton::BS_NORMAL);
185 }
186
187 virtual bool OnMousePressed(const MouseEvent& event) OVERRIDE {
188 mouse_offset_ = scroll_bar_->IsHorizontal() ? event.x() : event.y();
189 drag_start_position_ = GetPosition();
190 SetState(CustomButton::BS_PUSHED);
191 return true;
192 }
193
194 virtual bool OnMouseDragged(const MouseEvent& event) OVERRIDE {
195 // If the user moves the mouse more than |kScrollThumbDragOutSnap| outside
196 // the bounds of the thumb, the scrollbar will snap the scroll back to the
197 // point it was at before the drag began.
198 if (scroll_bar_->IsHorizontal()) {
199 if ((event.y() < y() - kScrollThumbDragOutSnap) ||
200 (event.y() > (y() + height() + kScrollThumbDragOutSnap))) {
201 scroll_bar_->ScrollToThumbPosition(drag_start_position_, false);
202 return true;
203 }
204 } else {
205 if ((event.x() < x() - kScrollThumbDragOutSnap) ||
206 (event.x() > (x() + width() + kScrollThumbDragOutSnap))) {
207 scroll_bar_->ScrollToThumbPosition(drag_start_position_, false);
208 return true;
209 }
210 }
211 if (scroll_bar_->IsHorizontal()) {
212 int thumb_x = event.x() - mouse_offset_;
213 scroll_bar_->ScrollToThumbPosition(x() + thumb_x, false);
214 } else {
215 int thumb_y = event.y() - mouse_offset_;
216 scroll_bar_->ScrollToThumbPosition(y() + thumb_y, false);
217 }
218 return true;
219 }
220
221 virtual void OnMouseReleased(const MouseEvent& event) OVERRIDE {
222 OnMouseCaptureLost();
223 }
224
225 virtual void OnMouseCaptureLost() OVERRIDE {
226 SetState(CustomButton::BS_HOT);
227 }
228
229 private: 134 private:
230 // Returns the bitmap rendered at the start of the thumb. 135 // Returns the bitmap rendered at the start of the thumb.
231 SkBitmap* start_cap_bitmap() const { 136 SkBitmap* start_cap_bitmap() const {
232 return scroll_bar_->images_[BitmapScrollBar::THUMB_START_CAP][state_]; 137 return scroll_bar_->images_[BitmapScrollBar::THUMB_START_CAP][GetState()];
233 } 138 }
234 139
235 // Returns the bitmap rendered at the end of the thumb. 140 // Returns the bitmap rendered at the end of the thumb.
236 SkBitmap* end_cap_bitmap() const { 141 SkBitmap* end_cap_bitmap() const {
237 return scroll_bar_->images_[BitmapScrollBar::THUMB_END_CAP][state_]; 142 return scroll_bar_->images_[BitmapScrollBar::THUMB_END_CAP][GetState()];
238 } 143 }
239 144
240 // Returns the bitmap that is tiled in the background of the thumb between 145 // Returns the bitmap that is tiled in the background of the thumb between
241 // the start and the end caps. 146 // the start and the end caps.
242 SkBitmap* background_bitmap() const { 147 SkBitmap* background_bitmap() const {
243 return scroll_bar_->images_[BitmapScrollBar::THUMB_MIDDLE][state_]; 148 return scroll_bar_->images_[BitmapScrollBar::THUMB_MIDDLE][GetState()];
244 } 149 }
245 150
246 // Returns the bitmap that is rendered in the middle of the thumb 151 // Returns the bitmap that is rendered in the middle of the thumb
247 // transparently over the background bitmap. 152 // transparently over the background bitmap.
248 SkBitmap* grippy_bitmap() const { 153 SkBitmap* grippy_bitmap() const {
249 return scroll_bar_->images_[BitmapScrollBar::THUMB_GRIPPY] 154 return scroll_bar_->images_[BitmapScrollBar::THUMB_GRIPPY]
250 [CustomButton::BS_NORMAL]; 155 [CustomButton::BS_NORMAL];
251 } 156 }
252 157
253 // Update our state and schedule a repaint when the mouse moves over us.
254 void SetState(CustomButton::ButtonState state) {
255 state_ = state;
256 SchedulePaint();
257 }
258
259 // The BitmapScrollBar that owns us. 158 // The BitmapScrollBar that owns us.
260 BitmapScrollBar* scroll_bar_; 159 BitmapScrollBar* scroll_bar_;
261 160
262 int drag_start_position_;
263
264 // The position of the mouse on the scroll axis relative to the top of this
265 // View when the drag started.
266 int mouse_offset_;
267
268 // The current state of the thumb button.
269 CustomButton::ButtonState state_;
270
271 DISALLOW_COPY_AND_ASSIGN(BitmapScrollBarThumb); 161 DISALLOW_COPY_AND_ASSIGN(BitmapScrollBarThumb);
272 }; 162 };
273 163
274 } // anonymous namespace 164 } // anonymous namespace
275 165
276 /////////////////////////////////////////////////////////////////////////////// 166 ///////////////////////////////////////////////////////////////////////////////
277 // BitmapScrollBar, public: 167 // BitmapScrollBar, public:
278 168
279 BitmapScrollBar::BitmapScrollBar(bool horizontal, bool show_scroll_buttons) 169 BitmapScrollBar::BitmapScrollBar(bool horizontal, bool show_scroll_buttons)
280 : contents_size_(0), 170 : BaseScrollBar(horizontal, new BitmapScrollBarThumb(this)),
281 contents_scroll_offset_(0), 171 contents_scroll_offset_(0),
282 ALLOW_THIS_IN_INITIALIZER_LIST(prev_button_(new AutorepeatButton(this))), 172 ALLOW_THIS_IN_INITIALIZER_LIST(prev_button_(new AutorepeatButton(this))),
283 ALLOW_THIS_IN_INITIALIZER_LIST(next_button_(new AutorepeatButton(this))), 173 ALLOW_THIS_IN_INITIALIZER_LIST(next_button_(new AutorepeatButton(this))),
284 ALLOW_THIS_IN_INITIALIZER_LIST(thumb_(new BitmapScrollBarThumb(this))),
285 thumb_track_state_(CustomButton::BS_NORMAL), 174 thumb_track_state_(CustomButton::BS_NORMAL),
286 last_scroll_amount_(SCROLL_NONE), 175 last_scroll_amount_(SCROLL_NONE),
287 ALLOW_THIS_IN_INITIALIZER_LIST(repeater_( 176 ALLOW_THIS_IN_INITIALIZER_LIST(repeater_(
288 NewCallback<BitmapScrollBar>(this, 177 NewCallback<BitmapScrollBar>(this,
289 &BitmapScrollBar::TrackClicked))), 178 &BitmapScrollBar::TrackClicked))),
290 context_menu_mouse_position_(0), 179 context_menu_mouse_position_(0),
291 show_scroll_buttons_(show_scroll_buttons), 180 show_scroll_buttons_(show_scroll_buttons),
292 ScrollBar(horizontal) { 181 ScrollBar(horizontal) {
293 if (!show_scroll_buttons_) { 182 if (!show_scroll_buttons_) {
294 prev_button_->SetVisible(false); 183 prev_button_->SetVisible(false);
295 next_button_->SetVisible(false); 184 next_button_->SetVisible(false);
296 } 185 }
297 186
298 AddChildView(prev_button_); 187 AddChildView(prev_button_);
299 AddChildView(next_button_); 188 AddChildView(next_button_);
300 AddChildView(thumb_);
301 189
302 set_context_menu_controller(this); 190 set_context_menu_controller(this);
303 prev_button_->set_context_menu_controller(this); 191 prev_button_->set_context_menu_controller(this);
304 next_button_->set_context_menu_controller(this); 192 next_button_->set_context_menu_controller(this);
305 thumb_->set_context_menu_controller(this);
306 }
307
308 gfx::Rect BitmapScrollBar::GetTrackBounds() const {
309 gfx::Size prefsize = prev_button_->GetPreferredSize();
310 if (IsHorizontal()) {
311 if (!show_scroll_buttons_)
312 prefsize.set_width(0);
313 int new_width =
314 std::max(0, width() - (prefsize.width() * 2));
315 gfx::Rect track_bounds(prefsize.width(), 0, new_width, prefsize.height());
316 return track_bounds;
317 }
318 if (!show_scroll_buttons_)
319 prefsize.set_height(0);
320 gfx::Rect track_bounds(0, prefsize.height(), prefsize.width(),
321 std::max(0, height() - (prefsize.height() * 2)));
322 return track_bounds;
323 } 193 }
324 194
325 void BitmapScrollBar::SetImage(ScrollBarPart part, 195 void BitmapScrollBar::SetImage(ScrollBarPart part,
326 CustomButton::ButtonState state, 196 CustomButton::ButtonState state,
327 SkBitmap* bitmap) { 197 SkBitmap* bitmap) {
328 DCHECK(part < PART_COUNT); 198 DCHECK(part < PART_COUNT);
329 DCHECK(state < CustomButton::BS_COUNT); 199 DCHECK(state < CustomButton::BS_COUNT);
330 switch (part) { 200 switch (part) {
331 case PREV_BUTTON: 201 case PREV_BUTTON:
332 prev_button_->SetImage(state, bitmap); 202 prev_button_->SetImage(state, bitmap);
333 break; 203 break;
334 case NEXT_BUTTON: 204 case NEXT_BUTTON:
335 next_button_->SetImage(state, bitmap); 205 next_button_->SetImage(state, bitmap);
336 break; 206 break;
337 case THUMB_START_CAP: 207 case THUMB_START_CAP:
338 case THUMB_MIDDLE: 208 case THUMB_MIDDLE:
339 case THUMB_END_CAP: 209 case THUMB_END_CAP:
340 case THUMB_GRIPPY: 210 case THUMB_GRIPPY:
341 case THUMB_TRACK: 211 case THUMB_TRACK:
342 images_[part][state] = bitmap; 212 images_[part][state] = bitmap;
343 break; 213 break;
344 } 214 }
345 } 215 }
346 216
347 void BitmapScrollBar::ScrollByAmount(ScrollAmount amount) { 217 int BaseScrollBar::GetLayoutSize() const {
348 ScrollBarController* controller = GetController(); 218 gfx::Size prefsize = prev_button_->GetPreferredSize();
349 int offset = contents_scroll_offset_; 219 return IsHorizontal() ? prefsize.height() : prefsize.width();
350 switch (amount) {
351 case SCROLL_START:
352 offset = GetMinPosition();
353 break;
354 case SCROLL_END:
355 offset = GetMaxPosition();
356 break;
357 case SCROLL_PREV_LINE:
358 offset -= controller->GetScrollIncrement(this, false, false);
359 offset = std::max(GetMinPosition(), offset);
360 break;
361 case SCROLL_NEXT_LINE:
362 offset += controller->GetScrollIncrement(this, false, true);
363 offset = std::min(GetMaxPosition(), offset);
364 break;
365 case SCROLL_PREV_PAGE:
366 offset -= controller->GetScrollIncrement(this, true, false);
367 offset = std::max(GetMinPosition(), offset);
368 break;
369 case SCROLL_NEXT_PAGE:
370 offset += controller->GetScrollIncrement(this, true, true);
371 offset = std::min(GetMaxPosition(), offset);
372 break;
373 }
374 contents_scroll_offset_ = offset;
375 ScrollContentsToOffset();
376 } 220 }
377 221
378 void BitmapScrollBar::ScrollToThumbPosition(int thumb_position, 222 gfx::Rect BaseScrollBar::GetTrackBounds() const {
379 bool scroll_to_middle) { 223 gfx::Size prefsize = prev_button_->GetPreferredSize();
380 contents_scroll_offset_ = 224 if (IsHorizontal()) {
381 CalculateContentsOffset(thumb_position, scroll_to_middle); 225 if (!show_scroll_buttons_)
382 if (contents_scroll_offset_ < GetMinPosition()) { 226 prefsize.set_width(0);
383 contents_scroll_offset_ = GetMinPosition(); 227 int new_width =
384 } else if (contents_scroll_offset_ > GetMaxPosition()) { 228 std::max(0, width() - (prefsize.width() * 2));
385 contents_scroll_offset_ = GetMaxPosition(); 229 gfx::Rect track_bounds(prefsize.width(), 0, new_width, prefsize.height());
230 return track_bounds;
386 } 231 }
387 ScrollContentsToOffset(); 232 if (!show_scroll_buttons_)
388 SchedulePaint(); 233 prefsize.set_height(0);
389 } 234 gfx::Rect track_bounds(0, prefsize.height(), prefsize.width(),
390 235 std::max(0, height() - (prefsize.height() * 2)));
391 void BitmapScrollBar::ScrollByContentsOffset(int contents_offset) { 236 return track_bounds;
392 contents_scroll_offset_ -= contents_offset;
393 if (contents_scroll_offset_ < GetMinPosition()) {
394 contents_scroll_offset_ = GetMinPosition();
395 } else if (contents_scroll_offset_ > GetMaxPosition()) {
396 contents_scroll_offset_ = GetMaxPosition();
397 }
398 ScrollContentsToOffset();
399 } 237 }
400 238
401 /////////////////////////////////////////////////////////////////////////////// 239 ///////////////////////////////////////////////////////////////////////////////
402 // BitmapScrollBar, View implementation: 240 // BaseScrollBar, View implementation:
403 241
404 gfx::Size BitmapScrollBar::GetPreferredSize() { 242 gfx::Size BaseScrollBar::GetPreferredSize() {
405 // In this case, we're returning the desired width of the scrollbar and its 243 // In this case, we're returning the desired width of the scrollbar and its
406 // minimum allowable height. 244 // minimum allowable height.
407 gfx::Size button_prefsize = prev_button_->GetPreferredSize(); 245 gfx::Size button_prefsize = prev_button_->GetPreferredSize();
408 return gfx::Size(button_prefsize.width(), button_prefsize.height() * 2); 246 return gfx::Size(button_prefsize.width(), button_prefsize.height() * 2);
409 } 247 }
410 248
411 void BitmapScrollBar::Layout() { 249 void BaseScrollBar::Layout() {
412 // Size and place the two scroll buttons. 250 // Size and place the two scroll buttons.
413 if (show_scroll_buttons_) { 251 if (show_scroll_buttons_) {
414 gfx::Size prefsize = prev_button_->GetPreferredSize(); 252 gfx::Size prefsize = prev_button_->GetPreferredSize();
415 prev_button_->SetBounds(0, 0, prefsize.width(), prefsize.height()); 253 prev_button_->SetBounds(0, 0, prefsize.width(), prefsize.height());
416 prefsize = next_button_->GetPreferredSize(); 254 prefsize = next_button_->GetPreferredSize();
417 if (IsHorizontal()) { 255 if (IsHorizontal()) {
418 next_button_->SetBounds(width() - prefsize.width(), 0, prefsize.width(), 256 next_button_->SetBounds(width() - prefsize.width(), 0, prefsize.width(),
419 prefsize.height()); 257 prefsize.height());
420 } else { 258 } else {
421 next_button_->SetBounds(0, height() - prefsize.height(), prefsize.width(), 259 next_button_->SetBounds(0, height() - prefsize.height(), prefsize.width(),
422 prefsize.height()); 260 prefsize.height());
423 } 261 }
424 } else { 262 } else {
425 prev_button_->SetBounds(0, 0, 0, 0); 263 prev_button_->SetBounds(0, 0, 0, 0);
426 next_button_->SetBounds(0, 0, 0, 0); 264 next_button_->SetBounds(0, 0, 0, 0);
427 } 265 }
428 266
267 BaseScrollBarThumb* thumb = GetThumb();
429 // Size and place the thumb 268 // Size and place the thumb
430 gfx::Size thumb_prefsize = thumb_->GetPreferredSize(); 269 gfx::Size thumb_prefsize = thumb->GetPreferredSize();
431 gfx::Rect track_bounds = GetTrackBounds(); 270 gfx::Rect track_bounds = GetTrackBounds();
432 271
433 // Preserve the height/width of the thumb (depending on orientation) as set 272 // Preserve the height/width of the thumb (depending on orientation) as set
434 // by the last call to |Update|, but coerce the width/height to be the 273 // by the last call to |Update|, but coerce the width/height to be the
435 // appropriate value for the bitmaps provided. 274 // appropriate value for the bitmaps provided.
436 if (IsHorizontal()) { 275 if (IsHorizontal()) {
437 thumb_->SetBounds(thumb_->x(), thumb_->y(), thumb_->width(), 276 thumb->SetBounds(thumb->x(), thumb->y(), thumb->width(),
438 thumb_prefsize.height()); 277 thumbprefsize.height());
439 } else { 278 } else {
440 thumb_->SetBounds(thumb_->x(), thumb_->y(), thumb_prefsize.width(), 279 thumb->SetBounds(thumb->x(), thumb->y(), thumbprefsize.width(),
441 thumb_->height()); 280 thumb->height());
442 } 281 }
443 282
444 // Hide the thumb if the track isn't tall enough to display even a tiny 283 // Hide the thumb if the track isn't tall enough to display even a tiny
445 // thumb. The user can only use the mousewheel, scroll buttons or keyboard 284 // thumb. The user can only use the mousewheel, scroll buttons or keyboard
446 // in this scenario. 285 // in this scenario.
447 if ((IsHorizontal() && (track_bounds.width() < thumb_prefsize.width()) || 286 if ((IsHorizontal() && (track_bounds.width() < thumb_prefsize.width()) ||
448 (!IsHorizontal() && (track_bounds.height() < thumb_prefsize.height())))) { 287 (!IsHorizontal() && (track_bounds.height() < thumb_prefsize.height())))) {
449 thumb_->SetVisible(false); 288 thumb->SetVisible(false);
450 } else if (!thumb_->IsVisible()) { 289 } else if (!thumb->IsVisible()) {
451 thumb_->SetVisible(true); 290 thumb->SetVisible(true);
452 } 291 }
453 } 292 }
454 293
455 bool BitmapScrollBar::OnMousePressed(const MouseEvent& event) {
456 if (event.IsOnlyLeftMouseButton()) {
457 SetThumbTrackState(CustomButton::BS_PUSHED);
458 gfx::Rect thumb_bounds = thumb_->bounds();
459 if (IsHorizontal()) {
460 if (event.x() < thumb_bounds.x()) {
461 last_scroll_amount_ = SCROLL_PREV_PAGE;
462 } else if (event.x() > thumb_bounds.right()) {
463 last_scroll_amount_ = SCROLL_NEXT_PAGE;
464 }
465 } else {
466 if (event.y() < thumb_bounds.y()) {
467 last_scroll_amount_ = SCROLL_PREV_PAGE;
468 } else if (event.y() > thumb_bounds.bottom()) {
469 last_scroll_amount_ = SCROLL_NEXT_PAGE;
470 }
471 }
472 TrackClicked();
473 repeater_.Start();
474 }
475 return true;
476 }
477
478 void BitmapScrollBar::OnMouseReleased(const MouseEvent& event) {
479 OnMouseCaptureLost();
480 }
481
482 void BitmapScrollBar::OnMouseCaptureLost() {
483 SetThumbTrackState(CustomButton::BS_NORMAL);
484 repeater_.Stop();
485 }
486
487 bool BitmapScrollBar::OnKeyPressed(const KeyEvent& event) {
488 ScrollAmount amount = SCROLL_NONE;
489 switch (event.key_code()) {
490 case ui::VKEY_UP:
491 if (!IsHorizontal())
492 amount = SCROLL_PREV_LINE;
493 break;
494 case ui::VKEY_DOWN:
495 if (!IsHorizontal())
496 amount = SCROLL_NEXT_LINE;
497 break;
498 case ui::VKEY_LEFT:
499 if (IsHorizontal())
500 amount = SCROLL_PREV_LINE;
501 break;
502 case ui::VKEY_RIGHT:
503 if (IsHorizontal())
504 amount = SCROLL_NEXT_LINE;
505 break;
506 case ui::VKEY_PRIOR:
507 amount = SCROLL_PREV_PAGE;
508 break;
509 case ui::VKEY_NEXT:
510 amount = SCROLL_NEXT_PAGE;
511 break;
512 case ui::VKEY_HOME:
513 amount = SCROLL_START;
514 break;
515 case ui::VKEY_END:
516 amount = SCROLL_END;
517 break;
518 }
519 if (amount != SCROLL_NONE) {
520 ScrollByAmount(amount);
521 return true;
522 }
523 return false;
524 }
525
526 bool BitmapScrollBar::OnMouseWheel(const MouseWheelEvent& event) {
527 ScrollByContentsOffset(event.offset());
528 return true;
529 }
530
531 ///////////////////////////////////////////////////////////////////////////////
532 // BitmapScrollBar, ContextMenuController implementation:
533
534 enum ScrollBarContextMenuCommands {
535 ScrollBarContextMenuCommand_ScrollHere = 1,
536 ScrollBarContextMenuCommand_ScrollStart,
537 ScrollBarContextMenuCommand_ScrollEnd,
538 ScrollBarContextMenuCommand_ScrollPageUp,
539 ScrollBarContextMenuCommand_ScrollPageDown,
540 ScrollBarContextMenuCommand_ScrollPrev,
541 ScrollBarContextMenuCommand_ScrollNext
542 };
543
544 void BitmapScrollBar::ShowContextMenuForView(View* source,
545 const gfx::Point& p,
546 bool is_mouse_gesture) {
547 Widget* widget = GetWidget();
548 gfx::Rect widget_bounds = widget->GetWindowScreenBounds();
549 gfx::Point temp_pt(p.x() - widget_bounds.x(), p.y() - widget_bounds.y());
550 View::ConvertPointFromWidget(this, &temp_pt);
551 context_menu_mouse_position_ = IsHorizontal() ? temp_pt.x() : temp_pt.y();
552
553 scoped_ptr<Menu> menu(
554 Menu::Create(this, Menu::TOPLEFT, GetWidget()->GetNativeView()));
555 menu->AppendDelegateMenuItem(ScrollBarContextMenuCommand_ScrollHere);
556 menu->AppendSeparator();
557 menu->AppendDelegateMenuItem(ScrollBarContextMenuCommand_ScrollStart);
558 menu->AppendDelegateMenuItem(ScrollBarContextMenuCommand_ScrollEnd);
559 menu->AppendSeparator();
560 menu->AppendDelegateMenuItem(ScrollBarContextMenuCommand_ScrollPageUp);
561 menu->AppendDelegateMenuItem(ScrollBarContextMenuCommand_ScrollPageDown);
562 menu->AppendSeparator();
563 menu->AppendDelegateMenuItem(ScrollBarContextMenuCommand_ScrollPrev);
564 menu->AppendDelegateMenuItem(ScrollBarContextMenuCommand_ScrollNext);
565 menu->RunMenuAt(p.x(), p.y());
566 }
567
568 ///////////////////////////////////////////////////////////////////////////////
569 // BitmapScrollBar, Menu::Delegate implementation:
570
571 std::wstring BitmapScrollBar::GetLabel(int id) const {
572 int ids_value = 0;
573 switch (id) {
574 case ScrollBarContextMenuCommand_ScrollHere:
575 ids_value = IDS_APP_SCROLLBAR_CXMENU_SCROLLHERE;
576 break;
577 case ScrollBarContextMenuCommand_ScrollStart:
578 ids_value = IsHorizontal() ? IDS_APP_SCROLLBAR_CXMENU_SCROLLLEFTEDGE
579 : IDS_APP_SCROLLBAR_CXMENU_SCROLLHOME;
580 break;
581 case ScrollBarContextMenuCommand_ScrollEnd:
582 ids_value = IsHorizontal() ? IDS_APP_SCROLLBAR_CXMENU_SCROLLRIGHTEDGE
583 : IDS_APP_SCROLLBAR_CXMENU_SCROLLEND;
584 break;
585 case ScrollBarContextMenuCommand_ScrollPageUp:
586 ids_value = IDS_APP_SCROLLBAR_CXMENU_SCROLLPAGEUP;
587 break;
588 case ScrollBarContextMenuCommand_ScrollPageDown:
589 ids_value = IDS_APP_SCROLLBAR_CXMENU_SCROLLPAGEDOWN;
590 break;
591 case ScrollBarContextMenuCommand_ScrollPrev:
592 ids_value = IsHorizontal() ? IDS_APP_SCROLLBAR_CXMENU_SCROLLLEFT
593 : IDS_APP_SCROLLBAR_CXMENU_SCROLLUP;
594 break;
595 case ScrollBarContextMenuCommand_ScrollNext:
596 ids_value = IsHorizontal() ? IDS_APP_SCROLLBAR_CXMENU_SCROLLRIGHT
597 : IDS_APP_SCROLLBAR_CXMENU_SCROLLDOWN;
598 break;
599 default:
600 NOTREACHED() << "Invalid BitmapScrollBar Context Menu command!";
601 }
602
603 return ids_value ? UTF16ToWide(l10n_util::GetStringUTF16(ids_value)) : L"";
604 }
605
606 bool BitmapScrollBar::IsCommandEnabled(int id) const {
607 switch (id) {
608 case ScrollBarContextMenuCommand_ScrollPageUp:
609 case ScrollBarContextMenuCommand_ScrollPageDown:
610 return !IsHorizontal();
611 }
612 return true;
613 }
614
615 void BitmapScrollBar::ExecuteCommand(int id) {
616 switch (id) {
617 case ScrollBarContextMenuCommand_ScrollHere:
618 ScrollToThumbPosition(context_menu_mouse_position_, true);
619 break;
620 case ScrollBarContextMenuCommand_ScrollStart:
621 ScrollByAmount(SCROLL_START);
622 break;
623 case ScrollBarContextMenuCommand_ScrollEnd:
624 ScrollByAmount(SCROLL_END);
625 break;
626 case ScrollBarContextMenuCommand_ScrollPageUp:
627 ScrollByAmount(SCROLL_PREV_PAGE);
628 break;
629 case ScrollBarContextMenuCommand_ScrollPageDown:
630 ScrollByAmount(SCROLL_NEXT_PAGE);
631 break;
632 case ScrollBarContextMenuCommand_ScrollPrev:
633 ScrollByAmount(SCROLL_PREV_LINE);
634 break;
635 case ScrollBarContextMenuCommand_ScrollNext:
636 ScrollByAmount(SCROLL_NEXT_LINE);
637 break;
638 }
639 }
640
641 ///////////////////////////////////////////////////////////////////////////////
642 // BitmapScrollBar, ButtonListener implementation:
643
644 void BitmapScrollBar::ButtonPressed(Button* sender, const views::Event& event) {
645 if (sender == prev_button_) {
646 ScrollByAmount(SCROLL_PREV_LINE);
647 } else if (sender == next_button_) {
648 ScrollByAmount(SCROLL_NEXT_LINE);
649 }
650 }
651
652 ///////////////////////////////////////////////////////////////////////////////
653 // BitmapScrollBar, ScrollBar implementation:
654
655 void BitmapScrollBar::Update(int viewport_size, int content_size,
656 int contents_scroll_offset) {
657 ScrollBar::Update(viewport_size, content_size, contents_scroll_offset);
658
659 // Make sure contents_size is always > 0 to avoid divide by zero errors in
660 // calculations throughout this code.
661 contents_size_ = std::max(1, content_size);
662
663 if (content_size < 0)
664 content_size = 0;
665 if (contents_scroll_offset < 0)
666 contents_scroll_offset = 0;
667 if (contents_scroll_offset > content_size)
668 contents_scroll_offset = content_size;
669
670 // Thumb Height and Thumb Pos.
671 // The height of the thumb is the ratio of the Viewport height to the
672 // content size multiplied by the height of the thumb track.
673 double ratio = static_cast<double>(viewport_size) / contents_size_;
674 int thumb_size = static_cast<int>(ratio * GetTrackSize());
675 thumb_->SetSize(thumb_size);
676
677 int thumb_position = CalculateThumbPosition(contents_scroll_offset);
678 thumb_->SetPosition(thumb_position);
679 }
680
681 int BitmapScrollBar::GetLayoutSize() const {
682 gfx::Size prefsize = prev_button_->GetPreferredSize();
683 return IsHorizontal() ? prefsize.height() : prefsize.width();
684 }
685
686 int BitmapScrollBar::GetPosition() const {
687 return thumb_->GetPosition();
688 }
689
690 /////////////////////////////////////////////////////////////////////////////// 294 ///////////////////////////////////////////////////////////////////////////////
691 // BitmapScrollBar, View implementation: 295 // BitmapScrollBar, View implementation:
692 296
693 void BitmapScrollBar::OnPaint(gfx::Canvas* canvas) { 297 void BitmapScrollBar::OnPaint(gfx::Canvas* canvas) {
694 // Paint the track. 298 // Paint the track.
695 gfx::Rect track_bounds = GetTrackBounds(); 299 gfx::Rect track_bounds = GetTrackBounds();
696 canvas->TileImageInt(*images_[THUMB_TRACK][thumb_track_state_], 300 canvas->TileImageInt(*images_[THUMB_TRACK][thumb_track_state_],
697 track_bounds.x(), track_bounds.y(), 301 track_bounds.x(), track_bounds.y(),
698 track_bounds.width(), track_bounds.height()); 302 track_bounds.width(), track_bounds.height());
699 } 303 }
700 304
701 /////////////////////////////////////////////////////////////////////////////// 305 ///////////////////////////////////////////////////////////////////////////////
702 // BitmapScrollBar, private: 306 // BaseScrollBar, ButtonListener implementation:
703 307
704 void BitmapScrollBar::TrackClicked() { 308 void BaseScrollBar::ButtonPressed(Button* sender, const views::Event& event) {
705 if (last_scroll_amount_ != SCROLL_NONE) 309 if (sender == prev_button_) {
706 ScrollByAmount(last_scroll_amount_); 310 ScrollByAmount(SCROLL_PREV_LINE);
707 } 311 } else if (sender == next_button_) {
708 312 ScrollByAmount(SCROLL_NEXT_LINE);
709 void BitmapScrollBar::ScrollContentsToOffset() { 313 }
710 GetController()->ScrollToPosition(this, contents_scroll_offset_);
711 thumb_->SetPosition(CalculateThumbPosition(contents_scroll_offset_));
712 }
713
714 int BitmapScrollBar::GetTrackSize() const {
715 gfx::Rect track_bounds = GetTrackBounds();
716 return IsHorizontal() ? track_bounds.width() : track_bounds.height();
717 }
718
719 int BitmapScrollBar::CalculateThumbPosition(int contents_scroll_offset) const {
720 return (contents_scroll_offset * GetTrackSize()) / contents_size_;
721 }
722
723 int BitmapScrollBar::CalculateContentsOffset(int thumb_position,
724 bool scroll_to_middle) const {
725 if (scroll_to_middle)
726 thumb_position = thumb_position - (thumb_->GetSize() / 2);
727 return (thumb_position * contents_size_) / GetTrackSize();
728 }
729
730 void BitmapScrollBar::SetThumbTrackState(CustomButton::ButtonState state) {
731 thumb_track_state_ = state;
732 SchedulePaint();
733 } 314 }
734 315
735 } // namespace views 316 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698