1 module ui.Core;
2 
3 public import ui.Def;
4 
5 package:
6 
7 string toString(char *source) {
8     if (!source) {
9         return null;
10     }
11     import core.stdc.string: strlen;
12     auto s = source[0..strlen(source)].idup;
13     uiFreeText(source);
14     return s;
15 }
16 
17 mixin template EventListenerMixin(string Event, TargetT = NoneTypeTag, ReturnT = void) {
18     template Impl() {
19         static if (is(ReturnT == void)) {
20             enum RET = "";
21         } else {
22             enum RET = "return 1;";
23         }
24         import std.format: format;
25         static if (is(TargetT == NoneTypeTag)) {
26             enum Impl = q{
27                 private static void delegate()[] %1$sListeners;
28                 private extern (C) static %2$s %1$sCallback(void *data) {
29                     foreach (dlg; %1$sListeners) {
30                         dlg();
31                     }
32                     %3$s
33                 }
34                 public static void %1$s(void delegate() f) {
35                     %1$sListeners ~= f;
36                 }
37             }.format(Event, ReturnT.stringof, RET);
38         } else {
39             enum Impl = q{
40                 private void delegate(%2$s v)[] %1$sListeners;
41                 private extern (C) static %3$s %1$sCallback(ui%2$s *, void *data) {
42                     auto v = cast(%2$s) data;
43                     foreach (dlg; v.%1$sListeners) {
44                         dlg(v);
45                     }
46                     %4$s
47                 }
48                 public %2$s add%1$s(void delegate(%2$s v) f) {
49                     %1$sListeners ~= f;
50                     return this;
51                 }
52             }.format(Event, TargetT.stringof, ReturnT.stringof, RET);
53         }
54     }
55     //pragma(msg, Impl!());
56     mixin(Impl!());
57 }
58 
59 struct NoneTypeTag {}
60 
61 
62 
63 extern(C):
64 
65 struct uiInitOptions {
66     size_t Size;
67 };
68 
69 const(char) *uiInit(uiInitOptions *options);
70 void uiUninit();
71 void uiFreeInitError(const(char) *err);
72 
73 void uiMain();
74 void uiMainSteps();
75 int uiMainStep(int wait);
76 void uiQuit();
77 
78 void uiQueueMain(void function(void *data) f, void *data);
79 
80 void uiOnShouldQuit(int function(void *data) f, void *data);
81 
82 void uiFreeText(char *text);
83 
84 import core.stdc.stdint;
85 
86 struct uiControl {
87     uint32_t Signature;
88     uint32_t OSSignature;
89     uint32_t TypeSignature;
90     void function(uiControl *) Destroy;
91     uintptr_t function(uiControl *) Handle;
92     uiControl *function(uiControl *) Parent;
93     void function(uiControl *, uiControl *) SetParent;
94     int function(uiControl *) Toplevel;
95     int function(uiControl *) Visible;
96     void function(uiControl *) Show;
97     void function(uiControl *) Hide;
98     int function(uiControl *) Enabled;
99     void function(uiControl *) Enable;
100     void function(uiControl *) Disable;
101 };
102 // TOOD add argument names to all arguments
103 void uiControlDestroy(uiControl *);
104 uintptr_t uiControlHandle(uiControl *);
105 uiControl *uiControlParent(uiControl *); // TODO: NO USE
106 void uiControlSetParent(uiControl *, uiControl *);
107 int uiControlToplevel(uiControl *);
108 int uiControlVisible(uiControl *);
109 void uiControlShow(uiControl *);
110 void uiControlHide(uiControl *);
111 int uiControlEnabled(uiControl *);
112 void uiControlEnable(uiControl *);
113 void uiControlDisable(uiControl *);
114 
115 // TODO: NO USE
116 // TODO make sure all controls have these
117 uiControl *uiAllocControl(size_t n, uint32_t OSsig, uint32_t typesig, const(char)*typenamestr);
118 void uiFreeControl(uiControl *);
119 
120 void uiControlVerifySetParent(uiControl *, uiControl *);
121 int uiControlEnabledToUser(uiControl *);
122 
123 // TODO: NO USE
124 void uiUserBugCannotSetParentOnToplevel(const(char) *type);
125 
126 struct uiWindow;
127 char *uiWindowTitle(uiWindow *w);
128 void uiWindowSetTitle(uiWindow *w, const(char) *title);
129 void uiWindowPosition(uiWindow *w, int *x, int *y);
130 void uiWindowSetPosition(uiWindow *w, int x, int y);
131 void uiWindowCenter(uiWindow *w);
132 void uiWindowOnPositionChanged(uiWindow *w, void function(uiWindow *, void *) f, void *data);
133 void uiWindowContentSize(uiWindow *w, int *width, int *height);
134 void uiWindowSetContentSize(uiWindow *w, int width, int height);
135 int uiWindowFullscreen(uiWindow *w);
136 void uiWindowSetFullscreen(uiWindow *w, int fullscreen);
137 void uiWindowOnContentSizeChanged(uiWindow *w, void function(uiWindow *, void *) f, void *data);
138 void uiWindowOnClosing(uiWindow *w, int function(uiWindow *w, void *data) f, void *data);
139 int uiWindowBorderless(uiWindow *w);
140 void uiWindowSetBorderless(uiWindow *w, int borderless);
141 void uiWindowSetChild(uiWindow *w, uiControl *child);
142 int uiWindowMargined(uiWindow *w);
143 void uiWindowSetMargined(uiWindow *w, int margined);
144 uiWindow *uiNewWindow(const(char) *title, int width, int height, int hasMenubar);
145 
146 struct uiButton;
147 char *uiButtonText(uiButton *b);
148 void uiButtonSetText(uiButton *b, const(char) *text);
149 void uiButtonOnClicked(uiButton *b, void function(uiButton *b, void *data) f, void *data);
150 uiButton *uiNewButton(const char *text);
151 
152 struct uiBox;
153 void uiBoxAppend(uiBox *b, uiControl *child, int stretchy);
154 void uiBoxDelete(uiBox *b, int index);
155 int uiBoxPadded(uiBox *b);
156 void uiBoxSetPadded(uiBox *b, int padded);
157 uiBox *uiNewHorizontalBox();
158 uiBox *uiNewVerticalBox();
159 
160 struct uiCheckbox;
161 char *uiCheckboxText(uiCheckbox *c);
162 void uiCheckboxSetText(uiCheckbox *c, const(char) *text);
163 void uiCheckboxOnToggled(uiCheckbox *c, void function(uiCheckbox *c, void *data) f, void *data);
164 int uiCheckboxChecked(uiCheckbox *c);
165 void uiCheckboxSetChecked(uiCheckbox *c, int checked);
166 uiCheckbox *uiNewCheckbox(const(char) *text);
167 
168 struct uiEntry;
169 char *uiEntryText(uiEntry *e);
170 void uiEntrySetText(uiEntry *e, const(char) *text);
171 void uiEntryOnChanged(uiEntry *e, void function(uiEntry *e, void *data) f, void *data);
172 int uiEntryReadOnly(uiEntry *e);
173 void uiEntrySetReadOnly(uiEntry *e, int readonly);
174 uiEntry *uiNewEntry();
175 uiEntry *uiNewPasswordEntry();
176 uiEntry *uiNewSearchEntry();
177 
178 struct uiLabel;
179 char *uiLabelText(uiLabel *l);
180 void uiLabelSetText(uiLabel *l, const(char) *text);
181 uiLabel *uiNewLabel(const(char) *text);
182 
183 struct uiTab;
184 void uiTabAppend(uiTab *t, const(char) *name, uiControl *c);
185 void uiTabInsertAt(uiTab *t, const(char) *name, int before, uiControl *c);
186 void uiTabDelete(uiTab *t, int index);
187 int uiTabNumPages(uiTab *t);
188 int uiTabMargined(uiTab *t, int page);
189 void uiTabSetMargined(uiTab *t, int page, int margined);
190 uiTab *uiNewTab();
191 
192 struct uiGroup;
193 char *uiGroupTitle(uiGroup *g);
194 void uiGroupSetTitle(uiGroup *g, const(char) *title);
195 void uiGroupSetChild(uiGroup *g, uiControl *c);
196 int uiGroupMargined(uiGroup *g);
197 void uiGroupSetMargined(uiGroup *g, int margined);
198 uiGroup *uiNewGroup(const(char) *title);
199 
200 struct uiSpinbox;
201 int uiSpinboxValue(uiSpinbox *s);
202 void uiSpinboxSetValue(uiSpinbox *s, int value);
203 void uiSpinboxOnChanged(uiSpinbox *s, void function(uiSpinbox *s, void *data) f, void *data);
204 uiSpinbox *uiNewSpinbox(int min, int max);
205 
206 struct uiSlider;
207 int uiSliderValue(uiSlider *s);
208 void uiSliderSetValue(uiSlider *s, int value);
209 void uiSliderOnChanged(uiSlider *s, void function(uiSlider *s, void *data) f, void *data);
210 uiSlider *uiNewSlider(int min, int max);
211 
212 struct uiProgressBar;
213 int uiProgressBarValue(uiProgressBar *p);
214 void uiProgressBarSetValue(uiProgressBar *p, int n);
215 uiProgressBar *uiNewProgressBar();
216 
217 struct uiSeparator;
218 uiSeparator *uiNewHorizontalSeparator();
219 uiSeparator *uiNewVerticalSeparator();
220 
221 struct uiCombobox;
222 void uiComboboxAppend(uiCombobox *c, const(char) *text);
223 int uiComboboxSelected(uiCombobox *c);
224 void uiComboboxSetSelected(uiCombobox *c, int n);
225 void uiComboboxOnSelected(uiCombobox *c, void function(uiCombobox *c, void *data) f, void *data);
226 uiCombobox *uiNewCombobox();
227 
228 struct uiEditableCombobox;
229 void uiEditableComboboxAppend(uiEditableCombobox *c, const(char) *text);
230 char *uiEditableComboboxText(uiEditableCombobox *c);
231 void uiEditableComboboxSetText(uiEditableCombobox *c, const(char) *text);
232 // TODO what do we call a function that sets the currently selected item and fills the text field with it? editable comboboxes have no consistent concept of selected item
233 void uiEditableComboboxOnChanged(uiEditableCombobox *c, void function(uiEditableCombobox *c, void *data) f, void *data);
234 uiEditableCombobox *uiNewEditableCombobox();
235 
236 struct uiRadioButtons;
237 void uiRadioButtonsAppend(uiRadioButtons *r, const(char) *text);
238 int uiRadioButtonsSelected(uiRadioButtons *r);
239 void uiRadioButtonsSetSelected(uiRadioButtons *r, int n);
240 void uiRadioButtonsOnSelected(uiRadioButtons *r, void function(uiRadioButtons *, void *) f, void *data);
241 uiRadioButtons *uiNewRadioButtons();
242 
243 struct uiDateTimePicker;
244 uiDateTimePicker *uiNewDateTimePicker();
245 uiDateTimePicker *uiNewDatePicker();
246 uiDateTimePicker *uiNewTimePicker();
247 
248 // TODO provide a facility for entering tab stops?
249 struct uiMultilineEntry;
250 char *uiMultilineEntryText(uiMultilineEntry *e);
251 void uiMultilineEntrySetText(uiMultilineEntry *e, const(char) *text);
252 void uiMultilineEntryAppend(uiMultilineEntry *e, const(char) *text);
253 void uiMultilineEntryOnChanged(uiMultilineEntry *e, void function(uiMultilineEntry *e, void *data) f, void *data);
254 int uiMultilineEntryReadOnly(uiMultilineEntry *e);
255 void uiMultilineEntrySetReadOnly(uiMultilineEntry *e, int readonly);
256 uiMultilineEntry *uiNewMultilineEntry();
257 uiMultilineEntry *uiNewNonWrappingMultilineEntry();
258 
259 struct uiMenuItem;
260 void uiMenuItemEnable(uiMenuItem *m);
261 void uiMenuItemDisable(uiMenuItem *m);
262 void uiMenuItemOnClicked(uiMenuItem *m, void function(uiMenuItem *sender, uiWindow *window, void *data) f, void *data);
263 int uiMenuItemChecked(uiMenuItem *m);
264 void uiMenuItemSetChecked(uiMenuItem *m, int checked);
265 
266 struct uiMenu;
267 uiMenuItem *uiMenuAppendItem(uiMenu *m, const(char) *name);
268 uiMenuItem *uiMenuAppendCheckItem(uiMenu *m, const(char) *name);
269 uiMenuItem *uiMenuAppendQuitItem(uiMenu *m);
270 uiMenuItem *uiMenuAppendPreferencesItem(uiMenu *m);
271 uiMenuItem *uiMenuAppendAboutItem(uiMenu *m);
272 void uiMenuAppendSeparator(uiMenu *m);
273 uiMenu *uiNewMenu(const(char) *name);
274 
275 char *uiOpenFile(uiWindow *parent);
276 char *uiSaveFile(uiWindow *parent);
277 void uiMsgBox(uiWindow *parent, const(char) *title, const(char) *description);
278 void uiMsgBoxError(uiWindow *parent, const(char) *title, const(char) *description);
279 
280 struct uiArea;
281 //struct uiAreaHandler;
282 //struct uiAreaDrawParams;
283 //struct uiAreaMouseEvent;
284 //struct uiAreaKeyEvent;
285 
286 struct uiDrawContext;
287 
288 struct uiAreaHandler {
289     void function(uiAreaHandler *, uiArea *, uiAreaDrawParams *) Draw;
290     // TODO document that resizes cause a full redraw for non-scrolling areas; implementation-defined for scrolling areas
291     void function(uiAreaHandler *, uiArea *, uiAreaMouseEvent *) MouseEvent;
292     // TODO document that on first show if the mouse is already in the uiArea then one gets sent with left=0
293     // TODO what about when the area is hidden and then shown again?
294     void function(uiAreaHandler *, uiArea *, int left) MouseCrossed;
295     void function(uiAreaHandler *, uiArea *) DragBroken;
296     int function(uiAreaHandler *, uiArea *, uiAreaKeyEvent *) KeyEvent;
297 }
298 
299 // TODO give a better name
300 // TODO document the types of width and height
301 void uiAreaSetSize(uiArea *a, int width, int height);
302 // TODO uiAreaQueueRedraw()
303 void uiAreaQueueRedrawAll(uiArea *a);
304 void uiAreaScrollTo(uiArea *a, double x, double y, double width, double height);
305 uiArea *uiNewArea(uiAreaHandler *ah);
306 uiArea *uiNewScrollingArea(uiAreaHandler *ah, int width, int height);
307 
308 struct uiAreaDrawParams {
309     uiDrawContext *Context;
310 
311     // TODO document that this is only defined for nonscrolling areas
312     double AreaWidth;
313     double AreaHeight;
314 
315     double ClipX;
316     double ClipY;
317     double ClipWidth;
318     double ClipHeight;
319 }
320 
321 struct uiDrawPath;
322 //struct uiDrawBrush;
323 //struct uiDrawStrokeParams;
324 //struct uiDrawMatrix;
325 
326 //struct uiDrawBrushGradientStop;
327 
328 /+
329  + enums:
330  + uiDrawBrushType
331  + uiDrawLineCap
332  + uiDrawLineJoin
333  +
334  + defines:
335  + uiDrawDefaultMiterLimit
336  +
337  + enums:
338  + uiDrawFillMode
339  +
340  +/
341 
342 struct uiDrawMatrix {
343     double M11;
344     double M12;
345     double M21;
346     double M22;
347     double M31;
348     double M32;
349 }
350 
351 struct uiDrawBrush {
352     BrushType Type;
353 
354     // solid brushes
355     double R;
356     double G;
357     double B;
358     double A;
359 
360     // gradient brushes
361     double X0;      // linear: start X, radial: start X
362     double Y0;      // linear: start Y, radial: start Y
363     double X1;      // linear: end X, radial: outer circle center X
364     double Y1;      // linear: end Y, radial: outer circle center Y
365     double OuterRadius;     // radial gradients only
366     uiDrawBrushGradientStop *Stops;
367     size_t NumStops;
368     // TODO extend mode
369     // cairo: none, repeat, reflect, pad; no individual control
370     // Direct2D: repeat, reflect, pad; no individual control
371     // Core Graphics: none, pad; before and after individually
372     // TODO cairo documentation is inconsistent about pad
373 
374     // TODO images
375 
376     // TODO transforms
377 }
378 
379 struct uiDrawBrushGradientStop {
380     double Pos;
381     double R;
382     double G;
383     double B;
384     double A;
385 }
386 
387 struct uiDrawStrokeParams {
388     LineCap Cap;
389     LineJoin Join;
390     // TODO what if this is 0? on windows there will be a crash with dashing
391     double Thickness;
392     double MiterLimit;
393     double *Dashes;
394     // TOOD what if this is 1 on Direct2D?
395     // TODO what if a dash is 0 on Cairo or Quartz?
396     size_t NumDashes;
397     double DashPhase;
398 }
399 
400 uiDrawPath *uiDrawNewPath(FillMode fillMode);
401 void uiDrawFreePath(uiDrawPath *p);
402 
403 void uiDrawPathNewFigure(uiDrawPath *p, double x, double y);
404 void uiDrawPathNewFigureWithArc(uiDrawPath *p, double xCenter, double yCenter, double radius, double startAngle, double sweep, int negative);
405 void uiDrawPathLineTo(uiDrawPath *p, double x, double y);
406 // notes: angles are both relative to 0 and go counterclockwise
407 // TODO is the initial line segment on cairo and OS X a proper join?
408 // TODO what if sweep < 0?
409 void uiDrawPathArcTo(uiDrawPath *p, double xCenter, double yCenter, double radius, double startAngle, double sweep, int negative);
410 void uiDrawPathBezierTo(uiDrawPath *p, double c1x, double c1y, double c2x, double c2y, double endX, double endY);
411 // TODO quadratic bezier
412 void uiDrawPathCloseFigure(uiDrawPath *p);
413 
414 // TODO effect of these when a figure is already started
415 void uiDrawPathAddRectangle(uiDrawPath *p, double x, double y, double width, double height);
416 
417 void uiDrawPathEnd(uiDrawPath *p);
418 
419 void uiDrawStroke(uiDrawContext *c, uiDrawPath *path, uiDrawBrush *b, uiDrawStrokeParams *p);
420 void uiDrawFill(uiDrawContext *c, uiDrawPath *path, uiDrawBrush *b);
421 
422 // TODO primitives:
423 // - rounded rectangles
424 // - elliptical arcs
425 // - quadratic bezier curves
426 
427 void uiDrawMatrixSetIdentity(uiDrawMatrix *m);
428 void uiDrawMatrixTranslate(uiDrawMatrix *m, double x, double y);
429 void uiDrawMatrixScale(uiDrawMatrix *m, double xCenter, double yCenter, double x, double y);
430 void uiDrawMatrixRotate(uiDrawMatrix *m, double x, double y, double amount);
431 void uiDrawMatrixSkew(uiDrawMatrix *m, double x, double y, double xamount, double yamount);
432 void uiDrawMatrixMultiply(uiDrawMatrix *dest, uiDrawMatrix *src);
433 int uiDrawMatrixInvertible(uiDrawMatrix *m);
434 int uiDrawMatrixInvert(uiDrawMatrix *m);
435 void uiDrawMatrixTransformPoint(uiDrawMatrix *m, double *x, double *y);
436 void uiDrawMatrixTransformSize(uiDrawMatrix *m, double *x, double *y);
437 
438 void uiDrawTransform(uiDrawContext *c, uiDrawMatrix *m);
439 
440 // TODO add a uiDrawPathStrokeToFill() or something like that
441 void uiDrawClip(uiDrawContext *c, uiDrawPath *path);
442 
443 void uiDrawSave(uiDrawContext *c);
444 void uiDrawRestore(uiDrawContext *c);
445 
446 // TODO manage the use of Text, Font, and TextFont, and of the uiDrawText prefix in general
447 
448 ///// TODO reconsider this
449 struct uiDrawFontFamilies;
450 
451 uiDrawFontFamilies *uiDrawListFontFamilies();
452 int uiDrawFontFamiliesNumFamilies(uiDrawFontFamilies *ff);
453 char *uiDrawFontFamiliesFamily(uiDrawFontFamilies *ff, int n);
454 void uiDrawFreeFontFamilies(uiDrawFontFamilies *ff);
455 ///// END TODO
456 
457 struct uiDrawTextLayout;
458 struct uiDrawTextFont;
459 //struct uiDrawTextFontDescriptor;
460 //struct uiDrawTextFontMetrics;
461 
462 /+
463  + enums:
464  + uiDrawTextWeight
465  + uiDrawTextItalic
466  + uiDrawTextStretch
467  +
468  +/
469 
470 struct uiDrawTextFontDescriptor {
471     const(char) *Family;
472     double Size;
473     TextWeight Weight;
474     TextItalic Italic;
475     TextStretch Stretch;
476 }
477 
478 struct uiDrawTextFontMetrics {
479     double Ascent;
480     double Descent;
481     double Leading;
482     // TODO do these two mean the same across all platforms?
483     double UnderlinePos;
484     double UnderlineThickness;
485 }
486 
487 uiDrawTextFont *uiDrawLoadClosestFont(const(uiDrawTextFontDescriptor) *desc);
488 void uiDrawFreeTextFont(uiDrawTextFont *font);
489 uintptr_t uiDrawTextFontHandle(uiDrawTextFont *font);
490 void uiDrawTextFontDescribe(uiDrawTextFont *font, uiDrawTextFontDescriptor *desc);
491 // TODO make copy with given attributes methods?
492 // TODO yuck this name
493 void uiDrawTextFontGetMetrics(uiDrawTextFont *font, uiDrawTextFontMetrics *metrics);
494 
495 // TODO initial line spacing? and what about leading?
496 uiDrawTextLayout *uiDrawNewTextLayout(const(char) *text, uiDrawTextFont *defaultFont, double width);
497 void uiDrawFreeTextLayout(uiDrawTextLayout *layout);
498 // TODO get width
499 void uiDrawTextLayoutSetWidth(uiDrawTextLayout *layout, double width);
500 void uiDrawTextLayoutExtents(uiDrawTextLayout *layout, double *width, double *height);
501 
502 // and the attributes that you can set on a text layout
503 void uiDrawTextLayoutSetColor(uiDrawTextLayout *layout, int startChar, int endChar, double r, double g, double b, double a);
504 
505 void uiDrawText(uiDrawContext *c, double x, double y, uiDrawTextLayout *layout);
506 
507 /+
508  + enums:
509  + uiModifiers
510  +
511  +/
512 
513 // TODO document drag captures
514 struct uiAreaMouseEvent {
515     // TODO document what these mean for scrolling areas
516     double X;
517     double Y;
518 
519     // TODO see draw above
520     double AreaWidth;
521     double AreaHeight;
522 
523     int Down;
524     int Up;
525 
526     int Count;
527 
528     ModifiersT Modifiers;
529 
530     uint64_t Held1To64;
531 }
532 
533 /+
534  + enums:
535  + uiExtKey
536  +
537  +/
538 
539 struct uiAreaKeyEvent {
540     char Key;
541     ExtKeyT ExtKey;
542     ModifiersT Modifier;
543 
544     ModifiersT Modifiers;
545 
546     int Up;
547 }
548 
549 struct uiFontButton;
550 // TODO document this returns a new font
551 uiDrawTextFont *uiFontButtonFont(uiFontButton *b);
552 // TOOD SetFont, mechanics
553 void uiFontButtonOnChanged(uiFontButton *b, void function(uiFontButton *, void *) f, void *data);
554 uiFontButton *uiNewFontButton();
555 
556 struct uiColorButton;
557 void uiColorButtonColor(uiColorButton *b, double *r, double *g, double *bl, double *a);
558 void uiColorButtonSetColor(uiColorButton *b, double r, double g, double bl, double a);
559 void uiColorButtonOnChanged(uiColorButton *b, void function(uiColorButton *, void *) f, void *data);
560 uiColorButton *uiNewColorButton();
561 
562 struct uiForm;
563 void uiFormAppend(uiForm *f, const(char) *label, uiControl *c, int stretchy);
564 void uiFormDelete(uiForm *f, int index);
565 int uiFormPadded(uiForm *f);
566 void uiFormSetPadded(uiForm *f, int padded);
567 uiForm *uiNewForm();
568 
569 /+
570  + enums:
571  + uiAlign
572  + uiAt
573  +
574  +/
575 
576 struct uiGrid;
577 void uiGridAppend(uiGrid *g, uiControl *c, int left, int top, int xspan, int yspan, int hexpand, Align halign, int vexpand, Align valign);
578 void uiGridInsertAt(uiGrid *g, uiControl *c, uiControl *existing, At at, int xspan, int yspan, int hexpand, Align halign, int vexpand, Align valign);
579 int uiGridPadded(uiGrid *g);
580 void uiGridSetPadded(uiGrid *g, int padded);
581 uiGrid *uiNewGrid();