您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 
 
 

598 行
19 KiB

using System;
using System.Collections.Generic;
using Unity.UIWidgets.async;
using Unity.UIWidgets.engine;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.scheduler;
using Unity.UIWidgets.service;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
using UnityEditor;
using UnityEngine;
namespace Unity.UIWidgets.editor {
#if UNITY_EDITOR
public abstract class UIWidgetsEditorWindow : EditorWindow, WindowHost {
WindowAdapter _windowAdapter;
static readonly List<UIWidgetsEditorWindow> _activeEditorWindows = new List<UIWidgetsEditorWindow>();
[InitializeOnLoadMethod]
static void _OnBaseEditorWindowLoaded()
{
EditorApplication.quitting += () =>
{
foreach (var editorWindow in _activeEditorWindows) {
editorWindow.OnDisable();
}
_activeEditorWindows.Clear();
};
}
public UIWidgetsEditorWindow() {
wantsMouseMove = true;
wantsMouseEnterLeaveWindow = true;
_activeEditorWindows.Add(this);
}
void OnDestroy() {
if (_activeEditorWindows.Contains(this)) {
_activeEditorWindows.Remove(this);
}
}
protected virtual void OnEnable() {
if (_windowAdapter == null) {
_windowAdapter = new EditorWindowAdapter(this);
}
_windowAdapter.OnEnable();
RenderBox rootRenderBox;
using (_windowAdapter.getScope()) {
rootRenderBox = createRenderBox();
}
if (rootRenderBox != null) {
_windowAdapter.attachRootRenderBox(rootRenderBox);
return;
}
Widget rootWidget;
using (_windowAdapter.getScope()) {
rootWidget = createWidget();
}
_windowAdapter.attachRootWidget(rootWidget);
}
protected virtual void OnDisable() {
_windowAdapter.OnDisable();
}
protected virtual void OnGUI() {
_windowAdapter.OnGUI(Event.current);
}
protected virtual void Update() {
_windowAdapter.Update();
}
protected virtual RenderBox createRenderBox() {
return null;
}
protected abstract Widget createWidget();
public Window window {
get { return _windowAdapter; }
}
}
public class EditorWindowAdapter : WindowAdapter {
public readonly EditorWindow editorWindow;
public EditorWindowAdapter(EditorWindow editorWindow) : base(true) {
this.editorWindow = editorWindow;
}
public override void scheduleFrame(bool regenerateLayerTree = true) {
base.scheduleFrame(regenerateLayerTree);
editorWindow.Repaint();
}
protected override bool hasFocus() {
return EditorWindow.focusedWindow == editorWindow;
}
public override GUIContent titleContent {
get { return editorWindow.titleContent; }
}
protected override float queryDevicePixelRatio() {
return EditorGUIUtility.pixelsPerPoint;
}
protected override int queryAntiAliasing() {
return defaultAntiAliasing;
}
protected override Vector2 queryWindowSize() {
return editorWindow.position.size;
}
protected override TimeSpan getTime() {
return TimeSpan.FromSeconds(EditorApplication.timeSinceStartup);
}
float? _lastUpdateTime;
protected override void updateDeltaTime() {
if (_lastUpdateTime == null) {
_lastUpdateTime = (float) EditorApplication.timeSinceStartup;
}
deltaTime = (float) EditorApplication.timeSinceStartup - _lastUpdateTime.Value;
unscaledDeltaTime = deltaTime;
_lastUpdateTime = (float) EditorApplication.timeSinceStartup;
}
}
#endif
public interface WindowHost {
Window window { get; }
}
public abstract class WindowAdapter : Window {
static readonly List<WindowAdapter> _windowAdapters = new List<WindowAdapter>();
public WindowAdapter(bool inEditorWindow = false) {
this.inEditorWindow = inEditorWindow;
}
public static List<WindowAdapter> windowAdapters {
get { return _windowAdapters; }
}
public WidgetInspectorService widgetInspectorService {
get {
D.assert(_binding != null);
return _binding.widgetInspectorService;
}
}
internal WidgetsBinding _binding;
float _lastWindowWidth;
float _lastWindowHeight;
bool _viewMetricsChanged;
readonly MicrotaskQueue _microtaskQueue = new MicrotaskQueue();
readonly TimerProvider _timerProvider = new TimerProvider();
readonly Rasterizer _rasterizer = new Rasterizer();
readonly ScrollInput _scrollInput = new ScrollInput();
bool _regenerateLayerTree;
Surface _surface;
bool _alive;
public bool alive {
get { return _alive; }
}
protected virtual TimeSpan getTime() {
return TimeSpan.FromSeconds(Time.time);
}
protected float deltaTime;
protected float unscaledDeltaTime;
void updatePhysicalSize() {
var size = queryWindowSize();
_physicalSize = new Size(
size.x * _devicePixelRatio,
size.y * _devicePixelRatio);
}
protected virtual void updateDeltaTime() {
deltaTime = Time.unscaledDeltaTime;
unscaledDeltaTime = Time.deltaTime;
}
protected virtual void updateSafeArea() {
}
public void onViewMetricsChanged() {
_viewMetricsChanged = true;
}
protected abstract bool hasFocus();
public void OnEnable() {
_devicePixelRatio = queryDevicePixelRatio();
_antiAliasing = queryAntiAliasing();
updatePhysicalSize();
updateSafeArea();
D.assert(_surface == null);
_surface = createSurface();
_rasterizer.setup(_surface);
_windowAdapters.Add(this);
_alive = true;
}
public void OnDisable() {
using (getScope()) {
_binding.detachRootWidget();
}
_windowAdapters.Remove(this);
_alive = false;
_rasterizer.teardown();
D.assert(_surface != null);
_surface.Dispose();
_surface = null;
}
readonly protected bool inEditorWindow;
public override IDisposable getScope() {
WindowAdapter oldInstance = (WindowAdapter) _instance;
_instance = this;
if (_binding == null) {
_binding = new WidgetsBinding(inEditorWindow);
}
SchedulerBinding._instance = _binding;
return new WindowDisposable(this, oldInstance);
}
class WindowDisposable : IDisposable {
readonly WindowAdapter _window;
readonly WindowAdapter _oldWindow;
public WindowDisposable(WindowAdapter window, WindowAdapter oldWindow) {
_window = window;
_oldWindow = oldWindow;
}
public void Dispose() {
D.assert(_instance == _window);
_instance = _oldWindow;
D.assert(SchedulerBinding._instance == _window._binding);
SchedulerBinding._instance = _oldWindow?._binding;
}
}
public void postPointerEvents(List<PointerData> data) {
withBinding(() => { onPointerEvent(new PointerDataPacket(data)); });
}
public void postPointerEvent(PointerData data) {
postPointerEvents(new List<PointerData>() {data});
}
public void withBinding(Action fn) {
using (getScope()) {
fn();
}
}
public T withBindingFunc<T>(Func<T> fn) {
using (getScope()) {
return fn();
}
}
protected bool displayMetricsChanged() {
if (_devicePixelRatio != queryDevicePixelRatio()) {
return true;
}
if (_antiAliasing != queryAntiAliasing()) {
return true;
}
var size = queryWindowSize();
if (_lastWindowWidth != size.x
|| _lastWindowHeight != size.y) {
return true;
}
if (_viewMetricsChanged) {
return true;
}
return false;
}
public virtual void OnGUI(Event evt = null) {
evt = evt ?? Event.current;
using (getScope()) {
if (displayMetricsChanged()) {
_devicePixelRatio = queryDevicePixelRatio();
_antiAliasing = queryAntiAliasing();
var size = queryWindowSize();
_lastWindowWidth = size.x;
_lastWindowHeight = size.y;
_physicalSize = new Size(
_lastWindowWidth * _devicePixelRatio,
_lastWindowHeight * _devicePixelRatio);
updateSafeArea();
_viewMetricsChanged = false;
if (onMetricsChanged != null) {
onMetricsChanged();
}
}
_doOnGUI(evt);
}
}
public virtual GUIContent titleContent {
get { return null; }
}
protected abstract float queryDevicePixelRatio();
protected abstract int queryAntiAliasing();
protected abstract Vector2 queryWindowSize();
protected virtual Surface createSurface() {
return new WindowSurfaceImpl();
}
void _beginFrame() {
if (onBeginFrame != null) {
onBeginFrame(getTime());
}
flushMicrotasks();
if (onDrawFrame != null) {
onDrawFrame();
}
}
void _doOnGUI(Event evt) {
if (evt.type == EventType.Repaint) {
if (_regenerateLayerTree) {
_regenerateLayerTree = false;
_beginFrame();
}
else {
_rasterizer.drawLastLayerTree();
}
return;
}
if (onPointerEvent != null) {
PointerData pointerData = new PointerData();
if (evt.type == EventType.MouseDown) {
pointerData = new PointerData(
timeStamp: Timer.timespanSinceStartup,
change: PointerChange.down,
kind: PointerDeviceKind.mouse,
device: InputUtils.getMouseButtonKey(evt.button),
physicalX: evt.mousePosition.x * _devicePixelRatio,
physicalY: evt.mousePosition.y * _devicePixelRatio
);
}
else if (evt.type == EventType.MouseUp || evt.rawType == EventType.MouseUp) {
pointerData = new PointerData(
timeStamp: Timer.timespanSinceStartup,
change: PointerChange.up,
kind: PointerDeviceKind.mouse,
device: InputUtils.getMouseButtonKey(evt.button),
physicalX: evt.mousePosition.x * _devicePixelRatio,
physicalY: evt.mousePosition.y * _devicePixelRatio
);
}
else if (evt.type == EventType.MouseDrag) {
pointerData = new PointerData(
timeStamp: Timer.timespanSinceStartup,
change: PointerChange.move,
kind: PointerDeviceKind.mouse,
device: InputUtils.getMouseButtonKey(evt.button),
physicalX: evt.mousePosition.x * _devicePixelRatio,
physicalY: evt.mousePosition.y * _devicePixelRatio
);
}
else if (evt.type == EventType.MouseMove) {
pointerData = new PointerData(
timeStamp: Timer.timespanSinceStartup,
change: PointerChange.hover,
kind: PointerDeviceKind.mouse,
device: InputUtils.getMouseButtonKey(evt.button),
physicalX: evt.mousePosition.x * _devicePixelRatio,
physicalY: evt.mousePosition.y * _devicePixelRatio
);
}
else if (evt.type == EventType.ScrollWheel) {
onScroll(-evt.delta.x * _devicePixelRatio,
-evt.delta.y * _devicePixelRatio,
evt.mousePosition.x * _devicePixelRatio,
evt.mousePosition.y * _devicePixelRatio,
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
// }));
// }
}
RawKeyboard.instance._handleKeyEvent(Event.current);
TextInput.OnGUI();
}
public void onScroll(float deltaX, float deltaY, float posX, float posY, int buttonId) {
_scrollInput.onScroll(deltaX,
deltaY,
posX,
posY,
buttonId
);
}
void _updateScrollInput(float deltaTime) {
var deltaScroll = _scrollInput.getScrollDelta(deltaTime);
if (deltaScroll == Vector2.zero) {
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
// }));
}
public void Update() {
if (_physicalSize == null || _physicalSize.isEmpty) {
updatePhysicalSize();
}
updateDeltaTime();
updateFPS(unscaledDeltaTime);
Timer.update();
bool hasFocus = this.hasFocus();
using (getScope()) {
WidgetsBinding.instance.focusManager.focusNone(!hasFocus);
_updateScrollInput(deltaTime);
TextInput.Update();
_timerProvider.update(flushMicrotasks);
flushMicrotasks();
}
}
static readonly TimeSpan _coolDownDelay = new TimeSpan(0, 0, 0, 0, 200);
static Timer frameCoolDownTimer;
public override void scheduleFrame(bool regenerateLayerTree = true) {
if (regenerateLayerTree) {
_regenerateLayerTree = true;
}
onFrameRateSpeedUp();
frameCoolDownTimer?.cancel();
frameCoolDownTimer = instance.run(
_coolDownDelay,
() => {
onFrameRateCoolDown();
frameCoolDownTimer = null;
});
}
public override void render(Scene scene) {
var layerTree = scene.takeLayerTree();
if (layerTree == null) {
return;
}
if (_physicalSize.isEmpty) {
return;
}
layerTree.frameSize = _physicalSize;
layerTree.devicePixelRatio = _devicePixelRatio;
layerTree.antiAliasing = _antiAliasing;
_rasterizer.draw(layerTree);
}
public override void scheduleMicrotask(Action callback) {
_microtaskQueue.scheduleMicrotask(callback);
}
public override void flushMicrotasks() {
_microtaskQueue.flushMicrotasks();
}
public override Timer run(TimeSpan duration, Action callback, bool periodic = false) {
return periodic
? _timerProvider.periodic(duration, callback)
: _timerProvider.run(duration, callback);
}
public override Timer runInMain(Action callback) {
return _timerProvider.runInMain(callback);
}
public void attachRootRenderBox(RenderBox root) {
using (getScope()) {
_binding.renderView.child = root;
}
}
public void attachRootWidget(Widget root) {
using (getScope()) {
_binding.attachRootWidget(root);
}
}
public void attachRootWidget(Func<Widget> root) {
using (getScope()) {
_binding.attachRootWidget(root());
}
}
internal void _forceRepaint() {
using (getScope()) {
RenderObjectVisitor visitor = null;
visitor = (child) => {
child.markNeedsPaint();
child.visitChildren(visitor);
};
_binding.renderView?.visitChildren(visitor);
}
}
}
}