blob: 1d0e962e294bed131bd15a3745d5a6aaaf861468 [file] [log] [blame]
// Copyright 2013 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 "third_party/blink/public/common/input/synthetic_web_input_event_builders.h"
#include "base/check_op.h"
#include "ui/events/base_event_utils.h"
namespace blink {
WebMouseEvent SyntheticWebMouseEventBuilder::Build(
blink::WebInputEvent::Type type) {
return WebMouseEvent(type, WebInputEvent::kNoModifiers,
ui::EventTimeForNow());
}
WebMouseEvent SyntheticWebMouseEventBuilder::Build(
blink::WebInputEvent::Type type,
float window_x,
float window_y,
int modifiers,
blink::WebPointerProperties::PointerType pointer_type) {
DCHECK(WebInputEvent::IsMouseEventType(type));
WebMouseEvent result(type, modifiers, ui::EventTimeForNow());
result.SetPositionInWidget(window_x, window_y);
result.SetPositionInScreen(window_x, window_y);
result.SetModifiers(modifiers);
result.pointer_type = pointer_type;
result.id = WebMouseEvent::kMousePointerId;
return result;
}
WebMouseWheelEvent SyntheticWebMouseWheelEventBuilder::Build(
WebMouseWheelEvent::Phase phase) {
WebMouseWheelEvent result(WebInputEvent::Type::kMouseWheel,
WebInputEvent::kNoModifiers, ui::EventTimeForNow());
result.phase = phase;
result.event_action =
WebMouseWheelEvent::GetPlatformSpecificDefaultEventAction(result);
return result;
}
WebMouseWheelEvent SyntheticWebMouseWheelEventBuilder::Build(
float x,
float y,
float dx,
float dy,
int modifiers,
ui::ScrollGranularity delta_units) {
return Build(x, y, 0, 0, dx, dy, modifiers, delta_units);
}
WebMouseWheelEvent SyntheticWebMouseWheelEventBuilder::Build(
float x,
float y,
float global_x,
float global_y,
float dx,
float dy,
int modifiers,
ui::ScrollGranularity delta_units) {
WebMouseWheelEvent result(WebInputEvent::Type::kMouseWheel, modifiers,
ui::EventTimeForNow());
result.SetPositionInScreen(global_x, global_y);
result.SetPositionInWidget(x, y);
result.delta_units = delta_units;
result.delta_x = dx;
result.delta_y = dy;
if (dx)
result.wheel_ticks_x = dx > 0.0f ? 1.0f : -1.0f;
if (dy)
result.wheel_ticks_y = dy > 0.0f ? 1.0f : -1.0f;
result.event_action =
WebMouseWheelEvent::GetPlatformSpecificDefaultEventAction(result);
return result;
}
WebGestureEvent SyntheticWebGestureEventBuilder::Build(
WebInputEvent::Type type,
blink::WebGestureDevice source_device,
int modifiers) {
DCHECK(WebInputEvent::IsGestureEventType(type));
WebGestureEvent result(type, modifiers, ui::EventTimeForNow(), source_device);
if (type == WebInputEvent::Type::kGestureTap ||
type == WebInputEvent::Type::kGestureTapUnconfirmed ||
type == WebInputEvent::Type::kGestureDoubleTap) {
result.data.tap.tap_count = 1;
result.data.tap.width = 10;
result.data.tap.height = 10;
}
result.SetNeedsWheelEvent(result.IsTouchpadZoomEvent());
return result;
}
WebGestureEvent SyntheticWebGestureEventBuilder::BuildScrollBegin(
float dx_hint,
float dy_hint,
blink::WebGestureDevice source_device,
int pointer_count) {
WebGestureEvent result =
Build(WebInputEvent::Type::kGestureScrollBegin, source_device);
result.data.scroll_begin.delta_x_hint = dx_hint;
result.data.scroll_begin.delta_y_hint = dy_hint;
result.data.scroll_begin.pointer_count = pointer_count;
return result;
}
WebGestureEvent SyntheticWebGestureEventBuilder::BuildScrollUpdate(
float dx,
float dy,
int modifiers,
blink::WebGestureDevice source_device) {
WebGestureEvent result = Build(WebInputEvent::Type::kGestureScrollUpdate,
source_device, modifiers);
result.data.scroll_update.delta_x = dx;
result.data.scroll_update.delta_y = dy;
return result;
}
WebGestureEvent SyntheticWebGestureEventBuilder::BuildPinchUpdate(
float scale,
float anchor_x,
float anchor_y,
int modifiers,
blink::WebGestureDevice source_device) {
WebGestureEvent result =
Build(WebInputEvent::Type::kGesturePinchUpdate, source_device, modifiers);
result.data.pinch_update.scale = scale;
result.SetPositionInWidget(gfx::PointF(anchor_x, anchor_y));
result.SetPositionInScreen(gfx::PointF(anchor_x, anchor_y));
return result;
}
WebGestureEvent SyntheticWebGestureEventBuilder::BuildFling(
float velocity_x,
float velocity_y,
blink::WebGestureDevice source_device) {
WebGestureEvent result =
Build(WebInputEvent::Type::kGestureFlingStart, source_device);
result.data.fling_start.velocity_x = velocity_x;
result.data.fling_start.velocity_y = velocity_y;
return result;
}
SyntheticWebTouchEvent::SyntheticWebTouchEvent() : WebTouchEvent() {
unique_touch_event_id = ui::GetNextTouchEventId();
SetTimestamp(ui::EventTimeForNow());
pointer_id_ = 0;
}
void SyntheticWebTouchEvent::ResetPoints() {
int activePointCount = 0;
unsigned count = 0;
for (unsigned int i = 0; i < kTouchesLengthCap; ++i) {
switch (touches[i].state) {
case WebTouchPoint::State::kStatePressed:
case WebTouchPoint::State::kStateMoved:
case WebTouchPoint::State::kStateStationary:
touches[i].state = WebTouchPoint::State::kStateStationary;
++activePointCount;
++count;
break;
case WebTouchPoint::State::kStateReleased:
case WebTouchPoint::State::kStateCancelled:
touches[i] = WebTouchPoint();
++count;
break;
case WebTouchPoint::State::kStateUndefined:
break;
}
if (count >= touches_length)
break;
}
touches_length = activePointCount;
type_ = WebInputEvent::Type::kUndefined;
moved_beyond_slop_region = false;
unique_touch_event_id = ui::GetNextTouchEventId();
}
int SyntheticWebTouchEvent::PressPoint(float x,
float y,
float radius_x,
float radius_y,
float rotation_angle,
float force) {
int index = FirstFreeIndex();
if (index == -1)
return -1;
WebTouchPoint& point = touches[index];
point.id = pointer_id_++;
point.SetPositionInWidget(x, y);
point.SetPositionInScreen(x, y);
point.state = WebTouchPoint::State::kStatePressed;
point.radius_x = radius_x;
point.radius_y = radius_y;
point.rotation_angle = rotation_angle;
point.force = force;
point.tilt_x = point.tilt_y = 0;
point.pointer_type = blink::WebPointerProperties::PointerType::kTouch;
++touches_length;
SetType(WebInputEvent::Type::kTouchStart);
dispatch_type = WebInputEvent::DispatchType::kBlocking;
return index;
}
void SyntheticWebTouchEvent::MovePoint(int index,
float x,
float y,
float radius_x,
float radius_y,
float rotation_angle,
float force) {
CHECK_GE(index, 0);
CHECK_LT(index, kTouchesLengthCap);
// Always set this bit to avoid otherwise unexpected touchmove suppression.
// The caller can opt-out explicitly, if necessary.
moved_beyond_slop_region = true;
WebTouchPoint& point = touches[index];
point.SetPositionInWidget(x, y);
point.SetPositionInScreen(x, y);
point.state = WebTouchPoint::State::kStateMoved;
point.radius_x = radius_x;
point.radius_y = radius_y;
point.rotation_angle = rotation_angle;
point.force = force;
SetType(WebInputEvent::Type::kTouchMove);
dispatch_type = WebInputEvent::DispatchType::kBlocking;
}
void SyntheticWebTouchEvent::ReleasePoint(int index) {
CHECK_GE(index, 0);
CHECK_LT(index, kTouchesLengthCap);
touches[index].state = WebTouchPoint::State::kStateReleased;
touches[index].force = 0.f;
SetType(WebInputEvent::Type::kTouchEnd);
dispatch_type = WebInputEvent::DispatchType::kBlocking;
}
void SyntheticWebTouchEvent::CancelPoint(int index) {
CHECK_GE(index, 0);
CHECK_LT(index, kTouchesLengthCap);
touches[index].state = WebTouchPoint::State::kStateCancelled;
SetType(WebInputEvent::Type::kTouchCancel);
dispatch_type = WebInputEvent::DispatchType::kEventNonBlocking;
}
void SyntheticWebTouchEvent::SetTimestamp(base::TimeTicks timestamp) {
SetTimeStamp(timestamp);
}
int SyntheticWebTouchEvent::FirstFreeIndex() {
for (size_t i = 0; i < kTouchesLengthCap; ++i) {
if (touches[i].state == WebTouchPoint::State::kStateUndefined)
return i;
}
return -1;
}
} // namespace blink