1// Copyright (c) 2012 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 CHROME_BROWSER_UI_PANELS_STACKED_PANEL_COLLECTION_H_
6#define CHROME_BROWSER_UI_PANELS_STACKED_PANEL_COLLECTION_H_
7
8#include <list>
9#include <vector>
10#include "base/basictypes.h"
11#include "chrome/browser/ui/panels/native_panel_stack_window.h"
12#include "chrome/browser/ui/panels/panel_collection.h"
13#include "chrome/browser/ui/panels/panel_constants.h"
14#include "ui/gfx/rect.h"
15
16class PanelManager;
17namespace gfx {
18class Vector2d;
19}
20
21class StackedPanelCollection : public PanelCollection,
22                               public NativePanelStackWindowDelegate {
23 public:
24  typedef std::list<Panel*> Panels;
25
26  explicit StackedPanelCollection(PanelManager* panel_manager);
27  virtual ~StackedPanelCollection();
28
29  // PanelCollection OVERRIDES:
30  virtual void OnDisplayChanged() OVERRIDE;
31  virtual void RefreshLayout() OVERRIDE;
32  virtual void AddPanel(Panel* panel,
33                        PositioningMask positioning_mask) OVERRIDE;
34  virtual void RemovePanel(Panel* panel, RemovalReason reason) OVERRIDE;
35  virtual void CloseAll() OVERRIDE;
36  virtual void ResizePanelWindow(
37      Panel* panel,
38      const gfx::Size& preferred_window_size) OVERRIDE;
39  virtual panel::Resizability GetPanelResizability(
40      const Panel* panel) const OVERRIDE;
41  virtual void OnPanelResizedByMouse(Panel* panel,
42                                     const gfx::Rect& new_bounds) OVERRIDE;
43  virtual void OnPanelAttentionStateChanged(Panel* panel) OVERRIDE;
44  virtual void OnPanelTitlebarClicked(Panel* panel,
45                                      panel::ClickModifier modifier) OVERRIDE;
46  virtual void ActivatePanel(Panel* panel) OVERRIDE;
47  virtual void MinimizePanel(Panel* panel) OVERRIDE;
48  virtual void RestorePanel(Panel* panel) OVERRIDE;
49  virtual void OnMinimizeButtonClicked(Panel* panel,
50                                       panel::ClickModifier modifier) OVERRIDE;
51  virtual void OnRestoreButtonClicked(Panel* panel,
52                                      panel::ClickModifier modifier) OVERRIDE;
53  virtual bool CanShowMinimizeButton(const Panel* panel) const OVERRIDE;
54  virtual bool CanShowRestoreButton(const Panel* panel) const OVERRIDE;
55  virtual bool IsPanelMinimized(const Panel* panel) const OVERRIDE;
56  virtual bool UsesAlwaysOnTopPanels() const OVERRIDE;
57  virtual void SavePanelPlacement(Panel* panel) OVERRIDE;
58  virtual void RestorePanelToSavedPlacement() OVERRIDE;
59  virtual void DiscardSavedPanelPlacement()  OVERRIDE;
60  virtual void UpdatePanelOnCollectionChange(Panel* panel) OVERRIDE;
61  virtual void OnPanelExpansionStateChanged(Panel* panel) OVERRIDE;
62  virtual void OnPanelActiveStateChanged(Panel* panel) OVERRIDE;
63  virtual gfx::Rect GetInitialPanelBounds(
64      const gfx::Rect& requested_bounds) const OVERRIDE;
65
66  Panel* GetPanelAbove(Panel* panel) const;
67  Panel* GetPanelBelow(Panel* panel) const;
68  bool HasPanel(Panel* panel) const;
69
70  void MoveAllDraggingPanelsInstantly(const gfx::Vector2d& delta_origin);
71
72  bool IsMinimized() const;
73  bool IsAnimatingPanelBounds(Panel* panel) const;
74
75  // Returns the maximum available space from the bottom of the stack. The
76  // maximum available space is defined as the distance between the bottom
77  // of the stack and the bottom of the working area, assuming that all inactive
78  // panels are collapsed.
79  int GetMaximiumAvailableBottomSpace() const;
80
81  int num_panels() const { return panels_.size(); }
82  const Panels& panels() const { return panels_; }
83  Panel* top_panel() const { return panels_.empty() ? NULL : panels_.front(); }
84  Panel* bottom_panel() const {
85    return panels_.empty() ? NULL : panels_.back();
86  }
87  Panel* most_recently_active_panel() const {
88    return most_recently_active_panels_.empty() ?
89        NULL : most_recently_active_panels_.front();
90  }
91
92 private:
93  struct PanelPlacement {
94    Panel* panel;
95    gfx::Point position;
96    // Used to remember the top panel, if different from |panel|, for use when
97    // restoring it. When there're only 2 panels in the stack and the bottom
98    // panel is being dragged out of the stack, both panels will be moved to
99    // the detached collection. We need to track the top panel in order to
100    // put it back to the same stack of the dragging panel.
101    Panel* top_panel;
102
103    PanelPlacement() : panel(NULL), top_panel(NULL) { }
104  };
105
106  // Overridden from PanelBoundsBatchUpdateObserver:
107  virtual base::string16 GetTitle() const OVERRIDE;
108  virtual gfx::Image GetIcon() const OVERRIDE;
109  virtual void PanelBoundsBatchUpdateCompleted() OVERRIDE;
110
111  // Returns the enclosing bounds that include all panels in the stack.
112  gfx::Rect GetEnclosingBounds() const;
113
114  // Returns the work area where the stack resides. If the stack spans across
115  // multiple displays, return the work area of the display that most closely
116  // intersects the stack.
117  gfx::Rect GetWorkArea() const;
118
119  // Refresh all panel layouts, with top panel poisitoned at |start_position|.
120  // All panels should have same width as |common_width|.
121  void RefreshLayoutWithTopPanelStartingAt(const gfx::Point& start_position,
122                                           int common_width);
123
124  // Tries to collapse panels in the least recently active order in order to get
125  // enough bottom space for |needed_space|. Returns the current available space
126  // so far if all panels that could be collapsed have been collapsed.
127  int MinimizePanelsForSpace(int needed_space);
128
129  // Returns the current available space above the top of the stack. The current
130  // available space is defined as the distance between the top of the working
131  // area and the top of the stack.
132  int GetCurrentAvailableTopSpace() const;
133
134  // Returns the current available space below the bottom of the stack. The
135  // current available space is defined as the distance between the bottom
136  // of the stack and the bottom of the working area.
137  int GetCurrentAvailableBottomSpace() const;
138
139  // Minimizes or restores all panels in the collection.
140  void MinimizeAll();
141  void RestoreAll(Panel* panel_clicked);
142
143  void UpdatePanelCornerStyle(Panel* panel);
144
145  NativePanelStackWindow* GetStackWindowForPanel(Panel* panel) const;
146
147  PanelManager* panel_manager_;
148
149  // Both stack window pointers are weak pointers and self owned. Once a stack
150  // window is created, it will only be destructed by calling Close when it is
151  // not longer needed as in RemovePanel and CloseAll.
152
153  // The main background window that encloses all panels in the stack when
154  // stacking is not occuring, or existing panels otherwise.
155  // This window provides:
156  // 1) the shadow around the the outer area of all panels.
157  // 2) the consolidated taskbar icon and the consolidated preview
158  //    (Windows only)
159  NativePanelStackWindow* primary_stack_window_;
160
161  // The additional background window that encloses those panels that are
162  // being added to the stack when the stacking is occuring. Since those panels
163  // have not been fully aligned with existing panels in the stack before the
164  // stacking ends, we put those panels in a separate background window that
165  // only provides the shadow around the outer area of those panels.
166  NativePanelStackWindow* secondary_stack_window_;
167
168  Panels panels_;  // The top panel is in the front of the list.
169
170  // Keeps track of the panels in their active order. The most recently active
171  // panel is in the front of the list.
172  Panels most_recently_active_panels_;
173
174  // Used to save the placement information for a panel.
175  PanelPlacement saved_panel_placement_;
176
177  bool minimizing_all_;  // True while minimizing all panels.
178
179  DISALLOW_COPY_AND_ASSIGN(StackedPanelCollection);
180};
181
182#endif  // CHROME_BROWSER_UI_PANELS_STACKED_PANEL_COLLECTION_H_
183