mirror of
https://github.com/ocornut/imgui.git
synced 2026-07-07 01:49:41 +00:00
Compare commits
1454 Commits
v1.90
...
v1.90.1-do
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2dc85e6e43 | ||
|
|
d6cb3c923d | ||
|
|
6470e2279e | ||
|
|
fdf8d02be1 | ||
|
|
788bb58b6b | ||
|
|
a5dec42866 | ||
|
|
a3eea8a75a | ||
|
|
cf02023565 | ||
|
|
69bf3291df | ||
|
|
ebcfcd8da3 | ||
|
|
8deb1007cd | ||
|
|
a683033e49 | ||
|
|
af00b182e3 | ||
|
|
fc2e532f99 | ||
|
|
8323a06e6d | ||
|
|
58261dbe9a | ||
|
|
f1ae47c4b9 | ||
|
|
7f9533b840 | ||
|
|
27e83c2953 | ||
|
|
278cf1a7bc | ||
|
|
edeb8ee3ab | ||
|
|
c6716f5e9f | ||
|
|
a1b06823fe | ||
|
|
0461ade24b | ||
|
|
c528b688cf | ||
|
|
26eef4df87 | ||
|
|
7938550d52 | ||
|
|
4758f74676 | ||
|
|
e3d7cd665d | ||
|
|
6f10cef2a1 | ||
|
|
33d18c580b | ||
|
|
0ea99132c8 | ||
|
|
4778560e66 | ||
|
|
e8dd47effa | ||
|
|
718fa0eec6 | ||
|
|
2523c197bc | ||
|
|
240ab5890b | ||
|
|
4a2426449a | ||
|
|
20e1caec85 | ||
|
|
f039e69b9c | ||
|
|
4aa81116a5 | ||
|
|
8340a30d27 | ||
|
|
1e1013085b | ||
|
|
036a6c875e | ||
|
|
0bd6489721 | ||
|
|
0000739c08 | ||
|
|
33d426842d | ||
|
|
3cb805489b | ||
|
|
22a7d241ff | ||
|
|
b4c5a83cfe | ||
|
|
70f2aaff43 | ||
|
|
55073aa7a3 | ||
|
|
8764a1b7c4 | ||
|
|
089ed30323 | ||
|
|
e265610a0c | ||
|
|
f59b54c6f4 | ||
|
|
0d582dabf3 | ||
|
|
8add6bcb9f | ||
|
|
6cfe3ddf52 | ||
|
|
54c1bdeceb | ||
|
|
4afffa36e9 | ||
|
|
f6836ff37f | ||
|
|
07dbd46ddd | ||
|
|
34646627aa | ||
|
|
86512eac06 | ||
|
|
03298fe875 | ||
|
|
69f524ba95 | ||
|
|
9d8de45313 | ||
|
|
5366bd09bf | ||
|
|
c58d2c89c3 | ||
|
|
1fade35159 | ||
|
|
58ca5f6424 | ||
|
|
d72e1563d4 | ||
|
|
9a2985611c | ||
|
|
0b77980cab | ||
|
|
aaf157cfdd | ||
|
|
96b5b1724b | ||
|
|
1fd5ff7152 | ||
|
|
52886872f1 | ||
|
|
5768de79e2 | ||
|
|
b112d73edb | ||
|
|
2ee40d3cf9 | ||
|
|
b4b864e40a | ||
|
|
d2b0167610 | ||
|
|
7965494ff3 | ||
|
|
c1a3c7f445 | ||
|
|
c6ec69c7c1 | ||
|
|
888834c636 | ||
|
|
077e4db772 | ||
|
|
f6253b87d0 | ||
|
|
6f171a066d | ||
|
|
e07663d9a1 | ||
|
|
1f3090a48d | ||
|
|
86891b0986 | ||
|
|
f37f6f67f6 | ||
|
|
bce4db00bc | ||
|
|
65a10410e3 | ||
|
|
61b8197942 | ||
|
|
3733b5064e | ||
|
|
c5c1c4134b | ||
|
|
7bb0a525c3 | ||
|
|
3d083dbe1a | ||
|
|
ce0d0ac829 | ||
|
|
6695006bea | ||
|
|
0941adc931 | ||
|
|
9d950444a2 | ||
|
|
450f1d7e7b | ||
|
|
37ea320b96 | ||
|
|
208b8242bc | ||
|
|
4cde40dbe1 | ||
|
|
9298e310b2 | ||
|
|
04e9a2fac1 | ||
|
|
2a6d7b1eaa | ||
|
|
51d1a72e9b | ||
|
|
4521dec85d | ||
|
|
83c4336828 | ||
|
|
f7fc186408 | ||
|
|
72ebd91567 | ||
|
|
9064dbd404 | ||
|
|
d27b4ad366 | ||
|
|
17bfafda55 | ||
|
|
ff534b0d0a | ||
|
|
f8aed6499f | ||
|
|
b7c250925f | ||
|
|
bb2fb74645 | ||
|
|
c418685315 | ||
|
|
2c0007731f | ||
|
|
61acb34e32 | ||
|
|
3ce6b06feb | ||
|
|
64b1e448d2 | ||
|
|
ac3bc73c13 | ||
|
|
afd0d3fca1 | ||
|
|
72d760ba00 | ||
|
|
f693c3d806 | ||
|
|
7e246a7bb9 | ||
|
|
1612813114 | ||
|
|
14f8b76c1a | ||
|
|
72dbe45adc | ||
|
|
1d8e48c161 | ||
|
|
a1b60fc1f5 | ||
|
|
300464a487 | ||
|
|
7d6e83efca | ||
|
|
762ec445e6 | ||
|
|
475453668d | ||
|
|
61d35972e2 | ||
|
|
676497fe05 | ||
|
|
1161301386 | ||
|
|
f422e7826f | ||
|
|
63b6300c39 | ||
|
|
f8704cd085 | ||
|
|
30594c37d0 | ||
|
|
f8f805f046 | ||
|
|
07d1709ca2 | ||
|
|
023e59a5f2 | ||
|
|
0110f4c8cc | ||
|
|
51b348095c | ||
|
|
f4942bca32 | ||
|
|
27c735e3e9 | ||
|
|
f6feddd1ee | ||
|
|
b79751ebad | ||
|
|
a5aff5fd3e | ||
|
|
8566fec661 | ||
|
|
dc3e531ff2 | ||
|
|
ac8573884d | ||
|
|
677c7b2258 | ||
|
|
a88e5be7f4 | ||
|
|
6b01114057 | ||
|
|
057fcae30c | ||
|
|
35b41949fb | ||
|
|
099e8533e2 | ||
|
|
66c09fc05b | ||
|
|
7d81a166f9 | ||
|
|
e4aeef4b9f | ||
|
|
1450d23b60 | ||
|
|
b9db5c566b | ||
|
|
ef07ddf087 | ||
|
|
fa5d2656b0 | ||
|
|
3f63cee4c1 | ||
|
|
0664877998 | ||
|
|
8fd0a04135 | ||
|
|
823a1385a2 | ||
|
|
3418d50949 | ||
|
|
f0f3b927e0 | ||
|
|
6cc967a124 | ||
|
|
2e810d575c | ||
|
|
19b436f68d | ||
|
|
54c1ac3e38 | ||
|
|
e590b5114e | ||
|
|
530134d125 | ||
|
|
031148dc56 | ||
|
|
594cc4793a | ||
|
|
d2291df551 | ||
|
|
bba39762dc | ||
|
|
ac38c8e6fe | ||
|
|
c11128891e | ||
|
|
adf693c061 | ||
|
|
07e07030a6 | ||
|
|
88ac2ced7c | ||
|
|
f498f084d6 | ||
|
|
4bc51c6ff4 | ||
|
|
1f2b84a654 | ||
|
|
4f692ba840 | ||
|
|
0ea3b87bd6 | ||
|
|
bed11b35d1 | ||
|
|
aec062a8a5 | ||
|
|
1668693bcf | ||
|
|
ec461c6ccb | ||
|
|
63370be0e5 | ||
|
|
1f0b46b93c | ||
|
|
ed72fcd12a | ||
|
|
dcb6335bfe | ||
|
|
ee5ce36745 | ||
|
|
4fdafef54f | ||
|
|
bf87fbcbcc | ||
|
|
ad44f5831a | ||
|
|
5320a6ebd3 | ||
|
|
6b3435a2db | ||
|
|
85beda96de | ||
|
|
9e30fb0ec1 | ||
|
|
9937660b1c | ||
|
|
e2cede6542 | ||
|
|
f5c5a710aa | ||
|
|
4078abe14c | ||
|
|
702626dd8a | ||
|
|
e25e4526cd | ||
|
|
192196711a | ||
|
|
345184330b | ||
|
|
ea4565368e | ||
|
|
0d7d877cb5 | ||
|
|
95412ad3a5 | ||
|
|
a526ff8c30 | ||
|
|
e4233c6fb6 | ||
|
|
c807192abc | ||
|
|
b0a936e5d4 | ||
|
|
97a1f761c6 | ||
|
|
5ebb6a2954 | ||
|
|
5386ddcd05 | ||
|
|
887abe9578 | ||
|
|
88dfd85e92 | ||
|
|
6342275bbb | ||
|
|
d822c65317 | ||
|
|
fc3815bfe5 | ||
|
|
824baa6a4d | ||
|
|
42e166089a | ||
|
|
6939676372 | ||
|
|
16aaf60697 | ||
|
|
90de839445 | ||
|
|
c191faf0ba | ||
|
|
d3025cde37 | ||
|
|
5eda547e6f | ||
|
|
3ea0fad204 | ||
|
|
540909bddf | ||
|
|
fad8afd62a | ||
|
|
595a428baa | ||
|
|
d2f9c5dfb7 | ||
|
|
9964740a47 | ||
|
|
38cfe22b8b | ||
|
|
94e850fd6f | ||
|
|
d7aca168ee | ||
|
|
a571933f8b | ||
|
|
4d5da74c79 | ||
|
|
5728f2e15f | ||
|
|
849c8052b7 | ||
|
|
ced92d9c52 | ||
|
|
375ae5dce4 | ||
|
|
50c4234aca | ||
|
|
5370b46c4e | ||
|
|
f87e891f18 | ||
|
|
edf522b58a | ||
|
|
cb04326b46 | ||
|
|
fb0b9c7160 | ||
|
|
69beaa1d0b | ||
|
|
d91211f9f2 | ||
|
|
11f5be0caf | ||
|
|
8f434874c0 | ||
|
|
6fd2ee9416 | ||
|
|
1dc7d0e633 | ||
|
|
3af9ac320d | ||
|
|
64b88da21b | ||
|
|
caf4b7f1e6 | ||
|
|
aceab9a877 | ||
|
|
bc2002ab92 | ||
|
|
71a0701920 | ||
|
|
db798fd5be | ||
|
|
b78738ff23 | ||
|
|
8cbd391f09 | ||
|
|
ff1567e240 | ||
|
|
e9f50fb87c | ||
|
|
f573ebf31a | ||
|
|
b12e056c21 | ||
|
|
0abe7d1cc5 | ||
|
|
e21f462f6f | ||
|
|
28a123ca47 | ||
|
|
cb8ead1f71 | ||
|
|
77637fd936 | ||
|
|
21fc57f2cf | ||
|
|
ad5aa54166 | ||
|
|
5d0deebba4 | ||
|
|
58eb40db76 | ||
|
|
9cd9c2eff9 | ||
|
|
9764adc7bb | ||
|
|
506717390f | ||
|
|
101aec95d9 | ||
|
|
e135cdbc24 | ||
|
|
24dfebf455 | ||
|
|
e900ca355e | ||
|
|
4789c7e485 | ||
|
|
7b5a8e4f2b | ||
|
|
250333d895 | ||
|
|
36055213c5 | ||
|
|
6b5a2426d7 | ||
|
|
2fa60bec27 | ||
|
|
693b4c57fe | ||
|
|
d666a1d473 | ||
|
|
6868d11669 | ||
|
|
414165d23f | ||
|
|
ec48681455 | ||
|
|
8dd5425182 | ||
|
|
505f19e3b0 | ||
|
|
377b864bb4 | ||
|
|
9b0c26b0b2 | ||
|
|
f337378066 | ||
|
|
8639a2f9f8 | ||
|
|
64519c6875 | ||
|
|
7b0d58c5e5 | ||
|
|
9948535118 | ||
|
|
1e14cc5cae | ||
|
|
aa86800092 | ||
|
|
1ee252772a | ||
|
|
033538731c | ||
|
|
31762a8173 | ||
|
|
5017602752 | ||
|
|
37958ca1b5 | ||
|
|
8eb8689391 | ||
|
|
c1ab3c406f | ||
|
|
d378e4088f | ||
|
|
08350e53e7 | ||
|
|
27004aca70 | ||
|
|
d5f0d45ae4 | ||
|
|
f1a073186c | ||
|
|
3e0d6ec895 | ||
|
|
e278277d53 | ||
|
|
1338eb31f7 | ||
|
|
007a427e0a | ||
|
|
8567a4cca3 | ||
|
|
ec1e57ed4a | ||
|
|
e51a0a80ca | ||
|
|
0647ba3bad | ||
|
|
acfc7798fd | ||
|
|
9ce0f35ef3 | ||
|
|
ef681e7019 | ||
|
|
704ab1114a | ||
|
|
afb1180d7d | ||
|
|
9c8f288d1a | ||
|
|
2aa9959553 | ||
|
|
15b4a064f9 | ||
|
|
06d5f9297d | ||
|
|
248ed1b01d | ||
|
|
cd36acc88b | ||
|
|
747f7fdbba | ||
|
|
f605351307 | ||
|
|
e31d116d37 | ||
|
|
0647cf434c | ||
|
|
fc198fe1db | ||
|
|
c1b70e0391 | ||
|
|
06e4f4e370 | ||
|
|
1dc3af381a | ||
|
|
c122c0ef89 | ||
|
|
b16f738d04 | ||
|
|
bf80204e63 | ||
|
|
8733ca49b0 | ||
|
|
6afcfe3442 | ||
|
|
848d21b6b5 | ||
|
|
1ab3007752 | ||
|
|
5f5ba8eb11 | ||
|
|
719d931304 | ||
|
|
ea83d040e6 | ||
|
|
7f38773b73 | ||
|
|
b50b22d787 | ||
|
|
2080d12bd9 | ||
|
|
dc8c3618e8 | ||
|
|
b17dffffb3 | ||
|
|
c1d2793580 | ||
|
|
0b4edf4e94 | ||
|
|
bac748fa95 | ||
|
|
05877c14df | ||
|
|
9b59455184 | ||
|
|
29653273c1 | ||
|
|
1b215ecb01 | ||
|
|
1780579403 | ||
|
|
835a5344b0 | ||
|
|
65ad63de84 | ||
|
|
ca097c2c68 | ||
|
|
fa0a314f59 | ||
|
|
c58fb46411 | ||
|
|
e7cc534367 | ||
|
|
29828d0469 | ||
|
|
8dfb52245b | ||
|
|
5d95e7eef9 | ||
|
|
92a39f78b9 | ||
|
|
79d39b190b | ||
|
|
6b77668171 | ||
|
|
9a49c1ddbd | ||
|
|
6b1e094cfb | ||
|
|
cfb837203c | ||
|
|
40caab4748 | ||
|
|
fa9fc05ac6 | ||
|
|
53589092b2 | ||
|
|
dedb381c51 | ||
|
|
0eb45a0577 | ||
|
|
58f5092c53 | ||
|
|
6bd447c885 | ||
|
|
47fb332fb2 | ||
|
|
2e01952b35 | ||
|
|
5a7d18a441 | ||
|
|
9c3359ef39 | ||
|
|
0b06c4b2b0 | ||
|
|
80b5fb51ed | ||
|
|
f9b5168fb3 | ||
|
|
7bfc379a23 | ||
|
|
3d5dc0d939 | ||
|
|
a11f36811f | ||
|
|
eb6f4b1a6a | ||
|
|
cd4cc9ff0d | ||
|
|
9e8e5ac363 | ||
|
|
6136b3844b | ||
|
|
0a8ab75e4b | ||
|
|
36a0d1028c | ||
|
|
0f7eb00f67 | ||
|
|
682447306d | ||
|
|
ac35b4bba2 | ||
|
|
cce307a2be | ||
|
|
afabb2f3d8 | ||
|
|
9b417b26d9 | ||
|
|
90deb0959a | ||
|
|
db0338a1f2 | ||
|
|
4161a67b38 | ||
|
|
865b2ca6f9 | ||
|
|
a44d4da87c | ||
|
|
16abfa5eb6 | ||
|
|
f53db3541a | ||
|
|
5e528d9eea | ||
|
|
f03ab2a5c5 | ||
|
|
fa1f540e6c | ||
|
|
91704b773e | ||
|
|
1ad1429c6d | ||
|
|
1b435ae3e0 | ||
|
|
105d82d134 | ||
|
|
86c2b609ef | ||
|
|
2cdfcb8fd2 | ||
|
|
31290807dc | ||
|
|
33cdbe97b8 | ||
|
|
34d4bc620d | ||
|
|
76902c482f | ||
|
|
e5efa01920 | ||
|
|
3f16a524c8 | ||
|
|
646c873598 | ||
|
|
e87dd0e65d | ||
|
|
539de4387b | ||
|
|
65cd14502c | ||
|
|
6ddcdbe3e8 | ||
|
|
9251eac585 | ||
|
|
3ed07a8f0b | ||
|
|
0e0a783b8c | ||
|
|
5991851eb9 | ||
|
|
a4adf60576 | ||
|
|
b79b1cb9c0 | ||
|
|
d7051928d9 | ||
|
|
b305953bd1 | ||
|
|
e7577d570e | ||
|
|
ca34c81ce9 | ||
|
|
085cff2fe5 | ||
|
|
b17bfdd6f4 | ||
|
|
81e0b18e38 | ||
|
|
b202fa9063 | ||
|
|
2231e1a369 | ||
|
|
256594575d | ||
|
|
cfe83c4b44 | ||
|
|
0157502eab | ||
|
|
f1bf642e8f | ||
|
|
4b9bc49020 | ||
|
|
d5a4d53000 | ||
|
|
705f082674 | ||
|
|
80533ea5e1 | ||
|
|
6aee4bcdc5 | ||
|
|
b794ecc079 | ||
|
|
732cd837a9 | ||
|
|
839ecce571 | ||
|
|
3ec14186cb | ||
|
|
a4e4f57cb0 | ||
|
|
ffa863a3ba | ||
|
|
3d75f438bc | ||
|
|
7180e9ac66 | ||
|
|
239d09804d | ||
|
|
04f7ea818d | ||
|
|
ee59d7a266 | ||
|
|
3607c42bec | ||
|
|
2a5eaf239f | ||
|
|
6f5f80a544 | ||
|
|
7a516a266d | ||
|
|
73ccb7e4b8 | ||
|
|
1a3af8cb4c | ||
|
|
862bfc53d3 | ||
|
|
fa55b0cb60 | ||
|
|
22d9a61b33 | ||
|
|
84e8802891 | ||
|
|
577e7cb493 | ||
|
|
cff8162454 | ||
|
|
376c88a864 | ||
|
|
bb26751b94 | ||
|
|
ebbb98d519 | ||
|
|
9e4956d86b | ||
|
|
388ca563db | ||
|
|
70703da782 | ||
|
|
b11518d7d7 | ||
|
|
7b53551032 | ||
|
|
06e87014f2 | ||
|
|
dd4ca70b0d | ||
|
|
657589ab47 | ||
|
|
c1ffac2fee | ||
|
|
4da92b89ed | ||
|
|
3dcbcd8bf0 | ||
|
|
cecf6b4209 | ||
|
|
b2a91dc390 | ||
|
|
ac08593b96 | ||
|
|
e3ac52630a | ||
|
|
455c21df71 | ||
|
|
d3a80d9f1b | ||
|
|
b26f1530b7 | ||
|
|
bae2240eda | ||
|
|
042a3b01d2 | ||
|
|
682249396f | ||
|
|
958e58b06b | ||
|
|
c49330fc52 | ||
|
|
fa004ae79a | ||
|
|
42575d4a99 | ||
|
|
6bc526676c | ||
|
|
e230ec5a01 | ||
|
|
770c995365 | ||
|
|
78f753ffff | ||
|
|
aa8e09d7f1 | ||
|
|
36c331ff74 | ||
|
|
8dacb4da20 | ||
|
|
fc625d249f | ||
|
|
34077c0140 | ||
|
|
600b8f60b4 | ||
|
|
e9053515bb | ||
|
|
30f0900b1c | ||
|
|
831e2c920e | ||
|
|
cf312545e8 | ||
|
|
d6f3a8848d | ||
|
|
9d20a5f0a5 | ||
|
|
ad8fdc917f | ||
|
|
05bc204dbd | ||
|
|
b36d1d465d | ||
|
|
25a9209b75 | ||
|
|
a9626e1162 | ||
|
|
a5ba26806f | ||
|
|
dbc70f21a9 | ||
|
|
85a661d276 | ||
|
|
acf043a675 | ||
|
|
2c13a74a9d | ||
|
|
de1588928b | ||
|
|
70fa37527d | ||
|
|
3d4af15d1d | ||
|
|
cba52b66af | ||
|
|
f79f0e42f7 | ||
|
|
cbade7b16d | ||
|
|
b626dd57d3 | ||
|
|
cb1d578470 | ||
|
|
4f5aac319e | ||
|
|
fc9d6b6cb5 | ||
|
|
4bdbea8375 | ||
|
|
2b9d88196e | ||
|
|
90ea7e2f2f | ||
|
|
ddabfc3477 | ||
|
|
f4f04cb5ec | ||
|
|
d7ef56dca2 | ||
|
|
5628416bd3 | ||
|
|
7538bbabb6 | ||
|
|
e1d7e14717 | ||
|
|
a616ff5d4a | ||
|
|
76e40fe5d1 | ||
|
|
20d61f5f62 | ||
|
|
2665288b30 | ||
|
|
8baa4ccff5 | ||
|
|
5d472c4895 | ||
|
|
0fe5170bc4 | ||
|
|
615e9ae345 | ||
|
|
3b3af6b731 | ||
|
|
e4d8267188 | ||
|
|
1cd32d3afe | ||
|
|
03ea87ea28 | ||
|
|
c46b79846c | ||
|
|
6636cb9f2f | ||
|
|
1e7672acf4 | ||
|
|
8596f2b0fc | ||
|
|
538d28e29e | ||
|
|
574ff0a280 | ||
|
|
51e568f9dc | ||
|
|
582f4db59b | ||
|
|
5116eee108 | ||
|
|
7ddc1adefb | ||
|
|
266dff9bed | ||
|
|
7f8b076f2b | ||
|
|
36ac557df0 | ||
|
|
013013737f | ||
|
|
b8e2b2bd6b | ||
|
|
71eb4034eb | ||
|
|
c142540705 | ||
|
|
3930472f34 | ||
|
|
6d03f93067 | ||
|
|
0e884304ee | ||
|
|
9085c2cae2 | ||
|
|
e8568f3ec9 | ||
|
|
16a9488c13 | ||
|
|
ea0399414c | ||
|
|
1abb02fb67 | ||
|
|
fbaf65b8f6 | ||
|
|
f2c7f3b200 | ||
|
|
1b579a110d | ||
|
|
7e00cde8a9 | ||
|
|
1ecc1db226 | ||
|
|
a7ace918fe | ||
|
|
91ac93f9a6 | ||
|
|
05c3e0b898 | ||
|
|
103c5edaaa | ||
|
|
75de34e281 | ||
|
|
f032ad6b1f | ||
|
|
871727dd2f | ||
|
|
3ff13edad9 | ||
|
|
7d80a8f4f5 | ||
|
|
3c80d57dc7 | ||
|
|
bb1e6f8af6 | ||
|
|
8432d1bfc7 | ||
|
|
7e2d172ae5 | ||
|
|
3bde375078 | ||
|
|
365b639981 | ||
|
|
d4fc525614 | ||
|
|
5be649e082 | ||
|
|
4b4be11fd2 | ||
|
|
e7bfcb970e | ||
|
|
7794b104c5 | ||
|
|
3b828e6f96 | ||
|
|
bbe946fb6c | ||
|
|
377f730054 | ||
|
|
f5528001f6 | ||
|
|
f68075b333 | ||
|
|
f1b5c742ff | ||
|
|
7e068da2bd | ||
|
|
44174b1fa1 | ||
|
|
861f786d81 | ||
|
|
f6951bb67d | ||
|
|
3b1b5266e5 | ||
|
|
c163b856d7 | ||
|
|
07eb7adbb4 | ||
|
|
4c108d22f0 | ||
|
|
c706ff6f3a | ||
|
|
992736dc5d | ||
|
|
927580d4a8 | ||
|
|
a1e4af62d3 | ||
|
|
28dd8d7efd | ||
|
|
4dff49b2f1 | ||
|
|
71a58261f6 | ||
|
|
8d1b82d596 | ||
|
|
3096e7a9cd | ||
|
|
1c3a9c8e74 | ||
|
|
813e0c18e6 | ||
|
|
3a82994429 | ||
|
|
106184bbea | ||
|
|
3895363432 | ||
|
|
a1e43c682a | ||
|
|
c3fd4ae473 | ||
|
|
69b5c2f541 | ||
|
|
a704614b3e | ||
|
|
6024051a2f | ||
|
|
b3e94f5de8 | ||
|
|
32380a0112 | ||
|
|
664fb38e39 | ||
|
|
0cbb96895a | ||
|
|
7b77cb3bb8 | ||
|
|
6faad0c34f | ||
|
|
05c1f2795a | ||
|
|
7feccf9ab2 | ||
|
|
bf4880f6a2 | ||
|
|
e0c0e53edf | ||
|
|
6994bf10bc | ||
|
|
3233d85d2f | ||
|
|
13f00331da | ||
|
|
af93c21cf9 | ||
|
|
cf98290873 | ||
|
|
1ca6ff974c | ||
|
|
575df6f192 | ||
|
|
0bdc145343 | ||
|
|
d049a7988c | ||
|
|
a4af3cc814 | ||
|
|
a89a3cd2f1 | ||
|
|
09780b8b3d | ||
|
|
9e294be5c5 | ||
|
|
a01d149369 | ||
|
|
483534b525 | ||
|
|
e1fca8d982 | ||
|
|
10a202422a | ||
|
|
27431dcc6b | ||
|
|
d8f9f6ba2a | ||
|
|
72090b646f | ||
|
|
aedcd2fb1a | ||
|
|
76ccbb899d | ||
|
|
5d87ee8d82 | ||
|
|
451c756b01 | ||
|
|
3aa9aae0be | ||
|
|
967073ba3d | ||
|
|
b8d8355f10 | ||
|
|
07c52a25ff | ||
|
|
cb2de62bb1 | ||
|
|
949a9fa2cb | ||
|
|
a1164399b0 | ||
|
|
e5b905481d | ||
|
|
7c183dc6a1 | ||
|
|
7fbd72b735 | ||
|
|
969278fc0b | ||
|
|
efc4c0fe9d | ||
|
|
81b24bd728 | ||
|
|
db2581bee9 | ||
|
|
75136d3bea | ||
|
|
0e6a096afd | ||
|
|
6f8d34768d | ||
|
|
9cda3035fd | ||
|
|
47f5ad32b7 | ||
|
|
9f35ba8546 | ||
|
|
7fd34d4f30 | ||
|
|
bb2aa5e770 | ||
|
|
56e10f1c35 | ||
|
|
718e15c7de | ||
|
|
8bc6d976cb | ||
|
|
dd80db87a6 | ||
|
|
1f54c16f52 | ||
|
|
50d421fa19 | ||
|
|
adbbd17cb6 | ||
|
|
3e8eebfbec | ||
|
|
2cbc0f1287 | ||
|
|
e2c1f0a7cd | ||
|
|
ca43436cd3 | ||
|
|
b27fd87177 | ||
|
|
07d3083279 | ||
|
|
d3d998a885 | ||
|
|
5f409c6fcc | ||
|
|
63310acd58 | ||
|
|
e6850891cc | ||
|
|
440ad0b440 | ||
|
|
5cdd788f30 | ||
|
|
596d81a973 | ||
|
|
84f3ecc231 | ||
|
|
cc48f1e5dd | ||
|
|
8dc04a4c9f | ||
|
|
c72040a715 | ||
|
|
c7c1bf177b | ||
|
|
5b0e59d9d5 | ||
|
|
7c06d9f043 | ||
|
|
511e32e8ca | ||
|
|
e5dfa0855f | ||
|
|
afad952450 | ||
|
|
fda1365c15 | ||
|
|
04022114d9 | ||
|
|
1575a3fbcd | ||
|
|
7e772f6a51 | ||
|
|
2e5860b5a0 | ||
|
|
4158cba1ff | ||
|
|
b955e485f1 | ||
|
|
02d6d2d487 | ||
|
|
b668726a38 | ||
|
|
835a8b2c9b | ||
|
|
239c8732d7 | ||
|
|
9bf3f910c8 | ||
|
|
e6c982509d | ||
|
|
9ddb8493d5 | ||
|
|
76e61958fd | ||
|
|
4f22a45cb5 | ||
|
|
825b61e4ba | ||
|
|
7e67aba286 | ||
|
|
a649d904d7 | ||
|
|
dfb82d5c22 | ||
|
|
d0fb547dc1 | ||
|
|
20f0cb0281 | ||
|
|
03b64defa5 | ||
|
|
655ebe4eaf | ||
|
|
b89202824e | ||
|
|
f70eacee8e | ||
|
|
433a7556c7 | ||
|
|
712203dbcb | ||
|
|
800fb26606 | ||
|
|
224f087a5f | ||
|
|
092426bed2 | ||
|
|
c6f1b7b92a | ||
|
|
328e4fa7e7 | ||
|
|
f3110a57cd | ||
|
|
cf029b3e1c | ||
|
|
7056032483 | ||
|
|
50ceb25003 | ||
|
|
9c364b16ff | ||
|
|
d61caf5714 | ||
|
|
e70f866ed2 | ||
|
|
9acb158990 | ||
|
|
1ba79baab5 | ||
|
|
01de69de36 | ||
|
|
8ec24036d7 | ||
|
|
29269d2aa8 | ||
|
|
43a85dd02e | ||
|
|
9ba64f9fe3 | ||
|
|
49fb8e6c45 | ||
|
|
9bf6509c6e | ||
|
|
5af385ea78 | ||
|
|
47219dd5c6 | ||
|
|
b6ae8a0dca | ||
|
|
a33d45d7cd | ||
|
|
5a665e423c | ||
|
|
fc95da8aa3 | ||
|
|
fd5859ed04 | ||
|
|
75e3793f4d | ||
|
|
8d4b5fef1d | ||
|
|
04a9ce3a18 | ||
|
|
87883abd86 | ||
|
|
f20725eada | ||
|
|
26646f2450 | ||
|
|
f208fd7ebb | ||
|
|
9350158d61 | ||
|
|
7a5196601e | ||
|
|
c7619d4a6a | ||
|
|
7ba774a440 | ||
|
|
b1af4d36ce | ||
|
|
c3f20f6b81 | ||
|
|
e7dca4fec2 | ||
|
|
9afb849e16 | ||
|
|
e1acb0b1fa | ||
|
|
3ead9820f7 | ||
|
|
f7db4fad31 | ||
|
|
cf4fcc4735 | ||
|
|
3eedb542a6 | ||
|
|
ecf7666624 | ||
|
|
d77d3416d3 | ||
|
|
5ce93bc0cc | ||
|
|
54a129a2e2 | ||
|
|
bdf60dac6a | ||
|
|
bbb543fc16 | ||
|
|
28d8eb220b | ||
|
|
0a6c5bc234 | ||
|
|
e91d275b10 | ||
|
|
8b8ab1db5b | ||
|
|
e02d6014bf | ||
|
|
8414c0bb09 | ||
|
|
49eb5f0280 | ||
|
|
7a536f1bd2 | ||
|
|
ff0c6c2bde | ||
|
|
4eecf80a4b | ||
|
|
104294c7e4 | ||
|
|
6b43a314bf | ||
|
|
8915f7933a | ||
|
|
87ded34f9f | ||
|
|
ff0f9aa856 | ||
|
|
9dc02464a4 | ||
|
|
7573d10a4a | ||
|
|
5412cdf2c8 | ||
|
|
3de440fda2 | ||
|
|
5bf9029bf9 | ||
|
|
09c9bf2edb | ||
|
|
b46076458c | ||
|
|
8691b56136 | ||
|
|
7f6a025c93 | ||
|
|
2cada3c143 | ||
|
|
4a3a895be9 | ||
|
|
f6fbb99a9c | ||
|
|
be107ba8f8 | ||
|
|
f902435a53 | ||
|
|
80d51c692a | ||
|
|
7227454dca | ||
|
|
f087359621 | ||
|
|
e215809c4d | ||
|
|
03b0266b59 | ||
|
|
d1c45c0d76 | ||
|
|
e30babef09 | ||
|
|
a608156da3 | ||
|
|
65a2350a5f | ||
|
|
cbf24a9151 | ||
|
|
f906d53f7d | ||
|
|
1f2bdd37b3 | ||
|
|
dc8ff68871 | ||
|
|
5536edede9 | ||
|
|
578e15f006 | ||
|
|
e1143377c2 | ||
|
|
8563ef3ce4 | ||
|
|
37fb531d1c | ||
|
|
86d3bba157 | ||
|
|
2ccc6d2ed1 | ||
|
|
13a5f5ba8b | ||
|
|
737a3644fc | ||
|
|
07ff47bf1b | ||
|
|
0737433c71 | ||
|
|
0bda7f196d | ||
|
|
9f96fcff3c | ||
|
|
bfacbac7c4 | ||
|
|
86fce79a6c | ||
|
|
c81a5a6070 | ||
|
|
0947fa3de0 | ||
|
|
cb9a6b8a8b | ||
|
|
2d21a64fed | ||
|
|
f94af2f5c5 | ||
|
|
8079344cee | ||
|
|
82e31d34f0 | ||
|
|
acdb4823dd | ||
|
|
b5144e477f | ||
|
|
e9c625a1dc | ||
|
|
d1851ed6b7 | ||
|
|
32c4e01267 | ||
|
|
2f9bae140b | ||
|
|
8a45c56c2c | ||
|
|
9391a97fbf | ||
|
|
79d497edae | ||
|
|
515ad62335 | ||
|
|
73353fad64 | ||
|
|
ff4bd758ca | ||
|
|
e24674fc0e | ||
|
|
529fccd9c2 | ||
|
|
4ee4f65c70 | ||
|
|
7cc86d4bc9 | ||
|
|
8011197c50 | ||
|
|
c96aaef132 | ||
|
|
6b32570644 | ||
|
|
5af930f97a | ||
|
|
515ecbddc2 | ||
|
|
7f7e8eeecd | ||
|
|
4e98d4329b | ||
|
|
5278da98d2 | ||
|
|
e1ed27aeaa | ||
|
|
c8349d3305 | ||
|
|
606175b98f | ||
|
|
05bc323be0 | ||
|
|
599a52629a | ||
|
|
c3efccaa9c | ||
|
|
b26f16a27f | ||
|
|
a0c2e55e8c | ||
|
|
5aebfedfad | ||
|
|
ce1626a51e | ||
|
|
0cabe4dedf | ||
|
|
0d6e3ab2b0 | ||
|
|
cfcad42b89 | ||
|
|
4a6f95acc8 | ||
|
|
5305c32242 | ||
|
|
951c9dd68b | ||
|
|
4ea9fdbbea | ||
|
|
e194219f2e | ||
|
|
a71d3c8cb3 | ||
|
|
238321c159 | ||
|
|
e181b0c3fc | ||
|
|
9d0bc3f9ab | ||
|
|
afe9c5c5f7 | ||
|
|
81a2546cea | ||
|
|
ee5560a958 | ||
|
|
62cfdceac1 | ||
|
|
d9fda22763 | ||
|
|
8dd83c5fe8 | ||
|
|
5794c0491a | ||
|
|
e043b89814 | ||
|
|
8fc19d2194 | ||
|
|
02501f07c3 | ||
|
|
a0e5bb9532 | ||
|
|
088ef6623a | ||
|
|
9c916cdaf9 | ||
|
|
ac9512e095 | ||
|
|
5d20da1b36 | ||
|
|
9b09c7597f | ||
|
|
2a1e903f43 | ||
|
|
e50894c95e | ||
|
|
991b16cc6a | ||
|
|
2886e0b6f5 | ||
|
|
067b691fd8 | ||
|
|
c40feabe4d | ||
|
|
2d4018aa89 | ||
|
|
e6439e1a16 | ||
|
|
26b9e2d0a5 | ||
|
|
3a5e758ee3 | ||
|
|
f768727284 | ||
|
|
a03846bd9e | ||
|
|
f3a0b17bb8 | ||
|
|
ac52d9d44c | ||
|
|
e2082a675c | ||
|
|
b94f0241f1 | ||
|
|
b96b1f2412 | ||
|
|
6644f1ff64 | ||
|
|
8cac70d8af | ||
|
|
5105c6c0d0 | ||
|
|
3a678d48b1 | ||
|
|
8bac6d428d | ||
|
|
2da200fc16 | ||
|
|
f6b6ad1959 | ||
|
|
3e84f7cd1d | ||
|
|
ac10889bde | ||
|
|
89a530b442 | ||
|
|
65e579e558 | ||
|
|
34e18ef771 | ||
|
|
8289e5f6b4 | ||
|
|
025e00cccc | ||
|
|
f78b5a0cdb | ||
|
|
ec49a486c7 | ||
|
|
afeefadb4e | ||
|
|
a423f032ee | ||
|
|
4ef06f5aa2 | ||
|
|
753223bd7b | ||
|
|
f663277591 | ||
|
|
1c7be88a1a | ||
|
|
3c114b280a | ||
|
|
2fbbcaa339 | ||
|
|
36cbe1e521 | ||
|
|
19d17ed274 | ||
|
|
01f940dc9a | ||
|
|
19c4fa8dd5 | ||
|
|
3bcc25f588 | ||
|
|
4cadb57c46 | ||
|
|
99c32ed4a5 | ||
|
|
c08b4b46f4 | ||
|
|
e138a5fcb5 | ||
|
|
fc16e54612 | ||
|
|
4575354bc0 | ||
|
|
3f51c831de | ||
|
|
962dcb466d | ||
|
|
b8d9c5c130 | ||
|
|
1a0d2578a1 | ||
|
|
12a1e7d04e | ||
|
|
4a8efd7e68 | ||
|
|
66cfbbff5e | ||
|
|
d23c69d319 | ||
|
|
1e7b50aeae | ||
|
|
c93e92671a | ||
|
|
ddc3f8f069 | ||
|
|
5261e5a6ba | ||
|
|
379733aba1 | ||
|
|
131de7ab62 | ||
|
|
d8ab2c1ac9 | ||
|
|
862781b195 | ||
|
|
cae4d020dc | ||
|
|
1f78e08427 | ||
|
|
760c1d95b9 | ||
|
|
510f0e505c | ||
|
|
d9c54826bb | ||
|
|
2515413080 | ||
|
|
d87b80c6c1 | ||
|
|
4a43f347bb | ||
|
|
dcbf976a8e | ||
|
|
f2d577c33f | ||
|
|
ae34241f8b | ||
|
|
1546153ca2 | ||
|
|
a3d6554e8e | ||
|
|
565af90958 | ||
|
|
797f2044cd | ||
|
|
5ea08394f5 | ||
|
|
9ee86f22b7 | ||
|
|
52ca91ca57 | ||
|
|
168af9b377 | ||
|
|
1a6eea012d | ||
|
|
50f6e12d31 | ||
|
|
c547b2e8ee | ||
|
|
56ba60ee68 | ||
|
|
f270c81c49 | ||
|
|
745fda081e | ||
|
|
5f8c9ae0ef | ||
|
|
056af2b1af | ||
|
|
5f79a28a07 | ||
|
|
69db792bf0 | ||
|
|
8b956216b7 | ||
|
|
e6cc547a94 | ||
|
|
e73217d6f7 | ||
|
|
2eaf5b03df | ||
|
|
c398153b40 | ||
|
|
33994bbfa1 | ||
|
|
7525637804 | ||
|
|
15ec78e9d8 | ||
|
|
3a7828de6b | ||
|
|
7b3433c68b | ||
|
|
84507cc744 | ||
|
|
cb76c086e0 | ||
|
|
407822e6a5 | ||
|
|
4e30698706 | ||
|
|
2dd8338e7d | ||
|
|
059560d28b | ||
|
|
d348d86df4 | ||
|
|
1d3862b6b3 | ||
|
|
bd82539ad5 | ||
|
|
83f55c9de5 | ||
|
|
33b88a0339 | ||
|
|
44bfa24cc3 | ||
|
|
2cff3f6a65 | ||
|
|
b48ed9ebc0 | ||
|
|
4e717b524c | ||
|
|
ae657a349a | ||
|
|
ed3c015f4e | ||
|
|
9cfc40c2cc | ||
|
|
6ebc63d3ef | ||
|
|
1ae0a1e658 | ||
|
|
46dff42239 | ||
|
|
35d1fb7b34 | ||
|
|
876a3299fc | ||
|
|
93896d550e | ||
|
|
18ffb7dd86 | ||
|
|
c0a89f8f4e | ||
|
|
c6193d0605 | ||
|
|
6cc380fc41 | ||
|
|
4053d9d638 | ||
|
|
45731cca19 | ||
|
|
dc92431328 | ||
|
|
d3e8e5731a | ||
|
|
53a5d32df1 | ||
|
|
85e1e2b0c8 | ||
|
|
9960ccddb2 | ||
|
|
4021776d0f | ||
|
|
fa0ce4b7d5 | ||
|
|
2a5ce1849a | ||
|
|
ae4b838840 | ||
|
|
79c075ca09 | ||
|
|
1127804109 | ||
|
|
67be485e24 | ||
|
|
fda57f48d5 | ||
|
|
840652830d | ||
|
|
5eabf44021 | ||
|
|
599d5f185c | ||
|
|
7abc368927 | ||
|
|
b57baa5ba0 | ||
|
|
3e47978a80 | ||
|
|
e647f89c33 | ||
|
|
82978fc88f | ||
|
|
95d49c3b98 | ||
|
|
455dc6e229 | ||
|
|
291bfe6841 | ||
|
|
35032d41fa | ||
|
|
28094b7cea | ||
|
|
b55b9aee9b | ||
|
|
0f1c21a6c9 | ||
|
|
175bab4f5f | ||
|
|
ba7b68798d | ||
|
|
e32256b4b4 | ||
|
|
132d8c5a99 | ||
|
|
b85f345369 | ||
|
|
85a3fb3bef | ||
|
|
6d91055462 | ||
|
|
136fc56af0 | ||
|
|
c355ed1267 | ||
|
|
1cefc48f13 | ||
|
|
211a9c8fd2 | ||
|
|
f29b3b4033 | ||
|
|
df65d4a14f | ||
|
|
c4e26f4b92 | ||
|
|
416918429d | ||
|
|
d5692bff00 | ||
|
|
dcef0c0237 | ||
|
|
a68c98bb67 | ||
|
|
b872aa5c8e | ||
|
|
a82be53407 | ||
|
|
49533bc86e | ||
|
|
e381f22ac1 | ||
|
|
9ac1e93aa1 | ||
|
|
bd5b38e232 | ||
|
|
5adcb9ce6d | ||
|
|
2ec135c9f7 | ||
|
|
58d46e1fe6 | ||
|
|
c039a77d21 | ||
|
|
741bdf151a | ||
|
|
5070c769b8 | ||
|
|
52e0de84a9 | ||
|
|
b974fffea0 | ||
|
|
a2616c79fe | ||
|
|
31b5b18611 | ||
|
|
8601c39571 | ||
|
|
af27ec296b | ||
|
|
a848807847 | ||
|
|
bdb30d7145 | ||
|
|
897e5c6231 | ||
|
|
1007873d94 | ||
|
|
fd201a90f1 | ||
|
|
a52ce7ac8b | ||
|
|
fd90afef43 | ||
|
|
5207afa0dd | ||
|
|
0699310b9c | ||
|
|
0c24fe276c | ||
|
|
c83391262e | ||
|
|
00262d51ad | ||
|
|
d7c04ccbfb | ||
|
|
b1f263b34b | ||
|
|
a58e4dfd0f | ||
|
|
18d6490dbd | ||
|
|
346f83e014 | ||
|
|
fefcc77f13 | ||
|
|
b6cdfef442 | ||
|
|
172e426ba9 | ||
|
|
f74d9ec7f7 | ||
|
|
9093166eea | ||
|
|
f5ed5478e1 | ||
|
|
9a4234ea8e | ||
|
|
af002dc861 | ||
|
|
adeb993122 | ||
|
|
81bc4265e5 | ||
|
|
a44c5f7afe | ||
|
|
66b51940bd | ||
|
|
d4e49a2697 | ||
|
|
521405488b | ||
|
|
24dfa0c957 | ||
|
|
158a65c98f | ||
|
|
6caf074bd5 | ||
|
|
905e14f384 | ||
|
|
4be79a8955 | ||
|
|
2d952504ed | ||
|
|
43219d36a6 | ||
|
|
99b27488e7 | ||
|
|
18972c5513 | ||
|
|
e312363007 | ||
|
|
6c34bffbb5 | ||
|
|
36b2f64051 | ||
|
|
705ff49400 | ||
|
|
f81caac459 | ||
|
|
0ada716184 | ||
|
|
e9c849884a | ||
|
|
a4191857c1 | ||
|
|
9d7480774f | ||
|
|
5d630c930d | ||
|
|
9852649e97 | ||
|
|
1722a31155 | ||
|
|
e5f2295398 | ||
|
|
8ef0ca9765 | ||
|
|
c031ea088a | ||
|
|
9824bf1ba1 | ||
|
|
0095b7a0ea | ||
|
|
6b4f6cd2c5 | ||
|
|
1b646a4440 | ||
|
|
f22024cb19 | ||
|
|
049c515840 | ||
|
|
352695bc57 | ||
|
|
74077491ce | ||
|
|
23b67e6ff5 | ||
|
|
7b4fbf4301 | ||
|
|
b8b74970d7 | ||
|
|
defbf1c4b3 | ||
|
|
16c6734bcb | ||
|
|
ee98a069f0 | ||
|
|
b30b82835a | ||
|
|
d107146687 | ||
|
|
88df66ec83 | ||
|
|
ce18371d1b | ||
|
|
9dea27b273 | ||
|
|
140ece0aeb | ||
|
|
7abf72ec78 | ||
|
|
574185426c | ||
|
|
dd61c4802a | ||
|
|
14cef31467 | ||
|
|
6277781e83 | ||
|
|
770cba0bd0 | ||
|
|
c38fe6b0e1 | ||
|
|
d3ee3e7ab5 | ||
|
|
ce500f8727 | ||
|
|
9a5f742e63 | ||
|
|
7e6700d261 | ||
|
|
c71522adc5 | ||
|
|
70b0bd13aa | ||
|
|
087ab2acbf | ||
|
|
24aeca3d0c | ||
|
|
9660657e95 | ||
|
|
13a3a2d0f3 | ||
|
|
ff4f40de41 | ||
|
|
24fc7c30dd | ||
|
|
06aa9d8d9a | ||
|
|
8c374512fd | ||
|
|
77d51ebf24 | ||
|
|
93b032ea92 | ||
|
|
03c8a78f04 | ||
|
|
002e513b82 | ||
|
|
ed84b2aaeb | ||
|
|
1176460e44 | ||
|
|
01429e7d16 | ||
|
|
4c35e00f49 | ||
|
|
7f960616e0 | ||
|
|
1cafdb5b46 | ||
|
|
b0fb340b57 | ||
|
|
85f3ba844c | ||
|
|
090eb437ed | ||
|
|
d574604a5d | ||
|
|
6eacddb50f | ||
|
|
4ff23d3306 | ||
|
|
c7687fc1d6 | ||
|
|
c47d34cf70 | ||
|
|
cd51f37fc0 | ||
|
|
da70c837da | ||
|
|
f1ae07e532 | ||
|
|
d9cd494eaf | ||
|
|
5979233a3c | ||
|
|
0b1d6a0d52 | ||
|
|
7b433605f9 | ||
|
|
3b9b1956cd | ||
|
|
7a41e0b1ea | ||
|
|
cc882b0723 | ||
|
|
6d6580f6be | ||
|
|
7684f53328 | ||
|
|
e3e4b7bdf5 | ||
|
|
679f4882a5 | ||
|
|
cb78e62df9 | ||
|
|
376f2aec54 | ||
|
|
010757266e | ||
|
|
d268471285 | ||
|
|
423577e14e | ||
|
|
f1c31ebc67 | ||
|
|
4433ce4312 | ||
|
|
456bbffcc4 | ||
|
|
17a7f352b5 | ||
|
|
637d9c42bf | ||
|
|
1c385c2ca4 | ||
|
|
25f25d546d | ||
|
|
6ac50634e3 | ||
|
|
50e453a3e2 | ||
|
|
4649bf042e | ||
|
|
2bd0ee27f0 | ||
|
|
0d16492eb7 | ||
|
|
2ae19801a9 | ||
|
|
950539b768 | ||
|
|
f270d6c52c | ||
|
|
22d6f00110 | ||
|
|
38e357ef10 | ||
|
|
0b7f3edc26 | ||
|
|
285269ef55 | ||
|
|
e25da4230b | ||
|
|
8be6f40ae1 | ||
|
|
83bd3595a4 | ||
|
|
32ee0a3947 | ||
|
|
7ddc22b326 | ||
|
|
0d5042f0f3 | ||
|
|
0eaddb4dcd | ||
|
|
74a11e2087 | ||
|
|
d4dd448511 | ||
|
|
56ad2a2d74 | ||
|
|
f421e73b40 | ||
|
|
72899318e6 | ||
|
|
84c6ea0cee | ||
|
|
c23b5463c7 | ||
|
|
9d8bc79025 | ||
|
|
0cad274b87 | ||
|
|
ac8931b2e9 | ||
|
|
4f112f898e | ||
|
|
e5ba982be0 | ||
|
|
200754b013 | ||
|
|
42ad3c1dd3 | ||
|
|
172570acae | ||
|
|
c29971cf72 | ||
|
|
ccc9a22db3 | ||
|
|
c00523dba4 | ||
|
|
9d5ec05150 | ||
|
|
2fecd332fc | ||
|
|
0e09032750 | ||
|
|
46b61427e1 | ||
|
|
bcf4ed28a9 | ||
|
|
6cfc9e6256 | ||
|
|
1ab236d9df | ||
|
|
2e1ac0f683 | ||
|
|
8364d1ca6c | ||
|
|
09d8943967 | ||
|
|
6e58a95a01 | ||
|
|
207ad45983 | ||
|
|
83ef61fa56 | ||
|
|
d0e0b106f0 | ||
|
|
98b66a5fc9 | ||
|
|
921bb92eec | ||
|
|
c50198debe | ||
|
|
6371474031 | ||
|
|
8657201257 | ||
|
|
b88492746e | ||
|
|
f6fc28dfd2 | ||
|
|
cdeef65b05 | ||
|
|
1e81a53e75 | ||
|
|
5e63711084 | ||
|
|
a2fbcc9ad4 | ||
|
|
10030ff3ec | ||
|
|
648735a4cf | ||
|
|
a4629b0b36 | ||
|
|
64cbbed152 | ||
|
|
43f375b2f2 | ||
|
|
1eb89d7e3b | ||
|
|
4d46383100 | ||
|
|
aa3fe81c87 | ||
|
|
9ea16e344a | ||
|
|
d8719cf59b | ||
|
|
9dcc07422e | ||
|
|
52c78820aa | ||
|
|
19b92751b9 | ||
|
|
f318f2d5ea | ||
|
|
21ff03978a | ||
|
|
25fd9d6132 | ||
|
|
3637193556 | ||
|
|
8e3274e137 | ||
|
|
c4a158656e | ||
|
|
e026c8d3b7 | ||
|
|
cab41d954e | ||
|
|
e0cbfd74d7 | ||
|
|
426930e028 | ||
|
|
e9fa17e1bf | ||
|
|
b807347e94 | ||
|
|
7113fc7dee | ||
|
|
e0f283cfcb | ||
|
|
7b968b098e | ||
|
|
e927a6ac4a | ||
|
|
9da475e4e8 | ||
|
|
5b282bdd48 | ||
|
|
fc80f2b41a | ||
|
|
68e9ef9885 | ||
|
|
296db2ed33 | ||
|
|
3171d61dfc | ||
|
|
00b9e70ba2 | ||
|
|
57e9f61852 | ||
|
|
cf365ed00b | ||
|
|
d98a5d54aa | ||
|
|
8074d56bdd | ||
|
|
fc3c3de70d | ||
|
|
997d1bd0eb | ||
|
|
baef79415b | ||
|
|
cb601d79e8 | ||
|
|
4cee46f909 | ||
|
|
25349b31d7 | ||
|
|
735267d27c | ||
|
|
b5ced477f4 | ||
|
|
67319a71e5 | ||
|
|
184a6f1198 | ||
|
|
b32bb4e6e3 | ||
|
|
0e62b7d68a | ||
|
|
a761779b12 | ||
|
|
29510fcb83 | ||
|
|
3f335b0d42 | ||
|
|
ffda84cfae | ||
|
|
e6bc840f6f | ||
|
|
0b26387a2b | ||
|
|
f7ef10e547 | ||
|
|
91cadc1130 | ||
|
|
47d1360124 | ||
|
|
f67699456c | ||
|
|
387f724d33 | ||
|
|
bcdfd5d61c | ||
|
|
e660d92fa5 | ||
|
|
9fdf72e42b | ||
|
|
df9051ded2 | ||
|
|
230c5ca735 | ||
|
|
3bd3693fb7 | ||
|
|
45cbebad64 | ||
|
|
6d0f9244b8 | ||
|
|
80a8aea7e3 | ||
|
|
4f0db01f7c | ||
|
|
6cd4e30b58 | ||
|
|
19540479d4 | ||
|
|
90dffb5a06 | ||
|
|
ef521d1e0b | ||
|
|
42c32bf00c | ||
|
|
c8a9969511 | ||
|
|
b0a8734c92 | ||
|
|
8d0723c2c3 |
1
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
1
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1 @@
|
||||
blank_issues_enabled: false
|
||||
90
.github/ISSUE_TEMPLATE/issue_template.yml
vendored
Normal file
90
.github/ISSUE_TEMPLATE/issue_template.yml
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
name: "Ask a question, report a bug, request a feature, etc."
|
||||
description: "Ask any question, discuss best practices, report a bug, request a feature."
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
FOR FIRST-TIME USERS ISSUES COMPILING/LINKING/RUNNING or LOADING FONTS, please use [GitHub Discussions](https://github.com/ocornut/imgui/discussions)
|
||||
For anything else: we are happy to use 'GitHub Issues' for many types of open-ended questions. We are encouraging 'Issues' becoming a large, centralized and cross-referenced database of Dear ImGui contents.
|
||||
|
||||
Be mindful that messages are being sent to the e-mail box of "Watching" users. Try to proof-read your messages before sending them. Edits are not seen by those users.
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
**Prerequisites:**
|
||||
- I have read [Frequently Asked Questions](https://github.com/ocornut/imgui/blob/master/docs/FAQ.md).
|
||||
- I have read [Contributing Guidelines -> General Advices](https://github.com/ocornut/imgui/blob/master/docs/CONTRIBUTING.md#getting-started--general-advice).
|
||||
- I have read [Contributing Guidelines -> How to open an Issue](https://github.com/ocornut/imgui/blob/master/docs/CONTRIBUTING.md#how-to-open-an-issue).
|
||||
- I have searched [Github Issues and PR](https://github.com/ocornut/imgui/issues?q=) for discussion of similar topics.
|
||||
|
||||
----
|
||||
- type: input
|
||||
id: specs_version
|
||||
attributes:
|
||||
label: "Version/Branch of Dear ImGui:"
|
||||
description: "(please specify if you have made substantial modifications to your copy)"
|
||||
value: "Version 1.XX, Branch: XXX (master/docking/etc.)"
|
||||
placeholder: "Version 1.XX, Branch: XXX (master/docking/etc.)"
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: specs_backend
|
||||
attributes:
|
||||
label: "Back-ends:"
|
||||
description: (or specify when using custom engine/back-ends)
|
||||
value: "imgui_impl_XXX.cpp + imgui_impl_XXX.cpp"
|
||||
placeholder: "imgui_impl_XXX.cpp + imgui_impl_XXX.cpp or n/a"
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: specs_compiler_os
|
||||
attributes:
|
||||
label: "Compiler, OS:"
|
||||
placeholder: "e.g. Windows 11 + MSVC 2022, macOS + Clang 12, Linux + GCC etc."
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: specs_full
|
||||
attributes:
|
||||
label: "Full config/build information:"
|
||||
placeholder: |
|
||||
(If you can run, you may go to 'Demo->Tools->About Dear ImGui->Config/Build Info' to obtain detailed information that you can paste here)
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
id: issue_description
|
||||
attributes:
|
||||
label: "Details:"
|
||||
description: "Try to be explicit with your goals, your expectations and what you have tried. Be mindful of [The XY Problem](https://xyproblem.info). What you have in mind or in your code is not obvious to other people. People frequently discuss problems and suggest incorrect solutions without first clarifying their goals. When requesting a new feature, please describe the usage context (how you intend to use it, why you need it, etc.). If you tried something and it failed, show us what you tried. If you are reporting a bug, explain what's the bug, how does it occur, etc. If you are reporting a crash, please include a debugger callstack."
|
||||
value: |
|
||||
**My Issue/Question:**
|
||||
|
||||
XXX _(please provide as much context as possible)_
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: screenshots
|
||||
attributes:
|
||||
label: "Screenshots/Video:"
|
||||
description: "Attach screenshots or gif/videos to clarify the context. They often convey useful information that is omitted by the description."
|
||||
placeholder: "(You can drag files here)"
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
id: repro_code
|
||||
attributes:
|
||||
label: "Minimal, Complete and Verifiable Example code:"
|
||||
description: "Provide an [MCVE](https://stackoverflow.com/help/mcve) to demonstrate your problem. An ideal submission includes a small piece of code that anyone can paste into one of the examples applications (examples/*/main.cpp) or the demo (imgui_demo.cpp) to understand and reproduce it. Narrowing your problem to its shortest and purest form is the easiest way to understand it, explain it and fix it. Please test your shortened code to ensure it exhibits the problem. Often while creating the MCVE you will solve the problem! Many questions that are missing a standalone verifiable example are missing the actual cause of their issue in the description, which ends up wasting everyone's time."
|
||||
value: |
|
||||
```cpp
|
||||
// Here's some code anyone can copy and paste to reproduce your issue
|
||||
ImGui::Begin("Example Bug");
|
||||
MoreCodeToExplainMyIssue();
|
||||
ImGui::End();
|
||||
```
|
||||
validations:
|
||||
required: false
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thank you for taking the time to read prerequisites, filling this template and double-checking your message and your code!
|
||||
46
.github/issue_template.md
vendored
46
.github/issue_template.md
vendored
@@ -1,46 +0,0 @@
|
||||
(Click "Preview" above ^ to turn URL into clickable links)
|
||||
|
||||
1. FOR FIRST-TIME USERS PROBLEMS COMPILING/LINKING/RUNNING or LOADING FONTS, please use [GitHub Discussions](https://github.com/ocornut/imgui/discussions). EVERYTHING ELSE CAN BE POSTED HERE!
|
||||
|
||||
2. PLEASE CAREFULLY READ: [FAQ](https://github.com/ocornut/imgui/blob/master/docs/FAQ.md)
|
||||
|
||||
3. PLEASE CAREFULLY READ: [Contributing Guidelines](https://github.com/ocornut/imgui/blob/master/docs/CONTRIBUTING.md)
|
||||
|
||||
4. PLEASE MAKE SURE that you have: read the FAQ; explored the contents of `ShowDemoWindow()` including the Examples menu; searched among Issues; used your IDE to search for keywords in all sources and text files; and read the links above.
|
||||
|
||||
5. Be mindful that messages are being sent to the e-mail box of "Watching" users. Try to proof-read your messages before sending them. Edits are not seen by those users.
|
||||
|
||||
6. Delete points 1-6 and PLEASE FILL THE TEMPLATE BELOW before submitting your issue.
|
||||
|
||||
Thank you!
|
||||
|
||||
----
|
||||
|
||||
_(you may also go to Demo>About Window, and click "Config/Build Information" to obtain a bunch of detailed information that you can paste here)_
|
||||
|
||||
**Version/Branch of Dear ImGui:**
|
||||
|
||||
Version: XXX
|
||||
Branch: XXX _(master/viewport/docking/etc.)_
|
||||
|
||||
**Back-end/Renderer/Compiler/OS**
|
||||
|
||||
Back-ends: imgui_impl_XXX.cpp + imgui_impl_XXX.cpp _(or specify if using a custom engine/back-end)_
|
||||
Compiler: XXX _(if the question is related to building or platform specific features)_
|
||||
Operating System: XXX
|
||||
|
||||
**My Issue/Question:**
|
||||
|
||||
XXX _(please provide as much context as possible)_
|
||||
|
||||
**Screenshots/Video**
|
||||
|
||||
XXX _(you can drag files here)_
|
||||
|
||||
**Standalone, minimal, complete and verifiable example:** _(see https://github.com/ocornut/imgui/issues/2261)_
|
||||
```
|
||||
// Here's some code anyone can copy and paste to reproduce your issue
|
||||
ImGui::Begin("Example Bug");
|
||||
MoreCodeToExplainMyIssue();
|
||||
ImGui::End();
|
||||
```
|
||||
@@ -1,6 +1,6 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-2023 Omar Cornut
|
||||
Copyright (c) 2014-2024 Omar Cornut
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy ALLEGRO_KEY_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
||||
// [X] Platform: Clipboard support (from Allegro 5.1.12)
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// Issues:
|
||||
// Missing features:
|
||||
// [ ] Renderer: Multi-viewport support (multiple windows)..
|
||||
// [ ] Renderer: The renderer is suboptimal as we need to convert vertices manually.
|
||||
// [ ] Platform: Missing gamepad support.
|
||||
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy ALLEGRO_KEY_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
||||
// [X] Platform: Clipboard support (from Allegro 5.1.12)
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// Issues:
|
||||
// Missing features:
|
||||
// [ ] Renderer: Multi-viewport support (multiple windows)..
|
||||
// [ ] Renderer: The renderer is suboptimal as we need to unindex our buffers and convert vertices manually.
|
||||
// [ ] Platform: Missing gamepad support.
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
// [ ] Platform: Clipboard support.
|
||||
// [ ] Platform: Gamepad support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [ ] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. FIXME: Check if this is even possible with Android.
|
||||
// [ ] Platform: Multi-viewport support (multiple windows). Not meaningful on Android.
|
||||
// Important:
|
||||
// - Consider using SDL or GLFW backend on Android, which will be more full-featured than this.
|
||||
// - FIXME: On-screen keyboard currently needs to be enabled by the application (see examples/ and issue #3446)
|
||||
@@ -156,7 +157,7 @@ static ImGuiKey ImGui_ImplAndroid_KeyCodeToImGuiKey(int32_t key_code)
|
||||
}
|
||||
}
|
||||
|
||||
int32_t ImGui_ImplAndroid_HandleInputEvent(AInputEvent* input_event)
|
||||
int32_t ImGui_ImplAndroid_HandleInputEvent(const AInputEvent* input_event)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
int32_t event_type = AInputEvent_getType(input_event);
|
||||
@@ -183,7 +184,7 @@ int32_t ImGui_ImplAndroid_HandleInputEvent(AInputEvent* input_event)
|
||||
case AKEY_EVENT_ACTION_UP:
|
||||
{
|
||||
ImGuiKey key = ImGui_ImplAndroid_KeyCodeToImGuiKey(event_key_code);
|
||||
if (key != ImGuiKey_None && (event_action == AKEY_EVENT_ACTION_DOWN || event_action == AKEY_EVENT_ACTION_UP))
|
||||
if (key != ImGuiKey_None)
|
||||
{
|
||||
io.AddKeyEvent(key, event_action == AKEY_EVENT_ACTION_DOWN);
|
||||
io.SetKeyEventNativeData(key, event_key_code, event_scan_code);
|
||||
@@ -221,25 +222,27 @@ int32_t ImGui_ImplAndroid_HandleInputEvent(AInputEvent* input_event)
|
||||
{
|
||||
case AMOTION_EVENT_ACTION_DOWN:
|
||||
case AMOTION_EVENT_ACTION_UP:
|
||||
{
|
||||
// Physical mouse buttons (and probably other physical devices) also invoke the actions AMOTION_EVENT_ACTION_DOWN/_UP,
|
||||
// but we have to process them separately to identify the actual button pressed. This is done below via
|
||||
// AMOTION_EVENT_ACTION_BUTTON_PRESS/_RELEASE. Here, we only process "FINGER" input (and "UNKNOWN", as a fallback).
|
||||
if((AMotionEvent_getToolType(input_event, event_pointer_index) == AMOTION_EVENT_TOOL_TYPE_FINGER)
|
||||
|| (AMotionEvent_getToolType(input_event, event_pointer_index) == AMOTION_EVENT_TOOL_TYPE_UNKNOWN))
|
||||
int tool_type = AMotionEvent_getToolType(input_event, event_pointer_index);
|
||||
if (tool_type == AMOTION_EVENT_TOOL_TYPE_FINGER || tool_type == AMOTION_EVENT_TOOL_TYPE_UNKNOWN)
|
||||
{
|
||||
io.AddMousePosEvent(AMotionEvent_getX(input_event, event_pointer_index), AMotionEvent_getY(input_event, event_pointer_index));
|
||||
io.AddMouseButtonEvent(0, event_action == AMOTION_EVENT_ACTION_DOWN);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AMOTION_EVENT_ACTION_BUTTON_PRESS:
|
||||
case AMOTION_EVENT_ACTION_BUTTON_RELEASE:
|
||||
{
|
||||
int32_t button_state = AMotionEvent_getButtonState(input_event);
|
||||
io.AddMouseButtonEvent(0, (button_state & AMOTION_EVENT_BUTTON_PRIMARY) != 0);
|
||||
io.AddMouseButtonEvent(1, (button_state & AMOTION_EVENT_BUTTON_SECONDARY) != 0);
|
||||
io.AddMouseButtonEvent(2, (button_state & AMOTION_EVENT_BUTTON_TERTIARY) != 0);
|
||||
}
|
||||
{
|
||||
int32_t button_state = AMotionEvent_getButtonState(input_event);
|
||||
io.AddMouseButtonEvent(0, (button_state & AMOTION_EVENT_BUTTON_PRIMARY) != 0);
|
||||
io.AddMouseButtonEvent(1, (button_state & AMOTION_EVENT_BUTTON_SECONDARY) != 0);
|
||||
io.AddMouseButtonEvent(2, (button_state & AMOTION_EVENT_BUTTON_TERTIARY) != 0);
|
||||
break;
|
||||
}
|
||||
case AMOTION_EVENT_ACTION_HOVER_MOVE: // Hovering: Tool moves while NOT pressed (such as a physical mouse)
|
||||
case AMOTION_EVENT_ACTION_MOVE: // Touch pointer moves while DOWN
|
||||
io.AddMousePosEvent(AMotionEvent_getX(input_event, event_pointer_index), AMotionEvent_getY(input_event, event_pointer_index));
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
// [ ] Platform: Clipboard support.
|
||||
// [ ] Platform: Gamepad support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [ ] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. FIXME: Check if this is even possible with Android.
|
||||
// [ ] Platform: Multi-viewport support (multiple windows). Not meaningful on Android.
|
||||
// Important:
|
||||
// - Consider using SDL or GLFW backend on Android, which will be more full-featured than this.
|
||||
// - FIXME: On-screen keyboard currently needs to be enabled by the application (see examples/ and issue #3446)
|
||||
@@ -29,7 +30,7 @@ struct ANativeWindow;
|
||||
struct AInputEvent;
|
||||
|
||||
IMGUI_IMPL_API bool ImGui_ImplAndroid_Init(ANativeWindow* window);
|
||||
IMGUI_IMPL_API int32_t ImGui_ImplAndroid_HandleInputEvent(AInputEvent* input_event);
|
||||
IMGUI_IMPL_API int32_t ImGui_ImplAndroid_HandleInputEvent(const AInputEvent* input_event);
|
||||
IMGUI_IMPL_API void ImGui_ImplAndroid_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplAndroid_NewFrame();
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'ID3D10ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
@@ -15,6 +16,7 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2023-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
|
||||
// 2021-05-19: DirectX10: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
|
||||
@@ -79,6 +81,10 @@ static ImGui_ImplDX10_Data* ImGui_ImplDX10_GetBackendData()
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplDX10_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||
}
|
||||
|
||||
// Forward Declarations
|
||||
static void ImGui_ImplDX10_InitPlatformInterface();
|
||||
static void ImGui_ImplDX10_ShutdownPlatformInterface();
|
||||
|
||||
// Functions
|
||||
static void ImGui_ImplDX10_SetupRenderState(ImDrawData* draw_data, ID3D10Device* ctx)
|
||||
{
|
||||
@@ -541,6 +547,7 @@ bool ImGui_ImplDX10_Init(ID3D10Device* device)
|
||||
io.BackendRendererUserData = (void*)bd;
|
||||
io.BackendRendererName = "imgui_impl_dx10";
|
||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional)
|
||||
|
||||
// Get factory from device
|
||||
IDXGIDevice* pDXGIDevice = nullptr;
|
||||
@@ -557,6 +564,8 @@ bool ImGui_ImplDX10_Init(ID3D10Device* device)
|
||||
if (pDXGIAdapter) pDXGIAdapter->Release();
|
||||
bd->pd3dDevice->AddRef();
|
||||
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
ImGui_ImplDX10_InitPlatformInterface();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -566,12 +575,13 @@ void ImGui_ImplDX10_Shutdown()
|
||||
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
ImGui_ImplDX10_ShutdownPlatformInterface();
|
||||
ImGui_ImplDX10_InvalidateDeviceObjects();
|
||||
if (bd->pFactory) { bd->pFactory->Release(); }
|
||||
if (bd->pd3dDevice) { bd->pd3dDevice->Release(); }
|
||||
io.BackendRendererName = nullptr;
|
||||
io.BackendRendererUserData = nullptr;
|
||||
io.BackendFlags &= ~ImGuiBackendFlags_RendererHasVtxOffset;
|
||||
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasViewports);
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
@@ -584,6 +594,129 @@ void ImGui_ImplDX10_NewFrame()
|
||||
ImGui_ImplDX10_CreateDeviceObjects();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
|
||||
// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously.
|
||||
// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first..
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
|
||||
// Helper structure we store in the void* RendererUserData field of each ImGuiViewport to easily retrieve our backend data.
|
||||
struct ImGui_ImplDX10_ViewportData
|
||||
{
|
||||
IDXGISwapChain* SwapChain;
|
||||
ID3D10RenderTargetView* RTView;
|
||||
|
||||
ImGui_ImplDX10_ViewportData() { SwapChain = nullptr; RTView = nullptr; }
|
||||
~ImGui_ImplDX10_ViewportData() { IM_ASSERT(SwapChain == nullptr && RTView == nullptr); }
|
||||
};
|
||||
|
||||
static void ImGui_ImplDX10_CreateWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData();
|
||||
ImGui_ImplDX10_ViewportData* vd = IM_NEW(ImGui_ImplDX10_ViewportData)();
|
||||
viewport->RendererUserData = vd;
|
||||
|
||||
// PlatformHandleRaw should always be a HWND, whereas PlatformHandle might be a higher-level handle (e.g. GLFWWindow*, SDL_Window*).
|
||||
// Some backends will leave PlatformHandleRaw == 0, in which case we assume PlatformHandle will contain the HWND.
|
||||
HWND hwnd = viewport->PlatformHandleRaw ? (HWND)viewport->PlatformHandleRaw : (HWND)viewport->PlatformHandle;
|
||||
IM_ASSERT(hwnd != 0);
|
||||
|
||||
// Create swap chain
|
||||
DXGI_SWAP_CHAIN_DESC sd;
|
||||
ZeroMemory(&sd, sizeof(sd));
|
||||
sd.BufferDesc.Width = (UINT)viewport->Size.x;
|
||||
sd.BufferDesc.Height = (UINT)viewport->Size.y;
|
||||
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
sd.SampleDesc.Count = 1;
|
||||
sd.SampleDesc.Quality = 0;
|
||||
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
sd.BufferCount = 1;
|
||||
sd.OutputWindow = hwnd;
|
||||
sd.Windowed = TRUE;
|
||||
sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
|
||||
sd.Flags = 0;
|
||||
|
||||
IM_ASSERT(vd->SwapChain == nullptr && vd->RTView == nullptr);
|
||||
bd->pFactory->CreateSwapChain(bd->pd3dDevice, &sd, &vd->SwapChain);
|
||||
|
||||
// Create the render target
|
||||
if (vd->SwapChain)
|
||||
{
|
||||
ID3D10Texture2D* pBackBuffer;
|
||||
vd->SwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer));
|
||||
bd->pd3dDevice->CreateRenderTargetView(pBackBuffer, nullptr, &vd->RTView);
|
||||
pBackBuffer->Release();
|
||||
}
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX10_DestroyWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
// The main viewport (owned by the application) will always have RendererUserData == 0 here since we didn't create the data for it.
|
||||
if (ImGui_ImplDX10_ViewportData* vd = (ImGui_ImplDX10_ViewportData*)viewport->RendererUserData)
|
||||
{
|
||||
if (vd->SwapChain)
|
||||
vd->SwapChain->Release();
|
||||
vd->SwapChain = nullptr;
|
||||
if (vd->RTView)
|
||||
vd->RTView->Release();
|
||||
vd->RTView = nullptr;
|
||||
IM_DELETE(vd);
|
||||
}
|
||||
viewport->RendererUserData = nullptr;
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX10_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
|
||||
{
|
||||
ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData();
|
||||
ImGui_ImplDX10_ViewportData* vd = (ImGui_ImplDX10_ViewportData*)viewport->RendererUserData;
|
||||
if (vd->RTView)
|
||||
{
|
||||
vd->RTView->Release();
|
||||
vd->RTView = nullptr;
|
||||
}
|
||||
if (vd->SwapChain)
|
||||
{
|
||||
ID3D10Texture2D* pBackBuffer = nullptr;
|
||||
vd->SwapChain->ResizeBuffers(0, (UINT)size.x, (UINT)size.y, DXGI_FORMAT_UNKNOWN, 0);
|
||||
vd->SwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer));
|
||||
if (pBackBuffer == nullptr) { fprintf(stderr, "ImGui_ImplDX10_SetWindowSize() failed creating buffers.\n"); return; }
|
||||
bd->pd3dDevice->CreateRenderTargetView(pBackBuffer, nullptr, &vd->RTView);
|
||||
pBackBuffer->Release();
|
||||
}
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX10_RenderViewport(ImGuiViewport* viewport, void*)
|
||||
{
|
||||
ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData();
|
||||
ImGui_ImplDX10_ViewportData* vd = (ImGui_ImplDX10_ViewportData*)viewport->RendererUserData;
|
||||
ImVec4 clear_color = ImVec4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
bd->pd3dDevice->OMSetRenderTargets(1, &vd->RTView, nullptr);
|
||||
if (!(viewport->Flags & ImGuiViewportFlags_NoRendererClear))
|
||||
bd->pd3dDevice->ClearRenderTargetView(vd->RTView, (float*)&clear_color);
|
||||
ImGui_ImplDX10_RenderDrawData(viewport->DrawData);
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX10_SwapBuffers(ImGuiViewport* viewport, void*)
|
||||
{
|
||||
ImGui_ImplDX10_ViewportData* vd = (ImGui_ImplDX10_ViewportData*)viewport->RendererUserData;
|
||||
vd->SwapChain->Present(0, 0); // Present without vsync
|
||||
}
|
||||
|
||||
void ImGui_ImplDX10_InitPlatformInterface()
|
||||
{
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
platform_io.Renderer_CreateWindow = ImGui_ImplDX10_CreateWindow;
|
||||
platform_io.Renderer_DestroyWindow = ImGui_ImplDX10_DestroyWindow;
|
||||
platform_io.Renderer_SetWindowSize = ImGui_ImplDX10_SetWindowSize;
|
||||
platform_io.Renderer_RenderWindow = ImGui_ImplDX10_RenderViewport;
|
||||
platform_io.Renderer_SwapBuffers = ImGui_ImplDX10_SwapBuffers;
|
||||
}
|
||||
|
||||
void ImGui_ImplDX10_ShutdownPlatformInterface()
|
||||
{
|
||||
ImGui::DestroyPlatformWindows();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'ID3D10ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
@@ -15,6 +16,7 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2023-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
|
||||
// 2021-05-19: DirectX11: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
|
||||
@@ -80,6 +82,10 @@ static ImGui_ImplDX11_Data* ImGui_ImplDX11_GetBackendData()
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplDX11_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||
}
|
||||
|
||||
// Forward Declarations
|
||||
static void ImGui_ImplDX11_InitPlatformInterface();
|
||||
static void ImGui_ImplDX11_ShutdownPlatformInterface();
|
||||
|
||||
// Functions
|
||||
static void ImGui_ImplDX11_SetupRenderState(ImDrawData* draw_data, ID3D11DeviceContext* ctx)
|
||||
{
|
||||
@@ -553,6 +559,7 @@ bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_co
|
||||
io.BackendRendererUserData = (void*)bd;
|
||||
io.BackendRendererName = "imgui_impl_dx11";
|
||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional)
|
||||
|
||||
// Get factory from device
|
||||
IDXGIDevice* pDXGIDevice = nullptr;
|
||||
@@ -572,6 +579,9 @@ bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_co
|
||||
bd->pd3dDevice->AddRef();
|
||||
bd->pd3dDeviceContext->AddRef();
|
||||
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
ImGui_ImplDX11_InitPlatformInterface();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -581,13 +591,14 @@ void ImGui_ImplDX11_Shutdown()
|
||||
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
ImGui_ImplDX11_ShutdownPlatformInterface();
|
||||
ImGui_ImplDX11_InvalidateDeviceObjects();
|
||||
if (bd->pFactory) { bd->pFactory->Release(); }
|
||||
if (bd->pd3dDevice) { bd->pd3dDevice->Release(); }
|
||||
if (bd->pd3dDeviceContext) { bd->pd3dDeviceContext->Release(); }
|
||||
io.BackendRendererName = nullptr;
|
||||
io.BackendRendererUserData = nullptr;
|
||||
io.BackendFlags &= ~ImGuiBackendFlags_RendererHasVtxOffset;
|
||||
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasViewports);
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
@@ -600,6 +611,129 @@ void ImGui_ImplDX11_NewFrame()
|
||||
ImGui_ImplDX11_CreateDeviceObjects();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
|
||||
// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously.
|
||||
// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first..
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
|
||||
// Helper structure we store in the void* RendererUserData field of each ImGuiViewport to easily retrieve our backend data.
|
||||
struct ImGui_ImplDX11_ViewportData
|
||||
{
|
||||
IDXGISwapChain* SwapChain;
|
||||
ID3D11RenderTargetView* RTView;
|
||||
|
||||
ImGui_ImplDX11_ViewportData() { SwapChain = nullptr; RTView = nullptr; }
|
||||
~ImGui_ImplDX11_ViewportData() { IM_ASSERT(SwapChain == nullptr && RTView == nullptr); }
|
||||
};
|
||||
|
||||
static void ImGui_ImplDX11_CreateWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||
ImGui_ImplDX11_ViewportData* vd = IM_NEW(ImGui_ImplDX11_ViewportData)();
|
||||
viewport->RendererUserData = vd;
|
||||
|
||||
// PlatformHandleRaw should always be a HWND, whereas PlatformHandle might be a higher-level handle (e.g. GLFWWindow*, SDL_Window*).
|
||||
// Some backends will leave PlatformHandleRaw == 0, in which case we assume PlatformHandle will contain the HWND.
|
||||
HWND hwnd = viewport->PlatformHandleRaw ? (HWND)viewport->PlatformHandleRaw : (HWND)viewport->PlatformHandle;
|
||||
IM_ASSERT(hwnd != 0);
|
||||
|
||||
// Create swap chain
|
||||
DXGI_SWAP_CHAIN_DESC sd;
|
||||
ZeroMemory(&sd, sizeof(sd));
|
||||
sd.BufferDesc.Width = (UINT)viewport->Size.x;
|
||||
sd.BufferDesc.Height = (UINT)viewport->Size.y;
|
||||
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
sd.SampleDesc.Count = 1;
|
||||
sd.SampleDesc.Quality = 0;
|
||||
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
sd.BufferCount = 1;
|
||||
sd.OutputWindow = hwnd;
|
||||
sd.Windowed = TRUE;
|
||||
sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
|
||||
sd.Flags = 0;
|
||||
|
||||
IM_ASSERT(vd->SwapChain == nullptr && vd->RTView == nullptr);
|
||||
bd->pFactory->CreateSwapChain(bd->pd3dDevice, &sd, &vd->SwapChain);
|
||||
|
||||
// Create the render target
|
||||
if (vd->SwapChain)
|
||||
{
|
||||
ID3D11Texture2D* pBackBuffer;
|
||||
vd->SwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer));
|
||||
bd->pd3dDevice->CreateRenderTargetView(pBackBuffer, nullptr, &vd->RTView);
|
||||
pBackBuffer->Release();
|
||||
}
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX11_DestroyWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
// The main viewport (owned by the application) will always have RendererUserData == nullptr since we didn't create the data for it.
|
||||
if (ImGui_ImplDX11_ViewportData* vd = (ImGui_ImplDX11_ViewportData*)viewport->RendererUserData)
|
||||
{
|
||||
if (vd->SwapChain)
|
||||
vd->SwapChain->Release();
|
||||
vd->SwapChain = nullptr;
|
||||
if (vd->RTView)
|
||||
vd->RTView->Release();
|
||||
vd->RTView = nullptr;
|
||||
IM_DELETE(vd);
|
||||
}
|
||||
viewport->RendererUserData = nullptr;
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX11_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
|
||||
{
|
||||
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||
ImGui_ImplDX11_ViewportData* vd = (ImGui_ImplDX11_ViewportData*)viewport->RendererUserData;
|
||||
if (vd->RTView)
|
||||
{
|
||||
vd->RTView->Release();
|
||||
vd->RTView = nullptr;
|
||||
}
|
||||
if (vd->SwapChain)
|
||||
{
|
||||
ID3D11Texture2D* pBackBuffer = nullptr;
|
||||
vd->SwapChain->ResizeBuffers(0, (UINT)size.x, (UINT)size.y, DXGI_FORMAT_UNKNOWN, 0);
|
||||
vd->SwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer));
|
||||
if (pBackBuffer == nullptr) { fprintf(stderr, "ImGui_ImplDX11_SetWindowSize() failed creating buffers.\n"); return; }
|
||||
bd->pd3dDevice->CreateRenderTargetView(pBackBuffer, nullptr, &vd->RTView);
|
||||
pBackBuffer->Release();
|
||||
}
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX11_RenderWindow(ImGuiViewport* viewport, void*)
|
||||
{
|
||||
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||
ImGui_ImplDX11_ViewportData* vd = (ImGui_ImplDX11_ViewportData*)viewport->RendererUserData;
|
||||
ImVec4 clear_color = ImVec4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
bd->pd3dDeviceContext->OMSetRenderTargets(1, &vd->RTView, nullptr);
|
||||
if (!(viewport->Flags & ImGuiViewportFlags_NoRendererClear))
|
||||
bd->pd3dDeviceContext->ClearRenderTargetView(vd->RTView, (float*)&clear_color);
|
||||
ImGui_ImplDX11_RenderDrawData(viewport->DrawData);
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX11_SwapBuffers(ImGuiViewport* viewport, void*)
|
||||
{
|
||||
ImGui_ImplDX11_ViewportData* vd = (ImGui_ImplDX11_ViewportData*)viewport->RendererUserData;
|
||||
vd->SwapChain->Present(0, 0); // Present without vsync
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX11_InitPlatformInterface()
|
||||
{
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
platform_io.Renderer_CreateWindow = ImGui_ImplDX11_CreateWindow;
|
||||
platform_io.Renderer_DestroyWindow = ImGui_ImplDX11_DestroyWindow;
|
||||
platform_io.Renderer_SetWindowSize = ImGui_ImplDX11_SetWindowSize;
|
||||
platform_io.Renderer_RenderWindow = ImGui_ImplDX11_RenderWindow;
|
||||
platform_io.Renderer_SwapBuffers = ImGui_ImplDX11_SwapBuffers;
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX11_ShutdownPlatformInterface()
|
||||
{
|
||||
ImGui::DestroyPlatformWindows();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'D3D12_GPU_DESCRIPTOR_HANDLE' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
// FIXME: The transition from removing a viewport and moving the window in an existing hosted viewport tends to flicker.
|
||||
|
||||
// Important: to compile on 32-bit systems, this backend requires code to be compiled with '#define ImTextureID ImU64'.
|
||||
// This is because we need ImTextureID to carry a 64-bit value and by default ImTextureID is defined as void*.
|
||||
@@ -23,6 +25,7 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2023-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
|
||||
// 2021-05-19: DirectX12: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
|
||||
@@ -54,7 +57,6 @@
|
||||
#endif
|
||||
|
||||
// DirectX data
|
||||
struct ImGui_ImplDX12_RenderBuffers;
|
||||
struct ImGui_ImplDX12_Data
|
||||
{
|
||||
ID3D12Device* pd3dDevice;
|
||||
@@ -67,10 +69,7 @@ struct ImGui_ImplDX12_Data
|
||||
ID3D12DescriptorHeap* pd3dSrvDescHeap;
|
||||
UINT numFramesInFlight;
|
||||
|
||||
ImGui_ImplDX12_RenderBuffers* pFrameResources;
|
||||
UINT frameIndex;
|
||||
|
||||
ImGui_ImplDX12_Data() { memset((void*)this, 0, sizeof(*this)); frameIndex = UINT_MAX; }
|
||||
ImGui_ImplDX12_Data() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts
|
||||
@@ -89,11 +88,88 @@ struct ImGui_ImplDX12_RenderBuffers
|
||||
int VertexBufferSize;
|
||||
};
|
||||
|
||||
// Buffers used for secondary viewports created by the multi-viewports systems
|
||||
struct ImGui_ImplDX12_FrameContext
|
||||
{
|
||||
ID3D12CommandAllocator* CommandAllocator;
|
||||
ID3D12Resource* RenderTarget;
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE RenderTargetCpuDescriptors;
|
||||
};
|
||||
|
||||
// Helper structure we store in the void* RendererUserData field of each ImGuiViewport to easily retrieve our backend data.
|
||||
// Main viewport created by application will only use the Resources field.
|
||||
// Secondary viewports created by this backend will use all the fields (including Window fields),
|
||||
struct ImGui_ImplDX12_ViewportData
|
||||
{
|
||||
// Window
|
||||
ID3D12CommandQueue* CommandQueue;
|
||||
ID3D12GraphicsCommandList* CommandList;
|
||||
ID3D12DescriptorHeap* RtvDescHeap;
|
||||
IDXGISwapChain3* SwapChain;
|
||||
ID3D12Fence* Fence;
|
||||
UINT64 FenceSignaledValue;
|
||||
HANDLE FenceEvent;
|
||||
UINT NumFramesInFlight;
|
||||
ImGui_ImplDX12_FrameContext* FrameCtx;
|
||||
|
||||
// Render buffers
|
||||
UINT FrameIndex;
|
||||
ImGui_ImplDX12_RenderBuffers* FrameRenderBuffers;
|
||||
|
||||
ImGui_ImplDX12_ViewportData(UINT num_frames_in_flight)
|
||||
{
|
||||
CommandQueue = nullptr;
|
||||
CommandList = nullptr;
|
||||
RtvDescHeap = nullptr;
|
||||
SwapChain = nullptr;
|
||||
Fence = nullptr;
|
||||
FenceSignaledValue = 0;
|
||||
FenceEvent = nullptr;
|
||||
NumFramesInFlight = num_frames_in_flight;
|
||||
FrameCtx = new ImGui_ImplDX12_FrameContext[NumFramesInFlight];
|
||||
FrameIndex = UINT_MAX;
|
||||
FrameRenderBuffers = new ImGui_ImplDX12_RenderBuffers[NumFramesInFlight];
|
||||
|
||||
for (UINT i = 0; i < NumFramesInFlight; ++i)
|
||||
{
|
||||
FrameCtx[i].CommandAllocator = nullptr;
|
||||
FrameCtx[i].RenderTarget = nullptr;
|
||||
|
||||
// Create buffers with a default size (they will later be grown as needed)
|
||||
FrameRenderBuffers[i].IndexBuffer = nullptr;
|
||||
FrameRenderBuffers[i].VertexBuffer = nullptr;
|
||||
FrameRenderBuffers[i].VertexBufferSize = 5000;
|
||||
FrameRenderBuffers[i].IndexBufferSize = 10000;
|
||||
}
|
||||
}
|
||||
~ImGui_ImplDX12_ViewportData()
|
||||
{
|
||||
IM_ASSERT(CommandQueue == nullptr && CommandList == nullptr);
|
||||
IM_ASSERT(RtvDescHeap == nullptr);
|
||||
IM_ASSERT(SwapChain == nullptr);
|
||||
IM_ASSERT(Fence == nullptr);
|
||||
IM_ASSERT(FenceEvent == nullptr);
|
||||
|
||||
for (UINT i = 0; i < NumFramesInFlight; ++i)
|
||||
{
|
||||
IM_ASSERT(FrameCtx[i].CommandAllocator == nullptr && FrameCtx[i].RenderTarget == nullptr);
|
||||
IM_ASSERT(FrameRenderBuffers[i].IndexBuffer == nullptr && FrameRenderBuffers[i].VertexBuffer == nullptr);
|
||||
}
|
||||
|
||||
delete[] FrameCtx; FrameCtx = nullptr;
|
||||
delete[] FrameRenderBuffers; FrameRenderBuffers = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
struct VERTEX_CONSTANT_BUFFER_DX12
|
||||
{
|
||||
float mvp[4][4];
|
||||
};
|
||||
|
||||
// Forward Declarations
|
||||
static void ImGui_ImplDX12_InitPlatformInterface();
|
||||
static void ImGui_ImplDX12_ShutdownPlatformInterface();
|
||||
|
||||
// Functions
|
||||
static void ImGui_ImplDX12_SetupRenderState(ImDrawData* draw_data, ID3D12GraphicsCommandList* ctx, ImGui_ImplDX12_RenderBuffers* fr)
|
||||
{
|
||||
@@ -167,11 +243,10 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
|
||||
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
|
||||
return;
|
||||
|
||||
// FIXME: I'm assuming that this only gets called once per frame!
|
||||
// If not, we can't just re-allocate the IB or VB, we'll have to do a proper allocator.
|
||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||
bd->frameIndex = bd->frameIndex + 1;
|
||||
ImGui_ImplDX12_RenderBuffers* fr = &bd->pFrameResources[bd->frameIndex % bd->numFramesInFlight];
|
||||
ImGui_ImplDX12_ViewportData* vd = (ImGui_ImplDX12_ViewportData*)draw_data->OwnerViewport->RendererUserData;
|
||||
vd->FrameIndex++;
|
||||
ImGui_ImplDX12_RenderBuffers* fr = &vd->FrameRenderBuffers[vd->FrameIndex % bd->numFramesInFlight];
|
||||
|
||||
// Create and grow vertex/index buffers if needed
|
||||
if (fr->VertexBuffer == nullptr || fr->VertexBufferSize < draw_data->TotalVtxCount)
|
||||
@@ -678,6 +753,13 @@ bool ImGui_ImplDX12_CreateDeviceObjects()
|
||||
return true;
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX12_DestroyRenderBuffers(ImGui_ImplDX12_RenderBuffers* render_buffers)
|
||||
{
|
||||
SafeRelease(render_buffers->IndexBuffer);
|
||||
SafeRelease(render_buffers->VertexBuffer);
|
||||
render_buffers->IndexBufferSize = render_buffers->VertexBufferSize = 0;
|
||||
}
|
||||
|
||||
void ImGui_ImplDX12_InvalidateDeviceObjects()
|
||||
{
|
||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||
@@ -689,13 +771,6 @@ void ImGui_ImplDX12_InvalidateDeviceObjects()
|
||||
SafeRelease(bd->pPipelineState);
|
||||
SafeRelease(bd->pFontTextureResource);
|
||||
io.Fonts->SetTexID(0); // We copied bd->pFontTextureView to io.Fonts->TexID so let's clear that as well.
|
||||
|
||||
for (UINT i = 0; i < bd->numFramesInFlight; i++)
|
||||
{
|
||||
ImGui_ImplDX12_RenderBuffers* fr = &bd->pFrameResources[i];
|
||||
SafeRelease(fr->IndexBuffer);
|
||||
SafeRelease(fr->VertexBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames_in_flight, DXGI_FORMAT rtv_format, ID3D12DescriptorHeap* cbv_srv_heap,
|
||||
@@ -709,25 +784,21 @@ bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames_in_flight, DXGI_FO
|
||||
io.BackendRendererUserData = (void*)bd;
|
||||
io.BackendRendererName = "imgui_impl_dx12";
|
||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional)
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
ImGui_ImplDX12_InitPlatformInterface();
|
||||
|
||||
bd->pd3dDevice = device;
|
||||
bd->RTVFormat = rtv_format;
|
||||
bd->hFontSrvCpuDescHandle = font_srv_cpu_desc_handle;
|
||||
bd->hFontSrvGpuDescHandle = font_srv_gpu_desc_handle;
|
||||
bd->pFrameResources = new ImGui_ImplDX12_RenderBuffers[num_frames_in_flight];
|
||||
bd->numFramesInFlight = num_frames_in_flight;
|
||||
bd->pd3dSrvDescHeap = cbv_srv_heap;
|
||||
bd->frameIndex = UINT_MAX;
|
||||
|
||||
// Create buffers with a default size (they will later be grown as needed)
|
||||
for (int i = 0; i < num_frames_in_flight; i++)
|
||||
{
|
||||
ImGui_ImplDX12_RenderBuffers* fr = &bd->pFrameResources[i];
|
||||
fr->IndexBuffer = nullptr;
|
||||
fr->VertexBuffer = nullptr;
|
||||
fr->IndexBufferSize = 10000;
|
||||
fr->VertexBufferSize = 5000;
|
||||
}
|
||||
// Create a dummy ImGui_ImplDX12_ViewportData holder for the main viewport,
|
||||
// Since this is created and managed by the application, we will only use the ->Resources[] fields.
|
||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||
main_viewport->RendererUserData = IM_NEW(ImGui_ImplDX12_ViewportData)(bd->numFramesInFlight);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -738,12 +809,24 @@ void ImGui_ImplDX12_Shutdown()
|
||||
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
// Manually delete main viewport render resources in-case we haven't initialized for viewports
|
||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||
if (ImGui_ImplDX12_ViewportData* vd = (ImGui_ImplDX12_ViewportData*)main_viewport->RendererUserData)
|
||||
{
|
||||
// We could just call ImGui_ImplDX12_DestroyWindow(main_viewport) as a convenience but that would be misleading since we only use data->Resources[]
|
||||
for (UINT i = 0; i < bd->numFramesInFlight; i++)
|
||||
ImGui_ImplDX12_DestroyRenderBuffers(&vd->FrameRenderBuffers[i]);
|
||||
IM_DELETE(vd);
|
||||
main_viewport->RendererUserData = nullptr;
|
||||
}
|
||||
|
||||
// Clean up windows and device objects
|
||||
ImGui_ImplDX12_ShutdownPlatformInterface();
|
||||
ImGui_ImplDX12_InvalidateDeviceObjects();
|
||||
delete[] bd->pFrameResources;
|
||||
|
||||
io.BackendRendererName = nullptr;
|
||||
io.BackendRendererUserData = nullptr;
|
||||
io.BackendFlags &= ~ImGuiBackendFlags_RendererHasVtxOffset;
|
||||
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasViewports);
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
@@ -756,6 +839,246 @@ void ImGui_ImplDX12_NewFrame()
|
||||
ImGui_ImplDX12_CreateDeviceObjects();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
|
||||
// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously.
|
||||
// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first..
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
|
||||
static void ImGui_ImplDX12_CreateWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||
ImGui_ImplDX12_ViewportData* vd = IM_NEW(ImGui_ImplDX12_ViewportData)(bd->numFramesInFlight);
|
||||
viewport->RendererUserData = vd;
|
||||
|
||||
// PlatformHandleRaw should always be a HWND, whereas PlatformHandle might be a higher-level handle (e.g. GLFWWindow*, SDL_Window*).
|
||||
// Some backends will leave PlatformHandleRaw == 0, in which case we assume PlatformHandle will contain the HWND.
|
||||
HWND hwnd = viewport->PlatformHandleRaw ? (HWND)viewport->PlatformHandleRaw : (HWND)viewport->PlatformHandle;
|
||||
IM_ASSERT(hwnd != 0);
|
||||
|
||||
vd->FrameIndex = UINT_MAX;
|
||||
|
||||
// Create command queue.
|
||||
D3D12_COMMAND_QUEUE_DESC queue_desc = {};
|
||||
queue_desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
|
||||
queue_desc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
|
||||
|
||||
HRESULT res = S_OK;
|
||||
res = bd->pd3dDevice->CreateCommandQueue(&queue_desc, IID_PPV_ARGS(&vd->CommandQueue));
|
||||
IM_ASSERT(res == S_OK);
|
||||
|
||||
// Create command allocator.
|
||||
for (UINT i = 0; i < bd->numFramesInFlight; ++i)
|
||||
{
|
||||
res = bd->pd3dDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&vd->FrameCtx[i].CommandAllocator));
|
||||
IM_ASSERT(res == S_OK);
|
||||
}
|
||||
|
||||
// Create command list.
|
||||
res = bd->pd3dDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, vd->FrameCtx[0].CommandAllocator, nullptr, IID_PPV_ARGS(&vd->CommandList));
|
||||
IM_ASSERT(res == S_OK);
|
||||
vd->CommandList->Close();
|
||||
|
||||
// Create fence.
|
||||
res = bd->pd3dDevice->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&vd->Fence));
|
||||
IM_ASSERT(res == S_OK);
|
||||
|
||||
vd->FenceEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
|
||||
IM_ASSERT(vd->FenceEvent != nullptr);
|
||||
|
||||
// Create swap chain
|
||||
// FIXME-VIEWPORT: May want to copy/inherit swap chain settings from the user/application.
|
||||
DXGI_SWAP_CHAIN_DESC1 sd1;
|
||||
ZeroMemory(&sd1, sizeof(sd1));
|
||||
sd1.BufferCount = bd->numFramesInFlight;
|
||||
sd1.Width = (UINT)viewport->Size.x;
|
||||
sd1.Height = (UINT)viewport->Size.y;
|
||||
sd1.Format = bd->RTVFormat;
|
||||
sd1.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
sd1.SampleDesc.Count = 1;
|
||||
sd1.SampleDesc.Quality = 0;
|
||||
sd1.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
||||
sd1.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED;
|
||||
sd1.Scaling = DXGI_SCALING_NONE;
|
||||
sd1.Stereo = FALSE;
|
||||
|
||||
IDXGIFactory4* dxgi_factory = nullptr;
|
||||
res = ::CreateDXGIFactory1(IID_PPV_ARGS(&dxgi_factory));
|
||||
IM_ASSERT(res == S_OK);
|
||||
|
||||
IDXGISwapChain1* swap_chain = nullptr;
|
||||
res = dxgi_factory->CreateSwapChainForHwnd(vd->CommandQueue, hwnd, &sd1, nullptr, nullptr, &swap_chain);
|
||||
IM_ASSERT(res == S_OK);
|
||||
|
||||
dxgi_factory->Release();
|
||||
|
||||
// Or swapChain.As(&mSwapChain)
|
||||
IM_ASSERT(vd->SwapChain == nullptr);
|
||||
swap_chain->QueryInterface(IID_PPV_ARGS(&vd->SwapChain));
|
||||
swap_chain->Release();
|
||||
|
||||
// Create the render targets
|
||||
if (vd->SwapChain)
|
||||
{
|
||||
D3D12_DESCRIPTOR_HEAP_DESC desc = {};
|
||||
desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
|
||||
desc.NumDescriptors = bd->numFramesInFlight;
|
||||
desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
|
||||
desc.NodeMask = 1;
|
||||
|
||||
HRESULT hr = bd->pd3dDevice->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&vd->RtvDescHeap));
|
||||
IM_ASSERT(hr == S_OK);
|
||||
|
||||
SIZE_T rtv_descriptor_size = bd->pd3dDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE rtv_handle = vd->RtvDescHeap->GetCPUDescriptorHandleForHeapStart();
|
||||
for (UINT i = 0; i < bd->numFramesInFlight; i++)
|
||||
{
|
||||
vd->FrameCtx[i].RenderTargetCpuDescriptors = rtv_handle;
|
||||
rtv_handle.ptr += rtv_descriptor_size;
|
||||
}
|
||||
|
||||
ID3D12Resource* back_buffer;
|
||||
for (UINT i = 0; i < bd->numFramesInFlight; i++)
|
||||
{
|
||||
IM_ASSERT(vd->FrameCtx[i].RenderTarget == nullptr);
|
||||
vd->SwapChain->GetBuffer(i, IID_PPV_ARGS(&back_buffer));
|
||||
bd->pd3dDevice->CreateRenderTargetView(back_buffer, nullptr, vd->FrameCtx[i].RenderTargetCpuDescriptors);
|
||||
vd->FrameCtx[i].RenderTarget = back_buffer;
|
||||
}
|
||||
}
|
||||
|
||||
for (UINT i = 0; i < bd->numFramesInFlight; i++)
|
||||
ImGui_ImplDX12_DestroyRenderBuffers(&vd->FrameRenderBuffers[i]);
|
||||
}
|
||||
|
||||
static void ImGui_WaitForPendingOperations(ImGui_ImplDX12_ViewportData* vd)
|
||||
{
|
||||
HRESULT hr = S_FALSE;
|
||||
if (vd && vd->CommandQueue && vd->Fence && vd->FenceEvent)
|
||||
{
|
||||
hr = vd->CommandQueue->Signal(vd->Fence, ++vd->FenceSignaledValue);
|
||||
IM_ASSERT(hr == S_OK);
|
||||
::WaitForSingleObject(vd->FenceEvent, 0); // Reset any forgotten waits
|
||||
hr = vd->Fence->SetEventOnCompletion(vd->FenceSignaledValue, vd->FenceEvent);
|
||||
IM_ASSERT(hr == S_OK);
|
||||
::WaitForSingleObject(vd->FenceEvent, INFINITE);
|
||||
}
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX12_DestroyWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
// The main viewport (owned by the application) will always have RendererUserData == 0 since we didn't create the data for it.
|
||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||
if (ImGui_ImplDX12_ViewportData* vd = (ImGui_ImplDX12_ViewportData*)viewport->RendererUserData)
|
||||
{
|
||||
ImGui_WaitForPendingOperations(vd);
|
||||
|
||||
SafeRelease(vd->CommandQueue);
|
||||
SafeRelease(vd->CommandList);
|
||||
SafeRelease(vd->SwapChain);
|
||||
SafeRelease(vd->RtvDescHeap);
|
||||
SafeRelease(vd->Fence);
|
||||
::CloseHandle(vd->FenceEvent);
|
||||
vd->FenceEvent = nullptr;
|
||||
|
||||
for (UINT i = 0; i < bd->numFramesInFlight; i++)
|
||||
{
|
||||
SafeRelease(vd->FrameCtx[i].RenderTarget);
|
||||
SafeRelease(vd->FrameCtx[i].CommandAllocator);
|
||||
ImGui_ImplDX12_DestroyRenderBuffers(&vd->FrameRenderBuffers[i]);
|
||||
}
|
||||
IM_DELETE(vd);
|
||||
}
|
||||
viewport->RendererUserData = nullptr;
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX12_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
|
||||
{
|
||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||
ImGui_ImplDX12_ViewportData* vd = (ImGui_ImplDX12_ViewportData*)viewport->RendererUserData;
|
||||
|
||||
ImGui_WaitForPendingOperations(vd);
|
||||
|
||||
for (UINT i = 0; i < bd->numFramesInFlight; i++)
|
||||
SafeRelease(vd->FrameCtx[i].RenderTarget);
|
||||
|
||||
if (vd->SwapChain)
|
||||
{
|
||||
ID3D12Resource* back_buffer = nullptr;
|
||||
vd->SwapChain->ResizeBuffers(0, (UINT)size.x, (UINT)size.y, DXGI_FORMAT_UNKNOWN, 0);
|
||||
for (UINT i = 0; i < bd->numFramesInFlight; i++)
|
||||
{
|
||||
vd->SwapChain->GetBuffer(i, IID_PPV_ARGS(&back_buffer));
|
||||
bd->pd3dDevice->CreateRenderTargetView(back_buffer, nullptr, vd->FrameCtx[i].RenderTargetCpuDescriptors);
|
||||
vd->FrameCtx[i].RenderTarget = back_buffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX12_RenderWindow(ImGuiViewport* viewport, void*)
|
||||
{
|
||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||
ImGui_ImplDX12_ViewportData* vd = (ImGui_ImplDX12_ViewportData*)viewport->RendererUserData;
|
||||
|
||||
ImGui_ImplDX12_FrameContext* frame_context = &vd->FrameCtx[vd->FrameIndex % bd->numFramesInFlight];
|
||||
UINT back_buffer_idx = vd->SwapChain->GetCurrentBackBufferIndex();
|
||||
|
||||
const ImVec4 clear_color = ImVec4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
D3D12_RESOURCE_BARRIER barrier = {};
|
||||
barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
|
||||
barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
|
||||
barrier.Transition.pResource = vd->FrameCtx[back_buffer_idx].RenderTarget;
|
||||
barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
|
||||
barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT;
|
||||
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET;
|
||||
|
||||
// Draw
|
||||
ID3D12GraphicsCommandList* cmd_list = vd->CommandList;
|
||||
|
||||
frame_context->CommandAllocator->Reset();
|
||||
cmd_list->Reset(frame_context->CommandAllocator, nullptr);
|
||||
cmd_list->ResourceBarrier(1, &barrier);
|
||||
cmd_list->OMSetRenderTargets(1, &vd->FrameCtx[back_buffer_idx].RenderTargetCpuDescriptors, FALSE, nullptr);
|
||||
if (!(viewport->Flags & ImGuiViewportFlags_NoRendererClear))
|
||||
cmd_list->ClearRenderTargetView(vd->FrameCtx[back_buffer_idx].RenderTargetCpuDescriptors, (float*)&clear_color, 0, nullptr);
|
||||
cmd_list->SetDescriptorHeaps(1, &bd->pd3dSrvDescHeap);
|
||||
|
||||
ImGui_ImplDX12_RenderDrawData(viewport->DrawData, cmd_list);
|
||||
|
||||
barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET;
|
||||
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PRESENT;
|
||||
cmd_list->ResourceBarrier(1, &barrier);
|
||||
cmd_list->Close();
|
||||
|
||||
vd->CommandQueue->Wait(vd->Fence, vd->FenceSignaledValue);
|
||||
vd->CommandQueue->ExecuteCommandLists(1, (ID3D12CommandList* const*)&cmd_list);
|
||||
vd->CommandQueue->Signal(vd->Fence, ++vd->FenceSignaledValue);
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX12_SwapBuffers(ImGuiViewport* viewport, void*)
|
||||
{
|
||||
ImGui_ImplDX12_ViewportData* vd = (ImGui_ImplDX12_ViewportData*)viewport->RendererUserData;
|
||||
|
||||
vd->SwapChain->Present(0, 0);
|
||||
while (vd->Fence->GetCompletedValue() < vd->FenceSignaledValue)
|
||||
::SwitchToThread();
|
||||
}
|
||||
|
||||
void ImGui_ImplDX12_InitPlatformInterface()
|
||||
{
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
platform_io.Renderer_CreateWindow = ImGui_ImplDX12_CreateWindow;
|
||||
platform_io.Renderer_DestroyWindow = ImGui_ImplDX12_DestroyWindow;
|
||||
platform_io.Renderer_SetWindowSize = ImGui_ImplDX12_SetWindowSize;
|
||||
platform_io.Renderer_RenderWindow = ImGui_ImplDX12_RenderWindow;
|
||||
platform_io.Renderer_SwapBuffers = ImGui_ImplDX12_SwapBuffers;
|
||||
}
|
||||
|
||||
void ImGui_ImplDX12_ShutdownPlatformInterface()
|
||||
{
|
||||
ImGui::DestroyPlatformWindows();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'D3D12_GPU_DESCRIPTOR_HANDLE' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// Important: to compile on 32-bit systems, this backend requires code to be compiled with '#define ImTextureID ImU64'.
|
||||
// See imgui_impl_dx12.cpp file for details.
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'LPDIRECT3DTEXTURE9' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
@@ -15,6 +16,7 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2023-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
|
||||
// 2021-06-25: DirectX9: Explicitly disable texture state stages after >= 1.
|
||||
@@ -75,6 +77,12 @@ static ImGui_ImplDX9_Data* ImGui_ImplDX9_GetBackendData()
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplDX9_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||
}
|
||||
|
||||
// Forward Declarations
|
||||
static void ImGui_ImplDX9_InitPlatformInterface();
|
||||
static void ImGui_ImplDX9_ShutdownPlatformInterface();
|
||||
static void ImGui_ImplDX9_CreateDeviceObjectsForPlatformWindows();
|
||||
static void ImGui_ImplDX9_InvalidateDeviceObjectsForPlatformWindows();
|
||||
|
||||
// Functions
|
||||
static void ImGui_ImplDX9_SetupRenderState(ImDrawData* draw_data)
|
||||
{
|
||||
@@ -271,6 +279,11 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
|
||||
global_vtx_offset += cmd_list->VtxBuffer.Size;
|
||||
}
|
||||
|
||||
// When using multi-viewports, it appears that there's an odd logic in DirectX9 which prevent subsequent windows
|
||||
// from rendering until the first window submits at least one draw call, even once. That's our workaround. (see #2560)
|
||||
if (global_vtx_offset == 0)
|
||||
bd->pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 0, 0, 0);
|
||||
|
||||
// Restore the DX9 transform
|
||||
bd->pd3dDevice->SetTransform(D3DTS_WORLD, &last_world);
|
||||
bd->pd3dDevice->SetTransform(D3DTS_VIEW, &last_view);
|
||||
@@ -291,10 +304,14 @@ bool ImGui_ImplDX9_Init(IDirect3DDevice9* device)
|
||||
io.BackendRendererUserData = (void*)bd;
|
||||
io.BackendRendererName = "imgui_impl_dx9";
|
||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional)
|
||||
|
||||
bd->pd3dDevice = device;
|
||||
bd->pd3dDevice->AddRef();
|
||||
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
ImGui_ImplDX9_InitPlatformInterface();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -304,11 +321,12 @@ void ImGui_ImplDX9_Shutdown()
|
||||
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
ImGui_ImplDX9_ShutdownPlatformInterface();
|
||||
ImGui_ImplDX9_InvalidateDeviceObjects();
|
||||
if (bd->pd3dDevice) { bd->pd3dDevice->Release(); }
|
||||
io.BackendRendererName = nullptr;
|
||||
io.BackendRendererUserData = nullptr;
|
||||
io.BackendFlags &= ~ImGuiBackendFlags_RendererHasVtxOffset;
|
||||
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasViewports);
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
@@ -361,6 +379,7 @@ bool ImGui_ImplDX9_CreateDeviceObjects()
|
||||
return false;
|
||||
if (!ImGui_ImplDX9_CreateFontsTexture())
|
||||
return false;
|
||||
ImGui_ImplDX9_CreateDeviceObjectsForPlatformWindows();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -372,6 +391,7 @@ void ImGui_ImplDX9_InvalidateDeviceObjects()
|
||||
if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; }
|
||||
if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; }
|
||||
if (bd->FontTexture) { bd->FontTexture->Release(); bd->FontTexture = nullptr; ImGui::GetIO().Fonts->SetTexID(0); } // We copied bd->pFontTextureView to io.Fonts->TexID so let's clear that as well.
|
||||
ImGui_ImplDX9_InvalidateDeviceObjectsForPlatformWindows();
|
||||
}
|
||||
|
||||
void ImGui_ImplDX9_NewFrame()
|
||||
@@ -383,6 +403,148 @@ void ImGui_ImplDX9_NewFrame()
|
||||
ImGui_ImplDX9_CreateDeviceObjects();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
|
||||
// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously.
|
||||
// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first..
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
|
||||
// Helper structure we store in the void* RendererUserData field of each ImGuiViewport to easily retrieve our backend data.
|
||||
struct ImGui_ImplDX9_ViewportData
|
||||
{
|
||||
IDirect3DSwapChain9* SwapChain;
|
||||
D3DPRESENT_PARAMETERS d3dpp;
|
||||
|
||||
ImGui_ImplDX9_ViewportData() { SwapChain = nullptr; ZeroMemory(&d3dpp, sizeof(D3DPRESENT_PARAMETERS)); }
|
||||
~ImGui_ImplDX9_ViewportData() { IM_ASSERT(SwapChain == nullptr); }
|
||||
};
|
||||
|
||||
static void ImGui_ImplDX9_CreateWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
|
||||
ImGui_ImplDX9_ViewportData* vd = IM_NEW(ImGui_ImplDX9_ViewportData)();
|
||||
viewport->RendererUserData = vd;
|
||||
|
||||
// PlatformHandleRaw should always be a HWND, whereas PlatformHandle might be a higher-level handle (e.g. GLFWWindow*, SDL_Window*).
|
||||
// Some backends will leave PlatformHandleRaw == 0, in which case we assume PlatformHandle will contain the HWND.
|
||||
HWND hwnd = viewport->PlatformHandleRaw ? (HWND)viewport->PlatformHandleRaw : (HWND)viewport->PlatformHandle;
|
||||
IM_ASSERT(hwnd != 0);
|
||||
|
||||
ZeroMemory(&vd->d3dpp, sizeof(D3DPRESENT_PARAMETERS));
|
||||
vd->d3dpp.Windowed = TRUE;
|
||||
vd->d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
||||
vd->d3dpp.BackBufferWidth = (UINT)viewport->Size.x;
|
||||
vd->d3dpp.BackBufferHeight = (UINT)viewport->Size.y;
|
||||
vd->d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
|
||||
vd->d3dpp.hDeviceWindow = hwnd;
|
||||
vd->d3dpp.EnableAutoDepthStencil = FALSE;
|
||||
vd->d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
|
||||
vd->d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; // Present without vsync
|
||||
|
||||
HRESULT hr = bd->pd3dDevice->CreateAdditionalSwapChain(&vd->d3dpp, &vd->SwapChain); IM_UNUSED(hr);
|
||||
IM_ASSERT(hr == D3D_OK);
|
||||
IM_ASSERT(vd->SwapChain != nullptr);
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX9_DestroyWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
// The main viewport (owned by the application) will always have RendererUserData == 0 since we didn't create the data for it.
|
||||
if (ImGui_ImplDX9_ViewportData* vd = (ImGui_ImplDX9_ViewportData*)viewport->RendererUserData)
|
||||
{
|
||||
if (vd->SwapChain)
|
||||
vd->SwapChain->Release();
|
||||
vd->SwapChain = nullptr;
|
||||
ZeroMemory(&vd->d3dpp, sizeof(D3DPRESENT_PARAMETERS));
|
||||
IM_DELETE(vd);
|
||||
}
|
||||
viewport->RendererUserData = nullptr;
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX9_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
|
||||
{
|
||||
ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
|
||||
ImGui_ImplDX9_ViewportData* vd = (ImGui_ImplDX9_ViewportData*)viewport->RendererUserData;
|
||||
if (vd->SwapChain)
|
||||
{
|
||||
vd->SwapChain->Release();
|
||||
vd->SwapChain = nullptr;
|
||||
vd->d3dpp.BackBufferWidth = (UINT)size.x;
|
||||
vd->d3dpp.BackBufferHeight = (UINT)size.y;
|
||||
HRESULT hr = bd->pd3dDevice->CreateAdditionalSwapChain(&vd->d3dpp, &vd->SwapChain); IM_UNUSED(hr);
|
||||
IM_ASSERT(hr == D3D_OK);
|
||||
}
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX9_RenderWindow(ImGuiViewport* viewport, void*)
|
||||
{
|
||||
ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
|
||||
ImGui_ImplDX9_ViewportData* vd = (ImGui_ImplDX9_ViewportData*)viewport->RendererUserData;
|
||||
ImVec4 clear_color = ImVec4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
LPDIRECT3DSURFACE9 render_target = nullptr;
|
||||
LPDIRECT3DSURFACE9 last_render_target = nullptr;
|
||||
LPDIRECT3DSURFACE9 last_depth_stencil = nullptr;
|
||||
vd->SwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &render_target);
|
||||
bd->pd3dDevice->GetRenderTarget(0, &last_render_target);
|
||||
bd->pd3dDevice->GetDepthStencilSurface(&last_depth_stencil);
|
||||
bd->pd3dDevice->SetRenderTarget(0, render_target);
|
||||
bd->pd3dDevice->SetDepthStencilSurface(nullptr);
|
||||
|
||||
if (!(viewport->Flags & ImGuiViewportFlags_NoRendererClear))
|
||||
{
|
||||
D3DCOLOR clear_col_dx = D3DCOLOR_RGBA((int)(clear_color.x*255.0f), (int)(clear_color.y*255.0f), (int)(clear_color.z*255.0f), (int)(clear_color.w*255.0f));
|
||||
bd->pd3dDevice->Clear(0, nullptr, D3DCLEAR_TARGET, clear_col_dx, 1.0f, 0);
|
||||
}
|
||||
|
||||
ImGui_ImplDX9_RenderDrawData(viewport->DrawData);
|
||||
|
||||
// Restore render target
|
||||
bd->pd3dDevice->SetRenderTarget(0, last_render_target);
|
||||
bd->pd3dDevice->SetDepthStencilSurface(last_depth_stencil);
|
||||
render_target->Release();
|
||||
last_render_target->Release();
|
||||
if (last_depth_stencil) last_depth_stencil->Release();
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX9_SwapBuffers(ImGuiViewport* viewport, void*)
|
||||
{
|
||||
ImGui_ImplDX9_ViewportData* vd = (ImGui_ImplDX9_ViewportData*)viewport->RendererUserData;
|
||||
HRESULT hr = vd->SwapChain->Present(nullptr, nullptr, vd->d3dpp.hDeviceWindow, nullptr, 0);
|
||||
// Let main application handle D3DERR_DEVICELOST by resetting the device.
|
||||
IM_ASSERT(SUCCEEDED(hr) || hr == D3DERR_DEVICELOST);
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX9_InitPlatformInterface()
|
||||
{
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
platform_io.Renderer_CreateWindow = ImGui_ImplDX9_CreateWindow;
|
||||
platform_io.Renderer_DestroyWindow = ImGui_ImplDX9_DestroyWindow;
|
||||
platform_io.Renderer_SetWindowSize = ImGui_ImplDX9_SetWindowSize;
|
||||
platform_io.Renderer_RenderWindow = ImGui_ImplDX9_RenderWindow;
|
||||
platform_io.Renderer_SwapBuffers = ImGui_ImplDX9_SwapBuffers;
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX9_ShutdownPlatformInterface()
|
||||
{
|
||||
ImGui::DestroyPlatformWindows();
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX9_CreateDeviceObjectsForPlatformWindows()
|
||||
{
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
for (int i = 1; i < platform_io.Viewports.Size; i++)
|
||||
if (!platform_io.Viewports[i]->RendererUserData)
|
||||
ImGui_ImplDX9_CreateWindow(platform_io.Viewports[i]);
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX9_InvalidateDeviceObjectsForPlatformWindows()
|
||||
{
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
for (int i = 1; i < platform_io.Viewports.Size; i++)
|
||||
if (platform_io.Viewports[i]->RendererUserData)
|
||||
ImGui_ImplDX9_DestroyWindow(platform_io.Viewports[i]);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'LPDIRECT3DTEXTURE9' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
|
||||
@@ -9,6 +9,10 @@
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy GLFW_KEY_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
||||
// [X] Platform: Gamepad support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange' (note: the resizing cursors requires GLFW 3.4+).
|
||||
// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// Issues:
|
||||
// [ ] Platform: Multi-viewport support: ParentViewportID not honored, and so io.ConfigViewportsNoDefaultParent has no effect (minor).
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
@@ -20,6 +24,8 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2023-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2023-12-19: Emscripten: Added ImGui_ImplGlfw_InstallEmscriptenCanvasResizeCallback() to register canvas selector and auto-resize GLFW window.
|
||||
// 2023-10-05: Inputs: Added support for extra ImGuiKey values: F13 to F24 function keys.
|
||||
// 2023-07-18: Inputs: Revert ignoring mouse data on GLFW_CURSOR_DISABLED as it can be used differently. User may set ImGuiConfigFLags_NoMouse if desired. (#5625, #6609)
|
||||
// 2023-06-12: Accept glfwGetTime() not returning a monotonically increasing value. This seems to happens on some Windows setup when peripherals disconnect, and is likely to also happen on browser + Emscripten. (#6491)
|
||||
@@ -27,6 +33,7 @@
|
||||
// 2023-03-16: Inputs: Fixed key modifiers handling on secondary viewports (docking branch). Broken on 2023/01/04. (#6248, #6034)
|
||||
// 2023-03-14: Emscripten: Avoid using glfwGetError() and glfwGetGamepadState() which are not correctly implemented in Emscripten emulation. (#6240)
|
||||
// 2023-02-03: Emscripten: Registering custom low-level mouse wheel handler to get more accurate scrolling impulses on Emscripten. (#4019, #6096)
|
||||
// 2023-01-18: Handle unsupported glfwGetVideoMode() call on e.g. Emscripten.
|
||||
// 2023-01-04: Inputs: Fixed mods state on Linux when using Alt-GR text input (e.g. German keyboard layout), could lead to broken text input. Revert a 2022/01/17 change were we resumed using mods provided by GLFW, turns out they were faulty.
|
||||
// 2022-11-22: Perform a dummy glfwGetError() read to cancel missing names with glfwGetKeyName(). (#5908)
|
||||
// 2022-10-18: Perform a dummy glfwGetError() read to cancel missing mouse cursors errors. Using GLFW_VERSION_COMBINED directly. (#5785)
|
||||
@@ -99,11 +106,29 @@
|
||||
|
||||
// We gather version tests as define in order to easily see which features are version-dependent.
|
||||
#define GLFW_VERSION_COMBINED (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 + GLFW_VERSION_REVISION)
|
||||
#define GLFW_HAS_WINDOW_TOPMOST (GLFW_VERSION_COMBINED >= 3200) // 3.2+ GLFW_FLOATING
|
||||
#define GLFW_HAS_WINDOW_HOVERED (GLFW_VERSION_COMBINED >= 3300) // 3.3+ GLFW_HOVERED
|
||||
#define GLFW_HAS_WINDOW_ALPHA (GLFW_VERSION_COMBINED >= 3300) // 3.3+ glfwSetWindowOpacity
|
||||
#define GLFW_HAS_PER_MONITOR_DPI (GLFW_VERSION_COMBINED >= 3300) // 3.3+ glfwGetMonitorContentScale
|
||||
#if defined(__EMSCRIPTEN__) || defined(__SWITCH__) // no Vulkan support in GLFW for Emscripten or homebrew Nintendo Switch
|
||||
#define GLFW_HAS_VULKAN (0)
|
||||
#else
|
||||
#define GLFW_HAS_VULKAN (GLFW_VERSION_COMBINED >= 3200) // 3.2+ glfwCreateWindowSurface
|
||||
#endif
|
||||
#define GLFW_HAS_FOCUS_WINDOW (GLFW_VERSION_COMBINED >= 3200) // 3.2+ glfwFocusWindow
|
||||
#define GLFW_HAS_FOCUS_ON_SHOW (GLFW_VERSION_COMBINED >= 3300) // 3.3+ GLFW_FOCUS_ON_SHOW
|
||||
#define GLFW_HAS_MONITOR_WORK_AREA (GLFW_VERSION_COMBINED >= 3300) // 3.3+ glfwGetMonitorWorkarea
|
||||
#define GLFW_HAS_OSX_WINDOW_POS_FIX (GLFW_VERSION_COMBINED >= 3301) // 3.3.1+ Fixed: Resizing window repositions it on MacOS #1553
|
||||
#ifdef GLFW_RESIZE_NESW_CURSOR // Let's be nice to people who pulled GLFW between 2019-04-16 (3.4 define) and 2019-11-29 (cursors defines) // FIXME: Remove when GLFW 3.4 is released?
|
||||
#define GLFW_HAS_NEW_CURSORS (GLFW_VERSION_COMBINED >= 3400) // 3.4+ GLFW_RESIZE_ALL_CURSOR, GLFW_RESIZE_NESW_CURSOR, GLFW_RESIZE_NWSE_CURSOR, GLFW_NOT_ALLOWED_CURSOR
|
||||
#else
|
||||
#define GLFW_HAS_NEW_CURSORS (0)
|
||||
#endif
|
||||
#ifdef GLFW_MOUSE_PASSTHROUGH // Let's be nice to people who pulled GLFW between 2019-04-16 (3.4 define) and 2020-07-17 (passthrough)
|
||||
#define GLFW_HAS_MOUSE_PASSTHROUGH (GLFW_VERSION_COMBINED >= 3400) // 3.4+ GLFW_MOUSE_PASSTHROUGH
|
||||
#else
|
||||
#define GLFW_HAS_MOUSE_PASSTHROUGH (0)
|
||||
#endif
|
||||
#define GLFW_HAS_GAMEPAD_API (GLFW_VERSION_COMBINED >= 3300) // 3.3+ glfwGetGamepadState() new api
|
||||
#define GLFW_HAS_GETKEYNAME (GLFW_VERSION_COMBINED >= 3200) // 3.2+ glfwGetKeyName()
|
||||
#define GLFW_HAS_GETERROR (GLFW_VERSION_COMBINED >= 3300) // 3.3+ glfwGetError()
|
||||
@@ -124,8 +149,13 @@ struct ImGui_ImplGlfw_Data
|
||||
GLFWwindow* MouseWindow;
|
||||
GLFWcursor* MouseCursors[ImGuiMouseCursor_COUNT];
|
||||
ImVec2 LastValidMousePos;
|
||||
GLFWwindow* KeyOwnerWindows[GLFW_KEY_LAST];
|
||||
bool InstalledCallbacks;
|
||||
bool CallbacksChainForAllWindows;
|
||||
bool WantUpdateMonitors;
|
||||
#ifdef __EMSCRIPTEN__
|
||||
const char* CanvasSelector;
|
||||
#endif
|
||||
|
||||
// Chain GLFW callbacks: our callbacks will call the user's previously installed callbacks, if any.
|
||||
GLFWwindowfocusfun PrevUserCallbackWindowFocus;
|
||||
@@ -137,7 +167,7 @@ struct ImGui_ImplGlfw_Data
|
||||
GLFWcharfun PrevUserCallbackChar;
|
||||
GLFWmonitorfun PrevUserCallbackMonitor;
|
||||
#ifdef _WIN32
|
||||
WNDPROC GlfwWndProc;
|
||||
WNDPROC PrevWndProc;
|
||||
#endif
|
||||
|
||||
ImGui_ImplGlfw_Data() { memset((void*)this, 0, sizeof(*this)); }
|
||||
@@ -155,6 +185,11 @@ static ImGui_ImplGlfw_Data* ImGui_ImplGlfw_GetBackendData()
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplGlfw_Data*)ImGui::GetIO().BackendPlatformUserData : nullptr;
|
||||
}
|
||||
|
||||
// Forward Declarations
|
||||
static void ImGui_ImplGlfw_UpdateMonitors();
|
||||
static void ImGui_ImplGlfw_InitPlatformInterface();
|
||||
static void ImGui_ImplGlfw_ShutdownPlatformInterface();
|
||||
|
||||
// Functions
|
||||
static const char* ImGui_ImplGlfw_GetClipboardText(void* user_data)
|
||||
{
|
||||
@@ -380,6 +415,9 @@ void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int keycode, int scancode, i
|
||||
|
||||
ImGui_ImplGlfw_UpdateKeyModifiers(window);
|
||||
|
||||
if (keycode >= 0 && keycode < IM_ARRAYSIZE(bd->KeyOwnerWindows))
|
||||
bd->KeyOwnerWindows[keycode] = (action == GLFW_PRESS) ? window : nullptr;
|
||||
|
||||
keycode = ImGui_ImplGlfw_TranslateUntranslatedKey(keycode, scancode);
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
@@ -405,6 +443,13 @@ void ImGui_ImplGlfw_CursorPosCallback(GLFWwindow* window, double x, double y)
|
||||
bd->PrevUserCallbackCursorPos(window, x, y);
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
int window_x, window_y;
|
||||
glfwGetWindowPos(window, &window_x, &window_y);
|
||||
x += window_x;
|
||||
y += window_y;
|
||||
}
|
||||
io.AddMousePosEvent((float)x, (float)y);
|
||||
bd->LastValidMousePos = ImVec2((float)x, (float)y);
|
||||
}
|
||||
@@ -443,7 +488,8 @@ void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c)
|
||||
|
||||
void ImGui_ImplGlfw_MonitorCallback(GLFWmonitor*, int)
|
||||
{
|
||||
// Unused in 'master' branch but 'docking' branch will use this, so we declare it ahead of it so if you have to install callbacks you can install this one too.
|
||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||
bd->WantUpdateMonitors = true;
|
||||
}
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
@@ -465,32 +511,7 @@ static EM_BOOL ImGui_ImplEmscripten_WheelCallback(int, const EmscriptenWheelEven
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
// GLFW doesn't allow to distinguish Mouse vs TouchScreen vs Pen.
|
||||
// Add support for Win32 (based on imgui_impl_win32), because we rely on _TouchScreen info to trickle inputs differently.
|
||||
static ImGuiMouseSource GetMouseSourceFromMessageExtraInfo()
|
||||
{
|
||||
LPARAM extra_info = ::GetMessageExtraInfo();
|
||||
if ((extra_info & 0xFFFFFF80) == 0xFF515700)
|
||||
return ImGuiMouseSource_Pen;
|
||||
if ((extra_info & 0xFFFFFF80) == 0xFF515780)
|
||||
return ImGuiMouseSource_TouchScreen;
|
||||
return ImGuiMouseSource_Mouse;
|
||||
}
|
||||
static LRESULT CALLBACK ImGui_ImplGlfw_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||
switch (msg)
|
||||
{
|
||||
case WM_MOUSEMOVE: case WM_NCMOUSEMOVE:
|
||||
case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK: case WM_LBUTTONUP:
|
||||
case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK: case WM_RBUTTONUP:
|
||||
case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK: case WM_MBUTTONUP:
|
||||
case WM_XBUTTONDOWN: case WM_XBUTTONDBLCLK: case WM_XBUTTONUP:
|
||||
ImGui::GetIO().AddMouseSourceEvent(GetMouseSourceFromMessageExtraInfo());
|
||||
break;
|
||||
}
|
||||
return ::CallWindowProc(bd->GlfwWndProc, hWnd, msg, wParam, lParam);
|
||||
}
|
||||
static LRESULT CALLBACK ImGui_ImplGlfw_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
#endif
|
||||
|
||||
void ImGui_ImplGlfw_InstallCallbacks(GLFWwindow* window)
|
||||
@@ -557,9 +578,16 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw
|
||||
io.BackendPlatformName = "imgui_impl_glfw";
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used)
|
||||
#ifndef __EMSCRIPTEN__
|
||||
io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports; // We can create multi-viewports on the Platform side (optional)
|
||||
#endif
|
||||
#if GLFW_HAS_MOUSE_PASSTHROUGH || (GLFW_HAS_WINDOW_HOVERED && defined(_WIN32))
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport; // We can call io.AddMouseViewportEvent() with correct data (optional)
|
||||
#endif
|
||||
|
||||
bd->Window = window;
|
||||
bd->Time = 0.0;
|
||||
bd->WantUpdateMonitors = true;
|
||||
|
||||
io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText;
|
||||
io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText;
|
||||
@@ -601,8 +629,13 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw
|
||||
emscripten_set_wheel_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, nullptr, false, ImGui_ImplEmscripten_WheelCallback);
|
||||
#endif
|
||||
|
||||
// Update monitors the first time (note: monitor callback are broken in GLFW 3.2 and earlier, see github.com/glfw/glfw/issues/784)
|
||||
ImGui_ImplGlfw_UpdateMonitors();
|
||||
glfwSetMonitorCallback(ImGui_ImplGlfw_MonitorCallback);
|
||||
|
||||
// Set platform dependent data in viewport
|
||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||
main_viewport->PlatformHandle = (void*)bd->Window;
|
||||
#ifdef _WIN32
|
||||
main_viewport->PlatformHandleRaw = glfwGetWin32Window(bd->Window);
|
||||
#elif defined(__APPLE__)
|
||||
@@ -610,12 +643,14 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw
|
||||
#else
|
||||
IM_UNUSED(main_viewport);
|
||||
#endif
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
ImGui_ImplGlfw_InitPlatformInterface();
|
||||
|
||||
// Windows: register a WndProc hook so we can intercept some messages.
|
||||
#ifdef _WIN32
|
||||
bd->GlfwWndProc = (WNDPROC)::GetWindowLongPtr((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC);
|
||||
IM_ASSERT(bd->GlfwWndProc != nullptr);
|
||||
::SetWindowLongPtr((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC, (LONG_PTR)ImGui_ImplGlfw_WndProc);
|
||||
bd->PrevWndProc = (WNDPROC)::GetWindowLongPtrW((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC);
|
||||
IM_ASSERT(bd->PrevWndProc != nullptr);
|
||||
::SetWindowLongPtrW((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC, (LONG_PTR)ImGui_ImplGlfw_WndProc);
|
||||
#endif
|
||||
|
||||
bd->ClientApi = client_api;
|
||||
@@ -643,6 +678,8 @@ void ImGui_ImplGlfw_Shutdown()
|
||||
IM_ASSERT(bd != nullptr && "No platform backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
ImGui_ImplGlfw_ShutdownPlatformInterface();
|
||||
|
||||
if (bd->InstalledCallbacks)
|
||||
ImGui_ImplGlfw_RestoreCallbacks(bd->Window);
|
||||
#ifdef __EMSCRIPTEN__
|
||||
@@ -652,16 +689,16 @@ void ImGui_ImplGlfw_Shutdown()
|
||||
for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_COUNT; cursor_n++)
|
||||
glfwDestroyCursor(bd->MouseCursors[cursor_n]);
|
||||
|
||||
// Windows: register a WndProc hook so we can intercept some messages.
|
||||
// Windows: restore our WndProc hook
|
||||
#ifdef _WIN32
|
||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||
::SetWindowLongPtr((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC, (LONG_PTR)bd->GlfwWndProc);
|
||||
bd->GlfwWndProc = nullptr;
|
||||
::SetWindowLongPtrW((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC, (LONG_PTR)bd->PrevWndProc);
|
||||
bd->PrevWndProc = nullptr;
|
||||
#endif
|
||||
|
||||
io.BackendPlatformName = nullptr;
|
||||
io.BackendPlatformUserData = nullptr;
|
||||
io.BackendFlags &= ~(ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_HasSetMousePos | ImGuiBackendFlags_HasGamepad);
|
||||
io.BackendFlags &= ~(ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_HasSetMousePos | ImGuiBackendFlags_HasGamepad | ImGuiBackendFlags_PlatformHasViewports | ImGuiBackendFlags_HasMouseHoveredViewport);
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
@@ -669,11 +706,15 @@ static void ImGui_ImplGlfw_UpdateMouseData()
|
||||
{
|
||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
|
||||
|
||||
// (those braces are here to reduce diff with multi-viewports support in 'docking' branch)
|
||||
ImGuiID mouse_viewport_id = 0;
|
||||
const ImVec2 mouse_pos_prev = io.MousePos;
|
||||
for (int n = 0; n < platform_io.Viewports.Size; n++)
|
||||
{
|
||||
GLFWwindow* window = bd->Window;
|
||||
ImGuiViewport* viewport = platform_io.Viewports[n];
|
||||
GLFWwindow* window = (GLFWwindow*)viewport->PlatformHandle;
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
const bool is_window_focused = true;
|
||||
@@ -683,19 +724,53 @@ static void ImGui_ImplGlfw_UpdateMouseData()
|
||||
if (is_window_focused)
|
||||
{
|
||||
// (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
|
||||
// When multi-viewports are enabled, all Dear ImGui positions are same as OS positions.
|
||||
if (io.WantSetMousePos)
|
||||
glfwSetCursorPos(window, (double)io.MousePos.x, (double)io.MousePos.y);
|
||||
glfwSetCursorPos(window, (double)(mouse_pos_prev.x - viewport->Pos.x), (double)(mouse_pos_prev.y - viewport->Pos.y));
|
||||
|
||||
// (Optional) Fallback to provide mouse position when focused (ImGui_ImplGlfw_CursorPosCallback already provides this when hovered or captured)
|
||||
if (bd->MouseWindow == nullptr)
|
||||
{
|
||||
double mouse_x, mouse_y;
|
||||
glfwGetCursorPos(window, &mouse_x, &mouse_y);
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
// Single viewport mode: mouse position in client window coordinates (io.MousePos is (0,0) when the mouse is on the upper-left corner of the app window)
|
||||
// Multi-viewport mode: mouse position in OS absolute coordinates (io.MousePos is (0,0) when the mouse is on the upper-left of the primary monitor)
|
||||
int window_x, window_y;
|
||||
glfwGetWindowPos(window, &window_x, &window_y);
|
||||
mouse_x += window_x;
|
||||
mouse_y += window_y;
|
||||
}
|
||||
bd->LastValidMousePos = ImVec2((float)mouse_x, (float)mouse_y);
|
||||
io.AddMousePosEvent((float)mouse_x, (float)mouse_y);
|
||||
}
|
||||
}
|
||||
|
||||
// (Optional) When using multiple viewports: call io.AddMouseViewportEvent() with the viewport the OS mouse cursor is hovering.
|
||||
// If ImGuiBackendFlags_HasMouseHoveredViewport is not set by the backend, Dear imGui will ignore this field and infer the information using its flawed heuristic.
|
||||
// - [X] GLFW >= 3.3 backend ON WINDOWS ONLY does correctly ignore viewports with the _NoInputs flag.
|
||||
// - [!] GLFW <= 3.2 backend CANNOT correctly ignore viewports with the _NoInputs flag, and CANNOT reported Hovered Viewport because of mouse capture.
|
||||
// Some backend are not able to handle that correctly. If a backend report an hovered viewport that has the _NoInputs flag (e.g. when dragging a window
|
||||
// for docking, the viewport has the _NoInputs flag in order to allow us to find the viewport under), then Dear ImGui is forced to ignore the value reported
|
||||
// by the backend, and use its flawed heuristic to guess the viewport behind.
|
||||
// - [X] GLFW backend correctly reports this regardless of another viewport behind focused and dragged from (we need this to find a useful drag and drop target).
|
||||
// FIXME: This is currently only correct on Win32. See what we do below with the WM_NCHITTEST, missing an equivalent for other systems.
|
||||
// See https://github.com/glfw/glfw/issues/1236 if you want to help in making this a GLFW feature.
|
||||
#if GLFW_HAS_MOUSE_PASSTHROUGH || (GLFW_HAS_WINDOW_HOVERED && defined(_WIN32))
|
||||
const bool window_no_input = (viewport->Flags & ImGuiViewportFlags_NoInputs) != 0;
|
||||
#if GLFW_HAS_MOUSE_PASSTHROUGH
|
||||
glfwSetWindowAttrib(window, GLFW_MOUSE_PASSTHROUGH, window_no_input);
|
||||
#endif
|
||||
if (glfwGetWindowAttrib(window, GLFW_HOVERED) && !window_no_input)
|
||||
mouse_viewport_id = viewport->ID;
|
||||
#else
|
||||
// We cannot use bd->MouseWindow maintained from CursorEnter/Leave callbacks, because it is locked to the window capturing mouse.
|
||||
#endif
|
||||
}
|
||||
|
||||
if (io.BackendFlags & ImGuiBackendFlags_HasMouseHoveredViewport)
|
||||
io.AddMouseViewportEvent(mouse_viewport_id);
|
||||
}
|
||||
|
||||
static void ImGui_ImplGlfw_UpdateMouseCursor()
|
||||
@@ -706,9 +781,10 @@ static void ImGui_ImplGlfw_UpdateMouseCursor()
|
||||
return;
|
||||
|
||||
ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor();
|
||||
// (those braces are here to reduce diff with multi-viewports support in 'docking' branch)
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
for (int n = 0; n < platform_io.Viewports.Size; n++)
|
||||
{
|
||||
GLFWwindow* window = bd->Window;
|
||||
GLFWwindow* window = (GLFWwindow*)platform_io.Viewports[n]->PlatformHandle;
|
||||
if (imgui_cursor == ImGuiMouseCursor_None || io.MouseDrawCursor)
|
||||
{
|
||||
// Hide OS mouse cursor if imgui is drawing it or if it wants no cursor
|
||||
@@ -777,6 +853,48 @@ static void ImGui_ImplGlfw_UpdateGamepads()
|
||||
#undef MAP_ANALOG
|
||||
}
|
||||
|
||||
static void ImGui_ImplGlfw_UpdateMonitors()
|
||||
{
|
||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
bd->WantUpdateMonitors = false;
|
||||
|
||||
int monitors_count = 0;
|
||||
GLFWmonitor** glfw_monitors = glfwGetMonitors(&monitors_count);
|
||||
if (monitors_count == 0) // Preserve existing monitor list if there are none. Happens on macOS sleeping (#5683)
|
||||
return;
|
||||
|
||||
platform_io.Monitors.resize(0);
|
||||
for (int n = 0; n < monitors_count; n++)
|
||||
{
|
||||
ImGuiPlatformMonitor monitor;
|
||||
int x, y;
|
||||
glfwGetMonitorPos(glfw_monitors[n], &x, &y);
|
||||
const GLFWvidmode* vid_mode = glfwGetVideoMode(glfw_monitors[n]);
|
||||
if (vid_mode == nullptr)
|
||||
continue; // Failed to get Video mode (e.g. Emscripten does not support this function)
|
||||
monitor.MainPos = monitor.WorkPos = ImVec2((float)x, (float)y);
|
||||
monitor.MainSize = monitor.WorkSize = ImVec2((float)vid_mode->width, (float)vid_mode->height);
|
||||
#if GLFW_HAS_MONITOR_WORK_AREA
|
||||
int w, h;
|
||||
glfwGetMonitorWorkarea(glfw_monitors[n], &x, &y, &w, &h);
|
||||
if (w > 0 && h > 0) // Workaround a small GLFW issue reporting zero on monitor changes: https://github.com/glfw/glfw/pull/1761
|
||||
{
|
||||
monitor.WorkPos = ImVec2((float)x, (float)y);
|
||||
monitor.WorkSize = ImVec2((float)w, (float)h);
|
||||
}
|
||||
#endif
|
||||
#if GLFW_HAS_PER_MONITOR_DPI
|
||||
// Warning: the validity of monitor DPI information on Windows depends on the application DPI awareness settings, which generally needs to be set in the manifest or at runtime.
|
||||
float x_scale, y_scale;
|
||||
glfwGetMonitorContentScale(glfw_monitors[n], &x_scale, &y_scale);
|
||||
monitor.DpiScale = x_scale;
|
||||
#endif
|
||||
monitor.PlatformHandle = (void*)glfw_monitors[n]; // [...] GLFW doc states: "guaranteed to be valid only until the monitor configuration changes"
|
||||
platform_io.Monitors.push_back(monitor);
|
||||
}
|
||||
}
|
||||
|
||||
void ImGui_ImplGlfw_NewFrame()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
@@ -791,6 +909,8 @@ void ImGui_ImplGlfw_NewFrame()
|
||||
io.DisplaySize = ImVec2((float)w, (float)h);
|
||||
if (w > 0 && h > 0)
|
||||
io.DisplayFramebufferScale = ImVec2((float)display_w / (float)w, (float)display_h / (float)h);
|
||||
if (bd->WantUpdateMonitors)
|
||||
ImGui_ImplGlfw_UpdateMonitors();
|
||||
|
||||
// Setup time step
|
||||
// (Accept glfwGetTime() not returning a monotonically increasing value. Seems to happens on disconnecting peripherals and probably on VMs and Emscripten, see #6491, #6189, #6114, #3644)
|
||||
@@ -807,6 +927,435 @@ void ImGui_ImplGlfw_NewFrame()
|
||||
ImGui_ImplGlfw_UpdateGamepads();
|
||||
}
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
static EM_BOOL ImGui_ImplGlfw_OnCanvasSizeChange(int event_type, const EmscriptenUiEvent* event, void* user_data)
|
||||
{
|
||||
ImGui_ImplGlfw_Data* bd = (ImGui_ImplGlfw_Data*)user_data;
|
||||
double canvas_width, canvas_height;
|
||||
emscripten_get_element_css_size(bd->CanvasSelector, &canvas_width, &canvas_height);
|
||||
glfwSetWindowSize(bd->Window, (int)canvas_width, (int)canvas_height);
|
||||
return true;
|
||||
}
|
||||
|
||||
static EM_BOOL ImGui_ImplEmscripten_FullscreenChangeCallback(int event_type, const EmscriptenFullscreenChangeEvent* event, void* user_data)
|
||||
{
|
||||
ImGui_ImplGlfw_Data* bd = (ImGui_ImplGlfw_Data*)user_data;
|
||||
double canvas_width, canvas_height;
|
||||
emscripten_get_element_css_size(bd->CanvasSelector, &canvas_width, &canvas_height);
|
||||
glfwSetWindowSize(bd->Window, (int)canvas_width, (int)canvas_height);
|
||||
return true;
|
||||
}
|
||||
|
||||
// 'canvas_selector' is a CSS selector. The event listener is applied to the first element that matches the query.
|
||||
// STRING MUST PERSIST FOR THE APPLICATION DURATION. PLEASE USE A STRING LITERAL OR ENSURE POINTER WILL STAY VALID.
|
||||
void ImGui_ImplGlfw_InstallEmscriptenCanvasResizeCallback(const char* canvas_selector)
|
||||
{
|
||||
IM_ASSERT(canvas_selector != nullptr);
|
||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplGlfw_InitForXXX()?");
|
||||
|
||||
bd->CanvasSelector = canvas_selector;
|
||||
emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, bd, false, ImGui_ImplGlfw_OnCanvasSizeChange);
|
||||
emscripten_set_fullscreenchange_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, bd, false, ImGui_ImplEmscripten_FullscreenChangeCallback);
|
||||
|
||||
// Change the size of the GLFW window according to the size of the canvas
|
||||
ImGui_ImplGlfw_OnCanvasSizeChange(EMSCRIPTEN_EVENT_RESIZE, {}, bd);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
|
||||
// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously.
|
||||
// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first..
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
|
||||
// Helper structure we store in the void* RendererUserData field of each ImGuiViewport to easily retrieve our backend data.
|
||||
struct ImGui_ImplGlfw_ViewportData
|
||||
{
|
||||
GLFWwindow* Window;
|
||||
bool WindowOwned;
|
||||
int IgnoreWindowPosEventFrame;
|
||||
int IgnoreWindowSizeEventFrame;
|
||||
#ifdef _WIN32
|
||||
WNDPROC PrevWndProc;
|
||||
#endif
|
||||
|
||||
ImGui_ImplGlfw_ViewportData() { memset(this, 0, sizeof(*this)); IgnoreWindowSizeEventFrame = IgnoreWindowPosEventFrame = -1; }
|
||||
~ImGui_ImplGlfw_ViewportData() { IM_ASSERT(Window == nullptr); }
|
||||
};
|
||||
|
||||
static void ImGui_ImplGlfw_WindowCloseCallback(GLFWwindow* window)
|
||||
{
|
||||
if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle(window))
|
||||
viewport->PlatformRequestClose = true;
|
||||
}
|
||||
|
||||
// GLFW may dispatch window pos/size events after calling glfwSetWindowPos()/glfwSetWindowSize().
|
||||
// However: depending on the platform the callback may be invoked at different time:
|
||||
// - on Windows it appears to be called within the glfwSetWindowPos()/glfwSetWindowSize() call
|
||||
// - on Linux it is queued and invoked during glfwPollEvents()
|
||||
// Because the event doesn't always fire on glfwSetWindowXXX() we use a frame counter tag to only
|
||||
// ignore recent glfwSetWindowXXX() calls.
|
||||
static void ImGui_ImplGlfw_WindowPosCallback(GLFWwindow* window, int, int)
|
||||
{
|
||||
if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle(window))
|
||||
{
|
||||
if (ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData)
|
||||
{
|
||||
bool ignore_event = (ImGui::GetFrameCount() <= vd->IgnoreWindowPosEventFrame + 1);
|
||||
//data->IgnoreWindowPosEventFrame = -1;
|
||||
if (ignore_event)
|
||||
return;
|
||||
}
|
||||
viewport->PlatformRequestMove = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void ImGui_ImplGlfw_WindowSizeCallback(GLFWwindow* window, int, int)
|
||||
{
|
||||
if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle(window))
|
||||
{
|
||||
if (ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData)
|
||||
{
|
||||
bool ignore_event = (ImGui::GetFrameCount() <= vd->IgnoreWindowSizeEventFrame + 1);
|
||||
//data->IgnoreWindowSizeEventFrame = -1;
|
||||
if (ignore_event)
|
||||
return;
|
||||
}
|
||||
viewport->PlatformRequestResize = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void ImGui_ImplGlfw_CreateWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||
ImGui_ImplGlfw_ViewportData* vd = IM_NEW(ImGui_ImplGlfw_ViewportData)();
|
||||
viewport->PlatformUserData = vd;
|
||||
|
||||
// GLFW 3.2 unfortunately always set focus on glfwCreateWindow() if GLFW_VISIBLE is set, regardless of GLFW_FOCUSED
|
||||
// With GLFW 3.3, the hint GLFW_FOCUS_ON_SHOW fixes this problem
|
||||
glfwWindowHint(GLFW_VISIBLE, false);
|
||||
glfwWindowHint(GLFW_FOCUSED, false);
|
||||
#if GLFW_HAS_FOCUS_ON_SHOW
|
||||
glfwWindowHint(GLFW_FOCUS_ON_SHOW, false);
|
||||
#endif
|
||||
glfwWindowHint(GLFW_DECORATED, (viewport->Flags & ImGuiViewportFlags_NoDecoration) ? false : true);
|
||||
#if GLFW_HAS_WINDOW_TOPMOST
|
||||
glfwWindowHint(GLFW_FLOATING, (viewport->Flags & ImGuiViewportFlags_TopMost) ? true : false);
|
||||
#endif
|
||||
GLFWwindow* share_window = (bd->ClientApi == GlfwClientApi_OpenGL) ? bd->Window : nullptr;
|
||||
vd->Window = glfwCreateWindow((int)viewport->Size.x, (int)viewport->Size.y, "No Title Yet", nullptr, share_window);
|
||||
vd->WindowOwned = true;
|
||||
viewport->PlatformHandle = (void*)vd->Window;
|
||||
#ifdef _WIN32
|
||||
viewport->PlatformHandleRaw = glfwGetWin32Window(vd->Window);
|
||||
#elif defined(__APPLE__)
|
||||
viewport->PlatformHandleRaw = (void*)glfwGetCocoaWindow(vd->Window);
|
||||
#endif
|
||||
glfwSetWindowPos(vd->Window, (int)viewport->Pos.x, (int)viewport->Pos.y);
|
||||
|
||||
// Install GLFW callbacks for secondary viewports
|
||||
glfwSetWindowFocusCallback(vd->Window, ImGui_ImplGlfw_WindowFocusCallback);
|
||||
glfwSetCursorEnterCallback(vd->Window, ImGui_ImplGlfw_CursorEnterCallback);
|
||||
glfwSetCursorPosCallback(vd->Window, ImGui_ImplGlfw_CursorPosCallback);
|
||||
glfwSetMouseButtonCallback(vd->Window, ImGui_ImplGlfw_MouseButtonCallback);
|
||||
glfwSetScrollCallback(vd->Window, ImGui_ImplGlfw_ScrollCallback);
|
||||
glfwSetKeyCallback(vd->Window, ImGui_ImplGlfw_KeyCallback);
|
||||
glfwSetCharCallback(vd->Window, ImGui_ImplGlfw_CharCallback);
|
||||
glfwSetWindowCloseCallback(vd->Window, ImGui_ImplGlfw_WindowCloseCallback);
|
||||
glfwSetWindowPosCallback(vd->Window, ImGui_ImplGlfw_WindowPosCallback);
|
||||
glfwSetWindowSizeCallback(vd->Window, ImGui_ImplGlfw_WindowSizeCallback);
|
||||
if (bd->ClientApi == GlfwClientApi_OpenGL)
|
||||
{
|
||||
glfwMakeContextCurrent(vd->Window);
|
||||
glfwSwapInterval(0);
|
||||
}
|
||||
}
|
||||
|
||||
static void ImGui_ImplGlfw_DestroyWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||
if (ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData)
|
||||
{
|
||||
if (vd->WindowOwned)
|
||||
{
|
||||
#if !GLFW_HAS_MOUSE_PASSTHROUGH && GLFW_HAS_WINDOW_HOVERED && defined(_WIN32)
|
||||
HWND hwnd = (HWND)viewport->PlatformHandleRaw;
|
||||
::RemovePropA(hwnd, "IMGUI_VIEWPORT");
|
||||
#endif
|
||||
|
||||
// Release any keys that were pressed in the window being destroyed and are still held down,
|
||||
// because we will not receive any release events after window is destroyed.
|
||||
for (int i = 0; i < IM_ARRAYSIZE(bd->KeyOwnerWindows); i++)
|
||||
if (bd->KeyOwnerWindows[i] == vd->Window)
|
||||
ImGui_ImplGlfw_KeyCallback(vd->Window, i, 0, GLFW_RELEASE, 0); // Later params are only used for main viewport, on which this function is never called.
|
||||
|
||||
glfwDestroyWindow(vd->Window);
|
||||
}
|
||||
vd->Window = nullptr;
|
||||
IM_DELETE(vd);
|
||||
}
|
||||
viewport->PlatformUserData = viewport->PlatformHandle = nullptr;
|
||||
}
|
||||
|
||||
static void ImGui_ImplGlfw_ShowWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData;
|
||||
|
||||
#if defined(_WIN32)
|
||||
// GLFW hack: Hide icon from task bar
|
||||
HWND hwnd = (HWND)viewport->PlatformHandleRaw;
|
||||
if (viewport->Flags & ImGuiViewportFlags_NoTaskBarIcon)
|
||||
{
|
||||
LONG ex_style = ::GetWindowLong(hwnd, GWL_EXSTYLE);
|
||||
ex_style &= ~WS_EX_APPWINDOW;
|
||||
ex_style |= WS_EX_TOOLWINDOW;
|
||||
::SetWindowLong(hwnd, GWL_EXSTYLE, ex_style);
|
||||
}
|
||||
|
||||
// GLFW hack: install hook for WM_NCHITTEST message handler
|
||||
#if !GLFW_HAS_MOUSE_PASSTHROUGH && GLFW_HAS_WINDOW_HOVERED && defined(_WIN32)
|
||||
::SetPropA(hwnd, "IMGUI_VIEWPORT", viewport);
|
||||
vd->PrevWndProc = (WNDPROC)::GetWindowLongPtrW(hwnd, GWLP_WNDPROC);
|
||||
::SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (LONG_PTR)ImGui_ImplGlfw_WndProc);
|
||||
#endif
|
||||
|
||||
#if !GLFW_HAS_FOCUS_ON_SHOW
|
||||
// GLFW hack: GLFW 3.2 has a bug where glfwShowWindow() also activates/focus the window.
|
||||
// The fix was pushed to GLFW repository on 2018/01/09 and should be included in GLFW 3.3 via a GLFW_FOCUS_ON_SHOW window attribute.
|
||||
// See https://github.com/glfw/glfw/issues/1189
|
||||
// FIXME-VIEWPORT: Implement same work-around for Linux/OSX in the meanwhile.
|
||||
if (viewport->Flags & ImGuiViewportFlags_NoFocusOnAppearing)
|
||||
{
|
||||
::ShowWindow(hwnd, SW_SHOWNA);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
glfwShowWindow(vd->Window);
|
||||
}
|
||||
|
||||
static ImVec2 ImGui_ImplGlfw_GetWindowPos(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData;
|
||||
int x = 0, y = 0;
|
||||
glfwGetWindowPos(vd->Window, &x, &y);
|
||||
return ImVec2((float)x, (float)y);
|
||||
}
|
||||
|
||||
static void ImGui_ImplGlfw_SetWindowPos(ImGuiViewport* viewport, ImVec2 pos)
|
||||
{
|
||||
ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData;
|
||||
vd->IgnoreWindowPosEventFrame = ImGui::GetFrameCount();
|
||||
glfwSetWindowPos(vd->Window, (int)pos.x, (int)pos.y);
|
||||
}
|
||||
|
||||
static ImVec2 ImGui_ImplGlfw_GetWindowSize(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData;
|
||||
int w = 0, h = 0;
|
||||
glfwGetWindowSize(vd->Window, &w, &h);
|
||||
return ImVec2((float)w, (float)h);
|
||||
}
|
||||
|
||||
static void ImGui_ImplGlfw_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
|
||||
{
|
||||
ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData;
|
||||
#if __APPLE__ && !GLFW_HAS_OSX_WINDOW_POS_FIX
|
||||
// Native OS windows are positioned from the bottom-left corner on macOS, whereas on other platforms they are
|
||||
// positioned from the upper-left corner. GLFW makes an effort to convert macOS style coordinates, however it
|
||||
// doesn't handle it when changing size. We are manually moving the window in order for changes of size to be based
|
||||
// on the upper-left corner.
|
||||
int x, y, width, height;
|
||||
glfwGetWindowPos(vd->Window, &x, &y);
|
||||
glfwGetWindowSize(vd->Window, &width, &height);
|
||||
glfwSetWindowPos(vd->Window, x, y - height + size.y);
|
||||
#endif
|
||||
vd->IgnoreWindowSizeEventFrame = ImGui::GetFrameCount();
|
||||
glfwSetWindowSize(vd->Window, (int)size.x, (int)size.y);
|
||||
}
|
||||
|
||||
static void ImGui_ImplGlfw_SetWindowTitle(ImGuiViewport* viewport, const char* title)
|
||||
{
|
||||
ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData;
|
||||
glfwSetWindowTitle(vd->Window, title);
|
||||
}
|
||||
|
||||
static void ImGui_ImplGlfw_SetWindowFocus(ImGuiViewport* viewport)
|
||||
{
|
||||
#if GLFW_HAS_FOCUS_WINDOW
|
||||
ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData;
|
||||
glfwFocusWindow(vd->Window);
|
||||
#else
|
||||
// FIXME: What are the effect of not having this function? At the moment imgui doesn't actually call SetWindowFocus - we set that up ahead, will answer that question later.
|
||||
(void)viewport;
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool ImGui_ImplGlfw_GetWindowFocus(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData;
|
||||
return glfwGetWindowAttrib(vd->Window, GLFW_FOCUSED) != 0;
|
||||
}
|
||||
|
||||
static bool ImGui_ImplGlfw_GetWindowMinimized(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData;
|
||||
return glfwGetWindowAttrib(vd->Window, GLFW_ICONIFIED) != 0;
|
||||
}
|
||||
|
||||
#if GLFW_HAS_WINDOW_ALPHA
|
||||
static void ImGui_ImplGlfw_SetWindowAlpha(ImGuiViewport* viewport, float alpha)
|
||||
{
|
||||
ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData;
|
||||
glfwSetWindowOpacity(vd->Window, alpha);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void ImGui_ImplGlfw_RenderWindow(ImGuiViewport* viewport, void*)
|
||||
{
|
||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||
ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData;
|
||||
if (bd->ClientApi == GlfwClientApi_OpenGL)
|
||||
glfwMakeContextCurrent(vd->Window);
|
||||
}
|
||||
|
||||
static void ImGui_ImplGlfw_SwapBuffers(ImGuiViewport* viewport, void*)
|
||||
{
|
||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||
ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData;
|
||||
if (bd->ClientApi == GlfwClientApi_OpenGL)
|
||||
{
|
||||
glfwMakeContextCurrent(vd->Window);
|
||||
glfwSwapBuffers(vd->Window);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
// Vulkan support (the Vulkan renderer needs to call a platform-side support function to create the surface)
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
|
||||
// Avoid including <vulkan.h> so we can build without it
|
||||
#if GLFW_HAS_VULKAN
|
||||
#ifndef VULKAN_H_
|
||||
#define VK_DEFINE_HANDLE(object) typedef struct object##_T* object;
|
||||
#if defined(__LP64__) || defined(_WIN64) || defined(__x86_64__) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)
|
||||
#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef struct object##_T *object;
|
||||
#else
|
||||
#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef uint64_t object;
|
||||
#endif
|
||||
VK_DEFINE_HANDLE(VkInstance)
|
||||
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSurfaceKHR)
|
||||
struct VkAllocationCallbacks;
|
||||
enum VkResult { VK_RESULT_MAX_ENUM = 0x7FFFFFFF };
|
||||
#endif // VULKAN_H_
|
||||
extern "C" { extern GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance, GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface); }
|
||||
static int ImGui_ImplGlfw_CreateVkSurface(ImGuiViewport* viewport, ImU64 vk_instance, const void* vk_allocator, ImU64* out_vk_surface)
|
||||
{
|
||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||
ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData;
|
||||
IM_UNUSED(bd);
|
||||
IM_ASSERT(bd->ClientApi == GlfwClientApi_Vulkan);
|
||||
VkResult err = glfwCreateWindowSurface((VkInstance)vk_instance, vd->Window, (const VkAllocationCallbacks*)vk_allocator, (VkSurfaceKHR*)out_vk_surface);
|
||||
return (int)err;
|
||||
}
|
||||
#endif // GLFW_HAS_VULKAN
|
||||
|
||||
static void ImGui_ImplGlfw_InitPlatformInterface()
|
||||
{
|
||||
// Register platform interface (will be coupled with a renderer interface)
|
||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
platform_io.Platform_CreateWindow = ImGui_ImplGlfw_CreateWindow;
|
||||
platform_io.Platform_DestroyWindow = ImGui_ImplGlfw_DestroyWindow;
|
||||
platform_io.Platform_ShowWindow = ImGui_ImplGlfw_ShowWindow;
|
||||
platform_io.Platform_SetWindowPos = ImGui_ImplGlfw_SetWindowPos;
|
||||
platform_io.Platform_GetWindowPos = ImGui_ImplGlfw_GetWindowPos;
|
||||
platform_io.Platform_SetWindowSize = ImGui_ImplGlfw_SetWindowSize;
|
||||
platform_io.Platform_GetWindowSize = ImGui_ImplGlfw_GetWindowSize;
|
||||
platform_io.Platform_SetWindowFocus = ImGui_ImplGlfw_SetWindowFocus;
|
||||
platform_io.Platform_GetWindowFocus = ImGui_ImplGlfw_GetWindowFocus;
|
||||
platform_io.Platform_GetWindowMinimized = ImGui_ImplGlfw_GetWindowMinimized;
|
||||
platform_io.Platform_SetWindowTitle = ImGui_ImplGlfw_SetWindowTitle;
|
||||
platform_io.Platform_RenderWindow = ImGui_ImplGlfw_RenderWindow;
|
||||
platform_io.Platform_SwapBuffers = ImGui_ImplGlfw_SwapBuffers;
|
||||
#if GLFW_HAS_WINDOW_ALPHA
|
||||
platform_io.Platform_SetWindowAlpha = ImGui_ImplGlfw_SetWindowAlpha;
|
||||
#endif
|
||||
#if GLFW_HAS_VULKAN
|
||||
platform_io.Platform_CreateVkSurface = ImGui_ImplGlfw_CreateVkSurface;
|
||||
#endif
|
||||
|
||||
// Register main window handle (which is owned by the main application, not by us)
|
||||
// This is mostly for simplicity and consistency, so that our code (e.g. mouse handling etc.) can use same logic for main and secondary viewports.
|
||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||
ImGui_ImplGlfw_ViewportData* vd = IM_NEW(ImGui_ImplGlfw_ViewportData)();
|
||||
vd->Window = bd->Window;
|
||||
vd->WindowOwned = false;
|
||||
main_viewport->PlatformUserData = vd;
|
||||
main_viewport->PlatformHandle = (void*)bd->Window;
|
||||
}
|
||||
|
||||
static void ImGui_ImplGlfw_ShutdownPlatformInterface()
|
||||
{
|
||||
ImGui::DestroyPlatformWindows();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// WndProc hook (declared here because we will need access to ImGui_ImplGlfw_ViewportData)
|
||||
#ifdef _WIN32
|
||||
static ImGuiMouseSource GetMouseSourceFromMessageExtraInfo()
|
||||
{
|
||||
LPARAM extra_info = ::GetMessageExtraInfo();
|
||||
if ((extra_info & 0xFFFFFF80) == 0xFF515700)
|
||||
return ImGuiMouseSource_Pen;
|
||||
if ((extra_info & 0xFFFFFF80) == 0xFF515780)
|
||||
return ImGuiMouseSource_TouchScreen;
|
||||
return ImGuiMouseSource_Mouse;
|
||||
}
|
||||
static LRESULT CALLBACK ImGui_ImplGlfw_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||
WNDPROC prev_wndproc = bd->PrevWndProc;
|
||||
ImGuiViewport* viewport = (ImGuiViewport*)::GetPropA(hWnd, "IMGUI_VIEWPORT");
|
||||
if (viewport != NULL)
|
||||
if (ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData)
|
||||
prev_wndproc = vd->PrevWndProc;
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
// GLFW doesn't allow to distinguish Mouse vs TouchScreen vs Pen.
|
||||
// Add support for Win32 (based on imgui_impl_win32), because we rely on _TouchScreen info to trickle inputs differently.
|
||||
case WM_MOUSEMOVE: case WM_NCMOUSEMOVE:
|
||||
case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK: case WM_LBUTTONUP:
|
||||
case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK: case WM_RBUTTONUP:
|
||||
case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK: case WM_MBUTTONUP:
|
||||
case WM_XBUTTONDOWN: case WM_XBUTTONDBLCLK: case WM_XBUTTONUP:
|
||||
ImGui::GetIO().AddMouseSourceEvent(GetMouseSourceFromMessageExtraInfo());
|
||||
break;
|
||||
|
||||
// We have submitted https://github.com/glfw/glfw/pull/1568 to allow GLFW to support "transparent inputs".
|
||||
// In the meanwhile we implement custom per-platform workarounds here (FIXME-VIEWPORT: Implement same work-around for Linux/OSX!)
|
||||
#if !GLFW_HAS_MOUSE_PASSTHROUGH && GLFW_HAS_WINDOW_HOVERED
|
||||
case WM_NCHITTEST:
|
||||
{
|
||||
// Let mouse pass-through the window. This will allow the backend to call io.AddMouseViewportEvent() properly (which is OPTIONAL).
|
||||
// The ImGuiViewportFlags_NoInputs flag is set while dragging a viewport, as want to detect the window behind the one we are dragging.
|
||||
// If you cannot easily access those viewport flags from your windowing/event code: you may manually synchronize its state e.g. in
|
||||
// your main loop after calling UpdatePlatformWindows(). Iterate all viewports/platform windows and pass the flag to your windowing system.
|
||||
if (viewport && (viewport->Flags & ImGuiViewportFlags_NoInputs))
|
||||
return HTTRANSPARENT;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return ::CallWindowProcW(prev_wndproc, hWnd, msg, wParam, lParam);
|
||||
}
|
||||
#endif // #ifdef _WIN32
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#if defined(__clang__)
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
// dear imgui: Platform Backend for GLFW
|
||||
// This needs to be used along with a Renderer (e.g. OpenGL3, Vulkan, WebGPU..)
|
||||
// (Info: GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.)
|
||||
// (Requires: GLFW 3.1+. Prefer GLFW 3.3+ for full feature support.)
|
||||
|
||||
// Implemented features:
|
||||
// [X] Platform: Clipboard support.
|
||||
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen (Windows only).
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy GLFW_KEY_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
||||
// [X] Platform: Gamepad support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange' (note: the resizing cursors requires GLFW 3.4+).
|
||||
// [x] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange' (note: the resizing cursors requires GLFW 3.4+).
|
||||
// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// Issues:
|
||||
// [ ] Platform: Multi-viewport support: ParentViewportID not honored, and so io.ConfigViewportsNoDefaultParent has no effect (minor).
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
@@ -30,6 +35,11 @@ IMGUI_IMPL_API bool ImGui_ImplGlfw_InitForOther(GLFWwindow* window, bool ins
|
||||
IMGUI_IMPL_API void ImGui_ImplGlfw_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplGlfw_NewFrame();
|
||||
|
||||
// Emscripten related initialization phase methods
|
||||
#ifdef __EMSCRIPTEN__
|
||||
IMGUI_IMPL_API void ImGui_ImplGlfw_InstallEmscriptenCanvasResizeCallback(const char* canvas_selector);
|
||||
#endif
|
||||
|
||||
// GLFW callbacks install
|
||||
// - When calling Init with 'install_callbacks=true': ImGui_ImplGlfw_InstallCallbacks() is called. GLFW callbacks will be installed for you. They will chain-call user's previously installed callbacks, if any.
|
||||
// - When calling Init with 'install_callbacks=false': GLFW callbacks won't be installed. You will need to call individual function yourself from your own GLFW callbacks.
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
// Implemented features:
|
||||
// [X] Platform: Partial keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy GLUT values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
||||
// Issues:
|
||||
// Missing features:
|
||||
// [ ] Platform: GLUT is unable to distinguish e.g. Backspace from CTRL+H or TAB from CTRL+I
|
||||
// [ ] Platform: Missing horizontal mouse wheel support.
|
||||
// [ ] Platform: Missing mouse cursor shape/visibility support.
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
// Implemented features:
|
||||
// [X] Platform: Partial keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy GLUT values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
||||
// Issues:
|
||||
// Missing features:
|
||||
// [ ] Platform: GLUT is unable to distinguish e.g. Backspace from CTRL+H or TAB from CTRL+I
|
||||
// [ ] Platform: Missing horizontal mouse wheel support.
|
||||
// [ ] Platform: Missing mouse cursor shape/visibility support.
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'MTLTexture' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'MTLTexture' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
@@ -15,6 +16,7 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2023-XX-XX: Metal: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2022-08-23: Metal: Update deprecated property 'sampleCount'->'rasterSampleCount'.
|
||||
// 2022-07-05: Metal: Add dispatch synchronization.
|
||||
// 2022-06-30: Metal: Use __bridge for ARC based systems.
|
||||
@@ -38,6 +40,12 @@
|
||||
#import <time.h>
|
||||
#import <Metal/Metal.h>
|
||||
|
||||
// Forward Declarations
|
||||
static void ImGui_ImplMetal_InitPlatformInterface();
|
||||
static void ImGui_ImplMetal_ShutdownPlatformInterface();
|
||||
static void ImGui_ImplMetal_CreateDeviceObjectsForPlatformWindows();
|
||||
static void ImGui_ImplMetal_InvalidateDeviceObjectsForPlatformWindows();
|
||||
|
||||
#pragma mark - Support classes
|
||||
|
||||
// A wrapper around a MTLBuffer object that knows the last time it was reused
|
||||
@@ -130,10 +138,14 @@ bool ImGui_ImplMetal_Init(id<MTLDevice> device)
|
||||
io.BackendRendererUserData = (void*)bd;
|
||||
io.BackendRendererName = "imgui_impl_metal";
|
||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional)
|
||||
|
||||
bd->SharedMetalContext = [[MetalContext alloc] init];
|
||||
bd->SharedMetalContext.device = device;
|
||||
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
ImGui_ImplMetal_InitPlatformInterface();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -141,13 +153,14 @@ void ImGui_ImplMetal_Shutdown()
|
||||
{
|
||||
ImGui_ImplMetal_Data* bd = ImGui_ImplMetal_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGui_ImplMetal_ShutdownPlatformInterface();
|
||||
ImGui_ImplMetal_DestroyDeviceObjects();
|
||||
ImGui_ImplMetal_DestroyBackendData();
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.BackendRendererName = nullptr;
|
||||
io.BackendRendererUserData = nullptr;
|
||||
io.BackendFlags &= ~ImGuiBackendFlags_RendererHasVtxOffset;
|
||||
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasViewports);
|
||||
}
|
||||
|
||||
void ImGui_ImplMetal_NewFrame(MTLRenderPassDescriptor* renderPassDescriptor)
|
||||
@@ -365,6 +378,7 @@ bool ImGui_ImplMetal_CreateDeviceObjects(id<MTLDevice> device)
|
||||
depthStencilDescriptor.depthWriteEnabled = NO;
|
||||
depthStencilDescriptor.depthCompareFunction = MTLCompareFunctionAlways;
|
||||
bd->SharedMetalContext.depthStencilState = [device newDepthStencilStateWithDescriptor:depthStencilDescriptor];
|
||||
ImGui_ImplMetal_CreateDeviceObjectsForPlatformWindows();
|
||||
ImGui_ImplMetal_CreateFontsTexture(device);
|
||||
|
||||
return true;
|
||||
@@ -374,9 +388,155 @@ void ImGui_ImplMetal_DestroyDeviceObjects()
|
||||
{
|
||||
ImGui_ImplMetal_Data* bd = ImGui_ImplMetal_GetBackendData();
|
||||
ImGui_ImplMetal_DestroyFontsTexture();
|
||||
ImGui_ImplMetal_InvalidateDeviceObjectsForPlatformWindows();
|
||||
[bd->SharedMetalContext.renderPipelineStateCache removeAllObjects];
|
||||
}
|
||||
|
||||
#pragma mark - Multi-viewport support
|
||||
|
||||
#import <QuartzCore/CAMetalLayer.h>
|
||||
|
||||
#if TARGET_OS_OSX
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
|
||||
// This is an _advanced_ and _optional_ feature, allowing the back-end to create and handle multiple viewports simultaneously.
|
||||
// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first..
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
|
||||
struct ImGuiViewportDataMetal
|
||||
{
|
||||
CAMetalLayer* MetalLayer;
|
||||
id<MTLCommandQueue> CommandQueue;
|
||||
MTLRenderPassDescriptor* RenderPassDescriptor;
|
||||
void* Handle = nullptr;
|
||||
bool FirstFrame = true;
|
||||
};
|
||||
|
||||
static void ImGui_ImplMetal_CreateWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplMetal_Data* bd = ImGui_ImplMetal_GetBackendData();
|
||||
ImGuiViewportDataMetal* data = IM_NEW(ImGuiViewportDataMetal)();
|
||||
viewport->RendererUserData = data;
|
||||
|
||||
// PlatformHandleRaw should always be a NSWindow*, whereas PlatformHandle might be a higher-level handle (e.g. GLFWWindow*, SDL_Window*).
|
||||
// Some back-ends will leave PlatformHandleRaw == 0, in which case we assume PlatformHandle will contain the NSWindow*.
|
||||
void* handle = viewport->PlatformHandleRaw ? viewport->PlatformHandleRaw : viewport->PlatformHandle;
|
||||
IM_ASSERT(handle != nullptr);
|
||||
|
||||
id<MTLDevice> device = bd->SharedMetalContext.device;
|
||||
CAMetalLayer* layer = [CAMetalLayer layer];
|
||||
layer.device = device;
|
||||
layer.framebufferOnly = YES;
|
||||
layer.pixelFormat = bd->SharedMetalContext.framebufferDescriptor.colorPixelFormat;
|
||||
#if TARGET_OS_OSX
|
||||
NSWindow* window = (__bridge NSWindow*)handle;
|
||||
NSView* view = window.contentView;
|
||||
view.layer = layer;
|
||||
view.wantsLayer = YES;
|
||||
#endif
|
||||
data->MetalLayer = layer;
|
||||
data->CommandQueue = [device newCommandQueue];
|
||||
data->RenderPassDescriptor = [[MTLRenderPassDescriptor alloc] init];
|
||||
data->Handle = handle;
|
||||
}
|
||||
|
||||
static void ImGui_ImplMetal_DestroyWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
// The main viewport (owned by the application) will always have RendererUserData == 0 since we didn't create the data for it.
|
||||
if (ImGuiViewportDataMetal* data = (ImGuiViewportDataMetal*)viewport->RendererUserData)
|
||||
IM_DELETE(data);
|
||||
viewport->RendererUserData = nullptr;
|
||||
}
|
||||
|
||||
inline static CGSize MakeScaledSize(CGSize size, CGFloat scale)
|
||||
{
|
||||
return CGSizeMake(size.width * scale, size.height * scale);
|
||||
}
|
||||
|
||||
static void ImGui_ImplMetal_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
|
||||
{
|
||||
ImGuiViewportDataMetal* data = (ImGuiViewportDataMetal*)viewport->RendererUserData;
|
||||
data->MetalLayer.drawableSize = MakeScaledSize(CGSizeMake(size.x, size.y), viewport->DpiScale);
|
||||
}
|
||||
|
||||
static void ImGui_ImplMetal_RenderWindow(ImGuiViewport* viewport, void*)
|
||||
{
|
||||
ImGuiViewportDataMetal* data = (ImGuiViewportDataMetal*)viewport->RendererUserData;
|
||||
|
||||
#if TARGET_OS_OSX
|
||||
void* handle = viewport->PlatformHandleRaw ? viewport->PlatformHandleRaw : viewport->PlatformHandle;
|
||||
NSWindow* window = (__bridge NSWindow*)handle;
|
||||
|
||||
// Always render the first frame, regardless of occlusionState, to avoid an initial flicker
|
||||
if ((window.occlusionState & NSWindowOcclusionStateVisible) == 0 && !data->FirstFrame)
|
||||
{
|
||||
// Do not render windows which are completely occluded. Calling -[CAMetalLayer nextDrawable] will hang for
|
||||
// approximately 1 second if the Metal layer is completely occluded.
|
||||
return;
|
||||
}
|
||||
data->FirstFrame = false;
|
||||
|
||||
viewport->DpiScale = (float)window.backingScaleFactor;
|
||||
if (data->MetalLayer.contentsScale != viewport->DpiScale)
|
||||
{
|
||||
data->MetalLayer.contentsScale = viewport->DpiScale;
|
||||
data->MetalLayer.drawableSize = MakeScaledSize(window.frame.size, viewport->DpiScale);
|
||||
}
|
||||
viewport->DrawData->FramebufferScale = ImVec2(viewport->DpiScale, viewport->DpiScale);
|
||||
#endif
|
||||
|
||||
id <CAMetalDrawable> drawable = [data->MetalLayer nextDrawable];
|
||||
if (drawable == nil)
|
||||
return;
|
||||
|
||||
MTLRenderPassDescriptor* renderPassDescriptor = data->RenderPassDescriptor;
|
||||
renderPassDescriptor.colorAttachments[0].texture = drawable.texture;
|
||||
renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(0, 0, 0, 0);
|
||||
if ((viewport->Flags & ImGuiViewportFlags_NoRendererClear) == 0)
|
||||
renderPassDescriptor.colorAttachments[0].loadAction = MTLLoadActionClear;
|
||||
|
||||
id <MTLCommandBuffer> commandBuffer = [data->CommandQueue commandBuffer];
|
||||
id <MTLRenderCommandEncoder> renderEncoder = [commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor];
|
||||
ImGui_ImplMetal_RenderDrawData(viewport->DrawData, commandBuffer, renderEncoder);
|
||||
[renderEncoder endEncoding];
|
||||
|
||||
[commandBuffer presentDrawable:drawable];
|
||||
[commandBuffer commit];
|
||||
}
|
||||
|
||||
static void ImGui_ImplMetal_InitPlatformInterface()
|
||||
{
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
platform_io.Renderer_CreateWindow = ImGui_ImplMetal_CreateWindow;
|
||||
platform_io.Renderer_DestroyWindow = ImGui_ImplMetal_DestroyWindow;
|
||||
platform_io.Renderer_SetWindowSize = ImGui_ImplMetal_SetWindowSize;
|
||||
platform_io.Renderer_RenderWindow = ImGui_ImplMetal_RenderWindow;
|
||||
}
|
||||
|
||||
static void ImGui_ImplMetal_ShutdownPlatformInterface()
|
||||
{
|
||||
ImGui::DestroyPlatformWindows();
|
||||
}
|
||||
|
||||
static void ImGui_ImplMetal_CreateDeviceObjectsForPlatformWindows()
|
||||
{
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
for (int i = 1; i < platform_io.Viewports.Size; i++)
|
||||
if (!platform_io.Viewports[i]->RendererUserData)
|
||||
ImGui_ImplMetal_CreateWindow(platform_io.Viewports[i]);
|
||||
}
|
||||
|
||||
static void ImGui_ImplMetal_InvalidateDeviceObjectsForPlatformWindows()
|
||||
{
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
for (int i = 1; i < platform_io.Viewports.Size; i++)
|
||||
if (platform_io.Viewports[i]->RendererUserData)
|
||||
ImGui_ImplMetal_DestroyWindow(platform_io.Viewports[i]);
|
||||
}
|
||||
|
||||
#pragma mark - MetalBuffer implementation
|
||||
|
||||
@implementation MetalBuffer
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
@@ -22,6 +23,7 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2023-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||
// 2021-12-08: OpenGL: Fixed mishandling of the the ImDrawCmd::IdxOffset field! This is an old bug but it never had an effect until some internal rendering changes in 1.86.
|
||||
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
|
||||
@@ -79,6 +81,10 @@ static ImGui_ImplOpenGL2_Data* ImGui_ImplOpenGL2_GetBackendData()
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplOpenGL2_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||
}
|
||||
|
||||
// Forward Declarations
|
||||
static void ImGui_ImplOpenGL2_InitPlatformInterface();
|
||||
static void ImGui_ImplOpenGL2_ShutdownPlatformInterface();
|
||||
|
||||
// Functions
|
||||
bool ImGui_ImplOpenGL2_Init()
|
||||
{
|
||||
@@ -89,6 +95,10 @@ bool ImGui_ImplOpenGL2_Init()
|
||||
ImGui_ImplOpenGL2_Data* bd = IM_NEW(ImGui_ImplOpenGL2_Data)();
|
||||
io.BackendRendererUserData = (void*)bd;
|
||||
io.BackendRendererName = "imgui_impl_opengl2";
|
||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional)
|
||||
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
ImGui_ImplOpenGL2_InitPlatformInterface();
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -99,9 +109,11 @@ void ImGui_ImplOpenGL2_Shutdown()
|
||||
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
ImGui_ImplOpenGL2_ShutdownPlatformInterface();
|
||||
ImGui_ImplOpenGL2_DestroyDeviceObjects();
|
||||
io.BackendRendererName = nullptr;
|
||||
io.BackendRendererUserData = nullptr;
|
||||
io.BackendFlags &= ~ImGuiBackendFlags_RendererHasViewports;
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
@@ -293,6 +305,35 @@ void ImGui_ImplOpenGL2_DestroyDeviceObjects()
|
||||
ImGui_ImplOpenGL2_DestroyFontsTexture();
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
|
||||
// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously.
|
||||
// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first..
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
|
||||
static void ImGui_ImplOpenGL2_RenderWindow(ImGuiViewport* viewport, void*)
|
||||
{
|
||||
if (!(viewport->Flags & ImGuiViewportFlags_NoRendererClear))
|
||||
{
|
||||
ImVec4 clear_color = ImVec4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
ImGui_ImplOpenGL2_RenderDrawData(viewport->DrawData);
|
||||
}
|
||||
|
||||
static void ImGui_ImplOpenGL2_InitPlatformInterface()
|
||||
{
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
platform_io.Renderer_RenderWindow = ImGui_ImplOpenGL2_RenderWindow;
|
||||
}
|
||||
|
||||
static void ImGui_ImplOpenGL2_ShutdownPlatformInterface()
|
||||
{
|
||||
ImGui::DestroyPlatformWindows();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#if defined(__clang__)
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [x] Renderer: Large meshes support (64k+ vertices) with 16-bit indices (Desktop OpenGL only).
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices (Desktop OpenGL only).
|
||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// About WebGL/ES:
|
||||
// - You need to '#define IMGUI_IMPL_OPENGL_ES2' or '#define IMGUI_IMPL_OPENGL_ES3' to use WebGL or OpenGL ES.
|
||||
@@ -22,7 +23,9 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2023-11-08: OpenGL: Update GL3W based imgui_impl_opengl3_loader.h to load "libGL.so" instead of "libGL.so.1", accomodating for NetBSD systems having only "libGL.so.3" available. (#6983)
|
||||
// 2023-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2024-01-09: OpenGL: Update GL3W based imgui_impl_opengl3_loader.h to load "libGL.so" and variants, fixing regression on distros missing a symlink.
|
||||
// 2023-11-08: OpenGL: Update GL3W based imgui_impl_opengl3_loader.h to load "libGL.so" instead of "libGL.so.1", accommodating for NetBSD systems having only "libGL.so.3" available. (#6983)
|
||||
// 2023-10-05: OpenGL: Rename symbols in our internal loader so that LTO compilation with another copy of gl3w is possible. (#6875, #6668, #4445)
|
||||
// 2023-06-20: OpenGL: Fixed erroneous use glGetIntegerv(GL_CONTEXT_PROFILE_MASK) on contexts lower than 3.2. (#6539, #6333)
|
||||
// 2023-05-09: OpenGL: Support for glBindSampler() backup/restore on ES3. (#6375)
|
||||
@@ -241,6 +244,10 @@ static ImGui_ImplOpenGL3_Data* ImGui_ImplOpenGL3_GetBackendData()
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplOpenGL3_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||
}
|
||||
|
||||
// Forward Declarations
|
||||
static void ImGui_ImplOpenGL3_InitPlatformInterface();
|
||||
static void ImGui_ImplOpenGL3_ShutdownPlatformInterface();
|
||||
|
||||
// OpenGL vertex attribute state (for ES 1.0 and ES 2.0 only)
|
||||
#ifndef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY
|
||||
struct ImGui_ImplOpenGL3_VtxAttribState
|
||||
@@ -332,6 +339,7 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
|
||||
if (bd->GlVersion >= 320)
|
||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
||||
#endif
|
||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional)
|
||||
|
||||
// Store GLSL version string so we can refer to it later in case we recreate shaders.
|
||||
// Note: GLSL version is NOT the same as GL version. Leave this to nullptr if unsure.
|
||||
@@ -369,6 +377,9 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
ImGui_ImplOpenGL3_InitPlatformInterface();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -378,10 +389,11 @@ void ImGui_ImplOpenGL3_Shutdown()
|
||||
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
ImGui_ImplOpenGL3_ShutdownPlatformInterface();
|
||||
ImGui_ImplOpenGL3_DestroyDeviceObjects();
|
||||
io.BackendRendererName = nullptr;
|
||||
io.BackendRendererUserData = nullptr;
|
||||
io.BackendFlags &= ~ImGuiBackendFlags_RendererHasVtxOffset;
|
||||
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasViewports);
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
@@ -935,6 +947,34 @@ void ImGui_ImplOpenGL3_DestroyDeviceObjects()
|
||||
ImGui_ImplOpenGL3_DestroyFontsTexture();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
|
||||
// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously.
|
||||
// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first..
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
|
||||
static void ImGui_ImplOpenGL3_RenderWindow(ImGuiViewport* viewport, void*)
|
||||
{
|
||||
if (!(viewport->Flags & ImGuiViewportFlags_NoRendererClear))
|
||||
{
|
||||
ImVec4 clear_color = ImVec4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
ImGui_ImplOpenGL3_RenderDrawData(viewport->DrawData);
|
||||
}
|
||||
|
||||
static void ImGui_ImplOpenGL3_InitPlatformInterface()
|
||||
{
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
platform_io.Renderer_RenderWindow = ImGui_ImplOpenGL3_RenderWindow;
|
||||
}
|
||||
|
||||
static void ImGui_ImplOpenGL3_ShutdownPlatformInterface()
|
||||
{
|
||||
ImGui::DestroyPlatformWindows();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#if defined(__GNUC__)
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [x] Renderer: Large meshes support (64k+ vertices) with 16-bit indices (Desktop OpenGL only).
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices (Desktop OpenGL only).
|
||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// About WebGL/ES:
|
||||
// - You need to '#define IMGUI_IMPL_OPENGL_ES2' or '#define IMGUI_IMPL_OPENGL_ES3' to use WebGL or OpenGL ES.
|
||||
|
||||
@@ -608,7 +608,7 @@ extern "C" {
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||
#define GL3W_ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||
|
||||
#if defined(_WIN32)
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
@@ -668,6 +668,10 @@ static int open_libgl(void)
|
||||
{
|
||||
// While most systems use libGL.so.1, NetBSD seems to use that libGL.so.3. See https://github.com/ocornut/imgui/issues/6983
|
||||
libgl = dlopen("libGL.so", RTLD_LAZY | RTLD_LOCAL);
|
||||
if (!libgl)
|
||||
libgl = dlopen("libGL.so.1", RTLD_LAZY | RTLD_LOCAL);
|
||||
if (!libgl)
|
||||
libgl = dlopen("libGL.so.3", RTLD_LAZY | RTLD_LOCAL);
|
||||
if (!libgl)
|
||||
return GL3W_ERROR_LIBRARY_OPEN;
|
||||
*(void **)(&glx_get_proc_address) = dlsym(libgl, "glXGetProcAddressARB");
|
||||
@@ -800,7 +804,7 @@ GL3W_API union ImGL3WProcs imgl3wProcs;
|
||||
static void load_procs(GL3WGetProcAddressProc proc)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < ARRAY_SIZE(proc_names); i++)
|
||||
for (i = 0; i < GL3W_ARRAY_SIZE(proc_names); i++)
|
||||
imgl3wProcs.ptr[i] = proc(proc_names[i]);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
// [X] Platform: OSX clipboard is supported within core Dear ImGui (no specific code in this backend).
|
||||
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [X] Platform: IME support.
|
||||
// [x] Platform: Multi-viewport / platform windows.
|
||||
// - [ ] Window size not correctly reported when enabling io.ConfigViewportsNoDecoration
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
// [X] Platform: OSX clipboard is supported within core Dear ImGui (no specific code in this backend).
|
||||
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [X] Platform: IME support.
|
||||
// [x] Platform: Multi-viewport / platform windows.
|
||||
// - [ ] Window size not correctly reported when enabling io.ConfigViewportsNoDecoration
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
@@ -29,6 +31,7 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2023-XX-XX: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2023-10-05: Inputs: Added support for extra ImGuiKey values: F13 to F20 function keys. Stopped mapping F13 into PrintScreen.
|
||||
// 2023-04-09: Inputs: Added support for io.AddMouseSourceEvent() to discriminate ImGuiMouseSource_Mouse/ImGuiMouseSource_Pen.
|
||||
// 2023-02-01: Fixed scroll wheel scaling for devices emitting events with hasPreciseScrollingDeltas==false (e.g. non-Apple mices).
|
||||
@@ -80,6 +83,7 @@ struct ImGui_ImplOSX_Data
|
||||
KeyEventResponder* KeyEventResponder;
|
||||
NSTextInputContext* InputContext;
|
||||
id Monitor;
|
||||
NSWindow* Window;
|
||||
|
||||
ImGui_ImplOSX_Data() { memset(this, 0, sizeof(*this)); }
|
||||
};
|
||||
@@ -91,6 +95,9 @@ static void ImGui_ImplOSX_DestroyBackendData() { IM_DELETE(
|
||||
static inline CFTimeInterval GetMachAbsoluteTimeInSeconds() { return (CFTimeInterval)(double)(clock_gettime_nsec_np(CLOCK_UPTIME_RAW) / 1e9); }
|
||||
|
||||
// Forward Declarations
|
||||
static void ImGui_ImplOSX_InitPlatformInterface();
|
||||
static void ImGui_ImplOSX_ShutdownPlatformInterface();
|
||||
static void ImGui_ImplOSX_UpdateMonitors();
|
||||
static void ImGui_ImplOSX_AddTrackingArea(NSView* _Nonnull view);
|
||||
static bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view);
|
||||
|
||||
@@ -134,12 +141,28 @@ static bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view);
|
||||
|
||||
- (void)updateImePosWithView:(NSView *)view
|
||||
{
|
||||
NSWindow *window = view.window;
|
||||
NSWindow* window = view.window;
|
||||
if (!window)
|
||||
return;
|
||||
NSRect contentRect = [window contentRectForFrameRect:window.frame];
|
||||
NSRect rect = NSMakeRect(_posX, contentRect.size.height - _posY, 0, 0);
|
||||
_imeRect = [window convertRectToScreen:rect];
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
NSRect frame = window.frame;
|
||||
NSRect contentRect = window.contentLayoutRect;
|
||||
if (window.styleMask & NSWindowStyleMaskFullSizeContentView) // No title bar windows should be considered.
|
||||
contentRect = frame;
|
||||
|
||||
NSRect firstScreenFrame = NSScreen.screens[0].frame;
|
||||
_imeRect = NSMakeRect(_posX, _posY, 0, 0);
|
||||
_imeRect.origin.y = firstScreenFrame.size.height - _imeRect.size.height - _imeRect.origin.y; // Opposite of ConvertNSRect()
|
||||
}
|
||||
else
|
||||
{
|
||||
NSRect contentRect = [window contentRectForFrameRect:window.frame];
|
||||
NSRect rect = NSMakeRect(_posX, contentRect.size.height - _posY, 0, 0);
|
||||
_imeRect = [window convertRectToScreen:rect];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)viewDidMoveToWindow
|
||||
@@ -234,6 +257,7 @@ static bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view);
|
||||
|
||||
- (void)onApplicationBecomeActive:(NSNotification*)aNotification;
|
||||
- (void)onApplicationBecomeInactive:(NSNotification*)aNotification;
|
||||
- (void)displaysDidChange:(NSNotification*)aNotification;
|
||||
|
||||
@end
|
||||
|
||||
@@ -251,6 +275,11 @@ static bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view);
|
||||
io.AddFocusEvent(false);
|
||||
}
|
||||
|
||||
- (void)displaysDidChange:(NSNotification*)aNotification
|
||||
{
|
||||
ImGui_ImplOSX_UpdateMonitors();
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
// Functions
|
||||
@@ -398,9 +427,16 @@ bool ImGui_ImplOSX_Init(NSView* view)
|
||||
// Setup backend capabilities flags
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
|
||||
//io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used)
|
||||
io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports; // We can create multi-viewports on the Platform side (optional)
|
||||
//io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport; // We can call io.AddMouseViewportEvent() with correct data (optional)
|
||||
io.BackendPlatformName = "imgui_impl_osx";
|
||||
|
||||
bd->Observer = [ImGuiObserver new];
|
||||
bd->Window = view.window ?: NSApp.orderedWindows.firstObject;
|
||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||
main_viewport->PlatformHandle = main_viewport->PlatformHandleRaw = (__bridge_retained void*)bd->Window;
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
ImGui_ImplOSX_InitPlatformInterface();
|
||||
|
||||
// Load cursors. Some of them are undocumented.
|
||||
bd->MouseCursorHidden = false;
|
||||
@@ -490,12 +526,12 @@ void ImGui_ImplOSX_Shutdown()
|
||||
bd->Monitor = nullptr;
|
||||
}
|
||||
|
||||
ImGui_ImplOSX_ShutdownPlatformInterface();
|
||||
ImGui_ImplOSX_DestroyBackendData();
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.BackendPlatformName = nullptr;
|
||||
io.BackendPlatformUserData = nullptr;
|
||||
io.BackendFlags &= ~(ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_HasGamepad);
|
||||
io.BackendFlags &= ~(ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_HasGamepad | ImGuiBackendFlags_PlatformHasViewports);
|
||||
}
|
||||
|
||||
static void ImGui_ImplOSX_UpdateMouseCursor()
|
||||
@@ -672,14 +708,23 @@ static bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view)
|
||||
|
||||
if (event.type == NSEventTypeMouseMoved || event.type == NSEventTypeLeftMouseDragged || event.type == NSEventTypeRightMouseDragged || event.type == NSEventTypeOtherMouseDragged)
|
||||
{
|
||||
NSPoint mousePoint = event.locationInWindow;
|
||||
if (event.window == nil)
|
||||
mousePoint = [[view window] convertPointFromScreen:mousePoint];
|
||||
mousePoint = [view convertPoint:mousePoint fromView:nil];
|
||||
if ([view isFlipped])
|
||||
mousePoint = NSMakePoint(mousePoint.x, mousePoint.y);
|
||||
NSPoint mousePoint;
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
mousePoint = NSEvent.mouseLocation;
|
||||
mousePoint.y = CGDisplayPixelsHigh(kCGDirectMainDisplay) - mousePoint.y; // Normalize y coordinate to top-left of main display.
|
||||
}
|
||||
else
|
||||
mousePoint = NSMakePoint(mousePoint.x, view.bounds.size.height - mousePoint.y);
|
||||
{
|
||||
mousePoint = event.locationInWindow;
|
||||
if (event.window == nil)
|
||||
mousePoint = [[view window] convertPointFromScreen:mousePoint];
|
||||
mousePoint = [view convertPoint:mousePoint fromView:nil]; // Convert to local coordinates of view
|
||||
if ([view isFlipped])
|
||||
mousePoint = NSMakePoint(mousePoint.x, mousePoint.y);
|
||||
else
|
||||
mousePoint = NSMakePoint(mousePoint.x, view.bounds.size.height - mousePoint.y);
|
||||
}
|
||||
io.AddMouseSourceEvent(GetMouseSource(event));
|
||||
io.AddMousePosEvent((float)mousePoint.x, (float)mousePoint.y);
|
||||
return io.WantCaptureMouse;
|
||||
@@ -807,6 +852,295 @@ static void ImGui_ImplOSX_AddTrackingArea(NSView* _Nonnull view)
|
||||
}];
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
|
||||
// This is an _advanced_ and _optional_ feature, allowing the back-end to create and handle multiple viewports simultaneously.
|
||||
// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first..
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
|
||||
struct ImGuiViewportDataOSX
|
||||
{
|
||||
NSWindow* Window;
|
||||
bool WindowOwned;
|
||||
|
||||
ImGuiViewportDataOSX() { WindowOwned = false; }
|
||||
~ImGuiViewportDataOSX() { IM_ASSERT(Window == nil); }
|
||||
};
|
||||
|
||||
@interface ImGui_ImplOSX_Window: NSWindow
|
||||
@end
|
||||
|
||||
@implementation ImGui_ImplOSX_Window
|
||||
|
||||
- (BOOL)canBecomeKeyWindow
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
static void ConvertNSRect(NSRect* r)
|
||||
{
|
||||
NSRect firstScreenFrame = NSScreen.screens[0].frame;
|
||||
IM_ASSERT(firstScreenFrame.origin.x == 0 && firstScreenFrame.origin.y == 0);
|
||||
r->origin.y = firstScreenFrame.size.height - r->origin.y - r->size.height;
|
||||
}
|
||||
|
||||
static void ImGui_ImplOSX_CreateWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplOSX_Data* bd = ImGui_ImplOSX_GetBackendData();
|
||||
ImGuiViewportDataOSX* data = IM_NEW(ImGuiViewportDataOSX)();
|
||||
viewport->PlatformUserData = data;
|
||||
|
||||
NSScreen* screen = bd->Window.screen;
|
||||
NSRect rect = NSMakeRect(viewport->Pos.x, viewport->Pos.y, viewport->Size.x, viewport->Size.y);
|
||||
ConvertNSRect(&rect);
|
||||
|
||||
NSWindowStyleMask styleMask = 0;
|
||||
if (viewport->Flags & ImGuiViewportFlags_NoDecoration)
|
||||
styleMask |= NSWindowStyleMaskBorderless;
|
||||
else
|
||||
styleMask |= NSWindowStyleMaskTitled | NSWindowStyleMaskResizable | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable;
|
||||
|
||||
NSWindow* window = [[ImGui_ImplOSX_Window alloc] initWithContentRect:rect
|
||||
styleMask:styleMask
|
||||
backing:NSBackingStoreBuffered
|
||||
defer:YES
|
||||
screen:screen];
|
||||
if (viewport->Flags & ImGuiViewportFlags_TopMost)
|
||||
[window setLevel:NSFloatingWindowLevel];
|
||||
|
||||
window.title = @"Untitled";
|
||||
window.opaque = YES;
|
||||
|
||||
KeyEventResponder* view = [[KeyEventResponder alloc] initWithFrame:rect];
|
||||
if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6)
|
||||
[view setWantsBestResolutionOpenGLSurface:YES];
|
||||
|
||||
window.contentView = view;
|
||||
|
||||
data->Window = window;
|
||||
data->WindowOwned = true;
|
||||
viewport->PlatformRequestResize = false;
|
||||
viewport->PlatformHandle = viewport->PlatformHandleRaw = (__bridge_retained void*)window;
|
||||
}
|
||||
|
||||
static void ImGui_ImplOSX_DestroyWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
NSWindow* window = (__bridge_transfer NSWindow*)viewport->PlatformHandleRaw;
|
||||
window = nil;
|
||||
|
||||
if (ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData)
|
||||
{
|
||||
NSWindow* window = data->Window;
|
||||
if (window != nil && data->WindowOwned)
|
||||
{
|
||||
window.contentView = nil;
|
||||
window.contentViewController = nil;
|
||||
[window orderOut:nil];
|
||||
}
|
||||
data->Window = nil;
|
||||
IM_DELETE(data);
|
||||
}
|
||||
viewport->PlatformUserData = viewport->PlatformHandle = viewport->PlatformHandleRaw = nullptr;
|
||||
}
|
||||
|
||||
static void ImGui_ImplOSX_ShowWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData;
|
||||
IM_ASSERT(data->Window != 0);
|
||||
|
||||
if (viewport->Flags & ImGuiViewportFlags_NoFocusOnAppearing)
|
||||
[data->Window orderFront:nil];
|
||||
else
|
||||
[data->Window makeKeyAndOrderFront:nil];
|
||||
|
||||
[data->Window setIsVisible:YES];
|
||||
}
|
||||
|
||||
static ImVec2 ImGui_ImplOSX_GetWindowPos(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData;
|
||||
IM_ASSERT(data->Window != 0);
|
||||
|
||||
NSWindow* window = data->Window;
|
||||
NSRect frame = window.frame;
|
||||
NSRect contentRect = window.contentLayoutRect;
|
||||
if (window.styleMask & NSWindowStyleMaskFullSizeContentView) // No title bar windows should be considered.
|
||||
contentRect = frame;
|
||||
|
||||
NSRect firstScreenFrame = NSScreen.screens[0].frame;
|
||||
return ImVec2(frame.origin.x, firstScreenFrame.size.height - frame.origin.y - contentRect.size.height);
|
||||
}
|
||||
|
||||
static void ImGui_ImplOSX_SetWindowPos(ImGuiViewport* viewport, ImVec2 pos)
|
||||
{
|
||||
ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData;
|
||||
IM_ASSERT(data->Window != 0);
|
||||
|
||||
NSWindow* window = data->Window;
|
||||
NSSize size = window.frame.size;
|
||||
|
||||
NSRect r = NSMakeRect(pos.x, pos.y, size.width, size.height);
|
||||
ConvertNSRect(&r);
|
||||
[window setFrameOrigin:r.origin];
|
||||
}
|
||||
|
||||
static ImVec2 ImGui_ImplOSX_GetWindowSize(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData;
|
||||
IM_ASSERT(data->Window != 0);
|
||||
|
||||
NSWindow* window = data->Window;
|
||||
NSSize size = window.contentLayoutRect.size;
|
||||
return ImVec2(size.width, size.height);
|
||||
}
|
||||
|
||||
static void ImGui_ImplOSX_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
|
||||
{
|
||||
ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData;
|
||||
IM_ASSERT(data->Window != 0);
|
||||
|
||||
NSWindow* window = data->Window;
|
||||
NSRect rect = window.frame;
|
||||
rect.origin.y -= (size.y - rect.size.height);
|
||||
rect.size.width = size.x;
|
||||
rect.size.height = size.y;
|
||||
[window setFrame:rect display:YES];
|
||||
}
|
||||
|
||||
static void ImGui_ImplOSX_SetWindowFocus(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplOSX_Data* bd = ImGui_ImplOSX_GetBackendData();
|
||||
ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData;
|
||||
IM_ASSERT(data->Window != 0);
|
||||
[data->Window makeKeyAndOrderFront:bd->Window];
|
||||
}
|
||||
|
||||
static bool ImGui_ImplOSX_GetWindowFocus(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData;
|
||||
IM_ASSERT(data->Window != 0);
|
||||
|
||||
return data->Window.isKeyWindow;
|
||||
}
|
||||
|
||||
static bool ImGui_ImplOSX_GetWindowMinimized(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData;
|
||||
IM_ASSERT(data->Window != 0);
|
||||
|
||||
return data->Window.isMiniaturized;
|
||||
}
|
||||
|
||||
static void ImGui_ImplOSX_SetWindowTitle(ImGuiViewport* viewport, const char* title)
|
||||
{
|
||||
ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData;
|
||||
IM_ASSERT(data->Window != 0);
|
||||
|
||||
data->Window.title = [NSString stringWithUTF8String:title];
|
||||
}
|
||||
|
||||
static void ImGui_ImplOSX_SetWindowAlpha(ImGuiViewport* viewport, float alpha)
|
||||
{
|
||||
ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData;
|
||||
IM_ASSERT(data->Window != 0);
|
||||
IM_ASSERT(alpha >= 0.0f && alpha <= 1.0f);
|
||||
|
||||
data->Window.alphaValue = alpha;
|
||||
}
|
||||
|
||||
static float ImGui_ImplOSX_GetWindowDpiScale(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData;
|
||||
IM_ASSERT(data->Window != 0);
|
||||
|
||||
return data->Window.backingScaleFactor;
|
||||
}
|
||||
|
||||
static void ImGui_ImplOSX_UpdateMonitors()
|
||||
{
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
platform_io.Monitors.resize(0);
|
||||
|
||||
NSRect firstScreenFrame = NSScreen.screens[0].frame;
|
||||
IM_ASSERT(firstScreenFrame.origin.x == 0 && firstScreenFrame.origin.y == 0);
|
||||
|
||||
for (NSScreen* screen in NSScreen.screens)
|
||||
{
|
||||
NSRect frame = screen.frame;
|
||||
NSRect visibleFrame = screen.visibleFrame;
|
||||
ConvertNSRect(&frame);
|
||||
ConvertNSRect(&visibleFrame);
|
||||
|
||||
ImGuiPlatformMonitor imgui_monitor;
|
||||
imgui_monitor.MainPos = ImVec2(frame.origin.x, frame.origin.y);
|
||||
imgui_monitor.MainSize = ImVec2(frame.size.width, frame.size.height);
|
||||
imgui_monitor.WorkPos = ImVec2(visibleFrame.origin.x, visibleFrame.origin.y);
|
||||
imgui_monitor.WorkSize = ImVec2(visibleFrame.size.width, visibleFrame.size.height);
|
||||
imgui_monitor.DpiScale = screen.backingScaleFactor;
|
||||
imgui_monitor.PlatformHandle = (__bridge_retained void*)screen;
|
||||
|
||||
platform_io.Monitors.push_back(imgui_monitor);
|
||||
}
|
||||
}
|
||||
|
||||
static void ImGui_ImplOSX_InitPlatformInterface()
|
||||
{
|
||||
ImGui_ImplOSX_Data* bd = ImGui_ImplOSX_GetBackendData();
|
||||
ImGui_ImplOSX_UpdateMonitors();
|
||||
|
||||
// Register platform interface (will be coupled with a renderer interface)
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
platform_io.Platform_CreateWindow = ImGui_ImplOSX_CreateWindow;
|
||||
platform_io.Platform_DestroyWindow = ImGui_ImplOSX_DestroyWindow;
|
||||
platform_io.Platform_ShowWindow = ImGui_ImplOSX_ShowWindow;
|
||||
platform_io.Platform_SetWindowPos = ImGui_ImplOSX_SetWindowPos;
|
||||
platform_io.Platform_GetWindowPos = ImGui_ImplOSX_GetWindowPos;
|
||||
platform_io.Platform_SetWindowSize = ImGui_ImplOSX_SetWindowSize;
|
||||
platform_io.Platform_GetWindowSize = ImGui_ImplOSX_GetWindowSize;
|
||||
platform_io.Platform_SetWindowFocus = ImGui_ImplOSX_SetWindowFocus;
|
||||
platform_io.Platform_GetWindowFocus = ImGui_ImplOSX_GetWindowFocus;
|
||||
platform_io.Platform_GetWindowMinimized = ImGui_ImplOSX_GetWindowMinimized;
|
||||
platform_io.Platform_SetWindowTitle = ImGui_ImplOSX_SetWindowTitle;
|
||||
platform_io.Platform_SetWindowAlpha = ImGui_ImplOSX_SetWindowAlpha;
|
||||
platform_io.Platform_GetWindowDpiScale = ImGui_ImplOSX_GetWindowDpiScale; // FIXME-DPI
|
||||
|
||||
// Register main window handle (which is owned by the main application, not by us)
|
||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||
ImGuiViewportDataOSX* data = IM_NEW(ImGuiViewportDataOSX)();
|
||||
data->Window = bd->Window;
|
||||
data->WindowOwned = false;
|
||||
main_viewport->PlatformUserData = data;
|
||||
main_viewport->PlatformHandle = (__bridge void*)bd->Window;
|
||||
|
||||
[NSNotificationCenter.defaultCenter addObserver:bd->Observer
|
||||
selector:@selector(displaysDidChange:)
|
||||
name:NSApplicationDidChangeScreenParametersNotification
|
||||
object:nil];
|
||||
}
|
||||
|
||||
static void ImGui_ImplOSX_ShutdownPlatformInterface()
|
||||
{
|
||||
ImGui_ImplOSX_Data* bd = ImGui_ImplOSX_GetBackendData();
|
||||
[NSNotificationCenter.defaultCenter removeObserver:bd->Observer
|
||||
name:NSApplicationDidChangeScreenParametersNotification
|
||||
object:nil];
|
||||
bd->Observer = nullptr;
|
||||
bd->Window = nullptr;
|
||||
if (bd->Monitor != nullptr)
|
||||
{
|
||||
[NSEvent removeMonitor:bd->Monitor];
|
||||
bd->Monitor = nullptr;
|
||||
}
|
||||
|
||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||
ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)main_viewport->PlatformUserData;
|
||||
IM_DELETE(data);
|
||||
main_viewport->PlatformUserData = nullptr;
|
||||
ImGui::DestroyPlatformWindows();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
||||
@@ -9,7 +9,10 @@
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy SDL_SCANCODE_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
||||
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// [X] Platform: Basic IME support. App needs to call 'SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");' before SDL_CreateWindow()!.
|
||||
// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
// Missing features:
|
||||
// [ ] Platform: Multi-viewport + Minimized windows seems to break mouse wheel events (at least under Windows).
|
||||
// [x] Platform: Basic IME support. App needs to call 'SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");' before SDL_CreateWindow()!.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
@@ -21,6 +24,7 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2023-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2023-10-05: Inputs: Added support for extra ImGuiKey values: F13 to F24 function keys, app back/forward keys.
|
||||
// 2023-04-06: Inputs: Avoid calling SDL_StartTextInput()/SDL_StopTextInput() as they don't only pertain to IME. It's unclear exactly what their relation is to IME. (#6306)
|
||||
// 2023-04-04: Inputs: Added support for io.AddMouseSourceEvent() to discriminate ImGuiMouseSource_Mouse/ImGuiMouseSource_TouchScreen. (#2702)
|
||||
@@ -46,7 +50,7 @@
|
||||
// 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range.
|
||||
// 2021-08-17: Calling io.AddFocusEvent() on SDL_WINDOWEVENT_FOCUS_GAINED/SDL_WINDOWEVENT_FOCUS_LOST.
|
||||
// 2021-07-29: Inputs: MousePos is correctly reported when the host platform window is hovered but not focused (using SDL_GetMouseFocus() + SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, requires SDL 2.0.5+)
|
||||
// 2021-06-29: *BREAKING CHANGE* Removed 'SDL_Window* window' parameter to ImGui_ImplSDL2_NewFrame() which was unnecessary.
|
||||
// 2021-06:29: *BREAKING CHANGE* Removed 'SDL_Window* window' parameter to ImGui_ImplSDL2_NewFrame() which was unnecessary.
|
||||
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
|
||||
// 2021-03-22: Rework global mouse pos availability check listing supported platforms explicitly, effectively fixing mouse access on Raspberry Pi. (#2837, #3950)
|
||||
// 2020-05-25: Misc: Report a zero display-size when window is minimized, to be consistent with other backends.
|
||||
@@ -87,6 +91,7 @@
|
||||
#endif
|
||||
|
||||
// SDL
|
||||
// (the multi-viewports feature requires SDL features supported from SDL 2.0.4+. SDL 2.0.5+ is highly recommended)
|
||||
#include <SDL.h>
|
||||
#include <SDL_syswm.h>
|
||||
#if defined(__APPLE__)
|
||||
@@ -98,7 +103,15 @@
|
||||
#else
|
||||
#define SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE 0
|
||||
#endif
|
||||
#define SDL_HAS_WINDOW_ALPHA SDL_VERSION_ATLEAST(2,0,5)
|
||||
#define SDL_HAS_ALWAYS_ON_TOP SDL_VERSION_ATLEAST(2,0,5)
|
||||
#define SDL_HAS_USABLE_DISPLAY_BOUNDS SDL_VERSION_ATLEAST(2,0,5)
|
||||
#define SDL_HAS_PER_MONITOR_DPI SDL_VERSION_ATLEAST(2,0,4)
|
||||
#define SDL_HAS_VULKAN SDL_VERSION_ATLEAST(2,0,6)
|
||||
#define SDL_HAS_DISPLAY_EVENT SDL_VERSION_ATLEAST(2,0,9)
|
||||
#if !SDL_HAS_VULKAN
|
||||
static const Uint32 SDL_WINDOW_VULKAN = 0x10000000;
|
||||
#endif
|
||||
|
||||
// SDL Data
|
||||
struct ImGui_ImplSDL2_Data
|
||||
@@ -113,6 +126,9 @@ struct ImGui_ImplSDL2_Data
|
||||
int PendingMouseLeaveFrame;
|
||||
char* ClipboardTextData;
|
||||
bool MouseCanUseGlobalState;
|
||||
bool MouseCanReportHoveredViewport; // This is hard to use/unreliable on SDL so we'll set ImGuiBackendFlags_HasMouseHoveredViewport dynamically based on state.
|
||||
bool UseVulkan;
|
||||
bool WantUpdateMonitors;
|
||||
|
||||
ImGui_ImplSDL2_Data() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
@@ -126,6 +142,11 @@ static ImGui_ImplSDL2_Data* ImGui_ImplSDL2_GetBackendData()
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplSDL2_Data*)ImGui::GetIO().BackendPlatformUserData : nullptr;
|
||||
}
|
||||
|
||||
// Forward Declarations
|
||||
static void ImGui_ImplSDL2_UpdateMonitors();
|
||||
static void ImGui_ImplSDL2_InitPlatformInterface(SDL_Window* window, void* sdl_gl_context);
|
||||
static void ImGui_ImplSDL2_ShutdownPlatformInterface();
|
||||
|
||||
// Functions
|
||||
static const char* ImGui_ImplSDL2_GetClipboardText(void*)
|
||||
{
|
||||
@@ -142,13 +163,13 @@ static void ImGui_ImplSDL2_SetClipboardText(void*, const char* text)
|
||||
}
|
||||
|
||||
// Note: native IME will only display if user calls SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1") _before_ SDL_CreateWindow().
|
||||
static void ImGui_ImplSDL2_SetPlatformImeData(ImGuiViewport*, ImGuiPlatformImeData* data)
|
||||
static void ImGui_ImplSDL2_SetPlatformImeData(ImGuiViewport* viewport, ImGuiPlatformImeData* data)
|
||||
{
|
||||
if (data->WantVisible)
|
||||
{
|
||||
SDL_Rect r;
|
||||
r.x = (int)data->InputPos.x;
|
||||
r.y = (int)data->InputPos.y;
|
||||
r.x = (int)(data->InputPos.x - viewport->Pos.x);
|
||||
r.y = (int)(data->InputPos.y - viewport->Pos.y + data->InputLineHeight);
|
||||
r.w = 1;
|
||||
r.h = (int)data->InputLineHeight;
|
||||
SDL_SetTextInputRect(&r);
|
||||
@@ -306,6 +327,13 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
|
||||
case SDL_MOUSEMOTION:
|
||||
{
|
||||
ImVec2 mouse_pos((float)event->motion.x, (float)event->motion.y);
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
int window_x, window_y;
|
||||
SDL_GetWindowPosition(SDL_GetWindowFromID(event->motion.windowID), &window_x, &window_y);
|
||||
mouse_pos.x += window_x;
|
||||
mouse_pos.y += window_y;
|
||||
}
|
||||
io.AddMouseSourceEvent(event->motion.which == SDL_TOUCH_MOUSEID ? ImGuiMouseSource_TouchScreen : ImGuiMouseSource_Mouse);
|
||||
io.AddMousePosEvent(mouse_pos.x, mouse_pos.y);
|
||||
return true;
|
||||
@@ -357,6 +385,15 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
|
||||
io.SetKeyEventNativeData(key, event->key.keysym.sym, event->key.keysym.scancode, event->key.keysym.scancode); // To support legacy indexing (<1.87 user code). Legacy backend uses SDLK_*** as indices to IsKeyXXX() functions.
|
||||
return true;
|
||||
}
|
||||
#if SDL_HAS_DISPLAY_EVENT
|
||||
case SDL_DISPLAYEVENT:
|
||||
{
|
||||
// 2.0.26 has SDL_DISPLAYEVENT_CONNECTED/SDL_DISPLAYEVENT_DISCONNECTED/SDL_DISPLAYEVENT_ORIENTATION,
|
||||
// so change of DPI/Scaling are not reflected in this event. (SDL3 has it)
|
||||
bd->WantUpdateMonitors = true;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
case SDL_WINDOWEVENT:
|
||||
{
|
||||
// - When capturing mouse, SDL will send a bunch of conflicting LEAVE/ENTER event on every mouse move, but the final ENTER tends to be right.
|
||||
@@ -374,15 +411,26 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
|
||||
bd->PendingMouseLeaveFrame = ImGui::GetFrameCount() + 1;
|
||||
if (window_event == SDL_WINDOWEVENT_FOCUS_GAINED)
|
||||
io.AddFocusEvent(true);
|
||||
else if (event->window.event == SDL_WINDOWEVENT_FOCUS_LOST)
|
||||
else if (window_event == SDL_WINDOWEVENT_FOCUS_LOST)
|
||||
io.AddFocusEvent(false);
|
||||
if (window_event == SDL_WINDOWEVENT_CLOSE || window_event == SDL_WINDOWEVENT_MOVED || window_event == SDL_WINDOWEVENT_RESIZED)
|
||||
if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle((void*)SDL_GetWindowFromID(event->window.windowID)))
|
||||
{
|
||||
if (window_event == SDL_WINDOWEVENT_CLOSE)
|
||||
viewport->PlatformRequestClose = true;
|
||||
if (window_event == SDL_WINDOWEVENT_MOVED)
|
||||
viewport->PlatformRequestMove = true;
|
||||
if (window_event == SDL_WINDOWEVENT_RESIZED)
|
||||
viewport->PlatformRequestResize = true;
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer)
|
||||
static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer, void* sdl_gl_context)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!");
|
||||
@@ -402,12 +450,23 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer)
|
||||
ImGui_ImplSDL2_Data* bd = IM_NEW(ImGui_ImplSDL2_Data)();
|
||||
io.BackendPlatformUserData = (void*)bd;
|
||||
io.BackendPlatformName = "imgui_impl_sdl2";
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used)
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used)
|
||||
if (mouse_can_use_global_state)
|
||||
io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports; // We can create multi-viewports on the Platform side (optional)
|
||||
|
||||
bd->Window = window;
|
||||
bd->Renderer = renderer;
|
||||
|
||||
// SDL on Linux/OSX doesn't report events for unfocused windows (see https://github.com/ocornut/imgui/issues/4960)
|
||||
// We will use 'MouseCanReportHoveredViewport' to set 'ImGuiBackendFlags_HasMouseHoveredViewport' dynamically each frame.
|
||||
bd->MouseCanUseGlobalState = mouse_can_use_global_state;
|
||||
#ifndef __APPLE__
|
||||
bd->MouseCanReportHoveredViewport = bd->MouseCanUseGlobalState;
|
||||
#else
|
||||
bd->MouseCanReportHoveredViewport = false;
|
||||
#endif
|
||||
bd->WantUpdateMonitors = true;
|
||||
|
||||
io.SetClipboardTextFn = ImGui_ImplSDL2_SetClipboardText;
|
||||
io.GetClipboardTextFn = ImGui_ImplSDL2_GetClipboardText;
|
||||
@@ -428,6 +487,7 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer)
|
||||
// Set platform dependent data in viewport
|
||||
// Our mouse update function expect PlatformHandle to be filled for the main viewport
|
||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||
main_viewport->PlatformHandle = (void*)window;
|
||||
main_viewport->PlatformHandleRaw = nullptr;
|
||||
SDL_SysWMinfo info;
|
||||
SDL_VERSION(&info.version);
|
||||
@@ -461,13 +521,17 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer)
|
||||
SDL_SetHint(SDL_HINT_MOUSE_AUTO_CAPTURE, "0");
|
||||
#endif
|
||||
|
||||
// We need SDL_CaptureMouse(), SDL_GetGlobalMouseState() from SDL 2.0.4+ to support multiple viewports.
|
||||
// We left the call to ImGui_ImplSDL2_InitPlatformInterface() outside of #ifdef to avoid unused-function warnings.
|
||||
if ((io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) && (io.BackendFlags & ImGuiBackendFlags_PlatformHasViewports))
|
||||
ImGui_ImplSDL2_InitPlatformInterface(window, sdl_gl_context);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ImGui_ImplSDL2_InitForOpenGL(SDL_Window* window, void* sdl_gl_context)
|
||||
{
|
||||
IM_UNUSED(sdl_gl_context); // Viewport branch will need this.
|
||||
return ImGui_ImplSDL2_Init(window, nullptr);
|
||||
return ImGui_ImplSDL2_Init(window, nullptr, sdl_gl_context);
|
||||
}
|
||||
|
||||
bool ImGui_ImplSDL2_InitForVulkan(SDL_Window* window)
|
||||
@@ -475,7 +539,11 @@ bool ImGui_ImplSDL2_InitForVulkan(SDL_Window* window)
|
||||
#if !SDL_HAS_VULKAN
|
||||
IM_ASSERT(0 && "Unsupported");
|
||||
#endif
|
||||
return ImGui_ImplSDL2_Init(window, nullptr);
|
||||
if (!ImGui_ImplSDL2_Init(window, nullptr, nullptr))
|
||||
return false;
|
||||
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
|
||||
bd->UseVulkan = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ImGui_ImplSDL2_InitForD3D(SDL_Window* window)
|
||||
@@ -483,22 +551,22 @@ bool ImGui_ImplSDL2_InitForD3D(SDL_Window* window)
|
||||
#if !defined(_WIN32)
|
||||
IM_ASSERT(0 && "Unsupported");
|
||||
#endif
|
||||
return ImGui_ImplSDL2_Init(window, nullptr);
|
||||
return ImGui_ImplSDL2_Init(window, nullptr, nullptr);
|
||||
}
|
||||
|
||||
bool ImGui_ImplSDL2_InitForMetal(SDL_Window* window)
|
||||
{
|
||||
return ImGui_ImplSDL2_Init(window, nullptr);
|
||||
return ImGui_ImplSDL2_Init(window, nullptr, nullptr);
|
||||
}
|
||||
|
||||
bool ImGui_ImplSDL2_InitForSDLRenderer(SDL_Window* window, SDL_Renderer* renderer)
|
||||
{
|
||||
return ImGui_ImplSDL2_Init(window, renderer);
|
||||
return ImGui_ImplSDL2_Init(window, renderer, nullptr);
|
||||
}
|
||||
|
||||
bool ImGui_ImplSDL2_InitForOther(SDL_Window* window)
|
||||
{
|
||||
return ImGui_ImplSDL2_Init(window, nullptr);
|
||||
return ImGui_ImplSDL2_Init(window, nullptr, nullptr);
|
||||
}
|
||||
|
||||
void ImGui_ImplSDL2_Shutdown()
|
||||
@@ -507,6 +575,8 @@ void ImGui_ImplSDL2_Shutdown()
|
||||
IM_ASSERT(bd != nullptr && "No platform backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
ImGui_ImplSDL2_ShutdownPlatformInterface();
|
||||
|
||||
if (bd->ClipboardTextData)
|
||||
SDL_free(bd->ClipboardTextData);
|
||||
for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_COUNT; cursor_n++)
|
||||
@@ -515,10 +585,11 @@ void ImGui_ImplSDL2_Shutdown()
|
||||
|
||||
io.BackendPlatformName = nullptr;
|
||||
io.BackendPlatformUserData = nullptr;
|
||||
io.BackendFlags &= ~(ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_HasSetMousePos | ImGuiBackendFlags_HasGamepad);
|
||||
io.BackendFlags &= ~(ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_HasSetMousePos | ImGuiBackendFlags_HasGamepad | ImGuiBackendFlags_PlatformHasViewports | ImGuiBackendFlags_HasMouseHoveredViewport);
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
// This code is incredibly messy because some of the functions we need for full viewport support are not available in SDL < 2.0.4.
|
||||
static void ImGui_ImplSDL2_UpdateMouseData()
|
||||
{
|
||||
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
|
||||
@@ -529,25 +600,57 @@ static void ImGui_ImplSDL2_UpdateMouseData()
|
||||
// SDL_CaptureMouse() let the OS know e.g. that our imgui drag outside the SDL window boundaries shouldn't e.g. trigger other operations outside
|
||||
SDL_CaptureMouse((bd->MouseButtonsDown != 0) ? SDL_TRUE : SDL_FALSE);
|
||||
SDL_Window* focused_window = SDL_GetKeyboardFocus();
|
||||
const bool is_app_focused = (bd->Window == focused_window);
|
||||
const bool is_app_focused = (focused_window && (bd->Window == focused_window || ImGui::FindViewportByPlatformHandle((void*)focused_window)));
|
||||
#else
|
||||
SDL_Window* focused_window = bd->Window;
|
||||
const bool is_app_focused = (SDL_GetWindowFlags(bd->Window) & SDL_WINDOW_INPUT_FOCUS) != 0; // SDL 2.0.3 and non-windowed systems: single-viewport only
|
||||
#endif
|
||||
|
||||
if (is_app_focused)
|
||||
{
|
||||
// (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
|
||||
if (io.WantSetMousePos)
|
||||
SDL_WarpMouseInWindow(bd->Window, (int)io.MousePos.x, (int)io.MousePos.y);
|
||||
{
|
||||
#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
SDL_WarpMouseGlobal((int)io.MousePos.x, (int)io.MousePos.y);
|
||||
else
|
||||
#endif
|
||||
SDL_WarpMouseInWindow(bd->Window, (int)io.MousePos.x, (int)io.MousePos.y);
|
||||
}
|
||||
|
||||
// (Optional) Fallback to provide mouse position when focused (SDL_MOUSEMOTION already provides this when hovered or captured)
|
||||
if (bd->MouseCanUseGlobalState && bd->MouseButtonsDown == 0)
|
||||
{
|
||||
int window_x, window_y, mouse_x_global, mouse_y_global;
|
||||
SDL_GetGlobalMouseState(&mouse_x_global, &mouse_y_global);
|
||||
SDL_GetWindowPosition(bd->Window, &window_x, &window_y);
|
||||
io.AddMousePosEvent((float)(mouse_x_global - window_x), (float)(mouse_y_global - window_y));
|
||||
// Single-viewport mode: mouse position in client window coordinates (io.MousePos is (0,0) when the mouse is on the upper-left corner of the app window)
|
||||
// Multi-viewport mode: mouse position in OS absolute coordinates (io.MousePos is (0,0) when the mouse is on the upper-left of the primary monitor)
|
||||
int mouse_x, mouse_y, window_x, window_y;
|
||||
SDL_GetGlobalMouseState(&mouse_x, &mouse_y);
|
||||
if (!(io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable))
|
||||
{
|
||||
SDL_GetWindowPosition(focused_window, &window_x, &window_y);
|
||||
mouse_x -= window_x;
|
||||
mouse_y -= window_y;
|
||||
}
|
||||
io.AddMousePosEvent((float)mouse_x, (float)mouse_y);
|
||||
}
|
||||
}
|
||||
|
||||
// (Optional) When using multiple viewports: call io.AddMouseViewportEvent() with the viewport the OS mouse cursor is hovering.
|
||||
// If ImGuiBackendFlags_HasMouseHoveredViewport is not set by the backend, Dear imGui will ignore this field and infer the information using its flawed heuristic.
|
||||
// - [!] SDL backend does NOT correctly ignore viewports with the _NoInputs flag.
|
||||
// Some backend are not able to handle that correctly. If a backend report an hovered viewport that has the _NoInputs flag (e.g. when dragging a window
|
||||
// for docking, the viewport has the _NoInputs flag in order to allow us to find the viewport under), then Dear ImGui is forced to ignore the value reported
|
||||
// by the backend, and use its flawed heuristic to guess the viewport behind.
|
||||
// - [X] SDL backend correctly reports this regardless of another viewport behind focused and dragged from (we need this to find a useful drag and drop target).
|
||||
if (io.BackendFlags & ImGuiBackendFlags_HasMouseHoveredViewport)
|
||||
{
|
||||
ImGuiID mouse_viewport_id = 0;
|
||||
if (SDL_Window* sdl_mouse_window = SDL_GetWindowFromID(bd->MouseWindowID))
|
||||
if (ImGuiViewport* mouse_viewport = ImGui::FindViewportByPlatformHandle((void*)sdl_mouse_window))
|
||||
mouse_viewport_id = mouse_viewport->ID;
|
||||
io.AddMouseViewportEvent(mouse_viewport_id);
|
||||
}
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDL2_UpdateMouseCursor()
|
||||
@@ -622,6 +725,39 @@ static void ImGui_ImplSDL2_UpdateGamepads()
|
||||
#undef MAP_ANALOG
|
||||
}
|
||||
|
||||
// FIXME: Note that doesn't update with DPI/Scaling change only as SDL2 doesn't have an event for it (SDL3 has).
|
||||
static void ImGui_ImplSDL2_UpdateMonitors()
|
||||
{
|
||||
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
platform_io.Monitors.resize(0);
|
||||
bd->WantUpdateMonitors = false;
|
||||
int display_count = SDL_GetNumVideoDisplays();
|
||||
for (int n = 0; n < display_count; n++)
|
||||
{
|
||||
// Warning: the validity of monitor DPI information on Windows depends on the application DPI awareness settings, which generally needs to be set in the manifest or at runtime.
|
||||
ImGuiPlatformMonitor monitor;
|
||||
SDL_Rect r;
|
||||
SDL_GetDisplayBounds(n, &r);
|
||||
monitor.MainPos = monitor.WorkPos = ImVec2((float)r.x, (float)r.y);
|
||||
monitor.MainSize = monitor.WorkSize = ImVec2((float)r.w, (float)r.h);
|
||||
#if SDL_HAS_USABLE_DISPLAY_BOUNDS
|
||||
SDL_GetDisplayUsableBounds(n, &r);
|
||||
monitor.WorkPos = ImVec2((float)r.x, (float)r.y);
|
||||
monitor.WorkSize = ImVec2((float)r.w, (float)r.h);
|
||||
#endif
|
||||
#if SDL_HAS_PER_MONITOR_DPI
|
||||
// FIXME-VIEWPORT: On MacOS SDL reports actual monitor DPI scale, ignoring OS configuration. We may want to set
|
||||
// DpiScale to cocoa_window.backingScaleFactor here.
|
||||
float dpi = 0.0f;
|
||||
if (!SDL_GetDisplayDPI(n, &dpi, nullptr, nullptr))
|
||||
monitor.DpiScale = dpi / 96.0f;
|
||||
#endif
|
||||
monitor.PlatformHandle = (void*)(intptr_t)n;
|
||||
platform_io.Monitors.push_back(monitor);
|
||||
}
|
||||
}
|
||||
|
||||
void ImGui_ImplSDL2_NewFrame()
|
||||
{
|
||||
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
|
||||
@@ -642,6 +778,10 @@ void ImGui_ImplSDL2_NewFrame()
|
||||
if (w > 0 && h > 0)
|
||||
io.DisplayFramebufferScale = ImVec2((float)display_w / w, (float)display_h / h);
|
||||
|
||||
// Update monitors
|
||||
if (bd->WantUpdateMonitors)
|
||||
ImGui_ImplSDL2_UpdateMonitors();
|
||||
|
||||
// Setup time step (we don't use SDL_GetTicks() because it is using millisecond resolution)
|
||||
// (Accept SDL_GetPerformanceCounter() not returning a monotonically increasing value. Happens in VMs and Emscripten, see #6189, #6114, #3644)
|
||||
static Uint64 frequency = SDL_GetPerformanceFrequency();
|
||||
@@ -658,6 +798,13 @@ void ImGui_ImplSDL2_NewFrame()
|
||||
io.AddMousePosEvent(-FLT_MAX, -FLT_MAX);
|
||||
}
|
||||
|
||||
// Our io.AddMouseViewportEvent() calls will only be valid when not capturing.
|
||||
// Technically speaking testing for 'bd->MouseButtonsDown == 0' would be more rygorous, but testing for payload reduces noise and potential side-effects.
|
||||
if (bd->MouseCanReportHoveredViewport && ImGui::GetDragDropPayload() == nullptr)
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport;
|
||||
else
|
||||
io.BackendFlags &= ~ImGuiBackendFlags_HasMouseHoveredViewport;
|
||||
|
||||
ImGui_ImplSDL2_UpdateMouseData();
|
||||
ImGui_ImplSDL2_UpdateMouseCursor();
|
||||
|
||||
@@ -665,6 +812,253 @@ void ImGui_ImplSDL2_NewFrame()
|
||||
ImGui_ImplSDL2_UpdateGamepads();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
|
||||
// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously.
|
||||
// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first..
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
|
||||
// Helper structure we store in the void* RendererUserData field of each ImGuiViewport to easily retrieve our backend data.
|
||||
struct ImGui_ImplSDL2_ViewportData
|
||||
{
|
||||
SDL_Window* Window;
|
||||
Uint32 WindowID;
|
||||
bool WindowOwned;
|
||||
SDL_GLContext GLContext;
|
||||
|
||||
ImGui_ImplSDL2_ViewportData() { Window = nullptr; WindowID = 0; WindowOwned = false; GLContext = nullptr; }
|
||||
~ImGui_ImplSDL2_ViewportData() { IM_ASSERT(Window == nullptr && GLContext == nullptr); }
|
||||
};
|
||||
|
||||
static void ImGui_ImplSDL2_CreateWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
|
||||
ImGui_ImplSDL2_ViewportData* vd = IM_NEW(ImGui_ImplSDL2_ViewportData)();
|
||||
viewport->PlatformUserData = vd;
|
||||
|
||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||
ImGui_ImplSDL2_ViewportData* main_viewport_data = (ImGui_ImplSDL2_ViewportData*)main_viewport->PlatformUserData;
|
||||
|
||||
// Share GL resources with main context
|
||||
bool use_opengl = (main_viewport_data->GLContext != nullptr);
|
||||
SDL_GLContext backup_context = nullptr;
|
||||
if (use_opengl)
|
||||
{
|
||||
backup_context = SDL_GL_GetCurrentContext();
|
||||
SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1);
|
||||
SDL_GL_MakeCurrent(main_viewport_data->Window, main_viewport_data->GLContext);
|
||||
}
|
||||
|
||||
Uint32 sdl_flags = 0;
|
||||
sdl_flags |= use_opengl ? SDL_WINDOW_OPENGL : (bd->UseVulkan ? SDL_WINDOW_VULKAN : 0);
|
||||
sdl_flags |= SDL_GetWindowFlags(bd->Window) & SDL_WINDOW_ALLOW_HIGHDPI;
|
||||
sdl_flags |= SDL_WINDOW_HIDDEN;
|
||||
sdl_flags |= (viewport->Flags & ImGuiViewportFlags_NoDecoration) ? SDL_WINDOW_BORDERLESS : 0;
|
||||
sdl_flags |= (viewport->Flags & ImGuiViewportFlags_NoDecoration) ? 0 : SDL_WINDOW_RESIZABLE;
|
||||
#if !defined(_WIN32)
|
||||
// See SDL hack in ImGui_ImplSDL2_ShowWindow().
|
||||
sdl_flags |= (viewport->Flags & ImGuiViewportFlags_NoTaskBarIcon) ? SDL_WINDOW_SKIP_TASKBAR : 0;
|
||||
#endif
|
||||
#if SDL_HAS_ALWAYS_ON_TOP
|
||||
sdl_flags |= (viewport->Flags & ImGuiViewportFlags_TopMost) ? SDL_WINDOW_ALWAYS_ON_TOP : 0;
|
||||
#endif
|
||||
vd->Window = SDL_CreateWindow("No Title Yet", (int)viewport->Pos.x, (int)viewport->Pos.y, (int)viewport->Size.x, (int)viewport->Size.y, sdl_flags);
|
||||
vd->WindowOwned = true;
|
||||
if (use_opengl)
|
||||
{
|
||||
vd->GLContext = SDL_GL_CreateContext(vd->Window);
|
||||
SDL_GL_SetSwapInterval(0);
|
||||
}
|
||||
if (use_opengl && backup_context)
|
||||
SDL_GL_MakeCurrent(vd->Window, backup_context);
|
||||
|
||||
viewport->PlatformHandle = (void*)vd->Window;
|
||||
viewport->PlatformHandleRaw = nullptr;
|
||||
SDL_SysWMinfo info;
|
||||
SDL_VERSION(&info.version);
|
||||
if (SDL_GetWindowWMInfo(vd->Window, &info))
|
||||
{
|
||||
#if defined(SDL_VIDEO_DRIVER_WINDOWS)
|
||||
viewport->PlatformHandleRaw = info.info.win.window;
|
||||
#elif defined(__APPLE__) && defined(SDL_VIDEO_DRIVER_COCOA)
|
||||
viewport->PlatformHandleRaw = (void*)info.info.cocoa.window;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDL2_DestroyWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
if (ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData)
|
||||
{
|
||||
if (vd->GLContext && vd->WindowOwned)
|
||||
SDL_GL_DeleteContext(vd->GLContext);
|
||||
if (vd->Window && vd->WindowOwned)
|
||||
SDL_DestroyWindow(vd->Window);
|
||||
vd->GLContext = nullptr;
|
||||
vd->Window = nullptr;
|
||||
IM_DELETE(vd);
|
||||
}
|
||||
viewport->PlatformUserData = viewport->PlatformHandle = nullptr;
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDL2_ShowWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
|
||||
#if defined(_WIN32)
|
||||
HWND hwnd = (HWND)viewport->PlatformHandleRaw;
|
||||
|
||||
// SDL hack: Hide icon from task bar
|
||||
// Note: SDL 2.0.6+ has a SDL_WINDOW_SKIP_TASKBAR flag which is supported under Windows but the way it create the window breaks our seamless transition.
|
||||
if (viewport->Flags & ImGuiViewportFlags_NoTaskBarIcon)
|
||||
{
|
||||
LONG ex_style = ::GetWindowLong(hwnd, GWL_EXSTYLE);
|
||||
ex_style &= ~WS_EX_APPWINDOW;
|
||||
ex_style |= WS_EX_TOOLWINDOW;
|
||||
::SetWindowLong(hwnd, GWL_EXSTYLE, ex_style);
|
||||
}
|
||||
|
||||
// SDL hack: SDL always activate/focus windows :/
|
||||
if (viewport->Flags & ImGuiViewportFlags_NoFocusOnAppearing)
|
||||
{
|
||||
::ShowWindow(hwnd, SW_SHOWNA);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
SDL_ShowWindow(vd->Window);
|
||||
}
|
||||
|
||||
static ImVec2 ImGui_ImplSDL2_GetWindowPos(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
|
||||
int x = 0, y = 0;
|
||||
SDL_GetWindowPosition(vd->Window, &x, &y);
|
||||
return ImVec2((float)x, (float)y);
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDL2_SetWindowPos(ImGuiViewport* viewport, ImVec2 pos)
|
||||
{
|
||||
ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
|
||||
SDL_SetWindowPosition(vd->Window, (int)pos.x, (int)pos.y);
|
||||
}
|
||||
|
||||
static ImVec2 ImGui_ImplSDL2_GetWindowSize(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
|
||||
int w = 0, h = 0;
|
||||
SDL_GetWindowSize(vd->Window, &w, &h);
|
||||
return ImVec2((float)w, (float)h);
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDL2_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
|
||||
{
|
||||
ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
|
||||
SDL_SetWindowSize(vd->Window, (int)size.x, (int)size.y);
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDL2_SetWindowTitle(ImGuiViewport* viewport, const char* title)
|
||||
{
|
||||
ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
|
||||
SDL_SetWindowTitle(vd->Window, title);
|
||||
}
|
||||
|
||||
#if SDL_HAS_WINDOW_ALPHA
|
||||
static void ImGui_ImplSDL2_SetWindowAlpha(ImGuiViewport* viewport, float alpha)
|
||||
{
|
||||
ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
|
||||
SDL_SetWindowOpacity(vd->Window, alpha);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void ImGui_ImplSDL2_SetWindowFocus(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
|
||||
SDL_RaiseWindow(vd->Window);
|
||||
}
|
||||
|
||||
static bool ImGui_ImplSDL2_GetWindowFocus(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
|
||||
return (SDL_GetWindowFlags(vd->Window) & SDL_WINDOW_INPUT_FOCUS) != 0;
|
||||
}
|
||||
|
||||
static bool ImGui_ImplSDL2_GetWindowMinimized(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
|
||||
return (SDL_GetWindowFlags(vd->Window) & SDL_WINDOW_MINIMIZED) != 0;
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDL2_RenderWindow(ImGuiViewport* viewport, void*)
|
||||
{
|
||||
ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
|
||||
if (vd->GLContext)
|
||||
SDL_GL_MakeCurrent(vd->Window, vd->GLContext);
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDL2_SwapBuffers(ImGuiViewport* viewport, void*)
|
||||
{
|
||||
ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
|
||||
if (vd->GLContext)
|
||||
{
|
||||
SDL_GL_MakeCurrent(vd->Window, vd->GLContext);
|
||||
SDL_GL_SwapWindow(vd->Window);
|
||||
}
|
||||
}
|
||||
|
||||
// Vulkan support (the Vulkan renderer needs to call a platform-side support function to create the surface)
|
||||
// SDL is graceful enough to _not_ need <vulkan/vulkan.h> so we can safely include this.
|
||||
#if SDL_HAS_VULKAN
|
||||
#include <SDL_vulkan.h>
|
||||
static int ImGui_ImplSDL2_CreateVkSurface(ImGuiViewport* viewport, ImU64 vk_instance, const void* vk_allocator, ImU64* out_vk_surface)
|
||||
{
|
||||
ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
|
||||
(void)vk_allocator;
|
||||
SDL_bool ret = SDL_Vulkan_CreateSurface(vd->Window, (VkInstance)vk_instance, (VkSurfaceKHR*)out_vk_surface);
|
||||
return ret ? 0 : 1; // ret ? VK_SUCCESS : VK_NOT_READY
|
||||
}
|
||||
#endif // SDL_HAS_VULKAN
|
||||
|
||||
static void ImGui_ImplSDL2_InitPlatformInterface(SDL_Window* window, void* sdl_gl_context)
|
||||
{
|
||||
// Register platform interface (will be coupled with a renderer interface)
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
platform_io.Platform_CreateWindow = ImGui_ImplSDL2_CreateWindow;
|
||||
platform_io.Platform_DestroyWindow = ImGui_ImplSDL2_DestroyWindow;
|
||||
platform_io.Platform_ShowWindow = ImGui_ImplSDL2_ShowWindow;
|
||||
platform_io.Platform_SetWindowPos = ImGui_ImplSDL2_SetWindowPos;
|
||||
platform_io.Platform_GetWindowPos = ImGui_ImplSDL2_GetWindowPos;
|
||||
platform_io.Platform_SetWindowSize = ImGui_ImplSDL2_SetWindowSize;
|
||||
platform_io.Platform_GetWindowSize = ImGui_ImplSDL2_GetWindowSize;
|
||||
platform_io.Platform_SetWindowFocus = ImGui_ImplSDL2_SetWindowFocus;
|
||||
platform_io.Platform_GetWindowFocus = ImGui_ImplSDL2_GetWindowFocus;
|
||||
platform_io.Platform_GetWindowMinimized = ImGui_ImplSDL2_GetWindowMinimized;
|
||||
platform_io.Platform_SetWindowTitle = ImGui_ImplSDL2_SetWindowTitle;
|
||||
platform_io.Platform_RenderWindow = ImGui_ImplSDL2_RenderWindow;
|
||||
platform_io.Platform_SwapBuffers = ImGui_ImplSDL2_SwapBuffers;
|
||||
#if SDL_HAS_WINDOW_ALPHA
|
||||
platform_io.Platform_SetWindowAlpha = ImGui_ImplSDL2_SetWindowAlpha;
|
||||
#endif
|
||||
#if SDL_HAS_VULKAN
|
||||
platform_io.Platform_CreateVkSurface = ImGui_ImplSDL2_CreateVkSurface;
|
||||
#endif
|
||||
|
||||
// Register main window handle (which is owned by the main application, not by us)
|
||||
// This is mostly for simplicity and consistency, so that our code (e.g. mouse handling etc.) can use same logic for main and secondary viewports.
|
||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||
ImGui_ImplSDL2_ViewportData* vd = IM_NEW(ImGui_ImplSDL2_ViewportData)();
|
||||
vd->Window = window;
|
||||
vd->WindowID = SDL_GetWindowID(window);
|
||||
vd->WindowOwned = false;
|
||||
vd->GLContext = sdl_gl_context;
|
||||
main_viewport->PlatformUserData = vd;
|
||||
main_viewport->PlatformHandle = vd->Window;
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDL2_ShutdownPlatformInterface()
|
||||
{
|
||||
ImGui::DestroyPlatformWindows();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#if defined(__clang__)
|
||||
|
||||
@@ -8,7 +8,10 @@
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy SDL_SCANCODE_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
||||
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// [X] Platform: Basic IME support. App needs to call 'SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");' before SDL_CreateWindow()!.
|
||||
// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
// Missing features:
|
||||
// [ ] Platform: Multi-viewport + Minimized windows seems to break mouse wheel events (at least under Windows).
|
||||
// [x] Platform: Basic IME support. App needs to call 'SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");' before SDL_CreateWindow()!.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
|
||||
@@ -9,7 +9,9 @@
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy SDL_SCANCODE_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
||||
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// [x] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable' -> the OS animation effect when window gets created/destroyed is problematic. SDL2 backend doesn't have issue.
|
||||
// Missing features:
|
||||
// [ ] Platform: Multi-viewport + Minimized windows seems to break mouse wheel events (at least under Windows).
|
||||
// [x] Platform: Basic IME support. Position somehow broken in SDL3 + app needs to call 'SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");' before SDL_CreateWindow()!.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
@@ -22,6 +24,7 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2023-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2023-11-13: Updated for recent SDL3 API changes.
|
||||
// 2023-10-05: Inputs: Added support for extra ImGuiKey values: F13 to F24 function keys, app back/forward keys.
|
||||
// 2023-05-04: Fixed build on Emscripten/iOS/Android. (#6391)
|
||||
@@ -71,6 +74,9 @@ struct ImGui_ImplSDL3_Data
|
||||
int PendingMouseLeaveFrame;
|
||||
char* ClipboardTextData;
|
||||
bool MouseCanUseGlobalState;
|
||||
bool MouseCanReportHoveredViewport; // This is hard to use/unreliable on SDL so we'll set ImGuiBackendFlags_HasMouseHoveredViewport dynamically based on state.
|
||||
bool UseVulkan;
|
||||
bool WantUpdateMonitors;
|
||||
|
||||
ImGui_ImplSDL3_Data() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
@@ -84,6 +90,11 @@ static ImGui_ImplSDL3_Data* ImGui_ImplSDL3_GetBackendData()
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplSDL3_Data*)ImGui::GetIO().BackendPlatformUserData : nullptr;
|
||||
}
|
||||
|
||||
// Forward Declarations
|
||||
static void ImGui_ImplSDL3_UpdateMonitors();
|
||||
static void ImGui_ImplSDL3_InitPlatformInterface(SDL_Window* window, void* sdl_gl_context);
|
||||
static void ImGui_ImplSDL3_ShutdownPlatformInterface();
|
||||
|
||||
// Functions
|
||||
static const char* ImGui_ImplSDL3_GetClipboardText(void*)
|
||||
{
|
||||
@@ -99,13 +110,13 @@ static void ImGui_ImplSDL3_SetClipboardText(void*, const char* text)
|
||||
SDL_SetClipboardText(text);
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDL3_SetPlatformImeData(ImGuiViewport*, ImGuiPlatformImeData* data)
|
||||
static void ImGui_ImplSDL3_SetPlatformImeData(ImGuiViewport* viewport, ImGuiPlatformImeData* data)
|
||||
{
|
||||
if (data->WantVisible)
|
||||
{
|
||||
SDL_Rect r;
|
||||
r.x = (int)data->InputPos.x;
|
||||
r.y = (int)data->InputPos.y;
|
||||
r.x = (int)(data->InputPos.x - viewport->Pos.x);
|
||||
r.y = (int)(data->InputPos.y - viewport->Pos.y + data->InputLineHeight);
|
||||
r.w = 1;
|
||||
r.h = (int)data->InputLineHeight;
|
||||
SDL_SetTextInputRect(&r);
|
||||
@@ -263,6 +274,13 @@ bool ImGui_ImplSDL3_ProcessEvent(const SDL_Event* event)
|
||||
case SDL_EVENT_MOUSE_MOTION:
|
||||
{
|
||||
ImVec2 mouse_pos((float)event->motion.x, (float)event->motion.y);
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
int window_x, window_y;
|
||||
SDL_GetWindowPosition(SDL_GetWindowFromID(event->motion.windowID), &window_x, &window_y);
|
||||
mouse_pos.x += window_x;
|
||||
mouse_pos.y += window_y;
|
||||
}
|
||||
io.AddMouseSourceEvent(event->motion.which == SDL_TOUCH_MOUSEID ? ImGuiMouseSource_TouchScreen : ImGuiMouseSource_Mouse);
|
||||
io.AddMousePosEvent(mouse_pos.x, mouse_pos.y);
|
||||
return true;
|
||||
@@ -309,6 +327,15 @@ bool ImGui_ImplSDL3_ProcessEvent(const SDL_Event* event)
|
||||
io.SetKeyEventNativeData(key, event->key.keysym.sym, event->key.keysym.scancode, event->key.keysym.scancode); // To support legacy indexing (<1.87 user code). Legacy backend uses SDLK_*** as indices to IsKeyXXX() functions.
|
||||
return true;
|
||||
}
|
||||
case SDL_EVENT_DISPLAY_ORIENTATION:
|
||||
case SDL_EVENT_DISPLAY_ADDED:
|
||||
case SDL_EVENT_DISPLAY_REMOVED:
|
||||
case SDL_EVENT_DISPLAY_MOVED:
|
||||
case SDL_EVENT_DISPLAY_CONTENT_SCALE_CHANGED:
|
||||
{
|
||||
bd->WantUpdateMonitors = true;
|
||||
return true;
|
||||
}
|
||||
case SDL_EVENT_WINDOW_MOUSE_ENTER:
|
||||
{
|
||||
bd->MouseWindowID = event->window.windowID;
|
||||
@@ -330,17 +357,32 @@ bool ImGui_ImplSDL3_ProcessEvent(const SDL_Event* event)
|
||||
case SDL_EVENT_WINDOW_FOCUS_LOST:
|
||||
io.AddFocusEvent(false);
|
||||
return true;
|
||||
case SDL_EVENT_WINDOW_CLOSE_REQUESTED:
|
||||
case SDL_EVENT_WINDOW_MOVED:
|
||||
case SDL_EVENT_WINDOW_RESIZED:
|
||||
if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle((void*)SDL_GetWindowFromID(event->window.windowID)))
|
||||
{
|
||||
if (event->type == SDL_EVENT_WINDOW_CLOSE_REQUESTED)
|
||||
viewport->PlatformRequestClose = true;
|
||||
if (event->type == SDL_EVENT_WINDOW_MOVED)
|
||||
viewport->PlatformRequestMove = true;
|
||||
if (event->type == SDL_EVENT_WINDOW_RESIZED)
|
||||
viewport->PlatformRequestResize = true;
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDL3_SetupPlatformHandles(ImGuiViewport* viewport, SDL_Window* window)
|
||||
{
|
||||
viewport->PlatformHandle = window;
|
||||
viewport->PlatformHandleRaw = nullptr;
|
||||
#if defined(__WIN32__) && !defined(__WINRT__)
|
||||
viewport->PlatformHandleRaw = (HWND)SDL_GetProperty(SDL_GetWindowProperties(window), "SDL.window.win32.hwnd", NULL);
|
||||
viewport->PlatformHandleRaw = (HWND)SDL_GetProperty(SDL_GetWindowProperties(window), "SDL.window.win32.hwnd", nullptr);
|
||||
#elif defined(__APPLE__) && defined(SDL_VIDEO_DRIVER_COCOA)
|
||||
viewport->PlatformHandleRaw = (void*)SDL_GetProperty(SDL_GetWindowProperties(window), "SDL.window.cocoa.window", NULL);
|
||||
viewport->PlatformHandleRaw = (void*)SDL_GetProperty(SDL_GetWindowProperties(window), "SDL.window.cocoa.window", nullptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -367,10 +409,21 @@ static bool ImGui_ImplSDL3_Init(SDL_Window* window, SDL_Renderer* renderer, void
|
||||
io.BackendPlatformName = "imgui_impl_sdl3";
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used)
|
||||
if (mouse_can_use_global_state)
|
||||
io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports; // We can create multi-viewports on the Platform side (optional)
|
||||
|
||||
bd->Window = window;
|
||||
bd->Renderer = renderer;
|
||||
|
||||
// SDL on Linux/OSX doesn't report events for unfocused windows (see https://github.com/ocornut/imgui/issues/4960)
|
||||
// We will use 'MouseCanReportHoveredViewport' to set 'ImGuiBackendFlags_HasMouseHoveredViewport' dynamically each frame.
|
||||
bd->MouseCanUseGlobalState = mouse_can_use_global_state;
|
||||
#ifndef __APPLE__
|
||||
bd->MouseCanReportHoveredViewport = bd->MouseCanUseGlobalState;
|
||||
#else
|
||||
bd->MouseCanReportHoveredViewport = false;
|
||||
#endif
|
||||
bd->WantUpdateMonitors = true;
|
||||
|
||||
io.SetClipboardTextFn = ImGui_ImplSDL3_SetClipboardText;
|
||||
io.GetClipboardTextFn = ImGui_ImplSDL3_GetClipboardText;
|
||||
@@ -398,27 +451,34 @@ static bool ImGui_ImplSDL3_Init(SDL_Window* window, SDL_Renderer* renderer, void
|
||||
// (This is unfortunately a global SDL setting, so enabling it might have a side-effect on your application.
|
||||
// It is unlikely to make a difference, but if your app absolutely needs to ignore the initial on-focus click:
|
||||
// you can ignore SDL_EVENT_MOUSE_BUTTON_DOWN events coming right after a SDL_WINDOWEVENT_FOCUS_GAINED)
|
||||
#ifdef SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH
|
||||
SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1");
|
||||
#endif
|
||||
|
||||
// From 2.0.22: Disable auto-capture, this is preventing drag and drop across multiple windows (see #5710)
|
||||
#ifdef SDL_HINT_MOUSE_AUTO_CAPTURE
|
||||
SDL_SetHint(SDL_HINT_MOUSE_AUTO_CAPTURE, "0");
|
||||
#endif
|
||||
|
||||
// SDL 3.x : see https://github.com/libsdl-org/SDL/issues/6659
|
||||
SDL_SetHint("SDL_BORDERLESS_WINDOWED_STYLE", "0");
|
||||
|
||||
// We need SDL_CaptureMouse(), SDL_GetGlobalMouseState() from SDL 2.0.4+ to support multiple viewports.
|
||||
// We left the call to ImGui_ImplSDL3_InitPlatformInterface() outside of #ifdef to avoid unused-function warnings.
|
||||
if ((io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) && (io.BackendFlags & ImGuiBackendFlags_PlatformHasViewports))
|
||||
ImGui_ImplSDL3_InitPlatformInterface(window, sdl_gl_context);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ImGui_ImplSDL3_InitForOpenGL(SDL_Window* window, void* sdl_gl_context)
|
||||
{
|
||||
IM_UNUSED(sdl_gl_context); // Viewport branch will need this.
|
||||
return ImGui_ImplSDL3_Init(window, nullptr, sdl_gl_context);
|
||||
}
|
||||
|
||||
bool ImGui_ImplSDL3_InitForVulkan(SDL_Window* window)
|
||||
{
|
||||
return ImGui_ImplSDL3_Init(window, nullptr, nullptr);
|
||||
if (!ImGui_ImplSDL3_Init(window, nullptr, nullptr))
|
||||
return false;
|
||||
ImGui_ImplSDL3_Data* bd = ImGui_ImplSDL3_GetBackendData();
|
||||
bd->UseVulkan = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ImGui_ImplSDL3_InitForD3D(SDL_Window* window)
|
||||
@@ -450,6 +510,8 @@ void ImGui_ImplSDL3_Shutdown()
|
||||
IM_ASSERT(bd != nullptr && "No platform backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
ImGui_ImplSDL3_ShutdownPlatformInterface();
|
||||
|
||||
if (bd->ClipboardTextData)
|
||||
SDL_free(bd->ClipboardTextData);
|
||||
for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_COUNT; cursor_n++)
|
||||
@@ -458,10 +520,11 @@ void ImGui_ImplSDL3_Shutdown()
|
||||
|
||||
io.BackendPlatformName = nullptr;
|
||||
io.BackendPlatformUserData = nullptr;
|
||||
io.BackendFlags &= ~(ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_HasSetMousePos | ImGuiBackendFlags_HasGamepad);
|
||||
io.BackendFlags &= ~(ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_HasSetMousePos | ImGuiBackendFlags_HasGamepad | ImGuiBackendFlags_PlatformHasViewports | ImGuiBackendFlags_HasMouseHoveredViewport);
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
// This code is incredibly messy because some of the functions we need for full viewport support are not available in SDL < 2.0.4.
|
||||
static void ImGui_ImplSDL3_UpdateMouseData()
|
||||
{
|
||||
ImGui_ImplSDL3_Data* bd = ImGui_ImplSDL3_GetBackendData();
|
||||
@@ -472,7 +535,7 @@ static void ImGui_ImplSDL3_UpdateMouseData()
|
||||
// SDL_CaptureMouse() let the OS know e.g. that our imgui drag outside the SDL window boundaries shouldn't e.g. trigger other operations outside
|
||||
SDL_CaptureMouse((bd->MouseButtonsDown != 0) ? SDL_TRUE : SDL_FALSE);
|
||||
SDL_Window* focused_window = SDL_GetKeyboardFocus();
|
||||
const bool is_app_focused = (bd->Window == focused_window);
|
||||
const bool is_app_focused = (focused_window && (bd->Window == focused_window || ImGui::FindViewportByPlatformHandle((void*)focused_window)));
|
||||
#else
|
||||
SDL_Window* focused_window = bd->Window;
|
||||
const bool is_app_focused = (SDL_GetWindowFlags(bd->Window) & SDL_WINDOW_INPUT_FOCUS) != 0; // SDL 2.0.3 and non-windowed systems: single-viewport only
|
||||
@@ -481,19 +544,48 @@ static void ImGui_ImplSDL3_UpdateMouseData()
|
||||
{
|
||||
// (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
|
||||
if (io.WantSetMousePos)
|
||||
SDL_WarpMouseInWindow(bd->Window, io.MousePos.x, io.MousePos.y);
|
||||
{
|
||||
#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
SDL_WarpMouseGlobal(io.MousePos.x, io.MousePos.y);
|
||||
else
|
||||
#endif
|
||||
SDL_WarpMouseInWindow(bd->Window, io.MousePos.x, io.MousePos.y);
|
||||
}
|
||||
|
||||
// (Optional) Fallback to provide mouse position when focused (SDL_EVENT_MOUSE_MOTION already provides this when hovered or captured)
|
||||
if (bd->MouseCanUseGlobalState && bd->MouseButtonsDown == 0)
|
||||
{
|
||||
// Single-viewport mode: mouse position in client window coordinates (io.MousePos is (0,0) when the mouse is on the upper-left corner of the app window)
|
||||
float mouse_x_global, mouse_y_global;
|
||||
// Multi-viewport mode: mouse position in OS absolute coordinates (io.MousePos is (0,0) when the mouse is on the upper-left of the primary monitor)
|
||||
float mouse_x, mouse_y;
|
||||
int window_x, window_y;
|
||||
SDL_GetGlobalMouseState(&mouse_x_global, &mouse_y_global);
|
||||
SDL_GetWindowPosition(focused_window, &window_x, &window_y);
|
||||
io.AddMousePosEvent(mouse_x_global - window_x, mouse_y_global - window_y);
|
||||
SDL_GetGlobalMouseState(&mouse_x, &mouse_y);
|
||||
if (!(io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable))
|
||||
{
|
||||
SDL_GetWindowPosition(focused_window, &window_x, &window_y);
|
||||
mouse_x -= window_x;
|
||||
mouse_y -= window_y;
|
||||
}
|
||||
io.AddMousePosEvent((float)mouse_x, (float)mouse_y);
|
||||
}
|
||||
}
|
||||
|
||||
// (Optional) When using multiple viewports: call io.AddMouseViewportEvent() with the viewport the OS mouse cursor is hovering.
|
||||
// If ImGuiBackendFlags_HasMouseHoveredViewport is not set by the backend, Dear imGui will ignore this field and infer the information using its flawed heuristic.
|
||||
// - [!] SDL backend does NOT correctly ignore viewports with the _NoInputs flag.
|
||||
// Some backend are not able to handle that correctly. If a backend report an hovered viewport that has the _NoInputs flag (e.g. when dragging a window
|
||||
// for docking, the viewport has the _NoInputs flag in order to allow us to find the viewport under), then Dear ImGui is forced to ignore the value reported
|
||||
// by the backend, and use its flawed heuristic to guess the viewport behind.
|
||||
// - [X] SDL backend correctly reports this regardless of another viewport behind focused and dragged from (we need this to find a useful drag and drop target).
|
||||
if (io.BackendFlags & ImGuiBackendFlags_HasMouseHoveredViewport)
|
||||
{
|
||||
ImGuiID mouse_viewport_id = 0;
|
||||
if (SDL_Window* sdl_mouse_window = SDL_GetWindowFromID(bd->MouseWindowID))
|
||||
if (ImGuiViewport* mouse_viewport = ImGui::FindViewportByPlatformHandle((void*)sdl_mouse_window))
|
||||
mouse_viewport_id = mouse_viewport->ID;
|
||||
io.AddMouseViewportEvent(mouse_viewport_id);
|
||||
}
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDL3_UpdateMouseCursor()
|
||||
@@ -568,6 +660,35 @@ static void ImGui_ImplSDL3_UpdateGamepads()
|
||||
#undef MAP_ANALOG
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDL3_UpdateMonitors()
|
||||
{
|
||||
ImGui_ImplSDL3_Data* bd = ImGui_ImplSDL3_GetBackendData();
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
platform_io.Monitors.resize(0);
|
||||
bd->WantUpdateMonitors = false;
|
||||
|
||||
int display_count;
|
||||
SDL_DisplayID* displays = SDL_GetDisplays(&display_count);
|
||||
for (int n = 0; n < display_count; n++)
|
||||
{
|
||||
// Warning: the validity of monitor DPI information on Windows depends on the application DPI awareness settings, which generally needs to be set in the manifest or at runtime.
|
||||
SDL_DisplayID display_id = displays[n];
|
||||
ImGuiPlatformMonitor monitor;
|
||||
SDL_Rect r;
|
||||
SDL_GetDisplayBounds(display_id, &r);
|
||||
monitor.MainPos = monitor.WorkPos = ImVec2((float)r.x, (float)r.y);
|
||||
monitor.MainSize = monitor.WorkSize = ImVec2((float)r.w, (float)r.h);
|
||||
SDL_GetDisplayUsableBounds(display_id, &r);
|
||||
monitor.WorkPos = ImVec2((float)r.x, (float)r.y);
|
||||
monitor.WorkSize = ImVec2((float)r.w, (float)r.h);
|
||||
// FIXME-VIEWPORT: On MacOS SDL reports actual monitor DPI scale, ignoring OS configuration. We may want to set
|
||||
// DpiScale to cocoa_window.backingScaleFactor here.
|
||||
monitor.DpiScale = SDL_GetDisplayContentScale(display_id);
|
||||
monitor.PlatformHandle = (void*)(intptr_t)n;
|
||||
platform_io.Monitors.push_back(monitor);
|
||||
}
|
||||
}
|
||||
|
||||
void ImGui_ImplSDL3_NewFrame()
|
||||
{
|
||||
ImGui_ImplSDL3_Data* bd = ImGui_ImplSDL3_GetBackendData();
|
||||
@@ -585,6 +706,10 @@ void ImGui_ImplSDL3_NewFrame()
|
||||
if (w > 0 && h > 0)
|
||||
io.DisplayFramebufferScale = ImVec2((float)display_w / w, (float)display_h / h);
|
||||
|
||||
// Update monitors
|
||||
if (bd->WantUpdateMonitors)
|
||||
ImGui_ImplSDL3_UpdateMonitors();
|
||||
|
||||
// Setup time step (we don't use SDL_GetTicks() because it is using millisecond resolution)
|
||||
// (Accept SDL_GetPerformanceCounter() not returning a monotonically increasing value. Happens in VMs and Emscripten, see #6189, #6114, #3644)
|
||||
static Uint64 frequency = SDL_GetPerformanceFrequency();
|
||||
@@ -601,6 +726,13 @@ void ImGui_ImplSDL3_NewFrame()
|
||||
io.AddMousePosEvent(-FLT_MAX, -FLT_MAX);
|
||||
}
|
||||
|
||||
// Our io.AddMouseViewportEvent() calls will only be valid when not capturing.
|
||||
// Technically speaking testing for 'bd->MouseButtonsDown == 0' would be more rygorous, but testing for payload reduces noise and potential side-effects.
|
||||
if (bd->MouseCanReportHoveredViewport && ImGui::GetDragDropPayload() == nullptr)
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport;
|
||||
else
|
||||
io.BackendFlags &= ~ImGuiBackendFlags_HasMouseHoveredViewport;
|
||||
|
||||
ImGui_ImplSDL3_UpdateMouseData();
|
||||
ImGui_ImplSDL3_UpdateMouseCursor();
|
||||
|
||||
@@ -608,6 +740,232 @@ void ImGui_ImplSDL3_NewFrame()
|
||||
ImGui_ImplSDL3_UpdateGamepads();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
|
||||
// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously.
|
||||
// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first..
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
|
||||
// Helper structure we store in the void* RendererUserData field of each ImGuiViewport to easily retrieve our backend data.
|
||||
struct ImGui_ImplSDL3_ViewportData
|
||||
{
|
||||
SDL_Window* Window;
|
||||
Uint32 WindowID;
|
||||
bool WindowOwned;
|
||||
SDL_GLContext GLContext;
|
||||
|
||||
ImGui_ImplSDL3_ViewportData() { Window = nullptr; WindowID = 0; WindowOwned = false; GLContext = nullptr; }
|
||||
~ImGui_ImplSDL3_ViewportData() { IM_ASSERT(Window == nullptr && GLContext == nullptr); }
|
||||
};
|
||||
|
||||
static void ImGui_ImplSDL3_CreateWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplSDL3_Data* bd = ImGui_ImplSDL3_GetBackendData();
|
||||
ImGui_ImplSDL3_ViewportData* vd = IM_NEW(ImGui_ImplSDL3_ViewportData)();
|
||||
viewport->PlatformUserData = vd;
|
||||
|
||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||
ImGui_ImplSDL3_ViewportData* main_viewport_data = (ImGui_ImplSDL3_ViewportData*)main_viewport->PlatformUserData;
|
||||
|
||||
// Share GL resources with main context
|
||||
bool use_opengl = (main_viewport_data->GLContext != nullptr);
|
||||
SDL_GLContext backup_context = nullptr;
|
||||
if (use_opengl)
|
||||
{
|
||||
backup_context = SDL_GL_GetCurrentContext();
|
||||
SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1);
|
||||
SDL_GL_MakeCurrent(main_viewport_data->Window, main_viewport_data->GLContext);
|
||||
}
|
||||
|
||||
Uint32 sdl_flags = 0;
|
||||
sdl_flags |= use_opengl ? SDL_WINDOW_OPENGL : (bd->UseVulkan ? SDL_WINDOW_VULKAN : 0);
|
||||
sdl_flags |= SDL_GetWindowFlags(bd->Window);
|
||||
sdl_flags |= (viewport->Flags & ImGuiViewportFlags_NoDecoration) ? SDL_WINDOW_BORDERLESS : 0;
|
||||
sdl_flags |= (viewport->Flags & ImGuiViewportFlags_NoDecoration) ? 0 : SDL_WINDOW_RESIZABLE;
|
||||
#if !defined(_WIN32)
|
||||
// See SDL hack in ImGui_ImplSDL3_ShowWindow().
|
||||
sdl_flags |= (viewport->Flags & ImGuiViewportFlags_NoTaskBarIcon) ? SDL_WINDOW_UTILITY : 0;
|
||||
#endif
|
||||
sdl_flags |= (viewport->Flags & ImGuiViewportFlags_TopMost) ? SDL_WINDOW_ALWAYS_ON_TOP : 0;
|
||||
vd->Window = SDL_CreateWindow("No Title Yet", (int)viewport->Size.x, (int)viewport->Size.y, sdl_flags);
|
||||
SDL_SetWindowPosition(vd->Window, (int)viewport->Pos.x, (int)viewport->Pos.y);
|
||||
vd->WindowOwned = true;
|
||||
if (use_opengl)
|
||||
{
|
||||
vd->GLContext = SDL_GL_CreateContext(vd->Window);
|
||||
SDL_GL_SetSwapInterval(0);
|
||||
}
|
||||
if (use_opengl && backup_context)
|
||||
SDL_GL_MakeCurrent(vd->Window, backup_context);
|
||||
|
||||
ImGui_ImplSDL3_SetupPlatformHandles(viewport, vd->Window);
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDL3_DestroyWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
if (ImGui_ImplSDL3_ViewportData* vd = (ImGui_ImplSDL3_ViewportData*)viewport->PlatformUserData)
|
||||
{
|
||||
if (vd->GLContext && vd->WindowOwned)
|
||||
SDL_GL_DeleteContext(vd->GLContext);
|
||||
if (vd->Window && vd->WindowOwned)
|
||||
SDL_DestroyWindow(vd->Window);
|
||||
vd->GLContext = nullptr;
|
||||
vd->Window = nullptr;
|
||||
IM_DELETE(vd);
|
||||
}
|
||||
viewport->PlatformUserData = viewport->PlatformHandle = nullptr;
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDL3_ShowWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplSDL3_ViewportData* vd = (ImGui_ImplSDL3_ViewportData*)viewport->PlatformUserData;
|
||||
#if defined(_WIN32)
|
||||
HWND hwnd = (HWND)viewport->PlatformHandleRaw;
|
||||
|
||||
// SDL hack: Hide icon from task bar
|
||||
// Note: SDL 3.0.0+ has a SDL_WINDOW_UTILITY flag which is supported under Windows but the way it create the window breaks our seamless transition.
|
||||
if (viewport->Flags & ImGuiViewportFlags_NoTaskBarIcon)
|
||||
{
|
||||
LONG ex_style = ::GetWindowLong(hwnd, GWL_EXSTYLE);
|
||||
ex_style &= ~WS_EX_APPWINDOW;
|
||||
ex_style |= WS_EX_TOOLWINDOW;
|
||||
::SetWindowLong(hwnd, GWL_EXSTYLE, ex_style);
|
||||
}
|
||||
|
||||
// SDL hack: SDL always activate/focus windows :/
|
||||
if (viewport->Flags & ImGuiViewportFlags_NoFocusOnAppearing)
|
||||
{
|
||||
::ShowWindow(hwnd, SW_SHOWNA);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
SDL_ShowWindow(vd->Window);
|
||||
}
|
||||
|
||||
static ImVec2 ImGui_ImplSDL3_GetWindowPos(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplSDL3_ViewportData* vd = (ImGui_ImplSDL3_ViewportData*)viewport->PlatformUserData;
|
||||
int x = 0, y = 0;
|
||||
SDL_GetWindowPosition(vd->Window, &x, &y);
|
||||
return ImVec2((float)x, (float)y);
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDL3_SetWindowPos(ImGuiViewport* viewport, ImVec2 pos)
|
||||
{
|
||||
ImGui_ImplSDL3_ViewportData* vd = (ImGui_ImplSDL3_ViewportData*)viewport->PlatformUserData;
|
||||
SDL_SetWindowPosition(vd->Window, (int)pos.x, (int)pos.y);
|
||||
}
|
||||
|
||||
static ImVec2 ImGui_ImplSDL3_GetWindowSize(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplSDL3_ViewportData* vd = (ImGui_ImplSDL3_ViewportData*)viewport->PlatformUserData;
|
||||
int w = 0, h = 0;
|
||||
SDL_GetWindowSize(vd->Window, &w, &h);
|
||||
return ImVec2((float)w, (float)h);
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDL3_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
|
||||
{
|
||||
ImGui_ImplSDL3_ViewportData* vd = (ImGui_ImplSDL3_ViewportData*)viewport->PlatformUserData;
|
||||
SDL_SetWindowSize(vd->Window, (int)size.x, (int)size.y);
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDL3_SetWindowTitle(ImGuiViewport* viewport, const char* title)
|
||||
{
|
||||
ImGui_ImplSDL3_ViewportData* vd = (ImGui_ImplSDL3_ViewportData*)viewport->PlatformUserData;
|
||||
SDL_SetWindowTitle(vd->Window, title);
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDL3_SetWindowAlpha(ImGuiViewport* viewport, float alpha)
|
||||
{
|
||||
ImGui_ImplSDL3_ViewportData* vd = (ImGui_ImplSDL3_ViewportData*)viewport->PlatformUserData;
|
||||
SDL_SetWindowOpacity(vd->Window, alpha);
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDL3_SetWindowFocus(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplSDL3_ViewportData* vd = (ImGui_ImplSDL3_ViewportData*)viewport->PlatformUserData;
|
||||
SDL_RaiseWindow(vd->Window);
|
||||
}
|
||||
|
||||
static bool ImGui_ImplSDL3_GetWindowFocus(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplSDL3_ViewportData* vd = (ImGui_ImplSDL3_ViewportData*)viewport->PlatformUserData;
|
||||
return (SDL_GetWindowFlags(vd->Window) & SDL_WINDOW_INPUT_FOCUS) != 0;
|
||||
}
|
||||
|
||||
static bool ImGui_ImplSDL3_GetWindowMinimized(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplSDL3_ViewportData* vd = (ImGui_ImplSDL3_ViewportData*)viewport->PlatformUserData;
|
||||
return (SDL_GetWindowFlags(vd->Window) & SDL_WINDOW_MINIMIZED) != 0;
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDL3_RenderWindow(ImGuiViewport* viewport, void*)
|
||||
{
|
||||
ImGui_ImplSDL3_ViewportData* vd = (ImGui_ImplSDL3_ViewportData*)viewport->PlatformUserData;
|
||||
if (vd->GLContext)
|
||||
SDL_GL_MakeCurrent(vd->Window, vd->GLContext);
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDL3_SwapBuffers(ImGuiViewport* viewport, void*)
|
||||
{
|
||||
ImGui_ImplSDL3_ViewportData* vd = (ImGui_ImplSDL3_ViewportData*)viewport->PlatformUserData;
|
||||
if (vd->GLContext)
|
||||
{
|
||||
SDL_GL_MakeCurrent(vd->Window, vd->GLContext);
|
||||
SDL_GL_SwapWindow(vd->Window);
|
||||
}
|
||||
}
|
||||
|
||||
// Vulkan support (the Vulkan renderer needs to call a platform-side support function to create the surface)
|
||||
// SDL is graceful enough to _not_ need <vulkan/vulkan.h> so we can safely include this.
|
||||
#include <SDL3/SDL_vulkan.h>
|
||||
static int ImGui_ImplSDL3_CreateVkSurface(ImGuiViewport* viewport, ImU64 vk_instance, const void* vk_allocator, ImU64* out_vk_surface)
|
||||
{
|
||||
ImGui_ImplSDL3_ViewportData* vd = (ImGui_ImplSDL3_ViewportData*)viewport->PlatformUserData;
|
||||
(void)vk_allocator;
|
||||
SDL_bool ret = SDL_Vulkan_CreateSurface(vd->Window, (VkInstance)vk_instance, (VkAllocationCallbacks*)vk_allocator, (VkSurfaceKHR*)out_vk_surface);
|
||||
return ret ? 0 : 1; // ret ? VK_SUCCESS : VK_NOT_READY
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDL3_InitPlatformInterface(SDL_Window* window, void* sdl_gl_context)
|
||||
{
|
||||
// Register platform interface (will be coupled with a renderer interface)
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
platform_io.Platform_CreateWindow = ImGui_ImplSDL3_CreateWindow;
|
||||
platform_io.Platform_DestroyWindow = ImGui_ImplSDL3_DestroyWindow;
|
||||
platform_io.Platform_ShowWindow = ImGui_ImplSDL3_ShowWindow;
|
||||
platform_io.Platform_SetWindowPos = ImGui_ImplSDL3_SetWindowPos;
|
||||
platform_io.Platform_GetWindowPos = ImGui_ImplSDL3_GetWindowPos;
|
||||
platform_io.Platform_SetWindowSize = ImGui_ImplSDL3_SetWindowSize;
|
||||
platform_io.Platform_GetWindowSize = ImGui_ImplSDL3_GetWindowSize;
|
||||
platform_io.Platform_SetWindowFocus = ImGui_ImplSDL3_SetWindowFocus;
|
||||
platform_io.Platform_GetWindowFocus = ImGui_ImplSDL3_GetWindowFocus;
|
||||
platform_io.Platform_GetWindowMinimized = ImGui_ImplSDL3_GetWindowMinimized;
|
||||
platform_io.Platform_SetWindowTitle = ImGui_ImplSDL3_SetWindowTitle;
|
||||
platform_io.Platform_RenderWindow = ImGui_ImplSDL3_RenderWindow;
|
||||
platform_io.Platform_SwapBuffers = ImGui_ImplSDL3_SwapBuffers;
|
||||
platform_io.Platform_SetWindowAlpha = ImGui_ImplSDL3_SetWindowAlpha;
|
||||
platform_io.Platform_CreateVkSurface = ImGui_ImplSDL3_CreateVkSurface;
|
||||
|
||||
// Register main window handle (which is owned by the main application, not by us)
|
||||
// This is mostly for simplicity and consistency, so that our code (e.g. mouse handling etc.) can use same logic for main and secondary viewports.
|
||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||
ImGui_ImplSDL3_ViewportData* vd = IM_NEW(ImGui_ImplSDL3_ViewportData)();
|
||||
vd->Window = window;
|
||||
vd->WindowID = SDL_GetWindowID(window);
|
||||
vd->WindowOwned = false;
|
||||
vd->GLContext = sdl_gl_context;
|
||||
main_viewport->PlatformUserData = vd;
|
||||
main_viewport->PlatformHandle = vd->Window;
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDL3_ShutdownPlatformInterface()
|
||||
{
|
||||
ImGui::DestroyPlatformWindows();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#if defined(__clang__)
|
||||
|
||||
@@ -9,7 +9,9 @@
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy SDL_SCANCODE_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
||||
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// [x] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable' -> the OS animation effect when window gets created/destroyed is problematic. SDL2 backend doesn't have issue.
|
||||
// Missing features:
|
||||
// [ ] Platform: Multi-viewport + Minimized windows seems to break mouse wheel events (at least under Windows).
|
||||
// [x] Platform: Basic IME support. Position somehow broken in SDL3 + app needs to call 'SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");' before SDL_CreateWindow()!.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'SDL_Texture*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
// Missing features:
|
||||
// [ ] Renderer: Multi-viewport support (multiple windows).
|
||||
|
||||
// You can copy and use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'SDL_Texture*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
// Missing features:
|
||||
// [ ] Renderer: Multi-viewport support (multiple windows).
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'SDL_Texture*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
// Missing features:
|
||||
// [ ] Renderer: Multi-viewport support (multiple windows).
|
||||
|
||||
// You can copy and use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'SDL_Texture*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
// Missing features:
|
||||
// [ ] Renderer: Multi-viewport support (multiple windows).
|
||||
|
||||
// You can copy and use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
// This needs to be used along with a Platform Backend (e.g. GLFW, SDL, Win32, custom..)
|
||||
|
||||
// Implemented features:
|
||||
// [!] Renderer: User texture binding. Use 'VkDescriptorSet' as ImTextureID. Read the FAQ about ImTextureID! See https://github.com/ocornut/imgui/pull/914 for discussions.
|
||||
// [x] Renderer: User texture binding. Use 'VkDescriptorSet' as ImTextureID. Read the FAQ about ImTextureID! See https://github.com/ocornut/imgui/pull/914 for discussions.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
// [x] Renderer: Multi-viewport / platform windows. With issues (flickering when creating a new viewport).
|
||||
|
||||
// Important: on 32-bit systems, user texture binding is only supported if your imconfig file has '#define ImTextureID ImU64'.
|
||||
// This is because we need ImTextureID to carry a 64-bit value and by default ImTextureID is defined as void*.
|
||||
@@ -33,6 +34,10 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2023-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2024-01-03: Vulkan: Added MinAllocationSize field in ImGui_ImplVulkan_InitInfo to workaround zealous "best practice" validation layer. (#7189, #4238)
|
||||
// 2024-01-03: Vulkan: Stoped creating command pools with VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT as we don't reset them.
|
||||
// 2023-11-29: Vulkan: Fixed mismatching allocator passed to vkCreateCommandPool() vs vkDestroyCommandPool(). (#7075)
|
||||
// 2023-11-10: *BREAKING CHANGE*: Removed parameter from ImGui_ImplVulkan_CreateFontsTexture(): backend now creates its own command-buffer to upload fonts.
|
||||
// *BREAKING CHANGE*: Removed ImGui_ImplVulkan_DestroyFontUploadObjects() which is now unecessary as we create and destroy those objects in the backend.
|
||||
// ImGui_ImplVulkan_CreateFontsTexture() is automatically called by NewFrame() the first time.
|
||||
@@ -78,73 +83,25 @@
|
||||
#ifndef IMGUI_DISABLE
|
||||
#include "imgui_impl_vulkan.h"
|
||||
#include <stdio.h>
|
||||
#ifndef IM_MAX
|
||||
#define IM_MAX(A, B) (((A) >= (B)) ? (A) : (B))
|
||||
#endif
|
||||
|
||||
// Visual Studio warnings
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (disable: 4127) // condition expression is constant
|
||||
#endif
|
||||
|
||||
// Reusable buffers used for rendering 1 current in-flight frame, for ImGui_ImplVulkan_RenderDrawData()
|
||||
// [Please zero-clear before use!]
|
||||
struct ImGui_ImplVulkanH_FrameRenderBuffers
|
||||
{
|
||||
VkDeviceMemory VertexBufferMemory;
|
||||
VkDeviceMemory IndexBufferMemory;
|
||||
VkDeviceSize VertexBufferSize;
|
||||
VkDeviceSize IndexBufferSize;
|
||||
VkBuffer VertexBuffer;
|
||||
VkBuffer IndexBuffer;
|
||||
};
|
||||
|
||||
// Each viewport will hold 1 ImGui_ImplVulkanH_WindowRenderBuffers
|
||||
// [Please zero-clear before use!]
|
||||
struct ImGui_ImplVulkanH_WindowRenderBuffers
|
||||
{
|
||||
uint32_t Index;
|
||||
uint32_t Count;
|
||||
ImGui_ImplVulkanH_FrameRenderBuffers* FrameRenderBuffers;
|
||||
};
|
||||
|
||||
// Vulkan data
|
||||
struct ImGui_ImplVulkan_Data
|
||||
{
|
||||
ImGui_ImplVulkan_InitInfo VulkanInitInfo;
|
||||
VkRenderPass RenderPass;
|
||||
VkDeviceSize BufferMemoryAlignment;
|
||||
VkPipelineCreateFlags PipelineCreateFlags;
|
||||
VkDescriptorSetLayout DescriptorSetLayout;
|
||||
VkPipelineLayout PipelineLayout;
|
||||
VkPipeline Pipeline;
|
||||
uint32_t Subpass;
|
||||
VkShaderModule ShaderModuleVert;
|
||||
VkShaderModule ShaderModuleFrag;
|
||||
|
||||
// Font data
|
||||
VkSampler FontSampler;
|
||||
VkDeviceMemory FontMemory;
|
||||
VkImage FontImage;
|
||||
VkImageView FontView;
|
||||
VkDescriptorSet FontDescriptorSet;
|
||||
VkCommandPool FontCommandPool;
|
||||
VkCommandBuffer FontCommandBuffer;
|
||||
|
||||
// Render buffers for main window
|
||||
ImGui_ImplVulkanH_WindowRenderBuffers MainWindowRenderBuffers;
|
||||
|
||||
ImGui_ImplVulkan_Data()
|
||||
{
|
||||
memset((void*)this, 0, sizeof(*this));
|
||||
BufferMemoryAlignment = 256;
|
||||
}
|
||||
};
|
||||
|
||||
// Forward Declarations
|
||||
struct ImGui_ImplVulkanH_FrameRenderBuffers;
|
||||
struct ImGui_ImplVulkanH_WindowRenderBuffers;
|
||||
bool ImGui_ImplVulkan_CreateDeviceObjects();
|
||||
void ImGui_ImplVulkan_DestroyDeviceObjects();
|
||||
void ImGui_ImplVulkanH_DestroyFrame(VkDevice device, ImGui_ImplVulkanH_Frame* fd, const VkAllocationCallbacks* allocator);
|
||||
void ImGui_ImplVulkanH_DestroyFrameSemaphores(VkDevice device, ImGui_ImplVulkanH_FrameSemaphores* fsd, const VkAllocationCallbacks* allocator);
|
||||
void ImGui_ImplVulkanH_DestroyFrameRenderBuffers(VkDevice device, ImGui_ImplVulkanH_FrameRenderBuffers* buffers, const VkAllocationCallbacks* allocator);
|
||||
void ImGui_ImplVulkanH_DestroyWindowRenderBuffers(VkDevice device, ImGui_ImplVulkanH_WindowRenderBuffers* buffers, const VkAllocationCallbacks* allocator);
|
||||
void ImGui_ImplVulkanH_DestroyAllViewportsRenderBuffers(VkDevice device, const VkAllocationCallbacks* allocator);
|
||||
void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, const VkAllocationCallbacks* allocator, int w, int h, uint32_t min_image_count);
|
||||
void ImGui_ImplVulkanH_CreateWindowCommandBuffers(VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, uint32_t queue_family, const VkAllocationCallbacks* allocator);
|
||||
|
||||
@@ -160,15 +117,18 @@ static bool g_FunctionsLoaded = true;
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkAllocateCommandBuffers) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkAllocateDescriptorSets) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkAllocateMemory) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkAcquireNextImageKHR) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkBeginCommandBuffer) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkBindBufferMemory) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkBindImageMemory) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdBeginRenderPass) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdBindDescriptorSets) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdBindIndexBuffer) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdBindPipeline) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdBindVertexBuffers) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdCopyBufferToImage) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdDrawIndexed) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdEndRenderPass) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdPipelineBarrier) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdPushConstants) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdSetScissor) \
|
||||
@@ -214,13 +174,17 @@ static bool g_FunctionsLoaded = true;
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkGetPhysicalDeviceSurfaceCapabilitiesKHR) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkGetPhysicalDeviceSurfaceFormatsKHR) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkGetPhysicalDeviceSurfacePresentModesKHR) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkGetPhysicalDeviceSurfaceSupportKHR) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkGetSwapchainImagesKHR) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkMapMemory) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkQueuePresentKHR) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkQueueSubmit) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkQueueWaitIdle) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkResetCommandPool) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkResetFences) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkUnmapMemory) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkUpdateDescriptorSets)
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkUpdateDescriptorSets) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkWaitForFences)
|
||||
|
||||
// Define function pointers
|
||||
#define IMGUI_VULKAN_FUNC_DEF(func) static PFN_##func func;
|
||||
@@ -234,11 +198,81 @@ static PFN_vkCmdBeginRenderingKHR ImGuiImplVulkanFuncs_vkCmdBeginRenderingKHR;
|
||||
static PFN_vkCmdEndRenderingKHR ImGuiImplVulkanFuncs_vkCmdEndRenderingKHR;
|
||||
#endif
|
||||
|
||||
// Reusable buffers used for rendering 1 current in-flight frame, for ImGui_ImplVulkan_RenderDrawData()
|
||||
// [Please zero-clear before use!]
|
||||
struct ImGui_ImplVulkanH_FrameRenderBuffers
|
||||
{
|
||||
VkDeviceMemory VertexBufferMemory;
|
||||
VkDeviceMemory IndexBufferMemory;
|
||||
VkDeviceSize VertexBufferSize;
|
||||
VkDeviceSize IndexBufferSize;
|
||||
VkBuffer VertexBuffer;
|
||||
VkBuffer IndexBuffer;
|
||||
};
|
||||
|
||||
// Each viewport will hold 1 ImGui_ImplVulkanH_WindowRenderBuffers
|
||||
// [Please zero-clear before use!]
|
||||
struct ImGui_ImplVulkanH_WindowRenderBuffers
|
||||
{
|
||||
uint32_t Index;
|
||||
uint32_t Count;
|
||||
ImGui_ImplVulkanH_FrameRenderBuffers* FrameRenderBuffers;
|
||||
};
|
||||
|
||||
// For multi-viewport support:
|
||||
// Helper structure we store in the void* RendererUserData field of each ImGuiViewport to easily retrieve our backend data.
|
||||
struct ImGui_ImplVulkan_ViewportData
|
||||
{
|
||||
bool WindowOwned;
|
||||
ImGui_ImplVulkanH_Window Window; // Used by secondary viewports only
|
||||
ImGui_ImplVulkanH_WindowRenderBuffers RenderBuffers; // Used by all viewports
|
||||
|
||||
ImGui_ImplVulkan_ViewportData() { WindowOwned = false; memset(&RenderBuffers, 0, sizeof(RenderBuffers)); }
|
||||
~ImGui_ImplVulkan_ViewportData() { }
|
||||
};
|
||||
|
||||
// Vulkan data
|
||||
struct ImGui_ImplVulkan_Data
|
||||
{
|
||||
ImGui_ImplVulkan_InitInfo VulkanInitInfo;
|
||||
VkRenderPass RenderPass;
|
||||
VkDeviceSize BufferMemoryAlignment;
|
||||
VkPipelineCreateFlags PipelineCreateFlags;
|
||||
VkDescriptorSetLayout DescriptorSetLayout;
|
||||
VkPipelineLayout PipelineLayout;
|
||||
VkPipeline Pipeline;
|
||||
uint32_t Subpass;
|
||||
VkShaderModule ShaderModuleVert;
|
||||
VkShaderModule ShaderModuleFrag;
|
||||
|
||||
// Font data
|
||||
VkSampler FontSampler;
|
||||
VkDeviceMemory FontMemory;
|
||||
VkImage FontImage;
|
||||
VkImageView FontView;
|
||||
VkDescriptorSet FontDescriptorSet;
|
||||
VkCommandPool FontCommandPool;
|
||||
VkCommandBuffer FontCommandBuffer;
|
||||
|
||||
// Render buffers for main window
|
||||
ImGui_ImplVulkanH_WindowRenderBuffers MainWindowRenderBuffers;
|
||||
|
||||
ImGui_ImplVulkan_Data()
|
||||
{
|
||||
memset((void*)this, 0, sizeof(*this));
|
||||
BufferMemoryAlignment = 256;
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// SHADERS
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// glsl_shader.vert, compiled with:
|
||||
// Forward Declarations
|
||||
static void ImGui_ImplVulkan_InitPlatformInterface();
|
||||
static void ImGui_ImplVulkan_ShutdownPlatformInterface();
|
||||
|
||||
// backends/vulkan/glsl_shader.vert, compiled with:
|
||||
// # glslangValidator -V -x -o glsl_shader.vert.u32 glsl_shader.vert
|
||||
/*
|
||||
#version 450 core
|
||||
@@ -302,7 +336,7 @@ static uint32_t __glsl_shader_vert_spv[] =
|
||||
0x0000002d,0x0000002c,0x000100fd,0x00010038
|
||||
};
|
||||
|
||||
// glsl_shader.frag, compiled with:
|
||||
// backends/vulkan/glsl_shader.frag, compiled with:
|
||||
// # glslangValidator -V -x -o glsl_shader.frag.u32 glsl_shader.frag
|
||||
/*
|
||||
#version 450 core
|
||||
@@ -399,16 +433,17 @@ static void CreateOrResizeBuffer(VkBuffer& buffer, VkDeviceMemory& buffer_memory
|
||||
VkMemoryRequirements req;
|
||||
vkGetBufferMemoryRequirements(v->Device, buffer, &req);
|
||||
bd->BufferMemoryAlignment = (bd->BufferMemoryAlignment > req.alignment) ? bd->BufferMemoryAlignment : req.alignment;
|
||||
VkDeviceSize size = IM_MAX(v->MinAllocationSize, req.size);
|
||||
VkMemoryAllocateInfo alloc_info = {};
|
||||
alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||
alloc_info.allocationSize = req.size;
|
||||
alloc_info.allocationSize = size;
|
||||
alloc_info.memoryTypeIndex = ImGui_ImplVulkan_MemoryType(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, req.memoryTypeBits);
|
||||
err = vkAllocateMemory(v->Device, &alloc_info, v->Allocator, &buffer_memory);
|
||||
check_vk_result(err);
|
||||
|
||||
err = vkBindBufferMemory(v->Device, buffer, buffer_memory, 0);
|
||||
check_vk_result(err);
|
||||
p_buffer_size = req.size;
|
||||
p_buffer_size = size;
|
||||
}
|
||||
|
||||
static void ImGui_ImplVulkan_SetupRenderState(ImDrawData* draw_data, VkPipeline pipeline, VkCommandBuffer command_buffer, ImGui_ImplVulkanH_FrameRenderBuffers* rb, int fb_width, int fb_height)
|
||||
@@ -469,8 +504,10 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
|
||||
if (pipeline == VK_NULL_HANDLE)
|
||||
pipeline = bd->Pipeline;
|
||||
|
||||
// Allocate array to store enough vertex/index buffers
|
||||
ImGui_ImplVulkanH_WindowRenderBuffers* wrb = &bd->MainWindowRenderBuffers;
|
||||
// Allocate array to store enough vertex/index buffers. Each unique viewport gets its own storage.
|
||||
ImGui_ImplVulkan_ViewportData* viewport_renderer_data = (ImGui_ImplVulkan_ViewportData*)draw_data->OwnerViewport->RendererUserData;
|
||||
IM_ASSERT(viewport_renderer_data != nullptr);
|
||||
ImGui_ImplVulkanH_WindowRenderBuffers* wrb = &viewport_renderer_data->RenderBuffers;
|
||||
if (wrb->FrameRenderBuffers == nullptr)
|
||||
{
|
||||
wrb->Index = 0;
|
||||
@@ -495,9 +532,9 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
|
||||
// Upload vertex/index data into a single contiguous GPU buffer
|
||||
ImDrawVert* vtx_dst = nullptr;
|
||||
ImDrawIdx* idx_dst = nullptr;
|
||||
VkResult err = vkMapMemory(v->Device, rb->VertexBufferMemory, 0, rb->VertexBufferSize, 0, (void**)(&vtx_dst));
|
||||
VkResult err = vkMapMemory(v->Device, rb->VertexBufferMemory, 0, rb->VertexBufferSize, 0, (void**)&vtx_dst);
|
||||
check_vk_result(err);
|
||||
err = vkMapMemory(v->Device, rb->IndexBufferMemory, 0, rb->IndexBufferSize, 0, (void**)(&idx_dst));
|
||||
err = vkMapMemory(v->Device, rb->IndexBufferMemory, 0, rb->IndexBufferSize, 0, (void**)&idx_dst);
|
||||
check_vk_result(err);
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
@@ -616,9 +653,9 @@ bool ImGui_ImplVulkan_CreateFontsTexture()
|
||||
{
|
||||
VkCommandPoolCreateInfo info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
||||
info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
|
||||
info.flags = 0;
|
||||
info.queueFamilyIndex = v->QueueFamily;
|
||||
vkCreateCommandPool(v->Device, &info, nullptr, &bd->FontCommandPool);
|
||||
vkCreateCommandPool(v->Device, &info, v->Allocator, &bd->FontCommandPool);
|
||||
}
|
||||
if (bd->FontCommandBuffer == VK_NULL_HANDLE)
|
||||
{
|
||||
@@ -668,7 +705,7 @@ bool ImGui_ImplVulkan_CreateFontsTexture()
|
||||
vkGetImageMemoryRequirements(v->Device, bd->FontImage, &req);
|
||||
VkMemoryAllocateInfo alloc_info = {};
|
||||
alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||
alloc_info.allocationSize = req.size;
|
||||
alloc_info.allocationSize = IM_MAX(v->MinAllocationSize, req.size);
|
||||
alloc_info.memoryTypeIndex = ImGui_ImplVulkan_MemoryType(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, req.memoryTypeBits);
|
||||
err = vkAllocateMemory(v->Device, &alloc_info, v->Allocator, &bd->FontMemory);
|
||||
check_vk_result(err);
|
||||
@@ -709,7 +746,7 @@ bool ImGui_ImplVulkan_CreateFontsTexture()
|
||||
bd->BufferMemoryAlignment = (bd->BufferMemoryAlignment > req.alignment) ? bd->BufferMemoryAlignment : req.alignment;
|
||||
VkMemoryAllocateInfo alloc_info = {};
|
||||
alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||
alloc_info.allocationSize = req.size;
|
||||
alloc_info.allocationSize = IM_MAX(v->MinAllocationSize, req.size);
|
||||
alloc_info.memoryTypeIndex = ImGui_ImplVulkan_MemoryType(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, req.memoryTypeBits);
|
||||
err = vkAllocateMemory(v->Device, &alloc_info, v->Allocator, &upload_buffer_memory);
|
||||
check_vk_result(err);
|
||||
@@ -783,7 +820,7 @@ bool ImGui_ImplVulkan_CreateFontsTexture()
|
||||
err = vkQueueSubmit(v->Queue, 1, &end_info, VK_NULL_HANDLE);
|
||||
check_vk_result(err);
|
||||
|
||||
err = vkDeviceWaitIdle(v->Device);
|
||||
err = vkQueueWaitIdle(v->Queue);
|
||||
check_vk_result(err);
|
||||
|
||||
vkDestroyBuffer(v->Device, upload_buffer, v->Allocator);
|
||||
@@ -1017,9 +1054,10 @@ void ImGui_ImplVulkan_DestroyDeviceObjects()
|
||||
{
|
||||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
||||
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
|
||||
ImGui_ImplVulkanH_DestroyWindowRenderBuffers(v->Device, &bd->MainWindowRenderBuffers, v->Allocator);
|
||||
ImGui_ImplVulkanH_DestroyAllViewportsRenderBuffers(v->Device, v->Allocator);
|
||||
ImGui_ImplVulkan_DestroyFontsTexture();
|
||||
|
||||
if (bd->FontCommandBuffer) { vkFreeCommandBuffers(v->Device, bd->FontCommandPool, 1, &bd->FontCommandBuffer); bd->FontCommandBuffer = VK_NULL_HANDLE; }
|
||||
if (bd->FontCommandPool) { vkDestroyCommandPool(v->Device, bd->FontCommandPool, v->Allocator); bd->FontCommandPool = VK_NULL_HANDLE; }
|
||||
if (bd->ShaderModuleVert) { vkDestroyShaderModule(v->Device, bd->ShaderModuleVert, v->Allocator); bd->ShaderModuleVert = VK_NULL_HANDLE; }
|
||||
if (bd->ShaderModuleFrag) { vkDestroyShaderModule(v->Device, bd->ShaderModuleFrag, v->Allocator); bd->ShaderModuleFrag = VK_NULL_HANDLE; }
|
||||
@@ -1083,6 +1121,7 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info, VkRenderPass rend
|
||||
io.BackendRendererUserData = (void*)bd;
|
||||
io.BackendRendererName = "imgui_impl_vulkan";
|
||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional)
|
||||
|
||||
IM_ASSERT(info->Instance != VK_NULL_HANDLE);
|
||||
IM_ASSERT(info->PhysicalDevice != VK_NULL_HANDLE);
|
||||
@@ -1100,6 +1139,13 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info, VkRenderPass rend
|
||||
|
||||
ImGui_ImplVulkan_CreateDeviceObjects();
|
||||
|
||||
// Our render function expect RendererUserData to be storing the window render buffer we need (for the main viewport we won't use ->Window)
|
||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||
main_viewport->RendererUserData = IM_NEW(ImGui_ImplVulkan_ViewportData)();
|
||||
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
ImGui_ImplVulkan_InitPlatformInterface();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1109,10 +1155,21 @@ void ImGui_ImplVulkan_Shutdown()
|
||||
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
// First destroy objects in all viewports
|
||||
ImGui_ImplVulkan_DestroyDeviceObjects();
|
||||
|
||||
// Manually delete main viewport render data in-case we haven't initialized for viewports
|
||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||
if (ImGui_ImplVulkan_ViewportData* vd = (ImGui_ImplVulkan_ViewportData*)main_viewport->RendererUserData)
|
||||
IM_DELETE(vd);
|
||||
main_viewport->RendererUserData = nullptr;
|
||||
|
||||
// Clean up windows
|
||||
ImGui_ImplVulkan_ShutdownPlatformInterface();
|
||||
|
||||
io.BackendRendererName = nullptr;
|
||||
io.BackendRendererUserData = nullptr;
|
||||
io.BackendFlags &= ~ImGuiBackendFlags_RendererHasVtxOffset;
|
||||
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasViewports);
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
@@ -1132,10 +1189,12 @@ void ImGui_ImplVulkan_SetMinImageCount(uint32_t min_image_count)
|
||||
if (bd->VulkanInitInfo.MinImageCount == min_image_count)
|
||||
return;
|
||||
|
||||
IM_ASSERT(0); // FIXME-VIEWPORT: Unsupported. Need to recreate all swap chains!
|
||||
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
|
||||
VkResult err = vkDeviceWaitIdle(v->Device);
|
||||
check_vk_result(err);
|
||||
ImGui_ImplVulkanH_DestroyWindowRenderBuffers(v->Device, &bd->MainWindowRenderBuffers, v->Allocator);
|
||||
ImGui_ImplVulkanH_DestroyAllViewportsRenderBuffers(v->Device, v->Allocator);
|
||||
|
||||
bd->VulkanInitInfo.MinImageCount = min_image_count;
|
||||
}
|
||||
|
||||
@@ -1281,7 +1340,7 @@ void ImGui_ImplVulkanH_CreateWindowCommandBuffers(VkPhysicalDevice physical_devi
|
||||
{
|
||||
VkCommandPoolCreateInfo info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
||||
info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
|
||||
info.flags = 0;
|
||||
info.queueFamilyIndex = queue_family;
|
||||
err = vkCreateCommandPool(device, &info, allocator, &fd->CommandPool);
|
||||
check_vk_result(err);
|
||||
@@ -1501,6 +1560,7 @@ void ImGui_ImplVulkanH_CreateOrResizeWindow(VkInstance instance, VkPhysicalDevic
|
||||
IM_ASSERT(g_FunctionsLoaded && "Need to call ImGui_ImplVulkan_LoadFunctions() if IMGUI_IMPL_VULKAN_NO_PROTOTYPES or VK_NO_PROTOTYPES are set!");
|
||||
(void)instance;
|
||||
ImGui_ImplVulkanH_CreateWindowSwapChain(physical_device, device, wd, allocator, width, height, min_image_count);
|
||||
//ImGui_ImplVulkan_CreatePipeline(device, allocator, VK_NULL_HANDLE, wd->RenderPass, VK_SAMPLE_COUNT_1_BIT, &wd->Pipeline, g_VulkanInitInfo.Subpass);
|
||||
ImGui_ImplVulkanH_CreateWindowCommandBuffers(physical_device, device, wd, queue_family, allocator);
|
||||
}
|
||||
|
||||
@@ -1566,6 +1626,268 @@ void ImGui_ImplVulkanH_DestroyWindowRenderBuffers(VkDevice device, ImGui_ImplVul
|
||||
buffers->Count = 0;
|
||||
}
|
||||
|
||||
void ImGui_ImplVulkanH_DestroyAllViewportsRenderBuffers(VkDevice device, const VkAllocationCallbacks* allocator)
|
||||
{
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
for (int n = 0; n < platform_io.Viewports.Size; n++)
|
||||
if (ImGui_ImplVulkan_ViewportData* vd = (ImGui_ImplVulkan_ViewportData*)platform_io.Viewports[n]->RendererUserData)
|
||||
ImGui_ImplVulkanH_DestroyWindowRenderBuffers(device, &vd->RenderBuffers, allocator);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
|
||||
// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously.
|
||||
// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first..
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
|
||||
static void ImGui_ImplVulkan_CreateWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
||||
ImGui_ImplVulkan_ViewportData* vd = IM_NEW(ImGui_ImplVulkan_ViewportData)();
|
||||
viewport->RendererUserData = vd;
|
||||
ImGui_ImplVulkanH_Window* wd = &vd->Window;
|
||||
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
|
||||
|
||||
// Create surface
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
VkResult err = (VkResult)platform_io.Platform_CreateVkSurface(viewport, (ImU64)v->Instance, (const void*)v->Allocator, (ImU64*)&wd->Surface);
|
||||
check_vk_result(err);
|
||||
|
||||
// Check for WSI support
|
||||
VkBool32 res;
|
||||
vkGetPhysicalDeviceSurfaceSupportKHR(v->PhysicalDevice, v->QueueFamily, wd->Surface, &res);
|
||||
if (res != VK_TRUE)
|
||||
{
|
||||
IM_ASSERT(0); // Error: no WSI support on physical device
|
||||
return;
|
||||
}
|
||||
|
||||
// Select Surface Format
|
||||
const VkFormat requestSurfaceImageFormat[] = {
|
||||
#if defined(IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING)
|
||||
v->UseDynamicRendering && v->ColorAttachmentFormat ? v->ColorAttachmentFormat : VK_FORMAT_B8G8R8A8_UNORM,
|
||||
#endif
|
||||
VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8_UNORM, VK_FORMAT_R8G8B8_UNORM };
|
||||
const VkColorSpaceKHR requestSurfaceColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
|
||||
wd->SurfaceFormat = ImGui_ImplVulkanH_SelectSurfaceFormat(v->PhysicalDevice, wd->Surface, requestSurfaceImageFormat, (size_t)IM_ARRAYSIZE(requestSurfaceImageFormat), requestSurfaceColorSpace);
|
||||
|
||||
// Select Present Mode
|
||||
// FIXME-VULKAN: Even thought mailbox seems to get us maximum framerate with a single window, it halves framerate with a second window etc. (w/ Nvidia and SDK 1.82.1)
|
||||
VkPresentModeKHR present_modes[] = { VK_PRESENT_MODE_MAILBOX_KHR, VK_PRESENT_MODE_IMMEDIATE_KHR, VK_PRESENT_MODE_FIFO_KHR };
|
||||
wd->PresentMode = ImGui_ImplVulkanH_SelectPresentMode(v->PhysicalDevice, wd->Surface, &present_modes[0], IM_ARRAYSIZE(present_modes));
|
||||
//printf("[vulkan] Secondary window selected PresentMode = %d\n", wd->PresentMode);
|
||||
|
||||
// Create SwapChain, RenderPass, Framebuffer, etc.
|
||||
wd->ClearEnable = (viewport->Flags & ImGuiViewportFlags_NoRendererClear) ? false : true;
|
||||
wd->UseDynamicRendering = v->UseDynamicRendering;
|
||||
ImGui_ImplVulkanH_CreateOrResizeWindow(v->Instance, v->PhysicalDevice, v->Device, wd, v->QueueFamily, v->Allocator, (int)viewport->Size.x, (int)viewport->Size.y, v->MinImageCount);
|
||||
vd->WindowOwned = true;
|
||||
}
|
||||
|
||||
static void ImGui_ImplVulkan_DestroyWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
// The main viewport (owned by the application) will always have RendererUserData == 0 since we didn't create the data for it.
|
||||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
||||
if (ImGui_ImplVulkan_ViewportData* vd = (ImGui_ImplVulkan_ViewportData*)viewport->RendererUserData)
|
||||
{
|
||||
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
|
||||
if (vd->WindowOwned)
|
||||
ImGui_ImplVulkanH_DestroyWindow(v->Instance, v->Device, &vd->Window, v->Allocator);
|
||||
ImGui_ImplVulkanH_DestroyWindowRenderBuffers(v->Device, &vd->RenderBuffers, v->Allocator);
|
||||
IM_DELETE(vd);
|
||||
}
|
||||
viewport->RendererUserData = nullptr;
|
||||
}
|
||||
|
||||
static void ImGui_ImplVulkan_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
|
||||
{
|
||||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
||||
ImGui_ImplVulkan_ViewportData* vd = (ImGui_ImplVulkan_ViewportData*)viewport->RendererUserData;
|
||||
if (vd == nullptr) // This is nullptr for the main viewport (which is left to the user/app to handle)
|
||||
return;
|
||||
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
|
||||
vd->Window.ClearEnable = (viewport->Flags & ImGuiViewportFlags_NoRendererClear) ? false : true;
|
||||
ImGui_ImplVulkanH_CreateOrResizeWindow(v->Instance, v->PhysicalDevice, v->Device, &vd->Window, v->QueueFamily, v->Allocator, (int)size.x, (int)size.y, v->MinImageCount);
|
||||
}
|
||||
|
||||
static void ImGui_ImplVulkan_RenderWindow(ImGuiViewport* viewport, void*)
|
||||
{
|
||||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
||||
ImGui_ImplVulkan_ViewportData* vd = (ImGui_ImplVulkan_ViewportData*)viewport->RendererUserData;
|
||||
ImGui_ImplVulkanH_Window* wd = &vd->Window;
|
||||
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
|
||||
VkResult err;
|
||||
|
||||
ImGui_ImplVulkanH_Frame* fd = &wd->Frames[wd->FrameIndex];
|
||||
ImGui_ImplVulkanH_FrameSemaphores* fsd = &wd->FrameSemaphores[wd->SemaphoreIndex];
|
||||
{
|
||||
{
|
||||
err = vkAcquireNextImageKHR(v->Device, wd->Swapchain, UINT64_MAX, fsd->ImageAcquiredSemaphore, VK_NULL_HANDLE, &wd->FrameIndex);
|
||||
check_vk_result(err);
|
||||
fd = &wd->Frames[wd->FrameIndex];
|
||||
}
|
||||
for (;;)
|
||||
{
|
||||
err = vkWaitForFences(v->Device, 1, &fd->Fence, VK_TRUE, 100);
|
||||
if (err == VK_SUCCESS) break;
|
||||
if (err == VK_TIMEOUT) continue;
|
||||
check_vk_result(err);
|
||||
}
|
||||
{
|
||||
err = vkResetCommandPool(v->Device, fd->CommandPool, 0);
|
||||
check_vk_result(err);
|
||||
VkCommandBufferBeginInfo info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||
info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
||||
err = vkBeginCommandBuffer(fd->CommandBuffer, &info);
|
||||
check_vk_result(err);
|
||||
}
|
||||
{
|
||||
ImVec4 clear_color = ImVec4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
memcpy(&wd->ClearValue.color.float32[0], &clear_color, 4 * sizeof(float));
|
||||
}
|
||||
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
|
||||
if (v->UseDynamicRendering)
|
||||
{
|
||||
// Transition swapchain image to a layout suitable for drawing.
|
||||
VkImageMemoryBarrier barrier = {};
|
||||
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
||||
barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
barrier.image = fd->Backbuffer;
|
||||
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
barrier.subresourceRange.levelCount = 1;
|
||||
barrier.subresourceRange.layerCount = 1;
|
||||
vkCmdPipelineBarrier(fd->CommandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0, nullptr, 0, nullptr, 1, &barrier);
|
||||
|
||||
VkRenderingAttachmentInfo attachmentInfo = {};
|
||||
attachmentInfo.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR;
|
||||
attachmentInfo.imageView = fd->BackbufferView;
|
||||
attachmentInfo.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
attachmentInfo.resolveMode = VK_RESOLVE_MODE_NONE;
|
||||
attachmentInfo.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
attachmentInfo.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
attachmentInfo.clearValue = wd->ClearValue;
|
||||
|
||||
VkRenderingInfo renderingInfo = {};
|
||||
renderingInfo.sType = VK_STRUCTURE_TYPE_RENDERING_INFO_KHR;
|
||||
renderingInfo.renderArea.extent.width = wd->Width;
|
||||
renderingInfo.renderArea.extent.height = wd->Height;
|
||||
renderingInfo.layerCount = 1;
|
||||
renderingInfo.viewMask = 0;
|
||||
renderingInfo.colorAttachmentCount = 1;
|
||||
renderingInfo.pColorAttachments = &attachmentInfo;
|
||||
|
||||
ImGuiImplVulkanFuncs_vkCmdBeginRenderingKHR(fd->CommandBuffer, &renderingInfo);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
VkRenderPassBeginInfo info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
||||
info.renderPass = wd->RenderPass;
|
||||
info.framebuffer = fd->Framebuffer;
|
||||
info.renderArea.extent.width = wd->Width;
|
||||
info.renderArea.extent.height = wd->Height;
|
||||
info.clearValueCount = (viewport->Flags & ImGuiViewportFlags_NoRendererClear) ? 0 : 1;
|
||||
info.pClearValues = (viewport->Flags & ImGuiViewportFlags_NoRendererClear) ? nullptr : &wd->ClearValue;
|
||||
vkCmdBeginRenderPass(fd->CommandBuffer, &info, VK_SUBPASS_CONTENTS_INLINE);
|
||||
}
|
||||
}
|
||||
|
||||
ImGui_ImplVulkan_RenderDrawData(viewport->DrawData, fd->CommandBuffer, wd->Pipeline);
|
||||
|
||||
{
|
||||
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
|
||||
if (v->UseDynamicRendering)
|
||||
{
|
||||
ImGuiImplVulkanFuncs_vkCmdEndRenderingKHR(fd->CommandBuffer);
|
||||
|
||||
// Transition image to a layout suitable for presentation
|
||||
VkImageMemoryBarrier barrier = {};
|
||||
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
||||
barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
barrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||
barrier.image = fd->Backbuffer;
|
||||
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
barrier.subresourceRange.levelCount = 1;
|
||||
barrier.subresourceRange.layerCount = 1;
|
||||
vkCmdPipelineBarrier(fd->CommandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, nullptr, 0, nullptr, 1, &barrier);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
vkCmdEndRenderPass(fd->CommandBuffer);
|
||||
}
|
||||
{
|
||||
VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
VkSubmitInfo info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||
info.waitSemaphoreCount = 1;
|
||||
info.pWaitSemaphores = &fsd->ImageAcquiredSemaphore;
|
||||
info.pWaitDstStageMask = &wait_stage;
|
||||
info.commandBufferCount = 1;
|
||||
info.pCommandBuffers = &fd->CommandBuffer;
|
||||
info.signalSemaphoreCount = 1;
|
||||
info.pSignalSemaphores = &fsd->RenderCompleteSemaphore;
|
||||
|
||||
err = vkEndCommandBuffer(fd->CommandBuffer);
|
||||
check_vk_result(err);
|
||||
err = vkResetFences(v->Device, 1, &fd->Fence);
|
||||
check_vk_result(err);
|
||||
err = vkQueueSubmit(v->Queue, 1, &info, fd->Fence);
|
||||
check_vk_result(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ImGui_ImplVulkan_SwapBuffers(ImGuiViewport* viewport, void*)
|
||||
{
|
||||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
||||
ImGui_ImplVulkan_ViewportData* vd = (ImGui_ImplVulkan_ViewportData*)viewport->RendererUserData;
|
||||
ImGui_ImplVulkanH_Window* wd = &vd->Window;
|
||||
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
|
||||
|
||||
VkResult err;
|
||||
uint32_t present_index = wd->FrameIndex;
|
||||
|
||||
ImGui_ImplVulkanH_FrameSemaphores* fsd = &wd->FrameSemaphores[wd->SemaphoreIndex];
|
||||
VkPresentInfoKHR info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
||||
info.waitSemaphoreCount = 1;
|
||||
info.pWaitSemaphores = &fsd->RenderCompleteSemaphore;
|
||||
info.swapchainCount = 1;
|
||||
info.pSwapchains = &wd->Swapchain;
|
||||
info.pImageIndices = &present_index;
|
||||
err = vkQueuePresentKHR(v->Queue, &info);
|
||||
if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR)
|
||||
ImGui_ImplVulkanH_CreateOrResizeWindow(v->Instance, v->PhysicalDevice, v->Device, &vd->Window, v->QueueFamily, v->Allocator, (int)viewport->Size.x, (int)viewport->Size.y, v->MinImageCount);
|
||||
else
|
||||
check_vk_result(err);
|
||||
|
||||
wd->FrameIndex = (wd->FrameIndex + 1) % wd->ImageCount; // This is for the next vkWaitForFences()
|
||||
wd->SemaphoreIndex = (wd->SemaphoreIndex + 1) % wd->ImageCount; // Now we can use the next set of semaphores
|
||||
}
|
||||
|
||||
void ImGui_ImplVulkan_InitPlatformInterface()
|
||||
{
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
IM_ASSERT(platform_io.Platform_CreateVkSurface != nullptr && "Platform needs to setup the CreateVkSurface handler.");
|
||||
platform_io.Renderer_CreateWindow = ImGui_ImplVulkan_CreateWindow;
|
||||
platform_io.Renderer_DestroyWindow = ImGui_ImplVulkan_DestroyWindow;
|
||||
platform_io.Renderer_SetWindowSize = ImGui_ImplVulkan_SetWindowSize;
|
||||
platform_io.Renderer_RenderWindow = ImGui_ImplVulkan_RenderWindow;
|
||||
platform_io.Renderer_SwapBuffers = ImGui_ImplVulkan_SwapBuffers;
|
||||
}
|
||||
|
||||
void ImGui_ImplVulkan_ShutdownPlatformInterface()
|
||||
{
|
||||
ImGui::DestroyPlatformWindows();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
// This needs to be used along with a Platform Backend (e.g. GLFW, SDL, Win32, custom..)
|
||||
|
||||
// Implemented features:
|
||||
// [!] Renderer: User texture binding. Use 'VkDescriptorSet' as ImTextureID. Read the FAQ about ImTextureID! See https://github.com/ocornut/imgui/pull/914 for discussions.
|
||||
// [x] Renderer: User texture binding. Use 'VkDescriptorSet' as ImTextureID. Read the FAQ about ImTextureID! See https://github.com/ocornut/imgui/pull/914 for discussions.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
// [x] Renderer: Multi-viewport / platform windows. With issues (flickering when creating a new viewport).
|
||||
|
||||
// Important: on 32-bit systems, user texture binding is only supported if your imconfig file has '#define ImTextureID ImU64'.
|
||||
// See imgui_impl_vulkan.cpp file for details.
|
||||
@@ -71,6 +72,7 @@ struct ImGui_ImplVulkan_InitInfo
|
||||
// Allocation, Debugging
|
||||
const VkAllocationCallbacks* Allocator;
|
||||
void (*CheckVkResultFn)(VkResult err);
|
||||
VkDeviceSize MinAllocationSize; // Minimum allocation size. Set to 1024*1024 to satisfy zealous best practices validation layer and waste a little memory.
|
||||
};
|
||||
|
||||
// Called by user code
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'WGPUTextureView' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
// Missing features:
|
||||
// [ ] Renderer: Multi-viewport support (multiple windows). Not meaningful on the web.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
@@ -329,7 +331,9 @@ static void ImGui_ImplWGPU_SetupRenderState(ImDrawData* draw_data, WGPURenderPas
|
||||
void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder pass_encoder)
|
||||
{
|
||||
// Avoid rendering when minimized
|
||||
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
|
||||
int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
|
||||
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
|
||||
if (fb_width <= 0 || fb_height <= 0 || draw_data->CmdListsCount == 0)
|
||||
return;
|
||||
|
||||
// FIXME: Assuming that this only gets called once per frame!
|
||||
@@ -448,6 +452,12 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
|
||||
// Project scissor/clipping rectangles into framebuffer space
|
||||
ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y);
|
||||
ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y);
|
||||
|
||||
// Clamp to viewport as wgpuRenderPassEncoderSetScissorRect() won't accept values that are off bounds
|
||||
if (clip_min.x < 0.0f) { clip_min.x = 0.0f; }
|
||||
if (clip_min.y < 0.0f) { clip_min.y = 0.0f; }
|
||||
if (clip_max.x > fb_width) { clip_max.x = (float)fb_width; }
|
||||
if (clip_max.y > fb_height) { clip_max.y = (float)fb_height; }
|
||||
if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
|
||||
continue;
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'WGPUTextureView' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
// Missing features:
|
||||
// [ ] Renderer: Multi-viewport support (multiple windows). Not meaningful on the web.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy VK_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
||||
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
@@ -39,6 +40,7 @@ typedef DWORD (WINAPI *PFN_XInputGetState)(DWORD, XINPUT_STATE*);
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2023-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2023-10-05: Inputs: Added support for extra ImGuiKey values: F13 to F24 function keys, app back/forward keys.
|
||||
// 2023-09-25: Inputs: Synthesize key-down event on key-up for VK_SNAPSHOT / ImGuiKey_PrintScreen as Windows doesn't emit it (same behavior as GLFW/SDL).
|
||||
// 2023-09-07: Inputs: Added support for keyboard codepage conversion for when application is compiled in MBCS mode and using a non-Unicode window.
|
||||
@@ -91,6 +93,11 @@ typedef DWORD (WINAPI *PFN_XInputGetState)(DWORD, XINPUT_STATE*);
|
||||
// 2017-10-23: Inputs: Using Win32 ::SetCapture/::GetCapture() to retrieve mouse positions outside the client area when dragging.
|
||||
// 2016-11-12: Inputs: Only call Win32 ::SetCursor(nullptr) when io.MouseDrawCursor is set.
|
||||
|
||||
// Forward Declarations
|
||||
static void ImGui_ImplWin32_InitPlatformInterface(bool platformHasOwnDC);
|
||||
static void ImGui_ImplWin32_ShutdownPlatformInterface();
|
||||
static void ImGui_ImplWin32_UpdateMonitors();
|
||||
|
||||
struct ImGui_ImplWin32_Data
|
||||
{
|
||||
HWND hWnd;
|
||||
@@ -101,6 +108,7 @@ struct ImGui_ImplWin32_Data
|
||||
INT64 TicksPerSecond;
|
||||
ImGuiMouseCursor LastMouseCursor;
|
||||
UINT32 KeyboardCodePage;
|
||||
bool WantUpdateMonitors;
|
||||
|
||||
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||
bool HasGamepad;
|
||||
@@ -150,16 +158,21 @@ static bool ImGui_ImplWin32_InitEx(void* hwnd, bool platform_has_own_dc)
|
||||
io.BackendPlatformName = "imgui_impl_win32";
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used)
|
||||
io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports; // We can create multi-viewports on the Platform side (optional)
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport; // We can call io.AddMouseViewportEvent() with correct data (optional)
|
||||
|
||||
bd->hWnd = (HWND)hwnd;
|
||||
bd->WantUpdateMonitors = true;
|
||||
bd->TicksPerSecond = perf_frequency;
|
||||
bd->Time = perf_counter;
|
||||
bd->LastMouseCursor = ImGuiMouseCursor_COUNT;
|
||||
ImGui_ImplWin32_UpdateKeyboardCodePage();
|
||||
|
||||
// Set platform dependent data in viewport
|
||||
ImGui::GetMainViewport()->PlatformHandleRaw = (void*)hwnd;
|
||||
IM_UNUSED(platform_has_own_dc); // Used in 'docking' branch
|
||||
// Our mouse update function expect PlatformHandle to be filled for the main viewport
|
||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||
main_viewport->PlatformHandle = main_viewport->PlatformHandleRaw = (void*)bd->hWnd;
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
ImGui_ImplWin32_InitPlatformInterface(platform_has_own_dc);
|
||||
|
||||
// Dynamically load XInput library
|
||||
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||
@@ -202,6 +215,8 @@ void ImGui_ImplWin32_Shutdown()
|
||||
IM_ASSERT(bd != nullptr && "No platform backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
ImGui_ImplWin32_ShutdownPlatformInterface();
|
||||
|
||||
// Unload XInput library
|
||||
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||
if (bd->XInputDLL)
|
||||
@@ -210,7 +225,7 @@ void ImGui_ImplWin32_Shutdown()
|
||||
|
||||
io.BackendPlatformName = nullptr;
|
||||
io.BackendPlatformUserData = nullptr;
|
||||
io.BackendFlags &= ~(ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_HasSetMousePos | ImGuiBackendFlags_HasGamepad);
|
||||
io.BackendFlags &= ~(ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_HasSetMousePos | ImGuiBackendFlags_HasGamepad | ImGuiBackendFlags_PlatformHasViewports | ImGuiBackendFlags_HasMouseHoveredViewport);
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
@@ -284,33 +299,59 @@ static void ImGui_ImplWin32_UpdateKeyModifiers()
|
||||
io.AddKeyEvent(ImGuiMod_Super, IsVkDown(VK_APPS));
|
||||
}
|
||||
|
||||
// This code supports multi-viewports (multiple OS Windows mapped into different Dear ImGui viewports)
|
||||
// Because of that, it is a little more complicated than your typical single-viewport binding code!
|
||||
static void ImGui_ImplWin32_UpdateMouseData()
|
||||
{
|
||||
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
IM_ASSERT(bd->hWnd != 0);
|
||||
|
||||
POINT mouse_screen_pos;
|
||||
bool has_mouse_screen_pos = ::GetCursorPos(&mouse_screen_pos) != 0;
|
||||
|
||||
HWND focused_window = ::GetForegroundWindow();
|
||||
const bool is_app_focused = (focused_window == bd->hWnd);
|
||||
const bool is_app_focused = (focused_window && (focused_window == bd->hWnd || ::IsChild(focused_window, bd->hWnd) || ImGui::FindViewportByPlatformHandle((void*)focused_window)));
|
||||
if (is_app_focused)
|
||||
{
|
||||
// (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
|
||||
// When multi-viewports are enabled, all Dear ImGui positions are same as OS positions.
|
||||
if (io.WantSetMousePos)
|
||||
{
|
||||
POINT pos = { (int)io.MousePos.x, (int)io.MousePos.y };
|
||||
if (::ClientToScreen(bd->hWnd, &pos))
|
||||
::SetCursorPos(pos.x, pos.y);
|
||||
if ((io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) == 0)
|
||||
::ClientToScreen(focused_window, &pos);
|
||||
::SetCursorPos(pos.x, pos.y);
|
||||
}
|
||||
|
||||
// (Optional) Fallback to provide mouse position when focused (WM_MOUSEMOVE already provides this when hovered or captured)
|
||||
// This also fills a short gap when clicking non-client area: WM_NCMOUSELEAVE -> modal OS move -> gap -> WM_NCMOUSEMOVE
|
||||
if (!io.WantSetMousePos && bd->MouseTrackedArea == 0)
|
||||
if (!io.WantSetMousePos && bd->MouseTrackedArea == 0 && has_mouse_screen_pos)
|
||||
{
|
||||
POINT pos;
|
||||
if (::GetCursorPos(&pos) && ::ScreenToClient(bd->hWnd, &pos))
|
||||
io.AddMousePosEvent((float)pos.x, (float)pos.y);
|
||||
// Single viewport mode: mouse position in client window coordinates (io.MousePos is (0,0) when the mouse is on the upper-left corner of the app window)
|
||||
// (This is the position you can get with ::GetCursorPos() + ::ScreenToClient() or WM_MOUSEMOVE.)
|
||||
// Multi-viewport mode: mouse position in OS absolute coordinates (io.MousePos is (0,0) when the mouse is on the upper-left of the primary monitor)
|
||||
// (This is the position you can get with ::GetCursorPos() or WM_MOUSEMOVE + ::ClientToScreen(). In theory adding viewport->Pos to a client position would also be the same.)
|
||||
POINT mouse_pos = mouse_screen_pos;
|
||||
if (!(io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable))
|
||||
::ScreenToClient(bd->hWnd, &mouse_pos);
|
||||
io.AddMousePosEvent((float)mouse_pos.x, (float)mouse_pos.y);
|
||||
}
|
||||
}
|
||||
|
||||
// (Optional) When using multiple viewports: call io.AddMouseViewportEvent() with the viewport the OS mouse cursor is hovering.
|
||||
// If ImGuiBackendFlags_HasMouseHoveredViewport is not set by the backend, Dear imGui will ignore this field and infer the information using its flawed heuristic.
|
||||
// - [X] Win32 backend correctly ignore viewports with the _NoInputs flag (here using ::WindowFromPoint with WM_NCHITTEST + HTTRANSPARENT in WndProc does that)
|
||||
// Some backend are not able to handle that correctly. If a backend report an hovered viewport that has the _NoInputs flag (e.g. when dragging a window
|
||||
// for docking, the viewport has the _NoInputs flag in order to allow us to find the viewport under), then Dear ImGui is forced to ignore the value reported
|
||||
// by the backend, and use its flawed heuristic to guess the viewport behind.
|
||||
// - [X] Win32 backend correctly reports this regardless of another viewport behind focused and dragged from (we need this to find a useful drag and drop target).
|
||||
ImGuiID mouse_viewport_id = 0;
|
||||
if (has_mouse_screen_pos)
|
||||
if (HWND hovered_hwnd = ::WindowFromPoint(mouse_screen_pos))
|
||||
if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle((void*)hovered_hwnd))
|
||||
mouse_viewport_id = viewport->ID;
|
||||
io.AddMouseViewportEvent(mouse_viewport_id);
|
||||
}
|
||||
|
||||
// Gamepad navigation mapping
|
||||
@@ -370,6 +411,35 @@ static void ImGui_ImplWin32_UpdateGamepads()
|
||||
#endif // #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||
}
|
||||
|
||||
static BOOL CALLBACK ImGui_ImplWin32_UpdateMonitors_EnumFunc(HMONITOR monitor, HDC, LPRECT, LPARAM)
|
||||
{
|
||||
MONITORINFO info = {};
|
||||
info.cbSize = sizeof(MONITORINFO);
|
||||
if (!::GetMonitorInfo(monitor, &info))
|
||||
return TRUE;
|
||||
ImGuiPlatformMonitor imgui_monitor;
|
||||
imgui_monitor.MainPos = ImVec2((float)info.rcMonitor.left, (float)info.rcMonitor.top);
|
||||
imgui_monitor.MainSize = ImVec2((float)(info.rcMonitor.right - info.rcMonitor.left), (float)(info.rcMonitor.bottom - info.rcMonitor.top));
|
||||
imgui_monitor.WorkPos = ImVec2((float)info.rcWork.left, (float)info.rcWork.top);
|
||||
imgui_monitor.WorkSize = ImVec2((float)(info.rcWork.right - info.rcWork.left), (float)(info.rcWork.bottom - info.rcWork.top));
|
||||
imgui_monitor.DpiScale = ImGui_ImplWin32_GetDpiScaleForMonitor(monitor);
|
||||
imgui_monitor.PlatformHandle = (void*)monitor;
|
||||
ImGuiPlatformIO& io = ImGui::GetPlatformIO();
|
||||
if (info.dwFlags & MONITORINFOF_PRIMARY)
|
||||
io.Monitors.push_front(imgui_monitor);
|
||||
else
|
||||
io.Monitors.push_back(imgui_monitor);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_UpdateMonitors()
|
||||
{
|
||||
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
||||
ImGui::GetPlatformIO().Monitors.resize(0);
|
||||
::EnumDisplayMonitors(nullptr, nullptr, ImGui_ImplWin32_UpdateMonitors_EnumFunc, 0);
|
||||
bd->WantUpdateMonitors = false;
|
||||
}
|
||||
|
||||
void ImGui_ImplWin32_NewFrame()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
@@ -380,6 +450,8 @@ void ImGui_ImplWin32_NewFrame()
|
||||
RECT rect = { 0, 0, 0, 0 };
|
||||
::GetClientRect(bd->hWnd, &rect);
|
||||
io.DisplaySize = ImVec2((float)(rect.right - rect.left), (float)(rect.bottom - rect.top));
|
||||
if (bd->WantUpdateMonitors)
|
||||
ImGui_ImplWin32_UpdateMonitors();
|
||||
|
||||
// Setup time step
|
||||
INT64 current_time = 0;
|
||||
@@ -595,8 +667,11 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
|
||||
bd->MouseTrackedArea = area;
|
||||
}
|
||||
POINT mouse_pos = { (LONG)GET_X_LPARAM(lParam), (LONG)GET_Y_LPARAM(lParam) };
|
||||
if (msg == WM_NCMOUSEMOVE && ::ScreenToClient(hwnd, &mouse_pos) == FALSE) // WM_NCMOUSEMOVE are provided in absolute coordinates.
|
||||
break;
|
||||
bool want_absolute_pos = (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) != 0;
|
||||
if (msg == WM_MOUSEMOVE && want_absolute_pos) // WM_MOUSEMOVE are client-relative coordinates.
|
||||
::ClientToScreen(hwnd, &mouse_pos);
|
||||
if (msg == WM_NCMOUSEMOVE && !want_absolute_pos) // WM_NCMOUSEMOVE are absolute coordinates.
|
||||
::ScreenToClient(hwnd, &mouse_pos);
|
||||
io.AddMouseSourceEvent(mouse_source);
|
||||
io.AddMousePosEvent((float)mouse_pos.x, (float)mouse_pos.y);
|
||||
break;
|
||||
@@ -735,6 +810,9 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
|
||||
bd->WantUpdateHasGamepad = true;
|
||||
#endif
|
||||
return 0;
|
||||
case WM_DISPLAYCHANGE:
|
||||
bd->WantUpdateMonitors = true;
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -799,6 +877,10 @@ typedef DPI_AWARENESS_CONTEXT(WINAPI* PFN_SetThreadDpiAwarenessContext)(DPI_AWAR
|
||||
// Helper function to enable DPI awareness without setting up a manifest
|
||||
void ImGui_ImplWin32_EnableDpiAwareness()
|
||||
{
|
||||
// Make sure monitors will be updated with latest correct scaling
|
||||
if (ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData())
|
||||
bd->WantUpdateMonitors = true;
|
||||
|
||||
if (_IsWindows10OrGreater())
|
||||
{
|
||||
static HINSTANCE user32_dll = ::LoadLibraryA("user32.dll"); // Reference counted per-process
|
||||
@@ -898,6 +980,348 @@ void ImGui_ImplWin32_EnableAlphaCompositing(void* hwnd)
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------
|
||||
// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
|
||||
// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously.
|
||||
// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first..
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
|
||||
// Helper structure we store in the void* RendererUserData field of each ImGuiViewport to easily retrieve our backend data.
|
||||
struct ImGui_ImplWin32_ViewportData
|
||||
{
|
||||
HWND Hwnd;
|
||||
HWND HwndParent;
|
||||
bool HwndOwned;
|
||||
DWORD DwStyle;
|
||||
DWORD DwExStyle;
|
||||
|
||||
ImGui_ImplWin32_ViewportData() { Hwnd = HwndParent = nullptr; HwndOwned = false; DwStyle = DwExStyle = 0; }
|
||||
~ImGui_ImplWin32_ViewportData() { IM_ASSERT(Hwnd == nullptr); }
|
||||
};
|
||||
|
||||
static void ImGui_ImplWin32_GetWin32StyleFromViewportFlags(ImGuiViewportFlags flags, DWORD* out_style, DWORD* out_ex_style)
|
||||
{
|
||||
if (flags & ImGuiViewportFlags_NoDecoration)
|
||||
*out_style = WS_POPUP;
|
||||
else
|
||||
*out_style = WS_OVERLAPPEDWINDOW;
|
||||
|
||||
if (flags & ImGuiViewportFlags_NoTaskBarIcon)
|
||||
*out_ex_style = WS_EX_TOOLWINDOW;
|
||||
else
|
||||
*out_ex_style = WS_EX_APPWINDOW;
|
||||
|
||||
if (flags & ImGuiViewportFlags_TopMost)
|
||||
*out_ex_style |= WS_EX_TOPMOST;
|
||||
}
|
||||
|
||||
static HWND ImGui_ImplWin32_GetHwndFromViewportID(ImGuiID viewport_id)
|
||||
{
|
||||
if (viewport_id != 0)
|
||||
if (ImGuiViewport* viewport = ImGui::FindViewportByID(viewport_id))
|
||||
return (HWND)viewport->PlatformHandle;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_CreateWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplWin32_ViewportData* vd = IM_NEW(ImGui_ImplWin32_ViewportData)();
|
||||
viewport->PlatformUserData = vd;
|
||||
|
||||
// Select style and parent window
|
||||
ImGui_ImplWin32_GetWin32StyleFromViewportFlags(viewport->Flags, &vd->DwStyle, &vd->DwExStyle);
|
||||
vd->HwndParent = ImGui_ImplWin32_GetHwndFromViewportID(viewport->ParentViewportId);
|
||||
|
||||
// Create window
|
||||
RECT rect = { (LONG)viewport->Pos.x, (LONG)viewport->Pos.y, (LONG)(viewport->Pos.x + viewport->Size.x), (LONG)(viewport->Pos.y + viewport->Size.y) };
|
||||
::AdjustWindowRectEx(&rect, vd->DwStyle, FALSE, vd->DwExStyle);
|
||||
vd->Hwnd = ::CreateWindowEx(
|
||||
vd->DwExStyle, _T("ImGui Platform"), _T("Untitled"), vd->DwStyle, // Style, class name, window name
|
||||
rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, // Window area
|
||||
vd->HwndParent, nullptr, ::GetModuleHandle(nullptr), nullptr); // Owner window, Menu, Instance, Param
|
||||
vd->HwndOwned = true;
|
||||
viewport->PlatformRequestResize = false;
|
||||
viewport->PlatformHandle = viewport->PlatformHandleRaw = vd->Hwnd;
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_DestroyWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
||||
if (ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData)
|
||||
{
|
||||
if (::GetCapture() == vd->Hwnd)
|
||||
{
|
||||
// Transfer capture so if we started dragging from a window that later disappears, we'll still receive the MOUSEUP event.
|
||||
::ReleaseCapture();
|
||||
::SetCapture(bd->hWnd);
|
||||
}
|
||||
if (vd->Hwnd && vd->HwndOwned)
|
||||
::DestroyWindow(vd->Hwnd);
|
||||
vd->Hwnd = nullptr;
|
||||
IM_DELETE(vd);
|
||||
}
|
||||
viewport->PlatformUserData = viewport->PlatformHandle = nullptr;
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_ShowWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData;
|
||||
IM_ASSERT(vd->Hwnd != 0);
|
||||
if (viewport->Flags & ImGuiViewportFlags_NoFocusOnAppearing)
|
||||
::ShowWindow(vd->Hwnd, SW_SHOWNA);
|
||||
else
|
||||
::ShowWindow(vd->Hwnd, SW_SHOW);
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_UpdateWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData;
|
||||
IM_ASSERT(vd->Hwnd != 0);
|
||||
|
||||
// Update Win32 parent if it changed _after_ creation
|
||||
// Unlike style settings derived from configuration flags, this is more likely to change for advanced apps that are manipulating ParentViewportID manually.
|
||||
HWND new_parent = ImGui_ImplWin32_GetHwndFromViewportID(viewport->ParentViewportId);
|
||||
if (new_parent != vd->HwndParent)
|
||||
{
|
||||
// Win32 windows can either have a "Parent" (for WS_CHILD window) or an "Owner" (which among other thing keeps window above its owner).
|
||||
// Our Dear Imgui-side concept of parenting only mostly care about what Win32 call "Owner".
|
||||
// The parent parameter of CreateWindowEx() sets up Parent OR Owner depending on WS_CHILD flag. In our case an Owner as we never use WS_CHILD.
|
||||
// Calling ::SetParent() here would be incorrect: it will create a full child relation, alter coordinate system and clipping.
|
||||
// Calling ::SetWindowLongPtr() with GWLP_HWNDPARENT seems correct although poorly documented.
|
||||
// https://devblogs.microsoft.com/oldnewthing/20100315-00/?p=14613
|
||||
vd->HwndParent = new_parent;
|
||||
::SetWindowLongPtr(vd->Hwnd, GWLP_HWNDPARENT, (LONG_PTR)vd->HwndParent);
|
||||
}
|
||||
|
||||
// (Optional) Update Win32 style if it changed _after_ creation.
|
||||
// Generally they won't change unless configuration flags are changed, but advanced uses (such as manually rewriting viewport flags) make this useful.
|
||||
DWORD new_style;
|
||||
DWORD new_ex_style;
|
||||
ImGui_ImplWin32_GetWin32StyleFromViewportFlags(viewport->Flags, &new_style, &new_ex_style);
|
||||
|
||||
// Only reapply the flags that have been changed from our point of view (as other flags are being modified by Windows)
|
||||
if (vd->DwStyle != new_style || vd->DwExStyle != new_ex_style)
|
||||
{
|
||||
// (Optional) Update TopMost state if it changed _after_ creation
|
||||
bool top_most_changed = (vd->DwExStyle & WS_EX_TOPMOST) != (new_ex_style & WS_EX_TOPMOST);
|
||||
HWND insert_after = top_most_changed ? ((viewport->Flags & ImGuiViewportFlags_TopMost) ? HWND_TOPMOST : HWND_NOTOPMOST) : 0;
|
||||
UINT swp_flag = top_most_changed ? 0 : SWP_NOZORDER;
|
||||
|
||||
// Apply flags and position (since it is affected by flags)
|
||||
vd->DwStyle = new_style;
|
||||
vd->DwExStyle = new_ex_style;
|
||||
::SetWindowLong(vd->Hwnd, GWL_STYLE, vd->DwStyle);
|
||||
::SetWindowLong(vd->Hwnd, GWL_EXSTYLE, vd->DwExStyle);
|
||||
RECT rect = { (LONG)viewport->Pos.x, (LONG)viewport->Pos.y, (LONG)(viewport->Pos.x + viewport->Size.x), (LONG)(viewport->Pos.y + viewport->Size.y) };
|
||||
::AdjustWindowRectEx(&rect, vd->DwStyle, FALSE, vd->DwExStyle); // Client to Screen
|
||||
::SetWindowPos(vd->Hwnd, insert_after, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, swp_flag | SWP_NOACTIVATE | SWP_FRAMECHANGED);
|
||||
::ShowWindow(vd->Hwnd, SW_SHOWNA); // This is necessary when we alter the style
|
||||
viewport->PlatformRequestMove = viewport->PlatformRequestResize = true;
|
||||
}
|
||||
}
|
||||
|
||||
static ImVec2 ImGui_ImplWin32_GetWindowPos(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData;
|
||||
IM_ASSERT(vd->Hwnd != 0);
|
||||
POINT pos = { 0, 0 };
|
||||
::ClientToScreen(vd->Hwnd, &pos);
|
||||
return ImVec2((float)pos.x, (float)pos.y);
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_SetWindowPos(ImGuiViewport* viewport, ImVec2 pos)
|
||||
{
|
||||
ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData;
|
||||
IM_ASSERT(vd->Hwnd != 0);
|
||||
RECT rect = { (LONG)pos.x, (LONG)pos.y, (LONG)pos.x, (LONG)pos.y };
|
||||
::AdjustWindowRectEx(&rect, vd->DwStyle, FALSE, vd->DwExStyle);
|
||||
::SetWindowPos(vd->Hwnd, nullptr, rect.left, rect.top, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
|
||||
}
|
||||
|
||||
static ImVec2 ImGui_ImplWin32_GetWindowSize(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData;
|
||||
IM_ASSERT(vd->Hwnd != 0);
|
||||
RECT rect;
|
||||
::GetClientRect(vd->Hwnd, &rect);
|
||||
return ImVec2(float(rect.right - rect.left), float(rect.bottom - rect.top));
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
|
||||
{
|
||||
ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData;
|
||||
IM_ASSERT(vd->Hwnd != 0);
|
||||
RECT rect = { 0, 0, (LONG)size.x, (LONG)size.y };
|
||||
::AdjustWindowRectEx(&rect, vd->DwStyle, FALSE, vd->DwExStyle); // Client to Screen
|
||||
::SetWindowPos(vd->Hwnd, nullptr, 0, 0, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_SetWindowFocus(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData;
|
||||
IM_ASSERT(vd->Hwnd != 0);
|
||||
::BringWindowToTop(vd->Hwnd);
|
||||
::SetForegroundWindow(vd->Hwnd);
|
||||
::SetFocus(vd->Hwnd);
|
||||
}
|
||||
|
||||
static bool ImGui_ImplWin32_GetWindowFocus(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData;
|
||||
IM_ASSERT(vd->Hwnd != 0);
|
||||
return ::GetForegroundWindow() == vd->Hwnd;
|
||||
}
|
||||
|
||||
static bool ImGui_ImplWin32_GetWindowMinimized(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData;
|
||||
IM_ASSERT(vd->Hwnd != 0);
|
||||
return ::IsIconic(vd->Hwnd) != 0;
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_SetWindowTitle(ImGuiViewport* viewport, const char* title)
|
||||
{
|
||||
// ::SetWindowTextA() doesn't properly handle UTF-8 so we explicitely convert our string.
|
||||
ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData;
|
||||
IM_ASSERT(vd->Hwnd != 0);
|
||||
int n = ::MultiByteToWideChar(CP_UTF8, 0, title, -1, nullptr, 0);
|
||||
ImVector<wchar_t> title_w;
|
||||
title_w.resize(n);
|
||||
::MultiByteToWideChar(CP_UTF8, 0, title, -1, title_w.Data, n);
|
||||
::SetWindowTextW(vd->Hwnd, title_w.Data);
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_SetWindowAlpha(ImGuiViewport* viewport, float alpha)
|
||||
{
|
||||
ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData;
|
||||
IM_ASSERT(vd->Hwnd != 0);
|
||||
IM_ASSERT(alpha >= 0.0f && alpha <= 1.0f);
|
||||
if (alpha < 1.0f)
|
||||
{
|
||||
DWORD style = ::GetWindowLongW(vd->Hwnd, GWL_EXSTYLE) | WS_EX_LAYERED;
|
||||
::SetWindowLongW(vd->Hwnd, GWL_EXSTYLE, style);
|
||||
::SetLayeredWindowAttributes(vd->Hwnd, 0, (BYTE)(255 * alpha), LWA_ALPHA);
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD style = ::GetWindowLongW(vd->Hwnd, GWL_EXSTYLE) & ~WS_EX_LAYERED;
|
||||
::SetWindowLongW(vd->Hwnd, GWL_EXSTYLE, style);
|
||||
}
|
||||
}
|
||||
|
||||
static float ImGui_ImplWin32_GetWindowDpiScale(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData;
|
||||
IM_ASSERT(vd->Hwnd != 0);
|
||||
return ImGui_ImplWin32_GetDpiScaleForHwnd(vd->Hwnd);
|
||||
}
|
||||
|
||||
// FIXME-DPI: Testing DPI related ideas
|
||||
static void ImGui_ImplWin32_OnChangedViewport(ImGuiViewport* viewport)
|
||||
{
|
||||
(void)viewport;
|
||||
#if 0
|
||||
ImGuiStyle default_style;
|
||||
//default_style.WindowPadding = ImVec2(0, 0);
|
||||
//default_style.WindowBorderSize = 0.0f;
|
||||
//default_style.ItemSpacing.y = 3.0f;
|
||||
//default_style.FramePadding = ImVec2(0, 0);
|
||||
default_style.ScaleAllSizes(viewport->DpiScale);
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
style = default_style;
|
||||
#endif
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK ImGui_ImplWin32_WndProcHandler_PlatformWindow(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam))
|
||||
return true;
|
||||
|
||||
if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle((void*)hWnd))
|
||||
{
|
||||
switch (msg)
|
||||
{
|
||||
case WM_CLOSE:
|
||||
viewport->PlatformRequestClose = true;
|
||||
return 0;
|
||||
case WM_MOVE:
|
||||
viewport->PlatformRequestMove = true;
|
||||
break;
|
||||
case WM_SIZE:
|
||||
viewport->PlatformRequestResize = true;
|
||||
break;
|
||||
case WM_MOUSEACTIVATE:
|
||||
if (viewport->Flags & ImGuiViewportFlags_NoFocusOnClick)
|
||||
return MA_NOACTIVATE;
|
||||
break;
|
||||
case WM_NCHITTEST:
|
||||
// Let mouse pass-through the window. This will allow the backend to call io.AddMouseViewportEvent() correctly. (which is optional).
|
||||
// The ImGuiViewportFlags_NoInputs flag is set while dragging a viewport, as want to detect the window behind the one we are dragging.
|
||||
// If you cannot easily access those viewport flags from your windowing/event code: you may manually synchronize its state e.g. in
|
||||
// your main loop after calling UpdatePlatformWindows(). Iterate all viewports/platform windows and pass the flag to your windowing system.
|
||||
if (viewport->Flags & ImGuiViewportFlags_NoInputs)
|
||||
return HTTRANSPARENT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return DefWindowProc(hWnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_InitPlatformInterface(bool platform_has_own_dc)
|
||||
{
|
||||
WNDCLASSEX wcex;
|
||||
wcex.cbSize = sizeof(WNDCLASSEX);
|
||||
wcex.style = CS_HREDRAW | CS_VREDRAW | (platform_has_own_dc ? CS_OWNDC : 0);
|
||||
wcex.lpfnWndProc = ImGui_ImplWin32_WndProcHandler_PlatformWindow;
|
||||
wcex.cbClsExtra = 0;
|
||||
wcex.cbWndExtra = 0;
|
||||
wcex.hInstance = ::GetModuleHandle(nullptr);
|
||||
wcex.hIcon = nullptr;
|
||||
wcex.hCursor = nullptr;
|
||||
wcex.hbrBackground = (HBRUSH)(COLOR_BACKGROUND + 1);
|
||||
wcex.lpszMenuName = nullptr;
|
||||
wcex.lpszClassName = _T("ImGui Platform");
|
||||
wcex.hIconSm = nullptr;
|
||||
::RegisterClassEx(&wcex);
|
||||
|
||||
ImGui_ImplWin32_UpdateMonitors();
|
||||
|
||||
// Register platform interface (will be coupled with a renderer interface)
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
platform_io.Platform_CreateWindow = ImGui_ImplWin32_CreateWindow;
|
||||
platform_io.Platform_DestroyWindow = ImGui_ImplWin32_DestroyWindow;
|
||||
platform_io.Platform_ShowWindow = ImGui_ImplWin32_ShowWindow;
|
||||
platform_io.Platform_SetWindowPos = ImGui_ImplWin32_SetWindowPos;
|
||||
platform_io.Platform_GetWindowPos = ImGui_ImplWin32_GetWindowPos;
|
||||
platform_io.Platform_SetWindowSize = ImGui_ImplWin32_SetWindowSize;
|
||||
platform_io.Platform_GetWindowSize = ImGui_ImplWin32_GetWindowSize;
|
||||
platform_io.Platform_SetWindowFocus = ImGui_ImplWin32_SetWindowFocus;
|
||||
platform_io.Platform_GetWindowFocus = ImGui_ImplWin32_GetWindowFocus;
|
||||
platform_io.Platform_GetWindowMinimized = ImGui_ImplWin32_GetWindowMinimized;
|
||||
platform_io.Platform_SetWindowTitle = ImGui_ImplWin32_SetWindowTitle;
|
||||
platform_io.Platform_SetWindowAlpha = ImGui_ImplWin32_SetWindowAlpha;
|
||||
platform_io.Platform_UpdateWindow = ImGui_ImplWin32_UpdateWindow;
|
||||
platform_io.Platform_GetWindowDpiScale = ImGui_ImplWin32_GetWindowDpiScale; // FIXME-DPI
|
||||
platform_io.Platform_OnChangedViewport = ImGui_ImplWin32_OnChangedViewport; // FIXME-DPI
|
||||
|
||||
// Register main window handle (which is owned by the main application, not by us)
|
||||
// This is mostly for simplicity and consistency, so that our code (e.g. mouse handling etc.) can use same logic for main and secondary viewports.
|
||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
||||
ImGui_ImplWin32_ViewportData* vd = IM_NEW(ImGui_ImplWin32_ViewportData)();
|
||||
vd->Hwnd = bd->hWnd;
|
||||
vd->HwndOwned = false;
|
||||
main_viewport->PlatformUserData = vd;
|
||||
main_viewport->PlatformHandle = (void*)bd->hWnd;
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_ShutdownPlatformInterface()
|
||||
{
|
||||
::UnregisterClass(_T("ImGui Platform"), ::GetModuleHandle(nullptr));
|
||||
ImGui::DestroyPlatformWindows();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy VK_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
||||
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
|
||||
@@ -36,10 +36,122 @@ HOW TO UPDATE?
|
||||
- Please report any issue!
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.90.1 (Released 2024-01-10)
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
Decorated log and release notes: https://github.com/ocornut/imgui/releases/tag/v1.90.1
|
||||
|
||||
Breaking changes:
|
||||
|
||||
- imgui_freetype: commented out ImGuiFreeType::BuildFontAtlas() obsoleted in 1.81.
|
||||
Prefer using #define IMGUI_ENABLE_FREETYPE or see commented code for manual calls.
|
||||
- Removed CalcListClipping() marked obsolete in 1.86. (#3841)
|
||||
Prefer using ImGuiListClipper which can return non-contiguous ranges.
|
||||
- Internals, Columns: commented out legacy ImGuiColumnsFlags_XXX symbols redirecting
|
||||
to ImGuiOldColumnsFlags_XXX, obsoleted from imgui_internal.h in 1.80.
|
||||
- Commented out obsolete ImGuiKey_KeyPadEnter redirection to ImGuiKey_KeypadEnter. (#2625, #7143)
|
||||
|
||||
Other changes:
|
||||
|
||||
- Windows:
|
||||
- BeginChild(): Fixed auto-resizing erroneously limiting size to host viewport
|
||||
minus padding. There are no limit to a child width/height. (#7063) [@Devyre]
|
||||
- BeginChild(): Resize borders rendered even when ImGuiWindowFlags_NoBackground
|
||||
is specified. (#1710, #7194)
|
||||
- Fixed some auto-resizing path using style.WindowMinSize.x (instead of x/y)
|
||||
for both axises since 1.90. (#7106) [@n0bodysec]
|
||||
- Scrolling: internal scrolling value is rounded instead of truncated, as a way to reduce
|
||||
speed asymmetry when (incorrectly) attempting to scroll by non-integer amount. (#6677)
|
||||
- Navigation (Keyboard/gamepad):
|
||||
- Nav, IO: SetNextFrameWantCaptureKeyboard(false) calls are not overridden back to true when
|
||||
navigation is enabled. SetNextFrameWantCaptureKeyboard() is always higher priority. (#6997)
|
||||
- Nav: Activation can also be performed with Keypad Enter. (#5606)
|
||||
- Drag and Drop:
|
||||
- Fixed drop target highlight on items temporarily pushing a widened clip rect
|
||||
(namely Selectables and Treenodes using SpanAllColumn flag) so the highlight properly covers
|
||||
all columns. (#7049, #4281, #3272)
|
||||
- InputText:
|
||||
- InputTextMultiline: Fixed Tab character input not repeating (1.89.4 regression).
|
||||
- InputTextMultiline: Tabbing through a multi-line text editor which allows Tab character inputs
|
||||
(using the ImGuiInputTextFlags_AllowTabInput flag) doesn't automatically activate it, in order
|
||||
to allow passing through multiple widgets easily. (#3092, #5759, #787)
|
||||
- Drags, Sliders, Inputs:
|
||||
- DragScalarN, SliderScalarN, InputScalarN: Fixed incorrect pushes into ItemWidth
|
||||
stack when number of components is 1. [#7095] [@Nahor]
|
||||
- Drags, Sliders, Inputs: removed all attempts to filter non-numerical characters during text
|
||||
editing. Invalid inputs not applied to value, visibly reverted after validation. (#6810, #7096)
|
||||
- Drags, Sliders, Inputs: removal of filter means that "nan" and "inf" values may be input. (#7096)
|
||||
- DragScalarN, SliderScalarN, InputScalarN, PushMultiItemsWidths: improve multi-components
|
||||
width computation to better distribute the error. (#7120, #7121) [@Nahor]
|
||||
- Menus:
|
||||
- Tweaked hover slack logic, adding an extra timeout to avoid situations where a slow vertical
|
||||
movements toward another parent BeginMenu() can keep the wrong child menu open. (#6671, #6926)
|
||||
- Color Editors:
|
||||
- ColorEdit: Layout tweaks for very small sizes. (#7120, #7121)
|
||||
- ColorPicker: Fixed saturation/value cursor radius not scaling properly.
|
||||
- Debug Tools:
|
||||
- Added io.ConfigDebugIsDebuggerPresent option. When enabled, this adds buttons in various
|
||||
locations of Metrics/Debugger to manually request a debugger break:
|
||||
- Request a debug break in a Begin() call.
|
||||
- Request a debug break in a ItemAdd() call via debug log and hovering 0xXXXXXX identifiers.
|
||||
- Request a debug break in a BeginTable() call.
|
||||
- Request a debug break in a SetShortcutRouting()/Shortcut() call. [Internal]
|
||||
- Metrics: Reorganize Tools menu.
|
||||
- Added DebugFlashStyleColor() to identify a style color. Added to Style Editor.
|
||||
- Debug Log: Hide its own clipper log to reduce noise in the output. (#5855)
|
||||
- Debug Log: Clicking any filter with SHIFT held enables it for 2 frames only,
|
||||
making it easier when dealing with spammy logs. (#5855)
|
||||
- Settings: Fixed an issue marking settings as dirty when merely clicking on a border or resize
|
||||
grip without moving it.
|
||||
- Misc: Added IMGUI_USER_H_FILENAME to change the path included when using
|
||||
IMGUI_INCLUDE_IMGUI_USER_H. (#7039) [@bryceberger]
|
||||
- Misc: Rework debug display of texture id in Metrics window to avoid compile-error when
|
||||
ImTextureID is defined to be larger than 64-bits. (#7090)
|
||||
- Misc: Added extra courtesy ==/!= operators when IMGUI_DEFINE_MATH_OPERATORS is defined.
|
||||
- Misc: Fixed text functions fast-path for handling "%s" and "%.*s" to handle null pointers gracefully,
|
||||
like most printf implementations. (#7016, #3466, #6846) [@codefrog2002]
|
||||
- Misc: Renamed some defines in imstb_textedit.h to avoid conflicts when using unity/jumbo builds
|
||||
on a codebase where another copy of the library is used.
|
||||
- Misc: During shutdown, check that io.BackendPlatformUserData and io.BackendRendererUserData are NULL
|
||||
in order to catch cases where backend was not shut down. (#7175)
|
||||
- Misc: Reworked Issue Template to a shinier and better form. (#5927) [@Panquesito7, @PathogenDavid, @ocornut]
|
||||
- Backends:
|
||||
- GLFW, Emscripten: Added ImGui_ImplGlfw_InstallEmscriptenCanvasResizeCallback() to
|
||||
register canvas selector and auto-resize GLFW window. (#6751) [@Traveller23, @ypujante]
|
||||
- GLFW: Fixed Windows specific hooks to use Unicode version of WndProc even when
|
||||
compiling in MBCS mode. (#7174) [@kimidaisuki22]
|
||||
- OpenGL3: Update GL3W based imgui_impl_opengl3_loader.h to load libGL.so variants in
|
||||
case of missing symlink. Fix 1.90 regression for some distros. (#6983)
|
||||
- Vulkan: Fixed mismatching allocator passed to vkCreateCommandPool() vs
|
||||
vkDestroyCommandPool(). (#7075) [@FoonTheRaccoon]
|
||||
- Vulkan: Added MinAllocationSize field in ImGui_ImplVulkan_InitInfo to workaround zealous
|
||||
"best practice" validation layer. (#7189, #4238) [@philae-ael]
|
||||
- Vulkan: Stopped creating command pools with VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT
|
||||
as we don't reset them.
|
||||
- WebGPU: Fixed wgpuRenderPassEncoderSetScissorRect() crash when rendering modal window's
|
||||
dimming layer, which has an unclipped value in ImDrawCmd::ClipRect. (#7191) [@aparis69]
|
||||
- Examples:
|
||||
- Examples: GLFW+Emscripten: Fixed examples not consistently resizing according to host canvas.
|
||||
(#6751) [@Traveller23, @ypujante]
|
||||
- Examples: SDL3: Minor fixes following recent SDL3 in-progress development.
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- Windows: Fixed ImGuiCol_TitleBg/Active alpha being used for viewport-owned windows. (#7181) [@PathogenDavid]
|
||||
- Backends: DX12: Changed swapchain scaling mode to DXGI_SCALING_NONE to reduce artifacts as
|
||||
queued frames aren't synchronized with platform window resizes. (#7152, #7153) [@SuperWangKai]
|
||||
- Backends: OSX: Fixed monitor and window position by correctly transforming Y origin on multi-viewports
|
||||
multi-monitor setups. (#7028, #7101, #6009, #6432) [@dmirty-kuzmenko, @734vin]
|
||||
- Backends: OSX: Fixed IME position in multi-monitor multi-viewports setups. (#7028) [@734vin]
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.90.0 (Released 2023-11-15)
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
Decorated log and release notes: https://github.com/ocornut/imgui/releases/tag/v1.90
|
||||
|
||||
Breaking changes:
|
||||
|
||||
- BeginChild(): Upgraded 'bool border = false' parameter to 'ImGuiChildFlags flags = 0'.
|
||||
@@ -225,6 +337,8 @@ Other changes:
|
||||
Fixed leaks, and added ImGui_ImplVulkan_DestroyFontsTexture() (probably no need to call this directly).
|
||||
(#6943, #6715, #6327, #3743, #4618)
|
||||
[@helynranta, @thomasherzog, @guybrush77, @albin-johansson, @MiroKaku, @benbatya-fb, @ocornut]
|
||||
- Backends: Vulkan: use specified ColorAttachmentFormat when creating a secondary window when enabling
|
||||
UseDynamicRendering option. (#6999, #5446, #5037) [@raaaviol]
|
||||
- Backends: GLFW: Clear emscripten's MouseWheel callback before shutdown. (#6790, #6096, #4019) [@halx99]
|
||||
- Backends: GLFW: Added support for F13 to F24 function keys. (#6891)
|
||||
- Backends: SDL2, SDL3: Added support for F13 to F24 function keys, AppBack, AppForward. (#6891)
|
||||
@@ -242,6 +356,31 @@ Other changes:
|
||||
- Examples: GLFW+Vulkan, SDL+Vulkan: Simplified and removed code due to backend improvements.
|
||||
- Internals: Renamed ImFloor() to ImTrunc(). Renamed ImFloorSigned() to ImFloor(). (#6861)
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- Viewports: Fixed window inner clipping rectangle off by one when window is located on a monitor
|
||||
with negative coordinates. While it is expected that other small issues with arise from this
|
||||
situation, at the moment we are fixing the most noticeable one. (#6861, #2884) [@Vuhdo, @alektron]
|
||||
- Docking: revised undocking to reduce accidental whole-node undocking:
|
||||
- cannot undock a whole node by dragging from empty space in tab-bar.
|
||||
- can undock whole node by dragging from window/collapse menu button.
|
||||
- can undock single window by dragging from its tab.
|
||||
- can still move (but not undock) whole node or whole hierarchy when node is part of a
|
||||
floating hierarchy.
|
||||
- added tooltip when hovering the collapse/window menu button, to faciliate understanding
|
||||
that whole dock node may be undocked or grabbed from here.
|
||||
- Docking: Fixed an issue leading to incorrect restoration of selected tab in dock nodes that
|
||||
don't carry the currently focused window. (#2304)
|
||||
- Docking: added ImGuiDockNodeFlags_NoUndocking. (#2999, #6823, #6780, #3492)
|
||||
- Docking: renamed ImGuiDockNodeFlags_NoSplit to ImGuiDockNodeFlags_NoDockingSplit.
|
||||
- Docking: renamed ImGuiDockNodeFlags_NoDockingInCentralNode to ImGuiDockNodeFlags_NoDockingOverCentralNode.
|
||||
- Docking: Internals: renamed ImGuiDockNodeFlags_NoDockingSplitMe to ImGuiDockNodeFlags_NoDockingSplit.
|
||||
- Docking: Fixed a bug where ClassId compare tests (when using SetNextWindowClass) on success would
|
||||
prevent further filter from running, namely the one that prevent docking over a popup.
|
||||
- Backends: GLFW: Fixed an assertion in situation where the WndProc handler is different between
|
||||
main and secondary viewport (may happen due to third-party hooks). (#6889)
|
||||
- Backends: DX9: Fixed incorrect assert triggering on reopening session with minimized windows. (#3424)
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.89.9 (Released 2023-09-04)
|
||||
@@ -299,6 +438,11 @@ Other changes:
|
||||
- Examples: Emscripten+WebGPU: Fixed WGPUInstance creation process + use preferred
|
||||
framebuffer format. (#6640, #6748) [@smileorigin]
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- Docking: when io.ConfigDockingWithShift is enabled, staying stationary while moving
|
||||
a window displays an help tooltip to increase affordance. (#6709, #4643)
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.89.8 (Released 2023-08-01)
|
||||
@@ -367,6 +511,16 @@ Other changes:
|
||||
- Examples: Vulkan: Creating minimal descriptor pools to fit only what is needed by
|
||||
example. (#6642) [@SaschaWillem]
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- Docking, Style: resizing separators use same colors as window borders (ImGuiCol_Border)
|
||||
for consistency. With default styles it doesn't make a big difference. (#2522) [@rmitton]
|
||||
In the future if we promote using thick value for inner/outer docking padding we may
|
||||
need to introduce new colors for it.
|
||||
- Docking: added style.DockingSeparatorSize, ImGuiStyleVar_DockingSeparatorSize. Now
|
||||
also scaled by style.ScaleAllSizes(). (#3481, #4721, #2522) [@PossiblyAShrub, @wobbier]
|
||||
- Docking: fixed rendering of docked-window scrollbar above outer border. (#2522)
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.89.7 (Released 2023-07-04)
|
||||
@@ -462,6 +616,23 @@ Other changes:
|
||||
- Examples: Win32+OpenGL3: Changed DefWindowProc() to DefWindowProcW() to match other examples
|
||||
and support the example app being compiled without UNICODE. (#6516, #5725, #5961, #5975) [@yenixing]
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- Viewports+Docking: Fixed extraneous viewport+platform-window recreation in various
|
||||
combination of showing or hiding windows, docking with/without split, undocking.
|
||||
While with some backends and without OS decorations, some extraneous window recreation
|
||||
were visibly not noticeable, they would typically become noticeable when enabling
|
||||
OS decorations on those windows (e.g. Windows title bar fade-in/animation).
|
||||
- Viewports: Closing a viewport via OS/platform means (e.g. OS close button or task-bar menu),
|
||||
mark all windows in this viewport as closed.
|
||||
- Docking: Fixed one-frame flickering on reappearing windows binding to a dock node
|
||||
where a later-submitted window was already bound.
|
||||
- Docking: Fixed dragging from title-bar empty space (regression from 1.88 related to
|
||||
keeping ID alive when calling low-level ButtonBehavior() directly). (#5181, #2645)
|
||||
- Docking: [Internal] DockBuilderDockWindow() API calls don't clear docking order
|
||||
if the target node is same as existing one.
|
||||
- Backends: Win32: Added support for changing ParentViewportID after viewport creation.
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.89.6 (Released 2023-05-31)
|
||||
@@ -531,6 +702,23 @@ Other changes:
|
||||
- Examples: Added SDL3+SDL_Renderer example. (#6286)
|
||||
- Examples: Updated all Visual Studio projects and batches to use /utf-8 argument.
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- Viewports: Fixed platform-side focus (e.g. Alt+Tab) from leading to accidental
|
||||
closure of Modal windows. Regression from 1.89.5. (#6357, #6299)
|
||||
- Viewports: Fixed loss of imgui-side focus when dragging a secondary viewport back in
|
||||
main viewport, due to platform-side handling changes. Regression from 1.89.5 (#6299)
|
||||
- Viewports: Avoid applying imgui-side focus when focus change is due to a viewport
|
||||
destruction. Fixes erroneous popup closure on closing a previous popup. (#6462, #6299)
|
||||
- Viewports: Added void* ImGuiPlatformMonitor::PlatformHandle field (backend-dependant),
|
||||
for usage by user code.
|
||||
- Backends: GLFW: Preserve monitor list when there are no monitor, may briefly
|
||||
happen when recovering from macOS sleeping mode. (#5683) [@Guistac]
|
||||
- Backends: SDL2: Update monitor list when receiving a display event. (#6348)
|
||||
Note however that SDL2 currently doesn't have an event for a DPI/Scaling change,
|
||||
so monitor data won't be updated in this situation.
|
||||
- Backends: SDL3: Update monitor list when receiving a display event. (#6348)
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.89.5 (Released 2023-04-13)
|
||||
@@ -588,7 +776,6 @@ Other changes:
|
||||
is to other IME function such as SDL_SetTextInputRect(). (#6306, #6071, #1953)
|
||||
- Backends: GLFW: Added support on Win32 only for io.AddMouseSourceEvent() to discriminate
|
||||
Mouse/TouchScreen/Pen. (#2334, #2702)
|
||||
- Backends: GLFW: Fixed key modifiers handling on secondary viewports. (#6248, #6034) [@aiekick]
|
||||
- Backends: Android: Added support for io.AddMouseSourceEvent() to discriminate Mouse/TouchScreen/Pen.
|
||||
(#6315) [@PathogenDavid]
|
||||
- Backends: OSX: Added support for io.AddMouseSourceEvent() to discriminate Mouse/Pen.
|
||||
@@ -604,6 +791,16 @@ Other changes:
|
||||
- TestSuite: Added variety of new regression tests and improved/amended existing ones
|
||||
in imgui_test_engine/ repo. [@PathogenDavid, @ocornut]
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- Viewports: Setting focus from Platform/OS (e.g. via decoration, or Alt-Tab) sets corresponding
|
||||
focus at Dear ImGui level (generally last focused window in the viewport). (#6299)
|
||||
- Docking: Fixed using GetItemXXX() or IsItemXXX() functions after a DockSpace(). (#6217)
|
||||
- Backends: GLFW: Fixed key modifiers handling on secondary viewports. (#6248, #6034) [@aiekick]
|
||||
- Backends: GLFW: Fixed Emscripten erroneously enabling multi-viewport support, leading to assert. (#5683)
|
||||
- Backends: SDL2/SDL3: Fixed IME text input rectangle position with viewports. (#6071, #1953)
|
||||
- Backends: SDL3: Fixed for compilation with multi-viewports. (#6255) [@P3RK4N]
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.89.4 (Released 2023-03-14)
|
||||
@@ -678,7 +875,6 @@ Other changes:
|
||||
and ImGuiConfigFlags_NavEnableGamepad by default. (#787)
|
||||
- Internals: Misc tweaks to facilitate applying an explicit-context patch. (#5856) [@Dragnalith]
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.89.3 (Released 2023-02-14)
|
||||
-----------------------------------------------------------------------
|
||||
@@ -779,6 +975,10 @@ Other changes:
|
||||
- Examples: SDL2+SDL_Renderer: Added call to SDL_RenderSetScale() to fix display on a
|
||||
Retina display (albeit lower-res as our other unmodified examples). (#6121, #6065, #5931).
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- Backends: GLFW: Handle unsupported glfwGetVideoMode() for Emscripten. (#6096)
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.89.2 (Released 2023-01-05)
|
||||
@@ -829,6 +1029,17 @@ All changes:
|
||||
- Backends: Vulkan: Fixed sampler passed to ImGui_ImplVulkan_AddTexture() not being honored as we were using
|
||||
an immutable sampler. (#5502, #6001, #914) [@martin-ejdestig, @rytisss]
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- Docking: Internals: fixed DockBuilderCopyDockSpace() crashing when windows not in the
|
||||
remapping list are docked on the left or top side of a split. (#6035)
|
||||
- Docking: fixed DockSpace() with ImGuiDockNodeFlags_KeepAliveOnly marking current window
|
||||
as written to, even if it doesn't technically submit an item. This allow using KeepAliveOnly
|
||||
from any window location. (#6037)
|
||||
- Backends: OSX: fixed typo in ImGui_ImplOSX_GetWindowSize that would cause issues when resiing
|
||||
from OS decorations, if they are enabled on secondary viewports. (#6009) [@sivu]
|
||||
- Backends: Metal: fixed secondary viewport rendering. (#6015) [@dmirty-kuzmenko]
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.89.1 (Released 2022-11-24)
|
||||
@@ -855,6 +1066,13 @@ Other changes:
|
||||
- Backends: GLFW: cancel out errors emitted by glfwGetKeyName() when a name is missing. (#5908)
|
||||
- Backends: WebGPU: fixed validation error with default depth buffer settings. (#5869, #5914) [@kdchambers]
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- Viewports: Fixed collapsed windows setting ImGuiViewportFlags_NoRendererClear without
|
||||
making title bar color opaque, leading to potential texture/fb garbage being visible.
|
||||
Right now as we don't fully support transparent viewports (#2766), so we turn that
|
||||
'TitleBgCollapsed' color opaque just lke we do for 'WindowBG' on uncollapsed windows.
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.89 (Released 2022-11-15)
|
||||
@@ -1046,6 +1264,23 @@ Other Changes:
|
||||
- Backends: Vulkan: Added experimental ImGui_ImplVulkan_RemoveTexture() for api symetry. (#914, #5738).
|
||||
- Backends: WebGPU: fixed rendering when a depth buffer is enabled. (#5869) [@brainlag]
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- Docking: Fixed incorrect focus highlight on docking node when focusing a menu. (#5702)
|
||||
- Docking, Nav: Fixed using gamepad/keyboard navigation not being able enter menu layer when
|
||||
it only contained the standard Collapse/Close buttons and no actual menu. (#5463, #4792)
|
||||
- Docking: Fixed regression introduced in v1.87 when docked window content not rendered
|
||||
while switching between with CTRL+Tab. [@rokups]
|
||||
- Docking: Fixed amending into an existing tab bar from rendering invisible items. (#5515)
|
||||
- Docking: Made spacing between dock nodes not a dropping gap. When hovering it only
|
||||
outer-docking drop markers are visible.
|
||||
- Docking+Viewports: Fixed undocking window node causing parent viewports to become unresponsive
|
||||
in certain situation (e.g. hidden tab bar). (#5503) [@rokups]
|
||||
- Backends: SDL: Fixed building backend under non-OSX Apple targets (e.g. iPhone). (#5665)
|
||||
- Backends: SDL: Fixed drag'n drop crossing a viewport border losing mouse coordinates. (#5710, #5012)
|
||||
- Backends: GLFW: Fixed leftover static variable preventing from changing or
|
||||
reinitializing backend while application is running. (#4616, #5434) [@rtoumazet]
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.88 (Released 2022-06-21)
|
||||
@@ -1180,6 +1415,26 @@ Other Changes:
|
||||
- Examples: Emscripten+WebGPU: Fix building for latest WebGPU specs. (#3632)
|
||||
- Examples: OSX+Metal, OSX+OpenGL: Removed now-unnecessary calls to ImGui_ImplOSX_HandleEvent(). (#4821)
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- Docking: Fixed floating docked nodes not being clamped into viewport workrect to stay reachable
|
||||
when io.ConfigWindowsMoveFromTitleBarOnly is true and multi-viewports are disabled. (#5044)
|
||||
- Docking: Fixed a regression where moving window would be interrupted after undocking a tab
|
||||
when io.ConfigDockingAlwaysTabBar is true. (#5324) [@rokups]
|
||||
- Docking: Fixed incorrect focus highlight on docking node when focusing empty central node
|
||||
or a child window which was manually injected into a dockspace window.
|
||||
- Docking, Modal: Fixed a crash when opening popup from a parent which is being docked on the same frame. (#5401)
|
||||
- Viewports: Fixed an issue where MouseViewport was lagging by a frame when using 1.87 Input Queue.
|
||||
A common side-effect would be that when releasing a window drag the underlying window would highlight
|
||||
for a frame. (#5837, #4921) [@cfillion]
|
||||
- Viewports: Fixed translating a host viewport from briefly altering the size of AlwaysAutoResize windows. (#5057)
|
||||
- Viewports: Fixed main viewport size not matching ImDrawData::DisplaySize for one frame during resize
|
||||
when multi-viewports are disabled. (#4900)
|
||||
- Backends: SDL: Fixed dragging out main viewport broken on some SDL setups. (#5012) [@rokups]
|
||||
- Backends: OSX: Added support for multi-viewports. [@stuartcarnie, @metarutaiga] (#4821, #2778)
|
||||
- Backends: Metal: Added support for multi-viewports. [@stuartcarnie, @metarutaiga] (#4821, #2778)
|
||||
- Examples: OSX+Metal, SDL+Metal, GLFW+Metal: Added support for multi-viewports. [@rokups]
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.87 (Released 2022-02-07)
|
||||
@@ -1322,6 +1577,29 @@ Other Changes:
|
||||
- Backends: WebGPU: Fixed incorrect size parameters in wgpuRenderPassEncoderSetIndexBuffer() and
|
||||
wgpuRenderPassEncoderSetVertexBuffer() calls. (#4891) [@FeepsDev]
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- Docking: Fixed a CTRL+TAB crash when aiming at an empty docked window. (#4792)
|
||||
- Docking: Tabs use their own identifier instead of the Window identifier.
|
||||
(This will invalidate some stored .ini data such as last selected tab, sorry!)
|
||||
- Docking: Fixed size constraints not working on single window holding on a dock id (still doesn't work on docked windows).
|
||||
- Docking: Fixed CTRL+TAB back into a docked window not selecting menu layer when no item are on main layer.
|
||||
- Viewports, IO: Added io.AddMouseViewportEvent() function to queue hovered viewport change (when known by backend).
|
||||
- Viewports: Relaxed specs for backend supporting ImGuiBackendFlags_HasMouseHoveredViewport: it is now _optional_
|
||||
for the backend to have to ignore viewports with the _NoInputs flag when call io.AddMouseViewportEvent(). It is
|
||||
much better if they can (Win32 and GLFW 3.3+ backends can, SDL and GLFW 3.2 backends cannot, they are lacking data).
|
||||
A concrete example is: when dragging a viewport for docking, the viewport is marked with _NoInputs to allow us
|
||||
to pick the target viewports for docking. If the backend reports a viewport with _NoInputs when calling the
|
||||
io.AddMouseViewportEvent() function, then Dear ImGui will revert to its flawed heuristic to find the viewport under.
|
||||
By lowering those specs, we allow the SDL and more backend to support this, only relying on the heuristic in a few
|
||||
drag and drop situations rather that relying on it everywhere.
|
||||
- Viewports: Fixed a CTRL+TAB crash with viewports enabled when the window list needs to appears in
|
||||
its own viewport (regression from 1.86). (#4023, #787)
|
||||
- Viewports: Fixed active InputText() from preventing viewports to merge. (#4212)
|
||||
- Backends: SDL: Added support for ImGuiBackendFlags_HasMouseHoveredViewport now that its specs have been lowered.
|
||||
- (Breaking) Removed ImGuiPlatformIO::Platform_SetImeInputPos() in favor of newly standardized
|
||||
io.SetPlatformImeDataFn() function. Should not affect more than default backends.
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.86 (Released 2021-12-22)
|
||||
@@ -1420,6 +1698,24 @@ Other Changes:
|
||||
wgpuRenderPassEncoderSetIndexBuffer() functions as validation layers appears to not do what the
|
||||
in-flux specs says. (#4766) [@meshula]
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- Docking: Revert removal of io.ConfigDockingWithShift config option (removed in 1.83). (#4643)
|
||||
- Docking: Fixed a bug undocking windows docked into a non-visible or _KeepAliveOnly dockspace
|
||||
when unrelated windows submitted before the dockspace have dynamic visibility. (#4757)
|
||||
- Docking, Style: Docked windows honor ImGuiCol_WindowBg. (#2700, #2539)
|
||||
- Docking, Style: Docked windows honor display their border properly. (#2522)
|
||||
- Docking: Fixed incorrectly rounded tab bars for dock node that are not at the top of their dock tree.
|
||||
- Docking: Fixed single-frame node pos/size inconsistencies when window stop or start being submitted.
|
||||
- Docking: Prevent docking any window created above a popup/modal. (#4317)
|
||||
- Viewports: Made it possible to explicitly assign ImGuiWindowClass::ParentViewportId to 0 in order
|
||||
to ensure a window is not parented. Previously this would use the global default (which might be 0,
|
||||
but not always as it would depend on io.ConfigViewportsNoDefaultParent). (#3152, #2871)
|
||||
- Viewports: Fixed tooltip in own viewport over modal from being incorrectly dimmed. (#4729)
|
||||
- Viewports: Fixed CTRL+TAB highlight outline on docked windows not always fitting in host viewport.
|
||||
- Backends: Made it possible to shutdown default Platform Backends before the Renderer backends. (#4656)
|
||||
- Disabled: Fixed nested BeginDisabled()/EndDisabled() bug in Docking branch due to bad merge. (#4655, #4452, #4453, #4462)
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.85 (Released 2021-10-12)
|
||||
@@ -1438,6 +1734,10 @@ Breaking Changes:
|
||||
Can use 'GetWindowContentRegionMax().x - GetWindowContentRegionMin().x' instead but it's not
|
||||
very useful in practice, and the only use of it in the demo was illfit.
|
||||
Using 'GetContentRegionAvail().x' is generally a better choice.
|
||||
- (Docking branch) IsWindowFocused() and IsWindowHovered() with only the _ChildWindows flag
|
||||
and without the _RootWindow flag used to leak docking hierarchy, so a docked window would
|
||||
return as the child of the window hosting the dockspace. This was inconsistent and incorrect
|
||||
with other behaviors so we fixed it. Added a new _DockHierarchy flag to opt-in this behavior.
|
||||
|
||||
Other Changes:
|
||||
|
||||
@@ -1511,6 +1811,29 @@ Other Changes:
|
||||
- Backends: All renderers: Normalize clipping rect handling across backends. (#4464)
|
||||
- Examples: Added SDL + SDL_Renderer example in "examples/example_sdl_sdlrenderer/" folder. (#3926) [@1bsyl]
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- IsWindowFocused: Fixed using ImGuiFocusedFlags_ChildWindows (without _RootWindow) from leaking the
|
||||
docking hierarchy. Added ImGuiFocusedFlags_DockHierarchy flag to consider docking hierarchy in the test.
|
||||
- IsWindowHovered: Fixed using ImGuiHoveredFlags_ChildWindows (without _RootWindow) from leaking the
|
||||
docking hierarchy. Added ImGuiHoveredFlags_DockHierarchy flag to consider docking hierarchy in the test.
|
||||
- Nav: Fixed an issue with losing focus on docked windows when pressing Alt while keyboard navigation
|
||||
is disabled. (#4547, #4439) [@PathogenDavid]
|
||||
- Docking: Fixed IsItemHovered() and functions depending on it (e.g. BeginPopupContextItem()) when
|
||||
called after Begin() on a docked window (broken 2021/03/04). (#3851)
|
||||
- Docking: Improved resizing system so that non-central zone are better at keeping their fixed size.
|
||||
The algorithm is still not handling the allocation of size ideally for nested sibling, but it got better.
|
||||
- Docking: Fixed settings load issue when mouse wheeling. (#4310)
|
||||
- Docking: Fixed manually created floating node with a central node from not hiding when windows are gone.
|
||||
- Docking + Drag and Drop: Fixed using BeginDragDropSource() or BeginDragDropTarget() inside a Begin()
|
||||
that returned false because the window is docked. (#4515)
|
||||
- Viewports: Fixed a crash while a window owning its viewport disappear while being dragged.
|
||||
It would manifest when e.g. reconfiguring dock nodes while dragging.
|
||||
- Viewports: Fixed unnecessary creation of temporary viewports when multiple docked windows
|
||||
got reassigned to a new node (created mid-frame) which already has a HostWindow.
|
||||
- Viewports: Fixed window with viewport ini data immediately merged into a host viewport from
|
||||
leaving a temporary viewport alive for a frame (would leak into backend).
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.84.2 (Released 2021-08-23)
|
||||
@@ -1647,6 +1970,25 @@ Other Changes:
|
||||
- Examples: Updated all .vcxproj to VS2015 (toolset v140) to facilitate usage with vcpkg.
|
||||
- Examples: SDL2: Accommodate for vcpkg install having headers in SDL2/SDL.h vs SDL.h.
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- Docking: Clicking on the right-most close button of a docking node closes all windows. (#4186)
|
||||
- Docking: Fix IsWindowAppearing() and ImGuiCond_Appearing on docked windows. (#4177, #3982, #1497, #1061)
|
||||
- Docking: Fix crash using DockBuilderRemoveNode() in some situations. (#3111, #3179, #3203, #4295) [@hsimyu]
|
||||
- Docking: Fix crash when a dock node gets re-qualified as dockspace>floating>dockspace, which tends to happen
|
||||
when incorrectly calling DockBuilderAddNode() without ImGuiDockNodeFlags_Dockspace and using it as a Dockspace
|
||||
on the next frame after the floating window hosting the node has been automatically created. (#3203, #4295)
|
||||
- Docking: Reworked node flags saving/inheritance so that flags enforced by docked windows via the
|
||||
DockNodeFlagsOverrideSet mechanism are are not left in empty dockspace nodes once the windows gets undocked.
|
||||
(#4292, #3834, #3633, #3521, #3492, #3335, #2999, #2648)
|
||||
- Docking: (Internal/Experimental) Removed DockNodeFlagsOverrideClear flags from ImGuiWindowClass as
|
||||
it is ambiguous how to apply them and we haven't got a use out of them yet.
|
||||
- Docking: Fixed ImGuiWindowFlags_UnsavedDocument clipping label in docked windows when there are
|
||||
no close button. (#5745)
|
||||
- Viewports: Fix popup/tooltip created without a parent window from being given a ParentViewportId value
|
||||
from the implicit/fallback window. (#4236, #2409)
|
||||
- Backends: Vulkan: Fix the use of the incorrect fence for secondary viewports. (#4208) [@FunMiles]
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.83 (Released 2021-05-24)
|
||||
@@ -1731,6 +2073,22 @@ Other Changes:
|
||||
- Docs: Improvements to description of using colored glyphs/emojis. (#4169, #3369)
|
||||
- Docs: Improvements to minor mistakes in documentation comments (#3923) [@ANF-Studios]
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- [Breaking] Removed io.ConfigDockingWithShift config option. Behavior always equivalent to having the
|
||||
option set to false (dock/undock by default, hold shift to avoid docking). (#2109)
|
||||
- Docking: DockSpace() returns its node ID.
|
||||
- Docking: Dockspace() never draws a background. (#3924)
|
||||
- Docking: Undocking nodes/windows covering most of the monitor max their size down to 90% to ease manipulations.
|
||||
- Docking: Docking node tab bar honors ItemInnerSpacing.x before first tab. (#4130)
|
||||
- Docking: Tweak rendering and alignment of dock node menu marker. (#4130)
|
||||
- Docking: Fixed restoring of tab order within a dockspace or a split node.
|
||||
- Docking: Fixed reappearing docked windows with no close button showing a tab with extraneous space for one frame.
|
||||
- Docking: Fixed multiple simultaneously reappearing window from appearing undocked for one frame.
|
||||
- Viewports: Hotfix for crash in monitor array access, caused by 4b9bc4902. (#3967)
|
||||
- Backends, Viewports: GLFW: Add a workaround for stuck keys after closing a GLFW window (#3837).
|
||||
- Backends, Viewports: Vulkan: Rebuild swapchain on VK_SUBOPTIMAL_KHR. (#3881)
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.82 (Released 2021-02-15)
|
||||
@@ -1826,6 +2184,13 @@ Other Changes:
|
||||
scheduled builds builds are not required. [@rokups]
|
||||
- Log/Capture: Added LogTextV, a va_list variant of LogText. [@PathogenDavid]
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- Viewports: Fix setting of ImGuiViewportFlags_NoRendererClear. (#3213)
|
||||
- Viewports: Added GetViewportPlatformMonitor() with a safety net to keep code portable.
|
||||
- Viewports, Backends: SDL: Fix missing ImGuiBackendFlags_HasSetMousePos flag in docking branch.
|
||||
- Viewports, Backends: GLFW: Fix application of WantSetMousePos. (#1542, #787)
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.81 (Released 2021-02-10)
|
||||
@@ -1907,6 +2272,17 @@ Other Changes:
|
||||
- Examples: WebGPU: Added Emscripten+WebGPU example. (#3632) [@bfierz]
|
||||
- Backends: GLFW: Added ImGui_ImplGlfw_InitForOther() initialization call to use with non OpenGL API. (#3632)
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- Docking: Fix losing docking information on closed windows for which the hosting node was split. (#3716) [@GamingMinds-DanielC]
|
||||
- Docking: Fix gap in hit test hole when using ImGuiDockNodeFlags_PassthruCentralNode touching the edge of a viewport. (#3733)
|
||||
- Viewports: (Breaking) removed ImGuiPlatformIO::MainViewport which is now pretty much unused and duplicate
|
||||
(and misleading as we will evolve the concept).
|
||||
- Viewports: (Breaking) turned ImGuiViewport::GetWorkPos(), ImGuiViewport::GetWorkSize() into regular fields
|
||||
(WorkPos, WorkSize) before exposing in master branch.
|
||||
- Viewports: Fix issue inferring viewport z-order when new popups gets created. (#3734) + Metrics updates.
|
||||
- Viewports, Backends: Vulkan: handle VK_ERROR_OUT_OF_DATE_KHR when resizing secondary viewport (#3766, #3758)
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.80 (Released 2021-01-21)
|
||||
@@ -2026,6 +2402,14 @@ Other Changes:
|
||||
- Docs: Split examples/README.txt into docs/BACKENDS.md and docs/EXAMPLES.md, and improved them.
|
||||
- Docs: Consistently renamed all occurrences of "binding" and "back-end" to "backend" in comments and docs.
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- Docking: Docked windows honor change of tab and text colors. (#2771)
|
||||
- Docking: Support for appending into existing tab-bar made to work with Docking + internal helper DockNodeBeginAmendTabBar().
|
||||
- Docking: Added experimental TabItemFlagsOverrideSet to ImGuiWindowClass.
|
||||
- Viewports: Fixed incorrect whitening of popups above a modal if both use their own viewport.
|
||||
- Viewports: Backends: Vulkan: Fixed build, removed extraneous pipeline creation. (#3459, #3579)
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.79 (Released 2020-10-08)
|
||||
@@ -2120,6 +2504,21 @@ Other Changes:
|
||||
- Examples: DX12: Added '#define ImTextureID ImU64' in project and build files to also allow building
|
||||
on 32-bit systems. Added project to default Visual Studio solution file. (#301)
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- Docking: DockSpace() emits ItemSize() properly (useful when not filling all space).
|
||||
- Docking: Fixed docking while hovering a child window. (#3420) broken by 85a661d. Improve metrics debugging.
|
||||
- Docking: Fix honoring payload filter with overlapping nodes (we incorrectly over-relied on g.HoveredDockNode
|
||||
when making change for #3398).
|
||||
- Docking: Fix handling of WindowMenuButtonPosition == ImGuiDir_None in Docking Nodes. (#3499)
|
||||
- Viewports: Fixed a rare edge-case if the window targeted by CTRL+Tab stops being rendered.
|
||||
- Viewports, Backends: DX12: Make secondary viewport format match main viewport one (#3462) {@BeastLe9enD]
|
||||
- Viewports: Backends: Vulkan: Removed unused shader code. Fix leaks. Avoid unnecessary pipeline creation for main
|
||||
viewport. (#3459) + Add ImGui_ImplVulkanH_CreateWindowSwapChain in ImGui_ImplVulkanH_CreateOrResizeWindow().
|
||||
- Viewports: Backends: DirectX9: Recover from D3DERR_DEVICELOST on secondary viewports. (#3424)
|
||||
- Viewports, Backends: Win32: Fix toggling of ImGuiViewportFlags_TopMost (#3477) [@Kodokuna]
|
||||
- Viewports: Backends: GLFW: Workaround for cases where glfwGetMonitorWorkarea fails (#3457) [@dougbinks]
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.78 (Released 2020-08-18)
|
||||
@@ -2221,6 +2620,23 @@ Other Changes:
|
||||
- Examples: Vulkan: Fixed GLFW+Vulkan and SDL+Vulkan clear color not being set. (#3390) [@RoryO]
|
||||
- CI: Emscripten has stopped their support for their fastcomp backend, switching to latest sdk [@Xipiryon]
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- Docking: Made DockBuilderAddNode() automatically call DockBuilderRemoveNode(). (#3399, #2109)
|
||||
- Docking: Storing HoveredDockNode in context which can be useful for easily detecting e.g. hovering an
|
||||
empty node. (#3398)
|
||||
- Docking: Fixed docking overlay bits appearing at (0,0), because of 43bd80a. Most typically noticeable
|
||||
when disabling multi-viewport.
|
||||
- Docking: Workaround recovery for node created without the _DockSpace flags later becoming a DockSpace. (#3340)
|
||||
- Docking: Rework size allocations to recover when there's no enough room for nodes + do not hold on
|
||||
_WantLockSizeOnce forever. (#3328)
|
||||
- Docking: Rework size allocation to allow user code to override node sizes. Not all edge cases will be
|
||||
properly handled but this is a step toward toolbar emitting size constraints.
|
||||
- Docking: Added experimental flags to perform more docking filtering and disable resize per axis.
|
||||
Designed for toolbar patterns.
|
||||
- Viewports, Backends, GLFW: Use GLFW_MOUSE_PASSTHROUGH when available.
|
||||
- Viewports, Backends: DX12: Fixed issue on shutdown when viewports are disabled. (#3347)
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.77 (Released 2020-06-29)
|
||||
@@ -2312,6 +2728,17 @@ Other Changes:
|
||||
- Examples: Apple: Fixed example_apple_metal and example_apple_opengl2 using imgui_impl_osx.mm
|
||||
not forwarding right and center mouse clicks. (#3260) [@nburrus]
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- Viewports: Don't set ImGuiViewportFlags_NoRendererClear when ImGuiWindowFlags_NoBackground is set. (#3213)
|
||||
- Viewports: Report minimized viewports as zero DisplaySize to be consistent with main branch. (#1542)
|
||||
- Docking, Settings: Allow reload of settings data at runtime. (#2573)
|
||||
- Backends, GLFW: Fix windows resizing incorrectly on Linux due to GLFW firing window positioning
|
||||
callbacks on next frame after window is resized manually. (#2117)
|
||||
- Backends: DX12: Fix OBJECT_DELETED_WHILE_STILL_IN_USE on viewport resizing. (#3210)
|
||||
- Backends: DX12: Fix for crash caused by early resource release. (#3121)
|
||||
- Backends, Win32: Request monitor update when DPI awareness is enabled to make sure they have the correct DPI settings.
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.76 (Released 2020-04-12)
|
||||
@@ -2384,6 +2811,20 @@ Other Changes:
|
||||
- Examples: SDL+DX11: Fixed resizing main window. (#3057) [@joeslay]
|
||||
- Examples: Added SDL+Metal example application. (#3017) [@coding-jackalope]
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- Docking: Fixed assert preventing dockspace from being created instead a hidden tab. (#3101)
|
||||
- Viewports: Fixed secondary viewports accidentally merging into a minimized host viewport. (#3118)
|
||||
- Viewports, Docking: Added per-viewport work area system for e.g. menu-bars. Fixed DockspaceOverViewport()
|
||||
and demo code (overlay etc) accordingly. (#3035, #2889, #2474, #1542, #2109)
|
||||
- Viewports: Improve menu positioning in multi-monitor setups. [@rokups]
|
||||
- Viewports: Software mouse cursor is also scaled by current DpiScale. (amend #939)
|
||||
- Viewports: Avoid manually clipping resize grips and borders, which messes up with automation ability
|
||||
to locate those items. Also simpler and more standard.
|
||||
- Viewports: Fix for UWP in the imgui_impl_win32.cpp IME handler. (#2895, #2892).
|
||||
- Viewports: Bunch of extra of comments to facilitate setting up multi-viewports.
|
||||
- Viewports, GLFW: Avoid using window positioning workaround for GLFW 3.3+ versions that have it fixed.
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.75 (Released 2020-02-10)
|
||||
@@ -2482,6 +2923,21 @@ Other Changes:
|
||||
- Examples: Metal: Wrapped main loop in @autoreleasepool block to ensure allocations get freed
|
||||
even if underlying system event loop gets paused due to app nap. (#2910, #2917) [@bear24rw]
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- Docking + Nav: Fixed messed up Ctrl+Tab order with docked windows.
|
||||
- Docking + Nav: Fixed failing to restore NavId when refocusing a child within a docked window.
|
||||
- Docking + Nav: Fixed failing to restore NavId when refocusing due to missing nav window (when
|
||||
it stops being submitted).
|
||||
- Docking: Fixed a bug where the tab bar of a hidden dockspace would keep requesting focus. (#2960)
|
||||
- Docking: Added experimental DockNodeFlagsOverrideSet/DockNodeFlagsOverrideClear flags in ImGuiWindowClass
|
||||
(currently experimenting with toolbar idioms).
|
||||
- Viewports: Fix resizing viewport-owning windows when mouse pos is outside the InnerClipRect
|
||||
(can happen with OS decoration enabled).
|
||||
- Viewports: Preserve last known size for minimized main viewport to be consistent with secondary viewports.
|
||||
- Backends: SDL: Honor NoTaskBarIcon flag under non Win32 OS. (#2117)
|
||||
- Backends: GLFW, SDL: Platform monitors declared properly even if multi-viewport is not enabled.
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.74 (Released 2019-11-25)
|
||||
@@ -2561,6 +3017,14 @@ Other Changes:
|
||||
- CI: Set up a bunch of continuous-integration tests using GitHub Actions. We now compile many of the example
|
||||
applications on Windows, Linux, MacOS, iOS, Emscripten. Removed Travis integration. (#2865) [@rokups]
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- Docking: Can undock from the small triangle button. (#2109,. #2645)
|
||||
- Docking: Fixed node->HasCloseButton not honoring ImGuiDockNodeFlags_NoCloseButton in a floating node,
|
||||
leading to empty space at the right of tab-bars with those flags. (#2109)
|
||||
- Docking: Made docked windows not use style.ChildRounding.
|
||||
- Multi-viewports: Added multi-viewport support in the DX12 back-end. (#2851) [@obfuscate]
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.73 (Released 2019-09-24)
|
||||
@@ -2623,6 +3087,28 @@ Other Changes:
|
||||
- Misc: Updated stb_rect_pack.h from 0.99 to 1.00 (fixes by @rygorous: off-by-1 bug in best-fit heuristic,
|
||||
fix handling of rectangles too large to fit inside texture). (#2762) [@tido64]
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- Docking: Fix BeginDocked() path that creates node so that SetNextWindowDockID() doesn't immediately discard the node. (#2109)
|
||||
- Docking: Fix for node created at the same time as windows that are still resizing (typically with
|
||||
io.ConfigDockingAlwaysTabBar) to not be zero/min sized. (#2109). The fix delays their visibility by one frame,
|
||||
which is not ideal but not very problematic as the .ini data gets populated after that.
|
||||
- Docking: Fix a crash that could occur with a malformed ini file (DockNode Parent value pointing to a missing node).
|
||||
- Viewport: Fix modal/popup window being stuck in unowned hidden viewport associated to fallback window without stealing
|
||||
it back. Fix modal reference viewport when opened outside of another window. (#1542)
|
||||
- Viewport: Modals don't need to set ImGuiViewportFlags_NoFocusOnClick, this also mitigate the issue described by #2445,
|
||||
which becomes particularly bad with unfocused modal. (#1542)
|
||||
- Viewport: better case case where host window gets moved and resized simultaneous (toggling maximized state).
|
||||
There's no perfect solution there, than using io.ConfigViewportsNoAutoMerge = false. (#1542)
|
||||
- Viewport, Docking: Fixed incorrect assignment of IsFallbackWindow which would tag dock node host windows created
|
||||
in NewFrame() as such, messing with popup viewport inheritance.
|
||||
- Viewport: Fixed issue where resize grip would display as hovered while mouse is still off the OS bounds so a click
|
||||
would miss it and focus the OS window behind expected one. (#1542)
|
||||
- Viewport: Fix to allow multiple shutdown / calls to DestroyPlatformWindows(). (#2769)
|
||||
- Viewport: Backends: GLFW: Fix setting window size on macOS (#2767, #2117) [@rokups]
|
||||
- Viewport: Backends: GLFW+Linux: Fix window having incorrect size after uncollapse. (#2756, #2117) [@rokups]
|
||||
- Viewport: Backends: DirectX9: Workaround for windows not refreshing when main viewport has no draw call. (#2560)
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.72b (Released 2019-07-31)
|
||||
@@ -2725,6 +3211,25 @@ Other Changes:
|
||||
(#2482, #2632) [@josiahmanson]
|
||||
- Examples: Added SDL2+DirectX11 example application. (#2632, #2612, #2482) [@vincenthamm]
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- Docking: Making it possible to undock a node by clicking on the tab bar / title bar for the node. (#2645).
|
||||
- Docking: Explicitly inhibit constraint when docked for now. Fix clipping issue related to constraints. (#2690).
|
||||
- Docking: Fixed dragging/resizing from OS decoration not marking settings as dirty.
|
||||
- Docking: Renamed io.ConfigDockingTabBarOnSingleWindows to io.ConfigDockingAlwaysTabBar.
|
||||
Added ImGuiWindowClass::DockingAlwaysTabBar to set on individual windows.
|
||||
- Docking: Perform simple check: assert if Docking or Viewport are enabled exactly on frame 1 (instead of frame 0
|
||||
or later), which is a common user error leading to loss of .ini data on load.
|
||||
- Docking: Fix so that an appearing window making a dock node reappear won't have a zero-size on its first frame.
|
||||
- Docking: Fixed using ImGuiDockNodeFlags_AutoHideTabBar with io.ConfigDockingTabBarOnSingleWindows.
|
||||
- Docking: Added ImGuiDockNode to .natvis file.
|
||||
- Docking: Fixed support for large meshes in GetBackgroundDrawList(), GetForegroundDrawList(). (#2638)
|
||||
- Viewport: Fix monitor dpi info not being copied to main viewport when multi-viewports are not enabled. (#2621, #1676)
|
||||
- Viewport: Refactored ImGuiWindowClass's ViewportFlagsOverrideMask + ViewportFlagsOverrideValue into
|
||||
ViewportFlagsOverrideSet + ViewportFlagsOverrideClear which appears easier to grasp. (#1542)
|
||||
- Viewport: Added ImGuiViewportFlags_NoAutoMerge to prevent merging into host viewport in a per-window basis
|
||||
via the ImGuiWindowClass override mechanism. (#1542)
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.71 (Released 2019-06-12)
|
||||
@@ -3064,6 +3569,7 @@ Breaking Changes:
|
||||
- Renamed ImFontAtlas::GlyphRangesBuilder to ImFontGlyphRangesBuilder. Kept redirection typedef (will obsolete).
|
||||
|
||||
Other Changes:
|
||||
|
||||
- Added BETA api for Tab Bar/Tabs widgets: (#261, #351)
|
||||
- Added BeginTabBar(), EndTabBar(), BeginTabItem(), EndTabItem(), SetTabItemClosed() API.
|
||||
- Added ImGuiTabBarFlags flags for BeginTabBar().
|
||||
@@ -3427,6 +3933,8 @@ Decorated log and release notes: https://github.com/ocornut/imgui/releases/tag/v
|
||||
|
||||
Breaking Changes:
|
||||
|
||||
- Tabs: Added ImGuiTabItemFlags_NoAssumedClosure to enable app to react on closure attempt, without having to draw
|
||||
an unsaved document marker (ImGuiTabItemFlags_UnsavedDocument sets _NoAssumedClosure automatically). (#7084)
|
||||
- DragInt(): The default compile-time format string has been changed from "%.0f" to "%d", as we are not using integers internally
|
||||
any more. If you used DragInt() with custom format strings, make sure you change them to use %d or an integer-compatible format.
|
||||
To honor backward-compatibility, the DragInt() code will currently parse and modify format strings to replace %*f with %d,
|
||||
|
||||
@@ -426,7 +426,7 @@ Finally, you may call `ImGui::ShowMetricsWindow()` to explore/visualize/understa
|
||||
|
||||
### Q: How can I use maths operators with ImVec2?
|
||||
|
||||
We do not export maths operators by default in imgui.h in order to not conflict with the use of your own maths types and maths operators. As a convenience, you may use `#defne IMGUI_DEFINE_MATH_OPERATORS` + `#include "imgui.h"` to access our basic maths operators.
|
||||
We do not export maths operators by default in imgui.h in order to not conflict with the use of your own maths types and maths operators. As a convenience, you may use `#define IMGUI_DEFINE_MATH_OPERATORS` + `#include "imgui.h"` to access our basic maths operators.
|
||||
|
||||
##### [Return to Index](#index)
|
||||
|
||||
|
||||
@@ -404,16 +404,12 @@ ImGui::Text(u8"こんにちは"); // this will always be encoded as UTF-8
|
||||
ImGui::Text("こんにちは"); // the encoding of this is depending on compiler settings/flags and may be incorrect.
|
||||
```
|
||||
|
||||
Since C++20, because the C++ committee hate its users, they decided to change the `u8""` syntax to not return `const char*` but a new type `const char_t*` which doesn't cast to `const char*`.
|
||||
Since C++20, because the C++ committee hate its users, they decided to change the `u8""` syntax to not return `const char*` but a new type `const char8_t*` which doesn't cast to `const char*`.
|
||||
Because of type usage of `u8""` in C++20 is a little more tedious:
|
||||
```cpp
|
||||
ImGui::Text((const char*)u8"こんにちは");
|
||||
```
|
||||
We suggest using a macro in your codebase:
|
||||
```cpp
|
||||
#define U8(_S) (const char*)u8##_S
|
||||
ImGui::Text(U8("こんにちは"));
|
||||
```
|
||||
However, you can disable this behavior completely using the compiler option [`/Zc:char8_t-`](https://learn.microsoft.com/en-us/cpp/build/reference/zc-char8-t?view=msvc-170) for MSVC and [`-fno-char8_t`](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1423r3.html) for Clang and GCC.
|
||||
##### [Return to Index](#index)
|
||||
|
||||
---------------------------------------
|
||||
@@ -486,7 +482,7 @@ Some fonts files are available in the `misc/fonts/` folder:
|
||||
#### MONOSPACE FONTS
|
||||
|
||||
Pixel Perfect:
|
||||
- Proggy Fonts, by Tristan Grimmer http://www.proggyfonts.net or http://upperbounds.net
|
||||
- Proggy Fonts, by Tristan Grimmer http://www.proggyfonts.net or http://upperboundsinteractive.com/fonts.php
|
||||
- Sweet16, Sweet16 Mono, by Martin Sedlak (Latin + Supplemental + Extended A) https://github.com/kmar/Sweet16Font (also include an .inl file to use directly in dear imgui.)
|
||||
|
||||
Regular:
|
||||
|
||||
@@ -110,7 +110,7 @@ Reading the changelogs is a good way to keep up to date with the things Dear ImG
|
||||
Calling the `ImGui::ShowDemoWindow()` function will create a demo window showcasing a variety of features and examples. The code is always available for reference in `imgui_demo.cpp`. [Here's how the demo looks](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v167/v167-misc.png).
|
||||
|
||||
You should be able to build the examples from sources. If you don't, let us know! If you want to have a quick look at some Dear ImGui features, you can download Windows binaries of the demo app here:
|
||||
- [imgui-demo-binaries-20230704.zip](https://www.dearimgui.com/binaries/imgui-demo-binaries-20230704.zip) (Windows, 1.89.7, built 2023/07/04, master) or [older binaries](https://www.dearimgui.com/binaries).
|
||||
- [imgui-demo-binaries-20240105.zip](https://www.dearimgui.com/binaries/imgui-demo-binaries-20240105.zip) (Windows, 1.90.1 WIP, built 2024/01/05, master) or [older binaries](https://www.dearimgui.com/binaries).
|
||||
|
||||
The demo applications are not DPI aware so expect some blurriness on a 4K screen. For DPI awareness in your application, you can load/reload your font at a different scale and scale your style with `style.ScaleAllSizes()` (see [FAQ](https://www.dearimgui.com/faq)).
|
||||
|
||||
@@ -207,7 +207,7 @@ Sponsoring, maintenance/support contracts and other B2B transactions are hosted
|
||||
|
||||
Omar: "I first discovered the IMGUI paradigm at [Q-Games](https://www.q-games.com) where Atman Binstock had dropped his own simple implementation in the codebase, which I spent quite some time improving and thinking about. It turned out that Atman was exposed to the concept directly by working with Casey. When I moved to Media Molecule I rewrote a new library trying to overcome the flaws and limitations of the first one I've worked with. It became this library and since then I have spent an unreasonable amount of time iterating and improving it."
|
||||
|
||||
Embeds [ProggyClean.ttf](http://upperbounds.net) font by Tristan Grimmer (MIT license).
|
||||
Embeds [ProggyClean.ttf](https://www.proggyfonts.net) font by Tristan Grimmer (MIT license).
|
||||
<br>Embeds [stb_textedit.h, stb_truetype.h, stb_rect_pack.h](https://github.com/nothings/stb/) by Sean Barrett (public domain).
|
||||
|
||||
Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. Also thank you to everyone posting feedback, questions and patches on GitHub.
|
||||
|
||||
@@ -129,7 +129,35 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
||||
- separator: width, thickness, centering (#1643, #2657)
|
||||
- splitter: formalize the splitter idiom into an official api (we want to handle n-way split) (#319)
|
||||
|
||||
- docking: merge docking branch (#2109)
|
||||
- docking: B: ordering currently held in tab bar should be implicitly held by windows themselves (also see #2304)
|
||||
- docking: B- tab bar: the order/focus restoring code could be part of TabBar and not DockNode? (#8)
|
||||
- docking: B~ rework code to be able to lazily create tab bar instance in a single place. The _Unsorted tab flag could be replacing a trailing-counter in DockNode?
|
||||
- docking: B~ fully track windows/settings reference in dock nodes. perhaps find a representation that allows facilitate use of dock builder functions.
|
||||
- docking: B~ Unreal style document system (requires low-level controls of dockspace serialization fork/copy/delete). this is mostly working but the DockBuilderXXX api are not exposed/finished.
|
||||
- docking: B: when docking outer, perform size locking on neighbors nodes the same way we do it with splitters, so other nodes are not resized.
|
||||
- docking: B~ central node resizing behavior incorrect.
|
||||
- docking: B: changing title font/style per-window is not supported as dock nodes are created in NewFrame.
|
||||
- docking: B- dock node inside its own viewports creates 1 temporary viewport per window on startup before ditching them (doesn't affect the user nor request platform windows to be created, but unnecessary)
|
||||
- docking: B- resize sibling locking behavior may be less desirable if we merged same-axis sibling in a same node level?
|
||||
- docking: B- single visible node part of a hidden split hierarchy (OnlyNodeWithWindows != NULL) should show a normal title bar (not a tab bar)
|
||||
- docking: B~ SetNextWindowDock() calls (with conditional) -> defer everything to DockContextUpdate (repro: Documents->[X]Windows->Dock 1 elsewhere->Click Redock All
|
||||
- docking: B~ tidy up tab list popup buttons features (available with manual tab-bar, see ImGuiTabBarFlags_NoTabListPopupButton code, not used by docking nodes)
|
||||
- docking: B- SetNextWindowDockId(0) with a second Begin() in the frame will asserts
|
||||
- docking: B: resize grip drawn in host window typically appears under scrollbar.
|
||||
- docking: B: resize grip auto-resize on multiple node hierarchy doesn't make much sense or should be improved?
|
||||
- docking: B- SetNextWindowFocus() doesn't seem to apply if the window is hidden this frame, need repro (#4)
|
||||
- docking: B- resizing a dock tree small currently has glitches (overlapping collapse and close button, etc.)
|
||||
- docking: B- dpi: look at interaction with the hi-dpi and multi-dpi stuff.
|
||||
- docking: B- tab bar: appearing on first frame with a dumb layout would do less harm that not appearing? (when behind dynamic branch) or store titles + render in EndTabBar()
|
||||
- docking: B- tab bar: make selected tab always shows its full title?
|
||||
- docking: B- hide close button on single tab bar?
|
||||
- docking: B- nav: design interactions so nav controls can dock/undock
|
||||
- docking: B- dockspace: flag to lock the dock tree and/or sizes (ImGuiDockNodeFlags_Locked?)
|
||||
- docking: B- reintroduce collapsing a floating dock node. also collapsing a docked dock node!
|
||||
- docking: B- allow dragging a non-floating dock node by clicking on the title-bar-looking section (not just the collapse/menu button)
|
||||
- docking: B- option to remember undocked window size? (instead of keeping their docked size) (relate to #2104)
|
||||
- docking: C- nav: CTRL+TAB highlighting tabs shows the mismatch between focus-stack and tab-order (not visible in VS because it doesn't highlight the tabs)
|
||||
- docking: C- after a dock/undock, the Scrollbar Status update in Begin() should use an updated e.g. size_y_for_scrollbars to avoid a 1 frame scrollbar flicker.
|
||||
|
||||
- tabs: "there is currently a problem because TabItem() will try to submit their own tooltip after 0.50 second, and this will have the effect of making your tooltip flicker once." -> tooltip priority work (WIP branch)
|
||||
- tabs: make EndTabBar fail if users doesn't respect BeginTabBar return value, for consistency/future-proofing.
|
||||
@@ -303,6 +331,20 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
||||
- nav/windowing: Resizing window will currently fail with certain types of resizing constraints/callback applied
|
||||
- focus: preserve ActiveId/focus stack state, e.g. when opening a menu and close it, previously selected InputText() focus gets restored (#622)
|
||||
|
||||
- viewport: make it possible to have no main/hosting viewport
|
||||
- viewport: We set ImGuiViewportFlags_NoFocusOnAppearing in a way that is required for GLFW/SDL binding, but could be handled better without
|
||||
on a custom e.g. Win32 bindings. It prevents newly dragged-out viewports from taking the focus, which makes ALT+F4 more ambiguous.
|
||||
- viewport: not focusing newly undocked viewport means clicking back on previous one doesn't bring OS window to front.
|
||||
- viewport: with platform decoration enabled, platform may force constraint (e.g. minimum size)
|
||||
- viewport: use getfocus/setfocus api to synchronize imgui<>platform focus better (e.g imgui-side ctrl-tab can focus os window, OS initial setup and alt-tab can focus imgui window etc.)
|
||||
- viewport: store per-viewport/monitor DPI in .ini file so an application reload or main window changing DPI on reload can be properly patched for.
|
||||
- viewport: implicit/fallback Debug window can hog a zombie viewport (harmless, noisy?) > could at least clear out the reference on a per session basis?
|
||||
- viewport: need to clarify how to use GetMousePos() from a user point of view.
|
||||
- platform: glfw: no support for ImGuiBackendFlags_HasMouseHoveredViewport.
|
||||
- platform: sdl: no support for ImGuiBackendFlags_HasMouseHoveredViewport. maybe we could use SDL_GetMouseFocus() / SDL_WINDOW_MOUSE_FOCUS if imgui could fallback on its heuristic when NoInputs is set
|
||||
- platform: sdl: no refresh of monitor/display (SDL doesn't seem to have an event for it).
|
||||
- platform: sdl: multi-viewport + minimized window seems to break mouse wheel events (at least under Win32).
|
||||
|
||||
- inputs: support track pad style scrolling & slider edit.
|
||||
- inputs/io: backspace and arrows in the context of a text input could use system repeat rate.
|
||||
- inputs/io: clarify/standardize/expose repeat rate and repeat delays (#1808)
|
||||
|
||||
@@ -40,6 +40,7 @@ int main(int, char**)
|
||||
ImGui::CreateContext();
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
|
||||
|
||||
// Setup Dear ImGui style
|
||||
ImGui::StyleColorsDark();
|
||||
|
||||
@@ -7,7 +7,10 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
050450AB2768052600AB6805 /* imgui_tables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5079822D257677DB0038A28D /* imgui_tables.cpp */; };
|
||||
050450AD276863B000AB6805 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 050450AC276863B000AB6805 /* QuartzCore.framework */; };
|
||||
05318E0F274C397200A8DE2E /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 05318E0E274C397200A8DE2E /* GameController.framework */; };
|
||||
05A275442773BEA20084EF39 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 05A275432773BEA20084EF39 /* QuartzCore.framework */; };
|
||||
07A82ED82139413D0078D120 /* imgui_widgets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07A82ED72139413C0078D120 /* imgui_widgets.cpp */; };
|
||||
07A82ED92139418F0078D120 /* imgui_widgets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07A82ED72139413C0078D120 /* imgui_widgets.cpp */; };
|
||||
5079822E257677DB0038A28D /* imgui_tables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5079822D257677DB0038A28D /* imgui_tables.cpp */; };
|
||||
@@ -33,7 +36,11 @@
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
050450AC276863B000AB6805 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
|
||||
05318E0E274C397200A8DE2E /* GameController.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameController.framework; path = System/Library/Frameworks/GameController.framework; sourceTree = SDKROOT; };
|
||||
05A2754027728F5B0084EF39 /* imgui_impl_metal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui_impl_metal.h; path = ../../backends/imgui_impl_metal.h; sourceTree = "<group>"; };
|
||||
05A2754127728F5B0084EF39 /* imgui_impl_osx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui_impl_osx.h; path = ../../backends/imgui_impl_osx.h; sourceTree = "<group>"; };
|
||||
05A275432773BEA20084EF39 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS15.2.sdk/System/Library/Frameworks/QuartzCore.framework; sourceTree = DEVELOPER_DIR; };
|
||||
07A82ED62139413C0078D120 /* imgui_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui_internal.h; path = ../../imgui_internal.h; sourceTree = "<group>"; };
|
||||
07A82ED72139413C0078D120 /* imgui_widgets.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_widgets.cpp; path = ../../imgui_widgets.cpp; sourceTree = "<group>"; };
|
||||
5079822D257677DB0038A28D /* imgui_tables.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_tables.cpp; path = ../../imgui_tables.cpp; sourceTree = "<group>"; };
|
||||
@@ -66,6 +73,7 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
05A275442773BEA20084EF39 /* QuartzCore.framework in Frameworks */,
|
||||
8309BD8F253CCAAA0045E2A1 /* UIKit.framework in Frameworks */,
|
||||
83BBE9E720EB46BD00295997 /* MetalKit.framework in Frameworks */,
|
||||
83BBE9E520EB46B900295997 /* Metal.framework in Frameworks */,
|
||||
@@ -76,6 +84,7 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
050450AD276863B000AB6805 /* QuartzCore.framework in Frameworks */,
|
||||
8309BDC6253CCCFE0045E2A1 /* AppKit.framework in Frameworks */,
|
||||
83BBE9EC20EB471700295997 /* MetalKit.framework in Frameworks */,
|
||||
05318E0F274C397200A8DE2E /* GameController.framework in Frameworks */,
|
||||
@@ -136,6 +145,8 @@
|
||||
83BBE9E320EB46B800295997 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
050450AC276863B000AB6805 /* QuartzCore.framework */,
|
||||
05A275432773BEA20084EF39 /* QuartzCore.framework */,
|
||||
05318E0E274C397200A8DE2E /* GameController.framework */,
|
||||
8309BDC5253CCCFE0045E2A1 /* AppKit.framework */,
|
||||
8309BD8E253CCAAA0045E2A1 /* UIKit.framework */,
|
||||
@@ -153,7 +164,9 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
5079822D257677DB0038A28D /* imgui_tables.cpp */,
|
||||
05A2754027728F5B0084EF39 /* imgui_impl_metal.h */,
|
||||
8309BDB5253CCC9D0045E2A1 /* imgui_impl_metal.mm */,
|
||||
05A2754127728F5B0084EF39 /* imgui_impl_osx.h */,
|
||||
8309BDB6253CCC9D0045E2A1 /* imgui_impl_osx.mm */,
|
||||
83BBEA0420EB54E700295997 /* imconfig.h */,
|
||||
83BBEA0320EB54E700295997 /* imgui.cpp */,
|
||||
@@ -268,9 +281,9 @@
|
||||
8309BDBB253CCCAD0045E2A1 /* imgui_impl_metal.mm in Sources */,
|
||||
83BBEA0920EB54E700295997 /* imgui.cpp in Sources */,
|
||||
83BBEA0720EB54E700295997 /* imgui_demo.cpp in Sources */,
|
||||
83BBEA0520EB54E700295997 /* imgui_draw.cpp in Sources */,
|
||||
83BBEA0520EB54E700295997 /* imgui_draw.cpp in Sources */,
|
||||
5079822E257677DB0038A28D /* imgui_tables.cpp in Sources */,
|
||||
07A82ED82139413D0078D120 /* imgui_widgets.cpp in Sources */,
|
||||
07A82ED82139413D0078D120 /* imgui_widgets.cpp in Sources */,
|
||||
8309BDA5253CCC070045E2A1 /* main.mm in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@@ -281,10 +294,10 @@
|
||||
files = (
|
||||
8309BDBE253CCCB60045E2A1 /* imgui_impl_metal.mm in Sources */,
|
||||
8309BDBF253CCCB60045E2A1 /* imgui_impl_osx.mm in Sources */,
|
||||
83BBEA0A20EB54E700295997 /* imgui.cpp in Sources */,
|
||||
83BBEA0820EB54E700295997 /* imgui_demo.cpp in Sources */,
|
||||
83BBEA0620EB54E700295997 /* imgui_draw.cpp in Sources */,
|
||||
5079822E257677DB0038A28D /* imgui_tables.cpp in Sources */,
|
||||
83BBEA0A20EB54E700295997 /* imgui.cpp in Sources */,
|
||||
83BBEA0820EB54E700295997 /* imgui_demo.cpp in Sources */,
|
||||
83BBEA0620EB54E700295997 /* imgui_draw.cpp in Sources */,
|
||||
050450AB2768052600AB6805 /* imgui_tables.cpp in Sources */,
|
||||
07A82ED92139418F0078D120 /* imgui_widgets.cpp in Sources */,
|
||||
8309BDA8253CCC080045E2A1 /* main.mm in Sources */,
|
||||
);
|
||||
|
||||
@@ -60,11 +60,21 @@
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
|
||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows
|
||||
|
||||
// Setup Dear ImGui style
|
||||
ImGui::StyleColorsDark();
|
||||
//ImGui::StyleColorsLight();
|
||||
|
||||
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
style.WindowRounding = 0.0f;
|
||||
style.Colors[ImGuiCol_WindowBg].w = 1.0f;
|
||||
}
|
||||
|
||||
// Setup Renderer backend
|
||||
ImGui_ImplMetal_Init(_device);
|
||||
|
||||
@@ -195,6 +205,13 @@
|
||||
// Present
|
||||
[commandBuffer presentDrawable:view.currentDrawable];
|
||||
[commandBuffer commit];
|
||||
|
||||
// Update and Render additional Platform Windows
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
ImGui::UpdatePlatformWindows();
|
||||
ImGui::RenderPlatformWindowsDefault();
|
||||
}
|
||||
}
|
||||
|
||||
-(void)mtkView:(MTKView*)view drawableSizeWillChange:(CGSize)size
|
||||
|
||||
@@ -47,11 +47,21 @@
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
|
||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows
|
||||
|
||||
// Setup Dear ImGui style
|
||||
ImGui::StyleColorsDark();
|
||||
//ImGui::StyleColorsLight();
|
||||
|
||||
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
style.WindowRounding = 0.0f;
|
||||
style.Colors[ImGuiCol_WindowBg].w = 1.0f;
|
||||
}
|
||||
|
||||
// Setup Platform/Renderer backends
|
||||
ImGui_ImplOSX_Init(self);
|
||||
ImGui_ImplOpenGL2_Init();
|
||||
@@ -136,6 +146,13 @@
|
||||
|
||||
ImGui_ImplOpenGL2_RenderDrawData(draw_data);
|
||||
|
||||
// Update and Render additional Platform Windows
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
ImGui::UpdatePlatformWindows();
|
||||
ImGui::RenderPlatformWindowsDefault();
|
||||
}
|
||||
|
||||
// Present
|
||||
[[self openGLContext] flushBuffer];
|
||||
|
||||
|
||||
@@ -76,6 +76,7 @@ int main(int, char**)
|
||||
|
||||
// Setup Platform/Renderer backends
|
||||
ImGui_ImplGlfw_InitForOther(window, true);
|
||||
ImGui_ImplGlfw_InstallEmscriptenCanvasResizeCallback("#canvas");
|
||||
ImGui_ImplWGPU_Init(wgpu_device, 3, wgpu_preferred_fmt, WGPUTextureFormat_Undefined);
|
||||
|
||||
// Load Fonts
|
||||
|
||||
@@ -33,11 +33,21 @@ int main(int, char**)
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
|
||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows
|
||||
|
||||
// Setup style
|
||||
ImGui::StyleColorsDark();
|
||||
//ImGui::StyleColorsLight();
|
||||
|
||||
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
style.WindowRounding = 0.0f;
|
||||
style.Colors[ImGuiCol_WindowBg].w = 1.0f;
|
||||
}
|
||||
|
||||
// Load Fonts
|
||||
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
||||
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
|
||||
@@ -69,7 +79,7 @@ int main(int, char**)
|
||||
id <MTLCommandQueue> commandQueue = [device newCommandQueue];
|
||||
|
||||
// Setup Platform/Renderer backends
|
||||
ImGui_ImplGlfw_InitForOpenGL(window, true);
|
||||
ImGui_ImplGlfw_InitForOther(window, true);
|
||||
ImGui_ImplMetal_Init(device);
|
||||
|
||||
NSWindow *nswin = glfwGetCocoaWindow(window);
|
||||
@@ -157,6 +167,13 @@ int main(int, char**)
|
||||
ImGui::Render();
|
||||
ImGui_ImplMetal_RenderDrawData(ImGui::GetDrawData(), commandBuffer, renderEncoder);
|
||||
|
||||
// Update and Render additional Platform Windows
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
ImGui::UpdatePlatformWindows();
|
||||
ImGui::RenderPlatformWindowsDefault();
|
||||
}
|
||||
|
||||
[renderEncoder popDebugGroup];
|
||||
[renderEncoder endEncoding];
|
||||
|
||||
|
||||
@@ -52,11 +52,23 @@ int main(int, char**)
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
|
||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows
|
||||
//io.ConfigViewportsNoAutoMerge = true;
|
||||
//io.ConfigViewportsNoTaskBarIcon = true;
|
||||
|
||||
// Setup Dear ImGui style
|
||||
ImGui::StyleColorsDark();
|
||||
//ImGui::StyleColorsLight();
|
||||
|
||||
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
style.WindowRounding = 0.0f;
|
||||
style.Colors[ImGuiCol_WindowBg].w = 1.0f;
|
||||
}
|
||||
|
||||
// Setup Platform/Renderer backends
|
||||
ImGui_ImplGlfw_InitForOpenGL(window, true);
|
||||
ImGui_ImplOpenGL2_Init();
|
||||
@@ -150,6 +162,17 @@ int main(int, char**)
|
||||
ImGui_ImplOpenGL2_RenderDrawData(ImGui::GetDrawData());
|
||||
//glUseProgram(last_program);
|
||||
|
||||
// Update and Render additional Platform Windows
|
||||
// (Platform functions may change the current OpenGL context, so we save/restore it to make it easier to paste this code elsewhere.
|
||||
// For this specific demo app we could also call glfwMakeContextCurrent(window) directly)
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
GLFWwindow* backup_current_context = glfwGetCurrentContext();
|
||||
ImGui::UpdatePlatformWindows();
|
||||
ImGui::RenderPlatformWindowsDefault();
|
||||
glfwMakeContextCurrent(backup_current_context);
|
||||
}
|
||||
|
||||
glfwMakeContextCurrent(window);
|
||||
glfwSwapBuffers(window);
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ endif
|
||||
CPPFLAGS += -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
|
||||
#CPPFLAGS += -g
|
||||
CPPFLAGS += -Wall -Wformat -Os $(EMS)
|
||||
# LDFLAGS += --shell-file ../libs/emscripten/shell_minimal.html
|
||||
LDFLAGS += --shell-file ../libs/emscripten/shell_minimal.html
|
||||
LDFLAGS += $(EMS)
|
||||
|
||||
##---------------------------------------------------------------------
|
||||
|
||||
@@ -77,13 +77,28 @@ int main(int, char**)
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
|
||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows
|
||||
//io.ConfigViewportsNoAutoMerge = true;
|
||||
//io.ConfigViewportsNoTaskBarIcon = true;
|
||||
|
||||
// Setup Dear ImGui style
|
||||
ImGui::StyleColorsDark();
|
||||
//ImGui::StyleColorsLight();
|
||||
|
||||
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
style.WindowRounding = 0.0f;
|
||||
style.Colors[ImGuiCol_WindowBg].w = 1.0f;
|
||||
}
|
||||
|
||||
// Setup Platform/Renderer backends
|
||||
ImGui_ImplGlfw_InitForOpenGL(window, true);
|
||||
#ifdef __EMSCRIPTEN__
|
||||
ImGui_ImplGlfw_InstallEmscriptenCanvasResizeCallback("#canvas");
|
||||
#endif
|
||||
ImGui_ImplOpenGL3_Init(glsl_version);
|
||||
|
||||
// Load Fonts
|
||||
@@ -176,6 +191,17 @@ int main(int, char**)
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
||||
|
||||
// Update and Render additional Platform Windows
|
||||
// (Platform functions may change the current OpenGL context, so we save/restore it to make it easier to paste this code elsewhere.
|
||||
// For this specific demo app we could also call glfwMakeContextCurrent(window) directly)
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
GLFWwindow* backup_current_context = glfwGetCurrentContext();
|
||||
ImGui::UpdatePlatformWindows();
|
||||
ImGui::RenderPlatformWindowsDefault();
|
||||
glfwMakeContextCurrent(backup_current_context);
|
||||
}
|
||||
|
||||
glfwSwapBuffers(window);
|
||||
}
|
||||
#ifdef __EMSCRIPTEN__
|
||||
|
||||
@@ -419,11 +419,23 @@ int main(int, char**)
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
|
||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows
|
||||
//io.ConfigViewportsNoAutoMerge = true;
|
||||
//io.ConfigViewportsNoTaskBarIcon = true;
|
||||
|
||||
// Setup Dear ImGui style
|
||||
ImGui::StyleColorsDark();
|
||||
//ImGui::StyleColorsLight();
|
||||
|
||||
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
style.WindowRounding = 0.0f;
|
||||
style.Colors[ImGuiCol_WindowBg].w = 1.0f;
|
||||
}
|
||||
|
||||
// Setup Platform/Renderer backends
|
||||
ImGui_ImplGlfw_InitForVulkan(window, true);
|
||||
ImGui_ImplVulkan_InitInfo init_info = {};
|
||||
@@ -531,17 +543,25 @@ int main(int, char**)
|
||||
|
||||
// Rendering
|
||||
ImGui::Render();
|
||||
ImDrawData* draw_data = ImGui::GetDrawData();
|
||||
const bool is_minimized = (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f);
|
||||
if (!is_minimized)
|
||||
ImDrawData* main_draw_data = ImGui::GetDrawData();
|
||||
const bool main_is_minimized = (main_draw_data->DisplaySize.x <= 0.0f || main_draw_data->DisplaySize.y <= 0.0f);
|
||||
wd->ClearValue.color.float32[0] = clear_color.x * clear_color.w;
|
||||
wd->ClearValue.color.float32[1] = clear_color.y * clear_color.w;
|
||||
wd->ClearValue.color.float32[2] = clear_color.z * clear_color.w;
|
||||
wd->ClearValue.color.float32[3] = clear_color.w;
|
||||
if (!main_is_minimized)
|
||||
FrameRender(wd, main_draw_data);
|
||||
|
||||
// Update and Render additional Platform Windows
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
wd->ClearValue.color.float32[0] = clear_color.x * clear_color.w;
|
||||
wd->ClearValue.color.float32[1] = clear_color.y * clear_color.w;
|
||||
wd->ClearValue.color.float32[2] = clear_color.z * clear_color.w;
|
||||
wd->ClearValue.color.float32[3] = clear_color.w;
|
||||
FrameRender(wd, draw_data);
|
||||
FramePresent(wd);
|
||||
ImGui::UpdatePlatformWindows();
|
||||
ImGui::RenderPlatformWindowsDefault();
|
||||
}
|
||||
|
||||
// Present Main Platform Window
|
||||
if (!main_is_minimized)
|
||||
FramePresent(wd);
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
|
||||
@@ -61,6 +61,7 @@ int main(int argc, char** argv)
|
||||
ImGui::CreateContext();
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
|
||||
|
||||
// Setup Dear ImGui style
|
||||
ImGui::StyleColorsDark();
|
||||
@@ -78,7 +79,6 @@ int main(int argc, char** argv)
|
||||
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
|
||||
ImGui_ImplGLUT_InstallFuncs();
|
||||
|
||||
|
||||
// Load Fonts
|
||||
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
||||
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
|
||||
|
||||
@@ -47,6 +47,12 @@ int main(int, char**)
|
||||
// Setup window
|
||||
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
|
||||
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+DirectX11 example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags);
|
||||
if (window == nullptr)
|
||||
{
|
||||
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
SDL_SysWMinfo wmInfo;
|
||||
SDL_VERSION(&wmInfo.version);
|
||||
SDL_GetWindowWMInfo(window, &wmInfo);
|
||||
@@ -65,11 +71,23 @@ int main(int, char**)
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
|
||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows
|
||||
//io.ConfigViewportsNoAutoMerge = true;
|
||||
//io.ConfigViewportsNoTaskBarIcon = true;
|
||||
|
||||
// Setup Dear ImGui style
|
||||
ImGui::StyleColorsDark();
|
||||
//ImGui::StyleColorsLight();
|
||||
|
||||
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
style.WindowRounding = 0.0f;
|
||||
style.Colors[ImGuiCol_WindowBg].w = 1.0f;
|
||||
}
|
||||
|
||||
// Setup Platform/Renderer backends
|
||||
ImGui_ImplSDL2_InitForD3D(window);
|
||||
ImGui_ImplDX11_Init(g_pd3dDevice, g_pd3dDeviceContext);
|
||||
@@ -170,6 +188,13 @@ int main(int, char**)
|
||||
g_pd3dDeviceContext->ClearRenderTargetView(g_mainRenderTargetView, clear_color_with_alpha);
|
||||
ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
|
||||
|
||||
// Update and Render additional Platform Windows
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
ImGui::UpdatePlatformWindows();
|
||||
ImGui::RenderPlatformWindowsDefault();
|
||||
}
|
||||
|
||||
g_pSwapChain->Present(1, 0); // Present with vsync
|
||||
//g_pSwapChain->Present(0, 0); // Present without vsync
|
||||
}
|
||||
|
||||
@@ -24,11 +24,21 @@ int main(int, char**)
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
|
||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows
|
||||
|
||||
// Setup style
|
||||
ImGui::StyleColorsDark();
|
||||
//ImGui::StyleColorsLight();
|
||||
|
||||
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
style.WindowRounding = 0.0f;
|
||||
style.Colors[ImGuiCol_WindowBg].w = 1.0f;
|
||||
}
|
||||
|
||||
// Load Fonts
|
||||
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
||||
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
|
||||
@@ -168,6 +178,13 @@ int main(int, char**)
|
||||
ImGui::Render();
|
||||
ImGui_ImplMetal_RenderDrawData(ImGui::GetDrawData(), commandBuffer, renderEncoder);
|
||||
|
||||
// Update and Render additional Platform Windows
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
ImGui::UpdatePlatformWindows();
|
||||
ImGui::RenderPlatformWindowsDefault();
|
||||
}
|
||||
|
||||
[renderEncoder popDebugGroup];
|
||||
[renderEncoder endEncoding];
|
||||
|
||||
|
||||
@@ -41,6 +41,12 @@ int main(int, char**)
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
|
||||
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
|
||||
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+OpenGL example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags);
|
||||
if (window == nullptr)
|
||||
{
|
||||
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
SDL_GLContext gl_context = SDL_GL_CreateContext(window);
|
||||
SDL_GL_MakeCurrent(window, gl_context);
|
||||
SDL_GL_SetSwapInterval(1); // Enable vsync
|
||||
@@ -51,11 +57,23 @@ int main(int, char**)
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
|
||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows
|
||||
//io.ConfigViewportsNoAutoMerge = true;
|
||||
//io.ConfigViewportsNoTaskBarIcon = true;
|
||||
|
||||
// Setup Dear ImGui style
|
||||
ImGui::StyleColorsDark();
|
||||
//ImGui::StyleColorsLight();
|
||||
|
||||
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
style.WindowRounding = 0.0f;
|
||||
style.Colors[ImGuiCol_WindowBg].w = 1.0f;
|
||||
}
|
||||
|
||||
// Setup Platform/Renderer backends
|
||||
ImGui_ImplSDL2_InitForOpenGL(window, gl_context);
|
||||
ImGui_ImplOpenGL2_Init();
|
||||
@@ -149,6 +167,19 @@ int main(int, char**)
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
//glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context where shaders may be bound
|
||||
ImGui_ImplOpenGL2_RenderDrawData(ImGui::GetDrawData());
|
||||
|
||||
// Update and Render additional Platform Windows
|
||||
// (Platform functions may change the current OpenGL context, so we save/restore it to make it easier to paste this code elsewhere.
|
||||
// For this specific demo app we could also call SDL_GL_MakeCurrent(window, gl_context) directly)
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
SDL_Window* backup_current_window = SDL_GL_GetCurrentWindow();
|
||||
SDL_GLContext backup_current_context = SDL_GL_GetCurrentContext();
|
||||
ImGui::UpdatePlatformWindows();
|
||||
ImGui::RenderPlatformWindowsDefault();
|
||||
SDL_GL_MakeCurrent(backup_current_window, backup_current_context);
|
||||
}
|
||||
|
||||
SDL_GL_SwapWindow(window);
|
||||
}
|
||||
|
||||
|
||||
@@ -68,6 +68,12 @@ int main(int, char**)
|
||||
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
|
||||
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
|
||||
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+OpenGL3 example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags);
|
||||
if (window == nullptr)
|
||||
{
|
||||
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
SDL_GLContext gl_context = SDL_GL_CreateContext(window);
|
||||
SDL_GL_MakeCurrent(window, gl_context);
|
||||
SDL_GL_SetSwapInterval(1); // Enable vsync
|
||||
@@ -78,11 +84,23 @@ int main(int, char**)
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
|
||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows
|
||||
//io.ConfigViewportsNoAutoMerge = true;
|
||||
//io.ConfigViewportsNoTaskBarIcon = true;
|
||||
|
||||
// Setup Dear ImGui style
|
||||
ImGui::StyleColorsDark();
|
||||
//ImGui::StyleColorsLight();
|
||||
|
||||
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
style.WindowRounding = 0.0f;
|
||||
style.Colors[ImGuiCol_WindowBg].w = 1.0f;
|
||||
}
|
||||
|
||||
// Setup Platform/Renderer backends
|
||||
ImGui_ImplSDL2_InitForOpenGL(window, gl_context);
|
||||
ImGui_ImplOpenGL3_Init(glsl_version);
|
||||
@@ -183,6 +201,19 @@ int main(int, char**)
|
||||
glClearColor(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
||||
|
||||
// Update and Render additional Platform Windows
|
||||
// (Platform functions may change the current OpenGL context, so we save/restore it to make it easier to paste this code elsewhere.
|
||||
// For this specific demo app we could also call SDL_GL_MakeCurrent(window, gl_context) directly)
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
SDL_Window* backup_current_window = SDL_GL_GetCurrentWindow();
|
||||
SDL_GLContext backup_current_context = SDL_GL_GetCurrentContext();
|
||||
ImGui::UpdatePlatformWindows();
|
||||
ImGui::RenderPlatformWindowsDefault();
|
||||
SDL_GL_MakeCurrent(backup_current_window, backup_current_context);
|
||||
}
|
||||
|
||||
SDL_GL_SwapWindow(window);
|
||||
}
|
||||
#ifdef __EMSCRIPTEN__
|
||||
|
||||
@@ -38,6 +38,11 @@ int main(int, char**)
|
||||
// Create window with SDL_Renderer graphics context
|
||||
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
|
||||
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+SDL_Renderer example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags);
|
||||
if (window == nullptr)
|
||||
{
|
||||
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
|
||||
return -1;
|
||||
}
|
||||
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED);
|
||||
if (renderer == nullptr)
|
||||
{
|
||||
|
||||
@@ -385,6 +385,11 @@ int main(int, char**)
|
||||
// Create window with Vulkan graphics context
|
||||
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_VULKAN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
|
||||
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+Vulkan example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags);
|
||||
if (window == nullptr)
|
||||
{
|
||||
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
ImVector<const char*> extensions;
|
||||
uint32_t extensions_count = 0;
|
||||
@@ -414,11 +419,23 @@ int main(int, char**)
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
|
||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows
|
||||
//io.ConfigFlags |= ImGuiConfigFlags_ViewportsNoTaskBarIcons;
|
||||
//io.ConfigFlags |= ImGuiConfigFlags_ViewportsNoMerge;
|
||||
|
||||
// Setup Dear ImGui style
|
||||
ImGui::StyleColorsDark();
|
||||
//ImGui::StyleColorsLight();
|
||||
|
||||
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
style.WindowRounding = 0.0f;
|
||||
style.Colors[ImGuiCol_WindowBg].w = 1.0f;
|
||||
}
|
||||
|
||||
// Setup Platform/Renderer backends
|
||||
ImGui_ImplSDL2_InitForVulkan(window);
|
||||
ImGui_ImplVulkan_InitInfo init_info = {};
|
||||
@@ -535,17 +552,25 @@ int main(int, char**)
|
||||
|
||||
// Rendering
|
||||
ImGui::Render();
|
||||
ImDrawData* draw_data = ImGui::GetDrawData();
|
||||
const bool is_minimized = (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f);
|
||||
if (!is_minimized)
|
||||
ImDrawData* main_draw_data = ImGui::GetDrawData();
|
||||
const bool main_is_minimized = (main_draw_data->DisplaySize.x <= 0.0f || main_draw_data->DisplaySize.y <= 0.0f);
|
||||
wd->ClearValue.color.float32[0] = clear_color.x * clear_color.w;
|
||||
wd->ClearValue.color.float32[1] = clear_color.y * clear_color.w;
|
||||
wd->ClearValue.color.float32[2] = clear_color.z * clear_color.w;
|
||||
wd->ClearValue.color.float32[3] = clear_color.w;
|
||||
if (!main_is_minimized)
|
||||
FrameRender(wd, main_draw_data);
|
||||
|
||||
// Update and Render additional Platform Windows
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
wd->ClearValue.color.float32[0] = clear_color.x * clear_color.w;
|
||||
wd->ClearValue.color.float32[1] = clear_color.y * clear_color.w;
|
||||
wd->ClearValue.color.float32[2] = clear_color.z * clear_color.w;
|
||||
wd->ClearValue.color.float32[3] = clear_color.w;
|
||||
FrameRender(wd, draw_data);
|
||||
FramePresent(wd);
|
||||
ImGui::UpdatePlatformWindows();
|
||||
ImGui::RenderPlatformWindowsDefault();
|
||||
}
|
||||
|
||||
// Present Main Platform Window
|
||||
if (!main_is_minimized)
|
||||
FramePresent(wd);
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
|
||||
@@ -64,7 +64,7 @@ int main(int, char**)
|
||||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
||||
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
|
||||
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
|
||||
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN);
|
||||
Uint32 window_flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN;
|
||||
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL3+OpenGL3 example", 1280, 720, window_flags);
|
||||
if (window == nullptr)
|
||||
{
|
||||
@@ -83,11 +83,23 @@ int main(int, char**)
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
|
||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows
|
||||
//io.ConfigViewportsNoAutoMerge = true;
|
||||
//io.ConfigViewportsNoTaskBarIcon = true;
|
||||
|
||||
// Setup Dear ImGui style
|
||||
ImGui::StyleColorsDark();
|
||||
//ImGui::StyleColorsLight();
|
||||
|
||||
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
style.WindowRounding = 0.0f;
|
||||
style.Colors[ImGuiCol_WindowBg].w = 1.0f;
|
||||
}
|
||||
|
||||
// Setup Platform/Renderer backends
|
||||
ImGui_ImplSDL3_InitForOpenGL(window, gl_context);
|
||||
ImGui_ImplOpenGL3_Init(glsl_version);
|
||||
@@ -188,6 +200,19 @@ int main(int, char**)
|
||||
glClearColor(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
||||
|
||||
// Update and Render additional Platform Windows
|
||||
// (Platform functions may change the current OpenGL context, so we save/restore it to make it easier to paste this code elsewhere.
|
||||
// For this specific demo app we could also call SDL_GL_MakeCurrent(window, gl_context) directly)
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
SDL_Window* backup_current_window = SDL_GL_GetCurrentWindow();
|
||||
SDL_GLContext backup_current_context = SDL_GL_GetCurrentContext();
|
||||
ImGui::UpdatePlatformWindows();
|
||||
ImGui::RenderPlatformWindowsDefault();
|
||||
SDL_GL_MakeCurrent(backup_current_window, backup_current_context);
|
||||
}
|
||||
|
||||
SDL_GL_SwapWindow(window);
|
||||
}
|
||||
#ifdef __EMSCRIPTEN__
|
||||
|
||||
@@ -35,19 +35,19 @@ int main(int, char**)
|
||||
SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");
|
||||
|
||||
// Create window with SDL_Renderer graphics context
|
||||
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN);
|
||||
Uint32 window_flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN;
|
||||
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL3+SDL_Renderer example", 1280, 720, window_flags);
|
||||
if (window == nullptr)
|
||||
{
|
||||
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
|
||||
return -1;
|
||||
}
|
||||
SDL_Renderer* renderer = SDL_CreateRenderer(window, NULL, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED);
|
||||
SDL_Renderer* renderer = SDL_CreateRenderer(window, nullptr, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED);
|
||||
if (renderer == nullptr)
|
||||
{
|
||||
SDL_Log("Error: SDL_CreateRenderer(): %s\n", SDL_GetError());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
|
||||
SDL_ShowWindow(window);
|
||||
|
||||
|
||||
@@ -53,11 +53,23 @@ int main(int, char**)
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
|
||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows
|
||||
//io.ConfigViewportsNoAutoMerge = true;
|
||||
//io.ConfigViewportsNoTaskBarIcon = true;
|
||||
|
||||
// Setup Dear ImGui style
|
||||
ImGui::StyleColorsDark();
|
||||
//ImGui::StyleColorsLight();
|
||||
|
||||
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
style.WindowRounding = 0.0f;
|
||||
style.Colors[ImGuiCol_WindowBg].w = 1.0f;
|
||||
}
|
||||
|
||||
// Setup Platform/Renderer backends
|
||||
ImGui_ImplWin32_Init(hwnd);
|
||||
ImGui_ImplDX10_Init(g_pd3dDevice);
|
||||
@@ -158,6 +170,13 @@ int main(int, char**)
|
||||
g_pd3dDevice->ClearRenderTargetView(g_mainRenderTargetView, clear_color_with_alpha);
|
||||
ImGui_ImplDX10_RenderDrawData(ImGui::GetDrawData());
|
||||
|
||||
// Update and Render additional Platform Windows
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
ImGui::UpdatePlatformWindows();
|
||||
ImGui::RenderPlatformWindowsDefault();
|
||||
}
|
||||
|
||||
g_pSwapChain->Present(1, 0); // Present with vsync
|
||||
//g_pSwapChain->Present(0, 0); // Present without vsync
|
||||
}
|
||||
@@ -174,7 +193,6 @@ int main(int, char**)
|
||||
}
|
||||
|
||||
// Helper functions
|
||||
|
||||
bool CreateDeviceD3D(HWND hWnd)
|
||||
{
|
||||
// Setup swap chain
|
||||
|
||||
@@ -53,11 +53,28 @@ int main(int, char**)
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
|
||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows
|
||||
//io.ConfigViewportsNoAutoMerge = true;
|
||||
//io.ConfigViewportsNoTaskBarIcon = true;
|
||||
//io.ConfigViewportsNoDefaultParent = true;
|
||||
//io.ConfigDockingAlwaysTabBar = true;
|
||||
//io.ConfigDockingTransparentPayload = true;
|
||||
//io.ConfigFlags |= ImGuiConfigFlags_DpiEnableScaleFonts; // FIXME-DPI: Experimental. THIS CURRENTLY DOESN'T WORK AS EXPECTED. DON'T USE IN USER APP!
|
||||
//io.ConfigFlags |= ImGuiConfigFlags_DpiEnableScaleViewports; // FIXME-DPI: Experimental.
|
||||
|
||||
// Setup Dear ImGui style
|
||||
ImGui::StyleColorsDark();
|
||||
//ImGui::StyleColorsLight();
|
||||
|
||||
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
style.WindowRounding = 0.0f;
|
||||
style.Colors[ImGuiCol_WindowBg].w = 1.0f;
|
||||
}
|
||||
|
||||
// Setup Platform/Renderer backends
|
||||
ImGui_ImplWin32_Init(hwnd);
|
||||
ImGui_ImplDX11_Init(g_pd3dDevice, g_pd3dDeviceContext);
|
||||
@@ -158,6 +175,13 @@ int main(int, char**)
|
||||
g_pd3dDeviceContext->ClearRenderTargetView(g_mainRenderTargetView, clear_color_with_alpha);
|
||||
ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
|
||||
|
||||
// Update and Render additional Platform Windows
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
ImGui::UpdatePlatformWindows();
|
||||
ImGui::RenderPlatformWindowsDefault();
|
||||
}
|
||||
|
||||
g_pSwapChain->Present(1, 0); // Present with vsync
|
||||
//g_pSwapChain->Present(0, 0); // Present without vsync
|
||||
}
|
||||
@@ -175,7 +199,6 @@ int main(int, char**)
|
||||
}
|
||||
|
||||
// Helper functions
|
||||
|
||||
bool CreateDeviceD3D(HWND hWnd)
|
||||
{
|
||||
// Setup swap chain
|
||||
@@ -230,6 +253,10 @@ void CleanupRenderTarget()
|
||||
if (g_mainRenderTargetView) { g_mainRenderTargetView->Release(); g_mainRenderTargetView = nullptr; }
|
||||
}
|
||||
|
||||
#ifndef WM_DPICHANGED
|
||||
#define WM_DPICHANGED 0x02E0 // From Windows SDK 8.1+ headers
|
||||
#endif
|
||||
|
||||
// Forward declare message handler from imgui_impl_win32.cpp
|
||||
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
@@ -258,6 +285,15 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
case WM_DESTROY:
|
||||
::PostQuitMessage(0);
|
||||
return 0;
|
||||
case WM_DPICHANGED:
|
||||
if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_DpiEnableScaleViewports)
|
||||
{
|
||||
//const int dpi = HIWORD(wParam);
|
||||
//printf("WM_DPICHANGED to %d (%.0f%%)\n", dpi, (float)dpi / 96.0f * 100.0f);
|
||||
const RECT* suggested_rect = (RECT*)lParam;
|
||||
::SetWindowPos(hWnd, nullptr, suggested_rect->left, suggested_rect->top, suggested_rect->right - suggested_rect->left, suggested_rect->bottom - suggested_rect->top, SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return ::DefWindowProcW(hWnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
@@ -87,11 +87,23 @@ int main(int, char**)
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
|
||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows
|
||||
//io.ConfigViewportsNoAutoMerge = true;
|
||||
//io.ConfigViewportsNoTaskBarIcon = true;
|
||||
|
||||
// Setup Dear ImGui style
|
||||
ImGui::StyleColorsDark();
|
||||
//ImGui::StyleColorsLight();
|
||||
|
||||
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
style.WindowRounding = 0.0f;
|
||||
style.Colors[ImGuiCol_WindowBg].w = 1.0f;
|
||||
}
|
||||
|
||||
// Setup Platform/Renderer backends
|
||||
ImGui_ImplWin32_Init(hwnd);
|
||||
ImGui_ImplDX12_Init(g_pd3dDevice, NUM_FRAMES_IN_FLIGHT,
|
||||
@@ -209,6 +221,13 @@ int main(int, char**)
|
||||
|
||||
g_pd3dCommandQueue->ExecuteCommandLists(1, (ID3D12CommandList* const*)&g_pd3dCommandList);
|
||||
|
||||
// Update and Render additional Platform Windows
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
ImGui::UpdatePlatformWindows();
|
||||
ImGui::RenderPlatformWindowsDefault(nullptr, (void*)g_pd3dCommandList);
|
||||
}
|
||||
|
||||
g_pSwapChain->Present(1, 0); // Present with vsync
|
||||
//g_pSwapChain->Present(0, 0); // Present without vsync
|
||||
|
||||
@@ -233,7 +252,6 @@ int main(int, char**)
|
||||
}
|
||||
|
||||
// Helper functions
|
||||
|
||||
bool CreateDeviceD3D(HWND hWnd)
|
||||
{
|
||||
// Setup swap chain
|
||||
|
||||
@@ -51,11 +51,23 @@ int main(int, char**)
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
|
||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows
|
||||
//io.ConfigViewportsNoAutoMerge = true;
|
||||
//io.ConfigViewportsNoTaskBarIcon = true;
|
||||
|
||||
// Setup Dear ImGui style
|
||||
ImGui::StyleColorsDark();
|
||||
//ImGui::StyleColorsLight();
|
||||
|
||||
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
style.WindowRounding = 0.0f;
|
||||
style.Colors[ImGuiCol_WindowBg].w = 1.0f;
|
||||
}
|
||||
|
||||
// Setup Platform/Renderer backends
|
||||
ImGui_ImplWin32_Init(hwnd);
|
||||
ImGui_ImplDX9_Init(g_pd3dDevice);
|
||||
@@ -162,6 +174,14 @@ int main(int, char**)
|
||||
ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData());
|
||||
g_pd3dDevice->EndScene();
|
||||
}
|
||||
|
||||
// Update and Render additional Platform Windows
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
ImGui::UpdatePlatformWindows();
|
||||
ImGui::RenderPlatformWindowsDefault();
|
||||
}
|
||||
|
||||
HRESULT result = g_pd3dDevice->Present(nullptr, nullptr, nullptr, nullptr);
|
||||
|
||||
// Handle loss of D3D9 device
|
||||
@@ -181,7 +201,6 @@ int main(int, char**)
|
||||
}
|
||||
|
||||
// Helper functions
|
||||
|
||||
bool CreateDeviceD3D(HWND hWnd)
|
||||
{
|
||||
if ((g_pD3D = Direct3DCreate9(D3D_SDK_VERSION)) == nullptr)
|
||||
@@ -217,6 +236,10 @@ void ResetDevice()
|
||||
ImGui_ImplDX9_CreateDeviceObjects();
|
||||
}
|
||||
|
||||
#ifndef WM_DPICHANGED
|
||||
#define WM_DPICHANGED 0x02E0 // From Windows SDK 8.1+ headers
|
||||
#endif
|
||||
|
||||
// Forward declare message handler from imgui_impl_win32.cpp
|
||||
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
@@ -245,6 +268,15 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
case WM_DESTROY:
|
||||
::PostQuitMessage(0);
|
||||
return 0;
|
||||
case WM_DPICHANGED:
|
||||
if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_DpiEnableScaleViewports)
|
||||
{
|
||||
//const int dpi = HIWORD(wParam);
|
||||
//printf("WM_DPICHANGED to %d (%.0f%%)\n", dpi, (float)dpi / 96.0f * 100.0f);
|
||||
const RECT* suggested_rect = (RECT*)lParam;
|
||||
::SetWindowPos(hWnd, nullptr, suggested_rect->left, suggested_rect->top, suggested_rect->right - suggested_rect->left, suggested_rect->bottom - suggested_rect->top, SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return ::DefWindowProcW(hWnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
@@ -33,14 +33,50 @@ void CleanupDeviceWGL(HWND hWnd, WGL_WindowData* data);
|
||||
void ResetDeviceWGL();
|
||||
LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
// Support function for multi-viewports
|
||||
// Unlike most other backend combination, we need specific hooks to combine Win32+OpenGL.
|
||||
// We could in theory decide to support Win32-specific code in OpenGL backend via e.g. an hypothetical ImGui_ImplOpenGL3_InitForRawWin32().
|
||||
static void Hook_Renderer_CreateWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
assert(viewport->RendererUserData == NULL);
|
||||
|
||||
WGL_WindowData* data = IM_NEW(WGL_WindowData);
|
||||
CreateDeviceWGL((HWND)viewport->PlatformHandle, data);
|
||||
viewport->RendererUserData = data;
|
||||
}
|
||||
|
||||
static void Hook_Renderer_DestroyWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
if (viewport->RendererUserData != NULL)
|
||||
{
|
||||
WGL_WindowData* data = (WGL_WindowData*)viewport->RendererUserData;
|
||||
CleanupDeviceWGL((HWND)viewport->PlatformHandle, data);
|
||||
IM_DELETE(data);
|
||||
viewport->RendererUserData = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void Hook_Platform_RenderWindow(ImGuiViewport* viewport, void*)
|
||||
{
|
||||
// Activate the platform window DC in the OpenGL rendering context
|
||||
if (WGL_WindowData* data = (WGL_WindowData*)viewport->RendererUserData)
|
||||
wglMakeCurrent(data->hDC, g_hRC);
|
||||
}
|
||||
|
||||
static void Hook_Renderer_SwapBuffers(ImGuiViewport* viewport, void*)
|
||||
{
|
||||
if (WGL_WindowData* data = (WGL_WindowData*)viewport->RendererUserData)
|
||||
::SwapBuffers(data->hDC);
|
||||
}
|
||||
|
||||
// Main code
|
||||
int main(int, char**)
|
||||
{
|
||||
// Create application window
|
||||
//ImGui_ImplWin32_EnableDpiAwareness();
|
||||
WNDCLASSEXW wc = { sizeof(wc), CS_OWNDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, L"ImGui Example", NULL };
|
||||
WNDCLASSEXW wc = { sizeof(wc), CS_OWNDC, WndProc, 0L, 0L, GetModuleHandle(nullptr), nullptr, nullptr, nullptr, nullptr, L"ImGui Example", nullptr };
|
||||
::RegisterClassExW(&wc);
|
||||
HWND hwnd = ::CreateWindowW(wc.lpszClassName, L"Dear ImGui Win32+OpenGL3 Example", WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL);
|
||||
HWND hwnd = ::CreateWindowW(wc.lpszClassName, L"Dear ImGui Win32+OpenGL3 Example", WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, nullptr, nullptr, wc.hInstance, nullptr);
|
||||
|
||||
// Initialize OpenGL
|
||||
if (!CreateDeviceWGL(hwnd, &g_MainWindow))
|
||||
@@ -62,19 +98,43 @@ int main(int, char**)
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
|
||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows
|
||||
|
||||
// Setup Dear ImGui style
|
||||
ImGui::StyleColorsDark();
|
||||
//ImGui::StyleColorsClassic();
|
||||
|
||||
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
style.WindowRounding = 0.0f;
|
||||
style.Colors[ImGuiCol_WindowBg].w = 1.0f;
|
||||
}
|
||||
|
||||
// Setup Platform/Renderer backends
|
||||
ImGui_ImplWin32_InitForOpenGL(hwnd);
|
||||
ImGui_ImplOpenGL3_Init();
|
||||
|
||||
// Win32+GL needs specific hooks for viewport, as there are specific things needed to tie Win32 and GL api.
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
IM_ASSERT(platform_io.Renderer_CreateWindow == NULL);
|
||||
IM_ASSERT(platform_io.Renderer_DestroyWindow == NULL);
|
||||
IM_ASSERT(platform_io.Renderer_SwapBuffers == NULL);
|
||||
IM_ASSERT(platform_io.Platform_RenderWindow == NULL);
|
||||
platform_io.Renderer_CreateWindow = Hook_Renderer_CreateWindow;
|
||||
platform_io.Renderer_DestroyWindow = Hook_Renderer_DestroyWindow;
|
||||
platform_io.Renderer_SwapBuffers = Hook_Renderer_SwapBuffers;
|
||||
platform_io.Platform_RenderWindow = Hook_Platform_RenderWindow;
|
||||
}
|
||||
|
||||
// Load Fonts
|
||||
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
||||
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
|
||||
// - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||
// - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||
// - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call.
|
||||
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||
@@ -84,8 +144,8 @@ int main(int, char**)
|
||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f);
|
||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f);
|
||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f);
|
||||
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese());
|
||||
//IM_ASSERT(font != NULL);
|
||||
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, nullptr, io.Fonts->GetGlyphRangesJapanese());
|
||||
//IM_ASSERT(font != nullptr);
|
||||
|
||||
// Our state
|
||||
bool show_demo_window = true;
|
||||
@@ -99,7 +159,7 @@ int main(int, char**)
|
||||
// Poll and handle messages (inputs, window resize, etc.)
|
||||
// See the WndProc() function below for our to dispatch events to the Win32 backend.
|
||||
MSG msg;
|
||||
while (::PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
|
||||
while (::PeekMessage(&msg, nullptr, 0U, 0U, PM_REMOVE))
|
||||
{
|
||||
::TranslateMessage(&msg);
|
||||
::DispatchMessage(&msg);
|
||||
@@ -158,6 +218,16 @@ int main(int, char**)
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
||||
|
||||
// Update and Render additional Platform Windows
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
ImGui::UpdatePlatformWindows();
|
||||
ImGui::RenderPlatformWindowsDefault();
|
||||
|
||||
// Restore the OpenGL rendering context to the main window DC, since platform windows might have changed it.
|
||||
wglMakeCurrent(g_MainWindow.hDC, g_hRC);
|
||||
}
|
||||
|
||||
// Present
|
||||
::SwapBuffers(g_MainWindow.hDC);
|
||||
}
|
||||
@@ -200,7 +270,7 @@ bool CreateDeviceWGL(HWND hWnd, WGL_WindowData* data)
|
||||
|
||||
void CleanupDeviceWGL(HWND hWnd, WGL_WindowData* data)
|
||||
{
|
||||
wglMakeCurrent(NULL, NULL);
|
||||
wglMakeCurrent(nullptr, nullptr);
|
||||
::ReleaseDC(hWnd, data->hDC);
|
||||
}
|
||||
|
||||
|
||||
@@ -50,12 +50,14 @@
|
||||
//#define IMGUI_DISABLE_SSE // Disable use of SSE intrinsics even if available
|
||||
|
||||
//---- Include imgui_user.h at the end of imgui.h as a convenience
|
||||
// May be convenient for some users to only explicitly include vanilla imgui.h and have extra stuff included.
|
||||
//#define IMGUI_INCLUDE_IMGUI_USER_H
|
||||
//#define IMGUI_USER_H_FILENAME "my_folder/my_imgui_user.h"
|
||||
|
||||
//---- Pack colors to BGRA8 instead of RGBA8 (to avoid converting from one to another)
|
||||
//#define IMGUI_USE_BGRA_PACKED_COLOR
|
||||
|
||||
//---- Use 32-bit for ImWchar (default is 16-bit) to support unicode planes 1-16. (e.g. point beyond 0xFFFF like emoticons, dingbats, symbols, shapes, ancient languages, etc...)
|
||||
//---- Use 32-bit for ImWchar (default is 16-bit) to support Unicode planes 1-16. (e.g. point beyond 0xFFFF like emoticons, dingbats, symbols, shapes, ancient languages, etc...)
|
||||
//#define IMGUI_USE_WCHAR32
|
||||
|
||||
//---- Avoid multiple STB libraries implementations, or redefine path/filenames to prioritize another version
|
||||
|
||||
479
imgui_demo.cpp
479
imgui_demo.cpp
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.90.0
|
||||
// dear imgui, v1.90.1
|
||||
// (demo code)
|
||||
|
||||
// Help:
|
||||
@@ -54,7 +54,7 @@
|
||||
// Because we can't assume anything about your support of maths operators, we cannot use them in imgui_demo.cpp.
|
||||
|
||||
// Navigating this file:
|
||||
// - In Visual Studio IDE: CTRL+comma ("Edit.GoToAll") can follow symbols in comments, whereas CTRL+F12 ("Edit.GoToImplementation") cannot.
|
||||
// - In Visual Studio: CTRL+comma ("Edit.GoToAll") can follow symbols in comments, whereas CTRL+F12 ("Edit.GoToImplementation") cannot.
|
||||
// - With Visual Assist installed: ALT+G ("VAssistX.GoToImplementation") can also follow symbols in comments.
|
||||
|
||||
/*
|
||||
@@ -85,6 +85,7 @@ Index of this file:
|
||||
// [SECTION] Example App: Fullscreen window / ShowExampleAppFullscreen()
|
||||
// [SECTION] Example App: Manipulating window titles / ShowExampleAppWindowTitles()
|
||||
// [SECTION] Example App: Custom Rendering using ImDrawList API / ShowExampleAppCustomRendering()
|
||||
// [SECTION] Example App: Docking, DockSpace / ShowExampleAppDockSpace()
|
||||
// [SECTION] Example App: Documents Handling / ShowExampleAppDocuments()
|
||||
|
||||
*/
|
||||
@@ -171,7 +172,8 @@ Index of this file:
|
||||
#define IM_MAX(A, B) (((A) >= (B)) ? (A) : (B))
|
||||
#define IM_CLAMP(V, MN, MX) ((V) < (MN) ? (MN) : (V) > (MX) ? (MX) : (V))
|
||||
|
||||
// Enforce cdecl calling convention for functions called by the standard library, in case compilation settings changed the default to e.g. __vectorcall
|
||||
// Enforce cdecl calling convention for functions called by the standard library,
|
||||
// in case compilation settings changed the default to e.g. __vectorcall
|
||||
#ifndef IMGUI_CDECL
|
||||
#ifdef _MSC_VER
|
||||
#define IMGUI_CDECL __cdecl
|
||||
@@ -190,6 +192,7 @@ Index of this file:
|
||||
static void ShowExampleAppMainMenuBar();
|
||||
static void ShowExampleAppConsole(bool* p_open);
|
||||
static void ShowExampleAppCustomRendering(bool* p_open);
|
||||
static void ShowExampleAppDockSpace(bool* p_open);
|
||||
static void ShowExampleAppDocuments(bool* p_open);
|
||||
static void ShowExampleAppLog(bool* p_open);
|
||||
static void ShowExampleAppLayout(bool* p_open);
|
||||
@@ -229,6 +232,16 @@ static void HelpMarker(const char* desc)
|
||||
}
|
||||
}
|
||||
|
||||
static void ShowDockingDisabledMessage()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui::Text("ERROR: Docking is not enabled! See Demo > Configuration.");
|
||||
ImGui::Text("Set io.ConfigFlags |= ImGuiConfigFlags_DockingEnable in your code, or ");
|
||||
ImGui::SameLine(0.0f, 0.0f);
|
||||
if (ImGui::SmallButton("click here"))
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
|
||||
}
|
||||
|
||||
// Helper to wire demo markers located in code to an interactive browser
|
||||
typedef void (*ImGuiDemoMarkerCallback)(const char* file, int line, const char* section, void* user_data);
|
||||
extern ImGuiDemoMarkerCallback GImGuiDemoMarkerCallback;
|
||||
@@ -262,6 +275,7 @@ void ImGui::ShowDemoWindow(bool* p_open)
|
||||
static bool show_app_main_menu_bar = false;
|
||||
static bool show_app_console = false;
|
||||
static bool show_app_custom_rendering = false;
|
||||
static bool show_app_dockspace = false;
|
||||
static bool show_app_documents = false;
|
||||
static bool show_app_log = false;
|
||||
static bool show_app_layout = false;
|
||||
@@ -274,7 +288,8 @@ void ImGui::ShowDemoWindow(bool* p_open)
|
||||
static bool show_app_window_titles = false;
|
||||
|
||||
if (show_app_main_menu_bar) ShowExampleAppMainMenuBar();
|
||||
if (show_app_documents) ShowExampleAppDocuments(&show_app_documents);
|
||||
if (show_app_dockspace) ShowExampleAppDockSpace(&show_app_dockspace); // Process the Docking app first, as explicit DockSpace() nodes needs to be submitted early (read comments near the DockSpace function)
|
||||
if (show_app_documents) ShowExampleAppDocuments(&show_app_documents); // Process the Document app next, as it may also use a DockSpace()
|
||||
if (show_app_console) ShowExampleAppConsole(&show_app_console);
|
||||
if (show_app_custom_rendering) ShowExampleAppCustomRendering(&show_app_custom_rendering);
|
||||
if (show_app_log) ShowExampleAppLog(&show_app_log);
|
||||
@@ -320,6 +335,7 @@ void ImGui::ShowDemoWindow(bool* p_open)
|
||||
static bool no_nav = false;
|
||||
static bool no_background = false;
|
||||
static bool no_bring_to_front = false;
|
||||
static bool no_docking = false;
|
||||
static bool unsaved_document = false;
|
||||
|
||||
ImGuiWindowFlags window_flags = 0;
|
||||
@@ -332,6 +348,7 @@ void ImGui::ShowDemoWindow(bool* p_open)
|
||||
if (no_nav) window_flags |= ImGuiWindowFlags_NoNav;
|
||||
if (no_background) window_flags |= ImGuiWindowFlags_NoBackground;
|
||||
if (no_bring_to_front) window_flags |= ImGuiWindowFlags_NoBringToFrontOnFocus;
|
||||
if (no_docking) window_flags |= ImGuiWindowFlags_NoDocking;
|
||||
if (unsaved_document) window_flags |= ImGuiWindowFlags_UnsavedDocument;
|
||||
if (no_close) p_open = NULL; // Don't pass our bool* to Begin
|
||||
|
||||
@@ -372,6 +389,7 @@ void ImGui::ShowDemoWindow(bool* p_open)
|
||||
ImGui::SeparatorText("Mini apps");
|
||||
ImGui::MenuItem("Console", NULL, &show_app_console);
|
||||
ImGui::MenuItem("Custom rendering", NULL, &show_app_custom_rendering);
|
||||
ImGui::MenuItem("Dockspace", NULL, &show_app_dockspace);
|
||||
ImGui::MenuItem("Documents", NULL, &show_app_documents);
|
||||
ImGui::MenuItem("Log", NULL, &show_app_log);
|
||||
ImGui::MenuItem("Property editor", NULL, &show_app_property_editor);
|
||||
@@ -458,6 +476,43 @@ void ImGui::ShowDemoWindow(bool* p_open)
|
||||
}
|
||||
ImGui::CheckboxFlags("io.ConfigFlags: NoMouseCursorChange", &io.ConfigFlags, ImGuiConfigFlags_NoMouseCursorChange);
|
||||
ImGui::SameLine(); HelpMarker("Instruct backend to not alter mouse cursor shape and visibility.");
|
||||
|
||||
ImGui::CheckboxFlags("io.ConfigFlags: DockingEnable", &io.ConfigFlags, ImGuiConfigFlags_DockingEnable);
|
||||
ImGui::SameLine();
|
||||
if (io.ConfigDockingWithShift)
|
||||
HelpMarker("Drag from window title bar or their tab to dock/undock. Hold SHIFT to enable docking.\n\nDrag from window menu button (upper-left button) to undock an entire node (all windows).");
|
||||
else
|
||||
HelpMarker("Drag from window title bar or their tab to dock/undock. Hold SHIFT to disable docking.\n\nDrag from window menu button (upper-left button) to undock an entire node (all windows).");
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_DockingEnable)
|
||||
{
|
||||
ImGui::Indent();
|
||||
ImGui::Checkbox("io.ConfigDockingNoSplit", &io.ConfigDockingNoSplit);
|
||||
ImGui::SameLine(); HelpMarker("Simplified docking mode: disable window splitting, so docking is limited to merging multiple windows together into tab-bars.");
|
||||
ImGui::Checkbox("io.ConfigDockingWithShift", &io.ConfigDockingWithShift);
|
||||
ImGui::SameLine(); HelpMarker("Enable docking when holding Shift only (allow to drop in wider space, reduce visual noise)");
|
||||
ImGui::Checkbox("io.ConfigDockingAlwaysTabBar", &io.ConfigDockingAlwaysTabBar);
|
||||
ImGui::SameLine(); HelpMarker("Create a docking node and tab-bar on single floating windows.");
|
||||
ImGui::Checkbox("io.ConfigDockingTransparentPayload", &io.ConfigDockingTransparentPayload);
|
||||
ImGui::SameLine(); HelpMarker("Make window or viewport transparent when docking and only display docking boxes on the target viewport. Useful if rendering of multiple viewport cannot be synced. Best used with ConfigViewportsNoAutoMerge.");
|
||||
ImGui::Unindent();
|
||||
}
|
||||
|
||||
ImGui::CheckboxFlags("io.ConfigFlags: ViewportsEnable", &io.ConfigFlags, ImGuiConfigFlags_ViewportsEnable);
|
||||
ImGui::SameLine(); HelpMarker("[beta] Enable beta multi-viewports support. See ImGuiPlatformIO for details.");
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
ImGui::Indent();
|
||||
ImGui::Checkbox("io.ConfigViewportsNoAutoMerge", &io.ConfigViewportsNoAutoMerge);
|
||||
ImGui::SameLine(); HelpMarker("Set to make all floating imgui windows always create their own viewport. Otherwise, they are merged into the main host viewports when overlapping it.");
|
||||
ImGui::Checkbox("io.ConfigViewportsNoTaskBarIcon", &io.ConfigViewportsNoTaskBarIcon);
|
||||
ImGui::SameLine(); HelpMarker("Toggling this at runtime is normally unsupported (most platform backends won't refresh the task bar icon state right away).");
|
||||
ImGui::Checkbox("io.ConfigViewportsNoDecoration", &io.ConfigViewportsNoDecoration);
|
||||
ImGui::SameLine(); HelpMarker("Toggling this at runtime is normally unsupported (most platform backends won't refresh the decoration right away).");
|
||||
ImGui::Checkbox("io.ConfigViewportsNoDefaultParent", &io.ConfigViewportsNoDefaultParent);
|
||||
ImGui::SameLine(); HelpMarker("Toggling this at runtime is normally unsupported (most platform backends won't refresh the parenting right away).");
|
||||
ImGui::Unindent();
|
||||
}
|
||||
|
||||
ImGui::Checkbox("io.ConfigInputTrickleEventQueue", &io.ConfigInputTrickleEventQueue);
|
||||
ImGui::SameLine(); HelpMarker("Enable input queue trickling: some types of events submitted during the same frame (e.g. button down + up) will be spread over multiple frames, improving interactions with low framerates.");
|
||||
ImGui::Checkbox("io.MouseDrawCursor", &io.MouseDrawCursor);
|
||||
@@ -477,10 +532,12 @@ void ImGui::ShowDemoWindow(bool* p_open)
|
||||
ImGui::Text("Also see Style->Rendering for rendering options.");
|
||||
|
||||
ImGui::SeparatorText("Debug");
|
||||
ImGui::Checkbox("io.ConfigDebugIsDebuggerPresent", &io.ConfigDebugIsDebuggerPresent);
|
||||
ImGui::SameLine(); HelpMarker("Enable various tools calling IM_DEBUG_BREAK().\n\nRequires a debugger being attached, otherwise IM_DEBUG_BREAK() options will appear to crash your application.");
|
||||
ImGui::BeginDisabled();
|
||||
ImGui::Checkbox("io.ConfigDebugBeginReturnValueOnce", &io.ConfigDebugBeginReturnValueOnce); // .
|
||||
ImGui::EndDisabled();
|
||||
ImGui::SameLine(); HelpMarker("First calls to Begin()/BeginChild() will return false.\n\nTHIS OPTION IS DISABLED because it needs to be set at application boot-time to make sense. Showing the disabled option is a way to make this feature easier to discover");
|
||||
ImGui::SameLine(); HelpMarker("First calls to Begin()/BeginChild() will return false.\n\nTHIS OPTION IS DISABLED because it needs to be set at application boot-time to make sense. Showing the disabled option is a way to make this feature easier to discover.");
|
||||
ImGui::Checkbox("io.ConfigDebugBeginReturnValueLoop", &io.ConfigDebugBeginReturnValueLoop);
|
||||
ImGui::SameLine(); HelpMarker("Some calls to Begin()/BeginChild() will return false.\n\nWill cycle through window depths then repeat. Windows should be flickering while running.");
|
||||
ImGui::Checkbox("io.ConfigDebugIgnoreFocusLoss", &io.ConfigDebugIgnoreFocusLoss);
|
||||
@@ -499,12 +556,16 @@ void ImGui::ShowDemoWindow(bool* p_open)
|
||||
"Those flags are set by the backends (imgui_impl_xxx files) to specify their capabilities.\n"
|
||||
"Here we expose them as read-only fields to avoid breaking interactions with your backend.");
|
||||
|
||||
// Make a local copy to avoid modifying actual backend flags.
|
||||
// FIXME: Maybe we need a BeginReadonly() equivalent to keep label bright?
|
||||
ImGui::BeginDisabled();
|
||||
ImGui::CheckboxFlags("io.BackendFlags: HasGamepad", &io.BackendFlags, ImGuiBackendFlags_HasGamepad);
|
||||
ImGui::CheckboxFlags("io.BackendFlags: HasMouseCursors", &io.BackendFlags, ImGuiBackendFlags_HasMouseCursors);
|
||||
ImGui::CheckboxFlags("io.BackendFlags: HasSetMousePos", &io.BackendFlags, ImGuiBackendFlags_HasSetMousePos);
|
||||
ImGui::CheckboxFlags("io.BackendFlags: RendererHasVtxOffset", &io.BackendFlags, ImGuiBackendFlags_RendererHasVtxOffset);
|
||||
ImGui::CheckboxFlags("io.BackendFlags: HasGamepad", &io.BackendFlags, ImGuiBackendFlags_HasGamepad);
|
||||
ImGui::CheckboxFlags("io.BackendFlags: HasMouseCursors", &io.BackendFlags, ImGuiBackendFlags_HasMouseCursors);
|
||||
ImGui::CheckboxFlags("io.BackendFlags: HasSetMousePos", &io.BackendFlags, ImGuiBackendFlags_HasSetMousePos);
|
||||
ImGui::CheckboxFlags("io.BackendFlags: PlatformHasViewports", &io.BackendFlags, ImGuiBackendFlags_PlatformHasViewports);
|
||||
ImGui::CheckboxFlags("io.BackendFlags: HasMouseHoveredViewport",&io.BackendFlags, ImGuiBackendFlags_HasMouseHoveredViewport);
|
||||
ImGui::CheckboxFlags("io.BackendFlags: RendererHasVtxOffset", &io.BackendFlags, ImGuiBackendFlags_RendererHasVtxOffset);
|
||||
ImGui::CheckboxFlags("io.BackendFlags: RendererHasViewports", &io.BackendFlags, ImGuiBackendFlags_RendererHasViewports);
|
||||
ImGui::EndDisabled();
|
||||
ImGui::TreePop();
|
||||
ImGui::Spacing();
|
||||
@@ -554,6 +615,7 @@ void ImGui::ShowDemoWindow(bool* p_open)
|
||||
ImGui::TableNextColumn(); ImGui::Checkbox("No nav", &no_nav);
|
||||
ImGui::TableNextColumn(); ImGui::Checkbox("No background", &no_background);
|
||||
ImGui::TableNextColumn(); ImGui::Checkbox("No bring to front", &no_bring_to_front);
|
||||
ImGui::TableNextColumn(); ImGui::Checkbox("No docking", &no_docking);
|
||||
ImGui::TableNextColumn(); ImGui::Checkbox("Unsaved document", &unsaved_document);
|
||||
ImGui::EndTable();
|
||||
}
|
||||
@@ -759,7 +821,8 @@ static void ShowDemoWindowWidgets()
|
||||
static int item_current = 0;
|
||||
ImGui::Combo("combo", &item_current, items, IM_ARRAYSIZE(items));
|
||||
ImGui::SameLine(); HelpMarker(
|
||||
"Using the simplified one-liner Combo API here.\nRefer to the \"Combo\" section below for an explanation of how to use the more flexible and general BeginCombo/EndCombo API.");
|
||||
"Using the simplified one-liner Combo API here.\n"
|
||||
"Refer to the \"Combo\" section below for an explanation of how to use the more flexible and general BeginCombo/EndCombo API.");
|
||||
}
|
||||
|
||||
{
|
||||
@@ -770,7 +833,8 @@ static void ShowDemoWindowWidgets()
|
||||
static int item_current = 1;
|
||||
ImGui::ListBox("listbox", &item_current, items, IM_ARRAYSIZE(items), 4);
|
||||
ImGui::SameLine(); HelpMarker(
|
||||
"Using the simplified one-liner ListBox API here.\nRefer to the \"List boxes\" section below for an explanation of how to use the more flexible and general BeginListBox/EndListBox API.");
|
||||
"Using the simplified one-liner ListBox API here.\n"
|
||||
"Refer to the \"List boxes\" section below for an explanation of how to use the more flexible and general BeginListBox/EndListBox API.");
|
||||
}
|
||||
|
||||
ImGui::TreePop();
|
||||
@@ -1088,7 +1152,7 @@ static void ShowDemoWindowWidgets()
|
||||
"CJK text will only appear if the font was loaded with the appropriate CJK character ranges. "
|
||||
"Call io.Fonts->AddFontFromFileTTF() manually to load extra character ranges. "
|
||||
"Read docs/FONTS.md for details.");
|
||||
ImGui::Text("Hiragana: \xe3\x81\x8b\xe3\x81\x8d\xe3\x81\x8f\xe3\x81\x91\xe3\x81\x93 (kakikukeko)"); // Normally we would use u8"blah blah" with the proper characters directly in the string.
|
||||
ImGui::Text("Hiragana: \xe3\x81\x8b\xe3\x81\x8d\xe3\x81\x8f\xe3\x81\x91\xe3\x81\x93 (kakikukeko)");
|
||||
ImGui::Text("Kanjis: \xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e (nihongo)");
|
||||
static char buf[32] = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e";
|
||||
//static char buf[32] = u8"NIHONGO"; // <- this is how you would write it with C++11, using real kanjis
|
||||
@@ -1132,7 +1196,7 @@ static void ShowDemoWindowWidgets()
|
||||
ImVec2 pos = ImGui::GetCursorScreenPos();
|
||||
ImVec2 uv_min = ImVec2(0.0f, 0.0f); // Top-left
|
||||
ImVec2 uv_max = ImVec2(1.0f, 1.0f); // Lower-right
|
||||
ImVec4 tint_col = use_text_color_for_tint ? ImGui::GetStyleColorVec4(ImGuiCol_Text) : ImVec4(1.0f, 1.0f, 1.0f, 1.0f); // No tint
|
||||
ImVec4 tint_col = use_text_color_for_tint ? ImGui::GetStyleColorVec4(ImGuiCol_Text) : ImVec4(1.0f, 1.0f, 1.0f, 1.0f); // No tint
|
||||
ImVec4 border_col = ImGui::GetStyleColorVec4(ImGuiCol_Border);
|
||||
ImGui::Image(my_tex_id, ImVec2(my_tex_w, my_tex_h), uv_min, uv_max, tint_col, border_col);
|
||||
if (ImGui::BeginItemTooltip())
|
||||
@@ -1191,9 +1255,9 @@ static void ShowDemoWindowWidgets()
|
||||
ImGui::CheckboxFlags("ImGuiComboFlags_PopupAlignLeft", &flags, ImGuiComboFlags_PopupAlignLeft);
|
||||
ImGui::SameLine(); HelpMarker("Only makes a difference if the popup is larger than the combo");
|
||||
if (ImGui::CheckboxFlags("ImGuiComboFlags_NoArrowButton", &flags, ImGuiComboFlags_NoArrowButton))
|
||||
flags &= ~ImGuiComboFlags_NoPreview; // Clear the other flag, as we cannot combine both
|
||||
flags &= ~ImGuiComboFlags_NoPreview; // Clear incompatible flags
|
||||
if (ImGui::CheckboxFlags("ImGuiComboFlags_NoPreview", &flags, ImGuiComboFlags_NoPreview))
|
||||
flags &= ~(ImGuiComboFlags_NoArrowButton | ImGuiComboFlags_WidthFitPreview); // Clear the other flag, as we cannot combine both
|
||||
flags &= ~(ImGuiComboFlags_NoArrowButton | ImGuiComboFlags_WidthFitPreview); // Clear incompatible flags
|
||||
if (ImGui::CheckboxFlags("ImGuiComboFlags_WidthFitPreview", &flags, ImGuiComboFlags_WidthFitPreview))
|
||||
flags &= ~ImGuiComboFlags_NoPreview;
|
||||
|
||||
@@ -1210,7 +1274,10 @@ static void ShowDemoWindowWidgets()
|
||||
// stored in the object itself, etc.)
|
||||
const char* items[] = { "AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIII", "JJJJ", "KKKK", "LLLLLLL", "MMMM", "OOOOOOO" };
|
||||
static int item_current_idx = 0; // Here we store our selection data as an index.
|
||||
const char* combo_preview_value = items[item_current_idx]; // Pass in the preview value visible before opening the combo (it could be anything)
|
||||
|
||||
// Pass in the preview value visible before opening the combo (it could technically be different contents or not pulled from items[])
|
||||
const char* combo_preview_value = items[item_current_idx];
|
||||
|
||||
if (ImGui::BeginCombo("combo 1", combo_preview_value, flags))
|
||||
{
|
||||
for (int n = 0; n < IM_ARRAYSIZE(items); n++)
|
||||
@@ -1250,8 +1317,10 @@ static void ShowDemoWindowWidgets()
|
||||
IMGUI_DEMO_MARKER("Widgets/List Boxes");
|
||||
if (ImGui::TreeNode("List boxes"))
|
||||
{
|
||||
// BeginListBox() is essentially a thin wrapper to using BeginChild()/EndChild() with the ImGuiChildFlags_FrameStyle flag for stylistic changes + displaying a label.
|
||||
// You may be tempted to simply use BeginChild() directly, however note that BeginChild() requires EndChild() to always be called (inconsistent with BeginListBox()/EndListBox()).
|
||||
// BeginListBox() is essentially a thin wrapper to using BeginChild()/EndChild()
|
||||
// using the ImGuiChildFlags_FrameStyle flag for stylistic changes + displaying a label.
|
||||
// You may be tempted to simply use BeginChild() directly. However note that BeginChild() requires EndChild()
|
||||
// to always be called (inconsistent with BeginListBox()/EndListBox()).
|
||||
|
||||
// Using the generic BeginListBox() API, you have full control over how to display the combo contents.
|
||||
// (your selection data could be an index, a pointer to the object, an id for the object, a flag intrusively
|
||||
@@ -1479,6 +1548,7 @@ static void ShowDemoWindowWidgets()
|
||||
HelpMarker("You can use the ImGuiInputTextFlags_CallbackResize facility if you need to wire InputTextMultiline() to a dynamic string type. See misc/cpp/imgui_stdlib.h for an example. (This is not demonstrated in imgui_demo.cpp because we don't want to include <string> in here)");
|
||||
ImGui::CheckboxFlags("ImGuiInputTextFlags_ReadOnly", &flags, ImGuiInputTextFlags_ReadOnly);
|
||||
ImGui::CheckboxFlags("ImGuiInputTextFlags_AllowTabInput", &flags, ImGuiInputTextFlags_AllowTabInput);
|
||||
ImGui::SameLine(); HelpMarker("When _AllowTabInput is set, passing through the widget with Tabbing doesn't automatically activate it, in order to also cycling through subsequent widgets.");
|
||||
ImGui::CheckboxFlags("ImGuiInputTextFlags_CtrlEnterForNewLine", &flags, ImGuiInputTextFlags_CtrlEnterForNewLine);
|
||||
ImGui::InputTextMultiline("##source", text, IM_ARRAYSIZE(text), ImVec2(-FLT_MIN, ImGui::GetTextLineHeight() * 16), flags);
|
||||
ImGui::TreePop();
|
||||
@@ -1569,16 +1639,21 @@ static void ShowDemoWindowWidgets()
|
||||
};
|
||||
static char buf1[64];
|
||||
ImGui::InputText("Completion", buf1, 64, ImGuiInputTextFlags_CallbackCompletion, Funcs::MyCallback);
|
||||
ImGui::SameLine(); HelpMarker("Here we append \"..\" each time Tab is pressed. See 'Examples>Console' for a more meaningful demonstration of using this callback.");
|
||||
ImGui::SameLine(); HelpMarker(
|
||||
"Here we append \"..\" each time Tab is pressed. "
|
||||
"See 'Examples>Console' for a more meaningful demonstration of using this callback.");
|
||||
|
||||
static char buf2[64];
|
||||
ImGui::InputText("History", buf2, 64, ImGuiInputTextFlags_CallbackHistory, Funcs::MyCallback);
|
||||
ImGui::SameLine(); HelpMarker("Here we replace and select text each time Up/Down are pressed. See 'Examples>Console' for a more meaningful demonstration of using this callback.");
|
||||
ImGui::SameLine(); HelpMarker(
|
||||
"Here we replace and select text each time Up/Down are pressed. "
|
||||
"See 'Examples>Console' for a more meaningful demonstration of using this callback.");
|
||||
|
||||
static char buf3[64];
|
||||
static int edit_count = 0;
|
||||
ImGui::InputText("Edit", buf3, 64, ImGuiInputTextFlags_CallbackEdit, Funcs::MyCallback, (void*)&edit_count);
|
||||
ImGui::SameLine(); HelpMarker("Here we toggle the casing of the first character on every edit + count edits.");
|
||||
ImGui::SameLine(); HelpMarker(
|
||||
"Here we toggle the casing of the first character on every edit + count edits.");
|
||||
ImGui::SameLine(); ImGui::Text("(%d)", edit_count);
|
||||
|
||||
ImGui::TreePop();
|
||||
@@ -1753,8 +1828,9 @@ static void ShowDemoWindowWidgets()
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
// Demo Trailing Tabs: click the "+" button to add a new tab (in your app you may want to use a font icon instead of the "+")
|
||||
// Note that we submit it before the regular tabs, but because of the ImGuiTabItemFlags_Trailing flag it will always appear at the end.
|
||||
// Demo Trailing Tabs: click the "+" button to add a new tab.
|
||||
// (In your app you may want to use a font icon instead of the "+")
|
||||
// We submit it before the regular tabs, but thanks to the ImGuiTabItemFlags_Trailing flag it will always appear at the end.
|
||||
if (show_trailing_button)
|
||||
if (ImGui::TabItemButton("+", ImGuiTabItemFlags_Trailing | ImGuiTabItemFlags_NoTooltip))
|
||||
active_tabs.push_back(next_tab_id++); // Add new tab
|
||||
@@ -2038,7 +2114,8 @@ static void ShowDemoWindowWidgets()
|
||||
if (ImGui::Button("Default: Float + HDR + Hue Wheel"))
|
||||
ImGui::SetColorEditOptions(ImGuiColorEditFlags_Float | ImGuiColorEditFlags_HDR | ImGuiColorEditFlags_PickerHueWheel);
|
||||
|
||||
// Always both a small version of both types of pickers (to make it more visible in the demo to people who are skimming quickly through it)
|
||||
// Always display a small version of both types of pickers
|
||||
// (that's in order to make it more visible in the demo to people who are skimming quickly through it)
|
||||
ImGui::Text("Both types:");
|
||||
float w = (ImGui::GetContentRegionAvail().x - ImGui::GetStyle().ItemSpacing.y) * 0.40f;
|
||||
ImGui::SetNextItemWidth(w);
|
||||
@@ -2601,18 +2678,24 @@ static void ShowDemoWindowWidgets()
|
||||
"IsWindowFocused() = %d\n"
|
||||
"IsWindowFocused(_ChildWindows) = %d\n"
|
||||
"IsWindowFocused(_ChildWindows|_NoPopupHierarchy) = %d\n"
|
||||
"IsWindowFocused(_ChildWindows|_DockHierarchy) = %d\n"
|
||||
"IsWindowFocused(_ChildWindows|_RootWindow) = %d\n"
|
||||
"IsWindowFocused(_ChildWindows|_RootWindow|_NoPopupHierarchy) = %d\n"
|
||||
"IsWindowFocused(_ChildWindows|_RootWindow|_DockHierarchy) = %d\n"
|
||||
"IsWindowFocused(_RootWindow) = %d\n"
|
||||
"IsWindowFocused(_RootWindow|_NoPopupHierarchy) = %d\n"
|
||||
"IsWindowFocused(_RootWindow|_DockHierarchy) = %d\n"
|
||||
"IsWindowFocused(_AnyWindow) = %d\n",
|
||||
ImGui::IsWindowFocused(),
|
||||
ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows),
|
||||
ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows | ImGuiFocusedFlags_NoPopupHierarchy),
|
||||
ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows | ImGuiFocusedFlags_DockHierarchy),
|
||||
ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows | ImGuiFocusedFlags_RootWindow),
|
||||
ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows | ImGuiFocusedFlags_RootWindow | ImGuiFocusedFlags_NoPopupHierarchy),
|
||||
ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows | ImGuiFocusedFlags_RootWindow | ImGuiFocusedFlags_DockHierarchy),
|
||||
ImGui::IsWindowFocused(ImGuiFocusedFlags_RootWindow),
|
||||
ImGui::IsWindowFocused(ImGuiFocusedFlags_RootWindow | ImGuiFocusedFlags_NoPopupHierarchy),
|
||||
ImGui::IsWindowFocused(ImGuiFocusedFlags_RootWindow | ImGuiFocusedFlags_DockHierarchy),
|
||||
ImGui::IsWindowFocused(ImGuiFocusedFlags_AnyWindow));
|
||||
|
||||
// Testing IsWindowHovered() function with its various flags.
|
||||
@@ -2622,10 +2705,13 @@ static void ShowDemoWindowWidgets()
|
||||
"IsWindowHovered(_AllowWhenBlockedByActiveItem) = %d\n"
|
||||
"IsWindowHovered(_ChildWindows) = %d\n"
|
||||
"IsWindowHovered(_ChildWindows|_NoPopupHierarchy) = %d\n"
|
||||
"IsWindowHovered(_ChildWindows|_DockHierarchy) = %d\n"
|
||||
"IsWindowHovered(_ChildWindows|_RootWindow) = %d\n"
|
||||
"IsWindowHovered(_ChildWindows|_RootWindow|_NoPopupHierarchy) = %d\n"
|
||||
"IsWindowHovered(_ChildWindows|_RootWindow|_DockHierarchy) = %d\n"
|
||||
"IsWindowHovered(_RootWindow) = %d\n"
|
||||
"IsWindowHovered(_RootWindow|_NoPopupHierarchy) = %d\n"
|
||||
"IsWindowHovered(_RootWindow|_DockHierarchy) = %d\n"
|
||||
"IsWindowHovered(_ChildWindows|_AllowWhenBlockedByPopup) = %d\n"
|
||||
"IsWindowHovered(_AnyWindow) = %d\n"
|
||||
"IsWindowHovered(_Stationary) = %d\n",
|
||||
@@ -2634,10 +2720,13 @@ static void ShowDemoWindowWidgets()
|
||||
ImGui::IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem),
|
||||
ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows),
|
||||
ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_NoPopupHierarchy),
|
||||
ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_DockHierarchy),
|
||||
ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_RootWindow),
|
||||
ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_NoPopupHierarchy),
|
||||
ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_DockHierarchy),
|
||||
ImGui::IsWindowHovered(ImGuiHoveredFlags_RootWindow),
|
||||
ImGui::IsWindowHovered(ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_NoPopupHierarchy),
|
||||
ImGui::IsWindowHovered(ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_DockHierarchy),
|
||||
ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_AllowWhenBlockedByPopup),
|
||||
ImGui::IsWindowHovered(ImGuiHoveredFlags_AnyWindow),
|
||||
ImGui::IsWindowHovered(ImGuiHoveredFlags_Stationary));
|
||||
@@ -2650,10 +2739,13 @@ static void ShowDemoWindowWidgets()
|
||||
|
||||
// Calling IsItemHovered() after begin returns the hovered status of the title bar.
|
||||
// This is useful in particular if you want to create a context menu associated to the title bar of a window.
|
||||
// This will also work when docked into a Tab (the Tab replace the Title Bar and guarantee the same properties).
|
||||
static bool test_window = false;
|
||||
ImGui::Checkbox("Hovered/Active tests after Begin() for title bar testing", &test_window);
|
||||
if (test_window)
|
||||
{
|
||||
// FIXME-DOCK: This window cannot be docked within the ImGui Demo window, this will cause a feedback loop and get them stuck.
|
||||
// Could we fix this through an ImGuiWindowClass feature? Or an API call to tag our parent as "don't skip items"?
|
||||
ImGui::Begin("Title bar Hovered/Active tests", &test_window);
|
||||
if (ImGui::BeginPopupContextItem()) // <-- This is using IsItemHovered()
|
||||
{
|
||||
@@ -3380,7 +3472,9 @@ static void ShowDemoWindowLayout()
|
||||
IMGUI_DEMO_MARKER("Layout/Scrolling/Horizontal contents size demo window");
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(2, 0));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(2, 0));
|
||||
HelpMarker("Test of different widgets react and impact the work rectangle growing when horizontal scrolling is enabled.\n\nUse 'Metrics->Tools->Show windows rectangles' to visualize rectangles.");
|
||||
HelpMarker(
|
||||
"Test how different widgets react and impact the work rectangle growing when horizontal scrolling is enabled.\n\n"
|
||||
"Use 'Metrics->Tools->Show windows rectangles' to visualize rectangles.");
|
||||
ImGui::Checkbox("H-scrollbar", &show_h_scrollbar);
|
||||
ImGui::Checkbox("Button", &show_button); // Will grow contents size (unless explicitly overwritten)
|
||||
ImGui::Checkbox("Tree nodes", &show_tree_nodes); // Will grow contents size and display highlight over full width
|
||||
@@ -3536,7 +3630,8 @@ static void ShowDemoWindowLayout()
|
||||
|
||||
HelpMarker(
|
||||
"Hit-testing is by default performed in item submission order, which generally is perceived as 'back-to-front'.\n\n"
|
||||
"By using SetNextItemAllowOverlap() you can notify that an item may be overlapped by another. Doing so alters the hovering logic: items using AllowOverlap mode requires an extra frame to accept hovered state.");
|
||||
"By using SetNextItemAllowOverlap() you can notify that an item may be overlapped by another. "
|
||||
"Doing so alters the hovering logic: items using AllowOverlap mode requires an extra frame to accept hovered state.");
|
||||
ImGui::Checkbox("Enable AllowOverlap", &enable_allow_overlap);
|
||||
|
||||
ImVec2 button1_pos = ImGui::GetCursorScreenPos();
|
||||
@@ -3923,7 +4018,8 @@ struct MyItem
|
||||
}
|
||||
|
||||
// qsort() is instable so always return a way to differenciate items.
|
||||
// Your own compare function may want to avoid fallback on implicit sort specs e.g. a Name compare if it wasn't already part of the sort specs.
|
||||
// Your own compare function may want to avoid fallback on implicit sort specs.
|
||||
// e.g. a Name compare if it wasn't already part of the sort specs.
|
||||
return (a->ID - b->ID);
|
||||
}
|
||||
};
|
||||
@@ -4106,8 +4202,9 @@ static void ShowDemoWindowTables()
|
||||
// as TableNextColumn() will automatically wrap around and create new rows as needed.
|
||||
// This is generally more convenient when your cells all contains the same type of data.
|
||||
HelpMarker(
|
||||
"Only using TableNextColumn(), which tends to be convenient for tables where every cell contains the same type of contents.\n"
|
||||
"This is also more similar to the old NextColumn() function of the Columns API, and provided to facilitate the Columns->Tables API transition.");
|
||||
"Only using TableNextColumn(), which tends to be convenient for tables where every cell contains "
|
||||
"the same type of contents.\n This is also more similar to the old NextColumn() function of the "
|
||||
"Columns API, and provided to facilitate the Columns->Tables API transition.");
|
||||
if (ImGui::BeginTable("table3", 3))
|
||||
{
|
||||
for (int item = 0; item < 14; item++)
|
||||
@@ -4163,8 +4260,8 @@ static void ShowDemoWindowTables()
|
||||
|
||||
if (ImGui::BeginTable("table1", 3, flags))
|
||||
{
|
||||
// Display headers so we can inspect their interaction with borders.
|
||||
// (Headers are not the main purpose of this section of the demo, so we are not elaborating on them too much. See other sections for details)
|
||||
// Display headers so we can inspect their interaction with borders
|
||||
// (Headers are not the main purpose of this section of the demo, so we are not elaborating on them now. See other sections for details)
|
||||
if (display_headers)
|
||||
{
|
||||
ImGui::TableSetupColumn("One");
|
||||
@@ -4203,7 +4300,9 @@ static void ShowDemoWindowTables()
|
||||
PushStyleCompact();
|
||||
ImGui::CheckboxFlags("ImGuiTableFlags_Resizable", &flags, ImGuiTableFlags_Resizable);
|
||||
ImGui::CheckboxFlags("ImGuiTableFlags_BordersV", &flags, ImGuiTableFlags_BordersV);
|
||||
ImGui::SameLine(); HelpMarker("Using the _Resizable flag automatically enables the _BordersInnerV flag as well, this is why the resize borders are still showing when unchecking this.");
|
||||
ImGui::SameLine(); HelpMarker(
|
||||
"Using the _Resizable flag automatically enables the _BordersInnerV flag as well, "
|
||||
"this is why the resize borders are still showing when unchecking this.");
|
||||
PopStyleCompact();
|
||||
|
||||
if (ImGui::BeginTable("table1", 3, flags))
|
||||
@@ -4344,7 +4443,8 @@ static void ShowDemoWindowTables()
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
// Use outer_size.x == 0.0f instead of default to make the table as tight as possible (only valid when no scrolling and no stretch column)
|
||||
// Use outer_size.x == 0.0f instead of default to make the table as tight as possible
|
||||
// (only valid when no scrolling and no stretch column)
|
||||
if (ImGui::BeginTable("table2", 3, flags | ImGuiTableFlags_SizingFixedFit, ImVec2(0.0f, 0.0f)))
|
||||
{
|
||||
ImGui::TableSetupColumn("One");
|
||||
@@ -4377,7 +4477,8 @@ static void ShowDemoWindowTables()
|
||||
"e.g.:\n"
|
||||
"- BorderOuterV\n"
|
||||
"- any form of row selection\n"
|
||||
"Because of this, activating BorderOuterV sets the default to PadOuterX. Using PadOuterX or NoPadOuterX you can override the default.\n\n"
|
||||
"Because of this, activating BorderOuterV sets the default to PadOuterX. "
|
||||
"Using PadOuterX or NoPadOuterX you can override the default.\n\n"
|
||||
"Actual padding values are using style.CellPadding.\n\n"
|
||||
"In this demo we don't show horizontal borders to emphasize how they don't affect default horizontal padding.");
|
||||
|
||||
@@ -4493,7 +4594,8 @@ static void ShowDemoWindowTables()
|
||||
EditTableSizingFlags(&sizing_policy_flags[table_n]);
|
||||
|
||||
// To make it easier to understand the different sizing policy,
|
||||
// For each policy: we display one table where the columns have equal contents width, and one where the columns have different contents width.
|
||||
// For each policy: we display one table where the columns have equal contents width,
|
||||
// and one where the columns have different contents width.
|
||||
if (ImGui::BeginTable("table1", 3, sizing_policy_flags[table_n] | flags1))
|
||||
{
|
||||
for (int row = 0; row < 3; row++)
|
||||
@@ -4522,7 +4624,9 @@ static void ShowDemoWindowTables()
|
||||
ImGui::Spacing();
|
||||
ImGui::TextUnformatted("Advanced");
|
||||
ImGui::SameLine();
|
||||
HelpMarker("This section allows you to interact and see the effect of various sizing policies depending on whether Scroll is enabled and the contents of your columns.");
|
||||
HelpMarker(
|
||||
"This section allows you to interact and see the effect of various sizing policies "
|
||||
"depending on whether Scroll is enabled and the contents of your columns.");
|
||||
|
||||
enum ContentsType { CT_ShowWidth, CT_ShortText, CT_LongText, CT_Button, CT_FillButton, CT_InputText };
|
||||
static ImGuiTableFlags flags = ImGuiTableFlags_ScrollY | ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_Resizable;
|
||||
@@ -4537,7 +4641,9 @@ static void ShowDemoWindowTables()
|
||||
if (contents_type == CT_FillButton)
|
||||
{
|
||||
ImGui::SameLine();
|
||||
HelpMarker("Be mindful that using right-alignment (e.g. size.x = -FLT_MIN) creates a feedback loop where contents width can feed into auto-column width can feed into contents width.");
|
||||
HelpMarker(
|
||||
"Be mindful that using right-alignment (e.g. size.x = -FLT_MIN) creates a feedback loop "
|
||||
"where contents width can feed into auto-column width can feed into contents width.");
|
||||
}
|
||||
ImGui::DragInt("Columns", &column_count, 0.1f, 1, 64, "%d", ImGuiSliderFlags_AlwaysClamp);
|
||||
ImGui::CheckboxFlags("ImGuiTableFlags_Resizable", &flags, ImGuiTableFlags_Resizable);
|
||||
@@ -4583,7 +4689,9 @@ static void ShowDemoWindowTables()
|
||||
IMGUI_DEMO_MARKER("Tables/Vertical scrolling, with clipping");
|
||||
if (ImGui::TreeNode("Vertical scrolling, with clipping"))
|
||||
{
|
||||
HelpMarker("Here we activate ScrollY, which will create a child window container to allow hosting scrollable contents.\n\nWe also demonstrate using ImGuiListClipper to virtualize the submission of many items.");
|
||||
HelpMarker(
|
||||
"Here we activate ScrollY, which will create a child window container to allow hosting scrollable contents.\n\n"
|
||||
"We also demonstrate using ImGuiListClipper to virtualize the submission of many items.");
|
||||
static ImGuiTableFlags flags = ImGuiTableFlags_ScrollY | ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable;
|
||||
|
||||
PushStyleCompact();
|
||||
@@ -4629,8 +4737,9 @@ static void ShowDemoWindowTables()
|
||||
HelpMarker(
|
||||
"When ScrollX is enabled, the default sizing policy becomes ImGuiTableFlags_SizingFixedFit, "
|
||||
"as automatically stretching columns doesn't make much sense with horizontal scrolling.\n\n"
|
||||
"Also note that as of the current version, you will almost always want to enable ScrollY along with ScrollX,"
|
||||
"because the container window won't automatically extend vertically to fix contents (this may be improved in future versions).");
|
||||
"Also note that as of the current version, you will almost always want to enable ScrollY along with ScrollX, "
|
||||
"because the container window won't automatically extend vertically to fix contents "
|
||||
"(this may be improved in future versions).");
|
||||
static ImGuiTableFlags flags = ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY | ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable;
|
||||
static int freeze_cols = 1;
|
||||
static int freeze_rows = 1;
|
||||
@@ -4687,7 +4796,8 @@ static void ShowDemoWindowTables()
|
||||
HelpMarker(
|
||||
"Showcase using Stretch columns + ScrollX together: "
|
||||
"this is rather unusual and only makes sense when specifying an 'inner_width' for the table!\n"
|
||||
"Without an explicit value, inner_width is == outer_size.x and therefore using Stretch columns + ScrollX together doesn't make sense.");
|
||||
"Without an explicit value, inner_width is == outer_size.x and therefore using Stretch columns "
|
||||
"along with ScrollX doesn't make sense.");
|
||||
static ImGuiTableFlags flags2 = ImGuiTableFlags_SizingStretchSame | ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_RowBg | ImGuiTableFlags_ContextMenuInBody;
|
||||
static float inner_width = 1000.0f;
|
||||
PushStyleCompact();
|
||||
@@ -4745,8 +4855,9 @@ static void ShowDemoWindowTables()
|
||||
}
|
||||
|
||||
// Create the real table we care about for the example!
|
||||
// We use a scrolling table to be able to showcase the difference between the _IsEnabled and _IsVisible flags above, otherwise in
|
||||
// a non-scrolling table columns are always visible (unless using ImGuiTableFlags_NoKeepColumnsVisible + resizing the parent window down)
|
||||
// We use a scrolling table to be able to showcase the difference between the _IsEnabled and _IsVisible flags above,
|
||||
// otherwise in a non-scrolling table columns are always visible (unless using ImGuiTableFlags_NoKeepColumnsVisible
|
||||
// + resizing the parent window down).
|
||||
const ImGuiTableFlags flags
|
||||
= ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY
|
||||
| ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV
|
||||
@@ -4768,7 +4879,8 @@ static void ShowDemoWindowTables()
|
||||
float indent_step = (float)((int)TEXT_BASE_WIDTH / 2);
|
||||
for (int row = 0; row < 8; row++)
|
||||
{
|
||||
ImGui::Indent(indent_step); // Add some indentation to demonstrate usage of per-column IndentEnable/IndentDisable flags.
|
||||
// Add some indentation to demonstrate usage of per-column IndentEnable/IndentDisable flags.
|
||||
ImGui::Indent(indent_step);
|
||||
ImGui::TableNextRow();
|
||||
for (int column = 0; column < column_count; column++)
|
||||
{
|
||||
@@ -4817,7 +4929,9 @@ static void ShowDemoWindowTables()
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
HelpMarker("Using TableSetupColumn() to setup explicit width.\n\nUnless _NoKeepColumnsVisible is set, fixed columns with set width may still be shrunk down if there's not enough space in the host.");
|
||||
HelpMarker(
|
||||
"Using TableSetupColumn() to setup explicit width.\n\nUnless _NoKeepColumnsVisible is set, "
|
||||
"fixed columns with set width may still be shrunk down if there's not enough space in the host.");
|
||||
|
||||
static ImGuiTableFlags flags2 = ImGuiTableFlags_None;
|
||||
PushStyleCompact();
|
||||
@@ -4827,7 +4941,8 @@ static void ShowDemoWindowTables()
|
||||
PopStyleCompact();
|
||||
if (ImGui::BeginTable("table2", 4, flags2))
|
||||
{
|
||||
// We could also set ImGuiTableFlags_SizingFixedFit on the table and all columns will default to ImGuiTableColumnFlags_WidthFixed.
|
||||
// We could also set ImGuiTableFlags_SizingFixedFit on the table and then all columns
|
||||
// will default to ImGuiTableColumnFlags_WidthFixed.
|
||||
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed, 100.0f);
|
||||
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed, TEXT_BASE_WIDTH * 15.0f);
|
||||
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed, TEXT_BASE_WIDTH * 30.0f);
|
||||
@@ -4899,7 +5014,10 @@ static void ShowDemoWindowTables()
|
||||
IMGUI_DEMO_MARKER("Tables/Row height");
|
||||
if (ImGui::TreeNode("Row height"))
|
||||
{
|
||||
HelpMarker("You can pass a 'min_row_height' to TableNextRow().\n\nRows are padded with 'style.CellPadding.y' on top and bottom, so effectively the minimum row height will always be >= 'style.CellPadding.y * 2.0f'.\n\nWe cannot honor a _maximum_ row height as that would require a unique clipping rectangle per row.");
|
||||
HelpMarker(
|
||||
"You can pass a 'min_row_height' to TableNextRow().\n\nRows are padded with 'style.CellPadding.y' on top and bottom, "
|
||||
"so effectively the minimum row height will always be >= 'style.CellPadding.y * 2.0f'.\n\n"
|
||||
"We cannot honor a _maximum_ row height as that would require a unique clipping rectangle per row.");
|
||||
if (ImGui::BeginTable("table_row_height", 1, ImGuiTableFlags_Borders))
|
||||
{
|
||||
for (int row = 0; row < 8; row++)
|
||||
@@ -4912,7 +5030,10 @@ static void ShowDemoWindowTables()
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
HelpMarker("Showcase using SameLine(0,0) to share Current Line Height between cells.\n\nPlease note that Tables Row Height is not the same thing as Current Line Height, as a table cell may contains multiple lines.");
|
||||
HelpMarker(
|
||||
"Showcase using SameLine(0,0) to share Current Line Height between cells.\n\n"
|
||||
"Please note that Tables Row Height is not the same thing as Current Line Height, "
|
||||
"as a table cell may contains multiple lines.");
|
||||
if (ImGui::BeginTable("table_share_lineheight", 2, ImGuiTableFlags_Borders))
|
||||
{
|
||||
ImGui::TableNextRow();
|
||||
@@ -5162,7 +5283,8 @@ static void ShowDemoWindowTables()
|
||||
{
|
||||
HelpMarker(
|
||||
"Showcase using PushItemWidth() and how it is preserved on a per-column basis.\n\n"
|
||||
"Note that on auto-resizing non-resizable fixed columns, querying the content width for e.g. right-alignment doesn't make sense.");
|
||||
"Note that on auto-resizing non-resizable fixed columns, querying the content width for "
|
||||
"e.g. right-alignment doesn't make sense.");
|
||||
if (ImGui::BeginTable("table_item_width", 3, ImGuiTableFlags_Borders))
|
||||
{
|
||||
ImGui::TableSetupColumn("small");
|
||||
@@ -5301,13 +5423,16 @@ static void ShowDemoWindowTables()
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
// Demonstrate creating custom context menus inside columns, while playing it nice with context menus provided by TableHeadersRow()/TableHeader()
|
||||
// Demonstrate creating custom context menus inside columns,
|
||||
// while playing it nice with context menus provided by TableHeadersRow()/TableHeader()
|
||||
if (open_action != -1)
|
||||
ImGui::SetNextItemOpen(open_action != 0);
|
||||
IMGUI_DEMO_MARKER("Tables/Context menus");
|
||||
if (ImGui::TreeNode("Context menus"))
|
||||
{
|
||||
HelpMarker("By default, right-clicking over a TableHeadersRow()/TableHeader() line will open the default context-menu.\nUsing ImGuiTableFlags_ContextMenuInBody we also allow right-clicking over columns body.");
|
||||
HelpMarker(
|
||||
"By default, right-clicking over a TableHeadersRow()/TableHeader() line will open the default context-menu.\n"
|
||||
"Using ImGuiTableFlags_ContextMenuInBody we also allow right-clicking over columns body.");
|
||||
static ImGuiTableFlags flags1 = ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Borders | ImGuiTableFlags_ContextMenuInBody;
|
||||
|
||||
PushStyleCompact();
|
||||
@@ -5344,7 +5469,9 @@ static void ShowDemoWindowTables()
|
||||
// [2.1] Right-click on the TableHeadersRow() line to open the default table context menu.
|
||||
// [2.2] Right-click on the ".." to open a custom popup
|
||||
// [2.3] Right-click in columns to open another custom popup
|
||||
HelpMarker("Demonstrate mixing table context menu (over header), item context button (over button) and custom per-colum context menu (over column body).");
|
||||
HelpMarker(
|
||||
"Demonstrate mixing table context menu (over header), item context button (over button) "
|
||||
"and custom per-colunm context menu (over column body).");
|
||||
ImGuiTableFlags flags2 = ImGuiTableFlags_Resizable | ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Borders;
|
||||
if (ImGui::BeginTable("table_context_menu_2", COLUMNS_COUNT, flags2))
|
||||
{
|
||||
@@ -5803,7 +5930,7 @@ static void ShowDemoWindowTables()
|
||||
// Here we demonstrate marking our data set as needing to be sorted again if we modified a quantity,
|
||||
// and we are currently sorting on the column showing the Quantity.
|
||||
// To avoid triggering a sort while holding the button, we only trigger it when the button has been released.
|
||||
// You will probably need a more advanced system in your code if you want to automatically sort when a specific entry changes.
|
||||
// You will probably need some extra logic if you want to automatically sort when a specific entry changes.
|
||||
if (ImGui::TableSetColumnIndex(2))
|
||||
{
|
||||
if (ImGui::SmallButton("Chop")) { item->Quantity += 1; }
|
||||
@@ -6091,13 +6218,15 @@ static void ShowDemoWindowInputs()
|
||||
for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) if (ImGui::IsMouseDown(i)) { ImGui::SameLine(); ImGui::Text("b%d (%.02f secs)", i, io.MouseDownDuration[i]); }
|
||||
ImGui::Text("Mouse wheel: %.1f", io.MouseWheel);
|
||||
|
||||
// We iterate both legacy native range and named ImGuiKey ranges, which is a little odd but this allows displaying the data for old/new backends.
|
||||
// User code should never have to go through such hoops! You can generally iterate between ImGuiKey_NamedKey_BEGIN and ImGuiKey_NamedKey_END.
|
||||
// We iterate both legacy native range and named ImGuiKey ranges. This is a little unusual/odd but this allows
|
||||
// displaying the data for old/new backends.
|
||||
// User code should never have to go through such hoops!
|
||||
// You can generally iterate between ImGuiKey_NamedKey_BEGIN and ImGuiKey_NamedKey_END.
|
||||
#ifdef IMGUI_DISABLE_OBSOLETE_KEYIO
|
||||
struct funcs { static bool IsLegacyNativeDupe(ImGuiKey) { return false; } };
|
||||
ImGuiKey start_key = ImGuiKey_NamedKey_BEGIN;
|
||||
#else
|
||||
struct funcs { static bool IsLegacyNativeDupe(ImGuiKey key) { return key < 512 && ImGui::GetIO().KeyMap[key] != -1; } }; // Hide Native<>ImGuiKey duplicates when both exists in the array
|
||||
struct funcs { static bool IsLegacyNativeDupe(ImGuiKey key) { return key >= 0 && key < 512 && ImGui::GetIO().KeyMap[key] != -1; } }; // Hide Native<>ImGuiKey duplicates when both exists in the array
|
||||
ImGuiKey start_key = (ImGuiKey)0;
|
||||
#endif
|
||||
ImGui::Text("Keys down:"); for (ImGuiKey key = start_key; key < ImGuiKey_NamedKey_END; key = (ImGuiKey)(key + 1)) { if (funcs::IsLegacyNativeDupe(key) || !ImGui::IsKeyDown(key)) continue; ImGui::SameLine(); ImGui::Text((key < ImGuiKey_NamedKey_BEGIN) ? "\"%s\"" : "\"%s\" %d", ImGui::GetKeyName(key), key); }
|
||||
@@ -6131,7 +6260,8 @@ static void ShowDemoWindowInputs()
|
||||
{
|
||||
HelpMarker(
|
||||
"Hovering the colored canvas will override io.WantCaptureXXX fields.\n"
|
||||
"Notice how normally (when set to none), the value of io.WantCaptureKeyboard would be false when hovering and true when clicking.");
|
||||
"Notice how normally (when set to none), the value of io.WantCaptureKeyboard would be false when hovering "
|
||||
"and true when clicking.");
|
||||
static int capture_override_mouse = -1;
|
||||
static int capture_override_keyboard = -1;
|
||||
const char* capture_override_desc[] = { "None", "Set to false", "Set to true" };
|
||||
@@ -6373,6 +6503,12 @@ void ImGui::ShowAboutWindow(bool* p_open)
|
||||
#endif
|
||||
#ifdef __EMSCRIPTEN__
|
||||
ImGui::Text("define: __EMSCRIPTEN__");
|
||||
#endif
|
||||
#ifdef IMGUI_HAS_VIEWPORT
|
||||
ImGui::Text("define: IMGUI_HAS_VIEWPORT");
|
||||
#endif
|
||||
#ifdef IMGUI_HAS_DOCK
|
||||
ImGui::Text("define: IMGUI_HAS_DOCK");
|
||||
#endif
|
||||
ImGui::Separator();
|
||||
ImGui::Text("io.BackendPlatformName: %s", io.BackendPlatformName ? io.BackendPlatformName : "NULL");
|
||||
@@ -6384,7 +6520,19 @@ void ImGui::ShowAboutWindow(bool* p_open)
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_NavNoCaptureKeyboard) ImGui::Text(" NavNoCaptureKeyboard");
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_NoMouse) ImGui::Text(" NoMouse");
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange) ImGui::Text(" NoMouseCursorChange");
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_DockingEnable) ImGui::Text(" DockingEnable");
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) ImGui::Text(" ViewportsEnable");
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_DpiEnableScaleViewports) ImGui::Text(" DpiEnableScaleViewports");
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_DpiEnableScaleFonts) ImGui::Text(" DpiEnableScaleFonts");
|
||||
if (io.MouseDrawCursor) ImGui::Text("io.MouseDrawCursor");
|
||||
if (io.ConfigViewportsNoAutoMerge) ImGui::Text("io.ConfigViewportsNoAutoMerge");
|
||||
if (io.ConfigViewportsNoTaskBarIcon) ImGui::Text("io.ConfigViewportsNoTaskBarIcon");
|
||||
if (io.ConfigViewportsNoDecoration) ImGui::Text("io.ConfigViewportsNoDecoration");
|
||||
if (io.ConfigViewportsNoDefaultParent) ImGui::Text("io.ConfigViewportsNoDefaultParent");
|
||||
if (io.ConfigDockingNoSplit) ImGui::Text("io.ConfigDockingNoSplit");
|
||||
if (io.ConfigDockingWithShift) ImGui::Text("io.ConfigDockingWithShift");
|
||||
if (io.ConfigDockingAlwaysTabBar) ImGui::Text("io.ConfigDockingAlwaysTabBar");
|
||||
if (io.ConfigDockingTransparentPayload) ImGui::Text("io.ConfigDockingTransparentPayload");
|
||||
if (io.ConfigMacOSXBehaviors) ImGui::Text("io.ConfigMacOSXBehaviors");
|
||||
if (io.ConfigInputTextCursorBlink) ImGui::Text("io.ConfigInputTextCursorBlink");
|
||||
if (io.ConfigWindowsResizeFromEdges) ImGui::Text("io.ConfigWindowsResizeFromEdges");
|
||||
@@ -6394,7 +6542,10 @@ void ImGui::ShowAboutWindow(bool* p_open)
|
||||
if (io.BackendFlags & ImGuiBackendFlags_HasGamepad) ImGui::Text(" HasGamepad");
|
||||
if (io.BackendFlags & ImGuiBackendFlags_HasMouseCursors) ImGui::Text(" HasMouseCursors");
|
||||
if (io.BackendFlags & ImGuiBackendFlags_HasSetMousePos) ImGui::Text(" HasSetMousePos");
|
||||
if (io.BackendFlags & ImGuiBackendFlags_PlatformHasViewports) ImGui::Text(" PlatformHasViewports");
|
||||
if (io.BackendFlags & ImGuiBackendFlags_HasMouseHoveredViewport)ImGui::Text(" HasMouseHoveredViewport");
|
||||
if (io.BackendFlags & ImGuiBackendFlags_RendererHasVtxOffset) ImGui::Text(" RendererHasVtxOffset");
|
||||
if (io.BackendFlags & ImGuiBackendFlags_RendererHasViewports) ImGui::Text(" RendererHasViewports");
|
||||
ImGui::Separator();
|
||||
ImGui::Text("io.Fonts: %d fonts, Flags: 0x%08X, TexSize: %d,%d", io.Fonts->Fonts.Size, io.Fonts->Flags, io.Fonts->TexWidth, io.Fonts->TexHeight);
|
||||
ImGui::Text("io.DisplaySize: %.2f,%.2f", io.DisplaySize.x, io.DisplaySize.y);
|
||||
@@ -6567,6 +6718,9 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
|
||||
ImGui::SliderFloat2("SeparatorTextPadding", (float*)&style.SeparatorTextPadding, 0.0f, 40.0f, "%.0f");
|
||||
ImGui::SliderFloat("LogSliderDeadzone", &style.LogSliderDeadzone, 0.0f, 12.0f, "%.0f");
|
||||
|
||||
ImGui::SeparatorText("Docking");
|
||||
ImGui::SliderFloat("DockingSplitterSize", &style.DockingSeparatorSize, 0.0f, 12.0f, "%.0f");
|
||||
|
||||
ImGui::SeparatorText("Tooltips");
|
||||
for (int n = 0; n < 2; n++)
|
||||
if (ImGui::TreeNodeEx(n == 0 ? "HoverFlagsForTooltipMouse" : "HoverFlagsForTooltipNav"))
|
||||
@@ -6631,6 +6785,12 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
|
||||
if (!filter.PassFilter(name))
|
||||
continue;
|
||||
ImGui::PushID(i);
|
||||
#ifndef IMGUI_DISABLE_DEBUG_TOOLS
|
||||
if (ImGui::Button("?"))
|
||||
ImGui::DebugFlashStyleColor((ImGuiCol)i);
|
||||
ImGui::SetItemTooltip("Flash given color to identify places where it is used.");
|
||||
ImGui::SameLine();
|
||||
#endif
|
||||
ImGui::ColorEdit4("##color", (float*)&style.Colors[i], ImGuiColorEditFlags_AlphaBar | alpha_flags);
|
||||
if (memcmp(&style.Colors[i], &ref->Colors[i], sizeof(ImVec4)) != 0)
|
||||
{
|
||||
@@ -7745,6 +7905,8 @@ static void ShowExampleAppConstrainedResize(bool* p_open)
|
||||
else
|
||||
{
|
||||
ImGui::Text("(Hold SHIFT to display a dummy viewport)");
|
||||
if (ImGui::IsWindowDocked())
|
||||
ImGui::Text("Warning: Sizing Constraints won't work if the window is docked!");
|
||||
if (ImGui::Button("Set 200x200")) { ImGui::SetWindowSize(ImVec2(200, 200)); } ImGui::SameLine();
|
||||
if (ImGui::Button("Set 500x500")) { ImGui::SetWindowSize(ImVec2(500, 500)); } ImGui::SameLine();
|
||||
if (ImGui::Button("Set 800x200")) { ImGui::SetWindowSize(ImVec2(800, 200)); }
|
||||
@@ -7771,7 +7933,7 @@ static void ShowExampleAppSimpleOverlay(bool* p_open)
|
||||
{
|
||||
static int location = 0;
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav;
|
||||
ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav;
|
||||
if (location >= 0)
|
||||
{
|
||||
const float PAD = 10.0f;
|
||||
@@ -7784,6 +7946,7 @@ static void ShowExampleAppSimpleOverlay(bool* p_open)
|
||||
window_pos_pivot.x = (location & 1) ? 1.0f : 0.0f;
|
||||
window_pos_pivot.y = (location & 2) ? 1.0f : 0.0f;
|
||||
ImGui::SetNextWindowPos(window_pos, ImGuiCond_Always, window_pos_pivot);
|
||||
ImGui::SetNextWindowViewport(viewport->ID);
|
||||
window_flags |= ImGuiWindowFlags_NoMove;
|
||||
}
|
||||
else if (location == -2)
|
||||
@@ -8170,6 +8333,134 @@ static void ShowExampleAppCustomRendering(bool* p_open)
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] Example App: Docking, DockSpace / ShowExampleAppDockSpace()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Demonstrate using DockSpace() to create an explicit docking node within an existing window.
|
||||
// Note: You can use most Docking facilities without calling any API. You DO NOT need to call DockSpace() to use Docking!
|
||||
// - Drag from window title bar or their tab to dock/undock. Hold SHIFT to disable docking.
|
||||
// - Drag from window menu button (upper-left button) to undock an entire node (all windows).
|
||||
// - When io.ConfigDockingWithShift == true, you instead need to hold SHIFT to enable docking.
|
||||
// About dockspaces:
|
||||
// - Use DockSpace() to create an explicit dock node _within_ an existing window.
|
||||
// - Use DockSpaceOverViewport() to create an explicit dock node covering the screen or a specific viewport.
|
||||
// This is often used with ImGuiDockNodeFlags_PassthruCentralNode.
|
||||
// - Important: Dockspaces need to be submitted _before_ any window they can host. Submit it early in your frame! (*)
|
||||
// - Important: Dockspaces need to be kept alive if hidden, otherwise windows docked into it will be undocked.
|
||||
// e.g. if you have multiple tabs with a dockspace inside each tab: submit the non-visible dockspaces with ImGuiDockNodeFlags_KeepAliveOnly.
|
||||
// (*) because of this constraint, the implicit \"Debug\" window can not be docked into an explicit DockSpace() node,
|
||||
// because that window is submitted as part of the part of the NewFrame() call. An easy workaround is that you can create
|
||||
// your own implicit "Debug##2" window after calling DockSpace() and leave it in the window stack for anyone to use.
|
||||
void ShowExampleAppDockSpace(bool* p_open)
|
||||
{
|
||||
// READ THIS !!!
|
||||
// TL;DR; this demo is more complicated than what most users you would normally use.
|
||||
// If we remove all options we are showcasing, this demo would become:
|
||||
// void ShowExampleAppDockSpace()
|
||||
// {
|
||||
// ImGui::DockSpaceOverViewport(ImGui::GetMainViewport());
|
||||
// }
|
||||
// In most cases you should be able to just call DockSpaceOverViewport() and ignore all the code below!
|
||||
// In this specific demo, we are not using DockSpaceOverViewport() because:
|
||||
// - (1) we allow the host window to be floating/moveable instead of filling the viewport (when opt_fullscreen == false)
|
||||
// - (2) we allow the host window to have padding (when opt_padding == true)
|
||||
// - (3) we expose many flags and need a way to have them visible.
|
||||
// - (4) we have a local menu bar in the host window (vs. you could use BeginMainMenuBar() + DockSpaceOverViewport()
|
||||
// in your code, but we don't here because we allow the window to be floating)
|
||||
|
||||
static bool opt_fullscreen = true;
|
||||
static bool opt_padding = false;
|
||||
static ImGuiDockNodeFlags dockspace_flags = ImGuiDockNodeFlags_None;
|
||||
|
||||
// We are using the ImGuiWindowFlags_NoDocking flag to make the parent window not dockable into,
|
||||
// because it would be confusing to have two docking targets within each others.
|
||||
ImGuiWindowFlags window_flags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking;
|
||||
if (opt_fullscreen)
|
||||
{
|
||||
const ImGuiViewport* viewport = ImGui::GetMainViewport();
|
||||
ImGui::SetNextWindowPos(viewport->WorkPos);
|
||||
ImGui::SetNextWindowSize(viewport->WorkSize);
|
||||
ImGui::SetNextWindowViewport(viewport->ID);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
|
||||
window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove;
|
||||
window_flags |= ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus;
|
||||
}
|
||||
else
|
||||
{
|
||||
dockspace_flags &= ~ImGuiDockNodeFlags_PassthruCentralNode;
|
||||
}
|
||||
|
||||
// When using ImGuiDockNodeFlags_PassthruCentralNode, DockSpace() will render our background
|
||||
// and handle the pass-thru hole, so we ask Begin() to not render a background.
|
||||
if (dockspace_flags & ImGuiDockNodeFlags_PassthruCentralNode)
|
||||
window_flags |= ImGuiWindowFlags_NoBackground;
|
||||
|
||||
// Important: note that we proceed even if Begin() returns false (aka window is collapsed).
|
||||
// This is because we want to keep our DockSpace() active. If a DockSpace() is inactive,
|
||||
// all active windows docked into it will lose their parent and become undocked.
|
||||
// We cannot preserve the docking relationship between an active window and an inactive docking, otherwise
|
||||
// any change of dockspace/settings would lead to windows being stuck in limbo and never being visible.
|
||||
if (!opt_padding)
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
|
||||
ImGui::Begin("DockSpace Demo", p_open, window_flags);
|
||||
if (!opt_padding)
|
||||
ImGui::PopStyleVar();
|
||||
|
||||
if (opt_fullscreen)
|
||||
ImGui::PopStyleVar(2);
|
||||
|
||||
// Submit the DockSpace
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_DockingEnable)
|
||||
{
|
||||
ImGuiID dockspace_id = ImGui::GetID("MyDockSpace");
|
||||
ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspace_flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowDockingDisabledMessage();
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenuBar())
|
||||
{
|
||||
if (ImGui::BeginMenu("Options"))
|
||||
{
|
||||
// Disabling fullscreen would allow the window to be moved to the front of other windows,
|
||||
// which we can't undo at the moment without finer window depth/z control.
|
||||
ImGui::MenuItem("Fullscreen", NULL, &opt_fullscreen);
|
||||
ImGui::MenuItem("Padding", NULL, &opt_padding);
|
||||
ImGui::Separator();
|
||||
|
||||
if (ImGui::MenuItem("Flag: NoDockingOverCentralNode", "", (dockspace_flags & ImGuiDockNodeFlags_NoDockingOverCentralNode) != 0)) { dockspace_flags ^= ImGuiDockNodeFlags_NoDockingOverCentralNode; }
|
||||
if (ImGui::MenuItem("Flag: NoDockingSplit", "", (dockspace_flags & ImGuiDockNodeFlags_NoDockingSplit) != 0)) { dockspace_flags ^= ImGuiDockNodeFlags_NoDockingSplit; }
|
||||
if (ImGui::MenuItem("Flag: NoUndocking", "", (dockspace_flags & ImGuiDockNodeFlags_NoUndocking) != 0)) { dockspace_flags ^= ImGuiDockNodeFlags_NoUndocking; }
|
||||
if (ImGui::MenuItem("Flag: NoResize", "", (dockspace_flags & ImGuiDockNodeFlags_NoResize) != 0)) { dockspace_flags ^= ImGuiDockNodeFlags_NoResize; }
|
||||
if (ImGui::MenuItem("Flag: AutoHideTabBar", "", (dockspace_flags & ImGuiDockNodeFlags_AutoHideTabBar) != 0)) { dockspace_flags ^= ImGuiDockNodeFlags_AutoHideTabBar; }
|
||||
if (ImGui::MenuItem("Flag: PassthruCentralNode", "", (dockspace_flags & ImGuiDockNodeFlags_PassthruCentralNode) != 0, opt_fullscreen)) { dockspace_flags ^= ImGuiDockNodeFlags_PassthruCentralNode; }
|
||||
ImGui::Separator();
|
||||
|
||||
if (ImGui::MenuItem("Close", NULL, false, p_open != NULL))
|
||||
*p_open = false;
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
HelpMarker(
|
||||
"When docking is enabled, you can ALWAYS dock MOST window into another! Try it now!" "\n"
|
||||
"- Drag from window title bar or their tab to dock/undock." "\n"
|
||||
"- Drag from window menu button (upper-left button) to undock an entire node (all windows)." "\n"
|
||||
"- Hold SHIFT to disable docking (if io.ConfigDockingWithShift == false, default)" "\n"
|
||||
"- Hold SHIFT to enable docking (if io.ConfigDockingWithShift == true)" "\n"
|
||||
"This demo app has nothing to do with enabling docking!" "\n\n"
|
||||
"This demo app only demonstrate the use of ImGui::DockSpace() which allows you to manually create a docking node _within_ another window." "\n\n"
|
||||
"Read comments in ShowExampleAppDockSpace() for more details.");
|
||||
|
||||
ImGui::EndMenuBar();
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] Example App: Documents Handling / ShowExampleAppDocuments()
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -8268,11 +8559,25 @@ void ShowExampleAppDocuments(bool* p_open)
|
||||
static ExampleAppDocuments app;
|
||||
|
||||
// Options
|
||||
enum Target
|
||||
{
|
||||
Target_None,
|
||||
Target_Tab, // Create documents as local tab into a local tab bar
|
||||
Target_DockSpaceAndWindow // Create documents as regular windows, and create an embedded dockspace
|
||||
};
|
||||
static Target opt_target = Target_Tab;
|
||||
static bool opt_reorderable = true;
|
||||
static ImGuiTabBarFlags opt_fitting_flags = ImGuiTabBarFlags_FittingPolicyDefault_;
|
||||
|
||||
// When (opt_target == Target_DockSpaceAndWindow) there is the possibily that one of our child Document window (e.g. "Eggplant")
|
||||
// that we emit gets docked into the same spot as the parent window ("Example: Documents").
|
||||
// This would create a problematic feedback loop because selecting the "Eggplant" tab would make the "Example: Documents" tab
|
||||
// not visible, which in turn would stop submitting the "Eggplant" window.
|
||||
// We avoid this problem by submitting our documents window even if our parent window is not currently visible.
|
||||
// Another solution may be to make the "Example: Documents" window use the ImGuiWindowFlags_NoDocking.
|
||||
|
||||
bool window_contents_visible = ImGui::Begin("Example: Documents", p_open, ImGuiWindowFlags_MenuBar);
|
||||
if (!window_contents_visible)
|
||||
if (!window_contents_visible && opt_target != Target_DockSpaceAndWindow)
|
||||
{
|
||||
ImGui::End();
|
||||
return;
|
||||
@@ -8316,6 +8621,12 @@ void ShowExampleAppDocuments(bool* p_open)
|
||||
doc.DoForceClose();
|
||||
ImGui::PopID();
|
||||
}
|
||||
ImGui::PushItemWidth(ImGui::GetFontSize() * 12);
|
||||
ImGui::Combo("Output", (int*)&opt_target, "None\0TabBar+Tabs\0DockSpace+Window\0");
|
||||
ImGui::PopItemWidth();
|
||||
bool redock_all = false;
|
||||
if (opt_target == Target_Tab) { ImGui::SameLine(); ImGui::Checkbox("Reorderable Tabs", &opt_reorderable); }
|
||||
if (opt_target == Target_DockSpaceAndWindow) { ImGui::SameLine(); redock_all = ImGui::Button("Redock all"); }
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
@@ -8329,7 +8640,8 @@ void ShowExampleAppDocuments(bool* p_open)
|
||||
// hole for one-frame, both in the tab-bar and in tab-contents when closing a tab/window.
|
||||
// The rarely used SetTabItemClosed() function is a way to notify of programmatic closure to avoid the one-frame hole.
|
||||
|
||||
// Submit Tab Bar and Tabs
|
||||
// Tabs
|
||||
if (opt_target == Target_Tab)
|
||||
{
|
||||
ImGuiTabBarFlags tab_bar_flags = (opt_fitting_flags) | (opt_reorderable ? ImGuiTabBarFlags_Reorderable : 0);
|
||||
if (ImGui::BeginTabBar("##tabs", tab_bar_flags))
|
||||
@@ -8368,6 +8680,53 @@ void ShowExampleAppDocuments(bool* p_open)
|
||||
ImGui::EndTabBar();
|
||||
}
|
||||
}
|
||||
else if (opt_target == Target_DockSpaceAndWindow)
|
||||
{
|
||||
if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_DockingEnable)
|
||||
{
|
||||
NotifyOfDocumentsClosedElsewhere(app);
|
||||
|
||||
// Create a DockSpace node where any window can be docked
|
||||
ImGuiID dockspace_id = ImGui::GetID("MyDockSpace");
|
||||
ImGui::DockSpace(dockspace_id);
|
||||
|
||||
// Create Windows
|
||||
for (int doc_n = 0; doc_n < app.Documents.Size; doc_n++)
|
||||
{
|
||||
MyDocument* doc = &app.Documents[doc_n];
|
||||
if (!doc->Open)
|
||||
continue;
|
||||
|
||||
ImGui::SetNextWindowDockID(dockspace_id, redock_all ? ImGuiCond_Always : ImGuiCond_FirstUseEver);
|
||||
ImGuiWindowFlags window_flags = (doc->Dirty ? ImGuiWindowFlags_UnsavedDocument : 0);
|
||||
bool visible = ImGui::Begin(doc->Name, &doc->Open, window_flags);
|
||||
|
||||
// Cancel attempt to close when unsaved add to save queue so we can display a popup.
|
||||
if (!doc->Open && doc->Dirty)
|
||||
{
|
||||
doc->Open = true;
|
||||
doc->DoQueueClose();
|
||||
}
|
||||
|
||||
MyDocument::DisplayContextMenu(doc);
|
||||
if (visible)
|
||||
MyDocument::DisplayContents(doc);
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowDockingDisabledMessage();
|
||||
}
|
||||
}
|
||||
|
||||
// Early out other contents
|
||||
if (!window_contents_visible)
|
||||
{
|
||||
ImGui::End();
|
||||
return;
|
||||
}
|
||||
|
||||
// Update closing queue
|
||||
static ImVector<MyDocument*> close_queue;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.90.0
|
||||
// dear imgui, v1.90.1
|
||||
// (drawing and font code)
|
||||
|
||||
/*
|
||||
@@ -214,6 +214,8 @@ void ImGui::StyleColorsDark(ImGuiStyle* dst)
|
||||
colors[ImGuiCol_TabActive] = ImLerp(colors[ImGuiCol_HeaderActive], colors[ImGuiCol_TitleBgActive], 0.60f);
|
||||
colors[ImGuiCol_TabUnfocused] = ImLerp(colors[ImGuiCol_Tab], colors[ImGuiCol_TitleBg], 0.80f);
|
||||
colors[ImGuiCol_TabUnfocusedActive] = ImLerp(colors[ImGuiCol_TabActive], colors[ImGuiCol_TitleBg], 0.40f);
|
||||
colors[ImGuiCol_DockingPreview] = colors[ImGuiCol_HeaderActive] * ImVec4(1.0f, 1.0f, 1.0f, 0.7f);
|
||||
colors[ImGuiCol_DockingEmptyBg] = ImVec4(0.20f, 0.20f, 0.20f, 1.00f);
|
||||
colors[ImGuiCol_PlotLines] = ImVec4(0.61f, 0.61f, 0.61f, 1.00f);
|
||||
colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f);
|
||||
colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f);
|
||||
@@ -274,6 +276,8 @@ void ImGui::StyleColorsClassic(ImGuiStyle* dst)
|
||||
colors[ImGuiCol_TabActive] = ImLerp(colors[ImGuiCol_HeaderActive], colors[ImGuiCol_TitleBgActive], 0.60f);
|
||||
colors[ImGuiCol_TabUnfocused] = ImLerp(colors[ImGuiCol_Tab], colors[ImGuiCol_TitleBg], 0.80f);
|
||||
colors[ImGuiCol_TabUnfocusedActive] = ImLerp(colors[ImGuiCol_TabActive], colors[ImGuiCol_TitleBg], 0.40f);
|
||||
colors[ImGuiCol_DockingPreview] = colors[ImGuiCol_Header] * ImVec4(1.0f, 1.0f, 1.0f, 0.7f);
|
||||
colors[ImGuiCol_DockingEmptyBg] = ImVec4(0.20f, 0.20f, 0.20f, 1.00f);
|
||||
colors[ImGuiCol_PlotLines] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
|
||||
colors[ImGuiCol_PlotLinesHovered] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f);
|
||||
colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f);
|
||||
@@ -335,6 +339,8 @@ void ImGui::StyleColorsLight(ImGuiStyle* dst)
|
||||
colors[ImGuiCol_TabActive] = ImLerp(colors[ImGuiCol_HeaderActive], colors[ImGuiCol_TitleBgActive], 0.60f);
|
||||
colors[ImGuiCol_TabUnfocused] = ImLerp(colors[ImGuiCol_Tab], colors[ImGuiCol_TitleBg], 0.80f);
|
||||
colors[ImGuiCol_TabUnfocusedActive] = ImLerp(colors[ImGuiCol_TabActive], colors[ImGuiCol_TitleBg], 0.40f);
|
||||
colors[ImGuiCol_DockingPreview] = colors[ImGuiCol_Header] * ImVec4(1.0f, 1.0f, 1.0f, 0.7f);
|
||||
colors[ImGuiCol_DockingEmptyBg] = ImVec4(0.20f, 0.20f, 0.20f, 1.00f);
|
||||
colors[ImGuiCol_PlotLines] = ImVec4(0.39f, 0.39f, 0.39f, 1.00f);
|
||||
colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f);
|
||||
colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f);
|
||||
@@ -3881,6 +3887,7 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, Im
|
||||
// - RenderArrow()
|
||||
// - RenderBullet()
|
||||
// - RenderCheckMark()
|
||||
// - RenderArrowDockMenu()
|
||||
// - RenderArrowPointingAt()
|
||||
// - RenderRectFilledRangeH()
|
||||
// - RenderRectFilledWithHole()
|
||||
@@ -3955,6 +3962,14 @@ void ImGui::RenderArrowPointingAt(ImDrawList* draw_list, ImVec2 pos, ImVec2 half
|
||||
}
|
||||
}
|
||||
|
||||
// This is less wide than RenderArrow() and we use in dock nodes instead of the regular RenderArrow() to denote a change of functionality,
|
||||
// and because the saved space means that the left-most tab label can stay at exactly the same position as the label of a loose window.
|
||||
void ImGui::RenderArrowDockMenu(ImDrawList* draw_list, ImVec2 p_min, float sz, ImU32 col)
|
||||
{
|
||||
draw_list->AddRectFilled(p_min + ImVec2(sz * 0.20f, sz * 0.15f), p_min + ImVec2(sz * 0.80f, sz * 0.30f), col);
|
||||
RenderArrowPointingAt(draw_list, p_min + ImVec2(sz * 0.50f, sz * 0.85f), ImVec2(sz * 0.30f, sz * 0.40f), ImGuiDir_Down, col);
|
||||
}
|
||||
|
||||
static inline float ImAcos01(float x)
|
||||
{
|
||||
if (x <= 0.0f) return IM_PI * 0.5f;
|
||||
@@ -4040,6 +4055,17 @@ void ImGui::RenderRectFilledWithHole(ImDrawList* draw_list, const ImRect& outer,
|
||||
if (fill_R && fill_D) draw_list->AddRectFilled(ImVec2(inner.Max.x, inner.Max.y), ImVec2(outer.Max.x, outer.Max.y), col, rounding, ImDrawFlags_RoundCornersBottomRight);
|
||||
}
|
||||
|
||||
ImDrawFlags ImGui::CalcRoundingFlagsForRectInRect(const ImRect& r_in, const ImRect& r_outer, float threshold)
|
||||
{
|
||||
bool round_l = r_in.Min.x <= r_outer.Min.x + threshold;
|
||||
bool round_r = r_in.Max.x >= r_outer.Max.x - threshold;
|
||||
bool round_t = r_in.Min.y <= r_outer.Min.y + threshold;
|
||||
bool round_b = r_in.Max.y >= r_outer.Max.y - threshold;
|
||||
return ImDrawFlags_RoundCornersNone
|
||||
| ((round_t && round_l) ? ImDrawFlags_RoundCornersTopLeft : 0) | ((round_t && round_r) ? ImDrawFlags_RoundCornersTopRight : 0)
|
||||
| ((round_b && round_l) ? ImDrawFlags_RoundCornersBottomLeft : 0) | ((round_b && round_r) ? ImDrawFlags_RoundCornersBottomRight : 0);
|
||||
}
|
||||
|
||||
// Helper for ColorPicker4()
|
||||
// NB: This is rather brittle and will show artifact when rounding this enabled if rounded corners overlap multiple cells. Caller currently responsible for avoiding that.
|
||||
// Spent a non reasonable amount of time trying to getting this right for ColorButton with rounding+anti-aliasing+ImGuiColorEditFlags_HalfAlphaPreview flag + various grid sizes and offsets, and eventually gave up... probably more reasonable to disable rounding altogether.
|
||||
@@ -4205,8 +4231,8 @@ static unsigned int stb_decompress(unsigned char *output, const unsigned char *i
|
||||
//-----------------------------------------------------------------------------
|
||||
// ProggyClean.ttf
|
||||
// Copyright (c) 2004, 2005 Tristan Grimmer
|
||||
// MIT license (see License.txt in http://www.upperbounds.net/download/ProggyClean.ttf.zip)
|
||||
// Download and more information at http://upperbounds.net
|
||||
// MIT license (see License.txt in http://www.proggyfonts.net/index.php?menu=download)
|
||||
// Download and more information at http://www.proggyfonts.net or http://upperboundsinteractive.com/fonts.php
|
||||
//-----------------------------------------------------------------------------
|
||||
// File: 'ProggyClean.ttf' (41208 bytes)
|
||||
// Exported using misc/fonts/binary_to_compressed_c.cpp (with compression + base85 string encoding).
|
||||
|
||||
499
imgui_internal.h
499
imgui_internal.h
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.90.0
|
||||
// dear imgui, v1.90.1
|
||||
// (internal structures/api)
|
||||
|
||||
// You may use this file to debug, understand or extend Dear ImGui features but we don't provide any guarantee of forward compatibility.
|
||||
@@ -124,6 +124,10 @@ struct ImGuiContext; // Main Dear ImGui context
|
||||
struct ImGuiContextHook; // Hook for extensions like ImGuiTestEngine
|
||||
struct ImGuiDataVarInfo; // Variable information (e.g. to avoid style variables from an enum)
|
||||
struct ImGuiDataTypeInfo; // Type information associated to a ImGuiDataType enum
|
||||
struct ImGuiDockContext; // Docking system context
|
||||
struct ImGuiDockRequest; // Docking system dock/undock queued request
|
||||
struct ImGuiDockNode; // Docking system node (hold a list of Windows OR two child dock nodes)
|
||||
struct ImGuiDockNodeSettings; // Storage for a dock node in .ini file (we preserve those even if the associated dock node isn't active during the session)
|
||||
struct ImGuiGroupData; // Stacked storage data for BeginGroup()/EndGroup()
|
||||
struct ImGuiInputTextState; // Internal state of the currently focused/edited text input box
|
||||
struct ImGuiInputTextDeactivateData;// Short term storage to backup text of a deactivating InputText() while another is stealing active id
|
||||
@@ -158,6 +162,7 @@ struct ImGuiWindowSettings; // Storage for a window .ini settings (we ke
|
||||
// Enumerations
|
||||
// Use your programming IDE "Go to definition" facility on the names of the center columns to find the actual flags/enum lists.
|
||||
enum ImGuiLocKey : int; // -> enum ImGuiLocKey // Enum: a localization entry for translation.
|
||||
typedef int ImGuiDataAuthority; // -> enum ImGuiDataAuthority_ // Enum: for storing the source authority (dock node vs window) of a field
|
||||
typedef int ImGuiLayoutType; // -> enum ImGuiLayoutType_ // Enum: Horizontal or vertical
|
||||
|
||||
// Flags
|
||||
@@ -196,13 +201,13 @@ extern IMGUI_API ImGuiContext* GImGui; // Current implicit context pointer
|
||||
namespace ImStb
|
||||
{
|
||||
|
||||
#undef STB_TEXTEDIT_STRING
|
||||
#undef STB_TEXTEDIT_CHARTYPE
|
||||
#define STB_TEXTEDIT_STRING ImGuiInputTextState
|
||||
#define STB_TEXTEDIT_CHARTYPE ImWchar
|
||||
#define STB_TEXTEDIT_GETWIDTH_NEWLINE (-1.0f)
|
||||
#define STB_TEXTEDIT_UNDOSTATECOUNT 99
|
||||
#define STB_TEXTEDIT_UNDOCHARCOUNT 999
|
||||
#undef IMSTB_TEXTEDIT_STRING
|
||||
#undef IMSTB_TEXTEDIT_CHARTYPE
|
||||
#define IMSTB_TEXTEDIT_STRING ImGuiInputTextState
|
||||
#define IMSTB_TEXTEDIT_CHARTYPE ImWchar
|
||||
#define IMSTB_TEXTEDIT_GETWIDTH_NEWLINE (-1.0f)
|
||||
#define IMSTB_TEXTEDIT_UNDOSTATECOUNT 99
|
||||
#define IMSTB_TEXTEDIT_UNDOCHARCOUNT 999
|
||||
#include "imstb_textedit.h"
|
||||
|
||||
} // namespace ImStb
|
||||
@@ -211,6 +216,9 @@ namespace ImStb
|
||||
// [SECTION] Macros
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Internal Drag and Drop payload types. String starting with '_' are reserved for Dear ImGui.
|
||||
#define IMGUI_PAYLOAD_TYPE_WINDOW "_IMWINDOW" // Payload == ImGuiWindow*
|
||||
|
||||
// Debug Printing Into TTY
|
||||
// (since IMGUI_VERSION_NUM >= 18729: IMGUI_DEBUG_LOG was reworked into IMGUI_DEBUG_PRINTF (and removed framecount from it). If you were using a #define IMGUI_DEBUG_LOG please rename)
|
||||
#ifndef IMGUI_DEBUG_PRINTF
|
||||
@@ -227,13 +235,15 @@ namespace ImStb
|
||||
#else
|
||||
#define IMGUI_DEBUG_LOG(...) ((void)0)
|
||||
#endif
|
||||
#define IMGUI_DEBUG_LOG_ACTIVEID(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventActiveId) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
|
||||
#define IMGUI_DEBUG_LOG_FOCUS(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventFocus) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
|
||||
#define IMGUI_DEBUG_LOG_POPUP(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventPopup) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
|
||||
#define IMGUI_DEBUG_LOG_NAV(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventNav) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
|
||||
#define IMGUI_DEBUG_LOG_SELECTION(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventSelection)IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
|
||||
#define IMGUI_DEBUG_LOG_CLIPPER(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventClipper) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
|
||||
#define IMGUI_DEBUG_LOG_IO(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventIO) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
|
||||
#define IMGUI_DEBUG_LOG_ACTIVEID(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventActiveId) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
|
||||
#define IMGUI_DEBUG_LOG_FOCUS(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventFocus) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
|
||||
#define IMGUI_DEBUG_LOG_POPUP(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventPopup) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
|
||||
#define IMGUI_DEBUG_LOG_NAV(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventNav) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
|
||||
#define IMGUI_DEBUG_LOG_SELECTION(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventSelection) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
|
||||
#define IMGUI_DEBUG_LOG_CLIPPER(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventClipper) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
|
||||
#define IMGUI_DEBUG_LOG_IO(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventIO) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
|
||||
#define IMGUI_DEBUG_LOG_DOCKING(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventDocking) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
|
||||
#define IMGUI_DEBUG_LOG_VIEWPORT(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventViewport) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
|
||||
|
||||
// Static Asserts
|
||||
#define IM_STATIC_ASSERT(_COND) static_assert(_COND, "")
|
||||
@@ -835,8 +845,8 @@ enum ImGuiItemStatusFlags_
|
||||
ImGuiItemStatusFlags_HasDeactivated = 1 << 5, // Set if the widget/group is able to provide data for the ImGuiItemStatusFlags_Deactivated flag.
|
||||
ImGuiItemStatusFlags_Deactivated = 1 << 6, // Only valid if ImGuiItemStatusFlags_HasDeactivated is set.
|
||||
ImGuiItemStatusFlags_HoveredWindow = 1 << 7, // Override the HoveredWindow test to allow cross-window hover testing.
|
||||
ImGuiItemStatusFlags_FocusedByTabbing = 1 << 8, // Set when the Focusable item just got focused by Tabbing (FIXME: to be removed soon)
|
||||
ImGuiItemStatusFlags_Visible = 1 << 9, // [WIP] Set when item is overlapping the current clipping rectangle (Used internally. Please don't use yet: API/system will change as we refactor Itemadd()).
|
||||
ImGuiItemStatusFlags_Visible = 1 << 8, // [WIP] Set when item is overlapping the current clipping rectangle (Used internally. Please don't use yet: API/system will change as we refactor Itemadd()).
|
||||
ImGuiItemStatusFlags_HasClipRect = 1 << 9, // g.LastItemData.ClipRect is valid
|
||||
|
||||
// Additional status + semantic for ImGuiTestEngine
|
||||
#ifdef IMGUI_ENABLE_TEST_ENGINE
|
||||
@@ -852,7 +862,7 @@ enum ImGuiItemStatusFlags_
|
||||
enum ImGuiHoveredFlagsPrivate_
|
||||
{
|
||||
ImGuiHoveredFlags_DelayMask_ = ImGuiHoveredFlags_DelayNone | ImGuiHoveredFlags_DelayShort | ImGuiHoveredFlags_DelayNormal | ImGuiHoveredFlags_NoSharedDelay,
|
||||
ImGuiHoveredFlags_AllowedMaskForIsWindowHovered = ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_AnyWindow | ImGuiHoveredFlags_NoPopupHierarchy | ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_ForTooltip | ImGuiHoveredFlags_Stationary,
|
||||
ImGuiHoveredFlags_AllowedMaskForIsWindowHovered = ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_AnyWindow | ImGuiHoveredFlags_NoPopupHierarchy | ImGuiHoveredFlags_DockHierarchy | ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_ForTooltip | ImGuiHoveredFlags_Stationary,
|
||||
ImGuiHoveredFlags_AllowedMaskForIsItemHovered = ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_AllowWhenOverlapped | ImGuiHoveredFlags_AllowWhenDisabled | ImGuiHoveredFlags_NoNavOverride | ImGuiHoveredFlags_ForTooltip | ImGuiHoveredFlags_Stationary | ImGuiHoveredFlags_DelayMask_,
|
||||
};
|
||||
|
||||
@@ -1121,7 +1131,7 @@ struct IMGUI_API ImGuiInputTextState
|
||||
void ClearText() { CurLenW = CurLenA = 0; TextW[0] = 0; TextA[0] = 0; CursorClamp(); }
|
||||
void ClearFreeMemory() { TextW.clear(); TextA.clear(); InitialTextA.clear(); }
|
||||
int GetUndoAvailCount() const { return Stb.undostate.undo_point; }
|
||||
int GetRedoAvailCount() const { return STB_TEXTEDIT_UNDOSTATECOUNT - Stb.undostate.redo_point; }
|
||||
int GetRedoAvailCount() const { return IMSTB_TEXTEDIT_UNDOSTATECOUNT - Stb.undostate.redo_point; }
|
||||
void OnKeyPressed(int key); // Cannot be inline because we call in code in stb_textedit.h implementation
|
||||
|
||||
// Cursor & Selection
|
||||
@@ -1162,6 +1172,9 @@ enum ImGuiNextWindowDataFlags_
|
||||
ImGuiNextWindowDataFlags_HasBgAlpha = 1 << 6,
|
||||
ImGuiNextWindowDataFlags_HasScroll = 1 << 7,
|
||||
ImGuiNextWindowDataFlags_HasChildFlags = 1 << 8,
|
||||
ImGuiNextWindowDataFlags_HasViewport = 1 << 9,
|
||||
ImGuiNextWindowDataFlags_HasDock = 1 << 10,
|
||||
ImGuiNextWindowDataFlags_HasWindowClass = 1 << 11,
|
||||
};
|
||||
|
||||
// Storage for SetNexWindow** functions
|
||||
@@ -1171,17 +1184,22 @@ struct ImGuiNextWindowData
|
||||
ImGuiCond PosCond;
|
||||
ImGuiCond SizeCond;
|
||||
ImGuiCond CollapsedCond;
|
||||
ImGuiCond DockCond;
|
||||
ImVec2 PosVal;
|
||||
ImVec2 PosPivotVal;
|
||||
ImVec2 SizeVal;
|
||||
ImVec2 ContentSizeVal;
|
||||
ImVec2 ScrollVal;
|
||||
ImGuiChildFlags ChildFlags;
|
||||
bool PosUndock;
|
||||
bool CollapsedVal;
|
||||
ImRect SizeConstraintRect;
|
||||
ImGuiSizeCallback SizeCallback;
|
||||
void* SizeCallbackUserData;
|
||||
float BgAlphaVal; // Override background alpha
|
||||
ImGuiID ViewportId;
|
||||
ImGuiID DockId;
|
||||
ImGuiWindowClass WindowClass;
|
||||
ImVec2 MenuBarOffsetMinVal; // (Always on) This is not exposed publicly, so we don't clear it and it doesn't have a corresponding flag (could we? for consistency?)
|
||||
|
||||
ImGuiNextWindowData() { memset(this, 0, sizeof(*this)); }
|
||||
@@ -1221,7 +1239,9 @@ struct ImGuiLastItemData
|
||||
ImGuiItemStatusFlags StatusFlags; // See ImGuiItemStatusFlags_
|
||||
ImRect Rect; // Full rectangle
|
||||
ImRect NavRect; // Navigation scoring rectangle (not displayed)
|
||||
ImRect DisplayRect; // Display rectangle (only if ImGuiItemStatusFlags_HasDisplayRect is set)
|
||||
// Rarely used fields are not explicitly cleared, only valid when the corresponding ImGuiItemStatusFlags is set.
|
||||
ImRect DisplayRect; // Display rectangle (ONLY VALID IF ImGuiItemStatusFlags_HasDisplayRect is set)
|
||||
ImRect ClipRect; // Clip rectangle at the time of submitting item (ONLY VALID IF ImGuiItemStatusFlags_HasClipRect is set)
|
||||
|
||||
ImGuiLastItemData() { memset(this, 0, sizeof(*this)); }
|
||||
};
|
||||
@@ -1312,6 +1332,7 @@ enum ImGuiInputEventType
|
||||
ImGuiInputEventType_MousePos,
|
||||
ImGuiInputEventType_MouseWheel,
|
||||
ImGuiInputEventType_MouseButton,
|
||||
ImGuiInputEventType_MouseViewport,
|
||||
ImGuiInputEventType_Key,
|
||||
ImGuiInputEventType_Text,
|
||||
ImGuiInputEventType_Focus,
|
||||
@@ -1333,6 +1354,7 @@ enum ImGuiInputSource
|
||||
struct ImGuiInputEventMousePos { float PosX, PosY; ImGuiMouseSource MouseSource; };
|
||||
struct ImGuiInputEventMouseWheel { float WheelX, WheelY; ImGuiMouseSource MouseSource; };
|
||||
struct ImGuiInputEventMouseButton { int Button; bool Down; ImGuiMouseSource MouseSource; };
|
||||
struct ImGuiInputEventMouseViewport { ImGuiID HoveredViewportID; };
|
||||
struct ImGuiInputEventKey { ImGuiKey Key; bool Down; float AnalogValue; };
|
||||
struct ImGuiInputEventText { unsigned int Char; };
|
||||
struct ImGuiInputEventAppFocused { bool Focused; };
|
||||
@@ -1347,6 +1369,7 @@ struct ImGuiInputEvent
|
||||
ImGuiInputEventMousePos MousePos; // if Type == ImGuiInputEventType_MousePos
|
||||
ImGuiInputEventMouseWheel MouseWheel; // if Type == ImGuiInputEventType_MouseWheel
|
||||
ImGuiInputEventMouseButton MouseButton; // if Type == ImGuiInputEventType_MouseButton
|
||||
ImGuiInputEventMouseViewport MouseViewport; // if Type == ImGuiInputEventType_MouseViewport
|
||||
ImGuiInputEventKey Key; // if Type == ImGuiInputEventType_Key
|
||||
ImGuiInputEventText Text; // if Type == ImGuiInputEventType_Text
|
||||
ImGuiInputEventAppFocused AppFocused; // if Type == ImGuiInputEventType_Focus
|
||||
@@ -1402,23 +1425,29 @@ struct ImGuiKeyOwnerData
|
||||
// Don't mistake with ImGuiInputTextFlags! (for ImGui::InputText() function)
|
||||
enum ImGuiInputFlags_
|
||||
{
|
||||
// Flags for IsKeyPressed(), IsMouseClicked(), Shortcut()
|
||||
// Flags for IsKeyPressed(), IsKeyChordPressed(), IsMouseClicked(), Shortcut()
|
||||
ImGuiInputFlags_None = 0,
|
||||
ImGuiInputFlags_Repeat = 1 << 0, // Return true on successive repeats. Default for legacy IsKeyPressed(). NOT Default for legacy IsMouseClicked(). MUST BE == 1.
|
||||
ImGuiInputFlags_RepeatRateDefault = 1 << 1, // Repeat rate: Regular (default)
|
||||
ImGuiInputFlags_RepeatRateNavMove = 1 << 2, // Repeat rate: Fast
|
||||
ImGuiInputFlags_RepeatRateNavTweak = 1 << 3, // Repeat rate: Faster
|
||||
ImGuiInputFlags_RepeatRateMask_ = ImGuiInputFlags_RepeatRateDefault | ImGuiInputFlags_RepeatRateNavMove | ImGuiInputFlags_RepeatRateNavTweak,
|
||||
|
||||
// Specify when repeating key pressed can be interrupted.
|
||||
// In theory ImGuiInputFlags_RepeatUntilOtherKeyPress may be a desirable default, but it would break too many behavior so everything is opt-in.
|
||||
ImGuiInputFlags_RepeatUntilRelease = 1 << 4, // Stop repeating when released (default for all functions except Shortcut). This only exists to allow overriding Shortcut() default behavior.
|
||||
ImGuiInputFlags_RepeatUntilKeyModsChange = 1 << 5, // Stop repeating when released OR if keyboard mods are changed (default for Shortcut)
|
||||
ImGuiInputFlags_RepeatUntilKeyModsChangeFromNone = 1 << 6, // Stop repeating when released OR if keyboard mods are leaving the None state. Allows going from Mod+Key to Key by releasing Mod.
|
||||
ImGuiInputFlags_RepeatUntilOtherKeyPress = 1 << 7, // Stop repeating when released OR if any other keyboard key is pressed during the repeat
|
||||
|
||||
// Flags for SetItemKeyOwner()
|
||||
ImGuiInputFlags_CondHovered = 1 << 4, // Only set if item is hovered (default to both)
|
||||
ImGuiInputFlags_CondActive = 1 << 5, // Only set if item is active (default to both)
|
||||
ImGuiInputFlags_CondHovered = 1 << 8, // Only set if item is hovered (default to both)
|
||||
ImGuiInputFlags_CondActive = 1 << 9, // Only set if item is active (default to both)
|
||||
ImGuiInputFlags_CondDefault_ = ImGuiInputFlags_CondHovered | ImGuiInputFlags_CondActive,
|
||||
ImGuiInputFlags_CondMask_ = ImGuiInputFlags_CondHovered | ImGuiInputFlags_CondActive,
|
||||
|
||||
// Flags for SetKeyOwner(), SetItemKeyOwner()
|
||||
ImGuiInputFlags_LockThisFrame = 1 << 6, // Access to key data will require EXPLICIT owner ID (ImGuiKeyOwner_Any/0 will NOT accepted for polling). Cleared at end of frame. This is useful to make input-owner-aware code steal keys from non-input-owner-aware code.
|
||||
ImGuiInputFlags_LockUntilRelease = 1 << 7, // Access to key data will require EXPLICIT owner ID (ImGuiKeyOwner_Any/0 will NOT accepted for polling). Cleared when the key is released or at end of each frame if key is released. This is useful to make input-owner-aware code steal keys from non-input-owner-aware code.
|
||||
ImGuiInputFlags_LockThisFrame = 1 << 10, // Access to key data will require EXPLICIT owner ID (ImGuiKeyOwner_Any/0 will NOT accepted for polling). Cleared at end of frame. This is useful to make input-owner-aware code steal keys from non-input-owner-aware code.
|
||||
ImGuiInputFlags_LockUntilRelease = 1 << 11, // Access to key data will require EXPLICIT owner ID (ImGuiKeyOwner_Any/0 will NOT accepted for polling). Cleared when the key is released or at end of each frame if key is released. This is useful to make input-owner-aware code steal keys from non-input-owner-aware code.
|
||||
|
||||
// Routing policies for Shortcut() + low-level SetShortcutRouting()
|
||||
// - The general idea is that several callers register interest in a shortcut, and only one owner gets it.
|
||||
@@ -1430,18 +1459,22 @@ enum ImGuiInputFlags_
|
||||
// - Using ImGuiInputFlags_RouteAlways is roughly equivalent to doing e.g. IsKeyPressed(key) + testing mods.
|
||||
// - Priorities: GlobalHigh > Focused (when owner is active item) > Global > Focused (when focused window) > GlobalLow.
|
||||
// - Can select only 1 policy among all available.
|
||||
ImGuiInputFlags_RouteFocused = 1 << 8, // (Default) Register focused route: Accept inputs if window is in focus stack. Deep-most focused window takes inputs. ActiveId takes inputs over deep-most focused window.
|
||||
ImGuiInputFlags_RouteGlobalLow = 1 << 9, // Register route globally (lowest priority: unless a focused window or active item registered the route) -> recommended Global priority.
|
||||
ImGuiInputFlags_RouteGlobal = 1 << 10, // Register route globally (medium priority: unless an active item registered the route, e.g. CTRL+A registered by InputText).
|
||||
ImGuiInputFlags_RouteGlobalHigh = 1 << 11, // Register route globally (highest priority: unlikely you need to use that: will interfere with every active items)
|
||||
ImGuiInputFlags_RouteFocused = 1 << 12, // (Default) Register focused route: Accept inputs if window is in focus stack. Deep-most focused window takes inputs. ActiveId takes inputs over deep-most focused window.
|
||||
ImGuiInputFlags_RouteGlobalLow = 1 << 13, // Register route globally (lowest priority: unless a focused window or active item registered the route) -> recommended Global priority.
|
||||
ImGuiInputFlags_RouteGlobal = 1 << 14, // Register route globally (medium priority: unless an active item registered the route, e.g. CTRL+A registered by InputText).
|
||||
ImGuiInputFlags_RouteGlobalHigh = 1 << 15, // Register route globally (highest priority: unlikely you need to use that: will interfere with every active items)
|
||||
ImGuiInputFlags_RouteMask_ = ImGuiInputFlags_RouteFocused | ImGuiInputFlags_RouteGlobal | ImGuiInputFlags_RouteGlobalLow | ImGuiInputFlags_RouteGlobalHigh, // _Always not part of this!
|
||||
ImGuiInputFlags_RouteAlways = 1 << 12, // Do not register route, poll keys directly.
|
||||
ImGuiInputFlags_RouteUnlessBgFocused= 1 << 13, // Global routes will not be applied if underlying background/void is focused (== no Dear ImGui windows are focused). Useful for overlay applications.
|
||||
ImGuiInputFlags_RouteAlways = 1 << 16, // Do not register route, poll keys directly.
|
||||
ImGuiInputFlags_RouteUnlessBgFocused= 1 << 17, // Global routes will not be applied if underlying background/void is focused (== no Dear ImGui windows are focused). Useful for overlay applications.
|
||||
ImGuiInputFlags_RouteExtraMask_ = ImGuiInputFlags_RouteAlways | ImGuiInputFlags_RouteUnlessBgFocused,
|
||||
|
||||
// [Internal] Mask of which function support which flags
|
||||
ImGuiInputFlags_SupportedByIsKeyPressed = ImGuiInputFlags_Repeat | ImGuiInputFlags_RepeatRateMask_,
|
||||
ImGuiInputFlags_SupportedByShortcut = ImGuiInputFlags_Repeat | ImGuiInputFlags_RepeatRateMask_ | ImGuiInputFlags_RouteMask_ | ImGuiInputFlags_RouteExtraMask_,
|
||||
ImGuiInputFlags_RepeatRateMask_ = ImGuiInputFlags_RepeatRateDefault | ImGuiInputFlags_RepeatRateNavMove | ImGuiInputFlags_RepeatRateNavTweak,
|
||||
ImGuiInputFlags_RepeatUntilMask_ = ImGuiInputFlags_RepeatUntilRelease | ImGuiInputFlags_RepeatUntilKeyModsChange | ImGuiInputFlags_RepeatUntilKeyModsChangeFromNone | ImGuiInputFlags_RepeatUntilOtherKeyPress,
|
||||
ImGuiInputFlags_RepeatMask_ = ImGuiInputFlags_Repeat | ImGuiInputFlags_RepeatRateMask_ | ImGuiInputFlags_RepeatUntilMask_,
|
||||
ImGuiInputFlags_SupportedByIsKeyPressed = ImGuiInputFlags_RepeatMask_,
|
||||
ImGuiInputFlags_SupportedByIsMouseClicked = ImGuiInputFlags_Repeat,
|
||||
ImGuiInputFlags_SupportedByShortcut = ImGuiInputFlags_RepeatMask_ | ImGuiInputFlags_RouteMask_ | ImGuiInputFlags_RouteExtraMask_,
|
||||
ImGuiInputFlags_SupportedBySetKeyOwner = ImGuiInputFlags_LockThisFrame | ImGuiInputFlags_LockUntilRelease,
|
||||
ImGuiInputFlags_SupportedBySetItemKeyOwner = ImGuiInputFlags_SupportedBySetKeyOwner | ImGuiInputFlags_CondMask_,
|
||||
};
|
||||
@@ -1486,6 +1519,7 @@ enum ImGuiActivateFlags_
|
||||
ImGuiActivateFlags_PreferInput = 1 << 0, // Favor activation that requires keyboard text input (e.g. for Slider/Drag). Default for Enter key.
|
||||
ImGuiActivateFlags_PreferTweak = 1 << 1, // Favor activation for tweaking with arrows or gamepad (e.g. for Slider/Drag). Default for Space key and if keyboard is not used.
|
||||
ImGuiActivateFlags_TryToPreserveState = 1 << 2, // Request widget to preserve state if it can (e.g. InputText will try to preserve cursor/selection)
|
||||
ImGuiActivateFlags_FromTabbing = 1 << 3, // Activation requested by a tabbing request
|
||||
};
|
||||
|
||||
// Early work-in-progress API for ScrollToItem()
|
||||
@@ -1597,7 +1631,7 @@ struct IMGUI_API ImGuiTypingSelectState
|
||||
// [SECTION] Columns support
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Flags for internal's BeginColumns(). Prefix using BeginTable() nowadays!
|
||||
// Flags for internal's BeginColumns(). This is an obsolete API. Prefer using BeginTable() nowadays!
|
||||
enum ImGuiOldColumnFlags_
|
||||
{
|
||||
ImGuiOldColumnFlags_None = 0,
|
||||
@@ -1605,16 +1639,16 @@ enum ImGuiOldColumnFlags_
|
||||
ImGuiOldColumnFlags_NoResize = 1 << 1, // Disable resizing columns when clicking on the dividers
|
||||
ImGuiOldColumnFlags_NoPreserveWidths = 1 << 2, // Disable column width preservation when adjusting columns
|
||||
ImGuiOldColumnFlags_NoForceWithinWindow = 1 << 3, // Disable forcing columns to fit within window
|
||||
ImGuiOldColumnFlags_GrowParentContentsSize = 1 << 4, // (WIP) Restore pre-1.51 behavior of extending the parent window contents size but _without affecting the columns width at all_. Will eventually remove.
|
||||
ImGuiOldColumnFlags_GrowParentContentsSize = 1 << 4, // Restore pre-1.51 behavior of extending the parent window contents size but _without affecting the columns width at all_. Will eventually remove.
|
||||
|
||||
// Obsolete names (will be removed)
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
ImGuiColumnsFlags_None = ImGuiOldColumnFlags_None,
|
||||
ImGuiColumnsFlags_NoBorder = ImGuiOldColumnFlags_NoBorder,
|
||||
ImGuiColumnsFlags_NoResize = ImGuiOldColumnFlags_NoResize,
|
||||
ImGuiColumnsFlags_NoPreserveWidths = ImGuiOldColumnFlags_NoPreserveWidths,
|
||||
ImGuiColumnsFlags_NoForceWithinWindow = ImGuiOldColumnFlags_NoForceWithinWindow,
|
||||
ImGuiColumnsFlags_GrowParentContentsSize = ImGuiOldColumnFlags_GrowParentContentsSize,
|
||||
//ImGuiColumnsFlags_None = ImGuiOldColumnFlags_None,
|
||||
//ImGuiColumnsFlags_NoBorder = ImGuiOldColumnFlags_NoBorder,
|
||||
//ImGuiColumnsFlags_NoResize = ImGuiOldColumnFlags_NoResize,
|
||||
//ImGuiColumnsFlags_NoPreserveWidths = ImGuiOldColumnFlags_NoPreserveWidths,
|
||||
//ImGuiColumnsFlags_NoForceWithinWindow = ImGuiOldColumnFlags_NoForceWithinWindow,
|
||||
//ImGuiColumnsFlags_GrowParentContentsSize = ImGuiOldColumnFlags_GrowParentContentsSize,
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -1664,8 +1698,148 @@ struct ImGuiOldColumns
|
||||
// [SECTION] Docking support
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#define DOCKING_HOST_DRAW_CHANNEL_BG 0 // Dock host: background fill
|
||||
#define DOCKING_HOST_DRAW_CHANNEL_FG 1 // Dock host: decorations and contents
|
||||
|
||||
#ifdef IMGUI_HAS_DOCK
|
||||
// <this is filled in 'docking' branch>
|
||||
|
||||
// Extend ImGuiDockNodeFlags_
|
||||
enum ImGuiDockNodeFlagsPrivate_
|
||||
{
|
||||
// [Internal]
|
||||
ImGuiDockNodeFlags_DockSpace = 1 << 10, // Saved // A dockspace is a node that occupy space within an existing user window. Otherwise the node is floating and create its own window.
|
||||
ImGuiDockNodeFlags_CentralNode = 1 << 11, // Saved // The central node has 2 main properties: stay visible when empty, only use "remaining" spaces from its neighbor.
|
||||
ImGuiDockNodeFlags_NoTabBar = 1 << 12, // Saved // Tab bar is completely unavailable. No triangle in the corner to enable it back.
|
||||
ImGuiDockNodeFlags_HiddenTabBar = 1 << 13, // Saved // Tab bar is hidden, with a triangle in the corner to show it again (NB: actual tab-bar instance may be destroyed as this is only used for single-window tab bar)
|
||||
ImGuiDockNodeFlags_NoWindowMenuButton = 1 << 14, // Saved // Disable window/docking menu (that one that appears instead of the collapse button)
|
||||
ImGuiDockNodeFlags_NoCloseButton = 1 << 15, // Saved // Disable close button
|
||||
ImGuiDockNodeFlags_NoResizeX = 1 << 16, // //
|
||||
ImGuiDockNodeFlags_NoResizeY = 1 << 17, // //
|
||||
// Disable docking/undocking actions in this dockspace or individual node (existing docked nodes will be preserved)
|
||||
// Those are not exposed in public because the desirable sharing/inheriting/copy-flag-on-split behaviors are quite difficult to design and understand.
|
||||
// The two public flags ImGuiDockNodeFlags_NoDockingOverCentralNode/ImGuiDockNodeFlags_NoDockingSplit don't have those issues.
|
||||
ImGuiDockNodeFlags_NoDockingSplitOther = 1 << 19, // // Disable this node from splitting other windows/nodes.
|
||||
ImGuiDockNodeFlags_NoDockingOverMe = 1 << 20, // // Disable other windows/nodes from being docked over this node.
|
||||
ImGuiDockNodeFlags_NoDockingOverOther = 1 << 21, // // Disable this node from being docked over another window or non-empty node.
|
||||
ImGuiDockNodeFlags_NoDockingOverEmpty = 1 << 22, // // Disable this node from being docked over an empty node (e.g. DockSpace with no other windows)
|
||||
ImGuiDockNodeFlags_NoDocking = ImGuiDockNodeFlags_NoDockingOverMe | ImGuiDockNodeFlags_NoDockingOverOther | ImGuiDockNodeFlags_NoDockingOverEmpty | ImGuiDockNodeFlags_NoDockingSplit | ImGuiDockNodeFlags_NoDockingSplitOther,
|
||||
// Masks
|
||||
ImGuiDockNodeFlags_SharedFlagsInheritMask_ = ~0,
|
||||
ImGuiDockNodeFlags_NoResizeFlagsMask_ = ImGuiDockNodeFlags_NoResize | ImGuiDockNodeFlags_NoResizeX | ImGuiDockNodeFlags_NoResizeY,
|
||||
// When splitting, those local flags are moved to the inheriting child, never duplicated
|
||||
ImGuiDockNodeFlags_LocalFlagsTransferMask_ = ImGuiDockNodeFlags_NoDockingSplit | ImGuiDockNodeFlags_NoResizeFlagsMask_ | ImGuiDockNodeFlags_AutoHideTabBar | ImGuiDockNodeFlags_CentralNode | ImGuiDockNodeFlags_NoTabBar | ImGuiDockNodeFlags_HiddenTabBar | ImGuiDockNodeFlags_NoWindowMenuButton | ImGuiDockNodeFlags_NoCloseButton,
|
||||
ImGuiDockNodeFlags_SavedFlagsMask_ = ImGuiDockNodeFlags_NoResizeFlagsMask_ | ImGuiDockNodeFlags_DockSpace | ImGuiDockNodeFlags_CentralNode | ImGuiDockNodeFlags_NoTabBar | ImGuiDockNodeFlags_HiddenTabBar | ImGuiDockNodeFlags_NoWindowMenuButton | ImGuiDockNodeFlags_NoCloseButton,
|
||||
};
|
||||
|
||||
// Store the source authority (dock node vs window) of a field
|
||||
enum ImGuiDataAuthority_
|
||||
{
|
||||
ImGuiDataAuthority_Auto,
|
||||
ImGuiDataAuthority_DockNode,
|
||||
ImGuiDataAuthority_Window,
|
||||
};
|
||||
|
||||
enum ImGuiDockNodeState
|
||||
{
|
||||
ImGuiDockNodeState_Unknown,
|
||||
ImGuiDockNodeState_HostWindowHiddenBecauseSingleWindow,
|
||||
ImGuiDockNodeState_HostWindowHiddenBecauseWindowsAreResizing,
|
||||
ImGuiDockNodeState_HostWindowVisible,
|
||||
};
|
||||
|
||||
// sizeof() 156~192
|
||||
struct IMGUI_API ImGuiDockNode
|
||||
{
|
||||
ImGuiID ID;
|
||||
ImGuiDockNodeFlags SharedFlags; // (Write) Flags shared by all nodes of a same dockspace hierarchy (inherited from the root node)
|
||||
ImGuiDockNodeFlags LocalFlags; // (Write) Flags specific to this node
|
||||
ImGuiDockNodeFlags LocalFlagsInWindows; // (Write) Flags specific to this node, applied from windows
|
||||
ImGuiDockNodeFlags MergedFlags; // (Read) Effective flags (== SharedFlags | LocalFlagsInNode | LocalFlagsInWindows)
|
||||
ImGuiDockNodeState State;
|
||||
ImGuiDockNode* ParentNode;
|
||||
ImGuiDockNode* ChildNodes[2]; // [Split node only] Child nodes (left/right or top/bottom). Consider switching to an array.
|
||||
ImVector<ImGuiWindow*> Windows; // Note: unordered list! Iterate TabBar->Tabs for user-order.
|
||||
ImGuiTabBar* TabBar;
|
||||
ImVec2 Pos; // Current position
|
||||
ImVec2 Size; // Current size
|
||||
ImVec2 SizeRef; // [Split node only] Last explicitly written-to size (overridden when using a splitter affecting the node), used to calculate Size.
|
||||
ImGuiAxis SplitAxis; // [Split node only] Split axis (X or Y)
|
||||
ImGuiWindowClass WindowClass; // [Root node only]
|
||||
ImU32 LastBgColor;
|
||||
|
||||
ImGuiWindow* HostWindow;
|
||||
ImGuiWindow* VisibleWindow; // Generally point to window which is ID is == SelectedTabID, but when CTRL+Tabbing this can be a different window.
|
||||
ImGuiDockNode* CentralNode; // [Root node only] Pointer to central node.
|
||||
ImGuiDockNode* OnlyNodeWithWindows; // [Root node only] Set when there is a single visible node within the hierarchy.
|
||||
int CountNodeWithWindows; // [Root node only]
|
||||
int LastFrameAlive; // Last frame number the node was updated or kept alive explicitly with DockSpace() + ImGuiDockNodeFlags_KeepAliveOnly
|
||||
int LastFrameActive; // Last frame number the node was updated.
|
||||
int LastFrameFocused; // Last frame number the node was focused.
|
||||
ImGuiID LastFocusedNodeId; // [Root node only] Which of our child docking node (any ancestor in the hierarchy) was last focused.
|
||||
ImGuiID SelectedTabId; // [Leaf node only] Which of our tab/window is selected.
|
||||
ImGuiID WantCloseTabId; // [Leaf node only] Set when closing a specific tab/window.
|
||||
ImGuiID RefViewportId; // Reference viewport ID from visible window when HostWindow == NULL.
|
||||
ImGuiDataAuthority AuthorityForPos :3;
|
||||
ImGuiDataAuthority AuthorityForSize :3;
|
||||
ImGuiDataAuthority AuthorityForViewport :3;
|
||||
bool IsVisible :1; // Set to false when the node is hidden (usually disabled as it has no active window)
|
||||
bool IsFocused :1;
|
||||
bool IsBgDrawnThisFrame :1;
|
||||
bool HasCloseButton :1; // Provide space for a close button (if any of the docked window has one). Note that button may be hidden on window without one.
|
||||
bool HasWindowMenuButton :1;
|
||||
bool HasCentralNodeChild :1;
|
||||
bool WantCloseAll :1; // Set when closing all tabs at once.
|
||||
bool WantLockSizeOnce :1;
|
||||
bool WantMouseMove :1; // After a node extraction we need to transition toward moving the newly created host window
|
||||
bool WantHiddenTabBarUpdate :1;
|
||||
bool WantHiddenTabBarToggle :1;
|
||||
|
||||
ImGuiDockNode(ImGuiID id);
|
||||
~ImGuiDockNode();
|
||||
bool IsRootNode() const { return ParentNode == NULL; }
|
||||
bool IsDockSpace() const { return (MergedFlags & ImGuiDockNodeFlags_DockSpace) != 0; }
|
||||
bool IsFloatingNode() const { return ParentNode == NULL && (MergedFlags & ImGuiDockNodeFlags_DockSpace) == 0; }
|
||||
bool IsCentralNode() const { return (MergedFlags & ImGuiDockNodeFlags_CentralNode) != 0; }
|
||||
bool IsHiddenTabBar() const { return (MergedFlags & ImGuiDockNodeFlags_HiddenTabBar) != 0; } // Hidden tab bar can be shown back by clicking the small triangle
|
||||
bool IsNoTabBar() const { return (MergedFlags & ImGuiDockNodeFlags_NoTabBar) != 0; } // Never show a tab bar
|
||||
bool IsSplitNode() const { return ChildNodes[0] != NULL; }
|
||||
bool IsLeafNode() const { return ChildNodes[0] == NULL; }
|
||||
bool IsEmpty() const { return ChildNodes[0] == NULL && Windows.Size == 0; }
|
||||
ImRect Rect() const { return ImRect(Pos.x, Pos.y, Pos.x + Size.x, Pos.y + Size.y); }
|
||||
|
||||
void SetLocalFlags(ImGuiDockNodeFlags flags) { LocalFlags = flags; UpdateMergedFlags(); }
|
||||
void UpdateMergedFlags() { MergedFlags = SharedFlags | LocalFlags | LocalFlagsInWindows; }
|
||||
};
|
||||
|
||||
// List of colors that are stored at the time of Begin() into Docked Windows.
|
||||
// We currently store the packed colors in a simple array window->DockStyle.Colors[].
|
||||
// A better solution may involve appending into a log of colors in ImGuiContext + store offsets into those arrays in ImGuiWindow,
|
||||
// but it would be more complex as we'd need to double-buffer both as e.g. drop target may refer to window from last frame.
|
||||
enum ImGuiWindowDockStyleCol
|
||||
{
|
||||
ImGuiWindowDockStyleCol_Text,
|
||||
ImGuiWindowDockStyleCol_Tab,
|
||||
ImGuiWindowDockStyleCol_TabHovered,
|
||||
ImGuiWindowDockStyleCol_TabActive,
|
||||
ImGuiWindowDockStyleCol_TabUnfocused,
|
||||
ImGuiWindowDockStyleCol_TabUnfocusedActive,
|
||||
ImGuiWindowDockStyleCol_COUNT
|
||||
};
|
||||
|
||||
struct ImGuiWindowDockStyle
|
||||
{
|
||||
ImU32 Colors[ImGuiWindowDockStyleCol_COUNT];
|
||||
};
|
||||
|
||||
struct ImGuiDockContext
|
||||
{
|
||||
ImGuiStorage Nodes; // Map ID -> ImGuiDockNode*: Active nodes
|
||||
ImVector<ImGuiDockRequest> Requests;
|
||||
ImVector<ImGuiDockNodeSettings> NodesSettings;
|
||||
bool WantFullRebuild;
|
||||
ImGuiDockContext() { memset(this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
#endif // #ifdef IMGUI_HAS_DOCK
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -1676,17 +1850,31 @@ struct ImGuiOldColumns
|
||||
// Every instance of ImGuiViewport is in fact a ImGuiViewportP.
|
||||
struct ImGuiViewportP : public ImGuiViewport
|
||||
{
|
||||
ImGuiWindow* Window; // Set when the viewport is owned by a window (and ImGuiViewportFlags_CanHostOtherWindows is NOT set)
|
||||
int Idx;
|
||||
int LastFrameActive; // Last frame number this viewport was activated by a window
|
||||
int LastFocusedStampCount; // Last stamp number from when a window hosted by this viewport was focused (by comparing this value between two viewport we have an implicit viewport z-order we use as fallback)
|
||||
ImGuiID LastNameHash;
|
||||
ImVec2 LastPos;
|
||||
float Alpha; // Window opacity (when dragging dockable windows/viewports we make them transparent)
|
||||
float LastAlpha;
|
||||
bool LastFocusedHadNavWindow;// Instead of maintaining a LastFocusedWindow (which may harder to correctly maintain), we merely store weither NavWindow != NULL last time the viewport was focused.
|
||||
short PlatformMonitor;
|
||||
int BgFgDrawListsLastFrame[2]; // Last frame number the background (0) and foreground (1) draw lists were used
|
||||
ImDrawList* BgFgDrawLists[2]; // Convenience background (0) and foreground (1) draw lists. We use them to draw software mouser cursor when io.MouseDrawCursor is set and to draw most debug overlays.
|
||||
ImDrawData DrawDataP;
|
||||
ImDrawDataBuilder DrawDataBuilder; // Temporary data while building final ImDrawData
|
||||
ImVec2 LastPlatformPos;
|
||||
ImVec2 LastPlatformSize;
|
||||
ImVec2 LastRendererSize;
|
||||
ImVec2 WorkOffsetMin; // Work Area: Offset from Pos to top-left corner of Work Area. Generally (0,0) or (0,+main_menu_bar_height). Work Area is Full Area but without menu-bars/status-bars (so WorkArea always fit inside Pos/Size!)
|
||||
ImVec2 WorkOffsetMax; // Work Area: Offset from Pos+Size to bottom-right corner of Work Area. Generally (0,0) or (0,-status_bar_height).
|
||||
ImVec2 BuildWorkOffsetMin; // Work Area: Offset being built during current frame. Generally >= 0.0f.
|
||||
ImVec2 BuildWorkOffsetMax; // Work Area: Offset being built during current frame. Generally <= 0.0f.
|
||||
|
||||
ImGuiViewportP() { BgFgDrawListsLastFrame[0] = BgFgDrawListsLastFrame[1] = -1; BgFgDrawLists[0] = BgFgDrawLists[1] = NULL; }
|
||||
~ImGuiViewportP() { if (BgFgDrawLists[0]) IM_DELETE(BgFgDrawLists[0]); if (BgFgDrawLists[1]) IM_DELETE(BgFgDrawLists[1]); }
|
||||
ImGuiViewportP() { Window = NULL; Idx = -1; LastFrameActive = BgFgDrawListsLastFrame[0] = BgFgDrawListsLastFrame[1] = LastFocusedStampCount = -1; LastNameHash = 0; Alpha = LastAlpha = 1.0f; LastFocusedHadNavWindow = false; PlatformMonitor = -1; BgFgDrawLists[0] = BgFgDrawLists[1] = NULL; LastPlatformPos = LastPlatformSize = LastRendererSize = ImVec2(FLT_MAX, FLT_MAX); }
|
||||
~ImGuiViewportP() { if (BgFgDrawLists[0]) IM_DELETE(BgFgDrawLists[0]); if (BgFgDrawLists[1]) IM_DELETE(BgFgDrawLists[1]); }
|
||||
void ClearRequestFlags() { PlatformRequestClose = PlatformRequestMove = PlatformRequestResize = false; }
|
||||
|
||||
// Calculate work rect pos/size given a set of offset (we have 1 pair of offset for rect locked from last frame data, and 1 pair for currently building rect)
|
||||
ImVec2 CalcWorkRectPos(const ImVec2& off_min) const { return ImVec2(Pos.x + off_min.x, Pos.y + off_min.y); }
|
||||
@@ -1709,14 +1897,19 @@ struct ImGuiViewportP : public ImGuiViewport
|
||||
struct ImGuiWindowSettings
|
||||
{
|
||||
ImGuiID ID;
|
||||
ImVec2ih Pos;
|
||||
ImVec2ih Pos; // NB: Settings position are stored RELATIVE to the viewport! Whereas runtime ones are absolute positions.
|
||||
ImVec2ih Size;
|
||||
ImVec2ih ViewportPos;
|
||||
ImGuiID ViewportId;
|
||||
ImGuiID DockId; // ID of last known DockNode (even if the DockNode is invisible because it has only 1 active window), or 0 if none.
|
||||
ImGuiID ClassId; // ID of window class if specified
|
||||
short DockOrder; // Order of the last time the window was visible within its DockNode. This is used to reorder windows that are reappearing on the same frame. Same value between windows that were active and windows that were none are possible.
|
||||
bool Collapsed;
|
||||
bool IsChild;
|
||||
bool WantApply; // Set when loaded from .ini data (to enable merging/loading .ini data into an already running context)
|
||||
bool WantDelete; // Set to invalidate/delete the settings entry
|
||||
|
||||
ImGuiWindowSettings() { memset(this, 0, sizeof(*this)); }
|
||||
ImGuiWindowSettings() { memset(this, 0, sizeof(*this)); DockOrder = -1; }
|
||||
char* GetName() { return (char*)(this + 1); }
|
||||
};
|
||||
|
||||
@@ -1750,6 +1943,9 @@ enum ImGuiLocKey : int
|
||||
ImGuiLocKey_WindowingMainMenuBar,
|
||||
ImGuiLocKey_WindowingPopup,
|
||||
ImGuiLocKey_WindowingUntitled,
|
||||
ImGuiLocKey_DockingHideTabBar,
|
||||
ImGuiLocKey_DockingHoldShiftToDock,
|
||||
ImGuiLocKey_DockingDragToUndockOrMoveNode,
|
||||
ImGuiLocKey_COUNT
|
||||
};
|
||||
|
||||
@@ -1767,17 +1963,20 @@ struct ImGuiLocEntry
|
||||
enum ImGuiDebugLogFlags_
|
||||
{
|
||||
// Event types
|
||||
ImGuiDebugLogFlags_None = 0,
|
||||
ImGuiDebugLogFlags_EventActiveId = 1 << 0,
|
||||
ImGuiDebugLogFlags_EventFocus = 1 << 1,
|
||||
ImGuiDebugLogFlags_EventPopup = 1 << 2,
|
||||
ImGuiDebugLogFlags_EventNav = 1 << 3,
|
||||
ImGuiDebugLogFlags_EventClipper = 1 << 4,
|
||||
ImGuiDebugLogFlags_EventSelection = 1 << 5,
|
||||
ImGuiDebugLogFlags_EventIO = 1 << 6,
|
||||
ImGuiDebugLogFlags_EventMask_ = ImGuiDebugLogFlags_EventActiveId | ImGuiDebugLogFlags_EventFocus | ImGuiDebugLogFlags_EventPopup | ImGuiDebugLogFlags_EventNav | ImGuiDebugLogFlags_EventClipper | ImGuiDebugLogFlags_EventSelection | ImGuiDebugLogFlags_EventIO,
|
||||
ImGuiDebugLogFlags_OutputToTTY = 1 << 10, // Also send output to TTY
|
||||
ImGuiDebugLogFlags_OutputToTestEngine = 1 << 11, // Also send output to Test Engine
|
||||
ImGuiDebugLogFlags_None = 0,
|
||||
ImGuiDebugLogFlags_EventActiveId = 1 << 0,
|
||||
ImGuiDebugLogFlags_EventFocus = 1 << 1,
|
||||
ImGuiDebugLogFlags_EventPopup = 1 << 2,
|
||||
ImGuiDebugLogFlags_EventNav = 1 << 3,
|
||||
ImGuiDebugLogFlags_EventClipper = 1 << 4,
|
||||
ImGuiDebugLogFlags_EventSelection = 1 << 5,
|
||||
ImGuiDebugLogFlags_EventIO = 1 << 6,
|
||||
ImGuiDebugLogFlags_EventDocking = 1 << 7,
|
||||
ImGuiDebugLogFlags_EventViewport = 1 << 8,
|
||||
|
||||
ImGuiDebugLogFlags_EventMask_ = ImGuiDebugLogFlags_EventActiveId | ImGuiDebugLogFlags_EventFocus | ImGuiDebugLogFlags_EventPopup | ImGuiDebugLogFlags_EventNav | ImGuiDebugLogFlags_EventClipper | ImGuiDebugLogFlags_EventSelection | ImGuiDebugLogFlags_EventIO | ImGuiDebugLogFlags_EventDocking | ImGuiDebugLogFlags_EventViewport,
|
||||
ImGuiDebugLogFlags_OutputToTTY = 1 << 20, // Also send output to TTY
|
||||
ImGuiDebugLogFlags_OutputToTestEngine = 1 << 21, // Also send output to Test Engine
|
||||
};
|
||||
|
||||
struct ImGuiDebugAllocEntry
|
||||
@@ -1806,7 +2005,9 @@ struct ImGuiMetricsConfig
|
||||
bool ShowTablesRects = false;
|
||||
bool ShowDrawCmdMesh = true;
|
||||
bool ShowDrawCmdBoundingBoxes = true;
|
||||
bool ShowTextEncodingViewer = false;
|
||||
bool ShowAtlasTintedWithTextColor = false;
|
||||
bool ShowDockingNodes = false;
|
||||
int ShowWindowsRectsType = -1;
|
||||
int ShowTablesRectsType = -1;
|
||||
};
|
||||
@@ -1862,7 +2063,10 @@ struct ImGuiContext
|
||||
bool Initialized;
|
||||
bool FontAtlasOwnedByContext; // IO.Fonts-> is owned by the ImGuiContext and will be destructed along with it.
|
||||
ImGuiIO IO;
|
||||
ImGuiPlatformIO PlatformIO;
|
||||
ImGuiStyle Style;
|
||||
ImGuiConfigFlags ConfigFlagsCurrFrame; // = g.IO.ConfigFlags at the time of NewFrame()
|
||||
ImGuiConfigFlags ConfigFlagsLastFrame;
|
||||
ImFont* Font; // (Shortcut) == FontStack.empty() ? IO.Font : FontStack.back()
|
||||
float FontSize; // (Shortcut) == FontBaseSize * g.CurrentWindow->FontWindowScale == window->FontSize(). Text height for current window.
|
||||
float FontBaseSize; // (Shortcut) == IO.FontGlobalScale * Font->Scale * Font->FontSize. Base text height.
|
||||
@@ -1870,6 +2074,7 @@ struct ImGuiContext
|
||||
double Time;
|
||||
int FrameCount;
|
||||
int FrameCountEnded;
|
||||
int FrameCountPlatformEnded;
|
||||
int FrameCountRendered;
|
||||
bool WithinFrameScope; // Set by NewFrame(), cleared by EndFrame()
|
||||
bool WithinFrameScopeWithImplicitWindow; // Set by NewFrame(), cleared by EndFrame() when the implicit debug window has been pushed
|
||||
@@ -1892,10 +2097,11 @@ struct ImGuiContext
|
||||
ImGuiStorage WindowsById; // Map window's ImGuiID to ImGuiWindow*
|
||||
int WindowsActiveCount; // Number of unique windows submitted by frame
|
||||
ImVec2 WindowsHoverPadding; // Padding around resizable windows for which hovering on counts as hovering the window == ImMax(style.TouchExtraPadding, WINDOWS_HOVER_PADDING)
|
||||
ImGuiID DebugBreakInWindow; // Set to break in Begin() call.
|
||||
ImGuiWindow* CurrentWindow; // Window being drawn into
|
||||
ImGuiWindow* HoveredWindow; // Window the mouse is hovering. Will typically catch mouse inputs.
|
||||
ImGuiWindow* HoveredWindowUnderMovingWindow; // Hovered window ignoring MovingWindow. Only set if MovingWindow is set.
|
||||
ImGuiWindow* MovingWindow; // Track the window we clicked on (in order to preserve focus). The actual window that is moved is generally MovingWindow->RootWindow.
|
||||
ImGuiWindow* MovingWindow; // Track the window we clicked on (in order to preserve focus). The actual window that is moved is generally MovingWindow->RootWindowDockTree.
|
||||
ImGuiWindow* WheelingWindow; // Track the window we started mouse-wheeling on. Until a timer elapse or mouse has moved, generally keep scrolling the same window even if during the course of scrolling the mouse ends up hovering a child window.
|
||||
ImVec2 WheelingWindowRefMousePos;
|
||||
int WheelingWindowStartFrame; // This may be set one frame before WheelingWindow is != NULL
|
||||
@@ -1936,10 +2142,14 @@ struct ImGuiContext
|
||||
// - The idea is that instead of "eating" a given key, we can link to an owner.
|
||||
// - Input query can then read input by specifying ImGuiKeyOwner_Any (== 0), ImGuiKeyOwner_None (== -1) or a custom ID.
|
||||
// - Routing is requested ahead of time for a given chord (Key + Mods) and granted in NewFrame().
|
||||
double LastKeyModsChangeTime; // Record the last time key mods changed (affect repeat delay when using shortcut logic)
|
||||
double LastKeyModsChangeFromNoneTime; // Record the last time key mods changed away from being 0 (affect repeat delay when using shortcut logic)
|
||||
double LastKeyboardKeyPressTime; // Record the last time a keyboard key (ignore mouse/gamepad ones) was pressed.
|
||||
ImGuiKeyOwnerData KeysOwnerData[ImGuiKey_NamedKey_COUNT];
|
||||
ImGuiKeyRoutingTable KeysRoutingTable;
|
||||
ImU32 ActiveIdUsingNavDirMask; // Active widget will want to read those nav move requests (e.g. can activate a button and move away from it)
|
||||
bool ActiveIdUsingAllKeyboardKeys; // Active widget will want to read all keyboard keys inputs. (FIXME: This is a shortcut for not taking ownership of 100+ keys but perhaps best to not have the inconsistency)
|
||||
ImGuiKeyChord DebugBreakInShortcutRouting; // Set to break in SetShortcutRouting()/Shortcut() calls.
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
|
||||
ImU32 ActiveIdUsingNavInputMask; // If you used this. Since (IMGUI_VERSION_NUM >= 18804) : 'g.ActiveIdUsingNavInputMask |= (1 << ImGuiNavInput_Cancel);' becomes 'SetKeyOwner(ImGuiKey_Escape, g.ActiveId) and/or SetKeyOwner(ImGuiKey_NavGamepadCancel, g.ActiveId);'
|
||||
#endif
|
||||
@@ -1954,6 +2164,7 @@ struct ImGuiContext
|
||||
bool DebugShowGroupRects;
|
||||
|
||||
// Shared stacks
|
||||
ImGuiCol DebugFlashStyleColorIdx; // (Keep close to ColorStack to share cache line)
|
||||
ImVector<ImGuiColorMod> ColorStack; // Stack for PushStyleColor()/PopStyleColor() - inherited by Begin()
|
||||
ImVector<ImGuiStyleMod> StyleVarStack; // Stack for PushStyleVar()/PopStyleVar() - inherited by Begin()
|
||||
ImVector<ImFont*> FontStack; // Stack for PushFont()/PopFont() - inherited by Begin()
|
||||
@@ -1967,7 +2178,16 @@ struct ImGuiContext
|
||||
int BeginMenuCount;
|
||||
|
||||
// Viewports
|
||||
ImVector<ImGuiViewportP*> Viewports; // Active viewports (Size==1 in 'master' branch). Each viewports hold their copy of ImDrawData.
|
||||
ImVector<ImGuiViewportP*> Viewports; // Active viewports (always 1+, and generally 1 unless multi-viewports are enabled). Each viewports hold their copy of ImDrawData.
|
||||
float CurrentDpiScale; // == CurrentViewport->DpiScale
|
||||
ImGuiViewportP* CurrentViewport; // We track changes of viewport (happening in Begin) so we can call Platform_OnChangedViewport()
|
||||
ImGuiViewportP* MouseViewport;
|
||||
ImGuiViewportP* MouseLastHoveredViewport; // Last known viewport that was hovered by mouse (even if we are not hovering any viewport any more) + honoring the _NoInputs flag.
|
||||
ImGuiID PlatformLastFocusedViewportId;
|
||||
ImGuiPlatformMonitor FallbackMonitor; // Virtual monitor used as fallback if backend doesn't provide monitor information.
|
||||
int ViewportCreatedCount; // Unique sequential creation counter (mostly for testing/debugging)
|
||||
int PlatformWindowsCreatedCount; // Unique sequential creation counter (mostly for testing/debugging)
|
||||
int ViewportFocusedStampCount; // Every time the front-most window changes, we stamp its viewport with an incrementing counter
|
||||
|
||||
// Gamepad/keyboard Navigation
|
||||
ImGuiWindow* NavWindow; // Focused window for navigation. Could be called 'FocusedWindow'
|
||||
@@ -2038,6 +2258,7 @@ struct ImGuiContext
|
||||
int DragDropMouseButton;
|
||||
ImGuiPayload DragDropPayload;
|
||||
ImRect DragDropTargetRect; // Store rectangle of current target candidate (we favor small targets when overlapping)
|
||||
ImRect DragDropTargetClipRect; // Store ClipRect at the time of item's drawing
|
||||
ImGuiID DragDropTargetId;
|
||||
ImGuiDragDropFlags DragDropAcceptFlags;
|
||||
float DragDropAcceptIdCurrRectSurface; // Target item surface (we resolve overlapping targets by prioritizing the smaller surface)
|
||||
@@ -2054,6 +2275,7 @@ struct ImGuiContext
|
||||
|
||||
// Tables
|
||||
ImGuiTable* CurrentTable;
|
||||
ImGuiID DebugBreakInTable; // Set to break in BeginTable() call.
|
||||
int TablesTempDataStacked; // Temporary table data size (because we leave previous instances undestructed, we generally don't use TablesTempData.Size)
|
||||
ImVector<ImGuiTableTempData> TablesTempData; // Temporary table data (buffers reused/shared across instances, support nesting)
|
||||
ImPool<ImGuiTable> Tables; // Persistent table data
|
||||
@@ -2112,6 +2334,12 @@ struct ImGuiContext
|
||||
// Platform support
|
||||
ImGuiPlatformImeData PlatformImeData; // Data updated by current frame
|
||||
ImGuiPlatformImeData PlatformImeDataPrev; // Previous frame data (when changing we will call io.SetPlatformImeDataFn
|
||||
ImGuiID PlatformImeViewport;
|
||||
|
||||
// Extensions
|
||||
// FIXME: We could provide an API to register one slot in an array held in ImGuiContext?
|
||||
ImGuiDockContext DockContext;
|
||||
void (*DockNodeWindowMenuHandler)(ImGuiContext* ctx, ImGuiDockNode* node, ImGuiTabBar* tab_bar);
|
||||
|
||||
// Settings
|
||||
bool SettingsLoaded;
|
||||
@@ -2143,15 +2371,21 @@ struct ImGuiContext
|
||||
ImGuiDebugLogFlags DebugLogFlags;
|
||||
ImGuiTextBuffer DebugLogBuf;
|
||||
ImGuiTextIndex DebugLogIndex;
|
||||
ImU8 DebugLogClipperAutoDisableFrames;
|
||||
ImGuiDebugLogFlags DebugLogAutoDisableFlags;
|
||||
ImU8 DebugLogAutoDisableFrames;
|
||||
ImU8 DebugLocateFrames; // For DebugLocateItemOnHover(). This is used together with DebugLocateId which is in a hot/cached spot above.
|
||||
bool DebugBreakInLocateId; // Debug break in ItemAdd() call for g.DebugLocateId.
|
||||
ImGuiKeyChord DebugBreakKeyChord; // = ImGuiKey_Pause
|
||||
ImS8 DebugBeginReturnValueCullDepth; // Cycle between 0..9 then wrap around.
|
||||
bool DebugItemPickerActive; // Item picker is active (started with DebugStartItemPicker())
|
||||
ImU8 DebugItemPickerMouseButton;
|
||||
ImGuiID DebugItemPickerBreakId; // Will call IM_DEBUG_BREAK() when encountering this ID
|
||||
float DebugFlashStyleColorTime;
|
||||
ImVec4 DebugFlashStyleColorBackup;
|
||||
ImGuiMetricsConfig DebugMetricsConfig;
|
||||
ImGuiIDStackTool DebugIDStackTool;
|
||||
ImGuiDebugAllocInfo DebugAllocInfo;
|
||||
ImGuiDockNode* DebugHoveredDockNode; // Hovered dock node.
|
||||
|
||||
// Misc
|
||||
float FramerateSecPerFrame[60]; // Calculate estimate of framerate for user over the last 60 frames..
|
||||
@@ -2169,13 +2403,14 @@ struct ImGuiContext
|
||||
InputTextState.Ctx = this;
|
||||
|
||||
Initialized = false;
|
||||
ConfigFlagsCurrFrame = ConfigFlagsLastFrame = ImGuiConfigFlags_None;
|
||||
FontAtlasOwnedByContext = shared_font_atlas ? false : true;
|
||||
Font = NULL;
|
||||
FontSize = FontBaseSize = 0.0f;
|
||||
IO.Fonts = shared_font_atlas ? shared_font_atlas : IM_NEW(ImFontAtlas)();
|
||||
Time = 0.0f;
|
||||
FrameCount = 0;
|
||||
FrameCountEnded = FrameCountRendered = -1;
|
||||
FrameCountEnded = FrameCountPlatformEnded = FrameCountRendered = -1;
|
||||
WithinFrameScope = WithinFrameScopeWithImplicitWindow = WithinEndChild = false;
|
||||
GcCompactAll = false;
|
||||
TestEngineHookItems = false;
|
||||
@@ -2218,6 +2453,8 @@ struct ImGuiContext
|
||||
LastActiveId = 0;
|
||||
LastActiveIdTimer = 0.0f;
|
||||
|
||||
LastKeyboardKeyPressTime = LastKeyModsChangeTime = LastKeyModsChangeFromNoneTime = -1.0;
|
||||
|
||||
ActiveIdUsingNavDirMask = 0x00;
|
||||
ActiveIdUsingAllKeyboardKeys = false;
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
|
||||
@@ -2229,6 +2466,13 @@ struct ImGuiContext
|
||||
DebugShowGroupRects = false;
|
||||
BeginMenuCount = 0;
|
||||
|
||||
CurrentDpiScale = 0.0f;
|
||||
CurrentViewport = NULL;
|
||||
MouseViewport = MouseLastHoveredViewport = NULL;
|
||||
PlatformLastFocusedViewportId = 0;
|
||||
ViewportCreatedCount = PlatformWindowsCreatedCount = 0;
|
||||
ViewportFocusedStampCount = 0;
|
||||
|
||||
NavWindow = NULL;
|
||||
NavId = NavFocusScopeId = NavActivateId = NavActivateDownId = NavActivatePressedId = 0;
|
||||
NavJustMovedToId = NavJustMovedToFocusScopeId = NavNextActivateId = 0;
|
||||
@@ -2307,6 +2551,9 @@ struct ImGuiContext
|
||||
|
||||
PlatformImeData.InputPos = ImVec2(0.0f, 0.0f);
|
||||
PlatformImeDataPrev.InputPos = ImVec2(-1.0f, -1.0f); // Different to ensure initial submission
|
||||
PlatformImeViewport = 0;
|
||||
|
||||
DockNodeWindowMenuHandler = NULL;
|
||||
|
||||
SettingsLoaded = false;
|
||||
SettingsDirtyTimer = 0.0f;
|
||||
@@ -2325,12 +2572,23 @@ struct ImGuiContext
|
||||
|
||||
DebugLogFlags = ImGuiDebugLogFlags_OutputToTTY;
|
||||
DebugLocateId = 0;
|
||||
DebugLogClipperAutoDisableFrames = 0;
|
||||
DebugLogAutoDisableFlags = ImGuiDebugLogFlags_None;
|
||||
DebugLogAutoDisableFrames = 0;
|
||||
DebugLocateFrames = 0;
|
||||
DebugBeginReturnValueCullDepth = -1;
|
||||
DebugItemPickerActive = false;
|
||||
DebugItemPickerMouseButton = ImGuiMouseButton_Left;
|
||||
DebugItemPickerBreakId = 0;
|
||||
DebugFlashStyleColorTime = 0.0f;
|
||||
DebugFlashStyleColorIdx = ImGuiCol_COUNT;
|
||||
DebugHoveredDockNode = NULL;
|
||||
|
||||
// Same as DebugBreakClearData(). Those fields are scattered in their respective subsystem to stay in hot-data locations
|
||||
DebugBreakInWindow = 0;
|
||||
DebugBreakInTable = 0;
|
||||
DebugBreakInLocateId = false;
|
||||
DebugBreakKeyChord = ImGuiKey_Pause;
|
||||
DebugBreakInShortcutRouting = ImGuiKey_None;
|
||||
|
||||
memset(FramerateSecPerFrame, 0, sizeof(FramerateSecPerFrame));
|
||||
FramerateSecPerFrameIdx = FramerateSecPerFrameCount = 0;
|
||||
@@ -2400,9 +2658,13 @@ struct IMGUI_API ImGuiWindow
|
||||
ImGuiContext* Ctx; // Parent UI context (needs to be set explicitly by parent).
|
||||
char* Name; // Window name, owned by the window.
|
||||
ImGuiID ID; // == ImHashStr(Name)
|
||||
ImGuiWindowFlags Flags; // See enum ImGuiWindowFlags_
|
||||
ImGuiWindowFlags Flags, FlagsPreviousFrame; // See enum ImGuiWindowFlags_
|
||||
ImGuiChildFlags ChildFlags; // Set when window is a child window. See enum ImGuiChildFlags_
|
||||
ImGuiWindowClass WindowClass; // Advanced users only. Set with SetNextWindowClass()
|
||||
ImGuiViewportP* Viewport; // Always set in Begin(). Inactive windows may have a NULL value here if their viewport was discarded.
|
||||
ImGuiID ViewportId; // We backup the viewport id (since the viewport may disappear or never be created if the window is inactive)
|
||||
ImVec2 ViewportPos; // We backup the viewport position (since the viewport may disappear or never be created if the window is inactive)
|
||||
int ViewportAllowPlatformMonitorExtend; // Reset to -1 every frame (index is guaranteed to be valid between NewFrame..EndFrame), only used in the Appearing frame of a tooltip/popup to enforce clamping to a given monitor
|
||||
ImVec2 Pos; // Position (always rounded-up to nearest pixel)
|
||||
ImVec2 Size; // Current size (==SizeFull or collapsed title bar size)
|
||||
ImVec2 SizeFull; // Size when non collapsed
|
||||
@@ -2417,6 +2679,7 @@ struct IMGUI_API ImGuiWindow
|
||||
float DecoInnerSizeX1, DecoInnerSizeY1; // Applied AFTER/OVER InnerRect. Specialized for Tables as they use specialized form of clipping and frozen rows/columns are inside InnerRect (and not part of regular decoration sizes).
|
||||
int NameBufLen; // Size of buffer storing Name. May be larger than strlen(Name)!
|
||||
ImGuiID MoveId; // == window->GetID("#MOVE")
|
||||
ImGuiID TabId; // == window->GetID("#TAB")
|
||||
ImGuiID ChildId; // ID of corresponding item in parent window (for navigation to return from child window to parent window)
|
||||
ImVec2 Scroll;
|
||||
ImVec2 ScrollMax;
|
||||
@@ -2425,6 +2688,7 @@ struct IMGUI_API ImGuiWindow
|
||||
ImVec2 ScrollTargetEdgeSnapDist; // 0.0f = no snapping, >0.0f snapping threshold
|
||||
ImVec2 ScrollbarSizes; // Size taken by each scrollbars on their smaller axis. Pay attention! ScrollbarSizes.x == width of the vertical scrollbar, ScrollbarSizes.y = height of the horizontal scrollbar.
|
||||
bool ScrollbarX, ScrollbarY; // Are scrollbars visible?
|
||||
bool ViewportOwned;
|
||||
bool Active; // Set to true on Begin(), unless Collapsed
|
||||
bool WasActive;
|
||||
bool WriteAccessed; // Set to true when any widget access the current window
|
||||
@@ -2454,6 +2718,7 @@ struct IMGUI_API ImGuiWindow
|
||||
ImGuiCond SetWindowPosAllowFlags : 8; // store acceptable condition flags for SetNextWindowPos() use.
|
||||
ImGuiCond SetWindowSizeAllowFlags : 8; // store acceptable condition flags for SetNextWindowSize() use.
|
||||
ImGuiCond SetWindowCollapsedAllowFlags : 8; // store acceptable condition flags for SetNextWindowCollapsed() use.
|
||||
ImGuiCond SetWindowDockAllowFlags : 8; // store acceptable condition flags for SetNextWindowDock() use.
|
||||
ImVec2 SetWindowPosVal; // store window position when using a non-zero Pivot (position set needs to be processed when we know the window size)
|
||||
ImVec2 SetWindowPosPivot; // store window pivot for positioning. ImVec2(0, 0) when positioning from top-left corner; ImVec2(0.5f, 0.5f) for centering; ImVec2(1, 1) for bottom right.
|
||||
|
||||
@@ -2473,11 +2738,13 @@ struct IMGUI_API ImGuiWindow
|
||||
ImVec2ih HitTestHoleOffset;
|
||||
|
||||
int LastFrameActive; // Last frame number the window was Active.
|
||||
int LastFrameJustFocused; // Last frame number the window was made Focused.
|
||||
float LastTimeActive; // Last timestamp the window was Active (using float as we don't need high precision there)
|
||||
float ItemWidthDefault;
|
||||
ImGuiStorage StateStorage;
|
||||
ImVector<ImGuiOldColumns> ColumnsStorage;
|
||||
float FontWindowScale; // User scale multiplier per-window, via SetWindowFontScale()
|
||||
float FontDpiScale;
|
||||
int SettingsOffset; // Offset into SettingsWindows[] (offsets are always valid as we only grow the array from the back)
|
||||
|
||||
ImDrawList* DrawList; // == &DrawListInst (for backward compatibility reason with code using imgui_internal.h we keep this a pointer)
|
||||
@@ -2486,6 +2753,7 @@ struct IMGUI_API ImGuiWindow
|
||||
ImGuiWindow* ParentWindowInBeginStack;
|
||||
ImGuiWindow* RootWindow; // Point to ourself or first ancestor that is not a child window. Doesn't cross through popups/dock nodes.
|
||||
ImGuiWindow* RootWindowPopupTree; // Point to ourself or first ancestor that is not a child window. Cross through popups parent<>child.
|
||||
ImGuiWindow* RootWindowDockTree; // Point to ourself or first ancestor that is not a child window. Cross through dock nodes.
|
||||
ImGuiWindow* RootWindowForTitleBarHighlight; // Point to ourself or first ancestor which will display TitleBgActive color when this window is active.
|
||||
ImGuiWindow* RootWindowForNav; // Point to ourself or first ancestor which doesn't have the NavFlattened flag.
|
||||
|
||||
@@ -2499,6 +2767,19 @@ struct IMGUI_API ImGuiWindow
|
||||
int MemoryDrawListVtxCapacity;
|
||||
bool MemoryCompacted; // Set when window extraneous data have been garbage collected
|
||||
|
||||
// Docking
|
||||
bool DockIsActive :1; // When docking artifacts are actually visible. When this is set, DockNode is guaranteed to be != NULL. ~~ (DockNode != NULL) && (DockNode->Windows.Size > 1).
|
||||
bool DockNodeIsVisible :1;
|
||||
bool DockTabIsVisible :1; // Is our window visible this frame? ~~ is the corresponding tab selected?
|
||||
bool DockTabWantClose :1;
|
||||
short DockOrder; // Order of the last time the window was visible within its DockNode. This is used to reorder windows that are reappearing on the same frame. Same value between windows that were active and windows that were none are possible.
|
||||
ImGuiWindowDockStyle DockStyle;
|
||||
ImGuiDockNode* DockNode; // Which node are we docked into. Important: Prefer testing DockIsActive in many cases as this will still be set when the dock node is hidden.
|
||||
ImGuiDockNode* DockNodeAsHost; // Which node are we owning (for parent windows)
|
||||
ImGuiID DockId; // Backup of last valid DockNode->ID, so single window remember their dock node id even when they are not bound any more
|
||||
ImGuiItemStatusFlags DockTabItemStatusFlags;
|
||||
ImRect DockTabItemRect;
|
||||
|
||||
public:
|
||||
ImGuiWindow(ImGuiContext* context, const char* name);
|
||||
~ImGuiWindow();
|
||||
@@ -2510,7 +2791,7 @@ public:
|
||||
|
||||
// We don't use g.FontSize because the window may be != g.CurrentWindow.
|
||||
ImRect Rect() const { return ImRect(Pos.x, Pos.y, Pos.x + Size.x, Pos.y + Size.y); }
|
||||
float CalcFontSize() const { ImGuiContext& g = *Ctx; float scale = g.FontBaseSize * FontWindowScale; if (ParentWindow) scale *= ParentWindow->FontWindowScale; return scale; }
|
||||
float CalcFontSize() const { ImGuiContext& g = *Ctx; float scale = g.FontBaseSize * FontWindowScale * FontDpiScale; if (ParentWindow) scale *= ParentWindow->FontWindowScale; return scale; }
|
||||
float TitleBarHeight() const { ImGuiContext& g = *Ctx; return (Flags & ImGuiWindowFlags_NoTitleBar) ? 0.0f : CalcFontSize() + g.Style.FramePadding.y * 2.0f; }
|
||||
ImRect TitleBarRect() const { return ImRect(Pos, ImVec2(Pos.x + SizeFull.x, Pos.y + TitleBarHeight())); }
|
||||
float MenuBarHeight() const { ImGuiContext& g = *Ctx; return (Flags & ImGuiWindowFlags_MenuBar) ? DC.MenuBarOffset.y + CalcFontSize() + g.Style.FramePadding.y * 2.0f : 0.0f; }
|
||||
@@ -2535,13 +2816,15 @@ enum ImGuiTabItemFlagsPrivate_
|
||||
ImGuiTabItemFlags_SectionMask_ = ImGuiTabItemFlags_Leading | ImGuiTabItemFlags_Trailing,
|
||||
ImGuiTabItemFlags_NoCloseButton = 1 << 20, // Track whether p_open was set or not (we'll need this info on the next frame to recompute ContentWidth during layout)
|
||||
ImGuiTabItemFlags_Button = 1 << 21, // Used by TabItemButton, change the tab item behavior to mimic a button
|
||||
ImGuiTabItemFlags_Unsorted = 1 << 22, // [Docking] Trailing tabs with the _Unsorted flag will be sorted based on the DockOrder of their Window.
|
||||
};
|
||||
|
||||
// Storage for one active tab item (sizeof() 40 bytes)
|
||||
// Storage for one active tab item (sizeof() 48 bytes)
|
||||
struct ImGuiTabItem
|
||||
{
|
||||
ImGuiID ID;
|
||||
ImGuiTabItemFlags Flags;
|
||||
ImGuiWindow* Window; // When TabItem is part of a DockNode's TabBar, we hold on to a window.
|
||||
int LastFrameVisible;
|
||||
int LastFrameSelected; // This allows us to infer an ordered list of the last activated tabs with little maintenance
|
||||
float Offset; // Position relative to beginning of tab
|
||||
@@ -2892,7 +3175,7 @@ namespace ImGui
|
||||
IMGUI_API ImGuiWindow* FindWindowByName(const char* name);
|
||||
IMGUI_API void UpdateWindowParentAndRootLinks(ImGuiWindow* window, ImGuiWindowFlags flags, ImGuiWindow* parent_window);
|
||||
IMGUI_API ImVec2 CalcWindowNextAutoFitSize(ImGuiWindow* window);
|
||||
IMGUI_API bool IsWindowChildOf(ImGuiWindow* window, ImGuiWindow* potential_parent, bool popup_hierarchy);
|
||||
IMGUI_API bool IsWindowChildOf(ImGuiWindow* window, ImGuiWindow* potential_parent, bool popup_hierarchy, bool dock_hierarchy);
|
||||
IMGUI_API bool IsWindowWithinBeginStackOf(ImGuiWindow* window, ImGuiWindow* potential_parent);
|
||||
IMGUI_API bool IsWindowAbove(ImGuiWindow* potential_above, ImGuiWindow* potential_below);
|
||||
IMGUI_API bool IsWindowNavFocusable(ImGuiWindow* window);
|
||||
@@ -2900,7 +3183,7 @@ namespace ImGui
|
||||
IMGUI_API void SetWindowSize(ImGuiWindow* window, const ImVec2& size, ImGuiCond cond = 0);
|
||||
IMGUI_API void SetWindowCollapsed(ImGuiWindow* window, bool collapsed, ImGuiCond cond = 0);
|
||||
IMGUI_API void SetWindowHitTestHole(ImGuiWindow* window, const ImVec2& pos, const ImVec2& size);
|
||||
IMGUI_API void SetWindowHiddendAndSkipItemsForCurrentFrame(ImGuiWindow* window);
|
||||
IMGUI_API void SetWindowHiddenAndSkipItemsForCurrentFrame(ImGuiWindow* window);
|
||||
inline ImRect WindowRectAbsToRel(ImGuiWindow* window, const ImRect& r) { ImVec2 off = window->DC.CursorStartPos; return ImRect(r.Min.x - off.x, r.Min.y - off.y, r.Max.x - off.x, r.Max.y - off.y); }
|
||||
inline ImRect WindowRectRelToAbs(ImGuiWindow* window, const ImRect& r) { ImVec2 off = window->DC.CursorStartPos; return ImRect(r.Min.x + off.x, r.Min.y + off.y, r.Max.x + off.x, r.Max.y + off.y); }
|
||||
inline ImVec2 WindowPosRelToAbs(ImGuiWindow* window, const ImVec2& p) { ImVec2 off = window->DC.CursorStartPos; return ImVec2(p.x + off.x, p.y + off.y); }
|
||||
@@ -2918,9 +3201,7 @@ namespace ImGui
|
||||
// Fonts, drawing
|
||||
IMGUI_API void SetCurrentFont(ImFont* font);
|
||||
inline ImFont* GetDefaultFont() { ImGuiContext& g = *GImGui; return g.IO.FontDefault ? g.IO.FontDefault : g.IO.Fonts->Fonts[0]; }
|
||||
inline ImDrawList* GetForegroundDrawList(ImGuiWindow* window) { IM_UNUSED(window); return GetForegroundDrawList(); } // This seemingly unnecessary wrapper simplifies compatibility between the 'master' and 'docking' branches.
|
||||
IMGUI_API ImDrawList* GetBackgroundDrawList(ImGuiViewport* viewport); // get background draw list for the given viewport. this draw list will be the first rendering one. Useful to quickly draw shapes/text behind dear imgui contents.
|
||||
IMGUI_API ImDrawList* GetForegroundDrawList(ImGuiViewport* viewport); // get foreground draw list for the given viewport. this draw list will be the last rendered one. Useful to quickly draw shapes/text over dear imgui contents.
|
||||
inline ImDrawList* GetForegroundDrawList(ImGuiWindow* window) { return GetForegroundDrawList(window->Viewport); }
|
||||
IMGUI_API void AddDrawListToDrawDataEx(ImDrawData* draw_data, ImVector<ImDrawList*>* out_list, ImDrawList* draw_list);
|
||||
|
||||
// Init
|
||||
@@ -2931,6 +3212,7 @@ namespace ImGui
|
||||
IMGUI_API void UpdateInputEvents(bool trickle_fast_inputs);
|
||||
IMGUI_API void UpdateHoveredWindowAndCaptureFlags();
|
||||
IMGUI_API void StartMouseMovingWindow(ImGuiWindow* window);
|
||||
IMGUI_API void StartMouseMovingWindowOrNode(ImGuiWindow* window, ImGuiDockNode* node, bool undock);
|
||||
IMGUI_API void UpdateMouseMovingWindowNewFrame();
|
||||
IMGUI_API void UpdateMouseMovingWindowEndFrame();
|
||||
|
||||
@@ -2940,7 +3222,13 @@ namespace ImGui
|
||||
IMGUI_API void CallContextHooks(ImGuiContext* context, ImGuiContextHookType type);
|
||||
|
||||
// Viewports
|
||||
IMGUI_API void TranslateWindowsInViewport(ImGuiViewportP* viewport, const ImVec2& old_pos, const ImVec2& new_pos);
|
||||
IMGUI_API void ScaleWindowsInViewport(ImGuiViewportP* viewport, float scale);
|
||||
IMGUI_API void DestroyPlatformWindow(ImGuiViewportP* viewport);
|
||||
IMGUI_API void SetWindowViewport(ImGuiWindow* window, ImGuiViewportP* viewport);
|
||||
IMGUI_API void SetCurrentViewport(ImGuiWindow* window, ImGuiViewportP* viewport);
|
||||
IMGUI_API const ImGuiPlatformMonitor* GetViewportPlatformMonitor(ImGuiViewport* viewport);
|
||||
IMGUI_API ImGuiViewportP* FindHoveredViewportFromPlatformWindowStack(const ImVec2& mouse_platform_pos);
|
||||
|
||||
// Settings
|
||||
IMGUI_API void MarkIniSettingsDirty();
|
||||
@@ -3089,7 +3377,7 @@ namespace ImGui
|
||||
|
||||
IMGUI_API ImGuiKeyData* GetKeyData(ImGuiContext* ctx, ImGuiKey key);
|
||||
inline ImGuiKeyData* GetKeyData(ImGuiKey key) { ImGuiContext& g = *GImGui; return GetKeyData(&g, key); }
|
||||
IMGUI_API void GetKeyChordName(ImGuiKeyChord key_chord, char* out_buf, int out_buf_size);
|
||||
IMGUI_API const char* GetKeyChordName(ImGuiKeyChord key_chord, char* out_buf, int out_buf_size);
|
||||
inline ImGuiKey MouseButtonToKey(ImGuiMouseButton button) { IM_ASSERT(button >= 0 && button < ImGuiMouseButton_COUNT); return (ImGuiKey)(ImGuiKey_MouseLeft + button); }
|
||||
IMGUI_API bool IsMouseDragPastThreshold(ImGuiMouseButton button, float lock_threshold = -1.0f);
|
||||
IMGUI_API ImVec2 GetKeyMagnitude2d(ImGuiKey key_left, ImGuiKey key_right, ImGuiKey key_up, ImGuiKey key_down);
|
||||
@@ -3151,6 +3439,61 @@ namespace ImGui
|
||||
IMGUI_API bool TestShortcutRouting(ImGuiKeyChord key_chord, ImGuiID owner_id);
|
||||
IMGUI_API ImGuiKeyRoutingData* GetShortcutRoutingData(ImGuiKeyChord key_chord);
|
||||
|
||||
// Docking
|
||||
// (some functions are only declared in imgui.cpp, see Docking section)
|
||||
IMGUI_API void DockContextInitialize(ImGuiContext* ctx);
|
||||
IMGUI_API void DockContextShutdown(ImGuiContext* ctx);
|
||||
IMGUI_API void DockContextClearNodes(ImGuiContext* ctx, ImGuiID root_id, bool clear_settings_refs); // Use root_id==0 to clear all
|
||||
IMGUI_API void DockContextRebuildNodes(ImGuiContext* ctx);
|
||||
IMGUI_API void DockContextNewFrameUpdateUndocking(ImGuiContext* ctx);
|
||||
IMGUI_API void DockContextNewFrameUpdateDocking(ImGuiContext* ctx);
|
||||
IMGUI_API void DockContextEndFrame(ImGuiContext* ctx);
|
||||
IMGUI_API ImGuiID DockContextGenNodeID(ImGuiContext* ctx);
|
||||
IMGUI_API void DockContextQueueDock(ImGuiContext* ctx, ImGuiWindow* target, ImGuiDockNode* target_node, ImGuiWindow* payload, ImGuiDir split_dir, float split_ratio, bool split_outer);
|
||||
IMGUI_API void DockContextQueueUndockWindow(ImGuiContext* ctx, ImGuiWindow* window);
|
||||
IMGUI_API void DockContextQueueUndockNode(ImGuiContext* ctx, ImGuiDockNode* node);
|
||||
IMGUI_API void DockContextProcessUndockWindow(ImGuiContext* ctx, ImGuiWindow* window, bool clear_persistent_docking_ref = true);
|
||||
IMGUI_API void DockContextProcessUndockNode(ImGuiContext* ctx, ImGuiDockNode* node);
|
||||
IMGUI_API bool DockContextCalcDropPosForDocking(ImGuiWindow* target, ImGuiDockNode* target_node, ImGuiWindow* payload_window, ImGuiDockNode* payload_node, ImGuiDir split_dir, bool split_outer, ImVec2* out_pos);
|
||||
IMGUI_API ImGuiDockNode*DockContextFindNodeByID(ImGuiContext* ctx, ImGuiID id);
|
||||
IMGUI_API void DockNodeWindowMenuHandler_Default(ImGuiContext* ctx, ImGuiDockNode* node, ImGuiTabBar* tab_bar);
|
||||
IMGUI_API bool DockNodeBeginAmendTabBar(ImGuiDockNode* node);
|
||||
IMGUI_API void DockNodeEndAmendTabBar();
|
||||
inline ImGuiDockNode* DockNodeGetRootNode(ImGuiDockNode* node) { while (node->ParentNode) node = node->ParentNode; return node; }
|
||||
inline bool DockNodeIsInHierarchyOf(ImGuiDockNode* node, ImGuiDockNode* parent) { while (node) { if (node == parent) return true; node = node->ParentNode; } return false; }
|
||||
inline int DockNodeGetDepth(const ImGuiDockNode* node) { int depth = 0; while (node->ParentNode) { node = node->ParentNode; depth++; } return depth; }
|
||||
inline ImGuiID DockNodeGetWindowMenuButtonId(const ImGuiDockNode* node) { return ImHashStr("#COLLAPSE", 0, node->ID); }
|
||||
inline ImGuiDockNode* GetWindowDockNode() { ImGuiContext& g = *GImGui; return g.CurrentWindow->DockNode; }
|
||||
IMGUI_API bool GetWindowAlwaysWantOwnTabBar(ImGuiWindow* window);
|
||||
IMGUI_API void BeginDocked(ImGuiWindow* window, bool* p_open);
|
||||
IMGUI_API void BeginDockableDragDropSource(ImGuiWindow* window);
|
||||
IMGUI_API void BeginDockableDragDropTarget(ImGuiWindow* window);
|
||||
IMGUI_API void SetWindowDock(ImGuiWindow* window, ImGuiID dock_id, ImGuiCond cond);
|
||||
|
||||
// Docking - Builder function needs to be generally called before the node is used/submitted.
|
||||
// - The DockBuilderXXX functions are designed to _eventually_ become a public API, but it is too early to expose it and guarantee stability.
|
||||
// - Do not hold on ImGuiDockNode* pointers! They may be invalidated by any split/merge/remove operation and every frame.
|
||||
// - To create a DockSpace() node, make sure to set the ImGuiDockNodeFlags_DockSpace flag when calling DockBuilderAddNode().
|
||||
// You can create dockspace nodes (attached to a window) _or_ floating nodes (carry its own window) with this API.
|
||||
// - DockBuilderSplitNode() create 2 child nodes within 1 node. The initial node becomes a parent node.
|
||||
// - If you intend to split the node immediately after creation using DockBuilderSplitNode(), make sure
|
||||
// to call DockBuilderSetNodeSize() beforehand. If you don't, the resulting split sizes may not be reliable.
|
||||
// - Call DockBuilderFinish() after you are done.
|
||||
IMGUI_API void DockBuilderDockWindow(const char* window_name, ImGuiID node_id);
|
||||
IMGUI_API ImGuiDockNode*DockBuilderGetNode(ImGuiID node_id);
|
||||
inline ImGuiDockNode* DockBuilderGetCentralNode(ImGuiID node_id) { ImGuiDockNode* node = DockBuilderGetNode(node_id); if (!node) return NULL; return DockNodeGetRootNode(node)->CentralNode; }
|
||||
IMGUI_API ImGuiID DockBuilderAddNode(ImGuiID node_id = 0, ImGuiDockNodeFlags flags = 0);
|
||||
IMGUI_API void DockBuilderRemoveNode(ImGuiID node_id); // Remove node and all its child, undock all windows
|
||||
IMGUI_API void DockBuilderRemoveNodeDockedWindows(ImGuiID node_id, bool clear_settings_refs = true);
|
||||
IMGUI_API void DockBuilderRemoveNodeChildNodes(ImGuiID node_id); // Remove all split/hierarchy. All remaining docked windows will be re-docked to the remaining root node (node_id).
|
||||
IMGUI_API void DockBuilderSetNodePos(ImGuiID node_id, ImVec2 pos);
|
||||
IMGUI_API void DockBuilderSetNodeSize(ImGuiID node_id, ImVec2 size);
|
||||
IMGUI_API ImGuiID DockBuilderSplitNode(ImGuiID node_id, ImGuiDir split_dir, float size_ratio_for_node_at_dir, ImGuiID* out_id_at_dir, ImGuiID* out_id_at_opposite_dir); // Create 2 child nodes in this parent node.
|
||||
IMGUI_API void DockBuilderCopyDockSpace(ImGuiID src_dockspace_id, ImGuiID dst_dockspace_id, ImVector<const char*>* in_window_remap_pairs);
|
||||
IMGUI_API void DockBuilderCopyNode(ImGuiID src_node_id, ImGuiID dst_node_id, ImVector<ImGuiID>* out_node_remap_pairs);
|
||||
IMGUI_API void DockBuilderCopyWindowSettings(const char* src_name, const char* dst_name);
|
||||
IMGUI_API void DockBuilderFinish(ImGuiID node_id);
|
||||
|
||||
// [EXPERIMENTAL] Focus Scope
|
||||
// This is generally used to identify a unique input location (for e.g. a selection set)
|
||||
// There is one per window (automatically set in Begin), but:
|
||||
@@ -3168,7 +3511,7 @@ namespace ImGui
|
||||
IMGUI_API bool BeginDragDropTargetCustom(const ImRect& bb, ImGuiID id);
|
||||
IMGUI_API void ClearDragDrop();
|
||||
IMGUI_API bool IsDragDropPayloadBeingAccepted();
|
||||
IMGUI_API void RenderDragDropTargetRect(const ImRect& bb);
|
||||
IMGUI_API void RenderDragDropTargetRect(const ImRect& bb, const ImRect& item_clip_rect);
|
||||
|
||||
// Typing-Select API
|
||||
IMGUI_API ImGuiTypingSelectRequest* GetTypingSelectRequest(ImGuiTypingSelectFlags flags = ImGuiTypingSelectFlags_None);
|
||||
@@ -3250,9 +3593,11 @@ namespace ImGui
|
||||
IMGUI_API bool BeginTabBarEx(ImGuiTabBar* tab_bar, const ImRect& bb, ImGuiTabBarFlags flags);
|
||||
IMGUI_API ImGuiTabItem* TabBarFindTabByID(ImGuiTabBar* tab_bar, ImGuiID tab_id);
|
||||
IMGUI_API ImGuiTabItem* TabBarFindTabByOrder(ImGuiTabBar* tab_bar, int order);
|
||||
IMGUI_API ImGuiTabItem* TabBarFindMostRecentlySelectedTabForActiveWindow(ImGuiTabBar* tab_bar);
|
||||
IMGUI_API ImGuiTabItem* TabBarGetCurrentTab(ImGuiTabBar* tab_bar);
|
||||
inline int TabBarGetTabOrder(ImGuiTabBar* tab_bar, ImGuiTabItem* tab) { return tab_bar->Tabs.index_from_ptr(tab); }
|
||||
IMGUI_API const char* TabBarGetTabName(ImGuiTabBar* tab_bar, ImGuiTabItem* tab);
|
||||
IMGUI_API void TabBarAddTab(ImGuiTabBar* tab_bar, ImGuiTabItemFlags tab_flags, ImGuiWindow* window);
|
||||
IMGUI_API void TabBarRemoveTab(ImGuiTabBar* tab_bar, ImGuiID tab_id);
|
||||
IMGUI_API void TabBarCloseTab(ImGuiTabBar* tab_bar, ImGuiTabItem* tab);
|
||||
IMGUI_API void TabBarQueueFocus(ImGuiTabBar* tab_bar, ImGuiTabItem* tab);
|
||||
@@ -3285,8 +3630,10 @@ namespace ImGui
|
||||
IMGUI_API void RenderBullet(ImDrawList* draw_list, ImVec2 pos, ImU32 col);
|
||||
IMGUI_API void RenderCheckMark(ImDrawList* draw_list, ImVec2 pos, ImU32 col, float sz);
|
||||
IMGUI_API void RenderArrowPointingAt(ImDrawList* draw_list, ImVec2 pos, ImVec2 half_sz, ImGuiDir direction, ImU32 col);
|
||||
IMGUI_API void RenderArrowDockMenu(ImDrawList* draw_list, ImVec2 p_min, float sz, ImU32 col);
|
||||
IMGUI_API void RenderRectFilledRangeH(ImDrawList* draw_list, const ImRect& rect, ImU32 col, float x_start_norm, float x_end_norm, float rounding);
|
||||
IMGUI_API void RenderRectFilledWithHole(ImDrawList* draw_list, const ImRect& outer, const ImRect& inner, ImU32 col, float rounding);
|
||||
IMGUI_API ImDrawFlags CalcRoundingFlagsForRectInRect(const ImRect& r_in, const ImRect& r_outer, float threshold);
|
||||
|
||||
// Widgets
|
||||
IMGUI_API void TextEx(const char* text, const char* text_end = NULL, ImGuiTextFlags flags = 0);
|
||||
@@ -3300,7 +3647,7 @@ namespace ImGui
|
||||
|
||||
// Widgets: Window Decorations
|
||||
IMGUI_API bool CloseButton(ImGuiID id, const ImVec2& pos);
|
||||
IMGUI_API bool CollapseButton(ImGuiID id, const ImVec2& pos);
|
||||
IMGUI_API bool CollapseButton(ImGuiID id, const ImVec2& pos, ImGuiDockNode* dock_node);
|
||||
IMGUI_API void Scrollbar(ImGuiAxis axis);
|
||||
IMGUI_API bool ScrollbarEx(const ImRect& bb, ImGuiID id, ImGuiAxis axis, ImS64* p_scroll_v, ImS64 avail_v, ImS64 contents_v, ImDrawFlags flags);
|
||||
IMGUI_API ImRect GetWindowScrollbarRect(ImGuiWindow* window, ImGuiAxis axis);
|
||||
@@ -3378,10 +3725,14 @@ namespace ImGui
|
||||
IMGUI_API void DebugLocateItem(ImGuiID target_id); // Call sparingly: only 1 at the same time!
|
||||
IMGUI_API void DebugLocateItemOnHover(ImGuiID target_id); // Only call on reaction to a mouse Hover: because only 1 at the same time!
|
||||
IMGUI_API void DebugLocateItemResolveWithLastItem();
|
||||
IMGUI_API void DebugBreakClearData();
|
||||
IMGUI_API bool DebugBreakButton(const char* label, const char* description_of_location);
|
||||
IMGUI_API void DebugBreakButtonTooltip(bool keyboard_only, const char* description_of_location);
|
||||
inline void DebugStartItemPicker() { ImGuiContext& g = *GImGui; g.DebugItemPickerActive = true; }
|
||||
IMGUI_API void ShowFontAtlas(ImFontAtlas* atlas);
|
||||
IMGUI_API void DebugHookIdInfo(ImGuiID id, ImGuiDataType data_type, const void* data_id, const void* data_id_end);
|
||||
IMGUI_API void DebugNodeColumns(ImGuiOldColumns* columns);
|
||||
IMGUI_API void DebugNodeDockNode(ImGuiDockNode* node, const char* label);
|
||||
IMGUI_API void DebugNodeDrawList(ImGuiWindow* window, ImGuiViewportP* viewport, const ImDrawList* draw_list, const char* label);
|
||||
IMGUI_API void DebugNodeDrawCmdShowMeshAndBoundingBox(ImDrawList* out_draw_list, const ImDrawList* draw_list, const ImDrawCmd* draw_cmd, bool show_mesh, bool show_aabb);
|
||||
IMGUI_API void DebugNodeFont(ImFont* font);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.90.0
|
||||
// dear imgui, v1.90.1
|
||||
// (tables and columns code)
|
||||
|
||||
/*
|
||||
@@ -329,6 +329,10 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
|
||||
return false;
|
||||
}
|
||||
|
||||
// [DEBUG] Debug break requested by user
|
||||
if (g.DebugBreakInTable == id)
|
||||
IM_DEBUG_BREAK();
|
||||
|
||||
// Acquire storage for the table
|
||||
ImGuiTable* table = g.Tables.GetOrAddByKey(id);
|
||||
const ImGuiTableFlags table_last_flags = table->Flags;
|
||||
@@ -3802,7 +3806,8 @@ static const char* DebugNodeTableGetSizingPolicyDesc(ImGuiTableFlags sizing_poli
|
||||
|
||||
void ImGui::DebugNodeTable(ImGuiTable* table)
|
||||
{
|
||||
const bool is_active = (table->LastFrameActive >= GetFrameCount() - 2); // Note that fully clipped early out scrolling tables will appear as inactive here.
|
||||
ImGuiContext& g = *GImGui;
|
||||
const bool is_active = (table->LastFrameActive >= g.FrameCount - 2); // Note that fully clipped early out scrolling tables will appear as inactive here.
|
||||
if (!is_active) { PushStyleColor(ImGuiCol_Text, GetStyleColorVec4(ImGuiCol_TextDisabled)); }
|
||||
bool open = TreeNode(table, "Table 0x%08X (%d columns, in '%s')%s", table->ID, table->ColumnsCount, table->OuterWindow->Name, is_active ? "" : " *Inactive*");
|
||||
if (!is_active) { PopStyleColor(); }
|
||||
@@ -3814,6 +3819,13 @@ void ImGui::DebugNodeTable(ImGuiTable* table)
|
||||
return;
|
||||
if (table->InstanceCurrent > 0)
|
||||
Text("** %d instances of same table! Some data below will refer to last instance.", table->InstanceCurrent + 1);
|
||||
if (g.IO.ConfigDebugIsDebuggerPresent)
|
||||
{
|
||||
if (DebugBreakButton("**DebugBreak**", "in BeginTable()"))
|
||||
g.DebugBreakInTable = table->ID;
|
||||
SameLine();
|
||||
}
|
||||
|
||||
bool clear_settings = SmallButton("Clear settings");
|
||||
BulletText("OuterRect: Pos: (%.1f,%.1f) Size: (%.1f,%.1f) Sizing: '%s'", table->OuterRect.Min.x, table->OuterRect.Min.y, table->OuterRect.GetWidth(), table->OuterRect.GetHeight(), DebugNodeTableGetSizingPolicyDesc(table->Flags));
|
||||
BulletText("ColumnsGivenWidth: %.1f, ColumnsAutoFitWidth: %.1f, InnerWidth: %.1f%s", table->ColumnsGivenWidth, table->ColumnsAutoFitWidth, table->InnerWidth, table->InnerWidth == 0.0f ? " (auto)" : "");
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.90.0
|
||||
// dear imgui, v1.90.1
|
||||
// (widgets code)
|
||||
|
||||
/*
|
||||
@@ -499,7 +499,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
|
||||
item_flags |= ImGuiItemFlags_ButtonRepeat;
|
||||
|
||||
ImGuiWindow* backup_hovered_window = g.HoveredWindow;
|
||||
const bool flatten_hovered_children = (flags & ImGuiButtonFlags_FlattenChildren) && g.HoveredWindow && g.HoveredWindow->RootWindow == window;
|
||||
const bool flatten_hovered_children = (flags & ImGuiButtonFlags_FlattenChildren) && g.HoveredWindow && g.HoveredWindow->RootWindowDockTree == window->RootWindowDockTree;
|
||||
if (flatten_hovered_children)
|
||||
g.HoveredWindow = window;
|
||||
|
||||
@@ -835,7 +835,8 @@ bool ImGui::CloseButton(ImGuiID id, const ImVec2& pos)
|
||||
return pressed;
|
||||
}
|
||||
|
||||
bool ImGui::CollapseButton(ImGuiID id, const ImVec2& pos)
|
||||
// The Collapse button also functions as a Dock Menu button.
|
||||
bool ImGui::CollapseButton(ImGuiID id, const ImVec2& pos, ImGuiDockNode* dock_node)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
@@ -848,15 +849,20 @@ bool ImGui::CollapseButton(ImGuiID id, const ImVec2& pos)
|
||||
return pressed;
|
||||
|
||||
// Render
|
||||
//bool is_dock_menu = (window->DockNodeAsHost && !window->Collapsed);
|
||||
ImU32 bg_col = GetColorU32((held && hovered) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button);
|
||||
ImU32 text_col = GetColorU32(ImGuiCol_Text);
|
||||
if (hovered || held)
|
||||
window->DrawList->AddCircleFilled(bb.GetCenter() + ImVec2(0.0f, -0.5f), g.FontSize * 0.5f + 1.0f, bg_col);
|
||||
RenderArrow(window->DrawList, bb.Min, text_col, window->Collapsed ? ImGuiDir_Right : ImGuiDir_Down, 1.0f);
|
||||
|
||||
if (dock_node)
|
||||
RenderArrowDockMenu(window->DrawList, bb.Min, g.FontSize, text_col);
|
||||
else
|
||||
RenderArrow(window->DrawList, bb.Min, text_col, window->Collapsed ? ImGuiDir_Right : ImGuiDir_Down, 1.0f);
|
||||
|
||||
// Switch to moving the window after mouse is moved beyond the initial drag threshold
|
||||
if (IsItemActive() && IsMouseDragging(0))
|
||||
StartMouseMovingWindow(window);
|
||||
StartMouseMovingWindowOrNode(window, dock_node, true); // Undock from window/collapse menu button
|
||||
|
||||
return pressed;
|
||||
}
|
||||
@@ -1007,28 +1013,25 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, ImS6
|
||||
return held;
|
||||
}
|
||||
|
||||
void ImGui::Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& tint_col, const ImVec4& border_col)
|
||||
// - Read about ImTextureID here: https://github.com/ocornut/imgui/wiki/Image-Loading-and-Displaying-Examples
|
||||
// - 'uv0' and 'uv1' are texture coordinates. Read about them from the same link above.
|
||||
void ImGui::Image(ImTextureID user_texture_id, const ImVec2& image_size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& tint_col, const ImVec4& border_col)
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
if (window->SkipItems)
|
||||
return;
|
||||
|
||||
ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size);
|
||||
if (border_col.w > 0.0f)
|
||||
bb.Max += ImVec2(2, 2);
|
||||
const float border_size = (border_col.w > 0.0f) ? 1.0f : 0.0f;
|
||||
const ImVec2 padding(border_size, border_size);
|
||||
const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + image_size + padding * 2.0f);
|
||||
ItemSize(bb);
|
||||
if (!ItemAdd(bb, 0))
|
||||
return;
|
||||
|
||||
if (border_col.w > 0.0f)
|
||||
{
|
||||
window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(border_col), 0.0f);
|
||||
window->DrawList->AddImage(user_texture_id, bb.Min + ImVec2(1, 1), bb.Max - ImVec2(1, 1), uv0, uv1, GetColorU32(tint_col));
|
||||
}
|
||||
else
|
||||
{
|
||||
window->DrawList->AddImage(user_texture_id, bb.Min, bb.Max, uv0, uv1, GetColorU32(tint_col));
|
||||
}
|
||||
// Render
|
||||
if (border_size > 0.0f)
|
||||
window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(border_col), 0.0f, ImDrawFlags_None, border_size);
|
||||
window->DrawList->AddImage(user_texture_id, bb.Min + padding, bb.Max - padding, uv0, uv1, GetColorU32(tint_col));
|
||||
}
|
||||
|
||||
// ImageButton() is flawed as 'id' is always derived from 'texture_id' (see #2464 #1390)
|
||||
@@ -1482,7 +1485,7 @@ void ImGui::SeparatorTextEx(ImGuiID id, const char* label, const char* label_end
|
||||
const float separator_thickness = style.SeparatorTextBorderSize;
|
||||
const ImVec2 min_size(label_size.x + extra_w + padding.x * 2.0f, ImMax(label_size.y + padding.y * 2.0f, separator_thickness));
|
||||
const ImRect bb(pos, ImVec2(window->WorkRect.Max.x, pos.y + min_size.y));
|
||||
const float text_baseline_y = ImTrunc((bb.GetHeight() - label_size.y) * style.SeparatorTextAlign.y + 0.99999f); //ImMax(padding.y, ImFloor((style.SeparatorTextSize - label_size.y) * 0.5f));
|
||||
const float text_baseline_y = ImTrunc((bb.GetHeight() - label_size.y) * style.SeparatorTextAlign.y + 0.99999f); //ImMax(padding.y, ImTrunc((style.SeparatorTextSize - label_size.y) * 0.5f));
|
||||
ItemSize(min_size, text_baseline_y);
|
||||
if (!ItemAdd(bb, id))
|
||||
return;
|
||||
@@ -1679,7 +1682,7 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF
|
||||
const ImGuiID id = window->GetID(label);
|
||||
IM_ASSERT((flags & (ImGuiComboFlags_NoArrowButton | ImGuiComboFlags_NoPreview)) != (ImGuiComboFlags_NoArrowButton | ImGuiComboFlags_NoPreview)); // Can't use both flags together
|
||||
if (flags & ImGuiComboFlags_WidthFitPreview)
|
||||
IM_ASSERT((flags & (ImGuiComboFlags_NoPreview | ImGuiComboFlags_CustomPreview)) == 0);
|
||||
IM_ASSERT((flags & (ImGuiComboFlags_NoPreview | (ImGuiComboFlags)ImGuiComboFlags_CustomPreview)) == 0);
|
||||
|
||||
const float arrow_size = (flags & ImGuiComboFlags_NoArrowButton) ? 0.0f : GetFrameHeight();
|
||||
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
||||
@@ -2432,14 +2435,13 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data,
|
||||
if (!temp_input_is_active)
|
||||
{
|
||||
// Tabbing or CTRL-clicking on Drag turns it into an InputText
|
||||
const bool input_requested_by_tabbing = temp_input_allowed && (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_FocusedByTabbing) != 0;
|
||||
const bool clicked = hovered && IsMouseClicked(0, id);
|
||||
const bool double_clicked = (hovered && g.IO.MouseClickedCount[0] == 2 && TestKeyOwner(ImGuiKey_MouseLeft, id));
|
||||
const bool make_active = (input_requested_by_tabbing || clicked || double_clicked || g.NavActivateId == id);
|
||||
const bool make_active = (clicked || double_clicked || g.NavActivateId == id);
|
||||
if (make_active && (clicked || double_clicked))
|
||||
SetKeyOwner(ImGuiKey_MouseLeft, id);
|
||||
if (make_active && temp_input_allowed)
|
||||
if (input_requested_by_tabbing || (clicked && g.IO.KeyCtrl) || double_clicked || (g.NavActivateId == id && (g.NavActivateFlags & ImGuiActivateFlags_PreferInput)))
|
||||
if ((clicked && g.IO.KeyCtrl) || double_clicked || (g.NavActivateId == id && (g.NavActivateFlags & ImGuiActivateFlags_PreferInput)))
|
||||
temp_input_is_active = true;
|
||||
|
||||
// (Optional) simple click (without moving) turns Drag into an InputText
|
||||
@@ -3024,13 +3026,12 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat
|
||||
if (!temp_input_is_active)
|
||||
{
|
||||
// Tabbing or CTRL-clicking on Slider turns it into an input box
|
||||
const bool input_requested_by_tabbing = temp_input_allowed && (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_FocusedByTabbing) != 0;
|
||||
const bool clicked = hovered && IsMouseClicked(0, id);
|
||||
const bool make_active = (input_requested_by_tabbing || clicked || g.NavActivateId == id);
|
||||
const bool make_active = (clicked || g.NavActivateId == id);
|
||||
if (make_active && clicked)
|
||||
SetKeyOwner(ImGuiKey_MouseLeft, id);
|
||||
if (make_active && temp_input_allowed)
|
||||
if (input_requested_by_tabbing || (clicked && g.IO.KeyCtrl) || (g.NavActivateId == id && (g.NavActivateFlags & ImGuiActivateFlags_PreferInput)))
|
||||
if ((clicked && g.IO.KeyCtrl) || (g.NavActivateId == id && (g.NavActivateFlags & ImGuiActivateFlags_PreferInput)))
|
||||
temp_input_is_active = true;
|
||||
|
||||
if (make_active && !temp_input_is_active)
|
||||
@@ -3402,14 +3403,6 @@ bool ImGui::TempInputText(const ImRect& bb, ImGuiID id, const char* label, char*
|
||||
return value_changed;
|
||||
}
|
||||
|
||||
static inline ImGuiInputTextFlags InputScalar_DefaultCharsFilter(ImGuiDataType data_type, const char* format)
|
||||
{
|
||||
if (data_type == ImGuiDataType_Float || data_type == ImGuiDataType_Double)
|
||||
return ImGuiInputTextFlags_CharsScientific;
|
||||
const char format_last_char = format[0] ? format[strlen(format) - 1] : 0;
|
||||
return (format_last_char == 'x' || format_last_char == 'X') ? ImGuiInputTextFlags_CharsHexadecimal : ImGuiInputTextFlags_CharsDecimal;
|
||||
}
|
||||
|
||||
// Note that Drag/Slider functions are only forwarding the min/max values clamping values if the ImGuiSliderFlags_AlwaysClamp flag is set!
|
||||
// This is intended: this way we allow CTRL+Click manual input to set a value out of bounds, for maximum flexibility.
|
||||
// However this may not be ideal for all uses, as some user code may break on out of bound values.
|
||||
@@ -3426,8 +3419,7 @@ bool ImGui::TempInputScalar(const ImRect& bb, ImGuiID id, const char* label, ImG
|
||||
DataTypeFormatString(data_buf, IM_ARRAYSIZE(data_buf), data_type, p_data, format);
|
||||
ImStrTrimBlanks(data_buf);
|
||||
|
||||
ImGuiInputTextFlags flags = ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_NoMarkEdited;
|
||||
flags |= InputScalar_DefaultCharsFilter(data_type, format);
|
||||
ImGuiInputTextFlags flags = ImGuiInputTextFlags_AutoSelectAll | (ImGuiInputTextFlags)ImGuiInputTextFlags_NoMarkEdited;
|
||||
|
||||
bool value_changed = false;
|
||||
if (TempInputText(bb, id, label, data_buf, IM_ARRAYSIZE(data_buf), flags))
|
||||
@@ -3471,10 +3463,7 @@ bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* p_data
|
||||
char buf[64];
|
||||
DataTypeFormatString(buf, IM_ARRAYSIZE(buf), data_type, p_data, format);
|
||||
|
||||
// Testing ActiveId as a minor optimization as filtering is not needed until active
|
||||
if (g.ActiveId == 0 && (flags & (ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsScientific)) == 0)
|
||||
flags |= InputScalar_DefaultCharsFilter(data_type, format);
|
||||
flags |= ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_NoMarkEdited; // We call MarkItemEdited() ourselves by comparing the actual data rather than the string.
|
||||
flags |= ImGuiInputTextFlags_AutoSelectAll | (ImGuiInputTextFlags)ImGuiInputTextFlags_NoMarkEdited; // We call MarkItemEdited() ourselves by comparing the actual data rather than the string.
|
||||
|
||||
bool value_changed = false;
|
||||
if (p_step == NULL)
|
||||
@@ -3568,7 +3557,6 @@ bool ImGui::InputScalarN(const char* label, ImGuiDataType data_type, void* p_dat
|
||||
|
||||
bool ImGui::InputFloat(const char* label, float* v, float step, float step_fast, const char* format, ImGuiInputTextFlags flags)
|
||||
{
|
||||
flags |= ImGuiInputTextFlags_CharsScientific;
|
||||
return InputScalar(label, ImGuiDataType_Float, (void*)v, (void*)(step > 0.0f ? &step : NULL), (void*)(step_fast > 0.0f ? &step_fast : NULL), format, flags);
|
||||
}
|
||||
|
||||
@@ -3611,7 +3599,6 @@ bool ImGui::InputInt4(const char* label, int v[4], ImGuiInputTextFlags flags)
|
||||
|
||||
bool ImGui::InputDouble(const char* label, double* v, double step, double step_fast, const char* format, ImGuiInputTextFlags flags)
|
||||
{
|
||||
flags |= ImGuiInputTextFlags_CharsScientific;
|
||||
return InputScalar(label, ImGuiDataType_Double, (void*)v, (void*)(step > 0.0 ? &step : NULL), (void*)(step_fast > 0.0 ? &step_fast : NULL), format, flags);
|
||||
}
|
||||
|
||||
@@ -3710,7 +3697,7 @@ namespace ImStb
|
||||
|
||||
static int STB_TEXTEDIT_STRINGLEN(const ImGuiInputTextState* obj) { return obj->CurLenW; }
|
||||
static ImWchar STB_TEXTEDIT_GETCHAR(const ImGuiInputTextState* obj, int idx) { IM_ASSERT(idx <= obj->CurLenW); return obj->TextW[idx]; }
|
||||
static float STB_TEXTEDIT_GETWIDTH(ImGuiInputTextState* obj, int line_start_idx, int char_idx) { ImWchar c = obj->TextW[line_start_idx + char_idx]; if (c == '\n') return STB_TEXTEDIT_GETWIDTH_NEWLINE; ImGuiContext& g = *obj->Ctx; return g.Font->GetCharAdvance(c) * (g.FontSize / g.Font->FontSize); }
|
||||
static float STB_TEXTEDIT_GETWIDTH(ImGuiInputTextState* obj, int line_start_idx, int char_idx) { ImWchar c = obj->TextW[line_start_idx + char_idx]; if (c == '\n') return IMSTB_TEXTEDIT_GETWIDTH_NEWLINE; ImGuiContext& g = *obj->Ctx; return g.Font->GetCharAdvance(c) * (g.FontSize / g.Font->FontSize); }
|
||||
static int STB_TEXTEDIT_KEYTOTEXT(int key) { return key >= 0x200000 ? 0 : key; }
|
||||
static ImWchar STB_TEXTEDIT_NEWLINE = '\n';
|
||||
static void STB_TEXTEDIT_LAYOUTROW(StbTexteditRow* r, ImGuiInputTextState* obj, int line_start_idx)
|
||||
@@ -3828,13 +3815,13 @@ static bool STB_TEXTEDIT_INSERTCHARS(ImGuiInputTextState* obj, int pos, const Im
|
||||
#define STB_TEXTEDIT_K_PGDOWN 0x20000F // keyboard input to move cursor down a page
|
||||
#define STB_TEXTEDIT_K_SHIFT 0x400000
|
||||
|
||||
#define STB_TEXTEDIT_IMPLEMENTATION
|
||||
#define STB_TEXTEDIT_memmove memmove
|
||||
#define IMSTB_TEXTEDIT_IMPLEMENTATION
|
||||
#define IMSTB_TEXTEDIT_memmove memmove
|
||||
#include "imstb_textedit.h"
|
||||
|
||||
// stb_textedit internally allows for a single undo record to do addition and deletion, but somehow, calling
|
||||
// the stb_textedit_paste() function creates two separate records, so we perform it manually. (FIXME: Report to nothings/stb?)
|
||||
static void stb_textedit_replace(ImGuiInputTextState* str, STB_TexteditState* state, const STB_TEXTEDIT_CHARTYPE* text, int text_len)
|
||||
static void stb_textedit_replace(ImGuiInputTextState* str, STB_TexteditState* state, const IMSTB_TEXTEDIT_CHARTYPE* text, int text_len)
|
||||
{
|
||||
stb_text_makeundo_replace(str, state, 0, str->CurLenW, text_len);
|
||||
ImStb::STB_TEXTEDIT_DELETECHARS(str, 0, str->CurLenW);
|
||||
@@ -3932,8 +3919,8 @@ static bool InputTextFilterCharacter(ImGuiContext* ctx, unsigned int* p_char, Im
|
||||
if (c < 0x20)
|
||||
{
|
||||
bool pass = false;
|
||||
pass |= (c == '\n' && (flags & ImGuiInputTextFlags_Multiline)); // Note that an Enter KEY will emit \r and be ignored (we poll for KEY in InputText() code)
|
||||
pass |= (c == '\t' && (flags & ImGuiInputTextFlags_AllowTabInput));
|
||||
pass |= (c == '\n') && (flags & ImGuiInputTextFlags_Multiline) != 0; // Note that an Enter KEY will emit \r and be ignored (we poll for KEY in InputText() code)
|
||||
pass |= (c == '\t') && (flags & ImGuiInputTextFlags_AllowTabInput) != 0;
|
||||
if (!pass)
|
||||
return false;
|
||||
apply_named_filters = false; // Override named filters below so newline and tabs can still be inserted.
|
||||
@@ -4053,7 +4040,7 @@ static void InputTextReconcileUndoStateAfterUserCallback(ImGuiInputTextState* st
|
||||
const int insert_len = new_last_diff - first_diff + 1;
|
||||
const int delete_len = old_last_diff - first_diff + 1;
|
||||
if (insert_len > 0 || delete_len > 0)
|
||||
if (STB_TEXTEDIT_CHARTYPE* p = stb_text_createundo(&state->Stb.undostate, first_diff, delete_len, insert_len))
|
||||
if (IMSTB_TEXTEDIT_CHARTYPE* p = stb_text_createundo(&state->Stb.undostate, first_diff, delete_len, insert_len))
|
||||
for (int i = 0; i < delete_len; i++)
|
||||
p[i] = ImStb::STB_TEXTEDIT_GETCHAR(state, first_diff + i);
|
||||
}
|
||||
@@ -4105,12 +4092,6 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
|
||||
const bool RENDER_SELECTION_WHEN_INACTIVE = false;
|
||||
const bool is_multiline = (flags & ImGuiInputTextFlags_Multiline) != 0;
|
||||
const bool is_readonly = (flags & ImGuiInputTextFlags_ReadOnly) != 0;
|
||||
const bool is_password = (flags & ImGuiInputTextFlags_Password) != 0;
|
||||
const bool is_undoable = (flags & ImGuiInputTextFlags_NoUndoRedo) == 0;
|
||||
const bool is_resizable = (flags & ImGuiInputTextFlags_CallbackResize) != 0;
|
||||
if (is_resizable)
|
||||
IM_ASSERT(callback != NULL); // Must provide a callback if you set the ImGuiInputTextFlags_CallbackResize flag!
|
||||
|
||||
if (is_multiline) // Open group before calling GetID() because groups tracks id created within their scope (including the scrollbar)
|
||||
BeginGroup();
|
||||
@@ -4124,7 +4105,6 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
|
||||
ImGuiWindow* draw_window = window;
|
||||
ImVec2 inner_size = frame_size;
|
||||
ImGuiItemStatusFlags item_status_flags = 0;
|
||||
ImGuiLastItemData item_data_backup;
|
||||
if (is_multiline)
|
||||
{
|
||||
@@ -4135,11 +4115,14 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
EndGroup();
|
||||
return false;
|
||||
}
|
||||
item_status_flags = g.LastItemData.StatusFlags;
|
||||
item_data_backup = g.LastItemData;
|
||||
window->DC.CursorPos = backup_pos;
|
||||
|
||||
// Prevent NavActivate reactivating in BeginChild().
|
||||
// Prevent NavActivation from Tabbing when our widget accepts Tab inputs: this allows cycling through widgets without stopping.
|
||||
if (g.NavActivateId == id && (g.NavActivateFlags & ImGuiActivateFlags_FromTabbing) && (flags & ImGuiInputTextFlags_AllowTabInput))
|
||||
g.NavActivateId = 0;
|
||||
|
||||
// Prevent NavActivate reactivating in BeginChild() when we are already active.
|
||||
const ImGuiID backup_activate_id = g.NavActivateId;
|
||||
if (g.ActiveId == id) // Prevent reactivation
|
||||
g.NavActivateId = 0;
|
||||
@@ -4171,7 +4154,6 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
if (!(flags & ImGuiInputTextFlags_MergedItem))
|
||||
if (!ItemAdd(total_bb, id, &frame_bb, ImGuiItemFlags_Inputable))
|
||||
return false;
|
||||
item_status_flags = g.LastItemData.StatusFlags;
|
||||
}
|
||||
const bool hovered = ItemHoverable(frame_bb, id, g.LastItemData.InFlags);
|
||||
if (hovered)
|
||||
@@ -4180,7 +4162,15 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
// We are only allowed to access the state if we are already the active widget.
|
||||
ImGuiInputTextState* state = GetInputTextState(id);
|
||||
|
||||
const bool input_requested_by_tabbing = (item_status_flags & ImGuiItemStatusFlags_FocusedByTabbing) != 0;
|
||||
if (g.LastItemData.InFlags & ImGuiItemFlags_ReadOnly)
|
||||
flags |= ImGuiInputTextFlags_ReadOnly;
|
||||
const bool is_readonly = (flags & ImGuiInputTextFlags_ReadOnly) != 0;
|
||||
const bool is_password = (flags & ImGuiInputTextFlags_Password) != 0;
|
||||
const bool is_undoable = (flags & ImGuiInputTextFlags_NoUndoRedo) == 0;
|
||||
const bool is_resizable = (flags & ImGuiInputTextFlags_CallbackResize) != 0;
|
||||
if (is_resizable)
|
||||
IM_ASSERT(callback != NULL); // Must provide a callback if you set the ImGuiInputTextFlags_CallbackResize flag!
|
||||
|
||||
const bool input_requested_by_nav = (g.ActiveId != id) && ((g.NavActivateId == id) && ((g.NavActivateFlags & ImGuiActivateFlags_PreferInput) || (g.NavInputSource == ImGuiInputSource_Keyboard)));
|
||||
|
||||
const bool user_clicked = hovered && io.MouseClicked[0];
|
||||
@@ -4192,7 +4182,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
float scroll_y = is_multiline ? draw_window->Scroll.y : FLT_MAX;
|
||||
|
||||
const bool init_changed_specs = (state != NULL && state->Stb.single_line != !is_multiline); // state != NULL means its our state.
|
||||
const bool init_make_active = (user_clicked || user_scroll_finish || input_requested_by_nav || input_requested_by_tabbing);
|
||||
const bool init_make_active = (user_clicked || user_scroll_finish || input_requested_by_nav);
|
||||
const bool init_state = (init_make_active || user_scroll_active);
|
||||
if ((init_state && g.ActiveId != id) || init_changed_specs)
|
||||
{
|
||||
@@ -4242,7 +4232,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
select_all = true;
|
||||
if (input_requested_by_nav && (!recycle_state || !(g.NavActivateFlags & ImGuiActivateFlags_TryToPreserveState)))
|
||||
select_all = true;
|
||||
if (input_requested_by_tabbing || (user_clicked && io.KeyCtrl))
|
||||
if (user_clicked && io.KeyCtrl)
|
||||
select_all = true;
|
||||
}
|
||||
|
||||
@@ -4405,7 +4395,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
|
||||
// We expect backends to emit a Tab key but some also emit a Tab character which we ignore (#2467, #1336)
|
||||
// (For Tab and Enter: Win32/SFML/Allegro are sending both keys and chars, GLFW and SDL are only sending keys. For Space they all send all threes)
|
||||
if ((flags & ImGuiInputTextFlags_AllowTabInput) && Shortcut(ImGuiKey_Tab, id) && !is_readonly)
|
||||
if ((flags & ImGuiInputTextFlags_AllowTabInput) && Shortcut(ImGuiKey_Tab, id, ImGuiInputFlags_Repeat) && !is_readonly)
|
||||
{
|
||||
unsigned int c = '\t'; // Insert TAB
|
||||
if (InputTextFilterCharacter(&g, &c, flags, callback, callback_user_data, ImGuiInputSource_Keyboard))
|
||||
@@ -4607,7 +4597,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
apply_new_text = "";
|
||||
apply_new_text_length = 0;
|
||||
value_changed = true;
|
||||
STB_TEXTEDIT_CHARTYPE empty_string;
|
||||
IMSTB_TEXTEDIT_CHARTYPE empty_string;
|
||||
stb_textedit_replace(state, &state->Stb, &empty_string, 0);
|
||||
}
|
||||
else if (strcmp(buf, state->InitialTextA.Data) != 0)
|
||||
@@ -4716,7 +4706,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
if (callback_data.SelectionEnd != utf8_selection_end || buf_dirty) { state->Stb.select_end = (callback_data.SelectionEnd == callback_data.SelectionStart) ? state->Stb.select_start : ImTextCountCharsFromUtf8(callback_data.Buf, callback_data.Buf + callback_data.SelectionEnd); }
|
||||
if (buf_dirty)
|
||||
{
|
||||
IM_ASSERT((flags & ImGuiInputTextFlags_ReadOnly) == 0);
|
||||
IM_ASSERT(!is_readonly);
|
||||
IM_ASSERT(callback_data.BufTextLen == (int)strlen(callback_data.Buf)); // You need to maintain BufTextLen if you change the text!
|
||||
InputTextReconcileUndoStateAfterUserCallback(state, callback_data.Buf, callback_data.BufTextLen); // FIXME: Move the rest of this block inside function and rename to InputTextReconcileStateAfterUserCallback() ?
|
||||
if (callback_data.BufTextLen > backup_current_text_length && is_resizable)
|
||||
@@ -4973,6 +4963,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
g.PlatformImeData.WantVisible = true;
|
||||
g.PlatformImeData.InputPos = ImVec2(cursor_screen_pos.x - 1.0f, cursor_screen_pos.y - g.FontSize);
|
||||
g.PlatformImeData.InputLineHeight = g.FontSize;
|
||||
g.PlatformImeViewport = window->Viewport->ID;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5046,10 +5037,10 @@ void ImGui::DebugNodeInputTextState(ImGuiInputTextState* state)
|
||||
Text("CurLenW: %d, CurLenA: %d, Cursor: %d, Selection: %d..%d", state->CurLenW, state->CurLenA, stb_state->cursor, stb_state->select_start, stb_state->select_end);
|
||||
Text("has_preferred_x: %d (%.2f)", stb_state->has_preferred_x, stb_state->preferred_x);
|
||||
Text("undo_point: %d, redo_point: %d, undo_char_point: %d, redo_char_point: %d", undo_state->undo_point, undo_state->redo_point, undo_state->undo_char_point, undo_state->redo_char_point);
|
||||
if (BeginChild("undopoints", ImVec2(0.0f, GetTextLineHeight() * 15), ImGuiChildFlags_Border)) // Visualize undo state
|
||||
if (BeginChild("undopoints", ImVec2(0.0f, GetTextLineHeight() * 10), ImGuiChildFlags_Border | ImGuiChildFlags_ResizeY)) // Visualize undo state
|
||||
{
|
||||
PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0));
|
||||
for (int n = 0; n < STB_TEXTEDIT_UNDOSTATECOUNT; n++)
|
||||
for (int n = 0; n < IMSTB_TEXTEDIT_UNDOSTATECOUNT; n++)
|
||||
{
|
||||
ImStb::StbUndoRecord* undo_rec = &undo_state->undo_rec[n];
|
||||
const char undo_rec_type = (n < undo_state->undo_point) ? 'u' : (n >= undo_state->redo_point) ? 'r' : ' ';
|
||||
@@ -5131,10 +5122,8 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag
|
||||
ImGuiContext& g = *GImGui;
|
||||
const ImGuiStyle& style = g.Style;
|
||||
const float square_sz = GetFrameHeight();
|
||||
const float w_full = CalcItemWidth();
|
||||
const float w_button = (flags & ImGuiColorEditFlags_NoSmallPreview) ? 0.0f : (square_sz + style.ItemInnerSpacing.x);
|
||||
const float w_inputs = w_full - w_button;
|
||||
const char* label_display_end = FindRenderedTextEnd(label);
|
||||
float w_full = CalcItemWidth();
|
||||
g.NextItemData.ClearFlags();
|
||||
|
||||
BeginGroup();
|
||||
@@ -5168,6 +5157,9 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag
|
||||
const bool alpha = (flags & ImGuiColorEditFlags_NoAlpha) == 0;
|
||||
const bool hdr = (flags & ImGuiColorEditFlags_HDR) != 0;
|
||||
const int components = alpha ? 4 : 3;
|
||||
const float w_button = (flags & ImGuiColorEditFlags_NoSmallPreview) ? 0.0f : (square_sz + style.ItemInnerSpacing.x);
|
||||
const float w_inputs = ImMax(w_full - w_button, 1.0f);
|
||||
w_full = w_inputs + w_button;
|
||||
|
||||
// Convert to the formats we need
|
||||
float f[4] = { col[0], col[1], col[2], alpha ? col[3] : 1.0f };
|
||||
@@ -5191,10 +5183,9 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag
|
||||
if ((flags & (ImGuiColorEditFlags_DisplayRGB | ImGuiColorEditFlags_DisplayHSV)) != 0 && (flags & ImGuiColorEditFlags_NoInputs) == 0)
|
||||
{
|
||||
// RGB/HSV 0..255 Sliders
|
||||
const float w_item_one = ImMax(1.0f, IM_TRUNC((w_inputs - (style.ItemInnerSpacing.x) * (components - 1)) / (float)components));
|
||||
const float w_item_last = ImMax(1.0f, IM_TRUNC(w_inputs - (w_item_one + style.ItemInnerSpacing.x) * (components - 1)));
|
||||
const float w_items = w_inputs - style.ItemInnerSpacing.x * (components - 1);
|
||||
|
||||
const bool hide_prefix = (w_item_one <= CalcTextSize((flags & ImGuiColorEditFlags_Float) ? "M:0.000" : "M:000").x);
|
||||
const bool hide_prefix = (IM_TRUNC(w_items / components) <= CalcTextSize((flags & ImGuiColorEditFlags_Float) ? "M:0.000" : "M:000").x);
|
||||
static const char* ids[4] = { "##X", "##Y", "##Z", "##W" };
|
||||
static const char* fmt_table_int[3][4] =
|
||||
{
|
||||
@@ -5210,11 +5201,14 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag
|
||||
};
|
||||
const int fmt_idx = hide_prefix ? 0 : (flags & ImGuiColorEditFlags_DisplayHSV) ? 2 : 1;
|
||||
|
||||
float prev_split = 0.0f;
|
||||
for (int n = 0; n < components; n++)
|
||||
{
|
||||
if (n > 0)
|
||||
SameLine(0, style.ItemInnerSpacing.x);
|
||||
SetNextItemWidth((n + 1 < components) ? w_item_one : w_item_last);
|
||||
float next_split = IM_TRUNC(w_items * (n + 1) / components);
|
||||
SetNextItemWidth(ImMax(next_split - prev_split, 1.0f));
|
||||
prev_split = next_split;
|
||||
|
||||
// FIXME: When ImGuiColorEditFlags_HDR flag is passed HS values snap in weird ways when SV values go below 0.
|
||||
if (flags & ImGuiColorEditFlags_Float)
|
||||
@@ -5239,7 +5233,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag
|
||||
else
|
||||
ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X", ImClamp(i[0], 0, 255), ImClamp(i[1], 0, 255), ImClamp(i[2], 0, 255));
|
||||
SetNextItemWidth(w_inputs);
|
||||
if (InputText("##Text", buf, IM_ARRAYSIZE(buf), ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase))
|
||||
if (InputText("##Text", buf, IM_ARRAYSIZE(buf), ImGuiInputTextFlags_CharsUppercase))
|
||||
{
|
||||
value_changed = true;
|
||||
char* p = buf;
|
||||
@@ -5337,7 +5331,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag
|
||||
|
||||
// Drag and Drop Target
|
||||
// NB: The flag test is merely an optional micro-optimization, BeginDragDropTarget() does the same test.
|
||||
if ((g.LastItemData.StatusFlags & ImGuiItemStatusFlags_HoveredRect) && !(flags & ImGuiColorEditFlags_NoDragDrop) && BeginDragDropTarget())
|
||||
if ((g.LastItemData.StatusFlags & ImGuiItemStatusFlags_HoveredRect) && !(g.LastItemData.InFlags & ImGuiItemFlags_ReadOnly) && !(flags & ImGuiColorEditFlags_NoDragDrop) && BeginDragDropTarget())
|
||||
{
|
||||
bool accepted_drag_drop = false;
|
||||
if (const ImGuiPayload* payload = AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_3F))
|
||||
@@ -5402,6 +5396,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
|
||||
ImGuiIO& io = g.IO;
|
||||
|
||||
const float width = CalcItemWidth();
|
||||
const bool is_readonly = ((g.NextItemData.ItemFlags | g.CurrentItemFlags) & ImGuiItemFlags_ReadOnly) != 0;
|
||||
g.NextItemData.ClearFlags();
|
||||
|
||||
PushID(label);
|
||||
@@ -5472,7 +5467,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
|
||||
{
|
||||
// Hue wheel + SV triangle logic
|
||||
InvisibleButton("hsv", ImVec2(sv_picker_size + style.ItemInnerSpacing.x + bars_width, sv_picker_size));
|
||||
if (IsItemActive())
|
||||
if (IsItemActive() && !is_readonly)
|
||||
{
|
||||
ImVec2 initial_off = g.IO.MouseClickedPos[0] - wheel_center;
|
||||
ImVec2 current_off = g.IO.MousePos - wheel_center;
|
||||
@@ -5507,7 +5502,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
|
||||
{
|
||||
// SV rectangle logic
|
||||
InvisibleButton("sv", ImVec2(sv_picker_size, sv_picker_size));
|
||||
if (IsItemActive())
|
||||
if (IsItemActive() && !is_readonly)
|
||||
{
|
||||
S = ImSaturate((io.MousePos.x - picker_pos.x) / (sv_picker_size - 1));
|
||||
V = 1.0f - ImSaturate((io.MousePos.y - picker_pos.y) / (sv_picker_size - 1));
|
||||
@@ -5520,7 +5515,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
|
||||
// Hue bar logic
|
||||
SetCursorScreenPos(ImVec2(bar0_pos_x, picker_pos.y));
|
||||
InvisibleButton("hue", ImVec2(bars_width, sv_picker_size));
|
||||
if (IsItemActive())
|
||||
if (IsItemActive() && !is_readonly)
|
||||
{
|
||||
H = ImSaturate((io.MousePos.y - picker_pos.y) / (sv_picker_size - 1));
|
||||
value_changed = value_changed_h = true;
|
||||
@@ -5726,7 +5721,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
|
||||
}
|
||||
|
||||
// Render cursor/preview circle (clamp S/V within 0..1 range because floating points colors may lead HSV values to be out of range)
|
||||
float sv_cursor_rad = value_changed_sv ? 10.0f : 6.0f;
|
||||
float sv_cursor_rad = value_changed_sv ? wheel_thickness * 0.55f : wheel_thickness * 0.40f;
|
||||
int sv_cursor_segments = draw_list->_CalcCircleAutoSegmentCount(sv_cursor_rad); // Lock segment count so the +1 one matches others.
|
||||
draw_list->AddCircleFilled(sv_cursor_pos, sv_cursor_rad, user_col32_striped_of_alpha, sv_cursor_segments);
|
||||
draw_list->AddCircle(sv_cursor_pos, sv_cursor_rad + 1, col_midgrey, sv_cursor_segments);
|
||||
@@ -6232,7 +6227,11 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
||||
}
|
||||
|
||||
if (span_all_columns)
|
||||
{
|
||||
TablePushBackgroundChannel();
|
||||
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HasClipRect;
|
||||
g.LastItemData.ClipRect = window->ClipRect;
|
||||
}
|
||||
|
||||
ImGuiButtonFlags button_flags = ImGuiTreeNodeFlags_None;
|
||||
if ((flags & ImGuiTreeNodeFlags_AllowOverlap) || (g.LastItemData.InFlags & ImGuiItemFlags_AllowOverlap))
|
||||
@@ -6461,7 +6460,7 @@ bool ImGui::CollapsingHeader(const char* label, bool* p_visible, ImGuiTreeNodeFl
|
||||
ImGuiID id = window->GetID(label);
|
||||
flags |= ImGuiTreeNodeFlags_CollapsingHeader;
|
||||
if (p_visible)
|
||||
flags |= ImGuiTreeNodeFlags_AllowOverlap | ImGuiTreeNodeFlags_ClipLabelForTrailingButton;
|
||||
flags |= ImGuiTreeNodeFlags_AllowOverlap | (ImGuiTreeNodeFlags)ImGuiTreeNodeFlags_ClipLabelForTrailingButton;
|
||||
bool is_open = TreeNodeBehavior(id, flags, label);
|
||||
if (p_visible != NULL)
|
||||
{
|
||||
@@ -6562,10 +6561,15 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
|
||||
|
||||
// FIXME: We can standardize the behavior of those two, we could also keep the fast path of override ClipRect + full push on render only,
|
||||
// which would be advantageous since most selectable are not selected.
|
||||
if (span_all_columns && window->DC.CurrentColumns)
|
||||
PushColumnsBackground();
|
||||
else if (span_all_columns && g.CurrentTable)
|
||||
TablePushBackgroundChannel();
|
||||
if (span_all_columns)
|
||||
{
|
||||
if (g.CurrentTable)
|
||||
TablePushBackgroundChannel();
|
||||
else if (window->DC.CurrentColumns)
|
||||
PushColumnsBackground();
|
||||
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HasClipRect;
|
||||
g.LastItemData.ClipRect = window->ClipRect;
|
||||
}
|
||||
|
||||
// We use NoHoldingActiveID on menus so user can click and _hold_ on a menu then drag to browse child entries
|
||||
ImGuiButtonFlags button_flags = 0;
|
||||
@@ -6616,10 +6620,13 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
|
||||
if (g.NavId == id)
|
||||
RenderNavHighlight(bb, id, ImGuiNavHighlightFlags_TypeThin | ImGuiNavHighlightFlags_NoRounding);
|
||||
|
||||
if (span_all_columns && window->DC.CurrentColumns)
|
||||
PopColumnsBackground();
|
||||
else if (span_all_columns && g.CurrentTable)
|
||||
TablePopBackgroundChannel();
|
||||
if (span_all_columns)
|
||||
{
|
||||
if (g.CurrentTable)
|
||||
TablePopBackgroundChannel();
|
||||
else if (window->DC.CurrentColumns)
|
||||
PopColumnsBackground();
|
||||
}
|
||||
|
||||
RenderTextClipped(text_min, text_max, label, NULL, &label_size, style.SelectableTextAlign, &bb);
|
||||
|
||||
@@ -7311,10 +7318,10 @@ bool ImGui::BeginViewportSideBar(const char* name, ImGuiViewport* viewport_p, Im
|
||||
IM_ASSERT(dir != ImGuiDir_None);
|
||||
|
||||
ImGuiWindow* bar_window = FindWindowByName(name);
|
||||
ImGuiViewportP* viewport = (ImGuiViewportP*)(void*)(viewport_p ? viewport_p : GetMainViewport());
|
||||
if (bar_window == NULL || bar_window->BeginCount == 0)
|
||||
{
|
||||
// Calculate and set window size/position
|
||||
ImGuiViewportP* viewport = (ImGuiViewportP*)(void*)(viewport_p ? viewport_p : GetMainViewport());
|
||||
ImRect avail_rect = viewport->GetBuildWorkRect();
|
||||
ImGuiAxis axis = (dir == ImGuiDir_Up || dir == ImGuiDir_Down) ? ImGuiAxis_Y : ImGuiAxis_X;
|
||||
ImVec2 pos = avail_rect.Min;
|
||||
@@ -7332,7 +7339,8 @@ bool ImGui::BeginViewportSideBar(const char* name, ImGuiViewport* viewport_p, Im
|
||||
viewport->BuildWorkOffsetMax[axis] -= axis_size;
|
||||
}
|
||||
|
||||
window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove;
|
||||
window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoDocking;
|
||||
SetNextWindowViewport(viewport->ID); // Enforce viewport so we don't create our own viewport when ImGuiConfigFlags_ViewportsNoMerge is set.
|
||||
PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
||||
PushStyleVar(ImGuiStyleVar_WindowMinSize, ImVec2(0, 0)); // Lift normal size constraint
|
||||
bool is_open = Begin(name, NULL, window_flags);
|
||||
@@ -7346,6 +7354,9 @@ bool ImGui::BeginMainMenuBar()
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiViewportP* viewport = (ImGuiViewportP*)(void*)GetMainViewport();
|
||||
|
||||
// Notify of viewport change so GetFrameHeight() can be accurate in case of DPI change
|
||||
SetCurrentViewport(NULL, viewport);
|
||||
|
||||
// For the main menu bar, which cannot be moved, we honor g.Style.DisplaySafeAreaPadding to ensure text can be visible on a TV set.
|
||||
// FIXME: This could be generalized as an opt-in way to clamp window->DC.CursorStartPos to avoid SafeArea?
|
||||
// FIXME: Consider removing support for safe area down the line... it's messy. Nowadays consoles have support for TV calibration in OS settings.
|
||||
@@ -7396,7 +7407,7 @@ static bool IsRootOfOpenMenuSet()
|
||||
const ImGuiPopupData* upper_popup = &g.OpenPopupStack[g.BeginPopupStack.Size];
|
||||
if (window->DC.NavLayerCurrent != upper_popup->ParentNavLayer)
|
||||
return false;
|
||||
return upper_popup->Window && (upper_popup->Window->Flags & ImGuiWindowFlags_ChildMenu) && ImGui::IsWindowChildOf(upper_popup->Window, window, true);
|
||||
return upper_popup->Window && (upper_popup->Window->Flags & ImGuiWindowFlags_ChildMenu) && ImGui::IsWindowChildOf(upper_popup->Window, window, true, false);
|
||||
}
|
||||
|
||||
bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled)
|
||||
@@ -7501,18 +7512,18 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled)
|
||||
ImGuiWindow* child_menu_window = (child_popup && child_popup->Window && child_popup->Window->ParentWindow == window) ? child_popup->Window : NULL;
|
||||
if (g.HoveredWindow == window && child_menu_window != NULL)
|
||||
{
|
||||
float ref_unit = g.FontSize; // FIXME-DPI
|
||||
float child_dir = (window->Pos.x < child_menu_window->Pos.x) ? 1.0f : -1.0f;
|
||||
ImRect next_window_rect = child_menu_window->Rect();
|
||||
const float ref_unit = g.FontSize; // FIXME-DPI
|
||||
const float child_dir = (window->Pos.x < child_menu_window->Pos.x) ? 1.0f : -1.0f;
|
||||
const ImRect next_window_rect = child_menu_window->Rect();
|
||||
ImVec2 ta = (g.IO.MousePos - g.IO.MouseDelta);
|
||||
ImVec2 tb = (child_dir > 0.0f) ? next_window_rect.GetTL() : next_window_rect.GetTR();
|
||||
ImVec2 tc = (child_dir > 0.0f) ? next_window_rect.GetBL() : next_window_rect.GetBR();
|
||||
float extra = ImClamp(ImFabs(ta.x - tb.x) * 0.30f, ref_unit * 0.5f, ref_unit * 2.5f); // add a bit of extra slack.
|
||||
const float pad_farmost_h = ImClamp(ImFabs(ta.x - tb.x) * 0.30f, ref_unit * 0.5f, ref_unit * 2.5f); // Add a bit of extra slack.
|
||||
ta.x += child_dir * -0.5f;
|
||||
tb.x += child_dir * ref_unit;
|
||||
tc.x += child_dir * ref_unit;
|
||||
tb.y = ta.y + ImMax((tb.y - extra) - ta.y, -ref_unit * 8.0f); // triangle has maximum height to limit the slope and the bias toward large sub-menus
|
||||
tc.y = ta.y + ImMin((tc.y + extra) - ta.y, +ref_unit * 8.0f);
|
||||
tb.y = ta.y + ImMax((tb.y - pad_farmost_h) - ta.y, -ref_unit * 8.0f); // Triangle has maximum height to limit the slope and the bias toward large sub-menus
|
||||
tc.y = ta.y + ImMin((tc.y + pad_farmost_h) - ta.y, +ref_unit * 8.0f);
|
||||
moving_toward_child_menu = ImTriangleContainsPoint(ta, tb, tc, g.IO.MousePos);
|
||||
//GetForegroundDrawList()->AddTriangleFilled(ta, tb, tc, moving_toward_child_menu ? IM_COL32(0,128,0,128) : IM_COL32(128,0,0,128)); // [DEBUG]
|
||||
}
|
||||
@@ -7524,10 +7535,13 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled)
|
||||
want_close = true;
|
||||
|
||||
// Open
|
||||
// (note: at this point 'hovered' actually includes the NavDisableMouseHover == false test)
|
||||
if (!menu_is_open && pressed) // Click/activate to open
|
||||
want_open = true;
|
||||
else if (!menu_is_open && hovered && !moving_toward_child_menu) // Hover to open
|
||||
want_open = true;
|
||||
else if (!menu_is_open && hovered && g.HoveredIdTimer >= 0.30f && g.MouseStationaryTimer >= 0.30f) // Hover to open (timer fallback)
|
||||
want_open = true;
|
||||
if (g.NavId == id && g.NavMoveDir == ImGuiDir_Right) // Nav-Right to open
|
||||
{
|
||||
want_open = true;
|
||||
@@ -7722,8 +7736,10 @@ bool ImGui::MenuItem(const char* label, const char* shortcut, bool* p_selected,
|
||||
// - TabBarCalcMaxTabWidth() [Internal]
|
||||
// - TabBarFindTabById() [Internal]
|
||||
// - TabBarFindTabByOrder() [Internal]
|
||||
// - TabBarFindMostRecentlySelectedTabForActiveWindow() [Internal]
|
||||
// - TabBarGetCurrentTab() [Internal]
|
||||
// - TabBarGetTabName() [Internal]
|
||||
// - TabBarAddTab() [Internal]
|
||||
// - TabBarRemoveTab() [Internal]
|
||||
// - TabBarCloseTab() [Internal]
|
||||
// - TabBarScrollClamp() [Internal]
|
||||
@@ -7842,7 +7858,8 @@ bool ImGui::BeginTabBarEx(ImGuiTabBar* tab_bar, const ImRect& tab_bar_bb, ImG
|
||||
|
||||
// Ensure correct ordering when toggling ImGuiTabBarFlags_Reorderable flag, or when a new tab was added while being not reorderable
|
||||
if ((flags & ImGuiTabBarFlags_Reorderable) != (tab_bar->Flags & ImGuiTabBarFlags_Reorderable) || (tab_bar->TabsAddedNew && !(flags & ImGuiTabBarFlags_Reorderable)))
|
||||
ImQsort(tab_bar->Tabs.Data, tab_bar->Tabs.Size, sizeof(ImGuiTabItem), TabItemComparerByBeginOrder);
|
||||
if ((flags & ImGuiTabBarFlags_DockNode) == 0) // FIXME: TabBar with DockNode can now be hybrid
|
||||
ImQsort(tab_bar->Tabs.Data, tab_bar->Tabs.Size, sizeof(ImGuiTabItem), TabItemComparerByBeginOrder);
|
||||
tab_bar->TabsAddedNew = false;
|
||||
|
||||
// Flags
|
||||
@@ -8124,6 +8141,10 @@ static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar)
|
||||
tab_bar->VisibleTabId = tab_bar->SelectedTabId;
|
||||
tab_bar->VisibleTabWasSubmitted = false;
|
||||
|
||||
// CTRL+TAB can override visible tab temporarily
|
||||
if (g.NavWindowingTarget != NULL && g.NavWindowingTarget->DockNode && g.NavWindowingTarget->DockNode->TabBar == tab_bar)
|
||||
tab_bar->VisibleTabId = scroll_to_tab_id = g.NavWindowingTarget->TabId;
|
||||
|
||||
// Apply request requests
|
||||
if (scroll_to_tab_id != 0)
|
||||
TabBarScrollToTab(tab_bar, scroll_to_tab_id, sections);
|
||||
@@ -8169,11 +8190,11 @@ static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar)
|
||||
// Dockable windows uses Name/ID in the global namespace. Non-dockable items use the ID stack.
|
||||
static ImU32 ImGui::TabBarCalcTabID(ImGuiTabBar* tab_bar, const char* label, ImGuiWindow* docked_window)
|
||||
{
|
||||
IM_ASSERT(docked_window == NULL); // master branch only
|
||||
IM_UNUSED(docked_window);
|
||||
if (tab_bar->Flags & ImGuiTabBarFlags_DockNode)
|
||||
if (docked_window != NULL)
|
||||
{
|
||||
ImGuiID id = ImHashStr(label);
|
||||
IM_UNUSED(tab_bar);
|
||||
IM_ASSERT(tab_bar->Flags & ImGuiTabBarFlags_DockNode);
|
||||
ImGuiID id = docked_window->TabId;
|
||||
KeepAliveID(id);
|
||||
return id;
|
||||
}
|
||||
@@ -8207,6 +8228,20 @@ ImGuiTabItem* ImGui::TabBarFindTabByOrder(ImGuiTabBar* tab_bar, int order)
|
||||
return &tab_bar->Tabs[order];
|
||||
}
|
||||
|
||||
// FIXME: See references to #2304 in TODO.txt
|
||||
ImGuiTabItem* ImGui::TabBarFindMostRecentlySelectedTabForActiveWindow(ImGuiTabBar* tab_bar)
|
||||
{
|
||||
ImGuiTabItem* most_recently_selected_tab = NULL;
|
||||
for (int tab_n = 0; tab_n < tab_bar->Tabs.Size; tab_n++)
|
||||
{
|
||||
ImGuiTabItem* tab = &tab_bar->Tabs[tab_n];
|
||||
if (most_recently_selected_tab == NULL || most_recently_selected_tab->LastFrameSelected < tab->LastFrameSelected)
|
||||
if (tab->Window && tab->Window->WasActive)
|
||||
most_recently_selected_tab = tab;
|
||||
}
|
||||
return most_recently_selected_tab;
|
||||
}
|
||||
|
||||
ImGuiTabItem* ImGui::TabBarGetCurrentTab(ImGuiTabBar* tab_bar)
|
||||
{
|
||||
if (tab_bar->LastTabItemIdx <= 0 || tab_bar->LastTabItemIdx >= tab_bar->Tabs.Size)
|
||||
@@ -8216,12 +8251,35 @@ ImGuiTabItem* ImGui::TabBarGetCurrentTab(ImGuiTabBar* tab_bar)
|
||||
|
||||
const char* ImGui::TabBarGetTabName(ImGuiTabBar* tab_bar, ImGuiTabItem* tab)
|
||||
{
|
||||
if (tab->Window)
|
||||
return tab->Window->Name;
|
||||
if (tab->NameOffset == -1)
|
||||
return "N/A";
|
||||
IM_ASSERT(tab->NameOffset < tab_bar->TabsNames.Buf.Size);
|
||||
return tab_bar->TabsNames.Buf.Data + tab->NameOffset;
|
||||
}
|
||||
|
||||
// The purpose of this call is to register tab in advance so we can control their order at the time they appear.
|
||||
// Otherwise calling this is unnecessary as tabs are appending as needed by the BeginTabItem() function.
|
||||
void ImGui::TabBarAddTab(ImGuiTabBar* tab_bar, ImGuiTabItemFlags tab_flags, ImGuiWindow* window)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
IM_ASSERT(TabBarFindTabByID(tab_bar, window->TabId) == NULL);
|
||||
IM_ASSERT(g.CurrentTabBar != tab_bar); // Can't work while the tab bar is active as our tab doesn't have an X offset yet, in theory we could/should test something like (tab_bar->CurrFrameVisible < g.FrameCount) but we'd need to solve why triggers the commented early-out assert in BeginTabBarEx() (probably dock node going from implicit to explicit in same frame)
|
||||
|
||||
if (!window->HasCloseButton)
|
||||
tab_flags |= ImGuiTabItemFlags_NoCloseButton; // Set _NoCloseButton immediately because it will be used for first-frame width calculation.
|
||||
|
||||
ImGuiTabItem new_tab;
|
||||
new_tab.ID = window->TabId;
|
||||
new_tab.Flags = tab_flags;
|
||||
new_tab.LastFrameVisible = tab_bar->CurrFrameVisible; // Required so BeginTabBar() doesn't ditch the tab
|
||||
if (new_tab.LastFrameVisible == -1)
|
||||
new_tab.LastFrameVisible = g.FrameCount - 1;
|
||||
new_tab.Window = window; // Required so tab bar layout can compute the tab width before tab submission
|
||||
tab_bar->Tabs.push_back(new_tab);
|
||||
}
|
||||
|
||||
// The *TabId fields are already set by the docking system _before_ the actual TabItem was created, so we clear them regardless.
|
||||
void ImGui::TabBarRemoveTab(ImGuiTabBar* tab_bar, ImGuiID tab_id)
|
||||
{
|
||||
@@ -8238,7 +8296,7 @@ void ImGui::TabBarCloseTab(ImGuiTabBar* tab_bar, ImGuiTabItem* tab)
|
||||
if (tab->Flags & ImGuiTabItemFlags_Button)
|
||||
return; // A button appended with TabItemButton().
|
||||
|
||||
if (!(tab->Flags & ImGuiTabItemFlags_UnsavedDocument))
|
||||
if ((tab->Flags & (ImGuiTabItemFlags_UnsavedDocument | ImGuiTabItemFlags_NoAssumedClosure)) == 0)
|
||||
{
|
||||
// This will remove a frame of lag for selecting another tab on closure.
|
||||
// However we don't run it in the case where the 'Unsaved' flag is set, so user gets a chance to fully undo the closure
|
||||
@@ -8502,7 +8560,7 @@ bool ImGui::BeginTabItem(const char* label, bool* p_open, ImGuiTabItemFlags f
|
||||
IM_ASSERT_USER_ERROR(tab_bar, "Needs to be called between BeginTabBar() and EndTabBar()!");
|
||||
return false;
|
||||
}
|
||||
IM_ASSERT(!(flags & ImGuiTabItemFlags_Button)); // BeginTabItem() Can't be used with button flags, use TabItemButton() instead!
|
||||
IM_ASSERT((flags & ImGuiTabItemFlags_Button) == 0); // BeginTabItem() Can't be used with button flags, use TabItemButton() instead!
|
||||
|
||||
bool ret = TabItemEx(tab_bar, label, p_open, flags, NULL);
|
||||
if (ret && !(flags & ImGuiTabItemFlags_NoPushId))
|
||||
@@ -8612,11 +8670,14 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
|
||||
const bool is_tab_button = (flags & ImGuiTabItemFlags_Button) != 0;
|
||||
tab->LastFrameVisible = g.FrameCount;
|
||||
tab->Flags = flags;
|
||||
tab->Window = docked_window;
|
||||
|
||||
// Append name _WITH_ the zero-terminator
|
||||
// (regular tabs are permitted in a DockNode tab bar, but window tabs not permitted in a non-DockNode tab bar)
|
||||
if (docked_window != NULL)
|
||||
{
|
||||
IM_ASSERT(docked_window == NULL); // master branch only
|
||||
IM_ASSERT(tab_bar->Flags & ImGuiTabBarFlags_DockNode);
|
||||
tab->NameOffset = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -8641,7 +8702,7 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
|
||||
tab_bar->VisibleTabWasSubmitted = true;
|
||||
|
||||
// On the very first frame of a tab bar we let first tab contents be visible to minimize appearing glitches
|
||||
if (!tab_contents_visible && tab_bar->SelectedTabId == 0 && tab_bar_appearing)
|
||||
if (!tab_contents_visible && tab_bar->SelectedTabId == 0 && tab_bar_appearing && docked_window == NULL)
|
||||
if (tab_bar->Tabs.Size == 1 && !(tab_bar->Flags & ImGuiTabBarFlags_AutoSelectNewTabs))
|
||||
tab_contents_visible = true;
|
||||
|
||||
@@ -8689,30 +8750,82 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
|
||||
}
|
||||
|
||||
// Click to Select a tab
|
||||
// Allow the close button to overlap
|
||||
ImGuiButtonFlags button_flags = ((is_tab_button ? ImGuiButtonFlags_PressedOnClickRelease : ImGuiButtonFlags_PressedOnClick) | ImGuiButtonFlags_AllowOverlap);
|
||||
if (g.DragDropActive)
|
||||
if (g.DragDropActive && !g.DragDropPayload.IsDataType(IMGUI_PAYLOAD_TYPE_WINDOW)) // FIXME: May be an opt-in property of the payload to disable this
|
||||
button_flags |= ImGuiButtonFlags_PressedOnDragDropHold;
|
||||
bool hovered, held;
|
||||
bool pressed = ButtonBehavior(bb, id, &hovered, &held, button_flags);
|
||||
if (pressed && !is_tab_button)
|
||||
TabBarQueueFocus(tab_bar, tab);
|
||||
|
||||
// Drag and drop: re-order tabs
|
||||
if (held && !tab_appearing && IsMouseDragging(0))
|
||||
// Transfer active id window so the active id is not owned by the dock host (as StartMouseMovingWindow()
|
||||
// will only do it on the drag). This allows FocusWindow() to be more conservative in how it clears active id.
|
||||
if (held && docked_window && g.ActiveId == id && g.ActiveIdIsJustActivated)
|
||||
g.ActiveIdWindow = docked_window;
|
||||
|
||||
// Drag and drop a single floating window node moves it
|
||||
ImGuiDockNode* node = docked_window ? docked_window->DockNode : NULL;
|
||||
const bool single_floating_window_node = node && node->IsFloatingNode() && (node->Windows.Size == 1);
|
||||
if (held && single_floating_window_node && IsMouseDragging(0, 0.0f))
|
||||
{
|
||||
if (!g.DragDropActive && (tab_bar->Flags & ImGuiTabBarFlags_Reorderable))
|
||||
// Move
|
||||
StartMouseMovingWindow(docked_window);
|
||||
}
|
||||
else if (held && !tab_appearing && IsMouseDragging(0))
|
||||
{
|
||||
// Drag and drop: re-order tabs
|
||||
int drag_dir = 0;
|
||||
float drag_distance_from_edge_x = 0.0f;
|
||||
if (!g.DragDropActive && ((tab_bar->Flags & ImGuiTabBarFlags_Reorderable) || (docked_window != NULL)))
|
||||
{
|
||||
// While moving a tab it will jump on the other side of the mouse, so we also test for MouseDelta.x
|
||||
if (g.IO.MouseDelta.x < 0.0f && g.IO.MousePos.x < bb.Min.x)
|
||||
{
|
||||
drag_dir = -1;
|
||||
drag_distance_from_edge_x = bb.Min.x - g.IO.MousePos.x;
|
||||
TabBarQueueReorderFromMousePos(tab_bar, tab, g.IO.MousePos);
|
||||
}
|
||||
else if (g.IO.MouseDelta.x > 0.0f && g.IO.MousePos.x > bb.Max.x)
|
||||
{
|
||||
drag_dir = +1;
|
||||
drag_distance_from_edge_x = g.IO.MousePos.x - bb.Max.x;
|
||||
TabBarQueueReorderFromMousePos(tab_bar, tab, g.IO.MousePos);
|
||||
}
|
||||
}
|
||||
|
||||
// Extract a Dockable window out of it's tab bar
|
||||
const bool can_undock = docked_window != NULL && !(docked_window->Flags & ImGuiWindowFlags_NoMove) && !(node->MergedFlags & ImGuiDockNodeFlags_NoUndocking);
|
||||
if (can_undock)
|
||||
{
|
||||
// We use a variable threshold to distinguish dragging tabs within a tab bar and extracting them out of the tab bar
|
||||
bool undocking_tab = (g.DragDropActive && g.DragDropPayload.SourceId == id);
|
||||
if (!undocking_tab) //&& (!g.IO.ConfigDockingWithShift || g.IO.KeyShift)
|
||||
{
|
||||
float threshold_base = g.FontSize;
|
||||
float threshold_x = (threshold_base * 2.2f);
|
||||
float threshold_y = (threshold_base * 1.5f) + ImClamp((ImFabs(g.IO.MouseDragMaxDistanceAbs[0].x) - threshold_base * 2.0f) * 0.20f, 0.0f, threshold_base * 4.0f);
|
||||
//GetForegroundDrawList()->AddRect(ImVec2(bb.Min.x - threshold_x, bb.Min.y - threshold_y), ImVec2(bb.Max.x + threshold_x, bb.Max.y + threshold_y), IM_COL32_WHITE); // [DEBUG]
|
||||
|
||||
float distance_from_edge_y = ImMax(bb.Min.y - g.IO.MousePos.y, g.IO.MousePos.y - bb.Max.y);
|
||||
if (distance_from_edge_y >= threshold_y)
|
||||
undocking_tab = true;
|
||||
if (drag_distance_from_edge_x > threshold_x)
|
||||
if ((drag_dir < 0 && TabBarGetTabOrder(tab_bar, tab) == 0) || (drag_dir > 0 && TabBarGetTabOrder(tab_bar, tab) == tab_bar->Tabs.Size - 1))
|
||||
undocking_tab = true;
|
||||
}
|
||||
|
||||
if (undocking_tab)
|
||||
{
|
||||
// Undock
|
||||
// FIXME: refactor to share more code with e.g. StartMouseMovingWindow
|
||||
DockContextQueueUndockWindow(&g, docked_window);
|
||||
g.MovingWindow = docked_window;
|
||||
SetActiveID(g.MovingWindow->MoveId, g.MovingWindow);
|
||||
g.ActiveIdClickOffset -= g.MovingWindow->Pos - bb.Min;
|
||||
g.ActiveIdNoClearOnFocusLoss = true;
|
||||
SetActiveIdUsingAllKeyboardKeys();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
@@ -8740,7 +8853,7 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
|
||||
flags |= ImGuiTabItemFlags_NoCloseWithMiddleMouseButton;
|
||||
|
||||
// Render tab label, process close button
|
||||
const ImGuiID close_button_id = p_open ? GetIDWithSeed("#CLOSE", NULL, id) : 0;
|
||||
const ImGuiID close_button_id = p_open ? GetIDWithSeed("#CLOSE", NULL, docked_window ? docked_window->ID : id) : 0;
|
||||
bool just_closed;
|
||||
bool text_clipped;
|
||||
TabItemLabelAndCloseButton(display_draw_list, bb, tab_just_unsaved ? (flags & ~ImGuiTabItemFlags_UnsavedDocument) : flags, tab_bar->FramePadding, label, id, close_button_id, tab_contents_visible, &just_closed, &text_clipped);
|
||||
@@ -8750,6 +8863,11 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
|
||||
TabBarCloseTab(tab_bar, tab);
|
||||
}
|
||||
|
||||
// Forward Hovered state so IsItemHovered() after Begin() can work (even though we are technically hovering our parent)
|
||||
// That state is copied to window->DockTabItemStatusFlags by our caller.
|
||||
if (docked_window && (hovered || g.HoveredId == close_button_id))
|
||||
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HoveredWindow;
|
||||
|
||||
// Restore main window position so user can draw there
|
||||
if (want_clip_rect)
|
||||
PopClipRect();
|
||||
@@ -8784,6 +8902,16 @@ void ImGui::SetTabItemClosed(const char* label)
|
||||
if (ImGuiTabItem* tab = TabBarFindTabByID(tab_bar, tab_id))
|
||||
tab->WantClose = true; // Will be processed by next call to TabBarLayout()
|
||||
}
|
||||
else if (ImGuiWindow* window = FindWindowByName(label))
|
||||
{
|
||||
if (window->DockIsActive)
|
||||
if (ImGuiDockNode* node = window->DockNode)
|
||||
{
|
||||
ImGuiID tab_id = TabBarCalcTabID(node->TabBar, label, window);
|
||||
TabBarRemoveTab(node->TabBar, tab_id);
|
||||
window->DockTabWantClose = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImVec2 ImGui::TabItemCalcSize(const char* label, bool has_close_button_or_unsaved_marker)
|
||||
@@ -8798,10 +8926,9 @@ ImVec2 ImGui::TabItemCalcSize(const char* label, bool has_close_button_or_unsave
|
||||
return ImVec2(ImMin(size.x, TabBarCalcMaxTabWidth()), size.y);
|
||||
}
|
||||
|
||||
ImVec2 ImGui::TabItemCalcSize(ImGuiWindow*)
|
||||
ImVec2 ImGui::TabItemCalcSize(ImGuiWindow* window)
|
||||
{
|
||||
IM_ASSERT(0); // This function exists to facilitate merge with 'docking' branch.
|
||||
return ImVec2(0.0f, 0.0f);
|
||||
return TabItemCalcSize(window->Name, window->HasCloseButton || (window->Flags & ImGuiWindowFlags_UnsavedDocument));
|
||||
}
|
||||
|
||||
void ImGui::TabItemBackground(ImDrawList* draw_list, const ImRect& bb, ImGuiTabItemFlags flags, ImU32 col)
|
||||
|
||||
143
imstb_textedit.h
143
imstb_textedit.h
@@ -4,6 +4,7 @@
|
||||
// - Fix in stb_textedit_discard_redo (see https://github.com/nothings/stb/issues/321)
|
||||
// - Fix in stb_textedit_find_charpos to handle last line (see https://github.com/ocornut/imgui/issues/6000 + #6783)
|
||||
// Grep for [DEAR IMGUI] to find the changes.
|
||||
// - Also renamed macros used or defined outside of IMSTB_TEXTEDIT_IMPLEMENTATION block from STB_TEXTEDIT_* to IMSTB_TEXTEDIT_*
|
||||
|
||||
// stb_textedit.h - v1.14 - public domain - Sean Barrett
|
||||
// Development of this library was sponsored by RAD Game Tools
|
||||
@@ -30,7 +31,7 @@
|
||||
// DEPENDENCIES
|
||||
//
|
||||
// Uses the C runtime function 'memmove', which you can override
|
||||
// by defining STB_TEXTEDIT_memmove before the implementation.
|
||||
// by defining IMSTB_TEXTEDIT_memmove before the implementation.
|
||||
// Uses no other functions. Performs no runtime allocations.
|
||||
//
|
||||
//
|
||||
@@ -274,8 +275,8 @@
|
||||
////
|
||||
////
|
||||
|
||||
#ifndef INCLUDE_STB_TEXTEDIT_H
|
||||
#define INCLUDE_STB_TEXTEDIT_H
|
||||
#ifndef INCLUDE_IMSTB_TEXTEDIT_H
|
||||
#define INCLUDE_IMSTB_TEXTEDIT_H
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@@ -286,33 +287,33 @@
|
||||
// and undo state.
|
||||
//
|
||||
|
||||
#ifndef STB_TEXTEDIT_UNDOSTATECOUNT
|
||||
#define STB_TEXTEDIT_UNDOSTATECOUNT 99
|
||||
#ifndef IMSTB_TEXTEDIT_UNDOSTATECOUNT
|
||||
#define IMSTB_TEXTEDIT_UNDOSTATECOUNT 99
|
||||
#endif
|
||||
#ifndef STB_TEXTEDIT_UNDOCHARCOUNT
|
||||
#define STB_TEXTEDIT_UNDOCHARCOUNT 999
|
||||
#ifndef IMSTB_TEXTEDIT_UNDOCHARCOUNT
|
||||
#define IMSTB_TEXTEDIT_UNDOCHARCOUNT 999
|
||||
#endif
|
||||
#ifndef STB_TEXTEDIT_CHARTYPE
|
||||
#define STB_TEXTEDIT_CHARTYPE int
|
||||
#ifndef IMSTB_TEXTEDIT_CHARTYPE
|
||||
#define IMSTB_TEXTEDIT_CHARTYPE int
|
||||
#endif
|
||||
#ifndef STB_TEXTEDIT_POSITIONTYPE
|
||||
#define STB_TEXTEDIT_POSITIONTYPE int
|
||||
#ifndef IMSTB_TEXTEDIT_POSITIONTYPE
|
||||
#define IMSTB_TEXTEDIT_POSITIONTYPE int
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
// private data
|
||||
STB_TEXTEDIT_POSITIONTYPE where;
|
||||
STB_TEXTEDIT_POSITIONTYPE insert_length;
|
||||
STB_TEXTEDIT_POSITIONTYPE delete_length;
|
||||
IMSTB_TEXTEDIT_POSITIONTYPE where;
|
||||
IMSTB_TEXTEDIT_POSITIONTYPE insert_length;
|
||||
IMSTB_TEXTEDIT_POSITIONTYPE delete_length;
|
||||
int char_storage;
|
||||
} StbUndoRecord;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
// private data
|
||||
StbUndoRecord undo_rec [STB_TEXTEDIT_UNDOSTATECOUNT];
|
||||
STB_TEXTEDIT_CHARTYPE undo_char[STB_TEXTEDIT_UNDOCHARCOUNT];
|
||||
StbUndoRecord undo_rec [IMSTB_TEXTEDIT_UNDOSTATECOUNT];
|
||||
IMSTB_TEXTEDIT_CHARTYPE undo_char[IMSTB_TEXTEDIT_UNDOCHARCOUNT];
|
||||
short undo_point, redo_point;
|
||||
int undo_char_point, redo_char_point;
|
||||
} StbUndoState;
|
||||
@@ -371,7 +372,7 @@ typedef struct
|
||||
float ymin,ymax; // height of row above and below baseline
|
||||
int num_chars;
|
||||
} StbTexteditRow;
|
||||
#endif //INCLUDE_STB_TEXTEDIT_H
|
||||
#endif //INCLUDE_IMSTB_TEXTEDIT_H
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
@@ -384,11 +385,11 @@ typedef struct
|
||||
|
||||
// implementation isn't include-guarded, since it might have indirectly
|
||||
// included just the "header" portion
|
||||
#ifdef STB_TEXTEDIT_IMPLEMENTATION
|
||||
#ifdef IMSTB_TEXTEDIT_IMPLEMENTATION
|
||||
|
||||
#ifndef STB_TEXTEDIT_memmove
|
||||
#ifndef IMSTB_TEXTEDIT_memmove
|
||||
#include <string.h>
|
||||
#define STB_TEXTEDIT_memmove memmove
|
||||
#define IMSTB_TEXTEDIT_memmove memmove
|
||||
#endif
|
||||
|
||||
|
||||
@@ -398,7 +399,7 @@ typedef struct
|
||||
//
|
||||
|
||||
// traverse the layout to locate the nearest character to a display position
|
||||
static int stb_text_locate_coord(STB_TEXTEDIT_STRING *str, float x, float y)
|
||||
static int stb_text_locate_coord(IMSTB_TEXTEDIT_STRING *str, float x, float y)
|
||||
{
|
||||
StbTexteditRow r;
|
||||
int n = STB_TEXTEDIT_STRINGLEN(str);
|
||||
@@ -458,7 +459,7 @@ static int stb_text_locate_coord(STB_TEXTEDIT_STRING *str, float x, float y)
|
||||
}
|
||||
|
||||
// API click: on mouse down, move the cursor to the clicked location, and reset the selection
|
||||
static void stb_textedit_click(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y)
|
||||
static void stb_textedit_click(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y)
|
||||
{
|
||||
// In single-line mode, just always make y = 0. This lets the drag keep working if the mouse
|
||||
// goes off the top or bottom of the text
|
||||
@@ -476,7 +477,7 @@ static void stb_textedit_click(STB_TEXTEDIT_STRING *str, STB_TexteditState *stat
|
||||
}
|
||||
|
||||
// API drag: on mouse drag, move the cursor and selection endpoint to the clicked location
|
||||
static void stb_textedit_drag(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y)
|
||||
static void stb_textedit_drag(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y)
|
||||
{
|
||||
int p = 0;
|
||||
|
||||
@@ -502,11 +503,11 @@ static void stb_textedit_drag(STB_TEXTEDIT_STRING *str, STB_TexteditState *state
|
||||
//
|
||||
|
||||
// forward declarations
|
||||
static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state);
|
||||
static void stb_text_redo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state);
|
||||
static void stb_text_makeundo_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length);
|
||||
static void stb_text_undo(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state);
|
||||
static void stb_text_redo(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state);
|
||||
static void stb_text_makeundo_delete(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length);
|
||||
static void stb_text_makeundo_insert(STB_TexteditState *state, int where, int length);
|
||||
static void stb_text_makeundo_replace(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int old_length, int new_length);
|
||||
static void stb_text_makeundo_replace(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int old_length, int new_length);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -518,7 +519,7 @@ typedef struct
|
||||
|
||||
// find the x/y location of a character, and remember info about the previous row in
|
||||
// case we get a move-up event (for page up, we'll have to rescan)
|
||||
static void stb_textedit_find_charpos(StbFindState *find, STB_TEXTEDIT_STRING *str, int n, int single_line)
|
||||
static void stb_textedit_find_charpos(StbFindState *find, IMSTB_TEXTEDIT_STRING *str, int n, int single_line)
|
||||
{
|
||||
StbTexteditRow r;
|
||||
int prev_start = 0;
|
||||
@@ -569,7 +570,7 @@ static void stb_textedit_find_charpos(StbFindState *find, STB_TEXTEDIT_STRING *s
|
||||
#define STB_TEXT_HAS_SELECTION(s) ((s)->select_start != (s)->select_end)
|
||||
|
||||
// make the selection/cursor state valid if client altered the string
|
||||
static void stb_textedit_clamp(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||
static void stb_textedit_clamp(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||
{
|
||||
int n = STB_TEXTEDIT_STRINGLEN(str);
|
||||
if (STB_TEXT_HAS_SELECTION(state)) {
|
||||
@@ -583,7 +584,7 @@ static void stb_textedit_clamp(STB_TEXTEDIT_STRING *str, STB_TexteditState *stat
|
||||
}
|
||||
|
||||
// delete characters while updating undo
|
||||
static void stb_textedit_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int len)
|
||||
static void stb_textedit_delete(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int len)
|
||||
{
|
||||
stb_text_makeundo_delete(str, state, where, len);
|
||||
STB_TEXTEDIT_DELETECHARS(str, where, len);
|
||||
@@ -591,7 +592,7 @@ static void stb_textedit_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *sta
|
||||
}
|
||||
|
||||
// delete the section
|
||||
static void stb_textedit_delete_selection(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||
static void stb_textedit_delete_selection(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||
{
|
||||
stb_textedit_clamp(str, state);
|
||||
if (STB_TEXT_HAS_SELECTION(state)) {
|
||||
@@ -628,7 +629,7 @@ static void stb_textedit_move_to_first(STB_TexteditState *state)
|
||||
}
|
||||
|
||||
// move cursor to last character of selection
|
||||
static void stb_textedit_move_to_last(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||
static void stb_textedit_move_to_last(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||
{
|
||||
if (STB_TEXT_HAS_SELECTION(state)) {
|
||||
stb_textedit_sortselection(state);
|
||||
@@ -640,13 +641,13 @@ static void stb_textedit_move_to_last(STB_TEXTEDIT_STRING *str, STB_TexteditStat
|
||||
}
|
||||
|
||||
#ifdef STB_TEXTEDIT_IS_SPACE
|
||||
static int is_word_boundary( STB_TEXTEDIT_STRING *str, int idx )
|
||||
static int is_word_boundary( IMSTB_TEXTEDIT_STRING *str, int idx )
|
||||
{
|
||||
return idx > 0 ? (STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(str,idx-1) ) && !STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(str, idx) ) ) : 1;
|
||||
}
|
||||
|
||||
#ifndef STB_TEXTEDIT_MOVEWORDLEFT
|
||||
static int stb_textedit_move_to_word_previous( STB_TEXTEDIT_STRING *str, int c )
|
||||
static int stb_textedit_move_to_word_previous( IMSTB_TEXTEDIT_STRING *str, int c )
|
||||
{
|
||||
--c; // always move at least one character
|
||||
while( c >= 0 && !is_word_boundary( str, c ) )
|
||||
@@ -661,7 +662,7 @@ static int stb_textedit_move_to_word_previous( STB_TEXTEDIT_STRING *str, int c )
|
||||
#endif
|
||||
|
||||
#ifndef STB_TEXTEDIT_MOVEWORDRIGHT
|
||||
static int stb_textedit_move_to_word_next( STB_TEXTEDIT_STRING *str, int c )
|
||||
static int stb_textedit_move_to_word_next( IMSTB_TEXTEDIT_STRING *str, int c )
|
||||
{
|
||||
const int len = STB_TEXTEDIT_STRINGLEN(str);
|
||||
++c; // always move at least one character
|
||||
@@ -688,7 +689,7 @@ static void stb_textedit_prep_selection_at_cursor(STB_TexteditState *state)
|
||||
}
|
||||
|
||||
// API cut: delete selection
|
||||
static int stb_textedit_cut(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||
static int stb_textedit_cut(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||
{
|
||||
if (STB_TEXT_HAS_SELECTION(state)) {
|
||||
stb_textedit_delete_selection(str,state); // implicitly clamps
|
||||
@@ -699,7 +700,7 @@ static int stb_textedit_cut(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||
}
|
||||
|
||||
// API paste: replace existing selection with passed-in text
|
||||
static int stb_textedit_paste_internal(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_CHARTYPE *text, int len)
|
||||
static int stb_textedit_paste_internal(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, IMSTB_TEXTEDIT_CHARTYPE *text, int len)
|
||||
{
|
||||
// if there's a selection, the paste should delete it
|
||||
stb_textedit_clamp(str, state);
|
||||
@@ -720,14 +721,14 @@ static int stb_textedit_paste_internal(STB_TEXTEDIT_STRING *str, STB_TexteditSta
|
||||
#endif
|
||||
|
||||
// API key: process a keyboard input
|
||||
static void stb_textedit_key(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_KEYTYPE key)
|
||||
static void stb_textedit_key(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_KEYTYPE key)
|
||||
{
|
||||
retry:
|
||||
switch (key) {
|
||||
default: {
|
||||
int c = STB_TEXTEDIT_KEYTOTEXT(key);
|
||||
if (c > 0) {
|
||||
STB_TEXTEDIT_CHARTYPE ch = (STB_TEXTEDIT_CHARTYPE) c;
|
||||
IMSTB_TEXTEDIT_CHARTYPE ch = (IMSTB_TEXTEDIT_CHARTYPE) c;
|
||||
|
||||
// can't add newline in single-line mode
|
||||
if (c == '\n' && state->single_line)
|
||||
@@ -892,8 +893,8 @@ retry:
|
||||
x = row.x0;
|
||||
for (i=0; i < row.num_chars; ++i) {
|
||||
float dx = STB_TEXTEDIT_GETWIDTH(str, start, i);
|
||||
#ifdef STB_TEXTEDIT_GETWIDTH_NEWLINE
|
||||
if (dx == STB_TEXTEDIT_GETWIDTH_NEWLINE)
|
||||
#ifdef IMSTB_TEXTEDIT_GETWIDTH_NEWLINE
|
||||
if (dx == IMSTB_TEXTEDIT_GETWIDTH_NEWLINE)
|
||||
break;
|
||||
#endif
|
||||
x += dx;
|
||||
@@ -954,8 +955,8 @@ retry:
|
||||
x = row.x0;
|
||||
for (i=0; i < row.num_chars; ++i) {
|
||||
float dx = STB_TEXTEDIT_GETWIDTH(str, find.prev_first, i);
|
||||
#ifdef STB_TEXTEDIT_GETWIDTH_NEWLINE
|
||||
if (dx == STB_TEXTEDIT_GETWIDTH_NEWLINE)
|
||||
#ifdef IMSTB_TEXTEDIT_GETWIDTH_NEWLINE
|
||||
if (dx == IMSTB_TEXTEDIT_GETWIDTH_NEWLINE)
|
||||
break;
|
||||
#endif
|
||||
x += dx;
|
||||
@@ -1112,8 +1113,8 @@ retry:
|
||||
|
||||
static void stb_textedit_flush_redo(StbUndoState *state)
|
||||
{
|
||||
state->redo_point = STB_TEXTEDIT_UNDOSTATECOUNT;
|
||||
state->redo_char_point = STB_TEXTEDIT_UNDOCHARCOUNT;
|
||||
state->redo_point = IMSTB_TEXTEDIT_UNDOSTATECOUNT;
|
||||
state->redo_char_point = IMSTB_TEXTEDIT_UNDOCHARCOUNT;
|
||||
}
|
||||
|
||||
// discard the oldest entry in the undo list
|
||||
@@ -1125,13 +1126,13 @@ static void stb_textedit_discard_undo(StbUndoState *state)
|
||||
int n = state->undo_rec[0].insert_length, i;
|
||||
// delete n characters from all other records
|
||||
state->undo_char_point -= n;
|
||||
STB_TEXTEDIT_memmove(state->undo_char, state->undo_char + n, (size_t) (state->undo_char_point*sizeof(STB_TEXTEDIT_CHARTYPE)));
|
||||
IMSTB_TEXTEDIT_memmove(state->undo_char, state->undo_char + n, (size_t) (state->undo_char_point*sizeof(IMSTB_TEXTEDIT_CHARTYPE)));
|
||||
for (i=0; i < state->undo_point; ++i)
|
||||
if (state->undo_rec[i].char_storage >= 0)
|
||||
state->undo_rec[i].char_storage -= n; // @OPTIMIZE: get rid of char_storage and infer it
|
||||
}
|
||||
--state->undo_point;
|
||||
STB_TEXTEDIT_memmove(state->undo_rec, state->undo_rec+1, (size_t) (state->undo_point*sizeof(state->undo_rec[0])));
|
||||
IMSTB_TEXTEDIT_memmove(state->undo_rec, state->undo_rec+1, (size_t) (state->undo_point*sizeof(state->undo_rec[0])));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1141,7 +1142,7 @@ static void stb_textedit_discard_undo(StbUndoState *state)
|
||||
// fill up even though the undo buffer didn't
|
||||
static void stb_textedit_discard_redo(StbUndoState *state)
|
||||
{
|
||||
int k = STB_TEXTEDIT_UNDOSTATECOUNT-1;
|
||||
int k = IMSTB_TEXTEDIT_UNDOSTATECOUNT-1;
|
||||
|
||||
if (state->redo_point <= k) {
|
||||
// if the k'th undo state has characters, clean those up
|
||||
@@ -1149,7 +1150,7 @@ static void stb_textedit_discard_redo(StbUndoState *state)
|
||||
int n = state->undo_rec[k].insert_length, i;
|
||||
// move the remaining redo character data to the end of the buffer
|
||||
state->redo_char_point += n;
|
||||
STB_TEXTEDIT_memmove(state->undo_char + state->redo_char_point, state->undo_char + state->redo_char_point-n, (size_t) ((STB_TEXTEDIT_UNDOCHARCOUNT - state->redo_char_point)*sizeof(STB_TEXTEDIT_CHARTYPE)));
|
||||
IMSTB_TEXTEDIT_memmove(state->undo_char + state->redo_char_point, state->undo_char + state->redo_char_point-n, (size_t) ((IMSTB_TEXTEDIT_UNDOCHARCOUNT - state->redo_char_point)*sizeof(IMSTB_TEXTEDIT_CHARTYPE)));
|
||||
// adjust the position of all the other records to account for above memmove
|
||||
for (i=state->redo_point; i < k; ++i)
|
||||
if (state->undo_rec[i].char_storage >= 0)
|
||||
@@ -1157,12 +1158,12 @@ static void stb_textedit_discard_redo(StbUndoState *state)
|
||||
}
|
||||
// now move all the redo records towards the end of the buffer; the first one is at 'redo_point'
|
||||
// [DEAR IMGUI]
|
||||
size_t move_size = (size_t)((STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point - 1) * sizeof(state->undo_rec[0]));
|
||||
size_t move_size = (size_t)((IMSTB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point - 1) * sizeof(state->undo_rec[0]));
|
||||
const char* buf_begin = (char*)state->undo_rec; (void)buf_begin;
|
||||
const char* buf_end = (char*)state->undo_rec + sizeof(state->undo_rec); (void)buf_end;
|
||||
IM_ASSERT(((char*)(state->undo_rec + state->redo_point)) >= buf_begin);
|
||||
IM_ASSERT(((char*)(state->undo_rec + state->redo_point + 1) + move_size) <= buf_end);
|
||||
STB_TEXTEDIT_memmove(state->undo_rec + state->redo_point+1, state->undo_rec + state->redo_point, move_size);
|
||||
IMSTB_TEXTEDIT_memmove(state->undo_rec + state->redo_point+1, state->undo_rec + state->redo_point, move_size);
|
||||
|
||||
// now move redo_point to point to the new one
|
||||
++state->redo_point;
|
||||
@@ -1176,32 +1177,32 @@ static StbUndoRecord *stb_text_create_undo_record(StbUndoState *state, int numch
|
||||
|
||||
// if we have no free records, we have to make room, by sliding the
|
||||
// existing records down
|
||||
if (state->undo_point == STB_TEXTEDIT_UNDOSTATECOUNT)
|
||||
if (state->undo_point == IMSTB_TEXTEDIT_UNDOSTATECOUNT)
|
||||
stb_textedit_discard_undo(state);
|
||||
|
||||
// if the characters to store won't possibly fit in the buffer, we can't undo
|
||||
if (numchars > STB_TEXTEDIT_UNDOCHARCOUNT) {
|
||||
if (numchars > IMSTB_TEXTEDIT_UNDOCHARCOUNT) {
|
||||
state->undo_point = 0;
|
||||
state->undo_char_point = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// if we don't have enough free characters in the buffer, we have to make room
|
||||
while (state->undo_char_point + numchars > STB_TEXTEDIT_UNDOCHARCOUNT)
|
||||
while (state->undo_char_point + numchars > IMSTB_TEXTEDIT_UNDOCHARCOUNT)
|
||||
stb_textedit_discard_undo(state);
|
||||
|
||||
return &state->undo_rec[state->undo_point++];
|
||||
}
|
||||
|
||||
static STB_TEXTEDIT_CHARTYPE *stb_text_createundo(StbUndoState *state, int pos, int insert_len, int delete_len)
|
||||
static IMSTB_TEXTEDIT_CHARTYPE *stb_text_createundo(StbUndoState *state, int pos, int insert_len, int delete_len)
|
||||
{
|
||||
StbUndoRecord *r = stb_text_create_undo_record(state, insert_len);
|
||||
if (r == NULL)
|
||||
return NULL;
|
||||
|
||||
r->where = pos;
|
||||
r->insert_length = (STB_TEXTEDIT_POSITIONTYPE) insert_len;
|
||||
r->delete_length = (STB_TEXTEDIT_POSITIONTYPE) delete_len;
|
||||
r->insert_length = (IMSTB_TEXTEDIT_POSITIONTYPE) insert_len;
|
||||
r->delete_length = (IMSTB_TEXTEDIT_POSITIONTYPE) delete_len;
|
||||
|
||||
if (insert_len == 0) {
|
||||
r->char_storage = -1;
|
||||
@@ -1213,7 +1214,7 @@ static STB_TEXTEDIT_CHARTYPE *stb_text_createundo(StbUndoState *state, int pos,
|
||||
}
|
||||
}
|
||||
|
||||
static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||
static void stb_text_undo(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||
{
|
||||
StbUndoState *s = &state->undostate;
|
||||
StbUndoRecord u, *r;
|
||||
@@ -1240,7 +1241,7 @@ static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||
// characters stored for *undoing* don't leave room for redo
|
||||
// if the last is true, we have to bail
|
||||
|
||||
if (s->undo_char_point + u.delete_length >= STB_TEXTEDIT_UNDOCHARCOUNT) {
|
||||
if (s->undo_char_point + u.delete_length >= IMSTB_TEXTEDIT_UNDOCHARCOUNT) {
|
||||
// the undo records take up too much character space; there's no space to store the redo characters
|
||||
r->insert_length = 0;
|
||||
} else {
|
||||
@@ -1249,7 +1250,7 @@ static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||
// there's definitely room to store the characters eventually
|
||||
while (s->undo_char_point + u.delete_length > s->redo_char_point) {
|
||||
// should never happen:
|
||||
if (s->redo_point == STB_TEXTEDIT_UNDOSTATECOUNT)
|
||||
if (s->redo_point == IMSTB_TEXTEDIT_UNDOSTATECOUNT)
|
||||
return;
|
||||
// there's currently not enough room, so discard a redo record
|
||||
stb_textedit_discard_redo(s);
|
||||
@@ -1281,11 +1282,11 @@ static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||
s->redo_point--;
|
||||
}
|
||||
|
||||
static void stb_text_redo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||
static void stb_text_redo(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||
{
|
||||
StbUndoState *s = &state->undostate;
|
||||
StbUndoRecord *u, r;
|
||||
if (s->redo_point == STB_TEXTEDIT_UNDOSTATECOUNT)
|
||||
if (s->redo_point == IMSTB_TEXTEDIT_UNDOSTATECOUNT)
|
||||
return;
|
||||
|
||||
// we need to do two things: apply the redo record, and create an undo record
|
||||
@@ -1337,20 +1338,20 @@ static void stb_text_makeundo_insert(STB_TexteditState *state, int where, int le
|
||||
stb_text_createundo(&state->undostate, where, 0, length);
|
||||
}
|
||||
|
||||
static void stb_text_makeundo_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length)
|
||||
static void stb_text_makeundo_delete(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length)
|
||||
{
|
||||
int i;
|
||||
STB_TEXTEDIT_CHARTYPE *p = stb_text_createundo(&state->undostate, where, length, 0);
|
||||
IMSTB_TEXTEDIT_CHARTYPE *p = stb_text_createundo(&state->undostate, where, length, 0);
|
||||
if (p) {
|
||||
for (i=0; i < length; ++i)
|
||||
p[i] = STB_TEXTEDIT_GETCHAR(str, where+i);
|
||||
}
|
||||
}
|
||||
|
||||
static void stb_text_makeundo_replace(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int old_length, int new_length)
|
||||
static void stb_text_makeundo_replace(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int old_length, int new_length)
|
||||
{
|
||||
int i;
|
||||
STB_TEXTEDIT_CHARTYPE *p = stb_text_createundo(&state->undostate, where, old_length, new_length);
|
||||
IMSTB_TEXTEDIT_CHARTYPE *p = stb_text_createundo(&state->undostate, where, old_length, new_length);
|
||||
if (p) {
|
||||
for (i=0; i < old_length; ++i)
|
||||
p[i] = STB_TEXTEDIT_GETCHAR(str, where+i);
|
||||
@@ -1362,8 +1363,8 @@ static void stb_textedit_clear_state(STB_TexteditState *state, int is_single_lin
|
||||
{
|
||||
state->undostate.undo_point = 0;
|
||||
state->undostate.undo_char_point = 0;
|
||||
state->undostate.redo_point = STB_TEXTEDIT_UNDOSTATECOUNT;
|
||||
state->undostate.redo_char_point = STB_TEXTEDIT_UNDOCHARCOUNT;
|
||||
state->undostate.redo_point = IMSTB_TEXTEDIT_UNDOSTATECOUNT;
|
||||
state->undostate.redo_char_point = IMSTB_TEXTEDIT_UNDOCHARCOUNT;
|
||||
state->select_end = state->select_start = 0;
|
||||
state->cursor = 0;
|
||||
state->has_preferred_x = 0;
|
||||
@@ -1386,16 +1387,16 @@ static void stb_textedit_initialize_state(STB_TexteditState *state, int is_singl
|
||||
#pragma GCC diagnostic ignored "-Wcast-qual"
|
||||
#endif
|
||||
|
||||
static int stb_textedit_paste(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_CHARTYPE const *ctext, int len)
|
||||
static int stb_textedit_paste(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, IMSTB_TEXTEDIT_CHARTYPE const *ctext, int len)
|
||||
{
|
||||
return stb_textedit_paste_internal(str, state, (STB_TEXTEDIT_CHARTYPE *) ctext, len);
|
||||
return stb_textedit_paste_internal(str, state, (IMSTB_TEXTEDIT_CHARTYPE *) ctext, len);
|
||||
}
|
||||
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif//STB_TEXTEDIT_IMPLEMENTATION
|
||||
#endif//IMSTB_TEXTEDIT_IMPLEMENTATION
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
@@ -55,4 +55,8 @@ More information at: https://docs.microsoft.com/en-us/visualstudio/debugger/crea
|
||||
<DisplayString>{{Name {Name,s} Active {(Active||WasActive)?1:0,d} Child {(Flags & 0x01000000)?1:0,d} Popup {(Flags & 0x04000000)?1:0,d} Hidden {(Hidden)?1:0,d}}</DisplayString>
|
||||
</Type>
|
||||
|
||||
<Type Name="ImGuiDockNode">
|
||||
<DisplayString>{{ID {ID,x} Pos=({Pos.x,g} {Pos.y,g}) Size=({Size.x,g} {Size.y,g}) Parent {(ParentNode==0)?0:ParentNode->ID,x} Childs {(ChildNodes[0] != 0)+(ChildNodes[1] != 0)} Windows {Windows.Size} }</DisplayString>
|
||||
</Type>
|
||||
|
||||
</AutoVisualizer>
|
||||
|
||||
@@ -437,7 +437,7 @@ bool ImFontAtlasBuildWithFreeTypeEx(FT_Library ft_library, ImFontAtlas* atlas, u
|
||||
ImFontAtlasBuildInit(atlas);
|
||||
|
||||
// Clear atlas
|
||||
atlas->TexID = (ImTextureID)nullptr;
|
||||
atlas->TexID = 0;
|
||||
atlas->TexWidth = atlas->TexHeight = 0;
|
||||
atlas->TexUvScale = ImVec2(0.0f, 0.0f);
|
||||
atlas->TexUvWhitePixel = ImVec2(0.0f, 0.0f);
|
||||
|
||||
@@ -43,9 +43,8 @@ namespace ImGuiFreeType
|
||||
IMGUI_API void SetAllocatorFunctions(void* (*alloc_func)(size_t sz, void* user_data), void (*free_func)(void* ptr, void* user_data), void* user_data = nullptr);
|
||||
|
||||
// Obsolete names (will be removed soon)
|
||||
// Prefer using '#define IMGUI_ENABLE_FREETYPE'
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
static inline bool BuildFontAtlas(ImFontAtlas* atlas, unsigned int flags = 0) { atlas->FontBuilderIO = GetBuilderForFreeType(); atlas->FontBuilderFlags = flags; return atlas->Build(); }
|
||||
//static inline bool BuildFontAtlas(ImFontAtlas* atlas, unsigned int flags = 0) { atlas->FontBuilderIO = GetBuilderForFreeType(); atlas->FontBuilderFlags = flags; return atlas->Build(); } // Prefer using '#define IMGUI_ENABLE_FREETYPE'
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user