146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// found in the LICENSE file.
446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#ifndef ASH_WM_OVERVIEW_WINDOW_GRID_H_
646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#define ASH_WM_OVERVIEW_WINDOW_GRID_H_
746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include <vector>
946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
1046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ash/wm/overview/window_selector.h"
1146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/macros.h"
1246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
1346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ui/aura/window_observer.h"
1446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
1546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)namespace aura {
1646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)class Window;
1746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
1846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
1946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)namespace views {
2046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)class Widget;
2146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
2246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
2346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)namespace ash {
2446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
2546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)class WindowSelectorItem;
2646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
2746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Represents a grid of windows in the Overview Mode in a particular root
2846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// window, and manages a selection widget that can be moved with the arrow keys.
2946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// The idea behind the movement strategy is that it should be possible to access
3046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// any window pressing a given arrow key repeatedly.
3146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// +-------+  +-------+  +-------+
3246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// |   0   |  |   1   |  |   2   |
3346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// +-------+  +-------+  +-------+
3446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// +-------+  +-------+  +-------+
3546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// |   3   |  |   4   |  |   5   |
3646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// +-------+  +-------+  +-------+
3746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// +-------+
3846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// |   6   |
3946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// +-------+
4046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Example sequences:
4146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)//  - Going right to left
4246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)//    0, 1, 2, 3, 4, 5, 6
4346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)//  - Going "top" to "bottom"
4446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)//    0, 3, 6, 1, 4, 2, 5
4546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// The selector is switched to the next window grid (if available) or wrapped if
4646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// it reaches the end of its movement sequence.
4746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)class ASH_EXPORT WindowGrid : public aura::WindowObserver {
4846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) public:
4946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  WindowGrid(aura::Window* root_window,
5046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)             const std::vector<aura::Window*>& window_list,
5146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)             WindowSelector* window_selector);
5246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual ~WindowGrid();
5346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
5408fd22434aed8d58d4e04bbbc0df2a942440bcc5Bo Liu  // Prepares the windows in this grid for overview. This will restore all
5508fd22434aed8d58d4e04bbbc0df2a942440bcc5Bo Liu  // minimized windows and ensure they are visible.
5608fd22434aed8d58d4e04bbbc0df2a942440bcc5Bo Liu  void PrepareForOverview();
5708fd22434aed8d58d4e04bbbc0df2a942440bcc5Bo Liu
5846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Positions all the windows in the grid.
5946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void PositionWindows(bool animate);
6046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
6146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Updates |selected_index_| according to the specified |direction| and calls
6246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // MoveSelectionWidget(). Returns |true| if the new selection index is out of
6346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // this window grid bounds.
6446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  bool Move(WindowSelector::Direction direction);
6546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
6646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Returns the target selected window, or NULL if there is none selected.
6746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  WindowSelectorItem* SelectedWindow() const;
6846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
6946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Returns true if a window is contained in any of the WindowSelectorItems
7046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // this grid owns.
7146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  bool Contains(const aura::Window* window) const;
7246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
7346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Returns true if the grid has no more windows.
7446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  bool empty() const { return window_list_.empty(); }
7546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
7646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Returns how many window selector items are in the grid.
7746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  size_t size() const { return window_list_.size(); }
7846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
7946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Returns true if the selection widget is active.
8046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  bool is_selecting() const { return selection_widget_ != NULL; }
8146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
8246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Returns the root window in which the grid displays the windows.
8346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  const aura::Window* root_window() const { return root_window_; }
8446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
8546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  const std::vector<WindowSelectorItem*>& window_list() const {
8646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return window_list_.get();
8746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
8846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
8946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // aura::WindowObserver:
9046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual void OnWindowDestroying(aura::Window* window) OVERRIDE;
9146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // TODO(nsatragno): Handle window bounds changed in WindowSelectorItem.
9246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual void OnWindowBoundsChanged(aura::Window* window,
9346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                     const gfx::Rect& old_bounds,
9446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                     const gfx::Rect& new_bounds) OVERRIDE;
9546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
9646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) private:
9746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  friend class WindowSelectorTest;
9846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
9946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Internal function to initialize the selection widget.
10046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void InitSelectionWidget(WindowSelector::Direction direction);
10146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
10246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Moves the selection widget to the specified |direction|.
10346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void MoveSelectionWidget(WindowSelector::Direction direction,
10446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                           bool recreate_selection_widget,
10546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                           bool out_of_bounds);
10646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
10746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Moves the selection widget to the targeted window.
10846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void MoveSelectionWidgetToTarget(bool animate);
10946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
11046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Returns the target bounds of the currently selected item.
11146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  const gfx::Rect GetSelectionBounds() const;
11246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
11346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Root window the grid is in.
11446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  aura::Window* root_window_;
11546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
11646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Pointer to the window selector that spawned this grid.
11746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  WindowSelector* window_selector_;
11846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
11946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Vector containing all the windows in this grid.
12046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ScopedVector<WindowSelectorItem> window_list_;
12146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
12246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Vector containing the observed windows.
12346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  std::set<aura::Window*> observed_windows_;
12446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
12546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Widget that indicates to the user which is the selected window.
12646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<views::Widget> selection_widget_;
12746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
12846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Current selected window position.
12946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  size_t selected_index_;
13046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
13146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Number of columns in the grid.
13246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  size_t num_columns_;
13346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
13446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(WindowGrid);
13546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)};
13646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
13746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}  // namespace ash
13846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
13946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#endif  // ASH_WM_OVERVIEW_WINDOW_GRID_H_
140