diff options
Diffstat (limited to 'chrome/views/native_button.cc')
-rw-r--r-- | chrome/views/native_button.cc | 212 |
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; +} + +} |