| 1 |
//wrapper for Andrew Fedoniouk's excellent HTMLayout (3.2.2.13) - http://www.terrainformatica.com/ |
|---|
| 2 |
|
|---|
| 3 |
//todo: make the event struct wrappers (i.e. HMouse, HKey, etc) return HElement everywhere, not HELEMENT |
|---|
| 4 |
//todo: wrap HTMLayoutElementSetExpando, HTMLayoutElementGetExpando |
|---|
| 5 |
//todo: complete HJson templates {fromAA,toAA,fromArray,toArray}; HJson.toString should work with arrays and maps maybe |
|---|
| 6 |
//todo: wrap HRange propperly |
|---|
| 7 |
//todo: handleEvent(size) followed by handleEvent(draw) makes draw to not work, but vice versa works |
|---|
| 8 |
//todo: port Andrew's hpp behaviors (or get some ideas from them) |
|---|
| 9 |
//todo: flowerd.skin: msgBox, SkinnedWindow.icon, dropped files (and other dropped stuff) handler, HSkinLite |
|---|
| 10 |
//todo: add scripting support |
|---|
| 11 |
//todo: add mootools style animator class |
|---|
| 12 |
|
|---|
| 13 |
/* |
|---|
| 14 |
|
|---|
| 15 |
changelog: |
|---|
| 16 |
|
|---|
| 17 |
0.7 |
|---|
| 18 |
JSON_VALUE.toString is not including the terminating null character for strings anymore |
|---|
| 19 |
added shortcuts for all HElement states (most of which are only getters; i.e. readOnly, disabled, checked, etc.) |
|---|
| 20 |
made HJson a separate class instead of alias of JSON_VALUE |
|---|
| 21 |
upadated to HTMLayout 3.2.2.13 (new HDataArrived members) |
|---|
| 22 |
added HJson.V_BYTES |
|---|
| 23 |
renamed HLayout.elementByUID to HLayout.getUID |
|---|
| 24 |
added HElement.location |
|---|
| 25 |
added HElement.isInside |
|---|
| 26 |
added flowerd.sharedlib, which can now load HTMLayout from memory |
|---|
| 27 |
added HBehavior.reset and HBehavior.resetAll . This is intended to be used if HTMLayout is unloaded and loaded again in the lifetime of the application |
|---|
| 28 |
|
|---|
| 29 |
0.6 |
|---|
| 30 |
renamed flowerd.flowerd to flowerd.dfl |
|---|
| 31 |
added flowerd.dwt |
|---|
| 32 |
added htmlayout.behavior.translatable |
|---|
| 33 |
removed HElement.setAttribute and HElement.setStyle and HElement.setState (these was because of flowerscript, which ain't gonna be) |
|---|
| 34 |
removed the Object parameter from all event handler delegates and put 'param' member in the appropriate struct instead |
|---|
| 35 |
added HDialogCreated struct |
|---|
| 36 |
changed the param of DOCUMENT_LOADED and DOCUMENT_COMPLETE notification to HReady instead of int |
|---|
| 37 |
renamed HElement.byId to HElement.getId and HElement.byTag to HElement.getTag |
|---|
| 38 |
renamed HElement.type to HElement.tag |
|---|
| 39 |
renamed HEventHandler.tag to HEventHandler.htag |
|---|
| 40 |
made this syntax possible: HElement.style["display"]="none"; |
|---|
| 41 |
added HElement.handleStatic, HElement.unhandleStatic that will not erase the event handlers for the element when the HElement object is destoyed. I.e. the event handler will be GC proof. handleStatic will take precedence before handleEvent |
|---|
| 42 |
added HElement.opIndex, HElement.opIndexAssign which is working with the element's attrinutes |
|---|
| 43 |
added HELement.opCall, HScrollBar.opCall, HEditBox.opCall |
|---|
| 44 |
modified HLite.render to make use of the x and y parameters |
|---|
| 45 |
updated to HTMLayout 3.2.2.8 (drag and drop) |
|---|
| 46 |
updated to HTMLayout 3.2.2.5 (graphin) |
|---|
| 47 |
removed the dependency of DFL for Win32 headers, now using tango.sys.win32.Types |
|---|
| 48 |
fixed few potential bugs similar to the one in 0.5 |
|---|
| 49 |
some small code cleanups |
|---|
| 50 |
|
|---|
| 51 |
0.5 |
|---|
| 52 |
fixed bug in HJson.opCall(char[]) |
|---|
| 53 |
|
|---|
| 54 |
0.4: |
|---|
| 55 |
fixed HElement.showPopup |
|---|
| 56 |
added HElement.showAsPopup, HElement.showAsPopupAt |
|---|
| 57 |
added additional parameter to HElement.addClass and HElement.delClass |
|---|
| 58 |
|
|---|
| 59 |
0.3: |
|---|
| 60 |
added HJson.parse, JSon.toBool |
|---|
| 61 |
added missing alias for UI_STATE_CHANGED |
|---|
| 62 |
added HElement.hasClass, HElement.scrollPos(POINT), HElement.viewSize |
|---|
| 63 |
renamed HElement.setCapture to capture |
|---|
| 64 |
|
|---|
| 65 |
0.2: |
|---|
| 66 |
wrapped all event structures. MOUSE_PARAMS becomes HMouse, etc. (params is omitted) |
|---|
| 67 |
aliased all METHOD_PARAMS derivatives like HXcall, HTextValue, etc. (params is omitted) |
|---|
| 68 |
wrapped JSON_VALUE (aliased as HJson; only partially tested) |
|---|
| 69 |
HElement is not increasing the ref count of the element by default anymore. call HElement.keep explicitly if you need it |
|---|
| 70 |
HLayoutBase,HLayout and HLite are now handling the events just like HElement (with handleEvent) |
|---|
| 71 |
added HElement.click, HElement.xcall |
|---|
| 72 |
added HEditBox, HScrollBar |
|---|
| 73 |
|
|---|
| 74 |
0.1: |
|---|
| 75 |
first release |
|---|
| 76 |
|
|---|
| 77 |
*/ |
|---|
| 78 |
|
|---|
| 79 |
module htmlayout.htmlayout; |
|---|
| 80 |
|
|---|
| 81 |
public import htmlayout.capi; |
|---|
| 82 |
public import htmlayout.events; |
|---|
| 83 |
public import htmlayout.element; |
|---|
| 84 |
public import htmlayout.graphin; |
|---|
| 85 |
import tango.stdc.stringz; |
|---|
| 86 |
import tango.text.convert.Utf; |
|---|
| 87 |
import tango.io.File; |
|---|
| 88 |
import tango.io.FileSystem; |
|---|
| 89 |
import tango.io.FilePath; |
|---|
| 90 |
import tango.sys.win32.Types; |
|---|
| 91 |
|
|---|
| 92 |
extern(Windows) BOOL OffsetViewportOrgEx( |
|---|
| 93 |
HDC hdc, // handle to device context |
|---|
| 94 |
int nXOffset, // horizontal offset |
|---|
| 95 |
int nYOffset, // vertical offset |
|---|
| 96 |
LPPOINT lpPoint // original origin |
|---|
| 97 |
); |
|---|
| 98 |
|
|---|
| 99 |
template EVENT_HANDLER_STRING0(char[] RETURNTYPE,char[] NAME,char[] TYPE,char[] EVENT) |
|---|
| 100 |
{ |
|---|
| 101 |
const EVENT_HANDLER_STRING0 = |
|---|
| 102 |
RETURNTYPE~" on"~NAME~"("~(TYPE.length?TYPE~" e":"")~") {return dg"~NAME~".call("~(TYPE.length?"e":"")~");}"~ |
|---|
| 103 |
"protected alias Handlers!("~RETURNTYPE~(TYPE.length?","~TYPE:"")~") dg"~NAME~"_t;"~ |
|---|
| 104 |
"protected dg"~NAME~"_t mdg"~NAME~";"~ |
|---|
| 105 |
"protected dg"~NAME~"_t dg"~NAME~"(){if(mdg"~NAME~" is null) mdg"~NAME~"=new dg"~NAME~"_t; return mdg"~NAME~";}"~ |
|---|
| 106 |
"bool handleEvent("~RETURNTYPE~" delegate("~(TYPE.length?TYPE:"")~") dg,Object param=null){return dg"~NAME~".add(dg,param);}"~ |
|---|
| 107 |
"bool unhandleEvent("~RETURNTYPE~" delegate("~(TYPE.length?TYPE:"")~") dg){return dg"~NAME~".del(dg);}"; |
|---|
| 108 |
} |
|---|
| 109 |
|
|---|
| 110 |
abstract class HLayoutBase : HEventHandler |
|---|
| 111 |
{ |
|---|
| 112 |
this(char[] mediatype="screen") |
|---|
| 113 |
{ |
|---|
| 114 |
if(!mediaType(mediatype)) throw new Exception("Error setting media type"); |
|---|
| 115 |
} |
|---|
| 116 |
|
|---|
| 117 |
HElement rootElement(){lastResult=HPR_INVALID_STATE;return null;} |
|---|
| 118 |
HElement findElement(INT x, INT y){lastResult=HPR_INVALID_STATE;return null;} |
|---|
| 119 |
bool mediaType(char[] mediatype){return false;} |
|---|
| 120 |
bool loadHTML(char[] url,char[] data){return false;} |
|---|
| 121 |
bool loadHTML(char[] file) |
|---|
| 122 |
{ |
|---|
| 123 |
char[] buf; |
|---|
| 124 |
scope(exit) delete buf; |
|---|
| 125 |
try (buf=cast(char[])File(file).read()); |
|---|
| 126 |
catch(Object o) |
|---|
| 127 |
{ |
|---|
| 128 |
lastResult=HPRESULT.HPR_FILE_NOT_FOUND; |
|---|
| 129 |
return false; |
|---|
| 130 |
} |
|---|
| 131 |
return loadHTML(FileSystem.toAbsolute(FilePath(file)).toString,buf); |
|---|
| 132 |
} |
|---|
| 133 |
bool masterCSS(char[] data,bool append=true) |
|---|
| 134 |
{ |
|---|
| 135 |
if(append) return cast(bool)HTMLayoutAppendMasterCSS(cast(LPCBYTE)data.ptr,data.length); |
|---|
| 136 |
else return cast(bool)HTMLayoutSetMasterCSS(cast(LPCBYTE)data.ptr,data.length); |
|---|
| 137 |
} |
|---|
| 138 |
bool renderBitmap(HBITMAP hbmp, INT x, INT y, INT w, INT h) {return false;} |
|---|
| 139 |
bool traverseUIEvent(UINT evt,PVOID eventCtlStruct,out bool bProcessed){return false;} |
|---|
| 140 |
bool declareElement(char[] type,UINT elementModel) {return cast(bool)HTMLayoutDeclareElementType(toStringz(type),elementModel);} |
|---|
| 141 |
|
|---|
| 142 |
HPRESULT lastResult; |
|---|
| 143 |
char[] lastResultMsg() |
|---|
| 144 |
{ |
|---|
| 145 |
if(lastResult==HPR_OK) return "HPR_OK"; |
|---|
| 146 |
else if(lastResult==HPR_INVALID_HANDLE) return "HPR_INVALID_HANDLE"; |
|---|
| 147 |
else if(lastResult==HPR_INVALID_FORMAT) return "HPR_INVALID_FORMAT"; |
|---|
| 148 |
else if(lastResult==HPR_FILE_NOT_FOUND) return "HPR_FILE_NOT_FOUND"; |
|---|
| 149 |
else if(lastResult==HPR_INVALID_PARAMETER) return "HPR_INVALID_PARAMETER"; |
|---|
| 150 |
else if(lastResult==HPR_INVALID_STATE) return "HPR_INVALID_STATE"; |
|---|
| 151 |
else return null; |
|---|
| 152 |
} |
|---|
| 153 |
|
|---|
| 154 |
mixin(EVENT_HANDLER_STRING0!("bool","LoadData","HLoadData","HLN_LOAD_DATA")); |
|---|
| 155 |
mixin(EVENT_HANDLER_STRING0!("bool","DataLoaded","HDataLoaded","HLN_DATA_LOADED")); |
|---|
| 156 |
mixin(EVENT_HANDLER_STRING0!("bool","CreateControl","HCreateControl","HLN_CREATE_CONTROL")); |
|---|
| 157 |
mixin(EVENT_HANDLER_STRING0!("bool","ControlCreated","HControlCreated","HLN_CONTROL_CREATED")); |
|---|
| 158 |
mixin(EVENT_HANDLER_STRING0!("bool","DestroyControl","HDestroyControl","HLN_DESTROY_CONTROL")); |
|---|
| 159 |
mixin(EVENT_HANDLER_STRING0!("bool","AttachBehavior","HAttachBehavior","HLN_ATTACH_BEHAVIOR")); |
|---|
| 160 |
mixin(EVENT_HANDLER_STRING0!("bool","BehaviorChanged","HBehaviorChanged","HLN_BEHAVIOR_CHANGED")); |
|---|
| 161 |
mixin(EVENT_HANDLER_STRING0!("bool","Ready","HReady","HLN_DOCUMENT_COMPLETE+HLN_DOCUMENT_LOADED")); |
|---|
| 162 |
|
|---|
| 163 |
protected: |
|---|
| 164 |
|
|---|
| 165 |
UINT mBaseCallback(LPNMHDR hdr) |
|---|
| 166 |
{ |
|---|
| 167 |
if(hdr.code==HLN_CREATE_CONTROL) return onCreateControl(HCreateControl(cast(LPNMHL_CREATE_CONTROL)hdr)); |
|---|
| 168 |
else if(hdr.code==HLN_CONTROL_CREATED) return onControlCreated(HControlCreated(cast(LPNMHL_CREATE_CONTROL)hdr)); |
|---|
| 169 |
else if(hdr.code==HLN_LOAD_DATA) return onLoadData(HLoadData(cast(LPNMHL_LOAD_DATA)hdr)); |
|---|
| 170 |
else if(hdr.code==HLN_DATA_LOADED) return onDataLoaded(HDataLoaded(cast(LPNMHL_DATA_LOADED)hdr)); |
|---|
| 171 |
else if(hdr.code==HLN_DESTROY_CONTROL) return onDestroyControl(HDestroyControl(cast(LPNMHL_DESTROY_CONTROL)hdr)); |
|---|
| 172 |
else if(hdr.code==HLN_ATTACH_BEHAVIOR) |
|---|
| 173 |
{ |
|---|
| 174 |
auto a=HAttachBehavior(cast(LPNMHL_ATTACH_BEHAVIOR)hdr); |
|---|
| 175 |
if(onAttachBehavior(a)) return true; |
|---|
| 176 |
else |
|---|
| 177 |
{ |
|---|
| 178 |
auto b=HBehavior.find(a.name); |
|---|
| 179 |
if(b) |
|---|
| 180 |
{ |
|---|
| 181 |
a.elementProc=b.callback; |
|---|
| 182 |
a.elementTag=b.htag; |
|---|
| 183 |
a.elementEvents=b.events; |
|---|
| 184 |
return true; |
|---|
| 185 |
} |
|---|
| 186 |
else return false; |
|---|
| 187 |
} |
|---|
| 188 |
} |
|---|
| 189 |
else if(hdr.code==HLN_BEHAVIOR_CHANGED) return onBehaviorChanged(HBehaviorChanged(cast(LPNMHL_BEHAVIOR_CHANGED)hdr)); |
|---|
| 190 |
else if(hdr.code==HLN_DOCUMENT_LOADED || hdr.code==HLN_DOCUMENT_COMPLETE) return onReady(HReady(hdr.code)); |
|---|
| 191 |
else |
|---|
| 192 |
{ |
|---|
| 193 |
//tango.io.Stdout.Stdout(cast(int)hdr.code).newline.flush; |
|---|
| 194 |
return false; |
|---|
| 195 |
} |
|---|
| 196 |
} |
|---|
| 197 |
|
|---|
| 198 |
protected: |
|---|
| 199 |
} |
|---|
| 200 |
|
|---|
| 201 |
class HLite : HLayoutBase |
|---|
| 202 |
{ |
|---|
| 203 |
this(char[] mediatype="screen") |
|---|
| 204 |
{ |
|---|
| 205 |
mHandle=HTMLiteCreateInstance(); |
|---|
| 206 |
mHandles[mHandle]=this; |
|---|
| 207 |
mHandles.rehash; |
|---|
| 208 |
if(HTMLiteSetCallback(mHandle,&mCallback)!=HPR_OK) throw new Exception("Error setting HTMLite callback"); |
|---|
| 209 |
super(mediatype); |
|---|
| 210 |
} |
|---|
| 211 |
~this() |
|---|
| 212 |
{ |
|---|
| 213 |
mHandles.remove(mHandle); |
|---|
| 214 |
HTMLiteDestroyInstance(mHandle); |
|---|
| 215 |
} |
|---|
| 216 |
|
|---|
| 217 |
HElement rootElement() |
|---|
| 218 |
{ |
|---|
| 219 |
HELEMENT hret; |
|---|
| 220 |
if((lastResult=HTMLiteGetRootElement(mHandle,&hret))==HPR_OK) return new HElement(hret); |
|---|
| 221 |
else return null; |
|---|
| 222 |
} |
|---|
| 223 |
|
|---|
| 224 |
HElement findElement(INT x, INT y) |
|---|
| 225 |
{ |
|---|
| 226 |
HELEMENT hret; |
|---|
| 227 |
if((lastResult=HTMLiteFindElement(mHandle,x,y,&hret))==HPR_OK) return new HElement(hret); |
|---|
| 228 |
else return null; |
|---|
| 229 |
} |
|---|
| 230 |
|
|---|
| 231 |
bool loadHTML(char[] url,char[] data){return (lastResult=HTMLiteLoadHtmlFromMemory(mHandle,toString16z(.toString16(url)),cast(LPCBYTE)toStringz(data),data.length))==HPR_OK;} |
|---|
| 232 |
bool loadHTML(char[] file){return HTMLiteLoadHtmlFromFile(mHandle,toString16z(.toString16(FileSystem.toAbsolute(FilePath(file)).toString)))==HPR_OK;} |
|---|
| 233 |
bool mediaType(char[] mediatype){return (lastResult=HTMLiteSetMediaType(mHandle,toStringz(mediatype)))==HPR_OK;} |
|---|
| 234 |
|
|---|
| 235 |
HPRESULT measure(INT viewWidth, INT viewHeight) {return HTMLiteMeasure (mHandle,viewWidth,viewHeight);} |
|---|
| 236 |
HPRESULT render(HDC hdc, INT x, INT y, INT w, INT h) |
|---|
| 237 |
{ |
|---|
| 238 |
POINT p; |
|---|
| 239 |
OffsetViewportOrgEx(hdc,x,y,&p); |
|---|
| 240 |
scope(exit) OffsetViewportOrgEx(hdc,p.x,p.y,null); |
|---|
| 241 |
return HTMLiteRender (mHandle,hdc,x,y,w,h); |
|---|
| 242 |
} |
|---|
| 243 |
|
|---|
| 244 |
bool renderBitmap(HBITMAP hbmp, INT x, INT y, INT w, INT h) {return (lastResult=HTMLiteRenderOnBitmap (mHandle,hbmp,x,y,w,h))==HPR_OK;} |
|---|
| 245 |
HPRESULT dataReady(char[] url,void[] data){return HTMLiteSetDataReady (mHandle,toStringz(url),cast(LPCBYTE)data.ptr,data.length);} |
|---|
| 246 |
INT minWidth() |
|---|
| 247 |
{ |
|---|
| 248 |
INT ret; |
|---|
| 249 |
if((lastResult=HTMLiteGetDocumentMinWidth(mHandle,&ret))==HPR_OK) return ret; |
|---|
| 250 |
else return -1; |
|---|
| 251 |
} |
|---|
| 252 |
INT minHeight() |
|---|
| 253 |
{ |
|---|
| 254 |
INT ret; |
|---|
| 255 |
if((lastResult=HTMLiteGetDocumentMinHeight(mHandle,&ret))==HPR_OK) return ret; |
|---|
| 256 |
else return -1; |
|---|
| 257 |
} |
|---|
| 258 |
|
|---|
| 259 |
bool traverseUIEvent(UINT evt,PVOID eventCtlStruct,out bool bProcessed) |
|---|
| 260 |
{ |
|---|
| 261 |
BOOL bOutProcessed; |
|---|
| 262 |
auto ret=cast(bool)HTMLiteTraverseUIEvent(mHandle,evt,eventCtlStruct,&bOutProcessed); |
|---|
| 263 |
bProcessed=cast(bool)bOutProcessed; |
|---|
| 264 |
return ret; |
|---|
| 265 |
} |
|---|
| 266 |
|
|---|
| 267 |
bool advanceFocus(UINT where) |
|---|
| 268 |
{ |
|---|
| 269 |
BOOL res; |
|---|
| 270 |
if((lastResult=HTMLiteAdvanceFocus(mHandle,where,&res))==HPR_OK) return cast(bool)res; |
|---|
| 271 |
else return false; |
|---|
| 272 |
} |
|---|
| 273 |
|
|---|
| 274 |
mixin(EVENT_HANDLER_STRING0!("bool","RefreshArea","HRefreshArea","HLN_REFRESH_AREA")); |
|---|
| 275 |
mixin(EVENT_HANDLER_STRING0!("bool","SetTimer","HSetTimer","HLN_SET_TIMER")); |
|---|
| 276 |
mixin(EVENT_HANDLER_STRING0!("bool","SetCursor","HSetCursor","HLN_SET_CURSOR")); |
|---|
| 277 |
mixin(EVENT_HANDLER_STRING0!("bool","UpdateUI","","HLN_UPDATE_UI")); |
|---|
| 278 |
|
|---|
| 279 |
protected: |
|---|
| 280 |
|
|---|
| 281 |
extern(Windows) static UINT mCallback(HTMLITE hLite,LPNMHDR hdr) |
|---|
| 282 |
{ |
|---|
| 283 |
auto lite=hLite in mHandles; |
|---|
| 284 |
if(lite is null) throw new Exception("Error handling event"); |
|---|
| 285 |
|
|---|
| 286 |
if(hdr.code==HLN_REFRESH_AREA) return lite.onRefreshArea(HRefreshArea(cast(LPNMHL_REFRESH_AREA)hdr)); |
|---|
| 287 |
else if(hdr.code==HLN_SET_TIMER) return lite.onSetTimer(HSetTimer(cast(LPNMHL_SET_TIMER)hdr)); |
|---|
| 288 |
else if(hdr.code==HLN_SET_CURSOR) return lite.onSetCursor(HSetCursor(cast(LPNMHL_SET_CURSOR)hdr)); |
|---|
| 289 |
else if(hdr.code==HLN_UPDATE_UI) return lite.onUpdateUI(); |
|---|
| 290 |
else return lite.mBaseCallback(hdr); |
|---|
| 291 |
} |
|---|
| 292 |
|
|---|
| 293 |
static HLite[HTMLITE] mHandles; |
|---|
| 294 |
HTMLITE mHandle; |
|---|
| 295 |
} |
|---|
| 296 |
|
|---|
| 297 |
class HLayout : HLayoutBase |
|---|
| 298 |
{ |
|---|
| 299 |
this(HWND handle,char[] mediatype="screen") |
|---|
| 300 |
{ |
|---|
| 301 |
mHandle=handle; |
|---|
| 302 |
mHandles[mHandle]=this; |
|---|
| 303 |
mHandles.rehash; |
|---|
| 304 |
HTMLayoutSetCallback(mHandle,&mCallback,mHandle); |
|---|
| 305 |
super(mediatype); |
|---|
| 306 |
} |
|---|
| 307 |
|
|---|
| 308 |
static char[] className8() {return fromStringz(HTMLayoutClassNameA());} |
|---|
| 309 |
static wchar[] className16() {return fromString16z(HTMLayoutClassNameW());} |
|---|
| 310 |
bool dataReady(char[] uri,void[] data) {return cast(bool)HTMLayoutDataReady (mHandle, toString16z(toString16(uri)), cast(LPBYTE)data.ptr, data.length);} |
|---|
| 311 |
bool dataReadyAsync(char[] uri,void[] data, UINT dataType) {return cast(bool)HTMLayoutDataReadyAsync (mHandle, toString16z(toString16(uri)), cast(LPBYTE)data.ptr, data.length,dataType);} |
|---|
| 312 |
LRESULT defProc(UINT msg, WPARAM wParam, LPARAM lParam) {return HTMLayoutProc (mHandle, msg, wParam, lParam);} |
|---|
| 313 |
LRESULT defProcND(UINT msg, WPARAM wParam, LPARAM lParam, out bool pbHandled) |
|---|
| 314 |
{ |
|---|
| 315 |
BOOL res; |
|---|
| 316 |
auto ret=HTMLayoutProcND (mHandle, msg, wParam, lParam, &res); |
|---|
| 317 |
pbHandled=cast(bool)res; |
|---|
| 318 |
return ret; |
|---|
| 319 |
} |
|---|
| 320 |
UINT minWidth() {return HTMLayoutGetMinWidth(mHandle);} |
|---|
| 321 |
UINT minHeight(UINT width) {return HTMLayoutGetMinHeight(mHandle,width);} |
|---|
| 322 |
bool loadHTML(char[] url,char[] data) |
|---|
| 323 |
{ |
|---|
| 324 |
if(url is null) return cast(bool)HTMLayoutLoadHtml(mHandle,cast(LPCBYTE)(toStringz(data)),data.length); |
|---|
| 325 |
else return cast(bool)HTMLayoutLoadHtmlEx(mHandle,cast(LPCBYTE)(toStringz(data)),data.length,toString16z(.toString16(url))); |
|---|
| 326 |
} |
|---|
| 327 |
bool loadHTML(char[] file){return cast(bool)HTMLayoutLoadFile(mHandle,toString16z(.toString16(FileSystem.toAbsolute(FilePath(file)).toString)));} |
|---|
| 328 |
bool mediaType(char[] mediatype){return true;return cast(bool)HTMLayoutSetMediaType(mHandle,toString16z(toString16(mediatype)));} |
|---|
| 329 |
|
|---|
| 330 |
void mode(int HTMLayoutMode) {return HTMLayoutSetMode(mHandle,HTMLayoutMode);} |
|---|
| 331 |
bool selectionExist() {return cast(bool)HTMLayoutSelectionExist(mHandle);} |
|---|
| 332 |
char[] selectedHTML() |
|---|
| 333 |
{ |
|---|
| 334 |
UINT pSize; |
|---|
| 335 |
auto ret=HTMLayoutGetSelectedHTML(mHandle,&pSize); |
|---|
| 336 |
return (cast(char*)ret)[0..pSize]; |
|---|
| 337 |
} |
|---|
| 338 |
bool clipboardCopy() {return cast(bool)HTMLayoutClipboardCopy(mHandle);} |
|---|
| 339 |
HElement rootElement() |
|---|
| 340 |
{ |
|---|
| 341 |
HELEMENT hret; |
|---|
| 342 |
if((lastResult=HTMLayoutGetRootElement(mHandle,&hret))==HLDOM_OK) return new HElement(hret); |
|---|
| 343 |
else return null; |
|---|
| 344 |
} |
|---|
| 345 |
|
|---|
| 346 |
HElement findElement(INT x, INT y) |
|---|
| 347 |
{ |
|---|
| 348 |
HELEMENT hret; |
|---|
| 349 |
if((lastResult=HTMLayoutFindElement(mHandle,POINT(x,y),&hret))==HLDOM_OK) return new HElement(hret); |
|---|
| 350 |
else return null; |
|---|
| 351 |
} |
|---|
| 352 |
|
|---|
| 353 |
HElement focusElement() |
|---|
| 354 |
{ |
|---|
| 355 |
HELEMENT hret; |
|---|
| 356 |
if((lastResult=HTMLayoutGetFocusElement(mHandle,&hret))==HLDOM_OK) return new HElement(hret); |
|---|
| 357 |
else return null; |
|---|
| 358 |
} |
|---|
| 359 |
|
|---|
| 360 |
HElement getUID(UINT uid) |
|---|
| 361 |
{ |
|---|
| 362 |
HELEMENT hret; |
|---|
| 363 |
if((lastResult=HTMLayoutGetElementByUID(mHandle,uid,&hret))==HLDOM_OK) return new HElement(hret); |
|---|
| 364 |
else return null; |
|---|
| 365 |
} |
|---|
| 366 |
|
|---|
| 367 |
bool traverseUIEvent(UINT evt,PVOID eventCtlStruct,out bool bProcessed) |
|---|
| 368 |
{ |
|---|
| 369 |
BOOL bOutProcessed; |
|---|
| 370 |
auto ret=cast(bool)HTMLayoutTraverseUIEvent(evt,eventCtlStruct,&bOutProcessed); |
|---|
| 371 |
bProcessed=cast(bool)bOutProcessed; |
|---|
| 372 |
return ret; |
|---|
| 373 |
} |
|---|
| 374 |
|
|---|
| 375 |
bool renderBitmap(HBITMAP hbmp, INT x, INT y, INT w, INT h) {return cast(bool)HTMLayoutRender(mHandle,hbmp,RECT(x,y,w,h));} |
|---|
| 376 |
|
|---|
| 377 |
UINT enumResources(bool delegate(char[] uri,char[] type,char[] imageData) dg) |
|---|
| 378 |
{ |
|---|
| 379 |
synchronized |
|---|
| 380 |
{ |
|---|
| 381 |
mEnumCallback=dg; |
|---|
| 382 |
return HTMLayoutEnumResources(mHandle,&mEnumResoureCallback); |
|---|
| 383 |
} |
|---|
| 384 |
} |
|---|
| 385 |
|
|---|
| 386 |
bool css(char[] data,char[] baseurl,char[] mediatype){return cast(bool)HTMLayoutSetCSS(mHandle,cast(LPCBYTE)data.ptr,data.length,toString16z(toString16(baseurl)), toString16z(toString16(mediatype)));} |
|---|
| 387 |
bool headers(char[] headers){return cast(bool)HTMLayoutSetHttpHeaders(mHandle,headers.ptr,headers.length);} |
|---|
| 388 |
bool setOption(UINT option,UINT value){return cast(bool)HTMLayoutSetOption(mHandle,option,value );} |
|---|
| 389 |
|
|---|
| 390 |
int dialog(POINT position, INT alignment, UINT style, UINT styleEx, LPHTMLAYOUT_NOTIFY notificationCallback, LPELEMENT_EVENT_PROC eventsCallback, LPVOID callbackParam, char[] html){INT_PTR ret=HTMLayoutDialog (mHandle, position, alignment, style, styleEx, notificationCallback, eventsCallback, callbackParam, cast(LPCBYTE) html.ptr, html.length); if(ret) return ret; else return -1;} |
|---|
| 391 |
|
|---|
| 392 |
bool _handleEvent(UINT subscription){return (lastResult=HTMLayoutWindowAttachEventHandler(mHandle,callback,htag,subscription))==HLDOM_OK;} |
|---|
| 393 |
bool _unhandleEvents(){return (lastResult=HTMLayoutWindowDetachEventHandler(mHandle,callback,htag))==HLDOM_OK;} |
|---|
| 394 |
|
|---|
| 395 |
HLDOM_RESULT lastResult; |
|---|
| 396 |
char[] lastResultMsg() |
|---|
| 397 |
{ |
|---|
| 398 |
if(lastResult==HLDOM_OK) return "HLDOM_OK - function completed successfully"; |
|---|
| 399 |
else if(lastResult==HLDOM_INVALID_HWND) return "HLDOM_INVALID_HWND - invalid HWND"; |
|---|
| 400 |
else if(lastResult==HLDOM_INVALID_HANDLE) return "HLDOM_INVALID_HANDLE - invalid HELEMENT"; |
|---|
| 401 |
else if(lastResult==HLDOM_PASSIVE_HANDLE) return "HLDOM_PASSIVE_HANDLE - attempt to use HELEMENT which is not marked by HTMLayout_UseElement()"; |
|---|
| 402 |
else if(lastResult==HLDOM_INVALID_PARAMETER) return "HLDOM_INVALID_PARAMETER - parameter is invalid, e.g. pointer is null"; |
|---|
| 403 |
else if(lastResult==HLDOM_OPERATION_FAILED) return "HLDOM_OPERATION_FAILED"; |
|---|
| 404 |
else return null; |
|---|
| 405 |
} |
|---|
| 406 |
|
|---|
| 407 |
mixin(EVENT_HANDLER_STRING0!("bool","DialogCreated","HDialogCreated","HLN_DIALOG_CREATED")); |
|---|
| 408 |
mixin(EVENT_HANDLER_STRING0!("bool","DialogCloseRQ","HDialogCloseRQ","HLN_DIALOG_CLOSE_RQ")); |
|---|
| 409 |
|
|---|
| 410 |
protected: |
|---|
| 411 |
|
|---|
| 412 |
static bool delegate(char[] uri,char[] type,char[] imageData) mEnumCallback; |
|---|
| 413 |
extern(Windows) static BOOL mEnumResoureCallback(LPCWSTR resourceUri, LPCSTR resourceType, LPCBYTE imageData, DWORD imageDataSize){return mEnumCallback(.toString(fromString16z(resourceUri)),fromStringz(resourceType),(cast(char*)imageData)[0..imageDataSize]);} |
|---|
| 414 |
|
|---|
| 415 |
extern(Windows) static LRESULT mCallback(UINT uMsg, WPARAM wParam, LPARAM lParam, LPVOID vParam) |
|---|
| 416 |
{ |
|---|
| 417 |
LPNMHDR hdr = cast(LPNMHDR)lParam; |
|---|
| 418 |
auto lay=cast(HWND)vParam in mHandles; |
|---|
| 419 |
if(lay is null) throw new Exception("Error handling event"); |
|---|
| 420 |
|
|---|
| 421 |
if(hdr.code==HLN_DIALOG_CREATED) return lay.onDialogCreated(HDialogCreated(hdr)); |
|---|
| 422 |
else if(hdr.code==HLN_DIALOG_CLOSE_RQ) return lay.onDialogCloseRQ(HDialogCloseRQ(cast(LPNMHL_DIALOG_CLOSE_RQ)hdr)); |
|---|
| 423 |
else return lay.mBaseCallback(hdr); |
|---|
| 424 |
} |
|---|
| 425 |
|
|---|
| 426 |
static HLayout[HWND] mHandles; |
|---|
| 427 |
HWND mHandle; |
|---|
| 428 |
} |
|---|