1 /* 2 These lines were written by an adorable little puppy sleeping on my keyboard. 3 / 4 oOO 5 \\_______/ 6 \======\ 7 || || 8 || || 9 10 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 11 2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222266 12 +36...................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................-8///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////8 13 */ 14 /** 15 Contains the core Component class. 16 This class will adapt itself at compile-time to a given DUI script. 17 */ 18 module declui.core; 19 20 import declui.components.component; 21 import declui.components.container; 22 import declui.backend; 23 import declui.parser; 24 25 import std.traits; 26 import std.typecons; 27 import std.format; 28 import std.conv; 29 30 private template symbolOfTag(Tag tag) 31 { 32 alias symbolOfTag = __traits(getMember, dui().getWidgets(), tag.name); 33 } 34 35 private template typeOfTag(Tag tag) 36 { 37 alias typeOfTag = ReturnType!(symbolOfTag!tag); 38 } 39 40 /** 41 This class will create a component from a Tag tree. 42 */ 43 class ComponentFromTag(Tag tag) : ReturnType!(__traits(getMember, ToolkitWidgets, tag.name)) 44 { 45 /* 46 These are all compile-time constructs that will automatically create the 47 class according to the DUI file passed in as a type argument. 48 */ 49 alias Type = ReturnType!(__traits(getMember, ToolkitWidgets, tag.name)); 50 51 private Type _instance; 52 53 private struct IdContainer 54 { 55 static foreach (tagged; tag.findIds) 56 { 57 mixin(format!`private %s _%s;`( 58 fullyQualifiedName!(typeOfTag!tagged), 59 tagged.id 60 )); 61 62 mixin(format! 63 `private void %s(%s value) 64 { 65 _%s = value; 66 }`( 67 tagged.id, 68 fullyQualifiedName!(typeOfTag!tagged), 69 tagged.id 70 )); 71 72 mixin(format! 73 `auto %s() 74 { 75 return _%s; 76 }`( 77 tagged.id, 78 tagged.id 79 )); 80 } 81 } 82 83 /** 84 A struct containing a reference to all children by their id. 85 */ 86 IdContainer byId; 87 88 /** 89 Creates the component and all child components. 90 */ 91 this(EventHandler)(EventHandler eventHandler) 92 { 93 _instance = __traits(getMember, dui().getWidgets(), tag.name)(); 94 static foreach (attribute; tag.attributes) 95 { 96 static if (attribute.type == AttributeType..string) 97 __traits(getMember, _instance, attribute.name)(attribute.value); 98 else static if (attribute.type == AttributeType.boolean) 99 __traits(getMember, _instance, attribute.name)(attribute.value.parse!bool); 100 else static if (attribute.type == AttributeType.integer) 101 __traits(getMember, _instance, attribute.name)(attribute.value.parse!int); 102 else static if (attribute.type == AttributeType.callback) 103 __traits(getMember, _instance, attribute.name)(&__traits(getMember, eventHandler, attribute.value)); 104 else 105 static assert(0, "Unsupported type " ~ attribute.type); 106 } 107 108 static if (tag.children.length > 0) 109 { 110 static foreach (child; tag.children) 111 { 112 static assert(__traits(hasMember, ToolkitWidgets, child.name), 113 "There is no tag with the name '" ~ child.name ~ "'"); 114 registerChild!(child)(new ComponentFromTag!(child)(eventHandler)); 115 } 116 } 117 } 118 119 private void registerChild(Tag tag, C)(C component) 120 { 121 _instance.add(component); 122 static if (tag.id.length > 0) 123 { 124 __traits(getMember, byId, tag.id) = component; 125 } 126 } 127 128 /* 129 Auto-generated getters and setters. 130 */ 131 static foreach (memberName; __traits(allMembers, Type)) 132 { 133 static foreach (member; __traits(getOverloads, Type, memberName)) 134 { 135 static if (Parameters!member.length > 0) 136 { 137 mixin(` 138 override %s %s(%s value) 139 { 140 return _instance.%s(value); 141 } 142 `.format( 143 fullyQualifiedName!(ReturnType!member), 144 memberName, 145 fullyQualifiedName!(Parameters!member[0]), 146 memberName) 147 ); 148 } 149 else 150 { 151 mixin(` 152 override %s %s() 153 { 154 return _instance.%s(); 155 } 156 `.format( 157 fullyQualifiedName!(ReturnType!member), 158 memberName, 159 memberName) 160 ); 161 } 162 } 163 } 164 } 165 166 /** 167 This class will parse a DUI file and automatically create a user interface based 168 on that DUI file. 169 170 Type Params: 171 file = The name of the DUI file. This file should be present in the views 172 directory and end with the `.dui` extension. 173 */ 174 abstract class Component(string file) : ComponentFromTag!(parseDUI!file) 175 { 176 private enum tag = parseDUI!file; 177 178 /// Instantiates a DUI file. 179 this() 180 { 181 super(this); 182 } 183 184 static foreach (callback; tag.findCallbacks) 185 { 186 mixin(format!"abstract void %s();"(callback)); 187 } 188 } 189 190 @("IContainer can have children") 191 unittest 192 { 193 enum tag = Tag("window", "", [], [Tag("label")]); // @suppress(dscanner.suspicious.unused_variable) 194 static struct EventHandler {} 195 new ComponentFromTag!(tag)(EventHandler()); 196 } 197 198 @("Non-IContainers cannot have children") 199 unittest 200 { 201 enum tag = Tag("label", "", [], [Tag("label")]); // @suppress(dscanner.suspicious.unused_variable) 202 static struct EventHandler {} 203 assert(!__traits(compiles, new ComponentFromTag!tag(EventHandler())), "Did compile Component, but shouldn't have"); 204 }