File: menu_button_controller.h

package info (click to toggle)
chromium 138.0.7204.183-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,908 kB
  • sloc: cpp: 34,937,088; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (136 lines) | stat: -rw-r--r-- 5,474 bytes parent folder | download | duplicates (9)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef UI_VIEWS_CONTROLS_BUTTON_MENU_BUTTON_CONTROLLER_H_
#define UI_VIEWS_CONTROLS_BUTTON_MENU_BUTTON_CONTROLLER_H_

#include <memory>
#include <utility>

#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "ui/views/controls/button/button_controller.h"

namespace views {
class ButtonControllerDelegate;
class MenuButton;

// A controller that contains the logic for showing a menu when the left mouse
// is pushed.
class VIEWS_EXPORT MenuButtonController : public ButtonController {
 public:
  // A scoped lock for keeping the MenuButton in STATE_PRESSED e.g., while a
  // menu is running. These are cumulative.
  class VIEWS_EXPORT PressedLock {
   public:
    explicit PressedLock(MenuButtonController* menu_button_controller);

    // |event| is the event that caused the button to be pressed. May be null.
    PressedLock(MenuButtonController* menu_button_controller,
                bool is_sibling_menu_show,
                const ui::LocatedEvent* event);

    PressedLock(const PressedLock&) = delete;
    PressedLock& operator=(const PressedLock&) = delete;

    ~PressedLock();

   private:
    base::WeakPtr<MenuButtonController> menu_button_controller_;
  };

  MenuButtonController(Button* button,
                       Button::PressedCallback callback,
                       std::unique_ptr<ButtonControllerDelegate> delegate);

  MenuButtonController(const MenuButtonController&) = delete;
  MenuButtonController& operator=(const MenuButtonController&) = delete;

  ~MenuButtonController() override;

  // view::ButtonController
  bool OnMousePressed(const ui::MouseEvent& event) override;
  void OnMouseReleased(const ui::MouseEvent& event) override;
  void OnMouseMoved(const ui::MouseEvent& event) override;
  void OnMouseEntered(const ui::MouseEvent& event) override;
  void OnMouseExited(const ui::MouseEvent& event) override;
  bool OnKeyPressed(const ui::KeyEvent& event) override;
  bool OnKeyReleased(const ui::KeyEvent& event) override;
  void OnGestureEvent(ui::GestureEvent* event) override;
  void UpdateButtonAccessibleDefaultActionVerb() override;
  bool IsTriggerableEvent(const ui::Event& event) override;
  void NotifyClick() override;

  // Calls TakeLock with is_sibling_menu_show as false and a nullptr to the
  // event.
  std::unique_ptr<PressedLock> TakeLock();

  // Convenience method to increment the lock count on a button to keep the
  // button in a PRESSED state when a menu is showing.
  std::unique_ptr<PressedLock> TakeLock(bool is_sibling_menu_show,
                                        const ui::LocatedEvent* event);

  // Activate the button (called when the button is pressed). |event| is the
  // event triggering the activation, if any.
  bool Activate(const ui::Event* event);

  // Returns true if the event is of the proper type to potentially trigger an
  // action. Since MenuButtons have properties other than event type (like
  // last menu open time) to determine if an event is valid to activate the
  // menu, this is distinct from IsTriggerableEvent().
  bool IsTriggerableEventType(const ui::Event& event);

  void SetCallback(Button::PressedCallback callback) {
    callback_ = std::move(callback);
  }

 private:
  // Increment/decrement the number of "pressed" locks this button has, and
  // set the state accordingly. The ink drop is snapped to the final ACTIVATED
  // state if |snap_ink_drop_to_activated| is true, otherwise the ink drop
  // will be animated to the ACTIVATED node_data. The ink drop is animated at
  // the location of |event| if non-null, otherwise at the default location.
  void IncrementPressedLocked(bool snap_ink_drop_to_activated,
                              const ui::LocatedEvent* event);

  void DecrementPressedLocked();

  // Called if the button state changes while pressed lock is engaged.
  void OnButtonStateChangedWhilePressedLocked();

  // Our callback.
  Button::PressedCallback callback_;

  // We use a time object in order to keep track of when the menu was closed.
  // The time is used for simulating menu behavior for the menu button; that
  // is, if the menu is shown and the button is pressed, we need to close the
  // menu. There is no clean way to get the second click event because the
  // menu is displayed using a modal loop and, unlike regular menus in
  // Windows, the button is not part of the displayed menu.
  base::TimeTicks menu_closed_time_;

  // Tracks if the current triggering event should open a menu.
  bool is_intentional_menu_trigger_ = true;

  // The current number of "pressed" locks this button has.
  int pressed_lock_count_ = 0;

  // Used to let Activate() know if IncrementPressedLocked() was called.
  raw_ptr<bool> increment_pressed_lock_called_ = nullptr;

  // True if the button was in a disabled state when a menu was run, and
  // should return to it once the press is complete. This can happen if, e.g.,
  // we programmatically show a menu on a disabled button.
  bool should_disable_after_press_ = false;

  // Subscribes to state changes on the button while pressed lock is engaged.
  base::CallbackListSubscription state_changed_subscription_;

  base::WeakPtrFactory<MenuButtonController> weak_factory_{this};
};

}  // namespace views

#endif  // UI_VIEWS_CONTROLS_BUTTON_MENU_BUTTON_CONTROLLER_H_