summaryrefslogtreecommitdiffstats
path: root/chrome/views/native_button.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/views/native_button.cc')
-rw-r--r--chrome/views/native_button.cc212
1 files changed, 212 insertions, 0 deletions
diff --git a/chrome/views/native_button.cc b/chrome/views/native_button.cc
new file mode 100644
index 0000000..97b66e1
--- /dev/null
+++ b/chrome/views/native_button.cc
@@ -0,0 +1,212 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "chrome/views/native_button.h"
+
+#include "chrome/common/l10n_util.h"
+#include "chrome/common/resource_bundle.h"
+#include "chrome/views/background.h"
+
+namespace ChromeViews {
+
+NativeButton::NativeButton(const std::wstring& label) {
+ Init(label, false);
+}
+
+NativeButton::NativeButton(const std::wstring& label, bool is_default) {
+ Init(label, is_default);
+}
+
+NativeButton::~NativeButton() {
+}
+
+void NativeButton::SetListener(Listener *l) {
+ listener_ = l;
+}
+
+void NativeButton::SetPadding(CSize size) {
+ padding_ = size;
+}
+
+void NativeButton::GetPreferredSize(CSize *out) {
+ HWND hwnd = GetNativeControlHWND();
+ if (hwnd) {
+ SIZE sz = {0, 0};
+ ::SendMessage(hwnd,
+ BCM_GETIDEALSIZE,
+ 0,
+ reinterpret_cast<LPARAM>(&sz));
+ sz.cx += 2 * padding_.cx;
+ sz.cy += 2 * padding_.cy;
+
+ if (min_dlu_size_.width())
+ sz.cx = std::max(static_cast<int>(sz.cx),
+ font_.horizontal_dlus_to_pixels(min_dlu_size_.width()));
+ if (min_dlu_size_.height())
+ sz.cy = std::max(static_cast<int>(sz.cy),
+ font_.vertical_dlus_to_pixels(min_dlu_size_.height()));
+
+ *out = sz;
+ }
+}
+
+void NativeButton::SetLabel(const std::wstring& l) {
+ // Even though we create a flipped HWND for a native button when the locale
+ // is right-to-left, Windows does not render text for the button using a
+ // right-to-left context (perhaps because the parent HWND is not flipped).
+ // The result is that RTL strings containing punctuation marks are not
+ // displayed properly. For example, the string "...ABC" (where A, B and C are
+ // Hebrew characters) is displayed as "ABC..." which is incorrect.
+ //
+ // In order to overcome this problem, we mark the localized Hebrew strings as
+ // RTL strings explicitly (using the appropriate Unicode formatting) so that
+ // Windows displays the text correctly regardless of the HWND hierarchy.
+ std::wstring localized_label;
+ if (l10n_util::AdjustStringForLocaleDirection(l, &localized_label))
+ label_.assign(localized_label);
+ else
+ label_.assign(l);
+
+ SetAccessibleName(l);
+ UpdateNativeButton();
+}
+
+const std::wstring NativeButton::GetLabel() const {
+ return label_;
+}
+
+HWND NativeButton::CreateNativeControl(HWND parent_container) {
+ DWORD flags = WS_CHILD | BS_PUSHBUTTON;
+ if (is_default_)
+ flags |= BS_DEFPUSHBUTTON;
+ HWND r = ::CreateWindowEx(GetAdditionalExStyle(), L"BUTTON", L"", flags, 0, 0,
+ GetWidth(), GetHeight(), parent_container, NULL,
+ NULL, NULL);
+ SendMessage(r, WM_SETFONT, reinterpret_cast<WPARAM>(font_.hfont()), FALSE);
+ ConfigureNativeButton(r);
+ return r;
+}
+
+LRESULT NativeButton::OnNotify(int w_param, LPNMHDR l_param) {
+ return 0;
+}
+
+LRESULT NativeButton::OnCommand(UINT code, int id, HWND source) {
+ if (code == BN_CLICKED)
+ Clicked();
+ return 0;
+}
+
+void NativeButton::UpdateNativeButton() {
+ HWND hwnd = GetNativeControlHWND();
+ if (hwnd)
+ ConfigureNativeButton(hwnd);
+}
+
+void NativeButton::ConfigureNativeButton(HWND hwnd) {
+ ::SetWindowText(hwnd, label_.c_str());
+}
+
+bool NativeButton::AcceleratorPressed(const Accelerator& accelerator) {
+ if (enabled_) {
+ Clicked();
+ return true;
+ }
+ return false;
+}
+
+bool NativeButton::GetAccessibleRole(VARIANT* role) {
+ DCHECK(role);
+
+ role->vt = VT_I4;
+ role->lVal = ROLE_SYSTEM_PUSHBUTTON;
+ return true;
+}
+
+bool NativeButton::GetAccessibleName(std::wstring* name) {
+ if (!accessible_name_.empty()) {
+ *name = accessible_name_;
+ return true;
+ }
+ return false;
+}
+
+void NativeButton::SetAccessibleName(const std::wstring& name) {
+ accessible_name_.assign(name);
+}
+
+void NativeButton::Init(const std::wstring& label, bool is_default) {
+ // Marking the string as an RTL string if the locale is RTL. Refer to
+ // the comments in NativeButton::SetLabel for more details.
+ std::wstring localized_label;
+ if (l10n_util::AdjustStringForLocaleDirection(label, &localized_label))
+ label_.assign(localized_label);
+ else
+ label_.assign(label);
+
+ l10n_util::AdjustStringForLocaleDirection(label, &label_);
+ listener_ = NULL;
+ SetAccessibleName(label);
+ // The padding of 8 is a bit arbitrary, there appears to be no way to
+ // get a recommended padding, and this value varies greatly among windows
+ // dialogs.
+ //
+ // The min size in DLUs comes from
+ // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwue/html/ch14e.asp
+ padding_ = CSize(8, 0);
+ is_default_ = is_default;
+ min_dlu_size_.SetSize(50, 14);
+ SetFocusable(true);
+ if (is_default)
+ AddAccelerator(Accelerator(VK_RETURN, false, false, false));
+}
+
+void NativeButton::Clicked() {
+ DCHECK(enabled_);
+ // Give the focus to the button.
+ if (IsFocusable())
+ RequestFocus();
+
+ if (listener_)
+ listener_->ButtonPressed(this);
+}
+
+bool NativeButton::NotifyOnKeyDown() const {
+ return true;
+}
+
+bool NativeButton::OnKeyDown(int virtual_key_code) {
+ if (virtual_key_code == VK_RETURN) {
+ Clicked();
+ return true;
+ }
+ return false;
+}
+
+}