1// Copyright (c) 2010 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_AEROPEEK_MANAGER_H_
6#define CHROME_BROWSER_AEROPEEK_MANAGER_H_
7#pragma once
8
9#include <windows.h>
10
11#include <list>
12
13#include "chrome/browser/tabs/tab_strip_model_observer.h"
14#include "ui/gfx/insets.h"
15
16namespace gfx {
17class Size;
18}
19class AeroPeekWindow;
20class SkBitmap;
21class TabContents;
22
23// A class which defines interfaces called from AeroPeekWindow.
24// This class is used for dispatching an event received by a thumbnail window
25// and for retrieving information from Chrome.
26// An AeroPeek window receives the following events:
27// * A user clicks an AeroPeek thumbnail.
28//   We need to select a tab associated with this window.
29// * A user closes an AeroPeek thumbnail.
30//   We need to close a tab associated with this window.
31// * A user clicks a toolbar button in an AeroPeek window.
32//   We may need to dispatch this button event to a tab associated with this
33//   thumbnail window.
34//   <http://msdn.microsoft.com/en-us/library/dd378460(VS.85).aspx#thumbbars>.
35// Also, it needs the following information of the browser:
36// * The bitmap of a tab associated with this window.
37//   This bitmap is used for creating thumbnail and preview images.
38// * The rectangle of a browser frame.
39//   This rectangle is used for pasting the above bitmap to the right position
40//   and for marking the tab-content area as opaque.
41// We assume these functions are called only from a UI thread (i.e.
42// Chrome_BrowserMain).
43class AeroPeekWindowDelegate {
44 public:
45  virtual void ActivateTab(int tab_id) = 0;
46  virtual void CloseTab(int tab_id) = 0;
47  virtual void GetContentInsets(gfx::Insets* insets) = 0;
48  virtual bool GetTabThumbnail(int tab_id, SkBitmap* thumbnail) = 0;
49  virtual bool GetTabPreview(int tab_id, SkBitmap* preview) = 0;
50
51 protected:
52  virtual ~AeroPeekWindowDelegate() {}
53};
54
55// A class that implements AeroPeek of Windows 7:
56// <http://msdn.microsoft.com/en-us/library/dd378460(VS.85).aspx#thumbnails>.
57// Windows 7 can dispay a thumbnail image of each tab to its taskbar so that
58// a user can preview the contents of a tab (AeroPeek), choose a tab, close
59// a tab, etc.
60// This class implements the TabStripModelObserver interface to receive the
61// following events sent from TabStripModel and dispatch them to Windows:
62// * A tab is added.
63//   This class adds a thumbnail window for this tab to the thumbnail list
64//   of Windows.
65// * A tab is being closed.
66//   This class deletes the thumbnail window associated with this tab from the
67//   thumbnail list of Windows.
68// * A tab has been updated.
69//   This class updates the image of the thumbnail window associated with this
70//   tab.
71// Also, this class receives events sent from Windows via thumbnail windows to
72// TabStripModel:
73// * A thumbnail window is closed.
74//   Ask TabStrip to close the tab associated with this thumbnail window.
75// * A thumbnail window is selected.
76//   Ask TabStrip to activate the tab associated with this thumbnail window.
77//
78// The simplest usage of this class is:
79// 1. Create an instance of TabThumbnailManager.
80// 2. Add this instance to the observer list of a TabStrip object.
81//
82//      scoped_ptr<TabThumbnailManager> manager;
83//      manager.reset(new TabThumbnailManager(
84//          frame_->GetWindow()->GetNativeWindow(),
85//          border_left,
86//          border_top,
87//          toolbar_top));
88//      g_browser->tabstrip_model()->AddObserver(manager);
89//
90// 3. Remove this instance from the observer list of the TabStrip object when
91//    we don't need it.
92//
93//      g_browser->tabstrip_model()->RemoveObserver(manager);
94//
95class AeroPeekManager : public TabStripModelObserver,
96                        public AeroPeekWindowDelegate {
97 public:
98  explicit AeroPeekManager(HWND application_window);
99  virtual ~AeroPeekManager();
100
101  // Sets the margins of the "user-perceived content area".
102  // (See comments of |content_insets_|).
103  void SetContentInsets(const gfx::Insets& insets);
104
105  // Returns whether or not we should enable Tab Thumbnailing and Aero Peek
106  // of Windows 7.
107  static bool Enabled();
108
109  // Overridden from TabStripModelObserver:
110  virtual void TabInsertedAt(TabContentsWrapper* contents,
111                             int index,
112                             bool foreground);
113  virtual void TabDetachedAt(TabContentsWrapper* contents, int index);
114  virtual void TabSelectedAt(TabContentsWrapper* old_contents,
115                             TabContentsWrapper* new_contents,
116                             int index,
117                             bool user_gesture);
118  virtual void TabMoved(TabContentsWrapper* contents,
119                        int from_index,
120                        int to_index,
121                        bool pinned_state_changed);
122  virtual void TabChangedAt(TabContentsWrapper* contents,
123                            int index,
124                            TabChangeType change_type);
125  virtual void TabReplacedAt(TabStripModel* tab_strip_model,
126                             TabContentsWrapper* old_contents,
127                             TabContentsWrapper* new_contents,
128                             int index);
129
130  // Overriden from TabThumbnailWindowDelegate:
131  virtual void CloseTab(int tab_id);
132  virtual void ActivateTab(int tab_id);
133  virtual void GetContentInsets(gfx::Insets* insets);
134  virtual bool GetTabThumbnail(int tab_id, SkBitmap* thumbnail);
135  virtual bool GetTabPreview(int tab_id, SkBitmap* preview);
136
137 private:
138  // Deletes the TabThumbnailWindow object associated with the specified
139  // Tab ID.
140  void DeleteAeroPeekWindow(int tab_id);
141
142  // If there is an AeroPeekWindow associated with |tab| it is removed and
143  // deleted.
144  void DeleteAeroPeekWindowForTab(TabContentsWrapper* tab);
145
146  // Retrieves the AeroPeekWindow object associated with the specified
147  // Tab ID.
148  AeroPeekWindow* GetAeroPeekWindow(int tab_id) const;
149
150  // If an AeroPeekWindow hasn't been created for |tab| yet, one is created.
151  // |foreground| is true if the tab is selected.
152  void CreateAeroPeekWindowIfNecessary(TabContentsWrapper* tab,
153                                       bool foreground);
154
155  // Returns a rectangle that fits into the destination rectangle and keeps
156  // the pixel-aspect ratio of the source one.
157  // (This function currently uses the longer-fit algorithm as IE8 does.)
158  void GetOutputBitmapSize(const gfx::Size& destination,
159                           const gfx::Size& source,
160                           gfx::Size* output) const;
161
162  // Returns the TabContents object associated with the specified Tab ID only
163  // if it is alive.
164  // Since Windows cannot send AeroPeek events directly to Chrome windows, we
165  // use a place-holder window to receive AeroPeek events. So, when Windows
166  // sends an AeroPeek event, the corresponding tab (and TabContents) may have
167  // been deleted by Chrome. To prevent us from accessing deleted TabContents,
168  // we need to check if the tab is still alive.
169  TabContents* GetTabContents(int tab_id) const;
170
171  // Returns the tab ID from the specified TabContents.
172  int GetTabID(TabContents* contents) const;
173
174 private:
175  // The parent window of the place-holder windows used by AeroPeek.
176  // In the case of Chrome, this window becomes a browser frame.
177  HWND application_window_;
178
179  // The list of the place-holder windows used by AeroPeek.
180  std::list<AeroPeekWindow*> tab_list_;
181
182  // The left and top borders of the frame window.
183  // When we create a preview bitmap, we use these values for preventing from
184  // over-writing the area of the browser frame.
185  int border_left_;
186  int border_top_;
187
188  // The top position of the toolbar.
189  // This value is used for setting the alpha values of the frame area so a
190  // preview image can use transparent colors only in the frame area.
191  int toolbar_top_;
192
193  // The margins of the "user-perceived content area".
194  // This value is used for pasting a tab image onto this "user-perceived
195  // content area" when creating a preview image.
196  gfx::Insets content_insets_;
197};
198
199#endif  // CHROME_BROWSER_AEROPEEK_MANAGER_H_
200