1 module formoshlep.widget; 2 3 import tags = dhtags.tags; 4 import attrs = dhtags.attrs; 5 import dhtags.tags.tag: HtmlFragment, HtmlString; 6 import vibe.http.server: HTTPServerRequest; 7 import std.conv: to; 8 import dlangui.core.events; 9 import openmethods; 10 mixin(registerMethods); 11 12 package: 13 14 struct FormoEvent 15 { 16 KeyEvent keyEvent; 17 MouseEvent mouseEvent; 18 } 19 20 // Custom Widget methods: 21 void readState(virtual!Widget, HTTPServerRequest); 22 FormoEvent[] getEvents(virtual!Widget, HTTPServerRequest); 23 HtmlFragment toHtml(virtual!Widget); 24 25 void readWidgetsState(Widget w, HTTPServerRequest req) 26 { 27 w.readState(req); 28 29 for(auto i = 0; i < w.childCount; i++) 30 w.child(i).readWidgetsState(req); 31 } 32 33 void processEvents(Widget w, HTTPServerRequest req) 34 { 35 FormoEvent[] events = w.getEvents(req); 36 37 foreach(e; events) 38 { 39 if(e.keyEvent !is null) 40 w.onKeyEvent(e.keyEvent); 41 42 if(e.mouseEvent !is null) 43 w.onMouseEvent(e.mouseEvent); 44 } 45 46 for(auto i = 0; i < w.childCount; i++) 47 w.child(i).processEvents(req); 48 } 49 50 public: 51 52 // Custom methods implementation: 53 import dlangui.widgets.widget: Widget; 54 @method void _readState(Widget w, HTTPServerRequest req) {} 55 @method FormoEvent[] _getEvents(Widget w, HTTPServerRequest req) { return null; } 56 @method HtmlFragment _toHtml(Widget w) { assert(false, "HTML output isn't implemented"); } 57 58 import dlangui.widgets.controls: TextWidget; 59 @method HtmlFragment _toHtml(TextWidget w) 60 { 61 return tags.span(w.text.to!string).addStyle(w); 62 } 63 64 import dlangui.widgets.editors: EditLine; 65 @method void _readState(EditLine w, HTTPServerRequest req) 66 { 67 if(req.form.get(w.id, "IMPOSSIBLE_VALUE") != "IMPOSSIBLE_VALUE") //FIXME: remove that shit 68 w.text = req.form.get(w.id).to!dstring; 69 } 70 @method FormoEvent[] _getEvents(EditLine w, HTTPServerRequest req) 71 { 72 import std.exception: enforce; 73 74 enforce(w.action is null); 75 76 return null; 77 } 78 @method HtmlFragment _toHtml(EditLine w) 79 { 80 return tags.input(attrs.type="text", attrs.name=w.id, attrs.value=w.text.to!string, attrs.style=w.styleStr); 81 } 82 83 import dlangui.widgets.controls: Button; 84 @method HtmlFragment _toHtml(Button w) 85 { 86 return tags.input(attrs.type="submit", attrs.name=w.id, attrs.value=w.text.to!string, attrs.style=w.styleStr); 87 } 88 @method FormoEvent[] _getEvents(Button w, HTTPServerRequest req) 89 { 90 if(req.form.get(w.id) is null) 91 return null; 92 else 93 return 94 [ 95 FormoEvent(null, new MouseEvent(MouseAction.ButtonDown, MouseButton.Left, 0, -10, -10, 0)), 96 FormoEvent(null, new MouseEvent(MouseAction.ButtonUp, MouseButton.Left, 0, -10, -10, 0)) 97 ]; 98 } 99 100 import dlangui.widgets.controls: ImageWidget; 101 @method HtmlFragment _toHtml(ImageWidget w) 102 { 103 assert(w.drawable !is null); 104 105 import dlangui.graphics.resources: drawableCache; 106 107 auto d = w.drawable; 108 109 return tags.img(attrs.src="/res/"~drawableCache._idToDrawableMap[w.drawableId]._filename, attrs.width=d.width, attrs.height=d.height); 110 } 111 112 113 import dlangui.widgets.controls: ImageTextButton; 114 @method HtmlFragment _toHtml(ImageTextButton w) 115 { 116 return 117 tags.button 118 ( 119 (cast(LinearLayout) w)._toHtml 120 ); 121 } 122 123 import dlangui.widgets.layouts: LinearLayout, Orientation; 124 @method HtmlFragment _toHtml(LinearLayout w) 125 { 126 final switch(w.orientation) 127 { 128 case Orientation.Horizontal: 129 string ret; 130 131 for(auto i = 0; i < w.childCount; i++) 132 ret ~= w.child(i).toHtml.toString(false); 133 134 return tags.div(attrs.style="width: auto; float: left")(ret); 135 136 case Orientation.Vertical: 137 string ret; 138 139 for(auto i = 0; i < w.childCount; i++) 140 ret ~= 141 tags.div(attrs.style="clear: both") 142 ( 143 w.child(i).toHtml 144 ).toString(false); 145 146 return tags.div(attrs.style="float: left")(ret); 147 } 148 } 149 150 private: 151 152 static this() 153 { 154 updateMethods(); 155 } 156 157 string styleStr(Widget w) 158 { 159 import std.format; 160 161 auto s = w.ownStyle; 162 163 return 164 "color: "~s.textColor.format!"#%06X; "~ 165 "font-size: "~s.fontSize.to!string~"px; "~ 166 "font-weight: "~s.fontWeight.to!string; 167 } 168 169 import dhtags.tags.tag: HtmlTag; 170 171 HtmlTag addStyle(HtmlTag tag, Widget w) 172 { 173 import dhtags.attrs.attribute: HtmlAttribute; 174 175 tag.attrs ~= HtmlAttribute("style", w.styleStr); 176 177 return tag; 178 }