OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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/ui/panels/docked_panel_strip.h" | 5 #include "chrome/browser/ui/panels/docked_panel_strip.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/message_loop.h" | 11 #include "base/message_loop.h" |
12 #include "chrome/browser/ui/browser.h" | 12 #include "chrome/browser/ui/browser.h" |
13 #include "chrome/browser/ui/panels/overflow_panel_strip.h" | 13 #include "chrome/browser/ui/panels/overflow_panel_strip.h" |
14 #include "chrome/browser/ui/panels/panel_drag_controller.h" | |
14 #include "chrome/browser/ui/panels/panel_manager.h" | 15 #include "chrome/browser/ui/panels/panel_manager.h" |
15 #include "chrome/browser/ui/panels/panel_mouse_watcher.h" | 16 #include "chrome/browser/ui/panels/panel_mouse_watcher.h" |
16 #include "chrome/common/chrome_notification_types.h" | 17 #include "chrome/common/chrome_notification_types.h" |
17 #include "content/public/browser/notification_service.h" | 18 #include "content/public/browser/notification_service.h" |
18 #include "content/public/browser/notification_source.h" | 19 #include "content/public/browser/notification_source.h" |
19 | 20 |
20 namespace { | 21 namespace { |
21 // Width to height ratio is used to compute the default width or height | 22 // Width to height ratio is used to compute the default width or height |
22 // when only one value is provided. | 23 // when only one value is provided. |
23 const double kPanelDefaultWidthToHeightRatio = 1.62; // golden ratio | 24 const double kPanelDefaultWidthToHeightRatio = 1.62; // golden ratio |
(...skipping 28 matching lines...) Expand all Loading... | |
52 // static | 53 // static |
53 const int DockedPanelStrip::kPanelMinWidth = 100; | 54 const int DockedPanelStrip::kPanelMinWidth = 100; |
54 const int DockedPanelStrip::kPanelMinHeight = 20; | 55 const int DockedPanelStrip::kPanelMinHeight = 20; |
55 | 56 |
56 DockedPanelStrip::DockedPanelStrip(PanelManager* panel_manager) | 57 DockedPanelStrip::DockedPanelStrip(PanelManager* panel_manager) |
57 : PanelStrip(PanelStrip::DOCKED), | 58 : PanelStrip(PanelStrip::DOCKED), |
58 panel_manager_(panel_manager), | 59 panel_manager_(panel_manager), |
59 minimized_panel_count_(0), | 60 minimized_panel_count_(0), |
60 are_titlebars_up_(false), | 61 are_titlebars_up_(false), |
61 disable_layout_refresh_(false), | 62 disable_layout_refresh_(false), |
62 dragging_panel_(NULL), | |
63 dragging_panel_original_x_(0), | 63 dragging_panel_original_x_(0), |
64 delayed_titlebar_action_(NO_ACTION), | 64 delayed_titlebar_action_(NO_ACTION), |
65 titlebar_action_factory_(this) { | 65 titlebar_action_factory_(this) { |
66 } | 66 } |
67 | 67 |
68 DockedPanelStrip::~DockedPanelStrip() { | 68 DockedPanelStrip::~DockedPanelStrip() { |
69 DCHECK(panels_.empty()); | 69 DCHECK(panels_.empty()); |
70 DCHECK(panels_pending_to_remove_.empty()); | 70 DCHECK(panels_pending_to_remove_.empty()); |
71 DCHECK(panels_in_temporary_layout_.empty()); | 71 DCHECK(panels_in_temporary_layout_.empty()); |
72 DCHECK_EQ(0, minimized_panel_count_); | 72 DCHECK_EQ(0, minimized_panel_count_); |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
176 panel), | 176 panel), |
177 base::TimeDelta::FromMilliseconds(PanelManager::AdjustTimeInterval( | 177 base::TimeDelta::FromMilliseconds(PanelManager::AdjustTimeInterval( |
178 kMoveNewPanelToOverflowDelayMs))); | 178 kMoveNewPanelToOverflowDelayMs))); |
179 } | 179 } |
180 #endif | 180 #endif |
181 panel->Initialize(gfx::Rect(x, y, width, height)); | 181 panel->Initialize(gfx::Rect(x, y, width, height)); |
182 } | 182 } |
183 | 183 |
184 // Set panel properties for this strip. | 184 // Set panel properties for this strip. |
185 panel->SetAppIconVisibility(true); | 185 panel->SetAppIconVisibility(true); |
186 panel->set_draggable(!panel->has_temporary_layout()); | |
187 panel->ApplyVisualStyleForStrip(); | 186 panel->ApplyVisualStyleForStrip(); |
188 | 187 |
189 if (panel->has_temporary_layout()) | 188 if (panel->has_temporary_layout()) |
190 panels_in_temporary_layout_.insert(panel); | 189 panels_in_temporary_layout_.insert(panel); |
191 else | 190 else |
192 panels_.push_back(panel); | 191 panels_.push_back(panel); |
193 } | 192 } |
194 | 193 |
195 int DockedPanelStrip::GetMaxPanelWidth() const { | 194 int DockedPanelStrip::GetMaxPanelWidth() const { |
196 return static_cast<int>(display_area_.width() * kPanelMaxWidthFactor); | 195 return static_cast<int>(display_area_.width() * kPanelMaxWidthFactor); |
(...skipping 15 matching lines...) Expand all Loading... | |
212 bool DockedPanelStrip::RemovePanel(Panel* panel) { | 211 bool DockedPanelStrip::RemovePanel(Panel* panel) { |
213 if (panel->has_temporary_layout()) { | 212 if (panel->has_temporary_layout()) { |
214 panels_in_temporary_layout_.erase(panel); | 213 panels_in_temporary_layout_.erase(panel); |
215 return true; | 214 return true; |
216 } | 215 } |
217 | 216 |
218 if (find(panels_.begin(), panels_.end(), panel) == panels_.end()) | 217 if (find(panels_.begin(), panels_.end(), panel) == panels_.end()) |
219 return false; | 218 return false; |
220 | 219 |
221 // If we're in the process of dragging, delay the removal. | 220 // If we're in the process of dragging, delay the removal. |
222 if (dragging_panel_) { | 221 if (panel_manager_->drag_controller()->dragging_panel()) { |
jennb
2012/02/21 20:01:46
nit: should there be a IsDragging()/DragInProgress
| |
223 panels_pending_to_remove_.push_back(panel); | 222 panels_pending_to_remove_.push_back(panel); |
224 return true; | 223 return true; |
225 } | 224 } |
226 | |
227 DoRemove(panel); | 225 DoRemove(panel); |
228 | 226 |
229 if (!disable_layout_refresh_) | 227 if (!disable_layout_refresh_) |
230 RefreshLayout(); | 228 RefreshLayout(); |
231 | 229 |
232 return true; | 230 return true; |
233 } | 231 } |
234 | 232 |
235 void DockedPanelStrip::DelayedRemove() { | 233 void DockedPanelStrip::DelayedRemove() { |
236 for (size_t i = 0; i < panels_pending_to_remove_.size(); ++i) | 234 for (size_t i = 0; i < panels_pending_to_remove_.size(); ++i) |
237 DoRemove(panels_pending_to_remove_[i]); | 235 DoRemove(panels_pending_to_remove_[i]); |
238 panels_pending_to_remove_.clear(); | 236 panels_pending_to_remove_.clear(); |
239 RefreshLayout(); | 237 RefreshLayout(); |
240 } | 238 } |
241 | 239 |
242 bool DockedPanelStrip::DoRemove(Panel* panel) { | 240 bool DockedPanelStrip::DoRemove(Panel* panel) { |
243 Panels::iterator iter = find(panels_.begin(), panels_.end(), panel); | 241 Panels::iterator iter = find(panels_.begin(), panels_.end(), panel); |
244 if (iter == panels_.end()) | 242 if (iter == panels_.end()) |
245 return false; | 243 return false; |
246 | 244 |
247 if (panel->expansion_state() != Panel::EXPANDED) | 245 if (panel->expansion_state() != Panel::EXPANDED) |
248 DecrementMinimizedPanels(); | 246 DecrementMinimizedPanels(); |
249 | 247 |
250 panels_.erase(iter); | 248 panels_.erase(iter); |
251 panel_manager_->OnPanelRemoved(panel); | 249 panel_manager_->OnPanelRemoved(panel); |
252 return true; | 250 return true; |
253 } | 251 } |
254 | 252 |
255 void DockedPanelStrip::StartDragging(Panel* panel) { | 253 bool DockedPanelStrip::CanDragPanel(const Panel* panel) const { |
254 // Only the panels having temporary layout can't be dragged. | |
255 return !panel->has_temporary_layout(); | |
256 } | |
257 | |
258 void DockedPanelStrip::StartDraggingPanel(Panel* panel) { | |
256 dragging_panel_iterator_ = find(panels_.begin(), panels_.end(), panel); | 259 dragging_panel_iterator_ = find(panels_.begin(), panels_.end(), panel); |
257 DCHECK(dragging_panel_iterator_ != panels_.end()); | 260 DCHECK(dragging_panel_iterator_ != panels_.end()); |
258 | 261 |
259 dragging_panel_ = panel; | |
260 dragging_panel_bounds_ = panel->GetBounds(); | 262 dragging_panel_bounds_ = panel->GetBounds(); |
261 dragging_panel_original_x_ = dragging_panel_bounds_.x(); | 263 dragging_panel_original_x_ = dragging_panel_bounds_.x(); |
262 } | 264 } |
263 | 265 |
264 void DockedPanelStrip::Drag(int delta_x) { | 266 void DockedPanelStrip::DragPanel(Panel* panel, int delta_x, int delta_y) { |
265 DCHECK(dragging_panel_); | |
266 | |
267 if (!delta_x) | 267 if (!delta_x) |
268 return; | 268 return; |
269 | 269 |
270 // Moves this panel to the dragging position. | 270 // Moves this panel to the dragging position. |
271 gfx::Rect new_bounds(dragging_panel_->GetBounds()); | 271 gfx::Rect new_bounds(panel->GetBounds()); |
272 new_bounds.set_x(new_bounds.x() + delta_x); | 272 new_bounds.set_x(new_bounds.x() + delta_x); |
273 dragging_panel_->SetPanelBounds(new_bounds); | 273 panel->SetPanelBounds(new_bounds); |
274 | 274 |
275 // Checks and processes other affected panels. | 275 // Checks and processes other affected panels. |
276 if (delta_x > 0) | 276 if (delta_x > 0) |
277 DragRight(); | 277 DragRight(panel); |
278 else | 278 else |
279 DragLeft(); | 279 DragLeft(panel); |
280 } | 280 } |
281 | 281 |
282 void DockedPanelStrip::DragLeft() { | 282 void DockedPanelStrip::DragLeft(Panel* dragging_panel) { |
283 // This is the left corner of the dragging panel. We use it to check against | 283 // This is the left corner of the dragging panel. We use it to check against |
284 // all the panels on its left. | 284 // all the panels on its left. |
285 int dragging_panel_left_boundary = dragging_panel_->GetBounds().x(); | 285 int dragging_panel_left_boundary = dragging_panel->GetBounds().x(); |
286 | 286 |
287 // This is the right corner which a panel will be moved to. | 287 // This is the right corner which a panel will be moved to. |
288 int current_panel_right_boundary = | 288 int current_panel_right_boundary = |
289 dragging_panel_bounds_.x() + dragging_panel_bounds_.width(); | 289 dragging_panel_bounds_.x() + dragging_panel_bounds_.width(); |
290 | 290 |
291 // Checks the panels to the left of the dragging panel. | 291 // Checks the panels to the left of the dragging panel. |
292 Panels::iterator current_panel_iterator = dragging_panel_iterator_; | 292 Panels::iterator current_panel_iterator = dragging_panel_iterator_; |
293 ++current_panel_iterator; | 293 ++current_panel_iterator; |
294 for (; current_panel_iterator != panels_.end(); ++current_panel_iterator) { | 294 for (; current_panel_iterator != panels_.end(); ++current_panel_iterator) { |
295 Panel* current_panel = *current_panel_iterator; | 295 Panel* current_panel = *current_panel_iterator; |
296 | 296 |
297 // Current panel will only be affected if the left corner of dragging | 297 // Current panel will only be affected if the left corner of dragging |
298 // panel goes beyond the middle position of the current panel. | 298 // panel goes beyond the middle position of the current panel. |
299 if (dragging_panel_left_boundary > current_panel->GetBounds().x() + | 299 if (dragging_panel_left_boundary > current_panel->GetBounds().x() + |
300 current_panel->GetBounds().width() / 2) | 300 current_panel->GetBounds().width() / 2) |
301 break; | 301 break; |
302 | 302 |
303 // Moves current panel to the new position. | 303 // Moves current panel to the new position. |
304 gfx::Rect bounds(current_panel->GetBounds()); | 304 gfx::Rect bounds(current_panel->GetBounds()); |
305 bounds.set_x(current_panel_right_boundary - bounds.width()); | 305 bounds.set_x(current_panel_right_boundary - bounds.width()); |
306 current_panel_right_boundary -= bounds.width() + kPanelsHorizontalSpacing; | 306 current_panel_right_boundary -= bounds.width() + kPanelsHorizontalSpacing; |
307 current_panel->SetPanelBounds(bounds); | 307 current_panel->SetPanelBounds(bounds); |
308 | 308 |
309 // Swaps current panel and dragging panel. | 309 // Swaps current panel and dragging panel. |
310 *dragging_panel_iterator_ = current_panel; | 310 *dragging_panel_iterator_ = current_panel; |
311 *current_panel_iterator = dragging_panel_; | 311 *current_panel_iterator = dragging_panel; |
312 dragging_panel_iterator_ = current_panel_iterator; | 312 dragging_panel_iterator_ = current_panel_iterator; |
313 } | 313 } |
314 | 314 |
315 // Updates the potential final position of dragging panel as the result of | 315 // Updates the potential final position of dragging panel as the result of |
316 // swapping with panels on its left. | 316 // swapping with panels on its left. |
317 dragging_panel_bounds_.set_x(current_panel_right_boundary - | 317 dragging_panel_bounds_.set_x(current_panel_right_boundary - |
318 dragging_panel_bounds_.width()); | 318 dragging_panel_bounds_.width()); |
319 } | 319 } |
320 | 320 |
321 void DockedPanelStrip::DragRight() { | 321 void DockedPanelStrip::DragRight(Panel* dragging_panel) { |
322 // This is the right corner of the dragging panel. We use it to check against | 322 // This is the right corner of the dragging panel. We use it to check against |
323 // all the panels on its right. | 323 // all the panels on its right. |
324 int dragging_panel_right_boundary = dragging_panel_->GetBounds().x() + | 324 int dragging_panel_right_boundary = dragging_panel->GetBounds().x() + |
325 dragging_panel_->GetBounds().width() - 1; | 325 dragging_panel->GetBounds().width() - 1; |
326 | 326 |
327 // This is the left corner which a panel will be moved to. | 327 // This is the left corner which a panel will be moved to. |
328 int current_panel_left_boundary = dragging_panel_bounds_.x(); | 328 int current_panel_left_boundary = dragging_panel_bounds_.x(); |
329 | 329 |
330 // Checks the panels to the right of the dragging panel. | 330 // Checks the panels to the right of the dragging panel. |
331 Panels::iterator current_panel_iterator = dragging_panel_iterator_; | 331 Panels::iterator current_panel_iterator = dragging_panel_iterator_; |
332 while (current_panel_iterator != panels_.begin()) { | 332 while (current_panel_iterator != panels_.begin()) { |
333 current_panel_iterator--; | 333 current_panel_iterator--; |
334 Panel* current_panel = *current_panel_iterator; | 334 Panel* current_panel = *current_panel_iterator; |
335 | 335 |
336 // Current panel will only be affected if the right corner of dragging | 336 // Current panel will only be affected if the right corner of dragging |
337 // panel goes beyond the middle position of the current panel. | 337 // panel goes beyond the middle position of the current panel. |
338 if (dragging_panel_right_boundary < current_panel->GetBounds().x() + | 338 if (dragging_panel_right_boundary < current_panel->GetBounds().x() + |
339 current_panel->GetBounds().width() / 2) | 339 current_panel->GetBounds().width() / 2) |
340 break; | 340 break; |
341 | 341 |
342 // Moves current panel to the new position. | 342 // Moves current panel to the new position. |
343 gfx::Rect bounds(current_panel->GetBounds()); | 343 gfx::Rect bounds(current_panel->GetBounds()); |
344 bounds.set_x(current_panel_left_boundary); | 344 bounds.set_x(current_panel_left_boundary); |
345 current_panel_left_boundary += bounds.width() + kPanelsHorizontalSpacing; | 345 current_panel_left_boundary += bounds.width() + kPanelsHorizontalSpacing; |
346 current_panel->SetPanelBounds(bounds); | 346 current_panel->SetPanelBounds(bounds); |
347 | 347 |
348 // Swaps current panel and dragging panel. | 348 // Swaps current panel and dragging panel. |
349 *dragging_panel_iterator_ = current_panel; | 349 *dragging_panel_iterator_ = current_panel; |
350 *current_panel_iterator = dragging_panel_; | 350 *current_panel_iterator = dragging_panel; |
351 dragging_panel_iterator_ = current_panel_iterator; | 351 dragging_panel_iterator_ = current_panel_iterator; |
352 } | 352 } |
353 | 353 |
354 // Updates the potential final position of dragging panel as the result of | 354 // Updates the potential final position of dragging panel as the result of |
355 // swapping with panels on its right. | 355 // swapping with panels on its right. |
356 dragging_panel_bounds_.set_x(current_panel_left_boundary); | 356 dragging_panel_bounds_.set_x(current_panel_left_boundary); |
357 } | 357 } |
358 | 358 |
359 void DockedPanelStrip::EndDragging(bool cancelled) { | 359 void DockedPanelStrip::EndDraggingPanel(Panel* panel, bool cancelled) { |
360 DCHECK(dragging_panel_); | |
361 | |
362 if (cancelled) | 360 if (cancelled) |
363 Drag(dragging_panel_original_x_ - dragging_panel_->GetBounds().x()); | 361 DragPanel(panel, dragging_panel_original_x_ - panel->GetBounds().x(), 0); |
364 else | 362 else |
365 dragging_panel_->SetPanelBounds(dragging_panel_bounds_); | 363 panel->SetPanelBounds(dragging_panel_bounds_); |
366 | |
367 dragging_panel_ = NULL; | |
368 | 364 |
369 DelayedRemove(); | 365 DelayedRemove(); |
370 } | 366 } |
371 | 367 |
372 void DockedPanelStrip::OnPanelExpansionStateChanged(Panel* panel) { | 368 void DockedPanelStrip::OnPanelExpansionStateChanged(Panel* panel) { |
373 gfx::Size size = panel->restored_size(); | 369 gfx::Size size = panel->restored_size(); |
374 Panel::ExpansionState expansion_state = panel->expansion_state(); | 370 Panel::ExpansionState expansion_state = panel->expansion_state(); |
375 Panel::ExpansionState old_state = panel->old_expansion_state(); | 371 Panel::ExpansionState old_state = panel->old_expansion_state(); |
376 switch (expansion_state) { | 372 switch (expansion_state) { |
377 case Panel::EXPANDED: | 373 case Panel::EXPANDED: |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
517 for (Panels::const_iterator iter = panels_.begin(); | 513 for (Panels::const_iterator iter = panels_.begin(); |
518 iter != panels_.end(); ++iter) { | 514 iter != panels_.end(); ++iter) { |
519 Panel* panel = *iter; | 515 Panel* panel = *iter; |
520 Panel::ExpansionState state = panel->expansion_state(); | 516 Panel::ExpansionState state = panel->expansion_state(); |
521 // Skip the expanded panel. | 517 // Skip the expanded panel. |
522 if (state == Panel::EXPANDED) | 518 if (state == Panel::EXPANDED) |
523 continue; | 519 continue; |
524 | 520 |
525 // If the panel is showing titlebar only, we want to keep it up when it is | 521 // If the panel is showing titlebar only, we want to keep it up when it is |
526 // being dragged. | 522 // being dragged. |
527 if (state == Panel::TITLE_ONLY && is_dragging_panel()) | 523 if (state == Panel::TITLE_ONLY && |
524 panel == panel_manager_->drag_controller()->dragging_panel()) | |
528 return true; | 525 return true; |
529 | 526 |
530 // We do not want to bring up other minimized panels if the mouse is over | 527 // We do not want to bring up other minimized panels if the mouse is over |
531 // the panel that pops up the titlebar to attract attention. | 528 // the panel that pops up the titlebar to attract attention. |
532 if (panel->IsDrawingAttention()) | 529 if (panel->IsDrawingAttention()) |
533 continue; | 530 continue; |
534 | 531 |
535 gfx::Rect bounds = panel->GetBounds(); | 532 gfx::Rect bounds = panel->GetBounds(); |
536 if (bounds.x() <= mouse_x && mouse_x <= bounds.right() && | 533 if (bounds.x() <= mouse_x && mouse_x <= bounds.right() && |
537 mouse_y >= bounds.y()) | 534 mouse_y >= bounds.y()) |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
737 | 734 |
738 void DockedPanelStrip::DelayedMovePanelToOverflow(Panel* panel) { | 735 void DockedPanelStrip::DelayedMovePanelToOverflow(Panel* panel) { |
739 if (panels_in_temporary_layout_.erase(panel)) { | 736 if (panels_in_temporary_layout_.erase(panel)) { |
740 DCHECK(panel->has_temporary_layout()); | 737 DCHECK(panel->has_temporary_layout()); |
741 panel->MoveToStrip(panel_manager_->overflow_strip()); | 738 panel->MoveToStrip(panel_manager_->overflow_strip()); |
742 } | 739 } |
743 } | 740 } |
744 | 741 |
745 void DockedPanelStrip::CloseAll() { | 742 void DockedPanelStrip::CloseAll() { |
746 // This should only be called at the end of tests to clean up. | 743 // This should only be called at the end of tests to clean up. |
747 DCHECK(!dragging_panel_); | |
748 DCHECK(panels_in_temporary_layout_.empty()); | 744 DCHECK(panels_in_temporary_layout_.empty()); |
749 | 745 |
750 // Make a copy of the iterator as closing panels can modify the vector. | 746 // Make a copy of the iterator as closing panels can modify the vector. |
751 Panels panels_copy = panels_; | 747 Panels panels_copy = panels_; |
752 | 748 |
753 // Start from the bottom to avoid reshuffling. | 749 // Start from the bottom to avoid reshuffling. |
754 for (Panels::reverse_iterator iter = panels_copy.rbegin(); | 750 for (Panels::reverse_iterator iter = panels_copy.rbegin(); |
755 iter != panels_copy.rend(); ++iter) | 751 iter != panels_copy.rend(); ++iter) |
756 (*iter)->Close(); | 752 (*iter)->Close(); |
757 } | 753 } |
758 | |
759 bool DockedPanelStrip::is_dragging_panel() const { | |
760 return dragging_panel_ != NULL; | |
761 } | |
OLD | NEW |