webglade

JavaScript library to dynamically create XUL GUI from Glade XML files
git clone https://logand.com/git/webglade.git/
Log | Files | Refs | README | LICENSE

webglade.js (29062B)


      1 function member(item, lst) {
      2   if (lst) {
      3     var tmpArr1 = lst;
      4     if (tmpArr1) {
      5       for (var tmpI2 = 0; tmpI2 < tmpArr1.length; tmpI2 = tmpI2 + 1) {
      6         var i = tmpArr1[tmpI2];
      7         if (i == item) {
      8           return true;
      9         };
     10       };
     11     };
     12   };
     13 };
     14 
     15 function pop(place) {
     16   return place.pop();
     17 };
     18 
     19 function push(item, place) {
     20   place.push(item);
     21 };
     22 
     23 function pushnew(item, place) {
     24   if (!member(item, place)) {
     25     push(item, place);
     26   };
     27   return place;
     28 };
     29 
     30 function object2alist(obj) {
     31   if (obj && 'object' == typeof obj && !obj.length) {
     32     var result = [  ];
     33     for (var i in obj) {
     34       push(cons(i, obj[i]), result);
     35     };
     36     return result;
     37   };
     38 };
     39 
     40 function copySeq(seq) {
     41   if (seq) {
     42     var result = [  ];
     43     {
     44       var tmpArr3 = seq;
     45       if (tmpArr3) {
     46         for (var tmpI4 = 0; tmpI4 < tmpArr3.length; tmpI4 = tmpI4 + 1) {
     47           var i = tmpArr3[tmpI4];
     48           push(i, result);
     49         };
     50       };
     51     };
     52     return result;
     53   };
     54 };
     55 
     56 function nreverse(seq) {
     57   if (seq) {
     58     return seq.reverse();
     59   };
     60 };
     61 
     62 function reverse(seq) {
     63   return nreverse(copySeq(seq));
     64 };
     65 
     66 function sort(sequence, predicate) {
     67   sequence.sort(function (x, y) {
     68                   return predicate(x, y) ? -1 : 1;
     69                 });
     70   return sequence;
     71 };
     72 
     73 var ns =
     74     { 'xul' : 'http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul', 
     75       'html' : 'http://www.w3.org/1999/xhtml' };
     76 
     77 function wget(id, doc) {
     78   return doc ? doc.getElementById(id) : document.getElementById(id);
     79 };
     80 
     81 var WHANDLER = {  };
     82 
     83 function whandler(sig) {
     84   if (sig) {
     85     var h = WHANDLER[sig];
     86     if (h) {
     87       return h;
     88     } else {
     89       return function (e) {
     90           alert('Unhandled event ' + sig + '.');
     91         };
     92     };
     93   };
     94 };
     95 
     96 function wgetp(w, prop) {
     97   return w[prop];
     98 };
     99 
    100 function wsetp(w, prop, value) {
    101   w.setAttribute(prop, value);
    102   return value;
    103 };
    104 
    105 function wgets(w, style) {
    106   return w.style[style];
    107 };
    108 
    109 function wsets(w, style, value) {
    110   w.style[style] = value;
    111   return value;
    112 };
    113 
    114 function wsete(w, event, handler, useCapture) {
    115   w.addEventListener(event, handler, useCapture ? true : false);
    116 };
    117 
    118 function wunsete(w, event, handler, useCapture) {
    119   w.removeEventListener(event, handler, useCapture ? true : false);
    120 };
    121 
    122 function wmake(pw, tag, props, sigs) {
    123   if (tag == 'string') {
    124     var w = document.createTextNode(props);
    125     if (pw) {
    126       pw.appendChild(w);
    127     };
    128     return w;
    129   } else {
    130     var w =
    131         tag.match('^xul:') ?
    132           document.createElementNS(ns.xul, tag.substring(4)) :
    133           document.createElementNS(ns.html, tag);
    134     if (pw) {
    135       pw.appendChild(w);
    136     };
    137     if (props) {
    138       for (var i in props) {
    139         if (undefined != props[i]) {
    140           wsetp(w, i, props[i]);
    141         };
    142       };
    143     };
    144     if (sigs) {
    145       for (var i in sigs) {
    146         if (undefined != sigs[i]) {
    147           wsete(w, i, whandler(sigs[i]));
    148         };
    149       };
    150     };
    151     return w;
    152   };
    153 };
    154 
    155 function wadda(w, child) {
    156   w.firstChild().insertBefore(child);
    157   return child;
    158 };
    159 
    160 function waddz(w, child) {
    161   w.appendChild(child);
    162   return child;
    163 };
    164 
    165 function wreplace(w, ow, nw) {
    166   w.replaceChild(nw, ow);
    167   return nw;
    168 };
    169 
    170 function wshow(w) {
    171   wsets(w, 'visibility', 'visible');
    172   wsets(w, 'display', '');
    173 };
    174 
    175 function whide(w) {
    176   wsets(w, 'visibility', 'hidden');
    177   wsets(w, 'display', 'none');
    178 };
    179 
    180 function changeVisibility(w, show) {
    181   if (show) {
    182     wshow(w);
    183   } else {
    184     whide(w);
    185   };
    186 };
    187 
    188 function toggleVisibility(w) {
    189   if ('hidden' == wgets(w, 'visibility')) {
    190     wshow(w);
    191   } else {
    192     whide(w);
    193   };
    194 };
    195 
    196 function wempty(w) {
    197   if (w.hasChildNodes()) {
    198     var tmpArr5 = w.childNodes;
    199     if (tmpArr5) {
    200       for (var tmpI6 = 0; tmpI6 < tmpArr5.length; tmpI6 = tmpI6 + 1) {
    201         var child = tmpArr5[tmpI6];
    202         w.removeChild(child);
    203       };
    204     };
    205   };
    206 };
    207 
    208 function wremove(w) {
    209   w.parentNode.removeChild(w);
    210 };
    211 
    212 function xmlToString(doc) {
    213   var s = new XMLSerializer();
    214   return s.serializeToString(doc);
    215 };
    216 
    217 function loadXml(url, callback) {
    218   if (window.ActiveXObject) {
    219     var doc = new ActiveXObject('Microsoft.XMLDOM');
    220     doc.async = false;
    221     doc.load(url);
    222     callback(doc);
    223   } else {
    224     if (document.implementation && document.implementation.createDocument) {
    225       var doc = document.implementation.createDocument('', '', null);
    226       doc.onload =
    227       function () {
    228         callback(doc);
    229       };
    230       doc.load(url);
    231     } else {
    232       alert('Your browser cannot handle this script.');
    233     };
    234   };
    235 };
    236 
    237 var WBUILD = {  };
    238 
    239 var WPACK = {  };
    240 
    241 
    242 // ECS add GTK stock_id support
    243 var stock_id = {  };
    244 stock_names = new Array("open","close","about","undo","redo","cut","copy","paste","save")
    245 
    246 for (x in stock_names) {
    247     var id =stock_names[x];
    248     stock_id['gtk-'+id]={label : 'Open'};
    249 }
    250 
    251 function stock_id_get_label(id) {
    252     //label = stock_id[id]["label"];
    253     label = id[4].toUpperCase()+id.substring(5).replace('-',' ');
    254     return label;
    255 };
    256 
    257 function stock_id_get_icon(id) {
    258     //label = stock_id[id]["icon"];
    259     label = 'gtk_stock/' + id + '.png';
    260     return label;
    261 };
    262 
    263 function wclass(widget) {
    264   if (widget.class == 'Custom') {
    265     return getProperty(widget, 'creation_function');
    266   } else {
    267     return widget.class;
    268   };
    269 };
    270 
    271 
    272 // ECS adding support for GtkBuilder (incomplete)
    273 function parseGlade(glade) {
    274   var widgets = {  };
    275   {
    276     var attrs =
    277         function (node) {
    278           var name = node.getAttribute('name');
    279           var value =
    280               node.childNodes[0] ? node.childNodes[0].nodeValue : undefined;
    281           var result = { name : name };
    282           if (value) {
    283             result.value = value;
    284           };
    285           {
    286             var tmpArr7 = node.attributes;
    287             if (tmpArr7) {
    288               for (var tmpI8 = 0; tmpI8 < tmpArr7.length;
    289                    tmpI8 = tmpI8 + 1) {
    290                 var a = tmpArr7[tmpI8];
    291                 result[a.nodeName] = a.nodeValue;
    292               };
    293             };
    294           };
    295           return result;
    296         };
    297     var recWidget =
    298         function (parent, node) {
    299           var id = node.getAttribute('id');
    300           var class = node.getAttribute('class');
    301           var widget =
    302               { id : id, 
    303                 parent : parent, 
    304                 children : [  ], 
    305                 class : class, 
    306                 property : {  }, 
    307                 signal : {  }, 
    308                 packing : {  } };
    309           if (parent) {
    310             pushnew(widget, parent.children);
    311           };
    312           widgets[id] = widget;
    313           rec(widget, node.childNodes);
    314           return widget;
    315         };
    316     var recChild =
    317         function (parent, node) {
    318           var current = null;
    319           var tmpArr9 = node.childNodes;
    320           if (tmpArr9) {
    321             for (var tmpI10 = 0; tmpI10 < tmpArr9.length;
    322                  tmpI10 = tmpI10 + 1) {
    323               var child = tmpArr9[tmpI10];
    324               switch (child.tagName) {
    325                 case 'widget':
    326                    current = recWidget(parent, child);
    327                    break;
    328                 case 'object': // GTKBuilder same as widget
    329                    current = recWidget(parent, child);
    330                    break;
    331                 case 'packing':   recPacking(parent, child, current);
    332               };
    333             };
    334           };
    335         };
    336     var recProperty =
    337         function (parent, node) {
    338           var as = attrs(node);
    339           parent.property[as.name] = as;
    340         };
    341     var recSignal =
    342         function (parent, node) {
    343           var as = attrs(node);
    344           parent.signal[as.name] = as;
    345         };
    346     var recPacking =
    347         function (parent, node, current) {
    348           var tmpArr11 = node.childNodes;
    349           if (tmpArr11) {
    350             for (var tmpI12 = 0; tmpI12 < tmpArr11.length;
    351                  tmpI12 = tmpI12 + 1) {
    352               var child = tmpArr11[tmpI12];
    353               if ('property' == child.tagName) {
    354                 var as = attrs(child);
    355                 current.packing[as.name] = as;
    356               };
    357             };
    358           };
    359         };
    360     var rec =
    361         function (parent, nodes, current) {
    362           var tmpArr13 = nodes;
    363           if (tmpArr13) {
    364             for (var tmpI14 = 0; tmpI14 < tmpArr13.length;
    365                  tmpI14 = tmpI14 + 1) {
    366               var node = tmpArr13[tmpI14];
    367               switch (node.tagName) {
    368                 case 'glade-interface':
    369                    rec(parent, node.childNodes);
    370                    break;
    371                 case 'interface':  // GTKBuilder same as widget
    372                    rec(parent, node.childNodes);
    373                    break;
    374                 case 'widget':
    375                    recWidget(parent, node);
    376                    break;
    377                 case 'object': // GTKBuilder same as widget
    378                    recWidget(parent, node);
    379                    break;
    380                 case 'child':
    381                    recChild(parent, node);
    382                    break;
    383                 case 'property':
    384                    recProperty(parent, node);
    385                    break;
    386                 case 'signal':
    387                    recSignal(parent, node);
    388                    break;
    389                 case 'packing':   recPacking(parent, node, current);
    390               };
    391             };
    392           };
    393         };
    394     rec(null, [ glade.documentElement ]);
    395   };
    396   return widgets;
    397 };
    398 
    399 function wbuild(pw, widgets) {
    400   var result = null;
    401   {
    402     var tmpArr15 = widgets;
    403     if (tmpArr15) {
    404       for (var tmpI16 = 0; tmpI16 < tmpArr15.length; tmpI16 = tmpI16 + 1) {
    405         var widget = tmpArr15[tmpI16];
    406         var fbuild = WBUILD[wclass(widget)];
    407         var fpack =
    408             widget && widget.parent ? WPACK[wclass(widget.parent)] :
    409               undefined;
    410         var w =
    411             fbuild ? fbuild(pw, widget) :
    412               wmake
    413               (pw, 'string', '{ ' + wclass(widget) + ' not implemented! }');
    414         if (fpack) {
    415           fpack(pw, w, widget);
    416         };
    417         result = w;
    418       };
    419     };
    420   };
    421   return result;
    422 };
    423 
    424 function getProperty(widget, name) {
    425   var it = widget.property[name];
    426   if (it) {
    427     return it.value;
    428   };
    429 };
    430 
    431 function getSignal(widget, name) {
    432   var it = widget.signal[name];
    433   if (it) {
    434     return it.handler;
    435   };
    436 };
    437 
    438 function getPacking(widget, name) {
    439   var it = widget.packing[name];
    440   if (it) {
    441     return it.value;
    442   };
    443 };
    444 
    445 WBUILD['GtkWindow'] =
    446 function (pw, self) {
    447   var title = getProperty(self, 'title');
    448   if ('window' == pw.tagName) {
    449     wsetp(pw, 'id', self.id);
    450     wsetp(pw, 'title', title);
    451     wbuild(pw, self.children);
    452     return pw;
    453   } else {
    454     var w =
    455         wmake
    456         (pw, 'xul:window',
    457          { id : self.id, 
    458            title : title });
    459     wbuild(w, self.children);
    460     return w;
    461   };
    462 };
    463 
    464 WPACK['GtkWindow'] =
    465 function (pw, w, self) {
    466   var resizable = 'True' == getProperty(self.parent, 'resizable');
    467   if (resizable) {
    468     wsetp(w, 'flex', 1);
    469   };
    470 };
    471 
    472 WBUILD['GtkDialog'] =
    473 function (pw, self) {
    474   return WBUILD['GtkWindow'](pw, self);
    475 };
    476 
    477 WPACK['GtkDialog'] =
    478 function (pw, w, self) {
    479   return WPACK['GtkWindow'](pw, w, self);
    480 };
    481 
    482 WBUILD['GtkButton'] =
    483 function (pw, self) {
    484   var tooltip = getProperty(self, 'tooltip');
    485   var label = getProperty(self, 'label');
    486   var sensitive = getProperty(self, 'sensitive');
    487   var clicked = getSignal(self, 'clicked');
    488   var w =
    489       wmake
    490       (pw, 'xul:button',
    491        { id : self.id, 
    492          tooltip : tooltip, 
    493          disabled : 'False' == sensitive, 
    494          label : label },
    495        { command : clicked });
    496   wbuild(w, self.children);
    497   return w;
    498 };
    499 
    500 WBUILD['GtkCheckButton'] =
    501 function (pw, self) {
    502   var active = getProperty(self, 'active');
    503   var label = getProperty(self, 'label');
    504   var toggled = getSignal(self, 'toggled');
    505   return wmake
    506     (pw, 'xul:checkbox',
    507      { id : self.id, 
    508        checked : active ? true : undefined, 
    509        label : label },
    510      { command : toggled });
    511 };
    512 
    513 WBUILD['GtkLabel'] =
    514 function (pw, self) {
    515   var label = getProperty(self, 'label');
    516   return wmake
    517     (pw, 'xul:label',
    518      { id : self.id, 
    519        value : label });
    520 };
    521 
    522 WBUILD['GtkEntry'] =
    523 function (pw, self) {
    524   var text = getProperty(self, 'text');
    525   var tooltip = getProperty(self, 'tooltip');
    526   var editable = getProperty(self, 'editable');
    527   var changed = getSignal(self, 'changed');
    528   return wmake
    529     (pw, 'xul:textbox',
    530      { id : self.id, 
    531        value : text, 
    532        tooltip : tooltip, 
    533        readonly : 'False' == editable ? true : undefined },
    534      { change : changed });
    535 };
    536 WPACK['GtkEntryCompletion'] =
    537 function (pw, w, self) {
    538   return WPACK['GtkEntry'](pw, w, self);
    539 };
    540 
    541 WBUILD['GtkTextView'] =
    542 function (pw, self) {
    543   var text = getProperty(self, 'text');
    544   var tooltip = getProperty(self, 'tooltip');
    545   var editable = getProperty(self, 'editable');
    546   var changed = getSignal(self, 'changed');
    547   return wmake
    548     (pw, 'xul:textbox',
    549      { id : self.id, 
    550        value : text, 
    551        tooltip : tooltip, 
    552        readonly : 'False' == editable ? true : undefined, 
    553        multiline : true },
    554      { change : changed });
    555 };
    556 
    557 WBUILD['GtkFrame'] =
    558 function (pw, self) {
    559   var w = wmake(pw, 'xul:groupbox', { id : self.id });
    560   var w2 = wmake(w, 'xul:caption');
    561   var label = [  ];
    562   var body = [  ];
    563   {
    564     var tmpArr17 = self.children;
    565     if (tmpArr17) {
    566       for (var tmpI18 = 0; tmpI18 < tmpArr17.length; tmpI18 = tmpI18 + 1) {
    567         var child = tmpArr17[tmpI18];
    568         if ('label_item' == getPacking(child, 'type')) {
    569           push(child, label);
    570         } else {
    571           push(child, body);
    572         };
    573       };
    574     };
    575   };
    576   wbuild(w2, label);
    577   wbuild(w, body);
    578 };
    579 
    580 // ECS added based on GtkFrame needs work
    581 WBUILD['GtkExpander'] =
    582 function (pw, self) {
    583   var w = wmake(pw, 'xul:groupbox', { id : self.id });
    584   var w2 = wmake(w, 'xul:caption');
    585   var label = [  ];
    586   var body = [  ];
    587   {
    588     var tmpArr17 = self.children;
    589     if (tmpArr17) {
    590       for (var tmpI18 = 0; tmpI18 < tmpArr17.length; tmpI18 = tmpI18 + 1) {
    591         var child = tmpArr17[tmpI18];
    592         if ('label_item' == getPacking(child, 'type')) {
    593           push(child, label);
    594         } else {
    595           push(child, body);
    596         };
    597       };
    598     };
    599   };
    600   wbuild(w2, label);
    601   wbuild(w, body);
    602 };
    603 
    604 // ECS added based on GTKFrame
    605 WBUILD['GtkViewport'] =
    606 function (pw, self) {
    607   var w = wmake(pw, 'xul:groupbox', { id : self.id });
    608   var w2 = wmake(w, 'xul:caption');
    609   var label = [  ];
    610   var body = [  ];
    611   {
    612     var tmpArr17 = self.children;
    613     if (tmpArr17) {
    614       for (var tmpI18 = 0; tmpI18 < tmpArr17.length; tmpI18 = tmpI18 + 1) {
    615         var child = tmpArr17[tmpI18];
    616         if ('label_item' == getPacking(child, 'type')) {
    617           push(child, label);
    618         } else {
    619           push(child, body);
    620         };
    621       };
    622     };
    623   };
    624   wbuild(w2, label);
    625   wbuild(w, body);
    626 };
    627 
    628 WBUILD['GtkAlignment'] =
    629 function (pw, self) {
    630   wbuild(pw, self.children);
    631 };
    632 
    633 WBUILD['GtkComboBox'] =
    634 function (pw, self) {
    635   var items = getProperty(self, 'items');
    636   var changed = getSignal(self, 'changed');
    637   var w =
    638       wmake(null, 'xul:menulist', { id : self.id }, { command : changed });
    639   var w2 = wmake(w, 'xul:menupopup');
    640   var n = 0;
    641   if (items) {
    642     var tmpArr19 = items.split('\n');
    643     if (tmpArr19) {
    644       for (var tmpI20 = 0; tmpI20 < tmpArr19.length;
    645            tmpI20 = tmpI20 + 1) {
    646         var item = tmpArr19[tmpI20];
    647         {
    648           var pair = item.split('|');
    649           wmake
    650           (w2, 'xul:menuitem',
    651            { value : pair[0], 
    652              label : pair[1] || pair[0] });
    653         };
    654         ++n;
    655       };
    656     };
    657   };
    658   waddz(pw, w);
    659   return w;
    660 };
    661 
    662 WBUILD['GtkMenuBar'] =
    663 function (pw, self) {
    664   var w = wmake(null, 'xul:menubar', { id : self.id });
    665   wbuild(w, self.children);
    666   waddz(pw, w);
    667   return w;
    668 };
    669 
    670 WBUILD['GtkMenu'] =
    671 function (pw, self) {
    672   var w = wmake(pw, 'xul:menupopup', { id : self.id });
    673   wbuild(w, self.children);
    674   return w;
    675 };
    676 
    677 // ECS added
    678 WBUILD['GtkMenuToolButton'] =
    679 function (pw, self) {
    680   var w = wmake(pw, 'xul:menupopup', { id : self.id });
    681   wbuild(w, self.children);
    682   return w;
    683 };
    684 
    685 WBUILD['GtkSeparatorMenuItem'] =
    686 function (pw, self) {
    687   return wmake(pw, 'xul:menuseparator', { id : self.id });
    688 };
    689 
    690 function findAccessKey(str) {
    691   var pos = str.indexOf('_');
    692   if (pos >= 0) {
    693     return str[pos + 1];
    694   };
    695 };
    696 
    697 function removeAccessKey(str) {
    698   return str.replace('_', '');
    699 };
    700 
    701 WBUILD['GtkMenuItem'] =
    702 function (pw, self) {
    703   var label = getProperty(self, 'label');
    704   var activate = getSignal(self, 'activate');
    705   if ('GtkMenuBar' == wclass(self.parent) || 0 < self.children.length) {
    706     var w =
    707         wmake
    708         (pw, 'xul:menu',
    709          { id : self.id, 
    710            label : removeAccessKey(label), 
    711            accesskey : findAccessKey(label) },
    712          { command : activate });
    713     if (0 < self.children.length) {
    714       wbuild(w, self.children);
    715     } else {
    716       wmake(w, 'xul:menupopup');
    717     };
    718     return w;
    719   } else {
    720     return wmake
    721       (pw, 'xul:menuitem',
    722        { id : self.id, 
    723          label : removeAccessKey(label), 
    724          accesskey : findAccessKey(label) },
    725        { command : activate });
    726   };
    727 };
    728 
    729 // ECS added
    730 WBUILD['GtkImageMenuItem'] =
    731 function (pw, self) {
    732   var label = getProperty(self, 'label');
    733   // ECS support gtk stock items
    734   var use_stock = getProperty(self, 'use_stock');
    735   var activate = getSignal(self, 'activate');
    736   var icon = getProperty(self, 'icon');
    737   var showLabel = true;
    738   var showImage = true;
    739   if(use_stock) {
    740     icon = stock_id_get_icon(label);
    741     label = stock_id_get_label(label);
    742   }
    743   if ('GtkMenuBar' == wclass(self.parent) || 0 < self.children.length) {
    744     var w =
    745         wmake
    746         (pw, 'xul:menu',
    747          { id : self.id, 
    748            label : removeAccessKey(label), 
    749            accesskey : findAccessKey(label) },
    750          { command : activate });
    751     if (0 < self.children.length) {
    752       wbuild(w, self.children);
    753     } else {
    754       wmake(w, 'xul:menupopup');
    755     };
    756     return w;
    757   } else {
    758     return wmake
    759       (pw, 'xul:menuitem',
    760        { id : self.id, 
    761          class : stock_id, 
    762          label : removeAccessKey(label), 
    763          image : showImage ? imageUrl(icon) : undefined, 
    764          accesskey : findAccessKey(label) },
    765        { command : activate });
    766   };
    767 };
    768 
    769 // ECS added
    770 WBUILD['GtkCheckMenuItem'] =
    771 function (pw, self) {
    772   var label = getProperty(self, 'label');
    773   // ECS support gtk stock items
    774   var use_stock = getProperty(self, 'use_stock');
    775   var activate = getSignal(self, 'activate');
    776   if(use_stock) {
    777     label = stock_id_get_label(label);
    778   }
    779   if ('GtkMenuBar' == wclass(self.parent) || 0 < self.children.length) {
    780     var w =
    781         wmake
    782         (pw, 'xul:menu',
    783          { id : self.id, 
    784            label : removeAccessKey(label), 
    785            accesskey : findAccessKey(label) },
    786          { command : activate });
    787     if (0 < self.children.length) {
    788       wbuild(w, self.children);
    789     } else {
    790       wmake(w, 'xul:menupopup');
    791     };
    792     return w;
    793   } else {
    794     return wmake
    795       (pw, 'xul:menuitem',
    796        { id : self.id, 
    797          class : stock_id, 
    798          type : "checkbox", 
    799          label : removeAccessKey(label), 
    800          accesskey : findAccessKey(label) },
    801        { command : activate });
    802   };
    803 };
    804 
    805 WBUILD['GtkHBox'] =
    806 function (pw, self) {
    807   var w =
    808       wmake
    809       (pw, 'xul:hbox',
    810        { id : self.id, 
    811          align : 'center' });
    812   wbuild(w, self.children);
    813   return w;
    814 };
    815 
    816 WPACK['GtkHBox'] =
    817 function (pw, w, self) {
    818   var padding = getPacking(self, 'padding');
    819   var expand = getPacking(self, 'expand');
    820   var fill = getPacking(self, 'fill');
    821   var pack_type = getPacking(self, 'pack_type');
    822   if ('True' == expand) {
    823     wsetp(w, 'flex', 1);
    824   };
    825 };
    826 
    827 WBUILD['GtkVBox'] =
    828 function (pw, self) {
    829   var w = wmake(pw, 'xul:vbox', { id : self.id });
    830   wbuild(w, self.children);
    831   return w;
    832 };
    833 
    834 WPACK['GtkVBox'] =
    835 function (pw, w, self) {
    836   var padding = getPacking(self, 'padding');
    837   var expand = getPacking(self, 'expand');
    838   var fill = getPacking(self, 'fill');
    839   var pack_type = getPacking(self, 'pack_type');
    840   if ('True' == expand) {
    841     wsetp(w, 'flex', 1);
    842   };
    843 };
    844 
    845 WBUILD['GtkHButtonBox'] =
    846 function (pw, self) {
    847   var w = wmake(pw, 'xul:hbox', { id : self.id });
    848   wbuild(w, self.children);
    849   return w;
    850 };
    851 
    852 WBUILD['GtkVButtonBox'] =
    853 function (pw, self) {
    854   var w = wmake(pw, 'xul:vbox', { id : self.id });
    855   wbuild(w, self.children);
    856   return w;
    857 };
    858 
    859 WBUILD['GtkHSeparator'] =
    860 function (pw, self) {
    861   return wmake
    862     (pw, 'xul:separator',
    863      { id : self.id, 
    864        orient : 'horizontal', 
    865        class : 'groove' });
    866 };
    867 
    868 WBUILD['GtkVSeparator'] =
    869 function (pw, self) {
    870   return wmake
    871     (pw, 'xul:separator',
    872      { id : self.id, 
    873        orient : 'vertical', 
    874        class : 'groove' });
    875 };
    876 
    877 WBUILD['GtkHPaned'] =
    878 function (pw, self) {
    879   var w = wmake(pw, 'xul:hbox', { id : self.id });
    880   var left = self.children[0];
    881   var right = self.children[1];
    882   wbuild(w, [ left ]);
    883   {
    884     var w2 = wmake(w, 'xul:splitter', { id : self.id + '-splitter' });
    885     wmake(w2, 'xul:grippy', { id : self.id + '-grippy' });
    886   };
    887   wbuild(w, [ right ]);
    888   return w;
    889 };
    890 
    891 WPACK['GtkHPaned'] =
    892 function (pw, w, self) {
    893   var shrink = getPacking(self, 'shrink');
    894   var resize = getPacking(self, 'resize');
    895   if ('True' == resize) {
    896     wsetp(w, 'flex', 1);
    897   };
    898 };
    899 
    900 WBUILD['GtkVPaned'] =
    901 function (pw, self) {
    902   var w = wmake(pw, 'xul:vbox', { id : self.id });
    903   var top = self.children[0];
    904   var bottom = self.children[1];
    905   wbuild(w, [ top ]);
    906   {
    907     var w2 = wmake(w, 'xul:splitter', { resizeafter : 'grow' });
    908     wmake(w2, 'xul:grippy');
    909   };
    910   wbuild(w, [ bottom ]);
    911   return w;
    912 };
    913 
    914 WPACK['GtkVPaned'] =
    915 function (pw, w, self) {
    916   var shrink = getPacking(self, 'shrink');
    917   var resize = getPacking(self, 'resize');
    918 };
    919 
    920 WBUILD['GtkNotebook'] =
    921 function (pw, self) {
    922   var tabs = [  ];
    923   var bodies = [  ];
    924   {
    925     var tmpArr21 = self.children;
    926     if (tmpArr21) {
    927       for (var tmpI22 = 0; tmpI22 < tmpArr21.length; tmpI22 = tmpI22 + 1) {
    928         var child = tmpArr21[tmpI22];
    929         if ('tab' == getPacking(child, 'type')) {
    930           push(child, tabs);
    931         } else {
    932           push(child, bodies);
    933         };
    934       };
    935     };
    936   };
    937   var w = wmake(null, 'xul:tabbox', { id : self.id });
    938   var w2 = wmake(w, 'xul:tabs');
    939   var w3 = wmake(w, 'xul:tabpanels', { flex : 1 });
    940   {
    941     var tmpArr23 = tabs;
    942     if (tmpArr23) {
    943       for (var tmpI24 = 0; tmpI24 < tmpArr23.length; tmpI24 = tmpI24 + 1) {
    944         var tab = tmpArr23[tmpI24];
    945         var w4 = wmake(w2, 'xul:tab');
    946         if ('GtkLabel' == tab.class) {
    947           wsetp(w4, 'label', tab.property.label.value);
    948         } else {
    949           wbuild(w4, [ tab ]);
    950         };
    951       };
    952     };
    953   };
    954   {
    955     var tmpArr25 = bodies;
    956     if (tmpArr25) {
    957       for (var tmpI26 = 0; tmpI26 < tmpArr25.length; tmpI26 = tmpI26 + 1) {
    958         var body = tmpArr25[tmpI26];
    959         var w5 = wmake(w3, 'xul:tabpanel');
    960         wbuild(w5, [ body ]);
    961       };
    962     };
    963   };
    964   waddz(pw, w);
    965   return w;
    966 };
    967 
    968 WPACK['GtkNotebook'] =
    969 function (pw, w, self) {
    970   var type = getPacking(self, 'type');
    971   var expand = 'True' == getPacking(self, 'tab_expand');
    972   var fill = 'True' == getPacking(self, 'tab_fill');
    973   if ('tab' != type) {
    974     wsetp(w, 'flex', 1);
    975   };
    976 };
    977 
    978 WBUILD['GtkToolbar'] =
    979 function (pw, self) {
    980   var w =
    981       wmake
    982       (pw, 'xul:toolbar',
    983        { id : self.id, 
    984          align : 'center' });
    985   wbuild(w, self.children);
    986   return w;
    987 };
    988 
    989 WPACK['GtkToolbar'] =
    990 function (pw, w, self) {
    991   var expand = getPacking(self, 'expand');
    992   var homogeneous = getPacking(self, 'homogeneous');
    993   if ('True' == expand) {
    994     wsetp(w, 'flex', 1);
    995   };
    996 };
    997 
    998 WBUILD['GtkToolItem'] =
    999 function (pw, self) {
   1000   var w = wmake(pw, 'xul:toolbaritem', { id : self.id });
   1001   wbuild(w, self.children);
   1002   return w;
   1003 };
   1004 
   1005 WBUILD['GtkSeparatorToolItem'] =
   1006 function (pw, self) {
   1007   var w = wmake(pw, 'xul:toolbarseparator', { id : self.id });
   1008   wbuild(w, self.children);
   1009   return w;
   1010 };
   1011 
   1012 function imageUrl(url) {
   1013   if (url) {
   1014     return 'images/' + url;
   1015   };
   1016 };
   1017 
   1018 WBUILD['GtkToolButton'] =
   1019 function (pw, self) {
   1020   var label = getProperty(self, 'label');
   1021   var icon = getProperty(self, 'icon');
   1022   var tooltip = getProperty(self, 'tooltip');
   1023   // ECS added stock_id support using css classes
   1024   var stock_id = getProperty(self, 'stock_id');
   1025   var clicked = getSignal(self, 'clicked');
   1026   var showLabel = true;
   1027   var showImage = true;
   1028   if(stock_id) {
   1029     label = stock_id_get_label(stock_id);
   1030     icon = stock_id_get_icon(stock_id);
   1031   }
   1032   return wmake
   1033     (pw, 'xul:toolbarbutton',
   1034      { id : self.id, 
   1035        class : stock_id, 
   1036        label : showLabel ? label : undefined, 
   1037        image : showImage ? imageUrl(icon) : undefined, 
   1038        tooltiptext : tooltip },
   1039      { command : clicked });
   1040 };
   1041 
   1042 WBUILD['GtkImage'] =
   1043 function (pw, self) {
   1044   var pixbuf = getProperty(self, 'pixbuf');
   1045   return wmake
   1046     (pw, 'xul:image',
   1047      { id : self.id, 
   1048        src : imageUrl(pixbuf) });
   1049 };
   1050 
   1051 WBUILD['GtkProgressBar'] =
   1052 function (pw, self) {
   1053   return wmake
   1054     (pw, 'xul:progressmeter',
   1055      { id : self.id, 
   1056        mode : 'determined' });
   1057 };
   1058 
   1059 WBUILD['GtkStatusbar'] =
   1060 function (pw, self) {
   1061   return wmake
   1062     (pw, 'xul:statusbarpanel',
   1063      { id : self.id, 
   1064        flex : 1 });
   1065 };
   1066 
   1067 function scan(regexp, string) {
   1068   if (string) {
   1069     return string.match(regexp);
   1070   };
   1071 };
   1072 
   1073 WBUILD['GtkTable'] =
   1074 function (pw, self) {
   1075   var nRows = getProperty(self, 'n_rows');
   1076   var nColumns = getProperty(self, 'n_columns');
   1077   var rowSpacing = getProperty(self, 'row_spacing');
   1078   var columnSpacing = getProperty(self, 'column_spacing');
   1079   var homogeneous = 'True' == getProperty(self, 'homogeneous');
   1080   var earlier =
   1081       function (x, y) {
   1082         var xleft = getPacking(x, 'left_attach');
   1083         var xright = getPacking(x, 'right_attach');
   1084         var xtop = getPacking(x, 'top_attach');
   1085         var xbottom = getPacking(x, 'bottom_attach');
   1086         var yleft = getPacking(y, 'left_attach');
   1087         var yright = getPacking(y, 'right_attach');
   1088         var ytop = getPacking(y, 'top_attach');
   1089         var ybottom = getPacking(y, 'bottom_attach');
   1090         return xtop < ytop || xtop == ytop && xleft < yleft;
   1091       };
   1092   var getfcols =
   1093       function (sorted) {
   1094         if (!homogeneous) {
   1095           var fcols = [  ];
   1096           var sorted = copySeq(sorted);
   1097           var child = pop(sorted);
   1098           for (var row = 0; row < nRows; row = row + 1) {
   1099             for (var col = 0; col < nColumns; col = col + 1) {
   1100               var left = getPacking(child, 'left_attach');
   1101               var right = getPacking(child, 'right_attach');
   1102               var top = getPacking(child, 'top_attach');
   1103               var bottom = getPacking(child, 'bottom_attach');
   1104               var xOptions = getPacking(child, 'x_options');
   1105               if (top == row && left == col) {
   1106                 if (null == child.packing.x_options || scan('expand', xOptions)) {
   1107                   for (var i = 0; i < (right - left) + 1;
   1108                        i = i + 1) {
   1109                     pushnew(col, fcols);
   1110                   };
   1111                 };
   1112                 child = pop(sorted);
   1113               };
   1114             };
   1115           };
   1116           return fcols;
   1117         };
   1118       };
   1119   var nRows = getProperty(self, 'n_rows');
   1120   var nColumns = getProperty(self, 'n_columns');
   1121   var rowSpacing = getProperty(self, 'row_spacing');
   1122   var columnSpacing = getProperty(self, 'column_spacing');
   1123   var homogeneous = 'True' == getProperty(self, 'homogeneous');
   1124   var sorted = reverse(sort(copySeq(self.children), earlier));
   1125   var fcols = getfcols(sorted);
   1126   var w = wmake(pw, 'xul:grid', { id : self.id });
   1127   var w2 = wmake(w, 'xul:columns');
   1128   var w3 = wmake(w, 'xul:rows');
   1129   for (var col = 0; col < nColumns; col = col + 1) {
   1130     wmake
   1131     (w2, 'xul:column',
   1132      { flex : homogeneous || member(col, fcols) ? 1 : undefined });
   1133   };
   1134   {
   1135     var child = pop(sorted);
   1136     for (var row = 0; row < nRows; row = row + 1) {
   1137       var w4 = wmake(w3, 'xul:row', { align : 'center' });
   1138       for (var col = 0; col < nColumns; col = col + 1) {
   1139         var left = getPacking(child, 'left_attach');
   1140         var right = getPacking(child, 'right_attach');
   1141         var top = getPacking(child, 'top_attach');
   1142         var bottom = getPacking(child, 'bottom_attach');
   1143         if (top == row && left == col) {
   1144           wbuild(w4, [ child ]);
   1145           child = pop(sorted);
   1146         };
   1147       };
   1148     };
   1149   };
   1150   return w;
   1151 };
   1152 
   1153 WBUILD['GtkScrolledWindow'] =
   1154 function (pw, self) {
   1155   var child = self.children[0];
   1156   var w = wbuild(pw, [ child ]);
   1157   return w;
   1158 };
   1159 
   1160 WBUILD['GtkTreeView'] =
   1161 function (pw, self) {
   1162   return wmake(pw, 'xul:tree', { id : self.id });
   1163 };
   1164 
   1165 // ECS added
   1166 WBUILD['GtkCalender'] =
   1167 function (pw, self) {
   1168   return wmake
   1169     (pw, 'xul:datepicker', 
   1170      { id : self.id, 
   1171        });
   1172 };
   1173 
   1174 
   1175 WBUILD['xul:iframe'] =
   1176 function (pw, self) {
   1177   var string1 = getProperty(self, 'string1');
   1178   var string2 = getProperty(self, 'string2');
   1179   return wmake
   1180     (pw, 'xul:iframe',
   1181      { id : self.id, 
   1182        src : string1 },
   1183      { load : string2 });
   1184 };
   1185 
   1186 function closeWindow() {
   1187   window.open('javascript:window.close();', '_self', '');
   1188 };
   1189 
   1190 function gtkMainQuit() {
   1191   closeWindow();
   1192 };
   1193