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 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293
|
// Copyright 2014 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_HOME_BUTTON_H_
#define ASH_SHELF_HOME_BUTTON_H_
#include <memory>
#include "ash/app_list/app_list_metrics.h"
#include "ash/app_list/app_list_model_provider.h"
#include "ash/app_list/quick_app_access_model.h"
#include "ash/ash_export.h"
#include "ash/public/cpp/app_list/app_list_controller_observer.h"
#include "ash/public/cpp/shelf_config.h"
#include "ash/shelf/home_button_controller.h"
#include "ash/shelf/shelf_button_delegate.h"
#include "ash/shelf/shelf_control_button.h"
#include "ash/shell_observer.h"
#include "base/memory/raw_ptr.h"
#include "base/scoped_observation.h"
#include "ui/base/metadata/metadata_header_macros.h"
#include "ui/events/devices/input_device_event_observer.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/transform.h"
#include "ui/views/view_targeter_delegate.h"
namespace views {
class AnimationBuilder;
class CircleLayerDelegate;
class ImageButton;
class Label;
} // namespace views
namespace ui {
class LayerOwner;
}
namespace ash {
class Shelf;
class ShelfButtonDelegate;
class ShelfNavigationWidget;
class Shell;
// Button used for the AppList icon on the shelf. It opens the app list (in
// clamshell mode) or home screen (in tablet mode). Because the clamshell-mode
// app list appears like a dismissable overlay, the button is highlighted while
// the app list is open in clamshell mode.
//
// If Assistant is enabled, the button is filled in; long-pressing it will
// launch Assistant.
//
// If Sunfish/Scanner is enabled, long-pressing the button will start a
// Sunfish-behaviour capture mode session instead.
class ASH_EXPORT HomeButton : public ShelfControlButton,
public ShelfButtonDelegate,
public views::ViewTargeterDelegate,
public ShellObserver,
public ShelfConfig::Observer,
public AppListModelProvider::Observer,
public QuickAppAccessModel::Observer,
public ui::InputDeviceEventObserver {
METADATA_HEADER(HomeButton, ShelfControlButton)
public:
class ScopedNoClipRect {
public:
explicit ScopedNoClipRect(ShelfNavigationWidget* shelf_navigation_widget);
ScopedNoClipRect(const ScopedNoClipRect&) = delete;
ScopedNoClipRect& operator=(const ScopedNoClipRect&) = delete;
~ScopedNoClipRect();
private:
const raw_ptr<ShelfNavigationWidget> shelf_navigation_widget_;
const gfx::Rect clip_rect_;
};
// An observer that can be used to track the nudge animation state. Currently
// used in testing.
class NudgeAnimationObserver : public base::CheckedObserver {
public:
NudgeAnimationObserver() = default;
NudgeAnimationObserver(const NudgeAnimationObserver&) = delete;
NudgeAnimationObserver& operator=(const NudgeAnimationObserver&) = delete;
~NudgeAnimationObserver() override = default;
// Called when the nudge animation is started/ended.
virtual void NudgeAnimationStarted(HomeButton* home_button) = 0;
virtual void NudgeAnimationEnded(HomeButton* home_button) = 0;
// Called when the nudge label is animated to fully shown.
virtual void NudgeLabelShown(HomeButton* home_button) = 0;
};
explicit HomeButton(Shelf* shelf);
HomeButton(const HomeButton&) = delete;
HomeButton& operator=(const HomeButton&) = delete;
~HomeButton() override;
// views::View:
gfx::Size CalculatePreferredSize(
const views::SizeBounds& available_size) const override;
void Layout(PassKey) override;
void AddedToWidget() override;
// views::Button:
void OnGestureEvent(ui::GestureEvent* event) override;
// ShelfButtonDelegate:
void OnShelfButtonAboutToRequestFocusFromTabTraversal(ShelfButton* button,
bool reverse) override;
void ButtonPressed(views::Button* sender,
const ui::Event& event,
views::InkDrop* ink_drop) override;
// ShelfConfig::Observer:
void OnShelfConfigUpdated() override;
// ui::InputDeviceEventObserver:
void OnInputDeviceConfigurationChanged(uint8_t input_device_types) override;
void OnDeviceListsComplete() override;
// Called when the availability of a long-press gesture may have changed, e.g.
// when Assistant becomes enabled.
void OnIconUpdated();
// True if the app list is shown for the display containing this button.
bool IsShowingAppList() const;
// Called when a locale change is detected. Updates the button tooltip and
// accessible name.
void HandleLocaleChange();
// Returns the display which contains this view.
int64_t GetDisplayId() const;
// Clip rect of this view's widget will be removed during the life time of the
// returned ScopedNoClipRect.
[[nodiscard]] std::unique_ptr<ScopedNoClipRect> CreateScopedNoClipRect();
// Checks if the `nudge_label_` can be shown for the launcher nudge.
// NOTE: This must be called after `CreateNudgeLabel()`, where the
// `nudge_label_` is created. This is because whether the nudge can be shown
// depends on nudge_label_'s preferred size.
bool CanShowNudgeLabel() const;
// Starts the launcher nudge animation.
void StartNudgeAnimation();
// Sets the button's "toggled" state - the button is toggled when the bubble
// launcher is shown.
void SetToggled(bool toggled);
void AddNudgeAnimationObserverForTest(NudgeAnimationObserver* observer);
void RemoveNudgeAnimationObserverForTest(NudgeAnimationObserver* observer);
views::View* expandable_container_for_test() const {
return expandable_container_;
}
views::Label* nudge_label_for_test() const { return nudge_label_; }
views::ImageButton* quick_app_button_for_test() const {
return quick_app_button_;
}
void UpdateTooltipText();
protected:
// views::Button:
void OnThemeChanged() override;
private:
class ButtonImageView;
// Creates `nudge_label_` for launcher nudge.
void CreateNudgeLabel();
// Creates the `expandable_container_` which holds either the `nudge_label_`
// or the `quick_app_button_`.
void CreateExpandableContainer();
// Creates the `quick_app_button_` to be shown next to the home button.
void CreateQuickAppButton();
// Called when the quick app button is pressed.
void QuickAppButtonPressed();
// Animation functions for launcher nudge.
void AnimateNudgeRipple(views::AnimationBuilder& builder);
void AnimateNudgeBounce(views::AnimationBuilder& builder);
void AnimateNudgeLabelSlideIn(views::AnimationBuilder& builder);
void AnimateNudgeLabelSlideOut();
void AnimateNudgeLabelFadeOut();
// Callbacks for the nudge animation.
void OnNudgeAnimationStarted();
void OnNudgeAnimationEnded();
void OnLabelSlideInAnimationEnded();
void OnLabelFadeOutAnimationEnded();
// Removes the nudge label from the view hierarchy.
void RemoveNudgeLabel();
// Removes the quick app button from the view hierarchy.
void RemoveQuickAppButton();
// views::ViewTargeterDelegate:
bool DoesIntersectRect(const views::View* target,
const gfx::Rect& rect) const override;
// ShellObserver:
void OnShellDestroying() override;
// AppListModelProvider::Observer:
void OnActiveAppListModelsChanged(AppListModel* model,
SearchModel* search_model) override;
// QuickAppAccessModel::Observer:
void OnQuickAppShouldShowChanged(bool quick_app_shown) override;
void OnQuickAppIconChanged() override;
// Create and animate in the quick app button from behind the home button.
void AnimateQuickAppButtonIn();
// Animate out the quick app button, deleting the quick app button when
// completed.
void AnimateQuickAppButtonOut();
// Callback for the quick app button slide out animation.
void OnQuickAppButtonSlideOutDone();
// Returns a transform which will translate the child of the
// `expandable_container` to be placed behind the home button.
gfx::Transform GetTransformForContainerChildBehindHomeButton();
// Returns a clip rect which will clip the `expandable_container` to the
// bounds of the home button.
gfx::Rect GetExpandableContainerClipRectToHomeButton();
base::ScopedObservation<QuickAppAccessModel, QuickAppAccessModel::Observer>
quick_app_model_observation_{this};
base::ScopedObservation<Shell, ShellObserver> shell_observation_{this};
base::ScopedObservation<AppListModelProvider, AppListModelProvider::Observer>
app_list_model_observation_{this};
const raw_ptr<Shelf> shelf_;
// The view that paints the home button content. In its own view to ensure
// the background is stacked above `expandable_container_`.
raw_ptr<ButtonImageView> button_image_view_ = nullptr;
// The container of `nudge_label_` or `quick_app_button_`. This is also
// responsible for painting the background of the contents. This container can
// expand visually by animation.
raw_ptr<views::View> expandable_container_ = nullptr;
// The app button which is shown next to the home button. Only shown when
// set by SetQuickApp().
raw_ptr<views::ImageButton> quick_app_button_ = nullptr;
// The controller used to determine the button's behavior.
HomeButtonController controller_;
// The delegate used by |nudge_ripple_layer_|. Only exists during the
// nudge animation.
std::unique_ptr<views::CircleLayerDelegate> ripple_layer_delegate_;
// The ripple layer in the launcher nudge animation. Only exists during the
// nudge animation.
ui::LayerOwner nudge_ripple_layer_;
// The label view and for launcher nudge animation.
raw_ptr<views::Label> nudge_label_ = nullptr;
// The timer that counts down to hide the nudge_label_ from showing state.
base::OneShotTimer label_nudge_timer_;
std::unique_ptr<ScopedNoClipRect> scoped_no_clip_rect_;
base::ObserverList<NudgeAnimationObserver> observers_;
base::WeakPtrFactory<HomeButton> weak_ptr_factory_{this};
};
} // namespace ash
#endif // ASH_SHELF_HOME_BUTTON_H_
|