diff options
author | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-19 21:18:44 +0000 |
---|---|---|
committer | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-19 21:18:44 +0000 |
commit | ff9b986cb33d05c87eb188215770f6a833a08b2b (patch) | |
tree | b116b0893bc7ad5017ee7dce9f820c86e2ad8cc0 /chrome/views | |
parent | b5c1e4d070251ec6663d8ab92a3bb83f6f3d75c1 (diff) | |
download | chromium_src-ff9b986cb33d05c87eb188215770f6a833a08b2b.zip chromium_src-ff9b986cb33d05c87eb188215770f6a833a08b2b.tar.gz chromium_src-ff9b986cb33d05c87eb188215770f6a833a08b2b.tar.bz2 |
Create cross-platform NativeButton2 class that wraps a NativeButtonWin.Once I get this to work I'll rename it NativeButton and remove the old one.
Review URL: http://codereview.chromium.org/48117
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@12160 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/views')
-rw-r--r-- | chrome/views/controls/button/checkbox.cc | 2 | ||||
-rw-r--r-- | chrome/views/controls/button/checkbox2.cc | 84 | ||||
-rw-r--r-- | chrome/views/controls/button/checkbox2.h | 67 | ||||
-rw-r--r-- | chrome/views/controls/button/native_button2.cc | 148 | ||||
-rw-r--r-- | chrome/views/controls/button/native_button2.h | 93 | ||||
-rw-r--r-- | chrome/views/controls/button/native_button_win.cc | 152 | ||||
-rw-r--r-- | chrome/views/controls/button/native_button_win.h | 44 | ||||
-rw-r--r-- | chrome/views/controls/button/native_button_wrapper.h | 64 | ||||
-rw-r--r-- | chrome/views/controls/button/radio_button.cc | 2 | ||||
-rw-r--r-- | chrome/views/controls/hwnd_view.cc | 17 | ||||
-rw-r--r-- | chrome/views/controls/hwnd_view.h | 5 | ||||
-rw-r--r-- | chrome/views/controls/native_control_win.cc | 29 | ||||
-rw-r--r-- | chrome/views/controls/native_control_win.h | 3 | ||||
-rw-r--r-- | chrome/views/controls/text_field.cc | 2 | ||||
-rw-r--r-- | chrome/views/views.vcproj | 16 |
15 files changed, 515 insertions, 213 deletions
diff --git a/chrome/views/controls/button/checkbox.cc b/chrome/views/controls/button/checkbox.cc index c5463de..b768037 100644 --- a/chrome/views/controls/button/checkbox.cc +++ b/chrome/views/controls/button/checkbox.cc @@ -66,7 +66,7 @@ void CheckBox::Layout() { int first_line_height = label_->GetFont().height(); hwnd_view_->SetBounds(0, ((first_line_height - kCheckBoxHeight) / 2) + 1, kCheckBoxWidth, kCheckBoxHeight); - hwnd_view_->UpdateHWNDBounds(); + hwnd_view_->Layout(); } } diff --git a/chrome/views/controls/button/checkbox2.cc b/chrome/views/controls/button/checkbox2.cc new file mode 100644 index 0000000..d3b4786 --- /dev/null +++ b/chrome/views/controls/button/checkbox2.cc @@ -0,0 +1,84 @@ +// 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 "chrome/views/controls/button/checkbox2.h" + +#include "chrome/views/controls/label.h" + +namespace views { + +// static +const char Checkbox2::kViewClassName[] = "chrome/views/Checkbox"; + +//////////////////////////////////////////////////////////////////////////////// +// Checkbox2, public: + +Checkbox2::Checkbox2() : NativeButton2(NULL), checked_(false) { + CreateLabel(std::wstring()); +} + +Checkbox2::Checkbox2(ButtonListener* listener) + : NativeButton2(listener), + checked_(false) { + CreateLabel(std::wstring()); +} + +Checkbox2::Checkbox2(ButtonListener* listener, const std::wstring& label) + : NativeButton2(listener, label), + checked_(false) { + CreateLabel(label); +} + +Checkbox2::~Checkbox2() { +} + +void Checkbox2::SetMultiline(bool multiline) { + label_->SetMultiLine(multiline); +} + +void Checkbox2::SetChecked(bool checked) { + if (checked_ == checked) + return; + checked_ = checked; + native_wrapper_->UpdateChecked(); +} + +//////////////////////////////////////////////////////////////////////////////// +// Checkbox2, View overrides: + +gfx::Size Checkbox2::GetPreferredSize() { + return gfx::Size(120, 30); +} + +void Checkbox2::Layout() { +} + +std::string Checkbox2::GetClassName() const { + return kViewClassName; +} + +//////////////////////////////////////////////////////////////////////////////// +// Checkbox2, NativeButton2 overrides: + +void Checkbox2::CreateWrapper() { + native_wrapper_ = NativeButtonWrapper::CreateCheckboxWrapper(this); + native_wrapper_->UpdateLabel(); + native_wrapper_->UpdateChecked(); +} + +void Checkbox2::InitBorder() { + // No border, so we do nothing. +} + +//////////////////////////////////////////////////////////////////////////////// +// Checkbox2, private: + +void Checkbox2::CreateLabel(const std::wstring& label_text) { + set_minimum_size(gfx::Size(0, 0)); + label_ = new Label(label_text); + label_->SetHorizontalAlignment(Label::ALIGN_LEFT); + AddChildView(label_); +} + +} // namespace views diff --git a/chrome/views/controls/button/checkbox2.h b/chrome/views/controls/button/checkbox2.h new file mode 100644 index 0000000..b3ef7cf --- /dev/null +++ b/chrome/views/controls/button/checkbox2.h @@ -0,0 +1,67 @@ +// 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 CHROME_VIEWS_CONTROLS_BUTTON_CHECKBOX2_H_ +#define CHROME_VIEWS_CONTROLS_BUTTON_CHECKBOX2_H_ + +#include "chrome/views/controls/button/native_button2.h" + +namespace views { + +class Label; + +// A NativeButton subclass representing a checkbox. +class Checkbox2 : public NativeButton2 { + public: + // The button's class name. + static const char kViewClassName[]; + + Checkbox2(); + explicit Checkbox2(ButtonListener* listener); + Checkbox2(ButtonListener* listener, const std::wstring& label); + virtual ~Checkbox2(); + + // Sets whether or not the checkbox label should wrap multiple lines of text. + // If true, long lines are wrapped, and this is reflected in the preferred + // size returned by GetPreferredSize. If false, text that will not fit within + // the available bounds for the label will be cropped. + void SetMultiline(bool multiline); + + // Sets/Gets whether or not the checkbox is checked. + void SetChecked(bool checked); + bool checked() const { return checked_; } + + // Overridden from View: + virtual gfx::Size GetPreferredSize(); + virtual void Layout(); + + protected: + virtual std::string GetClassName() const; + + // Overridden from NativeButton2: + virtual void CreateWrapper(); + virtual void InitBorder(); + + private: + // Called from the constructor to create and configure the checkbox label. + void CreateLabel(const std::wstring& label_text); + + // The checkbox's label. We don't use the OS version because of transparency + // and sizing issues. + Label* label_; + + // True if the checkbox is checked. + bool checked_; + + DISALLOW_COPY_AND_ASSIGN(Checkbox2); +}; + +// TODO(beng): move to own file and un-stub: +class RadioButton2 : public Checkbox2 { + +}; + +} // namespace views + +#endif // #ifndef CHROME_VIEWS_CONTROLS_BUTTON_CHECKBOX2_H_ diff --git a/chrome/views/controls/button/native_button2.cc b/chrome/views/controls/button/native_button2.cc new file mode 100644 index 0000000..5478cdd --- /dev/null +++ b/chrome/views/controls/button/native_button2.cc @@ -0,0 +1,148 @@ +// 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 "chrome/views/controls/button/native_button2.h" + +#include "base/logging.h" +#include "chrome/common/l10n_util.h" + +namespace views { + +static int kButtonBorderHWidth = 8; + +// static +const char NativeButton2::kViewClassName[] = "chrome/views/NativeButton"; + +//////////////////////////////////////////////////////////////////////////////// +// NativeButton, public: + +NativeButton2::NativeButton2(ButtonListener* listener) + : Button(listener), + native_wrapper_(NULL), + is_default_(false), + ignore_minimum_size_(false), + minimum_size_(50, 14) { + // The min size in DLUs comes from + // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwue/html/ch14e.asp + InitBorder(); +} + +NativeButton2::NativeButton2(ButtonListener* listener, + const std::wstring& label) + : Button(listener), + native_wrapper_(NULL), + label_(label), + is_default_(false), + ignore_minimum_size_(false), + minimum_size_(50, 14) { + // The min size in DLUs comes from + // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwue/html/ch14e.asp + InitBorder(); +} + +NativeButton2::~NativeButton2() { +} + +void NativeButton2::SetLabel(const std::wstring& label) { + label_ = label; + + // 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(label_, &localized_label)) + label_ = localized_label; + + if (native_wrapper_) + native_wrapper_->UpdateLabel(); +} + +void NativeButton2::SetIsDefault(bool is_default) { + if (is_default == is_default_) + return; + is_default_ = is_default; + if (native_wrapper_) + native_wrapper_->UpdateDefault(); +} + +void NativeButton2::ButtonPressed() { + // TODO(beng): obtain mouse event flags for native buttons someday. + NotifyClick(mouse_event_flags()); +} + +//////////////////////////////////////////////////////////////////////////////// +// NativeButton, View overrides: + +gfx::Size NativeButton2::GetPreferredSize() { + gfx::Size sz = native_wrapper_->GetView()->GetPreferredSize(); + + // Add in the border size. (Do this before clamping the minimum size in case + // that clamping causes an increase in size that would include the borders. + gfx::Insets border = GetInsets(); + sz.set_width(sz.width() + border.left() + border.right()); + sz.set_height(sz.height() + border.top() + border.bottom()); + + // Clamp the size returned to at least the minimum size. + if (!ignore_minimum_size_) { + if (minimum_size_.width()) { + int min_width = font_.horizontal_dlus_to_pixels(minimum_size_.width()); + sz.set_width(std::max(static_cast<int>(sz.width()), min_width)); + } + if (minimum_size_.height()) { + int min_height = font_.vertical_dlus_to_pixels(minimum_size_.height()); + sz.set_height(std::max(static_cast<int>(sz.height()), min_height)); + } + } + + return sz; +} + +void NativeButton2::Layout() { + if (native_wrapper_) { + native_wrapper_->GetView()->SetBounds(0, 0, width(), height()); + native_wrapper_->GetView()->Layout(); + } +} + +void NativeButton2::ViewHierarchyChanged(bool is_add, View* parent, + View* child) { + if (is_add && !native_wrapper_ && GetWidget()) { + CreateWrapper(); + AddChildView(native_wrapper_->GetView()); + } +} + +std::string NativeButton2::GetClassName() const { + return kViewClassName; +} + +bool NativeButton2::AcceleratorPressed(const Accelerator& accelerator) { + if (IsEnabled()) { + NotifyClick(mouse_event_flags()); + return true; + } + return false; +} + +//////////////////////////////////////////////////////////////////////////////// +// NativeButton, protected: + +void NativeButton2::CreateWrapper() { + native_wrapper_ = NativeButtonWrapper::CreateNativeButtonWrapper(this); + native_wrapper_->UpdateLabel(); +} + +void NativeButton2::InitBorder() { + set_border(Border::CreateEmptyBorder(0, kButtonBorderHWidth, 0, + kButtonBorderHWidth)); +} + +} // namespace views diff --git a/chrome/views/controls/button/native_button2.h b/chrome/views/controls/button/native_button2.h new file mode 100644 index 0000000..691a76c --- /dev/null +++ b/chrome/views/controls/button/native_button2.h @@ -0,0 +1,93 @@ +// 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 CHROME_VIEWS_CONTROLS_BUTTON_NATIVE_BUTTON2_H_ +#define CHROME_VIEWS_CONTROLS_BUTTON_NATIVE_BUTTON2_H_ + +#include "chrome/common/gfx/chrome_font.h" +#include "chrome/views/controls/button/button.h" +#include "chrome/views/controls/button/native_button_wrapper.h" + +class ChromeFont; + +namespace views { + +class NativeButton2 : public Button { + public: + // The button's class name. + static const char kViewClassName[]; + + explicit NativeButton2(ButtonListener* listener); + NativeButton2(ButtonListener* listener, const std::wstring& label); + virtual ~NativeButton2(); + + // Sets/Gets the text to be used as the button's label. + void SetLabel(const std::wstring& label); + std::wstring label() const { return label_; } + + // Sets the font to be used when displaying the button's label. + void set_font(const ChromeFont& font) { font_ = font; } + const ChromeFont& font() const { return font_; } + + // Sets/Gets whether or not the button appears as the default button in its + // current context. + void SetIsDefault(bool default_button); + bool is_default() const { return is_default_; } + + void set_minimum_size(const gfx::Size& minimum_size) { + minimum_size_ = minimum_size; + } + void set_ignore_minimum_size(bool ignore_minimum_size) { + ignore_minimum_size_ = ignore_minimum_size; + } + + // Called by the wrapper when the actual wrapped native button was pressed. + void ButtonPressed(); + + // Overridden from View: + virtual gfx::Size GetPreferredSize(); + virtual void Layout(); + + protected: + virtual void ViewHierarchyChanged(bool is_add, View* parent, View* child); + virtual std::string GetClassName() const; + virtual bool AcceleratorPressed(const Accelerator& accelerator); + + // Create the button wrapper. Can be overridden by subclass to create a + // wrapper of a particular type. See NativeButtonWrapper interface for types. + virtual void CreateWrapper(); + + // Sets a border to the button. Override to set a different border or to not + // set one (the default is 0,8,0,8 for push buttons). + virtual void InitBorder(); + + // The object that actually implements the native button. + NativeButtonWrapper* native_wrapper_; + + private: + // The button label. + std::wstring label_; + + // True if the button is the default button in its context. + bool is_default_; + + // The font used to render the button label. + ChromeFont font_; + + // True if the button should ignore the minimum size for the platform. Default + // is false. Set to true to create narrower buttons. + bool ignore_minimum_size_; + + // The minimum size of the button from the specified size in native dialog + // units. The definition of this unit may vary from platform to platform. If + // the width/height is non-zero, the preferred size of the button will not be + // less than this value when the dialog units are converted to pixels. + gfx::Size minimum_size_; + + DISALLOW_COPY_AND_ASSIGN(NativeButton2); +}; + +} // namespace views + +#endif // #ifndef CHROME_VIEWS_CONTROLS_BUTTON_NATIVE_BUTTON2_H_ diff --git a/chrome/views/controls/button/native_button_win.cc b/chrome/views/controls/button/native_button_win.cc index 35472cd..43c9134 100644 --- a/chrome/views/controls/button/native_button_win.cc +++ b/chrome/views/controls/button/native_button_win.cc @@ -4,7 +4,9 @@ #include "chrome/views/controls/button/native_button_win.h" -#include "chrome/common/l10n_util.h" +#include "base/logging.h" +#include "chrome/views/controls/button/native_button2.h" +#include "chrome/views/controls/button/checkbox2.h" #include "chrome/views/widget/widget.h" namespace views { @@ -12,14 +14,9 @@ namespace views { //////////////////////////////////////////////////////////////////////////////// // NativeButtonWin, public: -NativeButtonWin::NativeButtonWin(NativeButtonWrapperListener* listener) +NativeButtonWin::NativeButtonWin(NativeButton2* native_button) : NativeControlWin(), - listener_(listener), - is_default_(false), - ignore_minimum_size_(false), - min_dlu_size_(50, 14) { - // The min size in DLUs comes from - // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwue/html/ch14e.asp + native_button_(native_button) { } NativeButtonWin::~NativeButtonWin() { @@ -28,61 +25,20 @@ NativeButtonWin::~NativeButtonWin() { //////////////////////////////////////////////////////////////////////////////// // NativeButtonWin, NativeButtonWrapper implementation: -void NativeButtonWin::SetLabel(const std::wstring& label) { - label_ = label; - - // 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(label_, &localized_label)) - label_ = localized_label; - - // SetLabel can be called before the view is attached to a view hierarchy, so - // we check the HWND before attempting to do anything with it. - if (IsWindow(GetHWND())) - SetWindowText(GetHWND(), label_.c_str()); +void NativeButtonWin::UpdateLabel() { + SetWindowText(GetHWND(), native_button_->label().c_str()); } -std::wstring NativeButtonWin::GetLabel() const { - return label_; -} - -void NativeButtonWin::SetFont(const ChromeFont& font) { - font_ = font; -} - -void NativeButtonWin::SetDefaultButton(bool is_default) { - if (is_default == is_default_) - return; - is_default_ = is_default; - - // SetDefaultButton can be called before the view is attached to a view - // hierarchy, so we check the HWND before attempting to modify its style. - if (IsWindow(GetHWND())) { - SendMessage(GetHWND(), BM_SETSTYLE, - is_default_ ? BS_DEFPUSHBUTTON : BS_PUSHBUTTON, true); - } -} - -bool NativeButtonWin::IsDefaultButton() const { - return is_default_; -} - -void NativeButtonWin::SetMinimumSizeInPlatformUnits( - const gfx::Size& minimum_size) { - min_dlu_size_ = minimum_size; +void NativeButtonWin::UpdateFont() { + SendMessage(GetHWND(), WM_SETFONT, + reinterpret_cast<WPARAM>(native_button_->font().hfont()), + FALSE); } -void NativeButtonWin::SetIgnoreMinimumSize(bool ignore_minimum_size) { - ignore_minimum_size_ = ignore_minimum_size; +void NativeButtonWin::UpdateDefault() { + SendMessage(GetHWND(), BM_SETSTYLE, + native_button_->is_default() ? BS_DEFPUSHBUTTON : BS_PUSHBUTTON, + true); } View* NativeButtonWin::GetView() { @@ -93,22 +49,9 @@ View* NativeButtonWin::GetView() { // NativeButtonWin, View overrides: gfx::Size NativeButtonWin::GetPreferredSize() { - if (!GetHWND()) - return gfx::Size(); - SIZE sz = {0}; SendMessage(GetHWND(), BCM_GETIDEALSIZE, 0, reinterpret_cast<LPARAM>(&sz)); - if (!ignore_minimum_size_) { - 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())); - } - } return gfx::Size(sz.cx, sz.cy); } @@ -119,7 +62,7 @@ LRESULT NativeButtonWin::ProcessMessage(UINT message, WPARAM w_param, LPARAM l_param) { if (message == WM_COMMAND && HIWORD(w_param) == BN_CLICKED) { - listener_->ButtonPressed(); + native_button_->ButtonPressed(); return 0; } return NativeControlWin::ProcessMessage(message, w_param, l_param); @@ -128,7 +71,7 @@ LRESULT NativeButtonWin::ProcessMessage(UINT message, bool NativeButtonWin::OnKeyDown(int vkey) { bool enter_pressed = vkey == VK_RETURN; if (enter_pressed) - listener_->ButtonPressed(); + native_button_->ButtonPressed(); return enter_pressed; } @@ -138,7 +81,7 @@ bool NativeButtonWin::NotifyOnKeyDown() const { void NativeButtonWin::CreateNativeControl() { DWORD flags = WS_CHILD | BS_PUSHBUTTON; - if (is_default_) + if (native_button_->is_default()) flags |= BS_DEFPUSHBUTTON; HWND control_hwnd = CreateWindowEx(GetAdditionalExStyle(), L"BUTTON", L"", flags, 0, 0, width(), height(), @@ -150,17 +93,17 @@ void NativeButtonWin::CreateNativeControl() { void NativeButtonWin::NativeControlCreated(HWND control_hwnd) { NativeControlWin::NativeControlCreated(control_hwnd); - SendMessage(control_hwnd, WM_SETFONT, reinterpret_cast<WPARAM>(font_.hfont()), - FALSE); - SetLabel(GetLabel()); + UpdateFont(); + UpdateLabel(); + UpdateDefault(); } //////////////////////////////////////////////////////////////////////////////// // NativeCheckboxWin, public: -NativeCheckboxWin::NativeCheckboxWin(NativeButtonWrapperListener* listener) - : NativeButtonWin(listener), - selected_(false) { +NativeCheckboxWin::NativeCheckboxWin(Checkbox2* checkbox) + : NativeButtonWin(checkbox), + checkbox_(checkbox) { } NativeCheckboxWin::~NativeCheckboxWin() { @@ -169,19 +112,9 @@ NativeCheckboxWin::~NativeCheckboxWin() { //////////////////////////////////////////////////////////////////////////////// // NativeCheckboxWin, NativeButtonWrapper implementation: -void NativeCheckboxWin::SetSelected(bool selected) { - if (selected == selected_) - return; - - selected_ = selected; - if (GetHWND()) { - SendMessage(GetHWND(), BM_SETCHECK, selected ? BST_CHECKED : BST_UNCHECKED, - 0); - } -} - -bool NativeCheckboxWin::IsSelected() const { - return selected_; +void NativeCheckboxWin::UpdateChecked() { + SendMessage(GetHWND(), BM_SETCHECK, + checkbox_->checked() ? BST_CHECKED : BST_UNCHECKED, 0); } void NativeCheckboxWin::SetHighlight(bool highlight) { @@ -195,7 +128,7 @@ LRESULT NativeCheckboxWin::ProcessMessage(UINT message, WPARAM w_param, LPARAM l_param) { if (message == WM_COMMAND && HIWORD(w_param) == BN_CLICKED) { - SetSelected(!IsSelected()); + checkbox_->SetChecked(!checkbox_->checked()); // Fall through to the NativeButtonWin's handler, which will send the // clicked notification to the listener... } @@ -217,22 +150,21 @@ void NativeCheckboxWin::CreateNativeControl() { void NativeCheckboxWin::NativeControlCreated(HWND control_hwnd) { NativeButtonWin::NativeControlCreated(control_hwnd); - SetSelected(IsSelected()); + UpdateChecked(); } //////////////////////////////////////////////////////////////////////////////// // NativeRadioButtonWin, public: -NativeRadioButtonWin::NativeRadioButtonWin( - NativeButtonWrapperListener* listener) - : NativeCheckboxWin(listener) { +NativeRadioButtonWin::NativeRadioButtonWin(RadioButton2* radio_button) + : NativeCheckboxWin(radio_button) { } NativeRadioButtonWin::~NativeRadioButtonWin() { } //////////////////////////////////////////////////////////////////////////////// -// NativeRaidoButotnWin, NativeCheckboxWin overrides: +// NativeRadioButtonWin, NativeCheckboxWin overrides: void NativeRadioButtonWin::CreateNativeControl() { HWND control_hwnd = CreateWindowEx(GetAdditionalExStyle(), L"BUTTON", @@ -248,17 +180,15 @@ void NativeRadioButtonWin::CreateNativeControl() { // static NativeButtonWrapper* NativeButtonWrapper::CreateNativeButtonWrapper( - NativeButtonWrapperListener* listener, Type type) { - switch (type) { - case TYPE_BUTTON: - return new NativeButtonWin(listener); - case TYPE_CHECKBOX: - return new NativeCheckboxWin(listener); - case TYPE_RADIOBUTTON: - return new NativeRadioButtonWin(listener); - } - NOTREACHED() << "Invalid button type!"; - return NULL; + NativeButton2* native_button) { + return new NativeButtonWin(native_button); +} + +// static +NativeButtonWrapper* NativeButtonWrapper::CreateCheckboxWrapper( + Checkbox2* checkbox) { + return new NativeCheckboxWin(checkbox); } } // namespace views + diff --git a/chrome/views/controls/button/native_button_win.h b/chrome/views/controls/button/native_button_win.h index b711537..97eab47 100644 --- a/chrome/views/controls/button/native_button_win.h +++ b/chrome/views/controls/button/native_button_win.h @@ -5,7 +5,6 @@ #ifndef CHROME_VIEWS_CONTROLS_BUTTON_NATIVE_BUTTON_WIN_H_ #define CHROME_VIEWS_CONTROLS_BUTTON_NATIVE_BUTTON_WIN_H_ -#include "chrome/common/gfx/chrome_font.h" #include "chrome/views/controls/native_control_win.h" #include "chrome/views/controls/button/native_button_wrapper.h" @@ -15,17 +14,13 @@ namespace views { class NativeButtonWin : public NativeControlWin, public NativeButtonWrapper { public: - explicit NativeButtonWin(NativeButtonWrapperListener* listener); + explicit NativeButtonWin(NativeButton2* native_button); virtual ~NativeButtonWin(); // Overridden from NativeButtonWrapper: - virtual void SetLabel(const std::wstring& label); - virtual std::wstring GetLabel() const; - virtual void SetFont(const ChromeFont& font); - virtual void SetDefaultButton(bool is_default); - virtual bool IsDefaultButton() const; - virtual void SetMinimumSizeInPlatformUnits(const gfx::Size& minimum_size); - virtual void SetIgnoreMinimumSize(bool ignore_minimum_size); + virtual void UpdateLabel(); + virtual void UpdateFont(); + virtual void UpdateDefault(); virtual View* GetView(); // Overridden from View: @@ -43,24 +38,8 @@ class NativeButtonWin : public NativeControlWin, virtual void NativeControlCreated(HWND control_hwnd); private: - // Our listener. - NativeButtonWrapperListener* listener_; - - // The button label. - std::wstring label_; - - // True if the button is the default button in its context. - bool is_default_; - - // The font used to render the button label. - ChromeFont font_; - - // True if the button should ignore the minimum size for the platform. Default - // is false. - bool ignore_minimum_size_; - - // Minimum size, in dlus (see SetMinimumSizeInPlatformUnits). - gfx::Size min_dlu_size_; + // The NativeButton we are bound to. + NativeButton2* native_button_; DISALLOW_COPY_AND_ASSIGN(NativeButtonWin); }; @@ -68,12 +47,11 @@ class NativeButtonWin : public NativeControlWin, // A View that hosts a native Windows checkbox. class NativeCheckboxWin : public NativeButtonWin { public: - explicit NativeCheckboxWin(NativeButtonWrapperListener* listener); + explicit NativeCheckboxWin(Checkbox2* native_button); virtual ~NativeCheckboxWin(); // Overridden from NativeButtonWrapper: - virtual void SetSelected(bool selected); - virtual bool IsSelected() const; + virtual void UpdateChecked(); virtual void SetHighlight(bool highlight); // Overridden from NativeControlWin: @@ -86,8 +64,8 @@ class NativeCheckboxWin : public NativeButtonWin { virtual void NativeControlCreated(HWND control_hwnd); private: - // True if this checkbox is checked. - bool selected_; + // The Checkbox we are bound to. + Checkbox2* checkbox_; DISALLOW_COPY_AND_ASSIGN(NativeCheckboxWin); }; @@ -95,7 +73,7 @@ class NativeCheckboxWin : public NativeButtonWin { // A View that hosts a native Windows radio button. class NativeRadioButtonWin : public NativeCheckboxWin { public: - explicit NativeRadioButtonWin(NativeButtonWrapperListener* listener); + explicit NativeRadioButtonWin(RadioButton2* radio_button); virtual ~NativeRadioButtonWin(); protected: diff --git a/chrome/views/controls/button/native_button_wrapper.h b/chrome/views/controls/button/native_button_wrapper.h index f530b83..7eaacfe 100644 --- a/chrome/views/controls/button/native_button_wrapper.h +++ b/chrome/views/controls/button/native_button_wrapper.h @@ -9,59 +9,39 @@ class ChromeFont; namespace views { -// An interface implemented by the view that owns the NativeButtonWrapper that -// allows it to be notified when the button is pressed. -class NativeButtonWrapperListener { - public: - virtual void ButtonPressed() = 0; -}; +class Checkbox2; +class NativeButton2; +class RadioButton2; // A specialization of NativeControlWrapper that hosts a platform-native button. class NativeButtonWrapper { public: - // Sets/Gets the button's label. - virtual void SetLabel(const std::wstring& label) = 0; - virtual std::wstring GetLabel() const = 0; - - // Sets the font used by this button. - virtual void SetFont(const ChromeFont& font) = 0; - - // Sets whether or not the button should have the default appearance and - // action in its setting. - virtual void SetDefaultButton(bool is_default) = 0; - virtual bool IsDefaultButton() const = 0; - - // Sets the minimum size of the button from the specified size in native - // dialog units. The definition of this unit may vary from platform to - // platform. If the width/height is non-zero, the preferred size of the button - // will not be less than this value when the dialog units are converted to - // pixels. - virtual void SetMinimumSizeInPlatformUnits(const gfx::Size& minimum_size) = 0; - - // Call to have the button ignore its minimum size. Use this if you want - // buttons narrower than the defined minimum size. - virtual void SetIgnoreMinimumSize(bool ignore_minimum_size) = 0; - - // Sets/Gets the selected state of button. Valid only for checkboxes and radio - // buttons. - virtual void SetSelected(bool is_selected) {} - virtual bool IsSelected(bool is_selected) { return false; } - + // Updates the native button's label from the state stored in its associated + // NativeButton. + virtual void UpdateLabel() = 0; + + // Updates the native button's label font from the state stored in its + // associated NativeButton. + virtual void UpdateFont() = 0; + + // Updates the native button's default state from the state stored in its + // associated NativeButton. + virtual void UpdateDefault() = 0; + + // Updates the native button's checked state from the state stored in its + // associated NativeCheckbox. Valid only for checkboxes and radio buttons. + virtual void UpdateChecked() {} + // Shows the hover state for the button if |highlight| is true. virtual void SetHighlight(bool highlight) {}; // Retrieves the views::View that hosts the native control. virtual View* GetView() = 0; - enum Type { - TYPE_BUTTON, - TYPE_CHECKBOX, - TYPE_RADIOBUTTON - }; - // Creates an appropriate NativeButtonWrapper for the platform. - static NativeButtonWrapper* CreateNativeButtonWrapper( - NativeButtonWrapperListener* listener, Type type); + static NativeButtonWrapper* CreateNativeButtonWrapper(NativeButton2* button); + static NativeButtonWrapper* CreateCheckboxWrapper(Checkbox2* checkbox); + }; } // namespace views diff --git a/chrome/views/controls/button/radio_button.cc b/chrome/views/controls/button/radio_button.cc index 758c747..0736189 100644 --- a/chrome/views/controls/button/radio_button.cc +++ b/chrome/views/controls/button/radio_button.cc @@ -76,7 +76,7 @@ void RadioButton::Layout() { int first_line_height = label_->GetFont().height(); hwnd_view_->SetBounds(0, ((first_line_height - kRadioHeight) / 2) + 1, kRadioWidth, kRadioHeight); - hwnd_view_->UpdateHWNDBounds(); + hwnd_view_->Layout(); } } diff --git a/chrome/views/controls/hwnd_view.cc b/chrome/views/controls/hwnd_view.cc index cc9df6d..bc8a7eb 100644 --- a/chrome/views/controls/hwnd_view.cc +++ b/chrome/views/controls/hwnd_view.cc @@ -41,7 +41,7 @@ void HWNDView::Attach(HWND hwnd) { // Need to set the HWND's parent before changing its size to avoid flashing. ::SetParent(hwnd_, GetWidget()->GetNativeView()); - UpdateHWNDBounds(); + Layout(); // Register with the focus manager so the associated view is focused when the // native control gets the focus. @@ -64,7 +64,7 @@ HWND HWNDView::GetHWND() const { return hwnd_; } -void HWNDView::UpdateHWNDBounds() { +void HWNDView::Layout() { if (!hwnd_) return; @@ -131,15 +131,8 @@ void HWNDView::UpdateHWNDBounds() { } } -void HWNDView::DidChangeBounds(const gfx::Rect& previous, - const gfx::Rect& current) { - // TODO(beng): (Cleanup) Could UpdateHWNDBounds be replaced by a Layout - // method and this function gotten rid of? - UpdateHWNDBounds(); -} - void HWNDView::VisibilityChanged(View* starting_from, bool is_visible) { - UpdateHWNDBounds(); + Layout(); } gfx::Size HWNDView::GetPreferredSize() { @@ -159,7 +152,7 @@ void HWNDView::ViewHierarchyChanged(bool is_add, View *parent, View *child) { ::ShowWindow(hwnd_, SW_SHOW); else ::ShowWindow(hwnd_, SW_HIDE); - UpdateHWNDBounds(); + Layout(); } else if (!is_add) { ::ShowWindow(hwnd_, SW_HIDE); ::SetParent(hwnd_, NULL); @@ -168,7 +161,7 @@ void HWNDView::ViewHierarchyChanged(bool is_add, View *parent, View *child) { } void HWNDView::VisibleBoundsInRootChanged() { - UpdateHWNDBounds(); + Layout(); } void HWNDView::Focus() { diff --git a/chrome/views/controls/hwnd_view.h b/chrome/views/controls/hwnd_view.h index a13a1f8..d39fc2a 100644 --- a/chrome/views/controls/hwnd_view.h +++ b/chrome/views/controls/hwnd_view.h @@ -38,14 +38,11 @@ class HWNDView : public View { // Detach the attached window handle. It will no longer be updated void Detach(); - virtual void DidChangeBounds(const gfx::Rect& previous, - const gfx::Rect& current); virtual void VisibilityChanged(View* starting_from, bool is_visible); HWND GetHWND() const; - // Resize the hosted HWND to the bounds of this View. - void UpdateHWNDBounds(); + virtual void Layout(); virtual void Paint(ChromeCanvas* canvas); diff --git a/chrome/views/controls/native_control_win.cc b/chrome/views/controls/native_control_win.cc index f60b93c..4e4f2f7 100644 --- a/chrome/views/controls/native_control_win.cc +++ b/chrome/views/controls/native_control_win.cc @@ -10,13 +10,19 @@ namespace views { -//////////////////////////////////////////////////////////////////////////////// -// NativeControlWin, public: - // static const wchar_t* NativeControlWin::kNativeControlWinKey = L"__NATIVE_CONTROL_WIN__"; +static const wchar_t* kNativeControlOriginalWndProcKey = + L"__NATIVE_CONTROL_ORIGINAL_WNDPROC__"; + +// static +WNDPROC NativeControlWin::original_wndproc_ = NULL; + +//////////////////////////////////////////////////////////////////////////////// +// NativeControlWin, public: + NativeControlWin::NativeControlWin() : HWNDView() { } @@ -93,16 +99,21 @@ void NativeControlWin::ShowContextMenu(const gfx::Point& location) { } void NativeControlWin::NativeControlCreated(HWND native_control) { + TRACK_HWND_CREATION(native_control); + // Associate this object with the control's HWND so that WidgetWin can find // this object when it receives messages from it. SetProp(native_control, kNativeControlWinKey, this); + // Subclass the window so we can monitor for key presses. + original_wndproc_ = + win_util::SetWindowProc(native_control, + &NativeControlWin::NativeControlWndProc); + SetProp(native_control, kNativeControlOriginalWndProcKey, original_wndproc_); + Attach(native_control); // GetHWND() is now valid. - // Subclass the window so we can monitor for key presses. - win_util::Subclass(GetHWND(), &NativeControlWin::NativeControlWndProc); - // Update the newly created HWND with any resident enabled state. EnableWindow(GetHWND(), IsEnabled()); @@ -165,11 +176,13 @@ LRESULT NativeControlWin::NativeControlWndProc(HWND window, if (native_control->OnKeyDown(static_cast<int>(w_param))) return 0; } else if (message == WM_DESTROY) { - win_util::Unsubclass(window, &NativeControlWin::NativeControlWndProc); + win_util::SetWindowProc(window, native_control->original_wndproc_); + RemoveProp(window, kNativeControlWinKey); TRACK_HWND_DESTRUCTION(window); } - return DefWindowProc(window, message, w_param, l_param); + return CallWindowProc(native_control->original_wndproc_, window, message, + w_param, l_param); } } // namespace views diff --git a/chrome/views/controls/native_control_win.h b/chrome/views/controls/native_control_win.h index c2ecb41..02b89a2 100644 --- a/chrome/views/controls/native_control_win.h +++ b/chrome/views/controls/native_control_win.h @@ -86,6 +86,9 @@ class NativeControlWin : public HWNDView { WPARAM w_param, LPARAM l_param); + // The window procedure before we subclassed. + static WNDPROC original_wndproc_; + DISALLOW_COPY_AND_ASSIGN(NativeControlWin); }; diff --git a/chrome/views/controls/text_field.cc b/chrome/views/controls/text_field.cc index 9d61b43..a769c2a 100644 --- a/chrome/views/controls/text_field.cc +++ b/chrome/views/controls/text_field.cc @@ -953,7 +953,7 @@ void TextField::ViewHierarchyChanged(bool is_add, View* parent, View* child) { void TextField::Layout() { if (native_view_) { native_view_->SetBounds(GetLocalBounds(true)); - native_view_->UpdateHWNDBounds(); + native_view_->Layout(); } } diff --git a/chrome/views/views.vcproj b/chrome/views/views.vcproj index 1f19037..e828965 100644 --- a/chrome/views/views.vcproj +++ b/chrome/views/views.vcproj @@ -582,6 +582,14 @@ > </File> <File + RelativePath=".\controls\button\checkbox2.cc" + > + </File> + <File + RelativePath=".\controls\button\checkbox2.h" + > + </File> + <File RelativePath=".\controls\button\custom_button.cc" > </File> @@ -614,6 +622,14 @@ > </File> <File + RelativePath=".\controls\button\native_button2.cc" + > + </File> + <File + RelativePath=".\controls\button\native_button2.h" + > + </File> + <File RelativePath=".\controls\button\native_button_win.cc" > </File> |