|
256 | 256 | vsync_batons_.push_back(baton); |
257 | 257 | } |
258 | 258 |
|
259 | | -void UIWidgetsPanel::SetEventPhaseFromCursorButtonState( |
260 | | - UIWidgetsPointerEvent* event_data) { |
261 | | - MouseState state = GetMouseState(); |
262 | | - event_data->phase = state.buttons == 0 |
263 | | - ? state.state_is_down ? UIWidgetsPointerPhase::kUp |
264 | | - : UIWidgetsPointerPhase::kHover |
265 | | - : state.state_is_down ? UIWidgetsPointerPhase::kMove |
266 | | - : UIWidgetsPointerPhase::kDown; |
267 | | -} |
268 | | - |
269 | | -void UIWidgetsPanel::SendMouseMove(float x, float y) { |
270 | | - UIWidgetsPointerEvent event = {}; |
271 | | - event.x = x; |
272 | | - event.y = y; |
273 | | - SetEventPhaseFromCursorButtonState(&event); |
274 | | - SendPointerEventWithData(event); |
275 | | -} |
276 | | - |
277 | | -void UIWidgetsPanel::SendMouseDown(float x, float y) { |
278 | | - UIWidgetsPointerEvent event = {}; |
279 | | - SetEventPhaseFromCursorButtonState(&event); |
280 | | - event.x = x; |
281 | | - event.y = y; |
282 | | - SendPointerEventWithData(event); |
283 | | - SetMouseStateDown(true); |
284 | | -} |
285 | | - |
286 | | -void UIWidgetsPanel::SendMouseUp(float x, float y) { |
287 | | - UIWidgetsPointerEvent event = {}; |
288 | | - SetEventPhaseFromCursorButtonState(&event); |
289 | | - event.x = x; |
290 | | - event.y = y; |
291 | | - SendPointerEventWithData(event); |
292 | | - if (event.phase == UIWidgetsPointerPhase::kUp) { |
293 | | - SetMouseStateDown(false); |
294 | | - } |
295 | | -} |
296 | | - |
297 | | -void UIWidgetsPanel::SendMouseLeave() { |
298 | | - UIWidgetsPointerEvent event = {}; |
299 | | - event.phase = UIWidgetsPointerPhase::kRemove; |
300 | | - SendPointerEventWithData(event); |
301 | | -} |
302 | | - |
303 | | -void UIWidgetsPanel::SendScroll(float delta_x, float delta_y, float px, float py) { |
304 | | - UIWidgetsPointerEvent event = {}; |
305 | | - // TODO: this is a native method, use unity position instead. |
306 | | - event.x = px; |
307 | | - event.y = py; |
308 | | - SetEventPhaseFromCursorButtonState(&event); |
309 | | - event.signal_kind = UIWidgetsPointerSignalKind::kUIWidgetsPointerSignalKindScroll; |
310 | | - // TODO: See if this can be queried from the OS; this value is chosen |
311 | | - // arbitrarily to get something that feels reasonable. |
312 | | - const int kScrollOffsetMultiplier = 20; |
313 | | - event.scroll_delta_x = delta_x * kScrollOffsetMultiplier; |
314 | | - event.scroll_delta_y = delta_y * kScrollOffsetMultiplier; |
315 | | - SendPointerEventWithData(event); |
316 | | -} |
317 | | - |
318 | | -void UIWidgetsPanel::SendPointerEventWithData( |
319 | | - const UIWidgetsPointerEvent& event_data) { |
320 | | - MouseState mouse_state = GetMouseState(); |
321 | | - // If sending anything other than an add, and the pointer isn't already added, |
322 | | - // synthesize an add to satisfy Flutter's expectations about events. |
323 | | - if (!mouse_state.state_is_added && |
324 | | - event_data.phase != UIWidgetsPointerPhase::kAdd) { |
325 | | - UIWidgetsPointerEvent event = {}; |
326 | | - event.phase = UIWidgetsPointerPhase::kAdd; |
327 | | - event.x = event_data.x; |
328 | | - event.y = event_data.y; |
329 | | - event.buttons = 0; |
330 | | - SendPointerEventWithData(event); |
331 | | - } |
332 | | - // Don't double-add (e.g., if events are delivered out of order, so an add has |
333 | | - // already been synthesized). |
334 | | - if (mouse_state.state_is_added && |
335 | | - event_data.phase == UIWidgetsPointerPhase::kAdd) { |
336 | | - return; |
337 | | - } |
| 259 | +void UIWidgetsPanel::dispatchTouches(float x, float y, int button, UIWidgetsTouchPhase phase) |
| 260 | +{ |
| 261 | + PointerData pointer_data; |
| 262 | + pointer_data.Clear(); |
338 | 263 |
|
339 | | - UIWidgetsPointerEvent event = event_data; |
340 | | - event.device_kind = kUIWidgetsPointerDeviceKindMouse; |
341 | | - event.buttons = mouse_state.buttons; |
| 264 | + auto packet = std::make_unique<PointerDataPacket>(1); |
342 | 265 |
|
343 | | - // Set metadata that's always the same regardless of the event. |
344 | | - event.struct_size = sizeof(event); |
345 | | - event.timestamp = |
346 | | - std::chrono::duration_cast<std::chrono::microseconds>( |
347 | | - std::chrono::high_resolution_clock::now().time_since_epoch()) |
348 | | - .count(); |
| 266 | + pointer_data.time_stamp = std::chrono::duration_cast<std::chrono::microseconds>( |
| 267 | + std::chrono::high_resolution_clock::now().time_since_epoch()) |
| 268 | + .count(); |
| 269 | + |
| 270 | + pointer_data.change = UIWidgetsPanel::PointerDataChangeFromUITouchPhase(phase); |
| 271 | + pointer_data.kind = UIWidgetsPanel::DeviceKindFromTouchType(); |
| 272 | + pointer_data.device = -button; |
| 273 | + pointer_data.pointer_identifier = 0; |
| 274 | + pointer_data.physical_x = x; |
| 275 | + pointer_data.physical_y = y; |
| 276 | + pointer_data.physical_delta_x = 0.0; |
| 277 | + pointer_data.physical_delta_y = 0.0; |
| 278 | + pointer_data.pressure = 1.0; |
| 279 | + pointer_data.pressure_max = 1.0; |
| 280 | + pointer_data.signal_kind = PointerData::SignalKind::kNone; |
| 281 | + packet->SetPointerData(0, pointer_data); |
| 282 | + |
| 283 | + reinterpret_cast<EmbedderEngine*>(engine_)->DispatchPointerDataPacket( |
| 284 | + std::move(packet)); |
| 285 | +} |
| 286 | + |
| 287 | +PointerData::Change UIWidgetsPanel::PointerDataChangeFromUITouchPhase(UIWidgetsTouchPhase phase) |
| 288 | +{ |
| 289 | + switch(phase) { |
| 290 | + case TouchBegan: |
| 291 | + return PointerData::Change::kDown; |
| 292 | + case TouchMoved: |
| 293 | + return PointerData::Change::kMove; |
| 294 | + case TouchEnded: |
| 295 | + return PointerData::Change::kUp; |
| 296 | + case TouchCancelled: |
| 297 | + return PointerData::Change::kCancel; |
| 298 | + default: |
| 299 | + std::cerr << "Unhandled touch phase: " << phase << std::endl; |
| 300 | + break; |
| 301 | + } |
349 | 302 |
|
350 | | - UIWidgetsEngineSendPointerEvent(engine_, &event, 1); |
| 303 | + return PointerData::Change::kCancel; |
| 304 | +} |
351 | 305 |
|
352 | | - if (event_data.phase == UIWidgetsPointerPhase::kAdd) { |
353 | | - SetMouseStateAdded(true); |
354 | | - } else if (event_data.phase == UIWidgetsPointerPhase::kRemove) { |
355 | | - SetMouseStateAdded(false); |
356 | | - ResetMouseState(); |
357 | | - } |
| 306 | +PointerData::DeviceKind UIWidgetsPanel::DeviceKindFromTouchType() |
| 307 | +{ |
| 308 | + return PointerData::DeviceKind::kTouch; |
358 | 309 | } |
359 | 310 |
|
360 | 311 | void UIWidgetsPanel::OnKeyDown(int keyCode, bool isKeyDown) { |
|
374 | 325 | } |
375 | 326 | } |
376 | 327 |
|
377 | | -void UIWidgetsPanel::OnMouseMove(float x, float y) { |
| 328 | +void UIWidgetsPanel::OnMouseMove(float x, float y, int button) { |
378 | 329 | if (process_events_) { |
379 | | - SendMouseMove(x, y); |
| 330 | + dispatchTouches(x, y, button, TouchMoved); |
380 | 331 | } |
381 | 332 | } |
382 | 333 |
|
383 | 334 | void UIWidgetsPanel::OnScroll(float x, float y, float px, float py) { |
384 | | - if (process_events_) { |
385 | | - SendScroll(x, y, px, py); |
386 | | - } |
387 | | -} |
388 | | - |
389 | | -static uint64_t ConvertToUIWidgetsButton(int button) { |
390 | | - switch (button) { |
391 | | - case -1: |
392 | | - return kUIWidgetsPointerButtonMousePrimary; |
393 | | - case -2: |
394 | | - return kUIWidgetsPointerButtonMouseSecondary; |
395 | | - case -3: |
396 | | - return kUIWidgetsPointerButtonMouseMiddle; |
397 | | - } |
398 | | - std::cerr << "Mouse button not recognized: " << button << std::endl; |
399 | | - return 0; |
| 335 | + //there should not be scroll events on iPhone! |
| 336 | + std::cerr << "Invalid input on iPhone: scroll" << std::endl; |
400 | 337 | } |
401 | 338 |
|
402 | 339 | void UIWidgetsPanel::OnMouseDown(float x, float y, int button) { |
403 | 340 | if (process_events_) { |
404 | | - uint64_t uiwidgets_button = ConvertToUIWidgetsButton(button); |
405 | | - if (uiwidgets_button != 0) { |
406 | | - uint64_t mouse_buttons = GetMouseState().buttons | uiwidgets_button; |
407 | | - SetMouseButtons(mouse_buttons); |
408 | | - SendMouseDown(x, y); |
409 | | - } |
| 341 | + dispatchTouches(x, y, button, TouchBegan); |
410 | 342 | } |
411 | 343 | } |
412 | 344 |
|
413 | 345 | void UIWidgetsPanel::OnMouseUp(float x, float y, int button) { |
414 | 346 | if (process_events_) { |
415 | | - uint64_t uiwidgets_button = ConvertToUIWidgetsButton(button); |
416 | | - if (uiwidgets_button != 0) { |
417 | | - uint64_t mouse_buttons = GetMouseState().buttons & ~uiwidgets_button; |
418 | | - SetMouseButtons(mouse_buttons); |
419 | | - SendMouseUp(x, y); |
420 | | - } |
| 347 | + dispatchTouches(x, y, button, TouchEnded); |
421 | 348 | } |
422 | 349 | } |
423 | 350 |
|
424 | 351 | void UIWidgetsPanel::OnMouseLeave() { |
425 | | - if (process_events_) { |
426 | | - SendMouseLeave(); |
427 | | - } |
| 352 | + //there should not be mouse leave events on iPhone! |
| 353 | + std::cerr << "Invalid input on iPhone: mouse leave" << std::endl; |
428 | 354 | } |
429 | 355 |
|
430 | 356 | UIWIDGETS_API(UIWidgetsPanel*) |
@@ -493,8 +419,8 @@ static uint64_t ConvertToUIWidgetsButton(int button) { |
493 | 419 | } |
494 | 420 |
|
495 | 421 | UIWIDGETS_API(void) |
496 | | -UIWidgetsPanel_onMouseMove(UIWidgetsPanel* panel, float x, float y) { |
497 | | - panel->OnMouseMove(x, y); |
| 422 | +UIWidgetsPanel_onMouseMove(UIWidgetsPanel* panel, float x, float y, int button) { |
| 423 | + panel->OnMouseMove(x, y, button); |
498 | 424 | } |
499 | 425 |
|
500 | 426 | UIWIDGETS_API(void) |
|
0 commit comments