1// Copyright 2014 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
5#ifndef ASH_WM_OVERVIEW_WINDOW_GRID_H_
6#define ASH_WM_OVERVIEW_WINDOW_GRID_H_
7
8#include <vector>
9
10#include "ash/wm/overview/window_selector.h"
11#include "base/macros.h"
12#include "base/memory/scoped_ptr.h"
13#include "ui/aura/window_observer.h"
14
15namespace aura {
16class Window;
17}
18
19namespace views {
20class Widget;
21}
22
23namespace ash {
24
25class WindowSelectorItem;
26
27// Represents a grid of windows in the Overview Mode in a particular root
28// window, and manages a selection widget that can be moved with the arrow keys.
29// The idea behind the movement strategy is that it should be possible to access
30// any window pressing a given arrow key repeatedly.
31// +-------+  +-------+  +-------+
32// |   0   |  |   1   |  |   2   |
33// +-------+  +-------+  +-------+
34// +-------+  +-------+  +-------+
35// |   3   |  |   4   |  |   5   |
36// +-------+  +-------+  +-------+
37// +-------+
38// |   6   |
39// +-------+
40// Example sequences:
41//  - Going right to left
42//    0, 1, 2, 3, 4, 5, 6
43//  - Going "top" to "bottom"
44//    0, 3, 6, 1, 4, 2, 5
45// The selector is switched to the next window grid (if available) or wrapped if
46// it reaches the end of its movement sequence.
47class ASH_EXPORT WindowGrid : public aura::WindowObserver {
48 public:
49  WindowGrid(aura::Window* root_window,
50             const std::vector<aura::Window*>& window_list,
51             WindowSelector* window_selector);
52  virtual ~WindowGrid();
53
54  // Prepares the windows in this grid for overview. This will restore all
55  // minimized windows and ensure they are visible.
56  void PrepareForOverview();
57
58  // Positions all the windows in the grid.
59  void PositionWindows(bool animate);
60
61  // Updates |selected_index_| according to the specified |direction| and calls
62  // MoveSelectionWidget(). Returns |true| if the new selection index is out of
63  // this window grid bounds.
64  bool Move(WindowSelector::Direction direction, bool animate);
65
66  // Returns the target selected window, or NULL if there is none selected.
67  WindowSelectorItem* SelectedWindow() const;
68
69  // Returns true if a window is contained in any of the WindowSelectorItems
70  // this grid owns.
71  bool Contains(const aura::Window* window) const;
72
73  // Dims the items whose titles do not contain |pattern| and prevents their
74  // selection. The pattern has its accents removed and is converted to
75  // lowercase in a l10n sensitive context.
76  // If |pattern| is empty, no item is dimmed.
77  void FilterItems(const base::string16& pattern);
78
79  // Returns true if the grid has no more windows.
80  bool empty() const { return window_list_.empty(); }
81
82  // Returns how many window selector items are in the grid.
83  size_t size() const { return window_list_.size(); }
84
85  // Returns true if the selection widget is active.
86  bool is_selecting() const { return selection_widget_ != NULL; }
87
88  // Returns the root window in which the grid displays the windows.
89  const aura::Window* root_window() const { return root_window_; }
90
91  const std::vector<WindowSelectorItem*>& window_list() const {
92    return window_list_.get();
93  }
94
95  // aura::WindowObserver:
96  virtual void OnWindowDestroying(aura::Window* window) OVERRIDE;
97  // TODO(flackr): Handle window bounds changed in WindowSelectorItem.
98  virtual void OnWindowBoundsChanged(aura::Window* window,
99                                     const gfx::Rect& old_bounds,
100                                     const gfx::Rect& new_bounds) OVERRIDE;
101
102 private:
103  friend class WindowSelectorTest;
104
105  // Internal function to initialize the selection widget.
106  void InitSelectionWidget(WindowSelector::Direction direction);
107
108  // Moves the selection widget to the specified |direction|.
109  void MoveSelectionWidget(WindowSelector::Direction direction,
110                           bool recreate_selection_widget,
111                           bool out_of_bounds,
112                           bool animate);
113
114  // Moves the selection widget to the targeted window.
115  void MoveSelectionWidgetToTarget(bool animate);
116
117  // Returns the target bounds of the currently selected item.
118  const gfx::Rect GetSelectionBounds() const;
119
120  // Root window the grid is in.
121  aura::Window* root_window_;
122
123  // Pointer to the window selector that spawned this grid.
124  WindowSelector* window_selector_;
125
126  // Vector containing all the windows in this grid.
127  ScopedVector<WindowSelectorItem> window_list_;
128
129  // Vector containing the observed windows.
130  std::set<aura::Window*> observed_windows_;
131
132  // Widget that indicates to the user which is the selected window.
133  scoped_ptr<views::Widget> selection_widget_;
134
135  // Current selected window position.
136  size_t selected_index_;
137
138  // Number of columns in the grid.
139  size_t num_columns_;
140
141  DISALLOW_COPY_AND_ASSIGN(WindowGrid);
142};
143
144}  // namespace ash
145
146#endif  // ASH_WM_OVERVIEW_WINDOW_GRID_H_
147