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

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: Tests passing 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
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
40 const char Label::kViewClassName[] = "Label"; 39 const char Label::kViewClassName[] = "Label";
41 const int Label::kFocusBorderPadding = 1;
42 40
43 Label::Label() : Label(base::string16()) { 41 Label::Label() : Label(base::string16()) {
44 } 42 }
45 43
46 Label::Label(const base::string16& text) 44 Label::Label(const base::string16& text)
47 : Label(text, style::CONTEXT_LABEL, style::STYLE_PRIMARY) {} 45 : Label(text, style::CONTEXT_LABEL, style::STYLE_PRIMARY) {}
48 46
49 Label::Label(const base::string16& text, int text_context, int text_style) 47 Label::Label(const base::string16& text, int text_context, int text_style)
50 : context_menu_contents_(this) { 48 : context_menu_contents_(this) {
51 Init(text, style::GetFont(text_context, text_style)); 49 Init(text, style::GetFont(text_context, text_style));
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 render_text->ClearSelection(); 293 render_text->ClearSelection();
296 SchedulePaint(); 294 SchedulePaint();
297 } 295 }
298 296
299 void Label::SelectRange(const gfx::Range& range) { 297 void Label::SelectRange(const gfx::Range& range) {
300 gfx::RenderText* render_text = GetRenderTextForSelectionController(); 298 gfx::RenderText* render_text = GetRenderTextForSelectionController();
301 if (render_text && render_text->SelectRange(range)) 299 if (render_text && render_text->SelectRange(range))
302 SchedulePaint(); 300 SchedulePaint();
303 } 301 }
304 302
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 { 303 int Label::GetBaseline() const {
315 return GetInsets().top() + font_list().GetBaseline(); 304 return GetInsets().top() + font_list().GetBaseline();
316 } 305 }
317 306
318 gfx::Size Label::GetPreferredSize() const { 307 gfx::Size Label::GetPreferredSize() const {
319 // Return a size of (0, 0) if the label is not visible and if the 308 // Return a size of (0, 0) if the label is not visible and if the
320 // |collapse_when_hidden_| flag is set. 309 // |collapse_when_hidden_| flag is set.
321 // TODO(munjal): This logic probably belongs to the View class. But for now, 310 // 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 311 // put it here since putting it in View class means all inheriting classes
323 // need to respect the |collapse_when_hidden_| flag. 312 // 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); 435 render_text->SetElideBehavior(elide_behavior);
447 render_text->SetObscured(obscured()); 436 render_text->SetObscured(obscured());
448 render_text->SetMinLineHeight(line_height()); 437 render_text->SetMinLineHeight(line_height());
449 render_text->SetFontList(font_list()); 438 render_text->SetFontList(font_list());
450 render_text->set_shadows(shadows()); 439 render_text->set_shadows(shadows());
451 render_text->SetCursorEnabled(false); 440 render_text->SetCursorEnabled(false);
452 render_text->SetText(text); 441 render_text->SetText(text);
453 return render_text; 442 return render_text;
454 } 443 }
455 444
445 void Label::MaybePaintFocusRing(gfx::Canvas* canvas) const {
446 // No focus ring by default.
447 }
448
449 gfx::Rect Label::GetFocusRingBounds() const {
450 MaybeBuildRenderTextLines();
451
452 gfx::Rect focus_bounds;
453 if (lines_.empty()) {
454 focus_bounds = gfx::Rect(GetTextSize());
455 } else {
456 for (size_t i = 0; i < lines_.size(); ++i) {
457 gfx::Point origin;
458 origin += lines_[i]->GetLineOffset(0);
459 focus_bounds.Union(gfx::Rect(origin, lines_[i]->GetStringSize()));
460 }
461 }
462
463 focus_bounds.Inset(-(GetInsets() - View::GetInsets()));
464 focus_bounds.Intersect(GetLocalBounds());
465 return focus_bounds;
466 }
467
456 void Label::PaintText(gfx::Canvas* canvas) { 468 void Label::PaintText(gfx::Canvas* canvas) {
457 MaybeBuildRenderTextLines(); 469 MaybeBuildRenderTextLines();
458 470
459 for (size_t i = 0; i < lines_.size(); ++i) 471 for (size_t i = 0; i < lines_.size(); ++i)
460 lines_[i]->Draw(canvas); 472 lines_[i]->Draw(canvas);
461 473
462 #if DCHECK_IS_ON() 474 #if DCHECK_IS_ON()
463 // Attempt to ensure that if we're using subpixel rendering, we're painting 475 // 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 476 // 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. 477 // hierarchy that paints to a non-opaque layer.
(...skipping 26 matching lines...) Expand all
492 // fixed. 504 // fixed.
493 tracked_objects::ScopedTracker tracking_profile( 505 tracked_objects::ScopedTracker tracking_profile(
494 FROM_HERE_WITH_EXPLICIT_FUNCTION("441028 First PaintText()")); 506 FROM_HERE_WITH_EXPLICIT_FUNCTION("441028 First PaintText()"));
495 507
496 is_first_paint_text_ = false; 508 is_first_paint_text_ = false;
497 PaintText(canvas); 509 PaintText(canvas);
498 } else { 510 } else {
499 PaintText(canvas); 511 PaintText(canvas);
500 } 512 }
501 513
502 // Check for IsAccessibilityFocusable() to prevent drawing a focus rect for 514 if (HasFocus())
503 // non-focusable labels with selection, which are given focus explicitly in 515 MaybePaintFocusRing(canvas);
tapted 2017/04/19 12:28:45 views::Link are never selectable (Link::IsSelectio
504 // OnMousePressed.
505 if (HasFocus() && !ui::MaterialDesignController::IsSecondaryUiMaterial() &&
506 IsAccessibilityFocusable()) {
507 canvas->DrawFocusRect(GetFocusBounds());
508 }
509 } 516 }
510 517
511 void Label::OnNativeThemeChanged(const ui::NativeTheme* theme) { 518 void Label::OnNativeThemeChanged(const ui::NativeTheme* theme) {
512 UpdateColorsFromTheme(theme); 519 UpdateColorsFromTheme(theme);
513 } 520 }
514 521
515 gfx::NativeCursor Label::GetCursor(const ui::MouseEvent& event) { 522 gfx::NativeCursor Label::GetCursor(const ui::MouseEvent& event) {
516 return GetRenderTextForSelectionController() ? GetNativeIBeamCursor() 523 return GetRenderTextForSelectionController() ? GetNativeIBeamCursor()
517 : gfx::kNullCursor; 524 : gfx::kNullCursor;
518 } 525 }
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after
836 PreferredSizeChanged(); 843 PreferredSizeChanged();
837 SchedulePaint(); 844 SchedulePaint();
838 ClearRenderTextLines(); 845 ClearRenderTextLines();
839 } 846 }
840 847
841 void Label::MaybeBuildRenderTextLines() const { 848 void Label::MaybeBuildRenderTextLines() const {
842 if (!lines_.empty()) 849 if (!lines_.empty())
843 return; 850 return;
844 851
845 gfx::Rect rect = GetContentsBounds(); 852 gfx::Rect rect = GetContentsBounds();
846 if (focus_behavior() != FocusBehavior::NEVER) 853 rect.Inset(GetInsets() - View::GetInsets());
sky 2017/04/19 17:27:46 This is very subtle and worth a comment. In fact I
tapted 2017/04/20 11:50:17 Done.
847 rect.Inset(kFocusBorderPadding, kFocusBorderPadding);
848 if (rect.IsEmpty()) 854 if (rect.IsEmpty())
849 return; 855 return;
856
850 rect.Inset(-gfx::ShadowValue::GetMargin(shadows())); 857 rect.Inset(-gfx::ShadowValue::GetMargin(shadows()));
851 858
852 gfx::HorizontalAlignment alignment = horizontal_alignment(); 859 gfx::HorizontalAlignment alignment = horizontal_alignment();
853 gfx::DirectionalityMode directionality = render_text_->directionality_mode(); 860 gfx::DirectionalityMode directionality = render_text_->directionality_mode();
854 if (multi_line()) { 861 if (multi_line()) {
855 // Force the directionality and alignment of the first line on other lines. 862 // Force the directionality and alignment of the first line on other lines.
856 bool rtl = 863 bool rtl =
857 render_text_->GetDisplayTextDirection() == base::i18n::RIGHT_TO_LEFT; 864 render_text_->GetDisplayTextDirection() == base::i18n::RIGHT_TO_LEFT;
858 if (alignment == gfx::ALIGN_TO_HEAD) 865 if (alignment == gfx::ALIGN_TO_HEAD)
859 alignment = rtl ? gfx::ALIGN_RIGHT : gfx::ALIGN_LEFT; 866 alignment = rtl ? gfx::ALIGN_RIGHT : gfx::ALIGN_LEFT;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
895 } 902 }
896 // Append the remaining text to the last visible line. 903 // Append the remaining text to the last visible line.
897 for (size_t i = lines_.size(); i < lines.size(); ++i) 904 for (size_t i = lines_.size(); i < lines.size(); ++i)
898 lines_.back()->SetText(lines_.back()->text() + lines[i]); 905 lines_.back()->SetText(lines_.back()->text() + lines[i]);
899 } 906 }
900 907
901 stored_selection_range_ = gfx::Range::InvalidRange(); 908 stored_selection_range_ = gfx::Range::InvalidRange();
902 ApplyTextColors(); 909 ApplyTextColors();
903 } 910 }
904 911
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 { 912 std::vector<base::string16> Label::GetLinesForWidth(int width) const {
925 std::vector<base::string16> lines; 913 std::vector<base::string16> lines;
926 // |width| can be 0 when getting the default text size, in that case 914 // |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. 915 // the ideal lines (i.e. broken at newline characters) are wanted.
928 if (width <= 0) { 916 if (width <= 0) {
929 lines = base::SplitString( 917 lines = base::SplitString(
930 render_text_->GetDisplayText(), base::string16(1, '\n'), 918 render_text_->GetDisplayText(), base::string16(1, '\n'),
931 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); 919 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
932 } else { 920 } else {
933 gfx::ElideRectangleText(render_text_->GetDisplayText(), font_list(), width, 921 gfx::ElideRectangleText(render_text_->GetDisplayText(), font_list(), width,
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
1059 .WriteText(GetSelectedText()); 1047 .WriteText(GetSelectedText());
1060 } 1048 }
1061 1049
1062 void Label::BuildContextMenuContents() { 1050 void Label::BuildContextMenuContents() {
1063 context_menu_contents_.AddItemWithStringId(IDS_APP_COPY, IDS_APP_COPY); 1051 context_menu_contents_.AddItemWithStringId(IDS_APP_COPY, IDS_APP_COPY);
1064 context_menu_contents_.AddItemWithStringId(IDS_APP_SELECT_ALL, 1052 context_menu_contents_.AddItemWithStringId(IDS_APP_SELECT_ALL,
1065 IDS_APP_SELECT_ALL); 1053 IDS_APP_SELECT_ALL);
1066 } 1054 }
1067 1055
1068 } // namespace views 1056 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698