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.
5 #include "pdf/fading_controls.h"
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"
13 namespace chrome_pdf
{
15 const uint32 kFadingAlphaShift
= 64;
16 const uint32 kSplashFadingAlphaShift
= 16;
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) {
25 FadingControls::~FadingControls() {
26 STLDeleteElements(&controls_
);
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
);
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.
42 std::list
<Control
*>::iterator iter
;
43 for (iter
= controls_
.begin(); iter
!= controls_
.end(); ++iter
) {
44 (*iter
)->Paint(image_data
, rc
);
48 bool FadingControls::HandleEvent(const pp::InputEvent
& event
) {
52 pp::MouseInputEvent
mouse_event(event
);
53 if (mouse_event
.is_null())
54 return NotifyControls(event
);
56 pp::Point pt
= mouse_event
.GetPosition();
59 mouse_event
.GetType() == PP_INPUTEVENT_TYPE_MOUSEDOWN
||
60 mouse_event
.GetType() == PP_INPUTEVENT_TYPE_MOUSEUP
;
62 if (rect().Contains(pt
)) {
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.
75 if ((!rect().Contains(pt
)) ||
76 event
.GetType() == PP_INPUTEVENT_TYPE_MOUSELEAVE
) {
79 pp::MouseInputEvent
event_leave(pp::MouseInputEvent(
80 owner()->GetInstance(),
81 PP_INPUTEVENT_TYPE_MOUSELEAVE
,
84 mouse_event
.GetButton(),
85 mouse_event
.GetPosition(),
86 mouse_event
.GetClickCount(),
87 mouse_event
.GetMovement()));
88 return NotifyControls(event_leave
);
91 return NotifyControls(event
);
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_
;
102 if (current_alpha
>= kOpaqueAlpha
) {
104 current_alpha
= kOpaqueAlpha
;
105 } else if (current_alpha
<= kTransparentAlpha
) {
107 current_alpha
= kTransparentAlpha
;
109 current_transparency_
= static_cast<uint8
>(current_alpha
);
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);
118 owner()->Invalidate(id(), GetControlsRect());
120 if (state_
!= NONE
) // Fading still in progress.
121 fading_timer_id_
= owner()->ScheduleTimer(id(), fading_timeout_
);
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
);
133 void FadingControls::EventCaptureReleased() {
134 if (current_capture_control_
!= kInvalidControlId
) {
135 // Remove previous catpure.
136 Control
* ctrl
= GetControl(current_capture_control_
);
138 ctrl
->EventCaptureReleased();
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);
148 Control::MoveBy(offset
, invalidate
);
151 void FadingControls::OnEvent(uint32 control_id
, uint32 event_id
, void* data
) {
152 owner()->OnEvent(control_id
, event_id
, data
);
155 void FadingControls::Invalidate(uint32 control_id
, const pp::Rect
& rc
) {
156 owner()->Invalidate(control_id
, rc
);
159 uint32
FadingControls::ScheduleTimer(uint32 control_id
, uint32 timeout_ms
) {
160 // TODO(gene): implement timer routine properly.
162 //owner()->ScheduleTimer(control_id);
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
;
171 EventCaptureReleased();
172 current_capture_control_
= control_id
;
176 void FadingControls::SetCursor(uint32 control_id
,
177 PP_CursorType_Dev cursor_type
) {
178 owner()->SetCursor(control_id
, cursor_type
);
181 pp::Instance
* FadingControls::GetInstance() {
182 return owner()->GetInstance();
185 bool FadingControls::AddControl(Control
* control
) {
187 if (control
->owner() != this)
189 if (!rect().Contains(control
->rect()))
192 control
->AdjustTransparency(current_transparency_
, false);
193 controls_
.push_back(control
);
197 void FadingControls::RemoveControl(uint32 control_id
) {
198 if (current_capture_control_
== control_id
) {
199 current_capture_control_
= kInvalidControlId
;
201 std::list
<Control
*>::iterator iter
;
202 for (iter
= controls_
.begin(); iter
!= controls_
.end(); ++iter
) {
203 if ((*iter
)->id() == control_id
) {
205 controls_
.erase(iter
);
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
)
220 pp::Rect
FadingControls::GetControlsRect() {
222 std::list
<Control
*>::iterator iter
;
223 for (iter
= controls_
.begin(); iter
!= controls_
.end(); ++iter
) {
224 rc
= rc
.Union((*iter
)->rect());
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()))
235 // No need to invalidate since we are expanding triggering area only.
240 void FadingControls::Splash(uint32 time_ms
) {
242 splash_timeout_
= time_ms
;
243 alpha_shift_
= kSplashFadingAlphaShift
;
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_
);
251 if (ctrl
->HandleEvent(event
))
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
))
265 void FadingControls::FadeIn() {
266 bool already_visible
=
267 (state_
== NONE
&& current_transparency_
== kOpaqueAlpha
);
268 if (state_
!= FADING_IN
&& !already_visible
) {
270 fading_timer_id_
= owner()->ScheduleTimer(id(), fading_timeout_
);
276 void FadingControls::FadeOut() {
277 bool already_invisible
=
278 (state_
== NONE
&& current_transparency_
== kTransparentAlpha
);
279 if (state_
!= FADING_OUT
&& !already_invisible
) {
281 fading_timer_id_
= owner()->ScheduleTimer(id(), fading_timeout_
);
283 if (already_invisible
)
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.
298 if (current_transparency_
== kOpaqueAlpha
) {
299 if (splash_timeout_
) {
300 fading_timer_id_
= owner()->ScheduleTimer(id(), splash_timeout_
);
311 void FadingControls::CancelSplashMode() {
313 alpha_shift_
= kFadingAlphaShift
;
316 } // namespace chrome_pdf