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

Side by Side Diff: ash/common/system/tray/tray_popup_utils.cc

Issue 2734653002: chromeos: Move files in //ash/common to //ash (Closed)
Patch Set: fix a11y tests, fix docs Created 3 years, 9 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 | « ash/common/system/tray/tray_popup_utils.h ('k') | ash/common/system/tray/tray_utils.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2016 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 "ash/common/system/tray/tray_popup_utils.h"
6
7 #include <algorithm>
8 #include <utility>
9
10 #include "ash/common/ash_constants.h"
11 #include "ash/common/ash_view_ids.h"
12 #include "ash/common/session/session_state_delegate.h"
13 #include "ash/common/system/tray/fixed_sized_image_view.h"
14 #include "ash/common/system/tray/size_range_layout.h"
15 #include "ash/common/system/tray/tray_constants.h"
16 #include "ash/common/system/tray/tray_popup_item_style.h"
17 #include "ash/common/wm_shell.h"
18 #include "ash/resources/vector_icons/vector_icons.h"
19 #include "base/memory/ptr_util.h"
20 #include "ui/base/l10n/l10n_util.h"
21 #include "ui/gfx/paint_vector_icon.h"
22 #include "ui/views/animation/flood_fill_ink_drop_ripple.h"
23 #include "ui/views/animation/ink_drop_highlight.h"
24 #include "ui/views/animation/ink_drop_impl.h"
25 #include "ui/views/animation/ink_drop_mask.h"
26 #include "ui/views/animation/square_ink_drop_ripple.h"
27 #include "ui/views/background.h"
28 #include "ui/views/border.h"
29 #include "ui/views/controls/button/button.h"
30 #include "ui/views/controls/button/label_button.h"
31 #include "ui/views/controls/button/md_text_button.h"
32 #include "ui/views/controls/button/toggle_button.h"
33 #include "ui/views/controls/image_view.h"
34 #include "ui/views/controls/label.h"
35 #include "ui/views/controls/separator.h"
36 #include "ui/views/controls/slider.h"
37 #include "ui/views/layout/box_layout.h"
38 #include "ui/views/layout/fill_layout.h"
39 #include "ui/views/painter.h"
40
41 namespace ash {
42
43 namespace {
44
45 // Creates a layout manager that positions Views vertically. The Views will be
46 // stretched horizontally and centered vertically.
47 std::unique_ptr<views::LayoutManager> CreateDefaultCenterLayoutManager() {
48 // TODO(bruthig): Use constants instead of magic numbers.
49 auto box_layout =
50 base::MakeUnique<views::BoxLayout>(views::BoxLayout::kVertical, 4, 8, 0);
51 box_layout->set_main_axis_alignment(
52 views::BoxLayout::MAIN_AXIS_ALIGNMENT_CENTER);
53 box_layout->set_cross_axis_alignment(
54 views::BoxLayout::CROSS_AXIS_ALIGNMENT_STRETCH);
55 return std::move(box_layout);
56 }
57
58 // Creates a layout manager that positions Views horizontally. The Views will be
59 // centered along the horizontal and vertical axis.
60 std::unique_ptr<views::LayoutManager> CreateDefaultEndsLayoutManager() {
61 auto box_layout = base::MakeUnique<views::BoxLayout>(
62 views::BoxLayout::kHorizontal, 0, 0, 0);
63 box_layout->set_main_axis_alignment(
64 views::BoxLayout::MAIN_AXIS_ALIGNMENT_CENTER);
65 box_layout->set_cross_axis_alignment(
66 views::BoxLayout::CROSS_AXIS_ALIGNMENT_CENTER);
67 return std::move(box_layout);
68 }
69
70 std::unique_ptr<views::LayoutManager> CreateDefaultLayoutManager(
71 TriView::Container container) {
72 switch (container) {
73 case TriView::Container::START:
74 case TriView::Container::END:
75 return CreateDefaultEndsLayoutManager();
76 case TriView::Container::CENTER:
77 return CreateDefaultCenterLayoutManager();
78 }
79 // Required by some compilers.
80 NOTREACHED();
81 return nullptr;
82 }
83
84 // Configures the default size and flex value for the specified |container|
85 // of the given |tri_view|. Used by CreateDefaultRowView().
86 void ConfigureDefaultSizeAndFlex(TriView* tri_view,
87 TriView::Container container) {
88 int min_width = 0;
89 switch (container) {
90 case TriView::Container::START:
91 min_width = kTrayPopupItemMinStartWidth;
92 break;
93 case TriView::Container::CENTER:
94 tri_view->SetFlexForContainer(TriView::Container::CENTER, 1.f);
95 break;
96 case TriView::Container::END:
97 min_width = kTrayPopupItemMinEndWidth;
98 break;
99 }
100
101 tri_view->SetMinSize(container,
102 gfx::Size(min_width, kTrayPopupItemMinHeight));
103 constexpr int kTrayPopupItemMaxHeight = 144;
104 tri_view->SetMaxSize(
105 container,
106 gfx::Size(SizeRangeLayout::kAbsoluteMaxSize, kTrayPopupItemMaxHeight));
107 }
108
109 class BorderlessLabelButton : public views::LabelButton {
110 public:
111 BorderlessLabelButton(views::ButtonListener* listener,
112 const base::string16& text)
113 : LabelButton(listener, text) {
114 const int kHorizontalPadding = 20;
115 SetBorder(views::CreateEmptyBorder(gfx::Insets(0, kHorizontalPadding)));
116 TrayPopupItemStyle style(TrayPopupItemStyle::FontStyle::BUTTON);
117 style.SetupLabel(label());
118 SetHorizontalAlignment(gfx::ALIGN_CENTER);
119 SetFocusPainter(TrayPopupUtils::CreateFocusPainter());
120
121 TrayPopupUtils::ConfigureTrayPopupButton(this);
122 }
123
124 ~BorderlessLabelButton() override {}
125
126 // views::LabelButton:
127 int GetHeightForWidth(int width) const override { return kMenuButtonSize; }
128
129 private:
130 // TODO(estade,bruthig): there's a lot in common here with ActionableView.
131 // Find a way to share. See related TODO on InkDropHostView::SetInkDropMode().
132 std::unique_ptr<views::InkDrop> CreateInkDrop() override {
133 return TrayPopupUtils::CreateInkDrop(TrayPopupInkDropStyle::INSET_BOUNDS,
134 this);
135 }
136
137 std::unique_ptr<views::InkDropRipple> CreateInkDropRipple() const override {
138 return TrayPopupUtils::CreateInkDropRipple(
139 TrayPopupInkDropStyle::INSET_BOUNDS, this,
140 GetInkDropCenterBasedOnLastEvent());
141 }
142
143 std::unique_ptr<views::InkDropHighlight> CreateInkDropHighlight()
144 const override {
145 return TrayPopupUtils::CreateInkDropHighlight(
146 TrayPopupInkDropStyle::INSET_BOUNDS, this);
147 }
148
149 std::unique_ptr<views::InkDropMask> CreateInkDropMask() const override {
150 return TrayPopupUtils::CreateInkDropMask(
151 TrayPopupInkDropStyle::INSET_BOUNDS, this);
152 }
153
154 DISALLOW_COPY_AND_ASSIGN(BorderlessLabelButton);
155 };
156
157 } // namespace
158
159 TriView* TrayPopupUtils::CreateDefaultRowView() {
160 TriView* tri_view = CreateMultiTargetRowView();
161
162 tri_view->SetContainerLayout(
163 TriView::Container::START,
164 CreateDefaultLayoutManager(TriView::Container::START));
165 tri_view->SetContainerLayout(
166 TriView::Container::CENTER,
167 CreateDefaultLayoutManager(TriView::Container::CENTER));
168 tri_view->SetContainerLayout(
169 TriView::Container::END,
170 CreateDefaultLayoutManager(TriView::Container::END));
171
172 return tri_view;
173 }
174
175 TriView* TrayPopupUtils::CreateSubHeaderRowView() {
176 TriView* tri_view = CreateMultiTargetRowView();
177 tri_view->SetInsets(gfx::Insets(0, kTrayPopupPaddingHorizontal, 0, 0));
178 tri_view->SetContainerVisible(TriView::Container::START, false);
179 tri_view->SetContainerLayout(
180 TriView::Container::END,
181 CreateDefaultLayoutManager(TriView::Container::END));
182 return tri_view;
183 }
184
185 TriView* TrayPopupUtils::CreateMultiTargetRowView() {
186 TriView* tri_view = new TriView(0 /* padding_between_items */);
187
188 tri_view->SetInsets(gfx::Insets(0, kMenuExtraMarginFromLeftEdge, 0, 0));
189
190 ConfigureDefaultSizeAndFlex(tri_view, TriView::Container::START);
191 ConfigureDefaultSizeAndFlex(tri_view, TriView::Container::CENTER);
192 ConfigureDefaultSizeAndFlex(tri_view, TriView::Container::END);
193
194 tri_view->SetContainerLayout(TriView::Container::START,
195 base::MakeUnique<views::FillLayout>());
196 tri_view->SetContainerLayout(TriView::Container::CENTER,
197 base::MakeUnique<views::FillLayout>());
198 tri_view->SetContainerLayout(TriView::Container::END,
199 base::MakeUnique<views::FillLayout>());
200
201 return tri_view;
202 }
203
204 views::Label* TrayPopupUtils::CreateDefaultLabel() {
205 views::Label* label = new views::Label();
206 label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
207 label->SetBorder(
208 views::CreateEmptyBorder(0, 0, 0, kTrayPopupLabelRightPadding));
209 // Frequently the label will paint to a layer that's non-opaque, so subpixel
210 // rendering won't work unless we explicitly set a background. See
211 // crbug.com/686363
212 label->set_background(
213 views::Background::CreateSolidBackground(kBackgroundColor));
214 label->SetBackgroundColor(kBackgroundColor);
215 return label;
216 }
217
218 views::ImageView* TrayPopupUtils::CreateMainImageView() {
219 return new FixedSizedImageView(kTrayPopupItemMinStartWidth,
220 kTrayPopupItemMinHeight);
221 }
222
223 views::ImageView* TrayPopupUtils::CreateMoreImageView() {
224 views::ImageView* image =
225 new FixedSizedImageView(kMenuIconSize, kMenuIconSize);
226 image->EnableCanvasFlippingForRTLUI(true);
227 image->SetImage(
228 gfx::CreateVectorIcon(kSystemMenuArrowRightIcon, kMenuIconColor));
229 return image;
230 }
231
232 views::Slider* TrayPopupUtils::CreateSlider(views::SliderListener* listener) {
233 views::Slider* slider = new views::Slider(listener);
234 slider->SetBorder(views::CreateEmptyBorder(gfx::Insets(0, 16)));
235 return slider;
236 }
237
238 views::ToggleButton* TrayPopupUtils::CreateToggleButton(
239 views::ButtonListener* listener,
240 int accessible_name_id) {
241 views::ToggleButton* toggle = new views::ToggleButton(listener);
242 const gfx::Size toggle_size(toggle->GetPreferredSize());
243 const int vertical_padding = (kMenuButtonSize - toggle_size.height()) / 2;
244 const int horizontal_padding =
245 (kTrayToggleButtonWidth - toggle_size.width()) / 2;
246 toggle->SetBorder(views::CreateEmptyBorder(
247 gfx::Insets(vertical_padding, horizontal_padding)));
248 toggle->SetFocusPainter(CreateFocusPainter());
249 toggle->SetAccessibleName(l10n_util::GetStringUTF16(accessible_name_id));
250 return toggle;
251 }
252
253 std::unique_ptr<views::Painter> TrayPopupUtils::CreateFocusPainter() {
254 return views::Painter::CreateSolidFocusPainter(
255 kFocusBorderColor, kFocusBorderThickness, gfx::InsetsF());
256 }
257
258 void TrayPopupUtils::ConfigureTrayPopupButton(views::CustomButton* button) {
259 // All buttons that call into here want this focus painter, but
260 // SetFocusPainter is defined separately on derived classes and isn't part of
261 // CustomButton. TODO(estade): Address this.
262 // button->SetFocusPainter(TrayPopupUtils::CreateFocusPainter());
263 button->SetFocusForPlatform();
264
265 button->SetInkDropMode(views::InkDropHostView::InkDropMode::ON);
266 button->set_has_ink_drop_action_on_click(true);
267 button->set_ink_drop_base_color(kTrayPopupInkDropBaseColor);
268 button->set_ink_drop_visible_opacity(kTrayPopupInkDropRippleOpacity);
269 }
270
271 void TrayPopupUtils::ConfigureAsStickyHeader(views::View* view) {
272 view->set_id(VIEW_ID_STICKY_HEADER);
273 view->set_background(
274 views::Background::CreateSolidBackground(kBackgroundColor));
275 view->SetBorder(
276 views::CreateEmptyBorder(gfx::Insets(kMenuSeparatorVerticalPadding, 0)));
277 view->SetPaintToLayer();
278 view->layer()->SetFillsBoundsOpaquely(false);
279 }
280
281 void TrayPopupUtils::ShowStickyHeaderSeparator(views::View* view,
282 bool show_separator) {
283 if (show_separator) {
284 view->SetBorder(views::CreatePaddedBorder(
285 views::CreateSolidSidedBorder(0, 0, kSeparatorWidth, 0,
286 kMenuSeparatorColor),
287 gfx::Insets(kMenuSeparatorVerticalPadding, 0,
288 kMenuSeparatorVerticalPadding - kSeparatorWidth, 0)));
289 } else {
290 view->SetBorder(views::CreateEmptyBorder(
291 gfx::Insets(kMenuSeparatorVerticalPadding, 0)));
292 }
293 view->SchedulePaint();
294 }
295
296 void TrayPopupUtils::ConfigureContainer(TriView::Container container,
297 views::View* container_view) {
298 container_view->SetLayoutManager(
299 CreateDefaultLayoutManager(container).release());
300 }
301
302 views::LabelButton* TrayPopupUtils::CreateTrayPopupBorderlessButton(
303 views::ButtonListener* listener,
304 const base::string16& text) {
305 return new BorderlessLabelButton(listener, text);
306 }
307
308 views::LabelButton* TrayPopupUtils::CreateTrayPopupButton(
309 views::ButtonListener* listener,
310 const base::string16& text) {
311 auto* button = views::MdTextButton::Create(listener, text);
312 button->SetProminent(true);
313 return button;
314 }
315
316 views::Separator* TrayPopupUtils::CreateVerticalSeparator() {
317 views::Separator* separator = new views::Separator();
318 separator->SetPreferredHeight(24);
319 separator->SetColor(kMenuSeparatorColor);
320 return separator;
321 }
322
323 std::unique_ptr<views::InkDrop> TrayPopupUtils::CreateInkDrop(
324 TrayPopupInkDropStyle ink_drop_style,
325 views::InkDropHostView* host) {
326 std::unique_ptr<views::InkDropImpl> ink_drop =
327 base::MakeUnique<views::InkDropImpl>(host, host->size());
328 ink_drop->SetAutoHighlightMode(
329 views::InkDropImpl::AutoHighlightMode::SHOW_ON_RIPPLE);
330 ink_drop->SetShowHighlightOnHover(false);
331
332 return std::move(ink_drop);
333 }
334
335 std::unique_ptr<views::InkDropRipple> TrayPopupUtils::CreateInkDropRipple(
336 TrayPopupInkDropStyle ink_drop_style,
337 const views::View* host,
338 const gfx::Point& center_point,
339 SkColor color) {
340 return base::MakeUnique<views::FloodFillInkDropRipple>(
341 host->size(), TrayPopupUtils::GetInkDropInsets(ink_drop_style),
342 center_point, color, kTrayPopupInkDropRippleOpacity);
343 }
344
345 std::unique_ptr<views::InkDropHighlight> TrayPopupUtils::CreateInkDropHighlight(
346 TrayPopupInkDropStyle ink_drop_style,
347 const views::View* host,
348 SkColor color) {
349 const gfx::Rect bounds =
350 TrayPopupUtils::GetInkDropBounds(ink_drop_style, host);
351 std::unique_ptr<views::InkDropHighlight> highlight(
352 new views::InkDropHighlight(bounds.size(), 0,
353 gfx::PointF(bounds.CenterPoint()), color));
354 highlight->set_visible_opacity(kTrayPopupInkDropHighlightOpacity);
355 return highlight;
356 }
357
358 std::unique_ptr<views::InkDropMask> TrayPopupUtils::CreateInkDropMask(
359 TrayPopupInkDropStyle ink_drop_style,
360 const views::View* host) {
361 if (ink_drop_style == TrayPopupInkDropStyle::FILL_BOUNDS)
362 return nullptr;
363
364 const gfx::Size layer_size = host->size();
365 switch (ink_drop_style) {
366 case TrayPopupInkDropStyle::HOST_CENTERED: {
367 const gfx::Rect mask_bounds =
368 GetInkDropBounds(TrayPopupInkDropStyle::HOST_CENTERED, host);
369 const int radius =
370 std::min(mask_bounds.width(), mask_bounds.height()) / 2;
371 return base::MakeUnique<views::CircleInkDropMask>(
372 layer_size, mask_bounds.CenterPoint(), radius);
373 }
374 case TrayPopupInkDropStyle::INSET_BOUNDS: {
375 const gfx::Insets mask_insets =
376 GetInkDropInsets(TrayPopupInkDropStyle::INSET_BOUNDS);
377 return base::MakeUnique<views::RoundRectInkDropMask>(
378 layer_size, mask_insets, kTrayPopupInkDropCornerRadius);
379 }
380 case TrayPopupInkDropStyle::FILL_BOUNDS:
381 // Handled by quick return above.
382 break;
383 }
384 // Required by some compilers.
385 NOTREACHED();
386 return nullptr;
387 }
388
389 gfx::Insets TrayPopupUtils::GetInkDropInsets(
390 TrayPopupInkDropStyle ink_drop_style) {
391 gfx::Insets insets;
392 if (ink_drop_style == TrayPopupInkDropStyle::HOST_CENTERED ||
393 ink_drop_style == TrayPopupInkDropStyle::INSET_BOUNDS) {
394 insets.Set(kTrayPopupInkDropInset, kTrayPopupInkDropInset,
395 kTrayPopupInkDropInset, kTrayPopupInkDropInset);
396 }
397 return insets;
398 }
399
400 gfx::Rect TrayPopupUtils::GetInkDropBounds(TrayPopupInkDropStyle ink_drop_style,
401 const views::View* host) {
402 gfx::Rect bounds = host->GetLocalBounds();
403 bounds.Inset(GetInkDropInsets(ink_drop_style));
404 return bounds;
405 }
406
407 views::Separator* TrayPopupUtils::CreateListItemSeparator(bool left_inset) {
408 views::Separator* separator = new views::Separator();
409 separator->SetColor(kMenuSeparatorColor);
410 separator->SetBorder(views::CreateEmptyBorder(
411 kMenuSeparatorVerticalPadding - views::Separator::kThickness,
412 left_inset
413 ? kMenuExtraMarginFromLeftEdge + kMenuButtonSize +
414 kTrayPopupLabelHorizontalPadding
415 : 0,
416 kMenuSeparatorVerticalPadding, 0));
417 return separator;
418 }
419
420 views::Separator* TrayPopupUtils::CreateListSubHeaderSeparator() {
421 views::Separator* separator = new views::Separator();
422 separator->SetColor(kMenuSeparatorColor);
423 separator->SetBorder(views::CreateEmptyBorder(
424 kMenuSeparatorVerticalPadding - views::Separator::kThickness, 0, 0, 0));
425 return separator;
426 }
427
428 bool TrayPopupUtils::CanOpenWebUISettings(LoginStatus status) {
429 // TODO(tdanderson): Consider moving this into WmShell, or introduce a
430 // CanShowSettings() method in each delegate type that has a
431 // ShowSettings() method.
432 return status != LoginStatus::NOT_LOGGED_IN &&
433 status != LoginStatus::LOCKED &&
434 !WmShell::Get()->GetSessionStateDelegate()->IsInSecondaryLoginScreen();
435 }
436
437 } // namespace ash
OLDNEW
« no previous file with comments | « ash/common/system/tray/tray_popup_utils.h ('k') | ash/common/system/tray/tray_utils.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698