summaryrefslogtreecommitdiffstats
path: root/views
diff options
context:
space:
mode:
authorthakis@chromium.org <thakis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-30 00:02:07 +0000
committerthakis@chromium.org <thakis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-30 00:02:07 +0000
commit7fcce97e9d4605fa18a84fc46d3647e0b7a9240c (patch)
tree4d8a5a46c2c1871d009148b9f54d5b7b5d55dfb6 /views
parent09bc6209ac14a55e360c94c3e4ec6bbba03f4127 (diff)
downloadchromium_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.cc58
-rw-r--r--views/controls/listbox/listbox.h69
-rw-r--r--views/controls/listbox/native_listbox_win.cc135
-rw-r--r--views/controls/listbox/native_listbox_win.h57
-rw-r--r--views/controls/listbox/native_listbox_wrapper.h39
-rw-r--r--views/controls/tabbed_pane/native_tabbed_pane_win.cc17
-rw-r--r--views/views.gyp10
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',