@@ -10,8 +10,7 @@ namespace System.Windows.Forms.Design
10
10
{
11
11
public class ControlDesigner : IControlDesigner
12
12
{
13
- private objectEditor editor ;
14
- private bool toggleEditor = true ;
13
+ private readonly objectEditor editor ;
15
14
16
15
public Control Control { get ; set ; }
17
16
@@ -29,6 +28,7 @@ public virtual object Draw(int width, int height)
29
28
30
29
Control controlToSet = null ;
31
30
31
+ Editor . SetBackColor ( Color . White ) ;
32
32
Editor . BeginGroup ( width - 24 , "" ) ;
33
33
34
34
controlToSet = editor . Draw ( ) ;
@@ -40,6 +40,7 @@ public virtual object Draw(int width, int height)
40
40
41
41
private class controlProperty
42
42
{
43
+ public readonly List < objectEditor > arrayEditors = new List < objectEditor > ( ) ;
43
44
public objectEditor editor ;
44
45
public bool expanded ;
45
46
public PropertyInfo info ;
@@ -51,6 +52,7 @@ private class objectEditor
51
52
private readonly object obj ;
52
53
private readonly List < controlProperty > props ;
53
54
private readonly string name ;
55
+ private int rgb = 255 ;
54
56
55
57
public bool toggleEditor ;
56
58
@@ -67,6 +69,9 @@ public objectEditor(object o, string objName)
67
69
for ( int i = 0 ; i < pList . Count ; i ++ )
68
70
{
69
71
var p = pList [ i ] ;
72
+ if ( p . DeclaringType == typeof ( Delegate ) ) continue ;
73
+ if ( p . Name == "Item" ) continue ; // this[] will throw an exception.
74
+
70
75
var cp = new controlProperty ( )
71
76
{
72
77
info = p ,
@@ -99,13 +104,15 @@ public Control Draw()
99
104
return null ;
100
105
}
101
106
102
- Editor . BeginVertical ( "Box" ) ;
103
107
toggleEditor = Editor . Foldout ( name , toggleEditor ) ;
108
+ var style = toggleEditor ? "Box" : null ;
109
+ Editor . BeginVertical ( style ) ;
104
110
if ( toggleEditor )
105
111
{
106
112
// Fields.
107
113
if ( fields . Count > 0 )
108
114
{
115
+ Editor . SetBackColor ( Color . AliceBlue ) ;
109
116
Editor . BeginVertical ( "Box" ) ;
110
117
for ( int i = 0 ; i < fields . Count ; i ++ )
111
118
{
@@ -119,6 +126,9 @@ public Control Draw()
119
126
}
120
127
121
128
// Properties.
129
+ Editor . SetBackColor ( Color . White ) ;
130
+ if ( toggleEditor )
131
+ Editor . SetBackColor ( Color . FromArgb ( rgb , rgb , rgb ) ) ;
122
132
for ( int i = 0 ; i < props . Count ; i ++ )
123
133
{
124
134
var tc = Draw ( props [ i ] ) ;
@@ -127,6 +137,7 @@ public Control Draw()
127
137
}
128
138
129
139
// Methods.
140
+ Editor . SetBackColor ( Color . White ) ;
130
141
if ( methods . Count > 0 )
131
142
{
132
143
Editor . NewLine ( 1 ) ;
@@ -140,21 +151,33 @@ public Control Draw()
140
151
}
141
152
}
142
153
Editor . EndVertical ( ) ;
154
+
155
+ if ( toggleEditor )
156
+ Editor . NewLine ( 1 ) ;
157
+
143
158
return control ;
144
159
}
145
160
public Control Draw ( controlProperty p )
146
161
{
147
162
Control controlToSet = null ;
163
+
164
+ if ( p . info . CanRead == false ) return null ;
165
+
148
166
var val = p . info . GetValue ( obj , null ) ;
149
167
Type type = null ;
150
168
if ( val != null )
151
169
type = val . GetType ( ) ;
170
+ else
171
+ {
172
+ Editor . Label ( p . info . Name , "null" ) ;
173
+ return null ;
174
+ }
152
175
153
176
// Array & List.
154
177
if ( val is string == false )
155
- if ( ( type != null && type . IsArray ) || val is IEnumerable )
178
+ if ( type . IsArray || val is IEnumerable )
156
179
{
157
- Editor . BeginVertical ( "Box" ) ;
180
+ Editor . BeginVertical ( ) ;
158
181
p . expanded = Editor . Foldout ( p . info . Name , p . expanded ) ;
159
182
if ( p . expanded )
160
183
{
@@ -170,10 +193,16 @@ public Control Draw(controlProperty p)
170
193
}
171
194
else
172
195
{
173
- if ( p . editor == null )
174
- p . editor = new objectEditor ( e , arrayIndex . ToString ( ) ) ;
175
-
176
- p . editor . Draw ( ) ;
196
+ if ( arrayIndex >= p . arrayEditors . Count )
197
+ {
198
+ var aEditor = new objectEditor ( e , arrayIndex . ToString ( ) ) ;
199
+ aEditor . rgb = rgb - 25 ;
200
+ if ( aEditor . rgb < 128 )
201
+ aEditor . rgb = 128 ;
202
+ p . arrayEditors . Add ( aEditor ) ;
203
+ }
204
+
205
+ p . arrayEditors [ arrayIndex ] . Draw ( ) ;
177
206
}
178
207
arrayIndex ++ ;
179
208
}
@@ -183,16 +212,20 @@ public Control Draw(controlProperty p)
183
212
}
184
213
185
214
// If there is no Set() method then skip.
215
+ var canSet = true ;
186
216
var pSetMethod = p . info . GetSetMethod ( true ) ;
187
217
if ( pSetMethod == null || pSetMethod . IsPrivate )
188
- {
189
- Editor . Label ( p . info . Name , val ) ;
190
- return null ;
191
- }
218
+ canSet = false ;
192
219
193
220
// Other editors.
194
221
if ( val is bool )
195
222
{
223
+ if ( canSet == false )
224
+ {
225
+ Editor . Label ( p . info . Name , val ) ;
226
+ return null ;
227
+ }
228
+
196
229
var bVal = ( bool ) val ;
197
230
var ebVal = Editor . BooleanField ( p . info . Name , bVal ) ;
198
231
if ( ebVal . Changed )
@@ -206,37 +239,86 @@ public Control Draw(controlProperty p)
206
239
}
207
240
else if ( val is Color )
208
241
{
242
+ if ( canSet == false )
243
+ {
244
+ Editor . Label ( p . info . Name , val ) ;
245
+ return null ;
246
+ }
247
+
209
248
var colorVal = ( Color ) val ;
210
249
Editor . ColorField ( p . info . Name , colorVal , c => p . info . SetValue ( obj , c , null ) ) ;
211
250
}
212
251
else if ( val is string )
213
252
{
253
+ if ( canSet == false )
254
+ {
255
+ Editor . Label ( p . info . Name , val ) ;
256
+ return null ;
257
+ }
258
+
214
259
var stringtVal = ( string ) val ;
215
260
var esVal = Editor . TextField ( p . info . Name , stringtVal ) ;
216
261
if ( esVal . Changed )
217
262
p . info . SetValue ( obj , esVal . Value , null ) ;
218
263
}
219
264
else if ( val is int )
220
265
{
221
- var eiVal = Editor . IntField ( p . info . Name , ( int ) val ) ;
266
+ if ( canSet == false )
267
+ {
268
+ Editor . Label ( p . info . Name , val ) ;
269
+ return null ;
270
+ }
271
+
272
+ var eiVal = Editor . IntField ( p . info . Name , ( int ) val ) ;
222
273
if ( eiVal . Changed )
223
274
p . info . SetValue ( obj , eiVal . Value [ 0 ] , null ) ;
224
275
}
225
276
else if ( val is byte || val is sbyte || val is short || val is ushort || val is uint || val is long || val is ulong || val is float || val is double )
226
277
{
278
+ if ( canSet == false )
279
+ {
280
+ Editor . Label ( p . info . Name , val ) ;
281
+ return null ;
282
+ }
283
+
227
284
// TODO: editors for common types (like for int ^up there).
228
285
Editor . Label ( p . info . Name , val ) ;
229
286
}
230
287
else if ( val is Enum )
231
288
{
232
- var eeVal = Editor . EnumField ( p . info . Name , ( Enum ) val ) ;
233
- if ( eeVal . Changed )
234
- p . info . SetValue ( obj , eeVal . Value , null ) ;
289
+ if ( canSet == false )
290
+ {
291
+ Editor . Label ( p . info . Name , val ) ;
292
+ return null ;
293
+ }
294
+
295
+ var enumHasFlagAttribute = val . GetType ( ) . GetCustomAttributes ( typeof ( FlagsAttribute ) , false ) . Length > 0 ;
296
+ var enumOptions = Enum . GetNames ( val . GetType ( ) ) ;
297
+
298
+ if ( enumHasFlagAttribute )
299
+ {
300
+ // TODO: not gonna work with 'None' flag.
301
+ // https://forum.unity3d.com/threads/editorguilayout-enummaskfield-doesnt-use-enums-values.233332/
302
+ var eeVal = Editor . MaskField ( p . info . Name , Convert . ToInt32 ( val ) , enumOptions ) ;
303
+ if ( eeVal . Changed )
304
+ p . info . SetValue ( obj , eeVal . Value , null ) ;
305
+ }
306
+ else
307
+ {
308
+ var eeVal = Editor . EnumField ( p . info . Name , ( Enum ) val ) ;
309
+ if ( eeVal . Changed )
310
+ p . info . SetValue ( obj , eeVal . Value , null ) ;
311
+ }
235
312
}
236
313
else if ( val != null )
237
314
{
238
315
if ( p . editor == null )
316
+ {
239
317
p . editor = new objectEditor ( val , p . info . Name ) ;
318
+ p . editor . rgb = rgb - 25 ;
319
+ if ( p . editor . rgb < 128 )
320
+ p . editor . rgb = 128 ;
321
+ }
240
322
241
323
p . editor . Draw ( ) ;
242
324
}
0 commit comments