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 |