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