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

Side by Side Diff: chrome/browser/ui/views/sidebar/browser_sidebar_tab_strip_controller.cc

Issue 6250141: Sidebar mini tabs UI (views version).... Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 10 months 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
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 // Copyright (c) 2010 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/views/sidebar/browser_sidebar_tab_strip_controller.h "
6
7 #include "chrome/browser/sidebar/sidebar_container.h"
8 #include "chrome/browser/sidebar/sidebar_model.h"
9 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
10 #include "chrome/browser/ui/views/sidebar/sidebar_base_tab.h"
11 #include "chrome/browser/ui/views/sidebar/sidebar_base_tab_strip.h"
12 #include "chrome/browser/ui/views/sidebar/sidebar_tab_renderer_data.h"
13 #include "chrome/browser/ui/views/sidebar/sidebar_tab_strip_controller.h"
14 #include "chrome/browser/ui/views/sidebar/sidebar_tab_strip_host.h"
15 #include "views/widget/widget.h"
16
17 // TODO(alekseys): Add context menu, paint badge text, limit maximum tab strip
18 // height to 4 tabs + chevron, paint tabs programmatically instead of using
19 // images from resources.
20
21 namespace {
22
23 // The number of milliseconds between loading animation frames.
24 const int kLoadingAnimationFrameTimeMs = 30;
25
26 // Maps |contents|'s current state to SidebarTabRendererData::NetworkState.
27 SidebarTabRendererData::NetworkState TabContentsNetworkState(
28 const TabContents* contents) {
29 if (!contents || !contents->is_loading())
30 return SidebarTabRendererData::NETWORK_STATE_NONE;
31 if (contents->waiting_for_response())
32 return SidebarTabRendererData::NETWORK_STATE_WAITING;
33 return SidebarTabRendererData::NETWORK_STATE_LOADING;
34 }
35
36 // Comparator for sidebar tab ordering.
37 // Tabs are ordered by sidebar's content id and since content id is not
38 // controlled by the extension, tabs will always appear in the same order.
39 bool CompareContentIds(SidebarContainer* a, SidebarContainer* b) {
40 return a->content_id() < b->content_id();
41 }
42
43 } // namespace
44
45 // BrowserSidebarTabStripController, public:
46
47 BrowserSidebarTabStripController::BrowserSidebarTabStripController(
48 SidebarModel* model, Delegate* delegate)
49 : model_(model),
50 delegate_(delegate),
51 tab_strip_(NULL),
52 tab_(NULL) {
53 DCHECK(model_);
54 DCHECK(delegate_);
55 }
56
57 BrowserSidebarTabStripController::~BrowserSidebarTabStripController() {
58 }
59
60 bool BrowserSidebarTabStripController::IsSidebarExpanded() {
61 SidebarContainer* active_sidebar =
62 model()->GetActiveSidebarContainerFor(tab_);
63 return active_sidebar != NULL;
64 }
65
66 bool BrowserSidebarTabStripController::IsTabSelected(int model_index) {
67 SidebarContainer* active_sidebar =
68 model()->GetActiveSidebarContainerFor(tab_);
69 return active_sidebar &&
70 active_sidebar->content_id() == model_index_[model_index];
71 }
72
73 void BrowserSidebarTabStripController::SelectTab(int model_index) {
74 model()->ToggleSidebar(tab_, model_index_[model_index]);
75 }
76
77 void BrowserSidebarTabStripController::UpdateTabs(TabContentsWrapper* tab) {
78 // Do not animate tab insertions/removals when we switch to the different
79 // tab_contents, it means that user switched tabs and all we need to do is
80 // to show sidebar tabs for the current page.
81 bool animate = tab_ == tab;
82 tab_ = tab;
83
84 // Get the new model state (list of mini tabs sorted by content id).
85 std::vector<SidebarContainer*> new_model_index =
86 model()->GetAllSidebarsFor(tab_);
87 std::sort(new_model_index.begin(), new_model_index.end(), CompareContentIds);
88
89 SidebarContainer* active_sidebar =
90 model()->GetActiveSidebarContainerFor(tab_);
91
92 // Synchronize model index with the new state.
93 int model_index = 0;
94 int selected_model_index = -1;
95 std::vector<SidebarContainer*>::const_iterator it_new =
96 new_model_index.begin();
97 for (; it_new != new_model_index.end(); ++it_new, ++model_index) {
98 SidebarTabRendererData data;
99 SetSidebarTabRendererDataFromModel(*it_new, &data);
100
101 bool selected = *it_new == active_sidebar;
102 if (selected)
103 selected_model_index = model_index;
104
105 if (model_index >= static_cast<int>(model_index_.size())) {
106 // There're more tabs than in the model index, add the new one to the end.
107 model_index_.push_back((*it_new)->content_id());
108 tab_strip_->AddTabAt(model_index, animate, data);
109 } else if (model_index_[model_index] > (*it_new)->content_id()) {
110 // New tab should be inserted before the current one.
111 model_index_.insert(model_index_.begin() + model_index,
112 (*it_new)->content_id());
113 tab_strip_->AddTabAt(model_index, animate, data);
114 } else if (model_index_[model_index] < (*it_new)->content_id()) {
115 // The current tab is not in the model anymore and should be deleted.
116 tab_strip_->RemoveTabAt(model_index, animate);
117 model_index_.erase(model_index_.begin() + model_index);
118 } else {
119 // The same content id, nothing to update here.
120 }
121 }
122
123 // Remove excess tabs, model_index is now equal to the size of the new model.
124 if (static_cast<int>(model_index_.size()) > model_index) {
125 for (int i = model_index_.size(); i > model_index; --i)
126 tab_strip_->RemoveTabAt(i - 1, animate);
127 model_index_.erase(model_index_.begin() + model_index, model_index_.end());
128 }
129
130 if (selected_model_index >= 0)
131 tab_strip_->SelectTabAt(selected_model_index);
132
133 // In this case, no updates were issued yet, update view bounds only once.
134 if (!animate)
135 tab_strip_->SetToIdealBounds();
136 else
137 tab_strip_->SchedulePaint();
138 }
139
140 void BrowserSidebarTabStripController::UpdateState(
141 const SidebarContainer* sidebar) {
142 int model_index = 0;
143 std::vector<std::string>::const_iterator it = model_index_.begin();
144 for (; it != model_index_.end(); ++it, ++model_index) {
145 if (sidebar->content_id() == *it)
146 break;
147 }
148 // We might receive an update request too early and it's ok to ignore it,
149 // changes will be picked up when tab strip is going to be synched.
150 if (it == model_index_.end())
151 return;
152
153 SidebarTabRendererData data;
154 SetSidebarTabRendererDataFromModel(sidebar, &data);
155
156 tab_strip_->SetTabData(model_index, data);
157 tab_strip_->SchedulePaint();
158 }
159
160 void BrowserSidebarTabStripController::UpdateLoadingState(
161 const SidebarContainer* sidebar) {
162 UpdateLoadingAnimations();
163 }
164
165 void BrowserSidebarTabStripController::TabStripBoundsChanged(
166 bool is_animating) {
167 delegate_->OnSidebarTabStripBoundsChanged(is_animating);
168 }
169
170 // BrowserSidebarTabStripController, private:
171
172 void BrowserSidebarTabStripController::UpdateLoadingAnimations() {
173 bool should_animate = false;
174
175 // Check whether network state has changed for any tab or not.
176 int model_index = 0;
177 std::vector<std::string>::const_iterator it = model_index_.begin();
178 for (; it != model_index_.end(); ++it, ++model_index) {
179 SidebarBaseTab* tab = tab_strip_->GetBaseTabAtModelIndex(model_index);
180 SidebarContainer* sidebar =
181 model()->GetSidebarContainerFor(tab_, *it);
182 if (sidebar) {
183 TabContents* contents = sidebar->sidebar_contents();
184 if (tab->UpdateLoadingAnimation(TabContentsNetworkState(contents)))
185 should_animate = true;
186 }
187 }
188
189 if (should_animate) {
190 if (!loading_animation_timer_.IsRunning()) {
191 // Loads are happening, and the timer isn't running, so start it.
192 loading_animation_timer_.Start(
193 base::TimeDelta::FromMilliseconds(kLoadingAnimationFrameTimeMs), this,
194 &BrowserSidebarTabStripController::LoadingAnimationCallback);
195 }
196 } else {
197 if (loading_animation_timer_.IsRunning())
198 loading_animation_timer_.Stop();
199 }
200 }
201
202 void BrowserSidebarTabStripController::LoadingAnimationCallback() {
203 UpdateLoadingAnimations();
204 }
205
206 void BrowserSidebarTabStripController::SetTabDataAt(SidebarContainer* sidebar,
207 int model_index) {
208 SidebarTabRendererData data;
209 SetSidebarTabRendererDataFromModel(sidebar, &data);
210 tab_strip_->SetTabData(model_index, data);
211 }
212
213 void BrowserSidebarTabStripController::SetSidebarTabRendererDataFromModel(
214 const SidebarContainer* sidebar,
215 SidebarTabRendererData* data) {
216 data->icon = sidebar->icon();
217 data->title = sidebar->title();
218 data->badge_text = sidebar->badge_text();
219 data->network_state = TabContentsNetworkState(sidebar->sidebar_contents());
220 data->crashed = sidebar->sidebar_contents()->is_crashed();
221 }
222
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698