1 module dlangui.widgets.metadata;
2
3 import dlangui.widgets.widget;
4
5 interface WidgetMetadataDef {
6 Widget create();
7 /// short class name, e.g. "EditLine"
8 string className();
9 /// module name, e.g. "dlangui.widgets.editors"
10 string moduleName();
11 /// full class name, e.g. "dlangui.widgets.editors.EditLine"
12 string fullName();
13 }
14
15 struct WidgetSignalMetadata {
16 string name;
17 string typeString;
18 //TypeTuple
19 TypeInfo returnType;
20 TypeInfo paramsType;
21 }
22
23 private __gshared WidgetMetadataDef[string] _registeredWidgets;
24
25 WidgetMetadataDef findWidgetMetadata(string name) {
26 if (auto p = name in _registeredWidgets)
27 return *p;
28 return null;
29 }
30
31 void registerWidgetMetadata(string name, WidgetMetadataDef metadata) {
32 _registeredWidgets[name] = metadata;
33 }
34
35 WidgetSignalMetadata[] getSignalList(alias T)() {
36 WidgetSignalMetadata[] res;
37 foreach(m; __traits(allMembers, T)) {
38 static if (__traits(compiles, (typeof(__traits(getMember, T, m))))){
39 // skip non-public members
40 static if (__traits(getProtection, __traits(getMember, T, m)) == "public") {
41 static if (__traits(compiles, __traits(getMember, T, m).params_t ) && __traits(compiles, __traits(getMember, T, m).return_t)) {
42 alias ti = typeof(__traits(getMember, T, m));
43 res ~= WidgetSignalMetadata(m,
44 __traits(getMember, T, m).return_t.stringof ~ __traits(getMember, T, m).params_t.stringof,
45 typeid(__traits(getMember, T, m).return_t),
46 typeid(__traits(getMember, T, m).params_t));
47 }
48 }
49 }
50 }
51 return res;
52 }
53
54 string generateMetadataClass(alias t)() {
55 //pragma(msg, moduleName!t);
56 import std.traits;
57 //pragma(msg, getSignalList!t);
58 immutable string metadataClassName = t.stringof ~ "Metadata";
59 return "class " ~ metadataClassName ~ " : WidgetMetadataDef { \n" ~
60 " override Widget create() {\n" ~
61 " return new " ~ moduleName!t ~ "." ~ t.stringof ~ "();\n" ~
62 " }\n" ~
63 " override string className() {\n" ~
64 " return \"" ~ t.stringof ~ "\";\n" ~
65 " }\n" ~
66 " override string moduleName() {\n" ~
67 " return \"" ~ moduleName!t ~ "\";\n" ~
68 " }\n" ~
69 " override string fullName() {\n" ~
70 " return \"" ~ moduleName!t ~ "." ~ t.stringof ~ "\";\n" ~
71 " }\n" ~
72 "}\n";
73 }
74
75 string generateRegisterMetadataClass(alias t)() {
76 immutable string metadataClassName = t.stringof ~ "Metadata";
77 return "registerWidgetMetadata(\"" ~ t.stringof ~ "\", new " ~ metadataClassName ~ "());\n";
78 }
79
80 string registerWidgets(T...)(string registerFunctionName = "__gshared static this") {
81 string classDefs;
82 string registerDefs;
83 foreach(t; T) {
84 //pragma(msg, t.stringof);
85 //pragma(msg, moduleName!t);
86 //
87 immutable string classdef = generateMetadataClass!t;
88 //pragma(msg, classdef);
89 immutable string registerdef = generateRegisterMetadataClass!t;
90 //pragma(msg, registerdef);
91 classDefs ~= classdef;
92 registerDefs ~= registerdef;
93 //registerWidgetMetadata(T.stringof, new Metadata());
94 }
95 return classDefs ~ "\n" ~ registerFunctionName ~ "() {\n" ~ registerDefs ~ "}";
96 }
97
98 /// returns true if passed name is identifier of registered widget class
99 bool isWidgetClassName(string name) {
100 return (name in _registeredWidgets) !is null;
101 }
102