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

Side by Side Diff: ash/sticky_keys/sticky_keys_overlay.cc

Issue 137373003: Show overlay displaying the state of all sticky keys when it is enabled. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 11 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 | Annotate | Revision Log
OLDNEW
(Empty)
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/sticky_keys/sticky_keys_overlay.h"
6
7 #include "ash/shell.h"
8 #include "ash/shell_window_ids.h"
9 #include "ash/sticky_keys/sticky_keys_controller.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "ui/base/resource/resource_bundle.h"
12 #include "ui/gfx/animation/slide_animation.h"
13 #include "ui/gfx/canvas.h"
14 #include "ui/gfx/font_list.h"
15 #include "ui/gfx/text_utils.h"
16 #include "ui/views/border.h"
17 #include "ui/views/controls/label.h"
18 #include "ui/views/layout/box_layout.h"
19 #include "ui/views/view.h"
20 #include "ui/views/widget/widget.h"
21 #include "ui/views/widget/widget_delegate.h"
22
23 namespace ash {
24
25 namespace {
26
27 // Horizontal and vertical offset of the overlay on the screen.
James Cook 2014/01/14 00:59:03 Offset from... top-left corner? And maybe this sh
Tim Song 2014/01/14 03:01:10 Done.
28 const int kOverlayOffset = 18;
29
30 // Spacing between overlay contents and border.
31 const int kHorizontalBorderSpacing = 9;
32 const int kVerticalBorderSpacing = 4;
33
34 // Spacing between modifier key labels.
35 const int kKeyLabelSpacing = 7;
36
37 // Label names for each modifier key.
38 const char kControlKeyLabel[] = "ctrl";
39 const char kAltKeyLabel[] = "alt";
40 const char kShiftKeyLabel[] = "shift";
41 const char kSearchKeyLabel[] = "search";
42
43 // Duration of slide animation when overlay is shown or hidden.
44 const int kSlideAnimationDurationMs = 100;
45
46 }
47
48 ///////////////////////////////////////////////////////////////////////////////
49 // StickyKeyOverlayLabel
50 class StickyKeyOverlayLabel : public views::Label {
51 public:
52 StickyKeyOverlayLabel(const std::string& key_name);
James Cook 2014/01/14 00:59:03 explicit
Tim Song 2014/01/14 03:01:10 Done.
53
54 virtual ~StickyKeyOverlayLabel();
55
56 void SetKeyState(StickyKeyState state);
57
58 private:
59 virtual void PaintText(gfx::Canvas* canvas,
60 const base::string16& text,
61 const gfx::Rect& text_bounds,
62 int flags) OVERRIDE;
63
64 DISALLOW_COPY_AND_ASSIGN(StickyKeyOverlayLabel);
65 };
66
67 StickyKeyOverlayLabel::StickyKeyOverlayLabel(const std::string& key_name) {
68 SetText(base::UTF8ToUTF16(key_name));
James Cook 2014/01/14 00:59:03 Should you be using localized strings here? I don'
Tim Song 2014/01/14 03:01:10 Done. Good point, I'm not really sure, but if I ha
69 SetHorizontalAlignment(gfx::ALIGN_LEFT);
70 SetFontList(
71 font_list().DeriveFontListWithSize(18));
72 SetMultiLine(true);
James Cook 2014/01/14 00:59:03 Does it have to be multiline? The text is single l
Tim Song 2014/01/14 03:01:10 Done.
73 SetAutoColorReadabilityEnabled(false);
74 SetFocusable(false);
75 SetEnabledColor(SkColorSetARGB(0x80, 0xFF, 0xFF, 0xFF));
76 SetDisabledColor(SkColorSetARGB(0x80, 0xFF, 0xFF, 0xFF));
77 set_border(views::Border::CreateEmptyBorder(0, 0, 0, 0));
78 }
79
80 StickyKeyOverlayLabel::~StickyKeyOverlayLabel() {
81 }
82
83 void StickyKeyOverlayLabel::SetKeyState(StickyKeyState state) {
84 SkColor label_color = enabled_color();
85 int style;
James Cook 2014/01/14 00:59:03 either init style or don't init label_color, it's
Tim Song 2014/01/14 03:01:10 Done.
86 switch (state) {
87 case STICKY_KEY_STATE_ENABLED:
88 style = gfx::Font::NORMAL;
89 label_color = SkColorSetA(label_color, 0xFF);
90 break;
91 case STICKY_KEY_STATE_LOCKED:
92 style = gfx::Font::UNDERLINE;
93 label_color = SkColorSetA(label_color, 0xFF);
94 break;
95 default:
96 style = gfx::Font::NORMAL;
97 label_color = SkColorSetA(label_color, 0x80);
98 }
99
100 SetEnabledColor(label_color);
101 SetDisabledColor(label_color);
102 SetFontList(font_list().DeriveFontListWithSizeDeltaAndStyle(0, style));
103 }
104
105 void StickyKeyOverlayLabel::PaintText(gfx::Canvas* canvas,
106 const base::string16& text,
107 const gfx::Rect& text_bounds,
108 int flags) {
109 views::Label::PaintText(canvas,
110 text,
111 text_bounds,
112 flags | gfx::Canvas::NO_SUBPIXEL_RENDERING);
James Cook 2014/01/14 00:59:03 Why are you turning off subpixel rendering? Becaus
Tim Song 2014/01/14 03:01:10 Yeah, I was seeing some weird artifacts with the t
113 }
114
115
116 ///////////////////////////////////////////////////////////////////////////////
117 // StickyKeyOverlayLabel
118 class StickyKeysOverlayView : public views::WidgetDelegateView {
119 public:
120 StickyKeysOverlayView();
121
122 virtual ~StickyKeysOverlayView();
123
124 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
125
126 void SetKeyState(StickyKeyModifier modifier, StickyKeyState state);
127
128 private:
129 void AddKeyLabel(StickyKeyModifier modifier, const std::string& key_label);
130
131 typedef std::map<StickyKeyModifier, StickyKeyOverlayLabel*> ModifierLabelMap;
132 ModifierLabelMap modifier_label_map_;
133
134 DISALLOW_COPY_AND_ASSIGN(StickyKeysOverlayView);
135 };
136
137 StickyKeysOverlayView::StickyKeysOverlayView() {
138 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical,
139 kHorizontalBorderSpacing,
140 kVerticalBorderSpacing,
141 kKeyLabelSpacing));
142 AddKeyLabel(STICKY_KEY_CONTROL, kControlKeyLabel);
143 AddKeyLabel(STICKY_KEY_ALT, kAltKeyLabel);
144 AddKeyLabel(STICKY_KEY_SHIFT, kShiftKeyLabel);
145 AddKeyLabel(STICKY_KEY_SEARCH, kSearchKeyLabel);
146 }
147
148 StickyKeysOverlayView::~StickyKeysOverlayView() {}
149
150 void StickyKeysOverlayView::OnPaint(gfx::Canvas* canvas) {
151 SkPaint paint;
152 paint.setStyle(SkPaint::kFill_Style);
153 paint.setColor(SkColorSetARGB(0xB3, 0x55, 0x55, 0x55));
154 canvas->DrawRoundRect(GetLocalBounds(), 2, paint);
155 views::WidgetDelegateView::OnPaint(canvas);
156 }
157
158 void StickyKeysOverlayView::SetKeyState(StickyKeyModifier modifier,
159 StickyKeyState state) {
160 ModifierLabelMap::iterator it = modifier_label_map_.find(modifier);
161 if (it != modifier_label_map_.end()) {
James Cook 2014/01/14 00:59:03 optional: You could also DCHECK(it != map_.end()),
Tim Song 2014/01/14 03:01:10 Done.
162 StickyKeyOverlayLabel* label = it->second;
163 label->SetKeyState(state);
164 } else {
165 NOTREACHED();
166 }
167 }
168
169 void StickyKeysOverlayView::AddKeyLabel(StickyKeyModifier modifier,
170 const std::string& key_label) {
171 StickyKeyOverlayLabel* label = new StickyKeyOverlayLabel(key_label);
172 AddChildView(label);
173 modifier_label_map_[modifier] = label;
174 }
175
176 ///////////////////////////////////////////////////////////////////////////////
177 // StickyKeysOverlay
178 StickyKeysOverlay::StickyKeysOverlay()
179 : is_showing_(false),
180 overlay_view_(NULL) {
181 overlay_view_ = new StickyKeysOverlayView();
James Cook 2014/01/14 00:59:03 do this in overlay_view_() above
Tim Song 2014/01/14 03:01:10 Done.
182
183 views::Widget::InitParams params;
184 params.type = views::Widget::InitParams::TYPE_POPUP;
185 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
186 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
187 params.accept_events = false;
188 params.can_activate = false;
189 params.keep_on_top = true;
190 params.remove_standard_frame = true;
191 params.delegate = overlay_view_;
192 params.bounds = gfx::Rect(gfx::Point(kOverlayOffset, kOverlayOffset),
193 GetWidgetSize());
194 params.parent = Shell::GetContainer(
195 Shell::GetTargetRootWindow(),
196 internal::kShellWindowId_OverlayContainer);
197 overlay_widget_.reset(new views::Widget);
198 overlay_widget_->Init(params);
199 overlay_widget_->SetVisibilityChangedAnimationsEnabled(false);
200 overlay_widget_->SetContentsView(overlay_view_);
201 overlay_widget_->GetNativeView()->SetName("StickyKeysOverlay");
202
203 animation_.reset(new gfx::SlideAnimation(this));
James Cook 2014/01/14 00:59:03 I think you should use layer animations for this.
204 animation_->SetSlideDuration(kSlideAnimationDurationMs);
205 }
206
207 StickyKeysOverlay::~StickyKeysOverlay() {}
208
209 void StickyKeysOverlay::Show(bool visible) {
210 if (visible)
211 animation_->Show();
212 else
213 animation_->Hide();
214
215 is_showing_ = visible;
216 }
217
218 void StickyKeysOverlay::SetModifierKeyState(StickyKeyModifier modifier,
219 StickyKeyState state) {
220 overlay_view_->SetKeyState(modifier, state);
221 }
222
223 gfx::Size StickyKeysOverlay::GetWidgetSize() {
224 // Cache widget size so we don't recalculate the size multiple times during
225 // transition animations.
226 if (!widget_size_.get())
227 widget_size_.reset(new gfx::Size(overlay_view_->GetPreferredSize()));
228 return *widget_size_.get();
229 }
230
231 void StickyKeysOverlay::AnimationEnded(const gfx::Animation* animation) {
232 if (animation == animation_.get() && !animation_->IsShowing())
233 overlay_widget_->Hide();
234 }
235
236 void StickyKeysOverlay::AnimationProgressed(const gfx::Animation* animation) {
237 if (animation == animation_.get()) {
238 gfx::Size widget_size = GetWidgetSize();
239 int max_translation = widget_size.width() + kOverlayOffset;
240 int x = -widget_size.width() +
241 (animation_->GetCurrentValue() * max_translation);
242 overlay_widget_->SetBounds(gfx::Rect(gfx::Point(x, kOverlayOffset),
243 widget_size));
244 overlay_widget_->Show();
245 }
246 }
247
248 void StickyKeysOverlay::AnimationCanceled(const gfx::Animation* animation) {
249 gfx::Size widget_size = GetWidgetSize();
250 int x = is_showing_ ? kOverlayOffset : -widget_size.width();
251 overlay_widget_->SetBounds(gfx::Rect(gfx::Point(x, kOverlayOffset),
252 widget_size));
253 }
254
255 } // ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698