diff options
author | oshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-23 22:30:16 +0000 |
---|---|---|
committer | oshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-23 22:30:16 +0000 |
commit | 34e32cf2dda2b1f4d5221749ddaac10690b8a63f (patch) | |
tree | 989cbf8baf6c21d21a0880b3a8d6ad7a12c3c985 /views | |
parent | 42ecb863ac38c351dd79f4b49f501f4bbd667cac (diff) | |
download | chromium_src-34e32cf2dda2b1f4d5221749ddaac10690b8a63f.zip chromium_src-34e32cf2dda2b1f4d5221749ddaac10690b8a63f.tar.gz chromium_src-34e32cf2dda2b1f4d5221749ddaac10690b8a63f.tar.bz2 |
Refactor window impl of scroll bar for future linux implementation.
- Changed NativeScrollBar to use native wrapper
- Added NativeScrollBarWapper for NativeScrollBar to delegate operations to
native control.
- Moved window specific impl in NativeScrollBar to NativeScrollBarWin class
which is a native wrapper.
- Fixed a bug in native_control_win. need to call Layout when
view visibility is changed after native contol is created.
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/214048
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@27013 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'views')
-rw-r--r-- | views/controls/native_control_win.cc | 7 | ||||
-rw-r--r-- | views/controls/scrollbar/native_scroll_bar.cc | 340 | ||||
-rw-r--r-- | views/controls/scrollbar/native_scroll_bar.h | 68 | ||||
-rw-r--r-- | views/controls/scrollbar/native_scroll_bar_win.cc | 346 | ||||
-rw-r--r-- | views/controls/scrollbar/native_scroll_bar_win.h | 62 | ||||
-rw-r--r-- | views/controls/scrollbar/native_scroll_bar_wrapper.h | 42 | ||||
-rw-r--r-- | views/controls/scrollbar/scroll_bar.h | 3 | ||||
-rw-r--r-- | views/views.gyp | 3 |
8 files changed, 544 insertions, 327 deletions
diff --git a/views/controls/native_control_win.cc b/views/controls/native_control_win.cc index 406b470..9f4d2d6 100644 --- a/views/controls/native_control_win.cc +++ b/views/controls/native_control_win.cc @@ -78,7 +78,12 @@ void NativeControlWin::VisibilityChanged(View* starting_from, bool is_visible) { Detach(); DestroyWindow(hwnd); } else if (!native_view()) { - CreateNativeControl(); + if (GetWidget()) + CreateNativeControl(); + } else { + // The view becomes visible after native control is created. + // Layout now. + Layout(); } } diff --git a/views/controls/scrollbar/native_scroll_bar.cc b/views/controls/scrollbar/native_scroll_bar.cc index 5ec60f3..39a9120 100644 --- a/views/controls/scrollbar/native_scroll_bar.cc +++ b/views/controls/scrollbar/native_scroll_bar.cc @@ -8,326 +8,94 @@ #include <string> #include "base/message_loop.h" -#include "base/window_impl.h" -#include "views/controls/native/native_view_host.h" +#include "views/controls/scrollbar/native_scroll_bar_wrapper.h" #include "views/widget/widget.h" namespace views { -///////////////////////////////////////////////////////////////////////////// -// -// ScrollBarContainer -// -// Since windows scrollbars only send notifications to their parent hwnd, we -// use instances of this class to wrap native scrollbars. -// -///////////////////////////////////////////////////////////////////////////// -class ScrollBarContainer : public base::WindowImpl { - public: - explicit ScrollBarContainer(ScrollBar* parent) : parent_(parent), - scrollbar_(NULL) { - set_window_style(WS_CHILD); - Init(parent->GetWidget()->GetNativeView(), gfx::Rect()); - ShowWindow(hwnd(), SW_SHOW); - } - - virtual ~ScrollBarContainer() { - } - - BEGIN_MSG_MAP_EX(ScrollBarContainer); - MSG_WM_CREATE(OnCreate); - MSG_WM_ERASEBKGND(OnEraseBkgnd); - MSG_WM_PAINT(OnPaint); - MSG_WM_SIZE(OnSize); - MSG_WM_HSCROLL(OnHorizScroll); - MSG_WM_VSCROLL(OnVertScroll); - END_MSG_MAP(); - - HWND GetScrollBarHWND() { - return scrollbar_; - } - - // Invoked when the scrollwheel is used - void ScrollWithOffset(int o) { - SCROLLINFO si; - si.cbSize = sizeof(si); - si.fMask = SIF_POS; - GetScrollInfo(scrollbar_, SB_CTL, &si); - int pos = si.nPos - o; - - if (pos < parent_->GetMinPosition()) - pos = parent_->GetMinPosition(); - else if (pos > parent_->GetMaxPosition()) - pos = parent_->GetMaxPosition(); - - ScrollBarController* sbc = parent_->GetController(); - sbc->ScrollToPosition(parent_, pos); - - si.nPos = pos; - si.fMask = SIF_POS; - SetScrollInfo(scrollbar_, SB_CTL, &si, TRUE); - } - - private: - - LRESULT OnCreate(LPCREATESTRUCT create_struct) { - scrollbar_ = CreateWindow(L"SCROLLBAR", L"", - WS_CHILD | (parent_->IsHorizontal() ? - SBS_HORZ : SBS_VERT), - 0, 0, parent_->width(), parent_->height(), - hwnd(), NULL, NULL, NULL); - ShowWindow(scrollbar_, SW_SHOW); - return 1; - } - - LRESULT OnEraseBkgnd(HDC dc) { - return 1; - } - - void OnPaint(HDC ignore) { - PAINTSTRUCT ps; - HDC dc = BeginPaint(hwnd(), &ps); - EndPaint(hwnd(), &ps); - } - - void OnSize(int type, const CSize& sz) { - SetWindowPos(scrollbar_, - 0, 0, 0, sz.cx, sz.cy, - SWP_DEFERERASE | SWP_NOACTIVATE | SWP_NOCOPYBITS | - SWP_NOOWNERZORDER | SWP_NOSENDCHANGING | SWP_NOZORDER); - } - - void OnScroll(int code, HWND source, bool is_horizontal) { - int pos; - - if (code == SB_ENDSCROLL) { - return; - } - - // If we receive an event from the scrollbar, make the view - // component focused so we actually get mousewheel events. - if (source != NULL) { - Widget* widget = parent_->GetWidget(); - if (widget && widget->GetNativeView() != GetFocus()) { - parent_->RequestFocus(); - } - } - - SCROLLINFO si; - si.cbSize = sizeof(si); - si.fMask = SIF_POS | SIF_TRACKPOS; - GetScrollInfo(scrollbar_, SB_CTL, &si); - pos = si.nPos; - - ScrollBarController* sbc = parent_->GetController(); - - switch (code) { - case SB_BOTTOM: // case SB_RIGHT: - pos = parent_->GetMaxPosition(); - break; - case SB_TOP: // case SB_LEFT: - pos = parent_->GetMinPosition(); - break; - case SB_LINEDOWN: // case SB_LINERIGHT: - pos += sbc->GetScrollIncrement(parent_, false, true); - pos = std::min(parent_->GetMaxPosition(), pos); - break; - case SB_LINEUP: // case SB_LINELEFT: - pos -= sbc->GetScrollIncrement(parent_, false, false); - pos = std::max(parent_->GetMinPosition(), pos); - break; - case SB_PAGEDOWN: // case SB_PAGERIGHT: - pos += sbc->GetScrollIncrement(parent_, true, true); - pos = std::min(parent_->GetMaxPosition(), pos); - break; - case SB_PAGEUP: // case SB_PAGELEFT: - pos -= sbc->GetScrollIncrement(parent_, true, false); - pos = std::max(parent_->GetMinPosition(), pos); - break; - case SB_THUMBPOSITION: - case SB_THUMBTRACK: - pos = si.nTrackPos; - if (pos < parent_->GetMinPosition()) - pos = parent_->GetMinPosition(); - else if (pos > parent_->GetMaxPosition()) - pos = parent_->GetMaxPosition(); - break; - default: - break; - } - - sbc->ScrollToPosition(parent_, pos); - - si.nPos = pos; - si.fMask = SIF_POS; - SetScrollInfo(scrollbar_, SB_CTL, &si, TRUE); - - // Note: the system scrollbar modal loop doesn't give a chance - // to our message_loop so we need to call DidProcessMessage() - // manually. - // - // Sadly, we don't know what message has been processed. We may - // want to remove the message from DidProcessMessage() - MSG dummy; - dummy.hwnd = NULL; - dummy.message = 0; - MessageLoopForUI::current()->DidProcessMessage(dummy); - } - - // note: always ignore 2nd param as it is 16 bits - void OnHorizScroll(int n_sb_code, int ignore, HWND source) { - OnScroll(n_sb_code, source, true); - } +// static +const char NativeScrollBar::kViewClassName[] = "views/NativeScrollBar"; - // note: always ignore 2nd param as it is 16 bits - void OnVertScroll(int n_sb_code, int ignore, HWND source) { - OnScroll(n_sb_code, source, false); - } +//////////////////////////////////////////////////////////////////////////////// +// NativeScrollBar, public: +NativeScrollBar::NativeScrollBar(bool is_horizontal) + : ScrollBar(is_horizontal), + native_wrapper_(NULL) { +} +NativeScrollBar::~NativeScrollBar() { +} +// static +int NativeScrollBar::GetHorizontalScrollBarHeight() { + return NativeScrollBarWrapper::GetHorizontalScrollBarHeight(); +} - ScrollBar* parent_; - HWND scrollbar_; -}; +// static +int NativeScrollBar::GetVerticalScrollBarWidth() { + return NativeScrollBarWrapper::GetVerticalScrollBarWidth(); +} -NativeScrollBar::NativeScrollBar(bool is_horiz) - : sb_view_(NULL), - sb_container_(NULL), - ScrollBar(is_horiz) { +//////////////////////////////////////////////////////////////////////////////// +// NativeScrollBar, View overrides: +gfx::Size NativeScrollBar::GetPreferredSize() { + if (native_wrapper_) + return native_wrapper_->GetView()->GetPreferredSize(); + return gfx::Size(); } -NativeScrollBar::~NativeScrollBar() { - if (sb_container_) { - // We always destroy the scrollbar container explicitly to cover all - // cases including when the container is no longer connected to a - // widget tree. - DestroyWindow(sb_container_->hwnd()); - delete sb_container_; - } +void NativeScrollBar::Layout() { + if (native_wrapper_) + native_wrapper_->GetView()->Layout(); } void NativeScrollBar::ViewHierarchyChanged(bool is_add, View *parent, View *child) { Widget* widget; - if (is_add && (widget = GetWidget()) && !sb_view_) { - sb_view_ = new NativeViewHost; - AddChildView(sb_view_); - sb_container_ = new ScrollBarContainer(this); - sb_view_->Attach(sb_container_->hwnd()); - Layout(); + if (is_add && !native_wrapper_ && (widget = GetWidget())) { + native_wrapper_ = NativeScrollBarWrapper::CreateWrapper(this); + AddChildView(native_wrapper_->GetView()); } } -void NativeScrollBar::Layout() { - if (sb_view_) - sb_view_->SetBounds(GetLocalBounds(true)); +std::string NativeScrollBar::GetClassName() const { + return kViewClassName; } -gfx::Size NativeScrollBar::GetPreferredSize() { - if (IsHorizontal()) - return gfx::Size(0, GetLayoutSize()); - return gfx::Size(GetLayoutSize(), 0); +// Overridden from View for keyboard UI. +bool NativeScrollBar::OnKeyPressed(const KeyEvent& event) { + if (!native_wrapper_) + return false; + return native_wrapper_->GetView()->OnKeyPressed(event); +} + +bool NativeScrollBar::OnMouseWheel(const MouseWheelEvent& event) { + if (!native_wrapper_) + return false; + return native_wrapper_->GetView()->OnMouseWheel(event); } +//////////////////////////////////////////////////////////////////////////////// +// NativeScrollBar, ScrollBar overrides: void NativeScrollBar::Update(int viewport_size, int content_size, int current_pos) { ScrollBar::Update(viewport_size, content_size, current_pos); - if (!sb_container_) - return; - if (content_size < 0) - content_size = 0; - - if (current_pos < 0) - current_pos = 0; - - if (current_pos > content_size) - current_pos = content_size; - - SCROLLINFO si; - si.cbSize = sizeof(si); - si.fMask = SIF_DISABLENOSCROLL | SIF_POS | SIF_RANGE | SIF_PAGE; - si.nMin = 0; - si.nMax = content_size; - si.nPos = current_pos; - si.nPage = viewport_size; - SetScrollInfo(sb_container_->GetScrollBarHWND(), SB_CTL, &si, TRUE); + if (native_wrapper_) + native_wrapper_->Update(viewport_size, content_size, current_pos); } int NativeScrollBar::GetLayoutSize() const { - return GetSystemMetrics(IsHorizontal() ? SM_CYHSCROLL : SM_CYVSCROLL); + return IsHorizontal() ? + GetHorizontalScrollBarHeight() : GetVerticalScrollBarWidth(); } int NativeScrollBar::GetPosition() const { - SCROLLINFO si; - si.cbSize = sizeof(si); - si.fMask = SIF_POS; - GetScrollInfo(sb_container_->GetScrollBarHWND(), SB_CTL, &si); - return si.nPos; -} - -bool NativeScrollBar::OnMouseWheel(const MouseWheelEvent& e) { - if (!sb_container_) { - return false; - } - - sb_container_->ScrollWithOffset(e.GetOffset()); - return true; -} - -bool NativeScrollBar::OnKeyPressed(const KeyEvent& event) { - if (!sb_container_) { - return false; - } - int code = -1; - switch (event.GetCharacter()) { - case VK_UP: - if (!IsHorizontal()) - code = SB_LINEUP; - break; - case VK_PRIOR: - code = SB_PAGEUP; - break; - case VK_NEXT: - code = SB_PAGEDOWN; - break; - case VK_DOWN: - if (!IsHorizontal()) - code = SB_LINEDOWN; - break; - case VK_HOME: - code = SB_TOP; - break; - case VK_END: - code = SB_BOTTOM; - break; - case VK_LEFT: - if (IsHorizontal()) - code = SB_LINELEFT; - break; - case VK_RIGHT: - if (IsHorizontal()) - code = SB_LINERIGHT; - break; - } - if (code != -1) { - SendMessage(sb_container_->hwnd(), - IsHorizontal() ? WM_HSCROLL : WM_VSCROLL, - MAKELONG(static_cast<WORD>(code), 0), 0L); - return true; - } - return false; -} - -// static -int NativeScrollBar::GetHorizontalScrollBarHeight() { - return GetSystemMetrics(SM_CYHSCROLL); -} - -// static -int NativeScrollBar::GetVerticalScrollBarWidth() { - return GetSystemMetrics(SM_CXVSCROLL); + if (!native_wrapper_) + return 0; + return native_wrapper_->GetPosition(); } } // namespace views + diff --git a/views/controls/scrollbar/native_scroll_bar.h b/views/controls/scrollbar/native_scroll_bar.h index 85a0453..6595a09 100644 --- a/views/controls/scrollbar/native_scroll_bar.h +++ b/views/controls/scrollbar/native_scroll_bar.h @@ -1,67 +1,57 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2006-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. -#ifndef VIEWS_CONTROLS_SCROLLBAR_NATIVE_SCROLLBAR_H_ -#define VIEWS_CONTROLS_SCROLLBAR_NATIVE_SCROLLBAR_H_ +#ifndef VIEWS_CONTROLS_SCROLLBAR_NATIVE_SCROLL_BAR_H_ +#define VIEWS_CONTROLS_SCROLLBAR_NATIVE_SCROLL_BAR_H_ -#include "build/build_config.h" +#include <string> #include "views/controls/scrollbar/scroll_bar.h" +#include "views/view.h" namespace views { -class NativeViewHost; -class ScrollBarContainer; - -///////////////////////////////////////////////////////////////////////////// -// -// NativeScrollBar -// -// A View subclass that wraps a Native Windows scrollbar control. -// -// A scrollbar is either horizontal or vertical. -// -///////////////////////////////////////////////////////////////////////////// +class NativeScrollBarWrapper; + +// The NativeScrollBar class is a scrollbar that uses platform's +// native control. class NativeScrollBar : public ScrollBar { public: + // The scroll-bar's class name. + static const char kViewClassName[]; - // Create new scrollbar, either horizontal or vertical + // Create new scrollbar, either horizontal or vertical. explicit NativeScrollBar(bool is_horiz); virtual ~NativeScrollBar(); - // Overridden for layout purpose - virtual void Layout(); + // Return the system sizes. + static int GetHorizontalScrollBarHeight(); + static int GetVerticalScrollBarWidth(); + + private: + // Overridden from View. virtual gfx::Size GetPreferredSize(); + virtual void Layout(); + virtual void ViewHierarchyChanged(bool is_add, View* parent, View* child); + virtual std::string GetClassName() const; - // Overridden for keyboard UI purpose + // Overrideen from View for keyboard UI purpose. virtual bool OnKeyPressed(const KeyEvent& event); virtual bool OnMouseWheel(const MouseWheelEvent& e); - virtual void ViewHierarchyChanged(bool is_add, View *parent, View *child); - - // Overridden from ScrollBar + // Overridden from ScrollBar. virtual void Update(int viewport_size, int content_size, int current_pos); - virtual int GetLayoutSize() const; virtual int GetPosition() const; + virtual int GetLayoutSize() const; - // Return the system sizes - static int GetHorizontalScrollBarHeight(); - static int GetVerticalScrollBarWidth(); + // init border + NativeScrollBarWrapper* native_wrapper_; - private: -#if defined(OS_WIN) - // The sb_view_ takes care of keeping sb_container in sync with the - // view hierarchy - NativeViewHost* sb_view_; -#endif // defined(OS_WIN) - - // sb_container_ is a custom hwnd that we use to wrap the real - // windows scrollbar. We need to do this to get the scroll events - // without having to do anything special in the high level hwnd. - ScrollBarContainer* sb_container_; + DISALLOW_COPY_AND_ASSIGN(NativeScrollBar); }; } // namespace views -#endif // #ifndef VIEWS_CONTROLS_SCROLLBAR_NATIVE_SCROLLBAR_H_ +#endif // VIEWS_CONTROLS_SCROLLBAR_NATIVE_SCROLL_BAR_H_ + diff --git a/views/controls/scrollbar/native_scroll_bar_win.cc b/views/controls/scrollbar/native_scroll_bar_win.cc new file mode 100644 index 0000000..b15be33 --- /dev/null +++ b/views/controls/scrollbar/native_scroll_bar_win.cc @@ -0,0 +1,346 @@ +// 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. + +#include "views/controls/scrollbar/native_scroll_bar_win.h" + +#include <algorithm> +#include <string> + +#include "base/message_loop.h" +#include "base/window_impl.h" +#include "views/controls/scrollbar/native_scroll_bar.h" +#include "views/controls/scrollbar/scroll_bar.h" +#include "views/widget/widget.h" + +namespace views { + +///////////////////////////////////////////////////////////////////////////// +// +// ScrollBarContainer +// +// Since windows scrollbars only send notifications to their parent hwnd, we +// use instances of this class to wrap native scrollbars. +// +///////////////////////////////////////////////////////////////////////////// +class ScrollBarContainer : public base::WindowImpl { + public: + explicit ScrollBarContainer(ScrollBar* parent) + : parent_(parent), + scrollbar_(NULL) { + set_window_style(WS_CHILD); + Init(parent->GetWidget()->GetNativeView(), gfx::Rect()); + ShowWindow(hwnd(), SW_SHOW); + } + + virtual ~ScrollBarContainer() { + } + + BEGIN_MSG_MAP_EX(ScrollBarContainer); + MSG_WM_CREATE(OnCreate); + MSG_WM_ERASEBKGND(OnEraseBkgnd); + MSG_WM_PAINT(OnPaint); + MSG_WM_SIZE(OnSize); + MSG_WM_HSCROLL(OnHorizScroll); + MSG_WM_VSCROLL(OnVertScroll); + END_MSG_MAP(); + + HWND GetScrollBarHWND() { + return scrollbar_; + } + + // Invoked when the scrollwheel is used + void ScrollWithOffset(int o) { + SCROLLINFO si; + si.cbSize = sizeof(si); + si.fMask = SIF_POS; + GetScrollInfo(scrollbar_, SB_CTL, &si); + int pos = si.nPos - o; + + if (pos < parent_->GetMinPosition()) + pos = parent_->GetMinPosition(); + else if (pos > parent_->GetMaxPosition()) + pos = parent_->GetMaxPosition(); + + ScrollBarController* sbc = parent_->GetController(); + sbc->ScrollToPosition(parent_, pos); + + si.nPos = pos; + si.fMask = SIF_POS; + SetScrollInfo(scrollbar_, SB_CTL, &si, TRUE); + } + + private: + + LRESULT OnCreate(LPCREATESTRUCT create_struct) { + scrollbar_ = CreateWindow(L"SCROLLBAR", L"", + WS_CHILD | (parent_->IsHorizontal() ? + SBS_HORZ : SBS_VERT), + 0, 0, parent_->width(), parent_->height(), + hwnd(), NULL, NULL, NULL); + ShowWindow(scrollbar_, SW_SHOW); + return 1; + } + + LRESULT OnEraseBkgnd(HDC dc) { + return 1; + } + + void OnPaint(HDC ignore) { + PAINTSTRUCT ps; + HDC dc = BeginPaint(hwnd(), &ps); + EndPaint(hwnd(), &ps); + } + + void OnSize(int type, const CSize& sz) { + SetWindowPos(scrollbar_, + 0, 0, 0, sz.cx, sz.cy, + SWP_DEFERERASE | SWP_NOACTIVATE | SWP_NOCOPYBITS | + SWP_NOOWNERZORDER | SWP_NOSENDCHANGING | SWP_NOZORDER); + } + + void OnScroll(int code, HWND source, bool is_horizontal) { + int pos; + + if (code == SB_ENDSCROLL) { + return; + } + + // If we receive an event from the scrollbar, make the view + // component focused so we actually get mousewheel events. + if (source != NULL) { + Widget* widget = parent_->GetWidget(); + if (widget && widget->GetNativeView() != GetFocus()) { + parent_->RequestFocus(); + } + } + + SCROLLINFO si; + si.cbSize = sizeof(si); + si.fMask = SIF_POS | SIF_TRACKPOS; + GetScrollInfo(scrollbar_, SB_CTL, &si); + pos = si.nPos; + + ScrollBarController* sbc = parent_->GetController(); + + switch (code) { + case SB_BOTTOM: // case SB_RIGHT: + pos = parent_->GetMaxPosition(); + break; + case SB_TOP: // case SB_LEFT: + pos = parent_->GetMinPosition(); + break; + case SB_LINEDOWN: // case SB_LINERIGHT: + pos += sbc->GetScrollIncrement(parent_, false, true); + pos = std::min(parent_->GetMaxPosition(), pos); + break; + case SB_LINEUP: // case SB_LINELEFT: + pos -= sbc->GetScrollIncrement(parent_, false, false); + pos = std::max(parent_->GetMinPosition(), pos); + break; + case SB_PAGEDOWN: // case SB_PAGERIGHT: + pos += sbc->GetScrollIncrement(parent_, true, true); + pos = std::min(parent_->GetMaxPosition(), pos); + break; + case SB_PAGEUP: // case SB_PAGELEFT: + pos -= sbc->GetScrollIncrement(parent_, true, false); + pos = std::max(parent_->GetMinPosition(), pos); + break; + case SB_THUMBPOSITION: + case SB_THUMBTRACK: + pos = si.nTrackPos; + if (pos < parent_->GetMinPosition()) + pos = parent_->GetMinPosition(); + else if (pos > parent_->GetMaxPosition()) + pos = parent_->GetMaxPosition(); + break; + default: + break; + } + + sbc->ScrollToPosition(parent_, pos); + + si.nPos = pos; + si.fMask = SIF_POS; + SetScrollInfo(scrollbar_, SB_CTL, &si, TRUE); + + // Note: the system scrollbar modal loop doesn't give a chance + // to our message_loop so we need to call DidProcessMessage() + // manually. + // + // Sadly, we don't know what message has been processed. We may + // want to remove the message from DidProcessMessage() + MSG dummy; + dummy.hwnd = NULL; + dummy.message = 0; + MessageLoopForUI::current()->DidProcessMessage(dummy); + } + + // note: always ignore 2nd param as it is 16 bits + void OnHorizScroll(int n_sb_code, int ignore, HWND source) { + OnScroll(n_sb_code, source, true); + } + + // note: always ignore 2nd param as it is 16 bits + void OnVertScroll(int n_sb_code, int ignore, HWND source) { + OnScroll(n_sb_code, source, false); + } + + ScrollBar* parent_; + HWND scrollbar_; + + DISALLOW_COPY_AND_ASSIGN(ScrollBarContainer); +}; + +//////////////////////////////////////////////////////////////////////////////// +// NativeScrollBarWin, public: + +NativeScrollBarWin::NativeScrollBarWin(NativeScrollBar* scroll_bar) + : native_scroll_bar_(scroll_bar), + sb_container_(NULL) { + set_focus_view(scroll_bar); +} + +NativeScrollBarWin::~NativeScrollBarWin() { + if (sb_container_) { + // We always destroy the scrollbar container explicitly to cover all + // cases including when the container is no longer connected to a + // widget tree. + DestroyWindow(sb_container_->hwnd()); + delete sb_container_; + } +} + +//////////////////////////////////////////////////////////////////////////////// +// NativeScrollBarWin, View overrides: + +void NativeScrollBarWin::Layout() { + SetBounds(native_scroll_bar_->GetLocalBounds(true)); + NativeControlWin::Layout(); +} + +gfx::Size NativeScrollBarWin::GetPreferredSize() { + if (native_scroll_bar_->IsHorizontal()) + return gfx::Size(0, GetHorizontalScrollBarHeight()); + return gfx::Size(GetVerticalScrollBarWidth(), 0); +} + +bool NativeScrollBarWin::OnKeyPressed(const KeyEvent& event) { + if (!sb_container_) + return false; + int code = -1; + switch (event.GetCharacter()) { + case VK_UP: + if (!native_scroll_bar_->IsHorizontal()) + code = SB_LINEUP; + break; + case VK_PRIOR: + code = SB_PAGEUP; + break; + case VK_NEXT: + code = SB_PAGEDOWN; + break; + case VK_DOWN: + if (!native_scroll_bar_->IsHorizontal()) + code = SB_LINEDOWN; + break; + case VK_HOME: + code = SB_TOP; + break; + case VK_END: + code = SB_BOTTOM; + break; + case VK_LEFT: + if (native_scroll_bar_->IsHorizontal()) + code = SB_LINELEFT; + break; + case VK_RIGHT: + if (native_scroll_bar_->IsHorizontal()) + code = SB_LINERIGHT; + break; + } + if (code != -1) { + SendMessage(sb_container_->hwnd(), + native_scroll_bar_->IsHorizontal() ? WM_HSCROLL : WM_VSCROLL, + MAKELONG(static_cast<WORD>(code), 0), 0L); + return true; + } + return false; +} + +bool NativeScrollBarWin::OnMouseWheel(const MouseWheelEvent& e) { + if (!sb_container_) + return false; + sb_container_->ScrollWithOffset(e.GetOffset()); + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +// NativeScrollBarWin, NativeControlWin overrides: + +void NativeScrollBarWin::CreateNativeControl() { + sb_container_ = new ScrollBarContainer(native_scroll_bar_); + NativeControlCreated(sb_container_->hwnd()); +} + +//////////////////////////////////////////////////////////////////////////////// +// NativeScrollBarWin, NativeScrollBarWrapper overrides: + +int NativeScrollBarWin::GetPosition() const { + SCROLLINFO si; + si.cbSize = sizeof(si); + si.fMask = SIF_POS; + GetScrollInfo(sb_container_->GetScrollBarHWND(), SB_CTL, &si); + return si.nPos; +} + +View* NativeScrollBarWin::GetView() { + return this; +} + +void NativeScrollBarWin::Update(int viewport_size, + int content_size, + int current_pos) { + if (!sb_container_) + return; + + if (content_size < 0) + content_size = 0; + + if (current_pos < 0) + current_pos = 0; + + if (current_pos > content_size) + current_pos = content_size; + + SCROLLINFO si; + si.cbSize = sizeof(si); + si.fMask = SIF_DISABLENOSCROLL | SIF_POS | SIF_RANGE | SIF_PAGE; + si.nMin = 0; + si.nMax = content_size; + si.nPos = current_pos; + si.nPage = viewport_size; + SetScrollInfo(sb_container_->GetScrollBarHWND(), SB_CTL, &si, TRUE); +} + +//////////////////////////////////////////////////////////////////////////////// +// NativewScrollBarWrapper, public: + +// static +NativeScrollBarWrapper* NativeScrollBarWrapper::CreateWrapper( + NativeScrollBar* scroll_bar) { + return new NativeScrollBarWin(scroll_bar); +} + +// static +int NativeScrollBarWrapper::GetHorizontalScrollBarHeight() { + return GetSystemMetrics(SM_CYHSCROLL); +} + +// static +int NativeScrollBarWrapper::GetVerticalScrollBarWidth() { + return GetSystemMetrics(SM_CXVSCROLL); +} + +} // namespace views + diff --git a/views/controls/scrollbar/native_scroll_bar_win.h b/views/controls/scrollbar/native_scroll_bar_win.h new file mode 100644 index 0000000..566f036 --- /dev/null +++ b/views/controls/scrollbar/native_scroll_bar_win.h @@ -0,0 +1,62 @@ +// 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. + +#ifndef VIEWS_CONTROLS_SCROLLBAR_NATIVE_SCROLL_BAR_WIN_H_ +#define VIEWS_CONTROLS_SCROLLBAR_NATIVE_SCROLL_BAR_WIN_H_ + +#include "views/controls/native_control_win.h" +#include "views/controls/scrollbar/native_scroll_bar_wrapper.h" + +namespace views { + +class ScrollBarContainer; + +///////////////////////////////////////////////////////////////////////////// +// +// NativeScrollBarWin +// +// A View subclass that wraps a Native Windows scrollbar control. +// +// A scrollbar is either horizontal or vertical. +// +///////////////////////////////////////////////////////////////////////////// +class NativeScrollBarWin : public NativeControlWin, + public NativeScrollBarWrapper { + public: + // Create new scrollbar, either horizontal or vertical. + explicit NativeScrollBarWin(NativeScrollBar* native_scroll_bar); + virtual ~NativeScrollBarWin(); + + private: + // Overridden from View for layout purpose. + virtual void Layout(); + virtual gfx::Size GetPreferredSize(); + + // Overridden from View for keyboard UI purpose. + virtual bool OnKeyPressed(const KeyEvent& event); + virtual bool OnMouseWheel(const MouseWheelEvent& e); + + // Overridden from NativeControlWin. + virtual void CreateNativeControl(); + + // Overridden from ScrollBarWrapper. + virtual int GetPosition() const; + virtual View* GetView(); + virtual void Update(int viewport_size, int content_size, int current_pos); + + // The NativeScrollBar we are bound to. + NativeScrollBar* native_scroll_bar_; + + // sb_container_ is a custom hwnd that we use to wrap the real + // windows scrollbar. We need to do this to get the scroll events + // without having to do anything special in the high level hwnd. + ScrollBarContainer* sb_container_; + + DISALLOW_COPY_AND_ASSIGN(NativeScrollBarWin); +}; + +} // namespace views + +#endif // #ifndef VIEWS_CONTROLS_SCROLLBAR_NATIVE_SCROLL_BAR_WIN_H_ + diff --git a/views/controls/scrollbar/native_scroll_bar_wrapper.h b/views/controls/scrollbar/native_scroll_bar_wrapper.h new file mode 100644 index 0000000..6fb68ea --- /dev/null +++ b/views/controls/scrollbar/native_scroll_bar_wrapper.h @@ -0,0 +1,42 @@ +// 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. + +#ifndef VIEWS_CONTROLS_NATIVE_SCROLL_BAR_WRAPPER_H_ +#define VIEWS_CONTROLS_NATIVE_SCROLL_BAR_WRAPPER_H_ + +namespace views { + +class NativeScrollBar; +class View; + +// A specialization of NativeControlWrapper that hosts a platform-native +// scroll bar. +class NativeScrollBarWrapper { + public: + virtual ~NativeScrollBarWrapper() {} + + // Updates the scroll bar appearance given a viewport size, content size and + // current position. + virtual void Update(int viewport_size, + int content_size, + int current_pos) = 0; + + // Retrieves the views::View that hosts the native control. + virtual View* GetView() = 0; + + // Returns the position of the scrollbar. + virtual int GetPosition() const = 0; + + // Creates an appropriate NativeScrollBarWrapper for the platform. + static NativeScrollBarWrapper* CreateWrapper(NativeScrollBar* button); + + // Returns the system sizes of vertical/horizontal scroll bars. + static int GetVerticalScrollBarWidth(); + static int GetHorizontalScrollBarHeight(); +}; + +} // namespace views + +#endif // VIEWS_CONTROLS_NATIVE_SCROLL_BAR_WRAPPER_H_ + diff --git a/views/controls/scrollbar/scroll_bar.h b/views/controls/scrollbar/scroll_bar.h index 36a9d2e..9354fcb 100644 --- a/views/controls/scrollbar/scroll_bar.h +++ b/views/controls/scrollbar/scroll_bar.h @@ -5,8 +5,8 @@ #ifndef VIEWS_CONTROLS_SCROLLBAR_SCROLLBAR_H_ #define VIEWS_CONTROLS_SCROLLBAR_SCROLLBAR_H_ -#include "views/view.h" #include "views/event.h" +#include "views/view.h" namespace views { @@ -100,3 +100,4 @@ class ScrollBar : public View { } // namespace views #endif // #ifndef VIEWS_CONTROLS_SCROLLBAR_SCROLLBAR_H_ + diff --git a/views/views.gyp b/views/views.gyp index e9456e6..e1277cb 100644 --- a/views/views.gyp +++ b/views/views.gyp @@ -159,6 +159,9 @@ 'controls/scroll_view.h', 'controls/scrollbar/bitmap_scroll_bar.cc', 'controls/scrollbar/bitmap_scroll_bar.h', + 'controls/scrollbar/native_scroll_bar_wrapper.h', + 'controls/scrollbar/native_scroll_bar_win.cc', + 'controls/scrollbar/native_scroll_bar_win.h', 'controls/scrollbar/native_scroll_bar.cc', 'controls/scrollbar/native_scroll_bar.h', 'controls/scrollbar/scroll_bar.cc', |