diff options
Diffstat (limited to 'views')
-rw-r--r-- | views/controls/button/custom_button.cc | 21 | ||||
-rw-r--r-- | views/controls/button/custom_button.h | 5 | ||||
-rw-r--r-- | views/widget/root_view.cc | 7 |
3 files changed, 29 insertions, 4 deletions
diff --git a/views/controls/button/custom_button.cc b/views/controls/button/custom_button.cc index 973a8e5..e87bae9 100644 --- a/views/controls/button/custom_button.cc +++ b/views/controls/button/custom_button.cc @@ -6,6 +6,7 @@ #include "app/throb_animation.h" #include "base/keyboard_codes.h" +#include "views/screen.h" namespace views { @@ -71,8 +72,13 @@ bool CustomButton::GetAccessibleState(AccessibilityTypes::State* state) { } void CustomButton::SetEnabled(bool enabled) { - if (enabled ? (state_ == BS_DISABLED) : (state_ != BS_DISABLED)) - SetState(enabled ? BS_NORMAL : BS_DISABLED); + if (enabled ? (state_ != BS_DISABLED) : (state_ == BS_DISABLED)) + return; + + if (enabled) + SetState(IsMouseHovered() ? BS_HOT : BS_NORMAL); + else + SetState(BS_DISABLED); } bool CustomButton::IsEnabled() const { @@ -83,6 +89,17 @@ bool CustomButton::IsFocusable() const { return (state_ != BS_DISABLED) && View::IsFocusable(); } +bool CustomButton::IsMouseHovered() const { + // If we haven't yet been placed in an onscreen view hierarchy, we can't be + // hovered. + if (!GetWidget()) + return false; + + gfx::Point cursor_pos(Screen::GetCursorScreenPoint()); + ConvertPointToView(NULL, this, &cursor_pos); + return HitTest(cursor_pos); +} + //////////////////////////////////////////////////////////////////////////////// // CustomButton, protected: diff --git a/views/controls/button/custom_button.h b/views/controls/button/custom_button.h index 1f85e0b..4d7dff7 100644 --- a/views/controls/button/custom_button.h +++ b/views/controls/button/custom_button.h @@ -63,6 +63,11 @@ class CustomButton : public Button, } bool request_focus_on_press() const { return request_focus_on_press_; } + // Returns true if the mouse pointer is over this control. Note that this + // isn't the same as IsHotTracked() because the mouse may be over the control + // when it's disabled. + bool IsMouseHovered() const; + protected: // Construct the Button with a Listener. See comment for Button's ctor. explicit CustomButton(ButtonListener* listener); diff --git a/views/widget/root_view.cc b/views/widget/root_view.cc index 91ba511..a56ec99 100644 --- a/views/widget/root_view.cc +++ b/views/widget/root_view.cc @@ -455,8 +455,11 @@ void RootView::OnMouseReleased(const MouseEvent& e, bool canceled) { void RootView::OnMouseMoved(const MouseEvent& e) { View* v = GetViewForPoint(e.location()); - // Find the first enabled view. - while (v && !v->IsEnabled()) + // Find the first enabled view, or the existing move handler, whichever comes + // first. The check for the existing handler is because if a view becomes + // disabled while handling moves, it's wrong to suddenly send ET_MOUSE_EXITED + // and ET_MOUSE_ENTERED events, because the mouse hasn't actually exited yet. + while (v && !v->IsEnabled() && (v != mouse_move_handler_)) v = v->GetParent(); if (v && v != this) { if (v != mouse_move_handler_) { |