1 // Copyright (c) 2012 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/date/tray_date.h" 6 7 #include "ash/session_state_delegate.h" 8 #include "ash/shell.h" 9 #include "ash/shell_delegate.h" 10 #include "ash/system/date/date_view.h" 11 #include "ash/system/tray/system_tray.h" 12 #include "ash/system/tray/system_tray_delegate.h" 13 #include "ash/system/tray/system_tray_notifier.h" 14 #include "ash/system/tray/tray_constants.h" 15 #include "ash/system/tray/tray_item_view.h" 16 #include "ash/system/tray/tray_popup_header_button.h" 17 #include "base/i18n/time_formatting.h" 18 #include "base/strings/stringprintf.h" 19 #include "base/strings/utf_string_conversions.h" 20 #include "base/time/time.h" 21 #include "base/timer/timer.h" 22 #include "grit/ash_resources.h" 23 #include "grit/ash_strings.h" 24 #include "third_party/icu/source/i18n/unicode/datefmt.h" 25 #include "third_party/icu/source/i18n/unicode/fieldpos.h" 26 #include "third_party/icu/source/i18n/unicode/fmtable.h" 27 #include "third_party/skia/include/core/SkRect.h" 28 #include "ui/base/l10n/l10n_util.h" 29 #include "ui/base/resource/resource_bundle.h" 30 #include "ui/gfx/image/image.h" 31 #include "ui/gfx/image/image_skia.h" 32 #include "ui/gfx/size.h" 33 #include "ui/views/controls/button/button.h" 34 #include "ui/views/controls/image_view.h" 35 #include "ui/views/controls/label.h" 36 #include "ui/views/layout/box_layout.h" 37 #include "ui/views/layout/fill_layout.h" 38 #include "ui/views/painter.h" 39 #include "ui/views/view.h" 40 #include "ui/views/widget/widget.h" 41 42 namespace { 43 44 const int kPaddingVertical = 19; 45 46 class DateDefaultView : public views::View, 47 public views::ButtonListener { 48 public: 49 explicit DateDefaultView(ash::user::LoginStatus login) 50 : help_(NULL), 51 shutdown_(NULL), 52 lock_(NULL) { 53 SetLayoutManager(new views::FillLayout); 54 55 ash::internal::tray::DateView* date_view = 56 new ash::internal::tray::DateView(); 57 date_view->set_border(views::Border::CreateEmptyBorder(kPaddingVertical, 58 ash::kTrayPopupPaddingHorizontal, 59 0, 60 0)); 61 ash::internal::SpecialPopupRow* view = new ash::internal::SpecialPopupRow(); 62 view->SetContent(date_view); 63 AddChildView(view); 64 65 if (login == ash::user::LOGGED_IN_LOCKED || 66 login == ash::user::LOGGED_IN_NONE) 67 return; 68 69 date_view->SetActionable(true); 70 71 help_ = new ash::internal::TrayPopupHeaderButton(this, 72 IDR_AURA_UBER_TRAY_HELP, 73 IDR_AURA_UBER_TRAY_HELP, 74 IDR_AURA_UBER_TRAY_HELP_HOVER, 75 IDR_AURA_UBER_TRAY_HELP_HOVER, 76 IDS_ASH_STATUS_TRAY_HELP); 77 help_->SetTooltipText(l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_HELP)); 78 view->AddButton(help_); 79 80 if (login != ash::user::LOGGED_IN_LOCKED && 81 login != ash::user::LOGGED_IN_RETAIL_MODE) { 82 shutdown_ = new ash::internal::TrayPopupHeaderButton(this, 83 IDR_AURA_UBER_TRAY_SHUTDOWN, 84 IDR_AURA_UBER_TRAY_SHUTDOWN, 85 IDR_AURA_UBER_TRAY_SHUTDOWN_HOVER, 86 IDR_AURA_UBER_TRAY_SHUTDOWN_HOVER, 87 IDS_ASH_STATUS_TRAY_SHUTDOWN); 88 shutdown_->SetTooltipText( 89 l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_SHUTDOWN)); 90 view->AddButton(shutdown_); 91 } 92 93 if (ash::Shell::GetInstance()->session_state_delegate()->CanLockScreen()) { 94 lock_ = new ash::internal::TrayPopupHeaderButton(this, 95 IDR_AURA_UBER_TRAY_LOCKSCREEN, 96 IDR_AURA_UBER_TRAY_LOCKSCREEN, 97 IDR_AURA_UBER_TRAY_LOCKSCREEN_HOVER, 98 IDR_AURA_UBER_TRAY_LOCKSCREEN_HOVER, 99 IDS_ASH_STATUS_TRAY_LOCK); 100 lock_->SetTooltipText( 101 l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_LOCK)); 102 view->AddButton(lock_); 103 } 104 } 105 106 virtual ~DateDefaultView() {} 107 108 private: 109 // Overridden from views::ButtonListener. 110 virtual void ButtonPressed(views::Button* sender, 111 const ui::Event& event) OVERRIDE { 112 ash::Shell* shell = ash::Shell::GetInstance(); 113 ash::ShellDelegate* shell_delegate = shell->delegate(); 114 ash::SystemTrayDelegate* tray_delegate = shell->system_tray_delegate(); 115 if (sender == help_) { 116 shell_delegate->RecordUserMetricsAction(ash::UMA_TRAY_HELP); 117 tray_delegate->ShowHelp(); 118 } else if (sender == shutdown_) { 119 shell_delegate->RecordUserMetricsAction(ash::UMA_TRAY_SHUT_DOWN); 120 tray_delegate->ShutDown(); 121 } else if (sender == lock_) { 122 shell_delegate->RecordUserMetricsAction(ash::UMA_TRAY_LOCK_SCREEN); 123 tray_delegate->RequestLockScreen(); 124 } else { 125 NOTREACHED(); 126 } 127 } 128 129 ash::internal::TrayPopupHeaderButton* help_; 130 ash::internal::TrayPopupHeaderButton* shutdown_; 131 ash::internal::TrayPopupHeaderButton* lock_; 132 133 DISALLOW_COPY_AND_ASSIGN(DateDefaultView); 134 }; 135 136 } // namespace 137 138 namespace ash { 139 namespace internal { 140 141 TrayDate::TrayDate(SystemTray* system_tray) 142 : SystemTrayItem(system_tray), 143 time_tray_(NULL) { 144 Shell::GetInstance()->system_tray_notifier()->AddClockObserver(this); 145 } 146 147 TrayDate::~TrayDate() { 148 Shell::GetInstance()->system_tray_notifier()->RemoveClockObserver(this); 149 } 150 151 views::View* TrayDate::CreateTrayView(user::LoginStatus status) { 152 CHECK(time_tray_ == NULL); 153 ClockLayout clock_layout = 154 (system_tray()->shelf_alignment() == SHELF_ALIGNMENT_BOTTOM || 155 system_tray()->shelf_alignment() == SHELF_ALIGNMENT_TOP) ? 156 HORIZONTAL_CLOCK : VERTICAL_CLOCK; 157 time_tray_ = new tray::TimeView(clock_layout); 158 views::View* view = new TrayItemView(this); 159 view->AddChildView(time_tray_); 160 return view; 161 } 162 163 views::View* TrayDate::CreateDefaultView(user::LoginStatus status) { 164 return new DateDefaultView(status); 165 } 166 167 views::View* TrayDate::CreateDetailedView(user::LoginStatus status) { 168 return NULL; 169 } 170 171 void TrayDate::DestroyTrayView() { 172 time_tray_ = NULL; 173 } 174 175 void TrayDate::DestroyDefaultView() { 176 } 177 178 void TrayDate::DestroyDetailedView() { 179 } 180 181 void TrayDate::UpdateAfterLoginStatusChange(user::LoginStatus status) { 182 } 183 184 void TrayDate::UpdateAfterShelfAlignmentChange(ShelfAlignment alignment) { 185 if (time_tray_) { 186 ClockLayout clock_layout = (alignment == SHELF_ALIGNMENT_BOTTOM || 187 alignment == SHELF_ALIGNMENT_TOP) ? 188 HORIZONTAL_CLOCK : VERTICAL_CLOCK; 189 time_tray_->UpdateClockLayout(clock_layout); 190 } 191 } 192 193 void TrayDate::OnDateFormatChanged() { 194 if (time_tray_) 195 time_tray_->UpdateTimeFormat(); 196 } 197 198 void TrayDate::OnSystemClockTimeUpdated() { 199 if (time_tray_) 200 time_tray_->UpdateTimeFormat(); 201 } 202 203 void TrayDate::Refresh() { 204 if (time_tray_) 205 time_tray_->UpdateText(); 206 } 207 208 } // namespace internal 209 } // namespace ash 210