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

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

Issue 2810403002: Views: Don't add insets for views::Link focus rings under MD. (Closed)
Patch Set: Add missing // namespace comments Created 3 years, 8 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/label.h ('k') | ui/views/controls/label_unittest.cc » ('j') | 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/label.h" 5 #include "ui/views/controls/label.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <cmath> 10 #include <cmath>
11 #include <limits> 11 #include <limits>
12 #include <utility> 12 #include <utility>
13 #include <vector> 13 #include <vector>
14 14
15 #include "base/i18n/rtl.h" 15 #include "base/i18n/rtl.h"
16 #include "base/logging.h" 16 #include "base/logging.h"
17 #include "base/memory/ptr_util.h" 17 #include "base/memory/ptr_util.h"
18 #include "base/profiler/scoped_tracker.h" 18 #include "base/profiler/scoped_tracker.h"
19 #include "base/strings/string_split.h" 19 #include "base/strings/string_split.h"
20 #include "base/strings/utf_string_conversions.h" 20 #include "base/strings/utf_string_conversions.h"
21 #include "ui/accessibility/ax_node_data.h" 21 #include "ui/accessibility/ax_node_data.h"
22 #include "ui/base/clipboard/scoped_clipboard_writer.h" 22 #include "ui/base/clipboard/scoped_clipboard_writer.h"
23 #include "ui/base/cursor/cursor.h" 23 #include "ui/base/cursor/cursor.h"
24 #include "ui/base/default_style.h" 24 #include "ui/base/default_style.h"
25 #include "ui/base/material_design/material_design_controller.h"
26 #include "ui/gfx/canvas.h" 25 #include "ui/gfx/canvas.h"
27 #include "ui/gfx/color_utils.h" 26 #include "ui/gfx/color_utils.h"
28 #include "ui/gfx/geometry/insets.h" 27 #include "ui/gfx/geometry/insets.h"
29 #include "ui/gfx/text_elider.h" 28 #include "ui/gfx/text_elider.h"
30 #include "ui/native_theme/native_theme.h" 29 #include "ui/native_theme/native_theme.h"
31 #include "ui/strings/grit/ui_strings.h" 30 #include "ui/strings/grit/ui_strings.h"
32 #include "ui/views/background.h" 31 #include "ui/views/background.h"
33 #include "ui/views/controls/menu/menu_runner.h" 32 #include "ui/views/controls/menu/menu_runner.h"
34 #include "ui/views/focus/focus_manager.h" 33 #include "ui/views/focus/focus_manager.h"
35 #include "ui/views/native_cursor.h" 34 #include "ui/views/native_cursor.h"
36 #include "ui/views/selection_controller.h" 35 #include "ui/views/selection_controller.h"
37 36
38 namespace views { 37 namespace views {
39 // static 38 namespace {
39 // Returns additional Insets applied to |label->GetContentsBounds()| to obtain
40 // the text bounds. GetContentsBounds() includes the Border, but not any
41 // additional insets used by the Label (e.g. for a focus ring).
42 gfx::Insets NonBorderInsets(const Label& label) {
43 return label.GetInsets() - label.View::GetInsets();
44 }
45 } // namespace
46
40 const char Label::kViewClassName[] = "Label"; 47 const char Label::kViewClassName[] = "Label";
41 const int Label::kFocusBorderPadding = 1;
42 48
43 Label::Label() : Label(base::string16()) { 49 Label::Label() : Label(base::string16()) {
44 } 50 }
45 51
46 Label::Label(const base::string16& text) 52 Label::Label(const base::string16& text)
47 : Label(text, style::CONTEXT_LABEL, style::STYLE_PRIMARY) {} 53 : Label(text, style::CONTEXT_LABEL, style::STYLE_PRIMARY) {}
48 54
49 Label::Label(const base::string16& text, int text_context, int text_style) 55 Label::Label(const base::string16& text, int text_context, int text_style)
50 : context_menu_contents_(this) { 56 : context_menu_contents_(this) {
51 Init(text, style::GetFont(text_context, text_style)); 57 Init(text, style::GetFont(text_context, text_style));
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 render_text->ClearSelection(); 301 render_text->ClearSelection();
296 SchedulePaint(); 302 SchedulePaint();
297 } 303 }
298 304
299 void Label::SelectRange(const gfx::Range& range) { 305 void Label::SelectRange(const gfx::Range& range) {
300 gfx::RenderText* render_text = GetRenderTextForSelectionController(); 306 gfx::RenderText* render_text = GetRenderTextForSelectionController();
301 if (render_text && render_text->SelectRange(range)) 307 if (render_text && render_text->SelectRange(range))
302 SchedulePaint(); 308 SchedulePaint();
303 } 309 }
304 310
305 gfx::Insets Label::GetInsets() const {
306 gfx::Insets insets = View::GetInsets();
307 if (focus_behavior() != FocusBehavior::NEVER) {
308 insets += gfx::Insets(kFocusBorderPadding, kFocusBorderPadding,
309 kFocusBorderPadding, kFocusBorderPadding);
310 }
311 return insets;
312 }
313
314 int Label::GetBaseline() const { 311 int Label::GetBaseline() const {
315 return GetInsets().top() + font_list().GetBaseline(); 312 return GetInsets().top() + font_list().GetBaseline();
316 } 313 }
317 314
318 gfx::Size Label::GetPreferredSize() const { 315 gfx::Size Label::GetPreferredSize() const {
319 // Return a size of (0, 0) if the label is not visible and if the 316 // Return a size of (0, 0) if the label is not visible and if the
320 // |collapse_when_hidden_| flag is set. 317 // |collapse_when_hidden_| flag is set.
321 // TODO(munjal): This logic probably belongs to the View class. But for now, 318 // TODO(munjal): This logic probably belongs to the View class. But for now,
322 // put it here since putting it in View class means all inheriting classes 319 // put it here since putting it in View class means all inheriting classes
323 // need to respect the |collapse_when_hidden_| flag. 320 // need to respect the |collapse_when_hidden_| flag.
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
446 render_text->SetElideBehavior(elide_behavior); 443 render_text->SetElideBehavior(elide_behavior);
447 render_text->SetObscured(obscured()); 444 render_text->SetObscured(obscured());
448 render_text->SetMinLineHeight(line_height()); 445 render_text->SetMinLineHeight(line_height());
449 render_text->SetFontList(font_list()); 446 render_text->SetFontList(font_list());
450 render_text->set_shadows(shadows()); 447 render_text->set_shadows(shadows());
451 render_text->SetCursorEnabled(false); 448 render_text->SetCursorEnabled(false);
452 render_text->SetText(text); 449 render_text->SetText(text);
453 return render_text; 450 return render_text;
454 } 451 }
455 452
453 void Label::PaintFocusRing(gfx::Canvas* canvas) const {
454 // No focus ring by default.
455 }
456
457 gfx::Rect Label::GetFocusRingBounds() const {
458 MaybeBuildRenderTextLines();
459
460 gfx::Rect focus_bounds;
461 if (lines_.empty()) {
462 focus_bounds = gfx::Rect(GetTextSize());
463 } else {
464 for (size_t i = 0; i < lines_.size(); ++i) {
465 gfx::Point origin;
466 origin += lines_[i]->GetLineOffset(0);
467 focus_bounds.Union(gfx::Rect(origin, lines_[i]->GetStringSize()));
468 }
469 }
470
471 focus_bounds.Inset(-NonBorderInsets(*this));
472 focus_bounds.Intersect(GetLocalBounds());
473 return focus_bounds;
474 }
475
456 void Label::PaintText(gfx::Canvas* canvas) { 476 void Label::PaintText(gfx::Canvas* canvas) {
457 MaybeBuildRenderTextLines(); 477 MaybeBuildRenderTextLines();
458 478
459 for (size_t i = 0; i < lines_.size(); ++i) 479 for (size_t i = 0; i < lines_.size(); ++i)
460 lines_[i]->Draw(canvas); 480 lines_[i]->Draw(canvas);
461 481
462 #if DCHECK_IS_ON() 482 #if DCHECK_IS_ON()
463 // Attempt to ensure that if we're using subpixel rendering, we're painting 483 // Attempt to ensure that if we're using subpixel rendering, we're painting
464 // to an opaque background. What we don't want to find is an ancestor in the 484 // to an opaque background. What we don't want to find is an ancestor in the
465 // hierarchy that paints to a non-opaque layer. 485 // hierarchy that paints to a non-opaque layer.
(...skipping 26 matching lines...) Expand all
492 // fixed. 512 // fixed.
493 tracked_objects::ScopedTracker tracking_profile( 513 tracked_objects::ScopedTracker tracking_profile(
494 FROM_HERE_WITH_EXPLICIT_FUNCTION("441028 First PaintText()")); 514 FROM_HERE_WITH_EXPLICIT_FUNCTION("441028 First PaintText()"));
495 515
496 is_first_paint_text_ = false; 516 is_first_paint_text_ = false;
497 PaintText(canvas); 517 PaintText(canvas);
498 } else { 518 } else {
499 PaintText(canvas); 519 PaintText(canvas);
500 } 520 }
501 521
502 // Check for IsAccessibilityFocusable() to prevent drawing a focus rect for 522 if (HasFocus())
503 // non-focusable labels with selection, which are given focus explicitly in 523 PaintFocusRing(canvas);
504 // OnMousePressed.
505 if (HasFocus() && !ui::MaterialDesignController::IsSecondaryUiMaterial() &&
506 IsAccessibilityFocusable()) {
507 canvas->DrawFocusRect(GetFocusBounds());
508 }
509 } 524 }
510 525
511 void Label::OnNativeThemeChanged(const ui::NativeTheme* theme) { 526 void Label::OnNativeThemeChanged(const ui::NativeTheme* theme) {
512 UpdateColorsFromTheme(theme); 527 UpdateColorsFromTheme(theme);
513 } 528 }
514 529
515 gfx::NativeCursor Label::GetCursor(const ui::MouseEvent& event) { 530 gfx::NativeCursor Label::GetCursor(const ui::MouseEvent& event) {
516 return GetRenderTextForSelectionController() ? GetNativeIBeamCursor() 531 return GetRenderTextForSelectionController() ? GetNativeIBeamCursor()
517 : gfx::kNullCursor; 532 : gfx::kNullCursor;
518 } 533 }
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after
836 PreferredSizeChanged(); 851 PreferredSizeChanged();
837 SchedulePaint(); 852 SchedulePaint();
838 ClearRenderTextLines(); 853 ClearRenderTextLines();
839 } 854 }
840 855
841 void Label::MaybeBuildRenderTextLines() const { 856 void Label::MaybeBuildRenderTextLines() const {
842 if (!lines_.empty()) 857 if (!lines_.empty())
843 return; 858 return;
844 859
845 gfx::Rect rect = GetContentsBounds(); 860 gfx::Rect rect = GetContentsBounds();
846 if (focus_behavior() != FocusBehavior::NEVER) 861 rect.Inset(NonBorderInsets(*this));
847 rect.Inset(kFocusBorderPadding, kFocusBorderPadding);
848 if (rect.IsEmpty()) 862 if (rect.IsEmpty())
849 return; 863 return;
864
850 rect.Inset(-gfx::ShadowValue::GetMargin(shadows())); 865 rect.Inset(-gfx::ShadowValue::GetMargin(shadows()));
851 866
852 gfx::HorizontalAlignment alignment = horizontal_alignment(); 867 gfx::HorizontalAlignment alignment = horizontal_alignment();
853 gfx::DirectionalityMode directionality = render_text_->directionality_mode(); 868 gfx::DirectionalityMode directionality = render_text_->directionality_mode();
854 if (multi_line()) { 869 if (multi_line()) {
855 // Force the directionality and alignment of the first line on other lines. 870 // Force the directionality and alignment of the first line on other lines.
856 bool rtl = 871 bool rtl =
857 render_text_->GetDisplayTextDirection() == base::i18n::RIGHT_TO_LEFT; 872 render_text_->GetDisplayTextDirection() == base::i18n::RIGHT_TO_LEFT;
858 if (alignment == gfx::ALIGN_TO_HEAD) 873 if (alignment == gfx::ALIGN_TO_HEAD)
859 alignment = rtl ? gfx::ALIGN_RIGHT : gfx::ALIGN_LEFT; 874 alignment = rtl ? gfx::ALIGN_RIGHT : gfx::ALIGN_LEFT;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
895 } 910 }
896 // Append the remaining text to the last visible line. 911 // Append the remaining text to the last visible line.
897 for (size_t i = lines_.size(); i < lines.size(); ++i) 912 for (size_t i = lines_.size(); i < lines.size(); ++i)
898 lines_.back()->SetText(lines_.back()->text() + lines[i]); 913 lines_.back()->SetText(lines_.back()->text() + lines[i]);
899 } 914 }
900 915
901 stored_selection_range_ = gfx::Range::InvalidRange(); 916 stored_selection_range_ = gfx::Range::InvalidRange();
902 ApplyTextColors(); 917 ApplyTextColors();
903 } 918 }
904 919
905 gfx::Rect Label::GetFocusBounds() const {
906 MaybeBuildRenderTextLines();
907
908 gfx::Rect focus_bounds;
909 if (lines_.empty()) {
910 focus_bounds = gfx::Rect(GetTextSize());
911 } else {
912 for (size_t i = 0; i < lines_.size(); ++i) {
913 gfx::Point origin;
914 origin += lines_[i]->GetLineOffset(0);
915 focus_bounds.Union(gfx::Rect(origin, lines_[i]->GetStringSize()));
916 }
917 }
918
919 focus_bounds.Inset(-kFocusBorderPadding, -kFocusBorderPadding);
920 focus_bounds.Intersect(GetLocalBounds());
921 return focus_bounds;
922 }
923
924 std::vector<base::string16> Label::GetLinesForWidth(int width) const { 920 std::vector<base::string16> Label::GetLinesForWidth(int width) const {
925 std::vector<base::string16> lines; 921 std::vector<base::string16> lines;
926 // |width| can be 0 when getting the default text size, in that case 922 // |width| can be 0 when getting the default text size, in that case
927 // the ideal lines (i.e. broken at newline characters) are wanted. 923 // the ideal lines (i.e. broken at newline characters) are wanted.
928 if (width <= 0) { 924 if (width <= 0) {
929 lines = base::SplitString( 925 lines = base::SplitString(
930 render_text_->GetDisplayText(), base::string16(1, '\n'), 926 render_text_->GetDisplayText(), base::string16(1, '\n'),
931 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); 927 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
932 } else { 928 } else {
933 gfx::ElideRectangleText(render_text_->GetDisplayText(), font_list(), width, 929 gfx::ElideRectangleText(render_text_->GetDisplayText(), font_list(), width,
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
1059 .WriteText(GetSelectedText()); 1055 .WriteText(GetSelectedText());
1060 } 1056 }
1061 1057
1062 void Label::BuildContextMenuContents() { 1058 void Label::BuildContextMenuContents() {
1063 context_menu_contents_.AddItemWithStringId(IDS_APP_COPY, IDS_APP_COPY); 1059 context_menu_contents_.AddItemWithStringId(IDS_APP_COPY, IDS_APP_COPY);
1064 context_menu_contents_.AddItemWithStringId(IDS_APP_SELECT_ALL, 1060 context_menu_contents_.AddItemWithStringId(IDS_APP_SELECT_ALL,
1065 IDS_APP_SELECT_ALL); 1061 IDS_APP_SELECT_ALL);
1066 } 1062 }
1067 1063
1068 } // namespace views 1064 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/controls/label.h ('k') | ui/views/controls/label_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698