浏览代码

Merge branch 'master' into siyaoH/1.17/fixAndroid

/siyaoH-1.17-fixAndroid
siyao 3 年前
当前提交
da847262
共有 31 个文件被更改,包括 1023 次插入43 次删除
  1. 55
      README-ZH.md
  2. 58
      README.md
  3. 8
      com.unity.uiwidgets/Editor/UIWidgetsEditorPanel.cs
  4. 27
      com.unity.uiwidgets/Runtime/engine/UIWidgetsPanelWrapper.cs
  5. 20
      com.unity.uiwidgets/Runtime/gestures/converter.cs
  6. 20
      com.unity.uiwidgets/Runtime/gestures/events.cs
  7. 8
      com.unity.uiwidgets/Runtime/painting/text_style.cs
  8. 2
      com.unity.uiwidgets/Runtime/ui/pointer.cs
  9. 2
      com.unity.uiwidgets/Runtime/widgets/binding.cs
  10. 2
      engine/src/lib/ui/window/pointer_data.h
  11. 8
      engine/src/lib/ui/window/pointer_data_packet_converter.cc
  12. 4
      engine/src/shell/platform/embedder/embedder.cc
  13. 2
      engine/src/shell/platform/embedder/embedder.h
  14. 4
      engine/src/shell/platform/unity/darwin/macos/uiwidgets_panel.h
  15. 42
      engine/src/shell/platform/unity/darwin/macos/uiwidgets_panel.mm
  16. 43
      engine/src/shell/platform/unity/windows/uiwidgets_panel.cc
  17. 5
      engine/src/shell/platform/unity/windows/uiwidgets_panel.h
  18. 63
      Samples/UIWidgetsSamples_2019_4/Assets/Editor/EditorWindowSample/UnityObjectDragging.cs
  19. 3
      Samples/UIWidgetsSamples_2019_4/Assets/Editor/EditorWindowSample/UnityObjectDragging.cs.meta
  20. 8
      com.unity.uiwidgets/Editor/gesture.meta
  21. 3
      com.unity.uiwidgets/Editor/widgets.meta
  22. 64
      com.unity.uiwidgets/Editor/gesture/binding.cs
  23. 3
      com.unity.uiwidgets/Editor/gesture/binding.cs.meta
  24. 3
      com.unity.uiwidgets/Editor/gesture/editor_mouse_tracking.cs.meta
  25. 260
      com.unity.uiwidgets/Editor/gesture/editor_mouse_tracking.cs
  26. 222
      com.unity.uiwidgets/Editor/widgets/unity_editor_listener.cs
  27. 3
      com.unity.uiwidgets/Editor/widgets/unity_editor_listener.cs.meta
  28. 121
      com.unity.uiwidgets/Editor/widgets/unity_object_detector.cs
  29. 3
      com.unity.uiwidgets/Editor/widgets/unity_object_detector.cs.meta

55
README-ZH.md


UIWidgets主要来自[Flutter](https://github.com/flutter/flutter)。但UIWidgets通过使用强大的Unity引擎为开发人员提供了许多新功能,显著地改进他们开发的应用性能和工作流程。
UIWidgets 2.0是UIWidgets的最新版本,它主要着力于UI绘制相关的整体性能优化。经测试,UIWidgets 2.0在iPhone 6等部分机型上的帧率相对1.0版本可以取得10%左右的提升。如果因为各种原因您还需要使用UIWidgets 1.0,请在Releases中下载对应的包或者使用uiwidgets_1.0分支。
**UIWidgets 2.0**是UIWidgets的最新版本,它针对**中国版Unity**开发并主要着力于UI绘制相关的整体性能优化。经测试,UIWidgets 2.0在iPhone 6等部分机型上的帧率相对1.0版本可以取得10%左右的提升。
如果因为各种原因您还需要使用UIWidgets 1.0,请在Releases中下载对应的包或者使用uiwidgets_1.0分支。
#### 效率
通过使用最新的Unity渲染SDK,UIWidgets应用可以非常快速地运行并且大多数时间保持大于60fps的速度。

### 基于UIWidgets的项目
#### Unity Connect App
Unity Connect App是使用UIWidgets开发的一个移动App产品,您随时可以在Android (https://unity.cn/connectApp/download)
Unity Connect App是使用**UIWidgets 2.0**开发的一个移动App产品,您随时可以在Android (https://unity.cn/connectApp/download)
Unity的线上中文官方文档由UIWidgets开发,您可以点击以下网址 https://connect.unity.com/doc 来访问它的全部内容。该项目目前已开源,所有代码可以在
Unity的线上中文官方文档由UIWidgets 1.0开发,您可以点击以下网址 https://connect.unity.com/doc 来访问它的全部内容。该项目目前已开源,所有代码可以在
:warning: **注意:UIWidgets 2.0仅仅适用于中国版Unity**
UIWidgets的各个版本所需的Unity版本如下表所示。您可以从[https://unity.cn/releases](https://unity.cn/releases)下载最新的Unity。

| 2.0.1 | 2019.4.26f1c1 | N\A |
| 2.0.2 及以上 | 2019.4.26f1c1 ~ 2019.4.29f1c1 | N\A |
| 2.0.3 | 2019.4.26f1c1 ~ 2019.4.29f1c1 | N\A |
| 2.0.4及以上 | 2019.4.26f1c1 ~ 2019.4.29f1c1 | 2020.3.24f1c2 及以上 |
#### UIWidgets包

cd <YourPackagePath>
git clone https://github.com/Unity-Technologies/com.unity.uiwidgets.git com.unity.uiwidgets
```
在unity的PackageManager中,选择添加添加local file。选中```/com.unity.uiwidgets```下的```package.json```。
此外,因为UIWidgets 2.0中为各个平台编译的C++动态库文件较大,我们使用了github提供的**Git Large File Storage**来管理它们以
优化下载体验。为此,请您确保在下载UIWidgets前安装好该[服务](https://docs.github.com/en/repositories/working-with-files/managing-large-files/installing-git-large-file-storage)以便正确下载动态库文件。
最后,在unity的PackageManager中,选择添加添加local file。选中```/com.unity.uiwidgets```下的```package.json```。
UIWidgets目前暂时只支持MacOS(Metal),iOS(Metal),Android(Armv7,OpenGLes)以及 Windows(Direct3D11)。我们后续会针对更广泛的运行环境进行适配,敬请期待。
**UIWidgets 2.0**目前暂时只支持MacOS(Intel64,Metal),iOS(Metal),Android(OpenGLes)以及 Windows(Direct3D11)。我们后续会针对更广泛的运行环境进行适配,敬请期待。与之相对的,UIWidgets 1.0目前支持所有Unity导出目标平台。
## 入门指南

#### 常问问题解答
| 问题 | 回答 |
| :-----------------------------------------------| ---------------------: |
| 我可以使用UIWidgets创建独立应用吗? | 可以 |
| 我可以使用UIWidgets构建游戏UI吗? | 可以 |
| 我可以使用UIWidgets开发Unity编辑器插件吗? | 可以 |
| UIWidgets是UGUI / NGUI的扩展吗? | 不是 |
| UIWidgets只是Flutter的副本吗? | 不是 |
| 我可以通过简单的拖放操作来创建带有UIWidgets的UI吗? | 不可以 |
| 我是否需要付费使用UIWidgets? | 不需要 |
| 有推荐的适用于UIWidgets的IDE吗? | Rider, VSCode(Open .sln) |
1. 在打开一个UIWidgets 2.0项目后Unity编辑器崩溃了。
请确定您使用的Unity编辑器版本兼容您使用的UIWidgets版本。例如,**UIWidgets 2.0.3**只支持以下中国版Unity版本:2019.4.26f1c1 ~ 2019.4.29f1c1。您可以在[这里](#unity)查找兼容您UIWidgets版本的Unity版本信息。
2. 在打开一个UIWidgets 2.0项目后Unity控制台报错,报错信息为**DllNotFoundException: libUIWidgets**。
请首先检查您的UIWidgets根目录下/Runtime/Plugins中适配各个平台的C++库文件是否完整。例如,Windows平台下的libUIWidgets.dll位于*X86_64*子目录下,Mac平台下的libUIWidgets.dylib位于*osx*目录下。
如果您发现库文件不存在或者文件大小不正常(<1MB)请确认您已经在您电脑上安装了**Git Large File Storage**然后在UIWidgets根目录下执行如下指令
```
git lfs pull
```
3. UIWidgets 2.0和UIWidgets 1.0的区别大吗?哪个更适合我的项目?
在UIWidgets 1.0中所有渲染相关代码都由C#编写并且使用了Unity [Graphics API](https://docs.unity3d.com/ScriptReference/Graphics.html)
进行渲染。因此它可以正确运行在任意Unity支持的平台。不过与此同时,它的运行效率较低,且渲染效果与flutter在某一些细节上并不一致。
在UIWidgets 2.0中我们将一个flutter引擎嵌入到了C++动态库中,然后Unity通过调用这个动态库来进行渲染。因此,它的渲染结果与flutter完全一致,且性能比C#实现的渲染代码有明显提升。不过为了使flutter引擎和Unity可以正确协作,我们对flutter和Unity引擎都进行了一些修改。因此,目前UIWidgets 2.0只能够运行在包含上述修改的中国版Unity中,并且暂时只支持部分Unity的目标平台。
由于UIWidgets 2.0在效果和效率上的优势,因此推荐大家使用。仅当您需要在UIWidgets 2.0暂时不支持的平台(如webgl)上开发时才推荐使用UIWidgets 1.0。此外,由于人力原因,目前只有UIWidgets 2.0我们会持续更新。
4. 使用Unity 2020.3LTS打包UIWidgets 2.0的项目到iOS平台后Build失败,提示无法链接到OpenGLES库函数。
这是因为在Unity 2020.3版本中Unity导出的iOS项目默认不再包含对OpenGLES库的依赖,但UIWidgets 2.0需要依赖该库。为了解决这个问题,您需要手动用Xcode打开项目并为UnityFramework添加上对OpenGLES库的依赖。
## 如何贡献
请查看[CONTRIBUTING.md](CONTRIBUTING.md)

58
README.md


the powerful Unity Engine, it offers developers many new features to improve their Apps
as well as the develop workflow significantly.
As the latest version, UIWidgets 2.0 aims to optimize the overall performance of the package. Specifically, a performance gain around 10% is observed on mobile devices like iPhone 6 after upgrading to UIWidgets 2.0. However, if you still want to use the original UIWidgets 1.0, please download the archived packages from Releases or switch your working branch to uiwidgets_1.0.
**UIWidgets 2.0** is developed for **Unity China version** deliberately and aims to **optimize the overall performance of the package**. Specifically, a performance gain around **10%** is observed on mobile devices like iPhone 6 after upgrading to UIWidgets 2.0.
If you still want to use the original UIWidgets 1.0, please download the archived packages from Releases or switch your working branch to uiwidgets_1.0.
#### Efficiency
Using the latest Unity rendering SDKs, a UIWidgets App can run very fast and keep >60fps in most times.

### Projects using UIWidgets
#### Unity Connect App
The Unity Connect App is created using UIWidgets and available for both Android (https://unity.cn/connectApp/download)
The Unity Connect App is created using **UIWidgets 2.0** and available for both Android (https://unity.cn/connectApp/download)
The official website of Unity Chinese Documentation (https://connect.unity.com/doc) is powered by UIWidgets and
The official website of Unity Chinese Documentation (https://connect.unity.com/doc) is powered by UIWidgets 1.0 and
open-sourced @https://github.com/UnityTech/DocCN.
## Requirements

The compatible Unity versions for each UIWidgets release are listed below. You can download the latest Unity on [https://unity.cn/releases](https://unity.cn/releases).
:warning: **UIWidgets 2.0 are only compatible with Unity China version**
Specifically, the compatible Unity versions for each UIWidgets release are listed below. You can download the latest Unity on [https://unity.cn/releases](https://unity.cn/releases).
| 2.0.2 and above | 2019.4.26f1c1 ~ 2019.4.29f1c1 | N\A |
| 2.0.3 | 2019.4.26f1c1 ~ 2019.4.29f1c1 | N\A |
| 2.0.4 and above | 2019.4.26f1c1 ~ 2019.4.29f1c1 | 2020.3.24f1c2 and above |
#### UIWidgets Package
Visit our Github repository https://github.com/Unity-Technologies/com.unity.uiwidgets

git clone https://github.com/Unity-Technologies/com.unity.uiwidgets.git com.unity.uiwidgets
```
In PackageManger of unity, select add local file. select ```package.json``` under ```/com.unity.uiwidgets```
Note that there are many native libraries we built for UIWidget 2.0 to boost its performance, which are large files and hosted by
**Git Large File Storage**. You need to install [this service](https://docs.github.com/en/repositories/working-with-files/managing-large-files/installing-git-large-file-storage) first and then use it to fetch these libraries.
Finally, in PackageManger of unity, select add local file. select ```package.json``` under ```/com.unity.uiwidgets```
Currently UIWidgets only supports MacOS(Metal), iOS(Metal), Android(Armv7, OpenGLes) and Windows(Direct3D11). More devices will be supported in the future.
:warning: Though UIWidgets 1.0 is compatible to all platforms, currently **UIWidgets 2.0** only supports MacOS(Intel64, Metal), iOS(Metal), Android(OpenGLes) and Windows(Direct3D11). More devices will be supported in the future.
## Getting Start

#### FAQ
| Question | Answer |
| :-----------------------------------------------| ---------------------: |
| Can I create standalone App using UIWidgets? | **Yes** |
| Can I use UIWidgets to build game UIs? | **Yes** |
| Can I develop Unity Editor plugins using UIWidgets? | **Yes** |
| Is UIWidgets a extension of UGUI/NGUI? | **No** |
| Is UIWidgets just a copy of Flutter? | **No** |
| Can I create UI with UIWidgets by simply drag&drop? | **No** |
| Do I have to pay for using UIWidgets? | **No** |
| Any IDE recommendation for UIWidgets? | **Rider, VSCode(Open .sln)** |
1. The editor crashes when openning a UIWidgets 2.0 project, e.g., the Sample projects.
Please make sure that you are using campatible Unity versions to the specific UIWidgets version. For example, **UIWidgets 2.0.3** is only supported on Unity China version between 2019.4.26f1c1 and 2019.4.29f1c1. You can find the detailed information in
this [section](#unity).
2. After openning a UIWidgets 2.0 project I receive an error **DllNotFoundException: libUIWidgets**.
Please make sure that the native libraries are correctly downloaded to your project. You can find them under *UIWidgetsPackageRoot*/Runtime/Plugins. For example, the libUIWidgets.dll under the sub folder *X86_64* is the native library for Windows and the libUIWidgets.dylib under *osx* is for Mac.
If the libraries are not there or their sizes are small (<1MB), please ensure that you have installed **Git Large File Storage** in your computer and then try the following command line inside the UIWidgets repository.
```
git lfs pull
```
3. What is the difference between UIWidgets 2.0 and UIWidgets 1.0 ?
In UIWidgets 1.0 we used Unity [Graphics API](https://docs.unity3d.com/ScriptReference/Graphics.html) for the rendering and all rendering codes are writen in C#. Therefore it is able to run freely on all platforms that Unity supports but relatively slow. The rendering result is also not exactly the same as in flutter due to the difference between the Unity rendering engine and flutter engine.
In UIWidgets 2.0, we wrapped the flutter engine inside a native library which is writen in C++ and used it to render on Unity Textures. Its rendering result is the same as in flutter and the performance is also better. However, in order to ensure that the flutter engine works properly along with Unity, we modified both the flutter and Unity Engine. As the result, currently UIWidgets 2.0 can only run on specific Unity versions, i.e., Unity China version and supports only part of the build targets of Unity.
For better rendering result, performance and continuous upgrade and support, you are always suggested to use UIWidgets 2.0 for your project. Use UIWidgets 1.0 only if you need to support specific target platforms like webgl.
4. I encountered with a link error with OpenGLES for iOS build using UIWidgets 2.0 with Unity 2020.3LTS.
This is caused by Unity because it removed the dependency on OpenGLES library on Unity 2020.3. To fix this issue, please open the XCode project and manually add the OpenGLES library to the UnityFramework target.
## How to Contribute

8
com.unity.uiwidgets/Editor/UIWidgetsEditorPanel.cs


var pos = _getPointerPosition(position: evt.mousePosition);
_wrapper.OnMouseScroll(delta: delta, pos: pos);
}
else if (evt.type == EventType.DragUpdated) {
var pos = _getPointerPosition(position: evt.mousePosition);
_wrapper.OnDragUpdateInEditor(pos: pos);
}
else if (evt.type == EventType.DragPerform || evt.type == EventType.DragExited) {
var pos = _getPointerPosition(position: evt.mousePosition);
_wrapper.OnDragReleaseInEditor(pos: pos);
}
else if (evt.isKey) {
_wrapper.OnKeyDown(e: evt);
Event.current.Use();

27
com.unity.uiwidgets/Runtime/engine/UIWidgetsPanelWrapper.cs


public void OnPointerLeave() {
UIWidgetsPanel_onMouseLeave(ptr: _ptr);
}
public void OnDragUpdateInEditor(Vector2? pos) {
if (pos == null) {
return;
}
UIWidgetsPanel_onDragUpdateInEditor(ptr: _ptr, x: pos.Value.x, y: pos.Value.y);
}
public void OnDragReleaseInEditor(Vector2? pos) {
if (pos == null) {
return;
}
UIWidgetsPanel_onDragReleaseInEditor(ptr: _ptr, x: pos.Value.x, y: pos.Value.y);
}
public void OnKeyDown(Event e) {
int modifier = 0;

[DllImport(dllName: NativeBindings.dllName)]
static extern void UIWidgetsPanel_onScroll(IntPtr ptr, float x, float y, float px, float py);
#if UNITY_EDITOR
[DllImport(dllName: NativeBindings.dllName)]
static extern void UIWidgetsPanel_onDragUpdateInEditor(IntPtr ptr, float x ,float y);
[DllImport(dllName: NativeBindings.dllName)]
static extern void UIWidgetsPanel_onDragReleaseInEditor(IntPtr ptr, float x ,float y);
#else
static void UIWidgetsPanel_onDragUpdateInEditor(IntPtr ptr, float x, float y) { throw new NotImplementedException(); }
static void UIWidgetsPanel_onDragReleaseInEditor(IntPtr ptr, float x ,float y) { throw new NotImplementedException(); }
#endif
}
#endregion

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


case ui.PointerSignalKind.none:
D.assert(false); // This branch should already have 'none' filtered out.
break;
case ui.PointerSignalKind.editorDragMove: {
yield return new PointerDragFromEditorHoverEvent(
timeStamp: timeStamp,
pointer: datum.pointerIdentifier,
kind: kind,
device: datum.device,
position: position
);
break;
}
case ui.PointerSignalKind.editorDragRelease: {
yield return new PointerDragFromEditorReleaseEvent(
timeStamp: timeStamp,
pointer: datum.pointerIdentifier,
kind: kind,
device: datum.device,
position: position
);
break;
}
case ui.PointerSignalKind.unknown:
// Ignore unknown signals.
break;

20
com.unity.uiwidgets/Runtime/gestures/events.cs


Offset position = null,
Offset localPosition = null,
Matrix4 transform = null,
Object[] objectReferences = null,
string[] paths = null,
PointerDragFromEditorEnterEvent original = null
) : base(
timeStamp,

transform: transform,
original: original
) {
this.objectReferences = objectReferences;
this.paths = paths;
public Object[] objectReferences;
public string[] paths;
public static PointerDragFromEditorEnterEvent fromDragFromEditorEvent(PointerEvent evt) {
public static PointerDragFromEditorEnterEvent fromDragFromEditorEvent(PointerEvent evt,
Object[] objectReferences, string[] paths) {
return new PointerDragFromEditorEnterEvent(
timeStamp: evt.timeStamp,
pointer: evt.pointer,

localPosition: evt.localPosition,
transform: evt.transform,
objectReferences: objectReferences,
paths: paths,
original: evt.original as PointerDragFromEditorEnterEvent
);
}

position: position,
localPosition: transformPosition(transform, position),
transform: transform,
objectReferences: objectReferences,
paths: paths,
original: original as PointerDragFromEditorEnterEvent ?? this
);
}

Offset position = null,
Offset localPosition = null,
Object[] objectReferences = null,
string[] paths = null,
Matrix4 transform = null,
PointerDragFromEditorReleaseEvent original = null
) : base(

original: original
) {
this.objectReferences = objectReferences;
this.paths = paths;
public string[] paths;
Object[] objectReferences) {
Object[] objectReferences, string[] paths) {
return new PointerDragFromEditorReleaseEvent(
timeStamp: evt.timeStamp,
pointer: evt.pointer,

localPosition: evt.localPosition,
objectReferences: objectReferences,
paths: paths,
transform: evt.transform,
original: evt.original as PointerDragFromEditorReleaseEvent
);

8
com.unity.uiwidgets/Runtime/painting/text_style.cs


}
public ui.TextStyle getTextStyle(float textScaleFactor = 1.0f) {
var backgroundPaint = new Paint();
if (background != null) {
backgroundPaint = new Paint();
backgroundPaint.color = backgroundColor;
}
return new ui.TextStyle(
color: color,
decoration: decoration,

// locale: locale,
foreground: foreground,
background: background ?? (backgroundColor != null
? backgroundPaint
? new Paint {color = backgroundColor}
: null
),
shadows: shadows?.Cast<Shadow>().ToList(),

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


public enum PointerSignalKind {
none,
scroll,
editorDragMove,
editorDragRelease,
unknown,
}

2
com.unity.uiwidgets/Runtime/widgets/binding.cs


_renderViewElement = null;
}
internal void scheduleAttachRootWidget(Widget rootWidget) {
public void scheduleAttachRootWidget(Widget rootWidget) {
Timer.run(() => {
attachRootWidget(rootWidget);
return null;

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


enum class SignalKind : int64_t {
kNone,
kScroll,
kEditorDragUpdate,
kEditorDragRelease
};
int64_t time_stamp;

8
engine/src/lib/ui/window/pointer_data_packet_converter.cc


converted_pointers.push_back(pointer_data);
break;
}
case PointerData::SignalKind::kEditorDragUpdate: {
converted_pointers.push_back(pointer_data);
break;
}
case PointerData::SignalKind::kEditorDragRelease: {
converted_pointers.push_back(pointer_data);
break;
}
default: {
// Ignores unknown signal kind.
break;

4
engine/src/shell/platform/embedder/embedder.cc


return PointerData::SignalKind::kNone;
case kUIWidgetsPointerSignalKindScroll:
return PointerData::SignalKind::kScroll;
case kUIWidgetsPointerSignalKindEditorDragUpdate:
return PointerData::SignalKind::kEditorDragUpdate;
case kUIWidgetsPointerSignalKindEditorDragRelease:
return PointerData::SignalKind::kEditorDragRelease;
}
return PointerData::SignalKind::kNone;
}

2
engine/src/shell/platform/embedder/embedder.h


typedef enum {
kUIWidgetsPointerSignalKindNone,
kUIWidgetsPointerSignalKindScroll,
kUIWidgetsPointerSignalKindEditorDragUpdate,
kUIWidgetsPointerSignalKindEditorDragRelease
} UIWidgetsPointerSignalKind;
typedef struct {

4
engine/src/shell/platform/unity/darwin/macos/uiwidgets_panel.h


void OnMouseLeave();
void OnDragUpdateInEditor(float x, float y);
void OnDragReleaseInEditor(float x, float y);
bool NeedUpdateByPlayerLoop();
bool NeedUpdateByEditorLoop();

42
engine/src/shell/platform/unity/darwin/macos/uiwidgets_panel.mm


}
}
void UIWidgetsPanel::OnDragUpdateInEditor(float x, float y)
{
if (process_events_) {
UIWidgetsPointerEvent event = {};
event.x = x;
event.y = y;
SetEventPhaseFromCursorButtonState(&event);
event.signal_kind = UIWidgetsPointerSignalKind::kUIWidgetsPointerSignalKindEditorDragUpdate;
SendPointerEventWithData(event);
}
}
void UIWidgetsPanel::OnDragReleaseInEditor(float x, float y)
{
if (process_events_) {
UIWidgetsPointerEvent event = {};
event.x = x;
event.y = y;
SetEventPhaseFromCursorButtonState(&event);
event.signal_kind = UIWidgetsPointerSignalKind::kUIWidgetsPointerSignalKindEditorDragRelease;
SendPointerEventWithData(event);
}
}
static uint64_t ConvertToUIWidgetsButton(int button) {
switch (button) {
case -1:

UIWIDGETS_API(void)
UIWidgetsPanel_onScroll(UIWidgetsPanel* panel, float x, float y, float px, float py) {
panel->OnScroll(x, y, px, py);
}
UIWIDGETS_API(void)
UIWidgetsPanel_onDragUpdateInEditor(UIWidgetsPanel* panel, float x, float y) {
if (!panel->NeedUpdateByEditorLoop()) {
return;
}
panel->OnDragUpdateInEditor(x, y);
}
UIWIDGETS_API(void)
UIWidgetsPanel_onDragReleaseInEditor(UIWidgetsPanel* panel, float x, float y) {
if (!panel->NeedUpdateByEditorLoop()) {
return;
}
panel->OnDragReleaseInEditor(x, y);
}
} // namespace uiwidgets

43
engine/src/shell/platform/unity/windows/uiwidgets_panel.cc


}
}
void UIWidgetsPanel::OnDragUpdateInEditor(float x, float y)
{
if (process_events_) {
UIWidgetsPointerEvent event = {};
event.x = x;
event.y = y;
SetEventPhaseFromCursorButtonState(&event);
event.signal_kind = UIWidgetsPointerSignalKind::kUIWidgetsPointerSignalKindEditorDragUpdate;
SendPointerEventWithData(event);
}
}
void UIWidgetsPanel::OnDragReleaseInEditor(float x, float y)
{
if (process_events_) {
UIWidgetsPointerEvent event = {};
event.x = x;
event.y = y;
SetEventPhaseFromCursorButtonState(&event);
event.signal_kind = UIWidgetsPointerSignalKind::kUIWidgetsPointerSignalKindEditorDragRelease;
SendPointerEventWithData(event);
}
}
static uint64_t ConvertToUIWidgetsButton(int button) {
switch (button) {
case -1:

UIWidgetsPanel_onScroll(UIWidgetsPanel* panel, float x, float y, float px, float py) {
panel->OnScroll(x, y, px, py);
}
UIWIDGETS_API(void)
UIWidgetsPanel_onDragUpdateInEditor(UIWidgetsPanel* panel, float x, float y) {
if (!panel->NeedUpdateByEditorLoop()) {
return;
}
panel->OnDragUpdateInEditor(x, y);
}
UIWIDGETS_API(void)
UIWidgetsPanel_onDragReleaseInEditor(UIWidgetsPanel* panel, float x, float y) {
if (!panel->NeedUpdateByEditorLoop()) {
return;
}
panel->OnDragReleaseInEditor(x, y);
}
} // namespace uiwidgets

5
engine/src/shell/platform/unity/windows/uiwidgets_panel.h


void OnMouseLeave();
void OnDragUpdateInEditor(float x, float y);
void OnDragReleaseInEditor(float x, float y);
bool NeedUpdateByPlayerLoop();
bool NeedUpdateByEditorLoop();

63
Samples/UIWidgetsSamples_2019_4/Assets/Editor/EditorWindowSample/UnityObjectDragging.cs


using System.Collections.Generic;
using uiwidgets;
using Unity.UIWidgets.Editor;
using Unity.UIWidgets.gestures;
using Unity.UIWidgets.widgets;
using UnityEditor;
using UnityEngine;
namespace UIWidgetsEditorWindowSample
{
public class UnityObjectDraggingWindow : UIWidgetsEditorPanel
{
[MenuItem("UIWidgets/EditorSample/UnityObjectDragging")]
public static void CountDemo()
{
CreateWindow<UnityObjectDraggingWindow>();
}
protected override void onEnable()
{
AddFont("Material Icons", new List<string> {"MaterialIcons-Regular.ttf"}, new List<int> {0});
AddFont("CupertinoIcons", new List<string> {"CupertinoIcons.ttf"}, new List<int> {0});
AddFont("GalleryIcons", new List<string> {"gallery/GalleryIcons.ttf"}, new List<int> {0});
}
protected override void main()
{
editor_ui_.runEditorApp(new MyApp());
}
public class MyApp : StatelessWidget
{
public override Widget build(BuildContext context)
{
return
new Container(color: Colors.green, child:
new Center(child:
new UnityObjectDetector(
child: new Container(color: Colors.blue, width: 200f, height: 200f,
child: new Center(child: new Text("Drag UnityObject or file to me"))),
onEnter: (details) =>
{
Debug.Log("enter");
},
onHover: (details =>
{
Debug.Log("position = " + details.position);
}),
onExit: () =>
{
Debug.Log("on exit");
},
onRelease: (details) =>
{
Debug.Log("on release");
}
)
)
);
}
}
}
}

3
Samples/UIWidgetsSamples_2019_4/Assets/Editor/EditorWindowSample/UnityObjectDragging.cs.meta


fileFormatVersion: 2
guid: 9916a1957385427fa807b2ce6a676522
timeCreated: 1637912586

8
com.unity.uiwidgets/Editor/gesture.meta


fileFormatVersion: 2
guid: acbe72faebec34ea3832cc33152ff6ab
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

3
com.unity.uiwidgets/Editor/widgets.meta


fileFormatVersion: 2
guid: 3bdd889f92fa4e7a9fc1fa29df736e55
timeCreated: 1637914329

64
com.unity.uiwidgets/Editor/gesture/binding.cs


using System;
using System.Collections.Generic;
using Unity.UIWidgets.gestures;
using Unity.UIWidgets.ui;
namespace Unity.UIWidgets.widgets {
public class UiWidgetsEditorBinding : UiWidgetsBinding {
public new static UiWidgetsEditorBinding instance {
get { return (UiWidgetsEditorBinding) UiWidgetsBinding.instance; }
set { UiWidgetsBinding.instance = value; }
}
public static UiWidgetsEditorBinding ensureInitializedForEditor() {
if (UiWidgetsEditorBinding.instance == null) {
return new UiWidgetsEditorBinding();
}
return UiWidgetsEditorBinding.instance;
}
public EditorMouseTracker editorMouseTracker {
get { return _editorMouseTracker; }
}
EditorMouseTracker _editorMouseTracker;
private void initEditorMouseTracker(EditorMouseTracker tracker = null) {
_editorMouseTracker?.dispose();
_editorMouseTracker = tracker ?? new EditorMouseTracker(pointerRouter, hitTestMouseTrackers);
}
public EditorMouseTrackerAnnotation hitTestMouseTrackers(Offset position) {
List<EditorMouseTrackerAnnotation> annotations =
new List<EditorMouseTrackerAnnotation>(renderView.layer.findAllAnnotations<EditorMouseTrackerAnnotation>(
position * renderView.configuration.devicePixelRatio
).annotations);
if (annotations is null || annotations.Count == 0) {
return null;
}
return annotations[0];
}
protected override void initInstances() {
base.initInstances();
addPersistentFrameCallback(_handlePersistentFrameCallbackForEditor);
initEditorMouseTracker();
}
private void _handlePersistentFrameCallbackForEditor(TimeSpan timeStamp) {
_editorMouseTracker.schedulePostFrameCheck();
}
}
public static class editor_ui_ {
public static void runEditorApp(Widget app) {
var instance = UiWidgetsEditorBinding.ensureInitializedForEditor();
instance.scheduleAttachRootWidget(app);
instance.scheduleWarmUpFrame();
}
}
}

3
com.unity.uiwidgets/Editor/gesture/binding.cs.meta


fileFormatVersion: 2
guid: 4a770ce594324a7eb95b9457697ace16
timeCreated: 1637749525

3
com.unity.uiwidgets/Editor/gesture/editor_mouse_tracking.cs.meta


fileFormatVersion: 2
guid: d4a8f193e3d549a8bf5093b001ea327b
timeCreated: 1637750451

260
com.unity.uiwidgets/Editor/gesture/editor_mouse_tracking.cs


using System.Collections.Generic;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.scheduler;
using Unity.UIWidgets.ui;
using UnityEditor;
namespace Unity.UIWidgets.gestures {
public delegate void PointerDragFromEditorEnterEventListener(PointerDragFromEditorEnterEvent evt);
public delegate void PointerDragFromEditorHoverEventListener(PointerDragFromEditorHoverEvent evt);
public delegate void PointerDragFromEditorExitEventListener(PointerDragFromEditorExitEvent evt);
public delegate void PointerDragFromEditorReleaseEventListener(PointerDragFromEditorReleaseEvent evt);
public delegate EditorMouseTrackerAnnotation EditorMouseDetectorAnnotationFinder(Offset offset);
public class EditorMouseTrackerAnnotation {
public EditorMouseTrackerAnnotation(
PointerDragFromEditorEnterEventListener onDragFromEditorEnter = null,
PointerDragFromEditorHoverEventListener onDragFromEditorHover = null,
PointerDragFromEditorExitEventListener onDragFromEditorExit = null,
PointerDragFromEditorReleaseEventListener onDragFromEditorRelease = null
) {
this.onDragFromEditorEnter = onDragFromEditorEnter;
this.onDragFromEditorHover = onDragFromEditorHover;
this.onDragFromEditorExit = onDragFromEditorExit;
this.onDragFromEditorRelease = onDragFromEditorRelease;
}
public readonly PointerDragFromEditorEnterEventListener onDragFromEditorEnter;
public readonly PointerDragFromEditorHoverEventListener onDragFromEditorHover;
public readonly PointerDragFromEditorExitEventListener onDragFromEditorExit;
public readonly PointerDragFromEditorReleaseEventListener onDragFromEditorRelease;
}
public class _EditorTrackedAnnotation {
public _EditorTrackedAnnotation(EditorMouseTrackerAnnotation annotation) {
this.annotation = annotation;
}
public readonly EditorMouseTrackerAnnotation annotation;
public readonly HashSet<int> activeDevices = new HashSet<int>();
}
public class EditorMouseTracker : ChangeNotifier {
public readonly Dictionary<int, PointerEvent> _lastMouseEvent = new Dictionary<int, PointerEvent>();
public bool mouseIsConnected => _lastMouseEvent.isNotEmpty();
public readonly EditorMouseDetectorAnnotationFinder annotationFinder;
public readonly Dictionary<EditorMouseTrackerAnnotation, _EditorTrackedAnnotation> _trackedAnnotations =
new Dictionary<EditorMouseTrackerAnnotation, _EditorTrackedAnnotation>();
public void attachDragFromEditorAnnotation(EditorMouseTrackerAnnotation annotation) {
_trackedAnnotations[annotation] = new _EditorTrackedAnnotation(annotation);
_scheduleDragFromEditorMousePositionCheck();
}
public void detachDragFromEditorAnnotation(EditorMouseTrackerAnnotation annotation) {
var trackedAnnotation = _findAnnotation(annotation);
foreach (var deviceId in trackedAnnotation.activeDevices) {
annotation.onDragFromEditorExit(PointerDragFromEditorExitEvent.fromDragFromEditorEvent(
_lastMouseEvent[deviceId]
));
}
_trackedAnnotations.Remove(annotation);
}
_EditorTrackedAnnotation _findAnnotation(EditorMouseTrackerAnnotation annotation) {
if (!_trackedAnnotations.TryGetValue(annotation, out var trackedAnnotation)) {
D.assert(false, () => $"Unable to find annotation {annotation} in tracked annotations.");
}
return trackedAnnotation;
}
public EditorMouseTracker(
PointerRouter router,
EditorMouseDetectorAnnotationFinder annotationFinder
) {
D.assert(router != null);
D.assert(annotationFinder != null);
router.addGlobalRoute(route: _handleEvent);
this.annotationFinder = annotationFinder;
}
void _handleEvent(PointerEvent evt) {
int deviceId = 0;
if (_trackedAnnotations.isEmpty()) {
_lastMouseEvent.Remove(deviceId);
return;
}
if (evt is PointerDragFromEditorReleaseEvent) {
_scheduleDragFromEditorReleaseCheck();
_lastMouseEvent.Remove(deviceId);
}
else if (evt is PointerDragFromEditorEnterEvent ||
evt is PointerDragFromEditorHoverEvent ||
evt is PointerDragFromEditorExitEvent) {
if (!_lastMouseEvent.ContainsKey(deviceId) ||
_lastMouseEvent[deviceId].position != evt.position) {
_scheduleDragFromEditorMousePositionCheck();
}
_lastMouseEvent[deviceId] = evt;
}
}
public void schedulePostFrameCheck() {
}
void _scheduleDragFromEditorReleaseCheck() {
DragAndDrop.AcceptDrag();
var lastMouseEvent = new List<PointerEvent>();
foreach (int deviceId in _lastMouseEvent.Keys) {
var _deviceId = deviceId;
var deviceEvent = _lastMouseEvent[_deviceId];
//only process PointerEditorDragEvents
if (!(deviceEvent is PointerDragFromEditorEnterEvent ||
deviceEvent is PointerDragFromEditorHoverEvent ||
deviceEvent is PointerDragFromEditorExitEvent)) {
continue;
}
lastMouseEvent.Add(_lastMouseEvent[_deviceId]);
SchedulerBinding.instance.addPostFrameCallback(_ => {
foreach (var lastEvent in lastMouseEvent) {
EditorMouseTrackerAnnotation hit = annotationFinder(lastEvent.position);
if (hit == null) {
foreach (_EditorTrackedAnnotation trackedAnnotation in _trackedAnnotations.Values) {
if (trackedAnnotation.activeDevices.Contains(_deviceId)) {
trackedAnnotation.activeDevices.Remove(_deviceId);
}
}
return;
}
_EditorTrackedAnnotation hitAnnotation = _findAnnotation(hit);
// release
if (hitAnnotation.activeDevices.Contains(_deviceId)) {
if (hitAnnotation.annotation?.onDragFromEditorRelease != null) {
hitAnnotation.annotation.onDragFromEditorRelease(
PointerDragFromEditorReleaseEvent
.fromDragFromEditorEvent(
lastEvent, DragAndDrop.objectReferences, DragAndDrop.paths));
}
hitAnnotation.activeDevices.Remove(_deviceId);
}
}
});
}
SchedulerBinding.instance.scheduleFrame();
}
void _scheduleDragFromEditorMousePositionCheck() {
SchedulerBinding.instance.addPostFrameCallback(_ => { collectDragFromEditorMousePositions(); });
SchedulerBinding.instance.scheduleFrame();
}
public void collectDragFromEditorMousePositions() {
void exitAnnotation(_EditorTrackedAnnotation trackedAnnotation, int deviceId) {
if (trackedAnnotation.activeDevices.Contains(deviceId)) {
if (trackedAnnotation.annotation?.onDragFromEditorExit != null) {
trackedAnnotation.annotation.onDragFromEditorExit(
PointerDragFromEditorExitEvent.fromDragFromEditorEvent(
_lastMouseEvent[deviceId]));
}
trackedAnnotation.activeDevices.Remove(deviceId);
}
}
void exitAllDevices(_EditorTrackedAnnotation trackedAnnotation) {
if (trackedAnnotation.activeDevices.isNotEmpty()) {
HashSet<int> deviceIds = new HashSet<int>(trackedAnnotation.activeDevices);
foreach (int deviceId in deviceIds) {
exitAnnotation(trackedAnnotation, deviceId);
}
}
}
if (!mouseIsConnected) {
foreach (var annotation in _trackedAnnotations.Values) {
exitAllDevices(annotation);
}
return;
}
foreach (int deviceId in _lastMouseEvent.Keys) {
PointerEvent lastEvent = _lastMouseEvent[deviceId];
EditorMouseTrackerAnnotation hit = annotationFinder(lastEvent.position);
if (hit == null) {
foreach (_EditorTrackedAnnotation trackedAnnotation in _trackedAnnotations.Values) {
exitAnnotation(trackedAnnotation, deviceId);
}
return;
}
_EditorTrackedAnnotation hitAnnotation = _findAnnotation(hit);
// While acrossing two areas, set the flag to true to prevent setting the Pointer Copy VisualMode to None
bool enterFlag = false;
// enter
if (!hitAnnotation.activeDevices.Contains(deviceId)) {
hitAnnotation.activeDevices.Add(deviceId);
enterFlag = true;
// Both onRelease or onEnter event will enable Copy VisualMode
if (hitAnnotation.annotation?.onDragFromEditorRelease != null ||
hitAnnotation.annotation?.onDragFromEditorEnter != null) {
if (hitAnnotation.annotation?.onDragFromEditorEnter != null) {
hitAnnotation.annotation.onDragFromEditorEnter(
PointerDragFromEditorEnterEvent
.fromDragFromEditorEvent(lastEvent, DragAndDrop.objectReferences, DragAndDrop.paths));
}
}
}
// hover
if (hitAnnotation.annotation?.onDragFromEditorHover != null) {
hitAnnotation.annotation.onDragFromEditorHover(
PointerDragFromEditorHoverEvent.fromDragFromEditorEvent(lastEvent));
}
// leave
foreach (_EditorTrackedAnnotation trackedAnnotation in _trackedAnnotations.Values) {
if (hitAnnotation == trackedAnnotation) {
continue;
}
if (trackedAnnotation.activeDevices.Contains(deviceId)) {
if (trackedAnnotation.annotation?.onDragFromEditorExit != null) {
trackedAnnotation.annotation.onDragFromEditorExit(
PointerDragFromEditorExitEvent
.fromDragFromEditorEvent(lastEvent));
}
trackedAnnotation.activeDevices.Remove(deviceId);
}
}
}
}
}
}

222
com.unity.uiwidgets/Editor/widgets/unity_editor_listener.cs


using System.Collections.Generic;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
namespace Unity.UIWidgets.gestures
{
public class UnityEditorListener : SingleChildRenderObjectWidget
{
public UnityEditorListener(
Key key = null,
PointerDragFromEditorEnterEventListener onPointerDragFromEditorEnter = null,
PointerDragFromEditorHoverEventListener onPointerDragFromEditorHover = null,
PointerDragFromEditorExitEventListener onPointerDragFromEditorExit = null,
PointerDragFromEditorReleaseEventListener onPointerDragFromEditorRelease = null,
HitTestBehavior behavior = HitTestBehavior.deferToChild,
Widget child = null) : base(key: key, child: child)
{
this.onPointerDragFromEditorEnter = onPointerDragFromEditorEnter;
this.onPointerDragFromEditorHover = onPointerDragFromEditorHover;
this.onPointerDragFromEditorExit = onPointerDragFromEditorExit;
this.onPointerDragFromEditorRelease = onPointerDragFromEditorRelease;
this.behavior = behavior;
}
public readonly PointerDragFromEditorEnterEventListener onPointerDragFromEditorEnter;
public readonly PointerDragFromEditorHoverEventListener onPointerDragFromEditorHover;
public readonly PointerDragFromEditorExitEventListener onPointerDragFromEditorExit;
public readonly PointerDragFromEditorReleaseEventListener onPointerDragFromEditorRelease;
public readonly HitTestBehavior behavior;
public override RenderObject createRenderObject(BuildContext context) {
return new UnityEditorRenderPointerListener(
onPointerDragFromEditorEnter: onPointerDragFromEditorEnter,
onPointerDragFromEditorHover: onPointerDragFromEditorHover,
onPointerDragFromEditorExit: onPointerDragFromEditorExit,
onPointerDragFromEditorRelease: onPointerDragFromEditorRelease,
behavior: behavior
);
}
public override void updateRenderObject(BuildContext context, RenderObject renderObjectRaw) {
var renderObject = (UnityEditorRenderPointerListener) renderObjectRaw;
renderObject.behavior = behavior;
renderObject.onPointerDragFromEditorEnter = onPointerDragFromEditorEnter;
renderObject.onPointerDragFromEditorHover = onPointerDragFromEditorHover;
renderObject.onPointerDragFromEditorExit = onPointerDragFromEditorExit;
renderObject.onPointerDragFromEditorRelease = onPointerDragFromEditorRelease;
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
List<string> listeners = new List<string>();
if (onPointerDragFromEditorEnter != null) {
listeners.Add("dragFromEditorEnter");
}
if (onPointerDragFromEditorHover != null) {
listeners.Add("dragFromEditorHover");
}
if (onPointerDragFromEditorExit != null) {
listeners.Add("dragFromEditorExit");
}
if (onPointerDragFromEditorRelease != null) {
listeners.Add("dragFromEditorRelease");
}
properties.add(new EnumerableProperty<string>("listeners", listeners, ifEmpty: "<none>"));
properties.add(new EnumProperty<HitTestBehavior>("behavior", behavior));
}
}
public class UnityEditorRenderPointerListener : RenderProxyBoxWithHitTestBehavior {
public UnityEditorRenderPointerListener(
PointerDragFromEditorEnterEventListener onPointerDragFromEditorEnter = null,
PointerDragFromEditorHoverEventListener onPointerDragFromEditorHover = null,
PointerDragFromEditorExitEventListener onPointerDragFromEditorExit = null,
PointerDragFromEditorReleaseEventListener onPointerDragFromEditorRelease = null,
HitTestBehavior behavior = HitTestBehavior.deferToChild,
RenderBox child = null
) : base(behavior: behavior, child: child) {
_onPointerDragFromEditorEnter = onPointerDragFromEditorEnter;
_onPointerDragFromEditorHover = onPointerDragFromEditorHover;
_onPointerDragFromEditorExit = onPointerDragFromEditorExit;
_onPointerDragFromEditorRelease = onPointerDragFromEditorRelease;
if (_onPointerDragFromEditorEnter != null ||
_onPointerDragFromEditorHover != null ||
_onPointerDragFromEditorExit != null ||
_onPointerDragFromEditorRelease != null
) {
_hoverAnnotation = new EditorMouseTrackerAnnotation(
onDragFromEditorEnter: _onPointerDragFromEditorEnter,
onDragFromEditorHover: _onPointerDragFromEditorHover,
onDragFromEditorExit: _onPointerDragFromEditorExit,
onDragFromEditorRelease: _onPointerDragFromEditorRelease
);
}
}
PointerDragFromEditorEnterEventListener _onPointerDragFromEditorEnter;
public PointerDragFromEditorEnterEventListener onPointerDragFromEditorEnter {
get { return _onPointerDragFromEditorEnter; }
set {
if (_onPointerDragFromEditorEnter != value) {
_onPointerDragFromEditorEnter = value;
_updateAnnotations();
}
}
}
PointerDragFromEditorExitEventListener _onPointerDragFromEditorExit;
public PointerDragFromEditorExitEventListener onPointerDragFromEditorExit {
get { return _onPointerDragFromEditorExit; }
set {
if (_onPointerDragFromEditorExit != value) {
_onPointerDragFromEditorExit = value;
_updateAnnotations();
}
}
}
PointerDragFromEditorHoverEventListener _onPointerDragFromEditorHover;
public PointerDragFromEditorHoverEventListener onPointerDragFromEditorHover {
get { return _onPointerDragFromEditorHover; }
set {
if (_onPointerDragFromEditorHover != value) {
_onPointerDragFromEditorHover = value;
_updateAnnotations();
}
}
}
PointerDragFromEditorReleaseEventListener _onPointerDragFromEditorRelease;
public PointerDragFromEditorReleaseEventListener onPointerDragFromEditorRelease {
get { return _onPointerDragFromEditorRelease; }
set {
if (_onPointerDragFromEditorRelease != value) {
_onPointerDragFromEditorRelease = value;
_updateAnnotations();
}
}
}
EditorMouseTrackerAnnotation _hoverAnnotation;
public EditorMouseTrackerAnnotation hoverAnnotation {
get { return _hoverAnnotation; }
}
void _updateAnnotations() {
D.assert(_onPointerDragFromEditorEnter != _hoverAnnotation.onDragFromEditorEnter
|| _onPointerDragFromEditorHover != _hoverAnnotation.onDragFromEditorHover
|| _onPointerDragFromEditorExit != _hoverAnnotation.onDragFromEditorExit
|| _onPointerDragFromEditorRelease != _hoverAnnotation.onDragFromEditorRelease
, () => "Shouldn't call _updateAnnotations if nothing has changed.");
if (_hoverAnnotation != null && attached) {
UiWidgetsEditorBinding.instance.editorMouseTracker.detachDragFromEditorAnnotation(_hoverAnnotation);
}
if (_onPointerDragFromEditorEnter != null
|| _onPointerDragFromEditorHover != null
|| _onPointerDragFromEditorExit != null
|| _onPointerDragFromEditorRelease != null
) {
_hoverAnnotation = new EditorMouseTrackerAnnotation(
onDragFromEditorEnter: _onPointerDragFromEditorEnter
, onDragFromEditorHover: _onPointerDragFromEditorHover
, onDragFromEditorExit: _onPointerDragFromEditorExit
, onDragFromEditorRelease: _onPointerDragFromEditorRelease
);
if (attached) {
UiWidgetsEditorBinding.instance.editorMouseTracker.attachDragFromEditorAnnotation(_hoverAnnotation);
}
}
else {
_hoverAnnotation = null;
}
markNeedsPaint();
}
public override void attach(object owner) {
base.attach(owner);
if (_hoverAnnotation != null) {
UiWidgetsEditorBinding.instance.editorMouseTracker.attachDragFromEditorAnnotation(_hoverAnnotation);
}
}
public override void detach() {
base.detach();
if (_hoverAnnotation != null) {
UiWidgetsEditorBinding.instance.editorMouseTracker.detachDragFromEditorAnnotation(_hoverAnnotation);
}
}
public override void paint(PaintingContext context, Offset offset) {
if (_hoverAnnotation != null) {
AnnotatedRegionLayer<EditorMouseTrackerAnnotation> layer = new AnnotatedRegionLayer<EditorMouseTrackerAnnotation>(
_hoverAnnotation, size: size, offset: offset);
context.pushLayer(layer, base.paint, offset);
}
else {
base.paint(context, offset);
}
}
protected override void performResize() {
size = constraints.biggest;
}
}
}

3
com.unity.uiwidgets/Editor/widgets/unity_editor_listener.cs.meta


fileFormatVersion: 2
guid: ce9c6d444c634f238d062461e1b513b7
timeCreated: 1637724477

121
com.unity.uiwidgets/Editor/widgets/unity_object_detector.cs


using Unity.UIWidgets.foundation;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
using UnityEditor;
using UnityEngine;
namespace Unity.UIWidgets.gestures
{
public delegate void DragInEditorEnterCallback(DragFromEditorDetails details);
public delegate void DragInEditorHoverCallback(DragFromHoverEditorDetails details);
public delegate void DragInEditorExitCallback();
public delegate void DragInEditorReleaseCallback(DragFromEditorDetails details);
public class DragFromEditorDetails {
public DragFromEditorDetails(Object[] objectReferences, string[] paths, Offset position) {
this.objectReferences = objectReferences;
this.paths = paths;
this.position = position;
}
public readonly Object[] objectReferences;
public readonly string[] paths;
public readonly Offset position;
}
public class DragFromHoverEditorDetails {
public DragFromHoverEditorDetails( Offset position) {
this.position = position;
}
public readonly Offset position;
}
public class UnityObjectDetector : StatefulWidget {
public UnityObjectDetector(
Key key = null,
Widget child = null,
DragInEditorEnterCallback onEnter = null,
DragInEditorHoverCallback onHover = null,
DragInEditorExitCallback onExit = null,
DragInEditorReleaseCallback onRelease = null,
HitTestBehavior? behavior = null
) : base(key: key) {
this.child = child;
onDragInEditorEnter = onEnter;
onDragInEditorHover = onHover;
onDragInEditorExit = onExit;
onDragInEditorRelease = onRelease;
this.behavior = behavior;
}
public readonly Widget child;
public readonly DragInEditorEnterCallback onDragInEditorEnter;
public readonly DragInEditorHoverCallback onDragInEditorHover;
public readonly DragInEditorExitCallback onDragInEditorExit;
public readonly DragInEditorReleaseCallback onDragInEditorRelease;
public readonly HitTestBehavior? behavior;
public override State createState() {
return new UnityObjectDetectorState();
}
}
public class UnityObjectDetectorState : State<UnityObjectDetector> {
HitTestBehavior _defaultBehavior {
get { return widget.child == null ? HitTestBehavior.translucent : HitTestBehavior.deferToChild; }
}
private bool isActivated = false;
private Object[] objectReferences;
private string[] paths;
private Offset position;
private bool isUnityObjectDragging()
{
var dragObjects = DragAndDrop.objectReferences;
var dragPaths = DragAndDrop.paths;
if (dragObjects != null && dragObjects.Length == 1 ||
dragPaths != null && dragPaths.Length == 1)
{
return true;
}
return false;
}
public override Widget build(BuildContext context)
{
Widget result = new UnityEditorListener(
child: widget.child,
onPointerDragFromEditorEnter: widget.onDragInEditorEnter == null
? ((PointerDragFromEditorEnterEventListener) null)
: evt => { widget.onDragInEditorEnter.Invoke(new DragFromEditorDetails(evt.objectReferences, evt.paths, evt.position)); },
onPointerDragFromEditorHover: widget.onDragInEditorHover == null
? ((PointerDragFromEditorHoverEventListener) null)
: evt => {
widget.onDragInEditorHover.Invoke(new DragFromHoverEditorDetails(evt.position));
},
onPointerDragFromEditorExit: widget.onDragInEditorExit == null
? ((PointerDragFromEditorExitEventListener) null)
: evt => { widget.onDragInEditorExit.Invoke(); },
onPointerDragFromEditorRelease: widget.onDragInEditorRelease == null
? ((PointerDragFromEditorReleaseEventListener) null)
: evt => {
widget.onDragInEditorRelease.Invoke(new DragFromEditorDetails(evt.objectReferences, evt.paths, evt.position));
},
behavior: widget.behavior ?? _defaultBehavior
);
return result;
}
}
}

3
com.unity.uiwidgets/Editor/widgets/unity_object_detector.cs.meta


fileFormatVersion: 2
guid: 1e9774220f644e23992deb96ca656908
timeCreated: 1637723510
正在加载...
取消
保存