summaryrefslogtreecommitdiffstats
path: root/chrome/browser/aeropeek_manager.h
blob: 26ae0543b6334b8a8db81838ebb7d324ef903638 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
// Copyright (c) 2011 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 CHROME_BROWSER_AEROPEEK_MANAGER_H_
#define CHROME_BROWSER_AEROPEEK_MANAGER_H_
#pragma once

#include <windows.h>

#include <list>

#include "chrome/browser/tabs/tab_strip_model_observer.h"
#include "ui/gfx/insets.h"

class AeroPeekWindow;
class SkBitmap;
class TabContentsWrapper;

namespace content {
class WebContents;
}

namespace gfx {
class Size;
}

// A class which defines interfaces called from AeroPeekWindow.
// This class is used for dispatching an event received by a thumbnail window
// and for retrieving information from Chrome.
// An AeroPeek window receives the following events:
// * A user clicks an AeroPeek thumbnail.
//   We need to select a tab associated with this window.
// * A user closes an AeroPeek thumbnail.
//   We need to close a tab associated with this window.
// * A user clicks a toolbar button in an AeroPeek window.
//   We may need to dispatch this button event to a tab associated with this
//   thumbnail window.
//   <http://msdn.microsoft.com/en-us/library/dd378460(VS.85).aspx#thumbbars>.
// Also, it needs the following information of the browser:
// * The bitmap of a tab associated with this window.
//   This bitmap is used for creating thumbnail and preview images.
// * The rectangle of a browser frame.
//   This rectangle is used for pasting the above bitmap to the right position
//   and for marking the tab-content area as opaque.
// We assume these functions are called only from a UI thread (i.e.
// Chrome_BrowserMain).
class AeroPeekWindowDelegate {
 public:
  virtual void ActivateTab(int tab_id) = 0;
  virtual void CloseTab(int tab_id) = 0;
  virtual void GetContentInsets(gfx::Insets* insets) = 0;
  virtual bool GetTabThumbnail(int tab_id, SkBitmap* thumbnail) = 0;
  virtual bool GetTabPreview(int tab_id, SkBitmap* preview) = 0;

 protected:
  virtual ~AeroPeekWindowDelegate() {}
};

// A class that implements AeroPeek of Windows 7:
// <http://msdn.microsoft.com/en-us/library/dd378460(VS.85).aspx#thumbnails>.
// Windows 7 can dispay a thumbnail image of each tab to its taskbar so that
// a user can preview the contents of a tab (AeroPeek), choose a tab, close
// a tab, etc.
// This class implements the TabStripModelObserver interface to receive the
// following events sent from TabStripModel and dispatch them to Windows:
// * A tab is added.
//   This class adds a thumbnail window for this tab to the thumbnail list
//   of Windows.
// * A tab is being closed.
//   This class deletes the thumbnail window associated with this tab from the
//   thumbnail list of Windows.
// * A tab has been updated.
//   This class updates the image of the thumbnail window associated with this
//   tab.
// Also, this class receives events sent from Windows via thumbnail windows to
// TabStripModel:
// * A thumbnail window is closed.
//   Ask TabStrip to close the tab associated with this thumbnail window.
// * A thumbnail window is selected.
//   Ask TabStrip to activate the tab associated with this thumbnail window.
//
// The simplest usage of this class is:
// 1. Create an instance of TabThumbnailManager.
// 2. Add this instance to the observer list of a TabStrip object.
//
//      scoped_ptr<TabThumbnailManager> manager;
//      manager.reset(new TabThumbnailManager(
//          frame_->GetWindow()->GetNativeWindow(),
//          border_left,
//          border_top,
//          toolbar_top));
//      g_browser->tabstrip_model()->AddObserver(manager);
//
// 3. Remove this instance from the observer list of the TabStrip object when
//    we don't need it.
//
//      g_browser->tabstrip_model()->RemoveObserver(manager);
//
class AeroPeekManager : public TabStripModelObserver,
                        public AeroPeekWindowDelegate {
 public:
  explicit AeroPeekManager(HWND application_window);
  virtual ~AeroPeekManager();

  // Sets the margins of the "user-perceived content area".
  // (See comments of |content_insets_|).
  void SetContentInsets(const gfx::Insets& insets);

  // Returns whether or not we should enable Tab Thumbnailing and Aero Peek
  // of Windows 7.
  static bool Enabled();

  // Overridden from TabStripModelObserver:
  virtual void TabInsertedAt(TabContentsWrapper* contents,
                             int index,
                             bool foreground);
  virtual void TabDetachedAt(TabContentsWrapper* contents, int index);
  virtual void ActiveTabChanged(TabContentsWrapper* old_contents,
                                TabContentsWrapper* new_contents,
                                int index,
                                bool user_gesture);
  virtual void TabMoved(TabContentsWrapper* contents,
                        int from_index,
                        int to_index,
                        bool pinned_state_changed);
  virtual void TabChangedAt(TabContentsWrapper* contents,
                            int index,
                            TabChangeType change_type);
  virtual void TabReplacedAt(TabStripModel* tab_strip_model,
                             TabContentsWrapper* old_contents,
                             TabContentsWrapper* new_contents,
                             int index);

  // Overriden from TabThumbnailWindowDelegate:
  virtual void CloseTab(int tab_id);
  virtual void ActivateTab(int tab_id);
  virtual void GetContentInsets(gfx::Insets* insets);
  virtual bool GetTabThumbnail(int tab_id, SkBitmap* thumbnail);
  virtual bool GetTabPreview(int tab_id, SkBitmap* preview);

 private:
  // Deletes the TabThumbnailWindow object associated with the specified
  // Tab ID.
  void DeleteAeroPeekWindow(int tab_id);

  // If there is an AeroPeekWindow associated with |tab| it is removed and
  // deleted.
  void DeleteAeroPeekWindowForTab(TabContentsWrapper* tab);

  // Retrieves the AeroPeekWindow object associated with the specified
  // Tab ID.
  AeroPeekWindow* GetAeroPeekWindow(int tab_id) const;

  // If an AeroPeekWindow hasn't been created for |tab| yet, one is created.
  // |foreground| is true if the tab is selected.
  void CreateAeroPeekWindowIfNecessary(TabContentsWrapper* tab,
                                       bool foreground);

  // Returns a rectangle that fits into the destination rectangle and keeps
  // the pixel-aspect ratio of the source one.
  // (This function currently uses the longer-fit algorithm as IE8 does.)
  void GetOutputBitmapSize(const gfx::Size& destination,
                           const gfx::Size& source,
                           gfx::Size* output) const;

  // Returns the WebContents object associated with the specified Tab ID only
  // if it is alive.
  // Since Windows cannot send AeroPeek events directly to Chrome windows, we
  // use a place-holder window to receive AeroPeek events. So, when Windows
  // sends an AeroPeek event, the corresponding tab (and TabContents) may have
  // been deleted by Chrome. To prevent us from accessing deleted TabContents,
  // we need to check if the tab is still alive.
  content::WebContents* GetWebContents(int tab_id) const;

  // Returns the tab ID from the specified TabContentsWrapper.
  int GetTabID(TabContentsWrapper* contents) const;

 private:
  // The parent window of the place-holder windows used by AeroPeek.
  // In the case of Chrome, this window becomes a browser frame.
  HWND application_window_;

  // The list of the place-holder windows used by AeroPeek.
  std::list<AeroPeekWindow*> tab_list_;

  // The left and top borders of the frame window.
  // When we create a preview bitmap, we use these values for preventing from
  // over-writing the area of the browser frame.
  int border_left_;
  int border_top_;

  // The top position of the toolbar.
  // This value is used for setting the alpha values of the frame area so a
  // preview image can use transparent colors only in the frame area.
  int toolbar_top_;

  // The margins of the "user-perceived content area".
  // This value is used for pasting a tab image onto this "user-perceived
  // content area" when creating a preview image.
  gfx::Insets content_insets_;
};

#endif  // CHROME_BROWSER_AEROPEEK_MANAGER_H_