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

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

Issue 7767002: Revert 98434 - Adding a Views scrollbar implementation. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 9 years, 3 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
11 #include "base/callback.h" 11 #include "base/callback.h"
12 #include "base/compiler_specific.h" 12 #include "base/compiler_specific.h"
13 #include "base/message_loop.h" 13 #include "base/message_loop.h"
14 #include "base/string16.h" 14 #include "base/string16.h"
15 #include "base/utf_string_conversions.h" 15 #include "base/utf_string_conversions.h"
16 #include "grit/ui_strings.h" 16 #include "grit/ui_strings.h"
17 #include "third_party/skia/include/core/SkBitmap.h" 17 #include "third_party/skia/include/core/SkBitmap.h"
18 #include "ui/base/keycodes/keyboard_codes.h" 18 #include "ui/base/keycodes/keyboard_codes.h"
19 #include "ui/base/l10n/l10n_util.h" 19 #include "ui/base/l10n/l10n_util.h"
20 #include "ui/gfx/canvas.h" 20 #include "ui/gfx/canvas.h"
21 #include "views/controls/menu/menu.h" 21 #include "views/controls/menu/menu.h"
22 #include "views/controls/scrollbar/base_scroll_bar_thumb.h"
23 #include "views/controls/scroll_view.h" 22 #include "views/controls/scroll_view.h"
24 #include "views/widget/widget.h" 23 #include "views/widget/widget.h"
25 24
26 #undef min 25 #undef min
27 #undef max 26 #undef max
28 27
29 namespace views { 28 namespace views {
30 29
31 namespace { 30 namespace {
32 31
33 // The distance the mouse can be dragged outside the bounds of the thumb during 32 // The distance the mouse can be dragged outside the bounds of the thumb during
34 // dragging before the scrollbar will snap back to its regular position. 33 // dragging before the scrollbar will snap back to its regular position.
35 static const int kScrollThumbDragOutSnap = 100; 34 static const int kScrollThumbDragOutSnap = 100;
36 35
37 /////////////////////////////////////////////////////////////////////////////// 36 ///////////////////////////////////////////////////////////////////////////////
38 // 37 //
39 // AutorepeatButton 38 // AutorepeatButton
40 // 39 //
41 // A button that activates on mouse pressed rather than released, and that 40 // A button that activates on mouse pressed rather than released, and that
42 // continues to fire the clicked action as the mouse button remains pressed 41 // continues to fire the clicked action as the mouse button remains pressed
43 // down on the button. 42 // down on the button.
44 // 43 //
45 /////////////////////////////////////////////////////////////////////////////// 44 ///////////////////////////////////////////////////////////////////////////////
46 class AutorepeatButton : public ImageButton { 45 class AutorepeatButton : public ImageButton {
47 public: 46 public:
48 explicit AutorepeatButton(ButtonListener* listener) 47 AutorepeatButton(ButtonListener* listener)
49 : ImageButton(listener), 48 : ImageButton(listener),
50 ALLOW_THIS_IN_INITIALIZER_LIST(repeater_( 49 ALLOW_THIS_IN_INITIALIZER_LIST(repeater_(
51 NewCallback<AutorepeatButton>(this, 50 NewCallback<AutorepeatButton>(this,
52 &AutorepeatButton::NotifyClick))) { 51 &AutorepeatButton::NotifyClick))) {
53 } 52 }
54 virtual ~AutorepeatButton() {} 53 virtual ~AutorepeatButton() {}
55 54
56 protected: 55 protected:
57 virtual bool OnMousePressed(const MouseEvent& event) OVERRIDE { 56 virtual bool OnMousePressed(const MouseEvent& event) OVERRIDE {
58 Button::NotifyClick(event); 57 Button::NotifyClick(event);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 }; 90 };
92 91
93 /////////////////////////////////////////////////////////////////////////////// 92 ///////////////////////////////////////////////////////////////////////////////
94 // 93 //
95 // BitmapScrollBarThumb 94 // BitmapScrollBarThumb
96 // 95 //
97 // 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
98 // drag to scroll the associated contents view within the viewport. 97 // drag to scroll the associated contents view within the viewport.
99 // 98 //
100 /////////////////////////////////////////////////////////////////////////////// 99 ///////////////////////////////////////////////////////////////////////////////
101 class BitmapScrollBarThumb : public BaseScrollBarThumb { 100 class BitmapScrollBarThumb : public View {
102 public: 101 public:
103 explicit BitmapScrollBarThumb(BitmapScrollBar* scroll_bar) 102 explicit BitmapScrollBarThumb(BitmapScrollBar* scroll_bar)
104 : BaseScrollBarThumb(scroll_bar), 103 : scroll_bar_(scroll_bar),
105 scroll_bar_(scroll_bar) { 104 drag_start_position_(-1),
105 mouse_offset_(-1),
106 state_(CustomButton::BS_NORMAL) {
106 } 107 }
107 virtual ~BitmapScrollBarThumb() { } 108 virtual ~BitmapScrollBarThumb() { }
108 109
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
109 // View overrides: 153 // View overrides:
110 virtual gfx::Size GetPreferredSize() OVERRIDE { 154 virtual gfx::Size GetPreferredSize() OVERRIDE {
111 return gfx::Size(background_bitmap()->width(), 155 return gfx::Size(background_bitmap()->width(),
112 start_cap_bitmap()->height() + 156 start_cap_bitmap()->height() +
113 end_cap_bitmap()->height() + 157 end_cap_bitmap()->height() +
114 grippy_bitmap()->height()); 158 grippy_bitmap()->height());
115 } 159 }
116 160
117 protected: 161 protected:
118 // View overrides: 162 // View overrides:
119 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE { 163 virtual void Paint(gfx::Canvas* canvas) OVERRIDE {
120 canvas->DrawBitmapInt(*start_cap_bitmap(), 0, 0); 164 canvas->DrawBitmapInt(*start_cap_bitmap(), 0, 0);
121 int top_cap_height = start_cap_bitmap()->height(); 165 int top_cap_height = start_cap_bitmap()->height();
122 int bottom_cap_height = end_cap_bitmap()->height(); 166 int bottom_cap_height = end_cap_bitmap()->height();
123 int thumb_body_height = height() - top_cap_height - bottom_cap_height; 167 int thumb_body_height = height() - top_cap_height - bottom_cap_height;
124 canvas->TileImageInt(*background_bitmap(), 0, top_cap_height, 168 canvas->TileImageInt(*background_bitmap(), 0, top_cap_height,
125 background_bitmap()->width(), thumb_body_height); 169 background_bitmap()->width(), thumb_body_height);
126 canvas->DrawBitmapInt(*end_cap_bitmap(), 0, 170 canvas->DrawBitmapInt(*end_cap_bitmap(), 0,
127 height() - bottom_cap_height); 171 height() - bottom_cap_height);
128 172
129 // Paint the grippy over the track. 173 // Paint the grippy over the track.
130 int grippy_x = (width() - grippy_bitmap()->width()) / 2; 174 int grippy_x = (width() - grippy_bitmap()->width()) / 2;
131 int grippy_y = (thumb_body_height - grippy_bitmap()->height()) / 2; 175 int grippy_y = (thumb_body_height - grippy_bitmap()->height()) / 2;
132 canvas->DrawBitmapInt(*grippy_bitmap(), grippy_x, grippy_y); 176 canvas->DrawBitmapInt(*grippy_bitmap(), grippy_x, grippy_y);
133 } 177 }
134 178
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
135 private: 229 private:
136 // Returns the bitmap rendered at the start of the thumb. 230 // Returns the bitmap rendered at the start of the thumb.
137 SkBitmap* start_cap_bitmap() const { 231 SkBitmap* start_cap_bitmap() const {
138 return scroll_bar_->images_[BitmapScrollBar::THUMB_START_CAP][GetState()]; 232 return scroll_bar_->images_[BitmapScrollBar::THUMB_START_CAP][state_];
139 } 233 }
140 234
141 // Returns the bitmap rendered at the end of the thumb. 235 // Returns the bitmap rendered at the end of the thumb.
142 SkBitmap* end_cap_bitmap() const { 236 SkBitmap* end_cap_bitmap() const {
143 return scroll_bar_->images_[BitmapScrollBar::THUMB_END_CAP][GetState()]; 237 return scroll_bar_->images_[BitmapScrollBar::THUMB_END_CAP][state_];
144 } 238 }
145 239
146 // Returns the bitmap that is tiled in the background of the thumb between 240 // Returns the bitmap that is tiled in the background of the thumb between
147 // the start and the end caps. 241 // the start and the end caps.
148 SkBitmap* background_bitmap() const { 242 SkBitmap* background_bitmap() const {
149 return scroll_bar_->images_[BitmapScrollBar::THUMB_MIDDLE][GetState()]; 243 return scroll_bar_->images_[BitmapScrollBar::THUMB_MIDDLE][state_];
150 } 244 }
151 245
152 // Returns the bitmap that is rendered in the middle of the thumb 246 // Returns the bitmap that is rendered in the middle of the thumb
153 // transparently over the background bitmap. 247 // transparently over the background bitmap.
154 SkBitmap* grippy_bitmap() const { 248 SkBitmap* grippy_bitmap() const {
155 return scroll_bar_->images_[BitmapScrollBar::THUMB_GRIPPY] 249 return scroll_bar_->images_[BitmapScrollBar::THUMB_GRIPPY]
156 [CustomButton::BS_NORMAL]; 250 [CustomButton::BS_NORMAL];
157 } 251 }
158 252
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
159 // The BitmapScrollBar that owns us. 259 // The BitmapScrollBar that owns us.
160 BitmapScrollBar* scroll_bar_; 260 BitmapScrollBar* scroll_bar_;
161 261
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
162 DISALLOW_COPY_AND_ASSIGN(BitmapScrollBarThumb); 271 DISALLOW_COPY_AND_ASSIGN(BitmapScrollBarThumb);
163 }; 272 };
164 273
165 } // anonymous namespace 274 } // anonymous namespace
166 275
167 /////////////////////////////////////////////////////////////////////////////// 276 ///////////////////////////////////////////////////////////////////////////////
168 // BitmapScrollBar, public: 277 // BitmapScrollBar, public:
169 278
170 BitmapScrollBar::BitmapScrollBar(bool horizontal, bool show_scroll_buttons) 279 BitmapScrollBar::BitmapScrollBar(bool horizontal, bool show_scroll_buttons)
171 : BaseScrollBar(horizontal, new BitmapScrollBarThumb(this)), 280 : contents_size_(0),
281 contents_scroll_offset_(0),
172 ALLOW_THIS_IN_INITIALIZER_LIST(prev_button_(new AutorepeatButton(this))), 282 ALLOW_THIS_IN_INITIALIZER_LIST(prev_button_(new AutorepeatButton(this))),
173 ALLOW_THIS_IN_INITIALIZER_LIST(next_button_(new AutorepeatButton(this))), 283 ALLOW_THIS_IN_INITIALIZER_LIST(next_button_(new AutorepeatButton(this))),
174 show_scroll_buttons_(show_scroll_buttons) { 284 ALLOW_THIS_IN_INITIALIZER_LIST(thumb_(new BitmapScrollBarThumb(this))),
285 thumb_track_state_(CustomButton::BS_NORMAL),
286 last_scroll_amount_(SCROLL_NONE),
287 ALLOW_THIS_IN_INITIALIZER_LIST(repeater_(
288 NewCallback<BitmapScrollBar>(this,
289 &BitmapScrollBar::TrackClicked))),
290 context_menu_mouse_position_(0),
291 show_scroll_buttons_(show_scroll_buttons),
292 ScrollBar(horizontal) {
175 if (!show_scroll_buttons_) { 293 if (!show_scroll_buttons_) {
176 prev_button_->SetVisible(false); 294 prev_button_->SetVisible(false);
177 next_button_->SetVisible(false); 295 next_button_->SetVisible(false);
178 } 296 }
179 297
180 AddChildView(prev_button_); 298 AddChildView(prev_button_);
181 AddChildView(next_button_); 299 AddChildView(next_button_);
300 AddChildView(thumb_);
182 301
183 set_context_menu_controller(this); 302 set_context_menu_controller(this);
184 prev_button_->set_context_menu_controller(this); 303 prev_button_->set_context_menu_controller(this);
185 next_button_->set_context_menu_controller(this); 304 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;
186 } 323 }
187 324
188 void BitmapScrollBar::SetImage(ScrollBarPart part, 325 void BitmapScrollBar::SetImage(ScrollBarPart part,
189 CustomButton::ButtonState state, 326 CustomButton::ButtonState state,
190 SkBitmap* bitmap) { 327 SkBitmap* bitmap) {
191 DCHECK(part < PART_COUNT); 328 DCHECK(part < PART_COUNT);
192 DCHECK(state < CustomButton::BS_COUNT); 329 DCHECK(state < CustomButton::BS_COUNT);
193 switch (part) { 330 switch (part) {
194 case PREV_BUTTON: 331 case PREV_BUTTON:
195 prev_button_->SetImage(state, bitmap); 332 prev_button_->SetImage(state, bitmap);
196 break; 333 break;
197 case NEXT_BUTTON: 334 case NEXT_BUTTON:
198 next_button_->SetImage(state, bitmap); 335 next_button_->SetImage(state, bitmap);
199 break; 336 break;
200 case THUMB_START_CAP: 337 case THUMB_START_CAP:
201 case THUMB_MIDDLE: 338 case THUMB_MIDDLE:
202 case THUMB_END_CAP: 339 case THUMB_END_CAP:
203 case THUMB_GRIPPY: 340 case THUMB_GRIPPY:
204 case THUMB_TRACK: 341 case THUMB_TRACK:
205 images_[part][state] = bitmap; 342 images_[part][state] = bitmap;
206 break; 343 break;
207 } 344 }
208 } 345 }
209 346
210 int BitmapScrollBar::GetLayoutSize() const { 347 void BitmapScrollBar::ScrollByAmount(ScrollAmount amount) {
211 gfx::Size prefsize = prev_button_->GetPreferredSize(); 348 ScrollBarController* controller = GetController();
212 return IsHorizontal() ? prefsize.height() : prefsize.width(); 349 int offset = contents_scroll_offset_;
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();
213 } 376 }
214 377
215 gfx::Rect BitmapScrollBar::GetTrackBounds() const { 378 void BitmapScrollBar::ScrollToThumbPosition(int thumb_position,
216 gfx::Size prefsize = prev_button_->GetPreferredSize(); 379 bool scroll_to_middle) {
217 if (IsHorizontal()) { 380 contents_scroll_offset_ =
218 if (!show_scroll_buttons_) 381 CalculateContentsOffset(thumb_position, scroll_to_middle);
219 prefsize.set_width(0); 382 if (contents_scroll_offset_ < GetMinPosition()) {
220 int new_width = 383 contents_scroll_offset_ = GetMinPosition();
221 std::max(0, width() - (prefsize.width() * 2)); 384 } else if (contents_scroll_offset_ > GetMaxPosition()) {
222 gfx::Rect track_bounds(prefsize.width(), 0, new_width, prefsize.height()); 385 contents_scroll_offset_ = GetMaxPosition();
223 return track_bounds;
224 } 386 }
225 if (!show_scroll_buttons_) 387 ScrollContentsToOffset();
226 prefsize.set_height(0); 388 SchedulePaint();
227 gfx::Rect track_bounds(0, prefsize.height(), prefsize.width(), 389 }
228 std::max(0, height() - (prefsize.height() * 2))); 390
229 return track_bounds; 391 void BitmapScrollBar::ScrollByContentsOffset(int contents_offset) {
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();
230 } 399 }
231 400
232 /////////////////////////////////////////////////////////////////////////////// 401 ///////////////////////////////////////////////////////////////////////////////
233 // BitmapScrollBar, View implementation: 402 // BitmapScrollBar, View implementation:
234 403
235 gfx::Size BitmapScrollBar::GetPreferredSize() { 404 gfx::Size BitmapScrollBar::GetPreferredSize() {
236 // In this case, we're returning the desired width of the scrollbar and its 405 // In this case, we're returning the desired width of the scrollbar and its
237 // minimum allowable height. 406 // minimum allowable height.
238 gfx::Size button_prefsize = prev_button_->GetPreferredSize(); 407 gfx::Size button_prefsize = prev_button_->GetPreferredSize();
239 return gfx::Size(button_prefsize.width(), button_prefsize.height() * 2); 408 return gfx::Size(button_prefsize.width(), button_prefsize.height() * 2);
(...skipping 10 matching lines...) Expand all
250 prefsize.height()); 419 prefsize.height());
251 } else { 420 } else {
252 next_button_->SetBounds(0, height() - prefsize.height(), prefsize.width(), 421 next_button_->SetBounds(0, height() - prefsize.height(), prefsize.width(),
253 prefsize.height()); 422 prefsize.height());
254 } 423 }
255 } else { 424 } else {
256 prev_button_->SetBounds(0, 0, 0, 0); 425 prev_button_->SetBounds(0, 0, 0, 0);
257 next_button_->SetBounds(0, 0, 0, 0); 426 next_button_->SetBounds(0, 0, 0, 0);
258 } 427 }
259 428
260 BaseScrollBarThumb* thumb = GetThumb();
261 // Size and place the thumb 429 // Size and place the thumb
262 gfx::Size thumb_prefsize = thumb->GetPreferredSize(); 430 gfx::Size thumb_prefsize = thumb_->GetPreferredSize();
263 gfx::Rect track_bounds = GetTrackBounds(); 431 gfx::Rect track_bounds = GetTrackBounds();
264 432
265 // Preserve the height/width of the thumb (depending on orientation) as set 433 // Preserve the height/width of the thumb (depending on orientation) as set
266 // by the last call to |Update|, but coerce the width/height to be the 434 // by the last call to |Update|, but coerce the width/height to be the
267 // appropriate value for the bitmaps provided. 435 // appropriate value for the bitmaps provided.
268 if (IsHorizontal()) { 436 if (IsHorizontal()) {
269 thumb->SetBounds(thumb->x(), thumb->y(), thumb->width(), 437 thumb_->SetBounds(thumb_->x(), thumb_->y(), thumb_->width(),
270 thumb_prefsize.height()); 438 thumb_prefsize.height());
271 } else { 439 } else {
272 thumb->SetBounds(thumb->x(), thumb->y(), thumb_prefsize.width(), 440 thumb_->SetBounds(thumb_->x(), thumb_->y(), thumb_prefsize.width(),
273 thumb->height()); 441 thumb_->height());
274 } 442 }
275 443
276 // Hide the thumb if the track isn't tall enough to display even a tiny 444 // Hide the thumb if the track isn't tall enough to display even a tiny
277 // thumb. The user can only use the mousewheel, scroll buttons or keyboard 445 // thumb. The user can only use the mousewheel, scroll buttons or keyboard
278 // in this scenario. 446 // in this scenario.
279 if ((IsHorizontal() && (track_bounds.width() < thumb_prefsize.width()) || 447 if ((IsHorizontal() && (track_bounds.width() < thumb_prefsize.width()) ||
280 (!IsHorizontal() && (track_bounds.height() < thumb_prefsize.height())))) { 448 (!IsHorizontal() && (track_bounds.height() < thumb_prefsize.height())))) {
281 thumb->SetVisible(false); 449 thumb_->SetVisible(false);
282 } else if (!thumb->IsVisible()) { 450 } else if (!thumb_->IsVisible()) {
283 thumb->SetVisible(true); 451 thumb_->SetVisible(true);
284 } 452 }
285 } 453 }
286 454
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
287 /////////////////////////////////////////////////////////////////////////////// 531 ///////////////////////////////////////////////////////////////////////////////
288 // BitmapScrollBar, View implementation: 532 // BitmapScrollBar, ContextMenuController implementation:
289 533
290 void BitmapScrollBar::OnPaint(gfx::Canvas* canvas) { 534 enum ScrollBarContextMenuCommands {
291 // Paint the track. 535 ScrollBarContextMenuCommand_ScrollHere = 1,
292 gfx::Rect track_bounds = GetTrackBounds(); 536 ScrollBarContextMenuCommand_ScrollStart,
293 canvas->TileImageInt(*images_[THUMB_TRACK][GetThumbTrackState()], 537 ScrollBarContextMenuCommand_ScrollEnd,
294 track_bounds.x(), track_bounds.y(), 538 ScrollBarContextMenuCommand_ScrollPageUp,
295 track_bounds.width(), track_bounds.height()); 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 }
296 } 639 }
297 640
298 /////////////////////////////////////////////////////////////////////////////// 641 ///////////////////////////////////////////////////////////////////////////////
299 // BitmapScrollBar, ButtonListener implementation: 642 // BitmapScrollBar, ButtonListener implementation:
300 643
301 void BitmapScrollBar::ButtonPressed(Button* sender, const views::Event& event) { 644 void BitmapScrollBar::ButtonPressed(Button* sender, const views::Event& event) {
302 if (sender == prev_button_) { 645 if (sender == prev_button_) {
303 ScrollByAmount(SCROLL_PREV_LINE); 646 ScrollByAmount(SCROLL_PREV_LINE);
304 } else if (sender == next_button_) { 647 } else if (sender == next_button_) {
305 ScrollByAmount(SCROLL_NEXT_LINE); 648 ScrollByAmount(SCROLL_NEXT_LINE);
306 } 649 }
307 } 650 }
308 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 ///////////////////////////////////////////////////////////////////////////////
691 // BitmapScrollBar, View implementation:
692
693 void BitmapScrollBar::OnPaint(gfx::Canvas* canvas) {
694 // Paint the track.
695 gfx::Rect track_bounds = GetTrackBounds();
696 canvas->TileImageInt(*images_[THUMB_TRACK][thumb_track_state_],
697 track_bounds.x(), track_bounds.y(),
698 track_bounds.width(), track_bounds.height());
699 }
700
701 ///////////////////////////////////////////////////////////////////////////////
702 // BitmapScrollBar, private:
703
704 void BitmapScrollBar::TrackClicked() {
705 if (last_scroll_amount_ != SCROLL_NONE)
706 ScrollByAmount(last_scroll_amount_);
707 }
708
709 void BitmapScrollBar::ScrollContentsToOffset() {
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 }
734
309 } // namespace views 735 } // namespace views
OLDNEW
« no previous file with comments | « views/controls/scrollbar/bitmap_scroll_bar.h ('k') | views/controls/scrollbar/native_scroll_bar_gtk.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698