-
Notifications
You must be signed in to change notification settings - Fork 0
/
ColorsController.cs
185 lines (154 loc) · 5.53 KB
/
ColorsController.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
//
// Cuboid (http://github.com/arjonagelhout/cuboid)
// Copyright (c) 2023 Arjo Nagelhout
//
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Cuboid
{
public interface IHasPrimaryColor
{
public Binding<RealityColor> PrimaryColor { get; set; }
}
/// <summary>
/// ColorsController is responsible for storing the last selected color,
/// and can be retrieved
/// </summary>
public class ColorsController : MonoBehaviour
{
private static ColorsController _instance;
public static ColorsController Instance => _instance;
public StoredBinding<RealityColor> ActiveColor;
private SelectionController _selectionController;
private Action<Selection> _onSelectionChanged;
private void Awake()
{
// Singleton implementation
if (_instance != null && _instance != this) { Destroy(this); } else { _instance = this; }
ActiveColor = new("ColorsController_ActiveColor", new RealityColor());
}
private void Start()
{
_selectionController = SelectionController.Instance;
_onSelectionChanged = OnSelectionChanged;
_onValueChanged = OnValueChanged;
Register();
}
/// <summary>
/// Cached list of objects that should get their color changed
/// </summary>
private List<IBinding<RealityColor>> _targetBindings = new List<IBinding<RealityColor>>();
private RealityColor _previousValue;
private RealityColor[] _previousValues;
private Action<RealityColor> _onValueChanged;
private void StorePreviousValues()
{
_previousValue = ActiveColor.Value;
_previousValues = new RealityColor[_targetBindings.Count];
for (int i = 0; i < _targetBindings.Count; i++)
{
IBinding<RealityColor> binding = _targetBindings[i];
_previousValues[i] = binding.Value;
}
}
private void OnValueChanged(RealityColor color)
{
ActiveColor.Value = color;
}
public void OnSetValue(RealityColor color)
{
GetCommand(false).Do();
}
public void OnConfirmValue(RealityColor color)
{
UndoRedoController.Instance.Execute(GetCommand(true));
StorePreviousValues();
}
private void OnSelectionChanged(Selection selection)
{
List<IBinding<RealityColor>> newTargetBindings = new List<IBinding<RealityColor>>();
RealityColor? newColor = null;
foreach (RealityObjectData realityObject in selection.SelectedRealityObjects)
{
IHasPrimaryColor primaryColorObject = realityObject as IHasPrimaryColor;
if (primaryColorObject == null) { continue; }
newColor = primaryColorObject.PrimaryColor.Value;
newTargetBindings.Add(primaryColorObject.PrimaryColor);
}
if (newColor.HasValue)
{
ActiveColor.Value = newColor.Value;
}
SetTargetBindings(newTargetBindings);
StorePreviousValues();
}
/// <summary>
/// The target bindings should be listened to by the Property
/// because if the SetPropertyCommand gets executed, it does not update
/// the source binding (the _binding in this class), but it updates
/// the target bindings.
//
/// So, if any target bindings get changed, the source binding value
/// should be changed.
///
/// Note: The target bindings are the bindings stored in the <see cref="RealityObjectData"/>
/// instances.
/// </summary>
private void SetTargetBindings(List<IBinding<RealityColor>> targetBindings)
{
// unregister
if (_targetBindings != null)
{
foreach (IBinding<RealityColor> targetBinding in _targetBindings)
{
if (targetBinding == null) { continue; }
targetBinding.OnValueChanged -= _onValueChanged;
}
}
_targetBindings = targetBindings;
// register
if (_targetBindings != null)
{
foreach (IBinding<RealityColor> targetBinding in _targetBindings)
{
targetBinding.OnValueChanged += _onValueChanged;
}
}
}
private SetPropertyCommand<RealityColor> GetCommand(bool passPreviousValues)
{
return new SetPropertyCommand<RealityColor>(_targetBindings, _previousValue, ActiveColor.Value, passPreviousValues ? _previousValues : null);
}
#region Action registration
private void Register()
{
if (_selectionController != null)
{
_selectionController.Selection.Register(_onSelectionChanged);
}
}
private void Unregister()
{
if (_selectionController != null)
{
_selectionController.Selection.Unregister(_onSelectionChanged);
}
SetTargetBindings(null);
}
private void OnEnable()
{
Register();
}
private void OnDisable()
{
Unregister();
}
private void OnDestroy()
{
Unregister();
}
#endregion
}
}