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, |
| 88 PositioningMask positioning_mask) { |
87 DCHECK_NE(this, panel->panel_strip()); | 89 DCHECK_NE(this, panel->panel_strip()); |
88 panel->SetPanelStrip(this); | 90 panel->SetPanelStrip(this); |
89 | 91 |
| 92 bool known_position = (positioning_mask & KNOWN_POSITION) != 0; |
| 93 bool update_bounds = (positioning_mask & DO_NOT_UPDATE_BOUNDS) == 0; |
| 94 |
| 95 if (!panel->initialized()) { |
| 96 DCHECK(!known_position && update_bounds); |
| 97 InsertNewlyCreatedPanel(panel); |
| 98 } else if (known_position) { |
| 99 DCHECK(update_bounds); |
| 100 InsertExistingPanelAtKnownPosition(panel); |
| 101 } else { |
| 102 InsertExistingPanelAtDefaultPosition(panel, update_bounds); |
| 103 } |
| 104 |
90 // Always update limits, even on existing panels, in case the limits changed | 105 // Always update limits, even on existing panels, in case the limits changed |
91 // while panel was out of the strip. | 106 // while panel was out of the strip. |
92 int max_panel_width = GetMaxPanelWidth(); | 107 int max_panel_width = GetMaxPanelWidth(); |
93 int max_panel_height = GetMaxPanelHeight(); | 108 int max_panel_height = GetMaxPanelHeight(); |
94 panel->SetSizeRange(gfx::Size(kPanelMinWidth, kPanelMinHeight), | 109 panel->SetSizeRange(gfx::Size(kPanelMinWidth, kPanelMinHeight), |
95 gfx::Size(max_panel_width, max_panel_height)); | 110 gfx::Size(max_panel_width, max_panel_height)); |
96 | 111 |
| 112 panel->SetAppIconVisibility(true); |
| 113 panel->SetAlwaysOnTop(true); |
| 114 } |
| 115 |
| 116 void DockedPanelStrip::InsertNewlyCreatedPanel(Panel* panel) { |
| 117 DCHECK(!panel->initialized()); |
| 118 |
| 119 int max_panel_width = GetMaxPanelWidth(); |
| 120 int max_panel_height = GetMaxPanelHeight(); |
| 121 gfx::Size restored_size = panel->restored_size(); |
| 122 int height = restored_size.height(); |
| 123 int width = restored_size.width(); |
| 124 |
| 125 // Initialize the newly created panel. Does not bump any panels from strip. |
| 126 if (height == 0 && width == 0 && panel_manager_->auto_sizing_enabled()) { |
| 127 // Auto resizable is enabled only if no initial size is provided. |
| 128 panel->SetAutoResizable(true); |
| 129 } else { |
| 130 if (height == 0) |
| 131 height = width / kPanelDefaultWidthToHeightRatio; |
| 132 if (width == 0) |
| 133 width = height * kPanelDefaultWidthToHeightRatio; |
| 134 } |
| 135 |
| 136 // Constrain sizes to limits. |
| 137 if (width < kPanelMinWidth) |
| 138 width = kPanelMinWidth; |
| 139 else if (width > max_panel_width) |
| 140 width = max_panel_width; |
| 141 |
| 142 if (height < kPanelMinHeight) |
| 143 height = kPanelMinHeight; |
| 144 else if (height > max_panel_height) |
| 145 height = max_panel_height; |
| 146 |
| 147 panel->set_restored_size(gfx::Size(width, height)); |
| 148 int x = GetRightMostAvailablePosition() - width; |
| 149 int y = display_area_.bottom() - height; |
| 150 |
| 151 // Keep panel visible in the strip even if overlap would occur. |
| 152 // Panel is moved to overflow from the strip after a delay. |
| 153 if (x < display_area_.x()) { |
| 154 x = display_area_.x(); |
| 155 panel->set_has_temporary_layout(true); |
| 156 MessageLoop::current()->PostDelayedTask( |
| 157 FROM_HERE, |
| 158 base::Bind(&DockedPanelStrip::DelayedMovePanelToOverflow, |
| 159 base::Unretained(this), |
| 160 panel), |
| 161 base::TimeDelta::FromMilliseconds(PanelManager::AdjustTimeInterval( |
| 162 kMoveNewPanelToOverflowDelayMs))); |
| 163 } |
| 164 panel->Initialize(gfx::Rect(x, y, width, height)); |
| 165 |
| 166 if (panel->has_temporary_layout()) |
| 167 panels_in_temporary_layout_.insert(panel); |
| 168 else |
| 169 panels_.push_back(panel); |
| 170 } |
| 171 |
| 172 void DockedPanelStrip::InsertExistingPanelAtKnownPosition(Panel* panel) { |
| 173 DCHECK(panel->initialized()); |
| 174 |
| 175 FitPanelWithWidth(panel->GetBounds().width()); |
| 176 |
| 177 int x = panel->GetBounds().x(); |
| 178 Panels::iterator iter = panels_.begin(); |
| 179 for (; iter != panels_.end(); ++iter) |
| 180 if (x > (*iter)->GetBounds().x()) |
| 181 break; |
| 182 panels_.insert(iter, panel); |
| 183 |
| 184 // This will automatically update all affected panels due to the insertion. |
| 185 if (iter != panels_.end()) |
| 186 RefreshLayout(); |
| 187 } |
| 188 |
| 189 void DockedPanelStrip::InsertExistingPanelAtDefaultPosition( |
| 190 Panel* panel, bool update_bounds) { |
| 191 DCHECK(panel->initialized()); |
| 192 |
97 gfx::Size restored_size = panel->restored_size(); | 193 gfx::Size restored_size = panel->restored_size(); |
98 int height = restored_size.height(); | 194 int height = restored_size.height(); |
99 int width = restored_size.width(); | 195 int width = restored_size.width(); |
100 | 196 |
101 if (panel->initialized()) { | 197 int x = FitPanelWithWidth(width); |
102 int x = FitPanelWithWidth(width); | |
103 | 198 |
| 199 if (update_bounds) { |
104 Panel::ExpansionState expansion_state_to_restore; | 200 Panel::ExpansionState expansion_state_to_restore; |
105 if (panel->expansion_state() == Panel::EXPANDED) { | 201 if (panel->expansion_state() == Panel::EXPANDED) { |
106 expansion_state_to_restore = Panel::EXPANDED; | 202 expansion_state_to_restore = Panel::EXPANDED; |
107 } else { | 203 } else { |
108 if (are_titlebars_up_ || panel->IsDrawingAttention()) { | 204 if (are_titlebars_up_ || panel->IsDrawingAttention()) { |
109 expansion_state_to_restore = Panel::TITLE_ONLY; | 205 expansion_state_to_restore = Panel::TITLE_ONLY; |
110 height = panel->TitleOnlyHeight(); | 206 height = panel->TitleOnlyHeight(); |
111 } else { | 207 } else { |
112 expansion_state_to_restore = Panel::MINIMIZED; | 208 expansion_state_to_restore = Panel::MINIMIZED; |
113 height = Panel::kMinimizedPanelHeight; | 209 height = Panel::kMinimizedPanelHeight; |
114 } | 210 } |
115 IncrementMinimizedPanels(); | 211 IncrementMinimizedPanels(); |
116 } | 212 } |
117 int y = | 213 int y = |
118 GetBottomPositionForExpansionState(expansion_state_to_restore) - height; | 214 GetBottomPositionForExpansionState(expansion_state_to_restore) - height; |
119 panel->SetPanelBounds(gfx::Rect(x, y, width, height)); | 215 panel->SetPanelBounds(gfx::Rect(x, y, width, height)); |
120 | 216 |
121 // Update the minimized state to reflect current titlebar mode. | 217 // Update the minimized state to reflect current titlebar mode. |
122 // Do this AFTER setting panel bounds to avoid an extra bounds change. | 218 // Do this AFTER setting panel bounds to avoid an extra bounds change. |
123 if (panel->expansion_state() != Panel::EXPANDED) | 219 if (panel->expansion_state() != Panel::EXPANDED) |
124 panel->SetExpansionState(expansion_state_to_restore); | 220 panel->SetExpansionState(expansion_state_to_restore); |
125 | |
126 } else { | |
127 // Initialize the newly created panel. Does not bump any panels from strip. | |
128 if (height == 0 && width == 0 && panel_manager_->auto_sizing_enabled()) { | |
129 // Auto resizable is enabled only if no initial size is provided. | |
130 panel->SetAutoResizable(true); | |
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 } | 221 } |
168 | 222 |
169 // Set panel properties for this strip. | 223 panels_.push_back(panel); |
170 panel->SetAppIconVisibility(true); | |
171 | |
172 if (panel->has_temporary_layout()) | |
173 panels_in_temporary_layout_.insert(panel); | |
174 else | |
175 panels_.push_back(panel); | |
176 } | 224 } |
177 | 225 |
178 int DockedPanelStrip::GetMaxPanelWidth() const { | 226 int DockedPanelStrip::GetMaxPanelWidth() const { |
179 return static_cast<int>(display_area_.width() * kPanelMaxWidthFactor); | 227 return static_cast<int>(display_area_.width() * kPanelMaxWidthFactor); |
180 } | 228 } |
181 | 229 |
182 int DockedPanelStrip::GetMaxPanelHeight() const { | 230 int DockedPanelStrip::GetMaxPanelHeight() const { |
183 return display_area_.height(); | 231 return display_area_.height(); |
184 } | 232 } |
185 | 233 |
(...skipping 15 matching lines...) Expand all Loading... |
201 | 249 |
202 if (panel->has_temporary_layout()) { | 250 if (panel->has_temporary_layout()) { |
203 panels_in_temporary_layout_.erase(panel); | 251 panels_in_temporary_layout_.erase(panel); |
204 return; | 252 return; |
205 } | 253 } |
206 | 254 |
207 // Removing an element from the list will invalidate the iterator that refers | 255 // Removing an element from the list will invalidate the iterator that refers |
208 // to it. We need to update the iterator in that case. | 256 // to it. We need to update the iterator in that case. |
209 DCHECK(dragging_panel_current_iterator_ == panels_.end() || | 257 DCHECK(dragging_panel_current_iterator_ == panels_.end() || |
210 *dragging_panel_current_iterator_ != panel); | 258 *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 | 259 |
215 // Optimize for the common case of removing the last panel. | 260 // Optimize for the common case of removing the last panel. |
216 DCHECK(!panels_.empty()); | 261 DCHECK(!panels_.empty()); |
217 if (panels_.back() == panel) { | 262 if (panels_.back() == panel) { |
218 panels_.pop_back(); | 263 panels_.pop_back(); |
219 if (update_iterator_after_erase) | 264 |
220 dragging_panel_original_iterator_ = panels_.end(); | 265 // Update the saved panel placement if needed. This is because we might remove |
| 266 // |saved_panel_placement_.left_panel|. |
| 267 // Note: if |left_panel| moves to overflow and then comes back, it is OK to |
| 268 // restore the panel to the end of list since we do not want to deal with |
| 269 // this case specially. |
| 270 if (saved_panel_placement_.panel && |
| 271 saved_panel_placement_.left_panel == panel) |
| 272 saved_panel_placement_.left_panel = NULL; |
| 273 |
221 // No need to refresh layout as the remaining panels are unaffected. | 274 // 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. | 275 // Just check if other panels can now fit in the freed up space. |
223 panel_manager_->MovePanelsOutOfOverflowIfCanFit(); | 276 panel_manager_->MovePanelsOutOfOverflowIfCanFit(); |
224 } else { | 277 } else { |
225 Panels::iterator iter = find(panels_.begin(), panels_.end(), panel); | 278 Panels::iterator iter = find(panels_.begin(), panels_.end(), panel); |
226 DCHECK(iter != panels_.end()); | 279 DCHECK(iter != panels_.end()); |
227 iter = panels_.erase(iter); | 280 iter = panels_.erase(iter); |
228 if (update_iterator_after_erase) | 281 |
229 dragging_panel_original_iterator_ = iter; | 282 // Update the saved panel placement if needed. This is because we might remove |
| 283 // |saved_panel_placement_.left_panel|. |
| 284 if (saved_panel_placement_.panel && |
| 285 saved_panel_placement_.left_panel == panel) |
| 286 saved_panel_placement_.left_panel = *iter; |
| 287 |
230 RefreshLayout(); | 288 RefreshLayout(); |
231 } | 289 } |
232 } | 290 } |
233 | 291 |
234 bool DockedPanelStrip::CanShowPanelAsActive(const Panel* panel) const { | 292 bool DockedPanelStrip::CanShowPanelAsActive(const Panel* panel) const { |
235 // Panels with temporary layout cannot be shown as active. | 293 // Panels with temporary layout cannot be shown as active. |
236 return !panel->has_temporary_layout(); | 294 return !panel->has_temporary_layout(); |
237 } | 295 } |
238 | 296 |
| 297 void DockedPanelStrip::SavePanelPlacement(Panel* panel) { |
| 298 DCHECK(!saved_panel_placement_.panel); |
| 299 |
| 300 saved_panel_placement_.panel = panel; |
| 301 |
| 302 // To recover panel to its original placement, we only need to track the panel |
| 303 // that is placed after it. |
| 304 Panels::iterator iter = find(panels_.begin(), panels_.end(), panel); |
| 305 DCHECK(iter != panels_.end()); |
| 306 ++iter; |
| 307 saved_panel_placement_.left_panel = (iter == panels_.end()) ? NULL : *iter; |
| 308 } |
| 309 |
| 310 void DockedPanelStrip::RestorePanelToSavedPlacement() { |
| 311 DCHECK(saved_panel_placement_.panel); |
| 312 |
| 313 Panel* panel = saved_panel_placement_.panel; |
| 314 |
| 315 // Find next panel after this panel. |
| 316 Panels::iterator iter = std::find(panels_.begin(), panels_.end(), panel); |
| 317 DCHECK(iter != panels_.end()); |
| 318 Panels::iterator next_iter = iter; |
| 319 next_iter++; |
| 320 Panel* next_panel = (next_iter == panels_.end()) ? NULL : *iter; |
| 321 |
| 322 // Restoring is only needed when this panel is not in the right position. |
| 323 if (next_panel != saved_panel_placement_.left_panel) { |
| 324 // Remove this panel from its current position. |
| 325 panels_.erase(iter); |
| 326 |
| 327 // Insert this panel into its previous position. |
| 328 if (saved_panel_placement_.left_panel) { |
| 329 Panels::iterator iter_to_insert_before = std::find(panels_.begin(), |
| 330 panels_.end(), saved_panel_placement_.left_panel); |
| 331 DCHECK(iter_to_insert_before != panels_.end()); |
| 332 panels_.insert(iter_to_insert_before, panel); |
| 333 } else { |
| 334 panels_.push_back(panel); |
| 335 } |
| 336 } |
| 337 |
| 338 RefreshLayout(); |
| 339 |
| 340 DiscardSavedPanelPlacement(); |
| 341 } |
| 342 |
| 343 void DockedPanelStrip::DiscardSavedPanelPlacement() { |
| 344 DCHECK(saved_panel_placement_.panel); |
| 345 saved_panel_placement_.panel = NULL; |
| 346 saved_panel_placement_.left_panel = NULL; |
| 347 } |
| 348 |
239 bool DockedPanelStrip::CanDragPanel(const Panel* panel) const { | 349 bool DockedPanelStrip::CanDragPanel(const Panel* panel) const { |
240 // Only the panels having temporary layout can't be dragged. | 350 // Only the panels having temporary layout can't be dragged. |
241 return !panel->has_temporary_layout(); | 351 return !panel->has_temporary_layout(); |
242 } | 352 } |
243 | 353 |
244 Panel* DockedPanelStrip::dragging_panel() const { | 354 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_ = | 355 dragging_panel_current_iterator_ = |
251 find(panels_.begin(), panels_.end(), panel); | 356 find(panels_.begin(), panels_.end(), panel); |
252 DCHECK(dragging_panel_current_iterator_ != panels_.end()); | 357 DCHECK(dragging_panel_current_iterator_ != panels_.end()); |
253 dragging_panel_original_iterator_ = dragging_panel_current_iterator_; | |
254 } | 358 } |
255 | 359 |
256 void DockedPanelStrip::DragPanel(Panel* panel, int delta_x, int delta_y) { | 360 void DockedPanelStrip::DragPanelWithinStrip(Panel* panel, |
| 361 int delta_x, |
| 362 int delta_y) { |
257 if (!delta_x) | 363 if (!delta_x) |
258 return; | 364 return; |
259 | 365 |
260 // Moves this panel to the dragging position. | 366 // Moves this panel to the dragging position. |
261 gfx::Rect new_bounds(panel->GetBounds()); | 367 gfx::Rect new_bounds(panel->GetBounds()); |
262 new_bounds.set_x(new_bounds.x() + delta_x); | 368 new_bounds.set_x(new_bounds.x() + delta_x); |
263 panel->SetPanelBounds(new_bounds); | 369 panel->SetPanelBounds(new_bounds); |
264 | 370 |
265 // Checks and processes other affected panels. | 371 // Checks and processes other affected panels. |
266 if (delta_x > 0) | 372 if (delta_x > 0) |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
319 break; | 425 break; |
320 | 426 |
321 // Swaps the contents and makes |dragging_panel_current_iterator_| refers | 427 // Swaps the contents and makes |dragging_panel_current_iterator_| refers |
322 // to the new position. | 428 // to the new position. |
323 *dragging_panel_current_iterator_ = current_panel; | 429 *dragging_panel_current_iterator_ = current_panel; |
324 *current_panel_iterator = dragging_panel; | 430 *current_panel_iterator = dragging_panel; |
325 dragging_panel_current_iterator_ = current_panel_iterator; | 431 dragging_panel_current_iterator_ = current_panel_iterator; |
326 } | 432 } |
327 } | 433 } |
328 | 434 |
329 void DockedPanelStrip::EndDraggingPanel(Panel* panel, bool cancelled) { | 435 void DockedPanelStrip::EndDraggingPanelWithinStrip(Panel* panel, bool aborted) { |
330 if (cancelled) { | 436 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 | 437 |
343 // Move the dragging panel back to its original position by swapping it | 438 // Calls RefreshLayout to update the dragging panel to its final position |
344 // with its adjacent element until it reach its original position. | 439 // when the drag ends normally. Otherwise, the drag within this strip is |
345 while (dragging_panel_current_iterator_ != | 440 // aborted because either the drag enters other strip or the drag is |
346 dragging_panel_original_iterator_) { | 441 // cancelled. Either way, we don't need to do anything here and let the drag |
347 Panels::iterator next_iter = dragging_panel_current_iterator_; | 442 // controller handle the inter-strip transition or the drag cancellation. |
348 if (move_towards_end_of_list) | 443 if (!aborted) |
349 ++next_iter; | 444 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 } | 445 } |
363 | 446 |
364 void DockedPanelStrip::OnPanelExpansionStateChanged(Panel* panel) { | 447 void DockedPanelStrip::OnPanelExpansionStateChanged(Panel* panel) { |
365 gfx::Size size = panel->restored_size(); | 448 gfx::Size size = panel->restored_size(); |
366 Panel::ExpansionState expansion_state = panel->expansion_state(); | 449 Panel::ExpansionState expansion_state = panel->expansion_state(); |
367 Panel::ExpansionState old_state = panel->old_expansion_state(); | 450 Panel::ExpansionState old_state = panel->old_expansion_state(); |
368 switch (expansion_state) { | 451 switch (expansion_state) { |
369 case Panel::EXPANDED: | 452 case Panel::EXPANDED: |
370 if (old_state == Panel::TITLE_ONLY || old_state == Panel::MINIMIZED) | 453 if (old_state == Panel::TITLE_ONLY || old_state == Panel::MINIMIZED) |
371 DecrementMinimizedPanels(); | 454 DecrementMinimizedPanels(); |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
507 panel_manager_->display_settings_provider(); | 590 panel_manager_->display_settings_provider(); |
508 if (provider->IsAutoHidingDesktopBarEnabled( | 591 if (provider->IsAutoHidingDesktopBarEnabled( |
509 DisplaySettingsProvider::DESKTOP_BAR_ALIGNED_BOTTOM) && | 592 DisplaySettingsProvider::DESKTOP_BAR_ALIGNED_BOTTOM) && |
510 provider->GetDesktopBarVisibility( | 593 provider->GetDesktopBarVisibility( |
511 DisplaySettingsProvider::DESKTOP_BAR_ALIGNED_BOTTOM) == | 594 DisplaySettingsProvider::DESKTOP_BAR_ALIGNED_BOTTOM) == |
512 DisplaySettingsProvider::DESKTOP_BAR_VISIBLE && | 595 DisplaySettingsProvider::DESKTOP_BAR_VISIBLE && |
513 mouse_y >= display_area_.bottom()) | 596 mouse_y >= display_area_.bottom()) |
514 return true; | 597 return true; |
515 | 598 |
516 // Bring up titlebars if any panel needs the titlebar up. | 599 // Bring up titlebars if any panel needs the titlebar up. |
| 600 Panel* dragging_panel = dragging_panel_current_iterator_ == panels_.end() ? |
| 601 NULL : *dragging_panel_current_iterator_; |
517 for (Panels::const_iterator iter = panels_.begin(); | 602 for (Panels::const_iterator iter = panels_.begin(); |
518 iter != panels_.end(); ++iter) { | 603 iter != panels_.end(); ++iter) { |
519 Panel* panel = *iter; | 604 Panel* panel = *iter; |
520 Panel::ExpansionState state = panel->expansion_state(); | 605 Panel::ExpansionState state = panel->expansion_state(); |
521 // Skip the expanded panel. | 606 // Skip the expanded panel. |
522 if (state == Panel::EXPANDED) | 607 if (state == Panel::EXPANDED) |
523 continue; | 608 continue; |
524 | 609 |
525 // If the panel is showing titlebar only, we want to keep it up when it is | 610 // If the panel is showing titlebar only, we want to keep it up when it is |
526 // being dragged. | 611 // being dragged. |
527 if (state == Panel::TITLE_ONLY && panel == dragging_panel()) | 612 if (state == Panel::TITLE_ONLY && panel == dragging_panel) |
528 return true; | 613 return true; |
529 | 614 |
530 // We do not want to bring up other minimized panels if the mouse is over | 615 // 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. | 616 // the panel that pops up the titlebar to attract attention. |
532 if (panel->IsDrawingAttention()) | 617 if (panel->IsDrawingAttention()) |
533 continue; | 618 continue; |
534 | 619 |
535 gfx::Rect bounds = panel->GetBounds(); | 620 gfx::Rect bounds = panel->GetBounds(); |
536 if (bounds.x() <= mouse_x && mouse_x <= bounds.right() && | 621 if (bounds.x() <= mouse_x && mouse_x <= bounds.right() && |
537 mouse_y >= bounds.y()) | 622 mouse_y >= bounds.y()) |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
710 | 795 |
711 Panels::const_iterator panel_iter = panels_.begin(); | 796 Panels::const_iterator panel_iter = panels_.begin(); |
712 for (; panel_iter != panels_.end(); ++panel_iter) { | 797 for (; panel_iter != panels_.end(); ++panel_iter) { |
713 Panel* panel = *panel_iter; | 798 Panel* panel = *panel_iter; |
714 gfx::Rect new_bounds(panel->GetBounds()); | 799 gfx::Rect new_bounds(panel->GetBounds()); |
715 int x = rightmost_position - new_bounds.width(); | 800 int x = rightmost_position - new_bounds.width(); |
716 | 801 |
717 if (x < display_area_.x()) | 802 if (x < display_area_.x()) |
718 break; | 803 break; |
719 | 804 |
720 // Don't update the docked panel that is currently dragged. | 805 // Don't update the docked panel that is in preview mode. |
721 if (panel != dragging_panel()) { | 806 if (!panel->in_preview_mode()) { |
722 new_bounds.set_x(x); | 807 new_bounds.set_x(x); |
723 new_bounds.set_y( | 808 new_bounds.set_y( |
724 GetBottomPositionForExpansionState(panel->expansion_state()) - | 809 GetBottomPositionForExpansionState(panel->expansion_state()) - |
725 new_bounds.height()); | 810 new_bounds.height()); |
726 panel->SetPanelBounds(new_bounds); | 811 panel->SetPanelBounds(new_bounds); |
727 } | 812 } |
728 | 813 |
729 rightmost_position = x - kPanelsHorizontalSpacing; | 814 rightmost_position = x - kPanelsHorizontalSpacing; |
730 } | 815 } |
731 | 816 |
732 // Add/remove panels from/to overflow. A change in work area or the | 817 // Add/remove panels from/to overflow. A change in work area or the |
733 // resize/removal of a panel may affect how many panels fit in the strip. | 818 // resize/removal of a panel may affect how many panels fit in the strip. |
| 819 // TODO(jianli): Need to handle the case that panel in preview mode could be |
| 820 // moved to overflow. (http://crbug.com/117574) |
734 if (panel_iter != panels_.end()) | 821 if (panel_iter != panels_.end()) |
735 panel_manager_->MovePanelsToOverflow(*panel_iter); | 822 panel_manager_->MovePanelsToOverflow(*panel_iter); |
736 else | 823 else |
737 panel_manager_->MovePanelsOutOfOverflowIfCanFit(); | 824 panel_manager_->MovePanelsOutOfOverflowIfCanFit(); |
738 } | 825 } |
739 | 826 |
740 void DockedPanelStrip::DelayedMovePanelToOverflow(Panel* panel) { | 827 void DockedPanelStrip::DelayedMovePanelToOverflow(Panel* panel) { |
741 if (panels_in_temporary_layout_.erase(panel)) { | 828 if (panels_in_temporary_layout_.erase(panel)) { |
742 DCHECK(panel->has_temporary_layout()); | 829 DCHECK(panel->has_temporary_layout()); |
743 panel_manager_->MovePanelToStrip(panel, PanelStrip::IN_OVERFLOW); | 830 panel_manager_->MovePanelToStrip(panel, |
| 831 PanelStrip::IN_OVERFLOW, |
| 832 PanelStrip::DEFAULT_POSITION); |
744 } | 833 } |
745 } | 834 } |
746 | 835 |
747 void DockedPanelStrip::CloseAll() { | 836 void DockedPanelStrip::CloseAll() { |
748 // This should only be called at the end of tests to clean up. | 837 // This should only be called at the end of tests to clean up. |
749 DCHECK(panels_in_temporary_layout_.empty()); | 838 DCHECK(panels_in_temporary_layout_.empty()); |
750 | 839 |
751 // Make a copy of the iterator as closing panels can modify the vector. | 840 // Make a copy of the iterator as closing panels can modify the vector. |
752 Panels panels_copy = panels_; | 841 Panels panels_copy = panels_; |
753 | 842 |
754 // Start from the bottom to avoid reshuffling. | 843 // Start from the bottom to avoid reshuffling. |
755 for (Panels::reverse_iterator iter = panels_copy.rbegin(); | 844 for (Panels::reverse_iterator iter = panels_copy.rbegin(); |
756 iter != panels_copy.rend(); ++iter) | 845 iter != panels_copy.rend(); ++iter) |
757 (*iter)->Close(); | 846 (*iter)->Close(); |
758 } | 847 } |
OLD | NEW |