OLD | NEW |
---|---|
(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 | |
OLD | NEW |