split_view_divider.h 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. // Copyright 2017 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef ASH_WM_SPLITVIEW_SPLIT_VIEW_DIVIDER_H_
  5. #define ASH_WM_SPLITVIEW_SPLIT_VIEW_DIVIDER_H_
  6. #include <memory>
  7. #include "ash/ash_export.h"
  8. #include "base/scoped_multi_source_observation.h"
  9. #include "ui/aura/window.h"
  10. #include "ui/aura/window_observer.h"
  11. #include "ui/display/display.h"
  12. #include "ui/gfx/geometry/point.h"
  13. #include "ui/gfx/geometry/rect.h"
  14. #include "ui/gfx/geometry/size.h"
  15. #include "ui/wm/core/transient_window_observer.h"
  16. #include "ui/wm/public/activation_change_observer.h"
  17. namespace views {
  18. class View;
  19. class Widget;
  20. } // namespace views
  21. namespace aura {
  22. class ScopedWindowTargeter;
  23. } // namespace aura
  24. namespace ash {
  25. class SplitViewController;
  26. // Split view divider. It passes the mouse/gesture events to SplitViewController
  27. // to resize the left and right windows accordingly. The divider widget should
  28. // always placed above its observed windows to be able to receive events.
  29. class ASH_EXPORT SplitViewDivider : public aura::WindowObserver,
  30. public ::wm::ActivationChangeObserver,
  31. public ::wm::TransientWindowObserver {
  32. public:
  33. // The distance to the divider edge in which a touch gesture will be
  34. // considered as a valid event on the divider.
  35. static constexpr int kDividerEdgeInsetForTouch = 8;
  36. explicit SplitViewDivider(SplitViewController* controller);
  37. SplitViewDivider(const SplitViewDivider&) = delete;
  38. SplitViewDivider& operator=(const SplitViewDivider&) = delete;
  39. ~SplitViewDivider() override;
  40. // static version of GetDividerBoundsInScreen(bool is_dragging) function.
  41. static gfx::Rect GetDividerBoundsInScreen(
  42. const gfx::Rect& work_area_bounds_in_screen,
  43. bool landscape,
  44. int divider_position,
  45. bool is_dragging);
  46. // Do the divider spawning animation that adds a finishing touch to the
  47. // snapping animation of a window.
  48. void DoSpawningAnimation(int spawn_position);
  49. // Updates |divider_widget_|'s bounds.
  50. void UpdateDividerBounds();
  51. // Calculates the divider's expected bounds according to the divider's
  52. // position.
  53. gfx::Rect GetDividerBoundsInScreen(bool is_dragging);
  54. void SetAlwaysOnTop(bool on_top);
  55. // Set adjustability of the divider bar. Unadjustable divider does not receive
  56. // event and the divider bar view is not visible. When the divider is moved
  57. // for the virtual keyboard, the divider will be set unadjustable.
  58. void SetAdjustable(bool adjustable);
  59. // Get the adjustability of the divider bar.
  60. bool IsAdjustable() const;
  61. void AddObservedWindow(aura::Window* window);
  62. void RemoveObservedWindow(aura::Window* window);
  63. // Called when a window tab(s) are being dragged around the workspace. The
  64. // divider should be placed beneath the dragged window during dragging.
  65. void OnWindowDragStarted();
  66. void OnWindowDragEnded();
  67. // aura::WindowObserver:
  68. void OnWindowDestroying(aura::Window* window) override;
  69. // wm::ActivationChangeObserver:
  70. void OnWindowActivated(ActivationReason reason,
  71. aura::Window* gained_active,
  72. aura::Window* lost_active) override;
  73. void OnWindowBoundsChanged(aura::Window* window,
  74. const gfx::Rect& old_bounds,
  75. const gfx::Rect& new_bounds,
  76. ui::PropertyChangeReason reason) override;
  77. // ::wm::TransientWindowObserver:
  78. void OnTransientChildAdded(aura::Window* window,
  79. aura::Window* transient) override;
  80. void OnTransientChildRemoved(aura::Window* window,
  81. aura::Window* transient) override;
  82. // Checks if the `window` is observed.
  83. bool IsWindowObserved(const aura::Window* window) const;
  84. views::Widget* divider_widget() { return divider_widget_; }
  85. private:
  86. void CreateDividerWidget(SplitViewController* controller);
  87. void StartObservingTransientChild(aura::Window* transient);
  88. void StopObservingTransientChild(aura::Window* transient);
  89. SplitViewController* controller_;
  90. // The window targeter that is installed on the always on top container window
  91. // when the split view mode is active. It deletes itself when the split view
  92. // mode is ended. Upon destruction, it restores the previous window targeter
  93. // (if any) on the always on top container window.
  94. std::unique_ptr<aura::ScopedWindowTargeter> split_view_window_targeter_;
  95. // Split view divider widget. It's a black bar stretching from one edge of the
  96. // screen to the other, containing a small white drag bar in the middle. As
  97. // the user presses on it and drag it to left or right, the left and right
  98. // window will be resized accordingly.
  99. views::Widget* divider_widget_ = nullptr;
  100. // If true there is a window whose tabs are currently being dragged around.
  101. bool is_dragging_window_ = false;
  102. // Tracks observed windows.
  103. aura::Window::Windows observed_windows_;
  104. // The content view of the divider.
  105. views::View* divider_view_ = nullptr;
  106. // Tracks observed transient windows.
  107. base::ScopedMultiSourceObservation<aura::Window, aura::WindowObserver>
  108. transient_windows_observations_{this};
  109. };
  110. } // namespace ash
  111. #endif // ASH_WM_SPLITVIEW_SPLIT_VIEW_DIVIDER_H_