OLD | NEW |
---|---|
(Empty) | |
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.h" | |
12 #include "base/timer.h" | |
13 #include "grit/ash_strings.h" | |
14 #include "ui/aura/root_window.h" | |
15 #include "ui/base/l10n/l10n_util.h" | |
16 #include "ui/base/resource/resource_bundle.h" | |
17 #include "ui/gfx/canvas.h" | |
18 #include "ui/gfx/font.h" | |
19 #include "ui/views/controls/label.h" | |
20 #include "ui/views/view.h" | |
21 #include "ui/views/widget/widget.h" | |
22 #include "ui/views/widget/widget_delegate.h" | |
23 | |
24 namespace ash { | |
25 namespace { | |
26 | |
27 const int64 kDoublePressTimeOutMilliseconds = 300; | |
28 const int64 kHoldTimeOutMilliseconds = 1700; | |
29 const SkColor kForegroundColor = 0xFFFFFFFF; | |
30 const SkColor kBackgroundColor = 0xE0808080; | |
31 | |
32 class ExitWarningWidgetDelegateView : public views::WidgetDelegateView { | |
33 public: | |
34 ExitWarningWidgetDelegateView() : text_width_(0), width_(0), height_(0) { | |
35 text_ = l10n_util::GetStringUTF16(IDS_ASH_EXIT_WARNING_POPUP_TEXT); | |
36 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | |
37 font_ = rb.GetFont(ui::ResourceBundle::LargeFont); | |
38 text_width_ = font_.GetStringWidth(text_); | |
39 width_ = text_width_ + 100; | |
sky
2013/05/13 15:40:32
Where does the 100 come from? Are you sure you wan
sschmitz
2013/05/14 16:49:11
These are margins around the text when the whole t
| |
40 height_ = font_.GetHeight() + 100; | |
41 } | |
42 | |
43 virtual gfx::Size GetPreferredSize() OVERRIDE { | |
44 return gfx::Size(width_, height_); | |
45 } | |
46 | |
47 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE { | |
48 canvas->FillRect(GetLocalBounds(), kBackgroundColor); | |
49 canvas->DrawStringInt(text_, font_, kForegroundColor, | |
50 (width() - text_width_)/ 2, | |
51 (height() - font_.GetHeight()) / 2, | |
52 text_width_, font_.GetHeight()); | |
53 } | |
54 | |
55 private: | |
56 base::string16 text_; | |
sky
2013/05/13 15:40:32
Any reason you're not using a views::Label* to dra
sschmitz
2013/05/14 16:49:11
Using label.
Done.
| |
57 gfx::Font font_; | |
58 int text_width_; | |
59 int width_; | |
60 int height_; | |
61 }; | |
sky
2013/05/13 15:40:32
DISALLOW_...
sschmitz
2013/05/14 16:49:11
Done.
| |
62 | |
63 } // namespace | |
64 | |
65 ExitWarningHandler::ExitWarningHandler() : state_(IDLE), widget_(NULL) { | |
66 } | |
67 | |
68 ExitWarningHandler::~ExitWarningHandler() { | |
69 } | |
70 | |
71 void ExitWarningHandler::HandleExitKey(bool press) { | |
72 switch (state_) { | |
73 case IDLE: | |
74 if (press) { | |
75 state_ = WAIT_FOR_QUICK_RELEASE; | |
76 Show(); | |
77 StartTimers(); | |
78 } | |
79 break; | |
80 case WAIT_FOR_QUICK_RELEASE: | |
81 if (!press) | |
82 state_ = WAIT_FOR_DOUBLE_PRESS; | |
83 break; | |
84 case WAIT_FOR_DOUBLE_PRESS: | |
85 if (press) { | |
86 state_ = EXITING; | |
87 CancelTimers(); | |
88 Hide(); | |
89 Shell::GetInstance()->delegate()->Exit(); | |
90 } | |
91 break; | |
92 case WAIT_FOR_LONG_HOLD: | |
93 if (!press) | |
94 state_ = CANCELED; | |
95 break; | |
96 case CANCELED: | |
97 case EXITING: | |
98 break; | |
99 default: | |
100 NOTREACHED(); | |
101 break; | |
102 } | |
103 } | |
104 | |
105 void ExitWarningHandler::Timer1Action() { | |
106 if (state_ == WAIT_FOR_QUICK_RELEASE) | |
107 state_ = WAIT_FOR_LONG_HOLD; | |
108 else if (state_ == WAIT_FOR_DOUBLE_PRESS) | |
109 state_ = CANCELED; | |
110 } | |
111 | |
112 void ExitWarningHandler::Timer2Action() { | |
113 if (state_ == CANCELED) { | |
114 state_ = IDLE; | |
115 Hide(); | |
116 } | |
117 else if (state_ == WAIT_FOR_LONG_HOLD) { | |
118 state_ = EXITING; | |
119 Hide(); | |
120 Shell::GetInstance()->delegate()->Exit(); | |
121 } | |
122 } | |
123 | |
124 void ExitWarningHandler::StartTimers() { | |
125 timer1_.Start(FROM_HERE, | |
126 base::TimeDelta::FromMilliseconds( | |
127 kDoublePressTimeOutMilliseconds), | |
128 this, | |
129 &ExitWarningHandler::Timer1Action); | |
130 timer2_.Start(FROM_HERE, | |
131 base::TimeDelta::FromMilliseconds(kHoldTimeOutMilliseconds), | |
132 this, | |
133 &ExitWarningHandler::Timer2Action); | |
134 } | |
135 | |
136 void ExitWarningHandler::CancelTimers() { | |
137 timer1_.Stop(); | |
138 timer2_.Stop(); | |
139 } | |
140 | |
141 void ExitWarningHandler::Show() { | |
142 if (widget_) | |
143 return; | |
144 aura::RootWindow* root_window = Shell::GetActiveRootWindow(); | |
145 ExitWarningWidgetDelegateView* delegate = new ExitWarningWidgetDelegateView; | |
146 gfx::Size rs = root_window->bounds().size(); | |
147 gfx::Size ps = delegate->GetPreferredSize(); | |
148 gfx::Rect bounds((rs.width() - ps.width()) / 2, | |
149 (rs.height() - ps.height()) / 3, | |
150 ps.width(), ps.height()); | |
151 views::Widget::InitParams params; | |
152 params.type = views::Widget::InitParams::TYPE_POPUP; | |
153 params.transient = true; | |
154 params.transparent = true; | |
155 params.accept_events = false; | |
156 params.can_activate = false; | |
157 params.keep_on_top = true; | |
158 params.remove_standard_frame = true; | |
159 params.delegate = delegate; | |
160 params.bounds = bounds; | |
161 params.parent = Shell::GetContainer( | |
162 root_window, | |
163 internal::kShellWindowId_SettingBubbleContainer); | |
164 widget_ = new views::Widget; | |
165 widget_->Init(params); | |
166 widget_->SetContentsView(delegate); | |
167 widget_->GetNativeView()->SetName("ExitWarningWindow"); | |
168 widget_->Show(); | |
169 } | |
170 | |
171 void ExitWarningHandler::Hide() { | |
172 if (!widget_) | |
173 return; | |
174 widget_->Close(); | |
175 widget_ = NULL; | |
176 } | |
177 | |
178 } // namespace ash | |
OLD | NEW |