@@ -10,8 +10,7 @@ namespace System.Windows.Forms.Design
1010{
1111 public class ControlDesigner : IControlDesigner
1212 {
13- private objectEditor editor ;
14- private bool toggleEditor = true ;
13+ private readonly objectEditor editor ;
1514
1615 public Control Control { get ; set ; }
1716
@@ -29,6 +28,7 @@ public virtual object Draw(int width, int height)
2928
3029 Control controlToSet = null ;
3130
31+ Editor . SetBackColor ( Color . White ) ;
3232 Editor . BeginGroup ( width - 24 , "" ) ;
3333
3434 controlToSet = editor . Draw ( ) ;
@@ -40,6 +40,7 @@ public virtual object Draw(int width, int height)
4040
4141 private class controlProperty
4242 {
43+ public readonly List < objectEditor > arrayEditors = new List < objectEditor > ( ) ;
4344 public objectEditor editor ;
4445 public bool expanded ;
4546 public PropertyInfo info ;
@@ -51,6 +52,7 @@ private class objectEditor
5152 private readonly object obj ;
5253 private readonly List < controlProperty > props ;
5354 private readonly string name ;
55+ private int rgb = 255 ;
5456
5557 public bool toggleEditor ;
5658
@@ -67,6 +69,9 @@ public objectEditor(object o, string objName)
6769 for ( int i = 0 ; i < pList . Count ; i ++ )
6870 {
6971 var p = pList [ i ] ;
72+ if ( p . DeclaringType == typeof ( Delegate ) ) continue ;
73+ if ( p . Name == "Item" ) continue ; // this[] will throw an exception.
74+
7075 var cp = new controlProperty ( )
7176 {
7277 info = p ,
@@ -99,13 +104,15 @@ public Control Draw()
99104 return null ;
100105 }
101106
102- Editor . BeginVertical ( "Box" ) ;
103107 toggleEditor = Editor . Foldout ( name , toggleEditor ) ;
108+ var style = toggleEditor ? "Box" : null ;
109+ Editor . BeginVertical ( style ) ;
104110 if ( toggleEditor )
105111 {
106112 // Fields.
107113 if ( fields . Count > 0 )
108114 {
115+ Editor . SetBackColor ( Color . AliceBlue ) ;
109116 Editor . BeginVertical ( "Box" ) ;
110117 for ( int i = 0 ; i < fields . Count ; i ++ )
111118 {
@@ -119,6 +126,9 @@ public Control Draw()
119126 }
120127
121128 // Properties.
129+ Editor . SetBackColor ( Color . White ) ;
130+ if ( toggleEditor )
131+ Editor . SetBackColor ( Color . FromArgb ( rgb , rgb , rgb ) ) ;
122132 for ( int i = 0 ; i < props . Count ; i ++ )
123133 {
124134 var tc = Draw ( props [ i ] ) ;
@@ -127,6 +137,7 @@ public Control Draw()
127137 }
128138
129139 // Methods.
140+ Editor . SetBackColor ( Color . White ) ;
130141 if ( methods . Count > 0 )
131142 {
132143 Editor . NewLine ( 1 ) ;
@@ -140,21 +151,33 @@ public Control Draw()
140151 }
141152 }
142153 Editor . EndVertical ( ) ;
154+
155+ if ( toggleEditor )
156+ Editor . NewLine ( 1 ) ;
157+
143158 return control ;
144159 }
145160 public Control Draw ( controlProperty p )
146161 {
147162 Control controlToSet = null ;
163+
164+ if ( p . info . CanRead == false ) return null ;
165+
148166 var val = p . info . GetValue ( obj , null ) ;
149167 Type type = null ;
150168 if ( val != null )
151169 type = val . GetType ( ) ;
170+ else
171+ {
172+ Editor . Label ( p . info . Name , "null" ) ;
173+ return null ;
174+ }
152175
153176 // Array & List.
154177 if ( val is string == false )
155- if ( ( type != null && type . IsArray ) || val is IEnumerable )
178+ if ( type . IsArray || val is IEnumerable )
156179 {
157- Editor . BeginVertical ( "Box" ) ;
180+ Editor . BeginVertical ( ) ;
158181 p . expanded = Editor . Foldout ( p . info . Name , p . expanded ) ;
159182 if ( p . expanded )
160183 {
@@ -170,10 +193,16 @@ public Control Draw(controlProperty p)
170193 }
171194 else
172195 {
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 ( ) ;
177206 }
178207 arrayIndex ++ ;
179208 }
@@ -183,16 +212,20 @@ public Control Draw(controlProperty p)
183212 }
184213
185214 // If there is no Set() method then skip.
215+ var canSet = true ;
186216 var pSetMethod = p . info . GetSetMethod ( true ) ;
187217 if ( pSetMethod == null || pSetMethod . IsPrivate )
188- {
189- Editor . Label ( p . info . Name , val ) ;
190- return null ;
191- }
218+ canSet = false ;
192219
193220 // Other editors.
194221 if ( val is bool )
195222 {
223+ if ( canSet == false )
224+ {
225+ Editor . Label ( p . info . Name , val ) ;
226+ return null ;
227+ }
228+
196229 var bVal = ( bool ) val ;
197230 var ebVal = Editor . BooleanField ( p . info . Name , bVal ) ;
198231 if ( ebVal . Changed )
@@ -206,37 +239,86 @@ public Control Draw(controlProperty p)
206239 }
207240 else if ( val is Color )
208241 {
242+ if ( canSet == false )
243+ {
244+ Editor . Label ( p . info . Name , val ) ;
245+ return null ;
246+ }
247+
209248 var colorVal = ( Color ) val ;
210249 Editor . ColorField ( p . info . Name , colorVal , c => p . info . SetValue ( obj , c , null ) ) ;
211250 }
212251 else if ( val is string )
213252 {
253+ if ( canSet == false )
254+ {
255+ Editor . Label ( p . info . Name , val ) ;
256+ return null ;
257+ }
258+
214259 var stringtVal = ( string ) val ;
215260 var esVal = Editor . TextField ( p . info . Name , stringtVal ) ;
216261 if ( esVal . Changed )
217262 p . info . SetValue ( obj , esVal . Value , null ) ;
218263 }
219264 else if ( val is int )
220265 {
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 ) ;
222273 if ( eiVal . Changed )
223274 p . info . SetValue ( obj , eiVal . Value [ 0 ] , null ) ;
224275 }
225276 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 )
226277 {
278+ if ( canSet == false )
279+ {
280+ Editor . Label ( p . info . Name , val ) ;
281+ return null ;
282+ }
283+
227284 // TODO: editors for common types (like for int ^up there).
228285 Editor . Label ( p . info . Name , val ) ;
229286 }
230287 else if ( val is Enum )
231288 {
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+ }
235312 }
236313 else if ( val != null )
237314 {
238315 if ( p . editor == null )
316+ {
239317 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+ }
240322
241323 p . editor . Draw ( ) ;
242324 }
0 commit comments