File: shelf_app_button.h

package info (click to toggle)
chromium 120.0.6099.224-1~deb11u1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 6,112,112 kB
  • sloc: cpp: 32,907,025; ansic: 8,148,123; javascript: 3,679,536; python: 2,031,248; asm: 959,718; java: 804,675; xml: 617,256; sh: 111,417; objc: 100,835; perl: 88,443; cs: 53,032; makefile: 29,579; fortran: 24,137; php: 21,162; tcl: 21,147; sql: 20,809; ruby: 17,735; pascal: 12,864; yacc: 8,045; lisp: 3,388; lex: 1,323; ada: 727; awk: 329; jsp: 267; csh: 117; exp: 43; sed: 37
file content (270 lines) | stat: -rw-r--r-- 9,405 bytes parent folder | download
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef ASH_SHELF_SHELF_APP_BUTTON_H_
#define ASH_SHELF_SHELF_APP_BUTTON_H_

#include "ash/ash_export.h"
#include "ash/public/cpp/shelf_types.h"
#include "ash/shelf/shelf_button.h"
#include "ash/shelf/shelf_button_delegate.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/timer/timer.h"
#include "ui/compositor/layer_animation_observer.h"
#include "ui/gfx/shadow_value.h"
#include "ui/views/animation/ink_drop_observer.h"
#include "ui/views/animation/ink_drop_state.h"

namespace views {
class ImageView;
}  // namespace views

namespace ash {
struct ShelfItem;
class DotIndicator;
class ProgressIndicator;
class ShelfView;

// Button used for app shortcuts on the shelf.
class ASH_EXPORT ShelfAppButton : public ShelfButton,
                                  public views::InkDropObserver,
                                  public ui::ImplicitAnimationObserver {
 public:
  static const char kViewClassName[];

  // Used to indicate the current state of the button.
  enum State {
    // Nothing special. Usually represents an app shortcut item with no running
    // instance.
    STATE_NORMAL = 0,
    // Button has mouse hovering on it.
    STATE_HOVERED = 1 << 0,
    // Underlying ShelfItem has a running instance.
    STATE_RUNNING = 1 << 1,
    // Underlying ShelfItem needs user's attention.
    STATE_ATTENTION = 1 << 2,
    // Hide the status (temporarily for some animations).
    STATE_HIDDEN = 1 << 3,
    // Button is being dragged.
    STATE_DRAGGING = 1 << 4,
    // App has at least 1 notification.
    STATE_NOTIFICATION = 1 << 5,
    // Underlying ShelfItem owns the window that is currently active.
    STATE_ACTIVE = 1 << 6,
  };

  // Returns whether |event| should be handled by a ShelfAppButton if a context
  // menu for the view is shown. Note that the context menu controller will
  // redirect gesture events to the hotseat widget if the context menu was shown
  // for a ShelfAppButton). The hotseat widget uses this method to determine
  // whether such events can/should be dropped without handling.
  static bool ShouldHandleEventFromContextMenu(const ui::GestureEvent* event);

  ShelfAppButton(ShelfView* shelf_view,
                 ShelfButtonDelegate* shelf_button_delegate);

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

  ~ShelfAppButton() override;

  // Sets the image to display for this entry.
  void SetImage(const gfx::ImageSkia& image);

  // Retrieve the image to show proxy operations.
  gfx::ImageSkia GetImage() const;

  // Gets the resized `icon_image_` without the shadow.
  gfx::ImageSkia GetIconImage() const;

  // |state| is or'd into the current state.
  void AddState(State state);
  void ClearState(State state);
  int state() const { return state_; }

  // Clears drag drag state that might have been set by gesture handling when a
  // gesture ends. No-op if the drag state has already been cleared.
  void ClearDragStateOnGestureEnd();

  // Returns the bounds of the icon.
  gfx::Rect GetIconBounds() const;

  // Returns the ideal icon bounds within the button view of the provided size,
  // and with the provided icon scale.
  gfx::Rect GetIdealIconBounds(const gfx::Size& button_size,
                               float icon_scale) const;

  views::InkDrop* GetInkDropForTesting();

  // Called when user started dragging the shelf button.
  void OnDragStarted(const ui::LocatedEvent* event);

  // Callback used when a menu for this ShelfAppButton is closed.
  void OnMenuClosed();

  // views::Button overrides:
  void ShowContextMenu(const gfx::Point& p,
                       ui::MenuSourceType source_type) override;
  void GetAccessibleNodeData(ui::AXNodeData* node_data) override;
  bool ShouldEnterPushedState(const ui::Event& event) override;

  // views::View overrides:
  const char* GetClassName() const override;
  bool OnMousePressed(const ui::MouseEvent& event) override;
  void OnMouseReleased(const ui::MouseEvent& event) override;
  void OnMouseCaptureLost() override;
  bool OnMouseDragged(const ui::MouseEvent& event) override;
  void Layout() override;
  void ChildPreferredSizeChanged(views::View* child) override;

  // Update button state from ShelfItem.
  void ReflectItemStatus(const ShelfItem& item);

  // Returns whether the icon size is up to date.
  bool IsIconSizeCurrent();

  // Called when the request for the context menu model is canceled.
  void OnContextMenuModelRequestCanceled();

  bool FireDragTimerForTest();
  void FireRippleActivationTimerForTest();

  // Return the bounds in the local coordinates enclosing the small ripple area.
  gfx::Rect CalculateSmallRippleArea() const;

  void SetNotificationBadgeColor(SkColor color);

  float progress() { return progress_; }

  AppStatus app_status() { return app_status_; }

  ProgressIndicator* GetProgressIndicatorForTest() const;

 protected:
  // ui::EventHandler:
  void OnGestureEvent(ui::GestureEvent* event) override;

  // ui::ImplicitAnimationObserver:
  void OnImplicitAnimationsCompleted() override;

  // Sets the icon image with a shadow.
  void SetShadowedImage(const gfx::ImageSkia& bitmap);

 private:
  class AppNotificationIndicatorView;
  class AppStatusIndicatorView;

  // views::View:
  bool HandleAccessibleAction(const ui::AXActionData& action_data) override;

  // views::InkDropObserver:
  void InkDropAnimationStarted() override;
  void InkDropRippleAnimationEnded(views::InkDropState state) override;

  // Updates the parts of the button to reflect the current |state_| and
  // alignment. This may add or remove views, layout and paint.
  void UpdateState();

  // Invoked when |touch_drag_timer_| fires to show dragging UI.
  void OnTouchDragTimer();

  // Invoked when |ripple_activation_timer_| fires to activate the ink drop.
  void OnRippleTimer();

  // Calculates the preferred size of the icon.
  gfx::Size GetPreferredIconSize() const;

  // Scales up app icon if |scale_up| is true, otherwise scales it back to
  // normal size.
  void ScaleAppIcon(bool scale_up);

  // Calculates the icon bounds for an icon scaled by |icon_scale|.
  gfx::Rect GetIconViewBounds(const gfx::Rect& button_bounds,
                              float icon_scale) const;

  // Calculates the notification indicator bounds when scaled by |scale|.
  gfx::Rect GetNotificationIndicatorBounds(float scale);

  // Calculates the transform between the icon scaled by |icon_scale| and the
  // normal size icon.
  gfx::Transform GetScaleTransform(float icon_scale);

  // Marks whether the ink drop animation has started or not.
  void SetInkDropAnimationStarted(bool started);

  // Maybe hides the ink drop at the end of gesture handling.
  void MaybeHideInkDropWhenGestureEnds();

  // Updates the layer bounds for the `progress_indicator_` if any is currently
  // active.
  void UpdateProgressRingBounds();

  // Returns the icon scale adjusted to fit for the `progress_indicator_` if any
  // is currently active.
  float GetAdjustedIconScaleForProgressRing() const;

  // The icon part of a button can be animated independently of the rest.
  const raw_ptr<views::ImageView, ExperimentalAsh> icon_view_;

  // The ShelfView showing this ShelfAppButton. Owned by RootWindowController.
  const raw_ptr<ShelfView, ExperimentalAsh> shelf_view_;

  // Draws an indicator underneath the image to represent the state of the
  // application.
  const raw_ptr<AppStatusIndicatorView, ExperimentalAsh> indicator_;

  // Draws an indicator in the top right corner of the image to represent an
  // active notification.
  raw_ptr<DotIndicator, ExperimentalAsh> notification_indicator_ = nullptr;

  // The current application state, a bitfield of State enum values.
  int state_ = STATE_NORMAL;

  gfx::ShadowValues icon_shadows_;

  // The bitmap image for this app button.
  gfx::ImageSkia icon_image_;

  // The scaling factor for displaying the app icon.
  float icon_scale_ = 1.0f;

  // App status.
  AppStatus app_status_ = AppStatus::kReady;

  // Item progress. Only applicable if `is_promise_app_` is true.
  float progress_ = -1.0f;

  // Indicates whether the ink drop animation starts.
  bool ink_drop_animation_started_ = false;

  // A timer to defer showing drag UI when the shelf button is pressed.
  base::OneShotTimer drag_timer_;

  // A timer to activate the ink drop ripple during a long press.
  base::OneShotTimer ripple_activation_timer_;

  // The target visibility of the shelf app's context menu.
  // NOTE: when `context_menu_target_visibility_` is true, the context menu may
  // not show yet due to the async request for the menu model.
  bool context_menu_target_visibility_ = false;

  // An object that draws and updates the progress ring around promise app
  // icons.
  std::unique_ptr<ProgressIndicator> progress_indicator_;

  std::unique_ptr<ShelfButtonDelegate::ScopedActiveInkDropCount>
      ink_drop_count_;

  // Whether the app is a promise app  (i.e. an app with pending or installing
  // app status).
  bool is_promise_app_ = false;

  // Used to track whether the menu was deleted while running. Must be last.
  base::WeakPtrFactory<ShelfAppButton> weak_factory_{this};
};

}  // namespace ash

#endif  // ASH_SHELF_SHELF_APP_BUTTON_H_