summaryrefslogtreecommitdiffstats
path: root/views/controls
diff options
context:
space:
mode:
authorjbates@chromium.org <jbates@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-25 16:21:57 +0000
committerjbates@chromium.org <jbates@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-25 16:21:57 +0000
commitb751a2144e028ac6c069416a9d074dd06bbb37fa (patch)
tree44663e484b29322b9dae108939e91fda5393dd70 /views/controls
parentd7a2c3c554dbdc1e6b951342d6f65801fe0a63cd (diff)
downloadchromium_src-b751a2144e028ac6c069416a9d074dd06bbb37fa.zip
chromium_src-b751a2144e028ac6c069416a9d074dd06bbb37fa.tar.gz
chromium_src-b751a2144e028ac6c069416a9d074dd06bbb37fa.tar.bz2
Revert 98236 - Adding a Views scrollbar implementation.
BUG= TEST=Verified basic functionality using views_examples. Review URL: http://codereview.chromium.org/7669028 Patch from Daniel Nicoara <dnicoara@chromium.org>. TBR=backer@chromium.org Review URL: http://codereview.chromium.org/7749007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@98246 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'views/controls')
-rw-r--r--views/controls/scrollbar/base_scroll_bar.cc383
-rw-r--r--views/controls/scrollbar/base_scroll_bar.h156
-rw-r--r--views/controls/scrollbar/base_scroll_bar_button.cc47
-rw-r--r--views/controls/scrollbar/base_scroll_bar_button.h50
-rw-r--r--views/controls/scrollbar/base_scroll_bar_thumb.cc127
-rw-r--r--views/controls/scrollbar/base_scroll_bar_thumb.h82
-rw-r--r--views/controls/scrollbar/bitmap_scroll_bar.cc512
-rw-r--r--views/controls/scrollbar/bitmap_scroll_bar.h130
-rw-r--r--views/controls/scrollbar/native_scroll_bar_gtk.cc6
-rw-r--r--views/controls/scrollbar/native_scroll_bar_views.cc371
-rw-r--r--views/controls/scrollbar/native_scroll_bar_views.h76
-rw-r--r--views/controls/scrollbar/scrollbar_unittest.cc150
12 files changed, 588 insertions, 1502 deletions
diff --git a/views/controls/scrollbar/base_scroll_bar.cc b/views/controls/scrollbar/base_scroll_bar.cc
deleted file mode 100644
index d18d4fd..0000000
--- a/views/controls/scrollbar/base_scroll_bar.cc
+++ /dev/null
@@ -1,383 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "views/controls/scrollbar/base_scroll_bar.h"
-
-#if defined(OS_LINUX)
-#include "ui/gfx/screen.h"
-#endif
-
-#include "base/callback.h"
-#include "base/compiler_specific.h"
-#include "base/message_loop.h"
-#include "base/string16.h"
-#include "base/utf_string_conversions.h"
-#include "grit/ui_strings.h"
-#include "ui/base/keycodes/keyboard_codes.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "ui/gfx/canvas.h"
-#include "views/controls/menu/menu.h"
-#include "views/controls/scrollbar/base_scroll_bar_thumb.h"
-#include "views/controls/scroll_view.h"
-#include "views/widget/widget.h"
-
-#undef min
-#undef max
-
-namespace views {
-
-///////////////////////////////////////////////////////////////////////////////
-// BaseScrollBar, public:
-
-BaseScrollBar::BaseScrollBar(bool horizontal, BaseScrollBarThumb* thumb)
- : ScrollBar(horizontal),
- thumb_(thumb),
- contents_size_(0),
- contents_scroll_offset_(0),
- thumb_track_state_(CustomButton::BS_NORMAL),
- last_scroll_amount_(SCROLL_NONE),
- ALLOW_THIS_IN_INITIALIZER_LIST(repeater_(
- NewCallback<BaseScrollBar>(this,
- &BaseScrollBar::TrackClicked))),
- context_menu_mouse_position_(0) {
- AddChildView(thumb_);
-
- set_context_menu_controller(this);
- thumb_->set_context_menu_controller(this);
-}
-
-void BaseScrollBar::ScrollByAmount(ScrollAmount amount) {
- int offset = contents_scroll_offset_;
- switch (amount) {
- case SCROLL_START:
- offset = GetMinPosition();
- break;
- case SCROLL_END:
- offset = GetMaxPosition();
- break;
- case SCROLL_PREV_LINE:
- offset -= GetScrollIncrement(false, false);
- offset = std::max(GetMinPosition(), offset);
- break;
- case SCROLL_NEXT_LINE:
- offset += GetScrollIncrement(false, true);
- offset = std::min(GetMaxPosition(), offset);
- break;
- case SCROLL_PREV_PAGE:
- offset -= GetScrollIncrement(true, false);
- offset = std::max(GetMinPosition(), offset);
- break;
- case SCROLL_NEXT_PAGE:
- offset += GetScrollIncrement(true, true);
- offset = std::min(GetMaxPosition(), offset);
- break;
- default:
- break;
- }
- contents_scroll_offset_ = offset;
- ScrollContentsToOffset();
-}
-
-void BaseScrollBar::ScrollToThumbPosition(int thumb_position,
- bool scroll_to_middle) {
- contents_scroll_offset_ =
- CalculateContentsOffset(thumb_position, scroll_to_middle);
- if (contents_scroll_offset_ < GetMinPosition()) {
- contents_scroll_offset_ = GetMinPosition();
- } else if (contents_scroll_offset_ > GetMaxPosition()) {
- contents_scroll_offset_ = GetMaxPosition();
- }
- ScrollContentsToOffset();
- SchedulePaint();
-}
-
-void BaseScrollBar::ScrollByContentsOffset(int contents_offset) {
- contents_scroll_offset_ -= contents_offset;
- if (contents_scroll_offset_ < GetMinPosition()) {
- contents_scroll_offset_ = GetMinPosition();
- } else if (contents_scroll_offset_ > GetMaxPosition()) {
- contents_scroll_offset_ = GetMaxPosition();
- }
- ScrollContentsToOffset();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// BaseScrollBar, View implementation:
-
-bool BaseScrollBar::OnMousePressed(const MouseEvent& event) {
- if (event.IsOnlyLeftMouseButton()) {
- SetThumbTrackState(CustomButton::BS_PUSHED);
- gfx::Rect thumb_bounds = thumb_->bounds();
- if (IsHorizontal()) {
- if (event.x() < thumb_bounds.x()) {
- last_scroll_amount_ = SCROLL_PREV_PAGE;
- } else if (event.x() > thumb_bounds.right()) {
- last_scroll_amount_ = SCROLL_NEXT_PAGE;
- }
- } else {
- if (event.y() < thumb_bounds.y()) {
- last_scroll_amount_ = SCROLL_PREV_PAGE;
- } else if (event.y() > thumb_bounds.bottom()) {
- last_scroll_amount_ = SCROLL_NEXT_PAGE;
- }
- }
- TrackClicked();
- repeater_.Start();
- }
- return true;
-}
-
-void BaseScrollBar::OnMouseReleased(const MouseEvent& event) {
- OnMouseCaptureLost();
-}
-
-void BaseScrollBar::OnMouseCaptureLost() {
- SetThumbTrackState(CustomButton::BS_NORMAL);
- repeater_.Stop();
-}
-
-bool BaseScrollBar::OnKeyPressed(const KeyEvent& event) {
- ScrollAmount amount = SCROLL_NONE;
- switch (event.key_code()) {
- case ui::VKEY_UP:
- if (!IsHorizontal())
- amount = SCROLL_PREV_LINE;
- break;
- case ui::VKEY_DOWN:
- if (!IsHorizontal())
- amount = SCROLL_NEXT_LINE;
- break;
- case ui::VKEY_LEFT:
- if (IsHorizontal())
- amount = SCROLL_PREV_LINE;
- break;
- case ui::VKEY_RIGHT:
- if (IsHorizontal())
- amount = SCROLL_NEXT_LINE;
- break;
- case ui::VKEY_PRIOR:
- amount = SCROLL_PREV_PAGE;
- break;
- case ui::VKEY_NEXT:
- amount = SCROLL_NEXT_PAGE;
- break;
- case ui::VKEY_HOME:
- amount = SCROLL_START;
- break;
- case ui::VKEY_END:
- amount = SCROLL_END;
- break;
- default:
- break;
- }
- if (amount != SCROLL_NONE) {
- ScrollByAmount(amount);
- return true;
- }
- return false;
-}
-
-bool BaseScrollBar::OnMouseWheel(const MouseWheelEvent& event) {
- ScrollByContentsOffset(event.offset());
- return true;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// BaseScrollBar, ContextMenuController implementation:
-
-enum ScrollBarContextMenuCommands {
- ScrollBarContextMenuCommand_ScrollHere = 1,
- ScrollBarContextMenuCommand_ScrollStart,
- ScrollBarContextMenuCommand_ScrollEnd,
- ScrollBarContextMenuCommand_ScrollPageUp,
- ScrollBarContextMenuCommand_ScrollPageDown,
- ScrollBarContextMenuCommand_ScrollPrev,
- ScrollBarContextMenuCommand_ScrollNext
-};
-
-void BaseScrollBar::ShowContextMenuForView(View* source,
- const gfx::Point& p,
- bool is_mouse_gesture) {
- Widget* widget = GetWidget();
- gfx::Rect widget_bounds = widget->GetWindowScreenBounds();
- gfx::Point temp_pt(p.x() - widget_bounds.x(), p.y() - widget_bounds.y());
- View::ConvertPointFromWidget(this, &temp_pt);
- context_menu_mouse_position_ = IsHorizontal() ? temp_pt.x() : temp_pt.y();
-
- scoped_ptr<Menu> menu(
- Menu::Create(this, Menu::TOPLEFT, GetWidget()->GetNativeView()));
- menu->AppendDelegateMenuItem(ScrollBarContextMenuCommand_ScrollHere);
- menu->AppendSeparator();
- menu->AppendDelegateMenuItem(ScrollBarContextMenuCommand_ScrollStart);
- menu->AppendDelegateMenuItem(ScrollBarContextMenuCommand_ScrollEnd);
- menu->AppendSeparator();
- menu->AppendDelegateMenuItem(ScrollBarContextMenuCommand_ScrollPageUp);
- menu->AppendDelegateMenuItem(ScrollBarContextMenuCommand_ScrollPageDown);
- menu->AppendSeparator();
- menu->AppendDelegateMenuItem(ScrollBarContextMenuCommand_ScrollPrev);
- menu->AppendDelegateMenuItem(ScrollBarContextMenuCommand_ScrollNext);
- menu->RunMenuAt(p.x(), p.y());
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// BaseScrollBar, Menu::Delegate implementation:
-
-std::wstring BaseScrollBar::GetLabel(int id) const {
- int ids_value = 0;
- switch (id) {
- case ScrollBarContextMenuCommand_ScrollHere:
- ids_value = IDS_APP_SCROLLBAR_CXMENU_SCROLLHERE;
- break;
- case ScrollBarContextMenuCommand_ScrollStart:
- ids_value = IsHorizontal() ? IDS_APP_SCROLLBAR_CXMENU_SCROLLLEFTEDGE
- : IDS_APP_SCROLLBAR_CXMENU_SCROLLHOME;
- break;
- case ScrollBarContextMenuCommand_ScrollEnd:
- ids_value = IsHorizontal() ? IDS_APP_SCROLLBAR_CXMENU_SCROLLRIGHTEDGE
- : IDS_APP_SCROLLBAR_CXMENU_SCROLLEND;
- break;
- case ScrollBarContextMenuCommand_ScrollPageUp:
- ids_value = IDS_APP_SCROLLBAR_CXMENU_SCROLLPAGEUP;
- break;
- case ScrollBarContextMenuCommand_ScrollPageDown:
- ids_value = IDS_APP_SCROLLBAR_CXMENU_SCROLLPAGEDOWN;
- break;
- case ScrollBarContextMenuCommand_ScrollPrev:
- ids_value = IsHorizontal() ? IDS_APP_SCROLLBAR_CXMENU_SCROLLLEFT
- : IDS_APP_SCROLLBAR_CXMENU_SCROLLUP;
- break;
- case ScrollBarContextMenuCommand_ScrollNext:
- ids_value = IsHorizontal() ? IDS_APP_SCROLLBAR_CXMENU_SCROLLRIGHT
- : IDS_APP_SCROLLBAR_CXMENU_SCROLLDOWN;
- break;
- default:
- NOTREACHED() << "Invalid BaseScrollBar Context Menu command!";
- }
-
- return ids_value ? UTF16ToWide(l10n_util::GetStringUTF16(ids_value)) : L"";
-}
-
-bool BaseScrollBar::IsCommandEnabled(int id) const {
- switch (id) {
- case ScrollBarContextMenuCommand_ScrollPageUp:
- case ScrollBarContextMenuCommand_ScrollPageDown:
- return !IsHorizontal();
- }
- return true;
-}
-
-void BaseScrollBar::ExecuteCommand(int id) {
- switch (id) {
- case ScrollBarContextMenuCommand_ScrollHere:
- ScrollToThumbPosition(context_menu_mouse_position_, true);
- break;
- case ScrollBarContextMenuCommand_ScrollStart:
- ScrollByAmount(SCROLL_START);
- break;
- case ScrollBarContextMenuCommand_ScrollEnd:
- ScrollByAmount(SCROLL_END);
- break;
- case ScrollBarContextMenuCommand_ScrollPageUp:
- ScrollByAmount(SCROLL_PREV_PAGE);
- break;
- case ScrollBarContextMenuCommand_ScrollPageDown:
- ScrollByAmount(SCROLL_NEXT_PAGE);
- break;
- case ScrollBarContextMenuCommand_ScrollPrev:
- ScrollByAmount(SCROLL_PREV_LINE);
- break;
- case ScrollBarContextMenuCommand_ScrollNext:
- ScrollByAmount(SCROLL_NEXT_LINE);
- break;
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// BaseScrollBar, ScrollBar implementation:
-
-void BaseScrollBar::Update(int viewport_size, int content_size,
- int contents_scroll_offset) {
- ScrollBar::Update(viewport_size, content_size, contents_scroll_offset);
-
- // Make sure contents_size is always > 0 to avoid divide by zero errors in
- // calculations throughout this code.
- contents_size_ = std::max(1, content_size);
-
- if (content_size < 0)
- content_size = 0;
- if (contents_scroll_offset < 0)
- contents_scroll_offset = 0;
- if (contents_scroll_offset > content_size)
- contents_scroll_offset = content_size;
-
- // Thumb Height and Thumb Pos.
- // The height of the thumb is the ratio of the Viewport height to the
- // content size multiplied by the height of the thumb track.
- double ratio = static_cast<double>(viewport_size) / contents_size_;
- int thumb_size = static_cast<int>(ratio * GetTrackSize());
- thumb_->SetSize(thumb_size);
-
- int thumb_position = CalculateThumbPosition(contents_scroll_offset);
- thumb_->SetPosition(thumb_position);
-}
-
-int BaseScrollBar::GetPosition() const {
- return thumb_->GetPosition();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// BaseScrollBar, protected:
-
-BaseScrollBarThumb* BaseScrollBar::GetThumb() const {
- return thumb_;
-}
-
-CustomButton::ButtonState BaseScrollBar::GetThumbTrackState() const {
- return thumb_track_state_;
-}
-
-void BaseScrollBar::ScrollToPosition(int position) {
- GetController()->ScrollToPosition(this, position);
-}
-
-int BaseScrollBar::GetScrollIncrement(bool is_page, bool is_positive) {
- return GetController()->GetScrollIncrement(this, is_page, is_positive);
-}
-
-
-///////////////////////////////////////////////////////////////////////////////
-// BaseScrollBar, private:
-
-void BaseScrollBar::TrackClicked() {
- if (last_scroll_amount_ != SCROLL_NONE)
- ScrollByAmount(last_scroll_amount_);
-}
-
-void BaseScrollBar::ScrollContentsToOffset() {
- ScrollToPosition(contents_scroll_offset_);
- thumb_->SetPosition(CalculateThumbPosition(contents_scroll_offset_));
-}
-
-int BaseScrollBar::GetTrackSize() const {
- gfx::Rect track_bounds = GetTrackBounds();
- return IsHorizontal() ? track_bounds.width() : track_bounds.height();
-}
-
-int BaseScrollBar::CalculateThumbPosition(int contents_scroll_offset) const {
- return (contents_scroll_offset * GetTrackSize()) / contents_size_;
-}
-
-int BaseScrollBar::CalculateContentsOffset(int thumb_position,
- bool scroll_to_middle) const {
- if (scroll_to_middle)
- thumb_position = thumb_position - (thumb_->GetSize() / 2);
- return (thumb_position * contents_size_) / GetTrackSize();
-}
-
-void BaseScrollBar::SetThumbTrackState(CustomButton::ButtonState state) {
- thumb_track_state_ = state;
- SchedulePaint();
-}
-
-} // namespace views
diff --git a/views/controls/scrollbar/base_scroll_bar.h b/views/controls/scrollbar/base_scroll_bar.h
deleted file mode 100644
index 7a88459..0000000
--- a/views/controls/scrollbar/base_scroll_bar.h
+++ /dev/null
@@ -1,156 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef VIEWS_CONTROLS_SCROLLBAR_BASE_SCROLL_BAR_H_
-#define VIEWS_CONTROLS_SCROLLBAR_BASE_SCROLL_BAR_H_
-#pragma once
-
-#include "views/context_menu_controller.h"
-#include "views/controls/button/image_button.h"
-#include "views/controls/menu/menu.h"
-#include "views/controls/scrollbar/scroll_bar.h"
-#include "views/repeat_controller.h"
-
-namespace views {
-
-class BaseScrollBarThumb;
-
-///////////////////////////////////////////////////////////////////////////////
-//
-// BaseScrollBar
-//
-///////////////////////////////////////////////////////////////////////////////
-class BaseScrollBar : public ScrollBar,
- public ContextMenuController,
- public Menu::Delegate {
- public:
- BaseScrollBar(bool horizontal, BaseScrollBarThumb* thumb);
- virtual ~BaseScrollBar() { }
-
- // Get the bounds of the "track" area that the thumb is free to slide within.
- virtual gfx::Rect GetTrackBounds() const = 0;
-
- // An enumeration of different amounts of incremental scroll, representing
- // events sent from different parts of the UI/keyboard.
- enum ScrollAmount {
- SCROLL_NONE = 0,
- SCROLL_START,
- SCROLL_END,
- SCROLL_PREV_LINE,
- SCROLL_NEXT_LINE,
- SCROLL_PREV_PAGE,
- SCROLL_NEXT_PAGE,
- };
-
- // Scroll the contents by the specified type (see ScrollAmount above).
- void ScrollByAmount(ScrollAmount amount);
-
- // Scroll the contents to the appropriate position given the supplied
- // position of the thumb (thumb track coordinates). If |scroll_to_middle| is
- // true, then the conversion assumes |thumb_position| is in the middle of the
- // thumb rather than the top.
- void ScrollToThumbPosition(int thumb_position, bool scroll_to_middle);
-
- // Scroll the contents by the specified offset (contents coordinates).
- void ScrollByContentsOffset(int contents_offset);
-
- // View overrides:
- virtual gfx::Size GetPreferredSize() OVERRIDE = 0;
- virtual void Layout() OVERRIDE = 0;
- virtual bool OnMousePressed(const MouseEvent& event) OVERRIDE;
- virtual void OnMouseReleased(const MouseEvent& event) OVERRIDE;
- virtual void OnMouseCaptureLost() OVERRIDE;
- virtual bool OnKeyPressed(const KeyEvent& event) OVERRIDE;
- virtual bool OnMouseWheel(const MouseWheelEvent& event) OVERRIDE;
-
- // ScrollBar overrides:
- virtual void Update(int viewport_size,
- int content_size,
- int contents_scroll_offset) OVERRIDE;
- virtual int GetLayoutSize() const OVERRIDE = 0;
- virtual int GetPosition() const OVERRIDE;
-
- // ContextMenuController overrides.
- virtual void ShowContextMenuForView(View* source,
- const gfx::Point& p,
- bool is_mouse_gesture) OVERRIDE;
-
- // Menu::Delegate overrides:
- virtual std::wstring GetLabel(int id) const OVERRIDE;
- virtual bool IsCommandEnabled(int id) const OVERRIDE;
- virtual void ExecuteCommand(int id) OVERRIDE;
-
- protected:
- // View overrides:
- virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE = 0;
-
- BaseScrollBarThumb* GetThumb() const;
-
- CustomButton::ButtonState GetThumbTrackState() const;
-
- // Wrapper functions that calls the controller. We need this since native
- // scrollbars wrap around a different scrollbar. When calling the controller
- // we need to pass in the appropriate scrollbar. For normal scrollbars it's
- // the |this| scrollbar, for native scrollbars it's the native scrollbar used
- // to create this.
- virtual void ScrollToPosition(int position);
- virtual int GetScrollIncrement(bool is_page, bool is_positive);
-
- private:
- // Called when the mouse is pressed down in the track area.
- void TrackClicked();
-
- // Responsible for scrolling the contents and also updating the UI to the
- // current value of the Scroll Offset.
- void ScrollContentsToOffset();
-
- // Returns the size (width or height) of the track area of the ScrollBar.
- int GetTrackSize() const;
-
- // Calculate the position of the thumb within the track based on the
- // specified scroll offset of the contents.
- int CalculateThumbPosition(int contents_scroll_offset) const;
-
- // Calculates the current value of the contents offset (contents coordinates)
- // based on the current thumb position (thumb track coordinates). See
- // |ScrollToThumbPosition| for an explanation of |scroll_to_middle|.
- int CalculateContentsOffset(int thumb_position,
- bool scroll_to_middle) const;
-
- // Called when the state of the thumb track changes (e.g. by the user
- // pressing the mouse button down in it).
- void SetThumbTrackState(CustomButton::ButtonState state);
-
- BaseScrollBarThumb* thumb_;
-
- // The size of the scrolled contents, in pixels.
- int contents_size_;
-
- // The current amount the contents is offset by in the viewport.
- int contents_scroll_offset_;
-
- // The state of the scrollbar track. Typically, the track will highlight when
- // the user presses the mouse on them (during page scrolling).
- CustomButton::ButtonState thumb_track_state_;
-
- // The last amount of incremental scroll that this scrollbar performed. This
- // is accessed by the callbacks for the auto-repeat up/down buttons to know
- // what direction to repeatedly scroll in.
- ScrollAmount last_scroll_amount_;
-
- // An instance of a RepeatController which scrolls the scrollbar continuously
- // as the user presses the mouse button down on the up/down buttons or the
- // track.
- RepeatController repeater_;
-
- // The position of the mouse within the scroll bar when the context menu
- // was invoked.
- int context_menu_mouse_position_;
-
- DISALLOW_COPY_AND_ASSIGN(BaseScrollBar);
-};
-
-} // namespace views
-
-#endif // VIEWS_CONTROLS_SCROLLBAR_BASE_SCROLL_BAR_H_
diff --git a/views/controls/scrollbar/base_scroll_bar_button.cc b/views/controls/scrollbar/base_scroll_bar_button.cc
deleted file mode 100644
index 95239e7..0000000
--- a/views/controls/scrollbar/base_scroll_bar_button.cc
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "views/controls/scrollbar/base_scroll_bar_button.h"
-
-namespace views {
-
-BaseScrollBarButton::BaseScrollBarButton(ButtonListener* listener)
- : CustomButton(listener),
- ALLOW_THIS_IN_INITIALIZER_LIST(repeater_(
- NewCallback<BaseScrollBarButton>(this,
- &BaseScrollBarButton::NotifyClick))) {
-}
-
-BaseScrollBarButton::~BaseScrollBarButton() {
-}
-
-bool BaseScrollBarButton::OnMousePressed(const MouseEvent& event) {
- Button::NotifyClick(event);
- repeater_.Start();
- return true;
-}
-
-void BaseScrollBarButton::OnMouseReleased(const MouseEvent& event) {
- OnMouseCaptureLost();
-}
-
-void BaseScrollBarButton::OnMouseCaptureLost() {
- repeater_.Stop();
-}
-
-void BaseScrollBarButton::NotifyClick() {
-#if defined(OS_WIN)
- DWORD pos = GetMessagePos();
- POINTS points = MAKEPOINTS(pos);
- gfx::Point cursor_point(points.x, points.y);
-#elif defined(OS_LINUX)
- gfx::Point cursor_point = gfx::Screen::GetCursorScreenPoint();
-#endif
- views::MouseEvent event(ui::ET_MOUSE_RELEASED,
- cursor_point.x(), cursor_point.y(),
- ui::EF_LEFT_BUTTON_DOWN);
- Button::NotifyClick(event);
-}
-
-} // namespace views
diff --git a/views/controls/scrollbar/base_scroll_bar_button.h b/views/controls/scrollbar/base_scroll_bar_button.h
deleted file mode 100644
index 77bb666..0000000
--- a/views/controls/scrollbar/base_scroll_bar_button.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef VIEWS_CONTROLS_SCROLLBAR_BASE_SCROLL_BAR_BUTTON_H_
-#define VIEWS_CONTROLS_SCROLLBAR_BASE_SCROLL_BAR_BUTTON_H_
-#pragma once
-
-#include "views/controls/button/custom_button.h"
-
-#include "views/repeat_controller.h"
-
-#if defined(OS_LINUX)
-#include "ui/gfx/screen.h"
-#endif
-
-namespace views {
-
-///////////////////////////////////////////////////////////////////////////////
-//
-// ScrollBarButton
-//
-// A button that activates on mouse pressed rather than released, and that
-// continues to fire the clicked action as the mouse button remains pressed
-// down on the button.
-//
-///////////////////////////////////////////////////////////////////////////////
-class BaseScrollBarButton : public CustomButton {
- public:
- explicit BaseScrollBarButton(ButtonListener* listener);
- virtual ~BaseScrollBarButton();
-
- protected:
- virtual bool OnMousePressed(const MouseEvent& event) OVERRIDE;
- virtual void OnMouseReleased(const MouseEvent& event) OVERRIDE;
- virtual void OnMouseCaptureLost() OVERRIDE;
-
- private:
- void NotifyClick();
-
- // The repeat controller that we use to repeatedly click the button when the
- // mouse button is down.
- RepeatController repeater_;
-
- DISALLOW_COPY_AND_ASSIGN(BaseScrollBarButton);
-};
-
-} // namespace views
-
-#endif // VIEWS_CONTROLS_SCROLLBAR_BASE_SCROLL_BAR_BUTTON_H_
diff --git a/views/controls/scrollbar/base_scroll_bar_thumb.cc b/views/controls/scrollbar/base_scroll_bar_thumb.cc
deleted file mode 100644
index bbd42f9..0000000
--- a/views/controls/scrollbar/base_scroll_bar_thumb.cc
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "views/controls/scrollbar/base_scroll_bar_thumb.h"
-
-#include "views/controls/scrollbar/base_scroll_bar.h"
-#include "ui/gfx/canvas.h"
-#include "ui/gfx/rect.h"
-
-namespace {
-// The distance the mouse can be dragged outside the bounds of the thumb during
-// dragging before the scrollbar will snap back to its regular position.
-static const int kScrollThumbDragOutSnap = 100;
-}
-
-namespace views {
-
-BaseScrollBarThumb::BaseScrollBarThumb(BaseScrollBar* scroll_bar)
- : scroll_bar_(scroll_bar),
- drag_start_position_(-1),
- mouse_offset_(-1),
- state_(CustomButton::BS_NORMAL) {
-}
-
-BaseScrollBarThumb::~BaseScrollBarThumb() {
-}
-
-void BaseScrollBarThumb::SetSize(int size) {
- // Make sure the thumb is never sized smaller than its minimum possible
- // display size.
- gfx::Size prefsize = GetPreferredSize();
- size = std::max(size, scroll_bar_->IsHorizontal() ? prefsize.width() :
- prefsize.height());
- gfx::Rect thumb_bounds = bounds();
- if (scroll_bar_->IsHorizontal()) {
- thumb_bounds.set_width(size);
- } else {
- thumb_bounds.set_height(size);
- }
- SetBoundsRect(thumb_bounds);
-}
-
-int BaseScrollBarThumb::GetSize() const {
- if (scroll_bar_->IsHorizontal())
- return width();
- return height();
-}
-
-void BaseScrollBarThumb::SetPosition(int position) {
- gfx::Rect thumb_bounds = bounds();
- gfx::Rect track_bounds = scroll_bar_->GetTrackBounds();
- if (scroll_bar_->IsHorizontal()) {
- thumb_bounds.set_x(track_bounds.x() + position);
- } else {
- thumb_bounds.set_y(track_bounds.y() + position);
- }
- SetBoundsRect(thumb_bounds);
-}
-
-int BaseScrollBarThumb::GetPosition() const {
- gfx::Rect track_bounds = scroll_bar_->GetTrackBounds();
- if (scroll_bar_->IsHorizontal())
- return x() - track_bounds.x();
- return y() - track_bounds.y();
-}
-
-void BaseScrollBarThumb::OnMouseEntered(const MouseEvent& event) {
- SetState(CustomButton::BS_HOT);
-}
-
-void BaseScrollBarThumb::OnMouseExited(const MouseEvent& event) {
- SetState(CustomButton::BS_NORMAL);
-}
-
-bool BaseScrollBarThumb::OnMousePressed(const MouseEvent& event) {
- mouse_offset_ = scroll_bar_->IsHorizontal() ? event.x() : event.y();
- drag_start_position_ = GetPosition();
- SetState(CustomButton::BS_PUSHED);
- return true;
-}
-
-bool BaseScrollBarThumb::OnMouseDragged(const MouseEvent& event) {
- // If the user moves the mouse more than |kScrollThumbDragOutSnap| outside
- // the bounds of the thumb, the scrollbar will snap the scroll back to the
- // point it was at before the drag began.
- if (scroll_bar_->IsHorizontal()) {
- if ((event.y() < y() - kScrollThumbDragOutSnap) ||
- (event.y() > (y() + height() + kScrollThumbDragOutSnap))) {
- scroll_bar_->ScrollToThumbPosition(drag_start_position_, false);
- return true;
- }
- } else {
- if ((event.x() < x() - kScrollThumbDragOutSnap) ||
- (event.x() > (x() + width() + kScrollThumbDragOutSnap))) {
- scroll_bar_->ScrollToThumbPosition(drag_start_position_, false);
- return true;
- }
- }
- if (scroll_bar_->IsHorizontal()) {
- int thumb_x = event.x() - mouse_offset_;
- scroll_bar_->ScrollToThumbPosition(GetPosition() + thumb_x, false);
- } else {
- int thumb_y = event.y() - mouse_offset_;
- scroll_bar_->ScrollToThumbPosition(GetPosition() + thumb_y, false);
- }
- return true;
-}
-
-void BaseScrollBarThumb::OnMouseReleased(const MouseEvent& event) {
- OnMouseCaptureLost();
-}
-
-void BaseScrollBarThumb::OnMouseCaptureLost() {
- SetState(CustomButton::BS_HOT);
-}
-
-CustomButton::ButtonState BaseScrollBarThumb::GetState() const {
- return state_;
-}
-
-void BaseScrollBarThumb::SetState(CustomButton::ButtonState state) {
- state_ = state;
- SchedulePaint();
-}
-
-} // namespace views
diff --git a/views/controls/scrollbar/base_scroll_bar_thumb.h b/views/controls/scrollbar/base_scroll_bar_thumb.h
deleted file mode 100644
index 8720b9a..0000000
--- a/views/controls/scrollbar/base_scroll_bar_thumb.h
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef VIEWS_CONTROLS_SCROLLBAR_BASE_SCROLL_BAR_THUMB_H_
-#define VIEWS_CONTROLS_SCROLLBAR_BASE_SCROLL_BAR_THUMB_H_
-#pragma once
-
-#include "ui/gfx/size.h"
-#include "views/controls/button/custom_button.h"
-#include "views/controls/scrollbar/scroll_bar.h"
-#include "views/view.h"
-
-namespace gfx {
-class Canvas;
-}
-
-namespace views {
-
-class BaseScrollBar;
-
-///////////////////////////////////////////////////////////////////////////////
-//
-// BaseScrollBarThumb
-//
-// A view that acts as the thumb in the scroll bar track that the user can
-// drag to scroll the associated contents view within the viewport.
-//
-///////////////////////////////////////////////////////////////////////////////
-class BaseScrollBarThumb : public View {
- public:
- explicit BaseScrollBarThumb(BaseScrollBar* scroll_bar);
- virtual ~BaseScrollBarThumb();
-
- // Sets the size (width or height) of the thumb to the specified value.
- void SetSize(int size);
-
- // Retrieves the size (width or height) of the thumb.
- int GetSize() const;
-
- // Sets the position of the thumb on the x or y axis.
- void SetPosition(int position);
-
- // Gets the position of the thumb on the x or y axis.
- int GetPosition() const;
-
- // View overrides:
- virtual gfx::Size GetPreferredSize() OVERRIDE = 0;
-
- protected:
- // View overrides:
- virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE = 0;
- virtual void OnMouseEntered(const MouseEvent& event) OVERRIDE;
- virtual void OnMouseExited(const MouseEvent& event) OVERRIDE;
- virtual bool OnMousePressed(const MouseEvent& event) OVERRIDE;
- virtual bool OnMouseDragged(const MouseEvent& event) OVERRIDE;
- virtual void OnMouseReleased(const MouseEvent& event) OVERRIDE;
- virtual void OnMouseCaptureLost() OVERRIDE;
-
- CustomButton::ButtonState GetState() const;
- // Update our state and schedule a repaint when the mouse moves over us.
- void SetState(CustomButton::ButtonState state);
-
- private:
- // The BaseScrollBar that owns us.
- BaseScrollBar* scroll_bar_;
-
- int drag_start_position_;
-
- // The position of the mouse on the scroll axis relative to the top of this
- // View when the drag started.
- int mouse_offset_;
-
- // The current state of the thumb button.
- CustomButton::ButtonState state_;
-
- DISALLOW_COPY_AND_ASSIGN(BaseScrollBarThumb);
-};
-
-} // namespace views
-
-#endif // VIEWS_CONTROLS_SCROLLBAR_BASE_SCROLL_BAR_THUMB_H_
diff --git a/views/controls/scrollbar/bitmap_scroll_bar.cc b/views/controls/scrollbar/bitmap_scroll_bar.cc
index 6b7fbc0..b52e8d9 100644
--- a/views/controls/scrollbar/bitmap_scroll_bar.cc
+++ b/views/controls/scrollbar/bitmap_scroll_bar.cc
@@ -19,7 +19,6 @@
#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/canvas.h"
#include "views/controls/menu/menu.h"
-#include "views/controls/scrollbar/base_scroll_bar_thumb.h"
#include "views/controls/scroll_view.h"
#include "views/widget/widget.h"
@@ -45,7 +44,7 @@ static const int kScrollThumbDragOutSnap = 100;
///////////////////////////////////////////////////////////////////////////////
class AutorepeatButton : public ImageButton {
public:
- explicit AutorepeatButton(ButtonListener* listener)
+ AutorepeatButton(ButtonListener* listener)
: ImageButton(listener),
ALLOW_THIS_IN_INITIALIZER_LIST(repeater_(
NewCallback<AutorepeatButton>(this,
@@ -98,14 +97,59 @@ class AutorepeatButton : public ImageButton {
// drag to scroll the associated contents view within the viewport.
//
///////////////////////////////////////////////////////////////////////////////
-class BitmapScrollBarThumb : public BaseScrollBarThumb {
+class BitmapScrollBarThumb : public View {
public:
explicit BitmapScrollBarThumb(BitmapScrollBar* scroll_bar)
- : BaseScrollBarThumb(scroll_bar),
- scroll_bar_(scroll_bar) {
+ : scroll_bar_(scroll_bar),
+ drag_start_position_(-1),
+ mouse_offset_(-1),
+ state_(CustomButton::BS_NORMAL) {
}
virtual ~BitmapScrollBarThumb() { }
+ // Sets the size (width or height) of the thumb to the specified value.
+ void SetSize(int size) {
+ // Make sure the thumb is never sized smaller than its minimum possible
+ // display size.
+ gfx::Size prefsize = GetPreferredSize();
+ size = std::max(size, scroll_bar_->IsHorizontal() ? prefsize.width() :
+ prefsize.height());
+ gfx::Rect thumb_bounds = bounds();
+ if (scroll_bar_->IsHorizontal()) {
+ thumb_bounds.set_width(size);
+ } else {
+ thumb_bounds.set_height(size);
+ }
+ SetBoundsRect(thumb_bounds);
+ }
+
+ // Retrieves the size (width or height) of the thumb.
+ int GetSize() const {
+ if (scroll_bar_->IsHorizontal())
+ return width();
+ return height();
+ }
+
+ // Sets the position of the thumb on the x or y axis.
+ void SetPosition(int position) {
+ gfx::Rect thumb_bounds = bounds();
+ gfx::Rect track_bounds = scroll_bar_->GetTrackBounds();
+ if (scroll_bar_->IsHorizontal()) {
+ thumb_bounds.set_x(track_bounds.x() + position);
+ } else {
+ thumb_bounds.set_y(track_bounds.y() + position);
+ }
+ SetBoundsRect(thumb_bounds);
+ }
+
+ // Gets the position of the thumb on the x or y axis.
+ int GetPosition() const {
+ gfx::Rect track_bounds = scroll_bar_->GetTrackBounds();
+ if (scroll_bar_->IsHorizontal())
+ return x() - track_bounds.x();
+ return y() - track_bounds.y();
+ }
+
// View overrides:
virtual gfx::Size GetPreferredSize() OVERRIDE {
return gfx::Size(background_bitmap()->width(),
@@ -116,7 +160,7 @@ class BitmapScrollBarThumb : public BaseScrollBarThumb {
protected:
// View overrides:
- virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
+ virtual void Paint(gfx::Canvas* canvas) OVERRIDE {
canvas->DrawBitmapInt(*start_cap_bitmap(), 0, 0);
int top_cap_height = start_cap_bitmap()->height();
int bottom_cap_height = end_cap_bitmap()->height();
@@ -132,21 +176,71 @@ class BitmapScrollBarThumb : public BaseScrollBarThumb {
canvas->DrawBitmapInt(*grippy_bitmap(), grippy_x, grippy_y);
}
+ virtual void OnMouseEntered(const MouseEvent& event) OVERRIDE {
+ SetState(CustomButton::BS_HOT);
+ }
+
+ virtual void OnMouseExited(const MouseEvent& event) OVERRIDE {
+ SetState(CustomButton::BS_NORMAL);
+ }
+
+ virtual bool OnMousePressed(const MouseEvent& event) OVERRIDE {
+ mouse_offset_ = scroll_bar_->IsHorizontal() ? event.x() : event.y();
+ drag_start_position_ = GetPosition();
+ SetState(CustomButton::BS_PUSHED);
+ return true;
+ }
+
+ virtual bool OnMouseDragged(const MouseEvent& event) OVERRIDE {
+ // If the user moves the mouse more than |kScrollThumbDragOutSnap| outside
+ // the bounds of the thumb, the scrollbar will snap the scroll back to the
+ // point it was at before the drag began.
+ if (scroll_bar_->IsHorizontal()) {
+ if ((event.y() < y() - kScrollThumbDragOutSnap) ||
+ (event.y() > (y() + height() + kScrollThumbDragOutSnap))) {
+ scroll_bar_->ScrollToThumbPosition(drag_start_position_, false);
+ return true;
+ }
+ } else {
+ if ((event.x() < x() - kScrollThumbDragOutSnap) ||
+ (event.x() > (x() + width() + kScrollThumbDragOutSnap))) {
+ scroll_bar_->ScrollToThumbPosition(drag_start_position_, false);
+ return true;
+ }
+ }
+ if (scroll_bar_->IsHorizontal()) {
+ int thumb_x = event.x() - mouse_offset_;
+ scroll_bar_->ScrollToThumbPosition(x() + thumb_x, false);
+ } else {
+ int thumb_y = event.y() - mouse_offset_;
+ scroll_bar_->ScrollToThumbPosition(y() + thumb_y, false);
+ }
+ return true;
+ }
+
+ virtual void OnMouseReleased(const MouseEvent& event) OVERRIDE {
+ OnMouseCaptureLost();
+ }
+
+ virtual void OnMouseCaptureLost() OVERRIDE {
+ SetState(CustomButton::BS_HOT);
+ }
+
private:
// Returns the bitmap rendered at the start of the thumb.
SkBitmap* start_cap_bitmap() const {
- return scroll_bar_->images_[BitmapScrollBar::THUMB_START_CAP][GetState()];
+ return scroll_bar_->images_[BitmapScrollBar::THUMB_START_CAP][state_];
}
// Returns the bitmap rendered at the end of the thumb.
SkBitmap* end_cap_bitmap() const {
- return scroll_bar_->images_[BitmapScrollBar::THUMB_END_CAP][GetState()];
+ return scroll_bar_->images_[BitmapScrollBar::THUMB_END_CAP][state_];
}
// Returns the bitmap that is tiled in the background of the thumb between
// the start and the end caps.
SkBitmap* background_bitmap() const {
- return scroll_bar_->images_[BitmapScrollBar::THUMB_MIDDLE][GetState()];
+ return scroll_bar_->images_[BitmapScrollBar::THUMB_MIDDLE][state_];
}
// Returns the bitmap that is rendered in the middle of the thumb
@@ -156,9 +250,24 @@ class BitmapScrollBarThumb : public BaseScrollBarThumb {
[CustomButton::BS_NORMAL];
}
+ // Update our state and schedule a repaint when the mouse moves over us.
+ void SetState(CustomButton::ButtonState state) {
+ state_ = state;
+ SchedulePaint();
+ }
+
// The BitmapScrollBar that owns us.
BitmapScrollBar* scroll_bar_;
+ int drag_start_position_;
+
+ // The position of the mouse on the scroll axis relative to the top of this
+ // View when the drag started.
+ int mouse_offset_;
+
+ // The current state of the thumb button.
+ CustomButton::ButtonState state_;
+
DISALLOW_COPY_AND_ASSIGN(BitmapScrollBarThumb);
};
@@ -168,10 +277,19 @@ class BitmapScrollBarThumb : public BaseScrollBarThumb {
// BitmapScrollBar, public:
BitmapScrollBar::BitmapScrollBar(bool horizontal, bool show_scroll_buttons)
- : BaseScrollBar(horizontal, new BitmapScrollBarThumb(this)),
+ : contents_size_(0),
+ contents_scroll_offset_(0),
ALLOW_THIS_IN_INITIALIZER_LIST(prev_button_(new AutorepeatButton(this))),
ALLOW_THIS_IN_INITIALIZER_LIST(next_button_(new AutorepeatButton(this))),
- show_scroll_buttons_(show_scroll_buttons) {
+ ALLOW_THIS_IN_INITIALIZER_LIST(thumb_(new BitmapScrollBarThumb(this))),
+ thumb_track_state_(CustomButton::BS_NORMAL),
+ last_scroll_amount_(SCROLL_NONE),
+ ALLOW_THIS_IN_INITIALIZER_LIST(repeater_(
+ NewCallback<BitmapScrollBar>(this,
+ &BitmapScrollBar::TrackClicked))),
+ context_menu_mouse_position_(0),
+ show_scroll_buttons_(show_scroll_buttons),
+ ScrollBar(horizontal) {
if (!show_scroll_buttons_) {
prev_button_->SetVisible(false);
next_button_->SetVisible(false);
@@ -179,10 +297,29 @@ BitmapScrollBar::BitmapScrollBar(bool horizontal, bool show_scroll_buttons)
AddChildView(prev_button_);
AddChildView(next_button_);
+ AddChildView(thumb_);
set_context_menu_controller(this);
prev_button_->set_context_menu_controller(this);
next_button_->set_context_menu_controller(this);
+ thumb_->set_context_menu_controller(this);
+}
+
+gfx::Rect BitmapScrollBar::GetTrackBounds() const {
+ gfx::Size prefsize = prev_button_->GetPreferredSize();
+ if (IsHorizontal()) {
+ if (!show_scroll_buttons_)
+ prefsize.set_width(0);
+ int new_width =
+ std::max(0, width() - (prefsize.width() * 2));
+ gfx::Rect track_bounds(prefsize.width(), 0, new_width, prefsize.height());
+ return track_bounds;
+ }
+ if (!show_scroll_buttons_)
+ prefsize.set_height(0);
+ gfx::Rect track_bounds(0, prefsize.height(), prefsize.width(),
+ std::max(0, height() - (prefsize.height() * 2)));
+ return track_bounds;
}
void BitmapScrollBar::SetImage(ScrollBarPart part,
@@ -207,26 +344,58 @@ void BitmapScrollBar::SetImage(ScrollBarPart part,
}
}
-int BitmapScrollBar::GetLayoutSize() const {
- gfx::Size prefsize = prev_button_->GetPreferredSize();
- return IsHorizontal() ? prefsize.height() : prefsize.width();
+void BitmapScrollBar::ScrollByAmount(ScrollAmount amount) {
+ ScrollBarController* controller = GetController();
+ int offset = contents_scroll_offset_;
+ switch (amount) {
+ case SCROLL_START:
+ offset = GetMinPosition();
+ break;
+ case SCROLL_END:
+ offset = GetMaxPosition();
+ break;
+ case SCROLL_PREV_LINE:
+ offset -= controller->GetScrollIncrement(this, false, false);
+ offset = std::max(GetMinPosition(), offset);
+ break;
+ case SCROLL_NEXT_LINE:
+ offset += controller->GetScrollIncrement(this, false, true);
+ offset = std::min(GetMaxPosition(), offset);
+ break;
+ case SCROLL_PREV_PAGE:
+ offset -= controller->GetScrollIncrement(this, true, false);
+ offset = std::max(GetMinPosition(), offset);
+ break;
+ case SCROLL_NEXT_PAGE:
+ offset += controller->GetScrollIncrement(this, true, true);
+ offset = std::min(GetMaxPosition(), offset);
+ break;
+ }
+ contents_scroll_offset_ = offset;
+ ScrollContentsToOffset();
}
-gfx::Rect BitmapScrollBar::GetTrackBounds() const {
- gfx::Size prefsize = prev_button_->GetPreferredSize();
- if (IsHorizontal()) {
- if (!show_scroll_buttons_)
- prefsize.set_width(0);
- int new_width =
- std::max(0, width() - (prefsize.width() * 2));
- gfx::Rect track_bounds(prefsize.width(), 0, new_width, prefsize.height());
- return track_bounds;
+void BitmapScrollBar::ScrollToThumbPosition(int thumb_position,
+ bool scroll_to_middle) {
+ contents_scroll_offset_ =
+ CalculateContentsOffset(thumb_position, scroll_to_middle);
+ if (contents_scroll_offset_ < GetMinPosition()) {
+ contents_scroll_offset_ = GetMinPosition();
+ } else if (contents_scroll_offset_ > GetMaxPosition()) {
+ contents_scroll_offset_ = GetMaxPosition();
}
- if (!show_scroll_buttons_)
- prefsize.set_height(0);
- gfx::Rect track_bounds(0, prefsize.height(), prefsize.width(),
- std::max(0, height() - (prefsize.height() * 2)));
- return track_bounds;
+ ScrollContentsToOffset();
+ SchedulePaint();
+}
+
+void BitmapScrollBar::ScrollByContentsOffset(int contents_offset) {
+ contents_scroll_offset_ -= contents_offset;
+ if (contents_scroll_offset_ < GetMinPosition()) {
+ contents_scroll_offset_ = GetMinPosition();
+ } else if (contents_scroll_offset_ > GetMaxPosition()) {
+ contents_scroll_offset_ = GetMaxPosition();
+ }
+ ScrollContentsToOffset();
}
///////////////////////////////////////////////////////////////////////////////
@@ -257,20 +426,19 @@ void BitmapScrollBar::Layout() {
next_button_->SetBounds(0, 0, 0, 0);
}
- BaseScrollBarThumb* thumb = GetThumb();
// Size and place the thumb
- gfx::Size thumb_prefsize = thumb->GetPreferredSize();
+ gfx::Size thumb_prefsize = thumb_->GetPreferredSize();
gfx::Rect track_bounds = GetTrackBounds();
// Preserve the height/width of the thumb (depending on orientation) as set
// by the last call to |Update|, but coerce the width/height to be the
// appropriate value for the bitmaps provided.
if (IsHorizontal()) {
- thumb->SetBounds(thumb->x(), thumb->y(), thumb->width(),
+ thumb_->SetBounds(thumb_->x(), thumb_->y(), thumb_->width(),
thumb_prefsize.height());
} else {
- thumb->SetBounds(thumb->x(), thumb->y(), thumb_prefsize.width(),
- thumb->height());
+ thumb_->SetBounds(thumb_->x(), thumb_->y(), thumb_prefsize.width(),
+ thumb_->height());
}
// Hide the thumb if the track isn't tall enough to display even a tiny
@@ -278,21 +446,196 @@ void BitmapScrollBar::Layout() {
// in this scenario.
if ((IsHorizontal() && (track_bounds.width() < thumb_prefsize.width()) ||
(!IsHorizontal() && (track_bounds.height() < thumb_prefsize.height())))) {
- thumb->SetVisible(false);
- } else if (!thumb->IsVisible()) {
- thumb->SetVisible(true);
+ thumb_->SetVisible(false);
+ } else if (!thumb_->IsVisible()) {
+ thumb_->SetVisible(true);
}
}
+bool BitmapScrollBar::OnMousePressed(const MouseEvent& event) {
+ if (event.IsOnlyLeftMouseButton()) {
+ SetThumbTrackState(CustomButton::BS_PUSHED);
+ gfx::Rect thumb_bounds = thumb_->bounds();
+ if (IsHorizontal()) {
+ if (event.x() < thumb_bounds.x()) {
+ last_scroll_amount_ = SCROLL_PREV_PAGE;
+ } else if (event.x() > thumb_bounds.right()) {
+ last_scroll_amount_ = SCROLL_NEXT_PAGE;
+ }
+ } else {
+ if (event.y() < thumb_bounds.y()) {
+ last_scroll_amount_ = SCROLL_PREV_PAGE;
+ } else if (event.y() > thumb_bounds.bottom()) {
+ last_scroll_amount_ = SCROLL_NEXT_PAGE;
+ }
+ }
+ TrackClicked();
+ repeater_.Start();
+ }
+ return true;
+}
+
+void BitmapScrollBar::OnMouseReleased(const MouseEvent& event) {
+ OnMouseCaptureLost();
+}
+
+void BitmapScrollBar::OnMouseCaptureLost() {
+ SetThumbTrackState(CustomButton::BS_NORMAL);
+ repeater_.Stop();
+}
+
+bool BitmapScrollBar::OnKeyPressed(const KeyEvent& event) {
+ ScrollAmount amount = SCROLL_NONE;
+ switch (event.key_code()) {
+ case ui::VKEY_UP:
+ if (!IsHorizontal())
+ amount = SCROLL_PREV_LINE;
+ break;
+ case ui::VKEY_DOWN:
+ if (!IsHorizontal())
+ amount = SCROLL_NEXT_LINE;
+ break;
+ case ui::VKEY_LEFT:
+ if (IsHorizontal())
+ amount = SCROLL_PREV_LINE;
+ break;
+ case ui::VKEY_RIGHT:
+ if (IsHorizontal())
+ amount = SCROLL_NEXT_LINE;
+ break;
+ case ui::VKEY_PRIOR:
+ amount = SCROLL_PREV_PAGE;
+ break;
+ case ui::VKEY_NEXT:
+ amount = SCROLL_NEXT_PAGE;
+ break;
+ case ui::VKEY_HOME:
+ amount = SCROLL_START;
+ break;
+ case ui::VKEY_END:
+ amount = SCROLL_END;
+ break;
+ }
+ if (amount != SCROLL_NONE) {
+ ScrollByAmount(amount);
+ return true;
+ }
+ return false;
+}
+
+bool BitmapScrollBar::OnMouseWheel(const MouseWheelEvent& event) {
+ ScrollByContentsOffset(event.offset());
+ return true;
+}
+
///////////////////////////////////////////////////////////////////////////////
-// BitmapScrollBar, View implementation:
+// BitmapScrollBar, ContextMenuController implementation:
+
+enum ScrollBarContextMenuCommands {
+ ScrollBarContextMenuCommand_ScrollHere = 1,
+ ScrollBarContextMenuCommand_ScrollStart,
+ ScrollBarContextMenuCommand_ScrollEnd,
+ ScrollBarContextMenuCommand_ScrollPageUp,
+ ScrollBarContextMenuCommand_ScrollPageDown,
+ ScrollBarContextMenuCommand_ScrollPrev,
+ ScrollBarContextMenuCommand_ScrollNext
+};
-void BitmapScrollBar::OnPaint(gfx::Canvas* canvas) {
- // Paint the track.
- gfx::Rect track_bounds = GetTrackBounds();
- canvas->TileImageInt(*images_[THUMB_TRACK][GetThumbTrackState()],
- track_bounds.x(), track_bounds.y(),
- track_bounds.width(), track_bounds.height());
+void BitmapScrollBar::ShowContextMenuForView(View* source,
+ const gfx::Point& p,
+ bool is_mouse_gesture) {
+ Widget* widget = GetWidget();
+ gfx::Rect widget_bounds = widget->GetWindowScreenBounds();
+ gfx::Point temp_pt(p.x() - widget_bounds.x(), p.y() - widget_bounds.y());
+ View::ConvertPointFromWidget(this, &temp_pt);
+ context_menu_mouse_position_ = IsHorizontal() ? temp_pt.x() : temp_pt.y();
+
+ scoped_ptr<Menu> menu(
+ Menu::Create(this, Menu::TOPLEFT, GetWidget()->GetNativeView()));
+ menu->AppendDelegateMenuItem(ScrollBarContextMenuCommand_ScrollHere);
+ menu->AppendSeparator();
+ menu->AppendDelegateMenuItem(ScrollBarContextMenuCommand_ScrollStart);
+ menu->AppendDelegateMenuItem(ScrollBarContextMenuCommand_ScrollEnd);
+ menu->AppendSeparator();
+ menu->AppendDelegateMenuItem(ScrollBarContextMenuCommand_ScrollPageUp);
+ menu->AppendDelegateMenuItem(ScrollBarContextMenuCommand_ScrollPageDown);
+ menu->AppendSeparator();
+ menu->AppendDelegateMenuItem(ScrollBarContextMenuCommand_ScrollPrev);
+ menu->AppendDelegateMenuItem(ScrollBarContextMenuCommand_ScrollNext);
+ menu->RunMenuAt(p.x(), p.y());
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// BitmapScrollBar, Menu::Delegate implementation:
+
+std::wstring BitmapScrollBar::GetLabel(int id) const {
+ int ids_value = 0;
+ switch (id) {
+ case ScrollBarContextMenuCommand_ScrollHere:
+ ids_value = IDS_APP_SCROLLBAR_CXMENU_SCROLLHERE;
+ break;
+ case ScrollBarContextMenuCommand_ScrollStart:
+ ids_value = IsHorizontal() ? IDS_APP_SCROLLBAR_CXMENU_SCROLLLEFTEDGE
+ : IDS_APP_SCROLLBAR_CXMENU_SCROLLHOME;
+ break;
+ case ScrollBarContextMenuCommand_ScrollEnd:
+ ids_value = IsHorizontal() ? IDS_APP_SCROLLBAR_CXMENU_SCROLLRIGHTEDGE
+ : IDS_APP_SCROLLBAR_CXMENU_SCROLLEND;
+ break;
+ case ScrollBarContextMenuCommand_ScrollPageUp:
+ ids_value = IDS_APP_SCROLLBAR_CXMENU_SCROLLPAGEUP;
+ break;
+ case ScrollBarContextMenuCommand_ScrollPageDown:
+ ids_value = IDS_APP_SCROLLBAR_CXMENU_SCROLLPAGEDOWN;
+ break;
+ case ScrollBarContextMenuCommand_ScrollPrev:
+ ids_value = IsHorizontal() ? IDS_APP_SCROLLBAR_CXMENU_SCROLLLEFT
+ : IDS_APP_SCROLLBAR_CXMENU_SCROLLUP;
+ break;
+ case ScrollBarContextMenuCommand_ScrollNext:
+ ids_value = IsHorizontal() ? IDS_APP_SCROLLBAR_CXMENU_SCROLLRIGHT
+ : IDS_APP_SCROLLBAR_CXMENU_SCROLLDOWN;
+ break;
+ default:
+ NOTREACHED() << "Invalid BitmapScrollBar Context Menu command!";
+ }
+
+ return ids_value ? UTF16ToWide(l10n_util::GetStringUTF16(ids_value)) : L"";
+}
+
+bool BitmapScrollBar::IsCommandEnabled(int id) const {
+ switch (id) {
+ case ScrollBarContextMenuCommand_ScrollPageUp:
+ case ScrollBarContextMenuCommand_ScrollPageDown:
+ return !IsHorizontal();
+ }
+ return true;
+}
+
+void BitmapScrollBar::ExecuteCommand(int id) {
+ switch (id) {
+ case ScrollBarContextMenuCommand_ScrollHere:
+ ScrollToThumbPosition(context_menu_mouse_position_, true);
+ break;
+ case ScrollBarContextMenuCommand_ScrollStart:
+ ScrollByAmount(SCROLL_START);
+ break;
+ case ScrollBarContextMenuCommand_ScrollEnd:
+ ScrollByAmount(SCROLL_END);
+ break;
+ case ScrollBarContextMenuCommand_ScrollPageUp:
+ ScrollByAmount(SCROLL_PREV_PAGE);
+ break;
+ case ScrollBarContextMenuCommand_ScrollPageDown:
+ ScrollByAmount(SCROLL_NEXT_PAGE);
+ break;
+ case ScrollBarContextMenuCommand_ScrollPrev:
+ ScrollByAmount(SCROLL_PREV_LINE);
+ break;
+ case ScrollBarContextMenuCommand_ScrollNext:
+ ScrollByAmount(SCROLL_NEXT_LINE);
+ break;
+ }
}
///////////////////////////////////////////////////////////////////////////////
@@ -306,4 +649,87 @@ void BitmapScrollBar::ButtonPressed(Button* sender, const views::Event& event) {
}
}
+///////////////////////////////////////////////////////////////////////////////
+// BitmapScrollBar, ScrollBar implementation:
+
+void BitmapScrollBar::Update(int viewport_size, int content_size,
+ int contents_scroll_offset) {
+ ScrollBar::Update(viewport_size, content_size, contents_scroll_offset);
+
+ // Make sure contents_size is always > 0 to avoid divide by zero errors in
+ // calculations throughout this code.
+ contents_size_ = std::max(1, content_size);
+
+ if (content_size < 0)
+ content_size = 0;
+ if (contents_scroll_offset < 0)
+ contents_scroll_offset = 0;
+ if (contents_scroll_offset > content_size)
+ contents_scroll_offset = content_size;
+
+ // Thumb Height and Thumb Pos.
+ // The height of the thumb is the ratio of the Viewport height to the
+ // content size multiplied by the height of the thumb track.
+ double ratio = static_cast<double>(viewport_size) / contents_size_;
+ int thumb_size = static_cast<int>(ratio * GetTrackSize());
+ thumb_->SetSize(thumb_size);
+
+ int thumb_position = CalculateThumbPosition(contents_scroll_offset);
+ thumb_->SetPosition(thumb_position);
+}
+
+int BitmapScrollBar::GetLayoutSize() const {
+ gfx::Size prefsize = prev_button_->GetPreferredSize();
+ return IsHorizontal() ? prefsize.height() : prefsize.width();
+}
+
+int BitmapScrollBar::GetPosition() const {
+ return thumb_->GetPosition();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// BitmapScrollBar, View implementation:
+
+void BitmapScrollBar::OnPaint(gfx::Canvas* canvas) {
+ // Paint the track.
+ gfx::Rect track_bounds = GetTrackBounds();
+ canvas->TileImageInt(*images_[THUMB_TRACK][thumb_track_state_],
+ track_bounds.x(), track_bounds.y(),
+ track_bounds.width(), track_bounds.height());
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// BitmapScrollBar, private:
+
+void BitmapScrollBar::TrackClicked() {
+ if (last_scroll_amount_ != SCROLL_NONE)
+ ScrollByAmount(last_scroll_amount_);
+}
+
+void BitmapScrollBar::ScrollContentsToOffset() {
+ GetController()->ScrollToPosition(this, contents_scroll_offset_);
+ thumb_->SetPosition(CalculateThumbPosition(contents_scroll_offset_));
+}
+
+int BitmapScrollBar::GetTrackSize() const {
+ gfx::Rect track_bounds = GetTrackBounds();
+ return IsHorizontal() ? track_bounds.width() : track_bounds.height();
+}
+
+int BitmapScrollBar::CalculateThumbPosition(int contents_scroll_offset) const {
+ return (contents_scroll_offset * GetTrackSize()) / contents_size_;
+}
+
+int BitmapScrollBar::CalculateContentsOffset(int thumb_position,
+ bool scroll_to_middle) const {
+ if (scroll_to_middle)
+ thumb_position = thumb_position - (thumb_->GetSize() / 2);
+ return (thumb_position * contents_size_) / GetTrackSize();
+}
+
+void BitmapScrollBar::SetThumbTrackState(CustomButton::ButtonState state) {
+ thumb_track_state_ = state;
+ SchedulePaint();
+}
+
} // namespace views
diff --git a/views/controls/scrollbar/bitmap_scroll_bar.h b/views/controls/scrollbar/bitmap_scroll_bar.h
index 8b9a8fb..ce072bf 100644
--- a/views/controls/scrollbar/bitmap_scroll_bar.h
+++ b/views/controls/scrollbar/bitmap_scroll_bar.h
@@ -6,7 +6,11 @@
#define VIEWS_CONTROLS_SCROLLBAR_BITMAP_SCROLL_BAR_H_
#pragma once
-#include "views/controls/scrollbar/base_scroll_bar.h"
+#include "views/context_menu_controller.h"
+#include "views/controls/button/image_button.h"
+#include "views/controls/menu/menu.h"
+#include "views/controls/scrollbar/scroll_bar.h"
+#include "views/repeat_controller.h"
namespace views {
@@ -23,13 +27,24 @@ class BitmapScrollBarThumb;
// well as for the thumb and track. This is intended for creating UIs that
// have customized, non-native appearances, like floating HUDs etc.
//
+// Maybe TODO(beng): (Cleanup) If we need to, we may want to factor rendering
+// out of this altogether and have the user supply
+// Background impls for each component, and just use those
+// to render, so that for example we get native theme
+// rendering.
+//
///////////////////////////////////////////////////////////////////////////////
-class BitmapScrollBar : public BaseScrollBar,
- public ButtonListener {
+class BitmapScrollBar : public ScrollBar,
+ public ButtonListener,
+ public ContextMenuController,
+ public Menu::Delegate {
public:
BitmapScrollBar(bool horizontal, bool show_scroll_buttons);
virtual ~BitmapScrollBar() { }
+ // Get the bounds of the "track" area that the thumb is free to slide within.
+ gfx::Rect GetTrackBounds() const;
+
// A list of parts that the user may supply bitmaps for.
enum ScrollBarPart {
// The button used to represent scrolling up/left by 1 line.
@@ -56,31 +71,122 @@ class BitmapScrollBar : public BaseScrollBar,
CustomButton::ButtonState state,
SkBitmap* bitmap);
+ // An enumeration of different amounts of incremental scroll, representing
+ // events sent from different parts of the UI/keyboard.
+ enum ScrollAmount {
+ SCROLL_NONE = 0,
+ SCROLL_START,
+ SCROLL_END,
+ SCROLL_PREV_LINE,
+ SCROLL_NEXT_LINE,
+ SCROLL_PREV_PAGE,
+ SCROLL_NEXT_PAGE,
+ };
- gfx::Rect GetTrackBounds() const;
+ // Scroll the contents by the specified type (see ScrollAmount above).
+ void ScrollByAmount(ScrollAmount amount);
+
+ // Scroll the contents to the appropriate position given the supplied
+ // position of the thumb (thumb track coordinates). If |scroll_to_middle| is
+ // true, then the conversion assumes |thumb_position| is in the middle of the
+ // thumb rather than the top.
+ void ScrollToThumbPosition(int thumb_position, bool scroll_to_middle);
+
+ // Scroll the contents by the specified offset (contents coordinates).
+ void ScrollByContentsOffset(int contents_offset);
- protected:
// View overrides:
virtual gfx::Size GetPreferredSize() OVERRIDE;
virtual void Layout() OVERRIDE;
- virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
-
- // ScrollBar overrides:
- virtual int GetLayoutSize() const OVERRIDE;
+ virtual bool OnMousePressed(const MouseEvent& event) OVERRIDE;
+ virtual void OnMouseReleased(const MouseEvent& event) OVERRIDE;
+ virtual void OnMouseCaptureLost() OVERRIDE;
+ virtual bool OnKeyPressed(const KeyEvent& event) OVERRIDE;
+ virtual bool OnMouseWheel(const MouseWheelEvent& event) OVERRIDE;
// BaseButton::ButtonListener overrides:
virtual void ButtonPressed(Button* sender,
const views::Event& event) OVERRIDE;
+ // ScrollBar overrides:
+ virtual void Update(int viewport_size,
+ int content_size,
+ int contents_scroll_offset) OVERRIDE;
+ virtual int GetLayoutSize() const OVERRIDE;
+ virtual int GetPosition() const OVERRIDE;
+
+ // ContextMenuController overrides.
+ virtual void ShowContextMenuForView(View* source,
+ const gfx::Point& p,
+ bool is_mouse_gesture) OVERRIDE;
+
+ // Menu::Delegate overrides:
+ virtual std::wstring GetLabel(int id) const OVERRIDE;
+ virtual bool IsCommandEnabled(int id) const OVERRIDE;
+ virtual void ExecuteCommand(int id) OVERRIDE;
+
+ protected:
+ // View overrides:
+ virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
+
private:
- // Up/Down/Left/Right buttons.
- ImageButton* prev_button_;
- ImageButton* next_button_;
+ // Called when the mouse is pressed down in the track area.
+ void TrackClicked();
+
+ // Responsible for scrolling the contents and also updating the UI to the
+ // current value of the Scroll Offset.
+ void ScrollContentsToOffset();
+
+ // Returns the size (width or height) of the track area of the ScrollBar.
+ int GetTrackSize() const;
+
+ // Calculate the position of the thumb within the track based on the
+ // specified scroll offset of the contents.
+ int CalculateThumbPosition(int contents_scroll_offset) const;
+
+ // Calculates the current value of the contents offset (contents coordinates)
+ // based on the current thumb position (thumb track coordinates). See
+ // |ScrollToThumbPosition| for an explanation of |scroll_to_middle|.
+ int CalculateContentsOffset(int thumb_position,
+ bool scroll_to_middle) const;
+
+ // Called when the state of the thumb track changes (e.g. by the user
+ // pressing the mouse button down in it).
+ void SetThumbTrackState(CustomButton::ButtonState state);
// The thumb needs to be able to access the part images.
friend BitmapScrollBarThumb;
SkBitmap* images_[PART_COUNT][CustomButton::BS_COUNT];
+ // The size of the scrolled contents, in pixels.
+ int contents_size_;
+
+ // The current amount the contents is offset by in the viewport.
+ int contents_scroll_offset_;
+
+ // Up/Down/Left/Right buttons and the Thumb.
+ ImageButton* prev_button_;
+ ImageButton* next_button_;
+ BitmapScrollBarThumb* thumb_;
+
+ // The state of the scrollbar track. Typically, the track will highlight when
+ // the user presses the mouse on them (during page scrolling).
+ CustomButton::ButtonState thumb_track_state_;
+
+ // The last amount of incremental scroll that this scrollbar performed. This
+ // is accessed by the callbacks for the auto-repeat up/down buttons to know
+ // what direction to repeatedly scroll in.
+ ScrollAmount last_scroll_amount_;
+
+ // An instance of a RepeatController which scrolls the scrollbar continuously
+ // as the user presses the mouse button down on the up/down buttons or the
+ // track.
+ RepeatController repeater_;
+
+ // The position of the mouse within the scroll bar when the context menu
+ // was invoked.
+ int context_menu_mouse_position_;
+
// True if the scroll buttons at each end of the scroll bar should be shown.
bool show_scroll_buttons_;
diff --git a/views/controls/scrollbar/native_scroll_bar_gtk.cc b/views/controls/scrollbar/native_scroll_bar_gtk.cc
index cd9bebd..dc1a9b6 100644
--- a/views/controls/scrollbar/native_scroll_bar_gtk.cc
+++ b/views/controls/scrollbar/native_scroll_bar_gtk.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -8,9 +8,7 @@
#include "ui/base/keycodes/keyboard_codes_posix.h"
#include "views/controls/scrollbar/native_scroll_bar.h"
-#include "views/controls/scrollbar/native_scroll_bar_views.h"
#include "views/controls/scrollbar/scroll_bar.h"
-#include "views/widget/widget.h"
namespace views {
@@ -201,8 +199,6 @@ void NativeScrollBarGtk::MoveToBottom() {
// static
NativeScrollBarWrapper* NativeScrollBarWrapper::CreateWrapper(
NativeScrollBar* scroll_bar) {
- if (Widget::IsPureViews())
- return new NativeScrollBarViews(scroll_bar);
return new NativeScrollBarGtk(scroll_bar);
}
diff --git a/views/controls/scrollbar/native_scroll_bar_views.cc b/views/controls/scrollbar/native_scroll_bar_views.cc
deleted file mode 100644
index 775c23c..0000000
--- a/views/controls/scrollbar/native_scroll_bar_views.cc
+++ /dev/null
@@ -1,371 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "views/controls/scrollbar/native_scroll_bar_views.h"
-
-#include "base/logging.h"
-#include "ui/base/keycodes/keyboard_codes.h"
-#include "ui/gfx/canvas.h"
-#include "ui/gfx/canvas_skia.h"
-#include "ui/gfx/path.h"
-#include "views/controls/button/custom_button.h"
-#include "views/controls/focusable_border.h"
-#include "views/controls/scrollbar/native_scroll_bar.h"
-#include "views/controls/scrollbar/scroll_bar.h"
-#include "views/controls/scrollbar/base_scroll_bar_button.h"
-#include "views/controls/scrollbar/base_scroll_bar_thumb.h"
-
-namespace views {
-
-namespace {
-
-// Wrapper for the scroll buttons.
-class ScrollBarButton : public BaseScrollBarButton {
- public:
- enum Type {
- UP,
- DOWN,
- LEFT,
- RIGHT,
- };
-
- ScrollBarButton(ButtonListener* listener, Type type);
- virtual ~ScrollBarButton();
-
- virtual gfx::Size GetPreferredSize() OVERRIDE;
-
- protected:
- virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
-
- private:
- gfx::NativeTheme::ExtraParams GetNativeThemeParams() const;
- gfx::NativeTheme::Part GetNativeThemePart() const;
- gfx::NativeTheme::State GetNativeThemeState() const;
-
- Type type_;
-};
-
-// Wrapper for the scroll thumb
-class ScrollBarThumb : public BaseScrollBarThumb {
- public:
- explicit ScrollBarThumb(BaseScrollBar* scroll_bar);
- virtual ~ScrollBarThumb();
-
- virtual gfx::Size GetPreferredSize() OVERRIDE;
-
- protected:
- virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
-
- private:
- gfx::NativeTheme::ExtraParams GetNativeThemeParams() const;
- gfx::NativeTheme::Part GetNativeThemePart() const;
- gfx::NativeTheme::State GetNativeThemeState() const;
-
- ScrollBar* scroll_bar_;
-};
-
-/////////////////////////////////////////////////////////////////////////////
-// ScrollBarButton
-
-ScrollBarButton::ScrollBarButton(
- ButtonListener* listener,
- Type type)
- : BaseScrollBarButton(listener),
- type_(type) {
-}
-
-ScrollBarButton::~ScrollBarButton() {
-}
-
-gfx::Size ScrollBarButton::GetPreferredSize() {
- const gfx::NativeTheme* native_theme = gfx::NativeTheme::instance();
- return native_theme->GetPartSize(GetNativeThemePart(),
- GetNativeThemeState(),
- GetNativeThemeParams());
-}
-
-void ScrollBarButton::OnPaint(gfx::Canvas* canvas) {
- const gfx::NativeTheme* native_theme = gfx::NativeTheme::instance();
- gfx::Rect bounds;
- bounds.set_size(GetPreferredSize());
-
- native_theme->Paint(canvas->AsCanvasSkia(),
- GetNativeThemePart(),
- GetNativeThemeState(),
- bounds,
- GetNativeThemeParams());
-}
-
-gfx::NativeTheme::ExtraParams
- ScrollBarButton::GetNativeThemeParams() const {
- gfx::NativeTheme::ExtraParams params;
-
- switch (state_) {
- case CustomButton::BS_HOT:
- params.scrollbar_arrow.is_hovering = true;
- break;
- default:
- params.scrollbar_arrow.is_hovering = false;
- break;
- }
-
- return params;
-}
-
-gfx::NativeTheme::Part
- ScrollBarButton::GetNativeThemePart() const {
- switch (type_) {
- case UP:
- return gfx::NativeTheme::kScrollbarUpArrow;
- case DOWN:
- return gfx::NativeTheme::kScrollbarDownArrow;
- case LEFT:
- return gfx::NativeTheme::kScrollbarLeftArrow;
- case RIGHT:
- return gfx::NativeTheme::kScrollbarRightArrow;
- default:
- return gfx::NativeTheme::kScrollbarUpArrow;
- }
-}
-
-gfx::NativeTheme::State
- ScrollBarButton::GetNativeThemeState() const {
- gfx::NativeTheme::State state;
-
- switch (state_) {
- case CustomButton::BS_HOT:
- state = gfx::NativeTheme::kHovered;
- break;
- case CustomButton::BS_PUSHED:
- state = gfx::NativeTheme::kPressed;
- break;
- case CustomButton::BS_DISABLED:
- state = gfx::NativeTheme::kDisabled;
- break;
- case CustomButton::BS_NORMAL:
- default:
- state = gfx::NativeTheme::kNormal;
- break;
- }
-
- return state;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-// ScrollBarThumb
-
-ScrollBarThumb::ScrollBarThumb(BaseScrollBar* scroll_bar)
- : BaseScrollBarThumb(scroll_bar),
- scroll_bar_(scroll_bar) {
-}
-
-ScrollBarThumb::~ScrollBarThumb() {
-}
-
-gfx::Size ScrollBarThumb::GetPreferredSize() {
- const gfx::NativeTheme* native_theme = gfx::NativeTheme::instance();
- return native_theme->GetPartSize(GetNativeThemePart(),
- GetNativeThemeState(),
- GetNativeThemeParams());
-}
-
-void ScrollBarThumb::OnPaint(gfx::Canvas* canvas) {
- const gfx::NativeTheme* native_theme = gfx::NativeTheme::instance();
-
- native_theme->Paint(canvas->AsCanvasSkia(),
- GetNativeThemePart(),
- GetNativeThemeState(),
- GetLocalBounds(),
- GetNativeThemeParams());
-}
-
-gfx::NativeTheme::ExtraParams
- ScrollBarThumb::GetNativeThemeParams() const {
- gfx::NativeTheme::ExtraParams params;
-
- switch (GetState()) {
- case CustomButton::BS_HOT:
- params.scrollbar_thumb.is_hovering = true;
- break;
- default:
- params.scrollbar_thumb.is_hovering = false;
- break;
- }
-
- return params;
-}
-
-gfx::NativeTheme::Part ScrollBarThumb::GetNativeThemePart() const {
- if (scroll_bar_->IsHorizontal())
- return gfx::NativeTheme::kScrollbarHorizontalThumb;
- return gfx::NativeTheme::kScrollbarVerticalThumb;
-}
-
-gfx::NativeTheme::State ScrollBarThumb::GetNativeThemeState() const {
- gfx::NativeTheme::State state;
-
- switch (GetState()) {
- case CustomButton::BS_HOT:
- state = gfx::NativeTheme::kHovered;
- break;
- case CustomButton::BS_PUSHED:
- state = gfx::NativeTheme::kPressed;
- break;
- case CustomButton::BS_DISABLED:
- state = gfx::NativeTheme::kDisabled;
- break;
- case CustomButton::BS_NORMAL:
- default:
- state = gfx::NativeTheme::kNormal;
- break;
- }
-
- return state;
-}
-
-} // namespace
-
-////////////////////////////////////////////////////////////////////////////////
-// NativeScrollBarViews, public:
-
-NativeScrollBarViews::NativeScrollBarViews(NativeScrollBar* scroll_bar)
- : BaseScrollBar(scroll_bar->IsHorizontal(),
- new ScrollBarThumb(this)),
- native_scroll_bar_(scroll_bar) {
- SetController(native_scroll_bar_->GetController());
-
- if (native_scroll_bar_->IsHorizontal()) {
- prev_button_ = new ScrollBarButton(this, ScrollBarButton::LEFT);
- next_button_ = new ScrollBarButton(this, ScrollBarButton::RIGHT);
-
- part_ = gfx::NativeTheme::kScrollbarHorizontalTrack;
- } else {
- prev_button_ = new ScrollBarButton(this, ScrollBarButton::UP);
- next_button_ = new ScrollBarButton(this, ScrollBarButton::DOWN);
-
- part_ = gfx::NativeTheme::kScrollbarVerticalTrack;
- }
-
- state_ = gfx::NativeTheme::kNormal;
-
- AddChildView(prev_button_);
- AddChildView(next_button_);
-
- prev_button_->set_context_menu_controller(this);
- next_button_->set_context_menu_controller(this);
-}
-
-NativeScrollBarViews::~NativeScrollBarViews() {
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// NativeScrollBarViews, View overrides:
-
-void NativeScrollBarViews::Layout() {
- SetBoundsRect(native_scroll_bar_->GetLocalBounds());
-
- gfx::Size size = prev_button_->GetPreferredSize();
- prev_button_->SetBounds(0, 0, size.width(), size.height());
-
- if (native_scroll_bar_->IsHorizontal()) {
- next_button_->SetBounds(width() - size.width(), 0,
- size.width(), size.height());
- } else {
- next_button_->SetBounds(0, height() - size.height(),
- size.width(), size.height());
- }
-
- GetThumb()->SetBoundsRect(GetTrackBounds());
-}
-
-void NativeScrollBarViews::OnPaint(gfx::Canvas* canvas) {
- const gfx::NativeTheme* native_theme = gfx::NativeTheme::instance();
- gfx::Rect bounds = GetTrackBounds();
-
- params_.scrollbar_track.track_x = bounds.x();
- params_.scrollbar_track.track_y = bounds.y();
- params_.scrollbar_track.track_width = bounds.width();
- params_.scrollbar_track.track_height = bounds.height();
-
-
- native_theme->Paint(canvas->AsCanvasSkia(),
- part_,
- state_,
- bounds,
- params_);
-}
-
-gfx::Size NativeScrollBarViews::GetPreferredSize() {
- if (native_scroll_bar_->IsHorizontal())
- return gfx::Size(0, GetHorizontalScrollBarHeight());
- return gfx::Size(GetVerticalScrollBarWidth(), 0);
-}
-
-int NativeScrollBarViews::GetLayoutSize() const {
- gfx::Size size = prev_button_->GetPreferredSize();
- return IsHorizontal() ? size.height() : size.width();
-}
-
-void NativeScrollBarViews::ScrollToPosition(int position) {
- GetController()->ScrollToPosition(native_scroll_bar_, position);
-}
-
-int NativeScrollBarViews::GetScrollIncrement(bool is_page,
- bool is_positive) {
- return GetController()->GetScrollIncrement(native_scroll_bar_,
- is_page,
- is_positive);
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// BaseButton::ButtonListener overrides:
-
-void NativeScrollBarViews::ButtonPressed(Button* sender,
- const views::Event& event) {
- if (sender == prev_button_) {
- ScrollByAmount(SCROLL_PREV_LINE);
- } else if (sender == next_button_) {
- ScrollByAmount(SCROLL_NEXT_LINE);
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// NativeScrollBarViews, NativeScrollBarWrapper overrides:
-
-int NativeScrollBarViews::GetPosition() const {
- return BaseScrollBar::GetPosition();
-}
-
-View* NativeScrollBarViews::GetView() {
- return this;
-}
-
-void NativeScrollBarViews::Update(int viewport_size,
- int content_size,
- int current_pos) {
- BaseScrollBar::Update(viewport_size, content_size, current_pos);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// NativeScrollBarViews, private:
-
-gfx::Rect NativeScrollBarViews::GetTrackBounds() const {
- gfx::Rect bounds = GetLocalBounds();
- gfx::Size size = prev_button_->GetPreferredSize();
- BaseScrollBarThumb* thumb = GetThumb();
-
- if (native_scroll_bar_->IsHorizontal()) {
- bounds.set_x(bounds.x() + size.width());
- bounds.set_width(bounds.width() - 2 * size.width());
- bounds.set_height(thumb->GetPreferredSize().height());
- } else {
- bounds.set_y(bounds.y() + size.height());
- bounds.set_height(bounds.height() - 2 * size.height());
- bounds.set_width(thumb->GetPreferredSize().width());
- }
-
- return bounds;
-}
-
-} // namespace views
diff --git a/views/controls/scrollbar/native_scroll_bar_views.h b/views/controls/scrollbar/native_scroll_bar_views.h
deleted file mode 100644
index ae3a9a6..0000000
--- a/views/controls/scrollbar/native_scroll_bar_views.h
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef VIEWS_CONTROLS_SCROLLBAR_NATIVE_SCROLL_BAR_VIEWS_H_
-#define VIEWS_CONTROLS_SCROLLBAR_NATIVE_SCROLL_BAR_VIEWS_H_
-#pragma once
-
-#include "ui/gfx/native_theme.h"
-#include "ui/gfx/point.h"
-#include "views/controls/button/button.h"
-#include "views/controls/scrollbar/base_scroll_bar.h"
-#include "views/controls/scrollbar/native_scroll_bar_wrapper.h"
-#include "views/view.h"
-
-namespace gfx {
-class Canvas;
-}
-
-namespace views {
-
-class NativeScrollBar;
-
-// Views implementation for the scrollbar.
-class NativeScrollBarViews : public BaseScrollBar,
- public ButtonListener,
- public NativeScrollBarWrapper {
- public:
- // Creates new scrollbar, either horizontal or vertical.
- explicit NativeScrollBarViews(NativeScrollBar* native_scroll_bar);
- virtual ~NativeScrollBarViews();
-
- private:
- // View overrides:
- virtual void Layout();
- virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
- virtual gfx::Size GetPreferredSize();
-
- // ScrollBar overrides:
- virtual int GetLayoutSize() const OVERRIDE;
-
- // BaseScrollBar overrides:
- virtual void ScrollToPosition(int position);
- virtual int GetScrollIncrement(bool is_page, bool is_positive);
-
- // BaseButton::ButtonListener overrides:
- virtual void ButtonPressed(Button* sender,
- const views::Event& event) OVERRIDE;
-
- // NativeScrollBarWrapper overrides:
- virtual int GetPosition() const;
- virtual View* GetView();
- virtual void Update(int viewport_size, int content_size, int current_pos);
-
- // Returns the area for the track. This is the area of the scrollbar minus
- // the size of the arrow buttons.
- gfx::Rect GetTrackBounds() const;
-
- // The NativeScrollBar we are bound to.
- NativeScrollBar* native_scroll_bar_;
-
- // The scroll bar buttons (Up/Down, Left/Right).
- Button* prev_button_;
- Button* next_button_;
-
- gfx::NativeTheme::ExtraParams params_;
- gfx::NativeTheme::Part part_;
- gfx::NativeTheme::State state_;
-
- DISALLOW_COPY_AND_ASSIGN(NativeScrollBarViews);
-};
-
-} // namespace views
-
-#endif // VIEWS_CONTROLS_SCROLLBAR_NATIVE_SCROLL_BAR_VIEWS_H_
-
diff --git a/views/controls/scrollbar/scrollbar_unittest.cc b/views/controls/scrollbar/scrollbar_unittest.cc
deleted file mode 100644
index a19bfe6..0000000
--- a/views/controls/scrollbar/scrollbar_unittest.cc
+++ /dev/null
@@ -1,150 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "views/controls/scrollbar/scroll_bar.h"
-#include "views/controls/scrollbar/native_scroll_bar.h"
-#include "views/controls/scrollbar/native_scroll_bar_views.h"
-#include "views/test/views_test_base.h"
-#include "views/widget/widget.h"
-
-namespace {
-
-// The Scrollbar controller. This is the widget that should do the real
-// scrolling of contents.
-class TestScrollBarController : public views::ScrollBarController {
- public:
- virtual void ScrollToPosition(views::ScrollBar* source,
- int position) OVERRIDE {
- last_source = source;
- last_position = position;
- }
-
- virtual int GetScrollIncrement(views::ScrollBar* source,
- bool is_page,
- bool is_positive) OVERRIDE {
- last_source = source;
- last_is_page = is_page;
- last_is_positive = is_positive;
-
- if (is_page)
- return 20;
- return 10;
- }
-
- // We save the last values in order to assert the corectness of the scroll
- // operation.
- views::ScrollBar* last_source;
- bool last_is_positive;
- bool last_is_page;
- int last_position;
-};
-
-} // namespace
-
-namespace views {
-
-class NativeScrollBarTest : public ViewsTestBase {
- public:
- NativeScrollBarTest()
- : widget_(NULL),
- scrollbar_(NULL),
- controller_(NULL) {
- }
-
- virtual void SetUp() {
- ViewsTestBase::SetUp();
- Widget::SetPureViews(true);
- }
-
- virtual void TearDown() {
- Widget::SetPureViews(false);
- if (widget_)
- widget_->Close();
- ViewsTestBase::TearDown();
- }
-
- void InitScrollBar() {
- controller_.reset(new TestScrollBarController());
-
- ASSERT_FALSE(scrollbar_);
- native_scrollbar_ = new NativeScrollBar(true);
- native_scrollbar_->SetBounds(0, 0, 100, 100);
- scrollbar_ = new NativeScrollBarViews(native_scrollbar_);
- scrollbar_->SetController(controller_.get());
-
- widget_ = new Widget;
- Widget::InitParams params(Widget::InitParams::TYPE_POPUP);
- params.bounds = gfx::Rect(0, 0, 100, 100);
- widget_->Init(params);
- View* container = new View();
- widget_->SetContentsView(container);
- container->AddChildView(scrollbar_);
- scrollbar_->SetBounds(0, 0, 100, 100);
- scrollbar_->Update(100, 200, 0);
-
- track_size_ = scrollbar_->GetTrackBounds().width();
- }
-
- protected:
- Widget* widget_;
-
- // This is the native scrollbar the Views one wraps around.
- NativeScrollBar* native_scrollbar_;
-
- // This is the Views scrollbar.
- BaseScrollBar* scrollbar_;
-
- // Keep track of the size of the track. This is how we can tell when we
- // scroll to the middle.
- int track_size_;
-
- scoped_ptr<TestScrollBarController> controller_;
-};
-
-// TODO(dnicoara) Can't run the test on Windows since the scrollbar |Part|
-// isn't handled in NativeTheme.
-#if defined(OS_WIN)
-TEST_F(NativeScrollBarTest, DISABLED_Scrolling) {
-#else
-TEST_F(NativeScrollBarTest, Scrolling) {
-#endif
- InitScrollBar();
- EXPECT_EQ(scrollbar_->GetPosition(), 0);
- EXPECT_EQ(scrollbar_->GetMaxPosition(), 100);
- EXPECT_EQ(scrollbar_->GetMinPosition(), 0);
-
- // Scroll to middle.
- scrollbar_->ScrollToThumbPosition(track_size_ / 4, false);
- EXPECT_EQ(controller_->last_position, 50);
- EXPECT_EQ(controller_->last_source, native_scrollbar_);
-
- // Scroll to the end.
- scrollbar_->ScrollToThumbPosition(track_size_ / 2, false);
- EXPECT_EQ(controller_->last_position, 100);
-
- // Overscroll. Last position should be the maximum position.
- scrollbar_->ScrollToThumbPosition(track_size_, false);
- EXPECT_EQ(controller_->last_position, 100);
-
- // Underscroll. Last position should be the minimum position.
- scrollbar_->ScrollToThumbPosition(-10, false);
- EXPECT_EQ(controller_->last_position, 0);
-
- // Test the different fixed scrolling amounts. Generally used by buttons,
- // or click on track.
- scrollbar_->ScrollToThumbPosition(0, false);
- scrollbar_->ScrollByAmount(BaseScrollBar::SCROLL_NEXT_LINE);
- EXPECT_EQ(controller_->last_position, 10);
-
- scrollbar_->ScrollByAmount(BaseScrollBar::SCROLL_PREV_LINE);
- EXPECT_EQ(controller_->last_position, 0);
-
- scrollbar_->ScrollByAmount(BaseScrollBar::SCROLL_NEXT_PAGE);
- EXPECT_EQ(controller_->last_position, 20);
-
- scrollbar_->ScrollByAmount(BaseScrollBar::SCROLL_PREV_PAGE);
- EXPECT_EQ(controller_->last_position, 0);
-}
-
-} // namespace views