1// Copyright 2014 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/system/chromeos/rotation/tray_rotation_lock.h"
6
7#include "ash/shell.h"
8#include "ash/system/tray/system_tray.h"
9#include "ash/system/tray/tray_item_more.h"
10#include "ash/wm/maximize_mode/maximize_mode_controller.h"
11#include "grit/ash_resources.h"
12#include "grit/ash_strings.h"
13#include "ui/base/l10n/l10n_util.h"
14#include "ui/base/resource/resource_bundle.h"
15#include "ui/gfx/display.h"
16
17namespace ash {
18
19namespace tray {
20
21// Extends TrayItemMore, however does not make use of the chevron, nor of the
22// DetailedView. This was chosen over ActionableView in order to reuse the
23// layout and styling of labels and images. This allows RotationLockDefaultView
24// to maintain the look of other system tray items without code duplication.
25class RotationLockDefaultView : public TrayItemMore,
26                                public ShellObserver {
27 public:
28  explicit RotationLockDefaultView(SystemTrayItem* owner);
29  virtual ~RotationLockDefaultView();
30
31  // ActionableView:
32  virtual bool PerformAction(const ui::Event& event) OVERRIDE;
33
34  // ShellObserver:
35  virtual void OnMaximizeModeStarted() OVERRIDE;
36  virtual void OnMaximizeModeEnded() OVERRIDE;
37
38 private:
39  void UpdateImage();
40
41  DISALLOW_COPY_AND_ASSIGN(RotationLockDefaultView);
42};
43
44RotationLockDefaultView::RotationLockDefaultView(SystemTrayItem* owner)
45    : TrayItemMore(owner, false) {
46  UpdateImage();
47  SetVisible(Shell::GetInstance()->maximize_mode_controller()->
48                 IsMaximizeModeWindowManagerEnabled());
49  Shell::GetInstance()->AddShellObserver(this);
50}
51
52RotationLockDefaultView::~RotationLockDefaultView() {
53  Shell::GetInstance()->RemoveShellObserver(this);
54}
55
56bool RotationLockDefaultView::PerformAction(const ui::Event& event) {
57  MaximizeModeController* maximize_mode_controller = Shell::GetInstance()->
58      maximize_mode_controller();
59  maximize_mode_controller->SetRotationLocked(
60      !maximize_mode_controller->rotation_locked());
61  UpdateImage();
62  return true;
63}
64
65void RotationLockDefaultView::OnMaximizeModeStarted() {
66  UpdateImage();
67  SetVisible(true);
68}
69
70void RotationLockDefaultView::OnMaximizeModeEnded() {
71  SetVisible(false);
72}
73
74void RotationLockDefaultView::UpdateImage() {
75  base::string16 label;
76  ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
77  if (Shell::GetInstance()->maximize_mode_controller()->rotation_locked()) {
78    SetImage(bundle.GetImageNamed(
79        IDR_AURA_UBER_TRAY_AUTO_ROTATION_LOCKED_DARK).ToImageSkia());
80    label = l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_ROTATION_LOCK_LOCKED);
81    SetLabel(label);
82    SetAccessibleName(label);
83  } else {
84    SetImage(bundle.GetImageNamed(IDR_AURA_UBER_TRAY_AUTO_ROTATION_DARK).
85        ToImageSkia());
86    label = l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_ROTATION_LOCK_AUTO);
87    SetLabel(label);
88    SetAccessibleName(label);
89  }
90}
91
92}  // namespace tray
93
94TrayRotationLock::TrayRotationLock(SystemTray* system_tray)
95    : TrayImageItem(system_tray, IDR_AURA_UBER_TRAY_AUTO_ROTATION_LOCKED),
96      on_primary_display_(false) {
97  gfx::NativeView native_view = system_tray->GetWidget()->GetNativeView();
98  gfx::Display parent_display = Shell::GetScreen()->
99      GetDisplayNearestWindow(native_view);
100
101  on_primary_display_ = parent_display.IsInternal();
102
103  if (on_primary_display_)
104    Shell::GetInstance()->AddShellObserver(this);
105}
106
107TrayRotationLock::~TrayRotationLock() {
108  if (on_primary_display_)
109    Shell::GetInstance()->RemoveShellObserver(this);
110}
111
112void TrayRotationLock::OnRotationLockChanged(bool rotation_locked) {
113  tray_view()->SetVisible(ShouldBeVisible());
114}
115
116views::View* TrayRotationLock::CreateDefaultView(user::LoginStatus status) {
117  if (on_primary_display_)
118    return new tray::RotationLockDefaultView(this);
119  return NULL;
120}
121
122void TrayRotationLock::OnMaximizeModeStarted() {
123  tray_view()->SetVisible(
124      Shell::GetInstance()->maximize_mode_controller()->rotation_locked());
125  Shell::GetInstance()->maximize_mode_controller()->AddObserver(this);
126}
127
128void TrayRotationLock::OnMaximizeModeEnded() {
129  tray_view()->SetVisible(false);
130  Shell::GetInstance()->maximize_mode_controller()->RemoveObserver(this);
131}
132
133bool TrayRotationLock::GetInitialVisibility() {
134  return ShouldBeVisible();
135}
136
137bool TrayRotationLock::ShouldBeVisible() {
138  MaximizeModeController* controller = Shell::GetInstance()->
139      maximize_mode_controller();
140  return on_primary_display_ &&
141         controller->IsMaximizeModeWindowManagerEnabled() &&
142         controller->rotation_locked();
143}
144
145}  // namespace ash
146