summaryrefslogtreecommitdiffstats
path: root/views
diff options
context:
space:
mode:
Diffstat (limited to 'views')
-rw-r--r--views/controls/button/custom_button.cc21
-rw-r--r--views/controls/button/custom_button.h5
-rw-r--r--views/widget/root_view.cc7
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_) {