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

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

Issue 2297193002: Harmony: implement TabbedPane styling (Closed)
Patch Set: Created 4 years, 3 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
« no previous file with comments | « ui/views/controls/tabbed_pane/tabbed_pane.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/views/controls/tabbed_pane/tabbed_pane.h" 5 #include "ui/views/controls/tabbed_pane/tabbed_pane.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/macros.h" 8 #include "base/macros.h"
9 #include "third_party/skia/include/core/SkPaint.h" 9 #include "third_party/skia/include/core/SkPaint.h"
10 #include "third_party/skia/include/core/SkPath.h" 10 #include "third_party/skia/include/core/SkPath.h"
11 #include "ui/accessibility/ax_view_state.h" 11 #include "ui/accessibility/ax_view_state.h"
12 #include "ui/base/default_style.h" 12 #include "ui/base/default_style.h"
13 #include "ui/base/material_design/material_design_controller.h"
13 #include "ui/base/resource/resource_bundle.h" 14 #include "ui/base/resource/resource_bundle.h"
14 #include "ui/events/keycodes/keyboard_codes.h" 15 #include "ui/events/keycodes/keyboard_codes.h"
15 #include "ui/gfx/canvas.h" 16 #include "ui/gfx/canvas.h"
16 #include "ui/gfx/font_list.h" 17 #include "ui/gfx/font_list.h"
18 #include "ui/views/border.h"
17 #include "ui/views/controls/label.h" 19 #include "ui/views/controls/label.h"
18 #include "ui/views/controls/tabbed_pane/tabbed_pane_listener.h" 20 #include "ui/views/controls/tabbed_pane/tabbed_pane_listener.h"
21 #include "ui/views/layout/box_layout.h"
19 #include "ui/views/layout/layout_manager.h" 22 #include "ui/views/layout/layout_manager.h"
20 #include "ui/views/widget/widget.h" 23 #include "ui/views/widget/widget.h"
21 24
22 namespace { 25 namespace {
23 26
24 // TODO(markusheintz|msw): Use NativeTheme colors. 27 // TODO(markusheintz|msw): Use NativeTheme colors.
25 const SkColor kTabTitleColor_Inactive = SkColorSetRGB(0x64, 0x64, 0x64); 28 const SkColor kTabTitleColor_Inactive = SkColorSetRGB(0x64, 0x64, 0x64);
26 const SkColor kTabTitleColor_Active = SK_ColorBLACK; 29 const SkColor kTabTitleColor_Active = SK_ColorBLACK;
27 const SkColor kTabTitleColor_Hovered = SK_ColorBLACK; 30 const SkColor kTabTitleColor_Hovered = SK_ColorBLACK;
28 const SkColor kTabBorderColor = SkColorSetRGB(0xC8, 0xC8, 0xC8); 31 const SkColor kTabBorderColor = SkColorSetRGB(0xC8, 0xC8, 0xC8);
29 const SkScalar kTabBorderThickness = 1.0f; 32 const SkScalar kTabBorderThickness = 1.0f;
30 33
31 const gfx::Font::Weight kHoverWeight = gfx::Font::Weight::NORMAL; 34 const gfx::Font::Weight kHoverWeight = gfx::Font::Weight::NORMAL;
32 const gfx::Font::Weight kActiveWeight = gfx::Font::Weight::BOLD; 35 const gfx::Font::Weight kActiveWeight = gfx::Font::Weight::BOLD;
33 const gfx::Font::Weight kInactiveWeight = gfx::Font::Weight::NORMAL; 36 const gfx::Font::Weight kInactiveWeight = gfx::Font::Weight::NORMAL;
34 37
38 const int kHarmonyTabStripVerticalPad = 16;
39 const int kHarmonyTabStripTabHeight = 40;
40
35 } // namespace 41 } // namespace
36 42
37 namespace views { 43 namespace views {
38 44
39 // static 45 // static
40 const char TabbedPane::kViewClassName[] = "TabbedPane"; 46 const char TabbedPane::kViewClassName[] = "TabbedPane";
41 47
42 // The tab view shown in the tab strip. 48 // The tab view shown in the tab strip.
43 class Tab : public View { 49 class Tab : public View {
44 public: 50 public:
45 // Internal class name. 51 // Internal class name.
46 static const char kViewClassName[]; 52 static const char kViewClassName[];
47 53
48 Tab(TabbedPane* tabbed_pane, const base::string16& title, View* contents); 54 Tab(TabbedPane* tabbed_pane, const base::string16& title, View* contents);
49 ~Tab() override; 55 ~Tab() override;
50 56
51 View* contents() const { return contents_; } 57 View* contents() const { return contents_; }
52 58
53 bool selected() const { return contents_->visible(); } 59 bool selected() const { return contents_->visible(); }
54 void SetSelected(bool selected); 60 void SetSelected(bool selected);
55 61
62 // Called whenever tab_state_ changes.
sky 2016/08/31 16:44:03 Generally we put |'s around references to members/
Elly Fong-Jones 2016/08/31 16:49:11 Done.
63 virtual void OnStateChanged();
sky 2016/08/31 16:44:03 Make protected
Elly Fong-Jones 2016/08/31 16:49:11 Done.
64
56 // Overridden from View: 65 // Overridden from View:
57 bool OnMousePressed(const ui::MouseEvent& event) override; 66 bool OnMousePressed(const ui::MouseEvent& event) override;
58 void OnMouseEntered(const ui::MouseEvent& event) override; 67 void OnMouseEntered(const ui::MouseEvent& event) override;
59 void OnMouseExited(const ui::MouseEvent& event) override; 68 void OnMouseExited(const ui::MouseEvent& event) override;
60 void OnGestureEvent(ui::GestureEvent* event) override; 69 void OnGestureEvent(ui::GestureEvent* event) override;
61 gfx::Size GetPreferredSize() const override; 70 gfx::Size GetPreferredSize() const override;
62 void Layout() override; 71 void Layout() override;
63 const char* GetClassName() const override; 72 const char* GetClassName() const override;
64 73
74 protected:
75 Label* title_;
sky 2016/08/31 16:44:03 Style guide says no protected members.
Elly Fong-Jones 2016/08/31 16:49:10 Done.
76
65 private: 77 private:
66 enum TabState { 78 enum TabState {
67 TAB_INACTIVE, 79 TAB_INACTIVE,
68 TAB_ACTIVE, 80 TAB_ACTIVE,
69 TAB_HOVERED, 81 TAB_HOVERED,
70 }; 82 };
71 83
72 void SetState(TabState tab_state); 84 void SetState(TabState tab_state);
73 85
74 TabbedPane* tabbed_pane_; 86 TabbedPane* tabbed_pane_;
75 Label* title_;
76 gfx::Size preferred_title_size_; 87 gfx::Size preferred_title_size_;
77 TabState tab_state_; 88 TabState tab_state_;
78 // The content view associated with this tab. 89 // The content view associated with this tab.
79 View* contents_; 90 View* contents_;
80 91
81 DISALLOW_COPY_AND_ASSIGN(Tab); 92 DISALLOW_COPY_AND_ASSIGN(Tab);
82 }; 93 };
83 94
95 // A subclass of Tab that implements the Harmony visual styling.
96 class MdTab : public Tab {
97 public:
98 MdTab(TabbedPane* tabbed_pane, const base::string16& title, View* contents);
99 ~MdTab() override;
100
101 // Overridden from Tab:
102 void OnStateChanged() override;
103
104 private:
105 DISALLOW_COPY_AND_ASSIGN(MdTab);
106 };
107
84 // The tab strip shown above the tab contents. 108 // The tab strip shown above the tab contents.
85 class TabStrip : public View { 109 class TabStrip : public View {
86 public: 110 public:
87 // Internal class name. 111 // Internal class name.
88 static const char kViewClassName[]; 112 static const char kViewClassName[];
89 113
90 explicit TabStrip(TabbedPane* tabbed_pane); 114 explicit TabStrip(TabbedPane* tabbed_pane);
91 ~TabStrip() override; 115 ~TabStrip() override;
92 116
93 // Overridden from View: 117 // Overridden from View:
94 gfx::Size GetPreferredSize() const override; 118 gfx::Size GetPreferredSize() const override;
95 void Layout() override; 119 void Layout() override;
96 const char* GetClassName() const override; 120 const char* GetClassName() const override;
97 void OnPaint(gfx::Canvas* canvas) override; 121 void OnPaint(gfx::Canvas* canvas) override;
98 122
99 private: 123 private:
100 TabbedPane* tabbed_pane_; 124 TabbedPane* tabbed_pane_;
101 125
102 DISALLOW_COPY_AND_ASSIGN(TabStrip); 126 DISALLOW_COPY_AND_ASSIGN(TabStrip);
103 }; 127 };
104 128
129 // A subclass of TabStrip that implements the Harmony visual styling. This
130 // class uses a BoxLayout to position tabs.
131 class MdTabStrip : public TabStrip {
132 public:
133 explicit MdTabStrip(TabbedPane* tabbed_pane);
134 ~MdTabStrip() override;
135
136 // Overridden from View:
137 gfx::Size GetPreferredSize() const override;
138 void Layout() override;
139 void OnPaint(gfx::Canvas* canvas) override;
140
141 private:
142 DISALLOW_COPY_AND_ASSIGN(MdTabStrip);
143 };
144
105 // static 145 // static
106 const char Tab::kViewClassName[] = "Tab"; 146 const char Tab::kViewClassName[] = "Tab";
107 147
108 Tab::Tab(TabbedPane* tabbed_pane, const base::string16& title, View* contents) 148 Tab::Tab(TabbedPane* tabbed_pane, const base::string16& title, View* contents)
109 : tabbed_pane_(tabbed_pane), 149 : title_(new Label(
110 title_(new Label(
111 title, 150 title,
112 ui::ResourceBundle::GetSharedInstance().GetFontListWithDelta( 151 ui::ResourceBundle::GetSharedInstance().GetFontListWithDelta(
113 ui::kLabelFontSizeDelta, 152 ui::kLabelFontSizeDelta,
114 gfx::Font::NORMAL, 153 gfx::Font::NORMAL,
115 kActiveWeight))), 154 kActiveWeight))),
155 tabbed_pane_(tabbed_pane),
116 tab_state_(TAB_ACTIVE), 156 tab_state_(TAB_ACTIVE),
117 contents_(contents) { 157 contents_(contents) {
118 // Calculate this now while the font list is guaranteed to be bold. 158 // Calculate this now while the font list is guaranteed to be bold.
119 preferred_title_size_ = title_->GetPreferredSize(); 159 preferred_title_size_ = title_->GetPreferredSize();
120 160
121 SetState(TAB_INACTIVE); 161 SetState(TAB_INACTIVE);
122 AddChildView(title_); 162 AddChildView(title_);
123 } 163 }
124 164
125 Tab::~Tab() {} 165 Tab::~Tab() {}
126 166
127 void Tab::SetSelected(bool selected) { 167 void Tab::SetSelected(bool selected) {
128 contents_->SetVisible(selected); 168 contents_->SetVisible(selected);
129 SetState(selected ? TAB_ACTIVE : TAB_INACTIVE); 169 SetState(selected ? TAB_ACTIVE : TAB_INACTIVE);
130 } 170 }
131 171
172 void Tab::OnStateChanged() {
173 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
174 switch (tab_state_) {
175 case TAB_INACTIVE:
176 title_->SetEnabledColor(kTabTitleColor_Inactive);
177 title_->SetFontList(rb.GetFontListWithDelta(
178 ui::kLabelFontSizeDelta, gfx::Font::NORMAL, kInactiveWeight));
179 break;
180 case TAB_ACTIVE:
181 title_->SetEnabledColor(kTabTitleColor_Active);
182 title_->SetFontList(rb.GetFontListWithDelta(
183 ui::kLabelFontSizeDelta, gfx::Font::NORMAL, kActiveWeight));
184 break;
185 case TAB_HOVERED:
186 title_->SetEnabledColor(kTabTitleColor_Hovered);
187 title_->SetFontList(rb.GetFontListWithDelta(
188 ui::kLabelFontSizeDelta, gfx::Font::NORMAL, kHoverWeight));
189 break;
190 }
191 }
192
132 bool Tab::OnMousePressed(const ui::MouseEvent& event) { 193 bool Tab::OnMousePressed(const ui::MouseEvent& event) {
133 if (event.IsOnlyLeftMouseButton() && 194 if (event.IsOnlyLeftMouseButton() &&
134 GetLocalBounds().Contains(event.location())) 195 GetLocalBounds().Contains(event.location()))
135 tabbed_pane_->SelectTab(this); 196 tabbed_pane_->SelectTab(this);
136 return true; 197 return true;
137 } 198 }
138 199
139 void Tab::OnMouseEntered(const ui::MouseEvent& event) { 200 void Tab::OnMouseEntered(const ui::MouseEvent& event) {
140 SetState(selected() ? TAB_ACTIVE : TAB_HOVERED); 201 SetState(selected() ? TAB_ACTIVE : TAB_HOVERED);
141 } 202 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 } 239 }
179 240
180 const char* Tab::GetClassName() const { 241 const char* Tab::GetClassName() const {
181 return kViewClassName; 242 return kViewClassName;
182 } 243 }
183 244
184 void Tab::SetState(TabState tab_state) { 245 void Tab::SetState(TabState tab_state) {
185 if (tab_state == tab_state_) 246 if (tab_state == tab_state_)
186 return; 247 return;
187 tab_state_ = tab_state; 248 tab_state_ = tab_state;
188 249 OnStateChanged();
189 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
190 switch (tab_state) {
191 case TAB_INACTIVE:
192 title_->SetEnabledColor(kTabTitleColor_Inactive);
193 title_->SetFontList(rb.GetFontListWithDelta(
194 ui::kLabelFontSizeDelta, gfx::Font::NORMAL, kInactiveWeight));
195 break;
196 case TAB_ACTIVE:
197 title_->SetEnabledColor(kTabTitleColor_Active);
198 title_->SetFontList(rb.GetFontListWithDelta(
199 ui::kLabelFontSizeDelta, gfx::Font::NORMAL, kActiveWeight));
200 break;
201 case TAB_HOVERED:
202 title_->SetEnabledColor(kTabTitleColor_Hovered);
203 title_->SetFontList(rb.GetFontListWithDelta(
204 ui::kLabelFontSizeDelta, gfx::Font::NORMAL, kHoverWeight));
205 break;
206 }
207 SchedulePaint(); 250 SchedulePaint();
208 } 251 }
209 252
253 MdTab::MdTab(TabbedPane* tabbed_pane,
254 const base::string16& title,
255 View* contents)
256 : Tab(tabbed_pane, title, contents) {
257 OnStateChanged();
258 }
259
260 MdTab::~MdTab() {}
261
262 void MdTab::OnStateChanged() {
263 // These values are directly from the Harmony specs for tabbed panes.
264 const SkColor kSelectedBorderColor = SkColorSetRGB(0x42, 0x85, 0xF4);
265 const SkColor kNormalBorderColor = SkColorSetARGB(0x23, 0x00, 0x00, 0x00);
266 const SkColor kSelectedFontColor = SkColorSetRGB(0x42, 0x85, 0xF4);
267 const SkColor kNormalFontColor = SkColorSetRGB(0x5A, 0x5A, 0x5A);
268
269 SkColor border_color = selected() ? kSelectedBorderColor : kNormalBorderColor;
270 int border_thickness = selected() ? 2 : 1;
271 SetBorder(
272 Border::CreateSolidSidedBorder(0, 0, border_thickness, 0, border_color));
273
274 SkColor font_color = selected() ? kSelectedFontColor : kNormalFontColor;
275 title_->SetEnabledColor(font_color);
276
277 gfx::Font::Weight font_weight = gfx::Font::Weight::NORMAL;
278 #if defined(OS_WIN)
279 if (selected())
280 font_weight = gfx::Font::Weight::BOLD;
281 #endif
282
283 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
284 title_->SetFontList(rb.GetFontListWithDelta(ui::kLabelFontSizeDelta,
285 gfx::Font::NORMAL, font_weight));
286 }
287
210 // static 288 // static
211 const char TabStrip::kViewClassName[] = "TabStrip"; 289 const char TabStrip::kViewClassName[] = "TabStrip";
212 290
213 TabStrip::TabStrip(TabbedPane* tabbed_pane) : tabbed_pane_(tabbed_pane) {} 291 TabStrip::TabStrip(TabbedPane* tabbed_pane) : tabbed_pane_(tabbed_pane) {}
214 292
215 TabStrip::~TabStrip() {} 293 TabStrip::~TabStrip() {}
216 294
217 gfx::Size TabStrip::GetPreferredSize() const { 295 gfx::Size TabStrip::GetPreferredSize() const {
218 gfx::Size size; 296 gfx::Size size;
219 for (int i = 0; i < child_count(); ++i) { 297 for (int i = 0; i < child_count(); ++i) {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
266 SkPaint paint; 344 SkPaint paint;
267 paint.setStyle(SkPaint::kStroke_Style); 345 paint.setStyle(SkPaint::kStroke_Style);
268 paint.setColor(kTabBorderColor); 346 paint.setColor(kTabBorderColor);
269 paint.setStrokeWidth(kTabBorderThickness); 347 paint.setStrokeWidth(kTabBorderThickness);
270 canvas->DrawPath(path, paint); 348 canvas->DrawPath(path, paint);
271 } else { 349 } else {
272 canvas->sk_canvas()->drawLine(0, line_y, line_end, line_y, paint); 350 canvas->sk_canvas()->drawLine(0, line_y, line_end, line_y, paint);
273 } 351 }
274 } 352 }
275 353
354 MdTabStrip::MdTabStrip(TabbedPane* tabbed_pane) : TabStrip(tabbed_pane) {
355 BoxLayout* layout =
356 new BoxLayout(BoxLayout::kHorizontal, 0, kHarmonyTabStripVerticalPad, 0);
357 layout->set_main_axis_alignment(BoxLayout::MAIN_AXIS_ALIGNMENT_CENTER);
358 layout->set_cross_axis_alignment(BoxLayout::CROSS_AXIS_ALIGNMENT_STRETCH);
359 layout->SetDefaultFlex(1);
360 SetLayoutManager(layout);
361 }
362
363 MdTabStrip::~MdTabStrip() {}
364
365 gfx::Size MdTabStrip::GetPreferredSize() const {
366 return gfx::Size(width(),
367 kHarmonyTabStripVerticalPad * 2 + kHarmonyTabStripTabHeight);
368 }
369
370 // Let this class's LayoutManager handle the layout.
371 void MdTabStrip::Layout() {
372 return View::Layout();
373 }
374
375 // The tab strip "border" is drawn as part of the tabs, so all this method needs
376 // to do is paint the background.
377 void MdTabStrip::OnPaint(gfx::Canvas* canvas) {
378 OnPaintBackground(canvas);
379 }
380
276 TabbedPane::TabbedPane() 381 TabbedPane::TabbedPane()
277 : listener_(NULL), 382 : listener_(NULL),
278 tab_strip_(new TabStrip(this)), 383 tab_strip_(ui::MaterialDesignController::IsSecondaryUiMaterial()
279 contents_(new View()), 384 ? new MdTabStrip(this)
280 selected_tab_index_(-1) { 385 : new TabStrip(this)),
386 contents_(new View()),
387 selected_tab_index_(-1) {
281 #if defined(OS_MACOSX) 388 #if defined(OS_MACOSX)
282 SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY); 389 SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY);
283 #else 390 #else
284 SetFocusBehavior(FocusBehavior::ALWAYS); 391 SetFocusBehavior(FocusBehavior::ALWAYS);
285 #endif 392 #endif
286 393
287 AddChildView(tab_strip_); 394 AddChildView(tab_strip_);
288 AddChildView(contents_); 395 AddChildView(contents_);
289 } 396 }
290 397
(...skipping 12 matching lines...) Expand all
303 void TabbedPane::AddTab(const base::string16& title, View* contents) { 410 void TabbedPane::AddTab(const base::string16& title, View* contents) {
304 AddTabAtIndex(tab_strip_->child_count(), title, contents); 411 AddTabAtIndex(tab_strip_->child_count(), title, contents);
305 } 412 }
306 413
307 void TabbedPane::AddTabAtIndex(int index, 414 void TabbedPane::AddTabAtIndex(int index,
308 const base::string16& title, 415 const base::string16& title,
309 View* contents) { 416 View* contents) {
310 DCHECK(index >= 0 && index <= GetTabCount()); 417 DCHECK(index >= 0 && index <= GetTabCount());
311 contents->SetVisible(false); 418 contents->SetVisible(false);
312 419
313 tab_strip_->AddChildViewAt(new Tab(this, title, contents), index); 420 tab_strip_->AddChildViewAt(
421 ui::MaterialDesignController::IsSecondaryUiMaterial()
422 ? new MdTab(this, title, contents)
423 : new Tab(this, title, contents),
424 index);
314 contents_->AddChildViewAt(contents, index); 425 contents_->AddChildViewAt(contents, index);
315 if (selected_tab_index() < 0) 426 if (selected_tab_index() < 0)
316 SelectTabAt(index); 427 SelectTabAt(index);
317 428
318 PreferredSizeChanged(); 429 PreferredSizeChanged();
319 } 430 }
320 431
321 void TabbedPane::SelectTabAt(int index) { 432 void TabbedPane::SelectTabAt(int index) {
322 DCHECK(index >= 0 && index < GetTabCount()); 433 DCHECK(index >= 0 && index < GetTabCount());
323 if (index == selected_tab_index()) 434 if (index == selected_tab_index())
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
407 selected_tab->NotifyAccessibilityEvent( 518 selected_tab->NotifyAccessibilityEvent(
408 ui::AX_EVENT_FOCUS, true); 519 ui::AX_EVENT_FOCUS, true);
409 } 520 }
410 } 521 }
411 522
412 void TabbedPane::GetAccessibleState(ui::AXViewState* state) { 523 void TabbedPane::GetAccessibleState(ui::AXViewState* state) {
413 state->role = ui::AX_ROLE_TAB_LIST; 524 state->role = ui::AX_ROLE_TAB_LIST;
414 } 525 }
415 526
416 } // namespace views 527 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/controls/tabbed_pane/tabbed_pane.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698