// Copyright 2016 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_SYSTEM_PALETTE_PALETTE_TRAY_H_
#define ASH_SYSTEM_PALETTE_PALETTE_TRAY_H_
#include <memory>
#include "ash/ash_export.h"
#include "ash/public/cpp/projector/projector_session.h"
#include "ash/public/cpp/session/session_observer.h"
#include "ash/shelf/shelf_observer.h"
#include "ash/shell_observer.h"
#include "ash/system/palette/palette_tool_manager.h"
#include "ash/system/palette/stylus_battery_delegate.h"
#include "ash/system/tray/tray_background_view.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/scoped_observation.h"
#include "ui/base/metadata/metadata_header_macros.h"
#include "ui/display/manager/display_manager_observer.h"
#include "ui/events/devices/input_device_event_observer.h"
class PrefChangeRegistrar;
class PrefRegistrySimple;
class PrefService;
namespace gfx {
class Point;
}
namespace ui {
class Event;
class EventHandler;
class TouchEvent;
} // namespace ui
namespace views {
class ImageView;
class Widget;
} // namespace views
namespace ash {
class PaletteTrayTestApi;
class PaletteToolManager;
class PaletteWelcomeBubble;
class Shelf;
class TrayBubbleView;
class TrayBubbleWrapper;
// The PaletteTray shows the palette in the bottom area of the screen. This
// class also controls the lifetime for all of the tools available in the
// palette. PaletteTray has one instance per-display. It is only made visible if
// the display has stylus hardware.
class ASH_EXPORT PaletteTray : public TrayBackgroundView,
public SessionObserver,
public ShelfObserver,
public ShellObserver,
public display::DisplayManagerObserver,
public PaletteToolManager::Delegate,
public ui::InputDeviceEventObserver,
public ProjectorSessionObserver {
METADATA_HEADER(PaletteTray, TrayBackgroundView)
public:
explicit PaletteTray(Shelf* shelf);
PaletteTray(const PaletteTray&) = delete;
PaletteTray& operator=(const PaletteTray&) = delete;
~PaletteTray() override;
static void RegisterLocalStatePrefs(PrefRegistrySimple* registry);
static void RegisterProfilePrefs(PrefRegistrySimple* registry);
// Returns true if the palette tray contains the given point. This is useful
// for determining if an event should be propagated through to the palette.
bool ContainsPointInScreen(const gfx::Point& point);
// Returns true if the palette should be visible in the UI. This happens when
// there is a stylus display and the user has not disabled it in settings.
// This can be overridden by passing switches.
bool ShouldShowPalette() const;
// Handles stylus events to show the welcome bubble on first usage.
void OnStylusEvent(const ui::TouchEvent& event);
// SessionObserver:
void OnActiveUserPrefServiceChanged(PrefService* pref_service) override;
void OnSessionStateChanged(session_manager::SessionState state) override;
// ShellObserver:
void OnLockStateChanged(bool locked) override;
void OnShellInitialized() override;
void OnShellDestroying() override;
// display::DisplayManagerObserver:
void OnDidApplyDisplayChanges() override;
// TrayBackgroundView:
void ClickedOutsideBubble(const ui::LocatedEvent& event) override;
void UpdateTrayItemColor(bool is_active) override;
void OnThemeChanged() override;
std::u16string GetAccessibleNameForTray() override;
void HandleLocaleChange() override;
void HideBubbleWithView(const TrayBubbleView* bubble_view) override;
void AnchorUpdated() override;
void Initialize() override;
void CloseBubbleInternal() override;
void ShowBubble() override;
TrayBubbleView* GetBubbleView() override;
views::Widget* GetBubbleWidget() const override;
// PaletteToolManager::Delegate:
void HidePalette() override;
void HidePaletteImmediately() override;
void RecordPaletteOptionsUsage(PaletteTrayOptions option,
PaletteInvocationMethod method) override;
void RecordPaletteModeCancellation(PaletteModeCancelType type) override;
// ProjectorSessionObserver:
void OnProjectorSessionActiveStateChanged(bool active) override;
private:
friend class PaletteTrayTestApi;
friend class StatusAreaInternalsHandler;
// ui::InputDeviceObserver:
void OnInputDeviceConfigurationChanged(uint8_t input_device_types) override;
void OnStylusStateChanged(ui::StylusState stylus_state) override;
void OnTouchDeviceAssociationChanged() override;
// TrayBubbleView::Delegate:
void BubbleViewDestroyed() override;
std::u16string GetAccessibleNameForBubble() override;
bool ShouldEnableExtraKeyboardAccessibility() override;
void HideBubble(const TrayBubbleView* bubble_view) override;
// PaletteToolManager::Delegate:
void OnActiveToolChanged() override;
aura::Window* GetWindow() override;
// Returns true if we're on a display with a stylus or on every
// display if requested from the command line.
bool ShouldShowOnDisplay();
// Returns true if our widget is on an internal display.
bool IsWidgetOnInternalDisplay();
// Initializes with Shell's local state and starts to observe it.
void InitializeWithLocalState();
// Updates the tray icon from the palette tool manager.
void UpdateTrayIcon();
// Sets the icon to visible if the palette can be used.
void UpdateIconVisibility();
// Called when the palette enabled pref has changed.
void OnPaletteEnabledPrefChanged();
// Callback called when this TrayBackgroundView is pressed.
void OnPaletteTrayPressed(const ui::Event& event);
// Called when the has seen stylus pref has changed.
void OnHasSeenStylusPrefChanged();
// Deactivates the active tool. Returns false if there was no active tool.
bool DeactivateActiveTool();
// Helper method which returns true if the device has seen a stylus event
// previously, or if the device has an internal stylus.
bool HasSeenStylus();
// Have the palette act as though it is on a display with a stylus for
// testing purposes.
void SetDisplayHasStylusForTesting();
// ShelfObserver:
void OnAutoHideStateChanged(ShelfAutoHideState new_state) override;
std::unique_ptr<PaletteToolManager> palette_tool_manager_;
std::unique_ptr<PaletteWelcomeBubble> welcome_bubble_;
std::unique_ptr<TrayBubbleWrapper> bubble_;
// A Shell pre-target handler that notifies PaletteTray of stylus events.
std::unique_ptr<ui::EventHandler> stylus_event_handler_;
raw_ptr<PrefService> local_state_ = nullptr; // Not owned.
raw_ptr<PrefService> active_user_pref_service_ = nullptr; // Not owned.
std::unique_ptr<PrefChangeRegistrar> pref_change_registrar_local_;
std::unique_ptr<PrefChangeRegistrar> pref_change_registrar_user_;
// Weak pointer, will be parented by TrayContainer for its lifetime.
raw_ptr<views::ImageView> icon_ = nullptr;
// Cached palette pref value.
bool is_palette_enabled_ = true;
// True when the palette tray should not be visible, regardless of palette
// pref values.
bool is_palette_visibility_paused_ = false;
// Whether the palette should behave as though its display has a stylus.
bool display_has_stylus_for_testing_ = false;
// Used to indicate whether the palette bubble is automatically opened by a
// stylus eject event.
bool is_bubble_auto_opened_ = false;
// Number of actions in pen palette bubble.
int num_actions_in_bubble_ = 0;
base::ScopedObservation<ProjectorSession, ProjectorSessionObserver>
projector_session_observation_{this};
ScopedSessionObserver scoped_session_observer_;
base::WeakPtrFactory<PaletteTray> weak_factory_{this};
};
} // namespace ash
#endif // ASH_SYSTEM_PALETTE_PALETTE_TRAY_H_