| 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 |