diff options
author | jbates@chromium.org <jbates@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-25 16:21:57 +0000 |
---|---|---|
committer | jbates@chromium.org <jbates@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-25 16:21:57 +0000 |
commit | b751a2144e028ac6c069416a9d074dd06bbb37fa (patch) | |
tree | 44663e484b29322b9dae108939e91fda5393dd70 /views/controls | |
parent | d7a2c3c554dbdc1e6b951342d6f65801fe0a63cd (diff) | |
download | chromium_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.cc | 383 | ||||
-rw-r--r-- | views/controls/scrollbar/base_scroll_bar.h | 156 | ||||
-rw-r--r-- | views/controls/scrollbar/base_scroll_bar_button.cc | 47 | ||||
-rw-r--r-- | views/controls/scrollbar/base_scroll_bar_button.h | 50 | ||||
-rw-r--r-- | views/controls/scrollbar/base_scroll_bar_thumb.cc | 127 | ||||
-rw-r--r-- | views/controls/scrollbar/base_scroll_bar_thumb.h | 82 | ||||
-rw-r--r-- | views/controls/scrollbar/bitmap_scroll_bar.cc | 512 | ||||
-rw-r--r-- | views/controls/scrollbar/bitmap_scroll_bar.h | 130 | ||||
-rw-r--r-- | views/controls/scrollbar/native_scroll_bar_gtk.cc | 6 | ||||
-rw-r--r-- | views/controls/scrollbar/native_scroll_bar_views.cc | 371 | ||||
-rw-r--r-- | views/controls/scrollbar/native_scroll_bar_views.h | 76 | ||||
-rw-r--r-- | views/controls/scrollbar/scrollbar_unittest.cc | 150 |
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 |