浏览代码

Merge pull request #215 from Unity-Technologies/shiyun_HoverFix

Fix hover
/main
GitHub 3 年前
当前提交
21566389
共有 1 个文件被更改,包括 208 次插入185 次删除
  1. 393
      com.unity.uiwidgets/Runtime/rendering/mouse_tracking.cs

393
com.unity.uiwidgets/Runtime/rendering/mouse_tracking.cs


using System;
using System.Collections.Generic;
using System.Linq;
using Unity.UIWidgets.foundation;

public delegate void PointerExitEventListener(PointerExitEvent evt);
public delegate void PointerDragFromEditorEnterEventListener(PointerDragFromEditorEnterEvent evt);
public delegate void PointerDragFromEditorHoverEventListener(PointerDragFromEditorHoverEvent evt);
public delegate void PointerDragFromEditorExitEventListener(PointerDragFromEditorExitEvent evt);
public delegate void _UpdatedDeviceHandler(_MouseState mouseState,
HashSet<MouseTrackerAnnotation> previousAnnotations);
public delegate void PointerDragFromEditorReleaseEventListener(PointerDragFromEditorReleaseEvent evt);
public delegate void _UpdatedDeviceHandler(_MouseState mouseState, HashSet<MouseTrackerAnnotation> previousAnnotations);
public class _MouseState {
PointerEvent _latestEvent;
public class _MouseState {
public _MouseState(PointerEvent initialEvent = null
) {
D.assert(initialEvent != null);

public HashSet<MouseTrackerAnnotation> annotations {
get { return _annotations;}
}
HashSet<MouseTrackerAnnotation> _annotations = new HashSet<MouseTrackerAnnotation>();
public HashSet<MouseTrackerAnnotation> replaceAnnotations(HashSet<MouseTrackerAnnotation> value) {
HashSet<MouseTrackerAnnotation> previous = _annotations;
_annotations = value;
return previous;
}
public HashSet<MouseTrackerAnnotation> annotations { get; private set; } =
new HashSet<MouseTrackerAnnotation>();
// The most recently processed mouse event observed from this device.
public PointerEvent latestEvent {

_latestEvent = value;
}
}
PointerEvent _latestEvent;
get { return latestEvent.device;}
get { return latestEvent.device; }
}
public HashSet<MouseTrackerAnnotation> replaceAnnotations(HashSet<MouseTrackerAnnotation> value) {
var previous = annotations;
annotations = value;
return previous;
return Event == null ? "null" : describeIdentity(Event);
return Event == null ? "null" : describeIdentity(Object: Event);
string describeLatestEvent = $"latestEvent: {describeEvent(latestEvent)}";
string describeAnnotations = $"annotations: [list of {annotations.Count}]";
return $"{describeIdentity(this)}"+$"({describeLatestEvent}, {describeAnnotations})";
var describeLatestEvent = $"latestEvent: {describeEvent(Event: latestEvent)}";
var describeAnnotations = $"annotations: [list of {annotations.Count}]";
return $"{describeIdentity(this)}" + $"({describeLatestEvent}, {describeAnnotations})";
public class MouseTrackerAnnotation {
public class MouseTrackerAnnotation : Diagnosticable {
public readonly PointerEnterEventListener onEnter;
public readonly PointerExitEventListener onExit;
public readonly PointerHoverEventListener onHover;
PointerExitEventListener onExit = null,
PointerDragFromEditorEnterEventListener onDragFromEditorEnter = null,
PointerDragFromEditorHoverEventListener onDragFromEditorHover = null,
PointerDragFromEditorExitEventListener onDragFromEditorExit = null,
PointerDragFromEditorReleaseEventListener onDragFromEditorRelease = null
PointerExitEventListener onExit = null
this.onDragFromEditorEnter = onDragFromEditorEnter;
this.onDragFromEditorHover = onDragFromEditorHover;
this.onDragFromEditorExit = onDragFromEditorExit;
this.onDragFromEditorRelease = onDragFromEditorRelease;
public readonly PointerEnterEventListener onEnter;
public readonly PointerHoverEventListener onHover;
public readonly PointerExitEventListener onExit;
public readonly PointerDragFromEditorEnterEventListener onDragFromEditorEnter;
public readonly PointerDragFromEditorHoverEventListener onDragFromEditorHover;
public readonly PointerDragFromEditorExitEventListener onDragFromEditorExit;
public readonly PointerDragFromEditorReleaseEventListener onDragFromEditorRelease;
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties: properties);
properties.add(new FlagsSummary<Delegate>(
"callbacks",
new Dictionary<string, Delegate> {
{"enter", onEnter},
{"hover", onHover},
{"exit", onExit}
},
"<none>"
));
}
public readonly MouseTrackerAnnotation annotation;
public HashSet<int> activeDevices = new HashSet<int>();
}
public delegate IEnumerable<MouseTrackerAnnotation> MouseDetectorAnnotationFinder(Offset offset);
public class MouseTracker : ChangeNotifier {
public readonly Dictionary<int, _MouseState> _mouseStates = new Dictionary<int, _MouseState>();
readonly PointerRouter _router;
public readonly MouseTrackerAnnotation annotation;
public readonly Dictionary<MouseTrackerAnnotation, _TrackedAnnotation> _trackedAnnotations =
new Dictionary<MouseTrackerAnnotation, _TrackedAnnotation>();
public HashSet<int> activeDevices = new HashSet<int>();
}
public readonly MouseDetectorAnnotationFinder annotationFinder;
public delegate IEnumerable<MouseTrackerAnnotation> MouseDetectorAnnotationFinder(Offset offset);
bool _duringDeviceUpdate;
public bool _hasScheduledPostFrameCheck;
public class MouseTracker : ChangeNotifier{
router.addGlobalRoute(_handleEvent);
router.addGlobalRoute(route: _handleEvent);
public bool mouseIsConnected {
get { return _mouseStates.isNotEmpty(); }
}
public static bool _duringBuildPhase {
get { return SchedulerBinding.instance.schedulerPhase == SchedulerPhase.persistentCallbacks; }
}
_router.removeGlobalRoute(_handleEvent);
_router.removeGlobalRoute(route: _handleEvent);
public readonly MouseDetectorAnnotationFinder annotationFinder;
readonly Dictionary<int, PointerEvent> _lastMouseEvent = new Dictionary<int, PointerEvent>();
readonly PointerRouter _router;
public readonly Dictionary<int, _MouseState> _mouseStates = new Dictionary<int, _MouseState>();
public bool mouseIsConnected {
get { return _lastMouseEvent.isNotEmpty(); }
}
if (state == null)
if (state == null) {
}
PointerEvent lastEvent = state.latestEvent;
var lastEvent = state.latestEvent;
D.assert((value is PointerAddedEvent) == (lastEvent is PointerRemovedEvent));
if (value is PointerSignalEvent)
D.assert(value is PointerAddedEvent == lastEvent is PointerRemovedEvent);
if (value is PointerSignalEvent) {
}
public readonly Dictionary<MouseTrackerAnnotation, _TrackedAnnotation> _trackedAnnotations =
new Dictionary<MouseTrackerAnnotation, _TrackedAnnotation>();
if (Event.kind != PointerDeviceKind.mouse)
if (Event.kind != PointerDeviceKind.mouse) {
if (Event is PointerSignalEvent)
}
if (Event is PointerSignalEvent) {
int device = Event.device;
_MouseState existingState = _mouseStates.getOrDefault(device);
if (!_shouldMarkStateDirty(existingState, Event))
}
var device = Event.device;
var existingState = _mouseStates.getOrDefault(key: device);
if (!_shouldMarkStateDirty(state: existingState, value: Event)) {
PointerEvent previousEvent = existingState?.latestEvent;
}
var previousEvent = existingState?.latestEvent;
handleUpdatedDevice: (_MouseState mouseState, HashSet<MouseTrackerAnnotation> previousAnnotations) =>{
D.assert(mouseState.device == Event.device);
_dispatchDeviceCallbacks(
(mouseState, previousAnnotations) => {
D.assert(mouseState.device == Event.device);
_dispatchDeviceCallbacks(
lastAnnotations: previousAnnotations,
nextAnnotations: mouseState.annotations,
previousEvent: previousEvent,

);
}
public HashSet<MouseTrackerAnnotation> _findAnnotations(_MouseState state) {
var globalPosition = state.latestEvent.position;
var device = state.device;
var result = new HashSet<MouseTrackerAnnotation>();
foreach (var values in annotationFinder(offset: globalPosition)) {
result.Add(item: values);
}
return _mouseStates.ContainsKey(key: device)
? result
: new HashSet<MouseTrackerAnnotation>();
}
public void _updateAllDevices() {
_updateDevices(
handleUpdatedDevice: (mouseState, previousAnnotations) => {
_dispatchDeviceCallbacks(
lastAnnotations: previousAnnotations,
nextAnnotations: mouseState.annotations,
previousEvent: mouseState.latestEvent
);
}
);
}
void _updateDevices(
PointerEvent targetEvent = null,
_UpdatedDeviceHandler handleUpdatedDevice = null) {
D.assert(handleUpdatedDevice != null);
D.assert(result: !_duringBuildPhase);
D.assert(result: !_duringDeviceUpdate);
var mouseWasConnected = mouseIsConnected;
_MouseState targetState = null;
if (targetEvent != null) {
targetState = _mouseStates.getOrDefault(key: targetEvent.device);
if (targetState == null) {
targetState = new _MouseState(initialEvent: targetEvent);
_mouseStates[key: targetState.device] = targetState;
}
else {
D.assert(!(targetEvent is PointerAddedEvent));
targetState.latestEvent = targetEvent;
if (targetEvent is PointerRemovedEvent) {
_mouseStates.Remove(key: targetEvent.device);
}
}
}
D.assert(targetState == null == (targetEvent == null));
D.assert(() => {
_duringDeviceUpdate = true;
return true;
});
var dirtyStates = targetEvent == null
? (IEnumerable<_MouseState>) _mouseStates.Values
: new List<_MouseState> {targetState};
foreach (var dirtyState in dirtyStates) {
var nextAnnotations = _findAnnotations(state: dirtyState);
var lastAnnotations = dirtyState.replaceAnnotations(value: nextAnnotations);
handleUpdatedDevice(mouseState: dirtyState, previousAnnotations: lastAnnotations);
}
D.assert(() => {
_duringDeviceUpdate = false;
return true;
});
if (mouseWasConnected != mouseIsConnected) {
notifyListeners();
}
}
) {
) {
PointerEvent latestEvent = unhandledEvent ?? previousEvent;
var latestEvent = unhandledEvent ?? previousEvent;
var exiting = new List<MouseTrackerAnnotation>();
if (!nextAnnotations.Contains(lastAnnotation)) {
exitingAnnotations.Append(lastAnnotation);
if (!nextAnnotations.Contains(item: lastAnnotation)) {
exiting.Add(item: lastAnnotation);
foreach ( MouseTrackerAnnotation annotation in exitingAnnotations) {
exitingAnnotations = exiting;
foreach (var annotation in exitingAnnotations) {
annotation.onExit(PointerExitEvent.fromMouseEvent(latestEvent));
annotation.onExit(PointerExitEvent.fromMouseEvent(hover: latestEvent));
List<MouseTrackerAnnotation> entering = new List<MouseTrackerAnnotation>();
var entering = new List<MouseTrackerAnnotation>();
if (!lastAnnotations.Contains(nextAnnotation)) {
entering.Add(nextAnnotation);
if (!lastAnnotations.Contains(item: nextAnnotation)) {
entering.Add(item: nextAnnotation);
}
}
foreach ( MouseTrackerAnnotation annotation in enteringAnnotations) {
foreach (var annotation in enteringAnnotations) {
annotation.onEnter(PointerEnterEvent.fromMouseEvent(latestEvent));
annotation.onEnter(PointerEnterEvent.fromMouseEvent(hover: latestEvent));
if (unhandledEvent is PointerHoverEvent) {
Offset lastHoverPosition = previousEvent is PointerHoverEvent ? previousEvent.position : null;
bool pointerHasMoved = lastHoverPosition == null || lastHoverPosition != unhandledEvent.position;
nextAnnotations.ToList().Reverse();
IEnumerable<MouseTrackerAnnotation> hoveringAnnotations = pointerHasMoved ? nextAnnotations : enteringAnnotations;
foreach ( MouseTrackerAnnotation annotation in hoveringAnnotations) {
if (annotation.onHover != null) {
annotation.onHover((PointerHoverEvent)unhandledEvent);
}
}
}
}
public HashSet<MouseTrackerAnnotation> _findAnnotations(_MouseState state) {
Offset globalPosition = state.latestEvent.position;
int device = state.device;
HashSet<MouseTrackerAnnotation> result = new HashSet<MouseTrackerAnnotation>();
foreach (var values in annotationFinder(globalPosition)) {
result.Add(values);
if (unhandledEvent is PointerHoverEvent) {
var lastHoverPosition = previousEvent is PointerHoverEvent ? previousEvent.position : null;
var pointerHasMoved = lastHoverPosition == null || lastHoverPosition != unhandledEvent.position;
nextAnnotations.ToList().Reverse();
var hoveringAnnotations = pointerHasMoved ? nextAnnotations : enteringAnnotations;
foreach (var annotation in hoveringAnnotations) {
if (annotation.onHover != null) {
annotation.onHover((PointerHoverEvent) unhandledEvent);
}
}
return (_mouseStates.ContainsKey(device))
? result
: new HashSet<MouseTrackerAnnotation>{} as HashSet<MouseTrackerAnnotation>;
public static bool _duringBuildPhase {
get {
return SchedulerBinding.instance.schedulerPhase == SchedulerPhase.persistentCallbacks;
}
}
public void _updateAllDevices() {
_updateDevices(
handleUpdatedDevice: (_MouseState mouseState, HashSet<MouseTrackerAnnotation> previousAnnotations)=> {
_dispatchDeviceCallbacks(
lastAnnotations: previousAnnotations,
nextAnnotations: mouseState.annotations,
previousEvent: mouseState.latestEvent,
unhandledEvent: null
);
}
);
}
bool _duringDeviceUpdate = false;
void _updateDevices(
PointerEvent targetEvent = null,
_UpdatedDeviceHandler handleUpdatedDevice = null) {
D.assert(handleUpdatedDevice != null);
D.assert(!_duringBuildPhase);
D.assert(!_duringDeviceUpdate);
bool mouseWasConnected = mouseIsConnected;
_MouseState targetState = null;
if (targetEvent != null) {
targetState = _mouseStates.getOrDefault(targetEvent.device);
if (targetState == null) {
targetState = new _MouseState(initialEvent: targetEvent);
_mouseStates[targetState.device] = targetState;
} else {
D.assert(!(targetEvent is PointerAddedEvent));
targetState.latestEvent = targetEvent;
if (targetEvent is PointerRemovedEvent)
_mouseStates.Remove(targetEvent.device);
}
public void schedulePostFrameCheck() {
D.assert(result: _duringBuildPhase);
D.assert(result: !_duringDeviceUpdate);
if (!mouseIsConnected) {
return;
D.assert((targetState == null) == (targetEvent == null));
D.assert(()=> {
_duringDeviceUpdate = true;
return true;
});
IEnumerable<_MouseState> dirtyStates = targetEvent == null ? (IEnumerable<_MouseState>) _mouseStates.Values : new List<_MouseState>{targetState};
foreach ( _MouseState dirtyState in dirtyStates) {
HashSet<MouseTrackerAnnotation> nextAnnotations = _findAnnotations(dirtyState);
HashSet<MouseTrackerAnnotation> lastAnnotations = dirtyState.replaceAnnotations(nextAnnotations);
handleUpdatedDevice(dirtyState, lastAnnotations);
}
D.assert(() =>{
_duringDeviceUpdate = false;
return true;
});
if (mouseWasConnected != mouseIsConnected)
notifyListeners();
}
public bool _hasScheduledPostFrameCheck = false;
public void schedulePostFrameCheck() {
D.assert(_duringBuildPhase);
D.assert(!_duringDeviceUpdate);
if (!mouseIsConnected)
return;
_hasScheduledPostFrameCheck = true;
SchedulerBinding.instance.addPostFrameCallback((stamp => {
D.assert(_hasScheduledPostFrameCheck);
_hasScheduledPostFrameCheck = false;
_updateAllDevices();
}));
_hasScheduledPostFrameCheck = true;
SchedulerBinding.instance.addPostFrameCallback(stamp => {
D.assert(result: _hasScheduledPostFrameCheck);
_hasScheduledPostFrameCheck = false;
_updateAllDevices();
});
}
}
}
正在加载...
取消
保存