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

Side by Side Diff: ash/common/system/chromeos/palette/palette_tray.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
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/chromeos/palette/palette_tray.h"
6
7 #include "ash/common/material_design/material_design_controller.h"
8 #include "ash/common/session/session_state_delegate.h"
9 #include "ash/common/shelf/shelf_constants.h"
10 #include "ash/common/shelf/wm_shelf.h"
11 #include "ash/common/shelf/wm_shelf_util.h"
12 #include "ash/common/system/chromeos/palette/palette_tool_manager.h"
13 #include "ash/common/system/chromeos/palette/palette_utils.h"
14 #include "ash/common/system/tray/system_menu_button.h"
15 #include "ash/common/system/tray/system_tray_controller.h"
16 #include "ash/common/system/tray/system_tray_delegate.h"
17 #include "ash/common/system/tray/tray_bubble_wrapper.h"
18 #include "ash/common/system/tray/tray_constants.h"
19 #include "ash/common/system/tray/tray_popup_header_button.h"
20 #include "ash/common/system/tray/tray_popup_item_style.h"
21 #include "ash/common/wm_shell.h"
22 #include "ash/common/wm_window.h"
23 #include "ash/public/cpp/shell_window_ids.h"
24 #include "ash/resources/grit/ash_resources.h"
25 #include "ash/resources/vector_icons/vector_icons.h"
26 #include "ash/root_window_controller.h"
27 #include "ash/strings/grit/ash_strings.h"
28 #include "base/metrics/histogram_macros.h"
29 #include "ui/base/l10n/l10n_util.h"
30 #include "ui/base/resource/resource_bundle.h"
31 #include "ui/events/devices/input_device_manager.h"
32 #include "ui/events/devices/stylus_state.h"
33 #include "ui/gfx/color_palette.h"
34 #include "ui/gfx/paint_vector_icon.h"
35 #include "ui/gfx/vector_icons_public.h"
36 #include "ui/views/controls/image_view.h"
37 #include "ui/views/controls/label.h"
38 #include "ui/views/controls/separator.h"
39 #include "ui/views/layout/box_layout.h"
40 #include "ui/views/layout/fill_layout.h"
41
42 namespace ash {
43
44 namespace {
45
46 // Padding for tray icon (dp; the button that shows the palette menu).
47 constexpr int kTrayIconMainAxisInset = 8;
48 constexpr int kTrayIconCrossAxisInset = 0;
49
50 // Width of the palette itself (dp).
51 constexpr int kPaletteWidth = 332;
52
53 // Padding at the top/bottom of the palette (dp).
54 constexpr int kPalettePaddingOnTop = 4;
55 constexpr int kPalettePaddingOnBottom = 2;
56
57 // Margins between the title view and the edges around it (dp).
58 constexpr int kPaddingBetweenTitleAndLeftEdge = 12;
59 constexpr int kPaddingBetweenTitleAndSeparator = 3;
60
61 // Color of the separator.
62 const SkColor kPaletteSeparatorColor = SkColorSetARGB(0x1E, 0x00, 0x00, 0x00);
63
64 // Returns true if we are in a user session that can show the stylus tools.
65 bool IsInUserSession() {
66 SessionStateDelegate* session_state_delegate =
67 WmShell::Get()->GetSessionStateDelegate();
68 return !session_state_delegate->IsUserSessionBlocked() &&
69 session_state_delegate->GetSessionState() ==
70 session_manager::SessionState::ACTIVE &&
71 WmShell::Get()->system_tray_delegate()->GetUserLoginStatus() !=
72 LoginStatus::KIOSK_APP;
73 }
74
75 class TitleView : public views::View, public views::ButtonListener {
76 public:
77 explicit TitleView(PaletteTray* palette_tray) : palette_tray_(palette_tray) {
78 // TODO(tdanderson|jdufault): Use TriView to handle the layout of the title.
79 // See crbug.com/614453.
80 auto* box_layout =
81 new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 0);
82 SetLayoutManager(box_layout);
83
84 auto* title_label =
85 new views::Label(l10n_util::GetStringUTF16(IDS_ASH_STYLUS_TOOLS_TITLE));
86 title_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
87 AddChildView(title_label);
88 TrayPopupItemStyle style(TrayPopupItemStyle::FontStyle::TITLE);
89 style.SetupLabel(title_label);
90 box_layout->SetFlexForView(title_label, 1);
91 if (MaterialDesignController::IsSystemTrayMenuMaterial()) {
92 help_button_ =
93 new SystemMenuButton(this, TrayPopupInkDropStyle::HOST_CENTERED,
94 kSystemMenuHelpIcon, IDS_ASH_STATUS_TRAY_HELP);
95 settings_button_ = new SystemMenuButton(
96 this, TrayPopupInkDropStyle::HOST_CENTERED, kSystemMenuSettingsIcon,
97 IDS_ASH_PALETTE_SETTINGS);
98 } else {
99 gfx::ImageSkia help_icon =
100 gfx::CreateVectorIcon(kSystemMenuHelpIcon, kMenuIconColor);
101 gfx::ImageSkia settings_icon =
102 gfx::CreateVectorIcon(kSystemMenuSettingsIcon, kMenuIconColor);
103
104 auto* help_button = new ash::TrayPopupHeaderButton(
105 this, help_icon, IDS_ASH_STATUS_TRAY_HELP);
106 help_button->SetTooltipText(
107 l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_HELP));
108 help_button_ = help_button;
109
110 auto* settings_button = new ash::TrayPopupHeaderButton(
111 this, settings_icon, IDS_ASH_STATUS_TRAY_SETTINGS);
112 settings_button->SetTooltipText(
113 l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_SETTINGS));
114 settings_button_ = settings_button;
115 }
116
117 AddChildView(help_button_);
118 AddChildView(settings_button_);
119 }
120
121 ~TitleView() override {}
122
123 private:
124 // views::ButtonListener:
125 void ButtonPressed(views::Button* sender, const ui::Event& event) override {
126 if (sender == settings_button_) {
127 palette_tray_->RecordPaletteOptionsUsage(
128 PaletteTrayOptions::PALETTE_SETTINGS_BUTTON);
129 WmShell::Get()->system_tray_controller()->ShowPaletteSettings();
130 palette_tray_->HidePalette();
131 } else if (sender == help_button_) {
132 palette_tray_->RecordPaletteOptionsUsage(
133 PaletteTrayOptions::PALETTE_HELP_BUTTON);
134 WmShell::Get()->system_tray_controller()->ShowPaletteHelp();
135 palette_tray_->HidePalette();
136 } else {
137 NOTREACHED();
138 }
139 }
140
141 // Unowned pointers to button views so we can determine which button was
142 // clicked.
143 views::View* settings_button_;
144 views::View* help_button_;
145 PaletteTray* palette_tray_;
146
147 DISALLOW_COPY_AND_ASSIGN(TitleView);
148 };
149
150 } // namespace
151
152 PaletteTray::PaletteTray(WmShelf* wm_shelf)
153 : TrayBackgroundView(wm_shelf),
154 palette_tool_manager_(new PaletteToolManager(this)),
155 weak_factory_(this) {
156 PaletteTool::RegisterToolInstances(palette_tool_manager_.get());
157
158 if (MaterialDesignController::IsShelfMaterial()) {
159 SetInkDropMode(InkDropMode::ON);
160 SetContentsBackground(false);
161 } else {
162 SetContentsBackground(true);
163 }
164
165 SetLayoutManager(new views::FillLayout());
166 icon_ = new views::ImageView();
167 UpdateTrayIcon();
168
169 tray_container()->SetMargin(kTrayIconMainAxisInset, kTrayIconCrossAxisInset);
170 tray_container()->AddChildView(icon_);
171
172 WmShell::Get()->AddShellObserver(this);
173 WmShell::Get()->GetSessionStateDelegate()->AddSessionStateObserver(this);
174 ui::InputDeviceManager::GetInstance()->AddObserver(this);
175 }
176
177 PaletteTray::~PaletteTray() {
178 if (bubble_)
179 bubble_->bubble_view()->reset_delegate();
180
181 ui::InputDeviceManager::GetInstance()->RemoveObserver(this);
182 WmShell::Get()->RemoveShellObserver(this);
183 WmShell::Get()->GetSessionStateDelegate()->RemoveSessionStateObserver(this);
184 }
185
186 bool PaletteTray::PerformAction(const ui::Event& event) {
187 if (bubble_) {
188 if (num_actions_in_bubble_ == 0)
189 RecordPaletteOptionsUsage(PaletteTrayOptions::PALETTE_CLOSED_NO_ACTION);
190 HidePalette();
191 return true;
192 }
193
194 return ShowPalette();
195 }
196
197 bool PaletteTray::ShowPalette() {
198 if (bubble_)
199 return false;
200
201 DCHECK(tray_container());
202
203 views::TrayBubbleView::InitParams init_params(GetAnchorAlignment(),
204 kPaletteWidth, kPaletteWidth);
205 init_params.can_activate = true;
206 init_params.close_on_deactivate = true;
207
208 DCHECK(tray_container());
209
210 // The views::TrayBubbleView ctor will cause a shelf auto hide update check.
211 // Make sure to block auto hiding before that check happens.
212 should_block_shelf_auto_hide_ = true;
213
214 // TODO(tdanderson): Refactor into common row layout code.
215 // TODO(tdanderson|jdufault): Add material design ripple effects to the menu
216 // rows.
217
218 // Create and customize bubble view.
219 views::TrayBubbleView* bubble_view =
220 views::TrayBubbleView::Create(GetBubbleAnchor(), this, &init_params);
221 bubble_view->set_anchor_view_insets(GetBubbleAnchorInsets());
222 bubble_view->set_margins(
223 gfx::Insets(kPalettePaddingOnTop, 0, kPalettePaddingOnBottom, 0));
224
225 // Add title.
226 auto* title_view = new TitleView(this);
227 title_view->SetBorder(views::CreateEmptyBorder(
228 gfx::Insets(0, kPaddingBetweenTitleAndLeftEdge, 0, 0)));
229 bubble_view->AddChildView(title_view);
230
231 // Add horizontal separator.
232 views::Separator* separator = new views::Separator();
233 separator->SetColor(kPaletteSeparatorColor);
234 separator->SetBorder(views::CreateEmptyBorder(gfx::Insets(
235 kPaddingBetweenTitleAndSeparator, 0, kMenuSeparatorVerticalPadding, 0)));
236 bubble_view->AddChildView(separator);
237
238 // Add palette tools.
239 // TODO(tdanderson|jdufault): Use SystemMenuButton to get the material design
240 // ripples.
241 std::vector<PaletteToolView> views = palette_tool_manager_->CreateViews();
242 for (const PaletteToolView& view : views)
243 bubble_view->AddChildView(view.view);
244
245 // Show the bubble.
246 bubble_.reset(new ash::TrayBubbleWrapper(this, bubble_view));
247 SetIsActive(true);
248 return true;
249 }
250
251 bool PaletteTray::ContainsPointInScreen(const gfx::Point& point) {
252 if (icon_ && icon_->GetBoundsInScreen().Contains(point))
253 return true;
254
255 return bubble_ && bubble_->bubble_view()->GetBoundsInScreen().Contains(point);
256 }
257
258 void PaletteTray::SessionStateChanged(session_manager::SessionState state) {
259 UpdateIconVisibility();
260 }
261
262 void PaletteTray::OnLockStateChanged(bool locked) {
263 UpdateIconVisibility();
264
265 // The user can eject the stylus during the lock screen transition, which will
266 // open the palette. Make sure to close it if that happens.
267 if (locked)
268 HidePalette();
269 }
270
271 void PaletteTray::ClickedOutsideBubble() {
272 if (num_actions_in_bubble_ == 0)
273 RecordPaletteOptionsUsage(PaletteTrayOptions::PALETTE_CLOSED_NO_ACTION);
274 HidePalette();
275 }
276
277 base::string16 PaletteTray::GetAccessibleNameForTray() {
278 return l10n_util::GetStringUTF16(IDS_ASH_STYLUS_TOOLS_TITLE);
279 }
280
281 void PaletteTray::HideBubbleWithView(const views::TrayBubbleView* bubble_view) {
282 if (bubble_->bubble_view() == bubble_view)
283 HidePalette();
284 }
285
286 void PaletteTray::OnTouchscreenDeviceConfigurationChanged() {
287 UpdateIconVisibility();
288 }
289
290 void PaletteTray::OnStylusStateChanged(ui::StylusState stylus_state) {
291 PaletteDelegate* palette_delegate = WmShell::Get()->palette_delegate();
292
293 // Don't do anything if the palette should not be shown or if the user has
294 // disabled it all-together.
295 if (!IsInUserSession() || !palette_delegate->ShouldShowPalette())
296 return;
297
298 // Auto show/hide the palette if allowed by the user.
299 if (palette_delegate->ShouldAutoOpenPalette()) {
300 if (stylus_state == ui::StylusState::REMOVED && !bubble_) {
301 is_bubble_auto_opened_ = true;
302 ShowPalette();
303 } else if (stylus_state == ui::StylusState::INSERTED && bubble_) {
304 HidePalette();
305 }
306 }
307
308 // Disable any active modes if the stylus has been inserted.
309 if (stylus_state == ui::StylusState::INSERTED)
310 palette_tool_manager_->DisableActiveTool(PaletteGroup::MODE);
311 }
312
313 void PaletteTray::BubbleViewDestroyed() {
314 palette_tool_manager_->NotifyViewsDestroyed();
315 SetIsActive(false);
316 }
317
318 void PaletteTray::OnMouseEnteredView() {}
319
320 void PaletteTray::OnMouseExitedView() {}
321
322 base::string16 PaletteTray::GetAccessibleNameForBubble() {
323 return GetAccessibleNameForTray();
324 }
325
326 void PaletteTray::OnBeforeBubbleWidgetInit(
327 views::Widget* anchor_widget,
328 views::Widget* bubble_widget,
329 views::Widget::InitParams* params) const {
330 // Place the bubble in the same root window as |anchor_widget|.
331 WmWindow::Get(anchor_widget->GetNativeWindow())
332 ->GetRootWindowController()
333 ->ConfigureWidgetInitParamsForContainer(
334 bubble_widget, kShellWindowId_SettingBubbleContainer, params);
335 }
336
337 void PaletteTray::HideBubble(const views::TrayBubbleView* bubble_view) {
338 HideBubbleWithView(bubble_view);
339 }
340
341 void PaletteTray::HidePalette() {
342 should_block_shelf_auto_hide_ = false;
343 is_bubble_auto_opened_ = false;
344 num_actions_in_bubble_ = 0;
345 bubble_.reset();
346
347 shelf()->UpdateAutoHideState();
348 }
349
350 void PaletteTray::HidePaletteImmediately() {
351 if (bubble_)
352 bubble_->bubble_widget()->SetVisibilityChangedAnimationsEnabled(false);
353 HidePalette();
354 }
355
356 void PaletteTray::RecordPaletteOptionsUsage(PaletteTrayOptions option) {
357 DCHECK_NE(option, PaletteTrayOptions::PALETTE_OPTIONS_COUNT);
358
359 if (is_bubble_auto_opened_) {
360 UMA_HISTOGRAM_ENUMERATION("Ash.Shelf.Palette.Usage.AutoOpened", option,
361 PaletteTrayOptions::PALETTE_OPTIONS_COUNT);
362 } else {
363 UMA_HISTOGRAM_ENUMERATION("Ash.Shelf.Palette.Usage", option,
364 PaletteTrayOptions::PALETTE_OPTIONS_COUNT);
365 }
366 }
367
368 void PaletteTray::RecordPaletteModeCancellation(PaletteModeCancelType type) {
369 if (type == PaletteModeCancelType::PALETTE_MODE_CANCEL_TYPE_COUNT)
370 return;
371
372 UMA_HISTOGRAM_ENUMERATION(
373 "Ash.Shelf.Palette.ModeCancellation", type,
374 PaletteModeCancelType::PALETTE_MODE_CANCEL_TYPE_COUNT);
375 }
376
377 bool PaletteTray::ShouldBlockShelfAutoHide() const {
378 return should_block_shelf_auto_hide_;
379 }
380
381 void PaletteTray::OnActiveToolChanged() {
382 ++num_actions_in_bubble_;
383 UpdateTrayIcon();
384 }
385
386 WmWindow* PaletteTray::GetWindow() {
387 return shelf()->GetWindow();
388 }
389
390 void PaletteTray::SetShelfAlignment(ShelfAlignment alignment) {
391 if (alignment == shelf_alignment())
392 return;
393
394 TrayBackgroundView::SetShelfAlignment(alignment);
395 }
396
397 void PaletteTray::AnchorUpdated() {
398 if (bubble_)
399 bubble_->bubble_view()->UpdateBubble();
400 }
401
402 void PaletteTray::Initialize() {
403 PaletteDelegate* delegate = WmShell::Get()->palette_delegate();
404 // |delegate| can be null in tests.
405 if (!delegate)
406 return;
407
408 // OnPaletteEnabledPrefChanged will get called with the initial pref value,
409 // which will take care of showing the palette.
410 palette_enabled_subscription_ = delegate->AddPaletteEnableListener(base::Bind(
411 &PaletteTray::OnPaletteEnabledPrefChanged, weak_factory_.GetWeakPtr()));
412 }
413
414 void PaletteTray::UpdateTrayIcon() {
415 icon_->SetImage(CreateVectorIcon(
416 palette_tool_manager_->GetActiveTrayIcon(
417 palette_tool_manager_->GetActiveTool(ash::PaletteGroup::MODE)),
418 kTrayIconSize, kShelfIconColor));
419 }
420
421 void PaletteTray::OnPaletteEnabledPrefChanged(bool enabled) {
422 is_palette_enabled_ = enabled;
423
424 if (!enabled) {
425 SetVisible(false);
426 palette_tool_manager_->DisableActiveTool(PaletteGroup::MODE);
427 } else {
428 UpdateIconVisibility();
429 }
430 }
431
432 void PaletteTray::UpdateIconVisibility() {
433 SetVisible(is_palette_enabled_ && palette_utils::HasStylusInput() &&
434 IsInUserSession());
435 }
436
437 } // namespace ash
OLDNEW
« no previous file with comments | « ash/common/system/chromeos/palette/palette_tray.h ('k') | ash/common/system/chromeos/palette/palette_utils.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698