├── .gitignore
├── AffinityUI.sln
├── AffinityUI
├── AffinityUI.csproj
├── Area.cs
├── AssemblyInfo.cs
├── AutoSpace.cs
├── BindableContent.cs
├── BindableProperty.cs
├── Binder.cs
├── Box.cs
├── Button.cs
├── Composite.cs
├── ContentControl.cs
├── Control.cs
├── Extensions.cs
├── HorizontalPanel.cs
├── HorizontalSlider.cs
├── Label.cs
├── PasswordField.cs
├── ScrollView.cs
├── SelectionGrid.cs
├── TabControl.cs
├── TextArea.cs
├── TextField.cs
├── Toggle.cs
├── Tooltip.cs
├── TooltipRenderer.cs
├── TypedControl.cs
├── UI.cs
├── VerticalPanel.cs
├── VerticalSlider.cs
└── Window.cs
├── KspExample
├── AssemblyInfo.cs
├── ExampleGUI.cs
├── KspExample.csproj
└── res
│ ├── icon.png
│ └── license.txt
├── LICENSE.md
├── README.md
└── lib
├── Assembly-CSharp.dll
└── UnityEngine.dll
/.gitignore:
--------------------------------------------------------------------------------
1 | *proj.user
2 | **/obj/*
3 | **/bin/*
4 | *.ncb
5 | *.suo
6 | AffinityUI.userprefs
7 | AffinityUI.pidb
8 |
--------------------------------------------------------------------------------
/AffinityUI.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 11.00
3 | # Visual Studio 2010
4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AffinityUI", "AffinityUI\AffinityUI.csproj", "{22A4E171-AA2B-4150-A8A0-348D8134F706}"
5 | EndProject
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KspExample", "KspExample\KspExample.csproj", "{99F0CB38-DBCD-4177-AFBF-A8264CE1D669}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {22A4E171-AA2B-4150-A8A0-348D8134F706}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {22A4E171-AA2B-4150-A8A0-348D8134F706}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {22A4E171-AA2B-4150-A8A0-348D8134F706}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {22A4E171-AA2B-4150-A8A0-348D8134F706}.Release|Any CPU.Build.0 = Release|Any CPU
18 | {99F0CB38-DBCD-4177-AFBF-A8264CE1D669}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
19 | {99F0CB38-DBCD-4177-AFBF-A8264CE1D669}.Debug|Any CPU.Build.0 = Debug|Any CPU
20 | {99F0CB38-DBCD-4177-AFBF-A8264CE1D669}.Release|Any CPU.ActiveCfg = Release|Any CPU
21 | {99F0CB38-DBCD-4177-AFBF-A8264CE1D669}.Release|Any CPU.Build.0 = Release|Any CPU
22 | EndGlobalSection
23 | GlobalSection(MonoDevelopProperties) = preSolution
24 | Policies = $0
25 | $0.TextStylePolicy = $1
26 | $1.FileWidth = 120
27 | $1.inheritsSet = VisualStudio
28 | $1.inheritsScope = text/plain
29 | $1.scope = text/x-csharp
30 | $0.CSharpFormattingPolicy = $2
31 | $2.IndentSwitchBody = True
32 | $2.IndentBlocksInsideExpressions = True
33 | $2.AnonymousMethodBraceStyle = NextLine
34 | $2.PropertyBraceStyle = NextLine
35 | $2.PropertyGetBraceStyle = NextLine
36 | $2.PropertySetBraceStyle = NextLine
37 | $2.EventBraceStyle = NextLine
38 | $2.EventAddBraceStyle = NextLine
39 | $2.EventRemoveBraceStyle = NextLine
40 | $2.StatementBraceStyle = NextLine
41 | $2.ElseNewLinePlacement = NewLine
42 | $2.CatchNewLinePlacement = NewLine
43 | $2.FinallyNewLinePlacement = NewLine
44 | $2.WhileNewLinePlacement = DoNotCare
45 | $2.ArrayInitializerWrapping = DoNotChange
46 | $2.ArrayInitializerBraceStyle = NextLine
47 | $2.BeforeMethodDeclarationParentheses = False
48 | $2.BeforeMethodCallParentheses = False
49 | $2.BeforeConstructorDeclarationParentheses = False
50 | $2.NewLineBeforeConstructorInitializerColon = NewLine
51 | $2.NewLineAfterConstructorInitializerColon = SameLine
52 | $2.BeforeDelegateDeclarationParentheses = False
53 | $2.NewParentheses = False
54 | $2.SpacesBeforeBrackets = False
55 | $2.inheritsSet = Mono
56 | $2.inheritsScope = text/x-csharp
57 | $2.scope = text/x-csharp
58 | EndGlobalSection
59 | GlobalSection(SolutionProperties) = preSolution
60 | HideSolutionNode = FALSE
61 | EndGlobalSection
62 | EndGlobal
63 |
--------------------------------------------------------------------------------
/AffinityUI/AffinityUI.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | 8.0.30703
7 | 2.0
8 | {22A4E171-AA2B-4150-A8A0-348D8134F706}
9 | Library
10 | Properties
11 | AffinityUI
12 | AffinityUI
13 | v3.5
14 | 512
15 |
16 |
17 |
18 | true
19 | full
20 | false
21 | bin\Debug\
22 | DEBUG;TRACE
23 | prompt
24 | 4
25 | bin\Debug\AffinityUI.XML
26 |
27 |
28 | pdbonly
29 | true
30 | bin\Release\
31 | TRACE
32 | prompt
33 | 4
34 | bin\Release\AffinityUI.XML
35 |
36 |
37 |
38 |
39 |
40 | ..\lib\UnityEngine.dll
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 | I
102 |
103 |
104 |
105 |
106 | Attribute
107 |
108 |
109 |
110 |
111 | EventArgs
112 |
113 |
114 |
115 |
116 | Exception
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 | T
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
--------------------------------------------------------------------------------
/AffinityUI/Area.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using UnityEngine;
5 |
6 | namespace AffinityUI
7 | {
8 | ///
9 | /// Contains a block in a fixed screen area.
10 | ///
11 | public class Area : Composite
12 | {
13 | Rect dimensions;
14 |
15 | ///
16 | /// Initializes a new instance of the class.
17 | ///
18 | /// The dimensions.
19 | public Area(Rect dimensions)
20 | : base()
21 | {
22 | this.dimensions = dimensions;
23 | }
24 |
25 | public Area Dimensions(Rect dimensions)
26 | {
27 | this.dimensions = dimensions;
28 | return this;
29 | }
30 |
31 | public Rect Dimensions()
32 | {
33 | return dimensions;
34 | }
35 |
36 | ///
37 | /// Called when layout begins when using GUILayout.
38 | ///
39 | protected override void OnBeginLayout_GUILayout()
40 | {
41 | GUILayout.BeginArea(dimensions, Label());
42 | }
43 |
44 | ///
45 | /// Called when layout ends when using GUILayout.
46 | ///
47 | protected override void OnEndLayout_GUILayout()
48 | {
49 | GUILayout.EndArea();
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/AffinityUI/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("AffinityUI")]
9 | [assembly: AssemblyDescription("AffinityUI for Unity")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("AffinityUI")]
13 | [assembly: AssemblyCopyright("Copyright © Matt Olenik")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("48d7d6e2-d08e-48c4-a641-b2942dee8502")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("0.1.0.0")]
36 | [assembly: AssemblyFileVersion("0.1.0.0")]
37 |
--------------------------------------------------------------------------------
/AffinityUI/AutoSpace.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using UnityEngine;
3 |
4 | namespace AffinityUI
5 | {
6 | public class AutoSpace : Control
7 | {
8 | BindableProperty size;
9 |
10 | public AutoSpace()
11 | : this(0)
12 | {
13 | }
14 |
15 | public AutoSpace(int size)
16 | : base()
17 | {
18 | this.size = new BindableProperty(this, size);
19 | }
20 |
21 | public AutoSpace Size(int size)
22 | {
23 | this.size.Value = size;
24 | return this;
25 | }
26 |
27 | public BindableProperty Size()
28 | {
29 | return size;
30 | }
31 |
32 | protected override void Layout_GUILayout()
33 | {
34 | if (size == 0)
35 | {
36 | GUILayout.FlexibleSpace();
37 | }
38 | else
39 | {
40 | GUILayout.Space(size);
41 | }
42 | }
43 | }
44 | }
--------------------------------------------------------------------------------
/AffinityUI/BindableContent.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using UnityEngine;
5 |
6 | namespace AffinityUI
7 | {
8 | ///
9 | /// A bindable drop-in for GUIContent
10 | ///
11 | public class BindableContent
12 | {
13 | TOwner owner;
14 | BindableProperty label;
15 | GUIContent content;
16 |
17 | public TOwner OK { get { return owner; } }
18 |
19 | public BindableProperty Label()
20 | {
21 | return label;
22 | }
23 |
24 | public BindableContent Label(string text)
25 | {
26 | label.Value = text;
27 | return this;
28 | }
29 |
30 | public GUIContent Content()
31 | {
32 | return content;
33 | }
34 |
35 | public BindableContent Content(GUIContent content)
36 | {
37 | this.content = content;
38 | return this;
39 | }
40 |
41 | public Texture Image()
42 | {
43 | return content.image;
44 | }
45 |
46 | public BindableContent Image(Texture image)
47 | {
48 | content.image = image;
49 | return this;
50 | }
51 |
52 | public BindableContent(TOwner owner)
53 | : this(owner, new GUIContent())
54 | {
55 | }
56 |
57 | public BindableContent(TOwner owner, GUIContent content)
58 | {
59 | this.owner = owner;
60 | this.content = content;
61 | label = new BindableProperty(owner);
62 | label.OnPropertyChanged(((src, old, nw) => content.text = nw));
63 | }
64 |
65 | public void UpdateBinding()
66 | {
67 | label.UpdateBinding();
68 | }
69 | }
70 | }
--------------------------------------------------------------------------------
/AffinityUI/BindableProperty.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text.RegularExpressions;
3 |
4 | namespace AffinityUI
5 | {
6 | ///
7 | /// Change notification function signature.
8 | ///
9 | public delegate void PropertyChangedEventHandler(TSource src, TValue old, TValue nw);
10 |
11 | ///
12 | /// Encapsulates databinding and update notification functionality for control properties.
13 | ///
14 | /// The type of the owner control.
15 | /// The type of the property.
16 | public class BindableProperty
17 | {
18 | TProperty value;
19 | TOwner owner;
20 | Binder binder;
21 |
22 | ///
23 | /// Occurs when the property's value changes.
24 | ///
25 | public event PropertyChangedEventHandler PropertyChanged;
26 |
27 | ///
28 | /// Gets the binding direction. Throws an if the property is not bound.
29 | ///
30 | /// The direction.
31 | public BindingDirection Direction
32 | {
33 | get
34 | {
35 | if (binder != null)
36 | {
37 | return binder.Direction;
38 | }
39 | throw new InvalidOperationException("Property is not bound.");
40 | }
41 | }
42 |
43 | ///
44 | /// Initializes a new instance of the class.
45 | ///
46 | /// The owner control.
47 | public BindableProperty(TOwner owner)
48 | {
49 | this.owner = owner;
50 | }
51 |
52 | ///
53 | /// Initializes a new instance of the class.
54 | ///
55 | /// The owner control.
56 | /// The default value.
57 | public BindableProperty(TOwner owner, TProperty defaultValue)
58 | : this(owner)
59 | {
60 | value = defaultValue;
61 | }
62 |
63 | ///
64 | /// Gets or sets the value.
65 | ///
66 | /// The value.
67 | public TProperty Value
68 | {
69 | get
70 | {
71 | UpdateBinding();
72 | return value;
73 | }
74 | set
75 | {
76 | if (AreDifferent(this.value, value))
77 | {
78 | DispatchPropertyChanged(this.value, value);
79 | if (binder != null &&
80 | (binder.Direction == BindingDirection.TwoWay || binder.Direction == BindingDirection.OneWayToSource))
81 | {
82 | binder.Value = value;
83 | }
84 | }
85 | this.value = value;
86 | }
87 | }
88 |
89 | public static implicit operator TProperty(BindableProperty instance)
90 | {
91 | return instance.Value;
92 | }
93 |
94 | ///
95 | /// Sets the value but ignores databinding.
96 | ///
97 | /// The value.
98 | /// the owner control
99 | public TOwner SetIgnoreBinding(TProperty value)
100 | {
101 | this.value = value;
102 | return owner;
103 | }
104 |
105 | ///
106 | /// Binds this property using two way binding.
107 | ///
108 | /// The getter.
109 | /// The setter.
110 | /// the owner control
111 | public TOwner BindTwoWay(Func getter, Action setter)
112 | {
113 | binder = Binder.BindTwoWay(getter, setter);
114 | return owner;
115 | }
116 |
117 | ///
118 | /// Binds this property using one way binding.
119 | ///
120 | /// The getter.
121 | /// the owner control
122 | public TOwner BindOneWay(Func getter)
123 | {
124 | binder = Binder.BindOneWay(getter);
125 | return owner;
126 | }
127 |
128 | ///
129 | /// Binds this property using one way to source binding.
130 | ///
131 | /// The setter.
132 | /// the owner control
133 | public TOwner BindOneWayToSource(Action setter)
134 | {
135 | binder = Binder.BindOneWayToSource(setter);
136 | return owner;
137 | }
138 |
139 | ///
140 | /// Convenience fluent method for adding a handler to the event.
141 | ///
142 | /// The handler.
143 | /// the owner control
144 | public TOwner OnPropertyChanged(PropertyChangedEventHandler handler)
145 | {
146 | PropertyChanged += handler;
147 | return owner;
148 | }
149 |
150 | ///
151 | /// Updates the binding. Call this when the binding should be updated without getting or setting the property.
152 | ///
153 | public void UpdateBinding()
154 | {
155 | if (binder != null &&
156 | (binder.Direction == BindingDirection.TwoWay || binder.Direction == BindingDirection.OneWay))
157 | {
158 | if (AreDifferent(value, binder.Value))
159 | {
160 | DispatchPropertyChanged(value, binder.Value);
161 | value = binder.Value;
162 | }
163 | }
164 | }
165 |
166 | ///
167 | /// Dispatches property changed events.
168 | ///
169 | /// The old value.
170 | /// The new value.
171 | void DispatchPropertyChanged(TProperty oldValue, TProperty newValue)
172 | {
173 | if (PropertyChanged != null)
174 | {
175 | PropertyChanged(owner, oldValue, newValue);
176 | }
177 | }
178 |
179 | ///
180 | /// Determines if the arguments are different.
181 | ///
182 | /// First object.
183 | /// Second object.
184 | /// true if the arguments are different; otherwise, false.
185 | bool AreDifferent(object a, object b)
186 | {
187 | if (a == null && b == null)
188 | {
189 | return false;
190 | }
191 | if ((a == null && b != null) || (a != null && b == null))
192 | {
193 | return true;
194 | }
195 | return !a.Equals(b);
196 | }
197 | }
198 | }
--------------------------------------------------------------------------------
/AffinityUI/Binder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace AffinityUI
4 | {
5 | ///
6 | /// Data binding direction, indicates how data should be bound between source and destination.
7 | ///
8 | public enum BindingDirection
9 | {
10 | ///
11 | /// Binding is performed from the source to the control and the control to the source.
12 | ///
13 | TwoWay,
14 | ///
15 | /// Binding is performed from the source to the control.
16 | ///
17 | OneWay,
18 | ///
19 | /// Binding is performed from the control to the source.
20 | ///
21 | OneWayToSource
22 | }
23 |
24 | ///
25 | /// A data binding helper for fields and properties.
26 | ///
27 | /// The type of the field or property being bound
28 | public class Binder
29 | {
30 | Action setter;
31 | Func getter;
32 |
33 | ///
34 | /// Gets the .
35 | ///
36 | /// The binding direction.
37 | public BindingDirection Direction { get; private set; }
38 |
39 | ///
40 | /// Initializes a new instance of the class.
41 | ///
42 | /// The binding direction.
43 | Binder(BindingDirection direction)
44 | {
45 | Direction = direction;
46 | }
47 |
48 | ///
49 | /// Creates a binder with two way binding.
50 | ///
51 | /// The type of the value.
52 | /// The setter.
53 | /// The getter.
54 | /// a new Binder for type TValue
55 | public static Binder BindTwoWay(Func getter, Action setter)
56 | {
57 | var binder = new Binder(BindingDirection.TwoWay) { getter = getter, setter = setter };
58 | return binder;
59 | }
60 |
61 | ///
62 | /// Creates a binder with one way binding.
63 | ///
64 | /// The type of the value.
65 | /// The getter.
66 | /// a new Binder for type TValue
67 | public static Binder BindOneWay(Func getter)
68 | {
69 | var binder = new Binder(BindingDirection.OneWay) { getter = getter };
70 | return binder;
71 | }
72 |
73 | ///
74 | /// Creates a binder with one way to source binding.
75 | ///
76 | /// The type of the value.
77 | /// The setter.
78 | /// a new Binder for type TValue
79 | public static Binder BindOneWayToSource(Action setter)
80 | {
81 | var binder = new Binder(BindingDirection.OneWayToSource) { setter = setter };
82 | return binder;
83 | }
84 |
85 | ///
86 | /// Gets or sets the bound value.
87 | ///
88 | /// The bound value.
89 | public T Value
90 | {
91 | get
92 | {
93 | if (getter == null)
94 | {
95 | throw new InvalidOperationException("Cannot get the value because the binding mode is one way to source (write only).");
96 | }
97 | return getter();
98 | }
99 | set
100 | {
101 | if (setter == null)
102 | {
103 | throw new InvalidOperationException("Cannot set the value because the binding mode is one way (read only).");
104 | }
105 | setter(value);
106 | }
107 | }
108 | }
109 | }
--------------------------------------------------------------------------------
/AffinityUI/Box.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using UnityEngine;
5 |
6 | namespace AffinityUI
7 | {
8 | ///
9 | /// A box with GUIContent.
10 | ///
11 | public class Box : ContentControl
12 | {
13 | ///
14 | /// Initializes a new instance of the class.
15 | ///
16 | public Box()
17 | : base()
18 | {
19 | Style(() => GUI.skin.box);
20 | }
21 |
22 | ///
23 | /// Initializes a new instance of the class.
24 | ///
25 | /// The label text.
26 | public Box(string label)
27 | : this()
28 | {
29 | Label(label);
30 | }
31 |
32 | ///
33 | /// Called when layout is done using GUI.
34 | ///
35 | protected override void Layout_GUI()
36 | {
37 | GUI.Box(Position(), Content(), Style());
38 | }
39 |
40 | ///
41 | /// Called when layout is done using GUILayout.
42 | ///
43 | protected override void Layout_GUILayout()
44 | {
45 | GUILayout.Box(Content(), Style(), LayoutOptions());
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/AffinityUI/Button.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using UnityEngine;
3 |
4 | namespace AffinityUI
5 | {
6 | ///
7 | /// Handler type for button click events.
8 | ///
9 | public delegate void ButtonClickHandler(TSource src);
10 |
11 | ///
12 | /// A clickable button.
13 | ///
14 | public class Button : ContentControl