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

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

Powered by Google App Engine
This is Rietveld 408576698