| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "views/controls/button/button_dropdown.h" | 5 #include "views/controls/button/button_dropdown.h" |
| 6 | 6 |
| 7 #include "app/l10n_util.h" | 7 #include "app/l10n_util.h" |
| 8 #include "base/compiler_specific.h" | 8 #include "base/compiler_specific.h" |
| 9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
| 10 #include "grit/app_strings.h" | 10 #include "grit/app_strings.h" |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 43 if (IsEnabled() && e.IsLeftMouseButton() && HitTest(e.location())) { | 43 if (IsEnabled() && e.IsLeftMouseButton() && HitTest(e.location())) { |
| 44 // Store the y pos of the mouse coordinates so we can use them later to | 44 // Store the y pos of the mouse coordinates so we can use them later to |
| 45 // determine if the user dragged the mouse down (which should pop up the | 45 // determine if the user dragged the mouse down (which should pop up the |
| 46 // drag down menu immediately, instead of waiting for the timer) | 46 // drag down menu immediately, instead of waiting for the timer) |
| 47 y_position_on_lbuttondown_ = e.y(); | 47 y_position_on_lbuttondown_ = e.y(); |
| 48 | 48 |
| 49 // Schedule a task that will show the menu. | 49 // Schedule a task that will show the menu. |
| 50 MessageLoop::current()->PostDelayedTask(FROM_HERE, | 50 MessageLoop::current()->PostDelayedTask(FROM_HERE, |
| 51 show_menu_factory_.NewRunnableMethod(&ButtonDropDown::ShowDropDownMenu, | 51 show_menu_factory_.NewRunnableMethod(&ButtonDropDown::ShowDropDownMenu, |
| 52 GetWidget()->GetNativeView()), | 52 GetWidget()->GetNativeView()), |
| 53 kMenuTimerDelay); | 53 kMenuTimerDelay); |
| 54 } | 54 } |
| 55 | |
| 56 return ImageButton::OnMousePressed(e); | 55 return ImageButton::OnMousePressed(e); |
| 57 } | 56 } |
| 58 | 57 |
| 59 void ButtonDropDown::OnMouseReleased(const MouseEvent& e, bool canceled) { | 58 void ButtonDropDown::OnMouseReleased(const MouseEvent& e, bool canceled) { |
| 60 ImageButton::OnMouseReleased(e, canceled); | 59 if (e.IsLeftMouseButton() || e.IsRightMouseButton() && !HitTest(e.location())) |
| 60 ImageButton::OnMouseReleased(e, canceled); |
| 61 | 61 |
| 62 if (canceled) | 62 if (canceled) |
| 63 return; | 63 return; |
| 64 | 64 |
| 65 if (e.IsLeftMouseButton()) | 65 if (e.IsLeftMouseButton()) |
| 66 show_menu_factory_.RevokeAll(); | 66 show_menu_factory_.RevokeAll(); |
| 67 | 67 |
| 68 if (IsEnabled() && e.IsRightMouseButton() && HitTest(e.location())) { | 68 if (IsEnabled() && e.IsRightMouseButton() && HitTest(e.location())) { |
| 69 show_menu_factory_.RevokeAll(); | 69 show_menu_factory_.RevokeAll(); |
| 70 // Make the button look depressed while the menu is open. | |
| 71 // NOTE: SetState() schedules a paint, but it won't occur until after the | |
| 72 // context menu message loop has terminated, so we PaintNow() to | |
| 73 // update the appearance synchronously. | |
| 74 SetState(BS_PUSHED); | |
| 75 PaintNow(); | |
| 76 ShowDropDownMenu(GetWidget()->GetNativeView()); | 70 ShowDropDownMenu(GetWidget()->GetNativeView()); |
| 71 // Set the state back to normal after the drop down menu is closed. |
| 72 if (state_ != BS_DISABLED) |
| 73 SetState(BS_NORMAL); |
| 77 } | 74 } |
| 78 } | 75 } |
| 79 | 76 |
| 80 bool ButtonDropDown::OnMouseDragged(const MouseEvent& e) { | 77 bool ButtonDropDown::OnMouseDragged(const MouseEvent& e) { |
| 81 bool result = ImageButton::OnMouseDragged(e); | 78 bool result = ImageButton::OnMouseDragged(e); |
| 82 | 79 |
| 83 if (!show_menu_factory_.empty()) { | 80 if (!show_menu_factory_.empty()) { |
| 84 // If the mouse is dragged to a y position lower than where it was when | 81 // If the mouse is dragged to a y position lower than where it was when |
| 85 // clicked then we should not wait for the menu to appear but show | 82 // clicked then we should not wait for the menu to appear but show |
| 86 // it immediately. | 83 // it immediately. |
| 87 if (e.y() > y_position_on_lbuttondown_ + GetHorizontalDragThreshold()) { | 84 if (e.y() > y_position_on_lbuttondown_ + GetHorizontalDragThreshold()) { |
| 88 show_menu_factory_.RevokeAll(); | 85 show_menu_factory_.RevokeAll(); |
| 89 ShowDropDownMenu(GetWidget()->GetNativeView()); | 86 ShowDropDownMenu(GetWidget()->GetNativeView()); |
| 90 } | 87 } |
| 91 } | 88 } |
| 92 | 89 |
| 93 return result; | 90 return result; |
| 94 } | 91 } |
| 95 | 92 |
| 93 void ButtonDropDown::OnMouseExited(const MouseEvent& e) { |
| 94 // Starting a drag results in a MouseExited, we need to ignore it. |
| 95 // A right click release triggers an exit event. We want to |
| 96 // remain in a PUSHED state until the drop down menu closes. |
| 97 if (state_ != BS_DISABLED && !InDrag() && state_ != BS_PUSHED) |
| 98 SetState(BS_NORMAL); |
| 99 } |
| 100 |
| 96 //////////////////////////////////////////////////////////////////////////////// | 101 //////////////////////////////////////////////////////////////////////////////// |
| 97 // | 102 // |
| 98 // ButtonDropDown - Menu functions | 103 // ButtonDropDown - Menu functions |
| 99 // | 104 // |
| 100 //////////////////////////////////////////////////////////////////////////////// | 105 //////////////////////////////////////////////////////////////////////////////// |
| 101 | 106 |
| 102 void ButtonDropDown::ShowContextMenu(int x, int y, bool is_mouse_gesture) { | 107 void ButtonDropDown::ShowContextMenu(int x, int y, bool is_mouse_gesture) { |
| 103 show_menu_factory_.RevokeAll(); | 108 show_menu_factory_.RevokeAll(); |
| 104 // Make the button look depressed while the menu is open. | 109 // Make the button look depressed while the menu is open. |
| 105 // NOTE: SetState() schedules a paint, but it won't occur until after the | 110 // NOTE: SetState() schedules a paint, but it won't occur until after the |
| 106 // context menu message loop has terminated, so we PaintNow() to | 111 // context menu message loop has terminated, so we PaintNow() to |
| 107 // update the appearance synchronously. | 112 // update the appearance synchronously. |
| 108 SetState(BS_PUSHED); | 113 SetState(BS_PUSHED); |
| 109 PaintNow(); | 114 PaintNow(); |
| 110 ShowDropDownMenu(GetWidget()->GetNativeView()); | 115 ShowDropDownMenu(GetWidget()->GetNativeView()); |
| 111 SetState(BS_HOT); | 116 SetState(BS_HOT); |
| 112 } | 117 } |
| 113 | 118 |
| 119 bool ButtonDropDown::ShouldEnterPushedState(const MouseEvent& e) { |
| 120 // Enter PUSHED state on press with Left or Right mouse button. Remain |
| 121 // in this state while the context menu is open. |
| 122 return ((MouseEvent::EF_LEFT_BUTTON_DOWN | |
| 123 MouseEvent::EF_RIGHT_BUTTON_DOWN) & e.GetFlags()) != 0; |
| 124 } |
| 125 |
| 114 void ButtonDropDown::ShowDropDownMenu(gfx::NativeView window) { | 126 void ButtonDropDown::ShowDropDownMenu(gfx::NativeView window) { |
| 115 if (model_) { | 127 if (model_) { |
| 116 gfx::Rect lb = GetLocalBounds(true); | 128 gfx::Rect lb = GetLocalBounds(true); |
| 117 | 129 |
| 118 // Both the menu position and the menu anchor type change if the UI layout | 130 // Both the menu position and the menu anchor type change if the UI layout |
| 119 // is right-to-left. | 131 // is right-to-left. |
| 120 gfx::Point menu_position(lb.origin()); | 132 gfx::Point menu_position(lb.origin()); |
| 121 menu_position.Offset(0, lb.height() - 1); | 133 menu_position.Offset(0, lb.height() - 1); |
| 122 if (UILayoutIsRightToLeft()) | 134 if (UILayoutIsRightToLeft()) |
| 123 menu_position.Offset(lb.width() - 1, 0); | 135 menu_position.Offset(lb.width() - 1, 0); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 167 } | 179 } |
| 168 | 180 |
| 169 bool ButtonDropDown::GetAccessibleState(AccessibilityTypes::State* state) { | 181 bool ButtonDropDown::GetAccessibleState(AccessibilityTypes::State* state) { |
| 170 DCHECK(state); | 182 DCHECK(state); |
| 171 | 183 |
| 172 *state = AccessibilityTypes::STATE_HASPOPUP; | 184 *state = AccessibilityTypes::STATE_HASPOPUP; |
| 173 return true; | 185 return true; |
| 174 } | 186 } |
| 175 | 187 |
| 176 } // namespace views | 188 } // namespace views |
| OLD | NEW |