| // Copyright 2020 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef ASH_DISPLAY_DISPLAY_ALIGNMENT_CONTROLLER_H_ |
| #define ASH_DISPLAY_DISPLAY_ALIGNMENT_CONTROLLER_H_ |
| |
| #include <memory> |
| |
| #include "ash/ash_export.h" |
| #include "ash/display/window_tree_host_manager.h" |
| #include "ash/public/cpp/session/session_observer.h" |
| #include "base/containers/flat_map.h" |
| #include "ui/events/event_handler.h" |
| #include "ui/gfx/geometry/vector2d.h" |
| |
| namespace base { |
| class OneShotTimer; |
| } // namespace base |
| |
| namespace ash { |
| |
| class DisplayAlignmentIndicator; |
| |
| // DisplayAlignmentController is responsible for creating new |
| // DisplayAlignmentIndicators when the activation criteria is met. |
| // TODO(1091497): Consider combining DisplayHighlightController and |
| // DisplayAlignmentController. |
| class ASH_EXPORT DisplayAlignmentController |
| : public ui::EventHandler, |
| public WindowTreeHostManager::Observer, |
| public SessionObserver { |
| public: |
| enum class DisplayAlignmentState { |
| // No indicators shown and mouse is not on edge |
| kIdle, |
| |
| // Mouse is currently on one of the edges. |
| kOnEdge, |
| |
| // The indicators are visible. |
| kIndicatorsVisible, |
| |
| // A display is being dragged around in display layouts. Preview indicators |
| // are being updated and shown. |
| kLayoutPreview, |
| |
| // Screen is locked or there is only one display. |
| kDisabled, |
| }; |
| |
| DisplayAlignmentController(); |
| DisplayAlignmentController(const DisplayAlignmentController&) = delete; |
| DisplayAlignmentController& operator=(const DisplayAlignmentController&) = |
| delete; |
| ~DisplayAlignmentController() override; |
| |
| // WindowTreeHostManager::Observer: |
| void OnDisplayConfigurationChanged() override; |
| void OnDisplaysInitialized() override; |
| |
| // ui::EventHandler: |
| void OnMouseEvent(ui::MouseEvent* event) override; |
| |
| // SessionObserver: |
| void OnLockStateChanged(bool locked) override; |
| |
| // Update positions of display alignment preview highlights. Display being |
| // dragged is specified by |display_id|. |preview_indicators_| is |
| // populated with indicators from this display and its neighbors as |
| // it is not possible for |display_id| to change mid-drag. |
| void DisplayDragged(int64_t display_id, int32_t delta_x, int32_t delta_y); |
| |
| void SetTimerForTesting(std::unique_ptr<base::OneShotTimer> timer); |
| |
| const std::vector<std::unique_ptr<DisplayAlignmentIndicator>>& |
| GetActiveIndicatorsForTesting(); |
| |
| int64_t GetDraggedDisplayIdForTesting() const; |
| |
| private: |
| // Show all indicators on |src_display| and other indicators that shares |
| // an edge with |src_display|. Indicators on other displays are shown without |
| // pills. All indicators are created in this method and stored in |
| // |active_indicators_| to be destroyed in ResetState(). |
| void ShowIndicators(const display::Display& src_display); |
| |
| // Clears all indicators, containers, timer, and resets the state back to |
| // kIdle. |
| void ResetState(); |
| |
| // Used to transition to kDisable if required. Called whenever display |
| // configuration or lock state updates. |
| void RefreshState(); |
| |
| // Updates, shows/hides preview indicators according to changes reported by |
| // DisplayDragged(). |
| void ComputePreviewIndicators(); |
| |
| // Stores all DisplayAlignmentIndicators currently being shown. All indicators |
| // should either belong to or be a shared edge of display with |
| // |triggered_display_id_|. Indicators are created upon activation in |
| // ShowIndicators() or upon adjusting display layout in |
| // ComputePreviewIndicators() and cleared in ResetState(). |
| std::vector<std::unique_ptr<DisplayAlignmentIndicator>> active_indicators_; |
| |
| // Timer used for both edge trigger timeouts and hiding indicators. |
| std::unique_ptr<base::OneShotTimer> action_trigger_timer_; |
| |
| // Tracks current state of the controller. Mostly used to determine if action |
| // is taken in OnMouseEvent(); |
| DisplayAlignmentState current_state_ = DisplayAlignmentState::kIdle; |
| |
| // Tracks if the screen is locked to disable highlights. |
| bool is_locked_ = false; |
| |
| // Keeps track of the most recent display where the mouse hit the edge. |
| // Prevents activating indicators when user hits edges of different displays. |
| int64_t triggered_display_id_ = display::kInvalidDisplayId; |
| |
| // Number of times the mouse was on an edge of some display specified by |
| // |triggered_display_id_| recently. |
| int trigger_count_ = 0; |
| |
| // ID of display currently beign dragged. Cannot change from one valid |
| // ID to another as dropping the dragged display causes changes to display |
| // configuration, resetting this ID. |
| int64_t dragged_display_id_; |
| |
| // The difference between dragged display's actual position and preview |
| // position. Is an accumulation of |delta_x| and |delta_y| from |
| // DisplayDragged(). The offset is reset when a configuration event occurs. |
| gfx::Vector2d dragged_offset_; |
| }; |
| |
| } // namespace ash |
| |
| #endif // ASH_DISPLAY_DISPLAY_ALIGNMENT_CONTROLLER_H_ |