forked from flyover/imgui-js
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbind-imgui.cpp
More file actions
2827 lines (2664 loc) · 224 KB
/
bind-imgui.cpp
File metadata and controls
2827 lines (2664 loc) · 224 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#include "imgui.h"
#ifndef __FLT_MAX__
#define __FLT_MAX__ 3.40282346638528859812e+38F
#endif
#if defined(IMGUI_DISABLE_DEMO_WINDOWS)
// warning: unresolved symbol: _ZN5ImGui17ShowStyleSelectorEPKc
bool ImGui::ShowStyleSelector(const char*) { return false; }
// warning: unresolved symbol: _ZN5ImGui16ShowFontSelectorEPKc
void ImGui::ShowFontSelector(const char*) {}
#endif
#include <emscripten/bind.h>
#define FUNCTION(RET, ARGS, CODE...) \
emscripten::optional_override([] ARGS -> RET { CODE })
#define CLASS_MEMBER(CLASS, MEMBER) \
.property(#MEMBER, &CLASS::MEMBER)
#define CLASS_MEMBER_GET(CLASS, MEMBER, GET) \
.property(#MEMBER, FUNCTION(emscripten::val, (const CLASS& that), GET))
#define CLASS_MEMBER_SET(CLASS, MEMBER, SET) \
.property(#MEMBER, NULL, FUNCTION(void, (CLASS& that, emscripten::val value), SET))
#define CLASS_MEMBER_GET_SET(CLASS, MEMBER, GET, SET) \
.property(#MEMBER, \
FUNCTION(emscripten::val, (const CLASS& that), GET), \
FUNCTION(void, (CLASS& that, emscripten::val value), SET))
#define CLASS_MEMBER_GET_RAW_POINTER(CLASS, MEMBER) \
.property(#MEMBER, FUNCTION(emscripten::val, (const CLASS& that), { \
auto p = that.MEMBER; return p == NULL ? emscripten::val::null() : emscripten::val(p); \
}))
#define CLASS_MEMBER_GET_SET_RAW_POINTER(CLASS, MEMBER) \
.property(#MEMBER, FUNCTION(emscripten::val, (const CLASS& that), { \
auto p = that.MEMBER; return p == NULL ? emscripten::val::null() : emscripten::val(p); \
}), FUNCTION(void, (CLASS& that, emscripten::val value), { \
that.MEMBER = value.isNull() ? NULL : value.as<decltype(that.MEMBER)>(emscripten::allow_raw_pointers()); \
}))
#define CLASS_MEMBER_GET_RAW_REFERENCE(CLASS, MEMBER) \
.property(#MEMBER, FUNCTION(emscripten::val, (const CLASS& that), { \
auto p = &that.MEMBER; return emscripten::val(p); \
}))
#define CLASS_METHOD(CLASS, METHOD) \
.function(#METHOD, &CLASS::METHOD)
#include <malloc.h>
emscripten::val get_mallinfo() {
const auto& i = mallinfo();
emscripten::val rv(emscripten::val::object());
rv.set("arena", emscripten::val(i.arena));
rv.set("ordblks", emscripten::val(i.ordblks));
rv.set("smblks", emscripten::val(i.smblks));
rv.set("hblks", emscripten::val(i.hblks));
rv.set("hblkhd", emscripten::val(i.hblkhd));
rv.set("usmblks", emscripten::val(i.usmblks));
rv.set("fsmblks", emscripten::val(i.fsmblks));
rv.set("uordblks", emscripten::val(i.uordblks));
rv.set("fordblks", emscripten::val(i.fordblks));
rv.set("keepcost", emscripten::val(i.keepcost));
return rv;
}
EMSCRIPTEN_BINDINGS(mallinfo) {
emscripten::function("mallinfo", &get_mallinfo);
}
#define TODO() printf("TODO: %s\n", __PRETTY_FUNCTION__)
class WrapImGuiContext {
private:
static WrapImGuiContext* _current_wrap;
public:
static WrapImGuiContext* CreateContext(ImFontAtlas* shared_font_atlas = NULL) {
return new WrapImGuiContext(shared_font_atlas);
}
static void DestroyContext(WrapImGuiContext* wrap) {
delete wrap;
}
static void SetCurrentContext(WrapImGuiContext* wrap) {
_current_wrap = wrap;
ImGui::SetCurrentContext(wrap == NULL ? NULL : wrap->ctx);
}
static WrapImGuiContext* GetCurrentContext() {
return _current_wrap;
}
private:
static const char* _GetClipboardText(void* user_data) {
WrapImGuiContext* wrap_ctx = WrapImGuiContext::GetCurrentContext();
if (!wrap_ctx->_ImGuiIO_GetClipboardTextFn.isNull()) {
wrap_ctx->_ImGuiIO_ClipboardText = wrap_ctx->_ImGuiIO_GetClipboardTextFn(wrap_ctx->_ImGuiIO_ClipboardUserData).as<std::string>();
}
return wrap_ctx->_ImGuiIO_ClipboardText.c_str();
}
static void _SetClipboardText(void* user_data, const char* text) {
WrapImGuiContext* wrap_ctx = WrapImGuiContext::GetCurrentContext();
wrap_ctx->_ImGuiIO_ClipboardText = text;
if (!wrap_ctx->_ImGuiIO_SetClipboardTextFn.isNull()) {
wrap_ctx->_ImGuiIO_SetClipboardTextFn(wrap_ctx->_ImGuiIO_ClipboardUserData, wrap_ctx->_ImGuiIO_ClipboardText);
}
}
private:
ImGuiContext* ctx;
public:
std::string _ImGuiIO_IniFilename = "";
std::string _ImGuiIO_LogFilename = "";
emscripten::val _ImGuiIO_UserData = emscripten::val::null();
std::string _ImGuiIO_ClipboardText = "";
emscripten::val _ImGuiIO_GetClipboardTextFn = emscripten::val::null();
emscripten::val _ImGuiIO_SetClipboardTextFn = emscripten::val::null();
emscripten::val _ImGuiIO_ClipboardUserData = emscripten::val::null();
emscripten::val _ImGui_SetNextWindowSizeConstraints_custom_callback = emscripten::val::undefined();
emscripten::val _ImGui_PlotLines_values_getter = emscripten::val::undefined();
emscripten::val _ImGui_PlotLines_data = emscripten::val::undefined();
emscripten::val _ImGui_PlotHistogram_values_getter = emscripten::val::undefined();
emscripten::val _ImGui_PlotHistogram_data = emscripten::val::undefined();
emscripten::val _ImGui_Combo_items_getter = emscripten::val::undefined();
emscripten::val _ImGui_Combo_data = emscripten::val::undefined();
int _ImGui_Combo_items_count = 0;
std::string _ImGui_Combo_text = "";
emscripten::val _ImGui_InputText_callback = emscripten::val::undefined();
emscripten::val _ImGui_InputTextMultiline_callback = emscripten::val::undefined();
emscripten::val _ImGui_ListBox_A_items = emscripten::val::undefined();
int _ImGui_ListBox_A_items_count = 0;
std::string _ImGui_ListBox_A_text = "";
emscripten::val _ImGui_ListBox_B_items_getter = emscripten::val::undefined();
emscripten::val _ImGui_ListBox_B_data = emscripten::val::undefined();
int _ImGui_ListBox_B_items_count = 0;
std::string _ImGui_ListBox_B_text = "";
emscripten::val _ImGui_DragDropPayload_data = emscripten::val::object();
emscripten::val _ImGui_SetAllocatorFunctions_alloc_func = emscripten::val::undefined();
emscripten::val _ImGui_SetAllocatorFunctions_free_func = emscripten::val::undefined();
emscripten::val _ImGui_SetAllocatorFunctions_user_data = emscripten::val::undefined();
public:
WrapImGuiContext(ImFontAtlas* shared_font_atlas = NULL): ctx(ImGui::CreateContext()) {
ImGuiContext* prev_ctx = ImGui::GetCurrentContext();
ImGui::SetCurrentContext(ctx);
ImGuiIO& io = ImGui::GetIO();
io.IniFilename = NULL;
io.LogFilename = NULL;
io.GetClipboardTextFn = WrapImGuiContext::_GetClipboardText;
io.SetClipboardTextFn = WrapImGuiContext::_SetClipboardText;
io.ClipboardUserData = NULL;
ImGui::SetCurrentContext(prev_ctx);
}
~WrapImGuiContext() {
ImGuiContext* prev_ctx = ImGui::GetCurrentContext();
ImGui::SetCurrentContext(ctx);
ImGuiIO& io = ImGui::GetIO();
io.IniFilename = NULL;
io.LogFilename = NULL;
io.GetClipboardTextFn = NULL;
io.SetClipboardTextFn = NULL;
io.ClipboardUserData = NULL;
ImGui::SetCurrentContext(prev_ctx);
ImGui::DestroyContext(ctx);
ctx = NULL;
}
};
WrapImGuiContext* WrapImGuiContext::_current_wrap = NULL;
EMSCRIPTEN_BINDINGS(WrapImGuiContext) {
emscripten::class_<WrapImGuiContext>("WrapImGuiContext")
;
}
template <typename T>
T import_value(const emscripten::val& value) {
return value.as<T>();
}
template <typename T>
emscripten::val export_value(const T& value) {
return emscripten::val(value);
}
template <>
float import_value(const emscripten::val& value) {
// return __import_float(value);
const double _value = value.as<double>();
if (double(+FLT_MAX) <= _value) return +FLT_MAX;
if (_value <= double(-FLT_MAX)) return -FLT_MAX;
return float(_value);
}
template <typename T>
class import_maybe_null_value {
protected:
T _value;
const emscripten::val& _import;
public:
import_maybe_null_value(const emscripten::val& _import) : _import(_import) {
if (!_import.isNull()) { _import_value(); }
}
virtual void _import_value() {
_value = import_value<T>(_import);
}
operator T*() { return _import.isNull() ? NULL : &_value; }
operator const T*() const { return _import.isNull() ? NULL : &_value; }
};
class import_maybe_null_string : public import_maybe_null_value<std::string> {
public:
import_maybe_null_string(const emscripten::val& _import) : import_maybe_null_value(_import) {}
operator const char*() const { return _import.isNull() ? NULL : _value.c_str(); }
};
emscripten::val export_maybe_null_string(const char* value) {
return value == NULL ? emscripten::val::null() : emscripten::val(value);
}
template <typename T, size_t N = 1>
class access_value {
protected:
T _value[N];
emscripten::val& _access;
public:
access_value(emscripten::val& _access) : _access(_access) {
_import_value();
}
virtual ~access_value() {
_export_value();
}
virtual void _import_value() {
for (size_t i = 0; i < N; ++i) {
_value[i] = import_value<T>(_access[i]);
}
}
virtual void _export_value() {
for (size_t i = 0; i < N; ++i) {
_access.set(i, export_value<T>(_value[i]));
}
}
operator T&() { return _value[0]; }
operator const T&() const { return _value[0]; }
operator T*() { return &_value[0]; }
operator const T*() const { return &_value[0]; }
};
template <typename T, size_t N = 1>
class access_maybe_null_value {
protected:
T _value[N];
emscripten::val& _access;
public:
access_maybe_null_value(emscripten::val& _access) : _access(_access) {
if (!_access.isNull()) { _import_value(); }
}
virtual ~access_maybe_null_value() {
if (!_access.isNull()) { _export_value(); }
}
virtual void _import_value() {
for (size_t i = 0; i < N; ++i) {
_value[i] = import_value<T>(_access[i]);
}
}
virtual void _export_value() {
for (size_t i = 0; i < N; ++i) {
_access.set(i, export_value<T>(_value[i]));
}
}
operator T*() { return _access.isNull() ? NULL : &_value[0]; }
operator const T*() const { return _access.isNull() ? NULL : &_value[0]; }
};
template <typename T>
class access_typed_array {
protected:
std::vector<T> _value;
emscripten::val& _access;
public:
access_typed_array(emscripten::val& access): _access(access) {
_value.resize(_access["length"].template as<size_t>());
emscripten::val(emscripten::typed_memory_view<T>(_value.size(), _value.data())).call<void>("set", _access);
}
~access_typed_array() {
_access.call<void>("set", emscripten::typed_memory_view<T>(_value.size(), _value.data()));
}
T* data() { return _value.data(); }
const T* data() const { return _value.data(); }
size_t size() { return _value.size(); }
operator std::vector<T>&() { return _value; }
operator const std::vector<T>&() const { return _value; }
};
ImVec2& import_ImVec2(const emscripten::val& value, ImVec2& out) {
out.x = import_value<float>(value["x"]);
out.y = import_value<float>(value["y"]);
return out;
}
ImVec2 import_ImVec2(const emscripten::val& value) {
ImVec2 out; import_ImVec2(value, out); return out;
}
emscripten::val export_ImVec2(const ImVec2& value, emscripten::val out) {
out.set("x", export_value<float>(value.x));
out.set("y", export_value<float>(value.y));
return out;
}
emscripten::val export_ImVec2(const ImVec2& value) {
return export_ImVec2(value, emscripten::val::object());
}
template <>
ImVec2 import_value(const emscripten::val& value) {
return import_ImVec2(value);
}
emscripten::val ImVec2_Set(emscripten::val that, emscripten::val x, emscripten::val y) {
that.set("x", x);
that.set("y", y);
return that;
}
emscripten::val ImVec2_Copy(emscripten::val that, emscripten::val other) {
that.set("x", other["x"]);
that.set("y", other["y"]);
return that;
}
bool ImVec2_Equals(const emscripten::val that, emscripten::val other) {
if (!that["x"].strictlyEquals(other["x"])) { return false; }
if (!that["y"].strictlyEquals(other["y"])) { return false; }
return true;
}
EMSCRIPTEN_BINDINGS(ImVec2) {
emscripten::class_<ImVec2>("ImVec2")
// no constructors for EmscriptenClassReference
// .constructor()
// .constructor<float, float>()
CLASS_MEMBER(ImVec2, x)
CLASS_MEMBER(ImVec2, y)
.function("Set", &ImVec2_Set)
.function("Copy", &ImVec2_Copy)
.function("Equals", &ImVec2_Equals)
;
}
ImVec4& import_ImVec4(const emscripten::val& value, ImVec4& out) {
out.x = import_value<float>(value["x"]);
out.y = import_value<float>(value["y"]);
out.z = import_value<float>(value["z"]);
out.w = import_value<float>(value["w"]);
return out;
}
ImVec4 import_ImVec4(const emscripten::val& value) {
ImVec4 out; import_ImVec4(value, out); return out;
}
emscripten::val export_ImVec4(const ImVec4& value, emscripten::val out) {
out.set("x", export_value<float>(value.x));
out.set("y", export_value<float>(value.y));
out.set("z", export_value<float>(value.z));
out.set("w", export_value<float>(value.w));
return out;
}
emscripten::val export_ImVec4(const ImVec4& value) {
return export_ImVec4(value, emscripten::val::object());
}
template <>
ImVec4 import_value(const emscripten::val& value) {
return import_ImVec4(value);
}
emscripten::val ImVec4_Set(emscripten::val that, const emscripten::val x, const emscripten::val y, const emscripten::val z, const emscripten::val w) {
that.set("x", x);
that.set("y", y);
that.set("z", z);
that.set("w", w);
return that;
}
emscripten::val ImVec4_Copy(emscripten::val that, emscripten::val other) {
that.set("x", other["x"]);
that.set("y", other["y"]);
that.set("z", other["z"]);
that.set("w", other["w"]);
return that;
}
bool ImVec4_Equals(const emscripten::val that, emscripten::val other) {
if (!that["x"].strictlyEquals(other["x"])) { return false; }
if (!that["y"].strictlyEquals(other["y"])) { return false; }
if (!that["z"].strictlyEquals(other["z"])) { return false; }
if (!that["w"].strictlyEquals(other["w"])) { return false; }
return true;
}
EMSCRIPTEN_BINDINGS(ImVec4) {
emscripten::class_<ImVec4>("ImVec4")
// no constructors for EmscriptenClassReference
// .constructor()
// .constructor<float, float, float, float>()
CLASS_MEMBER(ImVec4, x)
CLASS_MEMBER(ImVec4, y)
CLASS_MEMBER(ImVec4, z)
CLASS_MEMBER(ImVec4, w)
.function("Set", &ImVec4_Set)
.function("Copy", &ImVec4_Copy)
.function("Equals", &ImVec4_Equals)
;
}
// Shared state of InputText(), passed to callback when a ImGuiInputTextFlags_Callback* flag is used and the corresponding callback is triggered.
// struct ImGuiInputTextCallbackData
EMSCRIPTEN_BINDINGS(ImGuiInputTextCallbackData) {
emscripten::class_<ImGuiInputTextCallbackData>("ImGuiInputTextCallbackData")
// ImGuiInputTextFlags EventFlag; // One of ImGuiInputTextFlags_Callback* // Read-only
CLASS_MEMBER(ImGuiInputTextCallbackData, EventFlag)
// ImGuiInputTextFlags Flags; // What user passed to InputText() // Read-only
CLASS_MEMBER(ImGuiInputTextCallbackData, Flags)
// void* UserData; // What user passed to InputText() // Read-only
// bool ReadOnly; // Read-only mode // Read-only
// CLASS_MEMBER(ImGuiInputTextCallbackData, ReadOnly)
// CharFilter event:
// ImWchar EventChar; // Character input // Read-write (replace character or set to zero)
CLASS_MEMBER(ImGuiInputTextCallbackData, EventChar)
// Completion,History,Always events:
// If you modify the buffer contents make sure you update 'BufTextLen' and set 'BufDirty' to true.
// ImGuiKey EventKey; // Key pressed (Up/Down/TAB) // Read-only
CLASS_MEMBER(ImGuiInputTextCallbackData, EventKey)
// char* Buf; // Current text buffer // Read-write (pointed data only, can't replace the actual pointer)
CLASS_MEMBER_GET_SET(ImGuiInputTextCallbackData, Buf,
{ return emscripten::val(std::string(that.Buf)); },
{ strncpy(that.Buf, value.as<std::string>().c_str(), that.BufSize - 1); }
)
// int BufTextLen; // Current text length in bytes // Read-write
CLASS_MEMBER(ImGuiInputTextCallbackData, BufTextLen)
// int BufSize; // Maximum text length in bytes // Read-only
CLASS_MEMBER(ImGuiInputTextCallbackData, BufSize)
// bool BufDirty; // Set if you modify Buf/BufTextLen!! // Write
CLASS_MEMBER(ImGuiInputTextCallbackData, BufDirty)
// int CursorPos; // // Read-write
CLASS_MEMBER(ImGuiInputTextCallbackData, CursorPos)
// int SelectionStart; // // Read-write (== to SelectionEnd when no selection)
CLASS_MEMBER(ImGuiInputTextCallbackData, SelectionStart)
// int SelectionEnd; // // Read-write
CLASS_MEMBER(ImGuiInputTextCallbackData, SelectionEnd)
// NB: Helper functions for text manipulation. Calling those function loses selection.
// IMGUI_API void DeleteChars(int pos, int bytes_count);
CLASS_METHOD(ImGuiInputTextCallbackData, DeleteChars)
// IMGUI_API void InsertChars(int pos, const char* text, const char* text_end = NULL);
.function("InsertChars", FUNCTION(void, (ImGuiInputTextCallbackData& that, int pos, std::string text), {
that.InsertChars(pos, text.c_str(), NULL);
}))
// bool HasSelection() const { return SelectionStart != SelectionEnd; }
CLASS_METHOD(ImGuiInputTextCallbackData, HasSelection)
;
}
// Resizing callback data to apply custom constraint. As enabled by SetNextWindowSizeConstraints(). Callback is called during the next Begin().
// NB: For basic min/max size constraint on each axis you don't need to use the callback! The SetNextWindowSizeConstraints() parameters are enough.
// struct ImGuiSizeCallbackData
// {
// void* UserData; // Read-only. What user passed to SetNextWindowSizeConstraints()
// ImVec2 Pos; // Read-only. Window position, for reference.
// ImVec2 CurrentSize; // Read-only. Current window size.
// ImVec2 DesiredSize; // Read-write. Desired size, based on user's mouse position. Write to this field to restrain resizing.
// };
EMSCRIPTEN_BINDINGS(ImGuiSizeCallbackData) {
emscripten::class_<ImGuiSizeCallbackData>("ImGuiSizeCallbackData")
CLASS_MEMBER_GET_RAW_REFERENCE(ImGuiSizeCallbackData, Pos)
CLASS_MEMBER_GET_RAW_REFERENCE(ImGuiSizeCallbackData, CurrentSize)
CLASS_MEMBER_GET_RAW_REFERENCE(ImGuiSizeCallbackData, DesiredSize)
;
}
EMSCRIPTEN_BINDINGS(ImGuiListClipper) {
emscripten::class_<ImGuiListClipper>("ImGuiListClipper")
.constructor()
.constructor<int>()
.constructor<int, float>()
CLASS_MEMBER(ImGuiListClipper, StartPosY)
CLASS_MEMBER(ImGuiListClipper, ItemsHeight)
CLASS_MEMBER(ImGuiListClipper, ItemsCount)
CLASS_MEMBER(ImGuiListClipper, StepNo)
CLASS_MEMBER(ImGuiListClipper, DisplayStart)
CLASS_MEMBER(ImGuiListClipper, DisplayEnd)
CLASS_METHOD(ImGuiListClipper, Step)
CLASS_METHOD(ImGuiListClipper, Begin)
CLASS_METHOD(ImGuiListClipper, End)
;
}
EMSCRIPTEN_BINDINGS(ImDrawCmd) {
emscripten::class_<ImDrawCmd>("ImDrawCmd")
CLASS_MEMBER(ImDrawCmd, ElemCount)
CLASS_MEMBER_GET_RAW_REFERENCE(ImDrawCmd, ClipRect)
CLASS_MEMBER_GET(ImDrawCmd, TextureId, { return emscripten::val((int) that.TextureId); })
;
}
EMSCRIPTEN_BINDINGS(ImDrawList) {
emscripten::class_<ImDrawList>("ImDrawList")
.function("IterateDrawCmds", FUNCTION(void, (const ImDrawList* that, emscripten::val callback), {
unsigned int ElemStart = 0;
for (const ImDrawCmd* pcmd = that->CmdBuffer.begin(); pcmd != that->CmdBuffer.end(); pcmd++) {
callback(emscripten::val(pcmd), emscripten::val(ElemStart));
ElemStart += pcmd->ElemCount;
}
}), emscripten::allow_raw_pointers())
// This is what you have to render
// ImVector<ImDrawCmd> CmdBuffer; // Draw commands. Typically 1 command = 1 GPU draw call, unless the command is a callback.
// ImVector<ImDrawIdx> IdxBuffer; // Index buffer. Each command consume ImDrawCmd::ElemCount of those
CLASS_MEMBER_GET(ImDrawList, IdxBuffer, {
return emscripten::val(emscripten::typed_memory_view((size_t)(that.IdxBuffer.size() * sizeof(ImDrawIdx)), (char *) &that.IdxBuffer.front()));
})
CLASS_MEMBER_GET(ImDrawList, VtxBuffer, {
return emscripten::val(emscripten::typed_memory_view((size_t)(that.VtxBuffer.size() * sizeof(ImDrawVert)), (char *) &that.VtxBuffer.front()));
})
// ImDrawListFlags Flags; // Flags, you may poke into these to adjust anti-aliasing settings per-primitive.
CLASS_MEMBER(ImDrawList, Flags)
// [Internal, used while building lists]
// const ImDrawListSharedData* _Data; // Pointer to shared draw data (you can use ImGui::GetDrawListSharedData() to get the one from current ImGui context)
// const char* _OwnerName; // Pointer to owner window's name for debugging
// unsigned int _VtxCurrentIdx; // [Internal] == VtxBuffer.Size
// ImDrawVert* _VtxWritePtr; // [Internal] point within VtxBuffer.Data after each add command (to avoid using the ImVector<> operators too much)
// ImDrawIdx* _IdxWritePtr; // [Internal] point within IdxBuffer.Data after each add command (to avoid using the ImVector<> operators too much)
// ImVector<ImVec4> _ClipRectStack; // [Internal]
// ImVector<ImTextureID> _TextureIdStack; // [Internal]
// ImVector<ImVec2> _Path; // [Internal] current path building
// int _ChannelsCurrent; // [Internal] current channel number (0)
// int _ChannelsCount; // [Internal] number of active channels (1+)
// ImVector<ImDrawChannel> _Channels; // [Internal] draw channels for columns API (not resized down so _ChannelsCount may be smaller than _Channels.Size)
// ImDrawList(const ImDrawListSharedData* shared_data) { _Data = shared_data; _OwnerName = NULL; Clear(); }
// ~ImDrawList() { ClearFreeMemory(); }
// IMGUI_API void PushClipRect(ImVec2 clip_rect_min, ImVec2 clip_rect_max, bool intersect_with_current_clip_rect = false); // Render-level scissoring. This is passed down to your render function but not used for CPU-side coarse clipping. Prefer using higher-level ImGui::PushClipRect() to affect logic (hit-testing and widget culling)
.function("PushClipRect", FUNCTION(void, (ImDrawList& that, emscripten::val clip_rect_min, emscripten::val clip_rect_max, bool intersect_with_current_clip_rect), {
that.PushClipRect(import_ImVec2(clip_rect_min), import_ImVec2(clip_rect_max), intersect_with_current_clip_rect);
}))
// IMGUI_API void PushClipRectFullScreen();
CLASS_METHOD(ImDrawList, PushClipRectFullScreen)
// IMGUI_API void PopClipRect();
CLASS_METHOD(ImDrawList, PopClipRect)
// IMGUI_API void PushTextureID(const ImTextureID& texture_id);
.function("PushTextureID", FUNCTION(void, (ImDrawList& that, emscripten::val texture_id), {
that.PushTextureID((ImTextureID) texture_id.as<int>());
}))
// IMGUI_API void PopTextureID();
CLASS_METHOD(ImDrawList, PopTextureID)
// inline ImVec2 GetClipRectMin() const { const ImVec4& cr = _ClipRectStack.back(); return ImVec2(cr.x, cr.y); }
.function("GetClipRectMin", FUNCTION(emscripten::val, (ImDrawList& that, emscripten::val out), {
return export_ImVec2(that.GetClipRectMin(), out);
}))
// inline ImVec2 GetClipRectMax() const { const ImVec4& cr = _ClipRectStack.back(); return ImVec2(cr.z, cr.w); }
.function("GetClipRectMax", FUNCTION(emscripten::val, (ImDrawList& that, emscripten::val out), {
return export_ImVec2(that.GetClipRectMax(), out);
}))
// Primitives
// IMGUI_API void AddLine(const ImVec2& a, const ImVec2& b, ImU32 col, float thickness = 1.0f);
.function("AddLine", FUNCTION(void, (ImDrawList& that, emscripten::val a, emscripten::val b, ImU32 col, float thickness), {
that.AddLine(import_ImVec2(a), import_ImVec2(b), col, thickness);
}))
// IMGUI_API void AddRect(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners_flags = ImDrawCornerFlags_All, float thickness = 1.0f); // a: upper-left, b: lower-right, rounding_corners_flags: 4-bits corresponding to which corner to round
.function("AddRect", FUNCTION(void, (ImDrawList& that, emscripten::val a, emscripten::val b, ImU32 col, float rounding, int rounding_corners_flags, float thickness), {
that.AddRect(import_ImVec2(a), import_ImVec2(b), col, rounding, rounding_corners_flags, thickness);
}))
// IMGUI_API void AddRectFilled(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners_flags = ImDrawCornerFlags_All); // a: upper-left, b: lower-right
.function("AddRectFilled", FUNCTION(void, (ImDrawList& that, emscripten::val a, emscripten::val b, ImU32 col, float rounding, int rounding_corners_flags), {
that.AddRectFilled(import_ImVec2(a), import_ImVec2(b), col, rounding, rounding_corners_flags);
}))
// IMGUI_API void AddRectFilledMultiColor(const ImVec2& a, const ImVec2& b, ImU32 col_upr_left, ImU32 col_upr_right, ImU32 col_bot_right, ImU32 col_bot_left);
.function("AddRectFilledMultiColor", FUNCTION(void, (ImDrawList& that, emscripten::val a, emscripten::val b, ImU32 col_upr_left, ImU32 col_upr_right, ImU32 col_bot_right, ImU32 col_bot_left), {
that.AddRectFilledMultiColor(import_ImVec2(a), import_ImVec2(b), col_upr_left, col_upr_right, col_bot_right, col_bot_left);
}))
// IMGUI_API void AddQuad(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, ImU32 col, float thickness = 1.0f);
.function("AddQuad", FUNCTION(void, (ImDrawList& that, emscripten::val a, emscripten::val b, emscripten::val c, emscripten::val d, ImU32 col, float thickness), {
that.AddQuad(import_ImVec2(a), import_ImVec2(b), import_ImVec2(c), import_ImVec2(d), col, thickness);
}))
// IMGUI_API void AddQuadFilled(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, ImU32 col);
.function("AddQuadFilled", FUNCTION(void, (ImDrawList& that, emscripten::val a, emscripten::val b, emscripten::val c, emscripten::val d, ImU32 col), {
that.AddQuadFilled(import_ImVec2(a), import_ImVec2(b), import_ImVec2(c), import_ImVec2(d), col);
}))
// IMGUI_API void AddTriangle(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col, float thickness = 1.0f);
.function("AddTriangle", FUNCTION(void, (ImDrawList& that, emscripten::val a, emscripten::val b, emscripten::val c, ImU32 col, float thickness), {
that.AddTriangle(import_ImVec2(a), import_ImVec2(b), import_ImVec2(c), col, thickness);
}))
// IMGUI_API void AddTriangleFilled(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col);
.function("AddTriangleFilled", FUNCTION(void, (ImDrawList& that, emscripten::val a, emscripten::val b, emscripten::val c, ImU32 col), {
that.AddTriangleFilled(import_ImVec2(a), import_ImVec2(b), import_ImVec2(c), col);
}))
// IMGUI_API void AddCircle(const ImVec2& centre, float radius, ImU32 col, int num_segments = 12, float thickness = 1.0f);
.function("AddCircle", FUNCTION(void, (ImDrawList& that, emscripten::val centre, float radius, ImU32 col, int num_segments, float thickness), {
that.AddCircle(import_ImVec2(centre), radius, col, num_segments, thickness);
}))
// IMGUI_API void AddCircleFilled(const ImVec2& centre, float radius, ImU32 col, int num_segments = 12);
.function("AddCircleFilled", FUNCTION(void, (ImDrawList& that, emscripten::val centre, float radius, ImU32 col, int num_segments), {
that.AddCircleFilled(import_ImVec2(centre), radius, col, num_segments);
}))
// IMGUI_API void AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL);
.function("AddText_A", FUNCTION(void, (ImDrawList& that, emscripten::val pos, ImU32 col, std::string text_begin), {
that.AddText(import_ImVec2(pos), col, text_begin.c_str(), NULL);
}))
// IMGUI_API void AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL, float wrap_width = 0.0f, const ImVec4* cpu_fine_clip_rect = NULL);
.function("AddText_B", FUNCTION(void, (ImDrawList& that, emscripten::val font, float font_size, emscripten::val pos, ImU32 col, std::string text_begin, float wrap_width, emscripten::val cpu_fine_clip_rect), {
ImFont* _font = font.as<ImFont*>(emscripten::allow_raw_pointers());
that.AddText(_font, font_size, import_ImVec2(pos), col, text_begin.c_str(), NULL, wrap_width, import_maybe_null_value<ImVec4>(cpu_fine_clip_rect));
}))
// IMGUI_API void AddImage(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a = ImVec2(0,0), const ImVec2& uv_b = ImVec2(1,1), ImU32 col = 0xFFFFFFFF);
.function("AddImage", FUNCTION(void, (ImDrawList& that, emscripten::val user_texture_id, emscripten::val a, emscripten::val b, emscripten::val uv_a, emscripten::val uv_b, ImU32 col), {
that.AddImage((ImTextureID) user_texture_id.as<int>(), import_ImVec2(a), import_ImVec2(b), import_ImVec2(uv_a), import_ImVec2(uv_b), col);
}))
// IMGUI_API void AddImageQuad(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, const ImVec2& uv_a = ImVec2(0,0), const ImVec2& uv_b = ImVec2(1,0), const ImVec2& uv_c = ImVec2(1,1), const ImVec2& uv_d = ImVec2(0,1), ImU32 col = 0xFFFFFFFF);
.function("AddImageQuad", FUNCTION(void, (ImDrawList& that, emscripten::val user_texture_id, emscripten::val a, emscripten::val b, emscripten::val c, emscripten::val d, emscripten::val uv_a, emscripten::val uv_b, emscripten::val uv_c, emscripten::val uv_d, ImU32 col), {
that.AddImageQuad((ImTextureID) user_texture_id.as<int>(), import_ImVec2(a), import_ImVec2(b), import_ImVec2(c), import_ImVec2(d), import_ImVec2(uv_a), import_ImVec2(uv_b), import_ImVec2(uv_c), import_ImVec2(uv_d), col);
}))
// IMGUI_API void AddImageRounded(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, ImU32 col, float rounding, int rounding_corners = ImDrawCornerFlags_All);
.function("AddImageRounded", FUNCTION(void, (ImDrawList& that, emscripten::val user_texture_id, emscripten::val a, emscripten::val b, emscripten::val uv_a, emscripten::val uv_b, ImU32 col, float rounding, int rounding_corners), {
that.AddImageRounded((ImTextureID) user_texture_id.as<int>(), import_ImVec2(a), import_ImVec2(b), import_ImVec2(uv_a), import_ImVec2(uv_b), col, rounding, rounding_corners);
}))
// IMGUI_API void AddPolyline(const ImVec2* points, const int num_points, ImU32 col, bool closed, float thickness);
.function("AddPolyline", FUNCTION(void, (ImDrawList& that, emscripten::val points, const int num_points, ImU32 col, bool closed, float thickness), {
ImVec2 _points[num_points];
for (int i = 0; i < num_points; ++i) {
_points[i] = import_ImVec2(points[i]);
}
that.AddPolyline(_points, num_points, col, closed, thickness);
}))
// IMGUI_API void AddConvexPolyFilled(const ImVec2* points, const int num_points, ImU32 col);
.function("AddConvexPolyFilled", FUNCTION(void, (ImDrawList& that, emscripten::val points, const int num_points, ImU32 col), {
ImVec2 _points[num_points];
for (int i = 0; i < num_points; ++i) {
_points[i] = import_ImVec2(points[i]);
}
that.AddConvexPolyFilled(_points, num_points, col);
}))
// IMGUI_API void AddBezierCurve(const ImVec2& pos0, const ImVec2& cp0, const ImVec2& cp1, const ImVec2& pos1, ImU32 col, float thickness, int num_segments = 0);
.function("AddBezierCurve", FUNCTION(void, (ImDrawList& that, emscripten::val pos0, emscripten::val cp0, emscripten::val cp1, emscripten::val pos1, ImU32 col, float thickness, int num_segments), {
that.AddBezierCurve(import_ImVec2(pos0), import_ImVec2(cp0), import_ImVec2(cp1), import_ImVec2(pos1), col, thickness, num_segments);
}))
// Stateful path API, add points then finish with PathFill() or PathStroke()
// inline void PathClear() { _Path.resize(0); }
CLASS_METHOD(ImDrawList, PathClear)
// inline void PathLineTo(const ImVec2& pos) { _Path.push_back(pos); }
.function("PathLineTo", FUNCTION(void, (ImDrawList& that, emscripten::val pos), {
that.PathLineTo(import_ImVec2(pos));
}))
// inline void PathLineToMergeDuplicate(const ImVec2& pos) { if (_Path.Size == 0 || memcmp(&_Path[_Path.Size-1], &pos, 8) != 0) _Path.push_back(pos); }
.function("PathLineToMergeDuplicate", FUNCTION(void, (ImDrawList& that, emscripten::val pos), {
that.PathLineToMergeDuplicate(import_ImVec2(pos));
}))
// inline void PathFillConvex(ImU32 col) { AddConvexPolyFilled(_Path.Data, _Path.Size, col); PathClear(); }
.function("PathFillConvex", FUNCTION(void, (ImDrawList& that, ImU32 col), {
that.PathFillConvex(col);
}))
// inline void PathStroke(ImU32 col, bool closed, float thickness = 1.0f) { AddPolyline(_Path.Data, _Path.Size, col, closed, thickness); PathClear(); }
.function("PathStroke", FUNCTION(void, (ImDrawList& that, ImU32 col, bool closed, float thickness), {
that.PathStroke(col, closed, thickness);
}))
// IMGUI_API void PathArcTo(const ImVec2& centre, float radius, float a_min, float a_max, int num_segments = 10);
.function("PathArcTo", FUNCTION(void, (ImDrawList& that, emscripten::val centre, float radius, float a_min, float a_max, int num_segments), {
that.PathArcTo(import_ImVec2(centre), radius, a_min, a_max, num_segments);
}))
// IMGUI_API void PathArcToFast(const ImVec2& centre, float radius, int a_min_of_12, int a_max_of_12); // Use precomputed angles for a 12 steps circle
.function("PathArcToFast", FUNCTION(void, (ImDrawList& that, emscripten::val centre, float radius, int a_min_of_12, int a_max_of_12), {
that.PathArcToFast(import_ImVec2(centre), radius, a_min_of_12, a_max_of_12);
}))
// IMGUI_API void PathBezierCurveTo(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, int num_segments = 0);
.function("PathBezierCurveTo", FUNCTION(void, (ImDrawList& that, emscripten::val p1, emscripten::val p2, emscripten::val p3, int num_segments), {
that.PathBezierCurveTo(import_ImVec2(p1), import_ImVec2(p2), import_ImVec2(p3), num_segments);
}))
// IMGUI_API void PathRect(const ImVec2& rect_min, const ImVec2& rect_max, float rounding = 0.0f, int rounding_corners_flags = ImDrawCornerFlags_All);
.function("PathRect", FUNCTION(void, (ImDrawList& that, emscripten::val rect_min, emscripten::val rect_max, float rounding, int rounding_corners_flags), {
that.PathRect(import_ImVec2(rect_min), import_ImVec2(rect_max), rounding, rounding_corners_flags);
}))
// Channels
// - Use to simulate layers. By switching channels to can render out-of-order (e.g. submit foreground primitives before background primitives)
// - Use to minimize draw calls (e.g. if going back-and-forth between multiple non-overlapping clipping rectangles, prefer to append into separate channels then merge at the end)
// IMGUI_API void ChannelsSplit(int channels_count);
CLASS_METHOD(ImDrawList, ChannelsSplit)
// IMGUI_API void ChannelsMerge();
CLASS_METHOD(ImDrawList, ChannelsMerge)
// IMGUI_API void ChannelsSetCurrent(int channel_index);
CLASS_METHOD(ImDrawList, ChannelsSetCurrent)
// Advanced
// IMGUI_API void AddCallback(ImDrawCallback callback, void* callback_data); // Your rendering function must check for 'UserCallback' in ImDrawCmd and call the function instead of rendering triangles.
.function("AddCallback", FUNCTION(void, (ImDrawList& that, emscripten::val callback, emscripten::val callback_data), {
// TODO
}))
// IMGUI_API void AddDrawCmd(); // This is useful if you need to forcefully create a new draw call (to allow for dependent rendering / blending). Otherwise primitives are merged into the same draw-call as much as possible
CLASS_METHOD(ImDrawList, AddDrawCmd)
// IMGUI_API ImDrawList* CloneOutput() const; // Create a clone of the CmdBuffer/IdxBuffer/VtxBuffer.
// Internal helpers
// NB: all primitives needs to be reserved via PrimReserve() beforehand!
// IMGUI_API void Clear();
CLASS_METHOD(ImDrawList, Clear)
// IMGUI_API void ClearFreeMemory();
CLASS_METHOD(ImDrawList, ClearFreeMemory)
// IMGUI_API void PrimReserve(int idx_count, int vtx_count);
CLASS_METHOD(ImDrawList, PrimReserve)
// IMGUI_API void PrimRect(const ImVec2& a, const ImVec2& b, ImU32 col); // Axis aligned rectangle (composed of two triangles)
.function("PrimRect", FUNCTION(void, (ImDrawList& that, emscripten::val a, emscripten::val b, ImU32 col), {
that.PrimRect(import_ImVec2(a), import_ImVec2(b), col);
}))
// IMGUI_API void PrimRectUV(const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, ImU32 col);
.function("PrimRectUV", FUNCTION(void, (ImDrawList& that, emscripten::val a, emscripten::val b, emscripten::val uv_a, emscripten::val uv_b, ImU32 col), {
that.PrimRectUV(import_ImVec2(a), import_ImVec2(b), import_ImVec2(uv_a), import_ImVec2(uv_b), col);
}))
// IMGUI_API void PrimQuadUV(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, const ImVec2& uv_a, const ImVec2& uv_b, const ImVec2& uv_c, const ImVec2& uv_d, ImU32 col);
.function("PrimQuadUV", FUNCTION(void, (ImDrawList& that, emscripten::val a, emscripten::val b, emscripten::val c, emscripten::val d, emscripten::val uv_a, emscripten::val uv_b, emscripten::val uv_c, emscripten::val uv_d, ImU32 col), {
that.PrimQuadUV(import_ImVec2(a), import_ImVec2(b), import_ImVec2(c), import_ImVec2(d), import_ImVec2(uv_a), import_ImVec2(uv_b), import_ImVec2(uv_c), import_ImVec2(uv_d), col);
}))
// inline void PrimWriteVtx(const ImVec2& pos, const ImVec2& uv, ImU32 col){ _VtxWritePtr->pos = pos; _VtxWritePtr->uv = uv; _VtxWritePtr->col = col; _VtxWritePtr++; _VtxCurrentIdx++; }
.function("PrimWriteVtx", FUNCTION(void, (ImDrawList& that, emscripten::val pos, emscripten::val uv, ImU32 col), {
that.PrimWriteVtx(import_ImVec2(pos), import_ImVec2(uv), col);
}))
// inline void PrimWriteIdx(ImDrawIdx idx) { *_IdxWritePtr = idx; _IdxWritePtr++; }
.function("PrimWriteIdx", FUNCTION(void, (ImDrawList& that, ImDrawIdx idx), {
that.PrimWriteIdx(idx);
}))
// inline void PrimVtx(const ImVec2& pos, const ImVec2& uv, ImU32 col) { PrimWriteIdx((ImDrawIdx)_VtxCurrentIdx); PrimWriteVtx(pos, uv, col); }
.function("PrimVtx", FUNCTION(void, (ImDrawList& that, emscripten::val pos, emscripten::val uv, ImU32 col), {
that.PrimVtx(import_ImVec2(pos), import_ImVec2(uv), col);
}))
// IMGUI_API void UpdateClipRect();
CLASS_METHOD(ImDrawList, UpdateClipRect)
// IMGUI_API void UpdateTextureID();
CLASS_METHOD(ImDrawList, UpdateTextureID)
;
}
EMSCRIPTEN_BINDINGS(ImDrawData) {
emscripten::class_<ImDrawData>("ImDrawData")
.function("IterateDrawLists", FUNCTION(void, (const ImDrawData* that, emscripten::val callback), {
for (int n = 0; n < that->CmdListsCount; n++) {
const ImDrawList* cmd_list = that->CmdLists[n];
callback(emscripten::val(cmd_list));
}
}), emscripten::allow_raw_pointers())
// bool Valid; // Only valid after Render() is called and before the next NewFrame() is called.
CLASS_MEMBER(ImDrawData, Valid)
// ImDrawList** CmdLists;
// int CmdListsCount;
CLASS_MEMBER(ImDrawData, CmdListsCount)
// int TotalIdxCount; // For convenience, sum of all cmd_lists idx_buffer.Size
CLASS_MEMBER(ImDrawData, TotalIdxCount)
// int TotalVtxCount; // For convenience, sum of all cmd_lists vtx_buffer.Size
CLASS_MEMBER(ImDrawData, TotalVtxCount)
// ImVec2 DisplayPos; // Upper-left position of the viewport to render (== upper-left of the orthogonal projection matrix to use)
CLASS_MEMBER_GET_RAW_REFERENCE(ImDrawData, DisplayPos)
// ImVec2 DisplaySize; // Size of the viewport to render (== io.DisplaySize for the main viewport) (DisplayPos + DisplaySize == lower-right of the orthogonal projection matrix to use)
CLASS_MEMBER_GET_RAW_REFERENCE(ImDrawData, DisplaySize)
// Functions
// ImDrawData() { Valid = false; CmdLists = NULL; CmdListsCount = TotalVtxCount = TotalIdxCount = 0; }
// IMGUI_API void DeIndexAllBuffers(); // For backward compatibility or convenience: convert all buffers from indexed to de-indexed, in case you cannot render indexed. Note: this is slow and most likely a waste of resources. Always prefer indexed rendering!
CLASS_METHOD(ImDrawData, DeIndexAllBuffers)
// IMGUI_API void ScaleClipRects(const ImVec2& sc); // Helper to scale the ClipRect field of each ImDrawCmd. Use if your final output buffer is at a different scale than ImGui expects, or if there is a difference between your window resolution and framebuffer resolution.
.function("ScaleClipRects", FUNCTION(void, (ImDrawData& that, emscripten::val sc), {
that.ScaleClipRects(import_ImVec2(sc));
}))
;
}
EMSCRIPTEN_BINDINGS(ImFontGlyph) {
emscripten::class_<ImFontGlyph>("ImFontGlyph")
// ImWchar Codepoint; // 0x0000..0xFFFF
CLASS_MEMBER(ImFontGlyph, Codepoint)
// float AdvanceX; // Distance to next character (= data from font + ImFontConfig::GlyphExtraSpacing.x baked in)
CLASS_MEMBER(ImFontGlyph, AdvanceX)
// float X0, Y0, X1, Y1; // Glyph corners
CLASS_MEMBER(ImFontGlyph, X0)
CLASS_MEMBER(ImFontGlyph, Y0)
CLASS_MEMBER(ImFontGlyph, X1)
CLASS_MEMBER(ImFontGlyph, Y1)
// float U0, V0, U1, V1; // Texture coordinates
CLASS_MEMBER(ImFontGlyph, U0)
CLASS_MEMBER(ImFontGlyph, V0)
CLASS_MEMBER(ImFontGlyph, U1)
CLASS_MEMBER(ImFontGlyph, V1)
;
}
EMSCRIPTEN_BINDINGS(ImFontConfig) {
emscripten::class_<ImFontConfig>("ImFontConfig")
// void* FontData; // // TTF/OTF data
// int FontDataSize; // // TTF/OTF data size
// FontData: DataView | null;
CLASS_MEMBER_GET_SET(ImFontConfig, FontData,
{ TODO(); return emscripten::val::null(); },
{ TODO(); }
)
// bool FontDataOwnedByAtlas; // true // TTF/OTF data ownership taken by the container ImFontAtlas (will delete memory itself).
CLASS_MEMBER(ImFontConfig, FontDataOwnedByAtlas)
// int FontNo; // 0 // Index of font within TTF/OTF file
CLASS_MEMBER(ImFontConfig, FontNo)
// float SizePixels; // // Size in pixels for rasterizer.
CLASS_MEMBER(ImFontConfig, SizePixels)
// int OversampleH, OversampleV; // 3, 1 // Rasterize at higher quality for sub-pixel positioning. We don't use sub-pixel positions on the Y axis.
CLASS_MEMBER(ImFontConfig, OversampleH)
CLASS_MEMBER(ImFontConfig, OversampleV)
// bool PixelSnapH; // false // Align every glyph to pixel boundary. Useful e.g. if you are merging a non-pixel aligned font with the default font. If enabled, you can set OversampleH/V to 1.
CLASS_MEMBER(ImFontConfig, PixelSnapH)
// ImVec2 GlyphExtraSpacing; // 0, 0 // Extra spacing (in pixels) between glyphs. Only X axis is supported for now.
CLASS_MEMBER_GET_RAW_REFERENCE(ImFontConfig, GlyphExtraSpacing)
// ImVec2 GlyphOffset; // 0, 0 // Offset all glyphs from this font input.
CLASS_MEMBER_GET_RAW_REFERENCE(ImFontConfig, GlyphOffset)
// const ImWchar* GlyphRanges; // NULL // Pointer to a user-provided list of Unicode range (2 value per range, values are inclusive, zero-terminated list). THE ARRAY DATA NEEDS TO PERSIST AS LONG AS THE FONT IS ALIVE.
CLASS_MEMBER_GET(ImFontConfig, GlyphRanges, {
return that.GlyphRanges == NULL ? emscripten::val::null() : emscripten::val((intptr_t) that.GlyphRanges);
})
// float GlyphMinAdvanceX; // 0 // Minimum AdvanceX for glyphs, set Min to align font icons, set both Min/Max to enforce mono-space font
CLASS_MEMBER(ImFontConfig, GlyphMinAdvanceX)
// float GlyphMaxAdvanceX; // FLT_MAX // Maximum AdvanceX for glyphs
CLASS_MEMBER(ImFontConfig, GlyphMaxAdvanceX)
// bool MergeMode; // false // Merge into previous ImFont, so you can combine multiple inputs font into one ImFont (e.g. ASCII font + icons + Japanese glyphs). You may want to use GlyphOffset.y when merge font of different heights.
CLASS_MEMBER(ImFontConfig, MergeMode)
// unsigned int RasterizerFlags; // 0x00 // Settings for custom font rasterizer (e.g. ImGuiFreeType). Leave as zero if you aren't using one.
CLASS_MEMBER(ImFontConfig, RasterizerFlags)
// float RasterizerMultiply; // 1.0f // Brighten (>1.0f) or darken (<1.0f) font output. Brightening small fonts may be a good workaround to make them more readable.
CLASS_MEMBER(ImFontConfig, RasterizerMultiply)
// [Internal]
// char Name[32]; // Name (strictly to ease debugging)
CLASS_MEMBER_GET_SET(ImFontConfig, Name,
{ return emscripten::val(std::string(that.Name)); },
{ strncpy(that.Name, value.as<std::string>().c_str(), sizeof(that.Name) - 1); }
)
// ImFont* DstFont;
CLASS_MEMBER_GET_RAW_POINTER(ImFontConfig, DstFont)
// IMGUI_API ImFontConfig();
;
}
EMSCRIPTEN_BINDINGS(ImFont) {
emscripten::class_<ImFont>("ImFont")
// Members: Hot ~62/78 bytes
// float FontSize; // <user set> // Height of characters, set during loading (don't change after loading)
CLASS_MEMBER(ImFont, FontSize)
// float Scale; // = 1.f // Base font scale, multiplied by the per-window font scale which you can adjust with SetFontScale()
CLASS_MEMBER(ImFont, Scale)
// ImVec2 DisplayOffset; // = (0.f,1.f) // Offset font rendering by xx pixels
CLASS_MEMBER_GET_RAW_REFERENCE(ImFont, DisplayOffset)
// ImVector<ImFontGlyph> Glyphs; // // All glyphs.
// CLASS_MEMBER(ImFont, Glyphs)
.function("IterateGlyphs", FUNCTION(void, (ImFont* that, emscripten::val callback), {
for (int n = 0; n < that->Glyphs.Size; n++) {
auto glyph = &that->Glyphs[n];
callback(emscripten::val(glyph));
}
}), emscripten::allow_raw_pointers())
// ImVector<float> IndexAdvanceX; // // Sparse. Glyphs->AdvanceX in a directly indexable way (more cache-friendly, for CalcTextSize functions which are often bottleneck in large UI).
// CLASS_MEMBER(ImFont, IndexAdvanceX)
// ImVector<unsigned short> IndexLookup; // // Sparse. Index glyphs by Unicode code-point.
// CLASS_MEMBER(ImFont, IndexLookup)
// const ImFontGlyph* FallbackGlyph; // == FindGlyph(FontFallbackChar)
// CLASS_MEMBER(ImFont, FallbackGlyph)
CLASS_MEMBER_GET_SET_RAW_POINTER(ImFont, FallbackGlyph)
// float FallbackAdvanceX; // == FallbackGlyph->AdvanceX
CLASS_MEMBER(ImFont, FallbackAdvanceX)
// ImWchar FallbackChar; // = '?' // Replacement glyph if one isn't found. Only set via SetFallbackChar()
CLASS_MEMBER(ImFont, FallbackChar)
// Members: Cold ~18/26 bytes
// short ConfigDataCount; // ~ 1 // Number of ImFontConfig involved in creating this font. Bigger than 1 when merging multiple font sources into one ImFont.
CLASS_MEMBER(ImFont, ConfigDataCount)
// ImFontConfig* ConfigData; // // Pointer within ContainerAtlas->ConfigData
// CLASS_MEMBER(ImFont, ConfigData)
.function("IterateConfigData", FUNCTION(void, (ImFont* that, emscripten::val callback), {
for (int n = 0; n < that->ConfigDataCount; n++) {
auto cfg = &that->ConfigData[n];
callback(emscripten::val(cfg));
}
}), emscripten::allow_raw_pointers())
// ImFontAtlas* ContainerAtlas; // // What we has been loaded into
// CLASS_MEMBER(ImFont, ContainerAtlas)
// float Ascent, Descent; // // Ascent: distance from top to bottom of e.g. 'A' [0..FontSize]
CLASS_MEMBER(ImFont, Ascent)
CLASS_MEMBER(ImFont, Descent)
// int MetricsTotalSurface;// // Total surface in pixels to get an idea of the font rasterization/texture cost (not exact, we approximate the cost of padding between glyphs)
CLASS_MEMBER(ImFont, MetricsTotalSurface)
// Methods
// IMGUI_API ImFont();
// IMGUI_API ~ImFont();
// IMGUI_API void ClearOutputData();
CLASS_METHOD(ImFont, ClearOutputData)
// IMGUI_API void BuildLookupTable();
CLASS_METHOD(ImFont, BuildLookupTable)
// IMGUI_API const ImFontGlyph*FindGlyph(ImWchar c) const;
.function("FindGlyph", FUNCTION(emscripten::val, (const ImFont& that, ImWchar c), {
const ImFontGlyph* glyph = that.FindGlyph(c);
return glyph == NULL ? emscripten::val::null() : emscripten::val(glyph);
}), emscripten::allow_raw_pointers())
// IMGUI_API const ImFontGlyph*FindGlyphNoFallback(ImWchar c) const;
.function("FindGlyphNoFallback", FUNCTION(emscripten::val, (const ImFont& that, ImWchar c), {
const ImFontGlyph* glyph = that.FindGlyphNoFallback(c);
return glyph == NULL ? emscripten::val::null() : emscripten::val(glyph);
}), emscripten::allow_raw_pointers())
// IMGUI_API void SetFallbackChar(ImWchar c);
CLASS_METHOD(ImFont, SetFallbackChar)
// float GetCharAdvance(ImWchar c) const { return ((int)c < IndexAdvanceX.Size) ? IndexAdvanceX[(int)c] : FallbackAdvanceX; }
CLASS_METHOD(ImFont, GetCharAdvance)
// bool IsLoaded() const { return ContainerAtlas != NULL; }
CLASS_METHOD(ImFont, IsLoaded)
// const char* GetDebugName() const { return ConfigData ? ConfigData->Name : "<unknown>"; }
.function("GetDebugName", FUNCTION(std::string, (const ImFont& that), { return that.GetDebugName(); }))
// 'max_width' stops rendering after a certain width (could be turned into a 2d size). FLT_MAX to disable.
// 'wrap_width' enable automatic word-wrapping across multiple lines to fit into given width. 0.0f to disable.
// IMGUI_API ImVec2 CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end = NULL, const char** remaining = NULL) const; // utf8
.function("CalcTextSizeA", FUNCTION(emscripten::val, (const ImFont& that, float size, float max_width, float wrap_width, std::string text_begin, emscripten::val remaining, emscripten::val out), {
const char* _text_begin = text_begin.c_str();
const char* _remaining = NULL;
const ImVec2 text_size = that.CalcTextSizeA(size, max_width, wrap_width, _text_begin, NULL, &_remaining);
if (!remaining.isNull()) {
remaining.set(0, (int)(_remaining - _text_begin));
}
return export_ImVec2(text_size, out);
}))
// IMGUI_API const char* CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) const;
.function("CalcWordWrapPositionA", FUNCTION(int, (const ImFont& that, float scale, std::string text, float wrap_width), {
const char* _text = text.c_str();
const char* pos = that.CalcWordWrapPositionA(scale, _text, NULL, wrap_width);
return (int)(pos - _text);
}))
// IMGUI_API void RenderChar(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, unsigned short c) const;
.function("RenderChar", FUNCTION(void, (const ImFont& that, emscripten::val draw_list, float size, emscripten::val pos, ImU32 col, unsigned short c), {
that.RenderChar(draw_list.as<ImDrawList*>(emscripten::allow_raw_pointers()), size, import_ImVec2(pos), col, c);
}))
// IMGUI_API void RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width = 0.0f, bool cpu_fine_clip = false) const;
// [Internal]
// IMGUI_API void GrowIndex(int new_size);
// IMGUI_API void AddGlyph(ImWchar c, float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1, float advance_x);
// IMGUI_API void AddRemapChar(ImWchar dst, ImWchar src, bool overwrite_dst = true); // Makes 'dst' character/glyph points to 'src' character/glyph. Currently needs to be called AFTER fonts have been built.
// #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
// typedef ImFontGlyph Glyph; // OBSOLETE 1.52+
// #endif
;
}
ImFontConfig import_ImFontConfig(emscripten::val value) {
ImFontConfig font_cfg;
// void* FontData; // // TTF/OTF data
// int FontDataSize; // // TTF/OTF data size
const emscripten::val FontData = value["FontData"];
if (FontData.isNull()) {
font_cfg.FontData = NULL;
font_cfg.FontDataSize = 0;
} else {
const emscripten::val buffer = FontData["buffer"];
const size_t byteOffset = FontData["byteOffset"].as<size_t>();
const size_t byteLength = FontData["byteLength"].as<size_t>();
font_cfg.FontData = NULL; // TODO
font_cfg.FontDataSize = 0; // TODO
printf("TODO: FontData %zu %zu\n", byteOffset, byteLength);
}
// bool FontDataOwnedByAtlas; // true // TTF/OTF data ownership taken by the container ImFontAtlas (will delete memory itself).
font_cfg.FontDataOwnedByAtlas = value["FontDataOwnedByAtlas"].as<bool>();
// int FontNo; // 0 // Index of font within TTF/OTF file
font_cfg.FontNo = value["FontNo"].as<int>();
// float SizePixels; // // Size in pixels for rasterizer.
font_cfg.SizePixels = import_value<float>(value["SizePixels"]);
// int OversampleH, OversampleV; // 3, 1 // Rasterize at higher quality for sub-pixel positioning. We don't use sub-pixel positions on the Y axis.
font_cfg.OversampleH = value["OversampleH"].as<int>();
font_cfg.OversampleV = value["OversampleV"].as<int>();
// bool PixelSnapH; // false // Align every glyph to pixel boundary. Useful e.g. if you are merging a non-pixel aligned font with the default font. If enabled, you can set OversampleH/V to 1.
font_cfg.PixelSnapH = value["PixelSnapH"].as<bool>();
// ImVec2 GlyphExtraSpacing; // 0, 0 // Extra spacing (in pixels) between glyphs. Only X axis is supported for now.
font_cfg.GlyphExtraSpacing = import_ImVec2(value["GlyphExtraSpacing"]);