1 // Copyright 2017 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 "chrome/browser/ui/views/chrome_layout_provider.h"
6
7 #include <algorithm>
8
9 #include "base/logging.h"
10 #include "chrome/browser/ui/views/chrome_typography.h"
11 #include "ui/base/pointer/touch_ui_controller.h"
12 #include "ui/gfx/shadow_value.h"
13
14 namespace {
15
16 // TODO(pbos): Inline kHarmonyLayoutUnit calculations below as it's not really
17 // respected (there's 3 * unit / 4 in use to express 12).
18 // The Harmony layout unit. All distances are in terms of this unit.
19 constexpr int kHarmonyLayoutUnit = 16;
20
21 ChromeLayoutProvider* g_chrome_layout_provider = nullptr;
22
23 } // namespace
24
ChromeLayoutProvider()25 ChromeLayoutProvider::ChromeLayoutProvider() {
26 DCHECK_EQ(nullptr, g_chrome_layout_provider);
27 g_chrome_layout_provider = this;
28 }
29
~ChromeLayoutProvider()30 ChromeLayoutProvider::~ChromeLayoutProvider() {
31 DCHECK_EQ(this, g_chrome_layout_provider);
32 g_chrome_layout_provider = nullptr;
33 }
34
35 // static
Get()36 ChromeLayoutProvider* ChromeLayoutProvider::Get() {
37 // Check to avoid downcasting a base LayoutProvider.
38 DCHECK_EQ(g_chrome_layout_provider, views::LayoutProvider::Get());
39 return static_cast<ChromeLayoutProvider*>(views::LayoutProvider::Get());
40 }
41
42 // static
43 std::unique_ptr<views::LayoutProvider>
CreateLayoutProvider()44 ChromeLayoutProvider::CreateLayoutProvider() {
45 return std::make_unique<ChromeLayoutProvider>();
46 }
47
GetInsetsMetric(int metric) const48 gfx::Insets ChromeLayoutProvider::GetInsetsMetric(int metric) const {
49 DCHECK_LT(metric, views::VIEWS_INSETS_MAX);
50 const bool touch_ui = ui::TouchUiController::Get()->touch_ui();
51 switch (metric) {
52 case views::INSETS_DIALOG:
53 case views::INSETS_DIALOG_SUBSECTION:
54 return gfx::Insets(kHarmonyLayoutUnit);
55 case views::INSETS_CHECKBOX_RADIO_BUTTON: {
56 gfx::Insets insets = LayoutProvider::GetInsetsMetric(metric);
57 // Checkboxes and radio buttons should be aligned flush to the left edge.
58 return gfx::Insets(insets.top(), 0, insets.bottom(), insets.right());
59 }
60 case views::INSETS_VECTOR_IMAGE_BUTTON:
61 return gfx::Insets(kHarmonyLayoutUnit / 4);
62 case views::InsetsMetric::INSETS_LABEL_BUTTON:
63 return touch_ui
64 ? gfx::Insets(kHarmonyLayoutUnit / 2, kHarmonyLayoutUnit / 2)
65 : LayoutProvider::GetInsetsMetric(metric);
66 case INSETS_BOOKMARKS_BAR_BUTTON:
67 return touch_ui ? gfx::Insets(8, 10) : gfx::Insets(6);
68 case INSETS_TOAST:
69 return gfx::Insets(0, kHarmonyLayoutUnit);
70 case INSETS_OMNIBOX_PILL_BUTTON:
71 return touch_ui ? gfx::Insets(kHarmonyLayoutUnit / 2, kHarmonyLayoutUnit)
72 : gfx::Insets(5, 12);
73 default:
74 return LayoutProvider::GetInsetsMetric(metric);
75 }
76 }
77
GetDistanceMetric(int metric) const78 int ChromeLayoutProvider::GetDistanceMetric(int metric) const {
79 DCHECK_GE(metric, views::VIEWS_DISTANCE_START);
80 DCHECK_LT(metric, views::VIEWS_DISTANCE_MAX);
81
82 if (metric < views::VIEWS_DISTANCE_END)
83 return LayoutProvider::GetDistanceMetric(metric);
84
85 switch (static_cast<ChromeDistanceMetric>(metric)) {
86 case DISTANCE_CONTENT_LIST_VERTICAL_SINGLE:
87 return kHarmonyLayoutUnit / 4;
88 case DISTANCE_CONTENT_LIST_VERTICAL_MULTI:
89 return kHarmonyLayoutUnit / 2;
90 case DISTANCE_CONTROL_LIST_VERTICAL:
91 return kHarmonyLayoutUnit * 3 / 4;
92 case DISTANCE_DROPDOWN_BUTTON_LABEL_ARROW_SPACING:
93 return 8;
94 case DISTANCE_DROPDOWN_BUTTON_RIGHT_MARGIN:
95 return 12;
96 case DISTANCE_RELATED_CONTROL_HORIZONTAL_SMALL:
97 return kHarmonyLayoutUnit;
98 case DISTANCE_RELATED_CONTROL_VERTICAL_SMALL:
99 return kHarmonyLayoutUnit / 2;
100 case DISTANCE_BUTTON_MINIMUM_WIDTH:
101 return GetDistanceMetric(views::DISTANCE_DIALOG_BUTTON_MINIMUM_WIDTH);
102 case DISTANCE_RELATED_LABEL_HORIZONTAL_LIST:
103 return kHarmonyLayoutUnit / 2;
104 case DISTANCE_SUBSECTION_HORIZONTAL_INDENT:
105 return 0;
106 case DISTANCE_TOAST_CONTROL_VERTICAL:
107 return 8;
108 case DISTANCE_TOAST_LABEL_VERTICAL:
109 return 12;
110 case DISTANCE_UNRELATED_CONTROL_HORIZONTAL:
111 return kHarmonyLayoutUnit;
112 case DISTANCE_UNRELATED_CONTROL_HORIZONTAL_LARGE:
113 return kHarmonyLayoutUnit;
114 case DISTANCE_UNRELATED_CONTROL_VERTICAL_LARGE:
115 return kHarmonyLayoutUnit;
116 case DISTANCE_BUBBLE_HEADER_VECTOR_ICON_SIZE:
117 return 20;
118 case DISTANCE_STANDALONE_BUBBLE_PREFERRED_WIDTH:
119 return kMediumDialogWidth;
120 case DISTANCE_LARGE_MODAL_DIALOG_PREFERRED_WIDTH:
121 return kLargeDialogWidth;
122 case DISTANCE_BETWEEN_PRIMARY_AND_SECONDARY_LABELS_HORIZONTAL:
123 return 24;
124 case DISTANCE_OMNIBOX_CELL_VERTICAL_PADDING:
125 return 8;
126 case DISTANCE_OMNIBOX_TWO_LINE_CELL_VERTICAL_PADDING:
127 return 4;
128 }
129 NOTREACHED();
130 return 0;
131 }
132
GetSnappedDialogWidth(int min_width) const133 int ChromeLayoutProvider::GetSnappedDialogWidth(int min_width) const {
134 for (int snap_point :
135 {kSmallDialogWidth, kMediumDialogWidth, kLargeDialogWidth}) {
136 if (min_width <= snap_point)
137 return snap_point;
138 }
139
140 return ((min_width + kHarmonyLayoutUnit - 1) / kHarmonyLayoutUnit) *
141 kHarmonyLayoutUnit;
142 }
143
GetTypographyProvider() const144 const views::TypographyProvider& ChromeLayoutProvider::GetTypographyProvider()
145 const {
146 return typography_provider_;
147 }
148
149 views::GridLayout::Alignment
GetControlLabelGridAlignment() const150 ChromeLayoutProvider::GetControlLabelGridAlignment() const {
151 return views::GridLayout::LEADING;
152 }
153
ShouldShowWindowIcon() const154 bool ChromeLayoutProvider::ShouldShowWindowIcon() const {
155 return false;
156 }
157
MakeShadowValues(int elevation,SkColor color) const158 gfx::ShadowValues ChromeLayoutProvider::MakeShadowValues(int elevation,
159 SkColor color) const {
160 return gfx::ShadowValue::MakeRefreshShadowValues(elevation, color);
161 }
162