├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ └── main.yml ├── .gitignore ├── CHANGELOG.md ├── CHANGELOG.md.meta ├── CODE_OF_CONDUCT.md ├── CODE_OF_CONDUCT.md.meta ├── Documentation~ ├── ALookAtContainerBindings.md ├── GettingStarted.md ├── HowToReactToUserInput.md ├── Images │ ├── ALookAtContainerBindings │ │ ├── ALookAtContainerBindings.Final.png │ │ ├── CharacterViewSetup.01.png │ │ ├── CharacterViewSetup.02.png │ │ ├── ContainerBindings.png │ │ ├── PartyViewSetup.01.png │ │ ├── PartyViewSetup.02.png │ │ └── PartyViewSetup.Final.png │ ├── GettingStarted │ │ ├── AccessSourceCodeOfDataSource.png │ │ ├── CreateProject.png │ │ ├── GettingStarted.png │ │ ├── ImportSample.png │ │ ├── InitialSetup.png │ │ ├── SetupInspector.png │ │ ├── UpgradeToURP.png │ │ ├── ViewInspector01-1.png │ │ ├── ViewInspector01-2.png │ │ ├── ViewInspector01-3.png │ │ ├── ViewInspector01-4.png │ │ └── ViewInspector02.png │ └── UserInput │ │ ├── UserInput.png │ │ ├── UserInputTutorial.DropdownHandler.png │ │ ├── UserInputTutorial.End.png │ │ ├── UserInputTutorial.FillInBindings.png │ │ ├── UserInputTutorial.PushButtonHandler.png │ │ ├── UserInputTutorial.Start.png │ │ └── UserInputTutorial.TextInputHandler.png └── images.meta ├── Editor.meta ├── Editor ├── DataBinding.uss ├── DataBinding.uss.meta ├── DefaultDataSourceTemplate.txt ├── DefaultDataSourceTemplate.txt.meta ├── JH.DataBinding.Editor.asmdef ├── JH.DataBinding.Editor.asmdef.meta ├── Properties.meta ├── Properties │ ├── AssemblyInfo.cs │ └── AssemblyInfo.cs.meta ├── Scripts.meta └── Scripts │ ├── BindingState.cs │ ├── BindingState.cs.meta │ ├── DataBindingCommonData.cs │ ├── DataBindingCommonData.cs.meta │ ├── DataBindingEditorDisplayText.cs │ ├── DataBindingEditorDisplayText.cs.meta │ ├── DataBindingEditorOperations.cs │ ├── DataBindingEditorOperations.cs.meta │ ├── DataBindingEditorStyle.cs │ ├── DataBindingEditorStyle.cs.meta │ ├── DatabindingEditorMenu.cs │ ├── DatabindingEditorMenu.cs.meta │ ├── IDataBindingEditorDisplayText.cs │ ├── IDataBindingEditorDisplayText.cs.meta │ ├── PropertyDrawers.meta │ ├── PropertyDrawers │ ├── ComponentPropertyBindingPropertyDrawer.cs │ ├── ComponentPropertyBindingPropertyDrawer.cs.meta │ ├── ComponentPropertyBindingSourcePathPropertyDrawer.cs │ ├── ComponentPropertyBindingSourcePathPropertyDrawer.cs.meta │ ├── ComponentPropertyBindingTargetComponentPropertyDrawer.cs │ ├── ComponentPropertyBindingTargetComponentPropertyDrawer.cs.meta │ ├── ComponentPropertyBindingTargetPathPropertyDrawer.cs │ ├── ComponentPropertyBindingTargetPathPropertyDrawer.cs.meta │ ├── ContainerPropertyBindingPropertyDrawer.cs │ ├── ContainerPropertyBindingPropertyDrawer.cs.meta │ ├── ContainerPropertyBindingSourcePathPropertyDrawer.cs │ ├── ContainerPropertyBindingSourcePathPropertyDrawer.cs.meta │ ├── DataSourceTypePropertyDrawer.cs │ └── DataSourceTypePropertyDrawer.cs.meta │ ├── SerializedPropertyExtensions.cs │ ├── SerializedPropertyExtensions.cs.meta │ ├── StringExtensions.cs │ ├── StringExtensions.cs.meta │ ├── Style.meta │ ├── Style │ ├── DataBindingStyles.cs │ ├── DataBindingStyles.cs.meta │ ├── VisualElementStyleExtensions.cs │ └── VisualElementStyleExtensions.cs.meta │ ├── ViewEditor.cs │ ├── ViewEditor.cs.meta │ ├── VisualElements.meta │ └── VisualElements │ ├── ComponentPropertyBindingListView.cs │ ├── ComponentPropertyBindingListView.cs.meta │ ├── ContainerPropertyBindingListView.cs │ ├── ContainerPropertyBindingListView.cs.meta │ ├── InternalErrorReport.cs │ └── InternalErrorReport.cs.meta ├── LICENSE.md ├── LICENSE.md.meta ├── README.md ├── README.md.meta ├── Runtime.meta ├── Runtime ├── JH.DataBinding.asmdef ├── JH.DataBinding.asmdef.meta ├── Scripts.meta └── Scripts │ ├── Attributes.meta │ ├── Attributes │ ├── BindingSourcePathAttribute.cs │ ├── BindingSourcePathAttribute.cs.meta │ ├── BindingTargetComponentAttribute.cs │ ├── BindingTargetComponentAttribute.cs.meta │ ├── BindingTargetPathAttribute.cs │ ├── BindingTargetPathAttribute.cs.meta │ ├── DataSourceTypeAttribute.cs │ ├── DataSourceTypeAttribute.cs.meta │ ├── EnumerableBindingSourcePathAttribute.cs │ └── EnumerableBindingSourcePathAttribute.cs.meta │ ├── Bindings.meta │ ├── Bindings │ ├── ComponentPropertyBinding.cs │ ├── ComponentPropertyBinding.cs.meta │ ├── ContainerPropertyBinding.cs │ └── ContainerPropertyBinding.cs.meta │ ├── DataSourceBase.cs │ ├── DataSourceBase.cs.meta │ ├── GameObjectPropertyAccess.cs │ ├── GameObjectPropertyAccess.cs.meta │ ├── INotifyDataSourceChanged.cs │ ├── INotifyDataSourceChanged.cs.meta │ ├── Reflection.meta │ ├── Reflection │ ├── ReflectionExtensions.cs │ ├── ReflectionExtensions.cs.meta │ ├── SerializableType.cs │ ├── SerializableType.cs.meta │ ├── SerializableTypes.cs │ └── SerializableTypes.cs.meta │ ├── View.cs │ └── View.cs.meta ├── Samples~ ├── A look at ContainerBindings - Finished │ ├── A look at ContainerBindings.unity │ ├── A look at ContainerBindings.unity.meta │ ├── Prefabs.meta │ ├── Prefabs │ │ ├── Attribute View.prefab │ │ ├── Attribute View.prefab.meta │ │ ├── Character View.prefab │ │ ├── Character View.prefab.meta │ │ ├── Party View.prefab │ │ └── Party View.prefab.meta │ ├── Scripts.meta │ ├── Scripts │ │ ├── AttributeViewModel.cs │ │ ├── AttributeViewModel.cs.meta │ │ ├── Bootstrap.cs │ │ ├── Bootstrap.cs.meta │ │ ├── CharacterViewModel.cs │ │ ├── CharacterViewModel.cs.meta │ │ ├── PartyViewModel.cs │ │ └── PartyViewModel.cs.meta │ ├── Textures.meta │ └── Textures │ │ ├── Attribute.Background.png │ │ ├── Attribute.Background.png.meta │ │ ├── CharacterImage.01.png │ │ ├── CharacterImage.01.png.meta │ │ ├── Frame.1px.png │ │ ├── Frame.1px.png.meta │ │ ├── FrameCornerRadius8.Top.Filled.png │ │ ├── FrameCornerRadius8.Top.Filled.png.meta │ │ ├── Level.Background.png │ │ ├── Level.Background.png.meta │ │ ├── Level.Progress.png │ │ ├── Level.Progress.png.meta │ │ ├── Pallete.png │ │ └── Pallete.png.meta ├── A look at ContainerBindings - Tutorial │ ├── A look at ContainerBindings.unity │ ├── A look at ContainerBindings.unity.meta │ ├── Prefabs.meta │ ├── Prefabs │ │ ├── Attribute View.prefab │ │ ├── Attribute View.prefab.meta │ │ ├── Character View.prefab │ │ ├── Character View.prefab.meta │ │ ├── Party View.prefab │ │ └── Party View.prefab.meta │ ├── Scripts.meta │ ├── Scripts │ │ ├── AttributeViewModel.cs │ │ ├── AttributeViewModel.cs.meta │ │ ├── Bootstrap.cs │ │ ├── Bootstrap.cs.meta │ │ ├── CharacterViewModel.cs │ │ ├── CharacterViewModel.cs.meta │ │ ├── PartyViewModel.cs │ │ └── PartyViewModel.cs.meta │ ├── Textures.meta │ └── Textures │ │ ├── Attribute.Background.png │ │ ├── Attribute.Background.png.meta │ │ ├── CharacterImage.01.png │ │ ├── CharacterImage.01.png.meta │ │ ├── Frame.1px.png │ │ ├── Frame.1px.png.meta │ │ ├── FrameCornerRadius8.Top.Filled.png │ │ ├── FrameCornerRadius8.Top.Filled.png.meta │ │ ├── Level.Background.png │ │ ├── Level.Background.png.meta │ │ ├── Level.Progress.png │ │ ├── Level.Progress.png.meta │ │ ├── Pallete.png │ │ └── Pallete.png.meta ├── EditableDropdown │ ├── EditableDropdown.unity │ ├── EditableDropdown.unity.meta │ ├── Prefabs.meta │ ├── Prefabs │ │ ├── EditableDropdown.prefab │ │ └── EditableDropdown.prefab.meta │ ├── Scripts.meta │ └── Scripts │ │ ├── EditableDropdown.cs │ │ ├── EditableDropdown.cs.meta │ │ ├── EditableDropdownSetup.cs │ │ └── EditableDropdownSetup.cs.meta ├── GameObjectPropertyBindings │ ├── GameObjectPropertyBindings.unity │ ├── GameObjectPropertyBindings.unity.meta │ ├── GameObjectPropertyBindingsSetup.cs │ ├── GameObjectPropertyBindingsSetup.cs.meta │ ├── JH.Databinding.Samples.GameObjectPropertyBindings.asmdef │ ├── JH.Databinding.Samples.GameObjectPropertyBindings.asmdef.meta │ ├── SceneCompositionDataSource.cs │ └── SceneCompositionDataSource.cs.meta ├── How to react to user input - Finished │ ├── Scripts.meta │ ├── Scripts │ │ ├── UserInputHandlingDataSource.cs │ │ ├── UserInputHandlingDataSource.cs.meta │ │ ├── UserInputHandlingSetup.cs │ │ ├── UserInputHandlingSetup.cs.meta │ │ ├── UserInputHandlingView.cs │ │ └── UserInputHandlingView.cs.meta │ ├── UserInputHandling.unity │ └── UserInputHandling.unity.meta ├── How to react to user input - Tutorial │ ├── Scripts.meta │ ├── Scripts │ │ ├── UserInputHandlingDataSource.cs │ │ ├── UserInputHandlingDataSource.cs.meta │ │ ├── UserInputHandlingSetup.cs │ │ ├── UserInputHandlingSetup.cs.meta │ │ ├── UserInputHandlingView.cs │ │ └── UserInputHandlingView.cs.meta │ ├── UserInputHandling.unity │ └── UserInputHandling.unity.meta └── MyFirstDataBoundView (Getting Started Tutorial) │ ├── Materials.meta │ ├── Materials │ ├── Cube Material.mat │ └── Cube Material.mat.meta │ ├── MyFirstDataBoundView.unity │ ├── MyFirstDataBoundView.unity.meta │ ├── Scripts.meta │ └── Scripts │ ├── CubeViewDataSource.cs │ ├── CubeViewDataSource.cs.meta │ ├── DynamicMaterialColor.cs │ ├── DynamicMaterialColor.cs.meta │ ├── MyFirstDataBoundViewSetup.cs │ ├── MyFirstDataBoundViewSetup.cs.meta │ ├── PlaceholderApplicationLogic.cs │ └── PlaceholderApplicationLogic.cs.meta ├── Tests.meta ├── Tests ├── Editor Tests.meta ├── Editor Tests │ ├── JH.DataBinding.Editor.Tests.asmdef │ ├── JH.DataBinding.Editor.Tests.asmdef.meta │ ├── NewTestScript.cs │ └── NewTestScript.cs.meta ├── Runtime.meta └── Runtime │ ├── JH.DataBinding.Tests.asmdef │ ├── JH.DataBinding.Tests.asmdef.meta │ ├── RuntimeContainerBindingsTest.cs │ └── RuntimeContainerBindingsTest.cs.meta ├── Third Party Notices.md ├── Third Party Notices.md.meta ├── package.json └── package.json.meta /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: JochenHeckl 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Please complete the following information:** 27 | - OS: [e.g. iOS] 28 | - Version [e.g. 22] 29 | - Unity Version [e.g. 2023.1.2] 30 | - Your package-lock.json version of this package [e.g. "de.jochenheckl.unity.databinding": { .., "hash": "9a919a9920afd00938a0b2776b565492e161c3a9" }] 31 | 32 | **Additional context** 33 | Add any other context about the problem here. 34 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Actions 2 | 3 | on: [push, pull_request, workflow_dispatch] 4 | 5 | jobs: 6 | run_test: 7 | name: Run Tests 8 | 9 | permissions: 10 | checks: write 11 | 12 | strategy: 13 | matrix: 14 | unityVersion: 15 | - 6000.0.32f1 16 | - 2023.2.20f1 17 | os: 18 | - ubuntu-latest 19 | # - windows-latest 20 | projectPath: 21 | - ./ 22 | testMode: 23 | - playmode 24 | # - editmode 25 | 26 | runs-on: ${{ matrix.os }} 27 | 28 | steps: 29 | # Checkout 30 | - name: Checkout repository 31 | uses: actions/checkout@v4 32 | with: 33 | lfs: false 34 | 35 | # Cache Library 36 | # - uses: actions/cache@v4 37 | # with: 38 | # path: ${{ matrix.projectPath }}/Library 39 | # key: Library-${{ matrix.projectPath }} 40 | # restore-keys: | 41 | # Library- 42 | 43 | # Test 44 | - name: run tests 45 | uses: game-ci/unity-test-runner@v4 46 | id: testRun 47 | env: 48 | UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }} 49 | UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} 50 | UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} 51 | with: 52 | packageMode: true 53 | projectPath: ${{ matrix.projectPath }} 54 | testMode: ${{ matrix.testMode }} 55 | artifactsPath: ${{ matrix.unityVersion }}-${{ matrix.os }}-${{ matrix.testMode }}-artifacts 56 | checkName: ${{ matrix.unityVersion }}-${{ matrix.os }}-${{ matrix.testMode }} Test Results 57 | unityVersion: ${{ matrix.unityVersion }} 58 | githubToken: ${{ secrets.GITHUB_TOKEN }} 59 | 60 | # Upload artifacts 61 | - uses: actions/upload-artifact@v4 62 | if: always() 63 | with: 64 | name: Test results for ${{ matrix.unityVersion }}-${{ matrix.os }}-${{ matrix.testMode }} 65 | path: ${{ steps.testRun.outputs.artifactsPath }} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.toptal.com/developers/gitignore/api/unity 2 | # Edit at https://www.toptal.com/developers/gitignore?templates=unity 3 | 4 | ### Unity ### 5 | # This .gitignore file should be placed at the root of your Unity project directory 6 | # 7 | # Get latest from https://github.com/github/gitignore/blob/main/Unity.gitignore 8 | # 9 | /[Ll]ibrary/ 10 | /[Tt]emp/ 11 | /[Oo]bj/ 12 | /[Bb]uild/ 13 | /[Bb]uilds/ 14 | /[Ll]ogs/ 15 | /[Uu]ser[Ss]ettings/ 16 | 17 | # MemoryCaptures can get excessive in size. 18 | # They also could contain extremely sensitive data 19 | /[Mm]emoryCaptures/ 20 | 21 | # Recordings can get excessive in size 22 | /[Rr]ecordings/ 23 | 24 | # Uncomment this line if you wish to ignore the asset store tools plugin 25 | # /[Aa]ssets/AssetStoreTools* 26 | 27 | # Autogenerated Jetbrains Rider plugin 28 | /[Aa]ssets/Plugins/Editor/JetBrains* 29 | 30 | # Visual Studio cache directory 31 | .vs/ 32 | 33 | # Gradle cache directory 34 | .gradle/ 35 | 36 | # Autogenerated VS/MD/Consulo solution and project files 37 | ExportedObj/ 38 | .consulo/ 39 | *.csproj 40 | *.unityproj 41 | *.sln 42 | *.suo 43 | *.tmp 44 | *.user 45 | *.userprefs 46 | *.pidb 47 | *.booproj 48 | *.svd 49 | *.pdb 50 | *.mdb 51 | *.opendb 52 | *.VC.db 53 | 54 | # Unity3D generated meta files 55 | *.pidb.meta 56 | *.pdb.meta 57 | *.mdb.meta 58 | 59 | # Unity3D generated file on crash reports 60 | sysinfo.txt 61 | 62 | # Builds 63 | *.apk 64 | *.aab 65 | *.unitypackage 66 | *.app 67 | 68 | # Crashlytics generated file 69 | crashlytics-build.properties 70 | 71 | # Packed Addressables 72 | /[Aa]ssets/[Aa]ddressable[Aa]ssets[Dd]ata/*/*.bin* 73 | 74 | # Temporary auto-generated Android Assets 75 | /[Aa]ssets/[Ss]treamingAssets/aa.meta 76 | /[Aa]ssets/[Ss]treamingAssets/aa/* 77 | 78 | # End of https://www.toptal.com/developers/gitignore/api/unity 79 | 80 | .vscode 81 | .idea 82 | .vs 83 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | For details on the latest version please refer to [Releases](https://github.com/JochenHeckl/DataBinding/releases/) -------------------------------------------------------------------------------- /CHANGELOG.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4bf14051de76ebf4eb62920a55876f76 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4cea29831d6d8e34c81ac9c824b05523 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Documentation~/ALookAtContainerBindings.md: -------------------------------------------------------------------------------- 1 | # A look at ContainerBindings 2 | 3 | This is a short step by step tutorial that will make you familiar with container bindings. 4 | 5 | We assume you completed the "Getting Started" tutorial and have a basic understanding of what data bindings are. 6 | 7 | ## Open the tutorial project 8 | 9 | - Open up Unity. 10 | - Import the DataBinding package if you have not done this already. You can follow the instructions in the ["Getting Started" tutorial](../README.md) to do so. 11 | - Open the PackageManager Window ( Menu: Window ⟶ Package Manager ) and select the DataBinding package. 12 | - From the samples on the right select and import **"A look at ContainerBindings - Tutorial"**. 13 | - Back in unity open the "A look at ContainerBindings" scene. 14 | - Running the sample renders an empty screen. But we will make it look like this: 15 | 16 | ![Tutorial Start](Images/ALookAtContainerBindings/ALookAtContainerBindings.Final.png) 17 | 18 | with just 2 small setups. 19 | 20 | ## Binding the Party View to display Characters 21 | - The Project already contains some code in Bootstrap.cs that generates random data for 4 characters. The data is exposed by the ParyViewModel's Charcters property. 22 | 23 |
24 | Show code 25 | 26 | ```csharp 27 | using System.Collections.Generic; 28 | 29 | namespace JH.DataBinding.Examples.ContainerBindings 30 | { 31 | public class PartyViewModel : DataSourceBase 32 | { 33 | public IEnumerable Characters { get; set; } 34 | } 35 | } 36 | 37 | ``` 38 |
39 | 40 | - What we are trying to achieve, is to display character data in the Party View. So lets open the **Party View** prefab. (*Hint: Typing 'Party V' in the search bar of our Project Window can help you find it faster*) 41 | 42 | ![PartyViewSetup](Images/ALookAtContainerBindings/PartyViewSetup.01.png) 43 | 44 | - Now add a new Binding by clicking the **Add Binding** button in the **Container Property Bindings** section of your Inspector window. 45 | - Select the **SourcePath** property to bind to the Characters property of your PartyViewModel. The editor will limit your choices to **IEnumerable** properties only. After all: This is a Container, so we expect it to hold Elements in a 1:n relationship. If we were to bind a 1:1 relationship, a Component Property Binding would do. 46 | - As **Target Container** select the Characters GameObject from your Hierarchy (It is already set up to show a Grid for our purpose). 47 | - Now finally, as we are binding 1:n, we have to supply an **Elememnt Template** that will be used to represent each element of the IEnumerable property in the scene. To do this, drag the **Character View** prefab into the **Element Template** binding input area. *(Hint: You can find the **Character View** prefab right next to the **Party View** prefab that you are current editing. If not you maybe have the Party V filter still active.*) 48 | 49 | - If you click run now you should be a scene like this: 50 | 51 | ![PartyViewSetup - Run](Images/ALookAtContainerBindings/PartyViewSetup.02.png) 52 | 53 | - Note that the **Character View** prefab itself is a **View** with it's own property bindings that become evaluated for each of the **CharacterViewModel**s that are stored in the **Characters** Property of the **PartyViewModel**. 54 | 55 | ![CharacterViewSetup - Run](Images/ALookAtContainerBindings/CharacterViewSetup.01.png) 56 | 57 | 58 | ## Binding the Charcter View to display Attributes 59 | 60 | Attributes are for Characters pretty much what Characters are for the Party. There is a 1:n relation of Characters:Attributes. Characters *'contain'* Attributes. So we go create a ContainerBinding: 61 | 62 | ![CharacterViewSetup - Run](Images/ALookAtContainerBindings/CharacterViewSetup.02.png) 63 | 64 | - Select the **Attributes** property of the CharacterViewModel as **Source Path** of the Binding. 65 | - Drag the **Attributes** GameObject into the **Target Container** inputArea. (*Hint: Just as with **Character View**s the **Attribute** GameObject is properly set up as Grid already.*) 66 | - Drag the **Attribute View** prefab into the **Element Template** input are. 67 | - Click Play and you should see the final result. 68 | 69 | 70 | -------------------------------------------------------------------------------- /Documentation~/Images/ALookAtContainerBindings/ALookAtContainerBindings.Final.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JochenHeckl/DataBinding/6e2e750e61e90dd72b2b80b2b9d397f2c818574c/Documentation~/Images/ALookAtContainerBindings/ALookAtContainerBindings.Final.png -------------------------------------------------------------------------------- /Documentation~/Images/ALookAtContainerBindings/CharacterViewSetup.01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JochenHeckl/DataBinding/6e2e750e61e90dd72b2b80b2b9d397f2c818574c/Documentation~/Images/ALookAtContainerBindings/CharacterViewSetup.01.png -------------------------------------------------------------------------------- /Documentation~/Images/ALookAtContainerBindings/CharacterViewSetup.02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JochenHeckl/DataBinding/6e2e750e61e90dd72b2b80b2b9d397f2c818574c/Documentation~/Images/ALookAtContainerBindings/CharacterViewSetup.02.png -------------------------------------------------------------------------------- /Documentation~/Images/ALookAtContainerBindings/ContainerBindings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JochenHeckl/DataBinding/6e2e750e61e90dd72b2b80b2b9d397f2c818574c/Documentation~/Images/ALookAtContainerBindings/ContainerBindings.png -------------------------------------------------------------------------------- /Documentation~/Images/ALookAtContainerBindings/PartyViewSetup.01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JochenHeckl/DataBinding/6e2e750e61e90dd72b2b80b2b9d397f2c818574c/Documentation~/Images/ALookAtContainerBindings/PartyViewSetup.01.png -------------------------------------------------------------------------------- /Documentation~/Images/ALookAtContainerBindings/PartyViewSetup.02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JochenHeckl/DataBinding/6e2e750e61e90dd72b2b80b2b9d397f2c818574c/Documentation~/Images/ALookAtContainerBindings/PartyViewSetup.02.png -------------------------------------------------------------------------------- /Documentation~/Images/ALookAtContainerBindings/PartyViewSetup.Final.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JochenHeckl/DataBinding/6e2e750e61e90dd72b2b80b2b9d397f2c818574c/Documentation~/Images/ALookAtContainerBindings/PartyViewSetup.Final.png -------------------------------------------------------------------------------- /Documentation~/Images/GettingStarted/AccessSourceCodeOfDataSource.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JochenHeckl/DataBinding/6e2e750e61e90dd72b2b80b2b9d397f2c818574c/Documentation~/Images/GettingStarted/AccessSourceCodeOfDataSource.png -------------------------------------------------------------------------------- /Documentation~/Images/GettingStarted/CreateProject.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JochenHeckl/DataBinding/6e2e750e61e90dd72b2b80b2b9d397f2c818574c/Documentation~/Images/GettingStarted/CreateProject.png -------------------------------------------------------------------------------- /Documentation~/Images/GettingStarted/GettingStarted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JochenHeckl/DataBinding/6e2e750e61e90dd72b2b80b2b9d397f2c818574c/Documentation~/Images/GettingStarted/GettingStarted.png -------------------------------------------------------------------------------- /Documentation~/Images/GettingStarted/ImportSample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JochenHeckl/DataBinding/6e2e750e61e90dd72b2b80b2b9d397f2c818574c/Documentation~/Images/GettingStarted/ImportSample.png -------------------------------------------------------------------------------- /Documentation~/Images/GettingStarted/InitialSetup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JochenHeckl/DataBinding/6e2e750e61e90dd72b2b80b2b9d397f2c818574c/Documentation~/Images/GettingStarted/InitialSetup.png -------------------------------------------------------------------------------- /Documentation~/Images/GettingStarted/SetupInspector.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JochenHeckl/DataBinding/6e2e750e61e90dd72b2b80b2b9d397f2c818574c/Documentation~/Images/GettingStarted/SetupInspector.png -------------------------------------------------------------------------------- /Documentation~/Images/GettingStarted/UpgradeToURP.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JochenHeckl/DataBinding/6e2e750e61e90dd72b2b80b2b9d397f2c818574c/Documentation~/Images/GettingStarted/UpgradeToURP.png -------------------------------------------------------------------------------- /Documentation~/Images/GettingStarted/ViewInspector01-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JochenHeckl/DataBinding/6e2e750e61e90dd72b2b80b2b9d397f2c818574c/Documentation~/Images/GettingStarted/ViewInspector01-1.png -------------------------------------------------------------------------------- /Documentation~/Images/GettingStarted/ViewInspector01-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JochenHeckl/DataBinding/6e2e750e61e90dd72b2b80b2b9d397f2c818574c/Documentation~/Images/GettingStarted/ViewInspector01-2.png -------------------------------------------------------------------------------- /Documentation~/Images/GettingStarted/ViewInspector01-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JochenHeckl/DataBinding/6e2e750e61e90dd72b2b80b2b9d397f2c818574c/Documentation~/Images/GettingStarted/ViewInspector01-3.png -------------------------------------------------------------------------------- /Documentation~/Images/GettingStarted/ViewInspector01-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JochenHeckl/DataBinding/6e2e750e61e90dd72b2b80b2b9d397f2c818574c/Documentation~/Images/GettingStarted/ViewInspector01-4.png -------------------------------------------------------------------------------- /Documentation~/Images/GettingStarted/ViewInspector02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JochenHeckl/DataBinding/6e2e750e61e90dd72b2b80b2b9d397f2c818574c/Documentation~/Images/GettingStarted/ViewInspector02.png -------------------------------------------------------------------------------- /Documentation~/Images/UserInput/UserInput.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JochenHeckl/DataBinding/6e2e750e61e90dd72b2b80b2b9d397f2c818574c/Documentation~/Images/UserInput/UserInput.png -------------------------------------------------------------------------------- /Documentation~/Images/UserInput/UserInputTutorial.DropdownHandler.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JochenHeckl/DataBinding/6e2e750e61e90dd72b2b80b2b9d397f2c818574c/Documentation~/Images/UserInput/UserInputTutorial.DropdownHandler.png -------------------------------------------------------------------------------- /Documentation~/Images/UserInput/UserInputTutorial.End.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JochenHeckl/DataBinding/6e2e750e61e90dd72b2b80b2b9d397f2c818574c/Documentation~/Images/UserInput/UserInputTutorial.End.png -------------------------------------------------------------------------------- /Documentation~/Images/UserInput/UserInputTutorial.FillInBindings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JochenHeckl/DataBinding/6e2e750e61e90dd72b2b80b2b9d397f2c818574c/Documentation~/Images/UserInput/UserInputTutorial.FillInBindings.png -------------------------------------------------------------------------------- /Documentation~/Images/UserInput/UserInputTutorial.PushButtonHandler.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JochenHeckl/DataBinding/6e2e750e61e90dd72b2b80b2b9d397f2c818574c/Documentation~/Images/UserInput/UserInputTutorial.PushButtonHandler.png -------------------------------------------------------------------------------- /Documentation~/Images/UserInput/UserInputTutorial.Start.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JochenHeckl/DataBinding/6e2e750e61e90dd72b2b80b2b9d397f2c818574c/Documentation~/Images/UserInput/UserInputTutorial.Start.png -------------------------------------------------------------------------------- /Documentation~/Images/UserInput/UserInputTutorial.TextInputHandler.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JochenHeckl/DataBinding/6e2e750e61e90dd72b2b80b2b9d397f2c818574c/Documentation~/Images/UserInput/UserInputTutorial.TextInputHandler.png -------------------------------------------------------------------------------- /Documentation~/images.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 25e0c4650f88b2c48b4067c79e42dd4f 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0ccc59310d95a76409731eae21caa140 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Editor/DataBinding.uss: -------------------------------------------------------------------------------- 1 | :root { 2 | --errorRed: rgb(160, 32, 32); 3 | --fontSizeLarger: 104% 4 | } 5 | 6 | .createDefaultDataSourceButton 7 | { 8 | margin: 24px; 9 | font-size: var(--fontSizeLarger); 10 | white-space: normal; 11 | } 12 | 13 | .dataSourceSelectionButton 14 | { 15 | min-width: 64px; 16 | min-height: 22px; 17 | } 18 | 19 | .dataSourceSelectionButtonGroup 20 | { 21 | flex-grow: 0; 22 | flex-direction: row; 23 | justify-content: flex-end; 24 | } 25 | 26 | .dataSourceFilterInput 27 | { 28 | flex-grow: 1; 29 | flex-shrink: 1; 30 | margin-right : 4px; 31 | } 32 | 33 | .dataSourceSelectionDataSourceDropDown 34 | { 35 | flex-grow: 1; 36 | flex-shrink: 1; 37 | margin-right : 4px; 38 | } 39 | 40 | .dataSourceSelectionFilterSection 41 | { 42 | font-size: var(--fontSizeLarger); 43 | margin-top: 4px; 44 | flex-direction: Row; 45 | flex-wrap: NoWrap; 46 | justify-content: space-between; 47 | } 48 | 49 | .dataSourceSelectionSelectionSection 50 | { 51 | font-size: var(--fontSizeLarger); 52 | margin-top: 4px; 53 | flex-direction: Row; 54 | flex-wrap: NoWrap; 55 | justify-content: space-between; 56 | } 57 | 58 | .errorMessageContainer { 59 | flex-grow: 0; 60 | padding: 8px; 61 | margin: 8px; 62 | border-color: var(--errorRed); 63 | border-radius: 8px; 64 | border-width: 2px; 65 | } 66 | 67 | .errorMessageText { 68 | font-size: var(--fontSizeLarger); 69 | white-space: normal; 70 | } 71 | 72 | /* .viewEditor { 73 | 74 | } 75 | 76 | .genericRow { 77 | flex-direction: row; 78 | justify-content: space-between; 79 | } 80 | 81 | .successText { 82 | font-size: 14px; 83 | color: green; 84 | white-space: normal; 85 | } 86 | 87 | .errorText { 88 | margin: 4px; 89 | color: rgb(192, 32, 32); 90 | font-size: 14px; 91 | white-space: normal; 92 | } 93 | 94 | .infoText { 95 | font-size: 12px; 96 | white-space: normal; 97 | } 98 | 99 | .invalidBinding { 100 | margin: 8px; 101 | background-color: red; 102 | } 103 | 104 | .bindingDataSourceTypeLabel { 105 | font-size: 14px; 106 | } 107 | 108 | .bindingGroup { 109 | padding-top: 4px; 110 | } 111 | 112 | .bindingGroupList { 113 | margin-top: 4px; 114 | margin-bottom: 4px; 115 | 116 | padding: 2px; 117 | 118 | 119 | border-width: 1px; 120 | border-radius: 4px; 121 | border-color: rgb(0, 0, 0); 122 | } 123 | 124 | .bindingGroupHeader { 125 | flex-direction: row; 126 | justify-content: space-between; 127 | } 128 | 129 | .bindingGroupLabel { 130 | -unity-text-align: middle-left; 131 | margin-left: 1px; 132 | margin-right: 1px; 133 | margin-top: 1px; 134 | margin-bottom: 1px; 135 | font-size: 14px; 136 | } 137 | 138 | .bindingActionButton { 139 | margin: 0px; 140 | width: 24px; 141 | height: 18px; 142 | } 143 | 144 | .addBindingActionButton { 145 | margin: 0px; 146 | height: 18px; 147 | } 148 | 149 | .bindingContainer 150 | { 151 | flex-direction: column; 152 | margin: 1px; 153 | 154 | border-width: 1px; 155 | border-radius: 2px; 156 | border-color: rgb(64, 64, 64); 157 | 158 | } 159 | 160 | .bindingHeaderRow{ 161 | padding: 2px; 162 | flex-direction: row; 163 | flex-wrap: wrap; 164 | 165 | background-color: var(--unity-colors-app_toolbar_button-background-hover); 166 | } 167 | 168 | .bindingInteractionButtonContainer { 169 | flex-direction: row; 170 | } 171 | 172 | .condensedBindingLabel { 173 | -unity-text-align: middle-left; 174 | white-space: normal; 175 | margin:2px; 176 | } 177 | 178 | .bindingProperty{ 179 | margin-right: 2px; 180 | } */ 181 | -------------------------------------------------------------------------------- /Editor/DataBinding.uss.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 70194f1e38a7b014ab3b1bce3d9d4f41 3 | ScriptedImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 2 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0} 11 | disableValidation: 0 12 | -------------------------------------------------------------------------------- /Editor/DefaultDataSourceTemplate.txt: -------------------------------------------------------------------------------- 1 | using JH.DataBinding; 2 | 3 | public class {{name}}DataSource : DataSourceBase<{{name}}DataSource> 4 | { 5 | public bool BoolProperty { get; set; } 6 | public int IntProperty { get; set; } 7 | public string StringProperty { get; set; } 8 | } 9 | -------------------------------------------------------------------------------- /Editor/DefaultDataSourceTemplate.txt.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 29f2c23c859fe8a41a13166b3671c440 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Editor/JH.DataBinding.Editor.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "JH.DataBinding.Editor", 3 | "rootNamespace": "JH.DataBinding.Editor", 4 | "references": [ 5 | "UnityEngine.UI", 6 | "UnityEditor.UI", 7 | "JH.DataBinding" 8 | ], 9 | "includePlatforms": [ 10 | "Editor" 11 | ], 12 | "excludePlatforms": [], 13 | "allowUnsafeCode": false, 14 | "overrideReferences": false, 15 | "precompiledReferences": [], 16 | "autoReferenced": true, 17 | "defineConstraints": [], 18 | "versionDefines": [], 19 | "noEngineReferences": false 20 | } -------------------------------------------------------------------------------- /Editor/JH.DataBinding.Editor.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a0e4c5c00223fb3458f9b15222e6807e 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Editor/Properties.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f908cbc3e68057a40a2537bf5ec8cdb9 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Editor/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.CompilerServices; 2 | 3 | [assembly: InternalsVisibleTo("JH.DataBinding.Editor.Tests")] 4 | -------------------------------------------------------------------------------- /Editor/Properties/AssemblyInfo.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 95f22f52c05809c49bd685bea6492fb5 -------------------------------------------------------------------------------- /Editor/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a9a6a563de6c75e4184cdb93956a7115 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Editor/Scripts/BindingState.cs: -------------------------------------------------------------------------------- 1 | namespace JH.DataBinding.Editor 2 | { 3 | internal enum ComponentPropertyBindingState 4 | { 5 | MissingDataSourceAssignment, 6 | NoBindableProperties, 7 | SourceUnbound, 8 | TargetUnbound, 9 | Unassignable, 10 | Complete, 11 | } 12 | 13 | internal enum ContainerPropertyBindingState 14 | { 15 | MissingDataSourceAssignment, 16 | NoBindableProperties, 17 | SourceUnbound, 18 | TargetUnbound, 19 | ElementTemplateMissing, 20 | ElementTemplateIsNotAssignable, 21 | Complete, 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Editor/Scripts/BindingState.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d27d6486b22eeb1499fe6ffa88fa4384 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/Scripts/DataBindingCommonData.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c6e7b2c8609554248827d6c6de1c4163 -------------------------------------------------------------------------------- /Editor/Scripts/DataBindingEditorDisplayText.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace JH.DataBinding.Editor 5 | { 6 | internal class DataBindingEditorDisplayText : IDataBindingEditorDisplayText 7 | { 8 | public string AssetPathLabel => "Asset Path"; 9 | 10 | public string BindingElementTemplateIsNotAssignableMessageText => 11 | "Please specify an element template with a View component"; 12 | 13 | public string BindingElementTemplateMissingMessageText => 14 | "Please specify an element template ( == a prefab with a View component)"; 15 | 16 | public string BindingMissingDataSourceAssignment => 17 | "Assign a DataSource to the hosting view."; 18 | 19 | public string BindingNoBindableProperties => 20 | "The DataSource does not have bindable properties."; 21 | 22 | public string BindingSourceUnboundMessageText => "Select the binding source path"; 23 | 24 | public string BindingTargetUnboundMessageText => 25 | "The Binding target is incomplete"; 26 | 27 | public string BindingUnassignableMessageText => 28 | "The binding source is not assignable to the binding target"; 29 | 30 | public string ComponentPropertyBindingCondensedLabelFormat_Type_Source_Target_Component => 31 | "{0} {1} binds to {2} ({3})"; 32 | 33 | public string ComponentPropertyBindingsText => "Component Property Bindings"; 34 | 35 | public string CondenseButtonText => "↸"; 36 | 37 | public string ContainerPropertyBindingCondensedLabelFormat_Type_Source_Target_Template => 38 | "{0} {1} expands into {2} ({3})"; 39 | 40 | public string ContainerPropertyBindingsText => "Container Property Bindings"; 41 | 42 | public string CreateDataSourceTypeToolTipText => 43 | "Enter the name of the DataSource to create."; 44 | 45 | public string CreateDefaultDataSourceText => "Create default DataSource"; 46 | 47 | public string CreateNewDataSourceTitle => "Create new DataSource"; 48 | 49 | public string DataSourceTypeInspectorFilterLabel => "DataSource Type Filter"; 50 | 51 | public string DataSourceTypeText => "DataSource Type"; 52 | 53 | public string EditDataSourceText => "Edit"; 54 | 55 | public string EditDataSourceTooltip => "Edit the sourcecode of the selected Datasource."; 56 | 57 | public string EditorErrorMessageText => 58 | "An internal error occured setting up the editor view. Please file an Issue."; 59 | 60 | public string HeavyCheckMark => "✔"; 61 | 62 | public string InvalidPathContent => 63 | "Please select a path inside the project tree structure."; 64 | 65 | public string InvalidPathTitle => "Invalid Path"; 66 | 67 | public string MissingDataSourcesErrorText => 68 | $"No data source was found in this project.{Environment.NewLine}{Environment.NewLine}Please define at least one class that implements INotifyDataSourceChanged that you want this View to bind to.{Environment.NewLine}{Environment.NewLine}The simplest way to create a data source is by deriving from DataSourceBase."; 69 | 70 | public string MoveDownButtonText => "▼"; 71 | 72 | public string MoveUpButtonText => "▲"; 73 | 74 | public string NewDataSourceText => "New"; 75 | 76 | public string NewDataSourceTooltip => "Create a new empty datasource."; 77 | 78 | public string NoDataSourcesText => "No data sources found."; 79 | 80 | public string OKLabel => "OK"; 81 | 82 | public string OpenFileBrowserButtonText => "…"; 83 | 84 | public string ReportErrorButtonText => "Report Error 🔗"; 85 | 86 | public string SourcePathText => "Source Path"; 87 | 88 | public string TargetComponentText => "Target Component"; 89 | 90 | public string TargetGameObjectText => "Target GameObject"; 91 | 92 | public string TargetPathText => "Target Path"; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /Editor/Scripts/DataBindingEditorDisplayText.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4ac366bcd5342014f9e4d852be7e722d 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/Scripts/DataBindingEditorOperations.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Linq; 3 | using UnityEditor; 4 | using UnityEngine; 5 | 6 | namespace JH.DataBinding.Editor 7 | { 8 | internal static class DataBindingEditorOperations 9 | { 10 | internal static void CreateNewDataSource(string currentViewName) 11 | { 12 | var pathToOpen = Application.dataPath; 13 | Object selectedObject = Selection.activeObject; 14 | 15 | if (selectedObject != null) 16 | { 17 | var selectedObjectPath = AssetDatabase.GetAssetPath(selectedObject); 18 | 19 | if (!string.IsNullOrEmpty(selectedObjectPath)) 20 | { 21 | pathToOpen = Path.GetDirectoryName(selectedObjectPath); 22 | } 23 | } 24 | 25 | var viewNameWithoutSpaces = new string( 26 | currentViewName.ToCharArray().Where(x => !char.IsWhiteSpace(x)).ToArray() 27 | ); 28 | 29 | string selectedPath = EditorUtility.SaveFilePanelInProject( 30 | "Select Asset Location", 31 | $"{viewNameWithoutSpaces}DataSource.cs", 32 | "cs", 33 | pathToOpen 34 | ); 35 | 36 | if (!string.IsNullOrEmpty(selectedPath)) 37 | { 38 | var dataSourceCode = DataBindingCommonData.DefaultDataSourceTemplate.Replace( 39 | DataBindingCommonData.DefaultDataSourceTemplateNamePlaceHolder, 40 | viewNameWithoutSpaces 41 | ); 42 | 43 | File.WriteAllText(selectedPath, dataSourceCode); 44 | AssetDatabase.ImportAsset(selectedPath); 45 | 46 | OpenDataSourceEditor(selectedPath); 47 | } 48 | } 49 | 50 | internal static void OpenDataSourceEditor(string dataSourceSourceFile) 51 | { 52 | if (dataSourceSourceFile != null) 53 | { 54 | var scriptAsset = AssetDatabase.LoadAssetAtPath( 55 | dataSourceSourceFile.Replace('/', Path.DirectorySeparatorChar) 56 | ); 57 | 58 | if (scriptAsset != null) 59 | { 60 | AssetDatabase.OpenAsset(scriptAsset); 61 | } 62 | } 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /Editor/Scripts/DataBindingEditorOperations.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ca01b45f99826834aa58b4a300765143 -------------------------------------------------------------------------------- /Editor/Scripts/DataBindingEditorStyle.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEditor; 3 | using UnityEngine; 4 | using UnityEngine.UIElements; 5 | 6 | namespace JH.DataBinding.Editor 7 | { 8 | public static class DataBindingEditorStyle 9 | { 10 | private static readonly string viewEditorStyleSheetFile = 11 | "Packages/de.jochenheckl.unity.databinding/Editor/DataBinding.uss"; 12 | 13 | private static StyleSheet sharedStyleSheetAsset; 14 | 15 | public const string errorMessageContainer = nameof(errorMessageContainer); 16 | public const string errorMessageText = nameof(errorMessageText); 17 | 18 | public const string createDefaultDataSourceButton = nameof(createDefaultDataSourceButton); 19 | 20 | public const string dataSourceFilterInput = nameof(dataSourceFilterInput); 21 | 22 | public const string dataSourceSelectionSelectionSection = nameof( 23 | dataSourceSelectionSelectionSection 24 | ); 25 | 26 | public const string dataSourceSelectionButton = nameof(dataSourceSelectionButton); 27 | public const string dataSourceSelectionButtonGroup = nameof(dataSourceSelectionButtonGroup); 28 | 29 | public const string dataSourceSelectionDataSourceDropDown = nameof( 30 | dataSourceSelectionDataSourceDropDown 31 | ); 32 | 33 | public const string dataSourceSelectionFilterSection = nameof( 34 | dataSourceSelectionFilterSection 35 | ); 36 | 37 | public const string viewEditorClassName = "viewEditor"; 38 | 39 | public const string GenericRow = "genericRow"; 40 | 41 | public const string SuccessText = "successText"; 42 | public const string ErrorText = "errorText"; 43 | public const string InfoText = "infoText"; 44 | 45 | public const string addBindingActionButton = "addBindingActionButton"; 46 | public const string bindingActionButton = "bindingActionButton"; 47 | public const string bindingContainer = "bindingContainer"; 48 | public const string bindingDataSourceTypeLabel = "bindingDataSourceTypeLabel"; 49 | public const string bindingGroup = "bindingGroup"; 50 | public const string bindingGroupHeader = "bindingGroupHeader"; 51 | public const string bindingGroupLabel = "bindingGroupLabel"; 52 | public const string bindingGroupList = "bindingGroupList"; 53 | public const string bindingHeaderRow = "bindingHeaderRow"; 54 | public const string bindingInteractionButtonContainer = "bindingInteractionButtonContainer"; 55 | public const string bindingProperty = "bindingProperty"; 56 | public const string condensedBindingLabel = "condensedBindingLabel"; 57 | public const string invalidBindingClassName = "invalidBinding"; 58 | 59 | public static StyleSheet StyleSheet 60 | { 61 | get 62 | { 63 | if (sharedStyleSheetAsset == null) 64 | { 65 | sharedStyleSheetAsset = AssetDatabase.LoadAssetAtPath( 66 | viewEditorStyleSheetFile 67 | ); 68 | } 69 | 70 | return sharedStyleSheetAsset; 71 | } 72 | } 73 | 74 | internal static void DataSourceStyle(VisualElement visualElement) 75 | { 76 | visualElement.style.marginTop = 12; 77 | } 78 | 79 | internal static void ErrorMessageStyle(VisualElement visualElement) 80 | { 81 | visualElement.style.marginTop = 12; 82 | visualElement.style.fontSize = 16; 83 | visualElement.style.color = Color.red; 84 | } 85 | 86 | internal static void ErrorButtonStyle(VisualElement visualElement) 87 | { 88 | visualElement.style.alignSelf = Align.Center; 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /Editor/Scripts/DataBindingEditorStyle.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e66fc32167fa038479f7eafeaeeff8d5 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/Scripts/DatabindingEditorMenu.cs: -------------------------------------------------------------------------------- 1 | using UnityEditor; 2 | 3 | namespace JH.DataBinding.Editor 4 | { 5 | public static class DataBindingEditorMenu 6 | { 7 | // [MenuItem("Data Binding/About")] 8 | // public static void About() 9 | // { 10 | // EditorUtility.DisplayDialog("Data Binding", "Thank you for using DataBinding.", "OK"); 11 | // } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Editor/Scripts/DatabindingEditorMenu.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6fcd6197c789f5b43bc96abadf3d7923 -------------------------------------------------------------------------------- /Editor/Scripts/IDataBindingEditorDisplayText.cs: -------------------------------------------------------------------------------- 1 | namespace JH.DataBinding.Editor 2 | { 3 | public interface IDataBindingEditorDisplayText 4 | { 5 | string AssetPathLabel { get; } 6 | string CreateNewDataSourceTitle { get; } 7 | string CreateDataSourceTypeToolTipText { get; } 8 | string DataSourceTypeInspectorFilterLabel { get; } 9 | string DataSourceTypeText { get; } 10 | string EditDataSourceTooltip { get; } 11 | string EditDataSourceText { get; } 12 | string HeavyCheckMark { get; } 13 | string InvalidPathContent { get; } 14 | string InvalidPathTitle { get; } 15 | string MissingDataSourcesErrorText { get; } 16 | string NewDataSourceText { get; } 17 | string NewDataSourceTooltip { get; } 18 | string OKLabel { get; } 19 | string SourcePathText { get; } 20 | string EditorErrorMessageText { get; } 21 | string ComponentPropertyBindingsText { get; } 22 | string BindingMissingDataSourceAssignment { get; } 23 | string BindingNoBindableProperties { get; } 24 | string BindingSourceUnboundMessageText { get; } 25 | string BindingTargetUnboundMessageText { get; } 26 | string BindingUnassignableMessageText { get; } 27 | string TargetGameObjectText { get; } 28 | string TargetComponentText { get; } 29 | string TargetPathText { get; } 30 | string ComponentPropertyBindingCondensedLabelFormat_Type_Source_Target_Component { get; } 31 | string ContainerPropertyBindingsText { get; } 32 | string MoveUpButtonText { get; } 33 | string MoveDownButtonText { get; } 34 | string OpenFileBrowserButtonText { get; } 35 | string CondenseButtonText { get; } 36 | string BindingElementTemplateMissingMessageText { get; } 37 | string BindingElementTemplateIsNotAssignableMessageText { get; } 38 | string ContainerPropertyBindingCondensedLabelFormat_Type_Source_Target_Template { get; } 39 | string ReportErrorButtonText { get; } 40 | string CreateDefaultDataSourceText { get; } 41 | string NoDataSourcesText { get; } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Editor/Scripts/IDataBindingEditorDisplayText.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4bdb3cb779c3cc448b508a7d31be38ed 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/Scripts/PropertyDrawers.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2d816739b11afd14fb4d9cdc56e67e02 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Editor/Scripts/PropertyDrawers/ComponentPropertyBindingPropertyDrawer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 716fbd843af930645a601184d5df797e -------------------------------------------------------------------------------- /Editor/Scripts/PropertyDrawers/ComponentPropertyBindingSourcePathPropertyDrawer.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using UnityEditor; 3 | using UnityEngine.UIElements; 4 | 5 | namespace JH.DataBinding.Editor 6 | { 7 | [CustomPropertyDrawer(typeof(BindingSourcePathAttribute))] 8 | public class ComponentPropertyBindingSourcePathPropertyDrawer : PropertyDrawer 9 | { 10 | public override VisualElement CreatePropertyGUI(SerializedProperty property) 11 | { 12 | var view = property.serializedObject.targetObject as View; 13 | var sourceProperties = DataBindingCommonData.GetBindableDataSourceProperties( 14 | view.dataSourceType.Type 15 | ); 16 | 17 | var options = sourceProperties.Select(x => x.Name).ToList(); 18 | 19 | var rootVisualElement = new DropdownField( 20 | property.displayName, 21 | options, 22 | options.IndexOf(property.stringValue) 23 | ); 24 | 25 | rootVisualElement.AddToClassList("unity-base-field__aligned"); 26 | 27 | rootVisualElement.RegisterValueChangedCallback(x => 28 | { 29 | property.stringValue = x.newValue; 30 | property.serializedObject.ApplyModifiedProperties(); 31 | 32 | EditorUtility.SetDirty(view); 33 | }); 34 | 35 | return rootVisualElement; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Editor/Scripts/PropertyDrawers/ComponentPropertyBindingSourcePathPropertyDrawer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a629df38f32ddcb49b6bd16a7bf234af 3 | -------------------------------------------------------------------------------- /Editor/Scripts/PropertyDrawers/ComponentPropertyBindingTargetComponentPropertyDrawer.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using UnityEditor; 3 | using UnityEditor.UIElements; 4 | using UnityEngine; 5 | using UnityEngine.UIElements; 6 | 7 | namespace JH.DataBinding.Editor 8 | { 9 | [CustomPropertyDrawer(typeof(BindingTargetComponentAttribute))] 10 | public class ComponentPropertyBindingTargetComponentPropertyDrawer : PropertyDrawer 11 | { 12 | public override VisualElement CreatePropertyGUI(SerializedProperty property) 13 | { 14 | var parentPath = property.propertyPath.Replace($".{property.name}", ""); 15 | SerializedProperty componentPropertyBinding = property.serializedObject.FindProperty( 16 | parentPath 17 | ); 18 | 19 | (var bindingState, var bindableProperties) = 20 | DataBindingCommonData.DetermineComponentPropertyBindingState( 21 | componentPropertyBinding 22 | ); 23 | 24 | if ( 25 | (bindingState == ComponentPropertyBindingState.MissingDataSourceAssignment) 26 | || (bindingState == ComponentPropertyBindingState.SourceUnbound) 27 | ) 28 | { 29 | return new PropertyField(property); 30 | } 31 | 32 | var componentPropertyBindingValue = 33 | componentPropertyBinding.boxedValue as ComponentPropertyBinding; 34 | 35 | if (componentPropertyBindingValue.TargetGameObject == null) 36 | { 37 | return new PropertyField(property); 38 | } 39 | 40 | var sourceType = bindableProperties.Single(x => 41 | x.Name == componentPropertyBindingValue.SourcePath 42 | ); 43 | 44 | var candidateComponts = 45 | componentPropertyBindingValue.TargetGameObject.GetComponentsInChildren(); 46 | 47 | var options = candidateComponts 48 | .Where(x => 49 | DataBindingCommonData 50 | .GetBindableComponentProperties(x, sourceType.PropertyType) 51 | .Any() 52 | ) 53 | .Select(x => new 54 | { 55 | component = x, 56 | displayName = DataBindingCommonData.GetComponentDisplayName(x), 57 | }) 58 | .ToArray(); 59 | 60 | var stringOptions = options.Select(x => x.displayName).ToList(); 61 | 62 | var rootVisualElement = new DropdownField( 63 | property.displayName, 64 | stringOptions, 65 | stringOptions.IndexOf( 66 | DataBindingCommonData.GetComponentDisplayName( 67 | componentPropertyBindingValue.TargetComponent 68 | ) 69 | ) 70 | ); 71 | 72 | rootVisualElement.AddToClassList("unity-base-field__aligned"); 73 | 74 | rootVisualElement.RegisterValueChangedCallback(changeEvent => 75 | { 76 | property.objectReferenceValue = options 77 | .FirstOrDefault(x => x.displayName == changeEvent.newValue) 78 | .component; 79 | property.serializedObject.ApplyModifiedProperties(); 80 | }); 81 | 82 | return rootVisualElement; 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /Editor/Scripts/PropertyDrawers/ComponentPropertyBindingTargetComponentPropertyDrawer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7774fbb0c2960be429c76f1aea672185 3 | -------------------------------------------------------------------------------- /Editor/Scripts/PropertyDrawers/ComponentPropertyBindingTargetPathPropertyDrawer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | using UnityEditor; 6 | using UnityEditor.UIElements; 7 | using UnityEngine.UIElements; 8 | 9 | namespace JH.DataBinding.Editor 10 | { 11 | [CustomPropertyDrawer(typeof(BindingTargetPathAttribute))] 12 | public class ComponentPropertyBindingTargetPathPropertyDrawer : PropertyDrawer 13 | { 14 | private VisualElement rootVisualElement; 15 | private List options; 16 | private DropdownField dropDown; 17 | 18 | public override VisualElement CreatePropertyGUI(SerializedProperty property) 19 | { 20 | rootVisualElement = new(); 21 | 22 | FillInRoot(rootVisualElement, property); 23 | 24 | return rootVisualElement; 25 | } 26 | 27 | private void FillInRoot(VisualElement root, SerializedProperty property) 28 | { 29 | root.Clear(); 30 | 31 | var parentPath = property.propertyPath.Replace($".{property.name}", ""); 32 | SerializedProperty componentPropertyBinding = property.serializedObject.FindProperty( 33 | parentPath 34 | ); 35 | 36 | (var bindingState, var bindableProperties) = 37 | DataBindingCommonData.DetermineComponentPropertyBindingState( 38 | componentPropertyBinding 39 | ); 40 | 41 | if ( 42 | (bindingState == ComponentPropertyBindingState.MissingDataSourceAssignment) 43 | || (bindingState == ComponentPropertyBindingState.SourceUnbound) 44 | ) 45 | { 46 | root.Add(new PropertyField(property)); 47 | return; 48 | } 49 | 50 | var componentPropertyBindingValue = 51 | componentPropertyBinding.boxedValue as ComponentPropertyBinding; 52 | 53 | if (componentPropertyBindingValue.TargetComponent == null) 54 | { 55 | root.Add(new PropertyField(property)); 56 | return; 57 | } 58 | 59 | var sourceType = bindableProperties.Single(x => 60 | x.Name == componentPropertyBindingValue.SourcePath 61 | ); 62 | 63 | options = DataBindingCommonData 64 | .GetBindableComponentProperties( 65 | componentPropertyBindingValue.TargetComponent, 66 | sourceType.PropertyType 67 | ) 68 | .Select(x => x.Name) 69 | .ToList(); 70 | 71 | dropDown = new DropdownField( 72 | property.displayName, 73 | options, 74 | options.IndexOf(componentPropertyBindingValue.TargetPath) 75 | ); 76 | 77 | dropDown.AddToClassList("unity-base-field__aligned"); 78 | 79 | dropDown.RegisterValueChangedCallback(x => 80 | { 81 | property.stringValue = x.newValue; 82 | property.serializedObject.ApplyModifiedProperties(); 83 | 84 | EditorUtility.SetDirty(property.serializedObject.targetObject); 85 | }); 86 | 87 | //dropDown.TrackPropertyValue(property.FindPropertyRelative(), HandleObjectChanged); 88 | 89 | root.Add(dropDown); 90 | } 91 | 92 | private void HandleObjectChanged(SerializedObject @object) { } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /Editor/Scripts/PropertyDrawers/ComponentPropertyBindingTargetPathPropertyDrawer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0497335885e9bc24aa8522ff3d609b48 3 | -------------------------------------------------------------------------------- /Editor/Scripts/PropertyDrawers/ContainerPropertyBindingPropertyDrawer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e94cac06aa96dab48a1060b0f76e3172 -------------------------------------------------------------------------------- /Editor/Scripts/PropertyDrawers/ContainerPropertyBindingSourcePathPropertyDrawer.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using UnityEditor; 4 | using UnityEngine.UIElements; 5 | 6 | namespace JH.DataBinding.Editor 7 | { 8 | [CustomPropertyDrawer(typeof(EnumerableBindingSourcePathAttribute))] 9 | public class ContainerPropertyBindingSourcePathPropertyDrawer : PropertyDrawer 10 | { 11 | public override VisualElement CreatePropertyGUI(SerializedProperty property) 12 | { 13 | var view = property.serializedObject.targetObject as View; 14 | var sourceProperties = DataBindingCommonData.GetBindableDataSourceProperties( 15 | view.dataSourceType.Type 16 | ); 17 | 18 | var options = sourceProperties 19 | .Where(x => 20 | typeof(IEnumerable).IsAssignableFrom(x.PropertyType) 21 | ) 22 | .Select(x => x.Name) 23 | .ToList(); 24 | 25 | var rootVisualElement = new DropdownField( 26 | property.displayName, 27 | options, 28 | options.IndexOf(property.stringValue) 29 | ); 30 | 31 | rootVisualElement.AddToClassList("unity-base-field__aligned"); 32 | 33 | rootVisualElement.RegisterValueChangedCallback(x => 34 | { 35 | property.stringValue = x.newValue; 36 | property.serializedObject.ApplyModifiedProperties(); 37 | 38 | EditorUtility.SetDirty(view); 39 | }); 40 | 41 | return rootVisualElement; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Editor/Scripts/PropertyDrawers/ContainerPropertyBindingSourcePathPropertyDrawer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4b9e118852bbfed4da05e5b753c99d77 -------------------------------------------------------------------------------- /Editor/Scripts/PropertyDrawers/DataSourceTypePropertyDrawer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 83fca6a5158bf634a944eb84ad169eb1 -------------------------------------------------------------------------------- /Editor/Scripts/SerializedPropertyExtensions.cs: -------------------------------------------------------------------------------- 1 | using UnityEditor; 2 | 3 | public static class SerializedPropertyExtensions 4 | { 5 | public static SerializedProperty GetParentProperty(this SerializedProperty property) 6 | { 7 | var path = property.propertyPath.Replace(".Array.data[", "["); 8 | var elements = path.Split('.'); 9 | 10 | SerializedProperty parent = property.serializedObject.FindProperty(elements[0]); 11 | 12 | for (int i = 1; i < elements.Length - 1; i++) 13 | { 14 | var element = elements[i]; 15 | if (element.Contains("[")) 16 | { 17 | var index = System.Convert.ToInt32( 18 | element.Substring(element.IndexOf("[")).Replace("[", "").Replace("]", "") 19 | ); 20 | parent = parent.GetArrayElementAtIndex(index); 21 | } 22 | else 23 | { 24 | parent = parent.FindPropertyRelative(element); 25 | } 26 | } 27 | 28 | return parent; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Editor/Scripts/SerializedPropertyExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0392df7260daa5a4ca470bb1247acac3 -------------------------------------------------------------------------------- /Editor/Scripts/StringExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace JH.DataBinding 4 | { 5 | /// 6 | /// This implementation is based on (Damerau–Levenshtein distance)[https://en.wikipedia.org/wiki/Damerau%E2%80%93Levenshtein_distance] 7 | /// 8 | public static partial class StringExtensions 9 | { 10 | /// 11 | /// This implementation is based on Damerau–Levenshtein distance 12 | /// 13 | public static int DamerauLevenshteinDistance(this string one, string other) 14 | { 15 | var distanceTable = new int[one.Length + 1, other.Length + 1]; 16 | 17 | for (var idxOne = 0; idxOne <= one.Length; idxOne++) 18 | { 19 | distanceTable[idxOne, 0] = idxOne; 20 | } 21 | 22 | for (var idxOther = 0; idxOther <= other.Length; idxOther++) 23 | { 24 | distanceTable[0, idxOther] = idxOther; 25 | } 26 | 27 | for (var idxOne = 1; idxOne <= one.Length; idxOne++) 28 | { 29 | for (var idxOther = 1; idxOther <= other.Length; idxOther++) 30 | { 31 | int cost = (one[idxOne - 1] == other[idxOther - 1]) ? 0 : 1; 32 | 33 | var deletionCost = distanceTable[idxOne - 1, idxOther] + 1; 34 | var insertionCost = distanceTable[idxOne, idxOther - 1] + 1; 35 | var substitutionCost = distanceTable[idxOne - 1, idxOther - 1] + cost; 36 | 37 | distanceTable[idxOne, idxOther] = Math.Min( 38 | Math.Min(deletionCost, insertionCost), 39 | substitutionCost 40 | ); 41 | 42 | if ( 43 | (idxOne > 1) 44 | && (idxOther > 1) 45 | && (one[idxOne - 1] == other[idxOther - 2]) 46 | && (one[idxOne - 2] == other[idxOther - 1]) 47 | ) 48 | { 49 | var transpositionCost = distanceTable[idxOne - 2, idxOther - 2] + 1; 50 | 51 | distanceTable[idxOne, idxOther] = Math.Min( 52 | distanceTable[idxOne, idxOther], 53 | transpositionCost 54 | ); 55 | } 56 | } 57 | } 58 | 59 | return distanceTable[one.Length, other.Length]; 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Editor/Scripts/StringExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 83c9e1b5057ab7f40a1f86d673dcce18 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/Scripts/Style.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cc96dbd16bea3ea44b8476173d6ce169 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Editor/Scripts/Style/DataBindingStyles.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEngine.UIElements; 3 | 4 | namespace JH.DataBinding.Editor 5 | { 6 | public static class DataBindingStyles 7 | { 8 | public static void ApplyBindingContainerStyle(this VisualElement visualElement) 9 | { 10 | visualElement.style.flexDirection = FlexDirection.Column; 11 | visualElement.style.marginTop = 4; 12 | } 13 | 14 | public static void ApplyInternalErrorSectionStyle(this VisualElement visualElement) 15 | { 16 | visualElement.style.fontSize = 14; 17 | visualElement.style.Margin(4); 18 | } 19 | 20 | public static void ApplyReportErrorButtonStyle(this VisualElement visualElement) 21 | { 22 | visualElement.style.fontSize = 16; 23 | visualElement.style.Margin(4); 24 | } 25 | 26 | public static void ApplyComponentPropertyBindingStyle(this VisualElement visualElement) 27 | { 28 | visualElement.style.Margin(4); 29 | } 30 | 31 | public static void ApplBindingHeaderStyle(this VisualElement visualElement) 32 | { 33 | visualElement.style.Margin(2); 34 | visualElement.style.Padding(4); 35 | visualElement.style.fontSize = 15; 36 | visualElement.style.height = 20; 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Editor/Scripts/Style/DataBindingStyles.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 52fcfc9662a177345850f4907ae37883 -------------------------------------------------------------------------------- /Editor/Scripts/Style/VisualElementStyleExtensions.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEngine.UIElements; 3 | 4 | namespace JH.DataBinding.Editor 5 | { 6 | public static class VisualElementStyleExtensions 7 | { 8 | public static StyleLength FromPixels(int pixels) 9 | { 10 | return new StyleLength(new Length(pixels, LengthUnit.Pixel)); 11 | } 12 | 13 | public static void Margin(this IStyle style, StyleLength length) 14 | { 15 | style.marginTop = style.marginLeft = style.marginRight = style.marginBottom = length; 16 | } 17 | 18 | public static void Padding(this IStyle style, StyleLength length) 19 | { 20 | style.paddingTop = 21 | style.paddingLeft = 22 | style.paddingRight = 23 | style.paddingBottom = 24 | length; 25 | } 26 | 27 | public static void BorderWidth(this IStyle style, StyleFloat length) 28 | { 29 | style.borderTopWidth = 30 | style.borderLeftWidth = 31 | style.borderRightWidth = 32 | style.borderBottomWidth = 33 | length; 34 | } 35 | 36 | public static void BorderRadius(this IStyle style, StyleLength length) 37 | { 38 | style.borderTopLeftRadius = 39 | style.borderTopRightRadius = 40 | style.borderBottomLeftRadius = 41 | style.borderBottomRightRadius = 42 | length; 43 | } 44 | 45 | public static void BorderColor(this IStyle style, StyleColor color) 46 | { 47 | style.borderTopColor = 48 | style.borderLeftColor = 49 | style.borderRightColor = 50 | style.borderBottomColor = 51 | color; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Editor/Scripts/Style/VisualElementStyleExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c342814ee0d3c9d42b7ece44dce00fc8 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Editor/Scripts/ViewEditor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Linq; 4 | using UnityEditor; 5 | using UnityEditor.UIElements; 6 | using UnityEngine; 7 | using UnityEngine.UIElements; 8 | 9 | namespace JH.DataBinding.Editor 10 | { 11 | [CustomEditor(typeof(View), true)] 12 | public class ViewEditor : UnityEditor.Editor 13 | { 14 | private View view; 15 | private VisualElement editorRootElement; 16 | 17 | public virtual void OnEnable() 18 | { 19 | view = target as View; 20 | 21 | if (view.dataSourceType?.Type == null) 22 | { 23 | var guessedDataSourceType = DataBindingCommonData.GuessDataSourceTypeName( 24 | view.name 25 | ); 26 | 27 | if (guessedDataSourceType != null) 28 | { 29 | Debug.Log( 30 | $"Guessing {guessedDataSourceType.Name} as data source type for view {view.name}." 31 | ); 32 | 33 | view.dataSourceType.Type = guessedDataSourceType; 34 | serializedObject.ApplyModifiedProperties(); 35 | serializedObject.Update(); 36 | EditorUtility.SetDirty(view); 37 | } 38 | } 39 | } 40 | 41 | public override VisualElement CreateInspectorGUI() 42 | { 43 | editorRootElement = new VisualElement(); 44 | editorRootElement.styleSheets.Add(DataBindingEditorStyle.StyleSheet); 45 | 46 | InspectorElement.FillDefaultInspector(editorRootElement, serializedObject, this); 47 | 48 | var dataSourceTypeProperty = serializedObject.FindProperty(nameof(View.dataSourceType)); 49 | 50 | editorRootElement.TrackSerializedObjectValue( 51 | serializedObject, 52 | x => 53 | { 54 | editorRootElement.Bind(x); 55 | } 56 | ); 57 | 58 | return editorRootElement; 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /Editor/Scripts/ViewEditor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 11b1999d624d0f744adfc3f1b1e084df 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/Scripts/VisualElements.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bf9b7aacfca032744a930438a832c8b0 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Editor/Scripts/VisualElements/ComponentPropertyBindingListView.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEditor; 3 | using UnityEngine.UIElements; 4 | 5 | namespace JH.DataBinding.Editor 6 | { 7 | class ComponentPropertyBindingListView : ListView 8 | { 9 | public ComponentPropertyBindingListView() 10 | { 11 | // TODO: think about how to apply styles in general 12 | this.ApplyBindingContainerStyle(); 13 | 14 | virtualizationMethod = CollectionVirtualizationMethod.DynamicHeight; 15 | bindingPath = nameof(View.componentPropertyBindings); 16 | 17 | headerTitle = DataBindingCommonData.EditorDisplayText.ComponentPropertyBindingsText; 18 | showFoldoutHeader = true; 19 | reorderable = true; 20 | reorderMode = ListViewReorderMode.Animated; 21 | selectionType = SelectionType.Single; 22 | showBoundCollectionSize = true; 23 | showAddRemoveFooter = true; 24 | showBorder = true; 25 | #if UNITY_2023_3_OR_NEWER 26 | bindingSourceSelectionMode = BindingSourceSelectionMode.AutoAssign; 27 | allowAdd = true; 28 | allowRemove = true; 29 | #endif // UNITY_2023_3_OR_NEWER 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Editor/Scripts/VisualElements/ComponentPropertyBindingListView.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ca491fdc153ea0943ac0124a0994439c -------------------------------------------------------------------------------- /Editor/Scripts/VisualElements/ContainerPropertyBindingListView.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEditor; 3 | using UnityEngine.UIElements; 4 | 5 | namespace JH.DataBinding.Editor 6 | { 7 | class ContainerPropertyBindingListView : ListView 8 | { 9 | public ContainerPropertyBindingListView() 10 | { 11 | // TODO: think about how to apply styles in general 12 | this.ApplyBindingContainerStyle(); 13 | 14 | virtualizationMethod = CollectionVirtualizationMethod.DynamicHeight; 15 | bindingPath = nameof(View.containerPropertyBindings); 16 | 17 | headerTitle = DataBindingCommonData.EditorDisplayText.ContainerPropertyBindingsText; 18 | showFoldoutHeader = true; 19 | reorderable = true; 20 | reorderMode = ListViewReorderMode.Animated; 21 | selectionType = SelectionType.Single; 22 | showBoundCollectionSize = true; 23 | showAddRemoveFooter = true; 24 | showBorder = true; 25 | #if UNITY_2023_3_OR_NEWER 26 | bindingSourceSelectionMode = BindingSourceSelectionMode.AutoAssign; 27 | allowAdd = true; 28 | allowRemove = true; 29 | #endif // UNITY_2023_3_OR_NEWER 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Editor/Scripts/VisualElements/ContainerPropertyBindingListView.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9aa7b1ebaa6143e459fd41b9137520f3 -------------------------------------------------------------------------------- /Editor/Scripts/VisualElements/InternalErrorReport.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | using UnityEngine.UIElements; 4 | 5 | namespace JH.DataBinding.Editor 6 | { 7 | internal class InternalErrorReport : VisualElement 8 | { 9 | internal InternalErrorReport(Exception exception) 10 | { 11 | // AddToClassList(); 12 | 13 | var errorLabel = new TextElement(); 14 | errorLabel.text = DataBindingCommonData.EditorDisplayText.EditorErrorMessageText; 15 | errorLabel.ApplyInternalErrorSectionStyle(); 16 | Add(errorLabel); 17 | 18 | var message = new TextElement(); 19 | message.text = exception.Message; 20 | message.ApplyInternalErrorSectionStyle(); 21 | Add(message); 22 | 23 | var reportBugLink = new Button(() => HandleReportError(exception)); 24 | reportBugLink.text = DataBindingCommonData.EditorDisplayText.ReportErrorButtonText; 25 | reportBugLink.ApplyReportErrorButtonStyle(); 26 | Add(reportBugLink); 27 | } 28 | 29 | private static void HandleReportError(Exception exception) 30 | { 31 | var link = 32 | $"https://github.com/JochenHeckl/DataBinding/issues/new?assignees=&labels=&template=bug_report.md&title={exception.Message}"; 33 | 34 | Application.OpenURL(link); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Editor/Scripts/VisualElements/InternalErrorReport.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a469d7ac74f5200409dad21bf674ca0b -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Unity Data Binding Copyright (c) 2019 Jochen Heckl 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /LICENSE.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 95bdfa3bf65e24e49830e8b148022e27 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Unity DataBinding 2 | 3 | ### What is Unity DataBinding? 4 | 5 | DataBinding is a method of connecting a data model with user interface components, allowing changes in one to automatically reflect in the other. 6 | 7 | This package supplies the means that will enable you to implement declarative user interfaces (== user interfaces that are a function of the underlying data that defines it). It's like WPF for Unity Game Objects. 8 | 9 | ```mermaid 10 | --- 11 | title: High Level Overview 12 | --- 13 | graph LR 14 | DS[DataSource] -->|Property|CPB(Component Property Binding) 15 | DS -->|IEnumerable<> Property|CB(Container Binding) 16 | CPB -->|Property|V[View] 17 | CB -->|populate Children| V 18 | ET([Element 19 | Template]) -.->CB 20 | ``` 21 | 22 | ### Tutorials 23 | 24 | - [Getting Started](Documentation~/GettingStarted.md) (Detailed Step by Step Tutorial - 5 minutes to complete) 25 | 26 | 27 | 28 | Create a simple scene showing a cube that randomly changes scale and color. This tutorial will make you familiar with fundamental ideas of this tool. 29 | 30 | --- 31 | 32 | - [How to react to user input](Documentation~/HowToReactToUserInput.md) (Step by Step Tutorial - 5 minutes to complete) 33 | 34 | 35 | 36 | Starting from a simple scene that renders some input controls fill in the blanks that makes user input available to your application logic. 37 | 38 | --- 39 | 40 | - [A look at ContainerBindings](Documentation~/ALookAtContainerBindings.md) (Step by Step Tutorial - 5 minutes to complete) 41 | 42 | 43 | 44 | Concerning user interface tool sets: When it comes to handling not just static but dynamic content is where the wheat is separated from the chaff. Starting with some basic prefabs you will put together a nice little party panel for your characters in this tutorial. 45 | 46 | 47 | ### Planned next steps: 48 | - Look into a Generic View<> component that limits the types of the datasourcedropdown to types derived from the generic type 49 | - Improve automatic tests 50 | - Add samples for new features 51 | - Update existing samples 52 | -------------------------------------------------------------------------------- /README.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1a086469b19476d4a91f606809a335d2 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Runtime.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 62858760387b5c442b31f990944f5199 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/JH.DataBinding.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "JH.DataBinding", 3 | "rootNamespace": "JH.DataBinding", 4 | "references": [ 5 | "UnityEditor.UI", 6 | "UnityEngine.UI" 7 | ], 8 | "includePlatforms": [], 9 | "excludePlatforms": [], 10 | "allowUnsafeCode": false, 11 | "overrideReferences": false, 12 | "precompiledReferences": [], 13 | "autoReferenced": true, 14 | "defineConstraints": [], 15 | "versionDefines": [], 16 | "noEngineReferences": false 17 | } -------------------------------------------------------------------------------- /Runtime/JH.DataBinding.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1ac1bd0cf575cfe4b8d295c36f1e0edd 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Runtime/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 83ee9808e86513f4c8698b9af318258e 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/Scripts/Attributes.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2e50870a1dcac7b4b8910db468342bcb 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/Scripts/Attributes/BindingSourcePathAttribute.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace JH.DataBinding 4 | { 5 | public class BindingSourcePathAttribute : PropertyAttribute 6 | { 7 | public BindingSourcePathAttribute() { } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Runtime/Scripts/Attributes/BindingSourcePathAttribute.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bbe1971d0f6875a48bc67e287d96f266 -------------------------------------------------------------------------------- /Runtime/Scripts/Attributes/BindingTargetComponentAttribute.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace JH.DataBinding 4 | { 5 | public class BindingTargetComponentAttribute : PropertyAttribute 6 | { 7 | public BindingTargetComponentAttribute() { } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Runtime/Scripts/Attributes/BindingTargetComponentAttribute.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: aa2f2c023a961f24499a55013d648215 3 | -------------------------------------------------------------------------------- /Runtime/Scripts/Attributes/BindingTargetPathAttribute.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace JH.DataBinding 4 | { 5 | public class BindingTargetPathAttribute : PropertyAttribute 6 | { 7 | public BindingTargetPathAttribute() { } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Runtime/Scripts/Attributes/BindingTargetPathAttribute.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7b7eb3219000e1c45bd8f11aa793915c -------------------------------------------------------------------------------- /Runtime/Scripts/Attributes/DataSourceTypeAttribute.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace JH.DataBinding 4 | { 5 | public class DataSourceTypeAttribute : PropertyAttribute 6 | { 7 | public DataSourceTypeAttribute() { } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Runtime/Scripts/Attributes/DataSourceTypeAttribute.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: beca1a8e272f22b44bef06a05a218ac6 -------------------------------------------------------------------------------- /Runtime/Scripts/Attributes/EnumerableBindingSourcePathAttribute.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace JH.DataBinding 4 | { 5 | public class EnumerableBindingSourcePathAttribute : PropertyAttribute 6 | { 7 | public EnumerableBindingSourcePathAttribute() { } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Runtime/Scripts/Attributes/EnumerableBindingSourcePathAttribute.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8a77df91e94d035469fae33ee18bcdef -------------------------------------------------------------------------------- /Runtime/Scripts/Bindings.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bf422ba30e09b6f439758daca7535415 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/Scripts/Bindings/ComponentPropertyBinding.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3846780fa3335054c92b027342af6c01 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Scripts/Bindings/ContainerPropertyBinding.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | using UnityEngine; 6 | 7 | namespace JH.DataBinding 8 | { 9 | [Serializable] 10 | public class ContainerPropertyBinding 11 | { 12 | [SerializeField] 13 | [EnumerableBindingSourcePath] 14 | private string sourcePath; 15 | 16 | [SerializeField] 17 | private Transform targetContainer; 18 | 19 | [SerializeField] 20 | private View elementTemplate; 21 | 22 | private object dataSource; 23 | 24 | private MethodInfo[] dataSourcePropertyAccessors; 25 | 26 | public object DataSource 27 | { 28 | get => dataSource; 29 | set 30 | { 31 | dataSource = value; 32 | BindSource(); 33 | } 34 | } 35 | 36 | public string SourcePath 37 | { 38 | get => sourcePath; 39 | set 40 | { 41 | sourcePath = value; 42 | BindSource(); 43 | } 44 | } 45 | 46 | public Transform TargetContainer 47 | { 48 | get => targetContainer; 49 | set => targetContainer = value; 50 | } 51 | 52 | public View ElementTemplate 53 | { 54 | get => elementTemplate; 55 | set => elementTemplate = value; 56 | } 57 | 58 | private void BindSource() 59 | { 60 | if (dataSource != null && !String.IsNullOrEmpty(sourcePath)) 61 | { 62 | dataSourcePropertyAccessors = dataSource 63 | .ResolvePublicPropertyPath(SourcePath, PathResolveOperation.GetValue) 64 | .ToArray(); 65 | } 66 | else 67 | { 68 | dataSourcePropertyAccessors = Array.Empty(); 69 | } 70 | } 71 | 72 | public void UpdateBinding() 73 | { 74 | if ( 75 | (dataSourcePropertyAccessors != null) 76 | && (ElementTemplate != null) 77 | && (TargetContainer != null) 78 | ) 79 | { 80 | var boundInstances = ( 81 | ( 82 | dataSourcePropertyAccessors.InvokeGetAccessChain(dataSource) 83 | as IEnumerable 84 | ) ?? Array.Empty() 85 | ).ToArray(); 86 | 87 | AddMissingChildren(boundInstances.Length); 88 | RemoveSuperfluousChildren(boundInstances.Length); 89 | 90 | for (var childIndex = 0; childIndex < boundInstances.Length; childIndex++) 91 | { 92 | // ReSharper disable once Unity.PerformanceCriticalCodeInvocation 93 | var view = TargetContainer.GetChild(childIndex).GetComponent(); 94 | view.DataSource = boundInstances[childIndex]; 95 | } 96 | } 97 | } 98 | 99 | private void AddMissingChildren(int numRequiredChildren) 100 | { 101 | while (TargetContainer.childCount < numRequiredChildren) 102 | { 103 | UnityEngine.Object.Instantiate(ElementTemplate, TargetContainer); 104 | } 105 | } 106 | 107 | private void RemoveSuperfluousChildren(int numberOfChildrenToKeep) 108 | { 109 | for ( 110 | var childIndex = numberOfChildrenToKeep; 111 | childIndex < TargetContainer.childCount; 112 | ++childIndex 113 | ) 114 | { 115 | UnityEngine.Object.Destroy(TargetContainer.GetChild(childIndex).gameObject); 116 | } 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /Runtime/Scripts/Bindings/ContainerPropertyBinding.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: dce748c50b76d1a48bb832a6cbdddc60 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Scripts/DataSourceBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace JH.DataBinding 4 | { 5 | public class DataSourceBase : INotifyDataSourceChanged 6 | where DataSourceType : DataSourceBase 7 | { 8 | public event Action DataSourceChanged = delegate { }; 9 | 10 | public void NotifyChanges(Action applyChanges) 11 | { 12 | applyChanges((DataSourceType)this); 13 | DataSourceChanged(); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Runtime/Scripts/DataSourceBase.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7ed873d9e07a7be42b7feaa2da5dc3c9 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Scripts/GameObjectPropertyAccess.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace JH.DataBinding 4 | { 5 | public class GameObjectPropertyAccess : MonoBehaviour 6 | { 7 | public bool GameObjectEnabled 8 | { 9 | get { return gameObject.activeSelf; } 10 | set { gameObject.SetActive(value); } 11 | } 12 | 13 | public int GameObjectLayer 14 | { 15 | get { return gameObject.layer; } 16 | set { gameObject.layer = value; } 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Runtime/Scripts/GameObjectPropertyAccess.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a79743bb58a566b4b80ab046e20646a7 -------------------------------------------------------------------------------- /Runtime/Scripts/INotifyDataSourceChanged.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace JH.DataBinding 4 | { 5 | public interface INotifyDataSourceChanged 6 | { 7 | event Action DataSourceChanged; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Runtime/Scripts/INotifyDataSourceChanged.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 338811c099851cc4bb0701000c865ff5 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Scripts/Reflection.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 940493e6208a6084db6ab57aa6126c99 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/Scripts/Reflection/ReflectionExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 11ec10790b93f904882562f020d59e97 3 | timeCreated: 1490795787 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Runtime/Scripts/Reflection/SerializableType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | 4 | namespace JH.DataBinding 5 | { 6 | [Serializable] 7 | public class SerializableType 8 | { 9 | public Type Type 10 | { 11 | get 12 | { 13 | if (!String.IsNullOrEmpty(assemblyQualifiedName)) 14 | { 15 | return System.Type.GetType(assemblyQualifiedName); 16 | } 17 | 18 | return null; 19 | } 20 | set 21 | { 22 | if (value != null) 23 | { 24 | assemblyQualifiedName = value.AssemblyQualifiedName; 25 | } 26 | else 27 | { 28 | assemblyQualifiedName = string.Empty; 29 | } 30 | } 31 | } 32 | 33 | [SerializeField] 34 | public string assemblyQualifiedName; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Runtime/Scripts/Reflection/SerializableType.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3fc93dfdf1e17944d9a252caa160d45b 3 | timeCreated: 1490776492 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Runtime/Scripts/Reflection/SerializableTypes.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using UnityEngine; 5 | 6 | namespace JH.DataBinding 7 | { 8 | [Serializable] 9 | public class SerializableTypes 10 | { 11 | public Type this[int i] 12 | { 13 | get 14 | { 15 | if (!String.IsNullOrEmpty(assemblyQualifiedName[i])) 16 | { 17 | return Type.GetType(assemblyQualifiedName[i]); 18 | } 19 | 20 | return null; 21 | } 22 | set 23 | { 24 | if (value != null) 25 | { 26 | assemblyQualifiedName[i] = value.AssemblyQualifiedName; 27 | } 28 | else 29 | { 30 | assemblyQualifiedName[i] = string.Empty; 31 | } 32 | } 33 | } 34 | 35 | public IEnumerable Types 36 | { 37 | get { return assemblyQualifiedName.Select(x => Type.GetType(x)); } 38 | } 39 | 40 | [SerializeField] 41 | public string[] assemblyQualifiedName; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Runtime/Scripts/Reflection/SerializableTypes.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 62dbface25d87254d9b0a631aea1db95 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Scripts/View.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using UnityEngine; 4 | 5 | namespace JH.DataBinding 6 | { 7 | [DebuggerDisplay("View({name}) : {DataSource}")] 8 | public class View : MonoBehaviour 9 | { 10 | #if UNITY_EDITOR 11 | [DataSourceType] 12 | public SerializableType dataSourceType; 13 | #endif // UNITY_EDITOR 14 | 15 | public ComponentPropertyBinding[] componentPropertyBindings = 16 | Array.Empty(); 17 | 18 | public ContainerPropertyBinding[] containerPropertyBindings = 19 | Array.Empty(); 20 | 21 | private INotifyDataSourceChanged dataSource; 22 | 23 | public void OnEnable() 24 | { 25 | BindBindingDataSources(dataSource); 26 | UpdateBindings(); 27 | } 28 | 29 | public void OnDestroy() 30 | { 31 | if (DataSource != null) 32 | { 33 | DataSource = null; 34 | } 35 | } 36 | 37 | public INotifyDataSourceChanged DataSource 38 | { 39 | get 40 | { 41 | // return local data source if available 42 | 43 | if (dataSource != null) 44 | { 45 | return dataSource; 46 | } 47 | 48 | // walk up the hierarchy if no local data source is available 49 | 50 | var parent = transform.parent; 51 | 52 | if (parent != null) 53 | { 54 | var parentViewBehaviour = parent.GetComponent(); 55 | 56 | if (parentViewBehaviour != null) 57 | { 58 | return parentViewBehaviour.DataSource; 59 | } 60 | } 61 | 62 | return null; 63 | } 64 | set 65 | { 66 | if (dataSource == value) 67 | { 68 | return; 69 | } 70 | 71 | var oldDataSource = DataSource as INotifyDataSourceChanged; 72 | 73 | if (oldDataSource != null) 74 | { 75 | oldDataSource.DataSourceChanged -= OnDataSourceChanged; 76 | } 77 | 78 | dataSource = value; 79 | BindBindingDataSources(dataSource); 80 | 81 | var newDataSource = DataSource as INotifyDataSourceChanged; 82 | 83 | if (newDataSource != null) 84 | { 85 | newDataSource.DataSourceChanged += OnDataSourceChanged; 86 | } 87 | 88 | UpdateBindings(); 89 | } 90 | } 91 | 92 | private void OnDataSourceChanged() 93 | { 94 | UpdateBindings(); 95 | } 96 | 97 | private void BindBindingDataSources(object bindingDataSource) 98 | { 99 | foreach (var binding in componentPropertyBindings) 100 | { 101 | binding.DataSource = bindingDataSource; 102 | } 103 | 104 | foreach (var binding in containerPropertyBindings) 105 | { 106 | binding.DataSource = bindingDataSource; 107 | } 108 | } 109 | 110 | private void UpdateBindings() 111 | { 112 | foreach (var binding in componentPropertyBindings) 113 | { 114 | binding.UpdateBinding(); 115 | } 116 | 117 | foreach (var binding in containerPropertyBindings) 118 | { 119 | binding.UpdateBinding(); 120 | } 121 | } 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /Runtime/Scripts/View.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 86b5f087a6158b7409c18f4ecd50007e 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Finished/A look at ContainerBindings.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8ad59056849855b4d926a9496d6a9c4f 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Finished/Prefabs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 56d130a2b36df094dbf7f1520a225d4e 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Finished/Prefabs/Attribute View.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4224f8f75e0244f48a63e9086793af2d 3 | PrefabImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Finished/Prefabs/Character View.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 761391fb3c4a0e640a664c16b9a1439e 3 | PrefabImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Finished/Prefabs/Party View.prefab: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1 &3139894007772533002 4 | GameObject: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | serializedVersion: 6 10 | m_Component: 11 | - component: {fileID: 3139894007772533003} 12 | - component: {fileID: 3139894007772532996} 13 | m_Layer: 5 14 | m_Name: Party View 15 | m_TagString: Untagged 16 | m_Icon: {fileID: 0} 17 | m_NavMeshLayer: 0 18 | m_StaticEditorFlags: 0 19 | m_IsActive: 1 20 | --- !u!224 &3139894007772533003 21 | RectTransform: 22 | m_ObjectHideFlags: 0 23 | m_CorrespondingSourceObject: {fileID: 0} 24 | m_PrefabInstance: {fileID: 0} 25 | m_PrefabAsset: {fileID: 0} 26 | m_GameObject: {fileID: 3139894007772533002} 27 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 28 | m_LocalPosition: {x: 0, y: 0, z: 0} 29 | m_LocalScale: {x: 1, y: 1, z: 1} 30 | m_ConstrainProportionsScale: 0 31 | m_Children: 32 | - {fileID: 1394055450767064804} 33 | m_Father: {fileID: 0} 34 | m_RootOrder: 0 35 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 36 | m_AnchorMin: {x: 0, y: 0} 37 | m_AnchorMax: {x: 1, y: 1} 38 | m_AnchoredPosition: {x: 0, y: 0} 39 | m_SizeDelta: {x: 0, y: 0} 40 | m_Pivot: {x: 0.5, y: 0.5} 41 | --- !u!114 &3139894007772532996 42 | MonoBehaviour: 43 | m_ObjectHideFlags: 0 44 | m_CorrespondingSourceObject: {fileID: 0} 45 | m_PrefabInstance: {fileID: 0} 46 | m_PrefabAsset: {fileID: 0} 47 | m_GameObject: {fileID: 3139894007772533002} 48 | m_Enabled: 1 49 | m_EditorHideFlags: 0 50 | m_Script: {fileID: 11500000, guid: 86b5f087a6158b7409c18f4ecd50007e, type: 3} 51 | m_Name: 52 | m_EditorClassIdentifier: 53 | dataSourceType: 54 | assemblyQualifiedName: de.JochenHeckl.Unity.DataBinding.Examples.ContainerBindings.PartyViewModel, 55 | Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null 56 | componentPropertyBindings: [] 57 | containerPropertyBindings: 58 | - showExpanded: 1 59 | targetContainer: {fileID: 1394055450767064804} 60 | elementTemplate: {fileID: 6668738108973706113, guid: 761391fb3c4a0e640a664c16b9a1439e, 61 | type: 3} 62 | sourcePath: Characters 63 | --- !u!1 &3183226223414695614 64 | GameObject: 65 | m_ObjectHideFlags: 0 66 | m_CorrespondingSourceObject: {fileID: 0} 67 | m_PrefabInstance: {fileID: 0} 68 | m_PrefabAsset: {fileID: 0} 69 | serializedVersion: 6 70 | m_Component: 71 | - component: {fileID: 1394055450767064804} 72 | - component: {fileID: 2085375641424296701} 73 | m_Layer: 5 74 | m_Name: Characters 75 | m_TagString: Untagged 76 | m_Icon: {fileID: 0} 77 | m_NavMeshLayer: 0 78 | m_StaticEditorFlags: 0 79 | m_IsActive: 1 80 | --- !u!224 &1394055450767064804 81 | RectTransform: 82 | m_ObjectHideFlags: 0 83 | m_CorrespondingSourceObject: {fileID: 0} 84 | m_PrefabInstance: {fileID: 0} 85 | m_PrefabAsset: {fileID: 0} 86 | m_GameObject: {fileID: 3183226223414695614} 87 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 88 | m_LocalPosition: {x: 0, y: 0, z: 0} 89 | m_LocalScale: {x: 1, y: 1, z: 1} 90 | m_ConstrainProportionsScale: 0 91 | m_Children: [] 92 | m_Father: {fileID: 3139894007772533003} 93 | m_RootOrder: -1 94 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 95 | m_AnchorMin: {x: 0, y: 0} 96 | m_AnchorMax: {x: 1, y: 1} 97 | m_AnchoredPosition: {x: 0, y: 0} 98 | m_SizeDelta: {x: 0, y: 0} 99 | m_Pivot: {x: 0.5, y: 0.5} 100 | --- !u!114 &2085375641424296701 101 | MonoBehaviour: 102 | m_ObjectHideFlags: 0 103 | m_CorrespondingSourceObject: {fileID: 0} 104 | m_PrefabInstance: {fileID: 0} 105 | m_PrefabAsset: {fileID: 0} 106 | m_GameObject: {fileID: 3183226223414695614} 107 | m_Enabled: 1 108 | m_EditorHideFlags: 0 109 | m_Script: {fileID: 11500000, guid: 8a8695521f0d02e499659fee002a26c2, type: 3} 110 | m_Name: 111 | m_EditorClassIdentifier: 112 | m_Padding: 113 | m_Left: 0 114 | m_Right: 0 115 | m_Top: 0 116 | m_Bottom: 0 117 | m_ChildAlignment: 4 118 | m_StartCorner: 0 119 | m_StartAxis: 0 120 | m_CellSize: {x: 372, y: 224} 121 | m_Spacing: {x: 4, y: 4} 122 | m_Constraint: 1 123 | m_ConstraintCount: 2 124 | -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Finished/Prefabs/Party View.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7db9b76be1d221f41baf341f586bf77d 3 | PrefabImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Finished/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fc7d55e3e2c6e6743b873a2d63df952f 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Finished/Scripts/AttributeViewModel.cs: -------------------------------------------------------------------------------- 1 | namespace JH.DataBinding.Examples.ContainerBindings 2 | { 3 | public class AttributeViewModel : DataSourceBase 4 | { 5 | public string Name { get; set; } 6 | public int Value { get; set; } 7 | public string ValueString => $"{Value}"; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Finished/Scripts/AttributeViewModel.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e4da929ef3ab79342a9c6ef1e377286e 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Finished/Scripts/Bootstrap.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using UnityEngine; 3 | using Random = UnityEngine.Random; 4 | 5 | namespace JH.DataBinding.Examples.ContainerBindings 6 | { 7 | public class Bootstrap : MonoBehaviour 8 | { 9 | public View partyViewTemplate; 10 | public Transform partyViewContainer; 11 | 12 | public Sprite theOneAndOnlyCharacterImage; 13 | 14 | private View partyView; 15 | 16 | void Start() 17 | { 18 | var partyViewModel = new PartyViewModel() 19 | { 20 | Characters = Enumerable.Range(1, 4).Select(x => MakeCharacterData(x)).ToArray() 21 | }; 22 | 23 | partyView = GameObject.Instantiate(partyViewTemplate, partyViewContainer); 24 | partyView.DataSource = partyViewModel; 25 | } 26 | 27 | private CharacterViewModel MakeCharacterData(int characterCreationIndex) 28 | { 29 | var charcterClasses = new string[] { "Mage", "Priest", "Rogue", "Warrior", }; 30 | 31 | var characterLevel = Random.Range(1, 10); 32 | 33 | return new CharacterViewModel() 34 | { 35 | Name = $"Character 0{characterCreationIndex}", 36 | Class = charcterClasses.ElementAt(Random.Range(0, 3)), 37 | Level = characterLevel, 38 | LevelProgress = Random.Range(0f, 1f), 39 | Attributes = MakeAttributes(characterLevel), 40 | CharacterImage = theOneAndOnlyCharacterImage 41 | }; 42 | } 43 | 44 | private AttributeViewModel[] MakeAttributes(int characterLevel) 45 | { 46 | var attributes = new string[] 47 | { 48 | "Agility", 49 | "Intelligence", 50 | "Resistence", 51 | "Sorcery", 52 | "Strength", 53 | "Will", 54 | }; 55 | 56 | return attributes 57 | .Select( 58 | x => 59 | new AttributeViewModel() 60 | { 61 | Name = x, 62 | Value = Random.Range(1, 6 + characterLevel / 6) 63 | } 64 | ) 65 | .ToArray(); 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Finished/Scripts/Bootstrap.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a5643dec7ede891438295f8e885970c9 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Finished/Scripts/CharacterViewModel.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace JH.DataBinding.Examples.ContainerBindings 4 | { 5 | public class CharacterViewModel : DataSourceBase 6 | { 7 | public string Name { get; set; } 8 | public string Class { get; set; } 9 | 10 | public int Level { get; set; } 11 | public string LevelString => $"{Level}"; 12 | public float LevelProgress { get; internal set; } 13 | 14 | public AttributeViewModel[] Attributes { get; set; } 15 | public Sprite CharacterImage { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Finished/Scripts/CharacterViewModel.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 887224b316db4c44584342debd818fe7 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Finished/Scripts/PartyViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | namespace JH.DataBinding.Examples.ContainerBindings 6 | { 7 | public class PartyViewModel : DataSourceBase 8 | { 9 | public IEnumerable Characters { get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Finished/Scripts/PartyViewModel.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1be032f3f070c4548a2dbc3ee949f288 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Finished/Textures.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: eef04ca37a9556c419c8d78540321aa5 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Finished/Textures/Attribute.Background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JochenHeckl/DataBinding/6e2e750e61e90dd72b2b80b2b9d397f2c818574c/Samples~/A look at ContainerBindings - Finished/Textures/Attribute.Background.png -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Finished/Textures/Attribute.Background.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4683bb3b508525b45a9c4eda5a3f522a 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 12 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | flipGreenChannel: 0 24 | isReadable: 0 25 | streamingMipmaps: 0 26 | streamingMipmapsPriority: 0 27 | vTOnly: 0 28 | ignoreMipmapLimit: 0 29 | grayScaleToAlpha: 0 30 | generateCubemap: 6 31 | cubemapConvolution: 0 32 | seamlessCubemap: 0 33 | textureFormat: 1 34 | maxTextureSize: 2048 35 | textureSettings: 36 | serializedVersion: 2 37 | filterMode: 1 38 | aniso: 1 39 | mipBias: 0 40 | wrapU: 1 41 | wrapV: 1 42 | wrapW: 0 43 | nPOTScale: 0 44 | lightmap: 0 45 | compressionQuality: 50 46 | spriteMode: 1 47 | spriteExtrude: 1 48 | spriteMeshType: 1 49 | alignment: 0 50 | spritePivot: {x: 0.5, y: 0.5} 51 | spritePixelsToUnits: 100 52 | spriteBorder: {x: 16, y: 16, z: 16, w: 32} 53 | spriteGenerateFallbackPhysicsShape: 1 54 | alphaUsage: 1 55 | alphaIsTransparency: 1 56 | spriteTessellationDetail: -1 57 | textureType: 8 58 | textureShape: 1 59 | singleChannelComponent: 0 60 | flipbookRows: 1 61 | flipbookColumns: 1 62 | maxTextureSizeSet: 0 63 | compressionQualitySet: 0 64 | textureFormatSet: 0 65 | ignorePngGamma: 0 66 | applyGammaDecoding: 0 67 | swizzle: 50462976 68 | cookieLightType: 0 69 | platformSettings: 70 | - serializedVersion: 3 71 | buildTarget: DefaultTexturePlatform 72 | maxTextureSize: 64 73 | resizeAlgorithm: 0 74 | textureFormat: -1 75 | textureCompression: 1 76 | compressionQuality: 50 77 | crunchedCompression: 0 78 | allowsAlphaSplitting: 0 79 | overridden: 0 80 | androidETC2FallbackOverride: 0 81 | forceMaximumCompressionQuality_BC6H_BC7: 0 82 | - serializedVersion: 3 83 | buildTarget: Standalone 84 | maxTextureSize: 2048 85 | resizeAlgorithm: 0 86 | textureFormat: -1 87 | textureCompression: 1 88 | compressionQuality: 50 89 | crunchedCompression: 0 90 | allowsAlphaSplitting: 0 91 | overridden: 0 92 | androidETC2FallbackOverride: 0 93 | forceMaximumCompressionQuality_BC6H_BC7: 0 94 | - serializedVersion: 3 95 | buildTarget: Server 96 | maxTextureSize: 2048 97 | resizeAlgorithm: 0 98 | textureFormat: -1 99 | textureCompression: 1 100 | compressionQuality: 50 101 | crunchedCompression: 0 102 | allowsAlphaSplitting: 0 103 | overridden: 0 104 | androidETC2FallbackOverride: 0 105 | forceMaximumCompressionQuality_BC6H_BC7: 0 106 | spriteSheet: 107 | serializedVersion: 2 108 | sprites: [] 109 | outline: [] 110 | physicsShape: [] 111 | bones: [] 112 | spriteID: 5e97eb03825dee720800000000000000 113 | internalID: 1537655665 114 | vertices: [] 115 | indices: 116 | edges: [] 117 | weights: [] 118 | secondaryTextures: [] 119 | nameFileIdTable: {} 120 | mipmapLimitGroupName: 121 | pSDRemoveMatte: 0 122 | userData: 123 | assetBundleName: 124 | assetBundleVariant: 125 | -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Finished/Textures/CharacterImage.01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JochenHeckl/DataBinding/6e2e750e61e90dd72b2b80b2b9d397f2c818574c/Samples~/A look at ContainerBindings - Finished/Textures/CharacterImage.01.png -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Finished/Textures/CharacterImage.01.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2cd5d91abcdb1654a8c2b29ae771d7e2 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 12 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | flipGreenChannel: 0 24 | isReadable: 0 25 | streamingMipmaps: 0 26 | streamingMipmapsPriority: 0 27 | vTOnly: 0 28 | ignoreMipmapLimit: 0 29 | grayScaleToAlpha: 0 30 | generateCubemap: 6 31 | cubemapConvolution: 0 32 | seamlessCubemap: 0 33 | textureFormat: 1 34 | maxTextureSize: 2048 35 | textureSettings: 36 | serializedVersion: 2 37 | filterMode: 1 38 | aniso: 1 39 | mipBias: 0 40 | wrapU: 1 41 | wrapV: 1 42 | wrapW: 0 43 | nPOTScale: 0 44 | lightmap: 0 45 | compressionQuality: 50 46 | spriteMode: 1 47 | spriteExtrude: 1 48 | spriteMeshType: 1 49 | alignment: 0 50 | spritePivot: {x: 0.5, y: 0.5} 51 | spritePixelsToUnits: 100 52 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 53 | spriteGenerateFallbackPhysicsShape: 1 54 | alphaUsage: 1 55 | alphaIsTransparency: 1 56 | spriteTessellationDetail: -1 57 | textureType: 8 58 | textureShape: 1 59 | singleChannelComponent: 0 60 | flipbookRows: 1 61 | flipbookColumns: 1 62 | maxTextureSizeSet: 0 63 | compressionQualitySet: 0 64 | textureFormatSet: 0 65 | ignorePngGamma: 0 66 | applyGammaDecoding: 0 67 | swizzle: 50462976 68 | cookieLightType: 0 69 | platformSettings: 70 | - serializedVersion: 3 71 | buildTarget: DefaultTexturePlatform 72 | maxTextureSize: 1024 73 | resizeAlgorithm: 0 74 | textureFormat: -1 75 | textureCompression: 1 76 | compressionQuality: 50 77 | crunchedCompression: 0 78 | allowsAlphaSplitting: 0 79 | overridden: 0 80 | androidETC2FallbackOverride: 0 81 | forceMaximumCompressionQuality_BC6H_BC7: 0 82 | - serializedVersion: 3 83 | buildTarget: Standalone 84 | maxTextureSize: 2048 85 | resizeAlgorithm: 0 86 | textureFormat: -1 87 | textureCompression: 1 88 | compressionQuality: 50 89 | crunchedCompression: 0 90 | allowsAlphaSplitting: 0 91 | overridden: 0 92 | androidETC2FallbackOverride: 0 93 | forceMaximumCompressionQuality_BC6H_BC7: 0 94 | - serializedVersion: 3 95 | buildTarget: Server 96 | maxTextureSize: 2048 97 | resizeAlgorithm: 0 98 | textureFormat: -1 99 | textureCompression: 1 100 | compressionQuality: 50 101 | crunchedCompression: 0 102 | allowsAlphaSplitting: 0 103 | overridden: 0 104 | androidETC2FallbackOverride: 0 105 | forceMaximumCompressionQuality_BC6H_BC7: 0 106 | spriteSheet: 107 | serializedVersion: 2 108 | sprites: [] 109 | outline: [] 110 | physicsShape: [] 111 | bones: [] 112 | spriteID: 5e97eb03825dee720800000000000000 113 | internalID: 0 114 | vertices: [] 115 | indices: 116 | edges: [] 117 | weights: [] 118 | secondaryTextures: [] 119 | nameFileIdTable: {} 120 | mipmapLimitGroupName: 121 | pSDRemoveMatte: 0 122 | userData: 123 | assetBundleName: 124 | assetBundleVariant: 125 | -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Finished/Textures/Frame.1px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JochenHeckl/DataBinding/6e2e750e61e90dd72b2b80b2b9d397f2c818574c/Samples~/A look at ContainerBindings - Finished/Textures/Frame.1px.png -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Finished/Textures/Frame.1px.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5d8e6e0e0417df34893dbdfaa4afe69f 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 12 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | flipGreenChannel: 0 24 | isReadable: 0 25 | streamingMipmaps: 0 26 | streamingMipmapsPriority: 0 27 | vTOnly: 0 28 | ignoreMipmapLimit: 0 29 | grayScaleToAlpha: 0 30 | generateCubemap: 6 31 | cubemapConvolution: 0 32 | seamlessCubemap: 0 33 | textureFormat: 1 34 | maxTextureSize: 2048 35 | textureSettings: 36 | serializedVersion: 2 37 | filterMode: 0 38 | aniso: 1 39 | mipBias: 0 40 | wrapU: 1 41 | wrapV: 1 42 | wrapW: 0 43 | nPOTScale: 0 44 | lightmap: 0 45 | compressionQuality: 50 46 | spriteMode: 1 47 | spriteExtrude: 1 48 | spriteMeshType: 1 49 | alignment: 0 50 | spritePivot: {x: 0.5, y: 0.5} 51 | spritePixelsToUnits: 100 52 | spriteBorder: {x: 2, y: 2, z: 2, w: 2} 53 | spriteGenerateFallbackPhysicsShape: 1 54 | alphaUsage: 1 55 | alphaIsTransparency: 1 56 | spriteTessellationDetail: -1 57 | textureType: 8 58 | textureShape: 1 59 | singleChannelComponent: 0 60 | flipbookRows: 1 61 | flipbookColumns: 1 62 | maxTextureSizeSet: 0 63 | compressionQualitySet: 0 64 | textureFormatSet: 0 65 | ignorePngGamma: 0 66 | applyGammaDecoding: 0 67 | swizzle: 50462976 68 | cookieLightType: 0 69 | platformSettings: 70 | - serializedVersion: 3 71 | buildTarget: DefaultTexturePlatform 72 | maxTextureSize: 32 73 | resizeAlgorithm: 0 74 | textureFormat: -1 75 | textureCompression: 1 76 | compressionQuality: 50 77 | crunchedCompression: 0 78 | allowsAlphaSplitting: 0 79 | overridden: 0 80 | androidETC2FallbackOverride: 0 81 | forceMaximumCompressionQuality_BC6H_BC7: 0 82 | - serializedVersion: 3 83 | buildTarget: Standalone 84 | maxTextureSize: 2048 85 | resizeAlgorithm: 0 86 | textureFormat: -1 87 | textureCompression: 1 88 | compressionQuality: 50 89 | crunchedCompression: 0 90 | allowsAlphaSplitting: 0 91 | overridden: 0 92 | androidETC2FallbackOverride: 0 93 | forceMaximumCompressionQuality_BC6H_BC7: 0 94 | - serializedVersion: 3 95 | buildTarget: Server 96 | maxTextureSize: 2048 97 | resizeAlgorithm: 0 98 | textureFormat: -1 99 | textureCompression: 1 100 | compressionQuality: 50 101 | crunchedCompression: 0 102 | allowsAlphaSplitting: 0 103 | overridden: 0 104 | androidETC2FallbackOverride: 0 105 | forceMaximumCompressionQuality_BC6H_BC7: 0 106 | spriteSheet: 107 | serializedVersion: 2 108 | sprites: [] 109 | outline: [] 110 | physicsShape: [] 111 | bones: [] 112 | spriteID: 5e97eb03825dee720800000000000000 113 | internalID: 1537655665 114 | vertices: [] 115 | indices: 116 | edges: [] 117 | weights: [] 118 | secondaryTextures: [] 119 | nameFileIdTable: {} 120 | mipmapLimitGroupName: 121 | pSDRemoveMatte: 0 122 | userData: 123 | assetBundleName: 124 | assetBundleVariant: 125 | -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Finished/Textures/FrameCornerRadius8.Top.Filled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JochenHeckl/DataBinding/6e2e750e61e90dd72b2b80b2b9d397f2c818574c/Samples~/A look at ContainerBindings - Finished/Textures/FrameCornerRadius8.Top.Filled.png -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Finished/Textures/FrameCornerRadius8.Top.Filled.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 42df3ca5268536342927f4e4b2489eba 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 12 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | flipGreenChannel: 0 24 | isReadable: 0 25 | streamingMipmaps: 0 26 | streamingMipmapsPriority: 0 27 | vTOnly: 0 28 | ignoreMipmapLimit: 0 29 | grayScaleToAlpha: 0 30 | generateCubemap: 6 31 | cubemapConvolution: 0 32 | seamlessCubemap: 0 33 | textureFormat: 1 34 | maxTextureSize: 2048 35 | textureSettings: 36 | serializedVersion: 2 37 | filterMode: 0 38 | aniso: 1 39 | mipBias: 0 40 | wrapU: 1 41 | wrapV: 1 42 | wrapW: 0 43 | nPOTScale: 0 44 | lightmap: 0 45 | compressionQuality: 50 46 | spriteMode: 1 47 | spriteExtrude: 1 48 | spriteMeshType: 1 49 | alignment: 0 50 | spritePivot: {x: 0.5, y: 0.5} 51 | spritePixelsToUnits: 100 52 | spriteBorder: {x: 16, y: 4, z: 16, w: 16} 53 | spriteGenerateFallbackPhysicsShape: 1 54 | alphaUsage: 1 55 | alphaIsTransparency: 1 56 | spriteTessellationDetail: -1 57 | textureType: 8 58 | textureShape: 1 59 | singleChannelComponent: 0 60 | flipbookRows: 1 61 | flipbookColumns: 1 62 | maxTextureSizeSet: 0 63 | compressionQualitySet: 0 64 | textureFormatSet: 0 65 | ignorePngGamma: 0 66 | applyGammaDecoding: 0 67 | swizzle: 50462976 68 | cookieLightType: 0 69 | platformSettings: 70 | - serializedVersion: 3 71 | buildTarget: DefaultTexturePlatform 72 | maxTextureSize: 2048 73 | resizeAlgorithm: 0 74 | textureFormat: -1 75 | textureCompression: 1 76 | compressionQuality: 50 77 | crunchedCompression: 0 78 | allowsAlphaSplitting: 0 79 | overridden: 0 80 | androidETC2FallbackOverride: 0 81 | forceMaximumCompressionQuality_BC6H_BC7: 0 82 | - serializedVersion: 3 83 | buildTarget: Standalone 84 | maxTextureSize: 2048 85 | resizeAlgorithm: 0 86 | textureFormat: -1 87 | textureCompression: 1 88 | compressionQuality: 50 89 | crunchedCompression: 0 90 | allowsAlphaSplitting: 0 91 | overridden: 0 92 | androidETC2FallbackOverride: 0 93 | forceMaximumCompressionQuality_BC6H_BC7: 0 94 | - serializedVersion: 3 95 | buildTarget: Server 96 | maxTextureSize: 2048 97 | resizeAlgorithm: 0 98 | textureFormat: -1 99 | textureCompression: 1 100 | compressionQuality: 50 101 | crunchedCompression: 0 102 | allowsAlphaSplitting: 0 103 | overridden: 0 104 | androidETC2FallbackOverride: 0 105 | forceMaximumCompressionQuality_BC6H_BC7: 0 106 | spriteSheet: 107 | serializedVersion: 2 108 | sprites: [] 109 | outline: [] 110 | physicsShape: [] 111 | bones: [] 112 | spriteID: 5e97eb03825dee720800000000000000 113 | internalID: 1537655665 114 | vertices: [] 115 | indices: 116 | edges: [] 117 | weights: [] 118 | secondaryTextures: [] 119 | nameFileIdTable: {} 120 | mipmapLimitGroupName: 121 | pSDRemoveMatte: 0 122 | userData: 123 | assetBundleName: 124 | assetBundleVariant: 125 | -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Finished/Textures/Level.Background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JochenHeckl/DataBinding/6e2e750e61e90dd72b2b80b2b9d397f2c818574c/Samples~/A look at ContainerBindings - Finished/Textures/Level.Background.png -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Finished/Textures/Level.Background.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c09ece7a4a9424447ba47f72efbc9dfd 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 12 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | flipGreenChannel: 0 24 | isReadable: 0 25 | streamingMipmaps: 0 26 | streamingMipmapsPriority: 0 27 | vTOnly: 0 28 | ignoreMipmapLimit: 0 29 | grayScaleToAlpha: 0 30 | generateCubemap: 6 31 | cubemapConvolution: 0 32 | seamlessCubemap: 0 33 | textureFormat: 1 34 | maxTextureSize: 2048 35 | textureSettings: 36 | serializedVersion: 2 37 | filterMode: 1 38 | aniso: 1 39 | mipBias: 0 40 | wrapU: 1 41 | wrapV: 1 42 | wrapW: 0 43 | nPOTScale: 0 44 | lightmap: 0 45 | compressionQuality: 50 46 | spriteMode: 1 47 | spriteExtrude: 1 48 | spriteMeshType: 1 49 | alignment: 0 50 | spritePivot: {x: 0.5, y: 0.5} 51 | spritePixelsToUnits: 100 52 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 53 | spriteGenerateFallbackPhysicsShape: 1 54 | alphaUsage: 1 55 | alphaIsTransparency: 1 56 | spriteTessellationDetail: -1 57 | textureType: 8 58 | textureShape: 1 59 | singleChannelComponent: 0 60 | flipbookRows: 1 61 | flipbookColumns: 1 62 | maxTextureSizeSet: 0 63 | compressionQualitySet: 0 64 | textureFormatSet: 0 65 | ignorePngGamma: 0 66 | applyGammaDecoding: 0 67 | swizzle: 50462976 68 | cookieLightType: 0 69 | platformSettings: 70 | - serializedVersion: 3 71 | buildTarget: DefaultTexturePlatform 72 | maxTextureSize: 2048 73 | resizeAlgorithm: 0 74 | textureFormat: -1 75 | textureCompression: 1 76 | compressionQuality: 50 77 | crunchedCompression: 0 78 | allowsAlphaSplitting: 0 79 | overridden: 0 80 | androidETC2FallbackOverride: 0 81 | forceMaximumCompressionQuality_BC6H_BC7: 0 82 | - serializedVersion: 3 83 | buildTarget: Standalone 84 | maxTextureSize: 2048 85 | resizeAlgorithm: 0 86 | textureFormat: -1 87 | textureCompression: 1 88 | compressionQuality: 50 89 | crunchedCompression: 0 90 | allowsAlphaSplitting: 0 91 | overridden: 0 92 | androidETC2FallbackOverride: 0 93 | forceMaximumCompressionQuality_BC6H_BC7: 0 94 | - serializedVersion: 3 95 | buildTarget: Server 96 | maxTextureSize: 2048 97 | resizeAlgorithm: 0 98 | textureFormat: -1 99 | textureCompression: 1 100 | compressionQuality: 50 101 | crunchedCompression: 0 102 | allowsAlphaSplitting: 0 103 | overridden: 0 104 | androidETC2FallbackOverride: 0 105 | forceMaximumCompressionQuality_BC6H_BC7: 0 106 | spriteSheet: 107 | serializedVersion: 2 108 | sprites: [] 109 | outline: [] 110 | physicsShape: [] 111 | bones: [] 112 | spriteID: 5e97eb03825dee720800000000000000 113 | internalID: 0 114 | vertices: [] 115 | indices: 116 | edges: [] 117 | weights: [] 118 | secondaryTextures: [] 119 | nameFileIdTable: {} 120 | mipmapLimitGroupName: 121 | pSDRemoveMatte: 0 122 | userData: 123 | assetBundleName: 124 | assetBundleVariant: 125 | -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Finished/Textures/Level.Progress.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JochenHeckl/DataBinding/6e2e750e61e90dd72b2b80b2b9d397f2c818574c/Samples~/A look at ContainerBindings - Finished/Textures/Level.Progress.png -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Finished/Textures/Level.Progress.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 724c1261922389e4981c5bff747f37ad 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 12 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | flipGreenChannel: 0 24 | isReadable: 0 25 | streamingMipmaps: 0 26 | streamingMipmapsPriority: 0 27 | vTOnly: 0 28 | ignoreMipmapLimit: 0 29 | grayScaleToAlpha: 0 30 | generateCubemap: 6 31 | cubemapConvolution: 0 32 | seamlessCubemap: 0 33 | textureFormat: 1 34 | maxTextureSize: 2048 35 | textureSettings: 36 | serializedVersion: 2 37 | filterMode: 1 38 | aniso: 1 39 | mipBias: 0 40 | wrapU: 1 41 | wrapV: 1 42 | wrapW: 0 43 | nPOTScale: 0 44 | lightmap: 0 45 | compressionQuality: 50 46 | spriteMode: 1 47 | spriteExtrude: 1 48 | spriteMeshType: 1 49 | alignment: 0 50 | spritePivot: {x: 0.5, y: 0.5} 51 | spritePixelsToUnits: 100 52 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 53 | spriteGenerateFallbackPhysicsShape: 1 54 | alphaUsage: 1 55 | alphaIsTransparency: 1 56 | spriteTessellationDetail: -1 57 | textureType: 8 58 | textureShape: 1 59 | singleChannelComponent: 0 60 | flipbookRows: 1 61 | flipbookColumns: 1 62 | maxTextureSizeSet: 0 63 | compressionQualitySet: 0 64 | textureFormatSet: 0 65 | ignorePngGamma: 0 66 | applyGammaDecoding: 0 67 | swizzle: 50462976 68 | cookieLightType: 0 69 | platformSettings: 70 | - serializedVersion: 3 71 | buildTarget: DefaultTexturePlatform 72 | maxTextureSize: 2048 73 | resizeAlgorithm: 0 74 | textureFormat: -1 75 | textureCompression: 1 76 | compressionQuality: 50 77 | crunchedCompression: 0 78 | allowsAlphaSplitting: 0 79 | overridden: 0 80 | androidETC2FallbackOverride: 0 81 | forceMaximumCompressionQuality_BC6H_BC7: 0 82 | - serializedVersion: 3 83 | buildTarget: Standalone 84 | maxTextureSize: 2048 85 | resizeAlgorithm: 0 86 | textureFormat: -1 87 | textureCompression: 1 88 | compressionQuality: 50 89 | crunchedCompression: 0 90 | allowsAlphaSplitting: 0 91 | overridden: 0 92 | androidETC2FallbackOverride: 0 93 | forceMaximumCompressionQuality_BC6H_BC7: 0 94 | - serializedVersion: 3 95 | buildTarget: Server 96 | maxTextureSize: 2048 97 | resizeAlgorithm: 0 98 | textureFormat: -1 99 | textureCompression: 1 100 | compressionQuality: 50 101 | crunchedCompression: 0 102 | allowsAlphaSplitting: 0 103 | overridden: 0 104 | androidETC2FallbackOverride: 0 105 | forceMaximumCompressionQuality_BC6H_BC7: 0 106 | spriteSheet: 107 | serializedVersion: 2 108 | sprites: [] 109 | outline: [] 110 | physicsShape: [] 111 | bones: [] 112 | spriteID: 5e97eb03825dee720800000000000000 113 | internalID: 0 114 | vertices: [] 115 | indices: 116 | edges: [] 117 | weights: [] 118 | secondaryTextures: [] 119 | nameFileIdTable: {} 120 | mipmapLimitGroupName: 121 | pSDRemoveMatte: 0 122 | userData: 123 | assetBundleName: 124 | assetBundleVariant: 125 | -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Finished/Textures/Pallete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JochenHeckl/DataBinding/6e2e750e61e90dd72b2b80b2b9d397f2c818574c/Samples~/A look at ContainerBindings - Finished/Textures/Pallete.png -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Finished/Textures/Pallete.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8dd2aa6114a1c91448f9a27f703e24ff 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 12 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 1 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | flipGreenChannel: 0 24 | isReadable: 0 25 | streamingMipmaps: 0 26 | streamingMipmapsPriority: 0 27 | vTOnly: 0 28 | ignoreMipmapLimit: 0 29 | grayScaleToAlpha: 0 30 | generateCubemap: 6 31 | cubemapConvolution: 0 32 | seamlessCubemap: 0 33 | textureFormat: 1 34 | maxTextureSize: 2048 35 | textureSettings: 36 | serializedVersion: 2 37 | filterMode: 1 38 | aniso: 1 39 | mipBias: 0 40 | wrapU: 0 41 | wrapV: 0 42 | wrapW: 0 43 | nPOTScale: 1 44 | lightmap: 0 45 | compressionQuality: 50 46 | spriteMode: 0 47 | spriteExtrude: 1 48 | spriteMeshType: 1 49 | alignment: 0 50 | spritePivot: {x: 0.5, y: 0.5} 51 | spritePixelsToUnits: 100 52 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 53 | spriteGenerateFallbackPhysicsShape: 1 54 | alphaUsage: 1 55 | alphaIsTransparency: 0 56 | spriteTessellationDetail: -1 57 | textureType: 0 58 | textureShape: 1 59 | singleChannelComponent: 0 60 | flipbookRows: 1 61 | flipbookColumns: 1 62 | maxTextureSizeSet: 0 63 | compressionQualitySet: 0 64 | textureFormatSet: 0 65 | ignorePngGamma: 0 66 | applyGammaDecoding: 0 67 | swizzle: 50462976 68 | cookieLightType: 0 69 | platformSettings: 70 | - serializedVersion: 3 71 | buildTarget: DefaultTexturePlatform 72 | maxTextureSize: 2048 73 | resizeAlgorithm: 0 74 | textureFormat: -1 75 | textureCompression: 1 76 | compressionQuality: 50 77 | crunchedCompression: 0 78 | allowsAlphaSplitting: 0 79 | overridden: 0 80 | androidETC2FallbackOverride: 0 81 | forceMaximumCompressionQuality_BC6H_BC7: 0 82 | - serializedVersion: 3 83 | buildTarget: Standalone 84 | maxTextureSize: 2048 85 | resizeAlgorithm: 0 86 | textureFormat: -1 87 | textureCompression: 1 88 | compressionQuality: 50 89 | crunchedCompression: 0 90 | allowsAlphaSplitting: 0 91 | overridden: 0 92 | androidETC2FallbackOverride: 0 93 | forceMaximumCompressionQuality_BC6H_BC7: 0 94 | - serializedVersion: 3 95 | buildTarget: Server 96 | maxTextureSize: 2048 97 | resizeAlgorithm: 0 98 | textureFormat: -1 99 | textureCompression: 1 100 | compressionQuality: 50 101 | crunchedCompression: 0 102 | allowsAlphaSplitting: 0 103 | overridden: 0 104 | androidETC2FallbackOverride: 0 105 | forceMaximumCompressionQuality_BC6H_BC7: 0 106 | spriteSheet: 107 | serializedVersion: 2 108 | sprites: [] 109 | outline: [] 110 | physicsShape: [] 111 | bones: [] 112 | spriteID: 113 | internalID: 0 114 | vertices: [] 115 | indices: 116 | edges: [] 117 | weights: [] 118 | secondaryTextures: [] 119 | nameFileIdTable: {} 120 | mipmapLimitGroupName: 121 | pSDRemoveMatte: 0 122 | userData: 123 | assetBundleName: 124 | assetBundleVariant: 125 | -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Tutorial/A look at ContainerBindings.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: dd8d7fa60023ef940b7ce9809dea9e39 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Tutorial/Prefabs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a8469ebd383ca5946b228042bbd71dfd 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Tutorial/Prefabs/Attribute View.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ff6d313dbcd9d084e9f4c9fa71cc6a57 3 | PrefabImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Tutorial/Prefabs/Character View.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 98a1ac3d8286b2e48bbc6612014ff8cb 3 | PrefabImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Tutorial/Prefabs/Party View.prefab: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1 &3139894007772533002 4 | GameObject: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | serializedVersion: 6 10 | m_Component: 11 | - component: {fileID: 3139894007772533003} 12 | - component: {fileID: 3139894007772532996} 13 | m_Layer: 5 14 | m_Name: Party View 15 | m_TagString: Untagged 16 | m_Icon: {fileID: 0} 17 | m_NavMeshLayer: 0 18 | m_StaticEditorFlags: 0 19 | m_IsActive: 1 20 | --- !u!224 &3139894007772533003 21 | RectTransform: 22 | m_ObjectHideFlags: 0 23 | m_CorrespondingSourceObject: {fileID: 0} 24 | m_PrefabInstance: {fileID: 0} 25 | m_PrefabAsset: {fileID: 0} 26 | m_GameObject: {fileID: 3139894007772533002} 27 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 28 | m_LocalPosition: {x: 0, y: 0, z: 0} 29 | m_LocalScale: {x: 1, y: 1, z: 1} 30 | m_ConstrainProportionsScale: 0 31 | m_Children: 32 | - {fileID: 1394055450767064804} 33 | m_Father: {fileID: 0} 34 | m_RootOrder: 0 35 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 36 | m_AnchorMin: {x: 0, y: 0} 37 | m_AnchorMax: {x: 1, y: 1} 38 | m_AnchoredPosition: {x: 0, y: 0} 39 | m_SizeDelta: {x: 0, y: 0} 40 | m_Pivot: {x: 0.5, y: 0.5} 41 | --- !u!114 &3139894007772532996 42 | MonoBehaviour: 43 | m_ObjectHideFlags: 0 44 | m_CorrespondingSourceObject: {fileID: 0} 45 | m_PrefabInstance: {fileID: 0} 46 | m_PrefabAsset: {fileID: 0} 47 | m_GameObject: {fileID: 3139894007772533002} 48 | m_Enabled: 1 49 | m_EditorHideFlags: 0 50 | m_Script: {fileID: 11500000, guid: 86b5f087a6158b7409c18f4ecd50007e, type: 3} 51 | m_Name: 52 | m_EditorClassIdentifier: 53 | dataSourceType: 54 | assemblyQualifiedName: de.JochenHeckl.Unity.DataBinding.Examples.ContainerBindings.PartyViewModel, 55 | Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null 56 | componentPropertyBindings: [] 57 | containerPropertyBindings: [] 58 | --- !u!1 &3183226223414695614 59 | GameObject: 60 | m_ObjectHideFlags: 0 61 | m_CorrespondingSourceObject: {fileID: 0} 62 | m_PrefabInstance: {fileID: 0} 63 | m_PrefabAsset: {fileID: 0} 64 | serializedVersion: 6 65 | m_Component: 66 | - component: {fileID: 1394055450767064804} 67 | - component: {fileID: 2085375641424296701} 68 | m_Layer: 5 69 | m_Name: Characters 70 | m_TagString: Untagged 71 | m_Icon: {fileID: 0} 72 | m_NavMeshLayer: 0 73 | m_StaticEditorFlags: 0 74 | m_IsActive: 1 75 | --- !u!224 &1394055450767064804 76 | RectTransform: 77 | m_ObjectHideFlags: 0 78 | m_CorrespondingSourceObject: {fileID: 0} 79 | m_PrefabInstance: {fileID: 0} 80 | m_PrefabAsset: {fileID: 0} 81 | m_GameObject: {fileID: 3183226223414695614} 82 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 83 | m_LocalPosition: {x: 0, y: 0, z: 0} 84 | m_LocalScale: {x: 1, y: 1, z: 1} 85 | m_ConstrainProportionsScale: 0 86 | m_Children: [] 87 | m_Father: {fileID: 3139894007772533003} 88 | m_RootOrder: -1 89 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 90 | m_AnchorMin: {x: 0, y: 0} 91 | m_AnchorMax: {x: 1, y: 1} 92 | m_AnchoredPosition: {x: 0, y: 0} 93 | m_SizeDelta: {x: 0, y: 0} 94 | m_Pivot: {x: 0.5, y: 0.5} 95 | --- !u!114 &2085375641424296701 96 | MonoBehaviour: 97 | m_ObjectHideFlags: 0 98 | m_CorrespondingSourceObject: {fileID: 0} 99 | m_PrefabInstance: {fileID: 0} 100 | m_PrefabAsset: {fileID: 0} 101 | m_GameObject: {fileID: 3183226223414695614} 102 | m_Enabled: 1 103 | m_EditorHideFlags: 0 104 | m_Script: {fileID: 11500000, guid: 8a8695521f0d02e499659fee002a26c2, type: 3} 105 | m_Name: 106 | m_EditorClassIdentifier: 107 | m_Padding: 108 | m_Left: 0 109 | m_Right: 0 110 | m_Top: 0 111 | m_Bottom: 0 112 | m_ChildAlignment: 4 113 | m_StartCorner: 0 114 | m_StartAxis: 0 115 | m_CellSize: {x: 372, y: 224} 116 | m_Spacing: {x: 4, y: 4} 117 | m_Constraint: 1 118 | m_ConstraintCount: 2 119 | -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Tutorial/Prefabs/Party View.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9d8409970404f6c4bb68a9f695e6e2dd 3 | PrefabImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Tutorial/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8a00cf5432697c94c8b4c7840194b61e 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Tutorial/Scripts/AttributeViewModel.cs: -------------------------------------------------------------------------------- 1 | namespace JH.DataBinding.Examples.ContainerBindings.Tutorial 2 | { 3 | public class AttributeViewModel : DataSourceBase 4 | { 5 | public string Name { get; set; } 6 | public int Value { get; set; } 7 | public string ValueString => $"{Value}"; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Tutorial/Scripts/AttributeViewModel.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0714ad331f413494796f9f1e09e64375 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Tutorial/Scripts/Bootstrap.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using UnityEngine; 3 | using Random = UnityEngine.Random; 4 | 5 | namespace JH.DataBinding.Examples.ContainerBindings.Tutorial 6 | { 7 | public class Bootstrap : MonoBehaviour 8 | { 9 | public View partyViewTemplate; 10 | public Transform partyViewContainer; 11 | 12 | public Sprite theOneAndOnlyCharacterImage; 13 | 14 | private View partyView; 15 | 16 | void Start() 17 | { 18 | var partyViewModel = new PartyViewModel() 19 | { 20 | Characters = Enumerable.Range(1, 4).Select(x => MakeCharacterData(x)).ToArray() 21 | }; 22 | 23 | partyView = GameObject.Instantiate(partyViewTemplate, partyViewContainer); 24 | partyView.DataSource = partyViewModel; 25 | } 26 | 27 | private CharacterViewModel MakeCharacterData(int characterCreationIndex) 28 | { 29 | var charcterClasses = new string[] { "Mage", "Priest", "Rogue", "Warrior", }; 30 | 31 | var characterLevel = Random.Range(1, 10); 32 | 33 | return new CharacterViewModel() 34 | { 35 | Name = $"Character 0{characterCreationIndex}", 36 | Class = charcterClasses.ElementAt(Random.Range(0, 3)), 37 | Level = characterLevel, 38 | LevelProgress = Random.Range(0f, 1f), 39 | Attributes = MakeAttributes(characterLevel), 40 | CharacterImage = theOneAndOnlyCharacterImage 41 | }; 42 | } 43 | 44 | private AttributeViewModel[] MakeAttributes(int characterLevel) 45 | { 46 | var attributes = new string[] 47 | { 48 | "Agility", 49 | "Intelligence", 50 | "Resistence", 51 | "Sorcery", 52 | "Strength", 53 | "Will", 54 | }; 55 | 56 | return attributes 57 | .Select( 58 | x => 59 | new AttributeViewModel() 60 | { 61 | Name = x, 62 | Value = Random.Range(1, 6 + characterLevel / 6) 63 | } 64 | ) 65 | .ToArray(); 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Tutorial/Scripts/Bootstrap.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7f74b4feb17c13045aa3f29ecb32b1d2 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Tutorial/Scripts/CharacterViewModel.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace JH.DataBinding.Examples.ContainerBindings.Tutorial 4 | { 5 | public class CharacterViewModel : DataSourceBase 6 | { 7 | public string Name { get; set; } 8 | public string Class { get; set; } 9 | 10 | public int Level { get; set; } 11 | public string LevelString => $"{Level}"; 12 | public float LevelProgress { get; internal set; } 13 | 14 | public AttributeViewModel[] Attributes { get; set; } 15 | public Sprite CharacterImage { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Tutorial/Scripts/CharacterViewModel.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b90edad79aed1a7478eecd8c5882d174 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Tutorial/Scripts/PartyViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace JH.DataBinding.Examples.ContainerBindings.Tutorial 4 | { 5 | public class PartyViewModel : DataSourceBase 6 | { 7 | public IEnumerable Characters { get; set; } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Tutorial/Scripts/PartyViewModel.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7b646498b8f3a154e9525cd581845bae 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Tutorial/Textures.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8b2efd32a83be6841920d98747032867 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Tutorial/Textures/Attribute.Background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JochenHeckl/DataBinding/6e2e750e61e90dd72b2b80b2b9d397f2c818574c/Samples~/A look at ContainerBindings - Tutorial/Textures/Attribute.Background.png -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Tutorial/Textures/Attribute.Background.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c94fd5fe15b4c7347bbdf240508f6200 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 12 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | flipGreenChannel: 0 24 | isReadable: 0 25 | streamingMipmaps: 0 26 | streamingMipmapsPriority: 0 27 | vTOnly: 0 28 | ignoreMipmapLimit: 0 29 | grayScaleToAlpha: 0 30 | generateCubemap: 6 31 | cubemapConvolution: 0 32 | seamlessCubemap: 0 33 | textureFormat: 1 34 | maxTextureSize: 2048 35 | textureSettings: 36 | serializedVersion: 2 37 | filterMode: 1 38 | aniso: 1 39 | mipBias: 0 40 | wrapU: 1 41 | wrapV: 1 42 | wrapW: 0 43 | nPOTScale: 0 44 | lightmap: 0 45 | compressionQuality: 50 46 | spriteMode: 1 47 | spriteExtrude: 1 48 | spriteMeshType: 1 49 | alignment: 0 50 | spritePivot: {x: 0.5, y: 0.5} 51 | spritePixelsToUnits: 100 52 | spriteBorder: {x: 16, y: 16, z: 16, w: 32} 53 | spriteGenerateFallbackPhysicsShape: 1 54 | alphaUsage: 1 55 | alphaIsTransparency: 1 56 | spriteTessellationDetail: -1 57 | textureType: 8 58 | textureShape: 1 59 | singleChannelComponent: 0 60 | flipbookRows: 1 61 | flipbookColumns: 1 62 | maxTextureSizeSet: 0 63 | compressionQualitySet: 0 64 | textureFormatSet: 0 65 | ignorePngGamma: 0 66 | applyGammaDecoding: 0 67 | swizzle: 50462976 68 | cookieLightType: 0 69 | platformSettings: 70 | - serializedVersion: 3 71 | buildTarget: DefaultTexturePlatform 72 | maxTextureSize: 64 73 | resizeAlgorithm: 0 74 | textureFormat: -1 75 | textureCompression: 1 76 | compressionQuality: 50 77 | crunchedCompression: 0 78 | allowsAlphaSplitting: 0 79 | overridden: 0 80 | androidETC2FallbackOverride: 0 81 | forceMaximumCompressionQuality_BC6H_BC7: 0 82 | - serializedVersion: 3 83 | buildTarget: Standalone 84 | maxTextureSize: 2048 85 | resizeAlgorithm: 0 86 | textureFormat: -1 87 | textureCompression: 1 88 | compressionQuality: 50 89 | crunchedCompression: 0 90 | allowsAlphaSplitting: 0 91 | overridden: 0 92 | androidETC2FallbackOverride: 0 93 | forceMaximumCompressionQuality_BC6H_BC7: 0 94 | - serializedVersion: 3 95 | buildTarget: Server 96 | maxTextureSize: 2048 97 | resizeAlgorithm: 0 98 | textureFormat: -1 99 | textureCompression: 1 100 | compressionQuality: 50 101 | crunchedCompression: 0 102 | allowsAlphaSplitting: 0 103 | overridden: 0 104 | androidETC2FallbackOverride: 0 105 | forceMaximumCompressionQuality_BC6H_BC7: 0 106 | spriteSheet: 107 | serializedVersion: 2 108 | sprites: [] 109 | outline: [] 110 | physicsShape: [] 111 | bones: [] 112 | spriteID: 5e97eb03825dee720800000000000000 113 | internalID: 1537655665 114 | vertices: [] 115 | indices: 116 | edges: [] 117 | weights: [] 118 | secondaryTextures: [] 119 | nameFileIdTable: {} 120 | mipmapLimitGroupName: 121 | pSDRemoveMatte: 0 122 | userData: 123 | assetBundleName: 124 | assetBundleVariant: 125 | -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Tutorial/Textures/CharacterImage.01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JochenHeckl/DataBinding/6e2e750e61e90dd72b2b80b2b9d397f2c818574c/Samples~/A look at ContainerBindings - Tutorial/Textures/CharacterImage.01.png -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Tutorial/Textures/CharacterImage.01.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d815245f502e2d340889ca1b93a95a99 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 12 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | flipGreenChannel: 0 24 | isReadable: 0 25 | streamingMipmaps: 0 26 | streamingMipmapsPriority: 0 27 | vTOnly: 0 28 | ignoreMipmapLimit: 0 29 | grayScaleToAlpha: 0 30 | generateCubemap: 6 31 | cubemapConvolution: 0 32 | seamlessCubemap: 0 33 | textureFormat: 1 34 | maxTextureSize: 2048 35 | textureSettings: 36 | serializedVersion: 2 37 | filterMode: 1 38 | aniso: 1 39 | mipBias: 0 40 | wrapU: 1 41 | wrapV: 1 42 | wrapW: 0 43 | nPOTScale: 0 44 | lightmap: 0 45 | compressionQuality: 50 46 | spriteMode: 1 47 | spriteExtrude: 1 48 | spriteMeshType: 1 49 | alignment: 0 50 | spritePivot: {x: 0.5, y: 0.5} 51 | spritePixelsToUnits: 100 52 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 53 | spriteGenerateFallbackPhysicsShape: 1 54 | alphaUsage: 1 55 | alphaIsTransparency: 1 56 | spriteTessellationDetail: -1 57 | textureType: 8 58 | textureShape: 1 59 | singleChannelComponent: 0 60 | flipbookRows: 1 61 | flipbookColumns: 1 62 | maxTextureSizeSet: 0 63 | compressionQualitySet: 0 64 | textureFormatSet: 0 65 | ignorePngGamma: 0 66 | applyGammaDecoding: 0 67 | swizzle: 50462976 68 | cookieLightType: 0 69 | platformSettings: 70 | - serializedVersion: 3 71 | buildTarget: DefaultTexturePlatform 72 | maxTextureSize: 1024 73 | resizeAlgorithm: 0 74 | textureFormat: -1 75 | textureCompression: 1 76 | compressionQuality: 50 77 | crunchedCompression: 0 78 | allowsAlphaSplitting: 0 79 | overridden: 0 80 | androidETC2FallbackOverride: 0 81 | forceMaximumCompressionQuality_BC6H_BC7: 0 82 | - serializedVersion: 3 83 | buildTarget: Standalone 84 | maxTextureSize: 2048 85 | resizeAlgorithm: 0 86 | textureFormat: -1 87 | textureCompression: 1 88 | compressionQuality: 50 89 | crunchedCompression: 0 90 | allowsAlphaSplitting: 0 91 | overridden: 0 92 | androidETC2FallbackOverride: 0 93 | forceMaximumCompressionQuality_BC6H_BC7: 0 94 | - serializedVersion: 3 95 | buildTarget: Server 96 | maxTextureSize: 2048 97 | resizeAlgorithm: 0 98 | textureFormat: -1 99 | textureCompression: 1 100 | compressionQuality: 50 101 | crunchedCompression: 0 102 | allowsAlphaSplitting: 0 103 | overridden: 0 104 | androidETC2FallbackOverride: 0 105 | forceMaximumCompressionQuality_BC6H_BC7: 0 106 | spriteSheet: 107 | serializedVersion: 2 108 | sprites: [] 109 | outline: [] 110 | physicsShape: [] 111 | bones: [] 112 | spriteID: 5e97eb03825dee720800000000000000 113 | internalID: 0 114 | vertices: [] 115 | indices: 116 | edges: [] 117 | weights: [] 118 | secondaryTextures: [] 119 | nameFileIdTable: {} 120 | mipmapLimitGroupName: 121 | pSDRemoveMatte: 0 122 | userData: 123 | assetBundleName: 124 | assetBundleVariant: 125 | -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Tutorial/Textures/Frame.1px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JochenHeckl/DataBinding/6e2e750e61e90dd72b2b80b2b9d397f2c818574c/Samples~/A look at ContainerBindings - Tutorial/Textures/Frame.1px.png -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Tutorial/Textures/Frame.1px.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1e0aca931e5c5764a8bd2c170dd83f61 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 12 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | flipGreenChannel: 0 24 | isReadable: 0 25 | streamingMipmaps: 0 26 | streamingMipmapsPriority: 0 27 | vTOnly: 0 28 | ignoreMipmapLimit: 0 29 | grayScaleToAlpha: 0 30 | generateCubemap: 6 31 | cubemapConvolution: 0 32 | seamlessCubemap: 0 33 | textureFormat: 1 34 | maxTextureSize: 2048 35 | textureSettings: 36 | serializedVersion: 2 37 | filterMode: 0 38 | aniso: 1 39 | mipBias: 0 40 | wrapU: 1 41 | wrapV: 1 42 | wrapW: 0 43 | nPOTScale: 0 44 | lightmap: 0 45 | compressionQuality: 50 46 | spriteMode: 1 47 | spriteExtrude: 1 48 | spriteMeshType: 1 49 | alignment: 0 50 | spritePivot: {x: 0.5, y: 0.5} 51 | spritePixelsToUnits: 100 52 | spriteBorder: {x: 2, y: 2, z: 2, w: 2} 53 | spriteGenerateFallbackPhysicsShape: 1 54 | alphaUsage: 1 55 | alphaIsTransparency: 1 56 | spriteTessellationDetail: -1 57 | textureType: 8 58 | textureShape: 1 59 | singleChannelComponent: 0 60 | flipbookRows: 1 61 | flipbookColumns: 1 62 | maxTextureSizeSet: 0 63 | compressionQualitySet: 0 64 | textureFormatSet: 0 65 | ignorePngGamma: 0 66 | applyGammaDecoding: 0 67 | swizzle: 50462976 68 | cookieLightType: 0 69 | platformSettings: 70 | - serializedVersion: 3 71 | buildTarget: DefaultTexturePlatform 72 | maxTextureSize: 32 73 | resizeAlgorithm: 0 74 | textureFormat: -1 75 | textureCompression: 1 76 | compressionQuality: 50 77 | crunchedCompression: 0 78 | allowsAlphaSplitting: 0 79 | overridden: 0 80 | androidETC2FallbackOverride: 0 81 | forceMaximumCompressionQuality_BC6H_BC7: 0 82 | - serializedVersion: 3 83 | buildTarget: Standalone 84 | maxTextureSize: 2048 85 | resizeAlgorithm: 0 86 | textureFormat: -1 87 | textureCompression: 1 88 | compressionQuality: 50 89 | crunchedCompression: 0 90 | allowsAlphaSplitting: 0 91 | overridden: 0 92 | androidETC2FallbackOverride: 0 93 | forceMaximumCompressionQuality_BC6H_BC7: 0 94 | - serializedVersion: 3 95 | buildTarget: Server 96 | maxTextureSize: 2048 97 | resizeAlgorithm: 0 98 | textureFormat: -1 99 | textureCompression: 1 100 | compressionQuality: 50 101 | crunchedCompression: 0 102 | allowsAlphaSplitting: 0 103 | overridden: 0 104 | androidETC2FallbackOverride: 0 105 | forceMaximumCompressionQuality_BC6H_BC7: 0 106 | spriteSheet: 107 | serializedVersion: 2 108 | sprites: [] 109 | outline: [] 110 | physicsShape: [] 111 | bones: [] 112 | spriteID: 5e97eb03825dee720800000000000000 113 | internalID: 1537655665 114 | vertices: [] 115 | indices: 116 | edges: [] 117 | weights: [] 118 | secondaryTextures: [] 119 | nameFileIdTable: {} 120 | mipmapLimitGroupName: 121 | pSDRemoveMatte: 0 122 | userData: 123 | assetBundleName: 124 | assetBundleVariant: 125 | -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Tutorial/Textures/FrameCornerRadius8.Top.Filled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JochenHeckl/DataBinding/6e2e750e61e90dd72b2b80b2b9d397f2c818574c/Samples~/A look at ContainerBindings - Tutorial/Textures/FrameCornerRadius8.Top.Filled.png -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Tutorial/Textures/FrameCornerRadius8.Top.Filled.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6ff6591213b50964ba24cf2e737d88e7 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 12 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | flipGreenChannel: 0 24 | isReadable: 0 25 | streamingMipmaps: 0 26 | streamingMipmapsPriority: 0 27 | vTOnly: 0 28 | ignoreMipmapLimit: 0 29 | grayScaleToAlpha: 0 30 | generateCubemap: 6 31 | cubemapConvolution: 0 32 | seamlessCubemap: 0 33 | textureFormat: 1 34 | maxTextureSize: 2048 35 | textureSettings: 36 | serializedVersion: 2 37 | filterMode: 0 38 | aniso: 1 39 | mipBias: 0 40 | wrapU: 1 41 | wrapV: 1 42 | wrapW: 0 43 | nPOTScale: 0 44 | lightmap: 0 45 | compressionQuality: 50 46 | spriteMode: 1 47 | spriteExtrude: 1 48 | spriteMeshType: 1 49 | alignment: 0 50 | spritePivot: {x: 0.5, y: 0.5} 51 | spritePixelsToUnits: 100 52 | spriteBorder: {x: 16, y: 4, z: 16, w: 16} 53 | spriteGenerateFallbackPhysicsShape: 1 54 | alphaUsage: 1 55 | alphaIsTransparency: 1 56 | spriteTessellationDetail: -1 57 | textureType: 8 58 | textureShape: 1 59 | singleChannelComponent: 0 60 | flipbookRows: 1 61 | flipbookColumns: 1 62 | maxTextureSizeSet: 0 63 | compressionQualitySet: 0 64 | textureFormatSet: 0 65 | ignorePngGamma: 0 66 | applyGammaDecoding: 0 67 | swizzle: 50462976 68 | cookieLightType: 0 69 | platformSettings: 70 | - serializedVersion: 3 71 | buildTarget: DefaultTexturePlatform 72 | maxTextureSize: 2048 73 | resizeAlgorithm: 0 74 | textureFormat: -1 75 | textureCompression: 1 76 | compressionQuality: 50 77 | crunchedCompression: 0 78 | allowsAlphaSplitting: 0 79 | overridden: 0 80 | androidETC2FallbackOverride: 0 81 | forceMaximumCompressionQuality_BC6H_BC7: 0 82 | - serializedVersion: 3 83 | buildTarget: Standalone 84 | maxTextureSize: 2048 85 | resizeAlgorithm: 0 86 | textureFormat: -1 87 | textureCompression: 1 88 | compressionQuality: 50 89 | crunchedCompression: 0 90 | allowsAlphaSplitting: 0 91 | overridden: 0 92 | androidETC2FallbackOverride: 0 93 | forceMaximumCompressionQuality_BC6H_BC7: 0 94 | - serializedVersion: 3 95 | buildTarget: Server 96 | maxTextureSize: 2048 97 | resizeAlgorithm: 0 98 | textureFormat: -1 99 | textureCompression: 1 100 | compressionQuality: 50 101 | crunchedCompression: 0 102 | allowsAlphaSplitting: 0 103 | overridden: 0 104 | androidETC2FallbackOverride: 0 105 | forceMaximumCompressionQuality_BC6H_BC7: 0 106 | spriteSheet: 107 | serializedVersion: 2 108 | sprites: [] 109 | outline: [] 110 | physicsShape: [] 111 | bones: [] 112 | spriteID: 5e97eb03825dee720800000000000000 113 | internalID: 1537655665 114 | vertices: [] 115 | indices: 116 | edges: [] 117 | weights: [] 118 | secondaryTextures: [] 119 | nameFileIdTable: {} 120 | mipmapLimitGroupName: 121 | pSDRemoveMatte: 0 122 | userData: 123 | assetBundleName: 124 | assetBundleVariant: 125 | -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Tutorial/Textures/Level.Background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JochenHeckl/DataBinding/6e2e750e61e90dd72b2b80b2b9d397f2c818574c/Samples~/A look at ContainerBindings - Tutorial/Textures/Level.Background.png -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Tutorial/Textures/Level.Background.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 250de0c48c897f148ab0bff763a29d2f 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 12 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | flipGreenChannel: 0 24 | isReadable: 0 25 | streamingMipmaps: 0 26 | streamingMipmapsPriority: 0 27 | vTOnly: 0 28 | ignoreMipmapLimit: 0 29 | grayScaleToAlpha: 0 30 | generateCubemap: 6 31 | cubemapConvolution: 0 32 | seamlessCubemap: 0 33 | textureFormat: 1 34 | maxTextureSize: 2048 35 | textureSettings: 36 | serializedVersion: 2 37 | filterMode: 1 38 | aniso: 1 39 | mipBias: 0 40 | wrapU: 1 41 | wrapV: 1 42 | wrapW: 0 43 | nPOTScale: 0 44 | lightmap: 0 45 | compressionQuality: 50 46 | spriteMode: 1 47 | spriteExtrude: 1 48 | spriteMeshType: 1 49 | alignment: 0 50 | spritePivot: {x: 0.5, y: 0.5} 51 | spritePixelsToUnits: 100 52 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 53 | spriteGenerateFallbackPhysicsShape: 1 54 | alphaUsage: 1 55 | alphaIsTransparency: 1 56 | spriteTessellationDetail: -1 57 | textureType: 8 58 | textureShape: 1 59 | singleChannelComponent: 0 60 | flipbookRows: 1 61 | flipbookColumns: 1 62 | maxTextureSizeSet: 0 63 | compressionQualitySet: 0 64 | textureFormatSet: 0 65 | ignorePngGamma: 0 66 | applyGammaDecoding: 0 67 | swizzle: 50462976 68 | cookieLightType: 0 69 | platformSettings: 70 | - serializedVersion: 3 71 | buildTarget: DefaultTexturePlatform 72 | maxTextureSize: 2048 73 | resizeAlgorithm: 0 74 | textureFormat: -1 75 | textureCompression: 1 76 | compressionQuality: 50 77 | crunchedCompression: 0 78 | allowsAlphaSplitting: 0 79 | overridden: 0 80 | androidETC2FallbackOverride: 0 81 | forceMaximumCompressionQuality_BC6H_BC7: 0 82 | - serializedVersion: 3 83 | buildTarget: Standalone 84 | maxTextureSize: 2048 85 | resizeAlgorithm: 0 86 | textureFormat: -1 87 | textureCompression: 1 88 | compressionQuality: 50 89 | crunchedCompression: 0 90 | allowsAlphaSplitting: 0 91 | overridden: 0 92 | androidETC2FallbackOverride: 0 93 | forceMaximumCompressionQuality_BC6H_BC7: 0 94 | - serializedVersion: 3 95 | buildTarget: Server 96 | maxTextureSize: 2048 97 | resizeAlgorithm: 0 98 | textureFormat: -1 99 | textureCompression: 1 100 | compressionQuality: 50 101 | crunchedCompression: 0 102 | allowsAlphaSplitting: 0 103 | overridden: 0 104 | androidETC2FallbackOverride: 0 105 | forceMaximumCompressionQuality_BC6H_BC7: 0 106 | spriteSheet: 107 | serializedVersion: 2 108 | sprites: [] 109 | outline: [] 110 | physicsShape: [] 111 | bones: [] 112 | spriteID: 5e97eb03825dee720800000000000000 113 | internalID: 0 114 | vertices: [] 115 | indices: 116 | edges: [] 117 | weights: [] 118 | secondaryTextures: [] 119 | nameFileIdTable: {} 120 | mipmapLimitGroupName: 121 | pSDRemoveMatte: 0 122 | userData: 123 | assetBundleName: 124 | assetBundleVariant: 125 | -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Tutorial/Textures/Level.Progress.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JochenHeckl/DataBinding/6e2e750e61e90dd72b2b80b2b9d397f2c818574c/Samples~/A look at ContainerBindings - Tutorial/Textures/Level.Progress.png -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Tutorial/Textures/Level.Progress.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d7ede02237241a943ad9a02a1ef31c2e 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 12 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | flipGreenChannel: 0 24 | isReadable: 0 25 | streamingMipmaps: 0 26 | streamingMipmapsPriority: 0 27 | vTOnly: 0 28 | ignoreMipmapLimit: 0 29 | grayScaleToAlpha: 0 30 | generateCubemap: 6 31 | cubemapConvolution: 0 32 | seamlessCubemap: 0 33 | textureFormat: 1 34 | maxTextureSize: 2048 35 | textureSettings: 36 | serializedVersion: 2 37 | filterMode: 1 38 | aniso: 1 39 | mipBias: 0 40 | wrapU: 1 41 | wrapV: 1 42 | wrapW: 0 43 | nPOTScale: 0 44 | lightmap: 0 45 | compressionQuality: 50 46 | spriteMode: 1 47 | spriteExtrude: 1 48 | spriteMeshType: 1 49 | alignment: 0 50 | spritePivot: {x: 0.5, y: 0.5} 51 | spritePixelsToUnits: 100 52 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 53 | spriteGenerateFallbackPhysicsShape: 1 54 | alphaUsage: 1 55 | alphaIsTransparency: 1 56 | spriteTessellationDetail: -1 57 | textureType: 8 58 | textureShape: 1 59 | singleChannelComponent: 0 60 | flipbookRows: 1 61 | flipbookColumns: 1 62 | maxTextureSizeSet: 0 63 | compressionQualitySet: 0 64 | textureFormatSet: 0 65 | ignorePngGamma: 0 66 | applyGammaDecoding: 0 67 | swizzle: 50462976 68 | cookieLightType: 0 69 | platformSettings: 70 | - serializedVersion: 3 71 | buildTarget: DefaultTexturePlatform 72 | maxTextureSize: 2048 73 | resizeAlgorithm: 0 74 | textureFormat: -1 75 | textureCompression: 1 76 | compressionQuality: 50 77 | crunchedCompression: 0 78 | allowsAlphaSplitting: 0 79 | overridden: 0 80 | androidETC2FallbackOverride: 0 81 | forceMaximumCompressionQuality_BC6H_BC7: 0 82 | - serializedVersion: 3 83 | buildTarget: Standalone 84 | maxTextureSize: 2048 85 | resizeAlgorithm: 0 86 | textureFormat: -1 87 | textureCompression: 1 88 | compressionQuality: 50 89 | crunchedCompression: 0 90 | allowsAlphaSplitting: 0 91 | overridden: 0 92 | androidETC2FallbackOverride: 0 93 | forceMaximumCompressionQuality_BC6H_BC7: 0 94 | - serializedVersion: 3 95 | buildTarget: Server 96 | maxTextureSize: 2048 97 | resizeAlgorithm: 0 98 | textureFormat: -1 99 | textureCompression: 1 100 | compressionQuality: 50 101 | crunchedCompression: 0 102 | allowsAlphaSplitting: 0 103 | overridden: 0 104 | androidETC2FallbackOverride: 0 105 | forceMaximumCompressionQuality_BC6H_BC7: 0 106 | spriteSheet: 107 | serializedVersion: 2 108 | sprites: [] 109 | outline: [] 110 | physicsShape: [] 111 | bones: [] 112 | spriteID: 5e97eb03825dee720800000000000000 113 | internalID: 0 114 | vertices: [] 115 | indices: 116 | edges: [] 117 | weights: [] 118 | secondaryTextures: [] 119 | nameFileIdTable: {} 120 | mipmapLimitGroupName: 121 | pSDRemoveMatte: 0 122 | userData: 123 | assetBundleName: 124 | assetBundleVariant: 125 | -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Tutorial/Textures/Pallete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JochenHeckl/DataBinding/6e2e750e61e90dd72b2b80b2b9d397f2c818574c/Samples~/A look at ContainerBindings - Tutorial/Textures/Pallete.png -------------------------------------------------------------------------------- /Samples~/A look at ContainerBindings - Tutorial/Textures/Pallete.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c0f44c14cc31518478d73909612e9ab4 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 12 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 1 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | flipGreenChannel: 0 24 | isReadable: 0 25 | streamingMipmaps: 0 26 | streamingMipmapsPriority: 0 27 | vTOnly: 0 28 | ignoreMipmapLimit: 0 29 | grayScaleToAlpha: 0 30 | generateCubemap: 6 31 | cubemapConvolution: 0 32 | seamlessCubemap: 0 33 | textureFormat: 1 34 | maxTextureSize: 2048 35 | textureSettings: 36 | serializedVersion: 2 37 | filterMode: 1 38 | aniso: 1 39 | mipBias: 0 40 | wrapU: 0 41 | wrapV: 0 42 | wrapW: 0 43 | nPOTScale: 1 44 | lightmap: 0 45 | compressionQuality: 50 46 | spriteMode: 0 47 | spriteExtrude: 1 48 | spriteMeshType: 1 49 | alignment: 0 50 | spritePivot: {x: 0.5, y: 0.5} 51 | spritePixelsToUnits: 100 52 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 53 | spriteGenerateFallbackPhysicsShape: 1 54 | alphaUsage: 1 55 | alphaIsTransparency: 0 56 | spriteTessellationDetail: -1 57 | textureType: 0 58 | textureShape: 1 59 | singleChannelComponent: 0 60 | flipbookRows: 1 61 | flipbookColumns: 1 62 | maxTextureSizeSet: 0 63 | compressionQualitySet: 0 64 | textureFormatSet: 0 65 | ignorePngGamma: 0 66 | applyGammaDecoding: 0 67 | swizzle: 50462976 68 | cookieLightType: 0 69 | platformSettings: 70 | - serializedVersion: 3 71 | buildTarget: DefaultTexturePlatform 72 | maxTextureSize: 2048 73 | resizeAlgorithm: 0 74 | textureFormat: -1 75 | textureCompression: 1 76 | compressionQuality: 50 77 | crunchedCompression: 0 78 | allowsAlphaSplitting: 0 79 | overridden: 0 80 | androidETC2FallbackOverride: 0 81 | forceMaximumCompressionQuality_BC6H_BC7: 0 82 | - serializedVersion: 3 83 | buildTarget: Standalone 84 | maxTextureSize: 2048 85 | resizeAlgorithm: 0 86 | textureFormat: -1 87 | textureCompression: 1 88 | compressionQuality: 50 89 | crunchedCompression: 0 90 | allowsAlphaSplitting: 0 91 | overridden: 0 92 | androidETC2FallbackOverride: 0 93 | forceMaximumCompressionQuality_BC6H_BC7: 0 94 | - serializedVersion: 3 95 | buildTarget: Server 96 | maxTextureSize: 2048 97 | resizeAlgorithm: 0 98 | textureFormat: -1 99 | textureCompression: 1 100 | compressionQuality: 50 101 | crunchedCompression: 0 102 | allowsAlphaSplitting: 0 103 | overridden: 0 104 | androidETC2FallbackOverride: 0 105 | forceMaximumCompressionQuality_BC6H_BC7: 0 106 | spriteSheet: 107 | serializedVersion: 2 108 | sprites: [] 109 | outline: [] 110 | physicsShape: [] 111 | bones: [] 112 | spriteID: 113 | internalID: 0 114 | vertices: [] 115 | indices: 116 | edges: [] 117 | weights: [] 118 | secondaryTextures: [] 119 | nameFileIdTable: {} 120 | mipmapLimitGroupName: 121 | pSDRemoveMatte: 0 122 | userData: 123 | assetBundleName: 124 | assetBundleVariant: 125 | -------------------------------------------------------------------------------- /Samples~/EditableDropdown/EditableDropdown.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b5c89b3d09e41d1458247e1acc52aca3 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Samples~/EditableDropdown/Prefabs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5d241afdffd552d4a9bec19133931f0d 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/EditableDropdown/Prefabs/EditableDropdown.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e6f6b7f2262989049ac33b2eb6cb6576 3 | PrefabImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Samples~/EditableDropdown/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: df1ed7babb04c3a41b9878f5c00a6620 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/EditableDropdown/Scripts/EditableDropdown.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using TMPro; 4 | using Unity.Logging; 5 | using UnityEngine; 6 | using UnityEngine.Events; 7 | 8 | namespace JH.DataBinding.Example.EditableDropdown 9 | { 10 | public class EditableDropdown : MonoBehaviour 11 | { 12 | public TMP_Dropdown dropdown; 13 | public TMP_InputField inputField; 14 | public Action ValueChanged 15 | { 16 | set { inputField.onValueChanged.AddListener(new UnityAction(value)); } 17 | } 18 | 19 | public string Value 20 | { 21 | set 22 | { 23 | Log.Debug("New Value: {Value}", value); 24 | 25 | if (inputField.text != value) 26 | { 27 | inputField.text = value; 28 | } 29 | 30 | var matchingIndex = dropdown.options.FindIndex((x) => x.text == value); 31 | 32 | if (dropdown.value != matchingIndex) 33 | { 34 | Log.Debug( 35 | "Updating dropdown value from {OldValue} to {NewValue}.", 36 | dropdown.value, 37 | matchingIndex 38 | ); 39 | 40 | dropdown.SetValueWithoutNotify(matchingIndex); 41 | } 42 | } 43 | } 44 | 45 | public string[] Options 46 | { 47 | get { return dropdown.options.Select(x => x.text).ToArray(); } 48 | set 49 | { 50 | if (value != null) 51 | { 52 | dropdown.options = value.Select(x => new TMP_Dropdown.OptionData(x)).ToList(); 53 | } 54 | else 55 | { 56 | dropdown.options.Clear(); 57 | } 58 | } 59 | } 60 | 61 | private Action valueChangedHandler; 62 | 63 | protected void Awake() 64 | { 65 | if (dropdown == null) 66 | { 67 | throw new ArgumentException("dropdown must be assigned a TMP_Dropdown."); 68 | } 69 | 70 | if (inputField == null) 71 | { 72 | throw new ArgumentException("inputField must be assigned a TMP_InputField."); 73 | } 74 | 75 | dropdown.onValueChanged.AddListener(new UnityAction(HandleDropdownValueChanged)); 76 | HandleDropdownValueChanged(dropdown.value); 77 | } 78 | 79 | public void HandleDropdownValueChanged(int selectedDropdownIndex) 80 | { 81 | if (dropdown.options.Count > selectedDropdownIndex) 82 | { 83 | inputField.text = dropdown.options[selectedDropdownIndex].text; 84 | } 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /Samples~/EditableDropdown/Scripts/EditableDropdown.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 15ecfb62f5796584a960293e09488d52 -------------------------------------------------------------------------------- /Samples~/EditableDropdown/Scripts/EditableDropdownSetup.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace JH.DataBinding.Example.EditableDropdown 4 | { 5 | public class EditableDropdownSetup : MonoBehaviour 6 | { 7 | public View view; 8 | 9 | private EditableDropdownDataSource dataSource; 10 | 11 | void Start() 12 | { 13 | dataSource = new EditableDropdownDataSource() 14 | { 15 | InputValueChanged = HandleInputValueChanged, 16 | DropdownOptions = new string[] { "Apple", "Pear", "Orange", "Plum" }, 17 | InputValue = "Pear", 18 | }; 19 | 20 | view.DataSource = dataSource; 21 | } 22 | 23 | private void HandleInputValueChanged(string newValue) 24 | { 25 | if (dataSource.InputValue != newValue) 26 | { 27 | dataSource.NotifyChanges(x => x.InputValue = newValue); 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Samples~/EditableDropdown/Scripts/EditableDropdownSetup.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 80b2b92c00fb1aa4baac4a0b703e5edb -------------------------------------------------------------------------------- /Samples~/GameObjectPropertyBindings/GameObjectPropertyBindings.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1230e971893a0a041a03595c147677f4 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Samples~/GameObjectPropertyBindings/GameObjectPropertyBindingsSetup.cs: -------------------------------------------------------------------------------- 1 | using System.Security.Cryptography.X509Certificates; 2 | using UnityEngine; 3 | 4 | namespace JH.DataBinding.Samples.GameObjectPropertyBindings 5 | { 6 | public class NewBehaGameObjectPropertyBindingsSetup : MonoBehaviour 7 | { 8 | public float changePropertiesIntervalSeconds; 9 | public View view; 10 | private float nextChangeSec; 11 | private SceneCompositionDataSource dataSource; 12 | 13 | void Start() 14 | { 15 | dataSource = new SceneCompositionDataSource(); 16 | view.DataSource = dataSource; 17 | nextChangeSec = changePropertiesIntervalSeconds; 18 | } 19 | 20 | void Update() 21 | { 22 | if (Time.time > nextChangeSec) 23 | { 24 | nextChangeSec += changePropertiesIntervalSeconds; 25 | 26 | dataSource.NotifyChanges( 27 | (x) => 28 | { 29 | x.Name = "This name was set using DataBindings"; 30 | x.EnabledPostprocessing = Random.Range(0, 2) != 0; 31 | x.ShowCube = Random.Range(0, 2) != 0; 32 | } 33 | ); 34 | } 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Samples~/GameObjectPropertyBindings/GameObjectPropertyBindingsSetup.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 12e35f6ea3f7b9442803c90631c5446d -------------------------------------------------------------------------------- /Samples~/GameObjectPropertyBindings/JH.Databinding.Samples.GameObjectPropertyBindings.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "GameObjectPropertyBindings", 3 | "rootNamespace": "", 4 | "references": [ 5 | "GUID:1ac1bd0cf575cfe4b8d295c36f1e0edd" 6 | ], 7 | "includePlatforms": [], 8 | "excludePlatforms": [], 9 | "allowUnsafeCode": false, 10 | "overrideReferences": false, 11 | "precompiledReferences": [], 12 | "autoReferenced": true, 13 | "defineConstraints": [], 14 | "versionDefines": [], 15 | "noEngineReferences": false 16 | } -------------------------------------------------------------------------------- /Samples~/GameObjectPropertyBindings/JH.Databinding.Samples.GameObjectPropertyBindings.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3aa883311c511604396fe0d2119ed41e 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Samples~/GameObjectPropertyBindings/SceneCompositionDataSource.cs: -------------------------------------------------------------------------------- 1 | using JH.DataBinding; 2 | 3 | namespace JH.DataBinding.Samples.GameObjectPropertyBindings 4 | { 5 | public class SceneCompositionDataSource : DataSourceBase 6 | { 7 | public string Name {get; set;} 8 | public bool EnabledPostprocessing {get; set;} 9 | public bool ShowCube {get; set;} 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Samples~/GameObjectPropertyBindings/SceneCompositionDataSource.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: eef3062db6c8cdc4fba3bb59aef97d36 -------------------------------------------------------------------------------- /Samples~/How to react to user input - Finished/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5fc7b4951af5dca42800d17c665e29a9 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/How to react to user input - Finished/Scripts/UserInputHandlingDataSource.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | using static UnityEngine.UI.Dropdown; 5 | 6 | namespace JH.DataBinding.Example.UserInputHandling 7 | { 8 | public class UserInputHandlingDataSource : DataSourceBase 9 | { 10 | public string TypedText { get; set; } 11 | public string SelectedDropDownText { get; set; } 12 | public string PressCounterText { get; set; } 13 | 14 | public List DropDownOptions { get; set; } 15 | 16 | // Tutorial Step: Add properties to store the interaction handles. 17 | public Action HandleDropDownSelectionChanged { get; set; } 18 | public Action HandleButtonPressed { get; set; } 19 | public Action HandleTypedTextChanged { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Samples~/How to react to user input - Finished/Scripts/UserInputHandlingDataSource.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 74d3914eb09fcd049b42a112fa8b31ec -------------------------------------------------------------------------------- /Samples~/How to react to user input - Finished/Scripts/UserInputHandlingSetup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | using UnityEngine; 6 | using UnityEngine.UI; 7 | 8 | using static System.Net.Mime.MediaTypeNames; 9 | 10 | namespace JH.DataBinding.Example.UserInputHandling 11 | { 12 | public class UserInputHandlingSetup : MonoBehaviour 13 | { 14 | public View view; 15 | 16 | private UserInputHandlingDataSource viewModel; 17 | private int pressCounter = 0; 18 | 19 | public void Start() 20 | { 21 | var dropdownOptions = new List() 22 | { 23 | new Dropdown.OptionData() { text = "Option 01" }, 24 | new Dropdown.OptionData() { text = "Option 02" }, 25 | }; 26 | 27 | viewModel = new UserInputHandlingDataSource(); 28 | 29 | viewModel.TypedText = MakeDisplayText(null); 30 | viewModel.SelectedDropDownText = MakeOptionText(dropdownOptions[0]); 31 | viewModel.PressCounterText = MakePressCounterText(pressCounter); 32 | 33 | viewModel.DropDownOptions = dropdownOptions; 34 | 35 | // Tutorial Step: Store the handlers in the ViewModel for our user interface. 36 | viewModel.HandleTypedTextChanged = HandleTypedTextChanged; 37 | viewModel.HandleDropDownSelectionChanged = HandleDropDownSelectionChanged; 38 | viewModel.HandleButtonPressed = HandleButtonPressed; 39 | 40 | view.DataSource = viewModel; 41 | } 42 | 43 | private void HandleDropDownSelectionChanged(int selectedOptionIndex) 44 | { 45 | viewModel.NotifyChanges( 46 | (x) => 47 | x.SelectedDropDownText = MakeOptionText(x.DropDownOptions[selectedOptionIndex]) 48 | ); 49 | ; 50 | } 51 | 52 | private void HandleTypedTextChanged(string newText) 53 | { 54 | viewModel.NotifyChanges((x) => x.TypedText = MakeDisplayText(newText)); 55 | } 56 | 57 | private void HandleButtonPressed() 58 | { 59 | pressCounter++; 60 | viewModel.NotifyChanges((x) => x.PressCounterText = MakePressCounterText(pressCounter)); 61 | } 62 | 63 | private string MakeDisplayText(string newText) 64 | { 65 | if (string.IsNullOrEmpty(newText)) 66 | { 67 | return "No text was typed."; 68 | } 69 | else 70 | { 71 | return $"You typed the text: {newText}."; 72 | } 73 | } 74 | 75 | private string MakeOptionText(Dropdown.OptionData optionData) 76 | { 77 | return $"Selected Option: {optionData.text}"; 78 | } 79 | 80 | private string MakePressCounterText(int pressCounter) 81 | { 82 | return $"You pressed a button {pressCounter} times"; 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /Samples~/How to react to user input - Finished/Scripts/UserInputHandlingSetup.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6e635ddbe2f86334e8620ff17031a014 -------------------------------------------------------------------------------- /Samples~/How to react to user input - Finished/Scripts/UserInputHandlingView.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace JH.DataBinding.Example.UserInputHandling 4 | { 5 | public class UserInputHandlingView : View 6 | { 7 | public Action HandleInputChangedAction { get; set; } 8 | public Action HandleSelectionChangedCallback { get; set; } 9 | public Action HandleButtonPressed { get; set; } 10 | 11 | public void OnTextInputValueChanged(string newValue) => 12 | HandleInputChangedAction?.Invoke(newValue); 13 | 14 | public void OnSelectedOptionValueChanged(int newValue) => 15 | HandleSelectionChangedCallback?.Invoke(newValue); 16 | 17 | public void OnCounterButtonPressed() => HandleButtonPressed?.Invoke(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Samples~/How to react to user input - Finished/Scripts/UserInputHandlingView.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: aeb9ee9acc511f5448904488dbff8825 -------------------------------------------------------------------------------- /Samples~/How to react to user input - Finished/UserInputHandling.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7245f9391bed7b047be88ace36f013db 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Samples~/How to react to user input - Tutorial/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5fc7b4951af5dca42800d17c665e29a9 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/How to react to user input - Tutorial/Scripts/UserInputHandlingDataSource.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | using static UnityEngine.UI.Dropdown; 5 | 6 | namespace JH.DataBinding.Example 7 | { 8 | public class UserInputHandlingDataSource 9 | : DataSourceBase 10 | { 11 | public string TypedText { get; set; } 12 | public string SelectedDropDownText { get; set; } 13 | public string PressCounterText { get; set; } 14 | 15 | public List DropDownOptions { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Samples~/How to react to user input - Tutorial/Scripts/UserInputHandlingDataSource.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4355cc31baad57748b99cb9a33e375bd 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/How to react to user input - Tutorial/Scripts/UserInputHandlingSetup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | using UnityEngine; 6 | using UnityEngine.UI; 7 | 8 | using static System.Net.Mime.MediaTypeNames; 9 | 10 | namespace JH.DataBinding.Example.UserInputHandling.Tutorial 11 | { 12 | public class UserInputHandlingSetup : MonoBehaviour 13 | { 14 | public View view; 15 | 16 | private UserInputHandlingDataSource viewModel; 17 | private int pressCounter = 0; 18 | 19 | public void Start() 20 | { 21 | var dropdownOptions = new List() 22 | { 23 | new Dropdown.OptionData() { text = "Option 01" }, 24 | new Dropdown.OptionData() { text = "Option 02" }, 25 | }; 26 | 27 | viewModel = new UserInputHandlingDataSource(); 28 | 29 | viewModel.TypedText = MakeDisplayText(null); 30 | viewModel.SelectedDropDownText = MakeOptionText(dropdownOptions[0]); 31 | viewModel.PressCounterText = MakePressCounterText(pressCounter); 32 | 33 | viewModel.DropDownOptions = dropdownOptions; 34 | view.DataSource = viewModel; 35 | } 36 | 37 | private void HandleDropDownSelectionChanged(int selectedOptionIndex) 38 | { 39 | viewModel.NotifyChanges( 40 | (x) => 41 | x.SelectedDropDownText = MakeOptionText(x.DropDownOptions[selectedOptionIndex]) 42 | ); 43 | } 44 | 45 | private void HandleTypedTextChanged(string newText) 46 | { 47 | viewModel.NotifyChanges((x) => x.TypedText = MakeDisplayText(newText)); 48 | } 49 | 50 | private void HandleButtonPressed() 51 | { 52 | pressCounter++; 53 | viewModel.NotifyChanges((x) => x.PressCounterText = MakePressCounterText(pressCounter)); 54 | } 55 | 56 | private string MakeDisplayText(string newText) 57 | { 58 | if (string.IsNullOrEmpty(newText)) 59 | { 60 | return "No text was typed."; 61 | } 62 | else 63 | { 64 | return $"You typed the text: {newText}."; 65 | } 66 | } 67 | 68 | private string MakeOptionText(Dropdown.OptionData optionData) 69 | { 70 | return $"Selected Option: {optionData.text}"; 71 | } 72 | 73 | private string MakePressCounterText(int pressCounter) 74 | { 75 | return $"You pressed a button {pressCounter} times"; 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /Samples~/How to react to user input - Tutorial/Scripts/UserInputHandlingSetup.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3dee75e9b04c33548a7cf2577f06c965 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/How to react to user input - Tutorial/Scripts/UserInputHandlingView.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace JH.DataBinding.Example.UserInputHandling.Tutorial 4 | { 5 | public class UserInputHandlingView : View 6 | { 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Samples~/How to react to user input - Tutorial/Scripts/UserInputHandlingView.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 489b2b6725c278b49b4a6ae0e20df9da 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/How to react to user input - Tutorial/UserInputHandling.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7245f9391bed7b047be88ace36f013db 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Samples~/MyFirstDataBoundView (Getting Started Tutorial)/Materials.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2ac895e2cfa9d5946897fd370f5ceef9 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/MyFirstDataBoundView (Getting Started Tutorial)/Materials/Cube Material.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 19e37ec431f11da46b47526a0db331a5 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 2100000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/MyFirstDataBoundView (Getting Started Tutorial)/MyFirstDataBoundView.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fc286372ee01f5449aca6ae7aa464775 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Samples~/MyFirstDataBoundView (Getting Started Tutorial)/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a4e6c9517b054ca46850471f716c3dec 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/MyFirstDataBoundView (Getting Started Tutorial)/Scripts/CubeViewDataSource.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | using UnityEngine; 4 | 5 | namespace JH.DataBinding.Examples.GettingStarted 6 | { 7 | public class CubeViewDataSource : DataSourceBase 8 | { 9 | public Vector3 CubeScale { get; set; } = Vector3.one; 10 | public Color CubeColor { get; set; } = Color.grey; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Samples~/MyFirstDataBoundView (Getting Started Tutorial)/Scripts/CubeViewDataSource.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4d7ff3a4b8122da42b38b9c3f85f762e 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/MyFirstDataBoundView (Getting Started Tutorial)/Scripts/DynamicMaterialColor.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace JH.DataBinding.Examples.GettingStarted 4 | { 5 | public class DynamicMaterialColor : MonoBehaviour 6 | { 7 | public Material material; 8 | public Color Color 9 | { 10 | set 11 | { 12 | var meshRenderer = GetComponent(); 13 | meshRenderer.material.color = value; 14 | } 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Samples~/MyFirstDataBoundView (Getting Started Tutorial)/Scripts/DynamicMaterialColor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 057e26d001e970748a75c63d830494af 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/MyFirstDataBoundView (Getting Started Tutorial)/Scripts/MyFirstDataBoundViewSetup.cs: -------------------------------------------------------------------------------- 1 | using JH.DataBinding; 2 | 3 | using UnityEngine; 4 | 5 | namespace JH.DataBinding.Examples.GettingStarted 6 | { 7 | public class MyFirstDataBoundViewSetup : MonoBehaviour 8 | { 9 | public View view; 10 | private PlaceholderApplicationLogic _placeholderApplicationLogic; 11 | 12 | public void Start() 13 | { 14 | _placeholderApplicationLogic = new PlaceholderApplicationLogic(); 15 | _placeholderApplicationLogic.Initialize(); 16 | 17 | view.DataSource = _placeholderApplicationLogic.CubeViewDataSource; 18 | } 19 | 20 | // Update is called once per frame 21 | public void Update() 22 | { 23 | _placeholderApplicationLogic.Update(Time.time); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Samples~/MyFirstDataBoundView (Getting Started Tutorial)/Scripts/MyFirstDataBoundViewSetup.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a4855c804356c314ead49030a2d1d8a4 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/MyFirstDataBoundView (Getting Started Tutorial)/Scripts/PlaceholderApplicationLogic.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | 3 | using UnityEngine; 4 | 5 | namespace JH.DataBinding.Examples.GettingStarted 6 | { 7 | /// 8 | /// This class is here as a replacement for whatever 9 | /// application logic your application might implement. 10 | /// You application might be arbitrarily complex and expose 11 | /// many data sources - static data sources as well as dynamic ones. 12 | /// This application is about changing the scale and color of a cube. 13 | /// That's it for this tutorial. 14 | /// So the sole data source exposed is a simple CubeViewDataSource. 15 | /// 16 | public class PlaceholderApplicationLogic 17 | { 18 | public CubeViewDataSource CubeViewDataSource { get; set; } 19 | private float _nextCubeUpdateTimeSeconds; 20 | 21 | public void Initialize() 22 | { 23 | CubeViewDataSource = new CubeViewDataSource(); 24 | _nextCubeUpdateTimeSeconds = 0f; 25 | } 26 | 27 | public void Update(float simulationTimeSeconds) 28 | { 29 | if (_nextCubeUpdateTimeSeconds < simulationTimeSeconds) 30 | { 31 | _nextCubeUpdateTimeSeconds += 3.0f; 32 | 33 | CubeViewDataSource.NotifyChanges(x => 34 | { 35 | x.CubeScale = Vector3.one + Random.insideUnitSphere; 36 | x.CubeColor = Random.ColorHSV(0, 1, 0, 1); 37 | }); 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Samples~/MyFirstDataBoundView (Getting Started Tutorial)/Scripts/PlaceholderApplicationLogic.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5e33dbc15a49e0b4e8ade8a995fadba2 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Tests.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cf9b9503feeaa3d4d92db3c72d1f8f46 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Tests/Editor Tests.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4c0d66e7367b5c3418b20f2694223830 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Tests/Editor Tests/JH.DataBinding.Editor.Tests.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "JH.DataBinding.Editor.Tests", 3 | "rootNamespace": "JH.DataBinding.Editor.Tests", 4 | "references": [ 5 | "JH.DataBinding", 6 | "JH.DataBinding.Editor" 7 | ], 8 | "optionalUnityReferences": [ 9 | "TestAssemblies" 10 | ], 11 | "includePlatforms": [ 12 | "Editor" 13 | ], 14 | "excludePlatforms": [], 15 | "allowUnsafeCode": false, 16 | "overrideReferences": true, 17 | "precompiledReferences": [], 18 | "autoReferenced": false, 19 | "defineConstraints": [], 20 | "versionDefines": [], 21 | "noEngineReferences": false 22 | } 23 | -------------------------------------------------------------------------------- /Tests/Editor Tests/JH.DataBinding.Editor.Tests.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: dafb10bdd2577a548ac1b8d3551fdcf4 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Tests/Editor Tests/NewTestScript.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using NUnit.Framework; 3 | using UnityEditor; 4 | using UnityEngine; 5 | using UnityEngine.TestTools; 6 | 7 | namespace JH.DataBinding.Editor.Tests 8 | { 9 | public class NewTestScript 10 | { 11 | // A Test behaves as an ordinary method 12 | [Test] 13 | public void NewTestScriptSimplePasses() { } 14 | 15 | // A UnityTest behaves like a coroutine in Play Mode. In Edit Mode you can use 16 | // `yield return null;` to skip a frame. 17 | [UnityTest] 18 | public IEnumerator NewTestScriptWithEnumeratorPasses() 19 | { 20 | // Use the Assert class to test conditions. 21 | // Use yield to skip a frame. 22 | yield return null; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Tests/Editor Tests/NewTestScript.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9ee9d25a595d6a2479f30fc87ea32722 -------------------------------------------------------------------------------- /Tests/Runtime.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bc53aee8a9da5ac4a89f721c09961e93 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Tests/Runtime/JH.DataBinding.Tests.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "JH.DataBinding.Tests", 3 | "rootNamespace": "JH.DataBinding.Tests", 4 | "references": [ 5 | "JH.DataBinding" 6 | ], 7 | "optionalUnityReferences": [ 8 | "TestAssemblies" 9 | ], 10 | "includePlatforms": [], 11 | "excludePlatforms": [], 12 | "allowUnsafeCode": false, 13 | "overrideReferences": true, 14 | "precompiledReferences": [], 15 | "autoReferenced": false, 16 | "defineConstraints": [], 17 | "versionDefines": [], 18 | "noEngineReferences": false 19 | } -------------------------------------------------------------------------------- /Tests/Runtime/JH.DataBinding.Tests.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b1bdfef5d4b4c9646b9eccad4b3ca7aa 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Tests/Runtime/RuntimeContainerBindingsTest.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using NUnit.Framework; 4 | using UnityEngine; 5 | using UnityEngine.TestTools; 6 | 7 | namespace JH.DataBinding.Tests 8 | { 9 | class PlayerDataSourceTest 10 | { 11 | class TestElementTemplateDataSource : DataSourceBase 12 | { 13 | public Vector3 Position { get; set; } 14 | } 15 | 16 | class TestContainerBindingsDataSource : DataSourceBase 17 | { 18 | public IEnumerable Positions { get; set; } 19 | } 20 | 21 | [UnityTest] 22 | public IEnumerator TestContainerBindings() 23 | { 24 | var testDataSource = new TestContainerBindingsDataSource() 25 | { 26 | Positions = new TestElementTemplateDataSource[] 27 | { 28 | new TestElementTemplateDataSource() { Position = new Vector3(1f, 0f, 0f) }, 29 | new TestElementTemplateDataSource() { Position = new Vector3(2f, 0f, 0f) }, 30 | }, 31 | }; 32 | 33 | var elementTemplateGameObject = new GameObject("ElementTemplate"); 34 | var elementTemplateView = elementTemplateGameObject.AddComponent(); 35 | 36 | var containerGameObject = new GameObject("ContainerTestObject"); 37 | var containerView = containerGameObject.AddComponent(); 38 | 39 | containerView.containerPropertyBindings = new ContainerPropertyBinding[] 40 | { 41 | new ContainerPropertyBinding() 42 | { 43 | SourcePath = nameof(testDataSource.Positions), 44 | TargetContainer = containerGameObject.transform, 45 | ElementTemplate = elementTemplateView, 46 | }, 47 | }; 48 | 49 | containerView.DataSource = testDataSource; 50 | 51 | if (!Application.isBatchMode) 52 | { 53 | // WaitForEndOfFrame does throw in batch mode, 54 | // so can not use it as of now. 55 | yield return new WaitForEndOfFrame(); 56 | Assert.AreEqual(2, containerGameObject.transform.childCount); 57 | } 58 | 59 | containerView.DataSource = null; 60 | 61 | if (!Application.isBatchMode) 62 | { 63 | // WaitForEndOfFrame does throw in batch mode, 64 | // so can not use it as of now. 65 | yield return new WaitForEndOfFrame(); 66 | Assert.AreEqual(0, containerGameObject.transform.childCount); 67 | } 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /Tests/Runtime/RuntimeContainerBindingsTest.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 101e0987aa7143445b70dc84c77dbf19 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Third Party Notices.md: -------------------------------------------------------------------------------- 1 | This package contains third-party software components governed by the license(s) indicated below: 2 | --------- 3 | 4 | Component Name: [provide component name] 5 | 6 | License Type: [Provide license type, i.e. "MIT", "Apache 2.0"] 7 | 8 | [Provide License Details] 9 | 10 | -------------------------------------------------------------------------------- /Third Party Notices.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bb5fa45a7a36c774484bd471a43db5e9 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "de.jochenheckl.unity.databinding", 3 | "displayName": "DataBinding", 4 | "version": "3.4.1", 5 | "unity": "2023.3", 6 | "description": "DataBinding is a method of connecting a data model with user interface components, allowing changes in one to automatically reflect in the other.\n\nThis package supplies the means that will enable you to implement declarative user interfaces (== user interfaces that are a function of the underlying data that defines it). It's like WPF for Unity Game Objects.", 7 | "keywords": [ 8 | "Data Binding", 9 | "DataBinding", 10 | "View Model", 11 | "ViewModel", 12 | "DataSource", 13 | "MVVM", 14 | "User Interface", 15 | "UserInterface", 16 | "UI", 17 | "Dynamic User Interface", 18 | "Dynamic UserInterface", 19 | "Dynamic UI", 20 | "Declarative User Interface", 21 | "Declarative UserInterface", 22 | "Declarative UI", 23 | "SOLID" 24 | ], 25 | "category": "Editor Extensions", 26 | "author": { 27 | "name": "Jochen Heckl", 28 | "email": "jochen.heckl@gmail.com", 29 | "url": "https://www.jochenheckl.de" 30 | }, 31 | "licensesUrl": "https://raw.githubusercontent.com/JochenHeckl/DataBinding/main/LICENSE.md", 32 | "dependencies": { 33 | "com.unity.test-framework": "1.4.5" 34 | }, 35 | "testtables": [ 36 | "JH.DataBinding" 37 | ], 38 | "samples": [ 39 | { 40 | "displayName": "MyFirstDataBoundView (Getting Started Tutorial)", 41 | "description": "The finished project you would have created when following the Getting Started Tutorial step by step.", 42 | "path": "Samples~/MyFirstDataBoundView (Getting Started Tutorial)" 43 | }, 44 | { 45 | "displayName": "A look at ContainerBindings - Tutorial", 46 | "description": "Starting point for a simple step by step tutorial introducing ContainerBindings.", 47 | "path": "Samples~/A look at ContainerBindings - Tutorial" 48 | }, 49 | { 50 | "displayName": "A look at ContainerBindings - Finished", 51 | "description": "The finished project you will end up with after completing the step by step tutorial.", 52 | "path": "Samples~/A look at ContainerBindings - Finished" 53 | }, 54 | { 55 | "displayName": "How to react to user input - Tutorial", 56 | "description": "Learn how to accept user input in a simple step by step tutorial. https://github.com/JochenHeckl/DataBinding/Documentation~/HowToReactToUserInput.md", 57 | "path": "Samples~/How to react to user input - Tutorial" 58 | }, 59 | { 60 | "displayName": "How to react to user input - Finished", 61 | "description": "The finished project you will end up with after completing the step by step tutorial.", 62 | "path": "Samples~/How to react to user input - Finished" 63 | }, 64 | { 65 | "displayName": "EditableDropdown", 66 | "description": "A simple view with an EditableDropdown.", 67 | "path": "Samples~/EditableDropdown" 68 | }, 69 | { 70 | "displayName": "GameObjectPropertyBindings", 71 | "description": "A simple scene demonstrating how to bind GameObject properties.", 72 | "path": "Samples~/GameObjectPropertyBindings" 73 | } 74 | ] 75 | } -------------------------------------------------------------------------------- /package.json.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7b0e889154411b3488b4bee4f0f3db18 3 | PackageManifestImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | --------------------------------------------------------------------------------