blob: aa9349dd8aa37d849848ec18d1b2d46d5112792f [file] [log] [blame]
// Copyright 2017 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_WM_SPLITSVIEW_SPLIT_VIEW_DIVIDER_H_
#define ASH_WM_SPLITSVIEW_SPLIT_VIEW_DIVIDER_H_
#include <memory>
#include "ash/ash_export.h"
#include "base/macros.h"
#include "ui/aura/window.h"
#include "ui/aura/window_observer.h"
#include "ui/display/display.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
#include "ui/wm/public/activation_change_observer.h"
namespace views {
class Widget;
} // namespace views
namespace aura {
class ScopedWindowTargeter;
} // namespace aura
namespace ash {
class SplitViewController;
enum class OrientationLockType;
// Split view divider. It passes the mouse/gesture events to SplitViewController
// to resize the left and right windows accordingly. The divider widget should
// always placed above its observed windows to be able to receive events.
class ASH_EXPORT SplitViewDivider : public aura::WindowObserver,
public ::wm::ActivationChangeObserver {
public:
SplitViewDivider(SplitViewController* controller, aura::Window* root_window);
~SplitViewDivider() override;
// Gets the size of the divider widget. The divider widget is enlarged during
// dragging. For now, it's a vertical rectangle.
static gfx::Size GetDividerSize(const gfx::Rect& work_area_bounds,
OrientationLockType screen_orientation,
bool is_dragging);
// static version of GetDividerBoundsInScreen(bool is_dragging) function.
static gfx::Rect GetDividerBoundsInScreen(
const gfx::Rect& work_area_bounds_in_screen,
OrientationLockType screen_orientation,
int divider_position,
bool is_dragging);
// Updates |divider_widget_|'s bounds.
void UpdateDividerBounds();
// Calculates the divider's expected bounds according to the divider's
// position.
gfx::Rect GetDividerBoundsInScreen(bool is_dragging);
void AddObservedWindow(aura::Window* window);
void RemoveObservedWindow(aura::Window* window);
// Called when a window tab(s) are being dragged around the workspace. The
// divider should be placed beneath the dragged window during dragging.
void OnWindowDragStarted(aura::Window* dragged_window);
void OnWindowDragEnded();
// aura::WindowObserver:
void OnWindowDestroying(aura::Window* window) override;
// wm::ActivationChangeObserver:
void OnWindowActivated(ActivationReason reason,
aura::Window* gained_active,
aura::Window* lost_active) override;
views::Widget* divider_widget() { return divider_widget_; }
private:
void CreateDividerWidget(aura::Window* root_window);
void SetAlwaysOnTop(bool on_top);
SplitViewController* controller_;
// The window targeter that is installed on the always on top container window
// when the split view mode is active. It deletes itself when the split view
// mode is ended. Upon destruction, it restores the previous window targeter
// (if any) on the always on top container window.
std::unique_ptr<aura::ScopedWindowTargeter> split_view_window_targeter_;
// Split view divider widget. It's a black bar stretching from one edge of the
// screen to the other, containing a small white drag bar in the middle. As
// the user presses on it and drag it to left or right, the left and right
// window will be resized accordingly.
views::Widget* divider_widget_ = nullptr;
// If true there is a window whose tabs are currently being dragged around.
bool is_dragging_window_ = false;
// Tracks observed windows.
aura::Window::Windows observed_windows_;
DISALLOW_COPY_AND_ASSIGN(SplitViewDivider);
};
} // namespace ash
#endif // ASH_WM_SPLITSVIEW_SPLIT_VIEW_DIVIDER_H_