Chromium Code Reviews| 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 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/message_loop.h" | 12 #include "base/message_loop.h" |
| 13 #include "chrome/browser/ui/browser.h" | 13 #include "chrome/browser/ui/browser.h" |
| 14 #include "chrome/browser/ui/panels/overflow_panel_strip.h" | |
| 15 #include "chrome/browser/ui/panels/panel_drag_controller.h" | |
| 14 #include "chrome/browser/ui/panels/panel_manager.h" | 16 #include "chrome/browser/ui/panels/panel_manager.h" |
| 15 #include "chrome/browser/ui/panels/panel_mouse_watcher.h" | 17 #include "chrome/browser/ui/panels/panel_mouse_watcher.h" |
| 16 #include "chrome/common/chrome_notification_types.h" | 18 #include "chrome/common/chrome_notification_types.h" |
| 17 #include "content/public/browser/notification_service.h" | 19 #include "content/public/browser/notification_service.h" |
| 18 #include "content/public/browser/notification_source.h" | 20 #include "content/public/browser/notification_source.h" |
| 19 | 21 |
| 20 namespace { | 22 namespace { |
| 21 // Width to height ratio is used to compute the default width or height | 23 // Width to height ratio is used to compute the default width or height |
| 22 // when only one value is provided. | 24 // when only one value is provided. |
| 23 const double kPanelDefaultWidthToHeightRatio = 1.62; // golden ratio | 25 const double kPanelDefaultWidthToHeightRatio = 1.62; // golden ratio |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 53 const int DockedPanelStrip::kPanelMinWidth = 100; | 55 const int DockedPanelStrip::kPanelMinWidth = 100; |
| 54 const int DockedPanelStrip::kPanelMinHeight = 20; | 56 const int DockedPanelStrip::kPanelMinHeight = 20; |
| 55 | 57 |
| 56 DockedPanelStrip::DockedPanelStrip(PanelManager* panel_manager) | 58 DockedPanelStrip::DockedPanelStrip(PanelManager* panel_manager) |
| 57 : PanelStrip(PanelStrip::DOCKED), | 59 : PanelStrip(PanelStrip::DOCKED), |
| 58 panel_manager_(panel_manager), | 60 panel_manager_(panel_manager), |
| 59 minimized_panel_count_(0), | 61 minimized_panel_count_(0), |
| 60 are_titlebars_up_(false), | 62 are_titlebars_up_(false), |
| 61 delayed_titlebar_action_(NO_ACTION), | 63 delayed_titlebar_action_(NO_ACTION), |
| 62 titlebar_action_factory_(this) { | 64 titlebar_action_factory_(this) { |
| 63 dragging_panel_current_iterator_ = dragging_panel_original_iterator_ = | 65 dragging_panel_current_iterator_ = panels_.end(); |
| 64 panels_.end(); | |
| 65 } | 66 } |
| 66 | 67 |
| 67 DockedPanelStrip::~DockedPanelStrip() { | 68 DockedPanelStrip::~DockedPanelStrip() { |
| 68 DCHECK(panels_.empty()); | 69 DCHECK(panels_.empty()); |
| 69 DCHECK(panels_in_temporary_layout_.empty()); | 70 DCHECK(panels_in_temporary_layout_.empty()); |
| 70 DCHECK_EQ(0, minimized_panel_count_); | 71 DCHECK_EQ(0, minimized_panel_count_); |
| 71 } | 72 } |
| 72 | 73 |
| 73 void DockedPanelStrip::SetDisplayArea(const gfx::Rect& display_area) { | 74 void DockedPanelStrip::SetDisplayArea(const gfx::Rect& display_area) { |
| 74 if (display_area_ == display_area) | 75 if (display_area_ == display_area) |
| 75 return; | 76 return; |
| 76 | 77 |
| 77 gfx::Rect old_area = display_area_; | 78 gfx::Rect old_area = display_area_; |
| 78 display_area_ = display_area; | 79 display_area_ = display_area; |
| 79 | 80 |
| 80 if (panels_.empty()) | 81 if (panels_.empty()) |
| 81 return; | 82 return; |
| 82 | 83 |
| 83 RefreshLayout(); | 84 RefreshLayout(); |
| 84 } | 85 } |
| 85 | 86 |
| 86 void DockedPanelStrip::AddPanel(Panel* panel) { | 87 void DockedPanelStrip::AddPanel(Panel* panel) { |
| 87 DCHECK_NE(this, panel->panel_strip()); | 88 DCHECK_NE(this, panel->panel_strip()); |
| 88 panel->set_panel_strip(this); | 89 panel->set_panel_strip(this); |
| 89 | 90 |
| 91 if (panel->initialized()) { | |
| 92 if (panel->in_preview_mode()) | |
| 93 InsertPreviewedPanel(panel); | |
| 94 else | |
| 95 InsertExistingPanel(panel); | |
| 96 } else { | |
| 97 InsertNewlyCreatedPanel(panel); | |
| 98 } | |
| 99 | |
| 90 // Always update limits, even on existing panels, in case the limits changed | 100 // Always update limits, even on existing panels, in case the limits changed |
| 91 // while panel was out of the strip. | 101 // while panel was out of the strip. |
| 92 int max_panel_width = GetMaxPanelWidth(); | 102 int max_panel_width = GetMaxPanelWidth(); |
| 93 int max_panel_height = GetMaxPanelHeight(); | 103 int max_panel_height = GetMaxPanelHeight(); |
| 94 panel->SetSizeRange(gfx::Size(kPanelMinWidth, kPanelMinHeight), | 104 panel->SetSizeRange(gfx::Size(kPanelMinWidth, kPanelMinHeight), |
| 95 gfx::Size(max_panel_width, max_panel_height)); | 105 gfx::Size(max_panel_width, max_panel_height)); |
| 96 | 106 |
| 107 panel->SetAppIconVisibility(true); | |
| 108 panel->SetAlwaysOnTop(true); | |
| 109 } | |
| 110 | |
| 111 | |
| 112 void DockedPanelStrip::InsertPreviewedPanel(Panel* panel) { | |
|
Andrei
2012/03/07 22:55:13
DCHECK panel is in preview mode
jianli
2012/03/08 01:18:26
Done.
| |
| 113 FitPanelWithWidth(panel->GetBounds().width()); | |
| 114 | |
| 115 int x = panel->GetBounds().x(); | |
| 116 Panels::iterator iter = panels_.begin(); | |
| 117 for (; iter != panels_.end(); ++iter) | |
| 118 if (x > (*iter)->GetBounds().x()) | |
| 119 break; | |
| 120 panels_.insert(iter, panel); | |
| 121 | |
| 122 // This will automatically update all affected panels due to the insertion. | |
| 123 if (iter != panels_.end()) | |
| 124 RefreshLayout(); | |
| 125 } | |
| 126 | |
| 127 void DockedPanelStrip::InsertExistingPanel(Panel* panel) { | |
| 97 gfx::Size restored_size = panel->restored_size(); | 128 gfx::Size restored_size = panel->restored_size(); |
| 98 int height = restored_size.height(); | 129 int height = restored_size.height(); |
| 99 int width = restored_size.width(); | 130 int width = restored_size.width(); |
| 100 | 131 |
| 101 if (panel->initialized()) { | 132 int x = FitPanelWithWidth(width); |
| 102 int x = FitPanelWithWidth(width); | |
| 103 | 133 |
| 104 Panel::ExpansionState expansion_state_to_restore; | 134 Panel::ExpansionState expansion_state_to_restore; |
| 105 if (panel->expansion_state() == Panel::EXPANDED) { | 135 if (panel->expansion_state() == Panel::EXPANDED) { |
| 106 expansion_state_to_restore = Panel::EXPANDED; | 136 expansion_state_to_restore = Panel::EXPANDED; |
| 137 } else { | |
| 138 if (are_titlebars_up_ || panel->IsDrawingAttention()) { | |
| 139 expansion_state_to_restore = Panel::TITLE_ONLY; | |
| 140 height = panel->TitleOnlyHeight(); | |
| 107 } else { | 141 } else { |
| 108 if (are_titlebars_up_ || panel->IsDrawingAttention()) { | 142 expansion_state_to_restore = Panel::MINIMIZED; |
| 109 expansion_state_to_restore = Panel::TITLE_ONLY; | 143 height = Panel::kMinimizedPanelHeight; |
| 110 height = panel->TitleOnlyHeight(); | |
| 111 } else { | |
| 112 expansion_state_to_restore = Panel::MINIMIZED; | |
| 113 height = Panel::kMinimizedPanelHeight; | |
| 114 } | |
| 115 IncrementMinimizedPanels(); | |
| 116 } | 144 } |
| 117 int y = | 145 IncrementMinimizedPanels(); |
| 118 GetBottomPositionForExpansionState(expansion_state_to_restore) - height; | 146 } |
| 119 panel->SetPanelBounds(gfx::Rect(x, y, width, height)); | 147 int y = |
| 148 GetBottomPositionForExpansionState(expansion_state_to_restore) - height; | |
| 149 panel->SetPanelBounds(gfx::Rect(x, y, width, height)); | |
| 120 | 150 |
| 121 // Update the minimized state to reflect current titlebar mode. | 151 // Update the minimized state to reflect current titlebar mode. |
| 122 // Do this AFTER setting panel bounds to avoid an extra bounds change. | 152 // Do this AFTER setting panel bounds to avoid an extra bounds change. |
| 123 if (panel->expansion_state() != Panel::EXPANDED) | 153 if (panel->expansion_state() != Panel::EXPANDED) |
| 124 panel->SetExpansionState(expansion_state_to_restore); | 154 panel->SetExpansionState(expansion_state_to_restore); |
| 125 | 155 |
| 156 panels_.push_back(panel); | |
| 157 } | |
| 158 | |
| 159 void DockedPanelStrip::InsertNewlyCreatedPanel(Panel* panel) { | |
| 160 int max_panel_width = GetMaxPanelWidth(); | |
|
Andrei
2012/03/07 22:55:13
DCHECK panel is not initialized
jianli
2012/03/08 01:18:26
Done.
| |
| 161 int max_panel_height = GetMaxPanelHeight(); | |
| 162 gfx::Size restored_size = panel->restored_size(); | |
| 163 int height = restored_size.height(); | |
| 164 int width = restored_size.width(); | |
| 165 | |
| 166 // Initialize the newly created panel. Does not bump any panels from strip. | |
| 167 if (height == 0 && width == 0 && panel_manager_->auto_sizing_enabled()) { | |
| 168 // Auto resizable is enabled only if no initial size is provided. | |
| 169 panel->SetAutoResizable(true); | |
| 126 } else { | 170 } else { |
| 127 // Initialize the newly created panel. Does not bump any panels from strip. | 171 if (height == 0) |
| 128 if (height == 0 && width == 0 && panel_manager_->auto_sizing_enabled()) { | 172 height = width / kPanelDefaultWidthToHeightRatio; |
| 129 // Auto resizable is enabled only if no initial size is provided. | 173 if (width == 0) |
| 130 panel->SetAutoResizable(true); | 174 width = height * kPanelDefaultWidthToHeightRatio; |
| 131 } else { | |
| 132 if (height == 0) | |
| 133 height = width / kPanelDefaultWidthToHeightRatio; | |
| 134 if (width == 0) | |
| 135 width = height * kPanelDefaultWidthToHeightRatio; | |
| 136 } | |
| 137 | |
| 138 // Constrain sizes to limits. | |
| 139 if (width < kPanelMinWidth) | |
| 140 width = kPanelMinWidth; | |
| 141 else if (width > max_panel_width) | |
| 142 width = max_panel_width; | |
| 143 | |
| 144 if (height < kPanelMinHeight) | |
| 145 height = kPanelMinHeight; | |
| 146 else if (height > max_panel_height) | |
| 147 height = max_panel_height; | |
| 148 | |
| 149 panel->set_restored_size(gfx::Size(width, height)); | |
| 150 int x = GetRightMostAvailablePosition() - width; | |
| 151 int y = display_area_.bottom() - height; | |
| 152 | |
| 153 // Keep panel visible in the strip even if overlap would occur. | |
| 154 // Panel is moved to overflow from the strip after a delay. | |
| 155 if (x < display_area_.x()) { | |
| 156 x = display_area_.x(); | |
| 157 panel->set_has_temporary_layout(true); | |
| 158 MessageLoop::current()->PostDelayedTask( | |
| 159 FROM_HERE, | |
| 160 base::Bind(&DockedPanelStrip::DelayedMovePanelToOverflow, | |
| 161 base::Unretained(this), | |
| 162 panel), | |
| 163 base::TimeDelta::FromMilliseconds(PanelManager::AdjustTimeInterval( | |
| 164 kMoveNewPanelToOverflowDelayMs))); | |
| 165 } | |
| 166 panel->Initialize(gfx::Rect(x, y, width, height)); | |
| 167 } | 175 } |
| 168 | 176 |
| 169 // Set panel properties for this strip. | 177 // Constrain sizes to limits. |
| 170 panel->SetAppIconVisibility(true); | 178 if (width < kPanelMinWidth) |
| 179 width = kPanelMinWidth; | |
| 180 else if (width > max_panel_width) | |
| 181 width = max_panel_width; | |
| 182 | |
| 183 if (height < kPanelMinHeight) | |
| 184 height = kPanelMinHeight; | |
| 185 else if (height > max_panel_height) | |
| 186 height = max_panel_height; | |
| 187 | |
| 188 panel->set_restored_size(gfx::Size(width, height)); | |
| 189 int x = GetRightMostAvailablePosition() - width; | |
| 190 int y = display_area_.bottom() - height; | |
| 191 | |
| 192 // Keep panel visible in the strip even if overlap would occur. | |
| 193 // Panel is moved to overflow from the strip after a delay. | |
| 194 if (x < display_area_.x()) { | |
| 195 x = display_area_.x(); | |
| 196 panel->set_has_temporary_layout(true); | |
| 197 MessageLoop::current()->PostDelayedTask( | |
| 198 FROM_HERE, | |
| 199 base::Bind(&DockedPanelStrip::DelayedMovePanelToOverflow, | |
| 200 base::Unretained(this), | |
| 201 panel), | |
| 202 base::TimeDelta::FromMilliseconds(PanelManager::AdjustTimeInterval( | |
| 203 kMoveNewPanelToOverflowDelayMs))); | |
| 204 } | |
| 205 panel->Initialize(gfx::Rect(x, y, width, height)); | |
| 171 | 206 |
| 172 if (panel->has_temporary_layout()) | 207 if (panel->has_temporary_layout()) |
| 173 panels_in_temporary_layout_.insert(panel); | 208 panels_in_temporary_layout_.insert(panel); |
| 174 else | 209 else |
| 175 panels_.push_back(panel); | 210 panels_.push_back(panel); |
| 176 } | 211 } |
| 177 | 212 |
| 178 int DockedPanelStrip::GetMaxPanelWidth() const { | 213 int DockedPanelStrip::GetMaxPanelWidth() const { |
| 179 return static_cast<int>(display_area_.width() * kPanelMaxWidthFactor); | 214 return static_cast<int>(display_area_.width() * kPanelMaxWidthFactor); |
| 180 } | 215 } |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 201 | 236 |
| 202 if (panel->has_temporary_layout()) { | 237 if (panel->has_temporary_layout()) { |
| 203 panels_in_temporary_layout_.erase(panel); | 238 panels_in_temporary_layout_.erase(panel); |
| 204 return; | 239 return; |
| 205 } | 240 } |
| 206 | 241 |
| 207 // Removing an element from the list will invalidate the iterator that refers | 242 // Removing an element from the list will invalidate the iterator that refers |
| 208 // to it. We need to update the iterator in that case. | 243 // to it. We need to update the iterator in that case. |
| 209 DCHECK(dragging_panel_current_iterator_ == panels_.end() || | 244 DCHECK(dragging_panel_current_iterator_ == panels_.end() || |
| 210 *dragging_panel_current_iterator_ != panel); | 245 *dragging_panel_current_iterator_ != panel); |
| 211 bool update_iterator_after_erase = | |
| 212 (dragging_panel_original_iterator_ != panels_.end() && | |
| 213 *dragging_panel_original_iterator_ == panel); | |
| 214 | 246 |
| 215 // Optimize for the common case of removing the last panel. | 247 // Optimize for the common case of removing the last panel. |
| 216 DCHECK(!panels_.empty()); | 248 DCHECK(!panels_.empty()); |
| 217 if (panels_.back() == panel) { | 249 if (panels_.back() == panel) { |
| 218 panels_.pop_back(); | 250 panels_.pop_back(); |
| 219 if (update_iterator_after_erase) | 251 |
| 220 dragging_panel_original_iterator_ = panels_.end(); | 252 // Update the saved panel placement if needed. This is because we might remove |
| 253 // |saved_panel_placement_.left_panel_|. | |
| 254 if (saved_panel_placement_.panel && | |
| 255 saved_panel_placement_.left_panel_ == panel) | |
| 256 saved_panel_placement_.left_panel_ = NULL; | |
|
Andrei
2012/03/07 22:55:13
saved_panel_placement_.left_panel_ may be simply g
jianli
2012/03/08 01:18:26
Good thought. I think we don't want to deal with i
| |
| 257 | |
| 221 // No need to refresh layout as the remaining panels are unaffected. | 258 // No need to refresh layout as the remaining panels are unaffected. |
| 222 // Just check if other panels can now fit in the freed up space. | 259 // Just check if other panels can now fit in the freed up space. |
| 223 panel_manager_->MovePanelsOutOfOverflowIfCanFit(); | 260 panel_manager_->MovePanelsOutOfOverflowIfCanFit(); |
| 224 } else { | 261 } else { |
| 225 Panels::iterator iter = find(panels_.begin(), panels_.end(), panel); | 262 Panels::iterator iter = find(panels_.begin(), panels_.end(), panel); |
| 226 DCHECK(iter != panels_.end()); | 263 DCHECK(iter != panels_.end()); |
| 227 iter = panels_.erase(iter); | 264 iter = panels_.erase(iter); |
| 228 if (update_iterator_after_erase) | 265 |
| 229 dragging_panel_original_iterator_ = iter; | 266 // Update the saved panel placement if needed. This is because we might remove |
| 267 // |saved_panel_placement_.left_panel_|. | |
| 268 if (saved_panel_placement_.panel && | |
| 269 saved_panel_placement_.left_panel_ == panel) | |
| 270 saved_panel_placement_.left_panel_ = *iter; | |
| 271 | |
| 230 RefreshLayout(); | 272 RefreshLayout(); |
| 231 } | 273 } |
| 232 } | 274 } |
| 233 | 275 |
| 234 bool DockedPanelStrip::CanShowPanelAsActive(const Panel* panel) const { | 276 bool DockedPanelStrip::CanShowPanelAsActive(const Panel* panel) const { |
| 235 // Panels with temporary layout cannot be shown as active. | 277 // Panels with temporary layout cannot be shown as active. |
| 236 return !panel->has_temporary_layout(); | 278 return !panel->has_temporary_layout(); |
| 237 } | 279 } |
| 238 | 280 |
| 281 void DockedPanelStrip::SavePanelPlacement(Panel* panel) { | |
| 282 DCHECK(!saved_panel_placement_.panel); | |
| 283 | |
| 284 saved_panel_placement_.panel = panel; | |
| 285 | |
| 286 // To recover panel to its original placement, we only need to track the panel | |
| 287 // that is placed after it. | |
| 288 Panels::iterator iter = find(panels_.begin(), panels_.end(), panel); | |
| 289 DCHECK(iter != panels_.end()); | |
| 290 ++iter; | |
| 291 saved_panel_placement_.left_panel_ = | |
| 292 (iter == panels_.end()) ? NULL : *iter; | |
| 293 } | |
| 294 | |
| 295 void DockedPanelStrip::RestorePanelToSavedPlacement() { | |
| 296 DCHECK(saved_panel_placement_.panel); | |
| 297 | |
| 298 Panel* panel = saved_panel_placement_.panel; | |
| 299 | |
| 300 // Find next panel after this panel. | |
| 301 Panels::iterator iter = std::find(panels_.begin(), panels_.end(), panel); | |
| 302 DCHECK(iter != panels_.end()); | |
| 303 Panels::iterator next_iter = iter; | |
| 304 next_iter++; | |
| 305 Panel* next_panel = (next_iter == panels_.end()) ? NULL : *iter; | |
| 306 | |
| 307 // If this panel is already in the right position, nothing to do. | |
| 308 if (next_panel != saved_panel_placement_.left_panel_) { | |
| 309 // Remove this panel from its current position. | |
| 310 panels_.erase(iter); | |
| 311 | |
| 312 // Insert this panel into its previous position. | |
| 313 if (saved_panel_placement_.left_panel_) { | |
| 314 Panels::iterator iter_to_insert_before = std::find(panels_.begin(), | |
| 315 panels_.end(), saved_panel_placement_.left_panel_); | |
| 316 DCHECK(iter_to_insert_before != panels_.end()); | |
| 317 panels_.insert(iter_to_insert_before, panel); | |
| 318 } else { | |
| 319 panels_.push_back(panel); | |
| 320 } | |
| 321 } | |
| 322 | |
| 323 RefreshLayout(); | |
| 324 | |
| 325 DiscardSavedPanelPlacement(); | |
| 326 } | |
| 327 | |
| 328 void DockedPanelStrip::DiscardSavedPanelPlacement() { | |
| 329 DCHECK(saved_panel_placement_.panel); | |
| 330 saved_panel_placement_.panel = NULL; | |
| 331 } | |
| 332 | |
| 239 bool DockedPanelStrip::CanDragPanel(const Panel* panel) const { | 333 bool DockedPanelStrip::CanDragPanel(const Panel* panel) const { |
| 240 // Only the panels having temporary layout can't be dragged. | 334 // Only the panels having temporary layout can't be dragged. |
| 241 return !panel->has_temporary_layout(); | 335 return !panel->has_temporary_layout(); |
| 242 } | 336 } |
| 243 | 337 |
| 244 Panel* DockedPanelStrip::dragging_panel() const { | 338 void DockedPanelStrip::StartDraggingPanelWithinStrip(Panel* panel) { |
| 245 return dragging_panel_current_iterator_ == panels_.end() ? NULL : | |
| 246 *dragging_panel_current_iterator_; | |
| 247 } | |
| 248 | |
| 249 void DockedPanelStrip::StartDraggingPanel(Panel* panel) { | |
| 250 dragging_panel_current_iterator_ = | 339 dragging_panel_current_iterator_ = |
| 251 find(panels_.begin(), panels_.end(), panel); | 340 find(panels_.begin(), panels_.end(), panel); |
| 252 DCHECK(dragging_panel_current_iterator_ != panels_.end()); | 341 DCHECK(dragging_panel_current_iterator_ != panels_.end()); |
| 253 dragging_panel_original_iterator_ = dragging_panel_current_iterator_; | |
| 254 } | 342 } |
| 255 | 343 |
| 256 void DockedPanelStrip::DragPanel(Panel* panel, int delta_x, int delta_y) { | 344 void DockedPanelStrip::DragPanelWithinStrip(Panel* panel, |
| 345 int delta_x, | |
| 346 int delta_y) { | |
| 257 if (!delta_x) | 347 if (!delta_x) |
| 258 return; | 348 return; |
| 259 | 349 |
| 260 // Moves this panel to the dragging position. | 350 // Moves this panel to the dragging position. |
| 261 gfx::Rect new_bounds(panel->GetBounds()); | 351 gfx::Rect new_bounds(panel->GetBounds()); |
| 262 new_bounds.set_x(new_bounds.x() + delta_x); | 352 new_bounds.set_x(new_bounds.x() + delta_x); |
| 263 panel->SetPanelBounds(new_bounds); | 353 panel->SetPanelBounds(new_bounds); |
| 264 | 354 |
| 265 // Checks and processes other affected panels. | 355 // Checks and processes other affected panels. |
| 266 if (delta_x > 0) | 356 if (delta_x > 0) |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 319 break; | 409 break; |
| 320 | 410 |
| 321 // Swaps the contents and makes |dragging_panel_current_iterator_| refers | 411 // Swaps the contents and makes |dragging_panel_current_iterator_| refers |
| 322 // to the new position. | 412 // to the new position. |
| 323 *dragging_panel_current_iterator_ = current_panel; | 413 *dragging_panel_current_iterator_ = current_panel; |
| 324 *current_panel_iterator = dragging_panel; | 414 *current_panel_iterator = dragging_panel; |
| 325 dragging_panel_current_iterator_ = current_panel_iterator; | 415 dragging_panel_current_iterator_ = current_panel_iterator; |
| 326 } | 416 } |
| 327 } | 417 } |
| 328 | 418 |
| 329 void DockedPanelStrip::EndDraggingPanel(Panel* panel, bool cancelled) { | 419 void DockedPanelStrip::EndDraggingPanelWithinStrip(Panel* panel, bool aborted) { |
| 330 if (cancelled) { | 420 dragging_panel_current_iterator_ = panels_.end(); |
| 331 if (dragging_panel_current_iterator_ != dragging_panel_original_iterator_) { | |
| 332 // Find out if the dragging panel should be moved toward the end/beginning | |
| 333 // of the list. | |
| 334 bool move_towards_end_of_list = true; | |
| 335 for (Panels::iterator iter = dragging_panel_original_iterator_; | |
| 336 iter != panels_.end(); ++iter) { | |
| 337 if (iter == dragging_panel_current_iterator_) { | |
| 338 move_towards_end_of_list = false; | |
| 339 break; | |
| 340 } | |
| 341 } | |
| 342 | 421 |
| 343 // Move the dragging panel back to its original position by swapping it | 422 // Calls RefreshLayout to update the dragging panel to its final position |
| 344 // with its adjacent element until it reach its original position. | 423 // when the drag ends normally. Otherwise, the drag within this strip is |
| 345 while (dragging_panel_current_iterator_ != | 424 // aborted because either the drag enters other strip or the drag is |
| 346 dragging_panel_original_iterator_) { | 425 // cancelled. Either way, we don't need to do anything here and let the drag |
| 347 Panels::iterator next_iter = dragging_panel_current_iterator_; | 426 // controller handle the inter-strip transition or the drag cancellation. |
| 348 if (move_towards_end_of_list) | 427 if (!aborted) |
| 349 ++next_iter; | 428 RefreshLayout(); |
| 350 else | |
| 351 --next_iter; | |
| 352 iter_swap(dragging_panel_current_iterator_, next_iter); | |
| 353 dragging_panel_current_iterator_ = next_iter; | |
| 354 } | |
| 355 } | |
| 356 } | |
| 357 | |
| 358 dragging_panel_current_iterator_ = dragging_panel_original_iterator_ = | |
| 359 panels_.end(); | |
| 360 | |
| 361 RefreshLayout(); | |
| 362 } | 429 } |
| 363 | 430 |
| 364 void DockedPanelStrip::OnPanelExpansionStateChanged(Panel* panel) { | 431 void DockedPanelStrip::OnPanelExpansionStateChanged(Panel* panel) { |
| 365 gfx::Size size = panel->restored_size(); | 432 gfx::Size size = panel->restored_size(); |
| 366 Panel::ExpansionState expansion_state = panel->expansion_state(); | 433 Panel::ExpansionState expansion_state = panel->expansion_state(); |
| 367 Panel::ExpansionState old_state = panel->old_expansion_state(); | 434 Panel::ExpansionState old_state = panel->old_expansion_state(); |
| 368 switch (expansion_state) { | 435 switch (expansion_state) { |
| 369 case Panel::EXPANDED: | 436 case Panel::EXPANDED: |
| 370 if (old_state == Panel::TITLE_ONLY || old_state == Panel::MINIMIZED) | 437 if (old_state == Panel::TITLE_ONLY || old_state == Panel::MINIMIZED) |
| 371 DecrementMinimizedPanels(); | 438 DecrementMinimizedPanels(); |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 514 for (Panels::const_iterator iter = panels_.begin(); | 581 for (Panels::const_iterator iter = panels_.begin(); |
| 515 iter != panels_.end(); ++iter) { | 582 iter != panels_.end(); ++iter) { |
| 516 Panel* panel = *iter; | 583 Panel* panel = *iter; |
| 517 Panel::ExpansionState state = panel->expansion_state(); | 584 Panel::ExpansionState state = panel->expansion_state(); |
| 518 // Skip the expanded panel. | 585 // Skip the expanded panel. |
| 519 if (state == Panel::EXPANDED) | 586 if (state == Panel::EXPANDED) |
| 520 continue; | 587 continue; |
| 521 | 588 |
| 522 // If the panel is showing titlebar only, we want to keep it up when it is | 589 // If the panel is showing titlebar only, we want to keep it up when it is |
| 523 // being dragged. | 590 // being dragged. |
| 524 if (state == Panel::TITLE_ONLY && panel == dragging_panel()) | 591 if (state == Panel::TITLE_ONLY && panel->in_preview_mode()) |
| 525 return true; | 592 return true; |
| 526 | 593 |
| 527 // We do not want to bring up other minimized panels if the mouse is over | 594 // We do not want to bring up other minimized panels if the mouse is over |
| 528 // the panel that pops up the titlebar to attract attention. | 595 // the panel that pops up the titlebar to attract attention. |
| 529 if (panel->IsDrawingAttention()) | 596 if (panel->IsDrawingAttention()) |
| 530 continue; | 597 continue; |
| 531 | 598 |
| 532 gfx::Rect bounds = panel->GetBounds(); | 599 gfx::Rect bounds = panel->GetBounds(); |
| 533 if (bounds.x() <= mouse_x && mouse_x <= bounds.right() && | 600 if (bounds.x() <= mouse_x && mouse_x <= bounds.right() && |
| 534 mouse_y >= bounds.y()) | 601 mouse_y >= bounds.y()) |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 679 int DockedPanelStrip::FitPanelWithWidth(int width) { | 746 int DockedPanelStrip::FitPanelWithWidth(int width) { |
| 680 int x = GetRightMostAvailablePosition() - width; | 747 int x = GetRightMostAvailablePosition() - width; |
| 681 if (x < display_area_.x()) { | 748 if (x < display_area_.x()) { |
| 682 // Insufficient space for the requested width. Bump panels to overflow. | 749 // Insufficient space for the requested width. Bump panels to overflow. |
| 683 Panel* last_panel_to_send_to_overflow; | 750 Panel* last_panel_to_send_to_overflow; |
| 684 for (Panels::reverse_iterator iter = panels_.rbegin(); | 751 for (Panels::reverse_iterator iter = panels_.rbegin(); |
| 685 iter != panels_.rend(); ++iter) { | 752 iter != panels_.rend(); ++iter) { |
| 686 last_panel_to_send_to_overflow = *iter; | 753 last_panel_to_send_to_overflow = *iter; |
| 687 x = last_panel_to_send_to_overflow->GetRestoredBounds().right() - width; | 754 x = last_panel_to_send_to_overflow->GetRestoredBounds().right() - width; |
| 688 if (x >= display_area_.x()) { | 755 if (x >= display_area_.x()) { |
| 689 panel_manager_->MovePanelsToOverflow(last_panel_to_send_to_overflow); | 756 panel_manager_->MovePanelsToOverflow(last_panel_to_send_to_overflow); |
|
Andrei
2012/03/07 22:55:13
This may move the panel in preview mode to overflo
jianli
2012/03/08 01:18:26
Yes, we have potential problem here and it has alr
| |
| 690 break; | 757 break; |
| 691 } | 758 } |
| 692 } | 759 } |
| 693 } | 760 } |
| 694 return x; | 761 return x; |
| 695 } | 762 } |
| 696 | 763 |
| 697 void DockedPanelStrip::RefreshLayout() { | 764 void DockedPanelStrip::RefreshLayout() { |
| 698 int rightmost_position = StartingRightPosition(); | 765 int rightmost_position = StartingRightPosition(); |
| 699 | 766 |
| 700 Panels::const_iterator panel_iter = panels_.begin(); | 767 Panels::const_iterator panel_iter = panels_.begin(); |
| 701 for (; panel_iter != panels_.end(); ++panel_iter) { | 768 for (; panel_iter != panels_.end(); ++panel_iter) { |
| 702 Panel* panel = *panel_iter; | 769 Panel* panel = *panel_iter; |
| 703 gfx::Rect new_bounds(panel->GetBounds()); | 770 gfx::Rect new_bounds(panel->GetBounds()); |
| 704 int x = rightmost_position - new_bounds.width(); | 771 int x = rightmost_position - new_bounds.width(); |
| 705 | 772 |
| 706 if (x < display_area_.x()) | 773 if (x < display_area_.x()) |
| 707 break; | 774 break; |
| 708 | 775 |
| 709 // Don't update the docked panel that is currently dragged. | 776 // Don't update the docked panel that is in preview mode. |
| 710 if (panel != dragging_panel()) { | 777 if (!panel->in_preview_mode()) { |
| 711 new_bounds.set_x(x); | 778 new_bounds.set_x(x); |
| 712 new_bounds.set_y( | 779 new_bounds.set_y( |
| 713 GetBottomPositionForExpansionState(panel->expansion_state()) - | 780 GetBottomPositionForExpansionState(panel->expansion_state()) - |
| 714 new_bounds.height()); | 781 new_bounds.height()); |
| 715 panel->SetPanelBounds(new_bounds); | 782 panel->SetPanelBounds(new_bounds); |
| 716 } | 783 } |
| 717 | 784 |
| 718 rightmost_position = x - kPanelsHorizontalSpacing; | 785 rightmost_position = x - kPanelsHorizontalSpacing; |
| 719 } | 786 } |
| 720 | 787 |
| 721 // Add/remove panels from/to overflow. A change in work area or the | 788 // Add/remove panels from/to overflow. A change in work area or the |
| 722 // resize/removal of a panel may affect how many panels fit in the strip. | 789 // resize/removal of a panel may affect how many panels fit in the strip. |
| 723 if (panel_iter != panels_.end()) | 790 if (panel_iter != panels_.end()) |
| 724 panel_manager_->MovePanelsToOverflow(*panel_iter); | 791 panel_manager_->MovePanelsToOverflow(*panel_iter); |
|
Andrei
2012/03/07 22:55:13
This may move the panel in preview mode to overflo
jianli
2012/03/08 01:18:26
ditto.
| |
| 725 else | 792 else |
| 726 panel_manager_->MovePanelsOutOfOverflowIfCanFit(); | 793 panel_manager_->MovePanelsOutOfOverflowIfCanFit(); |
| 727 } | 794 } |
| 728 | 795 |
| 729 void DockedPanelStrip::DelayedMovePanelToOverflow(Panel* panel) { | 796 void DockedPanelStrip::DelayedMovePanelToOverflow(Panel* panel) { |
| 730 if (panels_in_temporary_layout_.erase(panel)) { | 797 if (panels_in_temporary_layout_.erase(panel)) { |
| 731 DCHECK(panel->has_temporary_layout()); | 798 DCHECK(panel->has_temporary_layout()); |
| 732 panel_manager_->MovePanelToStrip(panel, PanelStrip::IN_OVERFLOW); | 799 panel_manager_->MovePanelToStrip(panel, PanelStrip::IN_OVERFLOW); |
| 733 } | 800 } |
| 734 } | 801 } |
| 735 | 802 |
| 736 void DockedPanelStrip::CloseAll() { | 803 void DockedPanelStrip::CloseAll() { |
| 737 // This should only be called at the end of tests to clean up. | 804 // This should only be called at the end of tests to clean up. |
| 738 DCHECK(panels_in_temporary_layout_.empty()); | 805 DCHECK(panels_in_temporary_layout_.empty()); |
| 739 | 806 |
| 740 // Make a copy of the iterator as closing panels can modify the vector. | 807 // Make a copy of the iterator as closing panels can modify the vector. |
| 741 Panels panels_copy = panels_; | 808 Panels panels_copy = panels_; |
| 742 | 809 |
| 743 // Start from the bottom to avoid reshuffling. | 810 // Start from the bottom to avoid reshuffling. |
| 744 for (Panels::reverse_iterator iter = panels_copy.rbegin(); | 811 for (Panels::reverse_iterator iter = panels_copy.rbegin(); |
| 745 iter != panels_copy.rend(); ++iter) | 812 iter != panels_copy.rend(); ++iter) |
| 746 (*iter)->Close(); | 813 (*iter)->Close(); |
| 747 } | 814 } |
| OLD | NEW |