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

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
« no previous file with comments | « chrome/browser/ui/panels/panel_overflow_strip.h ('k') | chrome/browser/ui/panels/panel_strip.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 kOverflowAreaHoverWidth = 200;
17
18 // Maximium number of overflow panels allowed to be shown.
19 const size_t 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 // TODO(jianli): consider using other container to improve the perf for
46 // inserting to the front. http://crbug.com/106222
47 if (is_new)
48 panels_.push_back(panel);
49 else
50 panels_.insert(panels_.begin(), panel);
51
52 if (panels_.size() == 1)
53 panel_manager_->mouse_watcher()->AddObserver(this);
54
55 panel->SetExpansionState(Panel::IN_OVERFLOW);
56
57 if (is_new) {
58 // When the overflow panel is added to the back, only need to refresh
59 // itself.
60 DoRefresh(panels_.size() - 1, panels_.size() - 1);
61 } else {
62 // When the overflow panel is added to the front, refresh all.
63 Refresh();
64 }
65 }
66
67 bool PanelOverflowStrip::Remove(Panel* panel) {
68 size_t index = 0;
69 for (Panels::iterator iter = panels_.begin(); iter != panels_.end();
70 ++iter, ++index) {
71 if (*iter == panel) {
72 panels_.erase(iter);
73 DoRefresh(index, panels_.size() - 1);
74 panel_manager_->OnPanelRemoved(panel);
75 if (panels_.empty())
76 panel_manager_->mouse_watcher()->RemoveObserver(this);
77 return true;
78 }
79 }
80 return false;
81 }
82
83 void PanelOverflowStrip::RemoveAll() {
84 // Make a copy of the iterator as closing panels can modify the vector.
85 Panels panels_copy = panels_;
86
87 // Start from the bottom to avoid reshuffling.
88 for (Panels::reverse_iterator iter = panels_copy.rbegin();
89 iter != panels_copy.rend(); ++iter)
90 (*iter)->Close();
91 }
92
93 void PanelOverflowStrip::OnPanelExpansionStateChanged(
94 Panel* panel, Panel::ExpansionState old_state) {
jennb 2011/12/03 00:06:53 DCHECK state is IN_OVERFLOW?
95 }
96
97 void PanelOverflowStrip::Refresh() {
98 if (panels_.empty())
99 return;
100 DoRefresh(0, panels_.size() - 1);
101 }
102
103 void PanelOverflowStrip::DoRefresh(size_t start_index, size_t end_index) {
104 if (panels_.empty())
105 return;
106
107 DCHECK(start_index < panels_.size());
108 DCHECK(end_index < panels_.size());
109
110 for (size_t index = start_index; index <= end_index; ++index) {
111 Panel* panel = panels_[index];
112 gfx::Rect new_bounds = ComputeLayout(index,
113 panel->IconOnlySize());
114 DCHECK(!new_bounds.IsEmpty());
115 panel->SetPanelBounds(new_bounds);
116 }
117 }
118
119 gfx::Rect PanelOverflowStrip::ComputeLayout(
120 size_t index, const gfx::Size& iconified_size) const {
121 DCHECK(index != kInvalidPanelIndex);
122
123 gfx::Rect bounds;
124 int bottom = (index == 0) ? display_area_.bottom() :
125 panels_[index - 1]->GetBounds().y();
126 bounds.set_x(display_area_.x());
127 bounds.set_y(bottom - iconified_size.height());
128
129 if (are_overflow_titles_shown_) {
130 // Both icon and title are visible when the mouse hovers over the overflow
131 // area.
132 bounds.set_width(kOverflowAreaHoverWidth);
133 bounds.set_height(iconified_size.height());
134 } else if (index < kMaxVisibleOverflowPanelsAllowed) {
135 // Only the icon is visible.
136 bounds.set_width(iconified_size.width());
137 bounds.set_height(iconified_size.height());
138 } else {
139 // Invisible for overflow-on-overflow.
140 bounds.set_width(0);
141 bounds.set_height(0);
142 }
143
144 return bounds;
145 }
146
147 void PanelOverflowStrip::OnMouseMove(const gfx::Point& mouse_position) {
148 bool show_overflow_titles = ShouldShowOverflowTitles(mouse_position);
149 ShowOverflowTitles(show_overflow_titles);
150 }
151
152 bool PanelOverflowStrip::ShouldShowOverflowTitles(
153 const gfx::Point& mouse_position) const {
154 if (panels_.empty())
155 return false;
156
157 int width = are_overflow_titles_shown_ ? kOverflowAreaHoverWidth
158 : display_area_.width();
159 return display_area_.x() <= mouse_position.x() &&
160 mouse_position.x() <= display_area_.x() + width &&
161 panels_.back()->GetBounds().y() <= mouse_position.y() &&
162 mouse_position.y() <= display_area_.bottom();
163 }
164
165 void PanelOverflowStrip::ShowOverflowTitles(bool show_overflow_titles) {
166 if (show_overflow_titles == are_overflow_titles_shown_)
167 return;
168 are_overflow_titles_shown_ = show_overflow_titles;
169
170 if (show_overflow_titles) {
171 overflow_hover_animator_start_width_ = display_area_.width();
172 overflow_hover_animator_end_width_ = kOverflowAreaHoverWidth;
173
174 // We need to bring all overflow panels to the top of z-order since the
175 // active panel might obscure the expanded overflow panels.
176 for (Panels::iterator iter = panels_.begin();
177 iter != panels_.end(); ++iter) {
178 (*iter)->EnsureFullyVisible();
179 }
180 } else {
181 overflow_hover_animator_start_width_ = kOverflowAreaHoverWidth;
182 overflow_hover_animator_end_width_ = display_area_.width();
183 }
184
185 if (!overflow_hover_animator_.get())
186 overflow_hover_animator_.reset(new ui::SlideAnimation(this));
187 if (overflow_hover_animator_->IsShowing())
188 overflow_hover_animator_->Reset();
189 overflow_hover_animator_->SetSlideDuration(kOverflowHoverAnimationMs);
190
191 overflow_hover_animator_->Show();
192 }
193
194 void PanelOverflowStrip::AnimationProgressed(const ui::Animation* animation) {
195 int current_width = overflow_hover_animator_->CurrentValueBetween(
196 overflow_hover_animator_start_width_, overflow_hover_animator_end_width_);
197 bool end_of_shrinking = current_width == display_area_.width();
198
199 // Update each overflow panel.
200 for (size_t i = 0; i < panels_.size(); ++i) {
201 Panel* overflow_panel = panels_[i];
202 gfx::Rect bounds = overflow_panel->GetBounds();
203
204 if (i >= kMaxVisibleOverflowPanelsAllowed && end_of_shrinking) {
205 bounds.set_width(0);
206 bounds.set_height(0);
207 } else {
208 bounds.set_width(current_width);
209 bounds.set_height(overflow_panel->IconOnlySize().height());
210 }
211
212 overflow_panel->SetPanelBoundsInstantly(bounds);
213 }
214 }
215
216 void PanelOverflowStrip::OnFullScreenModeChanged(bool is_full_screen) {
217 for (size_t i = 0; i < panels_.size(); ++i)
218 panels_[i]->FullScreenModeChanged(is_full_screen);
219 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/panels/panel_overflow_strip.h ('k') | chrome/browser/ui/panels/panel_strip.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698