| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/views/tabs/tab_overview_controller.h" | 5 #include "chrome/browser/views/tabs/tab_overview_controller.h" |
| 6 | 6 |
| 7 #include "chrome/browser/browser.h" | 7 #include "chrome/browser/browser.h" |
| 8 #include "chrome/browser/gtk/browser_window_gtk.h" | 8 #include "chrome/browser/gtk/browser_window_gtk.h" |
| 9 #include "chrome/browser/tab_contents/tab_contents.h" | 9 #include "chrome/browser/tab_contents/tab_contents.h" |
| 10 #include "chrome/browser/views/tabs/tab_overview_cell.h" | 10 #include "chrome/browser/views/tabs/tab_overview_cell.h" |
| 11 #include "chrome/browser/views/tabs/tab_overview_container.h" | 11 #include "chrome/browser/views/tabs/tab_overview_container.h" |
| 12 #include "chrome/browser/views/tabs/tab_overview_grid.h" | 12 #include "chrome/browser/views/tabs/tab_overview_grid.h" |
| 13 #include "chrome/browser/views/tabs/tab_overview_types.h" |
| 13 #include "chrome/browser/window_sizer.h" | 14 #include "chrome/browser/window_sizer.h" |
| 14 #include "views/fill_layout.h" | 15 #include "views/fill_layout.h" |
| 15 #include "views/widget/root_view.h" | 16 #include "views/widget/root_view.h" |
| 16 #include "views/widget/widget_gtk.h" | 17 #include "views/widget/widget_gtk.h" |
| 17 | 18 |
| 19 // Horizontal padding from the edge of the monitor to the overview. |
| 18 static int kMonitorPadding = 20; | 20 static int kMonitorPadding = 20; |
| 19 static int kInteriorPadding = 20; | 21 // Vertical padding between the overview and the windows along on the bottom. |
| 22 static int kWindowToOverviewPadding = 25; |
| 23 // Height of the windows along the bottom, as a percentage of the monitors |
| 24 // height. |
| 25 static float kWindowHeight = .30; |
| 26 // Height of the tab overview, as a percentage of monitors height. |
| 27 static float kOverviewHeight = .55; |
| 20 | 28 |
| 21 TabOverviewController::TabOverviewController( | 29 TabOverviewController::TabOverviewController( |
| 22 const gfx::Point& monitor_origin) | 30 const gfx::Point& monitor_origin) |
| 23 : host_(NULL), | 31 : host_(NULL), |
| 24 container_(NULL), | 32 container_(NULL), |
| 25 grid_(NULL), | 33 grid_(NULL), |
| 26 browser_(NULL), | 34 browser_(NULL), |
| 27 drag_browser_(NULL), | 35 drag_browser_(NULL), |
| 28 moved_offscreen_(false), | 36 moved_offscreen_(false), |
| 29 shown_(false) { | 37 shown_(false), |
| 38 horizontal_center_(0), |
| 39 change_window_bounds_on_animate_(false), |
| 40 mutating_grid_(false) { |
| 30 grid_ = new TabOverviewGrid(this); | 41 grid_ = new TabOverviewGrid(this); |
| 31 | 42 |
| 32 // Create the host. | 43 // Create the host. |
| 33 views::WidgetGtk* host = new views::WidgetGtk(views::WidgetGtk::TYPE_POPUP); | 44 views::WidgetGtk* host = new views::WidgetGtk(views::WidgetGtk::TYPE_POPUP); |
| 34 host->set_delete_on_destroy(false); | 45 host->set_delete_on_destroy(false); |
| 35 host->MakeTransparent(); | 46 host->MakeTransparent(); |
| 36 host->Init(NULL, gfx::Rect(), true); | 47 host->Init(NULL, gfx::Rect(), true); |
| 48 TabOverviewTypes::instance()->SetWindowType( |
| 49 host->GetNativeView(), |
| 50 TabOverviewTypes::WINDOW_TYPE_CHROME_TAB_SUMMARY, |
| 51 NULL); |
| 37 host_ = host; | 52 host_ = host; |
| 38 | 53 |
| 39 container_ = new TabOverviewContainer(); | 54 container_ = new TabOverviewContainer(); |
| 40 container_->AddChildView(grid_); | 55 container_->AddChildView(grid_); |
| 41 host->GetRootView()->SetLayoutManager(new views::FillLayout()); | 56 host->GetRootView()->SetLayoutManager(new views::FillLayout()); |
| 42 host->GetRootView()->AddChildView(container_); | 57 host->GetRootView()->AddChildView(container_); |
| 43 | 58 |
| 44 // Determine the bounds we're going to show at. | 59 // Determine the max size for the overview. |
| 45 scoped_ptr<WindowSizer::MonitorInfoProvider> provider( | 60 scoped_ptr<WindowSizer::MonitorInfoProvider> provider( |
| 46 WindowSizer::CreateDefaultMonitorInfoProvider()); | 61 WindowSizer::CreateDefaultMonitorInfoProvider()); |
| 47 monitor_bounds_ = provider->GetMonitorWorkAreaMatching( | 62 monitor_bounds_ = provider->GetMonitorWorkAreaMatching( |
| 48 gfx::Rect(monitor_origin.x(), monitor_origin.y(), 1, 1)); | 63 gfx::Rect(monitor_origin.x(), monitor_origin.y(), 1, 1)); |
| 49 int max_width = monitor_bounds_.width() - kMonitorPadding * 2 - | 64 monitor_bounds_.Inset(kMonitorPadding, 0); |
| 50 kInteriorPadding * 2; | 65 int max_width = monitor_bounds_.width(); |
| 51 int max_height = monitor_bounds_.height() / 2; | 66 int max_height = static_cast<int>(monitor_bounds_.height() * |
| 67 kOverviewHeight); |
| 52 container_->SetMaxSize(gfx::Size(max_width, max_height)); | 68 container_->SetMaxSize(gfx::Size(max_width, max_height)); |
| 69 |
| 70 // TODO: remove this when we get mid point. |
| 71 horizontal_center_ = monitor_bounds_.x() + monitor_bounds_.width() / 2; |
| 53 } | 72 } |
| 54 | 73 |
| 55 TabOverviewController::~TabOverviewController() { | 74 TabOverviewController::~TabOverviewController() { |
| 56 if (browser_) | 75 if (browser_) |
| 57 model()->RemoveObserver(this); | 76 model()->RemoveObserver(this); |
| 58 host_->Close(); | 77 host_->Close(); |
| 59 // The drag controller may call back to us from it's destructor. Make sure | 78 // The drag controller may call back to us from it's destructor. Make sure |
| 60 // it's destroyed before us. | 79 // it's destroyed before us. |
| 61 grid()->CancelDrag(); | 80 grid()->CancelDrag(); |
| 62 } | 81 } |
| 63 | 82 |
| 64 void TabOverviewController::SetBrowser(Browser* browser) { | 83 void TabOverviewController::SetBrowser(Browser* browser, |
| 84 int horizontal_center) { |
| 85 // TODO: update this when we horizontal_center is correct. |
| 86 // horizontal_center_ = horizontal_center; |
| 65 if (browser_) | 87 if (browser_) |
| 66 model()->RemoveObserver(this); | 88 model()->RemoveObserver(this); |
| 67 browser_ = browser; | 89 browser_ = browser; |
| 68 if (browser_) | 90 if (browser_) |
| 69 model()->AddObserver(this); | 91 model()->AddObserver(this); |
| 70 moved_offscreen_ = false; | 92 moved_offscreen_ = false; |
| 71 RecreateCells(); | 93 RecreateCells(); |
| 72 } | 94 } |
| 73 | 95 |
| 74 TabStripModel* TabOverviewController::model() const { | 96 TabStripModel* TabOverviewController::model() const { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 115 gfx::Rect bounds; | 137 gfx::Rect bounds; |
| 116 moved_offscreen_ = true; | 138 moved_offscreen_ = true; |
| 117 host_->GetBounds(&bounds, true); | 139 host_->GetBounds(&bounds, true); |
| 118 host_->SetBounds(gfx::Rect(-10000, -10000, bounds.width(), bounds.height())); | 140 host_->SetBounds(gfx::Rect(-10000, -10000, bounds.width(), bounds.height())); |
| 119 } | 141 } |
| 120 | 142 |
| 121 void TabOverviewController::SelectTabContents(TabContents* contents) { | 143 void TabOverviewController::SelectTabContents(TabContents* contents) { |
| 122 NOTIMPLEMENTED(); | 144 NOTIMPLEMENTED(); |
| 123 } | 145 } |
| 124 | 146 |
| 147 void TabOverviewController::GridAnimationEnded() { |
| 148 if (moved_offscreen_ || !change_window_bounds_on_animate_ || mutating_grid_) |
| 149 return; |
| 150 |
| 151 SetHostBounds(target_bounds_); |
| 152 grid_->UpdateDragController(); |
| 153 change_window_bounds_on_animate_ = false; |
| 154 } |
| 155 |
| 156 void TabOverviewController::GridAnimationProgressed() { |
| 157 if (moved_offscreen_ || !change_window_bounds_on_animate_) |
| 158 return; |
| 159 |
| 160 DCHECK(!mutating_grid_); |
| 161 |
| 162 SetHostBounds(grid_->AnimationPosition(start_bounds_, target_bounds_)); |
| 163 grid_->UpdateDragController(); |
| 164 } |
| 165 |
| 166 void TabOverviewController::GridAnimationCanceled() { |
| 167 change_window_bounds_on_animate_ = false; |
| 168 } |
| 169 |
| 125 void TabOverviewController::TabInsertedAt(TabContents* contents, | 170 void TabOverviewController::TabInsertedAt(TabContents* contents, |
| 126 int index, | 171 int index, |
| 127 bool foreground) { | 172 bool foreground) { |
| 128 if (!grid_->modifying_model()) | 173 if (!grid_->modifying_model()) |
| 129 grid_->CancelDrag(); | 174 grid_->CancelDrag(); |
| 130 | 175 |
| 131 TabOverviewCell* child = new TabOverviewCell(); | 176 TabOverviewCell* child = new TabOverviewCell(); |
| 132 ConfigureCell(child, index); | 177 ConfigureCell(child, index); |
| 178 mutating_grid_ = true; |
| 133 grid_->InsertCell(index, child); | 179 grid_->InsertCell(index, child); |
| 180 mutating_grid_ = false; |
| 134 | 181 |
| 135 TabCountChanged(); | 182 UpdateStartAndTargetBounds(); |
| 136 } | 183 } |
| 137 | 184 |
| 138 void TabOverviewController::TabClosingAt(TabContents* contents, int index) { | 185 void TabOverviewController::TabClosingAt(TabContents* contents, int index) { |
| 139 // Nothing to do, we only care when the tab is actually detached. | 186 // Nothing to do, we only care when the tab is actually detached. |
| 140 } | 187 } |
| 141 | 188 |
| 142 void TabOverviewController::TabDetachedAt(TabContents* contents, int index) { | 189 void TabOverviewController::TabDetachedAt(TabContents* contents, int index) { |
| 143 if (!grid_->modifying_model()) | 190 if (!grid_->modifying_model()) |
| 144 grid_->CancelDrag(); | 191 grid_->CancelDrag(); |
| 145 | 192 |
| 146 scoped_ptr<TabOverviewCell> child(grid_->GetTabOverviewCellAt(index)); | 193 scoped_ptr<TabOverviewCell> child(grid_->GetTabOverviewCellAt(index)); |
| 194 mutating_grid_ = true; |
| 147 grid_->RemoveCell(index); | 195 grid_->RemoveCell(index); |
| 196 mutating_grid_ = false; |
| 148 | 197 |
| 149 TabCountChanged(); | 198 UpdateStartAndTargetBounds(); |
| 150 } | 199 } |
| 151 | 200 |
| 152 void TabOverviewController::TabMoved(TabContents* contents, | 201 void TabOverviewController::TabMoved(TabContents* contents, |
| 153 int from_index, | 202 int from_index, |
| 154 int to_index) { | 203 int to_index) { |
| 155 if (!grid_->modifying_model()) | 204 if (!grid_->modifying_model()) |
| 156 grid_->CancelDrag(); | 205 grid_->CancelDrag(); |
| 157 | 206 |
| 207 mutating_grid_ = true; |
| 158 grid_->MoveCell(from_index, to_index); | 208 grid_->MoveCell(from_index, to_index); |
| 209 mutating_grid_ = false; |
| 210 |
| 211 UpdateStartAndTargetBounds(); |
| 159 } | 212 } |
| 160 | 213 |
| 161 void TabOverviewController::TabChangedAt(TabContents* contents, int index, | 214 void TabOverviewController::TabChangedAt(TabContents* contents, int index, |
| 162 bool loading_only) { | 215 bool loading_only) { |
| 163 ConfigureCell(grid_->GetTabOverviewCellAt(index), index); | 216 ConfigureCell(grid_->GetTabOverviewCellAt(index), index); |
| 164 } | 217 } |
| 165 | 218 |
| 166 void TabOverviewController::TabStripEmpty() { | 219 void TabOverviewController::TabStripEmpty() { |
| 167 if (!grid_->modifying_model()) { | 220 if (!grid_->modifying_model()) { |
| 168 grid_->CancelDrag(); | 221 grid_->CancelDrag(); |
| 169 // The tab strip is empty, hide the grid. | 222 // The tab strip is empty, hide the grid. |
| 170 host_->Hide(); | 223 host_->Hide(); |
| 171 } | 224 } |
| 172 } | 225 } |
| 173 | 226 |
| 174 void TabOverviewController::ConfigureCell(TabOverviewCell* cell, int index) { | 227 void TabOverviewController::ConfigureCell(TabOverviewCell* cell, int index) { |
| 175 ConfigureCell(cell, model()->GetTabContentsAt(index)); | 228 ConfigureCell(cell, model()->GetTabContentsAt(index)); |
| 176 } | 229 } |
| 177 | 230 |
| 178 void TabOverviewController::RecreateCells() { | 231 void TabOverviewController::RecreateCells() { |
| 179 grid_->RemoveAllChildViews(true); | 232 grid_->RemoveAllChildViews(true); |
| 180 | 233 |
| 181 if (model()) { | 234 if (model()) { |
| 182 for (int i = 0; i < model()->count(); ++i) { | 235 for (int i = 0; i < model()->count(); ++i) { |
| 183 TabOverviewCell* child = new TabOverviewCell(); | 236 TabOverviewCell* child = new TabOverviewCell(); |
| 184 ConfigureCell(child, i); | 237 ConfigureCell(child, i); |
| 185 grid_->AddChildView(child); | 238 grid_->AddChildView(child); |
| 186 } | 239 } |
| 187 } | 240 } |
| 188 TabCountChanged(); | |
| 189 } | |
| 190 | 241 |
| 191 void TabOverviewController::TabCountChanged() { | |
| 192 if (moved_offscreen_) | 242 if (moved_offscreen_) |
| 193 return; | 243 return; |
| 194 | 244 |
| 195 gfx::Size pref = container_->GetPreferredSize(); | 245 SetHostBounds(CalculateHostBounds()); |
| 196 int x = monitor_bounds_.x() + (monitor_bounds_.width() - pref.width()) / 2; | |
| 197 int y = monitor_bounds_.y() + monitor_bounds_.height() / 2 - pref.height(); | |
| 198 host_->SetBounds(gfx::Rect(x, y, pref.width(), pref.height())); | |
| 199 | |
| 200 container_->UpdateWidgetShape(pref.width(), pref.height()); | |
| 201 if (grid()->GetChildViewCount() > 0) { | 246 if (grid()->GetChildViewCount() > 0) { |
| 202 if (shown_) | 247 if (shown_) |
| 203 host_->Show(); | 248 host_->Show(); |
| 204 } else { | 249 } else { |
| 205 host_->Hide(); | 250 host_->Hide(); |
| 206 } | 251 } |
| 207 } | 252 } |
| 253 |
| 254 void TabOverviewController::UpdateStartAndTargetBounds() { |
| 255 if (moved_offscreen_ || !shown_) |
| 256 return; |
| 257 |
| 258 if (grid()->GetChildViewCount() == 0) { |
| 259 host_->Hide(); |
| 260 } else { |
| 261 host_->GetBounds(&start_bounds_, true); |
| 262 target_bounds_ = CalculateHostBounds(); |
| 263 change_window_bounds_on_animate_ = (start_bounds_ != target_bounds_); |
| 264 } |
| 265 } |
| 266 |
| 267 void TabOverviewController::SetHostBounds(const gfx::Rect& bounds) { |
| 268 host_->SetBounds(bounds); |
| 269 container_->UpdateWidgetShape(horizontal_center_, bounds.width(), |
| 270 bounds.height()); |
| 271 } |
| 272 |
| 273 gfx::Rect TabOverviewController::CalculateHostBounds() { |
| 274 gfx::Size pref = container_->GetPreferredSize(); |
| 275 int x = horizontal_center_ - pref.width() / 2; |
| 276 int y = monitor_bounds_.bottom() - |
| 277 static_cast<int>(monitor_bounds_.height() * kWindowHeight) - |
| 278 kWindowToOverviewPadding - pref.height(); |
| 279 return gfx::Rect(x, y, pref.width(), pref.height()). |
| 280 AdjustToFit(monitor_bounds_); |
| 281 } |
| OLD | NEW |