OLD | NEW |
| (Empty) |
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 "pdf/fading_controls.h" | |
6 | |
7 #include "base/logging.h" | |
8 #include "base/stl_util.h" | |
9 #include "pdf/draw_utils.h" | |
10 #include "pdf/resource_consts.h" | |
11 #include "ppapi/cpp/input_event.h" | |
12 | |
13 namespace chrome_pdf { | |
14 | |
15 const uint32 kFadingAlphaShift = 64; | |
16 const uint32 kSplashFadingAlphaShift = 16; | |
17 | |
18 FadingControls::FadingControls() | |
19 : state_(NONE), current_transparency_(kOpaqueAlpha), fading_timer_id_(0), | |
20 current_capture_control_(kInvalidControlId), | |
21 fading_timeout_(kFadingTimeoutMs), alpha_shift_(kFadingAlphaShift), | |
22 splash_(false), splash_timeout_(0) { | |
23 } | |
24 | |
25 FadingControls::~FadingControls() { | |
26 STLDeleteElements(&controls_); | |
27 } | |
28 | |
29 bool FadingControls::CreateFadingControls( | |
30 uint32 id, const pp::Rect& rc, bool visible, | |
31 Control::Owner* owner, uint8 transparency) { | |
32 current_transparency_ = transparency; | |
33 return Control::Create(id, rc, visible, owner); | |
34 } | |
35 | |
36 void FadingControls::Paint(pp::ImageData* image_data, const pp::Rect& rc) { | |
37 // When this control is set to invisible the individual controls are not. | |
38 // So we need to check for visible() here. | |
39 if (!visible()) | |
40 return; | |
41 | |
42 std::list<Control*>::iterator iter; | |
43 for (iter = controls_.begin(); iter != controls_.end(); ++iter) { | |
44 (*iter)->Paint(image_data, rc); | |
45 } | |
46 } | |
47 | |
48 bool FadingControls::HandleEvent(const pp::InputEvent& event) { | |
49 if (!visible()) | |
50 return false; | |
51 | |
52 pp::MouseInputEvent mouse_event(event); | |
53 if (mouse_event.is_null()) | |
54 return NotifyControls(event); | |
55 | |
56 pp::Point pt = mouse_event.GetPosition(); | |
57 | |
58 bool is_mouse_click = | |
59 mouse_event.GetType() == PP_INPUTEVENT_TYPE_MOUSEDOWN || | |
60 mouse_event.GetType() == PP_INPUTEVENT_TYPE_MOUSEUP; | |
61 | |
62 if (rect().Contains(pt)) { | |
63 CancelSplashMode(); | |
64 FadeIn(); | |
65 | |
66 // Eat mouse click if are invisible or just fading in. | |
67 // That prevents accidental clicks on the controls for touch devices. | |
68 bool eat_mouse_click = | |
69 (state_ == FADING_IN || current_transparency_ == kTransparentAlpha); | |
70 if (eat_mouse_click && is_mouse_click && | |
71 mouse_event.GetButton() == PP_INPUTEVENT_MOUSEBUTTON_LEFT) | |
72 return true; // Eat this event here. | |
73 } | |
74 | |
75 if ((!rect().Contains(pt)) || | |
76 event.GetType() == PP_INPUTEVENT_TYPE_MOUSELEAVE) { | |
77 if (!splash_) | |
78 FadeOut(); | |
79 pp::MouseInputEvent event_leave(pp::MouseInputEvent( | |
80 owner()->GetInstance(), | |
81 PP_INPUTEVENT_TYPE_MOUSELEAVE, | |
82 event.GetTimeStamp(), | |
83 event.GetModifiers(), | |
84 mouse_event.GetButton(), | |
85 mouse_event.GetPosition(), | |
86 mouse_event.GetClickCount(), | |
87 mouse_event.GetMovement())); | |
88 return NotifyControls(event_leave); | |
89 } | |
90 | |
91 return NotifyControls(event); | |
92 } | |
93 | |
94 void FadingControls::OnTimerFired(uint32 timer_id) { | |
95 if (timer_id == fading_timer_id_) { | |
96 int32 current_alpha = static_cast<int32>(current_transparency_); | |
97 if (state_ == FADING_IN) | |
98 current_alpha += alpha_shift_; | |
99 else if (state_ == FADING_OUT) | |
100 current_alpha -= alpha_shift_; | |
101 | |
102 if (current_alpha >= kOpaqueAlpha) { | |
103 state_ = NONE; | |
104 current_alpha = kOpaqueAlpha; | |
105 } else if (current_alpha <= kTransparentAlpha) { | |
106 state_ = NONE; | |
107 current_alpha = kTransparentAlpha; | |
108 } | |
109 current_transparency_ = static_cast<uint8>(current_alpha); | |
110 | |
111 // Invalidate controls with new alpha transparency. | |
112 std::list<Control*>::iterator iter; | |
113 for (iter = controls_.begin(); iter != controls_.end(); ++iter) { | |
114 // We are going to invalidate the whole FadingControls area, to | |
115 // allow simultaneous drawing. | |
116 (*iter)->AdjustTransparency(current_transparency_, false); | |
117 } | |
118 owner()->Invalidate(id(), GetControlsRect()); | |
119 | |
120 if (state_ != NONE) // Fading still in progress. | |
121 fading_timer_id_ = owner()->ScheduleTimer(id(), fading_timeout_); | |
122 else | |
123 OnFadingComplete(); | |
124 } else { | |
125 // Dispatch timer to controls. | |
126 std::list<Control*>::iterator iter; | |
127 for (iter = controls_.begin(); iter != controls_.end(); ++iter) { | |
128 (*iter)->OnTimerFired(timer_id); | |
129 } | |
130 } | |
131 } | |
132 | |
133 void FadingControls::EventCaptureReleased() { | |
134 if (current_capture_control_ != kInvalidControlId) { | |
135 // Remove previous catpure. | |
136 Control* ctrl = GetControl(current_capture_control_); | |
137 if (ctrl) | |
138 ctrl->EventCaptureReleased(); | |
139 } | |
140 } | |
141 | |
142 void FadingControls::MoveBy(const pp::Point& offset, bool invalidate) { | |
143 std::list<Control*>::iterator iter; | |
144 for (iter = controls_.begin(); iter != controls_.end(); ++iter) { | |
145 // We invalidate entire FadingControl later if needed. | |
146 (*iter)->MoveBy(offset, false); | |
147 } | |
148 Control::MoveBy(offset, invalidate); | |
149 } | |
150 | |
151 void FadingControls::OnEvent(uint32 control_id, uint32 event_id, void* data) { | |
152 owner()->OnEvent(control_id, event_id, data); | |
153 } | |
154 | |
155 void FadingControls::Invalidate(uint32 control_id, const pp::Rect& rc) { | |
156 owner()->Invalidate(control_id, rc); | |
157 } | |
158 | |
159 uint32 FadingControls::ScheduleTimer(uint32 control_id, uint32 timeout_ms) { | |
160 // TODO(gene): implement timer routine properly. | |
161 NOTIMPLEMENTED(); | |
162 //owner()->ScheduleTimer(control_id); | |
163 return 0; | |
164 } | |
165 | |
166 void FadingControls::SetEventCapture(uint32 control_id, bool set_capture) { | |
167 if (control_id == current_capture_control_) { | |
168 if (!set_capture) // Remove event capture. | |
169 current_capture_control_ = kInvalidControlId; | |
170 } else { | |
171 EventCaptureReleased(); | |
172 current_capture_control_ = control_id; | |
173 } | |
174 } | |
175 | |
176 void FadingControls::SetCursor(uint32 control_id, | |
177 PP_CursorType_Dev cursor_type) { | |
178 owner()->SetCursor(control_id, cursor_type); | |
179 } | |
180 | |
181 pp::Instance* FadingControls::GetInstance() { | |
182 return owner()->GetInstance(); | |
183 } | |
184 | |
185 bool FadingControls::AddControl(Control* control) { | |
186 DCHECK(control); | |
187 if (control->owner() != this) | |
188 return false; | |
189 if (!rect().Contains(control->rect())) | |
190 return false; | |
191 | |
192 control->AdjustTransparency(current_transparency_, false); | |
193 controls_.push_back(control); | |
194 return true; | |
195 } | |
196 | |
197 void FadingControls::RemoveControl(uint32 control_id) { | |
198 if (current_capture_control_ == control_id) { | |
199 current_capture_control_ = kInvalidControlId; | |
200 } | |
201 std::list<Control*>::iterator iter; | |
202 for (iter = controls_.begin(); iter != controls_.end(); ++iter) { | |
203 if ((*iter)->id() == control_id) { | |
204 delete (*iter); | |
205 controls_.erase(iter); | |
206 break; | |
207 } | |
208 } | |
209 } | |
210 | |
211 Control* FadingControls::GetControl(uint32 id) { | |
212 std::list<Control*>::iterator iter; | |
213 for (iter = controls_.begin(); iter != controls_.end(); ++iter) { | |
214 if ((*iter)->id() == id) | |
215 return *iter; | |
216 } | |
217 return NULL; | |
218 } | |
219 | |
220 pp::Rect FadingControls::GetControlsRect() { | |
221 pp::Rect rc; | |
222 std::list<Control*>::iterator iter; | |
223 for (iter = controls_.begin(); iter != controls_.end(); ++iter) { | |
224 rc = rc.Union((*iter)->rect()); | |
225 } | |
226 return rc; | |
227 } | |
228 | |
229 bool FadingControls::ExpandLeft(int offset) { | |
230 pp::Rect rc = rect(); | |
231 rc.set_width(rc.width() + offset); | |
232 rc.set_x(rc.x() - offset); | |
233 if (!rc.Contains(GetControlsRect())) | |
234 return false; | |
235 // No need to invalidate since we are expanding triggering area only. | |
236 SetRect(rc, false); | |
237 return true; | |
238 } | |
239 | |
240 void FadingControls::Splash(uint32 time_ms) { | |
241 splash_ = true; | |
242 splash_timeout_ = time_ms; | |
243 alpha_shift_ = kSplashFadingAlphaShift; | |
244 FadeIn(); | |
245 } | |
246 | |
247 bool FadingControls::NotifyControls(const pp::InputEvent& event) { | |
248 // First pass event to a control that current capture is set to. | |
249 Control* ctrl = GetControl(current_capture_control_); | |
250 if (ctrl) { | |
251 if (ctrl->HandleEvent(event)) | |
252 return true; | |
253 } | |
254 | |
255 std::list<Control*>::iterator iter; | |
256 for (iter = controls_.begin(); iter != controls_.end(); ++iter) { | |
257 // Now pass event to all control except control with capture, | |
258 // since we already passed to it above. | |
259 if ((*iter) != ctrl && (*iter)->HandleEvent(event)) | |
260 return true; | |
261 } | |
262 return false; | |
263 } | |
264 | |
265 void FadingControls::FadeIn() { | |
266 bool already_visible = | |
267 (state_ == NONE && current_transparency_ == kOpaqueAlpha); | |
268 if (state_ != FADING_IN && !already_visible) { | |
269 state_ = FADING_IN; | |
270 fading_timer_id_ = owner()->ScheduleTimer(id(), fading_timeout_); | |
271 } | |
272 if (already_visible) | |
273 OnFadingComplete(); | |
274 } | |
275 | |
276 void FadingControls::FadeOut() { | |
277 bool already_invisible = | |
278 (state_ == NONE && current_transparency_ == kTransparentAlpha); | |
279 if (state_ != FADING_OUT && !already_invisible) { | |
280 state_ = FADING_OUT; | |
281 fading_timer_id_ = owner()->ScheduleTimer(id(), fading_timeout_); | |
282 } | |
283 if (already_invisible) | |
284 OnFadingComplete(); | |
285 } | |
286 | |
287 void FadingControls::OnFadingComplete() { | |
288 DCHECK(current_transparency_ == kOpaqueAlpha || | |
289 current_transparency_ == kTransparentAlpha); | |
290 // In the splash mode following states are possible: | |
291 // Fade-in complete: splash_==true, splash_timeout_ != 0 | |
292 // We need to schedule timer for splash_timeout_. | |
293 // Splash timeout complete: splash_==true, splash_timeout_ == 0 | |
294 // We need to fade out still using splash settings. | |
295 // Fade-out complete: current_transparency_ == kTransparentAlpha | |
296 // We need to cancel splash mode and go back to normal settings. | |
297 if (splash_) { | |
298 if (current_transparency_ == kOpaqueAlpha) { | |
299 if (splash_timeout_) { | |
300 fading_timer_id_ = owner()->ScheduleTimer(id(), splash_timeout_); | |
301 splash_timeout_ = 0; | |
302 } else { | |
303 FadeOut(); | |
304 } | |
305 } else { | |
306 CancelSplashMode(); | |
307 } | |
308 } | |
309 } | |
310 | |
311 void FadingControls::CancelSplashMode() { | |
312 splash_ = false; | |
313 alpha_shift_ = kFadingAlphaShift; | |
314 } | |
315 | |
316 } // namespace chrome_pdf | |
OLD | NEW |