1 /** \file
2  * \brief Name space for C++ high level API
3  *
4  * See Copyright Notice in iup.h
5  */
6 module iup.iup_plusD;
7 
8 //#define __IUP_PLUS_H
9 
10 import std.string : toStringz, fromStringz, empty;
11 
12 public import iup.iup;
13 public import iup.iupcontrols;
14 public import iup.iup_config;
15 
16 //public import iup.iupkey;
17 public import iup.iupdraw;
18 
19 /+
20 
21 TODO check what's required for myproject:
22 
23 Timer (Handle) /* OK */
24 Config (Handle) /* OK, no CN */
25 
26 Fill (Control) /* OK, no CN */
27 Label (Control) /* OK */
28 List (Control)  /* OK */
29 Calendar (Control) /* OK */
30 Text (Control)  /* OK */
31 Button (Control)  /* OK */
32 Toggle (Control)  /* OK */
33 Matrix (Control)  /* OK */
34 MatrixList (Control)  /* OK */
35 
36 Vbox (Container)
37 Hbox (Container)
38 Expander (Container)
39 Tabs (Container)
40 Dialog (Container)
41 
42 +/
43 
44 
45 Handle[string] AA;
46 
47 
48 /+
49 #if 0 //TODO
50 
51 #ifdef _STRING_
52 std::string
53 #endif
54 void cdCanvasSetfAttribute(cdCanvas* canvas, const(char)* name, const(char)* format, ...);
55 void IupSetStrf(Ihandle* ih, const(char)* name, const(char)* format, ...);
56 void IupSetStrfId(Ihandle *ih, const(char)* name, int id, const(char)* format, ...);
57 void IupSetStrfId2(Ihandle* ih, const(char)* name, int lin, int col, const(char)* format, ...);
58 void IupMessagef(const(char)* title, const(char)* format, ...);
59 
60 int IupScanf(const(char)* format, ...);
61 int IupGetParam(const(char)* title, Iparamcb action, void* user_data, const(char)* format, ...);
62 int IupGetParamv(const(char)* title, Iparamcb action, void* user_data, const(char)* format, int param_count, int param_extra, void** param_data);
63 
64 Icallback IupGetCallback(Ihandle* ih, const(char)* name);
65 Icallback IupSetCallback(Ihandle* ih, const(char)* name, Icallback func);
66 
67 void IupTreeSetAttributeHandle(Ihandle* ih, const(char)* name, int id, Ihandle* ih_named);
68 
69 #endif
70 +/
71 
72 /** \brief Name space for C++ high level API
73  *
74  * \par
75  * Defines wrapper classes for all C structures.
76  *
77  * See \ref iup_plus.h
78  */
79 //namespace iup {
80 ////  char* Version() { return IupVersion(); }
81 ////  char* VersionDate() { return IupVersionDate(); }
82 ////  int VersionNumber() { return IupVersionNumber(); }
83 
84 ////  int Open(ref int argc, ref char** argv) { return IupOpen(&argc, &argv); }
85 int IupOpenD()
86 {
87     import core.runtime : Runtime;
88     return  IupOpen(&Runtime.cArgs.argc, &Runtime.cArgs.argv);
89 }
90 deprecated int IupOpenD(in string[] args) // ... main(string[] args) // C: int main(int argc, char **argv)
91 {
92 //  TODO check if there is a smarter (library supported?) solution to get from string[] to char*[]
93 //  passing local adresses/pointers seemed to work as well, but better not to; inform the GC not to collect
94 	import core.memory : GC;
95 	int*    argc_ptr = new int;
96 	char*** argv_ptr = new char**;
97 	GC.addRoot(/*cast(void*)*/argc_ptr);
98 	GC.setAttr(/*cast(void*)*/argc_ptr, GC.BlkAttr.NO_MOVE);
99 	GC.addRoot(/*cast(void*)*/argv_ptr);
100 	GC.setAttr(/*cast(void*)*/argv_ptr, GC.BlkAttr.NO_MOVE);
101 
102 	*argc_ptr = cast(int) args.length;
103 	char*[] args_carray;
104 	foreach (s; args)
105 		args_carray ~= cast(char*) s.toStringz;
106 	*argv_ptr = args_carray.ptr;
107 
108 	return IupOpen(argc_ptr, argv_ptr);
109 }
110 
111 // Avoid functions, that do nothing else than simply introducing new names/aliasing
112 ////  void Close() { IupClose(); }  or  alias Close = IupClose;
113 ////  void ImageLibOpen() { IupImageLibOpen(); }
114 
115 ////  int MainLoop() { return IupMainLoop(); }
116 ////  int LoopStep() { return IupLoopStep(); }
117 ////  int LoopStepWait() { return IupLoopStepWait(); }
118 ////  int MainLoopLevel() { return IupMainLoopLevel(); }
119 ////  void Flush() { IupFlush(); }
120 ////  void ExitLoop() { IupExitLoop(); }
121 
122 ////  int RecordInput(const(char)* filename, int mode) { return IupRecordInput(filename, mode); }
123 ////  int  PlayInput(const(char)* filename) { return IupPlayInput(filename); }
124 
125 ////  int Help(const(char)* url) { return IupHelp(url); }
126 ////  void Log(const(char)* type, const(char)* str) { IupLog(type, "%s", str); }
127 ////  const(char)* Load(const(char)* filename) { return IupLoad(filename); }
128 ////  const(char)* LoadBuffer(const(char)* buffer) { return IupLoadBuffer(buffer); }
129 
130 ////  void SetLanguage(const(char)* lng) { IupSetLanguage(lng); }
131 ////  const(char)* GetLanguage() { return IupGetLanguage(); }
132 ////  void SetLanguageString(const(char)* name, const(char)* str) { IupSetLanguageString(name, str); }
133 ////  void StoreLanguageString(const(char)* name, const(char)* str) { IupStoreLanguageString(name, str); }
134 ////  const(char)* GetLanguageString(const(char)* name) { return IupGetLanguageString(name); }
135 
136 ////  int GetAllClasses(char** names, int n) { return IupGetAllClasses(names, n); }
137 ////  int GetClassAttributes(const(char)* classname, char** names, int n) { return IupGetClassAttributes(classname, names, n); }
138 ////  int GetClassCallbacks(const(char)* classname, char** names, int n) { return IupGetClassCallbacks(classname, names, n); }
139 ////  void SetClassDefaultAttribute(const(char)* classname, const(char)* name, const(char)* value) { IupSetClassDefaultAttribute(classname, name, value); }
140 
141 ////  void SetGlobal(const(char)* name, const(char)* value) { IupSetGlobal(name, value); }
142 ////  void SetStringGlobal(const(char)* name, const(char)* value) { IupSetStrGlobal(name, value); }
143 ////  char* GetGlobal(const(char)* name) { return IupGetGlobal(name); }
144 
145 ////  int GetFile(char *arq) { return IupGetFile(arq); }
146 ////  void Message(const(char)* title, const(char)* msg) { IupMessage(title, msg); }
147 ////  int Alarm(const(char)* title, const(char)* msg, const(char)* b1, const(char)* b2, const(char)* b3) { return IupAlarm(title, msg, b1, b2, b3); }
148 ////  int ListDialog(int type, const(char)* title, int size, const(char)** list, int op, int max_col, int max_lin, int* marks) { return IupListDialog(type, title, size, list, op, max_col, max_lin, marks); }
149 ////  int GetText(const(char)* title, char* text, int maxsize = 10240) { return IupGetText(title, text, maxsize); }
150 ////  int GetColor(int x, int y, ubyte &r, ubyte &g, ubyte &b) { return IupGetColor(x, y, &r, &g, &b); }
151 
152 ////  int GetAllNames(char** names, int n) { return IupGetAllNames(names, n); }
153 ////  int GetAllDialogs(char** names, int n) { return IupGetAllDialogs(names, n); }
154 
155 enum FILL_TYPE {
156 	FILL_NONE,
157 	FILL_FRONT,
158 	FILL_BACK,
159 	FILL_BETWEEN,
160 	FILL_FRONT_AND_BACK,
161 	FILL_FRONT_AND_BETWEEN,
162 	FILL_BACK_AND_BETWEEN,
163 	FILL_FRONT_AND_BACK_AND_BETWEEN
164 }
165 
166 class /*Element*/ Handle // used as base class
167 {
168   private Ihandle* _ih;
169 
170   nothrow:
171 
172   /* forbidden */
173   private this() { this(cast(Ihandle*)null); }
174   /*private*/ this(Ihandle* ref_ih)  { _ih = ref_ih; }
175   this(/*Element*/Handle elem) { this(elem._ih); }
176 //  alias _ih this; // will only be usable within the class hierarchy, not from "outside"
177   // There is no destructor because all iup::Handle are just a reference to the Ihandle*,
178   // since several IUP elements are automatically destroyed when the dialog is destroyed
179   // So, to force an element to be destructed call the Destroy method
180 //  invariant() { assert(_ih != null); }
181 
182   @property Ihandle* GetHandle() @nogc { return _ih; }
183 
184   @property bool Failed() {
185     return _ih == null;
186   }
187 //alias  _     = GetHandle;
188 /*
189 Naming:
190 When (after Set/Get) Attribute/User comes first, parameter types are the same as Iup...-function, thus SetAttribute and IupSetAttribute have the same signature (except Ihandle* _ih)
191 When (after Set/Get) String/Integer/Double/RGB  signature has D types only
192 "mixed" SetStrAttr
193 */
194 //final void   SetUserData (const(char)* name,         void* data) @nogc  { IupSetAttribute(       _ih, name, cast(char*)data); } // hides the cast; explicitely cast and use SetAttribute instead
195   final void   SetAttribute(const(char)* name, const(char)* value) @nogc  { IupSetAttribute(       _ih, name,    value); }
196   final void   SetAttributeVALUE(              const(char)* value) @nogc  { IupSetAttribute(       _ih, "VALUE", value); }
197 //final void*  GetUserData (const(char)* name)                     @nogc  { return cast(void*)IupGetAttribute(_ih, name); }
198   final char*  GetAttribute(const(char)* name)                     @nogc  { return IupGetAttribute(_ih, name); }
199   final char*  GetAttributeVALUE()                                 @nogc  { return IupGetAttribute(_ih, "VALUE"); }
200 
201 // mixed C/D types to help with defining user attributes:
202   final void   SetAttributeStr(   string name, const(char)* value)        { IupSetAttribute(       _ih, name.toStringz, value); }
203   final char*  GetAttributeStr(   string name)                            { return IupGetAttribute(_ih, name.toStringz); }
204 //
205   final void   SetString(         string name,       string value)        { IupSetStrAttribute(    _ih, name.toStringz, value.toStringz); }
206   final void   SetStringVALUE(                       string value)        { IupSetStrAttribute(    _ih, "VALUE",        value.toStringz); }
207   final string GetString(         string name)                            { return IupGetAttribute(_ih, name.toStringz).fromStringz.idup; } // decoupled from C's string
208   final string GetStringVALUE()                                           { return IupGetAttribute(_ih, "VALUE"       ).fromStringz.idup; } // decoupled from C's string
209 
210   final void   SetInteger(        string name,          int value)        { IupSetInt(_ih, name.toStringz, value); }
211   final void   SetIntegerVALUE(                         int value)        { IupSetInt(_ih, "VALUE",        value); }
212   final int    GetInteger(        string name)                            { return IupGetInt(_ih, name.toStringz); }
213   final int    GetIntegerVALUE()                                          { return IupGetInt(_ih, "VALUE"); }
214 
215   final void   GetIntegerInteger( string name, out int i1, out int i2)    { IupGetIntInt(_ih, name.toStringz, &i1, &i2); }
216 
217   final void   SetDouble(         string name,       double value)        { IupSetDouble(_ih, name.toStringz, value); }
218   final void   SetDoubleVALUE(                       double value)        { IupSetDouble(_ih, "VALUE",        value); }
219   final double GetDouble(         string name)                            { return IupGetDouble(_ih, name.toStringz); }
220   final double GetDoubleVALUE()                                           { return IupGetDouble(_ih, "VALUE"); }
221   final void   SetRGB(            string name, ubyte r, ubyte g, ubyte b) { IupSetRGB(_ih, name.toStringz, r, g, b); }
222   final void   GetRGB(            string name, out ubyte r, out ubyte g, out ubyte b)  { IupGetRGB(_ih, name.toStringz, &r, &g, &b); }
223 ////
224 //final void   SetUserDataId (const(char)* name, int id, void* data) @nogc         {         IupSetAttributeId(_ih, name, id, cast(char*)data); }
225   final void   SetAttributeId(const(char)* name, int id, const(char)* value) @nogc {         IupSetAttributeId(_ih, name, id, value); }
226 //final void*  GetUserDataId (const(char)* name, int id) @nogc            { return cast(void*)IupGetAttributeId(_ih, name, id); }
227   final char*  GetAttributeId(const(char)* name, int id)            @nogc { return  IupGetAttributeId(_ih, name, id); }
228 
229   final void   SetStringId (    string name, int id, string value)        { IupSetStrAttributeId(_ih, name.toStringz, id, value.toStringz); }
230   final string GetStringId (    string name, int id)                      { return IupGetAttributeId(_ih, name.toStringz, id).fromStringz.idup; } // decoupled from C's string
231   final void   SetIntegerId(    string name, int id,    int value)        { IupSetIntId(_ih, name.toStringz, id, value); }
232   final int    GetIntegerId(    string name, int id)                      { return IupGetIntId(_ih, name.toStringz, id); }
233   final void   SetDoubleId (    string name, int id, double value)        { IupSetDoubleId(_ih, name.toStringz, id, value); }
234   final double GetDoubleId (    string name, int id)                      { return IupGetDoubleId(_ih, name.toStringz, id); }
235   final void   SetRGBId(        string name, int id, ubyte r, ubyte g, ubyte b)             { IupSetRGBId(_ih, name.toStringz, id, r, g, b); }
236   final void   GetRGBId(        string name, int id, out ubyte r, out ubyte g, out ubyte b) { IupGetRGBId(_ih, name.toStringz, id, &r, &g, &b); }
237 ////
238   final void   SetAttributeId2(const(char)* name, int lin, int col, const(char)* value) @nogc {        IupSetAttributeId2(_ih, name, lin, col, value); }
239   final char*  GetAttributeId2(const(char)* name, int lin, int col)                     @nogc { return IupGetAttributeId2(_ih, name, lin, col); }
240 //final void   SetUserDataId2 (const(char)* name, int lin, int col, void* data) @nogc { IupSetAttributeId2(_ih, name, lin, col, cast(char*)data); }
241 //final void*  GetUserDataId2 (const(char)* name, int lin, int col) @nogc             { return cast(void*)IupGetAttributeId2(_ih, name, lin, col); }
242 
243   final void   SetStringId2 (     string name, int lin, int col, string value) { IupSetStrAttributeId2(_ih, name.toStringz, lin, col, value.toStringz); }
244   final string GetStringId2 (     string name, int lin, int col)               { return IupGetAttributeId2(_ih, name.toStringz, lin, col).fromStringz.idup; } // decoupled from C's string
245   final void   SetIntegerId2(     string name, int lin, int col, int value)    { IupSetIntId2(_ih, name.toStringz, lin, col, value); }
246   final int    GetIntegerId2(     string name, int lin, int col)               { return IupGetIntId2(_ih, name.toStringz, lin, col); }
247   final void   SetDoubleId2 (     string name, int lin, int col, double value) { IupSetDoubleId2(_ih, name.toStringz, lin, col, value); }
248   final double GetDoubleId2 (     string name, int lin, int col)               { return IupGetDoubleId2(_ih, name.toStringz, lin, col); }
249   final void   SetRGBId2    (     string name, int lin, int col, ubyte r, ubyte g, ubyte b) { IupSetRGBId2(_ih, name.toStringz, lin, col, r, g, b); }
250   final void   GetRGBId2    (     string name, int lin, int col, out ubyte r, out ubyte g, out ubyte b) { IupGetRGBId2(_ih, name.toStringz, lin, col, &r, &g, &b); }
251 
252   /*Element*/Handle SetAttributes(const(char)* str) { return new /*Element*/Handle(IupSetAttributes(_ih, str)); }
253   final void   ResetAttribute(    string name)                                 { IupResetAttribute(_ih, name.toStringz); }
254   final int GetAllAttributes(ref string[] names/*, int n*/) {
255   	int n_max = IupGetAllAttributes(_ih, null, 0);
256     if (names is null /* || n==0*/)
257       return n_max;
258     else {
259       names.length = n_max;
260       char*[] arr = new char*[](n_max);
261       int res = IupGetAllAttributes(_ih, arr.ptr, n_max);
262       foreach(i, c; arr)
263         names[i] = c.fromStringz.idup;
264       return res;
265     }
266   }
267   final void SetAttributeHandle(string name, /*Element*/Handle elem) { IupSetAttributeHandle(_ih, name.toStringz, elem.GetHandle); }
268 //final /*Element*/Handle GetAttributeHandle(string name) { return new /*Element*/Handle(IupGetAttributeHandle(_ih, name.toStringz)); }
269   /*Element*/Handle GetAttributeHandle(const(char)* name) { return new /*Element*/Handle(IupGetAttributeHandle(_ih, name)); }
270   void SetAttributeHandleId(const(char)* name, int id, /*Element*/Handle elem) { IupSetAttributeHandleId(_ih, name, id, elem.GetHandle); }
271   /*Element*/Handle GetAttributeHandleId(const(char)* name, int id) { return new /*Element*/Handle(IupGetAttributeHandleId(_ih, name, id)); }
272   void SetAttributeHandleId2(const(char)* name, int lin, int col, /*Element*/Handle elem) { IupSetAttributeHandleId2(_ih, name, lin, col, elem.GetHandle); }
273   /*Element*/Handle GetAttributeHandleId2(const(char)* name, int lin, int col) { return new /*Element*/Handle(IupGetAttributeHandleId2(_ih, name, lin, col)); }
274 
275   Icallback GetCallback(const(char)* name) { return IupGetCallback(_ih, name); }
276 //  Icallback SetCallback(const(char)* name, Icallback func) { return IupSetCallback(_ih, name, func); }
277 
278   final void Destroy() @nogc { IupDestroy(_ih); }
279 
280   final int Map() @nogc { return IupMap(_ih); }
281   final void Unmap() @nogc { IupUnmap(_ih); }
282 
283   final string GetName() { return IupGetName(_ih).fromStringz.idup; } // decoupled from C's string
284 
285   final string GetClassName() { return IupGetClassName(_ih).fromStringz.idup; } // decoupled from C's string
286   final string GetClassType() { return IupGetClassType(_ih).fromStringz.idup; } // decoupled from C's string
287   final void SaveClassAttributes() @nogc { IupSaveClassAttributes(_ih); }
288   final void CopyClassAttributesTo(Handle dst) @nogc { IupCopyClassAttributes(_ih, dst._ih); }
289   final int ClassMatch(const(char)* classname) @nogc { return IupClassMatch(_ih, classname); }
290 
291   final Icallback SetCallback (const(char)* name, Icallback func) @nogc { return IupSetCallback(_ih, name, func); }
292 
293   final Handle SetHandle(const(char)* name) { return new Handle(IupSetHandle(name, _ih)); } // returned Handle's member _ih may be null
294   final Handle SetHandle(string       name) { return new Handle(IupSetHandle(name.toStringz, _ih)); } // returned Handle's member _ih may be null
295 
296   // Timer
297   void start() @nogc {}
298   void stop()  @nogc {}
299 // Dialog/Menu
300   int Popup(int x, int y) { return 0; }
301 // Dialog/Control
302   int Show() { return 0; }
303   int Hide() { return 0; }
304 
305 // Control
306   void Update() {}
307   void Redraw() {}
308   void Refresh() {}
309 // Container
310   void UpdateChildren() {}
311   void RedrawChildren() {}
312   void RefreshChildren() {}
313 
314 
315 } // class Handle
316 
317 Handle createHandle(Ihandle* ih)       nothrow { return new Handle(ih); } // createHandle was named GetHandle before
318 Handle createHandle(const(char)* name) nothrow { return new Handle(IupGetHandle(name)); }
319 Handle createHandle(string       name) nothrow { return new Handle(IupGetHandle(name.toStringz)); }
320 
321 //Handle SetHandle(const(char)* name, Handle handle) nothrow { return new Handle(IupSetHandle(name, handle.GetHandle())); } // returned Handle's member _ih may be null
322 //Handle SetHandle(string       name, Handle handle) nothrow { return new Handle(IupSetHandle(name.toStringz, handle.GetHandle())); } // returned Handle's member _ih may be null
323 void SetLanguagePack(Handle handle) @nogc nothrow { IupSetLanguagePack(handle.GetHandle()); }
324 
325 
326 class Control : Handle
327 {
328   nothrow:
329   private this(Ihandle* ih) { super(ih); }
330 //  alias _ih this;
331 
332   override void Update() { IupUpdate(_ih); }
333   override void Redraw() { IupRedraw(_ih, 1); }
334   override void Refresh() { IupRefresh(_ih); }
335 
336   final void Detach(Control child) { IupDetach(child._ih); }
337 
338   final Control GetBrother() {
339     return new Control(IupGetBrother(_ih));
340   }
341   final Container GetParent() {
342     if (_ih==null)
343       return new Container(null);
344     else {
345       Ihandle* ih_parent = IupGetParent(_ih);
346       try {
347         foreach (k, ref v; AA) {
348           Ihandle* ih_v = v.GetHandle;
349           if (ih_v!=null && ih_v==ih_parent)
350             return cast(Container)v;
351         }
352       }
353       catch (Exception e) { /* todo: handle exception */ }
354     }
355     return new Container(null);
356   }
357 
358   final Dialog  GetDialog() { return new Dialog(IupGetDialog(_ih)); }
359   final Control GetDialogChild(const(char)* name) { return new Control(IupGetDialogChild(_ih, name)); }
360   final int Reparent(Container new_parent, Control ref_child) { return IupReparent(_ih, new_parent.GetHandle(), ref_child.GetHandle()); }
361 
362 
363   final Control SetFocus() { return new Control(IupSetFocus(_ih)); }
364   final Control PreviousField() { return new Control(IupPreviousField(_ih)); }
365   final Control NextField() { return new Control(IupNextField(_ih)); }
366 
367 /* IupText and IupScintilla utilities */
368   final void ConvertLinColToPos(int lin, int col, out int pos) { IupTextConvertLinColToPos(_ih, lin, col, &pos); }
369   final void ConvertPosToLinCol(int pos, out int lin, out int col) { IupTextConvertPosToLinCol(_ih, pos, &lin, &col); }
370 
371 /* IupText, IupList, IupTree, IupMatrix and IupScintilla utility */
372   final int ConvertXYToPos(int x, int y) { return IupConvertXYToPos(_ih, x, y); }
373 
374   override int Show() { return IupShow(_ih); }
375   override int Hide() { return IupHide(_ih); }
376 }
377 
378 ptrdiff_t index_first_null(ref Control[] child_array) nothrow {
379     import std.algorithm.searching : countUntil;
380     ptrdiff_t  result;
381     result = child_array.countUntil!"a is null";
382     if (result == -1) {
383         result = child_array.length;
384         child_array ~= new Control(null); // used as Terminator
385     }
386     return result;
387 }
388 
389 Control GetFocus() nothrow {
390   Ihandle* ih_focus = IupGetFocus();
391   if (ih_focus==null)
392     return new Control(null);
393   else {
394     try {
395       foreach (k, ref v; AA) {
396       	Ihandle* ih_v = v.GetHandle;
397         if (ih_v!=null && ih_v==ih_focus)
398           return cast(Control)v;
399       }
400     }
401     catch (Exception e) { /* todo: handle exception */ }
402     return new Control(null);
403   }
404 }
405 
406 class Container : Control
407 {
408   nothrow:
409 //  @disable this();
410   this(Ihandle* ih) { super(ih); }
411   this(Ihandle* ih, Control[] child_array, FILL_TYPE fill=FILL_TYPE.FILL_NONE) {
412     super(ih);
413 //    child_array ~= new Control(null);
414     int cnt = 0;
415 	with (FILL_TYPE) {
416       if (fill==FILL_FRONT || fill==FILL_FRONT_AND_BACK)
417         IupAppend(_ih, IupFill());
418       foreach (c; child_array) {
419         if ((fill==FILL_BETWEEN && cnt)|| fill==FILL_FRONT_AND_BETWEEN || (fill==FILL_BACK_AND_BETWEEN && cnt) || fill==FILL_FRONT_AND_BACK_AND_BETWEEN)
420           IupAppend(_ih, IupFill());
421         IupAppend(_ih, c.GetHandle());
422         ++cnt;
423       }
424       if (fill==FILL_BACK || fill==FILL_FRONT_AND_BACK || fill==FILL_BACK_AND_BETWEEN || fill==FILL_FRONT_AND_BACK_AND_BETWEEN)
425         IupAppend(_ih, IupFill());
426 	}
427   }
428 
429   this(Ihandle* ih, Control child0, Control child1 = null, Control child2 = null, Control child3 = null, Control child4 = null,
430   	Control child5 = null, Control child6 = null, Control child7 = null, Control child8 = null, Control child9 = null)
431   {
432     super(ih);
433     if (child0 !is null) IupAppend(_ih, child0.GetHandle());
434     if (child1 !is null) IupAppend(_ih, child1.GetHandle());
435     if (child2 !is null) IupAppend(_ih, child2.GetHandle());
436     if (child3 !is null) IupAppend(_ih, child3.GetHandle());
437     if (child4 !is null) IupAppend(_ih, child4.GetHandle());
438     if (child5 !is null) IupAppend(_ih, child5.GetHandle());
439     if (child6 !is null) IupAppend(_ih, child6.GetHandle());
440     if (child7 !is null) IupAppend(_ih, child7.GetHandle());
441     if (child8 !is null) IupAppend(_ih, child8.GetHandle());
442     if (child9 !is null) IupAppend(_ih, child9.GetHandle());
443   }
444 //  alias _ih this;
445 
446   Control Append(Control child) {
447     Ihandle* ih_child = child.GetHandle();
448     if (_ih==null || ih_child==null) // this has a null Ihandle*, etc.
449       return new Control(null);
450     Ihandle* ih_parent = IupAppend(_ih, ih_child);
451     if (ih_parent==null || _ih != ih_parent)
452       return new Control(null);
453     else {
454       try {
455         foreach (k, ref v; AA) {
456           if (v.GetHandle!=null && v.GetHandle==ih_parent)
457             return cast(Control)v;
458         }
459       }
460       catch (Exception e) { /* todo: handle exception */ }
461       return new Control(null);
462     }
463   }
464 
465   Control Insert(Control ref_child, Control child) {
466     if (_ih==null || ref_child.GetHandle()==null || child.GetHandle()==null) // this has a null Ihandle*, etc.
467       return new Control(null);
468     Ihandle* ih_parent = IupInsert(_ih, ref_child.GetHandle(), child.GetHandle());
469     if (ih_parent==null || _ih != ih_parent)
470       return new Control(null);
471     else { //lookup in AA
472       try {
473         foreach (k, ref v; AA) {
474           if (v.GetHandle!=null && v.GetHandle==ih_parent)
475             return cast(Control)v;
476         }
477       }
478       catch (Exception e) { /* todo: handle exception */ }
479       return new Control(null);
480     }
481   }
482   Control GetChild(int pos) { return new Control(IupGetChild(_ih, pos)); }
483   int GetChildPos(Control child) { return IupGetChildPos(_ih, child.GetHandle()); }
484   int GetChildCount() { return IupGetChildCount(_ih); }
485 
486   Control GetFirstChild() { return new Control(IupGetNextChild(_ih, null)); }
487   Control GetNextChild(Control ref_child) { return new Control(IupGetNextChild(_ih, ref_child.GetHandle())); }
488 
489   override void UpdateChildren() { IupUpdateChildren(_ih); }
490   override void RedrawChildren() { IupRedraw(_ih, 1); }
491   override void RefreshChildren() { IupRefreshChildren(_ih); }
492 }
493 
494 class Dialog : Container
495 {
496   private bool _autoDestroy;
497   nothrow:
498 //    Dialog(const Control& child) : Container(IupDialog(child.GetHandle())) { }
499 //  @disable this();
500   this(                             Ihandle* ih)   { this(false, ih); }
501   this(           bool autoDestroy, Ihandle* ih)   { super(ih); _autoDestroy = autoDestroy; }
502   this(           bool autoDestroy, Control child) { super(IupDialog(child.GetHandle())); _autoDestroy = autoDestroy; }
503   this(string CN, bool autoDestroy, Control child) { this(autoDestroy, child); if (!CN.empty) { AA[CN] = this; IupSetHandle(CN.toStringz, _ih); } }
504   ~this() { if (_autoDestroy) { Destroy(); /* TODO manage deleting from AA */ } }
505 //  alias _ih this;
506 
507   override int Popup(int x, int y) { return IupPopup(_ih, x, y); }
508   override int Show() { return IupShow(_ih); }
509   int ShowXY(int x, int y) { return IupShowXY(_ih, x, y); }
510 }
511 
512 Dialog LayoutDialog(Dialog dialog) nothrow { return new Dialog(IupLayoutDialog(dialog.GetHandle())); }
513 Dialog ElementPropertiesDialog(Control control) nothrow { return new Dialog(IupElementPropertiesDialog(control.GetHandle())); }
514 
515 void MessageError(Dialog parent, const(char)* message)
516     { IupMessageError(parent.GetHandle(), message); }
517 int MessageAlarm(Dialog parent, const(char)* title, const(char)* message, const(char)* buttons)
518     { return IupMessageAlarm(parent.GetHandle(), title, message, buttons); }
519 
520 
521 class Menu : Container
522 {
523   nothrow:
524   this() { super(IupMenu(null)); }
525   this(Control child) { super(IupMenu(child.GetHandle(), null)); }
526   this(Control child0, Control child1 = null, Control child2 = null, Control child3 = null, Control child4 = null,
527     Control child5 = null, Control child6 = null, Control child7 = null, Control child8 = null, Control child9 = null)
528       { super(IupMenu(null), child0, child1, child2, child3, child4, child5, child6, child7, child8, child9); }
529 ////  this(Control[] child_array) { super(IupMenu(null), child_array); }
530 
531   override int Popup(int x, int y) { return IupPopup(_ih, x, y); }
532 }
533 
534 version(IM) //#ifdef __IM_PLUS_H   // im.im_plusD is not ready to be published
535 {
536 public import iup.iupim : IupLoadImage, IupSaveImage, IupImageFromImImage, IupGetNativeHandleImage, IupGetImageNativeHandle;
537 public import im.im_plusD;
538 
539 class Image : Handle
540 {
541   nothrow:
542   this(const(char)* filename) { super(IupLoadImage(filename)); }
543   this(ref im.im_plusD.Image image) { super(IupImageFromImImage(image.GetHandle())); }
544 
545   int Save(const(char)* filename, const(char)* im_format) { return IupSaveImage(_ih, filename, im_format); }
546   int SaveAsText(const(char)* filename, const(char)* iup_format, const(char)* name) { return IupSaveImageAsText(_ih, filename, iup_format, name); }
547 }
548 
549 class Clipboard : Handle
550 {
551   nothrow:
552   this() { super(IupClipboard()); }
553 
554   void SetImage(ref im.im_plusD.Image image) { SetAttribute("NATIVEIMAGE", cast(const(char)*)IupGetImageNativeHandle(image.GetHandle())); }// SetUserData("NATIVEIMAGE", cast(const(char)*)IupGetImageNativeHandle(image.GetHandle()));
555 
556   im.im_plusD.Image GetImage() { return new im.im_plusD.Image(IupGetNativeHandleImage(GetAttribute("NATIVEIMAGE"))); }
557 }
558 //TODO imImage* IupImageToImImage(Ihandle* iup_image)
559 } // version(IM)
560 
561 
562 class User : Handle
563 {
564   nothrow:
565   this() { super(IupUser); }
566 }
567 
568 class Param : Handle
569 {
570   nothrow:
571   this(const(char)* format) { super(IupParam(format)); }
572 }
573 
574 class Timer : Handle
575 {
576   nothrow:
577   this()          { super(IupTimer); }
578   this(string CN) { this(); if (!CN.empty) { AA[CN] = this; IupSetHandle(CN.toStringz, _ih); } }
579 
580   override void start() @nogc { SetAttribute(IUP_RUN, IUP_YES); }
581   override void stop()  @nogc { SetAttribute(IUP_RUN, IUP_NO);  }
582 }
583 
584 class MenuSeparator : Control
585 {
586   nothrow:
587   this() { super(IupSeparator()); }
588 }
589 
590 class MenuItem : Control
591 {
592   nothrow:
593   this(const(char)* title = null) { super(IupItem(title, null)); }
594 }
595 
596 class Canvas : Control
597 {
598   nothrow:
599   this() { super(IupCanvas(null)); }
600 
601   void DrawBegin() { IupDrawBegin(_ih); }
602   void DrawEnd() { IupDrawEnd(_ih); }
603   void DrawSetClipRect(int x1, int y1, int x2, int y2) { IupDrawSetClipRect(_ih, x1, y1, x2, y2); }
604   void DrawGetClipRect(ref int x1, ref int y1, ref int x2, ref int y2) { IupDrawGetClipRect(_ih, &x1, &y1, &x2, &y2); }
605   void DrawResetClip() { IupDrawResetClip(_ih); }
606   void DrawParentBackground() { IupDrawParentBackground(_ih); }
607   void DrawLine(int x1, int y1, int x2, int y2) { IupDrawLine(_ih, x1, y1, x2, y2); }
608   void DrawRectangle(int x1, int y1, int x2, int y2) { IupDrawRectangle(_ih, x1, y1, x2, y2); }
609   void DrawArc(int x1, int y1, int x2, int y2, double a1, double a2) { IupDrawArc(_ih, x1, y1, x2, y2, a1, a2); }
610   void DrawPolygon(ref int points, int count) { IupDrawPolygon(_ih, &points, count); }
611   void DrawText(const(char)* text, int len, int x, int y, int w, int h) { IupDrawText(_ih, text, len, x, y, w, h); } // signature changed from 3.24 to 3.25
612   void DrawImage(const(char)* name, int x, int y, int w, int h) { IupDrawImage(_ih, name, x, y, w, h); } // signature changed from 3.24 to 3.25
613   void DrawSelectRect(int x1, int y1, int x2, int y2) { IupDrawSelectRect(_ih, x1, y1, x2, y2); }
614   void DrawFocusRect(int x1, int y1, int x2, int y2) { IupDrawFocusRect(_ih, x1, y1, x2, y2); }
615   void DrawGetSize(ref int w, ref int h) { IupDrawGetSize(_ih, &w, &h); }
616   void DrawGetTextSize(const(char)* str, int len, ref int w, ref int h) { IupDrawGetTextSize(_ih, str, len, &w, &h); } // signature changed from 3.24 to 3.25
617   void DrawGetImageInfo(const(char)* name, ref int w, ref int h, ref int bpp) { IupDrawGetImageInfo(name, &w, &h, &bpp); }
618 }
619 
620 class Link : Control
621 {
622   nothrow:
623   this(const(char)* url = null, const(char)* title = null) { super(IupLink(url, title)); }
624 }
625 
626 class Label : Control
627 {
628   nothrow:
629   this(           const(char)* title = null) { super(IupLabel(title)); }
630   this(string CN, const(char)* title)        { this(title); if (!CN.empty) { AA[CN] = this; IupSetHandle(CN.toStringz, _ih); } }
631 }
632 
633 class Button : Control
634 {
635   nothrow:
636   this(           const(char)* title = null) { super(IupButton(title, null)); }
637   this(string CN, const(char)* title)        { this(title); if (!CN.empty) { AA[CN] = this; IupSetHandle(CN.toStringz, _ih); } }
638 }
639 
640 class FlatButton : Control
641 {
642   nothrow:
643   this(           const(char)* title = null) { super(IupFlatButton(title)); }
644   this(string CN, const(char)* title)        { this(title); if (!CN.empty) { AA[CN] = this; IupSetHandle(CN.toStringz, _ih); } }
645 }
646 
647 class FlatToggle : Control
648 {
649     nothrow:
650     this(const(char)* title = null) { super(IupFlatToggle(title)); }
651     this(Ihandle* ih) { super(ih); }
652     this(/*Element*/Handle elem) { this(elem._ih); }
653 }
654 
655 class FlatSeparator : Control
656 {
657     nothrow:
658     this() { super(IupFlatSeparator()); }
659     this(Ihandle* ih) { super(ih); }
660     this(/*Element*/Handle elem) { this(elem._ih); }
661 }
662 
663 class Space : Control
664 {
665     nothrow:
666     this() { super(IupSpace()); }
667     this(Ihandle* ih) { super(ih); }
668     this(/*Element*/Handle elem) { this(elem._ih); }
669 }
670 
671 class DropButton : Control
672 {
673     nothrow:
674     this() { super(IupDropButton(null)); }
675     this(Control child) { super(IupDropButton(child.GetHandle())); }
676     this(Ihandle* ih) { super(ih); }
677     this(/*Element*/Handle elem) { this(elem._ih); }
678 }
679 
680 class FlatLabel : Control
681 {
682     nothrow:
683     this(const(char)* title = null) { super(IupFlatLabel(title)); }
684     this(Ihandle* ih) { super(ih); }
685     this(/*Element*/Handle elem) { this(elem._ih); }
686 }
687 
688 class AnimatedLabel : Control
689 {
690   nothrow:
691   this(           Ihandle* animation = null) { super(IupAnimatedLabel(animation)); }
692   this(string CN, Ihandle* animation)        { this(animation); if (!CN.empty) { AA[CN] = this; IupSetHandle(CN.toStringz, _ih); } }
693 }
694 
695 class Toggle : Control
696 {
697   nothrow:
698   this(           const(char)* title = null) { super(IupToggle(title, null /*no action set by constructor */)); }
699   this(string CN, const(char)* title)        { this(title); if (!CN.empty) { AA[CN] = this; IupSetHandle(CN.toStringz, _ih); } }
700 }
701 
702 class Fill : Control
703 {
704   nothrow:
705   this() { super(IupFill); }
706 }
707 
708 deprecated class Spin : Control
709 {
710   nothrow:
711   this() { super(IupSpin); }
712 }
713 
714 class Calendar : Control
715 {
716   nothrow:
717   this()          { super(IupCalendar); }
718   this(string CN) { this(); if (!CN.empty) { AA[CN] = this; IupSetHandle(CN.toStringz, _ih); } }
719 }
720 
721 class Tree : Control
722 {
723   nothrow:
724   this() { super(IupTree); }
725   this(string CN) { this(); if (!CN.empty) { AA[CN] = this; IupSetHandle(CN.toStringz, _ih); } }
726 
727   int SetUserId(int id, void* userid) { return IupTreeSetUserId(_ih, id, userid); }
728   void* GetUserId(int id) { return IupTreeGetUserId(_ih, id); }
729   int GetId(void* userid) { return IupTreeGetId(_ih, userid); }
730   void  SetAttributeHandle(const(char)* name, int id, Ihandle* ih_named) { IupSetAttributeHandleId(_ih, name, id, ih_named); }
731 }
732 
733 class Val : Control
734 {
735   nothrow:
736   this(const(char)* orientation = null) { super(IupVal(orientation)); }
737 }
738 
739 class ProgressBar : Control
740 {
741   nothrow:
742   this() { super(IupProgressBar); }
743 }
744 
745 class List : Control
746 {
747   nothrow:
748   this()          { super(IupList(null)); }
749   this(string CN) { this(); if (!CN.empty) { AA[CN] = this; IupSetHandle(CN.toStringz, _ih); } }
750 }
751 
752 class Text : Control
753 {
754   nothrow:
755   this()          { super(IupText(null)); }
756   this(string CN) { this(); if (!CN.empty) { AA[CN] = this; IupSetHandle(CN.toStringz, _ih); } }
757 }
758 
759 
760 class Split : Container
761 {
762   nothrow:
763   this()                               { super(IupSplit(null, null)); }
764   this(Control child)                  { super(IupSplit(child.GetHandle(), null)); }
765   this(Control child1, Control child2) { super(IupSplit(child1.GetHandle(), child2.GetHandle())); }
766 }
767 
768 class Submenu : Container
769 {
770   nothrow:
771   this(const(char)* title = null)         { super(IupSubmenu(title, null)); }
772   this(const(char)* title, Control child) { super(IupSubmenu(title, child.GetHandle())); }
773 }
774 
775 class Radio : Container
776 {
777   nothrow:
778   this()              { super(IupRadio(null)); }
779   this(Control child) { super(IupRadio(child.GetHandle())); }
780   this(string CN, Control child) { super(IupRadio(child.GetHandle())); if (!CN.empty) { AA[CN] = this; IupSetHandle(CN.toStringz, _ih); } }
781 }
782 
783 class Sbox : Container
784 {
785   nothrow:
786   this()              { super(IupSbox(null)); }
787   this(Control child) { super(IupSbox(child.GetHandle())); }
788 }
789 
790 class ScrollBox : Container
791 {
792   nothrow:
793   this()              { super(IupScrollBox(null)); }
794   this(Control child) { super(IupScrollBox(child.GetHandle())); }
795 }
796 
797 class FlatScrollBox : Container
798 {
799   nothrow:
800   this()              { super(IupFlatScrollBox(null)); }
801   this(Control child) { super(IupFlatScrollBox(child.GetHandle())); }
802   this(FlatScrollBox container) { super(container.GetHandle()); }
803   this(Ihandle* _ih)  { super(_ih); }
804 }
805 
806 class Expander : Container
807 {
808   nothrow:
809   this()              { super(IupExpander(null)); }
810   this(Control child) { super(IupExpander(child.GetHandle())); }
811 }
812 
813 class DetachBox : Container
814 {
815   nothrow:
816   this()              { super(IupDetachBox(null)); }
817   this(Control child) { super(IupDetachBox(child.GetHandle())); }
818 }
819 
820   class BackgroundBox : Container
821   {
822     nothrow:
823     this()              { super(IupBackgroundBox(null)); }
824     this(Control child) { super(IupBackgroundBox(child.GetHandle())); }
825 
826     void DrawBegin() { IupDrawBegin(_ih); }
827     void DrawEnd() { IupDrawEnd(_ih); }
828     void DrawSetClipRect(int x1, int y1, int x2, int y2) { IupDrawSetClipRect(_ih, x1, y1, x2, y2); }
829     void DrawGetClipRect(ref int x1, ref int y1, ref int x2, ref int y2) { IupDrawGetClipRect(_ih, &x1, &y1, &x2, &y2); }
830     void DrawResetClip() { IupDrawResetClip(_ih); }
831     void DrawParentBackground() { IupDrawParentBackground(_ih); }
832     void DrawLine(int x1, int y1, int x2, int y2) { IupDrawLine(_ih, x1, y1, x2, y2); }
833     void DrawRectangle(int x1, int y1, int x2, int y2) { IupDrawRectangle(_ih, x1, y1, x2, y2); }
834     void DrawArc(int x1, int y1, int x2, int y2, double a1, double a2) { IupDrawArc(_ih, x1, y1, x2, y2, a1, a2); }
835     void DrawPolygon(int* points, int count) { IupDrawPolygon(_ih, points, count); }
836     void DrawText(const(char)* text, int len, int x, int y, int w, int h) { IupDrawText(_ih, text, len, x, y, w, h); } // signature changed from 3.24 to 3.25
837     void DrawImage(const(char)* name, int x, int y, int w, int h) { IupDrawImage(_ih, name, x, y, h, h); } // signature changed from 3.24 to 3.25
838     void DrawSelectRect(int x1, int y1, int x2, int y2) { IupDrawSelectRect(_ih, x1, y1, x2, y2); }
839     void DrawFocusRect(int x1, int y1, int x2, int y2) { IupDrawFocusRect(_ih, x1, y1, x2, y2); }
840     void DrawGetSize(ref int w, ref int h) { IupDrawGetSize(_ih, &w, &h); }
841     void DrawGetTextSize(const(char)* str, int len, ref int w, ref int h) { IupDrawGetTextSize(_ih, str, len, &w, &h); } // signature changed from 3.24 to 3.25
842     void DrawGetImageInfo(const(char)* name, ref int w, ref int h, ref int bpp) { IupDrawGetImageInfo(name, &w, &h, &bpp); }
843   }
844 
845 class Frame : Container
846 {
847   nothrow:
848   this()              { super(IupFrame(null)); }
849   this(Control child) { super(IupFrame(child.GetHandle)); }
850 }
851 
852 
853 class FlatFrame : Container
854 {
855   nothrow:
856   this()              { super(IupFlatFrame(null)); }
857   this(Control child) { super(IupFlatFrame(child.GetHandle)); }
858 }
859 deprecated class Spinbox : Container
860 {
861   nothrow:
862   this()              { super(IupSpinbox(null)); }
863   this(Control child) { super(IupSpinbox(child.GetHandle())); }
864 }
865 
866 class Vbox : Container //TODO do care for last element/child=null
867 {
868   nothrow:
869   this()              { super(IupVbox(null)); }
870   this(Ihandle* ih)   { super(ih); } // temporarily
871   this(Control child) { super(IupVbox(child.GetHandle, null)); }
872   this(Control child0, Control child1 = null, Control child2 = null, Control child3 = null, Control child4 = null,
873     Control child5 = null, Control child6 = null, Control child7 = null, Control child8 = null, Control child9 = null)
874     { super(IupVbox(null), child0, child1, child2, child3, child4, child5, child6, child7, child8, child9); }
875 
876   this(           Control[] child_array, FILL_TYPE fill=FILL_TYPE.FILL_NONE) { super(IupVbox(null), child_array, fill); }
877   this(string CN, Control[] child_array, FILL_TYPE fill=FILL_TYPE.FILL_NONE) { this(child_array, fill); if (!CN.empty) { AA[CN] = this; IupSetHandle(CN.toStringz, _ih); } }
878 }
879 
880 class Hbox : Container
881 {
882   nothrow:
883   this()              { super(IupHbox(null)); }
884   this(Ihandle* ih)   { super(ih); } // temporarily
885   this(Control child) { super(IupHbox(child.GetHandle, null)); }
886 
887   this(Control child0, Control child1 = null, Control child2 = null, Control child3 = null, Control child4 = null,
888      Control child5 = null, Control child6 = null, Control child7 = null, Control child8 = null, Control child9 = null)
889     { super(IupHbox(null), child0, child1, child2, child3, child4, child5, child6, child7, child8, child9); }
890   this(string CN, Control child0, Control child1 = null, Control child2 = null, Control child3 = null, Control child4 = null,
891     Control child5 = null, Control child6 = null, Control child7 = null, Control child8 = null, Control child9 = null)
892     { this(child0, child1, child2, child3, child4, child5, child6, child7, child8, child9);
893       if (!CN.empty) { AA[CN] = this; IupSetHandle(CN.toStringz, _ih); } }
894 
895   this(           Control[] child_array, FILL_TYPE fill=FILL_TYPE.FILL_NONE) { super(IupHbox(null), child_array, fill); }
896   this(string CN, Control[] child_array, FILL_TYPE fill=FILL_TYPE.FILL_NONE) { this(child_array, fill); if (!CN.empty) { AA[CN] = this; IupSetHandle(CN.toStringz, _ih); } }
897 }
898 
899   class Zbox : Container
900   {
901     nothrow:
902     this() { super(IupZbox(null)); }
903     this(Control child) { super(IupZbox(child.GetHandle(), null)); }
904     this(Control child0, Control child1 = null, Control child2 = null, Control child3 = null, Control child4 = null,
905       Control child5 = null, Control child6 = null, Control child7 = null, Control child8 = null, Control child9 = null)
906       { super(IupZbox(null), child0, child1, child2, child3, child4, child5, child6, child7, child8, child9); }
907     this(Control[] child_array) { super(IupZbox(null), child_array); }
908   }
909 
910   class Cbox : Container
911   {
912     nothrow:
913     this() { super(IupCbox(null)); }
914     this(Control child) { super(IupCbox(child.GetHandle(), null)); }
915     this(Control child0, Control child1 = null, Control child2 = null, Control child3 = null, Control child4 = null,
916       Control child5 = null, Control child6 = null, Control child7 = null, Control child8 = null, Control child9 = null)
917       { super(IupCbox(null), child0, child1, child2, child3, child4, child5, child6, child7, child8, child9); }
918     this(Control[] child_array) { super(IupCbox(null), child_array); }
919   }
920 
921 
922 class Tabs : Container
923 {
924     nothrow:
925     this()                        { super(IupTabs(null)); }
926 //  this(Ihandle* ih)             { super(ih); } // temporarily
927 //  this(string CN, Ihandle* ih)  { super(ih); if (!CN.empty) { AA[CN] = this; IupSetHandle(CN.toStringz, _ih); } } // temporarily
928     this(Control child) { super(IupTabs(child.GetHandle(), null)); }
929     this(Control child0, Control child1 = null, Control child2 = null, Control child3 = null, Control child4 = null,
930         Control child5 = null, Control child6 = null, Control child7 = null, Control child8 = null, Control child9 = null)
931     {
932         Control[] child_array;
933         child_array ~= child0; child_array ~= child1; child_array ~= child2; child_array ~= child3; child_array ~= child4;
934         child_array ~= child5; child_array ~= child6; child_array ~= child7; child_array ~= child8; child_array ~= child9;
935         this(child_array);
936     }
937     this(Control[] child_array)
938     {
939         ptrdiff_t  index = index_first_null(child_array);
940         if      (index==0)
941             this();
942         else if (index==1)
943             this(child_array[0]);
944         else {
945             Ihandle*[] arr_ih = new Ihandle*[index+1];
946             foreach (i; 0..index)
947                 arr_ih[i] = child_array[i].GetHandle();
948             arr_ih[index] = null;
949             super(IupTabsv(arr_ih.ptr));
950        }
951 //      super(IupTabs(null), child_array);
952   }
953   this(string CN, Control[] child_array) { this(child_array); if (!CN.empty) { AA[CN] = this; IupSetHandle(CN.toStringz, _ih); } }
954 }
955 
956 class GridBox : Container
957 {
958   nothrow:
959   this() { super(IupGridBox(null)); }
960   this(Control child) { super(IupGridBox(child.GetHandle(), null)); }
961   this(Control child0, Control child1 = null, Control child2 = null, Control child3 = null, Control child4 = null,
962     Control child5 = null, Control child6 = null, Control child7 = null, Control child8 = null, Control child9 = null)
963     { super(IupGridBox(null), child0, child1, child2, child3, child4, child5, child6, child7, child8, child9); }
964   this(Control[] child_array) { super(IupGridBox(null), child_array); }
965 }
966 
967 class ParamBox : Container
968 {
969   nothrow:
970   this() { super(IupParamBox(null)); }
971   this(Control child) { super(IupParamBox(child.GetHandle(), null)); }
972   this(Control child0, Control child1 = null, Control child2 = null, Control child3 = null, Control child4 = null,
973     Control child5 = null, Control child6 = null, Control child7 = null, Control child8 = null, Control child9 = null)
974     { super(IupParamBox(child0.GetHandle(), child1.GetHandle(), child2.GetHandle(), child3.GetHandle(), child4.GetHandle(),
975     child5.GetHandle(), child6.GetHandle(), child7.GetHandle(), child8.GetHandle(), child9.GetHandle(), null)); }
976 }
977 
978   class Normalizer : Container
979   {
980     nothrow:
981     this() { super(IupNormalizer(null)); }
982     this(Control child) { super(IupNormalizer(child.GetHandle(), null)); }
983     this(Control child0, Control child1 = null, Control child2 = null, Control child3 = null, Control child4 = null,
984       Control child5 = null, Control child6 = null, Control child7 = null, Control child8 = null, Control child9 = null)
985       { super(IupNormalizer(null), child0, child1, child2, child3, child4, child5, child6, child7, child8, child9); }
986     this(Control[] child_array) { super(IupNormalizer(null), child_array); }
987   }
988 
989 
990 class FileDialog : Dialog
991 {
992   nothrow:
993   this() { super(IupFileDlg); }
994 }
995 
996 class MessageDialog : Dialog
997 {
998   nothrow:
999   this(bool autoDestroy = true) { super(autoDestroy, IupMessageDlg()); }
1000 }
1001 
1002 class ColorDialog : Dialog
1003 {
1004   nothrow:
1005   this() { super(IupColorDlg); }
1006 }
1007 
1008 class FontDialog : Dialog
1009 {
1010   nothrow:
1011   this() { super(IupFontDlg); }
1012 }
1013 
1014 class ProgressDialog : Dialog
1015 {
1016   nothrow:
1017   this() { super(IupProgressDlg); }
1018 }
1019 
1020 version(IUP_SCINTILLA)
1021 {
1022 class ScintillaDlg : Dialog
1023 {
1024   public import iup.iup_scintilla;
1025   nothrow:
1026   this() { super(IupScintillaDlg()); }
1027 }
1028 }
1029 /+
1030 #ifdef LUA_VERSION
1031   public:
1032     LuaScripterDlg(lua_State *L) : Dialog(IupLuaScripterDlg(L)) {}
1033   };
1034 #endif
1035 +/
1036 version(IUP_GL)
1037 {
1038   public import iup.iupgl;
1039 
1040   class GLCanvas : Control
1041   {
1042     nothrow:
1043     this() { super(IupGLCanvas(null)); }
1044 
1045     static void Open() { IupGLCanvasOpen; }
1046 
1047     void MakeCurrent() { IupGLMakeCurrent(_ih); }
1048     int IsCurrent() { return IupGLIsCurrent(_ih); }
1049     void SwapBuffers() { IupGLSwapBuffers(_ih); }
1050     void Palette(int index, float r, float g, float b) { IupGLPalette(_ih, index, r, g, b); }
1051     void UseFont(int first, int count, int list_base) { IupGLUseFont(_ih, first, count, list_base); }
1052 
1053     static void Wait(int gl) { IupGLWait(gl); }
1054   }
1055 
1056   class GLBackgroundBox : Container
1057   {
1058     nothrow:
1059     this() { super(IupGLBackgroundBox(null)); }
1060     this(Control child) { super(IupGLBackgroundBox(child.GetHandle)); }
1061   }
1062 }
1063 /+
1064   class Controls
1065   {
1066     static void Open() { IupControlsOpen(); }
1067   }
1068 +/
1069 class Dial : Control
1070 {
1071   nothrow:
1072   this(const(char)* orientation = null) { super(IupDial(orientation)); }
1073 }
1074 
1075 class Gauge : Control
1076 {
1077   nothrow:
1078   this() { super(IupGauge); }
1079 }
1080 
1081 class ColorBrowser : Control
1082 {
1083   nothrow:
1084   this() { super(IupColorBrowser); }
1085 }
1086 
1087 class Cells : Control
1088 {
1089   nothrow:
1090   this() { super(IupCells); }
1091 }
1092 
1093 class Colorbar : Control
1094 {
1095   nothrow:
1096   this() { super(IupColorbar); }
1097 }
1098 
1099 class Matrix : Control
1100 {
1101   nothrow:
1102   this()          { super(IupMatrix(null)); }
1103   this(string CN) { this(); if (!CN.empty) { AA[CN] = this; IupSetHandle(CN.toStringz, _ih); } }
1104 
1105 //  void SetFormula(int col, const(char)* formula, const(char)* init = null) { IupMatrixSetFormula(_ih, col, formula, init); }
1106 //  void SetDynamic(const(char)* init = null) { IupMatrixSetDynamic(_ih, init); }
1107 }
1108 
1109 class MatrixList : Control
1110 {
1111   nothrow:
1112   this()          { super(IupMatrixList); }
1113   this(string CN) { this(); if (!CN.empty) { AA[CN] = this; IupSetHandle(CN.toStringz, _ih); } }
1114 }
1115 
1116 version(none/*IUP_MATRIXEX*/) {
1117 /+
1118   public import iup.iupmatrixex;
1119 
1120   class MatrixEx : Control
1121   {
1122     nothrow:
1123     this() { super(IupMatrixEx); }
1124 
1125     static void Open() { IupMatrixExOpen; }
1126   }
1127 +/
1128 }
1129 
1130 version(IUP_GLCONTROLS)
1131 {
1132   public import iup.iupglcontrols;
1133 
1134 /+
1135   class GLControls
1136   {
1137     static void Open() { IupGLControlsOpen(); }
1138   }
1139 +/
1140 
1141   class GLSubCanvas : Control
1142   {
1143     nothrow:
1144     this() { super(IupGLSubCanvas); }
1145   }
1146 
1147   class GLSeparator : Control
1148   {
1149     nothrow:
1150     this() { super(IupGLSeparator); }
1151   }
1152 
1153   class GLProgressBar : Control
1154   {
1155     nothrow:
1156     this() { super(IupGLProgressBar); }
1157   }
1158 
1159   class GLVal : Control
1160   {
1161     nothrow:
1162     this() { super(IupGLVal); }
1163   }
1164 
1165   class GLLabel : Control
1166   {
1167     nothrow:
1168     this(const(char)* title = null) { super(IupGLLabel(title)); }
1169   }
1170 
1171   class GLButton : Control
1172   {
1173     nothrow:
1174     this(const(char)* title = null) { super(IupGLButton(title)); }
1175   }
1176 
1177   class GLToggle : Control
1178   {
1179     nothrow:
1180     this(const(char)* title = null) { super(IupGLToggle(title)); }
1181   }
1182 
1183   class GLLink : Control
1184   {
1185     nothrow:
1186     this(const(char)* url = null, const(char)* title = null) { super(IupGLLink(url, title)); }
1187   }
1188 
1189   class GLFrame : Container
1190   {
1191     nothrow:
1192     this(Control child) { super(IupGLFrame(child.GetHandle)); }
1193     this() { super(IupGLFrame(null)); }
1194   }
1195 
1196   class GLExpander : Container
1197   {
1198     nothrow:
1199     this(Control child) { super(IupGLExpander(child.GetHandle)); }
1200     this() { super(IupGLExpander(null)); }
1201   }
1202 
1203   class GLScrollBox : Container
1204   {
1205     nothrow:
1206     this(Control child) { super(IupGLScrollBox(child.GetHandle)); }
1207     this() { super(IupGLScrollBox(null)); }
1208   }
1209 
1210   class GLSizeBox : Container
1211   {
1212     nothrow:
1213     this(Control child) { super(IupGLSizeBox(child.GetHandle)); }
1214     this() { super(IupGLSizeBox(null)); }
1215   }
1216 
1217   class GLCanvasBox : Container
1218   {
1219     nothrow:
1220     this() { super(IupGLCanvasBox(null)); }
1221     this(Control child) { super(IupGLCanvasBox(child.GetHandle(), null)); }
1222     this(Control child0, Control child1 = null, Control child2 = null, Control child3 = null, Control child4 = null,
1223       Control child5 = null, Control child6 = null, Control child7 = null, Control child8 = null, Control child9 = null)
1224       { super(IupGLCanvasBox(null), child0, child1, child2, child3, child4, child5, child6, child7, child8, child9); }
1225     this(Control[] child_array) { super(IupGLCanvasBox(null), child_array); }
1226   }
1227 
1228 } // version(IUP_GLCONTROLS)
1229 
1230 version(IUP_PLOT) {
1231   public import iup.iup_plot;
1232 
1233   class Plot : Control
1234   {
1235     nothrow:
1236     this() { super(IupPlot); }
1237 
1238     static void Open() { IupPlotOpen; }
1239 
1240     void Begin(int strXdata) { IupPlotBegin(_ih, strXdata); }
1241     void Add(double x, double y) { IupPlotAdd(_ih, x, y); }
1242     void AddStr(const(char)* x, double y) { IupPlotAddStr(_ih, x, y); }
1243     void AddSegment(double x, double y) { IupPlotAddSegment(_ih, x, y); }
1244     int End() { return IupPlotEnd(_ih); }
1245 
1246     int LoadData(const(char)* filename, int strXdata) { return IupPlotLoadData(_ih, filename, strXdata); }
1247 
1248 //  int SetFormula(int sample_count, const(char)* formula, const(char)* init) { return IupPlotSetFormula(_ih, sample_count, formula, init); }
1249 
1250     void Insert(int ds_index, int sample_index, double x, double y) { IupPlotInsert(_ih, ds_index, sample_index, x, y); }
1251     void InsertStr(int ds_index, int sample_index, const(char)* x, double y) { IupPlotInsertStr(_ih, ds_index, sample_index, x, y); }
1252     void InsertSegment(int ds_index, int sample_index, double x, double y) { IupPlotInsertSegment(_ih, ds_index, sample_index, x, y); }
1253 
1254     void InsertStrSamples(int ds_index, int sample_index, const(char)** x, double* y, int count) { IupPlotInsertStrSamples(_ih, ds_index, sample_index, x, y, count); }
1255     void InsertSamples(int ds_index, int sample_index, double* x, double* y, int count) { IupPlotInsertSamples(_ih, ds_index, sample_index, x, y, count); }
1256 
1257     void AddSamples(int ds_index, double* x, double* y, int count) { IupPlotAddSamples(_ih, ds_index, x, y, count); }
1258     void AddStrSamples(int ds_index, const(char)** x, double* y, int count) { IupPlotAddStrSamples(_ih, ds_index, x, y, count); }
1259 
1260     void GetSample(int ds_index, int sample_index, ref double x, ref double y) { IupPlotGetSample(_ih, ds_index, sample_index, &x, &y); }
1261     void GetSampleStr(int ds_index, int sample_index, const(char)** x, ref double y) { IupPlotGetSampleStr(_ih, ds_index, sample_index, x, &y); }
1262     int GetSampleSelection(int ds_index, int sample_index) { return IupPlotGetSampleSelection(_ih, ds_index, sample_index); }
1263     double GetSampleExtra(int ds_index, int sample_index) { return IupPlotGetSampleExtra(_ih, ds_index, sample_index); }
1264     void SetSample(int ds_index, int sample_index, double x, double y) { IupPlotSetSample(_ih, ds_index, sample_index, x, y); }
1265     void SetSampleStr(int ds_index, int sample_index, const(char)* x, double y) { IupPlotSetSampleStr(_ih, ds_index, sample_index, x, y); }
1266     void SetSampleSelection(int ds_index, int sample_index, int selected) { IupPlotSetSampleSelection(_ih, ds_index, sample_index, selected); }
1267     void SetSampleExtra(int ds_index, int sample_index, double extra) { IupPlotSetSampleExtra(_ih, ds_index, sample_index, extra); }
1268 
1269     void Transform(double x, double y, ref double cnv_x, ref double cnv_y) { IupPlotTransform(_ih, x, y, &cnv_x, &cnv_y); }
1270     void TransformTo(double cnv_x, double cnv_y, ref double x, ref double y) { IupPlotTransformTo(_ih, cnv_x, cnv_y, &x, &y); }
1271 
1272     int FindSample(double cnv_x, double cnv_y, ref int ds_index, ref int sample_index) { return IupPlotFindSample(_ih, cnv_x, cnv_y, &ds_index, &sample_index); }
1273 
1274     version(CD) void PaintTo(cd.cd_plusD.Canvas cd_canvas) { IupPlotPaintTo(_ih, cd_canvas.GetHandle()); }
1275   } // class Plot
1276 } // version(IUP_PLOT)
1277 
1278 version(IUP_MGLPLOT) {
1279   import iup.iup_mglplot;
1280 
1281   class MglPlot : Control
1282   {
1283     nothrow:
1284     this() { super(IupMglPlot); }
1285 
1286     static void Open() { IupMglPlotOpen; }
1287 
1288     void Begin(int dim) { IupMglPlotBegin(_ih, dim); }
1289     void Add1D(const(char)* name, double y) { IupMglPlotAdd1D(_ih, name, y); }
1290     void Add2D(double x, double y) { IupMglPlotAdd2D(_ih, x, y); }
1291     void Add3D(double x, double y, double z) { IupMglPlotAdd3D(_ih, x, y, z); }
1292     int End() { return IupMglPlotEnd(_ih); }
1293 
1294     int NewDataSet(int dim) { return IupMglPlotNewDataSet(_ih, dim); }
1295 
1296     void Insert1D(int ds_index, int sample_index, const(char)** names, const double* y, int count) { IupMglPlotInsert1D(_ih, ds_index, sample_index, names, y, count); }
1297     void Insert2D(int ds_index, int sample_index, const double* x, const double* y, int count) { IupMglPlotInsert2D(_ih, ds_index, sample_index, x, y, count); }
1298     void Insert3D(int ds_index, int sample_index, const double* x, const double* y, const double* z, int count) { IupMglPlotInsert3D(_ih, ds_index, sample_index, x, y, z, count); }
1299 
1300     void Set1D(int ds_index, const(char)** names, const double* y, int count) { IupMglPlotSet1D(_ih, ds_index, names, y, count); }
1301     void Set2D(int ds_index, const double* x, const double* y, int count) { IupMglPlotSet2D(_ih, ds_index, x, y, count); }
1302     void Set3D(int ds_index, const double* x, const double* y, const double* z, int count) { IupMglPlotSet3D(_ih, ds_index, x, y, z, count); }
1303     void SetFormula(int ds_index, const(char)* formulaX, const(char)* formulaY, const(char)* formulaZ, int count) { IupMglPlotSetFormula(_ih, ds_index, formulaX, formulaY, formulaZ, count); }
1304 
1305     void SetData(int ds_index, const double* data, int count_x, int count_y, int count_z) { IupMglPlotSetData(_ih, ds_index, data, count_x, count_y, count_z); }
1306     void LoadData(int ds_index, const(char)* filename, int count_x, int count_y, int count_z) { IupMglPlotLoadData(_ih, ds_index, filename, count_x, count_y, count_z); }
1307     void SetFromFormula(int ds_index, const(char)* formula, int count_x, int count_y, int count_z) { IupMglPlotSetFromFormula(_ih, ds_index, formula, count_x, count_y, count_z); }
1308 
1309     void Transform(double x, double y, double z, ref int ix, ref int iy) { IupMglPlotTransform(_ih, x, y, z, &ix, &iy); }
1310     void TransformTo(int ix, int iy, ref double x, ref double y, ref double z) { IupMglPlotTransformTo(_ih, ix, iy, &x, &y, &z); }
1311 
1312     void DrawMark(double x, double y, double z) { IupMglPlotDrawMark(_ih, x, y, z); }
1313     void DrawLine(double x1, double y1, double z1, double x2, double y2, double z2) { IupMglPlotDrawLine(_ih, x1, y1, z1, x2, y2, z2); }
1314     void DrawText(const(char)* text, double x, double y, double z) { IupMglPlotDrawText(_ih, text, x, y, z); }
1315 
1316     void PaintTo(const(char)* format, int w, int h, double dpi, ubyte* data) { IupMglPlotPaintTo(_ih, format, w, h, dpi, cast(void*)data); }
1317     void PaintTo(const(char)* format, int w, int h, double dpi, const(char)* filename) { IupMglPlotPaintTo(_ih, format, w, h, dpi, cast(void*)filename); }
1318 
1319   }
1320 
1321   class MglLabel : Control
1322   {
1323     nothrow:
1324     this(const(char)* title) { super(IupMglLabel(title)); }
1325   }
1326 }
1327 
1328 version(Windows) { version(IUP_OLE) {
1329   public import iup.iupole;
1330 
1331   class OleControl : Control
1332   {
1333     nothrow:
1334     this(const(char)* progid) { super(IupOleControl(progid)); }
1335 
1336     static void Open() { IupOleControlOpen; }
1337  }
1338 } }
1339 
1340 version(IUP_WEB) {
1341   public import iup.iupweb;
1342 
1343   class WebBrowser : Control
1344   {
1345     nothrow:
1346     this() { super(IupWebBrowser); }
1347 
1348     static void Open() { IupWebBrowserOpen; }
1349   }
1350 }
1351 
1352 
1353 version(IUP_SCINTILLA) {
1354   public import iup.iup_scintilla;
1355 
1356   class Scintilla : Control
1357   {
1358     nothrow:
1359     this() { super(IupScintilla); }
1360 
1361     static void Open() { IupScintillaOpen; }
1362   }
1363 }
1364 
1365 version(IUP_TUIO) {
1366   public import iup.iuptuio;
1367 
1368   class TuioClient : Handle
1369   {
1370     nothrow:
1371     this(int port) { super(IupTuioClient(port)); }
1372 
1373     static void Open() { IupTuioOpen; }
1374   }
1375 }
1376 
1377 class Config : Handle
1378 {
1379   nothrow:
1380   this()          { super(IupConfig()); }
1381 //  this(string CN) { this(); if (!CN.empty) { AA[CN] = this; IupSetHandle(CN.toStringz, _ih); } }
1382 
1383   int LoadConfig() { return IupConfigLoad(_ih); }
1384   int SaveConfig() { return IupConfigSave(_ih); }
1385 
1386   void SetVariableStrId   (const(char)* group, const(char)* key, int id, const(char)* value) { IupConfigSetVariableStrId(_ih, group, key, id, value); }
1387   void SetVariableIntId   (const(char)* group, const(char)* key, int id, int value)          { IupConfigSetVariableIntId(_ih, group, key, id, value); }
1388   void SetVariableDoubleId(const(char)* group, const(char)* key, int id, double value) { IupConfigSetVariableDoubleId(_ih, group, key, id, value); }
1389   void SetVariableStr(     const(char)* group, const(char)* key, const(char)* value)   { IupConfigSetVariableStr(_ih, group, key, value); }
1390   void SetVariableInt     (const(char)* group, const(char)* key, int value)            { IupConfigSetVariableInt(_ih, group, key, value); }
1391   void SetVariableDouble  (const(char)* group, const(char)* key, double value)         { IupConfigSetVariableDouble(_ih, group, key, value); }
1392 
1393   char*  GetVariableStr     (const(char)* group, const(char)* key)         { return cast(char*)IupConfigGetVariableStr(_ih, group, key); }
1394   int    GetVariableInt     (const(char)* group, const(char)* key)         { return IupConfigGetVariableInt(_ih, group, key); }
1395   double GetVariableDouble  (const(char)* group, const(char)* key)         { return IupConfigGetVariableDouble(_ih, group, key); }
1396   char*  GetVariableStrId   (const(char)* group, const(char)* key, int id) { return cast(char*)IupConfigGetVariableStrId(_ih, group, key, id); }
1397   int    GetVariableIntId   (const(char)* group, const(char)* key, int id) { return IupConfigGetVariableIntId(_ih, group, key, id); }
1398   double GetVariableDoubleId(const(char)* group, const(char)* key, int id) { return IupConfigGetVariableDoubleId(_ih, group, key, id); }
1399 
1400   char*  GetVariableStrDef     (const(char)* group, const(char)* key, const(char)* def) { return cast(char*)IupConfigGetVariableStrDef(_ih, group, key, def); }
1401   int    GetVariableIntDef     (const(char)* group, const(char)* key, int def) { return IupConfigGetVariableIntDef(_ih, group, key, def); }
1402   double GetVariableDoubleDef  (const(char)* group, const(char)* key, double def) { return IupConfigGetVariableDoubleDef(_ih, group, key, def); }
1403   char*  GetVariableStrIdDef   (const(char)* group, const(char)* key, int id, const(char)* def) { return cast(char*)IupConfigGetVariableStrIdDef(_ih, group, key, id, def); }
1404   int    GetVariableIntIdDef   (const(char)* group, const(char)* key, int id, int def) { return IupConfigGetVariableIntIdDef(_ih, group, key, id, def); }
1405   double GetVariableDoubleIdDef(const(char)* group, const(char)* key, int id, double def) { return IupConfigGetVariableDoubleIdDef(_ih, group, key, id, def); }
1406 
1407   void Copy(Config config2, const(char)* exclude_prefix) { IupConfigCopy(_ih, config2.GetHandle(), exclude_prefix); }
1408 
1409   void SetListVariable(const(char)* group, const(char)* key, const(char)* value, int add) { IupConfigSetListVariable(_ih, group, key, value, add); }
1410 
1411   void RecentInit(Menu menu, Icallback recent_cb, int max_recent) { IupConfigRecentInit(_ih, menu.GetHandle(), recent_cb, max_recent); }
1412   void RecentUpdate(const(char)* filename) { IupConfigRecentUpdate(_ih, filename); }
1413 
1414   void DialogShow(Dialog dialog, const(char)* name) { IupConfigDialogShow(_ih, dialog.GetHandle(), name); }
1415   void DialogClosed(Dialog dialog, const(char)* name) { IupConfigDialogClosed(_ih, dialog.GetHandle(), name); }
1416 }
1417 
1418 //} // namespace iup
1419 
1420 
1421 version(CD) //#ifdef __CD_PLUS_H
1422 { // was in C++ namespace cd
1423   import cd.cd_plusD;
1424 
1425   class CanvasIup : cd.cd_plusD.Canvas // public Canvas
1426   {
1427     nothrow:
1428     this(iup.iup_plusD.Canvas iup_canvas) { // CanvasIup(Iup::Canvas& iup_canvas) : Canvas() { ... }
1429       super();
1430       canvas = cdCreateCanvas(CD_IUP, iup_canvas.GetHandle());
1431     }
1432   }
1433 
1434   class CanvasIupDoubleBuffer : cd.cd_plusD.Canvas // public Canvas
1435   {
1436     nothrow:
1437     this(iup.iup_plusD.Canvas iup_canvas) { // CanvasIupDoubleBuffer(Iup::Canvas& iup_canvas) : Canvas() { ... }
1438       super();
1439       canvas = cdCreateCanvas(CD_IUPDBUFFER, iup_canvas.GetHandle());
1440     }
1441   }
1442 
1443   class CanvasIupDoubleBufferRGB : cd.cd_plusD.Canvas // public Canvas
1444   {
1445     nothrow:
1446     this(iup.iup_plusD.Canvas iup_canvas) { // CanvasIupDoubleBufferRGB(Iup::Canvas& iup_canvas) : Canvas() { ... }
1447       super();
1448       canvas = cdCreateCanvas(CD_IUPDBUFFERRGB, iup_canvas.GetHandle());
1449     }
1450   }
1451 } // version(CD)