Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "views/controls/scrollbar/native_scroll_bar_views.h" | |
| 6 | |
| 7 #include "base/logging.h" | |
| 8 #include "ui/base/keycodes/keyboard_codes.h" | |
| 9 #include "ui/gfx/canvas.h" | |
| 10 #include "ui/gfx/canvas_skia.h" | |
| 11 #include "ui/gfx/path.h" | |
| 12 #include "views/controls/button/custom_button.h" | |
| 13 #include "views/controls/focusable_border.h" | |
| 14 #include "views/controls/scrollbar/native_scroll_bar.h" | |
| 15 #include "views/controls/scrollbar/scroll_bar.h" | |
| 16 | |
| 17 namespace views { | |
| 18 | |
| 19 namespace { | |
| 20 | |
| 21 // Wrapper for the scroll buttons. | |
| 22 class ScrollBarButton : public CustomButton { | |
|
Ben Goodger (Google)
2011/08/19 17:44:33
Rather than reinvent the wheel here I'd rather you
| |
| 23 public: | |
| 24 enum Type { | |
| 25 UP, | |
| 26 DOWN, | |
| 27 LEFT, | |
| 28 RIGHT, | |
| 29 }; | |
| 30 | |
| 31 ScrollBarButton(ButtonListener* listener, Type type); | |
| 32 virtual ~ScrollBarButton(); | |
| 33 | |
| 34 virtual gfx::Size GetPreferredSize() OVERRIDE; | |
| 35 | |
| 36 protected: | |
| 37 virtual bool OnMousePressed(const MouseEvent& event) OVERRIDE; | |
| 38 virtual void OnMouseReleased(const MouseEvent& event) OVERRIDE; | |
| 39 virtual void OnMouseEntered(const MouseEvent& event) OVERRIDE; | |
| 40 virtual void OnMouseExited(const MouseEvent& event) OVERRIDE; | |
| 41 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; | |
| 42 | |
| 43 private: | |
| 44 gfx::NativeTheme::ExtraParams params_; | |
| 45 gfx::NativeTheme::Part part_; | |
| 46 gfx::NativeTheme::State state_; | |
| 47 }; | |
| 48 | |
| 49 } // namespace | |
| 50 | |
| 51 // Wrapper for the scroll thumb | |
| 52 class ScrollBarThumb : public View { | |
| 53 public: | |
| 54 enum Type { | |
| 55 VERTICAL, | |
| 56 HORIZONTAL, | |
| 57 }; | |
| 58 | |
| 59 ScrollBarThumb(NativeScrollBarWrapper* wrapper, Type type); | |
| 60 virtual ~ScrollBarThumb(); | |
| 61 | |
| 62 virtual gfx::Size GetPreferredSize() OVERRIDE; | |
| 63 | |
| 64 void Update(int position); | |
| 65 void Update(int viewport_size, int content_size, int position); | |
| 66 | |
| 67 int current_position() const { return current_position_; } | |
| 68 | |
| 69 // This is called when the layout changes and the scrollbar changes | |
| 70 // size. | |
| 71 void set_track_bounds(const gfx::Rect& bounds) { track_bounds_ = bounds; } | |
| 72 | |
| 73 protected: | |
| 74 virtual bool OnMousePressed(const MouseEvent& event) OVERRIDE; | |
| 75 virtual bool OnMouseDragged(const MouseEvent& event) OVERRIDE; | |
| 76 virtual void OnMouseEntered(const MouseEvent& event) OVERRIDE; | |
| 77 virtual void OnMouseExited(const MouseEvent& event) OVERRIDE; | |
| 78 virtual void OnMouseMoved(const MouseEvent& event) OVERRIDE; | |
| 79 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; | |
| 80 | |
| 81 private: | |
| 82 // Converts the position of the thumb to the pixel size of the thumb | |
| 83 // relative to the size of the drawing area. | |
| 84 int GetThumbPosition(int drawing_size) const; | |
| 85 | |
| 86 // Returns the size of the thumb relative to the drawing area size. | |
| 87 int GetThumbSize(int drawing_size) const; | |
| 88 | |
| 89 NativeScrollBarWrapper* wrapper_; | |
| 90 | |
| 91 Type type_; | |
| 92 | |
| 93 // The current position of the thumb. | |
| 94 int current_position_; | |
| 95 | |
| 96 // The size of the content we want to display. | |
| 97 int content_size_; | |
| 98 // The size of the viewport (displayable area). | |
| 99 int viewport_size_; | |
| 100 | |
| 101 // The track bounds. We need this to compute the size of the thumb relative | |
| 102 // to the size of the track. | |
| 103 gfx::Rect track_bounds_; | |
| 104 | |
| 105 // The distance from the tip of the thumb. Used when dragging to keep the | |
| 106 // position of the thumb at the same relative distance from the mouse click | |
| 107 // event. | |
| 108 int delta_; | |
| 109 | |
| 110 // Parameters required for the native theme. We keep these here since | |
| 111 // we may change them based on mouse events (hover, click, ...). | |
| 112 gfx::NativeTheme::ExtraParams params_; | |
| 113 gfx::NativeTheme::Part part_; | |
| 114 gfx::NativeTheme::State state_; | |
| 115 }; | |
| 116 | |
| 117 namespace { | |
| 118 | |
| 119 ///////////////////////////////////////////////////////////////////////////// | |
| 120 // ScrollBarButton | |
| 121 | |
| 122 ScrollBarButton::ScrollBarButton(ButtonListener* listener, Type type) | |
| 123 : CustomButton(listener), | |
| 124 params_(), | |
| 125 state_(gfx::NativeTheme::kNormal) { | |
| 126 switch (type) { | |
| 127 case UP: | |
| 128 part_ = gfx::NativeTheme::kScrollbarUpArrow; | |
| 129 break; | |
| 130 case DOWN: | |
| 131 part_ = gfx::NativeTheme::kScrollbarDownArrow; | |
| 132 break; | |
| 133 case LEFT: | |
| 134 part_ = gfx::NativeTheme::kScrollbarLeftArrow; | |
| 135 break; | |
| 136 case RIGHT: | |
| 137 part_ = gfx::NativeTheme::kScrollbarRightArrow; | |
| 138 break; | |
| 139 } | |
| 140 | |
| 141 params_.scrollbar_arrow.is_hovering = false; | |
| 142 } | |
| 143 | |
| 144 ScrollBarButton::~ScrollBarButton() { | |
| 145 } | |
| 146 | |
| 147 gfx::Size ScrollBarButton::GetPreferredSize() { | |
| 148 const gfx::NativeTheme* native_theme = gfx::NativeTheme::instance(); | |
| 149 return native_theme->GetPartSize(part_, state_, params_); | |
| 150 } | |
| 151 | |
| 152 bool ScrollBarButton::OnMousePressed(const MouseEvent& event) { | |
| 153 if (event.IsOnlyLeftMouseButton()) | |
| 154 Button::NotifyClick(event); | |
| 155 return true; | |
| 156 } | |
| 157 | |
| 158 void ScrollBarButton::OnMouseReleased(const MouseEvent& event) { | |
| 159 } | |
| 160 | |
| 161 void ScrollBarButton::OnMouseEntered(const MouseEvent& event) { | |
| 162 state_ = gfx::NativeTheme::kHovered; | |
| 163 params_.scrollbar_arrow.is_hovering = true; | |
| 164 SchedulePaint(); | |
| 165 } | |
| 166 | |
| 167 void ScrollBarButton::OnMouseExited(const MouseEvent& event) { | |
| 168 state_ = gfx::NativeTheme::kNormal; | |
| 169 params_.scrollbar_arrow.is_hovering = false; | |
| 170 SchedulePaint(); | |
| 171 } | |
| 172 | |
| 173 void ScrollBarButton::OnPaint(gfx::Canvas* canvas) { | |
| 174 const gfx::NativeTheme* native_theme = gfx::NativeTheme::instance(); | |
| 175 gfx::Rect bounds; | |
| 176 bounds.set_size(GetPreferredSize()); | |
| 177 | |
| 178 native_theme->Paint(canvas->AsCanvasSkia(), | |
| 179 part_, | |
| 180 state_, | |
| 181 bounds, | |
| 182 params_); | |
| 183 } | |
| 184 | |
| 185 } // namespace | |
| 186 | |
| 187 ///////////////////////////////////////////////////////////////////////////// | |
| 188 // ScrollBarThumb | |
| 189 | |
| 190 ScrollBarThumb::ScrollBarThumb(NativeScrollBarWrapper* wrapper, Type type) | |
| 191 : wrapper_(wrapper), | |
| 192 type_(type), | |
| 193 state_(gfx::NativeTheme::kNormal) { | |
| 194 switch (type) { | |
| 195 case VERTICAL: | |
| 196 part_ = gfx::NativeTheme::kScrollbarVerticalThumb; | |
| 197 break; | |
| 198 case HORIZONTAL: | |
| 199 part_ = gfx::NativeTheme::kScrollbarHorizontalThumb; | |
| 200 break; | |
| 201 } | |
| 202 params_.scrollbar_thumb.is_hovering = false; | |
| 203 } | |
| 204 | |
| 205 ScrollBarThumb::~ScrollBarThumb() { | |
| 206 } | |
| 207 | |
| 208 gfx::Size ScrollBarThumb::GetPreferredSize() { | |
| 209 const gfx::NativeTheme* native_theme = gfx::NativeTheme::instance(); | |
| 210 return native_theme->GetPartSize(part_, state_, params_); | |
| 211 } | |
| 212 | |
| 213 void ScrollBarThumb::Update(int position) { | |
| 214 Update(viewport_size_, content_size_, position); | |
| 215 } | |
| 216 | |
| 217 void ScrollBarThumb::Update(int viewport_size, | |
| 218 int content_size, | |
| 219 int position) { | |
| 220 // First constrain the size and position to the actual values used by the | |
| 221 // scrollbar. | |
| 222 if (content_size < 0) | |
| 223 content_size = 0; | |
| 224 | |
| 225 if (position < 0) | |
| 226 position = 0; | |
| 227 | |
| 228 if (position > content_size - viewport_size) | |
| 229 position = content_size - viewport_size; | |
| 230 | |
| 231 current_position_ = position; | |
| 232 content_size_ = content_size; | |
| 233 viewport_size_ = viewport_size; | |
| 234 | |
| 235 gfx::Rect bounds = GetLocalBounds(); | |
| 236 | |
| 237 if (type_ == HORIZONTAL) { | |
| 238 bounds.set_x(track_bounds_.x() + | |
| 239 GetThumbPosition(track_bounds_.width())); | |
| 240 bounds.set_width(GetThumbSize(track_bounds_.width())); | |
| 241 } else { | |
| 242 bounds.set_y(track_bounds_.y() + | |
| 243 GetThumbPosition(track_bounds_.height())); | |
| 244 bounds.set_height(GetThumbSize(track_bounds_.height())); | |
| 245 } | |
| 246 | |
| 247 // Update the position and size of the thumb. | |
| 248 SetBoundsRect(bounds); | |
| 249 | |
| 250 SchedulePaint(); | |
| 251 } | |
| 252 | |
| 253 bool ScrollBarThumb::OnMousePressed(const MouseEvent& event) { | |
| 254 if (!event.IsOnlyLeftMouseButton()) | |
| 255 return false; | |
| 256 | |
| 257 // Keep the distance from the tip of the thumb so that scrolling movement | |
| 258 // looks nice. (We want events relative to the mouse click.) | |
| 259 if (type_ == HORIZONTAL) { | |
| 260 int track_size = track_bounds_.width(); | |
| 261 delta_ = -event.x() * content_size_ / track_size; | |
| 262 } else { | |
| 263 int track_size = track_bounds_.height(); | |
| 264 delta_ = -event.y() * content_size_ / track_size; | |
| 265 } | |
| 266 | |
| 267 return true; | |
| 268 } | |
| 269 | |
| 270 | |
| 271 bool ScrollBarThumb::OnMouseDragged(const MouseEvent& event) { | |
| 272 // Let the scrollbar wrapper know that we're changing the current position. | |
| 273 // It should then all for UI updates. | |
| 274 if (type_ == HORIZONTAL) { | |
| 275 int track_size = track_bounds_.width(); | |
| 276 wrapper_->Update(viewport_size_, | |
| 277 content_size_, | |
| 278 current_position_ + delta_ + | |
| 279 event.x() * content_size_ / track_size); | |
| 280 } else { | |
| 281 int track_size = track_bounds_.height(); | |
| 282 wrapper_->Update(viewport_size_, | |
| 283 content_size_, | |
| 284 current_position_ + delta_ + | |
| 285 event.y() * content_size_ / track_size); | |
| 286 } | |
| 287 | |
| 288 return true; | |
| 289 } | |
| 290 | |
| 291 void ScrollBarThumb::OnMouseEntered(const MouseEvent& event) { | |
| 292 if (state_ != gfx::NativeTheme::kHovered) { | |
| 293 state_ = gfx::NativeTheme::kHovered; | |
| 294 params_.scrollbar_thumb.is_hovering = true; | |
| 295 SchedulePaint(); | |
| 296 } | |
| 297 } | |
| 298 | |
| 299 void ScrollBarThumb::OnMouseExited(const MouseEvent& event) { | |
| 300 if (state_ != gfx::NativeTheme::kNormal) { | |
| 301 state_ = gfx::NativeTheme::kNormal; | |
| 302 params_.scrollbar_thumb.is_hovering = false; | |
| 303 SchedulePaint(); | |
| 304 } | |
| 305 } | |
| 306 | |
| 307 void ScrollBarThumb::OnMouseMoved(const MouseEvent& event) { | |
| 308 OnMouseEntered(event); | |
| 309 } | |
| 310 | |
| 311 void ScrollBarThumb::OnPaint(gfx::Canvas* canvas) { | |
| 312 const gfx::NativeTheme* native_theme = gfx::NativeTheme::instance(); | |
| 313 | |
| 314 native_theme->Paint(canvas->AsCanvasSkia(), | |
| 315 part_, | |
| 316 state_, | |
| 317 GetLocalBounds(), | |
| 318 params_); | |
| 319 } | |
| 320 | |
| 321 int ScrollBarThumb::GetThumbSize(int drawing_size) const { | |
| 322 return (viewport_size_ * drawing_size) / | |
| 323 (content_size_ ? content_size_ : 1); | |
| 324 } | |
| 325 | |
| 326 int ScrollBarThumb::GetThumbPosition(int drawing_size) const { | |
| 327 return (current_position_ * drawing_size) / | |
| 328 (content_size_ ? content_size_ : 1); | |
| 329 } | |
| 330 | |
| 331 //////////////////////////////////////////////////////////////////////////////// | |
| 332 // NativeScrollBarViews, public: | |
| 333 | |
| 334 NativeScrollBarViews::NativeScrollBarViews(NativeScrollBar* scroll_bar) | |
| 335 : native_scroll_bar_(scroll_bar) { | |
| 336 if (native_scroll_bar_->IsHorizontal()) { | |
| 337 prev_button_ = new ScrollBarButton(this, ScrollBarButton::LEFT); | |
| 338 next_button_ = new ScrollBarButton(this, ScrollBarButton::RIGHT); | |
| 339 thumb_ = new ScrollBarThumb(this, ScrollBarThumb::HORIZONTAL); | |
| 340 | |
| 341 part_ = gfx::NativeTheme::kScrollbarHorizontalTrack; | |
| 342 } else { | |
| 343 prev_button_ = new ScrollBarButton(this, ScrollBarButton::UP); | |
| 344 next_button_ = new ScrollBarButton(this, ScrollBarButton::DOWN); | |
| 345 thumb_ = new ScrollBarThumb(this, ScrollBarThumb::VERTICAL); | |
| 346 | |
| 347 part_ = gfx::NativeTheme::kScrollbarVerticalTrack; | |
| 348 } | |
| 349 | |
| 350 state_ = gfx::NativeTheme::kNormal; | |
| 351 | |
| 352 AddChildView(prev_button_); | |
| 353 AddChildView(next_button_); | |
| 354 AddChildView(thumb_); | |
| 355 } | |
| 356 | |
| 357 NativeScrollBarViews::~NativeScrollBarViews() { | |
| 358 } | |
| 359 | |
| 360 //////////////////////////////////////////////////////////////////////////////// | |
| 361 // NativeScrollBarViews, View overrides: | |
| 362 | |
| 363 void NativeScrollBarViews::Layout() { | |
| 364 SetBoundsRect(native_scroll_bar_->GetLocalBounds()); | |
| 365 | |
| 366 gfx::Size size = prev_button_->GetPreferredSize(); | |
| 367 prev_button_->SetBounds(0, 0, size.width(), size.height()); | |
| 368 | |
| 369 if (native_scroll_bar_->IsHorizontal()) { | |
| 370 next_button_->SetBounds(width() - size.width(), 0, | |
| 371 size.width(), size.height()); | |
| 372 } else { | |
| 373 next_button_->SetBounds(0, height() - size.height(), | |
| 374 size.width(), size.height()); | |
| 375 } | |
| 376 | |
| 377 // Update the size of the thumb and tell it that the track size also changed. | |
| 378 thumb_->set_track_bounds(GetTrackBounds()); | |
| 379 thumb_->SetBoundsRect(GetTrackBounds()); | |
| 380 } | |
| 381 | |
| 382 gfx::Size NativeScrollBarViews::GetPreferredSize() { | |
| 383 if (native_scroll_bar_->IsHorizontal()) | |
| 384 return gfx::Size(0, GetHorizontalScrollBarHeight()); | |
| 385 return gfx::Size(GetVerticalScrollBarWidth(), 0); | |
| 386 } | |
| 387 | |
| 388 // TODO(oshima|jcampan): key/mouse events are not delievered and | |
| 389 // the following code is not tested. It requires the focus manager to be fully | |
| 390 // implemented. | |
| 391 bool NativeScrollBarViews::OnKeyPressed(const KeyEvent& event) { | |
| 392 switch (event.key_code()) { | |
| 393 case ui::VKEY_UP: | |
| 394 if (!native_scroll_bar_->IsHorizontal()) | |
| 395 MoveStep(false /* negative */); | |
| 396 break; | |
| 397 case ui::VKEY_DOWN: | |
| 398 if (!native_scroll_bar_->IsHorizontal()) | |
| 399 MoveStep(true /* positive */); | |
| 400 break; | |
| 401 case ui::VKEY_LEFT: | |
| 402 if (native_scroll_bar_->IsHorizontal()) | |
| 403 MoveStep(false /* negative */); | |
| 404 break; | |
| 405 case ui::VKEY_RIGHT: | |
| 406 if (native_scroll_bar_->IsHorizontal()) | |
| 407 MoveStep(true /* positive */); | |
| 408 break; | |
| 409 case ui::VKEY_PRIOR: | |
| 410 MovePage(false /* negative */); | |
| 411 break; | |
| 412 case ui::VKEY_NEXT: | |
| 413 MovePage(true /* positive */); | |
| 414 break; | |
| 415 case ui::VKEY_HOME: | |
| 416 MoveTo(0); | |
| 417 break; | |
| 418 case ui::VKEY_END: | |
| 419 MoveToBottom(); | |
| 420 break; | |
| 421 default: | |
| 422 return false; | |
| 423 } | |
| 424 return true; | |
| 425 } | |
| 426 | |
| 427 bool NativeScrollBarViews::OnMousePressed(const MouseEvent& event) { | |
| 428 if (!event.IsOnlyLeftMouseButton()) | |
| 429 return true; | |
| 430 | |
| 431 if (native_scroll_bar_->IsHorizontal()) { | |
| 432 if (event.x() < thumb_->bounds().x()) | |
| 433 MovePage(false); | |
| 434 else | |
| 435 MovePage(true); | |
| 436 } else { | |
| 437 if (event.y() < thumb_->bounds().y()) | |
| 438 MovePage(false); | |
| 439 else | |
| 440 MovePage(true); | |
| 441 } | |
| 442 | |
| 443 return true; | |
| 444 } | |
| 445 | |
| 446 void NativeScrollBarViews::OnMouseEntered(const MouseEvent& event) { | |
| 447 state_ = gfx::NativeTheme::kHovered; | |
| 448 SchedulePaint(); | |
| 449 } | |
| 450 | |
| 451 void NativeScrollBarViews::OnMouseExited(const MouseEvent& event) { | |
| 452 state_ = gfx::NativeTheme::kNormal; | |
| 453 SchedulePaint(); | |
| 454 } | |
| 455 | |
| 456 bool NativeScrollBarViews::OnMouseWheel(const MouseWheelEvent& e) { | |
| 457 MoveBy(-e.offset()); // e.GetOffset() > 0 means scroll up. | |
| 458 return true; | |
| 459 } | |
| 460 | |
| 461 void NativeScrollBarViews::OnPaint(gfx::Canvas* canvas) { | |
| 462 const gfx::NativeTheme* native_theme = gfx::NativeTheme::instance(); | |
| 463 gfx::Rect bounds = GetTrackBounds(); | |
| 464 | |
| 465 params_.scrollbar_track.track_x = bounds.x(); | |
| 466 params_.scrollbar_track.track_y = bounds.y(); | |
| 467 params_.scrollbar_track.track_width = bounds.width(); | |
| 468 params_.scrollbar_track.track_height = bounds.height(); | |
| 469 | |
| 470 | |
| 471 native_theme->Paint(canvas->AsCanvasSkia(), | |
| 472 part_, | |
| 473 state_, | |
| 474 bounds, | |
| 475 params_); | |
| 476 } | |
| 477 | |
| 478 void NativeScrollBarViews::ButtonPressed(Button* sender, | |
| 479 const views::Event& event) { | |
| 480 if (sender == prev_button_) { | |
| 481 MoveStep(false); | |
| 482 } else if (sender == next_button_) { | |
| 483 MoveStep(true); | |
| 484 } | |
| 485 } | |
| 486 | |
| 487 //////////////////////////////////////////////////////////////////////////////// | |
| 488 // NativeScrollBarViews, NativeScrollBarWrapper overrides: | |
| 489 | |
| 490 int NativeScrollBarViews::GetPosition() const { | |
| 491 return thumb_->current_position(); | |
| 492 } | |
| 493 | |
| 494 View* NativeScrollBarViews::GetView() { | |
| 495 return this; | |
| 496 } | |
| 497 | |
| 498 void NativeScrollBarViews::Update(int viewport_size, | |
| 499 int content_size, | |
| 500 int current_pos) { | |
| 501 thumb_->Update(viewport_size, content_size, current_pos); | |
| 502 | |
| 503 ValueChanged(); | |
| 504 } | |
| 505 | |
| 506 //////////////////////////////////////////////////////////////////////////////// | |
| 507 // NativeScrollBarViews, private: | |
| 508 | |
| 509 void NativeScrollBarViews::ValueChanged() { | |
| 510 ScrollBarController* controller = native_scroll_bar_->GetController(); | |
| 511 controller->ScrollToPosition(native_scroll_bar_, GetPosition()); | |
| 512 } | |
| 513 | |
| 514 void NativeScrollBarViews::MoveBy(int o) { | |
| 515 MoveTo(GetPosition() + o); | |
| 516 } | |
| 517 | |
| 518 void NativeScrollBarViews::MovePage(bool positive) { | |
| 519 ScrollBarController* controller = native_scroll_bar_->GetController(); | |
| 520 int scroll_increment = controller->GetScrollIncrement(native_scroll_bar_, | |
| 521 true, | |
| 522 positive); | |
| 523 if (!positive) | |
| 524 scroll_increment *= -1; | |
| 525 | |
| 526 MoveBy(scroll_increment); | |
| 527 } | |
| 528 | |
| 529 void NativeScrollBarViews::MoveStep(bool positive) { | |
| 530 ScrollBarController* controller = native_scroll_bar_->GetController(); | |
| 531 int scroll_increment = controller->GetScrollIncrement(native_scroll_bar_, | |
| 532 false, | |
| 533 positive); | |
| 534 if (!positive) | |
| 535 scroll_increment *= -1; | |
| 536 | |
| 537 MoveBy(scroll_increment); | |
| 538 } | |
| 539 | |
| 540 void NativeScrollBarViews::MoveTo(int p) { | |
| 541 if (p < native_scroll_bar_->GetMinPosition()) | |
| 542 p = native_scroll_bar_->GetMinPosition(); | |
| 543 if (p > native_scroll_bar_->GetMaxPosition()) | |
| 544 p = native_scroll_bar_->GetMaxPosition(); | |
| 545 | |
| 546 thumb_->Update(p); | |
| 547 ValueChanged(); | |
| 548 } | |
| 549 | |
| 550 void NativeScrollBarViews::MoveToBottom() { | |
| 551 MoveTo(native_scroll_bar_->GetMaxPosition()); | |
| 552 } | |
| 553 | |
| 554 gfx::Rect NativeScrollBarViews::GetTrackBounds() const { | |
| 555 gfx::Rect bounds = GetLocalBounds(); | |
| 556 gfx::Size size = prev_button_->GetPreferredSize(); | |
| 557 | |
| 558 if (native_scroll_bar_->IsHorizontal()) { | |
| 559 bounds.set_x(bounds.x() + size.width()); | |
| 560 bounds.set_width(bounds.width() - 2 * size.width()); | |
| 561 bounds.set_height(thumb_->GetPreferredSize().height()); | |
| 562 } else { | |
| 563 bounds.set_y(bounds.y() + size.height()); | |
| 564 bounds.set_height(bounds.height() - 2 * size.height()); | |
| 565 bounds.set_width(thumb_->GetPreferredSize().width()); | |
| 566 } | |
| 567 | |
| 568 return bounds; | |
| 569 } | |
| 570 | |
| 571 } // namespace views | |
| OLD | NEW |