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

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

Issue 8776035: Add PanelOverflowStrip to handle panel overflow. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix 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
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "chrome/browser/ui/panels/panel_overflow_strip.h"
6
7 #include "base/logging.h"
8 #include "chrome/browser/ui/panels/panel_manager.h"
9 #include "chrome/browser/ui/panels/panel_mouse_watcher.h"
10 #include "chrome/browser/ui/panels/panel_strip.h"
11 #include "ui/base/animation/slide_animation.h"
12
13 namespace {
14 // The width of the overflow area that is expanded to show more info, i.e.
15 // titles, when the mouse hovers over the area.
16 const int kOverflowAreaOverWidth = 200;
jennb 2011/12/02 21:16:58 kOverflowStripExpandedWidth? kOverflowStripShowing
jianli 2011/12/02 23:23:46 Fixed. I mean kOverflowAreaHoverWidth indeed.
17
18 // Maximium number of overflow panels allowed to show.
jennb 2011/12/02 21:16:58 to be shown.
jianli 2011/12/02 23:23:46 Done.
19 const int kMaxVisibleOverflowPanelsAllowed = 6;
20
21 // This value is experimental and subjective.
22 const int kOverflowHoverAnimationMs = 180;
23 }
24
25 PanelOverflowStrip::PanelOverflowStrip(PanelManager* panel_manager)
26 : panel_manager_(panel_manager),
27 are_overflow_titles_shown_(false),
28 overflow_hover_animator_start_width_(0),
29 overflow_hover_animator_end_width_(0) {
30 }
31
32 PanelOverflowStrip::~PanelOverflowStrip() {
33 DCHECK(panels_.empty());
34 }
35
36 void PanelOverflowStrip::SetDisplayArea(const gfx::Rect& display_area) {
37 if (display_area_ == display_area)
38 return;
39
40 display_area_ = display_area;
41 Refresh();
42 }
43
44 void PanelOverflowStrip::AddPanel(Panel* panel, bool is_new) {
45 if (is_new)
46 panels_.push_back(panel);
47 else
48 panels_.insert(panels_.begin(), panel);
jennb 2011/12/02 21:16:58 nit: not for this patch. vector is inefficient as
jianli 2011/12/02 23:23:46 Added TODO for this.
49
50 if (panels_.size() == 1)
51 panel_manager_->mouse_watcher()->AddObserver(this);
52
53 panel->SetExpansionState(Panel::IN_OVERFLOW);
54 }
55
56 bool PanelOverflowStrip::Remove(Panel* panel) {
57 size_t index = 0;
58 for (Panels::iterator iter = panels_.begin(); iter != panels_.end();
jennb 2011/12/02 21:16:58 nit: would be easier to read if you use find() the
jianli 2011/12/02 23:23:46 I need to also find the index for the panel.
59 ++iter, ++index) {
60 if (*iter == panel) {
61 panels_.erase(iter);
62 DoRefresh(index, panels_.size() - 1);
63 panel_manager_->OnPanelRemoved(panel);
64 if (panels_.empty())
65 panel_manager_->mouse_watcher()->RemoveObserver(this);
66 return true;
67 }
68 }
69 return false;
70 }
71
72 void PanelOverflowStrip::RemoveAll() {
73 // Make a copy of the iterator as closing panels can modify the vector.
74 Panels panels_copy = panels_;
75
76 // Start from the bottom to avoid reshuffling.
77 for (Panels::reverse_iterator iter = panels_copy.rbegin();
78 iter != panels_copy.rend(); ++iter)
79 (*iter)->Close();
80 }
81
82 void PanelOverflowStrip::UpdatePanelRestoredSize(
83 Panel* panel, const gfx::Size& restored_size) {
84 panel->set_restored_size(restored_size);
85 }
86
87 void PanelOverflowStrip::OnPanelExpansionStateChanged(
88 Panel* panel, Panel::ExpansionState old_state) {
89 size_t panel_index = FindPanelIndex(panel);
jennb 2011/12/02 21:16:58 Should make this method a no-op. Instead, in AddPa
jianli 2011/12/02 23:23:46 Done.
90 DoRefresh(panel_index, panels_.size() - 1);
91 }
92
93 void PanelOverflowStrip::Refresh() {
94 if (panels_.empty())
95 return;
96 DoRefresh(0, panels_.size() - 1);
jennb 2011/12/02 21:16:58 nit: There's only a few panels visible in overflow
jianli 2011/12/02 23:23:46 I rather do a full layout computation to avoid any
97 }
98
99 void PanelOverflowStrip::DoRefresh(size_t start_index, size_t end_index) {
100 if (panels_.empty())
101 return;
102
103 DCHECK(start_index < panels_.size());
104 DCHECK(end_index < panels_.size());
105
106 for (size_t index = start_index; index <= end_index; ++index) {
107 Panel* panel = panels_[index];
108 gfx::Rect new_bounds = ComputeLayout(index,
109 panel->IconOnlySize(),
110 panel->restored_size());
111 DCHECK(!new_bounds.IsEmpty());
112 panel->SetPanelBounds(new_bounds);
113 }
114 }
115
116 size_t PanelOverflowStrip::FindPanelIndex(Panel* panel) const {
117 for (size_t i = 0; i < panels_.size(); ++i)
118 if (panels_[i] == panel)
119 return i;
120 return kInvalidPanelIndex;
121 }
122
123 gfx::Rect PanelOverflowStrip::ComputeLayout(
124 size_t index, const gfx::Size& iconified_size,
125 const gfx::Size& restored_size) const {
126 DCHECK(index != kInvalidPanelIndex);
127
128 gfx::Rect bounds;
129 int bottom = (index == 0) ? display_area_.bottom() :
130 panels_[index - 1]->GetBounds().y();
131 bounds.set_x(display_area_.x());
132 bounds.set_y(bottom - iconified_size.height());
133
134 if (are_overflow_titles_shown_) {
135 // Both icon and title are visible when the mouse hovers over the overflow
136 // area.
137 bounds.set_width(kOverflowAreaOverWidth);
138 bounds.set_height(iconified_size.height());
139 } else if (index < kMaxVisibleOverflowPanelsAllowed) {
140 // Only the icon is visible.
141 bounds.set_width(iconified_size.width());
142 bounds.set_height(iconified_size.height());
143 } else {
144 // Invisible for overflow-on-overflow.
145 bounds.set_width(0);
jennb 2011/12/02 21:16:58 Using size(0, 0) seems wrong as that means panels
jianli 2011/12/02 23:23:46 This is the only way for now.
146 bounds.set_height(0);
147 }
148
149 return bounds;
150 }
151
152 void PanelOverflowStrip::OnMouseMove(const gfx::Point& mouse_position) {
153 bool show_overflow_titles = ShouldShowOverflowTitles(mouse_position);
jennb 2011/12/02 21:16:58 extra space after =
jianli 2011/12/02 23:23:46 Done.
154 ShowOverflowTitles(show_overflow_titles);
155 }
156
157 bool PanelOverflowStrip::ShouldShowOverflowTitles(
158 const gfx::Point& mouse_position) const {
159 if (panels_.empty())
160 return false;
161
162 int width = are_overflow_titles_shown_ ? kOverflowAreaOverWidth
163 : display_area_.width();
164 return display_area_.x() <= mouse_position.x() &&
165 mouse_position.x() <= display_area_.x() + width &&
jennb 2011/12/02 21:16:58 display_area_.right()
jianli 2011/12/02 23:23:46 width could be either kOverflowAreaHoverWidth or d
166 panels_.back()->GetBounds().y() <= mouse_position.y() &&
167 mouse_position.y() <= display_area_.bottom();
168 }
169
170 void PanelOverflowStrip::ShowOverflowTitles(bool show_overflow_titles) {
171 if (show_overflow_titles == are_overflow_titles_shown_)
172 return;
173 are_overflow_titles_shown_ = show_overflow_titles;
174
175 if (show_overflow_titles) {
176 overflow_hover_animator_start_width_ = display_area_.width();
177 overflow_hover_animator_end_width_ = kOverflowAreaOverWidth;
178
179 // We need to bring all overflow panels to the top of z-order again since
jennb 2011/12/02 21:16:58 This comment makes no sense to me.
jianli 2011/12/02 23:23:46 Changed.
180 // making an overflow panel expanded will cause it be activated and thus
181 // moved to the top of z-order.
182 for (Panels::iterator iter = panels_.begin();
183 iter != panels_.end(); ++iter) {
184 (*iter)->EnsureFullyVisible();
185 }
186 } else {
187 overflow_hover_animator_start_width_ = kOverflowAreaOverWidth;
188 overflow_hover_animator_end_width_ = display_area_.width();
189 }
190
191 if (!overflow_hover_animator_.get())
192 overflow_hover_animator_.reset(new ui::SlideAnimation(this));
193 if (overflow_hover_animator_->IsShowing())
194 overflow_hover_animator_->Reset();
195 overflow_hover_animator_->SetSlideDuration(kOverflowHoverAnimationMs);
196
197 overflow_hover_animator_->Show();
198 }
199
200 void PanelOverflowStrip::AnimationProgressed(const ui::Animation* animation) {
201 int current_width = overflow_hover_animator_->CurrentValueBetween(
202 overflow_hover_animator_start_width_, overflow_hover_animator_end_width_);
203 bool end_of_shrinking =
204 current_width == overflow_hover_animator_end_width_ &&
205 overflow_hover_animator_start_width_ > overflow_hover_animator_end_width_;
jennb 2011/12/02 21:16:58 is this the same as current_width == display_area_
jianli 2011/12/02 23:23:46 Yes. Thanks for suggesting the simple way to check
206
207 // Update each overflow panel.
jennb 2011/12/02 21:16:58 Could you replace all this with a call to Refresh(
jianli 2011/12/02 23:23:46 I think adding another parameter to Refresh will m
208 for (size_t i = 0; i < panels_.size(); ++i) {
209 Panel* overflow_panel = panels_[i];
210 gfx::Rect bounds = overflow_panel->GetBounds();
211
212 if (i >= kMaxVisibleOverflowPanelsAllowed && end_of_shrinking) {
213 bounds.set_width(0);
214 bounds.set_height(0);
215 } else {
216 bounds.set_width(current_width);
217 bounds.set_height(overflow_panel->IconOnlySize().height());
218 }
219
220 overflow_panel->SetPanelBoundsInstantly(bounds);
221 }
222 }
223
224 bool PanelOverflowStrip::mouse_watcher_needed() const {
225 return !panels_.empty();
226 }
227
228 Panel* PanelOverflowStrip::first_panel() const {
229 return panels_.empty() ? NULL : panels_.front();
230 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698