using Gtk;
+
+/**
+
+This basically provides all the data needed to add stuff to gtk objects
+
+
+*/
+
+
+
namespace Palete {
- public class Introspect.El : Object
- {
- public enum eltype {
- NS,
- CLASS,
- METHOD,
- PROP
- }
-
-
- public eltype type;
- }
-
+
public class Gtk : Palete {
public Gtk(Project.Project project)
{
- base(project);
+ aconstruct(project);
this.name = "Gtk";
var context = new Vala.CodeContext ();
this.package_cache.add_all(
this.loadPackages(Path.get_dirname (context.get_vapi_path("gee-0.8")))
);
- //this.load();
- // various loader methods..
- //this.map = [];
- //this.load();
- //this.proplist = {};
- //this.comments = { };
- // no parent...
+
+
+
}
-
- public override void load () {
+
+
+ // a) build a list of all widgets that can be added generically.
+ // b) build child list for all containers.
+ // c) build child list for all widgets (based on properties)
+ // d) handle oddities?
+
+ public bool loaded = false; // set to false to force a reload
- this.loadUsageFile(BuilderApplication.configDirectory() + "/resources/GtkUsage.txt");
-
-
+ public override void load ()
+ {
+ if (this.loaded) {
+ return;
+ }
+ Gir.factory(this.project, "Gtk"); // triggers a load...
+
+ this.init_node_defaults();
+ this.add_node_default_from_ctor_all();
+ this.init_child_defaults();
+
+ this.loaded = true;
+
+
}
- public string doc(string what) {
- var ns = what.split(".")[0];
- var gir = Gir.factory(this.project,ns);
- return gir.doc(what);
+
+
+
+
+ public string doc(string what)
+ {
+ var ns = what.split(".")[0];
+ var gir = Gir.factory(this.project,ns);
+ return ((Gir) gir).doc(what);
//return typeof(this.comments[ns][what]) == 'undefined' ? '' : this.comments[ns][what];
}
{
var es = ename.split(".");
+ if (es.length < 2) {
+ return null;
+ }
var gir = Gir.factory(this.project,es[0]);
-
+ if (gir == null) {
+ return null;
+ }
return gir.classes.get(es[1]);
}
+
+ public GirObject? getDelegate(string ename)
+ {
+ var es = ename.split(".");
+ if (es.length < 2) {
+ return null;
+ }
+ var gir = Gir.factory(this.project,es[0]);
+ if (gir == null) {
+ return null;
+ }
+ return gir.delegates.get(es[1]);
+
+ }
- public override Gee.HashMap<string,GirObject> getPropertiesFor( string ename, string type)
+ public GirObject? getClassOrEnum(string ename)
+ {
+
+ var es = ename.split(".");
+ if (es.length < 2) {
+ return null;
+ }
+ var gir = Gir.factory(this.project,es[0]);
+ if (gir.classes.has_key(es[1])) {
+ return gir.classes.get(es[1]);
+ }
+ if (gir.consts.has_key(es[1])) {
+ return gir.consts.get(es[1]);
+ }
+ return null;
+ }
+
+
+ public override Gee.HashMap<string,GirObject> getPropertiesFor( string ename, JsRender.NodePropType ptype)
{
//print("Loading for " + ename);
-
+ this.load();
// if (typeof(this.proplist[ename]) != 'undefined') {
//print("using cache");
// return this.proplist[ename][type];
cls.overlayParent(this.project);
- switch (type) {
- case "props":
- return cls.props;
- case "signals":
- return cls.signals;
- case "methods":
+ switch (ptype) {
+ case JsRender.NodePropType.PROP:
+ var ret = this.filterProps(cls.props);
+ // add ctor
+ this.add_props_from_ctors(cls, ret);
+ return ret;
+ case JsRender.NodePropType.LISTENER:
+ return this.filterSignals(cls.signals);
+ case JsRender.NodePropType.METHOD:
return cls.methods;
- case "ctors":
+ case JsRender.NodePropType.CTOR: // needed to query the arguments of a ctor.
return cls.ctors;
default:
- throw new Error.INVALID_VALUE( "getPropertiesFor called with: " + type);
+ GLib.error( "getPropertiesFor called with: " + ptype.to_string());
//var ret = new Gee.HashMap<string,GirObject>();
//return ret;
//cls.overlayInterfaces(gir);
-
-
+
}
+ // get rid of objecst from props list..
+ public Gee.HashMap<string,GirObject> filterProps(Gee.HashMap<string,GirObject> props)
+ {
+ // we shold probably cache this??
+
+ var outprops = new Gee.HashMap<string,GirObject>();
+
+ foreach(var k in props.keys) {
+ var val = props.get(k);
+// GLib.debug("FilterProp: %s", k);
+ // properties that dont make any sense to display.
+ if (
+ k == "___" ||
+ k == "parent" ||
+ k == "default_widget" ||
+ k == "root" ||
+ k == "layout_manager" || // ??
+ k == "widget" // gestures..
+ ) {
+ continue;
+ }
+
+ if (val.is_deprecated) {
+ continue;
+ }
+ if (!val.is_writable && !val.ctor_only ) { // if it's ctor we accept it.
+ continue;
+ }
+
+ if (val.type == "GLib.Object") { /// this is practually everything? ?? shoud we display it as a property?
+ continue;
+ }
+ if (!val.type.contains(".")) {
+ outprops.set(k,val);
+ continue;
+ }
+ var cls = this.getClassOrEnum(val.type);
+
+ // if cls == null - it's probably a struct? I don't think we handle thses
+ if ( cls != null ) { // cls.nodetype == "Enum") {
+ // assume it's ok
+ outprops.set(k,val);
+ continue;
+ }
+ // do nothing? - classes not allowed?
+
+ }
+
+
+ return outprops;
+
+
+ }
+
+ private void add_props_from_ctors(GirObject cls, Gee.HashMap<string,GirObject> props)
+ {
+ if (cls.ctors.has_key("new")) {
+ this.add_props_from_ctor(cls.ctors.get("new"), props);
+ return;
+ }
+ // does not have new ?? needed?
+ foreach(var ctor in cls.ctors.values) {
+ this.add_props_from_ctor(ctor, props);
+ break;
+
+ }
+ }
+
+ private void add_props_from_ctor(GirObject ctor, Gee.HashMap<string,GirObject> props)
+ {
+ var cname = ctor.gparent.fqn();
+ GLib.debug("Add node from ctor %s:%s", ctor.gparent.fqn(), ctor.name);
+
+ if (ctor.paramset == null) {
+ return;
+ }
+
+
+ // assume we are calling this for a reason...
+ // get the first value params.
+
+ //gtk box failing
+ //GLib.debug("No. of parmas %s %d", cls, ctor.params.size);
+
+ foreach (var prop in ctor.paramset.params) {
+
+
+ if (props.has_key(prop.name)) { // overlap (we assume it's the same..)
+ continue;
+ }
+ prop.propertyof = cname + "." + ctor.name; // as it's probably not filled in..
+
+ GLib.debug("adding proprty from ctor : %s, %s, %s", cname , prop.name, prop.type);
+
+ props.set(prop.name, prop);
+
+
+
+ }
+ }
+
+
+
+ // get rid of depricated from signal list..
+ public Gee.HashMap<string,GirObject> filterSignals(Gee.HashMap<string,GirObject> props)
+ {
+ // we shold probably cache this??
+
+ var outprops = new Gee.HashMap<string,GirObject>();
+
+ foreach(var k in props.keys) {
+ var val = props.get(k);
+
+ if (val.is_deprecated) {
+ continue;
+ }
+
+ outprops.set(k,val);
+
+ // do nothing? - classes not allowed?
+
+ }
+
+
+ return outprops;
+
+
+ }
+
public string[] getInheritsFor(string ename)
{
string[] ret = {};
- var cls = Gir.factoryFqn(this.project,ename);
+ var cls = this.getClass(ename);
if (cls == null || cls.nodetype != "Class") {
print("getInheritsFor:could not find cls: %s\n", ename);
}
-
- public override void fillPack(JsRender.Node node,JsRender.Node parent)
- {
-
- string inherits = string.joinv(" ",
- this.getInheritsFor (node.fqn())) + " ";
- inherits += node.fqn() + " ";
- //print ("fillPack:Inherits : %s\n", inherits);
- // parent.fqn() method ( node.fqn()
- var methods = this.getPropertiesFor (parent.fqn(), "methods");
-
- var res = new Gee.HashMap<string,string>();
- var map = methods.map_iterator();
- while (map.next()) {
-
- var n = map.get_key();
- //print ("fillPack:checking method %s\n", n);
-
- var meth = map.get_value();
- if (meth.paramset == null || meth.paramset.params.size < 1) {
- print ("fillPack:c -- no params\n");
-
- continue;
- }
- var fp = meth.paramset.params.get(0);
-
- var type = Gir.fqtypeLookup(this.project, fp.type, meth.ns);
- print ("fillPack:first param type is %s\n", type);
+ Gee.HashMap<string,Gee.HashMap<string,JsRender.NodeProp>> node_defaults;
+ Gee.HashMap<string,Gee.ArrayList<JsRender.NodeProp>> child_defaults;
+
+ public void init_node_defaults()
+ {
+ this.node_defaults = new Gee.HashMap<string,Gee.HashMap<string,JsRender.NodeProp>>();
+
+ // this lot could probably be configured?
+
+ // does this need to add properties to methods?
+ // these are fake methods.
+
+
+
+
+ this.add_node_default("Gtk.ComboBox", "has_entry", "false");
+ this.add_node_default("Gtk.Expander", "label", "Label");
+
+ this.add_node_default("Gtk.Frame", "label", "Label");
+
+ this.add_node_default("Gtk.Grid", "columns", "2"); // special properties (is special as it's not part of the standard?!)
+ //this.add_node_default("Gtk.Grid", "rows", "2"); << this is not really that important..
+
+ this.add_node_default("Gtk.HeaderBar", "title", "Window Title");
+ this.add_node_default("Gtk.Label", "label", "Label"); // althought the ctor asks for string.. - we can use label after ctor.
+
+ this.add_node_default("Gtk.Scale", "orientation");
+
+ this.add_node_default("Gtk.ToggleButton", "label", "Label");
+ this.add_node_default("Gtk.MenuItem", "label", "Label");
+ this.add_node_default("Gtk.CheckItem", "label", "Label");
+ this.add_node_default("Gtk.RadioMenuItem", "label", "Label");
+ this.add_node_default("Gtk.TearoffMenuItem", "label", "Label");
+
+ // not sure how many of these 'attributes' there are - documenation is a bit thin on the ground
+ this.add_node_default("Gtk.CellRendererText", "markup_column", "-1");
+ this.add_node_default("Gtk.CellRendererText", "text_column","-1");
+ this.add_node_default("Gtk.CellRendererPixBuf", "pixbuf_column", "-1");
+ this.add_node_default("Gtk.CellRendererToggle", "active_column", "-1");
-
- if (!inherits.contains(" " + type + " ")) {
- continue;
- }
-
-
- var pack = meth.name;
- for(var i =1; i < meth.paramset.params.size; i++) {
- var ty = Gir.fqtypeLookup(this.project,meth.paramset.params.get(i).type, meth.ns);
- pack += "," + Gir.guessDefaultValueForType(ty);
- }
+ //foreground
+ //foreground-gdk
+
+
+
+ // treeviewcolumn
+
+ }
+
+
+
+
+ private void add_node_default_from_ctor_all()
+ {
- print ("fillPack:add pack: -- %s\n",pack );
+ var pr = (Project.Gtk) this.project;
+
+
+
+ foreach(var key in pr.gir_cache.keys) {
+ var gir = pr.gir_cache.get(key);
+ GLib.debug("building drop list for package %s", key);
+ this.add_node_default_from_ctor_package(gir.classes);
+ }
+ }
- res.set(meth.name, pack);
-
-
+ private void add_node_default_from_ctor_package(Gee.HashMap<string,GirObject> classes)
+ {
+
+
+ foreach(var cls in classes.values) {
+ GLib.debug("building drop list for class %s.%s", cls.package, cls.name);
+ this.add_node_default_from_ctor_classes(cls);
+ }
+
+ }
+
+ private void add_node_default_from_ctor_classes(GirObject cls)
+ {
+ if (cls.ctors.has_key("new")) {
+ this.add_node_default_from_ctor(cls.ctors.get("new"));
+ return; // and no more.
}
- if (res.size < 1) {
- return ;
+ // does not have new ?? needed?
+ foreach(var ctor in cls.ctors.values) {
+ this.add_node_default_from_ctor(ctor);
+ break;
+
}
- if (res.has_key("pack_start")) {
- node.props.set("* pack", res.get("pack_start"));
+ }
+
+
+
+
+
+
+ private void add_node_default_from_ctor(GirObject ctor )
+ {
+ var cname = ctor.gparent.fqn();
+ GLib.debug("Add node from ctor %s:%s", ctor.gparent.fqn(), ctor.name);
+ if (!this.node_defaults.has_key(cname)) {
+ this.node_defaults.set(cname, new Gee.HashMap<string,JsRender.NodeProp>());
+ }
+
+ if (ctor.paramset == null) {
return;
}
- if (res.has_key("add")) {
- node.props.set("* pack", res.get("add"));
+
+ var defs= this.node_defaults.get(cname);
+
+
+
+ GLib.debug("ctor: %s: %s", cname , ctor.name);
+
+
+ // assume we are calling this for a reason...
+ // get the first value params.
+
+ //gtk box failing
+ //GLib.debug("No. of parmas %s %d", cls, ctor.params.size);
+
+ foreach (var prop in ctor.paramset.params) {
+ string[] opts;
+
+ if (defs.has_key(prop.name)) {
+ continue;
+ }
+ var sub = this.getClass(prop.type);
+
+ // GLib.debug("adding property from ctor : %s, %s, %s [%s]", cname , prop.name, prop.type, sub == null ? "-" : sub.nodetype);
+
+ if (sub != null) { // can't add child classes here...
+
+ GLib.debug("skipping ctor argument proprty is an object");
+ continue;
+ }
+ sub = this.getDelegate(prop.type);
+ if (sub != null) { // can't add child classes here...
+ this.node_defaults.get(cname).set(prop.name, new JsRender.NodeProp.raw(prop.name, prop.type, sub.sig));
+ continue;
+ }
+
+ // FIXME!!! - what about functions
+
+ var dval = "";
+ switch (prop.type) {
+ case "int":
+ dval = "0";break;
+ case "string":
+ dval = ""; break;
+ // anything else?
+
+ default: // enam? or bool?
+ this.typeOptions(cname, prop.name, prop.type, out opts);
+ dval = opts.length > 0 ? opts[0] : "";
+ break;
+ }
+
+ this.node_defaults.get(cname).set(prop.name, new JsRender.NodeProp.prop( prop.name, prop.type, dval));
+
+
+
+ }
+ }
+
+ private void add_node_default(string cname, string propname, string val = "")
+ {
+ if (!this.node_defaults.has_key(cname)) {
+ var add = new Gee.HashMap<string, JsRender.NodeProp>();
+ this.node_defaults.set(cname, add);
+ }
+ // this recurses...
+ var cls = this.getClass(cname);
+ if (cls == null) {
+ GLib.debug("invalid class name %s", cname);
return;
}
- var riter = res.map_iterator();
- while(riter.next()) {
- node.props.set("* pack", riter.get_value());
+ var ar = cls.props;
+
+ // liststore.columns - exists as a property but does not have a type (it's an array of typeofs()....
+ if (ar.has_key(propname) && ar.get(propname).type != "") { // must have type (otherwise special)
+ //GLib.debug("Class %s has property %s from %s - adding normal property", cls, propname, ar.get(propname).asJSONString());
+ var add = ar.get(propname).toNodeProp(this, cname); // our nodes dont have default values.
+ add.val = val;
+ this.node_defaults.get(cname).set(propname, add);
return;
+
+ }
+ //GLib.debug("Class %s has property %s - adding special property", cls, propname);
+ this.node_defaults.get(cname).set(propname,
+ new JsRender.NodeProp.special( propname, val)
+ );
+
+
+
+
+ }
+ private void init_child_defaults()
+ {
+ this.child_defaults = new Gee.HashMap<string,Gee.ArrayList<JsRender.NodeProp>>();
+
+ this.add_child_default("Gtk.Fixed", "x", "int", "0");
+ this.add_child_default("Gtk.Fixed", "y", "int", "0");
+ this.add_child_default("Gtk.Layout", "x", "int", "0");
+ this.add_child_default("Gtk.Layout", "y", "int", "0");
+ this.add_child_default("Gtk.Grid", "colspan", "int", "1");
+ //this.add_child_default("Gtk.Grid", "height", "int", "1");
+ this.add_child_default("Gtk.Stack", "stack_name", "string", "name");
+ this.add_child_default("Gtk.Stack", "stack_title", "string", "title");
+
+
+ }
+ private void add_child_default(string cls, string propname, string type, string val)
+ {
+ if (!this.child_defaults.has_key(cls)) {
+ this.child_defaults.set(cls, new Gee.ArrayList<JsRender.NodeProp>());
}
+ this.child_defaults.get(cls).add( new JsRender.NodeProp.prop(propname, type, val));
+
}
+
public Gee.ArrayList<string> packages(Project.Gtk gproject)
{
var vapidirs = gproject.vapidirs();
return ret;
}
+ // get a list of available vapi files...
public Gee.ArrayList<string> loadPackages(string dirname)
{
}
ret.add(Path.get_basename(fn).replace(".vapi", ""));
}
- } catch(Error e) {
+ } catch(GLib.Error e) {
print("oops - something went wrong scanning the packages\n");
}
return ret;
public override bool typeOptions(string fqn, string key, string type, out string[] opts)
{
opts = {};
- print("get typeOptions %s (%s)%s", fqn, type, key);
+ if (type == "" ) { // empty type dont try and fill in options
+ return false;
+ }
+ GLib.debug("get typeOptions %s (%s)%s", fqn, type, key);
if (type.up() == "BOOL" || type.up() == "BOOLEAN") {
opts = { "true", "false" };
return true;
}
- var gir= Gir.factoryFqn(this.project,type) ;
+
+ var gir= Gir.factoryFqn(this.project,type) ; // not get class as we are finding Enums.
if (gir == null) {
- print("could not find Gir data for %s\n", key);
+ GLib.debug("could not find Gir data for %s\n", key);
return false;
}
- print ("Got type %s", gir.asJSONString());
+ //print ("Got type %s", gir.asJSONString());
if (gir.nodetype != "Enum") {
return false;
}
}
- public override List<SourceCompletionItem> suggestComplete(
- JsRender.JsRender file,
- JsRender.Node? node,
- string proptype,
- string key,
- string complete_string
- ) {
+
+
+
+ void add_classes_from_method(GirObject cls, string method , Gee.ArrayList<string> ret)
+ {
- var ret = new List<SourceCompletionItem>();
- // completion rules??
+ //GLib.debug("add_classes_from_method %s, %s", cls.fqn(), method);
+ // does class have this method?
+ if (!cls.methods.has_key(method)) {
+ GLib.debug("skip %s does not have method %s", cls.fqn(), method);
+ return;
+ }
+ // add all the possible classes to ret based on first arguemnt?
+ var m = cls.methods.get(method);
- // make sure data is loaded
- Gir.factory(this.project,"Gtk");
+ if (m.paramset.params.size < 1) {
+ GLib.debug("%s: %s does not have any params?", cls.fqn(), method);
+ return;
+ }
+
- // Roo......
- // this. (based on the node type)
- // this.xxx // Node and any determination...
+ var ty = m.paramset.params.get(0).type;
+ GLib.debug("add %s method %s arg0 = %s", cls.fqn(), method, ty);
+ this.addRealClasses(ret, ty);
+ // skip dupe // skip depricated
+ // skip not object // skip GLib.Object (base)
- if (complete_string.index_of(".",0) < 0) {
- // string does not have a '.'
- // offer up vala keywords... / _this .. / look for var string = .. in the code..
-
- var max = (int)Vala.TokenType.YIELD +1;
- for (var i =0; i < max;i++) {
- var m = (Vala.TokenType)i;
- var s = m.to_string();
- var ss = s.slice(1,-1);
- if (s[0] == '`' && GLib.Regex.match_simple("^[a-z]+$", ss) &&
- complete_string != ss && ss.index_of(complete_string,0) == 0 ) {
- ret.append(new SourceCompletionItem (ss, ss, null, "vala : " + ss));
- }
- }
- var miter = ((Project.Gtk)this.project).gir_cache.map_iterator();
- while (miter.next()) {
- var ss = miter.get_key();
-
- if (complete_string != ss && ss.index_of(complete_string,0) == 0 ) {
- ret.append(new SourceCompletionItem (ss, ss, null, "vala namespace : " + ss));
- }
- }
-
-
- if (complete_string != "_this" && "_this".index_of(complete_string,0) == 0 ) { // should we ignore exact matches... ???
- ret.append(new SourceCompletionItem ("_this - the top level element", "_this", null, "Top level element"));
- }
- // basic types..
-
- return ret;
- }
+
+ //if (cls.fqn() == "GLib.Menu" && method == "append_submenu") {
+ // ty = m.paramset.params.get(1).type;
+ // GLib.debug("add %s method %s arg1 = %s", cls.fqn(), method, ty);
+ // this.addRealClasses(ret, ty);
+ //}
+ }
+
+ void addRealClasses(Gee.ArrayList<string> ret, string cn, bool allow_root = false)
+ {
+ if (!cn.contains(".")) {
+ return;
+ }
- // got at least one ".".
- var parts = complete_string.split(".");
- var curtype = "";
- var cur_instance = false;
- if (parts[0] == "this") {
- // work out from the node, what the type is...
- if (node == null) {
- print("node is empty - no return\n");
- return ret; // no idea..
- }
- curtype = "*" + node.fqn();
- cur_instance = true;
- } else {
- if (((Project.Gtk)this.project).gir_cache.get(parts[0]) == null) {
- return ret;
- }
- curtype = parts[0];
+ var w = this.getClass(cn);
+ if (w == null) {
+ return;
}
- // all Gtk.... etc.. types...
+ if (w.nodetype != "Class" && w.nodetype != "Interface" ) {
+ return;
+ }
+ if (ret.contains(cn)) {
+ return;
+ }
- //if (parts[0] == "Roo") {
- // curtype = "Roo";
- // cur_instance = false;
- //}
+ if (!allow_root && w.implements.contains("Gtk.Native")) { // removes popover + window
+ return;
+ }
- var prevbits = parts[0] + ".";
- for(var i =1; i < parts.length; i++) {
- print("matching %d/%d\n", i, parts.length);
- var is_last = i == parts.length -1;
-
-
-
- // look up all the properties of the type...
- var cls = Gir.factoryFqn(this.project,curtype);
- if (cls == null && curtype[0] != '*') {
- print("could not get class of curtype %s\n", curtype);
- return ret;
+ if (!w.is_deprecated && !w.is_abstract && w.nodetype == "Class" ) {
+ ret.add(cn);
+ }
+
+
+
+
+ foreach (var str in w.implementations) {
+ var c = this.getClass(str);
+ if (c.is_deprecated || c.is_abstract) {
+ continue;
}
-
- if (!is_last) {
-
- if (curtype[0] == '*' && parts[i] == "el") {
- curtype = curtype.substring(1);
- prevbits += parts[i] + ".";
- continue;
- }
-
- // only exact matches from here on...
- if (cur_instance) {
- if (cls == null) {
- return ret;
- }
- if (cls.props.has_key(parts[i])) {
- var prop = cls.props.get(parts[i]);
- if (prop.type.index_of(".",0) > -1) {
- // type is another roo object..
- curtype = prop.type;
- prevbits += parts[i] + ".";
- continue;
- }
- return ret;
- }
-
-
-
- // check methods?? - we do not export that at present..
- return ret; //no idea...
- }
- var look = prevbits + parts[i];
- var scls = Gir.factoryFqn(this.project,look);
- if (scls == null) {
- return ret;
- }
- curtype = look;
- prevbits += parts[i] + ".";
+ if (ret.contains(str)) {
continue;
-
- }
-
- // got to the last element..
- print("Got last element\n");
- if (curtype == "") { // should not happen.. we would have returned already..
- return ret;
}
- print("Got last element type %s\n",curtype);
- if (!cur_instance) {
- print("matching instance");
- // it's a static reference..
- var citer = cls.classes.map_iterator();
- while (citer.next()) {
- var scls = citer.get_key();
-
- if (parts[i].length > 0 && scls.index_of(parts[i],0) != 0) {
- continue;
- }
- // got a starting match..
- ret.append(new SourceCompletionItem (
- prevbits + scls,
- prevbits + scls,
- null,
- scls));
- }
- // methods....
- citer = cls.methods.map_iterator();
- while (citer.next()) {
- var scls = citer.get_key();
-
- if (parts[i].length > 0 && scls.index_of(parts[i],0) != 0) {
- continue;
- }
- // got a starting match..
- ret.append(new SourceCompletionItem (
- prevbits + scls + citer.get_value().sig ,
- prevbits + scls,
- null,
- scls));
- }
-
- // enums....
- citer = cls.consts.map_iterator();
- while (citer.next()) {
- var scls = citer.get_key();
-
- if (parts[i].length > 0 && scls.index_of(parts[i],0) != 0) {
- continue;
- }
- // got a starting match..
- ret.append(new SourceCompletionItem (
- prevbits + scls + citer.get_value().sig ,
- prevbits + scls,
- null,
- scls));
- }
-
-
- return ret;
- }
- print("matching property");
- if (cls == null) {
- return ret;
- }
-
-
- var citer = cls.methods.map_iterator();
- while (citer.next()) {
- var prop = citer.get_value();
- // does the name start with ...
- if (parts[i].length > 0 && prop.name.index_of(parts[i],0) != 0) {
- continue;
- }
- // got a matching property...
- // return type?
- ret.append(new SourceCompletionItem (
- prop.name + prop.sig + " : ("+ prop.propertyof + ")",
- prevbits + prop.name + "(",
- null,
- prop.doctxt));
+ if (!allow_root && c.implements.contains("Gtk.Native")) { // removes popover + window
+ continue;
}
- // get the properties / methods and subclasses.. of cls..
- // we have cls.. - see if the string matches any of the properties..
- citer = cls.props.map_iterator();
- while (citer.next()) {
- var prop = citer.get_value();
- // does the name start with ...
- if (parts[i].length > 0 && prop.name.index_of(parts[i],0) != 0) {
- continue;
- }
- // got a matching property...
-
- ret.append(new SourceCompletionItem (
- prop.name + " : " + prop.type + " ("+ prop.propertyof + ")",
- prevbits + prop.name,
- null,
- prop.doctxt));
- }
-
-
- return ret;
-
-
-
+ ret.add(str);
+ }
+ }
+
+
+ /**
+ this is the real list of objects that appear in the add object pulldown
+ @param in_rval "*top" || "Gtk.Widget"
+
+ */
+ public override Gee.ArrayList<string> getChildList(string in_rval, bool with_props)
+ {
+
+ GLib.debug("getChildList %s %s", in_rval, with_props ? "(with props)" : "");
+
+ //return this.original_getChildList( in_rval, with_props);
+ var pr = (Project.Gtk) this.project;
+ if (with_props && pr.child_list_cache_props.has_key(in_rval)) {
+ return pr.child_list_cache_props.get(in_rval);
+ }
+ if (!with_props && pr.child_list_cache.has_key(in_rval)) {
+ return pr.child_list_cache.get(in_rval);
+ }
+
+ // CACHE ?
+ var ret = new Gee.ArrayList<string>();
+
+ if (in_rval == "*top") {
+ // everythign that's not depricated and extends Gtk.Widget
+ // even a gtk window and about dialog are widgets
+ this.addRealClasses(ret, "Gtk.Widget", true);
+
+ return ret;
+
+
+
+ }
+ var cls = this.getClass(in_rval);
+ if (cls == null) {
+ GLib.debug("could not get class for %s", in_rval);
+ return ret;
}
+
+ // look through methods of in_rval
+ // set_X << ignore
+ // probably methods:
+ this.add_classes_from_method(cls, "add_controller", ret);
+ this.add_classes_from_method(cls, "add_shortcut", ret);
+ this.add_classes_from_method(cls, "add_tick_callback", ret); // wtf does this do.
+ this.add_classes_from_method(cls, "append", ret);
+ this.add_classes_from_method(cls, "append_column", ret); // columnview column
+ this.add_classes_from_method(cls, "append_item", ret); // GLib.Menu
+ //this.add_classes_from_method(cls, "append_submenu", ret); // GLib.Menu - complicated to support
+ this.add_classes_from_method(cls, "attach", ret); // grid column
+ this.add_classes_from_method(cls, "pack_start", ret); // headerbar (also has pack end?)
+
+ // add_controller 1st arge = ??
+ // add_menomic_label ??? << no ???
+ // add_shortcut?
+ // add_tick_callback ?
+ // append << core one to add stuff..
+
+ if (!with_props) {
+
+ pr.child_list_cache.set(in_rval, ret);
+ return ret;
+ }
+ foreach(var pn in cls.props.values) {
+
+ if (!pn.is_writable ) {
+ GLib.debug("Skip (not write) %s : (%s) %s", cls.fqn(), pn.type , pn.name);
+ continue;
+ }
+ // if (&& !pn.ctor_only << we add these?
+ // are they really available ?
+ GLib.debug("Add %s : (%s) %s", cls.fqn(), pn.type , pn.name);
+ this.addRealClasses(ret, pn.type);
+ }
+
+ pr.child_list_cache_props.set(in_rval, ret);
+
+ return ret;
+
+
+ }
+
+ public void buildChildListForDroppingProject()
+ {
+
+ this.load();
+ var pr = (Project.Gtk) this.project;
+ if (pr.dropList != null) {
+ GLib.debug("Drop list alreayd loaded");
+ return;
+ }
+ pr.dropList = new Gee.HashMap<string,Gee.ArrayList<string>>();
+ foreach(var key in pr.gir_cache.keys) {
+ var gir = pr.gir_cache.get(key);
+ GLib.debug("building drop list for package %s", key);
+ this.buildChildListForDropping(key, gir.classes);
+ }
+ }
+
+ public void buildChildListForDropping(string pkg, Gee.HashMap<string,GirObject> classes)
+ {
+
-
-
- return ret;
+ foreach(var cls in classes.keys) {
+ GLib.debug("building drop list for class %s.%s", pkg, cls);
+ this.buildDropList(pkg + "." + cls, this.getChildList(pkg + "." + cls, true));
+ }
+ this.buildDropList("*top", this.getChildList("*top", true));
}
- public override string[] getChildList(string in_rval)
- {
- return this.original_getChildList( in_rval);
+
+
+ public void buildDropList(string parent, Gee.ArrayList<string> children)
+ {
+
+ var pr = (Project.Gtk) this.project;
+ foreach(var c in children) {
+ if (!pr.dropList.has_key(c)) {
+
+ pr.dropList.set(c, new Gee.ArrayList<string>());
+ }
+ var dl = pr.dropList.get(c);
+ if (dl.contains(parent)) {
+ continue;
+ }
+ GLib.debug("%s[] = %s", c, parent);
+ dl.add(parent);
+ }
+
+
}
- public override string[] getDropList(string rval)
+
+ public override Gee.ArrayList<string> getDropList(string rval)
+ {
+ this.buildChildListForDroppingProject();
+ var pr = (Project.Gtk) this.project;
+ if (!pr.dropList.has_key(rval)) {
+ GLib.debug("returning empty drop list for %s", rval);
+ return new Gee.ArrayList<string>();
+ }
+ GLib.debug("returning %d items in drop list %s", pr.dropList.get(rval).size, rval);
+ return pr.dropList.get(rval);
+
+
+ }
+
+
+ public override JsRender.Node fqnToNode(string fqn)
{
- return this.default_getDropList(rval);
- }
+ this.load();
+ var ret = new JsRender.Node();
+ ret.setFqn(fqn);
+ if (!this.node_defaults.has_key(fqn)) {
+ return ret;
+ }
+
+ foreach (var nv in this.node_defaults.get(fqn).values) {
+ ret.add_prop(nv.dupe());
+ }
+ return ret;
+
+
+
+ }
+
+
+
}
}