Fix #7250 - better handling of adding properties
[roobuilder] / src / JsRender / NodeProp.vala
1 /**
2
3 This is a replacement for our key/value 
4 events and properties
5
6  
7 */ 
8 public enum JsRender.NodePropType 
9 {
10         
11         NONE, // fake value - used in popoveraddprop.
12         CTOR, // not used exetp getProperties for?
13         
14         
15         // these are all stored as properties, and should not overlap.
16         PROP,
17         
18         RAW,
19         METHOD,
20         SIGNAL,
21                 
22         // in theory we could have user defined properties that overlap - but probably not a good idea.
23         USER,
24
25
26         
27         // specials - these should be in a seperate list?
28         SPECIAL,
29
30
31         
32         // listerens can definatly overlap as they are stored in a seperate list. << no need to use this for listeners?
33         LISTENER;
34         
35
36         
37         public static string to_abbr(NodePropType intype)
38         {
39                 switch(intype) {
40                         case PROP: return  "";
41                         case RAW: return "$";
42                         case METHOD : return  "|";      
43                         case SIGNAL : return  "@"; // vala signal
44                         case USER : return  "#"; // user defined.
45                         case SPECIAL : return  "*"; // * prop| args | ctor | init
46                         case LISTENER : return  "";  // always raw...
47                         // not used
48                         case NONE:
49                         case CTOR:
50                                  return "";
51                         
52                 }
53                 return "??";
54         }
55         
56         // only usefull for reall values.
57         public static NodePropType from_string(string str)
58         {
59                 switch(str) {
60                         //case "" : return PROP;
61                         case "$": return  RAW;
62                         case "|": return METHOD;
63                         case "@": return  SIGNAL;
64                         case "#": return USER;
65                         case "*": return SPECIAL;
66                         //case "": return case LISTENER : return  ""  // always raw...
67                 }
68                 return PROP;
69         
70         }
71         
72 }
73
74
75
76 public class JsRender.NodeProp : Object {
77
78
79
80         public string name  = "";
81         public NodePropType ptype;  
82         public string rtype = ""; // return or type
83         public string val = "";
84         public int start_line = 0;
85         public int end_line = 0;
86         
87         
88         
89         public NodeProp(string name, NodePropType ptype, string rtype, string val) {
90                 this.name = name;
91                 this.ptype = ptype;
92                 this.rtype = rtype;
93                 this.val = val;
94         }
95         
96         public NodeProp.from_json(string key, string inval)
97         {
98                 this.val = inval;
99                 var kkv = key.strip().split(" ");
100                 string[] kk = {};
101                 for (var i = 0; i < kkv.length; i++) {
102                         if (kkv[i].length > 0 ) {
103                                 kk += kkv[i];
104                         }
105                 }
106                 
107                 switch(kk.length) {
108                         case 1: 
109                                 this.name = kk[0];
110                                 this.ptype = NodePropType.PROP;
111                                 this.rtype = "";                
112                                 return;
113                         case 2: 
114                                 this.name = kk[1];
115                                 if (kk[0].length > 1) {
116                                         // void fred (no type)
117                                         this.rtype = kk[0];
118                                         this.ptype = NodePropType.PROP;
119                                 } else {
120                                         // has a ptype.
121                                         
122                                         this.rtype = ""; // no return type, only a ptype indicator.
123                                         this.ptype = NodePropType.from_string(kk[0]);
124                                 }
125                                 return;
126                         default: // 3 or more... (ignores spaces..)
127                         case 3:
128                                 this.name =  kk[2];
129                                 this.ptype = NodePropType.from_string(kk[0]);
130                                 this.rtype = kk[1];
131                                 return;
132                         
133                 }
134                 
135         }
136         public string  to_json_key()
137         {
138                 
139                 var ortype = this.rtype +  (this.rtype.length > 0 ? " " : "");
140                 var oabbr = NodePropType.to_abbr(this.ptype);
141                 if (oabbr.length > 0) {
142                         oabbr += " ";
143                 }
144                 switch(this.ptype) {
145                         
146
147                         case NodePropType.LISTENER : 
148                                 return this.name; 
149                                 
150                         case NodePropType.PROP:
151                                 return ortype + this.name;                      
152                         
153                         case NodePropType.RAW:
154                         case NodePropType.METHOD:
155                         case NodePropType.SIGNAL:                       
156                         case NodePropType.USER :                        
157                                 return oabbr + ortype + this.name;                      
158                                 
159
160
161                         case NodePropType.SPECIAL:                      
162                                 return oabbr +   this.name;
163                         case NodePropType.NONE: // not used
164                         case NodePropType.CTOR:
165                                  return "";
166                         
167                         
168                 }
169                 return this.name;
170         }
171         
172         
173         public string  to_index_key()
174         {
175                 switch(this.ptype) {
176                         case NodePropType.PROP:
177                         case NodePropType.RAW:
178                         case NodePropType.METHOD :
179                         case NodePropType.SIGNAL :
180                         case NodePropType.USER : 
181                                 return this.name;
182                         
183                         case NodePropType.SPECIAL : 
184                                 return "* " + this.name;
185                                 
186                         // in seperate list..
187                         case NodePropType.LISTENER : 
188                                 return  this.name;
189                                 
190                         case NodePropType.NONE: // not used
191                         case NodePropType.CTOR:
192                                  return "";
193
194                                 
195                 }
196                 return this.name;
197         
198         }
199         // how it appears on the property list. -- 
200         public string to_display_name()
201         {
202                 
203                 //return (this.rtype.length > 0 ? this.rtype + " " : "") +  this.name;
204                 // before we showed "@" for signals
205                 switch(this.ptype) {
206                         case NodePropType.PROP:
207                                 return  this.name;
208                                 
209                         case NodePropType.RAW:
210                                 return "<span style=\"italic\">" + GLib.Markup.escape_text(this.name) + "</span>";
211                                 
212                         case NodePropType.METHOD :
213                                 return "<i>" + GLib.Markup.escape_text(this.rtype)  + "</i> <span color=\"#008000\" font_weight=\"bold\">" + GLib.Markup.escape_text( this.name) + "</span>";
214                                 
215                         case NodePropType.SIGNAL : // purpley
216                                 return "<span   color=\"#ea00d6\" font_weight=\"bold\">" + GLib.Markup.escape_text(this.name)+ "</span>";
217                                 
218                         case NodePropType.USER : 
219                                 return  "<i>" + GLib.Markup.escape_text(this.rtype)  + "</i> <span  font_weight=\"bold\">" + GLib.Markup.escape_text(this.name) + "</span>";
220                         
221                         case NodePropType.SPECIAL : 
222                                 return "<span   color=\"#0000CC\" font_weight=\"bold\">" + GLib.Markup.escape_text(this.name) + "</span>";       
223                                 
224                         // in seperate list..
225                         case NodePropType.LISTENER : 
226                                 return  "<b>" + this.name + "</b>";
227                                 
228                         case NodePropType.NONE: // not used
229                         case NodePropType.CTOR:
230                                  return "";
231                 
232                                 
233                 }
234                 return this.name;
235         }
236         
237         // used ot sort the dispaly list of properties.
238         public string to_sort_key()
239         {
240                 var n = this.name;
241                  
242                 //return (this.rtype.length > 0 ? this.rtype + " " : "") +  this.name;
243                 // before we showed "@" for signals
244                 switch(this.ptype) {
245                         case NodePropType.PROP:
246                                 return "5" +  n;
247                                 
248                         case NodePropType.RAW:
249                                 return "5" +  n;
250                                 
251                         case NodePropType.METHOD :
252                                 return "2" +  n;
253                                 
254                         case NodePropType.SIGNAL :
255                                 return "3" +  n;
256                                 
257                         case NodePropType.USER : 
258                                 return "4" +  n;
259                         
260                         case NodePropType.SPECIAL : 
261                                 return "1" +  n;
262                                 
263                         // in seperate list..
264                         case NodePropType.LISTENER : 
265                                 return  "0" + this.name;
266                         
267                         case NodePropType.NONE: // not used
268                         case NodePropType.CTOR:
269                                  return "";
270                                 
271                 }
272                 return this.name;
273         }
274         
275         
276         
277         
278         
279         public string to_tooltip()
280         {
281                  
282                 switch(this.ptype) {
283                         case NodePropType.PROP:
284                                 return this.rtype + " " + this.name + " = \"" + this.val + "\"";
285                         case NodePropType.LISTENER : 
286                                 // thsi might look a bit odd on javascript?
287                                 return "on " + this.name + " " + this.val;
288                                 
289                         case NodePropType.RAW:
290                                 return  this.rtype + " " + this.name + " = " + this.val;
291                         case NodePropType.METHOD :
292                                 // functions - js    FRED  function () { }  <<< could probably be cleaner..
293                                 // functions - vala    FRED () { }
294                                 return  this.rtype + " " + this.name  + " "  + this.val;
295                         case NodePropType.SIGNAL :
296                                 return  "signal: "  + this.rtype + " " + this.name  +  " " + this.val;
297                         case NodePropType.USER : 
298                                 return  "user defined: "  + this.rtype + " " + this.name  + " = "  + this.val;
299                         
300                         case NodePropType.SPECIAL:                      
301                                 return  "special property: "  + this.rtype + " " + this.name  + " = " +   this.val;                     
302
303                         case NodePropType.NONE: // not used
304                         case NodePropType.CTOR:
305                                  return "";
306                 }
307                 return this.name;
308                 
309
310         }
311         
312         public string to_property_option_markup()
313         {
314                 return "<b>" + this.name + "</b> <i>" + this.rtype + "</i>";
315         }
316         
317         public string to_property_option_tooltip()
318         {
319                 return this.to_property_option_markup(); // fixme will probaly want help info (possibly by havinga  reference to the GirObject that its created from
320         }
321         
322         
323         public bool is(NodeProp comp) {
324                 if (comp.ptype == NodePropType.LISTENER || this.ptype == NodePropType.LISTENER ) { 
325                         return comp.ptype == this.ptype && comp.name == this.name;
326                 }
327                 return comp.to_index_key() == this.to_index_key();
328         
329         }
330         
331         
332         /*
333         public NodeProp.listenerfromjson(string str, string inval)
334         {
335                 this.val = inval;
336                 this.name = str;
337                 this.ptype = NodePropType.LISTENER;
338                 this.rtype = "";
339                 
340         }
341         */
342         // regular addition - should work for properties  
343         public NodeProp.prop(string name, string rtype = "", string val = "")
344         {
345                 this(name, NodePropType.PROP, rtype, val);
346         }
347         public NodeProp.raw(string name, string rtype = "", string val = "")
348         {
349                 this(name, NodePropType.RAW, rtype, val);
350         }
351         
352         public NodeProp.valamethod(string name, string rtype = "void", string val = "() {\n\n}")
353         {
354                 this(name, NodePropType.METHOD, rtype, val);
355         }
356         public NodeProp.jsmethod(string name,  string val = "function() {\n\n}")
357         {
358                 this(name, NodePropType.METHOD, "", val);
359         }
360         
361         // vala (and js) specials.. props etc.. - they only have name/value (not type) - type is in xns/xtype
362         public NodeProp.special(string name, string val = "")
363         {
364                 this(name, NodePropType.SPECIAL, "", val);
365         }
366          
367         public NodeProp.listener(string name,   string val = "")
368         {
369                 this(name, NodePropType.LISTENER, "", val);
370         }
371          
372         public NodeProp.user(string name, string rtype = "", string val = "")
373         {
374                 this(name, NodePropType.USER, rtype, val);
375         }
376         public NodeProp.sig(string name, string rtype = "void", string val = "()")
377         {
378                 this(name, NodePropType.SIGNAL, rtype, val);
379         }
380         
381 }
382