- add sources.
[platform/framework/web/crosswalk.git] / src / ash / accelerators / exit_warning_handler.cc
1 // Copyright 2013 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/accelerators/exit_warning_handler.h"
6
7 #include "ash/shell.h"
8 #include "ash/shell_delegate.h"
9 #include "ash/shell_window_ids.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "base/time/time.h"
12 #include "base/timer/timer.h"
13 #include "grit/ash_strings.h"
14 #include "ui/aura/window.h"
15 #include "ui/base/accessibility/accessible_view_state.h"
16 #include "ui/base/l10n/l10n_util.h"
17 #include "ui/base/resource/resource_bundle.h"
18 #include "ui/gfx/canvas.h"
19 #include "ui/gfx/font.h"
20 #include "ui/views/controls/label.h"
21 #include "ui/views/layout/fill_layout.h"
22 #include "ui/views/view.h"
23 #include "ui/views/widget/widget.h"
24 #include "ui/views/widget/widget_delegate.h"
25
26 namespace ash {
27 namespace {
28
29 const int64 kTimeOutMilliseconds = 2000;
30 // Color of the text of the warning message.
31 const SkColor kTextColor = SK_ColorWHITE;
32 // Color of the window background.
33 const SkColor kWindowBackgroundColor = SkColorSetARGB(0xC0, 0x0, 0x0, 0x0);
34 // Radius of the rounded corners of the window.
35 const int kWindowCornerRadius = 2;
36 const int kHorizontalMarginAroundText = 100;
37 const int kVerticalMarginAroundText = 100;
38
39 class ExitWarningLabel : public views::Label {
40  public:
41   ExitWarningLabel() {}
42
43   virtual ~ExitWarningLabel() {}
44
45  private:
46   virtual void PaintText(gfx::Canvas* canvas,
47                          const string16& text,
48                          const gfx::Rect& text_bounds,
49                          int flags) OVERRIDE {
50     // Turn off subpixel rendering.
51     views::Label::PaintText(canvas,
52                             text,
53                             text_bounds,
54                             flags | gfx::Canvas::NO_SUBPIXEL_RENDERING);
55   }
56
57   DISALLOW_COPY_AND_ASSIGN(ExitWarningLabel);
58 };
59
60 class ExitWarningWidgetDelegateView : public views::WidgetDelegateView {
61  public:
62   ExitWarningWidgetDelegateView() : text_width_(0), width_(0), height_(0) {
63     text_ = l10n_util::GetStringUTF16(IDS_ASH_EXIT_WARNING_POPUP_TEXT);
64     accessible_name_ =
65         l10n_util::GetStringUTF16(IDS_ASH_EXIT_WARNING_POPUP_TEXT_ACCESSIBLE);
66     ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
67     font_ = rb.GetFont(ui::ResourceBundle::LargeFont);
68     text_width_ = font_.GetStringWidth(text_);
69     width_ = text_width_ + kHorizontalMarginAroundText;
70     height_ = font_.GetHeight() + kVerticalMarginAroundText;
71     views::Label* label = new ExitWarningLabel;
72     label->SetText(text_);
73     label->SetHorizontalAlignment(gfx::ALIGN_CENTER);
74     label->SetFont(font_);
75     label->SetEnabledColor(kTextColor);
76     label->SetDisabledColor(kTextColor);
77     label->SetAutoColorReadabilityEnabled(false);
78     AddChildView(label);
79     SetLayoutManager(new views::FillLayout);
80   }
81
82   virtual gfx::Size GetPreferredSize() OVERRIDE {
83     return gfx::Size(width_, height_);
84   }
85
86   virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
87     SkPaint paint;
88     paint.setStyle(SkPaint::kFill_Style);
89     paint.setColor(kWindowBackgroundColor);
90     canvas->DrawRoundRect(GetLocalBounds(), kWindowCornerRadius, paint);
91     views::WidgetDelegateView::OnPaint(canvas);
92   }
93
94   virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE {
95     state->name = accessible_name_;
96     state->role = ui::AccessibilityTypes::ROLE_ALERT;
97   }
98
99  private:
100   base::string16 text_;
101   base::string16 accessible_name_;
102   gfx::Font font_;
103   int text_width_;
104   int width_;
105   int height_;
106
107   DISALLOW_COPY_AND_ASSIGN(ExitWarningWidgetDelegateView);
108 };
109
110 }  // namespace
111
112 ExitWarningHandler::ExitWarningHandler()
113     : state_(IDLE),
114       stub_timer_for_test_(false) {
115 }
116
117 ExitWarningHandler::~ExitWarningHandler() {
118   // Note: If a timer is outstanding, it is stopped in its destructor.
119   Hide();
120 }
121
122 void ExitWarningHandler::HandleAccelerator() {
123   ShellDelegate* shell_delegate = Shell::GetInstance()->delegate();
124   switch (state_) {
125     case IDLE:
126       state_ = WAIT_FOR_DOUBLE_PRESS;
127       Show();
128       StartTimer();
129       shell_delegate->RecordUserMetricsAction(UMA_ACCEL_EXIT_FIRST_Q);
130       break;
131     case WAIT_FOR_DOUBLE_PRESS:
132       state_ = EXITING;
133       CancelTimer();
134       Hide();
135       shell_delegate->RecordUserMetricsAction(UMA_ACCEL_EXIT_SECOND_Q);
136       shell_delegate->Exit();
137       break;
138     case EXITING:
139       break;
140     default:
141       NOTREACHED();
142       break;
143   }
144 }
145
146 void ExitWarningHandler::TimerAction() {
147   Hide();
148   if (state_ == WAIT_FOR_DOUBLE_PRESS)
149     state_ = IDLE;
150 }
151
152 void ExitWarningHandler::StartTimer() {
153   if (stub_timer_for_test_)
154     return;
155   timer_.Start(FROM_HERE,
156                base::TimeDelta::FromMilliseconds(kTimeOutMilliseconds),
157                this,
158                &ExitWarningHandler::TimerAction);
159 }
160
161 void ExitWarningHandler::CancelTimer() {
162   timer_.Stop();
163 }
164
165 void ExitWarningHandler::Show() {
166   if (widget_)
167     return;
168   aura::Window* root_window = Shell::GetTargetRootWindow();
169   ExitWarningWidgetDelegateView* delegate = new ExitWarningWidgetDelegateView;
170   gfx::Size rs = root_window->bounds().size();
171   gfx::Size ps = delegate->GetPreferredSize();
172   gfx::Rect bounds((rs.width() - ps.width()) / 2,
173                    (rs.height() - ps.height()) / 3,
174                    ps.width(), ps.height());
175   views::Widget::InitParams params;
176   params.type = views::Widget::InitParams::TYPE_POPUP;
177   params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
178   params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
179   params.accept_events = false;
180   params.can_activate = false;
181   params.keep_on_top = true;
182   params.remove_standard_frame = true;
183   params.delegate = delegate;
184   params.bounds = bounds;
185   params.parent = Shell::GetContainer(
186       root_window,
187       internal::kShellWindowId_SettingBubbleContainer);
188   widget_.reset(new views::Widget);
189   widget_->Init(params);
190   widget_->SetContentsView(delegate);
191   widget_->GetNativeView()->SetName("ExitWarningWindow");
192   widget_->Show();
193
194   delegate->NotifyAccessibilityEvent(ui::AccessibilityTypes::EVENT_ALERT, true);
195 }
196
197 void ExitWarningHandler::Hide() {
198   widget_.reset();
199 }
200
201 }  // namespace ash