浏览代码

hook mouse input

/siyaoH-1.17-PlatformMessage
Kevin Gu 4 年前
当前提交
ce44c04f
共有 10 个文件被更改,包括 621 次插入164 次删除
  1. 82
      com.unity.uiwidgets/Runtime/editor/editor_window.cs
  2. 144
      com.unity.uiwidgets/Runtime/engine2/UIWidgetsPanel.cs
  3. 88
      com.unity.uiwidgets/Runtime/gestures/converter.cs
  4. 72
      com.unity.uiwidgets/Runtime/ui/pointer.cs
  5. 104
      com.unity.uiwidgets/Runtime/ui2/hooks.cs
  6. 13
      com.unity.uiwidgets/Runtime/ui2/window.cs
  7. 66
      engine/src/lib/ui/window/pointer_data.h
  8. 17
      engine/src/lib/ui/window/window.cc
  9. 158
      engine/src/shell/platform/unity/uiwidgets_panel.cc
  10. 41
      engine/src/shell/platform/unity/uiwidgets_panel.h

82
com.unity.uiwidgets/Runtime/editor/editor_window.cs


}
if (onPointerEvent != null) {
PointerData pointerData = null;
PointerData pointerData = new PointerData();
if (evt.type == EventType.MouseDown) {
pointerData = new PointerData(

InputUtils.getScrollButtonKey()
);
}
else if (evt.type == EventType.DragUpdated) {
pointerData = new PointerData(
timeStamp: Timer.timespanSinceStartup,
change: PointerChange.dragFromEditorMove,
kind: PointerDeviceKind.mouse,
device: InputUtils.getMouseButtonKey(evt.button),
physicalX: evt.mousePosition.x * _devicePixelRatio,
physicalY: evt.mousePosition.y * _devicePixelRatio
);
}
else if (evt.type == EventType.DragPerform) {
pointerData = new PointerData(
timeStamp: Timer.timespanSinceStartup,
change: PointerChange.dragFromEditorRelease,
kind: PointerDeviceKind.mouse,
device: InputUtils.getMouseButtonKey(evt.button),
physicalX: evt.mousePosition.x * _devicePixelRatio,
physicalY: evt.mousePosition.y * _devicePixelRatio
);
}
if (pointerData != null) {
onPointerEvent(new PointerDataPacket(new List<PointerData> {
pointerData
}));
}
// else if (evt.type == EventType.DragUpdated) {
// pointerData = new PointerData(
// timeStamp: Timer.timespanSinceStartup,
// change: PointerChange.dragFromEditorMove,
// kind: PointerDeviceKind.mouse,
// device: InputUtils.getMouseButtonKey(evt.button),
// physicalX: evt.mousePosition.x * _devicePixelRatio,
// physicalY: evt.mousePosition.y * _devicePixelRatio
// );
// }
// else if (evt.type == EventType.DragPerform) {
// pointerData = new PointerData(
// timeStamp: Timer.timespanSinceStartup,
// change: PointerChange.dragFromEditorRelease,
// kind: PointerDeviceKind.mouse,
// device: InputUtils.getMouseButtonKey(evt.button),
// physicalX: evt.mousePosition.x * _devicePixelRatio,
// physicalY: evt.mousePosition.y * _devicePixelRatio
// );
// }
//
// if (pointerData != null) {
// onPointerEvent(new PointerDataPacket(new List<PointerData> {
// pointerData
// }));
// }
}
RawKeyboard.instance._handleKeyEvent(Event.current);

return;
}
PointerData pointerData = new ScrollData(
timeStamp: Timer.timespanSinceStartup,
change: PointerChange.scroll,
kind: PointerDeviceKind.mouse,
device: _scrollInput.getDeviceId(),
physicalX: _scrollInput.getPointerPosX(),
physicalY: _scrollInput.getPointerPosY(),
scrollX: deltaScroll.x,
scrollY: deltaScroll.y
);
onPointerEvent(new PointerDataPacket(new List<PointerData> {
pointerData
}));
// PointerData pointerData = new ScrollData(
// timeStamp: Timer.timespanSinceStartup,
// change: PointerChange.scroll,
// kind: PointerDeviceKind.mouse,
// device: _scrollInput.getDeviceId(),
// physicalX: _scrollInput.getPointerPosX(),
// physicalY: _scrollInput.getPointerPosY(),
// scrollX: deltaScroll.x,
// scrollY: deltaScroll.y
// );
//
// onPointerEvent(new PointerDataPacket(new List<PointerData> {
// pointerData
// }));
}
public void Update() {

144
com.unity.uiwidgets/Runtime/engine2/UIWidgetsPanel.cs


using System;
using System.Collections.Generic;
using UnityEngine.EventSystems;
public class UIWidgetsPanel : RawImage {
public partial class UIWidgetsPanel : RawImage {
public static UIWidgetsPanel current {
get { return Window.instance._panel; }
}

_ptr = UIWidgetsPanel_constructor((IntPtr) _handle, UIWidgetsPanel_entrypoint);
UIWidgetsPanel_onEnable(_ptr, _renderTexture.GetNativeTexturePtr(),
_width, _height, _devicePixelRatio, Application.streamingAssetsPath);
Input_OnEnable();
}
protected virtual void main() {

}
protected override void OnDisable() {
Input_OnDisable();
UIWidgetsPanel_onDisable(_ptr);
UIWidgetsPanel_dispose(_ptr);
_ptr = IntPtr.Zero;

_renderTexture = null;
}
protected virtual void Update() {
Input_Update();
}
protected virtual void OnGUI() {
Input_OnGUI();
}
public int registerTexture(Texture texture) {
return UIWidgetsPanel_registerTexture(_ptr, texture.GetNativeTexturePtr());
}

public void markNewFrameAvailable(int textureId) {
UIWidgetsPanel_markNewFrameAvailable(_ptr, textureId);
}
delegate void UIWidgetsPanel_EntrypointCallback(IntPtr handle);

[DllImport(NativeBindings.dllName)]
static extern void UIWidgetsPanel_markNewFrameAvailable(IntPtr ptr, int textureId);
}
public partial class UIWidgetsPanel : IPointerDownHandler, IPointerUpHandler,
IPointerEnterHandler, IPointerExitHandler, IDragHandler {
bool _isEntered;
Vector2 _lastMousePosition;
void Input_OnEnable() {
}
void Input_OnDisable() {
}
void Input_Update() {
if (Input.touchCount == 0 && Input.mousePresent) {
if (_isEntered) {
if (!Input.GetMouseButton(0) && !Input.GetMouseButton(1) && !Input.GetMouseButton(2)) {
if (_lastMousePosition.x != Input.mousePosition.x ||
_lastMousePosition.y != Input.mousePosition.y) {
_lastMousePosition = Input.mousePosition;
_onMouseMove();
}
}
else {
_lastMousePosition = Input.mousePosition;
}
}
}
}
void Input_OnGUI() {
Event e = Event.current;
if (e.isKey) {
UIWidgetsPanel_onKey(_ptr, e.keyCode, e.type == EventType.KeyDown);
if (e.character != 0) {
UIWidgetsPanel_onChar(_ptr, e.character);
}
}
}
Vector2? _getPointerPosition(Vector2 position) {
Camera worldCamera = canvas.worldCamera;
if (RectTransformUtility.ScreenPointToLocalPointInRectangle(
rectTransform, position, worldCamera, out var localPoint)) {
var scaleFactor = canvas.scaleFactor;
localPoint.x = (localPoint.x - rectTransform.rect.min.x) * scaleFactor;
localPoint.y = (rectTransform.rect.max.y - localPoint.y) * scaleFactor;
return localPoint;
}
return null;
}
void _onMouseMove() {
var pos = _getPointerPosition(Input.mousePosition);
if (pos == null) {
return;
}
UIWidgetsPanel_onMouseMove(_ptr, pos.Value.x, pos.Value.y);
}
public void OnPointerDown(PointerEventData eventData) {
var pos = _getPointerPosition(Input.mousePosition);
if (pos == null) {
return;
}
// mouse event
if (eventData.pointerId < 0) {
UIWidgetsPanel_onMouseDown(_ptr, pos.Value.x, pos.Value.y, eventData.pointerId);
}
}
public void OnPointerUp(PointerEventData eventData) {
var pos = _getPointerPosition(Input.mousePosition);
if (pos == null) {
return;
}
// mouse event
if (eventData.pointerId < 0) {
UIWidgetsPanel_onMouseUp(_ptr, pos.Value.x, pos.Value.y, eventData.pointerId);
}
}
public void OnPointerEnter(PointerEventData eventData) {
D.assert(eventData.pointerId < 0);
_isEntered = true;
_lastMousePosition = Input.mousePosition;
}
public void OnPointerExit(PointerEventData eventData) {
D.assert(eventData.pointerId < 0);
_isEntered = false;
UIWidgetsPanel_onMouseLeave(_ptr);
}
public void OnDrag(PointerEventData eventData) {
var pos = _getPointerPosition(Input.mousePosition);
if (pos == null) {
return;
}
// mouse event
if (eventData.pointerId < 0) {
UIWidgetsPanel_onMouseMove(_ptr, pos.Value.x, pos.Value.y);
}
}
[DllImport(NativeBindings.dllName)]
static extern void UIWidgetsPanel_onChar(IntPtr ptr, char c);
[DllImport(NativeBindings.dllName)]
static extern void UIWidgetsPanel_onKey(IntPtr ptr, KeyCode keyCode, bool isKeyDown);
[DllImport(NativeBindings.dllName)]
static extern void UIWidgetsPanel_onMouseDown(IntPtr ptr, float x, float y, int button);
[DllImport(NativeBindings.dllName)]
static extern void UIWidgetsPanel_onMouseUp(IntPtr ptr, float x, float y, int button);
[DllImport(NativeBindings.dllName)]
static extern void UIWidgetsPanel_onMouseMove(IntPtr ptr, float x, float y);
[DllImport(NativeBindings.dllName)]
static extern void UIWidgetsPanel_onMouseLeave(IntPtr ptr);
}
}

88
com.unity.uiwidgets/Runtime/gestures/converter.cs


break;
}
case PointerChange.scroll: {
var _scrollData = (ScrollData) datum;
_PointerState state = _ensureStateForPointer(datum, position);
state.initScrollPointer();
if (state.lastPosition != position) {
state.lastPosition = position;
}
Offset scrollDelta = new Offset(_scrollData.scrollX, _scrollData.scrollY) / devicePixelRatio;
yield return new PointerScrollEvent(
timeStamp: timeStamp,
pointer: state.pointer,
kind: kind,
device: _scrollData.device,
position: position,
scrollDelta: scrollDelta
);
break;
}
// case PointerChange.scroll: {
// var _scrollData = (ScrollData) datum;
// _PointerState state = _ensureStateForPointer(datum, position);
// state.initScrollPointer();
//
// if (state.lastPosition != position) {
// state.lastPosition = position;
// }
//
// Offset scrollDelta = new Offset(_scrollData.scrollX, _scrollData.scrollY) / devicePixelRatio;
// yield return new PointerScrollEvent(
// timeStamp: timeStamp,
// pointer: state.pointer,
// kind: kind,
// device: _scrollData.device,
// position: position,
// scrollDelta: scrollDelta
// );
// break;
// }
case PointerChange.up:
case PointerChange.cancel: {

}
break;
#if UNITY_EDITOR
case PointerChange.dragFromEditorMove: {
_PointerState state = _ensureStateForPointer(datum, position);
state.startNewPointer();
yield return new PointerDragFromEditorHoverEvent(
timeStamp: timeStamp,
pointer: state.pointer,
kind: kind,
device: datum.device,
position: position
);
}
break;
case PointerChange.dragFromEditorRelease: {
_PointerState state = _ensureStateForPointer(datum, position);
state.startNewPointer();
yield return new PointerDragFromEditorReleaseEvent(
timeStamp: timeStamp,
pointer: state.pointer,
kind: kind,
device: datum.device,
position: position
);
}
break;
// case PointerChange.dragFromEditorMove: {
// _PointerState state = _ensureStateForPointer(datum, position);
// state.startNewPointer();
// yield return new PointerDragFromEditorHoverEvent(
// timeStamp: timeStamp,
// pointer: state.pointer,
// kind: kind,
// device: datum.device,
// position: position
// );
// }
// break;
// case PointerChange.dragFromEditorRelease: {
// _PointerState state = _ensureStateForPointer(datum, position);
// state.startNewPointer();
// yield return new PointerDragFromEditorReleaseEvent(
// timeStamp: timeStamp,
// pointer: state.pointer,
// kind: kind,
// device: datum.device,
// position: position
// );
// }
// break;
#endif
}
}

72
com.unity.uiwidgets/Runtime/ui/pointer.cs


down,
move,
up,
scroll,
dragFromEditorMove,
dragFromEditorRelease
stylus,
invertedStylus,
unknown
}
public enum PointerSignalKind {

}
public class PointerData {
public readonly struct PointerData {
TimeSpan timeStamp,
PointerChange change,
PointerDeviceKind kind,
TimeSpan? timeStamp = null,
PointerChange change = PointerChange.cancel,
PointerDeviceKind kind = PointerDeviceKind.touch,
int pointerIdentifier = 0,
float physicalDeltaX = 0.0f,
float physicalDeltaY = 0.0f,
bool synthesized = false,
float pressure = 0.0f,
float pressureMin = 0.0f,
float pressureMax = 0.0f,

int platformData = 0,
float scrollDeltaX = 0.0f,
float scrollDeltaY = 0.0f) {
this.timeStamp = timeStamp;
this.timeStamp = timeStamp ?? TimeSpan.Zero;
this.pointerIdentifier = pointerIdentifier;
this.physicalDeltaX = physicalDeltaX;
this.physicalDeltaY = physicalDeltaY;
this.synthesized = synthesized;
this.pressure = pressure;
this.pressureMin = pressureMin;
this.pressureMax = pressureMax;

public readonly PointerDeviceKind kind;
public readonly PointerSignalKind signalKind;
public readonly int device;
public readonly int pointerIdentifier;
public readonly float physicalDeltaX;
public readonly float physicalDeltaY;
public readonly bool synthesized;
public readonly float pressure;
public readonly float pressureMin;
public readonly float pressureMax;

public readonly int platformData;
public readonly float scrollDeltaX;
public readonly float scrollDeltaY;
}
public class ScrollData : PointerData {
public ScrollData(
TimeSpan timeStamp,
PointerChange change,
PointerDeviceKind kind,
PointerSignalKind signalKind = PointerSignalKind.none,
int device = 0,
float physicalX = 0.0f,
float physicalY = 0.0f,
float scrollX = 0.0f,
float scrollY = 0.0f) : base(timeStamp, change, kind, signalKind, device, physicalX, physicalY) {
this.scrollX = scrollX;
this.scrollY = scrollY;
}
public float scrollX;
public float scrollY;
public override string ToString() => $"PointerData(x: {physicalX}, y: {physicalY})";
public class PointerDataPacket {
public PointerDataPacket(List<PointerData> data) {
this.data = data;
// public class ScrollData : PointerData {
// public ScrollData(
// TimeSpan timeStamp,
// PointerChange change,
// PointerDeviceKind kind,
// PointerSignalKind signalKind = PointerSignalKind.none,
// int device = 0,
// float physicalX = 0.0f,
// float physicalY = 0.0f,
// float scrollX = 0.0f,
// float scrollY = 0.0f) : base(timeStamp, change, kind, signalKind, device, physicalX, physicalY) {
// this.scrollX = scrollX;
// this.scrollY = scrollY;
// }
//
// public float scrollX;
// public float scrollY;
// }
public struct PointerDataPacket {
public PointerDataPacket(List<PointerData> data = null) {
this.data = data ?? new List<PointerData>();
}
public readonly List<PointerData> data;

104
com.unity.uiwidgets/Runtime/ui2/hooks.cs


using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using AOT;
using Unity.UIWidgets.async2;

Window_updateWindowMetrics,
Window_beginFrame,
Window_drawFrame,
ui_._dispatchPlatformMessage);
ui_._dispatchPlatformMessage,
ui_._dispatchPointerDataPacket);
}
delegate void Mono_ThrowExceptionCallback(IntPtr exception);

Window_updateWindowMetricsCallback Window_updateWindowMetrics,
Window_beginFrameCallback Window_beginFrame,
Window_drawFrameCallback Window_drawFrame,
ui_.Window_dispatchPlatformMessageCallback Window_dispatchPlatformMessage);
ui_.Window_dispatchPlatformMessageCallback Window_dispatchPlatformMessage,
ui_.Window_dispatchPointerDataPacketCallback Window_dispatchPointerDataPacket);
}
public static partial class ui_ {

internal static unsafe void _dispatchPlatformMessage(
string name, byte* dataRaw, int dataLength, int responseId) {
try {
var window = Window.instance;
var data = new byte[dataLength];
Marshal.Copy((IntPtr) dataRaw, data, 0, dataLength);

Debug.LogError($"Message to \"{name}\" caused exception {ex}");
}
finally {
Window.instance._respondToPlatformMessage(responseId, null);
window._respondToPlatformMessage(responseId, null);
else if (Window.instance.onPlatformMessage != null) {
else if (window.onPlatformMessage != null) {
(name1, data1, callback1) => Window.instance.onPlatformMessage(name1, data1, callback1),
Window.instance._onPlatformMessageZone,
name, data, responseData =>
Window.instance._respondToPlatformMessage(responseId, responseData)
(name1, data1, callback1) => window.onPlatformMessage(name1, data1, callback1),
window._onPlatformMessageZone,
name, data, responseData => window._respondToPlatformMessage(responseId, responseData)
=> Window.instance._respondToPlatformMessage(responseId, responseData));
=> window._respondToPlatformMessage(responseId, responseData));
}
}
catch (Exception ex) {

internal unsafe delegate void Window_dispatchPointerDataPacketCallback(byte* bytes, int length);
[MonoPInvokeCallback(typeof(Window_dispatchPointerDataPacketCallback))]
internal static unsafe void _dispatchPointerDataPacket(byte* bytes, int length) {
try {
var window = Window.instance;
Debug.Log(_unpackPointerDataPacket(bytes, length));
if (window.onPointerDataPacket != null)
_invoke1<PointerDataPacket>(
p => window.onPointerDataPacket(p),
window._onPointerDataPacketZone,
_unpackPointerDataPacket(bytes, length));
}
catch (Exception ex) {
Debug.LogException(ex);
}
}
internal static void _invoke1<A>(Action<A> callback, Zone zone, A arg) {
if (callback == null)
return;
D.assert(zone != null);
if (ReferenceEquals(zone, Zone.current)) {
callback(arg);
}
else {
zone.runUnaryGuarded((a) => {
callback((A) a);
return null;
}, arg);
}
}
internal static void _invoke3<A1, A2, A3>(Action<A1, A2, A3> callback, Zone zone, A1 arg1, A2 arg2, A3 arg3) {
if (callback == null)
return;

return null;
});
}
}
const int _kPointerDataFieldCount = 28;
static unsafe PointerDataPacket _unpackPointerDataPacket(byte* packet, int packetLength) {
const int kStride = 8;
const int kBytesPerPointerData = _kPointerDataFieldCount * kStride;
int length = packetLength / kBytesPerPointerData;
D.assert(length * kBytesPerPointerData == packetLength);
List<PointerData> data = new List<PointerData>(length);
for (int i = 0; i < length; ++i) {
int offset = i * _kPointerDataFieldCount;
data.Add(new PointerData(
timeStamp: TimeSpan.FromMilliseconds(*(long*) (packet + kStride * offset++)),
change: (PointerChange) (*(long*) (packet + kStride * offset++)),
kind: (PointerDeviceKind) (*(long*) (packet + kStride * offset++)),
signalKind: (PointerSignalKind) (*(long*) (packet + kStride * offset++)),
device: (int) *(long*) (packet + kStride * offset++),
pointerIdentifier: (int) (*(long*) (packet + kStride * offset++)),
physicalX: (float) *(double*) (packet + kStride * offset++),
physicalY: (float) *(double*) (packet + kStride * offset++),
physicalDeltaX: (float) *(double*) (packet + kStride * offset++),
physicalDeltaY: (float) *(double*) (packet + kStride * offset++),
buttons: (int) *(long*) (packet + kStride * offset++),
obscured: *(long*) (packet + kStride * offset++) != 0,
synthesized: *(long*) (packet + kStride * offset++) != 0,
pressure: (float) *(double*) (packet + kStride * offset++),
pressureMin: (float) *(double*) (packet + kStride * offset++),
pressureMax: (float) *(double*) (packet + kStride * offset++),
distance: (float) *(double*) (packet + kStride * offset++),
distanceMax: (float) *(double*) (packet + kStride * offset++),
size: (float) *(double*) (packet + kStride * offset++),
radiusMajor: (float) *(double*) (packet + kStride * offset++),
radiusMinor: (float) *(double*) (packet + kStride * offset++),
radiusMin: (float) *(double*) (packet + kStride * offset++),
radiusMax: (float) *(double*) (packet + kStride * offset++),
orientation: (float) *(double*) (packet + kStride * offset++),
tilt: (float) *(double*) (packet + kStride * offset++),
platformData: (int) *(long*) (packet + kStride * offset++),
scrollDeltaX: (float) *(double*) (packet + kStride * offset++),
scrollDeltaY: (float) *(double*) (packet + kStride * offset++)
));
D.assert(offset == (i + 1) * _kPointerDataFieldCount);
}
return new PointerDataPacket(data: data);
}
}
}

13
com.unity.uiwidgets/Runtime/ui2/window.cs


}
}
public PointerDataPacketCallback onPointerDataPacket { get; set; }
public PointerDataPacketCallback onPointerDataPacket {
get { return _onPointerDataPacket; }
set {
_onPointerDataPacket = value;
_onPointerDataPacketZone = Zone.current;
}
}
PointerDataPacketCallback _onPointerDataPacket;
internal Zone _onPointerDataPacketZone;
public string defaultRouteName {
get {

[DllImport(NativeBindings.dllName)]
static extern void Window_freeDefaultRouteName(IntPtr routeNamePtr);
[DllImport(NativeBindings.dllName)]
static extern void Window_scheduleFrame(IntPtr ptr);

66
engine/src/lib/ui/window/pointer_data.h


namespace uiwidgets {
static constexpr int kPointerDataFieldCount = 28;
static constexpr int kBytesPerField = sizeof(int32_t);
static constexpr int kBytesPerField = sizeof(int64_t);
enum PointerButtonMouse : int32_t {
enum PointerButtonMouse : int64_t {
kPointerButtonMousePrimary = 1 << 0,
kPointerButtonMouseSecondary = 1 << 1,
kPointerButtonMouseMiddle = 1 << 2,

enum PointerButtonTouch : int32_t {
enum PointerButtonTouch : int64_t {
enum PointerButtonStylus : int32_t {
enum PointerButtonStylus : int64_t {
struct alignas(8) PointerData {
enum class Change : int32_t {
struct alignas(4) PointerData {
enum class Change : int64_t {
kCancel,
kAdd,
kRemove,

kUp,
};
enum class DeviceKind : int32_t {
enum class DeviceKind : int64_t {
kTouch,
kMouse,
kStylus,

enum class SignalKind : int32_t {
enum class SignalKind : int64_t {
int32_t time_stamp;
int64_t time_stamp;
int32_t device;
int32_t pointer_identifier;
float physical_x;
float physical_y;
float physical_delta_x;
float physical_delta_y;
int32_t buttons;
int32_t obscured;
int32_t synthesized;
float pressure;
float pressure_min;
float pressure_max;
float distance;
float distance_max;
float size;
float radius_major;
float radius_minor;
float radius_min;
float radius_max;
float orientation;
float tilt;
int32_t platformData;
float scroll_delta_x;
float scroll_delta_y;
int64_t device;
int64_t pointer_identifier;
double physical_x;
double physical_y;
double physical_delta_x;
double physical_delta_y;
int64_t buttons;
int64_t obscured;
int64_t synthesized;
double pressure;
double pressure_min;
double pressure_max;
double distance;
double distance_max;
double size;
double radius_major;
double radius_minor;
double radius_min;
double radius_max;
double orientation;
double tilt;
int64_t platformData;
double scroll_delta_x;
double scroll_delta_y;
void Clear();
};

17
engine/src/lib/ui/window/window.cc


int response_id);
Window_dispatchPlatformMessageCallback Window_dispatchPlatformMessage_;
typedef void (*Window_dispatchPointerDataPacketCallback)(const uint8_t* data,
int data_length);
Window_dispatchPointerDataPacketCallback Window_dispatchPointerDataPacket_;
UIWIDGETS_API(void)
Window_hook(
Window_constructorCallback Window_constructor,

Window_drawFrameCallback Window_drawFrame,
Window_dispatchPlatformMessageCallback Window_dispatchPlatformMessage) {
Window_dispatchPlatformMessageCallback Window_dispatchPlatformMessage,
Window_dispatchPointerDataPacketCallback Window_dispatchPointerDataPacket) {
Window_constructor_ = Window_constructor;
Window_dispose_ = Window_dispose;
Window_updateWindowMetrics_ = Window_updateWindowMetrics;

Window_dispatchPointerDataPacket_ = Window_dispatchPointerDataPacket;
}
UIWIDGETS_API(Mono_Handle) Window_instance() {

response_id);
}
void Window::DispatchPointerDataPacket(const PointerDataPacket& packet) {}
void Window::DispatchPointerDataPacket(const PointerDataPacket& packet) {
std::shared_ptr<MonoState> mono_state = mono_state_.lock();
if (!mono_state) return;
MonoState::Scope scope(mono_state);
const auto& buffer = packet.data();
Window_dispatchPointerDataPacket_(buffer.data(), buffer.size());
}
void Window::BeginFrame(fml::TimePoint frameTime) {
std::shared_ptr<MonoState> mono_state = mono_state_.lock();

158
engine/src/shell/platform/unity/uiwidgets_panel.cc


UIWidgetsEngineRunInitialized(engine);
UIWidgetsSystem::GetInstancePtr()->RegisterPanel(this);
process_events_ = true;
}
void UIWidgetsPanel::MonoEntrypoint() { entrypoint_callback_(handle_); }

// drain pending vsync batons
ProcessVSync();
process_events_ = false;
UIWidgetsSystem::GetInstancePtr()->UnregisterPanel(this);

vsync_batons_.push_back(baton);
}
using TimePoint = std::chrono::steady_clock::time_point;
void UIWidgetsPanel::SetEventPhaseFromCursorButtonState(
UIWidgetsPointerEvent* event_data) {
MouseState state = GetMouseState();
event_data->phase = state.buttons == 0
? state.state_is_down ? UIWidgetsPointerPhase::kUp
: UIWidgetsPointerPhase::kHover
: state.state_is_down ? UIWidgetsPointerPhase::kMove
: UIWidgetsPointerPhase::kDown;
}
void UIWidgetsPanel::SendMouseMove(float x, float y) {
UIWidgetsPointerEvent event = {};
event.x = x;
event.y = y;
SetEventPhaseFromCursorButtonState(&event);
SendPointerEventWithData(event);
}
void UIWidgetsPanel::SendMouseDown(float x, float y) {
UIWidgetsPointerEvent event = {};
SetEventPhaseFromCursorButtonState(&event);
event.x = x;
event.y = y;
SendPointerEventWithData(event);
SetMouseStateDown(true);
}
void UIWidgetsPanel::SendMouseUp(float x, float y) {
UIWidgetsPointerEvent event = {};
SetEventPhaseFromCursorButtonState(&event);
event.x = x;
event.y = y;
SendPointerEventWithData(event);
if (event.phase == UIWidgetsPointerPhase::kUp) {
SetMouseStateDown(false);
}
}
void UIWidgetsPanel::SendMouseLeave() {
UIWidgetsPointerEvent event = {};
event.phase = UIWidgetsPointerPhase::kRemove;
SendPointerEventWithData(event);
}
void UIWidgetsPanel::SendPointerEventWithData(
const UIWidgetsPointerEvent& event_data) {
MouseState mouse_state = GetMouseState();
// If sending anything other than an add, and the pointer isn't already added,
// synthesize an add to satisfy Flutter's expectations about events.
if (!mouse_state.state_is_added &&
event_data.phase != UIWidgetsPointerPhase::kAdd) {
UIWidgetsPointerEvent event = {};
event.phase = UIWidgetsPointerPhase::kAdd;
event.x = event_data.x;
event.y = event_data.y;
event.buttons = 0;
SendPointerEventWithData(event);
}
// Don't double-add (e.g., if events are delivered out of order, so an add has
// already been synthesized).
if (mouse_state.state_is_added &&
event_data.phase == UIWidgetsPointerPhase::kAdd) {
return;
}
TimePoint next_flutter_event_time = TimePoint::clock::now();
UIWidgetsPointerEvent event = event_data;
event.device_kind = kUIWidgetsPointerDeviceKindMouse;
event.buttons = mouse_state.buttons;
// Set metadata that's always the same regardless of the event.
event.struct_size = sizeof(event);
event.timestamp =
std::chrono::duration_cast<std::chrono::microseconds>(
std::chrono::high_resolution_clock::now().time_since_epoch())
.count();
UIWidgetsEngineSendPointerEvent(engine_, &event, 1);
if (event_data.phase == UIWidgetsPointerPhase::kAdd) {
SetMouseStateAdded(true);
} else if (event_data.phase == UIWidgetsPointerPhase::kRemove) {
SetMouseStateAdded(false);
ResetMouseState();
}
}
void UIWidgetsPanel::OnMouseMove(float x, float y) {
if (process_events_) {
SendMouseMove(x, y);
}
}
static uint64_t ConvertToUIWidgetsButton(int button) {
switch (button) {
case -1:
return kUIWidgetsPointerButtonMousePrimary;
case -2:
return kUIWidgetsPointerButtonMouseSecondary;
case -3:
return kUIWidgetsPointerButtonMouseMiddle;
}
std::cerr << "Mouse button not recognized: " << button << std::endl;
return 0;
}
void UIWidgetsPanel::OnMouseDown(float x, float y, int button) {
if (process_events_) {
uint64_t uiwidgets_button = ConvertToUIWidgetsButton(button);
if (uiwidgets_button != 0) {
uint64_t mouse_buttons = GetMouseState().buttons | uiwidgets_button;
SetMouseButtons(mouse_buttons);
SendMouseDown(x, y);
}
}
}
void UIWidgetsPanel::OnMouseUp(float x, float y, int button) {
if (process_events_) {
uint64_t uiwidgets_button = ConvertToUIWidgetsButton(button);
if (uiwidgets_button != 0) {
uint64_t mouse_buttons = GetMouseState().buttons & ~uiwidgets_button;
SetMouseButtons(mouse_buttons);
SendMouseUp(x, y);
}
}
}
void UIWidgetsPanel::OnMouseLeave() {
if (process_events_) {
SendMouseLeave();
}
}
UIWIDGETS_API(UIWidgetsPanel*)
UIWidgetsPanel_constructor(

UIWIDGETS_API(void)
UIWidgetsPanel_unregisterTexture(UIWidgetsPanel* panel, int texture_id) {
return panel->UnregisterTexture(texture_id);
panel->UnregisterTexture(texture_id);
}
UIWIDGETS_API(void)
UIWidgetsPanel_onMouseDown(UIWidgetsPanel* panel, float x, float y,
int button) {
panel->OnMouseDown(x, y, button);
}
UIWIDGETS_API(void)
UIWidgetsPanel_onMouseUp(UIWidgetsPanel* panel, float x, float y, int button) {
panel->OnMouseUp(x, y, button);
UIWIDGETS_API(void)
UIWidgetsPanel_onMouseMove(UIWidgetsPanel* panel, float x, float y) {
panel->OnMouseMove(x, y);
}
UIWIDGETS_API(void)
UIWidgetsPanel_onMouseLeave(UIWidgetsPanel* panel) { panel->OnMouseLeave(); }
} // namespace uiwidgets

41
engine/src/shell/platform/unity/uiwidgets_panel.h


namespace uiwidgets {
struct MouseState {
bool state_is_down = false;
bool state_is_added = false;
uint64_t buttons = 0;
};
class UIWidgetsPanel : public fml::RefCountedThreadSafe<UIWidgetsPanel> {
FML_FRIEND_MAKE_REF_COUNTED(UIWidgetsPanel);

void VSyncCallback(intptr_t baton);
void OnMouseMove(float x, float y);
void OnMouseDown(float x, float y, int button);
void OnMouseUp(float x, float y, int button);
void OnMouseLeave();
MouseState GetMouseState() { return mouse_state_; }
void ResetMouseState() { mouse_state_ = MouseState(); }
void SetMouseStateDown(bool is_down) { mouse_state_.state_is_down = is_down; }
void SetMouseStateAdded(bool is_added) {
mouse_state_.state_is_added = is_added;
}
void SetMouseButtons(uint64_t buttons) { mouse_state_.buttons = buttons; }
void SendMouseMove(float x, float y);
void SendMouseDown(float x, float y);
void SendMouseUp(float x, float y);
void SendMouseLeave();
void SetEventPhaseFromCursorButtonState(UIWidgetsPointerEvent* event_data);
void SendPointerEventWithData(const UIWidgetsPointerEvent& event_data);
Mono_Handle handle_;
EntrypointCallback entrypoint_callback_;

UIWidgetsEngine engine_ = nullptr;
std::vector<intptr_t> vsync_batons_;
MouseState mouse_state_;
bool process_events_ = false;
};
} // namespace uiwidgets
正在加载...
取消
保存