| // Copyright 2023 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_DESK_BUTTON_WIDGET_H_ |
| #define ASH_SHELF_DESK_BUTTON_WIDGET_H_ |
| |
| #include "ash/ash_export.h" |
| #include "ash/shelf/shelf_component.h" |
| #include "base/memory/raw_ptr.h" |
| #include "ui/views/widget/widget.h" |
| #include "ui/views/widget/widget_delegate.h" |
| |
| namespace ash { |
| |
| class DeskButtonContainer; |
| class DeskButtonWidget; |
| class Shelf; |
| enum class ShelfAlignment; |
| |
| // Delegate view for laying out the desk button UI. It does not use the default |
| // fill layout since the desk button UI has dynamic size, and the widget |
| // reserves the maximum possible space for the current shelf alignment and zero |
| // state. |
| class DeskButtonWidgetDelegateView : public views::WidgetDelegateView { |
| public: |
| DeskButtonWidgetDelegateView(); |
| DeskButtonWidgetDelegateView(const DeskButtonWidgetDelegateView&) = delete; |
| DeskButtonWidgetDelegateView& operator=(const DeskButtonWidgetDelegateView&) = |
| delete; |
| ~DeskButtonWidgetDelegateView() override; |
| |
| DeskButtonContainer* desk_button_container() const { |
| return desk_button_container_; |
| } |
| |
| // Initializes the view. Must be called before any meaningful UIs can be |
| // laid out. |
| void Init(DeskButtonWidget* desk_button_widget); |
| |
| // views::WidgetDelegateView: |
| void Layout(PassKey) override; |
| |
| // views::View: |
| bool AcceleratorPressed(const ui::Accelerator& accelerator) override; |
| |
| private: |
| raw_ptr<DeskButtonContainer> desk_button_container_ = nullptr; |
| raw_ptr<DeskButtonWidget> desk_button_widget_ = nullptr; |
| }; |
| |
| // The desk button provides an overview of existing desks and quick access to |
| // them. The button is only visible in clamshell mode and disappears when in |
| // overview. |
| class ASH_EXPORT DeskButtonWidget : public ShelfComponent, |
| public views::Widget { |
| public: |
| explicit DeskButtonWidget(Shelf* shelf); |
| DeskButtonWidget(const DeskButtonWidget&) = delete; |
| DeskButtonWidget& operator=(const DeskButtonWidget&) = delete; |
| ~DeskButtonWidget() override; |
| |
| // Returns the max length for the widget for the horizontal or vertical shelf. |
| static int GetMaxLength(bool horizontal_shelf); |
| |
| DeskButtonWidgetDelegateView* delegate_view() const { return delegate_view_; } |
| |
| Shelf* shelf() const { return shelf_; } |
| |
| // Indicates if the shelf should reserve some space for this widget. |
| bool ShouldReserveSpaceFromShelf() const; |
| |
| // Whether the desk button should currently be visible. |
| bool ShouldBeVisible() const; |
| |
| // Updates expanded state and values impacted by shelf alignment change. |
| void PrepareForAlignmentChange(); |
| |
| // ShelfComponent: |
| void CalculateTargetBounds() override; |
| gfx::Rect GetTargetBounds() const override; |
| void UpdateLayout(bool animate) override; |
| void UpdateTargetBoundsForGesture(int shelf_position) override; |
| |
| // Called when shelf layout manager detects a locale change. |
| void HandleLocaleChange(); |
| |
| // Initializes the widget, sets its contents view and basic properties. |
| void Initialize(aura::Window* container); |
| |
| DeskButtonContainer* GetDeskButtonContainer() const; |
| |
| // Returns true if this widget belongs to a horizontal shelf. |
| bool IsHorizontalShelf() const; |
| |
| void SetDefaultChildToFocus(views::View* default_child_to_focus); |
| |
| // Stores the current focused view for desk button widget. |
| void StoreDeskButtonFocus(); |
| |
| // Restores focus to the stored focused view of desk button widget if there is |
| // one. |
| void RestoreDeskButtonFocus(); |
| |
| // Depending on what child view has focus, either focus out of the desk |
| // button, or pass the focus to the next view. `reverse` indicates backward |
| // focusing, otherwise forward focusing. |
| void MaybeFocusOut(bool reverse); |
| |
| // Sets previous focus and next focus of desk button. |
| void InitializeAccessibleProperties(); |
| |
| private: |
| // views::Widget: |
| bool OnNativeWidgetActivationChanged(bool active) override; |
| |
| raw_ptr<DeskButtonWidgetDelegateView, DanglingUntriaged> delegate_view_ = |
| nullptr; |
| |
| gfx::Rect target_bounds_; |
| |
| raw_ptr<Shelf> const shelf_; |
| |
| // Default child view to focus when `OnNativeWidgetActivationChanged()` |
| // occurs. When it's not null, it should point to the desk button, the |
| // previous desk button, or the next desk button. |
| raw_ptr<views::View> default_child_to_focus_ = nullptr; |
| |
| // Stored focused view for the widget. This is used to restore the focus to |
| // the desk button when the desk bar is closed. When it's not null, it should |
| // point to the desk button, the previous desk button, or the next desk |
| // button. |
| raw_ptr<views::View> stored_focused_view_ = nullptr; |
| }; |
| |
| } // namespace ash |
| |
| #endif // ASH_SHELF_DESK_BUTTON_WIDGET_H_ |