Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(118)

Side by Side Diff: chrome/browser/ui/panels/panel_overflow_strip.cc

Issue 8953040: Add overflow indicator count on Windows. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix trybot Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/ui/panels/panel_overflow_strip.h ('k') | chrome/chrome_browser.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/panel_overflow_strip.h" 5 #include "chrome/browser/ui/panels/panel_overflow_strip.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "chrome/browser/ui/panels/panel_manager.h" 8 #include "chrome/browser/ui/panels/panel_manager.h"
9 #include "chrome/browser/ui/panels/panel_mouse_watcher.h" 9 #include "chrome/browser/ui/panels/panel_mouse_watcher.h"
10 #include "chrome/browser/ui/panels/panel_overflow_indicator.h"
10 #include "chrome/browser/ui/panels/panel_strip.h" 11 #include "chrome/browser/ui/panels/panel_strip.h"
11 #include "chrome/common/chrome_notification_types.h" 12 #include "chrome/common/chrome_notification_types.h"
12 #include "content/public/browser/notification_service.h" 13 #include "content/public/browser/notification_service.h"
13 #include "ui/base/animation/slide_animation.h" 14 #include "ui/base/animation/slide_animation.h"
14 15
15 namespace { 16 namespace {
16 // The width of the overflow area that is expanded to show more info, i.e. 17 // The width of the overflow area that is expanded to show more info, i.e.
17 // titles, when the mouse hovers over the area. 18 // titles, when the mouse hovers over the area.
18 static const int kOverflowAreaHoverWidth = 200; 19 static const int kOverflowAreaHoverWidth = 200;
19 20
20 // Maximium number of overflow panels allowed to be shown. 21 // Maximium number of visible overflow panels when the mouse does not hover over
21 const size_t kMaxVisibleOverflowPanelsAllowed = 6; 22 // the overflow area.
23 const size_t kMaxVisibleOverflowPanels = 6;
24
25 // The ratio to determine the maximum number of visible overflow panels when the
26 // mouse hovers over the overflow area. These panels cannot occupy more than the
27 // fixed percentage of the display area height.
28 const double kHeightRatioForMaxVisibleOverflowPanelsOnHover = 0.67;
22 29
23 // This value is experimental and subjective. 30 // This value is experimental and subjective.
24 const int kOverflowHoverAnimationMs = 180; 31 const int kOverflowHoverAnimationMs = 180;
25 } 32 }
26 33
27 PanelOverflowStrip::PanelOverflowStrip(PanelManager* panel_manager) 34 PanelOverflowStrip::PanelOverflowStrip(PanelManager* panel_manager)
28 : panel_manager_(panel_manager), 35 : panel_manager_(panel_manager),
29 current_display_width_(0), 36 current_display_width_(0),
30 max_visible_panels_(kMaxVisibleOverflowPanelsAllowed), 37 max_visible_panels_(kMaxVisibleOverflowPanels),
38 max_visible_panels_on_hover_(0),
31 are_overflow_titles_shown_(false), 39 are_overflow_titles_shown_(false),
32 overflow_hover_animator_start_width_(0), 40 overflow_hover_animator_start_width_(0),
33 overflow_hover_animator_end_width_(0) { 41 overflow_hover_animator_end_width_(0) {
34 } 42 }
35 43
36 PanelOverflowStrip::~PanelOverflowStrip() { 44 PanelOverflowStrip::~PanelOverflowStrip() {
37 DCHECK(panels_.empty()); 45 DCHECK(panels_.empty());
46 DCHECK(!overflow_indicator_.get());
38 } 47 }
39 48
40 void PanelOverflowStrip::SetDisplayArea(const gfx::Rect& display_area) { 49 void PanelOverflowStrip::SetDisplayArea(const gfx::Rect& display_area) {
41 if (display_area_ == display_area) 50 if (display_area_ == display_area)
42 return; 51 return;
52 display_area_ = display_area;
43 53
44 display_area_ = display_area;
45 UpdateCurrentWidth(); 54 UpdateCurrentWidth();
46 55
56 if (overflow_indicator_.get()) {
57 max_visible_panels_on_hover_ = 0; // reset this value for recomputation.
58 UpdateMaxVisiblePanelsOnHover();
59 UpdateOverflowIndicatorCount();
60 }
61
47 Refresh(); 62 Refresh();
48 } 63 }
49 64
65 void PanelOverflowStrip::UpdateMaxVisiblePanelsOnHover() {
66 // No need to recompute this value.
67 if (max_visible_panels_on_hover_)
68 return;
69
70 DCHECK(!panels_.empty());
71 max_visible_panels_on_hover_ =
72 kHeightRatioForMaxVisibleOverflowPanelsOnHover *
73 display_area_.height() /
74 panels_.front()->IconOnlySize().height();
75 }
76
50 void PanelOverflowStrip::UpdateCurrentWidth() { 77 void PanelOverflowStrip::UpdateCurrentWidth() {
51 current_display_width_ = are_overflow_titles_shown_ ? kOverflowAreaHoverWidth 78 current_display_width_ = are_overflow_titles_shown_ ? kOverflowAreaHoverWidth
52 : display_area_.width(); 79 : display_area_.width();
53 } 80 }
54 81
55 void PanelOverflowStrip::AddPanel(Panel* panel) { 82 void PanelOverflowStrip::AddPanel(Panel* panel) {
56 // TODO(jianli): consider using other container to improve the perf for 83 // TODO(jianli): consider using other container to improve the perf for
57 // inserting to the front. http://crbug.com/106222 84 // inserting to the front. http://crbug.com/106222
58 DCHECK_EQ(Panel::IN_OVERFLOW, panel->expansion_state()); 85 DCHECK_EQ(Panel::IN_OVERFLOW, panel->expansion_state());
59 // Newly created panels that were temporarily in the panel strip 86 // Newly created panels that were temporarily in the panel strip
60 // are added to the back of the overflow, whereas panels that are 87 // are added to the back of the overflow, whereas panels that are
61 // bumped from the panel strip by other panels go to the front 88 // bumped from the panel strip by other panels go to the front
62 // of overflow. 89 // of overflow.
63 if (panel->has_temporary_layout()) { 90 if (panel->has_temporary_layout()) {
64 panel->set_has_temporary_layout(false); 91 panel->set_has_temporary_layout(false);
65 panels_.push_back(panel); 92 panels_.push_back(panel);
66 DoRefresh(panels_.size() - 1, panels_.size() - 1); 93 DoRefresh(panels_.size() - 1, panels_.size() - 1);
67 } else { 94 } else {
68 panels_.insert(panels_.begin(), panel); 95 panels_.insert(panels_.begin(), panel);
69 Refresh(); 96 Refresh();
70 } 97 }
71 98
72 if (panels_.size() == 1) 99 if (num_panels() == 1)
73 panel_manager_->mouse_watcher()->AddObserver(this); 100 panel_manager_->mouse_watcher()->AddObserver(this);
101
102 // Update the overflow indicator only when the number of overflow panels go
103 // beyond the maximum visible limit.
104 if (num_panels() > max_visible_panels_) {
105 if (!overflow_indicator_.get()) {
106 overflow_indicator_.reset(PanelOverflowIndicator::Create());
107 UpdateMaxVisiblePanelsOnHover();
108 }
109 UpdateOverflowIndicatorCount();
110 }
74 } 111 }
75 112
76 bool PanelOverflowStrip::Remove(Panel* panel) { 113 bool PanelOverflowStrip::Remove(Panel* panel) {
77 size_t index = 0; 114 size_t index = 0;
78 for (Panels::iterator iter = panels_.begin(); iter != panels_.end(); 115 Panels::iterator iter = panels_.begin();
79 ++iter, ++index) { 116 for (; iter != panels_.end(); ++iter, ++index)
80 if (*iter == panel) { 117 if (*iter == panel)
81 panels_.erase(iter); 118 break;
82 DoRefresh(index, panels_.size() - 1); 119 if (iter == panels_.end())
83 panel_manager_->OnPanelRemoved(panel); 120 return false;
84 if (panels_.empty()) 121
85 panel_manager_->mouse_watcher()->RemoveObserver(this); 122 panels_.erase(iter);
86 return true; 123 DoRefresh(index, panels_.size() - 1);
87 } 124 panel_manager_->OnPanelRemoved(panel);
88 } 125
89 return false; 126 if (panels_.empty())
127 panel_manager_->mouse_watcher()->RemoveObserver(this);
128
129 // Update the overflow indicator. If the number of overflow panels fall below
130 // the maximum visible limit, we do not need the overflow indicator any more.
131 if (num_panels() < max_visible_panels_)
132 overflow_indicator_.reset();
133 else
134 UpdateOverflowIndicatorCount();
135
136 return true;
90 } 137 }
91 138
92 void PanelOverflowStrip::RemoveAll() { 139 void PanelOverflowStrip::RemoveAll() {
93 // Make a copy of the iterator as closing panels can modify the vector. 140 // Make a copy of the iterator as closing panels can modify the vector.
94 Panels panels_copy = panels_; 141 Panels panels_copy = panels_;
95 142
96 // Start from the bottom to avoid reshuffling. 143 // Start from the bottom to avoid reshuffling.
97 for (Panels::reverse_iterator iter = panels_copy.rbegin(); 144 for (Panels::reverse_iterator iter = panels_copy.rbegin();
98 iter != panels_copy.rend(); ++iter) 145 iter != panels_copy.rend(); ++iter)
99 (*iter)->Close(); 146 (*iter)->Close();
100 } 147 }
101 148
102 void PanelOverflowStrip::OnPanelExpansionStateChanged( 149 void PanelOverflowStrip::OnPanelExpansionStateChanged(
103 Panel* panel, Panel::ExpansionState old_state) { 150 Panel* panel, Panel::ExpansionState old_state) {
104 DCHECK(panel->expansion_state() == Panel::IN_OVERFLOW); 151 DCHECK(panel->expansion_state() == Panel::IN_OVERFLOW);
105 panel_manager_->panel_strip()->Remove(panel); 152 panel_manager_->panel_strip()->Remove(panel);
106 AddPanel(panel); 153 AddPanel(panel);
107 panel->SetAppIconVisibility(false); 154 panel->SetAppIconVisibility(false);
108 panel->set_draggable(false); 155 panel->set_draggable(false);
109 } 156 }
110 157
158 void PanelOverflowStrip::OnPanelAttentionStateChanged(Panel* panel) {
159 DCHECK(panel->expansion_state() == Panel::IN_OVERFLOW);
160 UpdateOverflowIndicatorAttention();
161 }
162
111 void PanelOverflowStrip::Refresh() { 163 void PanelOverflowStrip::Refresh() {
112 if (panels_.empty()) 164 if (panels_.empty())
113 return; 165 return;
114 DoRefresh(0, panels_.size() - 1); 166 DoRefresh(0, panels_.size() - 1);
115 } 167 }
116 168
117 void PanelOverflowStrip::DoRefresh(size_t start_index, size_t end_index) { 169 void PanelOverflowStrip::DoRefresh(size_t start_index, size_t end_index) {
118 if (panels_.empty() || start_index == panels_.size()) 170 if (panels_.empty() || start_index == panels_.size())
119 return; 171 return;
120 172
121 DCHECK(end_index < panels_.size()); 173 DCHECK(end_index < panels_.size());
122 174
123 for (size_t index = start_index; index <= end_index; ++index) { 175 for (size_t index = start_index; index <= end_index; ++index) {
124 Panel* panel = panels_[index]; 176 Panel* panel = panels_[index];
125 gfx::Rect new_bounds = ComputeLayout(index, 177 gfx::Rect new_bounds = ComputeLayout(index,
126 panel->IconOnlySize()); 178 panel->IconOnlySize());
127 panel->SetPanelBounds(new_bounds); 179 panel->SetPanelBounds(new_bounds);
128 } 180 }
129 } 181 }
130 182
183 void PanelOverflowStrip::UpdateOverflowIndicatorCount() {
184 int max_panels = max_visible_panels();
185
186 // Setting the count to 0 will hide the indicator.
187 if (num_panels() <= max_panels) {
188 overflow_indicator_->SetCount(0);
189 return;
190 }
191
192 // Update the bounds and count.
193 int height = overflow_indicator_->GetHeight();
194 overflow_indicator_->SetBounds(gfx::Rect(
195 display_area_.x(),
196 panels_[max_panels - 1]->GetBounds().y() - height,
197 current_display_width_,
198 height));
199 overflow_indicator_->SetCount(num_panels() - max_panels);
200
201 // The attention state might get changed when there is a change to count
202 // value.
203 UpdateOverflowIndicatorAttention();
204 }
205
206 void PanelOverflowStrip::UpdateOverflowIndicatorAttention() {
207 int max_panels = max_visible_panels();
208
209 // The overflow indicator is painted as drawing attention only when there is
210 // at least one hidden panel that is drawing attention.
211 bool is_drawing_attention = false;
212 for (int index = max_panels; index < num_panels(); ++index) {
213 if (panels_[index]->IsDrawingAttention()) {
214 is_drawing_attention = true;
215 break;
216 }
217 }
218 if (is_drawing_attention)
219 overflow_indicator_->DrawAttention();
220 else
221 overflow_indicator_->StopDrawingAttention();
222 }
223
131 gfx::Rect PanelOverflowStrip::ComputeLayout( 224 gfx::Rect PanelOverflowStrip::ComputeLayout(
132 size_t index, const gfx::Size& iconified_size) const { 225 size_t index, const gfx::Size& iconified_size) const {
133 DCHECK(index != kInvalidPanelIndex); 226 DCHECK(index != kInvalidPanelIndex);
134 227
135 gfx::Rect bounds; 228 gfx::Rect bounds;
136 int bottom = (index == 0) ? display_area_.bottom() : 229 int bottom = (index == 0) ? display_area_.bottom() :
137 panels_[index - 1]->GetBounds().y(); 230 panels_[index - 1]->GetBounds().y();
138 bounds.set_x(display_area_.x()); 231 bounds.set_x(display_area_.x());
139 bounds.set_y(bottom - iconified_size.height()); 232 bounds.set_y(bottom - iconified_size.height());
140 233
141 if (are_overflow_titles_shown_ || 234 if (static_cast<int>(index) < max_visible_panels()) {
142 static_cast<int>(index) < max_visible_panels_) {
143 bounds.set_width(current_display_width_); 235 bounds.set_width(current_display_width_);
144 bounds.set_height(iconified_size.height()); 236 bounds.set_height(iconified_size.height());
145 } else { 237 } else {
146 // Invisible for overflow-on-overflow. 238 // Invisible for overflow-on-overflow.
147 bounds.set_width(0); 239 bounds.set_width(0);
148 bounds.set_height(0); 240 bounds.set_height(0);
149 } 241 }
150 242
151 return bounds; 243 return bounds;
152 } 244 }
153 245
154 void PanelOverflowStrip::OnMouseMove(const gfx::Point& mouse_position) { 246 void PanelOverflowStrip::OnMouseMove(const gfx::Point& mouse_position) {
155 bool show_overflow_titles = ShouldShowOverflowTitles(mouse_position); 247 bool show_overflow_titles = ShouldShowOverflowTitles(mouse_position);
156 ShowOverflowTitles(show_overflow_titles); 248 ShowOverflowTitles(show_overflow_titles);
157 } 249 }
158 250
159 bool PanelOverflowStrip::ShouldShowOverflowTitles( 251 bool PanelOverflowStrip::ShouldShowOverflowTitles(
160 const gfx::Point& mouse_position) const { 252 const gfx::Point& mouse_position) const {
161 if (panels_.empty()) 253 if (panels_.empty())
162 return false; 254 return false;
163 255
164 Panel* top_visible_panel; 256 Panel* top_visible_panel = num_panels() >= max_visible_panels() ?
165 if (are_overflow_titles_shown_) { 257 panels_[max_visible_panels() - 1] : panels_.back();
166 top_visible_panel = panels_.back();
167 } else {
168 top_visible_panel = num_panels() >= max_visible_panels_ ?
169 panels_[max_visible_panels_ - 1] : panels_.back();
170 }
171 return mouse_position.x() <= display_area_.x() + current_display_width_ && 258 return mouse_position.x() <= display_area_.x() + current_display_width_ &&
172 top_visible_panel->GetBounds().y() <= mouse_position.y() && 259 top_visible_panel->GetBounds().y() <= mouse_position.y() &&
173 mouse_position.y() <= display_area_.bottom(); 260 mouse_position.y() <= display_area_.bottom();
174 } 261 }
175 262
176 void PanelOverflowStrip::ShowOverflowTitles(bool show_overflow_titles) { 263 void PanelOverflowStrip::ShowOverflowTitles(bool show_overflow_titles) {
177 if (show_overflow_titles == are_overflow_titles_shown_) 264 if (show_overflow_titles == are_overflow_titles_shown_)
178 return; 265 return;
179 are_overflow_titles_shown_ = show_overflow_titles; 266 are_overflow_titles_shown_ = show_overflow_titles;
180 267
(...skipping 18 matching lines...) Expand all
199 } 286 }
200 287
201 if (!overflow_hover_animator_.get()) 288 if (!overflow_hover_animator_.get())
202 overflow_hover_animator_.reset(new ui::SlideAnimation(this)); 289 overflow_hover_animator_.reset(new ui::SlideAnimation(this));
203 if (overflow_hover_animator_->IsShowing()) 290 if (overflow_hover_animator_->IsShowing())
204 overflow_hover_animator_->Reset(); 291 overflow_hover_animator_->Reset();
205 overflow_hover_animator_->SetSlideDuration( 292 overflow_hover_animator_->SetSlideDuration(
206 PanelManager::AdjustTimeInterval(kOverflowHoverAnimationMs)); 293 PanelManager::AdjustTimeInterval(kOverflowHoverAnimationMs));
207 294
208 overflow_hover_animator_->Show(); 295 overflow_hover_animator_->Show();
296
297 // The overflow indicator count needs to be updated when the overflow area
298 // gets changed.
299 UpdateOverflowIndicatorCount();
209 } 300 }
210 301
211 void PanelOverflowStrip::AnimationEnded(const ui::Animation* animation) { 302 void PanelOverflowStrip::AnimationEnded(const ui::Animation* animation) {
212 content::NotificationService::current()->Notify( 303 content::NotificationService::current()->Notify(
213 chrome::NOTIFICATION_PANEL_BOUNDS_ANIMATIONS_FINISHED, 304 chrome::NOTIFICATION_PANEL_BOUNDS_ANIMATIONS_FINISHED,
214 content::Source<PanelOverflowStrip>(this), 305 content::Source<PanelOverflowStrip>(this),
215 content::NotificationService::NoDetails()); 306 content::NotificationService::NoDetails());
216 } 307 }
217 308
218 void PanelOverflowStrip::AnimationProgressed(const ui::Animation* animation) { 309 void PanelOverflowStrip::AnimationProgressed(const ui::Animation* animation) {
219 int current_display_width = overflow_hover_animator_->CurrentValueBetween( 310 int current_display_width = overflow_hover_animator_->CurrentValueBetween(
220 overflow_hover_animator_start_width_, overflow_hover_animator_end_width_); 311 overflow_hover_animator_start_width_, overflow_hover_animator_end_width_);
221 bool end_of_shrinking = current_display_width == display_area_.width(); 312 bool end_of_shrinking = current_display_width == display_area_.width();
313 int max_visible_panels = end_of_shrinking ?
314 max_visible_panels_ : max_visible_panels_on_hover_;
222 315
223 // Update each overflow panel. 316 // Update each overflow panel.
224 for (size_t i = 0; i < panels_.size(); ++i) { 317 for (int i = 0; i < num_panels(); ++i) {
225 Panel* overflow_panel = panels_[i]; 318 Panel* overflow_panel = panels_[i];
226 gfx::Rect bounds = overflow_panel->GetBounds(); 319 gfx::Rect bounds = overflow_panel->GetBounds();
227 320
228 if (static_cast<int>(i) >= max_visible_panels_ && end_of_shrinking) { 321 if (i >= max_visible_panels) {
229 bounds.set_width(0); 322 bounds.set_width(0);
230 bounds.set_height(0); 323 bounds.set_height(0);
231 } else { 324 } else {
232 bounds.set_width(current_display_width); 325 bounds.set_width(current_display_width);
233 bounds.set_height(overflow_panel->IconOnlySize().height()); 326 bounds.set_height(overflow_panel->IconOnlySize().height());
234 } 327 }
235 328
236 overflow_panel->SetPanelBoundsInstantly(bounds); 329 overflow_panel->SetPanelBoundsInstantly(bounds);
237 } 330 }
331
332 // Update the indicator.
333 if (overflow_indicator_.get()) {
334 gfx::Rect bounds = overflow_indicator_->GetBounds();
335 bounds.set_width(current_display_width);
336 overflow_indicator_->SetBounds(bounds);
337 overflow_indicator_->SetCount(num_panels() - max_visible_panels);
338 }
238 } 339 }
239 340
240 void PanelOverflowStrip::OnFullScreenModeChanged(bool is_full_screen) { 341 void PanelOverflowStrip::OnFullScreenModeChanged(bool is_full_screen) {
241 for (size_t i = 0; i < panels_.size(); ++i) 342 for (size_t i = 0; i < panels_.size(); ++i)
242 panels_[i]->FullScreenModeChanged(is_full_screen); 343 panels_[i]->FullScreenModeChanged(is_full_screen);
243 } 344 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/panels/panel_overflow_strip.h ('k') | chrome/chrome_browser.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698