diff options
author | thakis@chromium.org <thakis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-30 00:02:07 +0000 |
---|---|---|
committer | thakis@chromium.org <thakis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-30 00:02:07 +0000 |
commit | 7fcce97e9d4605fa18a84fc46d3647e0b7a9240c (patch) | |
tree | 4d8a5a46c2c1871d009148b9f54d5b7b5d55dfb6 /views | |
parent | 09bc6209ac14a55e360c94c3e4ec6bbba03f4127 (diff) | |
download | chromium_src-7fcce97e9d4605fa18a84fc46d3647e0b7a9240c.zip chromium_src-7fcce97e9d4605fa18a84fc46d3647e0b7a9240c.tar.gz chromium_src-7fcce97e9d4605fa18a84fc46d3647e0b7a9240c.tar.bz2 |
Win: Add listbox view.
See http://codereview.chromium.org/2799042 for how I intend to use this.
BUG=45546
TEST=None
BUG=45546
TEST=None
Review URL: http://codereview.chromium.org/2815034
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@51196 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'views')
-rw-r--r-- | views/controls/listbox/listbox.cc | 58 | ||||
-rw-r--r-- | views/controls/listbox/listbox.h | 69 | ||||
-rw-r--r-- | views/controls/listbox/native_listbox_win.cc | 135 | ||||
-rw-r--r-- | views/controls/listbox/native_listbox_win.h | 57 | ||||
-rw-r--r-- | views/controls/listbox/native_listbox_wrapper.h | 39 | ||||
-rw-r--r-- | views/controls/tabbed_pane/native_tabbed_pane_win.cc | 17 | ||||
-rw-r--r-- | views/views.gyp | 10 |
7 files changed, 375 insertions, 10 deletions
diff --git a/views/controls/listbox/listbox.cc b/views/controls/listbox/listbox.cc new file mode 100644 index 0000000..dad2826 --- /dev/null +++ b/views/controls/listbox/listbox.cc @@ -0,0 +1,58 @@ +// Copyright (c) 2010 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/listbox/listbox.h" + +#include "views/controls/listbox/native_listbox_wrapper.h" +#include "views/controls/native/native_view_host.h" +#include "views/fill_layout.h" + +namespace views { + +// Listbox ------------------------------------------------------------------ + +Listbox::Listbox( + const std::vector<string16>& strings, Listbox::Listener* listener) + : strings_(strings), + listener_(listener), + native_wrapper_(NULL) { + SetLayoutManager(new FillLayout()); +} + +Listbox::~Listbox() { +} + +int Listbox::GetRowCount() const { + return static_cast<int>(strings_.size()); +} + +int Listbox::SelectedRow() const { + if (!native_wrapper_) + return -1; + return native_wrapper_->SelectedRow(); +} + +void Listbox::SelectRow(int model_row) { + if (!native_wrapper_) + return; + native_wrapper_->SelectRow(model_row); +} + +void Listbox::ViewHierarchyChanged(bool is_add, View* parent, View* child) { + if (is_add && !native_wrapper_ && GetWidget()) { + // The native wrapper's lifetime will be managed by the view hierarchy after + // we call AddChildView. + native_wrapper_ = CreateWrapper(); + AddChildView(native_wrapper_->GetView()); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// Listbox, protected: + +NativeListboxWrapper* Listbox::CreateWrapper() { + return NativeListboxWrapper::CreateNativeWrapper(this, strings_, listener_); +} + +} // namespace views diff --git a/views/controls/listbox/listbox.h b/views/controls/listbox/listbox.h new file mode 100644 index 0000000..81bd0da --- /dev/null +++ b/views/controls/listbox/listbox.h @@ -0,0 +1,69 @@ +// Copyright (c) 2010 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_LISTBOX_LISTBOX_H_ +#define VIEWS_CONTROLS_LISTBOX_LISTBOX_H_ + +#include "build/build_config.h" + +#include <string> +#include <vector> + +#include "base/string16.h" +#include "views/view.h" + +namespace views { + +class NativeListboxWrapper; + +// A Listbox is a view that displays multiple rows of fixed strings. +// Exactly one of these strings is shown as selected at all times. +class Listbox : public View { + public: + // An interface implemented by an object to let it know that a listbox + // selection has changed. + class Listener { + public: + // This is called if the user changes the current selection of the + // listbox. + virtual void ListboxSelectionChanged(Listbox* sender) = 0; + }; + + // Creates a new listbox, given the list of strings. |listener| can be NULL. + // Listbox does not take ownership of |listener|. + Listbox(const std::vector<string16>& strings, Listbox::Listener* listener); + virtual ~Listbox(); + + // Returns the number of rows in the table. + int GetRowCount() const; + + // Returns the 0-based index of the currently selected row, or -1 if nothing + // is selected. Note that as soon as a row has been selected once, there will + // always be a selected row. + int SelectedRow() const; + + // Selects the specified row. Note that this does NOT call the listener's + // |ListboxSelectionChanged()| method. + void SelectRow(int row); + + protected: + virtual NativeListboxWrapper* CreateWrapper(); + virtual void ViewHierarchyChanged(bool is_add, View* parent, View* child); + + private: + // Data stored in the listbox. + std::vector<string16> strings_; + + // Listens to selection changes. + Listbox::Listener* listener_; + + // The object that actually implements the table. + NativeListboxWrapper* native_wrapper_; + + DISALLOW_COPY_AND_ASSIGN(Listbox); +}; + +} // namespace views + +#endif // VIEWS_CONTROLS_LISTBOX_LISTBOX_H_ diff --git a/views/controls/listbox/native_listbox_win.cc b/views/controls/listbox/native_listbox_win.cc new file mode 100644 index 0000000..1c6d985 --- /dev/null +++ b/views/controls/listbox/native_listbox_win.cc @@ -0,0 +1,135 @@ +// Copyright (c) 2010 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/listbox/native_listbox_win.h" + +#include <commctrl.h> +#include <windowsx.h> + +#include "app/l10n_util.h" +#include "app/l10n_util_win.h" +#include "app/resource_bundle.h" +#include "base/logging.h" +#include "base/utf_string_conversions.h" +#include "base/win_util.h" +#include "gfx/font.h" +#include "views/controls/listbox/listbox.h" +#include "views/widget/widget.h" + +namespace views { + +//////////////////////////////////////////////////////////////////////////////// +// NativeListboxWin, public: + +NativeListboxWin::NativeListboxWin(Listbox* listbox, + const std::vector<string16>& strings, + Listbox::Listener* listener) + : listbox_(listbox), + strings_(strings), + listener_(listener) { + // Associates the actual HWND with the listbox so the listbox is the one + // considered as having the focus (not the wrapper) when the HWND is + // focused directly (with a click for example). + set_focus_view(listbox); +} + +NativeListboxWin::~NativeListboxWin() { +} + +//////////////////////////////////////////////////////////////////////////////// +// NativeListboxWin, NativeListboxWrapper implementation: + +int NativeListboxWin::GetRowCount() const { + if (!native_view()) + return 0; + return ListBox_GetCount(native_view()); +} + +int NativeListboxWin::SelectedRow() const { + if (!native_view()) + return -1; + return ListBox_GetCurSel(native_view()); +} + +void NativeListboxWin::SelectRow(int row) { + if (!native_view()) + return; + ListBox_SetCurSel(native_view(), row); +} + +View* NativeListboxWin::GetView() { + return this; +} + +//////////////////////////////////////////////////////////////////////////////// +// NativeListboxWin, View overrides: + +gfx::Size NativeListboxWin::GetPreferredSize() { + SIZE sz = {0}; + SendMessage(native_view(), BCM_GETIDEALSIZE, 0, + reinterpret_cast<LPARAM>(&sz)); + + return gfx::Size(sz.cx, sz.cy); +} + +//////////////////////////////////////////////////////////////////////////////// +// NativeListboxWin, NativeControlWin overrides: + +bool NativeListboxWin::ProcessMessage(UINT message, WPARAM w_param, + LPARAM l_param, LRESULT* result) { + if (message == WM_COMMAND) { + switch (HIWORD(w_param)) { + case LBN_SELCHANGE: + if (listener_) + listener_->ListboxSelectionChanged(listbox_); + return true; + default: + break; + } + } + + return NativeControlWin::ProcessMessage(message, w_param, l_param, result); +} + +//////////////////////////////////////////////////////////////////////////////// +// NativeListboxWin, protected: + +void NativeListboxWin::CreateNativeControl() { + int style = WS_CHILD | LBS_NOINTEGRALHEIGHT | LBS_NOTIFY; + // If there's only one column and the title string is empty, don't show a + // header. + HWND hwnd = ::CreateWindowEx(WS_EX_CLIENTEDGE | GetAdditionalRTLStyle(), + WC_LISTBOX, + L"", + style, + 0, 0, width(), height(), + listbox_->GetWidget()->GetNativeView(), + NULL, NULL, NULL); + HFONT font = ResourceBundle::GetSharedInstance(). + GetFont(ResourceBundle::BaseFont).hfont(); + SendMessage(hwnd, WM_SETFONT, reinterpret_cast<WPARAM>(font), FALSE); + l10n_util::AdjustUIFontForWindow(hwnd); + + for (size_t i = 0; i < strings_.size(); ++i) + ListBox_AddString(hwnd, UTF16ToWide(strings_[i]).c_str()); + + NativeControlCreated(hwnd); + + // Bug 964884: detach the IME attached to this window. + // We should attach IMEs only when we need to input CJK strings. + ::ImmAssociateContextEx(hwnd, NULL, 0); +} + +//////////////////////////////////////////////////////////////////////////////// +// NativeListboxWrapper, public: + +// static +NativeListboxWrapper* NativeListboxWrapper::CreateNativeWrapper( + Listbox* listbox, + const std::vector<string16>& strings, + Listbox::Listener* listener) { + return new NativeListboxWin(listbox, strings, listener); +} + +} // namespace views diff --git a/views/controls/listbox/native_listbox_win.h b/views/controls/listbox/native_listbox_win.h new file mode 100644 index 0000000..75844be --- /dev/null +++ b/views/controls/listbox/native_listbox_win.h @@ -0,0 +1,57 @@ +// Copyright (c) 2010 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_LISTBOX_NATIVE_LISTBOX_WIN_H_ +#define VIEWS_CONTROLS_LISTBOX_NATIVE_LISTBOX_WIN_H_ + +#include <windows.h> + +#include "base/string16.h" +#include "views/controls/listbox/native_listbox_wrapper.h" +#include "views/controls/native_control_win.h" + +namespace views { + +// A View that hosts a native Windows listbox. +class NativeListboxWin : public NativeControlWin, public NativeListboxWrapper { + public: + NativeListboxWin(Listbox* listbox, + const std::vector<string16>& strings, + Listbox::Listener* listener); + virtual ~NativeListboxWin(); + + // NativeListboxWrapper implementation: + virtual int GetRowCount() const; + virtual int SelectedRow() const; + virtual void SelectRow(int row); + virtual View* GetView(); + + // Overridden from View: + virtual gfx::Size GetPreferredSize(); + + // Overridden from NativeControlWin: + virtual bool ProcessMessage(UINT message, + WPARAM w_param, + LPARAM l_param, + LRESULT* result); + + protected: + virtual void CreateNativeControl(); + + private: + // The listbox we are bound to. + Listbox* listbox_; + + // The strings shown in the listbox. + std::vector<string16> strings_; + + // Listens to selection changes. + Listbox::Listener* listener_; + + DISALLOW_COPY_AND_ASSIGN(NativeListboxWin); +}; + +} // namespace views + +#endif // VIEWS_CONTROLS_LISTBOX_NATIVE_LISTBOX_WIN_H_ diff --git a/views/controls/listbox/native_listbox_wrapper.h b/views/controls/listbox/native_listbox_wrapper.h new file mode 100644 index 0000000..189ffc8 --- /dev/null +++ b/views/controls/listbox/native_listbox_wrapper.h @@ -0,0 +1,39 @@ +// Copyright (c) 2010 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_LISTBOX_NATIVE_LISTBOX_WRAPPER_H_ +#define VIEWS_CONTROLS_LISTBOX_NATIVE_LISTBOX_WRAPPER_H_ + +#include "gfx/native_widget_types.h" +#include "gfx/rect.h" +#include "views/controls/listbox/listbox.h" + +namespace views { + +// An interface implemented by an object that provides a platform-native +// listbox. +class NativeListboxWrapper { + public: + // Returns the number of rows in the table. + virtual int GetRowCount() const = 0; + + // Returns the 0-based index of the currently selected row. + virtual int SelectedRow() const = 0; + + // Selects the specified row, making sure it's visible. + virtual void SelectRow(int row) = 0; + + // Retrieves the views::View that hosts the native control. + virtual View* GetView() = 0; + + // Creates an appropriate NativeListboxWrapper for the platform. + static NativeListboxWrapper* CreateNativeWrapper( + Listbox* listbox, + const std::vector<string16>& strings, + Listbox::Listener* listener); +}; + +} // namespace views + +#endif // VIEWS_CONTROLS_LISTBOX_NATIVE_LISTBOX_WRAPPER_H_ diff --git a/views/controls/tabbed_pane/native_tabbed_pane_win.cc b/views/controls/tabbed_pane/native_tabbed_pane_win.cc index 832d4a2..8687325 100644 --- a/views/controls/tabbed_pane/native_tabbed_pane_win.cc +++ b/views/controls/tabbed_pane/native_tabbed_pane_win.cc @@ -195,13 +195,12 @@ void NativeTabbedPaneWin::CreateNativeControl() { // inherit the WS_EX_LAYOUTRTL property and this will result in the contents // being flipped, which is not what we want (because we handle mirroring in // views without the use of Windows' support for mirroring). Therefore, - // we initially create our HWND without the aforementioned property and we - // explicitly set this property our child is created. This way, on RTL - // locales, our tabs will be nicely rendered from right to left (by virtue of - // Windows doing the right thing with the TabbedPane HWND) and each tab - // contents will use an RTL layout correctly (by virtue of the mirroring - // infrastructure in views doing the right thing with each View we put - // in the tab). + // we initially create our HWND without WS_EX_LAYOUTRTL and we explicitly set + // this property our child is created. This way, on RTL locales, our tabs + // will be nicely rendered from right to left (by virtue of Windows doing the + // right thing with the TabbedPane HWND) and each tab contents will use an + // RTL layout correctly (by virtue of the mirroring infrastructure in views + // doing the right thing with each View we put in the tab). DWORD style = WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | WS_CLIPCHILDREN; HWND tab_control = ::CreateWindowEx(0, WC_TABCONTROL, @@ -220,8 +219,8 @@ void NativeTabbedPaneWin::CreateNativeControl() { content_window_->Init(tab_control, gfx::Rect()); // Explicitly setting the WS_EX_LAYOUTRTL property for the HWND (see above - // for a thorough explanation regarding why we waited until |content_window_| - // if created before we set this property for the tabbed pane's HWND). + // for why we waited until |content_window_| is created before we set this + // property for the tabbed pane's HWND). if (base::i18n::IsRTL()) l10n_util::HWNDSetRTLLayout(tab_control); diff --git a/views/views.gyp b/views/views.gyp index 0b87955..0193383 100644 --- a/views/views.gyp +++ b/views/views.gyp @@ -97,6 +97,11 @@ 'controls/label.h', 'controls/link.cc', 'controls/link.h', + 'controls/listbox/native_listbox_wrapper.h', + 'controls/listbox/native_listbox_win.cc', + 'controls/listbox/native_listbox_win.h', + 'controls/listbox/listbox.cc', + 'controls/listbox/listbox.h', 'controls/menu/controller.h', 'controls/menu/menu.cc', 'controls/menu/menu.h', @@ -329,8 +334,11 @@ 'controls/scrollbar/bitmap_scroll_bar.cc', 'controls/combo_box.cc', 'controls/hwnd_view.cc', - 'controls/table/group_table_view.cc', + 'controls/listbox/native_listbox_wrapper.h', + 'controls/listbox/listbox.cc', + 'controls/listbox/listbox.h', 'controls/native_control.cc', + 'controls/table/group_table_view.cc', 'controls/table/table_model.cc', 'controls/table/table_view.cc', 'controls/table/group_table_view.cc', |