diff --git a/CHANGELOG.md b/CHANGELOG.md index 41e226df..7f40ddd3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,3 +9,20 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### This is the first release of *Unity Package UIWidgets*. *just the first release* + + +## [1.5.4-release] - 2019-08-30 + +#### In this release we mainly focus on the optimization and stabilization of the framework. +#### We also upgrade UIWidgets to version 1.5.4, mainly derived from flutter 1.5.4. + +### New Features +- Optimize the GC performance of the rendering system [\#247](https://github.com/UnityTech/UIWidgets/pull/247) +- Optimize the rendering performance of shadows [\#257](https://github.com/UnityTech/UIWidgets/pull/257) +- Leverage Compute Buffer to optimize GPU-CPU communication [\#272](https://github.com/UnityTech/UIWidgets/pull/272) +- Cupertino Theme Supported [\#287](https://github.com/UnityTech/UIWidgets/pull/287) +- Support Unity Editor Drag&Drop mouse event [\#253](https://github.com/UnityTech/UIWidgets/pull/253) +- Implement geometric shapes anti-alias draw [\#262](https://github.com/UnityTech/UIWidgets/pull/262) +- Optimize paragraph layout [\#254](https://github.com/UnityTech/UIWidgets/pull/254) +- Support emoji display and edit [\#231](https://github.com/UnityTech/UIWidgets/pull/231) + diff --git a/Documentation~/CONTRIBUTING.md b/Documentation~/CONTRIBUTING.md new file mode 100644 index 00000000..cf9235f8 --- /dev/null +++ b/Documentation~/CONTRIBUTING.md @@ -0,0 +1,37 @@ +This repository exists for the sole purpose of publishing to package manager. Please contribute to https://github.com/UnityTech/UIWidgets instead. + +# Contributing + +## If you are interested in contributing, here are some ground rules: + +### Code Style (using JetBrains Rider) +1. **Import the Customized Code Cleanup Settings**: Open Preferences -> Manage Layers, +Choose 'Solution "\" personal' and Click "Add Layer" ("+") -> "Open Settings File...". +and Open the file "UIWidgetCleanupPlugin.DotSettings" under \/Packages/com.unity.uiwidgets/" + +2. **Cleanup Code style using the Customized Code Cleanup Settings**: Open Code -> Code Cleanup, +Pick a Cleanup scope as you want and Choose "UIWidgets" as the "Code cleanup profile", then click "OK" + +3. **Refine Code Style Rules**: Edit the ".editorconfig" file under \/Packages/com.unity.uiwidgets/". Visit + https://www.jetbrains.com/help/rider/EditorConfig_Index.html for the detailed. + +### Generate Code. + +Code files ending with ".gen.cs" are auto generated. Follow these steps to generate them: + +1. **Go to scripts Folder and Run npm install**: +``` +cd /Packages/com.unity.uiwidgets/scripts~ +npm install +``` + +2. **Run the codegen Command**: +``` +node uiwidgets-cli.js codegen . generate mixin code +``` + + +## All contributions are subject to the [Unity Contribution Agreement(UCA)](https://unity3d.com/legal/licenses/Unity_Contribution_Agreement) +By making a pull request, you are confirming agreement to the terms and conditions of the UCA, including that your Contributions are your original creation and that you have complete right and authority to make your Contributions. + +## Once you have a change ready following these ground rules. Simply make a pull request diff --git a/Documentation~/TableOfContents.md b/Documentation~/TableOfContents.md new file mode 100644 index 00000000..c1525550 --- /dev/null +++ b/Documentation~/TableOfContents.md @@ -0,0 +1,2 @@ +* [UIWidgets Documentation](index) +* [UIWidgets中文文档](index-zh) diff --git a/Documentation~/com.unity.uiwidgets.md b/Documentation~/com.unity.uiwidgets.md new file mode 100644 index 00000000..f74b8fcb --- /dev/null +++ b/Documentation~/com.unity.uiwidgets.md @@ -0,0 +1,356 @@ +# UIWidgets + + +## Introduction + +UIWidgets is a plugin package for Unity Editor which helps developers to create, debug and deploy efficient, +cross-platform Apps using the Unity Engine. + +UIWidgets is mainly derived from [Flutter](https://github.com/flutter/flutter). However, taking advantage of +the powerful Unity Engine, it offers developers many new features to improve their Apps +as well as the develop workflow significantly. + +#### Efficiency +Using the latest Unity rendering SDKs, a UIWidgets App can run very fast and keep >60fps in most times. + + +#### Cross-Platform +A UIWidgets App can be deployed on all kinds of platforms including PCs, mobile devices and web page directly, like +any other Unity projects. + +#### Multimedia Support +Except for basic 2D UIs, developers are also able to include 3D Models, audios, particle-systems to their UIWidgets Apps. + + +#### Developer-Friendly +A UIWidgets App can be debug in the Unity Editor directly with many advanced tools like +CPU/GPU Profiling, FPS Profiling. + + +## Example + +
+ + + + +
+ + + + + + + +
+ +### Projects using UIWidgets + +#### Unity Connect App +The Unity Connect App is created using UIWidgets and available for both Android (https://connect.unity.com/connectApp/download) +and iOS (Searching for "Unity Connect" in App Store). This project is open-sourced @https://github.com/UnityTech/ConnectAppCN. + +#### Unity Chinese Doc +The official website of Unity Chinese Documentation (https://connect.unity.com/doc) is powered by UIWidgets and +open-sourced @https://github.com/UnityTech/DocCN. + +## Requirements + +#### Unity + +Install **Unity 2018.4.10f1 (LTS)** or **Unity 2019.1.14f1** and above. You can download the latest Unity on https://unity3d.com/get-unity/download. + +#### UIWidgets Package +Visit our Github repository https://github.com/UnityTech/UIWidgets + to download the latest UIWidgets package. + +Move the downloaded package folder into the **Package** folder of your Unity project. + +Generally, you can make it using a console (or terminal) application by just a few commands as below: + + ```none + cd /Packages + git clone https://github.com/UnityTech/UIWidgets.git com.unity.uiwidgets + ``` + +## Getting Start + +#### i. Overview +In this tutorial, we will create a very simple UIWidgets App as the kick-starter. The app contains +only a text label and a button. The text label will count the times of clicks upon the button. + +First of all, please open or create a Unity Project and open it with Unity Editor. + +And then open Project Settings, go to Player section and **add "UIWidgets_DEBUG" to the Scripting Define Symbols field.** +This enables the debug mode of UIWidgets for your development. Remove this for your release build afterwards. + +#### ii. Scene Build +A UIWidgets App is usually built upon a Unity UI Canvas. Please follow the steps to create a +UI Canvas in Unity. +1. Create a new Scene by "File -> New Scene"; +1. Create a UI Canvas in the scene by "GameObject -> UI -> Canvas"; +1. Add a Panel (i.e., **Panel 1**) to the UI Canvas by right click on the Canvas and select "UI -> Panel". Then remove the +**Image** Component from the Panel. + +#### iii. Create Widget +A UIWidgets App is written in **C# Scripts**. Please follow the steps to create an App and play it +in Unity Editor. + +1. Create a new C# Script named "UIWidgetsExample.cs" and paste the following codes into it. + ```csharp + using System.Collections.Generic; + using Unity.UIWidgets.animation; + using Unity.UIWidgets.engine; + using Unity.UIWidgets.foundation; + using Unity.UIWidgets.material; + using Unity.UIWidgets.painting; + using Unity.UIWidgets.ui; + using Unity.UIWidgets.widgets; + using UnityEngine; + using FontStyle = Unity.UIWidgets.ui.FontStyle; + + namespace UIWidgetsSample { + public class UIWidgetsExample : UIWidgetsPanel { + protected override void OnEnable() { + // if you want to use your own font or font icons. + // FontManager.instance.addFont(Resources.Load(path: "path to your font"), "font family name"); + + // load custom font with weight & style. The font weight & style corresponds to fontWeight, fontStyle of + // a TextStyle object + // FontManager.instance.addFont(Resources.Load(path: "path to your font"), "Roboto", FontWeight.w500, + // FontStyle.italic); + + // add material icons, familyName must be "Material Icons" + // FontManager.instance.addFont(Resources.Load(path: "path to material icons"), "Material Icons"); + + base.OnEnable(); + } + + protected override Widget createWidget() { + return new WidgetsApp( + home: new ExampleApp(), + pageRouteBuilder: (RouteSettings settings, WidgetBuilder builder) => + new PageRouteBuilder( + settings: settings, + pageBuilder: (BuildContext context, Animation animation, + Animation secondaryAnimation) => builder(context) + ) + ); + } + + class ExampleApp : StatefulWidget { + public ExampleApp(Key key = null) : base(key) { + } + + public override State createState() { + return new ExampleState(); + } + } + + class ExampleState : State { + int counter = 0; + + public override Widget build(BuildContext context) { + return new Column( + children: new List { + new Text("Counter: " + this.counter), + new GestureDetector( + onTap: () => { + this.setState(() + => { + this.counter++; + }); + }, + child: new Container( + padding: EdgeInsets.symmetric(20, 20), + color: Colors.blue, + child: new Text("Click Me") + ) + ) + } + ); + } + } + } + } + ``` + +1. Save this script and attach it to **Panel 1** as its component. +1. Press the "Play" Button to start the App in Unity Editor. + +#### iv. Build App +Finally, the UIWidgets App can be built to packages for any specific platform by the following steps. +1. Open the Build Settings Panel by "File -> Build Settings..." +1. Choose a target platform and click "Build". Then the Unity Editor will automatically assemble +all relevant resources and generate the final App package. + +#### How to load images? +1. Put your images files in Resources folder. e.g. image1.png. +2. You can add image1@2.png and image1@3.png in the same folder to support HD screens. +3. Use Image.asset("image1") to load the image. Note: as in Unity, ".png" is not needed. + +UIWidgets supports Gif as well! +1. Suppose you have loading1.gif. Rename it to loading1.gif.bytes and copy it to Resources folder. +2. You can add loading1@2.gif.bytes and loading1@3.gif.bytes in the same folder to support HD screens. +3. Use Image.asset("loading1.gif") to load the gif images. + +#### Using Window Scope +If you see the error `AssertionError: Window.instance is null` or null pointer error of `Window.instance`, +it means the code is not running in the window scope. In this case, you can enclose your code +with window scope as below: +```csharp +using(WindowProvider.of(your gameObject with UIWidgetsPanel).getScope()) { + // code dealing with UIWidgets, + // e.g. setState(() => {....}) +} +``` + +This is needed if the code is in methods +not invoked by UIWidgets. For example, if the code is in `completed` callback of `UnityWebRequest`, +you need to enclose them with window scope. +Please see [HttpRequestSample](./Samples/UIWidgetSample/HttpRequestSample.cs) for detail. +For callback/event handler methods from UIWidgets (e.g `Widget.build, State.initState...`), you don't need do +it yourself, since the framework ensure it's in window scope. + +#### Show Status Bar on Android +Status bar is always hidden by default when an Unity project is running on an Android device. If you + want to show the status bar in your App, this + [solution](https://github.com/Over17/UnityShowAndroidStatusBar) seems to be + compatible to UIWidgets, therefore can be used as a good option before we release our + full support solution on this issue. + + Besides, + please set "Render Outside Safe Area" to true in the "Player Settings" to make this plugin working properly on Android P or later. + + + + +#### Automatically Adjust Frame Rate + +To build an App that is able to adjust the frame rate automatically, please open Project Settings, and in the Quality tab, set the "V Sync Count" option of the target platform to "Don't Sync". +The default logic is to reduce the frame rate when the screen is static, and change it back to 60 whenever the screen changes. +If you would like to disable this behavior, please set `Window.onFrameRateSpeedUp` and `Window.onFrameRateCoolDown` to null function, i.e., () => {}. + +Note that in Unity 2019.3 and above, UIWidgets will use OnDemandRenderAPI to implement this feature, which will greatly save the battery. + +#### WebGL Canvas Device Pixel Ratio Plugin +The width and height of the Canvas in browser may differ from the number of pixels the Canvas occupies on the screen. +Therefore, the image may blur in the builded WebGL program. +The Plugin `Plugins/platform/webgl/UIWidgetsCanvasDevicePixelRatio_20xx.x.jslib` (2018.3 and 2019.1 for now) solves this issue. +Please select the plugin of the Unity version corresponding to your project, and disable other versions of this plugin, as follows: select this plugin in the **Project** panel, and uncheck **WebGL** under **Select platforms for plugin** in the **Inspector** panel. +If you need to disable this plugin for any reason, please disable all the versions of this plugin as described above. + +This plugin overrides the following parameters in the Unity WebGL building module: +```none +JS_SystemInfo_GetWidth +JS_SystemInfo_GetHeight +JS_SystemInfo_GetCurrentCanvasWidth +JS_SystemInfo_GetCurrentCanvasHeight +$Browser +$JSEvents +``` +If you would like to implement your own WebGL plugin, and your plugin overrides at least one of the above parameters, you need to disable the `UIWidgetsCanvasDevicePixelRatio` plugin in the above mentioned way to avoid possible conflicts. +If you still need the function provided by this plugin, you can mannually apply the modification to Unity WebGL building module introduced in this plugin. +All the modifications introduced in `UIWidgetsCanvasDevicePixelRatio` are marked by `////////// Modifcation Start ////////////` and `////////// Modifcation End ////////////`. +In the marked codes, all the multiplications and divisions with `devicePixelRatio` are introduced by our modification. +To learn about the original script in detail, please refer to `SystemInfo.js` and `UnityNativeJS/UnityNative.js` in `PlaybackEngines/WebGLSupport/BuildTools/lib` in your Unity Editor installation. + +#### Image Import Setting +Unity, by default, resizes the width and height of an imported image to the nearest integer that is a power of 2. +In UIWidgets, you should almost always disable this by selecting the image in the "Project" panel, then in the "Inspector" panel set the "Non Power of 2" option (in "Advanced") to "None", to prevent your image from being resized unexpectedly. + +#### Update Emoji +UIWidgets supports rendering emoji in (editable) texts. +The default emoji resource version is [iOS 13.2](https://emojipedia.org/apple/ios-13.2). +We also prepared the resources of [Google Emoji](https://emojipedia.org/google). +To switch to Google version of emoji, please follow the following steps: + +1. Copy `Runtime/Resources/backup~/EmojiGoogle.png` to `Runtime/Resources/images` folder. +2. In the **Project** panel, find and select `EmojiGoogle` asset, and in the **Inspector** panel, change **Max Size** to 4096, and disable **Generate Mipmaps**. +3. In the `OnEnable()` function in your class overriding `UIWidgetsPanel`, add the following code + +```csharp +EmojiUtils.configuration = EmojiUtils.googleEmojiConfiguration; +``` + +If you would like to use your own images for emoji, please follow the following steps: + +1. Create the sprite sheet (take `EmojiGoogle.png` as an example), and put in a `Resources` folder in your project, (for example `Resources/myImages/MyEmoji.png`). +2. In the `OnEnable()` function, add the following code (replace example values with actual value). Note that the order of emoji codes should be consistent with the sprite sheet. + +```csharp +EmojiUtils.configuration = new EmojiResourceConfiguration( + spriteSheetAssetName: "myImage/MyEmoji", + emojiCodes: new List { + 0x1f004, 0x1f0cf, 0x1f170, ... + }, + spriteSheetNumberOfRows: 36, + spriteSheetNumberOfColumns: 37, +); +``` + +#### Interact with GameObject Drag&Drops + +

+ +

+ +With the provided packaged stateful widget `UnityObjectDetector` and its `onRelease` callback function, you can easily drag some objects (for example GameObject from Hierarchy, files from Project Window, etc) into the area, get the UnityEngine.Object[] references and make further modification. + + +## Debug UIWidgets Application + +#### Define UIWidgets_DEBUG +It's recommended to define the **UIWidgets_DEBUG** script symbol in editor, this will turn on +debug assertion in UIWidgets, which will help to find potential bugs earlier. To do this: +please go to **Player Settings -> Other Settings -> Configuration -> Scripting Define Symbols**, +and add **UIWidgets_DEBUG**. +The symbol is for debug purpose, please remove it from your release build. + +#### UIWidgets Inspector +The UIWidgets Inspector tool is for visualizing and exploring the widget trees. You can find it +via *Window/Analysis/UIWidgets* inspector in Editor menu. + +**Note** +* **UIWidgets_DEBUG** needs to be define for inspector to work properly. +* Inspector currently only works in Editor Play Mode, inspect standalone built application is not supported for now. + +## Learn + +#### Samples +You can find many UIWidgets sample projects on Github, which cover different aspects and provide you +learning materials in various levels: +* UIWidgetsSamples (https://github.com/UIWidgets/UIWidgetsSamples). These samples are developed by the dev team in order to illustrates all the features of +UIWidgets. First clone this Repo to the **Assets** folder of your local UIWidgets project. Then +you can find all the sample scenes under the **Scene** folder. +You can also try UIWidgets-based Editor windows by clicking the new **UIWidgetsTests** tab on the main menu +and open one of the dropdown samples. +* awesome-UIWidgets by Liangxie (https://github.com/liangxiegame/awesome-uiwidgets). This Repo contains +lots of UIWidget demo apps and third-party applications. +* ConnectApp (https://github.com/UnityTech/ConnectAppCN). This is an online, open-source UIWidget-based App developed +by the dev team. If you are making your own App with UIWidgets, this project will provides you with +many best practice cases. + + +#### Wiki +The develop team is still working on the UIWidgets Wiki. However, since UIWidgets is mainly derived from Flutter, + you can refer to Flutter Wiki to access detailed descriptions of UIWidgets APIs + from those of their Flutter counterparts. +Meanwhile, you can join the discussion channel at (https://connect.unity.com/g/uiwidgets) + +#### 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)** | + +## How to Contribute + +Check [CONTRIBUTING](CONTRIBUTING) diff --git a/Documentation~/images/example.png b/Documentation~/images/example.png deleted file mode 100644 index 216328df..00000000 Binary files a/Documentation~/images/example.png and /dev/null differ diff --git a/Documentation~/index-zh.md b/Documentation~/index-zh.md new file mode 100644 index 00000000..aa31ff20 --- /dev/null +++ b/Documentation~/index-zh.md @@ -0,0 +1,315 @@ +# UIWidgets + + +## 介绍 + +UIWidgets是Unity编辑器的一个插件包,可帮助开发人员通过Unity引擎来创建、调试和部署高效的跨平台应用。 + +UIWidgets主要来自[Flutter](https://github.com/flutter/flutter)。但UIWidgets通过使用强大的Unity引擎为开发人员提供了许多新功能,显著地改进他们开发的应用性能和工作流程。 + +#### 效率 +通过使用最新的Unity渲染SDK,UIWidgets应用可以非常快速地运行并且大多数时间保持大于60fps的速度。 + +#### 跨平台 +与任何其他Unity项目一样,UIWidgets应用可以直接部署在各种平台上,包括PC,移动设备和网页等。 + +#### 多媒体支持 +除了基本的2D UI之外,开发人员还能够将3D模型,音频,粒子系统添加到UIWidgets应用中。 + +#### 开发者友好 +开发者可以使用许多高级工具,如CPU/GPU Profiling和FPS Profiling,直接在Unity Editor中调试UIWidgets应用。 + +## 示例 + +
+ + + + +
+ + + + + + + +
+ +### 基于UIWidgets的项目 + +#### Unity Connect App +Unity Connect App是使用UIWidgets开发的一个移动App产品,您随时可以在Android (https://connect.unity.com/connectApp/download) +以及iOS (Searching for "Unity Connect" in App Store)端下载到它最新的版本. 本项目的所有代码均开源@https://github.com/UnityTech/ConnectAppCN. + +#### Unity中文官方文档 +Unity的线上中文官方文档由UIWidgets开发,您可以点击以下网址 https://connect.unity.com/doc 来访问它的全部内容。该项目目前已开源,所有代码可以在 +https://github.com/UnityTech/DocCN 查看。 + +## 使用要求 + +#### Unity + +安装 **Unity 2018.4.10f1(LTS)** 或 **Unity 2019.1.14f1** 及其更高版本。 你可以从[https://unity3d.com/get-unity/download](https://unity3d.com/get-unity/download)下载最新的Unity。 + +#### UIWidgets包 + +访问我们的Github存储库 [https://github.com/UnityTech/UIWidgets](https://github.com/UnityTech/UIWidgets)下载最新的UIWidgets包。 + +将下载的包文件夹移动到Unity项目的Package文件夹中。 + +通常,你可以在控制台(或终端)应用程序中输入下面的代码来完成这个操作: + + ```none + cd /Packages + git clone https://github.com/UnityTech/UIWidgets.git com.unity.uiwidgets + ``` + +## 入门指南 + +#### 一、 概观 +在本教程中,我们将创建一个非常简单的UIWidgets应用。 该应用只包含文本标签和按钮。 文本标签将计算按钮上的点击次数。 + +首先,请打开或创建Unity项目并使用Unity编辑器打开它。 + +然后打开Project Settings,转到Player部分并**将“UIWidgets_DEBUG”添加到Scripting Define Symbols字段中。** + +这样就启动了UIWidgets的调试模式。 在之后发布版本的时候清空这个字段。 + +#### 二、 场景构建 + +UIWidgets应用通常构建在Unity UI Canvas上。 请按照以下步骤在Unity中创建一个 +UI Canvas。 +1. 选择 File > New Scene来创建一个新场景。 +2. 选择 GameObject > UI > Canvas 在场景中创建UI Canvas。 +3. 右键单击Canvas并选择UI > Panel,将面板(即面板1)添加到UI Canvas中。 然后删除面板中的 **Image** 组件。 + +#### 三、创建小部件 + +UIWidgets应用是用**C#脚本**来编写的。 请按照以下步骤创建应用程序并在Unity编辑器中播放。 +1. 创建一个新C#脚本,命名为“UIWidgetsExample.cs”,并将以下代码粘贴到其中。 + +```csharp + using System.Collections.Generic; + using Unity.UIWidgets.animation; + using Unity.UIWidgets.engine; + using Unity.UIWidgets.foundation; + using Unity.UIWidgets.material; + using Unity.UIWidgets.painting; + using Unity.UIWidgets.ui; + using Unity.UIWidgets.widgets; + using UnityEngine; + using FontStyle = Unity.UIWidgets.ui.FontStyle; + + namespace UIWidgetsSample { + public class UIWidgetsExample : UIWidgetsPanel { + protected override void OnEnable() { + // if you want to use your own font or font icons. + // FontManager.instance.addFont(Resources.Load(path: "path to your font"), "font family name"); + + // load custom font with weight & style. The font weight & style corresponds to fontWeight, fontStyle of + // a TextStyle object + // FontManager.instance.addFont(Resources.Load(path: "path to your font"), "Roboto", FontWeight.w500, + // FontStyle.italic); + + // add material icons, familyName must be "Material Icons" + // FontManager.instance.addFont(Resources.Load(path: "path to material icons"), "Material Icons"); + + base.OnEnable(); + } + + protected override Widget createWidget() { + return new WidgetsApp( + home: new ExampleApp(), + pageRouteBuilder: (RouteSettings settings, WidgetBuilder builder) => + new PageRouteBuilder( + settings: settings, + pageBuilder: (BuildContext context, Animation animation, + Animation secondaryAnimation) => builder(context) + ) + ); + } + + class ExampleApp : StatefulWidget { + public ExampleApp(Key key = null) : base(key) { + } + + public override State createState() { + return new ExampleState(); + } + } + + class ExampleState : State { + int counter = 0; + + public override Widget build(BuildContext context) { + return new Column( + children: new List { + new Text("Counter: " + this.counter), + new GestureDetector( + onTap: () => { + this.setState(() => { + this.counter++; + }); + }, + child: new Container( + padding: EdgeInsets.symmetric(20, 20), + color: Colors.blue, + child: new Text("Click Me") + ) + ) + } + ); + } + } + } + } +``` + +2. 保存此脚本,并将其附加到Panel 1中作为其组件。 +3. 在Unity编辑器中,点击Play按钮来启动应用。 + +#### 四、构建应用程序 + +最后,你可以按以下步骤将UIWidgets应用构建成适用于任何特定平台的应用程序包。 +1. 选择**File** > **Build Settings...**打开Build Settings面板。 +2. 选择目标平台,点击Build。 之后Unity编辑器将自动组装所有相关资源并生成最终的应用程序包。 + +#### 五、如何加载图像? +1. 将你的图像文件,如image1.png,放在Resources文件夹中。 +2. 你可以在同一文件夹中添加image1@2.png和image1@3.png以支持高清屏幕显示。 +3. 使用Image.asset(“image1”)加载图像。 注意:因为是在Unity中,所以不需要添加.png后缀。 + + +UIWidgets也支持Gif! +1. 假设你有一个loading1.gif文件,将其重命名为loading1.gif.bytes并复制到Resources文件夹。 +2. 你可以在同一文件夹中添加loading1@2.gif.bytes和loading1@3.gif.bytes以支持高清屏幕显示。 +3. 使用Image.asset(“loading1.gif”)加载gif图像。 + +#### 六、在安卓上显示状态栏 +当一个Unity项目运行在Android设备上时,状态栏是默认隐藏且无法在编辑内进行调整的。 +如果您希望在您的UIWidgets App中显示状态栏,您可以使用这个[解决方案](https://github.com/Over17/UnityShowAndroidStatusBar)。我们将尽快推出我们自己的解决方案,并保证届时开发者可以进行无缝切换。 + +此外,为了让上述插件在Android P及以上Android系统中正常工作,请勾选上"Player Settings"中的"Render Outside Safe Area"选项。 + +#### 七、自动调节帧率 +如果要使得构建出的应用能够自动调节帧率,请打开Project Settings,将构建目标平台对应的Quality选项卡中的V Sync Count设置为Don't Sync。 +默认的逻辑是在界面静止时将帧率降低,在界面变动时再将帧率提高至60。 +如果您不想开启该功能,请将`Window.onFrameRateSpeedUp`和/或`Window.onFrameRateCoolDown`设置为空函数,()=> {}即可。 + +在Unity 2019.3版本及以上,UIWidgets将使用OnDemandRenderAPI来实现帧率调节,它将在不影响UI响应速度的情况下大幅降低耗电和发热问题。 + +#### 八、WebGL Canvas分辨率调整插件 +因为浏览器中Canvas的宽高和其在显示器上的像素数可能不一致,所以构建出的WebGL程序中画面可能会模糊。 +插件`Plugins/platform/webgl/UIWidgetsCanvasDevicePixelRatio_20xx.x.jslib`(目前有2018.3和2019.1)解决了这个问题。 +请根据您的项目的Unity版本选择对应的插件,并禁用此插件的其他版本。方法如下:在Project面板中选中该插件,在Inspector面板中的Select platforms for plugin中,去掉WebGL后面的对勾。 +如果您因为任何原因需要完全禁止此插件的功能,请按上述方法禁用此插件的所有版本。 + +此插件覆盖了Unity WebGL构建模块中的如下参数: +```none +JS_SystemInfo_GetWidth +JS_SystemInfo_GetHeight +JS_SystemInfo_GetCurrentCanvasWidth +JS_SystemInfo_GetCurrentCanvasHeight +$Browser +$JSEvents +``` +如果您需要实现自己的WebGL插件,并且您的插件覆盖了这些参数中的至少一种,您需要采用上文中提到的方法禁用`UIWidgetsCanvasDevicePixelRatio`插件,以防止可能的冲突。 +如果您仍然需要此插件所提供的功能,您可以手动将此插件对Unity WebGL构建模块的修改应用到您的插件中。 +`UIWidgetsCanvasDevicePixelRatio`插件中所有的修改之处都以`////////// Modification Start ////////////`和`////////// Modification End ////////////`标识。 +在被标识的代码中,所有乘/除以`devicePixelRatio`都来自于我们的修改。 +若您需要详细了解此插件所修改的脚本,请参考您的Unity Editor安装目录下的`PlaybackEngines/WebGLSupport/BuildTools/lib`文件夹中的`SystemInfo.js`和`UnityNativeJS/UnityNative.js`。 + +#### 九、图片导入设置 +默认情况下,Unity会将导入图片的宽和高放缩为最近的等于2的幂的整数。 +在UIWidgets中使用图片时,记得将这一特性关闭,以免图片被意外放缩,方法如下:在Project面板中选中图片,在"Inspector"面板中将"Non Power of 2"(在"Advanced"中)设置为"None"。 + +#### 十、更新表情(Emoji) +UIWidgets支持渲染文本中包含的表情。 +默认的表情资源为[iOS 13.2](https://emojipedia.org/apple/ios-13.2)。 +我们也准备了[Google Emoji](https://emojipedia.org/google)的表情资源。 +如果您希望切换到Google版本的表情,请按如下步骤操作: + +1. 拷贝`Runtime/Resources/backup~/EmojiGoogle.png`到`Runtime/Resources/images`目录。 +2. 在**Project**面板中,找到`EmojiGoogle`资源,在**Inspector**面板中,将**Max Size**更改为4096,并取消**Generate Mipmaps**选项前的对勾。 +3. 在您的代码中继承`UIWidgetsPanel`的类的`OnEnable()`函数中,添加如下代码 + +```csharp +EmojiUtils.configuration = EmojiUtils.googleEmojiConfiguration; +``` + +如果您希望使用自己的表情图片,请按如下步骤操作: + +1. 参照`EmojiGoogle.png`,创建您自己的Emoji表单,并放到工程目录下的某个`Resources`目录中,例如`Resources/myImages/MyEmoji.png`)。 +2. 在`OnEnable()`函数中,添加如下代码(记得将示例的值改为真实的值)。注意Emoji的编码的顺序要和Emoji表单一致。 + +```csharp +EmojiUtils.configuration = new EmojiResourceConfiguration( + spriteSheetAssetName: "myImage/MyEmoji", + emojiCodes: new List { + 0x1f004, 0x1f0cf, 0x1f170, ... + }, + spriteSheetNumberOfRows: 36, + spriteSheetNumberOfColumns: 37, +); +``` + +#### 十一、与GameObject进行拖拽交互 + +

+ +

+ +我们提供了一个包装好的`UnityObjectDetector`组件以及`onRelease`回调函数,借此您可以实现简单地将物体(例如Hierarchy内的场景物体、Project窗口下的文件等)拖拽至区域内,来获得`UnityEngine.Object[] `类型的引用并进行操作。 + + +## 调试UIWidgets应用程序 + +#### 定义UIWidgets_DEBUG +我们建议在Unity编辑器中定义 UIWidgets_DEBUG 脚本符号,这将打开UIWidgets中的调试断言(debug assertion),有助于更早发现潜在的Bug。 +因此选择 **Player Settings** > **Other Settings** > **Configuration** > **Scripting Define Symbols** ,并添加 UIWidgets_DEBUG。 +该符号仅供调试使用,请在发布版本中删除它。 + +#### UIWidgets Inspector + +UIWidgets Inspector工具用于可视化和浏览窗口小部件树。 你可以在Unity编辑器的**Window** > **Analysis** > **UIWidget Inspector** 中的找到它。 + +注意 +- 需要定义 UIWidgets_DEBUG 使inspector正常工作。 +- Inspector目前仅适用于编辑器的播放模式,目前不支持独立版本的应用程序。 + + +## 学习 + +#### 教程 + +包括开发组在内的广大开发者为UIWidgets提供了许多可供学习的样例和教程,你可以根据你的需求进行学习: +- UIWidgets官方示例。目前所有官方使用的示例项目均维护在一个独立的Github仓库( https://github.com/UIWidgets/UIWidgetsSamples )中。你可以 +将它clone到你项目本地的Assets目录下使用。 +具体的,你可以在Sample项目的**Scene**子文件夹中浏览所有示例UI场景。 +此外,你还可以点击主菜单上的新增的UIWidgetsTests选项卡,并在下拉菜单中选择一个EditorWindow UI示例来运行。 +- UIWidgets凉鞋系列教程。你可以在凉鞋老师整理的Github仓库( https://github.com/liangxiegame/awesome-uiwidgets )中学习UIWidgets的基本用法 +以及许多有趣的小Demo。 +- ConnectApp开源项目。这是一个完整的线上、开源、完全基于UIWidgets的第一方App项目。其中包含了大量产品级的UIWidgets工程实践细节, +如果你想深入了解UIWidgets并且使用它构建线上项目,请访问项目Github仓库了解更多( https://github.com/UnityTech/ConnectAppCN )。 + +#### Wiki + +目前开发团队仍在改进UIWidgets Wiki。 由于UIWidgets主要来源于Flutter,你也可以参考Flutter Wiki中与UIWidgets API对应部分的详细描述。 +同时,你可以加入我们的讨论组( https://connect.unity.com/g/uiwidgets )。 + +#### 常问问题解答 + +| 问题 | 回答 | +| :-----------------------------------------------| ---------------------: | +| 我可以使用UIWidgets创建独立应用吗? | 可以 | +| 我可以使用UIWidgets构建游戏UI吗? | 可以 | +| 我可以使用UIWidgets开发Unity编辑器插件吗? | 可以 | +| UIWidgets是UGUI / NGUI的扩展吗? | 不是 | +| UIWidgets只是Flutter的副本吗? | 不是 | +| 我可以通过简单的拖放操作来创建带有UIWidgets的UI吗? | 不可以 | +| 我是否需要付费使用UIWidgets? | 不需要 | +| 有推荐的适用于UIWidgets的IDE吗? | Rider, VSCode(Open .sln) | + +## 如何贡献 +请查看[CONTRIBUTING.md](CONTRIBUTING.md) diff --git a/Documentation~/index.md b/Documentation~/index.md new file mode 100644 index 00000000..f74b8fcb --- /dev/null +++ b/Documentation~/index.md @@ -0,0 +1,356 @@ +# UIWidgets + + +## Introduction + +UIWidgets is a plugin package for Unity Editor which helps developers to create, debug and deploy efficient, +cross-platform Apps using the Unity Engine. + +UIWidgets is mainly derived from [Flutter](https://github.com/flutter/flutter). However, taking advantage of +the powerful Unity Engine, it offers developers many new features to improve their Apps +as well as the develop workflow significantly. + +#### Efficiency +Using the latest Unity rendering SDKs, a UIWidgets App can run very fast and keep >60fps in most times. + + +#### Cross-Platform +A UIWidgets App can be deployed on all kinds of platforms including PCs, mobile devices and web page directly, like +any other Unity projects. + +#### Multimedia Support +Except for basic 2D UIs, developers are also able to include 3D Models, audios, particle-systems to their UIWidgets Apps. + + +#### Developer-Friendly +A UIWidgets App can be debug in the Unity Editor directly with many advanced tools like +CPU/GPU Profiling, FPS Profiling. + + +## Example + +
+ + + + +
+ + + + + + + +
+ +### Projects using UIWidgets + +#### Unity Connect App +The Unity Connect App is created using UIWidgets and available for both Android (https://connect.unity.com/connectApp/download) +and iOS (Searching for "Unity Connect" in App Store). This project is open-sourced @https://github.com/UnityTech/ConnectAppCN. + +#### Unity Chinese Doc +The official website of Unity Chinese Documentation (https://connect.unity.com/doc) is powered by UIWidgets and +open-sourced @https://github.com/UnityTech/DocCN. + +## Requirements + +#### Unity + +Install **Unity 2018.4.10f1 (LTS)** or **Unity 2019.1.14f1** and above. You can download the latest Unity on https://unity3d.com/get-unity/download. + +#### UIWidgets Package +Visit our Github repository https://github.com/UnityTech/UIWidgets + to download the latest UIWidgets package. + +Move the downloaded package folder into the **Package** folder of your Unity project. + +Generally, you can make it using a console (or terminal) application by just a few commands as below: + + ```none + cd /Packages + git clone https://github.com/UnityTech/UIWidgets.git com.unity.uiwidgets + ``` + +## Getting Start + +#### i. Overview +In this tutorial, we will create a very simple UIWidgets App as the kick-starter. The app contains +only a text label and a button. The text label will count the times of clicks upon the button. + +First of all, please open or create a Unity Project and open it with Unity Editor. + +And then open Project Settings, go to Player section and **add "UIWidgets_DEBUG" to the Scripting Define Symbols field.** +This enables the debug mode of UIWidgets for your development. Remove this for your release build afterwards. + +#### ii. Scene Build +A UIWidgets App is usually built upon a Unity UI Canvas. Please follow the steps to create a +UI Canvas in Unity. +1. Create a new Scene by "File -> New Scene"; +1. Create a UI Canvas in the scene by "GameObject -> UI -> Canvas"; +1. Add a Panel (i.e., **Panel 1**) to the UI Canvas by right click on the Canvas and select "UI -> Panel". Then remove the +**Image** Component from the Panel. + +#### iii. Create Widget +A UIWidgets App is written in **C# Scripts**. Please follow the steps to create an App and play it +in Unity Editor. + +1. Create a new C# Script named "UIWidgetsExample.cs" and paste the following codes into it. + ```csharp + using System.Collections.Generic; + using Unity.UIWidgets.animation; + using Unity.UIWidgets.engine; + using Unity.UIWidgets.foundation; + using Unity.UIWidgets.material; + using Unity.UIWidgets.painting; + using Unity.UIWidgets.ui; + using Unity.UIWidgets.widgets; + using UnityEngine; + using FontStyle = Unity.UIWidgets.ui.FontStyle; + + namespace UIWidgetsSample { + public class UIWidgetsExample : UIWidgetsPanel { + protected override void OnEnable() { + // if you want to use your own font or font icons. + // FontManager.instance.addFont(Resources.Load(path: "path to your font"), "font family name"); + + // load custom font with weight & style. The font weight & style corresponds to fontWeight, fontStyle of + // a TextStyle object + // FontManager.instance.addFont(Resources.Load(path: "path to your font"), "Roboto", FontWeight.w500, + // FontStyle.italic); + + // add material icons, familyName must be "Material Icons" + // FontManager.instance.addFont(Resources.Load(path: "path to material icons"), "Material Icons"); + + base.OnEnable(); + } + + protected override Widget createWidget() { + return new WidgetsApp( + home: new ExampleApp(), + pageRouteBuilder: (RouteSettings settings, WidgetBuilder builder) => + new PageRouteBuilder( + settings: settings, + pageBuilder: (BuildContext context, Animation animation, + Animation secondaryAnimation) => builder(context) + ) + ); + } + + class ExampleApp : StatefulWidget { + public ExampleApp(Key key = null) : base(key) { + } + + public override State createState() { + return new ExampleState(); + } + } + + class ExampleState : State { + int counter = 0; + + public override Widget build(BuildContext context) { + return new Column( + children: new List { + new Text("Counter: " + this.counter), + new GestureDetector( + onTap: () => { + this.setState(() + => { + this.counter++; + }); + }, + child: new Container( + padding: EdgeInsets.symmetric(20, 20), + color: Colors.blue, + child: new Text("Click Me") + ) + ) + } + ); + } + } + } + } + ``` + +1. Save this script and attach it to **Panel 1** as its component. +1. Press the "Play" Button to start the App in Unity Editor. + +#### iv. Build App +Finally, the UIWidgets App can be built to packages for any specific platform by the following steps. +1. Open the Build Settings Panel by "File -> Build Settings..." +1. Choose a target platform and click "Build". Then the Unity Editor will automatically assemble +all relevant resources and generate the final App package. + +#### How to load images? +1. Put your images files in Resources folder. e.g. image1.png. +2. You can add image1@2.png and image1@3.png in the same folder to support HD screens. +3. Use Image.asset("image1") to load the image. Note: as in Unity, ".png" is not needed. + +UIWidgets supports Gif as well! +1. Suppose you have loading1.gif. Rename it to loading1.gif.bytes and copy it to Resources folder. +2. You can add loading1@2.gif.bytes and loading1@3.gif.bytes in the same folder to support HD screens. +3. Use Image.asset("loading1.gif") to load the gif images. + +#### Using Window Scope +If you see the error `AssertionError: Window.instance is null` or null pointer error of `Window.instance`, +it means the code is not running in the window scope. In this case, you can enclose your code +with window scope as below: +```csharp +using(WindowProvider.of(your gameObject with UIWidgetsPanel).getScope()) { + // code dealing with UIWidgets, + // e.g. setState(() => {....}) +} +``` + +This is needed if the code is in methods +not invoked by UIWidgets. For example, if the code is in `completed` callback of `UnityWebRequest`, +you need to enclose them with window scope. +Please see [HttpRequestSample](./Samples/UIWidgetSample/HttpRequestSample.cs) for detail. +For callback/event handler methods from UIWidgets (e.g `Widget.build, State.initState...`), you don't need do +it yourself, since the framework ensure it's in window scope. + +#### Show Status Bar on Android +Status bar is always hidden by default when an Unity project is running on an Android device. If you + want to show the status bar in your App, this + [solution](https://github.com/Over17/UnityShowAndroidStatusBar) seems to be + compatible to UIWidgets, therefore can be used as a good option before we release our + full support solution on this issue. + + Besides, + please set "Render Outside Safe Area" to true in the "Player Settings" to make this plugin working properly on Android P or later. + + + + +#### Automatically Adjust Frame Rate + +To build an App that is able to adjust the frame rate automatically, please open Project Settings, and in the Quality tab, set the "V Sync Count" option of the target platform to "Don't Sync". +The default logic is to reduce the frame rate when the screen is static, and change it back to 60 whenever the screen changes. +If you would like to disable this behavior, please set `Window.onFrameRateSpeedUp` and `Window.onFrameRateCoolDown` to null function, i.e., () => {}. + +Note that in Unity 2019.3 and above, UIWidgets will use OnDemandRenderAPI to implement this feature, which will greatly save the battery. + +#### WebGL Canvas Device Pixel Ratio Plugin +The width and height of the Canvas in browser may differ from the number of pixels the Canvas occupies on the screen. +Therefore, the image may blur in the builded WebGL program. +The Plugin `Plugins/platform/webgl/UIWidgetsCanvasDevicePixelRatio_20xx.x.jslib` (2018.3 and 2019.1 for now) solves this issue. +Please select the plugin of the Unity version corresponding to your project, and disable other versions of this plugin, as follows: select this plugin in the **Project** panel, and uncheck **WebGL** under **Select platforms for plugin** in the **Inspector** panel. +If you need to disable this plugin for any reason, please disable all the versions of this plugin as described above. + +This plugin overrides the following parameters in the Unity WebGL building module: +```none +JS_SystemInfo_GetWidth +JS_SystemInfo_GetHeight +JS_SystemInfo_GetCurrentCanvasWidth +JS_SystemInfo_GetCurrentCanvasHeight +$Browser +$JSEvents +``` +If you would like to implement your own WebGL plugin, and your plugin overrides at least one of the above parameters, you need to disable the `UIWidgetsCanvasDevicePixelRatio` plugin in the above mentioned way to avoid possible conflicts. +If you still need the function provided by this plugin, you can mannually apply the modification to Unity WebGL building module introduced in this plugin. +All the modifications introduced in `UIWidgetsCanvasDevicePixelRatio` are marked by `////////// Modifcation Start ////////////` and `////////// Modifcation End ////////////`. +In the marked codes, all the multiplications and divisions with `devicePixelRatio` are introduced by our modification. +To learn about the original script in detail, please refer to `SystemInfo.js` and `UnityNativeJS/UnityNative.js` in `PlaybackEngines/WebGLSupport/BuildTools/lib` in your Unity Editor installation. + +#### Image Import Setting +Unity, by default, resizes the width and height of an imported image to the nearest integer that is a power of 2. +In UIWidgets, you should almost always disable this by selecting the image in the "Project" panel, then in the "Inspector" panel set the "Non Power of 2" option (in "Advanced") to "None", to prevent your image from being resized unexpectedly. + +#### Update Emoji +UIWidgets supports rendering emoji in (editable) texts. +The default emoji resource version is [iOS 13.2](https://emojipedia.org/apple/ios-13.2). +We also prepared the resources of [Google Emoji](https://emojipedia.org/google). +To switch to Google version of emoji, please follow the following steps: + +1. Copy `Runtime/Resources/backup~/EmojiGoogle.png` to `Runtime/Resources/images` folder. +2. In the **Project** panel, find and select `EmojiGoogle` asset, and in the **Inspector** panel, change **Max Size** to 4096, and disable **Generate Mipmaps**. +3. In the `OnEnable()` function in your class overriding `UIWidgetsPanel`, add the following code + +```csharp +EmojiUtils.configuration = EmojiUtils.googleEmojiConfiguration; +``` + +If you would like to use your own images for emoji, please follow the following steps: + +1. Create the sprite sheet (take `EmojiGoogle.png` as an example), and put in a `Resources` folder in your project, (for example `Resources/myImages/MyEmoji.png`). +2. In the `OnEnable()` function, add the following code (replace example values with actual value). Note that the order of emoji codes should be consistent with the sprite sheet. + +```csharp +EmojiUtils.configuration = new EmojiResourceConfiguration( + spriteSheetAssetName: "myImage/MyEmoji", + emojiCodes: new List { + 0x1f004, 0x1f0cf, 0x1f170, ... + }, + spriteSheetNumberOfRows: 36, + spriteSheetNumberOfColumns: 37, +); +``` + +#### Interact with GameObject Drag&Drops + +

+ +

+ +With the provided packaged stateful widget `UnityObjectDetector` and its `onRelease` callback function, you can easily drag some objects (for example GameObject from Hierarchy, files from Project Window, etc) into the area, get the UnityEngine.Object[] references and make further modification. + + +## Debug UIWidgets Application + +#### Define UIWidgets_DEBUG +It's recommended to define the **UIWidgets_DEBUG** script symbol in editor, this will turn on +debug assertion in UIWidgets, which will help to find potential bugs earlier. To do this: +please go to **Player Settings -> Other Settings -> Configuration -> Scripting Define Symbols**, +and add **UIWidgets_DEBUG**. +The symbol is for debug purpose, please remove it from your release build. + +#### UIWidgets Inspector +The UIWidgets Inspector tool is for visualizing and exploring the widget trees. You can find it +via *Window/Analysis/UIWidgets* inspector in Editor menu. + +**Note** +* **UIWidgets_DEBUG** needs to be define for inspector to work properly. +* Inspector currently only works in Editor Play Mode, inspect standalone built application is not supported for now. + +## Learn + +#### Samples +You can find many UIWidgets sample projects on Github, which cover different aspects and provide you +learning materials in various levels: +* UIWidgetsSamples (https://github.com/UIWidgets/UIWidgetsSamples). These samples are developed by the dev team in order to illustrates all the features of +UIWidgets. First clone this Repo to the **Assets** folder of your local UIWidgets project. Then +you can find all the sample scenes under the **Scene** folder. +You can also try UIWidgets-based Editor windows by clicking the new **UIWidgetsTests** tab on the main menu +and open one of the dropdown samples. +* awesome-UIWidgets by Liangxie (https://github.com/liangxiegame/awesome-uiwidgets). This Repo contains +lots of UIWidget demo apps and third-party applications. +* ConnectApp (https://github.com/UnityTech/ConnectAppCN). This is an online, open-source UIWidget-based App developed +by the dev team. If you are making your own App with UIWidgets, this project will provides you with +many best practice cases. + + +#### Wiki +The develop team is still working on the UIWidgets Wiki. However, since UIWidgets is mainly derived from Flutter, + you can refer to Flutter Wiki to access detailed descriptions of UIWidgets APIs + from those of their Flutter counterparts. +Meanwhile, you can join the discussion channel at (https://connect.unity.com/g/uiwidgets) + +#### 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)** | + +## How to Contribute + +Check [CONTRIBUTING](CONTRIBUTING) diff --git a/Documentation~/your-package-name.md b/Documentation~/your-package-name.md deleted file mode 100644 index b8a05415..00000000 --- a/Documentation~/your-package-name.md +++ /dev/null @@ -1,169 +0,0 @@ ->>> -**_Package Documentation Template_** - -Use this template to create preliminary, high-level documentation meant to introduce users to the feature and the sample files included in this package. When writing your documentation, do the following: - -1. Follow instructions in blockquotes. - -2. Replace angle brackets with the appropriate text. For example, replace "<package name>" with the official name of the package. - -3. Delete sections that do not apply to your package. For example, a package containing only sample files does not have a "Using <package_name>" section, so this section can be removed. - -4. After documentation is completed, make sure you delete all instructions and examples in blockquotes including this preamble and its title: - - ``` - >>> - Delete all of the text between pairs of blockquote markdown. - >>> - ``` ->>> - -# About <package name> - ->>> -Name the heading of the first topic after the **displayName** of the package as it appears in the package manifest. Check with your Product Manager to ensure that the package is named correctly. - -This first topic includes a brief, high-level explanation of the package and, if applicable, provides links to Unity Manual topics. - -There are two types of packages: - - - Packages that include features that augment the Unity Editor or Runtime. - - Packages that include sample files. - -Choose one of the following introductory paragraphs that best fits the package: ->>> - -Use the <package name> package to <list of the main uses for the package>. For example, use <package name> to create/generate/extend/capture <mention major use case, or a good example of what the package can be used for>. The <package name> package also includes <other relevant features or uses>. - -> *or* - -The <package name> package includes examples of <name of asset type, model, prefabs, and/or other GameObjects in the package>. For more information, see <xref to topic in the Unity Manual>. - ->>> -**_Examples:_** - -Here are some examples for reference only. Do not include these in the final documentation file: - -*Use the Unity Recorder package to capture and save in-game data. For example, use Unity Recorder to record an mp4 file during a game session. The Unity Recorder package also includes an interface for setting-up and triggering recording sessions.* - -*The Timeline Examples package includes examples of Timeline assets, Timeline Instances, animation, GameObjects, and scripts that illustrate how to use Unity's Timeline. For more information, see [ Unity's Timeline](https://docs.unity3d.com/Manual/TimelineSection.html) in the [Unity Manual](https://docs.unity3d.com). For licensing and usage, see Package Licensing.* ->>> - -# Installing <package name> ->>> -Begin this section with a cross-reference to the official Unity Manual topic on how to install packages. If the package requires special installation instructions, include these steps in this section. ->>> - -To install this package, follow the instructions in the [Package Manager documentation](https://docs.unity3d.com/Packages/com.unity.package-manager-ui@latest/index.html). - ->>> -For some packages, there may be additional steps to complete the setup. You can add those here. ->>> - -In addition, you need to install the following resources: - - - <name of resource>: To install, open *Window > <name of menu item>*. The resource appears <at this location>. - - <name of sample>: To install, open *Window > <name of menu item>*. The new sample folder appears <at this location>. - - - -# Using <package name> ->>> -The contents of this section depends on the type of package. - -For packages that augment the Unity Editor with additional features, this section should include workflow and/or reference documentation: - -* At a minimum, this section should include reference documentation that describes the windows, editors, and properties that the package adds to Unity. This reference documentation should include screen grabs (see how to add screens below), a list of settings, an explanation of what each setting does, and the default values of each setting. -* Ideally, this section should also include a workflow: a list of steps that the user can easily follow that demonstrates how to use the feature. This list of steps should include screen grabs (see how to add screens below) to better describe how to use the feature. - -For packages that include sample files, this section may include detailed information on how the user can use these sample files in their projects and scenes. However, workflow diagrams or illustrations could be included if deemed appropriate. - -## How to add images - -*(This section is for reference. Do not include in the final documentation file)* - -If the [Using <package name>](#UsingPackageName) section includes screen grabs or diagrams, a link to the image must be added to this MD file, before or after the paragraph with the instruction or description that references the image. In addition, a caption should be added to the image link that includes the name of the screen or diagram. All images must be PNG files with underscores for spaces. No animated GIFs. - -An example is included below: - -![A cinematic in the Timeline Editor window.](images/example.png) - -Notice that the example screen shot is included in the images folder. All screen grabs and/or diagrams must be added and referenced from the images folder. - -For more on the Unity documentation standards for creating and adding screen grabs, see this confluence page: https://confluence.hq.unity3d.com/pages/viewpage.action?pageId=13500715 ->>> - - - -# Technical details -## Requirements ->>> -This subtopic includes a bullet list with the compatible versions of Unity. This subtopic may also include additional requirements or recommendations for 3rd party software or hardware. An example includes a dependency on other packages. If you need to include references to non-Unity products, make sure you refer to these products correctly and that all references include the proper trademarks (tm or r) ->>> - -This version of <package name> is compatible with the following versions of the Unity Editor: - -* 2018.1 and later (recommended) - -To use this package, you must have the following 3rd party products: - -* <product name and version with trademark or registered trademark.> -* <product name and version with trademark or registered trademark.> -* <product name and version with trademark or registered trademark.> - -## Known limitations ->>> -This section lists the known limitations with this version of the package. If there are no known limitations, or if the limitations are trivial, exclude this section. An example is provided. ->>> - -<package name> version <package version> includes the following known limitations: - -* <brief one-line description of first limitation.> -* <brief one-line description of second limitation.> -* <and so on> - ->>> -*Example (For reference. Do not include in the final documentation file):* - -The Unity Recorder version 1.0 has the following limitations:* - -* The Unity Recorder does not support sound. -* The Recorder window and Recorder properties are not available in standalone players. -* MP4 encoding is only available on Windows. ->>> - -## Package contents ->>> -This section includes the location of important files you want the user to know about. For example, if this is a sample package containing textures, models, and materials separated by sample group, you may want to provide the folder location of each group. ->>> - -The following table indicates the <describe the breakdown you used here>: - -|Location|Description| -|---|---| -|``|Contains <describe what the folder contains>.| -|``|Contains <describe what the file represents or implements>.| - ->>> -*Example (For reference. Do not include in the final documentation file):* - -The following table indicates the root folder of each type of sample in this package. Each sample's root folder contains its own Materials, Models, or Textures folders: - -|Folder Location|Description| -|---|---| -|`WoodenCrate_Orange`|Root folder containing the assets for the orange crates.| -|`WoodenCrate_Mahogany`|Root folder containing the assets for the mahogany crates.| -|`WoodenCrate_Shared`|Root folder containing any material assets shared by all crates.| ->>> - -## Document revision history ->>> -This section includes the revision history of the document. The revision history tracks when a document is created, edited, and updated. If you create or update a document, you must add a new row describing the revision. The Documentation Team also uses this table to track when a document is edited and its editing level. An example is provided: - -|Date|Reason| -|---|---| -|Sept 12, 2017|Unedited. Published to package.| -|Sept 10, 2017|Document updated for package version 1.1.
New features:
  • audio support for capturing MP4s.
  • Instructions on saving Recorder prefabs| -|Sept 5, 2017|Limited edit by Documentation Team. Published to package.| -|Aug 25, 2017|Document created. Matches package version 1.0.| ->>> \ No newline at end of file diff --git a/Editor/UIWidgetsPanelEditor.cs b/Editor/UIWidgetsPanelEditor.cs index 82457b19..6a6dab38 100644 --- a/Editor/UIWidgetsPanelEditor.cs +++ b/Editor/UIWidgetsPanelEditor.cs @@ -9,7 +9,7 @@ public class UIWidgetsPanelEditor : RawImageEditor { public override void OnInspectorGUI() { base.OnInspectorGUI(); var pixelRatioProperty = this.serializedObject.FindProperty("devicePixelRatioOverride"); - var antiAliasingProperty = this.serializedObject.FindProperty("antiAliasingOverride"); + var antiAliasingProperty = this.serializedObject.FindProperty("hardwareAntiAliasing"); EditorGUILayout.PropertyField(pixelRatioProperty); EditorGUILayout.PropertyField(antiAliasingProperty); this.serializedObject.ApplyModifiedProperties(); diff --git a/QAReport.md b/QAReport.md index 26c5ba37..25a80c51 100644 --- a/QAReport.md +++ b/QAReport.md @@ -1,26 +1,21 @@ # Quality Report -Use this file to outline the test strategy for this package. -## Version tested: [*package version*] +## Version tested: [1.0.3-preview] -## QA Owner: [*Add Name*] -## UX Owner: [*Add Name*] +## QA Owner: Jason Fu +## UX Owner: Yuncong Zhang ## Test strategy -*Use this section to describe how this feature was tested.* -* A link to the Test Plan (Test Rails, other) * Results from the package's editor and runtime test suite. -* Link to automated test results (if any) -* Manual test Results, [here's an example](https://docs.google.com/spreadsheets/d/12A76U5Gf969w10KL4Ik0wC1oFIBDUoRrqIvQgD18TFo/edit#gid=0) -* Scenario test week outcome -* etc. +``` +Overall result: PASS +Total Tests run: 4, Passed: 4, Failures: 0, Errors: 0, Inconclusives: 0 +Total not run : 0, Invalid: 0, Ignored: 0, Skipped: 0 +``` +* Test Rail Scenarios:https://qatestrail.hq.unity3d.com/index.php?/suites/view/67&group_by=cases:section_id&group_order=asc&group_id=76244 +* Editor/Runtime Test Suite: +* Manual test Results: https://qatestrail.hq.unity3d.com/index.php?/runs/view/13298&group_by=cases:section_id&group_order=asc ## Package Status -Use this section to describe: -* UX status/evaluation results * package stability -* known bugs, issues -* performance metrics, -* etc - -In other words, a general feeling on the health of this package. + * Stable \ No newline at end of file diff --git a/README-ZH.md b/README-ZH.md index 3e281004..a1ce68a6 100644 --- a/README-ZH.md +++ b/README-ZH.md @@ -1,3 +1,5 @@ +⚠️ 本项目的开发与维护目前已转移至https://github.com/Unity-Technologies/com.unity.uiwidgets. 如果您遇到Issue或者对UIWidgets有任何意见和建议,请移步我们的新仓库。谢谢您的关注! + # UIWidgets @@ -49,7 +51,8 @@ https://github.com/UnityTech/DocCN 查看。 ## 使用要求 #### Unity -安装 Unity 2018.3 或更高版本。 你可以从[https://unity3d.com/get-unity/download](https://unity3d.com/get-unity/download)下载最新的Unity。 + +安装 **Unity 2018.4.10f1(LTS)** 或 **Unity 2019.1.14f1** 及其更高版本。 你可以从[https://unity3d.com/get-unity/download](https://unity3d.com/get-unity/download)下载最新的Unity。 #### UIWidgets包 @@ -193,8 +196,10 @@ UIWidgets也支持Gif! #### 七、自动调节帧率 如果要使得构建出的应用能够自动调节帧率,请打开Project Settings,将构建目标平台对应的Quality选项卡中的V Sync Count设置为Don't Sync。 -默认的逻辑是在界面静止时将帧率降低为25,在界面变动时将帧率提高至60。 -如果您需要修改帧率升高或降低时的行为,请将`Window.onFrameRateSpeedUp`和/或`Window.onFrameRateCoolDown`设置为您自己的函数。 +默认的逻辑是在界面静止时将帧率降低,在界面变动时再将帧率提高至60。 +如果您不想开启该功能,请将`Window.onFrameRateSpeedUp`和/或`Window.onFrameRateCoolDown`设置为空函数,()=> {}即可。 + +在Unity 2019.3版本及以上,UIWidgets将使用OnDemandRenderAPI来实现帧率调节,它将在不影响UI响应速度的情况下大幅降低耗电和发热问题。 #### 八、WebGL Canvas分辨率调整插件 因为浏览器中Canvas的宽高和其在显示器上的像素数可能不一致,所以构建出的WebGL程序中画面可能会模糊。 @@ -222,9 +227,34 @@ $JSEvents 在UIWidgets中使用图片时,记得将这一特性关闭,以免图片被意外放缩,方法如下:在Project面板中选中图片,在"Inspector"面板中将"Non Power of 2"(在"Advanced"中)设置为"None"。 #### 十、更新表情(Emoji) -UIWidgets支持渲染文本中包含的表情。表情的图片来自[https://www.joypixels.com](https://www.joypixels.com/)提供的免费资源。 -如果您希望使用自己的表情图片,请更新纹理图`Tests/Resources/Emoji.png`,以及`Runtime/ui/txt/emoji.cs`中将Unicode映射到纹理图中具体位置的映射表。 -特别地,请记得更新Dictionary变量`emojiLookupTable`,纹理图的行数`rowCount`以及纹理图的列数`colCount`。 +UIWidgets支持渲染文本中包含的表情。 +默认的表情资源为[iOS 13.2](https://emojipedia.org/apple/ios-13.2)。 +我们也准备了[Google Emoji](https://emojipedia.org/google)的表情资源。 +如果您希望切换到Google版本的表情,请按如下步骤操作: + +1. 拷贝`Runtime/Resources/backup~/EmojiGoogle.png`到`Runtime/Resources/images`目录。 +2. 在**Project**面板中,找到`EmojiGoogle`资源,在**Inspector**面板中,将**Max Size**更改为4096,取消选中**Generate Mipmaps**,并选中**Alpha Is Transparency**。 +3. 在您的代码中继承`UIWidgetsPanel`的类的`OnEnable()`函数中,添加如下代码 + +```csharp +EmojiUtils.configuration = EmojiUtils.googleEmojiConfiguration; +``` + +如果您希望使用自己的表情图片,请按如下步骤操作: + +1. 参照`EmojiGoogle.png`,创建您自己的Emoji表单,并放到工程目录下的某个`Resources`目录中,例如`Resources/myImages/MyEmoji.png`)。 +2. 在`OnEnable()`函数中,添加如下代码(记得将示例的值改为真实的值)。注意Emoji的编码的顺序要和Emoji表单一致。 + +```csharp +EmojiUtils.configuration = new EmojiResourceConfiguration( + spriteSheetAssetName: "myImage/MyEmoji", + emojiCodes: new List { + 0x1f004, 0x1f0cf, 0x1f170, ... + }, + spriteSheetNumberOfRows: 36, + spriteSheetNumberOfColumns: 37, +); +``` #### 十一、与GameObject进行拖拽交互 @@ -234,8 +264,6 @@ UIWidgets支持渲染文本中包含的表情。表情的图片来自[https://ww 我们提供了一个包装好的`UnityObjectDetector`组件以及`onRelease`回调函数,借此您可以实现简单地将物体(例如Hierarchy内的场景物体、Project窗口下的文件等)拖拽至区域内,来获得`UnityEngine.Object[] `类型的引用并进行操作。 -你可以在“UIWidgetsTests -> Drag&Drop”下找到简单的实例样例。 - ## 调试UIWidgets应用程序 @@ -255,15 +283,22 @@ UIWidgets Inspector工具用于可视化和浏览窗口小部件树。 你可以 ## 学习 -#### 示例 - -你可以在**Samples**文件夹的UIWidgets包中找到一些精心挑选的UIWidgets应用示例,并通过这些示例来开始你的学习。请随意尝试并进行修改以查看结果。 +#### 教程 -你也可以在支持**UIWidgets**的编辑器中,点击主菜单上的UIWidgets,并在下拉窗口中选择一个示例。 +包括开发组在内的广大开发者为UIWidgets提供了许多可供学习的样例和教程,你可以根据你的需求进行学习: +- UIWidgets官方示例。目前所有官方使用的示例项目均维护在一个独立的Github仓库( https://github.com/UIWidgets/UIWidgetsSamples )中。你可以 +将它clone到你项目本地的Assets目录下使用。 +具体的,你可以在Sample项目的**Scene**子文件夹中浏览所有示例UI场景。 +此外,你还可以点击主菜单上的新增的UIWidgetsTests选项卡,并在下拉菜单中选择一个EditorWindow UI示例来运行。 +- UIWidgets凉鞋系列教程。你可以在凉鞋老师整理的Github仓库( https://github.com/liangxiegame/awesome-uiwidgets )中学习UIWidgets的基本用法 +以及许多有趣的小Demo。 +- ConnectApp开源项目。这是一个完整的线上、开源、完全基于UIWidgets的第一方App项目。其中包含了大量产品级的UIWidgets工程实践细节, +如果你想深入了解UIWidgets并且使用它构建线上项目,请访问项目Github仓库了解更多( https://github.com/UnityTech/ConnectAppCN )。 #### Wiki -目前开发团队仍在改进UIWidgets Wiki。 由于UIWidgets主要来源于Flutter,你也可以参考Flutter Wiki中与UIWidgets API对应部分的详细描述。同时,你可以加入我们的讨论组( https://connect.unity.com/g/uiwidgets )。 +目前开发团队仍在改进UIWidgets Wiki。 由于UIWidgets主要来源于Flutter,你也可以参考Flutter Wiki中与UIWidgets API对应部分的详细描述。 +同时,你可以加入我们的讨论组( https://connect.unity.com/g/uiwidgets )。 #### 常问问题解答 diff --git a/README.md b/README.md index cba98852..e561546f 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +⚠️ The main repository of UIWidgets has been moved to https://github.com/Unity-Technologies/com.unity.uiwidgets. Please visit the new site if you have an issue or want to contribute. Thanks! + # UIWidgets [中文](README-ZH.md) @@ -55,10 +57,11 @@ and iOS (Searching for "Unity Connect" in App Store). This project is open-sourc The official website of Unity Chinese Documentation (https://connect.unity.com/doc) is powered by UIWidgets and open-sourced @https://github.com/UnityTech/DocCN. -## Requirement +## Requirements #### Unity -Install **Unity 2018.3** or above. You can download the latest Unity on https://unity3d.com/get-unity/download. + +Install **Unity 2018.4.10f1 (LTS)** or **Unity 2019.1.14f1** and above. You can download the latest Unity on https://unity3d.com/get-unity/download. #### UIWidgets Package Visit our Github repository https://github.com/UnityTech/UIWidgets @@ -228,8 +231,10 @@ Status bar is always hidden by default when an Unity project is running on an An #### Automatically Adjust Frame Rate To build an App that is able to adjust the frame rate automatically, please open Project Settings, and in the Quality tab, set the "V Sync Count" option of the target platform to "Don't Sync". -The default logic is to set the frame rate to 25 when the screen is static, and change the frame rate to 60 whenever the screen changes. -If you would like to modify the behavior of speeding up or cooling down the frame rate, please set `Window.onFrameRateSpeedUp` and/or `Window.onFrameRateCoolDown` to your own functions. +The default logic is to reduce the frame rate when the screen is static, and change it back to 60 whenever the screen changes. +If you would like to disable this behavior, please set `Window.onFrameRateSpeedUp` and `Window.onFrameRateCoolDown` to null function, i.e., () => {}. + +Note that in Unity 2019.3 and above, UIWidgets will use OnDemandRenderAPI to implement this feature, which will greatly save the battery. #### WebGL Canvas Device Pixel Ratio Plugin The width and height of the Canvas in browser may differ from the number of pixels the Canvas occupies on the screen. @@ -258,12 +263,34 @@ Unity, by default, resizes the width and height of an imported image to the near In UIWidgets, you should almost always disable this by selecting the image in the "Project" panel, then in the "Inspector" panel set the "Non Power of 2" option (in "Advanced") to "None", to prevent your image from being resized unexpectedly. #### Update Emoji -UIWidgets supports rendering emoji in (editable) texts. The emoji images comes from the free -resources provided by [https://www.joypixels.com](https://www.joypixels.com/). If you would -like to use your own images for emoji, please update the texture image `Tests/Resources/Emoji.png`, -and the unicode-index table in `Runtime/ui/txt/emoji.cs` which maps unicodes to specific locations -in the texture. Specifically, remember to update the Dictionary `emojiLookupTable`, number of rows -in the texture `rowCount`, and number of columns `colCount`. +UIWidgets supports rendering emoji in (editable) texts. +The default emoji resource version is [iOS 13.2](https://emojipedia.org/apple/ios-13.2). +We also prepared the resources of [Google Emoji](https://emojipedia.org/google). +To switch to Google version of emoji, please follow the following steps: + +1. Copy `Runtime/Resources/backup~/EmojiGoogle.png` to `Runtime/Resources/images` folder. +2. In the **Project** panel, find and select `EmojiGoogle` asset, and in the **Inspector** panel, change **Max Size** to 4096, disable **Generate Mipmaps**, and enable **Alpha Is Transparency**. +3. In the `OnEnable()` function in your class overriding `UIWidgetsPanel`, add the following code + +```csharp +EmojiUtils.configuration = EmojiUtils.googleEmojiConfiguration; +``` + +If you would like to use your own images for emoji, please follow the following steps: + +1. Create the sprite sheet (take `EmojiGoogle.png` as an example), and put in a `Resources` folder in your project, (for example `Resources/myImages/MyEmoji.png`). +2. In the `OnEnable()` function, add the following code (replace example values with actual value). Note that the order of emoji codes should be consistent with the sprite sheet. + +```csharp +EmojiUtils.configuration = new EmojiResourceConfiguration( + spriteSheetAssetName: "myImage/MyEmoji", + emojiCodes: new List { + 0x1f004, 0x1f0cf, 0x1f170, ... + }, + spriteSheetNumberOfRows: 36, + spriteSheetNumberOfColumns: 37, +); +``` #### Interact with GameObject Drag&Drops @@ -273,8 +300,6 @@ in the texture `rowCount`, and number of columns `colCount`. With the provided packaged stateful widget `UnityObjectDetector` and its `onRelease` callback function, you can easily drag some objects (for example GameObject from Hierarchy, files from Project Window, etc) into the area, get the UnityEngine.Object[] references and make further modification. -Please refer to "UIWidgetsTests -> Drag&Drop" for simple examples. - ## Debug UIWidgets Application @@ -288,6 +313,7 @@ The symbol is for debug purpose, please remove it from your release build. #### UIWidgets Inspector The UIWidgets Inspector tool is for visualizing and exploring the widget trees. You can find it via *Window/Analysis/UIWidgets* inspector in Editor menu. + **Note** * **UIWidgets_DEBUG** needs to be define for inspector to work properly. * Inspector currently only works in Editor Play Mode, inspect standalone built application is not supported for now. @@ -295,13 +321,19 @@ via *Window/Analysis/UIWidgets* inspector in Editor menu. ## Learn #### Samples -You can find many UIWidgets App samples in the UIWidgets package in the **Samples** folder. -Feel free to try them out and make modifications to see the results. -To get started, the UIWidgetsTheatre scene provides you -a list of carefully selected samples to start with. - -You can also try UIWidgets-based Editor windows by clicking **UIWidgetsTest** on the main menu +You can find many UIWidgets sample projects on Github, which cover different aspects and provide you +learning materials in various levels: +* UIWidgetsSamples (https://github.com/UIWidgets/UIWidgetsSamples). These samples are developed by the dev team in order to illustrates all the features of +UIWidgets. First clone this Repo to the **Assets** folder of your local UIWidgets project. Then +you can find all the sample scenes under the **Scene** folder. +You can also try UIWidgets-based Editor windows by clicking the new **UIWidgetsTests** tab on the main menu and open one of the dropdown samples. +* awesome-UIWidgets by Liangxie (https://github.com/liangxiegame/awesome-uiwidgets). This Repo contains +lots of UIWidget demo apps and third-party applications. +* ConnectApp (https://github.com/UnityTech/ConnectAppCN). This is an online, open-source UIWidget-based App developed +by the dev team. If you are making your own App with UIWidgets, this project will provides you with +many best practice cases. + #### Wiki The develop team is still working on the UIWidgets Wiki. However, since UIWidgets is mainly derived from Flutter, diff --git a/Runtime/Plugins/platform/ios/DeviceScreen.mm b/Runtime/Plugins/platform/ios/DeviceScreen.mm index 0c5d580b..7ccb4fac 100644 --- a/Runtime/Plugins/platform/ios/DeviceScreen.mm +++ b/Runtime/Plugins/platform/ios/DeviceScreen.mm @@ -1,8 +1,13 @@ #import +#import "UIWidgetsDevice.h" extern "C" { - int IOSDeviceScaleFactor() + float IOSDeviceScaleFactor() { - return [[UIScreen mainScreen] scale]; + float scale = [[UIScreen mainScreen] scale] * 1.0; + if ([UIWidgetsDevice NeedScreenDownSample]) { + scale *= 0.8696; + } + return scale; } } diff --git a/Runtime/Plugins/platform/ios/UIWidgetsTextInputPlugin.mm b/Runtime/Plugins/platform/ios/UIWidgetsTextInputPlugin.mm old mode 100644 new mode 100755 index 8148b874..62cd35c4 --- a/Runtime/Plugins/platform/ios/UIWidgetsTextInputPlugin.mm +++ b/Runtime/Plugins/platform/ios/UIWidgetsTextInputPlugin.mm @@ -211,6 +211,11 @@ - (void)setTextInputState:(NSDictionary*)state { [self.inputDelegate textWillChange:self]; [self.text setString:newText]; } + + NSInteger composingBase = [state[@"composingBase"] intValue]; + NSInteger composingExtent = [state[@"composingExtent"] intValue]; + NSRange composingRange = [self clampSelection:NSMakeRange(MIN(composingBase, composingExtent), ABS(composingBase - composingExtent)) forText:self.text]; + self.markedTextRange = composingRange.length > 0 ? [UIWidgetsTextRange rangeWithNSRange:composingRange] : nil; NSInteger selectionBase = [state[@"selectionBase"] intValue]; NSInteger selectionExtent = [state[@"selectionExtent"] intValue]; @@ -229,14 +234,6 @@ - (void)setTextInputState:(NSDictionary*)state { [self.inputDelegate selectionDidChange:self]; } - NSInteger composingBase = [state[@"composingBase"] intValue]; - NSInteger composingExtent = [state[@"composingExtent"] intValue]; - NSRange composingRange = [self clampSelection:NSMakeRange(MIN(composingBase, composingExtent), - ABS(composingBase - composingExtent)) - forText:self.text]; - self.markedTextRange = - composingRange.length > 0 ? [UIWidgetsTextRange rangeWithNSRange:composingRange] : nil; - if (textChanged) { [self.inputDelegate textDidChange:self]; @@ -428,6 +425,10 @@ - (NSUInteger)incrementOffsetPosition:(NSUInteger)position { - (UITextPosition*)positionFromPosition:(UITextPosition*)position offset:(NSInteger)offset { NSUInteger offsetPosition = ((UIWidgetsTextPosition*)position).index; + NSInteger newLocation = (NSInteger)offsetPosition + offset; + if (newLocation < 0 || newLocation > (NSInteger)self.text.length) { + return nil; + } if (offset >= 0) { for (NSInteger i = 0; i < offset && offsetPosition < self.text.length; ++i) offsetPosition = [self incrementOffsetPosition:offsetPosition]; diff --git a/Runtime/Resources/UIWidgets_GUITexture.shader.meta b/Runtime/Resources/UIWidgets_GUITexture.shader.meta deleted file mode 100644 index 493bae10..00000000 --- a/Runtime/Resources/UIWidgets_GUITexture.shader.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: ea02b3553b38477c85b9ca45949cc85c -timeCreated: 1544158153 \ No newline at end of file diff --git a/Tests/Resources/Emoji.png b/Runtime/Resources/backup~/EmojiGoogle.png similarity index 51% rename from Tests/Resources/Emoji.png rename to Runtime/Resources/backup~/EmojiGoogle.png index 2ad32cbe..e67ac9f9 100644 Binary files a/Tests/Resources/Emoji.png and b/Runtime/Resources/backup~/EmojiGoogle.png differ diff --git a/Samples/MaterialSample.meta b/Runtime/Resources/fonts.meta similarity index 77% rename from Samples/MaterialSample.meta rename to Runtime/Resources/fonts.meta index 3ceff443..3660509f 100644 --- a/Samples/MaterialSample.meta +++ b/Runtime/Resources/fonts.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 611706478d8aa410983272ad601895d3 +guid: 85e7c93f407b3475eb107fc0877ac351 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Runtime/Resources/fonts/CupertinoIcons.ttf b/Runtime/Resources/fonts/CupertinoIcons.ttf new file mode 100644 index 00000000..bef51e15 Binary files /dev/null and b/Runtime/Resources/fonts/CupertinoIcons.ttf differ diff --git a/Runtime/Resources/fonts/CupertinoIcons.ttf.meta b/Runtime/Resources/fonts/CupertinoIcons.ttf.meta new file mode 100644 index 00000000..77dfaaf7 --- /dev/null +++ b/Runtime/Resources/fonts/CupertinoIcons.ttf.meta @@ -0,0 +1,22 @@ +fileFormatVersion: 2 +guid: cb93bb6e1c3874b67b6ad9fe6c775045 +TrueTypeFontImporter: + externalObjects: {} + serializedVersion: 4 + fontSize: 16 + forceTextureCase: -2 + characterSpacing: 0 + characterPadding: 1 + includeFontData: 1 + fontName: CupertinoIcons + fontNames: + - CupertinoIcons + fallbackFontReferences: [] + customCharacters: + fontRenderingMode: 0 + ascentCalculationMode: 1 + useLegacyBoundsCalculation: 0 + shouldRoundAdvanceValue: 1 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Tests/Resources/GalleryIcons.ttf b/Runtime/Resources/fonts/GalleryIcons.ttf similarity index 100% rename from Tests/Resources/GalleryIcons.ttf rename to Runtime/Resources/fonts/GalleryIcons.ttf diff --git a/Tests/Resources/GalleryIcons.ttf.meta b/Runtime/Resources/fonts/GalleryIcons.ttf.meta similarity index 92% rename from Tests/Resources/GalleryIcons.ttf.meta rename to Runtime/Resources/fonts/GalleryIcons.ttf.meta index 66b79889..398ddb2a 100644 --- a/Tests/Resources/GalleryIcons.ttf.meta +++ b/Runtime/Resources/fonts/GalleryIcons.ttf.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 3a6743c0a08ca4626a9b85050002f40c +guid: 972403b703998429986576a840246ec2 TrueTypeFontImporter: externalObjects: {} serializedVersion: 4 diff --git a/Tests/Resources/MaterialIcons-Regular.ttf b/Runtime/Resources/fonts/MaterialIcons-Regular.ttf similarity index 100% rename from Tests/Resources/MaterialIcons-Regular.ttf rename to Runtime/Resources/fonts/MaterialIcons-Regular.ttf diff --git a/Tests/Resources/MaterialIcons-Regular.ttf.meta b/Runtime/Resources/fonts/MaterialIcons-Regular.ttf.meta similarity index 76% rename from Tests/Resources/MaterialIcons-Regular.ttf.meta rename to Runtime/Resources/fonts/MaterialIcons-Regular.ttf.meta index dc7caed0..564918c1 100644 --- a/Tests/Resources/MaterialIcons-Regular.ttf.meta +++ b/Runtime/Resources/fonts/MaterialIcons-Regular.ttf.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 454d829e3d72f41ad97833e7fc449127 +guid: 1bb29e480b1ee44a09d380d7e8521d1e TrueTypeFontImporter: externalObjects: {} serializedVersion: 4 @@ -11,8 +11,7 @@ TrueTypeFontImporter: fontName: Material Icons fontNames: - Material Icons - fallbackFontReferences: - - {fileID: 12800000, guid: c81e9379793cd4a3cbbc59d8be1ed447, type: 3} + fallbackFontReferences: [] customCharacters: fontRenderingMode: 0 ascentCalculationMode: 1 diff --git a/Runtime/Resources/fonts/SF-Pro-Text-Bold.otf b/Runtime/Resources/fonts/SF-Pro-Text-Bold.otf new file mode 100644 index 00000000..44c648fb Binary files /dev/null and b/Runtime/Resources/fonts/SF-Pro-Text-Bold.otf differ diff --git a/Runtime/Resources/fonts/SF-Pro-Text-Bold.otf.meta b/Runtime/Resources/fonts/SF-Pro-Text-Bold.otf.meta new file mode 100644 index 00000000..29a4f273 --- /dev/null +++ b/Runtime/Resources/fonts/SF-Pro-Text-Bold.otf.meta @@ -0,0 +1,23 @@ +fileFormatVersion: 2 +guid: 88aadcd46e08344f4b9d60ad85cca1a7 +TrueTypeFontImporter: + externalObjects: {} + serializedVersion: 4 + fontSize: 16 + forceTextureCase: -2 + characterSpacing: 0 + characterPadding: 1 + includeFontData: 1 + fontName: SF Pro Text + fontNames: + - SF Pro Text + fallbackFontReferences: + - {fileID: 12800000, guid: 3229e68e388b0492c9fe466e5f4bcef0, type: 3} + customCharacters: + fontRenderingMode: 0 + ascentCalculationMode: 1 + useLegacyBoundsCalculation: 0 + shouldRoundAdvanceValue: 1 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Resources/fonts/SF-Pro-Text-Regular.otf b/Runtime/Resources/fonts/SF-Pro-Text-Regular.otf new file mode 100644 index 00000000..65f9ea5e Binary files /dev/null and b/Runtime/Resources/fonts/SF-Pro-Text-Regular.otf differ diff --git a/Runtime/Resources/fonts/SF-Pro-Text-Regular.otf.meta b/Runtime/Resources/fonts/SF-Pro-Text-Regular.otf.meta new file mode 100644 index 00000000..af00457b --- /dev/null +++ b/Runtime/Resources/fonts/SF-Pro-Text-Regular.otf.meta @@ -0,0 +1,24 @@ +fileFormatVersion: 2 +guid: 8c3ad6425c3594ad5aaa32d70ad513ae +TrueTypeFontImporter: + externalObjects: {} + serializedVersion: 4 + fontSize: 16 + forceTextureCase: -2 + characterSpacing: 0 + characterPadding: 1 + includeFontData: 1 + fontName: SF Pro Text + fontNames: + - SF Pro Text + fallbackFontReferences: + - {fileID: 12800000, guid: 88aadcd46e08344f4b9d60ad85cca1a7, type: 3} + - {fileID: 12800000, guid: 3229e68e388b0492c9fe466e5f4bcef0, type: 3} + customCharacters: + fontRenderingMode: 0 + ascentCalculationMode: 1 + useLegacyBoundsCalculation: 0 + shouldRoundAdvanceValue: 1 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Resources/fonts/SF-Pro-Text-Semibold.otf b/Runtime/Resources/fonts/SF-Pro-Text-Semibold.otf new file mode 100644 index 00000000..f3377adb Binary files /dev/null and b/Runtime/Resources/fonts/SF-Pro-Text-Semibold.otf differ diff --git a/Runtime/Resources/fonts/SF-Pro-Text-Semibold.otf.meta b/Runtime/Resources/fonts/SF-Pro-Text-Semibold.otf.meta new file mode 100644 index 00000000..7ee6db40 --- /dev/null +++ b/Runtime/Resources/fonts/SF-Pro-Text-Semibold.otf.meta @@ -0,0 +1,22 @@ +fileFormatVersion: 2 +guid: 3229e68e388b0492c9fe466e5f4bcef0 +TrueTypeFontImporter: + externalObjects: {} + serializedVersion: 4 + fontSize: 16 + forceTextureCase: -2 + characterSpacing: 0 + characterPadding: 1 + includeFontData: 1 + fontName: SF Pro Text + fontNames: + - SF Pro Text + fallbackFontReferences: [] + customCharacters: + fontRenderingMode: 0 + ascentCalculationMode: 1 + useLegacyBoundsCalculation: 0 + shouldRoundAdvanceValue: 1 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples/ReduxSample.meta b/Runtime/Resources/images.meta similarity index 77% rename from Samples/ReduxSample.meta rename to Runtime/Resources/images.meta index 744061b1..70706e41 100644 --- a/Samples/ReduxSample.meta +++ b/Runtime/Resources/images.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 5d9b41f3c48f94f93b5aaf521adbe0bf +guid: 32feac74b59644395ac8e546617b14e2 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Runtime/Resources/images/EmojiIOS13.2.png b/Runtime/Resources/images/EmojiIOS13.2.png new file mode 100644 index 00000000..7a618606 Binary files /dev/null and b/Runtime/Resources/images/EmojiIOS13.2.png differ diff --git a/Tests/Resources/ali_landscape.png.meta b/Runtime/Resources/images/EmojiIOS13.2.png.meta similarity index 88% rename from Tests/Resources/ali_landscape.png.meta rename to Runtime/Resources/images/EmojiIOS13.2.png.meta index 82be4af5..38108f12 100644 --- a/Tests/Resources/ali_landscape.png.meta +++ b/Runtime/Resources/images/EmojiIOS13.2.png.meta @@ -1,12 +1,12 @@ fileFormatVersion: 2 -guid: e064ac38639964afe8017fb7079bf993 +guid: fe6ee86be009e43328c4814e85bff08c TextureImporter: - fileIDToRecycleName: {} + internalIDToNameTable: [] externalObjects: {} - serializedVersion: 7 + serializedVersion: 10 mipmaps: mipMapMode: 0 - enableMipMap: 1 + enableMipMap: 0 sRGBTexture: 1 linearTexture: 0 fadeOut: 0 @@ -37,7 +37,7 @@ TextureImporter: wrapU: -1 wrapV: -1 wrapW: -1 - nPOTScale: 0 + nPOTScale: 1 lightmap: 0 compressionQuality: 50 spriteMode: 0 @@ -49,7 +49,7 @@ TextureImporter: spriteBorder: {x: 0, y: 0, z: 0, w: 0} spriteGenerateFallbackPhysicsShape: 1 alphaUsage: 1 - alphaIsTransparency: 0 + alphaIsTransparency: 1 spriteTessellationDetail: -1 textureType: 0 textureShape: 1 @@ -60,7 +60,7 @@ TextureImporter: platformSettings: - serializedVersion: 2 buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 + maxTextureSize: 4096 resizeAlgorithm: 0 textureFormat: -1 textureCompression: 1 @@ -71,7 +71,7 @@ TextureImporter: androidETC2FallbackOverride: 0 - serializedVersion: 2 buildTarget: Standalone - maxTextureSize: 2048 + maxTextureSize: 4096 resizeAlgorithm: 0 textureFormat: -1 textureCompression: 1 @@ -82,7 +82,7 @@ TextureImporter: androidETC2FallbackOverride: 0 - serializedVersion: 2 buildTarget: iPhone - maxTextureSize: 2048 + maxTextureSize: 4096 resizeAlgorithm: 0 textureFormat: -1 textureCompression: 1 @@ -92,8 +92,8 @@ TextureImporter: overridden: 0 androidETC2FallbackOverride: 0 - serializedVersion: 2 - buildTarget: WebGL - maxTextureSize: 2048 + buildTarget: Android + maxTextureSize: 4096 resizeAlgorithm: 0 textureFormat: -1 textureCompression: 1 @@ -109,10 +109,12 @@ TextureImporter: physicsShape: [] bones: [] spriteID: + internalID: 0 vertices: [] indices: edges: [] weights: [] + secondaryTextures: [] spritePackingTag: pSDRemoveMatte: 0 pSDShowRemoveMatteOption: 0 diff --git a/Samples/ReduxSample/CounterApp.meta b/Runtime/Resources/shaders.meta similarity index 77% rename from Samples/ReduxSample/CounterApp.meta rename to Runtime/Resources/shaders.meta index 7b58fbd2..c76404ed 100644 --- a/Samples/ReduxSample/CounterApp.meta +++ b/Runtime/Resources/shaders.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 97e1cfc4dc13449d3a13f106893e44cd +guid: db2eb33ed6fce4c999c8481059ee7e6c folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Runtime/Resources/UIWidgets_GUITexture.shader b/Runtime/Resources/shaders/UIWidgets_GUITexture.shader similarity index 100% rename from Runtime/Resources/UIWidgets_GUITexture.shader rename to Runtime/Resources/shaders/UIWidgets_GUITexture.shader diff --git a/Runtime/Resources/shaders/UIWidgets_GUITexture.shader.meta b/Runtime/Resources/shaders/UIWidgets_GUITexture.shader.meta new file mode 100644 index 00000000..6ff779c9 --- /dev/null +++ b/Runtime/Resources/shaders/UIWidgets_GUITexture.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: f592638352fff481487dec316e583967 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Resources/UIWidgets_UIDefault.shader b/Runtime/Resources/shaders/UIWidgets_UIDefault.shader similarity index 100% rename from Runtime/Resources/UIWidgets_UIDefault.shader rename to Runtime/Resources/shaders/UIWidgets_UIDefault.shader diff --git a/Runtime/Resources/UIWidgets_UIDefault.shader.meta b/Runtime/Resources/shaders/UIWidgets_UIDefault.shader.meta similarity index 80% rename from Runtime/Resources/UIWidgets_UIDefault.shader.meta rename to Runtime/Resources/shaders/UIWidgets_UIDefault.shader.meta index dd6d6f6f..b86d763f 100644 --- a/Runtime/Resources/UIWidgets_UIDefault.shader.meta +++ b/Runtime/Resources/shaders/UIWidgets_UIDefault.shader.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 43b4ae1d316ca415589f96e49cc0fcab +guid: 3434943ef6cfa4c80b424b818d1ccd46 ShaderImporter: externalObjects: {} defaultTextures: [] diff --git a/Runtime/Resources/UIWidgets_canvas.cginc b/Runtime/Resources/shaders/UIWidgets_canvas.cginc similarity index 91% rename from Runtime/Resources/UIWidgets_canvas.cginc rename to Runtime/Resources/shaders/UIWidgets_canvas.cginc index 3f4fdaed..2f73499e 100644 --- a/Runtime/Resources/UIWidgets_canvas.cginc +++ b/Runtime/Resources/shaders/UIWidgets_canvas.cginc @@ -30,6 +30,18 @@ struct v2f { float2 fpos : TEXCOORD1; }; +inline half3 gamma_to_linear_space(half3 sRGB) { + return sRGB * (sRGB * (sRGB * 0.305306011h + 0.682171111h) + 0.012522878h); +} + +inline half4 adjust_color(half4 color) { +#ifdef UNITY_COLORSPACE_GAMMA + return color; +#else + color.rgb = gamma_to_linear_space(color.rgb); + return color; +#endif +} half shader_gradient_layout(half2 pos) { half4 p4 = half4(pos, 0.0, 1.0); @@ -50,9 +62,9 @@ half shader_gradient_layout(half2 pos) { half4 shader_gradient_colorize(half pt) { if (_tileMode == 0) { // clamp if (pt <= 0.0) { - return _leftColor; + return adjust_color(_leftColor); } else if (pt >= 1.0) { - return _rightColor; + return adjust_color(_rightColor); } half2 coord = half2(pt, 0.5); @@ -107,7 +119,7 @@ half4 shader_color (v2f i) { half4 c; #if defined(UIWIDGETS_COLOR) - c = _color; + c = adjust_color(_color); #elif defined(UIWIDGETS_IMAGE) half2 pt = shader_image_layout(i.fpos); c = shader_image_colorize(pt); diff --git a/Runtime/Resources/UIWidgets_canvas.cginc.meta b/Runtime/Resources/shaders/UIWidgets_canvas.cginc.meta similarity index 80% rename from Runtime/Resources/UIWidgets_canvas.cginc.meta rename to Runtime/Resources/shaders/UIWidgets_canvas.cginc.meta index aadc11ed..339442f4 100644 --- a/Runtime/Resources/UIWidgets_canvas.cginc.meta +++ b/Runtime/Resources/shaders/UIWidgets_canvas.cginc.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 6565922d18a5e4ee29fa183d2600eccc +guid: 12533dde17d054c58aa5aef1f8df7067 ShaderImporter: externalObjects: {} defaultTextures: [] diff --git a/Runtime/Resources/UIWidgets_canvas_convexFill.shader b/Runtime/Resources/shaders/UIWidgets_canvas_convexFill.shader similarity index 100% rename from Runtime/Resources/UIWidgets_canvas_convexFill.shader rename to Runtime/Resources/shaders/UIWidgets_canvas_convexFill.shader diff --git a/Runtime/Resources/UIWidgets_canvas_convexFill.shader.meta b/Runtime/Resources/shaders/UIWidgets_canvas_convexFill.shader.meta similarity index 80% rename from Runtime/Resources/UIWidgets_canvas_convexFill.shader.meta rename to Runtime/Resources/shaders/UIWidgets_canvas_convexFill.shader.meta index 9492987c..11ab2041 100644 --- a/Runtime/Resources/UIWidgets_canvas_convexFill.shader.meta +++ b/Runtime/Resources/shaders/UIWidgets_canvas_convexFill.shader.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: da4e74e0b377e41699f5c3ed2c7c69e4 +guid: 4ad4bfab828614fd090399d0cd793b1a ShaderImporter: externalObjects: {} defaultTextures: [] diff --git a/Runtime/Resources/UIWidgets_canvas_fill0.shader b/Runtime/Resources/shaders/UIWidgets_canvas_fill0.shader similarity index 100% rename from Runtime/Resources/UIWidgets_canvas_fill0.shader rename to Runtime/Resources/shaders/UIWidgets_canvas_fill0.shader diff --git a/Runtime/Resources/UIWidgets_canvas_fill0.shader.meta b/Runtime/Resources/shaders/UIWidgets_canvas_fill0.shader.meta similarity index 80% rename from Runtime/Resources/UIWidgets_canvas_fill0.shader.meta rename to Runtime/Resources/shaders/UIWidgets_canvas_fill0.shader.meta index 5f4df15b..1b244826 100644 --- a/Runtime/Resources/UIWidgets_canvas_fill0.shader.meta +++ b/Runtime/Resources/shaders/UIWidgets_canvas_fill0.shader.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: e75e9debfc1ad4e1687365932de72aa0 +guid: 104c51408606c4531bd029a900ff26b3 ShaderImporter: externalObjects: {} defaultTextures: [] diff --git a/Runtime/Resources/UIWidgets_canvas_fill1.shader b/Runtime/Resources/shaders/UIWidgets_canvas_fill1.shader similarity index 100% rename from Runtime/Resources/UIWidgets_canvas_fill1.shader rename to Runtime/Resources/shaders/UIWidgets_canvas_fill1.shader diff --git a/Runtime/Resources/UIWidgets_canvas_fill1.shader.meta b/Runtime/Resources/shaders/UIWidgets_canvas_fill1.shader.meta similarity index 80% rename from Runtime/Resources/UIWidgets_canvas_fill1.shader.meta rename to Runtime/Resources/shaders/UIWidgets_canvas_fill1.shader.meta index 767e1796..34807149 100644 --- a/Runtime/Resources/UIWidgets_canvas_fill1.shader.meta +++ b/Runtime/Resources/shaders/UIWidgets_canvas_fill1.shader.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 7dbfb4eecc7a84ddc90c53891aa77e0b +guid: cccc75413df09406bad8aab430428aec ShaderImporter: externalObjects: {} defaultTextures: [] diff --git a/Runtime/Resources/UIWidgets_canvas_filter.shader b/Runtime/Resources/shaders/UIWidgets_canvas_filter.shader similarity index 100% rename from Runtime/Resources/UIWidgets_canvas_filter.shader rename to Runtime/Resources/shaders/UIWidgets_canvas_filter.shader diff --git a/Runtime/Resources/UIWidgets_canvas_filter.shader.meta b/Runtime/Resources/shaders/UIWidgets_canvas_filter.shader.meta similarity index 80% rename from Runtime/Resources/UIWidgets_canvas_filter.shader.meta rename to Runtime/Resources/shaders/UIWidgets_canvas_filter.shader.meta index 9e86bb85..ade014c0 100644 --- a/Runtime/Resources/UIWidgets_canvas_filter.shader.meta +++ b/Runtime/Resources/shaders/UIWidgets_canvas_filter.shader.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 756de2a3eb91745ba853728245a033d9 +guid: 080129d418c1c442985d3aba354d88ca ShaderImporter: externalObjects: {} defaultTextures: [] diff --git a/Runtime/Resources/UIWidgets_canvas_shadowBox.shader b/Runtime/Resources/shaders/UIWidgets_canvas_shadowBox.shader similarity index 94% rename from Runtime/Resources/UIWidgets_canvas_shadowBox.shader rename to Runtime/Resources/shaders/UIWidgets_canvas_shadowBox.shader index d334c494..49548073 100644 --- a/Runtime/Resources/UIWidgets_canvas_shadowBox.shader +++ b/Runtime/Resources/shaders/UIWidgets_canvas_shadowBox.shader @@ -3,15 +3,13 @@ Shader "UIWidgets/ShadowBox" //originally from http://madebyevan.com/shaders/fast-rounded-rectangle-shadows/ Properties { - _SrcBlend("_SrcBlend", Int) = 1 // One - _DstBlend("_DstBlend", Int) = 10 // OneMinusSrcAlpha _StencilComp("_StencilComp", Float) = 8 // - Equal, 8 - Always } SubShader { ZTest Always ZWrite Off - Blend [_SrcBlend] [_DstBlend] + Blend SrcAlpha OneMinusSrcAlpha Stencil { Ref 128 diff --git a/Runtime/Resources/UIWidgets_canvas_shadowBox.shader.meta b/Runtime/Resources/shaders/UIWidgets_canvas_shadowBox.shader.meta similarity index 80% rename from Runtime/Resources/UIWidgets_canvas_shadowBox.shader.meta rename to Runtime/Resources/shaders/UIWidgets_canvas_shadowBox.shader.meta index 1370a10e..b5dcaf4a 100644 --- a/Runtime/Resources/UIWidgets_canvas_shadowBox.shader.meta +++ b/Runtime/Resources/shaders/UIWidgets_canvas_shadowBox.shader.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 105f52491741049d88708e718c749e34 +guid: e3e75e0dcee5243e2b95bc639eea758e ShaderImporter: externalObjects: {} defaultTextures: [] diff --git a/Runtime/Resources/UIWidgets_canvas_shadowRBox.shader b/Runtime/Resources/shaders/UIWidgets_canvas_shadowRBox.shader similarity index 96% rename from Runtime/Resources/UIWidgets_canvas_shadowRBox.shader rename to Runtime/Resources/shaders/UIWidgets_canvas_shadowRBox.shader index 7350e430..b5eeec3f 100644 --- a/Runtime/Resources/UIWidgets_canvas_shadowRBox.shader +++ b/Runtime/Resources/shaders/UIWidgets_canvas_shadowRBox.shader @@ -3,15 +3,13 @@ Shader "UIWidgets/ShadowRBox" //originally from http://madebyevan.com/shaders/fast-rounded-rectangle-shadows/ Properties { - _SrcBlend("_SrcBlend", Int) = 1 // One - _DstBlend("_DstBlend", Int) = 10 // OneMinusSrcAlpha _StencilComp("_StencilComp", Float) = 8 // - Equal, 8 - Always } SubShader { ZTest Always ZWrite Off - Blend [_SrcBlend] [_DstBlend] + Blend SrcAlpha OneMinusSrcAlpha Stencil { Ref 128 diff --git a/Runtime/Resources/UIWidgets_canvas_shadowRBox.shader.meta b/Runtime/Resources/shaders/UIWidgets_canvas_shadowRBox.shader.meta similarity index 80% rename from Runtime/Resources/UIWidgets_canvas_shadowRBox.shader.meta rename to Runtime/Resources/shaders/UIWidgets_canvas_shadowRBox.shader.meta index ee3c72de..0e1622bb 100644 --- a/Runtime/Resources/UIWidgets_canvas_shadowRBox.shader.meta +++ b/Runtime/Resources/shaders/UIWidgets_canvas_shadowRBox.shader.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 77c8565b9b449434490473ef8f7f0e91 +guid: cc9374790071e4da883a3319cda6cb20 ShaderImporter: externalObjects: {} defaultTextures: [] diff --git a/Runtime/Resources/UIWidgets_canvas_stencil.shader b/Runtime/Resources/shaders/UIWidgets_canvas_stencil.shader similarity index 100% rename from Runtime/Resources/UIWidgets_canvas_stencil.shader rename to Runtime/Resources/shaders/UIWidgets_canvas_stencil.shader diff --git a/Runtime/Resources/UIWidgets_canvas_stencil.shader.meta b/Runtime/Resources/shaders/UIWidgets_canvas_stencil.shader.meta similarity index 80% rename from Runtime/Resources/UIWidgets_canvas_stencil.shader.meta rename to Runtime/Resources/shaders/UIWidgets_canvas_stencil.shader.meta index 08ffb2ae..222331a5 100644 --- a/Runtime/Resources/UIWidgets_canvas_stencil.shader.meta +++ b/Runtime/Resources/shaders/UIWidgets_canvas_stencil.shader.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: b4673a8cf87214fdb8643b32e0ec3316 +guid: 57f3d43bd5ba648cda816d05ceb3b643 ShaderImporter: externalObjects: {} defaultTextures: [] diff --git a/Runtime/Resources/UIWidgets_canvas_stroke0.shader b/Runtime/Resources/shaders/UIWidgets_canvas_stroke0.shader similarity index 100% rename from Runtime/Resources/UIWidgets_canvas_stroke0.shader rename to Runtime/Resources/shaders/UIWidgets_canvas_stroke0.shader diff --git a/Runtime/Resources/UIWidgets_canvas_stroke0.shader.meta b/Runtime/Resources/shaders/UIWidgets_canvas_stroke0.shader.meta similarity index 80% rename from Runtime/Resources/UIWidgets_canvas_stroke0.shader.meta rename to Runtime/Resources/shaders/UIWidgets_canvas_stroke0.shader.meta index cdfb6d16..383630a0 100644 --- a/Runtime/Resources/UIWidgets_canvas_stroke0.shader.meta +++ b/Runtime/Resources/shaders/UIWidgets_canvas_stroke0.shader.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 7e33032771e1e46a6b5eda923148503f +guid: 3072a3ddd64a34c8cb3aa713b9705d72 ShaderImporter: externalObjects: {} defaultTextures: [] diff --git a/Runtime/Resources/UIWidgets_canvas_stroke1.shader b/Runtime/Resources/shaders/UIWidgets_canvas_stroke1.shader similarity index 100% rename from Runtime/Resources/UIWidgets_canvas_stroke1.shader rename to Runtime/Resources/shaders/UIWidgets_canvas_stroke1.shader diff --git a/Runtime/Resources/UIWidgets_canvas_stroke1.shader.meta b/Runtime/Resources/shaders/UIWidgets_canvas_stroke1.shader.meta similarity index 80% rename from Runtime/Resources/UIWidgets_canvas_stroke1.shader.meta rename to Runtime/Resources/shaders/UIWidgets_canvas_stroke1.shader.meta index 552f3be7..c201a5a5 100644 --- a/Runtime/Resources/UIWidgets_canvas_stroke1.shader.meta +++ b/Runtime/Resources/shaders/UIWidgets_canvas_stroke1.shader.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: ee8a29ca6a09f4510bbf6e3b70922edc +guid: c5ba00af1b3a24619b8572f17b98917a ShaderImporter: externalObjects: {} defaultTextures: [] diff --git a/Runtime/Resources/UIWidgets_canvas_strokeAlpha.shader b/Runtime/Resources/shaders/UIWidgets_canvas_strokeAlpha.shader similarity index 100% rename from Runtime/Resources/UIWidgets_canvas_strokeAlpha.shader rename to Runtime/Resources/shaders/UIWidgets_canvas_strokeAlpha.shader diff --git a/Runtime/Resources/UIWidgets_canvas_strokeAlpha.shader.meta b/Runtime/Resources/shaders/UIWidgets_canvas_strokeAlpha.shader.meta similarity index 80% rename from Runtime/Resources/UIWidgets_canvas_strokeAlpha.shader.meta rename to Runtime/Resources/shaders/UIWidgets_canvas_strokeAlpha.shader.meta index 886cafa8..c3689d9b 100644 --- a/Runtime/Resources/UIWidgets_canvas_strokeAlpha.shader.meta +++ b/Runtime/Resources/shaders/UIWidgets_canvas_strokeAlpha.shader.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: c57ed8e638931f946a7b5e26a54725d8 +guid: 72c25fdac75cf4041bf9ef313a342a28 ShaderImporter: externalObjects: {} defaultTextures: [] diff --git a/Runtime/Resources/UIWidgets_canvas_tex.shader b/Runtime/Resources/shaders/UIWidgets_canvas_tex.shader similarity index 100% rename from Runtime/Resources/UIWidgets_canvas_tex.shader rename to Runtime/Resources/shaders/UIWidgets_canvas_tex.shader diff --git a/Runtime/Resources/UIWidgets_canvas_tex.shader.meta b/Runtime/Resources/shaders/UIWidgets_canvas_tex.shader.meta similarity index 80% rename from Runtime/Resources/UIWidgets_canvas_tex.shader.meta rename to Runtime/Resources/shaders/UIWidgets_canvas_tex.shader.meta index 569dad32..8183422a 100644 --- a/Runtime/Resources/UIWidgets_canvas_tex.shader.meta +++ b/Runtime/Resources/shaders/UIWidgets_canvas_tex.shader.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 1702a648d08de40d9aacd9bbab1188b3 +guid: 9b0b3e1e797834f3abaefee47bce19df ShaderImporter: externalObjects: {} defaultTextures: [] diff --git a/Samples.meta b/Runtime/Resources/shaders/computebuffer.meta similarity index 77% rename from Samples.meta rename to Runtime/Resources/shaders/computebuffer.meta index 916c7410..8f66ff7c 100644 --- a/Samples.meta +++ b/Runtime/Resources/shaders/computebuffer.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 0e34324ad02e6491bb2e3ba81ff7b7df +guid: ad6fc8c9236144ca78ce73afd7a87833 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_cb.cginc b/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_cb.cginc new file mode 100644 index 00000000..75e27aa7 --- /dev/null +++ b/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_cb.cginc @@ -0,0 +1,27 @@ +struct vdata +{ + float2 vertex; + float2 uv; +}; + +StructuredBuffer databuffer; +StructuredBuffer indexbuffer; +int _startVertex; + +v2f vert_compute (uint vertex_id: SV_VertexID) +{ + v2f o = (v2f)0; + vdata v = databuffer[indexbuffer[_startVertex + vertex_id]]; + o.ftcoord = v.uv; + o.fpos = v.vertex; + + float3x3 mat = float3x3(_mat[0], _mat[1], _mat[2], _mat[3], _mat[4], _mat[5], 0, 0, 1); + float2 p = mul(mat, float3(v.vertex.xy, 1.0)).xy - _viewport.xy; + +#if UNITY_UV_STARTS_AT_TOP + o.vertex = float4(2.0 * p.x / _viewport.z - 1.0, 2.0 * p.y / _viewport.w - 1.0, 0, 1); +#else + o.vertex = float4(2.0 * p.x / _viewport.z - 1.0, 1.0 - 2.0 * p.y / _viewport.w, 0, 1); +#endif + return o; +} \ No newline at end of file diff --git a/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_cb.cginc.meta b/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_cb.cginc.meta new file mode 100644 index 00000000..8350461d --- /dev/null +++ b/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_cb.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 703259d9f57a14f58a79e9bb2de8195f +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_convexFill_cb.shader b/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_convexFill_cb.shader new file mode 100644 index 00000000..44113bd0 --- /dev/null +++ b/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_convexFill_cb.shader @@ -0,0 +1,76 @@ +Shader "UIWidgets/canvas_convexFill_cb" +{ + Properties + { + _SrcBlend("_SrcBlend", Int) = 1 // One + _DstBlend("_DstBlend", Int) = 10 // OneMinusSrcAlpha + _StencilComp("_StencilComp", Float) = 3 // - Equal, 8 - Always + } + + SubShader + { + ZTest Always + ZWrite Off + Blend [_SrcBlend] [_DstBlend] + + Stencil { + Ref 128 + Comp [_StencilComp] + } + + Pass { // 0, color + CGPROGRAM + #pragma require compute + #define UIWIDGETS_COLOR + #include "../UIWidgets_canvas.cginc" + #include "UIWidgets_canvas_cb.cginc" + #pragma vertex vert_compute + #pragma fragment frag + ENDCG + } + + Pass { // 1, linear + CGPROGRAM + #pragma require compute + #define UIWIDGETS_LINEAR + #include "../UIWidgets_canvas.cginc" + #include "UIWidgets_canvas_cb.cginc" + #pragma vertex vert_compute + #pragma fragment frag + ENDCG + } + + Pass { // 2, radial + CGPROGRAM + #pragma require compute + #define UIWIDGETS_RADIAL + #include "../UIWidgets_canvas.cginc" + #include "UIWidgets_canvas_cb.cginc" + #pragma vertex vert_compute + #pragma fragment frag + ENDCG + } + + Pass { // 3, sweep + CGPROGRAM + #pragma require compute + #define UIWIDGETS_SWEEP + #include "../UIWidgets_canvas.cginc" + #include "UIWidgets_canvas_cb.cginc" + #pragma vertex vert_compute + #pragma fragment frag + ENDCG + } + + Pass { // 4, image + CGPROGRAM + #pragma require compute + #define UIWIDGETS_IMAGE + #include "../UIWidgets_canvas.cginc" + #include "UIWidgets_canvas_cb.cginc" + #pragma vertex vert_compute + #pragma fragment frag + ENDCG + } + } +} \ No newline at end of file diff --git a/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_convexFill_cb.shader.meta b/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_convexFill_cb.shader.meta new file mode 100644 index 00000000..393941b3 --- /dev/null +++ b/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_convexFill_cb.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 1b5261459dc1b4070bf275274cb5dcdc +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_fill0_cb.shader b/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_fill0_cb.shader new file mode 100644 index 00000000..24ed56c1 --- /dev/null +++ b/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_fill0_cb.shader @@ -0,0 +1,33 @@ +Shader "UIWidgets/canvas_fill0_cb" +{ + Properties { + _StencilComp("_StencilComp", Float) = 3 // - Equal, 8 - Always + } + + SubShader { + ZTest Always + ZWrite Off + + Cull Off + ColorMask 0 + Stencil { + Ref 128 + CompFront [_StencilComp] + CompBack [_StencilComp] + ReadMask 128 + WriteMask 127 + PassFront IncrWrap + PassBack DecrWrap + } + + Pass { + CGPROGRAM + #pragma require compute + #include "../UIWidgets_canvas.cginc" + #include "UIWidgets_canvas_cb.cginc" + #pragma vertex vert_compute + #pragma fragment frag_stencil + ENDCG + } + } +} diff --git a/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_fill0_cb.shader.meta b/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_fill0_cb.shader.meta new file mode 100644 index 00000000..df5ea8c0 --- /dev/null +++ b/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_fill0_cb.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 8d1dce436d5e143c0a2f90e25210070a +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_fill1_cb.shader b/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_fill1_cb.shader new file mode 100644 index 00000000..6dc5a69c --- /dev/null +++ b/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_fill1_cb.shader @@ -0,0 +1,76 @@ +Shader "UIWidgets/canvas_fill1_cb" +{ + Properties { + _SrcBlend("_SrcBlend", Int) = 1 // One + _DstBlend("_DstBlend", Int) = 10 // OneMinusSrcAlpha + } + + SubShader { + ZTest Always + ZWrite Off + Blend [_SrcBlend] [_DstBlend] + + Stencil { + Ref 0 + Comp NotEqual + ReadMask 127 + WriteMask 127 + Pass Zero + } + + Pass { // 0, color + CGPROGRAM + #pragma require compute + #define UIWIDGETS_COLOR + #include "../UIWidgets_canvas.cginc" + #include "UIWidgets_canvas_cb.cginc" + #pragma vertex vert_compute + #pragma fragment frag + ENDCG + } + + Pass { // 1, linear + CGPROGRAM + #pragma require compute + #define UIWIDGETS_LINEAR + #include "../UIWidgets_canvas.cginc" + #include "UIWidgets_canvas_cb.cginc" + #pragma vertex vert_compute + #pragma fragment frag + ENDCG + } + + Pass { // 2, radial + CGPROGRAM + #pragma require compute + #define UIWIDGETS_RADIAL + #include "../UIWidgets_canvas.cginc" + #include "UIWidgets_canvas_cb.cginc" + #pragma vertex vert_compute + #pragma fragment frag + ENDCG + } + + Pass { // 3, sweep + CGPROGRAM + #pragma require compute + #define UIWIDGETS_SWEEP + #include "../UIWidgets_canvas.cginc" + #include "UIWidgets_canvas_cb.cginc" + #pragma vertex vert_compute + #pragma fragment frag + ENDCG + } + + Pass { // 4, image + CGPROGRAM + #pragma require compute + #define UIWIDGETS_IMAGE + #include "../UIWidgets_canvas.cginc" + #include "UIWidgets_canvas_cb.cginc" + #pragma vertex vert_compute + #pragma fragment frag + ENDCG + } + } +} diff --git a/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_fill1_cb.shader.meta b/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_fill1_cb.shader.meta new file mode 100644 index 00000000..dd98d8ca --- /dev/null +++ b/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_fill1_cb.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 609f86cb483334c4396d574a338c7921 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_filter_cb.shader b/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_filter_cb.shader new file mode 100644 index 00000000..336d1c2d --- /dev/null +++ b/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_filter_cb.shader @@ -0,0 +1,20 @@ +Shader "UIWidgets/canvas_filter_cb" +{ + Properties { + } + + SubShader { + ZTest Always + ZWrite Off + + Pass { // 0, mask filter + CGPROGRAM + #pragma require compute + #include "../UIWidgets_canvas.cginc" + #include "UIWidgets_canvas_cb.cginc" + #pragma vertex vert_compute + #pragma fragment frag_mf + ENDCG + } + } +} diff --git a/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_filter_cb.shader.meta b/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_filter_cb.shader.meta new file mode 100644 index 00000000..9a0fbc71 --- /dev/null +++ b/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_filter_cb.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 2c7a9c90ab5af4b02875f760080b1c51 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_shadowBox_cb.shader b/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_shadowBox_cb.shader new file mode 100644 index 00000000..fa5ec835 --- /dev/null +++ b/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_shadowBox_cb.shader @@ -0,0 +1,90 @@ +Shader "UIWidgets/ShadowBox_cb" +{ + //originally from http://madebyevan.com/shaders/fast-rounded-rectangle-shadows/ + Properties + { + _StencilComp("_StencilComp", Float) = 8 // - Equal, 8 - Always + } + SubShader + { + ZTest Always + ZWrite Off + Blend SrcAlpha OneMinusSrcAlpha + + Stencil { + Ref 128 + Comp [_StencilComp] + } + + Pass { + CGPROGRAM + #pragma require compute + + float4 _sb_box; + float4 _viewport; + float _sb_sigma; + float4 _sb_color; + float _mat[9]; + + struct vdata + { + float2 vertex; + float2 uv; + }; + + StructuredBuffer databuffer; + StructuredBuffer indexbuffer; + int _startVertex; + + struct v2f + { + float4 vertex : SV_POSITION; + float2 coord : TEXCOORD0; + }; + + float4 erf(float4 x) + { + float4 s = sign(x); + float4 a = abs(x); + x = 1.0 + (0.278393 + (0.230389 + 0.078108 * (a * a)) * a) * a; + x = x * x; + return s - s / (x * x); + return s; + } + + float boxShadow(float2 lower, float2 upper, float2 pnt, float sigma) + { + float4 query = float4(pnt - lower, pnt - upper); + float4 integral = 0.5 + 0.5 * erf(query * (sqrt(0.5) / sigma)); + return (integral.z - integral.x) * (integral.w - integral.y); + } + + v2f vert(uint vertex_id: SV_VertexID){ + v2f o; + vdata v = databuffer[indexbuffer[_startVertex + vertex_id]]; + float padding = 3.0 * _sb_sigma; + o.coord = lerp(_sb_box.xy - padding, _sb_box.zw + padding, v.vertex.xy); + float3x3 mat = float3x3(_mat[0], _mat[1], _mat[2], _mat[3], _mat[4], _mat[5], 0, 0, 1); + float2 p = mul(mat, float3(o.coord.xy, 1.0)).xy - _viewport.xy; + + #if UNITY_UV_STARTS_AT_TOP + o.vertex = float4(2.0 * p.x / _viewport.z - 1.0, 2.0 * p.y / _viewport.w - 1.0, 0, 1); + #else + o.vertex = float4(2.0 * p.x / _viewport.z - 1.0, 1.0 - 2.0 * p.y / _viewport.w, 0, 1); + #endif + return o; + } + + float4 frag(v2f i) : SV_TARGET { + float4 fragColor = _sb_color; + fragColor.a = fragColor.a * boxShadow(_sb_box.xy, _sb_box.zw, i.coord, _sb_sigma); + return fragColor; + } + + #pragma vertex vert + #pragma fragment frag + + ENDCG + } + } +} \ No newline at end of file diff --git a/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_shadowBox_cb.shader.meta b/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_shadowBox_cb.shader.meta new file mode 100644 index 00000000..9ac3b741 --- /dev/null +++ b/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_shadowBox_cb.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 444296b3078c944388a1f81cf1821808 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_shadowRBox_cb.shader b/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_shadowRBox_cb.shader new file mode 100644 index 00000000..4f411815 --- /dev/null +++ b/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_shadowRBox_cb.shader @@ -0,0 +1,123 @@ +Shader "UIWidgets/ShadowRBox_cb" +{ + //originally from http://madebyevan.com/shaders/fast-rounded-rectangle-shadows/ + Properties + { + _StencilComp("_StencilComp", Float) = 8 // - Equal, 8 - Always + } + SubShader + { + ZTest Always + ZWrite Off + Blend SrcAlpha OneMinusSrcAlpha + + Stencil { + Ref 128 + Comp [_StencilComp] + } + + Pass { + CGPROGRAM + + #pragma require compute + + float4 _sb_box; + float4 _viewport; + float _sb_sigma; + float4 _sb_color; + float _sb_corner; + float _mat[9]; + + struct vdata + { + float2 vertex; + float2 uv; + }; + + StructuredBuffer databuffer; + StructuredBuffer indexbuffer; + int _startVertex; + + struct v2f + { + float4 vertex : SV_POSITION; + float2 coord : TEXCOORD0; + }; + + float gaussian(float x, float sigma) + { + float pi = 3.141592653589793; + return exp(-(x*x) / (2.0 * sigma * sigma)) / (sqrt(2.0 * pi) * sigma); + } + + float2 erf(float2 x) + { + float2 s = sign(x); + float2 a = abs(x); + x = 1.0 + (0.278393 + (0.230389 + 0.078108 * (a * a)) * a) * a; + x = x * x; + return s - s / (x * x); + return s; + } + + float roundedBoxShadowX(float x, float y, float sigma, float corner, float2 halfSize) + { + float delta = min(halfSize.y - corner - abs(y), 0.0); + float curved = halfSize.x - corner + sqrt(max(0.0, corner * corner - delta * delta)); + float2 integral = 0.5 + 0.5 * erf((x + float2(-curved, curved)) * (sqrt(0.5)/sigma)); + return integral.y - integral.x; + } + + float roundedBoxShadow(float2 lower, float2 upper, float2 pnt, float sigma, float corner) + { + float2 center = (lower + upper) * 0.5; + float2 halfSize = (upper - lower) * 0.5; + pnt -= center; + + float low = pnt.y - halfSize.y; + float high = pnt.y + halfSize.y; + float start = clamp(-3.0 * sigma, low, high); + float end = clamp(3.0 * sigma, low, high); + + float step = (end - start) / 4.0; + float y = start + step * 0.5; + float value = 0.0; + + for(int i=0; i<4;i++) + { + value += roundedBoxShadowX(pnt.x, pnt.y - y, sigma, corner, halfSize) * gaussian(y, sigma) * step; + y += step; + } + + return value; + } + + v2f vert(uint vertex_id: SV_VertexID){ + v2f o; + vdata v = databuffer[indexbuffer[_startVertex + vertex_id]]; + float padding = 3.0 * _sb_sigma; + o.coord = lerp(_sb_box.xy - padding, _sb_box.zw + padding, v.vertex.xy); + float3x3 mat = float3x3(_mat[0], _mat[1], _mat[2], _mat[3], _mat[4], _mat[5], 0, 0, 1); + float2 p = mul(mat, float3(o.coord.xy, 1.0)).xy - _viewport.xy; + + #if UNITY_UV_STARTS_AT_TOP + o.vertex = float4(2.0 * p.x / _viewport.z - 1.0, 2.0 * p.y / _viewport.w - 1.0, 0, 1); + #else + o.vertex = float4(2.0 * p.x / _viewport.z - 1.0, 1.0 - 2.0 * p.y / _viewport.w, 0, 1); + #endif + return o; + } + + float4 frag(v2f i) : SV_TARGET { + float4 fragColor = _sb_color; + fragColor.a = fragColor.a * roundedBoxShadow(_sb_box.xy, _sb_box.zw, i.coord, _sb_sigma, _sb_corner); + return fragColor; + } + + #pragma vertex vert + #pragma fragment frag + + ENDCG + } + } +} \ No newline at end of file diff --git a/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_shadowRBox_cb.shader.meta b/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_shadowRBox_cb.shader.meta new file mode 100644 index 00000000..25227b29 --- /dev/null +++ b/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_shadowRBox_cb.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 4037f8954a4124abf93d3ff663baa78d +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_stencil_cb.shader b/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_stencil_cb.shader new file mode 100644 index 00000000..3af2d190 --- /dev/null +++ b/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_stencil_cb.shader @@ -0,0 +1,62 @@ +Shader "UIWidgets/canvas_stencil_cb" +{ + Properties { + } + + SubShader { + ZTest Always + ZWrite Off + + Pass { // 0, stencil clear + ColorMask 0 + Stencil { + Ref 128 + Pass Replace + } + + CGPROGRAM + #pragma require compute + #include "../UIWidgets_canvas.cginc" + #include "UIWidgets_canvas_cb.cginc" + #pragma vertex vert_compute + #pragma fragment frag_stencil + ENDCG + } + + Pass { // 1, stencil intersect 0 + Cull Off + ColorMask 0 + Stencil { + WriteMask 127 + PassFront IncrWrap + PassBack DecrWrap + } + + CGPROGRAM + #pragma require compute + #include "../UIWidgets_canvas.cginc" + #include "UIWidgets_canvas_cb.cginc" + #pragma vertex vert_compute + #pragma fragment frag_stencil + ENDCG + } + + Pass { // 2, stencil intersect 1 + ColorMask 0 + Stencil { + Ref 128 + Comp Less + Pass Replace + Fail Zero + } + + CGPROGRAM + #pragma require compute + #include "../UIWidgets_canvas.cginc" + #include "UIWidgets_canvas_cb.cginc" + #pragma vertex vert_compute + #pragma fragment frag_stencil + ENDCG + } + } +} diff --git a/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_stencil_cb.shader.meta b/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_stencil_cb.shader.meta new file mode 100644 index 00000000..c92082fa --- /dev/null +++ b/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_stencil_cb.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 6c8a50e3adb8349e0a98bd0de080c7e5 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_stroke0_cb.shader b/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_stroke0_cb.shader new file mode 100644 index 00000000..b35882f7 --- /dev/null +++ b/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_stroke0_cb.shader @@ -0,0 +1,75 @@ +Shader "UIWidgets/canvas_stroke0_cb" +{ + Properties { + _SrcBlend("_SrcBlend", Int) = 1 // One + _DstBlend("_DstBlend", Int) = 10 // OneMinusSrcAlpha + _StencilComp("_StencilComp", Float) = 3 // - Equal, 8 - Always + } + + SubShader { + ZTest Always + ZWrite Off + Blend [_SrcBlend] [_DstBlend] + + Stencil { + Ref 128 + Comp [_StencilComp] + Pass IncrSat + } + + Pass { // 0, color + CGPROGRAM + #pragma require compute + #define UIWIDGETS_COLOR + #include "../UIWidgets_canvas.cginc" + #include "UIWidgets_canvas_cb.cginc" + #pragma vertex vert_compute + #pragma fragment frag + ENDCG + } + + Pass { // 1, linear + CGPROGRAM + #pragma require compute + #define UIWIDGETS_LINEAR + #include "../UIWidgets_canvas.cginc" + #include "UIWidgets_canvas_cb.cginc" + #pragma vertex vert_compute + #pragma fragment frag + ENDCG + } + + Pass { // 2, radial + CGPROGRAM + #pragma require compute + #define UIWIDGETS_RADIAL + #include "../UIWidgets_canvas.cginc" + #include "UIWidgets_canvas_cb.cginc" + #pragma vertex vert_compute + #pragma fragment frag + ENDCG + } + + Pass { // 3, sweep + CGPROGRAM + #pragma require compute + #define UIWIDGETS_SWEEP + #include "../UIWidgets_canvas.cginc" + #include "UIWidgets_canvas_cb.cginc" + #pragma vertex vert_compute + #pragma fragment frag + ENDCG + } + + Pass { // 4, image + CGPROGRAM + #pragma require compute + #define UIWIDGETS_IMAGE + #include "../UIWidgets_canvas.cginc" + #include "UIWidgets_canvas_cb.cginc" + #pragma vertex vert_compute + #pragma fragment frag + ENDCG + } + } +} diff --git a/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_stroke0_cb.shader.meta b/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_stroke0_cb.shader.meta new file mode 100644 index 00000000..4740ef20 --- /dev/null +++ b/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_stroke0_cb.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 813531ada8c4e40c597b19027ac7fc87 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_stroke1_cb.shader b/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_stroke1_cb.shader new file mode 100644 index 00000000..2929dddf --- /dev/null +++ b/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_stroke1_cb.shader @@ -0,0 +1,29 @@ +Shader "UIWidgets/canvas_stroke1_cb" +{ + Properties { + } + + SubShader { + ZTest Always + ZWrite Off + + ColorMask 0 + Stencil { + Ref 0 + Comp NotEqual + ReadMask 127 + WriteMask 127 + Pass Zero + } + + Pass { + CGPROGRAM + #pragma require compute + #include "../UIWidgets_canvas.cginc" + #include "UIWidgets_canvas_cb.cginc" + #pragma vertex vert_compute + #pragma fragment frag_stencil + ENDCG + } + } +} diff --git a/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_stroke1_cb.shader.meta b/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_stroke1_cb.shader.meta new file mode 100644 index 00000000..bbc712a6 --- /dev/null +++ b/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_stroke1_cb.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 5bde36357cad4438faa8e580cd85f2cd +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_strokeAlpha_cb.shader b/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_strokeAlpha_cb.shader new file mode 100644 index 00000000..2f8b022f --- /dev/null +++ b/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_strokeAlpha_cb.shader @@ -0,0 +1,75 @@ +Shader "UIWidgets/canvas_strokeAlpha_cb" +{ + Properties { + _SrcBlend("_SrcBlend", Int) = 1 // One + _DstBlend("_DstBlend", Int) = 10 // OneMinusSrcAlpha + _StencilComp("_StencilComp", Float) = 3 // - Equal, 8 - Always + } + + SubShader { + ZTest Always + ZWrite Off + Blend [_SrcBlend] [_DstBlend] + + Stencil { + Ref 128 + Comp [_StencilComp] + Pass IncrSat + } + + Pass { // 0, color + CGPROGRAM + #pragma require compute + #define UIWIDGETS_COLOR + #include "../UIWidgets_canvas.cginc" + #include "UIWidgets_canvas_cb.cginc" + #pragma vertex vert_compute + #pragma fragment frag_stroke_alpha + ENDCG + } + + Pass { // 1, linear + CGPROGRAM + #pragma require compute + #define UIWIDGETS_LINEAR + #include "../UIWidgets_canvas.cginc" + #include "UIWidgets_canvas_cb.cginc" + #pragma vertex vert_compute + #pragma fragment frag_stroke_alpha + ENDCG + } + + Pass { // 2, radial + CGPROGRAM + #pragma require compute + #define UIWIDGETS_RADIAL + #include "../UIWidgets_canvas.cginc" + #include "UIWidgets_canvas_cb.cginc" + #pragma vertex vert_compute + #pragma fragment frag_stroke_alpha + ENDCG + } + + Pass { // 3, sweep + CGPROGRAM + #pragma require compute + #define UIWIDGETS_SWEEP + #include "../UIWidgets_canvas.cginc" + #include "UIWidgets_canvas_cb.cginc" + #pragma vertex vert_compute + #pragma fragment frag_stroke_alpha + ENDCG + } + + Pass { // 4, image + CGPROGRAM + #pragma require compute + #define UIWIDGETS_IMAGE + #include "../UIWidgets_canvas.cginc" + #include "UIWidgets_canvas_cb.cginc" + #pragma vertex vert_compute + #pragma fragment frag_stroke_alpha + ENDCG + } + } +} diff --git a/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_strokeAlpha_cb.shader.meta b/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_strokeAlpha_cb.shader.meta new file mode 100644 index 00000000..2e2d4911 --- /dev/null +++ b/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_strokeAlpha_cb.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: b6b3fce2866044f15aa7571d9d983a93 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_tex_cb.shader b/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_tex_cb.shader new file mode 100644 index 00000000..1538d4d5 --- /dev/null +++ b/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_tex_cb.shader @@ -0,0 +1,74 @@ +Shader "UIWidgets/canvas_tex_cb" +{ + Properties { + _SrcBlend("_SrcBlend", Int) = 1 // One + _DstBlend("_DstBlend", Int) = 10 // OneMinusSrcAlpha + _StencilComp("_StencilComp", Float) = 3 // - Equal, 8 - Always + } + + SubShader { + ZTest Always + ZWrite Off + Blend [_SrcBlend] [_DstBlend] + + Stencil { + Ref 128 + Comp [_StencilComp] + } + + Pass { // 0, color + CGPROGRAM + #pragma require compute + #define UIWIDGETS_COLOR + #include "../UIWidgets_canvas.cginc" + #include "UIWidgets_canvas_cb.cginc" + #pragma vertex vert_compute + #pragma fragment frag_tex + ENDCG + } + + Pass { // 1, linear + CGPROGRAM + #pragma require compute + #define UIWIDGETS_LINEAR + #include "../UIWidgets_canvas.cginc" + #include "UIWidgets_canvas_cb.cginc" + #pragma vertex vert_compute + #pragma fragment frag_tex + ENDCG + } + + Pass { // 2, radial + CGPROGRAM + #pragma require compute + #define UIWIDGETS_RADIAL + #include "../UIWidgets_canvas.cginc" + #include "UIWidgets_canvas_cb.cginc" + #pragma vertex vert_compute + #pragma fragment frag_tex + ENDCG + } + + Pass { // 3, sweep + CGPROGRAM + #pragma require compute + #define UIWIDGETS_SWEEP + #include "../UIWidgets_canvas.cginc" + #include "UIWidgets_canvas_cb.cginc" + #pragma vertex vert_compute + #pragma fragment frag_tex + ENDCG + } + + Pass { // 4, image + CGPROGRAM + #pragma require compute + #define UIWIDGETS_IMAGE + #include "../UIWidgets_canvas.cginc" + #include "UIWidgets_canvas_cb.cginc" + #pragma vertex vert_compute + #pragma fragment frag_tex + ENDCG + } + } +} diff --git a/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_tex_cb.shader.meta b/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_tex_cb.shader.meta new file mode 100644 index 00000000..c7461ef6 --- /dev/null +++ b/Runtime/Resources/shaders/computebuffer/UIWidgets_canvas_tex_cb.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: e87b6538afcca45d5af06b744d26e3bb +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/RuntimeExample.cs b/Runtime/RuntimeExample.cs deleted file mode 100644 index 12348a63..00000000 --- a/Runtime/RuntimeExample.cs +++ /dev/null @@ -1,27 +0,0 @@ -// ----------------------------------------------------------------------------- -// -// Use this runtime example C# file to develop runtime code. -// -// ----------------------------------------------------------------------------- - -namespace Unity.UIWidgets { - /// - /// Provide a general description of the public class. - /// - /// - /// Packages require XmlDoc documentation for ALL Package APIs. - /// https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/xmldoc/xml-documentation-comments - /// - public class MyPublicRuntimeExampleClass { - /// - /// Provide a description of what this private method does. - /// - /// Description of parameter 1 - /// Description of parameter 2 - /// Description of parameter 3 - /// Description of what the function returns - public int CountThingsAndDoStuff(int parameter1, int parameter2, bool parameter3) { - return parameter3 ? (parameter1 + parameter2) : (parameter1 - parameter2); - } - } -} \ No newline at end of file diff --git a/Runtime/animation/curves.cs b/Runtime/animation/curves.cs index 13940b73..aa0e68b2 100644 --- a/Runtime/animation/curves.cs +++ b/Runtime/animation/curves.cs @@ -1,10 +1,22 @@ +using System; using Unity.UIWidgets.foundation; using Unity.UIWidgets.ui; using UnityEngine; namespace Unity.UIWidgets.animation { public abstract class Curve { - public abstract float transform(float t); + public float transform(float t) { + D.assert(t >= 0.0f && t <= 1.0f); + if (t == 0.0f || t == 1.0f) { + return t; + } + + return this.transformInternal(t); + } + + protected virtual float transformInternal(float t) { + throw new NotImplementedException(); + } public Curve flipped { get { return new FlippedCurve(this); } @@ -16,7 +28,7 @@ public override string ToString() { } class _Linear : Curve { - public override float transform(float t) { + protected override float transformInternal(float t) { return t; } } @@ -28,12 +40,7 @@ public SawTooth(int count) { public readonly int count; - public override float transform(float t) { - D.assert(t >= 0.0 && t <= 1.0); - if (t == 1.0f) { - return 1.0f; - } - + protected override float transformInternal(float t) { t *= this.count; return t - (int) t; } @@ -56,17 +63,13 @@ public Interval(float begin, float end, Curve curve = null) { public readonly Curve curve; - public override float transform(float t) { + protected override float transformInternal(float t) { D.assert(t >= 0.0 && t <= 1.0); D.assert(this.begin >= 0.0); D.assert(this.begin <= 1.0); D.assert(this.end >= 0.0); D.assert(this.end <= 1.0); D.assert(this.end >= this.begin); - if (t == 0.0 || t == 1.0) { - return t; - } - t = ((t - this.begin) / (this.end - this.begin)).clamp(0.0f, 1.0f); if (t == 0.0 || t == 1.0) { return t; @@ -91,14 +94,9 @@ public Threshold(float threshold) { public readonly float threshold; - public override float transform(float t) { - D.assert(t >= 0.0 && t <= 1.0); + protected override float transformInternal(float t) { D.assert(this.threshold >= 0.0); D.assert(this.threshold <= 1.0); - if (t == 0.0 || t == 1.0) { - return t; - } - return t < this.threshold ? 0.0f : 1.0f; } } @@ -127,9 +125,7 @@ float _evaluateCubic(float a, float b, float m) { m * m * m; } - public override float transform(float t) { - D.assert(t >= 0.0 && t <= 1.0); - + protected override float transformInternal(float t) { float start = 0.0f; float end = 1.0f; while (true) { @@ -161,7 +157,7 @@ public FlippedCurve(Curve curve) { public readonly Curve curve; - public override float transform(float t) { + protected override float transformInternal(float t) { return 1.0f - this.curve.transform(1.0f - t); } @@ -174,8 +170,7 @@ class _DecelerateCurve : Curve { internal _DecelerateCurve() { } - public override float transform(float t) { - D.assert(t >= 0.0 && t <= 1.0); + protected override float transformInternal(float t) { t = 1.0f - t; return 1.0f - t * t; } @@ -185,8 +180,7 @@ class _BounceInCurve : Curve { internal _BounceInCurve() { } - public override float transform(float t) { - D.assert(t >= 0.0 && t <= 1.0); + protected override float transformInternal(float t) { return 1.0f - Curves._bounce(1.0f - t); } } @@ -195,8 +189,7 @@ class _BounceOutCurve : Curve { internal _BounceOutCurve() { } - public override float transform(float t) { - D.assert(t >= 0.0f && t <= 1.0f); + protected override float transformInternal(float t) { return Curves._bounce(t); } } @@ -205,8 +198,7 @@ class _BounceInOutCurve : Curve { internal _BounceInOutCurve() { } - public override float transform(float t) { - D.assert(t >= 0.0 && t <= 1.0f); + protected override float transformInternal(float t) { if (t < 0.5f) { return (1.0f - Curves._bounce(1.0f - t)) * 0.5f; } @@ -223,8 +215,7 @@ public ElasticInCurve(float period = 0.4f) { public readonly float period; - public override float transform(float t) { - D.assert(t >= 0.0 && t <= 1.0); + protected override float transformInternal(float t) { float s = this.period / 4.0f; t = t - 1.0f; return -Mathf.Pow(2.0f, 10.0f * t) * Mathf.Sin((t - s) * (Mathf.PI * 2.0f) / this.period); @@ -242,8 +233,7 @@ public ElasticOutCurve(float period = 0.4f) { public readonly float period; - public override float transform(float t) { - D.assert(t >= 0.0 && t <= 1.0); + protected override float transformInternal(float t) { float s = this.period / 4.0f; return Mathf.Pow(2.0f, -10.0f * t) * Mathf.Sin((t - s) * (Mathf.PI * 2.0f) / this.period) + 1.0f; } @@ -260,8 +250,7 @@ public ElasticInOutCurve(float period = 0.4f) { public readonly float period; - public override float transform(float t) { - D.assert(t >= 0.0 && t <= 1.0); + protected override float transformInternal(float t) { float s = this.period / 4.0f; t = 2.0f * t - 1.0f; if (t < 0.0) { @@ -345,7 +334,9 @@ public static class Curves { public static readonly Cubic easeInOutBack = new Cubic(0.68f, -0.55f, 0.265f, 1.55f); - public static readonly Curve fastOutSlowIn = new Cubic(0.4f, 0.0f, 0.2f, 1.0f); + public static readonly Cubic fastOutSlowIn = new Cubic(0.4f, 0.0f, 0.2f, 1.0f); + + public static readonly Cubic slowMiddle = new Cubic(0.15f, 0.85f, 0.85f, 0.15f); public static readonly Curve bounceIn = new _BounceInCurve(); diff --git a/Runtime/cupertino.meta b/Runtime/cupertino.meta new file mode 100644 index 00000000..e7263416 --- /dev/null +++ b/Runtime/cupertino.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 30914a0a38eca48bfa7c425f084a3684 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/cupertino/action_sheet.cs b/Runtime/cupertino/action_sheet.cs new file mode 100644 index 00000000..d1662fb6 --- /dev/null +++ b/Runtime/cupertino/action_sheet.cs @@ -0,0 +1,1098 @@ +using System.Collections.Generic; +using Unity.UIWidgets.foundation; +using Unity.UIWidgets.gestures; +using Unity.UIWidgets.painting; +using Unity.UIWidgets.rendering; +using Unity.UIWidgets.ui; +using Unity.UIWidgets.widgets; +using TextStyle = Unity.UIWidgets.painting.TextStyle; + +namespace Unity.UIWidgets.cupertino { + class CupertinoActionSheetUtils { + public static readonly TextStyle _kActionSheetActionStyle = new TextStyle( + // fontFamily: ".SF UI Text", + fontFamily: ".SF Pro Text", + inherit: false, + fontSize: 20.0f, + fontWeight: FontWeight.w400, + color: CupertinoColors.activeBlue, + textBaseline: TextBaseline.alphabetic + ); + + public static readonly TextStyle _kActionSheetContentStyle = new TextStyle( + // fontFamily: ".SF UI Text", + fontFamily: ".SF Pro Text", + inherit: false, + fontSize: 13.0f, + fontWeight: FontWeight.w400, + color: _kContentTextColor, + textBaseline: TextBaseline.alphabetic + ); + + public static readonly BoxDecoration _kAlertBlurOverlayDecoration = new BoxDecoration( + color: CupertinoColors.white, + backgroundBlendMode: BlendMode.overlay + ); + + public static readonly Color _kBackgroundColor = new Color(0xD1F8F8F8); + public static readonly Color _kPressedColor = new Color(0xA6E5E5EA); + public static readonly Color _kButtonDividerColor = new Color(0x403F3F3F); + public static readonly Color _kContentTextColor = new Color(0xFF8F8F8F); + public static readonly Color _kCancelButtonPressedColor = new Color(0xFFEAEAEA); + + public const float _kBlurAmount = 20.0f; + public const float _kEdgeHorizontalPadding = 8.0f; + public const float _kCancelButtonPadding = 8.0f; + public const float _kEdgeVerticalPadding = 10.0f; + public const float _kContentHorizontalPadding = 40.0f; + public const float _kContentVerticalPadding = 14.0f; + public const float _kButtonHeight = 56.0f; + public const float _kCornerRadius = 14.0f; + public const float _kDividerThickness = 1.0f; + } + + public class CupertinoActionSheet : StatelessWidget { + public CupertinoActionSheet( + Key key = null, + Widget title = null, + Widget message = null, + List actions = null, + ScrollController messageScrollController = null, + ScrollController actionScrollController = null, + Widget cancelButton = null + ) : base(key: key) { + D.assert(actions != null || title != null || message != null || cancelButton != null, + () => + "An action sheet must have a non-null value for at least one of the following arguments: actions, title, message, or cancelButton"); + this.title = title; + this.message = message; + this.actions = actions ?? new List(); + this.messageScrollController = messageScrollController; + this.actionScrollController = actionScrollController; + this.cancelButton = cancelButton; + } + + public readonly Widget title; + public readonly Widget message; + public readonly List actions; + public readonly ScrollController messageScrollController; + public readonly ScrollController actionScrollController; + public readonly Widget cancelButton; + + Widget _buildContent() { + List content = new List(); + if (this.title != null || this.message != null) { + Widget titleSection = new _CupertinoAlertContentSection( + title: this.title, + message: this.message, + scrollController: this.messageScrollController + ); + content.Add(new Flexible(child: titleSection)); + } + + return new Container( + color: CupertinoActionSheetUtils._kBackgroundColor, + child: new Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: content + ) + ); + } + + Widget _buildActions() { + if (this.actions == null || this.actions.isEmpty()) { + return new Container(height: 0.0f); + } + + return new Container( + child: new _CupertinoAlertActionSection( + children: this.actions, + scrollController: this.actionScrollController, + hasCancelButton: this.cancelButton != null + ) + ); + } + + Widget _buildCancelButton() { + float cancelPadding = (this.actions != null || this.message != null || this.title != null) + ? CupertinoActionSheetUtils._kCancelButtonPadding + : 0.0f; + return new Padding( + padding: EdgeInsets.only(top: cancelPadding), + child: new _CupertinoActionSheetCancelButton( + child: this.cancelButton + ) + ); + } + + public override Widget build(BuildContext context) { + List children = new List { + new Flexible(child: new ClipRRect( + borderRadius: BorderRadius.circular(12.0f), + child: new BackdropFilter( + filter: ImageFilter.blur(sigmaX: CupertinoActionSheetUtils._kBlurAmount, + sigmaY: CupertinoActionSheetUtils._kBlurAmount), + child: new Container( + decoration: CupertinoActionSheetUtils._kAlertBlurOverlayDecoration, + child: new _CupertinoAlertRenderWidget( + contentSection: this._buildContent(), + actionsSection: this._buildActions() + ) + ) + ) + ) + ), + }; + + if (this.cancelButton != null) { + children.Add(this._buildCancelButton() + ); + } + + Orientation orientation = MediaQuery.of(context).orientation; + + float actionSheetWidth; + if (orientation == Orientation.portrait) { + actionSheetWidth = MediaQuery.of(context).size.width - + (CupertinoActionSheetUtils._kEdgeHorizontalPadding * 2); + } + else { + actionSheetWidth = MediaQuery.of(context).size.height - + (CupertinoActionSheetUtils._kEdgeHorizontalPadding * 2); + } + + return new SafeArea( + child: new Container( + width: actionSheetWidth, + margin: EdgeInsets.symmetric( + horizontal: CupertinoActionSheetUtils._kEdgeHorizontalPadding, + vertical: CupertinoActionSheetUtils._kEdgeVerticalPadding + ), + child: new Column( + children: children, + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.stretch + ) + ) + ); + } + } + + + public class CupertinoActionSheetAction : StatelessWidget { + public CupertinoActionSheetAction( + Widget child, + VoidCallback onPressed, + bool isDefaultAction = false, + bool isDestructiveAction = false + ) { + D.assert(child != null); + D.assert(onPressed != null); + this.child = child; + this.onPressed = onPressed; + this.isDefaultAction = isDefaultAction; + this.isDestructiveAction = isDestructiveAction; + } + + public readonly VoidCallback onPressed; + public readonly bool isDefaultAction; + public readonly bool isDestructiveAction; + public readonly Widget child; + + public override Widget build(BuildContext context) { + TextStyle style = CupertinoActionSheetUtils._kActionSheetActionStyle; + + if (this.isDefaultAction) { + style = style.copyWith(fontWeight: FontWeight.w600); + } + + if (this.isDestructiveAction) { + style = style.copyWith(color: CupertinoColors.destructiveRed); + } + + return new GestureDetector( + onTap: () => this.onPressed(), + behavior: HitTestBehavior.opaque, + child: new ConstrainedBox( + constraints: new BoxConstraints( + minHeight: CupertinoActionSheetUtils._kButtonHeight + ), + child: new Container( + alignment: Alignment.center, + padding: EdgeInsets.symmetric( + vertical: 16.0f, + horizontal: 10.0f + ), + child: new DefaultTextStyle( + style: style, + child: this.child, + textAlign: TextAlign.center + ) + ) + ) + ); + } + } + + class _CupertinoActionSheetCancelButton : StatefulWidget { + public _CupertinoActionSheetCancelButton( + Key key = null, + Widget child = null + ) : base(key: key) { + this.child = child; + } + + public readonly Widget child; + + public override State createState() { + return new _CupertinoActionSheetCancelButtonState(); + } + } + + class _CupertinoActionSheetCancelButtonState : State<_CupertinoActionSheetCancelButton> { + Color _backgroundColor; + + public override void initState() { + this._backgroundColor = CupertinoColors.white; + base.initState(); + } + + void _onTapDown(TapDownDetails evt) { + this.setState(() => { this._backgroundColor = CupertinoActionSheetUtils._kCancelButtonPressedColor; }); + } + + void _onTapUp(TapUpDetails evt) { + this.setState(() => { this._backgroundColor = CupertinoColors.white; }); + } + + void _onTapCancel() { + this.setState(() => { this._backgroundColor = CupertinoColors.white; }); + } + + public override Widget build(BuildContext context) { + return new GestureDetector( + onTapDown: this._onTapDown, + onTapUp: this._onTapUp, + onTapCancel: this._onTapCancel, + child: new Container( + decoration: new BoxDecoration( + color: this._backgroundColor, + borderRadius: BorderRadius.circular(CupertinoActionSheetUtils._kCornerRadius) + ), + child: this.widget.child + ) + ); + } + } + + class _CupertinoAlertRenderWidget : RenderObjectWidget { + public _CupertinoAlertRenderWidget( + Widget contentSection, + Widget actionsSection, + Key key = null + ) : base(key: key) { + this.contentSection = contentSection; + this.actionsSection = actionsSection; + } + + public readonly Widget contentSection; + public readonly Widget actionsSection; + + public override RenderObject createRenderObject(BuildContext context) { + return new _RenderCupertinoAlert( + dividerThickness: CupertinoActionSheetUtils._kDividerThickness / + MediaQuery.of(context).devicePixelRatio + ); + } + + public override Element createElement() { + return new _CupertinoAlertRenderElement(this); + } + } + + class _CupertinoAlertRenderElement : RenderObjectElement { + public _CupertinoAlertRenderElement(_CupertinoAlertRenderWidget widget) : base(widget) { } + + Element _contentElement; + Element _actionsElement; + + public new _CupertinoAlertRenderWidget widget { + get { return base.widget as _CupertinoAlertRenderWidget; } + } + + public new _RenderCupertinoAlert renderObject { + get { return base.renderObject as _RenderCupertinoAlert; } + } + + public override void visitChildren(ElementVisitor visitor) { + if (this._contentElement != null) { + visitor(this._contentElement); + } + + if (this._actionsElement != null) { + visitor(this._actionsElement); + } + } + + public override void mount(Element parent, object newSlot) { + base.mount(parent, newSlot); + this._contentElement = this.updateChild(this._contentElement, this.widget.contentSection, + _AlertSections.contentSection); + this._actionsElement = this.updateChild(this._actionsElement, this.widget.actionsSection, + _AlertSections.actionsSection); + } + + protected override void insertChildRenderObject(RenderObject child, object slot) { + this._placeChildInSlot(child, slot); + } + + protected override void moveChildRenderObject(RenderObject child, object slot) { + this._placeChildInSlot(child, slot); + } + + public override void update(Widget newWidget) { + base.update(newWidget); + this._contentElement = this.updateChild(this._contentElement, this.widget.contentSection, + _AlertSections.contentSection); + this._actionsElement = this.updateChild(this._actionsElement, this.widget.actionsSection, + _AlertSections.actionsSection); + } + + protected override void forgetChild(Element child) { + D.assert(child == this._contentElement || child == this._actionsElement); + if (this._contentElement == child) { + this._contentElement = null; + } + else if (this._actionsElement == child) { + this._actionsElement = null; + } + } + + protected override void removeChildRenderObject(RenderObject child) { + D.assert(child == this.renderObject.contentSection || child == this.renderObject.actionsSection); + if (this.renderObject.contentSection == child) { + this.renderObject.contentSection = null; + } + else if (this.renderObject.actionsSection == child) { + this.renderObject.actionsSection = null; + } + } + + void _placeChildInSlot(RenderObject child, object slot) { + switch ((_AlertSections) slot) { + case _AlertSections.contentSection: + this.renderObject.contentSection = child as RenderBox; + break; + case _AlertSections.actionsSection: + this.renderObject.actionsSection = child as RenderBox; + ; + break; + } + } + } + + + class _RenderCupertinoAlert : RenderBox { + public _RenderCupertinoAlert( + RenderBox contentSection = null, + RenderBox actionsSection = null, + float dividerThickness = 0.0f + ) { + this._contentSection = contentSection; + this._actionsSection = actionsSection; + this._dividerThickness = dividerThickness; + } + + public RenderBox contentSection { + get { return this._contentSection; } + set { + if (value != this._contentSection) { + if (null != this._contentSection) { + this.dropChild(this._contentSection); + } + + this._contentSection = value; + if (null != this._contentSection) { + this.adoptChild(this._contentSection); + } + } + } + } + + RenderBox _contentSection; + + + public RenderBox actionsSection { + get { return this._actionsSection; } + set { + if (value != this._actionsSection) { + if (null != this._actionsSection) { + this.dropChild(this._actionsSection); + } + + this._actionsSection = value; + if (null != this._actionsSection) { + this.adoptChild(this._actionsSection); + } + } + } + } + + RenderBox _actionsSection; + + readonly float _dividerThickness; + + readonly Paint _dividerPaint = new Paint() { + color = CupertinoActionSheetUtils._kButtonDividerColor, + style = PaintingStyle.fill + }; + + public override void attach(object owner) { + base.attach(owner); + if (null != this.contentSection) { + this.contentSection.attach(owner); + } + + if (null != this.actionsSection) { + this.actionsSection.attach(owner); + } + } + + public override void detach() { + base.detach(); + if (null != this.contentSection) { + this.contentSection.detach(); + } + + if (null != this.actionsSection) { + this.actionsSection.detach(); + } + } + + public override void redepthChildren() { + if (null != this.contentSection) { + this.redepthChild(this.contentSection); + } + + if (null != this.actionsSection) { + this.redepthChild(this.actionsSection); + } + } + + public override void setupParentData(RenderObject child) { + if (!(child.parentData is MultiChildLayoutParentData)) { + child.parentData = new MultiChildLayoutParentData(); + } + } + + public override void visitChildren(RenderObjectVisitor visitor) { + if (this.contentSection != null) { + visitor(this.contentSection); + } + + if (this.actionsSection != null) { + visitor(this.actionsSection); + } + } + + public override List debugDescribeChildren() { + List value = new List(); + if (this.contentSection != null) { + value.Add(this.contentSection.toDiagnosticsNode(name: "content")); + } + + if (this.actionsSection != null) { + value.Add(this.actionsSection.toDiagnosticsNode(name: "actions")); + } + + return value; + } + + protected override float computeMinIntrinsicWidth(float height) { + return this.constraints.minWidth; + } + + protected override float computeMaxIntrinsicWidth(float height) { + return this.constraints.maxWidth; + } + + protected override float computeMinIntrinsicHeight(float width) { + float contentHeight = this.contentSection.getMinIntrinsicHeight(width); + float actionsHeight = this.actionsSection.getMinIntrinsicHeight(width); + bool hasDivider = contentHeight > 0.0f && actionsHeight > 0.0f; + float height = contentHeight + (hasDivider ? this._dividerThickness : 0.0f) + actionsHeight; + + if (actionsHeight > 0 || contentHeight > 0) { + height -= 2 * CupertinoActionSheetUtils._kEdgeVerticalPadding; + } + + if (height.isFinite()) { + return height; + } + + return 0.0f; + } + + protected internal override float computeMaxIntrinsicHeight(float width) { + float contentHeight = this.contentSection.getMaxIntrinsicHeight(width); + float actionsHeight = this.actionsSection.getMaxIntrinsicHeight(width); + bool hasDivider = contentHeight > 0.0f && actionsHeight > 0.0f; + float height = contentHeight + (hasDivider ? this._dividerThickness : 0.0f) + actionsHeight; + + if (actionsHeight > 0 || contentHeight > 0) { + height -= 2 * CupertinoActionSheetUtils._kEdgeVerticalPadding; + } + + if (height.isFinite()) { + return height; + } + + return 0.0f; + } + + protected override void performLayout() { + bool hasDivider = this.contentSection.getMaxIntrinsicHeight(this.constraints.maxWidth) > 0.0f + && this.actionsSection.getMaxIntrinsicHeight(this.constraints.maxWidth) > 0.0f; + float dividerThickness = hasDivider ? this._dividerThickness : 0.0f; + + float minActionsHeight = this.actionsSection.getMinIntrinsicHeight(this.constraints.maxWidth); + + + this.contentSection.layout( + this.constraints.deflate(EdgeInsets.only(bottom: minActionsHeight + dividerThickness)), + parentUsesSize: true + ); + Size contentSize = this.contentSection.size; + + + this.actionsSection.layout( + this.constraints.deflate(EdgeInsets.only(top: contentSize.height + dividerThickness)), + parentUsesSize: true + ); + Size actionsSize = this.actionsSection.size; + + + float actionSheetHeight = contentSize.height + dividerThickness + actionsSize.height; + + + this.size = new Size(this.constraints.maxWidth, actionSheetHeight); + + + D.assert(this.actionsSection.parentData is MultiChildLayoutParentData); + MultiChildLayoutParentData actionParentData = this.actionsSection.parentData as MultiChildLayoutParentData; + actionParentData.offset = new Offset(0.0f, contentSize.height + dividerThickness); + } + + public override void paint(PaintingContext context, Offset offset) { + MultiChildLayoutParentData contentParentData = this.contentSection.parentData as MultiChildLayoutParentData; + this.contentSection.paint(context, offset + contentParentData.offset); + + bool hasDivider = this.contentSection.size.height > 0.0f && this.actionsSection.size.height > 0.0f; + if (hasDivider) { + this._paintDividerBetweenContentAndActions(context.canvas, offset); + } + + MultiChildLayoutParentData actionsParentData = this.actionsSection.parentData as MultiChildLayoutParentData; + this.actionsSection.paint(context, offset + actionsParentData.offset); + } + + void _paintDividerBetweenContentAndActions(Canvas canvas, Offset offset) { + canvas.drawRect( + Rect.fromLTWH( + offset.dx, + offset.dy + this.contentSection.size.height, this.size.width, this._dividerThickness + ), this._dividerPaint + ); + } + + protected override bool hitTestChildren(HitTestResult result, Offset position = null) { + bool isHit = false; + MultiChildLayoutParentData contentSectionParentData = + this.contentSection.parentData as MultiChildLayoutParentData; + MultiChildLayoutParentData actionsSectionParentData = + this.actionsSection.parentData as MultiChildLayoutParentData; + ; + if (this.contentSection.hitTest(result, position: position - contentSectionParentData.offset)) { + isHit = true; + } + else if (this.actionsSection.hitTest(result, + position: position - actionsSectionParentData.offset)) { + isHit = true; + } + + return isHit; + } + } + + + enum _AlertSections { + contentSection, + actionsSection, + } + + + class _CupertinoAlertContentSection : StatelessWidget { + public _CupertinoAlertContentSection( + Key key = null, + Widget title = null, + Widget message = null, + ScrollController scrollController = null + ) : base(key: key) { + this.title = title; + this.message = message; + this.scrollController = scrollController; + } + + public readonly Widget title; + public readonly Widget message; + public readonly ScrollController scrollController; + + public override Widget build(BuildContext context) { + List titleContentGroup = new List(); + if (this.title != null) { + titleContentGroup.Add(new Padding( + padding: EdgeInsets.only( + left: CupertinoActionSheetUtils._kContentHorizontalPadding, + right: CupertinoActionSheetUtils._kContentHorizontalPadding, + bottom: CupertinoActionSheetUtils._kContentVerticalPadding, + top: CupertinoActionSheetUtils._kContentVerticalPadding + ), + child: new DefaultTextStyle( + style: this.message == null + ? CupertinoActionSheetUtils._kActionSheetContentStyle + : CupertinoActionSheetUtils._kActionSheetContentStyle.copyWith(fontWeight: FontWeight.w600), + textAlign: TextAlign.center, + child: this.title + ) + )); + } + + if (this.message != null) { + titleContentGroup.Add( + new Padding( + padding: EdgeInsets.only( + left: CupertinoActionSheetUtils._kContentHorizontalPadding, + right: CupertinoActionSheetUtils._kContentHorizontalPadding, + bottom: this.title == null ? CupertinoActionSheetUtils._kContentVerticalPadding : 22.0f, + top: this.title == null ? CupertinoActionSheetUtils._kContentVerticalPadding : 0.0f + ), + child: new DefaultTextStyle( + style: this.title == null + ? CupertinoActionSheetUtils._kActionSheetContentStyle.copyWith( + fontWeight: FontWeight.w600) + : CupertinoActionSheetUtils._kActionSheetContentStyle, + textAlign: TextAlign.center, + child: this.message + ) + ) + ); + } + + if (titleContentGroup.isEmpty()) { + return new SingleChildScrollView( + controller: this.scrollController, + child: new Container( + width: 0.0f, + height: 0.0f + ) + ); + } + + + if (titleContentGroup.Count > 1) { + titleContentGroup.Insert(1, new Padding(padding: EdgeInsets.only(top: 8.0f))); + } + + return new CupertinoScrollbar( + child: new SingleChildScrollView( + controller: this.scrollController, + child: new Column( + mainAxisSize: MainAxisSize.max, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: titleContentGroup + ) + ) + ); + } + } + + + class _CupertinoAlertActionSection : StatefulWidget { + public _CupertinoAlertActionSection( + List children, + Key key = null, + ScrollController scrollController = null, + bool hasCancelButton = false + ) : base(key: key) { + D.assert(children != null); + this.children = children; + this.scrollController = scrollController; + this.hasCancelButton = hasCancelButton; + } + + public readonly List children; + public readonly ScrollController scrollController; + public readonly bool hasCancelButton; + + public override State createState() { + return new _CupertinoAlertActionSectionState(); + } + } + + class _CupertinoAlertActionSectionState : State<_CupertinoAlertActionSection> { + public override Widget build(BuildContext context) { + float devicePixelRatio = MediaQuery.of(context).devicePixelRatio; + + List interactiveButtons = new List(); + for (int i = 0; i < this.widget.children.Count; i += 1) { + interactiveButtons.Add(new _PressableActionSheetActionButton( + child: this.widget.children[i] + ) + ); + } + + return new CupertinoScrollbar( + child: new SingleChildScrollView( + controller: this.widget.scrollController, + child: new _CupertinoAlertActionsRenderWidget( + actionButtons: interactiveButtons, + dividerThickness: CupertinoActionSheetUtils._kDividerThickness / devicePixelRatio, + hasCancelButton: this.widget.hasCancelButton + ) + ) + ); + } + } + + class _PressableActionSheetActionButton : StatefulWidget { + public _PressableActionSheetActionButton( + Widget child + ) { + this.child = child; + } + + public readonly Widget child; + + public override State createState() { + return new _PressableActionSheetActionButtonState(); + } + } + + class _PressableActionSheetActionButtonState : State<_PressableActionSheetActionButton> { + bool _isPressed = false; + + public override Widget build(BuildContext context) { + return new _ActionSheetActionButtonParentDataWidget( + isPressed: this._isPressed, + child: new GestureDetector( + behavior: HitTestBehavior.opaque, + onTapDown: (TapDownDetails details) => this.setState(() => { this._isPressed = true; }), + onTapUp: (TapUpDetails details) => this.setState(() => { this._isPressed = false; }), + onTapCancel: () => this.setState(() => this._isPressed = false), + child: this.widget.child + ) + ); + } + } + + class _ActionSheetActionButtonParentDataWidget : ParentDataWidget<_CupertinoAlertActionsRenderWidget> { + public _ActionSheetActionButtonParentDataWidget( + Widget child, + bool isPressed = false, + Key key = null + ) : base(key: key, child: child) { + this.isPressed = isPressed; + } + + public readonly bool isPressed; + + public override void applyParentData(RenderObject renderObject) { + D.assert(renderObject.parentData is _ActionSheetActionButtonParentData); + _ActionSheetActionButtonParentData parentData = + renderObject.parentData as _ActionSheetActionButtonParentData; + if (parentData.isPressed != this.isPressed) { + parentData.isPressed = this.isPressed; + AbstractNodeMixinDiagnosticableTree targetParent = renderObject.parent; + if (targetParent is RenderObject) { + ((RenderObject) targetParent).markNeedsPaint(); + } + } + } + } + + class _ActionSheetActionButtonParentData : MultiChildLayoutParentData { + public _ActionSheetActionButtonParentData( + bool isPressed = false + ) { + this.isPressed = isPressed; + } + + public bool isPressed; + } + + class _CupertinoAlertActionsRenderWidget : MultiChildRenderObjectWidget { + public _CupertinoAlertActionsRenderWidget( + List actionButtons, + Key key = null, + float dividerThickness = 0.0f, + bool hasCancelButton = false + ) : base(key: key, children: actionButtons) { + this._dividerThickness = dividerThickness; + this._hasCancelButton = hasCancelButton; + } + + readonly float _dividerThickness; + readonly bool _hasCancelButton; + + public override RenderObject createRenderObject(BuildContext context) { + return new _RenderCupertinoAlertActions( + dividerThickness: this._dividerThickness, + hasCancelButton: this._hasCancelButton + ); + } + + public override void updateRenderObject(BuildContext context, RenderObject renderObject) { + ((_RenderCupertinoAlertActions) renderObject).dividerThickness = this._dividerThickness; + ((_RenderCupertinoAlertActions) renderObject).hasCancelButton = this._hasCancelButton; + } + } + + class _RenderCupertinoAlertActions : RenderBoxContainerDefaultsMixinContainerRenderObjectMixinRenderBox { + public _RenderCupertinoAlertActions( + List children = null, + float dividerThickness = 0.0f, + bool hasCancelButton = false + ) { + this._dividerThickness = dividerThickness; + this._hasCancelButton = hasCancelButton; + this.addAll(children ?? new List()); + } + + public float dividerThickness { + get { return this._dividerThickness; } + set { + if (value == this._dividerThickness) { + return; + } + + this._dividerThickness = value; + this.markNeedsLayout(); + } + } + + float _dividerThickness; + + bool _hasCancelButton; + + public bool hasCancelButton { + get { return this._hasCancelButton; } + set { + if (value == this._hasCancelButton) { + return; + } + + this._hasCancelButton = value; + this.markNeedsLayout(); + } + } + + + readonly Paint _buttonBackgroundPaint = new Paint() { + color = CupertinoActionSheetUtils._kBackgroundColor, + style = PaintingStyle.fill + }; + + readonly Paint _pressedButtonBackgroundPaint = new Paint() { + color = CupertinoActionSheetUtils._kPressedColor, + style = PaintingStyle.fill + }; + + readonly Paint _dividerPaint = new Paint() { + color = CupertinoActionSheetUtils._kButtonDividerColor, + style = PaintingStyle.fill + }; + + public override void setupParentData(RenderObject child) { + if (!(child.parentData is _ActionSheetActionButtonParentData)) { + child.parentData = new _ActionSheetActionButtonParentData(); + } + } + + protected override float computeMinIntrinsicWidth(float height) { + return this.constraints.minWidth; + } + + protected override float computeMaxIntrinsicWidth(float height) { + return this.constraints.maxWidth; + } + + protected override float computeMinIntrinsicHeight(float width) { + if (this.childCount == 0) { + return 0.0f; + } + + if (this.childCount == 1) { + return this.firstChild.computeMaxIntrinsicHeight(width) + this.dividerThickness; + } + + if (this.hasCancelButton && this.childCount < 4) { + return this._computeMinIntrinsicHeightWithCancel(width); + } + + return this._computeMinIntrinsicHeightWithoutCancel(width); + } + + float _computeMinIntrinsicHeightWithCancel(float width) { + D.assert(this.childCount == 2 || this.childCount == 3); + if (this.childCount == 2) { + return this.firstChild.getMinIntrinsicHeight(width) + + this.childAfter(this.firstChild).getMinIntrinsicHeight(width) + + this.dividerThickness; + } + + return this.firstChild.getMinIntrinsicHeight(width) + + this.childAfter(this.firstChild).getMinIntrinsicHeight(width) + + this.childAfter(this.childAfter(this.firstChild)).getMinIntrinsicHeight(width) + + (this.dividerThickness * 2); + } + + float _computeMinIntrinsicHeightWithoutCancel(float width) { + D.assert(this.childCount >= 2); + return this.firstChild.getMinIntrinsicHeight(width) + + this.dividerThickness + + (0.5f * this.childAfter(this.firstChild).getMinIntrinsicHeight(width)); + } + + protected internal override float computeMaxIntrinsicHeight(float width) { + if (this.childCount == 0) { + return 0.0f; + } + + if (this.childCount == 1) { + return this.firstChild.computeMaxIntrinsicHeight(width) + this.dividerThickness; + } + + return this._computeMaxIntrinsicHeightStacked(width); + } + + float _computeMaxIntrinsicHeightStacked(float width) { + D.assert(this.childCount >= 2); + float allDividersHeight = (this.childCount - 1) * this.dividerThickness; + float heightAccumulation = allDividersHeight; + RenderBox button = this.firstChild; + while (button != null) { + heightAccumulation += button.getMaxIntrinsicHeight(width); + button = this.childAfter(button); + } + + return heightAccumulation; + } + + protected override void performLayout() { + BoxConstraints perButtonConstraints = this.constraints.copyWith( + minHeight: 0.0f, + maxHeight: float.PositiveInfinity + ); + RenderBox child = this.firstChild; + int index = 0; + float verticalOffset = 0.0f; + while (child != null) { + child.layout( + perButtonConstraints, + parentUsesSize: true + ); + D.assert(child.parentData is MultiChildLayoutParentData); + MultiChildLayoutParentData parentData = child.parentData as MultiChildLayoutParentData; + parentData.offset = new Offset(0.0f, verticalOffset); + verticalOffset += child.size.height; + if (index < this.childCount - 1) { + verticalOffset += this.dividerThickness; + } + + index += 1; + child = this.childAfter(child); + } + + this.size = this.constraints.constrain( + new Size(this.constraints.maxWidth, verticalOffset) + ); + } + + public override void paint(PaintingContext context, Offset offset) { + Canvas canvas = context.canvas; + this._drawButtonBackgroundsAndDividersStacked(canvas, offset); + this._drawButtons(context, offset); + } + + void _drawButtonBackgroundsAndDividersStacked(Canvas canvas, Offset offset) { + Offset dividerOffset = new Offset(0.0f, this.dividerThickness); + Path backgroundFillPath = new Path(); + // fillType = PathFillType.evenOdd + backgroundFillPath.addRect(Rect.fromLTWH(0.0f, 0.0f, this.size.width, this.size.height)); + + Path pressedBackgroundFillPath = new Path(); + Path dividersPath = new Path(); + Offset accumulatingOffset = offset; + RenderBox child = this.firstChild; + RenderBox prevChild = null; + while (child != null) { + D.assert(child.parentData is _ActionSheetActionButtonParentData); + _ActionSheetActionButtonParentData currentButtonParentData = + child.parentData as _ActionSheetActionButtonParentData; + bool isButtonPressed = currentButtonParentData.isPressed; + bool isPrevButtonPressed = false; + if (prevChild != null) { + D.assert(prevChild.parentData is _ActionSheetActionButtonParentData); + _ActionSheetActionButtonParentData previousButtonParentData = + prevChild.parentData as _ActionSheetActionButtonParentData; + isPrevButtonPressed = previousButtonParentData.isPressed; + } + + bool isDividerPresent = child != this.firstChild; + bool isDividerPainted = isDividerPresent && !(isButtonPressed || isPrevButtonPressed); + Rect dividerRect = Rect.fromLTWH( + accumulatingOffset.dx, + accumulatingOffset.dy, this.size.width, this._dividerThickness + ); + Rect buttonBackgroundRect = Rect.fromLTWH( + accumulatingOffset.dx, + accumulatingOffset.dy + (isDividerPresent ? this.dividerThickness : 0.0f), this.size.width, + child.size.height + ); + if (isButtonPressed) { + backgroundFillPath.addRect(buttonBackgroundRect); + pressedBackgroundFillPath.addRect(buttonBackgroundRect); + } + + if (isDividerPainted) { + backgroundFillPath.addRect(dividerRect); + dividersPath.addRect(dividerRect); + } + + accumulatingOffset += (isDividerPresent ? dividerOffset : Offset.zero) + + new Offset(0.0f, child.size.height); + prevChild = child; + child = this.childAfter(child); + } + + canvas.drawPath(backgroundFillPath, this._buttonBackgroundPaint); + canvas.drawPath(pressedBackgroundFillPath, this._pressedButtonBackgroundPaint); + canvas.drawPath(dividersPath, this._dividerPaint); + } + + void _drawButtons(PaintingContext context, Offset offset) { + RenderBox child = this.firstChild; + while (child != null) { + MultiChildLayoutParentData childParentData = child.parentData as MultiChildLayoutParentData; + context.paintChild(child, childParentData.offset + offset); + child = this.childAfter(child); + } + } + + protected override bool hitTestChildren(HitTestResult result, Offset position = null) { + return this.defaultHitTestChildren(result, position: position); + } + } +} \ No newline at end of file diff --git a/Runtime/RuntimeExample.cs.meta b/Runtime/cupertino/action_sheet.cs.meta similarity index 83% rename from Runtime/RuntimeExample.cs.meta rename to Runtime/cupertino/action_sheet.cs.meta index f9539c28..2fa7b7cd 100644 --- a/Runtime/RuntimeExample.cs.meta +++ b/Runtime/cupertino/action_sheet.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: f85dbe0ff914a4c3b9620d093073f3bb +guid: ea4f1fabac9a048f085e528a41c2415d MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Runtime/cupertino/activity_indicator.cs b/Runtime/cupertino/activity_indicator.cs new file mode 100644 index 00000000..bea234ab --- /dev/null +++ b/Runtime/cupertino/activity_indicator.cs @@ -0,0 +1,130 @@ +using System; +using Unity.UIWidgets.animation; +using Unity.UIWidgets.foundation; +using Unity.UIWidgets.ui; +using Unity.UIWidgets.widgets; +using UnityEngine; +using Canvas = Unity.UIWidgets.ui.Canvas; +using Color = Unity.UIWidgets.ui.Color; + +namespace Unity.UIWidgets.cupertino { + static class CupertinoActivityIndicatorUtils { + public const float _kDefaultIndicatorRadius = 10.0f; + public const float _kTwoPI = Mathf.PI * 2.0f; + public const int _kTickCount = 12; + public const int _kHalfTickCount = _kTickCount / 2; + public static readonly Color _kTickColor = CupertinoColors.lightBackgroundGray; + public static readonly Color _kActiveTickColor = new Color(0xFF9D9D9D); + } + + public class CupertinoActivityIndicator : StatefulWidget { + public CupertinoActivityIndicator( + Key key = null, + bool animating = true, + float radius = CupertinoActivityIndicatorUtils._kDefaultIndicatorRadius + ) : base(key: key) { + D.assert(radius > 0); + this.animating = animating; + this.radius = radius; + } + + public readonly bool animating; + public readonly float radius; + + public override State createState() { + return new _CupertinoActivityIndicatorState(); + } + } + + class _CupertinoActivityIndicatorState : TickerProviderStateMixin { + AnimationController _controller; + + public override void initState() { + base.initState(); + this._controller = new AnimationController( + duration: TimeSpan.FromSeconds(1), + vsync: this + ); + + if (this.widget.animating) { + this._controller.repeat(); + } + } + + public override void didUpdateWidget(StatefulWidget oldWidget) { + base.didUpdateWidget(oldWidget: oldWidget); + if (oldWidget is CupertinoActivityIndicator _oldWidget) { + if (this.widget.animating != _oldWidget.animating) { + if (this.widget.animating) { + this._controller.repeat(); + } + else { + this._controller.stop(); + } + } + } + } + + public override void dispose() { + this._controller.dispose(); + base.dispose(); + } + + public override Widget build(BuildContext context) { + return new SizedBox( + height: this.widget.radius * 2, + width: this.widget.radius * 2, + child: new CustomPaint( + painter: new _CupertinoActivityIndicatorPainter( + position: this._controller, + radius: this.widget.radius + ) + ) + ); + } + } + + class _CupertinoActivityIndicatorPainter : AbstractCustomPainter { + public _CupertinoActivityIndicatorPainter( + Animation position, + float radius + ) : base(repaint: position) { + this.tickFundamentalRRect = RRect.fromLTRBXY( + left: -radius, + top: 1.0f * radius / CupertinoActivityIndicatorUtils._kDefaultIndicatorRadius, + right: -radius / 2.0f, + bottom: -1.0f * radius / CupertinoActivityIndicatorUtils._kDefaultIndicatorRadius, + radiusX: 1.0f, + radiusY: 1.0f + ); + this.position = position; + } + + readonly Animation position; + readonly RRect tickFundamentalRRect; + + public override void paint(Canvas canvas, Size size) { + Paint paint = new Paint(); + + canvas.save(); + canvas.translate(size.width / 2.0f, size.height / 2.0f); + + int activeTick = (CupertinoActivityIndicatorUtils._kTickCount * this.position.value).floor(); + + for (int i = 0; i < CupertinoActivityIndicatorUtils._kTickCount; ++i) { + float t = (((i + activeTick) % CupertinoActivityIndicatorUtils._kTickCount) / + CupertinoActivityIndicatorUtils._kHalfTickCount).clamp(0, 1); + paint.color = Color.lerp(a: CupertinoActivityIndicatorUtils._kActiveTickColor, + b: CupertinoActivityIndicatorUtils._kTickColor, t: t); + canvas.drawRRect(rect: this.tickFundamentalRRect, paint: paint); + canvas.rotate(-CupertinoActivityIndicatorUtils._kTwoPI / CupertinoActivityIndicatorUtils._kTickCount); + } + + canvas.restore(); + } + + public override bool shouldRepaint(CustomPainter oldPainter) { + return (oldPainter as _CupertinoActivityIndicatorPainter).position != this.position; + } + } +} \ No newline at end of file diff --git a/Runtime/material/float_action_button.cs.meta b/Runtime/cupertino/activity_indicator.cs.meta similarity index 83% rename from Runtime/material/float_action_button.cs.meta rename to Runtime/cupertino/activity_indicator.cs.meta index 01b74162..840bed11 100644 --- a/Runtime/material/float_action_button.cs.meta +++ b/Runtime/cupertino/activity_indicator.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 274f3c1005cd046a28b169d8048c0292 +guid: a08f265049c0646969c9b5adafa6916f MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Runtime/cupertino/app.cs b/Runtime/cupertino/app.cs new file mode 100644 index 00000000..0dc573f1 --- /dev/null +++ b/Runtime/cupertino/app.cs @@ -0,0 +1,181 @@ +using System.Collections.Generic; +using Unity.UIWidgets.foundation; +using Unity.UIWidgets.material; +using Unity.UIWidgets.painting; +using Unity.UIWidgets.ui; +using Unity.UIWidgets.widgets; + +namespace Unity.UIWidgets.cupertino { + public class CupertinoApp : StatefulWidget { + public CupertinoApp( + Key key = null, + GlobalKey navigatorKey = null, + Widget home = null, + CupertinoThemeData theme = null, + Dictionary routes = null, + string initialRoute = null, + RouteFactory onGenerateRoute = null, + RouteFactory onUnknownRoute = null, + List navigatorObservers = null, + TransitionBuilder builder = null, + string title = "", + GenerateAppTitle onGenerateTitle = null, + Color color = null, + Locale locale = null, + List> localizationsDelegates = null, + LocaleListResolutionCallback localeListResolutionCallback = null, + LocaleResolutionCallback localeResolutionCallback = null, + List supportedLocales = null, + bool showPerformanceOverlay = false + ) : base(key: key) { + D.assert(title != null); + + supportedLocales = supportedLocales ?? new List {new Locale("en", "US")}; + this.navigatorKey = navigatorKey; + this.home = home; + this.theme = theme; + this.routes = routes ?? new Dictionary(); + this.initialRoute = initialRoute; + this.onGenerateRoute = onGenerateRoute; + this.onUnknownRoute = onUnknownRoute; + this.navigatorObservers = navigatorObservers ?? new List(); + this.builder = builder; + this.title = title; + this.onGenerateTitle = onGenerateTitle; + this.color = color; + this.locale = locale; + this.localizationsDelegates = localizationsDelegates; + this.localeListResolutionCallback = localeListResolutionCallback; + this.localeResolutionCallback = localeResolutionCallback; + this.supportedLocales = supportedLocales; + this.showPerformanceOverlay = showPerformanceOverlay; + } + + public readonly GlobalKey navigatorKey; + public readonly Widget home; + public readonly CupertinoThemeData theme; + public readonly Dictionary routes; + public readonly string initialRoute; + public readonly RouteFactory onGenerateRoute; + public readonly RouteFactory onUnknownRoute; + public readonly List navigatorObservers; + public readonly TransitionBuilder builder; + public readonly string title; + public readonly GenerateAppTitle onGenerateTitle; + public readonly Color color; + public readonly Locale locale; + public readonly List> localizationsDelegates; + public readonly LocaleListResolutionCallback localeListResolutionCallback; + public readonly LocaleResolutionCallback localeResolutionCallback; + public readonly List supportedLocales; + public readonly bool showPerformanceOverlay; + + public override State createState() { + return new _CupertinoAppState(); + } + + public static HeroController createCupertinoHeroController() { + return new HeroController(); + } + } + + + public class _AlwaysCupertinoScrollBehavior : ScrollBehavior { + public override Widget buildViewportChrome(BuildContext context, Widget child, AxisDirection axisDirection) { + return child; + } + + public override ScrollPhysics getScrollPhysics(BuildContext context) { + return new BouncingScrollPhysics(); + } + } + + class _CupertinoAppState : State { + HeroController _heroController; + + public override void initState() { + base.initState(); + this._heroController = CupertinoApp.createCupertinoHeroController(); + this._updateNavigator(); + } + + public override void didUpdateWidget(StatefulWidget oldWidget) { + base.didUpdateWidget(oldWidget); + if (this.widget.navigatorKey != ((CupertinoApp) oldWidget).navigatorKey) { + this._heroController = CupertinoApp.createCupertinoHeroController(); + } + + this._updateNavigator(); + } + + List _navigatorObservers; + + void _updateNavigator() { + if (this.widget.home != null || this.widget.routes.isNotEmpty() || this.widget.onGenerateRoute != null || + this.widget.onUnknownRoute != null) { + this._navigatorObservers = new List(); + foreach (var item in this.widget.navigatorObservers) { + this._navigatorObservers.Add(item); + } + } + else { + this._navigatorObservers = new List(); + } + } + + List _localizationsDelegates { + get { + var _delegates = new List(); + if (this.widget.localizationsDelegates != null) { + _delegates.AddRange(this.widget.localizationsDelegates); + } + + _delegates.Add(DefaultCupertinoLocalizations.del); + _delegates.Add(DefaultMaterialLocalizations.del); + return new List(_delegates); + } + } + + public override Widget build(BuildContext context) { + CupertinoThemeData effectiveThemeData = this.widget.theme ?? new CupertinoThemeData(); + + return new ScrollConfiguration( + behavior: new _AlwaysCupertinoScrollBehavior(), + child: new CupertinoTheme( + data: effectiveThemeData, + child: new WidgetsApp( + pageRouteBuilder: (RouteSettings settings, WidgetBuilder builder) => + new CupertinoPageRoute(settings: settings, builder: builder), + home: this.widget.home, + routes: this.widget.routes, + initialRoute: this.widget.initialRoute, + onGenerateRoute: this.widget.onGenerateRoute, + onUnknownRoute: this.widget.onUnknownRoute, + builder: this.widget.builder, + title: this.widget.title, + onGenerateTitle: this.widget.onGenerateTitle, + textStyle: effectiveThemeData.textTheme.textStyle, + color: this.widget.color ?? CupertinoColors.activeBlue, + locale: this.widget.locale, + localizationsDelegates: this._localizationsDelegates, + localeResolutionCallback: this.widget.localeResolutionCallback, + localeListResolutionCallback: this.widget.localeListResolutionCallback, + supportedLocales: this.widget.supportedLocales, + showPerformanceOverlay: this.widget.showPerformanceOverlay, + inspectorSelectButtonBuilder: (BuildContext _context, VoidCallback onPressed) => { + return CupertinoButton.filled( + child: new Icon( + CupertinoIcons.search, + size: 28.0f, + color: CupertinoColors.white + ), + padding: EdgeInsets.zero, + onPressed: onPressed + ); + } + ) + ) + ); + } + } +} \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/gallery/app.cs.meta b/Runtime/cupertino/app.cs.meta similarity index 83% rename from Samples/UIWidgetsGallery/gallery/app.cs.meta rename to Runtime/cupertino/app.cs.meta index 0d089b06..d5a1a616 100644 --- a/Samples/UIWidgetsGallery/gallery/app.cs.meta +++ b/Runtime/cupertino/app.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 3fff3cf3a1dd243d088be72945a3d7e9 +guid: ae05cbcca3d324a2da3b3aadbb2f124d MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Runtime/cupertino/bottom_app_bar.cs b/Runtime/cupertino/bottom_app_bar.cs new file mode 100644 index 00000000..e1928582 --- /dev/null +++ b/Runtime/cupertino/bottom_app_bar.cs @@ -0,0 +1,204 @@ +using System.Collections.Generic; +using Unity.UIWidgets.foundation; +using Unity.UIWidgets.gestures; +using Unity.UIWidgets.painting; +using Unity.UIWidgets.rendering; +using Unity.UIWidgets.ui; +using Unity.UIWidgets.widgets; +using TextStyle = Unity.UIWidgets.painting.TextStyle; + +namespace Unity.UIWidgets.cupertino { + class BottomAppBarUtils { + public const float _kTabBarHeight = 50.0f; + public static readonly Color _kDefaultTabBarBorderColor = new Color(0x4C000000); + } + + + public class CupertinoTabBar : StatelessWidget { + public CupertinoTabBar( + Key key = null, + List items = null, + ValueChanged onTap = null, + int currentIndex = 0, + Color backgroundColor = null, + Color activeColor = null, + Color inactiveColor = null, + float iconSize = 30.0f, + Border border = null + ) : base(key: key) { + D.assert(items != null); + D.assert(items.Count >= 2, + () => "Tabs need at least 2 items to conform to Apple's HIG" + ); + D.assert(0 <= currentIndex && currentIndex < items.Count); + + + this.items = items; + this.onTap = onTap; + this.currentIndex = currentIndex; + + this.backgroundColor = backgroundColor; + this.activeColor = activeColor; + this.inactiveColor = inactiveColor ?? CupertinoColors.inactiveGray; + this.iconSize = iconSize; + this.border = border ?? new Border( + top: new BorderSide( + color: BottomAppBarUtils._kDefaultTabBarBorderColor, + width: 0.0f, // One physical pixel. + style: BorderStyle.solid + ) + ); + } + + public readonly List items; + + public readonly ValueChanged onTap; + + public readonly int currentIndex; + + public readonly Color backgroundColor; + + public readonly Color activeColor; + + public readonly Color inactiveColor; + + public readonly float iconSize; + + public readonly Border border; + + public Size preferredSize { + get { return Size.fromHeight(BottomAppBarUtils._kTabBarHeight); } + } + + public bool opaque(BuildContext context) { + Color backgroundColor = + this.backgroundColor ?? CupertinoTheme.of(context).barBackgroundColor; + return backgroundColor.alpha == 0xFF; + } + + public override Widget build(BuildContext context) { + float bottomPadding = MediaQuery.of(context).padding.bottom; + + Widget result = new DecoratedBox( + decoration: new BoxDecoration( + border: this.border, + color: this.backgroundColor ?? CupertinoTheme.of(context).barBackgroundColor + ), + child: new SizedBox( + height: BottomAppBarUtils._kTabBarHeight + bottomPadding, + child: IconTheme.merge( // Default with the inactive state. + data: new IconThemeData( + color: this.inactiveColor, + size: this.iconSize + ), + child: new DefaultTextStyle( // Default with the inactive state. + style: CupertinoTheme.of(context).textTheme.tabLabelTextStyle + .copyWith(color: this.inactiveColor), + child: new Padding( + padding: EdgeInsets.only(bottom: bottomPadding), + child: new Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: this._buildTabItems(context) + ) + ) + ) + ) + ) + ); + + if (!this.opaque(context)) { + result = new ClipRect( + child: new BackdropFilter( + filter: ImageFilter.blur(sigmaX: 10.0f, sigmaY: 10.0f), + child: result + ) + ); + } + + return result; + } + + List _buildTabItems(BuildContext context) { + List result = new List { }; + + for (int index = 0; index < this.items.Count; index += 1) { + bool active = index == this.currentIndex; + var tabIndex = index; + result.Add( + this._wrapActiveItem( + context, + new Expanded( + child: new GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: this.onTap == null ? null : (GestureTapCallback) (() => { this.onTap(tabIndex); }), + child: new Padding( + padding: EdgeInsets.only(bottom: 4.0f), + child: new Column( + mainAxisAlignment: MainAxisAlignment.end, + children: this._buildSingleTabItem(this.items[index], active) + ) + ) + ) + ), + active: active + ) + ); + } + + return result; + } + + List _buildSingleTabItem(BottomNavigationBarItem item, bool active) { + List components = new List { + new Expanded( + child: new Center(child: active ? item.activeIcon : item.icon) + ) + }; + + if (item.title != null) { + components.Add(item.title); + } + + return components; + } + + Widget _wrapActiveItem(BuildContext context, Widget item, bool active) { + if (!active) { + return item; + } + + Color activeColor = this.activeColor ?? CupertinoTheme.of(context).primaryColor; + return IconTheme.merge( + data: new IconThemeData(color: activeColor), + child: DefaultTextStyle.merge( + style: new TextStyle(color: activeColor), + child: item + ) + ); + } + + public CupertinoTabBar copyWith( + Key key = null, + List items = null, + Color backgroundColor = null, + Color activeColor = null, + Color inactiveColor = null, + float? iconSize = null, + Border border = null, + int? currentIndex = null, + ValueChanged onTap = null + ) { + return new CupertinoTabBar( + key: key ?? this.key, + items: items ?? this.items, + backgroundColor: backgroundColor ?? this.backgroundColor, + activeColor: activeColor ?? this.activeColor, + inactiveColor: inactiveColor ?? this.inactiveColor, + iconSize: iconSize ?? this.iconSize, + border: border ?? this.border, + currentIndex: currentIndex ?? this.currentIndex, + onTap: onTap ?? this.onTap + ); + } + } +} \ No newline at end of file diff --git a/Runtime/material/float_action_button_location.cs.meta b/Runtime/cupertino/bottom_app_bar.cs.meta similarity index 83% rename from Runtime/material/float_action_button_location.cs.meta rename to Runtime/cupertino/bottom_app_bar.cs.meta index 4cf1d9c0..395de242 100644 --- a/Runtime/material/float_action_button_location.cs.meta +++ b/Runtime/cupertino/bottom_app_bar.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: cfa1c894caa2a46b19d419f6f53ae91f +guid: a4d68e50e84368e42b995ebca3727675 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Runtime/cupertino/button.cs b/Runtime/cupertino/button.cs new file mode 100644 index 00000000..bb75998c --- /dev/null +++ b/Runtime/cupertino/button.cs @@ -0,0 +1,239 @@ +using System; +using Unity.UIWidgets.animation; +using Unity.UIWidgets.foundation; +using Unity.UIWidgets.gestures; +using Unity.UIWidgets.painting; +using Unity.UIWidgets.rendering; +using Unity.UIWidgets.scheduler; +using Unity.UIWidgets.ui; +using Unity.UIWidgets.widgets; +using TextStyle = Unity.UIWidgets.painting.TextStyle; + +namespace Unity.UIWidgets.cupertino { + public class CupertinoButtonUtils { + public static readonly Color _kDisabledBackground = new Color(0xFFA9A9A9); + public static readonly Color _kDisabledForeground = new Color(0xFFD1D1D1); + public static readonly EdgeInsets _kButtonPadding = EdgeInsets.all(16.0f); + public static readonly EdgeInsets _kBackgroundButtonPadding = EdgeInsets.symmetric(vertical: 14.0f, horizontal: 64.0f); + } + + public class CupertinoButton : StatefulWidget { + public CupertinoButton( + Widget child, + VoidCallback onPressed, + Key key = null, + EdgeInsets padding = null, + Color color = null, + Color disabledColor = null, + float minSize = 44.0f, + float pressedOpacity = 0.1f, + BorderRadius borderRadius = null, + bool filled = false + ) : base(key: key) { + D.assert(pressedOpacity >= 0.0 && pressedOpacity <= 1.0); + this._filled = filled; + this.child = child; + this.onPressed = onPressed; + this.padding = padding; + this.color = color; + this.disabledColor = disabledColor; + this.minSize = minSize; + this.pressedOpacity = pressedOpacity; + this.borderRadius = borderRadius ?? BorderRadius.all(Radius.circular(8.0f)); + } + + public static CupertinoButton filled( + Widget child, + VoidCallback onPressed, + Key key = null, + EdgeInsets padding = null, + Color disabledColor = null, + float minSize = 44.0f, + float pressedOpacity = 0.1f, + BorderRadius borderRadius = null + ) { + D.assert(pressedOpacity >= 0.0 && pressedOpacity <= 1.0); + return new CupertinoButton( + key: key, + color: null, + child: child, + onPressed: onPressed, + padding: padding, + disabledColor: disabledColor, + minSize: minSize, + pressedOpacity: pressedOpacity, + borderRadius: borderRadius, + filled: true + ); + } + + public readonly Widget child; + + public readonly EdgeInsets padding; + + public readonly Color color; + + public readonly Color disabledColor; + + public readonly VoidCallback onPressed; + + public readonly float minSize; + + public readonly float? pressedOpacity; + + public readonly BorderRadius borderRadius; + public readonly bool _filled; + + public bool enabled { + get { return this.onPressed != null; } + } + + public override State createState() { + return new _CupertinoButtonState(); + } + + public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { + base.debugFillProperties(properties); + properties.add(new FlagProperty("enabled", value: this.enabled, ifFalse: "disabled")); + } + } + + class _CupertinoButtonState : SingleTickerProviderStateMixin { + static readonly TimeSpan kFadeOutDuration = new TimeSpan(0, 0, 0, 0, 10); + static readonly TimeSpan kFadeInDuration = new TimeSpan(0, 0, 0, 0, 100); + public readonly FloatTween _opacityTween = new FloatTween(begin: 1.0f, end: 0.0f); + AnimationController _animationController; + Animation _opacityAnimation; + + public override void initState() { + base.initState(); + this._animationController = new AnimationController( + duration: new TimeSpan(0, 0, 0, 0, 200), + value: 0.0f, + vsync: this); + this._opacityAnimation = this._animationController + .drive(new CurveTween(curve: Curves.decelerate)) + .drive(this._opacityTween); + this._setTween(); + } + + public override void didUpdateWidget(StatefulWidget old) { + base.didUpdateWidget(old); + this._setTween(); + } + + void _setTween() { + if (this.widget != null) { + this._opacityTween.end = this.widget.pressedOpacity ?? 1.0f; + } + } + + public override void dispose() { + this._animationController.dispose(); + this._animationController = null; + base.dispose(); + } + + bool _buttonHeldDown = false; + + void _handleTapDown(TapDownDetails evt) { + if (!this._buttonHeldDown) { + this._buttonHeldDown = true; + this._animate(); + } + } + + void _handleTapUp(TapUpDetails evt) { + if (this._buttonHeldDown) { + this._buttonHeldDown = false; + this._animate(); + } + } + + void _handleTapCancel() { + if (this._buttonHeldDown) { + this._buttonHeldDown = false; + this._animate(); + } + } + + void _animate() { + if (this._animationController.isAnimating) { + return; + } + + bool wasHeldDown = this._buttonHeldDown; + + TickerFuture ticker = this._buttonHeldDown + ? this._animationController.animateTo(1.0f, duration: kFadeOutDuration) + : this._animationController.animateTo(0.0f, duration: kFadeInDuration); + + ticker.Then(() => { + if (this.mounted && wasHeldDown != this._buttonHeldDown) { + this._animate(); + } + }); + } + + public override Widget build(BuildContext context) { + bool enabled = this.widget.enabled; + Color primaryColor = CupertinoTheme.of(context).primaryColor; + Color backgroundColor = this.widget.color ?? (this.widget._filled ? primaryColor : null); + + Color foregroundColor = backgroundColor != null + ? CupertinoTheme.of(context).primaryContrastingColor + : enabled + ? primaryColor + : CupertinoButtonUtils._kDisabledForeground; + + TextStyle textStyle = + CupertinoTheme.of(context).textTheme.textStyle.copyWith(color: foregroundColor); + return new GestureDetector( + behavior: HitTestBehavior.opaque, + onTapDown: enabled ? this._handleTapDown : (GestureTapDownCallback) null, + onTapUp: enabled ? this._handleTapUp : (GestureTapUpCallback) null, + onTapCancel: enabled ? this._handleTapCancel : (GestureTapCancelCallback) null, + onTap: this.widget.onPressed == null + ? (GestureTapCallback) null + : () => { + if (this.widget.onPressed != null) { + this.widget.onPressed(); + } + }, + child: new ConstrainedBox( + constraints: new BoxConstraints( + minWidth: this.widget.minSize, + minHeight: this.widget.minSize + ), + child: new FadeTransition( + opacity: this._opacityAnimation, + child: new DecoratedBox( + decoration: new BoxDecoration( + borderRadius: this.widget.borderRadius, + color: backgroundColor != null && !enabled + ? this.widget.disabledColor ?? CupertinoButtonUtils._kDisabledBackground + : backgroundColor + ), + child: new Padding( + padding: this.widget.padding ?? (backgroundColor != null + ? CupertinoButtonUtils._kBackgroundButtonPadding + : CupertinoButtonUtils._kButtonPadding), + child: new Center( + widthFactor: 1.0f, + heightFactor: 1.0f, + child: new DefaultTextStyle( + style: textStyle, + child: new IconTheme( + data: new IconThemeData(color: foregroundColor), + child: this.widget.child + ) + ) + ) + ) + ) + ) + ) + ); + } + } +} \ No newline at end of file diff --git a/Samples/MaterialSample/DividerButton.cs.meta b/Runtime/cupertino/button.cs.meta similarity index 83% rename from Samples/MaterialSample/DividerButton.cs.meta rename to Runtime/cupertino/button.cs.meta index b50b8871..20e588e4 100644 --- a/Samples/MaterialSample/DividerButton.cs.meta +++ b/Runtime/cupertino/button.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 7d02ebc8543484a84b26e073e5ec501f +guid: 7c17a9b64e1654955af4ee61cc15780b MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Runtime/cupertino/colors.cs b/Runtime/cupertino/colors.cs new file mode 100644 index 00000000..53174181 --- /dev/null +++ b/Runtime/cupertino/colors.cs @@ -0,0 +1,25 @@ +using Unity.UIWidgets.ui; + +namespace Unity.UIWidgets.cupertino { + public class CupertinoColors { + public static readonly Color activeBlue = new Color(0xFF007AFF); + + public static readonly Color activeGreen = new Color(0xFF4CD964); + + public static readonly Color activeOrange = new Color(0xFFFF9500); + + public static readonly Color white = new Color(0xFFFFFFFF); + + public static readonly Color black = new Color(0xFF000000); + + public static readonly Color lightBackgroundGray = new Color(0xFFE5E5EA); + + public static readonly Color extraLightBackgroundGray = new Color(0xFFEFEFF4); + + public static readonly Color darkBackgroundGray = new Color(0xFF171717); + + public static readonly Color inactiveGray = new Color(0xFF8E8E93); + + public static readonly Color destructiveRed = new Color(0xFFFF3B30); + } +} \ No newline at end of file diff --git a/Runtime/cupertino/colors.cs.meta b/Runtime/cupertino/colors.cs.meta new file mode 100644 index 00000000..a28cc179 --- /dev/null +++ b/Runtime/cupertino/colors.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 621f7fba7472f4619a8a7429071a58c0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/cupertino/date_picker.cs b/Runtime/cupertino/date_picker.cs new file mode 100644 index 00000000..abee361b --- /dev/null +++ b/Runtime/cupertino/date_picker.cs @@ -0,0 +1,1105 @@ +using System; +using System.Collections.Generic; +using Unity.UIWidgets.animation; +using Unity.UIWidgets.foundation; +using Unity.UIWidgets.painting; +using Unity.UIWidgets.rendering; +using Unity.UIWidgets.scheduler; +using Unity.UIWidgets.ui; +using Unity.UIWidgets.widgets; +using TextStyle = Unity.UIWidgets.painting.TextStyle; + +namespace Unity.UIWidgets.cupertino { + static class CupertinoDatePickerUtils { + public const float _kItemExtent = 32.0f; + public const float _kPickerWidth = 330.0f; + public const bool _kUseMagnifier = true; + public const float _kMagnification = 1.05f; + public const float _kDatePickerPadSize = 12.0f; + + public static Color _kBackgroundColor = CupertinoColors.white; + + public static TextStyle _kDefaultPickerTextStyle = new TextStyle( + letterSpacing: -0.83f + ); + + + public delegate Widget listGenerateDelegate(int index); + + public static List listGenerate(int count, listGenerateDelegate func) { + var list = new List(); + for (int i = 0; i < count; i++) { + list.Add(func(i)); + } + + return list; + } + } + + public class _DatePickerLayoutDelegate : MultiChildLayoutDelegate { + public _DatePickerLayoutDelegate( + List columnWidths + ) { + D.assert(columnWidths != null); + this.columnWidths = columnWidths; + } + + public readonly List columnWidths; + + public override void performLayout(Size size) { + float remainingWidth = size.width; + for (int i = 0; i < this.columnWidths.Count; i++) { + remainingWidth -= this.columnWidths[i] + CupertinoDatePickerUtils._kDatePickerPadSize * 2; + } + + float currentHorizontalOffset = 0.0f; + for (int i = 0; i < this.columnWidths.Count; i++) { + float childWidth = this.columnWidths[i] + CupertinoDatePickerUtils._kDatePickerPadSize * 2; + if (i == 0 || i == this.columnWidths.Count - 1) { + childWidth += remainingWidth / 2; + } + + this.layoutChild(i, BoxConstraints.tight(new Size(childWidth, size.height))); + this.positionChild(i, new Offset(currentHorizontalOffset, 0.0f)); + currentHorizontalOffset += childWidth; + } + } + + public override bool shouldRelayout(MultiChildLayoutDelegate oldDelegate) { + return this.columnWidths != ((_DatePickerLayoutDelegate) oldDelegate).columnWidths; + } + } + + public enum CupertinoDatePickerMode { + time, + date, + dateAndTime, + } + + enum _PickerColumnType { + dayOfMonth, + month, + year, + date, + hour, + minute, + dayPeriod, + } + + public class CupertinoDatePicker : StatefulWidget { + public CupertinoDatePicker( + ValueChanged onDateTimeChanged, + CupertinoDatePickerMode mode = CupertinoDatePickerMode.dateAndTime, + DateTime? initialDateTime = null, + DateTime? minimumDate = null, + DateTime? maximumDate = null, + int minimumYear = 1, + int? maximumYear = null, + int minuteInterval = 1, + bool use24hFormat = false + ) { + this.initialDateTime = initialDateTime ?? DateTime.Now; + D.assert(onDateTimeChanged != null); + D.assert( + minuteInterval > 0 && 60 % minuteInterval == 0, + () => "minute interval is not a positive integer factor of 60" + ); + D.assert(this.initialDateTime != null); + D.assert( + mode != CupertinoDatePickerMode.dateAndTime || minimumDate == null || + !(this.initialDateTime < minimumDate), + () => "initial date is before minimum date" + ); + D.assert( + mode != CupertinoDatePickerMode.dateAndTime || maximumDate == null || + !(this.initialDateTime > maximumDate), + () => "initial date is after maximum date" + ); + D.assert( + mode != CupertinoDatePickerMode.date || (minimumYear >= 1 && this.initialDateTime.Year >= minimumYear), + () => "initial year is not greater than minimum year, or mininum year is not positive" + ); + D.assert( + mode != CupertinoDatePickerMode.date || maximumYear == null || this.initialDateTime.Year <= maximumYear, + () => "initial year is not smaller than maximum year" + ); + D.assert( + this.initialDateTime.Minute % minuteInterval == 0, + () => "initial minute is not divisible by minute interval" + ); + this.onDateTimeChanged = onDateTimeChanged; + this.mode = mode; + this.minimumDate = minimumDate; + this.maximumDate = maximumDate; + this.minimumYear = minimumYear; + this.maximumYear = maximumYear; + this.minuteInterval = minuteInterval; + this.use24hFormat = use24hFormat; + } + + public readonly CupertinoDatePickerMode mode; + public readonly DateTime initialDateTime; + public readonly DateTime? minimumDate; + public readonly DateTime? maximumDate; + public readonly int minimumYear; + public readonly int? maximumYear; + public readonly int minuteInterval; + public readonly bool use24hFormat; + public readonly ValueChanged onDateTimeChanged; + + public override State createState() { + if (this.mode == CupertinoDatePickerMode.time || this.mode == CupertinoDatePickerMode.dateAndTime) { + return new _CupertinoDatePickerDateTimeState(); + } + else { + return new _CupertinoDatePickerDateState(); + } + } + + internal static float _getColumnWidth( + _PickerColumnType columnType, + CupertinoLocalizations localizations, + BuildContext context + ) { + string longestText = ""; + switch (columnType) { + case _PickerColumnType.date: + + for (int i = 1; i <= 12; i++) { + string date = + localizations.datePickerMediumDate(new DateTime(2018, i, 25)); + if (longestText.Length < date.Length) { + longestText = date; + } + } + + break; + case _PickerColumnType.hour: + for (int i = 0; i < 24; i++) { + string hour = localizations.datePickerHour(i); + if (longestText.Length < hour.Length) { + longestText = hour; + } + } + + break; + case _PickerColumnType.minute: + for (int i = 0; i < 60; i++) { + string minute = localizations.datePickerMinute(i); + if (longestText.Length < minute.Length) { + longestText = minute; + } + } + + break; + case _PickerColumnType.dayPeriod: + longestText = + localizations.anteMeridiemAbbreviation.Length > localizations.postMeridiemAbbreviation.Length + ? localizations.anteMeridiemAbbreviation + : localizations.postMeridiemAbbreviation; + break; + case _PickerColumnType.dayOfMonth: + for (int i = 1; i <= 31; i++) { + string dayOfMonth = localizations.datePickerDayOfMonth(i); + if (longestText.Length < dayOfMonth.Length) { + longestText = dayOfMonth; + } + } + + break; + case _PickerColumnType.month: + for (int i = 1; i <= 12; i++) { + string month = localizations.datePickerMonth(i); + if (longestText.Length < month.Length) { + longestText = month; + } + } + + break; + case _PickerColumnType.year: + longestText = localizations.datePickerYear(2018); + break; + } + + D.assert(longestText != "", () => "column type is not appropriate"); + TextPainter painter = new TextPainter( + text: new TextSpan( + style: DefaultTextStyle.of(context).style, + text: longestText + ) + ); + + + painter.layout(); + return painter.maxIntrinsicWidth; + } + } + + delegate Widget _ColumnBuilder(float offAxisFraction, TransitionBuilder itemPositioningBuilder); + + class _CupertinoDatePickerDateTimeState : State { + public CupertinoLocalizations localizations; + public Alignment alignCenterLeft; + public Alignment alignCenterRight; + public DateTime initialDateTime; + public int selectedDayFromInitial; + public int selectedHour; + public int previousHourIndex; + public int selectedMinute; + public int selectedAmPm; + public FixedExtentScrollController amPmController; + + public static Dictionary estimatedColumnWidths = new Dictionary(); + + public override void initState() { + base.initState(); + this.initialDateTime = this.widget.initialDateTime; + this.selectedDayFromInitial = 0; + this.selectedHour = this.widget.initialDateTime.Hour; + this.selectedMinute = this.widget.initialDateTime.Minute; + this.selectedAmPm = 0; + if (!this.widget.use24hFormat) { + this.selectedAmPm = this.selectedHour / 12; + this.selectedHour = this.selectedHour % 12; + if (this.selectedHour == 0) { + this.selectedHour = 12; + } + + this.amPmController = new FixedExtentScrollController(initialItem: this.selectedAmPm); + } + + this.previousHourIndex = this.selectedHour; + } + + public override void didUpdateWidget(StatefulWidget oldWidget) { + base.didUpdateWidget(oldWidget); + D.assert( + ((CupertinoDatePicker) oldWidget).mode == this.widget.mode, + () => "The CupertinoDatePicker's mode cannot change once it's built" + ); + } + + public override void didChangeDependencies() { + base.didChangeDependencies(); + + this.localizations = CupertinoLocalizations.of(this.context); + this.alignCenterLeft = Alignment.centerLeft; + this.alignCenterRight = Alignment.centerRight; + estimatedColumnWidths.Clear(); + } + + float _getEstimatedColumnWidth(_PickerColumnType columnType) { + if (!estimatedColumnWidths.TryGetValue((int) columnType, out float _)) { + estimatedColumnWidths[(int) columnType] = + CupertinoDatePicker._getColumnWidth(columnType, this.localizations, this.context); + } + + return estimatedColumnWidths[(int) columnType]; + } + + DateTime _getDateTime() { + DateTime date = new DateTime(this.initialDateTime.Year, this.initialDateTime.Month, this.initialDateTime.Day + ).Add(new TimeSpan(this.selectedDayFromInitial, 0, 0, 0)); + return new DateTime( + date.Year, + date.Month, + date.Day, + this.widget.use24hFormat ? this.selectedHour : this.selectedHour % 12 + this.selectedAmPm * 12, + this.selectedMinute, + 0 + ); + } + + Widget _buildMediumDatePicker(float offAxisFraction, TransitionBuilder itemPositioningBuilder) { + return CupertinoPicker.builder( + scrollController: new FixedExtentScrollController(initialItem: this.selectedDayFromInitial), + offAxisFraction: offAxisFraction, + itemExtent: CupertinoDatePickerUtils._kItemExtent, + useMagnifier: CupertinoDatePickerUtils._kUseMagnifier, + magnification: CupertinoDatePickerUtils._kMagnification, + backgroundColor: CupertinoDatePickerUtils._kBackgroundColor, + onSelectedItemChanged: (int index) => { + this.selectedDayFromInitial = index; + this.widget.onDateTimeChanged(this._getDateTime()); + }, + itemBuilder: (BuildContext context, int index) => { + DateTime dateTime = new DateTime(this.initialDateTime.Year, this.initialDateTime.Month, + this.initialDateTime.Day + ).Add(new TimeSpan(index, 0, 0, 0)); + if (this.widget.minimumDate != null && dateTime < this.widget.minimumDate) { + return null; + } + + if (this.widget.maximumDate != null && dateTime > this.widget.maximumDate) { + return null; + } + + return itemPositioningBuilder( + context, + new Text(this.localizations.datePickerMediumDate(dateTime)) + ); + } + ); + } + + Widget _buildHourPicker(float offAxisFraction, TransitionBuilder itemPositioningBuilder) { + return new CupertinoPicker( + scrollController: new FixedExtentScrollController(initialItem: this.selectedHour), + offAxisFraction: offAxisFraction, + itemExtent: CupertinoDatePickerUtils._kItemExtent, + useMagnifier: CupertinoDatePickerUtils._kUseMagnifier, + magnification: CupertinoDatePickerUtils._kMagnification, + backgroundColor: CupertinoDatePickerUtils._kBackgroundColor, + onSelectedItemChanged: (int index) => { + if (this.widget.use24hFormat) { + this.selectedHour = index; + this.widget.onDateTimeChanged(this._getDateTime()); + } + else { + this.selectedHour = index % 12; + + + bool wasAm = this.previousHourIndex >= 0 && this.previousHourIndex <= 11; + bool isAm = index >= 0 && index <= 11; + if (wasAm != isAm) { + this.amPmController.animateToItem( + 1 - this.amPmController.selectedItem, + duration: new TimeSpan(0, 0, 0, 0, 300), + curve: + Curves.easeOut + ); + } + else { + this.widget.onDateTimeChanged(this._getDateTime()); + } + } + + this.previousHourIndex = index; + }, + children: CupertinoDatePickerUtils.listGenerate(24, (index) => { + int hour = index; + if (!this.widget.use24hFormat) { + hour = hour % 12 == 0 ? 12 : hour % 12; + } + + return itemPositioningBuilder(this.context, + new Text(this.localizations.datePickerHour(hour) + ) + ); + }), + looping: true + ); + } + + Widget _buildMinutePicker(float offAxisFraction, TransitionBuilder itemPositioningBuilder) { + return new CupertinoPicker( + scrollController: new FixedExtentScrollController( + initialItem: this.selectedMinute / this.widget.minuteInterval), + offAxisFraction: offAxisFraction, + itemExtent: CupertinoDatePickerUtils._kItemExtent, + useMagnifier: CupertinoDatePickerUtils._kUseMagnifier, + magnification: CupertinoDatePickerUtils._kMagnification, + backgroundColor: CupertinoDatePickerUtils._kBackgroundColor, + onSelectedItemChanged: (int index) => { + this.selectedMinute = index * this.widget.minuteInterval; + this.widget.onDateTimeChanged(this._getDateTime()); + }, + children: CupertinoDatePickerUtils.listGenerate(60 / this.widget.minuteInterval, (int index) => { + int minute = index * this.widget.minuteInterval; + return itemPositioningBuilder(this.context, + new Text(this.localizations.datePickerMinute(minute) + ) + ); + }), + looping: true + ); + } + + Widget _buildAmPmPicker(float offAxisFraction, TransitionBuilder itemPositioningBuilder) { + return new CupertinoPicker( + scrollController: this.amPmController, + offAxisFraction: offAxisFraction, + itemExtent: CupertinoDatePickerUtils._kItemExtent, + useMagnifier: CupertinoDatePickerUtils._kUseMagnifier, + magnification: CupertinoDatePickerUtils._kMagnification, + backgroundColor: CupertinoDatePickerUtils._kBackgroundColor, + onSelectedItemChanged: (int index) => { + this.selectedAmPm = index; + this.widget.onDateTimeChanged(this._getDateTime()); + }, + children: CupertinoDatePickerUtils.listGenerate(2, (int index) => { + return itemPositioningBuilder(this.context, + new Text( + index == 0 + ? this.localizations.anteMeridiemAbbreviation + : this.localizations.postMeridiemAbbreviation + ) + ); + }) + ); + } + + public override Widget build(BuildContext context) { + List columnWidths = new List() { + this._getEstimatedColumnWidth(_PickerColumnType.hour), + this._getEstimatedColumnWidth(_PickerColumnType.minute), + }; + + List<_ColumnBuilder> pickerBuilders = new List<_ColumnBuilder> { + this._buildHourPicker, this._buildMinutePicker, + }; + + if (!this.widget.use24hFormat) { + if (this.localizations.datePickerDateTimeOrder == DatePickerDateTimeOrder.date_time_dayPeriod + || this.localizations.datePickerDateTimeOrder == DatePickerDateTimeOrder.time_dayPeriod_date) { + pickerBuilders.Add(this._buildAmPmPicker); + columnWidths.Add(this._getEstimatedColumnWidth(_PickerColumnType.dayPeriod)); + } + else { + pickerBuilders.Insert(0, this._buildAmPmPicker); + columnWidths.Insert(0, this._getEstimatedColumnWidth(_PickerColumnType.dayPeriod)); + } + } + + if (this.widget.mode == CupertinoDatePickerMode.dateAndTime) { + if (this.localizations.datePickerDateTimeOrder == DatePickerDateTimeOrder.time_dayPeriod_date + || this.localizations.datePickerDateTimeOrder == DatePickerDateTimeOrder.dayPeriod_time_date) { + pickerBuilders.Add(this._buildMediumDatePicker); + columnWidths.Add(this._getEstimatedColumnWidth(_PickerColumnType.date)); + } + else { + pickerBuilders.Insert(0, this._buildMediumDatePicker); + columnWidths.Insert(0, this._getEstimatedColumnWidth(_PickerColumnType.date)); + } + } + + List pickers = new List(); + for (int i = 0; i < columnWidths.Count; i++) { + var _i = i; + float offAxisFraction = 0.0f; + if (_i == 0) { + offAxisFraction = -0.5f; + } + else if (_i >= 2 || columnWidths.Count == 2) { + offAxisFraction = 0.5f; + } + + EdgeInsets padding = EdgeInsets.only(right: CupertinoDatePickerUtils._kDatePickerPadSize); + if (_i == columnWidths.Count - 1) { + padding = padding.flipped; + } + + pickers.Add(new LayoutId( + id: _i, + child: pickerBuilders[_i]( + offAxisFraction, + (BuildContext _context, Widget child) => { + return new Container( + alignment: _i == columnWidths.Count - 1 + ? this.alignCenterLeft + : this.alignCenterRight, + padding: padding, + child: new Container( + alignment: _i == columnWidths.Count - 1 + ? this.alignCenterLeft + : this.alignCenterRight, + width: _i == 0 || _i == columnWidths.Count - 1 + ? (float?) null + : columnWidths[_i] + CupertinoDatePickerUtils._kDatePickerPadSize, + child: child + ) + ); + } + ) + )); + } + + return new MediaQuery( + data: new MediaQueryData(textScaleFactor: 1.0f), + child: DefaultTextStyle.merge( + style: CupertinoDatePickerUtils._kDefaultPickerTextStyle, + child: new CustomMultiChildLayout( + layoutDelegate: new _DatePickerLayoutDelegate( + columnWidths: columnWidths + ), + children: pickers + ) + ) + ); + } + } + + class _CupertinoDatePickerDateState : State { + CupertinoLocalizations localizations; + + Alignment alignCenterLeft; + Alignment alignCenterRight; + + int selectedDay; + int selectedMonth; + int selectedYear; + FixedExtentScrollController dayController; + + Dictionary estimatedColumnWidths = new Dictionary(); + + public override void initState() { + base.initState(); + this.selectedDay = this.widget.initialDateTime.Day; + this.selectedMonth = this.widget.initialDateTime.Month; + this.selectedYear = this.widget.initialDateTime.Year; + this.dayController = new FixedExtentScrollController(initialItem: this.selectedDay - 1); + } + + public override void didChangeDependencies() { + base.didChangeDependencies(); + this.localizations = CupertinoLocalizations.of(this.context); + this.alignCenterLeft = Alignment.centerLeft; + this.alignCenterRight = Alignment.centerRight; + this.estimatedColumnWidths[(int) _PickerColumnType.dayOfMonth] = CupertinoDatePicker._getColumnWidth( + _PickerColumnType.dayOfMonth, this.localizations, this.context); + + this.estimatedColumnWidths[(int) _PickerColumnType.month] = CupertinoDatePicker._getColumnWidth( + _PickerColumnType.month, this.localizations, this.context); + + this.estimatedColumnWidths[(int) _PickerColumnType.year] = CupertinoDatePicker._getColumnWidth( + _PickerColumnType.year, this.localizations, this.context); + } + + Widget _buildDayPicker(float offAxisFraction, TransitionBuilder itemPositioningBuilder) { + int daysInCurrentMonth = DateTime.DaysInMonth(this.selectedYear, this.selectedMonth); + return new CupertinoPicker( + scrollController: this.dayController, + offAxisFraction: offAxisFraction, + itemExtent: CupertinoDatePickerUtils._kItemExtent, + useMagnifier: CupertinoDatePickerUtils._kUseMagnifier, + magnification: CupertinoDatePickerUtils._kMagnification, + backgroundColor: CupertinoDatePickerUtils._kBackgroundColor, + onSelectedItemChanged: (int index) => { + this.selectedDay = index + 1; + var validDay = this.selectedDay; + if (DateTime.DaysInMonth(this.selectedYear, this.selectedMonth) < this.selectedDay) { + validDay -= DateTime.DaysInMonth(this.selectedYear, this.selectedMonth); + } + + if (this.selectedDay == validDay) { + this.widget.onDateTimeChanged(new DateTime(this.selectedYear, this.selectedMonth, + this.selectedDay)); + } + }, + children: CupertinoDatePickerUtils.listGenerate(31, (int index) => { + TextStyle disableTextStyle = null; + + if (index >= daysInCurrentMonth) { + disableTextStyle = new TextStyle(color: CupertinoColors.inactiveGray); + } + + return itemPositioningBuilder(this.context, + new Text(this.localizations.datePickerDayOfMonth(index + 1), + style: disableTextStyle + ) + ); + }), + looping: true + ); + } + + Widget _buildMonthPicker(float offAxisFraction, TransitionBuilder itemPositioningBuilder) { + return new CupertinoPicker( + scrollController: new FixedExtentScrollController(initialItem: this.selectedMonth - 1), + offAxisFraction: offAxisFraction, + itemExtent: CupertinoDatePickerUtils._kItemExtent, + useMagnifier: CupertinoDatePickerUtils._kUseMagnifier, + magnification: CupertinoDatePickerUtils._kMagnification, + backgroundColor: CupertinoDatePickerUtils._kBackgroundColor, + onSelectedItemChanged: (int index) => { + this.selectedMonth = index + 1; + var validDay = this.selectedDay; + if (DateTime.DaysInMonth(this.selectedYear, this.selectedMonth) < this.selectedDay) { + validDay -= DateTime.DaysInMonth(this.selectedYear, this.selectedMonth); + } + + if (this.selectedDay == validDay) { + this.widget.onDateTimeChanged(new DateTime(this.selectedYear, this.selectedMonth, + this.selectedDay)); + } + }, + children: CupertinoDatePickerUtils.listGenerate(12, (int index) => { + return itemPositioningBuilder(this.context, + new Text(this.localizations.datePickerMonth(index + 1)) + ); + }), + looping: true + ); + } + + Widget _buildYearPicker(float offAxisFraction, TransitionBuilder itemPositioningBuilder) { + return CupertinoPicker.builder( + scrollController: new FixedExtentScrollController(initialItem: this.selectedYear), + itemExtent: CupertinoDatePickerUtils._kItemExtent, + offAxisFraction: offAxisFraction, + useMagnifier: CupertinoDatePickerUtils._kUseMagnifier, + magnification: CupertinoDatePickerUtils._kMagnification, + backgroundColor: CupertinoDatePickerUtils._kBackgroundColor, + onSelectedItemChanged: (int index) => { + this.selectedYear = index; + if (new DateTime(this.selectedYear, this.selectedMonth, this.selectedDay).Day == this.selectedDay) { + this.widget.onDateTimeChanged(new DateTime(this.selectedYear, this.selectedMonth, + this.selectedDay)); + } + }, + itemBuilder: (BuildContext context, int index) => { + if (index < this.widget.minimumYear) { + return null; + } + + if (this.widget.maximumYear != null && index > this.widget.maximumYear) { + return null; + } + + return itemPositioningBuilder( + context, + new Text(this.localizations.datePickerYear(index)) + ); + } + ); + } + + bool _keepInValidRange(ScrollEndNotification notification) { + var desiredDay = this.selectedDay; + if (DateTime.DaysInMonth(this.selectedYear, this.selectedMonth) < this.selectedDay) { + desiredDay -= DateTime.DaysInMonth(this.selectedYear, this.selectedMonth); + } + + if (desiredDay != this.selectedDay) { + SchedulerBinding.instance.addPostFrameCallback((TimeSpan timestamp) => { + this.dayController.animateToItem(this.dayController.selectedItem - desiredDay, + duration: new TimeSpan(0, 0, 0, 0, 200), + curve: + Curves.easeOut + ); + }); + } + + this.setState(() => { }); + return false; + } + + public override Widget build(BuildContext context) { + List<_ColumnBuilder> pickerBuilders = new List<_ColumnBuilder>(); + List columnWidths = new List(); + switch (this.localizations.datePickerDateOrder) { + case DatePickerDateOrder.mdy: + pickerBuilders = new List<_ColumnBuilder>() + {this._buildMonthPicker, this._buildDayPicker, this._buildYearPicker}; + columnWidths = new List() { + this.estimatedColumnWidths[(int) _PickerColumnType.month], + this.estimatedColumnWidths[(int) _PickerColumnType.dayOfMonth], + this.estimatedColumnWidths[(int) _PickerColumnType.year] + }; + break; + case DatePickerDateOrder.dmy: + pickerBuilders = new List<_ColumnBuilder> + {this._buildDayPicker, this._buildMonthPicker, this._buildYearPicker}; + columnWidths = new List { + this.estimatedColumnWidths[(int) _PickerColumnType.dayOfMonth], + this.estimatedColumnWidths[(int) _PickerColumnType.month], + this.estimatedColumnWidths[(int) _PickerColumnType.year] + }; + break; + case DatePickerDateOrder.ymd: + pickerBuilders = new List<_ColumnBuilder> + {this._buildYearPicker, this._buildMonthPicker, this._buildDayPicker}; + columnWidths = new List() { + this.estimatedColumnWidths[(int) _PickerColumnType.year], + this.estimatedColumnWidths[(int) _PickerColumnType.month], + this.estimatedColumnWidths[(int) _PickerColumnType.dayOfMonth] + }; + break; + case DatePickerDateOrder.ydm: + pickerBuilders = new List<_ColumnBuilder> + {this._buildYearPicker, this._buildDayPicker, this._buildMonthPicker}; + columnWidths = new List { + this.estimatedColumnWidths[(int) _PickerColumnType.year], + this.estimatedColumnWidths[(int) _PickerColumnType.dayOfMonth], + this.estimatedColumnWidths[(int) _PickerColumnType.month] + }; + break; + default: + D.assert(false, () => "date order is not specified"); + break; + } + + List pickers = new List(); + for (int i = 0; i < columnWidths.Count; i++) { + var _i = i; + float offAxisFraction = (_i - 1) * 0.3f; + EdgeInsets padding = EdgeInsets.only(right: CupertinoDatePickerUtils._kDatePickerPadSize); + + pickers.Add(new LayoutId( + id: _i, + child: pickerBuilders[_i]( + offAxisFraction, + (BuildContext _context, Widget child) => { + return new Container( + alignment: _i == columnWidths.Count - 1 + ? this.alignCenterLeft + : this.alignCenterRight, + padding: _i == 0 ? null : padding, + child: new Container( + alignment: _i == 0 ? this.alignCenterLeft : this.alignCenterRight, + width: columnWidths[_i] + CupertinoDatePickerUtils._kDatePickerPadSize, + child: child + ) + ); + } + ) + )); + } + + return new MediaQuery( + data: new MediaQueryData(textScaleFactor: 1.0f), + child: new NotificationListener( + onNotification: this._keepInValidRange, + child: DefaultTextStyle.merge( + style: CupertinoDatePickerUtils._kDefaultPickerTextStyle, + child: new CustomMultiChildLayout( + layoutDelegate: new _DatePickerLayoutDelegate( + columnWidths: columnWidths + ), + children: + pickers + ) + ) + ) + ); + } + } + + public enum CupertinoTimerPickerMode { + hm, + ms, + hms, + } + + public class CupertinoTimerPicker : StatefulWidget { + public CupertinoTimerPicker( + ValueChanged onTimerDurationChanged, + CupertinoTimerPickerMode mode = CupertinoTimerPickerMode.hms, + TimeSpan initialTimerDuration = new TimeSpan(), + int minuteInterval = 1, + int secondInterval = 1 + ) { + D.assert(onTimerDurationChanged != null); + D.assert(initialTimerDuration >= TimeSpan.Zero); + D.assert(initialTimerDuration < new TimeSpan(1, 0, 0, 0)); + D.assert(minuteInterval > 0 && 60 % minuteInterval == 0); + D.assert(secondInterval > 0 && 60 % secondInterval == 0); + D.assert((int) initialTimerDuration.TotalMinutes % minuteInterval == 0); + D.assert((int) initialTimerDuration.TotalSeconds % secondInterval == 0); + this.onTimerDurationChanged = onTimerDurationChanged; + this.mode = mode; + this.initialTimerDuration = initialTimerDuration; + this.minuteInterval = minuteInterval; + this.secondInterval = secondInterval; + } + + public readonly CupertinoTimerPickerMode mode; + public readonly TimeSpan initialTimerDuration; + public readonly int minuteInterval; + public readonly int secondInterval; + public readonly ValueChanged onTimerDurationChanged; + + public override State createState() { + return new _CupertinoTimerPickerState(); + } + } + + class _CupertinoTimerPickerState : State { + CupertinoLocalizations localizations; + Alignment alignCenterLeft; + Alignment alignCenterRight; + int selectedHour; + int selectedMinute; + int selectedSecond; + + public override void initState() { + base.initState(); + this.selectedMinute = (int) this.widget.initialTimerDuration.TotalMinutes % 60; + if (this.widget.mode != CupertinoTimerPickerMode.ms) { + this.selectedHour = (int) this.widget.initialTimerDuration.TotalHours; + } + + if (this.widget.mode != CupertinoTimerPickerMode.hm) { + this.selectedSecond = (int) this.widget.initialTimerDuration.TotalSeconds % 60; + } + } + + Widget _buildLabel(string text) { + return new Text( + text, + textScaleFactor: 0.8f, + style: new TextStyle(fontWeight: FontWeight.w600) + ); + } + + public override void didChangeDependencies() { + base.didChangeDependencies(); + this.localizations = CupertinoLocalizations.of(this.context); + this.alignCenterLeft = Alignment.centerLeft; + this.alignCenterRight = Alignment.centerRight; + } + + Widget _buildHourPicker() { + return new CupertinoPicker( + scrollController: new FixedExtentScrollController(initialItem: this.selectedHour), + offAxisFraction: -0.5f, + itemExtent: CupertinoDatePickerUtils._kItemExtent, + backgroundColor: CupertinoDatePickerUtils._kBackgroundColor, + onSelectedItemChanged: (int index) => { + this.setState(() => { + this.selectedHour = index; + this.widget.onTimerDurationChanged( + new TimeSpan( + hours: this.selectedHour, + minutes: this.selectedMinute, + seconds: this.selectedSecond)); + }); + }, + children: CupertinoDatePickerUtils.listGenerate(24, (int index) => { + float hourLabelWidth = this.widget.mode == CupertinoTimerPickerMode.hm + ? CupertinoDatePickerUtils._kPickerWidth / 4 + : CupertinoDatePickerUtils._kPickerWidth / 6; + return new Container( + alignment: this.alignCenterRight, + padding: EdgeInsets.only(right: hourLabelWidth), + child: new Container( + alignment: this.alignCenterRight, + padding: EdgeInsets.symmetric(horizontal: 2.0f), + child: new Text(this.localizations.timerPickerHour(index)) + ) + ); + }) + ); + } + + Widget _buildHourColumn() { + Widget hourLabel = new IgnorePointer( + child: new Container( + alignment: this.alignCenterRight, + child: new Container( + alignment: this.alignCenterLeft, + padding: EdgeInsets.symmetric(horizontal: 2.0f), + width: this.widget.mode == CupertinoTimerPickerMode.hm + ? CupertinoDatePickerUtils._kPickerWidth / 4 + : CupertinoDatePickerUtils._kPickerWidth / 6, + child: this._buildLabel(this.localizations.timerPickerHourLabel(this.selectedHour)) + ) + ) + ); + return new Stack( + children: new List { + this._buildHourPicker(), + hourLabel + } + ); + } + + Widget _buildMinutePicker() { + float offAxisFraction; + if (this.widget.mode == CupertinoTimerPickerMode.hm) { + offAxisFraction = 0.5f; + } + else if (this.widget.mode == CupertinoTimerPickerMode.hms) { + offAxisFraction = 0.0f; + } + else { + offAxisFraction = -0.5f; + } + + return new CupertinoPicker( + scrollController: new FixedExtentScrollController( + initialItem: this.selectedMinute / this.widget.minuteInterval + ), + offAxisFraction: offAxisFraction, + itemExtent: CupertinoDatePickerUtils._kItemExtent, + backgroundColor: CupertinoDatePickerUtils._kBackgroundColor, + onSelectedItemChanged: (int index) => { + this.setState(() => { + this.selectedMinute = index * this.widget.minuteInterval; + this.widget.onTimerDurationChanged( + new TimeSpan( + hours: this.selectedHour, + minutes: this.selectedMinute, + seconds: this.selectedSecond)); + }); + }, + children: CupertinoDatePickerUtils.listGenerate(60 / this.widget.minuteInterval, (int index) => { + int minute = index * this.widget.minuteInterval; + if (this.widget.mode == CupertinoTimerPickerMode.ms) { + return new Container( + alignment: this.alignCenterRight, + padding: EdgeInsets.only(right: CupertinoDatePickerUtils._kPickerWidth / 4), + child: new Container( + alignment: this.alignCenterRight, + padding: EdgeInsets.symmetric(horizontal: 2.0f), + child: new Text(this.localizations.timerPickerMinute(minute)) + ) + ); + } + else { + return new Container( + alignment: this.alignCenterLeft, + child: new Container( + alignment: this.alignCenterRight, + width: this.widget.mode == CupertinoTimerPickerMode.hm + ? CupertinoDatePickerUtils._kPickerWidth / 10 + : CupertinoDatePickerUtils._kPickerWidth / 6, + padding: EdgeInsets.symmetric(horizontal: 2.0f), + child: + new Text(this.localizations.timerPickerMinute(minute)) + ) + ); + } + }) + ); + } + + Widget _buildMinuteColumn() { + Widget minuteLabel; + if (this.widget.mode == CupertinoTimerPickerMode.hm) { + minuteLabel = new IgnorePointer( + child: new Container( + alignment: this.alignCenterLeft, + padding: EdgeInsets.only(left: CupertinoDatePickerUtils._kPickerWidth / 10), + child: new Container( + alignment: this.alignCenterLeft, + padding: EdgeInsets.symmetric(horizontal: 2.0f), + child: this._buildLabel(this.localizations.timerPickerMinuteLabel(this.selectedMinute)) + ) + ) + ); + } + else { + minuteLabel = new IgnorePointer( + child: new Container( + alignment: this.alignCenterRight, + child: new Container( + alignment: this.alignCenterLeft, + width: this.widget.mode == CupertinoTimerPickerMode.ms + ? CupertinoDatePickerUtils._kPickerWidth / 4 + : CupertinoDatePickerUtils._kPickerWidth / 6, + padding: EdgeInsets.symmetric(horizontal: 2.0f), + child: this._buildLabel(this.localizations.timerPickerMinuteLabel(this.selectedMinute)) + ) + ) + ); + } + + return new Stack( + children: new List { + this._buildMinutePicker(), + minuteLabel + } + ); + } + + Widget _buildSecondPicker() { + float offAxisFraction = 0.5f; + float secondPickerWidth = this.widget.mode == CupertinoTimerPickerMode.ms + ? CupertinoDatePickerUtils._kPickerWidth / 10 + : CupertinoDatePickerUtils._kPickerWidth / 6; + return new CupertinoPicker( + scrollController: new FixedExtentScrollController( + initialItem: this.selectedSecond / this.widget.secondInterval + ), + offAxisFraction: offAxisFraction, + itemExtent: CupertinoDatePickerUtils._kItemExtent, + backgroundColor: CupertinoDatePickerUtils._kBackgroundColor, + onSelectedItemChanged: (int index) => { + this.setState(() => { + this.selectedSecond = index * this.widget.secondInterval; + this.widget.onTimerDurationChanged( + new TimeSpan( + hours: this.selectedHour, + minutes: this.selectedMinute, + seconds: this.selectedSecond)); + }); + }, + children: CupertinoDatePickerUtils.listGenerate(60 / this.widget.secondInterval, (int index) => { + int second = index * this.widget.secondInterval; + return new Container( + alignment: this.alignCenterLeft, + child: new Container( + alignment: this.alignCenterRight, + padding: EdgeInsets.symmetric(horizontal: 2.0f), + width: secondPickerWidth, + child: new Text(this.localizations.timerPickerSecond(second)) + ) + ); + }) + ); + } + + Widget _buildSecondColumn() { + float secondPickerWidth = this.widget.mode == CupertinoTimerPickerMode.ms + ? CupertinoDatePickerUtils._kPickerWidth / 10 + : CupertinoDatePickerUtils._kPickerWidth / 6; + Widget secondLabel = new IgnorePointer( + child: new Container( + alignment: this.alignCenterLeft, + padding: EdgeInsets.only(left: secondPickerWidth), + child: new Container( + alignment: this.alignCenterLeft, + padding: EdgeInsets.symmetric(horizontal: 2.0f), + child: this._buildLabel(this.localizations.timerPickerSecondLabel(this.selectedSecond)) + ) + ) + ); + return new Stack( + children: new List { + this._buildSecondPicker(), + secondLabel + } + ); + } + + public override Widget build(BuildContext context) { + Widget picker; + if (this.widget.mode == CupertinoTimerPickerMode.hm) { + picker = new Row( + children: new List { + new Expanded(child: this._buildHourColumn()), + new Expanded(child: this._buildMinuteColumn()), + } + ); + } + else if (this.widget.mode == CupertinoTimerPickerMode.ms) { + picker = new Row( + children: new List { + new Expanded(child: this._buildMinuteColumn()), + new Expanded(child: this._buildSecondColumn()), + } + ); + } + else { + picker = new Row( + children: new List { + new Expanded(child: this._buildHourColumn()), + new Container( + width: CupertinoDatePickerUtils._kPickerWidth / 3, + child: this._buildMinuteColumn() + ), + new Expanded(child: this._buildSecondColumn()), + } + ); + } + + return new MediaQuery( + data: new MediaQueryData( + textScaleFactor: 1.0f + ), + child: picker + ); + } + } +} \ No newline at end of file diff --git a/Runtime/cupertino/date_picker.cs.meta b/Runtime/cupertino/date_picker.cs.meta new file mode 100644 index 00000000..a8afaf01 --- /dev/null +++ b/Runtime/cupertino/date_picker.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b8c8750ecccc84021b9aafc99e9ee64b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/cupertino/dialog.cs b/Runtime/cupertino/dialog.cs new file mode 100644 index 00000000..336573ef --- /dev/null +++ b/Runtime/cupertino/dialog.cs @@ -0,0 +1,1342 @@ +using System.Collections.Generic; +using Unity.UIWidgets.foundation; +using Unity.UIWidgets.gestures; +using Unity.UIWidgets.painting; +using Unity.UIWidgets.rendering; +using Unity.UIWidgets.ui; +using Unity.UIWidgets.widgets; +using UnityEngine; +using Canvas = Unity.UIWidgets.ui.Canvas; +using Color = Unity.UIWidgets.ui.Color; +using Rect = Unity.UIWidgets.ui.Rect; +using TextStyle = Unity.UIWidgets.painting.TextStyle; + +namespace Unity.UIWidgets.cupertino { + class CupertinoDialogUtils { + public static readonly TextStyle _kCupertinoDialogTitleStyle = new TextStyle( + fontFamily: ".SF UI Display", + fontSize: 18.0f, + fontWeight: FontWeight.w600, + color: CupertinoColors.black, + letterSpacing: 0.48f, + textBaseline: TextBaseline.alphabetic + ); + + public static readonly TextStyle _kCupertinoDialogContentStyle = new TextStyle( + fontFamily: ".SF UI Text", + fontSize: 13.4f, + fontWeight: FontWeight.w400, + color: CupertinoColors.black, + height: 1.036f, + letterSpacing: -0.25f, + textBaseline: TextBaseline.alphabetic + ); + + public static readonly TextStyle _kCupertinoDialogActionStyle = new TextStyle( + fontFamily: ".SF UI Text", + fontSize: 16.8f, + fontWeight: FontWeight.w400, + color: CupertinoColors.activeBlue, + textBaseline: TextBaseline.alphabetic + ); + + public const float _kCupertinoDialogWidth = 270.0f; + public const float _kAccessibilityCupertinoDialogWidth = 310.0f; + + public static readonly BoxDecoration _kCupertinoDialogBlurOverlayDecoration = new BoxDecoration( + color: CupertinoColors.white, + backgroundBlendMode: BlendMode.overlay + ); + + public const float _kBlurAmount = 20.0f; + public const float _kEdgePadding = 20.0f; + public const float _kMinButtonHeight = 45.0f; + public const float _kMinButtonFontSize = 10.0f; + public const float _kDialogCornerRadius = 12.0f; + public const float _kDividerThickness = 1.0f; + public const float _kMaxRegularTextScaleFactor = 1.4f; + + public static readonly Color _kDialogColor = new Color(0xC0FFFFFF); + public static readonly Color _kDialogPressedColor = new Color(0x90FFFFFF); + public static readonly Color _kButtonDividerColor = new Color(0x40FFFFFF); + + public static bool _isInAccessibilityMode(BuildContext context) { + MediaQueryData data = MediaQuery.of(context, nullOk: true); + return data != null && data.textScaleFactor > _kMaxRegularTextScaleFactor; + } + } + + + public class CupertinoAlertDialog : StatelessWidget { + public CupertinoAlertDialog( + Key key = null, + Widget title = null, + Widget content = null, + List actions = null, + ScrollController scrollController = null, + ScrollController actionScrollController = null + ) : base(key: key) { + D.assert(actions != null); + + this.title = title; + this.content = content; + this.actions = actions ?? new List(); + this.scrollController = scrollController; + this.actionScrollController = actionScrollController; + } + + public readonly Widget title; + public readonly Widget content; + public readonly List actions; + public readonly ScrollController scrollController; + public readonly ScrollController actionScrollController; + + Widget _buildContent() { + List children = new List(); + if (this.title != null || this.content != null) { + Widget titleSection = new _CupertinoDialogAlertContentSection( + title: this.title, + content: this.content, + scrollController: this.scrollController + ); + children.Add(new Flexible(flex: 3, child: titleSection)); + } + + return new Container( + color: CupertinoDialogUtils._kDialogColor, + child: new Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: children + ) + ); + } + + Widget _buildActions() { + Widget actionSection = new Container( + height: 0.0f + ); + if (this.actions.isNotEmpty()) { + actionSection = new _CupertinoDialogAlertActionSection( + children: this.actions, + scrollController: this.actionScrollController + ); + } + + return actionSection; + } + + public override Widget build(BuildContext context) { + CupertinoLocalizations localizations = CupertinoLocalizations.of(context); + bool isInAccessibilityMode = CupertinoDialogUtils._isInAccessibilityMode(context); + + float textScaleFactor = MediaQuery.of(context).textScaleFactor; + return new MediaQuery( + data: MediaQuery.of(context).copyWith( + textScaleFactor: Mathf.Max(textScaleFactor, 1.0f) + ), + child: new LayoutBuilder( + builder: (BuildContext _context, BoxConstraints constraints) => { + return new Center( + child: new Container( + margin: EdgeInsets.symmetric(vertical: CupertinoDialogUtils._kEdgePadding), + width: isInAccessibilityMode + ? CupertinoDialogUtils._kAccessibilityCupertinoDialogWidth + : CupertinoDialogUtils._kCupertinoDialogWidth, + child: new CupertinoPopupSurface( + isSurfacePainted: false, + child: new _CupertinoDialogRenderWidget( + contentSection: this._buildContent(), + actionsSection: this._buildActions() + ) + ) + ) + ); + } + ) + ); + } + } + + public class CupertinoDialog : StatelessWidget { + public CupertinoDialog( + Key key = null, + Widget child = null + ) : base(key: key) { + this.child = child; + } + + public readonly Widget child; + + public override Widget build(BuildContext context) { + return new Center( + child: new SizedBox( + width: CupertinoDialogUtils._kCupertinoDialogWidth, + child: new CupertinoPopupSurface( + child: this.child + ) + ) + ); + } + } + + public class CupertinoPopupSurface : StatelessWidget { + public CupertinoPopupSurface( + Key key = null, + bool isSurfacePainted = true, + Widget child = null + ) : base(key: key) { + this.isSurfacePainted = isSurfacePainted; + this.child = child; + } + + public readonly bool isSurfacePainted; + public readonly Widget child; + + public override Widget build(BuildContext context) { + return new ClipRRect( + borderRadius: BorderRadius.circular(CupertinoDialogUtils._kDialogCornerRadius), + child: new BackdropFilter( + filter: ImageFilter.blur(sigmaX: CupertinoDialogUtils._kBlurAmount, + sigmaY: CupertinoDialogUtils._kBlurAmount), + child: new Container( + decoration: CupertinoDialogUtils._kCupertinoDialogBlurOverlayDecoration, + child: new Container( + color: this.isSurfacePainted ? CupertinoDialogUtils._kDialogColor : null, + child: this.child + ) + ) + ) + ); + } + } + + class _CupertinoDialogRenderWidget : RenderObjectWidget { + public _CupertinoDialogRenderWidget( + Widget contentSection, + Widget actionsSection, + Key key = null + ) : base(key: key) { + this.contentSection = contentSection; + this.actionsSection = actionsSection; + } + + public readonly Widget contentSection; + public readonly Widget actionsSection; + + public override RenderObject createRenderObject(BuildContext context) { + return new _RenderCupertinoDialog( + dividerThickness: CupertinoDialogUtils._kDividerThickness / MediaQuery.of(context).devicePixelRatio, + isInAccessibilityMode: CupertinoDialogUtils._isInAccessibilityMode(context) + ); + } + + public override void updateRenderObject(BuildContext context, RenderObject renderObject) { + ((_RenderCupertinoDialog) renderObject).isInAccessibilityMode = + CupertinoDialogUtils._isInAccessibilityMode(context); + } + + public override Element createElement() { + return new _CupertinoDialogRenderElement(this); + } + } + + class _CupertinoDialogRenderElement : RenderObjectElement { + public _CupertinoDialogRenderElement(_CupertinoDialogRenderWidget widget) : base(widget) { + } + + Element _contentElement; + Element _actionsElement; + + public new _CupertinoDialogRenderWidget widget { + get { return base.widget as _CupertinoDialogRenderWidget; } + } + + public new _RenderCupertinoDialog renderObject { + get { return base.renderObject as _RenderCupertinoDialog; } + } + + public override void visitChildren(ElementVisitor visitor) { + if (this._contentElement != null) { + visitor(this._contentElement); + } + + if (this._actionsElement != null) { + visitor(this._actionsElement); + } + } + + public override void mount(Element parent, object newSlot) { + base.mount(parent, newSlot); + this._contentElement = this.updateChild(this._contentElement, this.widget.contentSection, + _AlertDialogSections.contentSection); + this._actionsElement = this.updateChild(this._actionsElement, this.widget.actionsSection, + _AlertDialogSections.actionsSection); + } + + + protected override void insertChildRenderObject(RenderObject child, object slot) { + D.assert(slot != null); + switch (slot) { + case _AlertDialogSections.contentSection: + this.renderObject.contentSection = child as RenderBox; + break; + case _AlertDialogSections.actionsSection: + this.renderObject.actionsSection = child as RenderBox; + ; + break; + } + } + + protected override void moveChildRenderObject(RenderObject child, object slot) { + D.assert(false); + } + + public override void update(Widget newWidget) { + base.update(newWidget); + this._contentElement = this.updateChild(this._contentElement, this.widget.contentSection, + _AlertDialogSections.contentSection); + this._actionsElement = this.updateChild(this._actionsElement, this.widget.actionsSection, + _AlertDialogSections.actionsSection); + } + + protected override void forgetChild(Element child) { + D.assert(child == this._contentElement || child == this._actionsElement); + if (this._contentElement == child) { + this._contentElement = null; + } + else { + D.assert(this._actionsElement == child); + this._actionsElement = null; + } + } + + protected override void removeChildRenderObject(RenderObject child) { + D.assert(child == this.renderObject.contentSection || child == this.renderObject.actionsSection); + if (this.renderObject.contentSection == child) { + this.renderObject.contentSection = null; + } + else { + D.assert(this.renderObject.actionsSection == child); + this.renderObject.actionsSection = null; + } + } + } + + class _RenderCupertinoDialog : RenderBox { + public _RenderCupertinoDialog( + RenderBox contentSection = null, + RenderBox actionsSection = null, + float dividerThickness = 0.0f, + bool isInAccessibilityMode = false + ) { + this._contentSection = contentSection; + this._actionsSection = actionsSection; + this._dividerThickness = dividerThickness; + this._isInAccessibilityMode = isInAccessibilityMode; + } + + public RenderBox contentSection { + get { return this._contentSection; } + set { + if (value != this._contentSection) { + if (this._contentSection != null) { + this.dropChild(this._contentSection); + } + + this._contentSection = value; + if (this._contentSection != null) { + this.adoptChild(this._contentSection); + } + } + } + } + + RenderBox _contentSection; + + + public RenderBox actionsSection { + get { return this._actionsSection; } + set { + if (value != this._actionsSection) { + if (null != this._actionsSection) { + this.dropChild(this._actionsSection); + } + + this._actionsSection = value; + if (null != this._actionsSection) { + this.adoptChild(this._actionsSection); + } + } + } + } + + RenderBox _actionsSection; + + public bool isInAccessibilityMode { + get { return this._isInAccessibilityMode; } + set { + if (value != this._isInAccessibilityMode) { + this._isInAccessibilityMode = value; + this.markNeedsLayout(); + } + } + } + + bool _isInAccessibilityMode; + + float _dialogWidth { + get { + return this.isInAccessibilityMode + ? CupertinoDialogUtils._kAccessibilityCupertinoDialogWidth + : CupertinoDialogUtils._kCupertinoDialogWidth; + } + } + + readonly float _dividerThickness; + + readonly Paint _dividerPaint = new Paint() { + color = CupertinoDialogUtils._kButtonDividerColor, + style = PaintingStyle.fill + }; + + public override void attach(object owner) { + base.attach(owner); + if (null != this.contentSection) { + this.contentSection.attach(owner); + } + + if (null != this.actionsSection) { + this.actionsSection.attach(owner); + } + } + + public override void detach() { + base.detach(); + if (null != this.contentSection) { + this.contentSection.detach(); + } + + if (null != this.actionsSection) { + this.actionsSection.detach(); + } + } + + public override void redepthChildren() { + if (null != this.contentSection) { + this.redepthChild(this.contentSection); + } + + if (null != this.actionsSection) { + this.redepthChild(this.actionsSection); + } + } + + public override void setupParentData(RenderObject child) { + if (!(child.parentData is BoxParentData)) { + child.parentData = new BoxParentData(); + } + } + + public override void visitChildren(RenderObjectVisitor visitor) { + if (this.contentSection != null) { + visitor(this.contentSection); + } + + if (this.actionsSection != null) { + visitor(this.actionsSection); + } + } + + public override List debugDescribeChildren() { + List value = new List(); + if (this.contentSection != null) { + value.Add(this.contentSection.toDiagnosticsNode(name: "content")); + } + + if (this.actionsSection != null) { + value.Add(this.actionsSection.toDiagnosticsNode(name: "actions")); + } + + return value; + } + + protected override float computeMinIntrinsicWidth(float height) { + return this._dialogWidth; + } + + protected override float computeMaxIntrinsicWidth(float height) { + return this._dialogWidth; + } + + protected override float computeMinIntrinsicHeight(float width) { + float contentHeight = this.contentSection.getMinIntrinsicHeight(width); + float actionsHeight = this.actionsSection.getMinIntrinsicHeight(width); + bool hasDivider = contentHeight > 0.0f && actionsHeight > 0.0f; + float height = contentHeight + (hasDivider ? this._dividerThickness : 0.0f) + actionsHeight; + if (height.isFinite()) { + return height; + } + + return 0.0f; + } + + protected internal override float computeMaxIntrinsicHeight(float width) { + float contentHeight = this.contentSection.getMaxIntrinsicHeight(width); + float actionsHeight = this.actionsSection.getMaxIntrinsicHeight(width); + bool hasDivider = contentHeight > 0.0f && actionsHeight > 0.0f; + float height = contentHeight + (hasDivider ? this._dividerThickness : 0.0f) + actionsHeight; + if (height.isFinite()) { + return height; + } + + return 0.0f; + } + + protected override void performLayout() { + if (this.isInAccessibilityMode) { + this.performAccessibilityLayout(); + } + else { + this.performRegularLayout(); + } + } + + void performRegularLayout() { + bool hasDivider = this.contentSection.getMaxIntrinsicHeight(this._dialogWidth) > 0.0f + && this.actionsSection.getMaxIntrinsicHeight(this._dialogWidth) > 0.0f; + float dividerThickness = hasDivider ? this._dividerThickness : 0.0f; + float minActionsHeight = this.actionsSection.getMinIntrinsicHeight(this._dialogWidth); + this.contentSection.layout( + this.constraints.deflate(EdgeInsets.only(bottom: minActionsHeight + dividerThickness)), + parentUsesSize: true + ); + Size contentSize = this.contentSection.size; + this.actionsSection.layout( + this.constraints.deflate(EdgeInsets.only(top: contentSize.height + dividerThickness)), + parentUsesSize: true + ); + Size actionsSize = this.actionsSection.size; + float dialogHeight = contentSize.height + dividerThickness + actionsSize.height; + this.size = this.constraints.constrain( + new Size(this._dialogWidth, dialogHeight) + ); + D.assert(this.actionsSection.parentData is BoxParentData); + BoxParentData actionParentData = this.actionsSection.parentData as BoxParentData; + actionParentData.offset = new Offset(0.0f, contentSize.height + dividerThickness); + } + + void performAccessibilityLayout() { + bool hasDivider = this.contentSection.getMaxIntrinsicHeight(this._dialogWidth) > 0.0f + && this.actionsSection.getMaxIntrinsicHeight(this._dialogWidth) > 0.0f; + float dividerThickness = hasDivider ? this._dividerThickness : 0.0f; + float maxContentHeight = this.contentSection.getMaxIntrinsicHeight(this._dialogWidth); + float maxActionsHeight = this.actionsSection.getMaxIntrinsicHeight(this._dialogWidth); + Size contentSize; + Size actionsSize; + if (maxContentHeight + dividerThickness + maxActionsHeight > this.constraints.maxHeight) { + this.actionsSection.layout( + this.constraints.deflate(EdgeInsets.only(top: this.constraints.maxHeight / 2.0f)), + parentUsesSize: true + ); + actionsSize = this.actionsSection.size; + this.contentSection.layout( + this.constraints.deflate(EdgeInsets.only(bottom: actionsSize.height + dividerThickness)), + parentUsesSize: true + ); + contentSize = this.contentSection.size; + } + else { + this.contentSection.layout(this.constraints, + parentUsesSize: true + ); + contentSize = this.contentSection.size; + this.actionsSection.layout(this.constraints.deflate(EdgeInsets.only(top: contentSize.height)), + parentUsesSize: true + ); + actionsSize = this.actionsSection.size; + } + + float dialogHeight = contentSize.height + dividerThickness + actionsSize.height; + this.size = this.constraints.constrain( + new Size(this._dialogWidth, dialogHeight) + ); + D.assert(this.actionsSection.parentData is BoxParentData); + BoxParentData actionParentData = this.actionsSection.parentData as BoxParentData; + actionParentData.offset = new Offset(0.0f, contentSize.height + dividerThickness); + } + + public override void paint(PaintingContext context, Offset offset) { + BoxParentData contentParentData = this.contentSection.parentData as BoxParentData; + this.contentSection.paint(context, offset + contentParentData.offset); + bool hasDivider = this.contentSection.size.height > 0.0f && this.actionsSection.size.height > 0.0f; + if (hasDivider) { + this._paintDividerBetweenContentAndActions(context.canvas, offset); + } + + BoxParentData actionsParentData = this.actionsSection.parentData as BoxParentData; + this.actionsSection.paint(context, offset + actionsParentData.offset); + } + + void _paintDividerBetweenContentAndActions(Canvas canvas, Offset offset) { + canvas.drawRect( + Rect.fromLTWH( + offset.dx, + offset.dy + this.contentSection.size.height, this.size.width, this._dividerThickness + ), this._dividerPaint + ); + } + + protected override bool hitTestChildren(HitTestResult result, Offset position = null + ) { + bool isHit = false; + BoxParentData contentSectionParentData = this.contentSection.parentData as BoxParentData; + BoxParentData actionsSectionParentData = this.actionsSection.parentData as BoxParentData; + ; + if (this.contentSection.hitTest(result, position: position - contentSectionParentData.offset)) { + isHit = true; + } + else if (this.actionsSection.hitTest(result, position: position - actionsSectionParentData.offset)) { + isHit = true; + } + + return isHit; + } + } + + enum _AlertDialogSections { + contentSection, + actionsSection, + } + + class _CupertinoDialogAlertContentSection : StatelessWidget { + public _CupertinoDialogAlertContentSection( + Key key = null, + Widget title = null, + Widget content = null, + ScrollController scrollController = null + ) : base(key: key) { + this.title = title; + this.content = content; + this.scrollController = scrollController; + } + + public readonly Widget title; + public readonly Widget content; + public readonly ScrollController scrollController; + + public override Widget build(BuildContext context) { + float textScaleFactor = MediaQuery.of(context).textScaleFactor; + List titleContentGroup = new List(); + if (this.title != null) { + titleContentGroup.Add(new Padding( + padding: EdgeInsets.only( + left: CupertinoDialogUtils._kEdgePadding, + right: CupertinoDialogUtils._kEdgePadding, + bottom: this.content == null ? CupertinoDialogUtils._kEdgePadding : 1.0f, + top: CupertinoDialogUtils._kEdgePadding * textScaleFactor + ), + child: new DefaultTextStyle( + style: CupertinoDialogUtils._kCupertinoDialogTitleStyle, + textAlign: TextAlign.center, + child: this.title + ) + )); + } + + if (this.content != null) { + titleContentGroup.Add( + new Padding( + padding: EdgeInsets.only( + left: CupertinoDialogUtils._kEdgePadding, + right: CupertinoDialogUtils._kEdgePadding, + bottom: CupertinoDialogUtils._kEdgePadding * textScaleFactor, + top: this.title == null ? CupertinoDialogUtils._kEdgePadding : 1.0f + ), + child: new DefaultTextStyle( + style: CupertinoDialogUtils._kCupertinoDialogContentStyle, + textAlign: TextAlign.center, + child: this.content + ) + ) + ); + } + + if (titleContentGroup.isEmpty()) { + return new SingleChildScrollView( + controller: this.scrollController, + child: new Container(width: 0.0f, height: 0.0f) + ); + } + + return new CupertinoScrollbar( + child: new SingleChildScrollView( + controller: this.scrollController, + child: new Column( + mainAxisSize: MainAxisSize.max, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: titleContentGroup + ) + ) + ); + } + } + + class _CupertinoDialogAlertActionSection : StatefulWidget { + public _CupertinoDialogAlertActionSection( + List children, + Key key = null, + ScrollController scrollController = null + ) : base(key: key) { + D.assert(children != null); + this.children = children; + this.scrollController = scrollController; + } + + public readonly List children; + public readonly ScrollController scrollController; + + public override State createState() { + return new _CupertinoDialogAlertActionSectionState(); + } + } + + class _CupertinoDialogAlertActionSectionState : State<_CupertinoDialogAlertActionSection> { + public override Widget build(BuildContext context) { + float devicePixelRatio = MediaQuery.of(context).devicePixelRatio; + List interactiveButtons = new List(); + for (int i = 0; i < this.widget.children.Count; i += 1) { + interactiveButtons.Add( + new _PressableDialogActionButton( + child: this.widget.children[i] + ) + ); + } + + return new CupertinoScrollbar( + child: new SingleChildScrollView( + controller: this.widget.scrollController, + child: new _CupertinoDialogActionsRenderWidget( + actionButtons: interactiveButtons, + dividerThickness: CupertinoDialogUtils._kDividerThickness / devicePixelRatio + ) + ) + ); + } + } + + class _PressableDialogActionButton : StatefulWidget { + public _PressableDialogActionButton( + Widget child + ) { + this.child = child; + } + + public readonly Widget child; + + public override State createState() { + return new _PressableDialogActionButtonState(); + } + } + + class _PressableDialogActionButtonState : State<_PressableDialogActionButton> { + bool _isPressed = false; + + public override Widget build(BuildContext context) { + return new _DialogActionButtonParentDataWidget( + isPressed: this._isPressed, + child: new GestureDetector( + behavior: HitTestBehavior.opaque, + onTapDown: (TapDownDetails details) => this.setState(() => { this._isPressed = true; }), + onTapUp: (TapUpDetails details) => this.setState(() => { this._isPressed = false; }), + onTapCancel: () => this.setState(() => this._isPressed = false), + child: this.widget.child + ) + ); + } + } + + class _DialogActionButtonParentDataWidget : ParentDataWidget<_CupertinoDialogActionsRenderWidget> { + public _DialogActionButtonParentDataWidget( + Widget child, + bool isPressed = false, + Key key = null + ) : base(key: key, child: child) { + this.isPressed = isPressed; + } + + public readonly bool isPressed; + + public override void applyParentData(RenderObject renderObject) { + D.assert(renderObject.parentData is _DialogActionButtonParentData); + _DialogActionButtonParentData parentData = renderObject.parentData as _DialogActionButtonParentData; + if (parentData.isPressed != this.isPressed) { + parentData.isPressed = this.isPressed; + AbstractNodeMixinDiagnosticableTree targetParent = renderObject.parent; + if (targetParent is RenderObject) { + ((RenderObject) targetParent).markNeedsPaint(); + } + } + } + } + + class _DialogActionButtonParentData : MultiChildLayoutParentData { + public _DialogActionButtonParentData( + bool isPressed = false + ) { + this.isPressed = isPressed; + } + + public bool isPressed; + } + + public class CupertinoDialogAction : StatelessWidget { + public CupertinoDialogAction( + Widget child, + VoidCallback onPressed = null, + bool isDefaultAction = false, + bool isDestructiveAction = false, + TextStyle textStyle = null + ) { + D.assert(child != null); + this.onPressed = onPressed; + this.isDefaultAction = isDefaultAction; + this.isDestructiveAction = isDestructiveAction; + this.textStyle = textStyle; + this.child = child; + } + + public readonly VoidCallback onPressed; + public readonly bool isDefaultAction; + public readonly bool isDestructiveAction; + public readonly TextStyle textStyle; + public readonly Widget child; + + public bool enabled { + get { return this.onPressed != null; } + } + + float _calculatePadding(BuildContext context) { + return 8.0f * MediaQuery.textScaleFactorOf(context); + } + + Widget _buildContentWithRegularSizingPolicy( + BuildContext context, + TextStyle textStyle, + Widget content + ) { + bool isInAccessibilityMode = CupertinoDialogUtils._isInAccessibilityMode(context); + float dialogWidth = isInAccessibilityMode + ? CupertinoDialogUtils._kAccessibilityCupertinoDialogWidth + : CupertinoDialogUtils._kCupertinoDialogWidth; + float textScaleFactor = MediaQuery.textScaleFactorOf(context); + float fontSizeRatio = + (textScaleFactor * textStyle.fontSize) / CupertinoDialogUtils._kMinButtonFontSize ?? 0f; + float padding = this._calculatePadding(context); + return new IntrinsicHeight( + child: new SizedBox( + width: float.PositiveInfinity, + child: new FittedBox( + fit: BoxFit.scaleDown, + child: new ConstrainedBox( + constraints: new BoxConstraints( + maxWidth: fontSizeRatio * (dialogWidth - (2 * padding)) + ), + child: new DefaultTextStyle( + style: textStyle, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + maxLines: 1, + child: content + ) + ) + ) + ) + ); + } + + Widget _buildContentWithAccessibilitySizingPolicy( + TextStyle textStyle, + Widget content + ) { + return new DefaultTextStyle( + style: textStyle, + textAlign: TextAlign.center, + child: content + ); + } + + public override Widget build(BuildContext context) { + TextStyle style = CupertinoDialogUtils._kCupertinoDialogActionStyle; + style = style.merge(this.textStyle); + if (this.isDestructiveAction) { + style = style.copyWith(color: CupertinoColors.destructiveRed); + } + + if (!this.enabled) { + style = style.copyWith(color: style.color.withOpacity(0.5f)); + } + + Widget sizedContent = CupertinoDialogUtils._isInAccessibilityMode(context) + ? this._buildContentWithAccessibilitySizingPolicy( + textStyle: style, + content: this.child + ) + : this._buildContentWithRegularSizingPolicy( + context: context, + textStyle: style, + content: this.child + ); + return new GestureDetector( + onTap: () => this.onPressed(), + behavior: HitTestBehavior.opaque, + child: new ConstrainedBox( + constraints: new BoxConstraints( + minHeight: CupertinoDialogUtils._kMinButtonHeight + ), + child: new Container( + alignment: Alignment.center, + padding: EdgeInsets.all(this._calculatePadding(context)), + child: sizedContent + ) + ) + ); + } + } + + class _CupertinoDialogActionsRenderWidget : MultiChildRenderObjectWidget { + public _CupertinoDialogActionsRenderWidget( + List actionButtons, + Key key = null, + float dividerThickness = 0.0f + ) : base(key: key, children: actionButtons) { + this._dividerThickness = dividerThickness; + } + + public readonly float _dividerThickness; + + public override RenderObject createRenderObject(BuildContext context) { + return new _RenderCupertinoDialogActions( + dialogWidth: CupertinoDialogUtils._isInAccessibilityMode(context) + ? CupertinoDialogUtils._kAccessibilityCupertinoDialogWidth + : CupertinoDialogUtils._kCupertinoDialogWidth, + dividerThickness: this._dividerThickness + ); + } + + public override void updateRenderObject(BuildContext context, RenderObject renderObject) { + (renderObject as _RenderCupertinoDialogActions).dialogWidth = + CupertinoDialogUtils._isInAccessibilityMode(context) + ? CupertinoDialogUtils._kAccessibilityCupertinoDialogWidth + : CupertinoDialogUtils._kCupertinoDialogWidth; + (renderObject as _RenderCupertinoDialogActions).dividerThickness = this._dividerThickness; + } + } + + class _RenderCupertinoDialogActions : RenderBoxContainerDefaultsMixinContainerRenderObjectMixinRenderBox< + RenderBox, MultiChildLayoutParentData> { + public _RenderCupertinoDialogActions( + float dialogWidth, + List children = null, + float dividerThickness = 0.0f + ) { + this._dialogWidth = dialogWidth; + this._dividerThickness = dividerThickness; + this.addAll(children); + } + + public float dialogWidth { + get { return this._dialogWidth; } + set { + if (value != this._dialogWidth) { + this._dialogWidth = value; + this.markNeedsLayout(); + } + } + } + + float _dialogWidth; + + + public float dividerThickness { + get { return this._dividerThickness; } + set { + if (value != this._dividerThickness) { + this._dividerThickness = value; + this.markNeedsLayout(); + } + } + } + + float _dividerThickness; + + readonly Paint _buttonBackgroundPaint = new Paint() { + color = CupertinoDialogUtils._kDialogColor, + style = PaintingStyle.fill + }; + + readonly Paint _pressedButtonBackgroundPaint = new Paint() { + color = CupertinoDialogUtils._kDialogPressedColor, + style = PaintingStyle.fill + }; + + + readonly Paint _dividerPaint = new Paint() { + color = CupertinoDialogUtils._kButtonDividerColor, + style = PaintingStyle.fill + }; + + List _pressedButtons { + get { + List childList = new List(); + + RenderBox currentChild = this.firstChild; + while (currentChild != null) { + D.assert(currentChild.parentData is _DialogActionButtonParentData); + _DialogActionButtonParentData parentData = currentChild.parentData as _DialogActionButtonParentData; + if (parentData.isPressed) { + childList.Add(currentChild); + } + + currentChild = this.childAfter(currentChild); + } + + return childList; + } + } + + bool _isButtonPressed { + get { + RenderBox currentChild = this.firstChild; + while (currentChild != null) { + D.assert(currentChild.parentData is _DialogActionButtonParentData); + _DialogActionButtonParentData parentData = currentChild.parentData as _DialogActionButtonParentData; + if (parentData.isPressed) { + return true; + } + + currentChild = this.childAfter(currentChild); + } + + return false; + } + } + + public override void setupParentData(RenderObject child) { + if (!(child.parentData is _DialogActionButtonParentData)) { + child.parentData = new _DialogActionButtonParentData(); + } + } + + protected override float computeMinIntrinsicWidth(float height) { + return this.dialogWidth; + } + + protected override float computeMaxIntrinsicWidth(float height) { + return this.dialogWidth; + } + + protected override float computeMinIntrinsicHeight(float width) { + float minHeight; + if (this.childCount == 0) { + minHeight = 0.0f; + } + else if (this.childCount == 1) { + minHeight = this._computeMinIntrinsicHeightSideBySide(width); + } + else { + if (this.childCount == 2 && this._isSingleButtonRow(width)) { + minHeight = this._computeMinIntrinsicHeightSideBySide(width); + } + else { + minHeight = this._computeMinIntrinsicHeightStacked(width); + } + } + + return minHeight; + } + + float _computeMinIntrinsicHeightSideBySide(float width) { + D.assert(this.childCount >= 1 && this.childCount <= 2); + float minHeight; + if (this.childCount == 1) { + minHeight = this.firstChild.getMinIntrinsicHeight(width); + } + else { + float perButtonWidth = (width - this.dividerThickness) / 2.0f; + minHeight = Mathf.Max(this.firstChild.getMinIntrinsicHeight(perButtonWidth), + this.lastChild.getMinIntrinsicHeight(perButtonWidth) + ); + } + + return minHeight; + } + + float _computeMinIntrinsicHeightStacked(float width) { + D.assert(this.childCount >= 2); + return this.firstChild.getMinIntrinsicHeight(width) + + this.dividerThickness + + (0.5f * this.childAfter(this.firstChild).getMinIntrinsicHeight(width)); + } + + protected internal override float computeMaxIntrinsicHeight(float width) { + float maxHeight; + if (this.childCount == 0) { + maxHeight = 0.0f; + } + else if (this.childCount == 1) { + maxHeight = this.firstChild.getMaxIntrinsicHeight(width); + } + else if (this.childCount == 2) { + if (this._isSingleButtonRow(width)) { + float perButtonWidth = (width - this.dividerThickness) / 2.0f; + maxHeight = Mathf.Max(this.firstChild.getMaxIntrinsicHeight(perButtonWidth), + this.lastChild.getMaxIntrinsicHeight(perButtonWidth) + ); + } + else { + maxHeight = this._computeMaxIntrinsicHeightStacked(width); + } + } + else { + maxHeight = this._computeMaxIntrinsicHeightStacked(width); + } + + return maxHeight; + } + + float _computeMaxIntrinsicHeightStacked(float width) { + D.assert(this.childCount >= 2); + float allDividersHeight = (this.childCount - 1) * this.dividerThickness; + float heightAccumulation = allDividersHeight; + RenderBox button = this.firstChild; + while (button != null) { + heightAccumulation += button.getMaxIntrinsicHeight(width); + button = this.childAfter(button); + } + + return heightAccumulation; + } + + bool _isSingleButtonRow(float width) { + bool isSingleButtonRow; + if (this.childCount == 1) { + isSingleButtonRow = true; + } + else if (this.childCount == 2) { + float sideBySideWidth = this.firstChild.getMaxIntrinsicWidth(float.PositiveInfinity) + + this.dividerThickness + + this.lastChild.getMaxIntrinsicWidth(float.PositiveInfinity); + isSingleButtonRow = sideBySideWidth <= width; + } + else { + isSingleButtonRow = false; + } + + return isSingleButtonRow; + } + + protected override void performLayout() { + if (this._isSingleButtonRow(this.dialogWidth)) { + if (this.childCount == 1) { + this.firstChild.layout( + this.constraints, + parentUsesSize: true + ); + this.size = this.constraints.constrain( + new Size(this.dialogWidth, this.firstChild.size.height) + ); + } + else { + BoxConstraints perButtonnewraints = new BoxConstraints( + minWidth: (this.constraints.minWidth - this.dividerThickness) / 2.0f, + maxWidth: (this.constraints.maxWidth - this.dividerThickness) / 2.0f, + minHeight: 0.0f, + maxHeight: float.PositiveInfinity + ); + this.firstChild.layout( + perButtonnewraints, + parentUsesSize: true + ); + this.lastChild.layout( + perButtonnewraints, + parentUsesSize: true + ); + D.assert(this.lastChild.parentData is MultiChildLayoutParentData); + MultiChildLayoutParentData secondButtonParentData = + this.lastChild.parentData as MultiChildLayoutParentData; + secondButtonParentData.offset = + new Offset(this.firstChild.size.width + this.dividerThickness, 0.0f); + this.size = this.constraints.constrain( + new Size(this.dialogWidth, + Mathf.Max(this.firstChild.size.height, this.lastChild.size.height + ) + ) + ); + } + } + else { + BoxConstraints perButtonnewraints = this.constraints.copyWith( + minHeight: 0.0f, + maxHeight: float.PositiveInfinity + ); + RenderBox child = this.firstChild; + int index = 0; + float verticalOffset = 0.0f; + while (child != null) { + child.layout( + perButtonnewraints, + parentUsesSize: true + ); + D.assert(child.parentData is MultiChildLayoutParentData); + MultiChildLayoutParentData parentData = child.parentData as MultiChildLayoutParentData; + parentData.offset = new Offset(0.0f, verticalOffset); + verticalOffset += child.size.height; + if (index < this.childCount - 1) { + verticalOffset += this.dividerThickness; + } + + index += 1; + child = this.childAfter(child); + } + + this.size = this.constraints.constrain( + new Size(this.dialogWidth, verticalOffset) + ); + } + } + + public override void paint(PaintingContext context, Offset offset) { + Canvas canvas = context.canvas; + if (this._isSingleButtonRow(this.size.width)) { + this._drawButtonBackgroundsAndDividersSingleRow(canvas, offset); + } + else { + this._drawButtonBackgroundsAndDividersStacked(canvas, offset); + } + + this._drawButtons(context, offset); + } + + void _drawButtonBackgroundsAndDividersSingleRow(Canvas canvas, Offset offset) { + Rect verticalDivider = this.childCount == 2 && !this._isButtonPressed + ? Rect.fromLTWH( + offset.dx + this.firstChild.size.width, + offset.dy, this.dividerThickness, + Mathf.Max(this.firstChild.size.height, this.lastChild.size.height + ) + ) + : Rect.zero; + List pressedButtonRects = new List(); + + foreach (var item in this._pressedButtons) { + MultiChildLayoutParentData buttonParentData = item.parentData as MultiChildLayoutParentData; + pressedButtonRects.Add( + Rect.fromLTWH( + offset.dx + buttonParentData.offset.dx, + offset.dy + buttonParentData.offset.dy, + item.size.width, + item.size.height + )); + } + + Path backgroundFillPath = new Path(); + + // backgroundFillPath.fillType = PathFillType.evenOdd; + backgroundFillPath.addRect(Rect.fromLTWH(0.0f, 0.0f, this.size.width, this.size.height)); + backgroundFillPath.addRect(verticalDivider); + + for (int i = 0; i < pressedButtonRects.Count; i += 1) { + backgroundFillPath.addRect(pressedButtonRects[i]); + } + + canvas.drawPath( + backgroundFillPath, this._buttonBackgroundPaint + ); + Path pressedBackgroundFillPath = new Path(); + for (int i = 0; i < pressedButtonRects.Count; i += 1) { + pressedBackgroundFillPath.addRect(pressedButtonRects[i]); + } + + canvas.drawPath( + pressedBackgroundFillPath, this._pressedButtonBackgroundPaint + ); + Path dividersPath = new Path(); + dividersPath.addRect(verticalDivider); + canvas.drawPath( + dividersPath, this._dividerPaint + ); + } + + void _drawButtonBackgroundsAndDividersStacked(Canvas canvas, Offset offset) { + Offset dividerOffset = new Offset(0.0f, this.dividerThickness); + Path backgroundFillPath = new Path(); + // ..fillType = PathFillType.evenOdd + backgroundFillPath.addRect(Rect.fromLTWH(0.0f, 0.0f, this.size.width, this.size.height)); + Path pressedBackgroundFillPath = new Path(); + Path dividersPath = new Path(); + Offset accumulatingOffset = offset; + RenderBox child = this.firstChild; + RenderBox prevChild = null; + + while (child != null) { + D.assert(child.parentData is _DialogActionButtonParentData); + _DialogActionButtonParentData currentButtonParentData = + child.parentData as _DialogActionButtonParentData; + bool isButtonPressed = currentButtonParentData.isPressed; + bool isPrevButtonPressed = false; + if (prevChild != null) { + D.assert(prevChild.parentData is _DialogActionButtonParentData); + _DialogActionButtonParentData previousButtonParentData = + prevChild.parentData as _DialogActionButtonParentData; + isPrevButtonPressed = previousButtonParentData.isPressed; + } + + bool isDividerPresent = child != this.firstChild; + bool isDividerPainted = isDividerPresent && !(isButtonPressed || isPrevButtonPressed); + Rect dividerRect = Rect.fromLTWH( + accumulatingOffset.dx, + accumulatingOffset.dy, this.size.width, this.dividerThickness + ); + Rect buttonBackgroundRect = Rect.fromLTWH( + accumulatingOffset.dx, + accumulatingOffset.dy + (isDividerPresent ? this.dividerThickness : 0.0f), this.size.width, + child.size.height + ); + if (isButtonPressed) { + backgroundFillPath.addRect(buttonBackgroundRect); + pressedBackgroundFillPath.addRect(buttonBackgroundRect); + } + + if (isDividerPainted) { + backgroundFillPath.addRect(dividerRect); + dividersPath.addRect(dividerRect); + } + + accumulatingOffset += (isDividerPresent ? dividerOffset : Offset.zero) + + new Offset(0.0f, child.size.height); + prevChild = child; + child = this.childAfter(child); + } + + canvas.drawPath(backgroundFillPath, this._buttonBackgroundPaint); + canvas.drawPath(pressedBackgroundFillPath, this._pressedButtonBackgroundPaint); + canvas.drawPath(dividersPath, this._dividerPaint); + } + + void _drawButtons(PaintingContext context, Offset offset) { + RenderBox child = this.firstChild; + while (child != null) { + MultiChildLayoutParentData childParentData = child.parentData as MultiChildLayoutParentData; + context.paintChild(child, childParentData.offset + offset); + child = this.childAfter(child); + } + } + + protected override bool hitTestChildren(HitTestResult result, + Offset position = null + ) { + return this.defaultHitTestChildren(result, position: position); + } + } +} \ No newline at end of file diff --git a/Runtime/cupertino/dialog.cs.meta b/Runtime/cupertino/dialog.cs.meta new file mode 100644 index 00000000..555583a6 --- /dev/null +++ b/Runtime/cupertino/dialog.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e184ed6bf781845be961798e888aa6ef +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/cupertino/icons.cs b/Runtime/cupertino/icons.cs new file mode 100644 index 00000000..96e524c2 --- /dev/null +++ b/Runtime/cupertino/icons.cs @@ -0,0 +1,142 @@ +using Unity.UIWidgets.widgets; + +namespace Unity.UIWidgets.cupertino { + public static class CupertinoIcons { + public const string iconFont = "CupertinoIcons"; + + public static readonly IconData left_chevron = new IconData(0xf3d2, fontFamily: iconFont); + public static readonly IconData right_chevron = new IconData(0xf3d3, fontFamily: iconFont); + public static readonly IconData share = new IconData(0xf4ca, fontFamily: iconFont); + public static readonly IconData share_solid = new IconData(0xf4cb, fontFamily: iconFont); + public static readonly IconData book = new IconData(0xf3e7, fontFamily: iconFont); + public static readonly IconData book_solid = new IconData(0xf3e8, fontFamily: iconFont); + public static readonly IconData bookmark = new IconData(0xf3e9, fontFamily: iconFont); + public static readonly IconData bookmark_solid = new IconData(0xf3ea, fontFamily: iconFont); + public static readonly IconData info = new IconData(0xf44c, fontFamily: iconFont); + public static readonly IconData reply = new IconData(0xf4c6, fontFamily: iconFont); + public static readonly IconData conversation_bubble = new IconData(0xf3fb, fontFamily: iconFont); + public static readonly IconData profile_circled = new IconData(0xf419, fontFamily: iconFont); + public static readonly IconData plus_circled = new IconData(0xf48a, fontFamily: iconFont); + public static readonly IconData minus_circled = new IconData(0xf463, fontFamily: iconFont); + public static readonly IconData flag = new IconData(0xf42c, fontFamily: iconFont); + public static readonly IconData search = new IconData(0xf4a5, fontFamily: iconFont); + public static readonly IconData check_mark = new IconData(0xf3fd, fontFamily: iconFont); + public static readonly IconData check_mark_circled = new IconData(0xf3fe, fontFamily: iconFont); + public static readonly IconData check_mark_circled_solid = new IconData(0xf3ff, fontFamily: iconFont); + public static readonly IconData circle = new IconData(0xf401, fontFamily: iconFont); + public static readonly IconData circle_filled = new IconData(0xf400, fontFamily: iconFont); + public static readonly IconData back = new IconData(0xf3cf, fontFamily: iconFont); + public static readonly IconData forward = new IconData(0xf3d1, fontFamily: iconFont); + public static readonly IconData home = new IconData(0xf447, fontFamily: iconFont); + public static readonly IconData shopping_cart = new IconData(0xf3f7, fontFamily: iconFont); + public static readonly IconData ellipsis = new IconData(0xf46a, fontFamily: iconFont); + public static readonly IconData phone = new IconData(0xf4b8, fontFamily: iconFont); + public static readonly IconData phone_solid = new IconData(0xf4b9, fontFamily: iconFont); + public static readonly IconData down_arrow = new IconData(0xf35d, fontFamily: iconFont); + public static readonly IconData up_arrow = new IconData(0xf366, fontFamily: iconFont); + public static readonly IconData battery_charging = new IconData(0xf111, fontFamily: iconFont); + public static readonly IconData battery_empty = new IconData(0xf112, fontFamily: iconFont); + public static readonly IconData battery_full = new IconData(0xf113, fontFamily: iconFont); + public static readonly IconData battery_75_percent = new IconData(0xf114, fontFamily: iconFont); + public static readonly IconData battery_25_percent = new IconData(0xf115, fontFamily: iconFont); + public static readonly IconData bluetooth = new IconData(0xf116, fontFamily: iconFont); + public static readonly IconData restart = new IconData(0xf21c, fontFamily: iconFont); + public static readonly IconData reply_all = new IconData(0xf21d, fontFamily: iconFont); + public static readonly IconData reply_thick_solid = new IconData(0xf21e, fontFamily: iconFont); + public static readonly IconData share_up = new IconData(0xf220, fontFamily: iconFont); + public static readonly IconData shuffle_thick = new IconData(0xf221, fontFamily: iconFont); + public static readonly IconData photo_camera = new IconData(0xf3f5, fontFamily: iconFont); + public static readonly IconData photo_camera_solid = new IconData(0xf3f6, fontFamily: iconFont); + public static readonly IconData video_camera = new IconData(0xf4cc, fontFamily: iconFont); + public static readonly IconData video_camera_solid = new IconData(0xf4cd, fontFamily: iconFont); + public static readonly IconData switch_camera = new IconData(0xf49e, fontFamily: iconFont); + public static readonly IconData switch_camera_solid = new IconData(0xf49f, fontFamily: iconFont); + public static readonly IconData collections = new IconData(0xf3c9, fontFamily: iconFont); + public static readonly IconData collections_solid = new IconData(0xf3ca, fontFamily: iconFont); + public static readonly IconData folder = new IconData(0xf434, fontFamily: iconFont); + public static readonly IconData folder_solid = new IconData(0xf435, fontFamily: iconFont); + public static readonly IconData folder_open = new IconData(0xf38a, fontFamily: iconFont); + public static readonly IconData delete = new IconData(0xf4c4, fontFamily: iconFont); + public static readonly IconData delete_solid = new IconData(0xf4c5, fontFamily: iconFont); + public static readonly IconData delete_simple = new IconData(0xf37f, fontFamily: iconFont); + public static readonly IconData pen = new IconData(0xf2bf, fontFamily: iconFont); + public static readonly IconData pencil = new IconData(0xf37e, fontFamily: iconFont); + public static readonly IconData create = new IconData(0xf417, fontFamily: iconFont); + public static readonly IconData create_solid = new IconData(0xf417, fontFamily: iconFont); + public static readonly IconData refresh = new IconData(0xf49a, fontFamily: iconFont); + public static readonly IconData refresh_circled = new IconData(0xf49b, fontFamily: iconFont); + public static readonly IconData refresh_circled_solid = new IconData(0xf49c, fontFamily: iconFont); + public static readonly IconData refresh_thin = new IconData(0xf49d, fontFamily: iconFont); + public static readonly IconData refresh_thick = new IconData(0xf3a8, fontFamily: iconFont); + public static readonly IconData refresh_bold = new IconData(0xf21c, fontFamily: iconFont); + public static readonly IconData clear_thick = new IconData(0xf2d7, fontFamily: iconFont); + public static readonly IconData clear_thick_circled = new IconData(0xf36e, fontFamily: iconFont); + public static readonly IconData clear = new IconData(0xf404, fontFamily: iconFont); + public static readonly IconData clear_circled = new IconData(0xf405, fontFamily: iconFont); + public static readonly IconData clear_circled_solid = new IconData(0xf406, fontFamily: iconFont); + public static readonly IconData add = new IconData(0xf489, fontFamily: iconFont); + public static readonly IconData add_circled = new IconData(0xf48a, fontFamily: iconFont); + public static readonly IconData add_circled_solid = new IconData(0xf48b, fontFamily: iconFont); + public static readonly IconData gear = new IconData(0xf43c, fontFamily: iconFont); + public static readonly IconData gear_solid = new IconData(0xf43d, fontFamily: iconFont); + public static readonly IconData gear_big = new IconData(0xf2f7, fontFamily: iconFont); + public static readonly IconData settings = new IconData(0xf411, fontFamily: iconFont); + public static readonly IconData settings_solid = new IconData(0xf412, fontFamily: iconFont); + public static readonly IconData music_note = new IconData(0xf46b, fontFamily: iconFont); + public static readonly IconData double_music_note = new IconData(0xf46c, fontFamily: iconFont); + public static readonly IconData play_arrow = new IconData(0xf487, fontFamily: iconFont); + public static readonly IconData play_arrow_solid = new IconData(0xf488, fontFamily: iconFont); + public static readonly IconData pause = new IconData(0xf477, fontFamily: iconFont); + public static readonly IconData pause_solid = new IconData(0xf478, fontFamily: iconFont); + public static readonly IconData loop = new IconData(0xf449, fontFamily: iconFont); + public static readonly IconData loop_thick = new IconData(0xf44a, fontFamily: iconFont); + public static readonly IconData volume_down = new IconData(0xf3b7, fontFamily: iconFont); + public static readonly IconData volume_mute = new IconData(0xf3b8, fontFamily: iconFont); + public static readonly IconData volume_off = new IconData(0xf3b9, fontFamily: iconFont); + public static readonly IconData volume_up = new IconData(0xf3ba, fontFamily: iconFont); + public static readonly IconData fullscreen = new IconData(0xf386, fontFamily: iconFont); + public static readonly IconData fullscreen_exit = new IconData(0xf37d, fontFamily: iconFont); + public static readonly IconData mic_off = new IconData(0xf45f, fontFamily: iconFont); + public static readonly IconData mic = new IconData(0xf460, fontFamily: iconFont); + public static readonly IconData mic_solid = new IconData(0xf461, fontFamily: iconFont); + public static readonly IconData clock = new IconData(0xf4be, fontFamily: iconFont); + public static readonly IconData clock_solid = new IconData(0xf4bf, fontFamily: iconFont); + public static readonly IconData time = new IconData(0xf402, fontFamily: iconFont); + public static readonly IconData time_solid = new IconData(0xf403, fontFamily: iconFont); + public static readonly IconData padlock = new IconData(0xf4c8, fontFamily: iconFont); + public static readonly IconData padlock_solid = new IconData(0xf4c9, fontFamily: iconFont); + public static readonly IconData eye = new IconData(0xf424, fontFamily: iconFont); + public static readonly IconData eye_solid = new IconData(0xf425, fontFamily: iconFont); + public static readonly IconData person = new IconData(0xf47d, fontFamily: iconFont); + public static readonly IconData person_solid = new IconData(0xf47e, fontFamily: iconFont); + public static readonly IconData person_add = new IconData(0xf47f, fontFamily: iconFont); + public static readonly IconData person_add_solid = new IconData(0xf480, fontFamily: iconFont); + public static readonly IconData group = new IconData(0xf47b, fontFamily: iconFont); + public static readonly IconData group_solid = new IconData(0xf47c, fontFamily: iconFont); + public static readonly IconData mail = new IconData(0xf422, fontFamily: iconFont); + public static readonly IconData mail_solid = new IconData(0xf423, fontFamily: iconFont); + public static readonly IconData location = new IconData(0xf455, fontFamily: iconFont); + public static readonly IconData location_solid = new IconData(0xf456, fontFamily: iconFont); + public static readonly IconData tag = new IconData(0xf48c, fontFamily: iconFont); + public static readonly IconData tag_solid = new IconData(0xf48d, fontFamily: iconFont); + public static readonly IconData tags = new IconData(0xf48e, fontFamily: iconFont); + public static readonly IconData tags_solid = new IconData(0xf48f, fontFamily: iconFont); + public static readonly IconData bus = new IconData(0xf36d, fontFamily: iconFont); + public static readonly IconData car = new IconData(0xf36f, fontFamily: iconFont); + public static readonly IconData car_detailed = new IconData(0xf2c1, fontFamily: iconFont); + public static readonly IconData train_style_one = new IconData(0xf3af, fontFamily: iconFont); + public static readonly IconData train_style_two = new IconData(0xf3b4, fontFamily: iconFont); + public static readonly IconData paw = new IconData(0xf479, fontFamily: iconFont); + public static readonly IconData paw_solid = new IconData(0xf47a, fontFamily: iconFont); + public static readonly IconData game_controller = new IconData(0xf43a, fontFamily: iconFont); + public static readonly IconData game_controller_solid = new IconData(0xf43b, fontFamily: iconFont); + public static readonly IconData lab_flask = new IconData(0xf430, fontFamily: iconFont); + public static readonly IconData lab_flask_solid = new IconData(0xf431, fontFamily: iconFont); + public static readonly IconData heart = new IconData(0xf442, fontFamily: iconFont); + public static readonly IconData heart_solid = new IconData(0xf443, fontFamily: iconFont); + public static readonly IconData bell = new IconData(0xf3e1, fontFamily: iconFont); + public static readonly IconData bell_solid = new IconData(0xf3e2, fontFamily: iconFont); + public static readonly IconData news = new IconData(0xf471, fontFamily: iconFont); + public static readonly IconData news_solid = new IconData(0xf472, fontFamily: iconFont); + } +} \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/gallery/icons.cs.meta b/Runtime/cupertino/icons.cs.meta similarity index 83% rename from Samples/UIWidgetsGallery/gallery/icons.cs.meta rename to Runtime/cupertino/icons.cs.meta index 6fea0324..0ccd6688 100644 --- a/Samples/UIWidgetsGallery/gallery/icons.cs.meta +++ b/Runtime/cupertino/icons.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 7b7592e2675d347bb9036ed6cb4fabe0 +guid: 1a5cd7317c4754d8fa8108ac59749344 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Runtime/cupertino/localization.cs b/Runtime/cupertino/localization.cs new file mode 100644 index 00000000..ecb26994 --- /dev/null +++ b/Runtime/cupertino/localization.cs @@ -0,0 +1,242 @@ +using System; +using System.Collections.Generic; +using RSG; +using Unity.UIWidgets.ui; +using Unity.UIWidgets.widgets; + +namespace Unity.UIWidgets.cupertino { + public enum DatePickerDateTimeOrder { + date_time_dayPeriod, + date_dayPeriod_time, + time_dayPeriod_date, + dayPeriod_time_date + } + + public enum DatePickerDateOrder { + dmy, + mdy, + ymd, + ydm + } + + public abstract class CupertinoLocalizations { + public abstract string datePickerYear(int yearIndex); + + public abstract string datePickerMonth(int monthIndex); + + public abstract string datePickerDayOfMonth(int dayIndex); + + public abstract string datePickerMediumDate(DateTime date); + + public abstract string datePickerHour(int hour); + + public abstract string datePickerHourSemanticsLabel(int hour); + + public abstract string datePickerMinute(int minute); + + public abstract string datePickerMinuteSemanticsLabel(int minute); + + public abstract DatePickerDateOrder datePickerDateOrder { get; } + + public abstract DatePickerDateTimeOrder datePickerDateTimeOrder { get; } + + public abstract string anteMeridiemAbbreviation { get; } + + public abstract string postMeridiemAbbreviation { get; } + + public abstract string alertDialogLabel { get; } + + public abstract string timerPickerHour(int hour); + + public abstract string timerPickerMinute(int minute); + + public abstract string timerPickerSecond(int second); + + public abstract string timerPickerHourLabel(int hour); + + public abstract string timerPickerMinuteLabel(int minute); + + public abstract string timerPickerSecondLabel(int second); + + public abstract string cutButtonLabel { get; } + + public abstract string copyButtonLabel { get; } + + public abstract string pasteButtonLabel { get; } + + public abstract string selectAllButtonLabel { get; } + + public static CupertinoLocalizations of(BuildContext context) { + return Localizations.of(context, typeof(CupertinoLocalizations)); + } + } + + class _CupertinoLocalizationsDelegate : LocalizationsDelegate { + public _CupertinoLocalizationsDelegate() { } + + public override bool isSupported(Locale locale) { + return locale.languageCode == "en"; + } + + public override IPromise load(Locale locale) { + return DefaultCupertinoLocalizations.load(locale); + } + + public override bool shouldReload(LocalizationsDelegate old) { + return false; + } + + public override string ToString() { + return "DefaultCupertinoLocalizations.delegate(en_US)"; + } + } + + public class DefaultCupertinoLocalizations : CupertinoLocalizations { + public DefaultCupertinoLocalizations() { } + + static readonly List _shortWeekdays = new List { + "Mon", + "Tue", + "Wed", + "Thu", + "Fri", + "Sat", + "Sun" + }; + + static readonly List _shortMonths = new List { + "Jan", + "Feb", + "Mar", + "Apr", + "May", + "Jun", + "Jul", + "Aug", + "Sep", + "Oct", + "Nov", + "Dec" + }; + + static readonly List _months = new List { + "January", + "February", + "March", + "April", + "May", + "June", + "July", + "August", + "September", + "October", + "November", + "December" + }; + + public override string datePickerYear(int yearIndex) { + return yearIndex.ToString(); + } + + public override string datePickerMonth(int monthIndex) { + return _months[monthIndex - 1]; + } + + public override string datePickerDayOfMonth(int dayIndex) { + return dayIndex.ToString(); + } + + public override string datePickerHour(int hour) { + return hour.ToString(); + } + + public override string datePickerHourSemanticsLabel(int hour) { + return hour.ToString() + " o'clock"; + } + + public override string datePickerMinute(int minute) { + return minute.ToString().PadLeft(2, '0'); + } + + public override string datePickerMinuteSemanticsLabel(int minute) { + if (minute == 1) { + return "1 minute"; + } + + return minute.ToString() + " minutes"; + } + + public override string datePickerMediumDate(DateTime date) { + var day = _shortWeekdays[((int) date.DayOfWeek + 6) % 7]; + var month = _shortMonths[date.Month - 1]; + return $"{day} {month} {date.Day.ToString().PadRight(2)} "; + } + + public override DatePickerDateOrder datePickerDateOrder { + get { return DatePickerDateOrder.mdy; } + } + + public override DatePickerDateTimeOrder datePickerDateTimeOrder { + get { return DatePickerDateTimeOrder.date_time_dayPeriod; } + } + + public override string anteMeridiemAbbreviation { + get { return "AM"; } + } + + public override string postMeridiemAbbreviation { + get { return "PM"; } + } + + public override string alertDialogLabel { + get { return "Alert"; } + } + + public override string timerPickerHour(int hour) { + return hour.ToString(); + } + + public override string timerPickerMinute(int minute) { + return minute.ToString(); + } + + public override string timerPickerSecond(int second) { + return second.ToString(); + } + + public override string timerPickerHourLabel(int hour) { + return hour == 1 ? "hour" : "hours"; + } + + public override string timerPickerMinuteLabel(int minute) { + return "min"; + } + + public override string timerPickerSecondLabel(int second) { + return "sec"; + } + + public override string cutButtonLabel { + get { return "Cut"; } + } + + public override string copyButtonLabel { + get { return "Copy"; } + } + + public override string pasteButtonLabel { + get { return "Paste"; } + } + + public override string selectAllButtonLabel { + get { return "Select All"; } + } + + public static IPromise load(Locale locale) { + return Promise.Resolved(new DefaultCupertinoLocalizations()); + } + + public static readonly LocalizationsDelegate + del = new _CupertinoLocalizationsDelegate(); + } +} \ No newline at end of file diff --git a/Runtime/cupertino/localization.cs.meta b/Runtime/cupertino/localization.cs.meta new file mode 100644 index 00000000..1d89ba7c --- /dev/null +++ b/Runtime/cupertino/localization.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: db635d91487ab4ea49c0a23ca5b6cc85 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/cupertino/nav_bar.cs b/Runtime/cupertino/nav_bar.cs new file mode 100644 index 00000000..b873f4b9 --- /dev/null +++ b/Runtime/cupertino/nav_bar.cs @@ -0,0 +1,1857 @@ +using System; +using System.Collections.Generic; +using Unity.UIWidgets.animation; +using Unity.UIWidgets.foundation; +using Unity.UIWidgets.painting; +using Unity.UIWidgets.rendering; +using Unity.UIWidgets.service; +using Unity.UIWidgets.ui; +using Unity.UIWidgets.widgets; +using UnityEngine; +using Color = Unity.UIWidgets.ui.Color; +using Rect = Unity.UIWidgets.ui.Rect; +using TextStyle = Unity.UIWidgets.painting.TextStyle; + +namespace Unity.UIWidgets.cupertino { + class NavBarUtils { + public const float _kNavBarPersistentHeight = 44.0f; + + public const float _kNavBarLargeTitleHeightExtension = 52.0f; + + public const float _kNavBarShowLargeTitleThreshold = 10.0f; + + public const float _kNavBarEdgePadding = 16.0f; + + public const float _kNavBarBackButtonTapWidth = 50.0f; + + public static readonly TimeSpan _kNavBarTitleFadeDuration = new TimeSpan(0, 0, 0, 0, 150); + + public static readonly Color _kDefaultNavBarBorderColor = new Color(0x4C000000); + + public static readonly Border _kDefaultNavBarBorder = new Border( + bottom: new BorderSide( + color: _kDefaultNavBarBorderColor, + width: 0.0f, // One physical pixel. + style: BorderStyle.solid + ) + ); + + public static readonly _HeroTag _defaultHeroTag = new _HeroTag(null); + + public static Widget _wrapWithBackground( + Border border = null, + Color backgroundColor = null, + Widget child = null, + bool updateSystemUiOverlay = true + ) { + Widget result = child; + if (updateSystemUiOverlay) { + bool darkBackground = backgroundColor.computeLuminance() < 0.179f; + SystemUiOverlayStyle overlayStyle = darkBackground + ? SystemUiOverlayStyle.light + : SystemUiOverlayStyle.dark; + result = new AnnotatedRegion( + value: overlayStyle, + sized: true, + child: result + ); + } + + DecoratedBox childWithBackground = new DecoratedBox( + decoration: new BoxDecoration( + border: border, + color: backgroundColor + ), + child: result + ); + if (backgroundColor.alpha == 0xFF) { + return childWithBackground; + } + + return new ClipRect( + child: new BackdropFilter( + filter: ImageFilter.blur(sigmaX: 10.0f, sigmaY: 10.0f), + child: childWithBackground + ) + ); + } + + public static Widget _wrapActiveColor(Color color, BuildContext context, Widget child) { + if (color == null) { + return child; + } + + return new CupertinoTheme( + data: CupertinoTheme.of(context).copyWith(primaryColor: color), + child: child + ); + } + + public static bool _isTransitionable(BuildContext context) { + ModalRoute route = ModalRoute.of(context); + return route is PageRoute && !(route as PageRoute).fullscreenDialog; + } + + public static HeroFlightShuttleBuilder _navBarHeroFlightShuttleBuilder = ( + BuildContext flightContext, + Animation animation, + HeroFlightDirection flightDirection, + BuildContext fromHeroContext, + BuildContext toHeroContext + ) => { + D.assert(animation != null); + + D.assert(fromHeroContext != null); + D.assert(toHeroContext != null); + D.assert(fromHeroContext.widget is Hero); + D.assert(toHeroContext.widget is Hero); + Hero fromHeroWidget = (Hero) fromHeroContext.widget; + Hero toHeroWidget = (Hero) toHeroContext.widget; + D.assert(fromHeroWidget.child is _TransitionableNavigationBar); + D.assert(toHeroWidget.child is _TransitionableNavigationBar); + _TransitionableNavigationBar fromNavBar = (_TransitionableNavigationBar) fromHeroWidget.child; + _TransitionableNavigationBar toNavBar = (_TransitionableNavigationBar) toHeroWidget.child; + D.assert(fromNavBar.componentsKeys != null); + D.assert(toNavBar.componentsKeys != null); + D.assert( + fromNavBar.componentsKeys.navBarBoxKey.currentContext.owner != null, + () => "The from nav bar to Hero must have been mounted in the previous frame" + ); + + D.assert( + toNavBar.componentsKeys.navBarBoxKey.currentContext.owner != null, + () => "The to nav bar to Hero must have been mounted in the previous frame" + ); + + switch (flightDirection) { + case HeroFlightDirection.push: + return new _NavigationBarTransition( + animation: animation, + bottomNavBar: fromNavBar, + topNavBar: toNavBar + ); + case HeroFlightDirection.pop: + return new _NavigationBarTransition( + animation: animation, + bottomNavBar: toNavBar, + topNavBar: fromNavBar + ); + } + + throw new UIWidgetsError($"Unknown flight direction: {flightDirection}"); + }; + + public static CreateRectTween _linearTranslateWithLargestRectSizeTween = (Rect begin, Rect end) => { + Size largestSize = new Size( + Mathf.Max(begin.size.width, end.size.width), + Mathf.Max(begin.size.height, end.size.height) + ); + return new RectTween( + begin: begin.topLeft & largestSize, + end: end.topLeft & largestSize + ); + }; + + public static TransitionBuilder _navBarHeroLaunchPadBuilder = ( + BuildContext context, + Widget child + ) => { + D.assert(child is _TransitionableNavigationBar); + return new Visibility( + maintainSize: true, + maintainAnimation: true, + maintainState: true, + visible: false, + child: child + ); + }; + } + + + class _HeroTag { + public _HeroTag( + NavigatorState navigator + ) { + this.navigator = navigator; + } + + public readonly NavigatorState navigator; + + public override string ToString() { + return $"Default Hero tag for Cupertino navigation bars with navigator {this.navigator}"; + } + + public bool Equals(_HeroTag other) { + if (ReferenceEquals(null, other)) { + return false; + } + + if (ReferenceEquals(this, other)) { + return true; + } + + return this.navigator == other.navigator; + } + + public override bool Equals(object obj) { + if (ReferenceEquals(null, obj)) { + return false; + } + + if (ReferenceEquals(this, obj)) { + return true; + } + + if (obj.GetType() != this.GetType()) { + return false; + } + + return this.Equals((_HeroTag) obj); + } + + public override int GetHashCode() { + return this.navigator.GetHashCode(); + } + + public static bool operator ==(_HeroTag left, _HeroTag right) { + return Equals(left, right); + } + + public static bool operator !=(_HeroTag left, _HeroTag right) { + return !Equals(left, right); + } + } + + public class CupertinoNavigationBar : ObstructingPreferredSizeWidget { + public CupertinoNavigationBar( + Key key = null, + Widget leading = null, + bool automaticallyImplyLeading = true, + bool automaticallyImplyMiddle = true, + string previousPageTitle = null, + Widget middle = null, + Widget trailing = null, + Border border = null, + Color backgroundColor = null, + EdgeInsets padding = null, + Color actionsForegroundColor = null, + bool transitionBetweenRoutes = true, + object heroTag = null + ) : base(key: key) { + this.leading = leading; + this.automaticallyImplyLeading = automaticallyImplyLeading; + this.automaticallyImplyMiddle = automaticallyImplyMiddle; + this.previousPageTitle = previousPageTitle; + this.middle = middle; + this.trailing = trailing; + this.border = border ?? NavBarUtils._kDefaultNavBarBorder; + this.backgroundColor = backgroundColor; + this.padding = padding; + this.actionsForegroundColor = actionsForegroundColor; + this.transitionBetweenRoutes = transitionBetweenRoutes; + this.heroTag = heroTag ?? NavBarUtils._defaultHeroTag; + + D.assert( + this.heroTag != null, + () => "heroTag cannot be null. Use transitionBetweenRoutes = false to " + + "disable Hero transition on this navigation bar." + ); + + D.assert( + !transitionBetweenRoutes || ReferenceEquals(this.heroTag, NavBarUtils._defaultHeroTag), + () => "Cannot specify a heroTag override if this navigation bar does not " + + "transition due to transitionBetweenRoutes = false." + ); + } + + public readonly Widget leading; + + public readonly bool automaticallyImplyLeading; + + public readonly bool automaticallyImplyMiddle; + + public readonly string previousPageTitle; + + public readonly Widget middle; + + public readonly Widget trailing; + + + public readonly Color backgroundColor; + + public readonly EdgeInsets padding; + + public readonly Border border; + + public readonly Color actionsForegroundColor; + + public readonly bool transitionBetweenRoutes; + + public readonly object heroTag; + + public override bool? fullObstruction { + get { return this.backgroundColor == null ? null : (bool?) (this.backgroundColor.alpha == 0xFF); } + } + + public override Size preferredSize { + get { return Size.fromHeight(NavBarUtils._kNavBarPersistentHeight); } + } + + public override State createState() { + return new _CupertinoNavigationBarState(); + } + } + + class _CupertinoNavigationBarState : State { + _NavigationBarStaticComponentsKeys keys; + + public override void initState() { + base.initState(); + this.keys = new _NavigationBarStaticComponentsKeys(); + } + + public override Widget build(BuildContext context) { + Color backgroundColor = this.widget.backgroundColor ?? CupertinoTheme.of(context).barBackgroundColor; + + _NavigationBarStaticComponents components = new _NavigationBarStaticComponents( + keys: this.keys, + route: ModalRoute.of(context), + userLeading: this.widget.leading, + automaticallyImplyLeading: this.widget.automaticallyImplyLeading, + automaticallyImplyTitle: this.widget.automaticallyImplyMiddle, + previousPageTitle: this.widget.previousPageTitle, + userMiddle: this.widget.middle, + userTrailing: this.widget.trailing, + padding: this.widget.padding, + userLargeTitle: null, + large: false + ); + + Widget navBar = NavBarUtils._wrapWithBackground( + border: this.widget.border, + backgroundColor: backgroundColor, + child: new DefaultTextStyle( + style: CupertinoTheme.of(context).textTheme.textStyle, + child: new _PersistentNavigationBar( + components: components, + padding: this.widget.padding + ) + ) + ); + + if (!this.widget.transitionBetweenRoutes || !NavBarUtils._isTransitionable(context)) { + return NavBarUtils._wrapActiveColor(this.widget.actionsForegroundColor, context, + navBar); // ignore: deprecated_member_use_from_same_package + } + + return NavBarUtils._wrapActiveColor( + this.widget.actionsForegroundColor, // ignore: deprecated_member_use_from_same_package + context, + new Builder( + builder: (BuildContext _context) => { + return new Hero( + tag: this.widget.heroTag as _HeroTag == NavBarUtils._defaultHeroTag + ? new _HeroTag(Navigator.of(_context)) + : this.widget.heroTag, + createRectTween: NavBarUtils._linearTranslateWithLargestRectSizeTween, + placeholderBuilder: NavBarUtils._navBarHeroLaunchPadBuilder, + flightShuttleBuilder: NavBarUtils._navBarHeroFlightShuttleBuilder, + transitionOnUserGestures: true, + child: new _TransitionableNavigationBar( + componentsKeys: this.keys, + backgroundColor: backgroundColor, + backButtonTextStyle: CupertinoTheme.of(_context).textTheme.navActionTextStyle, + titleTextStyle: CupertinoTheme.of(_context).textTheme.navTitleTextStyle, + largeTitleTextStyle: null, + border: this.widget.border, + hasUserMiddle: this.widget.middle != null, + largeExpanded: false, + child: navBar + ) + ); + } + ) + ); + } + } + + public class CupertinoSliverNavigationBar : StatefulWidget { + public CupertinoSliverNavigationBar( + Key key = null, + Widget largeTitle = null, + Widget leading = null, + bool automaticallyImplyLeading = true, + bool automaticallyImplyTitle = true, + string previousPageTitle = null, + Widget middle = null, + Widget trailing = null, + Border border = null, + Color backgroundColor = null, + EdgeInsets padding = null, + Color actionsForegroundColor = null, + bool transitionBetweenRoutes = true, + object heroTag = null + ) : base(key: key) { + D.assert( + automaticallyImplyTitle == true || largeTitle != null, + () => "No largeTitle has been provided but automaticallyImplyTitle is also " + + "false. Either provide a largeTitle or set automaticallyImplyTitle to " + + "true." + ); + this.largeTitle = largeTitle; + this.leading = leading; + this.automaticallyImplyLeading = automaticallyImplyLeading; + this.automaticallyImplyTitle = automaticallyImplyTitle; + this.previousPageTitle = previousPageTitle; + this.middle = middle; + this.trailing = trailing; + this.border = border ?? NavBarUtils._kDefaultNavBarBorder; + this.backgroundColor = backgroundColor; + this.padding = padding; + this.actionsForegroundColor = actionsForegroundColor; + this.transitionBetweenRoutes = transitionBetweenRoutes; + this.heroTag = heroTag ?? NavBarUtils._defaultHeroTag; + } + + public readonly Widget largeTitle; + + public readonly Widget leading; + + public readonly bool automaticallyImplyLeading; + + public readonly bool automaticallyImplyTitle; + + public readonly string previousPageTitle; + + public readonly Widget middle; + + public readonly Widget trailing; + + public readonly Color backgroundColor; + + public readonly EdgeInsets padding; + + public readonly Border border; + + public readonly Color actionsForegroundColor; + + public readonly bool transitionBetweenRoutes; + + public readonly object heroTag; + + public bool opaque { + get { return this.backgroundColor.alpha == 0xFF; } + } + + public override State createState() { + return new _CupertinoSliverNavigationBarState(); + } + } + + class _CupertinoSliverNavigationBarState : State { + _NavigationBarStaticComponentsKeys keys; + + public override void initState() { + base.initState(); + this.keys = new _NavigationBarStaticComponentsKeys(); + } + + public override Widget build(BuildContext context) { + Color actionsForegroundColor = + this.widget.actionsForegroundColor ?? + CupertinoTheme.of(context).primaryColor; // ignore: deprecated_member_use_from_same_package + + _NavigationBarStaticComponents components = new _NavigationBarStaticComponents( + keys: this.keys, + route: ModalRoute.of(context), + userLeading: this.widget.leading, + automaticallyImplyLeading: this.widget.automaticallyImplyLeading, + automaticallyImplyTitle: this.widget.automaticallyImplyTitle, + previousPageTitle: this.widget.previousPageTitle, + userMiddle: this.widget.middle, + userTrailing: this.widget.trailing, + userLargeTitle: this.widget.largeTitle, + padding: this.widget.padding, + large: true + ); + + return NavBarUtils._wrapActiveColor( + this.widget.actionsForegroundColor, // ignore: deprecated_member_use_from_same_package + context, + new SliverPersistentHeader( + pinned: true, // iOS navigation bars are always pinned. + del: new _LargeTitleNavigationBarSliverDelegate( + keys: this.keys, + components: components, + userMiddle: this.widget.middle, + backgroundColor: this.widget.backgroundColor ?? CupertinoTheme.of(context).barBackgroundColor, + border: this.widget.border, + padding: this.widget.padding, + actionsForegroundColor: actionsForegroundColor, + transitionBetweenRoutes: this.widget.transitionBetweenRoutes, + heroTag: this.widget.heroTag, + persistentHeight: NavBarUtils._kNavBarPersistentHeight + MediaQuery.of(context).padding.top, + alwaysShowMiddle: this.widget.middle != null + ) + ) + ); + } + } + + class _LargeTitleNavigationBarSliverDelegate + : SliverPersistentHeaderDelegate { + public _LargeTitleNavigationBarSliverDelegate( + _NavigationBarStaticComponentsKeys keys, + _NavigationBarStaticComponents components, + Widget userMiddle, + Color backgroundColor, + Border border, + EdgeInsets padding, + Color actionsForegroundColor, + bool transitionBetweenRoutes, + object heroTag, + float persistentHeight, + bool alwaysShowMiddle + ) { + this.keys = keys; + this.components = components; + this.userMiddle = userMiddle; + this.backgroundColor = backgroundColor; + this.border = border; + this.padding = padding; + this.actionsForegroundColor = actionsForegroundColor; + this.transitionBetweenRoutes = transitionBetweenRoutes; + this.heroTag = heroTag; + this.persistentHeight = persistentHeight; + this.alwaysShowMiddle = alwaysShowMiddle; + } + + public readonly _NavigationBarStaticComponentsKeys keys; + public readonly _NavigationBarStaticComponents components; + public readonly Widget userMiddle; + public readonly Color backgroundColor; + public readonly Border border; + public readonly EdgeInsets padding; + public readonly Color actionsForegroundColor; + public readonly bool transitionBetweenRoutes; + public readonly object heroTag; + public readonly float persistentHeight; + public readonly bool alwaysShowMiddle; + + public override float? minExtent { + get { return this.persistentHeight; } + } + + public override float? maxExtent { + get { return this.persistentHeight + NavBarUtils._kNavBarLargeTitleHeightExtension; } + } + + public override Widget build(BuildContext context, float shrinkOffset, bool overlapsContent) { + bool showLargeTitle = + shrinkOffset < this.maxExtent - this.minExtent - NavBarUtils._kNavBarShowLargeTitleThreshold; + + _PersistentNavigationBar persistentNavigationBar = + new _PersistentNavigationBar( + components: this.components, + padding: this.padding, + middleVisible: this.alwaysShowMiddle ? null : (bool?) !showLargeTitle + ); + + Widget navBar = NavBarUtils._wrapWithBackground( + border: this.border, + backgroundColor: this.backgroundColor, + child: new DefaultTextStyle( + style: CupertinoTheme.of(context).textTheme.textStyle, + child: new Stack( + fit: StackFit.expand, + children: new List { + new Positioned( + top: this.persistentHeight, + left: 0.0f, + right: 0.0f, + bottom: 0.0f, + child: new ClipRect( + child: new OverflowBox( + minHeight: 0.0f, + maxHeight: float.PositiveInfinity, + alignment: Alignment.bottomLeft, + child: new Padding( + padding: EdgeInsets.only( + left: NavBarUtils._kNavBarEdgePadding, + bottom: 8.0f + ), + child: new SafeArea( + top: false, + bottom: false, + child: new AnimatedOpacity( + opacity: showLargeTitle ? 1.0f : 0.0f, + duration: NavBarUtils._kNavBarTitleFadeDuration, + child: new DefaultTextStyle( + style: CupertinoTheme.of(context).textTheme + .navLargeTitleTextStyle, + maxLines: 1, + overflow: TextOverflow.ellipsis, + child: this.components.largeTitle + ) + ) + ) + ) + ) + ) + ), + new Positioned( + left: 0.0f, + right: 0.0f, + top: 0.0f, + child: persistentNavigationBar + ) + } + ) + ) + ); + + if (!this.transitionBetweenRoutes || !NavBarUtils._isTransitionable(context)) { + return navBar; + } + + return new Hero( + tag: this.heroTag as _HeroTag == NavBarUtils._defaultHeroTag + ? new _HeroTag(Navigator.of(context)) + : this.heroTag, + createRectTween: NavBarUtils._linearTranslateWithLargestRectSizeTween, + flightShuttleBuilder: NavBarUtils._navBarHeroFlightShuttleBuilder, + placeholderBuilder: NavBarUtils._navBarHeroLaunchPadBuilder, + transitionOnUserGestures: true, + child: new _TransitionableNavigationBar( + componentsKeys: this.keys, + backgroundColor: this.backgroundColor, + backButtonTextStyle: CupertinoTheme.of(context).textTheme.navActionTextStyle, + titleTextStyle: CupertinoTheme.of(context).textTheme.navTitleTextStyle, + largeTitleTextStyle: CupertinoTheme.of(context).textTheme.navLargeTitleTextStyle, + border: this.border, + hasUserMiddle: this.userMiddle != null, + largeExpanded: showLargeTitle, + child: navBar + ) + ); + } + + public override bool shouldRebuild(SliverPersistentHeaderDelegate _oldDelegate) { + _LargeTitleNavigationBarSliverDelegate oldDelegate = _oldDelegate as _LargeTitleNavigationBarSliverDelegate; + return this.components != oldDelegate.components + || this.userMiddle != oldDelegate.userMiddle + || this.backgroundColor != oldDelegate.backgroundColor + || this.border != oldDelegate.border + || this.padding != oldDelegate.padding + || this.actionsForegroundColor != oldDelegate.actionsForegroundColor + || this.transitionBetweenRoutes != oldDelegate.transitionBetweenRoutes + || this.persistentHeight != oldDelegate.persistentHeight + || this.alwaysShowMiddle != oldDelegate.alwaysShowMiddle + || this.heroTag != oldDelegate.heroTag; + } + } + + class _PersistentNavigationBar : StatelessWidget { + public _PersistentNavigationBar( + Key key = null, + _NavigationBarStaticComponents components = null, + EdgeInsets padding = null, + bool? middleVisible = null + ) : base(key: key) { + this.components = components; + this.padding = padding; + this.middleVisible = middleVisible ?? true; + } + + public readonly _NavigationBarStaticComponents components; + + public readonly EdgeInsets padding; + public readonly bool middleVisible; + + public override Widget build(BuildContext context) { + Widget middle = this.components.middle; + + if (middle != null) { + middle = new DefaultTextStyle( + style: CupertinoTheme.of(context).textTheme.navTitleTextStyle, + child: middle + ); + middle = new AnimatedOpacity( + opacity: this.middleVisible ? 1.0f : 0.0f, + duration: NavBarUtils._kNavBarTitleFadeDuration, + child: middle + ); + } + + Widget leading = this.components.leading; + Widget backChevron = this.components.backChevron; + Widget backLabel = this.components.backLabel; + + if (leading == null && backChevron != null && backLabel != null) { + leading = CupertinoNavigationBarBackButton._assemble( + backChevron, + backLabel + ); + } + + Widget paddedToolbar = new NavigationToolbar( + leading: leading, + middle: middle, + trailing: this.components.trailing, + centerMiddle: true, + middleSpacing: 6.0f + ); + + if (this.padding != null) { + paddedToolbar = new Padding( + padding: EdgeInsets.only( + top: this.padding.top, + bottom: this.padding.bottom + ), + child: paddedToolbar + ); + } + + return new SizedBox( + height: NavBarUtils._kNavBarPersistentHeight + MediaQuery.of(context).padding.top, + child: new SafeArea( + bottom: false, + child: paddedToolbar + ) + ); + } + } + + class _NavigationBarStaticComponentsKeys { + public _NavigationBarStaticComponentsKeys() { + this.navBarBoxKey = GlobalKey.key(debugLabel: "Navigation bar render box"); + this.leadingKey = GlobalKey.key(debugLabel: "Leading"); + this.backChevronKey = GlobalKey.key(debugLabel: "Back chevron"); + this.backLabelKey = GlobalKey.key(debugLabel: "Back label"); + this.middleKey = GlobalKey.key(debugLabel: "Middle"); + this.trailingKey = GlobalKey.key(debugLabel: "Trailing"); + this.largeTitleKey = GlobalKey.key(debugLabel: "Large title"); + } + + public readonly GlobalKey navBarBoxKey; + public readonly GlobalKey leadingKey; + public readonly GlobalKey backChevronKey; + public readonly GlobalKey backLabelKey; + public readonly GlobalKey middleKey; + public readonly GlobalKey trailingKey; + public readonly GlobalKey largeTitleKey; + } + + class _NavigationBarStaticComponents { + public _NavigationBarStaticComponents( + _NavigationBarStaticComponentsKeys keys, + ModalRoute route, + Widget userLeading, + bool automaticallyImplyLeading, + bool automaticallyImplyTitle, + string previousPageTitle, + Widget userMiddle, + Widget userTrailing, + Widget userLargeTitle, + EdgeInsets padding, + bool large + ) { + this.leading = createLeading( + leadingKey: keys.leadingKey, + userLeading: userLeading, + route: route, + automaticallyImplyLeading: automaticallyImplyLeading, + padding: padding + ); + this.backChevron = createBackChevron( + backChevronKey: keys.backChevronKey, + userLeading: userLeading, + route: route, + automaticallyImplyLeading: automaticallyImplyLeading + ); + this.backLabel = createBackLabel( + backLabelKey: keys.backLabelKey, + userLeading: userLeading, + route: route, + previousPageTitle: previousPageTitle, + automaticallyImplyLeading: automaticallyImplyLeading + ); + this.middle = createMiddle( + middleKey: keys.middleKey, + userMiddle: userMiddle, + userLargeTitle: userLargeTitle, + route: route, + automaticallyImplyTitle: automaticallyImplyTitle, + large: large + ); + this.trailing = createTrailing( + trailingKey: keys.trailingKey, + userTrailing: userTrailing, + padding: padding + ); + this.largeTitle = createLargeTitle( + largeTitleKey: keys.largeTitleKey, + userLargeTitle: userLargeTitle, + route: route, + automaticImplyTitle: automaticallyImplyTitle, + large: large + ); + } + + static Widget _derivedTitle( + bool automaticallyImplyTitle, + ModalRoute currentRoute + ) { + if (automaticallyImplyTitle && + currentRoute is CupertinoPageRoute route && + route.title != null) { + return new Text(route.title); + } + + return null; + } + + public readonly KeyedSubtree leading; + + static KeyedSubtree createLeading( + GlobalKey leadingKey, + Widget userLeading, + ModalRoute route, + bool automaticallyImplyLeading, + EdgeInsets padding + ) { + Widget leadingContent = null; + + if (userLeading != null) { + leadingContent = userLeading; + } + else if ( + automaticallyImplyLeading && + route is PageRoute pageRoute && + route.canPop && + pageRoute.fullscreenDialog + ) { + leadingContent = new CupertinoButton( + child: new Text("Close"), + padding: EdgeInsets.zero, + onPressed: () => { route.navigator.maybePop(); } + ); + } + + if (leadingContent == null) { + return null; + } + + return new KeyedSubtree( + key: leadingKey, + child: new Padding( + padding: EdgeInsets.only( + left: padding?.left ?? NavBarUtils._kNavBarEdgePadding + ), + child: IconTheme.merge( + data: new IconThemeData( + size: 32.0f + ), + child: leadingContent + ) + ) + ); + } + + public readonly KeyedSubtree backChevron; + + static KeyedSubtree createBackChevron( + GlobalKey backChevronKey, + Widget userLeading, + ModalRoute route, + bool automaticallyImplyLeading + ) { + if ( + userLeading != null || + !automaticallyImplyLeading || + route == null || + !route.canPop || + (route is PageRoute pageRoute && pageRoute.fullscreenDialog) + ) { + return null; + } + + return new KeyedSubtree(key: backChevronKey, child: new _BackChevron()); + } + + public readonly KeyedSubtree backLabel; + + static KeyedSubtree createBackLabel( + GlobalKey backLabelKey, + Widget userLeading, + ModalRoute route, + bool automaticallyImplyLeading, + string previousPageTitle + ) { + if ( + userLeading != null || + !automaticallyImplyLeading || + route == null || + !route.canPop || + (route is PageRoute pageRoute && pageRoute.fullscreenDialog) + ) { + return null; + } + + return new KeyedSubtree( + key: backLabelKey, + child: new _BackLabel( + specifiedPreviousTitle: previousPageTitle, + route: route + ) + ); + } + + public readonly KeyedSubtree middle; + + static KeyedSubtree createMiddle( + GlobalKey middleKey, + Widget userMiddle, + Widget userLargeTitle, + bool large, + bool automaticallyImplyTitle, + ModalRoute route + ) { + Widget middleContent = userMiddle; + + if (large) { + middleContent = middleContent ?? userLargeTitle; + } + + middleContent = middleContent ?? _derivedTitle( + automaticallyImplyTitle: automaticallyImplyTitle, + currentRoute: route + ); + + if (middleContent == null) { + return null; + } + + return new KeyedSubtree( + key: middleKey, + child: middleContent + ); + } + + public readonly KeyedSubtree trailing; + + static KeyedSubtree createTrailing( + GlobalKey trailingKey, + Widget userTrailing, + EdgeInsets padding + ) { + if (userTrailing == null) { + return null; + } + + return new KeyedSubtree( + key: trailingKey, + child: new Padding( + padding: EdgeInsets.only( + right: padding?.right ?? NavBarUtils._kNavBarEdgePadding + ), + child: IconTheme.merge( + data: new IconThemeData( + size: 32.0f + ), + child: userTrailing + ) + ) + ); + } + + public readonly KeyedSubtree largeTitle; + + static KeyedSubtree createLargeTitle( + GlobalKey largeTitleKey, + Widget userLargeTitle, + bool large, + bool automaticImplyTitle, + ModalRoute route + ) { + if (!large) { + return null; + } + + Widget largeTitleContent = userLargeTitle ?? _derivedTitle( + automaticallyImplyTitle: automaticImplyTitle, + currentRoute: route + ); + + D.assert( + largeTitleContent != null, + () => "largeTitle was not provided and there was no title from the route." + ); + + return new KeyedSubtree( + key: largeTitleKey, + child: largeTitleContent + ); + } + } + + public class CupertinoNavigationBarBackButton : StatelessWidget { + public CupertinoNavigationBarBackButton( + Color color, + string previousPageTitle + ) { + this._backChevron = null; + this._backLabel = null; + this.color = color; + this.previousPageTitle = previousPageTitle; + } + + internal CupertinoNavigationBarBackButton( + Color color, + string previousPageTitle, + Widget backChevron, + Widget backLabel + ) { + this._backChevron = backChevron; + this._backLabel = backLabel; + this.color = color; + this.previousPageTitle = previousPageTitle; + } + + public static CupertinoNavigationBarBackButton _assemble( + Widget _backChevron, + Widget _backLabel + ) { + return new CupertinoNavigationBarBackButton( + backChevron: _backChevron, + backLabel: _backLabel, + color: null, + previousPageTitle: null + ); + } + + public readonly Color color; + + public readonly string previousPageTitle; + + public readonly Widget _backChevron; + + public readonly Widget _backLabel; + + public override Widget build(BuildContext context) { + ModalRoute currentRoute = ModalRoute.of(context); + D.assert( + currentRoute?.canPop == true, + () => "CupertinoNavigationBarBackButton should only be used in routes that can be popped" + ); + + TextStyle actionTextStyle = CupertinoTheme.of(context).textTheme.navActionTextStyle; + if (this.color != null) { + actionTextStyle = actionTextStyle.copyWith(color: this.color); + } + + return new CupertinoButton( + child: new DefaultTextStyle( + style: actionTextStyle, + child: new ConstrainedBox( + constraints: new BoxConstraints(minWidth: NavBarUtils._kNavBarBackButtonTapWidth), + child: new Row( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.start, + children: new List { + new Padding(padding: EdgeInsets.only(left: 8.0f)), + this._backChevron ?? new _BackChevron(), + new Padding(padding: EdgeInsets.only(left: 6.0f)), + new Flexible( + child: this._backLabel ?? new _BackLabel( + specifiedPreviousTitle: this.previousPageTitle, + route: currentRoute + ) + ) + } + ) + ) + ), + padding: EdgeInsets.zero, + onPressed: () => { Navigator.maybePop(context); } + ); + } + } + + + class _BackChevron : StatelessWidget { + public _BackChevron(Key key = null) : base(key: key) { } + + public override Widget build(BuildContext context) { + TextStyle textStyle = DefaultTextStyle.of(context).style; + + Widget iconWidget = Text.rich( + new TextSpan( + text: char.ConvertFromUtf32(CupertinoIcons.back.codePoint), + style: new TextStyle( + inherit: false, + color: textStyle.color, + fontSize: 34.0f, + fontFamily: CupertinoIcons.back.fontFamily + ) + ) + ); + + return iconWidget; + } + } + + class _BackLabel : StatelessWidget { + public _BackLabel( + Key key = null, + string specifiedPreviousTitle = null, + ModalRoute route = null + ) : base(key: key) { + D.assert(route != null); + this.specifiedPreviousTitle = specifiedPreviousTitle; + this.route = route; + } + + public readonly string specifiedPreviousTitle; + public readonly ModalRoute route; + + Widget _buildPreviousTitleWidget(BuildContext context, string previousTitle, Widget child) { + if (previousTitle == null) { + return new SizedBox(height: 0.0f, width: 0.0f); + } + + Text textWidget = new Text( + previousTitle, + maxLines: 1, + overflow: TextOverflow.ellipsis + ); + + if (previousTitle.Length > 12) { + textWidget = new Text("Back"); + } + + return new Align( + alignment: Alignment.centerLeft, + widthFactor: 1.0f, + child: textWidget + ); + } + + public override Widget build(BuildContext context) { + if (this.specifiedPreviousTitle != null) { + return this._buildPreviousTitleWidget(context, this.specifiedPreviousTitle, null); + } + else if (this.route is CupertinoPageRoute cupertinoRoute) { + return new ValueListenableBuilder( + valueListenable: cupertinoRoute.previousTitle, + builder: this._buildPreviousTitleWidget + ); + } + else { + return new SizedBox(height: 0.0f, width: 0.0f); + } + } + } + + class _TransitionableNavigationBar : StatelessWidget { + public _TransitionableNavigationBar( + _NavigationBarStaticComponentsKeys componentsKeys = null, + Color backgroundColor = null, + TextStyle backButtonTextStyle = null, + TextStyle titleTextStyle = null, + TextStyle largeTitleTextStyle = null, + Border border = null, + bool? hasUserMiddle = null, + bool? largeExpanded = null, + Widget child = null + ) : base(key: componentsKeys.navBarBoxKey) { + D.assert(largeExpanded != null); + D.assert(!largeExpanded.Value || largeTitleTextStyle != null); + + this.componentsKeys = componentsKeys; + this.backgroundColor = backgroundColor; + this.backButtonTextStyle = backButtonTextStyle; + this.titleTextStyle = titleTextStyle; + this.largeTitleTextStyle = largeTitleTextStyle; + this.border = border; + this.hasUserMiddle = hasUserMiddle; + this.largeExpanded = largeExpanded; + this.child = child; + } + + public readonly _NavigationBarStaticComponentsKeys componentsKeys; + public readonly Color backgroundColor; + public readonly TextStyle backButtonTextStyle; + public readonly TextStyle titleTextStyle; + public readonly TextStyle largeTitleTextStyle; + public readonly Border border; + public readonly bool? hasUserMiddle; + public readonly bool? largeExpanded; + public readonly Widget child; + + public RenderBox renderBox { + get { + RenderBox box = (RenderBox) this.componentsKeys.navBarBoxKey.currentContext.findRenderObject(); + D.assert( + box.attached, + () => "_TransitionableNavigationBar.renderBox should be called when building " + + "hero flight shuttles when the from and the to nav bar boxes are already " + + "laid out and painted." + ); + return box; + } + } + + public override Widget build(BuildContext context) { + D.assert(() => { + bool? inHero = null; + context.visitAncestorElements((Element ancestor) => { + if (ancestor is ComponentElement) { + D.assert( + ancestor.widget.GetType() != typeof(_NavigationBarTransition), + () => "_TransitionableNavigationBar should never re-appear inside " + + "_NavigationBarTransition. Keyed _TransitionableNavigationBar should " + + "only serve as anchor points in routes rather than appearing inside " + + "Hero flights themselves." + ); + if (ancestor.widget.GetType() == typeof(Hero)) { + inHero = true; + } + } + + inHero = inHero ?? false; + return true; + }); + D.assert( + inHero == true, + () => "_TransitionableNavigationBar should only be added as the immediate " + + "child of Hero widgets." + ); + return true; + }); + return this.child; + } + } + + class _NavigationBarTransition : StatelessWidget { + public _NavigationBarTransition( + Animation animation, + _TransitionableNavigationBar topNavBar, + _TransitionableNavigationBar bottomNavBar + ) { + this.animation = animation; + this.topNavBar = topNavBar; + this.bottomNavBar = bottomNavBar; + this.heightTween = new FloatTween( + begin: this.bottomNavBar.renderBox.size.height, + end: this.topNavBar.renderBox.size.height + ); + this.backgroundTween = new ColorTween( + begin: this.bottomNavBar.backgroundColor, + end: this.topNavBar.backgroundColor + ); + this.borderTween = new BorderTween( + begin: this.bottomNavBar.border, + end: this.topNavBar.border + ); + } + + public readonly Animation animation; + public readonly _TransitionableNavigationBar topNavBar; + public readonly _TransitionableNavigationBar bottomNavBar; + + public readonly FloatTween heightTween; + public readonly ColorTween backgroundTween; + public readonly BorderTween borderTween; + + public override Widget build(BuildContext context) { + _NavigationBarComponentsTransition componentsTransition = new _NavigationBarComponentsTransition( + animation: this.animation, + bottomNavBar: this.bottomNavBar, + topNavBar: this.topNavBar, + directionality: Directionality.of(context) + ); + + List children = new List { + new AnimatedBuilder( + animation: this.animation, + builder: (BuildContext _context, Widget child) => { + return NavBarUtils._wrapWithBackground( + updateSystemUiOverlay: false, + backgroundColor: this.backgroundTween.evaluate(this.animation), + border: this.borderTween.evaluate(this.animation), + child: new SizedBox( + height: this.heightTween.evaluate(this.animation), + width: float.PositiveInfinity + ) + ); + } + ), + componentsTransition.bottomBackChevron, + componentsTransition.bottomBackLabel, + componentsTransition.bottomLeading, + componentsTransition.bottomMiddle, + componentsTransition.bottomLargeTitle, + componentsTransition.bottomTrailing, + componentsTransition.topLeading, + componentsTransition.topBackChevron, + componentsTransition.topBackLabel, + componentsTransition.topMiddle, + componentsTransition.topLargeTitle, + componentsTransition.topTrailing + }; + + children.RemoveAll((Widget child) => child == null); + + return new SizedBox( + height: Mathf.Max(this.heightTween.begin, this.heightTween.end) + MediaQuery.of(context).padding.top, + width: float.PositiveInfinity, + child: new Stack( + children: children + ) + ); + } + } + + class _NavigationBarComponentsTransition { + public _NavigationBarComponentsTransition( + Animation animation, + _TransitionableNavigationBar bottomNavBar, + _TransitionableNavigationBar topNavBar, + TextDirection directionality + ) { + this.animation = animation; + this.bottomComponents = bottomNavBar.componentsKeys; + this.topComponents = topNavBar.componentsKeys; + this.bottomNavBarBox = bottomNavBar.renderBox; + this.topNavBarBox = topNavBar.renderBox; + this.bottomBackButtonTextStyle = bottomNavBar.backButtonTextStyle; + this.topBackButtonTextStyle = topNavBar.backButtonTextStyle; + this.bottomTitleTextStyle = bottomNavBar.titleTextStyle; + this.topTitleTextStyle = topNavBar.titleTextStyle; + this.bottomLargeTitleTextStyle = bottomNavBar.largeTitleTextStyle; + this.topLargeTitleTextStyle = topNavBar.largeTitleTextStyle; + this.bottomHasUserMiddle = bottomNavBar.hasUserMiddle; + this.topHasUserMiddle = topNavBar.hasUserMiddle; + this.bottomLargeExpanded = bottomNavBar.largeExpanded; + this.topLargeExpanded = topNavBar.largeExpanded; + this.transitionBox = + bottomNavBar.renderBox.paintBounds.expandToInclude(topNavBar.renderBox.paintBounds); + this.forwardDirection = directionality == TextDirection.ltr ? 1.0f : -1.0f; + } + + public static Animatable fadeOut = new FloatTween( + begin: 1.0f, + end: 0.0f + ); + + public static Animatable fadeIn = new FloatTween( + begin: 0.0f, + end: 1.0f + ); + + public readonly Animation animation; + public readonly _NavigationBarStaticComponentsKeys bottomComponents; + public readonly _NavigationBarStaticComponentsKeys topComponents; + + public readonly RenderBox bottomNavBarBox; + public readonly RenderBox topNavBarBox; + + public readonly TextStyle bottomBackButtonTextStyle; + public readonly TextStyle topBackButtonTextStyle; + public readonly TextStyle bottomTitleTextStyle; + public readonly TextStyle topTitleTextStyle; + public readonly TextStyle bottomLargeTitleTextStyle; + public readonly TextStyle topLargeTitleTextStyle; + + public readonly bool? bottomHasUserMiddle; + public readonly bool? topHasUserMiddle; + public readonly bool? bottomLargeExpanded; + public readonly bool? topLargeExpanded; + + public readonly Rect transitionBox; + + public readonly float forwardDirection; + + public RelativeRect positionInTransitionBox( + GlobalKey key, + RenderBox from + ) { + RenderBox componentBox = (RenderBox) key.currentContext.findRenderObject(); + D.assert(componentBox.attached); + + return RelativeRect.fromRect( + componentBox.localToGlobal(Offset.zero, ancestor: from) & componentBox.size, this.transitionBox + ); + } + + public RelativeRectTween slideFromLeadingEdge( + GlobalKey fromKey, + RenderBox fromNavBarBox, + GlobalKey toKey, + RenderBox toNavBarBox + ) { + RelativeRect fromRect = this.positionInTransitionBox(fromKey, from: fromNavBarBox); + + RenderBox fromBox = (RenderBox) fromKey.currentContext.findRenderObject(); + RenderBox toBox = (RenderBox) toKey.currentContext.findRenderObject(); + + Rect toRect = + toBox.localToGlobal( + Offset.zero, + ancestor: toNavBarBox + ).translate( + 0.0f, + -fromBox.size.height / 2 + toBox.size.height / 2 + ) & fromBox.size; // Keep the from render object"s size. + + if (this.forwardDirection < 0) { + toRect = toRect.translate(-fromBox.size.width + toBox.size.width, 0.0f); + } + + return new RelativeRectTween( + begin: fromRect, + end: RelativeRect.fromRect(toRect, this.transitionBox) + ); + } + + public Animation fadeInFrom(float t, Curve curve = null) { + return this.animation.drive(fadeIn.chain( + new CurveTween(curve: new Interval(t, 1.0f, curve: curve ?? Curves.easeIn)) + )); + } + + public Animation fadeOutBy(float t, Curve curve = null) { + return this.animation.drive(fadeOut.chain( + new CurveTween(curve: new Interval(0.0f, t, curve: curve ?? Curves.easeOut)) + )); + } + + public Widget bottomLeading { + get { + KeyedSubtree bottomLeading = (KeyedSubtree) this.bottomComponents.leadingKey.currentWidget; + + if (bottomLeading == null) { + return null; + } + + return Positioned.fromRelativeRect( + rect: this.positionInTransitionBox(this.bottomComponents.leadingKey, from: this.bottomNavBarBox), + child: new FadeTransition( + opacity: this.fadeOutBy(0.4f), + child: bottomLeading.child + ) + ); + } + } + + public Widget bottomBackChevron { + get { + KeyedSubtree bottomBackChevron = (KeyedSubtree) this.bottomComponents.backChevronKey.currentWidget; + + if (bottomBackChevron == null) { + return null; + } + + return Positioned.fromRelativeRect( + rect: this.positionInTransitionBox(this.bottomComponents.backChevronKey, + from: this.bottomNavBarBox), + child: new FadeTransition( + opacity: this.fadeOutBy(0.6f), + child: new DefaultTextStyle( + style: this.bottomBackButtonTextStyle, + child: bottomBackChevron.child + ) + ) + ); + } + } + + public Widget bottomBackLabel { + get { + KeyedSubtree bottomBackLabel = (KeyedSubtree) this.bottomComponents.backLabelKey.currentWidget; + + if (bottomBackLabel == null) { + return null; + } + + RelativeRect from = + this.positionInTransitionBox(this.bottomComponents.backLabelKey, from: this.bottomNavBarBox); + + RelativeRectTween positionTween = new RelativeRectTween( + begin: from, + end: from.shift( + new Offset(this.forwardDirection * (-this.bottomNavBarBox.size.width / 2.0f), + 0.0f + ) + ) + ); + + return new PositionedTransition( + rect: this.animation.drive(positionTween), + child: new FadeTransition( + opacity: this.fadeOutBy(0.2f), + child: new DefaultTextStyle( + style: this.bottomBackButtonTextStyle, + child: bottomBackLabel.child + ) + ) + ); + } + } + + public Widget bottomMiddle { + get { + KeyedSubtree bottomMiddle = (KeyedSubtree) this.bottomComponents.middleKey.currentWidget; + KeyedSubtree topBackLabel = (KeyedSubtree) this.topComponents.backLabelKey.currentWidget; + KeyedSubtree topLeading = (KeyedSubtree) this.topComponents.leadingKey.currentWidget; + + if (this.bottomHasUserMiddle != true && this.bottomLargeExpanded == true) { + return null; + } + + if (bottomMiddle != null && topBackLabel != null) { + return new PositionedTransition( + rect: this.animation.drive(this.slideFromLeadingEdge( + fromKey: this.bottomComponents.middleKey, + fromNavBarBox: this.bottomNavBarBox, + toKey: this.topComponents.backLabelKey, + toNavBarBox: this.topNavBarBox + )), + child: new FadeTransition( + opacity: this.fadeOutBy(this.bottomHasUserMiddle == true ? 0.4f : 0.7f), + child: new Align( + alignment: Alignment.centerLeft, + child: new DefaultTextStyleTransition( + style: this.animation.drive(new TextStyleTween( + begin: this.bottomTitleTextStyle, + end: this.topBackButtonTextStyle + )), + child: bottomMiddle.child + ) + ) + ) + ); + } + + if (bottomMiddle != null && topLeading != null) { + return Positioned.fromRelativeRect( + rect: this.positionInTransitionBox(this.bottomComponents.middleKey, from: this.bottomNavBarBox), + child: new FadeTransition( + opacity: this.fadeOutBy(this.bottomHasUserMiddle == true ? 0.4f : 0.7f), + child: new DefaultTextStyle( + style: this.bottomTitleTextStyle, + child: bottomMiddle.child + ) + ) + ); + } + + return null; + } + } + + public Widget bottomLargeTitle { + get { + KeyedSubtree bottomLargeTitle = (KeyedSubtree) this.bottomComponents.largeTitleKey.currentWidget; + KeyedSubtree topBackLabel = (KeyedSubtree) this.topComponents.backLabelKey.currentWidget; + KeyedSubtree topLeading = (KeyedSubtree) this.topComponents.leadingKey.currentWidget; + + if (bottomLargeTitle == null || this.bottomLargeExpanded != true) { + return null; + } + + if (bottomLargeTitle != null && topBackLabel != null) { + return new PositionedTransition( + rect: this.animation.drive(this.slideFromLeadingEdge( + fromKey: this.bottomComponents.largeTitleKey, + fromNavBarBox: this.bottomNavBarBox, + toKey: this.topComponents.backLabelKey, + toNavBarBox: this.topNavBarBox + )), + child: new FadeTransition( + opacity: this.fadeOutBy(0.6f), + child: new Align( + alignment: Alignment.centerLeft, + child: new DefaultTextStyleTransition( + style: this.animation.drive(new TextStyleTween( + begin: this.bottomLargeTitleTextStyle, + end: this.topBackButtonTextStyle + )), + maxLines: 1, + overflow: TextOverflow.ellipsis, + child: bottomLargeTitle.child + ) + ) + ) + ); + } + + if (bottomLargeTitle != null && topLeading != null) { + RelativeRect from = this.positionInTransitionBox(this.bottomComponents.largeTitleKey, + from: this.bottomNavBarBox); + + RelativeRectTween positionTween = new RelativeRectTween( + begin: from, + end: from.shift( + new Offset(this.forwardDirection * this.bottomNavBarBox.size.width / 4.0f, + 0.0f + ) + ) + ); + + return new PositionedTransition( + rect: this.animation.drive(positionTween), + child: new FadeTransition( + opacity: this.fadeOutBy(0.4f), + child: new DefaultTextStyle( + style: this.bottomLargeTitleTextStyle, + child: bottomLargeTitle.child + ) + ) + ); + } + + return null; + } + } + + public Widget bottomTrailing { + get { + KeyedSubtree bottomTrailing = (KeyedSubtree) this.bottomComponents.trailingKey.currentWidget; + + if (bottomTrailing == null) { + return null; + } + + return Positioned.fromRelativeRect( + rect: this.positionInTransitionBox(this.bottomComponents.trailingKey, from: this.bottomNavBarBox), + child: new FadeTransition( + opacity: this.fadeOutBy(0.6f), + child: bottomTrailing.child + ) + ); + } + } + + public Widget topLeading { + get { + KeyedSubtree topLeading = (KeyedSubtree) this.topComponents.leadingKey.currentWidget; + + if (topLeading == null) { + return null; + } + + return Positioned.fromRelativeRect( + rect: this.positionInTransitionBox(this.topComponents.leadingKey, from: this.topNavBarBox), + child: new FadeTransition( + opacity: this.fadeInFrom(0.6f), + child: topLeading.child + ) + ); + } + } + + public Widget topBackChevron { + get { + KeyedSubtree topBackChevron = (KeyedSubtree) this.topComponents.backChevronKey.currentWidget; + KeyedSubtree bottomBackChevron = (KeyedSubtree) this.bottomComponents.backChevronKey.currentWidget; + + if (topBackChevron == null) { + return null; + } + + RelativeRect to = + this.positionInTransitionBox(this.topComponents.backChevronKey, from: this.topNavBarBox); + RelativeRect from = to; + + if (bottomBackChevron == null) { + RenderBox topBackChevronBox = + (RenderBox) this.topComponents.backChevronKey.currentContext.findRenderObject(); + from = to.shift( + new Offset(this.forwardDirection * topBackChevronBox.size.width * 2.0f, + 0.0f + ) + ); + } + + RelativeRectTween positionTween = new RelativeRectTween( + begin: from, + end: to + ); + + return new PositionedTransition( + rect: this.animation.drive(positionTween), + child: new FadeTransition( + opacity: this.fadeInFrom(bottomBackChevron == null ? 0.7f : 0.4f), + child: new DefaultTextStyle( + style: this.topBackButtonTextStyle, + child: topBackChevron.child + ) + ) + ); + } + } + + public Widget topBackLabel { + get { + KeyedSubtree bottomMiddle = (KeyedSubtree) this.bottomComponents.middleKey.currentWidget; + KeyedSubtree bottomLargeTitle = (KeyedSubtree) this.bottomComponents.largeTitleKey.currentWidget; + KeyedSubtree topBackLabel = (KeyedSubtree) this.topComponents.backLabelKey.currentWidget; + + if (topBackLabel == null) { + return null; + } + + RenderAnimatedOpacity topBackLabelOpacity = + (RenderAnimatedOpacity) this.topComponents.backLabelKey.currentContext?.ancestorRenderObjectOfType( + new TypeMatcher() + ); + + Animation midClickOpacity = null; + if (topBackLabelOpacity != null && topBackLabelOpacity.opacity.value < 1.0f) { + midClickOpacity = this.animation.drive(new FloatTween( + begin: 0.0f, + end: topBackLabelOpacity.opacity.value + )); + } + + if (bottomLargeTitle != null && + topBackLabel != null && this.bottomLargeExpanded.Value) { + return new PositionedTransition( + rect: this.animation.drive(this.slideFromLeadingEdge( + fromKey: this.bottomComponents.largeTitleKey, + fromNavBarBox: this.bottomNavBarBox, + toKey: this.topComponents.backLabelKey, + toNavBarBox: this.topNavBarBox + )), + child: new FadeTransition( + opacity: midClickOpacity ?? this.fadeInFrom(0.4f), + child: new DefaultTextStyleTransition( + style: this.animation.drive(new TextStyleTween( + begin: this.bottomLargeTitleTextStyle, + end: this.topBackButtonTextStyle + )), + maxLines: 1, + overflow: TextOverflow.ellipsis, + child: topBackLabel.child + ) + ) + ); + } + + if (bottomMiddle != null && topBackLabel != null) { + return new PositionedTransition( + rect: this.animation.drive(this.slideFromLeadingEdge( + fromKey: this.bottomComponents.middleKey, + fromNavBarBox: this.bottomNavBarBox, + toKey: this.topComponents.backLabelKey, + toNavBarBox: this.topNavBarBox + )), + child: new FadeTransition( + opacity: midClickOpacity ?? this.fadeInFrom(0.3f), + child: new DefaultTextStyleTransition( + style: this.animation.drive(new TextStyleTween( + begin: this.bottomTitleTextStyle, + end: this.topBackButtonTextStyle + )), + child: topBackLabel.child + ) + ) + ); + } + + return null; + } + } + + public Widget topMiddle { + get { + KeyedSubtree topMiddle = (KeyedSubtree) this.topComponents.middleKey.currentWidget; + + if (topMiddle == null) { + return null; + } + + if (this.topHasUserMiddle != true && this.topLargeExpanded == true) { + return null; + } + + RelativeRect to = this.positionInTransitionBox(this.topComponents.middleKey, from: this.topNavBarBox); + + RelativeRectTween positionTween = new RelativeRectTween( + begin: to.shift( + new Offset(this.forwardDirection * this.topNavBarBox.size.width / 2.0f, + 0.0f + ) + ), + end: to + ); + + return new PositionedTransition( + rect: this.animation.drive(positionTween), + child: new FadeTransition( + opacity: this.fadeInFrom(0.25f), + child: new DefaultTextStyle( + style: this.topTitleTextStyle, + child: topMiddle.child + ) + ) + ); + } + } + + public Widget topTrailing { + get { + KeyedSubtree topTrailing = (KeyedSubtree) this.topComponents.trailingKey.currentWidget; + + if (topTrailing == null) { + return null; + } + + return Positioned.fromRelativeRect( + rect: this.positionInTransitionBox(this.topComponents.trailingKey, from: this.topNavBarBox), + child: new FadeTransition( + opacity: this.fadeInFrom(0.4f), + child: topTrailing.child + ) + ); + } + } + + public Widget topLargeTitle { + get { + KeyedSubtree topLargeTitle = (KeyedSubtree) this.topComponents.largeTitleKey.currentWidget; + + if (topLargeTitle == null || this.topLargeExpanded != true) { + return null; + } + + RelativeRect to = + this.positionInTransitionBox(this.topComponents.largeTitleKey, from: this.topNavBarBox); + + RelativeRectTween positionTween = new RelativeRectTween( + begin: to.shift( + new Offset(this.forwardDirection * this.topNavBarBox.size.width, + 0.0f + ) + ), + end: to + ); + + return new PositionedTransition( + rect: this.animation.drive(positionTween), + child: new FadeTransition( + opacity: this.fadeInFrom(0.3f), + child: new DefaultTextStyle( + style: this.topLargeTitleTextStyle, + maxLines: 1, + overflow: TextOverflow.ellipsis, + child: topLargeTitle.child + ) + ) + ); + } + } + } +} \ No newline at end of file diff --git a/Runtime/cupertino/nav_bar.cs.meta b/Runtime/cupertino/nav_bar.cs.meta new file mode 100644 index 00000000..2ce6dfa4 --- /dev/null +++ b/Runtime/cupertino/nav_bar.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3b784deecd91aef4085ba0796eea3324 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/cupertino/page_scaffold.cs b/Runtime/cupertino/page_scaffold.cs new file mode 100644 index 00000000..9010251f --- /dev/null +++ b/Runtime/cupertino/page_scaffold.cs @@ -0,0 +1,144 @@ +using System; +using System.Collections.Generic; +using Unity.UIWidgets.animation; +using Unity.UIWidgets.foundation; +using Unity.UIWidgets.painting; +using Unity.UIWidgets.ui; +using Unity.UIWidgets.widgets; + +namespace Unity.UIWidgets.cupertino { + public class CupertinoPageScaffold : StatefulWidget { + /// Creates a layout for pages with a navigation bar at the top. + public CupertinoPageScaffold( + Widget child, + Key key = null, + ObstructingPreferredSizeWidget navigationBar = null, + Color backgroundColor = null, + bool resizeToAvoidBottomInset = true + ) : base(key: key) { + D.assert(child != null); + + this.child = child; + this.navigationBar = navigationBar; + this.backgroundColor = backgroundColor; + this.resizeToAvoidBottomInset = resizeToAvoidBottomInset; + } + + public readonly ObstructingPreferredSizeWidget navigationBar; + public readonly Widget child; + public readonly Color backgroundColor; + public readonly bool resizeToAvoidBottomInset; + + + public override State createState() { + return new _CupertinoPageScaffoldState(); + } + } + + class _CupertinoPageScaffoldState : State { + public readonly ScrollController _primaryScrollController = new ScrollController(); + + void _handleStatusBarTap() { + // Only act on the scroll controller if it has any attached scroll positions. + if (this._primaryScrollController.hasClients) { + this._primaryScrollController.animateTo( + 0.0f, + duration: new TimeSpan(0, 0, 0, 0, 500), + curve: Curves.linearToEaseOut + ); + } + } + + public override Widget build(BuildContext context) { + List stacked = new List(); + + Widget paddedContent = this.widget.child; + + MediaQueryData existingMediaQuery = MediaQuery.of(context); + if (this.widget.navigationBar != null) { + float topPadding = this.widget.navigationBar.preferredSize.height + existingMediaQuery.padding.top; + + float bottomPadding = this.widget.resizeToAvoidBottomInset + ? existingMediaQuery.viewInsets.bottom + : 0.0f; + + EdgeInsets newViewInsets = this.widget.resizeToAvoidBottomInset + ? existingMediaQuery.viewInsets.copyWith(bottom: 0.0f) + : existingMediaQuery.viewInsets; + + bool? fullObstruction = + this.widget.navigationBar.fullObstruction == false + ? CupertinoTheme.of(context).barBackgroundColor.alpha == 0xFF + : this.widget.navigationBar.fullObstruction; + + if (fullObstruction == true) { + paddedContent = new MediaQuery( + data: existingMediaQuery + .removePadding(removeTop: true) + .copyWith( + viewInsets: newViewInsets + ), + child: new Padding( + padding: EdgeInsets.only(top: topPadding, bottom: bottomPadding), + child: paddedContent + ) + ); + } + else { + paddedContent = new MediaQuery( + data: existingMediaQuery.copyWith( + padding: existingMediaQuery.padding.copyWith( + top: topPadding + ), + viewInsets: newViewInsets + ), + child: new Padding( + padding: EdgeInsets.only(bottom: bottomPadding), + child: paddedContent + ) + ); + } + } + + stacked.Add(new PrimaryScrollController( + controller: this._primaryScrollController, + child: paddedContent + )); + + if (this.widget.navigationBar != null) { + stacked.Add(new Positioned( + top: 0.0f, + left: 0.0f, + right: 0.0f, + child: this.widget.navigationBar + )); + } + + stacked.Add(new Positioned( + top: 0.0f, + left: 0.0f, + right: 0.0f, + height: existingMediaQuery.padding.top, + child: new GestureDetector( + onTap: this._handleStatusBarTap + ) + ) + ); + + return new DecoratedBox( + decoration: new BoxDecoration( + color: this.widget.backgroundColor ?? CupertinoTheme.of(context).scaffoldBackgroundColor + ), + child: new Stack( + children: stacked + ) + ); + } + } + + public abstract class ObstructingPreferredSizeWidget : PreferredSizeWidget { + + protected ObstructingPreferredSizeWidget(Key key = null) : base(key: key) {} + public virtual bool? fullObstruction { get; } + } +} \ No newline at end of file diff --git a/Runtime/cupertino/page_scaffold.cs.meta b/Runtime/cupertino/page_scaffold.cs.meta new file mode 100644 index 00000000..79bf948e --- /dev/null +++ b/Runtime/cupertino/page_scaffold.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c8f7baea91a434b17b549b70613e6976 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/cupertino/picker.cs b/Runtime/cupertino/picker.cs new file mode 100644 index 00000000..72a2b91b --- /dev/null +++ b/Runtime/cupertino/picker.cs @@ -0,0 +1,262 @@ +using System.Collections.Generic; +using Unity.UIWidgets.foundation; +using Unity.UIWidgets.painting; +using Unity.UIWidgets.rendering; +using Unity.UIWidgets.ui; +using Unity.UIWidgets.widgets; + +namespace Unity.UIWidgets.cupertino { + static class CupertinoPickerUtils { + public static Color _kHighlighterBorder = new Color(0xFF7F7F7F); + public static Color _kDefaultBackground = new Color(0xFFD2D4DB); + public const float _kDefaultDiameterRatio = 1.35f; + public const float _kDefaultPerspective = 0.004f; + public const float _kForegroundScreenOpacityFraction = 0.7f; + } + + public class CupertinoPicker : StatefulWidget { + public CupertinoPicker( + float itemExtent, + ValueChanged onSelectedItemChanged, + List children = null, + Key key = null, + float diameterRatio = CupertinoPickerUtils._kDefaultDiameterRatio, + Color backgroundColor = null, + float offAxisFraction = 0.0f, + bool useMagnifier = false, + float magnification = 1.0f, + FixedExtentScrollController scrollController = null, + bool looping = false, + ListWheelChildDelegate childDelegate = null + ) : base(key: key) { + D.assert(children != null || childDelegate != null); + D.assert(diameterRatio > 0.0, () => RenderListWheelViewport.diameterRatioZeroMessage); + D.assert(magnification > 0); + D.assert(itemExtent > 0); + + this.childDelegate = childDelegate ?? (looping + ? (ListWheelChildDelegate) new ListWheelChildLoopingListDelegate( + children: children) + : (ListWheelChildDelegate) new ListWheelChildListDelegate(children: children)); + + this.itemExtent = itemExtent; + this.onSelectedItemChanged = onSelectedItemChanged; + this.diameterRatio = diameterRatio; + this.backgroundColor = backgroundColor ?? CupertinoPickerUtils._kDefaultBackground; + this.offAxisFraction = offAxisFraction; + this.useMagnifier = useMagnifier; + this.magnification = magnification; + this.scrollController = scrollController; + } + + public static CupertinoPicker builder( + float itemExtent, + ValueChanged onSelectedItemChanged, + IndexedWidgetBuilder itemBuilder, + Key key = null, + float diameterRatio = CupertinoPickerUtils._kDefaultDiameterRatio, + Color backgroundColor = null, + float offAxisFraction = 0.0f, + bool useMagnifier = false, + float magnification = 1.0f, + FixedExtentScrollController scrollController = null, + int? childCount = null + ) { + D.assert(itemBuilder != null); + D.assert(diameterRatio > 0.0f, () => RenderListWheelViewport.diameterRatioZeroMessage); + D.assert(magnification > 0); + D.assert(itemExtent > 0); + + return new CupertinoPicker( + itemExtent: itemExtent, + onSelectedItemChanged: onSelectedItemChanged, + key: key, + diameterRatio: diameterRatio, + backgroundColor: backgroundColor, + offAxisFraction: offAxisFraction, + useMagnifier: useMagnifier, + magnification: magnification, + scrollController: scrollController, + childDelegate: new ListWheelChildBuilderDelegate(builder: itemBuilder, childCount: childCount) + ); + } + + public readonly float diameterRatio; + public readonly Color backgroundColor; + public readonly float offAxisFraction; + public readonly bool useMagnifier; + public readonly float magnification; + public readonly FixedExtentScrollController scrollController; + public readonly float itemExtent; + public readonly ValueChanged onSelectedItemChanged; + public readonly ListWheelChildDelegate childDelegate; + + public override State createState() { + return new _CupertinoPickerState(); + } + } + + class _CupertinoPickerState : State { + FixedExtentScrollController _controller; + + public override void initState() { + base.initState(); + if (this.widget.scrollController == null) { + this._controller = new FixedExtentScrollController(); + } + } + + public override void didUpdateWidget(StatefulWidget oldWidget) { + if (this.widget.scrollController != null && ((CupertinoPicker) oldWidget).scrollController == null) { + this._controller = null; + } + else if (this.widget.scrollController == null && ((CupertinoPicker) oldWidget).scrollController != null) { + D.assert(this._controller == null); + this._controller = new FixedExtentScrollController(); + } + + base.didUpdateWidget(oldWidget); + } + + public override void dispose() { + this._controller?.dispose(); + base.dispose(); + } + + void _handleSelectedItemChanged(int index) { + if (this.widget.onSelectedItemChanged != null) { + this.widget.onSelectedItemChanged(index); + } + } + + Widget _buildGradientScreen() { + if (this.widget.backgroundColor != null && this.widget.backgroundColor.alpha < 255) { + return new Container(); + } + + Color widgetBackgroundColor = this.widget.backgroundColor ?? new Color(0xFFFFFFFF); + return Positioned.fill( + child: new IgnorePointer( + child: new Container( + decoration: new BoxDecoration( + gradient: new LinearGradient( + colors: new List { + widgetBackgroundColor, + widgetBackgroundColor.withAlpha(0xF2), + widgetBackgroundColor.withAlpha(0xDD), + widgetBackgroundColor.withAlpha(0), + widgetBackgroundColor.withAlpha(0), + widgetBackgroundColor.withAlpha(0xDD), + widgetBackgroundColor.withAlpha(0xF2), + widgetBackgroundColor, + }, + stops: new List { + 0.0f, 0.05f, 0.09f, 0.22f, 0.78f, 0.91f, 0.95f, 1.0f + }, + begin: Alignment.topCenter, + end: Alignment.bottomCenter + ) + ) + ) + ) + ); + } + + Widget _buildMagnifierScreen() { + Color foreground = this.widget.backgroundColor?.withAlpha( + (int) (this.widget.backgroundColor.alpha * CupertinoPickerUtils._kForegroundScreenOpacityFraction) + ); + + return new IgnorePointer( + child: new Column( + children: new List { + new Expanded( + child: new Container( + color: foreground + ) + ), + new Container( + decoration: new BoxDecoration( + border: new Border( + top: new BorderSide(width: 0.0f, color: CupertinoPickerUtils._kHighlighterBorder), + bottom: new BorderSide(width: 0.0f, color: CupertinoPickerUtils._kHighlighterBorder) + ) + ), + constraints: BoxConstraints.expand( + height: this.widget.itemExtent * this.widget.magnification + ) + ), + new Expanded( + child: new Container( + color: foreground + ) + ), + } + ) + ); + } + + Widget _buildUnderMagnifierScreen() { + Color foreground = this.widget.backgroundColor?.withAlpha( + (int) (this.widget.backgroundColor.alpha * CupertinoPickerUtils._kForegroundScreenOpacityFraction) + ); + + return new Column( + children: new List { + new Expanded(child: new Container()), + new Container( + color: foreground, + constraints: BoxConstraints.expand( + height: this.widget.itemExtent * this.widget.magnification + ) + ), + new Expanded(child: new Container()) + } + ); + } + + Widget _addBackgroundToChild(Widget child) { + return new DecoratedBox( + decoration: new BoxDecoration( + color: this.widget.backgroundColor + ), + child: child + ); + } + + public override Widget build(BuildContext context) { + Widget result = new Stack( + children: new List { + Positioned.fill( + child: ListWheelScrollView.useDelegate( + controller: this.widget.scrollController ?? this._controller, + physics: new FixedExtentScrollPhysics(), + diameterRatio: this.widget.diameterRatio, + perspective: CupertinoPickerUtils._kDefaultPerspective, + offAxisFraction: this.widget.offAxisFraction, + useMagnifier: this.widget.useMagnifier, + magnification: this.widget.magnification, + itemExtent: this.widget.itemExtent, + onSelectedItemChanged: this._handleSelectedItemChanged, + childDelegate: this.widget.childDelegate + ) + ), + this._buildGradientScreen(), + this._buildMagnifierScreen() + } + ); + if (this.widget.backgroundColor != null && this.widget.backgroundColor.alpha < 255) { + result = new Stack( + children: new List { + this._buildUnderMagnifierScreen(), this._addBackgroundToChild(result), + } + ); + } + else { + result = this._addBackgroundToChild(result); + } + + return result; + } + } +} \ No newline at end of file diff --git a/Runtime/cupertino/picker.cs.meta b/Runtime/cupertino/picker.cs.meta new file mode 100644 index 00000000..fad26ed9 --- /dev/null +++ b/Runtime/cupertino/picker.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e1f9860a10b464e9da0c6258c08fa91e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/cupertino/route.cs b/Runtime/cupertino/route.cs new file mode 100644 index 00000000..10e6e5ce --- /dev/null +++ b/Runtime/cupertino/route.cs @@ -0,0 +1,757 @@ +using System; +using System.Collections.Generic; +using RSG; +using Unity.UIWidgets.animation; +using Unity.UIWidgets.foundation; +using Unity.UIWidgets.gestures; +using Unity.UIWidgets.painting; +using Unity.UIWidgets.rendering; +using Unity.UIWidgets.ui; +using Unity.UIWidgets.widgets; +using UnityEngine; +using Canvas = Unity.UIWidgets.ui.Canvas; +using Color = Unity.UIWidgets.ui.Color; +using Rect = Unity.UIWidgets.ui.Rect; + +namespace Unity.UIWidgets.cupertino { + public class CupertinoRouteUtils { + public const float _kBackGestureWidth = 20.0f; + public const float _kMinFlingVelocity = 1.0f; + + public const int _kMaxDroppedSwipePageForwardAnimationTime = 800; // Milliseconds. + + public const int _kMaxPageBackAnimationTime = 300; // Milliseconds. + + public static readonly Color _kModalBarrierColor = new Color(0x6604040F); + + public static readonly TimeSpan _kModalPopupTransitionDuration = new TimeSpan(0, 0, 0, 0, 335); + + public static readonly Animatable _kRightMiddleTween = new OffsetTween( + begin: new Offset(1.0f, 0.0f), + end: Offset.zero + ); + + public static readonly Animatable _kMiddleLeftTween = new OffsetTween( + begin: Offset.zero, + end: new Offset(-1.0f / 3.0f, 0.0f) + ); + + public static readonly Animatable _kBottomUpTween = new OffsetTween( + begin: new Offset(0.0f, 1.0f), + end: Offset.zero + ); + + public static readonly DecorationTween _kGradientShadowTween = new DecorationTween( + begin: _CupertinoEdgeShadowDecoration.none, + end: new _CupertinoEdgeShadowDecoration( + edgeGradient: new LinearGradient( + begin: new Alignment(0.9f, 0.0f), + end: Alignment.centerRight, + colors: new List { + new Color(0x00000000), + new Color(0x04000000), + new Color(0x12000000), + new Color(0x38000000), + }, + stops: new List {0.0f, 0.3f, 0.6f, 1.0f} + ) + ) + ); + + + public static IPromise showCupertinoModalPopup( + BuildContext context, + WidgetBuilder builder + ) { + return Navigator.of(context, rootNavigator: true).push( + new _CupertinoModalPopupRoute( + builder: builder, + barrierLabel: "Dismiss" + ) + ); + } + + + public static readonly Animatable _dialogScaleTween = new FloatTween(begin: 1.3f, end: 1.0f) + .chain(new CurveTween(curve: Curves.linearToEaseOut)); + + public static Widget _buildCupertinoDialogTransitions(BuildContext context, Animation animation, + Animation + secondaryAnimation, Widget child) { + CurvedAnimation fadeAnimation = new CurvedAnimation( + parent: animation, + curve: Curves.easeInOut + ); + if (animation.status == AnimationStatus.reverse) { + return new FadeTransition( + opacity: fadeAnimation, + child: child + ); + } + + return new FadeTransition( + opacity: fadeAnimation, + child: new ScaleTransition( + child: child, + scale: animation.drive(_dialogScaleTween) + ) + ); + } + + public static IPromise showCupertinoDialog( + BuildContext context, + WidgetBuilder builder + ) { + D.assert(builder != null); + return DialogUtils.showGeneralDialog( + context: context, + barrierDismissible: false, + barrierColor: _kModalBarrierColor, + transitionDuration: new TimeSpan(0, 0, 0, 0, 250), + pageBuilder: + (BuildContext _context, Animation animation, Animation secondaryAnimation) => { + return builder(_context); + }, + transitionBuilder: _buildCupertinoDialogTransitions + ); + } + } + + class _CupertinoEdgeShadowDecoration : Decoration, IEquatable<_CupertinoEdgeShadowDecoration> { + public _CupertinoEdgeShadowDecoration( + LinearGradient edgeGradient = null + ) { + this.edgeGradient = edgeGradient; + } + + public static _CupertinoEdgeShadowDecoration none = + new _CupertinoEdgeShadowDecoration(); + + public readonly LinearGradient edgeGradient; + + static _CupertinoEdgeShadowDecoration lerpCupertino( + _CupertinoEdgeShadowDecoration a, + _CupertinoEdgeShadowDecoration b, + float t + ) { + if (a == null && b == null) { + return null; + } + + return new _CupertinoEdgeShadowDecoration( + edgeGradient: LinearGradient.lerp(a?.edgeGradient, b?.edgeGradient, t) + ); + } + + public override Decoration lerpFrom(Decoration a, float t) { + if (!(a is _CupertinoEdgeShadowDecoration)) { + return lerpCupertino(null, this, t); + } + + return lerpCupertino((_CupertinoEdgeShadowDecoration) a, this, t); + } + + public override Decoration lerpTo(Decoration b, float t) { + if (!(b is _CupertinoEdgeShadowDecoration)) { + return lerpCupertino(this, null, t); + } + + return lerpCupertino(this, (_CupertinoEdgeShadowDecoration) b, t); + } + + public override BoxPainter createBoxPainter(VoidCallback onChanged = null) { + return new _CupertinoEdgeShadowPainter(this, onChanged); + } + + public override int GetHashCode() { + return this.edgeGradient.GetHashCode(); + } + + public bool Equals(_CupertinoEdgeShadowDecoration other) { + if (ReferenceEquals(null, other)) { + return false; + } + + if (ReferenceEquals(this, other)) { + return true; + } + + return Equals(this.edgeGradient, other.edgeGradient); + } + + public override bool Equals(object obj) { + if (ReferenceEquals(null, obj)) { + return false; + } + + if (ReferenceEquals(this, obj)) { + return true; + } + + if (obj.GetType() != this.GetType()) { + return false; + } + + return this.Equals((_CupertinoEdgeShadowDecoration) obj); + } + + public static bool operator ==(_CupertinoEdgeShadowDecoration left, _CupertinoEdgeShadowDecoration right) { + return Equals(left, right); + } + + public static bool operator !=(_CupertinoEdgeShadowDecoration left, _CupertinoEdgeShadowDecoration right) { + return !Equals(left, right); + } + + public int hashCode { + get { return this.edgeGradient.GetHashCode(); } + } + + public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { + base.debugFillProperties(properties); + properties.add(new DiagnosticsProperty("edgeGradient", this.edgeGradient)); + } + } + + class _CupertinoEdgeShadowPainter : BoxPainter { + public _CupertinoEdgeShadowPainter( + _CupertinoEdgeShadowDecoration decoration = null, + VoidCallback onChange = null + ) : base(onChange) { + D.assert(decoration != null); + this._decoration = decoration; + } + + readonly _CupertinoEdgeShadowDecoration _decoration; + + public override void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) { + LinearGradient gradient = this._decoration.edgeGradient; + if (gradient == null) { + return; + } + + float deltaX = -configuration.size.width; + Rect rect = (offset & configuration.size).translate(deltaX, 0.0f); + Paint paint = new Paint(); + paint.shader = gradient.createShader(rect); + canvas.drawRect(rect, paint); + } + } + + public class CupertinoPageRoute : PageRoute { + public CupertinoPageRoute( + WidgetBuilder builder, + RouteSettings settings = null, + string title = "", + bool maintainState = true, + bool fullscreenDialog = false + ) : + base(settings: settings, fullscreenDialog: fullscreenDialog) { + D.assert(builder != null); + D.assert(this.opaque); + this.builder = builder; + this.title = title; + this.maintainState = maintainState; + } + + public readonly WidgetBuilder builder; + public readonly string title; + ValueNotifier _previousTitle; + + public ValueListenable previousTitle { + get { + D.assert( + this._previousTitle != null, + () => "Cannot read the previousTitle for a route that has not yet been installed" + ); + return this._previousTitle; + } + } + + protected internal override void didChangePrevious(Route previousRoute) { + string previousTitleString = previousRoute is CupertinoPageRoute + ? ((CupertinoPageRoute) previousRoute).title + : null; + if (this._previousTitle == null) { + this._previousTitle = new ValueNotifier(previousTitleString); + } + + else { + this._previousTitle.value = previousTitleString; + } + + base.didChangePrevious(previousRoute); + } + + public override bool maintainState { get; } + + public override TimeSpan transitionDuration { + get { return new TimeSpan(0, 0, 0, 0, 400); } + } + + public override Color barrierColor { + get { return null; } + } + + + public string barrierLabel { + get { return null; } + } + + + public override bool canTransitionFrom(TransitionRoute previousRoute) { + return previousRoute is CupertinoPageRoute; + } + + + public override bool canTransitionTo(TransitionRoute nextRoute) { + return nextRoute is CupertinoPageRoute && !((CupertinoPageRoute) nextRoute).fullscreenDialog; + } + + static bool isPopGestureInProgress(PageRoute route) { + return route.navigator.userGestureInProgress; + } + + + public bool popGestureInProgress { + get { return isPopGestureInProgress(this); } + } + + public bool popGestureEnabled { + get { return _isPopGestureEnabled(this); } + } + + static bool _isPopGestureEnabled(PageRoute route) { + if (route.isFirst) { + return false; + } + + if (route.willHandlePopInternally) { + return false; + } + + if (route.hasScopedWillPopCallback) { + return false; + } + + if (route.fullscreenDialog) { + return false; + } + + if (route.animation.status != AnimationStatus.completed) { + return false; + } + + if (route.secondaryAnimation.status != AnimationStatus.dismissed) { + return false; + } + + if (isPopGestureInProgress(route)) { + return false; + } + + return true; + } + + + public override Widget buildPage(BuildContext context, Animation animation, + Animation secondaryAnimation) { + Widget result = this.builder(context); + + D.assert(() => { + if (result == null) { + throw new UIWidgetsError( + $"The builder for route {this.settings.name} returned null.\nRoute builders must never return null."); + } + + return true; + }); + return result; + } + + + static _CupertinoBackGestureController _startPopGesture(PageRoute route) { + D.assert(_isPopGestureEnabled(route)); + return new _CupertinoBackGestureController( + navigator: route.navigator, + controller: route.controller + ); + } + + public static Widget buildPageTransitions( + PageRoute route, + BuildContext context, + Animation animation, + Animation secondaryAnimation, + Widget child + ) { + if (route.fullscreenDialog) { + return new CupertinoFullscreenDialogTransition( + animation: animation, + child: child + ); + } + + else { + return new CupertinoPageTransition( + primaryRouteAnimation: animation, + secondaryRouteAnimation: secondaryAnimation, + linearTransition: isPopGestureInProgress(route), + child: new _CupertinoBackGestureDetector( + enabledCallback: () => _isPopGestureEnabled(route), + onStartPopGesture: () => _startPopGesture(route), + child: child + ) + ); + } + } + + public override Widget buildTransitions(BuildContext context, Animation animation, + Animation secondaryAnimation, Widget child) { + return buildPageTransitions(this, context, animation, secondaryAnimation, child); + } + + public new string debugLabel { + get { return $"{base.debugLabel}(${this.settings.name})"; } + } + } + + class CupertinoPageTransition : StatelessWidget { + public CupertinoPageTransition( + Animation primaryRouteAnimation, + Animation secondaryRouteAnimation, + Widget child, + bool linearTransition, + Key key = null + ) : base(key: key) { + this._primaryPositionAnimation = + (linearTransition + ? primaryRouteAnimation + : new CurvedAnimation( + parent: primaryRouteAnimation, + curve: Curves.linearToEaseOut, + reverseCurve: Curves.easeInToLinear + ) + ).drive(CupertinoRouteUtils._kRightMiddleTween); + + this._secondaryPositionAnimation = + (linearTransition + ? secondaryRouteAnimation + : new CurvedAnimation( + parent: secondaryRouteAnimation, + curve: Curves.linearToEaseOut, + reverseCurve: Curves.easeInToLinear + ) + ).drive(CupertinoRouteUtils._kMiddleLeftTween); + this._primaryShadowAnimation = + (linearTransition + ? primaryRouteAnimation + : new CurvedAnimation( + parent: primaryRouteAnimation, + curve: Curves.linearToEaseOut + ) + ).drive(CupertinoRouteUtils._kGradientShadowTween); + this.child = child; + } + + public readonly Animation _primaryPositionAnimation; + + public readonly Animation _secondaryPositionAnimation; + public readonly Animation _primaryShadowAnimation; + + public readonly Widget child; + + public override Widget build(BuildContext context) { + TextDirection textDirection = Directionality.of(context); + return new SlideTransition( + position: this._secondaryPositionAnimation, + textDirection: textDirection, + transformHitTests: false, + child: new SlideTransition( + position: this._primaryPositionAnimation, + textDirection: textDirection, + child: new DecoratedBoxTransition( + decoration: this._primaryShadowAnimation, + child: this.child + ) + ) + ); + } + } + + class CupertinoFullscreenDialogTransition : StatelessWidget { + public CupertinoFullscreenDialogTransition( + Animation animation, + Widget child, + Key key = null + ) : base(key: key) { + this._positionAnimation = new CurvedAnimation( + parent: animation, + curve: Curves.linearToEaseOut, + reverseCurve: Curves.linearToEaseOut.flipped + ).drive(CupertinoRouteUtils._kBottomUpTween); + this.child = child; + } + + readonly Animation _positionAnimation; + + public readonly Widget child; + + public override Widget build(BuildContext context) { + return new SlideTransition( + position: this._positionAnimation, + child: this.child + ); + } + } + + class _CupertinoBackGestureDetector : StatefulWidget { + public _CupertinoBackGestureDetector( + Widget child, + ValueGetter enabledCallback, + ValueGetter<_CupertinoBackGestureController> onStartPopGesture, + Key key = null + ) : base(key: key) { + D.assert(enabledCallback != null); + D.assert(onStartPopGesture != null); + D.assert(child != null); + this.child = child; + this.enabledCallback = enabledCallback; + this.onStartPopGesture = onStartPopGesture; + } + + public readonly Widget child; + + public readonly ValueGetter enabledCallback; + + public readonly ValueGetter<_CupertinoBackGestureController> onStartPopGesture; + + public override State createState() { + return new _CupertinoBackGestureDetectorState(); + } + } + + class _CupertinoBackGestureDetectorState : State<_CupertinoBackGestureDetector> { + _CupertinoBackGestureController _backGestureController; + HorizontalDragGestureRecognizer _recognizer; + + + public override void initState() { + base.initState(); + this._recognizer = new HorizontalDragGestureRecognizer(debugOwner: this); + this._recognizer.onStart = this._handleDragStart; + this._recognizer.onUpdate = this._handleDragUpdate; + this._recognizer.onEnd = this._handleDragEnd; + this._recognizer.onCancel = this._handleDragCancel; + } + + public override void dispose() { + this._recognizer.dispose(); + base.dispose(); + } + + void _handleDragStart(DragStartDetails details) { + D.assert(this.mounted); + D.assert(this._backGestureController == null); + this._backGestureController = this.widget.onStartPopGesture(); + } + + void _handleDragUpdate(DragUpdateDetails details) { + D.assert(this.mounted); + D.assert(this._backGestureController != null); + this._backGestureController.dragUpdate( + this._convertToLogical(details.primaryDelta / this.context.size.width)); + } + + void _handleDragEnd(DragEndDetails details) { + D.assert(this.mounted); + D.assert(this._backGestureController != null); + this._backGestureController.dragEnd( + this._convertToLogical(details.velocity.pixelsPerSecond.dx / this.context.size.width) ?? 0); + this._backGestureController = null; + } + + void _handleDragCancel() { + D.assert(this.mounted); + this._backGestureController?.dragEnd(0.0f); + this._backGestureController = null; + } + + void _handlePointerDown(PointerDownEvent evt) { + if (this.widget.enabledCallback()) { + this._recognizer.addPointer(evt); + } + } + + float? _convertToLogical(float? value) { + switch (Directionality.of(this.context)) { + case TextDirection.rtl: + return -value; + case TextDirection.ltr: + return value; + } + + return value; + } + + + public override Widget build(BuildContext context) { + float dragAreaWidth = Directionality.of(context) == TextDirection.ltr + ? MediaQuery.of(context).padding.left + : MediaQuery.of(context).padding.right; + dragAreaWidth = Mathf.Max(dragAreaWidth, CupertinoRouteUtils._kBackGestureWidth); + return new Stack( + fit: StackFit.passthrough, + children: new List { + this.widget.child, + new Positioned( + left: 0.0f, + width: dragAreaWidth, + top: 0.0f, + bottom: 0.0f, + child: new Listener( + onPointerDown: this._handlePointerDown, + behavior: HitTestBehavior.translucent + ) + ) + } + ); + } + } + + class _CupertinoBackGestureController { + public _CupertinoBackGestureController( + NavigatorState navigator, + AnimationController controller + ) { + D.assert(navigator != null); + D.assert(controller != null); + + this.navigator = navigator; + this.controller = controller; + this.navigator.didStartUserGesture(); + } + + public readonly AnimationController controller; + public readonly NavigatorState navigator; + + public void dragUpdate(float? delta) { + if (delta != null) { + this.controller.setValue(this.controller.value - (float) delta); + } + } + + public void dragEnd(float velocity) { + Curve animationCurve = Curves.fastLinearToSlowEaseIn; + bool animateForward; + + if (velocity.abs() >= CupertinoRouteUtils._kMinFlingVelocity) { + animateForward = velocity > 0 ? false : true; + } + else { + animateForward = this.controller.value > 0.5 ? true : false; + } + + if (animateForward) { + int droppedPageForwardAnimationTime = Mathf.Min( + MathUtils.lerpFloat(CupertinoRouteUtils._kMaxDroppedSwipePageForwardAnimationTime, 0f, + this.controller.value).floor(), + CupertinoRouteUtils._kMaxPageBackAnimationTime + ); + this.controller.animateTo(1.0f, duration: new TimeSpan(0, 0, 0, 0, droppedPageForwardAnimationTime), + curve: animationCurve); + } + else { + this.navigator.pop(); + + if (this.controller.isAnimating) { + int droppedPageBackAnimationTime = + MathUtils.lerpFloat(0f, CupertinoRouteUtils._kMaxDroppedSwipePageForwardAnimationTime, + this.controller.value).floor(); + this.controller.animateBack(0.0f, duration: new TimeSpan(0, 0, 0, 0, droppedPageBackAnimationTime), + curve: animationCurve); + } + } + + if (this.controller.isAnimating) { + AnimationStatusListener animationStatusCallback = null; + animationStatusCallback = (AnimationStatus status) => { + this.navigator.didStopUserGesture(); + this.controller.removeStatusListener(animationStatusCallback); + }; + this.controller.addStatusListener(animationStatusCallback); + } + else { + this.navigator.didStopUserGesture(); + } + } + } + + class _CupertinoModalPopupRoute : PopupRoute { + public _CupertinoModalPopupRoute( + WidgetBuilder builder = null, + string barrierLabel = null, + RouteSettings settings = null + ) : base(settings: settings) { + this.builder = builder; + this.barrierLabel = barrierLabel; + } + + public readonly WidgetBuilder builder; + + public readonly string barrierLabel; + + + public override Color barrierColor { + get { return CupertinoRouteUtils._kModalBarrierColor; } + } + + public override bool barrierDismissible { + get { return true; } + } + + public bool semanticsDismissible { + get { return false; } + } + + public override TimeSpan transitionDuration { + get { return CupertinoRouteUtils._kModalPopupTransitionDuration; } + } + + new Animation _animation; + + Tween _offsetTween; + + public override Animation createAnimation() { + D.assert(this._animation == null); + this._animation = new CurvedAnimation( + parent: base.createAnimation(), + curve: Curves.linearToEaseOut, + reverseCurve: Curves.linearToEaseOut.flipped + ); + this._offsetTween = new OffsetTween( + begin: new Offset(0.0f, 1.0f), + end: new Offset(0.0f, 0.0f) + ); + return this._animation; + } + + + public override Widget buildPage(BuildContext context, Animation animation, + Animation secondaryAnimation) { + return this.builder(context); + } + + + public override Widget buildTransitions(BuildContext context, Animation animation, + Animation secondaryAnimation, Widget child) { + return new Align( + alignment: Alignment.bottomCenter, + child: new FractionalTranslation( + translation: this._offsetTween.evaluate(this._animation), + child: child + ) + ); + } + } +} \ No newline at end of file diff --git a/Runtime/cupertino/route.cs.meta b/Runtime/cupertino/route.cs.meta new file mode 100644 index 00000000..36fe493d --- /dev/null +++ b/Runtime/cupertino/route.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8be76856222d049f6a345e650f6484ab +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/cupertino/scrollbar.cs b/Runtime/cupertino/scrollbar.cs new file mode 100644 index 00000000..d4b5b72d --- /dev/null +++ b/Runtime/cupertino/scrollbar.cs @@ -0,0 +1,120 @@ +using System; +using Unity.UIWidgets.animation; +using Unity.UIWidgets.async; +using Unity.UIWidgets.foundation; +using Unity.UIWidgets.ui; +using Unity.UIWidgets.widgets; + +namespace Unity.UIWidgets.cupertino { + class CupertinoScrollbarUtils { + public static readonly Color _kScrollbarColor = new Color(0x99777777); + public const float _kScrollbarThickness = 2.5f; + public const float _kScrollbarMainAxisMargin = 4.0f; + public const float _kScrollbarCrossAxisMargin = 2.5f; + public const float _kScrollbarMinLength = 36.0f; + public const float _kScrollbarMinOverscrollLength = 8.0f; + public static readonly Radius _kScrollbarRadius = Radius.circular(1.25f); + public static readonly TimeSpan _kScrollbarTimeToFade = new TimeSpan(0, 0, 0, 0, 50); + public static readonly TimeSpan _kScrollbarFadeDuration = new TimeSpan(0, 0, 0, 0, 250); + } + + public class CupertinoScrollbar : StatefulWidget { + public CupertinoScrollbar( + Widget child, + Key key = null + ) : base(key: key) { + this.child = child; + } + + public readonly Widget child; + + public override State createState() { + return new _CupertinoScrollbarState(); + } + } + + class _CupertinoScrollbarState : TickerProviderStateMixin { + ScrollbarPainter _painter; + TextDirection _textDirection; + AnimationController _fadeoutAnimationController; + Animation _fadeoutOpacityAnimation; + Timer _fadeoutTimer; + + public override void initState() { + base.initState(); + this._fadeoutAnimationController = new AnimationController( + vsync: this, + duration: CupertinoScrollbarUtils._kScrollbarFadeDuration + ); + this._fadeoutOpacityAnimation = new CurvedAnimation( + parent: this._fadeoutAnimationController, + curve: Curves.fastOutSlowIn + ); + } + + + public override void didChangeDependencies() { + base.didChangeDependencies(); + this._textDirection = Directionality.of(this.context); + this._painter = this._buildCupertinoScrollbarPainter(); + } + + ScrollbarPainter _buildCupertinoScrollbarPainter() { + return new ScrollbarPainter( + color: CupertinoScrollbarUtils._kScrollbarColor, + textDirection: this._textDirection, + thickness: CupertinoScrollbarUtils._kScrollbarThickness, + fadeoutOpacityAnimation: this._fadeoutOpacityAnimation, + mainAxisMargin: CupertinoScrollbarUtils._kScrollbarMainAxisMargin, + crossAxisMargin: CupertinoScrollbarUtils._kScrollbarCrossAxisMargin, + radius: CupertinoScrollbarUtils._kScrollbarRadius, + minLength: CupertinoScrollbarUtils._kScrollbarMinLength, + minOverscrollLength: CupertinoScrollbarUtils._kScrollbarMinOverscrollLength + ); + } + + bool _handleScrollNotification(ScrollNotification notification) { + if (notification is ScrollUpdateNotification || + notification is OverscrollNotification) { + if (this._fadeoutAnimationController.status != AnimationStatus.forward) { + this._fadeoutAnimationController.forward(); + } + + this._fadeoutTimer?.cancel(); + this._painter.update(notification.metrics, notification.metrics.axisDirection); + } + else if (notification is ScrollEndNotification) { + this._fadeoutTimer?.cancel(); + this._fadeoutTimer = Window.instance.run(CupertinoScrollbarUtils._kScrollbarTimeToFade, () => { + this._fadeoutAnimationController.reverse(); + this._fadeoutTimer = null; + }); + } + + return false; + } + + + public override void dispose() { + this._fadeoutAnimationController.dispose(); + this._fadeoutTimer?.cancel(); + this._painter.dispose(); + base.dispose(); + } + + + public override Widget build(BuildContext context) { + return new NotificationListener( + onNotification: this._handleScrollNotification, + child: new RepaintBoundary( + child: new CustomPaint( + foregroundPainter: this._painter, + child: new RepaintBoundary( + child: this.widget.child + ) + ) + ) + ); + } + } +} \ No newline at end of file diff --git a/Runtime/cupertino/scrollbar.cs.meta b/Runtime/cupertino/scrollbar.cs.meta new file mode 100644 index 00000000..f578e3e8 --- /dev/null +++ b/Runtime/cupertino/scrollbar.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cd3dad8c870d149cf8c5cbe1b4d1b285 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/cupertino/slider.cs b/Runtime/cupertino/slider.cs new file mode 100644 index 00000000..0d58acb7 --- /dev/null +++ b/Runtime/cupertino/slider.cs @@ -0,0 +1,380 @@ +using System; +using Unity.UIWidgets.animation; +using Unity.UIWidgets.foundation; +using Unity.UIWidgets.gestures; +using Unity.UIWidgets.rendering; +using Unity.UIWidgets.scheduler; +using Unity.UIWidgets.ui; +using Unity.UIWidgets.widgets; +using UnityEngine; +using Canvas = Unity.UIWidgets.ui.Canvas; +using Color = Unity.UIWidgets.ui.Color; +using Rect = Unity.UIWidgets.ui.Rect; + +namespace Unity.UIWidgets.cupertino { + class SliderUtils { + public const float _kPadding = 8.0f; + public static readonly Color _kTrackColor = new Color(0xFFB5B5B5); + public const float _kSliderHeight = 2.0f * (CupertinoThumbPainter.radius + _kPadding); + public const float _kSliderWidth = 176.0f; // Matches Material Design slider. + public static readonly TimeSpan _kDiscreteTransitionDuration = new TimeSpan(0, 0, 0, 0, 500); + public const float _kAdjustmentUnit = 0.1f; // Matches iOS implementation of material slider. + } + + public class CupertinoSlider : StatefulWidget { + public CupertinoSlider( + Key key = null, + float? value = null, + ValueChanged onChanged = null, + ValueChanged onChangeStart = null, + ValueChanged onChangeEnd = null, + float min = 0.0f, + float max = 1.0f, + int? divisions = null, + Color activeColor = null + ) : base(key: key) { + D.assert(value != null); + D.assert(onChanged != null); + D.assert(value >= min && value <= max); + D.assert(divisions == null || divisions > 0); + this.value = value.Value; + this.onChanged = onChanged; + this.onChangeStart = onChangeStart; + this.onChangeEnd = onChangeEnd; + this.min = min; + this.max = max; + this.divisions = divisions; + this.activeColor = activeColor; + } + + public readonly float value; + + public readonly ValueChanged onChanged; + + public readonly ValueChanged onChangeStart; + + public readonly ValueChanged onChangeEnd; + + public readonly float min; + + public readonly float max; + + public readonly int? divisions; + + public readonly Color activeColor; + + public override State createState() { + return new _CupertinoSliderState(); + } + + public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { + base.debugFillProperties(properties); + properties.add(new FloatProperty("value", this.value)); + properties.add(new FloatProperty("min", this.min)); + properties.add(new FloatProperty("max", this.max)); + } + } + + class _CupertinoSliderState : TickerProviderStateMixin { + void _handleChanged(float value) { + D.assert(this.widget.onChanged != null); + float lerpValue = MathUtils.lerpFloat(this.widget.min, this.widget.max, value); + if (lerpValue != this.widget.value) { + this.widget.onChanged(lerpValue); + } + } + + void _handleDragStart(float value) { + D.assert(this.widget.onChangeStart != null); + this.widget.onChangeStart(MathUtils.lerpFloat(this.widget.min, this.widget.max, value)); + } + + void _handleDragEnd(float value) { + D.assert(this.widget.onChangeEnd != null); + this.widget.onChangeEnd(MathUtils.lerpFloat(this.widget.min, this.widget.max, value)); + } + + public override Widget build(BuildContext context) { + return new _CupertinoSliderRenderObjectWidget( + value: (this.widget.value - this.widget.min) / (this.widget.max - this.widget.min), + divisions: this.widget.divisions, + activeColor: this.widget.activeColor ?? CupertinoTheme.of(context).primaryColor, + onChanged: this.widget.onChanged != null ? (ValueChanged) this._handleChanged : null, + onChangeStart: this.widget.onChangeStart != null ? (ValueChanged) this._handleDragStart : null, + onChangeEnd: this.widget.onChangeEnd != null ? (ValueChanged) this._handleDragEnd : null, + vsync: this + ); + } + } + + class _CupertinoSliderRenderObjectWidget : LeafRenderObjectWidget { + public _CupertinoSliderRenderObjectWidget( + Key key = null, + float? value = null, + int? divisions = null, + Color activeColor = null, + ValueChanged onChanged = null, + ValueChanged onChangeStart = null, + ValueChanged onChangeEnd = null, + TickerProvider vsync = null + ) : base(key: key) { + this.value = value; + this.divisions = divisions; + this.activeColor = activeColor; + this.onChanged = onChanged; + this.onChangeStart = onChangeStart; + this.onChangeEnd = onChangeEnd; + this.vsync = vsync; + } + + public readonly float? value; + public readonly int? divisions; + public readonly Color activeColor; + public readonly ValueChanged onChanged; + public readonly ValueChanged onChangeStart; + public readonly ValueChanged onChangeEnd; + public readonly TickerProvider vsync; + + public override RenderObject createRenderObject(BuildContext context) { + return new _RenderCupertinoSlider( + value: this.value ?? 0.0f, + divisions: this.divisions, + activeColor: this.activeColor, + onChanged: this.onChanged, + onChangeStart: this.onChangeStart, + onChangeEnd: this.onChangeEnd, + vsync: this.vsync + ); + } + + public override void updateRenderObject(BuildContext context, RenderObject _renderObject) { + _RenderCupertinoSlider renderObject = _renderObject as _RenderCupertinoSlider; + renderObject.value = this.value ?? 0.0f; + renderObject.divisions = this.divisions; + renderObject.activeColor = this.activeColor; + renderObject.onChanged = this.onChanged; + renderObject.onChangeStart = this.onChangeStart; + renderObject.onChangeEnd = this.onChangeEnd; + } + } + + class _RenderCupertinoSlider : RenderConstrainedBox { + public _RenderCupertinoSlider( + float value, + int? divisions = null, + Color activeColor = null, + ValueChanged onChanged = null, + ValueChanged onChangeStart = null, + ValueChanged onChangeEnd = null, + TickerProvider vsync = null + ) : base(additionalConstraints: BoxConstraints.tightFor(width: SliderUtils._kSliderWidth, + height: SliderUtils._kSliderHeight)) { + D.assert(value >= 0.0f && value <= 1.0f); + this._value = value; + this._divisions = divisions; + this._activeColor = activeColor; + this._onChanged = onChanged; + this.onChangeStart = onChangeStart; + this.onChangeEnd = onChangeEnd; + this._drag = new HorizontalDragGestureRecognizer(); + this._drag.onStart = this._handleDragStart; + this._drag.onUpdate = this._handleDragUpdate; + this._drag.onEnd = this._handleDragEnd; + this._position = new AnimationController( + value: value, + duration: SliderUtils._kDiscreteTransitionDuration, + vsync: vsync + ); + this._position.addListener(this.markNeedsPaint); + } + + public float value { + get { return this._value; } + set { + D.assert(value >= 0.0f && value <= 1.0f); + if (value == this._value) { + return; + } + + this._value = value; + if (this.divisions != null) { + this._position.animateTo(value, curve: Curves.fastOutSlowIn); + } + else { + this._position.setValue(value); + } + } + } + + float _value; + + public int? divisions { + get { return this._divisions; } + set { + if (value == this._divisions) { + return; + } + + this._divisions = value; + this.markNeedsPaint(); + } + } + + int? _divisions; + + public Color activeColor { + get { return this._activeColor; } + set { + if (value == this._activeColor) { + return; + } + + this._activeColor = value; + this.markNeedsPaint(); + } + } + + Color _activeColor; + + public ValueChanged onChanged { + get { return this._onChanged; } + set { + if (value == this._onChanged) { + return; + } + + this._onChanged = value; + } + } + + ValueChanged _onChanged; + + public ValueChanged onChangeStart; + public ValueChanged onChangeEnd; + + + AnimationController _position; + + HorizontalDragGestureRecognizer _drag; + float _currentDragValue = 0.0f; + + float _discretizedCurrentDragValue { + get { + float dragValue = this._currentDragValue.clamp(0.0f, 1.0f); + if (this.divisions != null) { + dragValue = Mathf.Round(dragValue * this.divisions.Value) / this.divisions.Value; + } + + return dragValue; + } + } + + public float _trackLeft { + get { return SliderUtils._kPadding; } + } + + public float _trackRight { + get { return this.size.width - SliderUtils._kPadding; } + } + + float _thumbCenter { + get { + float visualPosition = this._value; + + return MathUtils.lerpFloat(this._trackLeft + CupertinoThumbPainter.radius, + this._trackRight - CupertinoThumbPainter.radius, + visualPosition); + } + } + + public bool isInteractive { + get { return this.onChanged != null; } + } + + void _handleDragStart(DragStartDetails details) { + this._startInteraction(details.globalPosition); + } + + void _handleDragUpdate(DragUpdateDetails details) { + if (this.isInteractive) { + float extent = Mathf.Max(SliderUtils._kPadding, + this.size.width - 2.0f * (SliderUtils._kPadding + CupertinoThumbPainter.radius)); + float? valueDelta = details.primaryDelta / extent; + this._currentDragValue += valueDelta ?? 0.0f; + + this.onChanged(this._discretizedCurrentDragValue); + } + } + + void _handleDragEnd(DragEndDetails details) { + this._endInteraction(); + } + + void _startInteraction(Offset globalPosition) { + if (this.isInteractive) { + if (this.onChangeStart != null) { + this.onChangeStart(this._discretizedCurrentDragValue); + } + + this._currentDragValue = this._value; + this.onChanged(this._discretizedCurrentDragValue); + } + } + + void _endInteraction() { + if (this.onChangeEnd != null) { + this.onChangeEnd(this._discretizedCurrentDragValue); + } + + this._currentDragValue = 0.0f; + } + + protected override bool hitTestSelf(Offset position) { + return (position.dx - this._thumbCenter).abs() < CupertinoThumbPainter.radius + SliderUtils._kPadding; + } + + public override void handleEvent(PointerEvent e, HitTestEntry entry) { + D.assert(this.debugHandleEvent(e, entry)); + if (e is PointerDownEvent pointerDownEvent && this.isInteractive) { + this._drag.addPointer(pointerDownEvent); + } + } + + CupertinoThumbPainter _thumbPainter = new CupertinoThumbPainter(); + + public override + void paint(PaintingContext context, Offset offset) { + float visualPosition; + Color leftColor; + Color rightColor; + visualPosition = this._position.value; + leftColor = SliderUtils._kTrackColor; + rightColor = this._activeColor; + + float trackCenter = offset.dy + this.size.height / 2.0f; + float trackLeft = offset.dx + this._trackLeft; + float trackTop = trackCenter - 1.0f; + float trackBottom = trackCenter + 1.0f; + float trackRight = offset.dx + this._trackRight; + float trackActive = offset.dx + this._thumbCenter; + + Canvas canvas = context.canvas; + + if (visualPosition > 0.0f) { + Paint paint = new Paint(); + paint.color = rightColor; + canvas.drawRRect(RRect.fromLTRBXY(trackLeft, trackTop, trackActive, trackBottom, 1.0f, 1.0f), paint); + } + + if (visualPosition < 1.0f) { + Paint paint = new Paint(); + paint.color = leftColor; + canvas.drawRRect(RRect.fromLTRBXY(trackActive, trackTop, trackRight, trackBottom, 1.0f, 1.0f), paint); + } + + Offset thumbCenter = new Offset(trackActive, trackCenter); + this._thumbPainter.paint(canvas, + Rect.fromCircle(center: thumbCenter, radius: CupertinoThumbPainter.radius)); + } + } +} \ No newline at end of file diff --git a/Runtime/cupertino/slider.cs.meta b/Runtime/cupertino/slider.cs.meta new file mode 100644 index 00000000..0001ec63 --- /dev/null +++ b/Runtime/cupertino/slider.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9d6aaa856d879be40833f2ae7ec103ac +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/cupertino/switch.cs b/Runtime/cupertino/switch.cs new file mode 100644 index 00000000..089ce21c --- /dev/null +++ b/Runtime/cupertino/switch.cs @@ -0,0 +1,495 @@ +using System; +using Unity.UIWidgets.animation; +using Unity.UIWidgets.foundation; +using Unity.UIWidgets.gestures; +using Unity.UIWidgets.rendering; +using Unity.UIWidgets.scheduler; +using Unity.UIWidgets.ui; +using Unity.UIWidgets.widgets; +using UnityEngine; +using Canvas = Unity.UIWidgets.ui.Canvas; +using Color = Unity.UIWidgets.ui.Color; +using Rect = Unity.UIWidgets.ui.Rect; + +namespace Unity.UIWidgets.cupertino { + class CupertinoSwitchUtils { + public const float _kTrackWidth = 51.0f; + public const float _kTrackHeight = 31.0f; + public const float _kTrackRadius = _kTrackHeight / 2.0f; + public const float _kTrackInnerStart = _kTrackHeight / 2.0f; + public const float _kTrackInnerEnd = _kTrackWidth - _kTrackInnerStart; + public const float _kTrackInnerLength = _kTrackInnerEnd - _kTrackInnerStart; + public const float _kSwitchWidth = 59.0f; + public const float _kSwitchHeight = 39.0f; + public const float _kCupertinoSwitchDisabledOpacity = 0.5f; + public static readonly Color _kTrackColor = CupertinoColors.lightBackgroundGray; + public static readonly TimeSpan _kReactionDuration = new TimeSpan(0, 0, 0, 0, 300); + public static readonly TimeSpan _kToggleDuration = new TimeSpan(0, 0, 0, 0, 200); + } + + public class CupertinoSwitch : StatefulWidget { + public CupertinoSwitch( + bool value, + ValueChanged onChanged, + Key key = null, + Color activeColor = null, + DragStartBehavior dragStartBehavior = DragStartBehavior.start + ) : base(key: key) { + this.value = value; + this.onChanged = onChanged; + this.activeColor = activeColor; + this.dragStartBehavior = dragStartBehavior; + } + + public readonly bool value; + + public readonly ValueChanged onChanged; + + public readonly Color activeColor; + + public readonly DragStartBehavior dragStartBehavior; + + public override State createState() { + return new _CupertinoSwitchState(); + } + + public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { + base.debugFillProperties(properties); + properties.add(new FlagProperty("value", value: this.value, ifTrue: "on", ifFalse: "off", showName: true)); + properties.add(new ObjectFlagProperty>("onChanged", this.onChanged, ifNull: "disabled")); + } + } + + class _CupertinoSwitchState : TickerProviderStateMixin { + public override Widget build(BuildContext context) { + return new Opacity( + opacity: this.widget.onChanged == null ? CupertinoSwitchUtils._kCupertinoSwitchDisabledOpacity : 1.0f, + child: new _CupertinoSwitchRenderObjectWidget( + value: this.widget.value, + activeColor: this.widget.activeColor ?? CupertinoColors.activeGreen, + onChanged: this.widget.onChanged, + vsync: this, + dragStartBehavior: this.widget.dragStartBehavior + ) + ); + } + } + + class _CupertinoSwitchRenderObjectWidget : LeafRenderObjectWidget { + public _CupertinoSwitchRenderObjectWidget( + Key key = null, + bool value = false, + Color activeColor = null, + ValueChanged onChanged = null, + TickerProvider vsync = null, + DragStartBehavior dragStartBehavior = DragStartBehavior.start + ) : base(key: key) { + this.value = value; + this.activeColor = activeColor; + this.onChanged = onChanged; + this.vsync = vsync; + this.dragStartBehavior = dragStartBehavior; + } + + public readonly bool value; + public readonly Color activeColor; + public readonly ValueChanged onChanged; + public readonly TickerProvider vsync; + public readonly DragStartBehavior dragStartBehavior; + + public override RenderObject createRenderObject(BuildContext context) { + return new _RenderCupertinoSwitch( + value: this.value, + activeColor: this.activeColor, + onChanged: this.onChanged, + textDirection: Directionality.of(context), + vsync: this.vsync, + dragStartBehavior: this.dragStartBehavior + ); + } + + public override void updateRenderObject(BuildContext context, RenderObject renderObject) { + var _renderObject = renderObject as _RenderCupertinoSwitch; + _renderObject.value = this.value; + _renderObject.activeColor = this.activeColor; + _renderObject.onChanged = this.onChanged; + _renderObject.textDirection = Directionality.of(context); + _renderObject.vsync = this.vsync; + _renderObject.dragStartBehavior = this.dragStartBehavior; + } + } + + + class _RenderCupertinoSwitch : RenderConstrainedBox { + public _RenderCupertinoSwitch( + bool value, + Color activeColor, + TextDirection textDirection, + TickerProvider vsync, + ValueChanged onChanged = null, + DragStartBehavior dragStartBehavior = DragStartBehavior.start + ) : base(additionalConstraints: BoxConstraints.tightFor( + width: CupertinoSwitchUtils._kSwitchWidth, + height: CupertinoSwitchUtils._kSwitchHeight) + ) { + D.assert(activeColor != null); + D.assert(vsync != null); + this._value = value; + this._activeColor = activeColor; + this._onChanged = onChanged; + this._textDirection = textDirection; + this._vsync = vsync; + + this._tap = new TapGestureRecognizer() { + onTapDown = this._handleTapDown, + onTap = this._handleTap, + onTapUp = this._handleTapUp, + onTapCancel = this._handleTapCancel, + }; + + this._drag = new HorizontalDragGestureRecognizer() { + onStart = this._handleDragStart, + onUpdate = this._handleDragUpdate, + onEnd = this._handleDragEnd, + dragStartBehavior = dragStartBehavior + }; + + this._positionController = new AnimationController( + duration: CupertinoSwitchUtils._kToggleDuration, + value: value ? 1.0f : 0.0f, + vsync: vsync + ); + this._position = new CurvedAnimation( + parent: this._positionController, + curve: Curves.linear + ); + this._position.addListener(this.markNeedsPaint); + this._position.addStatusListener(this._handlePositionStateChanged); + + this._reactionController = new AnimationController( + duration: CupertinoSwitchUtils._kReactionDuration, + vsync: vsync + ); + this._reaction = new CurvedAnimation( + parent: this._reactionController, + curve: Curves.ease + ); + this._reaction.addListener(this.markNeedsPaint); + } + + AnimationController _positionController; + CurvedAnimation _position; + AnimationController _reactionController; + Animation _reaction; + + public bool value { + get { return this._value; } + set { + if (value == this._value) { + return; + } + + this._value = value; + // this.markNeedsSemanticsUpdate(); + this._position.curve = Curves.ease; + this._position.reverseCurve = Curves.ease.flipped; + if (value) { + this._positionController.forward(); + } + else { + this._positionController.reverse(); + } + } + } + + bool _value; + + public TickerProvider vsync { + get { return this._vsync; } + set { + D.assert(value != null); + if (value == this._vsync) { + return; + } + + this._vsync = value; + this._positionController.resync(this.vsync); + this._reactionController.resync(this.vsync); + } + } + + TickerProvider _vsync; + + public Color activeColor { + get { return this._activeColor; } + set { + D.assert(value != null); + if (value == this._activeColor) { + return; + } + + this._activeColor = value; + this.markNeedsPaint(); + } + } + + Color _activeColor; + + public ValueChanged onChanged { + get { return this._onChanged; } + set { + if (value == this._onChanged) { + return; + } + + bool wasInteractive = this.isInteractive; + this._onChanged = value; + if (wasInteractive != this.isInteractive) { + this.markNeedsPaint(); + } + } + } + + ValueChanged _onChanged; + + public TextDirection textDirection { + get { return this._textDirection; } + set { + if (this._textDirection == value) { + return; + } + + this._textDirection = value; + this.markNeedsPaint(); + } + } + + TextDirection _textDirection; + + + public DragStartBehavior dragStartBehavior { + get { return this._drag.dragStartBehavior; } + set { + if (this._drag.dragStartBehavior == value) { + return; + } + + this._drag.dragStartBehavior = value; + } + } + + public bool isInteractive { + get { return this.onChanged != null; } + } + + TapGestureRecognizer _tap; + HorizontalDragGestureRecognizer _drag; + + public override void attach(object _owner) { + base.attach(_owner); + if (this.value) { + this._positionController.forward(); + } + else { + this._positionController.reverse(); + } + + if (this.isInteractive) { + switch (this._reactionController.status) { + case AnimationStatus.forward: + this._reactionController.forward(); + break; + case AnimationStatus.reverse: + this._reactionController.reverse(); + break; + case AnimationStatus.dismissed: + case AnimationStatus.completed: + break; + } + } + } + + public override void detach() { + this._positionController.stop(); + this._reactionController.stop(); + base.detach(); + } + + void _handlePositionStateChanged(AnimationStatus status) { + if (this.isInteractive) { + if (status == AnimationStatus.completed && !this._value) { + this.onChanged(true); + } + else if (status == AnimationStatus.dismissed && this._value) { + this.onChanged(false); + } + } + } + + void _handleTapDown(TapDownDetails details) { + if (this.isInteractive) { + this._reactionController.forward(); + } + } + + void _handleTap() { + if (this.isInteractive) { + this.onChanged(!this._value); + this._emitVibration(); + } + } + + void _handleTapUp(TapUpDetails details) { + if (this.isInteractive) { + this._reactionController.reverse(); + } + } + + void _handleTapCancel() { + if (this.isInteractive) { + this._reactionController.reverse(); + } + } + + void _handleDragStart(DragStartDetails details) { + if (this.isInteractive) { + this._reactionController.forward(); + this._emitVibration(); + } + } + + void _handleDragUpdate(DragUpdateDetails details) { + if (this.isInteractive) { + this._position.curve = null; + this._position.reverseCurve = null; + float delta = details.primaryDelta / CupertinoSwitchUtils._kTrackInnerLength ?? 0f; + + this._positionController.setValue(this._positionController.value + delta); + + // switch (this.textDirection) { + // case TextDirection.rtl: + // this._positionController.setValue(this._positionController.value - delta); + // break; + // case TextDirection.ltr: + // this._positionController.setValue(this._positionController.value + delta); + // break; + // } + } + } + + void _handleDragEnd(DragEndDetails details) { + if (this._position.value >= 0.5) { + this._positionController.forward(); + } + else { + this._positionController.reverse(); + } + + this._reactionController.reverse(); + } + + void _emitVibration() { + // switch (Platform defaultTargetPlatform) { + // case TargetPlatform.iOS: + // HapticFeedback.lightImpact(); + // break; + // case TargetPlatform.fuchsia: + // case TargetPlatform.android: + // break; + // } + return; + } + + protected override bool hitTestSelf(Offset position) { + return true; + } + + public override void handleEvent(PointerEvent evt, HitTestEntry entry) { + D.assert(this.debugHandleEvent(evt, entry)); + if (evt is PointerDownEvent && this.isInteractive) { + this._drag.addPointer(evt as PointerDownEvent); + this._tap.addPointer(evt as PointerDownEvent); + } + } + + // public override void describeSemanticsConfiguration(SemanticsConfiguration config) { + // base.describeSemanticsConfiguration(config); + // + // if (isInteractive) + // config.onTap = _handleTap; + // + // config.isEnabled = isInteractive; + // config.isToggled = _value; + // } + + public readonly CupertinoThumbPainter _thumbPainter = new CupertinoThumbPainter(); + + public override void paint(PaintingContext context, Offset offset) { + Canvas canvas = context.canvas; + + float currentValue = this._position.value; + float currentReactionValue = this._reaction.value; + + float visualPosition = 0f; + switch (this.textDirection) { + case TextDirection.rtl: + visualPosition = 1.0f - currentValue; + break; + case TextDirection.ltr: + visualPosition = currentValue; + break; + } + + Color trackColor = this._value ? this.activeColor : CupertinoSwitchUtils._kTrackColor; + float borderThickness = + 1.5f + (CupertinoSwitchUtils._kTrackRadius - 1.5f) * Mathf.Max(currentReactionValue, currentValue); + + Paint paint = new Paint(); + paint.color = trackColor; + + Rect trackRect = Rect.fromLTWH( + offset.dx + (this.size.width - CupertinoSwitchUtils._kTrackWidth) / 2.0f, + offset.dy + (this.size.height - CupertinoSwitchUtils._kTrackHeight) / 2.0f, + CupertinoSwitchUtils._kTrackWidth, + CupertinoSwitchUtils._kTrackHeight + ); + RRect outerRRect = RRect.fromRectAndRadius(trackRect, Radius.circular(CupertinoSwitchUtils + ._kTrackRadius)); + RRect innerRRect = RRect.fromRectAndRadius(trackRect.deflate(borderThickness), Radius.circular + (CupertinoSwitchUtils._kTrackRadius)); + canvas.drawDRRect(outerRRect, innerRRect, paint); + + float currentThumbExtension = CupertinoThumbPainter.extension * currentReactionValue; + float thumbLeft = MathUtils.lerpFloat( + trackRect.left + CupertinoSwitchUtils._kTrackInnerStart - CupertinoThumbPainter.radius, + trackRect.left + CupertinoSwitchUtils._kTrackInnerEnd - CupertinoThumbPainter.radius - + currentThumbExtension, + visualPosition + ); + float thumbRight = MathUtils.lerpFloat( + trackRect.left + CupertinoSwitchUtils._kTrackInnerStart + CupertinoThumbPainter.radius + + currentThumbExtension, + trackRect.left + CupertinoSwitchUtils._kTrackInnerEnd + CupertinoThumbPainter.radius, + visualPosition + ); + float thumbCenterY = offset.dy + this.size.height / 2.0f; + + this._thumbPainter.paint(canvas, Rect.fromLTRB( + thumbLeft, + thumbCenterY - CupertinoThumbPainter.radius, + thumbRight, + thumbCenterY + CupertinoThumbPainter.radius + )); + } + + + public override void debugFillProperties(DiagnosticPropertiesBuilder description) { + base.debugFillProperties(description); + description.add( + new FlagProperty("value", value: this.value, ifTrue: "checked", ifFalse: "unchecked", showName: true)); + description.add(new FlagProperty("isInteractive", value: this.isInteractive, ifTrue: "enabled", + ifFalse: "disabled", + showName: true, defaultValue: true)); + } + } +} \ No newline at end of file diff --git a/Runtime/cupertino/switch.cs.meta b/Runtime/cupertino/switch.cs.meta new file mode 100644 index 00000000..0885e8a4 --- /dev/null +++ b/Runtime/cupertino/switch.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4eec4759a3c0145a88e1cff304d7400b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/cupertino/tab_scaffold.cs b/Runtime/cupertino/tab_scaffold.cs new file mode 100644 index 00000000..3905ddcb --- /dev/null +++ b/Runtime/cupertino/tab_scaffold.cs @@ -0,0 +1,221 @@ +using System.Collections.Generic; +using System.Linq; +using Unity.UIWidgets.foundation; +using Unity.UIWidgets.painting; +using Unity.UIWidgets.rendering; +using Unity.UIWidgets.ui; +using Unity.UIWidgets.widgets; + +namespace Unity.UIWidgets.cupertino { + public class CupertinoTabScaffold : StatefulWidget { + public CupertinoTabScaffold( + Key key = null, + CupertinoTabBar tabBar = null, + IndexedWidgetBuilder tabBuilder = null, + Color backgroundColor = null, + bool resizeToAvoidBottomInset = true + ) : base(key: key) { + D.assert(tabBar != null); + D.assert(tabBuilder != null); + this.tabBar = tabBar; + this.tabBuilder = tabBuilder; + this.backgroundColor = backgroundColor; + this.resizeToAvoidBottomInset = resizeToAvoidBottomInset; + } + + + public readonly CupertinoTabBar tabBar; + + public readonly IndexedWidgetBuilder tabBuilder; + + public readonly Color backgroundColor; + + public readonly bool resizeToAvoidBottomInset; + + public override State createState() { + return new _CupertinoTabScaffoldState(); + } + } + + class _CupertinoTabScaffoldState : State { + int _currentPage; + + public override void initState() { + base.initState(); + this._currentPage = this.widget.tabBar.currentIndex; + + } + + public override void didUpdateWidget(StatefulWidget _oldWidget) { + CupertinoTabScaffold oldWidget = _oldWidget as CupertinoTabScaffold; + base.didUpdateWidget(oldWidget); + if (this._currentPage >= this.widget.tabBar.items.Count) { + this._currentPage = this.widget.tabBar.items.Count - 1; + D.assert(this._currentPage >= 0, + () => "CupertinoTabBar is expected to keep at least 2 tabs after updating" + ); + } + + if (this.widget.tabBar.currentIndex != oldWidget.tabBar.currentIndex) { + this._currentPage = this.widget.tabBar.currentIndex; + } + } + + public override Widget build(BuildContext context) { + List stacked = new List { }; + + MediaQueryData existingMediaQuery = MediaQuery.of(context); + MediaQueryData newMediaQuery = MediaQuery.of(context); + + Widget content = new _TabSwitchingView( + currentTabIndex: this._currentPage, + tabNumber: this.widget.tabBar.items.Count, + tabBuilder: this.widget.tabBuilder + ); + EdgeInsets contentPadding = EdgeInsets.zero; + + if (this.widget.resizeToAvoidBottomInset) { + newMediaQuery = newMediaQuery.removeViewInsets(removeBottom: true); + contentPadding = EdgeInsets.only(bottom: existingMediaQuery.viewInsets.bottom); + } + + if (this.widget.tabBar != null && + (!this.widget.resizeToAvoidBottomInset || + this.widget.tabBar.preferredSize.height > existingMediaQuery.viewInsets.bottom)) { + float bottomPadding = this.widget.tabBar.preferredSize.height + existingMediaQuery.padding.bottom; + + if (this.widget.tabBar.opaque(context)) { + contentPadding = EdgeInsets.only(bottom: bottomPadding); + } + else { + newMediaQuery = newMediaQuery.copyWith( + padding: newMediaQuery.padding.copyWith( + bottom: bottomPadding + ) + ); + } + } + + content = new MediaQuery( + data: newMediaQuery, + child: new Padding( + padding: contentPadding, + child: content + ) + ); + + stacked.Add(content); + + if (this.widget.tabBar != null) { + stacked.Add(new Align( + alignment: Alignment.bottomCenter, + child: this.widget.tabBar.copyWith( + currentIndex: this._currentPage, + onTap: (int newIndex) => { + this.setState(() => { this._currentPage = newIndex; }); + if (this.widget.tabBar.onTap != null) { + this.widget.tabBar.onTap(newIndex); + } + } + ) + )); + } + + return new DecoratedBox( + decoration: new BoxDecoration( + color: this.widget.backgroundColor ?? CupertinoTheme.of(context).scaffoldBackgroundColor + ), + child: new Stack( + children: stacked + ) + ); + } + } + + class _TabSwitchingView : StatefulWidget { + public _TabSwitchingView( + int currentTabIndex, + int tabNumber, + IndexedWidgetBuilder tabBuilder + ) { + D.assert(tabNumber > 0); + D.assert(tabBuilder != null); + this.currentTabIndex = currentTabIndex; + this.tabNumber = tabNumber; + this.tabBuilder = tabBuilder; + } + + public readonly int currentTabIndex; + public readonly int tabNumber; + public readonly IndexedWidgetBuilder tabBuilder; + + public override State createState() { + return new _TabSwitchingViewState(); + } + } + + class _TabSwitchingViewState : State<_TabSwitchingView> { + List tabs; + List tabFocusNodes; + + public override void initState() { + base.initState(); + this.tabs = new List(this.widget.tabNumber); + for (int i = 0; i < this.widget.tabNumber; i++) { + this.tabs.Add(null); + } + this.tabFocusNodes = Enumerable.Repeat(new FocusScopeNode(), this.widget.tabNumber).ToList(); + } + + public override void didChangeDependencies() { + base.didChangeDependencies(); + this._focusActiveTab(); + } + + public override void didUpdateWidget(StatefulWidget _oldWidget) { + _TabSwitchingView oldWidget = _oldWidget as _TabSwitchingView; + base.didUpdateWidget(oldWidget); + this._focusActiveTab(); + } + + void _focusActiveTab() { + FocusScope.of(this.context).setFirstFocus(this.tabFocusNodes[this.widget.currentTabIndex]); + } + + public override void dispose() { + foreach (FocusScopeNode focusScopeNode in this.tabFocusNodes) { + focusScopeNode.detach(); + } + + base.dispose(); + } + + public override Widget build(BuildContext context) { + List children = new List(); + for (int index = 0; index < this.widget.tabNumber; index++) { + bool active = index == this.widget.currentTabIndex; + + var tabIndex = index; + if (active || this.tabs[index] != null) { + this.tabs[index] = this.widget.tabBuilder(context, tabIndex); + } + + children.Add(new Offstage( + offstage: !active, + child: new TickerMode( + enabled: active, + child: new FocusScope( + node: this.tabFocusNodes[index], + child: this.tabs[index] ?? new Container() + ) + ) + )); + } + + return new Stack( + fit: StackFit.expand, + children: children + ); + } + } +} \ No newline at end of file diff --git a/Runtime/cupertino/tab_scaffold.cs.meta b/Runtime/cupertino/tab_scaffold.cs.meta new file mode 100644 index 00000000..53fad060 --- /dev/null +++ b/Runtime/cupertino/tab_scaffold.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dd65a2bea05bed8409d301489cf20864 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/cupertino/tab_view.cs b/Runtime/cupertino/tab_view.cs new file mode 100644 index 00000000..caed0b57 --- /dev/null +++ b/Runtime/cupertino/tab_view.cs @@ -0,0 +1,141 @@ +using System.Collections.Generic; +using Unity.UIWidgets.foundation; +using Unity.UIWidgets.widgets; + +namespace Unity.UIWidgets.cupertino { + public class CupertinoTabView : StatefulWidget { + public CupertinoTabView( + Key key = null, + WidgetBuilder builder = null, + GlobalKey navigatorKey = null, + string defaultTitle = null, + Dictionary routes = null, + RouteFactory onGenerateRoute = null, + RouteFactory onUnknownRoute = null, + List navigatorObservers = null + ) : base(key: key) { + this.builder = builder; + this.navigatorKey = navigatorKey; + this.defaultTitle = defaultTitle; + this.routes = routes; + this.onGenerateRoute = onGenerateRoute; + this.onUnknownRoute = onUnknownRoute; + this.navigatorObservers = navigatorObservers ?? new List(); + } + + public readonly WidgetBuilder builder; + + public readonly GlobalKey navigatorKey; + + public readonly string defaultTitle; + + public readonly Dictionary routes; + + public readonly RouteFactory onGenerateRoute; + + public readonly RouteFactory onUnknownRoute; + + public readonly List navigatorObservers; + + public override State createState() { + return new _CupertinoTabViewState(); + } + } + + class _CupertinoTabViewState : State { + HeroController _heroController; + List _navigatorObservers; + + public override void initState() { + base.initState(); + this._heroController = CupertinoApp.createCupertinoHeroController(); + this._updateObservers(); + } + + public override void didUpdateWidget(StatefulWidget oldWidget) { + base.didUpdateWidget(oldWidget); + CupertinoTabView _oldWidget = (CupertinoTabView) oldWidget; + if (this.widget.navigatorKey != _oldWidget.navigatorKey + || this.widget.navigatorObservers != _oldWidget.navigatorObservers) { + this._updateObservers(); + } + } + + void _updateObservers() { + this._navigatorObservers = + new List(this.widget.navigatorObservers); + this._navigatorObservers.Add(this._heroController); + } + + public override Widget build(BuildContext context) { + return new Navigator( + key: this.widget.navigatorKey, + onGenerateRoute: this._onGenerateRoute, + onUnknownRoute: this._onUnknownRoute, + observers: this._navigatorObservers + ); + } + + Route _onGenerateRoute(RouteSettings settings) { + string name = settings.name; + WidgetBuilder routeBuilder = null; + string title = null; + if (name == Navigator.defaultRouteName && this.widget.builder != null) { + routeBuilder = this.widget.builder; + title = this.widget.defaultTitle; + } + else if (this.widget.routes != null) { + routeBuilder = this.widget.routes[name]; + } + + if (routeBuilder != null) { + return new CupertinoPageRoute( + builder: routeBuilder, + title: title, + settings: settings + ); + } + + if (this.widget.onGenerateRoute != null) { + return this.widget.onGenerateRoute(settings); + } + + return null; + } + + Route _onUnknownRoute(RouteSettings settings) { + D.assert(() => { + if (this.widget.onUnknownRoute == null) { + throw new UIWidgetsError( + $"Could not find a generator for route {settings} in the {this.GetType()}.\n" + + "Generators for routes are searched for in the following order:\n" + + " 1. For the \"/\" route, the \"builder\" property, if non-null, is used.\n" + + " 2. Otherwise, the \"routes\" table is used, if it has an entry for " + + "the route.\n" + + " 3. Otherwise, onGenerateRoute is called. It should return a " + + "non-null value for any valid route not handled by \"builder\" and \"routes\".\n" + + " 4. Finally if all else fails onUnknownRoute is called.\n" + + "Unfortunately, onUnknownRoute was not set." + ); + } + + return true; + }); + + Route result = this.widget.onUnknownRoute(settings); + D.assert(() => { + if (result == null) { + throw new UIWidgetsError( + "The onUnknownRoute callback returned null.\n" + + $"When the {this.GetType()} requested the route {settings} from its " + + "onUnknownRoute callback, the callback returned null. Such callbacks " + + "must never return null." + ); + } + + return true; + }); + return result; + } + } +} \ No newline at end of file diff --git a/Runtime/cupertino/tab_view.cs.meta b/Runtime/cupertino/tab_view.cs.meta new file mode 100644 index 00000000..366b7ff0 --- /dev/null +++ b/Runtime/cupertino/tab_view.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6a23c29fee52d4274be319d1f5df98c4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/cupertino/text_field.cs b/Runtime/cupertino/text_field.cs new file mode 100644 index 00000000..1451264e --- /dev/null +++ b/Runtime/cupertino/text_field.cs @@ -0,0 +1,574 @@ +using System.Collections.Generic; +using Unity.UIWidgets.foundation; +using Unity.UIWidgets.gestures; +using Unity.UIWidgets.painting; +using Unity.UIWidgets.rendering; +using Unity.UIWidgets.service; +using Unity.UIWidgets.ui; +using Unity.UIWidgets.widgets; +using TextStyle = Unity.UIWidgets.painting.TextStyle; + +namespace Unity.UIWidgets.cupertino { + class CupertinoTextFieldUtils { + public static readonly BorderSide _kDefaultRoundedBorderSide = new BorderSide( + color: CupertinoColors.lightBackgroundGray, + style: BorderStyle.solid, + width: 0.0f + ); + + public static readonly Border _kDefaultRoundedBorder = new Border( + top: _kDefaultRoundedBorderSide, + bottom: _kDefaultRoundedBorderSide, + left: _kDefaultRoundedBorderSide, + right: _kDefaultRoundedBorderSide + ); + + public static readonly BoxDecoration _kDefaultRoundedBorderDecoration = new BoxDecoration( + border: _kDefaultRoundedBorder, + borderRadius: BorderRadius.all(Radius.circular(4.0f)) + ); + + public static readonly Color _kSelectionHighlightColor = new Color(0x667FAACF); + + public static readonly Color _kInactiveTextColor = new Color(0xFFC2C2C2); + + public static readonly Color _kDisabledBackground = new Color(0xFFFAFAFA); + + public const int _iOSHorizontalCursorOffsetPixels = -2; + } + + public enum OverlayVisibilityMode { + never, + editing, + notEditing, + always + } + + public class CupertinoTextField : StatefulWidget { + public CupertinoTextField( + Key key = null, + TextEditingController controller = null, + FocusNode focusNode = null, + BoxDecoration decoration = null, + EdgeInsets padding = null, + string placeholder = null, + TextStyle placeholderStyle = null, + Widget prefix = null, + OverlayVisibilityMode prefixMode = OverlayVisibilityMode.always, + Widget suffix = null, + OverlayVisibilityMode suffixMode = OverlayVisibilityMode.always, + OverlayVisibilityMode clearButtonMode = OverlayVisibilityMode.never, + TextInputType keyboardType = null, + TextInputAction? textInputAction = null, + TextCapitalization textCapitalization = TextCapitalization.none, + TextStyle style = null, + StrutStyle strutStyle = null, + TextAlign textAlign = TextAlign.left, + bool autofocus = false, + bool obscureText = false, + bool autocorrect = true, + int? maxLines = 1, + int? minLines = null, + bool expands = false, + int? maxLength = null, + bool maxLengthEnforced = true, + ValueChanged onChanged = null, + VoidCallback onEditingComplete = null, + ValueChanged onSubmitted = null, + List inputFormatters = null, + bool? enabled = null, + float cursorWidth = 2.0f, + Radius cursorRadius = null, + Color cursorColor = null, + Brightness? keyboardAppearance = null, + EdgeInsets scrollPadding = null, + DragStartBehavior dragStartBehavior = DragStartBehavior.start, + ScrollPhysics scrollPhysics = null) : base(key: key) { + D.assert(maxLines == null || maxLines > 0); + D.assert(minLines == null || minLines > 0); + D.assert(maxLines == null || minLines == null || maxLines >= minLines, + () => "minLines can't be greater than maxLines"); + D.assert(!expands || (maxLines == null && minLines == null), + () => "minLines and maxLines must be null when expands is true."); + D.assert(maxLength == null || maxLength > 0); + + this.controller = controller; + this.focusNode = focusNode; + this.decoration = decoration ?? CupertinoTextFieldUtils._kDefaultRoundedBorderDecoration; + this.padding = padding ?? EdgeInsets.all(6.0f); + this.placeholder = placeholder; + this.placeholderStyle = placeholderStyle ?? new TextStyle( + fontWeight: FontWeight.w300, + color: CupertinoTextFieldUtils._kInactiveTextColor + ); + this.prefix = prefix; + this.prefixMode = prefixMode; + this.suffix = suffix; + this.suffixMode = suffixMode; + this.clearButtonMode = clearButtonMode; + this.textInputAction = textInputAction; + this.textCapitalization = textCapitalization; + this.style = style; + this.strutStyle = strutStyle; + this.textAlign = textAlign; + this.autofocus = autofocus; + this.obscureText = obscureText; + this.autocorrect = autocorrect; + this.maxLines = maxLines; + this.minLines = minLines; + this.expands = expands; + this.maxLength = maxLength; + this.maxLengthEnforced = maxLengthEnforced; + this.onChanged = onChanged; + this.onEditingComplete = onEditingComplete; + this.onSubmitted = onSubmitted; + this.inputFormatters = inputFormatters; + this.enabled = enabled; + this.cursorWidth = cursorWidth; + this.cursorRadius = cursorRadius ?? Radius.circular(2.0f); + this.cursorColor = cursorColor; + this.keyboardAppearance = keyboardAppearance; + this.scrollPadding = scrollPadding ?? EdgeInsets.all(20.0f); + this.dragStartBehavior = dragStartBehavior; + this.scrollPhysics = scrollPhysics; + this.keyboardType = keyboardType ?? (maxLines == 1 ? TextInputType.text : TextInputType.multiline); + } + + public readonly TextEditingController controller; + + public readonly FocusNode focusNode; + + public readonly BoxDecoration decoration; + + public readonly EdgeInsets padding; + + public readonly string placeholder; + + public readonly TextStyle placeholderStyle; + + public readonly Widget prefix; + + public readonly OverlayVisibilityMode prefixMode; + + public readonly Widget suffix; + + public readonly OverlayVisibilityMode suffixMode; + + public readonly OverlayVisibilityMode clearButtonMode; + + public readonly TextInputType keyboardType; + + public readonly TextInputAction? textInputAction; + + public readonly TextCapitalization textCapitalization; + + public readonly TextStyle style; + + public readonly StrutStyle strutStyle; + + public readonly TextAlign textAlign; + + public readonly bool autofocus; + + public readonly bool obscureText; + + public readonly bool autocorrect; + + public readonly int? maxLines; + + public readonly int? minLines; + + public readonly bool expands; + + public readonly int? maxLength; + + public readonly bool maxLengthEnforced; + + public readonly ValueChanged onChanged; + + public readonly VoidCallback onEditingComplete; + + public readonly ValueChanged onSubmitted; + + public readonly List inputFormatters; + + public readonly bool? enabled; + + public readonly float cursorWidth; + + public readonly Radius cursorRadius; + + public readonly Color cursorColor; + + public readonly Brightness? keyboardAppearance; + + public readonly EdgeInsets scrollPadding; + + public readonly DragStartBehavior dragStartBehavior; + + public readonly ScrollPhysics scrollPhysics; + + public override State createState() { + return new _CupertinoTextFieldState(); + } + + public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { + base.debugFillProperties(properties); + + properties.add( + new DiagnosticsProperty("controller", this.controller, defaultValue: null)); + properties.add(new DiagnosticsProperty("focusNode", this.focusNode, defaultValue: null)); + properties.add(new DiagnosticsProperty("decoration", this.decoration)); + properties.add(new DiagnosticsProperty("padding", this.padding)); + properties.add(new StringProperty("placeholder", this.placeholder)); + properties.add(new DiagnosticsProperty("placeholderStyle", this.placeholderStyle)); + properties.add(new DiagnosticsProperty("prefix", + this.prefix == null ? OverlayVisibilityMode.never : this.prefixMode)); + properties.add(new DiagnosticsProperty("suffix", + this.suffix == null ? OverlayVisibilityMode.never : this.suffixMode)); + properties.add(new DiagnosticsProperty("clearButtonMode", this.clearButtonMode)); + properties.add(new DiagnosticsProperty("keyboardType", this.keyboardType, + defaultValue: TextInputType.text)); + properties.add(new DiagnosticsProperty("style", this.style, defaultValue: null)); + properties.add(new DiagnosticsProperty("autofocus", this.autofocus, defaultValue: false)); + properties.add(new DiagnosticsProperty("obscureText", this.obscureText, defaultValue: false)); + properties.add(new DiagnosticsProperty("autocorrect", this.autocorrect, defaultValue: false)); + properties.add(new IntProperty("maxLines", this.maxLines, defaultValue: 1)); + properties.add(new IntProperty("minLines", this.minLines, defaultValue: null)); + properties.add(new DiagnosticsProperty("expands", this.expands, defaultValue: false)); + properties.add(new IntProperty("maxLength", this.maxLength, defaultValue: null)); + properties.add(new FlagProperty("maxLengthEnforced", value: this.maxLengthEnforced, + ifTrue: "max length enforced")); + properties.add(new DiagnosticsProperty("cursorColor", this.cursorColor, defaultValue: null)); + properties.add( + new DiagnosticsProperty("scrollPhysics", this.scrollPhysics, defaultValue: null)); + } + } + + class _CupertinoTextFieldState : AutomaticKeepAliveClientMixin { + GlobalKey _editableTextKey = GlobalKey.key(); + + TextEditingController _controller; + + TextEditingController _effectiveController { + get { return this.widget.controller ?? this._controller; } + } + + FocusNode _focusNode; + + FocusNode _effectiveFocusNode { + get { return this.widget.focusNode ?? this._focusNode ?? (this._focusNode = new FocusNode()); } + } + + public override void initState() { + base.initState(); + if (this.widget.controller == null) { + this._controller = new TextEditingController(); + this._controller.addListener(this.updateKeepAlive); + } + } + + public override void didUpdateWidget(StatefulWidget oldWidget) { + base.didUpdateWidget(oldWidget); + CupertinoTextField _oldWidget = (CupertinoTextField) oldWidget; + + if (this.widget.controller == null && _oldWidget.controller != null) { + this._controller = TextEditingController.fromValue(_oldWidget.controller.value); + this._controller.addListener(this.updateKeepAlive); + } + else if (this.widget.controller != null && _oldWidget.controller == null) { + this._controller = null; + } + + bool isEnabled = this.widget.enabled ?? true; + bool wasEnabled = _oldWidget.enabled ?? true; + + if (wasEnabled && !isEnabled) { + this._effectiveFocusNode.unfocus(); + } + } + + public override void dispose() { + this._focusNode?.dispose(); + this._controller?.removeListener(this.updateKeepAlive); + base.dispose(); + } + + void _requestKeyboard() { + this._editableTextKey.currentState?.requestKeyboard(); + } + + RenderEditable _renderEditable { + get { return this._editableTextKey.currentState.renderEditable; } + } + + void _handleTapDown(TapDownDetails details) { + this._renderEditable.handleTapDown(details); + } + + + void _handleSingleTapUp(TapUpDetails details) { + this._renderEditable.selectWordEdge(cause: SelectionChangedCause.tap); + this._requestKeyboard(); + } + + void _handleSingleLongTapStart(LongPressStartDetails details) { + this._renderEditable.selectPositionAt( + from: details.globalPosition, + cause: SelectionChangedCause.longPress + ); + } + + void _handleSingleLongTapMoveUpdate(LongPressMoveUpdateDetails details) { + this._renderEditable.selectPositionAt( + from: details.globalPosition, + cause: SelectionChangedCause.longPress + ); + } + + void _handleSingleLongTapEnd(LongPressEndDetails details) { + this._editableTextKey.currentState.showToolbar(); + } + + void _handleDoubleTapDown(TapDownDetails details) { + this._renderEditable.selectWord(cause: SelectionChangedCause.tap); + this._editableTextKey.currentState.showToolbar(); + } + + void _handleMouseDragSelectionStart(DragStartDetails details) { + this._renderEditable.selectPositionAt( + from: details.globalPosition, + cause: SelectionChangedCause.drag + ); + } + + void _handleMouseDragSelectionUpdate( + DragStartDetails startDetails, + DragUpdateDetails updateDetails + ) { + this._renderEditable.selectPositionAt( + from: startDetails.globalPosition, + to: updateDetails.globalPosition, + cause: SelectionChangedCause.drag + ); + } + + void _handleMouseDragSelectionEnd(DragEndDetails details) { + this._requestKeyboard(); + } + + void _handleSelectionChanged(TextSelection selection, SelectionChangedCause cause) { + if (cause == SelectionChangedCause.longPress) { + this._editableTextKey.currentState?.bringIntoView(selection.basePos); + } + } + + protected override bool wantKeepAlive { + get { return this._controller?.text?.isNotEmpty() == true; } + } + + bool _shouldShowAttachment( + OverlayVisibilityMode attachment, + bool hasText + ) { + switch (attachment) { + case OverlayVisibilityMode.never: + return false; + case OverlayVisibilityMode.always: + return true; + case OverlayVisibilityMode.editing: + return hasText; + case OverlayVisibilityMode.notEditing: + return !hasText; + } + + D.assert(false); + return false; + } + + bool _showPrefixWidget(TextEditingValue text) { + return this.widget.prefix != null && this._shouldShowAttachment( + attachment: this.widget.prefixMode, + hasText: text.text.isNotEmpty() + ); + } + + bool _showSuffixWidget(TextEditingValue text) { + return this.widget.suffix != null && this._shouldShowAttachment( + attachment: this.widget.suffixMode, + hasText: text.text.isNotEmpty() + ); + } + + bool _showClearButton(TextEditingValue text) { + return this._shouldShowAttachment( + attachment: this.widget.clearButtonMode, + hasText: text.text.isNotEmpty() + ); + } + + Widget _addTextDependentAttachments(Widget editableText, TextStyle textStyle, TextStyle placeholderStyle) { + D.assert(editableText != null); + D.assert(textStyle != null); + D.assert(placeholderStyle != null); + + if (this.widget.placeholder == null && + this.widget.clearButtonMode == OverlayVisibilityMode.never && + this.widget.prefix == null && + this.widget.suffix == null) { + return editableText; + } + + return new ValueListenableBuilder( + valueListenable: this._effectiveController, + child: editableText, + builder: (BuildContext context, TextEditingValue text, Widget child) => { + List rowChildren = new List(); + + if (this._showPrefixWidget(text)) { + rowChildren.Add(this.widget.prefix); + } + + List stackChildren = new List(); + if (this.widget.placeholder != null && text.text.isEmpty()) { + stackChildren.Add( + new Padding( + padding: this.widget.padding, + child: new Text( + this.widget.placeholder, + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: placeholderStyle + ) + ) + ); + } + + stackChildren.Add(child); + rowChildren.Add( + new Expanded + (child: new Stack + (children: stackChildren))); + + if (this._showSuffixWidget(text)) { + rowChildren.Add(this.widget.suffix); + } + else if (this._showClearButton(text)) { + rowChildren.Add( + new GestureDetector( + onTap: this.widget.enabled ?? true + ? () => { + bool textChanged = this._effectiveController.text.isNotEmpty(); + this._effectiveController.clear(); + if (this.widget.onChanged != null && textChanged) { + this.widget.onChanged(this._effectiveController.text); + } + } + : (GestureTapCallback) null, + child: new Padding( + padding: EdgeInsets.symmetric(horizontal: 6.0f), + child: new Icon( + CupertinoIcons.clear_thick_circled, + size: 18.0f, + color: CupertinoTextFieldUtils._kInactiveTextColor + ) + ) + ) + ); + } + + return new Row(children: rowChildren); + } + ); + } + + public override Widget build(BuildContext context) { + base.build(context); + TextEditingController controller = this._effectiveController; + List formatters = this.widget.inputFormatters ?? new List(); + bool enabled = this.widget.enabled ?? true; + Offset cursorOffset = + new Offset( + CupertinoTextFieldUtils._iOSHorizontalCursorOffsetPixels / MediaQuery.of(context).devicePixelRatio, + 0); + if (this.widget.maxLength != null && this.widget.maxLengthEnforced) { + formatters.Add(new LengthLimitingTextInputFormatter(this.widget.maxLength)); + } + + CupertinoThemeData themeData = CupertinoTheme.of(context); + TextStyle textStyle = themeData.textTheme.textStyle.merge(this.widget.style); + TextStyle placeholderStyle = textStyle.merge(this.widget.placeholderStyle); + Brightness keyboardAppearance = this.widget.keyboardAppearance ?? themeData.brightness; + Color cursorColor = this.widget.cursorColor ?? themeData.primaryColor; + + Widget paddedEditable = new Padding( + padding: this.widget.padding, + child: new RepaintBoundary( + child: new EditableText( + key: this._editableTextKey, + controller: controller, + focusNode: this._effectiveFocusNode, + keyboardType: this.widget.keyboardType, + textInputAction: this.widget.textInputAction, + textCapitalization: this.widget.textCapitalization, + style: textStyle, + strutStyle: this.widget.strutStyle, + textAlign: this.widget.textAlign, + autofocus: this.widget.autofocus, + obscureText: this.widget.obscureText, + autocorrect: this.widget.autocorrect, + maxLines: this.widget.maxLines, + minLines: this.widget.minLines, + expands: this.widget.expands, + selectionColor: CupertinoTextFieldUtils._kSelectionHighlightColor, + selectionControls: CupertinoTextSelectionUtils.cupertinoTextSelectionControls, + onChanged: this.widget.onChanged, + onSelectionChanged: this._handleSelectionChanged, + onEditingComplete: this.widget.onEditingComplete, + onSubmitted: this.widget.onSubmitted, + inputFormatters: formatters, + rendererIgnoresPointer: true, + cursorWidth: this.widget.cursorWidth, + cursorRadius: this.widget.cursorRadius, + cursorColor: cursorColor, + cursorOpacityAnimates: true, + cursorOffset: cursorOffset, + paintCursorAboveText: true, + backgroundCursorColor: CupertinoColors.inactiveGray, + scrollPadding: this.widget.scrollPadding, + keyboardAppearance: keyboardAppearance, + dragStartBehavior: this.widget.dragStartBehavior, + scrollPhysics: this.widget.scrollPhysics + ) + ) + ); + + return new IgnorePointer( + ignoring: !enabled, + child: new Container( + decoration: this.widget.decoration, + child: new Container( + color: enabled + ? null + : CupertinoTheme.of(context).brightness == Brightness.light + ? CupertinoTextFieldUtils._kDisabledBackground + : CupertinoColors.darkBackgroundGray, + child: new TextSelectionGestureDetector( + onTapDown: this._handleTapDown, + onSingleTapUp: this._handleSingleTapUp, + onSingleLongTapStart: this._handleSingleLongTapStart, + onSingleLongTapMoveUpdate: this._handleSingleLongTapMoveUpdate, + onSingleLongTapEnd: this._handleSingleLongTapEnd, + onDoubleTapDown: this._handleDoubleTapDown, + onDragSelectionStart: this._handleMouseDragSelectionStart, + onDragSelectionUpdate: this._handleMouseDragSelectionUpdate, + onDragSelectionEnd: this._handleMouseDragSelectionEnd, + behavior: HitTestBehavior.translucent, + child: this._addTextDependentAttachments(paddedEditable, textStyle, placeholderStyle) + ) + ) + ) + ); + } + } +} \ No newline at end of file diff --git a/Runtime/cupertino/text_field.cs.meta b/Runtime/cupertino/text_field.cs.meta new file mode 100644 index 00000000..ebc2f1ec --- /dev/null +++ b/Runtime/cupertino/text_field.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a300f388a142347fab65f219e2843698 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/cupertino/text_selection.cs b/Runtime/cupertino/text_selection.cs new file mode 100644 index 00000000..408a84b8 --- /dev/null +++ b/Runtime/cupertino/text_selection.cs @@ -0,0 +1,315 @@ +using System.Collections.Generic; +using Unity.UIWidgets.foundation; +using Unity.UIWidgets.painting; +using Unity.UIWidgets.rendering; +using Unity.UIWidgets.service; +using Unity.UIWidgets.ui; +using Unity.UIWidgets.widgets; +using UnityEngine; +using Canvas = Unity.UIWidgets.ui.Canvas; +using Color = Unity.UIWidgets.ui.Color; +using Rect = Unity.UIWidgets.ui.Rect; +using TextStyle = Unity.UIWidgets.painting.TextStyle; +using Transform = Unity.UIWidgets.widgets.Transform; + +namespace Unity.UIWidgets.cupertino { + public static class CupertinoTextSelectionUtils { + public static readonly TextSelectionControls cupertinoTextSelectionControls = new _CupertinoTextSelectionControls(); + + public const float _kHandlesPadding = 18.0f; + + public const float _kToolbarScreenPadding = 8.0f; + + public const float _kToolbarHeight = 36.0f; + + public static readonly Color _kToolbarBackgroundColor = new Color(0xFF2E2E2E); + + public static readonly Color _kToolbarDividerColor = new Color(0xFFB9B9B9); + + public static readonly Color _kHandlesColor = new Color(0xFF136FE0); + + public static readonly Size _kSelectionOffset = new Size(20.0f, 30.0f); + + public static readonly Size _kToolbarTriangleSize = new Size(18.0f, 9.0f); + + public static readonly EdgeInsets _kToolbarButtonPadding = + EdgeInsets.symmetric(vertical: 10.0f, horizontal: 18.0f); + + public static readonly BorderRadius _kToolbarBorderRadius = BorderRadius.all(Radius.circular(7.5f)); + + public static readonly TextStyle _kToolbarButtonFontStyle = new TextStyle( + fontSize: 14.0f, + letterSpacing: -0.11f, + fontWeight: FontWeight.w300, + color: CupertinoColors.white + ); + } + + class _TextSelectionToolbarNotchPainter : AbstractCustomPainter { + public override void paint(Canvas canvas, Size size) { + Paint paint = new Paint(); + paint.color = CupertinoTextSelectionUtils._kToolbarBackgroundColor; + paint.style = PaintingStyle.fill; + + Path triangle = new Path(); + triangle.lineTo(CupertinoTextSelectionUtils._kToolbarTriangleSize.width / 2, 0.0f); + triangle.lineTo(0.0f, CupertinoTextSelectionUtils._kToolbarTriangleSize.height); + triangle.lineTo(-(CupertinoTextSelectionUtils._kToolbarTriangleSize.width / 2), 0.0f); + triangle.close(); + canvas.drawPath(triangle, paint); + } + + public override bool shouldRepaint(CustomPainter oldPainter) { + return false; + } + } + + class _TextSelectionToolbar : StatelessWidget { + public _TextSelectionToolbar( + Key key = null, + VoidCallback handleCut = null, + VoidCallback handleCopy = null, + VoidCallback handlePaste = null, + VoidCallback handleSelectAll = null + ) : base(key: key) { + this.handleCut = handleCut; + this.handleCopy = handleCopy; + this.handlePaste = handlePaste; + this.handleSelectAll = handleSelectAll; + } + + readonly VoidCallback handleCut; + + readonly VoidCallback handleCopy; + + readonly VoidCallback handlePaste; + + readonly VoidCallback handleSelectAll; + + + public override Widget build(BuildContext context) { + List items = new List(); + Widget onePhysicalPixelVerticalDivider = + new SizedBox(width: 1.0f / MediaQuery.of(context).devicePixelRatio); + CupertinoLocalizations localizations = CupertinoLocalizations.of(context); + + if (this.handleCut != null) { + items.Add(this._buildToolbarButton(localizations.cutButtonLabel, this.handleCut)); + } + + if (this.handleCopy != null) { + if (items.isNotEmpty()) { + items.Add(onePhysicalPixelVerticalDivider); + } + + items.Add(this._buildToolbarButton(localizations.copyButtonLabel, this.handleCopy)); + } + + if (this.handlePaste != null) { + if (items.isNotEmpty()) { + items.Add(onePhysicalPixelVerticalDivider); + } + + items.Add(this._buildToolbarButton(localizations.pasteButtonLabel, this.handlePaste)); + } + + if (this.handleSelectAll != null) { + if (items.isNotEmpty()) { + items.Add(onePhysicalPixelVerticalDivider); + } + + items.Add(this._buildToolbarButton(localizations.selectAllButtonLabel, this.handleSelectAll)); + } + + Widget triangle = SizedBox.fromSize( + size: CupertinoTextSelectionUtils._kToolbarTriangleSize, + child: new CustomPaint( + painter: new _TextSelectionToolbarNotchPainter() + ) + ); + + return new Column( + mainAxisSize: MainAxisSize.min, + children: new List { + new ClipRRect( + borderRadius: CupertinoTextSelectionUtils._kToolbarBorderRadius, + child: new DecoratedBox( + decoration: new BoxDecoration( + color: CupertinoTextSelectionUtils._kToolbarDividerColor, + borderRadius: CupertinoTextSelectionUtils._kToolbarBorderRadius, + border: Border.all(color: CupertinoTextSelectionUtils._kToolbarBackgroundColor, + width: 0) + ), + child: new Row(mainAxisSize: MainAxisSize.min, children: items) + ) + ), + triangle, + new Padding(padding: EdgeInsets.only(bottom: 10.0f)) + } + ); + } + + CupertinoButton _buildToolbarButton(string text, VoidCallback onPressed) { + return new CupertinoButton( + child: new Text(text, style: CupertinoTextSelectionUtils._kToolbarButtonFontStyle), + color: CupertinoTextSelectionUtils._kToolbarBackgroundColor, + minSize: CupertinoTextSelectionUtils._kToolbarHeight, + padding: CupertinoTextSelectionUtils._kToolbarButtonPadding, + borderRadius: null, + pressedOpacity: 0.7f, + onPressed: onPressed + ); + } + } + + class _TextSelectionToolbarLayout : SingleChildLayoutDelegate { + public _TextSelectionToolbarLayout( + Size screenSize, + Rect globalEditableRegion, + Offset position) { + this.screenSize = screenSize; + this.globalEditableRegion = globalEditableRegion; + this.position = position; + } + + readonly Size screenSize; + + readonly Rect globalEditableRegion; + + readonly Offset position; + + public override BoxConstraints getConstraintsForChild(BoxConstraints constraints) { + return constraints.loosen(); + } + + public override Offset getPositionForChild(Size size, Size childSize) { + Offset globalPosition = this.globalEditableRegion.topLeft + this.position; + + float x = globalPosition.dx - childSize.width / 2.0f; + float y = globalPosition.dy - childSize.height; + + if (x < CupertinoTextSelectionUtils._kToolbarScreenPadding) { + x = CupertinoTextSelectionUtils._kToolbarScreenPadding; + } + else if (x + childSize.width > this.screenSize.width - CupertinoTextSelectionUtils._kToolbarScreenPadding) { + x = this.screenSize.width - childSize.width - CupertinoTextSelectionUtils._kToolbarScreenPadding; + } + + if (y < CupertinoTextSelectionUtils._kToolbarScreenPadding) { + y = CupertinoTextSelectionUtils._kToolbarScreenPadding; + } + else if (y + childSize.height > + this.screenSize.height - CupertinoTextSelectionUtils._kToolbarScreenPadding) { + y = this.screenSize.height - childSize.height - CupertinoTextSelectionUtils._kToolbarScreenPadding; + } + + return new Offset(x, y); + } + + public override bool shouldRelayout(SingleChildLayoutDelegate oldDelegate) { + _TextSelectionToolbarLayout _oldDelegate = (_TextSelectionToolbarLayout) oldDelegate; + return this.screenSize != _oldDelegate.screenSize + || this.globalEditableRegion != _oldDelegate.globalEditableRegion + || this.position != _oldDelegate.position; + } + } + + class _TextSelectionHandlePainter : AbstractCustomPainter { + public _TextSelectionHandlePainter(Offset origin) { + this.origin = origin; + } + + readonly Offset origin; + + + public override void paint(Canvas canvas, Size size) { + Paint paint = new Paint(); + paint.color = CupertinoTextSelectionUtils._kHandlesColor; + paint.strokeWidth = 2.0f; + + canvas.drawCircle(this.origin.translate(0.0f, 4.0f), 5.5f, paint); + canvas.drawLine( + this.origin, + this.origin.translate( + 0.0f, + -(size.height - 2.0f * CupertinoTextSelectionUtils._kHandlesPadding) + ), + paint + ); + } + + public override bool shouldRepaint(CustomPainter oldPainter) { + _TextSelectionHandlePainter _oldPainter = (_TextSelectionHandlePainter) oldPainter; + return this.origin != _oldPainter.origin; + } + } + + class _CupertinoTextSelectionControls : TextSelectionControls { + public override Size handleSize { + get { return CupertinoTextSelectionUtils._kSelectionOffset; } + } + + public override Widget buildToolbar(BuildContext context, Rect globalEditableRegion, Offset position, + TextSelectionDelegate del) { + D.assert(WidgetsD.debugCheckHasMediaQuery(context)); + return new ConstrainedBox( + constraints: BoxConstraints.tight(globalEditableRegion.size), + child: new CustomSingleChildLayout( + layoutDelegate: new _TextSelectionToolbarLayout( + MediaQuery.of(context).size, + globalEditableRegion, + position + ), + child: new _TextSelectionToolbar( + handleCut: this.canCut(del) ? () => this.handleCut(del) : (VoidCallback) null, + handleCopy: this.canCopy(del) ? () => this.handleCopy(del) : (VoidCallback) null, + handlePaste: this.canPaste(del) ? () => this.handlePaste(del) : (VoidCallback) null, + handleSelectAll: this.canSelectAll(del) ? () => this.handleSelectAll(del) : (VoidCallback) null + ) + ) + ); + } + + + public override Widget buildHandle(BuildContext context, TextSelectionHandleType type, float textLineHeight) { + Size desiredSize = new Size( + 2.0f * CupertinoTextSelectionUtils._kHandlesPadding, + textLineHeight + 2.0f * CupertinoTextSelectionUtils._kHandlesPadding + ); + + Widget handle = SizedBox.fromSize( + size: desiredSize, + child: new CustomPaint( + painter: new _TextSelectionHandlePainter( + origin: new Offset(CupertinoTextSelectionUtils._kHandlesPadding, + textLineHeight + CupertinoTextSelectionUtils._kHandlesPadding) + ) + ) + ); + + switch (type) { + case TextSelectionHandleType.left: + Matrix3 matrix = Matrix3.makeRotate(Mathf.PI); + matrix.preTranslate(-CupertinoTextSelectionUtils._kHandlesPadding, + -CupertinoTextSelectionUtils._kHandlesPadding); + + return new Transform( + transform: matrix, + child: handle + ); + case TextSelectionHandleType.right: + return new Transform( + transform: Matrix3.makeTrans( + -CupertinoTextSelectionUtils._kHandlesPadding, + -(textLineHeight + CupertinoTextSelectionUtils._kHandlesPadding) + ), + child: handle + ); + case TextSelectionHandleType.collapsed: + return new Container(); + } + + return null; + } + } +} \ No newline at end of file diff --git a/Runtime/cupertino/text_selection.cs.meta b/Runtime/cupertino/text_selection.cs.meta new file mode 100644 index 00000000..51d3e6dd --- /dev/null +++ b/Runtime/cupertino/text_selection.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2afc9187fdd8b4f7abbb404a4cb3cf71 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/cupertino/text_theme.cs b/Runtime/cupertino/text_theme.cs new file mode 100644 index 00000000..146215d8 --- /dev/null +++ b/Runtime/cupertino/text_theme.cs @@ -0,0 +1,190 @@ +using Unity.UIWidgets.foundation; +using Unity.UIWidgets.service; +using Unity.UIWidgets.ui; +using TextStyle = Unity.UIWidgets.painting.TextStyle; + +namespace Unity.UIWidgets.cupertino { + static class CupertinoTextThemeDataUtils { + public static readonly TextStyle _kDefaultLightTextStyle = new TextStyle( + inherit: false, + fontFamily: ".SF Pro Text", + fontSize: 17.0f, + letterSpacing: -0.41f, + color: CupertinoColors.black, + decoration: TextDecoration.none + ); + + public static readonly TextStyle _kDefaultDarkTextStyle = new TextStyle( + inherit: false, + fontFamily: ".SF Pro Text", + fontSize: 17.0f, + letterSpacing: -0.41f, + color: CupertinoColors.white, + decoration: TextDecoration.none + ); + + public static readonly TextStyle _kDefaultActionTextStyle = new TextStyle( + inherit: false, + fontFamily: ".SF Pro Text", + fontSize: 17.0f, + letterSpacing: -0.41f, + color: CupertinoColors.activeBlue, + decoration: TextDecoration.none + ); + + public static readonly TextStyle _kDefaultTabLabelTextStyle = new TextStyle( + inherit: false, + fontFamily: ".SF Pro Text", + fontSize: 10.0f, + letterSpacing: -0.24f, + color: CupertinoColors.inactiveGray + ); + + public static readonly TextStyle _kDefaultMiddleTitleLightTextStyle = new TextStyle( + inherit: false, + fontFamily: ".SF Pro Text", + fontSize: 17.0f, + fontWeight: FontWeight.w600, + letterSpacing: -0.41f, + color: CupertinoColors.black + ); + + public static readonly TextStyle _kDefaultMiddleTitleDarkTextStyle = new TextStyle( + inherit: false, + fontFamily: ".SF Pro Text", + fontSize: 17.0f, + fontWeight: FontWeight.w600, + letterSpacing: -0.41f, + color: CupertinoColors.white + ); + + public static readonly TextStyle _kDefaultLargeTitleLightTextStyle = new TextStyle( + inherit: false, + fontFamily: ".SF Pro Display", + fontSize: 34.0f, + fontWeight: FontWeight.w700, + letterSpacing: 0.41f, + color: CupertinoColors.black + ); + + public static readonly TextStyle _kDefaultLargeTitleDarkTextStyle = new TextStyle( + inherit: false, + fontFamily: ".SF Pro Display", + fontSize: 34.0f, + fontWeight: FontWeight.w700, + letterSpacing: 0.41f, + color: CupertinoColors.white + ); + } + + + public class CupertinoTextThemeData : Diagnosticable { + public CupertinoTextThemeData( + Color primaryColor = null, + Brightness? brightness = null, + TextStyle textStyle = null, + TextStyle actionTextStyle = null, + TextStyle tabLabelTextStyle = null, + TextStyle navTitleTextStyle = null, + TextStyle navLargeTitleTextStyle = null, + TextStyle navActionTextStyle = null + ) { + this._primaryColor = primaryColor ?? CupertinoColors.activeBlue; + this._brightness = brightness; + this._textStyle = textStyle; + this._actionTextStyle = actionTextStyle; + this._tabLabelTextStyle = tabLabelTextStyle; + this._navTitleTextStyle = navTitleTextStyle; + this._navLargeTitleTextStyle = navLargeTitleTextStyle; + this._navActionTextStyle = navActionTextStyle; + } + + readonly Color _primaryColor; + readonly Brightness? _brightness; + + bool _isLight { + get { return this._brightness != Brightness.dark; } + } + + readonly TextStyle _textStyle; + + public TextStyle textStyle { + get { + return this._textStyle ?? (this._isLight + ? CupertinoTextThemeDataUtils._kDefaultLightTextStyle + : CupertinoTextThemeDataUtils._kDefaultDarkTextStyle); + } + } + + readonly TextStyle _actionTextStyle; + + public TextStyle actionTextStyle { + get { + return this._actionTextStyle ?? CupertinoTextThemeDataUtils._kDefaultActionTextStyle.copyWith( + color: this._primaryColor + ); + } + } + + readonly TextStyle _tabLabelTextStyle; + + public TextStyle tabLabelTextStyle { + get { return this._tabLabelTextStyle ?? CupertinoTextThemeDataUtils._kDefaultTabLabelTextStyle; } + } + + readonly TextStyle _navTitleTextStyle; + + public TextStyle navTitleTextStyle { + get { + return this._navTitleTextStyle ?? + (this._isLight + ? CupertinoTextThemeDataUtils._kDefaultMiddleTitleLightTextStyle + : CupertinoTextThemeDataUtils._kDefaultMiddleTitleDarkTextStyle); + } + } + + readonly TextStyle _navLargeTitleTextStyle; + + /// Typography of large titles in sliver navigation bars. + public TextStyle navLargeTitleTextStyle { + get { + return this._navLargeTitleTextStyle ?? + (this._isLight + ? CupertinoTextThemeDataUtils._kDefaultLargeTitleLightTextStyle + : CupertinoTextThemeDataUtils._kDefaultLargeTitleDarkTextStyle); + } + } + + readonly TextStyle _navActionTextStyle; + + public TextStyle navActionTextStyle { + get { + return this._navActionTextStyle ?? CupertinoTextThemeDataUtils._kDefaultActionTextStyle.copyWith( + color: this._primaryColor + ); + } + } + + public CupertinoTextThemeData copyWith( + Color primaryColor, + Brightness? brightness, + TextStyle textStyle, + TextStyle actionTextStyle, + TextStyle tabLabelTextStyle, + TextStyle navTitleTextStyle, + TextStyle navLargeTitleTextStyle, + TextStyle navActionTextStyle + ) { + return new CupertinoTextThemeData( + primaryColor: primaryColor ?? this._primaryColor, + brightness: brightness ?? this._brightness, + textStyle: textStyle ?? this._textStyle, + actionTextStyle: actionTextStyle ?? this._actionTextStyle, + tabLabelTextStyle: tabLabelTextStyle ?? this._tabLabelTextStyle, + navTitleTextStyle: navTitleTextStyle ?? this._navTitleTextStyle, + navLargeTitleTextStyle: navLargeTitleTextStyle ?? this._navLargeTitleTextStyle, + navActionTextStyle: navActionTextStyle ?? this._navActionTextStyle + ); + } + } +} \ No newline at end of file diff --git a/Runtime/cupertino/text_theme.cs.meta b/Runtime/cupertino/text_theme.cs.meta new file mode 100644 index 00000000..9665e8a5 --- /dev/null +++ b/Runtime/cupertino/text_theme.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: df4b7fd7cba7a412f9904c599a8e2ae5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/cupertino/theme.cs b/Runtime/cupertino/theme.cs new file mode 100644 index 00000000..5c9ca65d --- /dev/null +++ b/Runtime/cupertino/theme.cs @@ -0,0 +1,241 @@ +using Unity.UIWidgets.foundation; +using Unity.UIWidgets.service; +using Unity.UIWidgets.ui; +using Unity.UIWidgets.widgets; + +namespace Unity.UIWidgets.cupertino { + static class CupertinoThemeDataUtils { + public static readonly Color _kDefaultBarLightBackgroundColor = new Color(0xCCF8F8F8); + public static readonly Color _kDefaultBarDarkBackgroundColor = new Color(0xB7212121); + } + + public class CupertinoTheme : StatelessWidget { + public CupertinoTheme( + CupertinoThemeData data, + Widget child, + Key key = null + ) : base(key: key) { + D.assert(child != null); + D.assert(data != null); + this.data = data; + this.child = child; + } + + public readonly CupertinoThemeData data; + + public readonly Widget child; + + public static CupertinoThemeData of(BuildContext context) { + _InheritedCupertinoTheme inheritedTheme = + (_InheritedCupertinoTheme) context.inheritFromWidgetOfExactType(typeof(_InheritedCupertinoTheme)); + return inheritedTheme?.theme?.data ?? new CupertinoThemeData(); + } + + + public override Widget build(BuildContext context) { + return new _InheritedCupertinoTheme( + theme: this, + child: new IconTheme( + data: new IconThemeData(color: this.data.primaryColor), + child: this.child + ) + ); + } + } + + class _InheritedCupertinoTheme : InheritedWidget { + public _InheritedCupertinoTheme( + CupertinoTheme theme, + Widget child, + Key key = null + ) + : base(key: key, child: child) { + D.assert(theme != null); + this.theme = theme; + } + + public readonly CupertinoTheme theme; + + public override bool updateShouldNotify(InheritedWidget old) { + return this.theme.data != ((_InheritedCupertinoTheme) old).theme.data; + } + } + + public class CupertinoThemeData : Diagnosticable { + public CupertinoThemeData( + Brightness? brightness = null, + Color primaryColor = null, + Color primaryContrastingColor = null, + CupertinoTextThemeData textTheme = null, + Color barBackgroundColor = null, + Color scaffoldBackgroundColor = null + ) { + this._brightness = brightness; + this._primaryColor = primaryColor; + this._primaryContrastingColor = primaryContrastingColor; + this._textTheme = textTheme; + this._barBackgroundColor = barBackgroundColor; + this._scaffoldBackgroundColor = scaffoldBackgroundColor; + } + + public static CupertinoThemeData raw( + Brightness? brightness = null, + Color primaryColor = null, + Color primaryContrastingColor = null, + CupertinoTextThemeData textTheme = null, + Color barBackgroundColor = null, + Color scaffoldBackgroundColor = null + ) { + D.assert(brightness != null); + D.assert(primaryColor != null); + D.assert(primaryContrastingColor != null); + D.assert(textTheme != null); + D.assert(barBackgroundColor != null); + D.assert(scaffoldBackgroundColor != null); + return new CupertinoThemeData( + brightness: brightness, + primaryColor: primaryColor, + primaryContrastingColor: primaryContrastingColor, + textTheme: textTheme, + barBackgroundColor: barBackgroundColor, + scaffoldBackgroundColor: scaffoldBackgroundColor + ); + } + + bool _isLight { + get { return this.brightness == Brightness.light; } + } + + public Brightness brightness { + get { return this._brightness ?? Brightness.light; } + } + + readonly Brightness? _brightness; + + public Color primaryColor { + get { + return this._primaryColor ?? + (this._isLight ? CupertinoColors.activeBlue : CupertinoColors.activeOrange); + } + } + + readonly Color _primaryColor; + + public Color primaryContrastingColor { + get { + return this._primaryContrastingColor ?? + (this._isLight ? CupertinoColors.white : CupertinoColors.black); + } + } + + readonly Color _primaryContrastingColor; + + public CupertinoTextThemeData textTheme { + get { + return this._textTheme ?? new CupertinoTextThemeData( + brightness: this.brightness, + primaryColor: this.primaryColor + ); + } + } + + readonly CupertinoTextThemeData _textTheme; + + public Color barBackgroundColor { + get { + return this._barBackgroundColor ?? + (this._isLight + ? CupertinoThemeDataUtils._kDefaultBarLightBackgroundColor + : CupertinoThemeDataUtils._kDefaultBarDarkBackgroundColor); + } + } + + readonly Color _barBackgroundColor; + + public Color scaffoldBackgroundColor { + get { + return this._scaffoldBackgroundColor ?? + (this._isLight ? CupertinoColors.white : CupertinoColors.black); + } + } + + readonly Color _scaffoldBackgroundColor; + + public CupertinoThemeData noDefault() { + return new _NoDefaultCupertinoThemeData( + this._brightness, + this._primaryColor, + this._primaryContrastingColor, + this._textTheme, + this._barBackgroundColor, + this._scaffoldBackgroundColor + ); + } + + public CupertinoThemeData copyWith( + Brightness? brightness = null, + Color primaryColor = null, + Color primaryContrastingColor = null, + CupertinoTextThemeData textTheme = null, + Color barBackgroundColor = null, + Color scaffoldBackgroundColor = null + ) { + return new CupertinoThemeData( + brightness: brightness ?? this._brightness, + primaryColor: primaryColor ?? this._primaryColor, + primaryContrastingColor: primaryContrastingColor ?? this._primaryContrastingColor, + textTheme: textTheme ?? this._textTheme, + barBackgroundColor: barBackgroundColor ?? this._barBackgroundColor, + scaffoldBackgroundColor: scaffoldBackgroundColor ?? this._scaffoldBackgroundColor + ); + } + + public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { + base.debugFillProperties(properties); + CupertinoThemeData defaultData = new CupertinoThemeData(); + properties.add( + new EnumProperty("brightness", this.brightness, defaultValue: defaultData.brightness)); + properties.add(new DiagnosticsProperty("primaryColor", this.primaryColor, + defaultValue: defaultData.primaryColor)); + properties.add(new DiagnosticsProperty("primaryContrastingColor", this.primaryContrastingColor, + defaultValue: defaultData.primaryContrastingColor)); + properties.add( + new DiagnosticsProperty("textTheme", this.textTheme, + defaultValue: defaultData.textTheme)); + properties.add(new DiagnosticsProperty("barBackgroundColor", this.barBackgroundColor, + defaultValue: defaultData.barBackgroundColor)); + properties.add(new DiagnosticsProperty("scaffoldBackgroundColor", this.scaffoldBackgroundColor, + defaultValue: defaultData.scaffoldBackgroundColor)); + } + } + + class _NoDefaultCupertinoThemeData : CupertinoThemeData { + public _NoDefaultCupertinoThemeData( + Brightness? brightness, + Color primaryColor, + Color primaryContrastingColor, + CupertinoTextThemeData textTheme, + Color barBackgroundColor, + Color scaffoldBackgroundColor + ) { + this.brightness = brightness; + this.primaryColor = primaryColor; + this.primaryContrastingColor = primaryContrastingColor; + this.textTheme = textTheme; + this.barBackgroundColor = barBackgroundColor; + this.scaffoldBackgroundColor = scaffoldBackgroundColor; + } + + public new readonly Brightness? brightness; + + public new readonly Color primaryColor; + + public new readonly Color primaryContrastingColor; + + public new readonly CupertinoTextThemeData textTheme; + + public new readonly Color barBackgroundColor; + + public new readonly Color scaffoldBackgroundColor; + } +} \ No newline at end of file diff --git a/Runtime/cupertino/theme.cs.meta b/Runtime/cupertino/theme.cs.meta new file mode 100644 index 00000000..a2448bea --- /dev/null +++ b/Runtime/cupertino/theme.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3ecd7071d542a4449a9f653bde26fbd9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/cupertino/thumb_painter.cs b/Runtime/cupertino/thumb_painter.cs new file mode 100644 index 00000000..c25858ca --- /dev/null +++ b/Runtime/cupertino/thumb_painter.cs @@ -0,0 +1,42 @@ +using Unity.UIWidgets.painting; +using Unity.UIWidgets.ui; + +namespace Unity.UIWidgets.cupertino { + public class CupertinoThumbPainter { + public CupertinoThumbPainter( + Color color = null, + Color shadowColor = null + ) { + this._shadowPaint = new BoxShadow( + color: shadowColor, + blurRadius: 1.0f + ).toPaint(); + + this.color = color ?? CupertinoColors.white; + this.shadowColor = shadowColor ?? new Color(0x2C000000); + } + + public readonly Color color; + + public readonly Color shadowColor; + + public readonly Paint _shadowPaint; + + public const float radius = 14.0f; + + public const float extension = 7.0f; + + public void paint(Canvas canvas, Rect rect) { + RRect rrect = RRect.fromRectAndRadius( + rect, + Radius.circular(rect.shortestSide / 2.0f) + ); + + canvas.drawRRect(rrect, this._shadowPaint); + canvas.drawRRect(rrect.shift(new Offset(0.0f, 3.0f)), this._shadowPaint); + var _paint = new Paint(); + _paint.color = this.color; + canvas.drawRRect(rrect, _paint); + } + } +} \ No newline at end of file diff --git a/Runtime/cupertino/thumb_painter.cs.meta b/Runtime/cupertino/thumb_painter.cs.meta new file mode 100644 index 00000000..34be9cef --- /dev/null +++ b/Runtime/cupertino/thumb_painter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 47bbdd4359daa489bb16dfd37b505cb7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/editor/editor_window.cs b/Runtime/editor/editor_window.cs index 8aaca14c..94079dbf 100644 --- a/Runtime/editor/editor_window.cs +++ b/Runtime/editor/editor_window.cs @@ -1,6 +1,7 @@ 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; @@ -14,10 +15,33 @@ namespace Unity.UIWidgets.editor { #if UNITY_EDITOR public abstract class UIWidgetsEditorWindow : EditorWindow, WindowHost { WindowAdapter _windowAdapter; - + + static readonly List _activeEditorWindows = new List(); + + [InitializeOnLoadMethod] + static void _OnBaseEditorWindowLoaded() + { + EditorApplication.quitting += () => + { + foreach (var editorWindow in _activeEditorWindows) { + editorWindow.OnDisable(); + } + + _activeEditorWindows.Clear(); + }; + } + public UIWidgetsEditorWindow() { this.wantsMouseMove = true; this.wantsMouseEnterLeaveWindow = true; + + _activeEditorWindows.Add(this); + } + + void OnDestroy() { + if (_activeEditorWindows.Contains(this)) { + _activeEditorWindows.Remove(this); + } } protected virtual void OnEnable() { @@ -91,7 +115,7 @@ public override GUIContent titleContent { protected override float queryDevicePixelRatio() { return EditorGUIUtility.pixelsPerPoint; } - + protected override int queryAntiAliasing() { return defaultAntiAliasing; } @@ -275,7 +299,7 @@ protected bool displayMetricsChanged() { if (this._devicePixelRatio != this.queryDevicePixelRatio()) { return true; } - + if (this._antiAliasing != this.queryAntiAliasing()) { return true; } @@ -363,7 +387,7 @@ void _doOnGUI(Event evt) { timeStamp: Timer.timespanSinceStartup, change: PointerChange.down, kind: PointerDeviceKind.mouse, - device: evt.button, + device: InputUtils.getMouseButtonKey(evt.button), physicalX: evt.mousePosition.x * this._devicePixelRatio, physicalY: evt.mousePosition.y * this._devicePixelRatio ); @@ -373,7 +397,7 @@ void _doOnGUI(Event evt) { timeStamp: Timer.timespanSinceStartup, change: PointerChange.up, kind: PointerDeviceKind.mouse, - device: evt.button, + device: InputUtils.getMouseButtonKey(evt.button), physicalX: evt.mousePosition.x * this._devicePixelRatio, physicalY: evt.mousePosition.y * this._devicePixelRatio ); @@ -383,7 +407,7 @@ void _doOnGUI(Event evt) { timeStamp: Timer.timespanSinceStartup, change: PointerChange.move, kind: PointerDeviceKind.mouse, - device: evt.button, + device: InputUtils.getMouseButtonKey(evt.button), physicalX: evt.mousePosition.x * this._devicePixelRatio, physicalY: evt.mousePosition.y * this._devicePixelRatio ); @@ -393,7 +417,7 @@ void _doOnGUI(Event evt) { timeStamp: Timer.timespanSinceStartup, change: PointerChange.hover, kind: PointerDeviceKind.mouse, - device: evt.button, + device: InputUtils.getMouseButtonKey(evt.button), physicalX: evt.mousePosition.x * this._devicePixelRatio, physicalY: evt.mousePosition.y * this._devicePixelRatio ); @@ -403,7 +427,7 @@ void _doOnGUI(Event evt) { -evt.delta.y * this._devicePixelRatio, evt.mousePosition.x * this._devicePixelRatio, evt.mousePosition.y * this._devicePixelRatio, - evt.button + InputUtils.getScrollButtonKey() ); } else if (evt.type == EventType.DragUpdated) { @@ -411,7 +435,7 @@ void _doOnGUI(Event evt) { timeStamp: Timer.timespanSinceStartup, change: PointerChange.dragFromEditorMove, kind: PointerDeviceKind.mouse, - device: evt.button, + device: InputUtils.getMouseButtonKey(evt.button), physicalX: evt.mousePosition.x * this._devicePixelRatio, physicalY: evt.mousePosition.y * this._devicePixelRatio ); @@ -421,7 +445,7 @@ void _doOnGUI(Event evt) { timeStamp: Timer.timespanSinceStartup, change: PointerChange.dragFromEditorRelease, kind: PointerDeviceKind.mouse, - device: evt.button, + device: InputUtils.getMouseButtonKey(evt.button), physicalX: evt.mousePosition.x * this._devicePixelRatio, physicalY: evt.mousePosition.y * this._devicePixelRatio ); diff --git a/Runtime/editor/surface.cs b/Runtime/editor/surface.cs index dd0797ee..dfdbee19 100644 --- a/Runtime/editor/surface.cs +++ b/Runtime/editor/surface.cs @@ -206,7 +206,7 @@ public GrSurface(Size size, float devicePixelRatio, int antiAliasing, MeshPool m useMipMap = false, autoGenerateMips = false, }; - + if (antiAliasing != 0) { desc.msaaSamples = antiAliasing; } @@ -224,6 +224,7 @@ public void Dispose() { if (this._canvas != null) { this._canvas.reset(); + this._canvas.dispose(); this._canvas = null; } } diff --git a/Runtime/editor/window_config.cs b/Runtime/editor/window_config.cs new file mode 100644 index 00000000..f985ddaf --- /dev/null +++ b/Runtime/editor/window_config.cs @@ -0,0 +1,36 @@ +using Unity.UIWidgets.foundation; + +namespace Unity.UIWidgets.editor { + public class WindowConfig { + public readonly bool disableRasterCache; + +#if UNITY_ANDROID + //make API compatible to low-end Android devices + public static float MaxRasterImageSize = 2048; +#else + public static float MaxRasterImageSize = 4096; +#endif + + static bool? _disableComputeBuffer = null; + + public static bool disableComputeBuffer { + //disable compute buffer by default for now + get { return _disableComputeBuffer ?? true; } + set { + D.assert(_disableComputeBuffer == null + || _disableComputeBuffer == value + , () => "The global settings of [disableComputeBuffer] cannot be initiated for multiple times!"); + + _disableComputeBuffer = value; + } + } + + public WindowConfig(bool disableRasterCache) { + this.disableRasterCache = disableRasterCache; + } + + public static readonly WindowConfig defaultConfig = new WindowConfig( + disableRasterCache: false + ); + } +} \ No newline at end of file diff --git a/Runtime/editor/window_config.cs.meta b/Runtime/editor/window_config.cs.meta new file mode 100644 index 00000000..63eff8de --- /dev/null +++ b/Runtime/editor/window_config.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b07028e6b697b43e4a5911da0ab9ca54 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/engine/DisplayMetrics.cs b/Runtime/engine/DisplayMetrics.cs index 23214a5c..d897f26c 100644 --- a/Runtime/engine/DisplayMetrics.cs +++ b/Runtime/engine/DisplayMetrics.cs @@ -187,7 +187,7 @@ static float AndroidDevicePixelRatio() { #if UNITY_IOS [DllImport("__Internal")] - static extern int IOSDeviceScaleFactor(); + static extern float IOSDeviceScaleFactor(); [DllImport("__Internal")] static extern viewMetrics IOSGetViewportPadding(); diff --git a/Runtime/engine/UIWidgetsPanel.cs b/Runtime/engine/UIWidgetsPanel.cs index 54e8233c..c886fea3 100644 --- a/Runtime/engine/UIWidgetsPanel.cs +++ b/Runtime/engine/UIWidgetsPanel.cs @@ -65,7 +65,7 @@ public override GUIContent titleContent { protected override float queryDevicePixelRatio() { return this._uiWidgetsPanel.devicePixelRatio; } - + protected override int queryAntiAliasing() { return this._uiWidgetsPanel.antiAliasing; } @@ -110,8 +110,13 @@ public class UIWidgetsPanel : RawImage, IPointerDownHandler, IPointerUpHandler, IPointerEnterHandler, IPointerExitHandler, WindowHost { static Event _repaintEvent; + [Tooltip("set to zero if you want to use the default device pixel ratio of the target platforms; otherwise the " + + "device pixel ratio will be forced to the given value on all devices.")] [SerializeField] protected float devicePixelRatioOverride; - [SerializeField] protected int antiAliasingOverride = Window.defaultAntiAliasing; + + [Tooltip("set to true will enable the hardware anti-alias feature, which will improve the appearance of the UI greatly but " + + "making it much slower. Enable it only when seriously required.")] + [SerializeField] protected bool hardwareAntiAliasing = false; WindowAdapter _windowAdapter; Texture _texture; Vector2 _lastMouseMove; @@ -133,6 +138,13 @@ void _handleViewMetricsChanged(string method, List args) { this._displayMetrics.onViewMetricsChanged(); } + protected virtual void InitWindowAdapter() { + D.assert(this._windowAdapter == null); + this._windowAdapter = new UIWidgetWindowAdapter(this); + + this._windowAdapter.OnEnable(); + } + protected override void OnEnable() { base.OnEnable(); @@ -148,10 +160,7 @@ protected override void OnEnable() { _repaintEvent = new Event {type = EventType.Repaint}; } - D.assert(this._windowAdapter == null); - this._windowAdapter = new UIWidgetWindowAdapter(this); - - this._windowAdapter.OnEnable(); + this.InitWindowAdapter(); Widget root; using (this._windowAdapter.getScope()) { @@ -169,9 +178,9 @@ public float devicePixelRatio { : this._displayMetrics.devicePixelRatio; } } - + public int antiAliasing { - get { return this.antiAliasingOverride >= 0 ? this.antiAliasingOverride : QualitySettings.antiAliasing; } + get { return this.hardwareAntiAliasing ? Window.defaultAntiAliasing : 0; } } public WindowPadding viewPadding { @@ -249,13 +258,16 @@ void OnGUI() { void handleMouseMovement() { var pos = this.getPointPosition(Input.mousePosition); + if (pos == null) { + return; + } this._windowAdapter.postPointerEvent(new PointerData( timeStamp: Timer.timespanSinceStartup, change: PointerChange.hover, kind: PointerDeviceKind.mouse, device: this.getMouseButtonDown(), - physicalX: pos.x, - physicalY: pos.y + physicalX: pos.Value.x, + physicalY: pos.Value.y )); } @@ -263,10 +275,13 @@ void handleMouseScroll() { if (Input.mouseScrollDelta.y != 0 || Input.mouseScrollDelta.x != 0) { var scaleFactor = this.canvas.scaleFactor; var pos = this.getPointPosition(Input.mousePosition); + if (pos == null) { + return; + } this._windowAdapter.onScroll(Input.mouseScrollDelta.x * scaleFactor, Input.mouseScrollDelta.y * scaleFactor, - pos.x, - pos.y, + pos.Value.x, + pos.Value.y, InputUtils.getScrollButtonKey()); } } @@ -285,48 +300,59 @@ int getMouseButtonDown() { } public void OnPointerDown(PointerEventData eventData) { - EventSystem.current.SetSelectedGameObject(this.gameObject, eventData); var position = this.getPointPosition(eventData); + if (position == null) { + return; + } + EventSystem.current.SetSelectedGameObject(this.gameObject, eventData); this._windowAdapter.postPointerEvent(new PointerData( timeStamp: Timer.timespanSinceStartup, change: PointerChange.down, kind: InputUtils.getPointerDeviceKind(eventData), device: InputUtils.getPointerDeviceKey(eventData), - physicalX: position.x, - physicalY: position.y + physicalX: position.Value.x, + physicalY: position.Value.y )); } public void OnPointerUp(PointerEventData eventData) { var position = this.getPointPosition(eventData); + if (position == null) { + return; + } this._windowAdapter.postPointerEvent(new PointerData( timeStamp: Timer.timespanSinceStartup, change: PointerChange.up, kind: InputUtils.getPointerDeviceKind(eventData), device: InputUtils.getPointerDeviceKey(eventData), - physicalX: position.x, - physicalY: position.y + physicalX: position.Value.x, + physicalY: position.Value.y )); } - public Vector2 getPointPosition(PointerEventData eventData) { + Camera getActiveCamera() { + //refer to: https://zhuanlan.zhihu.com/p/37127981 + Camera eventCamera = null; + if (this.canvas.renderMode != RenderMode.ScreenSpaceOverlay) { + eventCamera = this.canvas.GetComponent().eventCamera; + } + return eventCamera; + } + + Vector2? getPointPosition(PointerEventData eventData) { + Camera camera = this.getActiveCamera(); Vector2 localPoint; RectTransformUtility.ScreenPointToLocalPointInRectangle(this.rectTransform, eventData.position, - eventData.enterEventCamera, out localPoint); + camera, out localPoint); var scaleFactor = this.canvas.scaleFactor; localPoint.x = (localPoint.x - this.rectTransform.rect.min.x) * scaleFactor; localPoint.y = (this.rectTransform.rect.max.y - localPoint.y) * scaleFactor; return localPoint; } - public Vector2 getPointPosition(Vector2 position) { + Vector2? getPointPosition(Vector2 position) { Vector2 localPoint; - Camera eventCamera = null; - - if (this.canvas.renderMode != RenderMode.ScreenSpaceCamera) { - eventCamera = this.canvas.GetComponent().eventCamera; - } - + Camera eventCamera = this.getActiveCamera(); RectTransformUtility.ScreenPointToLocalPointInRectangle(this.rectTransform, position, eventCamera, out localPoint); @@ -338,44 +364,52 @@ public Vector2 getPointPosition(Vector2 position) { public void OnDrag(PointerEventData eventData) { var position = this.getPointPosition(eventData); + if (position == null) { + return; + } this._windowAdapter.postPointerEvent(new PointerData( timeStamp: Timer.timespanSinceStartup, change: PointerChange.move, kind: InputUtils.getPointerDeviceKind(eventData), device: InputUtils.getPointerDeviceKey(eventData), - physicalX: position.x, - physicalY: position.y + physicalX: position.Value.x, + physicalY: position.Value.y )); } public void OnPointerEnter(PointerEventData eventData) { + var position = this.getPointPosition(eventData); + if (position == null) { + return; + } var pointerKey = InputUtils.getPointerDeviceKey(eventData); this._enteredPointers.Add(pointerKey); this._lastMouseMove = eventData.position; - var position = this.getPointPosition(eventData); this._windowAdapter.postPointerEvent(new PointerData( timeStamp: Timer.timespanSinceStartup, change: PointerChange.hover, kind: InputUtils.getPointerDeviceKind(eventData), device: pointerKey, - physicalX: position.x, - physicalY: position.y + physicalX: position.Value.x, + physicalY: position.Value.y )); } public void OnPointerExit(PointerEventData eventData) { + var position = this.getPointPosition(eventData); + if (position == null) { + return; + } var pointerKey = InputUtils.getPointerDeviceKey(eventData); this._enteredPointers.Remove(pointerKey); - - var position = this.getPointPosition(eventData); this._windowAdapter.postPointerEvent(new PointerData( timeStamp: Timer.timespanSinceStartup, change: PointerChange.hover, kind: InputUtils.getPointerDeviceKind(eventData), device: pointerKey, - physicalX: position.x, - physicalY: position.y + physicalX: position.Value.x, + physicalY: position.Value.y )); } diff --git a/Runtime/engine/input_utils.cs b/Runtime/engine/input_utils.cs index 29e8f903..7066de35 100644 --- a/Runtime/engine/input_utils.cs +++ b/Runtime/engine/input_utils.cs @@ -3,12 +3,15 @@ using UnityEngine.EventSystems; namespace Unity.UIWidgets.engine { - static class InputUtils { + public static class InputUtils { const int mouseScrollId = 1; const int preservedKeyNum = 10; const int preservedMouseKeyNum = 100; const int fingerKeyStart = preservedKeyNum + preservedMouseKeyNum; + public const int MouseLeftKeyDevice = preservedKeyNum; + public const int MouseRightKeyDevice = preservedKeyNum + 1; + public static PointerDeviceKind getPointerDeviceKind(PointerEventData eventData) { return isTouchEvent(eventData) ? PointerDeviceKind.touch : PointerDeviceKind.mouse; } diff --git a/Runtime/engine/raycastable.meta b/Runtime/engine/raycastable.meta new file mode 100644 index 00000000..4b305bd7 --- /dev/null +++ b/Runtime/engine/raycastable.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d8e15e1221dae40e68226ec6d8ed8ddb +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/engine/raycastable/RaycastManager.cs b/Runtime/engine/raycastable/RaycastManager.cs new file mode 100644 index 00000000..f9c7aca8 --- /dev/null +++ b/Runtime/engine/raycastable/RaycastManager.cs @@ -0,0 +1,125 @@ +using System.Collections.Generic; +using Unity.UIWidgets.foundation; +using Unity.UIWidgets.ui; +using UnityEngine; + +namespace Unity.UIWidgets.engine.raycast { + public class RaycastableRect { + bool _isDirty = true; + + public bool isDirty { + get { return this._isDirty; } + } + + public float left; + public float right; + public float top; + public float bottom; + + public void MarkDirty() { + this._isDirty = true; + } + + public void UnmarkDirty() { + this._isDirty = false; + } + + public void UpdateRect(float left, float top, float width, float height) { + this.left = left; + this.right = left + width; + this.top = top; + this.bottom = top + height; + } + + public bool CheckInRect(Vector2 pos) { + return pos.x >= this.left && + pos.x < this.right && + pos.y >= this.top && + pos.y < this.bottom; + } + } + + public class RaycastManager { + static RaycastManager _instance; + + public static RaycastManager instance { + get { + if (_instance == null) { + _instance = new RaycastManager(); + } + + return _instance; + } + } + + public readonly Dictionary> raycastHandlerMap = + new Dictionary>(); + + public static void NewWindow(int windowHashCode) { + if (!instance.raycastHandlerMap.ContainsKey(windowHashCode)) { + instance.raycastHandlerMap.Add(windowHashCode, new Dictionary()); + } + } + + public static void DisposeWindow(int windowHashCode) { + if (instance.raycastHandlerMap.ContainsKey(windowHashCode)) { + instance.raycastHandlerMap.Remove(windowHashCode); + } + } + + public static void AddToList(int widgetHashCode, int windowHashCode) { + D.assert(instance.raycastHandlerMap.ContainsKey(windowHashCode), () => + $"Raycast Handler Map doesn't contain Window {windowHashCode}, " + + $"Make sure using UIWidgetsRaycastablePanel instead of UIWidgetsPanel " + + $"while using RaycastableContainer."); + D.assert(!instance.raycastHandlerMap[windowHashCode].ContainsKey(widgetHashCode), () => + $"Raycast Handler Map already contains Widget {widgetHashCode} at Window {windowHashCode}"); + + instance.raycastHandlerMap[windowHashCode][widgetHashCode] = new RaycastableRect(); + } + + public static void MarkDirty(int widgetHashCode, int windowHashCode) { + D.assert(instance.raycastHandlerMap.ContainsKey(windowHashCode), () => + $"Raycast Handler Map doesn't contain Window {windowHashCode}"); + D.assert(instance.raycastHandlerMap[windowHashCode].ContainsKey(widgetHashCode), () => + $"Raycast Handler Map doesn't contain Widget {widgetHashCode} at Window {windowHashCode}"); + + instance.raycastHandlerMap[windowHashCode][widgetHashCode].MarkDirty(); + } + + public static void UpdateSizeOffset(int widgetHashCode, int windowHashCode, Size size, Offset offset) { + D.assert(instance.raycastHandlerMap.ContainsKey(windowHashCode), () => + $"Raycast Handler Map doesn't contain Window {windowHashCode}"); + D.assert(instance.raycastHandlerMap[windowHashCode].ContainsKey(widgetHashCode), () => + $"Raycast Handler Map doesn't contain Widget {widgetHashCode} at Window {windowHashCode}"); + + if (instance.raycastHandlerMap[windowHashCode][widgetHashCode].isDirty) { + instance.raycastHandlerMap[windowHashCode][widgetHashCode] + .UpdateRect(offset.dx, offset.dy, size.width, size.height); + instance.raycastHandlerMap[windowHashCode][widgetHashCode].UnmarkDirty(); + } + } + + public static void RemoveFromList(int widgetHashCode, int windowHashCode) { + D.assert(instance.raycastHandlerMap.ContainsKey(windowHashCode), () => + $"Raycast Handler Map doesn't contain Window {windowHashCode}"); + D.assert(instance.raycastHandlerMap[windowHashCode].ContainsKey(widgetHashCode), () => + $"Raycast Handler Map doesn't contain Widget {widgetHashCode} at Window {windowHashCode}"); + + instance.raycastHandlerMap[windowHashCode].Remove(widgetHashCode); + } + + public static bool CheckCastThrough(int windowHashCode, Vector2 pos) { + D.assert(instance.raycastHandlerMap.ContainsKey(windowHashCode), () => + $"Raycast Handler Map doesn't contain Window {windowHashCode}"); + + foreach (var item in instance.raycastHandlerMap[windowHashCode]) { + if (item.Value.CheckInRect(pos)) { + return false; + } + } + + return true; + } + } +} \ No newline at end of file diff --git a/Runtime/engine/raycastable/RaycastManager.cs.meta b/Runtime/engine/raycastable/RaycastManager.cs.meta new file mode 100644 index 00000000..74519d43 --- /dev/null +++ b/Runtime/engine/raycastable/RaycastManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9574f12b230354e6f87fc5fc0c98c96e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/engine/raycastable/RaycastableContainer.cs b/Runtime/engine/raycastable/RaycastableContainer.cs new file mode 100644 index 00000000..429d6524 --- /dev/null +++ b/Runtime/engine/raycastable/RaycastableContainer.cs @@ -0,0 +1,106 @@ +using Unity.UIWidgets.foundation; +using Unity.UIWidgets.rendering; +using Unity.UIWidgets.ui; +using Unity.UIWidgets.widgets; + +namespace Unity.UIWidgets.engine.raycast { + class RaycastableBox : SingleChildRenderObjectWidget { + public RaycastableBox( + Key key = null, + Widget child = null + ) : base(key, child) { + this.windowHashCode = Window.instance.GetHashCode(); + } + + readonly int windowHashCode; + + public override RenderObject createRenderObject(BuildContext context) { + return new RenderRaycastableBox( + windowHashCode: this.windowHashCode, + widget: this + ); + } + + public override Element createElement() { + return new _RaycastableBoxRenderElement(windowHashCode: this.windowHashCode, widget: this); + } + } + + class RenderRaycastableBox : RenderProxyBox { + public RenderRaycastableBox( + int windowHashCode, + RaycastableBox widget + ) { + this.widgetHashCode = widget.GetHashCode(); + this.windowHashCode = windowHashCode; + } + + readonly int widgetHashCode; + readonly int windowHashCode; + + public override void paint(PaintingContext context, Offset offset) { + RaycastManager.UpdateSizeOffset(this.widgetHashCode, this.windowHashCode, this.size, offset); + + base.paint(context, offset); + } + } + + class _RaycastableBoxRenderElement : SingleChildRenderObjectElement { + public _RaycastableBoxRenderElement( + int windowHashCode, + RaycastableBox widget + ) : base(widget) { + this.windowHashCode = windowHashCode; + } + + public new RaycastableBox widget { + get { return base.widget as RaycastableBox; } + } + + int widgetHashCode; + int windowHashCode; + + public override void mount(Element parent, object newSlot) { + this.widgetHashCode = this.widget.GetHashCode(); + RaycastManager.AddToList(this.widgetHashCode, this.windowHashCode); + base.mount(parent, newSlot); + } + + public override void update(Widget newWidget) { + RaycastManager.MarkDirty(this.widgetHashCode, this.windowHashCode); + base.update(newWidget); + } + + public override void unmount() { + RaycastManager.RemoveFromList(this.widgetHashCode, this.windowHashCode); + base.unmount(); + } + } + + public class RaycastableContainer : StatelessWidget { + public RaycastableContainer( + Widget child = null, + Key key = null + ) : base(key) { + this.child = child; + } + + public readonly Widget child; + + public override Widget build(BuildContext context) { + Widget current = this.child; + + if (this.child == null) { + current = new LimitedBox( + maxWidth: 0.0f, + maxHeight: 0.0f, + child: new ConstrainedBox(constraints: BoxConstraints.expand()) + ); + } + + current = new RaycastableBox(child: current); + + return current; + } + } +} \ No newline at end of file diff --git a/Runtime/engine/raycastable/RaycastableContainer.cs.meta b/Runtime/engine/raycastable/RaycastableContainer.cs.meta new file mode 100644 index 00000000..3bb75ef0 --- /dev/null +++ b/Runtime/engine/raycastable/RaycastableContainer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9af0c7d6aab134f5ba187ff34acf2377 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/engine/raycastable/UIWidgetsRaycastablePanel.cs b/Runtime/engine/raycastable/UIWidgetsRaycastablePanel.cs new file mode 100644 index 00000000..2fc70de1 --- /dev/null +++ b/Runtime/engine/raycastable/UIWidgetsRaycastablePanel.cs @@ -0,0 +1,40 @@ +using Unity.UIWidgets.engine; +using UnityEngine; + +namespace Unity.UIWidgets.engine.raycast { + [RequireComponent(typeof(RectTransform))] + public class UIWidgetsRaycastablePanel : UIWidgetsPanel, ICanvasRaycastFilter { + int windowHashCode; + + protected override void InitWindowAdapter() { + base.InitWindowAdapter(); + this.windowHashCode = this.window.GetHashCode(); + RaycastManager.NewWindow(this.windowHashCode); + } + + protected override void OnDisable() { + base.OnDisable(); + RaycastManager.DisposeWindow(this.windowHashCode); + } + + public bool IsRaycastLocationValid(Vector2 screenPoint, Camera eventCamera) { + if (!this.enabled) { + return true; + } + + Vector2 local; + RectTransformUtility.ScreenPointToLocalPointInRectangle(this.rectTransform, screenPoint, eventCamera, + out local); + + Rect rect = this.rectTransform.rect; + + // Convert top left corner as reference origin point. + local.x += this.rectTransform.pivot.x * rect.width; + local.y -= this.rectTransform.pivot.y * rect.height; + local.x = local.x / this.devicePixelRatio; + local.y = -local.y / this.devicePixelRatio; + + return !RaycastManager.CheckCastThrough(this.windowHashCode, local); + } + } +} \ No newline at end of file diff --git a/Runtime/engine/raycastable/UIWidgetsRaycastablePanel.cs.meta b/Runtime/engine/raycastable/UIWidgetsRaycastablePanel.cs.meta new file mode 100644 index 00000000..f5ff1f78 --- /dev/null +++ b/Runtime/engine/raycastable/UIWidgetsRaycastablePanel.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e5265d12f7193408b90993bdf987f058 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/external/RTree.cs b/Runtime/external/RTree.cs new file mode 100644 index 00000000..a1bbd8e4 --- /dev/null +++ b/Runtime/external/RTree.cs @@ -0,0 +1,524 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Unity.UIWidgets.ui; + +namespace Unity.UIWidgets.external +{ + public interface ISpatialData + { + uiRect bounds { get; } + } + + public class IndexedRect : ISpatialData + { + private uiRect _bounds; + + public uiRect bounds + { + get { return _bounds; } + } + + public readonly int index; + + public IndexedRect(uiRect bounds, int index) + { + this._bounds = bounds; + this.index = index; + } + } + + /// + /// Non-generic class to produce instances of the generic class, + /// optionally using type inference. + /// + public static class ProjectionComparer + { + /// + /// Creates an instance of ProjectionComparer using the specified projection. + /// + /// Type parameter for the elements to be compared + /// Type parameter for the keys to be compared, after being projected from the elements + /// Projection to use when determining the key of an element + /// A comparer which will compare elements by projecting each element to its key, and comparing keys + public static ProjectionComparer Create(Func projection) + { + return new ProjectionComparer(projection); + } + + /// + /// Creates an instance of ProjectionComparer using the specified projection. + /// The ignored parameter is solely present to aid type inference. + /// + /// Type parameter for the elements to be compared + /// Type parameter for the keys to be compared, after being projected from the elements + /// Value is ignored - type may be used by type inference + /// Projection to use when determining the key of an element + /// A comparer which will compare elements by projecting each element to its key, and comparing keys + public static ProjectionComparer Create + (TSource ignored, + Func projection) + { + return new ProjectionComparer(projection); + } + } + + /// + /// Class generic in the source only to produce instances of the + /// doubly generic class, optionally using type inference. + /// + public static class ProjectionComparer + { + /// + /// Creates an instance of ProjectionComparer using the specified projection. + /// + /// Type parameter for the keys to be compared, after being projected from the elements + /// Projection to use when determining the key of an element + /// A comparer which will compare elements by projecting each element to its key, and comparing keys + public static ProjectionComparer Create(Func projection) + { + return new ProjectionComparer(projection); + } + } + + /// + /// Comparer which projects each element of the comparison to a key, and then compares + /// those keys using the specified (or default) comparer for the key type. + /// + /// Type of elements which this comparer will be asked to compare + /// Type of the key projected from the element + public class ProjectionComparer : IComparer + { + private readonly IComparer comparer; + private readonly Func projection; + + /// + /// Creates a new instance using the specified projection, which must not be null. + /// The default comparer for the projected type is used. + /// + /// Projection to use during comparisons + public ProjectionComparer(Func projection) + : this(projection, null) + { + } + + /// + /// Creates a new instance using the specified projection, which must not be null. + /// + /// Projection to use during comparisons + /// + /// The comparer to use on the keys. May be null, in + /// which case the default comparer will be used. + /// + public ProjectionComparer(Func projection, IComparer comparer) + { + this.comparer = comparer ?? Comparer.Default; + this.projection = projection; + } + + /// + /// Compares x and y by projecting them to keys and then comparing the keys. + /// Null values are not projected; they obey the + /// standard comparer contract such that two null values are equal; any null value is + /// less than any non-null value. + /// + public int Compare(TSource x, TSource y) + { + // Don't want to project from nullity + if (x == null && y == null) return 0; + if (x == null) return -1; + if (y == null) return 1; + return comparer.Compare(projection(x), projection(y)); + } + } + + public interface BBoxHierarchy where T : ISpatialData + { + IReadOnlyList Search(in uiRect boundingBox); + void BulkLoad(IEnumerable items); + + void Insert(T data); + + void Clear(); + } + + public class RTree : BBoxHierarchy where T : ISpatialData + { + public class RTreeNode : ISpatialData + { + internal readonly List children; + private uiRect _Rect; + + internal RTreeNode(List items, int height) + { + Height = height; + children = items; + ResetRect(); + } + + public IReadOnlyList Children => children; + public int Height { get; } + public bool IsLeaf => Height == 1; + public uiRect bounds => _Rect; + + internal void Add(ISpatialData node) + { + children.Add(node); + _Rect = bounds.expandToInclude(node.bounds); + } + + internal void Remove(ISpatialData node) + { + children.Remove(node); + ResetRect(); + } + + internal void RemoveRange(int index, int count) + { + children.RemoveRange(index, count); + ResetRect(); + } + + internal void ResetRect() + { + _Rect = GetEnclosingRect(children); + } + } + #region Search + + private List DoSearch(in uiRect boundingBox) + { + if (!uiRectHelper.overlaps(Root.bounds, boundingBox)) + return new List(); + + var intersections = new List(); + var queue = new Queue(); + queue.Enqueue(Root); + + while (queue.Count != 0) + { + var item = queue.Dequeue(); + if (item.IsLeaf) + { + foreach (var leafChildItem in item.children.Cast()) + if (uiRectHelper.overlaps(leafChildItem.bounds, boundingBox)) + intersections.Add(leafChildItem); + } + else + { + foreach (var child in item.children.Cast()) + if (uiRectHelper.overlaps(child.bounds, boundingBox)) + queue.Enqueue(child); + } + } + + return intersections; + } + + #endregion + + private static uiRect GetEnclosingRect(IEnumerable items) + { + var uiRect = uiRectHelper.zero; + foreach (var data in items) uiRect = uiRect.expandToInclude(data.bounds); + return uiRect; + } + + private List GetAllChildren(List list, RTreeNode n) + { + if (n.IsLeaf) + list.AddRange( + n.children.Cast()); + else + foreach (var node in n.children.Cast()) + GetAllChildren(list, node); + + return list; + } + + #region Sort Functions + + private static readonly IComparer CompareMinX = + ProjectionComparer.Create(d => d.bounds.left); + + private static readonly IComparer CompareMinY = + ProjectionComparer.Create(d => d.bounds.top); + + #endregion + + #region Insert + + private List FindCoveringArea(in uiRect area, int depth) + { + var path = new List(); + var node = Root; + var _area = area; //FIX CS1628 + + while (true) + { + path.Add(node); + if (node.IsLeaf || path.Count == depth) return path; + + node = node.children + .Select(c => new + {EnlargedArea = c.bounds.expandToInclude(_area).area, c.bounds.area, Node = c as RTreeNode}) + .OrderBy(x => x.EnlargedArea) + .ThenBy(x => x.area) + .Select(x => x.Node) + .First(); + } + } + + private void Insert(ISpatialData data, int depth) + { + var path = FindCoveringArea(data.bounds, depth); + + var insertNode = path.Last(); + insertNode.Add(data); + + while (--depth >= 0) + if (path[depth].children.Count > maxEntries) + { + var newNode = SplitNode(path[depth]); + if (depth == 0) + SplitRoot(newNode); + else + path[depth - 1].Add(newNode); + } + else + { + path[depth].ResetRect(); + } + } + + #region SplitNode + + private void SplitRoot(RTreeNode newRTreeNode) + { + Root = new RTreeNode(new List {Root, newRTreeNode}, Root.Height + 1); + } + + private RTreeNode SplitNode(RTreeNode rTreeNode) + { + SortChildren(rTreeNode); + + var splitPoint = GetBestSplitIndex(rTreeNode.children); + var newChildren = rTreeNode.children.Skip(splitPoint).ToList(); + rTreeNode.RemoveRange(splitPoint, rTreeNode.children.Count - splitPoint); + return new RTreeNode(newChildren, rTreeNode.Height); + } + + #region SortChildren + + private void SortChildren(RTreeNode rTreeNode) + { + rTreeNode.children.Sort(CompareMinX); + var splitsByX = GetPotentialSplitMargins(rTreeNode.children); + rTreeNode.children.Sort(CompareMinY); + var splitsByY = GetPotentialSplitMargins(rTreeNode.children); + + if (splitsByX < splitsByY) + rTreeNode.children.Sort(CompareMinX); + } + + private float GetPotentialSplitMargins(List children) + { + return GetPotentialEnclosingMargins(children) + + GetPotentialEnclosingMargins(children.AsEnumerable().Reverse().ToList()); + } + + private float GetPotentialEnclosingMargins(List children) + { + var uiRect = uiRectHelper.zero; + var i = 0; + for (; i < minEntries; i++) uiRect = uiRect.expandToInclude(children[i].bounds); + + var totalMargin = uiRect.margin; + for (; i < children.Count - minEntries; i++) + { + uiRect = uiRect.expandToInclude(children[i].bounds); + totalMargin += uiRect.margin; + } + + return totalMargin; + } + + #endregion + + private int GetBestSplitIndex(List children) + { + return Enumerable.Range(minEntries, children.Count - minEntries) + .Select(i => + { + var leftRect = GetEnclosingRect(children.Take(i)); + var rightRect = GetEnclosingRect(children.Skip(i)); + + var overlap = leftRect.intersect(rightRect).area; + var totalArea = leftRect.area + rightRect.area; + return new {i, overlap, totalArea}; + }) + .OrderBy(x => x.overlap) + .ThenBy(x => x.totalArea) + .Select(x => x.i) + .First(); + } + + #endregion + + #endregion + + #region BuildTree + + private RTreeNode BuildTree(List data) + { + var treeHeight = GetDepth(data.Count); + var rootMaxEntries = (int) Math.Ceiling(data.Count / Math.Pow(maxEntries, treeHeight - 1)); + return BuildNodes(data, 0, data.Count - 1, treeHeight, rootMaxEntries); + } + + private int GetDepth(int numNodes) + { + return (int) Math.Ceiling(Math.Log(numNodes) / Math.Log(maxEntries)); + } + + private RTreeNode BuildNodes(List data, int left, int right, int height, int maxEntries) + { + var num = right - left + 1; + if (num <= maxEntries) + return height == 1 + ? new RTreeNode(data.GetRange(left, num), height) + : new RTreeNode( + new List + { + BuildNodes(data, left, right, height - 1, this.maxEntries) + }, + height); + + data.Sort(left, num, CompareMinX); + + var nodeSize = (num + (maxEntries - 1)) / maxEntries; + var subSortLength = nodeSize * (int) Math.Ceiling(Math.Sqrt(maxEntries)); + + var children = new List(maxEntries); + for (var subCounter = left; subCounter <= right; subCounter += subSortLength) + { + var subRight = Math.Min(subCounter + subSortLength - 1, right); + data.Sort(subCounter, subRight - subCounter + 1, CompareMinY); + + for (var nodeCounter = subCounter; nodeCounter <= subRight; nodeCounter += nodeSize) + children.Add( + BuildNodes( + data, + nodeCounter, + Math.Min(nodeCounter + nodeSize - 1, subRight), + height - 1, + this.maxEntries)); + } + + return new RTreeNode(children, height); + } + + #endregion + private const int DefaultMaxEntries = 9; + private const int MinimumMaxEntries = 4; + private const int MinimumMinEntries = 2; + private const float DefaultFillFactor = 0.4f; + + private readonly EqualityComparer comparer; + private readonly int maxEntries; + private readonly int minEntries; + + public RTree() : this(DefaultMaxEntries) + { + } + + public RTree(int maxEntries) + : this(maxEntries, EqualityComparer.Default) + { + } + + public RTree(int maxEntries, EqualityComparer comparer) + { + this.comparer = comparer; + this.maxEntries = Math.Max(MinimumMaxEntries, maxEntries); + minEntries = Math.Max(MinimumMinEntries, (int) Math.Ceiling(this.maxEntries * DefaultFillFactor)); + + Clear(); + } + + public RTreeNode Root { get; private set; } + public uiRect uiRect => Root.bounds; + + public int Count { get; private set; } + + public void Clear() + { + Root = new RTreeNode(new List(), 1); + Count = 0; + } + + public IReadOnlyList Search() + { + return GetAllChildren(new List(), Root); + } + + public IReadOnlyList Search(in uiRect boundingBox) + { + return DoSearch(boundingBox); + } + + public void Insert(T item) + { + Insert(item, Root.Height); + Count++; + } + + public void BulkLoad(IEnumerable items) + { + var data = items.Cast().ToList(); + if (data.Count == 0) return; + + if (Root.IsLeaf && + Root.children.Count + data.Count < maxEntries) + { + foreach (var i in data) + Insert((T) i); + return; + } + + if (data.Count < minEntries) + { + foreach (var i in data) + Insert((T) i); + return; + } + + var dataRoot = BuildTree(data); + Count += data.Count; + + if (Root.children.Count == 0) + { + Root = dataRoot; + } + else if (Root.Height == dataRoot.Height) + { + if (Root.children.Count + dataRoot.children.Count <= maxEntries) + foreach (var isd in dataRoot.children) + Root.Add(isd); + else + SplitRoot(dataRoot); + } + else + { + if (Root.Height < dataRoot.Height) + { + var tmp = Root; + Root = dataRoot; + dataRoot = tmp; + } + + Insert(dataRoot, Root.Height - dataRoot.Height); + } + } + } +} \ No newline at end of file diff --git a/Runtime/external/RTree.cs.meta b/Runtime/external/RTree.cs.meta new file mode 100644 index 00000000..30f3da65 --- /dev/null +++ b/Runtime/external/RTree.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0a93ee633aad3dc4395851f56b650cc2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/external/SplayTree.cs b/Runtime/external/SplayTree.cs new file mode 100644 index 00000000..ac19690b --- /dev/null +++ b/Runtime/external/SplayTree.cs @@ -0,0 +1,493 @@ +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Unity.UIWidgets.external +{ class SplayTree : IDictionary where TKey : IComparable { + SplayTreeNode root; + int count; + int version = 0; + + public void Add(TKey key, TValue value) { + this.Set(key, value, throwOnExisting: true); + } + + public void Add(KeyValuePair item) { + this.Set(item.Key, item.Value, throwOnExisting: true); + } + + public void AddAll(IEnumerable list) { + foreach (var key in list) { + this.Add(new KeyValuePair(key, default)); + } + } + + void Set(TKey key, TValue value, bool throwOnExisting) { + if (this.count == 0) { + this.version++; + this.root = new SplayTreeNode(key, value); + this.count = 1; + return; + } + + this.Splay(key); + + var c = key.CompareTo(this.root.Key); + if (c == 0) { + if (throwOnExisting) { + throw new ArgumentException("An item with the same key already exists in the tree."); + } + + this.version++; + this.root.Value = value; + return; + } + + var n = new SplayTreeNode(key, value); + if (c < 0) { + n.LeftChild = this.root.LeftChild; + n.RightChild = this.root; + this.root.LeftChild = null; + } + else { + n.RightChild = this.root.RightChild; + n.LeftChild = this.root; + this.root.RightChild = null; + } + + this.root = n; + this.count++; + this.Splay(key); + this.version++; + } + + public void Clear() { + this.root = null; + this.count = 0; + this.version++; + } + + public bool ContainsKey(TKey key) { + if (this.count == 0) { + return false; + } + + this.Splay(key); + + return key.CompareTo(this.root.Key) == 0; + } + + public bool Contains(KeyValuePair item) { + if (this.count == 0) { + return false; + } + + this.Splay(item.Key); + + return item.Key.CompareTo(this.root.Key) == 0 && + (ReferenceEquals(this.root.Value, item.Value) || + (!ReferenceEquals(item.Value, null) && item.Value.Equals(this.root.Value))); + } + + public KeyValuePair? First() { + SplayTreeNode t = this.root; + if (t == null) { + return null; + } + + while (t.LeftChild != null) { + t = t.LeftChild; + } + + return new KeyValuePair(t.Key, t.Value); + } + + public KeyValuePair FirstOrDefault() { + SplayTreeNode t = this.root; + if (t == null) { + return new KeyValuePair(default(TKey), default(TValue)); + } + + while (t.LeftChild != null) { + t = t.LeftChild; + } + + return new KeyValuePair(t.Key, t.Value); + } + + public KeyValuePair? Last() { + SplayTreeNode t = this.root; + if (t == null) { + return null; + } + + while (t.RightChild != null) { + t = t.RightChild; + } + + return new KeyValuePair(t.Key, t.Value); + } + + public KeyValuePair LastOrDefault() { + SplayTreeNode t = this.root; + if (t == null) { + return new KeyValuePair(default(TKey), default(TValue)); + } + + while (t.RightChild != null) { + t = t.RightChild; + } + + return new KeyValuePair(t.Key, t.Value); + } + + void Splay(TKey key) { + SplayTreeNode l, r, t, y, header; + l = r = header = new SplayTreeNode(default(TKey), default(TValue)); + t = this.root; + while (true) { + var c = key.CompareTo(t.Key); + if (c < 0) { + if (t.LeftChild == null) { + break; + } + + if (key.CompareTo(t.LeftChild.Key) < 0) { + y = t.LeftChild; + t.LeftChild = y.RightChild; + y.RightChild = t; + t = y; + if (t.LeftChild == null) { + break; + } + } + + r.LeftChild = t; + r = t; + t = t.LeftChild; + } + else if (c > 0) { + if (t.RightChild == null) { + break; + } + + if (key.CompareTo(t.RightChild.Key) > 0) { + y = t.RightChild; + t.RightChild = y.LeftChild; + y.LeftChild = t; + t = y; + if (t.RightChild == null) { + break; + } + } + + l.RightChild = t; + l = t; + t = t.RightChild; + } + else { + break; + } + } + + l.RightChild = t.LeftChild; + r.LeftChild = t.RightChild; + t.LeftChild = header.RightChild; + t.RightChild = header.LeftChild; + this.root = t; + } + + public bool Remove(TKey key) { + if (this.count == 0) { + return false; + } + + this.Splay(key); + + if (key.CompareTo(this.root.Key) != 0) { + return false; + } + + if (this.root.LeftChild == null) { + this.root = this.root.RightChild; + } + else { + var swap = this.root.RightChild; + this.root = this.root.LeftChild; + this.Splay(key); + this.root.RightChild = swap; + } + + this.version++; + this.count--; + return true; + } + + public bool TryGetValue(TKey key, out TValue value) { + if (this.count == 0) { + value = default(TValue); + return false; + } + + this.Splay(key); + if (key.CompareTo(this.root.Key) != 0) { + value = default(TValue); + return false; + } + + value = this.root.Value; + return true; + } + + public TValue this[TKey key] { + get { + if (this.count == 0) { + throw new KeyNotFoundException("The key was not found in the tree."); + } + + this.Splay(key); + if (key.CompareTo(this.root.Key) != 0) { + throw new KeyNotFoundException("The key was not found in the tree."); + } + + return this.root.Value; + } + + set { this.Set(key, value, throwOnExisting: false); } + } + + public int Count { + get { return this.count; } + } + + public bool IsReadOnly { + get { return false; } + } + + public bool Remove(KeyValuePair item) { + if (this.count == 0) { + return false; + } + + this.Splay(item.Key); + + if (item.Key.CompareTo(this.root.Key) == 0 && (ReferenceEquals(this.root.Value, item.Value) || + (!ReferenceEquals(item.Value, null) && + item.Value.Equals(this.root.Value)))) { + return false; + } + + if (this.root.LeftChild == null) { + this.root = this.root.RightChild; + } + else { + var swap = this.root.RightChild; + this.root = this.root.LeftChild; + this.Splay(item.Key); + this.root.RightChild = swap; + } + + this.version++; + this.count--; + return true; + } + + public void Trim(int depth) { + if (depth < 0) { + throw new ArgumentOutOfRangeException("depth", "The trim depth must not be negative."); + } + + if (this.count == 0) { + return; + } + + if (depth == 0) { + this.Clear(); + } + else { + var prevCount = this.count; + this.count = this.Trim(this.root, depth - 1); + if (prevCount != this.count) { + this.version++; + } + } + } + + int Trim(SplayTreeNode node, int depth) { + if (depth == 0) { + node.LeftChild = null; + node.RightChild = null; + return 1; + } + else { + int count = 1; + + if (node.LeftChild != null) { + count += this.Trim(node.LeftChild, depth - 1); + } + + if (node.RightChild != null) { + count += this.Trim(node.RightChild, depth - 1); + } + + return count; + } + } + + public ICollection Keys { + get { return new TiedList(this, this.version, this.AsList(node => node.Key)); } + } + + public ICollection Values { + get { return new TiedList(this, this.version, this.AsList(node => node.Value)); } + } + + public void CopyTo(KeyValuePair[] array, int arrayIndex) { + this.AsList(node => new KeyValuePair(node.Key, node.Value)).CopyTo(array, arrayIndex); + } + + public IEnumerator> GetEnumerator() { + return new TiedList>(this, this.version, + this.AsList(node => new KeyValuePair(node.Key, node.Value))).GetEnumerator(); + } + + IList AsList(Func selector) { + if (this.root == null) { + return new TEnumerator[0]; + } + + var result = new List(this.count); + this.PopulateList(this.root, result, selector); + return result; + } + + void PopulateList(SplayTreeNode node, List list, + Func selector) { + if (node.LeftChild != null) { + this.PopulateList(node.LeftChild, list, selector); + } + + list.Add(selector(node)); + if (node.RightChild != null) { + this.PopulateList(node.RightChild, list, selector); + } + } + + IEnumerator IEnumerable.GetEnumerator() { + return this.GetEnumerator(); + } + + sealed class SplayTreeNode { + public readonly TKey Key; + + public TValue Value; + public SplayTreeNode LeftChild; + public SplayTreeNode RightChild; + + public SplayTreeNode(TKey key, TValue value) { + this.Key = key; + this.Value = value; + } + } + + sealed class TiedList : IList { + readonly SplayTree tree; + readonly int version; + readonly IList backingList; + + public TiedList(SplayTree tree, int version, IList backingList) { + if (tree == null) { + throw new ArgumentNullException("tree"); + } + + if (backingList == null) { + throw new ArgumentNullException("backingList"); + } + + this.tree = tree; + this.version = version; + this.backingList = backingList; + } + + public int IndexOf(T item) { + if (this.tree.version != this.version) { + throw new InvalidOperationException("The collection has been modified."); + } + + return this.backingList.IndexOf(item); + } + + public void Insert(int index, T item) { + throw new NotSupportedException(); + } + + public void RemoveAt(int index) { + throw new NotSupportedException(); + } + + public T this[int index] { + get { + if (this.tree.version != this.version) { + throw new InvalidOperationException("The collection has been modified."); + } + + return this.backingList[index]; + } + set { throw new NotSupportedException(); } + } + + public void Add(T item) { + throw new NotSupportedException(); + } + + public void Clear() { + throw new NotSupportedException(); + } + + public bool Contains(T item) { + if (this.tree.version != this.version) { + throw new InvalidOperationException("The collection has been modified."); + } + + return this.backingList.Contains(item); + } + + public void CopyTo(T[] array, int arrayIndex) { + if (this.tree.version != this.version) { + throw new InvalidOperationException("The collection has been modified."); + } + + this.backingList.CopyTo(array, arrayIndex); + } + + public int Count { + get { return this.tree.count; } + } + + public bool IsReadOnly { + get { return true; } + } + + public bool Remove(T item) { + throw new NotSupportedException(); + } + + public IEnumerator GetEnumerator() { + if (this.tree.version != this.version) { + throw new InvalidOperationException("The collection has been modified."); + } + + foreach (var item in this.backingList) { + yield return item; + if (this.tree.version != this.version) { + throw new InvalidOperationException("The collection has been modified."); + } + } + } + + IEnumerator IEnumerable.GetEnumerator() { + return this.GetEnumerator(); + } + } + } +} \ No newline at end of file diff --git a/Runtime/external/SplayTree.cs.meta b/Runtime/external/SplayTree.cs.meta new file mode 100644 index 00000000..21a69192 --- /dev/null +++ b/Runtime/external/SplayTree.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 600f58b77585e6845aa9f0924a5af554 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/foundation/basic_types.cs b/Runtime/foundation/basic_types.cs index 11b95261..d43ac5a0 100644 --- a/Runtime/foundation/basic_types.cs +++ b/Runtime/foundation/basic_types.cs @@ -8,6 +8,10 @@ namespace Unity.UIWidgets.foundation { public delegate void ValueChanged(T value); + public delegate void ValueSetter(T value); + + public delegate T ValueGetter(); + public delegate IEnumerable EnumerableFilter(IEnumerable input); public static class ObjectUtils { @@ -72,6 +76,15 @@ public static TValue getOrDefault(this IDictionary i it.TryGetValue(key, out v); return v; } + + public static TValue getOrDefault(this IDictionary it, TKey key, TValue defaultVal) { + TValue v = defaultVal; + if (key == null) { + return v; + } + it.TryGetValue(key, out v); + return v; + } public static T first(this IList it) { return it[0]; diff --git a/Runtime/foundation/diagnostics.cs b/Runtime/foundation/diagnostics.cs index 6a25b16f..1ed1b1fd 100644 --- a/Runtime/foundation/diagnostics.cs +++ b/Runtime/foundation/diagnostics.cs @@ -1421,7 +1421,13 @@ public override string ToString() { } public virtual string toString(DiagnosticLevel minLevel = DiagnosticLevel.debug) { - return this.toDiagnosticsNode(style: DiagnosticsTreeStyle.singleLine).toString(minLevel: minLevel); + string fullString = null; + D.assert(() => { + fullString = this.toDiagnosticsNode(style: DiagnosticsTreeStyle.singleLine) + .toString(minLevel: minLevel); + return true; + }); + return fullString ?? this.toStringShort(); } public virtual DiagnosticsNode toDiagnosticsNode( diff --git a/Runtime/gestures/binding.cs b/Runtime/gestures/binding.cs index 28702acb..d463591d 100644 --- a/Runtime/gestures/binding.cs +++ b/Runtime/gestures/binding.cs @@ -48,6 +48,8 @@ void _flushPointerEventQueue() { public readonly GestureArenaManager gestureArena; + public readonly PointerSignalResolver pointerSignalResolver = new PointerSignalResolver(); + public readonly Dictionary _hitTests = new Dictionary(); public readonly HashSet lastMoveTargets = new HashSet(); @@ -61,10 +63,13 @@ void _handlePointerEvent(PointerEvent evt) { } HitTestResult hitTestResult = null; - if (evt is PointerDownEvent) { + if (evt is PointerDownEvent || evt is PointerSignalEvent) { D.assert(!this._hitTests.ContainsKey(evt.pointer)); hitTestResult = new HitTestResult(); this.hitTest(hitTestResult, evt.position); + if (evt is PointerDownEvent) { + this._hitTests[evt.pointer] = hitTestResult; + } this._hitTests[evt.pointer] = hitTestResult; D.assert(() => { @@ -104,6 +109,9 @@ evt is PointerDragFromEditorReleaseEvent void _handlePointerScrollEvent(PointerEvent evt) { this.pointerRouter.clearScrollRoute(evt.pointer); + if (!this.pointerRouter.acceptScroll()) { + return; + } HitTestResult result = new HitTestResult(); this.hitTest(result, evt.position); @@ -160,6 +168,9 @@ public void handleEvent(PointerEvent evt, HitTestEntry entry) { else if (evt is PointerUpEvent) { this.gestureArena.sweep(evt.pointer); } + else if (evt is PointerSignalEvent) { + this.pointerSignalResolver.resolve((PointerSignalEvent) evt); + } } } } \ No newline at end of file diff --git a/Runtime/gestures/constants.cs b/Runtime/gestures/constants.cs index 54ff1ad4..7d8d98ed 100644 --- a/Runtime/gestures/constants.cs +++ b/Runtime/gestures/constants.cs @@ -16,6 +16,8 @@ public static class Constants { public static readonly TimeSpan kDoubleTapTimeout = new TimeSpan(0, 0, 0, 0, 300); + public static readonly TimeSpan kDoubleTapMinTime = new TimeSpan(0, 0, 0, 0, 40); + public static readonly TimeSpan kLongPressTimeout = new TimeSpan(0, 0, 0, 0, 500); public const float kMinFlingVelocity = 50.0f; diff --git a/Runtime/gestures/converter.cs b/Runtime/gestures/converter.cs index fedc8db9..bf979596 100644 --- a/Runtime/gestures/converter.cs +++ b/Runtime/gestures/converter.cs @@ -48,11 +48,25 @@ public void setUp() { public Offset lastPosition; + public Offset deltaTo(Offset to) { + return to - this.lastPosition; + } + public override string ToString() { return $"_PointerState(pointer: {this.pointer}, down: {this.down}, lastPosition: {this.lastPosition})"; } + + internal static int _synthesiseDownButtons(int buttons, PointerDeviceKind kind) { + switch (kind) { + case PointerDeviceKind.touch: + return buttons; + default: + return buttons; + } + } } + public static class PointerEventConverter { static readonly Dictionary _pointers = new Dictionary(); @@ -69,10 +83,36 @@ static _PointerState _ensureStateForPointer(PointerData datum, Offset position) public static IEnumerable expand(IEnumerable data, float devicePixelRatio) { foreach (PointerData datum in data) { var position = new Offset(datum.physicalX, datum.physicalY) / devicePixelRatio; + var radiusMinor = _toLogicalPixels(datum.radiusMinor, devicePixelRatio); + var radiusMajor = _toLogicalPixels(datum.radiusMajor, devicePixelRatio); + var radiusMin = _toLogicalPixels(datum.radiusMin, devicePixelRatio); + var radiusMax = _toLogicalPixels(datum.radiusMax, devicePixelRatio); var timeStamp = datum.timeStamp; var kind = datum.kind; switch (datum.change) { + case PointerChange.add: { + D.assert(!_pointers.ContainsKey(datum.device)); + _PointerState state = _ensureStateForPointer(datum, position); + D.assert(state.lastPosition == position); + yield return new PointerAddedEvent( + timeStamp: timeStamp, + kind: kind, + device: datum.device, + position: position, + obscured: datum.obscured, + pressureMin: datum.pressureMin, + pressureMax: datum.pressureMax, + distance: datum.distance, + distanceMax: datum.distanceMax, + radiusMin: radiusMin, + radiusMax: radiusMax, + orientation: datum.orientation, + tilt: datum.tilt + ); + break; + } + case PointerChange.down: { _PointerState state = _ensureStateForPointer(datum, position); if (state.down) { @@ -142,13 +182,14 @@ public static IEnumerable expand(IEnumerable data, fl 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, - delta: new Offset(_scrollData.scrollX, _scrollData.scrollY) / devicePixelRatio + scrollDelta: scrollDelta ); break; } @@ -226,5 +267,9 @@ public static IEnumerable expand(IEnumerable data, fl } } } + + static float _toLogicalPixels(float physicalPixels, float devicePixelRatio) { + return physicalPixels / devicePixelRatio; + } } } \ No newline at end of file diff --git a/Runtime/gestures/events.cs b/Runtime/gestures/events.cs index c0eb1b67..1a053e86 100644 --- a/Runtime/gestures/events.cs +++ b/Runtime/gestures/events.cs @@ -1,17 +1,33 @@ using System; +using Unity.UIWidgets.foundation; using Unity.UIWidgets.ui; using Object = UnityEngine.Object; namespace Unity.UIWidgets.gestures { - public abstract class PointerEvent { + public abstract class PointerEvent : Diagnosticable { public PointerEvent( TimeSpan timeStamp, int pointer = 0, - PointerDeviceKind kind = PointerDeviceKind.mouse, + PointerDeviceKind kind = PointerDeviceKind.touch, int device = 0, Offset position = null, Offset delta = null, + int buttons = 0, bool down = false, + bool obscured = false, + float pressure = 1.0f, + float pressureMin = 1.0f, + float pressureMax = 1.0f, + float distance = 0.0f, + float distanceMax = 0.0f, + float size = 0.0f, + float radiusMajor = 0.0f, + float radiusMinor = 0.0f, + float radiusMin = 0.0f, + float radiusMax = 0.0f, + float orientation = 0.0f, + float tilt = 0.0f, + int platformData = 0, bool synthesized = false ) { this.timeStamp = timeStamp; @@ -20,7 +36,22 @@ public PointerEvent( this.device = device; this.position = position ?? Offset.zero; this.delta = delta ?? Offset.zero; + this.buttons = buttons; this.down = down; + this.obscured = obscured; + this.pressure = pressure; + this.pressureMin = pressureMin; + this.pressureMax = pressureMax; + this.distance = distance; + this.distanceMax = distanceMax; + this.size = size; + this.radiusMajor = radiusMajor; + this.radiusMinor = radiusMinor; + this.radiusMin = radiusMin; + this.radiusMax = radiusMax; + this.orientation = orientation; + this.tilt = tilt; + this.platformData = platformData; this.synthesized = synthesized; } @@ -36,9 +67,87 @@ public PointerEvent( public readonly Offset delta; + public readonly int buttons; + public readonly bool down; + public readonly bool obscured; + + public readonly float pressure; + + public readonly float pressureMin; + + public readonly float pressureMax; + + public readonly float distance; + + public float distanceMin { + get { return 0.0f; } + } + + public readonly float distanceMax; + + public readonly float size; + + public readonly float radiusMajor; + + public readonly float radiusMinor; + + public readonly float radiusMin; + + public readonly float radiusMax; + + public readonly float orientation; + + public readonly float tilt; + + public readonly int platformData; + public readonly bool synthesized; + + public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { + base.debugFillProperties(properties); + properties.add(new DiagnosticsProperty("position", this.position)); + properties.add(new DiagnosticsProperty("delta", this.delta, defaultValue: Offset.zero, + level: DiagnosticLevel.debug)); + properties.add(new DiagnosticsProperty("timeStamp", this.timeStamp, defaultValue: TimeSpan.Zero, + level: DiagnosticLevel.debug)); + properties.add(new IntProperty("pointer", this.pointer, level: DiagnosticLevel.debug)); + properties.add(new EnumProperty("kind", this.kind, level: DiagnosticLevel.debug)); + properties.add(new IntProperty("device", this.device, defaultValue: 0, level: DiagnosticLevel.debug)); + properties.add(new IntProperty("buttons", this.buttons, defaultValue: 0, level: DiagnosticLevel.debug)); + properties.add(new DiagnosticsProperty("down", this.down, level: DiagnosticLevel.debug)); + properties.add( + new FloatProperty("pressure", this.pressure, defaultValue: 1.0, level: DiagnosticLevel.debug)); + properties.add(new FloatProperty("pressureMin", this.pressureMin, defaultValue: 1.0, + level: DiagnosticLevel.debug)); + properties.add(new FloatProperty("pressureMax", this.pressureMax, defaultValue: 1.0, + level: DiagnosticLevel.debug)); + properties.add( + new FloatProperty("distance", this.distance, defaultValue: 0.0, level: DiagnosticLevel.debug)); + properties.add(new FloatProperty("distanceMin", this.distanceMin, defaultValue: 0.0, + level: DiagnosticLevel.debug)); + properties.add(new FloatProperty("distanceMax", this.distanceMax, defaultValue: 0.0, + level: DiagnosticLevel.debug)); + properties.add(new FloatProperty("size", this.size, defaultValue: 0.0, level: DiagnosticLevel.debug)); + properties.add(new FloatProperty("radiusMajor", this.radiusMajor, defaultValue: 0.0, + level: DiagnosticLevel.debug)); + properties.add(new FloatProperty("radiusMinor", this.radiusMinor, defaultValue: 0.0, + level: DiagnosticLevel.debug)); + properties.add(new FloatProperty("radiusMin", this.radiusMin, defaultValue: 0.0, + level: DiagnosticLevel.debug)); + properties.add(new FloatProperty("radiusMax", this.radiusMax, defaultValue: 0.0, + level: DiagnosticLevel.debug)); + properties.add(new FloatProperty("orientation", this.orientation, defaultValue: 0.0, + level: DiagnosticLevel.debug)); + properties.add(new FloatProperty("tilt", this.tilt, defaultValue: 0.0, level: DiagnosticLevel.debug)); + properties.add(new IntProperty("platformData", this.platformData, defaultValue: 0, + level: DiagnosticLevel.debug)); + properties.add(new FlagProperty("obscured", value: this.obscured, ifTrue: "obscured", + level: DiagnosticLevel.debug)); + properties.add(new FlagProperty("synthesized", value: this.synthesized, ifTrue: "synthesized", + level: DiagnosticLevel.debug)); + } } public class PointerAddedEvent : PointerEvent { @@ -46,12 +155,32 @@ public PointerAddedEvent( TimeSpan timeStamp, PointerDeviceKind kind = PointerDeviceKind.touch, int device = 0, - Offset position = null + Offset position = null, + bool obscured = false, + float pressure = 0.0f, + float pressureMin = 1.0f, + float pressureMax = 1.0f, + float distance = 0.0f, + float distanceMax = 0.0f, + float radiusMin = 0.0f, + float radiusMax = 0.0f, + float orientation = 0.0f, + float tilt = 0.0f ) : base( timeStamp: timeStamp, kind: kind, device: device, - position: position + position: position, + obscured: obscured, + pressure: pressure, + pressureMin: pressureMin, + pressureMax: pressureMax, + distance: distance, + distanceMax: distanceMax, + radiusMin: radiusMin, + radiusMax: radiusMax, + orientation: orientation, + tilt: tilt ) { } } @@ -60,31 +189,455 @@ public class PointerRemovedEvent : PointerEvent { public PointerRemovedEvent( TimeSpan timeStamp, PointerDeviceKind kind = PointerDeviceKind.touch, - int device = 0 + int device = 0, + bool obscured = false, + float pressure = 0.0f, + float pressureMin = 1.0f, + float pressureMax = 1.0f, + float distanceMax = 0.0f, + float radiusMin = 0.0f, + float radiusMax = 0.0f ) : base( timeStamp: timeStamp, kind: kind, - device: device + device: device, + obscured: obscured, + pressure: pressure, + pressureMin: pressureMin, + pressureMax: pressureMax, + distanceMax: distanceMax, + radiusMin: radiusMin, + radiusMax: radiusMax ) { } } - public class PointerScrollEvent : PointerEvent { - public PointerScrollEvent( + public class PointerHoverEvent : PointerEvent { + public PointerHoverEvent( + TimeSpan timeStamp, + PointerDeviceKind kind = PointerDeviceKind.touch, + int device = 0, + Offset position = null, + Offset delta = null, + int buttons = 0, + bool obscured = false, + float pressure = 0.0f, + float pressureMin = 1.0f, + float pressureMax = 1.0f, + float distance = 0.0f, + float distanceMax = 0.0f, + float size = 0.0f, + float radiusMajor = 0.0f, + float radiusMinor = 0.0f, + float radiusMin = 0.0f, + float radiusMax = 0.0f, + float orientation = 0.0f, + float tilt = 0.0f, + bool synthesized = false) : base( + timeStamp: timeStamp, + kind: kind, + device: device, + position: position, + delta: delta, + buttons: buttons, + obscured: obscured, + pressure: pressure, + pressureMin: pressureMin, + pressureMax: pressureMax, + size: size, + radiusMajor: radiusMajor, + radiusMinor: radiusMinor, + distance: distance, + distanceMax: distanceMax, + radiusMin: radiusMin, + radiusMax: radiusMax, + orientation: orientation, + tilt: tilt, + synthesized: synthesized) { + } + } + + public class PointerEnterEvent : PointerEvent { + public PointerEnterEvent( + TimeSpan timeStamp, + PointerDeviceKind kind = PointerDeviceKind.touch, + int device = 0, + Offset position = null, + Offset delta = null, + int buttons = 0, + bool obscured = false, + float pressure = 0.0f, + float pressureMin = 1.0f, + float pressureMax = 1.0f, + float distance = 0.0f, + float distanceMax = 0.0f, + float size = 0.0f, + float radiusMajor = 0.0f, + float radiusMinor = 0.0f, + float radiusMin = 0.0f, + float radiusMax = 0.0f, + float orientation = 0.0f, + float tilt = 0.0f, + bool synthesized = false, + bool down = false) : base( + timeStamp: timeStamp, + kind: kind, + device: device, + position: position, + delta: delta, + buttons: buttons, + down: down, + obscured: obscured, + pressure: pressure, + pressureMin: pressureMin, + pressureMax: pressureMax, + size: size, + radiusMajor: radiusMajor, + radiusMinor: radiusMinor, + distance: distance, + distanceMax: distanceMax, + radiusMin: radiusMin, + radiusMax: radiusMax, + orientation: orientation, + tilt: tilt, + synthesized: synthesized) { + } + + public static PointerEnterEvent fromHoverEvent(PointerHoverEvent e) { + return fromMouseEvent(e); + } + + public static PointerEnterEvent fromMouseEvent(PointerEvent hover) { + return new PointerEnterEvent( + timeStamp: hover?.timeStamp ?? TimeSpan.Zero, + kind: hover?.kind ?? PointerDeviceKind.touch, + device: hover?.device ?? 0, + position: hover?.position, + delta: hover?.delta, + buttons: hover?.buttons ?? 0, + down: hover?.down ?? false, + obscured: hover?.obscured ?? false, + pressure: hover?.pressure ?? 0.0f, + pressureMin: hover?.pressureMin ?? 1.0f, + pressureMax: hover?.pressureMax ?? 1.0f, + distance: hover?.distance ?? 0.0f, + distanceMax: hover?.distanceMax ?? 0.0f, + size: hover?.size ?? 0.0f, + radiusMajor: hover?.radiusMajor ?? 0.0f, + radiusMinor: hover?.radiusMinor ?? 0.0f, + radiusMin: hover?.radiusMin ?? 0.0f, + radiusMax: hover?.radiusMax ?? 0.0f, + orientation: hover?.orientation ?? 0.0f, + tilt: hover?.tilt ?? 0.0f, + synthesized: hover?.synthesized ?? false + ); + } + } + + public class PointerExitEvent : PointerEvent { + public PointerExitEvent( + TimeSpan timeStamp, + PointerDeviceKind kind = PointerDeviceKind.touch, + int device = 0, + Offset position = null, + Offset delta = null, + int buttons = 0, + bool obscured = false, + float pressure = 0.0f, + float pressureMin = 1.0f, + float pressureMax = 1.0f, + float distance = 0.0f, + float distanceMax = 0.0f, + float size = 0.0f, + float radiusMajor = 0.0f, + float radiusMinor = 0.0f, + float radiusMin = 0.0f, + float radiusMax = 0.0f, + float orientation = 0.0f, + float tilt = 0.0f, + bool synthesized = false, + bool down = false) : base( + timeStamp: timeStamp, + kind: kind, + device: device, + position: position, + delta: delta, + buttons: buttons, + down: down, + obscured: obscured, + pressure: pressure, + pressureMin: pressureMin, + pressureMax: pressureMax, + size: size, + radiusMajor: radiusMajor, + radiusMinor: radiusMinor, + distance: distance, + distanceMax: distanceMax, + radiusMin: radiusMin, + radiusMax: radiusMax, + orientation: orientation, + tilt: tilt, + synthesized: synthesized) { + } + + public static PointerExitEvent fromHoverEvent(PointerHoverEvent e) { + return fromMouseEvent(e); + } + + public static PointerExitEvent fromMouseEvent(PointerEvent hover) { + return new PointerExitEvent( + timeStamp: hover?.timeStamp ?? TimeSpan.Zero, + kind: hover?.kind ?? PointerDeviceKind.touch, + device: hover?.device ?? 0, + position: hover?.position, + delta: hover?.delta, + buttons: hover?.buttons ?? 0, + down: hover?.down ?? false, + obscured: hover?.obscured ?? false, + pressure: hover?.pressure ?? 0.0f, + pressureMin: hover?.pressureMin ?? 1.0f, + pressureMax: hover?.pressureMax ?? 1.0f, + distance: hover?.distance ?? 0.0f, + distanceMax: hover?.distanceMax ?? 0.0f, + size: hover?.size ?? 0.0f, + radiusMajor: hover?.radiusMajor ?? 0.0f, + radiusMinor: hover?.radiusMinor ?? 0.0f, + radiusMin: hover?.radiusMin ?? 0.0f, + radiusMax: hover?.radiusMax ?? 0.0f, + orientation: hover?.orientation ?? 0.0f, + tilt: hover?.tilt ?? 0.0f, + synthesized: hover?.synthesized ?? false + ); + } + } + + public class PointerDownEvent : PointerEvent { + public PointerDownEvent( + TimeSpan timeStamp, + int pointer = 0, + PointerDeviceKind kind = PointerDeviceKind.touch, + int device = 0, + Offset position = null, + int buttons = 0, + bool obscured = false, + float pressure = 0.0f, + float pressureMin = 1.0f, + float pressureMax = 1.0f, + float distance = 0.0f, + float distanceMax = 0.0f, + float size = 0.0f, + float radiusMajor = 0.0f, + float radiusMinor = 0.0f, + float radiusMin = 0.0f, + float radiusMax = 0.0f, + float orientation = 0.0f, + float tilt = 0.0f + ) : base( + timeStamp: timeStamp, + pointer: pointer, + kind: kind, + device: device, + position: position, + buttons: buttons, + down: true, + obscured: obscured, + pressure: pressure, + pressureMin: pressureMin, + pressureMax: pressureMax, + size: size, + radiusMajor: radiusMajor, + radiusMinor: radiusMinor, + distance: distance, + distanceMax: distanceMax, + radiusMin: radiusMin, + radiusMax: radiusMax, + orientation: orientation, + tilt: tilt) { + } + } + + public class PointerMoveEvent : PointerEvent { + public PointerMoveEvent( + TimeSpan timeStamp, + int pointer = 0, + PointerDeviceKind kind = PointerDeviceKind.touch, + int device = 0, + Offset position = null, + Offset delta = null, + int buttons = 0, + bool obscured = false, + float pressure = 0.0f, + float pressureMin = 1.0f, + float pressureMax = 1.0f, + float distance = 0.0f, + float distanceMax = 0.0f, + float size = 0.0f, + float radiusMajor = 0.0f, + float radiusMinor = 0.0f, + float radiusMin = 0.0f, + float radiusMax = 0.0f, + float orientation = 0.0f, + float tilt = 0.0f, + int platformdData = 0, + bool synthesized = false + ) : base( + timeStamp: timeStamp, + pointer: pointer, + kind: kind, + device: device, + position: position, + delta: delta, + buttons: buttons, + down: true, + obscured: obscured, + pressure: pressure, + pressureMin: pressureMin, + pressureMax: pressureMax, + size: size, + radiusMajor: radiusMajor, + radiusMinor: radiusMinor, + distance: distance, + distanceMax: distanceMax, + radiusMin: radiusMin, + radiusMax: radiusMax, + orientation: orientation, + tilt: tilt, + platformData: platformdData, + synthesized: synthesized) { + } + } + + public class PointerUpEvent : PointerEvent { + public PointerUpEvent( + TimeSpan timeStamp, + int pointer = 0, + PointerDeviceKind kind = PointerDeviceKind.touch, + int device = 0, + Offset position = null, + int buttons = 0, + bool obscured = false, + float pressure = 0.0f, + float pressureMin = 1.0f, + float pressureMax = 1.0f, + float distance = 0.0f, + float distanceMax = 0.0f, + float size = 0.0f, + float radiusMajor = 0.0f, + float radiusMinor = 0.0f, + float radiusMin = 0.0f, + float radiusMax = 0.0f, + float orientation = 0.0f, + float tilt = 0.0f + ) : base( + timeStamp: timeStamp, + pointer: pointer, + kind: kind, + device: device, + position: position, + buttons: buttons, + down: false, + obscured: obscured, + pressure: pressure, + pressureMin: pressureMin, + pressureMax: pressureMax, + size: size, + radiusMajor: radiusMajor, + radiusMinor: radiusMinor, + distance: distance, + distanceMax: distanceMax, + radiusMin: radiusMin, + radiusMax: radiusMax, + orientation: orientation, + tilt: tilt) { + } + } + + public class PointerSignalEvent : PointerEvent { + public PointerSignalEvent( TimeSpan timeStamp, int pointer = 0, PointerDeviceKind kind = PointerDeviceKind.mouse, int device = 0, + Offset position = null + ) : base( + timeStamp, + pointer: pointer, + kind: kind, + device: device, + position: position + ) { + } + } + + public class PointerScrollEvent : PointerSignalEvent { + public PointerScrollEvent( + TimeSpan timeStamp, + int pointer, + PointerDeviceKind kind = PointerDeviceKind.mouse, + int device = 0, Offset position = null, - Offset delta = null) + Offset scrollDelta = null) : base( timeStamp, - pointer: pointer, kind: kind, + pointer: pointer, device: device, - position: position, - down: true, - delta: delta) { + position: position) { + D.assert(position != null); + D.assert(scrollDelta != null); + this.scrollDelta = scrollDelta; + } + + public readonly Offset scrollDelta; + + public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { + base.debugFillProperties(properties); + properties.add(new DiagnosticsProperty("scrollDelta", this.scrollDelta)); + } + } + + public class PointerCancelEvent : PointerEvent { + public PointerCancelEvent( + TimeSpan timeStamp, + int pointer = 0, + PointerDeviceKind kind = PointerDeviceKind.touch, + int device = 0, + Offset position = null, + int buttons = 0, + bool obscured = false, + float pressure = 0.0f, + float pressureMin = 1.0f, + float pressureMax = 1.0f, + float distance = 0.0f, + float distanceMax = 0.0f, + float size = 0.0f, + float radiusMajor = 0.0f, + float radiusMinor = 0.0f, + float radiusMin = 0.0f, + float radiusMax = 0.0f, + float orientation = 0.0f, + float tilt = 0.0f + ) : base( + timeStamp: timeStamp, + pointer: pointer, + kind: kind, + device: device, + position: position, + buttons: buttons, + down: false, + obscured: obscured, + pressure: pressure, + pressureMin: pressureMin, + pressureMax: pressureMax, + size: size, + radiusMajor: radiusMajor, + radiusMinor: radiusMinor, + distance: distance, + distanceMax: distanceMax, + radiusMin: radiusMin, + radiusMax: radiusMax, + orientation: orientation, + tilt: tilt) { } } @@ -201,157 +754,4 @@ public static PointerDragFromEditorReleaseEvent fromDragFromEditorEvent(PointerE ); } } - - public class PointerHoverEvent : PointerEvent { - public PointerHoverEvent( - TimeSpan timeStamp, - int pointer = 0, - PointerDeviceKind kind = PointerDeviceKind.mouse, - int device = 0, - Offset position = null) - : base( - timeStamp, - pointer: pointer, - kind: kind, - device: device, - position: position, - down: false) { - } - - public static PointerHoverEvent fromHoverEvent(PointerEvent hover) { - return new PointerHoverEvent( - timeStamp: hover.timeStamp, - pointer: hover.pointer, - kind: hover.kind, - device: hover.device, - position: hover.position - ); - } - } - - public class PointerEnterEvent : PointerEvent { - public PointerEnterEvent( - TimeSpan timeStamp, - int pointer = 0, - PointerDeviceKind kind = PointerDeviceKind.mouse, - int device = 0, - Offset position = null) - : base( - timeStamp, - pointer: pointer, - kind: kind, - device: device, - position: position, - down: false) { - } - - public static PointerEnterEvent fromHoverEvent(PointerEvent hover) { - return new PointerEnterEvent( - timeStamp: hover.timeStamp, - pointer: hover.pointer, - kind: hover.kind, - device: hover.device, - position: hover.position - ); - } - } - - public class PointerExitEvent : PointerEvent { - public PointerExitEvent( - TimeSpan timeStamp, - int pointer = 0, - PointerDeviceKind kind = PointerDeviceKind.mouse, - int device = 0, - Offset position = null) - : base( - timeStamp, - pointer: pointer, - kind: kind, - device: device, - position: position, - down: false) { - } - - public static PointerExitEvent fromHoverEvent(PointerEvent hover) { - return new PointerExitEvent( - timeStamp: hover.timeStamp, - pointer: hover.pointer, - kind: hover.kind, - device: hover.device, - position: hover.position - ); - } - } - - public class PointerDownEvent : PointerEvent { - public PointerDownEvent( - TimeSpan timeStamp, - int pointer = 0, - PointerDeviceKind kind = PointerDeviceKind.mouse, - int device = 0, - Offset position = null) - : base( - timeStamp, - pointer: pointer, - kind: kind, - device: device, - position: position, - down: true) { - } - } - - public class PointerMoveEvent : PointerEvent { - public PointerMoveEvent( - TimeSpan timeStamp, - int pointer = 0, - PointerDeviceKind kind = PointerDeviceKind.mouse, - int device = 0, - Offset position = null, - Offset delta = null, - bool synthesized = false) - : base( - timeStamp, - pointer: pointer, - kind: kind, - device: device, - position: position, - delta: delta, - down: true, - synthesized: synthesized) { - } - } - - public class PointerUpEvent : PointerEvent { - public PointerUpEvent( - TimeSpan timeStamp, - int pointer = 0, - PointerDeviceKind kind = PointerDeviceKind.mouse, - int device = 0, - Offset position = null) - : base( - timeStamp, - pointer: pointer, - kind: kind, - device: device, - position: position, - down: false) { - } - } - - public class PointerCancelEvent : PointerEvent { - public PointerCancelEvent( - TimeSpan timeStamp, - int pointer = 0, - PointerDeviceKind kind = PointerDeviceKind.mouse, - int device = 0, - Offset position = null) - : base( - timeStamp, - pointer: pointer, - kind: kind, - device: device, - position: position, - down: false) { - } - } } \ No newline at end of file diff --git a/Runtime/gestures/long_press.cs b/Runtime/gestures/long_press.cs index b9908f52..fdc81c90 100644 --- a/Runtime/gestures/long_press.cs +++ b/Runtime/gestures/long_press.cs @@ -6,168 +6,123 @@ namespace Unity.UIWidgets.gestures { public delegate void GestureLongPressUpCallback(); - public delegate void GestureLongPressDragStartCallback(GestureLongPressDragStartDetails details); + public delegate void GestureLongPressStartCallback(LongPressStartDetails details); - public delegate void GestureLongPressDragUpdateCallback(GestureLongPressDragUpdateDetails details); + public delegate void GestureLongPressMoveUpdateCallback(LongPressMoveUpdateDetails details); - public delegate void GestureLongPressDragUpCallback(GestureLongPressDragUpDetails details); + public delegate void GestureLongPressEndCallback(LongPressEndDetails details); - public class GestureLongPressDragStartDetails { - public GestureLongPressDragStartDetails( - TimeSpan? sourceTimeStamp = null, + public class LongPressStartDetails { + public LongPressStartDetails( Offset globalPosition = null ) { - this.sourceTimeStamp = sourceTimeStamp; this.globalPosition = globalPosition ?? Offset.zero; } - - public readonly TimeSpan? sourceTimeStamp; - public readonly Offset globalPosition; } - public class GestureLongPressDragUpdateDetails { - public GestureLongPressDragUpdateDetails( - TimeSpan? sourceTimeStamp = null, + public class LongPressMoveUpdateDetails { + public LongPressMoveUpdateDetails( Offset globalPosition = null, Offset offsetFromOrigin = null ) { - this.sourceTimeStamp = sourceTimeStamp; this.globalPosition = globalPosition ?? Offset.zero; this.offsetFromOrigin = offsetFromOrigin ?? Offset.zero; } - public readonly TimeSpan? sourceTimeStamp; - public readonly Offset globalPosition; public readonly Offset offsetFromOrigin; } - public class GestureLongPressDragUpDetails { - public GestureLongPressDragUpDetails( - TimeSpan? sourceTimeStamp = null, + public class LongPressEndDetails { + public LongPressEndDetails( Offset globalPosition = null ) { - this.sourceTimeStamp = sourceTimeStamp; this.globalPosition = globalPosition ?? Offset.zero; } - public readonly TimeSpan? sourceTimeStamp; - public readonly Offset globalPosition; } public class LongPressGestureRecognizer : PrimaryPointerGestureRecognizer { - public LongPressGestureRecognizer(object debugOwner = null, PointerDeviceKind? kind = null) : - base(deadline: Constants.kLongPressTimeout, debugOwner: debugOwner, kind: kind) { - } + public LongPressGestureRecognizer( + float? postAcceptSlopTolerance = null, + object debugOwner = null, + PointerDeviceKind? kind = null) : base( + deadline: Constants.kLongPressTimeout, + postAcceptSlopTolerance: postAcceptSlopTolerance, + kind: kind, + debugOwner: debugOwner) { } bool _longPressAccepted = false; + Offset _longPressOrigin; + public GestureLongPressCallback onLongPress; + public GestureLongPressStartCallback onLongPressStart; + + public GestureLongPressMoveUpdateCallback onLongPressMoveUpdate; + public GestureLongPressUpCallback onLongPressUp; + public GestureLongPressEndCallback onLongPressEnd; + protected override void didExceedDeadline() { this.resolve(GestureDisposition.accepted); this._longPressAccepted = true; - + base.acceptGesture(this.primaryPointer); if (this.onLongPress != null) { this.invokeCallback("onLongPress", () => { this.onLongPress(); return null; }); } - } - protected override void handlePrimaryPointer(PointerEvent evt) { - if (evt is PointerUpEvent) { - if (this._longPressAccepted && this.onLongPressUp != null) { - this._longPressAccepted = false; - this.invokeCallback("onLongPressUp", () => { - this.onLongPressUp(); + if (this.onLongPressStart != null) { + this.invokeCallback("onLongPressStart", + () => { + this.onLongPressStart(new LongPressStartDetails(globalPosition: this._longPressOrigin)); return null; }); - } - else { - this.resolve(GestureDisposition.rejected); - } - } - else if (evt is PointerDownEvent || evt is PointerCancelEvent) { - this._longPressAccepted = false; - } - } - - public override string debugDescription { - get { return "long press"; } - } - } - - public class LongPressDragGestureRecognizer : PrimaryPointerGestureRecognizer { - public LongPressDragGestureRecognizer(object debugOwner = null) : base( - deadline: Constants.kLongPressTimeout, - postAcceptSlopTolerance: null, - debugOwner: debugOwner - ) { - } - - bool _longPressAccepted = false; - - Offset _longPressOrigin; - - TimeSpan? _longPressStartTimestamp; - - public GestureLongPressDragStartCallback onLongPressStart; - - public GestureLongPressDragUpdateCallback onLongPressDragUpdate; - - public GestureLongPressDragUpCallback onLongPressUp; - - protected override void didExceedDeadline() { - this.resolve(GestureDisposition.accepted); - this._longPressAccepted = true; - base.acceptGesture(this.primaryPointer); - if (this.onLongPressStart != null) { - this.invokeCallback("onLongPressStart", () => { - this.onLongPressStart(new GestureLongPressDragStartDetails( - sourceTimeStamp: this._longPressStartTimestamp, - globalPosition: this._longPressOrigin - )); - return null; - }); } } - protected override void handlePrimaryPointer(PointerEvent e) { - if (e is PointerUpEvent) { - if (this._longPressAccepted == true && this.onLongPressUp != null) { - this._longPressAccepted = false; - this.invokeCallback("onLongPressUp", () => { - this.onLongPressUp(new GestureLongPressDragUpDetails( - sourceTimeStamp: e.timeStamp, - globalPosition: e.position - )); - return null; - }); + protected override void handlePrimaryPointer(PointerEvent evt) { + if (evt is PointerUpEvent) { + if (this._longPressAccepted) { + if (this.onLongPressUp != null) { + this.invokeCallback("onLongPressUp", () => { + this.onLongPressUp(); + return null; + }); + } + + if (this.onLongPressEnd != null) { + this.invokeCallback("onLongPressEnd", () => { + this.onLongPressEnd(new LongPressEndDetails(globalPosition: evt.position)); + return null; + }); + } + + this._longPressAccepted = true; } else { this.resolve(GestureDisposition.rejected); } } - else if (e is PointerDownEvent) { + else if (evt is PointerDownEvent || evt is PointerCancelEvent) { this._longPressAccepted = false; - this._longPressStartTimestamp = e.timeStamp; - this._longPressOrigin = e.position; + this._longPressOrigin = evt.position; } - else if (e is PointerMoveEvent && this._longPressAccepted && this.onLongPressDragUpdate != null) { - this.invokeCallback("onLongPressDrag", () => { - this.onLongPressDragUpdate(new GestureLongPressDragUpdateDetails( - sourceTimeStamp: e.timeStamp, - globalPosition: e.position, - offsetFromOrigin: e.position - this._longPressOrigin + else if (evt is PointerMoveEvent && this._longPressAccepted && this.onLongPressMoveUpdate != null) { + this.invokeCallback("onLongPressMoveUpdate", () => { + this.onLongPressMoveUpdate(new LongPressMoveUpdateDetails( + globalPosition: evt.position, + offsetFromOrigin: evt.position - this._longPressOrigin )); return null; }); @@ -177,15 +132,8 @@ protected override void handlePrimaryPointer(PointerEvent e) { public override void acceptGesture(int pointer) { } - protected override void didStopTrackingLastPointer(int pointer) { - this._longPressAccepted = false; - this._longPressOrigin = null; - this._longPressStartTimestamp = null; - base.didStopTrackingLastPointer(pointer); - } - public override string debugDescription { - get { return "long press drag"; } + get { return "long press"; } } } } \ No newline at end of file diff --git a/Runtime/gestures/monodrag.cs b/Runtime/gestures/monodrag.cs index 053e2a79..e736930d 100644 --- a/Runtime/gestures/monodrag.cs +++ b/Runtime/gestures/monodrag.cs @@ -95,7 +95,8 @@ public override void addAllowedPointer(PointerDownEvent evt) { protected override void handleEvent(PointerEvent evt) { D.assert(this._state != _DragState.ready); if (evt is PointerScrollEvent) { - Offset delta = evt.delta; + var scrollEvt = (PointerScrollEvent) evt; + Offset delta = scrollEvt.scrollDelta; if (this.onUpdate != null) { this.invokeCallback("onUpdate", () => { this.onUpdate(new DragUpdateDetails( diff --git a/Runtime/gestures/mouse_tracking.cs b/Runtime/gestures/mouse_tracking.cs index f02786d0..819a3083 100644 --- a/Runtime/gestures/mouse_tracking.cs +++ b/Runtime/gestures/mouse_tracking.cs @@ -109,7 +109,7 @@ public void detachAnnotation(MouseTrackerAnnotation annotation) { foreach (int deviceId in trackedAnnotation.activeDevices) { if (annotation.onExit != null) { annotation.onExit( - PointerExitEvent.fromHoverEvent((PointerHoverEvent) this._lastMouseEvent[deviceId])); + PointerExitEvent.fromMouseEvent(this._lastMouseEvent[deviceId])); } #if UNITY_EDITOR this.detachDragFromEditorAnnotation(annotation, deviceId); @@ -188,7 +188,7 @@ void exitAnnotation(_TrackedAnnotation trackedAnnotation, int deviceId) { if (trackedAnnotation.activeDevices.Contains(deviceId)) { if (trackedAnnotation.annotation?.onExit != null) { trackedAnnotation.annotation.onExit( - PointerExitEvent.fromHoverEvent(this._lastMouseEvent[deviceId])); + PointerExitEvent.fromMouseEvent(this._lastMouseEvent[deviceId])); } trackedAnnotation.activeDevices.Remove(deviceId); @@ -230,13 +230,13 @@ void exitAllDevices(_TrackedAnnotation trackedAnnotation) { if (!hitAnnotation.activeDevices.Contains(deviceId)) { hitAnnotation.activeDevices.Add(deviceId); if (hitAnnotation.annotation?.onEnter != null) { - hitAnnotation.annotation.onEnter(PointerEnterEvent.fromHoverEvent(lastEvent)); + hitAnnotation.annotation.onEnter(PointerEnterEvent.fromMouseEvent(lastEvent)); } } //hover - if (hitAnnotation.annotation?.onHover != null) { - hitAnnotation.annotation.onHover(PointerHoverEvent.fromHoverEvent(lastEvent)); + if (hitAnnotation.annotation?.onHover != null && lastEvent is PointerHoverEvent) { + hitAnnotation.annotation.onHover(lastEvent as PointerHoverEvent); } //leave @@ -248,7 +248,7 @@ void exitAllDevices(_TrackedAnnotation trackedAnnotation) { if (trackedAnnotation.activeDevices.Contains(deviceId)) { if (trackedAnnotation.annotation?.onExit != null) { trackedAnnotation.annotation.onExit( - PointerExitEvent.fromHoverEvent((PointerHoverEvent) lastEvent)); + PointerExitEvent.fromMouseEvent(lastEvent)); } trackedAnnotation.activeDevices.Remove(deviceId); diff --git a/Runtime/gestures/multitap.cs b/Runtime/gestures/multitap.cs index ddadb7a6..86a8ed92 100644 --- a/Runtime/gestures/multitap.cs +++ b/Runtime/gestures/multitap.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using Unity.UIWidgets.async; using Unity.UIWidgets.foundation; @@ -6,6 +7,32 @@ namespace Unity.UIWidgets.gestures { public delegate void GestureDoubleTapCallback(DoubleTapDetails details); + public delegate void GestureMultiTapDownCallback(int pointer, TapDownDetails details); + + public delegate void GestureMultiTapUpCallback(int pointer, TapUpDetails details); + + public delegate void GestureMultiTapCallback(int pointer); + + public delegate void GestureMultiTapCancelCallback(int pointer); + + class _CountdownZoned { + public _CountdownZoned(TimeSpan duration) { + D.assert(duration != null); + this._timer = Window.instance.run(duration, this._onTimeout); + } + + public bool _timeout = false; + public Timer _timer; + + public bool timeout { + get { return this._timeout; } + } + + void _onTimeout() { + this._timeout = true; + } + } + public class DoubleTapDetails { public DoubleTapDetails(Offset firstGlobalPosition = null) { this.firstGlobalPosition = firstGlobalPosition ?? Offset.zero; @@ -16,16 +43,20 @@ public DoubleTapDetails(Offset firstGlobalPosition = null) { class _TapTracker { internal _TapTracker( - PointerDownEvent evt = null, - GestureArenaEntry entry = null) { + PointerDownEvent evt, + TimeSpan doubleTapMinTime, + GestureArenaEntry entry = null + ) { this.pointer = evt.pointer; this._initialPosition = evt.position; + this._doubleTapMinTimeCountdown = new _CountdownZoned(duration: doubleTapMinTime); this.entry = entry; } public readonly int pointer; public readonly GestureArenaEntry entry; internal readonly Offset _initialPosition; + internal readonly _CountdownZoned _doubleTapMinTimeCountdown; bool _isTrackingPointer = false; @@ -36,7 +67,7 @@ public void startTrackingPointer(PointerRoute route) { } } - public void stopTrackingPointer(PointerRoute route) { + public virtual void stopTrackingPointer(PointerRoute route) { if (this._isTrackingPointer) { this._isTrackingPointer = false; GestureBinding.instance.pointerRouter.removeRoute(this.pointer, route); @@ -47,13 +78,16 @@ public bool isWithinTolerance(PointerEvent evt, float tolerance) { Offset offset = evt.position - this._initialPosition; return offset.distance <= tolerance; } + + public bool hasElapsedMinTime() { + return this._doubleTapMinTimeCountdown.timeout; + } } public class DoubleTapGestureRecognizer : GestureRecognizer { public DoubleTapGestureRecognizer(object debugOwner = null, PointerDeviceKind? kind = null) - : base(debugOwner: debugOwner, kind: kind) { - } + : base(debugOwner: debugOwner, kind: kind) { } public GestureDoubleTapCallback onDoubleTap; @@ -70,7 +104,8 @@ public override void addAllowedPointer(PointerDownEvent evt) { this._stopDoubleTapTimer(); _TapTracker tracker = new _TapTracker( evt: evt, - entry: GestureBinding.instance.gestureArena.add(evt.pointer, this) + entry: GestureBinding.instance.gestureArena.add(evt.pointer, this), + doubleTapMinTime: Constants.kDoubleTapMinTime ); this._trackers[evt.pointer] = tracker; tracker.startTrackingPointer(this._handleEvent); @@ -97,8 +132,7 @@ void _handleEvent(PointerEvent evt) { } } - public override void acceptGesture(int pointer) { - } + public override void acceptGesture(int pointer) { } public override void rejectGesture(int pointer) { _TapTracker tracker; @@ -171,6 +205,7 @@ void _clearTrackers() { foreach (var tracker in this._trackers.Values) { this._reject(tracker); } + D.assert(this._trackers.isEmpty()); } @@ -195,4 +230,194 @@ public override string debugDescription { get { return "double tap"; } } } + + class _TapGesture : _TapTracker { + public _TapGesture( + MultiTapGestureRecognizer gestureRecognizer, + PointerEvent evt, + TimeSpan longTapDelay + ) : base( + evt: (PointerDownEvent) evt, + entry: GestureBinding.instance.gestureArena.add(evt.pointer, gestureRecognizer), + doubleTapMinTime: Constants.kDoubleTapMinTime + ) { + this.gestureRecognizer = gestureRecognizer; + this._lastPosition = evt.position; + this.startTrackingPointer(this.handleEvent); + if (longTapDelay > TimeSpan.Zero) { + this._timer = Window.instance.run(longTapDelay, () => { + this._timer = null; + this.gestureRecognizer._dispatchLongTap(evt.pointer, this._lastPosition); + }); + } + } + + public readonly MultiTapGestureRecognizer gestureRecognizer; + + bool _wonArena = false; + Timer _timer; + + Offset _lastPosition; + Offset _finalPosition; + + void handleEvent(PointerEvent evt) { + D.assert(evt.pointer == this.pointer); + if (evt is PointerMoveEvent) { + if (!this.isWithinTolerance(evt, Constants.kTouchSlop)) { + this.cancel(); + } + else { + this._lastPosition = evt.position; + } + } + else if (evt is PointerCancelEvent) { + this.cancel(); + } + else if (evt is PointerUpEvent) { + this.stopTrackingPointer(this.handleEvent); + this._finalPosition = evt.position; + this._check(); + } + } + + public override void stopTrackingPointer(PointerRoute route) { + this._timer?.cancel(); + this._timer = null; + base.stopTrackingPointer(route); + } + + public void accept() { + this._wonArena = true; + this._check(); + } + + public void reject() { + this.stopTrackingPointer(this.handleEvent); + this.gestureRecognizer._dispatchCancel(this.pointer); + } + + public void cancel() { + if (this._wonArena) { + this.reject(); + } + else { + this.entry.resolve(GestureDisposition.rejected); + } + } + + void _check() { + if (this._wonArena && this._finalPosition != null) { + this.gestureRecognizer._dispatchTap(this.pointer, this._finalPosition); + } + } + } + + public class MultiTapGestureRecognizer : GestureRecognizer { + public MultiTapGestureRecognizer( + TimeSpan? longTapDelay = null, + object debugOwner = null, + PointerDeviceKind? kind = null + ) : base(debugOwner: debugOwner, kind: kind) { + this.longTapDelay = longTapDelay ?? TimeSpan.Zero; + } + + public GestureMultiTapDownCallback onTapDown; + + public GestureMultiTapUpCallback onTapUp; + + public GestureMultiTapCallback onTap; + + public GestureMultiTapCancelCallback onTapCancel; + + public TimeSpan longTapDelay; + + public GestureMultiTapDownCallback onLongTapDown; + + readonly Dictionary _gestureMap = new Dictionary(); + + public override void addAllowedPointer(PointerDownEvent evt) { + D.assert(!this._gestureMap.ContainsKey(evt.pointer)); + this._gestureMap[evt.pointer] = new _TapGesture( + gestureRecognizer: this, + evt: evt, + longTapDelay: this.longTapDelay + ); + if (this.onTapDown != null) { + this.invokeCallback("onTapDown", () => { + this.onTapDown(evt.pointer, new TapDownDetails(globalPosition: evt.position)); + return null; + }); + } + } + + public override void acceptGesture(int pointer) { + D.assert(this._gestureMap.ContainsKey(pointer)); + this._gestureMap[pointer].accept(); + } + + public override void rejectGesture(int pointer) { + D.assert(this._gestureMap.ContainsKey(pointer)); + this._gestureMap[pointer].reject(); + D.assert(!this._gestureMap.ContainsKey(pointer)); + } + + public void _dispatchCancel(int pointer) { + D.assert(this._gestureMap.ContainsKey(pointer)); + this._gestureMap.Remove(pointer); + if (this.onTapCancel != null) { + this.invokeCallback("onTapCancel", () => { + this.onTapCancel(pointer); + return null; + }); + } + } + + public void _dispatchTap(int pointer, Offset globalPosition) { + D.assert(this._gestureMap.ContainsKey(pointer)); + this._gestureMap.Remove(pointer); + if (this.onTapUp != null) { + this.invokeCallback("onTapUp", + () => { + this.onTapUp(pointer, new TapUpDetails(globalPosition: globalPosition)); + return null; + }); + } + + if (this.onTap != null) { + this.invokeCallback("onTap", () => { + this.onTap(pointer); + return null; + }); + } + } + + public void _dispatchLongTap(int pointer, Offset lastPosition) { + D.assert(this._gestureMap.ContainsKey(pointer)); + if (this.onLongTapDown != null) { + this.invokeCallback("onLongTapDown", + () => { + this.onLongTapDown(pointer, new TapDownDetails(globalPosition: lastPosition)); + return null; + }); + } + } + + public override void dispose() { + List<_TapGesture> localGestures = new List<_TapGesture>(); + foreach (var item in this._gestureMap) { + localGestures.Add(item.Value); + } + + foreach (_TapGesture gesture in localGestures) { + gesture.cancel(); + } + + D.assert(this._gestureMap.isEmpty); + base.dispose(); + } + + public override string debugDescription { + get { return "multitap"; } + } + } } \ No newline at end of file diff --git a/Runtime/gestures/pointer_router.cs b/Runtime/gestures/pointer_router.cs index c8db6c4a..f78439ec 100644 --- a/Runtime/gestures/pointer_router.cs +++ b/Runtime/gestures/pointer_router.cs @@ -25,6 +25,10 @@ public void removeRoute(int pointer, PointerRoute route) { this._routeMap.Remove(pointer); } } + + public bool acceptScroll() { + return this._routeMap.Count == 0; + } public void clearScrollRoute(int pointer) { if (this._routeMap.ContainsKey(pointer)) { diff --git a/Runtime/gestures/pointer_signal_resolver.cs b/Runtime/gestures/pointer_signal_resolver.cs new file mode 100644 index 00000000..caacf2bc --- /dev/null +++ b/Runtime/gestures/pointer_signal_resolver.cs @@ -0,0 +1,51 @@ +using System; +using Unity.UIWidgets.foundation; + +namespace Unity.UIWidgets.gestures { + public delegate void PointerSignalResolvedCallback(PointerSignalEvent evt); + + public class PointerSignalResolver { + PointerSignalResolvedCallback _firstRegisteredCallback; + + PointerSignalEvent _currentEvent; + + public void register(PointerSignalEvent evt, PointerSignalResolvedCallback callback) { + D.assert(evt != null); + D.assert(callback != null); + D.assert(this._currentEvent == null || this._currentEvent == evt); + if (this._firstRegisteredCallback != null) { + return; + } + + this._currentEvent = evt; + this._firstRegisteredCallback = callback; + } + + public void resolve(PointerSignalEvent evt) { + if (this._firstRegisteredCallback == null) { + D.assert(this._currentEvent == null); + return; + } + + D.assert(this._currentEvent == evt); + try { + this._firstRegisteredCallback(evt); + } + catch (Exception exception) { + UIWidgetsError.reportError(new UIWidgetsErrorDetails( + exception: exception, + library: "gesture library", + context: "while resolving a PointerSignalEvent", + informationCollector: information => { + information.AppendLine("Event: "); + information.AppendFormat(" {0}", evt); + } + ) + ); + } + + this._firstRegisteredCallback = null; + this._currentEvent = null; + } + } +} \ No newline at end of file diff --git a/Runtime/gestures/pointer_signal_resolver.cs.meta b/Runtime/gestures/pointer_signal_resolver.cs.meta new file mode 100644 index 00000000..483ad87d --- /dev/null +++ b/Runtime/gestures/pointer_signal_resolver.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 95a50dc2c902d46c5aea687bc4ecd1b8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/gestures/recognizer.cs b/Runtime/gestures/recognizer.cs index de51c165..722e5f45 100644 --- a/Runtime/gestures/recognizer.cs +++ b/Runtime/gestures/recognizer.cs @@ -37,7 +37,7 @@ public void addPointer(PointerDownEvent evt) { protected virtual void handleNonAllowedPointer(PointerDownEvent evt) { } - protected bool isPointerAllowed(PointerDownEvent evt) { + protected virtual bool isPointerAllowed(PointerDownEvent evt) { return this._kind == null || this._kind == evt.kind; } diff --git a/Runtime/gestures/scale.cs b/Runtime/gestures/scale.cs index a1d5b3b0..d8262c84 100644 --- a/Runtime/gestures/scale.cs +++ b/Runtime/gestures/scale.cs @@ -115,8 +115,8 @@ public _LineBetweenPointers( public class ScaleGestureRecognizer : OneSequenceGestureRecognizer { - public ScaleGestureRecognizer(object debugOwner) : base(debugOwner: debugOwner) { - } + public ScaleGestureRecognizer(object debugOwner, PointerDeviceKind? kind = null) : base(debugOwner: debugOwner, + kind: kind) { } public GestureScaleStartCallback onStart; @@ -409,4 +409,4 @@ public override string debugDescription { get { return "scale"; } } } -} +} \ No newline at end of file diff --git a/Runtime/gestures/tap.cs b/Runtime/gestures/tap.cs index 6dc833d1..8117b3cd 100644 --- a/Runtime/gestures/tap.cs +++ b/Runtime/gestures/tap.cs @@ -3,21 +3,45 @@ namespace Unity.UIWidgets.gestures { public class TapDownDetails { - public TapDownDetails(Offset globalPosition = null) { + public TapDownDetails(Offset globalPosition = null, + Offset localPosition = null, + PointerDeviceKind kind = PointerDeviceKind.touch, + int device = 0) { this.globalPosition = globalPosition ?? Offset.zero; + this.localPosition = localPosition ?? this.globalPosition; + this.kind = kind; + this.device = device; } public readonly Offset globalPosition; + + public readonly Offset localPosition; + + public readonly PointerDeviceKind kind; + + public readonly int device; } public delegate void GestureTapDownCallback(TapDownDetails details); public class TapUpDetails { - public TapUpDetails(Offset globalPosition = null) { + public TapUpDetails(Offset globalPosition = null, + Offset localPosition = null, + PointerDeviceKind kind = PointerDeviceKind.touch, + int device = 0) { this.globalPosition = globalPosition ?? Offset.zero; + this.localPosition = localPosition ?? this.globalPosition; + this.kind = kind; + this.device = device; } public readonly Offset globalPosition; + + public readonly Offset localPosition; + + public readonly PointerDeviceKind kind; + + public readonly int device; } public delegate void GestureTapUpCallback(TapUpDetails details); @@ -26,47 +50,56 @@ public TapUpDetails(Offset globalPosition = null) { public delegate void GestureTapCancelCallback(); - public class TapGestureRecognizer : PrimaryPointerGestureRecognizer { - public TapGestureRecognizer(object debugOwner = null) - : base(deadline: Constants.kPressTimeout, debugOwner: debugOwner) { - } - public GestureTapDownCallback onTapDown; + public abstract class BaseTapGestureRecognizer : PrimaryPointerGestureRecognizer { + public BaseTapGestureRecognizer(object debugOwner = null) + : base(deadline: Constants.kPressTimeout, debugOwner: debugOwner) { + + } - public GestureTapUpCallback onTapUp; + bool _sentTapDown = false; + bool _wonArenaForPrimaryPointer = false; - public GestureTapCallback onTap; + PointerDownEvent _down; + PointerUpEvent _up; - public GestureTapCancelCallback onTapCancel; + protected abstract void handleTapDown(PointerDownEvent down); - bool _sentTapDown = false; + protected abstract void handleTapUp(PointerDownEvent down, PointerUpEvent up); - bool _wonArenaForPrimaryPointer = false; + protected abstract void handleTapCancel(PointerDownEvent down, PointerCancelEvent cancel, string reason); - Offset _finalPosition; + public override void addAllowedPointer(PointerDownEvent evt) { + if (this.state == GestureRecognizerState.ready) { + this._down = evt; + } + base.addAllowedPointer(evt); + } protected override void handlePrimaryPointer(PointerEvent evt) { if (evt is PointerUpEvent) { - this._finalPosition = evt.position; + this._up = (PointerUpEvent) evt; this._checkUp(); - } - else if (evt is PointerCancelEvent) { + } else if (evt is PointerCancelEvent) { + this.resolve(GestureDisposition.rejected); + if (this._sentTapDown) { + this._checkCancel((PointerCancelEvent) evt, ""); + } + this._reset(); + } else if (evt.buttons != this._down?.buttons) { + this.resolve(GestureDisposition.rejected); + this.stopTrackingPointer(this.primaryPointer); } } protected override void resolve(GestureDisposition disposition) { if (this._wonArenaForPrimaryPointer && disposition == GestureDisposition.rejected) { - if (this.onTapCancel != null) { - this.invokeCallback("spontaneous onTapCancel", () => { - this.onTapCancel(); - return null; - }); - } - + D.assert(this._sentTapDown); + this._checkCancel(null, "spontaneous"); this._reset(); } - + base.resolve(disposition); } @@ -76,6 +109,7 @@ protected override void didExceedDeadline() { public override void acceptGesture(int pointer) { base.acceptGesture(pointer); + if (pointer == this.primaryPointer) { this._checkDown(); this._wonArenaForPrimaryPointer = true; @@ -86,11 +120,9 @@ public override void acceptGesture(int pointer) { public override void rejectGesture(int pointer) { base.rejectGesture(pointer); if (pointer == this.primaryPointer) { - if (this.onTapCancel != null) { - this.invokeCallback("forced onTapCancel", () => { - this.onTapCancel(); - return null; - }); + D.assert(this.state != GestureRecognizerState.possible); + if (this._sentTapDown) { + this._checkCancel(null, "forced"); } this._reset(); @@ -98,62 +130,125 @@ public override void rejectGesture(int pointer) { } void _checkDown() { - if (!this._sentTapDown) { - if (this.onTapDown != null) { - this.invokeCallback("onTapDown", () => { - this.onTapDown(new TapDownDetails(globalPosition: this.initialPosition)); - return null; - }); - } - - this._sentTapDown = true; + if (this._sentTapDown) { + return; } + + this.handleTapDown(down: this._down); + this._sentTapDown = true; } void _checkUp() { - if (this._wonArenaForPrimaryPointer && this._finalPosition != null) { - this.resolve(GestureDisposition.accepted); - if (!this._wonArenaForPrimaryPointer || this._finalPosition == null) { - return; - } - - if (this.onTapUp != null) { - this.invokeCallback("onTapUp", () => { - this.onTapUp(new TapUpDetails(globalPosition: this._finalPosition)); - return null; - }); - } - - if (this.onTap != null) { - this.invokeCallback("onTap", () => { - this.onTap(); - return null; - }); - } - - this._reset(); + if (!this._wonArenaForPrimaryPointer || this._up == null) { + return; } + this.handleTapUp(down: this._down, up: this._up); + this._reset(); + } + + void _checkCancel(PointerCancelEvent evt, string note) { + this.handleTapCancel(down: this._down, cancel: evt, reason: note); } void _reset() { this._sentTapDown = false; this._wonArenaForPrimaryPointer = false; - this._finalPosition = null; + this._up = null; + this._down = null; } - + public override string debugDescription { - get { return "tap"; } + get { return "base tap"; } } - + public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { base.debugFillProperties(properties); - properties.add(new FlagProperty("wonArenaForPrimaryPointer", - value: this._wonArenaForPrimaryPointer, - ifTrue: "won arena")); - properties.add(new DiagnosticsProperty("finalPosition", - this._finalPosition, defaultValue: Diagnostics.kNullDefaultValue)); - properties.add(new FlagProperty("sentTapDown", - value: this._sentTapDown, ifTrue: "sent tap down")); + properties.add(new FlagProperty("wonArenaForPrimaryPointer", value: this._wonArenaForPrimaryPointer, ifTrue: "won arena")); + properties.add(new DiagnosticsProperty("finalPosition", this._up?.position, defaultValue: null)); + properties.add(new DiagnosticsProperty("finalLocalPosition", this._up?.position, defaultValue: this._up?.position)); + properties.add(new DiagnosticsProperty("button", this._down?.buttons?? 0, defaultValue: 0)); + properties.add(new FlagProperty("sentTapDown", value: this._sentTapDown, ifTrue: "sent tap down")); + } + } + + public class TapGestureRecognizer : BaseTapGestureRecognizer { + public TapGestureRecognizer(object debugOwner = null) : base(debugOwner: debugOwner) { + } + + public GestureTapDownCallback onTapDown; + + public GestureTapUpCallback onTapUp; + + public GestureTapCallback onTap; + + public GestureTapCancelCallback onTapCancel; + + public GestureTapDownCallback onSecondaryTapDown; + + public GestureTapUpCallback onSecondaryTapUp; + + public GestureTapCancelCallback onSecondaryTapCancel; + + protected override bool isPointerAllowed(PointerDownEvent evt) { + if (this.onTapDown == null && + this.onTap == null && + this.onTapUp == null && + this.onTapCancel == null) { + return false; + } + + return base.isPointerAllowed(evt); + } + + protected override void handleTapDown(PointerDownEvent down) { + + if (this.onTapDown != null) { + TapDownDetails details = new TapDownDetails( + globalPosition: down.position, + kind: down.kind, + device: down.device + ); + + this.invokeCallback("onTapDown", () => { + this.onTapDown(details); + return null; + }); + } + } + + protected override void handleTapUp(PointerDownEvent down, PointerUpEvent up) { + TapUpDetails details = new TapUpDetails( + globalPosition: up.position, + kind: up.kind, + device: up.device + ); + + if (this.onTapUp != null) { + this.invokeCallback("onTapUp", () => { + this.onTapUp(details); + return null; + }); + } + + if (this.onTap != null) { + this.invokeCallback("onTap", () => { + this.onTap(); + return null; + }); + } + } + + protected override void handleTapCancel(PointerDownEvent down, PointerCancelEvent cancel, string note) { + if (this.onTapCancel != null) { + this.invokeCallback("onTapCancel", () => { + this.onTapCancel(); + return null; + }); + } + } + + public override string debugDescription { + get { return "tap"; } } } } \ No newline at end of file diff --git a/Runtime/material/app.cs b/Runtime/material/app.cs index 910d2c3c..5cac48b1 100644 --- a/Runtime/material/app.cs +++ b/Runtime/material/app.cs @@ -1,9 +1,12 @@ using System.Collections.Generic; using Unity.UIWidgets.animation; +using Unity.UIWidgets.cupertino; using Unity.UIWidgets.foundation; using Unity.UIWidgets.service; using Unity.UIWidgets.ui; using Unity.UIWidgets.widgets; +using Color = Unity.UIWidgets.ui.Color; +using Rect = Unity.UIWidgets.ui.Rect; using TextStyle = Unity.UIWidgets.painting.TextStyle; namespace Unity.UIWidgets.material { @@ -36,7 +39,7 @@ public MaterialApp( ThemeData theme = null, ThemeData darkTheme = null, Locale locale = null, - List> localizationsDelegates = null, + List localizationsDelegates = null, LocaleListResolutionCallback localeListResolutionCallback = null, LocaleResolutionCallback localeResolutionCallback = null, List supportedLocales = null, @@ -89,7 +92,7 @@ public MaterialApp( public readonly Locale locale; - public readonly List> localizationsDelegates; + public readonly List localizationsDelegates; public readonly LocaleListResolutionCallback localeListResolutionCallback; @@ -106,13 +109,19 @@ public override State createState() { class _MaterialAppState : State { + HeroController _heroController; + public override void initState() { base.initState(); + this._heroController = new HeroController(createRectTween: this._createRectTween); this._updateNavigator(); } public override void didUpdateWidget(StatefulWidget oldWidget) { base.didUpdateWidget(oldWidget); + if (this.widget.navigatorKey != (oldWidget as MaterialApp).navigatorKey) { + this._heroController = new HeroController(createRectTween: this._createRectTween); + } this._updateNavigator(); } @@ -124,9 +133,10 @@ void _updateNavigator() { this.widget.onGenerateRoute != null || this.widget.onUnknownRoute != null) { this._navigatorObservers = new List(this.widget.navigatorObservers); + this._navigatorObservers.Add(this._heroController); } else { - this._navigatorObservers = null; + this._navigatorObservers = new List(); } } @@ -136,12 +146,12 @@ RectTween _createRectTween(Rect begin, Rect end) { List _localizationsDelegates { get { - List> _delegates = - new List>(); + var _delegates = new List(); if (this.widget.localizationsDelegates != null) { _delegates.AddRange(this.widget.localizationsDelegates); } - + + _delegates.Add(DefaultCupertinoLocalizations.del); _delegates.Add(DefaultMaterialLocalizations.del); return new List(_delegates); } diff --git a/Runtime/material/app_bar.cs b/Runtime/material/app_bar.cs index 831d4476..673043be 100644 --- a/Runtime/material/app_bar.cs +++ b/Runtime/material/app_bar.cs @@ -47,9 +47,11 @@ public AppBar( Widget flexibleSpace = null, PreferredSizeWidget bottom = null, float? elevation = null, + ShapeBorder shape = null, Color backgroundColor = null, Brightness? brightness = null, IconThemeData iconTheme = null, + IconThemeData actionsIconTheme = null, TextTheme textTheme = null, bool primary = true, bool? centerTitle = null, @@ -65,9 +67,11 @@ public AppBar( this.flexibleSpace = flexibleSpace; this.bottom = bottom; this.elevation = elevation; + this.shape = shape; this.backgroundColor = backgroundColor; this.brightness = brightness; this.iconTheme = iconTheme; + this.actionsIconTheme = actionsIconTheme; this.textTheme = textTheme; this.primary = primary; this.centerTitle = centerTitle; @@ -91,12 +95,16 @@ public AppBar( public readonly float? elevation; + public readonly ShapeBorder shape; + public readonly Color backgroundColor; public readonly Brightness? brightness; public readonly IconThemeData iconTheme; + public readonly IconThemeData actionsIconTheme; + public readonly TextTheme textTheme; public readonly bool primary; @@ -153,9 +161,12 @@ public override Widget build(BuildContext context) { bool canPop = parentRoute?.canPop ?? false; bool useCloseButton = parentRoute is PageRoute && ((PageRoute) parentRoute).fullscreenDialog; - IconThemeData appBarIconTheme = this.widget.iconTheme + IconThemeData overallIconTheme = this.widget.iconTheme ?? appBarTheme.iconTheme ?? themeData.primaryIconTheme; + IconThemeData actionsIconTheme = this.widget.actionsIconTheme + ?? appBarTheme.actionsIconTheme + ?? overallIconTheme; TextStyle centerStyle = this.widget.textTheme?.title ?? appBarTheme.textTheme?.title ?? themeData.primaryTextTheme.title; @@ -174,8 +185,11 @@ public override Widget build(BuildContext context) { sideStyle = sideStyle.copyWith(color: sideStyle.color.withOpacity(opacity)); } - appBarIconTheme = appBarIconTheme.copyWith( - opacity: opacity * (appBarIconTheme.opacity ?? 1.0f) + overallIconTheme = overallIconTheme.copyWith( + opacity: opacity * (overallIconTheme.opacity ?? 1.0f) + ); + actionsIconTheme = actionsIconTheme.copyWith( + opacity: opacity * (actionsIconTheme.opacity ?? 1.0f) ); } @@ -223,6 +237,13 @@ public override Widget build(BuildContext context) { tooltip: MaterialLocalizations.of(context).openAppDrawerTooltip); } + if (actions != null) { + actions = IconTheme.merge( + data: actionsIconTheme, + child: actions + ); + } + Widget toolbar = new NavigationToolbar( leading: leading, middle: title, @@ -234,7 +255,7 @@ public override Widget build(BuildContext context) { child: new CustomSingleChildLayout( layoutDelegate: new _ToolbarContainerLayout(), child: IconTheme.merge( - data: appBarIconTheme, + data: overallIconTheme, child: new DefaultTextStyle( style: sideStyle, child: toolbar) @@ -299,6 +320,7 @@ public override Widget build(BuildContext context) { elevation: this.widget.elevation ?? appBarTheme.elevation ?? _defaultElevation, + shape: this.widget.shape, child: appBar )); } @@ -379,6 +401,7 @@ public _SliverAppBarDelegate( Color backgroundColor, Brightness? brightness, IconThemeData iconTheme, + IconThemeData actionsIconTheme, TextTheme textTheme, bool primary, bool? centerTitle, @@ -402,6 +425,7 @@ FloatingHeaderSnapConfiguration snapConfiguration this.backgroundColor = backgroundColor; this.brightness = brightness; this.iconTheme = iconTheme; + this.actionsIconTheme = actionsIconTheme; this.textTheme = textTheme; this.primary = primary; this.centerTitle = centerTitle; @@ -426,6 +450,7 @@ FloatingHeaderSnapConfiguration snapConfiguration public readonly Color backgroundColor; public readonly Brightness? brightness; public readonly IconThemeData iconTheme; + public readonly IconThemeData actionsIconTheme; public readonly TextTheme textTheme; public readonly bool primary; public readonly bool? centerTitle; @@ -506,6 +531,7 @@ public override bool shouldRebuild(SliverPersistentHeaderDelegate _oldDelegate) || this.backgroundColor != oldDelegate.backgroundColor || this.brightness != oldDelegate.brightness || this.iconTheme != oldDelegate.iconTheme + || this.actionsIconTheme != oldDelegate.actionsIconTheme || this.textTheme != oldDelegate.textTheme || this.primary != oldDelegate.primary || this.centerTitle != oldDelegate.centerTitle @@ -537,6 +563,7 @@ public SliverAppBar( Color backgroundColor = null, Brightness? brightness = null, IconThemeData iconTheme = null, + IconThemeData actionsIconTheme = null, TextTheme textTheme = null, bool primary = true, bool? centerTitle = null, @@ -558,6 +585,7 @@ public SliverAppBar( this.backgroundColor = backgroundColor; this.brightness = brightness; this.iconTheme = iconTheme; + this.actionsIconTheme = actionsIconTheme; this.textTheme = textTheme; this.primary = primary; this.centerTitle = centerTitle; @@ -590,6 +618,8 @@ public SliverAppBar( public readonly Brightness? brightness; public readonly IconThemeData iconTheme; + + public readonly IconThemeData actionsIconTheme; public readonly TextTheme textTheme; @@ -666,6 +696,7 @@ public override Widget build(BuildContext context) { backgroundColor: this.widget.backgroundColor, brightness: this.widget.brightness, iconTheme: this.widget.iconTheme, + actionsIconTheme: this.widget.actionsIconTheme, textTheme: this.widget.textTheme, primary: this.widget.primary, centerTitle: this.widget.centerTitle, diff --git a/Runtime/material/app_bar_theme.cs b/Runtime/material/app_bar_theme.cs index 1ad4ec54..1337af6e 100644 --- a/Runtime/material/app_bar_theme.cs +++ b/Runtime/material/app_bar_theme.cs @@ -10,12 +10,14 @@ public AppBarTheme( Color color = null, float? elevation = null, IconThemeData iconTheme = null, + IconThemeData actionsIconTheme = null, TextTheme textTheme = null ) { this.brightness = brightness; this.color = color; this.elevation = elevation; this.iconTheme = iconTheme; + this.actionsIconTheme = actionsIconTheme; this.textTheme = textTheme; } @@ -27,6 +29,8 @@ public AppBarTheme( public readonly IconThemeData iconTheme; + public readonly IconThemeData actionsIconTheme; + public readonly TextTheme textTheme; AppBarTheme copyWith( @@ -34,6 +38,7 @@ AppBarTheme copyWith( Color color = null, float? elevation = null, IconThemeData iconTheme = null, + IconThemeData actionsIconTheme = null, TextTheme textTheme = null ) { return new AppBarTheme( @@ -41,6 +46,7 @@ AppBarTheme copyWith( color: color ?? this.color, elevation: elevation ?? this.elevation, iconTheme: iconTheme ?? this.iconTheme, + actionsIconTheme: actionsIconTheme ?? this.actionsIconTheme, textTheme: textTheme ?? this.textTheme ); } @@ -55,6 +61,7 @@ public static AppBarTheme lerp(AppBarTheme a, AppBarTheme b, float t) { color: Color.lerp(a?.color, b?.color, t), elevation: MathUtils.lerpFloat(a?.elevation ?? 0.0f, b?.elevation ?? 0.0f, t), iconTheme: IconThemeData.lerp(a?.iconTheme, b?.iconTheme, t), + actionsIconTheme: IconThemeData.lerp(a?.actionsIconTheme, b?.actionsIconTheme, t), textTheme: TextTheme.lerp(a?.textTheme, b?.textTheme, t) ); } @@ -64,6 +71,7 @@ public override int GetHashCode() { hashCode = (hashCode * 397) ^ this.color?.GetHashCode() ?? 0; hashCode = (hashCode * 397) ^ this.elevation?.GetHashCode() ?? 0; hashCode = (hashCode * 397) ^ this.iconTheme?.GetHashCode() ?? 0; + hashCode = (hashCode * 397) ^ this.actionsIconTheme?.GetHashCode() ?? 0; hashCode = (hashCode * 397) ^ this.textTheme?.GetHashCode() ?? 0; return hashCode; } @@ -97,6 +105,7 @@ public bool Equals(AppBarTheme other) { && other.color == this.color && other.elevation == this.elevation && other.iconTheme == this.iconTheme + && other.actionsIconTheme == this.actionsIconTheme && other.textTheme == this.textTheme; } @@ -106,6 +115,7 @@ public override void debugFillProperties(DiagnosticPropertiesBuilder properties) properties.add(new DiagnosticsProperty("color", this.color, defaultValue: null)); properties.add(new DiagnosticsProperty("elevation", this.elevation, defaultValue: null)); properties.add(new DiagnosticsProperty("iconTheme", this.iconTheme, defaultValue: null)); + properties.add(new DiagnosticsProperty("actionsIconTheme", this.actionsIconTheme, defaultValue: null)); properties.add(new DiagnosticsProperty("textTheme", this.textTheme, defaultValue: null)); } } diff --git a/Runtime/material/bottom_navigation_bar.cs b/Runtime/material/bottom_navigation_bar.cs index cee2ac35..d50dcfc2 100644 --- a/Runtime/material/bottom_navigation_bar.cs +++ b/Runtime/material/bottom_navigation_bar.cs @@ -18,13 +18,6 @@ using Transform = Unity.UIWidgets.widgets.Transform; namespace Unity.UIWidgets.material { - class BottomNavigationBarUtils { - public const float _kActiveFontSize = 14.0f; - public const float _kInactiveFontSize = 12.0f; - public const float _kTopMargin = 6.0f; - public const float _kBottomMargin = 8.0f; - } - public enum BottomNavigationBarType { fix, shifting @@ -36,9 +29,17 @@ public BottomNavigationBar( List items = null, ValueChanged onTap = null, int currentIndex = 0, + float elevation = 8.0f, BottomNavigationBarType? type = null, Color fixedColor = null, - float iconSize = 24.0f + Color backgroundColor = null, + float iconSize = 24.0f, + Color selectedItemColor = null, + Color unselectedItemColor = null, + float selectedFontSize = 14.0f, + float unselectedFontSize = 12.0f, + bool showSelectedLabels = true, + bool? showUnselectedLabels = null ) : base(key: key) { D.assert(items != null); D.assert(items.Count >= 2); @@ -46,12 +47,26 @@ public BottomNavigationBar( () => "Every item must have a non-null title" ); D.assert(0 <= currentIndex && currentIndex < items.Count); + D.assert(elevation >= 0.0f); + D.assert(iconSize >= 0.0f); + D.assert(selectedItemColor == null || fixedColor == null, + () => "Either selectedItemColor or fixedColor can be specified, but not both!"); + D.assert(selectedFontSize >= 0.0f); + D.assert(unselectedFontSize >= 0.0f); + type = _type(type, items); this.items = items; this.onTap = onTap; this.currentIndex = currentIndex; + this.elevation = elevation; this.type = type ?? (items.Count <= 3 ? BottomNavigationBarType.fix : BottomNavigationBarType.shifting); - this.fixedColor = fixedColor; + this.backgroundColor = backgroundColor; this.iconSize = iconSize; + this.selectedItemColor = selectedItemColor ?? fixedColor; + this.unselectedItemColor = unselectedItemColor; + this.selectedFontSize = selectedFontSize; + this.unselectedFontSize = unselectedFontSize; + this.showSelectedLabels = showSelectedLabels; + this.showUnselectedLabels = showUnselectedLabels ?? _defaultShowUnselected(_type(type, items)); } public readonly List items; @@ -60,12 +75,54 @@ public BottomNavigationBar( public readonly int currentIndex; + public readonly float elevation; + public readonly BottomNavigationBarType? type; - public readonly Color fixedColor; + public Color fixedColor { + get { return this.selectedItemColor; } + } + + public readonly Color backgroundColor; public readonly float iconSize; + + public readonly Color selectedItemColor; + + public readonly Color unselectedItemColor; + + public readonly float selectedFontSize; + + public readonly float unselectedFontSize; + + public readonly bool showUnselectedLabels; + + public readonly bool showSelectedLabels; + + static BottomNavigationBarType _type( + BottomNavigationBarType? type, + List items + ) { + if (type != null) { + return type.Value; + } + + return items.Count <= 3 ? BottomNavigationBarType.fix : BottomNavigationBarType.shifting; + } + + static bool _defaultShowUnselected(BottomNavigationBarType type) { + switch (type) { + case BottomNavigationBarType.shifting: + return false; + case BottomNavigationBarType.fix: + return true; + } + + D.assert(false); + return false; + } + public override State createState() { return new _BottomNavigationBarState(); } @@ -81,8 +138,17 @@ public _BottomNavigationTile( ColorTween colorTween = null, float? flex = null, bool selected = false, + float? selectedFontSize = null, + float? unselectedFontSize = null, + bool? showSelectedLabels = null, + bool? showUnselectedLabels = null, string indexLabel = null ) { + D.assert(type != null); + D.assert(item != null); + D.assert(animation != null); + D.assert(selectedFontSize != null && selectedFontSize >= 0); + D.assert(unselectedFontSize != null && unselectedFontSize >= 0); this.type = type; this.item = item; this.animation = animation; @@ -91,6 +157,10 @@ public _BottomNavigationTile( this.colorTween = colorTween; this.flex = flex; this.selected = selected; + this.selectedFontSize = selectedFontSize.Value; + this.unselectedFontSize = unselectedFontSize.Value; + this.showSelectedLabels = showSelectedLabels ?? false; + this.showUnselectedLabels = showUnselectedLabels ?? false; this.indexLabel = indexLabel; } @@ -102,19 +172,37 @@ public _BottomNavigationTile( public readonly ColorTween colorTween; public readonly float? flex; public readonly bool selected; + public readonly float selectedFontSize; + public readonly float unselectedFontSize; public readonly string indexLabel; + public readonly bool showSelectedLabels; + public readonly bool showUnselectedLabels; public override Widget build(BuildContext context) { int size; - Widget label; + float bottomPadding = this.selectedFontSize / 2.0f; + float topPadding = this.selectedFontSize / 2.0f; + if (this.showSelectedLabels && !this.showUnselectedLabels) { + bottomPadding = new FloatTween( + begin: 0.0f, + end: this.selectedFontSize / 2.0f + ).evaluate(this.animation); + topPadding = new FloatTween( + begin: this.selectedFontSize, + end: this.selectedFontSize / 2.0f + ).evaluate(this.animation); + } + + if (!this.showSelectedLabels && !this.showUnselectedLabels) { + bottomPadding = 0.0f; + topPadding = this.selectedFontSize; + } switch (this.type) { case BottomNavigationBarType.fix: size = 1; - label = new _FixedLabel(colorTween: this.colorTween, animation: this.animation, item: this.item); break; case BottomNavigationBarType.shifting: size = ((this.flex * 1000.0f) ?? 0.0f).round(); - label = new _ShiftingLabel(animation: this.animation, item: this.item); break; default: throw new Exception("Unknown BottomNavigationBarType: " + this.type); @@ -126,21 +214,31 @@ public override Widget build(BuildContext context) { children: new List { new InkResponse( onTap: this.onTap == null ? (GestureTapCallback) null : () => { this.onTap(); }, - child: new Column( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - mainAxisSize: MainAxisSize.min, - children: new List { - new _TileIcon( - type: this.type, - colorTween: this.colorTween, - animation: this.animation, - iconSize: this.iconSize, - selected: this.selected, - item: this.item - ), - label - } + child: new Padding( + padding: EdgeInsets.only(top: topPadding, bottom: bottomPadding), + child: new Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + mainAxisSize: MainAxisSize.min, + children: new List { + new _TileIcon( + colorTween: this.colorTween, + animation: this.animation, + iconSize: this.iconSize, + selected: this.selected, + item: this.item + ), + new _Label( + colorTween: this.colorTween, + animation: this.animation, + item: this.item, + selectedFontSize: this.selectedFontSize, + unselectedFontSize: this.unselectedFontSize, + showSelectedLabels: this.showSelectedLabels, + showUnselectedLabels: this.showUnselectedLabels + ) + } + ) ) ) } @@ -153,14 +251,14 @@ public override Widget build(BuildContext context) { class _TileIcon : StatelessWidget { public _TileIcon( Key key = null, - BottomNavigationBarType? type = null, ColorTween colorTween = null, Animation animation = null, float? iconSize = null, bool? selected = null, BottomNavigationBarItem item = null ) : base(key: key) { - this.type = type; + D.assert(selected != null); + D.assert(item != null); this.colorTween = colorTween; this.animation = animation; this.iconSize = iconSize; @@ -168,7 +266,6 @@ public _TileIcon( this.item = item; } - BottomNavigationBarType? type; ColorTween colorTween; Animation animation; float? iconSize; @@ -176,31 +273,12 @@ public _TileIcon( BottomNavigationBarItem item; public override Widget build(BuildContext context) { - float tweenStart; - Color iconColor; - switch (this.type) { - case BottomNavigationBarType.fix: - tweenStart = 8.0f; - iconColor = this.colorTween.evaluate(this.animation); - break; - case BottomNavigationBarType.shifting: - tweenStart = 16.0f; - iconColor = Colors.white; - break; - default: - throw new Exception("Unknown BottomNavigationBarType: " + this.type); - } + Color iconColor = this.colorTween.evaluate(this.animation); return new Align( alignment: Alignment.topCenter, heightFactor: 1.0f, child: new Container( - margin: EdgeInsets.only( - top: new FloatTween( - begin: tweenStart, - end: BottomNavigationBarUtils._kTopMargin - ).evaluate(this.animation) - ), child: new IconTheme( data: new IconThemeData( color: iconColor, @@ -213,88 +291,83 @@ public override Widget build(BuildContext context) { } } - class _FixedLabel : StatelessWidget { - public _FixedLabel( + class _Label : StatelessWidget { + public _Label( Key key = null, ColorTween colorTween = null, Animation animation = null, - BottomNavigationBarItem item = null + BottomNavigationBarItem item = null, + float? selectedFontSize = null, + float? unselectedFontSize = null, + bool? showSelectedLabels = null, + bool? showUnselectedLabels = null ) : base(key: key) { + D.assert(colorTween != null); + D.assert(animation != null); + D.assert(item != null); + D.assert(selectedFontSize != null); + D.assert(unselectedFontSize != null); + D.assert(showSelectedLabels != null); + D.assert(showUnselectedLabels != null); this.colorTween = colorTween; this.animation = animation; this.item = item; + this.selectedFontSize = selectedFontSize.Value; + this.unselectedFontSize = unselectedFontSize.Value; + this.showSelectedLabels = showSelectedLabels.Value; + this.showUnselectedLabels = showUnselectedLabels.Value; } - ColorTween colorTween; - Animation animation; - BottomNavigationBarItem item; + public readonly ColorTween colorTween; + public readonly Animation animation; + public readonly BottomNavigationBarItem item; + public readonly float selectedFontSize; + public readonly float unselectedFontSize; + public readonly bool showSelectedLabels; + public readonly bool showUnselectedLabels; public override Widget build(BuildContext context) { - float t = new FloatTween( - begin: BottomNavigationBarUtils._kInactiveFontSize / BottomNavigationBarUtils._kActiveFontSize, - end: 1.0f - ).evaluate(this.animation); - return new Align( - alignment: Alignment.bottomCenter, - heightFactor: 1.0f, - child: new Container( - margin: EdgeInsets.only(bottom: BottomNavigationBarUtils._kBottomMargin), - child: DefaultTextStyle.merge( - style: new TextStyle( - fontSize: BottomNavigationBarUtils._kActiveFontSize, - color: this.colorTween.evaluate(this.animation) - ), - child: new Transform( - transform: Matrix3.makeScale(t), - alignment: Alignment.bottomCenter, - child: this.item.title - ) - ) + float t = new FloatTween(begin: this.unselectedFontSize / this.selectedFontSize, end: 1.0f) + .evaluate(this.animation); + Widget text = DefaultTextStyle.merge( + style: new TextStyle( + fontSize: this.selectedFontSize, + color: this.colorTween.evaluate(this.animation) + ), + child: new Transform( + transform: Matrix3.makeAll(t, 0, 0, + 0, t, 0, + 0, 0, 1), + alignment: Alignment.bottomCenter, + child: this.item.title ) ); - } - } - - class _ShiftingLabel : StatelessWidget { - public _ShiftingLabel( - Key key = null, - Animation animation = null, - BottomNavigationBarItem item = null - ) : base(key: key) { - this.animation = animation; - this.item = item; - } - - Animation animation; - BottomNavigationBarItem item; - - public override Widget build(BuildContext context) { + if (!this.showUnselectedLabels && !this.showSelectedLabels) { + text = new Opacity( + opacity: 0.0f, + child: text + ); + } + else if (!this.showUnselectedLabels) { + text = new FadeTransition( + opacity: this.animation, + child: text + ); + } + else if (!this.showSelectedLabels) { + text = new FadeTransition( + opacity: new FloatTween(begin: 1.0f, end: 0.0f).animate(this.animation), + child: text + ); + } return new Align( alignment: Alignment.bottomCenter, heightFactor: 1.0f, - child: new Container( - margin: EdgeInsets.only( - bottom: new FloatTween( - begin: 2.0f, - end: BottomNavigationBarUtils._kBottomMargin - ).evaluate(this.animation) - ), - child: new FadeTransition( - opacity: this.animation, - child: DefaultTextStyle.merge( - style: new TextStyle( - fontSize: BottomNavigationBarUtils._kActiveFontSize, - color: Colors.white - ), - child: this.item.title - ) - ) - ) + child: new Container(child: text) ); } } - class _BottomNavigationBarState : TickerProviderStateMixin { public List _controllers = new List { }; public List _animations; @@ -426,70 +499,62 @@ public override void didUpdateWidget(StatefulWidget _oldWidget) { List _createTiles() { MaterialLocalizations localizations = MaterialLocalizations.of(this.context); D.assert(localizations != null); - List children = new List { }; + ThemeData themeData = Theme.of(this.context); + Color themeColor; + switch (themeData.brightness) { + case Brightness.light: + themeColor = themeData.primaryColor; + break; + case Brightness.dark: + themeColor = themeData.accentColor; + break; + default: + throw new Exception("Unknown brightness: " + themeData.brightness); + } + + ColorTween colorTween; switch (this.widget.type) { case BottomNavigationBarType.fix: - ThemeData themeData = Theme.of(this.context); - TextTheme textTheme = themeData.textTheme; - Color themeColor; - switch (themeData.brightness) { - case Brightness.light: - themeColor = themeData.primaryColor; - break; - case Brightness.dark: - themeColor = themeData.accentColor; - break; - default: - throw new Exception("Unknown brightness: " + themeData.brightness); - } - - ColorTween colorTween = new ColorTween( - begin: textTheme.caption.color, - end: this.widget.fixedColor ?? themeColor + colorTween = new ColorTween( + begin: this.widget.unselectedItemColor ?? themeData.textTheme.caption.color, + end: this.widget.selectedItemColor ?? this.widget.fixedColor ?? themeColor ); - for (int i = 0; i < this.widget.items.Count; i += 1) { - int index = i; - children.Add( - new _BottomNavigationTile(this.widget.type, this.widget.items[i], this._animations[i], - this.widget.iconSize, - onTap: () => { - if (this.widget.onTap != null) { - this.widget.onTap(index); - } - }, - colorTween: colorTween, - selected: i == this.widget.currentIndex, - indexLabel: localizations.tabLabel(tabIndex: i + 1, - tabCount: this.widget.items.Count) - ) - ); - } - break; case BottomNavigationBarType.shifting: - for (int i = 0; i < this.widget.items.Count; i += 1) { - int index = i; - children.Add( - new _BottomNavigationTile(this.widget.type, this.widget.items[i], this._animations[i], - this.widget.iconSize, - onTap: () => { - if (this.widget.onTap != null) { - this.widget.onTap(index); - } - }, - flex: - this._evaluateFlex(this._animations[i]), - selected: i == this.widget.currentIndex, - indexLabel: localizations.tabLabel(tabIndex: i + 1, - tabCount: this.widget.items.Count) - ) - ); - } - + colorTween = new ColorTween( + begin: this.widget.unselectedItemColor ?? Colors.white, + end: this.widget.selectedItemColor ?? Colors.white + ); break; + default: + throw new UIWidgetsError($"Unknown bottom navigation bar type: {this.widget.type}"); + } + + List tiles = new List(); + for (int i = 0; i < this.widget.items.Count; i++) { + int index = i; + tiles.Add(new _BottomNavigationTile( + this.widget.type, + this.widget.items[i], + this._animations[i], + this.widget.iconSize, + selectedFontSize: this.widget.selectedFontSize, + unselectedFontSize: this.widget.unselectedFontSize, + onTap: () => { + if (this.widget.onTap != null) { + this.widget.onTap(index); + } + }, + colorTween: colorTween, + flex: this._evaluateFlex(this._animations[i]), + selected: i == this.widget.currentIndex, + showSelectedLabels: this.widget.showSelectedLabels, + showUnselectedLabels: this.widget.showUnselectedLabels, + indexLabel: localizations.tabLabel(tabIndex: i+1, tabCount: this.widget.items.Count) + )); } - return children; + return tiles; } Widget _createContainer(List tiles) { @@ -507,10 +572,11 @@ public override Widget build(BuildContext context) { D.assert(MaterialD.debugCheckHasMaterialLocalizations(context)); float additionalBottomPadding = - Mathf.Max(MediaQuery.of(context).padding.bottom - BottomNavigationBarUtils._kBottomMargin, 0.0f); + Mathf.Max(MediaQuery.of(context).padding.bottom - this.widget.selectedFontSize / 2.0f, 0.0f); Color backgroundColor = null; switch (this.widget.type) { case BottomNavigationBarType.fix: + backgroundColor = this.widget.backgroundColor; break; case BottomNavigationBarType.shifting: backgroundColor = this._backgroundColor; @@ -519,7 +585,7 @@ public override Widget build(BuildContext context) { return new Material( - elevation: 8.0f, + elevation: this.widget.elevation, color: backgroundColor, child: new ConstrainedBox( constraints: new BoxConstraints( diff --git a/Runtime/material/button_theme.cs b/Runtime/material/button_theme.cs index 17d3a00f..6025524e 100644 --- a/Runtime/material/button_theme.cs +++ b/Runtime/material/button_theme.cs @@ -279,7 +279,7 @@ public Color getFillColor(MaterialButton button) { return fillColor; } - if (button is FlatButton || button is OutlineButton) { + if (button is FlatButton || button is OutlineButton || button.GetType() == typeof(MaterialButton)) { return null; } diff --git a/Runtime/material/chip.cs b/Runtime/material/chip.cs index 75860859..26d5cdd4 100644 --- a/Runtime/material/chip.cs +++ b/Runtime/material/chip.cs @@ -52,6 +52,8 @@ public interface ChipAttributes { MaterialTapTargetSize? materialTapTargetSize { get; } float? elevation { get; } + + Color shadowColor { get; } } public interface DeletableChipAttributes { @@ -76,6 +78,8 @@ public interface SelectableChipAttributes { string tooltip { get; } ShapeBorder avatarBorder { get; } + + Color selectedShadowColor { get; } } public interface DisabledChipAttributes { @@ -108,7 +112,8 @@ public Chip( Color backgroundColor = null, EdgeInsets padding = null, MaterialTapTargetSize? materialTapTargetSize = null, - float? elevation = null + float? elevation = null, + Color shadowColor = null ) : base(key: key) { D.assert(label != null); D.assert(elevation == null || elevation >= 0.0f); @@ -126,6 +131,7 @@ public Chip( this._padding = padding; this._materialTapTargetSize = materialTapTargetSize; this._elevation = elevation; + this._shadowColor = shadowColor; } public Widget avatar { @@ -212,6 +218,12 @@ public float? elevation { float? _elevation; + public Color shadowColor { + get { return this._shadowColor; } + } + + Color _shadowColor; + public override Widget build(BuildContext context) { D.assert(MaterialD.debugCheckHasMaterial(context)); return new RawChip( @@ -230,6 +242,7 @@ public override Widget build(BuildContext context) { padding: this.padding, materialTapTargetSize: this.materialTapTargetSize, elevation: this.elevation, + shadowColor: this.shadowColor, isEnabled: true ); } @@ -265,6 +278,7 @@ public InputChip( EdgeInsets padding = null, MaterialTapTargetSize? materialTapTargetSize = null, float? elevation = null, + Color shadowColor = null, Color selectedShadowColor = null, ShapeBorder avatarBorder = null ) : base(key: key) { @@ -294,6 +308,8 @@ public InputChip( this._padding = padding; this._materialTapTargetSize = materialTapTargetSize; this._elevation = elevation; + this._shadowColor = shadowColor; + this._selectedShadowColor = selectedShadowColor; } public Widget avatar { @@ -428,6 +444,18 @@ public float? elevation { float? _elevation; + public Color shadowColor { + get { return this._shadowColor; } + } + + Color _shadowColor; + + public Color selectedShadowColor { + get { return this._selectedShadowColor; } + } + + Color _selectedShadowColor; + public ShapeBorder avatarBorder { get { return this._avatarBorder; } } @@ -459,6 +487,8 @@ public override Widget build(BuildContext context) { padding: this.padding, materialTapTargetSize: this.materialTapTargetSize, elevation: this.elevation, + shadowColor: this.shadowColor, + selectedShadowColor: this.selectedShadowColor, isEnabled: this.isEnabled == true && (this.onSelected != null || this.onDeleted != null || this.onPressed != null), avatarBorder: this.avatarBorder @@ -488,6 +518,8 @@ public ChoiceChip( EdgeInsets padding = null, MaterialTapTargetSize? materialTapTargetSize = null, float? elevation = null, + Color shadowColor = null, + Color selectedShadowColor = null, ShapeBorder avatarBorder = null ) : base(key: key) { D.assert(selected != null); @@ -511,6 +543,8 @@ public ChoiceChip( this._padding = padding; this._materialTapTargetSize = materialTapTargetSize; this._elevation = elevation; + this._shadowColor = shadowColor; + this._selectedShadowColor = selectedShadowColor; } public Widget avatar { @@ -609,6 +643,18 @@ public float? elevation { float? _elevation; + public Color shadowColor { + get { return this._shadowColor; } + } + + Color _shadowColor; + + public Color selectedShadowColor { + get { return this._selectedShadowColor; } + } + + Color _selectedShadowColor; + public ShapeBorder avatarBorder { get { return this._avatarBorder; } } @@ -642,6 +688,8 @@ public override Widget build(BuildContext context) { isEnabled: this.isEnabled, materialTapTargetSize: this.materialTapTargetSize, elevation: this.elevation, + shadowColor: this.shadowColor, + selectedShadowColor: this.selectedShadowColor, avatarBorder: this.avatarBorder ); } @@ -669,6 +717,8 @@ public FilterChip( EdgeInsets padding = null, MaterialTapTargetSize? materialTapTargetSize = null, float? elevation = null, + Color shadowColor = null, + Color selectedShadowColor = null, ShapeBorder avatarBorder = null ) : base(key: key) { D.assert(label != null); @@ -691,6 +741,8 @@ public FilterChip( this._padding = padding; this._materialTapTargetSize = materialTapTargetSize; this._elevation = elevation; + this._shadowColor = shadowColor; + this._selectedShadowColor = selectedShadowColor; } public Widget avatar { @@ -789,6 +841,18 @@ public float? elevation { float? _elevation; + public Color shadowColor { + get { return this._shadowColor; } + } + + Color _shadowColor; + + public Color selectedShadowColor { + get { return this._selectedShadowColor; } + } + + Color _selectedShadowColor; + public ShapeBorder avatarBorder { get { return this._avatarBorder; } } @@ -819,6 +883,8 @@ public override Widget build(BuildContext context) { isEnabled: this.isEnabled, materialTapTargetSize: this.materialTapTargetSize, elevation: this.elevation, + shadowColor: this.shadowColor, + selectedShadowColor: this.selectedShadowColor, avatarBorder: this.avatarBorder ); } @@ -839,7 +905,8 @@ public ActionChip( Color backgroundColor = null, EdgeInsets padding = null, MaterialTapTargetSize? materialTapTargetSize = null, - float? elevation = null + float? elevation = null, + Color shadowColor = null ) : base(key: key) { D.assert(label != null); D.assert( @@ -862,6 +929,7 @@ public ActionChip( this._padding = padding; this._materialTapTargetSize = materialTapTargetSize; this._elevation = elevation; + this._shadowColor = shadowColor; } @@ -943,6 +1011,12 @@ public float? elevation { float? _elevation; + public Color shadowColor { + get { return this._shadowColor; } + } + + Color _shadowColor; + public override Widget build(BuildContext context) { D.assert(MaterialD.debugCheckHasMaterial(context)); return new RawChip( @@ -959,7 +1033,8 @@ public override Widget build(BuildContext context) { labelPadding: this.labelPadding, isEnabled: true, materialTapTargetSize: this.materialTapTargetSize, - elevation: this.elevation + elevation: this.elevation, + shadowColor: this._shadowColor ); } } @@ -996,6 +1071,8 @@ public RawChip( Color backgroundColor = null, MaterialTapTargetSize? materialTapTargetSize = null, float? elevation = null, + Color shadowColor = null, + Color selectedShadowColor = null, ShapeBorder avatarBorder = null ) : base(key: key) { D.assert(label != null); @@ -1028,6 +1105,8 @@ public RawChip( this._backgroundColor = backgroundColor; this._materialTapTargetSize = materialTapTargetSize; this._elevation = elevation; + this._shadowColor = shadowColor; + this._selectedShadowColor = selectedShadowColor; } @@ -1163,6 +1242,18 @@ public float? elevation { float? _elevation; + public Color shadowColor { + get { return this._shadowColor; } + } + + Color _shadowColor; + + public Color selectedShadowColor { + get { return this._selectedShadowColor; } + } + + Color _selectedShadowColor; + public ShapeBorder avatarBorder { get { return this._avatarBorder; } } @@ -1426,16 +1517,21 @@ public override Widget build(BuildContext context) { ShapeBorder shape = this.widget.shape ?? chipTheme.shape; float elevation = this.widget.elevation ?? (chipTheme.elevation ?? _defaultElevation); float pressElevation = this.widget.pressElevation ?? (chipTheme.pressElevation ?? _defaultPressElevation); + Color shadowColor = this.widget.shadowColor ?? chipTheme.shadowColor ?? _defaultShadowColor; + Color selectedShadowColor = this.widget.selectedShadowColor ?? chipTheme.selectedShadowColor ?? _defaultShadowColor; + bool selected = this.widget.selected ?? false; Widget result = new Material( elevation: this.isTapping ? pressElevation : elevation, + shadowColor: selected ? selectedShadowColor : shadowColor, animationDuration: pressedAnimationDuration, shape: shape, clipBehavior: this.widget.clipBehavior, - child: new InkResponse( + child: new InkWell( onTap: this.canTap ? this._handleTap : (GestureTapCallback) null, onTapDown: this.canTap ? this._handleTapDown : (GestureTapDownCallback) null, - onTapCancel: this.canTap ? this._handleTapCancel : (GestureTapCallback) null, + onTapCancel: this.canTap ? this._handleTapCancel : (GestureTapCancelCallback) null, + customBorder: shape, child: new AnimatedBuilder( animation: ListenableUtils.merge(new List {this.selectController, this.enableController}), @@ -2008,7 +2104,7 @@ protected override float computeMinIntrinsicHeight(float width) { ); } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { return this.computeMinIntrinsicHeight(width); } @@ -2373,8 +2469,7 @@ public override void paint(PaintingContext context, Offset offset) { const bool _debugShowTapTargetOutlines = false; public override void debugPaint(PaintingContext context, Offset offset) { - D.assert(!_debugShowTapTargetOutlines); - D.assert(() => { + bool visualizeTapTargets() { Paint outlinePaint = new Paint(); outlinePaint.color = new Color(0xff800000); outlinePaint.strokeWidth = 1.0f; @@ -2386,7 +2481,9 @@ public override void debugPaint(PaintingContext context, Offset offset) { outlinePaint.color = new Color(0xff008000); context.canvas.drawRect(this.pressRect.shift(offset), outlinePaint); return true; - }); + } + + D.assert(!_debugShowTapTargetOutlines || visualizeTapTargets()); } protected override bool hitTestSelf(Offset position) { diff --git a/Runtime/material/chip_theme.cs b/Runtime/material/chip_theme.cs index 0c2158f4..4b0a2a6a 100644 --- a/Runtime/material/chip_theme.cs +++ b/Runtime/material/chip_theme.cs @@ -37,6 +37,8 @@ public ChipThemeData( Color disabledColor = null, Color selectedColor = null, Color secondarySelectedColor = null, + Color shadowColor = null, + Color selectedShadowColor = null, EdgeInsets labelPadding = null, EdgeInsets padding = null, ShapeBorder shape = null, @@ -61,6 +63,8 @@ public ChipThemeData( this.disabledColor = disabledColor; this.selectedColor = selectedColor; this.secondarySelectedColor = secondarySelectedColor; + this.shadowColor = shadowColor; + this.selectedShadowColor = selectedShadowColor; this.labelPadding = labelPadding; this.padding = padding; this.shape = shape; @@ -133,6 +137,10 @@ public static ChipThemeData fromDefaults( public readonly Color secondarySelectedColor; + public readonly Color shadowColor; + + public readonly Color selectedShadowColor; + public readonly EdgeInsets labelPadding; public readonly EdgeInsets padding; @@ -155,6 +163,8 @@ public ChipThemeData copyWith( Color disabledColor = null, Color selectedColor = null, Color secondarySelectedColor = null, + Color shadowColor = null, + Color selectedShadowColor = null, EdgeInsets labelPadding = null, EdgeInsets padding = null, ShapeBorder shape = null, @@ -170,6 +180,8 @@ public ChipThemeData copyWith( disabledColor: disabledColor ?? this.disabledColor, selectedColor: selectedColor ?? this.selectedColor, secondarySelectedColor: secondarySelectedColor ?? this.secondarySelectedColor, + shadowColor: shadowColor ?? this.shadowColor, + selectedShadowColor: selectedShadowColor ?? this.selectedShadowColor, labelPadding: labelPadding ?? this.labelPadding, padding: padding ?? this.padding, shape: shape ?? this.shape, @@ -192,6 +204,8 @@ public static ChipThemeData lerp(ChipThemeData a, ChipThemeData b, float t) { disabledColor: Color.lerp(a?.disabledColor, b?.disabledColor, t), selectedColor: Color.lerp(a?.selectedColor, b?.selectedColor, t), secondarySelectedColor: Color.lerp(a?.secondarySelectedColor, b?.secondarySelectedColor, t), + shadowColor: Color.lerp(a?.shadowColor, b?.shadowColor, t), + selectedShadowColor: Color.lerp(a?.selectedShadowColor, b?.selectedShadowColor, t), labelPadding: EdgeInsets.lerp(a?.labelPadding, b?.labelPadding, t), padding: EdgeInsets.lerp(a?.padding, b?.padding, t), shape: ShapeBorder.lerp(a?.shape, b?.shape, t), @@ -209,6 +223,8 @@ public override int GetHashCode() { hashCode = (hashCode * 397) ^ this.disabledColor.GetHashCode(); hashCode = (hashCode * 397) ^ this.selectedColor.GetHashCode(); hashCode = (hashCode * 397) ^ this.secondarySelectedColor.GetHashCode(); + hashCode = (hashCode * 397) ^ this.shadowColor?.GetHashCode() ?? 0; + hashCode = (hashCode * 397) ^ this.selectedShadowColor?.GetHashCode() ?? 0; hashCode = (hashCode * 397) ^ this.labelPadding.GetHashCode(); hashCode = (hashCode * 397) ^ this.padding.GetHashCode(); hashCode = (hashCode * 397) ^ this.shape.GetHashCode(); @@ -226,6 +242,8 @@ public bool Equals(ChipThemeData other) { && other.disabledColor == this.disabledColor && other.selectedColor == this.selectedColor && other.secondarySelectedColor == this.secondarySelectedColor + && other.shadowColor == this.shadowColor + && other.selectedShadowColor == this.selectedShadowColor && other.labelPadding == this.labelPadding && other.padding == this.padding && other.shape == this.shape @@ -278,6 +296,10 @@ public override void debugFillProperties(DiagnosticPropertiesBuilder properties) defaultValue: defaultData.selectedColor)); properties.add(new DiagnosticsProperty("secondarySelectedColor", this.secondarySelectedColor, defaultValue: defaultData.secondarySelectedColor)); + properties.add(new DiagnosticsProperty("shadowColor", this.shadowColor, + defaultValue: defaultData.shadowColor)); + properties.add(new DiagnosticsProperty("selectedShadowColor", this.selectedShadowColor, + defaultValue: defaultData.selectedShadowColor)); properties.add(new DiagnosticsProperty("labelPadding", this.labelPadding, defaultValue: defaultData.labelPadding)); properties.add( diff --git a/Runtime/material/date_picker.cs b/Runtime/material/date_picker.cs new file mode 100644 index 00000000..5ab6aebc --- /dev/null +++ b/Runtime/material/date_picker.cs @@ -0,0 +1,938 @@ +using System; +using System.Collections.Generic; +using com.unity.uiwidgets.Runtime.rendering; +using RSG; +using Unity.UIWidgets.animation; +using Unity.UIWidgets.async; +using Unity.UIWidgets.foundation; +using Unity.UIWidgets.gestures; +using Unity.UIWidgets.painting; +using Unity.UIWidgets.rendering; +using Unity.UIWidgets.service; +using Unity.UIWidgets.ui; +using Unity.UIWidgets.widgets; +using UnityEngine; +using Color = Unity.UIWidgets.ui.Color; +using TextStyle = Unity.UIWidgets.painting.TextStyle; + +/* + * Differences between Dart & C# + * Duration => TimeSpan + * -1 % 4 = 3 => -1 % 4 = -1 + * [Dart] [DateTime.weekday] provides a 1-based index (Start with Monday) + * [C#] [DateTime.DayOfWeek] provides a 0-based index (Start with Sunday) + * @IIzzaya + */ +namespace Unity.UIWidgets.material { + public class DatePickerUtils { + public const float _kDatePickerHeaderPortraitHeight = 100.0f; + public const float _kDatePickerHeaderLandscapeWidth = 168.0f; + public static readonly TimeSpan _kMonthScrollDuration = new TimeSpan(0, 0, 0, 0, 200); + public const float _kDayPickerRowHeight = 42.0f; + public const int _kMaxDayPickerRowCount = 6; + + public const float _kMaxDayPickerHeight = _kDayPickerRowHeight * (_kMaxDayPickerRowCount + 2); + public const float _kMonthPickerPortraitWidth = 330.0f; + public const float _kMonthPickerLandscapeWidth = 344.0f; + public const float _kDialogActionBarHeight = 52.0f; + public const float _kDatePickerLandscapeHeight = _kMaxDayPickerHeight + _kDialogActionBarHeight; + + internal static readonly _DayPickerGridDelegate _kDayPickerGridDelegate = new _DayPickerGridDelegate(); + + public static IPromise showDatePicker( + BuildContext context, + DateTime initialDate, + DateTime firstDate, + DateTime lastDate, + SelectableDayPredicate selectableDayPredicate = null, + DatePickerMode initialDatePickerMode = DatePickerMode.day, + Locale locale = null, + TransitionBuilder builder = null + ) { + D.assert(initialDate >= firstDate, () => "initialDate must be on or after firstDate"); + D.assert(initialDate <= lastDate, () => "initialDate must be on or before lastDate"); + D.assert(firstDate <= lastDate, () => "lastDate must be on or after firstDate"); + D.assert( + selectableDayPredicate == null || selectableDayPredicate(initialDate), + () => "Provided initialDate must satisfy provided selectableDayPredicate" + ); + D.assert(context != null); + D.assert(MaterialD.debugCheckHasMaterialLocalizations(context)); + + Widget child = new _DatePickerDialog( + initialDate: initialDate, + firstDate: firstDate, + lastDate: lastDate, + selectableDayPredicate: selectableDayPredicate, + initialDatePickerMode: initialDatePickerMode + ); + + if (locale != null) { + child = Localizations.overrides( + context: context, + locale: locale, + child: child + ); + } + + return DialogUtils.showDialog( + context: context, + builder: (BuildContext _context) => { return builder == null ? child : builder(_context, child); } + ); + } + } + + public enum DatePickerMode { + day, + year + } + + class _DatePickerHeader : StatelessWidget { + public _DatePickerHeader( + DateTime selectedDate, + DatePickerMode mode, + ValueChanged onModeChanged, + Orientation orientation, + Key key = null + ) : base(key: key) { + this.selectedDate = selectedDate; + this.mode = mode; + this.onModeChanged = onModeChanged; + this.orientation = orientation; + } + + public readonly DateTime selectedDate; + public readonly DatePickerMode mode; + public readonly ValueChanged onModeChanged; + public readonly Orientation orientation; + + void _handleChangeMode(DatePickerMode value) { + if (value != this.mode) { + this.onModeChanged(value); + } + } + + public override Widget build(BuildContext context) { + MaterialLocalizations localizations = MaterialLocalizations.of(context); + ThemeData themeData = Theme.of(context); + TextTheme headerTextTheme = themeData.primaryTextTheme; + Color dayColor = null; + Color yearColor = null; + switch (themeData.primaryColorBrightness) { + case Brightness.light: + dayColor = this.mode == DatePickerMode.day ? Colors.black87 : Colors.black54; + yearColor = this.mode == DatePickerMode.year ? Colors.black87 : Colors.black54; + break; + case Brightness.dark: + dayColor = this.mode == DatePickerMode.day ? Colors.white : Colors.white70; + yearColor = this.mode == DatePickerMode.year ? Colors.white : Colors.white70; + break; + } + + TextStyle dayStyle = headerTextTheme.display1.copyWith(color: dayColor, height: 1.4f); + TextStyle yearStyle = headerTextTheme.subhead.copyWith(color: yearColor, height: 1.4f); + Color backgroundColor = null; + switch (themeData.brightness) { + case Brightness.light: + backgroundColor = themeData.primaryColor; + break; + case Brightness.dark: + backgroundColor = themeData.backgroundColor; + break; + } + + float width = 0f; + float height = 0f; + EdgeInsets padding = null; + MainAxisAlignment mainAxisAlignment = MainAxisAlignment.center; + switch (this.orientation) { + case Orientation.portrait: + height = DatePickerUtils._kDatePickerHeaderPortraitHeight; + padding = EdgeInsets.symmetric(horizontal: 16.0f); + mainAxisAlignment = MainAxisAlignment.center; + break; + case Orientation.landscape: + width = DatePickerUtils._kDatePickerHeaderLandscapeWidth; + padding = EdgeInsets.all(8.0f); + mainAxisAlignment = MainAxisAlignment.start; + break; + } + + Widget yearButton = new IgnorePointer( + ignoring: this.mode != DatePickerMode.day, + child: new _DateHeaderButton( + color: backgroundColor, + onTap: Feedback.wrapForTap(() => this._handleChangeMode(DatePickerMode.year), context), + child: new Text(localizations.formatYear(this.selectedDate), style: yearStyle) + ) + ); + Widget dayButton = new IgnorePointer( + ignoring: this.mode == DatePickerMode.day, + child: new _DateHeaderButton( + color: backgroundColor, + onTap: Feedback.wrapForTap(() => this._handleChangeMode(DatePickerMode.day), context), + child: new Text(localizations.formatMediumDate(this.selectedDate), style: dayStyle) + ) + ); + return new Container( + width: width, + height: height, + padding: padding, + color: backgroundColor, + child: new Column( + mainAxisAlignment: mainAxisAlignment, + crossAxisAlignment: CrossAxisAlignment.start, + children: new List {yearButton, dayButton} + ) + ); + } + } + + class _DateHeaderButton : StatelessWidget { + public _DateHeaderButton( + GestureTapCallback onTap, + Color color, + Widget child, + Key key = null + ) : base(key: key) { + this.onTap = onTap; + this.color = color; + this.child = child; + } + + public readonly GestureTapCallback onTap; + public readonly Color color; + public readonly Widget child; + + public override Widget build(BuildContext context) { + ThemeData theme = Theme.of(context); + return new Material( + type: MaterialType.button, + color: this.color, + child: new InkWell( + borderRadius: MaterialConstantsUtils.kMaterialEdges[MaterialType.button], + highlightColor: theme.highlightColor, + splashColor: theme.splashColor, + onTap: this.onTap, + child: new Container( + padding: EdgeInsets.symmetric(horizontal: 8.0f), + child: this.child + ) + ) + ); + } + } + + class _DayPickerGridDelegate : SliverGridDelegate { + public _DayPickerGridDelegate() { } + + public override SliverGridLayout getLayout(SliverConstraints constraints) { + const int columnCount = 7; // DateTime.daysPerWeek = 7 + float tileWidth = constraints.crossAxisExtent / columnCount; + float tileHeight = Mathf.Min( + DatePickerUtils._kDayPickerRowHeight, + constraints.viewportMainAxisExtent / (DatePickerUtils._kMaxDayPickerRowCount + 1) + ); + return new SliverGridRegularTileLayout( + crossAxisCount: columnCount, + mainAxisStride: tileHeight, + crossAxisStride: tileWidth, + childMainAxisExtent: tileHeight, + childCrossAxisExtent: tileWidth, + reverseCrossAxis: AxisUtils.axisDirectionIsReversed(constraints.crossAxisDirection) + ); + } + + public override bool shouldRelayout(SliverGridDelegate oldDelegate) { + return false; + } + } + + public class DayPicker : StatelessWidget { + public DayPicker( + DateTime selectedDate, + DateTime currentDate, + ValueChanged onChanged, + DateTime firstDate, + DateTime lastDate, + DateTime displayedMonth, + SelectableDayPredicate selectableDayPredicate = null, + DragStartBehavior dragStartBehavior = DragStartBehavior.start, + Key key = null + ) : base(key: key) { + D.assert(onChanged != null); + D.assert(firstDate <= lastDate); + D.assert(selectedDate >= firstDate); + this.selectedDate = selectedDate; + this.currentDate = currentDate; + this.onChanged = onChanged; + this.firstDate = firstDate; + this.lastDate = lastDate; + this.displayedMonth = displayedMonth; + this.selectableDayPredicate = selectableDayPredicate; + this.dragStartBehavior = dragStartBehavior; + } + + public readonly DateTime selectedDate; + public readonly DateTime currentDate; + public readonly ValueChanged onChanged; + public readonly DateTime firstDate; + public readonly DateTime lastDate; + public readonly DateTime displayedMonth; + public readonly SelectableDayPredicate selectableDayPredicate; + public readonly DragStartBehavior dragStartBehavior; + + List _getDayHeaders(TextStyle headerStyle, MaterialLocalizations localizations) { + List result = new List(); + for (int i = localizations.firstDayOfWeekIndex; true; i = (i + 1) % 7) { + string weekday = localizations.narrowWeekdays[i]; + result.Add(new Center(child: new Text(weekday, style: headerStyle))); + if (i == (localizations.firstDayOfWeekIndex + 6) % 7) { + break; + } + } + + return result; + } + + static readonly List _daysInMonth = new List {31, -1, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + + static int getDaysInMonth(int year, int month) { + if (month == 2) { + bool isLeapYear = (year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0); + if (isLeapYear) { + return 29; + } + + return 28; + } + + return _daysInMonth[month - 1]; + } + + int _computeFirstDayOffset(int year, int month, MaterialLocalizations localizations) { + int weekdayFromMonday = new DateTime(year, month, 1).DayOfWeek.GetHashCode(); + if (weekdayFromMonday == 0) { + weekdayFromMonday = 7; + } + + weekdayFromMonday--; + + int firstDayOfWeekFromSunday = localizations.firstDayOfWeekIndex; + int firstDayOfWeekFromMonday = (firstDayOfWeekFromSunday - 1) % 7; + return (weekdayFromMonday - firstDayOfWeekFromMonday) % 7; + } + + public override Widget build(BuildContext context) { + ThemeData themeData = Theme.of(context); + MaterialLocalizations localizations = MaterialLocalizations.of(context); + int year = this.displayedMonth.Year; + int month = this.displayedMonth.Month; + int daysInMonth = getDaysInMonth(year, month); + int firstDayOffset = this._computeFirstDayOffset(year, month, localizations); + List labels = new List(); + labels.AddRange(this._getDayHeaders(themeData.textTheme.caption, localizations)); + for (int i = 0; true; i += 1) { + int day = i - firstDayOffset + 1; + if (day > daysInMonth) { + break; + } + + if (day < 1) { + labels.Add(new Container()); + } + else { + DateTime dayToBuild = new DateTime(year, month, day); + bool disabled = dayToBuild > this.lastDate + || dayToBuild < this.firstDate + || (this.selectableDayPredicate != null && + !this.selectableDayPredicate(dayToBuild)); + BoxDecoration decoration = null; + TextStyle itemStyle = themeData.textTheme.body1; + bool isSelectedDay = this.selectedDate.Year == year && this.selectedDate.Month == month && + this.selectedDate.Day == day; + if (isSelectedDay) { + itemStyle = themeData.accentTextTheme.body2; + decoration = new BoxDecoration( + color: themeData.accentColor, + shape: BoxShape.circle + ); + } + else if (disabled) { + itemStyle = themeData.textTheme.body1.copyWith(color: themeData.disabledColor); + } + else if (this.currentDate.Year == year && this.currentDate.Month == month && + this.currentDate.Day == day) { + itemStyle = themeData.textTheme.body2.copyWith(color: themeData.accentColor); + } + + Widget dayWidget = new Container( + decoration: decoration, + child: new Center( + child: new Text(localizations.formatDecimal(day), style: itemStyle) + ) + ); + if (!disabled) { + dayWidget = new GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: () => { this.onChanged(dayToBuild); }, + child: dayWidget, + dragStartBehavior: this.dragStartBehavior + ); + } + + labels.Add(dayWidget); + } + } + + return new Padding( + padding: EdgeInsets.symmetric(horizontal: 8.0f), + child: new Column( + children: new List { + new Container( + height: DatePickerUtils._kDayPickerRowHeight, + child: new Center( + child: new Text( + localizations.formatMonthYear(this.displayedMonth), + style: themeData.textTheme.subhead + ) + ) + ), + new Flexible( + child: GridView.custom( + gridDelegate: DatePickerUtils._kDayPickerGridDelegate, + childrenDelegate: new SliverChildListDelegate(labels, addRepaintBoundaries: false) + ) + ) + } + ) + ); + } + } + + class MonthPicker : StatefulWidget { + public MonthPicker( + DateTime selectedDate, + ValueChanged onChanged, + DateTime firstDate, + DateTime lastDate, + SelectableDayPredicate selectableDayPredicate, + DragStartBehavior dragStartBehavior = DragStartBehavior.start, + Key key = null + ) : base(key: key) { + D.assert(selectedDate != null); + D.assert(onChanged != null); + D.assert(firstDate <= lastDate); + D.assert(selectedDate >= firstDate); + this.selectedDate = selectedDate; + this.onChanged = onChanged; + this.firstDate = firstDate; + this.lastDate = lastDate; + this.selectableDayPredicate = selectableDayPredicate; + this.dragStartBehavior = dragStartBehavior; + } + + public readonly DateTime selectedDate; + public readonly ValueChanged onChanged; + public readonly DateTime firstDate; + public readonly DateTime lastDate; + public readonly SelectableDayPredicate selectableDayPredicate; + public readonly DragStartBehavior dragStartBehavior; + + public override State createState() { + return new _MonthPickerState(); + } + } + + class _MonthPickerState : SingleTickerProviderStateMixin { + static Animatable __chevronOpacityTween; + + static Animatable _chevronOpacityTween { + get { + if (__chevronOpacityTween == null) { + __chevronOpacityTween = new FloatTween(begin: 1.0f, end: 0.0f) { }; + __chevronOpacityTween.chain(new CurveTween(curve: Curves.easeInOut)); + } + + return __chevronOpacityTween; + } + } + + public override void initState() { + base.initState(); + int monthPage = _monthDelta(this.widget.firstDate, this.widget.selectedDate); + this._dayPickerController = new PageController(initialPage: monthPage); + this._handleMonthPageChanged(monthPage); + this._updateCurrentDate(); + this._chevronOpacityController = new AnimationController( + duration: new TimeSpan(0, 0, 0, 0, 250), + vsync: this + ); + this._chevronOpacityAnimation = this._chevronOpacityController.drive(_chevronOpacityTween); + } + + public override void didUpdateWidget(StatefulWidget oldWidget) { + base.didUpdateWidget(oldWidget); + if (this.widget.selectedDate != ((MonthPicker) oldWidget).selectedDate) { + int monthPage = _monthDelta(this.widget.firstDate, this.widget.selectedDate); + this._dayPickerController = new PageController(initialPage: monthPage); + this._handleMonthPageChanged(monthPage); + } + } + + MaterialLocalizations localizations; + + public override void didChangeDependencies() { + base.didChangeDependencies(); + this.localizations = MaterialLocalizations.of(this.context); + } + + DateTime _todayDate; + DateTime _currentDisplayedMonthDate; + Timer _timer; + PageController _dayPickerController; + AnimationController _chevronOpacityController; + Animation _chevronOpacityAnimation; + + void _updateCurrentDate() { + this._todayDate = DateTime.Now; + DateTime tomorrow = this._todayDate.AddDays(1); + TimeSpan timeUntilTomorrow = tomorrow.TimeOfDay - this._todayDate.TimeOfDay; + this._timer?.cancel(); + this._timer = Window.instance.run(timeUntilTomorrow, + () => { this.setState(() => { this._updateCurrentDate(); }); }); + } + + static int _monthDelta(DateTime startDate, DateTime endDate) { + return (endDate.Year - startDate.Year) * 12 + endDate.Month - startDate.Month; + } + + DateTime _addMonthsToMonthDate(DateTime monthDate, int monthsToAdd) { + return monthDate.AddMonths(monthsToAdd); + } + + Widget _buildItems(BuildContext context, int index) { + DateTime month = this._addMonthsToMonthDate(this.widget.firstDate, index); + return new DayPicker( + key: new ValueKey(month), + selectedDate: this.widget.selectedDate, + currentDate: this._todayDate, + onChanged: this.widget.onChanged, + firstDate: this.widget.firstDate, + lastDate: this.widget.lastDate, + displayedMonth: month, + selectableDayPredicate: this.widget.selectableDayPredicate, + dragStartBehavior: this.widget.dragStartBehavior + ); + } + + void _handleNextMonth() { + if (!this._isDisplayingLastMonth) { + this._dayPickerController.nextPage(duration: DatePickerUtils._kMonthScrollDuration, curve: Curves.ease); + } + } + + void _handlePreviousMonth() { + if (!this._isDisplayingFirstMonth) { + this._dayPickerController.previousPage(duration: DatePickerUtils._kMonthScrollDuration, + curve: Curves.ease); + } + } + + bool _isDisplayingFirstMonth { + get { + return this._currentDisplayedMonthDate <= + new DateTime(this.widget.firstDate.Year, this.widget.firstDate.Month, 1); + } + } + + bool _isDisplayingLastMonth { + get { + return this._currentDisplayedMonthDate >= + new DateTime(this.widget.lastDate.Year, this.widget.lastDate.Month, 1); + } + } + + DateTime _previousMonthDate; + DateTime _nextMonthDate; + + void _handleMonthPageChanged(int monthPage) { + this.setState(() => { + this._previousMonthDate = this._addMonthsToMonthDate(this.widget.firstDate, monthPage - 1); + this._currentDisplayedMonthDate = this._addMonthsToMonthDate(this.widget.firstDate, monthPage); + this._nextMonthDate = this._addMonthsToMonthDate(this.widget.firstDate, monthPage + 1); + }); + } + + public override Widget build(BuildContext context) { + return new SizedBox( + width: DatePickerUtils._kMonthPickerPortraitWidth, + height: DatePickerUtils._kMaxDayPickerHeight, + child: new Stack( + children: new List { + new NotificationListener( + onNotification: (_) => { + this._chevronOpacityController.forward(); + return false; + }, + child: new NotificationListener( + onNotification: (_) => { + this._chevronOpacityController.reverse(); + return false; + }, + child: PageView.builder( + dragStartBehavior: this.widget.dragStartBehavior, + key: new ValueKey(this.widget.selectedDate), + controller: this._dayPickerController, + scrollDirection: Axis.horizontal, + itemCount: _monthDelta(this.widget.firstDate, this.widget.lastDate) + 1, + itemBuilder: this._buildItems, + onPageChanged: this._handleMonthPageChanged + ) + ) + ), + new Positioned( + top: 0.0f, + left: 8.0f, + child: new FadeTransition( + opacity: this._chevronOpacityAnimation, + child: new IconButton( + icon: new Icon(Icons.chevron_left), + tooltip: this._isDisplayingFirstMonth + ? null + : $"{this.localizations.previousMonthTooltip} {this.localizations.formatMonthYear(this._previousMonthDate)}", + onPressed: this._isDisplayingFirstMonth + ? (VoidCallback) null + : this._handlePreviousMonth + ) + ) + ), + new Positioned( + top: 0.0f, + right: 8.0f, + child: new FadeTransition( + opacity: this._chevronOpacityAnimation, + child: new IconButton( + icon: new Icon(Icons.chevron_right), + tooltip: this._isDisplayingLastMonth + ? null + : $"{this.localizations.nextMonthTooltip} {this.localizations.formatMonthYear(this._nextMonthDate)}", + onPressed: this._isDisplayingLastMonth + ? (VoidCallback) null + : this._handleNextMonth + ) + ) + ) + } + ) + ); + } + + public override void dispose() { + this._timer?.cancel(); + this._dayPickerController?.dispose(); + base.dispose(); + } + } + + class _MonthPickerSortKey : Diagnosticable { + public _MonthPickerSortKey(float order) { } + public static readonly _MonthPickerSortKey previousMonth = new _MonthPickerSortKey(1.0f); + public static readonly _MonthPickerSortKey nextMonth = new _MonthPickerSortKey(2.0f); + public static readonly _MonthPickerSortKey calendar = new _MonthPickerSortKey(3.0f); + } + + public class YearPicker : StatefulWidget { + public YearPicker( + DateTime selectedDate, + ValueChanged onChanged, + DateTime firstDate, + DateTime lastDate, + DragStartBehavior dragStartBehavior = DragStartBehavior.start, + Key key = null + ) : base(key: key) { + D.assert(selectedDate != null); + D.assert(onChanged != null); + D.assert(firstDate <= lastDate); + this.selectedDate = selectedDate; + this.onChanged = onChanged; + this.firstDate = firstDate; + this.lastDate = lastDate; + this.dragStartBehavior = dragStartBehavior; + } + + public readonly DateTime selectedDate; + public readonly ValueChanged onChanged; + public readonly DateTime firstDate; + public readonly DateTime lastDate; + public readonly DragStartBehavior dragStartBehavior; + + public override State createState() { + return new _YearPickerState(); + } + } + + class _YearPickerState : State { + const float _itemExtent = 50.0f; + ScrollController scrollController; + + public override void initState() { + base.initState(); + this.scrollController = new ScrollController( + initialScrollOffset: (this.widget.selectedDate.Year - this.widget.firstDate.Year) * _itemExtent + ); + } + + public override Widget build(BuildContext context) { + D.assert(MaterialD.debugCheckHasMaterial(context)); + ThemeData themeData = Theme.of(context); + TextStyle style = themeData.textTheme.body1; + return ListView.builder( + dragStartBehavior: this.widget.dragStartBehavior, + controller: this.scrollController, + itemExtent: _itemExtent, + itemCount: this.widget.lastDate.Year - this.widget.firstDate.Year + 1, + itemBuilder: (BuildContext _context, int index) => { + int year = this.widget.firstDate.Year + index; + bool isSelected = year == this.widget.selectedDate.Year; + TextStyle itemStyle = isSelected + ? themeData.textTheme.headline.copyWith(color: themeData.accentColor) + : style; + return new InkWell( + key: new ValueKey(year), + onTap: () => { + this.widget.onChanged(new DateTime(year, this.widget.selectedDate.Month, + this.widget.selectedDate.Day)); + }, + child: new Center( + child: new Text(year.ToString(), style: itemStyle) + ) + ); + } + ); + } + } + + class _DatePickerDialog : StatefulWidget { + public _DatePickerDialog( + DateTime initialDate, + DateTime firstDate, + DateTime lastDate, + SelectableDayPredicate selectableDayPredicate, + DatePickerMode initialDatePickerMode, + Key key = null + ) : base(key: key) { + this.initialDate = initialDate; + this.firstDate = firstDate; + this.lastDate = lastDate; + this.selectableDayPredicate = selectableDayPredicate; + this.initialDatePickerMode = initialDatePickerMode; + } + + public readonly DateTime initialDate; + public readonly DateTime firstDate; + public readonly DateTime lastDate; + public readonly SelectableDayPredicate selectableDayPredicate; + public readonly DatePickerMode initialDatePickerMode; + + public override State createState() { + return new _DatePickerDialogState(); + } + } + + class _DatePickerDialogState : State<_DatePickerDialog> { + public override void initState() { + base.initState(); + this._selectedDate = this.widget.initialDate; + this._mode = this.widget.initialDatePickerMode; + } + + bool _announcedInitialDate = false; + public MaterialLocalizations localizations; + + public override void didChangeDependencies() { + base.didChangeDependencies(); + this.localizations = MaterialLocalizations.of(this.context); + if (!this._announcedInitialDate) { + this._announcedInitialDate = true; + } + } + + DateTime _selectedDate; + + DatePickerMode _mode; + GlobalKey _pickerKey = GlobalKey.key(); + + void _vibrate() { + switch (Theme.of(this.context).platform) { + case RuntimePlatform.Android: + // case RuntimePlatform.fuchsia: + // HapticFeedback.vibrate(); + break; + } + } + + void _handleModeChanged(DatePickerMode mode) { + this._vibrate(); + this.setState(() => { + this._mode = mode; + if (this._mode == DatePickerMode.day) { + // SemanticsService.announce(localizations.formatMonthYear(_selectedDate), textDirection); + } + else { + // SemanticsService.announce(localizations.formatYear(_selectedDate), textDirection); + } + }); + } + + void _handleYearChanged(DateTime value) { + if (value < this.widget.firstDate) { + value = this.widget.firstDate; + } + else if (value > this.widget.lastDate) { + value = this.widget.lastDate; + } + + if (value == this._selectedDate) { + return; + } + + this._vibrate(); + this.setState(() => { + this._mode = DatePickerMode.day; + this._selectedDate = value; + }); + } + + void _handleDayChanged(DateTime value) { + this._vibrate(); + this.setState(() => { this._selectedDate = value; }); + } + + void _handleCancel() { + Navigator.pop(this.context); + } + + void _handleOk() { + Navigator.pop(this.context, this._selectedDate); + } + + Widget _buildPicker() { + switch (this._mode) { + case DatePickerMode.day: + return new MonthPicker( + key: this._pickerKey, + selectedDate: this._selectedDate, + onChanged: this._handleDayChanged, + firstDate: this.widget.firstDate, + lastDate: this.widget.lastDate, + selectableDayPredicate: this.widget.selectableDayPredicate + ); + case DatePickerMode.year: + return new YearPicker( + key: this._pickerKey, + selectedDate: this._selectedDate, + onChanged: this._handleYearChanged, + firstDate: this.widget.firstDate, + lastDate: this.widget.lastDate + ); + } + + return null; + } + + public override Widget build(BuildContext context) { + ThemeData theme = Theme.of(context); + Widget picker = new Flexible( + child: new SizedBox( + height: DatePickerUtils._kMaxDayPickerHeight, + child: this._buildPicker() + ) + ); + Widget actions = ButtonTheme.bar( + child: new ButtonBar( + children: new List { + new FlatButton( + child: new Text(this.localizations.cancelButtonLabel), + onPressed: this._handleCancel + ), + new FlatButton( + child: new Text(this.localizations.okButtonLabel), + onPressed: this._handleOk + ) + } + ) + ); + Dialog dialog = new Dialog( + child: new OrientationBuilder( + builder: (BuildContext _context, Orientation orientation) => { + Widget header = new _DatePickerHeader( + selectedDate: this._selectedDate, + mode: this._mode, + onModeChanged: this._handleModeChanged, + orientation: orientation + ); + + switch (orientation) { + case Orientation.portrait: + return new SizedBox( + width: DatePickerUtils._kMonthPickerPortraitWidth, + child: new Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: new List { + header, + new Container( + color: theme.dialogBackgroundColor, + child: new Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: new List { + picker, + actions, + } + ) + ) + } + ) + ); + case Orientation.landscape: + return new SizedBox( + height: DatePickerUtils._kDatePickerLandscapeHeight, + child: new Row( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: new List { + header, + new Flexible( + child: new Container( + width: DatePickerUtils._kMonthPickerLandscapeWidth, + color: theme.dialogBackgroundColor, + child: new Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: new List {picker, actions} + ) + ) + ) + } + ) + ); + } + + return null; + } + ) + ); + + return new Theme( + data: theme.copyWith( + dialogBackgroundColor: Colors.transparent + ), + child: dialog + ); + } + } + + public delegate bool SelectableDayPredicate(DateTime day); +} \ No newline at end of file diff --git a/Runtime/material/date_picker.cs.meta b/Runtime/material/date_picker.cs.meta new file mode 100644 index 00000000..16036f93 --- /dev/null +++ b/Runtime/material/date_picker.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a56231ebee8e54b6599292d673909844 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/material/dialog.cs b/Runtime/material/dialog.cs index d172bca8..a5b229c5 100644 --- a/Runtime/material/dialog.cs +++ b/Runtime/material/dialog.cs @@ -292,10 +292,10 @@ public static IPromise showDialog( ) { D.assert(MaterialD.debugCheckHasMaterialLocalizations(context)); + ThemeData theme = Theme.of(context, shadowThemeOnly: true); return widgets.DialogUtils.showGeneralDialog( context: context, pageBuilder: (buildContext, animation, secondaryAnimation) => { - ThemeData theme = Theme.of(context, shadowThemeOnly: true); Widget pageChild = new Builder(builder: builder); return new SafeArea( child: new Builder( diff --git a/Runtime/material/drawer.cs b/Runtime/material/drawer.cs index 60f4e0e3..a4b189de 100644 --- a/Runtime/material/drawer.cs +++ b/Runtime/material/drawer.cs @@ -57,11 +57,10 @@ public DrawerController( Widget child = null, DrawerAlignment? alignment = null, DrawerCallback drawerCallback = null, - DragStartBehavior? dragStartBehavior = null + DragStartBehavior dragStartBehavior = DragStartBehavior.start ) : base(key: key) { D.assert(child != null); D.assert(alignment != null); - D.assert(dragStartBehavior != null); this.child = child; this.alignment = alignment ?? DrawerAlignment.start; this.drawerCallback = drawerCallback; diff --git a/Runtime/material/dropdown.cs b/Runtime/material/dropdown.cs index de1446fc..d7ccc1e3 100644 --- a/Runtime/material/dropdown.cs +++ b/Runtime/material/dropdown.cs @@ -330,15 +330,72 @@ public override Color barrierColor { public override Widget buildPage(BuildContext context, Animation animation, Animation secondaryAnimation) { + return new LayoutBuilder( + builder: (ctx, constraints) => { + return new _DropdownRoutePage( + route: this, + constraints: constraints, + items: this.items, + padding: this.padding, + buttonRect: this.buttonRect, + selectedIndex: this.selectedIndex, + elevation: this.elevation, + theme: this.theme, + style: this.style + ); + } + ); + } + + internal void _dismiss() { + this.navigator?.removeRoute(this); + } + } + + class _DropdownRoutePage : StatelessWidget where T : class { + public _DropdownRoutePage( + Key key = null, + _DropdownRoute route = null, + BoxConstraints constraints = null, + List> items = null, + EdgeInsets padding = null, + Rect buttonRect = null, + int? selectedIndex = null, + int elevation = 0, + ThemeData theme = null, + TextStyle style = null + ) : base(key: key) { + this.route = route; + this.constraints = constraints; + this.items = items; + this.padding = padding; + this.buttonRect = buttonRect; + this.selectedIndex = selectedIndex; + this.elevation = elevation; + this.theme = theme; + this.style = style; + } + + public readonly _DropdownRoute route; + public readonly BoxConstraints constraints; + public readonly List> items; + public readonly EdgeInsets padding; + public readonly Rect buttonRect; + public readonly int? selectedIndex; + public readonly int elevation; + public readonly ThemeData theme; + public readonly TextStyle style; + + public override Widget build(BuildContext context) { D.assert(WidgetsD.debugCheckHasDirectionality(context)); - float screenHeight = MediaQuery.of(context).size.height; - float maxMenuHeight = screenHeight - 2.0f * DropdownConstants._kMenuItemHeight; + float availableHeight = this.constraints.maxHeight; + float maxMenuHeight = availableHeight - 2.0f * DropdownConstants._kMenuItemHeight; float buttonTop = this.buttonRect.top; - float buttonBottom = this.buttonRect.bottom; + float buttonBottom = Mathf.Min(this.buttonRect.bottom, availableHeight); float topLimit = Mathf.Min(DropdownConstants._kMenuItemHeight, buttonTop); - float bottomLimit = Mathf.Max(screenHeight - DropdownConstants._kMenuItemHeight, buttonBottom); + float bottomLimit = Mathf.Max(availableHeight - DropdownConstants._kMenuItemHeight, buttonBottom); float? selectedItemOffset = this.selectedIndex * DropdownConstants._kMenuItemHeight + Constants.kMaterialListPadding.top; @@ -361,15 +418,15 @@ public override Widget buildPage(BuildContext context, Animation animatio menuTop = menuBottom - menuHeight; } - if (this.scrollController == null) { + if (this.route.scrollController == null) { float scrollOffset = preferredMenuHeight > maxMenuHeight ? Mathf.Max(0.0f, selectedItemOffset ?? 0.0f - (buttonTop - (menuTop ?? 0.0f))) : 0.0f; - this.scrollController = new ScrollController(initialScrollOffset: scrollOffset); + this.route.scrollController = new ScrollController(initialScrollOffset: scrollOffset); } Widget menu = new _DropdownMenu( - route: this, + route: this.route, padding: this.padding ); @@ -397,10 +454,6 @@ public override Widget buildPage(BuildContext context, Animation animatio ) ); } - - public void _dismiss() { - this.navigator?.removeRoute(this); - } } public class DropdownMenuItem : StatelessWidget where T : class { @@ -454,6 +507,10 @@ public DropdownButton( ValueChanged onChanged = null, int elevation = 8, TextStyle style = null, + Widget underline = null, + Widget icon = null, + Color iconDisabledColor = null, + Color iconEnabledColor = null, float iconSize = 24.0f, bool isDense = false, bool isExpanded = false @@ -469,6 +526,10 @@ public DropdownButton( this.onChanged = onChanged; this.elevation = elevation; this.style = style; + this.underline = underline; + this.icon = icon; + this.iconDisabledColor = iconDisabledColor; + this.iconEnabledColor = iconEnabledColor; this.iconSize = iconSize; this.isDense = isDense; this.isExpanded = isExpanded; @@ -488,6 +549,14 @@ public DropdownButton( public readonly TextStyle style; + public readonly Widget underline; + + public readonly Widget icon; + + public readonly Color iconDisabledColor; + + public readonly Color iconEnabledColor; + public readonly float iconSize; public readonly bool isDense; @@ -606,24 +675,34 @@ void _handleTap() { } } - Color _downArrowColor { + Color _iconColor { get { if (this._enabled) { - if (Theme.of(this.context).brightness == Brightness.light) { - return Colors.grey.shade700; + if (this.widget.iconEnabledColor != null) { + return this.widget.iconEnabledColor; } - else { - return Colors.white70; + + switch (Theme.of(this.context).brightness) { + case Brightness.light: + return Colors.grey.shade700; + case Brightness.dark: + return Colors.white70; } } else { - if (Theme.of(this.context).brightness == Brightness.light) { - return Colors.grey.shade400; + if (this.widget.iconDisabledColor != null) { + return this.widget.iconDisabledColor; } - else { - return Colors.white10; + + switch (Theme.of(this.context).brightness) { + case Brightness.light: + return Colors.grey.shade400; + case Brightness.dark: + return Colors.white10; } } + D.assert(false); + return null; } } @@ -661,6 +740,7 @@ public override Widget build(BuildContext context) { children: items ); + Icon defaultIcon = new Icon(Icons.arrow_drop_down); Widget result = new DefaultTextStyle( style: this._textStyle, child: new Container( @@ -671,9 +751,12 @@ public override Widget build(BuildContext context) { mainAxisSize: MainAxisSize.min, children: new List { this.widget.isExpanded ? new Expanded(child: innerItemsWidget) : (Widget) innerItemsWidget, - new Icon(Icons.arrow_drop_down, - size: this.widget.iconSize, - color: this._downArrowColor + new IconTheme( + data: new IconThemeData( + color: this._iconColor, + size: this.widget.iconSize + ), + child: this.widget.icon ?? defaultIcon ) } ) @@ -689,7 +772,7 @@ public override Widget build(BuildContext context) { left: 0.0f, right: 0.0f, bottom: bottom, - child: new Container( + child: this.widget.underline ?? new Container( height: 1.0f, decoration: new BoxDecoration( border: new Border( diff --git a/Runtime/material/expansion_panel.cs b/Runtime/material/expansion_panel.cs index 15e59cb2..41a31601 100644 --- a/Runtime/material/expansion_panel.cs +++ b/Runtime/material/expansion_panel.cs @@ -87,12 +87,14 @@ public class ExpansionPanel { public ExpansionPanel( ExpansionPanelHeaderBuilder headerBuilder = null, Widget body = null, - bool isExpanded = false) { + bool isExpanded = false, + bool canTapOnHeader = false) { D.assert(headerBuilder != null); D.assert(body != null); this.headerBuilder = headerBuilder; this.body = body; this.isExpanded = isExpanded; + this.canTapOnHeader = false; } public readonly ExpansionPanelHeaderBuilder headerBuilder; @@ -100,6 +102,8 @@ public ExpansionPanel( public readonly Widget body; public readonly bool isExpanded; + + public readonly bool canTapOnHeader; } @@ -107,7 +111,9 @@ public class ExpansionPanelRadio : ExpansionPanel { public ExpansionPanelRadio( object value = null, ExpansionPanelHeaderBuilder headerBuilder = null, - Widget body = null) : base(body: body, headerBuilder: headerBuilder) { + Widget body = null, + bool canTapOnHeader = false) + : base(body: body, headerBuilder: headerBuilder, canTapOnHeader: canTapOnHeader) { D.assert(headerBuilder != null); D.assert(body != null); D.assert(value != null); @@ -263,6 +269,10 @@ public override Widget build(BuildContext context) { } ExpansionPanel child = this.widget.children[index]; + Widget headerWidget = child.headerBuilder( + context, + this._isChildExpanded(index) + ); Row header = new Row( children: new List { new Expanded( @@ -273,9 +283,7 @@ public override Widget build(BuildContext context) { child: new ConstrainedBox( constraints: new BoxConstraints( minHeight: ExpansionPanelUtils._kPanelHeaderCollapsedHeight), - child: child.headerBuilder( - context, - this._isChildExpanded(index)) + child: headerWidget ) ) ), @@ -284,7 +292,11 @@ public override Widget build(BuildContext context) { child: new ExpandIcon( isExpanded: this._isChildExpanded(index), padding: EdgeInsets.all(16.0f), - onPressed: (bool isExpanded) => this._handlePressed(isExpanded, expandIndex) + onPressed: !child.canTapOnHeader + ? (ValueChanged) ((bool isExpanded) => { + this._handlePressed(isExpanded, expandIndex); + }) + : null ) ) } @@ -294,7 +306,13 @@ public override Widget build(BuildContext context) { key: new _SaltedKey(context, index * 2), child: new Column( children: new List { - header, + child.canTapOnHeader + ? (Widget) new InkWell( + onTap: () => + this._handlePressed(this._isChildExpanded(expandIndex), expandIndex), + child: header + ) + : header, new AnimatedCrossFade( firstChild: new Container(height: 0.0f), secondChild: child.body, diff --git a/Runtime/material/float_action_button.cs b/Runtime/material/floating_action_button.cs similarity index 70% rename from Runtime/material/float_action_button.cs rename to Runtime/material/floating_action_button.cs index 2669a483..7726ecc1 100644 --- a/Runtime/material/float_action_button.cs +++ b/Runtime/material/floating_action_button.cs @@ -6,6 +6,7 @@ using Unity.UIWidgets.widgets; using UnityEngine; using Color = Unity.UIWidgets.ui.Color; +using TextStyle = Unity.UIWidgets.painting.TextStyle; namespace Unity.UIWidgets.material { static class FloatActionButtonUtils { @@ -36,8 +37,8 @@ public class FloatingActionButton : StatelessWidget { Color foregroundColor = null, Color backgroundColor = null, object heroTag = null, - float elevation = 6.0f, - float highlightElevation = 12.0f, + float? elevation = null, + float? highlightElevation = null, float? disabledElevation = null, VoidCallback onPressed = null, bool mini = false, @@ -47,11 +48,10 @@ public class FloatingActionButton : StatelessWidget { bool isExtended = false, BoxConstraints _sizeConstraints = null ) : base(key: key) { - D.assert(elevation >= 0.0f); - D.assert(highlightElevation >= 0.0f); + D.assert(elevation == null || elevation >= 0.0f); + D.assert(highlightElevation == null || highlightElevation >= 0.0f); D.assert(disabledElevation == null || disabledElevation >= 0.0f); heroTag = heroTag ?? new _DefaultHeroTag(); - shape = shape ?? new CircleBorder(); this.child = child; this.tooltip = tooltip; this.foregroundColor = foregroundColor; @@ -109,8 +109,8 @@ public static FloatingActionButton extended( Color foregroundColor = null, Color backgroundColor = null, object heroTag = null, - float elevation = 6.0f, - float highlightElevation = 12.0f, + float? elevation = null, + float? highlightElevation = null, float? disabledElevation = null, VoidCallback onPressed = null, ShapeBorder shape = null, @@ -120,26 +120,30 @@ public static FloatingActionButton extended( Widget icon = null, Widget label = null ) { - D.assert(elevation >= 0.0f); - D.assert(highlightElevation >= 0.0f); + D.assert(elevation == null || elevation >= 0.0f); + D.assert(highlightElevation == null || highlightElevation >= 0.0f); D.assert(disabledElevation == null || disabledElevation >= 0.0f); - D.assert(icon != null); D.assert(label != null); heroTag = heroTag ?? new _DefaultHeroTag(); - shape = shape ?? new StadiumBorder(); BoxConstraints _sizeConstraints = FloatActionButtonUtils._kExtendedSizeConstraints; bool mini = false; Widget child = new _ChildOverflowBox( child: new Row( mainAxisSize: MainAxisSize.min, - children: new List { - new SizedBox(width: 16.0f), - icon, - new SizedBox(width: 8.0f), - label, - new SizedBox(width: 20.0f) - })); + children: icon == null + ? new List { + new SizedBox(width: 20.0f), + label, + new SizedBox(width: 20.0f), + } + : new List { + new SizedBox(width: 16.0f), + icon, + new SizedBox(width: 8.0f), + label, + new SizedBox(width: 20.0f) + })); return new FloatingActionButton( key: key, @@ -150,7 +154,7 @@ public static FloatingActionButton extended( heroTag: heroTag, elevation: elevation, highlightElevation: highlightElevation, - disabledElevation: disabledElevation ?? elevation, + disabledElevation: disabledElevation, onPressed: onPressed, mini: mini, shape: shape, @@ -173,9 +177,9 @@ public static FloatingActionButton extended( public readonly VoidCallback onPressed; - public readonly float elevation; + public readonly float? elevation; - public readonly float highlightElevation; + public readonly float? highlightElevation; public readonly float? disabledElevation; @@ -189,11 +193,43 @@ public static FloatingActionButton extended( public readonly MaterialTapTargetSize? materialTapTargetSize; - public readonly BoxConstraints _sizeConstraints; + readonly BoxConstraints _sizeConstraints; + + const float _defaultElevation = 6; + const float _defaultHighlightElevation = 12; + readonly ShapeBorder _defaultShape = new CircleBorder(); + readonly ShapeBorder _defaultExtendedShape = new StadiumBorder(); public override Widget build(BuildContext context) { ThemeData theme = Theme.of(context); - Color foregroundColor = this.foregroundColor ?? theme.accentIconTheme.color; + FloatingActionButtonThemeData floatingActionButtonTheme = theme.floatingActionButtonTheme; + Color backgroundColor = this.backgroundColor + ?? floatingActionButtonTheme.backgroundColor + ?? theme.colorScheme.secondary; + Color foregroundColor = this.foregroundColor + ?? floatingActionButtonTheme.foregroundColor + ?? theme.accentIconTheme.color + ?? theme.colorScheme.onSecondary; + + float elevation = this.elevation + ?? floatingActionButtonTheme.elevation + ?? _defaultElevation; + float disabledElevation = this.disabledElevation + ?? floatingActionButtonTheme.disabledElevation + ?? elevation; + float highlightElevation = this.highlightElevation + ?? floatingActionButtonTheme.highlightElevation + ?? _defaultHighlightElevation; + MaterialTapTargetSize materialTapTargetSize = this.materialTapTargetSize + ?? theme.materialTapTargetSize; + TextStyle textStyle = theme.accentTextTheme.button.copyWith( + color: foregroundColor, + letterSpacing: 1.2f + ); + ShapeBorder shape = this.shape + ?? floatingActionButtonTheme.shape + ?? (this.isExtended ? this._defaultExtendedShape : this._defaultShape); + Widget result = null; if (this.child != null) { @@ -206,16 +242,14 @@ public override Widget build(BuildContext context) { result = new RawMaterialButton( onPressed: this.onPressed, - elevation: this.elevation, - highlightElevation: this.highlightElevation, - disabledElevation: this.disabledElevation ?? this.elevation, + elevation: elevation, + highlightElevation: highlightElevation, + disabledElevation: disabledElevation, constraints: this._sizeConstraints, - materialTapTargetSize: this.materialTapTargetSize ?? theme.materialTapTargetSize, - fillColor: this.backgroundColor ?? theme.accentColor, - textStyle: theme.accentTextTheme.button.copyWith( - color: foregroundColor, - letterSpacing: 1.2f), - shape: this.shape, + materialTapTargetSize: materialTapTargetSize, + fillColor: backgroundColor, + textStyle: textStyle, + shape: shape, clipBehavior: this.clipBehavior, child: result); diff --git a/Runtime/material/floating_action_button.cs.meta b/Runtime/material/floating_action_button.cs.meta new file mode 100644 index 00000000..e1f8530e --- /dev/null +++ b/Runtime/material/floating_action_button.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 44d53f5996891c54780cbc0073567bfd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/material/float_action_button_location.cs b/Runtime/material/floating_action_button_location.cs similarity index 100% rename from Runtime/material/float_action_button_location.cs rename to Runtime/material/floating_action_button_location.cs diff --git a/Runtime/material/floating_action_button_location.cs.meta b/Runtime/material/floating_action_button_location.cs.meta new file mode 100644 index 00000000..34d17599 --- /dev/null +++ b/Runtime/material/floating_action_button_location.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6c8b71fe76d6bdb4ca66ecad56f25d3f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/material/floatting_action_button_theme.cs b/Runtime/material/floatting_action_button_theme.cs new file mode 100644 index 00000000..3246ce69 --- /dev/null +++ b/Runtime/material/floatting_action_button_theme.cs @@ -0,0 +1,129 @@ +using Unity.UIWidgets.foundation; +using Unity.UIWidgets.painting; +using Unity.UIWidgets.ui; + +namespace Unity.UIWidgets.material { + public class FloatingActionButtonThemeData : Diagnosticable { + public FloatingActionButtonThemeData( + Color backgroundColor = null, + Color foregroundColor = null, + float? elevation = null, + float? disabledElevation = null, + float? highlightElevation = null, + ShapeBorder shape = null + ) { + this.backgroundColor = backgroundColor; + this.foregroundColor = foregroundColor; + this.elevation = elevation; + this.disabledElevation = disabledElevation; + this.highlightElevation = highlightElevation; + this.shape = shape; + } + + public readonly Color backgroundColor; + + public readonly Color foregroundColor; + + public readonly float? elevation; + + public readonly float? disabledElevation; + + public readonly float? highlightElevation; + + public readonly ShapeBorder shape; + + public FloatingActionButtonThemeData copyWith( + Color backgroundColor, + Color foregroundColor, + float? elevation, + float? disabledElevation, + float? highlightElevation, + ShapeBorder shape + ) { + return new FloatingActionButtonThemeData( + backgroundColor: backgroundColor ?? this.backgroundColor, + foregroundColor: foregroundColor ?? this.foregroundColor, + elevation: elevation ?? this.elevation, + disabledElevation: disabledElevation ?? this.disabledElevation, + highlightElevation: highlightElevation ?? this.highlightElevation, + shape: shape ?? this.shape + ); + } + + public static FloatingActionButtonThemeData lerp(FloatingActionButtonThemeData a, FloatingActionButtonThemeData b, + float t) { + if (a == null && b == null) { + return null; + } + + return new FloatingActionButtonThemeData( + backgroundColor: Color.lerp(a?.backgroundColor, b?.backgroundColor, t), + foregroundColor: Color.lerp(a?.foregroundColor, b?.foregroundColor, t), + elevation: MathUtils.lerpFloat(a?.elevation ?? 0, b?.elevation ?? 0, t), + disabledElevation: MathUtils.lerpFloat(a?.disabledElevation ?? 0, b?.disabledElevation ?? 0, t), + highlightElevation: MathUtils.lerpFloat(a?.highlightElevation ?? 0, b?.highlightElevation ?? 0, t), + shape: ShapeBorder.lerp(a?.shape, b?.shape, t) + ); + } + + public override int GetHashCode() { + var hashCode = this.backgroundColor?.GetHashCode() ?? 0; + hashCode = (hashCode * 397) ^ this.foregroundColor?.GetHashCode() ?? 0; + hashCode = (hashCode * 397) ^ this.elevation?.GetHashCode() ?? 0; + hashCode = (hashCode * 397) ^ this.disabledElevation?.GetHashCode() ?? 0; + hashCode = (hashCode * 397) ^ this.highlightElevation?.GetHashCode() ?? 0; + hashCode = (hashCode * 397) ^ this.shape?.GetHashCode() ?? 0; + return hashCode; + } + + public bool Equals(FloatingActionButtonThemeData other) { + if (ReferenceEquals(null, other)) { + return false; + } + + if (ReferenceEquals(this, other)) { + return true; + } + + return Equals(this.backgroundColor, other.backgroundColor) + && Equals(this.elevation, other.elevation) + && Equals(this.shape, other.shape) + && Equals(this.foregroundColor, other.foregroundColor) + && Equals(this.disabledElevation, other.disabledElevation) + && Equals(this.highlightElevation, other.highlightElevation); + } + + public override bool Equals(object obj) { + if (ReferenceEquals(null, obj)) { + return false; + } + + if (ReferenceEquals(this, obj)) { + return true; + } + + if (obj.GetType() != this.GetType()) { + return false; + } + + return this.Equals((FloatingActionButtonThemeData) obj); + } + + public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { + base.debugFillProperties(properties); + FloatingActionButtonThemeData defaultData = new FloatingActionButtonThemeData(); + + properties.add(new DiagnosticsProperty("backgroundColor", this.backgroundColor, + defaultValue: defaultData.backgroundColor)); + properties.add(new DiagnosticsProperty("foregroundColor", this.foregroundColor, + defaultValue: defaultData.foregroundColor)); + properties.add(new DiagnosticsProperty("elevation", this.elevation, + defaultValue: defaultData.elevation)); + properties.add(new DiagnosticsProperty("disabledElevation", this.disabledElevation, + defaultValue: defaultData.disabledElevation)); + properties.add(new DiagnosticsProperty("highlightElevation", this.highlightElevation, + defaultValue: defaultData.highlightElevation)); + properties.add(new DiagnosticsProperty("shape", this.shape, defaultValue: defaultData.shape)); + } + } +} \ No newline at end of file diff --git a/Runtime/material/floatting_action_button_theme.cs.meta b/Runtime/material/floatting_action_button_theme.cs.meta new file mode 100644 index 00000000..5a9b27c5 --- /dev/null +++ b/Runtime/material/floatting_action_button_theme.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f2f4277e1c02b5b4281b4fc2b7ac3e21 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/material/ink_well.cs b/Runtime/material/ink_well.cs index 5f4af7fb..5f70e9f5 100644 --- a/Runtime/material/ink_well.cs +++ b/Runtime/material/ink_well.cs @@ -64,7 +64,7 @@ public InkResponse( Widget child = null, GestureTapCallback onTap = null, GestureTapDownCallback onTapDown = null, - GestureTapCallback onTapCancel = null, + GestureTapCancelCallback onTapCancel = null, GestureTapCallback onDoubleTap = null, GestureLongPressCallback onLongPress = null, ValueChanged onHighlightChanged = null, @@ -99,7 +99,7 @@ public InkResponse( public readonly GestureTapDownCallback onTapDown; - public readonly GestureTapCallback onTapCancel; + public readonly GestureTapCancelCallback onTapCancel; public readonly GestureTapCallback onDoubleTap; diff --git a/Runtime/material/input_border.cs b/Runtime/material/input_border.cs index 55700da9..b762f922 100644 --- a/Runtime/material/input_border.cs +++ b/Runtime/material/input_border.cs @@ -312,7 +312,7 @@ Path _gapBorderPath(Canvas canvas, RRect center, float start, float extent) { const float cornerArcSweep = Mathf.PI / 2.0f; float tlCornerArcSweep = start < center.tlRadiusX - ? Mathf.Asin(start / center.tlRadiusX) + ? Mathf.Asin((start / center.tlRadiusX).clamp(-1.0f, 1.0f)) : Mathf.PI / 2.0f; Path path = new Path(); @@ -361,7 +361,7 @@ public override void paint(Canvas canvas, Rect rect, } else { float extent = MathUtils.lerpFloat(0.0f, gapExtent + this.gapPadding * 2.0f, gapPercentage); - Path path = this._gapBorderPath(canvas, center, gapStart - this.gapPadding, extent); + Path path = this._gapBorderPath(canvas, center, Mathf.Max(0.0f,gapStart - this.gapPadding), extent); canvas.drawPath(path, paint); } } diff --git a/Runtime/material/input_decorator.cs b/Runtime/material/input_decorator.cs index 10e467ff..e0c4d748 100644 --- a/Runtime/material/input_decorator.cs +++ b/Runtime/material/input_decorator.cs @@ -635,15 +635,19 @@ class _RenderDecoration : RenderBox { public _RenderDecoration( _Decoration decoration, TextBaseline? textBaseline, - bool isFocused + bool isFocused, + bool expands ) { D.assert(decoration != null); D.assert(textBaseline != null); this._decoration = decoration; this._textBaseline = textBaseline; this._isFocused = isFocused; + this._expands = expands; } + public const float subtextGap = 8.0f; + public readonly Dictionary<_DecorationSlot, RenderBox> slotToChild = new Dictionary<_DecorationSlot, RenderBox>(); @@ -834,6 +838,20 @@ public bool isFocused { bool _isFocused; + public bool expands { + get { return this._expands; } + set { + if (this._expands == value) { + return; + } + + this._expands = value; + this.markNeedsLayout(); + } + } + + bool _expands = false; + public override void attach(object owner) { base.attach(owner); foreach (RenderBox child in this._children) { @@ -907,107 +925,189 @@ public EdgeInsets contentPadding { get { return this.decoration.contentPadding; } } + float _layoutLineBox(RenderBox box, BoxConstraints constraints) { + if (box == null) { + return 0.0f; + } + + box.layout(constraints, parentUsesSize: true); + float baseline = box.getDistanceToBaseline(this.textBaseline.Value).Value; + D.assert(baseline >= 0.0f); + return baseline; + } + _RenderDecorationLayout _layout(BoxConstraints layoutConstraints) { Dictionary boxToBaseline = new Dictionary(); BoxConstraints boxConstraints = layoutConstraints.loosen(); - float aboveBaseline = 0.0f; - float belowBaseline = 0.0f; - - void layoutLineBox(RenderBox box) { - if (box == null) { - return; - } - - box.layout(boxConstraints, parentUsesSize: true); - float baseline = box.getDistanceToBaseline(this.textBaseline ?? 0.0f) ?? 0.0f; - D.assert(baseline >= 0.0f); - boxToBaseline[box] = baseline; - aboveBaseline = Mathf.Max(baseline, aboveBaseline); - belowBaseline = Mathf.Max(box.size.height - baseline, belowBaseline); + if (this.prefix != null) { + boxToBaseline[this.prefix] = this._layoutLineBox(this.prefix, boxConstraints); + } + if (this.suffix != null) { + boxToBaseline[this.suffix] = this._layoutLineBox(this.suffix, boxConstraints); } - - layoutLineBox(this.prefix); - layoutLineBox(this.suffix); - if (this.icon != null) { - this.icon.layout(boxConstraints, parentUsesSize: true); + boxToBaseline[this.icon] = this._layoutLineBox(this.icon, boxConstraints); } - if (this.prefixIcon != null) { - this.prefixIcon.layout(boxConstraints, parentUsesSize: true); + boxToBaseline[this.prefixIcon] = this._layoutLineBox(this.prefixIcon, boxConstraints); } - if (this.suffixIcon != null) { - this.suffixIcon.layout(boxConstraints, parentUsesSize: true); + boxToBaseline[this.suffixIcon] = this._layoutLineBox(this.suffixIcon, boxConstraints); } - float inputWidth = Mathf.Max(0.0f, this.constraints.maxWidth - ( - _boxSize(this.icon).width - + this.contentPadding.left - + _boxSize(this.prefixIcon).width - + _boxSize(this.prefix).width - + _boxSize(this.suffix).width - + _boxSize(this.suffixIcon).width - + this.contentPadding.right)); - - boxConstraints = boxConstraints.copyWith(maxWidth: inputWidth); + float inputWidth = Math.Max(0.0f, this.constraints.maxWidth - ( + _boxSize(this.icon).width + + this.contentPadding.left + + _boxSize(this.prefixIcon).width + + _boxSize(this.prefix).width + + _boxSize(this.suffix).width + + _boxSize(this.suffixIcon).width + + this.contentPadding.right)); if (this.label != null) { - if (this.decoration.alignLabelWithHint == true) { - layoutLineBox(this.label); - } - else { - this.label.layout(boxConstraints, parentUsesSize: true); - } + boxToBaseline[this.label] = this._layoutLineBox(this.label, + boxConstraints.copyWith(maxWidth: inputWidth) + ); } - boxConstraints = boxConstraints.copyWith(minWidth: inputWidth); - layoutLineBox(this.hint); - layoutLineBox(this.input); - - float inputBaseline = this.contentPadding.top + aboveBaseline; - float containerHeight = this.contentPadding.top - + aboveBaseline - + belowBaseline - + this.contentPadding.bottom; - - if (this.label != null) { - containerHeight += this.decoration.floatingLabelHeight; - inputBaseline += this.decoration.floatingLabelHeight; + if (this.hint != null) { + boxToBaseline[this.hint] = this._layoutLineBox(this.hint, + boxConstraints.copyWith(minWidth: inputWidth, maxWidth: inputWidth) + ); } - containerHeight = Mathf.Max( - containerHeight, - Mathf.Max( - _boxSize(this.suffixIcon).height, - _boxSize(this.prefixIcon).height)); + if (this.counter != null) { + boxToBaseline[this.counter] = this._layoutLineBox(this.counter, boxConstraints); + } - float outlineBaseline = aboveBaseline + - (containerHeight - (2.0f + aboveBaseline + belowBaseline)) / 2.0f; + if (this.helperError != null) { + boxToBaseline[this.helperError] = this._layoutLineBox(this.helperError, + boxConstraints.copyWith( + maxWidth: Math.Max(0.0f, boxConstraints.maxWidth + - _boxSize(this.icon).width + - _boxSize(this.counter).width + - this.contentPadding.horizontal + ) + ) + ); + } - float subtextBaseline = 0.0f; - float subtextHeight = 0.0f; - if (this.helperError != null || this.counter != null) { - boxConstraints = layoutConstraints.loosen(); - aboveBaseline = 0.0f; - belowBaseline = 0.0f; - layoutLineBox(this.counter); - - boxConstraints = boxConstraints.copyWith( - maxWidth: Mathf.Max(0.0f, boxConstraints.maxWidth - - _boxSize(this.icon).width - - _boxSize(this.counter).width - - this.contentPadding.horizontal + float labelHeight = this.label == null + ? 0 + : this.decoration.floatingLabelHeight; + float topHeight = this.decoration.border.isOutline + ? Math.Max(labelHeight - boxToBaseline.getOrDefault(this.label, 0), 0) + : labelHeight; + float counterHeight = this.counter == null + ? 0 + : boxToBaseline.getOrDefault(this.counter, 0) + subtextGap; + bool helperErrorExists = this.helperError?.size != null + && this.helperError.size.height > 0; + float helperErrorHeight = !helperErrorExists + ? 0 + : this.helperError.size.height + subtextGap; + float bottomHeight = Math.Max( + counterHeight, + helperErrorHeight + ); + if (this.input != null) { + boxToBaseline[this.input] = this._layoutLineBox(this.input, + boxConstraints.deflate(EdgeInsets.only( + top: this.contentPadding.top + topHeight, + bottom: this.contentPadding.bottom + bottomHeight + )).copyWith( + minWidth: inputWidth, + maxWidth: inputWidth ) ); - layoutLineBox(this.helperError); + } - if (aboveBaseline + belowBaseline > 0.0f) { - const float subtextGap = 8.0f; - subtextBaseline = containerHeight + subtextGap + aboveBaseline; - subtextHeight = subtextGap + aboveBaseline + belowBaseline; - } + // The field can be occupied by a hint or by the input itself + float hintHeight = this.hint == null ? 0 : this.hint.size.height; + float inputDirectHeight = this.input == null ? 0 : this.input.size.height; + float inputHeight = Math.Max(hintHeight, inputDirectHeight); + float inputInternalBaseline = Math.Max( + boxToBaseline.getOrDefault(this.input, 0.0f), + boxToBaseline.getOrDefault(this.hint, 0.0f) + ); + + // Calculate the amount that prefix/suffix affects height above and below + // the input. + float prefixHeight = this.prefix == null ? 0 : this.prefix.size.height; + float suffixHeight = this.suffix == null ? 0 : this.suffix.size.height; + float fixHeight = Math.Max( + boxToBaseline.getOrDefault(this.prefix, 0.0f), + boxToBaseline.getOrDefault(this.suffix, 0.0f) + ); + float fixAboveInput = Math.Max(0, fixHeight - inputInternalBaseline); + float fixBelowBaseline = Math.Max( + prefixHeight - boxToBaseline.getOrDefault(this.prefix, 0.0f), + suffixHeight - boxToBaseline.getOrDefault(this.suffix, 0.0f) + ); + float fixBelowInput = Math.Max( + 0, + fixBelowBaseline - (inputHeight - inputInternalBaseline) + ); + + // Calculate the height of the input text container. + float prefixIconHeight = this.prefixIcon == null ? 0 : this.prefixIcon.size.height; + float suffixIconHeight = this.suffixIcon == null ? 0 : this.suffixIcon.size.height; + float fixIconHeight = Math.Max(prefixIconHeight, suffixIconHeight); + float contentHeight = Math.Max( + fixIconHeight, + topHeight + + this.contentPadding.top + + fixAboveInput + + inputHeight + + fixBelowInput + + this.contentPadding.bottom + ); + float maxContainerHeight = boxConstraints.maxHeight - bottomHeight; + float containerHeight = this.expands + ? maxContainerHeight + : Math.Min(contentHeight, maxContainerHeight); + + // Always position the prefix/suffix in the same place (baseline). + float overflow = Math.Max(0, contentHeight - maxContainerHeight); + float baselineAdjustment = fixAboveInput - overflow; + + // The baselines that will be used to draw the actual input text content. + float inputBaseline = this.contentPadding.top + + topHeight + + inputInternalBaseline + + baselineAdjustment; + // The text in the input when an outline border is present is centered + // within the container less 2.0 dps at the top to account for the vertical + // space occupied by the floating label. + float outlineBaseline = inputInternalBaseline + + baselineAdjustment / 2 + + (containerHeight - (2.0f + inputHeight)) / 2.0f; + + // Find the positions of the text below the input when it exists. + float subtextCounterBaseline = 0; + float subtextHelperBaseline = 0; + float subtextCounterHeight = 0; + float subtextHelperHeight = 0; + if (this.counter != null) { + subtextCounterBaseline = + containerHeight + subtextGap + boxToBaseline.getOrDefault(this.counter, 0.0f); + subtextCounterHeight = this.counter.size.height + subtextGap; } + if (helperErrorExists) { + subtextHelperBaseline = + containerHeight + subtextGap + boxToBaseline.getOrDefault(this.helperError, 0.0f); + subtextHelperHeight = helperErrorHeight; + } + + float subtextBaseline = Math.Max( + subtextCounterBaseline, + subtextHelperBaseline + ); + float subtextHeight = Math.Max( + subtextCounterHeight, + subtextHelperHeight + ); + return new _RenderDecorationLayout( boxToBaseline: boxToBaseline, containerHeight: containerHeight, @@ -1056,7 +1156,7 @@ float _lineHeight(float width, List boxes) { protected override float computeMinIntrinsicHeight(float width) { float subtextHeight = this._lineHeight(width, new List {this.helperError, this.counter}); if (subtextHeight > 0.0f) { - subtextHeight += 8.0f; + subtextHeight += subtextGap; } return this.contentPadding.top @@ -1066,13 +1166,12 @@ protected override float computeMinIntrinsicHeight(float width) { + this.contentPadding.bottom; } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { return this.computeMinIntrinsicHeight(width); } protected override float? computeDistanceToActualBaseline(TextBaseline baseline) { - D.assert(false, () => "not implemented"); - return 0.0f; + return _boxParentData(this.input).offset.dy + this.input.getDistanceToActualBaseline(baseline); } Matrix3 _labelTransform; @@ -1405,18 +1504,22 @@ public _Decorator( Key key = null, _Decoration decoration = null, TextBaseline? textBaseline = null, - bool isFocused = false + bool isFocused = false, + bool? expands = null ) : base(key: key) { D.assert(decoration != null); D.assert(textBaseline != null); + D.assert(expands != null); this.decoration = decoration; this.textBaseline = textBaseline; this.isFocused = isFocused; + this.expands = expands.Value; } public readonly _Decoration decoration; public readonly TextBaseline? textBaseline; public readonly bool isFocused; + public readonly bool expands; public override Element createElement() { return new _RenderDecorationElement(this); @@ -1426,7 +1529,8 @@ public override RenderObject createRenderObject(BuildContext context) { return new _RenderDecoration( decoration: this.decoration, textBaseline: this.textBaseline, - isFocused: this.isFocused + isFocused: this.isFocused, + expands: this.expands ); } @@ -1435,6 +1539,7 @@ public override void updateRenderObject(BuildContext context, RenderObject _rend renderObject.decoration = this.decoration; renderObject.textBaseline = this.textBaseline; renderObject.isFocused = this.isFocused; + renderObject.expands = this.expands; } } @@ -1476,6 +1581,7 @@ public InputDecorator( TextStyle baseStyle = null, TextAlign? textAlign = null, bool isFocused = false, + bool expands = false, bool isEmpty = false, Widget child = null ) : base(key: key) { @@ -1483,6 +1589,7 @@ public InputDecorator( this.baseStyle = baseStyle; this.textAlign = textAlign; this.isFocused = isFocused; + this.expands = expands; this.isEmpty = isEmpty; this.child = child; } @@ -1494,6 +1601,8 @@ public InputDecorator( public readonly TextAlign? textAlign; public readonly bool isFocused; + + public readonly bool expands; public readonly bool isEmpty; @@ -1518,6 +1627,7 @@ public override void debugFillProperties(DiagnosticPropertiesBuilder properties) properties.add(new DiagnosticsProperty("decoration", this.decoration)); properties.add(new DiagnosticsProperty("baseStyle", this.baseStyle, defaultValue: null)); properties.add(new DiagnosticsProperty("isFocused", this.isFocused)); + properties.add(new DiagnosticsProperty("expands", this.expands)); properties.add(new DiagnosticsProperty("isEmpty", this.isEmpty)); } } @@ -1928,7 +2038,8 @@ public override Widget build(BuildContext context) { container: container ), textBaseline: textBaseline, - isFocused: this.isFocused + isFocused: this.isFocused, + expands: this.widget.expands ); } } @@ -1972,8 +2083,10 @@ public InputDecoration( bool? alignLabelWithHint = null ) { D.assert(enabled != null); - D.assert(!(prefix != null && prefixText != null), () => "Declaring both prefix and prefixText is not supported"); - D.assert(!(suffix != null && suffixText != null), () => "Declaring both suffix and suffixText is not supported"); + D.assert(!(prefix != null && prefixText != null), + () => "Declaring both prefix and prefixText is not supported"); + D.assert(!(suffix != null && suffixText != null), + () => "Declaring both suffix and suffixText is not supported"); this.isCollapsed = false; this.icon = icon; this.labelText = labelText; @@ -1989,8 +2102,12 @@ public InputDecoration( this.hasFloatingPlaceholder = hasFloatingPlaceholder; this.isDense = isDense; this.contentPadding = contentPadding; + this.prefix = prefix; + this.prefixText = prefixText; this.prefixIcon = prefixIcon; this.prefixStyle = prefixStyle; + this.suffix = suffix; + this.suffixText = suffixText; this.suffixIcon = suffixIcon; this.suffixStyle = suffixStyle; this.counter = counter; diff --git a/Runtime/material/list_tile.cs b/Runtime/material/list_tile.cs index 4c647a70..c91b9fb8 100644 --- a/Runtime/material/list_tile.cs +++ b/Runtime/material/list_tile.cs @@ -749,7 +749,7 @@ protected override float computeMinIntrinsicHeight(float width) { this.title.getMinIntrinsicHeight(width) + this.subtitle?.getMinIntrinsicHeight(width) ?? 0.0f); } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { return this.computeMinIntrinsicHeight(width); } @@ -783,11 +783,23 @@ protected override void performLayout() { bool hasTrailing = this.trailing != null; bool isTwoLine = !this.isThreeLine && hasSubtitle; bool isOneLine = !this.isThreeLine && !hasSubtitle; + BoxConstraints maxIconHeightConstrains = new BoxConstraints( + maxHeight: this.isDense ? 48.0f: 56.0f + ); BoxConstraints looseConstraints = this.constraints.loosen(); + BoxConstraints iconConstraints = looseConstraints.enforce(maxIconHeightConstrains); float tileWidth = looseConstraints.maxWidth; - Size leadingSize = _layoutBox(this.leading, looseConstraints); - Size trailingSize = _layoutBox(this.trailing, looseConstraints); + Size leadingSize = _layoutBox(this.leading, iconConstraints); + Size trailingSize = _layoutBox(this.trailing, iconConstraints); + D.assert( + tileWidth != leadingSize.width, + () => "Leading widget consumes entire width. Please use a sized widget." + ); + D.assert( + tileWidth != trailingSize.width, + () => "Trailing widget consumes entire width. Please use a sized widget." + ); float titleStart = hasLeading ? Mathf.Max(_minLeadingWidth, leadingSize.width) + _horizontalTitleGap diff --git a/Runtime/material/material.cs b/Runtime/material/material.cs index d411d93c..14f01f0c 100644 --- a/Runtime/material/material.cs +++ b/Runtime/material/material.cs @@ -149,7 +149,11 @@ Color _getBackgroundColor(BuildContext context) { public override Widget build(BuildContext context) { Color backgroundColor = this._getBackgroundColor(context); - D.assert(backgroundColor != null || this.widget.type == MaterialType.transparency); + D.assert(backgroundColor != null || this.widget.type == MaterialType.transparency, + () => "If Material type is not MaterialType.transparency, a color must" + + "either be passed in through the 'color' property, or be defined " + + "in the theme (ex. canvasColor != null if type is set to " + + "MaterialType.canvas"); Widget contents = this.widget.child; if (contents != null) { contents = new AnimatedDefaultTextStyle( diff --git a/Runtime/material/material_button.cs b/Runtime/material/material_button.cs index 79964a40..637b831a 100644 --- a/Runtime/material/material_button.cs +++ b/Runtime/material/material_button.cs @@ -107,7 +107,7 @@ public override Widget build(BuildContext context) { return new RawMaterialButton( onPressed: this.onPressed, onHighlightChanged: this.onHighlightChanged, - fillColor: this.color, + fillColor: buttonTheme.getFillColor(this), textStyle: theme.textTheme.button.copyWith(color: buttonTheme.getTextColor(this)), highlightColor: this.highlightColor ?? theme.highlightColor, splashColor: this.splashColor ?? theme.splashColor, @@ -117,7 +117,7 @@ public override Widget build(BuildContext context) { constraints: buttonTheme.getConstraints(this).copyWith( minWidth: this.minWidth, minHeight: this.height), - shape: buttonTheme.shape, + shape: buttonTheme.getShape(this), clipBehavior: this.clipBehavior ?? Clip.none, animationDuration: buttonTheme.getAnimationDuration(this), child: this.child, diff --git a/Runtime/material/material_localizations.cs b/Runtime/material/material_localizations.cs index 87944712..acf44c4c 100644 --- a/Runtime/material/material_localizations.cs +++ b/Runtime/material/material_localizations.cs @@ -189,7 +189,7 @@ public override string formatYear(DateTime date) { public override string formatMediumDate(DateTime date) { string day = _shortWeekdays[((int) date.DayOfWeek + 6) % 7]; string month = _shortMonths[date.Month - 1]; - return $"{day}, {month} ${date.Day}"; + return $"{day}, {month} {date.Day}"; } public override string formatFullDate(DateTime date) { diff --git a/Runtime/material/popup_menu.cs b/Runtime/material/popup_menu.cs index a87139e5..1bcfd804 100644 --- a/Runtime/material/popup_menu.cs +++ b/Runtime/material/popup_menu.cs @@ -479,6 +479,7 @@ public static IPromise showMenu( float elevation = 8.0f ) { D.assert(context != null); + D.assert(position != null); D.assert(items != null && items.isNotEmpty()); D.assert(MaterialD.debugCheckHasMaterialLocalizations(context)); diff --git a/Runtime/material/progress_indicator.cs b/Runtime/material/progress_indicator.cs index 5b95ccea..de1652bf 100644 --- a/Runtime/material/progress_indicator.cs +++ b/Runtime/material/progress_indicator.cs @@ -233,6 +233,7 @@ public override Widget build(BuildContext context) { class _CircularProgressIndicatorPainter : AbstractCustomPainter { public _CircularProgressIndicatorPainter( + Color backgroundColor = null, Color valueColor = null, float? value = null, float? headValue = null, @@ -241,6 +242,7 @@ public _CircularProgressIndicatorPainter( float? rotationValue = null, float? strokeWidth = null ) { + this.backgroundColor = backgroundColor; this.valueColor = valueColor; this.value = value; this.headValue = headValue; @@ -257,6 +259,7 @@ public _CircularProgressIndicatorPainter( : Mathf.Max(headValue * 3 / 2 * Mathf.PI - tailValue * 3 / 2 * Mathf.PI ?? 0.0f, _epsilon); } + public readonly Color backgroundColor; public readonly Color valueColor; public readonly float? value; public readonly float? headValue; @@ -279,6 +282,15 @@ public override void paint(Canvas canvas, Size size) { paint.strokeWidth = this.strokeWidth ?? 0.0f; paint.style = PaintingStyle.stroke; + if (this.backgroundColor != null) { + Paint backgroundPaint = new Paint() { + color = this.backgroundColor, + strokeWidth = this.strokeWidth ?? 0.0f, + style = PaintingStyle.stroke + }; + canvas.drawArc(Offset.zero & size, 0, _sweep, false, backgroundPaint); + } + if (this.value == null) { paint.strokeCap = StrokeCap.square; @@ -290,7 +302,8 @@ public override void paint(Canvas canvas, Size size) { public override bool shouldRepaint(CustomPainter oldPainter) { D.assert(oldPainter is _CircularProgressIndicatorPainter); _CircularProgressIndicatorPainter painter = oldPainter as _CircularProgressIndicatorPainter; - return painter.valueColor != this.valueColor + return painter.backgroundColor != this.backgroundColor + || painter.valueColor != this.valueColor || painter.value != this.value || painter.headValue != this.headValue || painter.tailValue != this.tailValue @@ -365,6 +378,7 @@ Widget _buildIndicator(BuildContext context, float headValue, float tailValue, i ), child: new CustomPaint( painter: new _CircularProgressIndicatorPainter( + backgroundColor: this.widget.backgroundColor, valueColor: this.widget._getValueColor(context), value: this.widget.value, headValue: headValue, diff --git a/Runtime/material/radio.cs b/Runtime/material/radio.cs index 8f4cad9e..bab37e8a 100644 --- a/Runtime/material/radio.cs +++ b/Runtime/material/radio.cs @@ -162,8 +162,7 @@ TickerProvider vsync public override void paint(PaintingContext context, Offset offset) { Canvas canvas = context.canvas; - this.paintRadialReaction(canvas, offset, - new Offset(Constants.kRadialReactionRadius, Constants.kRadialReactionRadius)); + this.paintRadialReaction(canvas, offset, this.size.center(Offset.zero)); Offset center = (offset & this.size).center; Color radioColor = this.onChanged != null ? this.activeColor : this.inactiveColor; diff --git a/Runtime/material/scaffold.cs b/Runtime/material/scaffold.cs index f6bf2d95..d0d1030e 100644 --- a/Runtime/material/scaffold.cs +++ b/Runtime/material/scaffold.cs @@ -198,6 +198,92 @@ public void _updateWith( } } + class _BodyBoxConstraints : BoxConstraints { + public _BodyBoxConstraints( + float minWidth = 0.0f, + float maxWidth = float.PositiveInfinity, + float minHeight = 0.0f, + float maxHeight = float.PositiveInfinity, + float? bottomWidgetsHeight = null + ) : base(minWidth: minWidth, maxWidth: maxWidth, minHeight: minHeight, maxHeight: maxHeight) { + D.assert(bottomWidgetsHeight != null); + D.assert(bottomWidgetsHeight >= 0); + this.bottomWidgetsHeight = bottomWidgetsHeight.Value; + } + + public readonly float bottomWidgetsHeight; + + public bool Equals(_BodyBoxConstraints other) { + if (ReferenceEquals(null, other)) { + return false; + } + + if (ReferenceEquals(this, other)) { + return true; + } + + return this.bottomWidgetsHeight.Equals(other.bottomWidgetsHeight) + && base.Equals(other); + } + + public override bool Equals(object obj) { + if (ReferenceEquals(null, obj)) { + return false; + } + + if (ReferenceEquals(this, obj)) { + return true; + } + + if (obj.GetType() != this.GetType()) { + return false; + } + + return this.Equals((_BodyBoxConstraints) obj); + } + + public override int GetHashCode() { + unchecked { + var hashCode = base.GetHashCode(); + hashCode = (hashCode * 397) ^ this.bottomWidgetsHeight.GetHashCode(); + return hashCode; + } + } + + public static bool operator ==(_BodyBoxConstraints left, _BodyBoxConstraints right) { + return Equals(left, right); + } + + public static bool operator !=(_BodyBoxConstraints left, _BodyBoxConstraints right) { + return !Equals(left, right); + } + } + + class _BodyBuilder : StatelessWidget { + public _BodyBuilder(Key key = null, Widget body = null) : base(key: key) { + this.body = body; + } + + public readonly Widget body; + + public override Widget build(BuildContext context) { + return new LayoutBuilder( + builder: (ctx, constraints) => { + _BodyBoxConstraints bodyConstraints = (_BodyBoxConstraints) constraints; + MediaQueryData metrics = MediaQuery.of(context); + return new MediaQuery( + data: metrics.copyWith( + padding: metrics.padding.copyWith( + bottom: Mathf.Max(metrics.padding.bottom, bodyConstraints.bottomWidgetsHeight) + ) + ), + child: this.body + ); + } + ); + } + } + class _ScaffoldLayout : MultiChildLayoutDelegate { public _ScaffoldLayout( EdgeInsets minInsets, @@ -205,7 +291,8 @@ public _ScaffoldLayout( FloatingActionButtonLocation previousFloatingActionButtonLocation, FloatingActionButtonLocation currentFloatingActionButtonLocation, float floatingActionButtonMoveAnimationProgress, - FloatingActionButtonAnimator floatingActionButtonMotionAnimator + FloatingActionButtonAnimator floatingActionButtonMotionAnimator, + bool extendBody ) { D.assert(minInsets != null); D.assert(geometryNotifier != null); @@ -218,8 +305,11 @@ FloatingActionButtonAnimator floatingActionButtonMotionAnimator this.currentFloatingActionButtonLocation = currentFloatingActionButtonLocation; this.floatingActionButtonMoveAnimationProgress = floatingActionButtonMoveAnimationProgress; this.floatingActionButtonMotionAnimator = floatingActionButtonMotionAnimator; + this.extendBody = extendBody; } + public readonly bool extendBody; + public readonly EdgeInsets minInsets; public readonly _ScaffoldGeometryNotifier geometryNotifier; @@ -270,9 +360,15 @@ public override void performLayout(Size size) { float contentBottom = Mathf.Max(0.0f, bottom - Mathf.Max(this.minInsets.bottom, bottomWidgetsHeight)); if (this.hasChild(_ScaffoldSlot.body)) { - BoxConstraints bodyConstraints = new BoxConstraints( + float bodyMaxHeight = Mathf.Max(0.0f, contentBottom - contentTop); + if (this.extendBody) { + bodyMaxHeight += bottomWidgetsHeight; + D.assert(bodyMaxHeight <= Mathf.Max(0.0f, looseConstraints.maxHeight - contentTop)); + } + BoxConstraints bodyConstraints = new _BodyBoxConstraints( maxWidth: fullWidthConstraints.maxWidth, - maxHeight: Mathf.Max(0.0f, contentBottom - contentTop) + maxHeight: bodyMaxHeight, + bottomWidgetsHeight: this.extendBody ? bottomWidgetsHeight : 0.0f ); this.layoutChild(_ScaffoldSlot.body, bodyConstraints); this.positionChild(_ScaffoldSlot.body, new Offset(0.0f, contentTop)); @@ -591,7 +687,8 @@ public Scaffold( bool? resizeToAvoidBottomPadding = null, bool? resizeToAvoidBottomInset = null, bool primary = true, - DragStartBehavior drawerDragStartBehavior = DragStartBehavior.down + DragStartBehavior drawerDragStartBehavior = DragStartBehavior.start, + bool extendBody = false ) : base(key: key) { this.appBar = appBar; this.body = body; @@ -608,8 +705,11 @@ public Scaffold( this.resizeToAvoidBottomInset = resizeToAvoidBottomInset; this.primary = primary; this.drawerDragStartBehavior = drawerDragStartBehavior; + this.extendBody = extendBody; } + public readonly bool extendBody; + public readonly PreferredSizeWidget appBar; public readonly Widget body; @@ -1169,7 +1269,8 @@ public override Widget build(BuildContext context) { this._addIfNonNull( children: children, - child: this.widget.body, + child: this.widget.body != null && this.widget.extendBody + ? new _BodyBuilder(body: this.widget.body) : this.widget.body, childId: _ScaffoldSlot.body, removeLeftPadding: false, removeTopPadding: this.widget.appBar != null, @@ -1323,6 +1424,8 @@ public override Widget build(BuildContext context) { bottom: this._resizeToAvoidBottomInset ? mediaQuery.viewInsets.bottom : 0.0f ); + bool _extendBody = !(minInsets.bottom > 0) && this.widget.extendBody; + return new _ScaffoldScope( hasDrawer: this.hasDrawer, geometryNotifier: this._geometryNotifier, @@ -1335,6 +1438,7 @@ public override Widget build(BuildContext context) { return new CustomMultiChildLayout( children: new List(children), layoutDelegate: new _ScaffoldLayout( + extendBody: _extendBody, minInsets: minInsets, currentFloatingActionButtonLocation: this._floatingActionButtonLocation, floatingActionButtonMoveAnimationProgress: this diff --git a/Runtime/material/search.cs b/Runtime/material/search.cs new file mode 100644 index 00000000..2644b761 --- /dev/null +++ b/Runtime/material/search.cs @@ -0,0 +1,284 @@ +using System; +using System.Collections.Generic; +using RSG; +using Unity.UIWidgets.animation; +using Unity.UIWidgets.foundation; +using Unity.UIWidgets.service; +using Unity.UIWidgets.widgets; +using UnityEngine; +using Color = Unity.UIWidgets.ui.Color; + +namespace Unity.UIWidgets.material { + public class SearchUtils { + public static IPromise showSearch( + BuildContext context, + SearchDelegate del, + string query = "" + ) { + D.assert(del != null); + D.assert(context != null); + + del.query = query ?? del.query; + del._currentBody = _SearchBody.suggestions; + return Navigator.of(context).push(new _SearchPageRoute( + del: del + )); + } + } + + public abstract class SearchDelegate { + public abstract Widget buildSuggestions(BuildContext context); + public abstract Widget buildResults(BuildContext context); + public abstract Widget buildLeading(BuildContext context); + public abstract List buildActions(BuildContext context); + + public virtual ThemeData appBarTheme(BuildContext context) { + D.assert(context != null); + ThemeData theme = Theme.of(context); + D.assert(theme != null); + return theme.copyWith( + primaryColor: Colors.white, + primaryIconTheme: theme.primaryIconTheme.copyWith(color: Colors.grey), + primaryColorBrightness: Brightness.light, + primaryTextTheme: theme.textTheme + ); + } + + public virtual string query { + get { return this._queryTextController.text; } + set { + D.assert(this.query != null); + this._queryTextController.text = value; + } + } + + public virtual void showResults(BuildContext context) { + this._focusNode.unfocus(); + this._currentBody = _SearchBody.results; + } + + public virtual void showSuggestions(BuildContext context) { + FocusScope.of(context).requestFocus(this._focusNode); + this._currentBody = _SearchBody.suggestions; + } + + public virtual void close(BuildContext context, object result) { + this._currentBody = null; + this._focusNode.unfocus(); + var state = Navigator.of(context); + state.popUntil((Route route) => route == this._route); + state.pop(result); + } + + + public virtual Animation transitionAnimation { + get { return this._proxyAnimation; } + } + + readonly internal FocusNode _focusNode = new FocusNode(); + + readonly internal TextEditingController _queryTextController = new TextEditingController(); + + readonly internal ProxyAnimation _proxyAnimation = new ProxyAnimation(Animations.kAlwaysDismissedAnimation); + + readonly internal ValueNotifier<_SearchBody?> _currentBodyNotifier = new ValueNotifier<_SearchBody?>(null); + + internal _SearchBody? _currentBody { + get { return this._currentBodyNotifier.value; } + set { this._currentBodyNotifier.value = value; } + } + + internal _SearchPageRoute _route; + } + + enum _SearchBody { + suggestions, + results + } + + class _SearchPageRoute : PageRoute { + public _SearchPageRoute(SearchDelegate del) { + D.assert(del != null); + D.assert(del._route == null, + () => $"The {this.del.GetType()} instance is currently used by another active " + + "search. Please close that search by calling close() on the SearchDelegate " + + "before openening another search with the same delegate instance." + ); + this.del = del; + this.del._route = this; + } + + public readonly SearchDelegate del; + + public override Color barrierColor { + get { return null; } + } + + public override TimeSpan transitionDuration { + get { return new TimeSpan(0, 0, 0, 0, 300); } + } + + public override bool maintainState { + get { return false; } + } + + public override Widget buildTransitions( + BuildContext context, + Animation animation, + Animation secondaryAnimation, + Widget child + ) { + return new FadeTransition( + opacity: animation, + child: child + ); + } + + public override Animation createAnimation() { + Animation animation = base.createAnimation(); + this.del._proxyAnimation.parent = animation; + return animation; + } + + public override Widget buildPage( + BuildContext context, + Animation animation, + Animation secondaryAnimation + ) { + return new _SearchPage( + del: this.del, + animation: animation + ); + } + + protected internal override void didComplete(object result) { + base.didComplete(result); + D.assert(this.del._route == this); + this.del._route = null; + this.del._currentBody = null; + } + } + + class _SearchPage : StatefulWidget { + public _SearchPage( + SearchDelegate del, + Animation animation + ) { + this.del = del; + this.animation = animation; + } + + public readonly SearchDelegate del; + + public readonly Animation animation; + + public override State createState() { + return new _SearchPageState(); + } + } + + class _SearchPageState : State<_SearchPage> { + public override void initState() { + base.initState(); + this.queryTextController.addListener(this._onQueryChanged); + this.widget.animation.addStatusListener(this._onAnimationStatusChanged); + this.widget.del._currentBodyNotifier.addListener(this._onSearchBodyChanged); + this.widget.del._focusNode.addListener(this._onFocusChanged); + } + + public override void dispose() { + base.dispose(); + this.queryTextController.removeListener(this._onQueryChanged); + this.widget.animation.removeStatusListener(this._onAnimationStatusChanged); + this.widget.del._currentBodyNotifier.removeListener(this._onSearchBodyChanged); + this.widget.del._focusNode.removeListener(this._onFocusChanged); + } + + void _onAnimationStatusChanged(AnimationStatus status) { + if (status != AnimationStatus.completed) { + return; + } + + this.widget.animation.removeStatusListener(this._onAnimationStatusChanged); + if (this.widget.del._currentBody == _SearchBody.suggestions) { + FocusScope.of(this.context).requestFocus(this.widget.del._focusNode); + } + } + + void _onFocusChanged() { + if (this.widget.del._focusNode.hasFocus && this.widget.del._currentBody != _SearchBody.suggestions) { + this.widget.del.showSuggestions(this.context); + } + } + + void _onQueryChanged() { + this.setState(() => { }); + } + + void _onSearchBodyChanged() { + this.setState(() => { }); + } + + public override Widget build(BuildContext context) { + MaterialD.debugCheckHasMaterialLocalizations(context); + + ThemeData theme = this.widget.del.appBarTheme(context); + string searchFieldLabel = MaterialLocalizations.of(context).searchFieldLabel; + Widget body = null; + switch (this.widget.del._currentBody) { + case _SearchBody.suggestions: + body = new KeyedSubtree( + key: new ValueKey<_SearchBody>(_SearchBody.suggestions), + child: this.widget.del.buildSuggestions(context) + ); + break; + case _SearchBody.results: + body = new KeyedSubtree( + key: new ValueKey<_SearchBody>(_SearchBody.results), + child: this.widget.del.buildResults(context) + ); + break; + } + + string routeName; + switch (Theme.of(this.context).platform) { + case RuntimePlatform.IPhonePlayer: + routeName = ""; + break; + case RuntimePlatform.Android: + routeName = searchFieldLabel; + break; + } + + return new Scaffold( + appBar: new AppBar( + backgroundColor: theme.primaryColor, + iconTheme: theme.primaryIconTheme, + textTheme: theme.primaryTextTheme, + brightness: theme.primaryColorBrightness, + leading: this.widget.del.buildLeading(context), + title: new TextField( + controller: this.queryTextController, + focusNode: this.widget.del._focusNode, + style: theme.textTheme.title, + textInputAction: TextInputAction.search, + onSubmitted: (string _) => { this.widget.del.showResults(context); }, + decoration: new InputDecoration( + border: InputBorder.none, + hintText: searchFieldLabel + ) + ), + actions: this.widget.del.buildActions(context) + ), + body: new AnimatedSwitcher( + duration: new TimeSpan(0, 0, 0, 0, 300), + child: body + ) + ); + } + + TextEditingController queryTextController { + get { return this.widget.del._queryTextController; } + } + } +} \ No newline at end of file diff --git a/Runtime/material/search.cs.meta b/Runtime/material/search.cs.meta new file mode 100644 index 00000000..d08e6aee --- /dev/null +++ b/Runtime/material/search.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 421b92c9ff7d642af9b2e60e013c297d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/material/slider.cs b/Runtime/material/slider.cs index 28093883..048e7242 100644 --- a/Runtime/material/slider.cs +++ b/Runtime/material/slider.cs @@ -698,7 +698,7 @@ protected override float computeMinIntrinsicHeight(float width) { return Mathf.Max(this._minPreferredTrackHeight, this._maxSliderPartHeight); } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { return Mathf.Max(this._minPreferredTrackHeight, this._maxSliderPartHeight); } @@ -761,13 +761,13 @@ public override void paint(PaintingContext context, Offset offset) { sliderTheme: this._sliderTheme ).width; - if ((trackRect.width - tickMarkWidth) / this.divisions.Value >= 3.0f * tickMarkWidth) { + float adjustedTrackWidth = trackRect.width - tickMarkWidth; + if (adjustedTrackWidth / this.divisions.Value >= 3.0f * tickMarkWidth) { + float dy = trackRect.center.dy; for (int i = 0; i <= this.divisions; i++) { float tickValue = i / this.divisions.Value; - float tickX = trackRect.left + - tickValue * (trackRect.width - tickMarkWidth) + tickMarkWidth / 2; - float tickY = trackRect.center.dy; - Offset tickMarkOffset = new Offset(tickX, tickY); + float dx = trackRect.left + tickValue * adjustedTrackWidth + tickMarkWidth / 2; + Offset tickMarkOffset = new Offset(dx, dy); this._sliderTheme.tickMarkShape.paint( context, tickMarkOffset, diff --git a/Runtime/material/switch.cs b/Runtime/material/switch.cs index 0d0e24da..66943b19 100644 --- a/Runtime/material/switch.cs +++ b/Runtime/material/switch.cs @@ -34,7 +34,7 @@ public Switch( ImageProvider activeThumbImage = null, ImageProvider inactiveThumbImage = null, MaterialTapTargetSize? materialTapTargetSize = null, - DragStartBehavior dragStartBehavior = DragStartBehavior.down + DragStartBehavior dragStartBehavior = DragStartBehavior.start ) : this( key: key, value: value, @@ -63,7 +63,7 @@ public Switch( ImageProvider inactiveThumbImage = null, MaterialTapTargetSize? materialTapTargetSize = null, _SwitchType switchType = _SwitchType.material, - DragStartBehavior dragStartBehavior = DragStartBehavior.down + DragStartBehavior dragStartBehavior = DragStartBehavior.start ) : base(key: key) { D.assert(value != null); this.value = value.Value; diff --git a/Runtime/material/tab_bar_theme.cs b/Runtime/material/tab_bar_theme.cs index 521df69a..2e3f8425 100644 --- a/Runtime/material/tab_bar_theme.cs +++ b/Runtime/material/tab_bar_theme.cs @@ -11,12 +11,14 @@ public TabBarTheme( Decoration indicator = null, TabBarIndicatorSize? indicatorSize = null, Color labelColor = null, + EdgeInsets labelPadding = null, TextStyle labelStyle = null, Color unselectedLabelColor = null, TextStyle unselectedLabelStyle = null) { this.indicator = indicator; this.indicatorSize = indicatorSize; this.labelColor = labelColor; + this.labelPadding = labelPadding; this.labelStyle = labelStyle; this.unselectedLabelColor = unselectedLabelColor; this.unselectedLabelStyle = unselectedLabelStyle; @@ -28,6 +30,8 @@ public TabBarTheme( public readonly Color labelColor; + public readonly EdgeInsets labelPadding; + public readonly TextStyle labelStyle; public readonly Color unselectedLabelColor; @@ -38,6 +42,7 @@ public TabBarTheme copyWith( Decoration indicator = null, TabBarIndicatorSize? indicatorSize = null, Color labelColor = null, + EdgeInsets labelPadding = null, TextStyle labelStyle = null, Color unselectedLabelColor = null, TextStyle unselectedLabelStyle = null @@ -46,6 +51,7 @@ public TabBarTheme copyWith( indicator: indicator ?? this.indicator, indicatorSize: indicatorSize ?? this.indicatorSize, labelColor: labelColor ?? this.labelColor, + labelPadding: labelPadding ?? this.labelPadding, labelStyle: labelStyle ?? this.labelStyle, unselectedLabelColor: unselectedLabelColor ?? this.unselectedLabelColor, unselectedLabelStyle: unselectedLabelStyle ?? this.unselectedLabelStyle); @@ -62,6 +68,7 @@ public static TabBarTheme lerp(TabBarTheme a, TabBarTheme b, float t) { indicator: Decoration.lerp(a.indicator, b.indicator, t), indicatorSize: t < 0.5 ? a.indicatorSize : b.indicatorSize, labelColor: Color.lerp(a.labelColor, b.labelColor, t), + labelPadding: EdgeInsets.lerp(a.labelPadding, b.labelPadding, t), labelStyle: TextStyle.lerp(a.labelStyle, b.labelStyle, t), unselectedLabelColor: Color.lerp(a.unselectedLabelColor, b.unselectedLabelColor, t), unselectedLabelStyle: TextStyle.lerp(a.unselectedLabelStyle, b.unselectedLabelStyle, t) @@ -73,6 +80,7 @@ public override int GetHashCode() { var hashCode = this.indicator != null ? this.indicator.GetHashCode() : 0; hashCode = (hashCode * 397) ^ (this.indicatorSize != null ? this.indicatorSize.GetHashCode() : 0); hashCode = (hashCode * 397) ^ (this.labelColor != null ? this.labelColor.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (this.labelPadding != null ? this.labelPadding.GetHashCode() : 0); hashCode = (hashCode * 397) ^ (this.labelStyle != null ? this.labelStyle.GetHashCode() : 0); hashCode = (hashCode * 397) ^ (this.unselectedLabelColor != null ? this.unselectedLabelColor.GetHashCode() : 0); @@ -95,6 +103,7 @@ public bool Equals(TabBarTheme other) { return other.indicator == this.indicator && other.indicatorSize == this.indicatorSize && other.labelColor == this.labelColor && + other.labelPadding == this.labelPadding && other.unselectedLabelColor == this.unselectedLabelColor; } diff --git a/Runtime/material/tabs.cs b/Runtime/material/tabs.cs index abb67ac3..15add264 100644 --- a/Runtime/material/tabs.cs +++ b/Runtime/material/tabs.cs @@ -141,12 +141,15 @@ public _TabStyle( protected internal override Widget build(BuildContext context) { ThemeData themeData = Theme.of(context); TabBarTheme tabBarTheme = TabBarTheme.of(context); - - TextStyle defaultStyle = this.labelStyle ?? tabBarTheme.labelStyle ?? themeData.primaryTextTheme.body2; - TextStyle defaultUnselectedStyle = this.unselectedLabelStyle - ?? tabBarTheme.unselectedLabelStyle - ?? this.labelStyle ?? themeData.primaryTextTheme.body2; Animation animation = (Animation) this.listenable; + + TextStyle defaultStyle = (this.labelStyle + ?? tabBarTheme.labelStyle + ?? themeData.primaryTextTheme.body2).copyWith(inherit: true); + TextStyle defaultUnselectedStyle = (this.unselectedLabelStyle + ?? tabBarTheme.unselectedLabelStyle + ?? this.labelStyle + ?? themeData.primaryTextTheme.body2).copyWith(inherit: true); TextStyle textStyle = this.selected ? TextStyle.lerp(defaultStyle, defaultUnselectedStyle, animation.value) : TextStyle.lerp(defaultUnselectedStyle, defaultStyle, animation.value); @@ -508,7 +511,7 @@ public TabBar( EdgeInsets labelPadding = null, Color unselectedLabelColor = null, TextStyle unselectedLabelStyle = null, - DragStartBehavior dragStartBehavior = DragStartBehavior.down, + DragStartBehavior dragStartBehavior = DragStartBehavior.start, ValueChanged onTap = null ) : base(key: key) { indicatorPadding = indicatorPadding ?? EdgeInsets.zero; @@ -639,6 +642,16 @@ void _updateTabController() { return true; }); + D.assert(() => { + if (newController.length != this.widget.tabs.Count) { + throw new UIWidgetsError( + $"Controller's length property {newController.length} does not match the\n" + + $"number of tab elements {this.widget.tabs.Count} present in TabBar's tabs property." + ); + } + + return true; + }); if (newController == this._controller) { return; } @@ -827,12 +840,14 @@ public override Widget build(BuildContext context) { ); } + TabBarTheme tabBarTheme = TabBarTheme.of(context); + List wrappedTabs = new List(); for (int i = 0; i < this.widget.tabs.Count; i++) { wrappedTabs.Add(new Center( heightFactor: 1.0f, child: new Padding( - padding: this.widget.labelPadding ?? Constants.kTabLabelPadding, + padding: this.widget.labelPadding ?? tabBarTheme.labelPadding ?? Constants.kTabLabelPadding, child: new KeyedSubtree( key: this._tabKeys[i], child: this.widget.tabs[i] @@ -926,7 +941,7 @@ public TabBarView( List children = null, TabController controller = null, ScrollPhysics physics = null, - DragStartBehavior dragStartBehavior = DragStartBehavior.down + DragStartBehavior dragStartBehavior = DragStartBehavior.start ) : base(key: key) { D.assert(children != null); this.children = children; @@ -970,6 +985,16 @@ void _updateTabController() { return true; }); + D.assert(() => { + if (newController.length != this.widget.children.Count) { + throw new UIWidgetsError( + $"Controller's length property {newController.length} does not match the\n" + + $"number of elements {this.widget.children.Count} present in TabBarView's children property." + ); + } + + return true; + }); if (newController == this._controller) { return; } diff --git a/Runtime/material/text_field.cs b/Runtime/material/text_field.cs index 81a3b28e..bb9dcbfb 100644 --- a/Runtime/material/text_field.cs +++ b/Runtime/material/text_field.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Text; using Unity.UIWidgets.foundation; using Unity.UIWidgets.gestures; using Unity.UIWidgets.painting; @@ -19,23 +20,48 @@ public delegate Widget InputCounterWidgetBuilder( bool? isFocused); public class TextField : StatefulWidget { - public TextField(Key key = null, TextEditingController controller = null, FocusNode focusNode = null, - InputDecoration decoration = null, bool noDecoration = false, TextInputType keyboardType = null, + public TextField(Key key = null, + TextEditingController controller = null, + FocusNode focusNode = null, + InputDecoration decoration = null, + bool noDecoration = false, + TextInputType keyboardType = null, TextInputAction? textInputAction = null, - TextCapitalization textCapitalization = TextCapitalization.none, TextStyle style = null, - TextAlign textAlign = TextAlign.left, TextDirection textDirection = TextDirection.ltr, - bool autofocus = false, bool obscureText = false, bool autocorrect = false, int? maxLines = 1, - int? maxLength = null, bool maxLengthEnforced = true, ValueChanged onChanged = null, + TextCapitalization textCapitalization = TextCapitalization.none, + TextStyle style = null, + StrutStyle strutStyle = null, + TextAlign textAlign = TextAlign.left, + TextDirection textDirection = TextDirection.ltr, + bool autofocus = false, + bool obscureText = false, + bool autocorrect = false, + int? maxLines = 1, + int? minLines = null, + bool expands = false, + int? maxLength = null, + bool maxLengthEnforced = true, + ValueChanged onChanged = null, VoidCallback onEditingComplete = null, - ValueChanged onSubmitted = null, List inputFormatters = null, - bool? enabled = null, float? cursorWidth = 2.0f, Radius cursorRadius = null, Color cursorColor = null, - Brightness? keyboardAppearance = null, EdgeInsets scrollPadding = null, - DragStartBehavior dragStartBehavior = DragStartBehavior.down, + ValueChanged onSubmitted = null, + List inputFormatters = null, + bool? enabled = null, + float? cursorWidth = 2.0f, + Radius cursorRadius = null, + Color cursorColor = null, + Brightness? keyboardAppearance = null, + EdgeInsets scrollPadding = null, + DragStartBehavior dragStartBehavior = DragStartBehavior.start, bool? enableInteractiveSelection = null, GestureTapCallback onTap = null, - InputCounterWidgetBuilder buildCounter = null + InputCounterWidgetBuilder buildCounter = null, + ScrollPhysics scrollPhysics = null ) : base(key: key) { D.assert(maxLines == null || maxLines > 0); + D.assert(minLines == null || minLines > 0); + D.assert((maxLines == null) || (minLines == null) || (maxLines >= minLines), + () => "minLines can't be greater than maxLines"); + D.assert(!expands || (maxLines == null && minLines == null), + () => "minLines and maxLines must be null when expands is true."); D.assert(maxLength == null || maxLength == TextField.noMaxLength || maxLength > 0); this.controller = controller; @@ -44,12 +70,15 @@ public TextField(Key key = null, TextEditingController controller = null, FocusN this.textInputAction = textInputAction; this.textCapitalization = textCapitalization; this.style = style; + this.strutStyle = strutStyle; this.textAlign = textAlign; this.textDirection = textDirection; this.autofocus = autofocus; this.obscureText = obscureText; this.autocorrect = autocorrect; this.maxLines = maxLines; + this.minLines = minLines; + this.expands = expands; this.maxLength = maxLength; this.maxLengthEnforced = maxLengthEnforced; this.onChanged = onChanged; @@ -68,6 +97,7 @@ public TextField(Key key = null, TextEditingController controller = null, FocusN this.scrollPadding = scrollPadding ?? EdgeInsets.all(20.0f); this.dragStartBehavior = dragStartBehavior; this.buildCounter = buildCounter; + this.scrollPhysics = scrollPhysics; } public readonly TextEditingController controller; @@ -84,6 +114,8 @@ public TextField(Key key = null, TextEditingController controller = null, FocusN public readonly TextStyle style; + public readonly StrutStyle strutStyle; + public readonly TextAlign textAlign; public readonly TextDirection textDirection; @@ -95,6 +127,10 @@ public TextField(Key key = null, TextEditingController controller = null, FocusN public readonly bool autocorrect; public readonly int? maxLines; + + public readonly int? minLines; + + public readonly bool expands; public const long noMaxLength = -1; @@ -125,6 +161,8 @@ public TextField(Key key = null, TextEditingController controller = null, FocusN public readonly bool? enableInteractiveSelection; public readonly DragStartBehavior dragStartBehavior; + + public readonly ScrollPhysics scrollPhysics; public bool selectionEnabled { get { @@ -154,6 +192,8 @@ public override void debugFillProperties(DiagnosticPropertiesBuilder properties) properties.add(new DiagnosticsProperty("obscureText", this.obscureText, defaultValue: false)); properties.add(new DiagnosticsProperty("autocorrect", this.autocorrect, defaultValue: true)); properties.add(new IntProperty("maxLines", this.maxLines, defaultValue: 1)); + properties.add(new IntProperty("minLines", this.minLines, defaultValue: null)); + properties.add(new DiagnosticsProperty("expands", this.expands, defaultValue: false)); properties.add(new IntProperty("maxLength", this.maxLength, defaultValue: null)); properties.add(new FlagProperty("maxLengthEnforced", value: this.maxLengthEnforced, defaultValue: true, ifFalse: "maxLength not enforced")); @@ -167,6 +207,7 @@ public override void debugFillProperties(DiagnosticPropertiesBuilder properties) properties.add(new DiagnosticsProperty("keyboardAppearance", this.keyboardAppearance, defaultValue: null)); properties.add(new DiagnosticsProperty("scrollPadding", this.scrollPadding, defaultValue: EdgeInsets.all(20.0f))); properties.add(new FlagProperty("selectionEnabled", value: this.selectionEnabled, defaultValue: true, ifFalse: "selection disabled")); + properties.add(new DiagnosticsProperty("scrollPhysics", this.scrollPhysics, defaultValue: null)); } } @@ -294,9 +335,14 @@ void _requestKeyboard() { } void _handleSelectionChanged(TextSelection selection, SelectionChangedCause cause) { - if (Theme.of(this.context).platform == RuntimePlatform.IPhonePlayer - && cause == SelectionChangedCause.longPress) { - this._editableTextKey.currentState?.bringIntoView(selection.basePos); + switch (Theme.of(this.context).platform) { + case RuntimePlatform.IPhonePlayer: + if (cause == SelectionChangedCause.longPress) { + this._editableTextKey.currentState?.bringIntoView(selection.basePos); + } + return; + case RuntimePlatform.Android: + break; } } @@ -361,15 +407,56 @@ void _handleSingleTapCancel() { this._cancelCurrentSplash(); } - void _handleLongPress() { - if (this.widget.enableInteractiveSelection == true) { - this._renderEditable.handleLongPress(); + void _handleSingleLongTapStart(LongPressStartDetails details) { + if (this.widget.selectionEnabled) { + switch (Theme.of(this.context).platform) { + case RuntimePlatform.IPhonePlayer: + this._renderEditable.selectPositionAt( + from: details.globalPosition, + cause: SelectionChangedCause.longPress + ); + break; + case RuntimePlatform.Android: + this._renderEditable.selectWord(cause: SelectionChangedCause.longPress); + Feedback.forLongPress(this.context); + break; + } } - this._confirmCurrentSplash(); } - void _handleDragSelectionStart(DragStartDetails details) { + void _handleSingleLongTapMoveUpdate(LongPressMoveUpdateDetails details) { + if (this.widget.selectionEnabled) { + switch (Theme.of(this.context).platform) { + case RuntimePlatform.IPhonePlayer: + this._renderEditable.selectPositionAt( + from: details.globalPosition, + cause: SelectionChangedCause.longPress + ); + break; + case RuntimePlatform.Android: + this._renderEditable.selectWordsInRange( + from: details.globalPosition - details.offsetFromOrigin, + to: details.globalPosition, + cause: SelectionChangedCause.longPress); + Feedback.forLongPress(this.context); + break; + } + } + } + + void _handleSingleLongTapEnd(LongPressEndDetails details) { + this._editableTextKey.currentState.showToolbar(); + } + + void _handleDoubleTapDown(TapDownDetails details) { + if (this.widget.selectionEnabled) { + this._renderEditable.selectWord(cause: SelectionChangedCause.doubleTap); + this._editableTextKey.currentState.showToolbar(); + } + } + + void _handleMouseDragSelectionStart(DragStartDetails details) { this._renderEditable.selectPositionAt( from: details.globalPosition, cause: SelectionChangedCause.drag); @@ -377,7 +464,7 @@ void _handleDragSelectionStart(DragStartDetails details) { this._startSplash(details.globalPosition); } - void _handleDragSelectionUpdate(DragStartDetails startDetails, + void _handleMouseDragSelectionUpdate(DragStartDetails startDetails, DragUpdateDetails updateDetails) { this._renderEditable.selectPositionAt( from: startDetails.globalPosition, @@ -462,12 +549,15 @@ public override Widget build(BuildContext context) { textInputAction: this.widget.textInputAction, textCapitalization: this.widget.textCapitalization, style: style, + strutStyle: this.widget.strutStyle, textAlign: this.widget.textAlign, textDirection: this.widget.textDirection, autofocus: this.widget.autofocus, obscureText: this.widget.obscureText, autocorrect: this.widget.autocorrect, maxLines: this.widget.maxLines, + minLines: this.widget.minLines, + expands: this.widget.expands, selectionColor: themeData.textSelectionColor, selectionControls: this.widget.selectionEnabled ? textSelectionControls : null, onChanged: this.widget.onChanged, @@ -486,7 +576,8 @@ public override Widget build(BuildContext context) { scrollPadding: this.widget.scrollPadding, keyboardAppearance: keyboardAppearance, enableInteractiveSelection: this.widget.enableInteractiveSelection == true, - dragStartBehavior: this.widget.dragStartBehavior + dragStartBehavior: this.widget.dragStartBehavior, + scrollPhysics: this.widget.scrollPhysics ) ); @@ -501,6 +592,7 @@ public override Widget build(BuildContext context) { textAlign: this.widget.textAlign, isFocused: focusNode.hasFocus, isEmpty: controller.value.text.isEmpty(), + expands: this.widget.expands, child: _child ); }, @@ -515,9 +607,12 @@ public override Widget build(BuildContext context) { // onForcePressStart: forcePressEnabled ? this._handleForcePressStarted : null, // TODO: Remove this when force press is added onSingleTapUp: this._handleSingleTapUp, onSingleTapCancel: this._handleSingleTapCancel, - onSingleLongTapStart: this._handleLongPress, - onDragSelectionStart: this._handleDragSelectionStart, - onDragSelectionUpdate: this._handleDragSelectionUpdate, + onSingleLongTapStart: this._handleSingleLongTapStart, + onSingleLongTapMoveUpdate: this._handleSingleLongTapMoveUpdate, + onSingleLongTapEnd: this._handleSingleLongTapEnd, + onDoubleTapDown: this._handleDoubleTapDown, + onDragSelectionStart: this._handleMouseDragSelectionStart, + onDragSelectionUpdate: this._handleMouseDragSelectionUpdate, behavior: HitTestBehavior.translucent, child: child ) diff --git a/Runtime/material/text_form_field.cs b/Runtime/material/text_form_field.cs index 18fcdf79..a63357f1 100644 --- a/Runtime/material/text_form_field.cs +++ b/Runtime/material/text_form_field.cs @@ -19,6 +19,7 @@ public TextFormField( TextCapitalization textCapitalization = TextCapitalization.none, TextInputAction? textInputAction = null, TextStyle style = null, + StrutStyle strutStyle = null, TextDirection? textDirection = null, TextAlign textAlign = TextAlign.left, bool autofocus = false, @@ -26,7 +27,9 @@ public TextFormField( bool autocorrect = true, bool autovalidate = false, bool maxLengthEnforced = true, - int maxLines = 1, + int? maxLines = 1, + int? minLines = null, + bool expands = false, int? maxLength = null, VoidCallback onEditingComplete = null, ValueChanged onFieldSubmitted = null, @@ -59,6 +62,7 @@ public TextFormField( keyboardType: keyboardType, textInputAction: textInputAction, style: style, + strutStyle: strutStyle, textAlign: textAlign, textDirection: textDirection ?? TextDirection.ltr, textCapitalization: textCapitalization, @@ -67,6 +71,8 @@ public TextFormField( autocorrect: autocorrect, maxLengthEnforced: maxLengthEnforced, maxLines: maxLines, + minLines: minLines, + expands: expands, maxLength: maxLength, onChanged: field.didChange, onEditingComplete: onEditingComplete, @@ -85,6 +91,12 @@ public TextFormField( ) { D.assert(initialValue == null || controller == null); D.assert(maxLines > 0); + D.assert(maxLines == null || maxLines > 0); + D.assert(minLines == null || minLines > 0); + D.assert((maxLines == null) || (minLines == null) || (maxLines >= minLines), + () => "minLines can't be greater than maxLines"); + D.assert(!expands || (maxLines == null && minLines == null), + () => "minLines and maxLines must be null when expands is true."); D.assert(maxLength == null || maxLength > 0); this.controller = controller; } diff --git a/Runtime/material/text_selection.cs b/Runtime/material/text_selection.cs index 5bb2485e..3a7a38e5 100644 --- a/Runtime/material/text_selection.cs +++ b/Runtime/material/text_selection.cs @@ -15,7 +15,7 @@ namespace Unity.UIWidgets.material { public static class MaterialUtils { - public readonly static TextSelectionControls materialTextSelectionControls = + public static readonly TextSelectionControls materialTextSelectionControls = new _MaterialTextSelectionControls(); internal const float _kHandleSize = 22.0f; diff --git a/Runtime/material/theme_data.cs b/Runtime/material/theme_data.cs index c0167a65..97a55498 100644 --- a/Runtime/material/theme_data.cs +++ b/Runtime/material/theme_data.cs @@ -76,6 +76,7 @@ public ThemeData( BottomAppBarTheme bottomAppBarTheme = null, ColorScheme colorScheme = null, DialogTheme dialogTheme = null, + FloatingActionButtonThemeData floatingActionButtonTheme = null, Typography typography = null ) { brightness = brightness ?? Brightness.light; @@ -184,6 +185,7 @@ public ThemeData( labelStyle: textTheme.body2 ); dialogTheme = dialogTheme ?? new DialogTheme(); + floatingActionButtonTheme = floatingActionButtonTheme ?? new FloatingActionButtonThemeData(); D.assert(brightness != null); D.assert(primaryColor != null); @@ -232,6 +234,7 @@ public ThemeData( D.assert(cardTheme != null); D.assert(chipTheme != null); D.assert(dialogTheme != null); + D.assert(floatingActionButtonTheme != null); this.brightness = brightness ?? Brightness.light; this.primaryColor = primaryColor; @@ -281,6 +284,7 @@ public ThemeData( this.bottomAppBarTheme = bottomAppBarTheme; this.colorScheme = colorScheme; this.dialogTheme = dialogTheme; + this.floatingActionButtonTheme = floatingActionButtonTheme; this.typography = typography; } @@ -333,6 +337,7 @@ public static ThemeData raw( BottomAppBarTheme bottomAppBarTheme = null, ColorScheme colorScheme = null, DialogTheme dialogTheme = null, + FloatingActionButtonThemeData floatingActionButtonTheme = null, Typography typography = null ) { D.assert(brightness != null); @@ -384,6 +389,7 @@ public static ThemeData raw( D.assert(cardTheme != null); D.assert(chipTheme != null); D.assert(dialogTheme != null); + D.assert(floatingActionButtonTheme != null); return new ThemeData( brightness: brightness, @@ -434,6 +440,7 @@ public static ThemeData raw( bottomAppBarTheme: bottomAppBarTheme, colorScheme: colorScheme, dialogTheme: dialogTheme, + floatingActionButtonTheme: floatingActionButtonTheme, typography: typography); } @@ -544,6 +551,8 @@ public static ThemeData fallback() { public readonly ColorScheme colorScheme; public readonly DialogTheme dialogTheme; + + public readonly FloatingActionButtonThemeData floatingActionButtonTheme; public readonly Typography typography; @@ -596,6 +605,7 @@ public ThemeData copyWith( BottomAppBarTheme bottomAppBarTheme = null, ColorScheme colorScheme = null, DialogTheme dialogTheme = null, + FloatingActionButtonThemeData floatingActionButtonTheme = null, Typography typography = null ) { return raw( @@ -647,6 +657,7 @@ public ThemeData copyWith( bottomAppBarTheme: bottomAppBarTheme ?? this.bottomAppBarTheme, colorScheme: colorScheme ?? this.colorScheme, dialogTheme: dialogTheme ?? this.dialogTheme, + floatingActionButtonTheme: floatingActionButtonTheme ?? this.floatingActionButtonTheme, typography: typography ?? this.typography ); } @@ -734,6 +745,7 @@ public static ThemeData lerp(ThemeData a, ThemeData b, float t) { bottomAppBarTheme: BottomAppBarTheme.lerp(a.bottomAppBarTheme, b.bottomAppBarTheme, t), colorScheme: ColorScheme.lerp(a.colorScheme, b.colorScheme, t), dialogTheme: DialogTheme.lerp(a.dialogTheme, b.dialogTheme, t), + floatingActionButtonTheme: FloatingActionButtonThemeData.lerp(a.floatingActionButtonTheme, b.floatingActionButtonTheme, t), typography: Typography.lerp(a.typography, b.typography, t) ); } @@ -795,6 +807,7 @@ public bool Equals(ThemeData other) { other.bottomAppBarTheme == this.bottomAppBarTheme && other.colorScheme == this.colorScheme && other.dialogTheme == this.dialogTheme && + other.floatingActionButtonTheme == this.floatingActionButtonTheme && other.typography == this.typography; } @@ -878,6 +891,7 @@ public override int GetHashCode() { hashCode = (hashCode * 397) ^ this.bottomAppBarTheme.GetHashCode(); hashCode = (hashCode * 397) ^ this.colorScheme.GetHashCode(); hashCode = (hashCode * 397) ^ this.dialogTheme.GetHashCode(); + hashCode = (hashCode * 397) ^ this.floatingActionButtonTheme.GetHashCode(); hashCode = (hashCode * 397) ^ this.typography.GetHashCode(); this._cachedHashCode = hashCode; @@ -965,6 +979,8 @@ public override void debugFillProperties(DiagnosticPropertiesBuilder properties) defaultValue: defaultData.colorScheme)); properties.add(new DiagnosticsProperty("dialogTheme", this.dialogTheme, defaultValue: defaultData.dialogTheme)); + properties.add(new DiagnosticsProperty("floatingActionButtonTheme", + this.floatingActionButtonTheme, defaultValue: defaultData.floatingActionButtonTheme)); properties.add(new DiagnosticsProperty("typography", this.typography, defaultValue: defaultData.typography)); } diff --git a/Runtime/material/user_accounts_drawer_header.cs b/Runtime/material/user_accounts_drawer_header.cs index cf4cec02..44654451 100644 --- a/Runtime/material/user_accounts_drawer_header.cs +++ b/Runtime/material/user_accounts_drawer_header.cs @@ -118,8 +118,11 @@ public override void dispose() { public override void didUpdateWidget(StatefulWidget _oldWidget) { base.didUpdateWidget(_oldWidget); _AccountDetails oldWidget = _oldWidget as _AccountDetails; - if (this._animation.status == AnimationStatus.dismissed || - this._animation.status == AnimationStatus.reverse) { + if (oldWidget.isOpen == this.widget.isOpen) { + return; + } + + if(this.widget.isOpen ?? false) { this._controller.forward(); } else { diff --git a/Runtime/painting/box_border.cs b/Runtime/painting/box_border.cs index 15162923..b08d9c86 100644 --- a/Runtime/painting/box_border.cs +++ b/Runtime/painting/box_border.cs @@ -22,13 +22,18 @@ public Border( this.left = left ?? BorderSide.none; } + public static Border fromBorderSide(BorderSide side) { + D.assert(side != null); + return new Border(top: side, right: side, bottom: side, left: side); + } + public static Border all( Color color = null, float width = 1.0f, BorderStyle style = BorderStyle.solid ) { BorderSide side = new BorderSide(color: color, width: width, style: style); - return new Border(top: side, right: side, bottom: side, left: side); + return Border.fromBorderSide(side); } public static Border merge(Border a, Border b) { diff --git a/Runtime/painting/continuous_rectangle_border.cs b/Runtime/painting/continuous_rectangle_border.cs new file mode 100644 index 00000000..f1adbb24 --- /dev/null +++ b/Runtime/painting/continuous_rectangle_border.cs @@ -0,0 +1,158 @@ +using System.Runtime.CompilerServices; +using Unity.UIWidgets.foundation; +using Unity.UIWidgets.ui; +using UnityEngine; +using Canvas = Unity.UIWidgets.ui.Canvas; +using Rect = Unity.UIWidgets.ui.Rect; + +namespace Unity.UIWidgets.painting { + public class ContinuousRectangleBorder : ShapeBorder { + + public ContinuousRectangleBorder( + BorderSide side = null, + BorderRadius borderRadius = null) { + this.side = side ?? BorderSide.none; + this.borderRadius = borderRadius ?? BorderRadius.zero; + } + + public readonly BorderRadius borderRadius; + + public readonly BorderSide side; + + public override EdgeInsets dimensions { + get { + return EdgeInsets.all(this.side.width); + } + } + + public override ShapeBorder scale(float t) { + return new ContinuousRectangleBorder( + side: this.side.scale(t), + borderRadius: this.borderRadius * t + ); + } + + public override ShapeBorder lerpFrom(ShapeBorder a, float t) { + if (a is ContinuousRectangleBorder) { + return new ContinuousRectangleBorder( + side: BorderSide.lerp((a as ContinuousRectangleBorder).side, this.side, t), + borderRadius: BorderRadius.lerp((a as ContinuousRectangleBorder).borderRadius, + this.borderRadius, t) + ); + } + return base.lerpFrom(a, t); + } + + public override ShapeBorder lerpTo(ShapeBorder b, float t) { + if (b is ContinuousRectangleBorder) { + return new ContinuousRectangleBorder( + side: BorderSide.lerp(this.side, (b as ContinuousRectangleBorder).side, t), + borderRadius: BorderRadius.lerp(this.borderRadius, + (b as ContinuousRectangleBorder).borderRadius, t) + ); + } + return base.lerpTo(b, t); + } + + float _clampToShortest(RRect rrect, float value) { + return value > rrect.shortestSide ? rrect.shortestSide : value; + } + + Path _getPath(RRect rrect) { + float left = rrect.left; + float right = rrect.right; + float top = rrect.top; + float bottom = rrect.bottom; + + float tlRadiusX = Mathf.Max(0.0f, this._clampToShortest(rrect, rrect.tlRadiusX)); + float tlRadiusY = Mathf.Max(0.0f, this._clampToShortest(rrect, rrect.tlRadiusY)); + float trRadiusX = Mathf.Max(0.0f, this._clampToShortest(rrect, rrect.trRadiusX)); + float trRadiusY = Mathf.Max(0.0f, this._clampToShortest(rrect, rrect.trRadiusY)); + float blRadiusX = Mathf.Max(0.0f, this._clampToShortest(rrect, rrect.blRadiusX)); + float blRadiusY = Mathf.Max(0.0f, this._clampToShortest(rrect, rrect.blRadiusY)); + float brRadiusX = Mathf.Max(0.0f, this._clampToShortest(rrect, rrect.brRadiusX)); + float brRadiusY = Mathf.Max(0.0f, this._clampToShortest(rrect, rrect.brRadiusY)); + + Path path = new Path(); + path.moveTo(left, top + tlRadiusX); + path.cubicTo(left, top, left, top, left + tlRadiusY, top); + path.lineTo(right - trRadiusX, top); + path.cubicTo(right, top, right, top, right, top + trRadiusY); + path.lineTo(right, bottom - blRadiusX); + path.cubicTo(right, bottom, right, bottom, right - blRadiusY, bottom); + path.lineTo(left + brRadiusX, bottom); + path.cubicTo(left, bottom, left, bottom, left, bottom - brRadiusY); + path.close(); + return path; + } + + public override Path getInnerPath(Rect rect) { + return this._getPath(this.borderRadius.toRRect(rect).deflate(this.side.width)); + } + + public override Path getOuterPath(Rect rect) { + return this._getPath(this.borderRadius.toRRect(rect)); + } + + public override void paint(Canvas canvas, Rect rect) { + if (rect.isEmpty) { + return; + } + + switch (this.side.style) { + case BorderStyle.none: + break; + case BorderStyle.solid: + Path path = this.getOuterPath(rect); + Paint paint = this.side.toPaint(); + canvas.drawPath(path, paint); + break; + } + } + public bool Equals(ContinuousRectangleBorder other) { + if (ReferenceEquals(null, other)) { + return false; + } + + if (ReferenceEquals(this, other)) { + return true; + } + + return this.side == other.side && this.borderRadius == other.borderRadius; + } + + public override bool Equals(object obj) { + if (ReferenceEquals(null, obj)) { + return false; + } + + if (ReferenceEquals(this, obj)) { + return true; + } + + if (obj.GetType() != this.GetType()) { + return false; + } + + return this.Equals((ContinuousRectangleBorder) obj); + } + + public override int GetHashCode() { + var hashCode = (this.side != null ? this.side.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (this.borderRadius != null ? this.borderRadius.GetHashCode() : 0); + return hashCode; + } + + public static bool operator ==(ContinuousRectangleBorder left, ContinuousRectangleBorder right) { + return Equals(left, right); + } + + public static bool operator !=(ContinuousRectangleBorder left, ContinuousRectangleBorder right) { + return !Equals(left, right); + } + + public override string ToString() { + return $"{this.GetType()}({this.side}, {this.borderRadius})"; + } + } +} \ No newline at end of file diff --git a/Runtime/painting/continuous_rectangle_border.cs.meta b/Runtime/painting/continuous_rectangle_border.cs.meta new file mode 100644 index 00000000..5d6ce45f --- /dev/null +++ b/Runtime/painting/continuous_rectangle_border.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 85a3d3f3c01b8482e898b19fe9779021 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/painting/decoration_image.cs b/Runtime/painting/decoration_image.cs index d13349f5..657072ae 100644 --- a/Runtime/painting/decoration_image.cs +++ b/Runtime/painting/decoration_image.cs @@ -242,7 +242,8 @@ public static void paintImage( outputSize += sliceBorder; destinationSize += sliceBorder; D.assert(sourceSize == inputSize, - () => $"centerSlice was used with a BoxFit {fit} that does not guarantee that the image is fully visible."); + () => + $"centerSlice was used with a BoxFit {fit} that does not guarantee that the image is fully visible."); } if (repeat != ImageRepeat.noRepeat && destinationSize == outputSize) { @@ -281,13 +282,23 @@ public static void paintImage( Rect sourceRect = alignment.inscribe( sourceSize, Offset.zero & inputSize ); - foreach (Rect tileRect in _generateImageTileRects(rect, destinationRect, repeat)) { - canvas.drawImageRect(image, sourceRect, tileRect, paint); + if (repeat == ImageRepeat.noRepeat) { + canvas.drawImageRect(image, sourceRect, destinationRect, paint); + } + else { + foreach (Rect tileRect in _generateImageTileRects(rect, destinationRect, repeat)) { + canvas.drawImageRect(image, sourceRect, tileRect, paint); + } } } else { - foreach (Rect tileRect in _generateImageTileRects(rect, destinationRect, repeat)) { - canvas.drawImageNine(image, centerSlice, tileRect, paint); + if (repeat == ImageRepeat.noRepeat) { + canvas.drawImageNine(image, centerSlice, destinationRect, paint); + } + else { + foreach (Rect tileRect in _generateImageTileRects(rect, destinationRect, repeat)) { + canvas.drawImageNine(image, centerSlice, tileRect, paint); + } } } @@ -298,11 +309,6 @@ public static void paintImage( static IEnumerable _generateImageTileRects(Rect outputRect, Rect fundamentalRect, ImageRepeat repeat) { - if (repeat == ImageRepeat.noRepeat) { - yield return fundamentalRect; - yield break; - } - int startX = 0; int startY = 0; int stopX = 0; diff --git a/Runtime/painting/gradient.cs b/Runtime/painting/gradient.cs index 4304fd19..b5feb006 100644 --- a/Runtime/painting/gradient.cs +++ b/Runtime/painting/gradient.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using Unity.UIWidgets.foundation; +using Unity.UIWidgets.external; using Unity.UIWidgets.ui; using UnityEngine; using Color = Unity.UIWidgets.ui.Color; @@ -17,30 +18,46 @@ public _ColorsAndStops(List colors, List stops) { public readonly List colors; public readonly List stops; - public static _ColorsAndStops _interpolateColorsAndStops( - List aColors, List aStops, List bColors, List bStops, float t) { - D.assert(aColors.Count == bColors.Count, - () => "Cannot interpolate between two gradients with a different number of colors."); - D.assert((aStops == null && aColors.Count == 2) || (aStops != null && aStops.Count == aColors.Count)); - D.assert((bStops == null && bColors.Count == 2) || (bStops != null && bStops.Count == bColors.Count)); - List interpolatedColors = new List(); + static Color _sample(List colors, List stops, float t) { + D.assert(colors != null); + D.assert(colors.isNotEmpty); + D.assert(stops != null); + D.assert(stops.isNotEmpty); - for (int i = 0; i < aColors.Count; i += 1) { - interpolatedColors.Add(Color.lerp(aColors[i], bColors[i], t)); + if (t < stops.first()) { + return colors.first(); } - List interpolatedStops = null; - if (aStops != null || bStops != null) { - aStops = aStops ?? new List {0.0f, 1.0f}; - bStops = bStops ?? new List {0.0f, 1.0f}; - - D.assert(aStops.Count == bStops.Count); - interpolatedStops = new List(); - for (int i = 0; i < aStops.Count; i += 1) { - interpolatedStops.Add(MathUtils.lerpFloat(aStops[i], bStops[i], t).clamp(0.0f, 1.0f)); - } + if (t > stops.last()) { + return colors.last(); } + int index = stops.FindLastIndex((float s) => { return s <= t; }); + D.assert(index != -1); + return Color.lerp(colors[index], colors[index + 1], + (t - stops[index]) / (stops[index + 1] - stops[index])); + } + + internal static _ColorsAndStops _interpolateColorsAndStops( + List aColors, + List aStops, + List bColors, + List bStops, + float t) { + D.assert(aColors.Count >= 2); + D.assert(bColors.Count >= 2); + D.assert(aStops.Count == aColors.Count); + D.assert(bStops.Count == bColors.Count); + + SplayTree stops = new SplayTree(); + stops.AddAll(aStops); + stops.AddAll(bStops); + + List interpolatedStops = stops.Keys.ToList(); + List interpolatedColors = interpolatedStops.Select((float stop) => { + return Color.lerp(_sample(aColors, aStops, stop), _sample(bColors, bStops, stop), t); + }).ToList(); + return new _ColorsAndStops(interpolatedColors, interpolatedStops); } } @@ -65,10 +82,6 @@ protected List _impliedStops() { return this.stops; } - if (this.colors.Count == 2) { - return null; - } - D.assert(this.colors.Count >= 2, () => "colors list must have at least two colors"); float separation = 1.0f / (this.colors.Count - 1); @@ -159,16 +172,16 @@ public override Gradient scale(float factor) { } protected override Gradient lerpFrom(Gradient a, float t) { - if (a == null || (a is LinearGradient && a.colors.Count == this.colors.Count)) { - return LinearGradient.lerp((LinearGradient) a, this, t); + if (a == null || (a is LinearGradient)) { + return lerp((LinearGradient) a, this, t); } return base.lerpFrom(a, t); } protected override Gradient lerpTo(Gradient b, float t) { - if (b == null || (b is LinearGradient && b.colors.Count == this.colors.Count)) { - return LinearGradient.lerp(this, (LinearGradient) b, t); + if (b == null || (b is LinearGradient)) { + return lerp(this, (LinearGradient) b, t); } return base.lerpTo(b, t); @@ -187,8 +200,12 @@ public static LinearGradient lerp(LinearGradient a, LinearGradient b, float t) { return (LinearGradient) a.scale(1.0f - t); } - _ColorsAndStops interpolated = - _ColorsAndStops._interpolateColorsAndStops(a.colors, a.stops, b.colors, b.stops, t); + _ColorsAndStops interpolated = _ColorsAndStops._interpolateColorsAndStops( + a.colors, + a._impliedStops(), + b.colors, + b._impliedStops(), + t); return new LinearGradient( begin: Alignment.lerp(a.begin, b.begin, t), end: Alignment.lerp(a.end, b.end, t), @@ -250,7 +267,7 @@ public override int GetHashCode() { return !Equals(left, right); } - public override String ToString() { + public override string ToString() { return $"{this.GetType()}({this.begin}, {this.end}," + $"{this.colors.toStringList()}, {this.stops.toStringList()}, {this.tileMode})"; } @@ -296,16 +313,16 @@ public override Gradient scale(float factor) { } protected override Gradient lerpFrom(Gradient a, float t) { - if (a == null || (a is RadialGradient && a.colors.Count == this.colors.Count)) { - return RadialGradient.lerp((RadialGradient) a, this, t); + if (a == null || (a is RadialGradient)) { + return lerp((RadialGradient) a, this, t); } return base.lerpFrom(a, t); } protected override Gradient lerpTo(Gradient b, float t) { - if (b == null || (b is RadialGradient && b.colors.Count == this.colors.Count)) { - return RadialGradient.lerp(this, (RadialGradient) b, t); + if (b == null || (b is RadialGradient)) { + return lerp(this, (RadialGradient) b, t); } return base.lerpTo(b, t); @@ -324,8 +341,12 @@ public static RadialGradient lerp(RadialGradient a, RadialGradient b, float t) { return (RadialGradient) a.scale(1.0f - t); } - _ColorsAndStops interpolated = - _ColorsAndStops._interpolateColorsAndStops(a.colors, a.stops, b.colors, b.stops, t); + _ColorsAndStops interpolated = _ColorsAndStops._interpolateColorsAndStops( + a.colors, + a._impliedStops(), + b.colors, + b._impliedStops(), + t); return new RadialGradient( center: Alignment.lerp(a.center, b.center, t), radius: Mathf.Max(0.0f, MathUtils.lerpFloat(a.radius, b.radius, t)), @@ -387,7 +408,7 @@ public override int GetHashCode() { return !Equals(left, right); } - public override String ToString() { + public override string ToString() { return $"{this.GetType()}({this.center}, {this.radius}," + $"{this.colors.toStringList()}, {this.stops.toStringList()}, {this.tileMode})"; } @@ -439,7 +460,7 @@ public override Gradient scale(float factor) { protected override Gradient lerpFrom(Gradient a, float t) { if (a == null || (a is SweepGradient && a.colors.Count == this.colors.Count)) { - return SweepGradient.lerp((SweepGradient) a, this, t); + return lerp((SweepGradient) a, this, t); } return base.lerpFrom(a, t); @@ -532,7 +553,7 @@ public override int GetHashCode() { return !Equals(left, right); } - public override String ToString() { + public override string ToString() { return $"{this.GetType()}({this.center}, {this.startAngle}, {this.endAngle}, " + $"{this.colors.toStringList()}, {this.stops.toStringList()}, {this.tileMode})"; } diff --git a/Runtime/painting/image_stream.cs b/Runtime/painting/image_stream.cs index 97567ea3..168aa0c9 100644 --- a/Runtime/painting/image_stream.cs +++ b/Runtime/painting/image_stream.cs @@ -187,7 +187,7 @@ public virtual void addListener(ImageListener listener, ImageErrorListener onErr new UIWidgetsErrorDetails( exception: ex, library: "image resource service", - context: "by a synchronously-called image error listener" + context: "when reporting an error to an image listener" ) ); } @@ -298,9 +298,6 @@ public MultiFrameImageStreamCompleter( this._scale = scale; this._informationCollector = informationCollector; - this._framesEmitted = 0; - this._timer = null; - codec.Then((Action) this._handleCodecReady, ex => { this.reportError( context: "resolving an image codec", @@ -318,17 +315,22 @@ public MultiFrameImageStreamCompleter( FrameInfo _nextFrame; TimeSpan? _shownTimestamp; TimeSpan? _frameDuration; - int _framesEmitted; + int _framesEmitted = 0; Timer _timer; + bool _frameCallbackScheduled = false; + void _handleCodecReady(Codec codec) { this._codec = codec; D.assert(this._codec != null); - this._decodeNextFrameAndSchedule(); + if (this.hasListeners) { + this._decodeNextFrameAndSchedule(); + } } void _handleAppFrame(TimeSpan timestamp) { + this._frameCallbackScheduled = false; if (!this.hasListeners) { return; } @@ -349,8 +351,7 @@ void _handleAppFrame(TimeSpan timestamp) { TimeSpan delay = this._frameDuration.Value - (timestamp - this._shownTimestamp.Value); delay = new TimeSpan((long) (delay.Ticks * SchedulerBinding.instance.timeDilation)); - this._timer = Window.instance.run(delay, - () => { SchedulerBinding.instance.scheduleFrameCallback(this._handleAppFrame); }); + this._timer = Window.instance.run(delay, this._scheduleAppFrame); } bool _isFirstFrame() { @@ -371,6 +372,15 @@ void _decodeNextFrameAndSchedule() { return; } + this._scheduleAppFrame(); + } + + void _scheduleAppFrame() { + if (this._frameCallbackScheduled) { + return; + } + + this._frameCallbackScheduled = true; SchedulerBinding.instance.scheduleFrameCallback(this._handleAppFrame); } diff --git a/Runtime/painting/matrix_utils.cs b/Runtime/painting/matrix_utils.cs index d29c3247..a8205a5a 100644 --- a/Runtime/painting/matrix_utils.cs +++ b/Runtime/painting/matrix_utils.cs @@ -2,6 +2,7 @@ using Unity.UIWidgets.foundation; using Unity.UIWidgets.ui; using UnityEngine; +using Rect = Unity.UIWidgets.ui.Rect; namespace Unity.UIWidgets.painting { public static class MatrixUtils { @@ -22,6 +23,58 @@ public static List debugDescribeTransform(Matrix3 transform) { return result; } + public static Vector3 perspectiveTransform(this Matrix4x4 m4, Vector3 arg) { + List argStorage = new List {arg[0], arg[1], arg[2]}; + float x_ = (m4[0] * argStorage[0]) + + (m4[4] * argStorage[1]) + + (m4[8] * argStorage[2]) + + m4[12]; + float y_ = (m4[1] * argStorage[0]) + + (m4[5] * argStorage[1]) + + (m4[9] * argStorage[2]) + + m4[13]; + float z_ = (m4[2] * argStorage[0]) + + (m4[6] * argStorage[1]) + + (m4[10] * argStorage[2]) + + m4[14]; + float w_ = 1.0f / + ((m4[3] * argStorage[0]) + + (m4[7] * argStorage[1]) + + (m4[11] * argStorage[2]) + + m4[15]); + argStorage[0] = x_ * w_; + argStorage[1] = y_ * w_; + argStorage[2] = z_ * w_; + return arg; + } + + public static Offset transformPoint(Matrix4x4 transform, Offset point) { + Vector3 position3 = new Vector3(point.dx, point.dy, 0.0f); + Vector3 transformed3 = transform.perspectiveTransform(position3); + return new Offset(transformed3.x, transformed3.y); + } + + public static Rect transformRect(Matrix4x4 transform, Rect rect) { + Offset point1 = transformPoint(transform, rect.topLeft); + Offset point2 = transformPoint(transform, rect.topRight); + Offset point3 = transformPoint(transform, rect.bottomLeft); + Offset point4 = transformPoint(transform, rect.bottomRight); + return Rect.fromLTRB( + _min4(point1.dx, point2.dx, point3.dx, point4.dx), + _min4(point1.dy, point2.dy, point3.dy, point4.dy), + _max4(point1.dx, point2.dx, point3.dx, point4.dx), + _max4(point1.dy, point2.dy, point3.dy, point4.dy) + ); + } + + static float _min4(float a, float b, float c, float d) { + return Mathf.Min(a, Mathf.Min(b, Mathf.Min(c, d))); + } + + static float _max4(float a, float b, float c, float d) { + return Mathf.Max(a, Mathf.Max(b, Mathf.Max(c, d))); + } + public static Matrix4x4 toMatrix4x4(this Matrix3 matrix3) { var matrix = Matrix4x4.identity; @@ -47,8 +100,7 @@ public TransformProperty(string name, Matrix3 value, object defaultValue = null, DiagnosticLevel level = DiagnosticLevel.info ) : base(name, value, showName: showName, defaultValue: defaultValue ?? Diagnostics.kNoDefaultValue, - level: level) { - } + level: level) { } protected override string valueToString(TextTreeConfiguration parentConfiguration = null) { if (parentConfiguration != null && !parentConfiguration.lineBreakProperties) { diff --git a/Runtime/painting/notched_shapes.cs b/Runtime/painting/notched_shapes.cs index 835c79a1..41569c75 100644 --- a/Runtime/painting/notched_shapes.cs +++ b/Runtime/painting/notched_shapes.cs @@ -68,4 +68,24 @@ public override Path getOuterPath(Rect host, Rect guest) { return ret; } } + + class AutomaticNotchedShape : NotchedShape { + public AutomaticNotchedShape(ShapeBorder host, ShapeBorder guest = null) { + this.host = host; + this.guest = guest; + } + + public readonly ShapeBorder host; + public readonly ShapeBorder guest; + + public override Path getOuterPath(Rect hostRect, Rect guestRect) { + Path hostPath = this.host.getOuterPath(hostRect); + if (this.guest != null && guestRect != null) { + Path guestPath = this.guest.getOuterPath(guestRect); + return Path.combine(PathOperation.difference, hostPath, guestPath); + } + + return hostPath; + } + } } \ No newline at end of file diff --git a/Runtime/painting/strut_style.cs b/Runtime/painting/strut_style.cs new file mode 100644 index 00000000..a5a019db --- /dev/null +++ b/Runtime/painting/strut_style.cs @@ -0,0 +1,220 @@ +using System.Collections.Generic; +using System.Linq; +using Unity.UIWidgets.foundation; +using Unity.UIWidgets.ui; + +namespace Unity.UIWidgets.painting { + public class StrutStyle : Diagnosticable { + public StrutStyle( + string fontFamily = null, + List fontFamilyFallback = null, + float? fontSize = null, + float? height = null, + float? leading = null, + FontWeight fontWeight = null, + FontStyle? fontStyle = null, + bool forceStrutHeight = false, + string debugLabel = null + ) { + D.assert(fontSize == null || fontSize > 0); + D.assert(leading == null || leading >= 0); + this.fontFamily = fontFamily; + this._fontFamilyFallback = fontFamilyFallback; + this.fontSize = fontSize; + this.height = height; + this.fontWeight = fontWeight; + this.fontStyle = fontStyle; + this.leading = leading; + this.forceStrutHeight = forceStrutHeight; + this.debugLabel = debugLabel; + } + + public static StrutStyle fromTextStyle( + TextStyle textStyle, + string fontFamily = null, + List fontFamilyFallback = null, + float? fontSize = null, + float? height = null, + float? leading = null, + FontWeight fontWeight = null, + FontStyle? fontStyle = null, + bool forceStrutHeight = false, + string debugLabel = null + ) { + D.assert(textStyle != null); + D.assert(fontSize == null || fontSize > 0); + D.assert(leading == null || leading >= 0); + return new StrutStyle( + fontFamily: fontFamily ?? textStyle.fontFamily, + fontFamilyFallback: fontFamilyFallback ?? textStyle.fontFamilyFallback, + height: height ?? textStyle.height, + fontSize: fontSize ?? textStyle.fontSize, + fontWeight: fontWeight ?? textStyle.fontWeight, + fontStyle: fontStyle ?? textStyle.fontStyle, + debugLabel: debugLabel ?? textStyle.debugLabel + ); + } + + public static readonly StrutStyle disabled = new StrutStyle( + height: 0.0f, + leading: 0.0f + ); + + public readonly string fontFamily; + + public List fontFamilyFallback { + get { return this._fontFamilyFallback; } + } + + readonly List _fontFamilyFallback; + + public readonly float? fontSize; + public readonly float? height; + public readonly FontWeight fontWeight; + public readonly FontStyle? fontStyle; + public readonly float? leading; + public readonly bool forceStrutHeight; + public readonly string debugLabel; + + public RenderComparison compareTo(StrutStyle other) { + if (ReferenceEquals(this, other)) { + return RenderComparison.identical; + } + + if (other == null) { + return RenderComparison.layout; + } + + if (this.fontFamily != other.fontFamily || + this.fontSize != other.fontSize || + this.fontWeight != other.fontWeight || + this.fontStyle != other.fontStyle || + this.height != other.height || + this.leading != other.leading || + this.forceStrutHeight != other.forceStrutHeight || + !CollectionUtils.equalsList(this.fontFamilyFallback, other.fontFamilyFallback)) { + return RenderComparison.layout; + } + + return RenderComparison.identical; + } + + public StrutStyle inheritFromTextStyle(TextStyle other) { + if (other == null) { + return this; + } + + return new StrutStyle( + fontFamily: this.fontFamily ?? other.fontFamily, + fontFamilyFallback: this.fontFamilyFallback ?? other.fontFamilyFallback, + height: this.height ?? other.height, + leading: this.leading, + fontSize: this.fontSize ?? other.fontSize, + fontWeight: this.fontWeight ?? other.fontWeight, + fontStyle: this.fontStyle ?? other.fontStyle, + forceStrutHeight: this.forceStrutHeight, + debugLabel: this.debugLabel ?? other.debugLabel + ); + } + + public bool Equals(StrutStyle other) { + if (ReferenceEquals(null, other)) { + return false; + } + + if (ReferenceEquals(this, other)) { + return true; + } + + return this.fontFamily == other.fontFamily && + this.fontSize == other.fontSize && + this.fontWeight == other.fontWeight && + this.fontStyle == other.fontStyle && + this.height == other.height && + this.leading == other.leading && + this.forceStrutHeight == other.forceStrutHeight; + } + + public override bool Equals(object obj) { + if (ReferenceEquals(null, obj)) { + return false; + } + + if (ReferenceEquals(this, obj)) { + return true; + } + + if (obj.GetType() != this.GetType()) { + return false; + } + + return this.Equals((StrutStyle) obj); + } + + public static bool operator ==(StrutStyle left, StrutStyle right) { + return Equals(left, right); + } + + public static bool operator !=(StrutStyle left, StrutStyle right) { + return !Equals(left, right); + } + + public override int GetHashCode() { + unchecked { + var hashCode = this.fontFamily?.GetHashCode() ?? 0; + hashCode = (hashCode * 397) ^ (this.fontSize?.GetHashCode() ?? 0); + hashCode = (hashCode * 397) ^ (this.fontWeight?.GetHashCode() ?? 0); + hashCode = (hashCode * 397) ^ (this.fontStyle?.GetHashCode() ?? 0); + hashCode = (hashCode * 397) ^ (this.height?.GetHashCode() ?? 0); + hashCode = (hashCode * 397) ^ (this.leading?.GetHashCode() ?? 0); + hashCode = (hashCode * 397) ^ this.forceStrutHeight.GetHashCode(); + return hashCode; + } + } + + public override string toStringShort() { + return $"{this.GetType()}"; + } + + public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { + base.debugFillProperties(properties); + if (this.debugLabel != null) { + properties.add(new MessageProperty("debugLabel", this.debugLabel)); + } + + List styles = new List(); + styles.Add(new StringProperty("family", this.fontFamily, defaultValue: Diagnostics.kNullDefaultValue, + quoted: false)); + styles.Add(new EnumerableProperty("familyFallback", this.fontFamilyFallback)); + styles.Add(new DiagnosticsProperty("size", this.fontSize, + defaultValue: Diagnostics.kNullDefaultValue)); + string weightDescription = ""; + if (this.fontWeight != null) { + weightDescription = this.fontWeight.weightValue.ToString(); + } + + styles.Add(new DiagnosticsProperty( + "weight", this.fontWeight, + description: weightDescription, + defaultValue: Diagnostics.kNullDefaultValue + )); + styles.Add(new EnumProperty("style", this.fontStyle, + defaultValue: Diagnostics.kNullDefaultValue)); + styles.Add(new DiagnosticsProperty("height", this.height, + defaultValue: Diagnostics.kNullDefaultValue)); + styles.Add(new FlagProperty("forceStrutHeight", value: this.forceStrutHeight, + defaultValue: Diagnostics.kNullDefaultValue)); + + bool styleSpecified = styles.Any((DiagnosticsNode n) => !n.isFiltered(DiagnosticLevel.info)); + foreach (var style in styles) { + properties.add(style); + } + + if (!styleSpecified) { + properties.add(new FlagProperty("forceStrutHeight", value: this.forceStrutHeight, + ifTrue: "", + ifFalse: "")); + } + } + } +} \ No newline at end of file diff --git a/Runtime/painting/strut_style.cs.meta b/Runtime/painting/strut_style.cs.meta new file mode 100644 index 00000000..31c4ca16 --- /dev/null +++ b/Runtime/painting/strut_style.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5ec5d77d67faf40bfaef77f14968228c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/painting/text_painter.cs b/Runtime/painting/text_painter.cs index 30ea40e2..7449ca25 100644 --- a/Runtime/painting/text_painter.cs +++ b/Runtime/painting/text_painter.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using Unity.UIWidgets.foundation; using Unity.UIWidgets.service; using Unity.UIWidgets.ui; @@ -7,6 +7,16 @@ using Rect = Unity.UIWidgets.ui.Rect; namespace Unity.UIWidgets.painting { + class _CaretMetrics { + public _CaretMetrics(Offset offset, float? fullHeight) { + this.offset = offset; + this.fullHeight = fullHeight; + } + + public Offset offset; + public float? fullHeight; + } + public class TextPainter { TextSpan _text; TextAlign _textAlign; @@ -25,13 +35,15 @@ public TextPainter(TextSpan text = null, TextDirection textDirection = TextDirection.ltr, float textScaleFactor = 1.0f, int? maxLines = null, - string ellipsis = "") { + string ellipsis = "", + StrutStyle strutStyle = null) { this._text = text; this._textAlign = textAlign; this._textDirection = textDirection; this._textScaleFactor = textScaleFactor; this._maxLines = maxLines; this._ellipsis = ellipsis; + this._strutStyle = strutStyle; } public float textScaleFactor { @@ -132,6 +144,21 @@ public int? maxLines { } } + public StrutStyle strutStyle { + get { return this._strutStyle; } + set { + if (this._strutStyle == value) { + return; + } + + this._strutStyle = value; + this._paragraph = null; + this._needsLayout = true; + } + } + + StrutStyle _strutStyle; + public float minIntrinsicWidth { get { Debug.Assert(!this._needsLayout); @@ -206,29 +233,48 @@ public void paint(Canvas canvas, Offset offset) { } public Offset getOffsetForCaret(TextPosition position, Rect caretPrototype) { + this._computeCaretMetrics(position, caretPrototype); + return this._caretMetrics.offset; + } + + public float? getFullHeightForCaret(TextPosition position, Rect caretPrototype) { + this._computeCaretMetrics(position, caretPrototype); + return this._caretMetrics.fullHeight; + } + + _CaretMetrics _caretMetrics; + + TextPosition _previousCaretPosition; + Rect _previousCaretPrototype; + + void _computeCaretMetrics(TextPosition position, Rect caretPrototype) { D.assert(!this._needsLayout); - var offset = position.offset; - if (offset > 0) { - var prevCodeUnit = this._text.codeUnitAt(offset); - if (prevCodeUnit == null) // out of upper bounds - { - var rectNextLineTop = this._paragraph.getNextLineStartRectTop(); - if (rectNextLineTop != null) { - return new Offset(0, rectNextLineTop.Value); - } - } + if (position == this._previousCaretPosition && caretPrototype == this._previousCaretPrototype) { + return; } + var offset = position.offset; + Rect rect; switch (position.affinity) { case TextAffinity.upstream: - return this._getOffsetFromUpstream(offset, caretPrototype) ?? - this._getOffsetFromDownstream(offset, caretPrototype) ?? this._emptyOffset; + rect = this._getRectFromUpstream(offset, caretPrototype) ?? + this._getRectFromDownStream(offset, caretPrototype); + break; case TextAffinity.downstream: - return this._getOffsetFromDownstream(offset, caretPrototype) ?? - this._getOffsetFromUpstream(offset, caretPrototype) ?? this._emptyOffset; + rect = this._getRectFromDownStream(offset, caretPrototype) ?? + this._getRectFromUpstream(offset, caretPrototype); + break; + default: + throw new UIWidgetsError("Unknown Position Affinity"); } - return null; + this._caretMetrics = new _CaretMetrics( + offset: rect != null ? new Offset(rect.left, rect.top) : this._emptyOffset, + fullHeight: rect != null ? (float?) (rect.bottom - rect.top) : null); + + // Cache the caret position. This was forgot in flutter until https://github.com/flutter/flutter/pull/38821 + this._previousCaretPosition = position; + this._previousCaretPrototype = caretPrototype; } public Paragraph.LineRange getLineRange(int lineNumber) { @@ -321,7 +367,8 @@ ParagraphStyle _createParagraphStyle(TextDirection defaultTextDirection = TextDi textAlign: this.textAlign, textDirection: this.textDirection ?? defaultTextDirection, maxLines: this.maxLines, - ellipsis: this.ellipsis + ellipsis: this.ellipsis, + strutStyle: this._strutStyle ); } @@ -353,7 +400,7 @@ float _applyFloatingPointHack(float layoutValue) { const int _zwjUtf16 = 0x200d; - Offset _getOffsetFromUpstream(int offset, Rect caretPrototype) { + Rect _getRectFromUpstream(int offset, Rect caretPrototype) { string flattenedText = this._text.toPlainText(); var prevCodeUnit = this._text.codeUnitAt(Mathf.Max(0, offset - 1)); if (prevCodeUnit == null) { @@ -382,18 +429,20 @@ Offset _getOffsetFromUpstream(int offset, Rect caretPrototype) { TextBox box = boxes[0]; const int NEWLINE_CODE_UNIT = 10; if (prevCodeUnit == NEWLINE_CODE_UNIT) { - return new Offset(this._emptyOffset.dx, box.bottom); + return Rect.fromLTRB(this._emptyOffset.dx, box.bottom, + this._emptyOffset.dx, box.bottom + box.bottom - box.top); } float caretEnd = box.end; float dx = box.direction == TextDirection.rtl ? caretEnd - caretPrototype.width : caretEnd; - return new Offset(dx, box.top); + return Rect.fromLTRB(Mathf.Min(dx, this.width), box.top, + Mathf.Min(dx, this.width), box.bottom); } return null; } - Offset _getOffsetFromDownstream(int offset, Rect caretPrototype) { + Rect _getRectFromDownStream(int offset, Rect caretPrototype) { string flattenedText = this._text.toPlainText(); var nextCodeUnit = this._text.codeUnitAt(Mathf.Min(offset, flattenedText == null ? 0 : flattenedText.Length - 1)); @@ -423,7 +472,8 @@ Offset _getOffsetFromDownstream(int offset, Rect caretPrototype) { TextBox box = boxes[boxes.Count - 1]; float caretStart = box.start; float dx = box.direction == TextDirection.rtl ? caretStart - caretPrototype.width : caretStart; - return new Offset(dx, box.top); + return Rect.fromLTRB(Mathf.Min(dx, this.width), box.top, + Mathf.Min(dx, this.width), box.bottom); } return null; diff --git a/Runtime/painting/text_style.cs b/Runtime/painting/text_style.cs index 855cba9c..39f45edb 100644 --- a/Runtime/painting/text_style.cs +++ b/Runtime/painting/text_style.cs @@ -9,6 +9,7 @@ public class TextStyle : Diagnosticable, IEquatable { public static readonly float _defaultFontSize = 14.0f; public readonly bool inherit; public readonly Color color; + public readonly Color backgroundColor; public readonly float? fontSize; public readonly FontWeight fontWeight; public readonly FontStyle? fontStyle; @@ -19,22 +20,52 @@ public class TextStyle : Diagnosticable, IEquatable { public readonly TextDecoration decoration; public readonly Color decorationColor; public readonly TextDecorationStyle? decorationStyle; + public readonly float? decorationThickness; + public readonly Paint foreground; public readonly Paint background; public readonly string fontFamily; + public readonly List shadows; + + public List fontFamilyFallback { + get { return this._fontFamilyFallback; } + } + + readonly List _fontFamilyFallback; public readonly string debugLabel; const string _kDefaultDebugLabel = "unknown"; + const string _kColorForegroundWarning = "Cannot provide both a color and a foreground\n" + + "The color argument is just a shorthand for 'foreground: new Paint()..color = color'."; - public TextStyle(bool inherit = true, Color color = null, float? fontSize = null, + const string _kColorBackgroundWarning = "Cannot provide both a backgroundColor and a background\n" + + "The backgroundColor argument is just a shorthand for 'background: new Paint()..color = color'."; + + public TextStyle(bool inherit = true, + Color color = null, + Color backgroundColor = null, + float? fontSize = null, FontWeight fontWeight = null, - FontStyle? fontStyle = null, float? letterSpacing = null, float? wordSpacing = null, - TextBaseline? textBaseline = null, float? height = null, Paint background = null, + FontStyle? fontStyle = null, + float? letterSpacing = null, + float? wordSpacing = null, + TextBaseline? textBaseline = null, + float? height = null, + Paint foreground = null, + Paint background = null, TextDecoration decoration = null, - Color decorationColor = null, TextDecorationStyle? decorationStyle = null, - string fontFamily = null, string debugLabel = null) { + Color decorationColor = null, + TextDecorationStyle? decorationStyle = null, + float? decorationThickness = null, + string fontFamily = null, + List fontFamilyFallback = null, + List shadows = null, + string debugLabel = null) { + D.assert(color == null || foreground == null, () => _kColorForegroundWarning); + D.assert(backgroundColor == null || background == null, () => _kColorBackgroundWarning); this.inherit = inherit; this.color = color; + this.backgroundColor = backgroundColor; this.fontSize = fontSize; this.fontWeight = fontWeight; this.fontStyle = fontStyle; @@ -45,25 +76,28 @@ public TextStyle(bool inherit = true, Color color = null, float? fontSize = null this.decoration = decoration; this.decorationColor = decorationColor; this.decorationStyle = decorationStyle; + this.decorationThickness = decorationThickness; this.fontFamily = fontFamily; + this._fontFamilyFallback = fontFamilyFallback; this.debugLabel = debugLabel; + this.foreground = foreground; this.background = background; + this.shadows = shadows; } public RenderComparison compareTo(TextStyle other) { - if (this.inherit != other.inherit || this.fontFamily != other.fontFamily - || this.fontSize != other.fontSize || this.fontWeight != other.fontWeight - || this.fontStyle != other.fontStyle || - this.letterSpacing != other.letterSpacing - || this.wordSpacing != other.wordSpacing || - this.textBaseline != other.textBaseline - || this.height != other.height || this.background != other.background) { + if (this.inherit != other.inherit || this.fontFamily != other.fontFamily || + this.fontSize != other.fontSize || this.fontWeight != other.fontWeight || + this.fontStyle != other.fontStyle || this.letterSpacing != other.letterSpacing || + this.wordSpacing != other.wordSpacing || this.textBaseline != other.textBaseline || + this.height != other.height || this.background != other.background || + this.shadows.equalsList(other.shadows)) { return RenderComparison.layout; } if (this.color != other.color || this.decoration != other.decoration || - this.decorationColor != other.decorationColor - || this.decorationStyle != other.decorationStyle) { + this.decorationColor != other.decorationColor || + this.decorationStyle != other.decorationStyle) { return RenderComparison.paint; } @@ -82,10 +116,15 @@ public ParagraphStyle getParagraphStyle(TextAlign textAlign, public TextStyle apply( Color color = null, + Color backgroundColor = null, TextDecoration decoration = null, Color decorationColor = null, TextDecorationStyle? decorationStyle = null, + float decorationThicknessFactor = 1.0f, + float decorationThicknessDelta = 0.0f, string fontFamily = null, + List fontFamilyFallback = null, + List shadows = null, float fontSizeFactor = 1.0f, float fontSizeDelta = 0.0f, int fontWeightDelta = 0, @@ -96,11 +135,13 @@ public TextStyle apply( float heightFactor = 1.0f, float heightDelta = 0.0f ) { - D.assert(this.fontSize != null || (fontSizeFactor == 1.0 && fontSizeDelta == 0.0)); - D.assert(this.fontWeight != null || fontWeightDelta == 0.0); - D.assert(this.letterSpacing != null || (letterSpacingFactor == 1.0 && letterSpacingDelta == 0.0)); - D.assert(this.wordSpacing != null || (wordSpacingFactor == 1.0 && wordSpacingDelta == 0.0)); - D.assert(this.height != null || (heightFactor == 1.0 && heightDelta == 0.0)); + D.assert(this.fontSize != null || (fontSizeFactor == 1.0f && fontSizeDelta == 0.0f)); + D.assert(this.fontWeight != null || fontWeightDelta == 0.0f); + D.assert(this.letterSpacing != null || (letterSpacingFactor == 1.0f && letterSpacingDelta == 0.0f)); + D.assert(this.wordSpacing != null || (wordSpacingFactor == 1.0f && wordSpacingDelta == 0.0f)); + D.assert(this.height != null || (heightFactor == 1.0f && heightDelta == 0.0f)); + D.assert(this.decorationThickness != null || + (decorationThicknessFactor == 1.0f && decorationThicknessDelta == 0.0f)); string modifiedDebugLabel = ""; D.assert(() => { @@ -113,8 +154,10 @@ public TextStyle apply( return new TextStyle( inherit: this.inherit, - color: color ?? this.color, + color: this.foreground == null ? color ?? this.color : null, + backgroundColor: this.background == null ? backgroundColor ?? this.backgroundColor : null, fontFamily: fontFamily ?? this.fontFamily, + fontFamilyFallback: fontFamilyFallback ?? this.fontFamilyFallback, fontSize: this.fontSize == null ? null : this.fontSize * fontSizeFactor + fontSizeDelta, fontWeight: this.fontWeight == null ? null : this.fontWeight, fontStyle: this.fontStyle, @@ -124,10 +167,15 @@ public TextStyle apply( wordSpacing: this.wordSpacing == null ? null : this.wordSpacing * wordSpacingFactor + wordSpacingDelta, textBaseline: this.textBaseline, height: this.height == null ? null : this.height * heightFactor + heightDelta, + foreground: this.foreground, background: this.background, decoration: decoration ?? this.decoration, decorationColor: decorationColor ?? this.decorationColor, decorationStyle: decorationStyle ?? this.decorationStyle, + decorationThickness: this.decorationThickness == null + ? null + : this.decorationThickness * decorationThicknessFactor + decorationThicknessDelta, + shadows: shadows ?? this.shadows, debugLabel: modifiedDebugLabel ); } @@ -153,7 +201,9 @@ public TextStyle merge(TextStyle other) { return this.copyWith( color: other.color, + backgroundColor: other.backgroundColor, fontFamily: other.fontFamily, + fontFamilyFallback: other.fontFamilyFallback, fontSize: other.fontSize, fontWeight: other.fontWeight, fontStyle: other.fontStyle, @@ -161,16 +211,23 @@ public TextStyle merge(TextStyle other) { wordSpacing: other.wordSpacing, textBaseline: other.textBaseline, height: other.height, + foreground: other.foreground, + background: other.background, decoration: other.decoration, decorationColor: other.decorationColor, decorationStyle: other.decorationStyle, - background: other.background, + decorationThickness: other.decorationThickness, + shadows: other.shadows, debugLabel: mergedDebugLabel ); } - public TextStyle copyWith(Color color = null, + public TextStyle copyWith( + bool? inherit = null, + Color color = null, + Color backgroundColor = null, string fontFamily = null, + List fontFamilyFallback = null, float? fontSize = null, FontWeight fontWeight = null, FontStyle? fontStyle = null, @@ -178,11 +235,16 @@ public TextStyle copyWith(Color color = null, float? wordSpacing = null, TextBaseline? textBaseline = null, float? height = null, + Paint foreground = null, Paint background = null, TextDecoration decoration = null, Color decorationColor = null, TextDecorationStyle? decorationStyle = null, + float? decorationThickness = null, + List shadows = null, string debugLabel = null) { + D.assert(color == null || foreground == null, () => _kColorForegroundWarning); + D.assert(backgroundColor == null || background == null, () => _kColorBackgroundWarning); string newDebugLabel = null; D.assert(() => { if (this.debugLabel != null) { @@ -193,9 +255,11 @@ public TextStyle copyWith(Color color = null, }); return new TextStyle( - inherit: this.inherit, - color: color ?? this.color, + inherit: inherit ?? this.inherit, + color: this.foreground == null && foreground == null ? color ?? this.color : null, + backgroundColor: this.background == null && background == null ? color ?? this.color : null, fontFamily: fontFamily ?? this.fontFamily, + fontFamilyFallback: fontFamilyFallback ?? this.fontFamilyFallback, fontSize: fontSize ?? this.fontSize, fontWeight: fontWeight ?? this.fontWeight, fontStyle: fontStyle ?? this.fontStyle, @@ -206,7 +270,10 @@ public TextStyle copyWith(Color color = null, decoration: decoration ?? this.decoration, decorationColor: decorationColor ?? this.decorationColor, decorationStyle: decorationStyle ?? this.decorationStyle, + decorationThickness: decorationThickness ?? this.decorationThickness, + foreground: foreground ?? this.foreground, background: background ?? this.background, + shadows: shadows ?? this.shadows, debugLabel: newDebugLabel ); } @@ -228,18 +295,23 @@ public static TextStyle lerp(TextStyle a, TextStyle b, float t) { return new TextStyle( inherit: b.inherit, color: Color.lerp(null, b.color, t), - fontFamily: t < 0.5 ? null : b.fontFamily, - fontSize: t < 0.5 ? null : b.fontSize, - fontWeight: t < 0.5 ? null : b.fontWeight, - fontStyle: t < 0.5 ? null : b.fontStyle, - letterSpacing: t < 0.5 ? null : b.letterSpacing, - wordSpacing: t < 0.5 ? null : b.wordSpacing, - textBaseline: t < 0.5 ? null : b.textBaseline, - height: t < 0.5 ? null : b.height, - background: t < 0.5 ? null : b.background, - decoration: t < 0.5 ? null : b.decoration, + backgroundColor: Color.lerp(null, b.backgroundColor, t), + fontFamily: t < 0.5f ? null : b.fontFamily, + fontFamilyFallback: t < 0.5f ? null : b.fontFamilyFallback, + fontSize: t < 0.5f ? null : b.fontSize, + fontWeight: t < 0.5f ? null : b.fontWeight, + fontStyle: t < 0.5f ? null : b.fontStyle, + letterSpacing: t < 0.5f ? null : b.letterSpacing, + wordSpacing: t < 0.5f ? null : b.wordSpacing, + textBaseline: t < 0.5f ? null : b.textBaseline, + height: t < 0.5f ? null : b.height, + foreground: t < 0.5f ? null : b.foreground, + background: t < 0.5f ? null : b.background, + decoration: t < 0.5f ? null : b.decoration, decorationColor: Color.lerp(null, b.decorationColor, t), - decorationStyle: t < 0.5 ? null : b.decorationStyle, + decorationStyle: t < 0.5f ? null : b.decorationStyle, + decorationThickness: t < 0.5f ? null : b.decorationThickness, + shadows: t < 0.5f ? null : b.shadows, debugLabel: lerpDebugLabel ); } @@ -248,26 +320,35 @@ public static TextStyle lerp(TextStyle a, TextStyle b, float t) { return new TextStyle( inherit: a.inherit, color: Color.lerp(a.color, null, t), - fontFamily: t < 0.5 ? a.fontFamily : null, - fontSize: t < 0.5 ? a.fontSize : null, - fontWeight: t < 0.5 ? a.fontWeight : null, - fontStyle: t < 0.5 ? a.fontStyle : null, - letterSpacing: t < 0.5 ? a.letterSpacing : null, - wordSpacing: t < 0.5 ? a.wordSpacing : null, - textBaseline: t < 0.5 ? a.textBaseline : null, - height: t < 0.5 ? a.height : null, - background: t < 0.5 ? a.background : null, - decoration: t < 0.5 ? a.decoration : null, + backgroundColor: Color.lerp(a.backgroundColor, null, t), + fontFamily: t < 0.5f ? a.fontFamily : null, + fontFamilyFallback: t < 0.5f ? a.fontFamilyFallback : null, + fontSize: t < 0.5f ? a.fontSize : null, + fontWeight: t < 0.5f ? a.fontWeight : null, + fontStyle: t < 0.5f ? a.fontStyle : null, + letterSpacing: t < 0.5f ? a.letterSpacing : null, + wordSpacing: t < 0.5f ? a.wordSpacing : null, + textBaseline: t < 0.5f ? a.textBaseline : null, + height: t < 0.5f ? a.height : null, + foreground: t < 0.5f ? a.foreground : null, + background: t < 0.5f ? a.background : null, + decoration: t < 0.5f ? a.decoration : null, decorationColor: Color.lerp(a.decorationColor, null, t), - decorationStyle: t < 0.5 ? a.decorationStyle : null, + decorationStyle: t < 0.5f ? a.decorationStyle : null, + decorationThickness: t < 0.5f ? a.decorationThickness : null, + shadows: t < 0.5f ? a.shadows : null, debugLabel: lerpDebugLabel ); } return new TextStyle( inherit: b.inherit, - color: Color.lerp(a.color, b.color, t), + color: a.foreground == null && b.foreground == null ? Color.lerp(a.color, b.color, t) : null, + backgroundColor: a.background == null && b.background == null + ? Color.lerp(a.backgroundColor, b.backgroundColor, t) + : null, fontFamily: t < 0.5 ? a.fontFamily : b.fontFamily, + fontFamilyFallback: t < 0.5 ? a.fontFamilyFallback : b.fontFamilyFallback, fontSize: MathUtils.lerpNullableFloat(a.fontSize ?? b.fontSize, b.fontSize ?? a.fontSize, t), fontWeight: t < 0.5 ? a.fontWeight : b.fontWeight, fontStyle: t < 0.5 ? a.fontStyle : b.fontStyle, @@ -277,10 +358,23 @@ public static TextStyle lerp(TextStyle a, TextStyle b, float t) { b.wordSpacing ?? a.wordSpacing, t), textBaseline: t < 0.5 ? a.textBaseline : b.textBaseline, height: MathUtils.lerpNullableFloat(a.height ?? b.height, b.height ?? a.height, t), - background: t < 0.5 ? a.background : b.background, + foreground: (a.foreground != null || b.foreground != null) + ? t < 0.5 + ? a.foreground ?? new Paint() {color = a.color} + : b.foreground ?? new Paint() {color = b.color} + : null, + background: (a.background != null || b.background != null) + ? t < 0.5 + ? a.background ?? new Paint() {color = a.backgroundColor} + : b.background ?? new Paint() {color = b.backgroundColor} + : null, decoration: t < 0.5 ? a.decoration : b.decoration, decorationColor: Color.lerp(a.decorationColor, b.decorationColor, t), decorationStyle: t < 0.5 ? a.decorationStyle : b.decorationStyle, + decorationThickness: MathUtils.lerpFloat( + a.decorationThickness ?? b.decorationThickness ?? 0.0f, + b.decorationThickness ?? a.decorationThickness ?? 0.0f, t), + shadows: t < 0.5f ? a.shadows : b.shadows, debugLabel: lerpDebugLabel ); } @@ -291,8 +385,12 @@ public override void debugFillProperties(DiagnosticPropertiesBuilder properties) List styles = new List(); styles.Add(new DiagnosticsProperty("color", this.color, defaultValue: Diagnostics.kNullDefaultValue)); + styles.Add(new DiagnosticsProperty("backgroundColor", this.backgroundColor, + defaultValue: Diagnostics.kNullDefaultValue)); styles.Add(new StringProperty("family", this.fontFamily, defaultValue: Diagnostics.kNullDefaultValue, quoted: false)); + styles.Add(new EnumerableProperty("familyFallback", this.fontFamilyFallback, + defaultValue: Diagnostics.kNullDefaultValue)); styles.Add(new DiagnosticsProperty("size", this.fontSize, defaultValue: Diagnostics.kNullDefaultValue)); string weightDescription = ""; @@ -315,6 +413,8 @@ public override void debugFillProperties(DiagnosticPropertiesBuilder properties) defaultValue: Diagnostics.kNullDefaultValue)); styles.Add(new DiagnosticsProperty("height", this.height, defaultValue: Diagnostics.kNullDefaultValue)); + styles.Add(new StringProperty("foreground", this.foreground == null ? null : this.foreground.ToString(), + defaultValue: Diagnostics.kNullDefaultValue, quoted: false)); styles.Add(new StringProperty("background", this.background == null ? null : this.background.ToString(), defaultValue: Diagnostics.kNullDefaultValue, quoted: false)); if (this.decoration != null) { @@ -339,6 +439,8 @@ public override void debugFillProperties(DiagnosticPropertiesBuilder properties) D.assert(decorationDescription.isNotEmpty); styles.Add(new MessageProperty("decoration", string.Join(" ", decorationDescription.ToArray()))); + styles.Add(new FloatProperty("decorationThickness", this.decorationThickness, unit: "x", + defaultValue: Diagnostics.kNoDefaultValue)); } bool styleSpecified = styles.Any((DiagnosticsNode n) => !n.isFiltered(DiagnosticLevel.info)); @@ -363,14 +465,24 @@ public bool Equals(TextStyle other) { return true; } - return this.inherit == other.inherit && Equals(this.color, other.color) && - this.fontSize.Equals(other.fontSize) && this.fontWeight == other.fontWeight && - this.fontStyle == other.fontStyle && this.letterSpacing.Equals(other.letterSpacing) && - this.wordSpacing.Equals(other.wordSpacing) && this.textBaseline == other.textBaseline && + return this.inherit == other.inherit && + Equals(this.color, other.color) && + Equals(this.backgroundColor, other.backgroundColor) && + this.fontSize.Equals(other.fontSize) && + this.fontWeight == other.fontWeight && + this.fontStyle == other.fontStyle && + this.letterSpacing.Equals(other.letterSpacing) && + this.wordSpacing.Equals(other.wordSpacing) && + this.textBaseline == other.textBaseline && this.height.Equals(other.height) && Equals(this.decoration, other.decoration) && Equals(this.decorationColor, other.decorationColor) && - this.decorationStyle == other.decorationStyle && Equals(this.background, other.background) && + this.decorationStyle == other.decorationStyle && + this.decorationThickness == other.decorationThickness && + Equals(this.foreground, other.foreground) && + Equals(this.background, other.background) && + this.fontFamilyFallback.equalsList(other.fontFamilyFallback) && + this.shadows.equalsList(other.shadows) && string.Equals(this.fontFamily, other.fontFamily); } @@ -394,6 +506,7 @@ public override int GetHashCode() { unchecked { var hashCode = this.inherit.GetHashCode(); hashCode = (hashCode * 397) ^ (this.color != null ? this.color.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (this.backgroundColor != null ? this.backgroundColor.GetHashCode() : 0); hashCode = (hashCode * 397) ^ this.fontSize.GetHashCode(); hashCode = (hashCode * 397) ^ (this.fontWeight != null ? this.fontWeight.GetHashCode() : 0); hashCode = (hashCode * 397) ^ this.fontStyle.GetHashCode(); @@ -404,8 +517,13 @@ public override int GetHashCode() { hashCode = (hashCode * 397) ^ (this.decoration != null ? this.decoration.GetHashCode() : 0); hashCode = (hashCode * 397) ^ (this.decorationColor != null ? this.decorationColor.GetHashCode() : 0); hashCode = (hashCode * 397) ^ this.decorationStyle.GetHashCode(); + hashCode = (hashCode * 397) ^ this.decorationThickness.GetHashCode(); + hashCode = (hashCode * 397) ^ (this.foreground != null ? this.foreground.GetHashCode() : 0); hashCode = (hashCode * 397) ^ (this.background != null ? this.background.GetHashCode() : 0); hashCode = (hashCode * 397) ^ (this.fontFamily != null ? this.fontFamily.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ + (this.fontFamilyFallback != null ? this.fontFamilyFallback.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (this.shadows != null ? this.shadows.GetHashCode() : 0); return hashCode; } } diff --git a/Runtime/rendering/binding.cs b/Runtime/rendering/binding.cs index eb281408..d08ce137 100644 --- a/Runtime/rendering/binding.cs +++ b/Runtime/rendering/binding.cs @@ -18,6 +18,7 @@ public RendererBinding(bool inEditorWindow = false) { Window.instance.onMetricsChanged += this.handleMetricsChanged; Window.instance.onTextScaleFactorChanged += this.handleTextScaleFactorChanged; + Window.instance.onPlatformBrightnessChanged += this.handlePlatformBrightnessChanged; this.initRenderView(); D.assert(this.renderView != null); this.addPersistentFrameCallback(this._handlePersistentFrameCallback); diff --git a/Runtime/rendering/box.cs b/Runtime/rendering/box.cs index aa88223b..54321bf6 100644 --- a/Runtime/rendering/box.cs +++ b/Runtime/rendering/box.cs @@ -772,7 +772,7 @@ public float getMaxIntrinsicHeight(float width) { this.computeMaxIntrinsicHeight); } - protected virtual float computeMaxIntrinsicHeight(float width) { + protected internal virtual float computeMaxIntrinsicHeight(float width) { return 0.0f; } @@ -1093,12 +1093,12 @@ protected override void debugAssertDoesMeetConstraints() { if (this.constraints.hasBoundedWidth) { testIntrinsicsForValues(this.getMinIntrinsicWidth, this.getMaxIntrinsicWidth, "Width", - this.constraints.maxWidth); + this.constraints.maxHeight); } if (this.constraints.hasBoundedHeight) { testIntrinsicsForValues(this.getMinIntrinsicHeight, this.getMaxIntrinsicHeight, "Height", - this.constraints.maxHeight); + this.constraints.maxWidth); } debugCheckingIntrinsics = false; diff --git a/Runtime/rendering/custom_layout.cs b/Runtime/rendering/custom_layout.cs index f3f6c9f5..536ae8f4 100644 --- a/Runtime/rendering/custom_layout.cs +++ b/Runtime/rendering/custom_layout.cs @@ -233,7 +233,7 @@ protected override float computeMinIntrinsicHeight(float width) { return 0.0f; } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { float height = this._getSize(BoxConstraints.tightForFinite(width: width)).height; if (height.isFinite()) { return height; diff --git a/Runtime/rendering/debug.cs b/Runtime/rendering/debug.cs new file mode 100644 index 00000000..871aa3d2 --- /dev/null +++ b/Runtime/rendering/debug.cs @@ -0,0 +1,5 @@ +namespace Unity.UIWidgets.rendering { + public static class RenderingDebugUtils { + public static bool debugCheckElevationsEnabled = false; + } +} \ No newline at end of file diff --git a/Runtime/rendering/debug.cs.meta b/Runtime/rendering/debug.cs.meta new file mode 100644 index 00000000..8c4f13ab --- /dev/null +++ b/Runtime/rendering/debug.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bb8359f97867cd54592d13cfe1b1d39a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/rendering/editable.cs b/Runtime/rendering/editable.cs index 48842a7e..fa406549 100644 --- a/Runtime/rendering/editable.cs +++ b/Runtime/rendering/editable.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using Unity.UIWidgets.foundation; using Unity.UIWidgets.gestures; using Unity.UIWidgets.painting; @@ -10,6 +11,13 @@ using Rect = Unity.UIWidgets.ui.Rect; namespace Unity.UIWidgets.rendering { + class EditableUtils { + public static readonly float _kCaretGap = 1.0f; + public static readonly float _kCaretHeightOffset = 2.0f; + public static readonly Offset _kFloatingCaretSizeIncrease = new Offset(0.5f, 1.0f); + public static readonly float _kFloatingCaretRadius = 1.0f; + } + public delegate void SelectionChangedHandler(TextSelection selection, RenderEditable renderObject, SelectionChangedCause cause); @@ -40,67 +48,56 @@ public override string ToString() { } public class RenderEditable : RenderBox { - public static readonly char obscuringCharacter = '•'; - static readonly float _kCaretGap = 1.0f; - static readonly float _kCaretHeightOffset = 2.0f; - static readonly Offset _kFloatingCaretSizeIncrease = new Offset(0.5f, 1.0f); - static readonly float _kFloatingCaretRadius = 1.0f; - - TextPainter _textPainter; - Color _cursorColor; - int? _maxLines; - Color _selectionColor; - ViewportOffset _offset; - ValueNotifier _showCursor; - TextSelection _selection; - bool _obscureText; - TapGestureRecognizer _tap; - LongPressGestureRecognizer _longPress; - DoubleTapGestureRecognizer _doubleTap; - public bool ignorePointer; - public SelectionChangedHandler onSelectionChanged; - public CaretChangedHandler onCaretChanged; - Rect _lastCaretRect; - float? _textLayoutLastWidth; - List _selectionRects; - Rect _caretPrototype; - bool _hasVisualOverflow = false; - Offset _lastTapDownPosition; - public RenderEditable( TextSpan text, TextDirection textDirection, - ViewportOffset offset, - ValueNotifier showCursor, TextAlign textAlign = TextAlign.left, - float textScaleFactor = 1.0f, Color cursorColor = null, Color backgroundCursorColor = null, + ValueNotifier showCursor = null, bool? hasFocus = null, int? maxLines = 1, + int? minLines = null, + bool expands = false, + StrutStyle strutStyle = null, Color selectionColor = null, + float textScaleFactor = 1.0f, TextSelection selection = null, - bool obscureText = false, + ViewportOffset offset = null, SelectionChangedHandler onSelectionChanged = null, CaretChangedHandler onCaretChanged = null, bool ignorePointer = false, + bool obscureText = false, float cursorWidth = 1.0f, Radius cursorRadius = null, - bool? enableInteractiveSelection = null, bool paintCursorAboveText = false, Offset cursorOffset = null, float devicePixelRatio = 1.0f, + bool? enableInteractiveSelection = null, EdgeInsets floatingCursorAddedMargin = null, - TextSelectionDelegate textSelectionDelegate = null) { + TextSelectionDelegate textSelectionDelegate = null, + GlobalKeyEventHandlerDelegate globalKeyEventHandler = null) { floatingCursorAddedMargin = floatingCursorAddedMargin ?? EdgeInsets.fromLTRB(4, 4, 4, 5); D.assert(textSelectionDelegate != null); - this._textPainter = new TextPainter(text: text, textAlign: textAlign, textDirection: textDirection, - textScaleFactor: textScaleFactor); + D.assert(minLines == null || minLines > 0); + D.assert(maxLines == null || maxLines > 0); + D.assert((maxLines == null) || (minLines == null) || maxLines >= minLines, + () => "minLines can't be greater than maxLines"); + D.assert(offset != null); + D.assert(cursorWidth >= 0.0f); + this._textPainter = new TextPainter( + text: text, + textAlign: textAlign, + textDirection: textDirection, + textScaleFactor: textScaleFactor, + strutStyle: strutStyle); this._cursorColor = cursorColor; - + this._backgroundCursorColor = backgroundCursorColor; this._showCursor = showCursor ?? new ValueNotifier(false); this._hasFocus = hasFocus ?? false; this._maxLines = maxLines; + this._minLines = minLines; + this._expands = expands; this._selectionColor = selectionColor; this._selection = selection; this._obscureText = obscureText; @@ -112,6 +109,7 @@ public RenderEditable( this.onCaretChanged = onCaretChanged; this.onSelectionChanged = onSelectionChanged; this.textSelectionDelegate = textSelectionDelegate; + this.globalKeyEventHandler = globalKeyEventHandler; D.assert(this._maxLines == null || this._maxLines > 0); D.assert(this._showCursor != null); @@ -125,13 +123,20 @@ public RenderEditable( this._longPress = new LongPressGestureRecognizer(debugOwner: this); this._longPress.onLongPress = this._handleLongPress; - this._backgroundCursorColor = backgroundCursorColor; this._paintCursorOnTop = paintCursorAboveText; this._cursorOffset = cursorOffset; this._floatingCursorAddedMargin = floatingCursorAddedMargin; this._devicePixelRatio = devicePixelRatio; } + public static readonly char obscuringCharacter = '•'; + public SelectionChangedHandler onSelectionChanged; + float? _textLayoutLastWidth; + public CaretChangedHandler onCaretChanged; + public bool ignorePointer; + + float _devicePixelRatio; + public float devicePixelRatio { get { return this._devicePixelRatio; } set { @@ -144,91 +149,66 @@ public float devicePixelRatio { } } - float _devicePixelRatio; + bool _obscureText; - public Color backgroundCursorColor { - get { return this._backgroundCursorColor; } + public bool obscureText { + get { return this._obscureText; } set { - if (this.backgroundCursorColor == value) { + if (this._obscureText == value) { return; } - this._backgroundCursorColor = value; - this.markNeedsPaint(); + this._obscureText = value; + this.markNeedsSemanticsUpdate(); } } - Color _backgroundCursorColor; + public TextSelectionDelegate textSelectionDelegate; + public GlobalKeyEventHandlerDelegate globalKeyEventHandler; + Rect _lastCaretRect; - public bool paintCursorAboveText { - get { return this._paintCursorOnTop; } - set { - if (this._paintCursorOnTop == value) { - return; - } - this._paintCursorOnTop = value; - this.markNeedsLayout(); - } + public ValueListenable selectionStartInViewport { + get { return this._selectionStartInViewport; } } - bool _paintCursorOnTop; + readonly ValueNotifier _selectionStartInViewport = new ValueNotifier(true); - public Offset cursorOffset { - get { return this._cursorOffset; } - set { - if (this._cursorOffset == value) { - return; - } - - this._cursorOffset = value; - this.markNeedsLayout(); - } + public ValueListenable selectionEndInViewport { + get { return this._selectionEndInViewport; } } - Offset _cursorOffset; + readonly ValueNotifier _selectionEndInViewport = new ValueNotifier(true); - public EdgeInsets floatingCursorAddedMargin { - get { return this._floatingCursorAddedMargin; } - set { - if (this._floatingCursorAddedMargin == value) { - return; - } - - this._floatingCursorAddedMargin = value; - this.markNeedsPaint(); - } - } - - EdgeInsets _floatingCursorAddedMargin; - bool _floatingCursorOn = false; - Offset _floatingCursorOffset; - TextPosition _floatingCursorTextPosition; + DoubleTapGestureRecognizer _doubleTap; - public bool selectionEnabled { - get { return this.enableInteractiveSelection ?? !this.obscureText; } - } + void _updateSelectionExtentsVisibility(Offset effectiveOffset) { + Rect visibleRegion = Offset.zero & this.size; + Offset startOffset = this._textPainter.getOffsetForCaret( + new TextPosition(offset: this._selection.start, affinity: this._selection.affinity), + Rect.zero + ); - public bool obscureText { - get { return this._obscureText; } - set { - if (this._obscureText == value) { - return; - } + float visibleRegionSlop = 0.5f; + this._selectionStartInViewport.value = visibleRegion + .inflate(visibleRegionSlop) + .contains(startOffset + effectiveOffset); - this._obscureText = value; - this.markNeedsSemanticsUpdate(); - } + Offset endOffset = this._textPainter.getOffsetForCaret( + new TextPosition(offset: this._selection.end, affinity: this._selection.affinity), + Rect.zero + ); + this._selectionEndInViewport.value = visibleRegion + .inflate(visibleRegionSlop) + .contains(endOffset + effectiveOffset); } - public TextSelectionDelegate textSelectionDelegate; - int _extentOffset = -1; int _baseOffset = -1; - int _previousCursorLocation; + int _previousCursorLocation = -1; bool _resetCursor = false; @@ -241,6 +221,10 @@ void _handleKeyEvent(RawKeyEvent keyEvent) { this._extentOffset = this.selection.extentOffset; this._baseOffset = this.selection.baseOffset; } + + if (this.globalKeyEventHandler?.Invoke(keyEvent, false)?.swallow ?? false) { + return; + } KeyCode pressedKeyCode = keyEvent.data.unityEvent.keyCode; int modifiers = (int) keyEvent.data.unityEvent.modifiers; @@ -528,6 +512,8 @@ protected void markNeedsTextLayout() { this.markNeedsLayout(); } + TextPainter _textPainter; + public TextSpan text { get { return this._textPainter.text; } set { @@ -566,6 +552,20 @@ public TextDirection? textDirection { } } + public StrutStyle strutStyle { + get { return this._textPainter.strutStyle; } + set { + if (this._textPainter.strutStyle == value) { + return; + } + + this._textPainter.strutStyle = value; + this.markNeedsTextLayout(); + } + } + + Color _cursorColor; + public Color cursorColor { get { return this._cursorColor; } set { @@ -578,6 +578,23 @@ public Color cursorColor { } } + Color _backgroundCursorColor; + + public Color backgroundCursorColor { + get { return this._backgroundCursorColor; } + set { + if (this.backgroundCursorColor == value) { + return; + } + + this._backgroundCursorColor = value; + this.markNeedsPaint(); + } + } + + + ValueNotifier _showCursor; + public ValueNotifier showCursor { get { return this._showCursor; } set { @@ -599,7 +616,7 @@ public ValueNotifier showCursor { } } - bool _hasFocus; + bool _hasFocus = false; bool _listenerAttached = false; public bool hasFocus { @@ -625,6 +642,8 @@ public bool hasFocus { } } + int? _maxLines; + public int? maxLines { get { return this._maxLines; } set { @@ -638,6 +657,37 @@ public int? maxLines { } } + int? _minLines; + + public int? minLines { + get { return this._minLines; } + set { + D.assert(value == null || value > 0); + if (this._minLines == value) { + return; + } + + this._minLines = value; + this.markNeedsTextLayout(); + } + } + + bool _expands; + + public bool expands { + get { return this._expands; } + set { + if (this.expands == value) { + return; + } + + this._expands = value; + this.markNeedsTextLayout(); + } + } + + Color _selectionColor; + public Color selectionColor { get { return this._selectionColor; } set { @@ -662,6 +712,10 @@ public float textScaleFactor { } } + List _selectionRects; + + TextSelection _selection; + public TextSelection selection { get { return this._selection; } set { @@ -676,6 +730,8 @@ public TextSelection selection { } } + ViewportOffset _offset; + public ViewportOffset offset { get { return this._offset; } set { @@ -711,6 +767,35 @@ public float cursorWidth { } } + + bool _paintCursorOnTop; + + public bool paintCursorAboveText { + get { return this._paintCursorOnTop; } + set { + if (this._paintCursorOnTop == value) { + return; + } + + this._paintCursorOnTop = value; + this.markNeedsLayout(); + } + } + + Offset _cursorOffset; + + public Offset cursorOffset { + get { return this._cursorOffset; } + set { + if (this._cursorOffset == value) { + return; + } + + this._cursorOffset = value; + this.markNeedsLayout(); + } + } + Radius _cursorRadius; public Radius cursorRadius { @@ -725,6 +810,25 @@ public Radius cursorRadius { } } + public EdgeInsets floatingCursorAddedMargin { + get { return this._floatingCursorAddedMargin; } + set { + if (this._floatingCursorAddedMargin == value) { + return; + } + + this._floatingCursorAddedMargin = value; + this.markNeedsPaint(); + } + } + + EdgeInsets _floatingCursorAddedMargin; + + bool _floatingCursorOn = false; + Offset _floatingCursorOffset; + TextPosition _floatingCursorTextPosition; + + bool? _enableInteractiveSelection; public bool? enableInteractiveSelection { @@ -740,8 +844,8 @@ public bool? enableInteractiveSelection { } } - public float preferredLineHeight { - get { return this._textPainter.preferredLineHeight; } + public bool selectionEnabled { + get { return this.enableInteractiveSelection ?? !this.obscureText; } } @@ -761,6 +865,60 @@ public override void detach() { base.detach(); } + bool _isMultiline { + get { return this._maxLines != 1; } + } + + Axis _viewportAxis { + get { return this._isMultiline ? Axis.vertical : Axis.horizontal; } + } + + Offset _paintOffset { + get { + switch (this._viewportAxis) { + case Axis.horizontal: + return new Offset(-this.offset.pixels, 0.0f); + case Axis.vertical: + return new Offset(0.0f, -this.offset.pixels); + } + + return null; + } + } + + float _viewportExtent { + get { + D.assert(this.hasSize); + switch (this._viewportAxis) { + case Axis.horizontal: + return this.size.width; + case Axis.vertical: + return this.size.height; + } + + return 0.0f; + } + } + + float _getMaxScrollExtent(Size contentSize) { + D.assert(this.hasSize); + switch (this._viewportAxis) { + case Axis.horizontal: + return Mathf.Max(0.0f, contentSize.width - this.size.width); + case Axis.vertical: + return Mathf.Max(0.0f, contentSize.height - this.size.height); + } + + return 0.0f; + } + + float _maxScrollExtent = 0; + + bool _hasVisualOverflow { + get { return this._maxScrollExtent > 0 || this._paintOffset != Offset.zero; } + } + + /// Returns the local coordinates of the endpoints of the given selection. /// /// If the selection is collapsed (and therefore occupies a single point), the @@ -933,11 +1091,52 @@ protected override float computeMaxIntrinsicWidth(float height) { return this._textPainter.maxIntrinsicWidth + this.cursorWidth; } + public float preferredLineHeight { + get { return this._textPainter.preferredLineHeight; } + } + + float _preferredHeight(float width) { + bool lockedMax = this.maxLines != null && this.minLines == null; + bool lockedBoth = this.maxLines != null && this.minLines == this.maxLines; + bool singleLine = this.maxLines == 1; + if (singleLine || lockedMax || lockedBoth) { + return this.preferredLineHeight * this.maxLines.Value; + } + + bool minLimited = this.minLines != null && this.minLines > 1; + bool maxLimited = this.maxLines != null; + if (minLimited || maxLimited) { + this._layoutText(width); + if (minLimited && this._textPainter.height < this.preferredLineHeight * this.minLines.Value) { + return this.preferredLineHeight * this.minLines.Value; + } + + if (maxLimited && this._textPainter.height > this.preferredLineHeight * this.maxLines.Value) { + return this.preferredLineHeight * this.maxLines.Value; + } + } + + if (!width.isFinite()) { + var text = this._textPainter.text.text; + int lines = 1; + for (int index = 0; index < text.Length; ++index) { + if (text[index] == 0x0A) { + lines += 1; + } + } + + return this.preferredLineHeight * lines; + } + + this._layoutText(width); + return Mathf.Max(this.preferredLineHeight, this._textPainter.height); + } + protected override float computeMinIntrinsicHeight(float width) { return this._preferredHeight(width); } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { return this._preferredHeight(width); } @@ -946,6 +1145,13 @@ protected override float computeMaxIntrinsicHeight(float width) { return this._textPainter.computeDistanceToActualBaseline(baseline); } + protected override bool hitTestSelf(Offset position) { + return true; + } + + TapGestureRecognizer _tap; + LongPressGestureRecognizer _longPress; + public override void handleEvent(PointerEvent evt, HitTestEntry entry) { if (this.ignorePointer) { return; @@ -959,8 +1165,10 @@ public override void handleEvent(PointerEvent evt, HitTestEntry entry) { } } + Offset _lastTapDownPosition; + public void handleTapDown(TapDownDetails details) { - this._lastTapDownPosition = details.globalPosition - this._paintOffset; + this._lastTapDownPosition = details.globalPosition; if (!Application.isMobilePlatform) { this.selectPosition(SelectionChangedCause.tap); } @@ -1036,7 +1244,7 @@ public void selectWord(SelectionChangedCause? cause = null) { this.selectWordsInRange(from: this._lastTapDownPosition, cause: cause); } - void selectWordsInRange(Offset from = null, Offset to = null, SelectionChangedCause? cause = null) { + public void selectWordsInRange(Offset from = null, Offset to = null, SelectionChangedCause? cause = null) { D.assert(cause != null); D.assert(from != null); this._layoutText(this.constraints.maxWidth); @@ -1064,7 +1272,8 @@ public void selectWordEdge(SelectionChangedCause cause) { D.assert(this._lastTapDownPosition != null); if (this.onSelectionChanged != null) { TextPosition position = - this._textPainter.getPositionForOffset(this.globalToLocal(this._lastTapDownPosition)); + this._textPainter.getPositionForOffset( + this.globalToLocal(this._lastTapDownPosition - this._paintOffset)); TextRange word = this._textPainter.getWordBoundary(position); if (position.offset - word.start <= 1) { this.onSelectionChanged( @@ -1093,12 +1302,14 @@ TextSelection _selectWordAtOffset(TextPosition position) { return new TextSelection(baseOffset: word.start, extentOffset: word.end); } + Rect _caretPrototype; + void _layoutText(float constraintWidth) { if (this._textLayoutLastWidth == constraintWidth) { return; } - var caretMargin = _kCaretGap + this.cursorWidth; + var caretMargin = EditableUtils._kCaretGap + this.cursorWidth; var avialableWidth = Mathf.Max(0.0f, constraintWidth - caretMargin); var maxWidth = this._isMultiline ? avialableWidth : float.PositiveInfinity; this._textPainter.layout(minWidth: avialableWidth, maxWidth: maxWidth); @@ -1109,11 +1320,11 @@ Rect _getCaretPrototype { get { switch (Application.platform) { case RuntimePlatform.IPhonePlayer: - return Rect.fromLTWH(0.0f, -_kCaretHeightOffset + 0.5f, this.cursorWidth, + return Rect.fromLTWH(0.0f, 0.0f, this.cursorWidth, this.preferredLineHeight + 2.0f); default: - return Rect.fromLTWH(0.0f, _kCaretHeightOffset, this.cursorWidth, - this.preferredLineHeight - 2.0f * _kCaretHeightOffset); + return Rect.fromLTWH(0.0f, EditableUtils._kCaretHeightOffset, this.cursorWidth, + this.preferredLineHeight - 2.0f * EditableUtils._kCaretHeightOffset); } } } @@ -1127,30 +1338,13 @@ protected override void performLayout() { var textPainterSize = this._textPainter.size; this.size = new Size(this.constraints.maxWidth, this.constraints.constrainHeight(this._preferredHeight(this.constraints.maxWidth))); - var contentSize = new Size(textPainterSize.width + _kCaretGap + this.cursorWidth, + var contentSize = new Size(textPainterSize.width + EditableUtils._kCaretGap + this.cursorWidth, textPainterSize.height); - var _maxScrollExtent = this._getMaxScrollExtend(contentSize); - this._hasVisualOverflow = _maxScrollExtent > 0.0; - this.offset.applyViewportDimension(this._viewportExtend); - this.offset.applyContentDimensions(0.0f, _maxScrollExtent); - } - - public override void paint(PaintingContext context, Offset offset) { - this._layoutText(this.constraints.maxWidth); - if (this._hasVisualOverflow) { - context.pushClipRect(this.needsCompositing, offset, Offset.zero & this.size, this._paintContents); - } - else { - this._paintContents(context, offset); - } + this._maxScrollExtent = this._getMaxScrollExtent(contentSize); + this.offset.applyViewportDimension(this._viewportExtent); + this.offset.applyContentDimensions(0.0f, this._maxScrollExtent); } - protected override bool hitTestSelf(Offset position) { - return true; - } - - // describeSemanticsConfiguration todo - Offset _getPixelPerfectCursorOffset(Rect caretRect) { Offset caretPosition = this.localToGlobal(caretRect.topLeft); float pixelMultiple = 1.0f / this._devicePixelRatio; @@ -1163,12 +1357,37 @@ Offset _getPixelPerfectCursorOffset(Rect caretRect) { void _paintCaret(Canvas canvas, Offset effectiveOffset, TextPosition textPosition) { D.assert(this._textLayoutLastWidth == this.constraints.maxWidth); - var caretOffset = this._textPainter.getOffsetForCaret(textPosition, this._caretPrototype); var paint = new Paint() {color = this._floatingCursorOn ? this.backgroundCursorColor : this._cursorColor}; - Rect caretRect = this._caretPrototype.shift(caretOffset + effectiveOffset); + var caretOffset = this._textPainter.getOffsetForCaret(textPosition, this._caretPrototype) + effectiveOffset; + Rect caretRect = this._caretPrototype.shift(caretOffset); if (this._cursorOffset != null) { caretRect = caretRect.shift(this._cursorOffset); } + + float? caretHeight = this._textPainter.getFullHeightForCaret(textPosition, this._caretPrototype); + if (caretHeight != null) { + switch (Application.platform) { + case RuntimePlatform.IPhonePlayer: + float heightDiff = caretHeight.Value - caretRect.height; + caretRect = Rect.fromLTWH( + caretRect.left, + caretRect.top + heightDiff / 2f, + caretRect.width, + caretRect.height + ); + break; + default: + caretRect = Rect.fromLTWH( + caretRect.left, + caretRect.top - EditableUtils._kCaretHeightOffset, + caretRect.width, + caretHeight.Value + ); + break; + } + } + + caretRect = caretRect.shift(this._getPixelPerfectCursorOffset(caretRect)); if (this.cursorRadius == null) { canvas.drawRect(caretRect, paint); @@ -1210,14 +1429,16 @@ public void setFloatingCursor(FloatingCursorDragState? state, Offset boundedOffs this.markNeedsPaint(); } + // describeSemanticsConfiguration todo + void _paintFloatingCaret(Canvas canvas, Offset effectiveOffset) { D.assert(this._textLayoutLastWidth == this.constraints.maxWidth); D.assert(this._floatingCursorOn); Paint paint = new Paint() {color = this._cursorColor.withOpacity(0.75f)}; - float sizeAdjustmentX = _kFloatingCaretSizeIncrease.dx; - float sizeAdjustmentY = _kFloatingCaretSizeIncrease.dy; + float sizeAdjustmentX = EditableUtils._kFloatingCaretSizeIncrease.dx; + float sizeAdjustmentY = EditableUtils._kFloatingCaretSizeIncrease.dy; if (this._resetFloatingCursorAnimationValue != null) { sizeAdjustmentX = @@ -1234,7 +1455,7 @@ void _paintFloatingCaret(Canvas canvas, Offset effectiveOffset) { ); Rect caretRect = floatingCaretPrototype.shift(effectiveOffset); - Radius floatingCursorRadius = Radius.circular(_kFloatingCaretRadius); + Radius floatingCursorRadius = Radius.circular(EditableUtils._kFloatingCaretRadius); RRect caretRRect = RRect.fromRectAndRadius(caretRect, floatingCursorRadius); canvas.drawRRect(caretRRect, paint); } @@ -1326,6 +1547,7 @@ void _paintContents(PaintingContext context, Offset offset) { else if (!this._selection.isCollapsed && this._selectionColor != null) { showSelection = true; } + this._updateSelectionExtentsVisibility(effectiveOffset); } if (showSelection) { @@ -1358,76 +1580,18 @@ void markNeedsSemanticsUpdate() { // todo } - float _preferredHeight(float width) { - if (this.maxLines != null) { - return this.preferredLineHeight * this.maxLines.Value; - } - - if (!width.isFinite()) { - var text = this._textPainter.text.text; - int lines = 1; - for (int index = 0; index < text.Length; ++index) { - if (text[index] == 0x0A) { - lines += 1; - } - } - - return this.preferredLineHeight * lines; - } - - this._layoutText(width); - return Mathf.Max(this.preferredLineHeight, this._textPainter.height); - } - - bool _isMultiline { - get { return this._maxLines != 1; } - } - - Axis _viewportAxis { - get { return this._isMultiline ? Axis.vertical : Axis.horizontal; } - } - - Offset _paintOffset { - get { - switch (this._viewportAxis) { - case Axis.horizontal: - return new Offset(-this.offset.pixels, 0.0f); - case Axis.vertical: - return new Offset(0.0f, -this.offset.pixels); - } - - return null; - } + public override Rect describeApproximatePaintClip(RenderObject child) { + return this._hasVisualOverflow ? Offset.zero & this.size : null; } - float _viewportExtend { - get { - D.assert(this.hasSize); - switch (this._viewportAxis) { - case Axis.horizontal: - return this.size.width; - case Axis.vertical: - return this.size.height; - } - - return 0.0f; + public override void paint(PaintingContext context, Offset offset) { + this._layoutText(this.constraints.maxWidth); + if (this._hasVisualOverflow) { + context.pushClipRect(this.needsCompositing, offset, Offset.zero & this.size, this._paintContents); } - } - - float _getMaxScrollExtend(Size contentSize) { - D.assert(this.hasSize); - switch (this._viewportAxis) { - case Axis.horizontal: - return Mathf.Max(0.0f, contentSize.width - this.size.width); - case Axis.vertical: - return Mathf.Max(0.0f, contentSize.height - this.size.height); + else { + this._paintContents(context, offset); } - - return 0.0f; - } - - public override Rect describeApproximatePaintClip(RenderObject child) { - return this._hasVisualOverflow ? Offset.zero & this.size : null; } public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { @@ -1435,6 +1599,8 @@ public override void debugFillProperties(DiagnosticPropertiesBuilder properties) properties.add(new DiagnosticsProperty("cursorColor", this.cursorColor)); properties.add(new DiagnosticsProperty>("showCursor", this.showCursor)); properties.add(new DiagnosticsProperty("maxLines", this.maxLines)); + properties.add(new DiagnosticsProperty("minLines", this.minLines)); + properties.add(new DiagnosticsProperty("expands", this.expands)); properties.add(new DiagnosticsProperty("selectionColor", this.selectionColor)); properties.add(new DiagnosticsProperty("textScaleFactor", this.textScaleFactor)); properties.add(new DiagnosticsProperty("selection", this.selection)); diff --git a/Runtime/rendering/error.cs b/Runtime/rendering/error.cs index 763d4153..f4cb92a8 100644 --- a/Runtime/rendering/error.cs +++ b/Runtime/rendering/error.cs @@ -29,7 +29,7 @@ public RenderErrorBox(string message = "") { ); static ParagraphStyle paragraphStyle = new ParagraphStyle( - lineHeight: 1.0f + height: 1.0f ); } } \ No newline at end of file diff --git a/Runtime/rendering/flex.cs b/Runtime/rendering/flex.cs index afeec0ef..4e9037d4 100644 --- a/Runtime/rendering/flex.cs +++ b/Runtime/rendering/flex.cs @@ -274,7 +274,7 @@ protected override float computeMinIntrinsicHeight(float width) { ); } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { return this._getIntrinsicSize( sizingDirection: Axis.vertical, extent: width, @@ -385,6 +385,8 @@ protected override void performLayout() { if (totalFlex > 0 || this.crossAxisAlignment == CrossAxisAlignment.baseline) { float spacePerFlex = canFlex && totalFlex > 0 ? (freeSpace / totalFlex) : float.NaN; child = this.firstChild; + float maxSizeAboveBaseline = 0; + float maxSizeBelowBaseline = 0; while (child != null) { int flex = this._getFlex(child); if (flex > 0) { @@ -448,6 +450,9 @@ protected override void performLayout() { float? distance = child.getDistanceToBaseline(this.textBaseline, onlyReal: true); if (distance != null) { maxBaselineDistance = Mathf.Max(maxBaselineDistance, distance.Value); + maxSizeAboveBaseline = Mathf.Max(distance.Value, maxSizeAboveBaseline); + maxSizeBelowBaseline = Mathf.Max(child.size.height - distance.Value, maxSizeBelowBaseline); + crossSize = maxSizeAboveBaseline + maxSizeBelowBaseline; } } diff --git a/Runtime/rendering/image.cs b/Runtime/rendering/image.cs index d7981867..1b2af006 100644 --- a/Runtime/rendering/image.cs +++ b/Runtime/rendering/image.cs @@ -259,7 +259,7 @@ protected override float computeMinIntrinsicHeight(float width) { return this._sizeForConstraints(BoxConstraints.tightForFinite(width: width)).height; } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { D.assert(width >= 0.0); return this._sizeForConstraints(BoxConstraints.tightForFinite(width: width)).height; } diff --git a/Runtime/rendering/layer.cs b/Runtime/rendering/layer.cs index aa11c224..4cad0f53 100644 --- a/Runtime/rendering/layer.cs +++ b/Runtime/rendering/layer.cs @@ -1,6 +1,6 @@ -using System; -using System.Collections.Generic; -using Unity.UIWidgets.external.simplejson; +using System.Collections.Generic; +using System.Linq; +using System.Text; using Unity.UIWidgets.foundation; using Unity.UIWidgets.painting; using Unity.UIWidgets.ui; @@ -243,7 +243,7 @@ public Layer firstChild { public Layer lastChild { get { return this._lastChild; } } - + internal override S find(Offset regionOffset) { Layer current = this.lastChild; while (current != null) { @@ -282,6 +282,95 @@ bool _debugUltimateNextSiblingOf(Layer child, Layer equals = null) { return child == equals; } + PictureLayer _highlightConflictingLayer(PhysicalModelLayer child) { + PictureRecorder recorder = new PictureRecorder(); + var canvas = new RecorderCanvas(recorder); + canvas.drawPath(child.clipPath, new Paint() { + color = new Color(0xFFAA0000), + style = PaintingStyle.stroke, + strokeWidth = child.elevation + 10.0f, + }); + PictureLayer pictureLayer = new PictureLayer(child.clipPath.getBounds()); + pictureLayer.picture = recorder.endRecording(); + pictureLayer.debugCreator = child; + child.append(pictureLayer); + return pictureLayer; + } + + List _processConflictingPhysicalLayers(PhysicalModelLayer predecessor, PhysicalModelLayer child) { + UIWidgetsError.reportError(new UIWidgetsErrorDetails( + exception: new UIWidgetsError("Painting order is out of order with respect to elevation.\n" + + "See https://api.flutter.dev/flutter/rendering/debugCheckElevations.html " + + "for more details."), + context: "during compositing", + informationCollector: (StringBuilder builder) => { + builder.AppendLine("Attempted to composite layer"); + builder.AppendLine(child.ToString()); + builder.AppendLine("after layer"); + builder.AppendLine(predecessor.ToString()); + builder.AppendLine("which occupies the same area at a higher elevation."); + } + )); + return new List { + this._highlightConflictingLayer(predecessor), + this._highlightConflictingLayer(child) + }; + } + + protected List _debugCheckElevations() { + List physicalModelLayers = + this.depthFirstIterateChildren().OfType().ToList(); + List addedLayers = new List(); + + for (int i = 0; i < physicalModelLayers.Count; i++) { + PhysicalModelLayer physicalModelLayer = physicalModelLayers[i]; + D.assert(physicalModelLayer.lastChild?.debugCreator != physicalModelLayer, + () => "debugCheckElevations has either already visited this layer or failed to remove the" + + " added picture from it."); + float accumulatedElevation = physicalModelLayer.elevation; + Layer ancestor = physicalModelLayer.parent; + while (ancestor != null) { + if (ancestor is PhysicalModelLayer modelLayer) { + accumulatedElevation += modelLayer.elevation; + } + + ancestor = ancestor.parent; + } + + for (int j = 0; j <= i; j++) { + PhysicalModelLayer predecessor = physicalModelLayers[j]; + float predecessorAccumulatedElevation = predecessor.elevation; + ancestor = predecessor.parent; + while (ancestor != null) { + if (ancestor == predecessor) { + continue; + } + + if (ancestor is PhysicalModelLayer modelLayer) { + predecessorAccumulatedElevation += modelLayer.elevation; + } + + ancestor = ancestor.parent; + } + + if (predecessorAccumulatedElevation <= accumulatedElevation) { + continue; + } + + Path intersection = Path.combine( + PathOperation.intersect, + predecessor._debugTransformedClipPath, + physicalModelLayer._debugTransformedClipPath); + + if (intersection != null && intersection.computeMetrics().Any((metric) => metric.length > 0)) { + addedLayers.AddRange(this._processConflictingPhysicalLayers(predecessor, physicalModelLayer)); + } + } + } + + return addedLayers; + } + internal override void updateSubtreeNeedsAddToScene() { base.updateSubtreeNeedsAddToScene(); Layer child = this.firstChild; @@ -419,6 +508,25 @@ public virtual void applyTransform(Layer child, Matrix3 transform) { D.assert(transform != null); } + public List depthFirstIterateChildren() { + if (this.firstChild == null) { + return new List(); + } + + List children = new List(); + Layer child = this.firstChild; + while (child != null) { + children.Add(child); + if (child is ContainerLayer containerLayer) { + children.AddRange(containerLayer.depthFirstIterateChildren()); + } + + child = child.nextSibling; + } + + return children; + } + public override List debugDescribeChildren() { var children = new List(); if (this.firstChild == null) { @@ -470,9 +578,27 @@ public override void applyTransform(Layer child, Matrix3 transform) { } public Scene buildScene(SceneBuilder builder) { + List temporaryLayers = null; + D.assert(() => { + if (RenderingDebugUtils.debugCheckElevationsEnabled) { + temporaryLayers = this._debugCheckElevations(); + } + + return true; + }); this.updateSubtreeNeedsAddToScene(); this.addToScene(builder); - return builder.build(); + Scene scene = builder.build(); + D.assert(() => { + if (temporaryLayers != null) { + foreach (PictureLayer temporaryLayer in temporaryLayers) { + temporaryLayer.remove(); + } + } + + return true; + }); + return scene; } internal override flow.Layer addToScene(SceneBuilder builder, Offset layerOffset = null) { @@ -731,7 +857,7 @@ internal override S find(Offset regionOffset) { if (this._invertedTransform == null) { return null; } - + Offset transform = this._invertedTransform.mapXY(regionOffset.dx, regionOffset.dy); return base.find(transform); } @@ -756,7 +882,13 @@ internal override flow.Layer addToScene(SceneBuilder builder, Offset layerOffset public override void applyTransform(Layer child, Matrix3 transform) { D.assert(child != null); D.assert(transform != null); - transform.preConcat(this._lastEffectiveTransform); + D.assert(this._lastEffectiveTransform != null || this.transform != null); + if (this._lastEffectiveTransform == null) { + transform.preConcat(this.transform); + } + else { + transform.preConcat(this._lastEffectiveTransform); + } } public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { @@ -822,7 +954,7 @@ public override void debugFillProperties(DiagnosticPropertiesBuilder properties) properties.add(new DiagnosticsProperty("offset", this.offset)); } } - + public class BackdropFilterLayer : ContainerLayer { public BackdropFilterLayer(ImageFilter filter = null) { D.assert(filter != null); @@ -1043,7 +1175,7 @@ void _establishTransform() { protected override bool alwaysNeedsAddToScene { get { return true; } } - + internal override flow.Layer addToScene(SceneBuilder builder, Offset layerOffset = null) { layerOffset = layerOffset ?? Offset.zero; @@ -1217,6 +1349,20 @@ public Clip clipBehavior { } } + internal Path _debugTransformedClipPath { + get { + ContainerLayer ancestor = this.parent; + Matrix3 matrix = Matrix3.I(); + while (ancestor != null && ancestor.parent != null) { + ancestor.applyTransform(this, matrix); + ancestor = ancestor.parent; + } + + return this.clipPath.transform(matrix); + } + } + + Clip _clipBehavior; public float elevation { diff --git a/Runtime/rendering/list_body.cs b/Runtime/rendering/list_body.cs index 090737e6..1c1ef934 100644 --- a/Runtime/rendering/list_body.cs +++ b/Runtime/rendering/list_body.cs @@ -253,7 +253,7 @@ protected override float computeMinIntrinsicHeight(float width) { } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { switch (this.mainAxis) { case Axis.horizontal: return this._getIntrinsicMainAxis((RenderBox child) => child.getMaxIntrinsicHeight(width)); diff --git a/Runtime/rendering/list_wheel_viewport.cs b/Runtime/rendering/list_wheel_viewport.cs new file mode 100644 index 00000000..7b6dcc30 --- /dev/null +++ b/Runtime/rendering/list_wheel_viewport.cs @@ -0,0 +1,716 @@ +using System; +using System.Collections.Generic; +using Unity.UIWidgets.animation; +using Unity.UIWidgets.foundation; +using Unity.UIWidgets.gestures; +using Unity.UIWidgets.painting; +using Unity.UIWidgets.ui; +using UnityEngine; +using Rect = Unity.UIWidgets.ui.Rect; + +namespace Unity.UIWidgets.rendering { + delegate float ___ChildSizingFunction(RenderBox child); + + public interface IListWheelChildManager { + int? childCount { get; } + bool childExistsAt(int index); + void createChild(int index, RenderBox after); + void removeChild(RenderBox child); + } + + public class ListWheelParentData : ContainerBoxParentData { + public int index; + } + + public class RenderListWheelViewport : ContainerRenderObjectMixinRenderBox, + RenderAbstractViewport { + public RenderListWheelViewport( + IListWheelChildManager childManager, + ViewportOffset offset, + float itemExtent, + float diameterRatio = defaultDiameterRatio, + float perspective = defaultPerspective, + float offAxisFraction = 0.0f, + bool useMagnifier = false, + float magnification = 1.0f, + bool clipToSize = true, + bool renderChildrenOutsideViewport = false, + List children = null + ) { + D.assert(childManager != null); + D.assert(offset != null); + D.assert(diameterRatio > 0, () => diameterRatioZeroMessage); + D.assert(perspective > 0); + D.assert(perspective <= 0.01f, () => perspectiveTooHighMessage); + D.assert(magnification > 0); + D.assert(itemExtent > 0); + D.assert( + !renderChildrenOutsideViewport || !clipToSize, + () => clipToSizeAndRenderChildrenOutsideViewportConflict + ); + + this.childManager = childManager; + this._offset = offset; + this._diameterRatio = diameterRatio; + this._perspective = perspective; + this._offAxisFraction = offAxisFraction; + this._useMagnifier = useMagnifier; + this._magnification = magnification; + this._itemExtent = itemExtent; + this._clipToSize = clipToSize; + this._renderChildrenOutsideViewport = renderChildrenOutsideViewport; + this.addAll(children); + } + + public const float defaultDiameterRatio = 2.0f; + + public const float defaultPerspective = 0.003f; + + public const string diameterRatioZeroMessage = "You can't set a diameterRatio " + + "of 0 or of a negative number. It would imply a cylinder of 0 in diameter " + + "in which case nothing will be drawn."; + + public const string perspectiveTooHighMessage = "A perspective too high will " + + "be clipped in the z-axis and therefore not renderable. Value must be " + + "between 0 and 0.0f1."; + + public const string clipToSizeAndRenderChildrenOutsideViewportConflict = + "Cannot renderChildrenOutsideViewport and clipToSize since children " + + "rendered outside will be clipped anyway."; + + public readonly IListWheelChildManager childManager; + + public ViewportOffset offset { + get { return this._offset; } + set { + D.assert(value != null); + if (value == this._offset) { + return; + } + + if (this.attached) { + this._offset.removeListener(this._hasScrolled); + } + + this._offset = value; + if (this.attached) { + this._offset.addListener(this._hasScrolled); + } + + this.markNeedsLayout(); + } + } + + ViewportOffset _offset; + + public float diameterRatio { + get { return this._diameterRatio; } + set { + D.assert( + value > 0, + () => diameterRatioZeroMessage + ); + + this._diameterRatio = value; + this.markNeedsPaint(); + } + } + + float _diameterRatio; + + public float perspective { + get { return this._perspective; } + set { + D.assert(value > 0); + D.assert( + value <= 0.01f, + () => perspectiveTooHighMessage + ); + if (value == this._perspective) { + return; + } + + this._perspective = value; + this.markNeedsPaint(); + } + } + + float _perspective; + + public float offAxisFraction { + get { return this._offAxisFraction; } + set { + if (value == this._offAxisFraction) { + return; + } + + this._offAxisFraction = value; + this.markNeedsPaint(); + } + } + + float _offAxisFraction = 0.0f; + + public bool useMagnifier { + get { return this._useMagnifier; } + set { + if (value == this._useMagnifier) { + return; + } + + this._useMagnifier = value; + this.markNeedsPaint(); + } + } + + bool _useMagnifier = false; + + public float magnification { + get { return this._magnification; } + set { + D.assert(value > 0); + if (value == this._magnification) { + return; + } + + this._magnification = value; + this.markNeedsPaint(); + } + } + + float _magnification = 1.0f; + + public float itemExtent { + get { return this._itemExtent; } + set { + D.assert(value > 0); + if (value == this._itemExtent) { + return; + } + + this._itemExtent = value; + this.markNeedsLayout(); + } + } + + float _itemExtent; + + public bool clipToSize { + get { return this._clipToSize; } + set { + D.assert( + !this.renderChildrenOutsideViewport || !this.clipToSize, + () => clipToSizeAndRenderChildrenOutsideViewportConflict + ); + if (value == this._clipToSize) { + return; + } + + this._clipToSize = value; + this.markNeedsPaint(); + } + } + + bool _clipToSize; + + public bool renderChildrenOutsideViewport { + get { return this._renderChildrenOutsideViewport; } + set { + D.assert( + !this.renderChildrenOutsideViewport || !this.clipToSize, + () => clipToSizeAndRenderChildrenOutsideViewportConflict + ); + if (value == this._renderChildrenOutsideViewport) { + return; + } + + this._renderChildrenOutsideViewport = value; + this.markNeedsLayout(); + } + } + + bool _renderChildrenOutsideViewport; + + + void _hasScrolled() { + this.markNeedsLayout(); + } + + public override void setupParentData(RenderObject child) { + if (!(child.parentData is ListWheelParentData)) { + child.parentData = new ListWheelParentData(); + } + } + + public override void attach(object owner) { + base.attach(owner); + this._offset.addListener(this._hasScrolled); + } + + public override void detach() { + this._offset.removeListener(this._hasScrolled); + base.detach(); + } + + public override bool isRepaintBoundary { + get { return true; } + } + + float _viewportExtent { + get { + D.assert(this.hasSize); + return this.size.height; + } + } + + float _minEstimatedScrollExtent { + get { + D.assert(this.hasSize); + if (this.childManager.childCount == null) { + return float.NegativeInfinity; + } + + return 0.0f; + } + } + + float _maxEstimatedScrollExtent { + get { + D.assert(this.hasSize); + if (this.childManager.childCount == null) { + return float.PositiveInfinity; + } + + return Mathf.Max(0.0f, ((this.childManager.childCount ?? 0) - 1) * this._itemExtent); + } + } + + float _topScrollMarginExtent { + get { + D.assert(this.hasSize); + return -this.size.height / 2.0f + this._itemExtent / 2.0f; + } + } + + float _getUntransformedPaintingCoordinateY(float layoutCoordinateY) { + return layoutCoordinateY - this._topScrollMarginExtent - this.offset.pixels; + } + + float _maxVisibleRadian { + get { + if (this._diameterRatio < 1.0f) { + return Mathf.PI / 2.0f; + } + + return Mathf.Asin(1.0f / this._diameterRatio); + } + } + + float _getIntrinsicCrossAxis(___ChildSizingFunction childSize) { + float extent = 0.0f; + RenderBox child = this.firstChild; + while (child != null) { + extent = Mathf.Max(extent, childSize(child)); + child = this.childAfter(child); + } + + return extent; + } + + protected override float computeMinIntrinsicWidth(float height) { + return this._getIntrinsicCrossAxis( + (RenderBox child) => child.getMinIntrinsicWidth(height) + ); + } + + protected override float computeMaxIntrinsicWidth(float height) { + return this._getIntrinsicCrossAxis( + (RenderBox child) => child.getMaxIntrinsicWidth(height) + ); + } + + protected override float computeMinIntrinsicHeight(float width) { + if (this.childManager.childCount == null) { + return 0.0f; + } + + return (this.childManager.childCount ?? 0) * this._itemExtent; + } + + protected internal override float computeMaxIntrinsicHeight(float width) { + if (this.childManager.childCount == null) { + return 0.0f; + } + + return (this.childManager.childCount ?? 0) * this._itemExtent; + } + + protected override bool sizedByParent { + get { return true; } + } + + protected override void performResize() { + this.size = this.constraints.biggest; + } + + public int indexOf(RenderBox child) { + D.assert(child != null); + ListWheelParentData childParentData = (ListWheelParentData) child.parentData; + return childParentData.index; + } + + public int scrollOffsetToIndex(float scrollOffset) { + return (scrollOffset / this.itemExtent).floor(); + } + + public float indexToScrollOffset(int index) { + return index * this.itemExtent; + } + + void _createChild(int index, + RenderBox after = null + ) { + this.invokeLayoutCallback((BoxConstraints constraints) => { + D.assert(this.constraints == this.constraints); + this.childManager.createChild(index, after: after); + }); + } + + void _destroyChild(RenderBox child) { + this.invokeLayoutCallback((BoxConstraints constraints) => { + D.assert(this.constraints == this.constraints); + this.childManager.removeChild(child); + }); + } + + void _layoutChild(RenderBox child, BoxConstraints constraints, int index) { + child.layout(constraints, parentUsesSize: true); + ListWheelParentData childParentData = (ListWheelParentData) child.parentData; + float crossPosition = this.size.width / 2.0f - child.size.width / 2.0f; + childParentData.offset = new Offset(crossPosition, this.indexToScrollOffset(index)); + } + + protected override void performLayout() { + BoxConstraints childConstraints = this.constraints.copyWith( + minHeight: this._itemExtent, + maxHeight: this._itemExtent, + minWidth: 0.0f + ); + + float visibleHeight = this.size.height; + if (this.renderChildrenOutsideViewport) { + visibleHeight *= 2; + } + + float firstVisibleOffset = this.offset.pixels + this._itemExtent / 2 - visibleHeight / 2; + float lastVisibleOffset = firstVisibleOffset + visibleHeight; + + int targetFirstIndex = this.scrollOffsetToIndex(firstVisibleOffset); + int targetLastIndex = this.scrollOffsetToIndex(lastVisibleOffset); + + if (targetLastIndex * this._itemExtent == lastVisibleOffset) { + targetLastIndex--; + } + + while (!this.childManager.childExistsAt(targetFirstIndex) && targetFirstIndex <= targetLastIndex) { + targetFirstIndex++; + } + + while (!this.childManager.childExistsAt(targetLastIndex) && targetFirstIndex <= targetLastIndex) { + targetLastIndex--; + } + + if (targetFirstIndex > targetLastIndex) { + while (this.firstChild != null) { + this._destroyChild(this.firstChild); + } + + return; + } + + + if (this.childCount > 0 && + (this.indexOf(this.firstChild) > targetLastIndex || this.indexOf(this.lastChild) < targetFirstIndex)) { + while (this.firstChild != null) { + this._destroyChild(this.firstChild); + } + } + + + if (this.childCount == 0) { + this._createChild(targetFirstIndex); + this._layoutChild(this.firstChild, childConstraints, targetFirstIndex); + } + + int currentFirstIndex = this.indexOf(this.firstChild); + int currentLastIndex = this.indexOf(this.lastChild); + + while (currentFirstIndex < targetFirstIndex) { + this._destroyChild(this.firstChild); + currentFirstIndex++; + } + + while (currentLastIndex > targetLastIndex) { + this._destroyChild(this.lastChild); + currentLastIndex--; + } + + RenderBox child = this.firstChild; + while (child != null) { + child.layout(childConstraints, parentUsesSize: true); + child = this.childAfter(child); + } + + while (currentFirstIndex > targetFirstIndex) { + this._createChild(currentFirstIndex - 1); + this._layoutChild(this.firstChild, childConstraints, --currentFirstIndex); + } + + while (currentLastIndex < targetLastIndex) { + this._createChild(currentLastIndex + 1, after: this.lastChild); + this._layoutChild(this.lastChild, childConstraints, ++currentLastIndex); + } + + this.offset.applyViewportDimension(this._viewportExtent); + + float minScrollExtent = this.childManager.childExistsAt(targetFirstIndex - 1) + ? this._minEstimatedScrollExtent + : this.indexToScrollOffset(targetFirstIndex); + float maxScrollExtent = this.childManager.childExistsAt(targetLastIndex + 1) + ? this._maxEstimatedScrollExtent + : this.indexToScrollOffset(targetLastIndex); + this.offset.applyContentDimensions(minScrollExtent, maxScrollExtent); + } + + bool _shouldClipAtCurrentOffset() { + float highestUntransformedPaintY = this._getUntransformedPaintingCoordinateY(0.0f); + return highestUntransformedPaintY < 0.0f + || this.size.height < highestUntransformedPaintY + this._maxEstimatedScrollExtent + this._itemExtent; + } + + public override void paint(PaintingContext context, Offset offset) { + if (this.childCount > 0) { + if (this._clipToSize && this._shouldClipAtCurrentOffset()) { + context.pushClipRect( + this.needsCompositing, + offset, + Offset.zero & this.size, this._paintVisibleChildren + ); + } + else { + this._paintVisibleChildren(context, offset); + } + } + } + + void _paintVisibleChildren(PaintingContext context, Offset offset) { + RenderBox childToPaint = this.firstChild; + ListWheelParentData childParentData = (ListWheelParentData) childToPaint?.parentData; + + while (childParentData != null) { + this._paintTransformedChild(childToPaint, context, offset, childParentData.offset); + childToPaint = this.childAfter(childToPaint); + childParentData = (ListWheelParentData) childToPaint?.parentData; + } + } + + void _paintTransformedChild(RenderBox child, PaintingContext context, Offset offset, Offset layoutOffset) { + Offset untransformedPaintingCoordinates = offset + new Offset( + layoutOffset.dx, + this._getUntransformedPaintingCoordinateY(layoutOffset.dy) + ); + + + float fractionalY = (untransformedPaintingCoordinates.dy + this._itemExtent / 2.0f) / this.size.height; + + float angle = -(fractionalY - 0.5f) * 2.0f * this._maxVisibleRadian; + if (angle > Mathf.PI / 2.0f || angle < -Mathf.PI / 2.0f) { + return; + } + + var radius = this.size.height * this._diameterRatio / 2.0f; + var deltaY = radius * Mathf.Sin(angle); + + Matrix3 transform = Matrix3.I(); + // Matrix4x4 transform2 = MatrixUtils.createCylindricalProjectionTransform( + // radius: this.size.height * this._diameterRatio / 2.0f, + // angle: angle, + // perspective: this._perspective + // ); + + // Offset offsetToCenter = new Offset(untransformedPaintingCoordinates.dx, -this._topScrollMarginExtent); + + Offset offsetToCenter = + new Offset(untransformedPaintingCoordinates.dx, -deltaY - this._topScrollMarginExtent); + + if (!this.useMagnifier) { + this._paintChildCylindrically(context, offset, child, transform, offsetToCenter); + } + else { + this._paintChildWithMagnifier( + context, + offset, + child, + transform, + offsetToCenter, + untransformedPaintingCoordinates + ); + } + } + + void _paintChildWithMagnifier( + PaintingContext context, + Offset offset, + RenderBox child, + // Matrix4x4 cylindricalTransform, + Matrix3 cylindricalTransform, + Offset offsetToCenter, + Offset untransformedPaintingCoordinates + ) { + float magnifierTopLinePosition = this.size.height / 2 - this._itemExtent * this._magnification / 2; + float magnifierBottomLinePosition = this.size.height / 2 + this._itemExtent * this._magnification / 2; + + bool isAfterMagnifierTopLine = untransformedPaintingCoordinates.dy + >= magnifierTopLinePosition - this._itemExtent * this._magnification; + bool isBeforeMagnifierBottomLine = untransformedPaintingCoordinates.dy + <= magnifierBottomLinePosition; + + if (isAfterMagnifierTopLine && isBeforeMagnifierBottomLine) { + Rect centerRect = Rect.fromLTWH( + 0.0f, + magnifierTopLinePosition, this.size.width, this._itemExtent * this._magnification); + Rect topHalfRect = Rect.fromLTWH( + 0.0f, + 0.0f, this.size.width, + magnifierTopLinePosition); + Rect bottomHalfRect = Rect.fromLTWH( + 0.0f, + magnifierBottomLinePosition, this.size.width, + magnifierTopLinePosition); + + context.pushClipRect( + false, + offset, + centerRect, + (PaintingContext context1, Offset offset1) => { + context1.pushTransform( + false, + offset1, + cylindricalTransform, + // this._centerOriginTransform(cylindricalTransform), + (PaintingContext context2, Offset offset2) => { + context2.paintChild( + child, + offset2 + untransformedPaintingCoordinates); + }); + }); + + context.pushClipRect( + false, + offset, + untransformedPaintingCoordinates.dy <= magnifierTopLinePosition + ? topHalfRect + : bottomHalfRect, + (PaintingContext context1, Offset offset1) => { + this._paintChildCylindrically( + context1, + offset1, + child, + cylindricalTransform, + offsetToCenter + ); + } + ); + } + else { + this._paintChildCylindrically( + context, + offset, + child, + cylindricalTransform, + offsetToCenter + ); + } + } + + void _paintChildCylindrically( + PaintingContext context, + Offset offset, + RenderBox child, + // Matrix4x4 cylindricalTransform, + Matrix3 cylindricalTransform, + Offset offsetToCenter + ) { + context.pushTransform( + false, + offset, + cylindricalTransform, + // this._centerOriginTransform(cylindricalTransform), + (PaintingContext _context, Offset _offset) => { _context.paintChild(child, _offset + offsetToCenter); } + ); + } + + public override Rect describeApproximatePaintClip(RenderObject child) { + if (child != null && this._shouldClipAtCurrentOffset()) { + return Offset.zero & this.size; + } + + return null; + } + + protected override bool hitTestChildren(HitTestResult result, Offset position = null + ) { + return false; + } + + public RevealedOffset getOffsetToReveal(RenderObject target, float alignment, + Rect rect = null + ) { + rect = rect ?? target.paintBounds; + + RenderObject child = target; + while (child.parent != this) { + child = (RenderObject) child.parent; + } + + ListWheelParentData parentData = (ListWheelParentData) child.parentData; + float targetOffset = parentData.offset.dy; + Matrix4x4 transform = target.getTransformTo(this).toMatrix4x4(); + Rect bounds = MatrixUtils.transformRect(transform, rect); + Rect targetRect = bounds.translate(0.0f, (this.size.height - this.itemExtent) / 2); + + return new RevealedOffset(offset: targetOffset, rect: targetRect); + } + + public new RenderObject parent { + get { return (RenderObject) base.parent; } + } + + public new void showOnScreen( + RenderObject descendant = null, + Rect rect = null, + TimeSpan? duration = null, + Curve curve = null + ) { + duration = duration ?? TimeSpan.Zero; + curve = curve ?? Curves.ease; + if (descendant != null) { + RevealedOffset revealedOffset = this.getOffsetToReveal(descendant, 0.5f, rect: rect); + if (duration == TimeSpan.Zero) { + this.offset.jumpTo(revealedOffset.offset); + } + else { + this.offset.animateTo(revealedOffset.offset, duration: (TimeSpan) duration, curve: curve); + } + + rect = revealedOffset.rect; + } + + base.showOnScreen( + rect: rect, + duration: duration, + curve: curve + ); + } + } +} \ No newline at end of file diff --git a/Runtime/rendering/list_wheel_viewport.cs.meta b/Runtime/rendering/list_wheel_viewport.cs.meta new file mode 100644 index 00000000..54ae00bb --- /dev/null +++ b/Runtime/rendering/list_wheel_viewport.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 19267e4bc9a214b5eacd791e58a63f11 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/rendering/object.cs b/Runtime/rendering/object.cs index eabccd6e..68399c1f 100644 --- a/Runtime/rendering/object.cs +++ b/Runtime/rendering/object.cs @@ -7,6 +7,7 @@ using Unity.UIWidgets.ui; using UnityEngine; using Canvas = Unity.UIWidgets.ui.Canvas; +using Color = Unity.UIWidgets.ui.Color; using Rect = Unity.UIWidgets.ui.Rect; namespace Unity.UIWidgets.rendering { @@ -196,7 +197,7 @@ protected virtual void stopRecordingIfNeeded() { Paint paint = new Paint { style = PaintingStyle.stroke, strokeWidth = 1.0f, - color = new ui.Color(0xFFFF9800), + color = new Color(0xFFFF9800), }; this.canvas.drawRect(this.estimatedBounds, paint); } @@ -288,7 +289,8 @@ public void pushTransform(bool needsCompositing, Offset offset, Matrix3 transfor Matrix3 effectiveTransform; if (offset == null || offset == Offset.zero) { effectiveTransform = transform; - } else { + } + else { effectiveTransform = Matrix3.makeTrans(offset.dx, offset.dy); effectiveTransform.preConcat(transform); effectiveTransform.preTranslate(-offset.dx, -offset.dy); @@ -297,7 +299,7 @@ public void pushTransform(bool needsCompositing, Offset offset, Matrix3 transfor if (needsCompositing) { var inverse = Matrix3.I(); var invertible = effectiveTransform.invert(inverse); - + // it could just be "scale == 0", ignore the assertion. // D.assert(invertible); @@ -1377,6 +1379,7 @@ public override string toStringShallow( } public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { + base.debugFillProperties(properties); properties.add(new DiagnosticsProperty( "creator", this.debugCreator, defaultValue: Diagnostics.kNullDefaultValue, level: DiagnosticLevel.debug)); diff --git a/Runtime/rendering/paragraph.cs b/Runtime/rendering/paragraph.cs index fe937f44..baca4fa5 100644 --- a/Runtime/rendering/paragraph.cs +++ b/Runtime/rendering/paragraph.cs @@ -20,6 +20,9 @@ public enum TextOverflow { /// Use an ellipsis to indicate that the text has overflowed. ellipsis, + + /// Render overflowing text outside of its container. + visible, } @@ -30,7 +33,7 @@ public class RenderParagraph : RenderBox { TextOverflow _overflow; readonly TextPainter _textPainter; - bool _hasVisualOverflow = false; + bool _needsClipping = false; List _selectionRects; @@ -41,6 +44,7 @@ public RenderParagraph(TextSpan text, TextOverflow overflow = TextOverflow.clip, float textScaleFactor = 1.0f, int? maxLines = null, + StrutStyle strutStyle = null, Action onSelectionChanged = null, Color selectionColor = null ) { @@ -53,7 +57,8 @@ public RenderParagraph(TextSpan text, textDirection, textScaleFactor, maxLines, - overflow == TextOverflow.ellipsis ? _kEllipsis : "" + overflow == TextOverflow.ellipsis ? _kEllipsis : "", + strutStyle: strutStyle ); this._selection = null; @@ -209,7 +214,7 @@ protected override float computeMinIntrinsicHeight(float width) { return this._computeIntrinsicHeight(width); } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { return this._computeIntrinsicHeight(width); } @@ -405,11 +410,27 @@ public override void handleEvent(PointerEvent evt, HitTestEntry entry) { protected override void performLayout() { this._layoutTextWithConstraints(this.constraints); var textSize = this._textPainter.size; - var didOverflowHeight = this._textPainter.didExceedMaxLines; + var textDidExceedMaxLines = this._textPainter.didExceedMaxLines; this.size = this.constraints.constrain(textSize); + var didOverflowHeight = this.size.height < textSize.height || textDidExceedMaxLines; var didOverflowWidth = this.size.width < textSize.width; - this._hasVisualOverflow = didOverflowWidth || didOverflowHeight; + var hasVisualOverflow = didOverflowWidth || didOverflowHeight; + if (hasVisualOverflow) { + switch (this._overflow) { + case TextOverflow.visible: + this._needsClipping = false; + break; + case TextOverflow.clip: + case TextOverflow.ellipsis: + case TextOverflow.fade: + this._needsClipping = true; + break; + } + } + else { + this._needsClipping = false; + } this._selectionRects = null; } @@ -419,7 +440,7 @@ void paintParagraph(PaintingContext context, Offset offset) { this._layoutTextWithConstraints(this.constraints); var canvas = context.canvas; - if (this._hasVisualOverflow) { + if (this._needsClipping) { var bounds = offset & this.size; canvas.save(); canvas.clipRect(bounds); @@ -434,7 +455,7 @@ void paintParagraph(PaintingContext context, Offset offset) { } this._textPainter.paint(canvas, offset); - if (this._hasVisualOverflow) { + if (this._needsClipping) { canvas.restore(); } } @@ -465,6 +486,18 @@ void _paintSelection(Canvas canvas, Offset effectiveOffset) { canvas.drawPath(barPath, paint); } + public StrutStyle strutStyle { + get { return this._textPainter.strutStyle; } + set { + if (this._textPainter.strutStyle == value) { + return; + } + + this._textPainter.strutStyle = value; + this.markNeedsLayout(); + } + } + void _layoutText(float minWidth = 0.0f, float maxWidth = float.PositiveInfinity) { var widthMatters = this.softWrap || this.overflow == TextOverflow.ellipsis; this._textPainter.layout(minWidth, widthMatters ? maxWidth : float.PositiveInfinity); diff --git a/Runtime/rendering/performance_overlay.cs b/Runtime/rendering/performance_overlay.cs index f9dca3e8..ba743f10 100644 --- a/Runtime/rendering/performance_overlay.cs +++ b/Runtime/rendering/performance_overlay.cs @@ -62,7 +62,7 @@ protected override float computeMinIntrinsicHeight(float width) { return this._intrinsicHeight; } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { return this._intrinsicHeight; } diff --git a/Runtime/rendering/proxy_box.cs b/Runtime/rendering/proxy_box.cs index 5f2d16e4..4eac4bd1 100644 --- a/Runtime/rendering/proxy_box.cs +++ b/Runtime/rendering/proxy_box.cs @@ -125,7 +125,7 @@ protected override float computeMinIntrinsicHeight(float width) { return height; } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { if (this._additionalConstraints.hasBoundedHeight && this._additionalConstraints.hasTightHeight) { return this._additionalConstraints.minHeight; } @@ -300,7 +300,7 @@ protected override float computeMinIntrinsicHeight(float width) { return 0.0f; } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { if (width.isFinite()) { return width / this._aspectRatio; } @@ -435,7 +435,7 @@ protected override float computeMinIntrinsicHeight(float width) { return _applyStep(height, this._stepHeight); } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { if (this.child == null) { return 0.0f; } @@ -1169,12 +1169,8 @@ public Color color { Color _color; - protected static Paint _transparentPaint { - get { return new Paint {color = new Color(0x00000000)}; } - } - protected override bool alwaysNeedsCompositing { - get { return this._elevation != 0.0; } + get { return true; } } public override void debugFillProperties(DiagnosticPropertiesBuilder description) { @@ -1266,36 +1262,17 @@ public override void paint(PaintingContext context, Offset offset) { Path offsetRRectAsPath = new Path(); offsetRRectAsPath.addRRect(offsetRRect); - if (this.needsCompositing) { - PhysicalModelLayer physicalModel = new PhysicalModelLayer( - clipPath: offsetRRectAsPath, - clipBehavior: this.clipBehavior, - elevation: this.elevation, - color: this.color, - shadowColor: this.shadowColor); - context.pushLayer(physicalModel, base.paint, offset, childPaintBounds: offsetBounds); - } - else { - Canvas canvas = context.canvas; - if (this.elevation != 0.0) { - canvas.drawRect( - offsetBounds.inflate(20.0f), - _transparentPaint - ); - canvas.drawShadow( - offsetRRectAsPath, - this.shadowColor, - this.elevation, - this.color.alpha != 0xFF - ); - } - - Paint paint = new Paint {color = this.color}; - canvas.drawRRect(offsetRRect, paint); - context.clipRRectAndPaint(offsetRRect, this.clipBehavior, offsetBounds, - () => base.paint(context, offset)); - D.assert(context.canvas == canvas, () => "canvas changed even though needsCompositing was false"); - } + PhysicalModelLayer physicalModel = new PhysicalModelLayer( + clipPath: offsetRRectAsPath, + clipBehavior: this.clipBehavior, + elevation: this.elevation, + color: this.color, + shadowColor: this.shadowColor); + D.assert(() => { + physicalModel.debugCreator = this.debugCreator; + return true; + }); + context.pushLayer(physicalModel, base.paint, offset, childPaintBounds: offsetBounds); } } @@ -1353,37 +1330,13 @@ public override void paint(PaintingContext context, Offset offset) { Path offsetPath = new Path(); offsetPath.addPath(this._clip, offset); - if (this.needsCompositing) { - PhysicalModelLayer physicalModel = new PhysicalModelLayer( - clipPath: offsetPath, - clipBehavior: this.clipBehavior, - elevation: this.elevation, - color: this.color, - shadowColor: this.shadowColor); - context.pushLayer(physicalModel, base.paint, offset, childPaintBounds: offsetBounds); - } - else { - Canvas canvas = context.canvas; - if (this.elevation != 0.0) { - canvas.drawRect( - offsetBounds.inflate(20.0f), - _transparentPaint - ); - - canvas.drawShadow( - offsetPath, - this.shadowColor, - this.elevation, - this.color.alpha != 0xFF - ); - } - - Paint paint = new Paint {color = this.color, style = PaintingStyle.fill}; - canvas.drawPath(offsetPath, paint); - context.clipPathAndPaint(offsetPath, this.clipBehavior, - offsetBounds, () => base.paint(context, offset)); - D.assert(context.canvas == canvas, () => "canvas changed even though needsCompositing was false"); - } + PhysicalModelLayer physicalModel = new PhysicalModelLayer( + clipPath: offsetPath, + clipBehavior: this.clipBehavior, + elevation: this.elevation, + color: this.color, + shadowColor: this.shadowColor); + context.pushLayer(physicalModel, base.paint, offset, childPaintBounds: offsetBounds); } } @@ -1926,6 +1879,8 @@ public override void debugFillProperties(DiagnosticPropertiesBuilder properties) public delegate void PointerCancelEventListener(PointerCancelEvent evt); + public delegate void PointerSignalEventListener(PointerSignalEvent evt); + public delegate void PointerScrollEventListener(PointerScrollEvent evt); public class RenderPointerListener : RenderProxyBoxWithHitTestBehavior { @@ -1937,6 +1892,7 @@ public RenderPointerListener( PointerExitEventListener onPointerExit = null, PointerUpEventListener onPointerUp = null, PointerCancelEventListener onPointerCancel = null, + PointerSignalEventListener onPointerSignal = null, PointerScrollEventListener onPointerScroll = null, PointerDragFromEditorEnterEventListener onPointerDragFromEditorEnter = null, PointerDragFromEditorHoverEventListener onPointerDragFromEditorHover = null, @@ -1949,6 +1905,7 @@ public RenderPointerListener( this.onPointerMove = onPointerMove; this.onPointerUp = onPointerUp; this.onPointerCancel = onPointerCancel; + this.onPointerSignal = onPointerSignal; this.onPointerScroll = onPointerScroll; this._onPointerEnter = onPointerEnter; @@ -2072,10 +2029,16 @@ public PointerExitEventListener onPointerExit { public PointerCancelEventListener onPointerCancel; + public PointerSignalEventListener onPointerSignal; + public PointerScrollEventListener onPointerScroll; MouseTrackerAnnotation _hoverAnnotation; + public MouseTrackerAnnotation hoverAnnotation { + get { return this._hoverAnnotation; } + } + void _updateAnnotations() { D.assert(this._onPointerEnter != this._hoverAnnotation.onEnter || this._onPointerHover != this._hoverAnnotation.onHover || @@ -2178,6 +2141,11 @@ public override void handleEvent(PointerEvent evt, HitTestEntry entry) { return; } + if (this.onPointerSignal != null && evt is PointerSignalEvent) { + this.onPointerSignal((PointerSignalEvent) evt); + return; + } + if (this.onPointerScroll != null && evt is PointerScrollEvent) { this.onPointerScroll((PointerScrollEvent) evt); } @@ -2214,6 +2182,10 @@ public override void debugFillProperties(DiagnosticPropertiesBuilder properties) listeners.Add("cancel"); } + if (this.onPointerSignal != null) { + listeners.Add("signal"); + } + if (listeners.isEmpty()) { listeners.Add(""); } @@ -2392,7 +2364,7 @@ protected override float computeMinIntrinsicHeight(float width) { return base.computeMinIntrinsicHeight(width); } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { if (this.offstage) { return 0.0f; } diff --git a/Runtime/rendering/proxy_box.mixin.gen.cs b/Runtime/rendering/proxy_box.mixin.gen.cs index 07b42182..372e0485 100644 --- a/Runtime/rendering/proxy_box.mixin.gen.cs +++ b/Runtime/rendering/proxy_box.mixin.gen.cs @@ -37,7 +37,7 @@ protected override float computeMinIntrinsicHeight(float width) { return 0.0f; } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { if (this.child != null) { return this.child.getMaxIntrinsicHeight(width); } diff --git a/Runtime/rendering/rotated_box.cs b/Runtime/rendering/rotated_box.cs index d479cfde..362366ab 100644 --- a/Runtime/rendering/rotated_box.cs +++ b/Runtime/rendering/rotated_box.cs @@ -64,7 +64,7 @@ protected override float computeMinIntrinsicHeight(float width) { return this._isVertical ? this.child.getMinIntrinsicWidth(width) : this.child.getMinIntrinsicHeight(width); } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { if (this.child == null) { return 0.0f; } diff --git a/Runtime/rendering/shifted_box.cs b/Runtime/rendering/shifted_box.cs index 5a867bd0..359da663 100644 --- a/Runtime/rendering/shifted_box.cs +++ b/Runtime/rendering/shifted_box.cs @@ -36,7 +36,7 @@ protected override float computeMinIntrinsicHeight(float width) { return 0.0f; } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { if (this.child != null) { return this.child.getMaxIntrinsicHeight(width); } @@ -135,7 +135,7 @@ protected override float computeMinIntrinsicHeight(float width) { return this._padding.vertical; } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { if (this.child != null) { return this.child.getMaxIntrinsicHeight(Mathf.Max(0.0f, width - this._padding.horizontal)) + this._padding.vertical; @@ -566,7 +566,7 @@ protected override float computeMinIntrinsicHeight(float width) { return this._requestedSize.height; } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { return this._requestedSize.height; } @@ -601,7 +601,7 @@ public RenderFractionallySizedOverflowBox( public float? widthFactor { get { return this._widthFactor; } set { - if (this._widthFactor != value) { + if (this._widthFactor == value) { return; } @@ -615,7 +615,7 @@ public float? widthFactor { public float? heightFactor { get { return this._heightFactor; } set { - if (this._heightFactor != value) { + if (this._heightFactor == value) { return; } @@ -687,7 +687,7 @@ protected override float computeMinIntrinsicHeight(float width) { return result / (this._heightFactor ?? 1.0f); } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { float result; if (this.child == null) { result = base.computeMaxIntrinsicHeight(width); @@ -807,7 +807,7 @@ protected override float computeMinIntrinsicHeight(float width) { return 0.0f; } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { float height = this._getSize(BoxConstraints.tightForFinite(width: width)).height; if (height.isFinite()) { return height; @@ -842,7 +842,7 @@ public RenderBaseline( public float baseline { get { return this._baseline; } set { - if (this._baseline != value) { + if (this._baseline == value) { return; } @@ -857,7 +857,7 @@ public float baseline { public TextBaseline baselineType { get { return this._baselineType; } set { - if (this._baselineType != value) { + if (this._baselineType == value) { return; } diff --git a/Runtime/rendering/sliver.cs b/Runtime/rendering/sliver.cs index 9f295441..a5459583 100644 --- a/Runtime/rendering/sliver.cs +++ b/Runtime/rendering/sliver.cs @@ -341,6 +341,7 @@ public SliverGeometry( public readonly bool hasVisualOverflow; public readonly float? scrollOffsetCorrection; public readonly float cacheExtent; + public const float precisionErrorTolerance = 1e-10f; internal static string _debugCompareFloats(string labelA, float valueA, string labelB, float valueB) { if (valueA.ToString("F1") != valueB.ToString("F1")) { @@ -381,7 +382,7 @@ public bool debugAssertIsValid(InformationCollector informationCollector = null) ); } - if (this.maxPaintExtent < this.paintExtent) { + if (this.paintExtent - this.maxPaintExtent > precisionErrorTolerance) { verify(false, "The \"maxPaintExtent\" is less than the \"paintExtent\".\n" + _debugCompareFloats("maxPaintExtent", this.maxPaintExtent, "paintExtent", diff --git a/Runtime/rendering/sliver_fill.cs b/Runtime/rendering/sliver_fill.cs index bacf8abc..3562377b 100644 --- a/Runtime/rendering/sliver_fill.cs +++ b/Runtime/rendering/sliver_fill.cs @@ -81,7 +81,6 @@ protected override void performLayout() { } float paintedChildSize = this.calculatePaintOffset(this.constraints, from: 0.0f, to: extent); - Debug.Log("size" + paintedChildSize); D.assert(paintedChildSize.isFinite()); D.assert(paintedChildSize >= 0.0); this.geometry = new SliverGeometry( diff --git a/Runtime/rendering/sliver_grid.cs b/Runtime/rendering/sliver_grid.cs index 8ba7d98d..6722415c 100644 --- a/Runtime/rendering/sliver_grid.cs +++ b/Runtime/rendering/sliver_grid.cs @@ -113,7 +113,8 @@ public override int getMaxChildIndexForScrollOffset(float scrollOffset) { float _getOffsetFromStartInCrossAxis(float crossAxisStart) { if (this.reverseCrossAxis == true) { - return (this.crossAxisCount * this.crossAxisStride - crossAxisStart - this.childCrossAxisExtent) ?? + return (this.crossAxisCount * this.crossAxisStride - crossAxisStart - this.childCrossAxisExtent + - (this.crossAxisStride - this.childCrossAxisExtent)) ?? 0.0f; } diff --git a/Runtime/rendering/sliver_list.cs b/Runtime/rendering/sliver_list.cs index 267c677c..4fd7c827 100644 --- a/Runtime/rendering/sliver_list.cs +++ b/Runtime/rendering/sliver_list.cs @@ -57,7 +57,7 @@ protected override void performLayout() { } else { float firstChildScrollOffset = earliestScrollOffset - this.paintExtentOf(this.firstChild); - if (firstChildScrollOffset < 0.0) { + if (firstChildScrollOffset < -SliverGeometry.precisionErrorTolerance) { float correction = 0.0f; while (earliestUsefulChild != null) { D.assert(this.firstChild == earliestUsefulChild); diff --git a/Runtime/rendering/sliver_multi_box_adaptor.cs b/Runtime/rendering/sliver_multi_box_adaptor.cs index 33bf1d13..1d4f8a65 100644 --- a/Runtime/rendering/sliver_multi_box_adaptor.cs +++ b/Runtime/rendering/sliver_multi_box_adaptor.cs @@ -36,8 +36,12 @@ public class SliverMultiBoxAdaptorParentData : ContainerParentDataMixinSliverLog public bool keepAlive = false; - internal bool _keptAlive = false; + public bool keptAlive { + get { return this._keptAlive; } + } + internal bool _keptAlive = false; + public override string ToString() { return $"index={this.index}; {(this.keepAlive ? "keeyAlive; " : "")}{base.ToString()}"; } @@ -80,6 +84,7 @@ bool _debugAssertChildListLocked() { } public override void insert(RenderBox child, RenderBox after = null) { + D.assert(!this._keepAliveBucket.ContainsValue(value: child)); base.insert(child, after: after); D.assert(this.firstChild != null); D.assert(() => { diff --git a/Runtime/rendering/stack.cs b/Runtime/rendering/stack.cs index 6494b6c8..e78be2e5 100644 --- a/Runtime/rendering/stack.cs +++ b/Runtime/rendering/stack.cs @@ -300,7 +300,7 @@ protected override float computeMinIntrinsicHeight(float width) { return this._getIntrinsicDimension((RenderBox child) => child.getMinIntrinsicHeight(width)); } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { return this._getIntrinsicDimension((RenderBox child) => child.getMaxIntrinsicHeight(width)); } diff --git a/Runtime/rendering/table.cs b/Runtime/rendering/table.cs index 99f75bd8..c0774716 100644 --- a/Runtime/rendering/table.cs +++ b/Runtime/rendering/table.cs @@ -708,7 +708,7 @@ protected override float computeMinIntrinsicHeight(float width) { return rowTop; } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { return this.computeMinIntrinsicHeight(width); } @@ -841,12 +841,17 @@ List _computeColumnWidths(BoxConstraints constraints) { float deficit = tableWidth - maxWidthConstraint; int availableColumns = this.columns; - float minimumDeficit = 0.00000001f; - while (deficit > 0.0f && totalFlex > minimumDeficit) { + + //(Xingwei Zhu) this deficit is double and set to be 0.00000001f in flutter. + //since we use float by default, making it larger should make sense in most cases + float minimumDeficit = 0.0001f; + while (deficit > minimumDeficit && totalFlex > minimumDeficit) { float newTotalFlex = 0.0f; for (int x = 0; x < this.columns; x++) { if (flexes[x] != null) { - float newWidth = widths[x] - deficit * flexes[x].Value / totalFlex; + //(Xingwei Zhu) in case deficit * flexes[x].Value / totalFlex => 0 if deficit is really small, leading to dead loop, + //we amend it with a default larger value to ensure that this loop will eventually end + float newWidth = widths[x] - Mathf.Max(minimumDeficit, deficit * flexes[x].Value / totalFlex); D.assert(newWidth.isFinite()); if (newWidth <= minWidths[x]) { deficit -= widths[x] - minWidths[x]; diff --git a/Runtime/rendering/viewport.cs b/Runtime/rendering/viewport.cs index 357b6b4e..ff8298d9 100644 --- a/Runtime/rendering/viewport.cs +++ b/Runtime/rendering/viewport.cs @@ -185,7 +185,7 @@ protected override float computeMinIntrinsicHeight(float width) { return 0.0f; } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { D.assert(this.debugThrowIfNotCheckingIntrinsics()); return 0.0f; } diff --git a/Runtime/rendering/wrap.cs b/Runtime/rendering/wrap.cs index 55a729b1..bc943154 100644 --- a/Runtime/rendering/wrap.cs +++ b/Runtime/rendering/wrap.cs @@ -362,7 +362,7 @@ protected override float computeMinIntrinsicHeight(float width) { throw new Exception("Unknown axis: " + this.direction); } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { switch (this.direction) { case Axis.horizontal: return this._computeIntrinsicHeightForWidth(width); diff --git a/Runtime/service/keyboard.cs b/Runtime/service/keyboard.cs index 98408a27..09414190 100644 --- a/Runtime/service/keyboard.cs +++ b/Runtime/service/keyboard.cs @@ -7,7 +7,34 @@ using Unity.UIWidgets.ui; using UnityEngine; +#if UNITY_EDITOR +using UnityEditor; +#endif + namespace Unity.UIWidgets.service { + + public delegate RawInputKeyResponse GlobalKeyEventHandlerDelegate(RawKeyEvent rawEvt, bool enableCustomAction = false); + + public class RawInputKeyResponse { + public readonly bool swallow; + public readonly char input; + public readonly TextInputAction? inputAction; + + public RawInputKeyResponse(bool swallow, char input = '\0', TextInputAction? inputAction = null) { + this.swallow = swallow; + this.input = input; + this.inputAction = inputAction; + } + + public static RawInputKeyResponse convert(RawKeyEvent evt) { + return new RawInputKeyResponse( + false, + evt.data.unityEvent.character, + null); + } + + public static readonly RawInputKeyResponse swallowResponse = new RawInputKeyResponse(true, '\0', null); + } interface KeyboardDelegate: IDisposable { void show(); @@ -45,16 +72,26 @@ public void hide() { public void setEditingState(TextEditingValue value) { this._value = value; } + + Offset _editorWindowPosToScreenPos(Offset position) { +#if UNITY_EDITOR_WIN + return position * EditorGUIUtility.pixelsPerPoint; +#elif UNITY_EDITOR_OSX + //locate the IME 30 logical pixels lower than the caret + var offsetY = 30f; + return new Offset(position.dx, position.dy + offsetY); +#else + return position; +#endif + } public void setIMEPos(Offset imeGlobalPos) { var uiWidgetWindowAdapter = Window.instance as UIWidgetWindowAdapter; - if (uiWidgetWindowAdapter != null) { - var screenPos = uiWidgetWindowAdapter.windowPosToScreenPos(imeGlobalPos); - Input.compositionCursorPos = new Vector2(screenPos.dx, screenPos.dy); - } - else { // editor window case - Input.compositionCursorPos = new Vector2(imeGlobalPos.dx, imeGlobalPos.dy); - } + Offset screenPos = uiWidgetWindowAdapter != null + ? uiWidgetWindowAdapter.windowPosToScreenPos(imeGlobalPos) + : this._editorWindowPosToScreenPos(imeGlobalPos); + + Input.compositionCursorPos = new Vector2(screenPos.dx, screenPos.dy); } public void setClient(int client, TextInputConfiguration configuration) { @@ -69,6 +106,8 @@ public bool imeRequired() { return true; } + bool isIMEInput = false; + public void OnGUI() { if (TouchScreenKeyboard.isSupported) { return; @@ -81,9 +120,20 @@ public void OnGUI() { var currentEvent = Event.current; var oldValue = this._value; - + if (currentEvent != null && currentEvent.type == EventType.KeyDown) { - if (currentEvent.keyCode == KeyCode.Backspace) { + var response = TextInput._handleGlobalInputKey(this._client, + new RawKeyDownEvent(new RawKeyEventData(currentEvent))); + + if (response.swallow) { + if (response.inputAction != null) { + Window.instance.run(() => { TextInput._performAction(this._client, response.inputAction.Value); }); + } + + if (_validateCharacter(response.input)) { + this._value = this._value.insert(new string(response.input, 1)); + } + } else if (currentEvent.keyCode == KeyCode.Backspace) { if (this._value.selection.isValid) { this._value = this._value.deleteSelection(true); } @@ -101,7 +151,9 @@ public void OnGUI() { if (_validateCharacter(ch)) { this._value = this._value.insert(new string(ch, 1)); } - } else if (!string.IsNullOrEmpty(Input.compositionString)) { + } + else if (!string.IsNullOrEmpty(Input.compositionString)) { + this.isIMEInput = true; this._value = this._value.compose(Input.compositionString); } @@ -109,7 +161,14 @@ public void OnGUI() { } if (this._value != oldValue) { - Window.instance.run(() => { TextInput._updateEditingState(this._client, this._value); }); + if (this.isIMEInput) { + var isIMEInput = this.isIMEInput; + Window.instance.run(() => { TextInput._updateEditingState(this._client, this._value, isIMEInput); }); + this.isIMEInput = false; + } + else { + Window.instance.run(() => { TextInput._updateEditingState(this._client, this._value); }); + } } } diff --git a/Runtime/service/text_formatter.cs b/Runtime/service/text_formatter.cs index b63b110d..90ca8d7d 100644 --- a/Runtime/service/text_formatter.cs +++ b/Runtime/service/text_formatter.cs @@ -60,6 +60,10 @@ public LengthLimitingTextInputFormatter(int? maxLength) { public override TextEditingValue formatEditUpdate(TextEditingValue oldValue, TextEditingValue newValue) { if (this.maxLength != null && this.maxLength > 0 && newValue.text.Length > this.maxLength) { + if (Input.compositionString.Length > 0) { + return newValue; + } + TextSelection newSelection = newValue.selection.copyWith( baseOffset: Mathf.Min(newValue.selection.start, this.maxLength.Value), extentOffset: Mathf.Min(newValue.selection.end, this.maxLength.Value) @@ -72,9 +76,36 @@ public override TextEditingValue formatEditUpdate(TextEditingValue oldValue, Tex composing: TextRange.empty ); } + return newValue; } -} + } + + public class WhitelistingTextInputFormatter : TextInputFormatter { + public WhitelistingTextInputFormatter(Regex whitelistedPattern) { + D.assert(whitelistedPattern != null); + this.whitelistedPattern = whitelistedPattern; + } + + readonly Regex whitelistedPattern; + + public override TextEditingValue formatEditUpdate(TextEditingValue oldValue, TextEditingValue newValue) { + return Util._selectionAwareTextManipulation( + value: newValue, + substringManipulation: substring => { + string groups = ""; + foreach (Match match in this.whitelistedPattern.Matches(input: substring)) { + groups += match.Groups[0].Value; + } + + return groups; + } + ); + } + + public static readonly WhitelistingTextInputFormatter digitsOnly + = new WhitelistingTextInputFormatter(new Regex(@"\d+")); + } static class Util { internal static TextEditingValue _selectionAwareTextManipulation(TextEditingValue value, diff --git a/Runtime/service/text_input.cs b/Runtime/service/text_input.cs index d0e7510c..3f4ab70b 100644 --- a/Runtime/service/text_input.cs +++ b/Runtime/service/text_input.cs @@ -345,6 +345,9 @@ public TextEditingValue compose(string composeText) { D.assert(!string.IsNullOrEmpty(composeText)); var composeStart = this.composing == TextRange.empty ? this.selection.start : this.composing.start; var lastComposeEnd = this.composing == TextRange.empty ? this.selection.end : this.composing.end; + + composeStart = Mathf.Clamp(composeStart, 0, this.text.Length); + lastComposeEnd = Mathf.Clamp(lastComposeEnd, 0, this.text.Length); var newText = this.text.Substring(0, composeStart) + composeText + this.text.Substring(lastComposeEnd); var componseEnd = composeStart + composeText.Length; return new TextEditingValue( @@ -439,11 +442,13 @@ public interface TextSelectionDelegate { } public interface TextInputClient { - void updateEditingValue(TextEditingValue value); + void updateEditingValue(TextEditingValue value, bool isIMEInput); void performAction(TextInputAction action); void updateFloatingCursor(RawFloatingCursorPoint point); + + RawInputKeyResponse globalInputKeyHandler(RawKeyEvent evt); } public enum TextInputAction { @@ -608,7 +613,7 @@ internal static void OnGUI() { } } - internal static void _updateEditingState(int client, TextEditingValue value) { + internal static void _updateEditingState(int client, TextEditingValue value, bool isIMEInput = false) { if (_currentConnection == null) { return; } @@ -617,7 +622,7 @@ internal static void _updateEditingState(int client, TextEditingValue value) { return; } - _currentConnection._client.updateEditingValue(value); + _currentConnection._client.updateEditingValue(value, isIMEInput); } internal static void _performAction(int client, TextInputAction action) { @@ -632,6 +637,18 @@ internal static void _performAction(int client, TextInputAction action) { _currentConnection._client.performAction(action); } + internal static RawInputKeyResponse _handleGlobalInputKey(int client, RawKeyEvent evt) { + if (_currentConnection == null) { + return RawInputKeyResponse.convert(evt); + } + + if (client != _currentConnection._id) { + return RawInputKeyResponse.convert(evt); + } + + return _currentConnection._client.globalInputKeyHandler(evt); + } + static bool _hidePending = false; static internal void _scheduleHide() { diff --git a/Runtime/ui/geometry.cs b/Runtime/ui/geometry.cs index b8b2574d..a6230747 100644 --- a/Runtime/ui/geometry.cs +++ b/Runtime/ui/geometry.cs @@ -541,6 +541,14 @@ public Size size { get { return new Size(this.width, this.height); } } + public float area { + get { return this.width * this.height; } + } + + public float margin { + get { return this.width + this.height; } + } + public static readonly Rect zero = new Rect(0, 0, 0, 0); public static readonly Rect one = new Rect(0, 0, 1, 1); @@ -716,7 +724,15 @@ public Rect roundOut() { Mathf.Ceil(this.right), Mathf.Ceil(this.bottom)); } - public Rect roundOut(float devicePixelRatio) { + public Rect roundOutScale(float scale) { + return fromLTRB( + Mathf.Floor(this.left * scale), + Mathf.Floor(this.top * scale), + Mathf.Ceil(this.right * scale), + Mathf.Ceil(this.bottom * scale)); + } + + public Rect withDevicePixelRatio(float devicePixelRatio) { return fromLTRB( Mathf.Floor(this.left * devicePixelRatio) / devicePixelRatio, Mathf.Floor(this.top * devicePixelRatio) / devicePixelRatio, diff --git a/Runtime/ui/painting/canvas.cs b/Runtime/ui/painting/canvas.cs index 7067c20b..28becbdf 100644 --- a/Runtime/ui/painting/canvas.cs +++ b/Runtime/ui/painting/canvas.cs @@ -99,9 +99,11 @@ public void saveLayer(Rect rect, Paint paint) { } public void restore() { - this._saveCount--; - this._recorder.addDrawCmd(new DrawRestore { - }); + if (this._saveCount > 1) { + this._saveCount--; + this._recorder.addDrawCmd(new DrawRestore { + }); + } } public int getSaveCount() { diff --git a/Runtime/ui/painting/draw_cmd.cs b/Runtime/ui/painting/draw_cmd.cs index 622dfd84..9aa7089e 100644 --- a/Runtime/ui/painting/draw_cmd.cs +++ b/Runtime/ui/painting/draw_cmd.cs @@ -1,4 +1,4 @@ -namespace Unity.UIWidgets.ui { +namespace Unity.UIWidgets.ui { public abstract class DrawCmd { } diff --git a/Runtime/ui/painting/image.cs b/Runtime/ui/painting/image.cs index a565d1c6..08486d6d 100644 --- a/Runtime/ui/painting/image.cs +++ b/Runtime/ui/painting/image.cs @@ -23,6 +23,10 @@ public Image(Texture texture, bool noDispose = false, bool isAsset = false, Asse this._isDynamic = isDynamic; } + public bool valid { + get { return this._texture != null; } + } + public int width { get { return this._texture != null ? this._texture.width : 0; } } diff --git a/Runtime/ui/painting/path.cs b/Runtime/ui/painting/path.cs index 1dc6ac4c..b30c96da 100644 --- a/Runtime/ui/painting/path.cs +++ b/Runtime/ui/painting/path.cs @@ -1,10 +1,20 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Text; using Unity.UIWidgets.foundation; using UnityEngine; namespace Unity.UIWidgets.ui { + + public enum PathOperation { + difference, + intersect, + union, + xor, + reverseDifference, + } + struct VertexUV { public List fillVertices; public List fillUV; @@ -216,6 +226,34 @@ public Rect getBounds() { return Rect.fromLTRB(this._minX, this._minY, this._maxX, this._maxY); } + public Rect getBoundsWithMargin(float margin) { + if (this._minX - margin >= this._maxX + margin || this._minY - margin >= this._maxY + margin) { + return Rect.zero; + } + + return Rect.fromLTRB(this._minX - margin, this._minY - margin, this._maxX + margin, this._maxY + margin); + } + + public static Path combine(PathOperation operation, Path path1, Path path2) { + D.assert(path1 != null); + D.assert(path2 != null); + Path path = null; + D.assert(() => { + Debug.LogWarning("Path._op() not implemented yet!"); + return true; + }); + return path; +// if (path._op(path1, path2, (int) operation)) { +// return path; +// } +// throw new UIWidgetsError("Path.combine() failed. This may be due an invalid path; " + +// "in particular, check for NaN values."); + } + + public PathMetrics computeMetrics(bool forceClosed = false) { + return PathMetrics._(this, forceClosed); + } + void _appendMoveTo(float x, float y) { this._commands.Add((float) PathCommand.moveTo); this._commands.Add(x); @@ -1298,6 +1336,77 @@ static int _findUnitQuadRoots(float A, float B, float C, float[] roots) { } } + public class PathMetrics : IEnumerable { + public PathMetrics(IEnumerator enumerator) { + this._enumerator = enumerator; + } + + public static PathMetrics _(Path path, bool forceClosed) { + return new PathMetrics(PathMetricIterator._(new _PathMeasure())); // TODO: complete the implementation + } + + public readonly IEnumerator _enumerator; + + public IEnumerator GetEnumerator() { + return this._enumerator; + } + + IEnumerator IEnumerable.GetEnumerator() { + return this.GetEnumerator(); + } + } + + public class PathMetric { + // TODO + public readonly float length; + } + + public class PathMetricIterator : IEnumerator { + PathMetricIterator(_PathMeasure measure) { + this._pathMeasure = measure; + } + + internal static PathMetricIterator _(_PathMeasure _pathMeasure) { + D.assert(_pathMeasure != null); + return new PathMetricIterator(_pathMeasure); + } + + // PathMetric _pathMetric; // TODO + _PathMeasure _pathMeasure; + + public void Reset() { + throw new NotImplementedException(); + } + + public PathMetric Current { + get { + return null; // TODO : return this._pathMetric; + } + } + + object IEnumerator.Current { + get { + return null; // TODO : return this._pathMetric; + } + } + + public bool MoveNext() { +// if (_pathMeasure._nextContour()) { +// _pathMetric = PathMetric._(_pathMeasure); +// return true; +// } +// _pathMetric = null; + return false; + } + + public void Dispose() { + throw new NotImplementedException(); + } + } + + class _PathMeasure { + } + public enum PathWinding { counterClockwise = 1, // which just means the order as the input is. clockwise = 2, // which just means the reversed order. diff --git a/Runtime/ui/painting/picture.cs b/Runtime/ui/painting/picture.cs index 350a33f2..81e189f3 100644 --- a/Runtime/ui/painting/picture.cs +++ b/Runtime/ui/painting/picture.cs @@ -1,17 +1,26 @@ using System; using System.Collections.Generic; using Unity.UIWidgets.foundation; +using Unity.UIWidgets.external; namespace Unity.UIWidgets.ui { public class Picture { - public Picture(List drawCmds, Rect paintBounds, bool isDynamic = false) { + public Picture(List drawCmds, + Rect paintBounds, + bool isDynamic = false, + BBoxHierarchy bbh = null, + List stateUpdatesIndices = null) { this.drawCmds = drawCmds; this.paintBounds = paintBounds; this._isDynamic = isDynamic; + this.bbh = bbh; + this.stateUpdatesIndices = stateUpdatesIndices; } public readonly List drawCmds; public readonly Rect paintBounds; + public readonly BBoxHierarchy bbh; + public readonly List stateUpdatesIndices; public bool isDynamic { get { return this._isDynamic; } @@ -24,6 +33,10 @@ public class PictureRecorder { readonly List _drawCmds = new List(); readonly List _states = new List(); + + readonly BBoxHierarchy _bbh = new RTree(); + + readonly List _stateUpdateIndices = new List(); bool _isDynamic; @@ -51,15 +64,47 @@ public void reset() { layerOffset = null, paintBounds = Rect.zero, }); + this._bbh.Clear(); + this._stateUpdateIndices.Clear(); + } + + void restoreToCount(int count) { + count = this._states.Count - count; + while (count > 0) { + this.addDrawCmd(new DrawRestore()); + count--; + } + } + + void restore() { + var stateToRestore = this._getState(); + this._states.RemoveAt(this._states.Count - 1); + var state = this._getState(); + + if (!stateToRestore.saveLayer) { + state.paintBounds = stateToRestore.paintBounds; + } + else { + var paintBounds = stateToRestore.paintBounds.shift(stateToRestore.layerOffset); + paintBounds = state.xform.mapRect(paintBounds); + this._addPaintBounds(paintBounds); + } } public Picture endRecording() { + this.restoreToCount(1); + if (this._states.Count > 1) { throw new Exception("unmatched save/restore commands"); } var state = this._getState(); - return new Picture(new List(this._drawCmds), state.paintBounds, this._isDynamic); + return new Picture( + new List(this._drawCmds), + state.paintBounds, + this._isDynamic, + this._bbh, + this._stateUpdateIndices); } public void addDrawCmd(DrawCmd drawCmd) { @@ -68,6 +113,7 @@ public void addDrawCmd(DrawCmd drawCmd) { switch (drawCmd) { case DrawSave _: this._states.Add(this._getState().copy()); + this._stateUpdateIndices.Add(this._drawCmds.Count - 1); break; case DrawSaveLayer cmd: { this._states.Add(new CanvasState { @@ -77,23 +123,16 @@ public void addDrawCmd(DrawCmd drawCmd) { layerOffset = cmd.rect.topLeft, paintBounds = Rect.zero, }); + this._stateUpdateIndices.Add(this._drawCmds.Count - 1); break; } case DrawRestore _: { - var stateToRestore = this._getState(); - this._states.RemoveAt(this._states.Count - 1); - var state = this._getState(); - - if (!stateToRestore.saveLayer) { - state.paintBounds = stateToRestore.paintBounds; - } - else { - var paintBounds = stateToRestore.paintBounds.shift(stateToRestore.layerOffset); - paintBounds = state.xform.mapRect(paintBounds); - this._addPaintBounds(paintBounds); + //check for underflow + if (this._states.Count > 1) { + this.restore(); } - + this._stateUpdateIndices.Add(this._drawCmds.Count - 1); break; } @@ -101,6 +140,7 @@ public void addDrawCmd(DrawCmd drawCmd) { var state = this._getState(); state.xform = new Matrix3(state.xform); state.xform.preTranslate(cmd.dx, cmd.dy); + this._stateUpdateIndices.Add(this._drawCmds.Count - 1); break; } @@ -108,6 +148,7 @@ public void addDrawCmd(DrawCmd drawCmd) { var state = this._getState(); state.xform = new Matrix3(state.xform); state.xform.preScale(cmd.sx, (cmd.sy ?? cmd.sx)); + this._stateUpdateIndices.Add(this._drawCmds.Count - 1); break; } @@ -122,6 +163,7 @@ public void addDrawCmd(DrawCmd drawCmd) { cmd.offset.dx, cmd.offset.dy); } + this._stateUpdateIndices.Add(this._drawCmds.Count - 1); break; } @@ -130,6 +172,7 @@ public void addDrawCmd(DrawCmd drawCmd) { var state = this._getState(); state.xform = new Matrix3(state.xform); state.xform.preSkew(cmd.sx, cmd.sy); + this._stateUpdateIndices.Add(this._drawCmds.Count - 1); break; } @@ -137,18 +180,21 @@ public void addDrawCmd(DrawCmd drawCmd) { var state = this._getState(); state.xform = new Matrix3(state.xform); state.xform.preConcat(cmd.matrix); + this._stateUpdateIndices.Add(this._drawCmds.Count - 1); break; } case DrawResetMatrix _: { var state = this._getState(); state.xform = Matrix3.I(); + this._stateUpdateIndices.Add(this._drawCmds.Count - 1); break; } case DrawSetMatrix cmd: { var state = this._getState(); state.xform = new Matrix3(cmd.matrix); + this._stateUpdateIndices.Add(this._drawCmds.Count - 1); break; } @@ -157,6 +203,7 @@ public void addDrawCmd(DrawCmd drawCmd) { var rect = state.xform.mapRect(cmd.rect); state.scissor = state.scissor == null ? rect : state.scissor.intersect(rect); + this._stateUpdateIndices.Add(this._drawCmds.Count - 1); break; } @@ -165,6 +212,7 @@ public void addDrawCmd(DrawCmd drawCmd) { var rect = state.xform.mapRect(cmd.rrect.outerRect); state.scissor = state.scissor == null ? rect : state.scissor.intersect(rect); + this._stateUpdateIndices.Add(this._drawCmds.Count - 1); break; } @@ -178,6 +226,7 @@ public void addDrawCmd(DrawCmd drawCmd) { cache.computeFillMesh(0.0f, out _); var rect = cache.fillMesh.transform(state.xform).bounds; state.scissor = state.scissor == null ? rect : state.scissor.intersect(rect); + this._stateUpdateIndices.Add(this._drawCmds.Count - 1); break; } @@ -216,9 +265,13 @@ public void addDrawCmd(DrawCmd drawCmd) { float sigma = scale * paint.maskFilter.sigma; float sigma3 = 3 * sigma; this._addPaintBounds(mesh.bounds.inflate(sigma3)); + this._bbh.Insert(new IndexedRect(uiRectHelper.fromRect(mesh.bounds.inflate(sigma3 + 5)).Value, + this._drawCmds.Count - 1)); } else { this._addPaintBounds(mesh.bounds); + this._bbh.Insert(new IndexedRect(uiRectHelper.fromRect(mesh.bounds.inflate(5)).Value, + this._drawCmds.Count - 1)); } break; @@ -230,6 +283,8 @@ public void addDrawCmd(DrawCmd drawCmd) { cmd.image.width, cmd.image.height); rect = state.xform.mapRect(rect); this._addPaintBounds(rect); + this._bbh.Insert(new IndexedRect(uiRectHelper.fromRect(rect.inflate(5)).Value, + this._drawCmds.Count - 1)); if (cmd.image.isDynamic) { this._isDynamic = true; } @@ -241,6 +296,8 @@ public void addDrawCmd(DrawCmd drawCmd) { var state = this._getState(); var rect = state.xform.mapRect(cmd.dst); this._addPaintBounds(rect); + this._bbh.Insert(new IndexedRect(uiRectHelper.fromRect(rect.inflate(5)).Value, + this._drawCmds.Count - 1)); if (cmd.image.isDynamic) { this._isDynamic = true; } @@ -252,6 +309,8 @@ public void addDrawCmd(DrawCmd drawCmd) { var state = this._getState(); var rect = state.xform.mapRect(cmd.dst); this._addPaintBounds(rect); + this._bbh.Insert(new IndexedRect(uiRectHelper.fromRect(rect.inflate(5)).Value, + this._drawCmds.Count - 1)); if (cmd.image.isDynamic) { this._isDynamic = true; } @@ -263,6 +322,8 @@ public void addDrawCmd(DrawCmd drawCmd) { var state = this._getState(); var rect = state.xform.mapRect(cmd.picture.paintBounds); this._addPaintBounds(rect); + this._bbh.Insert(new IndexedRect(uiRectHelper.fromRect(rect.inflate(5)).Value, + this._drawCmds.Count - 1)); if (cmd.picture.isDynamic) { this._isDynamic = true; } @@ -281,9 +342,13 @@ public void addDrawCmd(DrawCmd drawCmd) { float sigma = scale * paint.maskFilter.sigma; float sigma3 = 3 * sigma; this._addPaintBounds(rect.inflate(sigma3)); + this._bbh.Insert(new IndexedRect(uiRectHelper.fromRect(rect.inflate(sigma3 + 5)).Value, + this._drawCmds.Count - 1)); } else { this._addPaintBounds(rect); + this._bbh.Insert(new IndexedRect(uiRectHelper.fromRect(rect.inflate(5)).Value, + this._drawCmds.Count - 1)); } break; diff --git a/Runtime/ui/painting/shadow_utils.cs b/Runtime/ui/painting/shadow_utils.cs index 0f5e5f66..f73616ba 100644 --- a/Runtime/ui/painting/shadow_utils.cs +++ b/Runtime/ui/painting/shadow_utils.cs @@ -142,12 +142,14 @@ float heightFunc(float x, float y) { static readonly Path _devSpacePath = new Path(); public static void drawShadow(Canvas canvas, Path path, Vector3 zPlaneParams, Vector3 devLightPos, float lightRadius, uiColor ambientColor, uiColor spotColor, int flags) { + #pragma warning disable CS0162 if (kUseFastShadow) { drawShadowFast(canvas, path, zPlaneParams, devLightPos, lightRadius, ambientColor, spotColor, flags); } else { drawShadowFull(canvas, path, zPlaneParams, devLightPos, lightRadius, ambientColor, spotColor, flags); } + #pragma warning restore CS0162 } //cached variables @@ -209,6 +211,7 @@ static void drawShadowFast(Canvas canvas, Path path, Vector3 zPlaneParams, Vecto Matrix3 viewMatrix = canvas.getTotalMatrix(); //debug shadow + #pragma warning disable CS0162 if (debugShadow) { var isRRect = path.isNaiveRRect; if (isRRect) { @@ -220,6 +223,7 @@ static void drawShadowFast(Canvas canvas, Path path, Vector3 zPlaneParams, Vecto spotColor = uiColor.fromColor(Colors.green); } } + #pragma warning restore CS0162 //ambient light float devSpaceOutset = ambientBlurRadius(zPlaneParams.z); diff --git a/Runtime/ui/painting/txt/font_manager.cs b/Runtime/ui/painting/txt/font_manager.cs index 967bf418..c6d6052a 100644 --- a/Runtime/ui/painting/txt/font_manager.cs +++ b/Runtime/ui/painting/txt/font_manager.cs @@ -24,7 +24,7 @@ public void onTextureRebuilt() { public class FontManager { readonly Dictionary[] _fonts = new Dictionary[9 * 2]; // max weight size x max style size - + static readonly int defaultFontSize = 14; public static readonly FontManager instance = new FontManager(); @@ -33,7 +33,7 @@ public class FontManager { Font.textureRebuilt += this.onFontTextureRebuilt; } - public void addFont(Font font, string familyName, + public void addFont(Font font, string familyName, FontWeight fontWeight = null, FontStyle fontStyle = FontStyle.normal) { fontWeight = fontWeight ?? FontWeight.normal; @@ -43,7 +43,7 @@ public void addFont(Font font, string familyName, var fonts = this._getFonts(fontWeight.index, fontStyle); fonts.TryGetValue(familyName, out var current); - D.assert(current == null || current.font == font, + D.assert(current == null || current.font == font, () => $"font with key {familyName} {fontWeight} {fontStyle} already exists"); var fontInfo = new FontInfo(font); fonts[familyName] = fontInfo; @@ -74,7 +74,7 @@ internal FontInfo getOrCreate(string familyName, FontWeight fontWeight, FontStyl return fontInfo; } } - + var osFont = Font.CreateDynamicFontFromOSFont(familyName, defaultFontSize); osFont.hideFlags = HideFlags.DontSave; osFont.material.hideFlags = HideFlags.DontSave; @@ -99,8 +99,7 @@ void onFontTextureRebuilt(Font font) { } } - public static class FontExtension - { + public static class FontExtension { internal static bool getGlyphInfo(this Font font, char ch, out CharacterInfo info, int fontSize, UnityEngine.FontStyle fontStyle) { if (fontSize <= 0) { @@ -111,8 +110,11 @@ internal static bool getGlyphInfo(this Font font, char ch, out CharacterInfo inf bool success = font.GetCharacterInfo(ch, out info, fontSize, fontStyle); if (!success) { if (!char.IsControl(ch)) { - Debug.LogWarning( - $"character info not found from the given font: character '{ch}' (code{(int) ch}) font: ${font.name}"); + D.assert(() => { + Debug.LogWarning( + $"character info not found from the given font: character '{ch}' (code{(int) ch}) font: ${font.name}"); + return true; + }); } info = default; @@ -122,11 +124,12 @@ internal static bool getGlyphInfo(this Font font, char ch, out CharacterInfo inf return true; } - internal static void RequestCharactersInTextureSafe(this Font font, string text, int fontSize, - UnityEngine.FontStyle fontStyle = UnityEngine.FontStyle.Normal) { + internal static void RequestCharactersInTextureSafe(this Font font, string text, int fontSize, + UnityEngine.FontStyle fontStyle = UnityEngine.FontStyle.Normal) { if (fontSize <= 0) { return; } + font.RequestCharactersInTexture(text, fontSize, fontStyle); } } diff --git a/Runtime/ui/pointer.cs b/Runtime/ui/pointer.cs index d2ce8ab6..fd2423d5 100644 --- a/Runtime/ui/pointer.cs +++ b/Runtime/ui/pointer.cs @@ -20,28 +20,88 @@ public enum PointerDeviceKind { mouse, } + public enum PointerSignalKind { + none, + scroll, + unknown, + } + public class PointerData { public PointerData( TimeSpan timeStamp, PointerChange change, PointerDeviceKind kind, - int device, - float physicalX, - float physicalY) { + PointerSignalKind signalKind = PointerSignalKind.none, + int device = 0, + float physicalX = 0.0f, + float physicalY = 0.0f, + int buttons = 0, + bool obscured = false, + float pressure = 0.0f, + float pressureMin = 0.0f, + float pressureMax = 0.0f, + float distance = 0.0f, + float distanceMax = 0.0f, + float size = 0.0f, + float radiusMajor = 0.0f, + float radiusMinor = 0.0f, + float radiusMin = 0.0f, + float radiusMax = 0.0f, + float orientation = 0.0f, + float tilt = 0.0f, + int platformData = 0, + float scrollDeltaX = 0.0f, + float scrollDeltaY = 0.0f) { this.timeStamp = timeStamp; this.change = change; this.kind = kind; + this.signalKind = signalKind; this.device = device; this.physicalX = physicalX; this.physicalY = physicalY; + this.buttons = buttons; + this.obscured = obscured; + this.pressure = pressure; + this.pressureMin = pressureMin; + this.pressureMax = pressureMax; + this.distance = distance; + this.distanceMax = distanceMax; + this.size = size; + this.radiusMajor = radiusMajor; + this.radiusMinor = radiusMinor; + this.radiusMin = radiusMin; + this.radiusMax = radiusMax; + this.orientation = orientation; + this.tilt = tilt; + this.platformData = platformData; + this.scrollDeltaX = scrollDeltaX; + this.scrollDeltaY = scrollDeltaY; } public readonly TimeSpan timeStamp; - public PointerChange change; - public PointerDeviceKind kind; - public int device; - public float physicalX; - public float physicalY; + public readonly PointerChange change; + public readonly PointerDeviceKind kind; + public readonly PointerSignalKind signalKind; + public readonly int device; + public readonly float physicalX; + public readonly float physicalY; + public readonly int buttons; + public readonly bool obscured; + public readonly float pressure; + public readonly float pressureMin; + public readonly float pressureMax; + public readonly float distance; + public readonly float distanceMax; + public readonly float size; + public readonly float radiusMajor; + public readonly float radiusMinor; + public readonly float radiusMin; + public readonly float radiusMax; + public readonly float orientation; + public readonly float tilt; + public readonly int platformData; + public readonly float scrollDeltaX; + public readonly float scrollDeltaY; } public class ScrollData : PointerData { @@ -49,11 +109,12 @@ public ScrollData( TimeSpan timeStamp, PointerChange change, PointerDeviceKind kind, - int device, - float physicalX, - float physicalY, - float scrollX, - float scrollY) : base(timeStamp, change, kind, device, physicalX, physicalY) { + 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; } diff --git a/Runtime/ui/renderer/allocator/debug.cs b/Runtime/ui/renderer/allocator/debug.cs index bf4184b0..70bdf346 100644 --- a/Runtime/ui/renderer/allocator/debug.cs +++ b/Runtime/ui/renderer/allocator/debug.cs @@ -33,6 +33,7 @@ public static void onFrameEnd() { return; } + #pragma warning disable CS0162 allocCount++; if (allocCount >= 120) { allocCount = 0; @@ -55,6 +56,7 @@ public static void onFrameEnd() { Debug.Log(debugInfo); } + #pragma warning restore CS0162 } public static void onAlloc(int objKey, string objName, int allocatedCount) { diff --git a/Runtime/ui/renderer/allocator/pool_object.cs b/Runtime/ui/renderer/allocator/pool_object.cs index f4d8bf35..24147c1c 100644 --- a/Runtime/ui/renderer/allocator/pool_object.cs +++ b/Runtime/ui/renderer/allocator/pool_object.cs @@ -33,10 +33,12 @@ public static TObject alloc() { var ret = pool.Pop(); ret.setup(); + #pragma warning disable CS0162 if (AllocDebugger.enableDebugging) { AllocDebugger.onAlloc(debugKey, debugName, allocatedCount); ret.activated_flag = true; } + #pragma warning restore CS0162 return ret; } @@ -46,6 +48,7 @@ public static void release(TObject obj) { return; } + #pragma warning disable CS0162 if (AllocDebugger.enableDebugging) { if (!obj.activated_flag) { Debug.Assert(false, "an item has been recycled more than once !"); @@ -55,6 +58,7 @@ public static void release(TObject obj) { AllocDebugger.onRelease(debugKey, debugName, allocatedCount); } + #pragma warning restore CS0162 obj.clear(); if (pool.Count > POOL_MAX_SIZE) { diff --git a/Runtime/ui/renderer/cmdbufferCanvas/rendering/canvas_computebuffer_utils.cs b/Runtime/ui/renderer/cmdbufferCanvas/rendering/canvas_computebuffer_utils.cs new file mode 100644 index 00000000..e66ece59 --- /dev/null +++ b/Runtime/ui/renderer/cmdbufferCanvas/rendering/canvas_computebuffer_utils.cs @@ -0,0 +1,96 @@ +using System.Collections.Generic; +using System.Runtime.InteropServices; +using UnityEngine; + +namespace Unity.UIWidgets.ui { + public partial class PictureFlusher { + + struct uiVertex + { + public Vector2 position; + public Vector2 uv; + } + + ComputeBuffer _computeBuffer; + List _vertices; + + ComputeBuffer _indexBuffer; + List _indices; + + int _startVertex; + int _startIndex; + + public const int COMPUTE_BUFFER_MAX_ITEM_NUM = 1024 * 1024; // maxsize = 1M vertex/index + + bool supportComputeBuffer { + get { return CanvasShader.supportComputeBuffer; } + } + + void _releaseComputeBuffer() { + if (!this.supportComputeBuffer) { + return; + } + + if (this._computeBuffer == null) { + return; + } + + this._computeBuffer.Dispose(); + this._indexBuffer.Dispose(); + this._vertices = null; + this._indices = null; + this._computeBuffer = null; + this._indexBuffer = null; + } + + void _initComputeBuffer() { + var stride = Marshal.SizeOf(typeof(uiVertex)); + var strideIndex = Marshal.SizeOf(typeof(int)); + this._computeBuffer = new ComputeBuffer(COMPUTE_BUFFER_MAX_ITEM_NUM, stride); + this._vertices = new List(); + + this._indexBuffer = new ComputeBuffer(COMPUTE_BUFFER_MAX_ITEM_NUM, strideIndex); + this._indices = new List(); + } + + void _resetComputeBuffer() { + if (!this.supportComputeBuffer) return; + + if (this._computeBuffer == null) { + this._initComputeBuffer(); + } + + this._vertices.Clear(); + this._indices.Clear(); + this._startVertex = 0; + this._startIndex = 0; + } + + void _bindComputeBuffer() { + if (!this.supportComputeBuffer) return; + + this._computeBuffer.SetData(this._vertices); + this._indexBuffer.SetData(this._indices); + } + + void _addMeshToComputeBuffer(List vertex, List uv, List triangles) { + if (!this.supportComputeBuffer) return; + + this._startVertex = this._vertices.Count; + this._startIndex = this._indices.Count; + + var hasUv = uv != null; + + for (int i = 0; i < vertex.Count; i++) { + this._vertices.Add(new uiVertex { + position = new Vector2(vertex[i].x, vertex[i].y), + uv = hasUv ? uv[i] : Vector2.zero + }); + } + + foreach (var triangleId in triangles) { + this._indices.Add(triangleId + this._startVertex); + } + } + } +} \ No newline at end of file diff --git a/Runtime/ui/renderer/cmdbufferCanvas/rendering/canvas_computebuffer_utils.cs.meta b/Runtime/ui/renderer/cmdbufferCanvas/rendering/canvas_computebuffer_utils.cs.meta new file mode 100644 index 00000000..823f280a --- /dev/null +++ b/Runtime/ui/renderer/cmdbufferCanvas/rendering/canvas_computebuffer_utils.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 88f2ad2c8ab504c5d95b1f70539f8d86 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/ui/renderer/cmdbufferCanvas/rendering/canvas_impl.cs b/Runtime/ui/renderer/cmdbufferCanvas/rendering/canvas_impl.cs index 65257abd..3532a0bf 100644 --- a/Runtime/ui/renderer/cmdbufferCanvas/rendering/canvas_impl.cs +++ b/Runtime/ui/renderer/cmdbufferCanvas/rendering/canvas_impl.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; +using System.Linq; using Unity.UIWidgets.foundation; +using Unity.UIWidgets.external; using UnityEngine; using UnityEngine.Rendering; @@ -42,6 +44,8 @@ public void dispose() { this._lastScissor = null; this._layers.Clear(); } + + this._releaseComputeBuffer(); } public PictureFlusher(RenderTexture renderTexture, float devicePixelRatio, MeshPool meshPool) { @@ -94,7 +98,7 @@ void _save() { layer.clipStack.save(); } - readonly uiOffset[] _saveLayer_Points = new uiOffset[4]; + static uiOffset[] _cachedPoints = new uiOffset[4]; void _saveLayer(uiRect bounds, uiPaint paint) { D.assert(bounds.width > 0); @@ -127,30 +131,31 @@ void _saveLayer(uiRect bounds, uiPaint paint) { this._currentLayer = layer; if (paint.backdrop != null) { - if (paint.backdrop is _BlurImageFilter) { - var filter = (_BlurImageFilter) paint.backdrop; + + if (paint.backdrop is _uiBlurImageFilter) { + var filter = (_uiBlurImageFilter) paint.backdrop; if (!(filter.sigmaX == 0 && filter.sigmaY == 0)) { - this._saveLayer_Points[0] = bounds.topLeft; - this._saveLayer_Points[1] = bounds.bottomLeft; - this._saveLayer_Points[2] = bounds.bottomRight; - this._saveLayer_Points[3] = bounds.topRight; + _cachedPoints[0] = bounds.topLeft; + _cachedPoints[1] = bounds.bottomLeft; + _cachedPoints[2] = bounds.bottomRight; + _cachedPoints[3] = bounds.topRight; - state.matrix.Value.mapPoints(this._saveLayer_Points); + state.matrix.Value.mapPoints(ref _cachedPoints); var parentBounds = parentLayer.layerBounds; for (int i = 0; i < 4; i++) { - this._saveLayer_Points[i] = new uiOffset( - (this._saveLayer_Points[i].dx - parentBounds.left) / parentBounds.width, - (this._saveLayer_Points[i].dy - parentBounds.top) / parentBounds.height + _cachedPoints[i] = new uiOffset( + (_cachedPoints[i].dx - parentBounds.left) / parentBounds.width, + (_cachedPoints[i].dy - parentBounds.top) / parentBounds.height ); } var mesh = ImageMeshGenerator.imageMesh( null, - this._saveLayer_Points[0], - this._saveLayer_Points[1], - this._saveLayer_Points[2], - this._saveLayer_Points[3], + _cachedPoints[0], + _cachedPoints[1], + _cachedPoints[2], + _cachedPoints[3], bounds); var renderDraw = CanvasShader.texRT(layer, layer.layerPaint.Value, mesh, parentLayer); layer.draws.Add(renderDraw); @@ -160,35 +165,36 @@ void _saveLayer(uiRect bounds, uiPaint paint) { layer.draws.Add(CanvasShader.texRT(layer, paint, blurMesh, blurLayer)); } } - else if (paint.backdrop is _MatrixImageFilter) { - var filter = (_MatrixImageFilter) paint.backdrop; + else if (paint.backdrop is _uiMatrixImageFilter) { + var filter = (_uiMatrixImageFilter) paint.backdrop; if (!filter.transform.isIdentity()) { layer.filterMode = filter.filterMode; - this._saveLayer_Points[0] = bounds.topLeft; - this._saveLayer_Points[1] = bounds.bottomLeft; - this._saveLayer_Points[2] = bounds.bottomRight; - this._saveLayer_Points[3] = bounds.topRight; - state.matrix.Value.mapPoints(this._saveLayer_Points); + _cachedPoints[0] = bounds.topLeft; + _cachedPoints[1] = bounds.bottomLeft; + _cachedPoints[2] = bounds.bottomRight; + _cachedPoints[3] = bounds.topRight; + + state.matrix.Value.mapPoints(ref _cachedPoints); var parentBounds = parentLayer.layerBounds; for (int i = 0; i < 4; i++) { - this._saveLayer_Points[i] = new uiOffset( - (this._saveLayer_Points[i].dx - parentBounds.left) / parentBounds.width, - (this._saveLayer_Points[i].dy - parentBounds.top) / parentBounds.height + _cachedPoints[i] = new uiOffset( + (_cachedPoints[i].dx - parentBounds.left) / parentBounds.width, + (_cachedPoints[i].dy - parentBounds.top) / parentBounds.height ); } var matrix = uiMatrix3.makeTrans(-bounds.left, -bounds.top); - matrix.postConcat(uiMatrix3.fromMatrix3(filter.transform)); + matrix.postConcat(filter.transform); matrix.postTranslate(bounds.left, bounds.top); var mesh = ImageMeshGenerator.imageMesh( matrix, - this._saveLayer_Points[0], - this._saveLayer_Points[1], - this._saveLayer_Points[2], - this._saveLayer_Points[3], + _cachedPoints[0], + _cachedPoints[1], + _cachedPoints[2], + _cachedPoints[3], bounds); var renderDraw = CanvasShader.texRT(layer, layer.layerPaint.Value, mesh, parentLayer); layer.draws.Add(renderDraw); @@ -277,7 +283,7 @@ void _setMatrix(uiMatrix3 matrix) { void _clipRect(Rect rect) { var path = uiPath.create(); - path.addRect(uiRectHelper.fromRect(rect)); + path.addRect(uiRectHelper.fromRect(rect).Value); this._clipPath(path); uiPathCacheManager.putToCache(path); } @@ -682,7 +688,11 @@ void _drawPath(uiPath path, uiPaint paint) { } void _drawImage(Image image, uiOffset offset, uiPaint paint) { - D.assert(image != null); + D.assert(image != null && image.valid); + + if (image == null || !image.valid) { + return; + } this._drawImageRect(image, null, @@ -694,7 +704,11 @@ void _drawImage(Image image, uiOffset offset, uiPaint paint) { } void _drawImageRect(Image image, uiRect? src, uiRect dst, uiPaint paint) { - D.assert(image != null); + D.assert(image != null && image.valid); + + if (image == null || !image.valid) { + return; + } if (src == null) { src = uiRectHelper.one; @@ -715,7 +729,11 @@ void _drawImageRect(Image image, uiRect? src, uiRect dst, uiPaint paint) { } void _drawImageNine(Image image, uiRect? src, uiRect center, uiRect dst, uiPaint paint) { - D.assert(image != null); + D.assert(image != null && image.valid); + + if (image == null || !image.valid) { + return; + } var scaleX = 1f / image.width; var scaleY = 1f / image.height; @@ -750,6 +768,21 @@ void _drawPicture(Picture picture, bool needsSave = true) { int saveCount = 0; var drawCmds = picture.drawCmds; + var queryBound = this._currentLayer.currentState.matrix?.invert().Value + .mapRect(this._currentLayer.layerBounds) ?? + this._currentLayer.layerBounds; + + // if (!uiRectHelper.contains(queryBound, uiRectHelper.fromRect(picture.paintBounds).Value)) { + // var indices = picture.bbh.Search(queryBound).Select(bound => bound.index); + // List cmdIndices = indices.ToList(); + // cmdIndices.AddRange(picture.stateUpdatesIndices); + // cmdIndices.Sort(); + // drawCmds = new List(); + // for (int i = 0; i < cmdIndices.Count; i++) { + // drawCmds.Add(picture.drawCmds[cmdIndices[i]]); + // } + // } + foreach (var drawCmd in drawCmds) { switch (drawCmd) { case DrawSave _: @@ -758,7 +791,7 @@ void _drawPicture(Picture picture, bool needsSave = true) { break; case DrawSaveLayer cmd: { saveCount++; - this._saveLayer(uiRectHelper.fromRect(cmd.rect), uiPaint.fromPaint(cmd.paint)); + this._saveLayer(uiRectHelper.fromRect(cmd.rect).Value, uiPaint.fromPaint(cmd.paint)); break; } @@ -836,14 +869,14 @@ void _drawPicture(Picture picture, bool needsSave = true) { } case DrawImageRect cmd: { - this._drawImageRect(cmd.image, uiRectHelper.fromRect(cmd.src), uiRectHelper.fromRect(cmd.dst), + this._drawImageRect(cmd.image, uiRectHelper.fromRect(cmd.src), uiRectHelper.fromRect(cmd.dst).Value, uiPaint.fromPaint(cmd.paint)); break; } case DrawImageNine cmd: { this._drawImageNine(cmd.image, uiRectHelper.fromRect(cmd.src), - uiRectHelper.fromRect(cmd.center), uiRectHelper.fromRect(cmd.dst), + uiRectHelper.fromRect(cmd.center).Value, uiRectHelper.fromRect(cmd.dst).Value, uiPaint.fromPaint(cmd.paint)); break; } @@ -854,6 +887,7 @@ void _drawPicture(Picture picture, bool needsSave = true) { } case DrawTextBlob cmd: { + this._paintTextShadow(cmd.textBlob, cmd.offset); this._drawTextBlob(cmd.textBlob, (uiOffset.fromOffset(cmd.offset)).Value, uiPaint.fromPaint(cmd.paint)); break; @@ -882,6 +916,24 @@ void _drawUIPicture(uiPicture picture, bool needsSave = true) { int saveCount = 0; var drawCmds = picture.drawCmds; + var queryBound = this._currentLayer.currentState.matrix?.invert().Value + .mapRect(this._currentLayer.layerBounds) ?? + this._currentLayer.layerBounds; + + // if (!uiRectHelper.contains(queryBound, picture.paintBounds)) { + // var indices = picture.bbh.Search(queryBound).Select(bound => bound.index); + // List cmdIndices = indices.ToList(); + // cmdIndices.Capacity += picture.stateUpdatesIndices.Count; + // for (int i = 0; i < picture.stateUpdatesIndices.Count; i++) { + // cmdIndices.Add(picture.stateUpdatesIndices[i]); + // } + // cmdIndices.Sort(); + // drawCmds = new List(); + // for (int i = 0; i < cmdIndices.Count; i++) { + // drawCmds.Add(picture.drawCmds[cmdIndices[i]]); + // } + // } + foreach (var drawCmd in drawCmds) { switch (drawCmd) { case uiDrawSave _: @@ -978,6 +1030,7 @@ void _drawUIPicture(uiPicture picture, bool needsSave = true) { } case uiDrawTextBlob cmd: { + this._paintTextShadow(cmd.textBlob, new Offset(cmd.offset.Value.dx, cmd.offset.Value.dy)); this._drawTextBlob(cmd.textBlob, cmd.offset.Value, cmd.paint); break; } @@ -996,6 +1049,22 @@ void _drawUIPicture(uiPicture picture, bool needsSave = true) { } } + void _paintTextShadow(TextBlob? textBlob, Offset offset) { + D.assert(textBlob != null); + if (textBlob.Value.style.shadows != null && textBlob.Value.style.shadows.isNotEmpty()) { + textBlob.Value.style.shadows.ForEach(shadow => { + Paint paint = new Paint { + color = shadow.color, + maskFilter = shadow.blurRadius != 0 + ? MaskFilter.blur(BlurStyle.normal, shadow.blurRadius) + : null, + }; + this._drawTextBlob(textBlob, uiOffset.fromOffset(shadow.offset + offset).Value, + uiPaint.fromPaint(paint)); + }); + } + } + void _drawTextBlob(TextBlob? textBlob, uiOffset offset, uiPaint paint) { D.assert(textBlob != null); @@ -1006,7 +1075,7 @@ void _drawTextBlob(TextBlob? textBlob, uiOffset offset, uiPaint paint) { matrix.preTranslate(offset.dx, offset.dy); var mesh = TextBlobMesh.create(textBlob.Value, scale, matrix); - var textBlobBounds = matrix.mapRect(uiRectHelper.fromRect(textBlob.Value.boundsInText)); + var textBlobBounds = matrix.mapRect(uiRectHelper.fromRect(textBlob.Value.boundsInText).Value); // request font texture so text mesh could be generated correctly var style = textBlob.Value.style; @@ -1021,17 +1090,20 @@ void _drawTextBlob(TextBlob? textBlob, uiOffset offset, uiPaint paint) { } if (paint.maskFilter != null && paint.maskFilter.Value.sigma != 0) { - this._drawWithMaskFilter(textBlobBounds, paint, paint.maskFilter.Value, null, null, false, 0, 0, tex, - textBlobBounds, mesh, notEmoji, this.___drawTextDrawMeshCallback); + this._drawWithMaskFilter(textBlobBounds, paint, paint.maskFilter.Value, null, null, false, 0, 0, + notEmoji ? tex : EmojiUtils.image.texture, + textBlobBounds, mesh, true, this.___drawTextDrawMeshCallback); return; } this._drawTextDrawMeshCallback(paint, null, null, false, 0, 0, tex, textBlobBounds, mesh, notEmoji); + } public void flush(uiPicture picture) { this._reset(); this._resetRenderTextureId(); + this._resetComputeBuffer(); this._drawUIPicture(picture, false); @@ -1048,6 +1120,7 @@ public void flush(uiPicture picture) { // this is necessary for webgl2. not sure why... just to be safe to disable the scissor. cmdBuf.DisableScissorRect(); + this._bindComputeBuffer(); Graphics.ExecuteCommandBuffer(cmdBuf); } @@ -1098,9 +1171,9 @@ void _drawLayer(RenderLayer layer, CommandBuffer cmdBuf) { subLayer.width, subLayer.height, RenderTextureFormat.Default, 24) { useMipMap = false, - autoGenerateMips = false, + autoGenerateMips = false }; - + if (this._renderTexture.antiAliasing != 0 && !subLayer.noMSAA) { desc.msaaSamples = this._renderTexture.antiAliasing; } @@ -1136,12 +1209,7 @@ void _drawLayer(RenderLayer layer, CommandBuffer cmdBuf) { if (mesh == null) { continue; } - - D.assert(mesh.vertices.Count > 0); - cmd.meshObj.SetVertices(mesh.vertices?.data); - cmd.meshObj.SetTriangles(mesh.triangles?.data, 0, false); - cmd.meshObj.SetUVs(0, mesh.uv?.data); - + if (mesh.matrix == null) { cmd.properties.SetFloatArray(CmdDraw.matId, CmdDraw.idMat3.fMat); } @@ -1160,7 +1228,22 @@ void _drawLayer(RenderLayer layer, CommandBuffer cmdBuf) { cmd.properties.SetFloatArray(CmdDraw.matId, this._drawLayer_matArray); } - cmdBuf.DrawMesh(cmd.meshObj, CmdDraw.idMat, cmd.material, 0, cmd.pass, cmd.properties.mpb); + D.assert(mesh.vertices.Count > 0); + if (this.supportComputeBuffer) { + this._addMeshToComputeBuffer(mesh.vertices?.data, mesh.uv?.data, mesh.triangles?.data); + cmd.properties.SetBuffer(CmdDraw.vertexBufferId, this._computeBuffer); + cmd.properties.SetBuffer(CmdDraw.indexBufferId, this._indexBuffer); + cmd.properties.SetInt(CmdDraw.startIndexId, this._startIndex); + cmdBuf.DrawProcedural(Matrix4x4.identity, cmd.material, cmd.pass, MeshTopology.Triangles, mesh.triangles.Count, 1, cmd.properties.mpb); + } + else { + cmd.meshObj.SetVertices(mesh.vertices?.data); + cmd.meshObj.SetTriangles(mesh.triangles?.data, 0, false); + cmd.meshObj.SetUVs(0, mesh.uv?.data); + + cmdBuf.DrawMesh(cmd.meshObj, CmdDraw.idMat, cmd.material, 0, cmd.pass, cmd.properties.mpb); + } + if (cmd.layerId != null) { cmdBuf.SetGlobalTexture(CmdDraw.texId, BuiltinRenderTextureType.None); } diff --git a/Runtime/ui/renderer/cmdbufferCanvas/rendering/canvas_shader.cs b/Runtime/ui/renderer/cmdbufferCanvas/rendering/canvas_shader.cs index c7245c44..914a863d 100644 --- a/Runtime/ui/renderer/cmdbufferCanvas/rendering/canvas_shader.cs +++ b/Runtime/ui/renderer/cmdbufferCanvas/rendering/canvas_shader.cs @@ -1,4 +1,5 @@ using System; +using Unity.UIWidgets.foundation; using UnityEngine; using UnityEngine.Rendering; @@ -62,7 +63,10 @@ public static void set(Material mat, BlendMode op) { mat.SetInt(_dstBlend, (int) UnityEngine.Rendering.BlendMode.Zero); } else { - Debug.LogWarning("Not supported BlendMode: " + op + ". Defaults to srcOver"); + D.assert(() => { + Debug.LogWarning("Not supported BlendMode: " + op + ". Defaults to srcOver"); + return true; + }); mat.SetInt(_srcBlend, (int) UnityEngine.Rendering.BlendMode.One); mat.SetInt(_dstBlend, (int) UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); } @@ -143,18 +147,18 @@ public Material getMaterial(BlendMode blend, bool ignoreClip) { } } - static class CanvasShader { - static readonly MaterialByBlendModeStencilComp _convexFillMat; - static readonly MaterialByStencilComp _fill0Mat; - static readonly MaterialByBlendMode _fill1Mat; - static readonly MaterialByBlendModeStencilComp _stroke0Mat; - static readonly Material _stroke1Mat; - static readonly MaterialByBlendModeStencilComp _texMat; - static readonly Material _stencilMat; - static readonly Material _filterMat; - static readonly MaterialByBlendModeStencilComp _strokeAlphaMat; - static readonly Material _shadowBox; - static readonly Material _shadowRBox; + static partial class CanvasShader { + static MaterialByBlendModeStencilComp _convexFillMat; + static MaterialByStencilComp _fill0Mat; + static MaterialByBlendMode _fill1Mat; + static MaterialByBlendModeStencilComp _stroke0Mat; + static Material _stroke1Mat; + static MaterialByBlendModeStencilComp _texMat; + static Material _stencilMat; + static Material _filterMat; + static MaterialByBlendModeStencilComp _strokeAlphaMat; + static Material _shadowBox; + static Material _shadowRBox; static Shader GetShader(string shaderName) { var shader = Shader.Find(shaderName); @@ -166,33 +170,9 @@ static Shader GetShader(string shaderName) { } static CanvasShader() { - var convexFillShader = GetShader("UIWidgets/canvas_convexFill"); - var fill0Shader = GetShader("UIWidgets/canvas_fill0"); - var fill1Shader = GetShader("UIWidgets/canvas_fill1"); - var stroke0Shader = GetShader("UIWidgets/canvas_stroke0"); - var stroke1Shader = GetShader("UIWidgets/canvas_stroke1"); - var texShader = GetShader("UIWidgets/canvas_tex"); - var stencilShader = GetShader("UIWidgets/canvas_stencil"); - var filterShader = GetShader("UIWidgets/canvas_filter"); - var shadowBoxShader = GetShader("UIWidgets/ShadowBox"); - var shadowRBoxShader = GetShader("UIWidgets/ShadowRBox"); - var strokeAlphaShader = GetShader("UIWidgets/canvas_strokeAlpha"); - - _convexFillMat = new MaterialByBlendModeStencilComp(convexFillShader); - _fill0Mat = new MaterialByStencilComp(fill0Shader); - _fill1Mat = new MaterialByBlendMode(fill1Shader); - _stroke0Mat = new MaterialByBlendModeStencilComp(stroke0Shader); - _stroke1Mat = new Material(stroke1Shader) {hideFlags = HideFlags.HideAndDontSave}; - _strokeAlphaMat = new MaterialByBlendModeStencilComp(strokeAlphaShader); - _texMat = new MaterialByBlendModeStencilComp(texShader); - _stencilMat = new Material(stencilShader) {hideFlags = HideFlags.HideAndDontSave}; - _filterMat = new Material(filterShader) {hideFlags = HideFlags.HideAndDontSave}; - _shadowBox = new Material(shadowBoxShader) {hideFlags = HideFlags.HideAndDontSave}; - _shadowRBox = new Material(shadowRBoxShader) {hideFlags = HideFlags.HideAndDontSave}; + InitShaders(); } - public static Material shadowBox => _shadowBox; - static readonly int _viewportId = Shader.PropertyToID("_viewport"); static readonly int _alphaId = Shader.PropertyToID("_alpha"); static readonly int _strokeMultId = Shader.PropertyToID("_strokeMult"); @@ -305,6 +285,7 @@ static void _getShaderPassAndProps( public static PictureFlusher.CmdDraw convexFill(PictureFlusher.RenderLayer layer, uiPaint paint, uiMeshMesh mesh) { var mat = _convexFillMat.getMaterial(paint.blendMode, layer.ignoreClip); + _getShaderPassAndProps(layer, paint, mesh.matrix, 1.0f, 0.0f, out var pass, out var props); return PictureFlusher.CmdDraw.create( @@ -444,7 +425,7 @@ public static PictureFlusher.CmdDraw tex(PictureFlusher.RenderLayer layer, uiPai image.texture.filterMode = paint.filterMode; props.SetTexture(_texId, image.texture); - props.SetInt(_texModeId, image.texture is RenderTexture ? 1 : 0); // pre alpha if RT else post alpha + props.SetInt(_texModeId, image.texture is RenderTexture || image.isDynamic ? 1 : 0); // pre alpha if RT else post alpha return PictureFlusher.CmdDraw.create( mesh: mesh, diff --git a/Runtime/ui/renderer/cmdbufferCanvas/rendering/canvas_shader_initializer.cs b/Runtime/ui/renderer/cmdbufferCanvas/rendering/canvas_shader_initializer.cs new file mode 100644 index 00000000..c124160d --- /dev/null +++ b/Runtime/ui/renderer/cmdbufferCanvas/rendering/canvas_shader_initializer.cs @@ -0,0 +1,80 @@ +using Unity.UIWidgets.editor; +using UnityEngine; +using UnityEngine.Rendering; + +namespace Unity.UIWidgets.ui { + static partial class CanvasShader { + const bool enableDebugLog = false; + + public static bool supportComputeBuffer; + + static void DebugAssert(bool condition, string logMsg) { + if (enableDebugLog && !condition) { + Debug.Log(logMsg); + } + } + + static bool IsShaderSupported() { + return SystemInfo.graphicsDeviceType == GraphicsDeviceType.Metal || + SystemInfo.graphicsDeviceType == GraphicsDeviceType.Vulkan || + SystemInfo.graphicsDeviceType == GraphicsDeviceType.Direct3D12; + } + + static void InitShaders() { + supportComputeBuffer = !WindowConfig.disableComputeBuffer && SystemInfo.supportsComputeShaders && IsShaderSupported(); + + if (!supportComputeBuffer) { + DebugAssert(false, "init default shaders"); + var convexFillShader = GetShader("UIWidgets/canvas_convexFill"); + var fill0Shader = GetShader("UIWidgets/canvas_fill0"); + var fill1Shader = GetShader("UIWidgets/canvas_fill1"); + var stroke0Shader = GetShader("UIWidgets/canvas_stroke0"); + var stroke1Shader = GetShader("UIWidgets/canvas_stroke1"); + var texShader = GetShader("UIWidgets/canvas_tex"); + var stencilShader = GetShader("UIWidgets/canvas_stencil"); + var filterShader = GetShader("UIWidgets/canvas_filter"); + var shadowBoxShader = GetShader("UIWidgets/ShadowBox"); + var shadowRBoxShader = GetShader("UIWidgets/ShadowRBox"); + var strokeAlphaShader = GetShader("UIWidgets/canvas_strokeAlpha"); + + _convexFillMat = new MaterialByBlendModeStencilComp(convexFillShader); + _fill0Mat = new MaterialByStencilComp(fill0Shader); + _fill1Mat = new MaterialByBlendMode(fill1Shader); + _stroke0Mat = new MaterialByBlendModeStencilComp(stroke0Shader); + _stroke1Mat = new Material(stroke1Shader) {hideFlags = HideFlags.HideAndDontSave}; + _strokeAlphaMat = new MaterialByBlendModeStencilComp(strokeAlphaShader); + _texMat = new MaterialByBlendModeStencilComp(texShader); + _stencilMat = new Material(stencilShader) {hideFlags = HideFlags.HideAndDontSave}; + _filterMat = new Material(filterShader) {hideFlags = HideFlags.HideAndDontSave}; + _shadowBox = new Material(shadowBoxShader) {hideFlags = HideFlags.HideAndDontSave}; + _shadowRBox = new Material(shadowRBoxShader) {hideFlags = HideFlags.HideAndDontSave}; + } + else { + DebugAssert(false, "init computebuffer shaders"); + var convexFillShaderCompute = GetShader("UIWidgets/canvas_convexFill_cb"); + var fill0ShaderCompute = GetShader("UIWidgets/canvas_fill0_cb"); + var fill1ShaderCompute = GetShader("UIWidgets/canvas_fill1_cb"); + var stroke0ShaderCompute = GetShader("UIWidgets/canvas_stroke0_cb"); + var stroke1ShaderCompute = GetShader("UIWidgets/canvas_stroke1_cb"); + var texShaderCompute = GetShader("UIWidgets/canvas_tex_cb"); + var stencilShaderCompute = GetShader("UIWidgets/canvas_stencil_cb"); + var filterShaderCompute = GetShader("UIWidgets/canvas_filter_cb"); + var shadowBoxShaderCompute = GetShader("UIWidgets/ShadowBox_cb"); + var shadowRBoxShaderCompute = GetShader("UIWidgets/ShadowRBox_cb"); + var strokeAlphaShaderCompute = GetShader("UIWidgets/canvas_strokeAlpha_cb"); + + _convexFillMat = new MaterialByBlendModeStencilComp(convexFillShaderCompute); + _fill0Mat = new MaterialByStencilComp(fill0ShaderCompute); + _fill1Mat = new MaterialByBlendMode(fill1ShaderCompute); + _stroke0Mat = new MaterialByBlendModeStencilComp(stroke0ShaderCompute); + _stroke1Mat = new Material(stroke1ShaderCompute) {hideFlags = HideFlags.HideAndDontSave}; + _strokeAlphaMat = new MaterialByBlendModeStencilComp(strokeAlphaShaderCompute); + _texMat = new MaterialByBlendModeStencilComp(texShaderCompute); + _stencilMat = new Material(stencilShaderCompute) {hideFlags = HideFlags.HideAndDontSave}; + _filterMat = new Material(filterShaderCompute) {hideFlags = HideFlags.HideAndDontSave}; + _shadowBox = new Material(shadowBoxShaderCompute) {hideFlags = HideFlags.HideAndDontSave}; + _shadowRBox = new Material(shadowRBoxShaderCompute) {hideFlags = HideFlags.HideAndDontSave}; + } + } + } +} \ No newline at end of file diff --git a/Runtime/ui/renderer/cmdbufferCanvas/rendering/canvas_shader_initializer.cs.meta b/Runtime/ui/renderer/cmdbufferCanvas/rendering/canvas_shader_initializer.cs.meta new file mode 100644 index 00000000..80d9d6c8 --- /dev/null +++ b/Runtime/ui/renderer/cmdbufferCanvas/rendering/canvas_shader_initializer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2ac77d972b29f49709bc66afaa7ca199 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/ui/renderer/cmdbufferCanvas/rendering/canvas_shader_utils.cs b/Runtime/ui/renderer/cmdbufferCanvas/rendering/canvas_shader_utils.cs index 2a80eed1..de219ee0 100644 --- a/Runtime/ui/renderer/cmdbufferCanvas/rendering/canvas_shader_utils.cs +++ b/Runtime/ui/renderer/cmdbufferCanvas/rendering/canvas_shader_utils.cs @@ -35,5 +35,9 @@ public void SetInt(int mid, int value) { public void SetFloatArray(int mid, float[] array) { this.mpb.SetFloatArray(mid, array); } + + public void SetBuffer(int mid, ComputeBuffer buffer) { + this.mpb.SetBuffer(mid, buffer); + } } } \ No newline at end of file diff --git a/Runtime/ui/renderer/cmdbufferCanvas/rendering/canvas_shadow_utils.cs b/Runtime/ui/renderer/cmdbufferCanvas/rendering/canvas_shadow_utils.cs index 8d07997b..e630e73d 100644 --- a/Runtime/ui/renderer/cmdbufferCanvas/rendering/canvas_shadow_utils.cs +++ b/Runtime/ui/renderer/cmdbufferCanvas/rendering/canvas_shadow_utils.cs @@ -46,7 +46,7 @@ void _drawRRectShadow(uiPath path, uiPaint paint) { } var bound = path.getBounds(); - var sigma = state.scale * paint.maskFilter.Value.sigma; + var sigma = state.scale * paint.maskFilter.Value.sigma / 3f; var vertices = ObjectPool>.alloc(); vertices.SetCapacity(4); @@ -67,7 +67,8 @@ void _drawRRectShadow(uiPath path, uiPaint paint) { ObjectPool.release(meshBounds); ObjectPool.release(blurMesh); var mesh = uiMeshMesh.create(state.matrix, vertices, _triangles); - layer.draws.Add(CanvasShader.fastShadow(layer, mesh, sigma, path.isRect, path.isCircle, path.rRectCorner, new Vector4(bound.left, bound.top, bound.right, bound.bottom), paint.color)); + var shadowColor = paint.color.withAlpha(128); + layer.draws.Add(CanvasShader.fastShadow(layer, mesh, sigma, path.isRect, path.isCircle, path.rRectCorner, new Vector4(bound.left, bound.top, bound.right, bound.bottom), shadowColor)); } } diff --git a/Runtime/ui/renderer/cmdbufferCanvas/rendering/render_cmd.cs b/Runtime/ui/renderer/cmdbufferCanvas/rendering/render_cmd.cs index f49b76fd..f7c802e8 100644 --- a/Runtime/ui/renderer/cmdbufferCanvas/rendering/render_cmd.cs +++ b/Runtime/ui/renderer/cmdbufferCanvas/rendering/render_cmd.cs @@ -42,6 +42,9 @@ internal class CmdDraw : RenderCmd { public static readonly Matrix3 idMat3 = Matrix3.I(); public static readonly int texId = Shader.PropertyToID("_tex"); public static readonly int matId = Shader.PropertyToID("_mat"); + public static readonly int vertexBufferId = Shader.PropertyToID("databuffer"); + public static readonly int indexBufferId = Shader.PropertyToID("indexbuffer"); + public static readonly int startIndexId = Shader.PropertyToID("_startVertex"); public override void clear() { diff --git a/Runtime/ui/renderer/cmdbufferCanvas/rendering/render_layer.cs b/Runtime/ui/renderer/cmdbufferCanvas/rendering/render_layer.cs index a2d6c368..722eba1f 100644 --- a/Runtime/ui/renderer/cmdbufferCanvas/rendering/render_layer.cs +++ b/Runtime/ui/renderer/cmdbufferCanvas/rendering/render_layer.cs @@ -39,7 +39,8 @@ public Vector4 viewport { public static RenderLayer create(int rtID = 0, int width = 0, int height = 0, FilterMode filterMode = FilterMode.Bilinear, - bool noMSAA = false, uiRect? layerBounds = null, uiPaint? layerPaint = null, bool ignoreClip = true) { + bool noMSAA = false, + uiRect? layerBounds = null, uiPaint? layerPaint = null, bool ignoreClip = true) { D.assert(layerBounds != null); var newLayer = ObjectPool.alloc(); newLayer.rtID = rtID; diff --git a/Runtime/ui/renderer/common/geometry/matrix/ui_matrix.cs b/Runtime/ui/renderer/common/geometry/matrix/ui_matrix.cs index ef5d0b30..76854633 100644 --- a/Runtime/ui/renderer/common/geometry/matrix/ui_matrix.cs +++ b/Runtime/ui/renderer/common/geometry/matrix/ui_matrix.cs @@ -316,7 +316,7 @@ public bool _isFinite() { TypeMask mask = this._getType(); if (0 == (mask & ~(TypeMask.kScale_Mask | TypeMask.kTranslate_Mask))) { - bool invertible = true; + // bool invertible = true; // Fix warning: value is never used if (!invertableCheck) { if ((mask & TypeMask.kScale_Mask) != 0) { diff --git a/Runtime/ui/renderer/common/geometry/matrix/ui_matrix_utils.cs b/Runtime/ui/renderer/common/geometry/matrix/ui_matrix_utils.cs index bc5f690a..5f49db22 100644 --- a/Runtime/ui/renderer/common/geometry/matrix/ui_matrix_utils.cs +++ b/Runtime/ui/renderer/common/geometry/matrix/ui_matrix_utils.cs @@ -4,16 +4,16 @@ namespace Unity.UIWidgets.ui { public partial struct uiMatrix3 { - public void mapPoints(uiOffset[] dst, uiOffset[] src) { + public void mapPoints(ref uiOffset[] dst, ref uiOffset[] src) { D.assert(dst != null && src != null && dst.Length == src.Length); - this._getMapPtsProc()(this, dst, src, src.Length); + this._getMapPtsProc()(this, ref dst, ref src, src.Length); } - public void mapPoints(uiOffset[] pts) { - this.mapPoints(pts, pts); + public void mapPoints(ref uiOffset[] pts) { + this.mapPoints(ref pts, ref pts); } - delegate void MapPtsProc(uiMatrix3 mat, uiOffset[] dst, uiOffset[] src, int count); + delegate void MapPtsProc(uiMatrix3 mat, ref uiOffset[] dst, ref uiOffset[] src, int count); static readonly MapPtsProc[] gMapPtsProcs = { Identity_pts, Trans_pts, @@ -36,7 +36,7 @@ MapPtsProc _getMapPtsProc() { return GetMapPtsProc(this._getType()); } - static void Identity_pts(uiMatrix3 m, uiOffset[] dst, uiOffset[] src, int count) { + static void Identity_pts(uiMatrix3 m, ref uiOffset[] dst, ref uiOffset[] src, int count) { D.assert(m._getType() == 0); if (dst != src && count > 0) { @@ -44,7 +44,7 @@ static void Identity_pts(uiMatrix3 m, uiOffset[] dst, uiOffset[] src, int count) } } - static void Trans_pts(uiMatrix3 m, uiOffset[] dst, uiOffset[] src, int count) { + static void Trans_pts(uiMatrix3 m, ref uiOffset[] dst, ref uiOffset[] src, int count) { D.assert(m._getType() <= TypeMask.kTranslate_Mask); if (count > 0) { var tx = m.getTranslateX(); @@ -55,7 +55,7 @@ static void Trans_pts(uiMatrix3 m, uiOffset[] dst, uiOffset[] src, int count) { } } - static void Scale_pts(uiMatrix3 m, uiOffset[] dst, uiOffset[] src, int count) { + static void Scale_pts(uiMatrix3 m, ref uiOffset[] dst, ref uiOffset[] src, int count) { D.assert(m._getType() <= (TypeMask.kScale_Mask | TypeMask.kTranslate_Mask)); if (count > 0) { var tx = m.getTranslateX(); @@ -69,7 +69,7 @@ static void Scale_pts(uiMatrix3 m, uiOffset[] dst, uiOffset[] src, int count) { } } - static void Persp_pts(uiMatrix3 m, uiOffset[] dst, uiOffset[] src, int count) { + static void Persp_pts(uiMatrix3 m, ref uiOffset[] dst, ref uiOffset[] src, int count) { D.assert(m._hasPerspective()); if (count > 0) { @@ -91,7 +91,7 @@ static void Persp_pts(uiMatrix3 m, uiOffset[] dst, uiOffset[] src, int count) { } } - static void Affine_pts(uiMatrix3 m, uiOffset[] dst, uiOffset[] src, int count) { + static void Affine_pts(uiMatrix3 m, ref uiOffset[] dst, ref uiOffset[] src, int count) { D.assert(m._getType() != TypeMask.kPerspective_Mask); if (count > 0) { var tx = m.getTranslateX(); diff --git a/Runtime/ui/renderer/common/geometry/path/path.cs b/Runtime/ui/renderer/common/geometry/path/path.cs index 37dc421c..82041cdf 100644 --- a/Runtime/ui/renderer/common/geometry/path/path.cs +++ b/Runtime/ui/renderer/common/geometry/path/path.cs @@ -30,10 +30,8 @@ void _updateRRectFlag(bool isNaiveRRect, uiPathShapeHint shapeHint = uiPathShape return; } this._isNaiveRRect = isNaiveRRect && this._hasOnlyMoveTos(); - if (this._isNaiveRRect) { - this._shapeHint = shapeHint; - this._rRectCorner = corner; - } + this._shapeHint = shapeHint; + this._rRectCorner = corner; } bool _hasOnlyMoveTos() { @@ -80,6 +78,8 @@ public override void clear() { this.needCache = false; this.pathKey = 0; this._isNaiveRRect = false; + this._shapeHint = uiPathShapeHint.Other; + this._rRectCorner = 0; } void _reset() { @@ -102,7 +102,7 @@ internal uiPathCache flatten(float scale) { return this._cache; } - var _cache = uiPathCache.create(scale); + var _cache = uiPathCache.create(scale, this._shapeHint); var i = 0; while (i < this._commands.Count) { @@ -170,6 +170,14 @@ public uiRect getBounds() { return uiRectHelper.fromLTRB(this._minX, this._minY, this._maxX, this._maxY); } + public uiRect getBoundsWithMargin(float margin) { + if (this._minX - margin >= this._maxX + margin || this._minY - margin >= this._maxY + margin) { + return uiRectHelper.zero; + } + + return uiRectHelper.fromLTRB(this._minX - margin, this._minY - margin, this._maxX + margin, this._maxY + margin); + } + void _appendMoveTo(float x, float y) { this._commands.Add((float) uiPathCommand.moveTo); this._commands.Add(x); diff --git a/Runtime/ui/renderer/common/geometry/path/path_cache.cs b/Runtime/ui/renderer/common/geometry/path/path_cache.cs index 656d32b4..1ba5d357 100644 --- a/Runtime/ui/renderer/common/geometry/path/path_cache.cs +++ b/Runtime/ui/renderer/common/geometry/path/path_cache.cs @@ -33,11 +33,14 @@ public uiMeshMesh strokeMesh { float _miterLimit; float _fringe; - public static uiPathCache create(float scale) { + uiPath.uiPathShapeHint _shapeHint; + + public static uiPathCache create(float scale, uiPath.uiPathShapeHint shapeHint) { uiPathCache newPathCache = ObjectPool.alloc(); newPathCache._distTol = 0.01f / scale; newPathCache._tessTol = 0.25f / scale; newPathCache._scale = scale; + newPathCache._shapeHint = shapeHint; return newPathCache; } @@ -49,6 +52,10 @@ public bool canReuse(float scale) { return true; } + public bool canSkipAAHairline { + get { return this._shapeHint == uiPath.uiPathShapeHint.Rect; } + } + public override void clear() { this._paths.Clear(); this._points.Clear(); @@ -57,6 +64,8 @@ public override void clear() { ObjectPool.release(this._strokeMesh); this._strokeMesh = null; + + this._shapeHint = uiPath.uiPathShapeHint.Other; } public uiPathCache() { @@ -394,7 +403,7 @@ uiVertexUV _expandStroke(float w, float fringe, StrokeCap lineCap, StrokeJoin li } uiVertexUV _expandFill(float fringe) { - float aa = fringe; + float aa = this.canSkipAAHairline ? 0f : fringe; float woff = aa * 0.5f; var points = this._points; var paths = this._paths; diff --git a/Runtime/ui/renderer/common/geometry/rect.cs b/Runtime/ui/renderer/common/geometry/rect.cs index 588514ac..aa7ea7cb 100644 --- a/Runtime/ui/renderer/common/geometry/rect.cs +++ b/Runtime/ui/renderer/common/geometry/rect.cs @@ -26,6 +26,14 @@ public float height { get { return this.bottom - this.top; } } + public float area { + get { return this.width * this.height; } + } + + public float margin { + get { return this.width + this.height; } + } + public uiOffset topLeft { get { return new uiOffset(this.left, this.top); } } @@ -95,7 +103,10 @@ public uiRect expandToInclude(uiRect? other) { } public static class uiRectHelper { - public static uiRect fromRect(Rect rect) { + public static uiRect? fromRect(Rect rect) { + if (rect == null) { + return null; + } return new uiRect(rect.left, rect.top, rect.right, rect.bottom); } diff --git a/Runtime/ui/renderer/common/picture.cs b/Runtime/ui/renderer/common/picture.cs index 53787156..92ed8da5 100644 --- a/Runtime/ui/renderer/common/picture.cs +++ b/Runtime/ui/renderer/common/picture.cs @@ -1,25 +1,34 @@ using System; using System.Collections.Generic; using Unity.UIWidgets.foundation; +using Unity.UIWidgets.external; namespace Unity.UIWidgets.ui { public class uiPicture : PoolObject { public uiPicture() { } - public static uiPicture create(List drawCmds, uiRect paintBounds) { + public static uiPicture create(List drawCmds, + uiRect paintBounds, + BBoxHierarchy bbh = null, + uiList stateUpdateIndices = null) { var picture = ObjectPool.alloc(); picture.drawCmds = drawCmds; picture.paintBounds = paintBounds; + picture.bbh = bbh; + picture.stateUpdatesIndices = stateUpdateIndices; return picture; } public List drawCmds; public uiRect paintBounds; + public BBoxHierarchy bbh; + public uiList stateUpdatesIndices; public override void clear() { //the recorder will dispose the draw commands this.drawCmds = null; + ObjectPool>.release(this.stateUpdatesIndices); } } @@ -27,6 +36,10 @@ public class uiPictureRecorder { readonly List _drawCmds = new List(128); readonly List _states = new List(32); + + readonly BBoxHierarchy _bbh = new RTree(); + + readonly List _stateUpdateIndices = new List(); public uiPictureRecorder() { this.reset(); @@ -59,15 +72,23 @@ public void reset() { layerOffset = null, paintBounds = uiRectHelper.zero }); + this._bbh.Clear(); + this._stateUpdateIndices.Clear(); } public uiPicture endRecording() { if (this._states.Count > 1) { throw new Exception("unmatched save/restore commands"); } - + + uiList stateUpdateIndices = ObjectPool>.alloc(); + stateUpdateIndices.AddRange(this._stateUpdateIndices); var state = this._getState(); - return uiPicture.create(this._drawCmds, state.paintBounds); + return uiPicture.create( + this._drawCmds, + state.paintBounds, + bbh: this._bbh, + stateUpdateIndices: stateUpdateIndices); } public void addDrawCmd(uiDrawCmd drawCmd) { @@ -76,6 +97,7 @@ public void addDrawCmd(uiDrawCmd drawCmd) { switch (drawCmd) { case uiDrawSave _: this._states.Add(this._getState().copy()); + this._stateUpdateIndices.Add(this._drawCmds.Count - 1); break; case uiDrawSaveLayer cmd: { this._states.Add(new uiCanvasState { @@ -85,6 +107,7 @@ public void addDrawCmd(uiDrawCmd drawCmd) { layerOffset = cmd.rect.Value.topLeft, paintBounds = uiRectHelper.zero }); + this._stateUpdateIndices.Add(this._drawCmds.Count - 1); break; } case uiDrawRestore _: { @@ -102,6 +125,7 @@ public void addDrawCmd(uiDrawCmd drawCmd) { } this._setState(state); + this._stateUpdateIndices.Add(this._drawCmds.Count - 1); break; } case uiDrawTranslate cmd: { @@ -109,6 +133,7 @@ public void addDrawCmd(uiDrawCmd drawCmd) { state.xform = new uiMatrix3(state.xform); state.xform.preTranslate(cmd.dx, cmd.dy); this._setState(state); + this._stateUpdateIndices.Add(this._drawCmds.Count - 1); break; } case uiDrawScale cmd: { @@ -116,6 +141,7 @@ public void addDrawCmd(uiDrawCmd drawCmd) { state.xform = new uiMatrix3(state.xform); state.xform.preScale(cmd.sx, (cmd.sy ?? cmd.sx)); this._setState(state); + this._stateUpdateIndices.Add(this._drawCmds.Count - 1); break; } case uiDrawRotate cmd: { @@ -131,6 +157,7 @@ public void addDrawCmd(uiDrawCmd drawCmd) { } this._setState(state); + this._stateUpdateIndices.Add(this._drawCmds.Count - 1); break; } case uiDrawSkew cmd: { @@ -138,6 +165,7 @@ public void addDrawCmd(uiDrawCmd drawCmd) { state.xform = new uiMatrix3(state.xform); state.xform.preSkew(cmd.sx, cmd.sy); this._setState(state); + this._stateUpdateIndices.Add(this._drawCmds.Count - 1); break; } case uiDrawConcat cmd: { @@ -145,18 +173,21 @@ public void addDrawCmd(uiDrawCmd drawCmd) { state.xform = new uiMatrix3(state.xform); state.xform.preConcat(cmd.matrix.Value); this._setState(state); + this._stateUpdateIndices.Add(this._drawCmds.Count - 1); break; } case uiDrawResetMatrix _: { var state = this._getState(); state.xform = uiMatrix3.I(); this._setState(state); + this._stateUpdateIndices.Add(this._drawCmds.Count - 1); break; } case uiDrawSetMatrix cmd: { var state = this._getState(); state.xform = new uiMatrix3(cmd.matrix.Value); this._setState(state); + this._stateUpdateIndices.Add(this._drawCmds.Count - 1); break; } case uiDrawClipRect cmd: { @@ -165,14 +196,16 @@ public void addDrawCmd(uiDrawCmd drawCmd) { var rect = state.xform.mapRect(cmd.rect.Value); state.scissor = state.scissor == null ? rect : state.scissor.Value.intersect(rect); this._setState(state); + this._stateUpdateIndices.Add(this._drawCmds.Count - 1); break; } case uiDrawClipRRect cmd: { var state = this._getState(); - var rect = state.xform.mapRect(uiRectHelper.fromRect(cmd.rrect.outerRect)); + var rect = state.xform.mapRect(uiRectHelper.fromRect(cmd.rrect.outerRect).Value); state.scissor = state.scissor == null ? rect : state.scissor.Value.intersect(rect); this._setState(state); + this._stateUpdateIndices.Add(this._drawCmds.Count - 1); break; } case uiDrawClipPath cmd: { @@ -188,6 +221,7 @@ public void addDrawCmd(uiDrawCmd drawCmd) { state.scissor = state.scissor == null ? rect : state.scissor.Value.intersect(rect); this._setState(state); ObjectPool.release(transformedMesh); + this._stateUpdateIndices.Add(this._drawCmds.Count - 1); break; } case uiDrawPath cmd: { @@ -228,9 +262,13 @@ public void addDrawCmd(uiDrawCmd drawCmd) { float sigma = scale * paint.maskFilter.Value.sigma; float sigma3 = 3 * sigma; this._addPaintBounds(uiRectHelper.inflate(mesh.bounds, sigma3)); + this._bbh.Insert(new IndexedRect(uiRectHelper.inflate(mesh.bounds, sigma3 + 5), + this._drawCmds.Count - 1)); } else { this._addPaintBounds(mesh.bounds); + this._bbh.Insert(new IndexedRect(uiRectHelper.inflate(mesh.bounds, 5), + this._drawCmds.Count - 1)); } ObjectPool.release(mesh); @@ -242,41 +280,55 @@ public void addDrawCmd(uiDrawCmd drawCmd) { cmd.image.width, cmd.image.height); rect = state.xform.mapRect(rect); this._addPaintBounds(rect); + this._bbh.Insert(new IndexedRect(uiRectHelper.inflate(rect, 5), + this._drawCmds.Count - 1)); break; } case uiDrawImageRect cmd: { var state = this._getState(); var rect = state.xform.mapRect(cmd.dst.Value); this._addPaintBounds(rect); + this._bbh.Insert(new IndexedRect(uiRectHelper.inflate(rect, 5), + this._drawCmds.Count - 1)); break; } case uiDrawImageNine cmd: { var state = this._getState(); var rect = state.xform.mapRect(cmd.dst.Value); this._addPaintBounds(rect); + this._bbh.Insert(new IndexedRect(uiRectHelper.inflate(rect, 5), + this._drawCmds.Count - 1)); break; } case uiDrawPicture cmd: { var state = this._getState(); - var rect = state.xform.mapRect(uiRectHelper.fromRect(cmd.picture.paintBounds)); + var rect = state.xform.mapRect(uiRectHelper.fromRect(cmd.picture.paintBounds).Value); this._addPaintBounds(rect); + this._bbh.Insert(new IndexedRect(uiRectHelper.inflate(rect, 5), + this._drawCmds.Count - 1)); break; } case uiDrawTextBlob cmd: { var state = this._getState(); var scale = uiXformUtils.getScale(state.xform); var rect = uiRectHelper.fromRect( - cmd.textBlob.Value.shiftedBoundsInText(cmd.offset.Value.dx, cmd.offset.Value.dy)); + cmd.textBlob.Value.shiftedBoundsInText(cmd.offset.Value.dx, cmd.offset.Value.dy)).Value; rect = state.xform.mapRect(rect); + this._bbh.Insert(new IndexedRect(uiRectHelper.inflate(rect, 5), + this._drawCmds.Count - 1)); var paint = cmd.paint; if (paint.maskFilter != null && paint.maskFilter.Value.sigma != 0) { float sigma = scale * paint.maskFilter.Value.sigma; float sigma3 = 3 * sigma; this._addPaintBounds(uiRectHelper.inflate(rect, sigma3)); + this._bbh.Insert(new IndexedRect(uiRectHelper.inflate(rect, sigma3 + 5), + this._drawCmds.Count - 1)); } else { this._addPaintBounds(rect); + this._bbh.Insert(new IndexedRect(uiRectHelper.inflate(rect, 5), + this._drawCmds.Count - 1)); } break; diff --git a/Runtime/ui/renderer/compositeCanvas/flow/layer_tree.cs b/Runtime/ui/renderer/compositeCanvas/flow/layer_tree.cs index 206986f3..739ae2e1 100644 --- a/Runtime/ui/renderer/compositeCanvas/flow/layer_tree.cs +++ b/Runtime/ui/renderer/compositeCanvas/flow/layer_tree.cs @@ -22,7 +22,7 @@ public float devicePixelRatio { get { return this._devicePixelRatio; } set { this._devicePixelRatio = value; } } - + int _antiAliasing; public int antiAliasing { diff --git a/Runtime/ui/renderer/compositeCanvas/flow/raster_cache.cs b/Runtime/ui/renderer/compositeCanvas/flow/raster_cache.cs index 04fe4f7b..8e14a774 100644 --- a/Runtime/ui/renderer/compositeCanvas/flow/raster_cache.cs +++ b/Runtime/ui/renderer/compositeCanvas/flow/raster_cache.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using Unity.UIWidgets.editor; using Unity.UIWidgets.foundation; using Unity.UIWidgets.ui; using UnityEngine; @@ -24,14 +25,19 @@ public RasterCacheResult(Image image, Rect logicalRect, float devicePixelRatio) public readonly float devicePixelRatio; public void draw(Canvas canvas) { - var bounds = canvas.getTotalMatrix().mapRect(this.logicalRect).roundOut(this.devicePixelRatio); + var boundRect = canvas.getTotalMatrix().mapRect(this.logicalRect); + var bounds = boundRect.withDevicePixelRatio(this.devicePixelRatio); D.assert(() => { - var textureWidth = Mathf.CeilToInt(bounds.width * this.devicePixelRatio); - var textureHeight = Mathf.CeilToInt(bounds.height * this.devicePixelRatio); - - D.assert(this.image.width == textureWidth); - D.assert(this.image.height == textureHeight); + var boundsInPixel = boundRect.roundOutScale(this.devicePixelRatio); + var textureWidth = Mathf.CeilToInt(boundsInPixel.width); + var textureHeight = Mathf.CeilToInt(boundsInPixel.height); + + //it is possible that there is a minor difference between the bound size and the image size (1 pixel at + //most) due to the roundOut operation when calculating the bounds if the elements in the canvas transform + //is not all integer + D.assert(Mathf.Abs(this.image.width - textureWidth) <= 1); + D.assert(Mathf.Abs(this.image.height - textureHeight) <= 1); return true; }); @@ -53,16 +59,20 @@ internal _RasterCacheKey(Picture picture, Matrix3 matrix, float devicePixelRatio this.picture = picture; this.matrix = new Matrix3(matrix); - D.assert(() => { - var x = this.matrix[2] * devicePixelRatio; - var y = this.matrix[5] * devicePixelRatio; - this.matrix[2] = (x - (int) x) / devicePixelRatio; // x - this.matrix[5] = (y - (int) y) / devicePixelRatio; // y - - D.assert(Mathf.Abs(this.matrix[2]) <= 1e-5); - D.assert(Mathf.Abs(this.matrix[5]) <= 1e-5); - return true; - }); + //This Assertion ensures that the transform of the given view matrix, i.e., dx, dy must be both integers in Skia. + //We disable it because in our PictureLayer.PreRoll and Paint function, we use alignToPixel() to align the view matrix + //before creating RasterCache which cannot meet this constraint due to the involved devicePixelRatio. + //Enable it when we find a way to fix this alignment issue +// D.assert(() => { +// var x = this.matrix[2] * devicePixelRatio; +// var y = this.matrix[5] * devicePixelRatio; +// this.matrix[2] = (x - (int) x) / devicePixelRatio; // x +// this.matrix[5] = (y - (int) y) / devicePixelRatio; // y +// +// D.assert(Mathf.Abs(this.matrix[2]) <= 1e-5); +// D.assert(Mathf.Abs(this.matrix[5]) <= 1e-5); +// return true; +// }); this.matrix[2] = 0.0f; this.matrix[5] = 0.0f; @@ -75,7 +85,7 @@ internal _RasterCacheKey(Picture picture, Matrix3 matrix, float devicePixelRatio public readonly Matrix3 matrix; public readonly float devicePixelRatio; - + public readonly int antiAliasing; public bool Equals(_RasterCacheKey other) { @@ -207,6 +217,10 @@ static bool _canRasterizePicture(Picture picture) { return false; } + if (Window.instance.windowConfig.disableRasterCache) { + return false; + } + var bounds = picture.paintBounds; if (bounds.isEmpty) { return false; @@ -220,21 +234,29 @@ static bool _canRasterizePicture(Picture picture) { return false; } + //https://forum.unity.com/threads/rendertexture-create-failed-rendertexture-too-big.58667/ + if (picture.paintBounds.size.width > WindowConfig.MaxRasterImageSize || + picture.paintBounds.size.height > WindowConfig.MaxRasterImageSize) { + return false; + } + return true; } RasterCacheResult _rasterizePicture(Picture picture, Matrix3 transform, float devicePixelRatio, int antiAliasing, MeshPool meshPool) { - var bounds = transform.mapRect(picture.paintBounds).roundOut(devicePixelRatio); + var boundRect = transform.mapRect(picture.paintBounds); + var bounds = boundRect.withDevicePixelRatio(devicePixelRatio); + var boundsInPixel = boundRect.roundOutScale(devicePixelRatio); var desc = new RenderTextureDescriptor( - Mathf.CeilToInt((bounds.width * devicePixelRatio)), - Mathf.CeilToInt((bounds.height * devicePixelRatio)), + Mathf.CeilToInt(boundsInPixel.width), + Mathf.CeilToInt(boundsInPixel.height), RenderTextureFormat.Default, 24) { useMipMap = false, autoGenerateMips = false, }; - + if (antiAliasing != 0) { desc.msaaSamples = antiAliasing; } diff --git a/Runtime/ui/text.cs b/Runtime/ui/text.cs index ae339682..4afeee1c 100644 --- a/Runtime/ui/text.cs +++ b/Runtime/ui/text.cs @@ -1,5 +1,7 @@ using System; using System.Collections.Generic; +using Unity.UIWidgets.foundation; +using Unity.UIWidgets.painting; namespace Unity.UIWidgets.ui { public enum FontStyle { @@ -96,7 +98,9 @@ class TextStyle : IEquatable { public readonly Color decorationColor; public readonly TextDecorationStyle decorationStyle = kDefaultDecorationStyle; public readonly string fontFamily = kDefaultFontFamily; + public readonly Paint foreground; public readonly Paint background; + public readonly List shadows; internal UnityEngine.Color UnityColor { get { return this.color.toColor(); } @@ -139,7 +143,9 @@ public static TextStyle applyStyle(TextStyle currentStyle, painting.TextStyle st decoration: style.decoration ?? currentStyle.decoration, decorationColor: style.decorationColor ?? currentStyle.decorationColor, fontFamily: style.fontFamily ?? currentStyle.fontFamily, - background: style.background ?? currentStyle.background + foreground: style.foreground ?? currentStyle.foreground, + background: style.background ?? currentStyle.background, + shadows: style.shadows ?? currentStyle.shadows ); } @@ -155,7 +161,9 @@ public static TextStyle applyStyle(TextStyle currentStyle, painting.TextStyle st decoration: style.decoration, decorationColor: style.decorationColor, fontFamily: style.fontFamily, - background: style.background + foreground: style.foreground, + background: style.background, + shadows: style.shadows ); } @@ -175,7 +183,8 @@ public bool Equals(TextStyle other) { Equals(this.decoration, other.decoration) && Equals(this.decorationColor, other.decorationColor) && this.decorationStyle == other.decorationStyle && - string.Equals(this.fontFamily, other.fontFamily); + string.Equals(this.fontFamily, other.fontFamily) && + this.shadows.equalsList(other.shadows); } public override bool Equals(object obj) { @@ -208,6 +217,7 @@ public override int GetHashCode() { hashCode = (hashCode * 397) ^ (this.decorationColor != null ? this.decorationColor.GetHashCode() : 0); hashCode = (hashCode * 397) ^ this.decorationStyle.GetHashCode(); hashCode = (hashCode * 397) ^ (this.fontFamily != null ? this.fontFamily.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (this.shadows != null ? this.shadows.GetHashCode() : 0); return hashCode; } } @@ -221,12 +231,21 @@ public override int GetHashCode() { } - public TextStyle(Color color = null, float? fontSize = null, - FontWeight fontWeight = null, FontStyle? fontStyle = null, float? letterSpacing = null, - float? wordSpacing = null, TextBaseline? textBaseline = null, float? height = null, - TextDecoration decoration = null, TextDecorationStyle? decorationStyle = null, Color decorationColor = null, + public TextStyle(Color color = null, + float? fontSize = null, + FontWeight fontWeight = null, + FontStyle? fontStyle = null, + float? letterSpacing = null, + float? wordSpacing = null, + TextBaseline? textBaseline = null, + float? height = null, + TextDecoration decoration = null, + TextDecorationStyle? decorationStyle = null, + Color decorationColor = null, string fontFamily = null, - Paint background = null + Paint foreground = null, + Paint background = null, + List shadows = null ) { this.color = color ?? this.color; this.fontSize = fontSize ?? this.fontSize; @@ -241,7 +260,9 @@ public TextStyle(Color color = null, float? fontSize = null, this.decorationStyle = decorationStyle ?? this.decorationStyle; this.decorationColor = decorationColor ?? this.decorationColor; this.fontFamily = fontFamily ?? this.fontFamily; + this.foreground = foreground ?? this.foreground; this.background = background ?? this.background; + this.shadows = shadows ?? this.shadows; } } @@ -253,8 +274,9 @@ public ParagraphStyle(TextAlign? textAlign = null, int? maxLines = null, float? fontSize = null, string fontFamily = null, - float? lineHeight = null, // todo - string ellipsis = null) { + float? height = null, // todo + string ellipsis = null, + StrutStyle strutStyle = null) { this.textAlign = textAlign; this.textDirection = textDirection; this.fontWeight = fontWeight; @@ -262,8 +284,9 @@ public ParagraphStyle(TextAlign? textAlign = null, this.maxLines = maxLines; this.fontSize = fontSize; this.fontFamily = fontFamily; - this.lineHeight = lineHeight; + this.height = height; this.ellipsis = ellipsis; + this.strutStyle = strutStyle; } public bool Equals(ParagraphStyle other) { @@ -278,7 +301,7 @@ public bool Equals(ParagraphStyle other) { return this.textAlign == other.textAlign && this.textDirection == other.textDirection && this.fontWeight == other.fontWeight && this.fontStyle == other.fontStyle && this.maxLines == other.maxLines && this.fontSize.Equals(other.fontSize) && - string.Equals(this.fontFamily, other.fontFamily) && this.lineHeight.Equals(other.lineHeight) && + string.Equals(this.fontFamily, other.fontFamily) && this.height.Equals(other.height) && string.Equals(this.ellipsis, other.ellipsis); } @@ -315,7 +338,7 @@ public override int GetHashCode() { hashCode = (hashCode * 397) ^ this.maxLines.GetHashCode(); hashCode = (hashCode * 397) ^ this.fontSize.GetHashCode(); hashCode = (hashCode * 397) ^ (this.fontFamily != null ? this.fontFamily.GetHashCode() : 0); - hashCode = (hashCode * 397) ^ this.lineHeight.GetHashCode(); + hashCode = (hashCode * 397) ^ this.height.GetHashCode(); hashCode = (hashCode * 397) ^ (this.ellipsis != null ? this.ellipsis.GetHashCode() : 0); return hashCode; } @@ -327,7 +350,7 @@ internal TextStyle getTextStyle() { fontStyle: this.fontStyle, fontFamily: this.fontFamily, fontSize: this.fontSize, - height: this.lineHeight + height: this.height ); } @@ -342,8 +365,9 @@ public TextAlign TextAlign { public readonly int? maxLines; public readonly float? fontSize; public readonly string fontFamily; - public readonly float? lineHeight; + public readonly float? height; public readonly string ellipsis; + public readonly StrutStyle strutStyle; public bool ellipsized() { return !string.IsNullOrEmpty(this.ellipsis); @@ -433,23 +457,18 @@ public class FontWeight : IEquatable { public readonly int index; - public static readonly FontWeight w100 = new FontWeight(0); - public static readonly FontWeight w200 = new FontWeight(1); - public static readonly FontWeight w300 = new FontWeight(2); - public static readonly FontWeight w400 = new FontWeight(3); - public static readonly FontWeight w500 = new FontWeight(4); - public static readonly FontWeight w600 = new FontWeight(5); - - public static readonly FontWeight w700 = new FontWeight(6); - - public static readonly FontWeight w800 = new FontWeight(7); - - public static readonly FontWeight w900 = new FontWeight(8); - - + public static readonly FontWeight w100 = new FontWeight(0); // Ultralight + public static readonly FontWeight w200 = new FontWeight(1); // Thin + public static readonly FontWeight w300 = new FontWeight(2); // Light + public static readonly FontWeight w400 = new FontWeight(3); // Regular + public static readonly FontWeight w500 = new FontWeight(4); // Medium + public static readonly FontWeight w600 = new FontWeight(5); // Semibold + public static readonly FontWeight w700 = new FontWeight(6); // Bold + public static readonly FontWeight w800 = new FontWeight(7); // Heavy + public static readonly FontWeight w900 = new FontWeight(8); // Black + public static readonly FontWeight normal = w400; - public static readonly FontWeight bold = w700; public static readonly List values = new List { diff --git a/Runtime/ui/txt/emoji.cs b/Runtime/ui/txt/emoji.cs index c6bb4342..b1a91dec 100644 --- a/Runtime/ui/txt/emoji.cs +++ b/Runtime/ui/txt/emoji.cs @@ -4,16 +4,451 @@ using UnityEngine; namespace Unity.UIWidgets.ui { + + public class EmojiResourceConfiguration { + public readonly string spriteSheetAssetName; + public readonly Dictionary emojiLookupTable; + public readonly int spriteSheetNumberOfRows; + public readonly int spriteSheetNumberOfColumns; + + public EmojiResourceConfiguration( + string spriteSheetAssetName, + List emojiCodes, + int spriteSheetNumberOfRows, + int spriteSheetNumberOfColumns + ) { + D.assert(spriteSheetAssetName != null); + D.assert(emojiCodes != null && emojiCodes.isNotEmpty()); + D.assert(spriteSheetNumberOfColumns > 0); + D.assert(spriteSheetNumberOfRows > 0); + D.assert(emojiCodes.Count <= spriteSheetNumberOfColumns * spriteSheetNumberOfRows); + this.spriteSheetAssetName = spriteSheetAssetName; + this.emojiLookupTable = new Dictionary(); + for (int i = 0; i < emojiCodes.Count; i++) { + this.emojiLookupTable[emojiCodes[i]] = i; + } + this.spriteSheetNumberOfRows = spriteSheetNumberOfRows; + this.spriteSheetNumberOfColumns = spriteSheetNumberOfColumns; + } + } + public class EmojiUtils { - static Image _image; + public static readonly EmojiResourceConfiguration googleEmojiConfiguration = new EmojiResourceConfiguration ( + "images/EmojiGoogle", + emojiCodes: new List { + 0x1f004, 0x1f0cf, 0x1f170, 0x1f171, 0x1f17e, 0x1f17f, 0x1f18e, + 0x1f191, 0x1f192, 0x1f193, 0x1f194, 0x1f195, 0x1f196, 0x1f197, + 0x1f198, 0x1f199, 0x1f19a, 0x1f1e6, 0x1f1e7, 0x1f1e8, 0x1f1e9, + 0x1f1ea, 0x1f1eb, 0x1f1ec, 0x1f1ed, 0x1f1ee, 0x1f1ef, 0x1f1f0, + 0x1f1f1, 0x1f1f2, 0x1f1f3, 0x1f1f4, 0x1f1f5, 0x1f1f6, 0x1f1f7, + 0x1f1f8, 0x1f1f9, 0x1f1fa, 0x1f1fb, 0x1f1fc, 0x1f1fd, 0x1f1fe, + 0x1f1ff, 0x1f201, 0x1f202, 0x1f21a, 0x1f22f, 0x1f232, 0x1f233, + 0x1f234, 0x1f235, 0x1f236, 0x1f237, 0x1f238, 0x1f239, 0x1f23a, + 0x1f250, 0x1f251, 0x1f300, 0x1f301, 0x1f302, 0x1f303, 0x1f304, + 0x1f305, 0x1f306, 0x1f307, 0x1f308, 0x1f309, 0x1f30a, 0x1f30b, + 0x1f30c, 0x1f30d, 0x1f30e, 0x1f30f, 0x1f310, 0x1f311, 0x1f312, + 0x1f313, 0x1f314, 0x1f315, 0x1f316, 0x1f317, 0x1f318, 0x1f319, + 0x1f31a, 0x1f31b, 0x1f31c, 0x1f31d, 0x1f31e, 0x1f31f, 0x1f320, + 0x1f321, 0x1f324, 0x1f325, 0x1f326, 0x1f327, 0x1f328, 0x1f329, + 0x1f32a, 0x1f32b, 0x1f32c, 0x1f32d, 0x1f32e, 0x1f32f, 0x1f330, + 0x1f331, 0x1f332, 0x1f333, 0x1f334, 0x1f335, 0x1f336, 0x1f337, + 0x1f338, 0x1f339, 0x1f33a, 0x1f33b, 0x1f33c, 0x1f33d, 0x1f33e, + 0x1f33f, 0x1f340, 0x1f341, 0x1f342, 0x1f343, 0x1f344, 0x1f345, + 0x1f346, 0x1f347, 0x1f348, 0x1f349, 0x1f34a, 0x1f34b, 0x1f34c, + 0x1f34d, 0x1f34e, 0x1f34f, 0x1f350, 0x1f351, 0x1f352, 0x1f353, + 0x1f354, 0x1f355, 0x1f356, 0x1f357, 0x1f358, 0x1f359, 0x1f35a, + 0x1f35b, 0x1f35c, 0x1f35d, 0x1f35e, 0x1f35f, 0x1f360, 0x1f361, + 0x1f362, 0x1f363, 0x1f364, 0x1f365, 0x1f366, 0x1f367, 0x1f368, + 0x1f369, 0x1f36a, 0x1f36b, 0x1f36c, 0x1f36d, 0x1f36e, 0x1f36f, + 0x1f370, 0x1f371, 0x1f372, 0x1f373, 0x1f374, 0x1f375, 0x1f376, + 0x1f377, 0x1f378, 0x1f379, 0x1f37a, 0x1f37b, 0x1f37c, 0x1f37d, + 0x1f37e, 0x1f37f, 0x1f380, 0x1f381, 0x1f382, 0x1f383, 0x1f384, + 0x1f385, 0x1f386, 0x1f387, 0x1f388, 0x1f389, 0x1f38a, 0x1f38b, + 0x1f38c, 0x1f38d, 0x1f38e, 0x1f38f, 0x1f390, 0x1f391, 0x1f392, + 0x1f393, 0x1f396, 0x1f397, 0x1f399, 0x1f39a, 0x1f39b, 0x1f39e, + 0x1f39f, 0x1f3a0, 0x1f3a1, 0x1f3a2, 0x1f3a3, 0x1f3a4, 0x1f3a5, + 0x1f3a6, 0x1f3a7, 0x1f3a8, 0x1f3a9, 0x1f3aa, 0x1f3ab, 0x1f3ac, + 0x1f3ad, 0x1f3ae, 0x1f3af, 0x1f3b0, 0x1f3b1, 0x1f3b2, 0x1f3b3, + 0x1f3b4, 0x1f3b5, 0x1f3b6, 0x1f3b7, 0x1f3b8, 0x1f3b9, 0x1f3ba, + 0x1f3bb, 0x1f3bc, 0x1f3bd, 0x1f3be, 0x1f3bf, 0x1f3c0, 0x1f3c1, + 0x1f3c2, 0x1f3c3, 0x1f3c4, 0x1f3c5, 0x1f3c6, 0x1f3c7, 0x1f3c8, + 0x1f3c9, 0x1f3ca, 0x1f3cb, 0x1f3cc, 0x1f3cd, 0x1f3ce, 0x1f3cf, + 0x1f3d0, 0x1f3d1, 0x1f3d2, 0x1f3d3, 0x1f3d4, 0x1f3d5, 0x1f3d6, + 0x1f3d7, 0x1f3d8, 0x1f3d9, 0x1f3da, 0x1f3db, 0x1f3dc, 0x1f3dd, + 0x1f3de, 0x1f3df, 0x1f3e0, 0x1f3e1, 0x1f3e2, 0x1f3e3, 0x1f3e4, + 0x1f3e5, 0x1f3e6, 0x1f3e7, 0x1f3e8, 0x1f3e9, 0x1f3ea, 0x1f3eb, + 0x1f3ec, 0x1f3ed, 0x1f3ee, 0x1f3ef, 0x1f3f0, 0x1f3f3, 0x1f3f4, + 0x1f3f5, 0x1f3f7, 0x1f3f8, 0x1f3f9, 0x1f3fa, 0x1f3fb, 0x1f3fc, + 0x1f3fd, 0x1f3fe, 0x1f3ff, 0x1f400, 0x1f401, 0x1f402, 0x1f403, + 0x1f404, 0x1f405, 0x1f406, 0x1f407, 0x1f408, 0x1f409, 0x1f40a, + 0x1f40b, 0x1f40c, 0x1f40d, 0x1f40e, 0x1f40f, 0x1f410, 0x1f411, + 0x1f412, 0x1f413, 0x1f414, 0x1f415, 0x1f416, 0x1f417, 0x1f418, + 0x1f419, 0x1f41a, 0x1f41b, 0x1f41c, 0x1f41d, 0x1f41e, 0x1f41f, + 0x1f420, 0x1f421, 0x1f422, 0x1f423, 0x1f424, 0x1f425, 0x1f426, + 0x1f427, 0x1f428, 0x1f429, 0x1f42a, 0x1f42b, 0x1f42c, 0x1f42d, + 0x1f42e, 0x1f42f, 0x1f430, 0x1f431, 0x1f432, 0x1f433, 0x1f434, + 0x1f435, 0x1f436, 0x1f437, 0x1f438, 0x1f439, 0x1f43a, 0x1f43b, + 0x1f43c, 0x1f43d, 0x1f43e, 0x1f43f, 0x1f440, 0x1f441, 0x1f442, + 0x1f443, 0x1f444, 0x1f445, 0x1f446, 0x1f447, 0x1f448, 0x1f449, + 0x1f44a, 0x1f44b, 0x1f44c, 0x1f44d, 0x1f44e, 0x1f44f, 0x1f450, + 0x1f451, 0x1f452, 0x1f453, 0x1f454, 0x1f455, 0x1f456, 0x1f457, + 0x1f458, 0x1f459, 0x1f45a, 0x1f45b, 0x1f45c, 0x1f45d, 0x1f45e, + 0x1f45f, 0x1f460, 0x1f461, 0x1f462, 0x1f463, 0x1f464, 0x1f465, + 0x1f466, 0x1f467, 0x1f468, 0x1f469, 0x1f46a, 0x1f46b, 0x1f46c, + 0x1f46d, 0x1f46e, 0x1f46f, 0x1f470, 0x1f471, 0x1f472, 0x1f473, + 0x1f474, 0x1f475, 0x1f476, 0x1f477, 0x1f478, 0x1f479, 0x1f47a, + 0x1f47b, 0x1f47c, 0x1f47d, 0x1f47e, 0x1f47f, 0x1f480, 0x1f481, + 0x1f482, 0x1f483, 0x1f484, 0x1f485, 0x1f486, 0x1f487, 0x1f488, + 0x1f489, 0x1f48a, 0x1f48b, 0x1f48c, 0x1f48d, 0x1f48e, 0x1f48f, + 0x1f490, 0x1f491, 0x1f492, 0x1f493, 0x1f494, 0x1f495, 0x1f496, + 0x1f497, 0x1f498, 0x1f499, 0x1f49a, 0x1f49b, 0x1f49c, 0x1f49d, + 0x1f49e, 0x1f49f, 0x1f4a0, 0x1f4a1, 0x1f4a2, 0x1f4a3, 0x1f4a4, + 0x1f4a5, 0x1f4a6, 0x1f4a7, 0x1f4a8, 0x1f4a9, 0x1f4aa, 0x1f4ab, + 0x1f4ac, 0x1f4ad, 0x1f4ae, 0x1f4af, 0x1f4b0, 0x1f4b1, 0x1f4b2, + 0x1f4b3, 0x1f4b4, 0x1f4b5, 0x1f4b6, 0x1f4b7, 0x1f4b8, 0x1f4b9, + 0x1f4ba, 0x1f4bb, 0x1f4bc, 0x1f4bd, 0x1f4be, 0x1f4bf, 0x1f4c0, + 0x1f4c1, 0x1f4c2, 0x1f4c3, 0x1f4c4, 0x1f4c5, 0x1f4c6, 0x1f4c7, + 0x1f4c8, 0x1f4c9, 0x1f4ca, 0x1f4cb, 0x1f4cc, 0x1f4cd, 0x1f4ce, + 0x1f4cf, 0x1f4d0, 0x1f4d1, 0x1f4d2, 0x1f4d3, 0x1f4d4, 0x1f4d5, + 0x1f4d6, 0x1f4d7, 0x1f4d8, 0x1f4d9, 0x1f4da, 0x1f4db, 0x1f4dc, + 0x1f4dd, 0x1f4de, 0x1f4df, 0x1f4e0, 0x1f4e1, 0x1f4e2, 0x1f4e3, + 0x1f4e4, 0x1f4e5, 0x1f4e6, 0x1f4e7, 0x1f4e8, 0x1f4e9, 0x1f4ea, + 0x1f4eb, 0x1f4ec, 0x1f4ed, 0x1f4ee, 0x1f4ef, 0x1f4f0, 0x1f4f1, + 0x1f4f2, 0x1f4f3, 0x1f4f4, 0x1f4f5, 0x1f4f6, 0x1f4f7, 0x1f4f8, + 0x1f4f9, 0x1f4fa, 0x1f4fb, 0x1f4fc, 0x1f4fd, 0x1f4ff, 0x1f500, + 0x1f501, 0x1f502, 0x1f503, 0x1f504, 0x1f505, 0x1f506, 0x1f507, + 0x1f508, 0x1f509, 0x1f50a, 0x1f50b, 0x1f50c, 0x1f50d, 0x1f50e, + 0x1f50f, 0x1f510, 0x1f511, 0x1f512, 0x1f513, 0x1f514, 0x1f515, + 0x1f516, 0x1f517, 0x1f518, 0x1f519, 0x1f51a, 0x1f51b, 0x1f51c, + 0x1f51d, 0x1f51e, 0x1f51f, 0x1f520, 0x1f521, 0x1f522, 0x1f523, + 0x1f524, 0x1f525, 0x1f526, 0x1f527, 0x1f528, 0x1f529, 0x1f52a, + 0x1f52b, 0x1f52c, 0x1f52d, 0x1f52e, 0x1f52f, 0x1f530, 0x1f531, + 0x1f532, 0x1f533, 0x1f534, 0x1f535, 0x1f536, 0x1f537, 0x1f538, + 0x1f539, 0x1f53a, 0x1f53b, 0x1f53c, 0x1f53d, 0x1f549, 0x1f54a, + 0x1f54b, 0x1f54c, 0x1f54d, 0x1f54e, 0x1f550, 0x1f551, 0x1f552, + 0x1f553, 0x1f554, 0x1f555, 0x1f556, 0x1f557, 0x1f558, 0x1f559, + 0x1f55a, 0x1f55b, 0x1f55c, 0x1f55d, 0x1f55e, 0x1f55f, 0x1f560, + 0x1f561, 0x1f562, 0x1f563, 0x1f564, 0x1f565, 0x1f566, 0x1f567, + 0x1f56f, 0x1f570, 0x1f573, 0x1f574, 0x1f575, 0x1f576, 0x1f577, + 0x1f578, 0x1f579, 0x1f57a, 0x1f587, 0x1f58a, 0x1f58b, 0x1f58c, + 0x1f58d, 0x1f590, 0x1f595, 0x1f596, 0x1f5a4, 0x1f5a5, 0x1f5a8, + 0x1f5b1, 0x1f5b2, 0x1f5bc, 0x1f5c2, 0x1f5c3, 0x1f5c4, 0x1f5d1, + 0x1f5d2, 0x1f5d3, 0x1f5dc, 0x1f5dd, 0x1f5de, 0x1f5e1, 0x1f5e3, + 0x1f5e8, 0x1f5ef, 0x1f5f3, 0x1f5fa, 0x1f5fb, 0x1f5fc, 0x1f5fd, + 0x1f5fe, 0x1f5ff, 0x1f600, 0x1f601, 0x1f602, 0x1f603, 0x1f604, + 0x1f605, 0x1f606, 0x1f607, 0x1f608, 0x1f609, 0x1f60a, 0x1f60b, + 0x1f60c, 0x1f60d, 0x1f60e, 0x1f60f, 0x1f610, 0x1f611, 0x1f612, + 0x1f613, 0x1f614, 0x1f615, 0x1f616, 0x1f617, 0x1f618, 0x1f619, + 0x1f61a, 0x1f61b, 0x1f61c, 0x1f61d, 0x1f61e, 0x1f61f, 0x1f620, + 0x1f621, 0x1f622, 0x1f623, 0x1f624, 0x1f625, 0x1f626, 0x1f627, + 0x1f628, 0x1f629, 0x1f62a, 0x1f62b, 0x1f62c, 0x1f62d, 0x1f62e, + 0x1f62f, 0x1f630, 0x1f631, 0x1f632, 0x1f633, 0x1f634, 0x1f635, + 0x1f636, 0x1f637, 0x1f638, 0x1f639, 0x1f63a, 0x1f63b, 0x1f63c, + 0x1f63d, 0x1f63e, 0x1f63f, 0x1f640, 0x1f641, 0x1f642, 0x1f643, + 0x1f644, 0x1f645, 0x1f646, 0x1f647, 0x1f648, 0x1f649, 0x1f64a, + 0x1f64b, 0x1f64c, 0x1f64d, 0x1f64e, 0x1f64f, 0x1f680, 0x1f681, + 0x1f682, 0x1f683, 0x1f684, 0x1f685, 0x1f686, 0x1f687, 0x1f688, + 0x1f689, 0x1f68a, 0x1f68b, 0x1f68c, 0x1f68d, 0x1f68e, 0x1f68f, + 0x1f690, 0x1f691, 0x1f692, 0x1f693, 0x1f694, 0x1f695, 0x1f696, + 0x1f697, 0x1f698, 0x1f699, 0x1f69a, 0x1f69b, 0x1f69c, 0x1f69d, + 0x1f69e, 0x1f69f, 0x1f6a0, 0x1f6a1, 0x1f6a2, 0x1f6a3, 0x1f6a4, + 0x1f6a5, 0x1f6a6, 0x1f6a7, 0x1f6a8, 0x1f6a9, 0x1f6aa, 0x1f6ab, + 0x1f6ac, 0x1f6ad, 0x1f6ae, 0x1f6af, 0x1f6b0, 0x1f6b1, 0x1f6b2, + 0x1f6b3, 0x1f6b4, 0x1f6b5, 0x1f6b6, 0x1f6b7, 0x1f6b8, 0x1f6b9, + 0x1f6ba, 0x1f6bb, 0x1f6bc, 0x1f6bd, 0x1f6be, 0x1f6bf, 0x1f6c0, + 0x1f6c1, 0x1f6c2, 0x1f6c3, 0x1f6c4, 0x1f6c5, 0x1f6cb, 0x1f6cc, + 0x1f6cd, 0x1f6ce, 0x1f6cf, 0x1f6d0, 0x1f6d1, 0x1f6d2, 0x1f6d5, + 0x1f6e0, 0x1f6e1, 0x1f6e2, 0x1f6e3, 0x1f6e4, 0x1f6e5, 0x1f6e9, + 0x1f6eb, 0x1f6ec, 0x1f6f0, 0x1f6f3, 0x1f6f4, 0x1f6f5, 0x1f6f6, + 0x1f6f7, 0x1f6f8, 0x1f6f9, 0x1f6fa, 0x1f7e0, 0x1f7e1, 0x1f7e2, + 0x1f7e3, 0x1f7e4, 0x1f7e5, 0x1f7e6, 0x1f7e7, 0x1f7e8, 0x1f7e9, + 0x1f7ea, 0x1f7eb, 0x1f90d, 0x1f90e, 0x1f90f, 0x1f910, 0x1f911, + 0x1f912, 0x1f913, 0x1f914, 0x1f915, 0x1f916, 0x1f917, 0x1f918, + 0x1f919, 0x1f91a, 0x1f91b, 0x1f91c, 0x1f91d, 0x1f91e, 0x1f91f, + 0x1f920, 0x1f921, 0x1f922, 0x1f923, 0x1f924, 0x1f925, 0x1f926, + 0x1f927, 0x1f928, 0x1f929, 0x1f92a, 0x1f92b, 0x1f92c, 0x1f92d, + 0x1f92e, 0x1f92f, 0x1f930, 0x1f931, 0x1f932, 0x1f933, 0x1f934, + 0x1f935, 0x1f936, 0x1f937, 0x1f938, 0x1f939, 0x1f93a, 0x1f93c, + 0x1f93d, 0x1f93e, 0x1f93f, 0x1f940, 0x1f941, 0x1f942, 0x1f943, + 0x1f944, 0x1f945, 0x1f947, 0x1f948, 0x1f949, 0x1f94a, 0x1f94b, + 0x1f94c, 0x1f94d, 0x1f94e, 0x1f94f, 0x1f950, 0x1f951, 0x1f952, + 0x1f953, 0x1f954, 0x1f955, 0x1f956, 0x1f957, 0x1f958, 0x1f959, + 0x1f95a, 0x1f95b, 0x1f95c, 0x1f95d, 0x1f95e, 0x1f95f, 0x1f960, + 0x1f961, 0x1f962, 0x1f963, 0x1f964, 0x1f965, 0x1f966, 0x1f967, + 0x1f968, 0x1f969, 0x1f96a, 0x1f96b, 0x1f96c, 0x1f96d, 0x1f96e, + 0x1f96f, 0x1f970, 0x1f971, 0x1f973, 0x1f974, 0x1f975, 0x1f976, + 0x1f97a, 0x1f97b, 0x1f97c, 0x1f97d, 0x1f97e, 0x1f97f, 0x1f980, + 0x1f981, 0x1f982, 0x1f983, 0x1f984, 0x1f985, 0x1f986, 0x1f987, + 0x1f988, 0x1f989, 0x1f98a, 0x1f98b, 0x1f98c, 0x1f98d, 0x1f98e, + 0x1f98f, 0x1f990, 0x1f991, 0x1f992, 0x1f993, 0x1f994, 0x1f995, + 0x1f996, 0x1f997, 0x1f998, 0x1f999, 0x1f99a, 0x1f99b, 0x1f99c, + 0x1f99d, 0x1f99e, 0x1f99f, 0x1f9a0, 0x1f9a1, 0x1f9a2, 0x1f9a5, + 0x1f9a6, 0x1f9a7, 0x1f9a8, 0x1f9a9, 0x1f9aa, 0x1f9ae, 0x1f9af, + 0x1f9b0, 0x1f9b1, 0x1f9b2, 0x1f9b3, 0x1f9b4, 0x1f9b5, 0x1f9b6, + 0x1f9b7, 0x1f9b8, 0x1f9b9, 0x1f9ba, 0x1f9bb, 0x1f9bc, 0x1f9bd, + 0x1f9be, 0x1f9bf, 0x1f9c0, 0x1f9c1, 0x1f9c2, 0x1f9c3, 0x1f9c4, + 0x1f9c5, 0x1f9c6, 0x1f9c7, 0x1f9c8, 0x1f9c9, 0x1f9ca, 0x1f9cd, + 0x1f9ce, 0x1f9cf, 0x1f9d0, 0x1f9d1, 0x1f9d2, 0x1f9d3, 0x1f9d4, + 0x1f9d5, 0x1f9d6, 0x1f9d7, 0x1f9d8, 0x1f9d9, 0x1f9da, 0x1f9db, + 0x1f9dc, 0x1f9dd, 0x1f9de, 0x1f9df, 0x1f9e0, 0x1f9e1, 0x1f9e2, + 0x1f9e3, 0x1f9e4, 0x1f9e5, 0x1f9e6, 0x1f9e7, 0x1f9e8, 0x1f9e9, + 0x1f9ea, 0x1f9eb, 0x1f9ec, 0x1f9ed, 0x1f9ee, 0x1f9ef, 0x1f9f0, + 0x1f9f1, 0x1f9f2, 0x1f9f3, 0x1f9f4, 0x1f9f5, 0x1f9f6, 0x1f9f7, + 0x1f9f8, 0x1f9f9, 0x1f9fa, 0x1f9fb, 0x1f9fc, 0x1f9fd, 0x1f9fe, + 0x1f9ff, 0x1fa70, 0x1fa71, 0x1fa72, 0x1fa73, 0x1fa78, 0x1fa79, + 0x1fa7a, 0x1fa80, 0x1fa81, 0x1fa82, 0x1fa90, 0x1fa91, 0x1fa92, + 0x1fa93, 0x1fa94, 0x1fa95, 0x203c, 0x2049, 0x20e3, 0x2122, + 0x2139, 0x2194, 0x2195, 0x2196, 0x2197, 0x2198, 0x2199, + 0x21a9, 0x21aa, 0x231a, 0x231b, 0x2328, 0x23cf, 0x23e9, + 0x23ea, 0x23eb, 0x23ec, 0x23ed, 0x23ee, 0x23ef, 0x23f0, + 0x23f1, 0x23f2, 0x23f3, 0x23f8, 0x23f9, 0x23fa, 0x24c2, + 0x25aa, 0x25ab, 0x25b6, 0x25c0, 0x25fb, 0x25fc, 0x25fd, + 0x25fe, 0x2600, 0x2601, 0x2602, 0x2603, 0x2604, 0x260e, + 0x2611, 0x2614, 0x2615, 0x2618, 0x261d, 0x2620, 0x2622, + 0x2623, 0x2626, 0x262a, 0x262e, 0x262f, 0x2638, 0x2639, + 0x263a, 0x2640, 0x2642, 0x2648, 0x2649, 0x264a, 0x264b, + 0x264c, 0x264d, 0x264e, 0x264f, 0x2650, 0x2651, 0x2652, + 0x2653, 0x265f, 0x2660, 0x2663, 0x2665, 0x2666, 0x2668, + 0x267b, 0x267e, 0x267f, 0x2692, 0x2693, 0x2694, 0x2695, + 0x2696, 0x2697, 0x2699, 0x269b, 0x269c, 0x26a0, 0x26a1, + 0x26aa, 0x26ab, 0x26b0, 0x26b1, 0x26bd, 0x26be, 0x26c4, + 0x26c5, 0x26c8, 0x26ce, 0x26cf, 0x26d1, 0x26d3, 0x26d4, + 0x26e9, 0x26ea, 0x26f0, 0x26f1, 0x26f2, 0x26f3, 0x26f4, + 0x26f5, 0x26f7, 0x26f8, 0x26f9, 0x26fa, 0x26fd, 0x2702, + 0x2705, 0x2708, 0x2709, 0x270a, 0x270b, 0x270c, 0x270d, + 0x270f, 0x2712, 0x2714, 0x2716, 0x271d, 0x2721, 0x2728, + 0x2733, 0x2734, 0x2744, 0x2747, 0x274c, 0x274e, 0x2753, + 0x2754, 0x2755, 0x2757, 0x2763, 0x2764, 0x2795, 0x2796, + 0x2797, 0x27a1, 0x27b0, 0x27bf, 0x2934, 0x2935, 0x2b05, + 0x2b06, 0x2b07, 0x2b1b, 0x2b1c, 0x2b50, 0x2b55, 0x3030, + 0x303d, 0x3297, 0x3299, 0xa9, 0xae, 0xfe0f + }, + spriteSheetNumberOfRows: 36, + spriteSheetNumberOfColumns: 37 + ); + + public static readonly EmojiResourceConfiguration appleEmojiConfiguration = new EmojiResourceConfiguration( + "images/EmojiIOS13.2", + emojiCodes: new List { + 0x1f004, 0x1f0cf, 0x1f170, 0x1f171, 0x1f17e, 0x1f17f, 0x1f18e, + 0x1f191, 0x1f192, 0x1f193, 0x1f194, 0x1f195, 0x1f196, 0x1f197, + 0x1f198, 0x1f199, 0x1f19a, 0x1f201, 0x1f202, 0x1f21a, 0x1f22f, + 0x1f232, 0x1f233, 0x1f234, 0x1f235, 0x1f236, 0x1f237, 0x1f238, + 0x1f239, 0x1f23a, 0x1f250, 0x1f251, 0x1f300, 0x1f301, 0x1f302, + 0x1f303, 0x1f304, 0x1f305, 0x1f306, 0x1f307, 0x1f308, 0x1f309, + 0x1f30a, 0x1f30b, 0x1f30c, 0x1f30d, 0x1f30e, 0x1f30f, 0x1f310, + 0x1f311, 0x1f312, 0x1f313, 0x1f314, 0x1f315, 0x1f316, 0x1f317, + 0x1f318, 0x1f319, 0x1f31a, 0x1f31b, 0x1f31c, 0x1f31d, 0x1f31e, + 0x1f31f, 0x1f320, 0x1f321, 0x1f324, 0x1f325, 0x1f326, 0x1f327, + 0x1f328, 0x1f329, 0x1f32a, 0x1f32b, 0x1f32c, 0x1f32d, 0x1f32e, + 0x1f32f, 0x1f330, 0x1f331, 0x1f332, 0x1f333, 0x1f334, 0x1f335, + 0x1f336, 0x1f337, 0x1f338, 0x1f339, 0x1f33a, 0x1f33b, 0x1f33c, + 0x1f33d, 0x1f33e, 0x1f33f, 0x1f340, 0x1f341, 0x1f342, 0x1f343, + 0x1f344, 0x1f345, 0x1f346, 0x1f347, 0x1f348, 0x1f349, 0x1f34a, + 0x1f34b, 0x1f34c, 0x1f34d, 0x1f34e, 0x1f34f, 0x1f350, 0x1f351, + 0x1f352, 0x1f353, 0x1f354, 0x1f355, 0x1f356, 0x1f357, 0x1f358, + 0x1f359, 0x1f35a, 0x1f35b, 0x1f35c, 0x1f35d, 0x1f35e, 0x1f35f, + 0x1f360, 0x1f361, 0x1f362, 0x1f363, 0x1f364, 0x1f365, 0x1f366, + 0x1f367, 0x1f368, 0x1f369, 0x1f36a, 0x1f36b, 0x1f36c, 0x1f36d, + 0x1f36e, 0x1f36f, 0x1f370, 0x1f371, 0x1f372, 0x1f373, 0x1f374, + 0x1f375, 0x1f376, 0x1f377, 0x1f378, 0x1f379, 0x1f37a, 0x1f37b, + 0x1f37c, 0x1f37d, 0x1f37e, 0x1f37f, 0x1f380, 0x1f381, 0x1f382, + 0x1f383, 0x1f384, 0x1f385, 0x1f386, 0x1f387, 0x1f388, 0x1f389, + 0x1f38a, 0x1f38b, 0x1f38c, 0x1f38d, 0x1f38e, 0x1f38f, 0x1f390, + 0x1f391, 0x1f392, 0x1f393, 0x1f396, 0x1f397, 0x1f399, 0x1f39a, + 0x1f39b, 0x1f39e, 0x1f39f, 0x1f3a0, 0x1f3a1, 0x1f3a2, 0x1f3a3, + 0x1f3a4, 0x1f3a5, 0x1f3a6, 0x1f3a7, 0x1f3a8, 0x1f3a9, 0x1f3aa, + 0x1f3ab, 0x1f3ac, 0x1f3ad, 0x1f3ae, 0x1f3af, 0x1f3b0, 0x1f3b1, + 0x1f3b2, 0x1f3b3, 0x1f3b4, 0x1f3b5, 0x1f3b6, 0x1f3b7, 0x1f3b8, + 0x1f3b9, 0x1f3ba, 0x1f3bb, 0x1f3bc, 0x1f3bd, 0x1f3be, 0x1f3bf, + 0x1f3c0, 0x1f3c1, 0x1f3c2, 0x1f3c3, 0x1f3c4, 0x1f3c5, 0x1f3c6, + 0x1f3c7, 0x1f3c8, 0x1f3c9, 0x1f3ca, 0x1f3cb, 0x1f3cc, 0x1f3cd, + 0x1f3ce, 0x1f3cf, 0x1f3d0, 0x1f3d1, 0x1f3d2, 0x1f3d3, 0x1f3d4, + 0x1f3d5, 0x1f3d6, 0x1f3d7, 0x1f3d8, 0x1f3d9, 0x1f3da, 0x1f3db, + 0x1f3dc, 0x1f3dd, 0x1f3de, 0x1f3df, 0x1f3e0, 0x1f3e1, 0x1f3e2, + 0x1f3e3, 0x1f3e4, 0x1f3e5, 0x1f3e6, 0x1f3e7, 0x1f3e8, 0x1f3e9, + 0x1f3ea, 0x1f3eb, 0x1f3ec, 0x1f3ed, 0x1f3ee, 0x1f3ef, 0x1f3f0, + 0x1f3f3, 0x1f3f4, 0x1f3f5, 0x1f3f7, 0x1f3f8, 0x1f3f9, 0x1f3fa, + 0x1f3fb, 0x1f3fc, 0x1f3fd, 0x1f3fe, 0x1f3ff, 0x1f400, 0x1f401, + 0x1f402, 0x1f403, 0x1f404, 0x1f405, 0x1f406, 0x1f407, 0x1f408, + 0x1f409, 0x1f40a, 0x1f40b, 0x1f40c, 0x1f40d, 0x1f40e, 0x1f40f, + 0x1f410, 0x1f411, 0x1f412, 0x1f413, 0x1f414, 0x1f415, 0x1f416, + 0x1f417, 0x1f418, 0x1f419, 0x1f41a, 0x1f41b, 0x1f41c, 0x1f41d, + 0x1f41e, 0x1f41f, 0x1f420, 0x1f421, 0x1f422, 0x1f423, 0x1f424, + 0x1f425, 0x1f426, 0x1f427, 0x1f428, 0x1f429, 0x1f42a, 0x1f42b, + 0x1f42c, 0x1f42d, 0x1f42e, 0x1f42f, 0x1f430, 0x1f431, 0x1f432, + 0x1f433, 0x1f434, 0x1f435, 0x1f436, 0x1f437, 0x1f438, 0x1f439, + 0x1f43a, 0x1f43b, 0x1f43c, 0x1f43d, 0x1f43e, 0x1f43f, 0x1f440, + 0x1f441, 0x1f442, 0x1f443, 0x1f444, 0x1f445, 0x1f446, 0x1f447, + 0x1f448, 0x1f449, 0x1f44a, 0x1f44b, 0x1f44c, 0x1f44d, 0x1f44e, + 0x1f44f, 0x1f450, 0x1f451, 0x1f452, 0x1f453, 0x1f454, 0x1f455, + 0x1f456, 0x1f457, 0x1f458, 0x1f459, 0x1f45a, 0x1f45b, 0x1f45c, + 0x1f45d, 0x1f45e, 0x1f45f, 0x1f460, 0x1f461, 0x1f462, 0x1f463, + 0x1f464, 0x1f465, 0x1f466, 0x1f467, 0x1f468, 0x1f469, 0x1f46a, + 0x1f46b, 0x1f46c, 0x1f46d, 0x1f46e, 0x1f46f, 0x1f470, 0x1f471, + 0x1f472, 0x1f473, 0x1f474, 0x1f475, 0x1f476, 0x1f477, 0x1f478, + 0x1f479, 0x1f47a, 0x1f47b, 0x1f47c, 0x1f47d, 0x1f47e, 0x1f47f, + 0x1f480, 0x1f481, 0x1f482, 0x1f483, 0x1f484, 0x1f485, 0x1f486, + 0x1f487, 0x1f488, 0x1f489, 0x1f48a, 0x1f48b, 0x1f48c, 0x1f48d, + 0x1f48e, 0x1f48f, 0x1f490, 0x1f491, 0x1f492, 0x1f493, 0x1f494, + 0x1f495, 0x1f496, 0x1f497, 0x1f498, 0x1f499, 0x1f49a, 0x1f49b, + 0x1f49c, 0x1f49d, 0x1f49e, 0x1f49f, 0x1f4a0, 0x1f4a1, 0x1f4a2, + 0x1f4a3, 0x1f4a4, 0x1f4a5, 0x1f4a6, 0x1f4a7, 0x1f4a8, 0x1f4a9, + 0x1f4aa, 0x1f4ab, 0x1f4ac, 0x1f4ad, 0x1f4ae, 0x1f4af, 0x1f4b0, + 0x1f4b1, 0x1f4b2, 0x1f4b3, 0x1f4b4, 0x1f4b5, 0x1f4b6, 0x1f4b7, + 0x1f4b8, 0x1f4b9, 0x1f4ba, 0x1f4bb, 0x1f4bc, 0x1f4bd, 0x1f4be, + 0x1f4bf, 0x1f4c0, 0x1f4c1, 0x1f4c2, 0x1f4c3, 0x1f4c4, 0x1f4c5, + 0x1f4c6, 0x1f4c7, 0x1f4c8, 0x1f4c9, 0x1f4ca, 0x1f4cb, 0x1f4cc, + 0x1f4cd, 0x1f4ce, 0x1f4cf, 0x1f4d0, 0x1f4d1, 0x1f4d2, 0x1f4d3, + 0x1f4d4, 0x1f4d5, 0x1f4d6, 0x1f4d7, 0x1f4d8, 0x1f4d9, 0x1f4da, + 0x1f4db, 0x1f4dc, 0x1f4dd, 0x1f4de, 0x1f4df, 0x1f4e0, 0x1f4e1, + 0x1f4e2, 0x1f4e3, 0x1f4e4, 0x1f4e5, 0x1f4e6, 0x1f4e7, 0x1f4e8, + 0x1f4e9, 0x1f4ea, 0x1f4eb, 0x1f4ec, 0x1f4ed, 0x1f4ee, 0x1f4ef, + 0x1f4f0, 0x1f4f1, 0x1f4f2, 0x1f4f3, 0x1f4f4, 0x1f4f5, 0x1f4f6, + 0x1f4f7, 0x1f4f8, 0x1f4f9, 0x1f4fa, 0x1f4fb, 0x1f4fc, 0x1f4fd, + 0x1f4ff, 0x1f500, 0x1f501, 0x1f502, 0x1f503, 0x1f504, 0x1f505, + 0x1f506, 0x1f507, 0x1f508, 0x1f509, 0x1f50a, 0x1f50b, 0x1f50c, + 0x1f50d, 0x1f50e, 0x1f50f, 0x1f510, 0x1f511, 0x1f512, 0x1f513, + 0x1f514, 0x1f515, 0x1f516, 0x1f517, 0x1f518, 0x1f519, 0x1f51a, + 0x1f51b, 0x1f51c, 0x1f51d, 0x1f51e, 0x1f51f, 0x1f520, 0x1f521, + 0x1f522, 0x1f523, 0x1f524, 0x1f525, 0x1f526, 0x1f527, 0x1f528, + 0x1f529, 0x1f52a, 0x1f52b, 0x1f52c, 0x1f52d, 0x1f52e, 0x1f52f, + 0x1f530, 0x1f531, 0x1f532, 0x1f533, 0x1f534, 0x1f535, 0x1f536, + 0x1f537, 0x1f538, 0x1f539, 0x1f53a, 0x1f53b, 0x1f53c, 0x1f53d, + 0x1f549, 0x1f54a, 0x1f54b, 0x1f54c, 0x1f54d, 0x1f54e, 0x1f550, + 0x1f551, 0x1f552, 0x1f553, 0x1f554, 0x1f555, 0x1f556, 0x1f557, + 0x1f558, 0x1f559, 0x1f55a, 0x1f55b, 0x1f55c, 0x1f55d, 0x1f55e, + 0x1f55f, 0x1f560, 0x1f561, 0x1f562, 0x1f563, 0x1f564, 0x1f565, + 0x1f566, 0x1f567, 0x1f56f, 0x1f570, 0x1f573, 0x1f574, 0x1f575, + 0x1f576, 0x1f577, 0x1f578, 0x1f579, 0x1f57a, 0x1f587, 0x1f58a, + 0x1f58b, 0x1f58c, 0x1f58d, 0x1f590, 0x1f595, 0x1f596, 0x1f5a4, + 0x1f5a5, 0x1f5a8, 0x1f5b1, 0x1f5b2, 0x1f5bc, 0x1f5c2, 0x1f5c3, + 0x1f5c4, 0x1f5d1, 0x1f5d2, 0x1f5d3, 0x1f5dc, 0x1f5dd, 0x1f5de, + 0x1f5e1, 0x1f5e3, 0x1f5e8, 0x1f5ef, 0x1f5f3, 0x1f5fa, 0x1f5fb, + 0x1f5fc, 0x1f5fd, 0x1f5fe, 0x1f5ff, 0x1f601, 0x1f602, 0x1f603, + 0x1f604, 0x1f605, 0x1f606, 0x1f607, 0x1f608, 0x1f609, 0x1f60a, + 0x1f60b, 0x1f60c, 0x1f60d, 0x1f60e, 0x1f60f, 0x1f610, 0x1f611, + 0x1f612, 0x1f613, 0x1f614, 0x1f615, 0x1f616, 0x1f617, 0x1f618, + 0x1f619, 0x1f61a, 0x1f61b, 0x1f61c, 0x1f61d, 0x1f61e, 0x1f61f, + 0x1f620, 0x1f621, 0x1f622, 0x1f623, 0x1f624, 0x1f625, 0x1f626, + 0x1f627, 0x1f628, 0x1f629, 0x1f62a, 0x1f62b, 0x1f62c, 0x1f62d, + 0x1f62e, 0x1f62f, 0x1f630, 0x1f631, 0x1f632, 0x1f633, 0x1f634, + 0x1f635, 0x1f636, 0x1f637, 0x1f638, 0x1f639, 0x1f63a, 0x1f63b, + 0x1f63c, 0x1f63d, 0x1f63e, 0x1f63f, 0x1f640, 0x1f641, 0x1f642, + 0x1f643, 0x1f644, 0x1f645, 0x1f646, 0x1f647, 0x1f648, 0x1f649, + 0x1f64a, 0x1f64b, 0x1f64c, 0x1f64d, 0x1f64e, 0x1f64f, 0x1f680, + 0x1f681, 0x1f682, 0x1f683, 0x1f684, 0x1f685, 0x1f686, 0x1f687, + 0x1f688, 0x1f689, 0x1f68a, 0x1f68b, 0x1f68c, 0x1f68d, 0x1f68e, + 0x1f68f, 0x1f690, 0x1f691, 0x1f692, 0x1f693, 0x1f694, 0x1f695, + 0x1f696, 0x1f697, 0x1f698, 0x1f699, 0x1f69a, 0x1f69b, 0x1f69c, + 0x1f69d, 0x1f69e, 0x1f69f, 0x1f6a0, 0x1f6a1, 0x1f6a2, 0x1f6a3, + 0x1f6a4, 0x1f6a5, 0x1f6a6, 0x1f6a7, 0x1f6a8, 0x1f6a9, 0x1f6aa, + 0x1f6ab, 0x1f6ac, 0x1f6ad, 0x1f6ae, 0x1f6af, 0x1f6b0, 0x1f6b1, + 0x1f6b2, 0x1f6b3, 0x1f6b4, 0x1f6b5, 0x1f6b6, 0x1f6b7, 0x1f6b8, + 0x1f6b9, 0x1f6ba, 0x1f6bb, 0x1f6bc, 0x1f6bd, 0x1f6be, 0x1f6bf, + 0x1f6c0, 0x1f6c1, 0x1f6c2, 0x1f6c3, 0x1f6c4, 0x1f6c5, 0x1f6cb, + 0x1f6cc, 0x1f6cd, 0x1f6ce, 0x1f6cf, 0x1f6d0, 0x1f6d1, 0x1f6d2, + 0x1f6d5, 0x1f6e0, 0x1f6e1, 0x1f6e2, 0x1f6e3, 0x1f6e4, 0x1f6e5, + 0x1f6e9, 0x1f6eb, 0x1f6ec, 0x1f6f0, 0x1f6f3, 0x1f6f4, 0x1f6f5, + 0x1f6f6, 0x1f6f7, 0x1f6f8, 0x1f6f9, 0x1f6fa, 0x1f7e0, 0x1f7e1, + 0x1f7e2, 0x1f7e3, 0x1f7e4, 0x1f7e5, 0x1f7e6, 0x1f7e7, 0x1f7e8, + 0x1f7e9, 0x1f7ea, 0x1f7eb, 0x1f90d, 0x1f90e, 0x1f90f, 0x1f910, + 0x1f911, 0x1f912, 0x1f913, 0x1f914, 0x1f915, 0x1f916, 0x1f917, + 0x1f918, 0x1f919, 0x1f91a, 0x1f91b, 0x1f91c, 0x1f91d, 0x1f91e, + 0x1f91f, 0x1f920, 0x1f921, 0x1f922, 0x1f923, 0x1f924, 0x1f925, + 0x1f926, 0x1f927, 0x1f928, 0x1f929, 0x1f92a, 0x1f92b, 0x1f92c, + 0x1f92d, 0x1f92e, 0x1f92f, 0x1f930, 0x1f931, 0x1f932, 0x1f933, + 0x1f934, 0x1f935, 0x1f936, 0x1f937, 0x1f938, 0x1f939, 0x1f93a, + 0x1f93c, 0x1f93d, 0x1f93e, 0x1f93f, 0x1f940, 0x1f941, 0x1f942, + 0x1f943, 0x1f944, 0x1f945, 0x1f947, 0x1f948, 0x1f949, 0x1f94a, + 0x1f94b, 0x1f94c, 0x1f94d, 0x1f94e, 0x1f94f, 0x1f950, 0x1f951, + 0x1f952, 0x1f953, 0x1f954, 0x1f955, 0x1f956, 0x1f957, 0x1f958, + 0x1f959, 0x1f95a, 0x1f95b, 0x1f95c, 0x1f95d, 0x1f95e, 0x1f95f, + 0x1f960, 0x1f961, 0x1f962, 0x1f963, 0x1f964, 0x1f965, 0x1f966, + 0x1f967, 0x1f968, 0x1f969, 0x1f96a, 0x1f96b, 0x1f96c, 0x1f96d, + 0x1f96e, 0x1f96f, 0x1f970, 0x1f971, 0x1f973, 0x1f974, 0x1f975, + 0x1f976, 0x1f97a, 0x1f97b, 0x1f97c, 0x1f97d, 0x1f97e, 0x1f97f, + 0x1f980, 0x1f981, 0x1f982, 0x1f983, 0x1f984, 0x1f985, 0x1f986, + 0x1f987, 0x1f988, 0x1f989, 0x1f98a, 0x1f98b, 0x1f98c, 0x1f98d, + 0x1f98e, 0x1f98f, 0x1f990, 0x1f991, 0x1f992, 0x1f993, 0x1f994, + 0x1f995, 0x1f996, 0x1f997, 0x1f998, 0x1f999, 0x1f99a, 0x1f99b, + 0x1f99c, 0x1f99d, 0x1f99e, 0x1f99f, 0x1f9a0, 0x1f9a1, 0x1f9a2, + 0x1f9a5, 0x1f9a6, 0x1f9a7, 0x1f9a8, 0x1f9a9, 0x1f9aa, 0x1f9ae, + 0x1f9af, 0x1f9b0, 0x1f9b1, 0x1f9b2, 0x1f9b3, 0x1f9b4, 0x1f9b5, + 0x1f9b6, 0x1f9b7, 0x1f9b8, 0x1f9b9, 0x1f9ba, 0x1f9bb, 0x1f9bc, + 0x1f9bd, 0x1f9be, 0x1f9bf, 0x1f9c0, 0x1f9c1, 0x1f9c2, 0x1f9c3, + 0x1f9c4, 0x1f9c5, 0x1f9c6, 0x1f9c7, 0x1f9c8, 0x1f9c9, 0x1f9ca, + 0x1f9cd, 0x1f9ce, 0x1f9cf, 0x1f9d0, 0x1f9d1, 0x1f9d2, 0x1f9d3, + 0x1f9d4, 0x1f9d5, 0x1f9d6, 0x1f9d7, 0x1f9d8, 0x1f9d9, 0x1f9da, + 0x1f9db, 0x1f9dc, 0x1f9dd, 0x1f9de, 0x1f9df, 0x1f9e0, 0x1f9e1, + 0x1f9e2, 0x1f9e3, 0x1f9e4, 0x1f9e5, 0x1f9e6, 0x1f9e7, 0x1f9e8, + 0x1f9e9, 0x1f9ea, 0x1f9eb, 0x1f9ec, 0x1f9ed, 0x1f9ee, 0x1f9ef, + 0x1f9f0, 0x1f9f1, 0x1f9f2, 0x1f9f3, 0x1f9f4, 0x1f9f5, 0x1f9f6, + 0x1f9f7, 0x1f9f8, 0x1f9f9, 0x1f9fa, 0x1f9fb, 0x1f9fc, 0x1f9fd, + 0x1f9fe, 0x1f9ff, 0x1fa70, 0x1fa71, 0x1fa72, 0x1fa73, 0x1fa78, + 0x1fa79, 0x1fa7a, 0x1fa80, 0x1fa81, 0x1fa82, 0x1fa90, 0x1fa91, + 0x1fa92, 0x1fa93, 0x1fa94, 0x1fa95, 0x203c, 0x2049, 0x2122, + 0x2139, 0x2194, 0x2195, 0x2196, 0x2197, 0x2198, 0x2199, + 0x21a9, 0x21aa, 0x231a, 0x231b, 0x2328, 0x23cf, 0x23e9, + 0x23ea, 0x23eb, 0x23ec, 0x23ed, 0x23ee, 0x23ef, 0x23f0, + 0x23f1, 0x23f2, 0x23f3, 0x23f8, 0x23f9, 0x23fa, 0x24c2, + 0x25aa, 0x25ab, 0x25b6, 0x25c0, 0x25fb, 0x25fc, 0x25fd, + 0x25fe, 0x2600, 0x2601, 0x2602, 0x2603, 0x2604, 0x260e, + 0x2611, 0x2614, 0x2615, 0x2618, 0x261d, 0x2620, 0x2622, + 0x2623, 0x2626, 0x262a, 0x262e, 0x262f, 0x2638, 0x2639, + 0x263a, 0x2648, 0x2649, 0x264a, 0x264b, 0x264c, 0x264d, + 0x264e, 0x264f, 0x2650, 0x2651, 0x2652, 0x2653, 0x265f, + 0x2660, 0x2663, 0x2665, 0x2666, 0x2668, 0x267b, 0x267e, + 0x267f, 0x2692, 0x2693, 0x2694, 0x2696, 0x2697, 0x2699, + 0x269b, 0x269c, 0x26a0, 0x26a1, 0x26aa, 0x26ab, 0x26b0, + 0x26b1, 0x26bd, 0x26be, 0x26c4, 0x26c5, 0x26c8, 0x26ce, + 0x26cf, 0x26d1, 0x26d3, 0x26d4, 0x26e9, 0x26ea, 0x26f0, + 0x26f1, 0x26f2, 0x26f3, 0x26f4, 0x26f5, 0x26f7, 0x26f8, + 0x26f9, 0x26fa, 0x26fd, 0x2702, 0x2705, 0x2708, 0x2709, + 0x270a, 0x270b, 0x270c, 0x270d, 0x270f, 0x2712, 0x2714, + 0x2716, 0x271d, 0x2721, 0x2728, 0x2733, 0x2734, 0x2744, + 0x2747, 0x274c, 0x274e, 0x2753, 0x2754, 0x2755, 0x2757, + 0x2763, 0x2764, 0x2795, 0x2796, 0x2797, 0x27a1, 0x27b0, + 0x27bf, 0x2934, 0x2935, 0x2b05, 0x2b06, 0x2b07, 0x2b1b, + 0x2b1c, 0x2b50, 0x2b55, 0x3030, 0x303d, 0x3297, 0x3299, + 0xa9, 0xae, 0xfe0f, + }, + spriteSheetNumberOfRows: 35, + spriteSheetNumberOfColumns: 37 + ); + + static readonly EmojiResourceConfiguration _defaultConfiguration = appleEmojiConfiguration; + + static EmojiResourceConfiguration _configuration = null; + public static EmojiResourceConfiguration configuration { + get { return _configuration ?? _defaultConfiguration; } + set { + if (value == _configuration) { + return; + } + + if (value != null && _configuration != null && + value.spriteSheetAssetName != _configuration.spriteSheetAssetName) { + try { + _image = new Image(Resources.Load(value.spriteSheetAssetName)); + } + catch (Exception e) { + _image = null; + Debug.LogError(e.StackTrace); + } + } + + _configuration = value; + } + } + + static Image _image; public static Image image { get { if (_image == null || _image.texture == null) { try { - _image = new Image( - Resources.Load("Emoji") - ); + _image = new Image(Resources.Load(configuration.spriteSheetAssetName)); } catch (Exception e) { _image = null; @@ -25,255 +460,40 @@ public static Image image { } } - public static readonly Dictionary emojiLookupTable = new Dictionary { - {0x1f004, 0}, {0x1f0cf, 1}, {0x1f170, 2}, {0x1f171, 3}, {0x1f17e, 4}, {0x1f17f, 5}, - {0x1f18e, 6}, {0x1f191, 7}, {0x1f192, 8}, {0x1f193, 9}, {0x1f194, 10}, {0x1f195, 11}, - {0x1f196, 12}, {0x1f197, 13}, {0x1f198, 14}, {0x1f199, 15}, {0x1f19a, 16}, {0x1f1e6, 17}, - {0x1f1e7, 18}, {0x1f1e8, 19}, {0x1f1e9, 20}, {0x1f1ea, 21}, {0x1f1eb, 22}, {0x1f1ec, 23}, - {0x1f1ed, 24}, {0x1f1ee, 25}, {0x1f1ef, 26}, {0x1f1f0, 27}, {0x1f1f1, 28}, {0x1f1f2, 29}, - {0x1f1f3, 30}, {0x1f1f4, 31}, {0x1f1f5, 32}, {0x1f1f6, 33}, {0x1f1f7, 34}, {0x1f1f8, 35}, - {0x1f1f9, 36}, {0x1f1fa, 37}, {0x1f1fb, 38}, {0x1f1fc, 39}, {0x1f1fd, 40}, {0x1f1fe, 41}, - {0x1f1ff, 42}, {0x1f201, 43}, {0x1f202, 44}, {0x1f21a, 45}, {0x1f22f, 46}, {0x1f232, 47}, - {0x1f233, 48}, {0x1f234, 49}, {0x1f235, 50}, {0x1f236, 51}, {0x1f237, 52}, {0x1f238, 53}, - {0x1f239, 54}, {0x1f23a, 55}, {0x1f250, 56}, {0x1f251, 57}, {0x1f300, 58}, {0x1f301, 59}, - {0x1f302, 60}, {0x1f303, 61}, {0x1f304, 62}, {0x1f305, 63}, {0x1f306, 64}, {0x1f307, 65}, - {0x1f308, 66}, {0x1f309, 67}, {0x1f30a, 68}, {0x1f30b, 69}, {0x1f30c, 70}, {0x1f30d, 71}, - {0x1f30e, 72}, {0x1f30f, 73}, {0x1f310, 74}, {0x1f311, 75}, {0x1f312, 76}, {0x1f313, 77}, - {0x1f314, 78}, {0x1f315, 79}, {0x1f316, 80}, {0x1f317, 81}, {0x1f318, 82}, {0x1f319, 83}, - {0x1f31a, 84}, {0x1f31b, 85}, {0x1f31c, 86}, {0x1f31d, 87}, {0x1f31e, 88}, {0x1f31f, 89}, - {0x1f320, 90}, {0x1f321, 91}, {0x1f324, 92}, {0x1f325, 93}, {0x1f326, 94}, {0x1f327, 95}, - {0x1f328, 96}, {0x1f329, 97}, {0x1f32a, 98}, {0x1f32b, 99}, {0x1f32c, 100}, {0x1f32d, 101}, - {0x1f32e, 102}, {0x1f32f, 103}, {0x1f330, 104}, {0x1f331, 105}, {0x1f332, 106}, {0x1f333, 107}, - {0x1f334, 108}, {0x1f335, 109}, {0x1f336, 110}, {0x1f337, 111}, {0x1f338, 112}, {0x1f339, 113}, - {0x1f33a, 114}, {0x1f33b, 115}, {0x1f33c, 116}, {0x1f33d, 117}, {0x1f33e, 118}, {0x1f33f, 119}, - {0x1f340, 120}, {0x1f341, 121}, {0x1f342, 122}, {0x1f343, 123}, {0x1f344, 124}, {0x1f345, 125}, - {0x1f346, 126}, {0x1f347, 127}, {0x1f348, 128}, {0x1f349, 129}, {0x1f34a, 130}, {0x1f34b, 131}, - {0x1f34c, 132}, {0x1f34d, 133}, {0x1f34e, 134}, {0x1f34f, 135}, {0x1f350, 136}, {0x1f351, 137}, - {0x1f352, 138}, {0x1f353, 139}, {0x1f354, 140}, {0x1f355, 141}, {0x1f356, 142}, {0x1f357, 143}, - {0x1f358, 144}, {0x1f359, 145}, {0x1f35a, 146}, {0x1f35b, 147}, {0x1f35c, 148}, {0x1f35d, 149}, - {0x1f35e, 150}, {0x1f35f, 151}, {0x1f360, 152}, {0x1f361, 153}, {0x1f362, 154}, {0x1f363, 155}, - {0x1f364, 156}, {0x1f365, 157}, {0x1f366, 158}, {0x1f367, 159}, {0x1f368, 160}, {0x1f369, 161}, - {0x1f36a, 162}, {0x1f36b, 163}, {0x1f36c, 164}, {0x1f36d, 165}, {0x1f36e, 166}, {0x1f36f, 167}, - {0x1f370, 168}, {0x1f371, 169}, {0x1f372, 170}, {0x1f373, 171}, {0x1f374, 172}, {0x1f375, 173}, - {0x1f376, 174}, {0x1f377, 175}, {0x1f378, 176}, {0x1f379, 177}, {0x1f37a, 178}, {0x1f37b, 179}, - {0x1f37c, 180}, {0x1f37d, 181}, {0x1f37e, 182}, {0x1f37f, 183}, {0x1f380, 184}, {0x1f381, 185}, - {0x1f382, 186}, {0x1f383, 187}, {0x1f384, 188}, {0x1f385, 189}, {0x1f386, 190}, {0x1f387, 191}, - {0x1f388, 192}, {0x1f389, 193}, {0x1f38a, 194}, {0x1f38b, 195}, {0x1f38c, 196}, {0x1f38d, 197}, - {0x1f38e, 198}, {0x1f38f, 199}, {0x1f390, 200}, {0x1f391, 201}, {0x1f392, 202}, {0x1f393, 203}, - {0x1f396, 204}, {0x1f397, 205}, {0x1f399, 206}, {0x1f39a, 207}, {0x1f39b, 208}, {0x1f39e, 209}, - {0x1f39f, 210}, {0x1f3a0, 211}, {0x1f3a1, 212}, {0x1f3a2, 213}, {0x1f3a3, 214}, {0x1f3a4, 215}, - {0x1f3a5, 216}, {0x1f3a6, 217}, {0x1f3a7, 218}, {0x1f3a8, 219}, {0x1f3a9, 220}, {0x1f3aa, 221}, - {0x1f3ab, 222}, {0x1f3ac, 223}, {0x1f3ad, 224}, {0x1f3ae, 225}, {0x1f3af, 226}, {0x1f3b0, 227}, - {0x1f3b1, 228}, {0x1f3b2, 229}, {0x1f3b3, 230}, {0x1f3b4, 231}, {0x1f3b5, 232}, {0x1f3b6, 233}, - {0x1f3b7, 234}, {0x1f3b8, 235}, {0x1f3b9, 236}, {0x1f3ba, 237}, {0x1f3bb, 238}, {0x1f3bc, 239}, - {0x1f3bd, 240}, {0x1f3be, 241}, {0x1f3bf, 242}, {0x1f3c0, 243}, {0x1f3c1, 244}, {0x1f3c2, 245}, - {0x1f3c3, 246}, {0x1f3c4, 247}, {0x1f3c5, 248}, {0x1f3c6, 249}, {0x1f3c7, 250}, {0x1f3c8, 251}, - {0x1f3c9, 252}, {0x1f3ca, 253}, {0x1f3cb, 254}, {0x1f3cc, 255}, {0x1f3cd, 256}, {0x1f3ce, 257}, - {0x1f3cf, 258}, {0x1f3d0, 259}, {0x1f3d1, 260}, {0x1f3d2, 261}, {0x1f3d3, 262}, {0x1f3d4, 263}, - {0x1f3d5, 264}, {0x1f3d6, 265}, {0x1f3d7, 266}, {0x1f3d8, 267}, {0x1f3d9, 268}, {0x1f3da, 269}, - {0x1f3db, 270}, {0x1f3dc, 271}, {0x1f3dd, 272}, {0x1f3de, 273}, {0x1f3df, 274}, {0x1f3e0, 275}, - {0x1f3e1, 276}, {0x1f3e2, 277}, {0x1f3e3, 278}, {0x1f3e4, 279}, {0x1f3e5, 280}, {0x1f3e6, 281}, - {0x1f3e7, 282}, {0x1f3e8, 283}, {0x1f3e9, 284}, {0x1f3ea, 285}, {0x1f3eb, 286}, {0x1f3ec, 287}, - {0x1f3ed, 288}, {0x1f3ee, 289}, {0x1f3ef, 290}, {0x1f3f0, 291}, {0x1f3f3, 292}, {0x1f3f4, 293}, - {0x1f3f5, 294}, {0x1f3f7, 295}, {0x1f3f8, 296}, {0x1f3f9, 297}, {0x1f3fa, 298}, {0x1f3fb, 299}, - {0x1f3fc, 300}, {0x1f3fd, 301}, {0x1f3fe, 302}, {0x1f3ff, 303}, {0x1f400, 304}, {0x1f401, 305}, - {0x1f402, 306}, {0x1f403, 307}, {0x1f404, 308}, {0x1f405, 309}, {0x1f406, 310}, {0x1f407, 311}, - {0x1f408, 312}, {0x1f409, 313}, {0x1f40a, 314}, {0x1f40b, 315}, {0x1f40c, 316}, {0x1f40d, 317}, - {0x1f40e, 318}, {0x1f40f, 319}, {0x1f410, 320}, {0x1f411, 321}, {0x1f412, 322}, {0x1f413, 323}, - {0x1f414, 324}, {0x1f415, 325}, {0x1f416, 326}, {0x1f417, 327}, {0x1f418, 328}, {0x1f419, 329}, - {0x1f41a, 330}, {0x1f41b, 331}, {0x1f41c, 332}, {0x1f41d, 333}, {0x1f41e, 334}, {0x1f41f, 335}, - {0x1f420, 336}, {0x1f421, 337}, {0x1f422, 338}, {0x1f423, 339}, {0x1f424, 340}, {0x1f425, 341}, - {0x1f426, 342}, {0x1f427, 343}, {0x1f428, 344}, {0x1f429, 345}, {0x1f42a, 346}, {0x1f42b, 347}, - {0x1f42c, 348}, {0x1f42d, 349}, {0x1f42e, 350}, {0x1f42f, 351}, {0x1f430, 352}, {0x1f431, 353}, - {0x1f432, 354}, {0x1f433, 355}, {0x1f434, 356}, {0x1f435, 357}, {0x1f436, 358}, {0x1f437, 359}, - {0x1f438, 360}, {0x1f439, 361}, {0x1f43a, 362}, {0x1f43b, 363}, {0x1f43c, 364}, {0x1f43d, 365}, - {0x1f43e, 366}, {0x1f43f, 367}, {0x1f440, 368}, {0x1f441, 369}, {0x1f442, 370}, {0x1f443, 371}, - {0x1f444, 372}, {0x1f445, 373}, {0x1f446, 374}, {0x1f447, 375}, {0x1f448, 376}, {0x1f449, 377}, - {0x1f44a, 378}, {0x1f44b, 379}, {0x1f44c, 380}, {0x1f44d, 381}, {0x1f44e, 382}, {0x1f44f, 383}, - {0x1f450, 384}, {0x1f451, 385}, {0x1f452, 386}, {0x1f453, 387}, {0x1f454, 388}, {0x1f455, 389}, - {0x1f456, 390}, {0x1f457, 391}, {0x1f458, 392}, {0x1f459, 393}, {0x1f45a, 394}, {0x1f45b, 395}, - {0x1f45c, 396}, {0x1f45d, 397}, {0x1f45e, 398}, {0x1f45f, 399}, {0x1f460, 400}, {0x1f461, 401}, - {0x1f462, 402}, {0x1f463, 403}, {0x1f464, 404}, {0x1f465, 405}, {0x1f466, 406}, {0x1f467, 407}, - {0x1f468, 408}, {0x1f469, 409}, {0x1f46a, 410}, {0x1f46b, 411}, {0x1f46c, 412}, {0x1f46d, 413}, - {0x1f46e, 414}, {0x1f46f, 415}, {0x1f470, 416}, {0x1f471, 417}, {0x1f472, 418}, {0x1f473, 419}, - {0x1f474, 420}, {0x1f475, 421}, {0x1f476, 422}, {0x1f477, 423}, {0x1f478, 424}, {0x1f479, 425}, - {0x1f47a, 426}, {0x1f47b, 427}, {0x1f47c, 428}, {0x1f47d, 429}, {0x1f47e, 430}, {0x1f47f, 431}, - {0x1f480, 432}, {0x1f481, 433}, {0x1f482, 434}, {0x1f483, 435}, {0x1f484, 436}, {0x1f485, 437}, - {0x1f486, 438}, {0x1f487, 439}, {0x1f488, 440}, {0x1f489, 441}, {0x1f48a, 442}, {0x1f48b, 443}, - {0x1f48c, 444}, {0x1f48d, 445}, {0x1f48e, 446}, {0x1f48f, 447}, {0x1f490, 448}, {0x1f491, 449}, - {0x1f492, 450}, {0x1f493, 451}, {0x1f494, 452}, {0x1f495, 453}, {0x1f496, 454}, {0x1f497, 455}, - {0x1f498, 456}, {0x1f499, 457}, {0x1f49a, 458}, {0x1f49b, 459}, {0x1f49c, 460}, {0x1f49d, 461}, - {0x1f49e, 462}, {0x1f49f, 463}, {0x1f4a0, 464}, {0x1f4a1, 465}, {0x1f4a2, 466}, {0x1f4a3, 467}, - {0x1f4a4, 468}, {0x1f4a5, 469}, {0x1f4a6, 470}, {0x1f4a7, 471}, {0x1f4a8, 472}, {0x1f4a9, 473}, - {0x1f4aa, 474}, {0x1f4ab, 475}, {0x1f4ac, 476}, {0x1f4ad, 477}, {0x1f4ae, 478}, {0x1f4af, 479}, - {0x1f4b0, 480}, {0x1f4b1, 481}, {0x1f4b2, 482}, {0x1f4b3, 483}, {0x1f4b4, 484}, {0x1f4b5, 485}, - {0x1f4b6, 486}, {0x1f4b7, 487}, {0x1f4b8, 488}, {0x1f4b9, 489}, {0x1f4ba, 490}, {0x1f4bb, 491}, - {0x1f4bc, 492}, {0x1f4bd, 493}, {0x1f4be, 494}, {0x1f4bf, 495}, {0x1f4c0, 496}, {0x1f4c1, 497}, - {0x1f4c2, 498}, {0x1f4c3, 499}, {0x1f4c4, 500}, {0x1f4c5, 501}, {0x1f4c6, 502}, {0x1f4c7, 503}, - {0x1f4c8, 504}, {0x1f4c9, 505}, {0x1f4ca, 506}, {0x1f4cb, 507}, {0x1f4cc, 508}, {0x1f4cd, 509}, - {0x1f4ce, 510}, {0x1f4cf, 511}, {0x1f4d0, 512}, {0x1f4d1, 513}, {0x1f4d2, 514}, {0x1f4d3, 515}, - {0x1f4d4, 516}, {0x1f4d5, 517}, {0x1f4d6, 518}, {0x1f4d7, 519}, {0x1f4d8, 520}, {0x1f4d9, 521}, - {0x1f4da, 522}, {0x1f4db, 523}, {0x1f4dc, 524}, {0x1f4dd, 525}, {0x1f4de, 526}, {0x1f4df, 527}, - {0x1f4e0, 528}, {0x1f4e1, 529}, {0x1f4e2, 530}, {0x1f4e3, 531}, {0x1f4e4, 532}, {0x1f4e5, 533}, - {0x1f4e6, 534}, {0x1f4e7, 535}, {0x1f4e8, 536}, {0x1f4e9, 537}, {0x1f4ea, 538}, {0x1f4eb, 539}, - {0x1f4ec, 540}, {0x1f4ed, 541}, {0x1f4ee, 542}, {0x1f4ef, 543}, {0x1f4f0, 544}, {0x1f4f1, 545}, - {0x1f4f2, 546}, {0x1f4f3, 547}, {0x1f4f4, 548}, {0x1f4f5, 549}, {0x1f4f6, 550}, {0x1f4f7, 551}, - {0x1f4f8, 552}, {0x1f4f9, 553}, {0x1f4fa, 554}, {0x1f4fb, 555}, {0x1f4fc, 556}, {0x1f4fd, 557}, - {0x1f4ff, 558}, {0x1f500, 559}, {0x1f501, 560}, {0x1f502, 561}, {0x1f503, 562}, {0x1f504, 563}, - {0x1f505, 564}, {0x1f506, 565}, {0x1f507, 566}, {0x1f508, 567}, {0x1f509, 568}, {0x1f50a, 569}, - {0x1f50b, 570}, {0x1f50c, 571}, {0x1f50d, 572}, {0x1f50e, 573}, {0x1f50f, 574}, {0x1f510, 575}, - {0x1f511, 576}, {0x1f512, 577}, {0x1f513, 578}, {0x1f514, 579}, {0x1f515, 580}, {0x1f516, 581}, - {0x1f517, 582}, {0x1f518, 583}, {0x1f519, 584}, {0x1f51a, 585}, {0x1f51b, 586}, {0x1f51c, 587}, - {0x1f51d, 588}, {0x1f51e, 589}, {0x1f51f, 590}, {0x1f520, 591}, {0x1f521, 592}, {0x1f522, 593}, - {0x1f523, 594}, {0x1f524, 595}, {0x1f525, 596}, {0x1f526, 597}, {0x1f527, 598}, {0x1f528, 599}, - {0x1f529, 600}, {0x1f52a, 601}, {0x1f52b, 602}, {0x1f52c, 603}, {0x1f52d, 604}, {0x1f52e, 605}, - {0x1f52f, 606}, {0x1f530, 607}, {0x1f531, 608}, {0x1f532, 609}, {0x1f533, 610}, {0x1f534, 611}, - {0x1f535, 612}, {0x1f536, 613}, {0x1f537, 614}, {0x1f538, 615}, {0x1f539, 616}, {0x1f53a, 617}, - {0x1f53b, 618}, {0x1f53c, 619}, {0x1f53d, 620}, {0x1f549, 621}, {0x1f54a, 622}, {0x1f54b, 623}, - {0x1f54c, 624}, {0x1f54d, 625}, {0x1f54e, 626}, {0x1f550, 627}, {0x1f551, 628}, {0x1f552, 629}, - {0x1f553, 630}, {0x1f554, 631}, {0x1f555, 632}, {0x1f556, 633}, {0x1f557, 634}, {0x1f558, 635}, - {0x1f559, 636}, {0x1f55a, 637}, {0x1f55b, 638}, {0x1f55c, 639}, {0x1f55d, 640}, {0x1f55e, 641}, - {0x1f55f, 642}, {0x1f560, 643}, {0x1f561, 644}, {0x1f562, 645}, {0x1f563, 646}, {0x1f564, 647}, - {0x1f565, 648}, {0x1f566, 649}, {0x1f567, 650}, {0x1f56f, 651}, {0x1f570, 652}, {0x1f573, 653}, - {0x1f574, 654}, {0x1f575, 655}, {0x1f576, 656}, {0x1f577, 657}, {0x1f578, 658}, {0x1f579, 659}, - {0x1f57a, 660}, {0x1f587, 661}, {0x1f58a, 662}, {0x1f58b, 663}, {0x1f58c, 664}, {0x1f58d, 665}, - {0x1f590, 666}, {0x1f595, 667}, {0x1f596, 668}, {0x1f5a4, 669}, {0x1f5a5, 670}, {0x1f5a8, 671}, - {0x1f5b1, 672}, {0x1f5b2, 673}, {0x1f5bc, 674}, {0x1f5c2, 675}, {0x1f5c3, 676}, {0x1f5c4, 677}, - {0x1f5d1, 678}, {0x1f5d2, 679}, {0x1f5d3, 680}, {0x1f5dc, 681}, {0x1f5dd, 682}, {0x1f5de, 683}, - {0x1f5e1, 684}, {0x1f5e3, 685}, {0x1f5e8, 686}, {0x1f5ef, 687}, {0x1f5f3, 688}, {0x1f5fa, 689}, - {0x1f5fb, 690}, {0x1f5fc, 691}, {0x1f5fd, 692}, {0x1f5fe, 693}, {0x1f5ff, 694}, {0x1f600, 695}, - {0x1f601, 696}, {0x1f602, 697}, {0x1f603, 698}, {0x1f604, 699}, {0x1f605, 700}, {0x1f606, 701}, - {0x1f607, 702}, {0x1f608, 703}, {0x1f609, 704}, {0x1f60a, 705}, {0x1f60b, 706}, {0x1f60c, 707}, - {0x1f60d, 708}, {0x1f60e, 709}, {0x1f60f, 710}, {0x1f610, 711}, {0x1f611, 712}, {0x1f612, 713}, - {0x1f613, 714}, {0x1f614, 715}, {0x1f615, 716}, {0x1f616, 717}, {0x1f617, 718}, {0x1f618, 719}, - {0x1f619, 720}, {0x1f61a, 721}, {0x1f61b, 722}, {0x1f61c, 723}, {0x1f61d, 724}, {0x1f61e, 725}, - {0x1f61f, 726}, {0x1f620, 727}, {0x1f621, 728}, {0x1f622, 729}, {0x1f623, 730}, {0x1f624, 731}, - {0x1f625, 732}, {0x1f626, 733}, {0x1f627, 734}, {0x1f628, 735}, {0x1f629, 736}, {0x1f62a, 737}, - {0x1f62b, 738}, {0x1f62c, 739}, {0x1f62d, 740}, {0x1f62e, 741}, {0x1f62f, 742}, {0x1f630, 743}, - {0x1f631, 744}, {0x1f632, 745}, {0x1f633, 746}, {0x1f634, 747}, {0x1f635, 748}, {0x1f636, 749}, - {0x1f637, 750}, {0x1f638, 751}, {0x1f639, 752}, {0x1f63a, 753}, {0x1f63b, 754}, {0x1f63c, 755}, - {0x1f63d, 756}, {0x1f63e, 757}, {0x1f63f, 758}, {0x1f640, 759}, {0x1f641, 760}, {0x1f642, 761}, - {0x1f643, 762}, {0x1f644, 763}, {0x1f645, 764}, {0x1f646, 765}, {0x1f647, 766}, {0x1f648, 767}, - {0x1f649, 768}, {0x1f64a, 769}, {0x1f64b, 770}, {0x1f64c, 771}, {0x1f64d, 772}, {0x1f64e, 773}, - {0x1f64f, 774}, {0x1f680, 775}, {0x1f681, 776}, {0x1f682, 777}, {0x1f683, 778}, {0x1f684, 779}, - {0x1f685, 780}, {0x1f686, 781}, {0x1f687, 782}, {0x1f688, 783}, {0x1f689, 784}, {0x1f68a, 785}, - {0x1f68b, 786}, {0x1f68c, 787}, {0x1f68d, 788}, {0x1f68e, 789}, {0x1f68f, 790}, {0x1f690, 791}, - {0x1f691, 792}, {0x1f692, 793}, {0x1f693, 794}, {0x1f694, 795}, {0x1f695, 796}, {0x1f696, 797}, - {0x1f697, 798}, {0x1f698, 799}, {0x1f699, 800}, {0x1f69a, 801}, {0x1f69b, 802}, {0x1f69c, 803}, - {0x1f69d, 804}, {0x1f69e, 805}, {0x1f69f, 806}, {0x1f6a0, 807}, {0x1f6a1, 808}, {0x1f6a2, 809}, - {0x1f6a3, 810}, {0x1f6a4, 811}, {0x1f6a5, 812}, {0x1f6a6, 813}, {0x1f6a7, 814}, {0x1f6a8, 815}, - {0x1f6a9, 816}, {0x1f6aa, 817}, {0x1f6ab, 818}, {0x1f6ac, 819}, {0x1f6ad, 820}, {0x1f6ae, 821}, - {0x1f6af, 822}, {0x1f6b0, 823}, {0x1f6b1, 824}, {0x1f6b2, 825}, {0x1f6b3, 826}, {0x1f6b4, 827}, - {0x1f6b5, 828}, {0x1f6b6, 829}, {0x1f6b7, 830}, {0x1f6b8, 831}, {0x1f6b9, 832}, {0x1f6ba, 833}, - {0x1f6bb, 834}, {0x1f6bc, 835}, {0x1f6bd, 836}, {0x1f6be, 837}, {0x1f6bf, 838}, {0x1f6c0, 839}, - {0x1f6c1, 840}, {0x1f6c2, 841}, {0x1f6c3, 842}, {0x1f6c4, 843}, {0x1f6c5, 844}, {0x1f6cb, 845}, - {0x1f6cc, 846}, {0x1f6cd, 847}, {0x1f6ce, 848}, {0x1f6cf, 849}, {0x1f6d0, 850}, {0x1f6d1, 851}, - {0x1f6d2, 852}, {0x1f6e0, 853}, {0x1f6e1, 854}, {0x1f6e2, 855}, {0x1f6e3, 856}, {0x1f6e4, 857}, - {0x1f6e5, 858}, {0x1f6e9, 859}, {0x1f6eb, 860}, {0x1f6ec, 861}, {0x1f6f0, 862}, {0x1f6f3, 863}, - {0x1f6f4, 864}, {0x1f6f5, 865}, {0x1f6f6, 866}, {0x1f6f7, 867}, {0x1f6f8, 868}, {0x1f6f9, 869}, - {0x1f910, 870}, {0x1f911, 871}, {0x1f912, 872}, {0x1f913, 873}, {0x1f914, 874}, {0x1f915, 875}, - {0x1f916, 876}, {0x1f917, 877}, {0x1f918, 878}, {0x1f919, 879}, {0x1f91a, 880}, {0x1f91b, 881}, - {0x1f91c, 882}, {0x1f91d, 883}, {0x1f91e, 884}, {0x1f91f, 885}, {0x1f920, 886}, {0x1f921, 887}, - {0x1f922, 888}, {0x1f923, 889}, {0x1f924, 890}, {0x1f925, 891}, {0x1f926, 892}, {0x1f927, 893}, - {0x1f928, 894}, {0x1f929, 895}, {0x1f92a, 896}, {0x1f92b, 897}, {0x1f92c, 898}, {0x1f92d, 899}, - {0x1f92e, 900}, {0x1f92f, 901}, {0x1f930, 902}, {0x1f931, 903}, {0x1f932, 904}, {0x1f933, 905}, - {0x1f934, 906}, {0x1f935, 907}, {0x1f936, 908}, {0x1f937, 909}, {0x1f938, 910}, {0x1f939, 911}, - {0x1f93a, 912}, {0x1f93c, 913}, {0x1f93d, 914}, {0x1f93e, 915}, {0x1f940, 916}, {0x1f941, 917}, - {0x1f942, 918}, {0x1f943, 919}, {0x1f944, 920}, {0x1f945, 921}, {0x1f947, 922}, {0x1f948, 923}, - {0x1f949, 924}, {0x1f94a, 925}, {0x1f94b, 926}, {0x1f94c, 927}, {0x1f94d, 928}, {0x1f94e, 929}, - {0x1f94f, 930}, {0x1f950, 931}, {0x1f951, 932}, {0x1f952, 933}, {0x1f953, 934}, {0x1f954, 935}, - {0x1f955, 936}, {0x1f956, 937}, {0x1f957, 938}, {0x1f958, 939}, {0x1f959, 940}, {0x1f95a, 941}, - {0x1f95b, 942}, {0x1f95c, 943}, {0x1f95d, 944}, {0x1f95e, 945}, {0x1f95f, 946}, {0x1f960, 947}, - {0x1f961, 948}, {0x1f962, 949}, {0x1f963, 950}, {0x1f964, 951}, {0x1f965, 952}, {0x1f966, 953}, - {0x1f967, 954}, {0x1f968, 955}, {0x1f969, 956}, {0x1f96a, 957}, {0x1f96b, 958}, {0x1f96c, 959}, - {0x1f96d, 960}, {0x1f96e, 961}, {0x1f96f, 962}, {0x1f970, 963}, {0x1f973, 964}, {0x1f974, 965}, - {0x1f975, 966}, {0x1f976, 967}, {0x1f97a, 968}, {0x1f97c, 969}, {0x1f97d, 970}, {0x1f97e, 971}, - {0x1f97f, 972}, {0x1f980, 973}, {0x1f981, 974}, {0x1f982, 975}, {0x1f983, 976}, {0x1f984, 977}, - {0x1f985, 978}, {0x1f986, 979}, {0x1f987, 980}, {0x1f988, 981}, {0x1f989, 982}, {0x1f98a, 983}, - {0x1f98b, 984}, {0x1f98c, 985}, {0x1f98d, 986}, {0x1f98e, 987}, {0x1f98f, 988}, {0x1f990, 989}, - {0x1f991, 990}, {0x1f992, 991}, {0x1f993, 992}, {0x1f994, 993}, {0x1f995, 994}, {0x1f996, 995}, - {0x1f997, 996}, {0x1f998, 997}, {0x1f999, 998}, {0x1f99a, 999}, {0x1f99b, 1000}, {0x1f99c, 1001}, - {0x1f99d, 1002}, {0x1f99e, 1003}, {0x1f99f, 1004}, {0x1f9a0, 1005}, {0x1f9a1, 1006}, {0x1f9a2, 1007}, - {0x1f9b0, 1008}, {0x1f9b1, 1009}, {0x1f9b2, 1010}, {0x1f9b3, 1011}, {0x1f9b4, 1012}, {0x1f9b5, 1013}, - {0x1f9b6, 1014}, {0x1f9b7, 1015}, {0x1f9b8, 1016}, {0x1f9b9, 1017}, {0x1f9c0, 1018}, {0x1f9c1, 1019}, - {0x1f9c2, 1020}, {0x1f9d0, 1021}, {0x1f9d1, 1022}, {0x1f9d2, 1023}, {0x1f9d3, 1024}, {0x1f9d4, 1025}, - {0x1f9d5, 1026}, {0x1f9d6, 1027}, {0x1f9d7, 1028}, {0x1f9d8, 1029}, {0x1f9d9, 1030}, {0x1f9da, 1031}, - {0x1f9db, 1032}, {0x1f9dc, 1033}, {0x1f9dd, 1034}, {0x1f9de, 1035}, {0x1f9df, 1036}, {0x1f9e0, 1037}, - {0x1f9e1, 1038}, {0x1f9e2, 1039}, {0x1f9e3, 1040}, {0x1f9e4, 1041}, {0x1f9e5, 1042}, {0x1f9e6, 1043}, - {0x1f9e7, 1044}, {0x1f9e8, 1045}, {0x1f9e9, 1046}, {0x1f9ea, 1047}, {0x1f9eb, 1048}, {0x1f9ec, 1049}, - {0x1f9ed, 1050}, {0x1f9ee, 1051}, {0x1f9ef, 1052}, {0x1f9f0, 1053}, {0x1f9f1, 1054}, {0x1f9f2, 1055}, - {0x1f9f3, 1056}, {0x1f9f4, 1057}, {0x1f9f5, 1058}, {0x1f9f6, 1059}, {0x1f9f7, 1060}, {0x1f9f8, 1061}, - {0x1f9f9, 1062}, {0x1f9fa, 1063}, {0x1f9fb, 1064}, {0x1f9fc, 1065}, {0x1f9fd, 1066}, {0x1f9fe, 1067}, - {0x1f9ff, 1068}, {0x203c, 1069}, {0x2049, 1070}, {0x2122, 1071}, {0x2139, 1072}, {0x2194, 1073}, - {0x2195, 1074}, {0x2196, 1075}, {0x2197, 1076}, {0x2198, 1077}, {0x2199, 1078}, {0x21a9, 1079}, - {0x21aa, 1080}, {0x231a, 1081}, {0x231b, 1082}, {0x2328, 1083}, {0x23cf, 1084}, {0x23e9, 1085}, - {0x23ea, 1086}, {0x23eb, 1087}, {0x23ec, 1088}, {0x23ed, 1089}, {0x23ee, 1090}, {0x23ef, 1091}, - {0x23f0, 1092}, {0x23f1, 1093}, {0x23f2, 1094}, {0x23f3, 1095}, {0x23f8, 1096}, {0x23f9, 1097}, - {0x23fa, 1098}, {0x24c2, 1099}, {0x25aa, 1100}, {0x25ab, 1101}, {0x25b6, 1102}, {0x25c0, 1103}, - {0x25fb, 1104}, {0x25fc, 1105}, {0x25fd, 1106}, {0x25fe, 1107}, {0x2600, 1108}, {0x2601, 1109}, - {0x2602, 1110}, {0x2603, 1111}, {0x2604, 1112}, {0x260e, 1113}, {0x2611, 1114}, {0x2614, 1115}, - {0x2615, 1116}, {0x2618, 1117}, {0x261d, 1118}, {0x2620, 1119}, {0x2622, 1120}, {0x2623, 1121}, - {0x2626, 1122}, {0x262a, 1123}, {0x262e, 1124}, {0x262f, 1125}, {0x2638, 1126}, {0x2639, 1127}, - {0x263a, 1128}, {0x2640, 1129}, {0x2642, 1130}, {0x2648, 1131}, {0x2649, 1132}, {0x264a, 1133}, - {0x264b, 1134}, {0x264c, 1135}, {0x264d, 1136}, {0x264e, 1137}, {0x264f, 1138}, {0x2650, 1139}, - {0x2651, 1140}, {0x2652, 1141}, {0x2653, 1142}, {0x265f, 1143}, {0x2660, 1144}, {0x2663, 1145}, - {0x2665, 1146}, {0x2666, 1147}, {0x2668, 1148}, {0x267b, 1149}, {0x267e, 1150}, {0x267f, 1151}, - {0x2692, 1152}, {0x2693, 1153}, {0x2694, 1154}, {0x2695, 1155}, {0x2696, 1156}, {0x2697, 1157}, - {0x2699, 1158}, {0x269b, 1159}, {0x269c, 1160}, {0x26a0, 1161}, {0x26a1, 1162}, {0x26aa, 1163}, - {0x26ab, 1164}, {0x26b0, 1165}, {0x26b1, 1166}, {0x26bd, 1167}, {0x26be, 1168}, {0x26c4, 1169}, - {0x26c5, 1170}, {0x26c8, 1171}, {0x26ce, 1172}, {0x26cf, 1173}, {0x26d1, 1174}, {0x26d3, 1175}, - {0x26d4, 1176}, {0x26e9, 1177}, {0x26ea, 1178}, {0x26f0, 1179}, {0x26f1, 1180}, {0x26f2, 1181}, - {0x26f3, 1182}, {0x26f4, 1183}, {0x26f5, 1184}, {0x26f7, 1185}, {0x26f8, 1186}, {0x26f9, 1187}, - {0x26fa, 1188}, {0x26fd, 1189}, {0x2702, 1190}, {0x2705, 1191}, {0x2708, 1192}, {0x2709, 1193}, - {0x270a, 1194}, {0x270b, 1195}, {0x270c, 1196}, {0x270d, 1197}, {0x270f, 1198}, {0x2712, 1199}, - {0x2714, 1200}, {0x2716, 1201}, {0x271d, 1202}, {0x2721, 1203}, {0x2728, 1204}, {0x2733, 1205}, - {0x2734, 1206}, {0x2744, 1207}, {0x2747, 1208}, {0x274c, 1209}, {0x274e, 1210}, {0x2753, 1211}, - {0x2754, 1212}, {0x2755, 1213}, {0x2757, 1214}, {0x2763, 1215}, {0x2764, 1216}, {0x2795, 1217}, - {0x2796, 1218}, {0x2797, 1219}, {0x27a1, 1220}, {0x27b0, 1221}, {0x27bf, 1222}, {0x2934, 1223}, - {0x2935, 1224}, {0x2b05, 1225}, {0x2b06, 1226}, {0x2b07, 1227}, {0x2b1b, 1228}, {0x2b1c, 1229}, - {0x2b50, 1230}, {0x2b55, 1231}, {0x3030, 1232}, {0x303d, 1233}, {0x3297, 1234}, {0x3299, 1235}, - }; + public static Dictionary emojiLookupTable { + get { + return configuration.emojiLookupTable; + } + } - public static readonly HashSet SingleCharEmojiCodePoints = new HashSet { - 0x203c, 0x2049, 0x2122, 0x2139, 0x2194, - 0x2195, 0x2196, 0x2197, 0x2198, 0x2199, 0x21a9, - 0x21aa, 0x231a, 0x231b, 0x2328, 0x23cf, 0x23e9, - 0x23ea, 0x23eb, 0x23ec, 0x23ed, 0x23ee, 0x23ef, - 0x23f0, 0x23f1, 0x23f2, 0x23f3, 0x23f8, 0x23f9, - 0x23fa, 0x24c2, 0x25aa, 0x25ab, 0x25b6, 0x25c0, - 0x25fb, 0x25fc, 0x25fd, 0x25fe, 0x2600, 0x2601, - 0x2602, 0x2603, 0x2604, 0x260e, 0x2611, 0x2614, - 0x2615, 0x2618, 0x261d, 0x2620, 0x2622, 0x2623, - 0x2626, 0x262a, 0x262e, 0x262f, 0x2638, 0x2639, - 0x263a, 0x2640, 0x2642, 0x2648, 0x2649, 0x264a, - 0x264b, 0x264c, 0x264d, 0x264e, 0x264f, 0x2650, - 0x2651, 0x2652, 0x2653, 0x265f, 0x2660, 0x2663, - 0x2665, 0x2666, 0x2668, 0x267b, 0x267e, 0x267f, - 0x2692, 0x2693, 0x2694, 0x2695, 0x2696, 0x2697, - 0x2699, 0x269b, 0x269c, 0x26a0, 0x26a1, 0x26aa, - 0x26ab, 0x26b0, 0x26b1, 0x26bd, 0x26be, 0x26c4, - 0x26c5, 0x26c8, 0x26ce, 0x26cf, 0x26d1, 0x26d3, - 0x26d4, 0x26e9, 0x26ea, 0x26f0, 0x26f1, 0x26f2, - 0x26f3, 0x26f4, 0x26f5, 0x26f7, 0x26f8, 0x26f9, - 0x26fa, 0x26fd, 0x2702, 0x2705, 0x2708, 0x2709, - 0x270a, 0x270b, 0x270c, 0x270d, 0x270f, 0x2712, - 0x2714, 0x2716, 0x271d, 0x2721, 0x2728, 0x2733, - 0x2734, 0x2744, 0x2747, 0x274c, 0x274e, 0x2753, - 0x2754, 0x2755, 0x2757, 0x2763, 0x2764, 0x2795, - 0x2796, 0x2797, 0x27a1, 0x27b0, 0x27bf, 0x2934, - 0x2935, 0x2b05, 0x2b06, 0x2b07, 0x2b1b, 0x2b1c, - 0x2b50, 0x2b55, 0x3030, 0x303d, 0x3297, 0x3299, - }; + public static int rowCount { + get { return configuration.spriteSheetNumberOfRows; } + } - public const int rowCount = 35; - public const int colCount = 36; + public static int colCount { + get { return configuration.spriteSheetNumberOfColumns; } + } + + public static float advanceFactor = 1.3f; + public static float sizeFactor = 1.2f; + public const int emptyEmojiCode = 0xfe0f; public static Rect getMinMaxRect(float fontSize, float ascent, float descent) { - return Rect.fromLTWH(fontSize * 0.05f, descent - fontSize, fontSize * 0.9f, fontSize * 0.9f); + return Rect.fromLTWH((advanceFactor - sizeFactor) / 2 * fontSize, + descent - fontSize * sizeFactor, + fontSize * sizeFactor, + fontSize * sizeFactor); } public static Rect getUVRect(int code) { bool exist = emojiLookupTable.TryGetValue(code, out int index); + if(!exist) { + exist = emojiLookupTable.TryGetValue(emptyEmojiCode, out index); + D.assert(() => { + Debug.LogWarning($"Unrecognized unicode for emoji {code:x}"); + return true; + }); + } if (exist) { return Rect.fromLTWH( (index % colCount) * (1.0f / colCount), @@ -281,10 +501,6 @@ public static Rect getUVRect(int code) { 1.0f / colCount, 1.0f / rowCount); } - D.assert(() => { - Debug.LogWarning($"Unrecognized unicode for emoji {code:x}"); - return true; - }); return Rect.fromLTWH(0, 0, 0, 0); } @@ -293,11 +509,11 @@ public static bool isSingleCharEmoji(int c) { } public static bool isSingleCharNonEmptyEmoji(int c) { - return SingleCharEmojiCodePoints.Contains(c); + return c <= 0xffff && emojiLookupTable.ContainsKey(c); } public static bool isEmptyEmoji(int c) { - return c == 0xFE0F; + return c == emptyEmojiCode && !emojiLookupTable.ContainsKey(c); } public static List splitByEmoji(string text) { diff --git a/Runtime/ui/txt/layout.cs b/Runtime/ui/txt/layout.cs index 54f39bb6..e13c8bff 100644 --- a/Runtime/ui/txt/layout.cs +++ b/Runtime/ui/txt/layout.cs @@ -8,7 +8,7 @@ public static float measureText(string text, TextStyle style) { char startingChar = text[0]; float totalWidth = 0; if (char.IsHighSurrogate(startingChar) || EmojiUtils.isSingleCharEmoji(startingChar)) { - float advance = style.fontSize + style.letterSpacing; + float advance = style.fontSize * EmojiUtils.advanceFactor + style.letterSpacing; for (int i = 0; i < text.Length; i++) { char ch = text[i]; if (char.IsHighSurrogate(ch) || EmojiUtils.isSingleCharNonEmptyEmoji(ch)) { @@ -42,7 +42,7 @@ public static int computeTruncateCount(float offset, string text, int start, int char startingChar = text[start]; float currentAdvance = offset; if (char.IsHighSurrogate(startingChar) || EmojiUtils.isSingleCharEmoji(startingChar)) { - float advance = style.fontSize + style.letterSpacing; + float advance = style.fontSize * EmojiUtils.advanceFactor + style.letterSpacing; for (int i = 0; i < count; i++) { char ch = text[start + i]; if (char.IsHighSurrogate(ch) || EmojiUtils.isSingleCharNonEmptyEmoji(ch)) { @@ -85,7 +85,7 @@ public static float computeCharWidths(float offset, string text, int start, int char startingChar = text[start]; float totalWidths = 0; if (char.IsHighSurrogate(startingChar) || EmojiUtils.isSingleCharEmoji(startingChar)) { - float advance = style.fontSize + style.letterSpacing; + float advance = style.fontSize * EmojiUtils.advanceFactor + style.letterSpacing; for (int i = 0; i < count; i++) { char ch = text[start + i]; if (char.IsHighSurrogate(ch) || EmojiUtils.isSingleCharNonEmptyEmoji(ch)) { @@ -224,16 +224,15 @@ static float _layoutEmoji(string text, int start, int count, TextStyle style, Fo x += letterSpaceHalfLeft; advances[i] = letterSpaceHalfLeft; - + float advance = style.fontSize * EmojiUtils.advanceFactor; var minX = x; - var maxX = metrics.descent - metrics.ascent + x; - var minY = metrics.ascent; + var maxX = advance + x; + var minY = -style.fontSize * EmojiUtils.sizeFactor; var maxY = metrics.descent; _updateBounds(minX, maxX, minY, maxY, ref bounds); positions[i] = x; - float advance = style.fontSize; x += advance; advances[i] += advance; diff --git a/Runtime/ui/txt/paragraph.cs b/Runtime/ui/txt/paragraph.cs index e61b1214..4394344a 100644 --- a/Runtime/ui/txt/paragraph.cs +++ b/Runtime/ui/txt/paragraph.cs @@ -1,1589 +1,1125 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using Unity.UIWidgets.foundation; -using UnityEngine; - -namespace Unity.UIWidgets.ui { - struct CodeUnitRun { - public readonly int lineNumber; - public readonly TextDirection direction; - public readonly Range codeUnits; - public Range xPos; - public readonly int start; - public readonly int count; - - public CodeUnitRun(Range cu, Range xPos, int line, - TextDirection direction, int start, int count) { - this.lineNumber = line; - this.codeUnits = cu; - this.xPos = xPos; - this.direction = direction; - this.start = start; - this.count = count; - } - - public GlyphPosition get(int i, GlyphPosition[] glyphPositions) { - D.assert(i < this.count); - return glyphPositions[this.start + i]; - } - } - - - struct FontMetrics { - public readonly float ascent; - public readonly float leading; - public readonly float descent; - public readonly float? underlineThickness; - public readonly float? underlinePosition; - public readonly float? strikeoutPosition; - public readonly float? fxHeight; - - static FontMetrics _previousFontMetrics; - static Font _previousFont; - static int _previousFontSize; - - public FontMetrics(float ascent, float descent, - float? underlineThickness = null, float? underlinePosition = null, float? strikeoutPosition = null, - float? fxHeight = null) { - this.ascent = ascent; - this.descent = descent; - this.underlineThickness = underlineThickness; - this.underlinePosition = underlinePosition; - this.strikeoutPosition = strikeoutPosition; - this.fxHeight = fxHeight; - this.leading = 0.0f; - } - - public static FontMetrics fromFont(Font font, int fontSize) { - if (fontSize == _previousFontSize && ReferenceEquals(font, _previousFont)) { - return _previousFontMetrics; - } - - var ascent = -font.ascent * fontSize / font.fontSize; - var descent = (font.lineHeight - font.ascent) * fontSize / font.fontSize; - font.RequestCharactersInTextureSafe("x", fontSize, UnityEngine.FontStyle.Normal); - font.getGlyphInfo('x', out var glyphInfo, fontSize, UnityEngine.FontStyle.Normal); - float fxHeight = glyphInfo.glyphHeight; - _previousFontMetrics = new FontMetrics(ascent, descent, fxHeight: fxHeight); - _previousFontSize = fontSize; - _previousFont = font; - - return _previousFontMetrics; - } - } - - struct PositionWithAffinity { - public readonly int position; - public readonly TextAffinity affinity; - - public PositionWithAffinity(int p, TextAffinity a) { - this.position = p; - this.affinity = a; - } - } - - struct GlyphPosition { - public Range xPos; - public readonly int codeUnit; - - public GlyphPosition(float start, float advance, int codeUnit) { - this.xPos = new Range(start, start + advance); - this.codeUnit = codeUnit; - } - - public void shiftSelf(float shift) { - this.xPos = new Range(this.xPos.start + shift, this.xPos.end + shift); - } - } - - struct Range : IEquatable> { - public Range(T start, T end) { - this.start = start; - this.end = end; - } - - public bool Equals(Range other) { - return EqualityComparer.Default.Equals(this.start, other.start) && - EqualityComparer.Default.Equals(this.end, other.end); - } - - public override bool Equals(object obj) { - if (ReferenceEquals(null, obj)) { - return false; - } - - return obj is Range && this.Equals((Range) obj); - } - - public override int GetHashCode() { - unchecked { - return (EqualityComparer.Default.GetHashCode(this.start) * 397) ^ - EqualityComparer.Default.GetHashCode(this.end); - } - } - - public static bool operator ==(Range left, Range right) { - return left.Equals(right); - } - - public static bool operator !=(Range left, Range right) { - return !left.Equals(right); - } - - public readonly T start, end; - } - - struct GlyphLine { - public readonly int start; - public readonly int count; - - public GlyphLine(int start, int count) { - this.start = start; - this.count = count; - } - - public GlyphPosition get(int i, GlyphPosition[] glyphPositions) { - return glyphPositions[this.start + i]; - } - - public GlyphPosition last(GlyphPosition[] glyphPositions) { - return glyphPositions[this.start + this.count - 1]; - } - } - - - public class Paragraph { - public struct LineRange { - public LineRange(int start, int end, int endExcludingWhitespace, int endIncludingNewLine, bool hardBreak) { - this.start = start; - this.end = end; - this.endExcludingWhitespace = endExcludingWhitespace; - this.endIncludingNewLine = endIncludingNewLine; - this.hardBreak = hardBreak; - } - - public readonly int start; - public readonly int end; - public readonly int endExcludingWhitespace; - public readonly int endIncludingNewLine; - public readonly bool hardBreak; - } - - bool _needsLayout = true; - - string _text; - string _ellipsizedText; - int _ellipsizedLength; - - StyledRuns _runs; - - ParagraphStyle _paragraphStyle; - List _lineRanges = new List(); - - List _lineWidths = new List(); - - GlyphLine[] _glyphLines; - GlyphPosition[] _glyphPositions; - PaintRecord[] _paintRecords; - CodeUnitRun[] _codeUnitRuns; - float[] _lineHeights; - float[] _textBlobPositionXs; - float _maxIntrinsicWidth; - float _minIntrinsicWidth; - float _alphabeticBaseline; - float _ideographicBaseline; - int _lineCount; - int _paintRecordsCount; - int _codeUnitRunsCount; - int _lineRangeCount; - int _lineWidthCount; - bool _didExceedMaxLines; - TabStops _tabStops = new TabStops(); - - static float[] _advancesBuffer; - static float[] _positionsBuffer; - static Range[] _wordsBuffer; - - // private float _characterWidth; - - float _width; - - const float kFloatDecorationSpacing = 3.0f; - - public float height { - get { - if (this._lineHeights == null) { - return 0; - } - - return this._lineHeights[this.getLineCount() - 1]; - } - } - - public float minIntrinsicWidth { - get { return this._minIntrinsicWidth; } - } - - public float maxIntrinsicWidth { - get { return this._maxIntrinsicWidth; } - } - - public float width { - get { return this._width; } - } - - - public float alphabeticBaseline { - get { return this._alphabeticBaseline; } - } - - public float ideographicBaseline { - get { return this._ideographicBaseline; } - } - - public bool didExceedMaxLines { - get { return this._didExceedMaxLines; } - } - - static List _paragraphPool = new List(); - - public static Paragraph create() { - if (_paragraphPool.isEmpty()) { - return new Paragraph(); - } - - Paragraph ret = _paragraphPool.last(); - _paragraphPool.RemoveAt(_paragraphPool.Count - 1); - return ret; - } - - public static void release(ref Paragraph paragraph) { - if (paragraph != null) { - paragraph.clear(); - _paragraphPool.Add(paragraph); - paragraph = null; - } - } - - public void clear() { - this._needsLayout = true; - this._maxIntrinsicWidth = default; - this._minIntrinsicWidth = default; - this._alphabeticBaseline = default; - this._ideographicBaseline = default; - this._lineCount = default; - this._paintRecordsCount = default; - this._codeUnitRunsCount = default; - this._lineRangeCount = default; - this._lineWidthCount = default; - this._didExceedMaxLines = default; - this._width = default; - this._text = default; - this._ellipsizedText = default; - this._ellipsizedLength = default; - this._runs = null; - this._paragraphStyle = null; - } - - readonly Paint _textPaint = new Paint { - filterMode = FilterMode.Bilinear - }; - - public void paint(Canvas canvas, Offset offset) { - for (int i = 0; i < this._paintRecordsCount; i++) { - var paintRecord = this._paintRecords[i]; - this.paintBackground(canvas, paintRecord, offset); - } - - for (int i = 0; i < this._paintRecordsCount; i++) { - var paintRecord = this._paintRecords[i]; - this._textPaint.color = paintRecord.style.color; - canvas.drawTextBlob(paintRecord.text, paintRecord.shiftedOffset(offset), this._textPaint); - this.paintDecorations(canvas, paintRecord, offset); - } - } - - public void layout(ParagraphConstraints constraints) { - if (!this._needsLayout && this._width == constraints.width) { - return; - } - - this._tabStops.setFont( - FontManager.instance.getOrCreate( - this._paragraphStyle.fontFamily ?? TextStyle.kDefaultFontFamily, - this._paragraphStyle.fontWeight ?? TextStyle.kDefaultFontWeight, - this._paragraphStyle.fontStyle ?? TextStyle.kDefaultfontStyle).font, - (int) (this._paragraphStyle.fontSize ?? TextStyle.kDefaultFontSize)); - - this._needsLayout = false; - this._width = Mathf.Floor(constraints.width); - - int lineStyleRunsCount = this._computeLineBreak(); - - if (this._glyphLines == null || this._glyphLines.Length < this._lineRangeCount) { - this._glyphLines = new GlyphLine[LayoutUtils.minPowerOfTwo(this._lineRangeCount)]; - } - - if (this._lineHeights == null || this._lineHeights.Length < this._lineRangeCount) { - this._lineHeights = new float[LayoutUtils.minPowerOfTwo(this._lineRangeCount)]; - } - - if (this._paintRecords == null || this._paintRecords.Length < lineStyleRunsCount) { - this._paintRecords = new PaintRecord[LayoutUtils.minPowerOfTwo(lineStyleRunsCount)]; - } - - this._paintRecordsCount = 0; - - if (this._codeUnitRuns == null || this._codeUnitRuns.Length < lineStyleRunsCount) { - this._codeUnitRuns = new CodeUnitRun[LayoutUtils.minPowerOfTwo(lineStyleRunsCount)]; - } - - this._codeUnitRunsCount = 0; - - int styleMaxLines = this._paragraphStyle.maxLines ?? int.MaxValue; - this._didExceedMaxLines = this._lineRangeCount > styleMaxLines; - - var lineLimit = Mathf.Min(styleMaxLines, this._lineRangeCount); - int styleRunIndex = 0; - float yOffset = 0; - float preMaxDescent = 0; - float maxWordWidth = 0; - - TextBlobBuilder builder = new TextBlobBuilder(); - int ellipsizedLength = this._text.Length + (this._paragraphStyle.ellipsis?.Length ?? 0); - - // All text blobs share a single position buffer, which is big enough taking ellipsis into consideration - if (this._textBlobPositionXs == null || this._textBlobPositionXs.Length < ellipsizedLength) { - this._textBlobPositionXs = new float[LayoutUtils.minPowerOfTwo(ellipsizedLength)]; - } - - builder.setPositionXs(this._textBlobPositionXs); - // this._glyphLines and this._codeUnitRuns will refer to this array for glyph positions - if (this._glyphPositions == null || this._glyphPositions.Length < ellipsizedLength) { - this._glyphPositions = new GlyphPosition[LayoutUtils.minPowerOfTwo(ellipsizedLength)]; - } - - // Pointer to the _glyphPositions array, to keep track of where the next glyph is stored - int pGlyphPositions = 0; - - // Compute max(NumberOfWords(line) for line in lines), to determine the size of word buffers - int maxWordCount = this._computeMaxWordCount(); - - if (_wordsBuffer == null || _wordsBuffer.Length < maxWordCount) { - _wordsBuffer = new Range[maxWordCount < 4 ? 4 : maxWordCount]; - } - - // Iterate through line ranges - for (int lineNumber = 0; lineNumber < lineLimit; ++lineNumber) { - var lineRange = this._lineRanges[lineNumber]; - int wordIndex = 0; - float runXOffset = 0; - float justifyXOffset = 0; - - // Break the line into words if justification should be applied. - bool justifyLine = this._paragraphStyle.textAlign == TextAlign.justify && - lineNumber != lineLimit - 1 && !lineRange.hardBreak && - // Do not apply justify if ellipsis should be added, or the ellipsis may be pushed - // out of the border. - // This is still not taken care of in the flutter engine. - !(this._paragraphStyle.ellipsized() && this._paragraphStyle.maxLines == null); - - int wordCount = this._findWords(lineRange.start, lineRange.end, _wordsBuffer); - float wordGapWidth = !(justifyLine && wordCount > 1) - ? 0 - : (this._width - this._lineWidths[lineNumber]) / (wordCount - 1); - - // Count the number of style runs, and compute the character number of the longest run by the way - int lineStyleRunCount = this._countLineStyleRuns(lineRange, styleRunIndex, out int maxTextCount); - - string ellipsis = this._paragraphStyle.ellipsis; - bool hardBreak = lineRange.hardBreak; - - if (!string.IsNullOrEmpty(ellipsis) && !hardBreak && !this._width.isInfinite() && - (lineNumber == lineLimit - 1 || this._paragraphStyle.maxLines == null)) { - maxTextCount += ellipsis.Length; - } - - // Allocate the advances and positions to store the layout result - // TODO: find a way to compute the maxTextCount for the entire paragraph, so that this allocation - // happens only once - if (_advancesBuffer == null || _advancesBuffer.Length < maxTextCount) { - _advancesBuffer = new float[LayoutUtils.minPowerOfTwo(maxTextCount)]; - } - - if (_positionsBuffer == null || _positionsBuffer.Length < maxTextCount) { - _positionsBuffer = new float[LayoutUtils.minPowerOfTwo(maxTextCount)]; - } - - // Keep of the position in _glyphPositions before evaluating this line - int glyphPositionLineStart = pGlyphPositions; - - if (lineStyleRunCount != 0) { - // Exclude trailing whitespace from right-justified lines so the last - // visible character in the line will be flush with the right margin. - int lineEndIndex = this._paragraphStyle.textAlign == TextAlign.right || - this._paragraphStyle.textAlign == TextAlign.center - ? lineRange.endExcludingWhitespace - : lineRange.end; - int lineStyleRunIndex = 0; - - // Instead of computing all lineStyleRuns at once and store into an array and iterate through them, - // compute each lineStyleRun and deal with it on the fly, to save the storage for the runs - while (styleRunIndex < this._runs.size) { - var styleRun = this._runs.getRun(styleRunIndex); - // Compute the intersection between current style run intersects and the line - int start = Mathf.Max(styleRun.start, lineRange.start); - int end = Mathf.Min(styleRun.end, lineEndIndex); - // Make sure that each run is not empty - if (start < end) { - var style = styleRun.style; - string text = this._text; - int textStart = start; - int textEnd = end; - int textCount = textEnd - textStart; - // Keep track of the pointer to _glyphPositions in the start of this run - int glyphPositionStyleRunStart = pGlyphPositions; - - // Ellipsize the text if ellipsis string is set, and this is the last lineStyleRun of - // the current line, and this is the last line or max line is not set - if (!string.IsNullOrEmpty(ellipsis) && !hardBreak && !this._width.isInfinite() && - lineStyleRunIndex == lineStyleRunCount - 1 && - (lineNumber == lineLimit - 1 || this._paragraphStyle.maxLines == null)) { - float ellipsisWidth = Layout.measureText(ellipsis, style); - - // Find the minimum number of characters to truncate, so that the truncated text - // appended with ellipsis is within the constraints of line width - int truncateCount = Layout.computeTruncateCount(runXOffset, text, textStart, - textCount, style, this._width - ellipsisWidth, this._tabStops); - - // If all the positions have not changed, use the cached ellipsized text - // else update the cache - if (!(this._ellipsizedLength == textStart + textCount - truncateCount && - this._ellipsizedText.Length == this._ellipsizedLength + ellipsis.Length && - this._ellipsizedText.EndsWith(ellipsis))) { - this._ellipsizedText = - text.Substring(0, textStart + textCount - truncateCount) + ellipsis; - this._ellipsizedLength = this._ellipsizedText.Length - ellipsis.Length; - } - - text = this._ellipsizedText; - textCount = text.Length - textStart; - D.assert(textCount != 0); - if (this._paragraphStyle.maxLines == null) { - lineLimit = lineNumber + 1; - this._didExceedMaxLines = true; - } - } - - float advance = Layout.doLayout(runXOffset, text, textStart, textCount, style, - _advancesBuffer, _positionsBuffer, this._tabStops, out var bounds); - - builder.allocRunPos(style, text, textStart, textCount); - builder.setBounds(bounds); - - // Update the max width of the words - // Fill in the glyph positions, and the positions of the text blob builder - float wordStartPosition = float.NaN; - for (int glyphIndex = 0; glyphIndex < textCount; ++glyphIndex) { - float glyphXOffset = _positionsBuffer[glyphIndex] + justifyXOffset; - float glyphAdvance = _advancesBuffer[glyphIndex]; - builder.setPositionX(glyphIndex, glyphXOffset); - this._glyphPositions[pGlyphPositions++] = new GlyphPosition(runXOffset + glyphXOffset, - glyphAdvance, textStart + glyphIndex); - if (wordIndex < wordCount) { - Range word = _wordsBuffer[wordIndex]; - // Run into the start of current word, record the start position of this word - if (word.start == start + glyphIndex) { - wordStartPosition = runXOffset + glyphXOffset; - } - - // Run into the end of current word - if (word.end == start + glyphIndex + 1) { - if (justifyLine) { - justifyXOffset += wordGapWidth; - } - - // Update the current word - wordIndex++; - // If the start position of this word has been recorded, calculate the - // width of this word, and update the entire word - if (!float.IsNaN(wordStartPosition)) { - maxWordWidth = Mathf.Max(maxWordWidth, - this._glyphPositions[pGlyphPositions - 1].xPos.end - wordStartPosition); - wordStartPosition = float.NaN; - } - } - } - } - - // Create paint record - var font = FontManager.instance.getOrCreate(style.fontFamily, - style.fontWeight, style.fontStyle).font; - var metrics = FontMetrics.fromFont(font, style.UnityFontSize); - PaintRecord paintRecord = new PaintRecord(style, runXOffset, 0, builder.make(), - metrics, advance); - this._paintRecords[this._paintRecordsCount++] = paintRecord; - runXOffset += advance; - - // Create code unit run - this._codeUnitRuns[this._codeUnitRunsCount++] = new CodeUnitRun( - new Range(start, end), - new Range(this._glyphPositions[glyphPositionStyleRunStart].xPos.start, - this._glyphPositions[pGlyphPositions - 1].xPos.end), - lineNumber, TextDirection.ltr, glyphPositionStyleRunStart, textCount); - - lineStyleRunIndex++; - } - - if (styleRun.end >= lineEndIndex) { - break; - } - - styleRunIndex++; - } - } - - float maxLineSpacing = 0; - float maxDescent = 0; - - void updateLineMetrics(FontMetrics metrics, float styleHeight) { - float lineSpacing = lineNumber == 0 - ? -metrics.ascent * styleHeight - : (-metrics.ascent + metrics.leading) * styleHeight; - if (lineSpacing > maxLineSpacing) { - maxLineSpacing = lineSpacing; - if (lineNumber == 0) { - this._alphabeticBaseline = lineSpacing; - this._ideographicBaseline = - (metrics.underlinePosition ?? 0.0f - metrics.ascent) * styleHeight; - } - } - - float descent = metrics.descent * styleHeight; - maxDescent = Mathf.Max(descent, maxDescent); - } - - if (lineStyleRunCount != 0) { - for (int i = 0; i < lineStyleRunCount; i++) { - var paintRecord = this._paintRecords[this._paintRecordsCount - i - 1]; - updateLineMetrics(paintRecord.metrics, paintRecord.style.height); - } - } - else { - var defaultFont = FontManager.instance.getOrCreate( - this._paragraphStyle.fontFamily ?? TextStyle.kDefaultFontFamily, - this._paragraphStyle.fontWeight ?? TextStyle.kDefaultFontWeight, - this._paragraphStyle.fontStyle ?? TextStyle.kDefaultfontStyle).font; - var metrics = FontMetrics.fromFont(defaultFont, - (int) (this._paragraphStyle.fontSize ?? TextStyle.kDefaultFontSize)); - updateLineMetrics(metrics, this._paragraphStyle.lineHeight ?? TextStyle.kDefaultHeight); - } - - this._lineHeights[lineNumber] = ((lineNumber == 0 ? 0 : this._lineHeights[lineNumber - 1]) - + Mathf.Round(maxLineSpacing + maxDescent)); - yOffset += Mathf.Round(maxLineSpacing + preMaxDescent); - preMaxDescent = maxDescent; - float lineXOffset = this.getLineXOffset(runXOffset); - int count = pGlyphPositions - glyphPositionLineStart; - if (lineXOffset != 0 && this._glyphPositions != null) { - for (int i = 0; i < count; ++i) { - this._glyphPositions[this._glyphPositions.Length - i - 1].shiftSelf(lineXOffset); - } - } - - this._glyphLines[lineNumber] = new GlyphLine(glyphPositionLineStart, count); - for (int i = 0; i < lineStyleRunCount; i++) { - var paintRecord = this._paintRecords[this._paintRecordsCount - 1 - i]; - paintRecord.shift(lineXOffset, yOffset); - this._paintRecords[this._paintRecordsCount - 1 - i] = paintRecord; - } - } - - this._lineCount = lineLimit; - - // min intrinsic width := minimum width this paragraph has to take, which equals the maximum word width - if (this._paragraphStyle.maxLines == 1 || (this._paragraphStyle.maxLines == null && - this._paragraphStyle.ellipsized())) { - this._minIntrinsicWidth = this.maxIntrinsicWidth; - } - else { - this._minIntrinsicWidth = Mathf.Min(maxWordWidth, this.maxIntrinsicWidth); - } - } - - int _countLineStyleRuns(LineRange lineRange, int styleRunIndex, out int maxTextCount) { - // Exclude trailing whitespace from right-justified lines so the last - // visible character in the line will be flush with the right margin. - int lineEndIndex = this._paragraphStyle.textAlign == TextAlign.right || - this._paragraphStyle.textAlign == TextAlign.center - ? lineRange.endExcludingWhitespace - : lineRange.end; - - maxTextCount = 0; - int lineStyleRunCount = 0; - for (int i = styleRunIndex; i < this._runs.size; i++) { - var styleRun = this._runs.getRun(i); - int start = Mathf.Max(styleRun.start, lineRange.start); - int end = Mathf.Min(styleRun.end, lineEndIndex); - // Make sure that each line is not empty - if (start < end) { - lineStyleRunCount++; - maxTextCount = Math.Max(end - start, maxTextCount); - } - - if (styleRun.end >= lineEndIndex) { - break; - } - } - - return lineStyleRunCount; - } - - internal int totalCodeUnitsInLine(int lineNumber) { - int lineStart = this._lineRanges[lineNumber].start; - int nextLineStart = lineNumber < this._lineRangeCount - 1 - ? this._lineRanges[lineNumber + 1].start - : this._text.Length; - return nextLineStart - lineStart; - } - - internal void setText(string text, StyledRuns runs) { - this._text = text; - this._runs = runs; - this._needsLayout = true; - } - - public void setParagraphStyle(ParagraphStyle style) { - this._needsLayout = true; - this._paragraphStyle = style; - } - - public List getRectsForRange(int start, int end) { - var lineBoxes = new SplayTree>(); - foreach (var run in this._codeUnitRuns) { - if (run.codeUnits.start >= end) { - break; - } - - if (run.codeUnits.end <= start) { - continue; - } - - float top = (run.lineNumber == 0) ? 0 : this._lineHeights[run.lineNumber - 1]; - float bottom = this._lineHeights[run.lineNumber]; - float left, right; - if (run.codeUnits.start >= start && run.codeUnits.end <= end) { - left = run.xPos.start; - right = run.xPos.end; - } - else { - left = float.MaxValue; - right = float.MinValue; - for (int i = 0; i < run.count; i++) { - var gp = run.get(i, this._glyphPositions); - if (gp.codeUnit >= start && gp.codeUnit + 1 <= end) { - left = Mathf.Min(left, gp.xPos.start); - right = Mathf.Max(right, gp.xPos.end); - } - } - - if (left == float.MaxValue || right == float.MinValue) { - continue; - } - } - - List boxs; - if (!lineBoxes.TryGetValue(run.lineNumber, out boxs)) { - boxs = new List(); - lineBoxes.Add(run.lineNumber, boxs); - } - - boxs.Add(TextBox.fromLTBD(left, top, right, bottom, run.direction)); - } - - for (int lineNumber = 0; lineNumber < this._lineRangeCount; ++lineNumber) { - var line = this._lineRanges[lineNumber]; - if (line.start >= end) { - break; - } - - if (line.endIncludingNewLine <= start) { - continue; - } - - if (!lineBoxes.ContainsKey(lineNumber)) { - if (line.end != line.endIncludingNewLine && line.end >= start && line.endIncludingNewLine <= end) { - var x = this._lineWidths[lineNumber]; - var top = (lineNumber > 0) ? this._lineHeights[lineNumber - 1] : 0; - var bottom = this._lineHeights[lineNumber]; - lineBoxes.Add(lineNumber, new List { - TextBox.fromLTBD( - x, top, x, bottom, TextDirection.ltr) - }); - } - } - } - - var result = new List(); - foreach (var keyValuePair in lineBoxes) { - result.AddRange(keyValuePair.Value); - } - - return result; - } - - public float? getNextLineStartRectTop() { - if (this._text.Length == 0 || this._text[this._text.Length - 1] != '\n') { - return null; - } - - var lineNumber = this.getLineCount() - 1; - return lineNumber > 0 ? this._lineHeights[lineNumber - 1] : 0; - } - - internal PositionWithAffinity getGlyphPositionAtCoordinate(float dx, float dy) { - if (this._lineHeights == null) { - return new PositionWithAffinity(0, TextAffinity.downstream); - } - - int yIndex; - for (yIndex = 0; yIndex < this.getLineCount() - 1; ++yIndex) { - if (dy < this._lineHeights[yIndex]) { - break; - } - } - - GlyphLine glyphLine = this._glyphLines[yIndex]; - if (glyphLine.count == 0) { - int lineStartIndex = 0; - for (int i = 0; i < yIndex; i++) { - lineStartIndex += this.totalCodeUnitsInLine(i); - } - - return new PositionWithAffinity(lineStartIndex, TextAffinity.downstream); - } - - - GlyphPosition gp = new GlyphPosition(); - bool gpSet = false; - for (int xIndex = 0; xIndex < glyphLine.count; ++xIndex) { - float glyphEnd = xIndex < glyphLine.count - 1 - ? glyphLine.get(xIndex + 1, this._glyphPositions).xPos.start - : glyphLine.get(xIndex, this._glyphPositions).xPos.end; - if (dx < glyphEnd) { - gp = glyphLine.get(xIndex, this._glyphPositions); - gpSet = true; - break; - } - } - - if (!gpSet) { - GlyphPosition lastGlyph = glyphLine.last(this._glyphPositions); - return new PositionWithAffinity(lastGlyph.codeUnit + 1, TextAffinity.upstream); - } - - TextDirection direction = TextDirection.ltr; - foreach (var run in this._codeUnitRuns) { - if (gp.codeUnit >= run.codeUnits.start && gp.codeUnit + 1 <= run.codeUnits.end) { - direction = run.direction; - break; - } - } - - float glyphCenter = (gp.xPos.start + gp.xPos.end) / 2; - if ((direction == TextDirection.ltr && dx < glyphCenter) || - (direction == TextDirection.rtl && dx >= glyphCenter)) { - return new PositionWithAffinity(gp.codeUnit, TextAffinity.downstream); - } - - return new PositionWithAffinity(gp.codeUnit + 1, TextAffinity.upstream); - } - - public int getLine(TextPosition position) { - D.assert(!this._needsLayout); - if (position.offset < 0) { - return 0; - } - - var offset = position.offset; - if (position.affinity == TextAffinity.upstream && offset > 0) { - offset = char.IsSurrogate(this._text[offset - 1]) ? offset - 2 : offset - 1; - } - - var lineCount = this.getLineCount(); - for (int lineIndex = 0; lineIndex < lineCount; ++lineIndex) { - var line = this._lineRanges[lineIndex]; - if ((offset >= line.start && offset < line.endIncludingNewLine)) { - return lineIndex; - } - } - - return Mathf.Max(lineCount - 1, 0); - } - - internal LineRange getLineRange(int lineIndex) { - return this._lineRanges[lineIndex]; - } - - internal Range getWordBoundary(int offset) { - WordSeparate s = new WordSeparate(this._text); - return s.findWordRange(offset); - } - - public int getLineCount() { - return this._lineCount; - } - - int _computeLineBreak() { - this._lineRangeCount = 0; - this._lineWidthCount = 0; - this._maxIntrinsicWidth = 0; - - int lineLimit = this._paragraphStyle.ellipsized() - ? this._paragraphStyle.maxLines ?? 1 - : this._paragraphStyle.maxLines ?? 0; - - var newLinePositions = LineBreaker.newLinePositions(this._text, out int newLineCount); - - var lineBreaker = LineBreaker.instance; - int runIndex = 0; - int countRuns = 0; - for (var newlineIndex = 0; newlineIndex < newLineCount; ++newlineIndex) { - if (lineLimit != 0 && this._lineRangeCount >= lineLimit) { - break; - } - - var blockStart = newlineIndex > 0 ? newLinePositions[newlineIndex - 1] + 1 : 0; - var blockEnd = newLinePositions[newlineIndex]; - var blockSize = blockEnd - blockStart; - if (blockSize == 0) { - this._addEmptyLine(blockStart, blockEnd); - continue; - } - - if (lineLimit != 0 && this._lineRangeCount >= lineLimit) { - break; - } - - this._resetLineBreaker(lineBreaker, blockStart, blockSize, - lineLimit == 0 ? 0 : lineLimit - this._lineRangeCount); - countRuns += this._addStyleRuns(lineBreaker, ref runIndex, blockStart, blockEnd); - - int breaksCount = lineBreaker.computeBreaks(); - countRuns += breaksCount - 1; - this._updateBreaks(lineBreaker, breaksCount, blockStart, blockEnd); - - lineBreaker.finish(); - } - - return countRuns; - } - - void _addLineRangeAndWidth(LineRange lineRange, float width) { - if (this._lineRanges.Count <= this._lineRangeCount) { - this._lineRanges.Add(lineRange); - this._lineRangeCount++; - } - else { - this._lineRanges[this._lineRangeCount++] = lineRange; - } - - if (this._lineWidths.Count <= this._lineWidthCount) { - this._lineWidths.Add(width); - this._lineWidthCount++; - } - else { - this._lineWidths[this._lineWidthCount++] = width; - } - } - - void _addEmptyLine(int blockStart, int blockEnd) { - this._addLineRangeAndWidth(new LineRange(blockStart, blockEnd, blockEnd, - blockEnd < this._text.Length ? blockEnd + 1 : blockEnd, true), 0); - } - - void _resetLineBreaker(LineBreaker lineBreaker, int blockStart, int blockSize, int lineLimit) { - lineBreaker.setLineWidth(this._width); - lineBreaker.resize(blockSize); - lineBreaker.setTabStops(this._tabStops); - lineBreaker.setText(this._text, blockStart, blockSize); - lineBreaker.lineLimit = lineLimit; - } - - int _addStyleRuns(LineBreaker lineBreaker, ref int runIndex, int blockStart, int blockEnd) { - int countRuns = 0; - float lineBlockWidth = 0; - while (runIndex < this._runs.size) { - var run = this._runs.getRun(runIndex); - if (run.start >= blockEnd) { - break; - } - - if (lineBreaker.lineLimit != 0 && lineBreaker.getBreaksCount() >= lineBreaker.lineLimit) { - break; - } - - if (run.end <= blockStart) { - runIndex++; - continue; - } - - int runStart = Mathf.Max(run.start, blockStart) - blockStart; - int runEnd = Mathf.Min(run.end, blockEnd) - blockStart; - lineBlockWidth += lineBreaker.addStyleRun(run.style, runStart, runEnd); - - countRuns++; - - if (run.end > blockEnd) { - break; - } - - runIndex++; - } - - this._maxIntrinsicWidth = Mathf.Max(lineBlockWidth, this._maxIntrinsicWidth); - - return countRuns; - } - - void _updateBreaks(LineBreaker lineBreaker, int breaksCount, int blockStart, int blockEnd) { - for (int i = 0; i < breaksCount; ++i) { - var breakStart = i > 0 ? lineBreaker.getBreak(i - 1) : 0; - var lineStart = breakStart + blockStart; - var lineEnd = lineBreaker.getBreak(i) + blockStart; - bool hardBreak = lineEnd == blockEnd; - var lineEndIncludingNewline = - hardBreak && lineEnd < this._text.Length ? lineEnd + 1 : lineEnd; - var lineEndExcludingWhitespace = lineEnd; - while (lineEndExcludingWhitespace > lineStart && - LayoutUtils.isLineEndSpace(this._text[lineEndExcludingWhitespace - 1])) { - lineEndExcludingWhitespace--; - } - - this._addLineRangeAndWidth(new LineRange(lineStart, lineEnd, - lineEndExcludingWhitespace, lineEndIncludingNewline, hardBreak), lineBreaker.getWidth(i)); - } - } - - int _computeMaxWordCount() { - int max = 0; - for (int lineNumber = 0; lineNumber < this._lineRangeCount; lineNumber++) { - var inWord = false; - int wordCount = 0, start = this._lineRanges[lineNumber].start, end = this._lineRanges[lineNumber].end; - for (int i = start; i < end; ++i) { - bool isSpace = LayoutUtils.isWordSpace(this._text[i]); - if (!inWord && !isSpace) { - inWord = true; - } - else if (inWord && isSpace) { - inWord = false; - wordCount++; - } - } - - if (inWord) { - wordCount++; - } - - if (wordCount > max) { - max = wordCount; - } - } - - return max; - } - - int _findWords(int start, int end, Range[] words) { - var inWord = false; - int wordCount = 0; - int wordStart = 0; - - for (int i = start; i < end; ++i) { - bool isSpace = LayoutUtils.isWordSpace(this._text[i]); - if (!inWord && !isSpace) { - wordStart = i; - inWord = true; - } - else if (inWord && isSpace) { - inWord = false; - words[wordCount++] = new Range(wordStart, i); - } - } - - if (inWord) { - words[wordCount] = new Range(wordStart, end); - } - - return wordCount; - } - - void paintDecorations(Canvas canvas, PaintRecord record, Offset baseOffset) { - if (record.style.decoration == null || record.style.decoration == TextDecoration.none) { - return; - } - - if (record.style.decorationColor == null) { - this._textPaint.color = record.style.color; - } - else { - this._textPaint.color = record.style.decorationColor; - } - - - var width = record.runWidth; - var metrics = record.metrics; - float underLineThickness = metrics.underlineThickness ?? (record.style.fontSize / 14.0f); - this._textPaint.style = PaintingStyle.stroke; - this._textPaint.strokeWidth = underLineThickness; - var recordOffset = record.shiftedOffset(baseOffset); - var x = recordOffset.dx; - var y = recordOffset.dy; - - int decorationCount = 1; - switch (record.style.decorationStyle) { - case TextDecorationStyle.doubleLine: - decorationCount = 2; - break; - } - - - var decoration = record.style.decoration; - for (int i = 0; i < decorationCount; i++) { - float yOffset = i * underLineThickness * kFloatDecorationSpacing; - float yOffsetOriginal = yOffset; - if (decoration != null && decoration.contains(TextDecoration.underline)) { - // underline - yOffset += metrics.underlinePosition ?? underLineThickness; - canvas.drawLine(new Offset(x, y + yOffset), new Offset(x + width, y + yOffset), this._textPaint); - yOffset = yOffsetOriginal; - } - - if (decoration != null && decoration.contains(TextDecoration.overline)) { - yOffset += metrics.ascent; - canvas.drawLine(new Offset(x, y + yOffset), new Offset(x + width, y + yOffset), this._textPaint); - yOffset = yOffsetOriginal; - } - - if (decoration != null && decoration.contains(TextDecoration.lineThrough)) { - yOffset += (decorationCount - 1.0f) * underLineThickness * kFloatDecorationSpacing / -2.0f; - yOffset += metrics.strikeoutPosition ?? (metrics.fxHeight ?? 0) / -2.0f; - canvas.drawLine(new Offset(x, y + yOffset), new Offset(x + width, y + yOffset), this._textPaint); - yOffset = yOffsetOriginal; - } - } - - this._textPaint.style = PaintingStyle.fill; - this._textPaint.strokeWidth = 0; - } - - void paintBackground(Canvas canvas, PaintRecord record, Offset baseOffset) { - if (record.style.background == null) { - return; - } - - var metrics = record.metrics; - Rect rect = Rect.fromLTRB(0, metrics.ascent, record.runWidth, metrics.descent); - rect = rect.shift(record.shiftedOffset(baseOffset)); - canvas.drawRect(rect, record.style.background); - } - - float getLineXOffset(float lineTotalAdvance) { - if (this._width.isInfinite()) { - return 0; - } - - if (this._paragraphStyle.textAlign == TextAlign.right) { - return this._width - lineTotalAdvance; - } - - if (this._paragraphStyle.textAlign == TextAlign.center) { - return (this._width - lineTotalAdvance) / 2; - } - - return 0; - } - } - - class SplayTree : IDictionary where TKey : IComparable { - SplayTreeNode root; - int count; - int version = 0; - - public void Add(TKey key, TValue value) { - this.Set(key, value, throwOnExisting: true); - } - - public void Add(KeyValuePair item) { - this.Set(item.Key, item.Value, throwOnExisting: true); - } - - void Set(TKey key, TValue value, bool throwOnExisting) { - if (this.count == 0) { - this.version++; - this.root = new SplayTreeNode(key, value); - this.count = 1; - return; - } - - this.Splay(key); - - var c = key.CompareTo(this.root.Key); - if (c == 0) { - if (throwOnExisting) { - throw new ArgumentException("An item with the same key already exists in the tree."); - } - - this.version++; - this.root.Value = value; - return; - } - - var n = new SplayTreeNode(key, value); - if (c < 0) { - n.LeftChild = this.root.LeftChild; - n.RightChild = this.root; - this.root.LeftChild = null; - } - else { - n.RightChild = this.root.RightChild; - n.LeftChild = this.root; - this.root.RightChild = null; - } - - this.root = n; - this.count++; - this.Splay(key); - this.version++; - } - - public void Clear() { - this.root = null; - this.count = 0; - this.version++; - } - - public bool ContainsKey(TKey key) { - if (this.count == 0) { - return false; - } - - this.Splay(key); - - return key.CompareTo(this.root.Key) == 0; - } - - public bool Contains(KeyValuePair item) { - if (this.count == 0) { - return false; - } - - this.Splay(item.Key); - - return item.Key.CompareTo(this.root.Key) == 0 && - (ReferenceEquals(this.root.Value, item.Value) || - (!ReferenceEquals(item.Value, null) && item.Value.Equals(this.root.Value))); - } - - public KeyValuePair First() { - SplayTreeNode t = this.root; - if (t == null) { - throw new NullReferenceException("The root of this tree is null!"); - } - - while (t.LeftChild != null) { - t = t.LeftChild; - } - - return new KeyValuePair(t.Key, t.Value); - } - - public KeyValuePair FirstOrDefault() { - SplayTreeNode t = this.root; - if (t == null) { - return new KeyValuePair(default(TKey), default(TValue)); - } - - while (t.LeftChild != null) { - t = t.LeftChild; - } - - return new KeyValuePair(t.Key, t.Value); - } - - public KeyValuePair Last() { - SplayTreeNode t = this.root; - if (t == null) { - throw new NullReferenceException("The root of this tree is null!"); - } - - while (t.RightChild != null) { - t = t.RightChild; - } - - return new KeyValuePair(t.Key, t.Value); - } - - public KeyValuePair LastOrDefault() { - SplayTreeNode t = this.root; - if (t == null) { - return new KeyValuePair(default(TKey), default(TValue)); - } - - while (t.RightChild != null) { - t = t.RightChild; - } - - return new KeyValuePair(t.Key, t.Value); - } - - void Splay(TKey key) { - SplayTreeNode l, r, t, y, header; - l = r = header = new SplayTreeNode(default(TKey), default(TValue)); - t = this.root; - while (true) { - var c = key.CompareTo(t.Key); - if (c < 0) { - if (t.LeftChild == null) { - break; - } - - if (key.CompareTo(t.LeftChild.Key) < 0) { - y = t.LeftChild; - t.LeftChild = y.RightChild; - y.RightChild = t; - t = y; - if (t.LeftChild == null) { - break; - } - } - - r.LeftChild = t; - r = t; - t = t.LeftChild; - } - else if (c > 0) { - if (t.RightChild == null) { - break; - } - - if (key.CompareTo(t.RightChild.Key) > 0) { - y = t.RightChild; - t.RightChild = y.LeftChild; - y.LeftChild = t; - t = y; - if (t.RightChild == null) { - break; - } - } - - l.RightChild = t; - l = t; - t = t.RightChild; - } - else { - break; - } - } - - l.RightChild = t.LeftChild; - r.LeftChild = t.RightChild; - t.LeftChild = header.RightChild; - t.RightChild = header.LeftChild; - this.root = t; - } - - public bool Remove(TKey key) { - if (this.count == 0) { - return false; - } - - this.Splay(key); - - if (key.CompareTo(this.root.Key) != 0) { - return false; - } - - if (this.root.LeftChild == null) { - this.root = this.root.RightChild; - } - else { - var swap = this.root.RightChild; - this.root = this.root.LeftChild; - this.Splay(key); - this.root.RightChild = swap; - } - - this.version++; - this.count--; - return true; - } - - public bool TryGetValue(TKey key, out TValue value) { - if (this.count == 0) { - value = default(TValue); - return false; - } - - this.Splay(key); - if (key.CompareTo(this.root.Key) != 0) { - value = default(TValue); - return false; - } - - value = this.root.Value; - return true; - } - - public TValue this[TKey key] { - get { - if (this.count == 0) { - throw new KeyNotFoundException("The key was not found in the tree."); - } - - this.Splay(key); - if (key.CompareTo(this.root.Key) != 0) { - throw new KeyNotFoundException("The key was not found in the tree."); - } - - return this.root.Value; - } - - set { this.Set(key, value, throwOnExisting: false); } - } - - public int Count { - get { return this.count; } - } - - public bool IsReadOnly { - get { return false; } - } - - public bool Remove(KeyValuePair item) { - if (this.count == 0) { - return false; - } - - this.Splay(item.Key); - - if (item.Key.CompareTo(this.root.Key) == 0 && (ReferenceEquals(this.root.Value, item.Value) || - (!ReferenceEquals(item.Value, null) && - item.Value.Equals(this.root.Value)))) { - return false; - } - - if (this.root.LeftChild == null) { - this.root = this.root.RightChild; - } - else { - var swap = this.root.RightChild; - this.root = this.root.LeftChild; - this.Splay(item.Key); - this.root.RightChild = swap; - } - - this.version++; - this.count--; - return true; - } - - public void Trim(int depth) { - if (depth < 0) { - throw new ArgumentOutOfRangeException("depth", "The trim depth must not be negative."); - } - - if (this.count == 0) { - return; - } - - if (depth == 0) { - this.Clear(); - } - else { - var prevCount = this.count; - this.count = this.Trim(this.root, depth - 1); - if (prevCount != this.count) { - this.version++; - } - } - } - - int Trim(SplayTreeNode node, int depth) { - if (depth == 0) { - node.LeftChild = null; - node.RightChild = null; - return 1; - } - else { - int count = 1; - - if (node.LeftChild != null) { - count += this.Trim(node.LeftChild, depth - 1); - } - - if (node.RightChild != null) { - count += this.Trim(node.RightChild, depth - 1); - } - - return count; - } - } - - public ICollection Keys { - get { return new TiedList(this, this.version, this.AsList(node => node.Key)); } - } - - public ICollection Values { - get { return new TiedList(this, this.version, this.AsList(node => node.Value)); } - } - - public void CopyTo(KeyValuePair[] array, int arrayIndex) { - this.AsList(node => new KeyValuePair(node.Key, node.Value)).CopyTo(array, arrayIndex); - } - - public IEnumerator> GetEnumerator() { - return new TiedList>(this, this.version, - this.AsList(node => new KeyValuePair(node.Key, node.Value))).GetEnumerator(); - } - - IList AsList(Func selector) { - if (this.root == null) { - return new TEnumerator[0]; - } - - var result = new List(this.count); - this.PopulateList(this.root, result, selector); - return result; - } - - void PopulateList(SplayTreeNode node, List list, - Func selector) { - if (node.LeftChild != null) { - this.PopulateList(node.LeftChild, list, selector); - } - - list.Add(selector(node)); - if (node.RightChild != null) { - this.PopulateList(node.RightChild, list, selector); - } - } - - IEnumerator IEnumerable.GetEnumerator() { - return this.GetEnumerator(); - } - - sealed class SplayTreeNode { - public readonly TKey Key; - - public TValue Value; - public SplayTreeNode LeftChild; - public SplayTreeNode RightChild; - - public SplayTreeNode(TKey key, TValue value) { - this.Key = key; - this.Value = value; - } - } - - sealed class TiedList : IList { - readonly SplayTree tree; - readonly int version; - readonly IList backingList; - - public TiedList(SplayTree tree, int version, IList backingList) { - if (tree == null) { - throw new ArgumentNullException("tree"); - } - - if (backingList == null) { - throw new ArgumentNullException("backingList"); - } - - this.tree = tree; - this.version = version; - this.backingList = backingList; - } - - public int IndexOf(T item) { - if (this.tree.version != this.version) { - throw new InvalidOperationException("The collection has been modified."); - } - - return this.backingList.IndexOf(item); - } - - public void Insert(int index, T item) { - throw new NotSupportedException(); - } - - public void RemoveAt(int index) { - throw new NotSupportedException(); - } - - public T this[int index] { - get { - if (this.tree.version != this.version) { - throw new InvalidOperationException("The collection has been modified."); - } - - return this.backingList[index]; - } - set { throw new NotSupportedException(); } - } - - public void Add(T item) { - throw new NotSupportedException(); - } - - public void Clear() { - throw new NotSupportedException(); - } - - public bool Contains(T item) { - if (this.tree.version != this.version) { - throw new InvalidOperationException("The collection has been modified."); - } - - return this.backingList.Contains(item); - } - - public void CopyTo(T[] array, int arrayIndex) { - if (this.tree.version != this.version) { - throw new InvalidOperationException("The collection has been modified."); - } - - this.backingList.CopyTo(array, arrayIndex); - } - - public int Count { - get { return this.tree.count; } - } - - public bool IsReadOnly { - get { return true; } - } - - public bool Remove(T item) { - throw new NotSupportedException(); - } - - public IEnumerator GetEnumerator() { - if (this.tree.version != this.version) { - throw new InvalidOperationException("The collection has been modified."); - } - - foreach (var item in this.backingList) { - yield return item; - if (this.tree.version != this.version) { - throw new InvalidOperationException("The collection has been modified."); - } - } - } - - IEnumerator IEnumerable.GetEnumerator() { - return this.GetEnumerator(); - } - } - } +using System; +using System.Collections.Generic; +using Unity.UIWidgets.foundation; +using Unity.UIWidgets.external; +using UnityEngine; + +namespace Unity.UIWidgets.ui { + struct CodeUnitRun { + public readonly int lineNumber; + public readonly TextDirection direction; + public readonly Range codeUnits; + public Range xPos; + public readonly int start; + public readonly int count; + + public CodeUnitRun(Range cu, Range xPos, int line, + TextDirection direction, int start, int count) { + this.lineNumber = line; + this.codeUnits = cu; + this.xPos = xPos; + this.direction = direction; + this.start = start; + this.count = count; + } + + public GlyphPosition get(int i, GlyphPosition[] glyphPositions) { + D.assert(i < this.count); + return glyphPositions[this.start + i]; + } + } + + + struct FontMetrics { + public readonly float ascent; + public readonly float leading; + public readonly float descent; + public readonly float? underlineThickness; + public readonly float? underlinePosition; + public readonly float? strikeoutPosition; + public readonly float? fxHeight; + + static FontMetrics _previousFontMetrics; + static Font _previousFont; + static int _previousFontSize; + + public FontMetrics(float ascent, float descent, + float? underlineThickness = null, float? underlinePosition = null, float? strikeoutPosition = null, + float? fxHeight = null) { + this.ascent = ascent; + this.descent = descent; + this.underlineThickness = underlineThickness; + this.underlinePosition = underlinePosition; + this.strikeoutPosition = strikeoutPosition; + this.fxHeight = fxHeight; + this.leading = 0.0f; + } + + public static FontMetrics fromFont(Font font, int fontSize) { + if (fontSize == _previousFontSize && ReferenceEquals(font, _previousFont)) { + return _previousFontMetrics; + } + + var ascent = -font.ascent * fontSize / font.fontSize; + var descent = (font.lineHeight - font.ascent) * fontSize / font.fontSize; + font.RequestCharactersInTextureSafe("x", fontSize, UnityEngine.FontStyle.Normal); + font.getGlyphInfo('x', out var glyphInfo, fontSize, UnityEngine.FontStyle.Normal); + float fxHeight = glyphInfo.glyphHeight; + _previousFontMetrics = new FontMetrics(ascent, descent, fxHeight: fxHeight); + _previousFontSize = fontSize; + _previousFont = font; + + return _previousFontMetrics; + } + } + + struct PositionWithAffinity { + public readonly int position; + public readonly TextAffinity affinity; + + public PositionWithAffinity(int p, TextAffinity a) { + this.position = p; + this.affinity = a; + } + } + + struct GlyphPosition { + public Range xPos; + public readonly int codeUnit; + + public GlyphPosition(float start, float advance, int codeUnit) { + this.xPos = new Range(start, start + advance); + this.codeUnit = codeUnit; + } + + public void shiftSelf(float shift) { + this.xPos = new Range(this.xPos.start + shift, this.xPos.end + shift); + } + } + + struct Range : IEquatable> { + public Range(T start, T end) { + this.start = start; + this.end = end; + } + + public bool Equals(Range other) { + return EqualityComparer.Default.Equals(this.start, other.start) && + EqualityComparer.Default.Equals(this.end, other.end); + } + + public override bool Equals(object obj) { + if (ReferenceEquals(null, obj)) { + return false; + } + + return obj is Range && this.Equals((Range) obj); + } + + public override int GetHashCode() { + unchecked { + return (EqualityComparer.Default.GetHashCode(this.start) * 397) ^ + EqualityComparer.Default.GetHashCode(this.end); + } + } + + public static bool operator ==(Range left, Range right) { + return left.Equals(right); + } + + public static bool operator !=(Range left, Range right) { + return !left.Equals(right); + } + + public readonly T start, end; + } + + struct GlyphLine { + public readonly int start; + public readonly int count; + + public GlyphLine(int start, int count) { + this.start = start; + this.count = count; + } + + public GlyphPosition get(int i, GlyphPosition[] glyphPositions) { + return glyphPositions[this.start + i]; + } + + public GlyphPosition last(GlyphPosition[] glyphPositions) { + return glyphPositions[this.start + this.count - 1]; + } + } + + + public class Paragraph { + public struct LineRange { + public LineRange(int start, int end, int endExcludingWhitespace, int endIncludingNewLine, bool hardBreak) { + this.start = start; + this.end = end; + this.endExcludingWhitespace = endExcludingWhitespace; + this.endIncludingNewLine = endIncludingNewLine; + this.hardBreak = hardBreak; + } + + public readonly int start; + public readonly int end; + public readonly int endExcludingWhitespace; + public readonly int endIncludingNewLine; + public readonly bool hardBreak; + } + + bool _needsLayout = true; + + string _text; + string _ellipsizedText; + int _ellipsizedLength; + + StyledRuns _runs; + + ParagraphStyle _paragraphStyle; + List _lineRanges = new List(); + + List _lineWidths = new List(); + + GlyphLine[] _glyphLines; + GlyphPosition[] _glyphPositions; + PaintRecord[] _paintRecords; + CodeUnitRun[] _codeUnitRuns; + float[] _lineHeights; + float[] _textBlobPositionXs; + float _maxIntrinsicWidth; + float _minIntrinsicWidth; + float _alphabeticBaseline; + float _ideographicBaseline; + int _lineCount; + int _paintRecordsCount; + int _codeUnitRunsCount; + int _lineRangeCount; + int _lineWidthCount; + bool _didExceedMaxLines; + TabStops _tabStops = new TabStops(); + + static float[] _advancesBuffer; + static float[] _positionsBuffer; + static Range[] _wordsBuffer; + + // private float _characterWidth; + + float _width; + + const float kFloatDecorationSpacing = 3.0f; + + public float height { + get { + if (this._lineHeights == null) { + return 0; + } + + return this._lineHeights[this.getLineCount() - 1]; + } + } + + public float minIntrinsicWidth { + get { return this._minIntrinsicWidth; } + } + + public float maxIntrinsicWidth { + get { return this._maxIntrinsicWidth; } + } + + public float width { + get { return this._width; } + } + + + public float alphabeticBaseline { + get { return this._alphabeticBaseline; } + } + + public float ideographicBaseline { + get { return this._ideographicBaseline; } + } + + public bool didExceedMaxLines { + get { return this._didExceedMaxLines; } + } + + static List _paragraphPool = new List(); + + public static Paragraph create() { + if (_paragraphPool.isEmpty()) { + return new Paragraph(); + } + + Paragraph ret = _paragraphPool.last(); + _paragraphPool.RemoveAt(_paragraphPool.Count - 1); + return ret; + } + + public static void release(ref Paragraph paragraph) { + if (paragraph != null) { + paragraph.clear(); + _paragraphPool.Add(paragraph); + paragraph = null; + } + } + + public void clear() { + this._needsLayout = true; + this._maxIntrinsicWidth = default; + this._minIntrinsicWidth = default; + this._alphabeticBaseline = default; + this._ideographicBaseline = default; + this._lineCount = default; + this._paintRecordsCount = default; + this._codeUnitRunsCount = default; + this._lineRangeCount = default; + this._lineWidthCount = default; + this._didExceedMaxLines = default; + this._width = default; + this._text = default; + this._ellipsizedText = default; + this._ellipsizedLength = default; + this._runs = null; + this._paragraphStyle = null; + } + + Paint _textPaint = new Paint { + filterMode = FilterMode.Bilinear + }; + + Paint _defaultPaint = new Paint { + filterMode = FilterMode.Bilinear + }; + + public void paint(Canvas canvas, Offset offset) { + for (int i = 0; i < this._paintRecordsCount; i++) { + var paintRecord = this._paintRecords[i]; + this.paintBackground(canvas, paintRecord, offset); + } + + for (int i = 0; i < this._paintRecordsCount; i++) { + var paintRecord = this._paintRecords[i]; + + if (paintRecord.style.foreground != null) { + this._textPaint = paintRecord.style.foreground; + } + else { + this._textPaint = this._defaultPaint; + this._textPaint.color = paintRecord.style.color; + } + + canvas.drawTextBlob(paintRecord.text, paintRecord.shiftedOffset(offset), this._textPaint); + + this.paintDecorations(canvas, paintRecord, offset); + } + } + + public void layout(ParagraphConstraints constraints) { + if (!this._needsLayout && this._width == constraints.width) { + return; + } + + this._tabStops.setFont( + FontManager.instance.getOrCreate( + this._paragraphStyle.fontFamily ?? TextStyle.kDefaultFontFamily, + this._paragraphStyle.fontWeight ?? TextStyle.kDefaultFontWeight, + this._paragraphStyle.fontStyle ?? TextStyle.kDefaultfontStyle).font, + (int) (this._paragraphStyle.fontSize ?? TextStyle.kDefaultFontSize)); + + this._needsLayout = false; + this._width = Mathf.Floor(constraints.width); + + int lineStyleRunsCount = this._computeLineBreak(); + + if (this._glyphLines == null || this._glyphLines.Length < this._lineRangeCount) { + this._glyphLines = new GlyphLine[LayoutUtils.minPowerOfTwo(this._lineRangeCount)]; + } + + if (this._lineHeights == null || this._lineHeights.Length < this._lineRangeCount) { + this._lineHeights = new float[LayoutUtils.minPowerOfTwo(this._lineRangeCount)]; + } + + if (this._paintRecords == null || this._paintRecords.Length < lineStyleRunsCount) { + this._paintRecords = new PaintRecord[LayoutUtils.minPowerOfTwo(lineStyleRunsCount)]; + } + + this._paintRecordsCount = 0; + + if (this._codeUnitRuns == null || this._codeUnitRuns.Length < lineStyleRunsCount) { + this._codeUnitRuns = new CodeUnitRun[LayoutUtils.minPowerOfTwo(lineStyleRunsCount)]; + } + + this._codeUnitRunsCount = 0; + + int styleMaxLines = this._paragraphStyle.maxLines ?? int.MaxValue; + this._didExceedMaxLines = this._lineRangeCount > styleMaxLines; + + var lineLimit = Mathf.Min(styleMaxLines, this._lineRangeCount); + int styleRunIndex = 0; + float yOffset = 0; + float preMaxDescent = 0; + float maxWordWidth = 0; + + TextBlobBuilder builder = new TextBlobBuilder(); + int ellipsizedLength = this._text.Length + (this._paragraphStyle.ellipsis?.Length ?? 0); + + // All text blobs share a single position buffer, which is big enough taking ellipsis into consideration + if (this._textBlobPositionXs == null || this._textBlobPositionXs.Length < ellipsizedLength) { + this._textBlobPositionXs = new float[LayoutUtils.minPowerOfTwo(ellipsizedLength)]; + } + + builder.setPositionXs(this._textBlobPositionXs); + // this._glyphLines and this._codeUnitRuns will refer to this array for glyph positions + if (this._glyphPositions == null || this._glyphPositions.Length < ellipsizedLength) { + this._glyphPositions = new GlyphPosition[LayoutUtils.minPowerOfTwo(ellipsizedLength)]; + } + + // Pointer to the _glyphPositions array, to keep track of where the next glyph is stored + int pGlyphPositions = 0; + + // Compute max(NumberOfWords(line) for line in lines), to determine the size of word buffers + int maxWordCount = this._computeMaxWordCount(); + + if (_wordsBuffer == null || _wordsBuffer.Length < maxWordCount) { + _wordsBuffer = new Range[maxWordCount < 4 ? 4 : maxWordCount]; + } + + // Iterate through line ranges + for (int lineNumber = 0; lineNumber < lineLimit; ++lineNumber) { + var lineRange = this._lineRanges[lineNumber]; + int wordIndex = 0; + float runXOffset = 0; + float justifyXOffset = 0; + + // Break the line into words if justification should be applied. + bool justifyLine = this._paragraphStyle.textAlign == TextAlign.justify && + lineNumber != lineLimit - 1 && !lineRange.hardBreak && + // Do not apply justify if ellipsis should be added, or the ellipsis may be pushed + // out of the border. + // This is still not taken care of in the flutter engine. + !(this._paragraphStyle.ellipsized() && this._paragraphStyle.maxLines == null); + + int wordCount = this._findWords(lineRange.start, lineRange.end, _wordsBuffer); + float wordGapWidth = !(justifyLine && wordCount > 1) + ? 0 + : (this._width - this._lineWidths[lineNumber]) / (wordCount - 1); + + // Count the number of style runs, and compute the character number of the longest run by the way + int lineStyleRunCount = this._countLineStyleRuns(lineRange, styleRunIndex, out int maxTextCount); + + string ellipsis = this._paragraphStyle.ellipsis; + bool hardBreak = lineRange.hardBreak; + + if (!string.IsNullOrEmpty(ellipsis) && !hardBreak && !this._width.isInfinite() && + (lineNumber == lineLimit - 1 || this._paragraphStyle.maxLines == null)) { + maxTextCount += ellipsis.Length; + } + + // Allocate the advances and positions to store the layout result + // TODO: find a way to compute the maxTextCount for the entire paragraph, so that this allocation + // happens only once + if (_advancesBuffer == null || _advancesBuffer.Length < maxTextCount) { + _advancesBuffer = new float[LayoutUtils.minPowerOfTwo(maxTextCount)]; + } + + if (_positionsBuffer == null || _positionsBuffer.Length < maxTextCount) { + _positionsBuffer = new float[LayoutUtils.minPowerOfTwo(maxTextCount)]; + } + + // Keep of the position in _glyphPositions before evaluating this line + int glyphPositionLineStart = pGlyphPositions; + + if (lineStyleRunCount != 0) { + // Exclude trailing whitespace from right-justified lines so the last + // visible character in the line will be flush with the right margin. + int lineEndIndex = this._paragraphStyle.textAlign == TextAlign.right || + this._paragraphStyle.textAlign == TextAlign.center + ? lineRange.endExcludingWhitespace + : lineRange.end; + int lineStyleRunIndex = 0; + + // Instead of computing all lineStyleRuns at once and store into an array and iterate through them, + // compute each lineStyleRun and deal with it on the fly, to save the storage for the runs + while (styleRunIndex < this._runs.size) { + var styleRun = this._runs.getRun(styleRunIndex); + // Compute the intersection between current style run intersects and the line + int start = Mathf.Max(styleRun.start, lineRange.start); + int end = Mathf.Min(styleRun.end, lineEndIndex); + // Make sure that each run is not empty + if (start < end) { + var style = styleRun.style; + string text = this._text; + int textStart = start; + int textEnd = end; + int textCount = textEnd - textStart; + // Keep track of the pointer to _glyphPositions in the start of this run + int glyphPositionStyleRunStart = pGlyphPositions; + + // Ellipsize the text if ellipsis string is set, and this is the last lineStyleRun of + // the current line, and this is the last line or max line is not set + if (!string.IsNullOrEmpty(ellipsis) && !hardBreak && !this._width.isInfinite() && + lineStyleRunIndex == lineStyleRunCount - 1 && + (lineNumber == lineLimit - 1 || this._paragraphStyle.maxLines == null)) { + float ellipsisWidth = Layout.measureText(ellipsis, style); + + // Find the minimum number of characters to truncate, so that the truncated text + // appended with ellipsis is within the constraints of line width + int truncateCount = Layout.computeTruncateCount(runXOffset, text, textStart, + textCount, style, this._width - ellipsisWidth, this._tabStops); + + // If all the positions have not changed, use the cached ellipsized text + // else update the cache + if (!(this._ellipsizedText != null && + this._ellipsizedLength == textStart + textCount - truncateCount && + this._ellipsizedText.Length == this._ellipsizedLength + ellipsis.Length && + this._ellipsizedText.EndsWith(ellipsis))) { + this._ellipsizedText = + text.Substring(0, textStart + textCount - truncateCount) + ellipsis; + this._ellipsizedLength = this._ellipsizedText.Length - ellipsis.Length; + } + + text = this._ellipsizedText; + textCount = text.Length - textStart; + D.assert(textCount != 0); + if (this._paragraphStyle.maxLines == null) { + lineLimit = lineNumber + 1; + this._didExceedMaxLines = true; + } + } + + float advance = Layout.doLayout(runXOffset, text, textStart, textCount, style, + _advancesBuffer, _positionsBuffer, this._tabStops, out var bounds); + + builder.allocRunPos(style, text, textStart, textCount); + builder.setBounds(bounds); + + // Update the max width of the words + // Fill in the glyph positions, and the positions of the text blob builder + float wordStartPosition = float.NaN; + for (int glyphIndex = 0; glyphIndex < textCount; ++glyphIndex) { + float glyphXOffset = _positionsBuffer[glyphIndex] + justifyXOffset; + float glyphAdvance = _advancesBuffer[glyphIndex]; + builder.setPositionX(glyphIndex, glyphXOffset); + this._glyphPositions[pGlyphPositions++] = new GlyphPosition(runXOffset + glyphXOffset, + glyphAdvance, textStart + glyphIndex); + if (wordIndex < wordCount) { + Range word = _wordsBuffer[wordIndex]; + // Run into the start of current word, record the start position of this word + if (word.start == start + glyphIndex) { + wordStartPosition = runXOffset + glyphXOffset; + } + + // Run into the end of current word + if (word.end == start + glyphIndex + 1) { + if (justifyLine) { + justifyXOffset += wordGapWidth; + } + + // Update the current word + wordIndex++; + // If the start position of this word has been recorded, calculate the + // width of this word, and update the entire word + if (!float.IsNaN(wordStartPosition)) { + maxWordWidth = Mathf.Max(maxWordWidth, + this._glyphPositions[pGlyphPositions - 1].xPos.end - wordStartPosition); + wordStartPosition = float.NaN; + } + } + } + } + + // Create paint record + var font = FontManager.instance.getOrCreate(style.fontFamily, + style.fontWeight, style.fontStyle).font; + var metrics = FontMetrics.fromFont(font, style.UnityFontSize); + PaintRecord paintRecord = new PaintRecord(style, runXOffset, 0, builder.make(), + metrics, advance); + this._paintRecords[this._paintRecordsCount++] = paintRecord; + runXOffset += advance; + + // Create code unit run + this._codeUnitRuns[this._codeUnitRunsCount++] = new CodeUnitRun( + new Range(start, end), + new Range(this._glyphPositions[glyphPositionStyleRunStart].xPos.start, + this._glyphPositions[pGlyphPositions - 1].xPos.end), + lineNumber, TextDirection.ltr, glyphPositionStyleRunStart, textCount); + + lineStyleRunIndex++; + } + + if (styleRun.end >= lineEndIndex) { + break; + } + + styleRunIndex++; + } + } + + float maxLineSpacing = 0; + float maxDescent = 0; + + void updateLineMetrics(FontMetrics metrics, float styleHeight) { + float lineSpacing = lineNumber == 0 + ? -metrics.ascent * styleHeight + : (-metrics.ascent + metrics.leading) * styleHeight; + if (lineSpacing > maxLineSpacing) { + maxLineSpacing = lineSpacing; + if (lineNumber == 0) { + this._alphabeticBaseline = lineSpacing; + this._ideographicBaseline = + (metrics.underlinePosition ?? 0.0f - metrics.ascent) * styleHeight; + } + } + + float descent = metrics.descent * styleHeight; + maxDescent = Mathf.Max(descent, maxDescent); + } + + if (lineStyleRunCount != 0) { + for (int i = 0; i < lineStyleRunCount; i++) { + var paintRecord = this._paintRecords[this._paintRecordsCount - i - 1]; + updateLineMetrics(paintRecord.metrics, paintRecord.style.height); + } + } + else { + var defaultFont = FontManager.instance.getOrCreate( + this._paragraphStyle.fontFamily ?? TextStyle.kDefaultFontFamily, + this._paragraphStyle.fontWeight ?? TextStyle.kDefaultFontWeight, + this._paragraphStyle.fontStyle ?? TextStyle.kDefaultfontStyle).font; + var metrics = FontMetrics.fromFont(defaultFont, + (int) (this._paragraphStyle.fontSize ?? TextStyle.kDefaultFontSize)); + updateLineMetrics(metrics, this._paragraphStyle.height ?? TextStyle.kDefaultHeight); + } + + this._lineHeights[lineNumber] = ((lineNumber == 0 ? 0 : this._lineHeights[lineNumber - 1]) + + Mathf.Round(maxLineSpacing + maxDescent)); + yOffset += Mathf.Round(maxLineSpacing + preMaxDescent); + preMaxDescent = maxDescent; + float lineXOffset = this.getLineXOffset(runXOffset); + int count = pGlyphPositions - glyphPositionLineStart; + if (lineXOffset != 0 && this._glyphPositions != null) { + for (int i = 0; i < count; ++i) { + this._glyphPositions[this._glyphPositions.Length - i - 1].shiftSelf(lineXOffset); + } + } + + this._glyphLines[lineNumber] = new GlyphLine(glyphPositionLineStart, count); + for (int i = 0; i < lineStyleRunCount; i++) { + var paintRecord = this._paintRecords[this._paintRecordsCount - 1 - i]; + paintRecord.shift(lineXOffset, yOffset); + this._paintRecords[this._paintRecordsCount - 1 - i] = paintRecord; + } + } + + this._lineCount = lineLimit; + + // min intrinsic width := minimum width this paragraph has to take, which equals the maximum word width + if (this._paragraphStyle.maxLines == 1 || (this._paragraphStyle.maxLines == null && + this._paragraphStyle.ellipsized())) { + this._minIntrinsicWidth = this.maxIntrinsicWidth; + } + else { + this._minIntrinsicWidth = Mathf.Min(maxWordWidth, this.maxIntrinsicWidth); + } + } + + int _countLineStyleRuns(LineRange lineRange, int styleRunIndex, out int maxTextCount) { + // Exclude trailing whitespace from right-justified lines so the last + // visible character in the line will be flush with the right margin. + int lineEndIndex = this._paragraphStyle.textAlign == TextAlign.right || + this._paragraphStyle.textAlign == TextAlign.center + ? lineRange.endExcludingWhitespace + : lineRange.end; + + maxTextCount = 0; + int lineStyleRunCount = 0; + for (int i = styleRunIndex; i < this._runs.size; i++) { + var styleRun = this._runs.getRun(i); + int start = Mathf.Max(styleRun.start, lineRange.start); + int end = Mathf.Min(styleRun.end, lineEndIndex); + // Make sure that each line is not empty + if (start < end) { + lineStyleRunCount++; + maxTextCount = Math.Max(end - start, maxTextCount); + } + + if (styleRun.end >= lineEndIndex) { + break; + } + } + + return lineStyleRunCount; + } + + internal int totalCodeUnitsInLine(int lineNumber) { + int lineStart = this._lineRanges[lineNumber].start; + int nextLineStart = lineNumber < this._lineRangeCount - 1 + ? this._lineRanges[lineNumber + 1].start + : this._text.Length; + return nextLineStart - lineStart; + } + + internal void setText(string text, StyledRuns runs) { + this._text = text; + this._runs = runs; + this._needsLayout = true; + } + + public void setParagraphStyle(ParagraphStyle style) { + this._needsLayout = true; + this._paragraphStyle = style; + } + + public List getRectsForRange(int start, int end) { + var lineBoxes = new SplayTree>(); + for (int runIndex = 0; runIndex < this._codeUnitRunsCount; runIndex++) { + var run = this._codeUnitRuns[runIndex]; + if (run.codeUnits.start >= end) { + break; + } + + if (run.codeUnits.end <= start) { + continue; + } + + float top = (run.lineNumber == 0) ? 0 : this._lineHeights[run.lineNumber - 1]; + float bottom = this._lineHeights[run.lineNumber]; + float left, right; + if (run.codeUnits.start >= start && run.codeUnits.end <= end) { + left = run.xPos.start; + right = run.xPos.end; + } + else { + left = float.MaxValue; + right = float.MinValue; + for (int i = 0; i < run.count; i++) { + var gp = run.get(i, this._glyphPositions); + if (gp.codeUnit >= start && gp.codeUnit + 1 <= end) { + left = Mathf.Min(left, gp.xPos.start); + right = Mathf.Max(right, gp.xPos.end); + } + } + + if (left == float.MaxValue || right == float.MinValue) { + continue; + } + } + + List boxs; + if (!lineBoxes.TryGetValue(run.lineNumber, out boxs)) { + boxs = new List(); + lineBoxes.Add(run.lineNumber, boxs); + } + + boxs.Add(TextBox.fromLTBD(left, top, right, bottom, run.direction)); + } + + for (int lineNumber = 0; lineNumber < this._lineRangeCount; ++lineNumber) { + var line = this._lineRanges[lineNumber]; + if (line.start >= end) { + break; + } + + if (line.endIncludingNewLine <= start) { + continue; + } + + if (!lineBoxes.ContainsKey(lineNumber)) { + if (line.end != line.endIncludingNewLine && line.end >= start && line.endIncludingNewLine <= end) { + var x = this._lineWidths[lineNumber]; + var top = (lineNumber > 0) ? this._lineHeights[lineNumber - 1] : 0; + var bottom = this._lineHeights[lineNumber]; + lineBoxes.Add(lineNumber, new List { + TextBox.fromLTBD( + x, top, x, bottom, TextDirection.ltr) + }); + } + } + } + + var result = new List(); + foreach (var keyValuePair in lineBoxes) { + result.AddRange(keyValuePair.Value); + } + + return result; + } + + public float? getNextLineStartRectTop() { + if (this._text.Length == 0 || this._text[this._text.Length - 1] != '\n') { + return null; + } + + var lineNumber = this.getLineCount() - 1; + return lineNumber > 0 ? this._lineHeights[lineNumber - 1] : 0; + } + + internal PositionWithAffinity getGlyphPositionAtCoordinate(float dx, float dy) { + if (this._lineHeights == null) { + return new PositionWithAffinity(0, TextAffinity.downstream); + } + + int yIndex; + for (yIndex = 0; yIndex < this.getLineCount() - 1; ++yIndex) { + if (dy < this._lineHeights[yIndex]) { + break; + } + } + + GlyphLine glyphLine = this._glyphLines[yIndex]; + if (glyphLine.count == 0) { + int lineStartIndex = 0; + for (int i = 0; i < yIndex; i++) { + lineStartIndex += this.totalCodeUnitsInLine(i); + } + + return new PositionWithAffinity(lineStartIndex, TextAffinity.downstream); + } + + + GlyphPosition gp = new GlyphPosition(); + bool gpSet = false; + for (int xIndex = 0; xIndex < glyphLine.count; ++xIndex) { + float glyphEnd = xIndex < glyphLine.count - 1 + ? glyphLine.get(xIndex + 1, this._glyphPositions).xPos.start + : glyphLine.get(xIndex, this._glyphPositions).xPos.end; + if (dx < glyphEnd) { + gp = glyphLine.get(xIndex, this._glyphPositions); + gpSet = true; + break; + } + } + + if (!gpSet) { + GlyphPosition lastGlyph = glyphLine.last(this._glyphPositions); + return new PositionWithAffinity(lastGlyph.codeUnit + 1, TextAffinity.upstream); + } + + TextDirection direction = TextDirection.ltr; + for (int runIndex = 0; runIndex < this._codeUnitRunsCount; runIndex++) { + var run = this._codeUnitRuns[runIndex]; + if (gp.codeUnit >= run.codeUnits.start && gp.codeUnit + 1 <= run.codeUnits.end) { + direction = run.direction; + break; + } + } + + float glyphCenter = (gp.xPos.start + gp.xPos.end) / 2; + if ((direction == TextDirection.ltr && dx < glyphCenter) || + (direction == TextDirection.rtl && dx >= glyphCenter)) { + return new PositionWithAffinity(gp.codeUnit, TextAffinity.downstream); + } + + return new PositionWithAffinity(gp.codeUnit + 1, TextAffinity.upstream); + } + + public int getLine(TextPosition position) { + D.assert(!this._needsLayout); + if (position.offset < 0) { + return 0; + } + + var offset = position.offset; + if (position.affinity == TextAffinity.upstream && offset > 0) { + offset = char.IsSurrogate(this._text[offset - 1]) ? offset - 2 : offset - 1; + } + + var lineCount = this.getLineCount(); + for (int lineIndex = 0; lineIndex < lineCount; ++lineIndex) { + var line = this._lineRanges[lineIndex]; + if ((offset >= line.start && offset < line.endIncludingNewLine)) { + return lineIndex; + } + } + + return Mathf.Max(lineCount - 1, 0); + } + + internal LineRange getLineRange(int lineIndex) { + return this._lineRanges[lineIndex]; + } + + internal Range getWordBoundary(int offset) { + WordSeparate s = new WordSeparate(this._text); + return s.findWordRange(offset); + } + + public int getLineCount() { + return this._lineCount; + } + + int _computeLineBreak() { + this._lineRangeCount = 0; + this._lineWidthCount = 0; + this._maxIntrinsicWidth = 0; + + int lineLimit = this._paragraphStyle.ellipsized() + ? this._paragraphStyle.maxLines ?? 1 + : this._paragraphStyle.maxLines ?? 0; + + var newLinePositions = LineBreaker.newLinePositions(this._text, out int newLineCount); + + var lineBreaker = LineBreaker.instance; + int runIndex = 0; + int countRuns = 0; + for (var newlineIndex = 0; newlineIndex < newLineCount; ++newlineIndex) { + if (lineLimit != 0 && this._lineRangeCount >= lineLimit) { + break; + } + + var blockStart = newlineIndex > 0 ? newLinePositions[newlineIndex - 1] + 1 : 0; + var blockEnd = newLinePositions[newlineIndex]; + var blockSize = blockEnd - blockStart; + if (blockSize == 0) { + this._addEmptyLine(blockStart, blockEnd); + continue; + } + + if (lineLimit != 0 && this._lineRangeCount >= lineLimit) { + break; + } + + this._resetLineBreaker(lineBreaker, blockStart, blockSize, + lineLimit == 0 ? 0 : lineLimit - this._lineRangeCount); + countRuns += this._addStyleRuns(lineBreaker, ref runIndex, blockStart, blockEnd); + + int breaksCount = lineBreaker.computeBreaks(); + countRuns += breaksCount - 1; + this._updateBreaks(lineBreaker, breaksCount, blockStart, blockEnd); + + lineBreaker.finish(); + } + + return countRuns; + } + + void _addLineRangeAndWidth(LineRange lineRange, float width) { + if (this._lineRanges.Count <= this._lineRangeCount) { + this._lineRanges.Add(lineRange); + this._lineRangeCount++; + } + else { + this._lineRanges[this._lineRangeCount++] = lineRange; + } + + if (this._lineWidths.Count <= this._lineWidthCount) { + this._lineWidths.Add(width); + this._lineWidthCount++; + } + else { + this._lineWidths[this._lineWidthCount++] = width; + } + } + + void _addEmptyLine(int blockStart, int blockEnd) { + this._addLineRangeAndWidth(new LineRange(blockStart, blockEnd, blockEnd, + blockEnd < this._text.Length ? blockEnd + 1 : blockEnd, true), 0); + } + + void _resetLineBreaker(LineBreaker lineBreaker, int blockStart, int blockSize, int lineLimit) { + lineBreaker.setLineWidth(this._width); + lineBreaker.resize(blockSize); + lineBreaker.setTabStops(this._tabStops); + lineBreaker.setText(this._text, blockStart, blockSize); + lineBreaker.lineLimit = lineLimit; + } + + int _addStyleRuns(LineBreaker lineBreaker, ref int runIndex, int blockStart, int blockEnd) { + int countRuns = 0; + float lineBlockWidth = 0; + while (runIndex < this._runs.size) { + var run = this._runs.getRun(runIndex); + if (run.start >= blockEnd) { + break; + } + + if (lineBreaker.lineLimit != 0 && lineBreaker.getBreaksCount() >= lineBreaker.lineLimit) { + break; + } + + if (run.end <= blockStart) { + runIndex++; + continue; + } + + int runStart = Mathf.Max(run.start, blockStart) - blockStart; + int runEnd = Mathf.Min(run.end, blockEnd) - blockStart; + lineBlockWidth += lineBreaker.addStyleRun(run.style, runStart, runEnd); + + countRuns++; + + if (run.end > blockEnd) { + break; + } + + runIndex++; + } + + this._maxIntrinsicWidth = Mathf.Max(lineBlockWidth, this._maxIntrinsicWidth); + + return countRuns; + } + + void _updateBreaks(LineBreaker lineBreaker, int breaksCount, int blockStart, int blockEnd) { + for (int i = 0; i < breaksCount; ++i) { + var breakStart = i > 0 ? lineBreaker.getBreak(i - 1) : 0; + var lineStart = breakStart + blockStart; + var lineEnd = lineBreaker.getBreak(i) + blockStart; + bool hardBreak = lineEnd == blockEnd; + var lineEndIncludingNewline = + hardBreak && lineEnd < this._text.Length ? lineEnd + 1 : lineEnd; + var lineEndExcludingWhitespace = lineEnd; + while (lineEndExcludingWhitespace > lineStart && + LayoutUtils.isLineEndSpace(this._text[lineEndExcludingWhitespace - 1])) { + lineEndExcludingWhitespace--; + } + + this._addLineRangeAndWidth(new LineRange(lineStart, lineEnd, + lineEndExcludingWhitespace, lineEndIncludingNewline, hardBreak), lineBreaker.getWidth(i)); + } + } + + int _computeMaxWordCount() { + int max = 0; + for (int lineNumber = 0; lineNumber < this._lineRangeCount; lineNumber++) { + var inWord = false; + int wordCount = 0, start = this._lineRanges[lineNumber].start, end = this._lineRanges[lineNumber].end; + for (int i = start; i < end; ++i) { + bool isSpace = LayoutUtils.isWordSpace(this._text[i]); + if (!inWord && !isSpace) { + inWord = true; + } + else if (inWord && isSpace) { + inWord = false; + wordCount++; + } + } + + if (inWord) { + wordCount++; + } + + if (wordCount > max) { + max = wordCount; + } + } + + return max; + } + + int _findWords(int start, int end, Range[] words) { + var inWord = false; + int wordCount = 0; + int wordStart = 0; + + for (int i = start; i < end; ++i) { + bool isSpace = LayoutUtils.isWordSpace(this._text[i]); + if (!inWord && !isSpace) { + wordStart = i; + inWord = true; + } + else if (inWord && isSpace) { + inWord = false; + words[wordCount++] = new Range(wordStart, i); + } + } + + if (inWord) { + words[wordCount] = new Range(wordStart, end); + } + + return wordCount; + } + + void paintDecorations(Canvas canvas, PaintRecord record, Offset baseOffset) { + if (record.style.decoration == null || record.style.decoration == TextDecoration.none) { + return; + } + + if (record.style.decorationColor == null) { + this._textPaint.color = record.style.color; + } + else { + this._textPaint.color = record.style.decorationColor; + } + + + var width = record.runWidth; + var metrics = record.metrics; + float underLineThickness = metrics.underlineThickness ?? (record.style.fontSize / 14.0f); + this._textPaint.style = PaintingStyle.stroke; + this._textPaint.strokeWidth = underLineThickness; + var recordOffset = record.shiftedOffset(baseOffset); + var x = recordOffset.dx; + var y = recordOffset.dy; + + int decorationCount = 1; + switch (record.style.decorationStyle) { + case TextDecorationStyle.doubleLine: + decorationCount = 2; + break; + } + + + var decoration = record.style.decoration; + for (int i = 0; i < decorationCount; i++) { + float yOffset = i * underLineThickness * kFloatDecorationSpacing; + float yOffsetOriginal = yOffset; + if (decoration != null && decoration.contains(TextDecoration.underline)) { + // underline + yOffset += metrics.underlinePosition ?? underLineThickness; + canvas.drawLine(new Offset(x, y + yOffset), new Offset(x + width, y + yOffset), this._textPaint); + yOffset = yOffsetOriginal; + } + + if (decoration != null && decoration.contains(TextDecoration.overline)) { + yOffset += metrics.ascent; + canvas.drawLine(new Offset(x, y + yOffset), new Offset(x + width, y + yOffset), this._textPaint); + yOffset = yOffsetOriginal; + } + + if (decoration != null && decoration.contains(TextDecoration.lineThrough)) { + yOffset += (decorationCount - 1.0f) * underLineThickness * kFloatDecorationSpacing / -2.0f; + yOffset += metrics.strikeoutPosition ?? (metrics.fxHeight ?? 0) / -2.0f; + canvas.drawLine(new Offset(x, y + yOffset), new Offset(x + width, y + yOffset), this._textPaint); + yOffset = yOffsetOriginal; + } + } + + this._textPaint.style = PaintingStyle.fill; + this._textPaint.strokeWidth = 0; + } + + void paintBackground(Canvas canvas, PaintRecord record, Offset baseOffset) { + if (record.style.background == null) { + return; + } + + var metrics = record.metrics; + Rect rect = Rect.fromLTRB(0, metrics.ascent, record.runWidth, metrics.descent); + rect = rect.shift(record.shiftedOffset(baseOffset)); + canvas.drawRect(rect, record.style.background); + } + + float getLineXOffset(float lineTotalAdvance) { + if (this._width.isInfinite()) { + return 0; + } + + if (this._paragraphStyle.textAlign == TextAlign.right) { + return this._width - lineTotalAdvance; + } + + if (this._paragraphStyle.textAlign == TextAlign.center) { + return (this._width - lineTotalAdvance) / 2; + } + + return 0; + } + } + + } \ No newline at end of file diff --git a/Runtime/ui/window.cs b/Runtime/ui/window.cs index eeaf1490..860e35aa 100644 --- a/Runtime/ui/window.cs +++ b/Runtime/ui/window.cs @@ -1,8 +1,10 @@ using System; using System.Collections.Generic; using Unity.UIWidgets.async; +using Unity.UIWidgets.editor; using Unity.UIWidgets.foundation; using UnityEngine; +using UnityEngine.Rendering; namespace Unity.UIWidgets.ui { public delegate void VoidCallback(); @@ -133,7 +135,7 @@ public static bool hasInstance { } internal static Window _instance; - + public const int defaultAntiAliasing = 4; public float devicePixelRatio { @@ -141,7 +143,7 @@ public float devicePixelRatio { } protected float _devicePixelRatio = 1.0f; - + public int antiAliasing { get { return this._antiAliasing; } } @@ -152,6 +154,8 @@ public Size physicalSize { get { return this._physicalSize; } } + public WindowConfig windowConfig = WindowConfig.defaultConfig; + protected Size _physicalSize = Size.zero; public WindowPadding viewInsets { @@ -209,6 +213,13 @@ public VoidCallback onTextScaleFactorChanged { VoidCallback _onTextScaleFactorChanged; + public VoidCallback onPlatformBrightnessChanged { + get { return this._onPlatformBrightnessChanged; } + set { this._onPlatformBrightnessChanged = value; } + } + + VoidCallback _onPlatformBrightnessChanged; + public FrameCallback onBeginFrame { get { return this._onBeginFrame; } set { this._onBeginFrame = value; } @@ -265,6 +276,8 @@ public float getFPS() { public const int defaultMaxTargetFrameRate = 60; public const int defaultMinTargetFrameRate = 25; + public const int defaultMaxRenderFrameInterval = 100; + public const int defaultMinRenderFrameInterval = 1; static Action _onFrameRateSpeedUp = defaultFrameRateSpeedUp; @@ -281,7 +294,11 @@ public static Action onFrameRateSpeedUp { } static void defaultFrameRateSpeedUp() { +#if UNITY_2019_3_OR_NEWER + OnDemandRendering.renderFrameInterval = defaultMinRenderFrameInterval; +#else Application.targetFrameRate = defaultMaxTargetFrameRate; +#endif } static Action _onFrameRateCoolDown = defaultFrameRateCoolDown; @@ -299,7 +316,11 @@ public static Action onFrameRateCoolDown { } static void defaultFrameRateCoolDown() { +#if UNITY_2019_3_OR_NEWER + OnDemandRendering.renderFrameInterval = defaultMaxRenderFrameInterval; +#else Application.targetFrameRate = defaultMinTargetFrameRate; +#endif } } } \ No newline at end of file diff --git a/Runtime/widgets/app.cs b/Runtime/widgets/app.cs index 255bb6d9..85a574a1 100644 --- a/Runtime/widgets/app.cs +++ b/Runtime/widgets/app.cs @@ -15,6 +15,8 @@ namespace Unity.UIWidgets.widgets { public delegate Locale LocaleResolutionCallback(Locale locale, List supportedLocales); + public delegate string GenerateAppTitle(BuildContext context); + public delegate PageRoute PageRouteFactory(RouteSettings settings, WidgetBuilder builder); public class WidgetsApp : StatefulWidget { @@ -37,6 +39,11 @@ public class WidgetsApp : StatefulWidget { public readonly LocaleResolutionCallback localeResolutionCallback; public readonly List supportedLocales; + public readonly string title; + public readonly GenerateAppTitle onGenerateTitle; + public readonly Color color; + public readonly InspectorSelectButtonBuilder inspectorSelectButtonBuilder; + public WidgetsApp( Key key = null, GlobalKey navigatorKey = null, @@ -54,7 +61,11 @@ public WidgetsApp( LocaleListResolutionCallback localeListResolutionCallback = null, LocaleResolutionCallback localeResolutionCallback = null, List supportedLocales = null, - bool showPerformanceOverlay = false + bool showPerformanceOverlay = false, + GenerateAppTitle onGenerateTitle = null, + string title = "", + Color color = null, + InspectorSelectButtonBuilder inspectorSelectButtonBuilder = null ) : base(key) { routes = routes ?? new Dictionary(); supportedLocales = supportedLocales ?? new List {new Locale("en", "US")}; @@ -76,11 +87,16 @@ public WidgetsApp( this.supportedLocales = supportedLocales; this.showPerformanceOverlay = showPerformanceOverlay; + this.onGenerateTitle = onGenerateTitle; + this.title = title; + this.color = color; + this.inspectorSelectButtonBuilder = inspectorSelectButtonBuilder; + D.assert( home == null || !this.routes.ContainsKey(Navigator.defaultRouteName), () => "If the home property is specified, the routes table " + - "cannot include an entry for \" / \", since it would be redundant." + "cannot include an entry for \" / \", since it would be redundant." ); D.assert( @@ -90,12 +106,12 @@ public WidgetsApp( onGenerateRoute != null || onUnknownRoute != null, () => "Either the home property must be specified, " + - "or the routes table must include an entry for \"/\", " + - "or there must be on onGenerateRoute callback specified, " + - "or there must be an onUnknownRoute callback specified, " + - "or the builder property must be specified, " + - "because otherwise there is nothing to fall back on if the " + - "app is started with an intent that specifies an unknown route." + "or the routes table must include an entry for \"/\", " + + "or there must be on onGenerateRoute callback specified, " + + "or there must be an onUnknownRoute callback specified, " + + "or the builder property must be specified, " + + "because otherwise there is nothing to fall back on if the " + + "app is started with an intent that specifies an unknown route." ); D.assert( @@ -103,8 +119,8 @@ public WidgetsApp( onGenerateRoute != null || pageRouteBuilder != null, () => "If neither builder nor onGenerateRoute are provided, the " + - "pageRouteBuilder must be specified so that the default handler " + - "will know what kind of PageRoute transition to build." + "pageRouteBuilder must be specified so that the default handler " + + "will know what kind of PageRoute transition to build." ); } @@ -130,7 +146,7 @@ public static Window of(BuildContext context) { return provider.window; } - + public static Window of(GameObject gameObject) { var panel = gameObject.GetComponent(); return panel == null ? null : panel.window; @@ -179,10 +195,9 @@ public void didChangeMetrics() { public void didChangeTextScaleFactor() { this.setState(); } - + public void didChangePlatformBrightness() { - this.setState(() => { - }); + this.setState(() => { }); } public void didChangeLocales(List locale) { @@ -207,7 +222,7 @@ List _localizationsDelegates { public override void initState() { base.initState(); this._updateNavigator(); - + //todo: xingwei.zhu: change the default locale to ui.Window.locale this._locale = this._resolveLocales(new List {new Locale("en", "US")}, this.widget.supportedLocales); @@ -250,7 +265,7 @@ Route _onGenerateRoute(RouteSettings settings) { if (pageContentBuilder != null) { D.assert(this.widget.pageRouteBuilder != null, () => "The default onGenerateRoute handler for WidgetsApp must have a " + - "pageRouteBuilder set if the home or routes properties are set."); + "pageRouteBuilder set if the home or routes properties are set."); var route = this.widget.pageRouteBuilder( settings, pageContentBuilder diff --git a/Runtime/widgets/automatic_keep_alive.cs b/Runtime/widgets/automatic_keep_alive.cs index 09b1755f..20cc3b4e 100644 --- a/Runtime/widgets/automatic_keep_alive.cs +++ b/Runtime/widgets/automatic_keep_alive.cs @@ -67,6 +67,9 @@ bool _addClient(KeepAliveNotification notification) { } else { SchedulerBinding.instance.addPostFrameCallback(timeStamp => { + if (!this.mounted) { + return; + } ParentDataElement childElement1 = this._getChildElement(); D.assert(childElement1 != null); this._updateParentDataOfChild(childElement1); @@ -78,6 +81,7 @@ bool _addClient(KeepAliveNotification notification) { } ParentDataElement _getChildElement() { + D.assert(this.mounted); Element element = (Element) this.context; Element childElement = null; element.visitChildren((Element child) => { childElement = child; }); diff --git a/Runtime/widgets/basic.cs b/Runtime/widgets/basic.cs index f35244ce..3acdbf47 100644 --- a/Runtime/widgets/basic.cs +++ b/Runtime/widgets/basic.cs @@ -1780,7 +1780,8 @@ public RichText( float textScaleFactor = 1.0f, int? maxLines = null, Action onSelectionChanged = null, - Color selectionColor = null + Color selectionColor = null, + StrutStyle strutStyle = null ) : base(key: key) { D.assert(text != null); D.assert(maxLines == null || maxLines > 0); @@ -1793,6 +1794,7 @@ public RichText( this.maxLines = maxLines; this.onSelectionChanged = onSelectionChanged; this.selectionColor = selectionColor; + this.strutStyle = strutStyle; } public readonly TextSpan text; @@ -1803,6 +1805,7 @@ public RichText( public readonly int? maxLines; public readonly Action onSelectionChanged; public readonly Color selectionColor; + public readonly StrutStyle strutStyle; public override RenderObject createRenderObject(BuildContext context) { return new RenderParagraph( @@ -1827,6 +1830,7 @@ public override void updateRenderObject(BuildContext context, RenderObject rende renderObject.maxLines = this.maxLines; renderObject.onSelectionChanged = this.onSelectionChanged; renderObject.selectionColor = this.selectionColor; + renderObject.strutStyle = this.strutStyle; } public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { @@ -1973,6 +1977,7 @@ public Listener( PointerHoverEventListener onPointerHover = null, PointerUpEventListener onPointerUp = null, PointerCancelEventListener onPointerCancel = null, + PointerSignalEventListener onPointerSignal = null, PointerScrollEventListener onPointerScroll = null, PointerDragFromEditorEnterEventListener onPointerDragFromEditorEnter = null, PointerDragFromEditorHoverEventListener onPointerDragFromEditorHover = null, @@ -1985,6 +1990,7 @@ public Listener( this.onPointerMove = onPointerMove; this.onPointerUp = onPointerUp; this.onPointerCancel = onPointerCancel; + this.onPointerSignal = onPointerSignal; this.onPointerHover = onPointerHover; this.onPointerExit = onPointerExit; this.onPointerEnter = onPointerEnter; @@ -2005,6 +2011,8 @@ public Listener( public readonly PointerCancelEventListener onPointerCancel; + public readonly PointerSignalEventListener onPointerSignal; + public readonly PointerHoverEventListener onPointerHover; public readonly PointerEnterEventListener onPointerEnter; @@ -2029,6 +2037,7 @@ public override RenderObject createRenderObject(BuildContext context) { onPointerMove: this.onPointerMove, onPointerUp: this.onPointerUp, onPointerCancel: this.onPointerCancel, + onPointerSignal: this.onPointerSignal, onPointerEnter: this.onPointerEnter, onPointerExit: this.onPointerExit, onPointerHover: this.onPointerHover, @@ -2047,6 +2056,7 @@ public override void updateRenderObject(BuildContext context, RenderObject rende renderObject.onPointerMove = this.onPointerMove; renderObject.onPointerUp = this.onPointerUp; renderObject.onPointerCancel = this.onPointerCancel; + renderObject.onPointerSignal = this.onPointerSignal; renderObject.onPointerEnter = this.onPointerEnter; renderObject.onPointerHover = this.onPointerHover; renderObject.onPointerExit = this.onPointerExit; @@ -2080,6 +2090,10 @@ public override void debugFillProperties(DiagnosticPropertiesBuilder properties) listeners.Add("cancel"); } + if (this.onPointerSignal != null) { + listeners.Add("signal"); + } + if (this.onPointerEnter != null) { listeners.Add("enter"); } diff --git a/Runtime/widgets/dismissible.cs b/Runtime/widgets/dismissible.cs index b91a06c8..88b1b867 100644 --- a/Runtime/widgets/dismissible.cs +++ b/Runtime/widgets/dismissible.cs @@ -42,7 +42,7 @@ public Dismissible( Dictionary dismissThresholds = null, TimeSpan? movementDuration = null, float crossAxisEndOffset = 0.0f, - DragStartBehavior dragStartBehavior = DragStartBehavior.down + DragStartBehavior dragStartBehavior = DragStartBehavior.start ) : base(key: key) { D.assert(key != null); D.assert(secondaryBackground != null ? background != null : true); diff --git a/Runtime/widgets/editable_text.cs b/Runtime/widgets/editable_text.cs index f4edcd2e..9d229ff4 100644 --- a/Runtime/widgets/editable_text.cs +++ b/Runtime/widgets/editable_text.cs @@ -36,7 +36,9 @@ public string text { get { return this.value.text; } set { - this.value = this.value.copyWith(text: value, selection: TextSelection.collapsed(-1), + this.value = this.value.copyWith( + text: value, + selection: TextSelection.collapsed(-1), composing: TextRange.empty); } } @@ -63,74 +65,56 @@ public void clearComposing() { } public class EditableText : StatefulWidget { - public readonly TextEditingController controller; - - public readonly FocusNode focusNode; - - public readonly bool obscureText; - - public readonly bool autocorrect; - - public readonly TextStyle style; - - public readonly TextAlign textAlign; - - public readonly TextDirection? textDirection; - - public readonly TextCapitalization textCapitalization; - - public readonly float? textScaleFactor; - - public readonly Color cursorColor; - - public readonly Color backgroundCursorColor; - - public readonly int? maxLines; - - public readonly bool autofocus; - - public readonly Color selectionColor; - - public readonly TextSelectionControls selectionControls; - - public readonly TextInputType keyboardType; - - public readonly TextInputAction? textInputAction; - - public readonly ValueChanged onChanged; - public readonly VoidCallback onEditingComplete; - public readonly ValueChanged onSubmitted; - - public readonly SelectionChangedCallback onSelectionChanged; - - public readonly List inputFormatters; - - public readonly bool rendererIgnoresPointer; - - public readonly bool unityTouchKeyboard; - - public EditableText(TextEditingController controller, FocusNode focusNode, TextStyle style, - Color cursorColor, Color backgroundCursorColor = null, bool obscureText = false, bool autocorrect = false, - TextAlign textAlign = TextAlign.left, TextDirection? textDirection = null, - float? textScaleFactor = null, int? maxLines = 1, - bool autofocus = false, Color selectionColor = null, TextSelectionControls selectionControls = null, - TextInputType keyboardType = null, TextInputAction? textInputAction = null, + public EditableText( + TextEditingController controller = null, + FocusNode focusNode = null, TextStyle style = null, + StrutStyle strutStyle = null, + Color cursorColor = null, + Color backgroundCursorColor = null, + bool obscureText = false, + bool autocorrect = false, + TextAlign textAlign = TextAlign.left, + TextDirection? textDirection = null, + float? textScaleFactor = null, + int? maxLines = 1, + int? minLines = null, + bool expands = false, + bool autofocus = false, + Color selectionColor = null, + TextSelectionControls selectionControls = null, + TextInputType keyboardType = null, + TextInputAction? textInputAction = null, TextCapitalization textCapitalization = TextCapitalization.none, - ValueChanged onChanged = null, VoidCallback onEditingComplete = null, - ValueChanged onSubmitted = null, SelectionChangedCallback onSelectionChanged = null, - List inputFormatters = null, bool rendererIgnoresPointer = false, - EdgeInsets scrollPadding = null, bool unityTouchKeyboard = false, - Key key = null, float? cursorWidth = 2.0f, Radius cursorRadius = null, bool cursorOpacityAnimates = false, - Offset cursorOffset = null, bool paintCursorAboveText = false, + ValueChanged onChanged = null, + VoidCallback onEditingComplete = null, + ValueChanged onSubmitted = null, + SelectionChangedCallback onSelectionChanged = null, + List inputFormatters = null, + bool rendererIgnoresPointer = false, + EdgeInsets scrollPadding = null, + bool unityTouchKeyboard = false, + Key key = null, + float? cursorWidth = 2.0f, + Radius cursorRadius = null, + bool cursorOpacityAnimates = false, + Offset cursorOffset = null, + bool paintCursorAboveText = false, Brightness? keyboardAppearance = Brightness.light, DragStartBehavior dragStartBehavior = DragStartBehavior.down, - bool? enableInteractiveSelection = null + bool? enableInteractiveSelection = null, + ScrollPhysics scrollPhysics = null, + GlobalKeyEventHandlerDelegate globalKeyEventHandler = null ) : base(key) { D.assert(controller != null); D.assert(focusNode != null); D.assert(style != null); D.assert(cursorColor != null); D.assert(maxLines == null || maxLines > 0); + D.assert(minLines == null || minLines > 0); + D.assert((maxLines == null) || (minLines == null) || (maxLines >= minLines), + () => "minLines can't be greater than maxLines"); + D.assert(!expands || (maxLines == null && minLines == null), + () => "minLines and maxLines must be null when expands is true."); // D.assert(backgroundCursorColor != null); // TODO: remove comment this.keyboardType = keyboardType ?? (maxLines == 1 ? TextInputType.text : TextInputType.multiline); @@ -140,6 +124,7 @@ public EditableText(TextEditingController controller, FocusNode focusNode, TextS this.obscureText = obscureText; this.autocorrect = autocorrect; this.style = style; + this._strutStyle = strutStyle; this.textAlign = textAlign; this.textDirection = textDirection; this.textScaleFactor = textScaleFactor; @@ -148,6 +133,8 @@ public EditableText(TextEditingController controller, FocusNode focusNode, TextS this.cursorColor = cursorColor; this.backgroundCursorColor = backgroundCursorColor ?? Colors.grey; // TODO: remove ?? this.maxLines = maxLines; + this.minLines = minLines; + this.expands = expands; this.autofocus = autofocus; this.selectionColor = selectionColor; this.onChanged = onChanged; @@ -176,8 +163,49 @@ public EditableText(TextEditingController controller, FocusNode focusNode, TextS this.keyboardAppearance = keyboardAppearance; this.enableInteractiveSelection = enableInteractiveSelection; this.dragStartBehavior = dragStartBehavior; + this.scrollPhysics = scrollPhysics; + this.globalKeyEventHandler = globalKeyEventHandler; + } + + public readonly TextEditingController controller; + public readonly FocusNode focusNode; + public readonly bool obscureText; + public readonly bool autocorrect; + public readonly TextStyle style; + public StrutStyle strutStyle { + get { + if (this._strutStyle == null) { + return this.style != null + ? StrutStyle.fromTextStyle(this.style, forceStrutHeight: true) + : StrutStyle.disabled; + } + + return this._strutStyle.inheritFromTextStyle(this.style); + } } + readonly StrutStyle _strutStyle; + public readonly TextAlign textAlign; + public readonly TextDirection? textDirection; + public readonly TextCapitalization textCapitalization; + public readonly float? textScaleFactor; + public readonly Color cursorColor; + public readonly Color backgroundCursorColor; + public readonly int? maxLines; + public readonly int? minLines; + public readonly bool expands; + public readonly bool autofocus; + public readonly Color selectionColor; + public readonly TextSelectionControls selectionControls; + public readonly TextInputType keyboardType; + public readonly TextInputAction? textInputAction; + public readonly ValueChanged onChanged; + public readonly VoidCallback onEditingComplete; + public readonly ValueChanged onSubmitted; + public readonly SelectionChangedCallback onSelectionChanged; + public readonly List inputFormatters; + public readonly bool rendererIgnoresPointer; + public readonly bool unityTouchKeyboard; public readonly float? cursorWidth; public readonly Radius cursorRadius; public readonly bool cursorOpacityAnimates; @@ -186,8 +214,9 @@ public EditableText(TextEditingController controller, FocusNode focusNode, TextS public readonly Brightness? keyboardAppearance; public readonly EdgeInsets scrollPadding; public readonly DragStartBehavior dragStartBehavior; - public readonly bool? enableInteractiveSelection; + public readonly ScrollPhysics scrollPhysics; + public readonly GlobalKeyEventHandlerDelegate globalKeyEventHandler; public bool selectionEnabled { get { return this.enableInteractiveSelection ?? !this.obscureText; } @@ -216,9 +245,14 @@ public override void debugFillProperties(DiagnosticPropertiesBuilder properties) properties.add(new DiagnosticsProperty("textScaleFactor", this.textScaleFactor, defaultValue: Diagnostics.kNullDefaultValue)); properties.add(new DiagnosticsProperty("maxLines", this.maxLines, defaultValue: 1)); + properties.add(new DiagnosticsProperty("minLines", this.minLines, + defaultValue: Diagnostics.kNullDefaultValue)); + properties.add(new DiagnosticsProperty("expands", this.expands, defaultValue: false)); properties.add(new DiagnosticsProperty("autofocus", this.autofocus, defaultValue: false)); properties.add( new DiagnosticsProperty("keyboardType", this.keyboardType, defaultValue: null)); + properties.add(new DiagnosticsProperty("scrollPhysics", this.scrollPhysics, + defaultValue: Diagnostics.kNullDefaultValue)); } } @@ -310,7 +344,7 @@ public override void dispose() { TextEditingValue _lastKnownRemoteTextEditingValue; - public void updateEditingValue(TextEditingValue value) { + public void updateEditingValue(TextEditingValue value, bool isIMEInput) { if (value.text != this._value.text) { this._hideSelectionOverlayIfNeeded(); this._showCaretOnScreen(); @@ -321,7 +355,7 @@ public void updateEditingValue(TextEditingValue value) { } this._lastKnownRemoteTextEditingValue = value; - this._formatAndSetValue(value); + this._formatAndSetValue(value, isIMEInput); this._stopCursorTimer(resetCharTicks: false); this._startCursorTimer(); @@ -330,7 +364,7 @@ public void updateEditingValue(TextEditingValue value) { public void performAction(TextInputAction action) { switch (action) { case TextInputAction.newline: - if (this.widget.maxLines == 1) { + if (!this._isMultiline) { this._finalizeEditing(true); } @@ -362,6 +396,10 @@ Offset _floatingCursorOffset { public void updateFloatingCursor(RawFloatingCursorPoint point) { switch (point.state) { case FloatingCursorDragState.Start: + if (this._floatingCursorResetController.isAnimating) { + this._floatingCursorResetController.stop(); + this._onFloatingCursorResetTick(); + } TextPosition currentTextPosition = new TextPosition(offset: this.renderEditable.selection.baseOffset); this._startCaretRect = this.renderEditable.getLocalRectForCaret(currentTextPosition); @@ -395,6 +433,10 @@ public void updateFloatingCursor(RawFloatingCursorPoint point) { } } + public RawInputKeyResponse globalInputKeyHandler(RawKeyEvent evt) { + return this.widget.globalKeyEventHandler?.Invoke(evt, true) ?? RawInputKeyResponse.convert(evt); + } + void _onFloatingCursorResetTick() { Offset finalPosition = this.renderEditable.getLocalRectForCaret(this._lastTextPosition).centerLeft - this._floatingCursorOffset; @@ -405,11 +447,13 @@ void _onFloatingCursorResetTick() { this._handleSelectionChanged(TextSelection.collapsed(offset: this._lastTextPosition.offset), this.renderEditable, SelectionChangedCause.forcePress); } + this._startCaretRect = null; this._lastTextPosition = null; this._pointOffsetOrigin = null; this._lastBoundedOffset = null; - } else { + } + else { float lerpValue = this._floatingCursorResetController.value; float lerpX = MathUtils.lerpFloat(this._lastBoundedOffset.dx, finalPosition.dx, lerpValue); float lerpY = MathUtils.lerpFloat(this._lastBoundedOffset.dy, finalPosition.dy, lerpValue); @@ -545,11 +589,13 @@ void _openOrCloseInputConnectionIfNeeded() { public void requestKeyboard() { if (this._hasFocus) { this._openInputConnection(); - } else { + } + else { List ancestorScopes = FocusScope.ancestorsOf(this.context); for (int i = ancestorScopes.Count - 1; i >= 1; i -= 1) { ancestorScopes[i].setFirstFocus(ancestorScopes[i - 1]); } + FocusScope.of(this.context).requestFocus(this.widget.focusNode); } } @@ -684,8 +730,8 @@ public IPromise didPushRoute(string route) { return Promise.Resolved(false); } - void _formatAndSetValue(TextEditingValue value) { - var textChanged = this._value?.text != value?.text; + void _formatAndSetValue(TextEditingValue value, bool isIMEInput = false) { + var textChanged = this._value?.text != value?.text || isIMEInput; if (textChanged && this.widget.inputFormatters != null && this.widget.inputFormatters.isNotEmpty()) { foreach (var formatter in this.widget.inputFormatters) { value = formatter.formatEditUpdate(this._value, value); @@ -825,7 +871,8 @@ void _handleFocusChanged() { get { TextDirection? result = this.widget.textDirection ?? Directionality.of(this.context); D.assert(result != null, - () => $"{this.GetType().FullName} created without a textDirection and with no ambient Directionality."); + () => + $"{this.GetType().FullName} created without a textDirection and with no ambient Directionality."); return result; } } @@ -865,13 +912,14 @@ public void hideToolbar() { } public override Widget build(BuildContext context) { + D.assert(WidgetsD.debugCheckHasMediaQuery(context)); FocusScope.of(context).reparentIfNeeded(this.widget.focusNode); base.build(context); // See AutomaticKeepAliveClientMixin. return new Scrollable( axisDirection: this._isMultiline ? AxisDirection.down : AxisDirection.right, controller: this._scrollController, - physics: new ClampingScrollPhysics(), + physics: this.widget.scrollPhysics, dragStartBehavior: this.widget.dragStartBehavior, viewportBuilder: (BuildContext _context, ViewportOffset offset) => new CompositedTransformTarget( @@ -887,6 +935,9 @@ public override Widget build(BuildContext context) { : this._cursorVisibilityNotifier, hasFocus: this._hasFocus, maxLines: this.widget.maxLines, + minLines: this.widget.minLines, + expands: this.widget.expands, + strutStyle: this.widget.strutStyle, selectionColor: this.widget.selectionColor, textScaleFactor: this.widget.textScaleFactor ?? MediaQuery.textScaleFactorOf(context), textAlign: this.widget.textAlign, @@ -903,7 +954,8 @@ public override Widget build(BuildContext context) { paintCursorAboveText: this.widget.paintCursorAboveText, enableInteractiveSelection: this.widget.enableInteractiveSelection == true, textSelectionDelegate: this, - devicePixelRatio: this._devicePixelRatio + devicePixelRatio: this._devicePixelRatio, + globalKeyEventHandler : this.widget.globalKeyEventHandler ) ) ); @@ -985,6 +1037,9 @@ class _Editable : LeafRenderObjectWidget { public readonly ValueNotifier showCursor; public readonly bool hasFocus; public readonly int? maxLines; + public readonly int? minLines; + public readonly bool expands; + public readonly StrutStyle strutStyle; public readonly Color selectionColor; public readonly float textScaleFactor; public readonly TextAlign textAlign; @@ -1002,18 +1057,37 @@ class _Editable : LeafRenderObjectWidget { public readonly TextSelectionDelegate textSelectionDelegate; public readonly bool? paintCursorAboveText; public readonly float? devicePixelRatio; + public readonly GlobalKeyEventHandlerDelegate globalKeyEventHandler; - - public _Editable(TextSpan textSpan = null, TextEditingValue value = null, - Color cursorColor = null, Color backgroundCursorColor = null, ValueNotifier showCursor = null, + public _Editable(TextSpan textSpan = null, + TextEditingValue value = null, + Color cursorColor = null, + Color backgroundCursorColor = null, + ValueNotifier showCursor = null, bool hasFocus = false, - int? maxLines = null, Color selectionColor = null, float textScaleFactor = 1.0f, - TextDirection? textDirection = null, bool obscureText = false, TextAlign textAlign = TextAlign.left, - bool autocorrect = false, ViewportOffset offset = null, SelectionChangedHandler onSelectionChanged = null, - CaretChangedHandler onCaretChanged = null, bool rendererIgnoresPointer = false, - Key key = null, TextSelectionDelegate textSelectionDelegate = null, float? cursorWidth = null, - Radius cursorRadius = null, Offset cursorOffset = null, bool enableInteractiveSelection = true, - bool? paintCursorAboveText = null, float? devicePixelRatio = null) : base(key) { + int? maxLines = null, + int? minLines = null, + bool expands = false, + StrutStyle strutStyle = null, + Color selectionColor = null, + float textScaleFactor = 1.0f, + TextDirection? textDirection = null, + bool obscureText = false, + TextAlign textAlign = TextAlign.left, + bool autocorrect = false, + ViewportOffset offset = null, + SelectionChangedHandler onSelectionChanged = null, + CaretChangedHandler onCaretChanged = null, + bool rendererIgnoresPointer = false, + Key key = null, + TextSelectionDelegate textSelectionDelegate = null, + float? cursorWidth = null, + Radius cursorRadius = null, + Offset cursorOffset = null, + bool enableInteractiveSelection = true, + bool? paintCursorAboveText = null, + float? devicePixelRatio = null, + GlobalKeyEventHandlerDelegate globalKeyEventHandler = null) : base(key) { this.textSpan = textSpan; this.value = value; this.cursorColor = cursorColor; @@ -1021,6 +1095,9 @@ public _Editable(TextSpan textSpan = null, TextEditingValue value = null, this.showCursor = showCursor; this.hasFocus = hasFocus; this.maxLines = maxLines; + this.minLines = minLines; + this.expands = expands; + this.strutStyle = strutStyle; this.selectionColor = selectionColor; this.textScaleFactor = textScaleFactor; this.textAlign = textAlign; @@ -1038,6 +1115,7 @@ public _Editable(TextSpan textSpan = null, TextEditingValue value = null, this.enableInteractiveSelection = enableInteractiveSelection; this.paintCursorAboveText = paintCursorAboveText; this.devicePixelRatio = devicePixelRatio; + this.globalKeyEventHandler = globalKeyEventHandler; } public override RenderObject createRenderObject(BuildContext context) { @@ -1050,6 +1128,9 @@ public override RenderObject createRenderObject(BuildContext context) { backgroundCursorColor: this.backgroundCursorColor, hasFocus: this.hasFocus, maxLines: this.maxLines, + minLines: this.minLines, + expands: this.expands, + strutStyle: this.strutStyle, selectionColor: this.selectionColor, textScaleFactor: this.textScaleFactor, textAlign: this.textAlign, @@ -1064,7 +1145,8 @@ public override RenderObject createRenderObject(BuildContext context) { enableInteractiveSelection: this.enableInteractiveSelection, textSelectionDelegate: this.textSelectionDelegate, paintCursorAboveText: this.paintCursorAboveText == true, - devicePixelRatio: this.devicePixelRatio ?? 1.0f + devicePixelRatio: this.devicePixelRatio ?? 1.0f, + globalKeyEventHandler : this.globalKeyEventHandler ); } @@ -1076,6 +1158,7 @@ public override void updateRenderObject(BuildContext context, RenderObject rende edit.showCursor = this.showCursor; edit.hasFocus = this.hasFocus; edit.maxLines = this.maxLines; + edit.strutStyle = this.strutStyle; edit.selectionColor = this.selectionColor; edit.textScaleFactor = this.textScaleFactor; edit.textAlign = this.textAlign; @@ -1093,6 +1176,7 @@ public override void updateRenderObject(BuildContext context, RenderObject rende edit.enableInteractiveSelection = this.enableInteractiveSelection; edit.paintCursorAboveText = this.paintCursorAboveText == true; edit.devicePixelRatio = this.devicePixelRatio ?? 1.0f; + edit.globalKeyEventHandler = this.globalKeyEventHandler; } } } \ No newline at end of file diff --git a/Runtime/widgets/fade_in_image.cs b/Runtime/widgets/fade_in_image.cs index 1a9aaa6f..dfc6a9c2 100644 --- a/Runtime/widgets/fade_in_image.cs +++ b/Runtime/widgets/fade_in_image.cs @@ -101,11 +101,11 @@ public static FadeInImage assetNetwork( ) { D.assert(placeholder != null); D.assert(image != null); - D.assert(fadeOutDuration != null); - D.assert(fadeOutCurve != null); - D.assert(fadeInDuration != null); - D.assert(fadeInCurve != null); - D.assert(alignment != null); + fadeOutDuration = fadeOutDuration ?? new TimeSpan(0, 0, 0, 0, 300); + fadeOutCurve = fadeOutCurve ?? Curves.easeOut; + fadeInDuration = fadeInDuration ?? new TimeSpan(0, 0, 0, 0, 700); + fadeInCurve = Curves.easeIn; + alignment = alignment ?? Alignment.center; var imageProvider = placeholderScale != null ? new ExactAssetImage(placeholder, bundle: bundle, scale: placeholderScale ?? 1.0f) : (ImageProvider) new AssetImage(placeholder, bundle: bundle); diff --git a/Runtime/widgets/form.cs b/Runtime/widgets/form.cs index 1f1e7cd2..f42740ec 100644 --- a/Runtime/widgets/form.cs +++ b/Runtime/widgets/form.cs @@ -217,12 +217,10 @@ public bool validate() { return !this.hasError; } - bool _validate() { + void _validate() { if (this.widget.validator != null) { this._errorText = this.widget.validator(this._value); } - - return !this.hasError; } public virtual void didChange(T value) { diff --git a/Runtime/widgets/gesture_detector.cs b/Runtime/widgets/gesture_detector.cs index d79e8f86..37450055 100644 --- a/Runtime/widgets/gesture_detector.cs +++ b/Runtime/widgets/gesture_detector.cs @@ -71,10 +71,10 @@ public GestureDetector( GestureTapCancelCallback onTapCancel = null, GestureDoubleTapCallback onDoubleTap = null, GestureLongPressCallback onLongPress = null, + GestureLongPressStartCallback onLongPressStart = null, + GestureLongPressMoveUpdateCallback onLongPressMoveUpdate = null, GestureLongPressUpCallback onLongPressUp = null, - GestureLongPressDragStartCallback onLongPressDragStart = null, - GestureLongPressDragUpdateCallback onLongPressDragUpdate = null, - GestureLongPressDragUpCallback onLongPressDragUp = null, + GestureLongPressEndCallback onLongPressEnd = null, GestureDragDownCallback onVerticalDragDown = null, GestureDragStartCallback onVerticalDragStart = null, GestureDragUpdateCallback onVerticalDragUpdate = null, @@ -103,9 +103,6 @@ public GestureDetector( bool haveHorizontalDrag = onHorizontalDragStart != null || onHorizontalDragUpdate != null || onHorizontalDragEnd != null; - bool haveLongPress = onLongPress != null || onLongPressUp != null; - bool haveLongPressDrag = onLongPressDragStart != null || onLongPressDragUpdate != null || - onLongPressDragUp != null; bool havePan = onPanStart != null || onPanUpdate != null || onPanEnd != null; bool haveScale = onScaleStart != null || onScaleUpdate != null || onScaleEnd != null; if (havePan || haveScale) { @@ -126,16 +123,6 @@ public GestureDetector( } } - if (haveLongPress && haveLongPressDrag) { - throw new UIWidgetsError( - "Incorrect GestureDetector arguments.\n" + - "Having both a long press and a long press drag recognizer is " + - "redundant as the long press drag is a superset of long press. " + - "Except long press drag allows for drags after the long press is " + - "triggered." - ); - } - return true; }); @@ -147,9 +134,9 @@ public GestureDetector( this.onDoubleTap = onDoubleTap; this.onLongPress = onLongPress; this.onLongPressUp = onLongPressUp; - this.onLongPressDragStart = onLongPressDragStart; - this.onLongPressDragUpdate = onLongPressDragUpdate; - this.onLongPressDragUp = onLongPressDragUp; + this.onLongPressStart = onLongPressStart; + this.onLongPressMoveUpdate = onLongPressMoveUpdate; + this.onLongPressEnd = onLongPressEnd; this.onVerticalDragDown = onVerticalDragDown; this.onVerticalDragStart = onVerticalDragStart; this.onVerticalDragUpdate = onVerticalDragUpdate; @@ -180,9 +167,9 @@ public GestureDetector( public readonly GestureDoubleTapCallback onDoubleTap; public readonly GestureLongPressCallback onLongPress; public readonly GestureLongPressUpCallback onLongPressUp; - public readonly GestureLongPressDragStartCallback onLongPressDragStart; - public readonly GestureLongPressDragUpdateCallback onLongPressDragUpdate; - public readonly GestureLongPressDragUpCallback onLongPressDragUp; + public readonly GestureLongPressStartCallback onLongPressStart; + public readonly GestureLongPressMoveUpdateCallback onLongPressMoveUpdate; + public readonly GestureLongPressEndCallback onLongPressEnd; public readonly GestureDragDownCallback onVerticalDragDown; public readonly GestureDragStartCallback onVerticalDragStart; public readonly GestureDragUpdateCallback onVerticalDragUpdate; @@ -231,30 +218,24 @@ public override Widget build(BuildContext context) { ); } - if (this.onLongPress != null || this.onLongPressUp != null) { + if (this.onLongPress != null || + this.onLongPressUp != null || + this.onLongPressStart != null || + this.onLongPressMoveUpdate != null || + this.onLongPressEnd != null) { gestures[typeof(LongPressGestureRecognizer)] = new GestureRecognizerFactoryWithHandlers( () => new LongPressGestureRecognizer(debugOwner: this), instance => { instance.onLongPress = this.onLongPress; + instance.onLongPressStart = this.onLongPressStart; + instance.onLongPressMoveUpdate = this.onLongPressMoveUpdate; + instance.onLongPressEnd = this.onLongPressEnd; instance.onLongPressUp = this.onLongPressUp; } ); } - if (this.onLongPressDragStart != null || this.onLongPressDragUpdate != null || - this.onLongPressDragUp != null) { - gestures[typeof(LongPressDragGestureRecognizer)] = - new GestureRecognizerFactoryWithHandlers( - () => new LongPressDragGestureRecognizer(debugOwner: this), - (LongPressDragGestureRecognizer instance) => { - instance.onLongPressStart = this.onLongPressDragStart; - instance.onLongPressDragUpdate = this.onLongPressDragUpdate; - instance.onLongPressUp = this.onLongPressDragUp; - } - ); - } - if (this.onVerticalDragDown != null || this.onVerticalDragStart != null || this.onVerticalDragUpdate != null || diff --git a/Runtime/widgets/heroes.cs b/Runtime/widgets/heroes.cs index f69422bd..bcd2c02e 100644 --- a/Runtime/widgets/heroes.cs +++ b/Runtime/widgets/heroes.cs @@ -66,10 +66,30 @@ public Hero( public readonly bool transitionOnUserGestures; internal static Dictionary - _allHeroesFor(BuildContext context, bool isUserGestureTransition) { + _allHeroesFor(BuildContext context, bool isUserGestureTransition, NavigatorState navigator) { D.assert(context != null); + D.assert(navigator != null); Dictionary result = new Dictionary { }; + void addHero(StatefulElement hero, object tag) { + D.assert(() => { + if (result.ContainsKey(tag)) { + throw new UIWidgetsError( + "There are multiple heroes that share the same tag within a subtree.\n" + + "Within each subtree for which heroes are to be animated (typically a PageRoute subtree), " + + "each Hero must have a unique non-null tag.\n" + + $"In this case, multiple heroes had the following tag: {tag}\n" + + "Here is the subtree for one of the offending heroes:\n" + + $"{hero.toStringDeep(prefixLineOne: "# ")}" + ); + } + + return true; + }); + _HeroState heroState = (_HeroState) hero.state; + result[tag] = heroState; + } + void visitor(Element element) { if (element.widget is Hero) { StatefulElement hero = (StatefulElement) element; @@ -77,22 +97,15 @@ void visitor(Element element) { if (!isUserGestureTransition || heroWidget.transitionOnUserGestures) { object tag = heroWidget.tag; D.assert(tag != null); - D.assert(() => { - if (result.ContainsKey(tag)) { - throw new UIWidgetsError( - "There are multiple heroes that share the same tag within a subtree.\n" + - "Within each subtree for which heroes are to be animated (typically a PageRoute subtree), " + - "each Hero must have a unique non-null tag.\n" + - $"In this case, multiple heroes had the following tag: {tag}\n" + - "Here is the subtree for one of the offending heroes:\n" + - $"{element.toStringDeep(prefixLineOne: "# ")}" - ); + if (Navigator.of(hero) == navigator) { + addHero(hero, tag); + } + else { + ModalRoute heroRoute = ModalRoute.of(hero); + if (heroRoute != null && heroRoute is PageRoute && heroRoute.isCurrent) { + addHero(hero, tag); } - - return true; - }); - _HeroState heroState = (_HeroState) hero.state; - result[tag] = heroState; + } } } @@ -131,6 +144,8 @@ public void endFlight() { } public override Widget build(BuildContext context) { + D.assert(context.ancestorWidgetOfExactType(typeof(Hero)) == null, + () => "A Hero widget cannot be the descendant of another Hero widget."); if (this._placeholderSize != null) { if (this.widget.placeholderBuilder == null) { return new SizedBox( @@ -163,7 +178,7 @@ public _HeroFlightManifest( HeroFlightShuttleBuilder shuttleBuilder, bool isUserGestureTransition ) { - D.assert(this.fromHero.widget.tag == this.toHero.widget.tag); + D.assert(fromHero.widget.tag.Equals(toHero.widget.tag)); this.type = type; this.overlay = overlay; this.navigatorRect = navigatorRect; @@ -417,7 +432,7 @@ public override string ToString() { } public class HeroController : NavigatorObserver { - HeroController(CreateRectTween createRectTween) { + public HeroController(CreateRectTween createRectTween = null) { this.createRectTween = createRectTween; } @@ -434,7 +449,16 @@ public override void didPush(Route route, Route previousRoute) { public override void didPop(Route route, Route previousRoute) { D.assert(this.navigator != null); D.assert(route != null); - this._maybeStartHeroTransition(route, previousRoute, HeroFlightDirection.pop, false); + if (!this.navigator.userGestureInProgress) { + this._maybeStartHeroTransition(route, previousRoute, HeroFlightDirection.pop, false); + } + } + + public override void didReplace(Route newRoute = null, Route oldRoute = null) { + D.assert(this.navigator != null); + if (newRoute?.isCurrent == true) { + this._maybeStartHeroTransition(oldRoute, newRoute, HeroFlightDirection.push, false); + } } public override void didStartUserGesture(Route route, Route previousRoute) { @@ -496,14 +520,15 @@ bool isUserGestureTransition Rect navigatorRect = HeroUtils._globalBoundingBoxFor(this.navigator.context); - Dictionary - fromHeroes = Hero._allHeroesFor(from.subtreeContext, isUserGestureTransition); - Dictionary toHeroes = Hero._allHeroesFor(to.subtreeContext, isUserGestureTransition); + Dictionary fromHeroes = + Hero._allHeroesFor(from.subtreeContext, isUserGestureTransition, this.navigator); + Dictionary toHeroes = + Hero._allHeroesFor(to.subtreeContext, isUserGestureTransition, this.navigator); to.offstage = false; foreach (object tag in fromHeroes.Keys) { - if (toHeroes[tag] != null) { + if (toHeroes.ContainsKey(tag)) { HeroFlightShuttleBuilder fromShuttleBuilder = fromHeroes[tag].widget.flightShuttleBuilder; HeroFlightShuttleBuilder toShuttleBuilder = toHeroes[tag].widget.flightShuttleBuilder; @@ -521,16 +546,16 @@ bool isUserGestureTransition isUserGestureTransition: isUserGestureTransition ); - if (this._flights[tag] != null) { - this._flights[tag].divert(manifest); + if (this._flights.TryGetValue(tag, out var result)) { + result.divert(manifest); } else { this._flights[tag] = new _HeroFlight(this._handleFlightEnded); this._flights[tag].start(manifest); } } - else if (this._flights[tag] != null) { - this._flights[tag].abort(); + else if (this._flights.TryGetValue(tag, out var result)) { + result.abort(); } } } @@ -550,4 +575,4 @@ BuildContext toHeroContext return toHero.child; }; } -} \ No newline at end of file +} diff --git a/Runtime/widgets/icon.cs b/Runtime/widgets/icon.cs index 58c2b7d3..d494ed35 100644 --- a/Runtime/widgets/icon.cs +++ b/Runtime/widgets/icon.cs @@ -1,5 +1,6 @@ using Unity.UIWidgets.foundation; using Unity.UIWidgets.painting; +using Unity.UIWidgets.rendering; using Unity.UIWidgets.ui; using TextStyle = Unity.UIWidgets.painting.TextStyle; @@ -36,6 +37,7 @@ public override Widget build(BuildContext context) { } Widget iconWidget = new RichText( + overflow: TextOverflow.visible, text: new TextSpan( text: new string(new[] {(char) this.icon.codePoint}), style: new TextStyle( diff --git a/Runtime/widgets/implicit_animations.cs b/Runtime/widgets/implicit_animations.cs index 82c8caee..9bff67c3 100644 --- a/Runtime/widgets/implicit_animations.cs +++ b/Runtime/widgets/implicit_animations.cs @@ -437,6 +437,275 @@ public override void debugFillProperties(DiagnosticPropertiesBuilder description } } + public class AnimatedAlign : ImplicitlyAnimatedWidget { + public AnimatedAlign( + Key key = null, + Alignment alignment = null, + Widget child = null, + Curve curve = null, + TimeSpan? duration = null + ) : base(key: key, curve: curve ?? Curves.linear, duration: duration) { + D.assert(alignment != null); + this.alignment = alignment; + this.child = child; + } + + public readonly Alignment alignment; + + public readonly Widget child; + + public override State createState() { + return new _AnimatedAlignState(); + } + + public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { + base.debugFillProperties(properties: properties); + properties.add(new DiagnosticsProperty("alignment", value: this.alignment)); + } + } + + class _AnimatedAlignState : AnimatedWidgetBaseState { + AlignmentTween _alignment; + + protected override void forEachTween(TweenVisitor visitor) { + this._alignment = (AlignmentTween) visitor.visit(this, tween: this._alignment, + targetValue: this.widget.alignment, constructor: value => new AlignmentTween(begin: value)); + } + + public override Widget build(BuildContext context) { + return new Align( + alignment: this._alignment.evaluate(animation: this.animation), + child: this.widget.child + ); + } + + public override void debugFillProperties(DiagnosticPropertiesBuilder description) { + base.debugFillProperties(properties: description); + description.add(new DiagnosticsProperty("alignment", value: this._alignment, defaultValue: null)); + } + } + + public class AnimatedPositioned : ImplicitlyAnimatedWidget { + public AnimatedPositioned( + Key key = null, + Widget child = null, + float? left = null, + float? top = null, + float? right = null, + float? bottom = null, + float? width = null, + float? height = null, + Curve curve = null, + TimeSpan? duration = null + ) : base(key: key, curve: curve ?? Curves.linear, duration: duration) { + D.assert(left == null || right == null || width == null); + D.assert(top == null || bottom == null || height == null); + this.child = child; + this.left = left; + this.top = top; + this.right = right; + this.bottom = bottom; + this.width = width; + this.height = height; + } + + public static AnimatedPositioned fromRect( + Key key = null, + Widget child = null, + Rect rect = null, + Curve curve = null, + TimeSpan? duration = null + ) { + return new AnimatedPositioned( + child: child, + duration: duration, + left: rect.left, + top: rect.top, + right: null, + bottom: null, + width: rect.width, + height: rect.height, + curve: curve ?? Curves.linear, + key: key + ); + } + + public readonly Widget child; + + public readonly float? left; + + public readonly float? top; + + public readonly float? right; + + public readonly float? bottom; + + public readonly float? width; + + public readonly float? height; + + public override State createState() { + return new _AnimatedPositionedState(); + } + + public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { + base.debugFillProperties(properties: properties); + properties.add(new FloatProperty("left", value: this.left, defaultValue: null)); + properties.add(new FloatProperty("top", value: this.top, defaultValue: null)); + properties.add(new FloatProperty("right", value: this.right, defaultValue: null)); + properties.add(new FloatProperty("bottom", value: this.bottom, defaultValue: null)); + properties.add(new FloatProperty("width", value: this.width, defaultValue: null)); + properties.add(new FloatProperty("height", value: this.height, defaultValue: null)); + } + } + + class _AnimatedPositionedState : AnimatedWidgetBaseState { + Tween _left; + Tween _top; + Tween _right; + Tween _bottom; + Tween _width; + Tween _height; + + protected override void forEachTween(TweenVisitor visitor) { + this._left = visitor.visit(this, tween: this._left, targetValue: this.widget.left, + constructor: value => new NullableFloatTween(begin: value)); + this._top = visitor.visit(this, tween: this._top, targetValue: this.widget.top, + constructor: value => new NullableFloatTween(begin: value)); + this._right = visitor.visit(this, tween: this._right, targetValue: this.widget.right, + constructor: value => new NullableFloatTween(begin: value)); + this._bottom = visitor.visit(this, tween: this._bottom, targetValue: this.widget.bottom, + constructor: value => new NullableFloatTween(begin: value)); + this._width = visitor.visit(this, tween: this._width, targetValue: this.widget.width, + constructor: value => new NullableFloatTween(begin: value)); + this._height = visitor.visit(this, tween: this._height, targetValue: this.widget.height, + constructor: value => new NullableFloatTween(begin: value)); + } + + public override Widget build(BuildContext context) { + return new Positioned( + child: this.widget.child, + left: this._left?.evaluate(animation: this.animation), + top: this._top?.evaluate(animation: this.animation), + right: this._right?.evaluate(animation: this.animation), + bottom: this._bottom?.evaluate(animation: this.animation), + width: this._width?.evaluate(animation: this.animation), + height: this._height?.evaluate(animation: this.animation) + ); + } + + public override void debugFillProperties(DiagnosticPropertiesBuilder description) { + base.debugFillProperties(properties: description); + description.add(ObjectFlagProperty>.has("left", value: this._left)); + description.add(ObjectFlagProperty>.has("top", value: this._top)); + description.add(ObjectFlagProperty>.has("right", value: this._right)); + description.add(ObjectFlagProperty>.has("bottom", value: this._bottom)); + description.add(ObjectFlagProperty>.has("width", value: this._width)); + description.add(ObjectFlagProperty>.has("height", value: this._height)); + } + } + + public class AnimatedPositionedDirectional : ImplicitlyAnimatedWidget { + public AnimatedPositionedDirectional( + Key key = null, + Widget child = null, + float? start = null, + float? top = null, + float? end = null, + float? bottom = null, + float? width = null, + float? height = null, + Curve curve = null, + TimeSpan? duration = null + ) : base(key: key, curve: curve, duration: duration) { + D.assert(start == null || end == null || width == null); + D.assert(top == null || bottom == null || height == null); + this.child = child; + this.start = start; + this.top = top; + this.end = end; + this.bottom = bottom; + this.width = width; + this.height = height; + } + + public readonly Widget child; + + public readonly float? start; + + public readonly float? top; + + public readonly float? end; + + public readonly float? bottom; + + public readonly float? width; + + public readonly float? height; + + public override State createState() { + return new _AnimatedPositionedDirectionalState(); + } + + public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { + base.debugFillProperties(properties: properties); + properties.add(new FloatProperty("start", value: this.start, defaultValue: null)); + properties.add(new FloatProperty("top", value: this.top, defaultValue: null)); + properties.add(new FloatProperty("end", value: this.end, defaultValue: null)); + properties.add(new FloatProperty("bottom", value: this.bottom, defaultValue: null)); + properties.add(new FloatProperty("width", value: this.width, defaultValue: null)); + properties.add(new FloatProperty("height", value: this.height, defaultValue: null)); + } + } + + class _AnimatedPositionedDirectionalState : AnimatedWidgetBaseState { + Tween _start; + Tween _top; + Tween _end; + Tween _bottom; + Tween _width; + Tween _height; + + protected override void forEachTween(TweenVisitor visitor) { + this._start = visitor.visit(this, tween: this._start, targetValue: this.widget.start, + constructor: value => new NullableFloatTween(begin: value)); + this._top = visitor.visit(this, tween: this._top, targetValue: this.widget.top, + constructor: value => new NullableFloatTween(begin: value)); + this._end = visitor.visit(this, tween: this._end, targetValue: this.widget.end, + constructor: value => new NullableFloatTween(begin: value)); + this._bottom = visitor.visit(this, tween: this._bottom, targetValue: this.widget.bottom, + constructor: value => new NullableFloatTween(begin: value)); + this._width = visitor.visit(this, tween: this._width, targetValue: this.widget.width, + constructor: value => new NullableFloatTween(begin: value)); + this._height = visitor.visit(this, tween: this._height, targetValue: this.widget.height, + constructor: value => new NullableFloatTween(begin: value)); + } + + public override Widget build(BuildContext context) { + D.assert(WidgetsD.debugCheckHasDirectionality(context)); + return Positioned.directional( + textDirection: Directionality.of(context: context), + child: this.widget.child, + start: this._start?.evaluate(animation: this.animation), + top: this._top?.evaluate(animation: this.animation), + end: this._end?.evaluate(animation: this.animation), + bottom: this._bottom?.evaluate(animation: this.animation), + width: this._width?.evaluate(animation: this.animation), + height: this._height?.evaluate(animation: this.animation) + ); + } + + public override void debugFillProperties(DiagnosticPropertiesBuilder description) { + base.debugFillProperties(properties: description); + description.add(ObjectFlagProperty>.has("start", value: this._start)); + description.add(ObjectFlagProperty>.has("top", value: this._top)); + description.add(ObjectFlagProperty>.has("end", value: this._end)); + description.add(ObjectFlagProperty>.has("bottom", value: this._bottom)); + description.add(ObjectFlagProperty>.has("width", value: this._width)); + description.add(ObjectFlagProperty>.has("height", value: this._height)); + } + } + public class AnimatedOpacity : ImplicitlyAnimatedWidget { public AnimatedOpacity( Key key = null, diff --git a/Runtime/widgets/layout_builder.cs b/Runtime/widgets/layout_builder.cs index f53b2072..6bdf74ee 100644 --- a/Runtime/widgets/layout_builder.cs +++ b/Runtime/widgets/layout_builder.cs @@ -158,7 +158,7 @@ protected override float computeMinIntrinsicHeight(float width) { return 0.0f; } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { D.assert(this._debugThrowIfNotCheckingIntrinsics()); return 0.0f; } diff --git a/Runtime/widgets/list_wheel_scroll_view.cs b/Runtime/widgets/list_wheel_scroll_view.cs new file mode 100644 index 00000000..94b4f324 --- /dev/null +++ b/Runtime/widgets/list_wheel_scroll_view.cs @@ -0,0 +1,804 @@ +using System; +using System.Collections.Generic; +using RSG; +using Unity.UIWidgets.animation; +using Unity.UIWidgets.foundation; +using Unity.UIWidgets.painting; +using Unity.UIWidgets.physics; +using Unity.UIWidgets.rendering; +using Unity.UIWidgets.external; +using Unity.UIWidgets.scheduler; +using Unity.UIWidgets.ui; +using UnityEngine; + +namespace Unity.UIWidgets.widgets { + public interface ListWheelChildDelegate { + Widget build(BuildContext context, int index); + int? estimatedChildCount { get; } + int trueIndexOf(int index); + bool shouldRebuild(ListWheelChildDelegate oldDelegate); + } + + public class ListWheelChildListDelegate : ListWheelChildDelegate { + public ListWheelChildListDelegate( + List children + ) { + D.assert(children != null); + this.children = children; + } + + public readonly List children; + + public int? estimatedChildCount { + get { return this.children.Count; } + } + + public Widget build(BuildContext context, int index) { + if (index < 0 || index >= this.children.Count) { + return null; + } + + return new Container(child: this.children[index]); + } + + public int trueIndexOf(int index) { + return index; + } + + public bool shouldRebuild(ListWheelChildDelegate oldDelegate) { + return this.children != ((ListWheelChildListDelegate) oldDelegate).children; + } + } + + public class ListWheelChildLoopingListDelegate : ListWheelChildDelegate { + public ListWheelChildLoopingListDelegate( + List children + ) { + D.assert(children != null); + this.children = children; + } + + public readonly List children; + + public int? estimatedChildCount { + get { return null; } + } + + public int trueIndexOf(int index) { + while (index < 0) { + index += this.children.Count; + } + + return index % this.children.Count; + } + + public Widget build(BuildContext context, int index) { + if (this.children.isEmpty()) { + return null; + } + + while (index < 0) { + index += this.children.Count; + } + + return new Container(child: this.children[index % this.children.Count]); + } + + public bool shouldRebuild(ListWheelChildDelegate oldDelegate) { + return this.children != ((ListWheelChildLoopingListDelegate) oldDelegate).children; + } + } + + public class ListWheelChildBuilderDelegate : ListWheelChildDelegate { + public ListWheelChildBuilderDelegate( + IndexedWidgetBuilder builder, + int? childCount = null + ) { + D.assert(builder != null); + this.builder = builder; + this.childCount = childCount; + } + + public readonly IndexedWidgetBuilder builder; + + public readonly int? childCount; + + public int? estimatedChildCount { + get { return this.childCount; } + } + + public Widget build(BuildContext context, int index) { + if (this.childCount == null) { + Widget child = this.builder(context, index); + return child == null ? null : new Container(child: child); + } + + if (index < 0 || index >= this.childCount) { + return null; + } + + return new Container(child: this.builder(context, index)); + } + + public int trueIndexOf(int index) { + return index; + } + + public bool shouldRebuild(ListWheelChildDelegate oldDelegate) { + return this.builder != ((ListWheelChildBuilderDelegate) oldDelegate).builder || + this.childCount != ((ListWheelChildBuilderDelegate) oldDelegate).childCount; + } + } + + class ListWheelScrollViewUtils { + public static int _getItemFromOffset( + float offset, + float itemExtent, + float minScrollExtent, + float maxScrollExtent + ) { + return (_clipOffsetToScrollableRange(offset, minScrollExtent, maxScrollExtent) / itemExtent).round(); + } + + public static float _clipOffsetToScrollableRange( + float offset, + float minScrollExtent, + float maxScrollExtent + ) { + return Mathf.Min(Mathf.Max(offset, minScrollExtent), maxScrollExtent); + } + } + + public class FixedExtentScrollController : ScrollController { + public FixedExtentScrollController( + int initialItem = 0 + ) { + this.initialItem = initialItem; + } + + public readonly int initialItem; + + public int selectedItem { + get { + D.assert(this.positions.isNotEmpty(), + () => + "FixedExtentScrollController.selectedItem cannot be accessed before a scroll view is built with it." + ); + D.assert(this.positions.Count == 1, + () => + "The selectedItem property cannot be read when multiple scroll views are attached to the same FixedExtentScrollController." + ); + _FixedExtentScrollPosition position = (_FixedExtentScrollPosition) this.position; + return position.itemIndex; + } + } + + public IPromise animateToItem( + int itemIndex, + TimeSpan duration, + Curve curve + ) { + if (!this.hasClients) { + return Promise.Resolved(); + } + + List futures = new List(); + foreach (_FixedExtentScrollPosition position in this.positions) { + futures.Add(position.animateTo( + itemIndex * position.itemExtent, + duration: duration, + curve: curve + )); + } + + return Promise.All(futures); + } + + public void jumpToItem(int itemIndex) { + foreach (_FixedExtentScrollPosition position in this.positions) { + position.jumpTo(itemIndex * position.itemExtent); + } + } + + public override ScrollPosition createScrollPosition(ScrollPhysics physics, ScrollContext context, + ScrollPosition oldPosition) { + return new _FixedExtentScrollPosition( + physics: physics, + context: context, + initialItem: this.initialItem, + oldPosition: oldPosition + ); + } + } + + public interface IFixedExtentMetrics { + int itemIndex { set; get; } + + FixedExtentMetrics copyWith( + float? minScrollExtent = null, + float? maxScrollExtent = null, + float? pixels = null, + float? viewportDimension = null, + AxisDirection? axisDirection = null, + int? itemIndex = null + ); + } + + public class FixedExtentMetrics : FixedScrollMetrics, IFixedExtentMetrics { + public FixedExtentMetrics( + int itemIndex, + float minScrollExtent = 0.0f, + float maxScrollExtent = 0.0f, + float pixels = 0.0f, + float viewportDimension = 0.0f, + AxisDirection axisDirection = AxisDirection.down + ) : base( + minScrollExtent: minScrollExtent, + maxScrollExtent: maxScrollExtent, + pixels: pixels, + viewportDimension: viewportDimension, + axisDirection: axisDirection + ) { + this.itemIndex = itemIndex; + } + + public int itemIndex { get; set; } + + public FixedExtentMetrics copyWith( + float? minScrollExtent = null, + float? maxScrollExtent = null, + float? pixels = null, + float? viewportDimension = null, + AxisDirection? axisDirection = null, + int? itemIndex = null + ) { + return new FixedExtentMetrics( + minScrollExtent: minScrollExtent ?? this.minScrollExtent, + maxScrollExtent: maxScrollExtent ?? this.maxScrollExtent, + pixels: pixels ?? this.pixels, + viewportDimension: viewportDimension ?? this.viewportDimension, + axisDirection: axisDirection ?? this.axisDirection, + itemIndex: itemIndex ?? this.itemIndex + ); + } + } + + class _FixedExtentScrollPosition : ScrollPositionWithSingleContext, IFixedExtentMetrics { + public _FixedExtentScrollPosition( + ScrollPhysics physics, + ScrollContext context, + int initialItem, + bool keepScrollOffset = true, + ScrollPosition oldPosition = null, + string debugLabel = null + ) : base( + physics: physics, + context: context, + initialPixels: _getItemExtentFromScrollContext(context) * initialItem, + keepScrollOffset: keepScrollOffset, + oldPosition: oldPosition, + debugLabel: debugLabel + ) { + D.assert( + context is _FixedExtentScrollableState, + () => "FixedExtentScrollController can only be used with ListWheelScrollViews" + ); + } + + static float _getItemExtentFromScrollContext(ScrollContext context) { + _FixedExtentScrollableState scrollable = (_FixedExtentScrollableState) context; + return scrollable.itemExtent; + } + + public float itemExtent { + get { return _getItemExtentFromScrollContext(this.context); } + } + + + public int itemIndex { + get { + return ListWheelScrollViewUtils._getItemFromOffset( + offset: this.pixels, + itemExtent: this.itemExtent, + minScrollExtent: this.minScrollExtent, + maxScrollExtent: this.maxScrollExtent + ); + } + set { } + } + + public FixedExtentMetrics copyWith( + float? minScrollExtent = null, + float? maxScrollExtent = null, + float? pixels = null, + float? viewportDimension = null, + AxisDirection? axisDirection = null, + int? itemIndex = null + ) { + return new FixedExtentMetrics( + minScrollExtent: minScrollExtent ?? this.minScrollExtent, + maxScrollExtent: maxScrollExtent ?? this.maxScrollExtent, + pixels: pixels ?? this.pixels, + viewportDimension: viewportDimension ?? this.viewportDimension, + axisDirection: axisDirection ?? this.axisDirection, + itemIndex: itemIndex ?? this.itemIndex + ); + } + } + + class _FixedExtentScrollable : Scrollable { + public _FixedExtentScrollable( + float itemExtent, + ViewportBuilder viewportBuilder, + Key key = null, + AxisDirection axisDirection = AxisDirection.down, + ScrollController controller = null, + ScrollPhysics physics = null + ) : base( + key: key, + axisDirection: axisDirection, + controller: controller, + physics: physics, + viewportBuilder: viewportBuilder + ) { + this.itemExtent = itemExtent; + } + + public readonly float itemExtent; + + public override State createState() { + return new _FixedExtentScrollableState(); + } + } + + class _FixedExtentScrollableState : ScrollableState { + public float itemExtent { + get { + _FixedExtentScrollable actualWidget = (_FixedExtentScrollable) this.widget; + return actualWidget.itemExtent; + } + } + } + + + public class FixedExtentScrollPhysics : ScrollPhysics { + public FixedExtentScrollPhysics( + ScrollPhysics parent = null + ) : base(parent: parent) { } + + public override ScrollPhysics applyTo(ScrollPhysics ancestor) { + return new FixedExtentScrollPhysics(parent: this.buildParent(ancestor)); + } + + public override Simulation createBallisticSimulation(ScrollMetrics position, float velocity) { + D.assert( + position is _FixedExtentScrollPosition, + () => "FixedExtentScrollPhysics can only be used with Scrollables that uses " + + "the FixedExtentScrollController" + ); + + _FixedExtentScrollPosition metrics = (_FixedExtentScrollPosition) position; + + if ((velocity <= 0.0f && metrics.pixels <= metrics.minScrollExtent) || + (velocity >= 0.0f && metrics.pixels >= metrics.maxScrollExtent)) { + return base.createBallisticSimulation(metrics, velocity); + } + + Simulation testFrictionSimulation = + base.createBallisticSimulation(metrics, velocity); + + if (testFrictionSimulation != null + && (testFrictionSimulation.x(float.PositiveInfinity) == metrics.minScrollExtent + || testFrictionSimulation.x(float.PositiveInfinity) == metrics.maxScrollExtent)) { + return base.createBallisticSimulation(metrics, velocity); + } + + int settlingItemIndex = ListWheelScrollViewUtils._getItemFromOffset( + offset: testFrictionSimulation?.x(float.PositiveInfinity) ?? metrics.pixels, + itemExtent: metrics.itemExtent, + minScrollExtent: metrics.minScrollExtent, + maxScrollExtent: metrics.maxScrollExtent + ); + + float settlingPixels = settlingItemIndex * metrics.itemExtent; + + if (velocity.abs() < this.tolerance.velocity + && (settlingPixels - metrics.pixels).abs() < this.tolerance.distance) { + return null; + } + + if (settlingItemIndex == metrics.itemIndex) { + return new SpringSimulation(this.spring, + metrics.pixels, + settlingPixels, + velocity, + tolerance: this.tolerance + ); + } + + return FrictionSimulation.through( + metrics.pixels, + settlingPixels, + velocity, this.tolerance.velocity * velocity.sign() + ); + } + } + + public class ListWheelScrollView : StatefulWidget { + public ListWheelScrollView( + float itemExtent, + List children = null, + Key key = null, + ScrollController controller = null, + ScrollPhysics physics = null, + float diameterRatio = RenderListWheelViewport.defaultDiameterRatio, + float perspective = RenderListWheelViewport.defaultPerspective, + float offAxisFraction = 0.0f, + bool useMagnifier = false, + float magnification = 1.0f, + ValueChanged onSelectedItemChanged = null, + bool clipToSize = true, + bool renderChildrenOutsideViewport = false, + ListWheelChildDelegate childDelegate = null + ) : base(key: key) { + D.assert(children != null || childDelegate != null); + D.assert(diameterRatio > 0.0, () => RenderListWheelViewport.diameterRatioZeroMessage); + D.assert(perspective > 0); + D.assert(perspective <= 0.01f, () => RenderListWheelViewport.perspectiveTooHighMessage); + D.assert(magnification > 0); + D.assert(itemExtent > 0); + D.assert( + !renderChildrenOutsideViewport || !clipToSize, + () => RenderListWheelViewport.clipToSizeAndRenderChildrenOutsideViewportConflict + ); + + this.childDelegate = childDelegate ?? new ListWheelChildListDelegate(children: children); + this.itemExtent = itemExtent; + this.controller = controller; + this.physics = physics; + this.diameterRatio = diameterRatio; + this.perspective = perspective; + this.offAxisFraction = offAxisFraction; + this.useMagnifier = useMagnifier; + this.magnification = magnification; + this.onSelectedItemChanged = onSelectedItemChanged; + this.clipToSize = clipToSize; + this.renderChildrenOutsideViewport = renderChildrenOutsideViewport; + } + + public static ListWheelScrollView useDelegate( + float itemExtent, + List children = null, + ListWheelChildDelegate childDelegate = null, + Key key = null, + ScrollController controller = null, + ScrollPhysics physics = null, + float diameterRatio = RenderListWheelViewport.defaultDiameterRatio, + float perspective = RenderListWheelViewport.defaultPerspective, + float offAxisFraction = 0.0f, + bool useMagnifier = false, + float magnification = 1.0f, + ValueChanged onSelectedItemChanged = null, + bool clipToSize = true, + bool renderChildrenOutsideViewport = false + ) { + return new ListWheelScrollView( + itemExtent: itemExtent, + children: children, + childDelegate: childDelegate, + key: key, + controller: controller, + physics: physics, + diameterRatio: diameterRatio, + perspective: perspective, + offAxisFraction: offAxisFraction, + useMagnifier: useMagnifier, + magnification: magnification, + onSelectedItemChanged: onSelectedItemChanged, + clipToSize: clipToSize, + renderChildrenOutsideViewport: renderChildrenOutsideViewport + ); + } + + public readonly ScrollController controller; + public readonly ScrollPhysics physics; + public readonly float diameterRatio; + public readonly float perspective; + public readonly float offAxisFraction; + public readonly bool useMagnifier; + public readonly float magnification; + public readonly float itemExtent; + public readonly ValueChanged onSelectedItemChanged; + public readonly bool clipToSize; + public readonly bool renderChildrenOutsideViewport; + public readonly ListWheelChildDelegate childDelegate; + + public override State createState() { + return new _ListWheelScrollViewState(); + } + } + + class _ListWheelScrollViewState : State { + int _lastReportedItemIndex = 0; + ScrollController scrollController; + + public override void initState() { + base.initState(); + this.scrollController = this.widget.controller ?? new FixedExtentScrollController(); + if (this.widget.controller is FixedExtentScrollController controller) { + this._lastReportedItemIndex = controller.initialItem; + } + } + + public override void didUpdateWidget(StatefulWidget oldWidget) { + base.didUpdateWidget(oldWidget); + if (this.widget.controller != null && this.widget.controller != this.scrollController) { + ScrollController oldScrollController = this.scrollController; + SchedulerBinding.instance.addPostFrameCallback((_) => { oldScrollController.dispose(); }); + this.scrollController = this.widget.controller; + } + } + + public override Widget build(BuildContext context) { + return new NotificationListener( + onNotification: (ScrollNotification notification) => { + if (notification.depth == 0 + && this.widget.onSelectedItemChanged != null + && notification is ScrollUpdateNotification + && notification.metrics is FixedExtentMetrics metrics) { + int currentItemIndex = metrics.itemIndex; + + if (currentItemIndex != this._lastReportedItemIndex) { + this._lastReportedItemIndex = currentItemIndex; + int trueIndex = this.widget.childDelegate.trueIndexOf(currentItemIndex); + this.widget.onSelectedItemChanged(trueIndex); + } + } + + return false; + }, + child: new _FixedExtentScrollable( + controller: this.scrollController, + physics: this.widget.physics, + itemExtent: this.widget.itemExtent, + viewportBuilder: (BuildContext _context, ViewportOffset _offset) => { + return new ListWheelViewport( + diameterRatio: this.widget.diameterRatio, + perspective: this.widget.perspective, + offAxisFraction: this.widget.offAxisFraction, + useMagnifier: this.widget.useMagnifier, + magnification: this.widget.magnification, + itemExtent: this.widget.itemExtent, + clipToSize: this.widget.clipToSize, + renderChildrenOutsideViewport: this.widget.renderChildrenOutsideViewport, + offset: _offset, + childDelegate: this.widget.childDelegate + ); + } + ) + ); + } + } + + public class ListWheelElement : RenderObjectElement, IListWheelChildManager { + public ListWheelElement(ListWheelViewport widget) : base(widget) { } + + public new ListWheelViewport widget { + get { return (ListWheelViewport) base.widget; } + } + + public new RenderListWheelViewport renderObject { + get { return (RenderListWheelViewport) base.renderObject; } + } + + + readonly Dictionary _childWidgets = new Dictionary(); + + readonly SplayTree _childElements = new SplayTree(); + + public override void update(Widget newWidget) { + ListWheelViewport oldWidget = this.widget; + base.update(newWidget); + ListWheelChildDelegate newDelegate = ((ListWheelViewport) newWidget).childDelegate; + ListWheelChildDelegate oldDelegate = oldWidget.childDelegate; + if (newDelegate != oldDelegate && + (newDelegate.GetType() != oldDelegate.GetType() || newDelegate.shouldRebuild(oldDelegate))) { + this.performRebuild(); + } + } + + public int? childCount { + get { return this.widget.childDelegate.estimatedChildCount; } + } + + protected override void performRebuild() { + this._childWidgets.Clear(); + base.performRebuild(); + if (this._childElements.isEmpty()) { + return; + } + + int firstIndex = this._childElements.First()?.Key ?? 0; + int lastIndex = this._childElements.Last()?.Key ?? 0; + + for (int index = firstIndex; index <= lastIndex; ++index) { + Element newChild = this.updateChild(this._childElements[index], this.retrieveWidget(index), index); + if (newChild != null) { + this._childElements[index] = newChild; + } + else { + this._childElements.Remove(index); + } + } + } + + Widget retrieveWidget(int index) { + return this._childWidgets.putIfAbsent(index, + () => { return this.widget.childDelegate.build(this, index); }); + } + + public bool childExistsAt(int index) { + return this.retrieveWidget(index) != null; + } + + public void createChild(int index, RenderBox after) { + this.owner.buildScope(this, () => { + bool insertFirst = after == null; + D.assert(insertFirst || this._childElements[index - 1] != null); + // Debug.Log($"{index}: {this._childElements.getOrDefault(index)}"); + + Element newChild = this.updateChild(this._childElements.getOrDefault(index), this.retrieveWidget(index), + index); + + // Debug.Log(newChild); + if (newChild != null) { + this._childElements[index] = newChild; + } + else { + this._childElements.Remove(index); + } + }); + } + + public void removeChild(RenderBox child) { + int index = this.renderObject.indexOf(child); + this.owner.buildScope(this, () => { + D.assert(this._childElements.ContainsKey(index)); + Element result = this.updateChild(this._childElements[index], null, index); + D.assert(result == null); + this._childElements.Remove(index); + D.assert(!this._childElements.ContainsKey(index)); + }); + } + + protected override Element updateChild(Element child, Widget newWidget, object newSlot) { + ListWheelParentData oldParentData = (ListWheelParentData) child?.renderObject?.parentData; + Element newChild = base.updateChild(child, newWidget, newSlot); + ListWheelParentData newParentData = (ListWheelParentData) newChild?.renderObject?.parentData; + if (newParentData != null) { + newParentData.index = (int) newSlot; + if (oldParentData != null) { + newParentData.offset = oldParentData.offset; + } + } + + return newChild; + } + + protected override void insertChildRenderObject(RenderObject child, object slot) { + RenderListWheelViewport renderObject = this.renderObject; + D.assert(renderObject.debugValidateChild(child)); + + renderObject.insert((RenderBox) child, + (RenderBox) this._childElements.getOrDefault((int) slot - 1)?.renderObject); + // Debug.Log($"insert: {this._childElements.getOrDefault((int) slot - 1)}"); + + + D.assert(renderObject == this.renderObject); + } + + protected override void moveChildRenderObject(RenderObject child, dynamic slot) { + const string moveChildRenderObjectErrorMessage = + "Currently we maintain the list in contiguous increasing order, so " + + "moving children around is not allowed."; + D.assert(false, () => moveChildRenderObjectErrorMessage); + } + + protected override void removeChildRenderObject(RenderObject child) { + D.assert(child.parent == this.renderObject); + this.renderObject.remove((RenderBox) child); + } + + public override void visitChildren(ElementVisitor visitor) { + foreach (var item in this._childElements) { + visitor(item.Value); + } + } + + protected override void forgetChild(Element child) { + this._childElements.Remove((int) (child.slot)); + } + } + + public class ListWheelViewport : RenderObjectWidget { + public ListWheelViewport( + float itemExtent, + ViewportOffset offset, + ListWheelChildDelegate childDelegate, + Key key = null, + float diameterRatio = RenderListWheelViewport.defaultDiameterRatio, + float perspective = RenderListWheelViewport.defaultPerspective, + float offAxisFraction = 0.0f, + bool useMagnifier = false, + float magnification = 1.0f, + bool clipToSize = true, + bool renderChildrenOutsideViewport = false + ) : base(key: key) { + D.assert(childDelegate != null); + D.assert(offset != null); + D.assert(diameterRatio > 0, () => RenderListWheelViewport.diameterRatioZeroMessage); + D.assert(perspective > 0); + D.assert(perspective <= 0.01, () => RenderListWheelViewport.perspectiveTooHighMessage); + D.assert(itemExtent > 0); + D.assert( + !renderChildrenOutsideViewport || !clipToSize, + () => RenderListWheelViewport.clipToSizeAndRenderChildrenOutsideViewportConflict + ); + + this.itemExtent = itemExtent; + this.offset = offset; + this.childDelegate = childDelegate; + this.diameterRatio = diameterRatio; + this.perspective = perspective; + this.offAxisFraction = offAxisFraction; + this.useMagnifier = useMagnifier; + this.magnification = magnification; + this.clipToSize = clipToSize; + this.renderChildrenOutsideViewport = renderChildrenOutsideViewport; + } + + public readonly float diameterRatio; + public readonly float perspective; + public readonly float offAxisFraction; + public readonly bool useMagnifier; + public readonly float magnification; + public readonly float itemExtent; + public readonly bool clipToSize; + public readonly bool renderChildrenOutsideViewport; + public readonly ViewportOffset offset; + public readonly ListWheelChildDelegate childDelegate; + + public override Element createElement() { + return new ListWheelElement(this); + } + + public override RenderObject createRenderObject(BuildContext context) { + ListWheelElement childManager = (ListWheelElement) context; + return new RenderListWheelViewport( + childManager: childManager, + offset: this.offset, + diameterRatio: this.diameterRatio, + perspective: this.perspective, + offAxisFraction: this.offAxisFraction, + useMagnifier: this.useMagnifier, + magnification: this.magnification, + itemExtent: this.itemExtent, + clipToSize: this.clipToSize, + renderChildrenOutsideViewport: this.renderChildrenOutsideViewport + ); + } + + public override void updateRenderObject(BuildContext context, RenderObject renderObject) { + var viewport = (RenderListWheelViewport) renderObject; + viewport.offset = this.offset; + viewport.diameterRatio = this.diameterRatio; + viewport.perspective = this.perspective; + viewport.offAxisFraction = this.offAxisFraction; + viewport.useMagnifier = this.useMagnifier; + viewport.magnification = this.magnification; + viewport.itemExtent = this.itemExtent; + viewport.clipToSize = this.clipToSize; + viewport.renderChildrenOutsideViewport = this.renderChildrenOutsideViewport; + } + } +} \ No newline at end of file diff --git a/Runtime/widgets/list_wheel_scroll_view.cs.meta b/Runtime/widgets/list_wheel_scroll_view.cs.meta new file mode 100644 index 00000000..51e1b45b --- /dev/null +++ b/Runtime/widgets/list_wheel_scroll_view.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5f33e2b8a13bf4308b91f226530921e3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/widgets/nested_scroll_view.cs b/Runtime/widgets/nested_scroll_view.cs index 337b9b33..d4876463 100644 --- a/Runtime/widgets/nested_scroll_view.cs +++ b/Runtime/widgets/nested_scroll_view.cs @@ -25,7 +25,7 @@ public NestedScrollView( ScrollPhysics physics = null, NestedScrollViewHeaderSliversBuilder headerSliverBuilder = null, Widget body = null, - DragStartBehavior dragStartBehavior = DragStartBehavior.down + DragStartBehavior dragStartBehavior = DragStartBehavior.start ) : base(key: key) { D.assert(headerSliverBuilder != null); D.assert(body != null); @@ -157,7 +157,7 @@ public _NestedScrollViewCustomScrollView( ScrollController controller, List slivers, SliverOverlapAbsorberHandle handle, - DragStartBehavior dragStartBehavior = DragStartBehavior.down + DragStartBehavior dragStartBehavior = DragStartBehavior.start ) : base( scrollDirection: scrollDirection, reverse: reverse, diff --git a/Runtime/widgets/orientation_builder.cs b/Runtime/widgets/orientation_builder.cs new file mode 100644 index 00000000..0839da1e --- /dev/null +++ b/Runtime/widgets/orientation_builder.cs @@ -0,0 +1,28 @@ +using Unity.UIWidgets.foundation; +using Unity.UIWidgets.rendering; + +namespace Unity.UIWidgets.widgets { + public delegate Widget OrientationWidgetBuilder(BuildContext context, Orientation orientation); + + public class OrientationBuilder : StatelessWidget { + public OrientationBuilder( + OrientationWidgetBuilder builder, + Key key = null + ) : base(key: key) { + D.assert(builder != null); + this.builder = builder; + } + + public readonly OrientationWidgetBuilder builder; + + Widget _buildWithConstraints(BuildContext context, BoxConstraints constraints) { + Orientation orientation = + constraints.maxWidth > constraints.maxHeight ? Orientation.landscape : Orientation.portrait; + return this.builder(context, orientation); + } + + public override Widget build(BuildContext context) { + return new LayoutBuilder(builder: this._buildWithConstraints); + } + } +} \ No newline at end of file diff --git a/Runtime/widgets/orientation_builder.cs.meta b/Runtime/widgets/orientation_builder.cs.meta new file mode 100644 index 00000000..efe43680 --- /dev/null +++ b/Runtime/widgets/orientation_builder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 838b65ef835974b40a5b9d2974e2cb0d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/widgets/overlay.cs b/Runtime/widgets/overlay.cs index 734c83a4..ae2fd0c6 100644 --- a/Runtime/widgets/overlay.cs +++ b/Runtime/widgets/overlay.cs @@ -139,18 +139,41 @@ public override void initState() { this.insertAll(this.widget.initialEntries); } - public void insert(OverlayEntry entry, OverlayEntry above = null) { - D.assert(entry._overlay == null); - D.assert(above == null || (above._overlay == this && this._entries.Contains(above))); - entry._overlay = this; - this.setState(() => { - int index = above == null ? this._entries.Count : this._entries.IndexOf(above) + 1; - this._entries.Insert(index, entry); - }); + internal int _insertionIndex(OverlayEntry below, OverlayEntry above) { + D.assert(below == null || above == null); + if (below != null) { + return this._entries.IndexOf(below); + } + + if (above != null) { + return this._entries.IndexOf(above) + 1; + } + + return this._entries.Count; } - public void insertAll(ICollection entries, OverlayEntry above = null) { - D.assert(above == null || (above._overlay == this && this._entries.Contains(above))); + public void insert(OverlayEntry entry, OverlayEntry below = null, OverlayEntry above = null) { + D.assert(above == null || below == null, () => "Only one of `above` and `below` may be specified."); + D.assert(above == null || (above._overlay == this && this._entries.Contains(above)), + () => "The provided entry for `above` is not present in the Overlay."); + D.assert(below == null || (below._overlay == this && this._entries.Contains(below)), + () => "The provided entry for `below` is not present in the Overlay."); + D.assert(!this._entries.Contains(entry), () => "The specified entry is already present in the Overlay."); + D.assert(entry._overlay == null, () => "The specified entry is already present in another Overlay."); + entry._overlay = this; + this.setState(() => { this._entries.Insert(this._insertionIndex(below, above), entry); }); + } + + public void insertAll(ICollection entries, OverlayEntry below = null, OverlayEntry above = null) { + D.assert(above == null || below == null, () => "Only one of `above` and `below` may be specified."); + D.assert(above == null || (above._overlay == this && this._entries.Contains(above)), + () => "The provided entry for `above` is not present in the Overlay."); + D.assert(below == null || (below._overlay == this && this._entries.Contains(below)), + () => "The provided entry for `below` is not present in the Overlay."); + D.assert(entries.All(entry => !this._entries.Contains(entry)), + () => "One or more of the specified entries are already present in the Overlay."); + D.assert(entries.All(entry => entry._overlay == null), + () => "One or more of the specified entries are already present in another Overlay."); if (entries.isEmpty()) { return; } @@ -161,16 +184,48 @@ public void insertAll(ICollection entries, OverlayEntry above = nu } this.setState(() => { - int index = above == null ? this._entries.Count : this._entries.IndexOf(above) + 1; - this._entries.InsertRange(index, entries); + this._entries.InsertRange(this._insertionIndex(below, above), entries); + }); + } + + public void rearrange(IEnumerable newEntries, OverlayEntry below = null, OverlayEntry above = null) { + List newEntriesList = + newEntries is List ?(newEntries as List) : newEntries.ToList(); + D.assert(above == null || below == null, () => "Only one of `above` and `below` may be specified."); + D.assert(above == null || (above._overlay == this && this._entries.Contains(above)), + () => "The provided entry for `above` is not present in the Overlay."); + D.assert(below == null || (below._overlay == this && this._entries.Contains(below)), + () => "The provided entry for `below` is not present in the Overlay."); + D.assert(newEntriesList.All(entry => !this._entries.Contains(entry)), + () => "One or more of the specified entries are already present in the Overlay."); + D.assert(newEntriesList.All(entry => entry._overlay == null), + () => "One or more of the specified entries are already present in another Overlay."); + if (newEntriesList.isEmpty()) { + return; + } + + if (this._entries.SequenceEqual(newEntriesList)) { + return; + } + + HashSet old = new HashSet(this._entries); + foreach(OverlayEntry entry in newEntriesList) { + entry._overlay = entry._overlay ?? this; + } + this.setState(() => { + this._entries.Clear(); + this._entries.AddRange(newEntriesList); + foreach (OverlayEntry entry in newEntriesList) { + old.Remove(entry); + } + + this._entries.InsertRange(this._insertionIndex(below, above), old); }); } internal void _remove(OverlayEntry entry) { if (this.mounted) { - this.setState(() => { - this._entries.Remove(entry); - }); + this.setState(() => { this._entries.Remove(entry); }); } } diff --git a/Runtime/widgets/page_view.cs b/Runtime/widgets/page_view.cs index 34b25f06..10d11ab1 100644 --- a/Runtime/widgets/page_view.cs +++ b/Runtime/widgets/page_view.cs @@ -30,14 +30,14 @@ public PageController( public readonly float viewportFraction; - public float page { + public virtual float page { get { D.assert(this.positions.isNotEmpty(), () => "PageController.page cannot be accessed before a PageView is built with it." ); D.assert(this.positions.Count == 1, () => "The page property cannot be read when multiple PageViews are attached to " + - "the same PageController." + "the same PageController." ); _PagePosition position = (_PagePosition) this.position; return position.page; @@ -215,8 +215,7 @@ public override bool applyViewportDimension(float viewportDimension) { } public class PageScrollPhysics : ScrollPhysics { - public PageScrollPhysics(ScrollPhysics parent = null) : base(parent: parent) { - } + public PageScrollPhysics(ScrollPhysics parent = null) : base(parent: parent) { } public override ScrollPhysics applyTo(ScrollPhysics ancestor) { return new PageScrollPhysics(parent: this.buildParent(ancestor)); @@ -286,7 +285,7 @@ public PageView( bool pageSnapping = true, ValueChanged onPageChanged = null, List children = null, - DragStartBehavior dragStartBehavior = DragStartBehavior.down, + DragStartBehavior dragStartBehavior = DragStartBehavior.start, IndexedWidgetBuilder itemBuilder = null, SliverChildDelegate childDelegate = null, int itemCount = 0 @@ -308,6 +307,34 @@ public PageView( this.childrenDelegate = new SliverChildListDelegate(children ?? new List()); } } + + public static PageView builder( + IndexedWidgetBuilder itemBuilder, + Key key = null, + Axis scrollDirection = Axis.horizontal, + bool reverse = false, + PageController controller = null, + ScrollPhysics physics = null, + bool pageSnapping = true, + ValueChanged onPageChanged = null, + int itemCount = 0, + DragStartBehavior dragStartBehavior = DragStartBehavior.start + ) { + return new PageView( + itemBuilder: itemBuilder, + key: key, + scrollDirection: scrollDirection, + reverse: reverse, + controller: controller, + physics: physics, + pageSnapping: pageSnapping, + onPageChanged: onPageChanged, + itemCount: itemCount, + dragStartBehavior: dragStartBehavior + ); + } + + // TODO: PageView.custom public readonly Axis scrollDirection; diff --git a/Runtime/widgets/pages.cs b/Runtime/widgets/pages.cs index faab8093..ee314532 100644 --- a/Runtime/widgets/pages.cs +++ b/Runtime/widgets/pages.cs @@ -7,6 +7,8 @@ namespace Unity.UIWidgets.widgets { public abstract class PageRoute : ModalRoute { public readonly bool fullscreenDialog; + public PageRoute() {} + public PageRoute(RouteSettings settings, bool fullscreenDialog = false) : base(settings) { this.fullscreenDialog = fullscreenDialog; } diff --git a/Runtime/widgets/routes.cs b/Runtime/widgets/routes.cs index f9c35dab..035bb042 100644 --- a/Runtime/widgets/routes.cs +++ b/Runtime/widgets/routes.cs @@ -28,7 +28,7 @@ protected virtual bool finishedWhenPopped { protected internal override void install(OverlayEntry insertionPoint) { D.assert(this._overlayEntries.isEmpty()); this._overlayEntries.AddRange(this.createOverlayEntries()); - this.navigator.overlay?.insertAll(this._overlayEntries, insertionPoint); + this.navigator.overlay?.insertAll(this._overlayEntries, above: insertionPoint); base.install(insertionPoint); } @@ -122,11 +122,11 @@ internal void _handleStatusChanged(AnimationStatus status) { break; case AnimationStatus.dismissed: - // We might still be the current route if a subclass is controlling the + // We might still be an active route if a subclass is controlling the // the transition and hits the dismissed status. For example, the iOS // back gesture drives this animation to the dismissed status before // popping the navigator. - if (!this.isCurrent) { + if (!this.isActive) { this.navigator.finalizeRoute(this); D.assert(this.overlayEntries.isEmpty()); } @@ -471,8 +471,9 @@ public override Widget build(BuildContext context) { } public abstract class ModalRoute : LocalHistoryRouteTransitionRoute { - protected ModalRoute(RouteSettings settings) : base(settings) { - } + + protected ModalRoute() {} + protected ModalRoute(RouteSettings settings) : base(settings) { } public static Color _kTransparent = new Color(0x00000000); @@ -605,7 +606,7 @@ public void removeScopedWillPopCallback(WillPopCallback callback) { this._willPopCallbacks.Remove(callback); } - protected bool hasScopedWillPopCallback { + public bool hasScopedWillPopCallback { get { return this._willPopCallbacks.isNotEmpty(); } } diff --git a/Runtime/widgets/scroll_metrics.cs b/Runtime/widgets/scroll_metrics.cs index 32cffc28..861a20b7 100644 --- a/Runtime/widgets/scroll_metrics.cs +++ b/Runtime/widgets/scroll_metrics.cs @@ -35,6 +35,17 @@ public static ScrollMetrics copyWith(ScrollMetrics it, ); } + if (it is IFixedExtentMetrics) { + return new FixedExtentMetrics( + minScrollExtent: minScrollExtent ?? it.minScrollExtent, + maxScrollExtent: maxScrollExtent ?? it.maxScrollExtent, + pixels: pixels ?? it.pixels, + viewportDimension: viewportDimension ?? it.viewportDimension, + axisDirection: axisDirection ?? it.axisDirection, + itemIndex: ((IFixedExtentMetrics) it).itemIndex + ); + } + return new FixedScrollMetrics( minScrollExtent: minScrollExtent ?? it.minScrollExtent, maxScrollExtent: maxScrollExtent ?? it.maxScrollExtent, diff --git a/Runtime/widgets/scroll_physics.cs b/Runtime/widgets/scroll_physics.cs index 9036fe54..42dfe0e9 100644 --- a/Runtime/widgets/scroll_physics.cs +++ b/Runtime/widgets/scroll_physics.cs @@ -73,10 +73,9 @@ public virtual SpringDescription spring { } } - // todo: Handle the case of the device pixel ratio changing. use 1 as devicePixelRatio for now. static readonly Tolerance _kDefaultTolerance = new Tolerance( - velocity: 1.0f / (0.050f * 1), - distance: 1.0f / 1 + velocity: 1.0f / (0.050f * Window.instance.devicePixelRatio), + distance: 1.0f / Window.instance.devicePixelRatio ); public virtual Tolerance tolerance { diff --git a/Runtime/widgets/scroll_position.cs b/Runtime/widgets/scroll_position.cs index bcd23fa7..4503be87 100644 --- a/Runtime/widgets/scroll_position.cs +++ b/Runtime/widgets/scroll_position.cs @@ -61,6 +61,14 @@ public float maxScrollExtent { float? _maxScrollExtent; + public bool hasMinScrollExtent { + get { return this._minScrollExtent != null; } + } + + public bool hasMaxScrollExtent { + get { return this._maxScrollExtent != null; } + } + public override float pixels { get { D.assert(this._pixels != null); diff --git a/Runtime/widgets/scroll_view.cs b/Runtime/widgets/scroll_view.cs index d7f53afb..3e90151f 100644 --- a/Runtime/widgets/scroll_view.cs +++ b/Runtime/widgets/scroll_view.cs @@ -19,7 +19,7 @@ protected ScrollView( Key center = null, float anchor = 0.0f, float? cacheExtent = null, - DragStartBehavior dragStartBehavior = DragStartBehavior.down + DragStartBehavior dragStartBehavior = DragStartBehavior.start ) : base(key: key) { D.assert(!(controller != null && primary == true), () => "Primary ScrollViews obtain their ScrollController via inheritance from a PrimaryScrollController widget. " + @@ -131,7 +131,7 @@ public CustomScrollView( float anchor = 0.0f, float? cacheExtent = null, List slivers = null, - DragStartBehavior dragStartBehavior = DragStartBehavior.down + DragStartBehavior dragStartBehavior = DragStartBehavior.start ) : base( key: key, scrollDirection: scrollDirection, @@ -166,7 +166,7 @@ public BoxScrollView( bool shrinkWrap = false, EdgeInsets padding = null, float? cacheExtent = null, - DragStartBehavior dragStartBehavior = DragStartBehavior.down + DragStartBehavior dragStartBehavior = DragStartBehavior.start ) : base( key: key, scrollDirection: scrollDirection, @@ -218,7 +218,7 @@ public ListView( bool addRepaintBoundaries = true, float? cacheExtent = null, List children = null, - DragStartBehavior dragStartBehavior = DragStartBehavior.down + DragStartBehavior dragStartBehavior = DragStartBehavior.start ) : base( key: key, scrollDirection: scrollDirection, @@ -254,7 +254,7 @@ public ListView( bool addAutomaticKeepAlives = true, bool addRepaintBoundaries = true, float? cacheExtent = null, - DragStartBehavior dragStartBehavior = DragStartBehavior.down + DragStartBehavior dragStartBehavior = DragStartBehavior.start ) : base(key: key, scrollDirection: scrollDirection, reverse: reverse, @@ -290,7 +290,7 @@ public static ListView builder( bool addAutomaticKeepAlives = true, bool addRepaintBoundaries = true, float? cacheExtent = null, - DragStartBehavior dragStartBehavior = DragStartBehavior.down + DragStartBehavior dragStartBehavior = DragStartBehavior.start ) { return new ListView( key: key, @@ -327,7 +327,7 @@ public static ListView builder( bool addAutomaticKeepAlives = true, bool addRepaintBoundaries = true, float? cacheExtent = null, - DragStartBehavior dragStartBehavior = DragStartBehavior.down + DragStartBehavior dragStartBehavior = DragStartBehavior.start ) : base( key: key, scrollDirection: scrollDirection, @@ -583,7 +583,7 @@ public GridView( SliverGridDelegate gridDelegate = null, SliverChildDelegate childrenDelegate = null, float? cacheExtent = null, - DragStartBehavior dragStartBehavior = DragStartBehavior.down + DragStartBehavior dragStartBehavior = DragStartBehavior.start ) : base( key: key, scrollDirection: scrollDirection, @@ -614,7 +614,7 @@ public static GridView custom( SliverGridDelegate gridDelegate = null, SliverChildDelegate childrenDelegate = null, float? cacheExtent = null, - DragStartBehavior dragStartBehavior = DragStartBehavior.down + DragStartBehavior dragStartBehavior = DragStartBehavior.start ) { return new GridView( key: key, @@ -649,7 +649,7 @@ public GridView( bool addRepaintBoundaries = true, float? cacheExtent = null, List children = null, - DragStartBehavior dragStartBehavior = DragStartBehavior.down + DragStartBehavior dragStartBehavior = DragStartBehavior.start ) : base( key: key, scrollDirection: scrollDirection, @@ -692,7 +692,7 @@ public static GridView count( bool addRepaintBoundaries = true, float? cacheExtent = null, List children = null, - DragStartBehavior dragStartBehavior = DragStartBehavior.down + DragStartBehavior dragStartBehavior = DragStartBehavior.start ) { return new GridView( key: key, @@ -732,7 +732,7 @@ public GridView( bool addRepaintBoundaries = true, bool addSemanticIndexes = true, List children = null, - DragStartBehavior dragStartBehavior = DragStartBehavior.down + DragStartBehavior dragStartBehavior = DragStartBehavior.start ) : base( key: key, scrollDirection: scrollDirection, @@ -773,7 +773,7 @@ public static GridView extent( bool addAutomaticKeepAlives = true, bool addRepaintBoundaries = true, List children = null, - DragStartBehavior dragStartBehavior = DragStartBehavior.down + DragStartBehavior dragStartBehavior = DragStartBehavior.start ) { return new GridView( key: key, diff --git a/Runtime/widgets/scrollable.cs b/Runtime/widgets/scrollable.cs index 424f54c3..351eb7ae 100644 --- a/Runtime/widgets/scrollable.cs +++ b/Runtime/widgets/scrollable.cs @@ -9,6 +9,7 @@ using Unity.UIWidgets.rendering; using Unity.UIWidgets.scheduler; using Unity.UIWidgets.ui; +using UnityEngine; namespace Unity.UIWidgets.widgets { public delegate Widget ViewportBuilder(BuildContext context, ViewportOffset position); @@ -20,7 +21,7 @@ public Scrollable( ScrollController controller = null, ScrollPhysics physics = null, ViewportBuilder viewportBuilder = null, - DragStartBehavior dragStartBehavior = DragStartBehavior.down + DragStartBehavior dragStartBehavior = DragStartBehavior.start ) : base(key: key) { D.assert(viewportBuilder != null); @@ -360,6 +361,29 @@ void _handleDragCancel() { D.assert(this._hold == null); D.assert(this._drag == null); } + + float _targetScrollOffsetForPointerScroll(PointerScrollEvent e) { + float delta = this.widget.axis == Axis.horizontal ? e.delta.dx : e.delta.dy; + return Mathf.Min(Mathf.Max(this.position.pixels + delta, this.position.minScrollExtent), + this.position.maxScrollExtent); + } + + void _receivedPointerSignal(PointerSignalEvent e) { + if (e is PointerScrollEvent && this.position != null) { + float targetScrollOffset = this._targetScrollOffsetForPointerScroll(e as PointerScrollEvent); + if (targetScrollOffset != this.position.pixels) { + GestureBinding.instance.pointerSignalResolver.register(e, this._handlePointerScroll); + } + } + } + + void _handlePointerScroll(PointerEvent e) { + D.assert(e is PointerScrollEvent); + float targetScrollOffset = this._targetScrollOffsetForPointerScroll(e as PointerScrollEvent); + if (targetScrollOffset != this.position.pixels) { + this.position.jumpTo(targetScrollOffset); + } + } void _disposeHold() { this._hold = null; @@ -375,14 +399,17 @@ public override Widget build(BuildContext context) { Widget result = new _ScrollableScope( scrollable: this, position: this.position, - child: new RawGestureDetector( - key: this._gestureDetectorKey, - gestures: this._gestureRecognizers, - behavior: HitTestBehavior.opaque, - child: new IgnorePointer( - key: this._ignorePointerKey, - ignoring: this._shouldIgnorePointer, - child: this.widget.viewportBuilder(context, this.position) + child: new Listener( + onPointerSignal: this._receivedPointerSignal, + child: new RawGestureDetector( + key: this._gestureDetectorKey, + gestures: this._gestureRecognizers, + behavior: HitTestBehavior.opaque, + child: new IgnorePointer( + key: this._ignorePointerKey, + ignoring: this._shouldIgnorePointer, + child: this.widget.viewportBuilder(context, this.position) + ) ) ) ); diff --git a/Runtime/widgets/selectable_text.cs b/Runtime/widgets/selectable_text.cs index 53f5a71a..1107325d 100644 --- a/Runtime/widgets/selectable_text.cs +++ b/Runtime/widgets/selectable_text.cs @@ -8,6 +8,7 @@ using Unity.UIWidgets.painting; using Unity.UIWidgets.rendering; using Unity.UIWidgets.ui; +using Color = Unity.UIWidgets.ui.Color; using Constants = Unity.UIWidgets.gestures.Constants; using TextStyle = Unity.UIWidgets.painting.TextStyle; @@ -22,7 +23,10 @@ public SelectableText(string data, float? textScaleFactor = null, int? maxLines = null, FocusNode focusNode = null, - Color selectionColor = null) : base(key) { + Color selectionColor = null, + GestureTapDownCallback onTapDown = null, + GestureTapUpCallback onTapUp = null, + GestureTapCancelCallback onTapCancel = null) : base(key) { D.assert(data != null); this.textSpan = null; this.data = data; @@ -34,6 +38,9 @@ public SelectableText(string data, this.maxLines = maxLines; this.focusNode = focusNode ?? new FocusNode(); this.selectionColor = selectionColor; + this.onTapDown = onTapDown; + this.onTapUp = onTapUp; + this.onTapCancel = onTapCancel; } public SelectableText(TextSpan textSpan, @@ -45,7 +52,10 @@ public SelectableText(TextSpan textSpan, float? textScaleFactor = null, int? maxLines = null, FocusNode focusNode = null, - Color selectionColor = null) : base(key) { + Color selectionColor = null, + GestureTapDownCallback onTapDown = null, + GestureTapUpCallback onTapUp = null, + GestureTapCancelCallback onTapCancel = null) : base(key) { D.assert(textSpan != null); this.textSpan = textSpan; this.data = null; @@ -57,6 +67,9 @@ public SelectableText(TextSpan textSpan, this.maxLines = maxLines; this.focusNode = focusNode ?? new FocusNode(); this.selectionColor = selectionColor; + this.onTapDown = onTapDown; + this.onTapUp = onTapUp; + this.onTapCancel = onTapCancel; } public static SelectableText rich(TextSpan textSpan, @@ -68,7 +81,10 @@ public static SelectableText rich(TextSpan textSpan, float? textScaleFactor = null, int? maxLines = null, FocusNode focusNode = null, - Color selectionColor = null) { + Color selectionColor = null, + GestureTapDownCallback onTapDown = null, + GestureTapUpCallback onTapUp = null, + GestureTapCancelCallback onTapCancel = null) { return new SelectableText( textSpan, key, style, @@ -78,7 +94,10 @@ public static SelectableText rich(TextSpan textSpan, textScaleFactor, maxLines, focusNode, - selectionColor); + selectionColor, + onTapDown, + onTapUp, + onTapCancel); } public readonly string data; @@ -101,6 +120,12 @@ public static SelectableText rich(TextSpan textSpan, public readonly Color selectionColor; + public readonly GestureTapDownCallback onTapDown; + + public readonly GestureTapUpCallback onTapUp; + + public readonly GestureTapCancelCallback onTapCancel; + public override State createState() { return new _SelectableTextState(); } @@ -172,12 +197,15 @@ public IPromise didPushRoute(string route) { } void _handleTapDown(TapDownDetails details) { + this.widget.onTapDown?.Invoke(details); } void _handleSingleTapUp(TapUpDetails details) { + this.widget.onTapUp?.Invoke(details); } void _handleSingleTapCancel() { + this.widget.onTapCancel?.Invoke(); } void _handleLongPress() { diff --git a/Runtime/widgets/single_child_scroll_view.cs b/Runtime/widgets/single_child_scroll_view.cs index ca60d4d5..14cb693a 100644 --- a/Runtime/widgets/single_child_scroll_view.cs +++ b/Runtime/widgets/single_child_scroll_view.cs @@ -19,7 +19,7 @@ public SingleChildScrollView( ScrollPhysics physics = null, ScrollController controller = null, Widget child = null, - DragStartBehavior dragStartBehavior = DragStartBehavior.down + DragStartBehavior dragStartBehavior = DragStartBehavior.start ) : base(key: key) { D.assert(!(controller != null && primary == true), () => "Primary ScrollViews obtain their ScrollController via inheritance from a PrimaryScrollController widget. " + @@ -296,7 +296,7 @@ protected override float computeMinIntrinsicHeight(float width) { return 0.0f; } - protected override float computeMaxIntrinsicHeight(float width) { + protected internal override float computeMaxIntrinsicHeight(float width) { if (this.child != null) { return this.child.getMaxIntrinsicHeight(width); } diff --git a/Runtime/widgets/sliver.cs b/Runtime/widgets/sliver.cs index a2a8257b..6e8970ce 100644 --- a/Runtime/widgets/sliver.cs +++ b/Runtime/widgets/sliver.cs @@ -5,6 +5,7 @@ using Unity.UIWidgets.foundation; using Unity.UIWidgets.painting; using Unity.UIWidgets.rendering; +using Unity.UIWidgets.external; using Unity.UIWidgets.ui; namespace Unity.UIWidgets.widgets { @@ -355,29 +356,27 @@ protected override void performRebuild() { this._currentBeforeChild = null; D.assert(this._currentlyUpdatingChildIndex == null); try { - int firstIndex = 0; - int lastIndex = 0; - - if (!this._childElements.isEmpty()) { - firstIndex = this._childElements.First().Key; - lastIndex = this._childElements.Last().Key; - if (this._didUnderflow) { - lastIndex += 1; - } - } - - for (int index = firstIndex; index <= lastIndex; ++index) { + void processElement(int index) { this._currentlyUpdatingChildIndex = index; Element newChild = this.updateChild(this._childElements.getOrDefault(index), this._build(index), index); if (newChild != null) { this._childElements[index] = newChild; - this._currentBeforeChild = (RenderBox) newChild.renderObject; + var parentData = (SliverMultiBoxAdaptorParentData) newChild.renderObject.parentData; + if (!parentData.keptAlive) { + this._currentBeforeChild = (RenderBox) newChild.renderObject; + } } else { this._childElements.Remove(index); } } + // processElement may modify the Map - need to do a .toList() here. + this._childElements.Keys.ToList().ForEach(action: processElement); + if (this._didUnderflow) { + var lastKey = this._childElements?.Last()?.Key ?? -1; + processElement(lastKey + 1); + } } finally { this._currentlyUpdatingChildIndex = null; @@ -588,7 +587,7 @@ public override void debugVisitOnstageChildren(ElementVisitor visitor) { } } - class SliverFillRemaining : SingleChildRenderObjectWidget { + public class SliverFillRemaining : SingleChildRenderObjectWidget { public SliverFillRemaining( Key key = null, Widget child = null @@ -633,4 +632,4 @@ public override void debugFillProperties(DiagnosticPropertiesBuilder properties) properties.add(new DiagnosticsProperty("keepAlive", this.keepAlive)); } } -} \ No newline at end of file +} diff --git a/Runtime/widgets/text.cs b/Runtime/widgets/text.cs index a842e611..fc3f46c4 100644 --- a/Runtime/widgets/text.cs +++ b/Runtime/widgets/text.cs @@ -106,15 +106,17 @@ public class Text : StatelessWidget { public Text(string data, Key key = null, TextStyle style = null, + StrutStyle strutStyle = null, TextAlign? textAlign = null, bool? softWrap = null, TextOverflow? overflow = null, float? textScaleFactor = null, int? maxLines = null) : base(key) { - D.assert(data != null); + D.assert(data != null, () => "A non-null string must be provided to a Text widget."); this.textSpan = null; this.data = data; this.style = style; + this.strutStyle = strutStyle; this.textAlign = textAlign; this.softWrap = softWrap; this.overflow = overflow; @@ -125,15 +127,17 @@ public Text(string data, Text(TextSpan textSpan, Key key = null, TextStyle style = null, + StrutStyle strutStyle = null, TextAlign? textAlign = null, bool? softWrap = null, TextOverflow? overflow = null, float? textScaleFactor = null, int? maxLines = null) : base(key) { - D.assert(textSpan != null); + D.assert(textSpan != null, () => "A non-null TextSpan must be provided to a Text.rich widget."); this.textSpan = textSpan; this.data = null; this.style = style; + this.strutStyle = strutStyle; this.textAlign = textAlign; this.softWrap = softWrap; this.overflow = overflow; @@ -144,6 +148,7 @@ public Text(string data, public static Text rich(TextSpan textSpan, Key key = null, TextStyle style = null, + StrutStyle strutStyle = null, TextAlign? textAlign = null, bool? softWrap = null, TextOverflow? overflow = null, @@ -152,6 +157,7 @@ public static Text rich(TextSpan textSpan, return new Text( textSpan, key, style, + strutStyle, textAlign, softWrap, overflow, @@ -165,6 +171,8 @@ public static Text rich(TextSpan textSpan, public readonly TextStyle style; + public readonly StrutStyle strutStyle; + public readonly TextAlign? textAlign; public readonly bool? softWrap; @@ -188,6 +196,7 @@ public override Widget build(BuildContext context) { overflow: this.overflow ?? defaultTextStyle.overflow, textScaleFactor: this.textScaleFactor ?? MediaQuery.textScaleFactorOf(context), maxLines: this.maxLines ?? defaultTextStyle.maxLines, + strutStyle: this.strutStyle, text: new TextSpan( style: effectiveTextStyle, text: this.data, diff --git a/Runtime/widgets/text_selection.cs b/Runtime/widgets/text_selection.cs index 77b06f80..e86011e4 100644 --- a/Runtime/widgets/text_selection.cs +++ b/Runtime/widgets/text_selection.cs @@ -8,6 +8,7 @@ using Unity.UIWidgets.scheduler; using Unity.UIWidgets.service; using Unity.UIWidgets.ui; +using Rect = Unity.UIWidgets.ui.Rect; namespace Unity.UIWidgets.widgets { static class TextSelectionUtils { @@ -96,10 +97,10 @@ public void handlePaste(TextSelectionDelegate selectionDelegate) { offset: value.selection.start + data.text.Length ) ); + + selectionDelegate.bringIntoView(selectionDelegate.textEditingValue.selection.extendPos); + selectionDelegate.hideToolbar(); } - - selectionDelegate.bringIntoView(selectionDelegate.textEditingValue.selection.extendPos); - selectionDelegate.hideToolbar(); }); } @@ -122,7 +123,7 @@ public TextSelectionOverlay(TextEditingValue value = null, RenderEditable renderObject = null, TextSelectionControls selectionControls = null, TextSelectionDelegate selectionDelegate = null, - DragStartBehavior? dragStartBehavior = null) { + DragStartBehavior dragStartBehavior = DragStartBehavior.start) { D.assert(value != null); D.assert(context != null); this.context = context; @@ -133,9 +134,10 @@ public TextSelectionOverlay(TextEditingValue value = null, this.selectionDelegate = selectionDelegate; this._value = value; OverlayState overlay = Overlay.of(context); - D.assert(overlay != null); - this._handleController = new AnimationController(duration: _fadeDuration, vsync: overlay); - this._toolbarController = new AnimationController(duration: _fadeDuration, vsync: overlay); + D.assert(overlay != null, () => $"No Overlay widget exists above {context}.\n" + + "Usually the Navigator created by WidgetsApp provides the overlay. Perhaps your " + + "app content was created above the Navigator with the WidgetsApp builder parameter."); + this._toolbarController = new AnimationController(duration: fadeDuration, vsync: overlay); this.dragStartBehavior = dragStartBehavior; } @@ -145,16 +147,11 @@ public TextSelectionOverlay(TextEditingValue value = null, public readonly RenderEditable renderObject; public readonly TextSelectionControls selectionControls; public readonly TextSelectionDelegate selectionDelegate; - public readonly DragStartBehavior? dragStartBehavior; + public readonly DragStartBehavior dragStartBehavior; - public static TimeSpan _fadeDuration = TimeSpan.FromMilliseconds(150); - AnimationController _handleController; + public static readonly TimeSpan fadeDuration = TimeSpan.FromMilliseconds(150); AnimationController _toolbarController; - Animation _handleOpacity { - get { return this._handleController.view; } - } - Animation _toolbarOpacity { get { return this._toolbarController.view; } } @@ -178,7 +175,6 @@ public void showHandles() { this._buildHandle(context, _TextSelectionHandlePosition.end)), }; Overlay.of(this.context, debugRequiredFor: this.debugRequiredFor).insertAll(this._handles); - this._handleController.forward(from: 0.0f); } public void showToolbar() { @@ -234,13 +230,11 @@ public void hide() { this._toolbar?.remove(); this._toolbar = null; - this._handleController.stop(); this._toolbarController.stop(); } public void dispose() { this.hide(); - this._handleController.dispose(); this._toolbarController.dispose(); } @@ -250,20 +244,17 @@ Widget _buildHandle(BuildContext context, _TextSelectionHandlePosition position) return new Container(); // hide the second handle when collapsed } - return new FadeTransition( - opacity: this._handleOpacity, - child: new _TextSelectionHandleOverlay( - onSelectionHandleChanged: (TextSelection newSelection) => { - this._handleSelectionHandleChanged(newSelection, position); - }, - onSelectionHandleTapped: this._handleSelectionHandleTapped, - layerLink: this.layerLink, - renderObject: this.renderObject, - selection: this._selection, - selectionControls: this.selectionControls, - position: position, - dragStartBehavior: this.dragStartBehavior ?? DragStartBehavior.down - ) + return new _TextSelectionHandleOverlay( + onSelectionHandleChanged: (TextSelection newSelection) => { + this._handleSelectionHandleChanged(newSelection, position); + }, + onSelectionHandleTapped: this._handleSelectionHandleTapped, + layerLink: this.layerLink, + renderObject: this.renderObject, + selection: this._selection, + selectionControls: this.selectionControls, + position: position, + dragStartBehavior: this.dragStartBehavior ); } @@ -333,7 +324,7 @@ internal _TextSelectionHandleOverlay( ValueChanged onSelectionHandleChanged = null, VoidCallback onSelectionHandleTapped = null, TextSelectionControls selectionControls = null, - DragStartBehavior dragStartBehavior = DragStartBehavior.down + DragStartBehavior dragStartBehavior = DragStartBehavior.start ) : base(key: key) { this.selection = selection; this.position = position; @@ -357,11 +348,59 @@ internal _TextSelectionHandleOverlay( public override State createState() { return new _TextSelectionHandleOverlayState(); } + + internal ValueListenable _visibility { + get { + switch (this.position) { + case _TextSelectionHandlePosition.start: + return this.renderObject.selectionStartInViewport; + case _TextSelectionHandlePosition.end: + return this.renderObject.selectionEndInViewport; + } + + return null; + } + } } - class _TextSelectionHandleOverlayState : State<_TextSelectionHandleOverlay> { + class _TextSelectionHandleOverlayState : SingleTickerProviderStateMixin<_TextSelectionHandleOverlay> { Offset _dragPosition; + AnimationController _controller; + + Animation _opacity { + get { return this._controller.view; } + } + + public override void initState() { + base.initState(); + this._controller = new AnimationController(duration: TextSelectionOverlay.fadeDuration, vsync: this); + this._handleVisibilityChanged(); + this.widget._visibility.addListener(this._handleVisibilityChanged); + } + + void _handleVisibilityChanged() { + if (this.widget._visibility.value) { + this._controller.forward(); + } + else { + this._controller.reverse(); + } + } + + public override void didUpdateWidget(StatefulWidget oldWidget) { + base.didUpdateWidget(oldWidget); + (oldWidget as _TextSelectionHandleOverlay)._visibility.removeListener(this._handleVisibilityChanged); + this._handleVisibilityChanged(); + this.widget._visibility.addListener(this._handleVisibilityChanged); + } + + public override void dispose() { + this.widget._visibility.removeListener(this._handleVisibilityChanged); + this._controller.dispose(); + base.dispose(); + } + void _handleDragStart(DragStartDetails details) { this._dragPosition = details.globalPosition + new Offset(0.0f, -this.widget.selectionControls.handleSize.height); @@ -421,24 +460,33 @@ public override Widget build(BuildContext context) { break; } + Size viewport = this.widget.renderObject.size; + point = new Offset( + point.dx.clamp(0.0f, viewport.width), + point.dy.clamp(0.0f, viewport.height) + ); + return new CompositedTransformFollower( link: this.widget.layerLink, showWhenUnlinked: false, - child: new GestureDetector( - dragStartBehavior: this.widget.dragStartBehavior, - onPanStart: this._handleDragStart, - onPanUpdate: this._handleDragUpdate, - onTap: this._handleTap, - child: new Stack( - overflow: Overflow.visible, - children: new List() { - new Positioned( - left: point.dx, - top: point.dy, - child: this.widget.selectionControls.buildHandle(context, type, - this.widget.renderObject.preferredLineHeight) - ) - } + child: new FadeTransition( + opacity: this._opacity, + child: new GestureDetector( + dragStartBehavior: this.widget.dragStartBehavior, + onPanStart: this._handleDragStart, + onPanUpdate: this._handleDragUpdate, + onTap: this._handleTap, + child: new Stack( + overflow: Overflow.visible, + children: new List() { + new Positioned( + left: point.dx, + top: point.dy, + child: this.widget.selectionControls.buildHandle(context, type, + this.widget.renderObject.preferredLineHeight) + ) + } + ) ) ) ); @@ -473,7 +521,9 @@ public TextSelectionGestureDetector( GestureTapDownCallback onTapDown = null, GestureTapUpCallback onSingleTapUp = null, GestureTapCancelCallback onSingleTapCancel = null, - GestureLongPressCallback onSingleLongTapStart = null, + GestureLongPressStartCallback onSingleLongTapStart = null, + GestureLongPressMoveUpdateCallback onSingleLongTapMoveUpdate = null, + GestureLongPressEndCallback onSingleLongTapEnd = null, GestureTapDownCallback onDoubleTapDown = null, GestureDragStartCallback onDragSelectionStart = null, DragSelectionUpdateCallback onDragSelectionUpdate = null, @@ -500,7 +550,11 @@ public TextSelectionGestureDetector( public readonly GestureTapCancelCallback onSingleTapCancel; - public readonly GestureLongPressCallback onSingleLongTapStart; + public readonly GestureLongPressStartCallback onSingleLongTapStart; + + public readonly GestureLongPressMoveUpdateCallback onSingleLongTapMoveUpdate; + + public readonly GestureLongPressEndCallback onSingleLongTapEnd; public readonly GestureTapDownCallback onDoubleTapDown; @@ -613,12 +667,26 @@ void _handleDragEnd(DragEndDetails details) { this._lastDragUpdateDetails = null; } - void _handleLongPressStart() { + void _handleLongPressStart(LongPressStartDetails details) { if (!this._isDoubleTap && this.widget.onSingleLongTapStart != null) { - this.widget.onSingleLongTapStart(); + this.widget.onSingleLongTapStart(details); } } + void _handleLongPressMoveUpdate(LongPressMoveUpdateDetails details) { + if (!this._isDoubleTap && this.widget.onSingleLongTapMoveUpdate != null) { + this.widget.onSingleLongTapMoveUpdate(details); + } + } + + void _handleLongPressEnd(LongPressEndDetails details) { + if (!this._isDoubleTap && this.widget.onSingleLongTapEnd != null) { + this.widget.onSingleLongTapEnd(details); + } + + this._isDoubleTap = false; + } + void _doubleTapTimeout() { this._doubleTapTimer = null; this._lastTapOffset = null; @@ -647,11 +715,18 @@ public override Widget build(BuildContext context) { ) ); - if (this.widget.onSingleLongTapStart != null) { + if (this.widget.onSingleLongTapStart != null || + this.widget.onSingleLongTapMoveUpdate != null || + this.widget.onSingleLongTapEnd != null + ) { gestures[typeof(LongPressGestureRecognizer)] = new GestureRecognizerFactoryWithHandlers( () => new LongPressGestureRecognizer(debugOwner: this, kind: PointerDeviceKind.touch), - instance => { instance.onLongPress = this._handleLongPressStart; }); + instance => { + instance.onLongPressStart = this._handleLongPressStart; + instance.onLongPressMoveUpdate = this._handleLongPressMoveUpdate; + instance.onLongPressEnd = this._handleLongPressEnd; + }); } if (this.widget.onDragSelectionStart != null || @@ -670,6 +745,9 @@ public override Widget build(BuildContext context) { ); } + // TODO: if (this.widget.onForcePressStart != null || this.widget.onForcePressEnd != null) { + // } + return new RawGestureDetector( gestures: gestures, behavior: this.widget.behavior, diff --git a/Runtime/widgets/transitions.cs b/Runtime/widgets/transitions.cs index 9273fd82..a581d06e 100644 --- a/Runtime/widgets/transitions.cs +++ b/Runtime/widgets/transitions.cs @@ -5,6 +5,7 @@ using Unity.UIWidgets.ui; using UnityEngine; using Rect = Unity.UIWidgets.ui.Rect; +using TextStyle = Unity.UIWidgets.painting.TextStyle; namespace Unity.UIWidgets.widgets { public abstract class AnimatedWidget : StatefulWidget { @@ -361,6 +362,48 @@ protected internal override Widget build(BuildContext context) { } } + public class DefaultTextStyleTransition : AnimatedWidget { + public DefaultTextStyleTransition( + Key key = null, + Animation style = null, + Widget child = null, + TextAlign? textAlign = null, + bool softWrap = true, + TextOverflow overflow = TextOverflow.clip, + int? maxLines = null + ) : base(key: key, listenable: style) { + D.assert(style != null); + D.assert(child != null); + this.textAlign = textAlign; + this.softWrap = softWrap; + this.overflow = overflow; + this.maxLines = maxLines; + this.child = child; + } + + Animation style { + get { return (Animation) this.listenable; } + } + + public readonly TextAlign? textAlign; + + public readonly bool softWrap; + public readonly TextOverflow overflow; + public readonly int? maxLines; + public readonly Widget child; + + protected internal override Widget build(BuildContext context) { + return new DefaultTextStyle( + style: this.style.value, + textAlign: this.textAlign, + softWrap: this.softWrap, + overflow: this.overflow, + maxLines: this.maxLines, + child: this.child + ); + } + } + public class AnimatedBuilder : AnimatedWidget { public readonly TransitionBuilder builder; diff --git a/Runtime/widgets/value_listenable_builder.cs b/Runtime/widgets/value_listenable_builder.cs new file mode 100644 index 00000000..7b7e74e4 --- /dev/null +++ b/Runtime/widgets/value_listenable_builder.cs @@ -0,0 +1,63 @@ +using Unity.UIWidgets.foundation; + +namespace Unity.UIWidgets.widgets { + public delegate Widget ValueWidgetBuilder(BuildContext context, T value, Widget child); + + public class ValueListenableBuilder : StatefulWidget { + public ValueListenableBuilder( + ValueListenable valueListenable, + ValueWidgetBuilder builder, + Widget child = null + ) { + D.assert(valueListenable != null); + D.assert(builder != null); + this.valueListenable = valueListenable; + this.builder = builder; + this.child = child; + } + + public readonly ValueListenable valueListenable; + + public readonly ValueWidgetBuilder builder; + + public readonly Widget child; + + public override State createState() { + return new _ValueListenableBuilderState(); + } + } + + class _ValueListenableBuilderState : State> { + T value; + + public override void initState() { + base.initState(); + this.value = this.widget.valueListenable.value; + this.widget.valueListenable.addListener(this._valueChanged); + } + + public override void didUpdateWidget(StatefulWidget _oldWidget) { + ValueListenableBuilder oldWidget = _oldWidget as ValueListenableBuilder; + if (oldWidget.valueListenable != this.widget.valueListenable) { + oldWidget.valueListenable.removeListener(this._valueChanged); + this.value = this.widget.valueListenable.value; + this.widget.valueListenable.addListener(this._valueChanged); + } + + base.didUpdateWidget(oldWidget); + } + + public override void dispose() { + this.widget.valueListenable.removeListener(this._valueChanged); + base.dispose(); + } + + void _valueChanged() { + this.setState(() => { this.value = this.widget.valueListenable.value; }); + } + + public override Widget build(BuildContext context) { + return this.widget.builder(context, this.value, this.widget.child); + } + } +} \ No newline at end of file diff --git a/Runtime/widgets/value_listenable_builder.cs.meta b/Runtime/widgets/value_listenable_builder.cs.meta new file mode 100644 index 00000000..4c877411 --- /dev/null +++ b/Runtime/widgets/value_listenable_builder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c4b7ae22b588cdf4093501087a4ecadb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples/MaterialSample/DividerButton.cs b/Samples/MaterialSample/DividerButton.cs deleted file mode 100644 index 449faf43..00000000 --- a/Samples/MaterialSample/DividerButton.cs +++ /dev/null @@ -1,92 +0,0 @@ -using System.Collections.Generic; -using Unity.UIWidgets.engine; -using Unity.UIWidgets.foundation; -using Unity.UIWidgets.material; -using Unity.UIWidgets.painting; -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; -using TextStyle = Unity.UIWidgets.painting.TextStyle; - -namespace UIWidgetsSample { - public class DividerButton : UIWidgetsSamplePanel { - - protected override Widget createWidget() { - return new WidgetsApp( - home: new DemoApp(), - pageRouteBuilder: this.pageRouteBuilder); - } - - public class DemoApp : StatefulWidget { - public DemoApp(Key key = null) : base(key) { - } - - public override State createState() { - return new _DemoAppState(); - } - } - - public class _DemoAppState : State { - string title = "Hello"; - string subtitle = "World"; - TextEditingController controller = new TextEditingController(""); - - public override Widget build(BuildContext context) { - return new Container( - height: 200, - padding: EdgeInsets.all(10), - decoration: new BoxDecoration( - color: new Color(0xFFEF1F7F), - border: Border.all(color: Color.fromARGB(255, 0xDF, 0x10, 0x70), width: 5), - borderRadius: BorderRadius.all(20) - ), - child: new Center( - child: new Column( - children: new List() { - new Text(this.title), - new Divider(), - new Text(this.subtitle), - new Divider(), - new Container( - width: 500, - decoration: new BoxDecoration(border: Border.all(new Color(0xFF00FF00), 1)), - child: new EditableText( - controller: this.controller, - focusNode: new FocusNode(), - style: new TextStyle( - fontSize: 18, - height: 1.5f, - color: new Color(0xFFFF89FD)), - cursorColor: Color.fromARGB(255, 0, 0, 0) - ) - ), - new Divider(), - new ButtonBar( - children: new List { - new FlatButton( - onPressed: () => { - this.setState(() => { this.title = this.controller.text; }); - }, - padding: EdgeInsets.all(5.0f), - child: new Center( - child: new Text("Set Title") - ) - ), - new RaisedButton( - onPressed: () => { - this.setState(() => { this.subtitle = this.controller.text; }); - }, - padding: EdgeInsets.all(5.0f), - child: new Center( - child: new Text("Set Subtitle") - ) - ) - } - ) - } - ) - ) - ); - } - } - } -} \ No newline at end of file diff --git a/Samples/ReduxSample/.sample.json b/Samples/ReduxSample/.sample.json deleted file mode 100644 index 39ad4031..00000000 --- a/Samples/ReduxSample/.sample.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "displayName":"Redux Sample", - "description": "Sample usage of Redux & UIWidgets", - "createSeparatePackage": false -} diff --git a/Samples/ReduxSample/CounterApp/CounterApp.unity b/Samples/ReduxSample/CounterApp/CounterApp.unity deleted file mode 100644 index ce61cfed..00000000 --- a/Samples/ReduxSample/CounterApp/CounterApp.unity +++ /dev/null @@ -1,503 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!29 &1 -OcclusionCullingSettings: - m_ObjectHideFlags: 0 - serializedVersion: 2 - m_OcclusionBakeSettings: - smallestOccluder: 5 - smallestHole: 0.25 - backfaceThreshold: 100 - m_SceneGUID: 00000000000000000000000000000000 - m_OcclusionCullingData: {fileID: 0} ---- !u!104 &2 -RenderSettings: - m_ObjectHideFlags: 0 - serializedVersion: 9 - m_Fog: 0 - m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} - m_FogMode: 3 - m_FogDensity: 0.01 - m_LinearFogStart: 0 - m_LinearFogEnd: 300 - m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} - m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} - m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} - m_AmbientIntensity: 1 - m_AmbientMode: 0 - m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} - m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} - m_HaloStrength: 0.5 - m_FlareStrength: 1 - m_FlareFadeSpeed: 3 - m_HaloTexture: {fileID: 0} - m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} - m_DefaultReflectionMode: 0 - m_DefaultReflectionResolution: 128 - m_ReflectionBounces: 1 - m_ReflectionIntensity: 1 - m_CustomReflection: {fileID: 0} - m_Sun: {fileID: 0} - m_IndirectSpecularColor: {r: 0.44657892, g: 0.4964127, b: 0.5748172, a: 1} - m_UseRadianceAmbientProbe: 0 ---- !u!157 &3 -LightmapSettings: - m_ObjectHideFlags: 0 - serializedVersion: 11 - m_GIWorkflowMode: 0 - m_GISettings: - serializedVersion: 2 - m_BounceScale: 1 - m_IndirectOutputScale: 1 - m_AlbedoBoost: 1 - m_EnvironmentLightingMode: 0 - m_EnableBakedLightmaps: 1 - m_EnableRealtimeLightmaps: 1 - m_LightmapEditorSettings: - serializedVersion: 10 - m_Resolution: 2 - m_BakeResolution: 40 - m_AtlasSize: 1024 - m_AO: 0 - m_AOMaxDistance: 1 - m_CompAOExponent: 1 - m_CompAOExponentDirect: 0 - m_Padding: 2 - m_LightmapParameters: {fileID: 0} - m_LightmapsBakeMode: 1 - m_TextureCompression: 1 - m_FinalGather: 0 - m_FinalGatherFiltering: 1 - m_FinalGatherRayCount: 256 - m_ReflectionCompression: 2 - m_MixedBakeMode: 2 - m_BakeBackend: 1 - m_PVRSampling: 1 - m_PVRDirectSampleCount: 32 - m_PVRSampleCount: 500 - m_PVRBounces: 2 - m_PVRFilterTypeDirect: 0 - m_PVRFilterTypeIndirect: 0 - m_PVRFilterTypeAO: 0 - m_PVRFilteringMode: 1 - m_PVRCulling: 1 - m_PVRFilteringGaussRadiusDirect: 1 - m_PVRFilteringGaussRadiusIndirect: 5 - m_PVRFilteringGaussRadiusAO: 2 - m_PVRFilteringAtrousPositionSigmaDirect: 0.5 - m_PVRFilteringAtrousPositionSigmaIndirect: 2 - m_PVRFilteringAtrousPositionSigmaAO: 1 - m_ShowResolutionOverlay: 1 - m_LightingDataAsset: {fileID: 0} - m_UseShadowmask: 1 ---- !u!196 &4 -NavMeshSettings: - serializedVersion: 2 - m_ObjectHideFlags: 0 - m_BuildSettings: - serializedVersion: 2 - agentTypeID: 0 - agentRadius: 0.5 - agentHeight: 2 - agentSlope: 45 - agentClimb: 0.4 - ledgeDropHeight: 0 - maxJumpAcrossDistance: 0 - minRegionArea: 2 - manualCellSize: 0 - cellSize: 0.16666667 - manualTileSize: 0 - tileSize: 256 - accuratePlacement: 0 - debug: - m_Flags: 0 - m_NavMeshData: {fileID: 0} ---- !u!1 &147477927 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 147477931} - - component: {fileID: 147477930} - - component: {fileID: 147477929} - - component: {fileID: 147477928} - m_Layer: 5 - m_Name: Canvas - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!114 &147477928 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 147477927} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 1301386320, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_IgnoreReversedGraphics: 1 - m_BlockingObjects: 0 - m_BlockingMask: - serializedVersion: 2 - m_Bits: 4294967295 ---- !u!114 &147477929 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 147477927} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 1980459831, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_UiScaleMode: 0 - m_ReferencePixelsPerUnit: 100 - m_ScaleFactor: 1 - m_ReferenceResolution: {x: 800, y: 600} - m_ScreenMatchMode: 0 - m_MatchWidthOrHeight: 0 - m_PhysicalUnit: 3 - m_FallbackScreenDPI: 96 - m_DefaultSpriteDPI: 96 - m_DynamicPixelsPerUnit: 1 ---- !u!223 &147477930 -Canvas: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 147477927} - m_Enabled: 1 - serializedVersion: 3 - m_RenderMode: 0 - m_Camera: {fileID: 0} - m_PlaneDistance: 100 - m_PixelPerfect: 0 - m_ReceivesEvents: 1 - m_OverrideSorting: 0 - m_OverridePixelPerfect: 0 - m_SortingBucketNormalizedSize: 0 - m_AdditionalShaderChannelsFlag: 0 - m_SortingLayerID: 0 - m_SortingOrder: 0 - m_TargetDisplay: 0 ---- !u!224 &147477931 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 147477927} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 0, y: 0, z: 0} - m_Children: - - {fileID: 1059242950} - m_Father: {fileID: 0} - m_RootOrder: 2 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 0, y: 0} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0, y: 0} ---- !u!1 &148280213 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 148280216} - - component: {fileID: 148280215} - - component: {fileID: 148280214} - m_Layer: 0 - m_Name: EventSystem - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!114 &148280214 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 148280213} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 1077351063, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_HorizontalAxis: Horizontal - m_VerticalAxis: Vertical - m_SubmitButton: Submit - m_CancelButton: Cancel - m_InputActionsPerSecond: 10 - m_RepeatDelay: 0.5 - m_ForceModuleActive: 0 ---- !u!114 &148280215 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 148280213} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: -619905303, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_FirstSelected: {fileID: 0} - m_sendNavigationEvents: 1 - m_DragThreshold: 10 ---- !u!4 &148280216 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 148280213} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 3 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!1 &1059242949 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1059242950} - - component: {fileID: 1059242952} - - component: {fileID: 1059242951} - m_Layer: 5 - m_Name: GameObject - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &1059242950 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1059242949} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 147477931} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0.5, y: 0.5} - m_AnchorMax: {x: 0.5, y: 0.5} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 300, y: 200} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &1059242951 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1059242949} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 1df7452b5a8dd478ca8988b48502efe1, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_Texture: {fileID: 0} - m_UVRect: - serializedVersion: 2 - x: 0 - y: 0 - width: 1 - height: 1 - devicePixelRatioOverride: 0 ---- !u!222 &1059242952 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1059242949} - m_CullTransparentMesh: 0 ---- !u!1 &1660260751 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1660260753} - - component: {fileID: 1660260752} - m_Layer: 0 - m_Name: Directional Light - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!108 &1660260752 -Light: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1660260751} - m_Enabled: 1 - serializedVersion: 8 - m_Type: 1 - m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} - m_Intensity: 1 - m_Range: 10 - m_SpotAngle: 30 - m_CookieSize: 10 - m_Shadows: - m_Type: 2 - m_Resolution: -1 - m_CustomResolution: -1 - m_Strength: 1 - m_Bias: 0.05 - m_NormalBias: 0.4 - m_NearPlane: 0.2 - m_Cookie: {fileID: 0} - m_DrawHalo: 0 - m_Flare: {fileID: 0} - m_RenderMode: 0 - m_CullingMask: - serializedVersion: 2 - m_Bits: 4294967295 - m_Lightmapping: 4 - m_LightShadowCasterMode: 0 - m_AreaSize: {x: 1, y: 1} - m_BounceIntensity: 1 - m_ColorTemperature: 6570 - m_UseColorTemperature: 0 - m_ShadowRadius: 0 - m_ShadowAngle: 0 ---- !u!4 &1660260753 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1660260751} - m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} - m_LocalPosition: {x: 0, y: 3, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 1 - m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} ---- !u!1 &1941984212 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1941984215} - - component: {fileID: 1941984214} - - component: {fileID: 1941984213} - m_Layer: 0 - m_Name: Main Camera - m_TagString: MainCamera - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!81 &1941984213 -AudioListener: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1941984212} - m_Enabled: 1 ---- !u!20 &1941984214 -Camera: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1941984212} - m_Enabled: 1 - serializedVersion: 2 - m_ClearFlags: 1 - m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} - m_projectionMatrixMode: 1 - m_SensorSize: {x: 36, y: 24} - m_LensShift: {x: 0, y: 0} - m_GateFitMode: 2 - m_FocalLength: 50 - m_NormalizedViewPortRect: - serializedVersion: 2 - x: 0 - y: 0 - width: 1 - height: 1 - near clip plane: 0.3 - far clip plane: 1000 - field of view: 60 - orthographic: 0 - orthographic size: 5 - m_Depth: -1 - m_CullingMask: - serializedVersion: 2 - m_Bits: 4294967295 - m_RenderingPath: -1 - m_TargetTexture: {fileID: 0} - m_TargetDisplay: 0 - m_TargetEye: 3 - m_HDR: 1 - m_AllowMSAA: 1 - m_AllowDynamicResolution: 0 - m_ForceIntoRT: 0 - m_OcclusionCulling: 1 - m_StereoConvergence: 10 - m_StereoSeparation: 0.022 ---- !u!4 &1941984215 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1941984212} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 1, z: -10} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} diff --git a/Samples/ReduxSample/CounterApp/CounterApp.unity.meta b/Samples/ReduxSample/CounterApp/CounterApp.unity.meta deleted file mode 100644 index 72bb8a7a..00000000 --- a/Samples/ReduxSample/CounterApp/CounterApp.unity.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: b223e0fe089d54420b281da7ec2b7420 -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/ReduxSample/CounterApp/CounterAppSample.cs b/Samples/ReduxSample/CounterApp/CounterAppSample.cs deleted file mode 100644 index fa9a503b..00000000 --- a/Samples/ReduxSample/CounterApp/CounterAppSample.cs +++ /dev/null @@ -1,113 +0,0 @@ -using System; -using System.Collections.Generic; -using Unity.UIWidgets.foundation; -using Unity.UIWidgets.gestures; -using Unity.UIWidgets.painting; -using Unity.UIWidgets.Redux; -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; -using TextStyle = Unity.UIWidgets.painting.TextStyle; - -namespace Unity.UIWidgets.Sample.Redux { - public class CounterAppSample : UIWidgetsSample.UIWidgetsSamplePanel { - protected override Widget createWidget() { - return new WidgetsApp( - home: new CounterApp(), - pageRouteBuilder: this.pageRouteBuilder); - } - } - - [Serializable] - public class CouterState { - public int count; - - public CouterState(int count = 0) { - this.count = count; - } - } - - [Serializable] - public class CounterIncAction { - public int amount; - } - - public class CounterApp : StatelessWidget { - public override Widget build(BuildContext context) { - var store = new Store(reduce, new CouterState(), - ReduxLogging.create()); - return new StoreProvider(store, this.createWidget()); - } - - public static CouterState reduce(CouterState state, object action) { - var inc = action as CounterIncAction; - if (inc == null) { - return state; - } - - return new CouterState(inc.amount + state.count); - } - - Widget createWidget() { - return new Container( - height: 200.0f, - padding: EdgeInsets.all(10), - decoration: new BoxDecoration( - color: new Color(0xFF7F7F7F), - border: Border.all(color: Color.fromARGB(255, 255, 0, 0), width: 5), - borderRadius: BorderRadius.all(2)), - child: new Column( - children: new List() { - new StoreConnector( - converter: (state) => $"Count:{state.count}", - builder: (context, countText, dispatcher) => new Text(countText, style: new TextStyle( - fontSize: 20, fontWeight: FontWeight.w700 - )), - pure: true - ), - new StoreConnector( - converter: (state) => null, - builder: (context, _, dispatcher) => new CustomButton( - backgroundColor: Color.fromARGB(255, 0, 204, 204), - padding: EdgeInsets.all(10), - child: new Text("Add", style: new TextStyle( - fontSize: 16, color: Color.fromARGB(255, 255, 255, 255) - )), onPressed: () => { dispatcher.dispatch(new CounterIncAction() {amount = 1}); }), - pure: true - ), - } - ) - ); - } - } - - public class CustomButton : StatelessWidget { - public CustomButton( - Key key = null, - GestureTapCallback onPressed = null, - EdgeInsets padding = null, - Color backgroundColor = null, - Widget child = null - ) : base(key: key) { - this.onPressed = onPressed; - this.padding = padding ?? EdgeInsets.all(8.0f); - this.backgroundColor = backgroundColor; - this.child = child; - } - - public readonly GestureTapCallback onPressed; - public readonly EdgeInsets padding; - public readonly Widget child; - public readonly Color backgroundColor; - - public override Widget build(BuildContext context) { - return new GestureDetector( - onTap: this.onPressed, - child: new Container( - padding: this.padding, - decoration: new BoxDecoration(color: this.backgroundColor), - child: this.child - ) - ); - } - } -} \ No newline at end of file diff --git a/Samples/ReduxSample/CounterApp/CounterAppSample.cs.meta b/Samples/ReduxSample/CounterApp/CounterAppSample.cs.meta deleted file mode 100644 index 66524ae6..00000000 --- a/Samples/ReduxSample/CounterApp/CounterAppSample.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 1df7452b5a8dd478ca8988b48502efe1 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/ReduxSample/ObjectFinder.meta b/Samples/ReduxSample/ObjectFinder.meta deleted file mode 100644 index 4dcc57ba..00000000 --- a/Samples/ReduxSample/ObjectFinder.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 9b02ce0cc0eb64ae7bce356d7d003e6d -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/ReduxSample/ObjectFinder/FinderGameObject.cs b/Samples/ReduxSample/ObjectFinder/FinderGameObject.cs deleted file mode 100644 index 78de465e..00000000 --- a/Samples/ReduxSample/ObjectFinder/FinderGameObject.cs +++ /dev/null @@ -1,25 +0,0 @@ -using UnityEngine; - -namespace Unity.UIWidgets.Sample.Redux.ObjectFinder { - public class FinderGameObject : MonoBehaviour { - // Start is called before the first frame update - void Start() { - this.GetComponent().material.color = new Color(1.0f, 0, 0, 1.0f); - } - - // Update is called once per frame - void Update() { - var selectedId = StoreProvider.store.getState().selected; - if (selectedId == this.GetInstanceID()) { - this.GetComponent().material.color = new Color(1.0f, 0, 0, 1.0f); - } - else { - this.GetComponent().material.color = new Color(1.0f, 1.0f, 1.0f, 1.0f); - } - } - - void OnMouseDown() { - StoreProvider.store.dispatcher.dispatch(new SelectObjectAction() {id = this.GetInstanceID()}); - } - } -} \ No newline at end of file diff --git a/Samples/ReduxSample/ObjectFinder/FinderGameObject.cs.meta b/Samples/ReduxSample/ObjectFinder/FinderGameObject.cs.meta deleted file mode 100644 index 8212230b..00000000 --- a/Samples/ReduxSample/ObjectFinder/FinderGameObject.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 969624a932ff84fe09dc38f9460223fb -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/ReduxSample/ObjectFinder/ObjectFinderApp.cs b/Samples/ReduxSample/ObjectFinder/ObjectFinderApp.cs deleted file mode 100644 index fe39d435..00000000 --- a/Samples/ReduxSample/ObjectFinder/ObjectFinderApp.cs +++ /dev/null @@ -1,223 +0,0 @@ -using System; -using System.Collections.Generic; -using Unity.UIWidgets.foundation; -using Unity.UIWidgets.material; -using Unity.UIWidgets.painting; -using Unity.UIWidgets.rendering; -using Unity.UIWidgets.Redux; -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; -using UnityEngine; -using Color = Unity.UIWidgets.ui.Color; -using TextStyle = Unity.UIWidgets.painting.TextStyle; - -namespace Unity.UIWidgets.Sample.Redux.ObjectFinder { - public class ObjectFinderApp : UIWidgetsSample.UIWidgetsSamplePanel { - public ObjectFinderApp() { - } - - protected override Widget createWidget() { - return new WidgetsApp( - home: new StoreProvider(StoreProvider.store, this.createRootWidget()), - pageRouteBuilder: this.pageRouteBuilder); - } - - Widget createRootWidget() { - return new StoreConnector( - pure: true, - builder: (context, viewModel, dispatcher) => new ObjectFinderAppWidget( - model: viewModel, - doSearch: (text) => dispatcher.dispatch(SearchAction.create(text)), - onSelect: (id) => dispatcher.dispatch(new SelectObjectAction() {id = id}), - title: this.gameObject.name - ), - converter: (state) => new ObjectFinderAppWidgetModel() { - objects = state.objects, - selected = state.selected, - } - ); - } - } - - - public delegate void onFindCallback(string keyword); - - public class ObjectFinderAppWidgetModel : IEquatable { - public int selected; - public List objects; - - public bool Equals(ObjectFinderAppWidgetModel other) { - if (ReferenceEquals(null, other)) { - return false; - } - if (ReferenceEquals(this, other)) { - return true; - } - return this.selected == other.selected && this.objects.equalsList(other.objects); - } - - public override bool Equals(object obj) { - if (ReferenceEquals(null, obj)) { - return false; - } - if (ReferenceEquals(this, obj)) { - return true; - } - if (obj.GetType() != this.GetType()) { - return false; - } - return this.Equals((ObjectFinderAppWidgetModel) obj); - } - - public override int GetHashCode() { - unchecked { - return (this.selected * 397) ^ this.objects.hashList(); - } - } - - public static bool operator ==(ObjectFinderAppWidgetModel left, ObjectFinderAppWidgetModel right) { - return Equals(left, right); - } - - public static bool operator !=(ObjectFinderAppWidgetModel left, ObjectFinderAppWidgetModel right) { - return !Equals(left, right); - } - } - - public class ObjectFinderAppWidget : StatefulWidget { - public readonly List objectInfos; - public readonly int selected; - - public readonly Action doSearch; - - public readonly Action onSelect; - - public readonly string title; - - public ObjectFinderAppWidget( - ObjectFinderAppWidgetModel model = null, - Action doSearch = null, - Action onSelect = null, - string title = null, - Key key = null) : base(key) { - this.objectInfos = model.objects; - this.selected = model.selected; - this.doSearch = doSearch; - this.onSelect = onSelect; - this.title = title; - } - - public override State createState() { - return new _ObjectFinderAppWidgetState(); - } - } - - public class _ObjectFinderAppWidgetState : State { - TextEditingController _controller; - - FocusNode _focusNode; - - public override void initState() { - base.initState(); - this._controller = new TextEditingController(""); - this._focusNode = new FocusNode(); - if (this.widget.doSearch != null) { - Window.instance.scheduleMicrotask(() => this.widget.doSearch("")); - } - - this._controller.addListener(this.textChange); - } - - public override void dispose() { - this._focusNode.dispose(); - this._controller.removeListener(this.textChange); - base.dispose(); - } - - public override Widget build(BuildContext context) { - Debug.Log("build ObjectFinderAppWidget"); - - return new Container( - padding: EdgeInsets.all(10), - decoration: new BoxDecoration(color: new Color(0x4FFFFFFF), - border: Border.all(color: Color.fromARGB(255, 255, 0, 0), width: 5), - borderRadius: BorderRadius.all(2)), - child: new Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: new List() { - this._buildTitle(), - this._buildSearchInput(), - this._buildResultCount(), - this._buildResults(), - } - ) - ); - } - - void textChange() { - if (this.widget.doSearch != null) { - this.widget.doSearch(this._controller.text); - } - } - - Widget _buildTitle() { - return new Text(this.widget.title, textAlign: TextAlign.center, - style: new TextStyle(fontSize: 20, height: 1.5f)); - } - - Widget _buildSearchInput() { - return new Row( - children: new List { - new Text("Search:"), - new Flexible(child: - new Container( - margin: EdgeInsets.only(left: 8), - decoration: new BoxDecoration(border: Border.all(new Color(0xFF000000), 1)), - padding: EdgeInsets.only(left: 8, right: 8), - child: new EditableText( - selectionControls: MaterialUtils.materialTextSelectionControls, - backgroundCursorColor: Colors.transparent, - controller: this._controller, - focusNode: this._focusNode, - style: new TextStyle( - fontSize: 18, - height: 1.5f - ), - cursorColor: Color.fromARGB(255, 0, 0, 0) - ) - ) - ) - } - ); - } - - Widget _buildResultItem(GameObjectInfo obj) { - return new GestureDetector(child: - new Container( - key: new ValueKey(obj.id), - child: new Text(obj.name), - padding: EdgeInsets.all(8), - color: this.widget.selected == obj.id ? new Color(0xFFFF0000) : new Color(0) - ), onTap: () => { - if (this.widget.onSelect != null) { - this.widget.onSelect(obj.id); - } - }); - } - - Widget _buildResultCount() { - return new Text($"Total Results:{this.widget.objectInfos.Count}", - style: new TextStyle(height: 3.0f, fontSize: 12)); - } - - Widget _buildResults() { - List rows = new List(); - this.widget.objectInfos.ForEach(obj => { rows.Add(this._buildResultItem(obj)); }); - return new Flexible( - child: new ListView( - children: rows, - physics: new AlwaysScrollableScrollPhysics()) - ); - } - } -} \ No newline at end of file diff --git a/Samples/ReduxSample/ObjectFinder/ObjectFinderApp.cs.meta b/Samples/ReduxSample/ObjectFinder/ObjectFinderApp.cs.meta deleted file mode 100644 index 0a517699..00000000 --- a/Samples/ReduxSample/ObjectFinder/ObjectFinderApp.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 3e8946ae1a1b9498eb3eaa2cc6fc9b23 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/ReduxSample/ObjectFinder/ObjectFinderScene.unity b/Samples/ReduxSample/ObjectFinder/ObjectFinderScene.unity deleted file mode 100644 index 99fab765..00000000 --- a/Samples/ReduxSample/ObjectFinder/ObjectFinderScene.unity +++ /dev/null @@ -1,1743 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!29 &1 -OcclusionCullingSettings: - m_ObjectHideFlags: 0 - serializedVersion: 2 - m_OcclusionBakeSettings: - smallestOccluder: 5 - smallestHole: 0.25 - backfaceThreshold: 100 - m_SceneGUID: 00000000000000000000000000000000 - m_OcclusionCullingData: {fileID: 0} ---- !u!104 &2 -RenderSettings: - m_ObjectHideFlags: 0 - serializedVersion: 9 - m_Fog: 0 - m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} - m_FogMode: 3 - m_FogDensity: 0.01 - m_LinearFogStart: 0 - m_LinearFogEnd: 300 - m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} - m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} - m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} - m_AmbientIntensity: 1 - m_AmbientMode: 0 - m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} - m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} - m_HaloStrength: 0.5 - m_FlareStrength: 1 - m_FlareFadeSpeed: 3 - m_HaloTexture: {fileID: 0} - m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} - m_DefaultReflectionMode: 0 - m_DefaultReflectionResolution: 128 - m_ReflectionBounces: 1 - m_ReflectionIntensity: 1 - m_CustomReflection: {fileID: 0} - m_Sun: {fileID: 0} - m_IndirectSpecularColor: {r: 0.44657892, g: 0.4964127, b: 0.5748172, a: 1} - m_UseRadianceAmbientProbe: 0 ---- !u!157 &3 -LightmapSettings: - m_ObjectHideFlags: 0 - serializedVersion: 11 - m_GIWorkflowMode: 0 - m_GISettings: - serializedVersion: 2 - m_BounceScale: 1 - m_IndirectOutputScale: 1 - m_AlbedoBoost: 1 - m_EnvironmentLightingMode: 0 - m_EnableBakedLightmaps: 1 - m_EnableRealtimeLightmaps: 1 - m_LightmapEditorSettings: - serializedVersion: 10 - m_Resolution: 2 - m_BakeResolution: 40 - m_AtlasSize: 1024 - m_AO: 0 - m_AOMaxDistance: 1 - m_CompAOExponent: 1 - m_CompAOExponentDirect: 0 - m_Padding: 2 - m_LightmapParameters: {fileID: 0} - m_LightmapsBakeMode: 1 - m_TextureCompression: 1 - m_FinalGather: 0 - m_FinalGatherFiltering: 1 - m_FinalGatherRayCount: 256 - m_ReflectionCompression: 2 - m_MixedBakeMode: 2 - m_BakeBackend: 1 - m_PVRSampling: 1 - m_PVRDirectSampleCount: 32 - m_PVRSampleCount: 500 - m_PVRBounces: 2 - m_PVRFilterTypeDirect: 0 - m_PVRFilterTypeIndirect: 0 - m_PVRFilterTypeAO: 0 - m_PVRFilteringMode: 1 - m_PVRCulling: 1 - m_PVRFilteringGaussRadiusDirect: 1 - m_PVRFilteringGaussRadiusIndirect: 5 - m_PVRFilteringGaussRadiusAO: 2 - m_PVRFilteringAtrousPositionSigmaDirect: 0.5 - m_PVRFilteringAtrousPositionSigmaIndirect: 2 - m_PVRFilteringAtrousPositionSigmaAO: 1 - m_ShowResolutionOverlay: 1 - m_LightingDataAsset: {fileID: 0} - m_UseShadowmask: 1 ---- !u!196 &4 -NavMeshSettings: - serializedVersion: 2 - m_ObjectHideFlags: 0 - m_BuildSettings: - serializedVersion: 2 - agentTypeID: 0 - agentRadius: 0.5 - agentHeight: 2 - agentSlope: 45 - agentClimb: 0.4 - ledgeDropHeight: 0 - maxJumpAcrossDistance: 0 - minRegionArea: 2 - manualCellSize: 0 - cellSize: 0.16666667 - manualTileSize: 0 - tileSize: 256 - accuratePlacement: 0 - debug: - m_Flags: 0 - m_NavMeshData: {fileID: 0} ---- !u!1 &384523370 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 384523374} - - component: {fileID: 384523373} - - component: {fileID: 384523372} - - component: {fileID: 384523371} - - component: {fileID: 384523375} - m_Layer: 0 - m_Name: Sphere (3) - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!135 &384523371 -SphereCollider: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 384523370} - m_Material: {fileID: 0} - m_IsTrigger: 0 - m_Enabled: 1 - serializedVersion: 2 - m_Radius: 0.5 - m_Center: {x: 0, y: 0, z: 0} ---- !u!23 &384523372 -MeshRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 384523370} - m_Enabled: 1 - m_CastShadows: 1 - m_ReceiveShadows: 1 - m_DynamicOccludee: 1 - m_MotionVectors: 1 - m_LightProbeUsage: 1 - m_ReflectionProbeUsage: 1 - m_RenderingLayerMask: 1 - m_RendererPriority: 0 - m_Materials: - - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} - m_StaticBatchInfo: - firstSubMesh: 0 - subMeshCount: 0 - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_PreserveUVs: 0 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_StitchLightmapSeams: 0 - m_SelectedEditorRenderState: 3 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_SortingLayerID: 0 - m_SortingLayer: 0 - m_SortingOrder: 0 ---- !u!33 &384523373 -MeshFilter: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 384523370} - m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0} ---- !u!4 &384523374 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 384523370} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 5, y: 5, z: 1} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 15 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!114 &384523375 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 384523370} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 969624a932ff84fe09dc38f9460223fb, type: 3} - m_Name: - m_EditorClassIdentifier: ---- !u!1 &565543731 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 565543735} - - component: {fileID: 565543734} - - component: {fileID: 565543733} - - component: {fileID: 565543732} - - component: {fileID: 565543736} - m_Layer: 0 - m_Name: Cube (2) - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!65 &565543732 -BoxCollider: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 565543731} - m_Material: {fileID: 0} - m_IsTrigger: 0 - m_Enabled: 1 - serializedVersion: 2 - m_Size: {x: 1, y: 1, z: 1} - m_Center: {x: 0, y: 0, z: 0} ---- !u!23 &565543733 -MeshRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 565543731} - m_Enabled: 1 - m_CastShadows: 1 - m_ReceiveShadows: 1 - m_DynamicOccludee: 1 - m_MotionVectors: 1 - m_LightProbeUsage: 1 - m_ReflectionProbeUsage: 1 - m_RenderingLayerMask: 1 - m_RendererPriority: 0 - m_Materials: - - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} - m_StaticBatchInfo: - firstSubMesh: 0 - subMeshCount: 0 - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_PreserveUVs: 0 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_StitchLightmapSeams: 0 - m_SelectedEditorRenderState: 3 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_SortingLayerID: 0 - m_SortingLayer: 0 - m_SortingOrder: 0 ---- !u!33 &565543734 -MeshFilter: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 565543731} - m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} ---- !u!4 &565543735 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 565543731} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: -3, y: -2, z: 2} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 7 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!114 &565543736 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 565543731} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 969624a932ff84fe09dc38f9460223fb, type: 3} - m_Name: - m_EditorClassIdentifier: ---- !u!1 &603416551 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 603416555} - - component: {fileID: 603416554} - - component: {fileID: 603416553} - - component: {fileID: 603416552} - - component: {fileID: 603416556} - m_Layer: 0 - m_Name: Sphere (1) - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!135 &603416552 -SphereCollider: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 603416551} - m_Material: {fileID: 0} - m_IsTrigger: 0 - m_Enabled: 1 - serializedVersion: 2 - m_Radius: 0.5 - m_Center: {x: 0, y: 0, z: 0} ---- !u!23 &603416553 -MeshRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 603416551} - m_Enabled: 1 - m_CastShadows: 1 - m_ReceiveShadows: 1 - m_DynamicOccludee: 1 - m_MotionVectors: 1 - m_LightProbeUsage: 1 - m_ReflectionProbeUsage: 1 - m_RenderingLayerMask: 1 - m_RendererPriority: 0 - m_Materials: - - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} - m_StaticBatchInfo: - firstSubMesh: 0 - subMeshCount: 0 - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_PreserveUVs: 0 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_StitchLightmapSeams: 0 - m_SelectedEditorRenderState: 3 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_SortingLayerID: 0 - m_SortingLayer: 0 - m_SortingOrder: 0 ---- !u!33 &603416554 -MeshFilter: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 603416551} - m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0} ---- !u!4 &603416555 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 603416551} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 4, y: 5, z: 1} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 13 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!114 &603416556 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 603416551} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 969624a932ff84fe09dc38f9460223fb, type: 3} - m_Name: - m_EditorClassIdentifier: ---- !u!1 &647588331 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 647588333} - - component: {fileID: 647588332} - m_Layer: 0 - m_Name: Directional Light - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!108 &647588332 -Light: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 647588331} - m_Enabled: 1 - serializedVersion: 8 - m_Type: 1 - m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} - m_Intensity: 1 - m_Range: 10 - m_SpotAngle: 30 - m_CookieSize: 10 - m_Shadows: - m_Type: 2 - m_Resolution: -1 - m_CustomResolution: -1 - m_Strength: 1 - m_Bias: 0.05 - m_NormalBias: 0.4 - m_NearPlane: 0.2 - m_Cookie: {fileID: 0} - m_DrawHalo: 0 - m_Flare: {fileID: 0} - m_RenderMode: 0 - m_CullingMask: - serializedVersion: 2 - m_Bits: 4294967295 - m_Lightmapping: 4 - m_LightShadowCasterMode: 0 - m_AreaSize: {x: 1, y: 1} - m_BounceIntensity: 1 - m_ColorTemperature: 6570 - m_UseColorTemperature: 0 - m_ShadowRadius: 0 - m_ShadowAngle: 0 ---- !u!4 &647588333 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 647588331} - m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} - m_LocalPosition: {x: 0, y: 3, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 1 - m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} ---- !u!1 &734465800 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 734465801} - - component: {fileID: 734465803} - - component: {fileID: 734465802} - m_Layer: 5 - m_Name: Object Finder - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &734465801 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 734465800} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 2.2167413} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 1343734726} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0.5} - m_AnchorMax: {x: 0, y: 0.5} - m_AnchoredPosition: {x: 180, y: 0} - m_SizeDelta: {x: 300, y: 400} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &734465802 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 734465800} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 3e8946ae1a1b9498eb3eaa2cc6fc9b23, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null ---- !u!222 &734465803 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 734465800} - m_CullTransparentMesh: 0 ---- !u!1 &767651608 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 767651612} - - component: {fileID: 767651611} - - component: {fileID: 767651610} - - component: {fileID: 767651609} - - component: {fileID: 767651613} - m_Layer: 0 - m_Name: Cube - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!65 &767651609 -BoxCollider: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 767651608} - m_Material: {fileID: 0} - m_IsTrigger: 0 - m_Enabled: 1 - serializedVersion: 2 - m_Size: {x: 1, y: 1, z: 1} - m_Center: {x: 0, y: 0, z: 0} ---- !u!23 &767651610 -MeshRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 767651608} - m_Enabled: 1 - m_CastShadows: 1 - m_ReceiveShadows: 1 - m_DynamicOccludee: 1 - m_MotionVectors: 1 - m_LightProbeUsage: 1 - m_ReflectionProbeUsage: 1 - m_RenderingLayerMask: 1 - m_RendererPriority: 0 - m_Materials: - - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} - m_StaticBatchInfo: - firstSubMesh: 0 - subMeshCount: 0 - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_PreserveUVs: 0 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_StitchLightmapSeams: 0 - m_SelectedEditorRenderState: 3 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_SortingLayerID: 0 - m_SortingLayer: 0 - m_SortingOrder: 0 ---- !u!33 &767651611 -MeshFilter: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 767651608} - m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} ---- !u!4 &767651612 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 767651608} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 4 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!114 &767651613 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 767651608} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 969624a932ff84fe09dc38f9460223fb, type: 3} - m_Name: - m_EditorClassIdentifier: ---- !u!1 &1072507468 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1072507472} - - component: {fileID: 1072507471} - - component: {fileID: 1072507470} - - component: {fileID: 1072507469} - - component: {fileID: 1072507473} - m_Layer: 0 - m_Name: Cube (7) - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!65 &1072507469 -BoxCollider: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1072507468} - m_Material: {fileID: 0} - m_IsTrigger: 0 - m_Enabled: 1 - serializedVersion: 2 - m_Size: {x: 1, y: 1, z: 1} - m_Center: {x: 0, y: 0, z: 0} ---- !u!23 &1072507470 -MeshRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1072507468} - m_Enabled: 1 - m_CastShadows: 1 - m_ReceiveShadows: 1 - m_DynamicOccludee: 1 - m_MotionVectors: 1 - m_LightProbeUsage: 1 - m_ReflectionProbeUsage: 1 - m_RenderingLayerMask: 1 - m_RendererPriority: 0 - m_Materials: - - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} - m_StaticBatchInfo: - firstSubMesh: 0 - subMeshCount: 0 - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_PreserveUVs: 0 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_StitchLightmapSeams: 0 - m_SelectedEditorRenderState: 3 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_SortingLayerID: 0 - m_SortingLayer: 0 - m_SortingOrder: 0 ---- !u!33 &1072507471 -MeshFilter: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1072507468} - m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} ---- !u!4 &1072507472 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1072507468} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 1, y: 1, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 12 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!114 &1072507473 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1072507468} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 969624a932ff84fe09dc38f9460223fb, type: 3} - m_Name: - m_EditorClassIdentifier: ---- !u!1 &1159158897 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1159158900} - - component: {fileID: 1159158899} - - component: {fileID: 1159158898} - m_Layer: 0 - m_Name: Main Camera - m_TagString: MainCamera - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!81 &1159158898 -AudioListener: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1159158897} - m_Enabled: 1 ---- !u!20 &1159158899 -Camera: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1159158897} - m_Enabled: 1 - serializedVersion: 2 - m_ClearFlags: 1 - m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} - m_projectionMatrixMode: 1 - m_SensorSize: {x: 36, y: 24} - m_LensShift: {x: 0, y: 0} - m_GateFitMode: 2 - m_FocalLength: 50 - m_NormalizedViewPortRect: - serializedVersion: 2 - x: 0 - y: 0 - width: 1 - height: 1 - near clip plane: 0.3 - far clip plane: 1000 - field of view: 60 - orthographic: 0 - orthographic size: 5 - m_Depth: -1 - m_CullingMask: - serializedVersion: 2 - m_Bits: 4294967295 - m_RenderingPath: -1 - m_TargetTexture: {fileID: 0} - m_TargetDisplay: 0 - m_TargetEye: 3 - m_HDR: 1 - m_AllowMSAA: 1 - m_AllowDynamicResolution: 0 - m_ForceIntoRT: 0 - m_OcclusionCulling: 1 - m_StereoConvergence: 10 - m_StereoSeparation: 0.022 ---- !u!4 &1159158900 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1159158897} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 1, z: -10} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!1 &1310826967 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1310826971} - - component: {fileID: 1310826970} - - component: {fileID: 1310826969} - - component: {fileID: 1310826968} - - component: {fileID: 1310826972} - m_Layer: 0 - m_Name: Cube (4) - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!65 &1310826968 -BoxCollider: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1310826967} - m_Material: {fileID: 0} - m_IsTrigger: 0 - m_Enabled: 1 - serializedVersion: 2 - m_Size: {x: 1, y: 1, z: 1} - m_Center: {x: 0, y: 0, z: 0} ---- !u!23 &1310826969 -MeshRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1310826967} - m_Enabled: 1 - m_CastShadows: 1 - m_ReceiveShadows: 1 - m_DynamicOccludee: 1 - m_MotionVectors: 1 - m_LightProbeUsage: 1 - m_ReflectionProbeUsage: 1 - m_RenderingLayerMask: 1 - m_RendererPriority: 0 - m_Materials: - - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} - m_StaticBatchInfo: - firstSubMesh: 0 - subMeshCount: 0 - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_PreserveUVs: 0 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_StitchLightmapSeams: 0 - m_SelectedEditorRenderState: 3 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_SortingLayerID: 0 - m_SortingLayer: 0 - m_SortingOrder: 0 ---- !u!33 &1310826970 -MeshFilter: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1310826967} - m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} ---- !u!4 &1310826971 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1310826967} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: -3, y: 2, z: 2} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 9 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!114 &1310826972 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1310826967} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 969624a932ff84fe09dc38f9460223fb, type: 3} - m_Name: - m_EditorClassIdentifier: ---- !u!1 &1343734722 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1343734726} - - component: {fileID: 1343734725} - - component: {fileID: 1343734724} - - component: {fileID: 1343734723} - m_Layer: 5 - m_Name: Canvas - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!114 &1343734723 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1343734722} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 1301386320, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_IgnoreReversedGraphics: 1 - m_BlockingObjects: 0 - m_BlockingMask: - serializedVersion: 2 - m_Bits: 4294967295 ---- !u!114 &1343734724 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1343734722} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 1980459831, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_UiScaleMode: 0 - m_ReferencePixelsPerUnit: 100 - m_ScaleFactor: 1 - m_ReferenceResolution: {x: 800, y: 600} - m_ScreenMatchMode: 0 - m_MatchWidthOrHeight: 0 - m_PhysicalUnit: 3 - m_FallbackScreenDPI: 96 - m_DefaultSpriteDPI: 96 - m_DynamicPixelsPerUnit: 1 ---- !u!223 &1343734725 -Canvas: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1343734722} - m_Enabled: 1 - serializedVersion: 3 - m_RenderMode: 0 - m_Camera: {fileID: 0} - m_PlaneDistance: 100 - m_PixelPerfect: 0 - m_ReceivesEvents: 1 - m_OverrideSorting: 0 - m_OverridePixelPerfect: 0 - m_SortingBucketNormalizedSize: 0 - m_AdditionalShaderChannelsFlag: 0 - m_SortingLayerID: 0 - m_SortingOrder: 0 - m_TargetDisplay: 0 ---- !u!224 &1343734726 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1343734722} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 0, y: 0, z: 0} - m_Children: - - {fileID: 734465801} - m_Father: {fileID: 0} - m_RootOrder: 2 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 0, y: 0} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0, y: 0} ---- !u!1 &1377538370 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1377538374} - - component: {fileID: 1377538373} - - component: {fileID: 1377538372} - - component: {fileID: 1377538371} - - component: {fileID: 1377538375} - m_Layer: 0 - m_Name: Cube (5) - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!65 &1377538371 -BoxCollider: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1377538370} - m_Material: {fileID: 0} - m_IsTrigger: 0 - m_Enabled: 1 - serializedVersion: 2 - m_Size: {x: 1, y: 1, z: 1} - m_Center: {x: 0, y: 0, z: 0} ---- !u!23 &1377538372 -MeshRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1377538370} - m_Enabled: 1 - m_CastShadows: 1 - m_ReceiveShadows: 1 - m_DynamicOccludee: 1 - m_MotionVectors: 1 - m_LightProbeUsage: 1 - m_ReflectionProbeUsage: 1 - m_RenderingLayerMask: 1 - m_RendererPriority: 0 - m_Materials: - - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} - m_StaticBatchInfo: - firstSubMesh: 0 - subMeshCount: 0 - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_PreserveUVs: 0 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_StitchLightmapSeams: 0 - m_SelectedEditorRenderState: 3 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_SortingLayerID: 0 - m_SortingLayer: 0 - m_SortingOrder: 0 ---- !u!33 &1377538373 -MeshFilter: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1377538370} - m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} ---- !u!4 &1377538374 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1377538370} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 4, y: -3, z: 2} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 10 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!114 &1377538375 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1377538370} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 969624a932ff84fe09dc38f9460223fb, type: 3} - m_Name: - m_EditorClassIdentifier: ---- !u!1 &1393112515 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1393112519} - - component: {fileID: 1393112518} - - component: {fileID: 1393112517} - - component: {fileID: 1393112516} - - component: {fileID: 1393112520} - m_Layer: 0 - m_Name: Cube (6) - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!65 &1393112516 -BoxCollider: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1393112515} - m_Material: {fileID: 0} - m_IsTrigger: 0 - m_Enabled: 1 - serializedVersion: 2 - m_Size: {x: 1, y: 1, z: 1} - m_Center: {x: 0, y: 0, z: 0} ---- !u!23 &1393112517 -MeshRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1393112515} - m_Enabled: 1 - m_CastShadows: 1 - m_ReceiveShadows: 1 - m_DynamicOccludee: 1 - m_MotionVectors: 1 - m_LightProbeUsage: 1 - m_ReflectionProbeUsage: 1 - m_RenderingLayerMask: 1 - m_RendererPriority: 0 - m_Materials: - - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} - m_StaticBatchInfo: - firstSubMesh: 0 - subMeshCount: 0 - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_PreserveUVs: 0 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_StitchLightmapSeams: 0 - m_SelectedEditorRenderState: 3 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_SortingLayerID: 0 - m_SortingLayer: 0 - m_SortingOrder: 0 ---- !u!33 &1393112518 -MeshFilter: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1393112515} - m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} ---- !u!4 &1393112519 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1393112515} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 1, y: 4, z: 2} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 11 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!114 &1393112520 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1393112515} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 969624a932ff84fe09dc38f9460223fb, type: 3} - m_Name: - m_EditorClassIdentifier: ---- !u!1 &1467859730 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1467859734} - - component: {fileID: 1467859733} - - component: {fileID: 1467859732} - - component: {fileID: 1467859731} - - component: {fileID: 1467859735} - m_Layer: 0 - m_Name: Cube (3) - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!65 &1467859731 -BoxCollider: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1467859730} - m_Material: {fileID: 0} - m_IsTrigger: 0 - m_Enabled: 1 - serializedVersion: 2 - m_Size: {x: 1, y: 1, z: 1} - m_Center: {x: 0, y: 0, z: 0} ---- !u!23 &1467859732 -MeshRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1467859730} - m_Enabled: 1 - m_CastShadows: 1 - m_ReceiveShadows: 1 - m_DynamicOccludee: 1 - m_MotionVectors: 1 - m_LightProbeUsage: 1 - m_ReflectionProbeUsage: 1 - m_RenderingLayerMask: 1 - m_RendererPriority: 0 - m_Materials: - - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} - m_StaticBatchInfo: - firstSubMesh: 0 - subMeshCount: 0 - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_PreserveUVs: 0 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_StitchLightmapSeams: 0 - m_SelectedEditorRenderState: 3 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_SortingLayerID: 0 - m_SortingLayer: 0 - m_SortingOrder: 0 ---- !u!33 &1467859733 -MeshFilter: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1467859730} - m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} ---- !u!4 &1467859734 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1467859730} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 4, y: 4, z: 3} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 8 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!114 &1467859735 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1467859730} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 969624a932ff84fe09dc38f9460223fb, type: 3} - m_Name: - m_EditorClassIdentifier: ---- !u!1 &1468246482 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1468246486} - - component: {fileID: 1468246485} - - component: {fileID: 1468246484} - - component: {fileID: 1468246483} - - component: {fileID: 1468246487} - m_Layer: 0 - m_Name: Cube (1) - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!65 &1468246483 -BoxCollider: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1468246482} - m_Material: {fileID: 0} - m_IsTrigger: 0 - m_Enabled: 1 - serializedVersion: 2 - m_Size: {x: 1, y: 1, z: 1} - m_Center: {x: 0, y: 0, z: 0} ---- !u!23 &1468246484 -MeshRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1468246482} - m_Enabled: 1 - m_CastShadows: 1 - m_ReceiveShadows: 1 - m_DynamicOccludee: 1 - m_MotionVectors: 1 - m_LightProbeUsage: 1 - m_ReflectionProbeUsage: 1 - m_RenderingLayerMask: 1 - m_RendererPriority: 0 - m_Materials: - - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} - m_StaticBatchInfo: - firstSubMesh: 0 - subMeshCount: 0 - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_PreserveUVs: 0 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_StitchLightmapSeams: 0 - m_SelectedEditorRenderState: 3 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_SortingLayerID: 0 - m_SortingLayer: 0 - m_SortingOrder: 0 ---- !u!33 &1468246485 -MeshFilter: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1468246482} - m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} ---- !u!4 &1468246486 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1468246482} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 4, y: 2, z: 1} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 6 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!114 &1468246487 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1468246482} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 969624a932ff84fe09dc38f9460223fb, type: 3} - m_Name: - m_EditorClassIdentifier: ---- !u!1 &1927534151 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1927534155} - - component: {fileID: 1927534154} - - component: {fileID: 1927534153} - - component: {fileID: 1927534152} - - component: {fileID: 1927534156} - m_Layer: 0 - m_Name: Sphere (2) - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!135 &1927534152 -SphereCollider: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1927534151} - m_Material: {fileID: 0} - m_IsTrigger: 0 - m_Enabled: 1 - serializedVersion: 2 - m_Radius: 0.5 - m_Center: {x: 0, y: 0, z: 0} ---- !u!23 &1927534153 -MeshRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1927534151} - m_Enabled: 1 - m_CastShadows: 1 - m_ReceiveShadows: 1 - m_DynamicOccludee: 1 - m_MotionVectors: 1 - m_LightProbeUsage: 1 - m_ReflectionProbeUsage: 1 - m_RenderingLayerMask: 1 - m_RendererPriority: 0 - m_Materials: - - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} - m_StaticBatchInfo: - firstSubMesh: 0 - subMeshCount: 0 - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_PreserveUVs: 0 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_StitchLightmapSeams: 0 - m_SelectedEditorRenderState: 3 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_SortingLayerID: 0 - m_SortingLayer: 0 - m_SortingOrder: 0 ---- !u!33 &1927534154 -MeshFilter: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1927534151} - m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0} ---- !u!4 &1927534155 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1927534151} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 2, y: 3, z: 4} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 14 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!114 &1927534156 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1927534151} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 969624a932ff84fe09dc38f9460223fb, type: 3} - m_Name: - m_EditorClassIdentifier: ---- !u!1 &1972966962 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1972966966} - - component: {fileID: 1972966965} - - component: {fileID: 1972966964} - - component: {fileID: 1972966963} - - component: {fileID: 1972966967} - m_Layer: 0 - m_Name: Sphere - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!135 &1972966963 -SphereCollider: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1972966962} - m_Material: {fileID: 0} - m_IsTrigger: 0 - m_Enabled: 1 - serializedVersion: 2 - m_Radius: 0.5 - m_Center: {x: 0, y: 0, z: 0} ---- !u!23 &1972966964 -MeshRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1972966962} - m_Enabled: 1 - m_CastShadows: 1 - m_ReceiveShadows: 1 - m_DynamicOccludee: 1 - m_MotionVectors: 1 - m_LightProbeUsage: 1 - m_ReflectionProbeUsage: 1 - m_RenderingLayerMask: 1 - m_RendererPriority: 0 - m_Materials: - - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} - m_StaticBatchInfo: - firstSubMesh: 0 - subMeshCount: 0 - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_PreserveUVs: 0 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_StitchLightmapSeams: 0 - m_SelectedEditorRenderState: 3 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_SortingLayerID: 0 - m_SortingLayer: 0 - m_SortingOrder: 0 ---- !u!33 &1972966965 -MeshFilter: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1972966962} - m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0} ---- !u!4 &1972966966 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1972966962} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 3, y: 1, z: 2} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 5 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!114 &1972966967 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1972966962} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 969624a932ff84fe09dc38f9460223fb, type: 3} - m_Name: - m_EditorClassIdentifier: ---- !u!1 &2003825408 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 2003825411} - - component: {fileID: 2003825410} - - component: {fileID: 2003825409} - m_Layer: 0 - m_Name: EventSystem - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!114 &2003825409 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 2003825408} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 1077351063, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_HorizontalAxis: Horizontal - m_VerticalAxis: Vertical - m_SubmitButton: Submit - m_CancelButton: Cancel - m_InputActionsPerSecond: 10 - m_RepeatDelay: 0.5 - m_ForceModuleActive: 0 ---- !u!114 &2003825410 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 2003825408} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: -619905303, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_FirstSelected: {fileID: 0} - m_sendNavigationEvents: 1 - m_DragThreshold: 10 ---- !u!4 &2003825411 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 2003825408} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 3 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} diff --git a/Samples/ReduxSample/ObjectFinder/ObjectFinderScene.unity.meta b/Samples/ReduxSample/ObjectFinder/ObjectFinderScene.unity.meta deleted file mode 100644 index 3f9cd80a..00000000 --- a/Samples/ReduxSample/ObjectFinder/ObjectFinderScene.unity.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 27efec1d60b5b47ea892e8d510fb47e3 -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/ReduxSample/ObjectFinder/Reducer.cs b/Samples/ReduxSample/ObjectFinder/Reducer.cs deleted file mode 100644 index a0e54d10..00000000 --- a/Samples/ReduxSample/ObjectFinder/Reducer.cs +++ /dev/null @@ -1,151 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Unity.UIWidgets.Redux; - -namespace Unity.UIWidgets.Sample.Redux.ObjectFinder { - [Serializable] - public class GameObjectInfo : IEquatable { - public int id; - public string name; - - public bool Equals(GameObjectInfo other) { - if (ReferenceEquals(null, other)) { - return false; - } - if (ReferenceEquals(this, other)) { - return true; - } - return this.id == other.id && string.Equals(this.name, other.name); - } - - public override bool Equals(object obj) { - if (ReferenceEquals(null, obj)) { - return false; - } - if (ReferenceEquals(this, obj)) { - return true; - } - if (obj.GetType() != this.GetType()) { - return false; - } - return this.Equals((GameObjectInfo) obj); - } - - public override int GetHashCode() { - unchecked { - return (this.id * 397) ^ (this.name != null ? this.name.GetHashCode() : 0); - } - } - - public static bool operator ==(GameObjectInfo left, GameObjectInfo right) { - return Equals(left, right); - } - - public static bool operator !=(GameObjectInfo left, GameObjectInfo right) { - return !Equals(left, right); - } - } - - public class FinderAppState : IEquatable { - public int selected; - public List objects; - - public FinderAppState() { - this.selected = 0; - this.objects = new List(); - } - - public bool Equals(FinderAppState other) { - if (ReferenceEquals(null, other)) { - return false; - } - if (ReferenceEquals(this, other)) { - return true; - } - return this.selected == other.selected && Equals(this.objects, other.objects); - } - - public override bool Equals(object obj) { - if (ReferenceEquals(null, obj)) { - return false; - } - if (ReferenceEquals(this, obj)) { - return true; - } - if (obj.GetType() != this.GetType()) { - return false; - } - return this.Equals((FinderAppState) obj); - } - - public override int GetHashCode() { - unchecked { - return (this.selected * 397) ^ (this.objects != null ? this.objects.GetHashCode() : 0); - } - } - - public static bool operator ==(FinderAppState left, FinderAppState right) { - return Equals(left, right); - } - - public static bool operator !=(FinderAppState left, FinderAppState right) { - return !Equals(left, right); - } - } - - public static class SearchAction { - public static ThunkAction create(string keyword) { - return new ThunkAction( - displayName: "SearchAction", - action: (dispatcher, getState) => { - var objects = UnityEngine.Object.FindObjectsOfType(typeof(FinderGameObject)).Where( - obj => keyword == "" || obj.name.ToUpper().Contains(keyword.ToUpper())).Select( - obj => new GameObjectInfo {id = obj.GetInstanceID(), name = obj.name}).ToList(); - - dispatcher.dispatch(new SearchResultAction {keyword = keyword, results = objects}); - return null; - }); - } - } - - [Serializable] - public class SearchResultAction { - public string keyword; - public List results; - } - - [Serializable] - public class SelectObjectAction { - public int id; - } - - public class ObjectFinderReducer { - public static FinderAppState Reduce(FinderAppState state, object action) { - if (action is SearchResultAction) { - var resultAction = (SearchResultAction) action; - var selected = state.selected; - if (selected != 0) { - var obj = resultAction.results.Find(o => o.id == selected); - if (obj == null) { - selected = 0; - } - } - - return new FinderAppState() { - objects = resultAction.results, - selected = state.selected, - }; - } - - if (action is SelectObjectAction) { - return new FinderAppState() { - objects = state.objects, - selected = ((SelectObjectAction) action).id, - }; - } - - return state; - } - } -} \ No newline at end of file diff --git a/Samples/ReduxSample/ObjectFinder/Reducer.cs.meta b/Samples/ReduxSample/ObjectFinder/Reducer.cs.meta deleted file mode 100644 index 6d898cbe..00000000 --- a/Samples/ReduxSample/ObjectFinder/Reducer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 0a71f0cd918124d70a15139e7aaca9ac -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/ReduxSample/ObjectFinder/StoreProvider.cs b/Samples/ReduxSample/ObjectFinder/StoreProvider.cs deleted file mode 100644 index 05d95cdc..00000000 --- a/Samples/ReduxSample/ObjectFinder/StoreProvider.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Unity.UIWidgets.Redux; - -namespace Unity.UIWidgets.Sample.Redux.ObjectFinder { - public static class StoreProvider { - static Store _store; - - public static Store store { - get { - if (_store != null) { - return _store; - } - - var middlewares = new Middleware[] { - ReduxLogging.create(), - ReduxThunk.create(), - }; - _store = new Store(ObjectFinderReducer.Reduce, - new FinderAppState(), - middlewares - ); - return _store; - } - } - } -} \ No newline at end of file diff --git a/Samples/ReduxSample/ObjectFinder/StoreProvider.cs.meta b/Samples/ReduxSample/ObjectFinder/StoreProvider.cs.meta deleted file mode 100644 index 5d1b0056..00000000 --- a/Samples/ReduxSample/ObjectFinder/StoreProvider.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 7eed2508558af4e7997726a61f44a9a4 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetSample.meta b/Samples/UIWidgetSample.meta deleted file mode 100644 index 1df1375d..00000000 --- a/Samples/UIWidgetSample.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 554f0428d312c457e91dcab77ad9aa3c -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetSample/.sample.json b/Samples/UIWidgetSample/.sample.json deleted file mode 100644 index b8933138..00000000 --- a/Samples/UIWidgetSample/.sample.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "displayName":"UIWidgetSample", - "description": "Sample usage of UI Wideget", - "createSeparatePackage": false -} diff --git a/Samples/UIWidgetSample/AntialiasSVGSample.cs b/Samples/UIWidgetSample/AntialiasSVGSample.cs deleted file mode 100644 index 2a8577c6..00000000 --- a/Samples/UIWidgetSample/AntialiasSVGSample.cs +++ /dev/null @@ -1,146 +0,0 @@ -using System.Collections.Generic; -using Unity.UIWidgets.engine; -using Unity.UIWidgets.foundation; -using Unity.UIWidgets.material; -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; -using UnityEngine; -using Canvas = Unity.UIWidgets.ui.Canvas; -using Color = Unity.UIWidgets.ui.Color; -using Gradient = Unity.UIWidgets.ui.Gradient; -using Image = Unity.UIWidgets.ui.Image; -using UIWidgetRect = Unity.UIWidgets.ui.Rect; - - -public class AntialiasSVGSample : UIWidgetsPanel { - protected override void OnEnable() { - FontManager.instance.addFont(Resources.Load("MaterialIcons-Regular"), "Material Icons"); - FontManager.instance.addFont(Resources.Load("GalleryIcons"), "GalleryIcons"); - - base.OnEnable(); - } - - protected override Widget createWidget() { - Debug.Log("[SVG Testbed Panel Created]"); - - return new SVGTestbedPanelWidget(); - } -} - -public class SVGTestbedPanelWidget : StatefulWidget { - public SVGTestbedPanelWidget(Key key = null) : base(key) { } - - public override State createState() { - return new SVGTestbedPanelWidgetState(); - } -} - -public class SVGTestbedPanelWidgetState : State { - static Texture2D texture6; - - public class CurvePainter : AbstractCustomPainter { - public override void paint(Canvas canvas, Size size) { - var paint = new Paint() - { - color = new Color(0xFFFF0000), - }; - - paint.color = Colors.yellow; - paint.style = PaintingStyle.stroke; - paint.strokeWidth = 3; - - var startPoint = new Offset(0, size.height / 6); - var controlPoint1 = new Offset(size.width / 4, 0); - var controlPoint2 = new Offset(3 * size.width / 4, 0); - var endPoint = new Offset(size.width, size.height / 6); - - var path = new Path(); - path.moveTo(startPoint.dx, startPoint.dy); - path.cubicTo( - controlPoint1.dx, controlPoint1.dy, - controlPoint2.dx, controlPoint2.dy, - endPoint.dx, endPoint.dy - ); - - path.moveTo(10, 10); - path.lineTo(90, 10); - path.lineTo(10, 90); - path.lineTo(90, 90); - path.winding(PathWinding.clockwise); - path.close(); - - path.moveTo(110, 10); - path.lineTo(190, 10); - path.lineTo(110, 90); - path.lineTo(190, 90); - path.close(); - - path.addRect(UIWidgetRect.fromLTWH(10, 25, 180, 50)); - - path.addRect(UIWidgetRect.fromLTWH(200, 0, 100, 100)); - path.addRRect(RRect.fromRectAndRadius(UIWidgetRect.fromLTWH(225, 25, 50, 50), 10)); - path.winding(PathWinding.clockwise); - path.addOval(UIWidgetRect.fromLTWH(200, 50, 100, 100)); - path.winding(PathWinding.clockwise); - - - canvas.drawPath(path, paint); - - paint = new Paint { - color = new Color(0xFFFF0000), - shader = Gradient.linear( - new Offset(0, 0), - new Offset(size.width, 200), - new List() { - Colors.red, Colors.black, Colors.green - }, null, TileMode.clamp), - }; - canvas.translate(0, 200); - canvas.drawPath(path, paint); - - canvas.translate(0, 200); - // paint.maskFilter = MaskFilter.blur(BlurStyle.normal, 5); - paint.shader = new ImageShader(new Image(texture6, true), TileMode.mirror); - canvas.drawPath(path, paint); - - canvas.translate(0, 200); - paint = new Paint { - color = new Color(0xFF00FF00), - shader = Gradient.sweep( - new Offset(size.width / 2, 100), - new List() { - Colors.red, Colors.black, Colors.green, Colors.red, - }, null, TileMode.clamp, 0 * Mathf.PI / 180, 360 * Mathf.PI / 180), - }; - canvas.drawPath(path, paint); - - - paint.shader = Gradient.radial( - new Offset(size.width / 2, 100), 200f, - new List() - { - Colors.red, Colors.black, Colors.green - }, null, TileMode.clamp); - canvas.translate(0, 200); - canvas.drawPath(path, paint); - } - - public override bool shouldRepaint(CustomPainter oldDelegate) { - return true; - } - } - - public override Widget build(BuildContext context) { - texture6 = Resources.Load("6"); - - return new SingleChildScrollView( - child: new Container( - child: new CustomPaint( - painter: new CurvePainter(), - child: new Container() - ), - height: 1500 - ) - ); - } -} \ No newline at end of file diff --git a/Samples/UIWidgetSample/AntialiasSVGSample.cs.meta b/Samples/UIWidgetSample/AntialiasSVGSample.cs.meta deleted file mode 100644 index d36aac51..00000000 --- a/Samples/UIWidgetSample/AntialiasSVGSample.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 41696ca988ae5c44da3f545825faf3ac -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetSample/AsScreenSample.cs b/Samples/UIWidgetSample/AsScreenSample.cs deleted file mode 100644 index e13e1c39..00000000 --- a/Samples/UIWidgetSample/AsScreenSample.cs +++ /dev/null @@ -1,570 +0,0 @@ -using System.Collections.Generic; -using Unity.UIWidgets.foundation; -using Unity.UIWidgets.material; -using Unity.UIWidgets.painting; -using Unity.UIWidgets.rendering; -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; -using UnityEngine; -using Color = Unity.UIWidgets.ui.Color; -using Image = Unity.UIWidgets.widgets.Image; -using TextStyle = Unity.UIWidgets.painting.TextStyle; - -namespace UIWidgetsSample { - public class AsScreenSample : UIWidgetsSamplePanel { - protected override Widget createWidget() { - return new WidgetsApp( - home: new AsScreenWidget(), - pageRouteBuilder: this.pageRouteBuilder); - } - - public class AsScreenWidget : StatefulWidget { - public AsScreenWidget(Key key = null) : base(key) { - } - - public override State createState() { - return new _AsScreenState(); - } - } - - class _AsScreenState : State { - const float headerHeight = 50.0f; - - Widget _buildHeader(BuildContext context) { - return new Container( - padding: EdgeInsets.only(left: 16.0f, right: 8.0f), - height: headerHeight, - color: CLColors.header, - child: new Row( - mainAxisAlignment: MainAxisAlignment.center, - children: new List { - new Container( - child: new Text( - "All Assets", - style: new TextStyle( - fontSize: 16, - color: Color.fromARGB(100, 255, 255, 0) - ) - ) - ), - new CustomButton( - padding: EdgeInsets.only(0.0f, 0.0f, 16.0f, 0.0f), - child: new Icon( - Icons.keyboard_arrow_down, - size: 18.0f, - color: CLColors.icon2 - ) - ), - new Container( - decoration: new BoxDecoration( - color: CLColors.white, - borderRadius: BorderRadius.all(3) - ), - width: 320, - height: 36, - padding: EdgeInsets.all(10.0f), - margin: EdgeInsets.only(right: 4), - child: new EditableText( - maxLines: 1, - selectionControls: MaterialUtils.materialTextSelectionControls, - controller: new TextEditingController("Type here to search assets"), - focusNode: new FocusNode(), - style: new TextStyle( - fontSize: 16 - ), - selectionColor: Color.fromARGB(255, 255, 0, 0), - cursorColor: Color.fromARGB(255, 0, 0, 0), - backgroundCursorColor: Colors.blue - ) - ), - new Container( - decoration: new BoxDecoration( - color: CLColors.background4, - borderRadius: BorderRadius.all(2) - ), - width: 36, - height: 36, - child: new Row( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: new List { - new CustomButton( - padding: EdgeInsets.only(8.0f, 0.0f, 8.0f, 0.0f), - child: new Icon( - Icons.search, - size: 18.0f, - color: CLColors.white - ) - ) - } - ) - ), - new Container( - margin: EdgeInsets.only(left: 16, right: 16), - child: new Text( - "Learn Game Development", - style: new TextStyle( - fontSize: 12, - color: CLColors.white - ) - ) - ), - new Container( - decoration: new BoxDecoration( - border: Border.all( - color: CLColors.white - ) - ), - margin: EdgeInsets.only(right: 16), - padding: EdgeInsets.all(4), - child: new Row( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: new List { - new Text( - "Plus/Pro", - style: new TextStyle( - fontSize: 11, - color: CLColors.white - ) - ) - } - ) - ), - new Container( - margin: EdgeInsets.only(right: 16), - child: new Text( - "Impressive New Assets", - style: new TextStyle( - fontSize: 12, - color: CLColors.white - ) - ) - ), - new Container( - child: new Text( - "Shop On Old Store", - style: new TextStyle( - fontSize: 12, - color: CLColors.white - ) - ) - ), - } - ) - ); - } - - Widget _buildFooter(BuildContext context) { - return new Container( - color: CLColors.header, - margin: EdgeInsets.only(top: 50), - height: 90, - child: new Row( - mainAxisAlignment: MainAxisAlignment.center, - children: new List { - new Container( - margin: EdgeInsets.only(right: 10), - child: new Text( - "Copyright © 2018 Unity Technologies", - style: new TextStyle( - fontSize: 12, - color: CLColors.text9 - ) - ) - ), - new Container( - margin: EdgeInsets.only(right: 10), - child: new Text( - "All prices are exclusive of tax", - style: new TextStyle( - fontSize: 12, - color: CLColors.text9 - ) - ) - ), - new Container( - margin: EdgeInsets.only(right: 10), - child: new Text( - "Terms of Service and EULA", - style: new TextStyle( - fontSize: 12, - color: CLColors.text10 - ) - ) - ), - new Container( - child: new Text( - "Cookies", - style: new TextStyle( - fontSize: 12, - color: CLColors.text10 - ) - ) - ), - } - ) - ); - } - - Widget _buildBanner(BuildContext context) { - return new Container( - height: 450, - color: CLColors.white, - child: Image.network( - "https://assetstorev1-prd-cdn.unity3d.com/banner/9716cc07-748c-43cc-8809-10113119c97a.jpg", - fit: BoxFit.cover, - filterMode: FilterMode.Bilinear - ) - ); - } - - Widget _buildTopAssetsRow(BuildContext context, string title) { - var testCard = new AssetCard( - "AI Template", - "INVECTOR", - 45.0f, - 36.0f, - true, - "https://assetstorev1-prd-cdn.unity3d.com/key-image/76a549ae-de17-4536-bd96-4231ed20dece.jpg" - ); - return new Container( - margin: EdgeInsets.only(left: 98), - child: new Column( - children: new List { - new Container( - child: new Container( - margin: EdgeInsets.only(top: 50, bottom: 20), - child: new Row( - crossAxisAlignment: CrossAxisAlignment.baseline, - children: new List { - new Container( - child: new Text( - title, - style: new TextStyle( - fontSize: 24, - color: CLColors.black - ) - ) - ), - new Container( - margin: EdgeInsets.only(left: 15), - child: - new Text( - "See More", - style: new TextStyle( - fontSize: 16, - color: CLColors.text4 - ) - ) - ) - }) - ) - ), - new Row( - children: new List { - testCard, - testCard, - testCard, - testCard, - testCard, - testCard - } - ) - } - )); - } - - bool _onNotification(ScrollNotification notification, BuildContext context) { - return true; - } - - Widget _buildContentList(BuildContext context) { - return new NotificationListener( - onNotification: (ScrollNotification notification) => { - this._onNotification(notification, context); - return true; - }, - child: new Flexible( - child: new ListView( - physics: new AlwaysScrollableScrollPhysics(), - children: new List { - this._buildBanner(context), - this._buildTopAssetsRow(context, "Recommanded For You"), - this._buildTopAssetsRow(context, "Beach Day"), - this._buildTopAssetsRow(context, "Top Free Packages"), - this._buildTopAssetsRow(context, "Top Paid Packages"), - this._buildFooter(context) - } - ) - ) - ); - } - - public override Widget build(BuildContext context) { - var container = new Container( - color: CLColors.background3, - child: new Container( - color: CLColors.background3, - child: new Column( - children: new List { - this._buildHeader(context), - this._buildContentList(context), - } - ) - ) - ); - return container; - } - } - - public class AssetCard : StatelessWidget { - public AssetCard( - string name, - string category, - float price, - float priceDiscount, - bool showBadge, - string imageSrc - ) { - this.name = name; - this.category = category; - this.price = price; - this.priceDiscount = priceDiscount; - this.showBadge = showBadge; - this.imageSrc = imageSrc; - } - - public string name; - public string category; - public float price; - public float priceDiscount; - public bool showBadge; - public string imageSrc; - - public override Widget build(BuildContext context) { - var card = new Container( - margin: EdgeInsets.only(right: 45), - child: new Container( - child: new Column( - children: new List { - new Container( - decoration: new BoxDecoration( - color: CLColors.white, - borderRadius: BorderRadius.only(topLeft: 3, topRight: 3) - ), - width: 200, - height: 124, - child: Image.network( - this.imageSrc, - fit: BoxFit.fill - ) - ), - new Container( - color: CLColors.white, - width: 200, - height: 86, - padding: EdgeInsets.fromLTRB(14, 12, 14, 8), - child: new Column( - crossAxisAlignment: CrossAxisAlignment.baseline, - children: new List { - new Container( - height: 18, - padding: EdgeInsets.only(top: 3), - child: - new Text(this.category, - style: new TextStyle( - fontSize: 11, - color: CLColors.text5 - ) - ) - ), - new Container( - height: 20, - padding: EdgeInsets.only(top: 2), - child: - new Text(this.name, - style: new TextStyle( - fontSize: 14, - color: CLColors.text6 - ) - ) - ), - new Container( - height: 22, - padding: EdgeInsets.only(top: 4), - child: new Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: new List { - new Container( - child: new Row( - children: new List { - new Container( - margin: EdgeInsets.only(right: 10), - child: new Text( - "$" + this.price, - style: new TextStyle( - fontSize: 14, - color: CLColors.text7, - decoration: TextDecoration.lineThrough - ) - ) - ), - new Container( - child: new Text( - "$" + this.priceDiscount, - style: new TextStyle( - fontSize: 14, - color: CLColors.text8 - ) - ) - ) - }) - ), - this.showBadge - ? new Container( - width: 80, - height: 18, - color: CLColors.black, - child: new Row( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: new List { - new Text( - "Plus/Pro", - style: new TextStyle( - fontSize: 11, - color: CLColors.white - ) - ) - } - ) - ) - : new Container() - } - ) - ) - } - ) - ) - } - ) - ) - ); - return card; - } - } - - public class EventsWaterfallScreen : StatefulWidget { - public EventsWaterfallScreen(Key key = null) : base(key: key) { - } - - public override State createState() { - return new _EventsWaterfallScreenState(); - } - } - - class _EventsWaterfallScreenState : State { - const float headerHeight = 80.0f; - - float _offsetY = 0.0f; - - Widget _buildHeader(BuildContext context) { - return new Container( - padding: EdgeInsets.only(left: 16.0f, right: 8.0f), - // color: CLColors.blue, - height: headerHeight - this._offsetY, - child: new Row( - children: new List { - new Flexible( - flex: 1, - fit: FlexFit.tight, - child: new Text( - "Today", - style: new TextStyle( - fontSize: (34.0f / headerHeight) * - (headerHeight - this._offsetY), - color: CLColors.white - ) - )), - new CustomButton( - padding: EdgeInsets.only(8.0f, 0.0f, 8.0f, 0.0f), - child: new Icon( - Icons.notifications, - size: 18.0f, - color: CLColors.icon2 - ) - ), - new CustomButton( - padding: EdgeInsets.only(8.0f, 0.0f, 16.0f, 0.0f), - child: new Icon( - Icons.account_circle, - size: 18.0f, - color: CLColors.icon2 - ) - ) - } - ) - ); - } - - bool _onNotification(ScrollNotification notification, BuildContext context) { - float pixels = notification.metrics.pixels; - if (pixels >= 0.0) { - if (pixels <= headerHeight) { - this.setState(() => { this._offsetY = pixels / 2.0f; }); - } - } - else { - if (this._offsetY != 0.0) { - this.setState(() => { this._offsetY = 0.0f; }); - } - } - - return true; - } - - - Widget _buildContentList(BuildContext context) { - return new NotificationListener( - onNotification: (ScrollNotification notification) => { - this._onNotification(notification, context); - return true; - }, - child: new Flexible( - child: new Container( - // color: CLColors.green, - child: ListView.builder( - itemCount: 20, - itemExtent: 100, - physics: new AlwaysScrollableScrollPhysics(), - itemBuilder: (BuildContext context1, int index) => { - return new Container( - color: Color.fromARGB(255, (index * 10) % 256, (index * 20) % 256, - (index * 30) % 256) - ); - } - ) - ) - ) - ); - } - - public override Widget build(BuildContext context) { - var container = new Container( - // color: CLColors.background1, - child: new Container( - // color: CLColors.background1, - child: new Column( - children: new List { - this._buildHeader(context), - this._buildContentList(context) - } - ) - ) - ); - return container; - } - } - } -} \ No newline at end of file diff --git a/Samples/UIWidgetSample/AsScreenSample.cs.meta b/Samples/UIWidgetSample/AsScreenSample.cs.meta deleted file mode 100644 index be668b07..00000000 --- a/Samples/UIWidgetSample/AsScreenSample.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 71d034a309904459c9016f0f17734267 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetSample/BenchMarkLayout.cs b/Samples/UIWidgetSample/BenchMarkLayout.cs deleted file mode 100644 index 3a1c9248..00000000 --- a/Samples/UIWidgetSample/BenchMarkLayout.cs +++ /dev/null @@ -1,149 +0,0 @@ -using System.Collections.Generic; -using Unity.UIWidgets.foundation; -using Unity.UIWidgets.material; -using Unity.UIWidgets.painting; -using Unity.UIWidgets.rendering; -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; -using UnityEngine; -using Color = Unity.UIWidgets.ui.Color; -using FontStyle = Unity.UIWidgets.ui.FontStyle; -using Material = Unity.UIWidgets.material.Material; - -namespace UIWidgetsSample { - public class BenchMarkLayout : UIWidgetsSamplePanel { - protected override Widget createWidget() { - return new MaterialApp( - showPerformanceOverlay: false, - home: new Material( - child: new BenchMarkLayoutWidget()), - builder: (_, child) => { - return new Builder(builder: - context => { - return new MediaQuery( - data: MediaQuery.of(context).copyWith( - textScaleFactor: 1.0f - ), - child: child); - }); - }); - } - - protected override void OnEnable() { - base.OnEnable(); - FontManager.instance.addFont(Resources.Load(path: "MaterialIcons-Regular"), "Material Icons"); - } - } - - class BenchMarkLayoutWidget : StatefulWidget { - public BenchMarkLayoutWidget(Key key = null) : base(key) { - } - - public override State createState() { - return new BenchMarkLayoutWidgetState(); - } - } - - class BenchMarkLayoutWidgetState : State { - int width = 260; - bool visible = true; - - Widget richtext = new Container( - child: new RichText( - text: new TextSpan("", children: - new List() { - new TextSpan("Real-time 3D revolutioni\t淡粉色的方式地方\tzes the animation pipeline "), - new TextSpan(style: new TextStyle(color: Color.fromARGB(255, 255, 0, 0)), - text: "for Disney Television Animation's\t “Baymax Dreams"), - new TextSpan("\t", style: new TextStyle(color: Colors.black)), - new TextSpan(" Unity Widgets"), - new TextSpan(" Text"), - new TextSpan("Real-time 3D revolutionizes the animation pipeline "), - new TextSpan(style: new TextStyle(color: Color.fromARGB(125, 255, 0, 0)), - text: "Transparent Red Text\n\n"), - new TextSpan("Bold Text Test Bold Textfs Test: FontWeight.w70\n\n"), - new TextSpan(style: new TextStyle(fontStyle: FontStyle.italic), - text: "This is FontStyle.italic Text This is FontStyle.italic Text\n\n"), - new TextSpan( - style: new TextStyle(fontStyle: FontStyle.italic, fontWeight: FontWeight.w700), - text: - "This is FontStyle.italic And 发撒放豆腐sad 发生的 Bold Text This is FontStyle.italic And Bold Text\n\n"), - new TextSpan(style: new TextStyle(fontSize: 18), - text: "FontSize 18: Get a named matrix value from the shader.\n\n"), - new TextSpan(style: new TextStyle(fontSize: 24), - text: "Emoji \ud83d\ude0a\ud83d\ude0b\t\ud83d\ude0d\ud83d\ude0e\ud83d\ude00"), - new TextSpan(style: new TextStyle(fontSize: 14), - text: "Emoji \ud83d\ude0a\ud83d\ude0b\ud83d\ude0d\ud83d\ude0e\ud83d\ude00 Emoji"), - new TextSpan(style: new TextStyle(fontSize: 18), - text: "Emoji \ud83d\ude01\ud83d\ude02\ud83d\ude03\ud83d\ude04\ud83d\ude05"), - new TextSpan(style: new TextStyle(fontSize: 18), - text: "\ud83d\ude01\ud83d\ude02\ud83d\ude03\ud83d\ude04\ud83d\ude05"), - new TextSpan(style: new TextStyle(fontSize: 18), - text: "\ud83d\ude01\ud83d\ude02\ud83d\ude03\ud83d\ude04\ud83d\ude05"), - new TextSpan(style: new TextStyle(fontSize: 18), - text: "\ud83d\ude01\ud83d\ude02\ud83d\ude03\ud83d\ude04\ud83d\ude05"), - new TextSpan(style: new TextStyle(fontSize: 18), - text: "\ud83d\ude01\ud83d\ude02\ud83d\ude03\ud83d\ude04\ud83d\ude05"), - new TextSpan(style: new TextStyle(fontSize: 24), - text: - "Emoji \ud83d\ude06\ud83d\ude1C\ud83d\ude18\ud83d\ude2D\ud83d\ude0C\ud83d\ude1E\n\n"), - new TextSpan(style: new TextStyle(fontSize: 14), - text: "FontSize 14"), - }) - ) - ); - - public override Widget build(BuildContext context) { - Widget buttons = new Column( - mainAxisAlignment: MainAxisAlignment.end, - children: new List { - new Text($"Width: {this.width}"), - new RaisedButton( - onPressed: () => { this.setState(() => { this.width += 10; }); }, - child: new Text("Add Width") - ), - new Divider(), - new RaisedButton( - onPressed: () => { this.setState(() => { this.width -= 10; }); }, - child: new Text("Dec Width") - ), - new Divider(), - new RaisedButton( - onPressed: () => { this.setState(() => { this.visible = true; }); }, - child: new Text("Show") - ), - new Divider(), - new RaisedButton( - onPressed: () => { this.setState(() => { this.visible = false; }); }, - child: new Text("Hide") - ) - } - ); - Widget child = new Column( - children: new List { - this.visible ? this.richtext : new Text(""), - this.visible - ? new Text( - "Very Very Very Very Very Very Very Very Very Very Very Very Very Very\nVery Very Very Very Very Very Very Very Very Very Very Long Text", - maxLines: 3, overflow: TextOverflow.ellipsis, textAlign: TextAlign.justify - ) - : new Text("") - }); - child = new Stack( - children: new List { - child, - buttons - } - ); - child = new Container( - width: this.width, - color: Colors.black12, - child: child - ); - child = new Center( - child: child - ); - return child; - } - } -} \ No newline at end of file diff --git a/Samples/UIWidgetSample/BenchMarkLayout.cs.meta b/Samples/UIWidgetSample/BenchMarkLayout.cs.meta deleted file mode 100644 index e20edd81..00000000 --- a/Samples/UIWidgetSample/BenchMarkLayout.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: cba57cf034e23904ab2f929598f4cb45 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetSample/CustomPaintSample.cs b/Samples/UIWidgetSample/CustomPaintSample.cs deleted file mode 100644 index 31a95b2b..00000000 --- a/Samples/UIWidgetSample/CustomPaintSample.cs +++ /dev/null @@ -1,69 +0,0 @@ -using Unity.UIWidgets.foundation; -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; - -namespace UIWidgetsSample { - public class CustomPaintSample : UIWidgetsSamplePanel { - protected override Widget createWidget() { - return new WidgetsApp( - home: new Unity.UIWidgets.widgets.CustomPaint( - child: new Container(width: 300, height: 300, color: new Color(0XFFFFFFFF)), - foregroundPainter: new GridPainter(null) - ), - pageRouteBuilder: this.pageRouteBuilder); - } - } - - public class GridPainter : AbstractCustomPainter { - public GridPainter(Listenable repaint) : base(repaint) { - } - - public override void paint(Canvas canvas, Size size) { - int numGrid = 4; - var paint = new Paint(); - paint.color = new Color(0xFFFF0000); - paint.strokeWidth = 2; - paint.style = PaintingStyle.stroke; - for (int i = 1; i < numGrid; i++) { - float offsetY = size.height * i / numGrid; - canvas.drawLine(new Offset(0, offsetY), new Offset(size.width, offsetY), - paint); - } - - for (int i = 1; i < numGrid; i++) { - float offsetx = size.width * i / numGrid; - canvas.drawLine(new Offset(offsetx, 0), new Offset(offsetx, size.height), - paint); - } - - - // draw a arrow line - canvas.save(); - canvas.rotate(0.4f); - canvas.scale(2, 2); - canvas.translate(50, 50); - canvas.drawLine(new Offset(0, 0), new Offset(100, 0), - new Paint() { - color = new Color(0xFFFF0000), - strokeWidth = 2, - style = PaintingStyle.stroke - }); - var path = new Path(); - var arrowPaint = new Paint() { - color = new Color(0xFFFF0000), - style = PaintingStyle.fill - }; - path.moveTo(100, 0); - path.lineTo(100, 5); - path.lineTo(120, 0); - path.lineTo(100, -5); - path.close(); - canvas.drawPath(path, arrowPaint); - canvas.restore(); - } - - public override bool shouldRepaint(CustomPainter oldDelegate) { - return false; - } - } -} \ No newline at end of file diff --git a/Samples/UIWidgetSample/CustomPaintSample.cs.meta b/Samples/UIWidgetSample/CustomPaintSample.cs.meta deleted file mode 100644 index 80cd3418..00000000 --- a/Samples/UIWidgetSample/CustomPaintSample.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 5debfd6de8ea942d487383a56aad8491 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetSample/DragDropSample.cs b/Samples/UIWidgetSample/DragDropSample.cs deleted file mode 100644 index 792f3513..00000000 --- a/Samples/UIWidgetSample/DragDropSample.cs +++ /dev/null @@ -1,151 +0,0 @@ -using System.Collections.Generic; -using Unity.UIWidgets.foundation; -using Unity.UIWidgets.rendering; -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; -using UnityEngine; - -namespace UIWidgetsSample { - public class DragDropSample : UIWidgetsSamplePanel { - protected override Widget createWidget() { - return new WidgetsApp( - home: new DragDropApp(), - pageRouteBuilder: this.pageRouteBuilder - ); - } - - class DragDropApp : StatefulWidget { - public DragDropApp(Key key = null) : base(key) { - } - - public override State createState() { - return new DragDropState(); - } - } - - class DragTargetWidget : StatefulWidget { - public DragTargetWidget(Key key = null) : base(key) { - } - - public override State createState() { - return new DragTargetWidgetState(); - } - } - - class DragTargetWidgetState : State { - int value; - - public override Widget build(BuildContext context) { - return new Positioned( - left: 40.0f, - bottom: 40.0f, - child: new DragTarget( - onAccept: obj => { - Debug.Log("ON ACCEPTED ..." + obj); - this.setState(() => { this.value += obj; }); - }, - builder: (inner_context2, accepted, rejected) => { - return new Container( - width: 40.0f, - height: 40.0f, - constraints: BoxConstraints.tight(new Size(40, 40)), - color: CLColors.red, - child: new Center(child: new Text("" + this.value)) - ); - } - ) - ); - } - } - - class DragDropState : State { - public override Widget build(BuildContext context) { - var entries = new List(); - - var entry_bg = new OverlayEntry( - inner_context => new Container( - color: CLColors.white - )); - - var entry = new OverlayEntry( - inner_context => new Positioned( - left: 0.0f, - bottom: 0.0f, - child: new GestureDetector( - onTap: () => { }, - child: new Draggable( - 5, - child: new Container( - color: CLColors.blue, - width: 30.0f, - height: 30.0f, - constraints: BoxConstraints.tight(new Size(30, 30)), - child: new Center(child: new Text("5")) - ), - feedback: new Container( - color: CLColors.green, - width: 30.0f, - height: 30.0f), - //maxSimultaneousDrags: 1, - childWhenDragging: new Container( - color: CLColors.black, - width: 30.0f, - height: 30.0f, - constraints: BoxConstraints.tight(new Size(30, 30)) - ) - ) - ) - ) - ); - - var entry3 = new OverlayEntry( - inner_context => new Positioned( - left: 0.0f, - bottom: 40.0f, - child: new GestureDetector( - onTap: () => { }, - child: - new Draggable( - 8, - child: new Container( - color: CLColors.background4, - width: 30.0f, - height: 30.0f, - constraints: BoxConstraints.tight(new Size(30, 30)), - child: new Center(child: new Text("8"))) - , - feedback: new Container( - color: CLColors.green, - width: 30.0f, - height: 30.0f), - maxSimultaneousDrags: 1, - childWhenDragging: new Container( - color: CLColors.black, - width: 30.0f, - height: 30.0f, - constraints: BoxConstraints.tight(new Size(30, 30)) - ) - ) - ) - ) - ); - - var entry2 = new OverlayEntry( - inner_context => new DragTargetWidget() - ); - - entries.Add(entry_bg); - entries.Add(entry); - entries.Add(entry2); - entries.Add(entry3); - - return new Container( - color: CLColors.white, - child: new Overlay( - initialEntries: entries - ) - ); - } - } - } -} \ No newline at end of file diff --git a/Samples/UIWidgetSample/DragDropSample.cs.meta b/Samples/UIWidgetSample/DragDropSample.cs.meta deleted file mode 100644 index b0c9963f..00000000 --- a/Samples/UIWidgetSample/DragDropSample.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: d01ae8029ff2f4e54a5e9c1a9672e5dc -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetSample/Editor.meta b/Samples/UIWidgetSample/Editor.meta deleted file mode 100644 index c8206f3b..00000000 --- a/Samples/UIWidgetSample/Editor.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 0ae90c343ee0e4f7daf768fe6383340f -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetSample/Editor/DragNDrop.meta b/Samples/UIWidgetSample/Editor/DragNDrop.meta deleted file mode 100644 index 893a6dc1..00000000 --- a/Samples/UIWidgetSample/Editor/DragNDrop.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 087f4b1b8d7aa4e93bca841df8a1d603 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetSample/Editor/DragNDrop/CustomInspectorSample.cs b/Samples/UIWidgetSample/Editor/DragNDrop/CustomInspectorSample.cs deleted file mode 100644 index d15f5aed..00000000 --- a/Samples/UIWidgetSample/Editor/DragNDrop/CustomInspectorSample.cs +++ /dev/null @@ -1,374 +0,0 @@ -using System.Collections.Generic; -using Unity.UIWidgets.editor; -using Unity.UIWidgets.foundation; -using Unity.UIWidgets.material; -using Unity.UIWidgets.painting; -using Unity.UIWidgets.rendering; -using Unity.UIWidgets.service; -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; -using UnityEditor; -using UnityEngine; -using Color = Unity.UIWidgets.ui.Color; -using Transform = UnityEngine.Transform; - -namespace UIWidgetsSample.DragNDrop { - public class CustomInspectorSample : UIWidgetsEditorWindow { - [MenuItem("UIWidgetsTests/Drag&Drop/Custom Inspector")] - public static void ShowEditorWindow() { - var window = GetWindow(); - window.titleContent.text = "Custom Inspector Sample"; - } - - protected override void OnEnable() { - FontManager.instance.addFont(Resources.Load("MaterialIcons-Regular"), "Material Icons"); - FontManager.instance.addFont(Resources.Load("GalleryIcons"), "GalleryIcons"); - - base.OnEnable(); - } - - protected override Widget createWidget() { - Debug.Log("[ WIDGET RECREATED ]"); - return new MaterialApp( - home: new CustomInspectorSampleWidget(), - darkTheme: new ThemeData(primaryColor: Colors.black26) - ); - } - } - - public class CustomInspectorSampleWidget : StatefulWidget { - public CustomInspectorSampleWidget(Key key = null) : base(key) { - } - - public override State createState() { - return new CustomInspectorSampleWidgetState(); - } - } - - public class CustomInspectorSampleWidgetState : State { - GameObject objectRef; - Transform transformRef; - - TextEditingController textController = new TextEditingController(); - - public override void initState() { - this.textController.addListener(() => { - var text = this.textController.text.ToLower(); - this.textController.value = this.textController.value.copyWith( - text: text, - selection: new TextSelection(baseOffset: text.Length, extentOffset: text.Length), - composing: TextRange.empty - ); - }); - base.initState(); - } - - enum ETransfrom { - Position, - Rotation, - Scale - } - - // make custom control of cursor position in TextField. - int oldCursorPosition = 0; - - // The decimal point input-and-parse exists problem. - Widget getCardRow(ETransfrom type, bool hasRef) { - var xValue = hasRef - ? type == ETransfrom.Position - ? this.transformRef.position.x.ToString() - : type == ETransfrom.Rotation - ? this.transformRef.localEulerAngles.x.ToString() - : this.transformRef.localScale.x.ToString() - : ""; - // Using individual TextEditingController to control TextField cursor position. - var xValueController = TextEditingController.fromValue( - new TextEditingValue(xValue, TextSelection.collapsed(this.oldCursorPosition)) - ); - - var yValue = hasRef - ? type == ETransfrom.Position - ? this.transformRef.position.y.ToString() - : type == ETransfrom.Rotation - ? this.transformRef.localEulerAngles.y.ToString() - : this.transformRef.localScale.y.ToString() - : ""; - - var yValueController = TextEditingController.fromValue( - new TextEditingValue(yValue, TextSelection.collapsed(this.oldCursorPosition)) - ); - - var zValue = hasRef - ? type == ETransfrom.Position - ? this.transformRef.position.z.ToString() - : type == ETransfrom.Rotation - ? this.transformRef.localEulerAngles.z.ToString() - : this.transformRef.localScale.z.ToString() - : ""; - - var zValueController = TextEditingController.fromValue( - new TextEditingValue(zValue, TextSelection.collapsed(this.oldCursorPosition)) - ); - - return new Column( - children: new List { - new Container( - padding: EdgeInsets.symmetric(vertical: 8f), - child: new Align( - alignment: Alignment.centerLeft, - child: new Text( - type == ETransfrom.Position ? "Position" : - type == ETransfrom.Rotation ? "Rotation" : "Scale", - style: new TextStyle(fontSize: 16.0f) - ) - ) - ), - new Row( - children: new List { - new Flexible( - flex: 8, - child: new Container( - decoration: new BoxDecoration( - color: new Color(0xfff5f5f5)), - child: new TextField( - decoration: new InputDecoration( - border: new UnderlineInputBorder(), - contentPadding: - EdgeInsets.symmetric( - horizontal: 10f, vertical: 5f), - labelText: "X" - ), - controller: xValueController, - onChanged: hasRef - ? (str) => { - // While the TextField value changed, try to parse and assign to transformRef. - this.setState(() => { - float result = 0; - float.TryParse(str, out result); - if (str == "" || str[0] == '0') { - this.oldCursorPosition = 1; - } - else { - this.oldCursorPosition = - xValueController.selection.startPos.offset; - } - - switch (type) { - case ETransfrom.Position: - var newPos = this.transformRef.position; - newPos.x = result; - this.transformRef.position = newPos; - break; - case ETransfrom.Rotation: - var newRot = this.transformRef.localEulerAngles; - newRot.x = result; - this.transformRef.localEulerAngles = newRot; - break; - case ETransfrom.Scale: - var newScale = this.transformRef.localScale; - newScale.x = result; - this.transformRef.localScale = newScale; - break; - } - }); - } - : (ValueChanged) null - ) - )), - new Flexible( - child: new Container() - ), - new Flexible( - flex: 8, - child: new Container( - decoration: new BoxDecoration( - color: new Color(0xfff5f5f5)), - child: new TextField( - decoration: new InputDecoration( - border: new UnderlineInputBorder(), - contentPadding: - EdgeInsets.symmetric( - horizontal: 10f, vertical: 5f), - labelText: "Y" - ), - controller: yValueController, - onChanged: hasRef - ? (str) => { - this.setState(() => { - float result = 0; - float.TryParse(str, out result); - if (str == "" || str[0] == '0') { - this.oldCursorPosition = 1; - } - else { - this.oldCursorPosition = - yValueController.selection.startPos.offset; - } - - switch (type) { - case ETransfrom.Position: - var newPos = this.transformRef.position; - newPos.y = result; - this.transformRef.position = newPos; - break; - case ETransfrom.Rotation: - var newRot = this.transformRef.localEulerAngles; - newRot.y = result; - this.transformRef.localEulerAngles = newRot; - break; - case ETransfrom.Scale: - var newScale = this.transformRef.localScale; - newScale.y = result; - this.transformRef.localScale = newScale; - break; - } - }); - } - : (ValueChanged) null - ) - )), - new Flexible( - child: new Container() - ), - new Flexible( - flex: 8, - child: new Container( - decoration: new BoxDecoration( - color: new Color(0xfff5f5f5)), - child: new TextField( - decoration: new InputDecoration( - border: new UnderlineInputBorder(), - contentPadding: - EdgeInsets.symmetric( - horizontal: 10f, vertical: 5f), - labelText: "Z" - ), - controller: zValueController, - onChanged: hasRef - ? (str) => { - this.setState(() => { - float result = 0; - float.TryParse(str, out result); - if (str == "" || str[0] == '0') { - this.oldCursorPosition = 1; - } - else { - this.oldCursorPosition = - zValueController.selection.startPos.offset; - } - - switch (type) { - case ETransfrom.Position: - var newPos = this.transformRef.position; - newPos.z = result; - this.transformRef.position = newPos; - break; - case ETransfrom.Rotation: - var newRot = this.transformRef.localEulerAngles; - newRot.z = result; - this.transformRef.localEulerAngles = newRot; - break; - case ETransfrom.Scale: - var newScale = this.transformRef.localScale; - newScale.z = result; - this.transformRef.localScale = newScale; - break; - } - }); - } - : (ValueChanged) null - ) - )) - } - ) - } - ); - } - - public override Widget build(BuildContext context) { - return new Theme( - data: new ThemeData( - appBarTheme: new AppBarTheme( - color: Colors.purple - ), - cardTheme: new CardTheme( - color: Colors.white, - elevation: 2.0f - ) - ), - child: new Scaffold( - appBar: new AppBar(title: new Text("Custom Inspector")), - body: new ListView( - children: new List { - new Card( - clipBehavior: Clip.antiAlias, - margin: EdgeInsets.all(20.0f), - shape: new RoundedRectangleBorder( - borderRadius: BorderRadius.circular(20.0f) - ), - child: new Container( - padding: EdgeInsets.symmetric(vertical: 20f, horizontal: 10f), - child: new Column( - mainAxisSize: MainAxisSize.min, - children: new List { - new UnityObjectDetector( - // When receiving a GameObject, get its transfrom. - onRelease: (details) => { - this.setState(() => { - var gameObj = details.objectReferences[0] as GameObject; - if (gameObj) { - this.objectRef = gameObj; - if (this.objectRef) { - this.transformRef = this.objectRef.transform; - } - } - }); - }, - child: new ListTile( - title: new Text( - this.objectRef == null ? "Object Name" : this.objectRef.name, - style: new TextStyle(fontSize: 28.0f)), - subtitle: new Text("Drag an object here", - style: new TextStyle(fontSize: 16.0f)), - contentPadding: EdgeInsets.symmetric(horizontal: 10f) - ) - ), - new Card( - clipBehavior: Clip.antiAlias, - shape: new RoundedRectangleBorder( - borderRadius: BorderRadius.circular(20.0f) - ), - child: new Container( - padding: EdgeInsets.symmetric(horizontal: 10.0f), - child: new Column( - mainAxisSize: MainAxisSize.min, - children: new List { - new Container( - padding: EdgeInsets.only(top: 20f), - child: new Align( - alignment: Alignment.centerLeft, - child: new Text("Transform", - style: new TextStyle(fontSize: 20.0f)) - ) - ), - this.getCardRow(ETransfrom.Position, - this.objectRef != null), - this.getCardRow(ETransfrom.Rotation, - this.objectRef != null), - this.getCardRow(ETransfrom.Scale, this.objectRef != null), - new Container(padding: EdgeInsets.only(bottom: 20f)) - } - ) - ) - ), - } - ) - ) - ) - } - ) - ) - ); - } - } -} \ No newline at end of file diff --git a/Samples/UIWidgetSample/Editor/DragNDrop/CustomInspectorSample.cs.meta b/Samples/UIWidgetSample/Editor/DragNDrop/CustomInspectorSample.cs.meta deleted file mode 100644 index e775529b..00000000 --- a/Samples/UIWidgetSample/Editor/DragNDrop/CustomInspectorSample.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 5978da8ac1ccd4638bfe3d8425443807 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetSample/Editor/DragNDrop/UnityObjectDetectorSample.cs b/Samples/UIWidgetSample/Editor/DragNDrop/UnityObjectDetectorSample.cs deleted file mode 100644 index 97cf1d95..00000000 --- a/Samples/UIWidgetSample/Editor/DragNDrop/UnityObjectDetectorSample.cs +++ /dev/null @@ -1,171 +0,0 @@ -using System.Collections.Generic; -using Unity.UIWidgets.animation; -using Unity.UIWidgets.editor; -using Unity.UIWidgets.foundation; -using Unity.UIWidgets.material; -using Unity.UIWidgets.painting; -using Unity.UIWidgets.widgets; -using UnityEditor; -using UnityEngine; -using Color = Unity.UIWidgets.ui.Color; - -namespace UIWidgetsSample.DragNDrop { - public class UnityObjectDetectorSample : UIWidgetsEditorWindow { - [MenuItem("UIWidgetsTests/Drag&Drop/UnityObject Detector")] - public static void ShowEditorWindow() { - var window = GetWindow(); - window.titleContent.text = "UnityObject Detector Sample"; - } - - protected override Widget createWidget() { - Debug.Log("[ WIDGET RECREATED ]"); - return new WidgetsApp( - home: new UnityObjectDetectorSampleWidget(), - pageRouteBuilder: (RouteSettings settings, WidgetBuilder builder) => - new PageRouteBuilder( - settings: settings, - pageBuilder: (BuildContext context, Animation animation, - Animation secondaryAnimation) => builder(context) - ) - ); - } - } - - public class UnityObjectDetectorSampleWidget : StatefulWidget { - public UnityObjectDetectorSampleWidget(Key key = null) : base(key) { - } - - public override State createState() { - return new UnityObjectDetectorSampleWidgetState(); - } - } - - public class UnityObjectDetectorSampleWidgetState : State { - readonly Color highlightColor = Color.fromARGB(255, 88, 127, 219); - readonly Color defaultColor = Color.fromARGB(255, 211, 211, 211); - readonly List isHighlighted = new List { }; - readonly List objects = new List(); - - List getUnityObjectDetectorList(int count) { - if (this.isHighlighted.isEmpty()) { - for (int i = 0; i < count; i++) { - this.isHighlighted.Add(false); - } - } - - if (this.objects.isEmpty()) { - for (int i = 0; i < count; i++) { - this.objects.Add(null); - } - } - - List widgetList = new List(); - widgetList.Add(this.getGapBox("Generated List with UnityObjectDetector")); - - for (int i = 0; i < count; i++) { - var _i = i; - - Widget widget = new Container( - decoration: this.isHighlighted[_i] - ? new BoxDecoration(color: this.highlightColor) - : new BoxDecoration(color: this.defaultColor), - height: 100f, - child: new UnityObjectDetector( - onEnter: () => { - Debug.Log("Widget " + _i + " onEnter"); - this.setState(() => { this.isHighlighted[_i] = true; }); - }, - onRelease: (details) => { - Debug.Log("Widget " + _i + " onRelease"); - this.setState(() => { - this.isHighlighted[_i] = false; - this.objects[_i] = details.objectReferences; - }); - }, - onExit: () => { - Debug.Log("Widget " + _i + " onExit"); - this.setState(() => { this.isHighlighted[_i] = false; }); - }, - child: new Center( - child: new Text(this.objects[_i] != null - ? this.getNameString(this.objects[_i]) - : "[Drop/Multi-Drop Here]") - ) - ) - ); - - widgetList.Add(widget); - if (_i != count - 1) { - widgetList.Add(this.getGapBox()); - } - } - - return widgetList; - } - - string getNameString(Object[] objs) { - var str = ""; - for (int i = 0; i < objs.Length; i++) { - str += "[" + objs[i].name + "]"; - if (i != objs.Length - 1) { - str += "\n"; - } - } - - return str; - } - - Widget getGapBox(string str = "") { - return new Container( - height: 25, - child: str == "" - ? null - : new Center( - child: new Text(str) - ) - ); - } - - bool highlight; - Object[] objRef; - - public override Widget build(BuildContext context) { - var columnList = new List(); - - columnList.Add(this.getGapBox()); - columnList.AddRange(this.getUnityObjectDetectorList(3)); - columnList.AddRange( - new List { - this.getGapBox("With Listener"), - new Container( - decoration: this.highlight - ? new BoxDecoration(color: this.highlightColor) - : new BoxDecoration(color: this.defaultColor), - height: 100f, - child: new Listener( - onPointerDragFromEditorEnter: (evt) => { this.setState(() => { this.highlight = true; }); }, - onPointerDragFromEditorExit: (evt) => { this.setState(() => { this.highlight = false; }); }, - // onPointerDragFromEditorHover: (evt) => { }, - onPointerDragFromEditorRelease: (evt) => { - this.objRef = evt.objectReferences; - this.setState(() => { this.highlight = false; }); - }, - child: new Center( - child: new Text(this.objRef != null - ? this.getNameString(this.objRef) - : "[Drop/Multi-Drop Here]") - ) - ) - ) - } - ); - - return new Container( - padding: EdgeInsets.symmetric(horizontal: 25f), - color: Colors.grey, - child: new ListView( - children: columnList - )); - } - } -} \ No newline at end of file diff --git a/Samples/UIWidgetSample/Editor/DragNDrop/UnityObjectDetectorSample.cs.meta b/Samples/UIWidgetSample/Editor/DragNDrop/UnityObjectDetectorSample.cs.meta deleted file mode 100644 index 6bea379b..00000000 --- a/Samples/UIWidgetSample/Editor/DragNDrop/UnityObjectDetectorSample.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 2948179a390a944a9a44b7f86cfa3c57 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetSample/Editor/UIWidgetsSample.Editor.asmdef b/Samples/UIWidgetSample/Editor/UIWidgetsSample.Editor.asmdef deleted file mode 100644 index 05a68793..00000000 --- a/Samples/UIWidgetSample/Editor/UIWidgetsSample.Editor.asmdef +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "UIWidgetsSample.Editor", - "references": [ - "Unity.UIWidgets", - "UIWidgetsSample"], - "optionalUnityReferences": [], - "includePlatforms": [ - "Editor" - ], - "excludePlatforms": [] -} \ No newline at end of file diff --git a/Samples/UIWidgetSample/Editor/UIWidgetsSample.Editor.asmdef.meta b/Samples/UIWidgetSample/Editor/UIWidgetsSample.Editor.asmdef.meta deleted file mode 100644 index b875e7cb..00000000 --- a/Samples/UIWidgetSample/Editor/UIWidgetsSample.Editor.asmdef.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 3d357564df62f4f7286d70a70fe8b98b -AssemblyDefinitionImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetSample/ExpansionPanelSample.cs b/Samples/UIWidgetSample/ExpansionPanelSample.cs deleted file mode 100644 index cc25d2b3..00000000 --- a/Samples/UIWidgetSample/ExpansionPanelSample.cs +++ /dev/null @@ -1,158 +0,0 @@ -using System.Collections.Generic; -using Unity.UIWidgets.engine; -using Unity.UIWidgets.foundation; -using Unity.UIWidgets.material; -using Unity.UIWidgets.rendering; -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; -using UnityEngine; -using Material = Unity.UIWidgets.material.Material; - -namespace UIWidgetsSample { - public class ExpansionPanelSample : UIWidgetsSamplePanel { - int testCaseId = 1; - - readonly List testCases = new List { - new SingleChildScrollWidget(), - new ExpansionPanelWidget() - }; - - protected override Widget createWidget() { - return new WidgetsApp( - home: this.testCases[this.testCaseId], - pageRouteBuilder: this.pageRouteBuilder); - } - } - - - class SingleChildScrollWidget : StatefulWidget { - public SingleChildScrollWidget(Key key = null) : base(key) { - } - - public override State createState() { - return new SingleChildScrollWidgetState(); - } - } - - class SingleChildScrollWidgetState : State { - public override Widget build(BuildContext context) { - return new Material( - child: new SingleChildScrollView( - child: new Container( - width: 40.0f, - height: 40.0f, - constraints: BoxConstraints.tight(new Size(40, 600)), - color: CLColors.red, - child: new Center(child: new Text("Beijing")) - ) - ) - ); - } - } - - - class ExpansionPanelWidget : StatefulWidget { - public ExpansionPanelWidget(Key key = null) : base(key) { - } - - public override State createState() { - return new ExpansionPanelWidgetState(); - } - } - - class ExpansionPanelWidgetState : State { - readonly List isExpand = new List {false, false}; - - public override Widget build(BuildContext context) { - return new Material( - child: new SingleChildScrollView( - child: new ExpansionPanelList( - expansionCallback: (int _index, bool _isExpanded) => { - Debug.Log(" from [" + (_isExpanded ? "Open" : "Close") + "]" + - " to [" + (_isExpanded ? "Close" : "Open") + "]"); - - this.isExpand[_index] = !_isExpanded; - this.setState(() => { }); - }, - children: new List { - new ExpansionPanel( - headerBuilder: (BuildContext subContext, bool isExpanded) => { - return new Container( - color: Colors.black45, - child: new Center( - child: new Text("Beijing") - ) - ); - }, - body: new Container( - child: new Column( - children: new List { - new Card( - child: new Container( - color: Colors.black38, - height: 36, - width: 300, - child: new Center( - child: new Text("Beijing") - ) - ) - ) - } - ) - ), - isExpanded: this.isExpand[0] - ), - new ExpansionPanel( - headerBuilder: (BuildContext subContext, bool isExpanded) => { - return new Container( - color: Colors.black45, - child: new Center( - child: new Text("Hebei") - ) - ); - }, - body: new Container( - child: new Column( - children: new List { - new Card( - child: new Container( - color: Colors.black38, - height: 36, - width: 300, - child: new Center( - child: new Text("Tianjin") - ) - ) - ), - new Card( - child: new Container( - color: Colors.black38, - height: 36, - width: 300, - child: new Center( - child: new Text("Shijiazhuang") - ) - ) - ), - new Card( - child: new Container( - color: Colors.black38, - height: 36, - width: 300, - child: new Center( - child: new Text("Zhumadian") - ) - ) - ) - } - ) - ), - isExpanded: this.isExpand[1] - ), - } - ) - ) - ); - } - } -} \ No newline at end of file diff --git a/Samples/UIWidgetSample/ExpansionPanelSample.cs.meta b/Samples/UIWidgetSample/ExpansionPanelSample.cs.meta deleted file mode 100644 index 0ccdc84a..00000000 --- a/Samples/UIWidgetSample/ExpansionPanelSample.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 7b7c8f92f79054eb6ae6e6749ebec2a1 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetSample/HoverRecognizerSample.cs b/Samples/UIWidgetSample/HoverRecognizerSample.cs deleted file mode 100644 index bef34d92..00000000 --- a/Samples/UIWidgetSample/HoverRecognizerSample.cs +++ /dev/null @@ -1,82 +0,0 @@ -using System.Collections.Generic; -using Unity.UIWidgets.gestures; -using Unity.UIWidgets.material; -using Unity.UIWidgets.painting; -using Unity.UIWidgets.rendering; -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; -using UnityEngine; - -namespace UIWidgetsSample { - public class HoverRecognizerSample : UIWidgetsSamplePanel { - protected override Widget createWidget() { - return new MaterialApp( - showPerformanceOverlay: false, - home: new HoverMainPanel() - ); - } - - protected override void OnEnable() { - FontManager.instance.addFont(Resources.Load(path: "MaterialIcons-Regular"), "Material Icons"); - base.OnEnable(); - } - } - - class HoverMainPanel : StatefulWidget { - public override State createState() { - return new HoverMainPanelState(); - } - } - - class HoverMainPanelState : State { - bool hoverActivated = false; - - public override Widget build(BuildContext context) { - return new Scaffold( - appBar: new AppBar( - title: new Center( - child: new SelectableText("Test Hover Widget") - ) - ), - body: new Card( - color: Colors.white, - child: new Center( - child: new Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.center, - children: new List { - new Icon(this.hoverActivated ? Unity.UIWidgets.material.Icons.pool : Unity.UIWidgets.material.Icons.directions_walk, size: 128.0f), - new RichText( - text: new TextSpan( - text: "Test <", - style: new TextStyle(color: Colors.black), - children: new List() { - new TextSpan( - text: "Hover Me", - style: new TextStyle( - color: Colors.green, - decoration: TextDecoration.underline - ), - hoverRecognizer: new HoverRecognizer { - OnPointerEnter = evt => { - this.setState(() => { this.hoverActivated = true; }); - }, - OnPointerLeave = () => { - this.setState(() => { this.hoverActivated = false;}); - } - } - ), - new TextSpan( - text: ">" - ) - } - ) - ) - } - ) - ) - ) - ); - } - } -} \ No newline at end of file diff --git a/Samples/UIWidgetSample/HoverRecognizerSample.cs.meta b/Samples/UIWidgetSample/HoverRecognizerSample.cs.meta deleted file mode 100644 index 845ccc7c..00000000 --- a/Samples/UIWidgetSample/HoverRecognizerSample.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: aeab7b6e566d741a8a11a4400d52e708 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetSample/HttpRequestSample.cs b/Samples/UIWidgetSample/HttpRequestSample.cs deleted file mode 100644 index 575f1b9b..00000000 --- a/Samples/UIWidgetSample/HttpRequestSample.cs +++ /dev/null @@ -1,63 +0,0 @@ -using System; -using System.Collections.Generic; -using Unity.UIWidgets.engine; -using Unity.UIWidgets.foundation; -using Unity.UIWidgets.material; -using Unity.UIWidgets.widgets; -using UnityEngine; -using UnityEngine.Networking; - -public class HttpRequestSample : UIWidgetsPanel -{ - protected override Widget createWidget() { - return new MaterialApp( - title: "Http Request Sample", - home: new Scaffold( - body:new AsyncRequestWidget(this.gameObject) - ) - ); - } -} - -public class AsyncRequestWidget : StatefulWidget { - - public readonly GameObject gameObjOfUIWidgetsPanel; - - public AsyncRequestWidget(GameObject gameObjOfUiWidgetsPanel, Key key = null) : base(key) { - this.gameObjOfUIWidgetsPanel = gameObjOfUiWidgetsPanel; - } - - public override State createState() { - return new _AsyncRequestWidgetState(); - } -} - -[Serializable] -public class TimeData { - public long currentFileTime; -} - -class _AsyncRequestWidgetState : State { - - long _fileTime; - - public override Widget build(BuildContext context) { - - return new Column( - children: new List() { - new FlatButton(child: new Text("Click To Get Time"), onPressed: () => { - UnityWebRequest www = UnityWebRequest.Get("http://worldclockapi.com/api/json/est/now"); - var asyncOperation = www.SendWebRequest(); - asyncOperation.completed += operation => { - var timeData = JsonUtility.FromJson(www.downloadHandler.text); - using(WindowProvider.of(this.widget.gameObjOfUIWidgetsPanel).getScope()) - { - this.setState(() => { this._fileTime = timeData.currentFileTime; }); - } - - }; - }), - new Text($"current file time: {this._fileTime}") - }); - } -} \ No newline at end of file diff --git a/Samples/UIWidgetSample/HttpRequestSample.cs.meta b/Samples/UIWidgetSample/HttpRequestSample.cs.meta deleted file mode 100644 index ad2e0a3e..00000000 --- a/Samples/UIWidgetSample/HttpRequestSample.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: cfa3e1cd78bb74aef90a7a0289dfc23c -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetSample/LongPressSample.cs b/Samples/UIWidgetSample/LongPressSample.cs deleted file mode 100644 index 6841e19a..00000000 --- a/Samples/UIWidgetSample/LongPressSample.cs +++ /dev/null @@ -1,38 +0,0 @@ -using Unity.UIWidgets.material; -using Unity.UIWidgets.widgets; -using UnityEngine; - -namespace UIWidgetsSample { - public class LongPressSample : UIWidgetsSamplePanel { - protected override Widget createWidget() { - return new WidgetsApp( - home: new LongPressSampleWidget(), - pageRouteBuilder: this.pageRouteBuilder); - } - } - - public class LongPressSampleWidget : StatefulWidget { - public override State createState() { - return new _LongPressSampleWidgetState(); - } - } - - class _LongPressSampleWidgetState : State { - public override Widget build(BuildContext context) { - return new GestureDetector( - onLongPressDragStart: (value) => { Debug.Log($"Long Press Drag Start: {value}"); }, - onLongPressDragUpdate: (value) => { Debug.Log($"Long Press Drag Update: {value}"); }, - onLongPressDragUp: (value) => { Debug.Log($"Long Press Drag Up: {value}"); }, - onLongPressUp: () => { Debug.Log($"Long Press Up"); }, - onLongPress: () => { Debug.Log($"Long Press"); }, - child: new Center( - child: new Container( - width: 200, - height: 200, - color: Colors.blue - ) - ) - ); - } - } -} \ No newline at end of file diff --git a/Samples/UIWidgetSample/LongPressSample.cs.meta b/Samples/UIWidgetSample/LongPressSample.cs.meta deleted file mode 100644 index 748d2409..00000000 --- a/Samples/UIWidgetSample/LongPressSample.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 5bab4c4cc3a446f280edec6a9d0a4f16 -timeCreated: 1556594174 \ No newline at end of file diff --git a/Samples/UIWidgetSample/LongPressSample.unity b/Samples/UIWidgetSample/LongPressSample.unity deleted file mode 100644 index 998ce35b..00000000 --- a/Samples/UIWidgetSample/LongPressSample.unity +++ /dev/null @@ -1,468 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!29 &1 -OcclusionCullingSettings: - m_ObjectHideFlags: 0 - serializedVersion: 2 - m_OcclusionBakeSettings: - smallestOccluder: 5 - smallestHole: 0.25 - backfaceThreshold: 100 - m_SceneGUID: 00000000000000000000000000000000 - m_OcclusionCullingData: {fileID: 0} ---- !u!104 &2 -RenderSettings: - m_ObjectHideFlags: 0 - serializedVersion: 9 - m_Fog: 0 - m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} - m_FogMode: 3 - m_FogDensity: 0.01 - m_LinearFogStart: 0 - m_LinearFogEnd: 300 - m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} - m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} - m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} - m_AmbientIntensity: 1 - m_AmbientMode: 0 - m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} - m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} - m_HaloStrength: 0.5 - m_FlareStrength: 1 - m_FlareFadeSpeed: 3 - m_HaloTexture: {fileID: 0} - m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} - m_DefaultReflectionMode: 0 - m_DefaultReflectionResolution: 128 - m_ReflectionBounces: 1 - m_ReflectionIntensity: 1 - m_CustomReflection: {fileID: 0} - m_Sun: {fileID: 0} - m_IndirectSpecularColor: {r: 0.44657898, g: 0.49641287, b: 0.5748173, a: 1} - m_UseRadianceAmbientProbe: 0 ---- !u!157 &3 -LightmapSettings: - m_ObjectHideFlags: 0 - serializedVersion: 11 - m_GIWorkflowMode: 0 - m_GISettings: - serializedVersion: 2 - m_BounceScale: 1 - m_IndirectOutputScale: 1 - m_AlbedoBoost: 1 - m_EnvironmentLightingMode: 0 - m_EnableBakedLightmaps: 1 - m_EnableRealtimeLightmaps: 1 - m_LightmapEditorSettings: - serializedVersion: 10 - m_Resolution: 2 - m_BakeResolution: 40 - m_AtlasSize: 1024 - m_AO: 0 - m_AOMaxDistance: 1 - m_CompAOExponent: 1 - m_CompAOExponentDirect: 0 - m_Padding: 2 - m_LightmapParameters: {fileID: 0} - m_LightmapsBakeMode: 1 - m_TextureCompression: 1 - m_FinalGather: 0 - m_FinalGatherFiltering: 1 - m_FinalGatherRayCount: 256 - m_ReflectionCompression: 2 - m_MixedBakeMode: 2 - m_BakeBackend: 1 - m_PVRSampling: 1 - m_PVRDirectSampleCount: 32 - m_PVRSampleCount: 500 - m_PVRBounces: 2 - m_PVRFilterTypeDirect: 0 - m_PVRFilterTypeIndirect: 0 - m_PVRFilterTypeAO: 0 - m_PVRFilteringMode: 1 - m_PVRCulling: 1 - m_PVRFilteringGaussRadiusDirect: 1 - m_PVRFilteringGaussRadiusIndirect: 5 - m_PVRFilteringGaussRadiusAO: 2 - m_PVRFilteringAtrousPositionSigmaDirect: 0.5 - m_PVRFilteringAtrousPositionSigmaIndirect: 2 - m_PVRFilteringAtrousPositionSigmaAO: 1 - m_ShowResolutionOverlay: 1 - m_LightingDataAsset: {fileID: 0} - m_UseShadowmask: 1 ---- !u!196 &4 -NavMeshSettings: - serializedVersion: 2 - m_ObjectHideFlags: 0 - m_BuildSettings: - serializedVersion: 2 - agentTypeID: 0 - agentRadius: 0.5 - agentHeight: 2 - agentSlope: 45 - agentClimb: 0.4 - ledgeDropHeight: 0 - maxJumpAcrossDistance: 0 - minRegionArea: 2 - manualCellSize: 0 - cellSize: 0.16666667 - manualTileSize: 0 - tileSize: 256 - accuratePlacement: 0 - debug: - m_Flags: 0 - m_NavMeshData: {fileID: 0} ---- !u!1 &332995326 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 332995329} - - component: {fileID: 332995328} - - component: {fileID: 332995327} - m_Layer: 0 - m_Name: EventSystem - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!114 &332995327 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 332995326} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 1077351063, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_HorizontalAxis: Horizontal - m_VerticalAxis: Vertical - m_SubmitButton: Submit - m_CancelButton: Cancel - m_InputActionsPerSecond: 10 - m_RepeatDelay: 0.5 - m_ForceModuleActive: 0 ---- !u!114 &332995328 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 332995326} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: -619905303, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_FirstSelected: {fileID: 0} - m_sendNavigationEvents: 1 - m_DragThreshold: 10 ---- !u!4 &332995329 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 332995326} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 3 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!1 &1301752092 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1301752095} - - component: {fileID: 1301752094} - - component: {fileID: 1301752093} - m_Layer: 0 - m_Name: Main Camera - m_TagString: MainCamera - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!81 &1301752093 -AudioListener: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1301752092} - m_Enabled: 1 ---- !u!20 &1301752094 -Camera: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1301752092} - m_Enabled: 1 - serializedVersion: 2 - m_ClearFlags: 1 - m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} - m_projectionMatrixMode: 1 - m_SensorSize: {x: 36, y: 24} - m_LensShift: {x: 0, y: 0} - m_GateFitMode: 2 - m_FocalLength: 50 - m_NormalizedViewPortRect: - serializedVersion: 2 - x: 0 - y: 0 - width: 1 - height: 1 - near clip plane: 0.3 - far clip plane: 1000 - field of view: 60 - orthographic: 0 - orthographic size: 5 - m_Depth: -1 - m_CullingMask: - serializedVersion: 2 - m_Bits: 4294967295 - m_RenderingPath: -1 - m_TargetTexture: {fileID: 0} - m_TargetDisplay: 0 - m_TargetEye: 3 - m_HDR: 1 - m_AllowMSAA: 1 - m_AllowDynamicResolution: 0 - m_ForceIntoRT: 0 - m_OcclusionCulling: 1 - m_StereoConvergence: 10 - m_StereoSeparation: 0.022 ---- !u!4 &1301752095 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1301752092} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 1, z: -10} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!1 &1907726269 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1907726273} - - component: {fileID: 1907726272} - - component: {fileID: 1907726271} - - component: {fileID: 1907726270} - - component: {fileID: 1907726275} - - component: {fileID: 1907726274} - m_Layer: 5 - m_Name: Canvas - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!114 &1907726270 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1907726269} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 1301386320, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_IgnoreReversedGraphics: 1 - m_BlockingObjects: 0 - m_BlockingMask: - serializedVersion: 2 - m_Bits: 4294967295 ---- !u!114 &1907726271 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1907726269} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 1980459831, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_UiScaleMode: 0 - m_ReferencePixelsPerUnit: 100 - m_ScaleFactor: 1 - m_ReferenceResolution: {x: 800, y: 600} - m_ScreenMatchMode: 0 - m_MatchWidthOrHeight: 0 - m_PhysicalUnit: 3 - m_FallbackScreenDPI: 96 - m_DefaultSpriteDPI: 96 - m_DynamicPixelsPerUnit: 1 ---- !u!223 &1907726272 -Canvas: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1907726269} - m_Enabled: 1 - serializedVersion: 3 - m_RenderMode: 0 - m_Camera: {fileID: 0} - m_PlaneDistance: 100 - m_PixelPerfect: 0 - m_ReceivesEvents: 1 - m_OverrideSorting: 0 - m_OverridePixelPerfect: 0 - m_SortingBucketNormalizedSize: 0 - m_AdditionalShaderChannelsFlag: 0 - m_SortingLayerID: 0 - m_SortingOrder: 0 - m_TargetDisplay: 0 ---- !u!224 &1907726273 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1907726269} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 0, y: 0, z: 0} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 2 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 0, y: 0} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0, y: 0} ---- !u!114 &1907726274 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1907726269} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 5bab4c4cc3a446f280edec6a9d0a4f16, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_Texture: {fileID: 0} - m_UVRect: - serializedVersion: 2 - x: 0 - y: 0 - width: 1 - height: 1 - devicePixelRatioOverride: 0 - antiAliasingOverride: 4 ---- !u!222 &1907726275 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1907726269} - m_CullTransparentMesh: 0 ---- !u!1 &1963403153 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1963403155} - - component: {fileID: 1963403154} - m_Layer: 0 - m_Name: Directional Light - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!108 &1963403154 -Light: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1963403153} - m_Enabled: 1 - serializedVersion: 8 - m_Type: 1 - m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} - m_Intensity: 1 - m_Range: 10 - m_SpotAngle: 30 - m_CookieSize: 10 - m_Shadows: - m_Type: 2 - m_Resolution: -1 - m_CustomResolution: -1 - m_Strength: 1 - m_Bias: 0.05 - m_NormalBias: 0.4 - m_NearPlane: 0.2 - m_Cookie: {fileID: 0} - m_DrawHalo: 0 - m_Flare: {fileID: 0} - m_RenderMode: 0 - m_CullingMask: - serializedVersion: 2 - m_Bits: 4294967295 - m_Lightmapping: 4 - m_LightShadowCasterMode: 0 - m_AreaSize: {x: 1, y: 1} - m_BounceIntensity: 1 - m_ColorTemperature: 6570 - m_UseColorTemperature: 0 - m_ShadowRadius: 0 - m_ShadowAngle: 0 ---- !u!4 &1963403155 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1963403153} - m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} - m_LocalPosition: {x: 0, y: 3, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 1 - m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} diff --git a/Samples/UIWidgetSample/LongPressSample.unity.meta b/Samples/UIWidgetSample/LongPressSample.unity.meta deleted file mode 100644 index d36e2629..00000000 --- a/Samples/UIWidgetSample/LongPressSample.unity.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: ea79b711dbc434533b52afdbe4e3ec11 -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetSample/MaterialSample.cs b/Samples/UIWidgetSample/MaterialSample.cs deleted file mode 100644 index 0d01d521..00000000 --- a/Samples/UIWidgetSample/MaterialSample.cs +++ /dev/null @@ -1,570 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using RSG; -using Unity.UIWidgets.foundation; -using Unity.UIWidgets.material; -using Unity.UIWidgets.painting; -using Unity.UIWidgets.rendering; -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; -using UnityEngine; -using Color = Unity.UIWidgets.ui.Color; -using Material = Unity.UIWidgets.material.Material; -using TextStyle = Unity.UIWidgets.painting.TextStyle; - -namespace UIWidgetsSample { - public class MaterialSample : UIWidgetsSamplePanel { - const int testCaseId = 6; - - readonly List testCases = new List { - new MaterialButtonWidget(), - new MaterialInkWellWidget(), - new MaterialAppBarWidget(), - new MaterialTabBarWidget(), - new TableWidget(), - new BottomAppBarWidget(), - new MaterialSliderWidget(), - new MaterialNavigationBarWidget(), - new MaterialReorderableListViewWidget(), - }; - - protected override Widget createWidget() { - return new MaterialApp( - showPerformanceOverlay: false, - home: this.testCases[testCaseId]); - } - - protected override void OnEnable() { - FontManager.instance.addFont(Resources.Load(path: "MaterialIcons-Regular"), "Material Icons"); - base.OnEnable(); - } - } - - public class BottomAppBarWidget : StatelessWidget { - public BottomAppBarWidget(Key key = null) : base(key) { - - } - - public override Widget build(BuildContext context) { - return new Scaffold( - backgroundColor: Color.clear, - bottomNavigationBar: new BottomAppBar( - child: new Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: new List { - new IconButton(icon: new Icon(Unity.UIWidgets.material.Icons.menu), onPressed: () => { }), - new IconButton(icon: new Icon(Unity.UIWidgets.material.Icons.account_balance), - onPressed: () => { }) - }))); - } - } - - - public class TableWidget : StatelessWidget { - public TableWidget(Key key = null) : base(key) { - } - - public override Widget build(BuildContext context) { - return new Scaffold( - body: new Table( - children: new List { - new TableRow( - decoration: new BoxDecoration(color: Colors.blue), - children: new List { - new Text("item 1"), - new Text("item 2") - } - ), - new TableRow(children: new List { - new Text("item 3"), - new Text("item 4") - } - ) - }, - defaultVerticalAlignment: TableCellVerticalAlignment.middle)); - } - } - - - public class MaterialTabBarWidget : StatefulWidget { - public MaterialTabBarWidget(Key key = null) : base(key) { - } - - public override State createState() { - return new MaterialTabBarWidgetState(); - } - } - - public class MaterialTabBarWidgetState : SingleTickerProviderStateMixin { - TabController _tabController; - - public override void initState() { - base.initState(); - this._tabController = new TabController(vsync: this, length: Choice.choices.Count); - } - - public override void dispose() { - this._tabController.dispose(); - base.dispose(); - } - - void _nextPage(int delta) { - int newIndex = this._tabController.index + delta; - if (newIndex < 0 || newIndex >= this._tabController.length) { - return; - } - - this._tabController.animateTo(newIndex); - } - - public override Widget build(BuildContext context) { - List tapChildren = new List(); - foreach (Choice choice in Choice.choices) { - tapChildren.Add( - new Padding( - padding: EdgeInsets.all(16.0f), - child: new ChoiceCard(choice: choice))); - } - - return new Scaffold( - appBar: new AppBar( - title: new Center( - child: new Text("AppBar Bottom Widget") - ), - leading: new IconButton( - tooltip: "Previous choice", - icon: new Icon(Unity.UIWidgets.material.Icons.arrow_back), - onPressed: () => { this._nextPage(-1); } - ), - actions: new List { - new IconButton( - icon: new Icon(Unity.UIWidgets.material.Icons.arrow_forward), - tooltip: "Next choice", - onPressed: () => { this._nextPage(1); }) - }, - bottom: new PreferredSize( - preferredSize: Size.fromHeight(48.0f), - child: new Theme( - data: Theme.of(context).copyWith(accentColor: Colors.white), - child: new Container( - height: 48.0f, - alignment: Alignment.center, - child: new TabPageSelector( - controller: this._tabController)))) - ), - body: new TabBarView( - controller: this._tabController, - children: tapChildren - )); - } - } - - public class MaterialAppBarWidget : StatefulWidget { - public MaterialAppBarWidget(Key key = null) : base(key) { - } - - public override State createState() { - return new MaterialAppBarWidgetState(); - } - } - - public class MaterialAppBarWidgetState : State { - Choice _selectedChoice = Choice.choices[0]; - - GlobalKey _scaffoldKey = GlobalKey.key(); - - VoidCallback _showBottomSheetCallback; - - public override void initState() { - base.initState(); - this._showBottomSheetCallback = this._showBottomSheet; - } - - void _showBottomSheet() { - this.setState(() => { this._showBottomSheetCallback = null; }); - - this._scaffoldKey.currentState.showBottomSheet((BuildContext subContext) => { - ThemeData themeData = Theme.of(subContext); - return new Container( - decoration: new BoxDecoration( - border: new Border( - top: new BorderSide( - color: themeData.disabledColor))), - child: new Padding( - padding: EdgeInsets.all(32.0f), - child: new Text("This is a Material persistent bottom sheet. Drag downwards to dismiss it.", - textAlign: TextAlign.center, - style: new TextStyle( - color: themeData.accentColor, - fontSize: 16.0f)) - ) - ); - }).closed.Then((object obj) => { - if (this.mounted) { - this.setState(() => { this._showBottomSheetCallback = this._showBottomSheet; }); - } - - return new Promise(); - }); - } - - void _select(Choice choice) { - this.setState(() => { this._selectedChoice = choice; }); - } - - public override Widget build(BuildContext context) { - return new Scaffold( - key: this._scaffoldKey, - appBar: new AppBar( - title: new Text("Basic AppBar"), - actions: new List { - new IconButton( - icon: new Icon(Choice.choices[0].icon), - //color: Colors.blue, - onPressed: () => { this._select((Choice.choices[0])); } - ), - new IconButton( - icon: new Icon(Choice.choices[1].icon), - //color: Colors.blue, - onPressed: () => { this._select((Choice.choices[1])); } - ), - - new PopupMenuButton( - onSelected: this._select, - itemBuilder: (BuildContext subContext) => { - List> popupItems = new List>(); - for (int i = 2; i < Choice.choices.Count; i++) { - popupItems.Add(new PopupMenuItem( - value: Choice.choices[i], - child: new Text(Choice.choices[i].title))); - } - - return popupItems; - } - ) - } - ), - body: new Padding( - padding: EdgeInsets.all(16.0f), - child: new ChoiceCard(choice: this._selectedChoice) - ), - floatingActionButton: new FloatingActionButton( - backgroundColor: Colors.redAccent, - child: new Icon(Unity.UIWidgets.material.Icons.add_alert), - onPressed: this._showBottomSheetCallback - ), - drawer: new Drawer( - child: new ListView( - padding: EdgeInsets.zero, - children: new List { - new ListTile( - leading: new Icon(Unity.UIWidgets.material.Icons.account_circle), - title: new Text("Login"), - onTap: () => { } - ), - new Divider( - height: 2.0f), - new ListTile( - leading: new Icon(Unity.UIWidgets.material.Icons.account_balance_wallet), - title: new Text("Wallet"), - onTap: () => { } - ), - new Divider( - height: 2.0f), - new ListTile( - leading: new Icon(Unity.UIWidgets.material.Icons.accessibility), - title: new Text("Balance"), - onTap: () => { } - ) - } - ) - ) - ); - } - } - - - class Choice { - public Choice(string title, IconData icon) { - this.title = title; - this.icon = icon; - } - - public readonly string title; - public readonly IconData icon; - - public static List choices = new List { - new Choice("Car", Unity.UIWidgets.material.Icons.directions_car), - new Choice("Bicycle", Unity.UIWidgets.material.Icons.directions_bike), - new Choice("Boat", Unity.UIWidgets.material.Icons.directions_boat), - new Choice("Bus", Unity.UIWidgets.material.Icons.directions_bus), - new Choice("Train", Unity.UIWidgets.material.Icons.directions_railway), - new Choice("Walk", Unity.UIWidgets.material.Icons.directions_walk) - }; - } - - class ChoiceCard : StatelessWidget { - public ChoiceCard(Key key = null, Choice choice = null) : base(key: key) { - this.choice = choice; - } - - public readonly Choice choice; - - public override Widget build(BuildContext context) { - TextStyle textStyle = Theme.of(context).textTheme.display1; - return new Card( - color: Colors.white, - child: new Center( - child: new Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.center, - children: new List { - new Icon(this.choice.icon, size: 128.0f, color: textStyle.color), - new RaisedButton( - child: new Text(this.choice.title, style: textStyle), - onPressed: () => { - SnackBar snackBar = new SnackBar( - content: new Text(this.choice.title + " is chosen !"), - action: new SnackBarAction( - label: "Ok", - onPressed: () => { })); - - Scaffold.of(context).showSnackBar(snackBar); - }) - } - ) - ) - ); - } - } - - public class MaterialInkWellWidget : StatefulWidget { - public MaterialInkWellWidget(Key key = null) : base(key) { - } - - public override State createState() { - return new MaterialInkWidgetState(); - } - } - - public class MaterialInkWidgetState : State { - public override Widget build(BuildContext context) { - return new Material( - //color: Colors.blue, - child: new Center( - child: new Container( - width: 200, - height: 200, - child: new InkWell( - borderRadius: BorderRadius.circular(2.0f), - highlightColor: new Color(0xAAFF0000), - splashColor: new Color(0xAA0000FF), - onTap: () => { Debug.Log("on tap"); } - ) - ) - ) - ); - } - } - - public class MaterialButtonWidget : StatefulWidget { - public MaterialButtonWidget(Key key = null) : base(key) { - } - - public override State createState() { - return new MaterialButtonWidgetState(); - } - } - - public class MaterialButtonWidgetState : State { - public override Widget build(BuildContext context) { - return new Stack( - children: new List { - new Material( - child: new Center( - child: new Column( - children: new List { - new Padding(padding: EdgeInsets.only(top: 30f)), - new MaterialButton( - shape: new RoundedRectangleBorder(borderRadius: BorderRadius.all(20.0f)), - color: new Color(0xFF00FF00), - splashColor: new Color(0xFFFF0011), - highlightColor: new Color(0x88FF0011), - child: new Text("Click Me"), - onPressed: () => { Debug.Log("pressed flat button"); } - ), - new Padding(padding: EdgeInsets.only(top: 30f)), - new MaterialButton( - shape: new RoundedRectangleBorder(borderRadius: BorderRadius.all(20.0f)), - color: new Color(0xFFFF00FF), - splashColor: new Color(0xFFFF0011), - highlightColor: new Color(0x88FF0011), - elevation: 4.0f, - child: new Text("Click Me"), - onPressed: () => { Debug.Log("pressed raised button"); } - ) - } - ) - ) - ), - new PerformanceOverlay() - } - ); - } - } - - public class MaterialSliderWidget : StatefulWidget { - public override State createState() { - return new MaterialSliderState(); - } - } - - public class MaterialSliderState : State { - - float _value = 0.8f; - - void onChanged(float value) { - this.setState(() => { this._value = value; }); - } - - public override Widget build(BuildContext context) { - return new Scaffold( - appBar: new AppBar( - title: new Text("Slider and Indicators")), - body: new Column( - children: new List { - new Padding( - padding: EdgeInsets.only(top: 100.0f), - child: new Container( - child: new Slider( - divisions: 10, - min: 0.4f, - label: "Here", - value: this._value, - onChanged: this.onChanged)) - ) - } - ) - ); - } - } - - class MaterialNavigationBarWidget : StatefulWidget { - public MaterialNavigationBarWidget(Key key = null) : base(key) { - } - - public override State createState() { - return new MaterialNavigationBarWidgetState(); - } - } - - class MaterialNavigationBarWidgetState : SingleTickerProviderStateMixin { - int _currentIndex = 0; - - public MaterialNavigationBarWidgetState() { - } - - public override Widget build(BuildContext context) { - return new Scaffold( - bottomNavigationBar: new Container( - height: 100, - color: Colors.blue, - child: new Center( - child: new BottomNavigationBar( - type: BottomNavigationBarType.shifting, - // type: BottomNavigationBarType.fix, - items: new List { - new BottomNavigationBarItem( - icon: new Icon(icon: Unity.UIWidgets.material.Icons.work, size: 30), - title: new Text("Work"), - activeIcon: new Icon(icon: Unity.UIWidgets.material.Icons.work, size: 50), - backgroundColor: Colors.blue - ), - new BottomNavigationBarItem( - icon: new Icon(icon: Unity.UIWidgets.material.Icons.home, size: 30), - title: new Text("Home"), - activeIcon: new Icon(icon: Unity.UIWidgets.material.Icons.home, size: 50), - backgroundColor: Colors.blue - ), - new BottomNavigationBarItem( - icon: new Icon(icon: Unity.UIWidgets.material.Icons.shop, size: 30), - title: new Text("Shop"), - activeIcon: new Icon(icon: Unity.UIWidgets.material.Icons.shop, size: 50), - backgroundColor: Colors.blue - ), - new BottomNavigationBarItem( - icon: new Icon(icon: Unity.UIWidgets.material.Icons.school, size: 30), - title: new Text("School"), - activeIcon: new Icon(icon: Unity.UIWidgets.material.Icons.school, size: 50), - backgroundColor: Colors.blue - ), - }, - currentIndex: this._currentIndex, - onTap: (value) => { this.setState(() => { this._currentIndex = value; }); } - ) - ) - ) - ); - } - } - - class MaterialReorderableListViewWidget : StatefulWidget { - public MaterialReorderableListViewWidget(Key key = null) : base(key) { - } - - public override State createState() { - return new MaterialReorderableListViewWidgetState(); - } - } - - class MaterialReorderableListViewWidgetState : State { - List items = new List {"First", "Second", "Third"}; - - public override Widget build(BuildContext context) { - return new Stack( - children: new List { - new Scaffold( - body: new Scrollbar( - child: new ReorderableListView( - header: new Text("Header of list"), - children: this.items.Select((item) => { - return new Container( - key: Key.key(item), - width: 300.0f, - height: 50.0f, - decoration: new BoxDecoration( - color: Colors.blue, - border: Border.all( - color: Colors.black - ) - ), - child: new Center( - child: new Text( - item, - style: new TextStyle( - fontSize: 32 - ) - ) - ) - ); - }).ToList(), - onReorder: (int oldIndex, int newIndex) => { - this.setState(() => { - if (newIndex > oldIndex) { - newIndex -= 1; - } - string item = this.items[oldIndex]; - this.items.RemoveAt(oldIndex); - this.items.Insert(newIndex, item); - }); - } - ) - ) - ), - new PerformanceOverlay() - } - ); - } - } -} \ No newline at end of file diff --git a/Samples/UIWidgetSample/MaterialSample.cs.meta b/Samples/UIWidgetSample/MaterialSample.cs.meta deleted file mode 100644 index 9c0f0518..00000000 --- a/Samples/UIWidgetSample/MaterialSample.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: d7c3be43dd8b94a349f26e3e7173c3f6 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetSample/MaterialThemeSample.cs b/Samples/UIWidgetSample/MaterialThemeSample.cs deleted file mode 100644 index 216572eb..00000000 --- a/Samples/UIWidgetSample/MaterialThemeSample.cs +++ /dev/null @@ -1,86 +0,0 @@ -using System.Collections.Generic; -using Unity.UIWidgets.animation; -using Unity.UIWidgets.engine; -using Unity.UIWidgets.material; -using Unity.UIWidgets.painting; -using Unity.UIWidgets.rendering; -using Unity.UIWidgets.service; -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; -using UnityEngine; -using Image = Unity.UIWidgets.widgets.Image; - -namespace UIWidgetsSample { - public class MaterialThemeSample: UIWidgetsSamplePanel { - - protected override Widget createWidget() { - return new MaterialApp( - home: new MaterialThemeSampleWidget(), - darkTheme: new ThemeData(primaryColor: Colors.black26) - ); - } - - protected override void OnEnable() { - FontManager.instance.addFont(Resources.Load(path: "MaterialIcons-Regular"), "Material Icons"); - base.OnEnable(); - } - } - - public class MaterialThemeSampleWidget: StatefulWidget { - public override State createState() { - return new _MaterialThemeSampleWidgetState(); - } - } - - class _MaterialThemeSampleWidgetState : State { - public override Widget build(BuildContext context) { - return new Theme( - data: new ThemeData( - appBarTheme: new AppBarTheme( - color: Colors.purple - ), - bottomAppBarTheme: new BottomAppBarTheme( - color: Colors.blue - ), - cardTheme: new CardTheme( - color: Colors.red, - elevation: 2.0f - ) - ), - child: new Scaffold( - appBar: new AppBar(title: new Text("Test App Bar Theme")), - body: new Center( - child: new Card( - shape: new RoundedRectangleBorder( - borderRadius: BorderRadius.all(5.0f) - ), - child: new Container( - height: 250, - child: new Column( - children: new List { - Image.asset( - "products/backpack", - fit: BoxFit.cover, - width: 200, - height: 200 - ), - new Text("Card Theme") - } - ) - ) - ) - ), - bottomNavigationBar: new BottomAppBar( - child: new Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: new List { - new IconButton(icon: new Icon(Unity.UIWidgets.material.Icons.menu), onPressed: () => { }), - new IconButton(icon: new Icon(Unity.UIWidgets.material.Icons.account_balance), onPressed: () => { }) - }) - ) - ) - ); - } - } -} \ No newline at end of file diff --git a/Samples/UIWidgetSample/MaterialThemeSample.cs.meta b/Samples/UIWidgetSample/MaterialThemeSample.cs.meta deleted file mode 100644 index 0d5a461b..00000000 --- a/Samples/UIWidgetSample/MaterialThemeSample.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: f5061bd7b85f4179a65c68ac289a4a58 -timeCreated: 1556597371 \ No newline at end of file diff --git a/Samples/UIWidgetSample/MaterialThemeSample.unity b/Samples/UIWidgetSample/MaterialThemeSample.unity deleted file mode 100644 index a32147d7..00000000 --- a/Samples/UIWidgetSample/MaterialThemeSample.unity +++ /dev/null @@ -1,468 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!29 &1 -OcclusionCullingSettings: - m_ObjectHideFlags: 0 - serializedVersion: 2 - m_OcclusionBakeSettings: - smallestOccluder: 5 - smallestHole: 0.25 - backfaceThreshold: 100 - m_SceneGUID: 00000000000000000000000000000000 - m_OcclusionCullingData: {fileID: 0} ---- !u!104 &2 -RenderSettings: - m_ObjectHideFlags: 0 - serializedVersion: 9 - m_Fog: 0 - m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} - m_FogMode: 3 - m_FogDensity: 0.01 - m_LinearFogStart: 0 - m_LinearFogEnd: 300 - m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} - m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} - m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} - m_AmbientIntensity: 1 - m_AmbientMode: 0 - m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} - m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} - m_HaloStrength: 0.5 - m_FlareStrength: 1 - m_FlareFadeSpeed: 3 - m_HaloTexture: {fileID: 0} - m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} - m_DefaultReflectionMode: 0 - m_DefaultReflectionResolution: 128 - m_ReflectionBounces: 1 - m_ReflectionIntensity: 1 - m_CustomReflection: {fileID: 0} - m_Sun: {fileID: 0} - m_IndirectSpecularColor: {r: 0.44657898, g: 0.49641287, b: 0.5748173, a: 1} - m_UseRadianceAmbientProbe: 0 ---- !u!157 &3 -LightmapSettings: - m_ObjectHideFlags: 0 - serializedVersion: 11 - m_GIWorkflowMode: 0 - m_GISettings: - serializedVersion: 2 - m_BounceScale: 1 - m_IndirectOutputScale: 1 - m_AlbedoBoost: 1 - m_EnvironmentLightingMode: 0 - m_EnableBakedLightmaps: 1 - m_EnableRealtimeLightmaps: 1 - m_LightmapEditorSettings: - serializedVersion: 10 - m_Resolution: 2 - m_BakeResolution: 40 - m_AtlasSize: 1024 - m_AO: 0 - m_AOMaxDistance: 1 - m_CompAOExponent: 1 - m_CompAOExponentDirect: 0 - m_Padding: 2 - m_LightmapParameters: {fileID: 0} - m_LightmapsBakeMode: 1 - m_TextureCompression: 1 - m_FinalGather: 0 - m_FinalGatherFiltering: 1 - m_FinalGatherRayCount: 256 - m_ReflectionCompression: 2 - m_MixedBakeMode: 2 - m_BakeBackend: 1 - m_PVRSampling: 1 - m_PVRDirectSampleCount: 32 - m_PVRSampleCount: 500 - m_PVRBounces: 2 - m_PVRFilterTypeDirect: 0 - m_PVRFilterTypeIndirect: 0 - m_PVRFilterTypeAO: 0 - m_PVRFilteringMode: 1 - m_PVRCulling: 1 - m_PVRFilteringGaussRadiusDirect: 1 - m_PVRFilteringGaussRadiusIndirect: 5 - m_PVRFilteringGaussRadiusAO: 2 - m_PVRFilteringAtrousPositionSigmaDirect: 0.5 - m_PVRFilteringAtrousPositionSigmaIndirect: 2 - m_PVRFilteringAtrousPositionSigmaAO: 1 - m_ShowResolutionOverlay: 1 - m_LightingDataAsset: {fileID: 0} - m_UseShadowmask: 1 ---- !u!196 &4 -NavMeshSettings: - serializedVersion: 2 - m_ObjectHideFlags: 0 - m_BuildSettings: - serializedVersion: 2 - agentTypeID: 0 - agentRadius: 0.5 - agentHeight: 2 - agentSlope: 45 - agentClimb: 0.4 - ledgeDropHeight: 0 - maxJumpAcrossDistance: 0 - minRegionArea: 2 - manualCellSize: 0 - cellSize: 0.16666667 - manualTileSize: 0 - tileSize: 256 - accuratePlacement: 0 - debug: - m_Flags: 0 - m_NavMeshData: {fileID: 0} ---- !u!1 &1354633538 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1354633541} - - component: {fileID: 1354633540} - - component: {fileID: 1354633539} - m_Layer: 0 - m_Name: EventSystem - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!114 &1354633539 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1354633538} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 1077351063, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_HorizontalAxis: Horizontal - m_VerticalAxis: Vertical - m_SubmitButton: Submit - m_CancelButton: Cancel - m_InputActionsPerSecond: 10 - m_RepeatDelay: 0.5 - m_ForceModuleActive: 0 ---- !u!114 &1354633540 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1354633538} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: -619905303, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_FirstSelected: {fileID: 0} - m_sendNavigationEvents: 1 - m_DragThreshold: 10 ---- !u!4 &1354633541 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1354633538} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 3 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!1 &1488377021 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1488377023} - - component: {fileID: 1488377022} - m_Layer: 0 - m_Name: Directional Light - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!108 &1488377022 -Light: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1488377021} - m_Enabled: 1 - serializedVersion: 8 - m_Type: 1 - m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} - m_Intensity: 1 - m_Range: 10 - m_SpotAngle: 30 - m_CookieSize: 10 - m_Shadows: - m_Type: 2 - m_Resolution: -1 - m_CustomResolution: -1 - m_Strength: 1 - m_Bias: 0.05 - m_NormalBias: 0.4 - m_NearPlane: 0.2 - m_Cookie: {fileID: 0} - m_DrawHalo: 0 - m_Flare: {fileID: 0} - m_RenderMode: 0 - m_CullingMask: - serializedVersion: 2 - m_Bits: 4294967295 - m_Lightmapping: 4 - m_LightShadowCasterMode: 0 - m_AreaSize: {x: 1, y: 1} - m_BounceIntensity: 1 - m_ColorTemperature: 6570 - m_UseColorTemperature: 0 - m_ShadowRadius: 0 - m_ShadowAngle: 0 ---- !u!4 &1488377023 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1488377021} - m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} - m_LocalPosition: {x: 0, y: 3, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 1 - m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} ---- !u!1 &1752286437 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1752286441} - - component: {fileID: 1752286440} - - component: {fileID: 1752286439} - - component: {fileID: 1752286438} - - component: {fileID: 1752286443} - - component: {fileID: 1752286442} - m_Layer: 5 - m_Name: Canvas - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!114 &1752286438 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1752286437} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 1301386320, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_IgnoreReversedGraphics: 1 - m_BlockingObjects: 0 - m_BlockingMask: - serializedVersion: 2 - m_Bits: 4294967295 ---- !u!114 &1752286439 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1752286437} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 1980459831, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_UiScaleMode: 0 - m_ReferencePixelsPerUnit: 100 - m_ScaleFactor: 1 - m_ReferenceResolution: {x: 800, y: 600} - m_ScreenMatchMode: 0 - m_MatchWidthOrHeight: 0 - m_PhysicalUnit: 3 - m_FallbackScreenDPI: 96 - m_DefaultSpriteDPI: 96 - m_DynamicPixelsPerUnit: 1 ---- !u!223 &1752286440 -Canvas: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1752286437} - m_Enabled: 1 - serializedVersion: 3 - m_RenderMode: 0 - m_Camera: {fileID: 0} - m_PlaneDistance: 100 - m_PixelPerfect: 0 - m_ReceivesEvents: 1 - m_OverrideSorting: 0 - m_OverridePixelPerfect: 0 - m_SortingBucketNormalizedSize: 0 - m_AdditionalShaderChannelsFlag: 0 - m_SortingLayerID: 0 - m_SortingOrder: 0 - m_TargetDisplay: 0 ---- !u!224 &1752286441 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1752286437} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 0, y: 0, z: 0} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 2 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 0, y: 0} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0, y: 0} ---- !u!114 &1752286442 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1752286437} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: f5061bd7b85f4179a65c68ac289a4a58, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_Texture: {fileID: 0} - m_UVRect: - serializedVersion: 2 - x: 0 - y: 0 - width: 1 - height: 1 - devicePixelRatioOverride: 0 - antiAliasingOverride: 4 ---- !u!222 &1752286443 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1752286437} - m_CullTransparentMesh: 0 ---- !u!1 &1937049299 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1937049302} - - component: {fileID: 1937049301} - - component: {fileID: 1937049300} - m_Layer: 0 - m_Name: Main Camera - m_TagString: MainCamera - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!81 &1937049300 -AudioListener: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1937049299} - m_Enabled: 1 ---- !u!20 &1937049301 -Camera: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1937049299} - m_Enabled: 1 - serializedVersion: 2 - m_ClearFlags: 1 - m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} - m_projectionMatrixMode: 1 - m_SensorSize: {x: 36, y: 24} - m_LensShift: {x: 0, y: 0} - m_GateFitMode: 2 - m_FocalLength: 50 - m_NormalizedViewPortRect: - serializedVersion: 2 - x: 0 - y: 0 - width: 1 - height: 1 - near clip plane: 0.3 - far clip plane: 1000 - field of view: 60 - orthographic: 0 - orthographic size: 5 - m_Depth: -1 - m_CullingMask: - serializedVersion: 2 - m_Bits: 4294967295 - m_RenderingPath: -1 - m_TargetTexture: {fileID: 0} - m_TargetDisplay: 0 - m_TargetEye: 3 - m_HDR: 1 - m_AllowMSAA: 1 - m_AllowDynamicResolution: 0 - m_ForceIntoRT: 0 - m_OcclusionCulling: 1 - m_StereoConvergence: 10 - m_StereoSeparation: 0.022 ---- !u!4 &1937049302 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1937049299} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 1, z: -10} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} diff --git a/Samples/UIWidgetSample/MaterialThemeSample.unity.meta b/Samples/UIWidgetSample/MaterialThemeSample.unity.meta deleted file mode 100644 index bad5ea33..00000000 --- a/Samples/UIWidgetSample/MaterialThemeSample.unity.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 525ef411443314aae829b4252f00e997 -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetSample/Navigation.unity b/Samples/UIWidgetSample/Navigation.unity deleted file mode 100644 index 75e74600..00000000 --- a/Samples/UIWidgetSample/Navigation.unity +++ /dev/null @@ -1,648 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!29 &1 -OcclusionCullingSettings: - m_ObjectHideFlags: 0 - serializedVersion: 2 - m_OcclusionBakeSettings: - smallestOccluder: 5 - smallestHole: 0.25 - backfaceThreshold: 100 - m_SceneGUID: 00000000000000000000000000000000 - m_OcclusionCullingData: {fileID: 0} ---- !u!104 &2 -RenderSettings: - m_ObjectHideFlags: 0 - serializedVersion: 9 - m_Fog: 0 - m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} - m_FogMode: 3 - m_FogDensity: 0.01 - m_LinearFogStart: 0 - m_LinearFogEnd: 300 - m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} - m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} - m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} - m_AmbientIntensity: 1 - m_AmbientMode: 0 - m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} - m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} - m_HaloStrength: 0.5 - m_FlareStrength: 1 - m_FlareFadeSpeed: 3 - m_HaloTexture: {fileID: 0} - m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} - m_DefaultReflectionMode: 0 - m_DefaultReflectionResolution: 128 - m_ReflectionBounces: 1 - m_ReflectionIntensity: 1 - m_CustomReflection: {fileID: 0} - m_Sun: {fileID: 0} - m_IndirectSpecularColor: {r: 0.44657892, g: 0.4964127, b: 0.5748172, a: 1} - m_UseRadianceAmbientProbe: 0 ---- !u!157 &3 -LightmapSettings: - m_ObjectHideFlags: 0 - serializedVersion: 11 - m_GIWorkflowMode: 0 - m_GISettings: - serializedVersion: 2 - m_BounceScale: 1 - m_IndirectOutputScale: 1 - m_AlbedoBoost: 1 - m_EnvironmentLightingMode: 0 - m_EnableBakedLightmaps: 1 - m_EnableRealtimeLightmaps: 1 - m_LightmapEditorSettings: - serializedVersion: 10 - m_Resolution: 2 - m_BakeResolution: 40 - m_AtlasSize: 1024 - m_AO: 0 - m_AOMaxDistance: 1 - m_CompAOExponent: 1 - m_CompAOExponentDirect: 0 - m_Padding: 2 - m_LightmapParameters: {fileID: 0} - m_LightmapsBakeMode: 1 - m_TextureCompression: 1 - m_FinalGather: 0 - m_FinalGatherFiltering: 1 - m_FinalGatherRayCount: 256 - m_ReflectionCompression: 2 - m_MixedBakeMode: 2 - m_BakeBackend: 1 - m_PVRSampling: 1 - m_PVRDirectSampleCount: 32 - m_PVRSampleCount: 500 - m_PVRBounces: 2 - m_PVRFilterTypeDirect: 0 - m_PVRFilterTypeIndirect: 0 - m_PVRFilterTypeAO: 0 - m_PVRFilteringMode: 1 - m_PVRCulling: 1 - m_PVRFilteringGaussRadiusDirect: 1 - m_PVRFilteringGaussRadiusIndirect: 5 - m_PVRFilteringGaussRadiusAO: 2 - m_PVRFilteringAtrousPositionSigmaDirect: 0.5 - m_PVRFilteringAtrousPositionSigmaIndirect: 2 - m_PVRFilteringAtrousPositionSigmaAO: 1 - m_ShowResolutionOverlay: 1 - m_LightingDataAsset: {fileID: 0} - m_UseShadowmask: 1 ---- !u!196 &4 -NavMeshSettings: - serializedVersion: 2 - m_ObjectHideFlags: 0 - m_BuildSettings: - serializedVersion: 2 - agentTypeID: 0 - agentRadius: 0.5 - agentHeight: 2 - agentSlope: 45 - agentClimb: 0.4 - ledgeDropHeight: 0 - maxJumpAcrossDistance: 0 - minRegionArea: 2 - manualCellSize: 0 - cellSize: 0.16666667 - manualTileSize: 0 - tileSize: 256 - accuratePlacement: 0 - debug: - m_Flags: 0 - m_NavMeshData: {fileID: 0} ---- !u!1 &4286172 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 4286176} - - component: {fileID: 4286175} - - component: {fileID: 4286174} - - component: {fileID: 4286173} - m_Layer: 5 - m_Name: Canvas - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!114 &4286173 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 4286172} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 1301386320, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_IgnoreReversedGraphics: 1 - m_BlockingObjects: 0 - m_BlockingMask: - serializedVersion: 2 - m_Bits: 4294967295 ---- !u!114 &4286174 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 4286172} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 1980459831, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_UiScaleMode: 0 - m_ReferencePixelsPerUnit: 100 - m_ScaleFactor: 1 - m_ReferenceResolution: {x: 800, y: 600} - m_ScreenMatchMode: 0 - m_MatchWidthOrHeight: 0 - m_PhysicalUnit: 3 - m_FallbackScreenDPI: 96 - m_DefaultSpriteDPI: 96 - m_DynamicPixelsPerUnit: 1 ---- !u!223 &4286175 -Canvas: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 4286172} - m_Enabled: 1 - serializedVersion: 3 - m_RenderMode: 0 - m_Camera: {fileID: 0} - m_PlaneDistance: 100 - m_PixelPerfect: 0 - m_ReceivesEvents: 1 - m_OverrideSorting: 0 - m_OverridePixelPerfect: 0 - m_SortingBucketNormalizedSize: 0 - m_AdditionalShaderChannelsFlag: 0 - m_SortingLayerID: 0 - m_SortingOrder: 0 - m_TargetDisplay: 0 ---- !u!224 &4286176 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 4286172} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 0, y: 0, z: 0} - m_Children: - - {fileID: 927824195} - - {fileID: 1158582124} - - {fileID: 172161728} - m_Father: {fileID: 0} - m_RootOrder: 2 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 0, y: 0} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0, y: 0} ---- !u!1 &26611619 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 26611622} - - component: {fileID: 26611621} - - component: {fileID: 26611620} - m_Layer: 0 - m_Name: Main Camera - m_TagString: MainCamera - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!81 &26611620 -AudioListener: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 26611619} - m_Enabled: 1 ---- !u!20 &26611621 -Camera: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 26611619} - m_Enabled: 1 - serializedVersion: 2 - m_ClearFlags: 1 - m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} - m_projectionMatrixMode: 1 - m_SensorSize: {x: 36, y: 24} - m_LensShift: {x: 0, y: 0} - m_GateFitMode: 2 - m_FocalLength: 50 - m_NormalizedViewPortRect: - serializedVersion: 2 - x: 0 - y: 0 - width: 1 - height: 1 - near clip plane: 0.3 - far clip plane: 1000 - field of view: 60 - orthographic: 0 - orthographic size: 5 - m_Depth: -1 - m_CullingMask: - serializedVersion: 2 - m_Bits: 4294967295 - m_RenderingPath: -1 - m_TargetTexture: {fileID: 0} - m_TargetDisplay: 0 - m_TargetEye: 3 - m_HDR: 1 - m_AllowMSAA: 1 - m_AllowDynamicResolution: 0 - m_ForceIntoRT: 0 - m_OcclusionCulling: 1 - m_StereoConvergence: 10 - m_StereoSeparation: 0.022 ---- !u!4 &26611622 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 26611619} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 1, z: -10} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!1 &172161727 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 172161728} - - component: {fileID: 172161730} - - component: {fileID: 172161729} - m_Layer: 5 - m_Name: PageView - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 0 ---- !u!224 &172161728 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 172161727} - m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 4286176} - m_RootOrder: 2 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &172161729 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 172161727} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: a8dea5be0500345ccb20b797d19e741c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_Texture: {fileID: 0} - m_UVRect: - serializedVersion: 2 - x: 0 - y: 0 - width: 1 - height: 1 ---- !u!222 &172161730 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 172161727} - m_CullTransparentMesh: 0 ---- !u!1 &897547349 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 897547351} - - component: {fileID: 897547350} - m_Layer: 0 - m_Name: Directional Light - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!108 &897547350 -Light: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 897547349} - m_Enabled: 1 - serializedVersion: 8 - m_Type: 1 - m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} - m_Intensity: 1 - m_Range: 10 - m_SpotAngle: 30 - m_CookieSize: 10 - m_Shadows: - m_Type: 2 - m_Resolution: -1 - m_CustomResolution: -1 - m_Strength: 1 - m_Bias: 0.05 - m_NormalBias: 0.4 - m_NearPlane: 0.2 - m_Cookie: {fileID: 0} - m_DrawHalo: 0 - m_Flare: {fileID: 0} - m_RenderMode: 0 - m_CullingMask: - serializedVersion: 2 - m_Bits: 4294967295 - m_Lightmapping: 4 - m_LightShadowCasterMode: 0 - m_AreaSize: {x: 1, y: 1} - m_BounceIntensity: 1 - m_ColorTemperature: 6570 - m_UseColorTemperature: 0 - m_ShadowRadius: 0 - m_ShadowAngle: 0 ---- !u!4 &897547351 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 897547349} - m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} - m_LocalPosition: {x: 0, y: 3, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 1 - m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} ---- !u!1 &927824194 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 927824195} - - component: {fileID: 927824197} - - component: {fileID: 927824196} - m_Layer: 5 - m_Name: Navigation - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &927824195 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 927824194} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 4286176} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &927824196 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 927824194} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 020016dfbbaef41b496f4e5be17d098c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_Texture: {fileID: 0} - m_UVRect: - serializedVersion: 2 - x: 0 - y: 0 - width: 1 - height: 1 ---- !u!222 &927824197 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 927824194} - m_CullTransparentMesh: 0 ---- !u!1 &1158582123 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1158582124} - - component: {fileID: 1158582126} - - component: {fileID: 1158582125} - m_Layer: 5 - m_Name: CustomPaint - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 0 ---- !u!224 &1158582124 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1158582123} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 4286176} - m_RootOrder: 1 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &1158582125 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1158582123} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 5debfd6de8ea942d487383a56aad8491, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_Texture: {fileID: 0} - m_UVRect: - serializedVersion: 2 - x: 0 - y: 0 - width: 1 - height: 1 ---- !u!222 &1158582126 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1158582123} - m_CullTransparentMesh: 0 ---- !u!1 &1838283857 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1838283860} - - component: {fileID: 1838283859} - - component: {fileID: 1838283858} - m_Layer: 0 - m_Name: EventSystem - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!114 &1838283858 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1838283857} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 1077351063, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_HorizontalAxis: Horizontal - m_VerticalAxis: Vertical - m_SubmitButton: Submit - m_CancelButton: Cancel - m_InputActionsPerSecond: 10 - m_RepeatDelay: 0.5 - m_ForceModuleActive: 0 ---- !u!114 &1838283859 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1838283857} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: -619905303, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_FirstSelected: {fileID: 0} - m_sendNavigationEvents: 1 - m_DragThreshold: 10 ---- !u!4 &1838283860 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1838283857} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 3 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} diff --git a/Samples/UIWidgetSample/Navigation.unity.meta b/Samples/UIWidgetSample/Navigation.unity.meta deleted file mode 100644 index 2a84e5b6..00000000 --- a/Samples/UIWidgetSample/Navigation.unity.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 48300882e985d484880e16569661a93c -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetSample/NavigationSample.cs b/Samples/UIWidgetSample/NavigationSample.cs deleted file mode 100644 index fe48fa9f..00000000 --- a/Samples/UIWidgetSample/NavigationSample.cs +++ /dev/null @@ -1,186 +0,0 @@ -using System; -using System.Collections.Generic; -using Unity.UIWidgets.animation; -using Unity.UIWidgets.foundation; -using Unity.UIWidgets.material; -using Unity.UIWidgets.painting; -using Unity.UIWidgets.rendering; -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; -using DialogUtils = Unity.UIWidgets.widgets.DialogUtils; -using TextStyle = Unity.UIWidgets.painting.TextStyle; - -namespace UIWidgetsSample { - public class NavigationSample : UIWidgetsSamplePanel { - - protected override Widget createWidget() { - return new WidgetsApp( - initialRoute: "/", - textStyle: new TextStyle(fontSize: 24), - pageRouteBuilder: this.pageRouteBuilder, - routes: new Dictionary { - {"/", (context) => new HomeScreen()}, - {"/detail", (context) => new DetailScreen()} - }); - } - - protected override PageRouteFactory pageRouteBuilder { - get { - return (RouteSettings settings, WidgetBuilder builder) => - new PageRouteBuilder( - settings: settings, - pageBuilder: (BuildContext context, Animation animation, - Animation secondaryAnimation) => builder(context), - transitionsBuilder: (BuildContext context, Animation - animation, Animation secondaryAnimation, Widget child) => - new _FadeUpwardsPageTransition( - routeAnimation: animation, - child: child - ) - ); - } - } - } - - - class HomeScreen : StatelessWidget { - public override Widget build(BuildContext context) { - return new NavigationPage( - body: new Container( - color: new Color(0xFF888888), - child: new Center( - child: new CustomButton(onPressed: () => { Navigator.pushNamed(context, "/detail"); }, - child: new Text("Go to Detail")) - )), - title: "Home" - ); - } - } - - class DetailScreen : StatelessWidget { - public override Widget build(BuildContext context) { - return new NavigationPage( - body: new Container( - color: new Color(0xFF1389FD), - child: new Center( - child: new Column( - children: new List() { - new CustomButton(onPressed: () => { Navigator.pop(context); }, child: new Text("Back")), - new CustomButton( - onPressed: () => { - _Dialog.showDialog(context, builder: (BuildContext c) => new Dialog()); - }, child: new Text("Show Dialog")) - } - ) - )), - title: "Detail"); - } - } - - class Dialog : StatelessWidget { - public override Widget build(BuildContext context) { - return new Center(child: new Container( - color: new Color(0xFFFF0000), - width: 100, - height: 80, - child: new Center( - child: new Text("Hello Dialog") - ))); - } - } - - class _FadeUpwardsPageTransition : StatelessWidget { - internal _FadeUpwardsPageTransition( - Key key = null, - Animation routeAnimation = null, // The route's linear 0.0 - 1.0 animation. - Widget child = null - ) : base(key: key) { - this._positionAnimation = _bottomUpTween.chain(_fastOutSlowInTween).animate(routeAnimation); - this._opacityAnimation = _easeInTween.animate(routeAnimation); - this.child = child; - } - - static Tween _bottomUpTween = new OffsetTween( - begin: new Offset(0.0f, 0.25f), - end: Offset.zero - ); - - static Animatable _fastOutSlowInTween = new CurveTween(curve: Curves.fastOutSlowIn); - static Animatable _easeInTween = new CurveTween(curve: Curves.easeIn); - - readonly Animation _positionAnimation; - readonly Animation _opacityAnimation; - public readonly Widget child; - - public override Widget build(BuildContext context) { - return new SlideTransition( - position: this._positionAnimation, - child: new FadeTransition( - opacity: this._opacityAnimation, - child: this.child - ) - ); - } - } - - class NavigationPage : StatelessWidget { - public readonly Widget body; - public readonly string title; - - public NavigationPage(Widget body = null, string title = null) { - this.title = title; - this.body = body; - } - - public override Widget build(BuildContext context) { - Widget back = null; - if (Navigator.of(context).canPop()) { - back = new CustomButton(onPressed: () => { Navigator.pop(context); }, - child: new Text("Go Back")); - back = new Column(mainAxisAlignment: MainAxisAlignment.center, children: new List() {back}); - } - - - return new Container( - child: new Column( - children: new List() { - new ConstrainedBox(constraints: new BoxConstraints(maxHeight: 80), - child: new DecoratedBox( - decoration: new BoxDecoration(color: new Color(0XFFE1ECF4)), - child: new NavigationToolbar(leading: back, - middle: new Text(this.title, textAlign: TextAlign.center)))), - new Flexible(child: this.body) - } - ) - ); - } - } - - static class _Dialog { - public static void showDialog(BuildContext context, - bool barrierDismissible = true, WidgetBuilder builder = null) { - DialogUtils.showGeneralDialog( - context: context, - pageBuilder: (BuildContext buildContext, Animation animation, - Animation secondaryAnimation) => { - return builder(buildContext); - }, - barrierDismissible: barrierDismissible, - barrierColor: new Color(0x8A000000), - transitionDuration: TimeSpan.FromMilliseconds(150), - transitionBuilder: _buildMaterialDialogTransitions - ); - } - - static Widget _buildMaterialDialogTransitions(BuildContext context, - Animation animation, Animation secondaryAnimation, Widget child) { - return new FadeTransition( - opacity: new CurvedAnimation( - parent: animation, - curve: Curves.easeOut - ), - child: child - ); - } - } -} \ No newline at end of file diff --git a/Samples/UIWidgetSample/NavigationSample.cs.meta b/Samples/UIWidgetSample/NavigationSample.cs.meta deleted file mode 100644 index 4e3a12fd..00000000 --- a/Samples/UIWidgetSample/NavigationSample.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 020016dfbbaef41b496f4e5be17d098c -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetSample/PageViewSample.cs b/Samples/UIWidgetSample/PageViewSample.cs deleted file mode 100644 index c8619335..00000000 --- a/Samples/UIWidgetSample/PageViewSample.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.Collections.Generic; -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; - -namespace UIWidgetsSample { - public class PageViewSample : UIWidgetsSamplePanel { - - protected override Widget createWidget() { - return new WidgetsApp( - home: new Container( - width: 200, - height: 400, - child: new PageView( - children: new List() { - new Container( - color: new Color(0xFFE91E63) - ), - new Container( - color: new Color(0xFF00BCD4) - ), - new Container( - color: new Color(0xFF673AB7) - ) - } - )), - pageRouteBuilder: this.pageRouteBuilder); - } - } -} \ No newline at end of file diff --git a/Samples/UIWidgetSample/PageViewSample.cs.meta b/Samples/UIWidgetSample/PageViewSample.cs.meta deleted file mode 100644 index db4487e5..00000000 --- a/Samples/UIWidgetSample/PageViewSample.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: a8dea5be0500345ccb20b797d19e741c -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetSample/Resources.meta b/Samples/UIWidgetSample/Resources.meta deleted file mode 100644 index 89285f4a..00000000 --- a/Samples/UIWidgetSample/Resources.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 77196fe8699ab4d4ebcdcd40d51ad725 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetSample/Resources/VideoSampleRT.renderTexture b/Samples/UIWidgetSample/Resources/VideoSampleRT.renderTexture deleted file mode 100644 index 40eaf3b4..00000000 --- a/Samples/UIWidgetSample/Resources/VideoSampleRT.renderTexture +++ /dev/null @@ -1,34 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!84 &8400000 -RenderTexture: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_Name: VideoSampleRT - m_ImageContentsHash: - serializedVersion: 2 - Hash: 00000000000000000000000000000000 - m_ForcedFallbackFormat: 4 - m_DownscaleFallback: 0 - m_Width: 480 - m_Height: 270 - m_AntiAliasing: 1 - m_DepthFormat: 2 - m_ColorFormat: 0 - m_MipMap: 0 - m_GenerateMips: 1 - m_SRGB: 0 - m_UseDynamicScale: 0 - m_BindMS: 0 - m_TextureSettings: - serializedVersion: 2 - m_FilterMode: 0 - m_Aniso: 0 - m_MipBias: 0 - m_WrapU: 1 - m_WrapV: 1 - m_WrapW: 1 - m_Dimension: 2 - m_VolumeDepth: 1 diff --git a/Samples/UIWidgetSample/Resources/VideoSampleRT.renderTexture.meta b/Samples/UIWidgetSample/Resources/VideoSampleRT.renderTexture.meta deleted file mode 100644 index 997a6eb7..00000000 --- a/Samples/UIWidgetSample/Resources/VideoSampleRT.renderTexture.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 53bf3f9b1464948cbb3f58add96afa32 -NativeFormatImporter: - externalObjects: {} - mainObjectFileID: 8400000 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetSample/Resources/file_example_MOV_480_700kB.mov b/Samples/UIWidgetSample/Resources/file_example_MOV_480_700kB.mov deleted file mode 100644 index 28c89a1c..00000000 Binary files a/Samples/UIWidgetSample/Resources/file_example_MOV_480_700kB.mov and /dev/null differ diff --git a/Samples/UIWidgetSample/Resources/file_example_MOV_480_700kB.mov.meta b/Samples/UIWidgetSample/Resources/file_example_MOV_480_700kB.mov.meta deleted file mode 100644 index ebf786d9..00000000 --- a/Samples/UIWidgetSample/Resources/file_example_MOV_480_700kB.mov.meta +++ /dev/null @@ -1,21 +0,0 @@ -fileFormatVersion: 2 -guid: 9906c152cf75248e98d1edd60759f014 -VideoClipImporter: - externalObjects: {} - serializedVersion: 2 - useLegacyImporter: 0 - quality: 0.5 - isColorLinear: 0 - frameRange: 0 - startFrame: -1 - endFrame: -1 - colorSpace: 0 - deinterlace: 0 - encodeAlpha: 0 - flipVertical: 0 - flipHorizontal: 0 - importAudio: 1 - targetSettings: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetSample/SampleExample.cs b/Samples/UIWidgetSample/SampleExample.cs deleted file mode 100644 index 2741641f..00000000 --- a/Samples/UIWidgetSample/SampleExample.cs +++ /dev/null @@ -1,8 +0,0 @@ -// ----------------------------------------------------------------------------- -// -// Use this sample example C# file to develop samples to guide usage of APIs -// in your package. -// -// ----------------------------------------------------------------------------- - - diff --git a/Samples/UIWidgetSample/SampleExample.cs.meta b/Samples/UIWidgetSample/SampleExample.cs.meta deleted file mode 100644 index a2deacbf..00000000 --- a/Samples/UIWidgetSample/SampleExample.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: d0b6d46ec9aeb4883a36de0ed9efc4db -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetSample/ScaleGestureSample.cs b/Samples/UIWidgetSample/ScaleGestureSample.cs deleted file mode 100644 index 0a0c8d2b..00000000 --- a/Samples/UIWidgetSample/ScaleGestureSample.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System.Collections.Generic; -using Unity.UIWidgets.material; -using Unity.UIWidgets.rendering; -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; -using UnityEngine; - -namespace UIWidgetsSample { - public class ScaleGestureSample : UIWidgetsSamplePanel { - protected override Widget createWidget() { - return new MaterialApp( - showPerformanceOverlay: false, - home: new ScaleGesturePanel() - ); - } - - protected override void OnEnable() { - FontManager.instance.addFont(Resources.Load(path: "MaterialIcons-Regular"), "Material Icons"); - base.OnEnable(); - } - } - - class ScaleGesturePanel : StatefulWidget { - public override State createState() { - return new ScaleGesturePanelState(); - } - } - - class ScaleGesturePanelState : State { - float scaleValue = 1.0f; - - public override Widget build(BuildContext context) { - return new Scaffold( - appBar: new AppBar( - title: new Center( - child: new Text("Test Scale Gesture Widget") - ) - ), - body: new GestureDetector( - onScaleStart: scaleDetails => { Debug.Log("Scale Start !"); }, - onScaleUpdate: scaleDetails => { - Debug.Log("Scale value = " + scaleDetails.scale); - this.setState(() => { this.scaleValue = scaleDetails.scale; }); - }, - onScaleEnd: scaleDetails => { Debug.Log("Scale End"); }, - child: new Card( - color: Colors.white, - child: new Center( - child: new Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.center, - children: new List { - new Icon(Unity.UIWidgets.material.Icons.ac_unit, size: 128.0f, color: Colors.black), - new RaisedButton( - child: new Text("Scale: " + this.scaleValue), - onPressed: () => { Debug.Log("Button Pressed"); }) - } - ) - )) - ) - ); - } - } -} \ No newline at end of file diff --git a/Samples/UIWidgetSample/ScaleGestureSample.cs.meta b/Samples/UIWidgetSample/ScaleGestureSample.cs.meta deleted file mode 100644 index f3974db9..00000000 --- a/Samples/UIWidgetSample/ScaleGestureSample.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 38800d11bb7a9447582e892145b3bd82 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetSample/ScrollBar.unity b/Samples/UIWidgetSample/ScrollBar.unity deleted file mode 100644 index 028acf60..00000000 --- a/Samples/UIWidgetSample/ScrollBar.unity +++ /dev/null @@ -1,502 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!29 &1 -OcclusionCullingSettings: - m_ObjectHideFlags: 0 - serializedVersion: 2 - m_OcclusionBakeSettings: - smallestOccluder: 5 - smallestHole: 0.25 - backfaceThreshold: 100 - m_SceneGUID: 00000000000000000000000000000000 - m_OcclusionCullingData: {fileID: 0} ---- !u!104 &2 -RenderSettings: - m_ObjectHideFlags: 0 - serializedVersion: 9 - m_Fog: 0 - m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} - m_FogMode: 3 - m_FogDensity: 0.01 - m_LinearFogStart: 0 - m_LinearFogEnd: 300 - m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} - m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} - m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} - m_AmbientIntensity: 1 - m_AmbientMode: 0 - m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} - m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} - m_HaloStrength: 0.5 - m_FlareStrength: 1 - m_FlareFadeSpeed: 3 - m_HaloTexture: {fileID: 0} - m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} - m_DefaultReflectionMode: 0 - m_DefaultReflectionResolution: 128 - m_ReflectionBounces: 1 - m_ReflectionIntensity: 1 - m_CustomReflection: {fileID: 0} - m_Sun: {fileID: 0} - m_IndirectSpecularColor: {r: 0.44657898, g: 0.49641275, b: 0.5748174, a: 1} - m_UseRadianceAmbientProbe: 0 ---- !u!157 &3 -LightmapSettings: - m_ObjectHideFlags: 0 - serializedVersion: 11 - m_GIWorkflowMode: 0 - m_GISettings: - serializedVersion: 2 - m_BounceScale: 1 - m_IndirectOutputScale: 1 - m_AlbedoBoost: 1 - m_EnvironmentLightingMode: 0 - m_EnableBakedLightmaps: 1 - m_EnableRealtimeLightmaps: 1 - m_LightmapEditorSettings: - serializedVersion: 10 - m_Resolution: 2 - m_BakeResolution: 40 - m_AtlasSize: 1024 - m_AO: 0 - m_AOMaxDistance: 1 - m_CompAOExponent: 1 - m_CompAOExponentDirect: 0 - m_Padding: 2 - m_LightmapParameters: {fileID: 0} - m_LightmapsBakeMode: 1 - m_TextureCompression: 1 - m_FinalGather: 0 - m_FinalGatherFiltering: 1 - m_FinalGatherRayCount: 256 - m_ReflectionCompression: 2 - m_MixedBakeMode: 2 - m_BakeBackend: 1 - m_PVRSampling: 1 - m_PVRDirectSampleCount: 32 - m_PVRSampleCount: 500 - m_PVRBounces: 2 - m_PVRFilterTypeDirect: 0 - m_PVRFilterTypeIndirect: 0 - m_PVRFilterTypeAO: 0 - m_PVRFilteringMode: 1 - m_PVRCulling: 1 - m_PVRFilteringGaussRadiusDirect: 1 - m_PVRFilteringGaussRadiusIndirect: 5 - m_PVRFilteringGaussRadiusAO: 2 - m_PVRFilteringAtrousPositionSigmaDirect: 0.5 - m_PVRFilteringAtrousPositionSigmaIndirect: 2 - m_PVRFilteringAtrousPositionSigmaAO: 1 - m_ShowResolutionOverlay: 1 - m_LightingDataAsset: {fileID: 0} - m_UseShadowmask: 1 ---- !u!196 &4 -NavMeshSettings: - serializedVersion: 2 - m_ObjectHideFlags: 0 - m_BuildSettings: - serializedVersion: 2 - agentTypeID: 0 - agentRadius: 0.5 - agentHeight: 2 - agentSlope: 45 - agentClimb: 0.4 - ledgeDropHeight: 0 - maxJumpAcrossDistance: 0 - minRegionArea: 2 - manualCellSize: 0 - cellSize: 0.16666667 - manualTileSize: 0 - tileSize: 256 - accuratePlacement: 0 - debug: - m_Flags: 0 - m_NavMeshData: {fileID: 0} ---- !u!1 &288417894 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 288417898} - - component: {fileID: 288417897} - - component: {fileID: 288417896} - - component: {fileID: 288417895} - m_Layer: 5 - m_Name: Canvas - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!114 &288417895 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 288417894} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 1301386320, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_IgnoreReversedGraphics: 1 - m_BlockingObjects: 0 - m_BlockingMask: - serializedVersion: 2 - m_Bits: 4294967295 ---- !u!114 &288417896 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 288417894} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 1980459831, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_UiScaleMode: 0 - m_ReferencePixelsPerUnit: 100 - m_ScaleFactor: 1 - m_ReferenceResolution: {x: 800, y: 600} - m_ScreenMatchMode: 0 - m_MatchWidthOrHeight: 0 - m_PhysicalUnit: 3 - m_FallbackScreenDPI: 96 - m_DefaultSpriteDPI: 96 - m_DynamicPixelsPerUnit: 1 ---- !u!223 &288417897 -Canvas: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 288417894} - m_Enabled: 1 - serializedVersion: 3 - m_RenderMode: 0 - m_Camera: {fileID: 0} - m_PlaneDistance: 100 - m_PixelPerfect: 0 - m_ReceivesEvents: 1 - m_OverrideSorting: 0 - m_OverridePixelPerfect: 0 - m_SortingBucketNormalizedSize: 0 - m_AdditionalShaderChannelsFlag: 0 - m_SortingLayerID: 0 - m_SortingOrder: 0 - m_TargetDisplay: 0 ---- !u!224 &288417898 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 288417894} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 0, y: 0, z: 0} - m_Children: - - {fileID: 1525809614} - m_Father: {fileID: 0} - m_RootOrder: 2 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 0, y: 0} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0, y: 0} ---- !u!1 &501956623 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 501956625} - - component: {fileID: 501956624} - m_Layer: 0 - m_Name: Directional Light - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!108 &501956624 -Light: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 501956623} - m_Enabled: 1 - serializedVersion: 8 - m_Type: 1 - m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} - m_Intensity: 1 - m_Range: 10 - m_SpotAngle: 30 - m_CookieSize: 10 - m_Shadows: - m_Type: 2 - m_Resolution: -1 - m_CustomResolution: -1 - m_Strength: 1 - m_Bias: 0.05 - m_NormalBias: 0.4 - m_NearPlane: 0.2 - m_Cookie: {fileID: 0} - m_DrawHalo: 0 - m_Flare: {fileID: 0} - m_RenderMode: 0 - m_CullingMask: - serializedVersion: 2 - m_Bits: 4294967295 - m_Lightmapping: 4 - m_LightShadowCasterMode: 0 - m_AreaSize: {x: 1, y: 1} - m_BounceIntensity: 1 - m_ColorTemperature: 6570 - m_UseColorTemperature: 0 - m_ShadowRadius: 0 - m_ShadowAngle: 0 ---- !u!4 &501956625 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 501956623} - m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} - m_LocalPosition: {x: 0, y: 3, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 1 - m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} ---- !u!1 &522912515 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 522912518} - - component: {fileID: 522912517} - - component: {fileID: 522912516} - m_Layer: 0 - m_Name: EventSystem - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!114 &522912516 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 522912515} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 1077351063, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_HorizontalAxis: Horizontal - m_VerticalAxis: Vertical - m_SubmitButton: Submit - m_CancelButton: Cancel - m_InputActionsPerSecond: 10 - m_RepeatDelay: 0.5 - m_ForceModuleActive: 0 ---- !u!114 &522912517 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 522912515} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: -619905303, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_FirstSelected: {fileID: 0} - m_sendNavigationEvents: 1 - m_DragThreshold: 10 ---- !u!4 &522912518 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 522912515} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 3 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!1 &1525809613 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1525809614} - - component: {fileID: 1525809615} - - component: {fileID: 1525809616} - m_Layer: 5 - m_Name: GameObject - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &1525809614 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1525809613} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 288417898} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0.5, y: 0.5} - m_AnchorMax: {x: 0.5, y: 0.5} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 100, y: 100} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!222 &1525809615 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1525809613} - m_CullTransparentMesh: 0 ---- !u!114 &1525809616 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1525809613} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: c5c73cb2437bb4d369115d787656adf4, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_Texture: {fileID: 0} - m_UVRect: - serializedVersion: 2 - x: 0 - y: 0 - width: 1 - height: 1 ---- !u!1 &1713793689 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1713793692} - - component: {fileID: 1713793691} - - component: {fileID: 1713793690} - m_Layer: 0 - m_Name: Main Camera - m_TagString: MainCamera - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!81 &1713793690 -AudioListener: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1713793689} - m_Enabled: 1 ---- !u!20 &1713793691 -Camera: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1713793689} - m_Enabled: 1 - serializedVersion: 2 - m_ClearFlags: 1 - m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} - m_projectionMatrixMode: 1 - m_SensorSize: {x: 36, y: 24} - m_LensShift: {x: 0, y: 0} - m_GateFitMode: 2 - m_FocalLength: 50 - m_NormalizedViewPortRect: - serializedVersion: 2 - x: 0 - y: 0 - width: 1 - height: 1 - near clip plane: 0.3 - far clip plane: 1000 - field of view: 60 - orthographic: 0 - orthographic size: 5 - m_Depth: -1 - m_CullingMask: - serializedVersion: 2 - m_Bits: 4294967295 - m_RenderingPath: -1 - m_TargetTexture: {fileID: 0} - m_TargetDisplay: 0 - m_TargetEye: 3 - m_HDR: 1 - m_AllowMSAA: 1 - m_AllowDynamicResolution: 0 - m_ForceIntoRT: 0 - m_OcclusionCulling: 1 - m_StereoConvergence: 10 - m_StereoSeparation: 0.022 ---- !u!4 &1713793692 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1713793689} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 1, z: -10} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} diff --git a/Samples/UIWidgetSample/ScrollBar.unity.meta b/Samples/UIWidgetSample/ScrollBar.unity.meta deleted file mode 100644 index 5f9a3e6e..00000000 --- a/Samples/UIWidgetSample/ScrollBar.unity.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 254fc2f80945542b191aff7ab8fda8cb -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetSample/ScrollbarSample.cs b/Samples/UIWidgetSample/ScrollbarSample.cs deleted file mode 100644 index 766fb9c7..00000000 --- a/Samples/UIWidgetSample/ScrollbarSample.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System.Collections.Generic; -using Unity.UIWidgets.material; -using Unity.UIWidgets.painting; -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; - -namespace UIWidgetsSample { - public class ScrollbarSample : UIWidgetsSamplePanel { - protected override Widget createWidget() { - var scroll = new Container( - decoration: new BoxDecoration( - border: Border.all(color: new Color(0xFFFFFF00)) - ), - child: new Scrollbar( - child: new ListView( - children: new List { - new Container(height: 40.0f, child: new Text("0")), - new Container(height: 40.0f, child: new Text("1")), - new Container(height: 40.0f, child: new Text("2")), - new Container(height: 40.0f, child: new Text("3")), - new Container(height: 40.0f, child: new Text("4")), - new Container(height: 40.0f, child: new Text("5")), - new Container(height: 40.0f, child: new Text("6")), - new Container(height: 40.0f, child: new Text("7")), - new Container(height: 40.0f, child: new Text("8")), - new Container(height: 40.0f, child: new Text("9")), - new Container(height: 40.0f, child: new Text("10")), - new Container(height: 40.0f, child: new Text("11")), - new Container(height: 40.0f, child: new Text("12")), - new Container(height: 40.0f, child: new Text("13")), - new Container(height: 40.0f, child: new Text("14")), - new Container(height: 40.0f, child: new Text("15")), - new Container(height: 40.0f, child: new Text("16")), - new Container(height: 40.0f, child: new Text("17")), - } - ) - ) - ); - return new WidgetsApp( - home: scroll, - pageRouteBuilder: this.pageRouteBuilder); - } - } -} \ No newline at end of file diff --git a/Samples/UIWidgetSample/ScrollbarSample.cs.meta b/Samples/UIWidgetSample/ScrollbarSample.cs.meta deleted file mode 100644 index 28c5e32a..00000000 --- a/Samples/UIWidgetSample/ScrollbarSample.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c5c73cb2437bb4d369115d787656adf4 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetSample/SelectOnStart.cs b/Samples/UIWidgetSample/SelectOnStart.cs deleted file mode 100644 index 610717f2..00000000 --- a/Samples/UIWidgetSample/SelectOnStart.cs +++ /dev/null @@ -1,10 +0,0 @@ -using UnityEngine; -using UnityEngine.EventSystems; - -namespace UIWidgetsSample { - public class SelectOnStart : MonoBehaviour { - void Start() { - EventSystem.current.SetSelectedGameObject(this.gameObject); - } - } -} \ No newline at end of file diff --git a/Samples/UIWidgetSample/SelectOnStart.cs.meta b/Samples/UIWidgetSample/SelectOnStart.cs.meta deleted file mode 100644 index 5ab30bf4..00000000 --- a/Samples/UIWidgetSample/SelectOnStart.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c42d7614d405d465aab861f4a0cb146e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetSample/TextInput.unity b/Samples/UIWidgetSample/TextInput.unity deleted file mode 100644 index 349a8462..00000000 --- a/Samples/UIWidgetSample/TextInput.unity +++ /dev/null @@ -1,1751 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!29 &1 -OcclusionCullingSettings: - m_ObjectHideFlags: 0 - serializedVersion: 2 - m_OcclusionBakeSettings: - smallestOccluder: 5 - smallestHole: 0.25 - backfaceThreshold: 100 - m_SceneGUID: 00000000000000000000000000000000 - m_OcclusionCullingData: {fileID: 0} ---- !u!104 &2 -RenderSettings: - m_ObjectHideFlags: 0 - serializedVersion: 9 - m_Fog: 0 - m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} - m_FogMode: 3 - m_FogDensity: 0.01 - m_LinearFogStart: 0 - m_LinearFogEnd: 300 - m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} - m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} - m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} - m_AmbientIntensity: 1 - m_AmbientMode: 0 - m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} - m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} - m_HaloStrength: 0.5 - m_FlareStrength: 1 - m_FlareFadeSpeed: 3 - m_HaloTexture: {fileID: 0} - m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} - m_DefaultReflectionMode: 0 - m_DefaultReflectionResolution: 128 - m_ReflectionBounces: 1 - m_ReflectionIntensity: 1 - m_CustomReflection: {fileID: 0} - m_Sun: {fileID: 0} - m_IndirectSpecularColor: {r: 0.37311953, g: 0.38074, b: 0.35872698, a: 1} - m_UseRadianceAmbientProbe: 0 ---- !u!157 &3 -LightmapSettings: - m_ObjectHideFlags: 0 - serializedVersion: 11 - m_GIWorkflowMode: 0 - m_GISettings: - serializedVersion: 2 - m_BounceScale: 1 - m_IndirectOutputScale: 1 - m_AlbedoBoost: 1 - m_EnvironmentLightingMode: 0 - m_EnableBakedLightmaps: 1 - m_EnableRealtimeLightmaps: 1 - m_LightmapEditorSettings: - serializedVersion: 10 - m_Resolution: 2 - m_BakeResolution: 40 - m_AtlasSize: 1024 - m_AO: 0 - m_AOMaxDistance: 1 - m_CompAOExponent: 1 - m_CompAOExponentDirect: 0 - m_Padding: 2 - m_LightmapParameters: {fileID: 0} - m_LightmapsBakeMode: 1 - m_TextureCompression: 1 - m_FinalGather: 0 - m_FinalGatherFiltering: 1 - m_FinalGatherRayCount: 256 - m_ReflectionCompression: 2 - m_MixedBakeMode: 2 - m_BakeBackend: 1 - m_PVRSampling: 1 - m_PVRDirectSampleCount: 32 - m_PVRSampleCount: 500 - m_PVRBounces: 2 - m_PVRFilterTypeDirect: 0 - m_PVRFilterTypeIndirect: 0 - m_PVRFilterTypeAO: 0 - m_PVRFilteringMode: 1 - m_PVRCulling: 1 - m_PVRFilteringGaussRadiusDirect: 1 - m_PVRFilteringGaussRadiusIndirect: 5 - m_PVRFilteringGaussRadiusAO: 2 - m_PVRFilteringAtrousPositionSigmaDirect: 0.5 - m_PVRFilteringAtrousPositionSigmaIndirect: 2 - m_PVRFilteringAtrousPositionSigmaAO: 1 - m_ShowResolutionOverlay: 1 - m_LightingDataAsset: {fileID: 0} - m_UseShadowmask: 1 ---- !u!196 &4 -NavMeshSettings: - serializedVersion: 2 - m_ObjectHideFlags: 0 - m_BuildSettings: - serializedVersion: 2 - agentTypeID: 0 - agentRadius: 0.5 - agentHeight: 2 - agentSlope: 45 - agentClimb: 0.4 - ledgeDropHeight: 0 - maxJumpAcrossDistance: 0 - minRegionArea: 2 - manualCellSize: 0 - cellSize: 0.16666667 - manualTileSize: 0 - tileSize: 256 - accuratePlacement: 0 - debug: - m_Flags: 0 - m_NavMeshData: {fileID: 0} ---- !u!1 &43384371 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 43384372} - - component: {fileID: 43384374} - - component: {fileID: 43384373} - m_Layer: 5 - m_Name: Background - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &43384372 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 43384371} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 1556903570} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0.25} - m_AnchorMax: {x: 1, y: 0.75} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &43384373 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 43384371} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} - m_Type: 1 - m_PreserveAspect: 0 - m_FillCenter: 1 - m_FillMethod: 4 - m_FillAmount: 1 - m_FillClockwise: 1 - m_FillOrigin: 0 - m_UseSpriteMesh: 0 ---- !u!222 &43384374 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 43384371} - m_CullTransparentMesh: 0 ---- !u!1 &71411787 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 71411788} - m_Layer: 5 - m_Name: Handle Slide Area - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &71411788 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 71411787} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: - - {fileID: 385671180} - m_Father: {fileID: 1556903570} - m_RootOrder: 2 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: -20, y: 0} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!1 &244594849 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 244594852} - - component: {fileID: 244594851} - - component: {fileID: 244594850} - - component: {fileID: 244594854} - m_Layer: 0 - m_Name: Main Camera - m_TagString: MainCamera - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!81 &244594850 -AudioListener: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 244594849} - m_Enabled: 1 ---- !u!20 &244594851 -Camera: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 244594849} - m_Enabled: 1 - serializedVersion: 2 - m_ClearFlags: 2 - m_BackGroundColor: {r: 1, g: 1, b: 1, a: 1} - m_projectionMatrixMode: 1 - m_SensorSize: {x: 36, y: 24} - m_LensShift: {x: 0, y: 0} - m_GateFitMode: 2 - m_FocalLength: 50 - m_NormalizedViewPortRect: - serializedVersion: 2 - x: 0 - y: 0 - width: 1 - height: 1 - near clip plane: 1 - far clip plane: 100 - field of view: 26.991467 - orthographic: 0 - orthographic size: 5 - m_Depth: -1 - m_CullingMask: - serializedVersion: 2 - m_Bits: 4294967295 - m_RenderingPath: -1 - m_TargetTexture: {fileID: 0} - m_TargetDisplay: 0 - m_TargetEye: 3 - m_HDR: 1 - m_AllowMSAA: 1 - m_AllowDynamicResolution: 0 - m_ForceIntoRT: 0 - m_OcclusionCulling: 1 - m_StereoConvergence: 10 - m_StereoSeparation: 0.022 ---- !u!4 &244594852 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 244594849} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: -15} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!114 &244594854 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 244594849} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: -768656878, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_EventMask: - serializedVersion: 2 - m_Bits: 4294967295 - m_MaxRayIntersections: 0 ---- !u!1 &304189370 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 304189374} - - component: {fileID: 304189373} - - component: {fileID: 304189372} - - component: {fileID: 304189371} - - component: {fileID: 304189376} - m_Layer: 5 - m_Name: Canvas - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!114 &304189371 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 304189370} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 1301386320, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_IgnoreReversedGraphics: 1 - m_BlockingObjects: 0 - m_BlockingMask: - serializedVersion: 2 - m_Bits: 4294967295 ---- !u!114 &304189372 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 304189370} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 1980459831, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_UiScaleMode: 0 - m_ReferencePixelsPerUnit: 100 - m_ScaleFactor: 1.5 - m_ReferenceResolution: {x: 800, y: 600} - m_ScreenMatchMode: 0 - m_MatchWidthOrHeight: 0 - m_PhysicalUnit: 3 - m_FallbackScreenDPI: 96 - m_DefaultSpriteDPI: 96 - m_DynamicPixelsPerUnit: 1 ---- !u!223 &304189373 -Canvas: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 304189370} - m_Enabled: 1 - serializedVersion: 3 - m_RenderMode: 0 - m_Camera: {fileID: 0} - m_PlaneDistance: 100 - m_PixelPerfect: 0 - m_ReceivesEvents: 1 - m_OverrideSorting: 0 - m_OverridePixelPerfect: 0 - m_SortingBucketNormalizedSize: 0 - m_AdditionalShaderChannelsFlag: 0 - m_SortingLayerID: 0 - m_SortingOrder: 0 - m_TargetDisplay: 0 ---- !u!224 &304189374 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 304189370} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 0, y: 0, z: 0} - m_Children: - - {fileID: 1387978527} - - {fileID: 1354314692} - - {fileID: 1142533064} - - {fileID: 1399904531} - m_Father: {fileID: 0} - m_RootOrder: 2 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 0, y: 0} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0, y: 0} ---- !u!222 &304189376 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 304189370} - m_CullTransparentMesh: 0 ---- !u!1 &335487698 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 335487699} - - component: {fileID: 335487702} - - component: {fileID: 335487701} - - component: {fileID: 335487700} - m_Layer: 5 - m_Name: Button - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &335487699 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 335487698} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: - - {fileID: 998549136} - m_Father: {fileID: 1399904531} - m_RootOrder: 3 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0.5, y: 0.5} - m_AnchorMax: {x: 0.5, y: 0.5} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 160, y: 30} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &335487700 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 335487698} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 1392445389, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Navigation: - m_Mode: 3 - m_SelectOnUp: {fileID: 0} - m_SelectOnDown: {fileID: 0} - m_SelectOnLeft: {fileID: 0} - m_SelectOnRight: {fileID: 0} - m_Transition: 1 - m_Colors: - m_NormalColor: {r: 1, g: 1, b: 1, a: 1} - m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} - m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} - m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} - m_ColorMultiplier: 1 - m_FadeDuration: 0.1 - m_SpriteState: - m_HighlightedSprite: {fileID: 0} - m_PressedSprite: {fileID: 0} - m_DisabledSprite: {fileID: 0} - m_AnimationTriggers: - m_NormalTrigger: Normal - m_HighlightedTrigger: Highlighted - m_PressedTrigger: Pressed - m_DisabledTrigger: Disabled - m_Interactable: 1 - m_TargetGraphic: {fileID: 335487701} - m_OnClick: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0, - Culture=neutral, PublicKeyToken=null ---- !u!114 &335487701 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 335487698} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} - m_Type: 1 - m_PreserveAspect: 0 - m_FillCenter: 1 - m_FillMethod: 4 - m_FillAmount: 1 - m_FillClockwise: 1 - m_FillOrigin: 0 - m_UseSpriteMesh: 0 ---- !u!222 &335487702 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 335487698} - m_CullTransparentMesh: 0 ---- !u!1 &385671179 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 385671180} - - component: {fileID: 385671182} - - component: {fileID: 385671181} - m_Layer: 5 - m_Name: Handle - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &385671180 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 385671179} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 71411788} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 0, y: 1} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 20, y: 0} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &385671181 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 385671179} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_Sprite: {fileID: 10913, guid: 0000000000000000f000000000000000, type: 0} - m_Type: 0 - m_PreserveAspect: 0 - m_FillCenter: 1 - m_FillMethod: 4 - m_FillAmount: 1 - m_FillClockwise: 1 - m_FillOrigin: 0 - m_UseSpriteMesh: 0 ---- !u!222 &385671182 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 385671179} - m_CullTransparentMesh: 0 ---- !u!1 &390948269 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 390948272} - - component: {fileID: 390948271} - - component: {fileID: 390948270} - m_Layer: 0 - m_Name: EventSystem - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!114 &390948270 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 390948269} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 1077351063, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_HorizontalAxis: Horizontal - m_VerticalAxis: Vertical - m_SubmitButton: Submit - m_CancelButton: Cancel - m_InputActionsPerSecond: 10 - m_RepeatDelay: 0.5 - m_ForceModuleActive: 0 ---- !u!114 &390948271 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 390948269} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: -619905303, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_FirstSelected: {fileID: 0} - m_sendNavigationEvents: 1 - m_DragThreshold: 10 ---- !u!4 &390948272 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 390948269} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 3 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!1 &431912886 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 431912887} - m_Layer: 5 - m_Name: Fill Area - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &431912887 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 431912886} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: - - {fileID: 1777916082} - m_Father: {fileID: 1556903570} - m_RootOrder: 1 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0.25} - m_AnchorMax: {x: 1, y: 0.75} - m_AnchoredPosition: {x: -5, y: 0} - m_SizeDelta: {x: -20, y: 0} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!1 &554372217 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 554372218} - - component: {fileID: 554372221} - - component: {fileID: 554372220} - - component: {fileID: 554372219} - m_Layer: 5 - m_Name: InputField - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &554372218 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 554372217} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: - - {fileID: 1148735785} - - {fileID: 1621115925} - m_Father: {fileID: 1399904531} - m_RootOrder: 1 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0.5, y: 1} - m_AnchorMax: {x: 0.5, y: 1} - m_AnchoredPosition: {x: 0, y: -100} - m_SizeDelta: {x: 160, y: 30} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &554372219 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 554372217} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 575553740, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Navigation: - m_Mode: 3 - m_SelectOnUp: {fileID: 0} - m_SelectOnDown: {fileID: 0} - m_SelectOnLeft: {fileID: 0} - m_SelectOnRight: {fileID: 0} - m_Transition: 1 - m_Colors: - m_NormalColor: {r: 1, g: 1, b: 1, a: 1} - m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} - m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} - m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} - m_ColorMultiplier: 1 - m_FadeDuration: 0.1 - m_SpriteState: - m_HighlightedSprite: {fileID: 0} - m_PressedSprite: {fileID: 0} - m_DisabledSprite: {fileID: 0} - m_AnimationTriggers: - m_NormalTrigger: Normal - m_HighlightedTrigger: Highlighted - m_PressedTrigger: Pressed - m_DisabledTrigger: Disabled - m_Interactable: 1 - m_TargetGraphic: {fileID: 554372220} - m_TextComponent: {fileID: 1621115926} - m_Placeholder: {fileID: 1148735786} - m_ContentType: 0 - m_InputType: 0 - m_AsteriskChar: 42 - m_KeyboardType: 0 - m_LineType: 0 - m_HideMobileInput: 0 - m_CharacterValidation: 0 - m_CharacterLimit: 0 - m_OnEndEdit: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.InputField+SubmitEvent, UnityEngine.UI, Version=1.0.0.0, - Culture=neutral, PublicKeyToken=null - m_OnValueChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.InputField+OnChangeEvent, UnityEngine.UI, Version=1.0.0.0, - Culture=neutral, PublicKeyToken=null - m_CaretColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} - m_CustomCaretColor: 0 - m_SelectionColor: {r: 0.65882355, g: 0.80784315, b: 1, a: 0.7529412} - m_Text: - m_CaretBlinkRate: 0.85 - m_CaretWidth: 1 - m_ReadOnly: 0 ---- !u!114 &554372220 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 554372217} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_Sprite: {fileID: 10911, guid: 0000000000000000f000000000000000, type: 0} - m_Type: 1 - m_PreserveAspect: 0 - m_FillCenter: 1 - m_FillMethod: 4 - m_FillAmount: 1 - m_FillClockwise: 1 - m_FillOrigin: 0 - m_UseSpriteMesh: 0 ---- !u!222 &554372221 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 554372217} - m_CullTransparentMesh: 0 ---- !u!1 &579295879 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 579295880} - - component: {fileID: 579295882} - - component: {fileID: 579295881} - m_Layer: 5 - m_Name: Text - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &579295880 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 579295879} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 1399904531} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0.5, y: 1} - m_AnchorMax: {x: 0.5, y: 1} - m_AnchoredPosition: {x: 0, y: -30} - m_SizeDelta: {x: 160, y: 30} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &579295881 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 579295879} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_FontData: - m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} - m_FontSize: 14 - m_FontStyle: 0 - m_BestFit: 0 - m_MinSize: 10 - m_MaxSize: 40 - m_Alignment: 0 - m_AlignByGeometry: 0 - m_RichText: 1 - m_HorizontalOverflow: 0 - m_VerticalOverflow: 0 - m_LineSpacing: 1 - m_Text: Unity UI Panels ---- !u!222 &579295882 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 579295879} - m_CullTransparentMesh: 0 ---- !u!1 &998549135 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 998549136} - - component: {fileID: 998549138} - - component: {fileID: 998549137} - m_Layer: 5 - m_Name: Text - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &998549136 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 998549135} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 335487699} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &998549137 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 998549135} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_FontData: - m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} - m_FontSize: 14 - m_FontStyle: 0 - m_BestFit: 0 - m_MinSize: 10 - m_MaxSize: 40 - m_Alignment: 4 - m_AlignByGeometry: 0 - m_RichText: 1 - m_HorizontalOverflow: 0 - m_VerticalOverflow: 0 - m_LineSpacing: 1 - m_Text: Button ---- !u!222 &998549138 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 998549135} - m_CullTransparentMesh: 0 ---- !u!1 &1142533063 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1142533064} - - component: {fileID: 1142533066} - - component: {fileID: 1142533065} - - component: {fileID: 1142533067} - m_Layer: 5 - m_Name: Select On Start - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 0 ---- !u!224 &1142533064 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1142533063} - m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 304189374} - m_RootOrder: 2 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 1} - m_AnchorMax: {x: 0, y: 1} - m_AnchoredPosition: {x: 500, y: -305} - m_SizeDelta: {x: 300, y: 400} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &1142533065 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1142533063} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: e9bc91696c1584e11b23dca1a9e3cde3, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_Texture: {fileID: 0} - m_UVRect: - serializedVersion: 2 - x: 0 - y: 0 - width: 1 - height: 1 - devicePixelRatioOverride: 0 - antiAliasingOverride: 4 ---- !u!222 &1142533066 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1142533063} - m_CullTransparentMesh: 0 ---- !u!114 &1142533067 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1142533063} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: c42d7614d405d465aab861f4a0cb146e, type: 3} - m_Name: - m_EditorClassIdentifier: ---- !u!1 &1148735784 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1148735785} - - component: {fileID: 1148735787} - - component: {fileID: 1148735786} - m_Layer: 5 - m_Name: Placeholder - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &1148735785 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1148735784} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 554372218} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: -0.5} - m_SizeDelta: {x: -20, y: -13} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &1148735786 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1148735784} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 0.5} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_FontData: - m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} - m_FontSize: 14 - m_FontStyle: 2 - m_BestFit: 0 - m_MinSize: 10 - m_MaxSize: 40 - m_Alignment: 0 - m_AlignByGeometry: 0 - m_RichText: 1 - m_HorizontalOverflow: 0 - m_VerticalOverflow: 0 - m_LineSpacing: 1 - m_Text: Enter text... ---- !u!222 &1148735787 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1148735784} - m_CullTransparentMesh: 0 ---- !u!1 &1354314691 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1354314692} - - component: {fileID: 1354314694} - - component: {fileID: 1354314693} - m_Layer: 5 - m_Name: TextInput Override Ratio - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 0 ---- !u!224 &1354314692 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1354314691} - m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 304189374} - m_RootOrder: 1 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &1354314693 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1354314691} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: e9bc91696c1584e11b23dca1a9e3cde3, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_Texture: {fileID: 0} - m_UVRect: - serializedVersion: 2 - x: 0 - y: 0 - width: 1 - height: 1 - devicePixelRatioOverride: 4 - antiAliasingOverride: 4 ---- !u!222 &1354314694 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1354314691} - m_CullTransparentMesh: 0 ---- !u!1 &1387978526 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1387978527} - - component: {fileID: 1387978529} - - component: {fileID: 1387978528} - m_Layer: 5 - m_Name: TextInput - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &1387978527 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1387978526} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 304189374} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &1387978528 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1387978526} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 9c5c86936ca864ae684720ddcd50d759, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_Texture: {fileID: 0} - m_UVRect: - serializedVersion: 2 - x: 0 - y: 0 - width: 1 - height: 1 - devicePixelRatioOverride: 0 - antiAliasingOverride: 0 ---- !u!222 &1387978529 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1387978526} - m_CullTransparentMesh: 0 ---- !u!1 &1399904530 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1399904531} - - component: {fileID: 1399904533} - - component: {fileID: 1399904532} - m_Layer: 5 - m_Name: Panel - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 0 ---- !u!224 &1399904531 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1399904530} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: - - {fileID: 579295880} - - {fileID: 554372218} - - {fileID: 1556903570} - - {fileID: 335487699} - m_Father: {fileID: 304189374} - m_RootOrder: 3 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 1, y: 1} - m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: -100, y: -200} - m_SizeDelta: {x: 200, y: 400} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &1399904532 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1399904530} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 0.392} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} - m_Type: 1 - m_PreserveAspect: 0 - m_FillCenter: 1 - m_FillMethod: 4 - m_FillAmount: 1 - m_FillClockwise: 1 - m_FillOrigin: 0 - m_UseSpriteMesh: 0 ---- !u!222 &1399904533 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1399904530} - m_CullTransparentMesh: 0 ---- !u!1 &1492232671 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1492232675} - - component: {fileID: 1492232674} - - component: {fileID: 1492232673} - - component: {fileID: 1492232672} - m_Layer: 0 - m_Name: Cube - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 0 ---- !u!65 &1492232672 -BoxCollider: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1492232671} - m_Material: {fileID: 0} - m_IsTrigger: 0 - m_Enabled: 1 - serializedVersion: 2 - m_Size: {x: 1, y: 1, z: 1} - m_Center: {x: 0, y: 0, z: 0} ---- !u!23 &1492232673 -MeshRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1492232671} - m_Enabled: 1 - m_CastShadows: 1 - m_ReceiveShadows: 1 - m_DynamicOccludee: 1 - m_MotionVectors: 1 - m_LightProbeUsage: 1 - m_ReflectionProbeUsage: 1 - m_RenderingLayerMask: 1 - m_RendererPriority: 0 - m_Materials: - - {fileID: 2100000, guid: 7e4e4512ac8a44bf09367b1661efddc4, type: 2} - m_StaticBatchInfo: - firstSubMesh: 0 - subMeshCount: 0 - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_PreserveUVs: 0 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_StitchLightmapSeams: 0 - m_SelectedEditorRenderState: 3 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_SortingLayerID: 0 - m_SortingLayer: 0 - m_SortingOrder: 0 ---- !u!33 &1492232674 -MeshFilter: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1492232671} - m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} ---- !u!4 &1492232675 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1492232671} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: -1} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 1 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!1 &1556903569 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1556903570} - - component: {fileID: 1556903571} - m_Layer: 5 - m_Name: Slider - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &1556903570 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1556903569} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: - - {fileID: 43384372} - - {fileID: 431912887} - - {fileID: 71411788} - m_Father: {fileID: 1399904531} - m_RootOrder: 2 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0.5, y: 1} - m_AnchorMax: {x: 0.5, y: 1} - m_AnchoredPosition: {x: 0, y: -150} - m_SizeDelta: {x: 160, y: 20} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &1556903571 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1556903569} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: -113659843, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Navigation: - m_Mode: 3 - m_SelectOnUp: {fileID: 0} - m_SelectOnDown: {fileID: 0} - m_SelectOnLeft: {fileID: 0} - m_SelectOnRight: {fileID: 0} - m_Transition: 1 - m_Colors: - m_NormalColor: {r: 1, g: 1, b: 1, a: 1} - m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} - m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} - m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} - m_ColorMultiplier: 1 - m_FadeDuration: 0.1 - m_SpriteState: - m_HighlightedSprite: {fileID: 0} - m_PressedSprite: {fileID: 0} - m_DisabledSprite: {fileID: 0} - m_AnimationTriggers: - m_NormalTrigger: Normal - m_HighlightedTrigger: Highlighted - m_PressedTrigger: Pressed - m_DisabledTrigger: Disabled - m_Interactable: 1 - m_TargetGraphic: {fileID: 385671181} - m_FillRect: {fileID: 1777916082} - m_HandleRect: {fileID: 385671180} - m_Direction: 0 - m_MinValue: 0 - m_MaxValue: 1 - m_WholeNumbers: 0 - m_Value: 0 - m_OnValueChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.Slider+SliderEvent, UnityEngine.UI, Version=1.0.0.0, - Culture=neutral, PublicKeyToken=null ---- !u!1 &1621115924 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1621115925} - - component: {fileID: 1621115927} - - component: {fileID: 1621115926} - m_Layer: 5 - m_Name: Text - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &1621115925 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1621115924} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 554372218} - m_RootOrder: 1 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: -0.5} - m_SizeDelta: {x: -20, y: -13} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &1621115926 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1621115924} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_FontData: - m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} - m_FontSize: 14 - m_FontStyle: 0 - m_BestFit: 0 - m_MinSize: 10 - m_MaxSize: 40 - m_Alignment: 0 - m_AlignByGeometry: 0 - m_RichText: 0 - m_HorizontalOverflow: 1 - m_VerticalOverflow: 0 - m_LineSpacing: 1 - m_Text: ---- !u!222 &1621115927 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1621115924} - m_CullTransparentMesh: 0 ---- !u!1 &1777916081 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1777916082} - - component: {fileID: 1777916084} - - component: {fileID: 1777916083} - m_Layer: 5 - m_Name: Fill - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &1777916082 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1777916081} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 431912887} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 0, y: 1} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 10, y: 0} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &1777916083 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1777916081} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} - m_Type: 1 - m_PreserveAspect: 0 - m_FillCenter: 1 - m_FillMethod: 4 - m_FillAmount: 1 - m_FillClockwise: 1 - m_FillOrigin: 0 - m_UseSpriteMesh: 0 ---- !u!222 &1777916084 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1777916081} - m_CullTransparentMesh: 0 diff --git a/Samples/UIWidgetSample/TextInput.unity.meta b/Samples/UIWidgetSample/TextInput.unity.meta deleted file mode 100644 index d4700191..00000000 --- a/Samples/UIWidgetSample/TextInput.unity.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: a677aa8bdebec4af786ef0846602c037 -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetSample/TextInputSample.cs b/Samples/UIWidgetSample/TextInputSample.cs deleted file mode 100644 index 2c2dadd0..00000000 --- a/Samples/UIWidgetSample/TextInputSample.cs +++ /dev/null @@ -1,265 +0,0 @@ -using System.Collections.Generic; -using Unity.UIWidgets.foundation; -using Unity.UIWidgets.material; -using Unity.UIWidgets.painting; -using Unity.UIWidgets.rendering; -using Unity.UIWidgets.service; -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; -using UnityEngine; -using Color = Unity.UIWidgets.ui.Color; - -namespace UIWidgetsSample { - public class TextInputSample : UIWidgetsSamplePanel { - class _TextInputSample : StatefulWidget { - public readonly string title; - - public _TextInputSample(Key key = null, string title = null) : base(key) { - this.title = title; - } - - public override State createState() { - return new _TextInputSampleState(); - } - } - - protected override Widget createWidget() { - return new MaterialApp( - home: new EditableInputTypeWidget() - ); - } - - - class _TextInputSampleState : State<_TextInputSample> { - TextEditingController titleController = new TextEditingController(""); - TextEditingController descController = new TextEditingController(""); - FocusNode _titleFocusNode; - FocusNode _descFocusNode; - - public override void initState() { - base.initState(); - this._titleFocusNode = new FocusNode(); - this._descFocusNode = new FocusNode(); - } - - public override void dispose() { - this._titleFocusNode.dispose(); - this._descFocusNode.dispose(); - base.dispose(); - } - - Widget title() { - return new Container(child: new Text(this.widget.title ?? "", textAlign: TextAlign.center, - style: new TextStyle(fontSize: 24, fontWeight: FontWeight.w700)), - margin: EdgeInsets.only(bottom: 20)); - } - - Widget titleInput() { - return new Row( - children: new List( - ) { - new SizedBox(width: 100, child: new Text("Title")), - new Flexible(child: new Container( - decoration: new BoxDecoration(border: Border.all(new Color(0xFF000000), 1)), - padding: EdgeInsets.fromLTRB(8, 0, 8, 0), - child: new EditableText(maxLines: 1, - controller: this.titleController, - selectionControls: MaterialUtils.materialTextSelectionControls, - backgroundCursorColor: Colors.transparent, - autofocus: true, - focusNode: new FocusNode(), - style: new TextStyle( - fontSize: 18, - height: 1.5f, - color: new Color(0xFF1389FD) - ), - selectionColor: Color.fromARGB(255, 255, 0, 0), - cursorColor: Color.fromARGB(255, 0, 0, 0)) - )), - } - ); - } - - Widget descInput() { - return new Container( - margin: EdgeInsets.fromLTRB(0, 10, 0, 10), - child: new Row( - children: new List( - ) { - new SizedBox(width: 100, child: new Text("Description")), - new Flexible(child: new Container( - height: 200, - decoration: new BoxDecoration(border: Border.all(new Color(0xFF000000), 1)), - padding: EdgeInsets.fromLTRB(8, 0, 8, 0), - child: new EditableText(maxLines: 200, - controller: this.descController, - backgroundCursorColor: Colors.transparent, - selectionControls: MaterialUtils.materialTextSelectionControls, - focusNode: new FocusNode(), - style: new TextStyle( - fontSize: 18, - height: 1.5f, - color: new Color(0xFF1389FD) - ), - selectionColor: Color.fromARGB(255, 255, 0, 0), - cursorColor: Color.fromARGB(255, 0, 0, 0)) - )), - } - )); - } - - public override Widget build(BuildContext context) { - var container = new Container( - padding: EdgeInsets.all(10), - decoration: new BoxDecoration(color: new Color(0x7F000000), - border: Border.all(color: Color.fromARGB(255, 255, 0, 0), width: 5), - borderRadius: BorderRadius.all(2)), - child: new Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: new List { - this.title(), - this.titleInput(), - this.descInput(), - } - ) - ); - return container; - } - } - } - - public class EditableInputTypeWidget : StatefulWidget { - public EditableInputTypeWidget(Key key = null) : base(key) { - } - - public override State createState() { - return new _EditableInputTypeWidgetState(); - } - } - - class _EditableInputTypeWidgetState : State { - Widget rowWidgets(string title, Widget widget) { - return new Container( - height: 80, - child: new Row( - children: new List { - new Container(width: 100, child: new Text(title, style: new TextStyle(fontSize: 14, height: 2.0f, color: Colors.black, decoration: TextDecoration.none))), - new Flexible(child: new Container(child: widget, padding: EdgeInsets.all(4), decoration: - new BoxDecoration(border: Border.all(color: Color.black)))) - } - )); - } - - void textSubmitted(string text) { - Debug.Log($"text submitted {text}"); - } - - List buildInputs(bool unityKeyboard) { - List widgets = new List(); - var style = new TextStyle(); - var cursorColor = new Color(0xFF000000); - var selectionColor = new Color(0xFF6F6F6F); - - widgets.Add(this.rowWidgets("Default", new EditStateProvider(builder: ((buildContext, controller, node) => - new EditableText(controller, node, style, cursorColor, Colors.blue, - selectionColor: selectionColor, onSubmitted: this.textSubmitted - , unityTouchKeyboard: unityKeyboard, - selectionControls: MaterialUtils.materialTextSelectionControls, - cursorWidth: 5.0f, cursorRadius: Radius.circular(2.5f), cursorOpacityAnimates: true, paintCursorAboveText: true))))); - - widgets.Add(this.rowWidgets("Multiple Line", new EditStateProvider( - builder: ((buildContext, controller, node) => - new EditableText(controller, node, style, cursorColor, Colors.transparent, - selectionColor: selectionColor, maxLines: 4, - onSubmitted: this.textSubmitted, unityTouchKeyboard: unityKeyboard, - selectionControls: MaterialUtils.materialTextSelectionControls))))); - - widgets.Add(this.rowWidgets("ObscureText", new EditStateProvider( - builder: ((buildContext, controller, node) => - new EditableText(controller, node, style, cursorColor, Colors.transparent, - selectionColor: selectionColor, obscureText: true, - onSubmitted: this.textSubmitted, unityTouchKeyboard: unityKeyboard, - selectionControls: MaterialUtils.materialTextSelectionControls))))); - - widgets.Add(this.rowWidgets("Number", new EditStateProvider(builder: ((buildContext, controller, node) => - new EditableText(controller, node, style, cursorColor, Colors.transparent, - selectionColor: selectionColor, keyboardType: TextInputType.number, - onSubmitted: this.textSubmitted, unityTouchKeyboard: unityKeyboard, - selectionControls: MaterialUtils.materialTextSelectionControls))))); - - widgets.Add(this.rowWidgets("Phone", new EditStateProvider(builder: ((buildContext, controller, node) => - new EditableText(controller, node, style, cursorColor, Colors.transparent, - selectionColor: selectionColor, keyboardType: TextInputType.phone, - onSubmitted: this.textSubmitted, unityTouchKeyboard: unityKeyboard, - selectionControls: MaterialUtils.materialTextSelectionControls))))); - - widgets.Add(this.rowWidgets("Email", new EditStateProvider(builder: ((buildContext, controller, node) => - new EditableText(controller, node, style, cursorColor, Colors.transparent, - selectionColor: selectionColor, keyboardType: TextInputType.emailAddress, - onSubmitted: this.textSubmitted, unityTouchKeyboard: unityKeyboard, - selectionControls: MaterialUtils.materialTextSelectionControls))))); - - widgets.Add(this.rowWidgets("Url", new EditStateProvider(builder: ((buildContext, controller, node) => - new EditableText(controller, node, style, cursorColor, Colors.transparent, - selectionColor: selectionColor, keyboardType: TextInputType.url, - onSubmitted: this.textSubmitted, unityTouchKeyboard: unityKeyboard, - selectionControls: MaterialUtils.materialTextSelectionControls))))); - return widgets; - } - - public override Widget build(BuildContext context) { - List widgets = new List(); - - widgets.Add(new Text("UIWidgets Touch Keyboard", style: new TextStyle(fontSize: 20, height: 2.0f, color: Colors.black, decoration: TextDecoration.none), - textAlign: TextAlign.center)); - widgets.AddRange(this.buildInputs(false)); - - widgets.Add(new Text("Unity Touch Keyboard", style: new TextStyle(fontSize: 20, height: 2.0f, color: Colors.black, decoration: TextDecoration.none), - textAlign: TextAlign.center)); - widgets.AddRange(this.buildInputs(true)); - - return new Container( - padding: EdgeInsets.all(12), - child: new SingleChildScrollView(child: new Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: widgets))); - } - } - - public class EditStateProvider : StatefulWidget { - public delegate EditableText EditableBuilder(BuildContext context, - TextEditingController controller, FocusNode focusNode); - - public readonly EditableBuilder builder; - - public EditStateProvider(Key key = null, EditableBuilder builder = null) : base(key) { - D.assert(builder != null); - this.builder = builder; - } - - public override State createState() { - return new _EditStateProviderState(); - } - } - - class _EditStateProviderState : State { - TextEditingController _controller; - FocusNode _focusNode; - - public override void initState() { - base.initState(); - this._focusNode = new FocusNode(); - this._controller = new TextEditingController(""); - } - - - public override void dispose() { - this._focusNode.dispose(); - base.dispose(); - } - - public override Widget build(BuildContext context) { - return this.widget.builder(context, this._controller, this._focusNode); - } - } -} \ No newline at end of file diff --git a/Samples/UIWidgetSample/TextInputSample.cs.meta b/Samples/UIWidgetSample/TextInputSample.cs.meta deleted file mode 100644 index d3901dd9..00000000 --- a/Samples/UIWidgetSample/TextInputSample.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: e9bc91696c1584e11b23dca1a9e3cde3 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetSample/TextLayoutSample.unity b/Samples/UIWidgetSample/TextLayoutSample.unity deleted file mode 100644 index 6286c08a..00000000 --- a/Samples/UIWidgetSample/TextLayoutSample.unity +++ /dev/null @@ -1,296 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!29 &1 -OcclusionCullingSettings: - m_ObjectHideFlags: 0 - serializedVersion: 2 - m_OcclusionBakeSettings: - smallestOccluder: 5 - smallestHole: 0.25 - backfaceThreshold: 100 - m_SceneGUID: 00000000000000000000000000000000 - m_OcclusionCullingData: {fileID: 0} ---- !u!104 &2 -RenderSettings: - m_ObjectHideFlags: 0 - serializedVersion: 9 - m_Fog: 0 - m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} - m_FogMode: 3 - m_FogDensity: 0.01 - m_LinearFogStart: 0 - m_LinearFogEnd: 300 - m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} - m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} - m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} - m_AmbientIntensity: 1 - m_AmbientMode: 0 - m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} - m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} - m_HaloStrength: 0.5 - m_FlareStrength: 1 - m_FlareFadeSpeed: 3 - m_HaloTexture: {fileID: 0} - m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} - m_DefaultReflectionMode: 0 - m_DefaultReflectionResolution: 128 - m_ReflectionBounces: 1 - m_ReflectionIntensity: 1 - m_CustomReflection: {fileID: 0} - m_Sun: {fileID: 0} - m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1} - m_UseRadianceAmbientProbe: 0 ---- !u!157 &3 -LightmapSettings: - m_ObjectHideFlags: 0 - serializedVersion: 11 - m_GIWorkflowMode: 1 - m_GISettings: - serializedVersion: 2 - m_BounceScale: 1 - m_IndirectOutputScale: 1 - m_AlbedoBoost: 1 - m_EnvironmentLightingMode: 0 - m_EnableBakedLightmaps: 1 - m_EnableRealtimeLightmaps: 1 - m_LightmapEditorSettings: - serializedVersion: 12 - m_Resolution: 2 - m_BakeResolution: 40 - m_AtlasSize: 1024 - m_AO: 0 - m_AOMaxDistance: 1 - m_CompAOExponent: 1 - m_CompAOExponentDirect: 0 - m_ExtractAmbientOcclusion: 0 - m_Padding: 2 - m_LightmapParameters: {fileID: 0} - m_LightmapsBakeMode: 1 - m_TextureCompression: 1 - m_FinalGather: 0 - m_FinalGatherFiltering: 1 - m_FinalGatherRayCount: 256 - m_ReflectionCompression: 2 - m_MixedBakeMode: 2 - m_BakeBackend: 1 - m_PVRSampling: 1 - m_PVRDirectSampleCount: 32 - m_PVRSampleCount: 512 - m_PVRBounces: 2 - m_PVREnvironmentSampleCount: 256 - m_PVREnvironmentReferencePointCount: 2048 - m_PVRFilteringMode: 1 - m_PVRDenoiserTypeDirect: 1 - m_PVRDenoiserTypeIndirect: 1 - m_PVRDenoiserTypeAO: 1 - m_PVRFilterTypeDirect: 0 - m_PVRFilterTypeIndirect: 0 - m_PVRFilterTypeAO: 0 - m_PVREnvironmentMIS: 1 - m_PVRCulling: 1 - m_PVRFilteringGaussRadiusDirect: 1 - m_PVRFilteringGaussRadiusIndirect: 5 - m_PVRFilteringGaussRadiusAO: 2 - m_PVRFilteringAtrousPositionSigmaDirect: 0.5 - m_PVRFilteringAtrousPositionSigmaIndirect: 2 - m_PVRFilteringAtrousPositionSigmaAO: 1 - m_ShowResolutionOverlay: 1 - m_ExportTrainingData: 0 - m_LightingDataAsset: {fileID: 0} - m_UseShadowmask: 1 ---- !u!196 &4 -NavMeshSettings: - serializedVersion: 2 - m_ObjectHideFlags: 0 - m_BuildSettings: - serializedVersion: 2 - agentTypeID: 0 - agentRadius: 0.5 - agentHeight: 2 - agentSlope: 45 - agentClimb: 0.4 - ledgeDropHeight: 0 - maxJumpAcrossDistance: 0 - minRegionArea: 2 - manualCellSize: 0 - cellSize: 0.16666667 - manualTileSize: 0 - tileSize: 256 - accuratePlacement: 0 - debug: - m_Flags: 0 - m_NavMeshData: {fileID: 0} ---- !u!1 &1668830267 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1668830270} - - component: {fileID: 1668830269} - - component: {fileID: 1668830268} - m_Layer: 0 - m_Name: Main Camera - m_TagString: MainCamera - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!81 &1668830268 -AudioListener: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1668830267} - m_Enabled: 1 ---- !u!20 &1668830269 -Camera: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1668830267} - m_Enabled: 1 - serializedVersion: 2 - m_ClearFlags: 1 - m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} - m_projectionMatrixMode: 1 - m_GateFitMode: 2 - m_FOVAxisMode: 0 - m_SensorSize: {x: 36, y: 24} - m_LensShift: {x: 0, y: 0} - m_FocalLength: 50 - m_NormalizedViewPortRect: - serializedVersion: 2 - x: 0 - y: 0 - width: 1 - height: 1 - near clip plane: 0.3 - far clip plane: 1000 - field of view: 60 - orthographic: 0 - orthographic size: 5 - m_Depth: -1 - m_CullingMask: - serializedVersion: 2 - m_Bits: 4294967295 - m_RenderingPath: -1 - m_TargetTexture: {fileID: 0} - m_TargetDisplay: 0 - m_TargetEye: 3 - m_HDR: 1 - m_AllowMSAA: 1 - m_AllowDynamicResolution: 0 - m_ForceIntoRT: 0 - m_OcclusionCulling: 1 - m_StereoConvergence: 10 - m_StereoSeparation: 0.022 ---- !u!4 &1668830270 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1668830267} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 1, z: -10} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!1 &1774196668 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1774196670} - - component: {fileID: 1774196669} - m_Layer: 0 - m_Name: Directional Light - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!108 &1774196669 -Light: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1774196668} - m_Enabled: 1 - serializedVersion: 9 - m_Type: 1 - m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} - m_Intensity: 1 - m_Range: 10 - m_SpotAngle: 30 - m_InnerSpotAngle: 21.80208 - m_CookieSize: 10 - m_Shadows: - m_Type: 2 - m_Resolution: -1 - m_CustomResolution: -1 - m_Strength: 1 - m_Bias: 0.05 - m_NormalBias: 0.4 - m_NearPlane: 0.2 - m_CullingMatrixOverride: - e00: 1 - e01: 0 - e02: 0 - e03: 0 - e10: 0 - e11: 1 - e12: 0 - e13: 0 - e20: 0 - e21: 0 - e22: 1 - e23: 0 - e30: 0 - e31: 0 - e32: 0 - e33: 1 - m_UseCullingMatrixOverride: 0 - m_Cookie: {fileID: 0} - m_DrawHalo: 0 - m_Flare: {fileID: 0} - m_RenderMode: 0 - m_CullingMask: - serializedVersion: 2 - m_Bits: 4294967295 - m_RenderingLayerMask: 1 - m_Lightmapping: 4 - m_LightShadowCasterMode: 0 - m_AreaSize: {x: 1, y: 1} - m_BounceIntensity: 1 - m_ColorTemperature: 6570 - m_UseColorTemperature: 0 - m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0} - m_UseBoundingSphereOverride: 0 - m_ShadowRadius: 0 - m_ShadowAngle: 0 ---- !u!4 &1774196670 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1774196668} - m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} - m_LocalPosition: {x: 0, y: 3, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 1 - m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} diff --git a/Samples/UIWidgetSample/TextLayoutSample.unity.meta b/Samples/UIWidgetSample/TextLayoutSample.unity.meta deleted file mode 100644 index b27e0d8e..00000000 --- a/Samples/UIWidgetSample/TextLayoutSample.unity.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 12e27c4b597519147a207be6204dc1f5 -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetSample/ToDoAppSample.cs b/Samples/UIWidgetSample/ToDoAppSample.cs deleted file mode 100644 index 3c6f45be..00000000 --- a/Samples/UIWidgetSample/ToDoAppSample.cs +++ /dev/null @@ -1,216 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using Unity.UIWidgets.foundation; -using Unity.UIWidgets.gestures; -using Unity.UIWidgets.material; -using Unity.UIWidgets.painting; -using Unity.UIWidgets.rendering; -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; -using UnityEngine; -using Color = Unity.UIWidgets.ui.Color; -using TextStyle = Unity.UIWidgets.painting.TextStyle; -using Texture = Unity.UIWidgets.widgets.Texture; - -namespace UIWidgetsSample { - public class ToDoAppSample : UIWidgetsSamplePanel { - public class ToDoListApp : StatefulWidget { - public ToDoListApp(Key key = null) : base(key) { - } - - public override State createState() { - return new _ToDoListAppState(); - } - } - - protected override Widget createWidget() { - return new WidgetsApp( - home: new ToDoListApp(), - pageRouteBuilder: this.pageRouteBuilder); - } - - public class CustomButton : StatelessWidget { - public CustomButton( - Key key = null, - GestureTapCallback onPressed = null, - EdgeInsets padding = null, - Color backgroundColor = null, - Widget child = null - ) : base(key: key) { - this.onPressed = onPressed; - this.padding = padding ?? EdgeInsets.all(8.0f); - this.backgroundColor = backgroundColor ?? CLColors.transparent; - this.child = child; - } - - public readonly GestureTapCallback onPressed; - public readonly EdgeInsets padding; - public readonly Widget child; - public readonly Color backgroundColor; - - public override Widget build(BuildContext context) { - return new GestureDetector( - onTap: this.onPressed, - child: new Container( - padding: this.padding, - color: this.backgroundColor, - child: this.child - ) - ); - } - } - - class _ToDoListAppState : State { - public class ToDoItem { - public int id; - public string content; - } - - List items = new List(); - int nextId = 0; - TextEditingController controller = new TextEditingController(""); - FocusNode _focusNode; - - public override void initState() { - base.initState(); - this._focusNode = new FocusNode(); - } - - public override void dispose() { - this._focusNode.dispose(); - base.dispose(); - } - - Widget title() { - return new Text("ToDo App", textAlign: TextAlign.center, - style: new TextStyle(fontSize: 30, fontWeight: FontWeight.w700)); - } - - Widget textInput() { - return new Container( - child: new Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: new List( - ) { - new Container( - width: 300, - decoration: new BoxDecoration(border: Border.all(new Color(0xFF000000), 1)), - padding: EdgeInsets.fromLTRB(8, 0, 8, 0), - child: new EditableText(maxLines: 1, - controller: this.controller, - onSubmitted: (text) => { - this.controller.clear(); - this._addItem(text); - }, - selectionControls: MaterialUtils.materialTextSelectionControls, - autofocus: true, - focusNode: new FocusNode(), - style: new TextStyle( - fontSize: 18, - height: 1.5f, - color: new Color(0xFF1389FD) - ), - selectionColor: Color.fromARGB(255, 255, 0, 0), - cursorColor: Color.fromARGB(255, 0, 0, 0)) - ), - - new CustomButton(backgroundColor: Color.fromARGB(255, 0, 204, 204), - padding: EdgeInsets.all(10), - child: new Text("Add", style: new TextStyle( - fontSize: 20, color: Color.fromARGB(255, 255, 255, 255), fontWeight: FontWeight.w700 - )), onPressed: () => { this._addItem(); }) - } - ) - ); - } - - void _addItem(string text = null) { - this.setState(() => { - text = text ?? this.controller.text; - if (text != "") { - this.items.Add(new ToDoItem() - {id = this.nextId++, content = text}); - } - }); - } - - Widget contents() { - var children = this.items.Select((item) => { - return (Widget) new Text( - item.content, style: new TextStyle( - fontSize: 18, - height: 1.5f - ) - ); - }); - return new Flexible( - child: new ListView( - physics: new AlwaysScrollableScrollPhysics(), - children: children.ToList() - ) - ); - } - - Widget videoTexture() { - var texture = Resources.Load("VideoSampleRT"); - return new Center( - child: new Container( - width: 240, height: 135, - child: new Texture(texture: texture) - ) - ); - } - - public override Widget build(BuildContext context) { - var container = new Container( - padding: EdgeInsets.all(10), - decoration: new BoxDecoration(color: new Color(0x7F000000), - border: Border.all(color: Color.fromARGB(255, 255, 0, 0), width: 5), - borderRadius: BorderRadius.all(2)), - child: new Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: new List { - this.title(), - this.textInput(), - // textInput(), - this.contents(), - this.videoTexture(), - } - ) - ); - return container; - } - } - } - - public class CustomButton : StatelessWidget { - public CustomButton( - Key key = null, - GestureTapCallback onPressed = null, - EdgeInsets padding = null, - Color backgroundColor = null, - Widget child = null - ) : base(key: key) { - this.onPressed = onPressed; - this.padding = padding ?? EdgeInsets.all(8.0f); - this.backgroundColor = backgroundColor ?? CLColors.transparent; - this.child = child; - } - - public readonly GestureTapCallback onPressed; - public readonly EdgeInsets padding; - public readonly Widget child; - public readonly Color backgroundColor; - - public override Widget build(BuildContext context) { - return new GestureDetector( - onTap: this.onPressed, - child: new Container( - padding: this.padding, - color: this.backgroundColor, - child: this.child - ) - ); - } - } -} \ No newline at end of file diff --git a/Samples/UIWidgetSample/ToDoAppSample.cs.meta b/Samples/UIWidgetSample/ToDoAppSample.cs.meta deleted file mode 100644 index 830a97bb..00000000 --- a/Samples/UIWidgetSample/ToDoAppSample.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 45683c1d42a0d4392a02956cc7886f83 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetSample/UIWidgetSample.unity b/Samples/UIWidgetSample/UIWidgetSample.unity deleted file mode 100644 index c77ccdd7..00000000 --- a/Samples/UIWidgetSample/UIWidgetSample.unity +++ /dev/null @@ -1,2625 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!29 &1 -OcclusionCullingSettings: - m_ObjectHideFlags: 0 - serializedVersion: 2 - m_OcclusionBakeSettings: - smallestOccluder: 5 - smallestHole: 0.25 - backfaceThreshold: 100 - m_SceneGUID: 00000000000000000000000000000000 - m_OcclusionCullingData: {fileID: 0} ---- !u!104 &2 -RenderSettings: - m_ObjectHideFlags: 0 - serializedVersion: 9 - m_Fog: 0 - m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} - m_FogMode: 3 - m_FogDensity: 0.01 - m_LinearFogStart: 0 - m_LinearFogEnd: 300 - m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} - m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} - m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} - m_AmbientIntensity: 1 - m_AmbientMode: 0 - m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} - m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} - m_HaloStrength: 0.5 - m_FlareStrength: 1 - m_FlareFadeSpeed: 3 - m_HaloTexture: {fileID: 0} - m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} - m_DefaultReflectionMode: 0 - m_DefaultReflectionResolution: 128 - m_ReflectionBounces: 1 - m_ReflectionIntensity: 1 - m_CustomReflection: {fileID: 0} - m_Sun: {fileID: 0} - m_IndirectSpecularColor: {r: 0.37311953, g: 0.38074, b: 0.35872698, a: 1} - m_UseRadianceAmbientProbe: 0 ---- !u!157 &3 -LightmapSettings: - m_ObjectHideFlags: 0 - serializedVersion: 11 - m_GIWorkflowMode: 0 - m_GISettings: - serializedVersion: 2 - m_BounceScale: 1 - m_IndirectOutputScale: 1 - m_AlbedoBoost: 1 - m_EnvironmentLightingMode: 0 - m_EnableBakedLightmaps: 1 - m_EnableRealtimeLightmaps: 1 - m_LightmapEditorSettings: - serializedVersion: 10 - m_Resolution: 2 - m_BakeResolution: 40 - m_AtlasSize: 1024 - m_AO: 0 - m_AOMaxDistance: 1 - m_CompAOExponent: 1 - m_CompAOExponentDirect: 0 - m_Padding: 2 - m_LightmapParameters: {fileID: 0} - m_LightmapsBakeMode: 1 - m_TextureCompression: 1 - m_FinalGather: 0 - m_FinalGatherFiltering: 1 - m_FinalGatherRayCount: 256 - m_ReflectionCompression: 2 - m_MixedBakeMode: 2 - m_BakeBackend: 1 - m_PVRSampling: 1 - m_PVRDirectSampleCount: 32 - m_PVRSampleCount: 500 - m_PVRBounces: 2 - m_PVRFilterTypeDirect: 0 - m_PVRFilterTypeIndirect: 0 - m_PVRFilterTypeAO: 0 - m_PVRFilteringMode: 1 - m_PVRCulling: 1 - m_PVRFilteringGaussRadiusDirect: 1 - m_PVRFilteringGaussRadiusIndirect: 5 - m_PVRFilteringGaussRadiusAO: 2 - m_PVRFilteringAtrousPositionSigmaDirect: 0.5 - m_PVRFilteringAtrousPositionSigmaIndirect: 2 - m_PVRFilteringAtrousPositionSigmaAO: 1 - m_ShowResolutionOverlay: 1 - m_LightingDataAsset: {fileID: 0} - m_UseShadowmask: 1 ---- !u!196 &4 -NavMeshSettings: - serializedVersion: 2 - m_ObjectHideFlags: 0 - m_BuildSettings: - serializedVersion: 2 - agentTypeID: 0 - agentRadius: 0.5 - agentHeight: 2 - agentSlope: 45 - agentClimb: 0.4 - ledgeDropHeight: 0 - maxJumpAcrossDistance: 0 - minRegionArea: 2 - manualCellSize: 0 - cellSize: 0.16666667 - manualTileSize: 0 - tileSize: 256 - accuratePlacement: 0 - debug: - m_Flags: 0 - m_NavMeshData: {fileID: 0} ---- !u!1 &43384371 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 43384372} - - component: {fileID: 43384374} - - component: {fileID: 43384373} - m_Layer: 5 - m_Name: Background - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &43384372 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 43384371} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 1556903570} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0.25} - m_AnchorMax: {x: 1, y: 0.75} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &43384373 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 43384371} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} - m_Type: 1 - m_PreserveAspect: 0 - m_FillCenter: 1 - m_FillMethod: 4 - m_FillAmount: 1 - m_FillClockwise: 1 - m_FillOrigin: 0 - m_UseSpriteMesh: 0 ---- !u!222 &43384374 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 43384371} - m_CullTransparentMesh: 0 ---- !u!1 &71411787 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 71411788} - m_Layer: 5 - m_Name: Handle Slide Area - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &71411788 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 71411787} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: - - {fileID: 385671180} - m_Father: {fileID: 1556903570} - m_RootOrder: 2 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: -20, y: 0} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!1 &244594849 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 244594852} - - component: {fileID: 244594851} - - component: {fileID: 244594850} - - component: {fileID: 244594854} - m_Layer: 0 - m_Name: Main Camera - m_TagString: MainCamera - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!81 &244594850 -AudioListener: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 244594849} - m_Enabled: 1 ---- !u!20 &244594851 -Camera: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 244594849} - m_Enabled: 1 - serializedVersion: 2 - m_ClearFlags: 1 - m_BackGroundColor: {r: 1, g: 1, b: 1, a: 1} - m_projectionMatrixMode: 1 - m_SensorSize: {x: 36, y: 24} - m_LensShift: {x: 0, y: 0} - m_GateFitMode: 2 - m_FocalLength: 50 - m_NormalizedViewPortRect: - serializedVersion: 2 - x: 0 - y: 0 - width: 1 - height: 1 - near clip plane: 1 - far clip plane: 100 - field of view: 26.991467 - orthographic: 0 - orthographic size: 5 - m_Depth: -1 - m_CullingMask: - serializedVersion: 2 - m_Bits: 4294967295 - m_RenderingPath: -1 - m_TargetTexture: {fileID: 0} - m_TargetDisplay: 0 - m_TargetEye: 3 - m_HDR: 1 - m_AllowMSAA: 1 - m_AllowDynamicResolution: 0 - m_ForceIntoRT: 0 - m_OcclusionCulling: 1 - m_StereoConvergence: 10 - m_StereoSeparation: 0.022 ---- !u!4 &244594852 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 244594849} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: -15} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!114 &244594854 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 244594849} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: -768656878, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_EventMask: - serializedVersion: 2 - m_Bits: 4294967295 - m_MaxRayIntersections: 0 ---- !u!1 &304189370 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 304189374} - - component: {fileID: 304189373} - - component: {fileID: 304189372} - - component: {fileID: 304189371} - - component: {fileID: 304189376} - m_Layer: 5 - m_Name: Canvas - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!114 &304189371 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 304189370} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 1301386320, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_IgnoreReversedGraphics: 1 - m_BlockingObjects: 0 - m_BlockingMask: - serializedVersion: 2 - m_Bits: 4294967295 ---- !u!114 &304189372 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 304189370} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 1980459831, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_UiScaleMode: 0 - m_ReferencePixelsPerUnit: 100 - m_ScaleFactor: 1 - m_ReferenceResolution: {x: 800, y: 600} - m_ScreenMatchMode: 0 - m_MatchWidthOrHeight: 0 - m_PhysicalUnit: 3 - m_FallbackScreenDPI: 96 - m_DefaultSpriteDPI: 96 - m_DynamicPixelsPerUnit: 1 ---- !u!223 &304189373 -Canvas: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 304189370} - m_Enabled: 1 - serializedVersion: 3 - m_RenderMode: 0 - m_Camera: {fileID: 0} - m_PlaneDistance: 100 - m_PixelPerfect: 0 - m_ReceivesEvents: 1 - m_OverrideSorting: 0 - m_OverridePixelPerfect: 0 - m_SortingBucketNormalizedSize: 0 - m_AdditionalShaderChannelsFlag: 0 - m_SortingLayerID: 0 - m_SortingOrder: 0 - m_TargetDisplay: 0 ---- !u!224 &304189374 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 304189370} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 0, y: 0, z: 0} - m_Children: - - {fileID: 1387978527} - - {fileID: 1628409007} - - {fileID: 895510406} - - {fileID: 1399904531} - - {fileID: 432951246} - - {fileID: 552752111} - - {fileID: 1199742532} - m_Father: {fileID: 0} - m_RootOrder: 2 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 0, y: 0} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0, y: 0} ---- !u!222 &304189376 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 304189370} - m_CullTransparentMesh: 0 ---- !u!1 &335487698 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 335487699} - - component: {fileID: 335487702} - - component: {fileID: 335487701} - - component: {fileID: 335487700} - m_Layer: 5 - m_Name: Button - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &335487699 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 335487698} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: - - {fileID: 998549136} - m_Father: {fileID: 1399904531} - m_RootOrder: 3 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0.5, y: 0.5} - m_AnchorMax: {x: 0.5, y: 0.5} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 160, y: 30} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &335487700 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 335487698} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 1392445389, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Navigation: - m_Mode: 3 - m_SelectOnUp: {fileID: 0} - m_SelectOnDown: {fileID: 0} - m_SelectOnLeft: {fileID: 0} - m_SelectOnRight: {fileID: 0} - m_Transition: 1 - m_Colors: - m_NormalColor: {r: 1, g: 1, b: 1, a: 1} - m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} - m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} - m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} - m_ColorMultiplier: 1 - m_FadeDuration: 0.1 - m_SpriteState: - m_HighlightedSprite: {fileID: 0} - m_PressedSprite: {fileID: 0} - m_DisabledSprite: {fileID: 0} - m_AnimationTriggers: - m_NormalTrigger: Normal - m_HighlightedTrigger: Highlighted - m_PressedTrigger: Pressed - m_DisabledTrigger: Disabled - m_Interactable: 1 - m_TargetGraphic: {fileID: 335487701} - m_OnClick: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0, - Culture=neutral, PublicKeyToken=null ---- !u!114 &335487701 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 335487698} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} - m_Type: 1 - m_PreserveAspect: 0 - m_FillCenter: 1 - m_FillMethod: 4 - m_FillAmount: 1 - m_FillClockwise: 1 - m_FillOrigin: 0 - m_UseSpriteMesh: 0 ---- !u!222 &335487702 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 335487698} - m_CullTransparentMesh: 0 ---- !u!1 &385671179 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 385671180} - - component: {fileID: 385671182} - - component: {fileID: 385671181} - m_Layer: 5 - m_Name: Handle - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &385671180 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 385671179} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 71411788} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 0, y: 1} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 20, y: 0} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &385671181 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 385671179} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_Sprite: {fileID: 10913, guid: 0000000000000000f000000000000000, type: 0} - m_Type: 0 - m_PreserveAspect: 0 - m_FillCenter: 1 - m_FillMethod: 4 - m_FillAmount: 1 - m_FillClockwise: 1 - m_FillOrigin: 0 - m_UseSpriteMesh: 0 ---- !u!222 &385671182 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 385671179} - m_CullTransparentMesh: 0 ---- !u!1 &390948269 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 390948272} - - component: {fileID: 390948271} - - component: {fileID: 390948270} - m_Layer: 0 - m_Name: EventSystem - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!114 &390948270 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 390948269} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 1077351063, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_HorizontalAxis: Horizontal - m_VerticalAxis: Vertical - m_SubmitButton: Submit - m_CancelButton: Cancel - m_InputActionsPerSecond: 10 - m_RepeatDelay: 0.5 - m_ForceModuleActive: 0 ---- !u!114 &390948271 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 390948269} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: -619905303, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_FirstSelected: {fileID: 0} - m_sendNavigationEvents: 1 - m_DragThreshold: 10 ---- !u!4 &390948272 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 390948269} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 3 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!1 &431912886 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 431912887} - m_Layer: 5 - m_Name: Fill Area - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &431912887 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 431912886} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: - - {fileID: 1777916082} - m_Father: {fileID: 1556903570} - m_RootOrder: 1 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0.25} - m_AnchorMax: {x: 1, y: 0.75} - m_AnchoredPosition: {x: -5, y: 0} - m_SizeDelta: {x: -20, y: 0} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!1 &432951245 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 432951246} - - component: {fileID: 432951248} - - component: {fileID: 432951247} - m_Layer: 5 - m_Name: DragDrop - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 0 ---- !u!224 &432951246 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 432951245} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 304189374} - m_RootOrder: 4 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0.5, y: 0.5} - m_AnchorMax: {x: 0.5, y: 0.5} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 100, y: 100} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &432951247 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 432951245} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: d01ae8029ff2f4e54a5e9c1a9672e5dc, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_Texture: {fileID: 0} - m_UVRect: - serializedVersion: 2 - x: 0 - y: 0 - width: 1 - height: 1 - devicePixelRatioOverride: 0 ---- !u!222 &432951248 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 432951245} - m_CullTransparentMesh: 0 ---- !u!1 &484983222 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 484983223} - - component: {fileID: 484983225} - - component: {fileID: 484983224} - m_Layer: 5 - m_Name: Panel - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &484983223 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 484983222} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: - - {fileID: 1474326675} - - {fileID: 749367608} - - {fileID: 918558202} - m_Father: {fileID: 1628409007} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 1, y: 0} - m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: -75, y: -70} - m_SizeDelta: {x: 150, y: -140} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &484983224 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 484983222} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 0.392} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} - m_Type: 1 - m_PreserveAspect: 0 - m_FillCenter: 1 - m_FillMethod: 4 - m_FillAmount: 1 - m_FillClockwise: 1 - m_FillOrigin: 0 - m_UseSpriteMesh: 0 ---- !u!222 &484983225 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 484983222} - m_CullTransparentMesh: 0 ---- !u!1 &552752110 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 552752111} - - component: {fileID: 552752113} - - component: {fileID: 552752112} - m_Layer: 5 - m_Name: Material - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &552752111 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 552752110} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 304189374} - m_RootOrder: 5 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: -20, y: -20} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &552752112 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 552752110} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: d7c3be43dd8b94a349f26e3e7173c3f6, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_Texture: {fileID: 0} - m_UVRect: - serializedVersion: 2 - x: 0 - y: 0 - width: 1 - height: 1 - devicePixelRatioOverride: 0 ---- !u!222 &552752113 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 552752110} - m_CullTransparentMesh: 1 ---- !u!1 &554372217 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 554372218} - - component: {fileID: 554372221} - - component: {fileID: 554372220} - - component: {fileID: 554372219} - m_Layer: 5 - m_Name: InputField - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &554372218 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 554372217} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: - - {fileID: 1148735785} - - {fileID: 1621115925} - m_Father: {fileID: 1399904531} - m_RootOrder: 1 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0.5, y: 1} - m_AnchorMax: {x: 0.5, y: 1} - m_AnchoredPosition: {x: 0, y: -100} - m_SizeDelta: {x: 160, y: 30} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &554372219 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 554372217} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 575553740, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Navigation: - m_Mode: 3 - m_SelectOnUp: {fileID: 0} - m_SelectOnDown: {fileID: 0} - m_SelectOnLeft: {fileID: 0} - m_SelectOnRight: {fileID: 0} - m_Transition: 1 - m_Colors: - m_NormalColor: {r: 1, g: 1, b: 1, a: 1} - m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} - m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} - m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} - m_ColorMultiplier: 1 - m_FadeDuration: 0.1 - m_SpriteState: - m_HighlightedSprite: {fileID: 0} - m_PressedSprite: {fileID: 0} - m_DisabledSprite: {fileID: 0} - m_AnimationTriggers: - m_NormalTrigger: Normal - m_HighlightedTrigger: Highlighted - m_PressedTrigger: Pressed - m_DisabledTrigger: Disabled - m_Interactable: 1 - m_TargetGraphic: {fileID: 554372220} - m_TextComponent: {fileID: 1621115926} - m_Placeholder: {fileID: 1148735786} - m_ContentType: 0 - m_InputType: 0 - m_AsteriskChar: 42 - m_KeyboardType: 0 - m_LineType: 0 - m_HideMobileInput: 0 - m_CharacterValidation: 0 - m_CharacterLimit: 0 - m_OnEndEdit: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.InputField+SubmitEvent, UnityEngine.UI, Version=1.0.0.0, - Culture=neutral, PublicKeyToken=null - m_OnValueChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.InputField+OnChangeEvent, UnityEngine.UI, Version=1.0.0.0, - Culture=neutral, PublicKeyToken=null - m_CaretColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} - m_CustomCaretColor: 0 - m_SelectionColor: {r: 0.65882355, g: 0.80784315, b: 1, a: 0.7529412} - m_Text: - m_CaretBlinkRate: 0.85 - m_CaretWidth: 1 - m_ReadOnly: 0 ---- !u!114 &554372220 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 554372217} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_Sprite: {fileID: 10911, guid: 0000000000000000f000000000000000, type: 0} - m_Type: 1 - m_PreserveAspect: 0 - m_FillCenter: 1 - m_FillMethod: 4 - m_FillAmount: 1 - m_FillClockwise: 1 - m_FillOrigin: 0 - m_UseSpriteMesh: 0 ---- !u!222 &554372221 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 554372217} - m_CullTransparentMesh: 0 ---- !u!1 &579295879 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 579295880} - - component: {fileID: 579295882} - - component: {fileID: 579295881} - m_Layer: 5 - m_Name: Text - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &579295880 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 579295879} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 1399904531} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0.5, y: 1} - m_AnchorMax: {x: 0.5, y: 1} - m_AnchoredPosition: {x: 0, y: -30} - m_SizeDelta: {x: 160, y: 30} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &579295881 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 579295879} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_FontData: - m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} - m_FontSize: 14 - m_FontStyle: 0 - m_BestFit: 0 - m_MinSize: 10 - m_MaxSize: 40 - m_Alignment: 0 - m_AlignByGeometry: 0 - m_RichText: 1 - m_HorizontalOverflow: 0 - m_VerticalOverflow: 0 - m_LineSpacing: 1 - m_Text: Unity UI Panels ---- !u!222 &579295882 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 579295879} - m_CullTransparentMesh: 0 ---- !u!1 &749367607 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 749367608} - - component: {fileID: 749367611} - - component: {fileID: 749367610} - - component: {fileID: 749367609} - m_Layer: 5 - m_Name: InputField - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &749367608 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 749367607} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: - - {fileID: 1333497002} - - {fileID: 1882375726} - m_Father: {fileID: 484983223} - m_RootOrder: 1 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0.5, y: 1} - m_AnchorMax: {x: 0.5, y: 1} - m_AnchoredPosition: {x: 0, y: -60} - m_SizeDelta: {x: 130, y: 30} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &749367609 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 749367607} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 575553740, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Navigation: - m_Mode: 3 - m_SelectOnUp: {fileID: 0} - m_SelectOnDown: {fileID: 0} - m_SelectOnLeft: {fileID: 0} - m_SelectOnRight: {fileID: 0} - m_Transition: 1 - m_Colors: - m_NormalColor: {r: 1, g: 1, b: 1, a: 1} - m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} - m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} - m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} - m_ColorMultiplier: 1 - m_FadeDuration: 0.1 - m_SpriteState: - m_HighlightedSprite: {fileID: 0} - m_PressedSprite: {fileID: 0} - m_DisabledSprite: {fileID: 0} - m_AnimationTriggers: - m_NormalTrigger: Normal - m_HighlightedTrigger: Highlighted - m_PressedTrigger: Pressed - m_DisabledTrigger: Disabled - m_Interactable: 1 - m_TargetGraphic: {fileID: 749367610} - m_TextComponent: {fileID: 1882375727} - m_Placeholder: {fileID: 1333497003} - m_ContentType: 0 - m_InputType: 0 - m_AsteriskChar: 42 - m_KeyboardType: 0 - m_LineType: 0 - m_HideMobileInput: 0 - m_CharacterValidation: 0 - m_CharacterLimit: 0 - m_OnEndEdit: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.InputField+SubmitEvent, UnityEngine.UI, Version=1.0.0.0, - Culture=neutral, PublicKeyToken=null - m_OnValueChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.InputField+OnChangeEvent, UnityEngine.UI, Version=1.0.0.0, - Culture=neutral, PublicKeyToken=null - m_CaretColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} - m_CustomCaretColor: 0 - m_SelectionColor: {r: 0.65882355, g: 0.80784315, b: 1, a: 0.7529412} - m_Text: - m_CaretBlinkRate: 0.85 - m_CaretWidth: 1 - m_ReadOnly: 0 ---- !u!114 &749367610 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 749367607} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_Sprite: {fileID: 10911, guid: 0000000000000000f000000000000000, type: 0} - m_Type: 1 - m_PreserveAspect: 0 - m_FillCenter: 1 - m_FillMethod: 4 - m_FillAmount: 1 - m_FillClockwise: 1 - m_FillOrigin: 0 - m_UseSpriteMesh: 0 ---- !u!222 &749367611 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 749367607} - m_CullTransparentMesh: 0 ---- !u!1 &895510405 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 895510406} - - component: {fileID: 895510408} - - component: {fileID: 895510407} - m_Layer: 5 - m_Name: ASCanvas - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 0 ---- !u!224 &895510406 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 895510405} - m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 304189374} - m_RootOrder: 2 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: -20, y: -20} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &895510407 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 895510405} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 71d034a309904459c9016f0f17734267, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_Texture: {fileID: 0} - m_UVRect: - serializedVersion: 2 - x: 0 - y: 0 - width: 1 - height: 1 - devicePixelRatioOverride: 0 ---- !u!222 &895510408 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 895510405} - m_CullTransparentMesh: 0 ---- !u!1 &918558201 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 918558202} - - component: {fileID: 918558205} - - component: {fileID: 918558204} - - component: {fileID: 918558203} - m_Layer: 5 - m_Name: Button - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &918558202 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 918558201} - m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: - - {fileID: 1762141486} - m_Father: {fileID: 484983223} - m_RootOrder: 2 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0.5, y: 1} - m_AnchorMax: {x: 0.5, y: 1} - m_AnchoredPosition: {x: 0, y: -100} - m_SizeDelta: {x: 130, y: 30} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &918558203 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 918558201} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 1392445389, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Navigation: - m_Mode: 3 - m_SelectOnUp: {fileID: 0} - m_SelectOnDown: {fileID: 0} - m_SelectOnLeft: {fileID: 0} - m_SelectOnRight: {fileID: 0} - m_Transition: 1 - m_Colors: - m_NormalColor: {r: 1, g: 1, b: 1, a: 1} - m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} - m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} - m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} - m_ColorMultiplier: 1 - m_FadeDuration: 0.1 - m_SpriteState: - m_HighlightedSprite: {fileID: 0} - m_PressedSprite: {fileID: 0} - m_DisabledSprite: {fileID: 0} - m_AnimationTriggers: - m_NormalTrigger: Normal - m_HighlightedTrigger: Highlighted - m_PressedTrigger: Pressed - m_DisabledTrigger: Disabled - m_Interactable: 1 - m_TargetGraphic: {fileID: 918558204} - m_OnClick: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0, - Culture=neutral, PublicKeyToken=null ---- !u!114 &918558204 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 918558201} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} - m_Type: 1 - m_PreserveAspect: 0 - m_FillCenter: 1 - m_FillMethod: 4 - m_FillAmount: 1 - m_FillClockwise: 1 - m_FillOrigin: 0 - m_UseSpriteMesh: 0 ---- !u!222 &918558205 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 918558201} - m_CullTransparentMesh: 0 ---- !u!1 &998549135 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 998549136} - - component: {fileID: 998549138} - - component: {fileID: 998549137} - m_Layer: 5 - m_Name: Text - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &998549136 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 998549135} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 335487699} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &998549137 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 998549135} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_FontData: - m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} - m_FontSize: 14 - m_FontStyle: 0 - m_BestFit: 0 - m_MinSize: 10 - m_MaxSize: 40 - m_Alignment: 4 - m_AlignByGeometry: 0 - m_RichText: 1 - m_HorizontalOverflow: 0 - m_VerticalOverflow: 0 - m_LineSpacing: 1 - m_Text: Button ---- !u!222 &998549138 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 998549135} - m_CullTransparentMesh: 0 ---- !u!1 &1148735784 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1148735785} - - component: {fileID: 1148735787} - - component: {fileID: 1148735786} - m_Layer: 5 - m_Name: Placeholder - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &1148735785 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1148735784} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 554372218} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: -0.5} - m_SizeDelta: {x: -20, y: -13} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &1148735786 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1148735784} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 0.5} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_FontData: - m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} - m_FontSize: 14 - m_FontStyle: 2 - m_BestFit: 0 - m_MinSize: 10 - m_MaxSize: 40 - m_Alignment: 0 - m_AlignByGeometry: 0 - m_RichText: 1 - m_HorizontalOverflow: 0 - m_VerticalOverflow: 0 - m_LineSpacing: 1 - m_Text: Enter text... ---- !u!222 &1148735787 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1148735784} - m_CullTransparentMesh: 0 ---- !u!1 &1199742531 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1199742532} - - component: {fileID: 1199742534} - - component: {fileID: 1199742533} - m_Layer: 5 - m_Name: ExpansionPanel - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 0 ---- !u!224 &1199742532 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1199742531} - m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 304189374} - m_RootOrder: 6 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0.5, y: 0} - m_AnchorMax: {x: 0.5, y: 0} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 300, y: 500} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &1199742533 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1199742531} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 7b7c8f92f79054eb6ae6e6749ebec2a1, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_Texture: {fileID: 0} - m_UVRect: - serializedVersion: 2 - x: 0 - y: 0 - width: 1 - height: 1 - devicePixelRatioOverride: 0 ---- !u!222 &1199742534 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1199742531} - m_CullTransparentMesh: 0 ---- !u!1 &1333497001 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1333497002} - - component: {fileID: 1333497004} - - component: {fileID: 1333497003} - m_Layer: 5 - m_Name: Placeholder - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &1333497002 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1333497001} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 749367608} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: -0.5} - m_SizeDelta: {x: -20, y: -13} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &1333497003 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1333497001} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 0.5} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_FontData: - m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} - m_FontSize: 14 - m_FontStyle: 2 - m_BestFit: 0 - m_MinSize: 10 - m_MaxSize: 40 - m_Alignment: 0 - m_AlignByGeometry: 0 - m_RichText: 1 - m_HorizontalOverflow: 0 - m_VerticalOverflow: 0 - m_LineSpacing: 1 - m_Text: Enter text... ---- !u!222 &1333497004 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1333497001} - m_CullTransparentMesh: 0 ---- !u!1 &1387978526 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1387978527} - - component: {fileID: 1387978529} - - component: {fileID: 1387978528} - - component: {fileID: 1387978530} - m_Layer: 5 - m_Name: ToAppPanel - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 0 ---- !u!224 &1387978527 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1387978526} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 304189374} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: -20, y: -20} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &1387978528 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1387978526} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 45683c1d42a0d4392a02956cc7886f83, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_Texture: {fileID: 0} - m_UVRect: - serializedVersion: 2 - x: 0 - y: 0 - width: 1 - height: 1 - devicePixelRatioOverride: 0 ---- !u!222 &1387978529 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1387978526} - m_CullTransparentMesh: 0 ---- !u!114 &1387978530 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1387978526} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: c1b5fe397122c4c5988b2bddfe92bd95, type: 3} - m_Name: - m_EditorClassIdentifier: - videoClip: {fileID: 32900000, guid: 9906c152cf75248e98d1edd60759f014, type: 3} - renderTexture: {fileID: 8400000, guid: 53bf3f9b1464948cbb3f58add96afa32, type: 2} ---- !u!1 &1399904530 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1399904531} - - component: {fileID: 1399904533} - - component: {fileID: 1399904532} - m_Layer: 5 - m_Name: Panel - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 0 ---- !u!224 &1399904531 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1399904530} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: - - {fileID: 579295880} - - {fileID: 554372218} - - {fileID: 1556903570} - - {fileID: 335487699} - m_Father: {fileID: 304189374} - m_RootOrder: 3 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 1, y: 1} - m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: -100, y: -200} - m_SizeDelta: {x: 200, y: 400} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &1399904532 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1399904530} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 0.392} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} - m_Type: 1 - m_PreserveAspect: 0 - m_FillCenter: 1 - m_FillMethod: 4 - m_FillAmount: 1 - m_FillClockwise: 1 - m_FillOrigin: 0 - m_UseSpriteMesh: 0 ---- !u!222 &1399904533 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1399904530} - m_CullTransparentMesh: 0 ---- !u!1 &1474326674 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1474326675} - - component: {fileID: 1474326677} - - component: {fileID: 1474326676} - m_Layer: 5 - m_Name: Text - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &1474326675 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1474326674} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 484983223} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0.5, y: 1} - m_AnchorMax: {x: 0.5, y: 1} - m_AnchoredPosition: {x: 0, y: -30} - m_SizeDelta: {x: 130, y: 30} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &1474326676 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1474326674} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_FontData: - m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} - m_FontSize: 14 - m_FontStyle: 0 - m_BestFit: 0 - m_MinSize: 10 - m_MaxSize: 40 - m_Alignment: 0 - m_AlignByGeometry: 0 - m_RichText: 1 - m_HorizontalOverflow: 0 - m_VerticalOverflow: 0 - m_LineSpacing: 1 - m_Text: UGUI Nested ---- !u!222 &1474326677 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1474326674} - m_CullTransparentMesh: 0 ---- !u!1 &1492232671 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1492232675} - - component: {fileID: 1492232674} - - component: {fileID: 1492232673} - - component: {fileID: 1492232672} - m_Layer: 0 - m_Name: Cube - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 0 ---- !u!65 &1492232672 -BoxCollider: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1492232671} - m_Material: {fileID: 0} - m_IsTrigger: 0 - m_Enabled: 1 - serializedVersion: 2 - m_Size: {x: 1, y: 1, z: 1} - m_Center: {x: 0, y: 0, z: 0} ---- !u!23 &1492232673 -MeshRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1492232671} - m_Enabled: 1 - m_CastShadows: 1 - m_ReceiveShadows: 1 - m_DynamicOccludee: 1 - m_MotionVectors: 1 - m_LightProbeUsage: 1 - m_ReflectionProbeUsage: 1 - m_RenderingLayerMask: 1 - m_RendererPriority: 0 - m_Materials: - - {fileID: 2100000, guid: 7e4e4512ac8a44bf09367b1661efddc4, type: 2} - m_StaticBatchInfo: - firstSubMesh: 0 - subMeshCount: 0 - m_StaticBatchRoot: {fileID: 0} - m_ProbeAnchor: {fileID: 0} - m_LightProbeVolumeOverride: {fileID: 0} - m_ScaleInLightmap: 1 - m_PreserveUVs: 0 - m_IgnoreNormalsForChartDetection: 0 - m_ImportantGI: 0 - m_StitchLightmapSeams: 0 - m_SelectedEditorRenderState: 3 - m_MinimumChartSize: 4 - m_AutoUVMaxDistance: 0.5 - m_AutoUVMaxAngle: 89 - m_LightmapParameters: {fileID: 0} - m_SortingLayerID: 0 - m_SortingLayer: 0 - m_SortingOrder: 0 ---- !u!33 &1492232674 -MeshFilter: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1492232671} - m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} ---- !u!4 &1492232675 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1492232671} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: -1} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 1 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!1 &1556903569 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1556903570} - - component: {fileID: 1556903571} - m_Layer: 5 - m_Name: Slider - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &1556903570 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1556903569} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: - - {fileID: 43384372} - - {fileID: 431912887} - - {fileID: 71411788} - m_Father: {fileID: 1399904531} - m_RootOrder: 2 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0.5, y: 1} - m_AnchorMax: {x: 0.5, y: 1} - m_AnchoredPosition: {x: 0, y: -150} - m_SizeDelta: {x: 160, y: 20} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &1556903571 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1556903569} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: -113659843, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Navigation: - m_Mode: 3 - m_SelectOnUp: {fileID: 0} - m_SelectOnDown: {fileID: 0} - m_SelectOnLeft: {fileID: 0} - m_SelectOnRight: {fileID: 0} - m_Transition: 1 - m_Colors: - m_NormalColor: {r: 1, g: 1, b: 1, a: 1} - m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} - m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} - m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} - m_ColorMultiplier: 1 - m_FadeDuration: 0.1 - m_SpriteState: - m_HighlightedSprite: {fileID: 0} - m_PressedSprite: {fileID: 0} - m_DisabledSprite: {fileID: 0} - m_AnimationTriggers: - m_NormalTrigger: Normal - m_HighlightedTrigger: Highlighted - m_PressedTrigger: Pressed - m_DisabledTrigger: Disabled - m_Interactable: 1 - m_TargetGraphic: {fileID: 385671181} - m_FillRect: {fileID: 1777916082} - m_HandleRect: {fileID: 385671180} - m_Direction: 0 - m_MinValue: 0 - m_MaxValue: 1 - m_WholeNumbers: 0 - m_Value: 0 - m_OnValueChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.Slider+SliderEvent, UnityEngine.UI, Version=1.0.0.0, - Culture=neutral, PublicKeyToken=null ---- !u!1 &1621115924 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1621115925} - - component: {fileID: 1621115927} - - component: {fileID: 1621115926} - m_Layer: 5 - m_Name: Text - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &1621115925 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1621115924} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 554372218} - m_RootOrder: 1 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: -0.5} - m_SizeDelta: {x: -20, y: -13} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &1621115926 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1621115924} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_FontData: - m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} - m_FontSize: 14 - m_FontStyle: 0 - m_BestFit: 0 - m_MinSize: 10 - m_MaxSize: 40 - m_Alignment: 0 - m_AlignByGeometry: 0 - m_RichText: 0 - m_HorizontalOverflow: 1 - m_VerticalOverflow: 0 - m_LineSpacing: 1 - m_Text: ---- !u!222 &1621115927 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1621115924} - m_CullTransparentMesh: 0 ---- !u!1 &1628409006 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1628409007} - - component: {fileID: 1628409009} - - component: {fileID: 1628409008} - m_Layer: 5 - m_Name: ToAppPanelWithUGUI - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 0 ---- !u!224 &1628409007 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1628409006} - m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: - - {fileID: 484983223} - m_Father: {fileID: 304189374} - m_RootOrder: 1 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0.5, y: 0.5} - m_AnchorMax: {x: 0.5, y: 0.5} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 600, y: 300} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &1628409008 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1628409006} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 45683c1d42a0d4392a02956cc7886f83, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_Texture: {fileID: 0} - m_UVRect: - serializedVersion: 2 - x: 0 - y: 0 - width: 1 - height: 1 - devicePixelRatioOverride: 0 ---- !u!222 &1628409009 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1628409006} - m_CullTransparentMesh: 0 ---- !u!1 &1762141485 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1762141486} - - component: {fileID: 1762141488} - - component: {fileID: 1762141487} - m_Layer: 5 - m_Name: Text - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &1762141486 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1762141485} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 918558202} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &1762141487 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1762141485} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_FontData: - m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} - m_FontSize: 14 - m_FontStyle: 0 - m_BestFit: 0 - m_MinSize: 10 - m_MaxSize: 40 - m_Alignment: 4 - m_AlignByGeometry: 0 - m_RichText: 1 - m_HorizontalOverflow: 0 - m_VerticalOverflow: 0 - m_LineSpacing: 1 - m_Text: Button ---- !u!222 &1762141488 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1762141485} - m_CullTransparentMesh: 0 ---- !u!1 &1777916081 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1777916082} - - component: {fileID: 1777916084} - - component: {fileID: 1777916083} - m_Layer: 5 - m_Name: Fill - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &1777916082 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1777916081} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 431912887} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 0, y: 1} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 10, y: 0} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &1777916083 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1777916081} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} - m_Type: 1 - m_PreserveAspect: 0 - m_FillCenter: 1 - m_FillMethod: 4 - m_FillAmount: 1 - m_FillClockwise: 1 - m_FillOrigin: 0 - m_UseSpriteMesh: 0 ---- !u!222 &1777916084 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1777916081} - m_CullTransparentMesh: 0 ---- !u!1 &1882375725 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1882375726} - - component: {fileID: 1882375728} - - component: {fileID: 1882375727} - m_Layer: 5 - m_Name: Text - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &1882375726 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1882375725} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 749367608} - m_RootOrder: 1 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: -0.5} - m_SizeDelta: {x: -20, y: -13} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &1882375727 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1882375725} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_FontData: - m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} - m_FontSize: 14 - m_FontStyle: 0 - m_BestFit: 0 - m_MinSize: 10 - m_MaxSize: 40 - m_Alignment: 0 - m_AlignByGeometry: 0 - m_RichText: 0 - m_HorizontalOverflow: 1 - m_VerticalOverflow: 0 - m_LineSpacing: 1 - m_Text: ---- !u!222 &1882375728 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1882375725} - m_CullTransparentMesh: 0 diff --git a/Samples/UIWidgetSample/UIWidgetSample.unity.meta b/Samples/UIWidgetSample/UIWidgetSample.unity.meta deleted file mode 100644 index f788d270..00000000 --- a/Samples/UIWidgetSample/UIWidgetSample.unity.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 4e3b67b8f19ff4635b924fb6e01a071d -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetSample/UIWidgetsSamplePanel.cs b/Samples/UIWidgetSample/UIWidgetsSamplePanel.cs deleted file mode 100644 index de9f1422..00000000 --- a/Samples/UIWidgetSample/UIWidgetsSamplePanel.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Unity.UIWidgets.animation; -using Unity.UIWidgets.engine; -using Unity.UIWidgets.widgets; - -namespace UIWidgetsSample { - public class UIWidgetsSamplePanel: UIWidgetsPanel { - - protected virtual PageRouteFactory pageRouteBuilder { - get { - return (RouteSettings settings, WidgetBuilder builder) => - new PageRouteBuilder( - settings: settings, - pageBuilder: (BuildContext context, Animation animation, - Animation secondaryAnimation) => builder(context) - ); - } - } - - } -} \ No newline at end of file diff --git a/Samples/UIWidgetSample/UIWidgetsSamplePanel.cs.meta b/Samples/UIWidgetSample/UIWidgetsSamplePanel.cs.meta deleted file mode 100644 index 2e1a9c12..00000000 --- a/Samples/UIWidgetSample/UIWidgetsSamplePanel.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 4a21c5e1a50e24057a4ecf249fa86c1f -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetSample/Utils.cs b/Samples/UIWidgetSample/Utils.cs deleted file mode 100644 index 970ba791..00000000 --- a/Samples/UIWidgetSample/Utils.cs +++ /dev/null @@ -1,45 +0,0 @@ -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; - -namespace UIWidgetsSample { - - public static class Icons { - public static readonly IconData notifications = new IconData(0xe7f4, fontFamily: "Material Icons"); - public static readonly IconData account_circle = new IconData(0xe853, fontFamily: "Material Icons"); - public static readonly IconData search = new IconData(0xe8b6, fontFamily: "Material Icons"); - public static readonly IconData keyboard_arrow_down = new IconData(0xe313, fontFamily: "Material Icons"); - } - - public static class CLColors { - public static readonly Color primary = new Color(0xFFE91E63); - public static readonly Color secondary1 = new Color(0xFF00BCD4); - public static readonly Color secondary2 = new Color(0xFFF0513C); - public static readonly Color background1 = new Color(0xFF292929); - public static readonly Color background2 = new Color(0xFF383838); - public static readonly Color background3 = new Color(0xFFF5F5F5); - public static readonly Color background4 = new Color(0xFF00BCD4); - public static readonly Color icon1 = new Color(0xFFFFFFFF); - public static readonly Color icon2 = new Color(0xFFA4A4A4); - public static readonly Color text1 = new Color(0xFFFFFFFF); - public static readonly Color text2 = new Color(0xFFD8D8D8); - public static readonly Color text3 = new Color(0xFF959595); - public static readonly Color text4 = new Color(0xFF002835); - public static readonly Color text5 = new Color(0xFF9E9E9E); - public static readonly Color text6 = new Color(0xFF002835); - public static readonly Color text7 = new Color(0xFF5A5A5B); - public static readonly Color text8 = new Color(0xFF239988); - public static readonly Color text9 = new Color(0xFFB3B5B6); - public static readonly Color text10 = new Color(0xFF00BCD4); - public static readonly Color dividingLine1 = new Color(0xFF666666); - public static readonly Color dividingLine2 = new Color(0xFF404040); - - public static readonly Color transparent = new Color(0x00000000); - public static readonly Color white = new Color(0xFFFFFFFF); - public static readonly Color black = new Color(0xFF000000); - public static readonly Color red = new Color(0xFFFF0000); - public static readonly Color green = new Color(0xFF00FF00); - public static readonly Color blue = new Color(0xFF0000FF); - - public static readonly Color header = new Color(0xFF060B0C); - } -} \ No newline at end of file diff --git a/Samples/UIWidgetSample/Utils.cs.meta b/Samples/UIWidgetSample/Utils.cs.meta deleted file mode 100644 index 7b832306..00000000 --- a/Samples/UIWidgetSample/Utils.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 3781c9e4efebd4c928ef175761d31b58 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetSample/VideoSampleComponent.cs b/Samples/UIWidgetSample/VideoSampleComponent.cs deleted file mode 100644 index cf6d4b33..00000000 --- a/Samples/UIWidgetSample/VideoSampleComponent.cs +++ /dev/null @@ -1,20 +0,0 @@ -using UnityEngine; -using UnityEngine.Video; -using Texture = Unity.UIWidgets.widgets.Texture; - -namespace UIWidgetsSample { - public class VideoSampleComponent : MonoBehaviour { - public VideoClip videoClip; - public RenderTexture renderTexture; - - void Start() { - var videoPlayer = this.gameObject.AddComponent(); - videoPlayer.clip = this.videoClip; - videoPlayer.targetTexture = this.renderTexture; - videoPlayer.isLooping = true; - videoPlayer.sendFrameReadyEvents = true; - videoPlayer.frameReady += (_, __) => Texture.textureFrameAvailable(); - videoPlayer.Play(); - } - } -} diff --git a/Samples/UIWidgetSample/VideoSampleComponent.cs.meta b/Samples/UIWidgetSample/VideoSampleComponent.cs.meta deleted file mode 100644 index b52e8cd2..00000000 --- a/Samples/UIWidgetSample/VideoSampleComponent.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c1b5fe397122c4c5988b2bddfe92bd95 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetSample/txt.meta b/Samples/UIWidgetSample/txt.meta deleted file mode 100644 index c658e7d2..00000000 --- a/Samples/UIWidgetSample/txt.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 57dc3a2ca4c5643b482cd6c4e9e545d6 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetSample/txt/FontWeightStyle.cs b/Samples/UIWidgetSample/txt/FontWeightStyle.cs deleted file mode 100644 index 87533ebf..00000000 --- a/Samples/UIWidgetSample/txt/FontWeightStyle.cs +++ /dev/null @@ -1,86 +0,0 @@ -using System.Collections.Generic; -using Unity.UIWidgets.material; -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; -using UnityEngine; -using FontStyle = Unity.UIWidgets.ui.FontStyle; -using TextStyle = Unity.UIWidgets.painting.TextStyle; - -namespace UIWidgetsSample { - public class FontWeightStyle : UIWidgetsSamplePanel { - protected override void OnEnable() { - // To run this sample, you need to download Roboto fonts and place them under Resources/Fonts folder - // Roboto fonts could be downloaded from google website - // https://fonts.google.com/specimen/Roboto?selection.family=Roboto - FontManager.instance.addFont(Resources.Load(path: "MaterialIcons-Regular"), "Material Icons"); - FontManager.instance.addFont(Resources.Load(path: "Fonts/Roboto-Black"), "Roboto", - FontWeight.w900); - FontManager.instance.addFont(Resources.Load(path: "Fonts/Roboto-BlackItalic"), "Roboto", - FontWeight.w900, FontStyle.italic); - FontManager.instance.addFont(Resources.Load(path: "Fonts/Roboto-Bold"), "Roboto", - FontWeight.bold); - FontManager.instance.addFont(Resources.Load(path: "Fonts/Roboto-BoldItalic"), "Roboto", - FontWeight.bold, FontStyle.italic); - FontManager.instance.addFont(Resources.Load(path: "Fonts/Roboto-Regular"), "Roboto", - FontWeight.normal); - FontManager.instance.addFont(Resources.Load(path: "Fonts/Roboto-Italic"), "Roboto", - FontWeight.normal, FontStyle.italic); - FontManager.instance.addFont(Resources.Load(path: "Fonts/Roboto-Medium"), "Roboto", - FontWeight.w500); - FontManager.instance.addFont(Resources.Load(path: "Fonts/Roboto-MediumItalic"), "Roboto", - FontWeight.w500, FontStyle.italic); - FontManager.instance.addFont(Resources.Load(path: "Fonts/Roboto-Light"), "Roboto", - FontWeight.w300); - FontManager.instance.addFont(Resources.Load(path: "Fonts/Roboto-LightItalic"), "Roboto", - FontWeight.w300, FontStyle.italic); - FontManager.instance.addFont(Resources.Load(path: "Fonts/Roboto-Thin"), "Roboto", - FontWeight.w100); - FontManager.instance.addFont(Resources.Load(path: "Fonts/Roboto-ThinItalic"), "Roboto", - FontWeight.w100, FontStyle.italic); - - base.OnEnable(); - } - - protected override Widget createWidget() { - return new MaterialApp( - title: "Navigation Basics", - home: new FontWeightStyleWidget() - ); - } - } - - class FontWeightStyleWidget : StatelessWidget { - public override Widget build(BuildContext context) { - var fontStyleTexts = new List { - new Text("Thin", style: new TextStyle(fontWeight: FontWeight.w100)), - new Text("Thin Italic", style: new TextStyle(fontWeight: FontWeight.w100, - fontStyle: FontStyle.italic)), - new Text("Light", style: new TextStyle(fontWeight: FontWeight.w300)), - new Text("Light Italic", style: new TextStyle(fontWeight: FontWeight.w300, - fontStyle: FontStyle.italic)), - new Text("Regular", style: new TextStyle(fontWeight: FontWeight.normal)), - new Text("Regular Italic", style: new TextStyle(fontWeight: FontWeight.normal, - fontStyle: FontStyle.italic)), - new Text("Medium", style: new TextStyle(fontWeight: FontWeight.w500)), - new Text("Medium Italic", style: new TextStyle(fontWeight: FontWeight.w500, - fontStyle: FontStyle.italic)), - new Text("Bold", style: new TextStyle(fontWeight: FontWeight.bold)), - new Text("Bold Italic", style: new TextStyle(fontWeight: FontWeight.bold, - fontStyle: FontStyle.italic)), - new Text("Black", style: new TextStyle(fontWeight: FontWeight.w900)), - new Text("Black Italic", style: new TextStyle(fontWeight: FontWeight.w900, - fontStyle: FontStyle.italic)), - }; - return new Scaffold( - appBar: new AppBar( - title: new Text("Font weight & style") - ), - body: new Card( - child: new DefaultTextStyle( - style: new TextStyle(fontSize: 40, fontFamily: "Roboto"), - child: new ListView(children: fontStyleTexts)) - ) - ); - } - } -} \ No newline at end of file diff --git a/Samples/UIWidgetSample/txt/FontWeightStyle.cs.meta b/Samples/UIWidgetSample/txt/FontWeightStyle.cs.meta deleted file mode 100644 index 0345d26c..00000000 --- a/Samples/UIWidgetSample/txt/FontWeightStyle.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: b64f268a7786741718163d1a4eef0a8c -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetSample/txt/TextFieldSample.cs b/Samples/UIWidgetSample/txt/TextFieldSample.cs deleted file mode 100644 index dd386a24..00000000 --- a/Samples/UIWidgetSample/txt/TextFieldSample.cs +++ /dev/null @@ -1,72 +0,0 @@ -using Unity.UIWidgets.material; -using Unity.UIWidgets.painting; -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; -using UnityEngine; -using DialogUtils = Unity.UIWidgets.material.DialogUtils; - -namespace UIWidgetsSample { - public class TextFieldSample : UIWidgetsSamplePanel { - protected override Widget createWidget() { - return new MaterialApp( - title: "Text Fields", - home: new MyCustomForm() - ); - } - - protected override void OnEnable() { - base.OnEnable(); - FontManager.instance.addFont(Resources.Load(path: "MaterialIcons-Regular"), "Material Icons"); - } - } - - class MyCustomForm : StatefulWidget { - public override State createState() { - return new _MyCustomFormState(); - } - } - - class _MyCustomFormState : State { - readonly TextEditingController myController = new TextEditingController(); - - public override void dispose() { - this.myController.dispose(); - base.dispose(); - } - - public override Widget build(BuildContext context) { - return new Scaffold( - appBar: new AppBar( - title: new Text("Retrieve Text Input") - ), - body: new Padding( - padding: EdgeInsets.all(16.0f), - child: new TextField( - controller: this.myController, - autofocus: true, - decoration: new InputDecoration( - hintText: "hinthere", - labelText: "pwd", - prefixIcon: new Icon(Unity.UIWidgets.material.Icons.search))) - ), - floatingActionButton: new FloatingActionButton( - // When the user presses the button, show an alert dialog with the - // text the user has typed into our text field. - onPressed: () => { - DialogUtils.showDialog( - context: context, - builder: (_context) => { - return new AlertDialog( - // Retrieve the text the user has typed in using our - // TextEditingController - content: new Text(this.myController.text) - ); - }); - }, - tooltip: "Show me the value", - child: new Icon(Icons.search) - ) - ); - } - } -} \ No newline at end of file diff --git a/Samples/UIWidgetSample/txt/TextFieldSample.cs.meta b/Samples/UIWidgetSample/txt/TextFieldSample.cs.meta deleted file mode 100644 index 2a1ae401..00000000 --- a/Samples/UIWidgetSample/txt/TextFieldSample.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 85b678a668e064f5c90ee8a9f7c13f35 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetSample/txt/TextSpanGesture.cs b/Samples/UIWidgetSample/txt/TextSpanGesture.cs deleted file mode 100644 index 1da1d7da..00000000 --- a/Samples/UIWidgetSample/txt/TextSpanGesture.cs +++ /dev/null @@ -1,68 +0,0 @@ -using System.Collections.Generic; -using Unity.UIWidgets.gestures; -using Unity.UIWidgets.material; -using Unity.UIWidgets.painting; -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; -using UnityEngine; -using TextStyle = Unity.UIWidgets.painting.TextStyle; - -namespace UIWidgetsSample { - public class TextSpanGesture : UIWidgetsSamplePanel { - protected override Widget createWidget() { - return new WidgetsApp( - home: new BuzzingText(), - pageRouteBuilder: this.pageRouteBuilder); - } - } - - class BuzzingText : StatefulWidget { - public override State createState() { - return new _BuzzingTextState(); - } - } - - class _BuzzingTextState : State { - LongPressGestureRecognizer _longPressRecognizer; - - public override void initState() { - base.initState(); - this._longPressRecognizer = new LongPressGestureRecognizer(); - this._longPressRecognizer.onLongPress = this._handlePress; - } - - public override void dispose() { - this._longPressRecognizer.dispose(); - base.dispose(); - } - - void _handlePress() { - Debug.Log("Long Pressed Text"); - } - /* - - Any professional looking app you have seen probably has multiple screens in it. It can contain a welcome screen, a login screen and then further screens. - */ - - public override Widget build(BuildContext context) { - return new RichText( - text: new TextSpan( - text: "Can you ", - style: new TextStyle(color: Colors.black), - children: new List() { - new TextSpan( - text: "find the", - style: new TextStyle( - color: Colors.green, - decoration: TextDecoration.underline - ) - //recognizer: this._longPressRecognizer - ), - new TextSpan( - text: " secret?" - ) - } - )); - } - } -} \ No newline at end of file diff --git a/Samples/UIWidgetSample/txt/TextSpanGesture.cs.meta b/Samples/UIWidgetSample/txt/TextSpanGesture.cs.meta deleted file mode 100644 index 381007df..00000000 --- a/Samples/UIWidgetSample/txt/TextSpanGesture.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c91c5cfdde64e465e956815f92b78ae7 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetSample/txt/TextStyleSample.cs b/Samples/UIWidgetSample/txt/TextStyleSample.cs deleted file mode 100644 index cb0d43da..00000000 --- a/Samples/UIWidgetSample/txt/TextStyleSample.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System.Collections.Generic; -using Unity.UIWidgets.material; -using Unity.UIWidgets.painting; -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; - -namespace UIWidgetsSample { - - public class TextStyleSample : UIWidgetsSamplePanel { - - protected override Widget createWidget() { - return new MaterialApp( - title: "Text Style", - home: new TextStyleSampleWidget() - ); - } - } - - class TextStyleSampleWidget : StatelessWidget { - public override Widget build(BuildContext context) { - var fontStyleTexts = new List { - new Text("text", style: new TextStyle(fontSize: 18)), - new Text("text with font size 0 below", style: new TextStyle(fontSize: 14)), - new Text("font size 0", style: new TextStyle(fontSize: 0)), - new Text("text with font size 0 above", style: new TextStyle(fontSize: 14)), - new Text("text with font size 0.3f", style: new TextStyle(fontSize: 0.3f)), - new Text("Text with background", style: new TextStyle(fontSize: 14, background: - new Paint(){color = new Color(0xFF00FF00)})), - new Text("positive letter spacing", style: new TextStyle(fontSize: 14, letterSpacing:5)), - new Text("negative letter spacing", style: new TextStyle(fontSize: 14, letterSpacing:-1)), - new Text("positive word spacing test", style: new TextStyle(fontSize: 14, wordSpacing: 20f)), - new Text("negative word spacing test", style: new TextStyle(fontSize: 14, wordSpacing: -4f)), - - }; - return new Scaffold( - appBar: new AppBar( - title: new Text("Text Style") - ), - body: new Card( - child: new DefaultTextStyle( - style: new TextStyle(fontSize: 40, fontFamily: "Roboto"), - child: new ListView(children: fontStyleTexts)) - ) - ); - } - } -} \ No newline at end of file diff --git a/Samples/UIWidgetSample/txt/TextStyleSample.cs.meta b/Samples/UIWidgetSample/txt/TextStyleSample.cs.meta deleted file mode 100644 index b5f2fd1d..00000000 --- a/Samples/UIWidgetSample/txt/TextStyleSample.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 1de691b215926469a959e54492262ff4 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetsGallery.meta b/Samples/UIWidgetsGallery.meta deleted file mode 100644 index aff0c070..00000000 --- a/Samples/UIWidgetsGallery.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: d5570637d1b25467596ae3c19ff7f0b2 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetsGallery/Editor.meta b/Samples/UIWidgetsGallery/Editor.meta deleted file mode 100644 index 10dd8fcd..00000000 --- a/Samples/UIWidgetsGallery/Editor.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 348a394ab7d3f4ba088eb92226e94979 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetsGallery/Editor/GalleryMainEditor.cs b/Samples/UIWidgetsGallery/Editor/GalleryMainEditor.cs deleted file mode 100644 index d935056a..00000000 --- a/Samples/UIWidgetsGallery/Editor/GalleryMainEditor.cs +++ /dev/null @@ -1,26 +0,0 @@ -using UIWidgetsGallery.gallery; -using Unity.UIWidgets.editor; -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; -using UnityEditor; -using UnityEngine; - -namespace UIWidgetsGallery { - public class GalleryMainEditor : UIWidgetsEditorWindow { - - [MenuItem("UIWidgetsTests/Gallery")] - public static void gallery() { - EditorWindow.GetWindow(); - } - - protected override Widget createWidget() { - return new GalleryApp(); - } - - protected override void OnEnable() { - FontManager.instance.addFont(Resources.Load("MaterialIcons-Regular"), "Material Icons"); - FontManager.instance.addFont(Resources.Load("GalleryIcons"), "GalleryIcons"); - base.OnEnable(); - } - } -} diff --git a/Samples/UIWidgetsGallery/Editor/GalleryMainEditor.cs.meta b/Samples/UIWidgetsGallery/Editor/GalleryMainEditor.cs.meta deleted file mode 100644 index 8bfa1793..00000000 --- a/Samples/UIWidgetsGallery/Editor/GalleryMainEditor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 98f11153c8c804448abe7a050222da98 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetsGallery/Editor/UIWidgetsGallery.Editor.asmdef b/Samples/UIWidgetsGallery/Editor/UIWidgetsGallery.Editor.asmdef deleted file mode 100644 index 5a3b1c82..00000000 --- a/Samples/UIWidgetsGallery/Editor/UIWidgetsGallery.Editor.asmdef +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "UIWidgetsGallery.Editor", - "references": [ - "Unity.UIWidgets", - "UIWidgetsGallery"], - "optionalUnityReferences": [], - "includePlatforms": [ - "Editor" - ], - "excludePlatforms": [] -} \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/Editor/UIWidgetsGallery.Editor.asmdef.meta b/Samples/UIWidgetsGallery/Editor/UIWidgetsGallery.Editor.asmdef.meta deleted file mode 100644 index 1689291e..00000000 --- a/Samples/UIWidgetsGallery/Editor/UIWidgetsGallery.Editor.asmdef.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 58e068d0e290f4278b5ee4a75e56c10f -AssemblyDefinitionImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetsGallery/GalleryMain.cs b/Samples/UIWidgetsGallery/GalleryMain.cs deleted file mode 100644 index 269b097b..00000000 --- a/Samples/UIWidgetsGallery/GalleryMain.cs +++ /dev/null @@ -1,21 +0,0 @@ -using UIWidgetsGallery.gallery; -using Unity.UIWidgets.engine; -using Unity.UIWidgets.material; -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; -using UnityEngine; - -namespace UIWidgetsGallery { - public class GalleryMain : UIWidgetsPanel { - protected override Widget createWidget() { - return new GalleryApp(); - } - - protected override void OnEnable() { - FontManager.instance.addFont(Resources.Load("MaterialIcons-Regular"), "Material Icons"); - FontManager.instance.addFont(Resources.Load("GalleryIcons"), "GalleryIcons"); - - base.OnEnable(); - } - } -} diff --git a/Samples/UIWidgetsGallery/GalleryMain.cs.meta b/Samples/UIWidgetsGallery/GalleryMain.cs.meta deleted file mode 100644 index efab2055..00000000 --- a/Samples/UIWidgetsGallery/GalleryMain.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 9c5c86936ca864ae684720ddcd50d759 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetsGallery/UIWidgetsGallery.asmdef b/Samples/UIWidgetsGallery/UIWidgetsGallery.asmdef deleted file mode 100644 index 03378a7e..00000000 --- a/Samples/UIWidgetsGallery/UIWidgetsGallery.asmdef +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "UIWidgetsGallery", - "references": ["Unity.UIWidgets"], - "includePlatforms": [], - "excludePlatforms": [] -} diff --git a/Samples/UIWidgetsGallery/UIWidgetsGallery.asmdef.meta b/Samples/UIWidgetsGallery/UIWidgetsGallery.asmdef.meta deleted file mode 100644 index 08dfd5a3..00000000 --- a/Samples/UIWidgetsGallery/UIWidgetsGallery.asmdef.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 8597b5a1d1bdd45048ad62795a71b2f2 -AssemblyDefinitionImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetsGallery/demo.meta b/Samples/UIWidgetsGallery/demo.meta deleted file mode 100644 index 12a6f43e..00000000 --- a/Samples/UIWidgetsGallery/demo.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 5159692a5f76049d49b05fb717c096e3 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetsGallery/demo/animation.meta b/Samples/UIWidgetsGallery/demo/animation.meta deleted file mode 100644 index ff400158..00000000 --- a/Samples/UIWidgetsGallery/demo/animation.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 4861503ddfc74b9ba36f159521c79b65 -timeCreated: 1554970886 \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/demo/animation/home.cs b/Samples/UIWidgetsGallery/demo/animation/home.cs deleted file mode 100644 index 06eb8223..00000000 --- a/Samples/UIWidgetsGallery/demo/animation/home.cs +++ /dev/null @@ -1,616 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Unity.UIWidgets.animation; -using Unity.UIWidgets.foundation; -using Unity.UIWidgets.gestures; -using Unity.UIWidgets.material; -using Unity.UIWidgets.painting; -using Unity.UIWidgets.physics; -using Unity.UIWidgets.rendering; -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; -using UnityEngine; -using Color = Unity.UIWidgets.ui.Color; -using Rect = Unity.UIWidgets.ui.Rect; - -namespace UIWidgetsGallery.gallery { - class AnimationHomeUtils { - public static readonly Color _kAppBackgroundColor = new Color(0xFF353662); - public static readonly TimeSpan _kScrollDuration = new TimeSpan(0, 0, 0, 0, 400); - public static readonly Curve _kScrollCurve = Curves.fastOutSlowIn; - public const float _kAppBarMinHeight = 90.0f; - public const float _kAppBarMidHeight = 256.0f; - } - - class _RenderStatusBarPaddingSliver : RenderSliver { - public _RenderStatusBarPaddingSliver( - float? maxHeight = null, - float? scrollFactor = null - ) { - D.assert(maxHeight >= 0.0f); - D.assert(scrollFactor >= 1.0f); - this._maxHeight = maxHeight; - this._scrollFactor = scrollFactor; - } - - public float? maxHeight { - get { return this._maxHeight; } - set { - D.assert(this.maxHeight >= 0.0f); - if (this._maxHeight == value) { - return; - } - - this._maxHeight = value; - this.markNeedsLayout(); - } - } - - float? _maxHeight; - - public float? scrollFactor { - get { return this._scrollFactor; } - set { - D.assert(this.scrollFactor >= 1.0f); - if (this._scrollFactor == value) { - return; - } - - this._scrollFactor = value; - this.markNeedsLayout(); - } - } - - float? _scrollFactor; - - protected override void performLayout() { - float? height = - (this.maxHeight - this.constraints.scrollOffset / this.scrollFactor)?.clamp(0.0f, - this.maxHeight ?? 0.0f); - this.geometry = new SliverGeometry( - paintExtent: Mathf.Min(height ?? 0.0f, this.constraints.remainingPaintExtent), - scrollExtent: this.maxHeight ?? 0.0f, - maxPaintExtent: this.maxHeight ?? 0.0f - ); - } - } - - class _StatusBarPaddingSliver : SingleChildRenderObjectWidget { - public _StatusBarPaddingSliver( - Key key = null, - float? maxHeight = null, - float scrollFactor = 5.0f - ) : base(key: key) { - D.assert(maxHeight != null && maxHeight >= 0.0f); - D.assert(scrollFactor >= 1.0f); - this.maxHeight = maxHeight; - this.scrollFactor = scrollFactor; - } - - public readonly float? maxHeight; - public readonly float scrollFactor; - - public override RenderObject createRenderObject(BuildContext context) { - return new _RenderStatusBarPaddingSliver( - maxHeight: this.maxHeight, - scrollFactor: this.scrollFactor - ); - } - - public override void updateRenderObject(BuildContext context, RenderObject _renderObject) { - _RenderStatusBarPaddingSliver renderObject = _renderObject as _RenderStatusBarPaddingSliver; - renderObject.maxHeight = this.maxHeight; - renderObject.scrollFactor = this.scrollFactor; - } - - public override void debugFillProperties(DiagnosticPropertiesBuilder description) { - base.debugFillProperties(description); - description.add(new FloatProperty("maxHeight", this.maxHeight)); - description.add(new FloatProperty("scrollFactor", this.scrollFactor)); - } - } - - class _SliverAppBarDelegate : SliverPersistentHeaderDelegate { - public _SliverAppBarDelegate( - float minHeight, - float maxHeight, - Widget child - ) { - this.minHeight = minHeight; - this.maxHeight = maxHeight; - this.child = child; - } - - public readonly float minHeight; - public readonly float maxHeight; - public readonly Widget child; - - public override float? minExtent { - get { return this.minHeight; } - } - - public override float? maxExtent { - get { return Mathf.Max(this.maxHeight, this.minHeight); } - } - - public override Widget build(BuildContext context, float shrinkOffset, bool overlapsContent) { - return SizedBox.expand(child: this.child); - } - - public override bool shouldRebuild(SliverPersistentHeaderDelegate _oldDelegate) { - _SliverAppBarDelegate oldDelegate = _oldDelegate as _SliverAppBarDelegate; - return this.maxHeight != oldDelegate.maxHeight - || this.minHeight != oldDelegate.minHeight - || this.child != oldDelegate.child; - } - - public override string ToString() { - return "_SliverAppBarDelegate"; - } - } - - class _AllSectionsLayout : MultiChildLayoutDelegate { - public _AllSectionsLayout( - Alignment translation, - float tColumnToRow, - float tCollapsed, - int cardCount, - float selectedIndex - ) { - this.translation = translation; - this.tColumnToRow = tColumnToRow; - this.tCollapsed = tCollapsed; - this.cardCount = cardCount; - this.selectedIndex = selectedIndex; - } - - public readonly Alignment translation; - public readonly float tColumnToRow; - public readonly float tCollapsed; - public readonly int cardCount; - public readonly float selectedIndex; - - Rect _interpolateRect(Rect begin, Rect end) { - return Rect.lerp(begin, end, this.tColumnToRow); - } - - Offset _interpolatePoint(Offset begin, Offset end) { - return Offset.lerp(begin, end, this.tColumnToRow); - } - - public override void performLayout(Size size) { - float columnCardX = size.width / 5.0f; - float columnCardWidth = size.width - columnCardX; - float columnCardHeight = size.height / this.cardCount; - float rowCardWidth = size.width; - Offset offset = this.translation.alongSize(size); - float columnCardY = 0.0f; - float rowCardX = -(this.selectedIndex * rowCardWidth); - - float columnTitleX = size.width / 10.0f; - float rowTitleWidth = size.width * ((1 + this.tCollapsed) / 2.25f); - float rowTitleX = (size.width - rowTitleWidth) / 2.0f - this.selectedIndex * rowTitleWidth; - - const float paddedSectionIndicatorWidth = AnimationWidgetsUtils.kSectionIndicatorWidth + 8.0f; - float rowIndicatorWidth = paddedSectionIndicatorWidth + - (1.0f - this.tCollapsed) * (rowTitleWidth - paddedSectionIndicatorWidth); - float rowIndicatorX = (size.width - rowIndicatorWidth) / 2.0f - this.selectedIndex * rowIndicatorWidth; - - for (int index = 0; index < this.cardCount; index++) { - Rect columnCardRect = Rect.fromLTWH(columnCardX, columnCardY, columnCardWidth, columnCardHeight); - Rect rowCardRect = Rect.fromLTWH(rowCardX, 0.0f, rowCardWidth, size.height); - Rect cardRect = this._interpolateRect(columnCardRect, rowCardRect).shift(offset); - string cardId = $"card{index}"; - if (this.hasChild(cardId)) { - this.layoutChild(cardId, BoxConstraints.tight(cardRect.size)); - this.positionChild(cardId, cardRect.topLeft); - } - - Size titleSize = this.layoutChild($"title{index}", BoxConstraints.loose(cardRect.size)); - float columnTitleY = columnCardRect.centerLeft.dy - titleSize.height / 2.0f; - float rowTitleY = rowCardRect.centerLeft.dy - titleSize.height / 2.0f; - float centeredRowTitleX = rowTitleX + (rowTitleWidth - titleSize.width) / 2.0f; - Offset columnTitleOrigin = new Offset(columnTitleX, columnTitleY); - Offset rowTitleOrigin = new Offset(centeredRowTitleX, rowTitleY); - Offset titleOrigin = this._interpolatePoint(columnTitleOrigin, rowTitleOrigin); - this.positionChild($"title{index}", titleOrigin + offset); - - Size indicatorSize = this.layoutChild($"indicator{index}", BoxConstraints.loose(cardRect.size)); - float columnIndicatorX = cardRect.centerRight.dx - indicatorSize.width - 16.0f; - float columnIndicatorY = cardRect.bottomRight.dy - indicatorSize.height - 16.0f; - Offset columnIndicatorOrigin = new Offset(columnIndicatorX, columnIndicatorY); - Rect titleRect = Rect.fromPoints(titleOrigin, titleSize.bottomRight(titleOrigin)); - float centeredRowIndicatorX = rowIndicatorX + (rowIndicatorWidth - indicatorSize.width) / 2.0f; - float rowIndicatorY = titleRect.bottomCenter.dy + 16.0f; - Offset rowIndicatorOrigin = new Offset(centeredRowIndicatorX, rowIndicatorY); - Offset indicatorOrigin = this._interpolatePoint(columnIndicatorOrigin, rowIndicatorOrigin); - this.positionChild($"indicator{index}", indicatorOrigin + offset); - - columnCardY += columnCardHeight; - rowCardX += rowCardWidth; - rowTitleX += rowTitleWidth; - rowIndicatorX += rowIndicatorWidth; - } - } - - public override bool shouldRelayout(MultiChildLayoutDelegate _oldDelegate) { - _AllSectionsLayout oldDelegate = _oldDelegate as _AllSectionsLayout; - return this.tColumnToRow != oldDelegate.tColumnToRow - || this.cardCount != oldDelegate.cardCount - || this.selectedIndex != oldDelegate.selectedIndex; - } - } - - class _AllSectionsView : AnimatedWidget { - public _AllSectionsView( - Key key = null, - int? sectionIndex = null, - List
    sections = null, - ValueNotifier selectedIndex = null, - float? minHeight = null, - float? midHeight = null, - float? maxHeight = null, - List sectionCards = null - ) : base(key: key, listenable: selectedIndex) { - sectionCards = sectionCards ?? new List(); - D.assert(sections != null); - D.assert(sectionCards.Count == sections.Count); - D.assert(sectionIndex >= 0 && sectionIndex < sections.Count); - D.assert(selectedIndex != null); - D.assert(selectedIndex.value >= 0.0f && (float) selectedIndex.value < sections.Count); - this.sectionIndex = sectionIndex; - this.sections = sections; - this.selectedIndex = selectedIndex; - this.minHeight = minHeight; - this.midHeight = midHeight; - this.maxHeight = maxHeight; - this.sectionCards = sectionCards; - } - - public readonly int? sectionIndex; - public readonly List
    sections; - public readonly ValueNotifier selectedIndex; - public readonly float? minHeight; - public readonly float? midHeight; - public readonly float? maxHeight; - public readonly List sectionCards; - - float _selectedIndexDelta(int index) { - return (index - this.selectedIndex.value).abs().clamp(0.0f, 1.0f); - } - - Widget _build(BuildContext context, BoxConstraints constraints) { - Size size = constraints.biggest; - - float? tColumnToRow = - 1.0f - ((size.height - this.midHeight) / - (this.maxHeight - this.midHeight))?.clamp(0.0f, 1.0f); - - - float? tCollapsed = - 1.0f - ((size.height - this.minHeight) / - (this.midHeight - this.minHeight))?.clamp(0.0f, 1.0f); - - float _indicatorOpacity(int index) { - return 1.0f - this._selectedIndexDelta(index) * 0.5f; - } - - float? _titleOpacity(int index) { - return 1.0f - this._selectedIndexDelta(index) * tColumnToRow * 0.5f; - } - - float? _titleScale(int index) { - return 1.0f - this._selectedIndexDelta(index) * tColumnToRow * 0.15f; - } - - List children = new List(this.sectionCards); - - for (int index = 0; index < this.sections.Count; index++) { - Section section = this.sections[index]; - children.Add(new LayoutId( - id: $"title{index}", - child: new SectionTitle( - section: section, - scale: _titleScale(index), - opacity: _titleOpacity(index) - ) - )); - } - - for (int index = 0; index < this.sections.Count; index++) { - children.Add(new LayoutId( - id: $"indicator{index}", - child: new SectionIndicator( - opacity: _indicatorOpacity(index) - ) - )); - } - - return new CustomMultiChildLayout( - layoutDelegate: new _AllSectionsLayout( - translation: new Alignment((this.selectedIndex.value - this.sectionIndex) * 2.0f - 1.0f ?? 0.0f, - -1.0f), - tColumnToRow: tColumnToRow ?? 0.0f, - tCollapsed: tCollapsed ?? 0.0f, - cardCount: this.sections.Count, - selectedIndex: this.selectedIndex.value - ), - children: children - ); - } - - protected override Widget build(BuildContext context) { - return new LayoutBuilder(builder: this._build); - } - } - - class _SnappingScrollPhysics : ClampingScrollPhysics { - public _SnappingScrollPhysics( - ScrollPhysics parent = null, - float? midScrollOffset = null - ) : base(parent: parent) { - D.assert(midScrollOffset != null); - this.midScrollOffset = midScrollOffset ?? 0.0f; - } - - public readonly float midScrollOffset; - - public override ScrollPhysics applyTo(ScrollPhysics ancestor) { - return new _SnappingScrollPhysics(parent: this.buildParent(ancestor), - midScrollOffset: this.midScrollOffset); - } - - Simulation _toMidScrollOffsetSimulation(float offset, float dragVelocity) { - float velocity = Mathf.Max(dragVelocity, this.minFlingVelocity); - return new ScrollSpringSimulation(this.spring, offset, this.midScrollOffset, velocity, - tolerance: this.tolerance); - } - - Simulation _toZeroScrollOffsetSimulation(float offset, float dragVelocity) { - float velocity = Mathf.Max(dragVelocity, this.minFlingVelocity); - return new ScrollSpringSimulation(this.spring, offset, 0.0f, velocity, tolerance: this.tolerance); - } - - public override Simulation createBallisticSimulation(ScrollMetrics position, float dragVelocity) { - Simulation simulation = base.createBallisticSimulation(position, dragVelocity); - float offset = position.pixels; - - if (simulation != null) { - float simulationEnd = simulation.x(float.PositiveInfinity); - if (simulationEnd >= this.midScrollOffset) { - return simulation; - } - - if (dragVelocity > 0.0f) { - return this._toMidScrollOffsetSimulation(offset, dragVelocity); - } - - if (dragVelocity < 0.0f) { - return this._toZeroScrollOffsetSimulation(offset, dragVelocity); - } - } - else { - float snapThreshold = this.midScrollOffset / 2.0f; - if (offset >= snapThreshold && offset < this.midScrollOffset) { - return this._toMidScrollOffsetSimulation(offset, dragVelocity); - } - - if (offset > 0.0f && offset < snapThreshold) { - return this._toZeroScrollOffsetSimulation(offset, dragVelocity); - } - } - - return simulation; - } - } - - public class AnimationDemoHome : StatefulWidget { - public AnimationDemoHome(Key key = null) : base(key: key) { - } - - public const string routeName = "/animation"; - - public override State createState() { - return new _AnimationDemoHomeState(); - } - } - - class _AnimationDemoHomeState : State { - ScrollController _scrollController = new ScrollController(); - PageController _headingPageController = new PageController(); - PageController _detailsPageController = new PageController(); - ScrollPhysics _headingScrollPhysics = new NeverScrollableScrollPhysics(); - ValueNotifier selectedIndex = new ValueNotifier(0.0f); - - public override Widget build(BuildContext context) { - return new Scaffold( - backgroundColor: AnimationHomeUtils._kAppBackgroundColor, - body: new Builder( - builder: this._buildBody - ) - ); - } - - void _handleBackButton(float midScrollOffset) { - if (this._scrollController.offset >= midScrollOffset) { - this._scrollController.animateTo(0.0f, curve: AnimationHomeUtils._kScrollCurve, - duration: AnimationHomeUtils._kScrollDuration); - } - else { - Navigator.maybePop(this.context); - } - } - - bool _handleScrollNotification(ScrollNotification notification, float midScrollOffset) { - if (notification.depth == 0 && notification is ScrollUpdateNotification) { - ScrollPhysics physics = this._scrollController.position.pixels >= midScrollOffset - ? (ScrollPhysics) new PageScrollPhysics() - : new NeverScrollableScrollPhysics(); - if (physics != this._headingScrollPhysics) { - this.setState(() => { this._headingScrollPhysics = physics; }); - } - } - - return false; - } - - void _maybeScroll(float midScrollOffset, int pageIndex, float xOffset) { - if (this._scrollController.offset < midScrollOffset) { - this._headingPageController.animateToPage(pageIndex, curve: AnimationHomeUtils._kScrollCurve, - duration: AnimationHomeUtils._kScrollDuration); - this._scrollController.animateTo(midScrollOffset, curve: AnimationHomeUtils._kScrollCurve, - duration: AnimationHomeUtils._kScrollDuration); - } - else { - float centerX = this._headingPageController.position.viewportDimension / 2.0f; - int newPageIndex = xOffset > centerX ? pageIndex + 1 : pageIndex - 1; - this._headingPageController.animateToPage(newPageIndex, curve: AnimationHomeUtils._kScrollCurve, - duration: AnimationHomeUtils._kScrollDuration); - } - } - - bool _handlePageNotification(ScrollNotification notification, PageController leader, PageController follower) { - if (notification.depth == 0 && notification is ScrollUpdateNotification) { - this.selectedIndex.value = leader.page; - if (follower.page != leader.page) { - follower.position.jumpTo(leader.position.pixels); // ignore: deprecated_member_use - } - } - - return false; - } - - IEnumerable _detailItemsFor(Section section) { - IEnumerable detailItems = section.details.Select((SectionDetail detail) => { - return new SectionDetailView(detail: detail); - }); - return ListTile.divideTiles(context: this.context, tiles: detailItems); - } - - List _allHeadingItems(float maxHeight, float midScrollOffset) { - List sectionCards = new List { }; - for (int index = 0; index < AnimationSectionsUtils.allSections.Count; index++) { - sectionCards.Add(new LayoutId( - id: $"card{index}", - child: new GestureDetector( - behavior: HitTestBehavior.opaque, - child: new SectionCard(section: AnimationSectionsUtils.allSections[index]), - onTapUp: (TapUpDetails details) => { - float xOffset = details.globalPosition.dx; - this.setState(() => { this._maybeScroll(midScrollOffset, index, xOffset); }); - } - ) - )); - } - - List headings = new List { }; - for (int index = 0; index < AnimationSectionsUtils.allSections.Count; index++) { - headings.Add(new Container( - color: AnimationHomeUtils._kAppBackgroundColor, - child: new ClipRect( - child: new _AllSectionsView( - sectionIndex: index, - sections: AnimationSectionsUtils.allSections, - selectedIndex: this.selectedIndex, - minHeight: AnimationHomeUtils._kAppBarMinHeight, - midHeight: AnimationHomeUtils._kAppBarMidHeight, - maxHeight: maxHeight, - sectionCards: sectionCards - ) - ) - ) - ); - } - - return headings; - } - - Widget _buildBody(BuildContext context) { - MediaQueryData mediaQueryData = MediaQuery.of(context); - float statusBarHeight = mediaQueryData.padding.top; - float screenHeight = mediaQueryData.size.height; - float appBarMaxHeight = screenHeight - statusBarHeight; - - float appBarMidScrollOffset = statusBarHeight + appBarMaxHeight - AnimationHomeUtils._kAppBarMidHeight; - - return SizedBox.expand( - child: new Stack( - children: new List { - new NotificationListener( - onNotification: (ScrollNotification notification) => { - return this._handleScrollNotification(notification, appBarMidScrollOffset); - }, - child: new CustomScrollView( - controller: this._scrollController, - physics: new _SnappingScrollPhysics(midScrollOffset: appBarMidScrollOffset), - slivers: new List { - new _StatusBarPaddingSliver( - maxHeight: statusBarHeight, - scrollFactor: 7.0f - ), - new SliverPersistentHeader( - pinned: true, - del: new _SliverAppBarDelegate( - minHeight: AnimationHomeUtils._kAppBarMinHeight, - maxHeight: appBarMaxHeight, - child: new NotificationListener( - onNotification: (ScrollNotification notification) => { - return this._handlePageNotification(notification, - this._headingPageController, this._detailsPageController); - }, - child: new PageView( - physics: this._headingScrollPhysics, - controller: this._headingPageController, - children: this._allHeadingItems(appBarMaxHeight, - appBarMidScrollOffset) - ) - ) - ) - ), - new SliverToBoxAdapter( - child: new SizedBox( - height: 610.0f, - child: new NotificationListener( - onNotification: (ScrollNotification notification) => { - return this._handlePageNotification(notification, - this._detailsPageController, this._headingPageController); - }, - child: new PageView( - controller: this._detailsPageController, - children: AnimationSectionsUtils.allSections - .Select((Section section) => { - return new Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: this._detailItemsFor(section).ToList() - ); - }).ToList() - ) - ) - ) - ) - } - ) - ), - new Positioned( - top: statusBarHeight, - left: 0.0f, - child: new IconTheme( - data: new IconThemeData(color: Colors.white), - child: new SafeArea( - top: false, - bottom: false, - child: new IconButton( - icon: new BackButtonIcon(), - tooltip: "Back", - onPressed: () => { this._handleBackButton(appBarMidScrollOffset); } - ) - ) - ) - ) - } - ) - ); - } - } -} \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/demo/animation/home.cs.meta b/Samples/UIWidgetsGallery/demo/animation/home.cs.meta deleted file mode 100644 index fcce05fd..00000000 --- a/Samples/UIWidgetsGallery/demo/animation/home.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 628b4648bdda4c8d8c8fc6778c874067 -timeCreated: 1554970915 \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/demo/animation/sections.cs b/Samples/UIWidgetsGallery/demo/animation/sections.cs deleted file mode 100644 index 78dc6635..00000000 --- a/Samples/UIWidgetsGallery/demo/animation/sections.cs +++ /dev/null @@ -1,201 +0,0 @@ -using System.Collections.Generic; -using Unity.UIWidgets.material; -using Unity.UIWidgets.ui; - -namespace UIWidgetsGallery.gallery { - public class AnimationSectionsUtils { - public static readonly Color _mariner = new Color(0xFF3B5F8F); - public static readonly Color _mediumPurple = new Color(0xFF8266D4); - public static readonly Color _tomato = new Color(0xFFF95B57); - public static readonly Color _mySin = new Color(0xFFF3A646); - const string _kGalleryAssetsPackage = "flutter_gallery_assets"; - - public static readonly SectionDetail _eyeglassesDetail = new SectionDetail( - imageAsset: "products/sunnies", - imageAssetPackage: _kGalleryAssetsPackage, - title: "Flutter enables interactive animation", - subtitle: "3K views - 5 days" - ); - - public static readonly SectionDetail _eyeglassesImageDetail = new SectionDetail( - imageAsset: "products/sunnies", - imageAssetPackage: _kGalleryAssetsPackage - ); - - public static readonly SectionDetail _seatingDetail = new SectionDetail( - imageAsset: "products/table", - imageAssetPackage: _kGalleryAssetsPackage, - title: "Flutter enables interactive animation", - subtitle: "3K views - 5 days" - ); - - public static readonly SectionDetail _seatingImageDetail = new SectionDetail( - imageAsset: "products/table", - imageAssetPackage: _kGalleryAssetsPackage - ); - - public static readonly SectionDetail _decorationDetail = new SectionDetail( - imageAsset: "products/earrings", - imageAssetPackage: _kGalleryAssetsPackage, - title: "Flutter enables interactive animation", - subtitle: "3K views - 5 days" - ); - - public static readonly SectionDetail _decorationImageDetail = new SectionDetail( - imageAsset: "products/earrings", - imageAssetPackage: _kGalleryAssetsPackage - ); - - public static readonly SectionDetail _protectionDetail = new SectionDetail( - imageAsset: "products/hat", - imageAssetPackage: _kGalleryAssetsPackage, - title: "Flutter enables interactive animation", - subtitle: "3K views - 5 days" - ); - - public static readonly SectionDetail _protectionImageDetail = new SectionDetail( - imageAsset: "products/hat", - imageAssetPackage: _kGalleryAssetsPackage - ); - - public static List
    allSections = new List
    { - new Section( - title: "SUNGLASSES", - leftColor: _mediumPurple, - rightColor: _mariner, - backgroundAsset: "products/sunnies", - backgroundAssetPackage: _kGalleryAssetsPackage, - details: new List { - _eyeglassesDetail, - _eyeglassesImageDetail, - _eyeglassesDetail, - _eyeglassesDetail, - _eyeglassesDetail, - _eyeglassesDetail - } - ), - new Section( - title: "FURNITURE", - leftColor: _tomato, - rightColor: _mediumPurple, - backgroundAsset: "products/table", - backgroundAssetPackage: _kGalleryAssetsPackage, - details: new List { - _seatingDetail, - _seatingImageDetail, - _seatingDetail, - _seatingDetail, - _seatingDetail, - _seatingDetail - } - ), - new Section( - title: "JEWELRY", - leftColor: _mySin, - rightColor: _tomato, - backgroundAsset: "products/earrings", - backgroundAssetPackage: _kGalleryAssetsPackage, - details: new List { - _decorationDetail, - _decorationImageDetail, - _decorationDetail, - _decorationDetail, - _decorationDetail, - _decorationDetail - } - ), - new Section( - title: "HEADWEAR", - leftColor: Colors.white, - rightColor: _tomato, - backgroundAsset: "products/hat", - backgroundAssetPackage: _kGalleryAssetsPackage, - details: new List { - _protectionDetail, - _protectionImageDetail, - _protectionDetail, - _protectionDetail, - _protectionDetail, - _protectionDetail - } - ) - }; - } - - - public class SectionDetail { - public SectionDetail( - string title = null, - string subtitle = null, - string imageAsset = null, - string imageAssetPackage = null - ) { - this.title = title; - this.subtitle = subtitle; - this.imageAsset = imageAsset; - this.imageAssetPackage = imageAssetPackage; - } - - public readonly string title; - public readonly string subtitle; - public readonly string imageAsset; - public readonly string imageAssetPackage; - } - - public class Section { - public Section( - string title, - string backgroundAsset, - string backgroundAssetPackage, - Color leftColor, - Color rightColor, - List details - ) { - this.title = title; - this.backgroundAsset = backgroundAsset; - this.backgroundAssetPackage = backgroundAssetPackage; - this.leftColor = leftColor; - this.rightColor = rightColor; - this.details = details; - } - - public readonly string title; - public readonly string backgroundAsset; - public readonly string backgroundAssetPackage; - public readonly Color leftColor; - public readonly Color rightColor; - public readonly List details; - - public static bool operator ==(Section left, Section right) { - return Equals(left, right); - } - - public static bool operator !=(Section left, Section right) { - return !Equals(left, right); - } - - public bool Equals(Section other) { - return this.title == other.title; - } - - public override bool Equals(object obj) { - if (ReferenceEquals(null, obj)) { - return false; - } - - if (ReferenceEquals(this, obj)) { - return true; - } - - if (obj.GetType() != this.GetType()) { - return false; - } - - return this.Equals((Section) obj); - } - - public override int GetHashCode() { - return this.title.GetHashCode(); - } - } -} diff --git a/Samples/UIWidgetsGallery/demo/animation/sections.cs.meta b/Samples/UIWidgetsGallery/demo/animation/sections.cs.meta deleted file mode 100644 index dd42ed52..00000000 --- a/Samples/UIWidgetsGallery/demo/animation/sections.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 5180fb461b7448de8d4d084ff3f7c761 -timeCreated: 1555049317 \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/demo/animation/widgets.cs b/Samples/UIWidgetsGallery/demo/animation/widgets.cs deleted file mode 100644 index d2df415c..00000000 --- a/Samples/UIWidgetsGallery/demo/animation/widgets.cs +++ /dev/null @@ -1,169 +0,0 @@ -using System.Collections.Generic; -using Unity.UIWidgets.foundation; -using Unity.UIWidgets.material; -using Unity.UIWidgets.painting; -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; -using Image = Unity.UIWidgets.widgets.Image; - -namespace UIWidgetsGallery.gallery { - class AnimationWidgetsUtils { - public const float kSectionIndicatorWidth = 32.0f; - } - - public class SectionCard : StatelessWidget { - public SectionCard( - Key key = null, - Section section = null - ) : base(key: key) { - D.assert(section != null); - this.section = section; - } - - public readonly Section section; - - public override Widget build(BuildContext context) { - return new DecoratedBox( - decoration: new BoxDecoration( - gradient: new LinearGradient( - begin: Alignment.centerLeft, - end: Alignment.centerRight, - colors: new List { - this.section.leftColor, this.section.rightColor - } - ) - ), - child: Image.asset(this.section.backgroundAsset, - color: Color.fromRGBO(255, 255, 255, 0.075f), - colorBlendMode: BlendMode.modulate, - fit: BoxFit.cover - ) - ); - } - } - - public class SectionTitle : StatelessWidget { - public SectionTitle( - Key key = null, - Section section = null, - float? scale = null, - float? opacity = null - ) : base(key: key) { - D.assert(section != null); - D.assert(scale != null); - D.assert(opacity != null && opacity >= 0.0f && opacity <= 1.0f); - this.section = section; - this.scale = scale; - this.opacity = opacity; - } - - public readonly Section section; - public readonly float? scale; - public readonly float? opacity; - - public static readonly TextStyle sectionTitleStyle = new TextStyle( - fontFamily: "Raleway", - inherit: false, - fontSize: 24.0f, - fontWeight: FontWeight.w500, - color: Colors.white, - textBaseline: TextBaseline.alphabetic - ); - - public static readonly TextStyle sectionTitleShadowStyle = sectionTitleStyle.copyWith( - color: new Color(0x19000000) - ); - - public override Widget build(BuildContext context) { - return new IgnorePointer( - child: new Opacity( - opacity: this.opacity ?? 1.0f, - child: new Transform( - transform: Matrix3.makeScale(this.scale ?? 1.0f), - alignment: Alignment.center, - child: new Stack( - children: new List { - new Positioned( - top: 4.0f, - child: new Text(this.section.title, style: sectionTitleShadowStyle) - ), - new Text(this.section.title, style: sectionTitleStyle) - } - ) - ) - ) - ); - } - } - - public class SectionIndicator : StatelessWidget { - public SectionIndicator(Key key = null, float opacity = 1.0f) : base(key: key) { - this.opacity = opacity; - } - - public readonly float opacity; - - public override Widget build(BuildContext context) { - return new IgnorePointer( - child: new Container( - width: AnimationWidgetsUtils.kSectionIndicatorWidth, - height: 3.0f, - color: Colors.white.withOpacity(this.opacity) - ) - ); - } - } - - public class SectionDetailView : StatelessWidget { - public SectionDetailView( - Key key = null, - SectionDetail detail = null - ) : base(key: key) { - D.assert(detail != null && detail.imageAsset != null); - D.assert((detail.imageAsset ?? detail.title) != null); - this.detail = detail; - } - - public readonly SectionDetail detail; - - public override Widget build(BuildContext context) { - Widget image = new DecoratedBox( - decoration: new BoxDecoration( - borderRadius: BorderRadius.circular(6.0f), - image: new DecorationImage( - image: new AssetImage( - this.detail.imageAsset - ), - fit: BoxFit.cover, - alignment: Alignment.center - ) - ) - ); - - Widget item; - if (this.detail.title == null && this.detail.subtitle == null) { - item = new Container( - height: 240.0f, - padding: EdgeInsets.all(16.0f), - child: new SafeArea( - top: false, - bottom: false, - child: image - ) - ); - } - else { - item = new ListTile( - title: new Text(this.detail.title), - subtitle: new Text(this.detail.subtitle), - leading: new SizedBox(width: 32.0f, height: 32.0f, child: image) - ); - } - - return new DecoratedBox( - decoration: new BoxDecoration(color: Colors.grey.shade200), - child: item - ); - } - } -} \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/demo/animation/widgets.cs.meta b/Samples/UIWidgetsGallery/demo/animation/widgets.cs.meta deleted file mode 100644 index ae1689c3..00000000 --- a/Samples/UIWidgetsGallery/demo/animation/widgets.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 4c84aedb64bf44338944d63be7c563ed -timeCreated: 1555049115 \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/demo/animation_demo.cs b/Samples/UIWidgetsGallery/demo/animation_demo.cs deleted file mode 100644 index c6032344..00000000 --- a/Samples/UIWidgetsGallery/demo/animation_demo.cs +++ /dev/null @@ -1,15 +0,0 @@ -using Unity.UIWidgets.foundation; -using Unity.UIWidgets.widgets; - -namespace UIWidgetsGallery.gallery { - public class AnimationDemo : StatelessWidget { - public AnimationDemo(Key key = null) : base(key: key) { - } - - public const string routeName = "/animation"; - - public override Widget build(BuildContext context) { - return new AnimationDemoHome(); - } - } -} \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/demo/animation_demo.cs.meta b/Samples/UIWidgetsGallery/demo/animation_demo.cs.meta deleted file mode 100644 index c51f9afc..00000000 --- a/Samples/UIWidgetsGallery/demo/animation_demo.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: f13faff4d2b84ce0935236f3b953849f -timeCreated: 1554969121 \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/demo/colors_demo.cs b/Samples/UIWidgetsGallery/demo/colors_demo.cs deleted file mode 100644 index bf735c6f..00000000 --- a/Samples/UIWidgetsGallery/demo/colors_demo.cs +++ /dev/null @@ -1,172 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using Unity.UIWidgets.foundation; -using Unity.UIWidgets.material; -using Unity.UIWidgets.painting; -using Unity.UIWidgets.rendering; -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; -using TextStyle = Unity.UIWidgets.painting.TextStyle; - -namespace UIWidgetsGallery.gallery { - class ColorDemoConstants { - public const float kColorItemHeight = 48.0f; - - public static readonly List allPalettes = new List { - new Palette(name: "RED", primary: Colors.red, accent: Colors.redAccent, threshold: 300), - new Palette(name: "PINK", primary: Colors.pink, accent: Colors.pinkAccent, threshold: 200), - new Palette(name: "PURPLE", primary: Colors.purple, accent: Colors.purpleAccent, threshold: 200), - new Palette(name: "DEEP PURPLE", primary: Colors.deepPurple, accent: Colors.deepPurpleAccent, - threshold: 200), - new Palette(name: "INDIGO", primary: Colors.indigo, accent: Colors.indigoAccent, threshold: 200), - new Palette(name: "BLUE", primary: Colors.blue, accent: Colors.blueAccent, threshold: 400), - new Palette(name: "LIGHT BLUE", primary: Colors.lightBlue, accent: Colors.lightBlueAccent, threshold: 500), - new Palette(name: "CYAN", primary: Colors.cyan, accent: Colors.cyanAccent, threshold: 600), - new Palette(name: "TEAL", primary: Colors.teal, accent: Colors.tealAccent, threshold: 400), - new Palette(name: "GREEN", primary: Colors.green, accent: Colors.greenAccent, threshold: 500), - new Palette(name: "LIGHT GREEN", primary: Colors.lightGreen, accent: Colors.lightGreenAccent, - threshold: 600), - new Palette(name: "LIME", primary: Colors.lime, accent: Colors.limeAccent, threshold: 800), - new Palette(name: "YELLOW", primary: Colors.yellow, accent: Colors.yellowAccent), - new Palette(name: "AMBER", primary: Colors.amber, accent: Colors.amberAccent), - new Palette(name: "ORANGE", primary: Colors.orange, accent: Colors.orangeAccent, threshold: 700), - new Palette(name: "DEEP ORANGE", primary: Colors.deepOrange, accent: Colors.deepOrangeAccent, - threshold: 400), - new Palette(name: "BROWN", primary: Colors.brown, threshold: 200), - new Palette(name: "GREY", primary: Colors.grey, threshold: 500), - new Palette(name: "BLUE GREY", primary: Colors.blueGrey, threshold: 500), - }; - } - - public class Palette { - public Palette(string name = null, MaterialColor primary = null, MaterialAccentColor accent = null, - int threshold = 900) { - this.name = name; - this.primary = primary; - this.accent = accent; - this.threshold = threshold; - } - - public readonly string name; - public readonly MaterialColor primary; - public readonly MaterialAccentColor accent; - public readonly int threshold; - - public bool isValid { - get { return this.name != null && this.primary != null; } - } - } - - - public class ColorItem : StatelessWidget { - public ColorItem( - Key key = null, - int? index = null, - Color color = null, - string prefix = "" - ) : base(key: key) { - D.assert(index != null); - D.assert(color != null); - D.assert(prefix != null); - this.index = index; - this.color = color; - this.prefix = prefix; - } - - - public readonly int? index; - public readonly Color color; - public readonly string prefix; - - string colorString() { - return $"#{this.color.value.ToString("X8").ToUpper()}"; - } - - public override Widget build(BuildContext context) { - return new Container( - height: ColorDemoConstants.kColorItemHeight, - padding: EdgeInsets.symmetric(horizontal: 16.0f), - color: this.color, - child: new SafeArea( - top: false, - bottom: false, - child: new Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.center, - children: new List { - new Text($"{this.prefix}{this.index}"), - new Text(this.colorString()) - } - ) - ) - ); - } - } - - public class PaletteTabView : StatelessWidget { - public PaletteTabView( - Key key = null, - Palette colors = null - ) : base(key: key) { - D.assert(colors != null && colors.isValid); - this.colors = colors; - } - - public readonly Palette colors; - - public readonly static List primaryKeys = new List {50, 100, 200, 300, 400, 500, 600, 700, 800, 900}; - public readonly static List accentKeys = new List {100, 200, 400, 700}; - - public override Widget build(BuildContext context) { - TextTheme textTheme = Theme.of(context).textTheme; - TextStyle whiteTextStyle = textTheme.body1.copyWith(color: Colors.white); - TextStyle blackTextStyle = textTheme.body1.copyWith(color: Colors.black); - List colorItems = primaryKeys.Select((int index) => { - return new DefaultTextStyle( - style: index > this.colors.threshold ? whiteTextStyle : blackTextStyle, - child: new ColorItem(index: index, color: this.colors.primary[index]) - ); - }).ToList(); - - if (this.colors.accent != null) { - colorItems.AddRange(accentKeys.Select((int index) => { - return new DefaultTextStyle( - style: index > this.colors.threshold ? whiteTextStyle : blackTextStyle, - child: new ColorItem(index: index, color: this.colors.accent[index], prefix: "A") - ); - }).ToList()); - } - - return new ListView( - itemExtent: ColorDemoConstants.kColorItemHeight, - children: colorItems - ); - } - } - - public class ColorsDemo : StatelessWidget { - public const string routeName = "/colors"; - - public override Widget build(BuildContext context) { - return new DefaultTabController( - length: ColorDemoConstants.allPalettes.Count, - child: new Scaffold( - appBar: new AppBar( - elevation: 0.0f, - title: new Text("Colors"), - bottom: new TabBar( - isScrollable: true, - tabs: ColorDemoConstants.allPalettes - .Select((Palette swatch) => new Tab(text: swatch.name)).ToList() - ) - ), - body: new TabBarView( - children: ColorDemoConstants.allPalettes.Select((Palette colors) => { - return new PaletteTabView(colors: colors); - }).ToList() - ) - ) - ); - } - } -} \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/demo/colors_demo.cs.meta b/Samples/UIWidgetsGallery/demo/colors_demo.cs.meta deleted file mode 100644 index 4278d19f..00000000 --- a/Samples/UIWidgetsGallery/demo/colors_demo.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 40024f3eaf7b44bfb09e27137c9d4aa9 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetsGallery/demo/contacts_demo.cs b/Samples/UIWidgetsGallery/demo/contacts_demo.cs deleted file mode 100644 index 0277a1fe..00000000 --- a/Samples/UIWidgetsGallery/demo/contacts_demo.cs +++ /dev/null @@ -1,365 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using Unity.UIWidgets.foundation; -using Unity.UIWidgets.material; -using Unity.UIWidgets.painting; -using Unity.UIWidgets.rendering; -using Unity.UIWidgets.service; -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; -using Image = Unity.UIWidgets.widgets.Image; - -namespace UIWidgetsGallery.gallery { - class _ContactCategory : StatelessWidget { - public _ContactCategory(Key key = null, IconData icon = null, List children = null) : base(key: key) { - this.icon = icon; - this.children = children; - } - - public readonly IconData icon; - public readonly List children; - - public override Widget build(BuildContext context) { - ThemeData themeData = Theme.of(context); - return new Container( - padding: EdgeInsets.symmetric(vertical: 16.0f), - decoration: new BoxDecoration( - border: new Border(bottom: new BorderSide(color: themeData.dividerColor)) - ), - child: new DefaultTextStyle( - style: Theme.of(context).textTheme.subhead, - child: new SafeArea( - top: false, - bottom: false, - child: new Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: new List { - new Container( - padding: EdgeInsets.symmetric(vertical: 24.0f), - width: 72.0f, - child: new Icon(this.icon, color: themeData.primaryColor) - ), - new Expanded(child: new Column(children: this.children)) - } - ) - ) - ) - ); - } - } - - class _ContactItem : StatelessWidget { - public _ContactItem(Key key = null, IconData icon = null, List lines = null, string tooltip = null, - VoidCallback onPressed = null) : base(key: key) { - D.assert(lines.Count > 1); - this.icon = icon; - this.lines = lines; - this.tooltip = tooltip; - this.onPressed = onPressed; - } - - public readonly IconData icon; - public readonly List lines; - public readonly string tooltip; - public readonly VoidCallback onPressed; - - public override Widget build(BuildContext context) { - ThemeData themeData = Theme.of(context); - List columnChildren = this.lines.GetRange(0, this.lines.Count - 1) - .Select((string line) => new Text(line)).ToList(); - columnChildren.Add(new Text(this.lines.Last(), style: themeData.textTheme.caption)); - - List rowChildren = new List { - new Expanded( - child: new Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: columnChildren - ) - ) - }; - if (this.icon != null) { - rowChildren.Add(new SizedBox( - width: 72.0f, - child: new IconButton( - icon: new Icon(this.icon), - color: themeData.primaryColor, - onPressed: this.onPressed - ) - )); - } - - return new Padding( - padding: EdgeInsets.symmetric(vertical: 16.0f), - child: new Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: rowChildren - ) - ); - } - } - - public class ContactsDemo : StatefulWidget { - public const string routeName = "/contacts"; - - public override State createState() { - return new ContactsDemoState(); - } - } - - public enum AppBarBehavior { - normal, - pinned, - floating, - snapping - } - - public class ContactsDemoState : State { - readonly GlobalKey _scaffoldKey = GlobalKey.key(); - const float _appBarHeight = 256.0f; - - AppBarBehavior _appBarBehavior = AppBarBehavior.pinned; - - public override Widget build(BuildContext context) { - return new Theme( - data: new ThemeData( - brightness: Brightness.light, - primarySwatch: Colors.indigo, - platform: Theme.of(context).platform - ), - child: new Scaffold( - key: this._scaffoldKey, - body: new CustomScrollView( - slivers: new List { - new SliverAppBar( - expandedHeight: _appBarHeight, - pinned: this._appBarBehavior == AppBarBehavior.pinned, - floating: this._appBarBehavior == AppBarBehavior.floating || - this._appBarBehavior == AppBarBehavior.snapping, - snap: this._appBarBehavior == AppBarBehavior.snapping, - actions: new List { - new IconButton( - icon: new Icon(Icons.create), - tooltip: "Edit", - onPressed: () => { - this._scaffoldKey.currentState.showSnackBar(new SnackBar( - content: new Text("Editing isn't supported in this screen.") - )); - } - ), - new PopupMenuButton( - onSelected: (AppBarBehavior value) => { - this.setState(() => { this._appBarBehavior = value; }); - }, - itemBuilder: (BuildContext _context) => new List> { - new PopupMenuItem( - value: AppBarBehavior.normal, - child: new Text("App bar scrolls away") - ), - new PopupMenuItem( - value: AppBarBehavior.pinned, - child: new Text("App bar stays put") - ), - new PopupMenuItem( - value: AppBarBehavior.floating, - child: new Text("App bar floats") - ), - new PopupMenuItem( - value: AppBarBehavior.snapping, - child: new Text("App bar snaps") - ) - } - ) - }, - flexibleSpace: new FlexibleSpaceBar( - title: new Text("Ali Connors"), - background: new Stack( - fit: StackFit.expand, - children: new List { - Image.asset( - "ali_landscape", - fit: BoxFit.cover, - height: _appBarHeight - ), - new DecoratedBox( - decoration: new BoxDecoration( - gradient: new LinearGradient( - begin: new Alignment(0.0f, -1.0f), - end: new Alignment(0.0f, -0.4f), - colors: new List - {new Color(0x60000000), new Color(0x00000000)} - ) - ) - ) - } - ) - ) - ), - new SliverList( - del: new SliverChildListDelegate(new List { - new AnnotatedRegion( - value: SystemUiOverlayStyle.dark, - child: new _ContactCategory( - icon: Icons.call, - children: new List { - new _ContactItem( - icon: Icons.message, - tooltip: "Send message", - onPressed: () => { - this._scaffoldKey.currentState.showSnackBar(new SnackBar( - content: new Text( - "Pretend that this opened your SMS application.") - )); - }, - lines: new List { - "(650) 555-1234", - "Mobile" - } - ), - new _ContactItem( - icon: Icons.message, - tooltip: "Send message", - onPressed: () => { - this._scaffoldKey.currentState.showSnackBar(new SnackBar( - content: new Text("A messaging app appears.") - )); - }, - lines: new List { - "(323) 555-6789", - "Work" - } - ), - new _ContactItem( - icon: Icons.message, - tooltip: "Send message", - onPressed: () => { - this._scaffoldKey.currentState.showSnackBar(new SnackBar( - content: new Text( - "Imagine if you will, a messaging application.") - )); - }, - lines: new List { - "(650) 555-6789", - "Home" - } - ) - } - ) - ), - new _ContactCategory( - icon: Icons.contact_mail, - children: new List { - new _ContactItem( - icon: Icons.email, - tooltip: "Send personal e-mail", - onPressed: () => { - this._scaffoldKey.currentState.showSnackBar(new SnackBar( - content: new Text("Here, your e-mail application would open.") - )); - }, - lines: new List { - "ali_connors@example.com", - "Personal" - } - ), - new _ContactItem( - icon: Icons.email, - tooltip: "Send work e-mail", - onPressed: () => { - this._scaffoldKey.currentState.showSnackBar(new SnackBar( - content: new Text( - "Summon your favorite e-mail application here.") - )); - }, - lines: new List { - "aliconnors@example.com", - "Work" - } - ) - } - ), - new _ContactCategory( - icon: Icons.location_on, - children: new List { - new _ContactItem( - icon: Icons.map, - tooltip: "Open map", - onPressed: () => { - this._scaffoldKey.currentState.showSnackBar(new SnackBar( - content: new Text("This would show a map of San Francisco.") - )); - }, - lines: new List { - "2000 Main Street", - "San Francisco, CA", - "Home" - } - ), - new _ContactItem( - icon: Icons.map, - tooltip: "Open map", - onPressed: () => { - this._scaffoldKey.currentState.showSnackBar(new SnackBar( - content: new Text("This would show a map of Mountain View.") - )); - }, - lines: new List { - "1600 Amphitheater Parkway", - "Mountain View, CA", - "Work" - } - ), - new _ContactItem( - icon: Icons.map, - tooltip: "Open map", - onPressed: () => { - this._scaffoldKey.currentState.showSnackBar(new SnackBar( - content: new Text( - "This would also show a map, if this was not a demo.") - )); - }, - lines: new List { - "126 Severyns Ave", - "Mountain View, CA", - "Jet Travel", - } - ) - } - ), - new _ContactCategory( - icon: Icons.today, - children: new List { - new _ContactItem( - lines: new List { - "Birthday", - "January 9th, 1989" - } - ), - new _ContactItem( - lines: new List { - "Wedding anniversary", - "June 21st, 2014" - } - ), - new _ContactItem( - lines: new List { - "First day in office", - "January 20th, 2015", - } - ), - new _ContactItem( - lines: new List { - "Last day in office", - "August 9th, 2018" - } - ) - } - ) - }) - ) - } - ) - ) - ); - } - } -} \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/demo/contacts_demo.cs.meta b/Samples/UIWidgetsGallery/demo/contacts_demo.cs.meta deleted file mode 100644 index a29dc915..00000000 --- a/Samples/UIWidgetsGallery/demo/contacts_demo.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 42aac0c9b12e437db9787de912355ed9 -timeCreated: 1553060178 \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/demo/material.meta b/Samples/UIWidgetsGallery/demo/material.meta deleted file mode 100644 index 739884d9..00000000 --- a/Samples/UIWidgetsGallery/demo/material.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: edc3bae86553f44c2b7e7fddbf6cb497 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetsGallery/demo/material/backdrop_demo.cs b/Samples/UIWidgetsGallery/demo/material/backdrop_demo.cs deleted file mode 100644 index edb21e26..00000000 --- a/Samples/UIWidgetsGallery/demo/material/backdrop_demo.cs +++ /dev/null @@ -1,423 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Unity.UIWidgets.animation; -using Unity.UIWidgets.foundation; -using Unity.UIWidgets.gestures; -using Unity.UIWidgets.material; -using Unity.UIWidgets.painting; -using Unity.UIWidgets.rendering; -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; -using UnityEngine; -using Image = Unity.UIWidgets.widgets.Image; -using Material = Unity.UIWidgets.material.Material; - -namespace UIWidgetsGallery.gallery { - class BackdropDemoConstants { - public static readonly List allCategories = new List { - new Category( - title: "Accessories", - assets: new List { - "products/belt", - "products/earrings", - "products/backpack", - "products/hat", - "products/scarf", - "products/sunnies" - } - ), - new Category( - title: "Blue", - assets: new List { - "products/backpack", - "products/cup", - "products/napkins", - "products/top" - } - ), - new Category( - title: "Cold Weather", - assets: new List { - "products/jacket", - "products/jumper", - "products/scarf", - "products/sweater", - "products/sweats" - } - ), - new Category( - title: "Home", - assets: new List { - "products/cup", - "products/napkins", - "products/planters", - "products/table", - "products/teaset" - } - ), - new Category( - title: "Tops", - assets: new List { - "products/jumper", - "products/shirt", - "products/sweater", - "products/top" - } - ), - new Category( - title: "Everything", - assets: new List { - "products/backpack", - "products/belt", - "products/cup", - "products/dress", - "products/earrings", - "products/flatwear", - "products/hat", - "products/jacket", - "products/jumper", - "products/napkins", - "products/planters", - "products/scarf", - "products/shirt", - "products/sunnies", - "products/sweater", - "products/sweats", - "products/table", - "products/teaset", - "products/top" - } - ), - }; - } - - public class Category { - public Category(string title = null, List assets = null) { - this.title = title; - this.assets = assets; - } - - public readonly string title; - public readonly List assets; - - public override string ToString() { - return $"{this.GetType()}('{this.title}')"; - } - } - - - public class CategoryView : StatelessWidget { - public CategoryView(Key key = null, Category category = null) : base(key: key) { - this.category = category; - } - - public readonly Category category; - - public override Widget build(BuildContext context) { - ThemeData theme = Theme.of(context); - return new ListView( - key: new PageStorageKey(this.category), - padding: EdgeInsets.symmetric( - vertical: 16.0f, - horizontal: 64.0f - ), - children: this.category.assets.Select((string asset) => { - return new Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: new List { - new Card( - child: new Container( - width: 144.0f, - alignment: Alignment.center, - child: new Column( - children: new List { - Image.asset( - asset, - fit: BoxFit.contain - ), - new Container( - padding: EdgeInsets.only(bottom: 16.0f), - alignment: Alignment.center, - child: new Text( - asset, - style: theme.textTheme.caption - ) - ), - } - ) - ) - ), - new SizedBox(height: 24.0f) - } - ); - }).ToList() - ); - } - } - - public class BackdropPanel : StatelessWidget { - public BackdropPanel( - Key key = null, - VoidCallback onTap = null, - GestureDragUpdateCallback onVerticalDragUpdate = null, - GestureDragEndCallback onVerticalDragEnd = null, - Widget title = null, - Widget child = null - ) : base(key: key) { - this.onTap = onTap; - this.onVerticalDragUpdate = onVerticalDragUpdate; - this.onVerticalDragEnd = onVerticalDragEnd; - this.title = title; - this.child = child; - } - - public readonly VoidCallback onTap; - public readonly GestureDragUpdateCallback onVerticalDragUpdate; - public readonly GestureDragEndCallback onVerticalDragEnd; - public readonly Widget title; - public readonly Widget child; - - public override Widget build(BuildContext context) { - ThemeData theme = Theme.of(context); - return new Material( - elevation: 2.0f, - borderRadius: BorderRadius.only( - topLeft: Radius.circular(16.0f), - topRight: Radius.circular(16.0f) - ), - child: new Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: new List { - new GestureDetector( - behavior: HitTestBehavior.opaque, - onVerticalDragUpdate: this.onVerticalDragUpdate, - onVerticalDragEnd: this.onVerticalDragEnd, - onTap: this.onTap != null ? (GestureTapCallback) (() => { this.onTap(); }) : null, - child: new Container( - height: 48.0f, - padding: EdgeInsets.only(left: 16.0f), - alignment: Alignment.centerLeft, - child: new DefaultTextStyle( - style: theme.textTheme.subhead, - child: new Tooltip( - message: "Tap to dismiss", - child: this.title - ) - ) - ) - ), - new Divider(height: 1.0f), - new Expanded(child: this.child) - } - ) - ); - } - } - - public class BackdropTitle : AnimatedWidget { - public BackdropTitle( - Key key = null, - Listenable listenable = null - ) : base(key: key, listenable: listenable) { - } - - protected override Widget build(BuildContext context) { - Animation animation = (Animation) this.listenable; - return new DefaultTextStyle( - style: Theme.of(context).primaryTextTheme.title, - softWrap: false, - overflow: TextOverflow.ellipsis, - child: new Stack( - children: new List { - new Opacity( - opacity: new CurvedAnimation( - parent: new ReverseAnimation(animation), - curve: new Interval(0.5f, 1.0f) - ).value, - child: new Text("Select a Category") - ), - new Opacity( - opacity: new CurvedAnimation( - parent: animation, - curve: new Interval(0.5f, 1.0f) - ).value, - child: new Text("Asset Viewer") - ), - } - ) - ); - } - } - - public class BackdropDemo : StatefulWidget { - public const string routeName = "/material/backdrop"; - - public override State createState() { - return new _BackdropDemoState(); - } - } - - class _BackdropDemoState : SingleTickerProviderStateMixin { - GlobalKey _backdropKey = GlobalKey.key(debugLabel: "Backdrop"); - AnimationController _controller; - Category _category = BackdropDemoConstants.allCategories[0]; - - public override void initState() { - base.initState(); - this._controller = new AnimationController( - duration: new TimeSpan(0, 0, 0, 0, 300), - value: 1.0f, - vsync: this - ); - } - - public override void dispose() { - this._controller.dispose(); - base.dispose(); - } - - void _changeCategory(Category category) { - this.setState(() => { - this._category = category; - this._controller.fling(velocity: 2.0f); - }); - } - - bool _backdropPanelVisible { - get { - AnimationStatus status = this._controller.status; - return status == AnimationStatus.completed || status == AnimationStatus.forward; - } - } - - void _toggleBackdropPanelVisibility() { - this._controller.fling(velocity: this._backdropPanelVisible ? -2.0f : 2.0f); - } - - float? _backdropHeight { - get { - RenderBox renderBox = (RenderBox) this._backdropKey.currentContext.findRenderObject(); - return renderBox.size.height; - } - } - - - void _handleDragUpdate(DragUpdateDetails details) { - if (this._controller.isAnimating || this._controller.status == AnimationStatus.completed) { - return; - } - - this._controller.setValue(this._controller.value - - details.primaryDelta / (this._backdropHeight ?? details.primaryDelta) ?? 0.0f); - } - - void _handleDragEnd(DragEndDetails details) { - if (this._controller.isAnimating || this._controller.status == AnimationStatus.completed) { - return; - } - - float? flingVelocity = details.velocity.pixelsPerSecond.dy / this._backdropHeight; - if (flingVelocity < 0.0f) { - this._controller.fling(velocity: Mathf.Max(2.0f, -flingVelocity ?? 0.0f)); - } - else if (flingVelocity > 0.0f) { - this._controller.fling(velocity: Mathf.Min(-2.0f, -flingVelocity ?? 0.0f)); - } - else { - this._controller.fling(velocity: this._controller.value < 0.5f ? -2.0f : 2.0f); - } - } - - Widget _buildStack(BuildContext context, BoxConstraints constraints) { - const float panelTitleHeight = 48.0f; - Size panelSize = constraints.biggest; - float panelTop = panelSize.height - panelTitleHeight; - - Animation panelAnimation = this._controller.drive( - new RelativeRectTween( - begin: RelativeRect.fromLTRB( - 0.0f, - panelTop - MediaQuery.of(context).padding.bottom, - 0.0f, - panelTop - panelSize.height - ), - end: RelativeRect.fromLTRB(0.0f, 0.0f, 0.0f, 0.0f) - ) - ); - - ThemeData theme = Theme.of(context); - List backdropItems = BackdropDemoConstants.allCategories.Select( - (Category category) => { - bool selected = category == this._category; - return new Material( - shape: new RoundedRectangleBorder( - borderRadius: BorderRadius.all(Radius.circular(4.0f)) - ), - color: selected - ? Colors.white.withOpacity(0.25f) - : Colors.transparent, - child: new ListTile( - title: new Text(category.title), - selected: selected, - onTap: () => { this._changeCategory(category); } - ) - ); - }).ToList(); - - return new Container( - key: this._backdropKey, - color: theme.primaryColor, - child: new Stack( - children: new List { - new ListTileTheme( - iconColor: theme.primaryIconTheme.color, - textColor: theme.primaryTextTheme.title.color.withOpacity(0.6f), - selectedColor: theme.primaryTextTheme.title.color, - child: new Padding( - padding: EdgeInsets.symmetric(horizontal: 16.0f), - child: new Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: backdropItems - ) - ) - ), - new PositionedTransition( - rect: panelAnimation, - child: new BackdropPanel( - onTap: this._toggleBackdropPanelVisibility, - onVerticalDragUpdate: this._handleDragUpdate, - onVerticalDragEnd: this._handleDragEnd, - title: new Text(this._category.title), - child: new CategoryView(category: this._category) - ) - ), - } - ) - ); - } - - public override Widget build(BuildContext context) { - return new Scaffold( - appBar: new AppBar( - elevation: 0.0f, - title: new BackdropTitle( - listenable: this._controller.view - ), - actions: new List { - new IconButton( - onPressed: this._toggleBackdropPanelVisibility, - icon: new AnimatedIcon( - icon: AnimatedIcons.close_menu, - progress: this._controller.view - ) - ) - } - ), - body: new LayoutBuilder( - builder: this._buildStack - ) - ); - } - } -} \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/demo/material/backdrop_demo.cs.meta b/Samples/UIWidgetsGallery/demo/material/backdrop_demo.cs.meta deleted file mode 100644 index 94a1441d..00000000 --- a/Samples/UIWidgetsGallery/demo/material/backdrop_demo.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 98bee0a7e51f4f2d9c8670daf147a15f -timeCreated: 1553145970 \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/demo/material/bottom_app_bar_demo.cs b/Samples/UIWidgetsGallery/demo/material/bottom_app_bar_demo.cs deleted file mode 100644 index b6fc5819..00000000 --- a/Samples/UIWidgetsGallery/demo/material/bottom_app_bar_demo.cs +++ /dev/null @@ -1,523 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using Unity.UIWidgets.foundation; -using Unity.UIWidgets.gestures; -using Unity.UIWidgets.material; -using Unity.UIWidgets.painting; -using Unity.UIWidgets.rendering; -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; -using UnityEngine; -using Canvas = Unity.UIWidgets.ui.Canvas; -using Color = Unity.UIWidgets.ui.Color; -using Material = Unity.UIWidgets.material.Material; -using Rect = Unity.UIWidgets.ui.Rect; - -namespace UIWidgetsGallery.gallery { - public class BottomAppBarDemo : StatefulWidget { - public const string routeName = "/material/bottom_app_bar"; - - public override State createState() { - return new _BottomAppBarDemoState(); - } - } - - - class _BottomAppBarDemoState : State { - static readonly GlobalKey _scaffoldKey = GlobalKey.key(); - - - static readonly _ChoiceValue kNoFab = new _ChoiceValue( - title: "None", - label: "do not show a floating action button", - value: null - ); - - static readonly _ChoiceValue kCircularFab = new _ChoiceValue( - title: "Circular", - label: "circular floating action button", - value: new FloatingActionButton( - onPressed: _showSnackbar, - child: new Icon(Icons.add), - backgroundColor: Colors.orange - ) - ); - - static readonly _ChoiceValue kDiamondFab = new _ChoiceValue( - title: "Diamond", - label: "diamond shape floating action button", - value: new _DiamondFab( - onPressed: _showSnackbar, - child: new Icon(Icons.add) - ) - ); - - - static readonly _ChoiceValue kShowNotchTrue = new _ChoiceValue( - title: "On", - label: "show bottom appbar notch", - value: true - ); - - static readonly _ChoiceValue kShowNotchFalse = new _ChoiceValue( - title: "Off", - label: "do not show bottom appbar notch", - value: false - ); - - - static readonly _ChoiceValue kFabEndDocked = - new _ChoiceValue( - title: "Attached - End", - label: "floating action button is docked at the end of the bottom app bar", - value: FloatingActionButtonLocation.endDocked - ); - - static readonly _ChoiceValue kFabCenterDocked = - new _ChoiceValue( - title: "Attached - Center", - label: "floating action button is docked at the center of the bottom app bar", - value: FloatingActionButtonLocation.centerDocked - ); - - static readonly _ChoiceValue kFabEndFloat = - new _ChoiceValue( - title: "Free - End", - label: "floating action button floats above the end of the bottom app bar", - value: FloatingActionButtonLocation.endFloat - ); - - static readonly _ChoiceValue kFabCenterFloat = - new _ChoiceValue( - title: "Free - Center", - label: "floating action button is floats above the center of the bottom app bar", - value: FloatingActionButtonLocation.centerFloat - ); - - static void _showSnackbar() { - const string text = - "When the Scaffold's floating action button location changes, " + - "the floating action button animates to its new position." + - "The BottomAppBar adapts its shape appropriately."; - _scaffoldKey.currentState.showSnackBar( - new SnackBar(content: new Text(text)) - ); - } - - - static readonly List<_NamedColor> kBabColors = new List<_NamedColor> { - new _NamedColor(null, "Clear"), - new _NamedColor(new Color(0xFFFFC100), "Orange"), - new _NamedColor(new Color(0xFF91FAFF), "Light Blue"), - new _NamedColor(new Color(0xFF00D1FF), "Cyan"), - new _NamedColor(new Color(0xFF00BCFF), "Cerulean"), - new _NamedColor(new Color(0xFF009BEE), "Blue") - }; - - _ChoiceValue _fabShape = kCircularFab; - _ChoiceValue _showNotch = kShowNotchTrue; - _ChoiceValue _fabLocation = kFabEndDocked; - Color _babColor = kBabColors.First().color; - - void _onShowNotchChanged(_ChoiceValue value) { - this.setState(() => { this._showNotch = value; }); - } - - void _onFabShapeChanged(_ChoiceValue value) { - this.setState(() => { this._fabShape = value; }); - } - - void _onFabLocationChanged(_ChoiceValue value) { - this.setState(() => { this._fabLocation = value; }); - } - - void _onBabColorChanged(Color value) { - this.setState(() => { this._babColor = value; }); - } - - public override Widget build(BuildContext context) { - return new Scaffold( - key: _scaffoldKey, - appBar: new AppBar( - title: new Text("Bottom app bar"), - elevation: 0.0f, - actions: new List { - new MaterialDemoDocumentationButton(BottomAppBarDemo.routeName), - new IconButton( - icon: new Icon(Icons.sentiment_very_satisfied), - onPressed: () => { - this.setState(() => { - this._fabShape = this._fabShape == kCircularFab ? kDiamondFab : kCircularFab; - }); - } - ) - } - ), - body: new ListView( - padding: EdgeInsets.only(bottom: 88.0f), - children: new List { - new _AppBarDemoHeading("FAB Shape"), - - new _RadioItem(kCircularFab, this._fabShape, this._onFabShapeChanged), - new _RadioItem(kDiamondFab, this._fabShape, this._onFabShapeChanged), - new _RadioItem(kNoFab, this._fabShape, this._onFabShapeChanged), - - new Divider(), - new _AppBarDemoHeading("Notch"), - - new _RadioItem(kShowNotchTrue, this._showNotch, this._onShowNotchChanged), - new _RadioItem(kShowNotchFalse, this._showNotch, this._onShowNotchChanged), - - new Divider(), - new _AppBarDemoHeading("FAB Position"), - - new _RadioItem(kFabEndDocked, this._fabLocation, - this._onFabLocationChanged), - new _RadioItem(kFabCenterDocked, this._fabLocation, - this._onFabLocationChanged), - new _RadioItem(kFabEndFloat, this._fabLocation, - this._onFabLocationChanged), - new _RadioItem(kFabCenterFloat, this._fabLocation, - this._onFabLocationChanged), - - new Divider(), - new _AppBarDemoHeading("App bar color"), - - new _ColorsItem(kBabColors, this._babColor, this._onBabColorChanged) - } - ), - floatingActionButton: - this._fabShape.value, - floatingActionButtonLocation: - this._fabLocation.value, - bottomNavigationBar: new _DemoBottomAppBar( - color: this._babColor, - fabLocation: this._fabLocation.value, - shape: this._selectNotch() - ) - ); - } - - NotchedShape _selectNotch() { - if (!this._showNotch.value) { - return null; - } - - if (this._fabShape == kCircularFab) { - return new CircularNotchedRectangle(); - } - - if (this._fabShape == kDiamondFab) { - return new _DiamondNotchedRectangle(); - } - - return null; - } - } - - class _ChoiceValue { - public _ChoiceValue(T value, string title, string label) { - this.value = value; - this.title = title; - this.label = label; - } - - public readonly T value; - public readonly string title; - string label; // For the Semantics widget that contains title - - public override string ToString() { - return $"{this.GetType()}('{this.title}')"; - } - } - - class _RadioItem : StatelessWidget { - public _RadioItem(_ChoiceValue value, _ChoiceValue groupValue, ValueChanged<_ChoiceValue> onChanged) { - this.value = value; - this.groupValue = groupValue; - this.onChanged = onChanged; - } - - _ChoiceValue value; - _ChoiceValue groupValue; - ValueChanged<_ChoiceValue> onChanged; - - public override Widget build(BuildContext context) { - ThemeData theme = Theme.of(context); - return new Container( - height: 56.0f, - padding: EdgeInsets.only(left: 16.0f), - alignment: Alignment.centerLeft, - child: new Row( - children: new List { - new Radio<_ChoiceValue>( - value: this.value, - groupValue: this.groupValue, - onChanged: this.onChanged - ), - new Expanded( - child: new GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: () => { this.onChanged(this.value); }, - child: new Text(this.value.title, - style: theme.textTheme.subhead - ) - ) - ) - } - ) - ); - } - } - - class _NamedColor { - public _NamedColor(Color color, string name) { - this.color = color; - this.name = name; - } - - public readonly Color color; - public readonly string name; - } - - class _ColorsItem : StatelessWidget { - public _ColorsItem(List<_NamedColor> colors, Color selectedColor, ValueChanged onChanged) { - this.colors = colors; - this.selectedColor = selectedColor; - this.onChanged = onChanged; - } - - List<_NamedColor> colors; - public readonly Color selectedColor; - ValueChanged onChanged; - - public override Widget build(BuildContext context) { - return new Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: this.colors.Select<_NamedColor, Widget>((_NamedColor namedColor) => { - return new RawMaterialButton( - onPressed: () => { this.onChanged(namedColor.color); }, - constraints: BoxConstraints.tightFor( - width: 32.0f, - height: 32.0f - ), - fillColor: namedColor.color, - shape: new CircleBorder( - side: new BorderSide( - color: namedColor.color == this.selectedColor ? Colors.black : new Color(0xFFD5D7DA), - width: 2.0f - ) - ) - ); - }).ToList() - ); - } - } - - class _AppBarDemoHeading : StatelessWidget { - public _AppBarDemoHeading(string text) { - this.text = text; - } - - public readonly string text; - - public override Widget build(BuildContext context) { - ThemeData theme = Theme.of(context); - return new Container( - height: 48.0f, - padding: EdgeInsets.only(left: 56.0f), - alignment: Alignment.centerLeft, - child: new Text(this.text, - style: theme.textTheme.body1.copyWith( - color: theme.primaryColor - ) - ) - ); - } - } - - class _DemoBottomAppBar : StatelessWidget { - public _DemoBottomAppBar( - Color color = null, - FloatingActionButtonLocation fabLocation = null, - NotchedShape shape = null - ) { - this.color = color; - this.fabLocation = fabLocation; - this.shape = shape; - } - - public readonly Color color; - public readonly FloatingActionButtonLocation fabLocation; - public readonly NotchedShape shape; - - static readonly List kCenterLocations = new List { - FloatingActionButtonLocation.centerDocked, - FloatingActionButtonLocation.centerFloat - }; - - public override Widget build(BuildContext context) { - List rowContents = new List { - new IconButton( - icon: new Icon(Icons.menu), - onPressed: () => { - BottomSheetUtils.showModalBottomSheet( - context: context, - builder: (BuildContext _context) => new _DemoDrawer() - ); - } - ) - }; - - if (kCenterLocations.Contains(this.fabLocation)) { - rowContents.Add( - new Expanded(child: new SizedBox()) - ); - } - - rowContents.AddRange(new List { - new IconButton( - icon: new Icon(Icons.search), - onPressed: () => { - Scaffold.of(context).showSnackBar( - new SnackBar(content: new Text("This is a dummy search action.")) - ); - } - ), - new IconButton( - icon: new Icon( - Theme.of(context).platform == RuntimePlatform.Android - ? Icons.more_vert - : Icons.more_horiz - ), - onPressed: () => { - Scaffold.of(context).showSnackBar( - new SnackBar(content: new Text("This is a dummy menu action.")) - ); - } - ) - }); - - return new BottomAppBar( - color: this.color, - child: new Row(children: rowContents), - shape: this.shape - ); - } - } - - class _DemoDrawer : StatelessWidget { - public _DemoDrawer() { - } - - public override Widget build(BuildContext context) { - return new Drawer( - child: new Column( - children: new List { - new ListTile( - leading: new Icon(Icons.search), - title: new Text("Search") - ), - new ListTile( - leading: new Icon(Icons.threed_rotation), - title: new Text("3D") - ) - } - ) - ); - } - } - - class _DiamondFab : StatelessWidget { - public _DiamondFab( - Widget child, - VoidCallback onPressed - ) { - this.child = child; - this.onPressed = onPressed; - } - - public readonly Widget child; - public readonly VoidCallback onPressed; - - public override Widget build(BuildContext context) { - return new Material( - shape: new _DiamondBorder(), - color: Colors.orange, - child: new InkWell( - onTap: this.onPressed == null ? (GestureTapCallback) null : () => { this.onPressed(); }, - child: new Container( - width: 56.0f, - height: 56.0f, - child: IconTheme.merge( - data: new IconThemeData(color: Theme.of(context).accentIconTheme.color), - child: this.child - ) - ) - ), - elevation: 6.0f - ); - } - } - - class _DiamondNotchedRectangle : NotchedShape { - public _DiamondNotchedRectangle() { - } - - public override Path getOuterPath(Rect host, Rect guest) { - if (guest == null || !host.overlaps(guest)) { - Path path = new Path(); - path.addRect(host); - return path; - } - - D.assert(guest.width > 0.0f); - - Rect intersection = guest.intersect(host); - float notchToCenter = - intersection.height * (guest.height / 2.0f) - / (guest.width / 2.0f); - - Path ret = new Path(); - ret.moveTo(host.left, host.top); - ret.lineTo(guest.center.dx - notchToCenter, host.top); - ret.lineTo(guest.left + guest.width / 2.0f, guest.bottom); - ret.lineTo(guest.center.dx + notchToCenter, host.top); - ret.lineTo(host.right, host.top); - ret.lineTo(host.right, host.bottom); - ret.lineTo(host.left, host.bottom); - ret.close(); - return ret; - } - } - - class _DiamondBorder : ShapeBorder { - public _DiamondBorder() { - } - - public override EdgeInsets dimensions { - get { return EdgeInsets.only(); } - } - - public override Path getInnerPath(Rect rect) { - return this.getOuterPath(rect); - } - - public override Path getOuterPath(Rect rect) { - Path path = new Path(); - path.moveTo(rect.left + rect.width / 2.0f, rect.top); - path.lineTo(rect.right, rect.top + rect.height / 2.0f); - path.lineTo(rect.left + rect.width / 2.0f, rect.bottom); - path.lineTo(rect.left, rect.top + rect.height / 2.0f); - path.close(); - return path; - } - - public override void paint(Canvas canvas, Rect rect) { - } - - public override ShapeBorder scale(float t) { - return null; - } - } -} \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/demo/material/bottom_app_bar_demo.cs.meta b/Samples/UIWidgetsGallery/demo/material/bottom_app_bar_demo.cs.meta deleted file mode 100644 index 3eaa1125..00000000 --- a/Samples/UIWidgetsGallery/demo/material/bottom_app_bar_demo.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 7c1d20efeafe42699212e2147c0828af -timeCreated: 1553149093 \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/demo/material/bottom_navigation_demo.cs b/Samples/UIWidgetsGallery/demo/material/bottom_navigation_demo.cs deleted file mode 100644 index 6193137b..00000000 --- a/Samples/UIWidgetsGallery/demo/material/bottom_navigation_demo.cs +++ /dev/null @@ -1,228 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using Unity.UIWidgets.animation; -using Unity.UIWidgets.material; -using Unity.UIWidgets.painting; -using Unity.UIWidgets.scheduler; -using Unity.UIWidgets.service; -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; - -namespace UIWidgetsGallery.gallery { - public class NavigationIconView { - public NavigationIconView( - Widget icon = null, - Widget activeIcon = null, - string title = null, - Color color = null, - TickerProvider vsync = null - ) { - this._icon = icon; - this._color = color; - this._title = title; - this.item = new BottomNavigationBarItem( - icon: icon, - activeIcon: activeIcon, - title: new Text(title), - backgroundColor: color - ); - this.controller = new AnimationController( - duration: ThemeUtils.kThemeAnimationDuration, - vsync: vsync - ); - this._animation = this.controller.drive(new CurveTween( - curve: new Interval(0.5f, 1.0f, curve: Curves.fastOutSlowIn) - )); - } - - readonly Widget _icon; - readonly Color _color; - readonly string _title; - public readonly BottomNavigationBarItem item; - public readonly AnimationController controller; - Animation _animation; - - public FadeTransition transition(BottomNavigationBarType type, BuildContext context) { - Color iconColor; - if (type == BottomNavigationBarType.shifting) { - iconColor = this._color; - } - else { - ThemeData themeData = Theme.of(context); - iconColor = themeData.brightness == Brightness.light - ? themeData.primaryColor - : themeData.accentColor; - } - - return new FadeTransition( - opacity: this._animation, - child: new SlideTransition( - position: this._animation.drive( - new OffsetTween( - begin: new Offset(0.0f, 0.02f), // Slightly down. - end: Offset.zero - ) - ), - child: new IconTheme( - data: new IconThemeData( - color: iconColor, - size: 120.0f - ), - child: this._icon - ) - ) - ); - } - } - - public class CustomIcon : StatelessWidget { - public override Widget build(BuildContext context) { - IconThemeData iconTheme = IconTheme.of(context); - return new Container( - margin: EdgeInsets.all(4.0f), - width: iconTheme.size - 8.0f, - height: iconTheme.size - 8.0f, - color: iconTheme.color - ); - } - } - - public class CustomInactiveIcon : StatelessWidget { - public override Widget build(BuildContext context) { - IconThemeData iconTheme = IconTheme.of(context); - return new Container( - margin: EdgeInsets.all(4.0f), - width: iconTheme.size - 8.0f, - height: iconTheme.size - 8.0f, - decoration: new BoxDecoration( - border: Border.all(color: iconTheme.color, width: 2.0f) - ) - ); - } - } - - public class BottomNavigationDemo : StatefulWidget { - public const string routeName = "/material/bottom_navigation"; - - public override State createState() { - return new _BottomNavigationDemoState(); - } - } - - class _BottomNavigationDemoState : TickerProviderStateMixin { - int _currentIndex = 0; - BottomNavigationBarType _type = BottomNavigationBarType.shifting; - List _navigationViews; - - public override void initState() { - base.initState(); - this._navigationViews = new List { - new NavigationIconView( - icon: new Icon(Icons.access_alarm), - title: "Alarm", - color: Colors.deepPurple, - vsync: this - ), - new NavigationIconView( - activeIcon: new CustomIcon(), - icon: new CustomInactiveIcon(), - title: "Box", - color: Colors.deepOrange, - vsync: this - ), - new NavigationIconView( - activeIcon: new Icon(Icons.cloud), - icon: new Icon(Icons.cloud_queue), - title: "Cloud", - color: Colors.teal, - vsync: this - ), - new NavigationIconView( - activeIcon: new Icon(Icons.favorite), - icon: new Icon(Icons.favorite_border), - title: "Favorites", - color: Colors.indigo, - vsync: this - ), - new NavigationIconView( - icon: new Icon(Icons.event_available), - title: "Event", - color: Colors.pink, - vsync: this - ) - }; - - this._navigationViews[this._currentIndex].controller.setValue(1.0f); - } - - public override void dispose() { - foreach (NavigationIconView view in this._navigationViews) { - view.controller.dispose(); - } - - base.dispose(); - } - - Widget _buildTransitionsStack() { - List transitions = new List { }; - - foreach (NavigationIconView view in this._navigationViews) { - transitions.Add(view.transition(this._type, this.context)); - } - - transitions.Sort((FadeTransition a, FadeTransition b) => { - Animation aAnimation = a.opacity; - Animation bAnimation = b.opacity; - float aValue = aAnimation.value; - float bValue = bAnimation.value; - return aValue.CompareTo(bValue); - }); - - return new Stack(children: transitions.Select(w => w).ToList()); - } - - public override Widget build(BuildContext context) { - BottomNavigationBar botNavBar = new BottomNavigationBar( - items: this._navigationViews.Select((NavigationIconView navigationView) => navigationView.item) - .ToList(), - currentIndex: this._currentIndex, - type: this._type, - onTap: (int index) => { - this.setState(() => { - this._navigationViews[this._currentIndex].controller.reverse(); - this._currentIndex = index; - this._navigationViews[this._currentIndex].controller.forward(); - }); - } - ); - - return new Scaffold( - appBar: new AppBar( - title: new Text("Bottom navigation"), - actions: new List { - new MaterialDemoDocumentationButton(BottomNavigationDemo.routeName), - new PopupMenuButton( - onSelected: (BottomNavigationBarType value) => { - this.setState(() => { this._type = value; }); - }, - itemBuilder: (BuildContext _context) => new List> { - new PopupMenuItem( - value: BottomNavigationBarType.fix, - child: new Text("Fixed") - ), - new PopupMenuItem( - value: BottomNavigationBarType.shifting, - child: new Text("Shifting") - ) - } - ) - } - ), - body: new Center( - child: this._buildTransitionsStack() - ), - bottomNavigationBar: botNavBar - ); - } - } -} \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/demo/material/bottom_navigation_demo.cs.meta b/Samples/UIWidgetsGallery/demo/material/bottom_navigation_demo.cs.meta deleted file mode 100644 index ec110510..00000000 --- a/Samples/UIWidgetsGallery/demo/material/bottom_navigation_demo.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: d279028b09c04c2b8ab3fba122868004 -timeCreated: 1553221768 \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/demo/material/buttons_demo.cs b/Samples/UIWidgetsGallery/demo/material/buttons_demo.cs deleted file mode 100644 index b26991a2..00000000 --- a/Samples/UIWidgetsGallery/demo/material/buttons_demo.cs +++ /dev/null @@ -1,382 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using Unity.UIWidgets.foundation; -using Unity.UIWidgets.material; -using Unity.UIWidgets.painting; -using Unity.UIWidgets.rendering; -using Unity.UIWidgets.widgets; - -namespace UIWidgetsGallery.gallery { - class ButtonsDemo : StatefulWidget { - public const string routeName = "/material/buttons"; - - public ButtonsDemo(Key key = null) : base(key: key) { - } - - public override State createState() { - return new _ButtonsDemoState(); - } - } - - class _ButtonsDemoState : State { - const string _raisedText = - "Raised buttons add dimension to mostly flat layouts. They emphasize " + - "functions on busy or wide spaces."; - - const string _raisedCode = "buttons_raised"; - - const string _flatText = "A flat button displays an ink splash on press " + - "but does not lift. Use flat buttons on toolbars, in dialogs and " + - "inline with padding"; - - const string _flatCode = "buttons_flat"; - - const string _outlineText = - "Outline buttons become opaque and elevate when pressed. They are often " + - "paired with raised buttons to indicate an alternative, secondary action."; - - const string _outlineCode = "buttons_outline"; - - const string _dropdownText = - "A dropdown button displays a menu that's used to select a value from a " + - "small set of values. The button displays the current value and a down " + - "arrow."; - - const string _dropdownCode = "buttons_dropdown"; - - const string _iconText = - "IconButtons are appropriate for toggle buttons that allow a single choice " + - "to be selected or deselected, such as adding or removing an item's star."; - - const string _iconCode = "buttons_icon"; - - const string _actionText = - "Floating action buttons are used for a promoted action. They are " + - "distinguished by a circled icon floating above the UI and can have motion " + - "behaviors that include morphing, launching, and a transferring anchor " + - "point."; - - const string _actionCode = "buttons_action"; - - ShapeBorder _buttonShape; - - public _ButtonsDemoState() { - } - - public override Widget build(BuildContext context) { - ButtonThemeData buttonTheme = ButtonTheme.of(context).copyWith( - shape: this._buttonShape - ); - - List demos = new List { - new ComponentDemoTabData( - tabName: "RAISED", - description: _raisedText, - demoWidget: ButtonTheme.fromButtonThemeData( - data: buttonTheme, - child: this.buildRaisedButton() - ), - exampleCodeTag: _raisedCode, - documentationUrl: "https://docs.flutter.io/flutter/material/RaisedButton-class.html" - ), - new ComponentDemoTabData( - tabName: "FLAT", - description: _flatText, - demoWidget: ButtonTheme.fromButtonThemeData( - data: buttonTheme, - child: this.buildFlatButton() - ), - exampleCodeTag: _flatCode, - documentationUrl: "https://docs.flutter.io/flutter/material/FlatButton-class.html" - ), - new ComponentDemoTabData( - tabName: "OUTLINE", - description: _outlineText, - demoWidget: ButtonTheme.fromButtonThemeData( - data: buttonTheme, - child: this.buildOutlineButton() - ), - exampleCodeTag: _outlineCode, - documentationUrl: "https://docs.flutter.io/flutter/material/OutlineButton-class.html" - ), - new ComponentDemoTabData( - tabName: "DROPDOWN", - description: _dropdownText, - demoWidget: this.buildDropdownButton(), - exampleCodeTag: _dropdownCode, - documentationUrl: "https://docs.flutter.io/flutter/material/DropdownButton-class.html" - ), - new ComponentDemoTabData( - tabName: "ICON", - description: _iconText, - demoWidget: this.buildIconButton(), - exampleCodeTag: _iconCode, - documentationUrl: "https://docs.flutter.io/flutter/material/IconButton-class.html" - ), - new ComponentDemoTabData( - tabName: "ACTION", - description: _actionText, - demoWidget: this.buildActionButton(), - exampleCodeTag: _actionCode, - documentationUrl: "https://docs.flutter.io/flutter/material/FloatingActionButton-class.html" - ) - }; - - return new TabbedComponentDemoScaffold( - title: "Buttons", - demos: demos, - actions: new List { - new IconButton( - icon: new Icon(Icons.sentiment_very_satisfied), - onPressed: () => { - this.setState(() => { - this._buttonShape = this._buttonShape == null ? new StadiumBorder() : null; - }); - } - ) - } - ); - } - - public Widget buildRaisedButton() { - return new Align( - alignment: new Alignment(0.0f, -0.2f), - child: new Column( - mainAxisSize: MainAxisSize.min, - children: new List { - new ButtonBar( - mainAxisSize: MainAxisSize.min, - children: new List { - new RaisedButton( - child: new Text("RAISED BUTTON"), - onPressed: () => { - // Perform some action - } - ), - new RaisedButton( - child: new Text("DISABLED"), - onPressed: null - ) - } - ), - new ButtonBar( - mainAxisSize: MainAxisSize.min, - children: new List { - RaisedButton.icon( - icon: new Icon(Icons.add, size: 18.0f), - label: new Text("RAISED BUTTON"), - onPressed: () => { - // Perform some action - } - ), - RaisedButton.icon( - icon: new Icon(Icons.add, size: 18.0f), - label: new Text("DISABLED"), - onPressed: null - ) - } - ) - } - ) - ); - } - - public Widget buildFlatButton() { - return new Align( - alignment: new Alignment(0.0f, -0.2f), - child: new Column( - mainAxisSize: MainAxisSize.min, - children: new List { - new ButtonBar( - mainAxisSize: MainAxisSize.min, - children: new List { - new FlatButton( - child: new Text("FLAT BUTTON"), - onPressed: () => { - // Perform some action - } - ), - new FlatButton( - child: new Text("DISABLED"), - onPressed: null - ) - } - ), - new ButtonBar( - mainAxisSize: MainAxisSize.min, - children: new List { - FlatButton.icon( - icon: new Icon(Icons.add_circle_outline, size: 18.0f), - label: new Text("FLAT BUTTON"), - onPressed: () => { - // Perform some action - } - ), - FlatButton.icon( - icon: new Icon(Icons.add_circle_outline, size: 18.0f), - label: new Text("DISABLED"), - onPressed: null - ), - } - ) - } - ) - ); - } - - Widget buildOutlineButton() { - return new Align( - alignment: new Alignment(0.0f, -0.2f), - child: new Column( - mainAxisSize: MainAxisSize.min, - children: new List { - new ButtonBar( - mainAxisSize: MainAxisSize.min, - children: new List { - new OutlineButton( - child: new Text("OUTLINE BUTTON"), - onPressed: () => { - // Perform some action - } - ), - - new OutlineButton( - child: new Text("DISABLED"), - onPressed: null - ) - } - ), - new ButtonBar( - mainAxisSize: MainAxisSize.min, - children: new List { - OutlineButton.icon( - icon: new Icon(Icons.add, size: 18.0f), - label: new Text("OUTLINE BUTTON"), - onPressed: () => { - // Perform some action - } - ), - OutlineButton.icon( - icon: new Icon(Icons.add, size: 18.0f), - label: new Text("DISABLED"), - onPressed: null - ) - } - ) - } - ) - ); - } - - // https://en.wikipedia.org/wiki/Free_Four - string dropdown1Value = "Free"; - string dropdown2Value; - string dropdown3Value = "Four"; - - public Widget buildDropdownButton() { - return new Padding( - padding: EdgeInsets.all(24.0f), - child: new Column( - mainAxisAlignment: MainAxisAlignment.start, - children: new List { - new ListTile( - title: new Text("Simple dropdown:"), - trailing: new DropdownButton( - value: this.dropdown1Value, - onChanged: (string newValue) => { - this.setState(() => { this.dropdown1Value = newValue; }); - }, - items: new List {"One", "Two", "Free", "Four"}.Select((string value) => { - return new DropdownMenuItem( - value: value, - child: new Text(value) - ); - }).ToList() - ) - ), - new SizedBox( - height: 24.0f - ), - new ListTile( - title: new Text("Dropdown with a hint:"), - trailing: new DropdownButton( - value: this.dropdown2Value, - hint: new Text("Choose"), - onChanged: (string newValue) => { - this.setState(() => { this.dropdown2Value = newValue; }); - }, - items: new List {"One", "Two", "Free", "Four"}.Select((string value) => { - return new DropdownMenuItem( - value: value, - child: new Text(value) - ); - }).ToList() - ) - ), - new SizedBox( - height: 24.0f - ), - new ListTile( - title: new Text("Scrollable dropdown:"), - trailing: new DropdownButton( - value: this.dropdown3Value, - onChanged: (string newValue) => { - this.setState(() => { this.dropdown3Value = newValue; }); - }, - items: new List { - "One", "Two", "Free", "Four", "Can", "I", "Have", "A", "Little", - "Bit", "More", "Five", "Six", "Seven", "Eight", "Nine", "Ten" - }.Select>(value => { - return new DropdownMenuItem( - value: value, - child: new Text(value) - ); - }).ToList() - ) - ) - } - ) - ); - } - - bool iconButtonToggle = false; - - public Widget buildIconButton() { - return new Align( - alignment: new Alignment(0.0f, -0.2f), - child: new Row( - mainAxisSize: MainAxisSize.min, - children: new List { - new IconButton( - icon: new Icon( - Icons.thumb_up - ), - onPressed: () => { this.setState(() => this.iconButtonToggle = !this.iconButtonToggle); }, - color: this.iconButtonToggle ? Theme.of(this.context).primaryColor : null - ), - new IconButton( - icon: new Icon( - Icons.thumb_up - ), - onPressed: null - ) - }.Select( - (Widget button) => new SizedBox(width: 64.0f, height: 64.0f, child: button)).ToList() - ) - ); - } - - public Widget buildActionButton() { - return new Align( - alignment: new Alignment(0.0f, -0.2f), - child: new FloatingActionButton( - child: new Icon(Icons.add), - onPressed: () => { - // Perform some action - }, - tooltip: "floating action button" - ) - ); - } - } -} \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/demo/material/buttons_demo.cs.meta b/Samples/UIWidgetsGallery/demo/material/buttons_demo.cs.meta deleted file mode 100644 index 8934bcca..00000000 --- a/Samples/UIWidgetsGallery/demo/material/buttons_demo.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: bf7a009b9ad594f1887c1178cd01160b -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetsGallery/demo/material/cards_demo.cs b/Samples/UIWidgetsGallery/demo/material/cards_demo.cs deleted file mode 100644 index 8e4b7fbc..00000000 --- a/Samples/UIWidgetsGallery/demo/material/cards_demo.cs +++ /dev/null @@ -1,217 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using Unity.UIWidgets.foundation; -using Unity.UIWidgets.material; -using Unity.UIWidgets.painting; -using Unity.UIWidgets.rendering; -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; -using Image = Unity.UIWidgets.widgets.Image; -using TextStyle = Unity.UIWidgets.painting.TextStyle; - -namespace UIWidgetsGallery.gallery { - class CardsDemoConstants { - public static readonly List destinations = new List { - new TravelDestination( - assetName: "india_thanjavur_market", - title: "Top 10 Cities to Visit in Tamil Nadu", - description: new List { - "Number 10", - "Thanjavur", - "Thanjavur, Tamil Nadu" - } - ), - new TravelDestination( - assetName: "india_chettinad_silk_maker", - title: "Artisans of Southern India", - description: new List { - "Silk Spinners", - "Chettinad", - "Sivaganga, Tamil Nadu" - } - ) - }; - } - - public class TravelDestination { - public TravelDestination( - string assetName = null, - string title = null, - List description = null - ) { - this.assetName = assetName; - this.title = title; - this.description = description; - } - - public readonly string assetName; - public readonly string title; - public readonly List description; - - public bool isValid { - get { return this.assetName != null && this.title != null && this.description?.Count == 3; } - } - } - - - public class TravelDestinationItem : StatelessWidget { - public TravelDestinationItem(Key key = null, TravelDestination destination = null, ShapeBorder shape = null) - : base(key: key) { - D.assert(destination != null && destination.isValid); - this.destination = destination; - this.shape = shape; - } - - public const float height = 366.0f; - public readonly TravelDestination destination; - public readonly ShapeBorder shape; - - public override Widget build(BuildContext context) { - ThemeData theme = Theme.of(context); - TextStyle titleStyle = theme.textTheme.headline.copyWith(color: Colors.white); - TextStyle descriptionStyle = theme.textTheme.subhead; - - return new SafeArea( - top: false, - bottom: false, - child: new Container( - padding: EdgeInsets.all(8.0f), - height: height, - child: new Card( - shape: this.shape, - child: new Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: new List { - new SizedBox( - height: 184.0f, - child: new Stack( - children: new List { - Positioned.fill( - child: Image.asset(this.destination.assetName, - fit: BoxFit.cover - ) - ), - new Positioned( - bottom: 16.0f, - left: 16.0f, - right: 16.0f, - child: new FittedBox( - fit: BoxFit.scaleDown, - alignment: Alignment.centerLeft, - child: new Text(this.destination.title, - style: titleStyle - ) - ) - ) - } - ) - ), - new Expanded( - child: new Padding( - padding: EdgeInsets.fromLTRB(16.0f, 16.0f, 16.0f, 0.0f), - child: new DefaultTextStyle( - softWrap: false, - overflow: TextOverflow.ellipsis, - style: descriptionStyle, - child: new Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: new List { - new Padding( - padding: EdgeInsets.only(bottom: 8.0f), - child: new Text(this.destination.description[0], - style: descriptionStyle.copyWith(color: Colors.black54) - ) - ), - new Text(this.destination.description[1]), - new Text(this.destination.description[2]) - } - ) - ) - ) - ), - ButtonTheme.bar( - child: new ButtonBar( - alignment: MainAxisAlignment.start, - children: new List { - new FlatButton( - child: new Text("SHARE"), - textColor: Colors.amber.shade500, - onPressed: () => { - /* do nothing */ - } - ), - new FlatButton( - child: new Text("EXPLORE"), - textColor: Colors.amber.shade500, - onPressed: () => { - /* do nothing */ - } - ) - } - ) - ), - } - ) - ) - ) - ); - } - } - - - public class CardsDemo : StatefulWidget { - public const string routeName = "/material/cards"; - - public override State createState() { - return new _CardsDemoState(); - } - } - - class _CardsDemoState : State { - ShapeBorder _shape; - - public override Widget build(BuildContext context) { - return new Scaffold( - appBar: new AppBar( - title: new Text("Travel stream"), - actions: new List { - new MaterialDemoDocumentationButton(CardsDemo.routeName), - new IconButton( - icon: new Icon( - Icons.sentiment_very_satisfied - ), - onPressed: () => { - this.setState(() => { - this._shape = this._shape != null - ? null - : new RoundedRectangleBorder( - borderRadius: BorderRadius.only( - topLeft: Radius.circular(16.0f), - topRight: Radius.circular(16.0f), - bottomLeft: Radius.circular(2.0f), - bottomRight: Radius.circular(2.0f) - ) - ); - }); - } - ) - } - ), - body: new ListView( - itemExtent: TravelDestinationItem.height, - padding: EdgeInsets.only(top: 8.0f, left: 8.0f, right: 8.0f), - children: CardsDemoConstants.destinations.Select( - (TravelDestination destination) => { - return new Container( - margin: EdgeInsets.only(bottom: 8.0f), - child: new TravelDestinationItem( - destination: destination, - shape: this._shape - ) - ); - }).ToList() - ) - ); - } - } -} \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/demo/material/cards_demo.cs.meta b/Samples/UIWidgetsGallery/demo/material/cards_demo.cs.meta deleted file mode 100644 index a599eef9..00000000 --- a/Samples/UIWidgetsGallery/demo/material/cards_demo.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: f199ea32d87544c892f57b8af0fcbb03 -timeCreated: 1553136548 \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/demo/material/chip_demo.cs b/Samples/UIWidgetsGallery/demo/material/chip_demo.cs deleted file mode 100644 index a5f50143..00000000 --- a/Samples/UIWidgetsGallery/demo/material/chip_demo.cs +++ /dev/null @@ -1,322 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using Unity.UIWidgets.foundation; -using Unity.UIWidgets.material; -using Unity.UIWidgets.painting; -using Unity.UIWidgets.rendering; -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; - -namespace UIWidgetsGallery.gallery { - class ChipDemoUtils { - public static readonly List _defaultMaterials = new List { - "poker", - "tortilla", - "fish and", - "micro", - "wood" - }; - - public static readonly List _defaultActions = new List { - "flake", - "cut", - "fragment", - "splinter", - "nick", - "fry", - "solder", - "cash in", - "eat" - }; - - public static readonly Dictionary _results = new Dictionary { - {"flake", "flaking"}, - {"cut", "cutting"}, - {"fragment", "fragmenting"}, - {"splinter", "splintering"}, - {"nick", "nicking"}, - {"fry", "frying"}, - {"solder", "soldering"}, - {"cash in", "cashing in"}, - {"eat", "eating"} - }; - - public static readonly List _defaultTools = new List { - "hammer", - "chisel", - "fryer", - "fabricator", - "customer" - }; - - public static readonly Dictionary _avatars = new Dictionary { - {"hammer", "people/square/ali"}, - {"chisel", "people/square/sandra"}, - {"fryer", "people/square/trevor"}, - {"fabricator", "people/square/stella"}, - {"customer", "people/square/peter"} - }; - - public static readonly Dictionary> _toolActions = - new Dictionary> { - {"hammer", new HashSet(new List {"flake", "fragment", "splinter"})}, - {"chisel", new HashSet(new List {"flake", "nick", "splinter"})}, - {"fryer", new HashSet(new List {"fry"})}, - {"fabricator", new HashSet(new List {"solder"})}, - {"customer", new HashSet(new List {"cash in", "eat"})} - }; - - public static readonly Dictionary> _materialActions = - new Dictionary> { - {"poker", new HashSet(new List {"cash in"})}, - {"tortilla", new HashSet(new List {"fry", "eat"})}, - {"fish and", new HashSet(new List {"fry", "eat"})}, - {"micro", new HashSet(new List {"solder", "fragment"})}, - {"wood", new HashSet(new List {"flake", "cut", "splinter", "nick"})} - }; - } - - - class _ChipsTile : StatelessWidget { - public _ChipsTile( - Key key = null, - string label = null, - List children = null - ) : base(key: key) { - this.label = label; - this.children = children; - } - - public readonly string label; - public readonly List children; - - public override Widget build(BuildContext context) { - List cardChildren = new List { - new Container( - padding: EdgeInsets.only(top: 16.0f, bottom: 4.0f), - alignment: Alignment.center, - child: new Text(this.label, textAlign: TextAlign.left) - ) - }; - if (this.children.isNotEmpty()) { - cardChildren.Add(new Wrap( - children: this.children.Select((Widget chip) => { - return new Padding( - padding: EdgeInsets.all(2.0f), - child: chip - ); - }).ToList())); - } - else { - TextStyle textStyle = Theme.of(context).textTheme.caption.copyWith(fontStyle: FontStyle.italic); - cardChildren.Add( - new Container( - alignment: Alignment.center, - constraints: new BoxConstraints(minWidth: 48.0f, minHeight: 48.0f), - padding: EdgeInsets.all(8.0f), - child: new Text("None", style: textStyle) - ) - ); - } - - return new Card( - child: new Column( - mainAxisSize: MainAxisSize.min, - children: cardChildren - ) - ); - } - } - - public class ChipDemo : StatefulWidget { - public const string routeName = "/material/chip"; - - public override State createState() { - return new _ChipDemoState(); - } - } - - class _ChipDemoState : State { - public _ChipDemoState() { - this._reset(); - } - - HashSet _materials = new HashSet(new List { }); - string _selectedMaterial = ""; - string _selectedAction = ""; - HashSet _tools = new HashSet(new List { }); - HashSet _selectedTools = new HashSet(new List { }); - HashSet _actions = new HashSet(new List { }); - bool _showShapeBorder = false; - - void _reset() { - this._materials.Clear(); - this._materials.UnionWith(ChipDemoUtils._defaultMaterials); - this._actions.Clear(); - this._actions.UnionWith(ChipDemoUtils._defaultActions); - this._tools.Clear(); - this._tools.UnionWith(ChipDemoUtils._defaultTools); - this._selectedMaterial = ""; - this._selectedAction = ""; - this._selectedTools.Clear(); - } - - void _removeMaterial(string name) { - this._materials.Remove(name); - if (this._selectedMaterial == name) { - this._selectedMaterial = ""; - } - } - - void _removeTool(string name) { - this._tools.Remove(name); - this._selectedTools.Remove(name); - } - - string _capitalize(string name) { - D.assert(name != null && name.isNotEmpty()); - return name.Substring(0, 1).ToUpper() + name.Substring(1); - } - - Color _nameToColor(string name) { - D.assert(name.Length > 1); - int hash = name.GetHashCode() & 0xffff; - float hue = (360.0f * hash / (1 << 15)) % 360.0f; - return HSVColor.fromAHSV(1.0f, hue, 0.4f, 0.90f).toColor(); - } - - AssetImage _nameToAvatar(string name) { - D.assert(ChipDemoUtils._avatars.ContainsKey(name)); - return new AssetImage( - ChipDemoUtils._avatars[name] - ); - } - - string _createResult() { - if (this._selectedAction.isEmpty()) { - return ""; - } - - return this._capitalize(ChipDemoUtils._results[this._selectedAction]) + "!"; - } - - public override Widget build(BuildContext context) { - List chips = this._materials.Select((string name) => { - return new Chip( - key: Key.key(name), - backgroundColor: this._nameToColor(name), - label: new Text(this._capitalize(name)), - onDeleted: () => { this.setState(() => { this._removeMaterial(name); }); } - ); - }).ToList(); - - List inputChips = this._tools.Select((string name) => { - return new InputChip( - key: ValueKey.key(name), - avatar: new CircleAvatar( - backgroundImage: this._nameToAvatar(name) - ), - label: new Text(this._capitalize(name)), - onDeleted: () => { this.setState(() => { this._removeTool(name); }); }); - }).ToList(); - - List choiceChips = this._materials.Select((string name) => { - return new ChoiceChip( - key: ValueKey.key(name), - backgroundColor: this._nameToColor(name), - label: new Text(this._capitalize(name)), - selected: this._selectedMaterial == name, - onSelected: (bool value) => { - this.setState(() => { this._selectedMaterial = value ? name : ""; }); - } - ); - }).ToList(); - - List filterChips = ChipDemoUtils._defaultTools.Select((string name) => { - return new FilterChip( - key: ValueKey.key(name), - label: new Text(this._capitalize(name)), - selected: this._tools.Contains(name) ? this._selectedTools.Contains(name) : false, - onSelected: !this._tools.Contains(name) - ? (ValueChanged) null - : (bool value) => { - this.setState(() => { - if (!value) { - this._selectedTools.Remove(name); - } - else { - this._selectedTools.Add(name); - } - }); - } - ); - }).ToList(); - - HashSet allowedActions = new HashSet(new List { }); - if (this._selectedMaterial != null && this._selectedMaterial.isNotEmpty()) { - foreach (string tool in this._selectedTools) { - allowedActions.UnionWith(ChipDemoUtils._toolActions[tool]); - } - - allowedActions = - new HashSet( - allowedActions.Intersect(ChipDemoUtils._materialActions[this._selectedMaterial])); - } - - List actionChips = allowedActions.Select((string name) => { - return new ActionChip( - label: new Text(this._capitalize(name)), - onPressed: () => { this.setState(() => { this._selectedAction = name; }); } - ); - }).ToList(); - - ThemeData theme = Theme.of(context); - List tiles = new List { - new SizedBox(height: 8.0f, width: 0.0f), - new _ChipsTile(label: "Available Materials (Chip)", children: chips), - new _ChipsTile(label: "Available Tools (InputChip)", children: inputChips), - new _ChipsTile(label: "Choose a Material (ChoiceChip)", children: choiceChips), - new _ChipsTile(label: "Choose Tools (FilterChip)", children: filterChips), - new _ChipsTile(label: "Perform Allowed Action (ActionChip)", children: actionChips), - new Divider(), - new Padding( - padding: EdgeInsets.all(8.0f), - child: new Center( - child: new Text(this._createResult(), - style: theme.textTheme.title - ) - ) - ) - }; - - return new Scaffold( - appBar: new AppBar( - title: new Text("Chips"), - actions: new List { - new MaterialDemoDocumentationButton(ChipDemo.routeName), - new IconButton( - onPressed: () => { - this.setState(() => { this._showShapeBorder = !this._showShapeBorder; }); - }, - icon: new Icon(Icons.vignette) - ) - } - ), - body: new ChipTheme( - data: this._showShapeBorder - ? theme.chipTheme.copyWith( - shape: new BeveledRectangleBorder( - side: new BorderSide(width: 0.66f, style: BorderStyle.solid, color: Colors.grey), - borderRadius: BorderRadius.circular(10.0f) - )) - : theme.chipTheme, - child: new ListView(children: tiles) - ), - floatingActionButton: new FloatingActionButton( - onPressed: () => this.setState(this._reset), - child: new Icon(Icons.refresh) - ) - ); - } - } -} \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/demo/material/chip_demo.cs.meta b/Samples/UIWidgetsGallery/demo/material/chip_demo.cs.meta deleted file mode 100644 index 0467f59f..00000000 --- a/Samples/UIWidgetsGallery/demo/material/chip_demo.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: c65920c8c4b64c709b62586d0bde9579 -timeCreated: 1555411023 \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/demo/material/modal_bottom_sheet_demo.cs b/Samples/UIWidgetsGallery/demo/material/modal_bottom_sheet_demo.cs deleted file mode 100644 index 93139b54..00000000 --- a/Samples/UIWidgetsGallery/demo/material/modal_bottom_sheet_demo.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System.Collections.Generic; -using Unity.UIWidgets.material; -using Unity.UIWidgets.painting; -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; - -namespace UIWidgetsGallery.gallery { - public class ModalBottomSheetDemo : StatelessWidget { - public const string routeName = "/material/modal-bottom-sheet"; - - public override Widget build(BuildContext context) { - return new Scaffold( - appBar: new AppBar( - title: new Text("Modal bottom sheet"), - actions: new List {new MaterialDemoDocumentationButton(routeName)} - ), - body: new Center( - child: new RaisedButton( - child: new Text("SHOW BOTTOM SHEET"), - onPressed: () => { - BottomSheetUtils.showModalBottomSheet(context: context, - builder: (BuildContext _context) => { - return new Container( - child: new Padding( - padding: EdgeInsets.all(32.0f), - child: new Text("This is the modal bottom sheet. Tap anywhere to dismiss.", - textAlign: TextAlign.center, - style: new TextStyle( - color: Theme.of(_context).accentColor, - fontSize: 24.0f - ) - ) - ) - ); - }); - } - ) - ) - ); - } - } -} \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/demo/material/modal_bottom_sheet_demo.cs.meta b/Samples/UIWidgetsGallery/demo/material/modal_bottom_sheet_demo.cs.meta deleted file mode 100644 index 85074c75..00000000 --- a/Samples/UIWidgetsGallery/demo/material/modal_bottom_sheet_demo.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 3c47b9e1a46e47858145acbe84590d05 -timeCreated: 1555059325 \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/demo/material/persistent_bottom_sheet_demo.cs b/Samples/UIWidgetsGallery/demo/material/persistent_bottom_sheet_demo.cs deleted file mode 100644 index 081078be..00000000 --- a/Samples/UIWidgetsGallery/demo/material/persistent_bottom_sheet_demo.cs +++ /dev/null @@ -1,102 +0,0 @@ -using System.Collections.Generic; -using Unity.UIWidgets.material; -using Unity.UIWidgets.painting; -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; -using DialogUtils = Unity.UIWidgets.material.DialogUtils; - -namespace UIWidgetsGallery.gallery { - public class PersistentBottomSheetDemo : StatefulWidget { - public const string routeName = "/material/persistent-bottom-sheet"; - - public override State createState() { - return new _PersistentBottomSheetDemoState(); - } - } - - class _PersistentBottomSheetDemoState : State { - GlobalKey _scaffoldKey = GlobalKey.key(); - - VoidCallback _showBottomSheetCallback; - - public override void initState() { - base.initState(); - this._showBottomSheetCallback = this._showBottomSheet; - } - - void _showBottomSheet() { - this.setState(() => { - // disable the button - this._showBottomSheetCallback = null; - }); - this._scaffoldKey.currentState.showBottomSheet((BuildContext context) => { - ThemeData themeData = Theme.of(this.context); - return new Container( - decoration: new BoxDecoration( - border: new Border(top: new BorderSide(color: themeData.disabledColor)) - ), - child: new Padding( - padding: EdgeInsets.all(32.0f), - child: new Text("This is a Material persistent bottom sheet. Drag downwards to dismiss it.", - textAlign: TextAlign.center, - style: new TextStyle( - color: themeData.accentColor, - fontSize: 24.0f - ) - ) - ) - ); - }) - .closed.Then((value) => { - if (this.mounted) { - this.setState(() => { - // re-enable the button - this._showBottomSheetCallback = this._showBottomSheet; - }); - } - }); - } - - void _showMessage() { - DialogUtils.showDialog( - context: this.context, - builder: (BuildContext context) => { - return new AlertDialog( - content: new Text("You tapped the floating action button."), - actions: new List { - new FlatButton( - onPressed: () => { Navigator.pop(context); }, - child: new Text("OK") - ) - } - ); - } - ); - } - - public override Widget build(BuildContext context) { - return new Scaffold( - key: this._scaffoldKey, - appBar: new AppBar( - title: new Text("Persistent bottom sheet"), - actions: new List { - new MaterialDemoDocumentationButton(PersistentBottomSheetDemo.routeName) - } - ), - floatingActionButton: new FloatingActionButton( - onPressed: this._showMessage, - backgroundColor: Colors.redAccent, - child: new Icon( - Icons.add - ) - ), - body: new Center( - child: new RaisedButton( - onPressed: this._showBottomSheetCallback, - child: new Text("SHOW BOTTOM SHEET") - ) - ) - ); - } - } -} diff --git a/Samples/UIWidgetsGallery/demo/material/persistent_bottom_sheet_demo.cs.meta b/Samples/UIWidgetsGallery/demo/material/persistent_bottom_sheet_demo.cs.meta deleted file mode 100644 index 9fcbb089..00000000 --- a/Samples/UIWidgetsGallery/demo/material/persistent_bottom_sheet_demo.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: afb410d95c524a18b8761713f1335427 -timeCreated: 1555059936 \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/demo/material/tabs_fab_demo.cs b/Samples/UIWidgetsGallery/demo/material/tabs_fab_demo.cs deleted file mode 100644 index 5eacfb4c..00000000 --- a/Samples/UIWidgetsGallery/demo/material/tabs_fab_demo.cs +++ /dev/null @@ -1,184 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using Unity.UIWidgets.foundation; -using Unity.UIWidgets.material; -using Unity.UIWidgets.painting; -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; - -namespace UIWidgetsGallery.gallery { - class TabsFabDemoUtils { - public const string _explanatoryText = - "When the Scaffold's floating action button changes, the new button fades and " + - "turns into view. In this demo, changing tabs can cause the app to be rebuilt " + - "with a FloatingActionButton that the Scaffold distinguishes from the others " + - "by its key."; - - public static readonly List<_Page> _allPages = new List<_Page> { - new _Page(label: "Blue", colors: Colors.indigo, icon: Icons.add), - new _Page(label: "Eco", colors: Colors.green, icon: Icons.create), - new _Page(label: "No"), - new _Page(label: "Teal", colors: Colors.teal, icon: Icons.add), - new _Page(label: "Red", colors: Colors.red, icon: Icons.create) - }; - } - - class _Page { - public _Page( - string label, - MaterialColor colors = null, - IconData icon = null - ) { - this.label = label; - this.colors = colors; - this.icon = icon; - } - - public readonly string label; - public readonly MaterialColor colors; - public readonly IconData icon; - - public Color labelColor { - get { return this.colors != null ? this.colors.shade300 : Colors.grey.shade300; } - } - - public bool fabDefined { - get { return this.colors != null && this.icon != null; } - } - - public Color fabColor { - get { return this.colors.shade400; } - } - - public Icon fabIcon { - get { return new Icon(this.icon); } - } - - public Key fabKey { - get { return new ValueKey(this.fabColor); } - } - } - - - public class TabsFabDemo : StatefulWidget { - public const string routeName = "/material/tabs-fab"; - - public override State createState() { - return new _TabsFabDemoState(); - } - } - - class _TabsFabDemoState : SingleTickerProviderStateMixin { - GlobalKey _scaffoldKey = GlobalKey.key(); - - TabController _controller; - _Page _selectedPage; - bool _extendedButtons = false; - - public override void initState() { - base.initState(); - this._controller = new TabController(vsync: this, length: TabsFabDemoUtils._allPages.Count); - this._controller.addListener(this._handleTabSelection); - this._selectedPage = TabsFabDemoUtils._allPages[0]; - } - - public override void dispose() { - this._controller.dispose(); - base.dispose(); - } - - void _handleTabSelection() { - this.setState(() => { this._selectedPage = TabsFabDemoUtils._allPages[this._controller.index]; }); - } - - void _showExplanatoryText() { - this._scaffoldKey.currentState.showBottomSheet((BuildContext context) => { - return new Container( - decoration: new BoxDecoration( - border: new Border(top: new BorderSide(color: Theme.of(this.context).dividerColor)) - ), - child: new Padding( - padding: EdgeInsets.all(32.0f), - child: new Text(TabsFabDemoUtils._explanatoryText, - style: Theme.of(this.context).textTheme.subhead) - ) - ); - }); - } - - Widget buildTabView(_Page page) { - return new Builder( - builder: (BuildContext context) => { - return new Container( - key: new ValueKey(page.label), - padding: EdgeInsets.fromLTRB(48.0f, 48.0f, 48.0f, 96.0f), - child: new Card( - child: new Center( - child: new Text(page.label, - style: new TextStyle( - color: page.labelColor, - fontSize: 32.0f - ), - textAlign: TextAlign.center - ) - ) - ) - ); - } - ); - } - - Widget buildFloatingActionButton(_Page page) { - if (!page.fabDefined) { - return null; - } - - if (this._extendedButtons) { - return FloatingActionButton.extended( - key: new ValueKey(page.fabKey), - tooltip: "Show explanation", - backgroundColor: page.fabColor, - icon: page.fabIcon, - label: new Text(page.label.ToUpper()), - onPressed: this._showExplanatoryText - ); - } - - return new FloatingActionButton( - key: page.fabKey, - tooltip: "Show explanation", - backgroundColor: page.fabColor, - child: page.fabIcon, - onPressed: this._showExplanatoryText - ); - } - - public override Widget build(BuildContext context) { - return new Scaffold( - key: this._scaffoldKey, - appBar: new AppBar( - title: new Text("FAB per tab"), - bottom: new TabBar( - controller: this._controller, - tabs: TabsFabDemoUtils._allPages - .Select<_Page, Widget>((_Page page) => new Tab(text: page.label.ToUpper())).ToList() - ), - actions: new List { - new MaterialDemoDocumentationButton(TabsFabDemo.routeName), - new IconButton( - icon: new Icon(Icons.sentiment_very_satisfied), - onPressed: () => { - this.setState(() => { this._extendedButtons = !this._extendedButtons; }); - } - ) - } - ), - floatingActionButton: this.buildFloatingActionButton(this._selectedPage), - body: new TabBarView( - controller: this._controller, - children: TabsFabDemoUtils._allPages.Select<_Page, Widget>(this.buildTabView).ToList() - ) - ); - } - } -} \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/demo/material/tabs_fab_demo.cs.meta b/Samples/UIWidgetsGallery/demo/material/tabs_fab_demo.cs.meta deleted file mode 100644 index 6c2242bf..00000000 --- a/Samples/UIWidgetsGallery/demo/material/tabs_fab_demo.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 7c2dcb794cc84a458f028f3751cf08a7 -timeCreated: 1555060923 \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/demo/shrine.meta b/Samples/UIWidgetsGallery/demo/shrine.meta deleted file mode 100644 index d6898547..00000000 --- a/Samples/UIWidgetsGallery/demo/shrine.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 2621a6f94ad8a4b5ab7199025967dc90 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetsGallery/demo/shrine/shrine_data.cs b/Samples/UIWidgetsGallery/demo/shrine/shrine_data.cs deleted file mode 100644 index 6e208542..00000000 --- a/Samples/UIWidgetsGallery/demo/shrine/shrine_data.cs +++ /dev/null @@ -1,280 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using Unity.UIWidgets.foundation; - -namespace UIWidgetsGallery.gallery { - class ShrineData { - const string _kGalleryAssetsPackage = "flutter_gallery_assets"; - - static Vendor _ali = new Vendor( - name: "Ali’s shop", - avatarAsset: "people/square/ali", - avatarAssetPackage: _kGalleryAssetsPackage, - description: - "Ali Connor’s makes custom goods for folks of all shapes and sizes " + - "made by hand and sometimes by machine, but always with love and care. " + - "Custom orders are available upon request if you need something extra special." - ); - - static Vendor _peter = new Vendor( - name: "Peter’s shop", - avatarAsset: "people/square/peter", - avatarAssetPackage: _kGalleryAssetsPackage, - description: - "Peter makes great stuff for awesome people like you. Super cool and extra " + - "awesome all of his shop’s goods are handmade with love. Custom orders are " + - "available upon request if you need something extra special." - ); - - static Vendor _sandra = new Vendor( - name: "Sandra’s shop", - avatarAsset: "people/square/sandra", - avatarAssetPackage: _kGalleryAssetsPackage, - description: - "Sandra specializes in furniture, beauty and travel products with a classic vibe. " + - "Custom orders are available if you’re looking for a certain color or material." - ); - - static Vendor _stella = new Vendor( - name: "Stella’s shop", - avatarAsset: "people/square/stella", - avatarAssetPackage: _kGalleryAssetsPackage, - description: - "Stella sells awesome stuff at lovely prices. made by hand and sometimes by " + - "machine, but always with love and care. Custom orders are available upon request " + - "if you need something extra special." - ); - - static Vendor _trevor = new Vendor( - name: "Trevor’s shop", - avatarAsset: "people/square/trevor", - avatarAssetPackage: _kGalleryAssetsPackage, - description: - "Trevor makes great stuff for awesome people like you. Super cool and extra " + - "awesome all of his shop’s goods are handmade with love. Custom orders are " + - "available upon request if you need something extra special." - ); - - static readonly List _allProducts = new List { - new Product( - name: "Vintage Brown Belt", - imageAsset: "products/belt", - imageAssetPackage: _kGalleryAssetsPackage, - categories: new List {"fashion", "latest"}, - price: 300.00f, - vendor: _sandra, - description: - "Isn’t it cool when things look old, but they're not. Looks Old But Not makes " + - "awesome vintage goods that are base smart. This ol’ belt just got an upgrade. " - ), - new Product( - name: "Sunglasses", - imageAsset: "products/sunnies", - imageAssetPackage: _kGalleryAssetsPackage, - categories: new List {"travel", "fashion", "beauty"}, - price: 20.00f, - vendor: _trevor, - description: - "Be an optimist. Carry Sunglasses with you at all times. All Tints and " + - "Shades products come with polarized lenses and base duper UV protection " + - "so you can look at the sun for however long you want. Sunglasses make you " + - "look cool, wear them." - ), - new Product( - name: "Flatwear", - imageAsset: "products/flatwear", - imageAssetPackage: _kGalleryAssetsPackage, - categories: new List {"furniture"}, - price: 30.00f, - vendor: _trevor, - description: - "Leave the tunnel and the rain is fallin amazing things happen when you wait" - ), - new Product( - name: "Salmon Sweater", - imageAsset: "products/sweater", - imageAssetPackage: _kGalleryAssetsPackage, - categories: new List {"fashion"}, - price: 300.00f, - vendor: _stella, - description: - "Looks can be deceiving. This sweater comes in a wide variety of " + - "flavors, including salmon, that pop as soon as they hit your eyes. " + - "Sweaters heat quickly, so savor the warmth." - ), - new Product( - name: "Pine Table", - imageAsset: "products/table", - imageAssetPackage: _kGalleryAssetsPackage, - categories: new List {"furniture"}, - price: 63.00f, - vendor: _stella, - description: - "Leave the tunnel and the rain is fallin amazing things happen when you wait" - ), - new Product( - name: "Green Comfort Jacket", - imageAsset: "products/jacket", - imageAssetPackage: _kGalleryAssetsPackage, - categories: new List {"fashion"}, - price: 36.00f, - vendor: _ali, - description: - "Leave the tunnel and the rain is fallin amazing things happen when you wait" - ), - new Product( - name: "Chambray Top", - imageAsset: "products/top", - imageAssetPackage: _kGalleryAssetsPackage, - categories: new List {"fashion"}, - price: 125.00f, - vendor: _peter, - description: - "Leave the tunnel and the rain is fallin amazing things happen when you wait" - ), - new Product( - name: "Blue Cup", - imageAsset: "products/cup", - imageAssetPackage: _kGalleryAssetsPackage, - categories: new List {"travel", "furniture"}, - price: 75.00f, - vendor: _sandra, - description: - "Drinksy has been making extraordinary mugs for decades. With each " + - "cup purchased Drinksy donates a cup to those in need. Buy yourself a mug, " + - "buy someone else a mug." - ), - new Product( - name: "Tea Set", - imageAsset: "products/teaset", - imageAssetPackage: _kGalleryAssetsPackage, - categories: new List {"furniture", "fashion"}, - price: 70.00f, - vendor: _trevor, - featureTitle: "Beautiful glass teapot", - featureDescription: - "Teapot holds extremely hot liquids and pours them from the spout.", - description: - "Impress your guests with Tea Set by Kitchen Stuff. Teapot holds extremely " + - "hot liquids and pours them from the spout. Use the handle, shown on the right, " + - "so your fingers don’t get burnt while pouring." - ), - new Product( - name: "Blue linen napkins", - imageAsset: "products/napkins", - imageAssetPackage: _kGalleryAssetsPackage, - categories: new List {"furniture", "fashion"}, - price: 89.00f, - vendor: _trevor, - description: - "Blue linen napkins were meant to go with friends, so you may want to pick " + - "up a bunch of these. These things are absorbant." - ), - new Product( - name: "Dipped Earrings", - imageAsset: "products/earrings", - imageAssetPackage: _kGalleryAssetsPackage, - categories: new List {"fashion", "beauty"}, - price: 25.00f, - vendor: _stella, - description: - "WeDipIt does it again. These hand-dipped 4 inch earrings are perfect for " + - "the office or the beach. Just be sure you don’t drop it in a bucket of " + - "red paint, then they won’t look dipped anymore." - ), - new Product( - name: "Perfect Planters", - imageAsset: "products/planters", - imageAssetPackage: _kGalleryAssetsPackage, - categories: new List {"latest", "furniture"}, - price: 30.00f, - vendor: _ali, - description: - "The Perfect Planter Co makes the best vessels for just about anything you " + - "can pot. This set of Perfect Planters holds succulents and cuttings perfectly. " + - "Looks great in any room. Keep out of reach from cats." - ), - new Product( - name: "Cloud-White Dress", - imageAsset: "products/dress", - imageAssetPackage: _kGalleryAssetsPackage, - categories: new List {"fashion"}, - price: 54.00f, - vendor: _sandra, - description: - "Trying to find the perfect outift to match your mood? Try no longer. " + - "This Cloud-White Dress has you covered for those nights when you need " + - "to get out, or even if you’re just headed to work." - ), - new Product( - name: "Backpack", - imageAsset: "products/backpack", - imageAssetPackage: _kGalleryAssetsPackage, - categories: new List {"travel", "fashion"}, - price: 25.00f, - vendor: _peter, - description: - "This backpack by Bags ‘n’ stuff can hold just about anything: a laptop, " + - "a pen, a protractor, notebooks, small animals, plugs for your devices, " + - "sunglasses, gym clothes, shoes, gloves, two kittens, and even lunch!" - ), - new Product( - name: "Charcoal Straw Hat", - imageAsset: "products/hat", - imageAssetPackage: _kGalleryAssetsPackage, - categories: new List {"travel", "fashion", "latest"}, - price: 25.00f, - vendor: _ali, - description: - "This is the helmet for those warm summer days on the road. " + - "Jetset approved, these hats have been rigorously tested. Keep that face " + - "protected from the sun." - ), - new Product( - name: "Ginger Scarf", - imageAsset: "products/scarf", - imageAssetPackage: _kGalleryAssetsPackage, - categories: new List {"latest", "fashion"}, - price: 17.00f, - vendor: _peter, - description: - "Leave the tunnel and the rain is fallin amazing things happen when you wait" - ), - new Product( - name: "Blush Sweats", - imageAsset: "products/sweats", - imageAssetPackage: _kGalleryAssetsPackage, - categories: new List {"travel", "fashion", "latest"}, - price: 25.00f, - vendor: _stella, - description: - "Leave the tunnel and the rain is fallin amazing things happen when you wait" - ), - new Product( - name: "Mint Jumper", - imageAsset: "products/jumper", - imageAssetPackage: _kGalleryAssetsPackage, - categories: new List {"travel", "fashion", "beauty"}, - price: 25.00f, - vendor: _peter, - description: - "Leave the tunnel and the rain is fallin amazing things happen when you wait" - ), - new Product( - name: "Ochre Shirt", - imageAsset: "products/shirt", - imageAssetPackage: _kGalleryAssetsPackage, - categories: new List {"fashion", "latest"}, - price: 120.00f, - vendor: _stella, - description: - "Leave the tunnel and the rain is fallin amazing things happen when you wait" - ) - }; - - public static List allProducts() { - D.assert(_allProducts.All((Product product) => product.isValid())); - return new List(_allProducts); - } - } -} \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/demo/shrine/shrine_data.cs.meta b/Samples/UIWidgetsGallery/demo/shrine/shrine_data.cs.meta deleted file mode 100644 index 21d9cf9a..00000000 --- a/Samples/UIWidgetsGallery/demo/shrine/shrine_data.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: f29bb63cff3148cbb3ef3be8196d5709 -timeCreated: 1553240837 \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/demo/shrine/shrine_home.cs b/Samples/UIWidgetsGallery/demo/shrine/shrine_home.cs deleted file mode 100644 index b6a4940a..00000000 --- a/Samples/UIWidgetsGallery/demo/shrine/shrine_home.cs +++ /dev/null @@ -1,410 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using com.unity.uiwidgets.Runtime.rendering; -using Unity.UIWidgets.foundation; -using Unity.UIWidgets.gestures; -using Unity.UIWidgets.material; -using Unity.UIWidgets.painting; -using Unity.UIWidgets.rendering; -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; -using Constants = Unity.UIWidgets.material.Constants; -using Image = Unity.UIWidgets.widgets.Image; - -namespace UIWidgetsGallery.gallery { - class ShrineHomeUtils { - public const float unitSize = Constants.kToolbarHeight; - - public static readonly List _products = new List(ShrineData.allProducts()); - public static readonly Dictionary _shoppingCart = new Dictionary(); - - public const int _childrenPerBlock = 8; - public const int _rowsPerBlock = 5; - - public static int _minIndexInRow(int rowIndex) { - int blockIndex = rowIndex / _rowsPerBlock; - return new List {0, 2, 4, 6, 7}[rowIndex % _rowsPerBlock] + blockIndex * _childrenPerBlock; - } - - public static int _maxIndexInRow(int rowIndex) { - int blockIndex = rowIndex / _rowsPerBlock; - return new List {1, 3, 5, 6, 7}[rowIndex % _rowsPerBlock] + blockIndex * _childrenPerBlock; - } - - public static int _rowAtIndex(int index) { - int blockCount = index / _childrenPerBlock; - return new List {0, 0, 1, 1, 2, 2, 3, 4}[index - blockCount * _childrenPerBlock] + - blockCount * _rowsPerBlock; - } - - public static int _columnAtIndex(int index) { - return new List {0, 1, 0, 1, 0, 1, 0, 0}[index % _childrenPerBlock]; - } - - public static int _columnSpanAtIndex(int index) { - return new List {1, 1, 1, 1, 1, 1, 2, 2}[index % _childrenPerBlock]; - } - } - - class _ShrineGridLayout : SliverGridLayout { - public _ShrineGridLayout( - float? rowStride = null, - float? columnStride = null, - float? tileHeight = null, - float? tileWidth = null - ) { - this.rowStride = rowStride; - this.columnStride = columnStride; - this.tileHeight = tileHeight; - this.tileWidth = tileWidth; - } - - public readonly float? rowStride; - public readonly float? columnStride; - public readonly float? tileHeight; - public readonly float? tileWidth; - - public override int getMinChildIndexForScrollOffset(float scrollOffset) { - return ShrineHomeUtils._minIndexInRow((int) (scrollOffset / this.rowStride)); - } - - public override int getMaxChildIndexForScrollOffset(float scrollOffset) { - return ShrineHomeUtils._maxIndexInRow((int) (scrollOffset / this.rowStride)); - } - - public override SliverGridGeometry getGeometryForChildIndex(int index) { - int row = ShrineHomeUtils._rowAtIndex(index); - int column = ShrineHomeUtils._columnAtIndex(index); - int columnSpan = ShrineHomeUtils._columnSpanAtIndex(index); - return new SliverGridGeometry( - scrollOffset: row * this.rowStride, - crossAxisOffset: column * this.columnStride, - mainAxisExtent: this.tileHeight, - crossAxisExtent: this.tileWidth + (columnSpan - 1) * this.columnStride - ); - } - - public override float computeMaxScrollOffset(int childCount) { - if (childCount == 0) { - return 0.0f; - } - - int rowCount = ShrineHomeUtils._rowAtIndex(childCount - 1) + 1; - float? rowSpacing = this.rowStride - this.tileHeight; - return (this.rowStride * rowCount - rowSpacing) ?? 0.0f; - } - } - - class _ShrineGridDelegate : SliverGridDelegate { - const float _spacing = 8.0f; - - public override SliverGridLayout getLayout(SliverConstraints constraints) { - float tileWidth = (constraints.crossAxisExtent - _spacing) / 2.0f; - const float tileHeight = 40.0f + 144.0f + 40.0f; - return new _ShrineGridLayout( - tileWidth: tileWidth, - tileHeight: tileHeight, - rowStride: tileHeight + _spacing, - columnStride: tileWidth + _spacing - ); - } - - public override bool shouldRelayout(SliverGridDelegate oldDelegate) { - return false; - } - } - - class _VendorItem : StatelessWidget { - public _VendorItem(Key key = null, Vendor vendor = null) : base(key: key) { - D.assert(vendor != null); - this.vendor = vendor; - } - - public readonly Vendor vendor; - - public override Widget build(BuildContext context) { - return new SizedBox( - height: 24.0f, - child: new Row( - children: new List { - new SizedBox( - width: 24.0f, - child: new ClipRRect( - borderRadius: BorderRadius.circular(12.0f), - child: Image.asset( - this.vendor.avatarAsset, - fit: BoxFit.cover - ) - ) - ), - new SizedBox(width: 8.0f), - new Expanded( - child: new Text(this.vendor.name, style: ShrineTheme.of(context).vendorItemStyle) - ) - } - ) - ); - } - } - - abstract class _PriceItem : StatelessWidget { - public _PriceItem(Key key = null, Product product = null) - : base(key: key) { - D.assert(product != null); - this.product = product; - } - - public readonly Product product; - - public Widget buildItem(BuildContext context, TextStyle style, EdgeInsets padding) { - BoxDecoration decoration = null; - if (ShrineHomeUtils._shoppingCart.getOrDefault(this.product) != null) { - decoration = new BoxDecoration(color: ShrineTheme.of(context).priceHighlightColor); - } - - return new Container( - padding: padding, - decoration: decoration, - child: new Text(this.product.priceString, style: style) - ); - } - } - - class _ProductPriceItem : _PriceItem { - public _ProductPriceItem(Key key = null, Product product = null) : base(key: key, product: product) { - } - - public override Widget build(BuildContext context) { - return this.buildItem( - context, - ShrineTheme.of(context).priceStyle, - EdgeInsets.symmetric(horizontal: 16.0f, vertical: 8.0f) - ); - } - } - - class _FeaturePriceItem : _PriceItem { - public _FeaturePriceItem(Key key = null, Product product = null) : base(key: key, product: product) { - } - - public override Widget build(BuildContext context) { - return this.buildItem( - context, - ShrineTheme.of(context).featurePriceStyle, - EdgeInsets.symmetric(horizontal: 24.0f, vertical: 16.0f) - ); - } - } - - class _HeadingLayout : MultiChildLayoutDelegate { - public _HeadingLayout() { - } - - public const string price = "price"; - public const string image = "image"; - public const string title = "title"; - public const string description = "description"; - public const string vendor = "vendor"; - - public override void performLayout(Size size) { - Size priceSize = this.layoutChild(price, BoxConstraints.loose(size)); - this.positionChild(price, new Offset(size.width - priceSize.width, 0.0f)); - - float halfWidth = size.width / 2.0f; - float halfHeight = size.height / 2.0f; - const float halfUnit = ShrineHomeUtils.unitSize / 2.0f; - const float margin = 16.0f; - - Size imageSize = this.layoutChild(image, BoxConstraints.loose(size)); - float imageX = imageSize.width < halfWidth - halfUnit - ? halfWidth / 2.0f - imageSize.width / 2.0f - halfUnit - : halfWidth - imageSize.width; - this.positionChild(image, new Offset(imageX, halfHeight - imageSize.height / 2.0f)); - - float maxTitleWidth = halfWidth + ShrineHomeUtils.unitSize - margin; - BoxConstraints titleBoxConstraints = new BoxConstraints(maxWidth: maxTitleWidth); - Size titleSize = this.layoutChild(title, titleBoxConstraints); - float titleX = halfWidth - ShrineHomeUtils.unitSize; - float titleY = halfHeight - titleSize.height; - this.positionChild(title, new Offset(titleX, titleY)); - - Size descriptionSize = this.layoutChild(description, titleBoxConstraints); - float descriptionY = titleY + titleSize.height + margin; - this.positionChild(description, new Offset(titleX, descriptionY)); - - this.layoutChild(vendor, titleBoxConstraints); - float vendorY = descriptionY + descriptionSize.height + margin; - this.positionChild(vendor, new Offset(titleX, vendorY)); - } - - public override bool shouldRelayout(MultiChildLayoutDelegate oldDelegate) { - return false; - } - } - - class _HeadingShrineHome : StatelessWidget { - public _HeadingShrineHome(Key key = null, Product product = null) : base(key: key) { - D.assert(product != null); - D.assert(product.featureTitle != null); - D.assert(product.featureDescription != null); - this.product = product; - } - - public readonly Product product; - - public override Widget build(BuildContext context) { - Size screenSize = MediaQuery.of(context).size; - ShrineTheme theme = ShrineTheme.of(context); - return new SizedBox( - height: screenSize.width > screenSize.height - ? (screenSize.height - Constants.kToolbarHeight) * 0.85f - : (screenSize.height - Constants.kToolbarHeight) * 0.70f, - child: new Container( - decoration: new BoxDecoration( - color: theme.cardBackgroundColor, - border: new Border(bottom: new BorderSide(color: theme.dividerColor)) - ), - child: new CustomMultiChildLayout( - layoutDelegate: new _HeadingLayout(), - children: new List { - new LayoutId( - id: _HeadingLayout.price, - child: new _FeaturePriceItem(product: this.product) - ), - new LayoutId( - id: _HeadingLayout.image, - child: Image.asset( - this.product.imageAsset, - fit: BoxFit.cover - ) - ), - new LayoutId( - id: _HeadingLayout.title, - child: new Text(this.product.featureTitle, style: theme.featureTitleStyle) - ), - new LayoutId( - id: _HeadingLayout.description, - child: new Text(this.product.featureDescription, style: theme.featureStyle) - ), - new LayoutId( - id: _HeadingLayout.vendor, - child: new _VendorItem(vendor: this.product.vendor) - ) - } - ) - ) - ); - } - } - - class _ProductItem : StatelessWidget { - public _ProductItem(Key key = null, Product product = null, VoidCallback onPressed = null) : base(key: key) { - D.assert(product != null); - this.product = product; - this.onPressed = onPressed; - } - - public readonly Product product; - public readonly VoidCallback onPressed; - - public override Widget build(BuildContext context) { - return new Card( - child: new Stack( - children: new List { - new Column( - children: new List { - new Align( - alignment: Alignment.centerRight, - child: new _ProductPriceItem(product: this.product) - ), - new Container( - width: 144.0f, - height: 144.0f, - padding: EdgeInsets.symmetric(horizontal: 8.0f), - child:new Hero( - tag: this.product.tag, - child: Image.asset(this.product.imageAsset, - fit: BoxFit.contain - ) - ) - ), - new Padding( - padding: EdgeInsets.symmetric(horizontal: 8.0f), - child: new _VendorItem(vendor: this.product.vendor) - ) - } - ), - new Material( - type: MaterialType.transparency, - child: new InkWell(onTap: this.onPressed == null - ? (GestureTapCallback) null - : () => { this.onPressed(); }) - ) - } - ) - ); - } - } - - public class ShrineHome : StatefulWidget { - public override State createState() { - return new _ShrineHomeState(); - } - } - - class _ShrineHomeState : State { - public _ShrineHomeState() { - } - - readonly GlobalKey _scaffoldKey = GlobalKey.key(debugLabel: "Shrine Home"); - static readonly _ShrineGridDelegate gridDelegate = new _ShrineGridDelegate(); - - void _showOrderPage(Product product) { - Order order = ShrineHomeUtils._shoppingCart.getOrDefault(product) ?? new Order(product: product); - Navigator.push(this.context, new ShrineOrderRoute( - order: order, - builder: (BuildContext context) => { - return new OrderPage( - order: order, - products: ShrineHomeUtils._products, - shoppingCart: ShrineHomeUtils._shoppingCart - ); - } - )).Then(completedOrder => { - D.assert((completedOrder as Order).product != null); - if ((completedOrder as Order).quantity == 0) { - ShrineHomeUtils._shoppingCart.Remove((completedOrder as Order).product); - } - }); - } - - public override Widget build(BuildContext context) { - Product featured = ShrineHomeUtils._products.First((Product product) => product.featureDescription != null); - return new ShrinePage( - scaffoldKey: this._scaffoldKey, - products: ShrineHomeUtils._products, - shoppingCart: ShrineHomeUtils._shoppingCart, - body: new CustomScrollView( - slivers: new List { - new SliverToBoxAdapter(child: new _HeadingShrineHome(product: featured)), - new SliverSafeArea( - top: false, - minimum: EdgeInsets.all(16.0f), - sliver: new SliverGrid( - gridDelegate: gridDelegate, - layoutDelegate: new SliverChildListDelegate( - ShrineHomeUtils._products.Select((Product product) => { - return new _ProductItem( - product: product, - onPressed: () => { this._showOrderPage(product); } - ); - }).ToList() - ) - ) - ) - } - ) - ); - } - } -} \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/demo/shrine/shrine_home.cs.meta b/Samples/UIWidgetsGallery/demo/shrine/shrine_home.cs.meta deleted file mode 100644 index d63694f0..00000000 --- a/Samples/UIWidgetsGallery/demo/shrine/shrine_home.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: ec9f3366e13014909b0287e1305641e1 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetsGallery/demo/shrine/shrine_order.cs b/Samples/UIWidgetsGallery/demo/shrine/shrine_order.cs deleted file mode 100644 index 7794ddd7..00000000 --- a/Samples/UIWidgetsGallery/demo/shrine/shrine_order.cs +++ /dev/null @@ -1,341 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using com.unity.uiwidgets.Runtime.rendering; -using Unity.UIWidgets.foundation; -using Unity.UIWidgets.material; -using Unity.UIWidgets.painting; -using Unity.UIWidgets.rendering; -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; -using Image = Unity.UIWidgets.widgets.Image; - -namespace UIWidgetsGallery.gallery { - class _ProductItemShrineOrder : StatelessWidget { - public _ProductItemShrineOrder( - Key key = null, - Product product = null, - int? quantity = null, - ValueChanged onChanged = null - ) : base(key: key) { - D.assert(product != null); - D.assert(quantity != null); - D.assert(onChanged != null); - this.product = product; - this.quantity = quantity; - this.onChanged = onChanged; - } - - public readonly Product product; - public readonly int? quantity; - public readonly ValueChanged onChanged; - - public override Widget build(BuildContext context) { - ShrineTheme theme = ShrineTheme.of(context); - return new Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: new List { - new Text(this.product.name, style: theme.featureTitleStyle), - new SizedBox(height: 24.0f), - new Text(this.product.description, style: theme.featureStyle), - new SizedBox(height: 16.0f), - new Padding( - padding: EdgeInsets.only(top: 8.0f, bottom: 8.0f, right: 88.0f), - child: new DropdownButtonHideUnderline( - child: new Container( - decoration: new BoxDecoration( - border: Border.all( - color: new Color(0xFFD9D9D9) - ) - ), - child: new DropdownButton( - items: new List {0, 1, 2, 3, 4, 5}.Select>( - (int value) => { - return new DropdownMenuItem( - value: $"{value}", - child: new Padding( - padding: EdgeInsets.only(left: 8.0f), - child: new Text($"Quantity {value}", style: theme.quantityMenuStyle) - ) - ); - }).ToList(), - value: $"{this.quantity}", - onChanged: (value) => { this.onChanged(int.Parse(value)); }) - ) - ) - ) - } - ); - } - } - - class _VendorItemShrineOrder : StatelessWidget { - public _VendorItemShrineOrder(Key key = null, Vendor vendor = null) - : base(key: key) { - D.assert(vendor != null); - this.vendor = vendor; - } - - public readonly Vendor vendor; - - public override Widget build(BuildContext context) { - ShrineTheme theme = ShrineTheme.of(context); - return new Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: new List { - new SizedBox( - height: 24.0f, - child: new Align( - alignment: Alignment.bottomLeft, - child: new Text(this.vendor.name, style: theme.vendorTitleStyle) - ) - ), - new SizedBox(height: 16.0f), - new Text(this.vendor.description, style: theme.vendorStyle) - } - ); - } - } - - class _HeadingLayoutShrineOrder : MultiChildLayoutDelegate { - public _HeadingLayoutShrineOrder() { - } - - public const string image = "image"; - public const string icon = "icon"; - public const string product = "product"; - public const string vendor = "vendor"; - - public override void performLayout(Size size) { - const float margin = 56.0f; - bool landscape = size.width > size.height; - float imageWidth = (landscape ? size.width / 2.0f : size.width) - margin * 2.0f; - BoxConstraints imageConstraints = new BoxConstraints(maxHeight: 224.0f, maxWidth: imageWidth); - Size imageSize = this.layoutChild(image, imageConstraints); - const float imageY = 0.0f; - this.positionChild(image, new Offset(margin, imageY)); - - float productWidth = landscape ? size.width / 2.0f : size.width - margin; - BoxConstraints productConstraints = new BoxConstraints(maxWidth: productWidth); - Size productSize = this.layoutChild(product, productConstraints); - float productX = landscape ? size.width / 2.0f : margin; - float productY = landscape ? 0.0f : imageY + imageSize.height + 16.0f; - this.positionChild(product, new Offset(productX, productY)); - - Size iconSize = this.layoutChild(icon, BoxConstraints.loose(size)); - this.positionChild(icon, new Offset(productX - iconSize.width - 16.0f, productY + 8.0f)); - - float vendorWidth = landscape ? size.width - margin : productWidth; - this.layoutChild(vendor, new BoxConstraints(maxWidth: vendorWidth)); - float vendorX = landscape ? margin : productX; - float vendorY = productY + productSize.height + 16.0f; - this.positionChild(vendor, new Offset(vendorX, vendorY)); - } - - public override bool shouldRelayout(MultiChildLayoutDelegate oldDelegate) { - return true; - } - } - - class _HeadingShrineOrder : StatelessWidget { - public _HeadingShrineOrder( - Key key = null, - Product product = null, - int? quantity = null, - ValueChanged quantityChanged = null - ) : base(key: key) { - D.assert(product != null); - D.assert(quantity != null && quantity >= 0 && quantity <= 5); - this.product = product; - this.quantity = quantity; - this.quantityChanged = quantityChanged; - } - - public readonly Product product; - public readonly int? quantity; - public readonly ValueChanged quantityChanged; - - public override Widget build(BuildContext context) { - Size screenSize = MediaQuery.of(context).size; - return new SizedBox( - height: (screenSize.height - Constants.kToolbarHeight) * 1.35f, - child: new Material( - type: MaterialType.card, - elevation: 0.0f, - child: new Padding( - padding: EdgeInsets.only(left: 16.0f, top: 18.0f, right: 16.0f, bottom: 24.0f), - child: new CustomMultiChildLayout( - layoutDelegate: new _HeadingLayoutShrineOrder(), - children: new List { - new LayoutId( - id: _HeadingLayoutShrineOrder.image, - child: new Hero( - tag: this.product.tag, - child: Image.asset(this.product.imageAsset, - fit: BoxFit.contain, - alignment: Alignment.center - ) - ) - ), - new LayoutId( - id: _HeadingLayoutShrineOrder.icon, - child: new Icon( - Icons.info_outline, - size: 24.0f, - color: new Color(0xFFFFE0E0) - ) - ), - new LayoutId( - id: _HeadingLayoutShrineOrder.product, - child: new _ProductItemShrineOrder( - product: this.product, - quantity: this.quantity, - onChanged: this.quantityChanged - ) - ), - new LayoutId( - id: _HeadingLayoutShrineOrder.vendor, - child: new _VendorItemShrineOrder(vendor: this.product.vendor) - ) - } - ) - ) - ) - ); - } - } - - public class OrderPage : StatefulWidget { - public OrderPage( - Key key = null, - Order order = null, - List products = null, - Dictionary shoppingCart = null - ) : base(key: key) { - D.assert(order != null); - D.assert(products != null && products.isNotEmpty()); - D.assert(shoppingCart != null); - this.order = order; - this.products = products; - this.shoppingCart = shoppingCart; - } - - public readonly Order order; - public readonly List products; - public readonly Dictionary shoppingCart; - - public override State createState() { - return new _OrderPageState(); - } - } - - class _OrderPageState : State { - GlobalKey scaffoldKey; - - public override void initState() { - base.initState(); - this.scaffoldKey = GlobalKey.key(debugLabel: $"Shrine Order {this.widget.order}"); - } - - public Order currentOrder { - get { return ShrineOrderRoute.of(this.context).order; } - set { ShrineOrderRoute.of(this.context).order = value; } - } - - void updateOrder(int? quantity = null, bool? inCart = null) { - Order newOrder = this.currentOrder.copyWith(quantity: quantity, inCart: inCart); - if (this.currentOrder != newOrder) { - this.setState(() => { - this.widget.shoppingCart[newOrder.product] = newOrder; - this.currentOrder = newOrder; - }); - } - } - - void showSnackBarMessage(string message) { - this.scaffoldKey.currentState.showSnackBar(new SnackBar(content: new Text(message))); - } - - public override Widget build(BuildContext context) { - return new ShrinePage( - scaffoldKey: this.scaffoldKey, - products: this.widget.products, - shoppingCart: this.widget.shoppingCart, - floatingActionButton: new FloatingActionButton( - onPressed: () => { - this.updateOrder(inCart: true); - int n = this.currentOrder.quantity; - string item = this.currentOrder.product.name; - string message = n == 1 ? $"is one {item} item" : $"are {n} {item} items"; - this.showSnackBarMessage( - $"There {message} in the shopping cart." - ); - }, - backgroundColor: new Color(0xFF16F0F0), - tooltip: "Add to cart", - child: new Icon( - Icons.add_shopping_cart, - color: Colors.black - ) - ), - body: new CustomScrollView( - slivers: new List { - new SliverToBoxAdapter( - child: new _HeadingShrineOrder( - product: this.widget.order.product, - quantity: this.currentOrder.quantity, - quantityChanged: (int value) => { this.updateOrder(quantity: value); } - ) - ), - new SliverSafeArea( - top: false, - minimum: EdgeInsets.fromLTRB(8.0f, 32.0f, 8.0f, 8.0f), - sliver: new SliverGrid( - gridDelegate: new SliverGridDelegateWithMaxCrossAxisExtent( - maxCrossAxisExtent: 248.0f, - mainAxisSpacing: 8.0f, - crossAxisSpacing: 8.0f - ), - layoutDelegate: new SliverChildListDelegate( - this.widget.products - .FindAll((Product product) => product != this.widget.order.product) - .Select((Product product) => { - return new Card( - elevation: 1.0f, - child: Image.asset( - product.imageAsset, - fit: BoxFit.contain - ) - ); - }).ToList() - ) - ) - ) - } - ) - ); - } - } - - public class ShrineOrderRoute : ShrinePageRoute { - public ShrineOrderRoute( - Order order = null, - WidgetBuilder builder = null, - RouteSettings settings = null - ) : base(builder: builder, settings: settings) { - D.assert(order != null); - this.order = order; - } - - public Order order; - - public override object currentResult { - get { return this.order; } - } - - public new static ShrineOrderRoute of(BuildContext context) { - return (ShrineOrderRoute) ModalRoute.of(context); - } - } -} \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/demo/shrine/shrine_order.cs.meta b/Samples/UIWidgetsGallery/demo/shrine/shrine_order.cs.meta deleted file mode 100644 index 5ec0c230..00000000 --- a/Samples/UIWidgetsGallery/demo/shrine/shrine_order.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: b0720924e140457dbc8626755c82f3ba -timeCreated: 1553244438 \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/demo/shrine/shrine_page.cs b/Samples/UIWidgetsGallery/demo/shrine/shrine_page.cs deleted file mode 100644 index d74f2cde..00000000 --- a/Samples/UIWidgetsGallery/demo/shrine/shrine_page.cs +++ /dev/null @@ -1,156 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using Unity.UIWidgets.foundation; -using Unity.UIWidgets.material; -using Unity.UIWidgets.painting; -using Unity.UIWidgets.service; -using Unity.UIWidgets.widgets; - -namespace UIWidgetsGallery.gallery { - public enum ShrineAction { - sortByPrice, - sortByProduct, - emptyCart - } - - public class ShrinePage : StatefulWidget { - public ShrinePage( - Key key = null, - GlobalKey scaffoldKey = null, - Widget body = null, - Widget floatingActionButton = null, - List products = null, - Dictionary shoppingCart = null - ) : base(key: key) { - D.assert(body != null); - D.assert(scaffoldKey != null); - this.scaffoldKey = scaffoldKey; - this.body = body; - this.floatingActionButton = floatingActionButton; - this.products = products; - this.shoppingCart = shoppingCart; - } - - public readonly GlobalKey scaffoldKey; - public readonly Widget body; - public readonly Widget floatingActionButton; - public readonly List products; - public readonly Dictionary shoppingCart; - - public override State createState() { - return new ShrinePageState(); - } - } - - public class ShrinePageState : State { - float _appBarElevation = 0.0f; - - bool _handleScrollNotification(ScrollNotification notification) { - float elevation = notification.metrics.extentBefore() <= 0.0f ? 0.0f : 1.0f; - if (elevation != this._appBarElevation) { - this.setState(() => { this._appBarElevation = elevation; }); - } - - return false; - } - - void _showShoppingCart() { - BottomSheetUtils.showModalBottomSheet(context: this.context, builder: (BuildContext context) => { - if (this.widget.shoppingCart.isEmpty()) { - return new Padding( - padding: EdgeInsets.all(24.0f), - child: new Text("The shopping cart is empty") - ); - } - - return new ListView( - padding: Constants.kMaterialListPadding, - children: this.widget.shoppingCart.Values.Select((Order order) => { - return new ListTile( - title: new Text(order.product.name), - leading: new Text($"{order.quantity}"), - subtitle: new Text(order.product.vendor.name) - ); - }).ToList() - ); - }); - } - - void _sortByPrice() { - this.widget.products.Sort((Product a, Product b) => a.price?.CompareTo(b.price) ?? (b == null ? 0 : -1)); - } - - void _sortByProduct() { - this.widget.products.Sort((Product a, Product b) => a.name.CompareTo(b.name)); - } - - void _emptyCart() { - this.widget.shoppingCart.Clear(); - this.widget.scaffoldKey.currentState.showSnackBar( - new SnackBar(content: new Text("Shopping cart is empty"))); - } - - public override Widget build(BuildContext context) { - ShrineTheme theme = ShrineTheme.of(context); - return new Scaffold( - key: this.widget.scaffoldKey, - appBar: new AppBar( - elevation: this._appBarElevation, - backgroundColor: theme.appBarBackgroundColor, - iconTheme: Theme.of(context).iconTheme, - brightness: Brightness.light, - flexibleSpace: new Container( - decoration: new BoxDecoration( - border: new Border( - bottom: new BorderSide(color: theme.dividerColor) - ) - ) - ), - title: new Text("SHRINE", style: ShrineTheme.of(context).appBarTitleStyle), - centerTitle: true, - actions: new List { - new IconButton( - icon: new Icon(Icons.shopping_cart), - tooltip: "Shopping cart", - onPressed: this._showShoppingCart - ), - new PopupMenuButton( - itemBuilder: (BuildContext _) => new List> { - new PopupMenuItem( - value: ShrineAction.sortByPrice, - child: new Text("Sort by price") - ), - new PopupMenuItem( - value: ShrineAction.sortByProduct, - child: new Text("Sort by product") - ), - new PopupMenuItem( - value: ShrineAction.emptyCart, - child: new Text("Empty shopping cart") - ) - }, - onSelected: (ShrineAction action) => { - switch (action) { - case ShrineAction.sortByPrice: - this.setState(this._sortByPrice); - break; - case ShrineAction.sortByProduct: - this.setState(this._sortByProduct); - break; - case ShrineAction.emptyCart: - this.setState(this._emptyCart); - break; - } - } - ) - } - ), - floatingActionButton: this.widget.floatingActionButton, - body: new NotificationListener( - onNotification: this._handleScrollNotification, - child: this.widget.body - ) - ); - } - } -} \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/demo/shrine/shrine_page.cs.meta b/Samples/UIWidgetsGallery/demo/shrine/shrine_page.cs.meta deleted file mode 100644 index 77517dea..00000000 --- a/Samples/UIWidgetsGallery/demo/shrine/shrine_page.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 81f9ca5ad3e848f4889059abd3037d17 -timeCreated: 1553246179 \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/demo/shrine/shrine_theme.cs b/Samples/UIWidgetsGallery/demo/shrine/shrine_theme.cs deleted file mode 100644 index 6a811ad6..00000000 --- a/Samples/UIWidgetsGallery/demo/shrine/shrine_theme.cs +++ /dev/null @@ -1,98 +0,0 @@ -using Unity.UIWidgets.foundation; -using Unity.UIWidgets.material; -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; -using TextStyle = Unity.UIWidgets.painting.TextStyle; - -namespace UIWidgetsGallery.gallery { - public class ShrineStyle : TextStyle { - public ShrineStyle(bool inherit, Color color, float fontSize, FontWeight fontWeight, TextBaseline textBaseline, - string fontFamily = null - ) : base(inherit: inherit, color: color, fontSize: fontSize, fontWeight: fontWeight, fontFamily: fontFamily, - textBaseline: textBaseline) { - } - - public static ShrineStyle roboto(float size, FontWeight weight, Color color) { - return new ShrineStyle(inherit: false, color: color, fontSize: size, fontWeight: weight, - textBaseline: TextBaseline.alphabetic); - } - - public static ShrineStyle abrilFatface(float size, FontWeight weight, Color color) { - return new ShrineStyle(inherit: false, color: color, fontFamily: "AbrilFatface", fontSize: size, - fontWeight: weight, textBaseline: TextBaseline.alphabetic); - } - } - - public class ShrineThemeUtils { - public static TextStyle robotoRegular12(Color color) { - return ShrineStyle.roboto(12.0f, FontWeight.w400, color); - } - - public static TextStyle robotoLight12(Color color) { - return ShrineStyle.roboto(12.0f, FontWeight.w400, color); - } - - public static TextStyle robotoRegular14(Color color) { - return ShrineStyle.roboto(14.0f, FontWeight.w400, color); - } - - public static TextStyle robotoMedium14(Color color) { - return ShrineStyle.roboto(14.0f, FontWeight.w700, color); - } - - public static TextStyle robotoLight14(Color color) { - return ShrineStyle.roboto(14.0f, FontWeight.w400, color); - } - - public static TextStyle robotoRegular16(Color color) { - return ShrineStyle.roboto(16.0f, FontWeight.w400, color); - } - - public static TextStyle robotoRegular20(Color color) { - return ShrineStyle.roboto(20.0f, FontWeight.w400, color); - } - - public static TextStyle abrilFatfaceRegular24(Color color) { - return ShrineStyle.abrilFatface(24.0f, FontWeight.w400, color); - } - - public static TextStyle abrilFatfaceRegular34(Color color) { - return ShrineStyle.abrilFatface(34.0f, FontWeight.w400, color); - } - } - - public class ShrineTheme : InheritedWidget { - public ShrineTheme(Key key = null, Widget child = null) - : base(key: key, child: child) { - D.assert(child != null); - } - - public readonly Color cardBackgroundColor = Colors.white; - public readonly Color appBarBackgroundColor = Colors.white; - public readonly Color dividerColor = new Color(0xFFD9D9D9); - public readonly Color priceHighlightColor = new Color(0xFFFFE0E0); - - public readonly TextStyle appBarTitleStyle = ShrineThemeUtils.robotoRegular20(Colors.black87); - public readonly TextStyle vendorItemStyle = ShrineThemeUtils.robotoRegular12(new Color(0xFF81959D)); - public readonly TextStyle priceStyle = ShrineThemeUtils.robotoRegular14(Colors.black87); - - public readonly TextStyle featureTitleStyle = - ShrineThemeUtils.abrilFatfaceRegular34(new Color(0xFF0A3142)); - - public readonly TextStyle featurePriceStyle = ShrineThemeUtils.robotoRegular16(Colors.black87); - public readonly TextStyle featureStyle = ShrineThemeUtils.robotoLight14(Colors.black54); - public readonly TextStyle orderTitleStyle = ShrineThemeUtils.abrilFatfaceRegular24(Colors.black87); - public readonly TextStyle orderStyle = ShrineThemeUtils.robotoLight14(Colors.black54); - public readonly TextStyle vendorTitleStyle = ShrineThemeUtils.robotoMedium14(Colors.black87); - public readonly TextStyle vendorStyle = ShrineThemeUtils.robotoLight14(Colors.black54); - public readonly TextStyle quantityMenuStyle = ShrineThemeUtils.robotoLight14(Colors.black54); - - public static ShrineTheme of(BuildContext context) { - return (ShrineTheme) context.inheritFromWidgetOfExactType(typeof(ShrineTheme)); - } - - public override bool updateShouldNotify(InheritedWidget oldWidget) { - return false; - } - } -} \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/demo/shrine/shrine_theme.cs.meta b/Samples/UIWidgetsGallery/demo/shrine/shrine_theme.cs.meta deleted file mode 100644 index 9a6bd34f..00000000 --- a/Samples/UIWidgetsGallery/demo/shrine/shrine_theme.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 468619e1fd4f4437ba3f0929e269aab4 -timeCreated: 1553241961 \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/demo/shrine/shrine_types.cs b/Samples/UIWidgetsGallery/demo/shrine/shrine_types.cs deleted file mode 100644 index c78e5007..00000000 --- a/Samples/UIWidgetsGallery/demo/shrine/shrine_types.cs +++ /dev/null @@ -1,165 +0,0 @@ -using System.Collections.Generic; -using Unity.UIWidgets.foundation; -using Unity.UIWidgets.ui; - -namespace UIWidgetsGallery.gallery { - public class Vendor { - public Vendor( - string name, - string description, - string avatarAsset, - string avatarAssetPackage - ) { - this.name = name; - this.description = description; - this.avatarAsset = avatarAsset; - this.avatarAssetPackage = avatarAssetPackage; - } - - public readonly string name; - public readonly string description; - public readonly string avatarAsset; - public readonly string avatarAssetPackage; - - public bool isValid() { - return this.name != null && this.description != null && this.avatarAsset != null; - } - - public override string ToString() { - return $"Vendor({this.name})"; - } - } - - public class Product { - public Product( - string name = null, - string description = null, - string featureTitle = null, - string featureDescription = null, - string imageAsset = null, - string imageAssetPackage = null, - List categories = null, - float? price = null, - Vendor vendor = null - ) { - this.name = name; - this.description = description; - this.featureTitle = featureTitle; - this.featureDescription = featureDescription; - this.imageAsset = imageAsset; - this.imageAssetPackage = imageAssetPackage; - this.categories = categories; - this.price = price; - this.vendor = vendor; - } - - public readonly string name; - public readonly string description; - public readonly string featureTitle; - public readonly string featureDescription; - public readonly string imageAsset; - public readonly string imageAssetPackage; - public readonly List categories; - public readonly float? price; - public readonly Vendor vendor; - - public string tag { - get { return this.name; } - } - - public string priceString { - get { return $"${(this.price ?? 0.0f).floor()}"; } - } - - public bool isValid() { - return this.name != null && this.description != null && this.imageAsset != null && - this.categories != null && this.categories.isNotEmpty() && this.price != null && - this.vendor.isValid(); - } - - public override string ToString() { - return $"Product({this.name})"; - } - } - - public class Order { - public Order(Product product, int quantity = 1, bool inCart = false) { - D.assert(product != null); - D.assert(quantity >= 0); - this.product = product; - this.quantity = quantity; - this.inCart = inCart; - } - - public readonly Product product; - public readonly int quantity; - public readonly bool inCart; - - public Order copyWith(Product product = null, int? quantity = null, bool? inCart = null) { - return new Order( - product: product ?? this.product, - quantity: quantity ?? this.quantity, - inCart: inCart ?? this.inCart - ); - } - - public static bool operator ==(Order left, Order right) { - if (left is null && right is null) { - return true; - } - - if (left is null || right is null) { - return false; - } - - return left.Equals(right); - } - - public static bool operator !=(Order left, Order right) { - if (left is null && right is null) { - return false; - } - - if (left is null || right is null) { - return true; - } - - return !left.Equals(right); - } - - public bool Equals(Order other) { - return this.product == other.product && - this.quantity == other.quantity && - this.inCart == other.inCart; - } - - public override bool Equals(object obj) { - if (ReferenceEquals(null, obj)) { - return false; - } - - if (ReferenceEquals(this, obj)) { - return true; - } - - if (obj.GetType() != this.GetType()) { - return false; - } - - return this.Equals((Order) obj); - } - - public override int GetHashCode() { - unchecked { - var hashCode = (this.product != null ? this.product.GetHashCode() : 0); - hashCode = (hashCode * 397) ^ this.quantity.GetHashCode(); - hashCode = (hashCode * 397) ^ this.inCart.GetHashCode(); - return hashCode; - } - } - - public override string ToString() { - return $"Order({this.product}, quantity={this.quantity}, inCart={this.inCart})"; - } - } -} \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/demo/shrine/shrine_types.cs.meta b/Samples/UIWidgetsGallery/demo/shrine/shrine_types.cs.meta deleted file mode 100644 index 59744c16..00000000 --- a/Samples/UIWidgetsGallery/demo/shrine/shrine_types.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 924c1662fb504687af28a4f05901a20a -timeCreated: 1553240139 \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/demo/shrine_demo.cs b/Samples/UIWidgetsGallery/demo/shrine_demo.cs deleted file mode 100644 index dfb0bf86..00000000 --- a/Samples/UIWidgetsGallery/demo/shrine_demo.cs +++ /dev/null @@ -1,40 +0,0 @@ -using Unity.UIWidgets.animation; -using Unity.UIWidgets.material; -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; - -namespace UIWidgetsGallery.gallery { - class ShrineDemoUtils { - public static Widget buildShrine(BuildContext context, Widget child) { - return new Theme( - data: new ThemeData( - primarySwatch: Colors.grey, - iconTheme: new IconThemeData(color: new Color(0xFF707070)), - platform: Theme.of(context).platform - ), - child: new ShrineTheme(child: child) - ); - } - } - - public class ShrinePageRoute : MaterialPageRoute { - public ShrinePageRoute( - WidgetBuilder builder, - RouteSettings settings - ) : base(builder: builder, settings: settings) { - } - - public override Widget buildPage(BuildContext context, Animation animation, - Animation secondaryAnimation) { - return ShrineDemoUtils.buildShrine(context, base.buildPage(context, animation, secondaryAnimation)); - } - } - - public class ShrineDemo : StatelessWidget { - public const string routeName = "/shrine"; - - public override Widget build(BuildContext context) { - return ShrineDemoUtils.buildShrine(context, new ShrineHome()); - } - } -} \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/demo/shrine_demo.cs.meta b/Samples/UIWidgetsGallery/demo/shrine_demo.cs.meta deleted file mode 100644 index a95f0d63..00000000 --- a/Samples/UIWidgetsGallery/demo/shrine_demo.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 5902905cca7447d2aa1fe5ae7f6c5cbc -timeCreated: 1553239620 \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/demo/typography_demo.cs b/Samples/UIWidgetsGallery/demo/typography_demo.cs deleted file mode 100644 index e5e2d288..00000000 --- a/Samples/UIWidgetsGallery/demo/typography_demo.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System.Collections.Generic; -using Unity.UIWidgets.foundation; -using Unity.UIWidgets.material; -using Unity.UIWidgets.painting; -using Unity.UIWidgets.rendering; -using Unity.UIWidgets.widgets; - -namespace UIWidgetsGallery.gallery { - public class TextStyleItem : StatelessWidget { - public TextStyleItem( - Key key = null, - string name = null, - TextStyle style = null, - string text = null - ) : base(key: key) { - D.assert(name != null); - D.assert(style != null); - D.assert(text != null); - this.name = name; - this.style = style; - this.text = text; - } - - public readonly string name; - public readonly TextStyle style; - public readonly string text; - - public override Widget build(BuildContext context) { - ThemeData theme = Theme.of(context); - TextStyle nameStyle = theme.textTheme.caption.copyWith(color: theme.textTheme.caption.color); - return new Padding( - padding: EdgeInsets.symmetric(horizontal: 8.0f, vertical: 16.0f), - child: new Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: new List { - new SizedBox( - width: 72.0f, - child: new Text(this.name, style: nameStyle) - ), - new Expanded( - child: new Text(this.text, style: this.style.copyWith(height: 1.0f)) - ) - } - ) - ); - } - } - - public class TypographyDemo : StatelessWidget { - public const string routeName = "/typography"; - - public override Widget build(BuildContext context) { - TextTheme textTheme = Theme.of(context).textTheme; - List styleItems = new List { - new TextStyleItem(name: "Display 3", style: textTheme.display3, text: "Regular 56sp"), - new TextStyleItem(name: "Display 2", style: textTheme.display2, text: "Regular 45sp"), - new TextStyleItem(name: "Display 1", style: textTheme.display1, text: "Regular 34sp"), - new TextStyleItem(name: "Headline", style: textTheme.headline, text: "Regular 24sp"), - new TextStyleItem(name: "Title", style: textTheme.title, text: "Medium 20sp"), - new TextStyleItem(name: "Subheading", style: textTheme.subhead, text: "Regular 16sp"), - new TextStyleItem(name: "Body 2", style: textTheme.body2, text: "Medium 14sp"), - new TextStyleItem(name: "Body 1", style: textTheme.body1, text: "Regular 14sp"), - new TextStyleItem(name: "Caption", style: textTheme.caption, text: "Regular 12sp"), - new TextStyleItem(name: "Button", style: textTheme.button, text: "MEDIUM (ALL CAPS) 14sp") - }; - - if (MediaQuery.of(context).size.width > 500.0f) { - styleItems.Insert(0, new TextStyleItem( - name: "Display 4", - style: textTheme.display4, - text: "Light 112sp" - )); - } - - return new Scaffold( - appBar: new AppBar(title: new Text("Typography")), - body: new SafeArea( - top: false, - bottom: false, - child: new ListView(children: styleItems) - ) - ); - } - } -} \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/demo/typography_demo.cs.meta b/Samples/UIWidgetsGallery/demo/typography_demo.cs.meta deleted file mode 100644 index 20fca164..00000000 --- a/Samples/UIWidgetsGallery/demo/typography_demo.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: ec695ed4b0de477a8f58aebe079b8ac0 -timeCreated: 1553075802 \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/gallery.meta b/Samples/UIWidgetsGallery/gallery.meta deleted file mode 100644 index 01002ec1..00000000 --- a/Samples/UIWidgetsGallery/gallery.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 05f67c3cc663543059f6e339e99ce4b8 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetsGallery/gallery.unity b/Samples/UIWidgetsGallery/gallery.unity deleted file mode 100644 index 18788968..00000000 --- a/Samples/UIWidgetsGallery/gallery.unity +++ /dev/null @@ -1,504 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!29 &1 -OcclusionCullingSettings: - m_ObjectHideFlags: 0 - serializedVersion: 2 - m_OcclusionBakeSettings: - smallestOccluder: 5 - smallestHole: 0.25 - backfaceThreshold: 100 - m_SceneGUID: 00000000000000000000000000000000 - m_OcclusionCullingData: {fileID: 0} ---- !u!104 &2 -RenderSettings: - m_ObjectHideFlags: 0 - serializedVersion: 9 - m_Fog: 0 - m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} - m_FogMode: 3 - m_FogDensity: 0.01 - m_LinearFogStart: 0 - m_LinearFogEnd: 300 - m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} - m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} - m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} - m_AmbientIntensity: 1 - m_AmbientMode: 0 - m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} - m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} - m_HaloStrength: 0.5 - m_FlareStrength: 1 - m_FlareFadeSpeed: 3 - m_HaloTexture: {fileID: 0} - m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} - m_DefaultReflectionMode: 0 - m_DefaultReflectionResolution: 128 - m_ReflectionBounces: 1 - m_ReflectionIntensity: 1 - m_CustomReflection: {fileID: 0} - m_Sun: {fileID: 0} - m_IndirectSpecularColor: {r: 0.44657892, g: 0.4964127, b: 0.5748172, a: 1} - m_UseRadianceAmbientProbe: 0 ---- !u!157 &3 -LightmapSettings: - m_ObjectHideFlags: 0 - serializedVersion: 11 - m_GIWorkflowMode: 0 - m_GISettings: - serializedVersion: 2 - m_BounceScale: 1 - m_IndirectOutputScale: 1 - m_AlbedoBoost: 1 - m_EnvironmentLightingMode: 0 - m_EnableBakedLightmaps: 1 - m_EnableRealtimeLightmaps: 1 - m_LightmapEditorSettings: - serializedVersion: 10 - m_Resolution: 2 - m_BakeResolution: 40 - m_AtlasSize: 1024 - m_AO: 0 - m_AOMaxDistance: 1 - m_CompAOExponent: 1 - m_CompAOExponentDirect: 0 - m_Padding: 2 - m_LightmapParameters: {fileID: 0} - m_LightmapsBakeMode: 1 - m_TextureCompression: 1 - m_FinalGather: 0 - m_FinalGatherFiltering: 1 - m_FinalGatherRayCount: 256 - m_ReflectionCompression: 2 - m_MixedBakeMode: 2 - m_BakeBackend: 1 - m_PVRSampling: 1 - m_PVRDirectSampleCount: 32 - m_PVRSampleCount: 500 - m_PVRBounces: 2 - m_PVRFilterTypeDirect: 0 - m_PVRFilterTypeIndirect: 0 - m_PVRFilterTypeAO: 0 - m_PVRFilteringMode: 1 - m_PVRCulling: 1 - m_PVRFilteringGaussRadiusDirect: 1 - m_PVRFilteringGaussRadiusIndirect: 5 - m_PVRFilteringGaussRadiusAO: 2 - m_PVRFilteringAtrousPositionSigmaDirect: 0.5 - m_PVRFilteringAtrousPositionSigmaIndirect: 2 - m_PVRFilteringAtrousPositionSigmaAO: 1 - m_ShowResolutionOverlay: 1 - m_LightingDataAsset: {fileID: 0} - m_UseShadowmask: 1 ---- !u!196 &4 -NavMeshSettings: - serializedVersion: 2 - m_ObjectHideFlags: 0 - m_BuildSettings: - serializedVersion: 2 - agentTypeID: 0 - agentRadius: 0.5 - agentHeight: 2 - agentSlope: 45 - agentClimb: 0.4 - ledgeDropHeight: 0 - maxJumpAcrossDistance: 0 - minRegionArea: 2 - manualCellSize: 0 - cellSize: 0.16666667 - manualTileSize: 0 - tileSize: 256 - accuratePlacement: 0 - debug: - m_Flags: 0 - m_NavMeshData: {fileID: 0} ---- !u!1 &242452675 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 242452676} - - component: {fileID: 242452678} - - component: {fileID: 242452677} - m_Layer: 5 - m_Name: gallery - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &242452676 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 242452675} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 1248027221} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &242452677 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 242452675} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 9c5c86936ca864ae684720ddcd50d759, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_Texture: {fileID: 0} - m_UVRect: - serializedVersion: 2 - x: 0 - y: 0 - width: 1 - height: 1 - devicePixelRatioOverride: 0 - antiAliasingOverride: 4 ---- !u!222 &242452678 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 242452675} - m_CullTransparentMesh: 0 ---- !u!1 &1152820164 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1152820167} - - component: {fileID: 1152820166} - - component: {fileID: 1152820165} - m_Layer: 0 - m_Name: EventSystem - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!114 &1152820165 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1152820164} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 1077351063, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_HorizontalAxis: Horizontal - m_VerticalAxis: Vertical - m_SubmitButton: Submit - m_CancelButton: Cancel - m_InputActionsPerSecond: 10 - m_RepeatDelay: 0.5 - m_ForceModuleActive: 0 ---- !u!114 &1152820166 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1152820164} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: -619905303, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_FirstSelected: {fileID: 0} - m_sendNavigationEvents: 1 - m_DragThreshold: 10 ---- !u!4 &1152820167 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1152820164} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 3 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!1 &1248027217 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1248027221} - - component: {fileID: 1248027220} - - component: {fileID: 1248027219} - - component: {fileID: 1248027218} - m_Layer: 5 - m_Name: Canvas - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!114 &1248027218 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1248027217} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 1301386320, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_IgnoreReversedGraphics: 1 - m_BlockingObjects: 0 - m_BlockingMask: - serializedVersion: 2 - m_Bits: 4294967295 ---- !u!114 &1248027219 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1248027217} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 1980459831, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_UiScaleMode: 0 - m_ReferencePixelsPerUnit: 100 - m_ScaleFactor: 1 - m_ReferenceResolution: {x: 800, y: 600} - m_ScreenMatchMode: 0 - m_MatchWidthOrHeight: 0 - m_PhysicalUnit: 3 - m_FallbackScreenDPI: 96 - m_DefaultSpriteDPI: 96 - m_DynamicPixelsPerUnit: 1 ---- !u!223 &1248027220 -Canvas: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1248027217} - m_Enabled: 1 - serializedVersion: 3 - m_RenderMode: 0 - m_Camera: {fileID: 0} - m_PlaneDistance: 100 - m_PixelPerfect: 0 - m_ReceivesEvents: 1 - m_OverrideSorting: 0 - m_OverridePixelPerfect: 0 - m_SortingBucketNormalizedSize: 0 - m_AdditionalShaderChannelsFlag: 0 - m_SortingLayerID: 0 - m_SortingOrder: 0 - m_TargetDisplay: 0 ---- !u!224 &1248027221 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1248027217} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 0, y: 0, z: 0} - m_Children: - - {fileID: 242452676} - m_Father: {fileID: 0} - m_RootOrder: 2 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 0, y: 0} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0, y: 0} ---- !u!1 &1304413924 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1304413926} - - component: {fileID: 1304413925} - m_Layer: 0 - m_Name: Directional Light - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!108 &1304413925 -Light: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1304413924} - m_Enabled: 1 - serializedVersion: 8 - m_Type: 1 - m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} - m_Intensity: 1 - m_Range: 10 - m_SpotAngle: 30 - m_CookieSize: 10 - m_Shadows: - m_Type: 2 - m_Resolution: -1 - m_CustomResolution: -1 - m_Strength: 1 - m_Bias: 0.05 - m_NormalBias: 0.4 - m_NearPlane: 0.2 - m_Cookie: {fileID: 0} - m_DrawHalo: 0 - m_Flare: {fileID: 0} - m_RenderMode: 0 - m_CullingMask: - serializedVersion: 2 - m_Bits: 4294967295 - m_Lightmapping: 4 - m_LightShadowCasterMode: 0 - m_AreaSize: {x: 1, y: 1} - m_BounceIntensity: 1 - m_ColorTemperature: 6570 - m_UseColorTemperature: 0 - m_ShadowRadius: 0 - m_ShadowAngle: 0 ---- !u!4 &1304413926 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1304413924} - m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} - m_LocalPosition: {x: 0, y: 3, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 1 - m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} ---- !u!1 &1396321320 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1396321323} - - component: {fileID: 1396321322} - - component: {fileID: 1396321321} - m_Layer: 0 - m_Name: Main Camera - m_TagString: MainCamera - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!81 &1396321321 -AudioListener: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1396321320} - m_Enabled: 1 ---- !u!20 &1396321322 -Camera: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1396321320} - m_Enabled: 1 - serializedVersion: 2 - m_ClearFlags: 1 - m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} - m_projectionMatrixMode: 1 - m_SensorSize: {x: 36, y: 24} - m_LensShift: {x: 0, y: 0} - m_GateFitMode: 2 - m_FocalLength: 50 - m_NormalizedViewPortRect: - serializedVersion: 2 - x: 0 - y: 0 - width: 1 - height: 1 - near clip plane: 0.3 - far clip plane: 1000 - field of view: 60 - orthographic: 0 - orthographic size: 5 - m_Depth: -1 - m_CullingMask: - serializedVersion: 2 - m_Bits: 4294967295 - m_RenderingPath: -1 - m_TargetTexture: {fileID: 0} - m_TargetDisplay: 0 - m_TargetEye: 3 - m_HDR: 1 - m_AllowMSAA: 1 - m_AllowDynamicResolution: 0 - m_ForceIntoRT: 0 - m_OcclusionCulling: 1 - m_StereoConvergence: 10 - m_StereoSeparation: 0.022 ---- !u!4 &1396321323 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1396321320} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 1, z: -10} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} diff --git a/Samples/UIWidgetsGallery/gallery.unity.meta b/Samples/UIWidgetsGallery/gallery.unity.meta deleted file mode 100644 index e461bb62..00000000 --- a/Samples/UIWidgetsGallery/gallery.unity.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 97d82ba0e79874aee90750ac8d1661bc -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetsGallery/gallery/app.cs b/Samples/UIWidgetsGallery/gallery/app.cs deleted file mode 100644 index fd5a42f1..00000000 --- a/Samples/UIWidgetsGallery/gallery/app.cs +++ /dev/null @@ -1,141 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using RSG; -using Unity.UIWidgets.async; -using Unity.UIWidgets.foundation; -using Unity.UIWidgets.material; -using Unity.UIWidgets.scheduler; -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; -using UnityEngine; - -namespace UIWidgetsGallery.gallery { - public delegate IPromise UpdateUrlFetcher(); - - public class GalleryApp : StatefulWidget { - public GalleryApp( - Key key = null, - UpdateUrlFetcher updateUrlFetcher = null, - bool enablePerformanceOverlay = false, - bool enableRasterCacheImagesCheckerboard = false, - bool enableOffscreenLayersCheckerboard = false, - VoidCallback onSendFeedback = null, - bool testMode = false - ) : base(key: key) { - this.updateUrlFetcher = updateUrlFetcher; - this.enablePerformanceOverlay = enablePerformanceOverlay; - this.enableRasterCacheImagesCheckerboard = enableRasterCacheImagesCheckerboard; - this.enableOffscreenLayersCheckerboard = enableOffscreenLayersCheckerboard; - this.onSendFeedback = onSendFeedback; - this.testMode = testMode; - } - - public readonly UpdateUrlFetcher updateUrlFetcher; - - public readonly bool enablePerformanceOverlay; - - public readonly bool enableRasterCacheImagesCheckerboard; - - public readonly bool enableOffscreenLayersCheckerboard; - - public readonly VoidCallback onSendFeedback; - - public readonly bool testMode; - - public override State createState() { - return new _GalleryAppState(); - } - } - - class _GalleryAppState : State { - GalleryOptions _options; - Timer _timeDilationTimer; - - Dictionary _buildRoutes() { - return DemoUtils.kAllGalleryDemos.ToDictionary( - (demo) => $"{demo.routeName}", - (demo) => demo.buildRoute); - } - - public override void initState() { - base.initState(); - this._options = new GalleryOptions( - theme: GalleryTheme.kLightGalleryTheme, - textScaleFactor: GalleryTextScaleValue.kAllGalleryTextScaleValues[0], - timeDilation: SchedulerBinding.instance.timeDilation, - platform: Application.platform, - showPerformanceOverlay: this.widget.enablePerformanceOverlay - ); - } - - public override void dispose() { - this._timeDilationTimer?.cancel(); - this._timeDilationTimer = null; - base.dispose(); - } - - void _handleOptionsChanged(GalleryOptions newOptions) { - this.setState(() => { - if (this._options.timeDilation != newOptions.timeDilation) { - this._timeDilationTimer?.cancel(); - this._timeDilationTimer = null; - if (newOptions.timeDilation > 1.0f) { - this._timeDilationTimer = Window.instance.run(new TimeSpan(0, 0, 0, 0, 150), - () => { SchedulerBinding.instance.timeDilation = newOptions.timeDilation; }); - } else { - SchedulerBinding.instance.timeDilation = newOptions.timeDilation; - } - } - - this._options = newOptions; - }); - } - - Widget _applyTextScaleFactor(Widget child) { - return new Builder( - builder: context => { - return new MediaQuery( - data: MediaQuery.of(context).copyWith( - textScaleFactor: this._options.textScaleFactor.scale - ), - child: child - ); - } - ); - } - - public override Widget build(BuildContext context) { - Widget home = new GalleryHome( - testMode: this.widget.testMode, - optionsPage: new GalleryOptionsPage( - options: this._options, - onOptionsChanged: this._handleOptionsChanged, - onSendFeedback: this.widget.onSendFeedback ?? (() => { - Application.OpenURL("https://github.com/UnityTech/UIWidgets/issues"); - }) - ), - options: this._options - ); - - if (this.widget.updateUrlFetcher != null) { - home = new Updater( - updateUrlFetcher: this.widget.updateUrlFetcher, - child: home - ); - } - - return new MaterialApp( - theme: this._options.theme.data.copyWith(/*platform: this._options.platform*/), - title: "UIWidgets Gallery", - color: Colors.grey, - showPerformanceOverlay: this._options.showPerformanceOverlay, - //checkerboardOffscreenLayers: this._options.showOffscreenLayersCheckerboard, - //checkerboardRasterCacheImages: this._options.showRasterCacheImagesCheckerboard, - routes: this._buildRoutes(), - builder: (BuildContext _, Widget child) => this._applyTextScaleFactor(child), - home: home - ); - } - } -} diff --git a/Samples/UIWidgetsGallery/gallery/backdrop.cs b/Samples/UIWidgetsGallery/gallery/backdrop.cs deleted file mode 100644 index 629c6870..00000000 --- a/Samples/UIWidgetsGallery/gallery/backdrop.cs +++ /dev/null @@ -1,365 +0,0 @@ -using System; -using System.Collections.Generic; -using Unity.UIWidgets.animation; -using Unity.UIWidgets.foundation; -using Unity.UIWidgets.gestures; -using Unity.UIWidgets.material; -using Unity.UIWidgets.painting; -using Unity.UIWidgets.rendering; -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; -using UnityEngine; - -namespace UIWidgetsGallery.gallery { - class BackdropConstants { - public const float _kFrontHeadingHeight = 32.0f; - public const float _kFrontClosedHeight = 92.0f; - public const float _kBackAppBarHeight = 56.0f; - - public static readonly Animatable _kFrontHeadingBevelRadius = new BorderRadiusTween( - begin: BorderRadius.only( - topLeft: Radius.circular(12.0f), - topRight: Radius.circular(12.0f) - ), - end: BorderRadius.only( - topLeft: Radius.circular(_kFrontHeadingHeight), - topRight: Radius.circular(_kFrontHeadingHeight) - ) - ); - } - - class _TappableWhileStatusIs : StatefulWidget { - public _TappableWhileStatusIs( - AnimationStatus status, - Key key = null, - AnimationController controller = null, - Widget child = null - ) : base(key: key) { - this.controller = controller; - this.status = status; - this.child = child; - } - - public readonly AnimationController controller; - public readonly AnimationStatus status; - public readonly Widget child; - - public override State createState() { - return new _TappableWhileStatusIsState(); - } - } - - class _TappableWhileStatusIsState : State<_TappableWhileStatusIs> { - bool _active; - - public override void initState() { - base.initState(); - this.widget.controller.addStatusListener(this._handleStatusChange); - this._active = this.widget.controller.status == this.widget.status; - } - - public override void dispose() { - this.widget.controller.removeStatusListener(this._handleStatusChange); - base.dispose(); - } - - void _handleStatusChange(AnimationStatus status) { - bool value = this.widget.controller.status == this.widget.status; - if (this._active != value) { - this.setState(() => { this._active = value; }); - } - } - - public override Widget build(BuildContext context) { - return new AbsorbPointer( - absorbing: !this._active, - child: this.widget.child - ); - } - } - - class _CrossFadeTransition : AnimatedWidget { - public _CrossFadeTransition( - Key key = null, - Alignment alignment = null, - Animation progress = null, - Widget child0 = null, - Widget child1 = null - ) : base(key: key, listenable: progress) { - this.alignment = alignment ?? Alignment.center; - this.child0 = child0; - this.child1 = child1; - } - - public readonly Alignment alignment; - public readonly Widget child0; - public readonly Widget child1; - - protected override Widget build(BuildContext context) { - Animation progress = this.listenable as Animation; - - float opacity1 = new CurvedAnimation( - parent: new ReverseAnimation(progress), - curve: new Interval(0.5f, 1.0f) - ).value; - - float opacity2 = new CurvedAnimation( - parent: progress, - curve: new Interval(0.5f, 1.0f) - ).value; - - return new Stack( - alignment: this.alignment, - children: new List { - new Opacity( - opacity: opacity1, - child: this.child1 - ), - new Opacity( - opacity: opacity2, - child: this.child0 - ) - } - ); - } - } - - class _BackAppBar : StatelessWidget { - public _BackAppBar( - Key key = null, - Widget leading = null, - Widget title = null, - Widget trailing = null - ) : base(key: key) { - D.assert(title != null); - this.leading = leading ?? new SizedBox(width: 56.0f); - this.title = title; - this.trailing = trailing; - } - - public readonly Widget leading; - public readonly Widget title; - public readonly Widget trailing; - - public override Widget build(BuildContext context) { - List children = new List { - new Container( - alignment: Alignment.center, - width: 56.0f, - child: this.leading - ), - new Expanded( - child: this.title - ), - }; - - if (this.trailing != null) { - children.Add( - new Container( - alignment: Alignment.center, - width: 56.0f, - child: this.trailing - ) - ); - } - - ThemeData theme = Theme.of(context); - - return IconTheme.merge( - data: theme.primaryIconTheme, - child: new DefaultTextStyle( - style: theme.primaryTextTheme.title, - child: new SizedBox( - height: BackdropConstants._kBackAppBarHeight, - child: new Row(children: children) - ) - ) - ); - } - } - - public class Backdrop : StatefulWidget { - public Backdrop( - Widget frontAction = null, - Widget frontTitle = null, - Widget frontHeading = null, - Widget frontLayer = null, - Widget backTitle = null, - Widget backLayer = null - ) { - this.frontAction = frontAction; - this.frontTitle = frontTitle; - this.frontHeading = frontHeading; - this.frontLayer = frontLayer; - this.backTitle = backTitle; - this.backLayer = backLayer; - } - - public readonly Widget frontAction; - public readonly Widget frontTitle; - public readonly Widget frontLayer; - public readonly Widget frontHeading; - public readonly Widget backTitle; - public readonly Widget backLayer; - - public override State createState() { - return new _BackdropState(); - } - } - - class _BackdropState : SingleTickerProviderStateMixin { - GlobalKey _backdropKey = GlobalKey.key(debugLabel: "Backdrop"); - AnimationController _controller; - Animation _frontOpacity; - - static Animatable _frontOpacityTween = new FloatTween(begin: 0.2f, end: 1.0f) - .chain(new CurveTween(curve: new Interval(0.0f, 0.4f, curve: Curves.easeInOut))); - - public override void initState() { - base.initState(); - this._controller = new AnimationController( - duration: new TimeSpan(0, 0, 0, 0, 300), - value: 1.0f, - vsync: this - ); - this._frontOpacity = this._controller.drive(_frontOpacityTween); - } - - public override void dispose() { - this._controller.dispose(); - base.dispose(); - } - - float? _backdropHeight { - get { - RenderBox renderBox = (RenderBox) this._backdropKey.currentContext.findRenderObject(); - return Mathf.Max(0.0f, - renderBox.size.height - BackdropConstants._kBackAppBarHeight - - BackdropConstants._kFrontClosedHeight); - } - } - - void _handleDragUpdate(DragUpdateDetails details) { - this._controller.setValue(this._controller.value - - details.primaryDelta / (this._backdropHeight ?? details.primaryDelta) ?? 0.0f); - } - - void _handleDragEnd(DragEndDetails details) { - if (this._controller.isAnimating || this._controller.status == AnimationStatus.completed) { - return; - } - - float? flingVelocity = details.velocity.pixelsPerSecond.dy / this._backdropHeight; - if (flingVelocity < 0.0f) { - this._controller.fling(velocity: Mathf.Max(2.0f, -flingVelocity ?? 0.0f)); - } - else if (flingVelocity > 0.0f) { - this._controller.fling(velocity: Mathf.Min(-2.0f, -flingVelocity ?? 0.0f)); - } - else { - this._controller.fling(velocity: this._controller.value < 0.5 ? -2.0f : 2.0f); - } - } - - void _toggleFrontLayer() { - AnimationStatus status = this._controller.status; - bool isOpen = status == AnimationStatus.completed || status == AnimationStatus.forward; - this._controller.fling(velocity: isOpen ? -2.0f : 2.0f); - } - - Widget _buildStack(BuildContext context, BoxConstraints constraints) { - Animation frontRelativeRect = this._controller.drive(new RelativeRectTween( - begin: RelativeRect.fromLTRB(0.0f, constraints.biggest.height - BackdropConstants._kFrontClosedHeight, - 0.0f, 0.0f), - end: RelativeRect.fromLTRB(0.0f, BackdropConstants._kBackAppBarHeight, 0.0f, 0.0f) - )); - - List layers = new List { - new Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: new List { - new _BackAppBar( - leading: this.widget.frontAction, - title: new _CrossFadeTransition( - progress: this._controller, - alignment: Alignment.centerLeft, - child0: this.widget.frontTitle, - child1: this.widget.backTitle - ), - trailing: new IconButton( - onPressed: this._toggleFrontLayer, - tooltip: "Toggle options page", - icon: new AnimatedIcon( - icon: AnimatedIcons.close_menu, - progress: this._controller - ) - ) - ), - new Expanded( - child: new Visibility( - child: this.widget.backLayer, - visible: this._controller.status != AnimationStatus.completed, - maintainState: true - ) - ) - } - ), - new PositionedTransition( - rect: frontRelativeRect, - child: new AnimatedBuilder( - animation: this._controller, - builder: (BuildContext _context, Widget child) => { - return new PhysicalShape( - elevation: 12.0f, - color: Theme.of(_context).canvasColor, - clipper: new ShapeBorderClipper( - shape: new BeveledRectangleBorder( - borderRadius: BackdropConstants._kFrontHeadingBevelRadius.evaluate( - this._controller) - ) - ), - clipBehavior: Clip.antiAlias, - child: child - ); - }, - child: new _TappableWhileStatusIs( - AnimationStatus.completed, - controller: this._controller, - child: new FadeTransition( - opacity: this._frontOpacity, - child: this.widget.frontLayer - ) - ) - ) - ) - }; - - if (this.widget.frontHeading != null) { - layers.Add( - new PositionedTransition( - rect: frontRelativeRect, - child: new Container( - alignment: Alignment.topLeft, - child: new GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: this._toggleFrontLayer, - onVerticalDragUpdate: this._handleDragUpdate, - onVerticalDragEnd: this._handleDragEnd, - child: this.widget.frontHeading - ) - ) - ) - ); - } - - return new Stack( - key: this._backdropKey, - children: layers - ); - } - - public override Widget build(BuildContext context) { - return new LayoutBuilder(builder: this._buildStack); - } - } -} \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/gallery/backdrop.cs.meta b/Samples/UIWidgetsGallery/gallery/backdrop.cs.meta deleted file mode 100644 index dd6437aa..00000000 --- a/Samples/UIWidgetsGallery/gallery/backdrop.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: f3ee24c4986845abb1356402632d8524 -timeCreated: 1552886622 \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/gallery/demo.cs b/Samples/UIWidgetsGallery/gallery/demo.cs deleted file mode 100644 index eb46de18..00000000 --- a/Samples/UIWidgetsGallery/gallery/demo.cs +++ /dev/null @@ -1,253 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using Unity.UIWidgets.foundation; -using Unity.UIWidgets.material; -using Unity.UIWidgets.painting; -using Unity.UIWidgets.service; -using Unity.UIWidgets.widgets; -using UnityEngine; - -namespace UIWidgetsGallery.gallery { - public class ComponentDemoTabData { - public ComponentDemoTabData( - Widget demoWidget = null, - string exampleCodeTag = null, - string description = null, - string tabName = null, - string documentationUrl = null - ) { - this.demoWidget = demoWidget; - this.exampleCodeTag = exampleCodeTag; - this.description = description; - this.tabName = tabName; - this.documentationUrl = documentationUrl; - } - - public readonly Widget demoWidget; - public readonly string exampleCodeTag; - public readonly string description; - public readonly string tabName; - public readonly string documentationUrl; - - public static bool operator ==(ComponentDemoTabData left, ComponentDemoTabData right) { - return left.Equals(right); - } - - public static bool operator !=(ComponentDemoTabData left, ComponentDemoTabData right) { - return !left.Equals(right); - } - - public bool Equals(ComponentDemoTabData other) { - return other.tabName == this.tabName - && other.description == this.description - && other.documentationUrl == this.documentationUrl; - } - - public override bool Equals(object obj) { - if (ReferenceEquals(null, obj)) { - return false; - } - - if (ReferenceEquals(this, obj)) { - return true; - } - - if (obj.GetType() != this.GetType()) { - return false; - } - - return this.Equals((ComponentDemoTabData) obj); - } - - public override int GetHashCode() { - unchecked { - var hashCode = this.tabName.GetHashCode(); - hashCode = (hashCode * 397) ^ this.description.GetHashCode(); - hashCode = (hashCode * 397) ^ this.documentationUrl.GetHashCode(); - return hashCode; - } - } - } - - - public class TabbedComponentDemoScaffold : StatelessWidget { - public TabbedComponentDemoScaffold( - string title = null, - List demos = null, - List actions = null - ) { - this.title = title; - this.demos = demos; - this.actions = actions; - } - - public readonly List demos; - public readonly string title; - public readonly List actions; - - void _showExampleCode(BuildContext context) { - string tag = this.demos[DefaultTabController.of(context).index].exampleCodeTag; - if (tag != null) { - Navigator.push(context, new MaterialPageRoute( - builder: (BuildContext _context) => new FullScreenCodeDialog(exampleCodeTag: tag) - )); - } - } - - void _showApiDocumentation(BuildContext context) { - string url = this.demos[DefaultTabController.of(context).index].documentationUrl; - if (url != null) { - Application.OpenURL(url); - } - } - - public override Widget build(BuildContext context) { - List actions = this.actions ?? new List { }; - actions.AddRange( - new List { - new Builder( - builder: (BuildContext _context) => { - return new IconButton( - icon: new Icon(Icons.library_books), - onPressed: () => this._showApiDocumentation(_context) - ); - } - ), - new Builder( - builder: (BuildContext _context) => { - return new IconButton( - icon: new Icon(Icons.code), - tooltip: "Show example code", - onPressed: () => this._showExampleCode(_context) - ); - } - ) - } - ); - return new DefaultTabController( - length: this.demos.Count, - child: new Scaffold( - appBar: new AppBar( - title: new Text(this.title), - actions: actions, - bottom: new TabBar( - isScrollable: true, - tabs: this.demos.Select( - (ComponentDemoTabData data) => new Tab(text: data.tabName)) - .ToList() - ) - ), - body: new TabBarView( - children: this.demos.Select((ComponentDemoTabData demo) => { - return new SafeArea( - top: false, - bottom: false, - child: new Column( - children: new List { - new Padding( - padding: EdgeInsets.all(16.0f), - child: new Text(demo.description, - style: Theme.of(context).textTheme.subhead - ) - ), - new Expanded(child: demo.demoWidget) - } - ) - ); - }).ToList() - ) - ) - ); - } - } - - - public class FullScreenCodeDialog : StatefulWidget { - public FullScreenCodeDialog(Key key = null, string exampleCodeTag = null) : base(key: key) { - this.exampleCodeTag = exampleCodeTag; - } - - public readonly string exampleCodeTag; - - public override State createState() { - return new FullScreenCodeDialogState(); - } - } - - public class FullScreenCodeDialogState : State { - public FullScreenCodeDialogState() { - } - - string _exampleCode; - - public override void didChangeDependencies() { - base.didChangeDependencies(); - string code = - new ExampleCodeParser().getExampleCode(this.widget.exampleCodeTag, DefaultAssetBundle.of(this.context)); - if (this.mounted) { - this.setState(() => { this._exampleCode = code; }); - } - } - - public override Widget build(BuildContext context) { - SyntaxHighlighterStyle style = Theme.of(context).brightness == Brightness.dark - ? SyntaxHighlighterStyle.darkThemeStyle() - : SyntaxHighlighterStyle.lightThemeStyle(); - - Widget body; - if (this._exampleCode == null) { - body = new Center( - child: new CircularProgressIndicator() - ); - } - else { - body = new SingleChildScrollView( - child: new Padding( - padding: EdgeInsets.all(16.0f), - child: new RichText( - text: new TextSpan( - style: new TextStyle(fontFamily: "monospace", fontSize: 10.0f), - children: new List { - new DartSyntaxHighlighter(style).format(this._exampleCode) - } - ) - ) - ) - ); - } - - return new Scaffold( - appBar: new AppBar( - leading: new IconButton( - icon: new Icon( - Icons.clear - ), - onPressed: () => { Navigator.pop(context); } - ), - title: new Text("Example code") - ), - body: body - ); - } - } - - class MaterialDemoDocumentationButton : StatelessWidget { - public MaterialDemoDocumentationButton(string routeName, Key key = null) : base(key: key) { - this.documentationUrl = DemoUtils.kDemoDocumentationUrl[routeName]; - D.assert(DemoUtils.kDemoDocumentationUrl[routeName] != null, - () => $"A documentation URL was not specified for demo route {routeName} in kAllGalleryDemos" - ); - } - - - public readonly string documentationUrl; - - public override Widget build(BuildContext context) { - return new IconButton( - icon: new Icon(Icons.library_books), - tooltip: "API documentation", - onPressed: () => Application.OpenURL(this.documentationUrl) - ); - } - } -} \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/gallery/demo.cs.meta b/Samples/UIWidgetsGallery/gallery/demo.cs.meta deleted file mode 100644 index 4238ae2e..00000000 --- a/Samples/UIWidgetsGallery/gallery/demo.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 3c8404e1b03d43aba2e91d19f124de5e -timeCreated: 1552462303 \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/gallery/demos.cs b/Samples/UIWidgetsGallery/gallery/demos.cs deleted file mode 100644 index e4fb1b73..00000000 --- a/Samples/UIWidgetsGallery/gallery/demos.cs +++ /dev/null @@ -1,611 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Unity.UIWidgets.foundation; -using Unity.UIWidgets.material; -using Unity.UIWidgets.widgets; - -namespace UIWidgetsGallery.gallery { - public class GalleryDemoCategory : IEquatable { - public GalleryDemoCategory(string name = null, IconData icon = null) { - D.assert(name != null); - D.assert(icon != null); - - this.name = name; - this.icon = icon; - } - - public readonly string name; - - public readonly IconData icon; - - public bool Equals(GalleryDemoCategory other) { - if (ReferenceEquals(null, other)) { - return false; - } - if (ReferenceEquals(this, other)) { - return true; - } - return string.Equals(this.name, other.name) && Equals(this.icon, other.icon); - } - - public override bool Equals(object obj) { - if (ReferenceEquals(null, obj)) { - return false; - } - if (ReferenceEquals(this, obj)) { - return true; - } - if (obj.GetType() != this.GetType()) { - return false; - } - return this.Equals((GalleryDemoCategory) obj); - } - - public override int GetHashCode() { - unchecked { - return ((this.name != null ? this.name.GetHashCode() : 0) * 397) ^ - (this.icon != null ? this.icon.GetHashCode() : 0); - } - } - - public static bool operator ==(GalleryDemoCategory left, GalleryDemoCategory right) { - return Equals(left, right); - } - - public static bool operator !=(GalleryDemoCategory left, GalleryDemoCategory right) { - return !Equals(left, right); - } - - public override string ToString() { - return $"{this.GetType()}({this.name})"; - } - } - - public static partial class DemoUtils { - internal static readonly GalleryDemoCategory _kDemos = new GalleryDemoCategory( - name: "Studies", - icon: GalleryIcons.animation - ); - - internal static readonly GalleryDemoCategory _kStyle = new GalleryDemoCategory( - name: "Style", - icon: GalleryIcons.custom_typography - ); - - internal static readonly GalleryDemoCategory _kMaterialComponents = new GalleryDemoCategory( - name: "Material", - icon: GalleryIcons.category_mdc - ); - - internal static readonly GalleryDemoCategory _kCupertinoComponents = new GalleryDemoCategory( - name: "Cupertino", - icon: GalleryIcons.phone_iphone - ); - - internal static readonly GalleryDemoCategory _kMedia = new GalleryDemoCategory( - name: "Media", - icon: GalleryIcons.drive_video - ); - } - - public class GalleryDemo { - public GalleryDemo( - string title = null, - IconData icon = null, - string subtitle = null, - GalleryDemoCategory category = null, - string routeName = null, - string documentationUrl = null, - WidgetBuilder buildRoute = null - ) { - D.assert(title != null); - D.assert(icon != null); - D.assert(category != null); - D.assert(routeName != null); - D.assert(buildRoute != null); - this.title = title; - this.icon = icon; - this.subtitle = subtitle; - this.category = category; - this.routeName = routeName; - this.documentationUrl = documentationUrl; - this.buildRoute = buildRoute; - } - - public readonly string title; - public readonly IconData icon; - public readonly string subtitle; - public readonly GalleryDemoCategory category; - public readonly string routeName; - public readonly string documentationUrl; - public readonly WidgetBuilder buildRoute; - - public override string ToString() { - return $"{this.GetType()}({this.title} {this.routeName})"; - } - - } - - public static partial class DemoUtils { - static List _buildGalleryDemos() { - List galleryDemos = new List { - // Demos - new GalleryDemo( - title: "Shrine", - subtitle: "Basic shopping app", - icon: GalleryIcons.shrine, - category: DemoUtils._kDemos, - routeName: ShrineDemo.routeName, - buildRoute: (BuildContext context) => new ShrineDemo() - ), - new GalleryDemo( - title: "Contact profile", - subtitle: "Address book entry with a flexible appbar", - icon: GalleryIcons.account_box, - category: DemoUtils._kDemos, - routeName: ContactsDemo.routeName, - buildRoute: (BuildContext context) => new ContactsDemo() - ), - new GalleryDemo( - title: "Animation", - subtitle: "Section organizer", - icon: GalleryIcons.animation, - category: DemoUtils._kDemos, - routeName: AnimationDemo.routeName, - buildRoute: (BuildContext context) => new AnimationDemo() - ), - - // Style - new GalleryDemo( - title: "Colors", - subtitle: "All of the predefined colors", - icon: GalleryIcons.colors, - category: DemoUtils._kStyle, - routeName: ColorsDemo.routeName, - buildRoute: (BuildContext context) => new ColorsDemo() - ), - new GalleryDemo( - title: "Typography", - subtitle: "All of the predefined text styles", - icon: GalleryIcons.custom_typography, - category: DemoUtils._kStyle, - routeName: TypographyDemo.routeName, - buildRoute: (BuildContext context) => new TypographyDemo() - ), - - // Material Components - new GalleryDemo( - title: "Backdrop", - subtitle: "Select a front layer from back layer", - icon: GalleryIcons.backdrop, - category: DemoUtils._kMaterialComponents, - routeName: BackdropDemo.routeName, - buildRoute: (BuildContext context) => new BackdropDemo() - ), - new GalleryDemo( - title: "Bottom app bar", - subtitle: "Optional floating action button notch", - icon: GalleryIcons.bottom_app_bar, - category: DemoUtils._kMaterialComponents, - routeName: BottomAppBarDemo.routeName, - documentationUrl: "https://docs.flutter.io/flutter/material/BottomAppBar-class.html", - buildRoute: (BuildContext context) => new BottomAppBarDemo() - ), - new GalleryDemo( - title: "Bottom navigation", - subtitle: "Bottom navigation with cross-fading views", - icon: GalleryIcons.bottom_navigation, - category: DemoUtils._kMaterialComponents, - routeName: BottomNavigationDemo.routeName, - documentationUrl: "https://docs.flutter.io/flutter/material/BottomNavigationBar-class.html", - buildRoute: (BuildContext context) => new BottomNavigationDemo() - ), - new GalleryDemo( - title: "Bottom sheet: Modal", - subtitle: "A dismissable bottom sheet", - icon: GalleryIcons.bottom_sheets, - category: _kMaterialComponents, - routeName: ModalBottomSheetDemo.routeName, - documentationUrl: "https://docs.flutter.io/flutter/material/showModalBottomSheet.html", - buildRoute: (BuildContext context) => new ModalBottomSheetDemo() - ), - new GalleryDemo( - title: "Bottom sheet: Persistent", - subtitle: "A bottom sheet that sticks around", - icon: GalleryIcons.bottom_sheet_persistent, - category: _kMaterialComponents, - routeName: PersistentBottomSheetDemo.routeName, - documentationUrl: "https://docs.flutter.io/flutter/material/ScaffoldState/showBottomSheet.html", - buildRoute: (BuildContext context) => new PersistentBottomSheetDemo() - ), - new GalleryDemo( - title: "Buttons", - subtitle: "Flat, raised, dropdown, and more", - icon: GalleryIcons.generic_buttons, - category: DemoUtils._kMaterialComponents, - routeName: ButtonsDemo.routeName, - buildRoute: (BuildContext context) => new ButtonsDemo() - ), - new GalleryDemo( - title: "Buttons: Floating Action Button", - subtitle: "FAB with transitions", - icon: GalleryIcons.buttons, - category: _kMaterialComponents, - routeName: TabsFabDemo.routeName, - documentationUrl: "https://docs.flutter.io/flutter/material/FloatingActionButton-class.html", - buildRoute: (BuildContext context) => new TabsFabDemo() - ), - new GalleryDemo( - title: "Cards", - subtitle: "Baseline cards with rounded corners", - icon: GalleryIcons.cards, - category: DemoUtils._kMaterialComponents, - routeName: CardsDemo.routeName, - documentationUrl: "https://docs.flutter.io/flutter/material/Card-class.html", - buildRoute: (BuildContext context) => new CardsDemo() - ), - new GalleryDemo( - title: "Chips", - subtitle: "Labeled with delete buttons and avatars", - icon: GalleryIcons.chips, - category: _kMaterialComponents, - routeName: ChipDemo.routeName, - documentationUrl: "https://docs.flutter.io/flutter/material/Chip-class.html", - buildRoute: (BuildContext context) => new ChipDemo() - ), -// new GalleryDemo( -// title: "Data tables", -// subtitle: "Rows and columns", -// icon: GalleryIcons.data_table, -// category: GalleryDemoCategory._kMaterialComponents, -// routeName: DataTableDemo.routeName, -// documentationUrl: "https://docs.flutter.io/flutter/material/PaginatedDataTable-class.html", -// buildRoute: (BuildContext context) => DataTableDemo() -// ), -// new GalleryDemo( -// title: "Dialogs", -// subtitle: "Simple, alert, and fullscreen", -// icon: GalleryIcons.dialogs, -// category: GalleryDemoCategory._kMaterialComponents, -// routeName: DialogDemo.routeName, -// documentationUrl: "https://docs.flutter.io/flutter/material/showDialog.html", -// buildRoute: (BuildContext context) => DialogDemo() -// ), -// new GalleryDemo( -// title: "Elevations", -// subtitle: "Shadow values on cards", -// // TODO(larche): Change to custom icon for elevations when one exists. -// icon: GalleryIcons.cupertino_progress, -// category: GalleryDemoCategory._kMaterialComponents, -// routeName: ElevationDemo.routeName, -// documentationUrl: "https://docs.flutter.io/flutter/material/Material/elevation.html", -// buildRoute: (BuildContext context) => ElevationDemo() -// ), -// new GalleryDemo( -// title: "Expand/collapse list control", -// subtitle: "A list with one sub-list level", -// icon: GalleryIcons.expand_all, -// category: GalleryDemoCategory._kMaterialComponents, -// routeName: TwoLevelListDemo.routeName, -// documentationUrl: "https://docs.flutter.io/flutter/material/ExpansionTile-class.html", -// buildRoute: (BuildContext context) => TwoLevelListDemo() -// ), -// new GalleryDemo( -// title: "Expansion panels", -// subtitle: "List of expanding panels", -// icon: GalleryIcons.expand_all, -// category: GalleryDemoCategory._kMaterialComponents, -// routeName: ExpansionPanelsDemo.routeName, -// documentationUrl: "https://docs.flutter.io/flutter/material/ExpansionPanel-class.html", -// buildRoute: (BuildContext context) => ExpansionPanelsDemo() -// ), -// new GalleryDemo( -// title: "Grid", -// subtitle: "Row and column layout", -// icon: GalleryIcons.grid_on, -// category: GalleryDemoCategory._kMaterialComponents, -// routeName: GridListDemo.routeName, -// documentationUrl: "https://docs.flutter.io/flutter/widgets/GridView-class.html", -// buildRoute: (BuildContext context) => new GridListDemo() -// ), -// new GalleryDemo( -// title: "Icons", -// subtitle: "Enabled and disabled icons with opacity", -// icon: GalleryIcons.sentiment_very_satisfied, -// category: GalleryDemoCategory._kMaterialComponents, -// routeName: IconsDemo.routeName, -// documentationUrl: "https://docs.flutter.io/flutter/material/IconButton-class.html", -// buildRoute: (BuildContext context) => IconsDemo() -// ), -// new GalleryDemo( -// title: "Lists", -// subtitle: "Scrolling list layouts", -// icon: GalleryIcons.list_alt, -// category: GalleryDemoCategory._kMaterialComponents, -// routeName: ListDemo.routeName, -// documentationUrl: "https://docs.flutter.io/flutter/material/ListTile-class.html", -// buildRoute: (BuildContext context) => new ListDemo() -// ), -// new GalleryDemo( -// title: "Lists: leave-behind list items", -// subtitle: "List items with hidden actions", -// icon: GalleryIcons.lists_leave_behind, -// category: GalleryDemoCategory._kMaterialComponents, -// routeName: LeaveBehindDemo.routeName, -// documentationUrl: "https://docs.flutter.io/flutter/widgets/Dismissible-class.html", -// buildRoute: (BuildContext context) => new LeaveBehindDemo() -// ), -// new GalleryDemo( -// title: "Lists: reorderable", -// subtitle: "Reorderable lists", -// icon: GalleryIcons.list_alt, -// category: GalleryDemoCategory._kMaterialComponents, -// routeName: ReorderableListDemo.routeName, -// documentationUrl: "https://docs.flutter.io/flutter/material/ReorderableListView-class.html", -// buildRoute: (BuildContext context) => new ReorderableListDemo() -// ), -// new GalleryDemo( -// title: "Menus", -// subtitle: "Menu buttons and simple menus", -// icon: GalleryIcons.more_vert, -// category: GalleryDemoCategory._kMaterialComponents, -// routeName: MenuDemo.routeName, -// documentationUrl: "https://docs.flutter.io/flutter/material/PopupMenuButton-class.html", -// buildRoute: (BuildContext context) => new MenuDemo() -// ), -// new GalleryDemo( -// title: "Navigation drawer", -// subtitle: "Navigation drawer with standard header", -// icon: GalleryIcons.menu, -// category: GalleryDemoCategory._kMaterialComponents, -// routeName: DrawerDemo.routeName, -// documentationUrl: "https://docs.flutter.io/flutter/material/Drawer-class.html", -// buildRoute: (BuildContext context) => DrawerDemo() -// ), -// new GalleryDemo( -// title: "Pagination", -// subtitle: "PageView with indicator", -// icon: GalleryIcons.page_control, -// category: GalleryDemoCategory._kMaterialComponents, -// routeName: PageSelectorDemo.routeName, -// documentationUrl: "https://docs.flutter.io/flutter/material/TabBarView-class.html", -// buildRoute: (BuildContext context) => PageSelectorDemo() -// ), -// new GalleryDemo( -// title: "Pickers", -// subtitle: "Date and time selection widgets", -// icon: GalleryIcons.@event, -// category: GalleryDemoCategory._kMaterialComponents, -// routeName: DateAndTimePickerDemo.routeName, -// documentationUrl: "https://docs.flutter.io/flutter/material/showDatePicker.html", -// buildRoute: (BuildContext context) => DateAndTimePickerDemo() -// ), -// new GalleryDemo( -// title: "Progress indicators", -// subtitle: "Linear, circular, indeterminate", -// icon: GalleryIcons.progress_activity, -// category: GalleryDemoCategory._kMaterialComponents, -// routeName: ProgressIndicatorDemo.routeName, -// documentationUrl: "https://docs.flutter.io/flutter/material/LinearProgressIndicator-class.html", -// buildRoute: (BuildContext context) => ProgressIndicatorDemo() -// ), -// new GalleryDemo( -// title: "Pull to refresh", -// subtitle: "Refresh indicators", -// icon: GalleryIcons.refresh, -// category: GalleryDemoCategory._kMaterialComponents, -// routeName: OverscrollDemo.routeName, -// documentationUrl: "https://docs.flutter.io/flutter/material/RefreshIndicator-class.html", -// buildRoute: (BuildContext context) => OverscrollDemo() -// ), -// new GalleryDemo( -// title: "Search", -// subtitle: "Expandable search", -// icon: Icons.search, -// category: GalleryDemoCategory._kMaterialComponents, -// routeName: SearchDemo.routeName, -// documentationUrl: "https://docs.flutter.io/flutter/material/showSearch.html", -// buildRoute: (BuildContext context) => SearchDemo() -// ), -// new GalleryDemo( -// title: "Selection controls", -// subtitle: "Checkboxes, radio buttons, and switches", -// icon: GalleryIcons.check_box, -// category: GalleryDemoCategory._kMaterialComponents, -// routeName: SelectionControlsDemo.routeName, -// buildRoute: (BuildContext context) => SelectionControlsDemo() -// ), -// new GalleryDemo( -// title: "Sliders", -// subtitle: "Widgets for selecting a value by swiping", -// icon: GalleryIcons.sliders, -// category: GalleryDemoCategory._kMaterialComponents, -// routeName: SliderDemo.routeName, -// documentationUrl: "https://docs.flutter.io/flutter/material/Slider-class.html", -// buildRoute: (BuildContext context) => SliderDemo() -// ), -// new GalleryDemo( -// title: "Snackbar", -// subtitle: "Temporary messaging", -// icon: GalleryIcons.snackbar, -// category: GalleryDemoCategory._kMaterialComponents, -// routeName: SnackBarDemo.routeName, -// documentationUrl: "https://docs.flutter.io/flutter/material/ScaffoldState/showSnackBar.html", -// buildRoute: (BuildContext context) => SnackBarDemo() -// ), -// new GalleryDemo( -// title: "Tabs", -// subtitle: "Tabs with independently scrollable views", -// icon: GalleryIcons.tabs, -// category: GalleryDemoCategory._kMaterialComponents, -// routeName: TabsDemo.routeName, -// documentationUrl: "https://docs.flutter.io/flutter/material/TabBarView-class.html", -// buildRoute: (BuildContext context) => TabsDemo() -// ), -// new GalleryDemo( -// title: "Tabs: Scrolling", -// subtitle: "Tab bar that scrolls", -// category: GalleryDemoCategory._kMaterialComponents, -// icon: GalleryIcons.tabs, -// routeName: ScrollableTabsDemo.routeName, -// documentationUrl: "https://docs.flutter.io/flutter/material/TabBar-class.html", -// buildRoute: (BuildContext context) => ScrollableTabsDemo() -// ), -// new GalleryDemo( -// title: "Text fields", -// subtitle: "Single line of editable text and numbers", -// icon: GalleryIcons.text_fields_alt, -// category: GalleryDemoCategory._kMaterialComponents, -// routeName: TextFormFieldDemo.routeName, -// documentationUrl: "https://docs.flutter.io/flutter/material/TextFormField-class.html", -// buildRoute: (BuildContext context) => const TextFormFieldDemo() -// ), -// new GalleryDemo( -// title: "Tooltips", -// subtitle: "Short message displayed on long-press", -// icon: GalleryIcons.tooltip, -// category: GalleryDemoCategory._kMaterialComponents, -// routeName: TooltipDemo.routeName, -// documentationUrl: "https://docs.flutter.io/flutter/material/Tooltip-class.html", -// buildRoute: (BuildContext context) => TooltipDemo() -// ), -// -// // Cupertino Components -// new GalleryDemo( -// title: "Activity Indicator", -// icon: GalleryIcons.cupertino_progress, -// category: GalleryDemoCategory._kCupertinoComponents, -// routeName: CupertinoProgressIndicatorDemo.routeName, -// documentationUrl: "https://docs.flutter.io/flutter/cupertino/CupertinoActivityIndicator-class.html", -// buildRoute: (BuildContext context) => CupertinoProgressIndicatorDemo() -// ), -// new GalleryDemo( -// title: "Alerts", -// icon: GalleryIcons.dialogs, -// category: GalleryDemoCategory._kCupertinoComponents, -// routeName: CupertinoAlertDemo.routeName, -// documentationUrl: "https://docs.flutter.io/flutter/cupertino/showCupertinoDialog.html", -// buildRoute: (BuildContext context) => CupertinoAlertDemo() -// ), -// new GalleryDemo( -// title: "Buttons", -// icon: GalleryIcons.generic_buttons, -// category: GalleryDemoCategory._kCupertinoComponents, -// routeName: CupertinoButtonsDemo.routeName, -// documentationUrl: "https://docs.flutter.io/flutter/cupertino/CupertinoButton-class.html", -// buildRoute: (BuildContext context) => CupertinoButtonsDemo() -// ), -// new GalleryDemo( -// title: "Navigation", -// icon: GalleryIcons.bottom_navigation, -// category: GalleryDemoCategory._kCupertinoComponents, -// routeName: CupertinoNavigationDemo.routeName, -// documentationUrl: "https://docs.flutter.io/flutter/cupertino/CupertinoTabScaffold-class.html", -// buildRoute: (BuildContext context) => CupertinoNavigationDemo() -// ), -// new GalleryDemo( -// title: "Pickers", -// icon: GalleryIcons.@event, -// category: GalleryDemoCategory._kCupertinoComponents, -// routeName: CupertinoPickerDemo.routeName, -// documentationUrl: "https://docs.flutter.io/flutter/cupertino/CupertinoPicker-class.html", -// buildRoute: (BuildContext context) => CupertinoPickerDemo() -// ), -// new GalleryDemo( -// title: "Pull to refresh", -// icon: GalleryIcons.cupertino_pull_to_refresh, -// category: _kCupertinoComponents, -// routeName: CupertinoRefreshControlDemo.routeName, -// documentationUrl: -// "https://docs.flutter.io/flutter/cupertino/CupertinoSliverRefreshControl-class.html", -// buildRoute: (BuildContext context) => CupertinoRefreshControlDemo() -// ), -// new GalleryDemo( -// title: "Segmented Control", -// icon: GalleryIcons.tabs, -// category: GalleryDemoCategory._kCupertinoComponents, -// routeName: CupertinoSegmentedControlDemo.routeName, -// documentationUrl: "https://docs.flutter.io/flutter/cupertino/CupertinoSegmentedControl-class.html", -// buildRoute: (BuildContext context) => CupertinoSegmentedControlDemo() -// ), -// new GalleryDemo( -// title: "Sliders", -// icon: GalleryIcons.sliders, -// category: GalleryDemoCategory._kCupertinoComponents, -// routeName: CupertinoSliderDemo.routeName, -// documentationUrl: "https://docs.flutter.io/flutter/cupertino/CupertinoSlider-class.html", -// buildRoute: (BuildContext context) => CupertinoSliderDemo() -// ), -// new GalleryDemo( -// title: "Switches", -// icon: GalleryIcons.cupertino_switch, -// category: GalleryDemoCategory._kCupertinoComponents, -// routeName: CupertinoSwitchDemo.routeName, -// documentationUrl: "https://docs.flutter.io/flutter/cupertino/CupertinoSwitch-class.html", -// buildRoute: (BuildContext context) => CupertinoSwitchDemo() -// ), -// new GalleryDemo( -// title: "Text Fields", -// icon: GalleryIcons.text_fields_alt, -// category: GalleryDemoCategory._kCupertinoComponents, -// routeName: CupertinoTextFieldDemo.routeName, -// buildRoute: (BuildContext context) => CupertinoTextFieldDemo() -// ), -// -// // Media -// new GalleryDemo( -// title: "Animated images", -// subtitle: "GIF and WebP animations", -// icon: GalleryIcons.animation, -// category: GalleryDemoCategory._kMedia, -// routeName: ImagesDemo.routeName, -// buildRoute: (BuildContext context) => ImagesDemo() -// ), -// new GalleryDemo( -// title: "Video", -// subtitle: "Video playback", -// icon: GalleryIcons.drive_video, -// category: GalleryDemoCategory._kMedia, -// routeName: VideoDemo.routeName, -// buildRoute: (BuildContext context) => new VideoDemo() -// ), - }; - - // Keep Pesto around for its regression test value. It is not included - // in (release builds) the performance tests. - D.assert(() => { -// galleryDemos.Insert(0, -// new GalleryDemo( -// title: "Pesto", -// subtitle: "Simple recipe browser", -// icon: Icons.adjust, -// category: GalleryDemoCategory._kDemos, -// routeName: PestoDemo.routeName, -// buildRoute: (BuildContext context) => new PestoDemo() -// ) -// ); - return true; - }); - - return galleryDemos; - } - - public static readonly List kAllGalleryDemos = _buildGalleryDemos(); - - public static readonly HashSet kAllGalleryDemoCategories = - new HashSet(kAllGalleryDemos.Select(demo => demo.category)); - - public static readonly Dictionary> kGalleryCategoryToDemos = - kAllGalleryDemoCategories.ToDictionary( - category => category, - category => kAllGalleryDemos.Where(demo => demo.category == category).ToList() - ); - - public static readonly Dictionary kDemoDocumentationUrl = - kAllGalleryDemos.Where(demo => demo.documentationUrl != null).ToDictionary( - demo => demo.routeName, - demo => demo.documentationUrl - ); - } -} diff --git a/Samples/UIWidgetsGallery/gallery/demos.cs.meta b/Samples/UIWidgetsGallery/gallery/demos.cs.meta deleted file mode 100644 index 3c90e06e..00000000 --- a/Samples/UIWidgetsGallery/gallery/demos.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: b079397083e3d41bb83262e1423dfa25 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetsGallery/gallery/example_code_parser.cs b/Samples/UIWidgetsGallery/gallery/example_code_parser.cs deleted file mode 100644 index 035e0bb0..00000000 --- a/Samples/UIWidgetsGallery/gallery/example_code_parser.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using RSG; -using Unity.UIWidgets.foundation; -using UnityEngine; - -namespace UIWidgetsGallery.gallery { - - public class ExampleCodeParser { - const string _kStartTag = "// START "; - const string _kEndTag = "// END"; - - Dictionary _exampleCode; - - public string getExampleCode(string tag, AssetBundle bundle) { - if (this._exampleCode == null) { - this._parseExampleCode(bundle); - } - return this._exampleCode.getOrDefault(tag); - } - - void _parseExampleCode(AssetBundle bundle) { - string code = Resources.Load("example_code.cs")?.text ?? - "// example_code.cs not found\n"; - this._exampleCode = new Dictionary{}; - - List lines = code.Split('\n').ToList(); - - List codeBlock = null; - string codeTag = null; - - foreach (string line in lines) { - if (codeBlock == null) { - if (line.StartsWith(_kStartTag)) { - codeBlock = new List(); - codeTag = line.Substring(_kStartTag.Length).Trim(); - } else { - } - } else { - if (line.StartsWith(_kEndTag)) { - this._exampleCode[codeTag] = string.Join("\n", codeBlock); - codeBlock = null; - codeTag = null; - } else { - codeBlock.Add(line.TrimEnd()); - } - } - } - } - } - -} \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/gallery/example_code_parser.cs.meta b/Samples/UIWidgetsGallery/gallery/example_code_parser.cs.meta deleted file mode 100644 index 495edbb1..00000000 --- a/Samples/UIWidgetsGallery/gallery/example_code_parser.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 57879fd6125746699974c2e0bc8762b8 -timeCreated: 1552468268 \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/gallery/home.cs b/Samples/UIWidgetsGallery/gallery/home.cs deleted file mode 100644 index 141fc17c..00000000 --- a/Samples/UIWidgetsGallery/gallery/home.cs +++ /dev/null @@ -1,406 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using RSG; -using Unity.UIWidgets.animation; -using Unity.UIWidgets.foundation; -using Unity.UIWidgets.material; -using Unity.UIWidgets.painting; -using Unity.UIWidgets.rendering; -using Unity.UIWidgets.service; -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; -using UnityEngine; -using Color = Unity.UIWidgets.ui.Color; - -namespace UIWidgetsGallery.gallery { - public static class HomeUtils { - internal static readonly Color _kUIWidgetsBlue = new Color(0xFF003D75); - internal const float _kDemoItemHeight = 64.0f; - internal static TimeSpan _kFrontLayerSwitchDuration = new TimeSpan(0, 0, 0, 0, 300); - } - - class _UIWidgetsLogo : StatelessWidget { - public _UIWidgetsLogo(Key key = null, bool isDark = false) : base(key: key) { - this._isDark = isDark; - } - - readonly bool _isDark; - - public override Widget build(BuildContext context) { - return new Center( - child: new Container( - width: 34.0f, - height: 34.0f, - decoration: new BoxDecoration( - image: new DecorationImage( - image: new AssetImage( - this._isDark ? "unity-black" : "unity-white") - ) - ) - ) - ); - } - } - - class _CategoryItem : StatelessWidget { - public _CategoryItem( - Key key = null, - GalleryDemoCategory category = null, - VoidCallback onTap = null - ) : base(key: key) { - this.category = category; - this.onTap = onTap; - } - - public readonly GalleryDemoCategory category; - - public readonly VoidCallback onTap; - - public override Widget build(BuildContext context) { - ThemeData theme = Theme.of(context); - bool isDark = theme.brightness == Brightness.dark; - - return new RepaintBoundary( - child: new RawMaterialButton( - padding: EdgeInsets.zero, - splashColor: theme.primaryColor.withOpacity(0.12f), - highlightColor: Colors.transparent, - onPressed: this.onTap, - child: new Column( - mainAxisAlignment: MainAxisAlignment.end, - crossAxisAlignment: CrossAxisAlignment.center, - children: new List { - new Padding( - padding: EdgeInsets.all(6.0f), - child: new Icon( - this.category.icon, - size: 60.0f, - color: isDark ? Colors.white : HomeUtils._kUIWidgetsBlue - ) - ), - new SizedBox(height: 10.0f), - new Container( - height: 48.0f, - alignment: Alignment.center, - child: new Text( - this.category.name, - textAlign: TextAlign.center, - style: theme.textTheme.subhead.copyWith( - fontFamily: "GoogleSans", - color: isDark ? Colors.white : HomeUtils._kUIWidgetsBlue - ) - ) - ) - } - ) - ) - ); - } - } - - class _CategoriesPage : StatelessWidget { - public _CategoriesPage( - Key key = null, - IEnumerable categories = null, - ValueChanged onCategoryTap = null - ) : base(key: key) { - this.categories = categories; - this.onCategoryTap = onCategoryTap; - } - - public readonly IEnumerable categories; - - public readonly ValueChanged onCategoryTap; - - public override Widget build(BuildContext context) { - float aspectRatio = 160.0f / 180.0f; - List categoriesList = this.categories.ToList(); - int columnCount = (MediaQuery.of(context).orientation == Orientation.portrait) ? 2 : 3; - - return new SingleChildScrollView( - key: new PageStorageKey("categories"), - child: new LayoutBuilder( - builder: (_, constraints) => { - float columnWidth = constraints.biggest.width / columnCount; - float rowHeight = Mathf.Min(225.0f, columnWidth * aspectRatio); - int rowCount = (categoriesList.Count + columnCount - 1) / columnCount; - - return new RepaintBoundary( - child: new Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: Enumerable.Range(0, rowCount).Select(rowIndex => { - int columnCountForRow = rowIndex == rowCount - 1 - ? categoriesList.Count - columnCount * Mathf.Max(0, rowCount - 1) - : columnCount; - - return (Widget) new Row( - children: Enumerable.Range(0, columnCountForRow).Select(columnIndex => { - int index = rowIndex * columnCount + columnIndex; - GalleryDemoCategory category = categoriesList[index]; - - return (Widget) new SizedBox( - width: columnWidth, - height: rowHeight, - child: new _CategoryItem( - category: category, - onTap: () => { this.onCategoryTap(category); } - ) - ); - }).ToList() - ); - }).ToList() - ) - ); - } - ) - ); - } - } - - class _DemoItem : StatelessWidget { - public _DemoItem(Key key = null, GalleryDemo demo = null) : base(key: key) { - this.demo = demo; - } - - public readonly GalleryDemo demo; - - void _launchDemo(BuildContext context) { - if (this.demo.routeName != null) { - Navigator.pushNamed(context, this.demo.routeName); - } - } - - public override Widget build(BuildContext context) { - ThemeData theme = Theme.of(context); - bool isDark = theme.brightness == Brightness.dark; - float textScaleFactor = MediaQuery.textScaleFactorOf(context); - - List titleChildren = new List { - new Text( - this.demo.title, - style: theme.textTheme.subhead.copyWith( - color: isDark ? Colors.white : new Color(0xFF202124) - ) - ), - }; - - if (this.demo.subtitle != null) { - titleChildren.Add( - new Text( - this.demo.subtitle, - style: theme.textTheme.body1.copyWith( - color: isDark ? Colors.white : new Color(0xFF60646B) - ) - ) - ); - } - - return new RawMaterialButton( - padding: EdgeInsets.zero, - splashColor: theme.primaryColor.withOpacity(0.12f), - highlightColor: Colors.transparent, - onPressed: () => { this._launchDemo(context); }, - child: new Container( - constraints: new BoxConstraints(minHeight: HomeUtils._kDemoItemHeight * textScaleFactor), - child: new Row( - children: new List { - new Container( - width: 56.0f, - height: 56.0f, - alignment: Alignment.center, - child: new Icon( - this.demo.icon, - size: 24.0f, - color: isDark ? Colors.white : HomeUtils._kUIWidgetsBlue - ) - ), - new Expanded( - child: new Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: titleChildren - ) - ), - new SizedBox(width: 44.0f), - } - ) - ) - ); - } - } - - class _DemosPage : StatelessWidget { - public _DemosPage(GalleryDemoCategory category) { - this.category = category; - } - - public readonly GalleryDemoCategory category; - - public override Widget build(BuildContext context) { - float windowBottomPadding = MediaQuery.of(context).padding.bottom; - return new KeyedSubtree( - key: new ValueKey("GalleryDemoList"), - child: new ListView( - key: new PageStorageKey(this.category.name), - padding: EdgeInsets.only(top: 8.0f, bottom: windowBottomPadding), - children: DemoUtils.kGalleryCategoryToDemos[this.category] - .Select(demo => (Widget) new _DemoItem(demo: demo)).ToList() - ) - ); - } - } - - public class GalleryHome : StatefulWidget { - public GalleryHome( - Key key = null, - bool testMode = false, - Widget optionsPage = null, - GalleryOptions options = null - ) : base(key: key) { - this.testMode = testMode; - this.optionsPage = optionsPage; - this.options = options; - } - - public readonly Widget optionsPage; - public readonly bool testMode; - public readonly GalleryOptions options; - - public static bool showPreviewBanner = true; - - public override State createState() { - return new _GalleryHomeState(); - } - } - - class _GalleryHomeState : SingleTickerProviderStateMixin { - readonly GlobalKey _scaffoldKey = GlobalKey.key(); - AnimationController _controller; - GalleryDemoCategory _category; - - static Widget _topHomeLayout(Widget currentChild, List previousChildren) { - List children = previousChildren; - if (currentChild != null) { - children = children.ToList(); - children.Add(currentChild); - } - - return new Stack( - children: children, - alignment: Alignment.topCenter - ); - } - - public static AnimatedSwitcherLayoutBuilder _centerHomeLayout = AnimatedSwitcher.defaultLayoutBuilder; - - public override void initState() { - base.initState(); - this._controller = new AnimationController( - duration: new TimeSpan(0, 0, 0, 0, 600), - debugLabel: "preview banner", - vsync: this - ); - this._controller.forward(); - } - - public override void dispose() { - this._controller.dispose(); - base.dispose(); - } - - public override Widget build(BuildContext context) { - ThemeData theme = Theme.of(context); - bool isDark = theme.brightness == Brightness.dark; - MediaQueryData media = MediaQuery.of(context); - bool centerHome = media.orientation == Orientation.portrait && media.size.height < 800.0; - - Curve switchOutCurve = new Interval(0.4f, 1.0f, curve: Curves.fastOutSlowIn); - Curve switchInCurve = new Interval(0.4f, 1.0f, curve: Curves.fastOutSlowIn); - - Widget home = new Scaffold( - key: this._scaffoldKey, - backgroundColor: isDark ? HomeUtils._kUIWidgetsBlue : theme.primaryColor, - body: new SafeArea( - bottom: false, - child: new WillPopScope( - onWillPop: () => { - if (this._category != null) { - this.setState(() => this._category = null); - return Promise.Resolved(false); - } - - return Promise.Resolved(true); - }, - child: new Backdrop( - backTitle: new Text("Options"), - backLayer: this.widget.optionsPage, - frontAction: new AnimatedSwitcher( - duration: HomeUtils._kFrontLayerSwitchDuration, - switchOutCurve: switchOutCurve, - switchInCurve: switchInCurve, - child: this._category == null - ? (Widget) new _UIWidgetsLogo(isDark: this.widget.options?.theme == GalleryTheme.kDarkGalleryTheme) - : new IconButton( - icon: new BackButtonIcon(), - tooltip: "Back", - onPressed: () => this.setState(() => this._category = null) - ) - ), - frontTitle: new AnimatedSwitcher( - duration: HomeUtils._kFrontLayerSwitchDuration, - child: this._category == null - ? new Text("UIWidgets gallery") - : new Text(this._category.name) - ), - frontHeading: this.widget.testMode ? null : new Container(height: 24.0f), - frontLayer: new AnimatedSwitcher( - duration: HomeUtils._kFrontLayerSwitchDuration, - switchOutCurve: switchOutCurve, - switchInCurve: switchInCurve, - layoutBuilder: centerHome ? _centerHomeLayout : _topHomeLayout, - child: this._category != null - ? (Widget) new _DemosPage(this._category) - : new _CategoriesPage( - categories: DemoUtils.kAllGalleryDemoCategories, - onCategoryTap: (GalleryDemoCategory category) => { - this.setState(() => this._category = category); - } - ) - ) - ) - ) - ) - ); - - D.assert(() => { - GalleryHome.showPreviewBanner = false; - return true; - }); - - if (GalleryHome.showPreviewBanner) { - home = new Stack( - fit: StackFit.expand, - children: new List { - home, - new FadeTransition( - opacity: new CurvedAnimation(parent: this._controller, curve: Curves.easeInOut), - child: new Banner( - message: "PREVIEW", - location: BannerLocation.topEnd - ) - ) - } - ); - } - - home = new AnnotatedRegion( - child: home, - value: SystemUiOverlayStyle.light - ); - - return home; - } - } -} \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/gallery/home.cs.meta b/Samples/UIWidgetsGallery/gallery/home.cs.meta deleted file mode 100644 index 69687799..00000000 --- a/Samples/UIWidgetsGallery/gallery/home.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: b6b1570fca0b749e688be67e7bb61a5c -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetsGallery/gallery/icons.cs b/Samples/UIWidgetsGallery/gallery/icons.cs deleted file mode 100644 index 071ae77d..00000000 --- a/Samples/UIWidgetsGallery/gallery/icons.cs +++ /dev/null @@ -1,46 +0,0 @@ -using Unity.UIWidgets.widgets; - -namespace UIWidgetsGallery.gallery { - public static class GalleryIcons { - public static readonly IconData tooltip = new IconData(0xe900, fontFamily: "GalleryIcons"); - public static readonly IconData text_fields_alt = new IconData(0xe901, fontFamily: "GalleryIcons"); - public static readonly IconData tabs = new IconData(0xe902, fontFamily: "GalleryIcons"); - public static readonly IconData switches = new IconData(0xe903, fontFamily: "GalleryIcons"); - public static readonly IconData sliders = new IconData(0xe904, fontFamily: "GalleryIcons"); - public static readonly IconData shrine = new IconData(0xe905, fontFamily: "GalleryIcons"); - public static readonly IconData sentiment_very_satisfied = new IconData(0xe906, fontFamily: "GalleryIcons"); - public static readonly IconData refresh = new IconData(0xe907, fontFamily: "GalleryIcons"); - public static readonly IconData progress_activity = new IconData(0xe908, fontFamily: "GalleryIcons"); - public static readonly IconData phone_iphone = new IconData(0xe909, fontFamily: "GalleryIcons"); - public static readonly IconData page_control = new IconData(0xe90a, fontFamily: "GalleryIcons"); - public static readonly IconData more_vert = new IconData(0xe90b, fontFamily: "GalleryIcons"); - public static readonly IconData menu = new IconData(0xe90c, fontFamily: "GalleryIcons"); - public static readonly IconData list_alt = new IconData(0xe90d, fontFamily: "GalleryIcons"); - public static readonly IconData grid_on = new IconData(0xe90e, fontFamily: "GalleryIcons"); - public static readonly IconData expand_all = new IconData(0xe90f, fontFamily: "GalleryIcons"); - public static readonly IconData @event = new IconData(0xe910, fontFamily: "GalleryIcons"); - public static readonly IconData drive_video = new IconData(0xe911, fontFamily: "GalleryIcons"); - public static readonly IconData dialogs = new IconData(0xe912, fontFamily: "GalleryIcons"); - public static readonly IconData data_table = new IconData(0xe913, fontFamily: "GalleryIcons"); - public static readonly IconData custom_typography = new IconData(0xe914, fontFamily: "GalleryIcons"); - public static readonly IconData colors = new IconData(0xe915, fontFamily: "GalleryIcons"); - public static readonly IconData chips = new IconData(0xe916, fontFamily: "GalleryIcons"); - public static readonly IconData check_box = new IconData(0xe917, fontFamily: "GalleryIcons"); - public static readonly IconData cards = new IconData(0xe918, fontFamily: "GalleryIcons"); - public static readonly IconData buttons = new IconData(0xe919, fontFamily: "GalleryIcons"); - public static readonly IconData bottom_sheets = new IconData(0xe91a, fontFamily: "GalleryIcons"); - public static readonly IconData bottom_navigation = new IconData(0xe91b, fontFamily: "GalleryIcons"); - public static readonly IconData animation = new IconData(0xe91c, fontFamily: "GalleryIcons"); - public static readonly IconData account_box = new IconData(0xe91d, fontFamily: "GalleryIcons"); - public static readonly IconData snackbar = new IconData(0xe91e, fontFamily: "GalleryIcons"); - public static readonly IconData category_mdc = new IconData(0xe91f, fontFamily: "GalleryIcons"); - public static readonly IconData cupertino_progress = new IconData(0xe920, fontFamily: "GalleryIcons"); - public static readonly IconData cupertino_pull_to_refresh = new IconData(0xe921, fontFamily: "GalleryIcons"); - public static readonly IconData cupertino_switch = new IconData(0xe922, fontFamily: "GalleryIcons"); - public static readonly IconData generic_buttons = new IconData(0xe923, fontFamily: "GalleryIcons"); - public static readonly IconData backdrop = new IconData(0xe924, fontFamily: "GalleryIcons"); - public static readonly IconData bottom_app_bar = new IconData(0xe925, fontFamily: "GalleryIcons"); - public static readonly IconData bottom_sheet_persistent = new IconData(0xe926, fontFamily: "GalleryIcons"); - public static readonly IconData lists_leave_behind = new IconData(0xe927, fontFamily: "GalleryIcons"); - } -} diff --git a/Samples/UIWidgetsGallery/gallery/options.cs b/Samples/UIWidgetsGallery/gallery/options.cs deleted file mode 100644 index a3fe3e31..00000000 --- a/Samples/UIWidgetsGallery/gallery/options.cs +++ /dev/null @@ -1,475 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Unity.UIWidgets.foundation; -using Unity.UIWidgets.material; -using Unity.UIWidgets.painting; -using Unity.UIWidgets.rendering; -using Unity.UIWidgets.service; -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; -using UnityEngine; -using Color = Unity.UIWidgets.ui.Color; - -namespace UIWidgetsGallery.gallery { - public class GalleryOptions : IEquatable { - public GalleryOptions( - GalleryTheme theme = null, - GalleryTextScaleValue textScaleFactor = null, - float timeDilation = 1.0f, - RuntimePlatform? platform = null, - bool showOffscreenLayersCheckerboard = false, - bool showRasterCacheImagesCheckerboard = false, - bool showPerformanceOverlay = false - ) { - D.assert(theme != null); - D.assert(textScaleFactor != null); - - this.theme = theme; - this.textScaleFactor = textScaleFactor; - this.timeDilation = timeDilation; - this.platform = platform ?? Application.platform; - this.showOffscreenLayersCheckerboard = showOffscreenLayersCheckerboard; - this.showRasterCacheImagesCheckerboard = showRasterCacheImagesCheckerboard; - this.showPerformanceOverlay = showPerformanceOverlay; - } - - public readonly GalleryTheme theme; - public readonly GalleryTextScaleValue textScaleFactor; - public readonly float timeDilation; - public readonly RuntimePlatform platform; - public readonly bool showPerformanceOverlay; - public readonly bool showRasterCacheImagesCheckerboard; - public readonly bool showOffscreenLayersCheckerboard; - - public GalleryOptions copyWith( - GalleryTheme theme = null, - GalleryTextScaleValue textScaleFactor = null, - float? timeDilation = null, - RuntimePlatform? platform = null, - bool? showPerformanceOverlay = null, - bool? showRasterCacheImagesCheckerboard = null, - bool? showOffscreenLayersCheckerboard = null - ) { - return new GalleryOptions( - theme: theme ?? this.theme, - textScaleFactor: textScaleFactor ?? this.textScaleFactor, - timeDilation: timeDilation ?? this.timeDilation, - platform: platform ?? this.platform, - showPerformanceOverlay: showPerformanceOverlay ?? this.showPerformanceOverlay, - showOffscreenLayersCheckerboard: - showOffscreenLayersCheckerboard ?? this.showOffscreenLayersCheckerboard, - showRasterCacheImagesCheckerboard: showRasterCacheImagesCheckerboard ?? - this.showRasterCacheImagesCheckerboard - ); - } - - public bool Equals(GalleryOptions other) { - if (ReferenceEquals(null, other)) { - return false; - } - if (ReferenceEquals(this, other)) { - return true; - } - return Equals(this.theme, other.theme) && Equals(this.textScaleFactor, other.textScaleFactor) && - this.timeDilation.Equals(other.timeDilation) && this.platform == other.platform && - this.showPerformanceOverlay == other.showPerformanceOverlay && - this.showRasterCacheImagesCheckerboard == other.showRasterCacheImagesCheckerboard && - this.showOffscreenLayersCheckerboard == other.showOffscreenLayersCheckerboard; - } - - public override bool Equals(object obj) { - if (ReferenceEquals(null, obj)) { - return false; - } - if (ReferenceEquals(this, obj)) { - return true; - } - if (obj.GetType() != this.GetType()) { - return false; - } - return this.Equals((GalleryOptions) obj); - } - - public override int GetHashCode() { - unchecked { - var hashCode = (this.theme != null ? this.theme.GetHashCode() : 0); - hashCode = (hashCode * 397) ^ (this.textScaleFactor != null ? this.textScaleFactor.GetHashCode() : 0); - hashCode = (hashCode * 397) ^ this.timeDilation.GetHashCode(); - hashCode = (hashCode * 397) ^ (int) this.platform; - hashCode = (hashCode * 397) ^ this.showPerformanceOverlay.GetHashCode(); - hashCode = (hashCode * 397) ^ this.showRasterCacheImagesCheckerboard.GetHashCode(); - hashCode = (hashCode * 397) ^ this.showOffscreenLayersCheckerboard.GetHashCode(); - return hashCode; - } - } - - public static bool operator ==(GalleryOptions left, GalleryOptions right) { - return Equals(left, right); - } - - public static bool operator !=(GalleryOptions left, GalleryOptions right) { - return !Equals(left, right); - } - - public override string ToString() { - return $"{this.GetType()}({this.theme})"; - } - } - - class _OptionsItem : StatelessWidget { - const float _kItemHeight = 48.0f; - static readonly EdgeInsets _kItemPadding = EdgeInsets.only(left: 56.0f); - - public _OptionsItem(Key key = null, Widget child = null) : base(key: key) { - this.child = child; - } - - public readonly Widget child; - - public override Widget build(BuildContext context) { - float textScaleFactor = MediaQuery.textScaleFactorOf(context); - - return new Container( - constraints: new BoxConstraints(minHeight: _kItemHeight * textScaleFactor), - padding: _kItemPadding, - alignment: Alignment.centerLeft, - child: new DefaultTextStyle( - style: DefaultTextStyle.of(context).style, - maxLines: 2, - overflow: TextOverflow.fade, - child: new IconTheme( - data: Theme.of(context).primaryIconTheme, - child: this.child - ) - ) - ); - } - } - - class _BooleanItem : StatelessWidget { - public _BooleanItem(string title, bool value, ValueChanged onChanged, Key switchKey = null) { - this.title = title; - this.value = value; - this.onChanged = onChanged; - this.switchKey = switchKey; - } - - public readonly string title; - public readonly bool value; - public readonly ValueChanged onChanged; - public readonly Key switchKey; - - public override Widget build(BuildContext context) { - bool isDark = Theme.of(context).brightness == Brightness.dark; - return new _OptionsItem( - child: new Row( - children: new List { - new Expanded(child: new Text(this.title)), - new Switch( - key: this.switchKey, - value: this.value, - onChanged: this.onChanged, - activeColor: new Color(0xFF39CEFD), - activeTrackColor: isDark ? Colors.white30 : Colors.black26 - ) - } - ) - ); - } - } - - class _ActionItem : StatelessWidget { - public _ActionItem(string text, VoidCallback onTap) { - this.text = text; - this.onTap = onTap; - } - - public readonly string text; - public readonly VoidCallback onTap; - - public override Widget build(BuildContext context) { - return new _OptionsItem( - child: new _FlatButton( - onPressed: this.onTap, - child: new Text(this.text) - ) - ); - } - } - - class _FlatButton : StatelessWidget { - public _FlatButton(Key key = null, VoidCallback onPressed = null, Widget child = null) : base(key: key) { - this.onPressed = onPressed; - this.child = child; - } - - public readonly VoidCallback onPressed; - public readonly Widget child; - - public override Widget build(BuildContext context) { - return new FlatButton( - padding: EdgeInsets.zero, - onPressed: this.onPressed, - child: new DefaultTextStyle( - style: Theme.of(context).primaryTextTheme.subhead, - child: this.child - ) - ); - } - } - - class _Heading : StatelessWidget { - public _Heading(string text) { - this.text = text; - } - - public readonly string text; - - public override Widget build(BuildContext context) { - ThemeData theme = Theme.of(context); - return new _OptionsItem( - child: new DefaultTextStyle( - style: theme.textTheme.body1.copyWith( - fontFamily: "GoogleSans", - color: theme.accentColor - ), - child: new Text(this.text) - ) - ); - } - } - - class _ThemeItem : StatelessWidget { - public _ThemeItem(GalleryOptions options, ValueChanged onOptionsChanged) { - this.options = options; - this.onOptionsChanged = onOptionsChanged; - } - - public readonly GalleryOptions options; - public readonly ValueChanged onOptionsChanged; - - public override Widget build(BuildContext context) { - return new _BooleanItem( - "Dark Theme", - this.options.theme == GalleryTheme.kDarkGalleryTheme, - (bool? value) => { - this.onOptionsChanged( - this.options.copyWith( - theme: value == true ? GalleryTheme.kDarkGalleryTheme : GalleryTheme.kLightGalleryTheme - ) - ); - }, - switchKey: Key.key("dark_theme") - ); - } - } - - class _TextScaleFactorItem : StatelessWidget { - public _TextScaleFactorItem(GalleryOptions options, ValueChanged onOptionsChanged) { - this.options = options; - this.onOptionsChanged = onOptionsChanged; - } - - public readonly GalleryOptions options; - public readonly ValueChanged onOptionsChanged; - - public override Widget build(BuildContext context) { - return new _OptionsItem( - child: new Row( - children: new List { - new Expanded( - child: new Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: new List { - new Text("Text size"), - new Text( - this.options.textScaleFactor.label, - style: Theme.of(context).primaryTextTheme.body1 - ), - } - ) - ), - new PopupMenuButton( - padding: EdgeInsets.only(right: 16.0f), - icon: new Icon(Icons.arrow_drop_down), - itemBuilder: _ => { - return GalleryTextScaleValue.kAllGalleryTextScaleValues.Select(scaleValue => - (PopupMenuEntry) new PopupMenuItem( - value: scaleValue, - child: new Text(scaleValue.label) - )).ToList(); - }, - onSelected: scaleValue => { - this.onOptionsChanged( - this.options.copyWith(textScaleFactor: scaleValue) - ); - } - ), - } - ) - ); - } - } - - - class _TimeDilationItem : StatelessWidget { - public _TimeDilationItem(GalleryOptions options, ValueChanged onOptionsChanged) { - this.options = options; - this.onOptionsChanged = onOptionsChanged; - } - - public readonly GalleryOptions options; - public readonly ValueChanged onOptionsChanged; - - public override Widget build(BuildContext context) { - return new _BooleanItem( - "Slow motion", - this.options.timeDilation != 1.0f, - (bool? value) => { - this.onOptionsChanged( - this.options.copyWith( - timeDilation: value == true ? 20.0f : 1.0f - ) - ); - }, - switchKey: Key.key("slow_motion") - ); - } - } - - class _PlatformItem : StatelessWidget { - public _PlatformItem(GalleryOptions options, ValueChanged onOptionsChanged) { - this.options = options; - this.onOptionsChanged = onOptionsChanged; - } - - public readonly GalleryOptions options; - public readonly ValueChanged onOptionsChanged; - - string _platformLabel(RuntimePlatform platform) { - return platform.ToString(); - } - - public override Widget build(BuildContext context) { - return new _OptionsItem( - child: new Row( - children: new List { - new Expanded( - child: new Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: new List { - new Text("Platform mechanics"), - new Text( - this._platformLabel(this.options.platform), - style: Theme.of(context).primaryTextTheme.body1 - ), - } - ) - ), - new PopupMenuButton( - padding: EdgeInsets.only(right: 16.0f), - icon: new Icon(Icons.arrow_drop_down), - itemBuilder: _ => { - var values = Enum.GetValues(typeof(RuntimePlatform)).Cast(); - return values.Select(platform => - (PopupMenuEntry) new PopupMenuItem( - value: platform, - child: new Text(this._platformLabel(platform)) - )).ToList(); - }, - onSelected: platform => { - this.onOptionsChanged( - this.options.copyWith(platform: platform) - ); - } - ), - } - ) - ); - } - } - - public class GalleryOptionsPage : StatelessWidget { - public GalleryOptionsPage( - Key key = null, - GalleryOptions options = null, - ValueChanged onOptionsChanged = null, - VoidCallback onSendFeedback = null - ) : base(key: key) { - this.options = options; - this.onOptionsChanged = onOptionsChanged; - this.onSendFeedback = onSendFeedback; - } - - public readonly GalleryOptions options; - public readonly ValueChanged onOptionsChanged; - public readonly VoidCallback onSendFeedback; - - List _enabledDiagnosticItems() { - List items = new List { - new Divider(), - new _Heading("Diagnostics"), - }; - - items.Add( - new _BooleanItem( - "Highlight offscreen layers", - this.options.showOffscreenLayersCheckerboard, - (bool? value) => { - this.onOptionsChanged(this.options.copyWith(showOffscreenLayersCheckerboard: value)); - } - ) - ); - items.Add( - new _BooleanItem( - "Highlight raster cache images", - this.options.showRasterCacheImagesCheckerboard, - (bool? value) => { - this.onOptionsChanged(this.options.copyWith(showRasterCacheImagesCheckerboard: value)); - } - ) - ); - items.Add( - new _BooleanItem( - "Show performance overlay", - this.options.showPerformanceOverlay, - (bool? value) => { this.onOptionsChanged(this.options.copyWith(showPerformanceOverlay: value)); } - ) - ); - - return items; - } - - public override Widget build(BuildContext context) { - ThemeData theme = Theme.of(context); - - var children = new List { - new _Heading("Display"), - new _ThemeItem(this.options, this.onOptionsChanged), - new _TextScaleFactorItem(this.options, this.onOptionsChanged), - new _TimeDilationItem(this.options, this.onOptionsChanged), - new Divider(), - new _Heading("Platform mechanics"), - new _PlatformItem(this.options, this.onOptionsChanged) - }; - - children.AddRange(this._enabledDiagnosticItems()); - children.AddRange(new List { - new Divider(), - new _Heading("UIWidgets Gallery"), - new _ActionItem("About UIWidgets Gallery", () => { - /* showGalleryAboutDialog(context); */ - }), - new _ActionItem("Send feedback", this.onSendFeedback), - }); - - return new DefaultTextStyle( - style: theme.primaryTextTheme.subhead, - child: new ListView( - padding: EdgeInsets.only(bottom: 124.0f), - children: children - )); - } - } -} diff --git a/Samples/UIWidgetsGallery/gallery/options.cs.meta b/Samples/UIWidgetsGallery/gallery/options.cs.meta deleted file mode 100644 index 288eab58..00000000 --- a/Samples/UIWidgetsGallery/gallery/options.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 9eb439aba25814f79979120cd5966537 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetsGallery/gallery/scales.cs b/Samples/UIWidgetsGallery/gallery/scales.cs deleted file mode 100644 index 5bb4c906..00000000 --- a/Samples/UIWidgetsGallery/gallery/scales.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace UIWidgetsGallery.gallery { - public class GalleryTextScaleValue : IEquatable { - public GalleryTextScaleValue(float? scale = null, string label = null) { - this.scale = scale; - this.label = label; - } - - public readonly float? scale; - public readonly string label; - - public bool Equals(GalleryTextScaleValue other) { - if (ReferenceEquals(null, other)) { - return false; - } - if (ReferenceEquals(this, other)) { - return true; - } - return this.scale.Equals(other.scale) && string.Equals(this.label, other.label); - } - - public override bool Equals(object obj) { - if (ReferenceEquals(null, obj)) { - return false; - } - if (ReferenceEquals(this, obj)) { - return true; - } - if (obj.GetType() != this.GetType()) { - return false; - } - return this.Equals((GalleryTextScaleValue) obj); - } - - public override int GetHashCode() { - unchecked { - return (this.scale.GetHashCode() * 397) ^ (this.label != null ? this.label.GetHashCode() : 0); - } - } - - public static bool operator ==(GalleryTextScaleValue left, GalleryTextScaleValue right) { - return Equals(left, right); - } - - public static bool operator !=(GalleryTextScaleValue left, GalleryTextScaleValue right) { - return !Equals(left, right); - } - - - public override string ToString() { - return $"{this.GetType()}({this.label})"; - } - - public static readonly List kAllGalleryTextScaleValues = new List { - new GalleryTextScaleValue(null, "System Default"), - new GalleryTextScaleValue(0.8f, "Small"), - new GalleryTextScaleValue(1.0f, "Normal"), - new GalleryTextScaleValue(1.3f, "Large"), - new GalleryTextScaleValue(2.0f, "Huge"), - }; - } -} diff --git a/Samples/UIWidgetsGallery/gallery/scales.cs.meta b/Samples/UIWidgetsGallery/gallery/scales.cs.meta deleted file mode 100644 index 4ec613de..00000000 --- a/Samples/UIWidgetsGallery/gallery/scales.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 9bf87177b342d4feba4778ca5a9b20a5 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetsGallery/gallery/syntax_highlighter.cs b/Samples/UIWidgetsGallery/gallery/syntax_highlighter.cs deleted file mode 100644 index 0447b0bb..00000000 --- a/Samples/UIWidgetsGallery/gallery/syntax_highlighter.cs +++ /dev/null @@ -1,427 +0,0 @@ -using System.Collections.Generic; -using System.Text.RegularExpressions; -using Unity.UIWidgets.foundation; -using Unity.UIWidgets.painting; -using Unity.UIWidgets.ui; -using TextStyle = Unity.UIWidgets.painting.TextStyle; - -namespace UIWidgetsGallery.gallery { - public class SyntaxHighlighterStyle { - public SyntaxHighlighterStyle( - TextStyle baseStyle = null, - TextStyle numberStyle = null, - TextStyle commentStyle = null, - TextStyle keywordStyle = null, - TextStyle stringStyle = null, - TextStyle punctuationStyle = null, - TextStyle classStyle = null, - TextStyle constantStyle = null - ) { - this.baseStyle = baseStyle; - this.numberStyle = numberStyle; - this.commentStyle = commentStyle; - this.keywordStyle = keywordStyle; - this.stringStyle = stringStyle; - this.punctuationStyle = punctuationStyle; - this.classStyle = classStyle; - this.constantStyle = constantStyle; - } - - public static SyntaxHighlighterStyle lightThemeStyle() { - return new SyntaxHighlighterStyle( - baseStyle: new TextStyle(color: new Color(0xFF000000)), - numberStyle: new TextStyle(color: new Color(0xFF1565C0)), - commentStyle: new TextStyle(color: new Color(0xFF9E9E9E)), - keywordStyle: new TextStyle(color: new Color(0xFF9C27B0)), - stringStyle: new TextStyle(color: new Color(0xFF43A047)), - punctuationStyle: new TextStyle(color: new Color(0xFF000000)), - classStyle: new TextStyle(color: new Color(0xFF512DA8)), - constantStyle: new TextStyle(color: new Color(0xFF795548)) - ); - } - - public static SyntaxHighlighterStyle darkThemeStyle() { - return new SyntaxHighlighterStyle( - baseStyle: new TextStyle(color: new Color(0xFFFFFFFF)), - numberStyle: new TextStyle(color: new Color(0xFF1565C0)), - commentStyle: new TextStyle(color: new Color(0xFF9E9E9E)), - keywordStyle: new TextStyle(color: new Color(0xFF80CBC4)), - stringStyle: new TextStyle(color: new Color(0xFF009688)), - punctuationStyle: new TextStyle(color: new Color(0xFFFFFFFF)), - classStyle: new TextStyle(color: new Color(0xFF009688)), - constantStyle: new TextStyle(color: new Color(0xFF795548)) - ); - } - - public readonly TextStyle baseStyle; - public readonly TextStyle numberStyle; - public readonly TextStyle commentStyle; - public readonly TextStyle keywordStyle; - public readonly TextStyle stringStyle; - public readonly TextStyle punctuationStyle; - public readonly TextStyle classStyle; - public readonly TextStyle constantStyle; - } - - public abstract class SyntaxHighlighter { - // ignore: one_member_abstracts - public abstract TextSpan format(string src); - } - - public class DartSyntaxHighlighter : SyntaxHighlighter { - public DartSyntaxHighlighter(SyntaxHighlighterStyle _style = null) { - this._spans = new List<_HighlightSpan> { }; - this._style = _style ?? SyntaxHighlighterStyle.darkThemeStyle(); - } - - SyntaxHighlighterStyle _style; - - readonly List _keywords = new List { - "abstract", "as", "assert", "async", "await", "break", "case", "catch", - "class", "const", "continue", "default", "deferred", "do", "dynamic", "else", - "enum", "export", "external", "extends", "factory", "false", "final", - "finally", "for", "get", "if", "implements", "import", "in", "is", "library", - "new", "null", "operator", "part", "rethrow", "return", "set", "static", - "super", "switch", "sync", "this", "throw", "true", "try", "typedef", "var", - "void", "while", "with", "yield" - }; - - readonly List _builtInTypes = new List { - "int", "double", "num", "bool" - }; - - string _src; - StringScanner _scanner; - - List<_HighlightSpan> _spans; - - public override TextSpan format(string src) { - this._src = src; - this._scanner = new StringScanner(this._src); - - if (this._generateSpans()) { - List formattedText = new List { }; - int currentPosition = 0; - - foreach (_HighlightSpan span in this._spans) { - if (currentPosition != span.start) { - formattedText.Add(new TextSpan(text: this._src.Substring(currentPosition, span.start))); - } - - formattedText.Add(new TextSpan(style: span.textStyle(this._style), - text: span.textForSpan(this._src))); - - currentPosition = span.end; - } - - if (currentPosition != this._src.Length) { - formattedText.Add(new TextSpan(text: this._src.Substring(currentPosition, this._src.Length))); - } - - return new TextSpan(style: this._style.baseStyle, children: formattedText); - } - else { - return new TextSpan(style: this._style.baseStyle, text: src); - } - } - - bool _generateSpans() { - int lastLoopPosition = this._scanner.position; - - while (!this._scanner.isDone) { - this._scanner.scan(new Regex(@"\s+")); - - // Block comments - if (this._scanner.scan(new Regex(@"/\*(.|\n)*\*/"))) { - this._spans.Add(new _HighlightSpan( - _HighlightType.comment, - this._scanner.lastMatch.Index, - this._scanner.lastMatch.Index + this._scanner.lastMatch.Length - )); - continue; - } - - // Line comments - if (this._scanner.scan(new Regex(@"//"))) { - int startComment = this._scanner.lastMatch.Index; - - bool eof = false; - int endComment; - if (this._scanner.scan(new Regex(@".*\n"))) { - endComment = this._scanner.lastMatch.Index + this._scanner.lastMatch.Length - 1; - } - else { - eof = true; - endComment = this._src.Length; - } - - this._spans.Add(new _HighlightSpan( - _HighlightType.comment, - startComment, - endComment - )); - - if (eof) { - break; - } - - continue; - } - - // Raw r"String" - if (this._scanner.scan(new Regex(@"r"".*"""))) { - this._spans.Add(new _HighlightSpan( - _HighlightType._string, - this._scanner.lastMatch.Index, - this._scanner.lastMatch.Index + this._scanner.lastMatch.Length - )); - continue; - } - - // Raw r"String" - if (this._scanner.scan(new Regex(@"r"".*"""))) { - this._spans.Add(new _HighlightSpan( - _HighlightType._string, - this._scanner.lastMatch.Index, - this._scanner.lastMatch.Index + this._scanner.lastMatch.Length - )); - continue; - } - - // Multiline """String""" - if (this._scanner.scan(new Regex(@"""""""(?:[^""\\]|\\(.|\n))*"""""""))) { - this._spans.Add(new _HighlightSpan( - _HighlightType._string, - this._scanner.lastMatch.Index, - this._scanner.lastMatch.Index + this._scanner.lastMatch.Length - )); - continue; - } - - // Multiline '''String''' - if (this._scanner.scan(new Regex(@"'''(?:[^""\\]|\\(.|\n))*'''"))) { - this._spans.Add(new _HighlightSpan( - _HighlightType._string, - this._scanner.lastMatch.Index, - this._scanner.lastMatch.Index + this._scanner.lastMatch.Length - )); - continue; - } - - // "String" - if (this._scanner.scan(new Regex(@"""(?:[^""\\]|\\.)*"""))) { - this._spans.Add(new _HighlightSpan( - _HighlightType._string, - this._scanner.lastMatch.Index, - this._scanner.lastMatch.Index + this._scanner.lastMatch.Length - )); - continue; - } - - // "String" - if (this._scanner.scan(new Regex(@"""(?:[^""\\]|\\.)*"""))) { - this._spans.Add(new _HighlightSpan( - _HighlightType._string, - this._scanner.lastMatch.Index, - this._scanner.lastMatch.Index + this._scanner.lastMatch.Length - )); - continue; - } - - // Double - if (this._scanner.scan(new Regex(@"\d+\.\d+"))) { - this._spans.Add(new _HighlightSpan( - _HighlightType.number, - this._scanner.lastMatch.Index, - this._scanner.lastMatch.Index + this._scanner.lastMatch.Length - )); - continue; - } - - // Integer - if (this._scanner.scan(new Regex(@"\d+"))) { - this._spans.Add(new _HighlightSpan( - _HighlightType.number, - this._scanner.lastMatch.Index, - this._scanner.lastMatch.Index + this._scanner.lastMatch.Length) - ); - continue; - } - - // Punctuation - if (this._scanner.scan(new Regex(@"[\[\]{}().!=<>&\|\?\+\-\*/%\^~;:,]"))) { - this._spans.Add(new _HighlightSpan( - _HighlightType.punctuation, - this._scanner.lastMatch.Index, - this._scanner.lastMatch.Index + this._scanner.lastMatch.Length - )); - continue; - } - - // Meta data - if (this._scanner.scan(new Regex(@"@\w+"))) { - this._spans.Add(new _HighlightSpan( - _HighlightType.keyword, - this._scanner.lastMatch.Index, - this._scanner.lastMatch.Index + this._scanner.lastMatch.Length - )); - continue; - } - - // Words - if (this._scanner.scan(new Regex(@"\w+"))) { - _HighlightType? type = null; - - string word = this._scanner.lastMatch.Groups[0].Value; - if (word.StartsWith("_")) { - word = word.Substring(1); - } - - if (this._keywords.Contains(word)) { - type = _HighlightType.keyword; - } - else if (this._builtInTypes.Contains(word)) { - type = _HighlightType.keyword; - } - else if (this._firstLetterIsUpperCase(word)) { - type = _HighlightType.klass; - } - else if (word.Length >= 2 && word.StartsWith("k") && - this._firstLetterIsUpperCase(word.Substring(1))) { - type = _HighlightType.constant; - } - - if (type != null) { - this._spans.Add(new _HighlightSpan( - type, - this._scanner.lastMatch.Index, - this._scanner.lastMatch.Index + this._scanner.lastMatch.Length - )); - } - } - - // Check if this loop did anything - if (lastLoopPosition == this._scanner.position) { - // Failed to parse this file, abort gracefully - return false; - } - - lastLoopPosition = this._scanner.position; - } - - this._simplify(); - return true; - } - - void _simplify() { - for (int i = this._spans.Count - 2; i >= 0; i -= 1) { - if (this._spans[i].type == this._spans[i + 1].type && this._spans[i].end == this._spans[i + 1].start) { - this._spans[i] = new _HighlightSpan( - this._spans[i].type, - this._spans[i].start, - this._spans[i + 1].end - ); - this._spans.RemoveAt(i + 1); - } - } - } - - bool _firstLetterIsUpperCase(string str) { - if (str.isNotEmpty()) { - string first = str.Substring(0, 1); - return first == first.ToUpper(); - } - - return false; - } - } - - enum _HighlightType { - number, - comment, - keyword, - _string, - punctuation, - klass, - constant - } - - class _HighlightSpan { - public _HighlightSpan(_HighlightType? type, int start, int end) { - this.type = type; - this.start = start; - this.end = end; - } - - public readonly _HighlightType? type; - public readonly int start; - public readonly int end; - - public string textForSpan(string src) { - return src.Substring(this.start, this.end); - } - - public TextStyle textStyle(SyntaxHighlighterStyle style) { - if (this.type == _HighlightType.number) { - return style.numberStyle; - } - else if (this.type == _HighlightType.comment) { - return style.commentStyle; - } - else if (this.type == _HighlightType.keyword) { - return style.keywordStyle; - } - else if (this.type == _HighlightType._string) { - return style.stringStyle; - } - else if (this.type == _HighlightType.punctuation) { - return style.punctuationStyle; - } - else if (this.type == _HighlightType.klass) { - return style.classStyle; - } - else if (this.type == _HighlightType.constant) { - return style.constantStyle; - } - else { - return style.baseStyle; - } - } - } - - public class StringScanner { - string _source { get; set; } - public int position { get; set; } - - public Match lastMatch { - get { return this._lastMatch; } - } - Match _lastMatch; - - public StringScanner(string source) { - this._source = source; - this.position = 0; - } - - public override string ToString() { - return this.isDone ? "" : this._source.Substring(this.position); - } - - public bool isDone { - get { return this.position >= this._source.Length; } - } - - public bool scan(Regex regex) { - var match = regex.Match(this.ToString()); - - if (match.Success) { - this.position += match.Length; - this._lastMatch = match; - return true; - } - else { - return false; - } - } - } -} \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/gallery/syntax_highlighter.cs.meta b/Samples/UIWidgetsGallery/gallery/syntax_highlighter.cs.meta deleted file mode 100644 index c5541b25..00000000 --- a/Samples/UIWidgetsGallery/gallery/syntax_highlighter.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 205d7446dc624493a18d7118ffeec352 -timeCreated: 1552469338 \ No newline at end of file diff --git a/Samples/UIWidgetsGallery/gallery/themes.cs b/Samples/UIWidgetsGallery/gallery/themes.cs deleted file mode 100644 index bddf0dbd..00000000 --- a/Samples/UIWidgetsGallery/gallery/themes.cs +++ /dev/null @@ -1,83 +0,0 @@ -using Unity.UIWidgets.material; -using Unity.UIWidgets.ui; - -namespace UIWidgetsGallery.gallery { - public class GalleryTheme { - GalleryTheme(string name, ThemeData data) { - this.name = name; - this.data = data; - } - - public readonly string name; - public readonly ThemeData data; - - public static readonly GalleryTheme kDarkGalleryTheme = new GalleryTheme("Dark", _buildDarkTheme()); - - public static readonly GalleryTheme kLightGalleryTheme = new GalleryTheme("Light", _buildLightTheme()); - - static TextTheme _buildTextTheme(TextTheme baseTheme) { - return baseTheme.copyWith( - title: baseTheme.title.copyWith( - fontFamily: "GoogleSans" - ) - ); - } - - static ThemeData _buildDarkTheme() { - Color primaryColor = new Color(0xFF0175c2); - Color secondaryColor = new Color(0xFF13B9FD); - ThemeData baseTheme = ThemeData.dark(); - ColorScheme colorScheme = ColorScheme.dark().copyWith( - primary: primaryColor, - secondary: secondaryColor - ); - return baseTheme.copyWith( - primaryColor: primaryColor, - buttonColor: primaryColor, - indicatorColor: Colors.white, - accentColor: secondaryColor, - canvasColor: new Color(0xFF202124), - scaffoldBackgroundColor: new Color(0xFF202124), - backgroundColor: new Color(0xFF202124), - errorColor: new Color(0xFFB00020), - buttonTheme: new ButtonThemeData( - colorScheme: colorScheme, - textTheme: ButtonTextTheme.primary - ), - textTheme: _buildTextTheme(baseTheme.textTheme), - primaryTextTheme: _buildTextTheme(baseTheme.primaryTextTheme), - accentTextTheme: _buildTextTheme(baseTheme.accentTextTheme) - ); - } - - static ThemeData _buildLightTheme() { - Color primaryColor = new Color(0xFF0175c2); - Color secondaryColor = new Color(0xFF13B9FD); - ColorScheme colorScheme = ColorScheme.light().copyWith( - primary: primaryColor, - secondary: secondaryColor - ); - ThemeData baseTheme = ThemeData.light(); - return baseTheme.copyWith( - colorScheme: colorScheme, - primaryColor: primaryColor, - buttonColor: primaryColor, - indicatorColor: Colors.white, - splashColor: Colors.white24, - splashFactory: InkRipple.splashFactory, - accentColor: secondaryColor, - canvasColor: Colors.white, - scaffoldBackgroundColor: Colors.white, - backgroundColor: Colors.white, - errorColor: new Color(0xFFB00020), - buttonTheme: new ButtonThemeData( - colorScheme: colorScheme, - textTheme: ButtonTextTheme.primary - ), - textTheme: _buildTextTheme(baseTheme.textTheme), - primaryTextTheme: _buildTextTheme(baseTheme.primaryTextTheme), - accentTextTheme: _buildTextTheme(baseTheme.accentTextTheme) - ); - } - } -} diff --git a/Samples/UIWidgetsGallery/gallery/themes.cs.meta b/Samples/UIWidgetsGallery/gallery/themes.cs.meta deleted file mode 100644 index fcaf4306..00000000 --- a/Samples/UIWidgetsGallery/gallery/themes.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 7510605485ec34459a4ac9b456cf583f -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetsGallery/gallery/updater.cs b/Samples/UIWidgetsGallery/gallery/updater.cs deleted file mode 100644 index 82000011..00000000 --- a/Samples/UIWidgetsGallery/gallery/updater.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System; -using System.Collections.Generic; -using RSG; -using Unity.UIWidgets.foundation; -using Unity.UIWidgets.material; -using Unity.UIWidgets.painting; -using Unity.UIWidgets.widgets; -using UnityEngine; -using DialogUtils = Unity.UIWidgets.material.DialogUtils; - -namespace UIWidgetsGallery.gallery { - public class Updater : StatefulWidget { - public Updater(UpdateUrlFetcher updateUrlFetcher = null, Widget child = null, Key key = null) - : base(key: key) { - D.assert(updateUrlFetcher != null); - this.updateUrlFetcher = updateUrlFetcher; - this.child = child; - } - - public readonly UpdateUrlFetcher updateUrlFetcher; - public readonly Widget child; - - public override State createState() { - return new UpdaterState(); - } - } - - public class UpdaterState : State { - public override void initState() { - base.initState(); - this._checkForUpdates(); - } - - static DateTime? _lastUpdateCheck; - - IPromise _checkForUpdates() { - // Only prompt once a day - if (_lastUpdateCheck != null && - (DateTime.Now - _lastUpdateCheck.Value).TotalDays < 1) { - return Promise.Resolved(); // We already checked for updates recently - } - - _lastUpdateCheck = DateTime.Now; - - return this.widget.updateUrlFetcher().Then(updateUrl => { - if (updateUrl != null) { - return DialogUtils.showDialog(context: this.context, builder: this._buildDialog).Then( - result => { - if (result != null) { - bool wantsUpdate = (bool) result; - if (wantsUpdate) { - Application.OpenURL(updateUrl); - } - } - }); - } - - return Promise.Resolved(); - }); - } - - Widget _buildDialog(BuildContext context) { - ThemeData theme = Theme.of(context); - TextStyle dialogTextStyle = theme.textTheme.subhead.copyWith(color: theme.textTheme.caption.color); - return new AlertDialog( - title: new Text("Update UIWidgets Gallery?"), - content: new Text("A newer version is available.", style: dialogTextStyle), - actions: new List() { - new FlatButton( - child: new Text("NO THANKS"), - onPressed: () => { Navigator.pop(context, false); } - ), - new FlatButton( - child: new Text("UPDATE"), - onPressed: () => { Navigator.pop(context, true); } - ) - } - ); - } - - public override Widget build(BuildContext context) { - return this.widget.child; - } - } -} diff --git a/Samples/UIWidgetsGallery/gallery/updater.cs.meta b/Samples/UIWidgetsGallery/gallery/updater.cs.meta deleted file mode 100644 index 84f68051..00000000 --- a/Samples/UIWidgetsGallery/gallery/updater.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c69f6e2d93b02484fab6f2e2408c7d88 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetsSample.asmdef b/Samples/UIWidgetsSample.asmdef deleted file mode 100644 index 08533610..00000000 --- a/Samples/UIWidgetsSample.asmdef +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "UIWidgetsSample", - "references": [ - "Unity.UIWidgets" - ], - "optionalUnityReferences": [], - "includePlatforms": [], - "excludePlatforms": [], - "allowUnsafeCode": false, - "overrideReferences": false, - "precompiledReferences": [], - "autoReferenced": true, - "defineConstraints": [] -} \ No newline at end of file diff --git a/Samples/UIWidgetsSample.asmdef.meta b/Samples/UIWidgetsSample.asmdef.meta deleted file mode 100644 index 99ce63ba..00000000 --- a/Samples/UIWidgetsSample.asmdef.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: a7ca98f66c76743a39c34ff4c984fa65 -AssemblyDefinitionImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetsTheatre.meta b/Samples/UIWidgetsTheatre.meta deleted file mode 100644 index 3b35111e..00000000 --- a/Samples/UIWidgetsTheatre.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: b54f053c2c5d34691b30237abaf17e14 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetsTheatre/UIWidgetsTheatre.asmdef b/Samples/UIWidgetsTheatre/UIWidgetsTheatre.asmdef deleted file mode 100644 index f6e63745..00000000 --- a/Samples/UIWidgetsTheatre/UIWidgetsTheatre.asmdef +++ /dev/null @@ -1,9 +0,0 @@ -{ - "name": "UIWidgetsTheatre", - "references": [ - "Unity.UIWidgets", - "UIWidgetsGallery", - "UIWidgetsSample"], - "includePlatforms": [], - "excludePlatforms": [] -} diff --git a/Samples/UIWidgetsTheatre/UIWidgetsTheatre.asmdef.meta b/Samples/UIWidgetsTheatre/UIWidgetsTheatre.asmdef.meta deleted file mode 100644 index b93e1bad..00000000 --- a/Samples/UIWidgetsTheatre/UIWidgetsTheatre.asmdef.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: ce5674c12e2e24bf6bb350c64744f227 -AssemblyDefinitionImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetsTheatre/UIWidgetsTheatre.cs b/Samples/UIWidgetsTheatre/UIWidgetsTheatre.cs deleted file mode 100644 index c2cceb7e..00000000 --- a/Samples/UIWidgetsTheatre/UIWidgetsTheatre.cs +++ /dev/null @@ -1,73 +0,0 @@ -using System.Collections.Generic; -using UIWidgetsGallery.gallery; -using UIWidgetsSample; -using Unity.UIWidgets.material; -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; - -#if UNITY_EDITOR -using UnityEditor; -using UnityEditor.UI; -#endif - -using UnityEngine; - - -namespace UIWidgetsTheatre { - - class TheatreEntry { - public string entryName; - public Widget entryWidget; - } - - class UIWidgetsTheatre : UIWidgetsSamplePanel { - static readonly List entries = new List { - new TheatreEntry{entryName = "UIWidget Gallery", entryWidget = new GalleryApp()}, - new TheatreEntry{entryName = "Material App Bar", entryWidget = new MaterialAppBarWidget()}, - new TheatreEntry{entryName = "Material Tab Bar" , entryWidget = new MaterialTabBarWidget()}, - new TheatreEntry{entryName = "Asset Store", entryWidget = new AsScreenSample.AsScreenWidget()}, - new TheatreEntry{entryName = "ToDo App", entryWidget = new ToDoAppSample.ToDoListApp()} - }; - - public static string[] entryKeys { - get { - List ret = new List(); - foreach (var entry in entries) { - ret.Add(entry.entryName); - } - - return ret.ToArray(); - } - } - - [SerializeField] public int testCaseId; - - protected override Widget createWidget() { - return new MaterialApp( - showPerformanceOverlay: false, - home: entries[this.testCaseId].entryWidget); - } - - protected override void OnEnable() { - FontManager.instance.addFont(Resources.Load("MaterialIcons-Regular"), "Material Icons"); - FontManager.instance.addFont(Resources.Load("GalleryIcons"), "GalleryIcons"); - base.OnEnable(); - } - } - - - #if UNITY_EDITOR - [CustomEditor(typeof(UIWidgetsTheatre), true)] - [CanEditMultipleObjects] - public class UIWidgetTheatreEditor : RawImageEditor { - int _choiceIndex; - - public override void OnInspectorGUI() { - var materialSample = this.target as UIWidgetsTheatre; - this._choiceIndex = EditorGUILayout.Popup("Test Case", materialSample.testCaseId, UIWidgetsTheatre.entryKeys); - materialSample.testCaseId = this._choiceIndex; - EditorUtility.SetDirty(this.target); - } - } - #endif -} \ No newline at end of file diff --git a/Samples/UIWidgetsTheatre/UIWidgetsTheatre.cs.meta b/Samples/UIWidgetsTheatre/UIWidgetsTheatre.cs.meta deleted file mode 100644 index 4fbf3a28..00000000 --- a/Samples/UIWidgetsTheatre/UIWidgetsTheatre.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 3ace0d3c7f55946559f1497f0fbf6025 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Samples/UIWidgetsTheatre/UIWidgetsTheatre.unity b/Samples/UIWidgetsTheatre/UIWidgetsTheatre.unity deleted file mode 100644 index 921d788d..00000000 --- a/Samples/UIWidgetsTheatre/UIWidgetsTheatre.unity +++ /dev/null @@ -1,504 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!29 &1 -OcclusionCullingSettings: - m_ObjectHideFlags: 0 - serializedVersion: 2 - m_OcclusionBakeSettings: - smallestOccluder: 5 - smallestHole: 0.25 - backfaceThreshold: 100 - m_SceneGUID: 00000000000000000000000000000000 - m_OcclusionCullingData: {fileID: 0} ---- !u!104 &2 -RenderSettings: - m_ObjectHideFlags: 0 - serializedVersion: 9 - m_Fog: 0 - m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} - m_FogMode: 3 - m_FogDensity: 0.01 - m_LinearFogStart: 0 - m_LinearFogEnd: 300 - m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} - m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} - m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} - m_AmbientIntensity: 1 - m_AmbientMode: 0 - m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} - m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} - m_HaloStrength: 0.5 - m_FlareStrength: 1 - m_FlareFadeSpeed: 3 - m_HaloTexture: {fileID: 0} - m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} - m_DefaultReflectionMode: 0 - m_DefaultReflectionResolution: 128 - m_ReflectionBounces: 1 - m_ReflectionIntensity: 1 - m_CustomReflection: {fileID: 0} - m_Sun: {fileID: 0} - m_IndirectSpecularColor: {r: 0.44657898, g: 0.49641287, b: 0.5748173, a: 1} - m_UseRadianceAmbientProbe: 0 ---- !u!157 &3 -LightmapSettings: - m_ObjectHideFlags: 0 - serializedVersion: 11 - m_GIWorkflowMode: 0 - m_GISettings: - serializedVersion: 2 - m_BounceScale: 1 - m_IndirectOutputScale: 1 - m_AlbedoBoost: 1 - m_EnvironmentLightingMode: 0 - m_EnableBakedLightmaps: 1 - m_EnableRealtimeLightmaps: 1 - m_LightmapEditorSettings: - serializedVersion: 10 - m_Resolution: 2 - m_BakeResolution: 40 - m_AtlasSize: 1024 - m_AO: 0 - m_AOMaxDistance: 1 - m_CompAOExponent: 1 - m_CompAOExponentDirect: 0 - m_Padding: 2 - m_LightmapParameters: {fileID: 0} - m_LightmapsBakeMode: 1 - m_TextureCompression: 1 - m_FinalGather: 0 - m_FinalGatherFiltering: 1 - m_FinalGatherRayCount: 256 - m_ReflectionCompression: 2 - m_MixedBakeMode: 2 - m_BakeBackend: 1 - m_PVRSampling: 1 - m_PVRDirectSampleCount: 32 - m_PVRSampleCount: 500 - m_PVRBounces: 2 - m_PVRFilterTypeDirect: 0 - m_PVRFilterTypeIndirect: 0 - m_PVRFilterTypeAO: 0 - m_PVRFilteringMode: 1 - m_PVRCulling: 1 - m_PVRFilteringGaussRadiusDirect: 1 - m_PVRFilteringGaussRadiusIndirect: 5 - m_PVRFilteringGaussRadiusAO: 2 - m_PVRFilteringAtrousPositionSigmaDirect: 0.5 - m_PVRFilteringAtrousPositionSigmaIndirect: 2 - m_PVRFilteringAtrousPositionSigmaAO: 1 - m_ShowResolutionOverlay: 1 - m_LightingDataAsset: {fileID: 0} - m_UseShadowmask: 1 ---- !u!196 &4 -NavMeshSettings: - serializedVersion: 2 - m_ObjectHideFlags: 0 - m_BuildSettings: - serializedVersion: 2 - agentTypeID: 0 - agentRadius: 0.5 - agentHeight: 2 - agentSlope: 45 - agentClimb: 0.4 - ledgeDropHeight: 0 - maxJumpAcrossDistance: 0 - minRegionArea: 2 - manualCellSize: 0 - cellSize: 0.16666667 - manualTileSize: 0 - tileSize: 256 - accuratePlacement: 0 - debug: - m_Flags: 0 - m_NavMeshData: {fileID: 0} ---- !u!1 &314914769 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 314914773} - - component: {fileID: 314914772} - - component: {fileID: 314914771} - - component: {fileID: 314914770} - m_Layer: 5 - m_Name: Canvas - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!114 &314914770 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 314914769} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 1301386320, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_IgnoreReversedGraphics: 1 - m_BlockingObjects: 0 - m_BlockingMask: - serializedVersion: 2 - m_Bits: 4294967295 ---- !u!114 &314914771 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 314914769} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 1980459831, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_UiScaleMode: 0 - m_ReferencePixelsPerUnit: 100 - m_ScaleFactor: 1 - m_ReferenceResolution: {x: 800, y: 600} - m_ScreenMatchMode: 0 - m_MatchWidthOrHeight: 0 - m_PhysicalUnit: 3 - m_FallbackScreenDPI: 96 - m_DefaultSpriteDPI: 96 - m_DynamicPixelsPerUnit: 1 ---- !u!223 &314914772 -Canvas: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 314914769} - m_Enabled: 1 - serializedVersion: 3 - m_RenderMode: 0 - m_Camera: {fileID: 0} - m_PlaneDistance: 100 - m_PixelPerfect: 0 - m_ReceivesEvents: 1 - m_OverrideSorting: 0 - m_OverridePixelPerfect: 0 - m_SortingBucketNormalizedSize: 0 - m_AdditionalShaderChannelsFlag: 0 - m_SortingLayerID: 0 - m_SortingOrder: 0 - m_TargetDisplay: 0 ---- !u!224 &314914773 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 314914769} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 0, y: 0, z: 0} - m_Children: - - {fileID: 1344738457} - m_Father: {fileID: 0} - m_RootOrder: 2 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 0, y: 0} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0, y: 0} ---- !u!1 &1040325770 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1040325773} - - component: {fileID: 1040325772} - - component: {fileID: 1040325771} - m_Layer: 0 - m_Name: EventSystem - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!114 &1040325771 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1040325770} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 1077351063, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_HorizontalAxis: Horizontal - m_VerticalAxis: Vertical - m_SubmitButton: Submit - m_CancelButton: Cancel - m_InputActionsPerSecond: 10 - m_RepeatDelay: 0.5 - m_ForceModuleActive: 0 ---- !u!114 &1040325772 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1040325770} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: -619905303, guid: f70555f144d8491a825f0804e09c671c, type: 3} - m_Name: - m_EditorClassIdentifier: - m_FirstSelected: {fileID: 0} - m_sendNavigationEvents: 1 - m_DragThreshold: 10 ---- !u!4 &1040325773 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1040325770} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 3 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!1 &1125362302 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1125362304} - - component: {fileID: 1125362303} - m_Layer: 0 - m_Name: Directional Light - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!108 &1125362303 -Light: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1125362302} - m_Enabled: 1 - serializedVersion: 8 - m_Type: 1 - m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} - m_Intensity: 1 - m_Range: 10 - m_SpotAngle: 30 - m_CookieSize: 10 - m_Shadows: - m_Type: 2 - m_Resolution: -1 - m_CustomResolution: -1 - m_Strength: 1 - m_Bias: 0.05 - m_NormalBias: 0.4 - m_NearPlane: 0.2 - m_Cookie: {fileID: 0} - m_DrawHalo: 0 - m_Flare: {fileID: 0} - m_RenderMode: 0 - m_CullingMask: - serializedVersion: 2 - m_Bits: 4294967295 - m_Lightmapping: 4 - m_LightShadowCasterMode: 0 - m_AreaSize: {x: 1, y: 1} - m_BounceIntensity: 1 - m_ColorTemperature: 6570 - m_UseColorTemperature: 0 - m_ShadowRadius: 0 - m_ShadowAngle: 0 ---- !u!4 &1125362304 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1125362302} - m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} - m_LocalPosition: {x: 0, y: 3, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 1 - m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} ---- !u!1 &1344738456 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1344738457} - - component: {fileID: 1344738459} - - component: {fileID: 1344738458} - m_Layer: 5 - m_Name: TheatrePanel - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &1344738457 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1344738456} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 314914773} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &1344738458 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1344738456} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 3ace0d3c7f55946559f1497f0fbf6025, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null - m_Texture: {fileID: 0} - m_UVRect: - serializedVersion: 2 - x: 0 - y: 0 - width: 1 - height: 1 - devicePixelRatioOverride: 0 - testCaseId: 2 ---- !u!222 &1344738459 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1344738456} - m_CullTransparentMesh: 0 ---- !u!1 &1814350050 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1814350053} - - component: {fileID: 1814350052} - - component: {fileID: 1814350051} - m_Layer: 0 - m_Name: Main Camera - m_TagString: MainCamera - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!81 &1814350051 -AudioListener: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1814350050} - m_Enabled: 1 ---- !u!20 &1814350052 -Camera: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1814350050} - m_Enabled: 1 - serializedVersion: 2 - m_ClearFlags: 1 - m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} - m_projectionMatrixMode: 1 - m_SensorSize: {x: 36, y: 24} - m_LensShift: {x: 0, y: 0} - m_GateFitMode: 2 - m_FocalLength: 50 - m_NormalizedViewPortRect: - serializedVersion: 2 - x: 0 - y: 0 - width: 1 - height: 1 - near clip plane: 0.3 - far clip plane: 1000 - field of view: 60 - orthographic: 0 - orthographic size: 5 - m_Depth: -1 - m_CullingMask: - serializedVersion: 2 - m_Bits: 4294967295 - m_RenderingPath: -1 - m_TargetTexture: {fileID: 0} - m_TargetDisplay: 0 - m_TargetEye: 3 - m_HDR: 1 - m_AllowMSAA: 1 - m_AllowDynamicResolution: 0 - m_ForceIntoRT: 0 - m_OcclusionCulling: 1 - m_StereoConvergence: 10 - m_StereoSeparation: 0.022 ---- !u!4 &1814350053 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1814350050} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 1, z: -10} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} diff --git a/Samples/UIWidgetsTheatre/UIWidgetsTheatre.unity.meta b/Samples/UIWidgetsTheatre/UIWidgetsTheatre.unity.meta deleted file mode 100644 index 0ff4a0bb..00000000 --- a/Samples/UIWidgetsTheatre/UIWidgetsTheatre.unity.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 98c373eb224884f5f9606a9eefe03de7 -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/scripts/cmds.meta b/Scripts/cmds.meta similarity index 100% rename from scripts/cmds.meta rename to Scripts/cmds.meta diff --git a/scripts/cmds/codegen.js b/Scripts/cmds/codegen.js similarity index 100% rename from scripts/cmds/codegen.js rename to Scripts/cmds/codegen.js diff --git a/scripts/cmds/codegen.js.meta b/Scripts/cmds/codegen.js.meta similarity index 100% rename from scripts/cmds/codegen.js.meta rename to Scripts/cmds/codegen.js.meta diff --git a/scripts/gitignore b/Scripts/gitignore similarity index 100% rename from scripts/gitignore rename to Scripts/gitignore diff --git a/scripts/gitignore.meta b/Scripts/gitignore.meta similarity index 100% rename from scripts/gitignore.meta rename to Scripts/gitignore.meta diff --git a/scripts/package.json b/Scripts/package.json similarity index 100% rename from scripts/package.json rename to Scripts/package.json diff --git a/scripts/package.json.meta b/Scripts/package.json.meta similarity index 100% rename from scripts/package.json.meta rename to Scripts/package.json.meta diff --git a/scripts/uiwidgets-cli.js b/Scripts/uiwidgets-cli.js similarity index 100% rename from scripts/uiwidgets-cli.js rename to Scripts/uiwidgets-cli.js diff --git a/scripts/uiwidgets-cli.js.meta b/Scripts/uiwidgets-cli.js.meta similarity index 100% rename from scripts/uiwidgets-cli.js.meta rename to Scripts/uiwidgets-cli.js.meta diff --git a/Tests.meta b/Tests.meta deleted file mode 100644 index d2def0b0..00000000 --- a/Tests.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 07e384a2d3b6c4ad6b1c07140c686a33 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/.tests.json b/Tests/.tests.json deleted file mode 100644 index 327abb29..00000000 --- a/Tests/.tests.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "createSeparatePackage": false -} diff --git a/Tests/Editor.meta b/Tests/Editor.meta deleted file mode 100644 index 3d3ec2c6..00000000 --- a/Tests/Editor.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 643ff5e7d7c4d44b7b520132441fd8c1 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/Editor/CanvasAndLayers.cs b/Tests/Editor/CanvasAndLayers.cs deleted file mode 100644 index 14444c15..00000000 --- a/Tests/Editor/CanvasAndLayers.cs +++ /dev/null @@ -1,623 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using RSG; -using Unity.UIWidgets.editor; -using Unity.UIWidgets.material; -using Unity.UIWidgets.painting; -using Unity.UIWidgets.ui; -using UnityEditor; -using UnityEngine; -using Color = Unity.UIWidgets.ui.Color; -using Gradient = Unity.UIWidgets.ui.Gradient; -using Material = UnityEngine.Material; -using Rect = UnityEngine.Rect; - -namespace UIWidgets.Tests { - public class CanvasAndLayers : EditorWindow { - static Material _guiTextureMat; - - internal static Material _getGUITextureMat() { - if (_guiTextureMat) { - return _guiTextureMat; - } - - var guiTextureShader = Shader.Find("UIWidgets/GUITexture"); - if (guiTextureShader == null) { - throw new Exception("UIWidgets/GUITexture not found"); - } - - _guiTextureMat = new Material(guiTextureShader); - _guiTextureMat.hideFlags = HideFlags.HideAndDontSave; - return _guiTextureMat; - } - - readonly Action[] _options; - - readonly string[] _optionStrings; - - int _selected; - - ImageStream _stream; - - RenderTexture _renderTexture; - - WindowAdapter _windowAdapter; - - MeshPool _meshPool; - - static Texture2D texture6; - - int _antiAliasing = Window.defaultAntiAliasing; - - CanvasAndLayers() { - this._options = new Action[] { - this.drawPloygon4, - this.drawRect, - this.drawRectShadow, - this.drawImageRect, - this.drawPicture, - this.clipRect, - this.clipRRect, - this.saveLayer, - this.drawLine, - this.drawParagraph, - }; - this._optionStrings = this._options.Select(x => x.Method.Name).ToArray(); - this._selected = 0; - - this.titleContent = new GUIContent("CanvasAndLayers"); - } - - void OnGUI() { - this._selected = EditorGUILayout.Popup("test case", this._selected, this._optionStrings); - if (this._selected == 3) { - using (this._windowAdapter.getScope()) { - if (GUI.Button(new Rect(20, 50, 100, 20), "Image 1")) { - this.LoadImage( - "http://a.hiphotos.baidu.com/image/h%3D300/sign=10b374237f0e0cf3bff748fb3a47f23d/adaf2edda3cc7cd90df1ede83401213fb80e9127.jpg"); - } - - if (GUI.Button(new Rect(20, 150, 100, 20), "Image 2")) { - this.LoadImage( - "http://a.hiphotos.baidu.com/image/pic/item/cf1b9d16fdfaaf519b4aa960875494eef11f7a47.jpg"); - } - - if (GUI.Button(new Rect(20, 250, 100, 20), "Image 3")) { - this.LoadImage( - "http://a.hiphotos.baidu.com/image/pic/item/2f738bd4b31c8701c1e721dd2a7f9e2f0708ffbc.jpg"); - } - } - } - - this._windowAdapter.OnGUI(); - - if (Event.current.type == EventType.Repaint || Event.current.type == EventType.MouseDown) { - this.createRenderTexture(); - - Window.instance = this._windowAdapter; - - if (Event.current.type == EventType.MouseDown) { - Promise.Delayed(new TimeSpan(0, 0, 5)).Then(() => { Debug.Log("Promise.Delayed: 5s"); }); - } - - this._options[this._selected](); - - Window.instance = null; - - Graphics.DrawTexture(new Rect(0, 0, this.position.width, this.position.height), - this._renderTexture, _getGUITextureMat()); - } - } - - void Update() { - this._windowAdapter.Update(); - } - - void OnEnable() { - this._windowAdapter = new EditorWindowAdapter(this); - this._windowAdapter.OnEnable(); - this._meshPool = new MeshPool(); - - texture6 = Resources.Load("6"); - } - - void OnDisable() { - this._meshPool.Dispose(); - this._meshPool = null; - } - - void createRenderTexture() { - var width = (int) (this.position.width * EditorGUIUtility.pixelsPerPoint); - var height = (int) (this.position.height * EditorGUIUtility.pixelsPerPoint); - if (this._renderTexture == null || - this._renderTexture.width != width || - this._renderTexture.height != height) { - var desc = new RenderTextureDescriptor( - width, - height, - RenderTextureFormat.Default, 24) { - useMipMap = false, - autoGenerateMips = false, - }; - - if (this._antiAliasing != 0) { - desc.msaaSamples = this._antiAliasing; - } - - this._renderTexture = RenderTexture.GetTemporary(desc); - } - } - - void LoadImage(string url) { - Dictionary headers = new Dictionary(); - NetworkImage networkImage = new NetworkImage(url, headers: headers); - ImageConfiguration imageConfig = new ImageConfiguration(); - this._stream = networkImage.resolve(imageConfig); - } - - void drawPloygon4() { - var canvas = new CommandBufferCanvas(this._renderTexture, Window.instance.devicePixelRatio, - this._meshPool); - - var paint = new Paint { - color = new Color(0xFFFF0000), - shader = Gradient.linear(new Offset(80, 80), new Offset(180, 180), new List() { - Colors.red, Colors.black, Colors.green - }, null, TileMode.clamp) - }; - - var path = new Path(); - path.moveTo(10, 150); - path.lineTo(10, 160); - path.lineTo(140, 120); - path.lineTo(110, 180); - path.winding(PathWinding.clockwise); - path.close(); - path.addRect(Unity.UIWidgets.ui.Rect.fromLTWH(0, 100, 100, 100)); - path.addRect(Unity.UIWidgets.ui.Rect.fromLTWH(200, 0, 100, 100)); - path.addRRect(RRect.fromRectAndRadius(Unity.UIWidgets.ui.Rect.fromLTWH(150, 100, 30, 30), 10)); - path.addOval(Unity.UIWidgets.ui.Rect.fromLTWH(150, 50, 100, 100)); - path.winding(PathWinding.clockwise); - - if (Event.current.type == EventType.MouseDown) { - var pos = new Offset( - Event.current.mousePosition.x, - Event.current.mousePosition.y - ); - - Debug.Log(pos + ": " + path.contains(pos)); - } - - canvas.drawPath(path, paint); - - canvas.rotate(Mathf.PI * 15 / 180); - - canvas.translate(100, 100); - - paint.shader = Gradient.radial(new Offset(80, 80), 100, new List() { - Colors.red, Colors.black, Colors.green - }, null, TileMode.clamp); - canvas.drawPath(path, paint); - - - canvas.translate(100, 100); - paint.shader = Gradient.sweep(new Offset(120, 100), new List() { - Colors.red, Colors.black, Colors.green, Colors.red, - }, null, TileMode.clamp, 10 * Mathf.PI / 180, 135 * Mathf.PI / 180); - canvas.drawPath(path, paint); - - - canvas.translate(100, 100); - //paint.maskFilter = MaskFilter.blur(BlurStyle.normal, 5); - paint.shader = new ImageShader(new Image(texture6, true), TileMode.mirror); - canvas.drawPath(path, paint); - - canvas.flush(); - } - - void drawLine() { - var canvas = new CommandBufferCanvas(this._renderTexture, Window.instance.devicePixelRatio, - this._meshPool); - - var paint = new Paint { - color = new Color(0xFFFF0000), - style = PaintingStyle.stroke, - strokeWidth = 10, - shader = Gradient.linear(new Offset(10, 10), new Offset(180, 180), new List() { - Colors.red, Colors.green, Colors.yellow - }, null, TileMode.clamp) - }; - - canvas.drawLine( - new Offset(10, 20), - new Offset(50, 20), - paint); - - canvas.drawLine( - new Offset(10, 10), - new Offset(100, 100), - paint); - - canvas.drawLine( - new Offset(10, 10), - new Offset(10, 50), - paint); - - canvas.drawLine( - new Offset(40, 10), - new Offset(90, 10), - paint); - - - canvas.drawArc(Unity.UIWidgets.ui.Rect.fromLTWH(200, 200, 100, 100), Mathf.PI / 4, - -Mathf.PI / 2 + Mathf.PI * 4 - 1, true, paint); - - paint.maskFilter = MaskFilter.blur(BlurStyle.normal, 1); - paint.strokeWidth = 4; - - canvas.drawLine( - new Offset(40, 20), - new Offset(120, 190), - paint); - - canvas.scale(3); - TextBlobBuilder builder = new TextBlobBuilder(); - string text = "This is a text blob"; - builder.setBounds(new Rect(-10, -20, 200, 50)); - builder.setPositionXs(new float[] { - 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, - 110, 120, 130, 140, 150, 160, 170, 180, 190 - }); - builder.allocRunPos(new TextStyle(), text, 0, text.Length); - - var textBlob = builder.make(); - canvas.drawTextBlob(textBlob, new Offset(100, 100), new Paint { - color = Colors.black, - maskFilter = MaskFilter.blur(BlurStyle.normal, 5), - }); - canvas.drawTextBlob(textBlob, new Offset(100, 100), paint); - - canvas.drawLine( - new Offset(10, 30), - new Offset(10, 60), - new Paint() {style = PaintingStyle.stroke, strokeWidth = 0.1f}); - - canvas.drawLine( - new Offset(20, 30), - new Offset(20, 60), - new Paint() {style = PaintingStyle.stroke, strokeWidth = 0.333f}); - - canvas.flush(); - } - - void drawRect() { - var canvas = new CommandBufferCanvas(this._renderTexture, Window.instance.devicePixelRatio, - this._meshPool); - - var paint = new Paint { - color = new Color(0xFFFF0000), - }; - - canvas.rotate(15 * Mathf.PI / 180); - var rect = Unity.UIWidgets.ui.Rect.fromLTWH(10, 10, 100, 100); - var rrect = RRect.fromRectAndCorners(rect, 0, 4, 8, 16); - - canvas.drawRRect(rrect, paint); - - paint = new Paint { - color = new Color(0xFF00FF00), - }; - - rect = Unity.UIWidgets.ui.Rect.fromLTWH(10, 150, 100, 100); - rrect = RRect.fromRectAndCorners(rect, 0, 4, 8, 16); - canvas.drawRRect(rrect, paint); - - rect = Unity.UIWidgets.ui.Rect.fromLTWH(150, 150, 100, 100); - rrect = RRect.fromRectAndCorners(rect, 10, 12, 14, 16); - var rect1 = Unity.UIWidgets.ui.Rect.fromLTWH(160, 160, 80, 80); - var rrect1 = RRect.fromRectAndCorners(rect1, 5, 6, 7, 8); - - canvas.drawDRRect(rrect, rrect1, paint); - - canvas.flush(); - } - - void drawRectShadow() { - var canvas = new CommandBufferCanvas(this._renderTexture, Window.instance.devicePixelRatio, - this._meshPool); - - var paint = new Paint { - color = new Color(0xFF00FF00), - maskFilter = MaskFilter.blur(BlurStyle.normal, 3), - }; - - canvas.clipRect(Unity.UIWidgets.ui.Rect.fromLTWH(25, 25, 300, 300)); - - canvas.rotate(-Mathf.PI / 8.0f); - - canvas.drawRect( - Unity.UIWidgets.ui.Rect.fromLTWH(10, 10, 100, 100), - paint); - - paint = new Paint { - color = new Color(0xFFFFFF00), - maskFilter = MaskFilter.blur(BlurStyle.normal, 5), - style = PaintingStyle.stroke, - strokeWidth = 55, - shader = Gradient.linear(new Offset(10, 10), new Offset(180, 180), new List() { - Colors.red, Colors.green, Colors.yellow - }, null, TileMode.clamp) - }; - - canvas.drawRect( - Unity.UIWidgets.ui.Rect.fromLTWH(10, 150, 200, 200), - paint); - - canvas.drawImage(new Image(texture6, true), - new Offset(50, 150), - paint); - - canvas.flush(); - } - - void drawPicture() { - var pictureRecorder = new PictureRecorder(); - var canvas = new RecorderCanvas(pictureRecorder); - - var paint = new Paint { - color = new Color(0xFFFF0000), - }; - - var path = new Path(); - path.moveTo(10, 10); - path.lineTo(10, 110); - path.lineTo(90, 110); - path.lineTo(100, 10); - path.close(); - canvas.drawPath(path, paint); - - paint = new Paint { - color = new Color(0xFFFFFF00), - }; - - var rect = Unity.UIWidgets.ui.Rect.fromLTWH(10, 150, 100, 100); - var rrect = RRect.fromRectAndCorners(rect, 0, 4, 8, 16); - var rect1 = Unity.UIWidgets.ui.Rect.fromLTWH(18, 152, 88, 92); - var rrect1 = RRect.fromRectAndCorners(rect1, 0, 4, 8, 16); - - canvas.drawDRRect(rrect, rrect1, paint); - - canvas.rotate(-45 * Mathf.PI / 180, new Offset(150, 150)); - - paint = new Paint { - color = new Color(0xFF00FFFF), - maskFilter = MaskFilter.blur(BlurStyle.normal, 3), - }; - canvas.drawRect( - Unity.UIWidgets.ui.Rect.fromLTWH(150, 150, 110, 120), - paint); - - var picture = pictureRecorder.endRecording(); - Debug.Log("picture.paintBounds: " + picture.paintBounds); - - var editorCanvas = new CommandBufferCanvas(this._renderTexture, Window.instance.devicePixelRatio, - this._meshPool); - editorCanvas.drawPicture(picture); - - editorCanvas.rotate(-15 * Mathf.PI / 180); - editorCanvas.translate(100, 100); - editorCanvas.drawPicture(picture); - editorCanvas.flush(); - } - - void drawParagraph() { - var pb = new ParagraphBuilder(new ParagraphStyle{}); - pb.addText("Hello drawParagraph"); - var paragraph = pb.build(); - paragraph.layout(new ParagraphConstraints(width:300)); - var canvas = new CommandBufferCanvas(this._renderTexture, Window.instance.devicePixelRatio, - this._meshPool); - canvas.drawParagraph(paragraph, new Offset(10f, 100f)); - canvas.flush(); - Unity.UIWidgets.ui.Paragraph.release(ref paragraph); - } - - void drawImageRect() { - if (this._stream == null || this._stream.completer == null || this._stream.completer.currentImage == null) { - return; - } - - var canvas = new CommandBufferCanvas(this._renderTexture, Window.instance.devicePixelRatio, - this._meshPool); - - var paint = new Paint { - // color = new Color(0x7FFF0000), - shader = Gradient.linear(new Offset(100, 100), new Offset(280, 280), new List() { - Colors.red, Colors.black, Colors.green - }, null, TileMode.clamp) - }; - - canvas.drawImageRect(this._stream.completer.currentImage.image, - Unity.UIWidgets.ui.Rect.fromLTWH(100, 50, 250, 250), - paint - ); - canvas.flush(); - } - - void clipRect() { - var pictureRecorder = new PictureRecorder(); - var canvas = new RecorderCanvas(pictureRecorder); - - var paint = new Paint { - color = new Color(0xFFFF0000), - }; - - var path = new Path(); - path.moveTo(10, 10); - path.lineTo(10, 110); - path.lineTo(90, 110); - path.lineTo(110, 10); - path.close(); - - canvas.drawPath(path, paint); - - paint = new Paint { - color = new Color(0xFFFFFF00), - }; - - var rect = Unity.UIWidgets.ui.Rect.fromLTWH(10, 150, 100, 100); - var rrect = RRect.fromRectAndCorners(rect, 0, 4, 8, 16); - var rect1 = Unity.UIWidgets.ui.Rect.fromLTWH(18, 152, 88, 92); - var rrect1 = RRect.fromRectAndCorners(rect1, 0, 4, 8, 16); - canvas.drawDRRect(rrect, rrect1, paint); - - canvas.rotate(-45 * Mathf.PI / 180.0f, new Offset(150, 150)); - -// paint = new Paint { -// color = new Color(0xFF00FFFF), -// blurSigma = 3, -// }; -// canvas.drawRectShadow( -// Rect.fromLTWH(150, 150, 110, 120), -// paint); - - var picture = pictureRecorder.endRecording(); - Debug.Log("picture.paintBounds: " + picture.paintBounds); - - var editorCanvas = new CommandBufferCanvas(this._renderTexture, Window.instance.devicePixelRatio, - this._meshPool); - editorCanvas.rotate(-5 * Mathf.PI / 180); - editorCanvas.clipRect(Unity.UIWidgets.ui.Rect.fromLTWH(25, 15, 250, 250)); - editorCanvas.rotate(5 * Mathf.PI / 180); - - editorCanvas.drawPicture(picture); - - editorCanvas.rotate(-15 * Mathf.PI / 180); - editorCanvas.translate(100, 100); - - editorCanvas.drawPicture(picture); - - editorCanvas.flush(); - } - - void clipRRect() { - var pictureRecorder = new PictureRecorder(); - var canvas = new RecorderCanvas(pictureRecorder); - - var paint = new Paint { - color = new Color(0xFFFF0000), - }; - - var path = new Path(); - path.moveTo(10, 10); - path.lineTo(10, 110); - path.lineTo(90, 110); - path.lineTo(110, 10); - path.close(); - - canvas.drawPath(path, paint); - - paint = new Paint { - color = new Color(0xFFFFFF00), - }; - - var rect = Unity.UIWidgets.ui.Rect.fromLTWH(10, 150, 100, 100); - var rrect = RRect.fromRectAndCorners(rect, 0, 4, 8, 16); - var rect1 = Unity.UIWidgets.ui.Rect.fromLTWH(18, 152, 88, 92); - var rrect1 = RRect.fromRectAndCorners(rect1, 0, 4, 8, 16); - canvas.drawDRRect(rrect, rrect1, paint); - - canvas.rotate(-45 * Mathf.PI / 180.0f, new Offset(150, 150)); - -// paint = new Paint { -// color = new Color(0xFF00FFFF), -// blurSigma = 3, -// }; -// canvas.drawRectShadow( -// Rect.fromLTWH(150, 150, 110, 120), -// paint); - - var picture = pictureRecorder.endRecording(); - Debug.Log("picture.paintBounds: " + picture.paintBounds); - - var editorCanvas = new CommandBufferCanvas(this._renderTexture, Window.instance.devicePixelRatio, - this._meshPool); - editorCanvas.rotate(-5 * Mathf.PI / 180); - editorCanvas.clipRRect(RRect.fromRectAndRadius(Unity.UIWidgets.ui.Rect.fromLTWH(25, 15, 250, 250), 50)); - editorCanvas.rotate(5 * Mathf.PI / 180); - - editorCanvas.drawPicture(picture); - - editorCanvas.rotate(-15 * Mathf.PI / 180); - editorCanvas.translate(100, 100); - - editorCanvas.drawPicture(picture); - - editorCanvas.flush(); - } - - void saveLayer() { - var pictureRecorder = new PictureRecorder(); - var canvas = new RecorderCanvas(pictureRecorder); - var paint1 = new Paint { - color = new Color(0xFFFFFFFF), - }; - - var path1 = new Path(); - path1.moveTo(0, 0); - path1.lineTo(0, 90); - path1.lineTo(90, 90); - path1.lineTo(90, 0); - path1.close(); - canvas.drawPath(path1, paint1); - - - var paint = new Paint { - color = new Color(0xFFFF0000), - }; - - var path = new Path(); - path.moveTo(20, 20); - path.lineTo(20, 70); - path.lineTo(70, 70); - path.lineTo(70, 20); - path.close(); - - canvas.drawPath(path, paint); - - var paint2 = new Paint { - color = new Color(0xFFFFFF00), - }; - - var path2 = new Path(); - path2.moveTo(30, 30); - path2.lineTo(30, 60); - path2.lineTo(60, 60); - path2.lineTo(60, 30); - path2.close(); - - canvas.drawPath(path2, paint2); - - var picture = pictureRecorder.endRecording(); - - var editorCanvas = new CommandBufferCanvas(this._renderTexture, Window.instance.devicePixelRatio, - this._meshPool); - - editorCanvas.saveLayer( - picture.paintBounds, new Paint { - color = new Color(0xFFFFFFFF), - }); - editorCanvas.drawPicture(picture); - editorCanvas.restore(); - - editorCanvas.saveLayer(Unity.UIWidgets.ui.Rect.fromLTWH(45, 45, 90, 90), new Paint { - color = new Color(0xFFFFFFFF), - backdrop = ImageFilter.blur(3f, 3f) - }); - editorCanvas.restore(); - - editorCanvas.flush(); - } - } -} \ No newline at end of file diff --git a/Tests/Editor/CanvasAndLayers.cs.meta b/Tests/Editor/CanvasAndLayers.cs.meta deleted file mode 100644 index a6990b65..00000000 --- a/Tests/Editor/CanvasAndLayers.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 670ec19e3d68342e985db21ef957463c -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/Editor/EditableTextWiget.cs b/Tests/Editor/EditableTextWiget.cs deleted file mode 100644 index fd911390..00000000 --- a/Tests/Editor/EditableTextWiget.cs +++ /dev/null @@ -1,80 +0,0 @@ -using Unity.UIWidgets.animation; -using Unity.UIWidgets.editor; -using Unity.UIWidgets.material; -using Unity.UIWidgets.painting; -using Unity.UIWidgets.widgets; -using UnityEditor; -using UnityEngine; -using Color = Unity.UIWidgets.ui.Color; -using TextStyle = Unity.UIWidgets.painting.TextStyle; - -namespace UIWidgets.Tests { - public class EditableTextWiget : EditorWindow { - WindowAdapter windowAdapter; - - Widget root; - - Widget image; - - [MenuItem("UIWidgetsTests/EditableTextWidget")] - public static void renderWidgets() { - GetWindow(typeof(EditableTextWiget)); - } - - string txt = "Hello\n" + - "This is useful when you need to check if a certain key has been pressed - possibly with modifiers. The syntax for the key string\n" + - "asfsd \n" + - "P1:\n" + - "This is useful when you need to check if a certain key has been pressed - possibly with modifiers.The syntax for the key st\n" + - "\n" + - "\n" + - "\n" + - "\n" + - " sfsafd"; - - EditableTextWiget() { - } - - void OnGUI() { - this.windowAdapter.OnGUI(); - } - - void Update() { - this.windowAdapter.Update(); - } - - void OnEnable() { - this.windowAdapter = new EditorWindowAdapter(this); - this.windowAdapter.OnEnable(); - this.root = new Container( - width: 200, - height: 200, - margin: EdgeInsets.all(30.0f), - padding: EdgeInsets.all(15.0f), - color: Color.fromARGB(255, 244, 190, 85), - child: new EditableText( - maxLines: 100, - selectionControls: MaterialUtils.materialTextSelectionControls, - controller: new TextEditingController(this.txt), - focusNode: new FocusNode(), - style: new TextStyle(), - selectionColor: Color.fromARGB(255, 255, 0, 0), - cursorColor: Color.fromARGB(255, 0, 0, 0) - ) - ); - this.windowAdapter.attachRootWidget(() => new WidgetsApp(home: this.root, - pageRouteBuilder: (RouteSettings settings, WidgetBuilder builder) => - new PageRouteBuilder( - settings: settings, - pageBuilder: (BuildContext context, Animation animation, - Animation secondaryAnimation) => builder(context) - ))); - this.titleContent = new GUIContent("EditableTextWidget"); - } - - void OnDisable() { - this.windowAdapter.OnDisable(); - this.windowAdapter = null; - } - } -} \ No newline at end of file diff --git a/Tests/Editor/EditableTextWiget.cs.meta b/Tests/Editor/EditableTextWiget.cs.meta deleted file mode 100644 index db8cdbea..00000000 --- a/Tests/Editor/EditableTextWiget.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 1438fd697c854ab783eb666a6a62115c -timeCreated: 1537236780 \ No newline at end of file diff --git a/Tests/Editor/EditorExampleTest.cs b/Tests/Editor/EditorExampleTest.cs deleted file mode 100644 index e38879e1..00000000 --- a/Tests/Editor/EditorExampleTest.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System.Collections; -using NUnit.Framework; -using UnityEngine.TestTools; - -class EditorExampleTest { - [Test] - public void EditorSampleTestSimplePasses() { - // Use the Assert class to test conditions. - } - - // A UnityTest behaves like a coroutine in PlayMode - // and allows you to yield null to skip a frame in EditMode - [UnityTest] - public IEnumerator EditorSampleTestWithEnumeratorPasses() { - // Use the Assert class to test conditions. - // yield to skip a frame - yield return null; - } -} \ No newline at end of file diff --git a/Tests/Editor/EditorExampleTest.cs.meta b/Tests/Editor/EditorExampleTest.cs.meta deleted file mode 100644 index 1704d91d..00000000 --- a/Tests/Editor/EditorExampleTest.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 324dcc98993604886878344a0ea94d18 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/Editor/Gestures.cs b/Tests/Editor/Gestures.cs deleted file mode 100644 index 56d05961..00000000 --- a/Tests/Editor/Gestures.cs +++ /dev/null @@ -1,98 +0,0 @@ -using System; -using System.Linq; -using Unity.UIWidgets.editor; -using Unity.UIWidgets.gestures; -using Unity.UIWidgets.painting; -using Unity.UIWidgets.rendering; -using Unity.UIWidgets.ui; -using UnityEditor; -using UnityEngine; -using Color = Unity.UIWidgets.ui.Color; - -namespace UIWidgets.Tests { - public class Gestures : EditorWindow { - readonly Func[] _options; - - readonly string[] _optionStrings; - - int _selected; - - Gestures() { - this._options = new Func[] { - this.tap, - }; - this._optionStrings = this._options.Select(x => x.Method.Name).ToArray(); - this._selected = 0; - - this.titleContent = new GUIContent("Gestures"); - } - - WindowAdapter windowAdapter; - - [NonSerialized] bool hasInvoked = false; - - void OnGUI() { - var selected = EditorGUILayout.Popup("test case", this._selected, this._optionStrings); - if (selected != this._selected || !this.hasInvoked) { - this._selected = selected; - this.hasInvoked = true; - - var renderBox = this._options[this._selected](); - if (this.windowAdapter != null) { - this.windowAdapter.attachRootRenderBox(renderBox); - } - } - - this.windowAdapter.OnGUI(); - } - - void Update() { - this.windowAdapter.Update(); - } - - void OnEnable() { - this.windowAdapter = new EditorWindowAdapter(this); - this.windowAdapter.OnEnable(); - - this._tapRecognizer = new TapGestureRecognizer(); - this._tapRecognizer.onTap = () => { Debug.Log("tap"); }; - - this._panRecognizer = new PanGestureRecognizer(); - this._panRecognizer.onUpdate = (details) => { Debug.Log("onUpdate " + details); }; - - this._doubleTapGesture = new DoubleTapGestureRecognizer(); - this._doubleTapGesture.onDoubleTap = (detail) => { Debug.Log("onDoubleTap"); }; - } - - void OnDisable() { - this.windowAdapter.OnDisable(); - this.windowAdapter = null; - } - - TapGestureRecognizer _tapRecognizer; - - PanGestureRecognizer _panRecognizer; - - DoubleTapGestureRecognizer _doubleTapGesture; - - void _handlePointerDown(PointerDownEvent evt) { - this._tapRecognizer.addPointer(evt); - this._panRecognizer.addPointer(evt); - this._doubleTapGesture.addPointer(evt); - } - - RenderBox tap() { - return new RenderPointerListener( - onPointerDown: this._handlePointerDown, - behavior: HitTestBehavior.opaque, - child: new RenderConstrainedBox( - additionalConstraints: BoxConstraints.tight(Size.square(100)), - child: new RenderDecoratedBox( - decoration: new BoxDecoration( - color: new Color(0xFF00FF00) - ) - )) - ); - } - } -} \ No newline at end of file diff --git a/Tests/Editor/Gestures.cs.meta b/Tests/Editor/Gestures.cs.meta deleted file mode 100644 index cc4e9a0c..00000000 --- a/Tests/Editor/Gestures.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: b6e93a3e08aa4ed49ebe367645f04fd9 -timeCreated: 1536304600 \ No newline at end of file diff --git a/Tests/Editor/Menu.cs b/Tests/Editor/Menu.cs deleted file mode 100644 index 1965dc6a..00000000 --- a/Tests/Editor/Menu.cs +++ /dev/null @@ -1,45 +0,0 @@ -using UnityEditor; - -namespace UIWidgets.Tests { - public static class Menu { - [MenuItem("UIWidgetsTests/CanvasAndLayers")] - public static void canvasAndLayers() { - EditorWindow.GetWindow(typeof(CanvasAndLayers)); - } - - [MenuItem("UIWidgetsTests/RenderBoxes")] - public static void renderBoxes() { - EditorWindow.GetWindow(typeof(RenderBoxes)); - } - - [MenuItem("UIWidgetsTests/RenderParagraph")] - public static void renderRenderParagraph() { - EditorWindow.GetWindow(typeof(Paragraph)); - } - - [MenuItem("UIWidgetsTests/Gestures")] - public static void gestures() { - EditorWindow.GetWindow(typeof(Gestures)); - } - - [MenuItem("UIWidgetsTests/RenderEditable")] - public static void renderEditable() { - EditorWindow.GetWindow(typeof(RenderEditable)); - } - - [MenuItem("UIWidgetsTests/Widgets")] - public static void renderWidgets() { - EditorWindow.GetWindow(typeof(Widgets)); - } - - [MenuItem("UIWidgetsTests/Show SceneViewTests")] - public static void showSceneView() { - SceneViewTests.show(); - } - - [MenuItem("UIWidgetsTests/Hide SceneViewTests")] - public static void hideSceneView() { - SceneViewTests.hide(); - } - } -} \ No newline at end of file diff --git a/Tests/Editor/Menu.cs.meta b/Tests/Editor/Menu.cs.meta deleted file mode 100644 index 6dc65f6f..00000000 --- a/Tests/Editor/Menu.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: a00837aa7e8a44daeb1df672601c872c -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/Editor/MouseHover.cs b/Tests/Editor/MouseHover.cs deleted file mode 100644 index 1cc0f73e..00000000 --- a/Tests/Editor/MouseHover.cs +++ /dev/null @@ -1,92 +0,0 @@ -using System.Collections.Generic; -using Unity.UIWidgets.foundation; -using Unity.UIWidgets.painting; -using Unity.UIWidgets.rendering; -using Unity.UIWidgets.widgets; -using UnityEngine; -using Color = Unity.UIWidgets.ui.Color; - -namespace UIWidgets.Tests { - public class MouseHoverWidget : StatefulWidget { - public MouseHoverWidget(Key key = null) : base(key) { - } - - public override State createState() { - return new _MouseHoverWidgetState(); - } - } - - class _MouseHoverWidgetState : State { - public static Widget createRow(bool canHover = true, bool nest = false) { - Widget result = new Container(width: 200, height: 60, color: Color.fromARGB(255, 255, 0, 255)); - if (canHover) { - result = new HoverTrackWidget(null, - result, "inner"); - } - - if (nest) { - result = new Container(child: result, padding: EdgeInsets.all(40), - color: Color.fromARGB(255, 255, 0, 0)); - result = new HoverTrackWidget(null, - result, "outer"); - } - - return result; - } - - public override Widget build(BuildContext context) { - //1 131231 - return new Container( - alignment: Alignment.center, color: Color.fromARGB(255, 0, 255, 0), - child: new Column( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: new List { - createRow(), - createRow(false), - createRow(), - createRow(true, true), - })); - } - } - - public class HoverTrackWidget : StatefulWidget { - public readonly Widget child; - public readonly string name; - - public HoverTrackWidget(Key key, Widget child, string name) : base(key) { - this.child = child; - this.name = name; - } - - public override State createState() { - return new _HoverTrackWidgetState(); - } - } - - class _HoverTrackWidgetState : State { - bool hover; - - public override Widget build(BuildContext context) { - return new Listener(child: - new Container( - forgroundDecoration: this.hover - ? new BoxDecoration(color: Color.fromARGB(80, 255, 255, 255)) - : null, - child: this.widget.child - ), - onPointerEnter: (evt) => { - if (this.mounted) { - Debug.Log(this.widget.name + " pointer enter"); - this.setState(() => { this.hover = true; }); - } - }, - onPointerExit: (evt) => { - if (this.mounted) { - Debug.Log(this.widget.name + " pointer exit"); - this.setState(() => { this.hover = false; }); - } - } - ); - } - } -} \ No newline at end of file diff --git a/Tests/Editor/MouseHover.cs.meta b/Tests/Editor/MouseHover.cs.meta deleted file mode 100644 index e093b909..00000000 --- a/Tests/Editor/MouseHover.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: ec7305290445466da6da50593cdaa4b7 -timeCreated: 1542181137 \ No newline at end of file diff --git a/Tests/Editor/Paragraph.cs b/Tests/Editor/Paragraph.cs deleted file mode 100644 index 79e8dd53..00000000 --- a/Tests/Editor/Paragraph.cs +++ /dev/null @@ -1,236 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Unity.UIWidgets.editor; -using Unity.UIWidgets.painting; -using Unity.UIWidgets.rendering; -using Unity.UIWidgets.ui; -using UnityEditor; -using UnityEngine; -using Color = Unity.UIWidgets.ui.Color; -using FontStyle = Unity.UIWidgets.ui.FontStyle; -using TextStyle = Unity.UIWidgets.painting.TextStyle; - -namespace UIWidgets.Tests { - public class Paragraph : EditorWindow { - readonly Func[] _options; - - readonly string[] _optionStrings; - - int _selected; - - Paragraph() { - this._options = new Func[] { - this.text, - this.textHeight, - this.textOverflow, - this.textAlign, - this.textDecoration, - }; - this._optionStrings = this._options.Select(x => x.Method.Name).ToArray(); - this._selected = 0; - - this.titleContent = new GUIContent("RenderParagraph"); - } - - WindowAdapter windowAdapter; - - [NonSerialized] bool hasInvoked = false; - - void OnGUI() { - var selected = EditorGUILayout.Popup("test case", this._selected, this._optionStrings); - if (selected != this._selected || !this.hasInvoked) { - this._selected = selected; - this.hasInvoked = true; - - var renderBox = this._options[this._selected](); - this.windowAdapter.attachRootRenderBox(renderBox); - } - - this.windowAdapter.OnGUI(); - } - - void Update() { - this.windowAdapter.Update(); - } - - void OnEnable() { - this.windowAdapter = new EditorWindowAdapter(this); - this.windowAdapter.OnEnable(); - } - - void OnDisable() { - this.windowAdapter.OnDisable(); - this.windowAdapter = null; - } - - RenderBox none() { - return null; - } - - RenderBox box(RenderParagraph p, int width = 200, int height = 200) { - return new RenderConstrainedOverflowBox( - minWidth: width, - maxWidth: width, - minHeight: height, - maxHeight: height, - alignment: Alignment.center, - child: p - ) - ; - } - - RenderBox flexItemBox(RenderParagraph p, int width = 200, int height = 150) { - return new RenderConstrainedBox( - additionalConstraints: new BoxConstraints(minWidth: width, maxWidth: width, minHeight: height, - maxHeight: height), - child: new RenderDecoratedBox( - decoration: new BoxDecoration( - color: new Color(0xFFFFFFFF), - borderRadius: BorderRadius.all(3), - border: Border.all(Color.fromARGB(255, 255, 0, 0), 1) - ), - child: new RenderPadding(EdgeInsets.all(10), p - ) - )); - } - - RenderBox text() { - return this.box( - new RenderParagraph(new TextSpan("", children: - new List() { - new TextSpan("Real-time 3D revolutioni淡粉色的方式地方zes the animation pipeline ", null), - new TextSpan(style: new TextStyle(color: Color.fromARGB(255, 255, 0, 0)), - text: "for Disney Television Animation's “Baymax Dreams"), - new TextSpan(" Unity Widgets"), - new TextSpan(" Text"), - new TextSpan("Real-time 3D revolutionizes the animation pipeline "), - new TextSpan(style: new TextStyle(color: Color.fromARGB(125, 255, 0, 0)), - text: "Transparent Red Text\n\n"), - new TextSpan(style: new TextStyle(fontWeight: FontWeight.w700), - text: "Bold Text Test Bold Textfs Test: FontWeight.w70\n\n"), - new TextSpan(style: new TextStyle(fontStyle: FontStyle.italic), - text: "This is FontStyle.italic Text This is FontStyle.italic Text\n\n"), - new TextSpan( - style: new TextStyle(fontStyle: FontStyle.italic, fontWeight: FontWeight.w700), - text: - "This is FontStyle.italic And 发撒放豆腐sad 发生的 Bold Text This is FontStyle.italic And Bold Text\n\n"), - new TextSpan(style: new TextStyle(fontSize: 18), - text: "FontSize 18: Get a named matrix value from the shader.\n\n"), - new TextSpan(style: new TextStyle(fontSize: 24), - text: "Emoji \ud83d\ude0a\ud83d\ude0b\ud83d\ude0d\ud83d\ude0e\ud83d\ude00"), - new TextSpan(style: new TextStyle(fontSize: 14), - text: "Emoji \ud83d\ude0a\ud83d\ude0b\ud83d\ude0d\ud83d\ude0e\ud83d\ude00 Emoji"), - new TextSpan(style: new TextStyle(fontSize: 18), - text: "Emoji \ud83d\ude01\ud83d\ude02\ud83d\ude03\ud83d\ude04\ud83d\ude05"), - new TextSpan(style: new TextStyle(fontSize: 18), - text: "\ud83d\ude01\ud83d\ude02\ud83d\ude03\ud83d\ude04\ud83d\ude05"), - new TextSpan(style: new TextStyle(fontSize: 18), - text: "\ud83d\ude01\ud83d\ude02\ud83d\ude03\ud83d\ude04\ud83d\ude05"), - new TextSpan(style: new TextStyle(fontSize: 18), - text: "\ud83d\ude01\ud83d\ude02\ud83d\ude03\ud83d\ude04\ud83d\ude05"), - new TextSpan(style: new TextStyle(fontSize: 18), - text: "\ud83d\ude01\ud83d\ude02\ud83d\ude03\ud83d\ude04\ud83d\ude05"), - new TextSpan(style: new TextStyle(fontSize: 24), - text: "Emoji \ud83d\ude06\ud83d\ude1C\ud83d\ude18\ud83d\ude2D\ud83d\ude0C\ud83d\ude1E\n\n"), - new TextSpan(style: new TextStyle(fontSize: 14), - text: "FontSize 14"), - }))); - } - - RenderBox textDecoration() { - return this.box( - new RenderParagraph(new TextSpan(style: new TextStyle(height: 1.2f), text: "", children: - new List() { - new TextSpan(style: new TextStyle(color: Color.fromARGB(255, 255, 0, 0), - decoration: TextDecoration.underline), - text: "Real-time 3D revolution\n"), - new TextSpan(style: new TextStyle(color: Color.fromARGB(255, 255, 0, 0), - decoration: TextDecoration.underline, decorationStyle: TextDecorationStyle.doubleLine), - text: "Double line Real-time 3D revolution\n"), - new TextSpan(style: new TextStyle(color: Color.fromARGB(255, 255, 0, 0), - decoration: TextDecoration.underline, fontSize: 24), - text: "Real-time 3D revolution\n"), - new TextSpan(style: new TextStyle(color: Color.fromARGB(255, 255, 0, 0), - decoration: TextDecoration.overline), - text: "Over line Real-time 3D revolution\n"), - new TextSpan(style: new TextStyle(color: Color.fromARGB(255, 255, 0, 0), - decoration: TextDecoration.overline, decorationStyle: TextDecorationStyle.doubleLine), - text: "Over line Real-time 3D revolution\n"), - new TextSpan(style: new TextStyle(color: Color.fromARGB(255, 255, 0, 0), - decoration: TextDecoration.lineThrough), - text: "Line through Real-time 3D revolution\n"), - new TextSpan(style: new TextStyle(color: Color.fromARGB(255, 255, 0, 0), - decoration: TextDecoration.lineThrough, - decorationColor: Color.fromARGB(255, 0, 255, 0)), - text: "Color Line through Real-time 3D revolution\n"), - })), width: 400); - } - - RenderBox textAlign() { - var flexbox = new RenderFlex( - direction: Axis.vertical, - mainAxisAlignment: MainAxisAlignment.spaceAround, - crossAxisAlignment: CrossAxisAlignment.center); - var height = 120; - - flexbox.add(this.flexItemBox( - new RenderParagraph(new TextSpan(EditorGUIUtility.pixelsPerPoint.ToString() + - "Align To Left\nMaterials define how light reacts with the " + - "surface of a model, and are an essential ingredient in making " + - "believable visuals. When you’ve created a "), - textAlign: TextAlign.left), - height: height - )); - flexbox.add(this.flexItemBox( - new RenderParagraph(new TextSpan(EditorGUIUtility.pixelsPerPoint.ToString() + - "Align To Rgit\nMaterials define how light reacts with the " + - "surface of a model, and are an essential ingredient in making " + - "believable visuals. When you’ve created a "), - textAlign: TextAlign.right), - height: height - )); - flexbox.add(this.flexItemBox( - new RenderParagraph(new TextSpan(EditorGUIUtility.pixelsPerPoint.ToString() + - "Align To Center\nMaterials define how light reacts with the " + - "surface of a model, and are an essential ingredient in making " + - "believable visuals. When you’ve created a "), - textAlign: TextAlign.center), - height: height - )); - flexbox.add(this.flexItemBox( - new RenderParagraph(new TextSpan("Align To Justify\nMaterials define how light reacts with the " + - "surface of a model, and are an essential ingredient in making " + - "believable visuals. When you’ve created a "), - textAlign: TextAlign.justify), - height: height - )); - return flexbox; - } - - RenderBox textOverflow() { - return this.box( - new RenderParagraph(new TextSpan("", children: - new List() { - new TextSpan( - "Real-time 3D revolutionizes:\n the animation pipeline.\n\n\nrevolutionizesn\n\nReal-time 3D revolutionizes the animation pipeline ", - null), - }), maxLines: 3), 200, 80); - } - - RenderBox textHeight() { - var text = - "Hello UIWidgets. Real-time 3D revolutionize \nReal-time 3D revolutionize\nReal-time 3D revolutionize\n\n"; - return this.box( - new RenderParagraph(new TextSpan(text: "", children: - new List() { - new TextSpan(style: new TextStyle(height: 1), - text: "Height 1.0 Text:" + text), - new TextSpan(style: new TextStyle(height: 1.2f), - text: "Height 1.2 Text:" + text), - new TextSpan(style: new TextStyle(height: 1.5f), - text: "Height 1.5 Text:" + text), - })), width: 300, height: 300); - } - } -} \ No newline at end of file diff --git a/Tests/Editor/Paragraph.cs.meta b/Tests/Editor/Paragraph.cs.meta deleted file mode 100644 index 703ef8e8..00000000 --- a/Tests/Editor/Paragraph.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: f4121086094d45de9e29781269270102 -timeCreated: 1535424100 \ No newline at end of file diff --git a/Tests/Editor/RenderBoxes.cs b/Tests/Editor/RenderBoxes.cs deleted file mode 100644 index 8b92677b..00000000 --- a/Tests/Editor/RenderBoxes.cs +++ /dev/null @@ -1,153 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Unity.UIWidgets.editor; -using Unity.UIWidgets.painting; -using Unity.UIWidgets.rendering; -using Unity.UIWidgets.ui; -using UnityEditor; -using UnityEngine; -using Color = Unity.UIWidgets.ui.Color; - -namespace UIWidgets.Tests { - public class RenderBoxes : EditorWindow { - readonly Func[] _options; - - readonly string[] _optionStrings; - - int _selected; - - RenderBoxes() { - this._options = new Func[] { - this.decoratedBox, - this.decoratedShape, - this.flex, - }; - this._optionStrings = this._options.Select(x => x.Method.Name).ToArray(); - this._selected = 0; - - this.titleContent = new GUIContent("RenderBoxes"); - } - - WindowAdapter windowAdapter; - - [NonSerialized] bool hasInvoked = false; - - void OnGUI() { - var selected = EditorGUILayout.Popup("test case", this._selected, this._optionStrings); - if (selected != this._selected || !this.hasInvoked) { - this._selected = selected; - this.hasInvoked = true; - - var renderBox = this._options[this._selected](); - this.windowAdapter.attachRootRenderBox(renderBox); - } - - this.windowAdapter.OnGUI(); - } - - void Update() { - this.windowAdapter.Update(); - } - - void OnEnable() { - this.windowAdapter = new EditorWindowAdapter(this); - this.windowAdapter.OnEnable(); - } - - void OnDisable() { - this.windowAdapter.OnDisable(); - this.windowAdapter = null; - } - - RenderBox none() { - return null; - } - - RenderBox decoratedBox() { - return new RenderConstrainedOverflowBox( - minWidth: 100, - maxWidth: 100, - minHeight: 100, - maxHeight: 100, - child: new RenderDecoratedBox( - decoration: new BoxDecoration( - color: new Color(0xFFFF00FF), - borderRadius: BorderRadius.all(15), - boxShadow: new List { - new BoxShadow( - color: new Color(0xFFFF00FF), - offset: new Offset(0, 0), - blurRadius: 3.0f, - spreadRadius: 10 - ) - }, - image: new DecorationImage( - image: new NetworkImage( - url: - "https://sg.fiverrcdn.com/photos/4665137/original/39322-140411095619534.jpg?1424268945" - ), - fit: BoxFit.cover) - ) - ) - ); - } - - RenderBox decoratedShape() { - return new RenderConstrainedOverflowBox( - minWidth: 100, - maxWidth: 100, - minHeight: 100, - maxHeight: 100, - child: new RenderDecoratedBox( - decoration: new ShapeDecoration( - color: new Color(0xFFFF00FF), - shape: new BeveledRectangleBorder( - new BorderSide(width: 5, color: Color.white), - BorderRadius.circular(5)), - image: new DecorationImage( - image: new NetworkImage( - url: - "https://sg.fiverrcdn.com/photos/4665137/original/39322-140411095619534.jpg?1424268945" - ), - fit: BoxFit.cover) - ) - ) - ); - } - - - RenderBox flex() { - var flexbox = new RenderFlex( - direction: Axis.horizontal, - crossAxisAlignment: CrossAxisAlignment.center); - - flexbox.add(new RenderConstrainedBox( - additionalConstraints: new BoxConstraints(minWidth: 300, minHeight: 200), - child: new RenderDecoratedBox( - decoration: new BoxDecoration( - color: new Color(0xFF00FF00) - ) - ))); - - flexbox.add(new RenderConstrainedBox( - additionalConstraints: new BoxConstraints(minWidth: 100, minHeight: 300), - child: new RenderDecoratedBox( - decoration: new BoxDecoration( - color: new Color(0xFF00FFFF) - ) - ))); - - flexbox.add(new RenderConstrainedBox( - additionalConstraints: new BoxConstraints(minWidth: 50, minHeight: 100), - child: new RenderDecoratedBox( - decoration: new BoxDecoration( - color: new Color(0xFF0000FF) - ) - ))); - - - return flexbox; - } - } -} \ No newline at end of file diff --git a/Tests/Editor/RenderBoxes.cs.meta b/Tests/Editor/RenderBoxes.cs.meta deleted file mode 100644 index d33221aa..00000000 --- a/Tests/Editor/RenderBoxes.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: e773b48a6f94416d89e1f690b34c1379 -timeCreated: 1534920245 \ No newline at end of file diff --git a/Tests/Editor/RenderEditable.cs b/Tests/Editor/RenderEditable.cs deleted file mode 100644 index b6a966ed..00000000 --- a/Tests/Editor/RenderEditable.cs +++ /dev/null @@ -1,201 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using RSG; -using Unity.UIWidgets.animation; -using Unity.UIWidgets.editor; -using Unity.UIWidgets.foundation; -using Unity.UIWidgets.painting; -using Unity.UIWidgets.rendering; -using Unity.UIWidgets.service; -using Unity.UIWidgets.ui; -using UnityEditor; -using UnityEngine; -using Color = Unity.UIWidgets.ui.Color; -using TextStyle = Unity.UIWidgets.painting.TextStyle; - -namespace UIWidgets.Tests { - public class RenderEditable : EditorWindow, TextSelectionDelegate { - readonly Func[] _options; - - readonly string[] _optionStrings; - - int _selected; - - class _FixedViewportOffset : ViewportOffset { - internal _FixedViewportOffset(float _pixels) { - this._pixels = _pixels; - } - - internal new static _FixedViewportOffset zero() { - return new _FixedViewportOffset(0.0f); - } - - float _pixels; - - public override float pixels { - get { return this._pixels; } - } - - public override bool applyViewportDimension(float viewportDimension) { - return true; - } - - public override bool applyContentDimensions(float minScrollExtent, float maxScrollExtent) { - return true; - } - - public override void correctBy(float correction) { - this._pixels += correction; - } - - public override void jumpTo(float pixels) { - } - - public override IPromise animateTo(float to, TimeSpan duration, Curve curve) { - return Promise.Resolved(); - } - - public override ScrollDirection userScrollDirection { - get { return ScrollDirection.idle; } - } - - public override bool allowImplicitScrolling { - get { return false; } - } - } - - RenderEditable() { - this._options = new Func[] { - this.textEditable, - }; - this._optionStrings = this._options.Select(x => x.Method.Name).ToArray(); - this._selected = 0; - this.titleContent = new GUIContent("RenderEditable"); - } - - WindowAdapter windowAdapter; - - [NonSerialized] bool hasInvoked = false; - - void OnGUI() { - var selected = EditorGUILayout.Popup("test case", this._selected, this._optionStrings); - if (selected != this._selected || !this.hasInvoked) { - this._selected = selected; - this.hasInvoked = true; - - var renderBox = this._options[this._selected](); - this.windowAdapter.attachRootRenderBox(renderBox); - } - - this.windowAdapter.OnGUI(); - } - - void Update() { - this.windowAdapter.Update(); - } - - void OnEnable() { - this.windowAdapter = new EditorWindowAdapter(this); - this.windowAdapter.OnEnable(); - } - - void OnDisable() { - this.windowAdapter.OnDisable(); - this.windowAdapter = null; - } - - RenderBox box(RenderBox p, int width = 400, int height = 400) { - return new RenderConstrainedOverflowBox( - minWidth: width, - maxWidth: width, - minHeight: height, - maxHeight: height, - alignment: Alignment.center, - child: p - ) - ; - } - - RenderBox flexItemBox(RenderBox p, int width = 200, int height = 100) { - return new RenderConstrainedBox( - additionalConstraints: new BoxConstraints(minWidth: width, maxWidth: width, minHeight: height, - maxHeight: height), - child: new RenderDecoratedBox( - decoration: new BoxDecoration( - color: new Color(0xFFFFFFFF), - borderRadius: BorderRadius.all(3), - border: Border.all(Color.fromARGB(255, 255, 0, 0), 1) - ), - child: new RenderPadding(EdgeInsets.all(10), p - ) - )); - } - - RenderBox textEditable() { - var span = new TextSpan("", children: - new List { - new TextSpan( - "Word Wrap:The ascent of the font is the distance from the baseline to the top line of the font, as defined in the font's original data file.", - null), - }, style: new TextStyle(height: 1.0f)); - - var flexbox = new RenderFlex( - direction: Axis.vertical, - mainAxisAlignment: MainAxisAlignment.spaceAround, - crossAxisAlignment: CrossAxisAlignment.center); - - flexbox.add(this.flexItemBox( - new Unity.UIWidgets.rendering.RenderEditable(span, TextDirection.ltr, - new _FixedViewportOffset(0.0f), new ValueNotifier(true), - onSelectionChanged: this.selectionChanged, cursorColor: Color.fromARGB(255, 0, 0, 0), - maxLines: 100, - selectionColor: Color.fromARGB(255, 255, 0, 0), - textSelectionDelegate: this) - )); - - span = new TextSpan("", children: - new List { - new TextSpan( - "Hard Break:The ascent of the font is the distance\nfrom the baseline to the top \nline of the font,\nas defined in", - null), - }, style: new TextStyle(height: 1.0f)); - flexbox.add(this.flexItemBox( - new Unity.UIWidgets.rendering.RenderEditable(span, TextDirection.ltr, - new _FixedViewportOffset(0.0f), new ValueNotifier(true), - onSelectionChanged: this.selectionChanged, cursorColor: Color.fromARGB(255, 0, 0, 0), - maxLines: 100, - selectionColor: Color.fromARGB(255, 255, 0, 0), - textSelectionDelegate: this) - )); - - span = new TextSpan("", children: - new List { - new TextSpan("Single Line:How to create mixin", null), - }, style: new TextStyle(height: 1.0f)); - flexbox.add(this.flexItemBox( - new Unity.UIWidgets.rendering.RenderEditable(span, TextDirection.ltr, - new _FixedViewportOffset(0.0f), new ValueNotifier(true), - onSelectionChanged: this.selectionChanged, cursorColor: Color.fromARGB(255, 0, 0, 0), - selectionColor: Color.fromARGB(255, 255, 0, 0), - textSelectionDelegate: this) - , width: 300)); - return flexbox; - } - - - void selectionChanged(TextSelection selection, Unity.UIWidgets.rendering.RenderEditable renderObject, - SelectionChangedCause cause) { - Debug.Log($"selection {selection}"); - renderObject.selection = selection; - } - - public TextEditingValue textEditingValue { get; set; } - - public void hideToolbar() { - } - - public void bringIntoView(TextPosition textPosition) { - } - } -} \ No newline at end of file diff --git a/Tests/Editor/RenderEditable.cs.meta b/Tests/Editor/RenderEditable.cs.meta deleted file mode 100644 index 720a1d10..00000000 --- a/Tests/Editor/RenderEditable.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 3133671f82dc4c0e93d4dbeb9e50b55d -timeCreated: 1536660300 \ No newline at end of file diff --git a/Tests/Editor/SceneViewTests.cs b/Tests/Editor/SceneViewTests.cs deleted file mode 100644 index 03396e2c..00000000 --- a/Tests/Editor/SceneViewTests.cs +++ /dev/null @@ -1,165 +0,0 @@ -using System; -using System.Linq; -using System.Reflection; -using Unity.UIWidgets.editor; -using Unity.UIWidgets.painting; -using Unity.UIWidgets.rendering; -using Unity.UIWidgets.widgets; -using UnityEditor; -using UnityEngine; -using Color = Unity.UIWidgets.ui.Color; - -namespace UIWidgets.Tests { - public class SceneViewTests { - public static void show() { - onPreSceneGUIDelegate += OnPreSceneGUI; -#pragma warning disable 0618 - SceneView.onSceneGUIDelegate += OnSceneGUI; -#pragma warning restore 0618 - EditorApplication.update += Update; - - SceneView.RepaintAll(); - - _options = new Func[] { - none, - listView, - eventsPage, - }; - _optionStrings = _options.Select(x => x.Method.Name).ToArray(); - _selected = 0; - } - - public static void hide() { - onPreSceneGUIDelegate -= OnPreSceneGUI; -#pragma warning disable 0618 - SceneView.onSceneGUIDelegate -= OnSceneGUI; -#pragma warning restore 0618 - EditorApplication.update -= Update; - SceneView.RepaintAll(); - } - -#pragma warning disable 0618 - public static SceneView.OnSceneFunc onPreSceneGUIDelegate { - get { - var field = typeof(SceneView).GetField("onPreSceneGUIDelegate", - BindingFlags.Static | BindingFlags.NonPublic); - - return (SceneView.OnSceneFunc) field.GetValue(null); - } - - set { - var field = typeof(SceneView).GetField("onPreSceneGUIDelegate", - BindingFlags.Static | BindingFlags.NonPublic); - - field.SetValue(null, value); - } - } -#pragma warning restore 0618 - - static Func[] _options; - - static string[] _optionStrings; - - static int _selected; - - [NonSerialized] static bool hasInvoked = false; - - static EventType _lastEventType; - - static void OnPreSceneGUI(SceneView sceneView) { - _lastEventType = Event.current.rawType; - } - - static void OnSceneGUI(SceneView sceneView) { - //HandleUtility.AddDefaultControl(GUIUtility.GetControlID(FocusType.Passive)); - Handles.BeginGUI(); - - if (windowAdapter == null) { - windowAdapter = new EditorWindowAdapter(sceneView); - } - else if (windowAdapter != null && windowAdapter.editorWindow != sceneView) { - windowAdapter = new EditorWindowAdapter(sceneView); - } - - var selected = EditorGUILayout.Popup("test case", _selected, _optionStrings); - if (selected != _selected || !hasInvoked) { - _selected = selected; - hasInvoked = true; - - var widget = _options[_selected](); - windowAdapter.attachRootWidget(widget); - } - - if (Event.current.type == EventType.Used) { - Event.current.type = _lastEventType; - windowAdapter.OnGUI(); - Event.current.type = EventType.Used; - } - else { - windowAdapter.OnGUI(); - } - - Handles.EndGUI(); - } - - static void Update() { - if (windowAdapter != null) { - windowAdapter.Update(); - } - } - - static EditorWindowAdapter windowAdapter; - - public static Widget none() { - return null; - } - - public static Widget listView() { - return ListView.builder( - itemExtent: 20.0f, - itemBuilder: (context, index) => { - return new Container( - color: Color.fromARGB(255, (index * 10) % 256, (index * 10) % 256, (index * 10) % 256) - ); - } - ); - } - - public static Widget eventsPage() { - return new EventsWaterfallScreen(); - } - - public static RenderBox flex() { - var flexbox = new RenderFlex( - direction: Axis.horizontal, - crossAxisAlignment: CrossAxisAlignment.center); - - flexbox.add(new RenderConstrainedBox( - additionalConstraints: new BoxConstraints(minWidth: 300, minHeight: 200), - child: new RenderDecoratedBox( - decoration: new BoxDecoration( - color: new Color(0xFF00FF00) - ) - ))); - - flexbox.add(new RenderConstrainedBox( - additionalConstraints: new BoxConstraints(minWidth: 100, minHeight: 300), - child: new RenderDecoratedBox( - decoration: new BoxDecoration( - color: new Color(0xFF00FFFF) - ) - ))); - - flexbox.add(new RenderConstrainedBox( - additionalConstraints: new BoxConstraints(minWidth: 50, minHeight: 100), - child: new RenderDecoratedBox( - decoration: new BoxDecoration( - color: new Color(0xFF0000FF) - ) - ))); - - - return flexbox; - } - } -} \ No newline at end of file diff --git a/Tests/Editor/SceneViewTests.cs.meta b/Tests/Editor/SceneViewTests.cs.meta deleted file mode 100644 index c7b3ff8f..00000000 --- a/Tests/Editor/SceneViewTests.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: fc7ab0f913ef4bde95759153a732dbc0 -timeCreated: 1537936714 \ No newline at end of file diff --git a/Tests/Editor/Unity.UIWidgets.Editor.Tests.asmdef b/Tests/Editor/Unity.UIWidgets.Editor.Tests.asmdef deleted file mode 100644 index b24ca118..00000000 --- a/Tests/Editor/Unity.UIWidgets.Editor.Tests.asmdef +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "Unity.UIWidgets.Editor.Tests", - "references": [ - "Unity.UIWidgets.Editor", - "Unity.UIWidgets" - ], - "optionalUnityReferences": [ - "TestAssemblies" - ], - "includePlatforms": [ - "Editor" - ], - "excludePlatforms": [] -} diff --git a/Tests/Editor/Unity.UIWidgets.Editor.Tests.asmdef.meta b/Tests/Editor/Unity.UIWidgets.Editor.Tests.asmdef.meta deleted file mode 100644 index 17311a33..00000000 --- a/Tests/Editor/Unity.UIWidgets.Editor.Tests.asmdef.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: ddfee6fb567544c4d81e78d84f47d64c -AssemblyDefinitionImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/Editor/Widgets.cs b/Tests/Editor/Widgets.cs deleted file mode 100644 index 075fc7ac..00000000 --- a/Tests/Editor/Widgets.cs +++ /dev/null @@ -1,919 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using UIWidgets.Tests.demo_charts; -using Unity.UIWidgets.animation; -using Unity.UIWidgets.editor; -using Unity.UIWidgets.foundation; -using Unity.UIWidgets.gestures; -using Unity.UIWidgets.material; -using Unity.UIWidgets.painting; -using Unity.UIWidgets.rendering; -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; -using UnityEditor; -using UnityEngine; -using Color = Unity.UIWidgets.ui.Color; -using Image = Unity.UIWidgets.widgets.Image; -using TextStyle = Unity.UIWidgets.painting.TextStyle; -using Transform = Unity.UIWidgets.widgets.Transform; - -namespace UIWidgets.Tests { - public class Widgets : EditorWindow { - WindowAdapter windowAdapter; - - readonly Func[] _options; - - readonly string[] _optionStrings; - - int _selected; - - string localImagePath; - - [NonSerialized] bool hasInvoked = false; - - public Widgets() { - this.wantsMouseEnterLeaveWindow = true; - this.wantsMouseMove = true; - this._options = new Func[] { - this.localImage, - this.container, - this.flexRow, - this.flexColumn, - this.containerSimple, - this.eventsPage, - this.asPage, - this.stack, - this.mouseHover, - this.charts - }; - this._optionStrings = this._options.Select(x => x.Method.Name).ToArray(); - this._selected = 0; - - this.titleContent = new GUIContent("Widgets Test"); - } - - void OnGUI() { - var selected = EditorGUILayout.Popup("test case", this._selected, this._optionStrings); - - // if local image test - if (selected == 0) { - this.localImagePath = EditorGUILayout.TextField(this.localImagePath); - - if (this._selected != selected) { - this._selected = selected; - this._attachRootWidget(new Container()); - } - - if (GUILayout.Button("loadLocal")) { - var rootWidget = this._options[this._selected](); - this._attachRootWidget(rootWidget); - } - - if (GUILayout.Button("loadAsset")) { - var rootWidget = this.loadAsset(); - this._attachRootWidget(rootWidget); - } - - if (GUILayout.Button("UnloadUnusedAssets")) { - Resources.UnloadUnusedAssets(); - } - } - else if (selected != this._selected || !this.hasInvoked) { - this._selected = selected; - this.hasInvoked = true; - - var rootWidget = this._options[this._selected](); - - this._attachRootWidget(rootWidget); - } - - this.windowAdapter.OnGUI(); - } - - void _attachRootWidget(Widget widget) { - this.windowAdapter.attachRootWidget(() => new WidgetsApp( - home: widget, - navigatorKey: GlobalKey.key(), - pageRouteBuilder: (RouteSettings settings, WidgetBuilder builder) => - new PageRouteBuilder( - settings: settings, - pageBuilder: (BuildContext context, Animation animation, - Animation secondaryAnimation) => builder(context) - ))); - } - - void Update() { - this.windowAdapter.Update(); - } - - void OnEnable() { - FontManager.instance.addFont(Resources.Load("MaterialIcons-Regular"), "Material Icons"); - - this.windowAdapter = new EditorWindowAdapter(this); - this.windowAdapter.OnEnable(); - } - - void OnDisable() { - this.windowAdapter.OnDisable(); - this.windowAdapter = null; - } - - Widget stack() { - var image = new Container( - width: 150, - height: 150, - child: Image.network( - "https://tse3.mm.bing.net/th?id=OIP.XOAIpvR1kh-CzISe_Nj9GgHaHs&pid=Api", - width: 100, - height: 100 - ) - ); - var text = new Container( - width: 150, - height: 150, - child: new Text("TTTTTTTTTTTTTTTTEST") - ); - List rowImages = new List(); - rowImages.Add(image); - rowImages.Add(text); - return new Stack( - children: rowImages, - alignment: Alignment.center - ); - } - - Widget localImage() { - var image = Image.file(this.localImagePath, - filterMode: FilterMode.Bilinear - ); - - return image; - } - - Widget loadAsset() { - var image = Image.asset(this.localImagePath, - filterMode: FilterMode.Bilinear - ); - - return image; - } - - Widget flexRow() { - var image = Image.network( - "https://tse3.mm.bing.net/th?id=OIP.XOAIpvR1kh-CzISe_Nj9GgHaHs&pid=Api", - width: 100, - height: 100 - ); - List rowImages = new List(); - rowImages.Add(image); - rowImages.Add(image); - rowImages.Add(image); - rowImages.Add(image); - - var row = new Row( - textDirection: null, - textBaseline: null, - key: null, - mainAxisAlignment: MainAxisAlignment.start, - mainAxisSize: MainAxisSize.max, - crossAxisAlignment: CrossAxisAlignment.center, - verticalDirection: VerticalDirection.down, - children: rowImages - ); - - return row; - } - - Widget flexColumn() { - var image = Image.network( - "https://tse3.mm.bing.net/th?id=OIP.XOAIpvR1kh-CzISe_Nj9GgHaHs&pid=Api", - width: 100, - height: 100 - ); - List columnImages = new List(); - columnImages.Add(image); - columnImages.Add(image); - columnImages.Add(image); - - var column = new Column( - textDirection: null, - textBaseline: null, - key: null, - mainAxisAlignment: MainAxisAlignment.start, - mainAxisSize: MainAxisSize.max, - crossAxisAlignment: CrossAxisAlignment.center, - verticalDirection: VerticalDirection.down, - children: columnImages - ); - - return column; - } - - Widget container() { - var image = Image.network( - "https://tse3.mm.bing.net/th?id=OIP.XOAIpvR1kh-CzISe_Nj9GgHaHs&pid=Api", - width: 100, - height: 100, - repeat: ImageRepeat.repeatX - ); - var container = new Container( - width: 200, - height: 200, - margin: EdgeInsets.all(30.0f), - padding: EdgeInsets.all(15.0f), - child: image, - decoration: new BoxDecoration( - color: CLColors.white, - borderRadius: BorderRadius.all(30), - gradient: new LinearGradient(colors: new List {CLColors.blue, CLColors.red, CLColors.green}) - ) - ); - - return container; - } - - Widget containerSimple() { - var container = new Container( - alignment: Alignment.centerRight, - color: Color.fromARGB(255, 244, 190, 85), - child: new Container( - width: 120, - height: 120, - color: Color.fromARGB(255, 255, 0, 85) - ) - ); - - return container; - } - - Widget eventsPage() { - return new EventsWaterfallScreen(); - } - - Widget asPage() { - return new AsScreen(); - } - - Widget mouseHover() { - return new MouseHoverWidget(); - } - - Widget charts() { - return new ChartPage(); - } - } - - - public class AsScreen : StatefulWidget { - public AsScreen(Key key = null) : base(key) { - } - - public override State createState() { - return new _AsScreenState(); - } - } - - class _AsScreenState : State { - const float headerHeight = 50.0f; - - Widget _buildHeader(BuildContext context) { - var container = new Container( - padding: EdgeInsets.only(left: 16.0f, right: 8.0f), - height: headerHeight, - color: CLColors.header, - child: new Row( - mainAxisAlignment: MainAxisAlignment.center, - children: new List { - new Container( - child: new Text( - "All Assets", - style: new TextStyle( - fontSize: 16, - color: Color.fromARGB(100, 255, 255, 0) - ) - ) - ), - new CustomButton( - padding: EdgeInsets.only(0.0f, 0.0f, 16.0f, 0.0f), - child: new Icon( - Icons.keyboard_arrow_down, - size: 18.0f, - color: CLColors.icon2 - ) - ), - new Container( - decoration: new BoxDecoration( - color: CLColors.white, - borderRadius: BorderRadius.all(3) - ), - width: 320, - height: 36, - padding: EdgeInsets.all(10.0f), - margin: EdgeInsets.only(right: 4), - child: new EditableText( - maxLines: 1, - selectionControls: MaterialUtils.materialTextSelectionControls, - controller: new TextEditingController("Type here to search assets"), - focusNode: new FocusNode(), - style: new TextStyle( - fontSize: 16 - ), - selectionColor: Color.fromARGB(255, 255, 0, 0), - cursorColor: Color.fromARGB(255, 0, 0, 0) - ) - ), - new Container( - decoration: new BoxDecoration( - color: CLColors.background4, - borderRadius: BorderRadius.all(2) - ), - width: 36, - height: 36, - child: new Row( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: new List { - new CustomButton( - padding: EdgeInsets.only(8.0f, 0.0f, 8.0f, 0.0f), - child: new Icon( - Icons.search, - size: 18.0f, - color: CLColors.white - ) - ) - } - ) - ), - new Container( - margin: EdgeInsets.only(left: 16, right: 16), - child: new Text( - "Learn Game Development", - style: new TextStyle( - fontSize: 12, - color: CLColors.white - ) - ) - ), - new Container( - decoration: new BoxDecoration( - border: Border.all( - color: CLColors.white - ) - ), - margin: EdgeInsets.only(right: 16), - padding: EdgeInsets.all(4), - child: new Row( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: new List { - new Text( - "Plus/Pro", - style: new TextStyle( - fontSize: 11, - color: CLColors.white - ) - ) - } - ) - ), - new Container( - margin: EdgeInsets.only(right: 16), - child: new Text( - "Impressive New Assets", - style: new TextStyle( - fontSize: 12, - color: CLColors.white - ) - ) - ), - new Container( - child: new Text( - "Shop On Old Store", - style: new TextStyle( - fontSize: 12, - color: CLColors.white - ) - ) - ), - } - ) - ); - - return container; - } - - Widget _buildFooter(BuildContext context) { - return new Container( - color: CLColors.header, - margin: EdgeInsets.only(top: 50), - height: 90, - child: new Row( - mainAxisAlignment: MainAxisAlignment.center, - children: new List { - new Container( - margin: EdgeInsets.only(right: 10), - child: new Text( - "Copyright © 2018 Unity Technologies", - style: new TextStyle( - fontSize: 12, - color: CLColors.text9 - ) - ) - ), - new Container( - margin: EdgeInsets.only(right: 10), - child: new Text( - "All prices are exclusive of tax", - style: new TextStyle( - fontSize: 12, - color: CLColors.text9 - ) - ) - ), - new Container( - margin: EdgeInsets.only(right: 10), - child: new Text( - "Terms of Service and EULA", - style: new TextStyle( - fontSize: 12, - color: CLColors.text10 - ) - ) - ), - new Container( - child: new Text( - "Cookies", - style: new TextStyle( - fontSize: 12, - color: CLColors.text10 - ) - ) - ), - } - ) - ); - } - - Widget _buildBanner(BuildContext context) { - return new Container( - height: 450, - color: CLColors.white, - child: Image.network( - "https://assetstorev1-prd-cdn.unity3d.com/banner/9716cc07-748c-43cc-8809-10113119c97a.jpg", - fit: BoxFit.cover, - filterMode: FilterMode.Bilinear - ) - ); - } - - Widget _buildTopAssetsRow(BuildContext context, string title) { - var testCard = new AssetCard( - "AI Template", - "INVECTOR", - 45.0f, - 36.0f, - true, - "https://assetstorev1-prd-cdn.unity3d.com/key-image/76a549ae-de17-4536-bd96-4231ed20dece.jpg" - ); - return new Container( - margin: EdgeInsets.only(left: 98), - child: new Column( - children: new List { - new Container( - child: new Container( - margin: EdgeInsets.only(top: 50, bottom: 20), - child: new Row( - crossAxisAlignment: CrossAxisAlignment.baseline, - children: new List { - new Container( - child: new Text( - title, - style: new TextStyle( - fontSize: 24, - color: CLColors.black - ) - ) - ), - new Container( - margin: EdgeInsets.only(left: 15), - child: - new Text( - "See More", - style: new TextStyle( - fontSize: 16, - color: CLColors.text4 - ) - ) - ) - }) - ) - ), - new Row( - children: new List { - testCard, - testCard, - testCard, - testCard, - testCard, - testCard - } - ) - } - )); - } - - bool _onNotification(ScrollNotification notification, BuildContext context) { - return true; - } - - Widget _buildContentList(BuildContext context) { - return new NotificationListener( - onNotification: (ScrollNotification notification) => { - this._onNotification(notification, context); - return true; - }, - child: new Flexible( - child: new ListView( - physics: new AlwaysScrollableScrollPhysics(), - children: new List { - this._buildBanner(context), - this._buildTopAssetsRow(context, "Recommanded For You"), - this._buildTopAssetsRow(context, "Beach Day"), - this._buildTopAssetsRow(context, "Top Free Packages"), - this._buildTopAssetsRow(context, "Top Paid Packages"), - this._buildFooter(context) - } - ) - ) - ); - } - - public override Widget build(BuildContext context) { - var mediaQueryData = MediaQuery.of(context); - var px = mediaQueryData.size.width / 2; - var py = mediaQueryData.size.width / 2; - - var container = new Container( - color: CLColors.background3, - child: new Container( - color: CLColors.background3, - child: new Transform( - transform: Matrix3.makeRotate(Mathf.PI / 180 * 5, px, py), - child: - new Column( - children: new List { - this._buildHeader(context), - this._buildContentList(context), - } - ) - ) - ) - ); - - var stack = new Stack( - children: new List { - container, - new Positioned( - top: 50, - right: 50, - child: new BackdropFilter( - filter: ImageFilter.blur(10, 10), - child: new Container( - width: 300, height: 300, - decoration: new BoxDecoration( - color: Colors.transparent - ) - ) - ) - ) - } - ); - - return stack; - } - } - - public class AssetCard : StatelessWidget { - public AssetCard( - string name, - string category, - float price, - float priceDiscount, - bool showBadge, - string imageSrc - ) { - this.name = name; - this.category = category; - this.price = price; - this.priceDiscount = priceDiscount; - this.showBadge = showBadge; - this.imageSrc = imageSrc; - } - - public readonly string name; - public readonly string category; - public readonly float price; - public readonly float priceDiscount; - public readonly bool showBadge; - public readonly string imageSrc; - - public override Widget build(BuildContext context) { - var card = new Container( - margin: EdgeInsets.only(right: 45), - child: new Container( - child: new Column( - children: new List { - new Container( - decoration: new BoxDecoration( - color: CLColors.white, - borderRadius: BorderRadius.only(topLeft: 3, topRight: 3) - ), - width: 200, - height: 124, - child: Image.network( - this.imageSrc, - fit: BoxFit.fill - ) - ), - new Container( - color: CLColors.white, - width: 200, - height: 86, - padding: EdgeInsets.fromLTRB(14, 12, 14, 8), - child: new Column( - crossAxisAlignment: CrossAxisAlignment.baseline, - children: new List { - new Container( - height: 18, - padding: EdgeInsets.only(top: 3), - child: - new Text(this.category, - style: new TextStyle( - fontSize: 11, - color: CLColors.text5 - ) - ) - ), - new Container( - height: 20, - padding: EdgeInsets.only(top: 2), - child: - new Text(this.name, - style: new TextStyle( - fontSize: 14, - color: CLColors.text6 - ) - ) - ), - new Container( - height: 22, - padding: EdgeInsets.only(top: 4), - child: new Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: new List { - new Container( - child: new Row( - children: new List { - new Container( - margin: EdgeInsets.only(right: 10), - child: new Text( - "$" + this.price, - style: new TextStyle( - fontSize: 14, - color: CLColors.text7, - decoration: TextDecoration.lineThrough - ) - ) - ), - new Container( - child: new Text( - "$" + this.priceDiscount, - style: new TextStyle( - fontSize: 14, - color: CLColors.text8 - ) - ) - ) - }) - ), - this.showBadge - ? new Container( - width: 80, - height: 18, - color: CLColors.black, - child: new Row( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: new List { - new Text( - "Plus/Pro", - style: new TextStyle( - fontSize: 11, - color: CLColors.white - ) - ) - } - ) - ) - : new Container() - } - ) - ) - } - ) - ) - } - ) - ) - ); - return card; - } - } - - public class EventsWaterfallScreen : StatefulWidget { - public EventsWaterfallScreen(Key key = null) : base(key: key) { - } - - public override State createState() { - return new _EventsWaterfallScreenState(); - } - } - - class _EventsWaterfallScreenState : State { - const float headerHeight = 80.0f; - - float _offsetY = 0.0f; -#pragma warning disable 0414 - int _index = -1; -#pragma warning restore 0414 - - Widget _buildHeader(BuildContext context) { - return new Container( - padding: EdgeInsets.only(left: 16.0f, right: 8.0f), - // color: CLColors.blue, - height: headerHeight - this._offsetY, - child: new Row( - children: new List { - new Flexible( - flex: 1, - fit: FlexFit.tight, - child: new Text( - "Today", - style: new TextStyle( - fontSize: (34.0f / headerHeight) * - (headerHeight - this._offsetY), - color: CLColors.white - ) - )), - new CustomButton( - padding: EdgeInsets.only(8.0f, 0.0f, 8.0f, 0.0f), - child: new Icon( - Icons.notifications, - size: 18.0f, - color: CLColors.icon2 - ) - ), - new CustomButton( - padding: EdgeInsets.only(8.0f, 0.0f, 16.0f, 0.0f), - child: new Icon( - Icons.account_circle, - size: 18.0f, - color: CLColors.icon2 - ) - ) - } - ) - ); - } - - bool _onNotification(ScrollNotification notification, BuildContext context) { - float pixels = notification.metrics.pixels; - if (pixels >= 0.0) { - if (pixels <= headerHeight) { - this.setState(() => { this._offsetY = pixels / 2.0f; }); - } - } - else { - if (this._offsetY != 0.0) { - this.setState(() => { this._offsetY = 0.0f; }); - } - } - - return true; - } - - - Widget _buildContentList(BuildContext context) { - return new NotificationListener( - onNotification: (ScrollNotification notification) => { - this._onNotification(notification, context); - return true; - }, - child: new Flexible( - child: new Container( - // color: CLColors.green, - child: ListView.builder( - itemCount: 20, - itemExtent: 100, - physics: new AlwaysScrollableScrollPhysics(), - itemBuilder: (BuildContext context1, int index) => { - return new Container( - color: Color.fromARGB(255, (index * 10) % 256, (index * 20) % 256, - (index * 30) % 256) - ); - } - ) - ) - ) - ); - } - - public override Widget build(BuildContext context) { - var container = new Container( - // color: CLColors.background1, - child: new Container( - // color: CLColors.background1, - child: new Column( - children: new List { - this._buildHeader(context), - this._buildContentList(context) - } - ) - ) - ); - return container; - } - } - - public class CustomButton : StatelessWidget { - public CustomButton( - Key key = null, - GestureTapCallback onPressed = null, - EdgeInsets padding = null, - Color backgroundColor = null, - Widget child = null - ) : base(key: key) { - this.onPressed = onPressed; - this.padding = padding ?? EdgeInsets.all(8.0f); - this.backgroundColor = backgroundColor ?? CLColors.transparent; - this.child = child; - } - - public readonly GestureTapCallback onPressed; - public readonly EdgeInsets padding; - public readonly Widget child; - public readonly Color backgroundColor; - - public override Widget build(BuildContext context) { - return new GestureDetector( - onTap: this.onPressed, - child: new Container( - padding: this.padding, - color: this.backgroundColor, - child: this.child - ) - ); - } - } - - public static class Icons { - public static readonly IconData notifications = new IconData(0xe7f4, fontFamily: "Material Icons"); - public static readonly IconData account_circle = new IconData(0xe853, fontFamily: "Material Icons"); - public static readonly IconData search = new IconData(0xe8b6, fontFamily: "Material Icons"); - public static readonly IconData keyboard_arrow_down = new IconData(0xe313, fontFamily: "Material Icons"); - } - - public static class CLColors { - public static readonly Color primary = new Color(0xFFE91E63); - public static readonly Color secondary1 = new Color(0xFF00BCD4); - public static readonly Color secondary2 = new Color(0xFFF0513C); - public static readonly Color background1 = new Color(0xFF292929); - public static readonly Color background2 = new Color(0xFF383838); - public static readonly Color background3 = new Color(0xFFF5F5F5); - public static readonly Color background4 = new Color(0xFF00BCD4); - public static readonly Color icon1 = new Color(0xFFFFFFFF); - public static readonly Color icon2 = new Color(0xFFA4A4A4); - public static readonly Color text1 = new Color(0xFFFFFFFF); - public static readonly Color text2 = new Color(0xFFD8D8D8); - public static readonly Color text3 = new Color(0xFF959595); - public static readonly Color text4 = new Color(0xFF002835); - public static readonly Color text5 = new Color(0xFF9E9E9E); - public static readonly Color text6 = new Color(0xFF002835); - public static readonly Color text7 = new Color(0xFF5A5A5B); - public static readonly Color text8 = new Color(0xFF239988); - public static readonly Color text9 = new Color(0xFFB3B5B6); - public static readonly Color text10 = new Color(0xFF00BCD4); - public static readonly Color dividingLine1 = new Color(0xFF666666); - public static readonly Color dividingLine2 = new Color(0xFF404040); - - public static readonly Color transparent = new Color(0x00000000); - public static readonly Color white = new Color(0xFFFFFFFF); - public static readonly Color black = new Color(0xFF000000); - public static readonly Color red = new Color(0xFFFF0000); - public static readonly Color green = new Color(0xFF00FF00); - public static readonly Color blue = new Color(0xFF0000FF); - - public static readonly Color header = new Color(0xFF060B0C); - } -} \ No newline at end of file diff --git a/Tests/Editor/Widgets.cs.meta b/Tests/Editor/Widgets.cs.meta deleted file mode 100644 index 6a0d1569..00000000 --- a/Tests/Editor/Widgets.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 1d2e1850f336481aa984d96b28c513b2 -timeCreated: 1536916429 \ No newline at end of file diff --git a/Tests/Editor/demo_charts.meta b/Tests/Editor/demo_charts.meta deleted file mode 100644 index 58d1031a..00000000 --- a/Tests/Editor/demo_charts.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 16325b3157a5144c789848b8ecc53311 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/Editor/demo_charts/bar.cs b/Tests/Editor/demo_charts/bar.cs deleted file mode 100644 index d3816044..00000000 --- a/Tests/Editor/demo_charts/bar.cs +++ /dev/null @@ -1,149 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using Unity.UIWidgets.animation; -using Unity.UIWidgets.foundation; -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; -using UnityEngine; -using Canvas = Unity.UIWidgets.ui.Canvas; -using Color = Unity.UIWidgets.ui.Color; -using Rect = Unity.UIWidgets.ui.Rect; - -namespace UIWidgets.Tests.demo_charts { - public class BarChart { - public BarChart(List bars) { - this.bars = bars; - } - - public static BarChart empty() { - return new BarChart(new List()); - } - - public static BarChart random(Size size) { - var barWidthFraction = 0.75f; - var ranks = selectRanks(ColorPalette.primary.length); - var barCount = ranks.Count; - var barDistance = size.width / (1 + barCount); - var barWidth = barDistance * barWidthFraction; - var startX = barDistance - barWidth / 2; - var bars = Enumerable.Range(0, barCount).Select(i => new Bar( - ranks[i], - startX + i * barDistance, - barWidth, - Random.value * size.height, - ColorPalette.primary[ranks[i]] - )).ToList(); - return new BarChart(bars); - } - - static List selectRanks(int cap) { - var ranks = new List(); - var rank = 0; - while (true) { - if (Random.value < 0.2f) { - rank++; - } - if (cap <= rank) { - break; - } - ranks.Add(rank); - rank++; - } - return ranks; - } - - public readonly List bars; - } - - public class BarChartTween : Tween { - readonly MergeTween _barsTween; - - public BarChartTween(BarChart begin, BarChart end) : base(begin: begin, end: end) { - this._barsTween = new MergeTween(begin.bars, end.bars); - } - - public override BarChart lerp(float t) { - return new BarChart(this._barsTween.lerp(t)); - } - } - - public class Bar : MergeTweenable { - public Bar(int rank, float x, float width, float height, Color color) { - this.rank = rank; - this.x = x; - this.width = width; - this.height = height; - this.color = color; - } - - public readonly int rank; - public readonly float x; - public readonly float width; - public readonly float height; - public readonly Color color; - - public Bar empty { - get { return new Bar(this.rank, this.x, 0.0f, 0.0f, this.color); } - } - - public bool less(Bar other) { - return this.rank < other.rank; - } - - public Tween tweenTo(Bar other) { - return new BarTween(this, other); - } - - public static Bar lerp(Bar begin, Bar end, float t) { - D.assert(begin.rank == end.rank); - return new Bar( - begin.rank, - MathUtils.lerpFloat(begin.x, end.x, t), - MathUtils.lerpFloat(begin.width, end.width, t), - MathUtils.lerpFloat(begin.height, end.height, t), - Color.lerp(begin.color, end.color, t) - ); - } - } - - public class BarTween : Tween { - public BarTween(Bar begin, Bar end) : base(begin: begin, end: end) { - D.assert(begin.rank == end.rank); - } - - public override Bar lerp(float t) { - return Bar.lerp(this.begin, this.end, t); - } - } - - public class BarChartPainter : AbstractCustomPainter { - public BarChartPainter(Animation animation) - : base(repaint: animation) { - this.animation = animation; - } - - public readonly Animation animation; - - public override void paint(Canvas canvas, Size size) { - var paint = new Paint(); - paint.style = PaintingStyle.fill; - var chart = this.animation.value; - foreach (var bar in chart.bars) { - paint.color = bar.color; - canvas.drawRect( - Rect.fromLTWH( - bar.x, - size.height - bar.height, - bar.width, - bar.height - ), - paint - ); - } - } - - public override bool shouldRepaint(CustomPainter old) { - return false; - } - } -} diff --git a/Tests/Editor/demo_charts/bar.cs.meta b/Tests/Editor/demo_charts/bar.cs.meta deleted file mode 100644 index 1bf83dd4..00000000 --- a/Tests/Editor/demo_charts/bar.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 20c43f616dd7640279364f93d965f4c0 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/Editor/demo_charts/color_palette.cs b/Tests/Editor/demo_charts/color_palette.cs deleted file mode 100644 index c094d6b9..00000000 --- a/Tests/Editor/demo_charts/color_palette.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System.Collections.Generic; -using Unity.UIWidgets.foundation; -using Unity.UIWidgets.material; -using UnityEngine; -using Color = Unity.UIWidgets.ui.Color; - -namespace UIWidgets.Tests.demo_charts { - public class ColorPalette { - public static readonly ColorPalette primary = new ColorPalette(new List { - Colors.blue[400], - Colors.red[400], - Colors.green[400], - Colors.yellow[400], - Colors.purple[400], - Colors.orange[400], - Colors.teal[400] - }); - - public ColorPalette(List colors) { - D.assert(colors.isNotEmpty); - this._colors = colors; - } - - readonly List _colors; - - public Color this[int index] { - get { return this._colors[index % this.length]; } - } - - public int length { - get { return this._colors.Count; } - } - - public Color random() { - return this[Random.Range(0, this.length - 1)]; - } - } -} diff --git a/Tests/Editor/demo_charts/color_palette.cs.meta b/Tests/Editor/demo_charts/color_palette.cs.meta deleted file mode 100644 index 29d155f8..00000000 --- a/Tests/Editor/demo_charts/color_palette.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: f9e9e9f9c5ecd474b8ef6a194f2d9fc7 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/Editor/demo_charts/main.cs b/Tests/Editor/demo_charts/main.cs deleted file mode 100644 index 7dcfc5a1..00000000 --- a/Tests/Editor/demo_charts/main.cs +++ /dev/null @@ -1,67 +0,0 @@ -using System; -using Unity.UIWidgets.animation; -using Unity.UIWidgets.material; -using Unity.UIWidgets.ui; -using Unity.UIWidgets.widgets; - -namespace UIWidgets.Tests.demo_charts { - /*** - * from https://github.com/mravn/charts - */ - public class ChartPage : StatefulWidget { - public override State createState() { - return new ChartPageState(); - } - } - - public class ChartPageState : TickerProviderStateMixin { - public static readonly Size size = new Size(200.0f, 100.0f); - - AnimationController _animation; - BarChartTween _tween; - - public override - void initState() { - base.initState(); - this._animation = new AnimationController( - duration: new TimeSpan(0, 0, 0, 0, 300), - vsync: this - ); - this._tween = new BarChartTween( - BarChart.empty(), - BarChart.random(size) - ); - this._animation.forward(); - } - - public override void dispose() { - this._animation.dispose(); - base.dispose(); - } - - void changeData() { - this.setState(() => { - this._tween = new BarChartTween( - this._tween.evaluate(this._animation), - BarChart.random(size) - ); - this._animation.forward(from: 0.0f); - }); - } - - public override Widget build(BuildContext context) { - return new Scaffold( - body: new Center( - child: new CustomPaint( - size: size, - painter: new BarChartPainter(this._tween.animate(this._animation)) - ) - ), - floatingActionButton: new FloatingActionButton( - child: new Icon(Unity.UIWidgets.material.Icons.refresh), - onPressed: this.changeData - ) - ); - } - } -} diff --git a/Tests/Editor/demo_charts/main.cs.meta b/Tests/Editor/demo_charts/main.cs.meta deleted file mode 100644 index d5b30190..00000000 --- a/Tests/Editor/demo_charts/main.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 905d6da1ea7b947be937556edda2b664 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/Editor/demo_charts/tween.cs b/Tests/Editor/demo_charts/tween.cs deleted file mode 100644 index d6ce62fe..00000000 --- a/Tests/Editor/demo_charts/tween.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using Unity.UIWidgets.animation; - -namespace UIWidgets.Tests.demo_charts { - public interface MergeTweenable { - T empty { get; } - - Tween tweenTo(T other); - - bool less(T other); - } - - public class MergeTween : Tween> where T : MergeTweenable { - public MergeTween(List begin, List end) : base(begin: begin, end: end) { - int bMax = begin.Count; - int eMax = end.Count; - var b = 0; - var e = 0; - while (b + e < bMax + eMax) { - if (b < bMax && (e == eMax || begin[b].less(end[e]))) { - this._tweens.Add(begin[b].tweenTo(begin[b].empty)); - b++; - } else if (e < eMax && (b == bMax || end[e].less(begin[b]))) { - this._tweens.Add(end[e].empty.tweenTo(end[e])); - e++; - } else { - this._tweens.Add(begin[b].tweenTo(end[e])); - b++; - e++; - } - } - } - - readonly List> _tweens = new List>(); - - public override List lerp(float t) { - return Enumerable.Range(0, this._tweens.Count).Select(i => this._tweens[i].lerp(t)).ToList(); - } - } -} diff --git a/Tests/Editor/demo_charts/tween.cs.meta b/Tests/Editor/demo_charts/tween.cs.meta deleted file mode 100644 index ea889f25..00000000 --- a/Tests/Editor/demo_charts/tween.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: ae95c92eb6d8346f3bbc89a91d9e191d -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/Resources.meta b/Tests/Resources.meta deleted file mode 100644 index b49964eb..00000000 --- a/Tests/Resources.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: a4bf4806dd96141b189111637bb1f450 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/Resources/6.png b/Tests/Resources/6.png deleted file mode 100644 index a83dfc4e..00000000 Binary files a/Tests/Resources/6.png and /dev/null differ diff --git a/Tests/Resources/6.png.meta b/Tests/Resources/6.png.meta deleted file mode 100644 index 800b8e3b..00000000 --- a/Tests/Resources/6.png.meta +++ /dev/null @@ -1,88 +0,0 @@ -fileFormatVersion: 2 -guid: d8fa175306ac44f8ea120cf256fd21d9 -TextureImporter: - fileIDToRecycleName: {} - externalObjects: {} - serializedVersion: 7 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -100 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 2 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - vertices: [] - indices: - edges: [] - weights: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/Resources/Emoji.png.meta b/Tests/Resources/Emoji.png.meta deleted file mode 100644 index 9972de85..00000000 --- a/Tests/Resources/Emoji.png.meta +++ /dev/null @@ -1,90 +0,0 @@ -fileFormatVersion: 2 -guid: 7a63b2e6e2c2045edb6a0be310ef2472 -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 10 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -100 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 2 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/Resources/ali_landscape.png b/Tests/Resources/ali_landscape.png deleted file mode 100644 index 8ac86a5d..00000000 Binary files a/Tests/Resources/ali_landscape.png and /dev/null differ diff --git a/Tests/Resources/india_chettinad_silk_maker.png b/Tests/Resources/india_chettinad_silk_maker.png deleted file mode 100644 index ea4ff6b1..00000000 Binary files a/Tests/Resources/india_chettinad_silk_maker.png and /dev/null differ diff --git a/Tests/Resources/india_chettinad_silk_maker.png.meta b/Tests/Resources/india_chettinad_silk_maker.png.meta deleted file mode 100644 index e2255d03..00000000 --- a/Tests/Resources/india_chettinad_silk_maker.png.meta +++ /dev/null @@ -1,134 +0,0 @@ -fileFormatVersion: 2 -guid: 759295bbc368246a0877963ba053ed5d -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 10 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -100 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 0 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 2 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - - serializedVersion: 2 - buildTarget: Standalone - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - - serializedVersion: 2 - buildTarget: iPhone - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - - serializedVersion: 2 - buildTarget: Android - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - - serializedVersion: 2 - buildTarget: WebGL - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/Resources/india_thanjavur_market.png b/Tests/Resources/india_thanjavur_market.png deleted file mode 100644 index 5d808ac8..00000000 Binary files a/Tests/Resources/india_thanjavur_market.png and /dev/null differ diff --git a/Tests/Resources/india_thanjavur_market.png.meta b/Tests/Resources/india_thanjavur_market.png.meta deleted file mode 100644 index 6fcb9d07..00000000 --- a/Tests/Resources/india_thanjavur_market.png.meta +++ /dev/null @@ -1,134 +0,0 @@ -fileFormatVersion: 2 -guid: 69711c649948f4cb1ad20b82f1926a29 -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 10 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -100 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 0 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 2 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - - serializedVersion: 2 - buildTarget: Standalone - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - - serializedVersion: 2 - buildTarget: iPhone - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - - serializedVersion: 2 - buildTarget: Android - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - - serializedVersion: 2 - buildTarget: WebGL - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/Resources/people.meta b/Tests/Resources/people.meta deleted file mode 100644 index 8be17793..00000000 --- a/Tests/Resources/people.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 8988da6435b0e414da67d5bb45802754 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/Resources/people/ali_landscape.png b/Tests/Resources/people/ali_landscape.png deleted file mode 100644 index 8ac86a5d..00000000 Binary files a/Tests/Resources/people/ali_landscape.png and /dev/null differ diff --git a/Tests/Resources/people/ali_landscape.png.meta b/Tests/Resources/people/ali_landscape.png.meta deleted file mode 100644 index 9536bb18..00000000 --- a/Tests/Resources/people/ali_landscape.png.meta +++ /dev/null @@ -1,88 +0,0 @@ -fileFormatVersion: 2 -guid: 0842a5ed1d4784702990d69f6c5d348d -TextureImporter: - fileIDToRecycleName: {} - externalObjects: {} - serializedVersion: 9 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -100 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 2 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - vertices: [] - indices: - edges: [] - weights: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/Resources/people/square.meta b/Tests/Resources/people/square.meta deleted file mode 100644 index f38af9e0..00000000 --- a/Tests/Resources/people/square.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 321c11a98ef1c452ba9bf4fad8ac67fe -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/Resources/people/square/ali.png b/Tests/Resources/people/square/ali.png deleted file mode 100644 index 177a60de..00000000 Binary files a/Tests/Resources/people/square/ali.png and /dev/null differ diff --git a/Tests/Resources/people/square/ali.png.meta b/Tests/Resources/people/square/ali.png.meta deleted file mode 100644 index a2ddd8f0..00000000 --- a/Tests/Resources/people/square/ali.png.meta +++ /dev/null @@ -1,88 +0,0 @@ -fileFormatVersion: 2 -guid: f644f877472c942209cc4ff5beaf452a -TextureImporter: - fileIDToRecycleName: {} - externalObjects: {} - serializedVersion: 9 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -100 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 2 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - vertices: [] - indices: - edges: [] - weights: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/Resources/people/square/peter.png b/Tests/Resources/people/square/peter.png deleted file mode 100644 index 98d89879..00000000 Binary files a/Tests/Resources/people/square/peter.png and /dev/null differ diff --git a/Tests/Resources/people/square/peter.png.meta b/Tests/Resources/people/square/peter.png.meta deleted file mode 100644 index 4ab76134..00000000 --- a/Tests/Resources/people/square/peter.png.meta +++ /dev/null @@ -1,88 +0,0 @@ -fileFormatVersion: 2 -guid: 739817fca86d74ffda90f9a891db4c99 -TextureImporter: - fileIDToRecycleName: {} - externalObjects: {} - serializedVersion: 9 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -100 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 2 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - vertices: [] - indices: - edges: [] - weights: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/Resources/people/square/sandra.png b/Tests/Resources/people/square/sandra.png deleted file mode 100644 index 96e4c3fb..00000000 Binary files a/Tests/Resources/people/square/sandra.png and /dev/null differ diff --git a/Tests/Resources/people/square/sandra.png.meta b/Tests/Resources/people/square/sandra.png.meta deleted file mode 100644 index f2feba8d..00000000 --- a/Tests/Resources/people/square/sandra.png.meta +++ /dev/null @@ -1,88 +0,0 @@ -fileFormatVersion: 2 -guid: 61c32ad851b0c4c90a05f5857c8bf810 -TextureImporter: - fileIDToRecycleName: {} - externalObjects: {} - serializedVersion: 9 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -100 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 2 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - vertices: [] - indices: - edges: [] - weights: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/Resources/people/square/stella.png b/Tests/Resources/people/square/stella.png deleted file mode 100644 index 1a98808e..00000000 Binary files a/Tests/Resources/people/square/stella.png and /dev/null differ diff --git a/Tests/Resources/people/square/stella.png.meta b/Tests/Resources/people/square/stella.png.meta deleted file mode 100644 index 0c402c1d..00000000 --- a/Tests/Resources/people/square/stella.png.meta +++ /dev/null @@ -1,88 +0,0 @@ -fileFormatVersion: 2 -guid: 89e334df4c00c47258db57d508fcb3d0 -TextureImporter: - fileIDToRecycleName: {} - externalObjects: {} - serializedVersion: 9 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -100 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 2 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - vertices: [] - indices: - edges: [] - weights: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/Resources/people/square/trevor.png b/Tests/Resources/people/square/trevor.png deleted file mode 100644 index 9fbd09ec..00000000 Binary files a/Tests/Resources/people/square/trevor.png and /dev/null differ diff --git a/Tests/Resources/people/square/trevor.png.meta b/Tests/Resources/people/square/trevor.png.meta deleted file mode 100644 index dba47155..00000000 --- a/Tests/Resources/people/square/trevor.png.meta +++ /dev/null @@ -1,88 +0,0 @@ -fileFormatVersion: 2 -guid: 88e5367b95d2f462693ad5524593ab14 -TextureImporter: - fileIDToRecycleName: {} - externalObjects: {} - serializedVersion: 9 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -100 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 2 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - vertices: [] - indices: - edges: [] - weights: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/Resources/products.meta b/Tests/Resources/products.meta deleted file mode 100644 index 30c07a1e..00000000 --- a/Tests/Resources/products.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 2edd4d858895b44ff89047544e685c54 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/Resources/products/backpack.png b/Tests/Resources/products/backpack.png deleted file mode 100644 index 3ed4c43d..00000000 Binary files a/Tests/Resources/products/backpack.png and /dev/null differ diff --git a/Tests/Resources/products/backpack.png.meta b/Tests/Resources/products/backpack.png.meta deleted file mode 100644 index c6416fb8..00000000 --- a/Tests/Resources/products/backpack.png.meta +++ /dev/null @@ -1,88 +0,0 @@ -fileFormatVersion: 2 -guid: 674a904c9f4234b9ba9f78eb37f237fe -TextureImporter: - fileIDToRecycleName: {} - externalObjects: {} - serializedVersion: 9 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -100 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 2 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - vertices: [] - indices: - edges: [] - weights: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/Resources/products/belt.png b/Tests/Resources/products/belt.png deleted file mode 100644 index c47993a2..00000000 Binary files a/Tests/Resources/products/belt.png and /dev/null differ diff --git a/Tests/Resources/products/belt.png.meta b/Tests/Resources/products/belt.png.meta deleted file mode 100644 index 2a51b87a..00000000 --- a/Tests/Resources/products/belt.png.meta +++ /dev/null @@ -1,88 +0,0 @@ -fileFormatVersion: 2 -guid: 8a6d8f5795ade4d2abc66cd64533f8ac -TextureImporter: - fileIDToRecycleName: {} - externalObjects: {} - serializedVersion: 9 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -100 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 2 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - vertices: [] - indices: - edges: [] - weights: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/Resources/products/cup.png b/Tests/Resources/products/cup.png deleted file mode 100644 index e294a568..00000000 Binary files a/Tests/Resources/products/cup.png and /dev/null differ diff --git a/Tests/Resources/products/cup.png.meta b/Tests/Resources/products/cup.png.meta deleted file mode 100644 index e34cb2a7..00000000 --- a/Tests/Resources/products/cup.png.meta +++ /dev/null @@ -1,88 +0,0 @@ -fileFormatVersion: 2 -guid: 7443ec2c33a954d6ea65634db88ec9de -TextureImporter: - fileIDToRecycleName: {} - externalObjects: {} - serializedVersion: 9 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -100 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 2 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - vertices: [] - indices: - edges: [] - weights: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/Resources/products/deskset.png b/Tests/Resources/products/deskset.png deleted file mode 100644 index e45b3d0d..00000000 Binary files a/Tests/Resources/products/deskset.png and /dev/null differ diff --git a/Tests/Resources/products/deskset.png.meta b/Tests/Resources/products/deskset.png.meta deleted file mode 100644 index 162ff2fc..00000000 --- a/Tests/Resources/products/deskset.png.meta +++ /dev/null @@ -1,88 +0,0 @@ -fileFormatVersion: 2 -guid: 9181044e6c0c4467b933708e3834f35e -TextureImporter: - fileIDToRecycleName: {} - externalObjects: {} - serializedVersion: 9 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -100 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 2 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - vertices: [] - indices: - edges: [] - weights: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/Resources/products/dress.png b/Tests/Resources/products/dress.png deleted file mode 100644 index e508339e..00000000 Binary files a/Tests/Resources/products/dress.png and /dev/null differ diff --git a/Tests/Resources/products/dress.png.meta b/Tests/Resources/products/dress.png.meta deleted file mode 100644 index 7ec924f6..00000000 --- a/Tests/Resources/products/dress.png.meta +++ /dev/null @@ -1,88 +0,0 @@ -fileFormatVersion: 2 -guid: 452e42b2f60134df48d45ab49a21d8ec -TextureImporter: - fileIDToRecycleName: {} - externalObjects: {} - serializedVersion: 9 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -100 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 2 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - vertices: [] - indices: - edges: [] - weights: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/Resources/products/earrings.png b/Tests/Resources/products/earrings.png deleted file mode 100644 index 603b9fe5..00000000 Binary files a/Tests/Resources/products/earrings.png and /dev/null differ diff --git a/Tests/Resources/products/earrings.png.meta b/Tests/Resources/products/earrings.png.meta deleted file mode 100644 index 1cdf6794..00000000 --- a/Tests/Resources/products/earrings.png.meta +++ /dev/null @@ -1,88 +0,0 @@ -fileFormatVersion: 2 -guid: 7619ea1564ba546ab91b5f0ab38a9f6b -TextureImporter: - fileIDToRecycleName: {} - externalObjects: {} - serializedVersion: 9 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -100 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 2 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - vertices: [] - indices: - edges: [] - weights: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/Resources/products/flatwear.png b/Tests/Resources/products/flatwear.png deleted file mode 100644 index 23d30816..00000000 Binary files a/Tests/Resources/products/flatwear.png and /dev/null differ diff --git a/Tests/Resources/products/flatwear.png.meta b/Tests/Resources/products/flatwear.png.meta deleted file mode 100644 index af372dc8..00000000 --- a/Tests/Resources/products/flatwear.png.meta +++ /dev/null @@ -1,88 +0,0 @@ -fileFormatVersion: 2 -guid: 2a94339103e7e40219169f13b5ce7013 -TextureImporter: - fileIDToRecycleName: {} - externalObjects: {} - serializedVersion: 9 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -100 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 2 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - vertices: [] - indices: - edges: [] - weights: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/Resources/products/hat.png b/Tests/Resources/products/hat.png deleted file mode 100644 index 8b9e115c..00000000 Binary files a/Tests/Resources/products/hat.png and /dev/null differ diff --git a/Tests/Resources/products/hat.png.meta b/Tests/Resources/products/hat.png.meta deleted file mode 100644 index af7c768f..00000000 --- a/Tests/Resources/products/hat.png.meta +++ /dev/null @@ -1,88 +0,0 @@ -fileFormatVersion: 2 -guid: 1c9bf8d4be2ec4909968b137cca6a5a5 -TextureImporter: - fileIDToRecycleName: {} - externalObjects: {} - serializedVersion: 9 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -100 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 2 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - vertices: [] - indices: - edges: [] - weights: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/Resources/products/jacket.png b/Tests/Resources/products/jacket.png deleted file mode 100644 index 595b545a..00000000 Binary files a/Tests/Resources/products/jacket.png and /dev/null differ diff --git a/Tests/Resources/products/jacket.png.meta b/Tests/Resources/products/jacket.png.meta deleted file mode 100644 index 5f35151e..00000000 --- a/Tests/Resources/products/jacket.png.meta +++ /dev/null @@ -1,88 +0,0 @@ -fileFormatVersion: 2 -guid: 39dfc9119bacf4b85b0d265fae8a101f -TextureImporter: - fileIDToRecycleName: {} - externalObjects: {} - serializedVersion: 9 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -100 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 2 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - vertices: [] - indices: - edges: [] - weights: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/Resources/products/jumper.png b/Tests/Resources/products/jumper.png deleted file mode 100644 index d113cf82..00000000 Binary files a/Tests/Resources/products/jumper.png and /dev/null differ diff --git a/Tests/Resources/products/jumper.png.meta b/Tests/Resources/products/jumper.png.meta deleted file mode 100644 index 759dfb9e..00000000 --- a/Tests/Resources/products/jumper.png.meta +++ /dev/null @@ -1,88 +0,0 @@ -fileFormatVersion: 2 -guid: 4de6e7bd13cc942acaf79ea01980376e -TextureImporter: - fileIDToRecycleName: {} - externalObjects: {} - serializedVersion: 9 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -100 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 2 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - vertices: [] - indices: - edges: [] - weights: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/Resources/products/kitchen_quattro.png b/Tests/Resources/products/kitchen_quattro.png deleted file mode 100644 index 5806a675..00000000 Binary files a/Tests/Resources/products/kitchen_quattro.png and /dev/null differ diff --git a/Tests/Resources/products/kitchen_quattro.png.meta b/Tests/Resources/products/kitchen_quattro.png.meta deleted file mode 100644 index 09787ad3..00000000 --- a/Tests/Resources/products/kitchen_quattro.png.meta +++ /dev/null @@ -1,88 +0,0 @@ -fileFormatVersion: 2 -guid: d02d7a685bb6643ab841d43ee08037a1 -TextureImporter: - fileIDToRecycleName: {} - externalObjects: {} - serializedVersion: 9 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -100 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 2 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - vertices: [] - indices: - edges: [] - weights: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/Resources/products/napkins.png b/Tests/Resources/products/napkins.png deleted file mode 100644 index f96359b4..00000000 Binary files a/Tests/Resources/products/napkins.png and /dev/null differ diff --git a/Tests/Resources/products/napkins.png.meta b/Tests/Resources/products/napkins.png.meta deleted file mode 100644 index 664671fa..00000000 --- a/Tests/Resources/products/napkins.png.meta +++ /dev/null @@ -1,88 +0,0 @@ -fileFormatVersion: 2 -guid: 2cfec1ff4da1c4180a77badc07700991 -TextureImporter: - fileIDToRecycleName: {} - externalObjects: {} - serializedVersion: 9 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -100 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 2 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - vertices: [] - indices: - edges: [] - weights: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/Resources/products/planters.png b/Tests/Resources/products/planters.png deleted file mode 100644 index a78ef21f..00000000 Binary files a/Tests/Resources/products/planters.png and /dev/null differ diff --git a/Tests/Resources/products/planters.png.meta b/Tests/Resources/products/planters.png.meta deleted file mode 100644 index a1d964e4..00000000 --- a/Tests/Resources/products/planters.png.meta +++ /dev/null @@ -1,88 +0,0 @@ -fileFormatVersion: 2 -guid: d6cfe1d64e50b4921b6127378911cf72 -TextureImporter: - fileIDToRecycleName: {} - externalObjects: {} - serializedVersion: 9 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -100 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 2 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - vertices: [] - indices: - edges: [] - weights: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/Resources/products/platter.png b/Tests/Resources/products/platter.png deleted file mode 100644 index 3986e51d..00000000 Binary files a/Tests/Resources/products/platter.png and /dev/null differ diff --git a/Tests/Resources/products/platter.png.meta b/Tests/Resources/products/platter.png.meta deleted file mode 100644 index 846266f0..00000000 --- a/Tests/Resources/products/platter.png.meta +++ /dev/null @@ -1,88 +0,0 @@ -fileFormatVersion: 2 -guid: 5670aeff677b64088bebe4eca1226f4d -TextureImporter: - fileIDToRecycleName: {} - externalObjects: {} - serializedVersion: 9 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -100 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 2 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - vertices: [] - indices: - edges: [] - weights: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/Resources/products/scarf.png b/Tests/Resources/products/scarf.png deleted file mode 100644 index dfb7cc24..00000000 Binary files a/Tests/Resources/products/scarf.png and /dev/null differ diff --git a/Tests/Resources/products/scarf.png.meta b/Tests/Resources/products/scarf.png.meta deleted file mode 100644 index 1cee6ae0..00000000 --- a/Tests/Resources/products/scarf.png.meta +++ /dev/null @@ -1,88 +0,0 @@ -fileFormatVersion: 2 -guid: cbceefcfd006d450c82769c232fc553e -TextureImporter: - fileIDToRecycleName: {} - externalObjects: {} - serializedVersion: 9 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -100 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 2 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - vertices: [] - indices: - edges: [] - weights: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/Resources/products/shirt.png b/Tests/Resources/products/shirt.png deleted file mode 100644 index cf58066f..00000000 Binary files a/Tests/Resources/products/shirt.png and /dev/null differ diff --git a/Tests/Resources/products/shirt.png.meta b/Tests/Resources/products/shirt.png.meta deleted file mode 100644 index 510f2be6..00000000 --- a/Tests/Resources/products/shirt.png.meta +++ /dev/null @@ -1,88 +0,0 @@ -fileFormatVersion: 2 -guid: 62306f72bb1ce45babf84b36b72a517c -TextureImporter: - fileIDToRecycleName: {} - externalObjects: {} - serializedVersion: 9 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -100 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 2 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - vertices: [] - indices: - edges: [] - weights: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/Resources/products/sunnies.png b/Tests/Resources/products/sunnies.png deleted file mode 100644 index 2b2d0545..00000000 Binary files a/Tests/Resources/products/sunnies.png and /dev/null differ diff --git a/Tests/Resources/products/sunnies.png.meta b/Tests/Resources/products/sunnies.png.meta deleted file mode 100644 index 93d9c9d6..00000000 --- a/Tests/Resources/products/sunnies.png.meta +++ /dev/null @@ -1,88 +0,0 @@ -fileFormatVersion: 2 -guid: 86fa61eb0c5b14c9380cc7996cc0eb05 -TextureImporter: - fileIDToRecycleName: {} - externalObjects: {} - serializedVersion: 9 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -100 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 2 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - vertices: [] - indices: - edges: [] - weights: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/Resources/products/sweater.png b/Tests/Resources/products/sweater.png deleted file mode 100644 index 53d4f7e2..00000000 Binary files a/Tests/Resources/products/sweater.png and /dev/null differ diff --git a/Tests/Resources/products/sweater.png.meta b/Tests/Resources/products/sweater.png.meta deleted file mode 100644 index 66ded2af..00000000 --- a/Tests/Resources/products/sweater.png.meta +++ /dev/null @@ -1,88 +0,0 @@ -fileFormatVersion: 2 -guid: 62ba7ebbec25c471daaf40bb55f357ad -TextureImporter: - fileIDToRecycleName: {} - externalObjects: {} - serializedVersion: 9 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -100 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 2 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - vertices: [] - indices: - edges: [] - weights: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/Resources/products/sweats.png b/Tests/Resources/products/sweats.png deleted file mode 100644 index 03051077..00000000 Binary files a/Tests/Resources/products/sweats.png and /dev/null differ diff --git a/Tests/Resources/products/sweats.png.meta b/Tests/Resources/products/sweats.png.meta deleted file mode 100644 index bbba053d..00000000 --- a/Tests/Resources/products/sweats.png.meta +++ /dev/null @@ -1,88 +0,0 @@ -fileFormatVersion: 2 -guid: 2c1f449cb818546b6aac2487bf16ea91 -TextureImporter: - fileIDToRecycleName: {} - externalObjects: {} - serializedVersion: 9 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -100 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 2 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - vertices: [] - indices: - edges: [] - weights: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/Resources/products/table.png b/Tests/Resources/products/table.png deleted file mode 100644 index f537bf8e..00000000 Binary files a/Tests/Resources/products/table.png and /dev/null differ diff --git a/Tests/Resources/products/table.png.meta b/Tests/Resources/products/table.png.meta deleted file mode 100644 index f96eb7c7..00000000 --- a/Tests/Resources/products/table.png.meta +++ /dev/null @@ -1,88 +0,0 @@ -fileFormatVersion: 2 -guid: 63d5bc443792b4135ada2687a51c6524 -TextureImporter: - fileIDToRecycleName: {} - externalObjects: {} - serializedVersion: 9 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -100 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 2 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - vertices: [] - indices: - edges: [] - weights: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/Resources/products/teaset.png b/Tests/Resources/products/teaset.png deleted file mode 100644 index 0d681650..00000000 Binary files a/Tests/Resources/products/teaset.png and /dev/null differ diff --git a/Tests/Resources/products/teaset.png.meta b/Tests/Resources/products/teaset.png.meta deleted file mode 100644 index 5283772b..00000000 --- a/Tests/Resources/products/teaset.png.meta +++ /dev/null @@ -1,88 +0,0 @@ -fileFormatVersion: 2 -guid: 1ea4cd0db6dd649858a8d4ae1d8e1b0c -TextureImporter: - fileIDToRecycleName: {} - externalObjects: {} - serializedVersion: 9 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -100 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 2 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - vertices: [] - indices: - edges: [] - weights: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/Resources/products/top.png b/Tests/Resources/products/top.png deleted file mode 100644 index 30ff7546..00000000 Binary files a/Tests/Resources/products/top.png and /dev/null differ diff --git a/Tests/Resources/products/top.png.meta b/Tests/Resources/products/top.png.meta deleted file mode 100644 index 1baf6467..00000000 --- a/Tests/Resources/products/top.png.meta +++ /dev/null @@ -1,88 +0,0 @@ -fileFormatVersion: 2 -guid: 28c554c1d07094c75bf3336f43b55c85 -TextureImporter: - fileIDToRecycleName: {} - externalObjects: {} - serializedVersion: 9 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -100 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 2 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - vertices: [] - indices: - edges: [] - weights: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/Resources/unity-black.png b/Tests/Resources/unity-black.png deleted file mode 100644 index 8f5a1911..00000000 Binary files a/Tests/Resources/unity-black.png and /dev/null differ diff --git a/Tests/Resources/unity-black.png.meta b/Tests/Resources/unity-black.png.meta deleted file mode 100644 index 13f57a70..00000000 --- a/Tests/Resources/unity-black.png.meta +++ /dev/null @@ -1,88 +0,0 @@ -fileFormatVersion: 2 -guid: b09b9022b548f4a788de5d6d2b47aeac -TextureImporter: - fileIDToRecycleName: {} - externalObjects: {} - serializedVersion: 9 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -100 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 2 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - vertices: [] - indices: - edges: [] - weights: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/Resources/unity-white.png b/Tests/Resources/unity-white.png deleted file mode 100644 index fe54b23d..00000000 Binary files a/Tests/Resources/unity-white.png and /dev/null differ diff --git a/Tests/Resources/unity-white.png.meta b/Tests/Resources/unity-white.png.meta deleted file mode 100644 index a7e6acba..00000000 --- a/Tests/Resources/unity-white.png.meta +++ /dev/null @@ -1,88 +0,0 @@ -fileFormatVersion: 2 -guid: 18b226d86a5e74dd392f35201ac60139 -TextureImporter: - fileIDToRecycleName: {} - externalObjects: {} - serializedVersion: 9 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -100 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - singleChannelComponent: 0 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - serializedVersion: 2 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: - vertices: [] - indices: - edges: [] - weights: [] - spritePackingTag: - pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 0 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/Runtime.meta b/Tests/Runtime.meta deleted file mode 100644 index 0445a5cd..00000000 --- a/Tests/Runtime.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: c2d6e16ea80ac4c7c83c21d2d0d9a4ee -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/Runtime/RuntimeExampleTest.cs b/Tests/Runtime/RuntimeExampleTest.cs deleted file mode 100644 index 0e59fb52..00000000 --- a/Tests/Runtime/RuntimeExampleTest.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System.Collections; -using NUnit.Framework; -using UnityEngine.TestTools; - -class RuntimeExampleTest { - [Test] - public void PlayModeSampleTestSimplePasses() { - // Use the Assert class to test conditions. - } - - // A UnityTest behaves like a coroutine in PlayMode - // and allows you to yield null to skip a frame in EditMode - [UnityTest] - public IEnumerator PlayModeSampleTestWithEnumeratorPasses() { - // Use the Assert class to test conditions. - // yield to skip a frame - yield return null; - } -} \ No newline at end of file diff --git a/Tests/Runtime/RuntimeExampleTest.cs.meta b/Tests/Runtime/RuntimeExampleTest.cs.meta deleted file mode 100644 index 3f8d5818..00000000 --- a/Tests/Runtime/RuntimeExampleTest.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 59b1c9d60b19a408898d5495008de48e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Tests/Runtime/Unity.UIWidgets.Tests.asmdef b/Tests/Runtime/Unity.UIWidgets.Tests.asmdef deleted file mode 100644 index 511c4bda..00000000 --- a/Tests/Runtime/Unity.UIWidgets.Tests.asmdef +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "Unity.UIWidgets.Tests", - "references": [ - "Unity.UIWidgets" - ], - "optionalUnityReferences": [ - "TestAssemblies" - ], - "includePlatforms": [], - "excludePlatforms": [] -} diff --git a/Tests/Runtime/Unity.UIWidgets.Tests.asmdef.meta b/Tests/Runtime/Unity.UIWidgets.Tests.asmdef.meta deleted file mode 100644 index 60095e36..00000000 --- a/Tests/Runtime/Unity.UIWidgets.Tests.asmdef.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 14a815924271b4a9f9efdffaba3f607b -AssemblyDefinitionImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/package.json b/package.json index e349e2ad..5fd9bb09 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { "name": "com.unity.uiwidgets", "displayName":"UIWidgets", - "version": "1.0.0-preview", - "unity": "2018.1", + "version": "1.5.4-preview.1", + "unity": "2018.4", "description": "UIWidgets allows you to build beautiful cross-platform apps through Unity", "dependencies": { }