diff options
Diffstat (limited to 'xfa_test/pdf/fading_controls.cc')
-rw-r--r-- | xfa_test/pdf/fading_controls.cc | 316 |
1 files changed, 316 insertions, 0 deletions
diff --git a/xfa_test/pdf/fading_controls.cc b/xfa_test/pdf/fading_controls.cc new file mode 100644 index 0000000000..8a9fd89510 --- /dev/null +++ b/xfa_test/pdf/fading_controls.cc @@ -0,0 +1,316 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "pdf/fading_controls.h" + +#include "base/logging.h" +#include "base/stl_util.h" +#include "pdf/draw_utils.h" +#include "pdf/resource_consts.h" +#include "ppapi/cpp/input_event.h" + +namespace chrome_pdf { + +const uint32 kFadingAlphaShift = 64; +const uint32 kSplashFadingAlphaShift = 16; + +FadingControls::FadingControls() + : state_(NONE), current_transparency_(kOpaqueAlpha), fading_timer_id_(0), + current_capture_control_(kInvalidControlId), + fading_timeout_(kFadingTimeoutMs), alpha_shift_(kFadingAlphaShift), + splash_(false), splash_timeout_(0) { +} + +FadingControls::~FadingControls() { + STLDeleteElements(&controls_); +} + +bool FadingControls::CreateFadingControls( + uint32 id, const pp::Rect& rc, bool visible, + Control::Owner* owner, uint8 transparency) { + current_transparency_ = transparency; + return Control::Create(id, rc, visible, owner); +} + +void FadingControls::Paint(pp::ImageData* image_data, const pp::Rect& rc) { + // When this control is set to invisible the individual controls are not. + // So we need to check for visible() here. + if (!visible()) + return; + + std::list<Control*>::iterator iter; + for (iter = controls_.begin(); iter != controls_.end(); ++iter) { + (*iter)->Paint(image_data, rc); + } +} + +bool FadingControls::HandleEvent(const pp::InputEvent& event) { + if (!visible()) + return false; + + pp::MouseInputEvent mouse_event(event); + if (mouse_event.is_null()) + return NotifyControls(event); + + pp::Point pt = mouse_event.GetPosition(); + + bool is_mouse_click = + mouse_event.GetType() == PP_INPUTEVENT_TYPE_MOUSEDOWN || + mouse_event.GetType() == PP_INPUTEVENT_TYPE_MOUSEUP; + + if (rect().Contains(pt)) { + CancelSplashMode(); + FadeIn(); + + // Eat mouse click if are invisible or just fading in. + // That prevents accidental clicks on the controls for touch devices. + bool eat_mouse_click = + (state_ == FADING_IN || current_transparency_ == kTransparentAlpha); + if (eat_mouse_click && is_mouse_click && + mouse_event.GetButton() == PP_INPUTEVENT_MOUSEBUTTON_LEFT) + return true; // Eat this event here. + } + + if ((!rect().Contains(pt)) || + event.GetType() == PP_INPUTEVENT_TYPE_MOUSELEAVE) { + if (!splash_) + FadeOut(); + pp::MouseInputEvent event_leave(pp::MouseInputEvent( + owner()->GetInstance(), + PP_INPUTEVENT_TYPE_MOUSELEAVE, + event.GetTimeStamp(), + event.GetModifiers(), + mouse_event.GetButton(), + mouse_event.GetPosition(), + mouse_event.GetClickCount(), + mouse_event.GetMovement())); + return NotifyControls(event_leave); + } + + return NotifyControls(event); +} + +void FadingControls::OnTimerFired(uint32 timer_id) { + if (timer_id == fading_timer_id_) { + int32 current_alpha = static_cast<int32>(current_transparency_); + if (state_ == FADING_IN) + current_alpha += alpha_shift_; + else if (state_ == FADING_OUT) + current_alpha -= alpha_shift_; + + if (current_alpha >= kOpaqueAlpha) { + state_ = NONE; + current_alpha = kOpaqueAlpha; + } else if (current_alpha <= kTransparentAlpha) { + state_ = NONE; + current_alpha = kTransparentAlpha; + } + current_transparency_ = static_cast<uint8>(current_alpha); + + // Invalidate controls with new alpha transparency. + std::list<Control*>::iterator iter; + for (iter = controls_.begin(); iter != controls_.end(); ++iter) { + // We are going to invalidate the whole FadingControls area, to + // allow simultaneous drawing. + (*iter)->AdjustTransparency(current_transparency_, false); + } + owner()->Invalidate(id(), GetControlsRect()); + + if (state_ != NONE) // Fading still in progress. + fading_timer_id_ = owner()->ScheduleTimer(id(), fading_timeout_); + else + OnFadingComplete(); + } else { + // Dispatch timer to controls. + std::list<Control*>::iterator iter; + for (iter = controls_.begin(); iter != controls_.end(); ++iter) { + (*iter)->OnTimerFired(timer_id); + } + } +} + +void FadingControls::EventCaptureReleased() { + if (current_capture_control_ != kInvalidControlId) { + // Remove previous catpure. + Control* ctrl = GetControl(current_capture_control_); + if (ctrl) + ctrl->EventCaptureReleased(); + } +} + +void FadingControls::MoveBy(const pp::Point& offset, bool invalidate) { + std::list<Control*>::iterator iter; + for (iter = controls_.begin(); iter != controls_.end(); ++iter) { + // We invalidate entire FadingControl later if needed. + (*iter)->MoveBy(offset, false); + } + Control::MoveBy(offset, invalidate); +} + +void FadingControls::OnEvent(uint32 control_id, uint32 event_id, void* data) { + owner()->OnEvent(control_id, event_id, data); +} + +void FadingControls::Invalidate(uint32 control_id, const pp::Rect& rc) { + owner()->Invalidate(control_id, rc); +} + +uint32 FadingControls::ScheduleTimer(uint32 control_id, uint32 timeout_ms) { + // TODO(gene): implement timer routine properly. + NOTIMPLEMENTED(); + //owner()->ScheduleTimer(control_id); + return 0; +} + +void FadingControls::SetEventCapture(uint32 control_id, bool set_capture) { + if (control_id == current_capture_control_) { + if (!set_capture) // Remove event capture. + current_capture_control_ = kInvalidControlId; + } else { + EventCaptureReleased(); + current_capture_control_ = control_id; + } +} + +void FadingControls::SetCursor(uint32 control_id, + PP_CursorType_Dev cursor_type) { + owner()->SetCursor(control_id, cursor_type); +} + +pp::Instance* FadingControls::GetInstance() { + return owner()->GetInstance(); +} + +bool FadingControls::AddControl(Control* control) { + DCHECK(control); + if (control->owner() != this) + return false; + if (!rect().Contains(control->rect())) + return false; + + control->AdjustTransparency(current_transparency_, false); + controls_.push_back(control); + return true; +} + +void FadingControls::RemoveControl(uint32 control_id) { + if (current_capture_control_ == control_id) { + current_capture_control_ = kInvalidControlId; + } + std::list<Control*>::iterator iter; + for (iter = controls_.begin(); iter != controls_.end(); ++iter) { + if ((*iter)->id() == control_id) { + delete (*iter); + controls_.erase(iter); + break; + } + } +} + +Control* FadingControls::GetControl(uint32 id) { + std::list<Control*>::iterator iter; + for (iter = controls_.begin(); iter != controls_.end(); ++iter) { + if ((*iter)->id() == id) + return *iter; + } + return NULL; +} + +pp::Rect FadingControls::GetControlsRect() { + pp::Rect rc; + std::list<Control*>::iterator iter; + for (iter = controls_.begin(); iter != controls_.end(); ++iter) { + rc = rc.Union((*iter)->rect()); + } + return rc; +} + +bool FadingControls::ExpandLeft(int offset) { + pp::Rect rc = rect(); + rc.set_width(rc.width() + offset); + rc.set_x(rc.x() - offset); + if (!rc.Contains(GetControlsRect())) + return false; + // No need to invalidate since we are expanding triggering area only. + SetRect(rc, false); + return true; +} + +void FadingControls::Splash(uint32 time_ms) { + splash_ = true; + splash_timeout_ = time_ms; + alpha_shift_ = kSplashFadingAlphaShift; + FadeIn(); +} + +bool FadingControls::NotifyControls(const pp::InputEvent& event) { + // First pass event to a control that current capture is set to. + Control* ctrl = GetControl(current_capture_control_); + if (ctrl) { + if (ctrl->HandleEvent(event)) + return true; + } + + std::list<Control*>::iterator iter; + for (iter = controls_.begin(); iter != controls_.end(); ++iter) { + // Now pass event to all control except control with capture, + // since we already passed to it above. + if ((*iter) != ctrl && (*iter)->HandleEvent(event)) + return true; + } + return false; +} + +void FadingControls::FadeIn() { + bool already_visible = + (state_ == NONE && current_transparency_ == kOpaqueAlpha); + if (state_ != FADING_IN && !already_visible) { + state_ = FADING_IN; + fading_timer_id_ = owner()->ScheduleTimer(id(), fading_timeout_); + } + if (already_visible) + OnFadingComplete(); +} + +void FadingControls::FadeOut() { + bool already_invisible = + (state_ == NONE && current_transparency_ == kTransparentAlpha); + if (state_ != FADING_OUT && !already_invisible) { + state_ = FADING_OUT; + fading_timer_id_ = owner()->ScheduleTimer(id(), fading_timeout_); + } + if (already_invisible) + OnFadingComplete(); +} + +void FadingControls::OnFadingComplete() { + DCHECK(current_transparency_ == kOpaqueAlpha || + current_transparency_ == kTransparentAlpha); + // In the splash mode following states are possible: + // Fade-in complete: splash_==true, splash_timeout_ != 0 + // We need to schedule timer for splash_timeout_. + // Splash timeout complete: splash_==true, splash_timeout_ == 0 + // We need to fade out still using splash settings. + // Fade-out complete: current_transparency_ == kTransparentAlpha + // We need to cancel splash mode and go back to normal settings. + if (splash_) { + if (current_transparency_ == kOpaqueAlpha) { + if (splash_timeout_) { + fading_timer_id_ = owner()->ScheduleTimer(id(), splash_timeout_); + splash_timeout_ = 0; + } else { + FadeOut(); + } + } else { + CancelSplashMode(); + } + } +} + +void FadingControls::CancelSplashMode() { + splash_ = false; + alpha_shift_ = kFadingAlphaShift; +} + +} // namespace chrome_pdf |