/**
-Known issues with Palete
-
-
-Object Add:
-
-SourceView/TextView - can add widget (which doesnt really seem to work) - as it's subclassing a container
-Gtk.Table - adding children? (nothing is currently allowed.
-
-
-Properties list
-- need to remove widgets from this..
-- help / show source interface etc..?
-- make wider?
-
-Events list
-- signature on insert
-- show source interface / help
+This basically provides all the data needed to add stuff to gtk objects
*/
- public class Introspect.El : Object
- {
- public enum eltype {
- NS,
- CLASS,
- METHOD,
- PROP
- }
-
-
- public eltype type;
- }
-
+
public class Gtk : Palete {
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...
+
}
// c) build child list for all widgets (based on properties)
// d) handle oddities?
+ public bool loaded = false; // set to false to force a reload
+
public override void load ()
{
-
- Gir.factory(this.project, "Gtk"); // triggers a load...
- var pr = (Project.Gtk) this.project;
-
-
- this.map = new Gee.ArrayList<Usage>();
- this.generic_child_widgets = new Gee.ArrayList<string>();
- this.all_no_parent = new Gee.ArrayList<string>();
- var top = new Gee.ArrayList<string>();
- top.add("*top");
- foreach(var key in pr.gir_cache.keys) {
- var gir = pr.gir_cache.get(key);
-
- this.build_generic_children(gir.classes);
- }
- // add containers.
- this.map.add(new Usage( top, this.all_no_parent));
- var alltop = new Gee.ArrayList<string>();
- alltop.add("*top");
-
-
- foreach(var k in this.generic_containers) {
- alltop.add(k);
- this.add_special_children(k, "Gtk.Menu", "_menu");
+ if (this.loaded) {
+ return;
}
- var u = new Usage( alltop, this.generic_child_widgets);
- //GLib.debug("add Usage: %s", u.to_string());
-
- this.map.add(u);
-
+ Gir.factory(this.project, "Gtk"); // triggers a load...
- foreach(var key in pr.gir_cache.keys) {
- var gir = pr.gir_cache.get(key);
- this.build_class_children_from_props(gir.classes);
- }
- // oddities.
-
- this.add_special_children("Gtk.Menu","Gtk.MenuItem", "");
- this.add_special_children("Gtk.MenuBar", "Gtk.MenuItem", "");
- this.add_special_children("Gtk.Toolbar", "Gtk.ToolItem", "");
- this.add_special_children("Gtk.MenuItem","Gtk.Box", "");
- this.add_special_children("Gtk.Notebook", "Gtk.Label", "label[]"); //??
- this.add_special_children("Gtk.Window","Gtk.HeaderBar", "titlebar");
-
- this.add_special_children("Gtk.Stack","Gtk.Label", "titles[]");
- this.add_special_children("Gtk.TreeView","Gtk.TreeViewColumn", ""); // any viewcolum added..
- this.add_special_children("Gtk.TreeViewColumn","Gtk.CellRenderer", "");
-
- this.add_special_children("Gtk.Dialog","Gtk.Button", "buttons[]");
- //this.add_special_children("Gtk.Dialog","Gtk.Button", "response_id");
- this.add_special_children("Gtk.RadioButton","Gtk.Button", "_group_name"); // fake property
-
- this.add_special_children("Gtk.ButtonBox","Gtk.Button", "");
-
-
-
this.init_node_defaults();
+ this.add_node_default_from_ctor_all();
this.init_child_defaults();
- //foreach(var m in this.map) {
- // GLib.debug("Usage: %s", m.to_string());
- // }
-
- }
-
-
-
-
- // containers that can contain only certial types of children, and should be ignored from the general bulk add.
- Gee.ArrayList<string> generic_child_widgets;
- Gee.ArrayList<string> all_no_parent;
-/*
- string[] special_containers = {
- "Gtk.Menu",
- "Gtk.MenuBar",
- "Gtk.Toolbar", // only toolbarItems.
-
- "Gtk.Assistant", // needs fake child? including fake page type
- "Gtk.Notebook", // needs fake child?
-
- };
- // children (or anythign that extends this) - that can not be added to a standard widget
- string[] special_containers_children = {
- "Gtk.MenuItem",
- "Gtk.ToolbarItem"
- };
- */
- // widgets that can not be added to anything? - including their children.
- string[] no_parent = { // except *top
- "Gtk.Window",
- "Gtk.Dialog",
- };
-
- string[] generic_containers = {
- "Gtk.Assistant",
- "Gtk.ActionBar",
- "Gtk.AspectFrame",
- "Gtk.Frame",
- "Gtk.Fixed",
- "Gtk.Box",
- "Gtk.Dialog",
- "Gtk.Expander", // add method is different..
- "Gtk.FlowBox",
- "Gtk.HeaderBar",
- "Gtk.InfoBar",
- "Gtk.ListBox",
- "Gtk.Overlay",
- "Gtk.Paned",
- "Gtk.Popover",
- "Gtk.PopoverMenu",
- "Gtk.Revealer",
- "Gtk.ScrolledWindow",
- "Gtk.Stack", // add with name?
- "Gtk.ToolItem",
- "Gtk.ToolPalette",
- "Gtk.Viewport",
- "Gtk.Window",
- "Gtk.Notebook",
- "Gtk.ApplicationWindow",
- "Gtk.Grid",
- "Gtk.SearchBar",
-
- };
-
- string[] widgets_blacklist = {
- "Gtk.Arrow", //Depricated
-
- "Gtk.ShortcutLabel",
- "Gtk.ShortcutsGroup",
- "Gtk.ShortcutsSection",
- "Gtk.ShortcutsShortcut",
- "Gtk.ShortcutsWindow",
- "Gtk.Socket",
- "Gtk.ToolItemGroup",
-
- //"Gtk.ButtonBox", << why ?
- "Gtk.CellView",
- "Gtk.EventBox",
- "Gtk.FlowBoxChild",
- "Gtk.Invisible",
- "Gtk.ListBoxRow",
- "Gtk.OffscreenWindow",
- "Gtk.Plug",
- "Gtk.HSV",
- "Gtk.ImageMenuItem", //deprecated? (not sure why it's not been picked up)
-
- "Gtk.Menu", // it's added as a special only?
- "Gtk.MenuItem",
- "Gtk.ToolItem",
-
- "WebKit.WebViewBase",
-
- "Gtk.HeaderBar", // only to window
- };
-
- /**
- * Gtk's heirachy of parent/children is not particulaly logical
- * Gtk.Containers - some are not really that good t being containers. Gtk.Bin (single only) - is a good flag for indicating
- * Gtk.Widgets - some are not great at being widgets
- * Gtk.Menu - should really only contain menuitems, but the API doesnt really restrict this.
- * The list goes on.
- *
- *
- */
-
- public void build_generic_children(Gee.HashMap<string,GirObject> classes)
- {
- foreach(var cls in classes.values) {
-
- var fqn = cls.fqn();
-
- if (cls.is_deprecated) { // don't add depricated to our selection.
- //GLib.debug("Class %s is depricated", cls.fqn());
- continue;
- }
-
- if (!cls.inherits.contains("Gtk.Widget") && !cls.implements.contains("Gtk.Widget")) {
- continue;
- }
- if (cls.is_abstract) {
- continue;
- }
- if (cls.nodetype == "Interface") {
- continue;
- }
- var is_black = false;
- for (var i = 0 ; i < this.widgets_blacklist.length; i++) {
- var black = this.widgets_blacklist[i];
-
- if (fqn == black || cls.implements.contains(black) || cls.inherits.contains(black)) {
- is_black = true;
- break;
- }
- }
- if (is_black) {
- continue;
- }
-
-
-
- for (var i = 0 ; i < this.no_parent.length; i++) {
- var black = this.no_parent[i];
-
- if (fqn == black || cls.implements.contains(black) || cls.inherits.contains(black)) {
- is_black = true;
- all_no_parent.add(fqn);
-
- break;
- }
-
-
- }
- if (is_black) {
- continue;
- }
- this.generic_child_widgets.add(fqn);
-
-
-
- //this.add_special_children(fqn, "Gtk.Menu", "_menu"); // fake propety
- }
-
- }
-
- public void add_special_children(string parent, string child, string prop)
- {
- this.getClass(parent);
- var cls_cn = this.getClass(child);
- var localopts_r = new Gee.ArrayList<string>();
- var localopts_l = new Gee.ArrayList<string>();
- localopts_l.add(parent);
-
- if (cls_cn == null) {
- return;
- }
- if (!cls_cn.is_abstract) { // and check for interface?
-
- localopts_r.add(child + ( prop.length > 0 ? ":" + prop : "") );
- }
- GLib.debug("Special Parent %s - add %s ", parent , child);
- foreach(var impl in cls_cn.implementations) {
-
- // in theory these can not be abstract?
-
- var impcls = this.getClass(impl);
- if (impcls.is_abstract) {
- continue;
- }
- if (impcls.nodetype == "Interface") {
- continue;
- }
- GLib.debug("Special Parent %s - add %s ", parent , impl + ( prop.length > 0 ? ":" + prop : ""));
- localopts_r.add( impl + ( prop.length > 0 ? ":" + prop : "") );
- }
- this.map.add(new Usage(localopts_l, localopts_r));
+ this.loaded = true;
+
}
-
-
- public void build_class_children_from_props(Gee.HashMap<string,GirObject> classes)
- {
-
-
-
- foreach(var cls in classes.values) {
-
-
- if (cls.is_deprecated) { // don't add depricated to our selection.
- //GLib.debug("Class %s is depricated", cls.fqn());
- continue;
- }
-
-
-
- // we can still add properties of abstract classes...
-
- if (cls.is_abstract || cls.nodetype == "Interface") {
- continue;
- }
-
-
- if (cls.props.size < 1) {
- continue;
- }
-
- var localopts_r = new Gee.ArrayList<string>();
- var localopts_l = new Gee.ArrayList<string>();
- localopts_l.add(cls.fqn());
-
- // we have a class that extends a widget - let's see if we can add the object based properties. here.
-
- var props = cls.props.values.to_array();
- for (var i = 0 ;i < props.length;i++) {
- var prop = props[i];
-
- if (!prop.type.contains(".")) {
- // not a namespaced object - ignore
- continue;
- }
- // gtkcontainer child is a abstract method - that can be called multiple times
- // gtkwidget parent - is a similar method
- if (!prop.is_readable && !prop.is_writable) {
- continue;
- }
- if (prop.is_deprecated) {
- continue;
- }
-
- if (prop.name == "parent" ||
- (prop.name == "child" && cls.fqn() != "Gtk.Popover") || // allow child only on popover.
- prop.name == "attached_to" ||
- prop.name == "mnemonic_widget" ||
- prop.name == "application" ||
- prop.name == "transient_for" ||
- prop.name == "screen" || // gtk windows.
- prop.name == "accel_closure" ||
- prop.name == "accel_widget" ||
- prop.name == "label_widget" ||
- prop.name == "align_widget" ||
- prop.name == "icon_widget" ||
- prop.name == "action_target" ||
- prop.name == "related_action" || // not sure if we should disable this.
- prop.name == "visible_child" ||
- prop.name == "attach_widget" || // gtk menu
- prop.name == "relative_to" // popover
-
-
- ) {
- continue;
- }
-
-
-
- var propcls = this.getClass(prop.type);
- if (propcls == null) {
- continue;
- }
-
-
-
-
- // any other weird stuff.
- // Button.image -> can be a Gtk.Widget.. but really only makes sense as a Gtk.Image
- if (prop.name == "image" && propcls.name == "Gtk.Widget") {
- localopts_r.add( "Gtk.Image:image");
- continue;
-
- }
-
-
- // check if propcls is abstract?
- if (!propcls.is_abstract && propcls.nodetype != "Interface") {
- localopts_r.add( prop.type + ":" + prop.name);
- //GLib.debug("Add Widget Prop %s:%s (%s) - from %s", cls.fqn(), prop.name, prop.type, prop.propertyof);
- }
-
-
-
- //GLib.debug("Add Widget Prop %s:%s (%s) - from %s", cls.fqn(), prop.name, prop.type, prop.propertyof);
- foreach(var impl in propcls.implementations) {
- //GLib.debug("Add Widget Prop %s:%s (%s) - from %s", cls.fqn(), prop.name, prop.type, prop.propertyof);
- // in theory these can not be abstract?
-
- var impcls = this.getClass(impl);
- if (impcls.is_abstract || impcls.nodetype == "Interface") {
- continue;
- }
- //GLib.debug("Add Widget Prop %s:%s (%s)", cls.fqn(), prop.name, impl);
- localopts_r.add( impl + ":" + prop.name );
- }
-
-
-
-
- // lookup type -> is it an object
- // and not a enum..
- // if so then add it to localopts
-
- }
- if (localopts_r.size > 0) {
- this.map.add(new Usage(localopts_l, localopts_r));
- }
- }
-
-
-
-
-
- }
+
public string doc(string what)
{
var ns = what.split(".")[0];
var gir = Gir.factory(this.project,ns);
- return gir.doc(what);
+ return ((Gir) gir).doc(what);
//return typeof(this.comments[ns][what]) == 'undefined' ? '' : this.comments[ns][what];
}
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 GirObject? getClassOrEnum(string ename)
{
//print("Loading for " + ename);
-
+ this.load();
// if (typeof(this.proplist[ename]) != 'undefined') {
//print("using cache");
// return this.proplist[ename][type];
switch (ptype) {
case JsRender.NodePropType.PROP:
- return this.filterProps(cls.props);
+ 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:
foreach(var k in props.keys) {
var val = props.get(k);
- if (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.nodetype == "Enum") {
+ if ( cls != null ) { // cls.nodetype == "Enum") {
// assume it's ok
outprops.set(k,val);
continue;
}
+
+ 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)
{
}
- Gee.HashMap<string,Gee.ArrayList<JsRender.NodeProp>> node_defaults;
+ 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.ArrayList<JsRender.NodeProp>>();
+ 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.ListStore", "types", "/*\n fill in an array of { typeof(xxx), typeof(xxx) } \n */\n{\n\tttypeof(string)\n}");
- this.add_node_default("Gtk.TreeStore", "types", "/*\n fill in an array of { typeof(xxx), typeof(xxx) } \n */\n{\n\tttypeof(string)\n}");
-
-
- this.add_node_default_from_ctor("Gtk.Box", "new");
- this.add_node_default("Gtk.AccelLabel", "label", "Label");
-
-
- this.add_node_default_from_ctor("Gtk.AppChooserButton", "new");
- this.add_node_default_from_ctor("Gtk.AppChooserWidget", "new");
-
- this.add_node_default_from_ctor("Gtk.AspectFrame", "new");
-
- this.add_node_default("Gtk.Button", "label", "Label"); // these are not necessary
- this.add_node_default("Gtk.CheckButton", "label", "Label");
-
+
this.add_node_default("Gtk.ComboBox", "has_entry", "false");
this.add_node_default("Gtk.Expander", "label", "Label");
- this.add_node_default_from_ctor("Gtk.FileChooserButton", "new");
- this.add_node_default_from_ctor("Gtk.FileChooserWidget", "new");
+
this.add_node_default("Gtk.Frame", "label", "Label");
- this.add_node_default("Gtk.Grid", "columns", "2"); // special properties
+ 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_from_ctor("Gtk.LinkButton", "with_label");
- this.add_node_default_from_ctor("Gtk.Paned", "new");
+
this.add_node_default("Gtk.Scale", "orientation");
- this.add_node_default_from_ctor("Gtk.ScaleButton", "new"); /// ctor ignore optional array of strings at end?
- this.add_node_default_from_ctor("Gtk.Scrollbar", "new");
- this.add_node_default_from_ctor("Gtk.Separator", "new");
- this.add_node_default_from_ctor("Gtk.SpinButton", "new");
+
this.add_node_default("Gtk.ToggleButton", "label", "Label");
this.add_node_default("Gtk.MenuItem", "label", "Label");
this.add_node_default("Gtk.CheckItem", "label", "Label");
}
- public void add_node_default_from_ctor(string cls, string method )
+
+
+
+ private void add_node_default_from_ctor_all()
+ {
+
+ 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);
+ }
+ }
+
+ private void add_node_default_from_ctor_package(Gee.HashMap<string,GirObject> classes)
{
- GLib.debug("Add node from ctor %s:%s", cls, method);
- if (!this.node_defaults.has_key(cls)) {
- this.node_defaults.set(cls, new Gee.ArrayList<JsRender.NodeProp>());
+
+
+
+ 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.
}
+ // does not have new ?? needed?
+ foreach(var ctor in cls.ctors.values) {
+ this.add_node_default_from_ctor(ctor);
+ break;
+ }
+ }
+
+
+
+
+
+
+ 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;
+ }
+
+ var defs= this.node_defaults.get(cname);
- var ar = this.getPropertiesFor(cls, JsRender.NodePropType.CTOR);
- GLib.debug("ctor: %s", ar.get(method).asJSONString());
+ GLib.debug("ctor: %s: %s", cname , ctor.name);
// assume we are calling this for a reason...
//gtk box failing
//GLib.debug("No. of parmas %s %d", cls, ctor.params.size);
- var m = ar.get(method);
- if (m != null) {
-
+
+ foreach (var prop in ctor.paramset.params) {
+ string[] opts;
- foreach (var prop in m.paramset.params) {
- string[] opts;
-
- GLib.debug("adding proprty from ctor : %s, %s, %s", cls, prop.name, prop.type);
-
- var sub = this.getClass(prop.type);
- if (sub != null) { // can't add child classes here...
- GLib.debug("skipping ctor argument proprty is an object");
- continue;
- }
- var dval = "";
- switch (prop.type) {
- case "int":
- dval = "0";break;
- case "string":
- dval = ""; break;
- // anything else?
- default:
- this.typeOptions(cls, prop.name, prop.type, out opts);
- dval = opts.length > 0 ? opts[0] : "";
- break;
- }
-
- this.node_defaults.get(cls).add( new JsRender.NodeProp.prop( prop.name, prop.type, dval));
+ 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));
+
+
+
}
}
- public void add_node_default(string cls, string propname, string val = "")
+ private void add_node_default(string cname, string propname, string val = "")
{
- if (!this.node_defaults.has_key(cls)) {
- this.node_defaults.set(cls, new Gee.ArrayList<JsRender.NodeProp>());
+ if (!this.node_defaults.has_key(cname)) {
+ var add = new Gee.HashMap<string, JsRender.NodeProp>();
+ this.node_defaults.set(cname, add);
}
-
- var ar = getPropertiesFor( cls, JsRender.NodePropType.PROP);
+ // this recurses...
+ var cls = this.getClass(cname);
+ if (cls == null) {
+ GLib.debug("invalid class name %s", cname);
+ return;
+ }
+ 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(); // our nodes dont have default values.
+ var add = ar.get(propname).toNodeProp(this, cname); // our nodes dont have default values.
add.val = val;
- this.node_defaults.get(cls).add(add);
- } else {
- //GLib.debug("Class %s has property %s - adding special property", cls, propname);
- this.node_defaults.get(cls).add(
- new JsRender.NodeProp.special( propname, 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)
+ );
- }
}
- public void init_child_defaults()
+ private void init_child_defaults()
{
this.child_defaults = new Gee.HashMap<string,Gee.ArrayList<JsRender.NodeProp>>();
}
- public void add_child_default(string cls, string propname, string type, string val)
+ 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 override void on_child_added(JsRender.Node? parent,JsRender.Node child)
- {
-
- if (parent != null && !child.has("* prop")) { // child has a property - no need for child properties
-
- if (this.child_defaults.has_key(parent.fqn())) {
- foreach(var k in this.child_defaults.get(parent.fqn())) {
- if (!child.has(k.to_index_key())) {
- child.set_prop(k.dupe());
- }
- }
- }
- }
- if (this.node_defaults.has_key(child.fqn())) {
- foreach(var k in this.node_defaults.get(child.fqn())) {
-
- if (!child.has(k.to_index_key())) {
- GLib.debug("Adding Property %s", k.to_tooltip());
- child.set_prop(k.dupe());
- }
- }
- }
-
- // if child is a struct
- var childcls = this.getClass(child.fqn());
- if (childcls != null && childcls.nodetype == "Struct") {
- // then we need to add all the props.
- foreach(var prop in childcls.props.values) {
- child.set_prop(prop.toNodeProp());
-
-
- }
-
-
- }
- // any other combo?
- switch(parent.fqn()) {
- case "Gtk.Dialog":
- if (child.has("* prop") && child.get_prop("* prop").val == "buttons[]") {
- child.set_prop( new JsRender.NodeProp.special("response_id", "1"));
- }
- break;
-
- }
-
- // not really
- //this.fillPack(child, parent);
-
-
-
-
}
public Gee.ArrayList<string> packages(Project.Gtk gproject)
}
- public override List<SourceCompletionItem> suggestComplete(
- JsRender.JsRender file,
- JsRender.Node? node,
- JsRender.NodeProp? xxxprop, // is this even used?
- 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 ) {
- var sci = SourceCompletionItem.new2();
- //string label, string text, Pixbuf? icon, string? info)
- sci.label = ss;
- sci.text = ss;
- sci.info = "vala : " + ss;
- ret.append(sci);
- }
- }
- 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 ) {
-
- var sci = SourceCompletionItem.new2();
- //string label, string text, Pixbuf? icon, string? info)
- sci.label = ss;
- sci.text = ss;
- sci.info = "vala namespace: " + ss;
- ret.append(sci);
- }
- }
-
-
- if (complete_string != "_this" && "_this".index_of(complete_string,0) == 0 ) { // should we ignore exact matches... ???
-
- var sci = SourceCompletionItem.new2();
- //string label, string text, Pixbuf? icon, string? info)
- sci.label = "_this - the top level element";
- sci.text = "_this";
- sci.info = "Reference to the container object instance of this file";
- ret.append(sci);
- }
- // 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 = this.getClass(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 clsprop = cls.props.get(parts[i]);
- if (clsprop.type.index_of(".",0) > -1) {
- // type is another roo object..
- curtype = clsprop.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 = this.getClass(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..
- var sci = SourceCompletionItem.new2();
- //string label, string text, Pixbuf? icon, string? info)
- sci.label = prevbits + scls;
- sci.text = prevbits + scls;
- sci.info = scls;
-
- ret.append(sci);
- }
- // 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..
- var sci = SourceCompletionItem.new2();
- //string label, string text, Pixbuf? icon, string? info)
- sci.label = prevbits + scls + citer.get_value().sig;
- sci.text = prevbits + scls;
- sci.info = scls;
- ret.append(sci);
- }
-
- // 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..
-
- var sci = SourceCompletionItem.new2();
- //string label, string text, Pixbuf? icon, string? info)
- sci.label = prevbits + scls + citer.get_value().sig;
- sci.text = prevbits + scls;
- sci.info = scls;
- ret.append(sci);
- }
-
-
- return ret;
}
- print("matching property");
- if (cls == null) {
- return ret;
- }
-
-
- var citer = cls.methods.map_iterator();
- while (citer.next()) {
- var cprop = citer.get_value();
- // does the name start with ...
- if (parts[i].length > 0 && cprop.name.index_of(parts[i],0) != 0) {
- continue;
- }
- // got a matching property...
- // return type?
- var sci = SourceCompletionItem.new2();
- //string label, string text, Pixbuf? icon, string? info)
- sci.label = cprop.name + cprop.sig + " : ("+ cprop.propertyof + ")";
- sci.text = prevbits + cprop.name + "(";
- sci.info = cprop.doctxt;
-
- ret.append(sci);
+ 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 cprop = citer.get_value();
- // does the name start with ...
- if (parts[i].length > 0 && cprop.name.index_of(parts[i],0) != 0) {
- continue;
- }
- // got a matching property...
- var sci = SourceCompletionItem.new2();
- //string label, string text, Pixbuf? icon, string? info)
- sci.label = cprop.name + " : " + cprop.type + " ("+ cprop.propertyof + ")";
- sci.text = prevbits + cprop.name;
- sci.info = cprop.doctxt;
- ret.append(sci);
- }
-
-
- 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;
+
+
+
+ }
+
+
+
}
}