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

Side by Side Diff: ui/views/controls/tabbed_pane/native_tabbed_pane_views.cc

Issue 8687013: Get the examples to run in aura_shell. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' 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
Property Changes:
Added: svn:eol-style
+ LF
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 "ui/views/controls/tabbed_pane/native_tabbed_pane_views.h"
6
7 #include "base/logging.h"
8 #include "base/stl_util.h"
9 #include "ui/base/resource/resource_bundle.h"
10 #include "ui/gfx/canvas_skia.h"
11 #include "ui/gfx/font.h"
12 #include "ui/views/controls/tabbed_pane/tabbed_pane.h"
13 #include "ui/views/controls/tabbed_pane/tabbed_pane_listener.h"
14 #include "ui/views/layout/fill_layout.h"
15 #include "ui/views/widget/widget.h"
16
17 namespace views {
18
19 class TabStrip;
20
21 class Tab : public View {
22 public:
23 Tab(TabStrip* tab_strip, const string16& title)
24 : tab_strip_(tab_strip),
25 title_(title) {}
26 virtual ~Tab() {}
27
28 static int GetMinimumTabHeight() {
29 return gfx::Font().GetHeight() + 10;
30 }
31
32 // Overridden from View:
33 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
34 canvas->FillRect(GetTabColor(), GetLocalBounds());
35 canvas->DrawStringInt(title_, gfx::Font(), SK_ColorBLACK, GetLocalBounds());
36 }
37 virtual bool OnMousePressed(const MouseEvent& event) OVERRIDE;
38 virtual gfx::Size GetPreferredSize() OVERRIDE {
39 gfx::Size ps(gfx::Font().GetStringWidth(title_), GetMinimumTabHeight());
40 ps.Enlarge(10, 0);
41 return ps;
42 }
43
44 private:
45 SkColor GetTabColor() const;
46
47 TabStrip* tab_strip_;
48 string16 title_;
49
50 DISALLOW_COPY_AND_ASSIGN(Tab);
51 };
52
53 class TabStrip : public View {
54 public:
55 explicit TabStrip(NativeTabbedPaneViews* owner)
56 : owner_(owner),
57 selected_tab_(NULL) {
58 }
59 virtual ~TabStrip() {}
60
61 void SelectTab(View* tab) {
62 if (tab == selected_tab_)
63 return;
64 if (selected_tab_)
65 selected_tab_->SchedulePaint();
66 selected_tab_ = tab;
67 selected_tab_->SchedulePaint();
68 owner_->TabSelectionChanged(GetIndexOf(tab));
69 }
70
71 bool IsTabSelected(const View* tab) const {
72 return tab == selected_tab_;
73 }
74
75 int GetSelectedIndex() const {
76 return GetIndexOf(selected_tab_);
77 }
78
79 void RemoveTabAt(int index) {
80 delete child_at(index);
81 }
82
83 // Overridden from View:
84 virtual gfx::Size GetPreferredSize() OVERRIDE {
85 return gfx::Size(50, Tab::GetMinimumTabHeight());
86 }
87 virtual void Layout() OVERRIDE {
88 int x = 0;
89 for (int i = 0; i < child_count(); ++i) {
90 gfx::Size ps = child_at(i)->GetPreferredSize();
91 child_at(i)->SetBounds(x, 0, ps.width(), ps.height());
92 x = child_at(i)->bounds().right();
93 }
94 }
95
96 private:
97 NativeTabbedPaneViews* owner_;
98 View* selected_tab_;
99
100 DISALLOW_COPY_AND_ASSIGN(TabStrip);
101 };
102
103 bool Tab::OnMousePressed(const MouseEvent& event) {
104 tab_strip_->SelectTab(this);
105 return true;
106 }
107
108 SkColor Tab::GetTabColor() const {
109 return tab_strip_->IsTabSelected(this) ? SK_ColorRED : SK_ColorBLUE;
110 }
111
112 // Custom layout manager that takes care of sizing and displaying the tab pages.
113 class TabLayout : public LayoutManager {
114 public:
115 TabLayout() {}
116
117 // Switches to the tab page identified by the given index.
sky 2011/11/28 23:46:22 update comment (no index)
118 void SwitchToPage(View* host, View* page) {
119 for (int i = 0; i < host->child_count(); ++i) {
120 View* child = host->child_at(i);
121 // The child might not have been laid out yet.
122 if (child == page)
123 child->SetBoundsRect(host->GetContentsBounds());
124 child->SetVisible(child == page);
125 }
126
127 FocusManager* focus_manager = page->GetFocusManager();
128 DCHECK(focus_manager);
129 const View* focused_view = focus_manager->GetFocusedView();
130 if (focused_view && host->Contains(focused_view) &&
131 !page->Contains(focused_view))
132 focus_manager->SetFocusedView(page);
133 }
134
135 private:
136 // LayoutManager overrides:
137 virtual void Layout(View* host) {
sky 2011/11/28 23:46:22 OVERRIDE
138 gfx::Rect bounds(host->GetContentsBounds());
139 for (int i = 0; i < host->child_count(); ++i) {
140 View* child = host->child_at(i);
141 // We only layout visible children, since it may be expensive.
142 if (child->IsVisible() && child->bounds() != bounds)
143 child->SetBoundsRect(bounds);
144 }
145 }
146
147 virtual gfx::Size GetPreferredSize(View* host) {
148 // First, query the preferred sizes to determine a good width.
149 int width = 0;
150 for (int i = 0; i < host->child_count(); ++i) {
151 View* page = host->child_at(i);
152 width = std::max(width, page->GetPreferredSize().width());
153 }
154 // After we know the width, decide on the height.
155 return gfx::Size(width, GetPreferredHeightForWidth(host, width));
156 }
157
158 virtual int GetPreferredHeightForWidth(View* host, int width) {
159 int height = 0;
160 for (int i = 0; i < host->child_count(); ++i) {
161 View* page = host->child_at(i);
162 height = std::max(height, page->GetHeightForWidth(width));
163 }
164 return height;
165 }
166
167 DISALLOW_COPY_AND_ASSIGN(TabLayout);
168 };
169
170 ////////////////////////////////////////////////////////////////////////////////
171 // NativeTabbedPaneViews, public:
172
173 NativeTabbedPaneViews::NativeTabbedPaneViews(TabbedPane* tabbed_pane)
174 : tabbed_pane_(tabbed_pane),
175 ALLOW_THIS_IN_INITIALIZER_LIST(tab_strip_(new TabStrip(this))),
sky 2011/11/28 23:46:22 make order match header.
176 tab_layout_manager_(new TabLayout),
177 content_window_(NULL),
178 selected_index_(-1) {
179 AddChildView(tab_strip_);
180 }
181
182 NativeTabbedPaneViews::~NativeTabbedPaneViews() {
183 // We own the tab views, let's delete them.
184 STLDeleteContainerPointers(tab_views_.begin(), tab_views_.end());
185 }
186
187 void NativeTabbedPaneViews::TabSelectionChanged(int index) {
188 DoSelectTabAt(index, true);
189 }
190
191 ////////////////////////////////////////////////////////////////////////////////
192 // NativeTabbedPaneViews, NativeTabbedPaneWrapper implementation:
193
194 void NativeTabbedPaneViews::AddTab(const string16& title, View* contents) {
195 AddTabAtIndex(static_cast<int>(tab_views_.size()), title, contents, true);
196 }
197
198 void NativeTabbedPaneViews::AddTabAtIndex(int index,
199 const string16& title,
200 View* contents,
201 bool select_if_first_tab) {
202 DCHECK(index <= static_cast<int>(tab_views_.size()));
203 contents->set_parent_owned(false);
204 contents->SetVisible(false);
205 tab_views_.insert(tab_views_.begin() + index, contents);
206 tab_titles_.insert(tab_titles_.begin() + index, title);
207
208 if (tab_views_.size() == 1 && select_if_first_tab)
209 selected_index_ = 0;
210
211 // Add native tab only if the native control is alreay created.
212 if (content_window_) {
213 AddNativeTab(index, title);
214
215 View* content_root = content_window_->GetRootView();
216 content_root->AddChildView(contents);
217 // Switch to the newly added tab if requested;
218 if (tab_views_.size() == 1 && select_if_first_tab)
219 tab_layout_manager_->SwitchToPage(content_root, contents);
220 }
221 }
222
223 void NativeTabbedPaneViews::AddNativeTab(int index, const string16& title) {
224 tab_strip_->AddChildViewAt(new Tab(tab_strip_, title), index);
225 }
226
227 View* NativeTabbedPaneViews::RemoveTabAtIndex(int index) {
228 int tab_count = static_cast<int>(tab_views_.size());
229 DCHECK(index >= 0 && index < tab_count);
230
231 if (index < (tab_count - 1)) {
232 // Select the next tab.
233 SelectTabAt(index + 1);
234 } else {
235 // We are the last tab, select the previous one.
236 if (index > 0) {
237 SelectTabAt(index - 1);
238 } else if (content_window_) {
239 // That was the last tab. Remove the contents.
240 content_window_->GetRootView()->RemoveAllChildViews(false);
241 }
242 }
243 tab_strip_->RemoveTabAt(index);
244
245 std::vector<View*>::iterator iter = tab_views_.begin() + index;
246 View* removed_tab = *iter;
247 if (content_window_)
248 content_window_->GetRootView()->RemoveChildView(removed_tab);
249 tab_views_.erase(iter);
250 tab_titles_.erase(tab_titles_.begin() + index);
251
252 return removed_tab;
253 }
254
255 void NativeTabbedPaneViews::SelectTabAt(int index) {
256 DCHECK((index >= 0) && (index < static_cast<int>(tab_views_.size())));
257 tab_strip_->SelectTab(tab_strip_->child_at(index));
258 }
259
260 int NativeTabbedPaneViews::GetTabCount() {
261 return tab_strip_->child_count();
262 }
263
264 int NativeTabbedPaneViews::GetSelectedTabIndex() {
265 return tab_strip_->GetSelectedIndex();
266 }
267
268 View* NativeTabbedPaneViews::GetSelectedTab() {
269 if (selected_index_ < 0)
270 return NULL;
271 return tab_views_[selected_index_];
272 }
273
274 View* NativeTabbedPaneViews::GetView() {
275 return this;
276 }
277
278 void NativeTabbedPaneViews::SetFocus() {
279 // Focus the associated HWND.
280 OnFocus();
281 }
282
283 gfx::Size NativeTabbedPaneViews::GetPreferredSize() {
284 return gfx::Size(0, tab_strip_->GetPreferredSize().height());
285 }
286
287 gfx::NativeView NativeTabbedPaneViews::GetTestingHandle() const {
288 return NULL;
289 }
290
291 ////////////////////////////////////////////////////////////////////////////////
292 // NativeTabbedPaneViews, View overrides:
293
294 void NativeTabbedPaneViews::Layout() {
295 gfx::Size ps = tab_strip_->GetPreferredSize();
296 tab_strip_->SetBounds(0, 0, width(), ps.height());
297
298 gfx::Point child_origin(0, tab_strip_->bounds().bottom());
299 View::ConvertPointToWidget(this, &child_origin);
300
301 if (content_window_) {
302 content_window_->SetBounds(gfx::Rect(child_origin.x(),
303 child_origin.y(),
304 width(),
305 std::max(0, height() - ps.height())));
306 }
307 }
308
309 FocusTraversable* NativeTabbedPaneViews::GetFocusTraversable() {
310 return content_window_;
311 }
312
313 void NativeTabbedPaneViews::ViewHierarchyChanged(bool is_add,
314 View *parent,
315 View *child) {
316 if (is_add && child == this)
317 InitControl();
318 }
319
320 ////////////////////////////////////////////////////////////////////////////////
321 // NativeTabbedPaneViews, private:
322
323 void NativeTabbedPaneViews::InitControl() {
324 content_window_ = new Widget;
325 Widget::InitParams params(Widget::InitParams::TYPE_CONTROL);
326 params.parent = GetWidget()->GetNativeView();
327 content_window_->Init(params);
328 content_window_->GetRootView()->SetLayoutManager(tab_layout_manager_);
329 content_window_->GetRootView()->set_background(
330 Background::CreateSolidBackground(SK_ColorLTGRAY));
331 content_window_->SetFocusTraversableParentView(this);
332 content_window_->SetFocusTraversableParent(
333 GetWidget()->GetFocusTraversable());
334
335 // Add tabs that are already added if any.
336 if (!tab_views_.empty()) {
337 InitializeTabs();
338 if (selected_index_ >= 0)
339 DoSelectTabAt(selected_index_, false);
340 }
341 }
342
343 void NativeTabbedPaneViews::InitializeTabs() {
344 for (size_t i = 0; i < tab_titles_.size(); ++i)
345 AddNativeTab(i, tab_titles_[i]);
346
347 View* content_root = content_window_->GetRootView();
348 for (std::vector<View*>::iterator tab(tab_views_.begin());
349 tab != tab_views_.end(); ++tab)
350 content_root->AddChildView(*tab);
351 }
352
353 void NativeTabbedPaneViews::DoSelectTabAt(int index, boolean invoke_listener) {
354 selected_index_ = index;
355 if (content_window_) {
356 View* content_root = content_window_->GetRootView();
357 tab_layout_manager_->SwitchToPage(content_root, tab_views_[index]);
358 }
359 if (invoke_listener && tabbed_pane_->listener())
360 tabbed_pane_->listener()->TabSelectedAt(index);
361 }
362
363 ////////////////////////////////////////////////////////////////////////////////
364 // NativeTabbedPaneWrapper, public:
365
366 // static
367 NativeTabbedPaneWrapper* NativeTabbedPaneWrapper::CreateNativeWrapper(
368 TabbedPane* tabbed_pane) {
369 return new NativeTabbedPaneViews(tabbed_pane);
370 }
371
372 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698