Compare commits
1216 Commits
1.7
...
bugrepro/q
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
02affc24c7 | ||
|
|
cb5a42ef2e | ||
|
|
437bc31aca | ||
|
|
7597bb70a6 | ||
|
|
b6bbaf9e53 | ||
|
|
70b566b1b8 | ||
|
|
8adba89a83 | ||
|
|
04c069bf1b | ||
|
|
edb06f2543 | ||
|
|
de21f60910 | ||
|
|
f110afd1d0 | ||
|
|
84052f6db0 | ||
|
|
2b8b069396 | ||
|
|
1bed9c8a62 | ||
|
|
7eddab06d2 | ||
|
|
66a572f177 | ||
|
|
1ee12f5b90 | ||
|
|
b1ff6bf11b | ||
|
|
d8eac5c04b | ||
|
|
8c0b76074c | ||
|
|
498a0627fd | ||
|
|
04df3d5bab | ||
|
|
2a53aa8fa2 | ||
|
|
0c92b1dd6c | ||
|
|
e265a33b4c | ||
|
|
75526982f3 | ||
|
|
9c4b53faa6 | ||
|
|
18d0875bde | ||
|
|
d9afb45c05 | ||
|
|
c52ecb65b6 | ||
|
|
3f34d12805 | ||
|
|
e01a332386 | ||
|
|
0e66f8a368 | ||
|
|
6241eeca66 | ||
|
|
d54d417c09 | ||
|
|
e8814b102a | ||
|
|
aca80b186e | ||
|
|
34d614ab37 | ||
|
|
c91e5099e0 | ||
|
|
4ccb7df73c | ||
|
|
fd122b08da | ||
|
|
617c3d0029 | ||
|
|
f4db14a745 | ||
|
|
4a86415c65 | ||
|
|
29ac5a2d16 | ||
|
|
9995f70c78 | ||
|
|
38f605d562 | ||
|
|
c6f0ec9d98 | ||
|
|
4cb4ab9db0 | ||
|
|
d5214b8605 | ||
|
|
9dbca2618d | ||
|
|
383246aa7f | ||
|
|
f1efa95802 | ||
|
|
f18a288def | ||
|
|
cf6b3c06e0 | ||
|
|
94fcdc990c | ||
|
|
96990be5bb | ||
|
|
0157d7d914 | ||
|
|
fbfec2f196 | ||
|
|
60dcec9286 | ||
|
|
4e3f4e3073 | ||
|
|
cf44110033 | ||
|
|
3cb6c2b8d0 | ||
|
|
b5a9c03c21 | ||
|
|
3a280ae377 | ||
|
|
29be2ae819 | ||
|
|
764385de9f | ||
|
|
ea7cb3cbbb | ||
|
|
4fc43cbadd | ||
|
|
932a80e73b | ||
|
|
ac0b00add3 | ||
|
|
82729c85ea | ||
|
|
fd98824184 | ||
|
|
3ce1a6c77e | ||
|
|
bc8d17119a | ||
|
|
411750e865 | ||
|
|
3ac8c5f384 | ||
|
|
6b720715bf | ||
|
|
d515969724 | ||
|
|
ad8457490b | ||
|
|
c0ef4ae0d2 | ||
|
|
ede6dff09b | ||
|
|
c1420a7e80 | ||
|
|
ef1ce9bb1d | ||
|
|
52cd8f753d | ||
|
|
496be36585 | ||
|
|
f9e758d02f | ||
|
|
958d1500e5 | ||
|
|
282c3106a4 | ||
|
|
a74dace6e4 | ||
|
|
1998800883 | ||
|
|
c8b16c9712 | ||
|
|
ffc8038cc4 | ||
|
|
21d7d220c5 | ||
|
|
b52bb85190 | ||
|
|
c8386e6ce1 | ||
|
|
9d9bce1860 | ||
|
|
12e8549f8f | ||
|
|
f0c008fae3 | ||
|
|
61e93a1970 | ||
|
|
763ad1ae6b | ||
|
|
bf43df1233 | ||
|
|
8e0ba911d0 | ||
|
|
a1f427e8e2 | ||
|
|
301af34dec | ||
|
|
598fedaf86 | ||
|
|
809ca9e586 | ||
|
|
8c881b6db7 | ||
|
|
b0f98dfd2d | ||
|
|
8e5e4d9d0e | ||
|
|
ee14264655 | ||
|
|
6757370ca0 | ||
|
|
91f0a250e7 | ||
|
|
63ae96a919 | ||
|
|
65b0b7e140 | ||
|
|
a11414ed8d | ||
|
|
74bd786be8 | ||
|
|
ca26e856db | ||
|
|
be2c297fa9 | ||
|
|
838e953320 | ||
|
|
e61d55df53 | ||
|
|
376202c3f8 | ||
|
|
2a37813409 | ||
|
|
bbef108e32 | ||
|
|
a0329a01fb | ||
|
|
4af2f1d46b | ||
|
|
24040ccfbf | ||
|
|
5a455f86a1 | ||
|
|
9a8ca5135e | ||
|
|
a9485ee0b2 | ||
|
|
6a9988e7b0 | ||
|
|
7f072366ed | ||
|
|
0b5e9bc6c1 | ||
|
|
8834f7d75b | ||
|
|
4627571f3f | ||
|
|
d071fc440a | ||
|
|
bcbb75da72 | ||
|
|
ca0f767f21 | ||
|
|
30955b5f5b | ||
|
|
7a4c969b86 | ||
|
|
3ffe116a02 | ||
|
|
fb59e30c59 | ||
|
|
8955ec8bcb | ||
|
|
1868ad7bd4 | ||
|
|
1abebef40b | ||
|
|
de3ef59506 | ||
|
|
b56e6a8279 | ||
|
|
da21d35f4b | ||
|
|
73cdaa8698 | ||
|
|
a97e3ae831 | ||
|
|
6bc2979989 | ||
|
|
3c48b3aab3 | ||
|
|
7371171115 | ||
|
|
da38c09dec | ||
|
|
b55656deec | ||
|
|
76b03f4700 | ||
|
|
cc719325cc | ||
|
|
a52428cf35 | ||
|
|
47ada6dd56 | ||
|
|
2862f2b76f | ||
|
|
48b067023f | ||
|
|
51b47a26af | ||
|
|
cc8dbd3d0c | ||
|
|
c523d514ee | ||
|
|
e9e88d81e8 | ||
|
|
cffea940ea | ||
|
|
647cb4c7f6 | ||
|
|
0b2cc6e078 | ||
|
|
d9f1a04e8d | ||
|
|
048d156998 | ||
|
|
65f23f9c30 | ||
|
|
667b9bb28c | ||
|
|
fb6175c4b3 | ||
|
|
192533647d | ||
|
|
2afe86e63b | ||
|
|
b52070dc0e | ||
|
|
3cbd437ee6 | ||
|
|
532dc04ec6 | ||
|
|
8050ca6259 | ||
|
|
f493c44729 | ||
|
|
11301e2f0f | ||
|
|
151bc356fc | ||
|
|
f4f7e4508b | ||
|
|
9cf99ff45c | ||
|
|
882f25c7f7 | ||
|
|
69c7d3fd57 | ||
|
|
62d8426ec4 | ||
|
|
d8189e3e03 | ||
|
|
9a4daf8926 | ||
|
|
4c1e45eea9 | ||
|
|
98a7a0e017 | ||
|
|
c461721456 | ||
|
|
f634a1e3f7 | ||
|
|
7a8222a063 | ||
|
|
35042c2bef | ||
|
|
c9c3fdc1a2 | ||
|
|
69c2c0770f | ||
|
|
3f32bc3dce | ||
|
|
8a76c63983 | ||
|
|
7cc4bae1b7 | ||
|
|
bf922a2ecb | ||
|
|
27b8480da6 | ||
|
|
f97a660584 | ||
|
|
6d30643672 | ||
|
|
e4b2d37f96 | ||
|
|
45ad75fcd4 | ||
|
|
8e5225224d | ||
|
|
8a65d2cc0b | ||
|
|
cfb5c5e2fe | ||
|
|
2c58580d06 | ||
|
|
4901b977a0 | ||
|
|
120557b8a6 | ||
|
|
3c51d201d5 | ||
|
|
b1fcae9bc2 | ||
|
|
ecd05ffbc5 | ||
|
|
7b20eedf6d | ||
|
|
93b3f77969 | ||
|
|
f7c3dea53f | ||
|
|
02e591fc52 | ||
|
|
3ee9866d84 | ||
|
|
84ec64fade | ||
|
|
f8f75cdabc | ||
|
|
feda194b01 | ||
|
|
249ee2ce67 | ||
|
|
d97ccb9792 | ||
|
|
90ba005bc6 | ||
|
|
1a762df812 | ||
|
|
0dd41fc7e9 | ||
|
|
ff7a30dcc3 | ||
|
|
c40f38097a | ||
|
|
7439040147 | ||
|
|
2fa27e8f62 | ||
|
|
b5ad2f6870 | ||
|
|
ac082ca846 | ||
|
|
fb88f37b37 | ||
|
|
0e29658664 | ||
|
|
4d5a43ea1f | ||
|
|
396973b987 | ||
|
|
82d6648119 | ||
|
|
b3dd4516ca | ||
|
|
7956ec3b73 | ||
|
|
9b7eaebd40 | ||
|
|
307161a8f1 | ||
|
|
ee5bd0094b | ||
|
|
71f4246ac1 | ||
|
|
d4b515b7a3 | ||
|
|
162b6b914c | ||
|
|
a824bba23f | ||
|
|
42ceb96cc2 | ||
|
|
1e926005c7 | ||
|
|
1252ba40b3 | ||
|
|
5419b27a12 | ||
|
|
28324e7a6a | ||
|
|
13b94d151b | ||
|
|
4e18d198a0 | ||
|
|
6e602970fb | ||
|
|
4b36717630 | ||
|
|
53e6f6dc0e | ||
|
|
0afb9ae113 | ||
|
|
b907c67ee3 | ||
|
|
fb701e8307 | ||
|
|
1097908882 | ||
|
|
5c26aaa9cd | ||
|
|
d0f1f2ce77 | ||
|
|
a9d2be775b | ||
|
|
b7665abf68 | ||
|
|
d4d325a401 | ||
|
|
06534bb5d8 | ||
|
|
a5589dbe29 | ||
|
|
4706d2527c | ||
|
|
b5a76a4373 | ||
|
|
36931e7c45 | ||
|
|
013e390428 | ||
|
|
91821901e3 | ||
|
|
6e3524f9b2 | ||
|
|
26acf4dab4 | ||
|
|
d99b842ae1 | ||
|
|
84f0c45cbd | ||
|
|
ee59ad5e4b | ||
|
|
82ad2242dd | ||
|
|
dd1363de6c | ||
|
|
92d4922077 | ||
|
|
b8acc8614c | ||
|
|
48bac96c71 | ||
|
|
9b4ac4738a | ||
|
|
8a2eac8bcb | ||
|
|
de40629094 | ||
|
|
3cfc4c484f | ||
|
|
a900f73f7b | ||
|
|
18253c467c | ||
|
|
71c221981e | ||
|
|
fae03328f6 | ||
|
|
a113a428e7 | ||
|
|
d4e020eb4a | ||
|
|
53c65c6129 | ||
|
|
b60e3ef4c9 | ||
|
|
7f71efd5f8 | ||
|
|
fc04dc77c4 | ||
|
|
c960673de4 | ||
|
|
7d08925ea2 | ||
|
|
688139cd38 | ||
|
|
ab40c02b56 | ||
|
|
02847c74bd | ||
|
|
d12def7baa | ||
|
|
ed52e6a955 | ||
|
|
eaa474e76f | ||
|
|
d8e0be874b | ||
|
|
296de10571 | ||
|
|
9ae0ab294c | ||
|
|
760fc8d0fb | ||
|
|
62020a3ff9 | ||
|
|
e7c51aabd3 | ||
|
|
e83996b402 | ||
|
|
64a4ad5029 | ||
|
|
7e051d5e71 | ||
|
|
0d82880ea7 | ||
|
|
fe18f994ac | ||
|
|
a5e7b94da1 | ||
|
|
77e19fa5bd | ||
|
|
8ad64e5e6f | ||
|
|
8b3a17d629 | ||
|
|
2666ed3f5e | ||
|
|
68e9f4bcea | ||
|
|
ecb2c4ff47 | ||
|
|
37688e1874 | ||
|
|
adcde3a65c | ||
|
|
1f7c1e4188 | ||
|
|
35c9ccdd6a | ||
|
|
b784780428 | ||
|
|
6ebb680c92 | ||
|
|
ceab323916 | ||
|
|
92b49f78a9 | ||
|
|
8e7e68eddc | ||
|
|
1c21555767 | ||
|
|
2f6d618048 | ||
|
|
f9b806ede5 | ||
|
|
8894572174 | ||
|
|
2c924a3a82 | ||
|
|
640ef58553 | ||
|
|
897e0debca | ||
|
|
233736a20b | ||
|
|
e3c08593b9 | ||
|
|
f6315ba4c0 | ||
|
|
1bb3e5de37 | ||
|
|
54a29b5cae | ||
|
|
2f9f2c9ba6 | ||
|
|
146338c9f4 | ||
|
|
b3e398c530 | ||
|
|
2c5df301d8 | ||
|
|
a0aef05b2d | ||
|
|
d958e1cc70 | ||
|
|
9a8539fa42 | ||
|
|
5386d44fdb | ||
|
|
019692fd2f | ||
|
|
448313b1e3 | ||
|
|
b1605cc58b | ||
|
|
8383b227aa | ||
|
|
cd41697ee6 | ||
|
|
4e99b44823 | ||
|
|
54802ed856 | ||
|
|
572b62aa9a | ||
|
|
b74ca53ac8 | ||
|
|
74e9cc94e6 | ||
|
|
8edf8737ce | ||
|
|
b6460c11f7 | ||
|
|
d75e691795 | ||
|
|
b68e348ff3 | ||
|
|
54ad9ec2f2 | ||
|
|
9283a55364 | ||
|
|
35c1517709 | ||
|
|
7b9bde123b | ||
|
|
7b780bc7e9 | ||
|
|
84da42c262 | ||
|
|
1bcd425849 | ||
|
|
aafa9526f6 | ||
|
|
16565fcd46 | ||
|
|
f288d953fc | ||
|
|
f1fb3f1eac | ||
|
|
70da9cc638 | ||
|
|
c63290e6d3 | ||
|
|
57c311f850 | ||
|
|
0963967939 | ||
|
|
7d21516f6d | ||
|
|
ba71ad7407 | ||
|
|
8af8c603c1 | ||
|
|
d461c41d8b | ||
|
|
edb2538220 | ||
|
|
5639b5632a | ||
|
|
c72fdf3586 | ||
|
|
a690477b73 | ||
|
|
3638622c48 | ||
|
|
7fc7fba697 | ||
|
|
e7a4b3ecdd | ||
|
|
5977ffcc1c | ||
|
|
16f6a0f35c | ||
|
|
3845f8cfae | ||
|
|
9546e55cb0 | ||
|
|
5407e23d31 | ||
|
|
99240a2f4e | ||
|
|
d7f677c8fc | ||
|
|
1d0a304d2b | ||
|
|
bf6e8886b1 | ||
|
|
cadd94c233 | ||
|
|
a99c3e1b70 | ||
|
|
214e7d2013 | ||
|
|
219ad5be01 | ||
|
|
199ad09185 | ||
|
|
e60d535242 | ||
|
|
f3532e6ea0 | ||
|
|
cba3f77906 | ||
|
|
91e2df3ead | ||
|
|
fd4431246c | ||
|
|
2f12cd8f3d | ||
|
|
3ef91d8b7f | ||
|
|
558eef792f | ||
|
|
269e062609 | ||
|
|
2eb72114d7 | ||
|
|
a0d5c25c29 | ||
|
|
934ba440b3 | ||
|
|
aff9806ab1 | ||
|
|
0cd515679f | ||
|
|
5a657785d7 | ||
|
|
39274d3e6b | ||
|
|
d92691bc5c | ||
|
|
83a2620015 | ||
|
|
3dd455bfb7 | ||
|
|
5389bcc825 | ||
|
|
49ccecbadd | ||
|
|
64619d85e9 | ||
|
|
1e5cbed254 | ||
|
|
0e6f38381b | ||
|
|
cad7cb1c8f | ||
|
|
696ce887a8 | ||
|
|
0a496aca76 | ||
|
|
68403c866b | ||
|
|
5669e07252 | ||
|
|
07524ad00c | ||
|
|
2f261b6b70 | ||
|
|
ff9a7fba69 | ||
|
|
d43c68bef4 | ||
|
|
5dbf3590f8 | ||
|
|
6ff0a5d759 | ||
|
|
2ee9debb66 | ||
|
|
9aab0af1dc | ||
|
|
820161ba29 | ||
|
|
0024ed54c8 | ||
|
|
f08efcdab7 | ||
|
|
3b8e3b6c6b | ||
|
|
c1f6d64ac3 | ||
|
|
a74d2aae7a | ||
|
|
113cdbafe9 | ||
|
|
c9fede2aab | ||
|
|
f640d8852b | ||
|
|
8f10d86cad | ||
|
|
02ef55f9f1 | ||
|
|
6cd6408bef | ||
|
|
7ec71d65be | ||
|
|
8ad2ece8b9 | ||
|
|
7cc63926d4 | ||
|
|
6184b06d12 | ||
|
|
559a195669 | ||
|
|
95d711ece7 | ||
|
|
74a1520382 | ||
|
|
31ba0ec52d | ||
|
|
10f70c8dd6 | ||
|
|
452a89bfa2 | ||
|
|
5b7630b318 | ||
|
|
82b3aba854 | ||
|
|
0a9506cd21 | ||
|
|
10c918b93c | ||
|
|
2ac996218f | ||
|
|
429bcfc4e0 | ||
|
|
ae5cf1d723 | ||
|
|
4ba58ac1be | ||
|
|
cc918c5195 | ||
|
|
bc767cefac | ||
|
|
0aec6dfdb1 | ||
|
|
9469273c7a | ||
|
|
fe7a8d450c | ||
|
|
b45644af74 | ||
|
|
73d627554a | ||
|
|
b9773cd262 | ||
|
|
47ad860921 | ||
|
|
1c6c7e767f | ||
|
|
da70b1baed | ||
|
|
9072555814 | ||
|
|
b599554ba7 | ||
|
|
2b62b1965a | ||
|
|
ea55c74768 | ||
|
|
729624ab04 | ||
|
|
4fa43c7ba1 | ||
|
|
1f95f67a15 | ||
|
|
73fd21939f | ||
|
|
104a065aeb | ||
|
|
7b4e04703d | ||
|
|
a705ccfe5e | ||
|
|
84a8fd61b4 | ||
|
|
724a67f2ef | ||
|
|
d1e29e6773 | ||
|
|
f2ddbd2cc3 | ||
|
|
8a0fa46deb | ||
|
|
28cc64be4a | ||
|
|
4856da3bec | ||
|
|
08518e02e0 | ||
|
|
1e7f0d7c5f | ||
|
|
793661ea09 | ||
|
|
4c177d7823 | ||
|
|
e763cb138a | ||
|
|
6da693c5da | ||
|
|
d1de3a29b4 | ||
|
|
940991c75e | ||
|
|
c0d1bd3f92 | ||
|
|
92192b7949 | ||
|
|
9fda86a511 | ||
|
|
4114f00183 | ||
|
|
848327d8b3 | ||
|
|
44d38f9f84 | ||
|
|
fe7f71d986 | ||
|
|
05b7980cfe | ||
|
|
e2e34fb11b | ||
|
|
1935d3bace | ||
|
|
8767159cc9 | ||
|
|
198bd60565 | ||
|
|
f8b1745c68 | ||
|
|
30f43d7579 | ||
|
|
950914e15c | ||
|
|
bd4aed18c9 | ||
|
|
d47130f0c8 | ||
|
|
f530668711 | ||
|
|
67bb7c16cf | ||
|
|
c30a266c01 | ||
|
|
66b91c1de3 | ||
|
|
4c670a552e | ||
|
|
d5e46dff31 | ||
|
|
3695595826 | ||
|
|
303532483b | ||
|
|
ff92af1e62 | ||
|
|
49b2a10cc6 | ||
|
|
a3f7126dfe | ||
|
|
2faecc68c0 | ||
|
|
fe75297a29 | ||
|
|
60c6ffaabb | ||
|
|
408fe315ed | ||
|
|
5ec68ef608 | ||
|
|
c7f33f589e | ||
|
|
942d086905 | ||
|
|
8dbd87ae0d | ||
|
|
f04e813af3 | ||
|
|
a0accacb5d | ||
|
|
1b0bae7780 | ||
|
|
f7bb0c1dbd | ||
|
|
4c4dcf4423 | ||
|
|
7017ce8396 | ||
|
|
9f1a9df621 | ||
|
|
d7b57d460f | ||
|
|
6be5339fd3 | ||
|
|
82d933ad34 | ||
|
|
cae9627e06 | ||
|
|
5a6ceade6c | ||
|
|
e2870dbe4f | ||
|
|
d5471aceb6 | ||
|
|
e63a34a4a5 | ||
|
|
8be6183543 | ||
|
|
1ee5d21d4a | ||
|
|
26ba2199cb | ||
|
|
08d2b6f764 | ||
|
|
7ae49ee330 | ||
|
|
a609f2233b | ||
|
|
d3de373995 | ||
|
|
a5f364da03 | ||
|
|
499c9412bb | ||
|
|
c48a100f73 | ||
|
|
7e7c9d7300 | ||
|
|
0600c42775 | ||
|
|
4a47366ba0 | ||
|
|
a330042339 | ||
|
|
5e2cc2cc12 | ||
|
|
2a6bd9e415 | ||
|
|
1e3acd2a92 | ||
|
|
ab50f0f19b | ||
|
|
1283cc87dc | ||
|
|
c373354c0c | ||
|
|
d2aba705fb | ||
|
|
78815664cc | ||
|
|
e754bb25c6 | ||
|
|
4a3d15432e | ||
|
|
921d94d731 | ||
|
|
01b2bbc11c | ||
|
|
a45f53f9d9 | ||
|
|
3e44e0c9a9 | ||
|
|
63f0bc9e02 | ||
|
|
1c9b44394e | ||
|
|
84315daa1a | ||
|
|
337afd2919 | ||
|
|
126ed773cd | ||
|
|
38432ccacd | ||
|
|
0825a6bdc2 | ||
|
|
cd35f1ff62 | ||
|
|
0c95550af6 | ||
|
|
e1fe8054d0 | ||
|
|
29c675661f | ||
|
|
de917f103a | ||
|
|
95ff95e995 | ||
|
|
9fdf0c2ae1 | ||
|
|
3b2a395668 | ||
|
|
fec58dd217 | ||
|
|
148a25a452 | ||
|
|
e6dd002ca8 | ||
|
|
95acf7a4cb | ||
|
|
73a5809f62 | ||
|
|
627b6a1593 | ||
|
|
755bc6ac14 | ||
|
|
dafa14536f | ||
|
|
a4d337e891 | ||
|
|
44476789c2 | ||
|
|
458ae05564 | ||
|
|
169d2fe8e2 | ||
|
|
4615936f9e | ||
|
|
ebaf0d170f | ||
|
|
040fe14907 | ||
|
|
59013303ac | ||
|
|
4dab634abf | ||
|
|
32b6c3acbe | ||
|
|
91398d5fab | ||
|
|
b596aaf1f4 | ||
|
|
ec56120290 | ||
|
|
8ba160b0f6 | ||
|
|
6a6854ed84 | ||
|
|
8b49eabe95 | ||
|
|
a17f6468cd | ||
|
|
c62b1a5a9b | ||
|
|
2e4c01f604 | ||
|
|
3ab3076263 | ||
|
|
efc42e8d3f | ||
|
|
e49ecc880e | ||
|
|
cfd4e61a3b | ||
|
|
b56cf151fe | ||
|
|
87414585ea | ||
|
|
3b814866e2 | ||
|
|
55620a5d10 | ||
|
|
5a99c8390a | ||
|
|
1f7ac6897c | ||
|
|
24f1f6be33 | ||
|
|
6c589f0500 | ||
|
|
767bbcb251 | ||
|
|
c12da6b6d5 | ||
|
|
ab2b481a80 | ||
|
|
fb844bc989 | ||
|
|
098a368c79 | ||
|
|
1acbf48786 | ||
|
|
e120f6f318 | ||
|
|
a7b6dd5f24 | ||
|
|
5cd46d572e | ||
|
|
0031f1bcfd | ||
|
|
42998971cc | ||
|
|
35f8e3c3f6 | ||
|
|
98a8e67f9b | ||
|
|
6c53777f1b | ||
|
|
02a8da4fb8 | ||
|
|
29fd6f4a40 | ||
|
|
0f6be75620 | ||
|
|
78025d1e34 | ||
|
|
b75a10b9eb | ||
|
|
6aed1508af | ||
|
|
e9c050b659 | ||
|
|
3c9598a560 | ||
|
|
6bded5e832 | ||
|
|
e34b4c4d09 | ||
|
|
3662f30ea4 | ||
|
|
63ff503568 | ||
|
|
1070cbce87 | ||
|
|
a1d62522f3 | ||
|
|
cfd90b6779 | ||
|
|
b184c6f830 | ||
|
|
2aefa9efa0 | ||
|
|
5791198c51 | ||
|
|
a94daba3fc | ||
|
|
8e85e46ee9 | ||
|
|
118fe3d32e | ||
|
|
fb31f893ae | ||
|
|
d275226df9 | ||
|
|
a5279b5efd | ||
|
|
81007f629f | ||
|
|
060fe44e71 | ||
|
|
3c13f51017 | ||
|
|
ad9cdad927 | ||
|
|
31992dcb83 | ||
|
|
a5ecfbdd91 | ||
|
|
0929fb1c75 | ||
|
|
4515c85f91 | ||
|
|
230f562cb4 | ||
|
|
3758dc7dda | ||
|
|
464624f2a5 | ||
|
|
0be61b0a1b | ||
|
|
5faf36700b | ||
|
|
995df8e3e8 | ||
|
|
14189dc601 | ||
|
|
9c881ec53e | ||
|
|
581451c342 | ||
|
|
eb198736b8 | ||
|
|
e8f390f2ad | ||
|
|
2beb4982b0 | ||
|
|
46159d88bd | ||
|
|
fbff1ed4a7 | ||
|
|
6bd87113b4 | ||
|
|
7e3a82ed3e | ||
|
|
f9efe2755e | ||
|
|
a88beb7574 | ||
|
|
792aaf76da | ||
|
|
f11a6a6a8c | ||
|
|
6d926ee6e4 | ||
|
|
666d4be478 | ||
|
|
ce88a00b4b | ||
|
|
075a9d30f0 | ||
|
|
ec4e22b5ae | ||
|
|
56ca80e8fc | ||
|
|
ec144472ce | ||
|
|
991ced33f6 | ||
|
|
78357b53a4 | ||
|
|
16529c6704 | ||
|
|
1ead71442f | ||
|
|
a3f2e8ec9a | ||
|
|
a2b5f40ed1 | ||
|
|
d63a9db5a2 | ||
|
|
03a17c3a9d | ||
|
|
0f8823664c | ||
|
|
cdaa03a413 | ||
|
|
e25a940ad1 | ||
|
|
9332eb3bf8 | ||
|
|
84561a9d67 | ||
|
|
f1f722f1ce | ||
|
|
e5b82e0a45 | ||
|
|
6c5f477c31 | ||
|
|
20546acc4e | ||
|
|
87319c69d2 | ||
|
|
dc36435b35 | ||
|
|
ea9bf1ef0f | ||
|
|
adbaedef89 | ||
|
|
2fafef87df | ||
|
|
cd88e19648 | ||
|
|
a2f1c1347a | ||
|
|
e74055c1fd | ||
|
|
1acafd8a6c | ||
|
|
529cedfcbf | ||
|
|
affd1d12ae | ||
|
|
300bd89728 | ||
|
|
61fb31b62a | ||
|
|
58f1900b06 | ||
|
|
b6038bd7d7 | ||
|
|
07853bdc4d | ||
|
|
6289e92e54 | ||
|
|
0a1023aa83 | ||
|
|
bc6417c923 | ||
|
|
b201737149 | ||
|
|
c93911016f | ||
|
|
2e92357adc | ||
|
|
8223f462c6 | ||
|
|
b9b8bfc430 | ||
|
|
f9df3c5872 | ||
|
|
9881e0488f | ||
|
|
5a4342c0af | ||
|
|
c244d7628d | ||
|
|
ab830bb6ee | ||
|
|
827008a96a | ||
|
|
340e65df0b | ||
|
|
83cc6f1b0c | ||
|
|
35a44574a0 | ||
|
|
7a21857ea7 | ||
|
|
94afae2729 | ||
|
|
d8e703275f | ||
|
|
08dc12e8d7 | ||
|
|
31d43b6608 | ||
|
|
ab9396af61 | ||
|
|
30ca6769e4 | ||
|
|
22f6f4b2f1 | ||
|
|
b19f2dfbed | ||
|
|
82f3cd9c5f | ||
|
|
567308934e | ||
|
|
4d1add5221 | ||
|
|
c619c72094 | ||
|
|
e2bb4fb830 | ||
|
|
5c0176f35b | ||
|
|
095dbe1a7f | ||
|
|
230317551b | ||
|
|
a48ce5ccff | ||
|
|
10cf965be2 | ||
|
|
39c058cd29 | ||
|
|
2815a5e84a | ||
|
|
08dc4540f8 | ||
|
|
bcb0668ace | ||
|
|
0b36b7c7e8 | ||
|
|
2421e607a9 | ||
|
|
403f0626b4 | ||
|
|
1bb0b13d77 | ||
|
|
1787a69edb | ||
|
|
04b9590d59 | ||
|
|
c36832d71c | ||
|
|
eff711b9ca | ||
|
|
340f618060 | ||
|
|
58c246cedc | ||
|
|
e27f142ec8 | ||
|
|
6d760cb5e1 | ||
|
|
85f02d8ceb | ||
|
|
fe87380d83 | ||
|
|
20c41fa3b1 | ||
|
|
34d4ba6f64 | ||
|
|
bdb5c533f2 | ||
|
|
07bcea1226 | ||
|
|
f645a4345f | ||
|
|
1c0c594abe | ||
|
|
c77b9628b4 | ||
|
|
a3750ea79a | ||
|
|
4cd362dc33 | ||
|
|
812892f3f2 | ||
|
|
2e6924ec43 | ||
|
|
56a871b86b | ||
|
|
8354043337 | ||
|
|
410d893de9 | ||
|
|
406dd19285 | ||
|
|
586ed8d70b | ||
|
|
da8539820e | ||
|
|
267bc4ec79 | ||
|
|
fb8639969c | ||
|
|
5fdbc12524 | ||
|
|
18651bbf7a | ||
|
|
bcaf0737e9 | ||
|
|
ad7f5f5970 | ||
|
|
652286760b | ||
|
|
df0dde80ef | ||
|
|
03f1a6930c | ||
|
|
e20a8ba396 | ||
|
|
73dd788fa1 | ||
|
|
ebb623f080 | ||
|
|
1dde7e3e99 | ||
|
|
fc74698dac | ||
|
|
c554bdc68c | ||
|
|
4a8ac4a309 | ||
|
|
042cabbe5d | ||
|
|
1e1204a991 | ||
|
|
6c42a2d40e | ||
|
|
a85c56a25a | ||
|
|
ac51ffc7d4 | ||
|
|
c648e5fbba | ||
|
|
6fd88a8570 | ||
|
|
bab0c99d13 | ||
|
|
79ef648a27 | ||
|
|
0f55a2f87a | ||
|
|
87e9cbc388 | ||
|
|
821002ce43 | ||
|
|
dab7195408 | ||
|
|
349816dab7 | ||
|
|
46968556bb | ||
|
|
e09a328281 | ||
|
|
8c757955b5 | ||
|
|
e7d20a403a | ||
|
|
bafa21d11c | ||
|
|
07fc7d0437 | ||
|
|
cc1f75b1b3 | ||
|
|
4a7446e57b | ||
|
|
fc0fa1c58c | ||
|
|
bb4f5a5037 | ||
|
|
09eb303bab | ||
|
|
4708b2c25d | ||
|
|
e514a8c3e1 | ||
|
|
aefbbd5738 | ||
|
|
ab881c9b5a | ||
|
|
e54ebd096c | ||
|
|
6054ccfdf2 | ||
|
|
2fda6d11e1 | ||
|
|
34c25a065a | ||
|
|
89ceb01b59 | ||
|
|
65c1b53ea0 | ||
|
|
522b2623be | ||
|
|
d2bf83e4ac | ||
|
|
30c3a047d1 | ||
|
|
2b6c18dbcd | ||
|
|
7b486bb28c | ||
|
|
10b61f0e30 | ||
|
|
1b35810766 | ||
|
|
fc0160213e | ||
|
|
a039f102a3 | ||
|
|
41efefa21e | ||
|
|
cc8ee097a3 | ||
|
|
1bacb31949 | ||
|
|
be75247dba | ||
|
|
6bc68fece8 | ||
|
|
be8250acb7 | ||
|
|
8372ffc0d7 | ||
|
|
a10187ed5d | ||
|
|
7fbd1ea920 | ||
|
|
ef4a0214ed | ||
|
|
d5ac23a8d2 | ||
|
|
7434865967 | ||
|
|
f29d3bf5f8 | ||
|
|
97baed0ef9 | ||
|
|
378f380968 | ||
|
|
8e506aa327 | ||
|
|
df96b7ab81 | ||
|
|
20cd7b04a5 | ||
|
|
fa16020d61 | ||
|
|
5ba4e0ee9d | ||
|
|
a27ee4944a | ||
|
|
f537ff007c | ||
|
|
c563fc7d42 | ||
|
|
9d0f137f9d | ||
|
|
bcc823e900 | ||
|
|
23b2ade6bd | ||
|
|
9bebf50d4d | ||
|
|
6b98322d96 | ||
|
|
97faaea983 | ||
|
|
35c7964365 | ||
|
|
65f74077d3 | ||
|
|
d8cf526b5a | ||
|
|
5ce2c0eefd | ||
|
|
1a47d52ed9 | ||
|
|
383e4f8abd | ||
|
|
9698baefd0 | ||
|
|
c5f05694aa | ||
|
|
cda924ac74 | ||
|
|
f719697852 | ||
|
|
df61c35314 | ||
|
|
a3f80ef2f8 | ||
|
|
e6f05a7815 | ||
|
|
1ce6d3721e | ||
|
|
07be3dd0d4 | ||
|
|
f5fe7e6cc8 | ||
|
|
6d9fa9eecd | ||
|
|
313be585ae | ||
|
|
8a725298de | ||
|
|
721402b710 | ||
|
|
73e6822a1d | ||
|
|
9f7c4cb217 | ||
|
|
855b572656 | ||
|
|
93e388e04f | ||
|
|
146b929b5d | ||
|
|
5f38814fd2 | ||
|
|
45a364c44b | ||
|
|
d35afdf81c | ||
|
|
5f7eb335e6 | ||
|
|
9173226be7 | ||
|
|
5d8da8aab6 | ||
|
|
df00c13899 | ||
|
|
d1567322ec | ||
|
|
eb42d9e3f0 | ||
|
|
79eb41298c | ||
|
|
e0f48c9f32 | ||
|
|
f033e4eb36 | ||
|
|
8751216f62 | ||
|
|
cfeb59ee8f | ||
|
|
3c340aee40 | ||
|
|
2b2c5efd1a | ||
|
|
985224f24b | ||
|
|
97f26743e5 | ||
|
|
a3bf159281 | ||
|
|
543427255f | ||
|
|
8eba26fd53 | ||
|
|
17b6b7f7b9 | ||
|
|
0997d48d60 | ||
|
|
6e6bd92d5e | ||
|
|
a6e0fdb6b9 | ||
|
|
7d27d76448 | ||
|
|
418c4514df | ||
|
|
bd675c09a1 | ||
|
|
bacaa0127a | ||
|
|
76b1a394f2 | ||
|
|
984bcd5f06 | ||
|
|
7ba5d1de3b | ||
|
|
16cca5a719 | ||
|
|
9d5c7bfc53 | ||
|
|
62c25eec2e | ||
|
|
bc3126ebee | ||
|
|
d6f56169e1 | ||
|
|
c0d9e3247b | ||
|
|
0a1a783054 | ||
|
|
dc9a0145e2 | ||
|
|
9f532fb543 | ||
|
|
b719435ae8 | ||
|
|
16816d47d6 | ||
|
|
a693a995b1 | ||
|
|
f8a287675b | ||
|
|
e462098cce | ||
|
|
3d2e45b5d5 | ||
|
|
a49faeced6 | ||
|
|
401ebc586e | ||
|
|
cccd3a47f0 | ||
|
|
96912515a8 | ||
|
|
04785a8b49 | ||
|
|
2b129380d6 | ||
|
|
a6e698b0fe | ||
|
|
33d7d730f4 | ||
|
|
5607fab8db | ||
|
|
c2ae9abfb5 | ||
|
|
a8cb498eb5 | ||
|
|
d0c1b94585 | ||
|
|
e17f6c0066 | ||
|
|
a550567a4c | ||
|
|
3fabf34bee | ||
|
|
0d02be6387 | ||
|
|
fff3adf967 | ||
|
|
4b41291830 | ||
|
|
8dd8eabf1a | ||
|
|
1591ed49da | ||
|
|
a069a812db | ||
|
|
3416a74723 | ||
|
|
58afb97eb2 | ||
|
|
738a78d12b | ||
|
|
545c45e78d | ||
|
|
0a3c2433e7 | ||
|
|
df7627c08a | ||
|
|
b089b49b28 | ||
|
|
7547163d2d | ||
|
|
95f61629a9 | ||
|
|
3227ffab81 | ||
|
|
1ecc42d50c | ||
|
|
712751e89b | ||
|
|
b6d87d10c4 | ||
|
|
59e5759bc2 | ||
|
|
ee256284cc | ||
|
|
f3934ebd2c | ||
|
|
22a43eb9af | ||
|
|
ba92225678 | ||
|
|
496451c434 | ||
|
|
9d52f40632 | ||
|
|
c55cac97d0 | ||
|
|
8d09acdf5f | ||
|
|
fcf02fc8bf | ||
|
|
721d344533 | ||
|
|
9dc53f9755 | ||
|
|
aa72a8cd5a | ||
|
|
099a9018df | ||
|
|
34b07ef340 | ||
|
|
3907660dde | ||
|
|
3d1b450cbb | ||
|
|
93ccaff407 | ||
|
|
a2d17fd0b9 | ||
|
|
9fa80d2061 | ||
|
|
5ef9f4e8ac | ||
|
|
bcd639599a | ||
|
|
1b8ac876ce | ||
|
|
420a85943a | ||
|
|
00bee2edcb | ||
|
|
41383bf7a4 | ||
|
|
3bb0c6a8d2 | ||
|
|
0f61ef63a2 | ||
|
|
6ebb432932 | ||
|
|
b08c49e788 | ||
|
|
1b6fa1bd36 | ||
|
|
dc6d77e266 | ||
|
|
4f5ffa2370 | ||
|
|
860a1a1bb0 | ||
|
|
daa6afd14c | ||
|
|
28754ec260 | ||
|
|
ab0208b603 | ||
|
|
358dfd4cb7 | ||
|
|
6d2d5ca0ed | ||
|
|
e71c54f041 | ||
|
|
f9c3a301b5 | ||
|
|
2c162630f4 | ||
|
|
8015e49bee | ||
|
|
3f97845c9c | ||
|
|
4946cdeed3 | ||
|
|
eff3798987 | ||
|
|
554deb22da | ||
|
|
0249b0e933 | ||
|
|
2f59fb197b | ||
|
|
38df31e99f | ||
|
|
a6cbfbf065 | ||
|
|
28b210586c | ||
|
|
33073c75ee | ||
|
|
23b2ea7195 | ||
|
|
80beeb7ffb | ||
|
|
d2b5bedfa1 | ||
|
|
d5cec9f5de | ||
|
|
05deea3cd8 | ||
|
|
7632278ba8 | ||
|
|
faf3971044 | ||
|
|
8e4e998e74 | ||
|
|
995882d2d1 | ||
|
|
c8b896bdd6 | ||
|
|
201e631a0b | ||
|
|
a3d1990857 | ||
|
|
ba79f754dc | ||
|
|
61a4373459 | ||
|
|
924b32b3c5 | ||
|
|
664798ee6e | ||
|
|
2dd39ad0cb | ||
|
|
90bd78846a | ||
|
|
31db3d9562 | ||
|
|
52d91d350b | ||
|
|
432ff65cc2 | ||
|
|
037140b980 | ||
|
|
8cd05c7314 | ||
|
|
ec0e841bb8 | ||
|
|
613a18f60c | ||
|
|
d6fd54cec4 | ||
|
|
4e47518a3f | ||
|
|
47f773ab7c | ||
|
|
5a8f176860 | ||
|
|
8cfb10ef10 | ||
|
|
95671f9d9a | ||
|
|
427af43904 | ||
|
|
4944ad5882 | ||
|
|
59f9824cc2 | ||
|
|
71f0b644f2 | ||
|
|
b60b54327b | ||
|
|
0f2da43737 | ||
|
|
558bd42447 | ||
|
|
7107bfe3e6 | ||
|
|
be150c1c52 | ||
|
|
9f4cb1a13e | ||
|
|
0addad590e | ||
|
|
793e48150a | ||
|
|
3ba4bc2d08 | ||
|
|
43faf85eb4 | ||
|
|
ad3febd87e | ||
|
|
3e4d172765 | ||
|
|
607ec01feb | ||
|
|
dc14a309a7 | ||
|
|
fdc56b938e | ||
|
|
4b62714ef5 | ||
|
|
2763aec6c2 | ||
|
|
73b874ec0b | ||
|
|
124b521308 | ||
|
|
e09d4e2d3b | ||
|
|
0897263fc9 | ||
|
|
570f2c7e30 | ||
|
|
b573d3f0f7 | ||
|
|
862c5f21d4 | ||
|
|
1305dee081 | ||
|
|
84497f422d | ||
|
|
ccd7557c75 | ||
|
|
1116eff816 | ||
|
|
55ab08129a | ||
|
|
c94705593f | ||
|
|
4f0f82f6b4 | ||
|
|
b76e45064f | ||
|
|
97653f03be | ||
|
|
96f3100f77 | ||
|
|
06501c8a70 | ||
|
|
dc93db9276 | ||
|
|
d6e678883c | ||
|
|
3c424474ee | ||
|
|
631736b202 | ||
|
|
495ef0dd6a | ||
|
|
2a379d8735 | ||
|
|
6fcc55ce60 | ||
|
|
a36f85aae3 | ||
|
|
ac5cb637e7 | ||
|
|
185ef5eb63 | ||
|
|
46b4e50a23 | ||
|
|
e593233b8f | ||
|
|
852ff762c5 | ||
|
|
c12b0c161f | ||
|
|
84fb080d13 | ||
|
|
81e5d14e4f | ||
|
|
ad1b77f79e | ||
|
|
6cbf7247ce | ||
|
|
d5700d94e6 | ||
|
|
e9f287e2d7 | ||
|
|
79f9f72ef4 | ||
|
|
a70b419c34 | ||
|
|
3cdd33f42f | ||
|
|
2f0cbf83e9 | ||
|
|
f2aaf65674 | ||
|
|
5681a5a231 | ||
|
|
aab3de29e1 | ||
|
|
08d84337e7 | ||
|
|
9b18ffb05c | ||
|
|
dcdd9333d4 | ||
|
|
7bb363d3b2 | ||
|
|
c8127c1b36 | ||
|
|
57dc7396ee | ||
|
|
c781e82c37 | ||
|
|
ea1fbf021d | ||
|
|
a754743014 | ||
|
|
c95d857483 | ||
|
|
8ea346ca4a | ||
|
|
1b3f90d73f | ||
|
|
6687485e4c | ||
|
|
79abef21a5 | ||
|
|
3fe1a8e79f | ||
|
|
076125e0cf | ||
|
|
0d8479b206 | ||
|
|
cb2930f0e9 | ||
|
|
2574e91634 | ||
|
|
17cac581b8 | ||
|
|
b6bc3810bd | ||
|
|
15cb93ed43 | ||
|
|
bc09ec8a6a | ||
|
|
1354fa8a4a | ||
|
|
9d8d6f33ef | ||
|
|
15601fc3c9 | ||
|
|
eb3ad6b5a3 | ||
|
|
2434455d41 | ||
|
|
62fe37be9f | ||
|
|
f2957e35d5 | ||
|
|
ba08d0c131 | ||
|
|
65a6201121 | ||
|
|
9fba1e9799 | ||
|
|
8656108e81 | ||
|
|
63b5109113 | ||
|
|
264b08a731 | ||
|
|
0c686c1339 | ||
|
|
27007184aa | ||
|
|
7e2f448ae1 | ||
|
|
90a9159748 | ||
|
|
e0e6d1fd3e | ||
|
|
123fcdde1f | ||
|
|
15956ab222 | ||
|
|
c6d95c42a8 | ||
|
|
fe7497ab92 | ||
|
|
030b3c34d2 | ||
|
|
ca3fe4070a | ||
|
|
bef7aab7f6 | ||
|
|
d4bcc96f2f | ||
|
|
b5003f8fb8 |
@@ -47,7 +47,7 @@ AlignAfterOpenBracket: true
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: true
|
||||
BinPackParameters: true
|
||||
ColumnLimit: 0
|
||||
ColumnLimit: 100
|
||||
Cpp11BracedListStyle: false
|
||||
DerivePointerBinding: false
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
|
||||
@@ -49,7 +49,7 @@ with section("format"):
|
||||
|
||||
# If a positional argument group contains more than this many arguments, then
|
||||
# force it to a vertical layout.
|
||||
max_pargs_hwrap = 4
|
||||
max_pargs_hwrap = 6
|
||||
|
||||
# If a cmdline positional group consumes more than this many lines without
|
||||
# nesting, then invalidate the layout (and nest)
|
||||
@@ -94,8 +94,7 @@ with section("format"):
|
||||
keyword_case = 'upper'
|
||||
|
||||
# A list of command names which should always be wrapped
|
||||
always_wrap = ["add_executable", "add_library",
|
||||
"target_link_libraries", "target_include_directories", "install"]
|
||||
always_wrap = []
|
||||
|
||||
# If true, the argument lists which are known to be sortable will be sorted
|
||||
# lexicographicall
|
||||
@@ -103,7 +102,7 @@ with section("format"):
|
||||
|
||||
# If true, the parsers may infer whether or not an argument list is sortable
|
||||
# (without annotation).
|
||||
autosort = True
|
||||
autosort = False
|
||||
|
||||
# By default, if cmake-format cannot successfully fit everything into the
|
||||
# desired linewidth it will apply the last, most agressive attempt that it
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[codespell]
|
||||
skip = ./build-*,.git,*.svg,rc_assets.py
|
||||
skip = ./build-*,.git,*.svg,rc_assets.py,./src/flutter/generated*
|
||||
interactive = 3
|
||||
ignore-words-list = overlay,overlayed
|
||||
ignore-words-list = overlay,overlayed,seh,sharable
|
||||
|
||||
7
.gitignore
vendored
7
.gitignore
vendored
@@ -67,3 +67,10 @@ kddockwidgets_minimal_example
|
||||
.vscode
|
||||
/.cache
|
||||
/compile_commands.json
|
||||
/site
|
||||
.DS_Store
|
||||
.packages
|
||||
pubspec.lock
|
||||
.dart_tool
|
||||
mjb_rejected_*
|
||||
mjb_rejected_classes.log
|
||||
|
||||
3
.krazy
3
.krazy
@@ -16,9 +16,6 @@ EXCLUDE style
|
||||
SKIP /fwd_headers/
|
||||
SKIP Doxyfile.cmake
|
||||
|
||||
#skip some example files
|
||||
SKIP /examples/qtquick/CMakeFiles/
|
||||
|
||||
#skip CMake files
|
||||
SKIP /KDDockWidgetsConfig.cmake.in
|
||||
#skip more files
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
# See https://pre-commit.com for more information
|
||||
# See https://pre-commit.com/hooks.html for more hooks
|
||||
exclude: ^(cmake/ECM|cmake/KDAB/)
|
||||
exclude: ^(cmake/ECM|cmake/KDAB/|src/3rdparty/)
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.3.0
|
||||
rev: v3.2.0
|
||||
hooks:
|
||||
- id: trailing-whitespace
|
||||
- id: end-of-file-fixer
|
||||
@@ -13,22 +13,22 @@ repos:
|
||||
args: [--allow-multiple-documents]
|
||||
- id: check-json
|
||||
- repo: https://github.com/pre-commit/mirrors-clang-format
|
||||
rev: v14.0.0
|
||||
rev: v14.0.6
|
||||
hooks:
|
||||
- id: clang-format
|
||||
exclude: (.json)
|
||||
- repo: https://github.com/PyCQA/pylint
|
||||
rev: v2.15.2
|
||||
rev: v2.15.3
|
||||
hooks:
|
||||
- id: pylint
|
||||
exclude: ^(.cmake-format.py|conan/conanfile.py)
|
||||
additional_dependencies: ["PySide2", "PySide6"]
|
||||
- repo: https://github.com/pre-commit/mirrors-autopep8
|
||||
rev: v1.7.0
|
||||
rev: v1.6.0
|
||||
hooks:
|
||||
- id: autopep8
|
||||
- repo: https://github.com/codespell-project/codespell
|
||||
rev: v2.2.1
|
||||
rev: v2.1.0
|
||||
hooks:
|
||||
- id: codespell
|
||||
- repo: https://github.com/cheshirekow/cmake-format-precommit
|
||||
|
||||
@@ -140,8 +140,6 @@ disable=print-statement,
|
||||
exception-escape,
|
||||
comprehension-escape,
|
||||
consider-using-f-string,
|
||||
useless-option-value,
|
||||
unknown-option-value,
|
||||
R0801,I1101,E0401
|
||||
|
||||
# Enable the message, report, category or checker with the given id(s). You can
|
||||
|
||||
13
.reuse/dep5
13
.reuse/dep5
@@ -9,12 +9,12 @@ Copyright: 2019-2022 Klarälvdalens Datakonsult AB, a KDAB Group company <info@k
|
||||
License: GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#misc documentation
|
||||
Files: CONTRIBUTORS.txt Changelog README.md README-QtQuick.md README-WASM.md README-Wayland.md README-bindings.md README-troubleshooting conan/README.txt python/examples/README.txt python/examples-qt6/README.txt docs/KDDockWidgets-CopyrightAssignmentForm.pdf *.html
|
||||
Files: CONTRIBUTORS.txt Changelog README.md README-QtQuick.md README-WASM.md README-Wayland.md README-bindings.md README-troubleshooting conan/README.txt python/examples/README.txt python/examples-qt6/README.txt docs_devel/*.md docs/KDDockWidgets-CopyrightAssignmentForm.pdf *.html
|
||||
Copyright: 2019-2022 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
|
||||
License: GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
#misc config files
|
||||
Files: .pre-commit-config.yaml .codespellrc .krazy .cmake-format .clang-format .clazy .gitignore .mdlrc .mdlrc.rb .pep8 .pylintrc appveyor.yml code.dev-*.code-workspace docs/api/Doxyfile.cmake distro/*
|
||||
Files: .pre-commit-config.yaml .codespellrc .krazy .cmake-format .clang-format .clazy .gitignore .mdlrc .mdlrc.rb .pep8 .pylintrc appveyor.yml mkdocs.yml code.dev-*.code-workspace code.dev*.code-workspace docs/api/Doxyfile.cmake distro/* *.yaml
|
||||
Copyright: 2019-2022 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
|
||||
License: BSD-3-Clause
|
||||
|
||||
@@ -27,3 +27,12 @@ License: GPL-2.0-only OR GPL-3.0-only
|
||||
Files: cmake/ECM/modules/*
|
||||
Copyright: The KDE Project
|
||||
License: BSD-3-Clause
|
||||
|
||||
#3rdparty C++
|
||||
Files: src/3rdparty/kdbindings/genindex_array.h
|
||||
Copyright: 2021 Jeremy Burns
|
||||
License: MIT
|
||||
|
||||
Files: src/3rdparty/doctest/doctest.h
|
||||
Copyright: 2016-2021 Viktor Kirilov <vik.kirilov@gmail.com>
|
||||
License: MIT
|
||||
|
||||
364
CMakeLists.txt
364
CMakeLists.txt
@@ -11,63 +11,48 @@
|
||||
|
||||
# Pass the following variables to cmake to control the build:
|
||||
#
|
||||
# -DKDDockWidgets_QT6=[true|false]
|
||||
# Build against Qt6 rather than Qt5
|
||||
# Default=false (Qt5 will be used even if Qt6 is available)
|
||||
# -DKDDockWidgets_QT6=[true|false] Build against Qt6 rather than Qt5
|
||||
# Default=false (Qt5 will be used even if Qt6 is available)
|
||||
#
|
||||
# -DKDDockWidgets_STATIC=[true|false]
|
||||
# Build static versions of the libraries
|
||||
# Default=false
|
||||
# -DKDDockWidgets_STATIC=[true|false] Build static versions of the libraries
|
||||
# Default=false
|
||||
#
|
||||
# -DKDDockWidgets_TESTS=[true|false]
|
||||
# Build the test harness.
|
||||
# Currently ignored (except for Python bindings) unless KDDockWidgets_DEVELOPER_MODE=True.
|
||||
# Default=false
|
||||
# -DKDDockWidgets_TESTS=[true|false] Build the test harness. Currently ignored
|
||||
# (except for Python bindings) unless KDDockWidgets_DEVELOPER_MODE=True.
|
||||
# Default=false
|
||||
#
|
||||
# -DKDDockWidgets_EXAMPLES=[true|false]
|
||||
# Build the examples.
|
||||
# Default=true
|
||||
# -DKDDockWidgets_EXAMPLES=[true|false] Build the examples. Default=true
|
||||
#
|
||||
# -DKDDockWidgets_DOCS=[true|false]
|
||||
# Build the API documentation. Enables the 'docs' build target.
|
||||
# Default=false
|
||||
# -DKDDockWidgets_DOCS=[true|false] Build the API documentation. Enables the
|
||||
# 'docs' build target. Default=false
|
||||
#
|
||||
# -DKDDockWidgets_QTQUICK=[true|false]
|
||||
# Build for QtQuick instead of QtWidgets.
|
||||
# Default=false
|
||||
# -DKDDockWidgets_PYTHON_BINDINGS=[true|false] Build/Generate python bindings.
|
||||
# Always false for Debug builds (If your shiboken or pyside is installed in a
|
||||
# non-standard locations try passing the SHIBOKEN_CUSTOM_PREFIX and
|
||||
# PYSIDE_CUSTOM_PREFIX variables.) Default=false
|
||||
#
|
||||
# -DKDDockWidgets_PYTHON_BINDINGS=[true|false]
|
||||
# Build/Generate python bindings. Always false for Debug builds
|
||||
# (If your shiboken or pyside is installed in a non-standard locations
|
||||
# try passing the SHIBOKEN_CUSTOM_PREFIX and PYSIDE_CUSTOM_PREFIX variables.)
|
||||
# Default=false
|
||||
#
|
||||
# -DKDDockWidgets_PYTHON_BINDINGS_INSTALL_PREFIX=[path]
|
||||
# Set an alternative install path for Python bindings
|
||||
# Default=CMAKE_INSTALL_PREFIX
|
||||
# -DKDDockWidgets_PYTHON_BINDINGS_INSTALL_PREFIX=[path] Set an alternative
|
||||
# install path for Python bindings Default=CMAKE_INSTALL_PREFIX
|
||||
|
||||
# ## DO NOT USE IF YOU ARE AN END-USER. FOR THE DEVELOPERS ONLY!!
|
||||
## Special CMake Options for Developers
|
||||
# ## DO NOT USE IF YOU ARE AN END-USER. FOR THE DEVELOPERS ONLY!! # Special
|
||||
# CMake Options for Developers
|
||||
#
|
||||
# -DKDDockWidgets_DEVELOPER_MODE=[true|false]
|
||||
# Configure the build for a developer setup.
|
||||
# Enables some features that are not geared towards end-users.
|
||||
# Forces the test harness to be built.
|
||||
# Default=false
|
||||
# -DKDDockWidgets_DEVELOPER_MODE=[true|false] Configure the build for a
|
||||
# developer setup. Enables some features that are not geared towards end-users.
|
||||
# Forces the test harness to be built. Default=false
|
||||
#
|
||||
# -DKDDockWidgets_WERROR=[true|false]
|
||||
# Compile with the -Werror gcc/clang option (always true for developer-mode)
|
||||
# Default=false
|
||||
# -DKDDockWidgets_WERROR=[true|false] Compile with the -Werror gcc/clang option
|
||||
# (always true for developer-mode) Default=false
|
||||
#
|
||||
# -DKDDockWidgets_LINTER=[true|false]
|
||||
# Build the layout linter.
|
||||
# Ignored unless KDDockWidgets_DEVELOPER_MODE=True
|
||||
# Default=true
|
||||
# -DKDDockWidgets_LINTER=[true|false] Build the layout linter. Ignored unless
|
||||
# KDDockWidgets_DEVELOPER_MODE=True Default=true
|
||||
#
|
||||
# -DKDDockWidgets_FUZZER=[true|false]
|
||||
# Build the fuzzer.
|
||||
# Ignored unless KDDockWidgets_DEVELOPER_MODE=True
|
||||
# Default=true
|
||||
# -DKDDockWidgets_CODE_COVERAGE=[true|false] Enable coverage reporting. Ignored
|
||||
# unless KDDockWidgets_DEVELOPER_MODE=True Default=false
|
||||
#
|
||||
# -DKDDockWidgets_FRONTENDS='qtwidgets;qtquick' Semicolon separated list of
|
||||
# frontends to enable. If not specified, frontends will be enabled based on
|
||||
# availability of libraries on your system.
|
||||
|
||||
cmake_minimum_required(VERSION 3.12)
|
||||
|
||||
@@ -76,6 +61,7 @@ set(KDAB_INSTALL
|
||||
True
|
||||
CACHE INTERNAL "Install to default KDAB Location"
|
||||
)
|
||||
|
||||
if(DEFINED CMAKE_INSTALL_PREFIX)
|
||||
if(NOT "${CMAKE_INSTALL_PREFIX}" STREQUAL "")
|
||||
set(KDAB_INSTALL
|
||||
@@ -92,96 +78,170 @@ project(
|
||||
LANGUAGES CXX
|
||||
)
|
||||
|
||||
set(${PROJECT_NAME}_VERSION_MAJOR 1)
|
||||
set(${PROJECT_NAME}_VERSION_MINOR 6)
|
||||
set(${PROJECT_NAME}_VERSION_PATCH 95)
|
||||
set(${PROJECT_NAME}_VERSION
|
||||
${${PROJECT_NAME}_VERSION_MAJOR}.${${PROJECT_NAME}_VERSION_MINOR}.${${PROJECT_NAME}_VERSION_PATCH}
|
||||
)
|
||||
set(PROJECT_VERSION ${${PROJECT_NAME}_VERSION}) #PROJECT_VERSION is needed by some ECM modules
|
||||
set(${PROJECT_NAME}_SOVERSION "1.7")
|
||||
set(KDDockWidgets_VERSION_MAJOR 2)
|
||||
set(KDDockWidgets_VERSION_MINOR 0)
|
||||
set(KDDockWidgets_VERSION_PATCH 9)
|
||||
set(KDDockWidgets_VERSION ${KDDockWidgets_VERSION_MAJOR}.${KDDockWidgets_VERSION_MINOR}.${KDDockWidgets_VERSION_PATCH})
|
||||
set(PROJECT_VERSION ${KDDockWidgets_VERSION}) # PROJECT_VERSION is needed by some ECM modules
|
||||
set(KDDockWidgets_SOVERSION "2.0")
|
||||
|
||||
include(FeatureSummary)
|
||||
|
||||
option(${PROJECT_NAME}_QT6 "Build against Qt 6" OFF)
|
||||
option(${PROJECT_NAME}_DEVELOPER_MODE "Developer Mode" OFF)
|
||||
option(${PROJECT_NAME}_PYTHON_BINDINGS "Build python bindings" OFF)
|
||||
option(${PROJECT_NAME}_QTQUICK "Build for QtQuick instead of QtWidgets" OFF)
|
||||
option(${PROJECT_NAME}_STATIC "Build statically" OFF)
|
||||
option(${PROJECT_NAME}_TESTS "Build the tests" OFF)
|
||||
option(${PROJECT_NAME}_EXAMPLES "Build the examples" ON)
|
||||
option(${PROJECT_NAME}_DOCS "Build the API documentation" OFF)
|
||||
option(${PROJECT_NAME}_WERROR "Use -Werror (will be true for developer-mode unconditionally)" OFF)
|
||||
option(${PROJECT_NAME}_X11EXTRAS
|
||||
"Link with QtX11Extras to detect if the compositor supports transparency. Not applicable to non-Linux or Qt6."
|
||||
option(KDDockWidgets_QT6 "Build against Qt 6" OFF)
|
||||
option(KDDockWidgets_DEVELOPER_MODE "Developer Mode" OFF)
|
||||
option(KDDockWidgets_PYTHON_BINDINGS "Build python bindings" OFF)
|
||||
option(KDDockWidgets_STATIC "Build statically" OFF)
|
||||
option(KDDockWidgets_TESTS "Build the tests" OFF)
|
||||
option(KDDockWidgets_EXAMPLES "Build the examples" ON)
|
||||
option(KDDockWidgets_DOCS "Build the API documentation" OFF)
|
||||
option(KDDockWidgets_WERROR "Use -Werror (will be true for developer-mode unconditionally)" OFF)
|
||||
option(KDDockWidgets_X11EXTRAS
|
||||
"Link against QtX11Extras to detect if the compositor supports transparency. Not applicable on non-Linux or Qt6."
|
||||
ON
|
||||
)
|
||||
option(${PROJECT_NAME}_XLib "On Linux, link against XLib, for a more robust window z-order detection." OFF)
|
||||
option(KDDockWidgets_XLib "On Linux, link against XLib, for a more robust window z-order detection." OFF)
|
||||
option(KDDockWidgets_CODE_COVERAGE "Enable coverage reporting" OFF)
|
||||
option(KDDockWidgets_FRONTENDS "Semicolon separated list of frontends to enable" "")
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake/ECM/modules")
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake/KDAB/modules")
|
||||
|
||||
# Set a default build type if none was specified
|
||||
set(default_build_type "Release")
|
||||
if(EXISTS "${CMAKE_SOURCE_DIR}/.git" OR ${PROJECT_NAME}_DEVELOPER_MODE)
|
||||
if(EXISTS "${CMAKE_SOURCE_DIR}/.git" OR KDDockWidgets_DEVELOPER_MODE)
|
||||
set(default_build_type "Debug")
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||
message(STATUS "Setting build type to ${default_build_type} as none was specified.")
|
||||
set(CMAKE_BUILD_TYPE
|
||||
"${default_build_type}"
|
||||
CACHE STRING "Choose the type of build." FORCE
|
||||
)
|
||||
|
||||
# Set the possible values of build type for cmake-gui
|
||||
set_property(
|
||||
CACHE CMAKE_BUILD_TYPE
|
||||
PROPERTY STRINGS
|
||||
"Debug"
|
||||
"Release"
|
||||
"MinSizeRel"
|
||||
"RelWithDebInfo"
|
||||
)
|
||||
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
|
||||
endif()
|
||||
|
||||
if(${PROJECT_NAME}_XLib)
|
||||
if(KDDockWidgets_XLib)
|
||||
add_definitions(-DKDDockWidgets_XLIB)
|
||||
endif()
|
||||
|
||||
if(${PROJECT_NAME}_QT6)
|
||||
if(MSVC AND MSVC_TOOLSET_VERSION LESS 142)
|
||||
message(FATAL_ERROR "VS 2019 is the minimum required toolset")
|
||||
endif()
|
||||
|
||||
if(KDDockWidgets_QT6)
|
||||
set(Qt_VERSION_MAJOR 6)
|
||||
set(QT_MIN_VERSION "6.2.0")
|
||||
set(${PROJECT_NAME}_LIBRARY_QTID "-qt6")
|
||||
set(KDDockWidgets_LIBRARY_QTID "-qt6")
|
||||
else()
|
||||
set(Qt_VERSION_MAJOR 5)
|
||||
set(QT_MIN_VERSION "5.15")
|
||||
set(${PROJECT_NAME}_LIBRARY_QTID "")
|
||||
set(KDDockWidgets_LIBRARY_QTID "")
|
||||
endif()
|
||||
find_package(Qt${Qt_VERSION_MAJOR} ${QT_MIN_VERSION} NO_MODULE REQUIRED COMPONENTS Widgets Test)
|
||||
include(KDQtInstallPaths) #to set QT_INSTALL_FOO variables
|
||||
|
||||
set(${PROJECT_NAME}_DEPS "widgets")
|
||||
if(${PROJECT_NAME}_QTQUICK)
|
||||
find_package(Qt${Qt_VERSION_MAJOR} NO_MODULE REQUIRED COMPONENTS Quick QuickControls2)
|
||||
add_definitions(-DKDDOCKWIDGETS_QTQUICK)
|
||||
set(${PROJECT_NAME}_DEPS "${${PROJECT_NAME}_DEPS} quick quickcontrols2")
|
||||
# BEGIN frontend enabling
|
||||
if(KDDockWidgets_FRONTENDS)
|
||||
set(KDDockWidgets_ALL_FRONTENDS "qtwidgets;qtquick;dummy;flutter")
|
||||
|
||||
foreach(frontend ${KDDockWidgets_FRONTENDS})
|
||||
if(NOT ${frontend} IN_LIST KDDockWidgets_ALL_FRONTENDS)
|
||||
message(FATAL_ERROR "Unknown frontend ${frontend}")
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
if(KDDockWidgets_FRONTENDS)
|
||||
# qtwidgets
|
||||
if("qtwidgets" IN_LIST KDDockWidgets_FRONTENDS)
|
||||
find_package(Qt${Qt_VERSION_MAJOR} ${QT_MIN_VERSION} NO_MODULE REQUIRED COMPONENTS Widgets)
|
||||
set(KDDW_FRONTEND_QTWIDGETS ON)
|
||||
endif()
|
||||
|
||||
# qtquick
|
||||
if("qtquick" IN_LIST KDDockWidgets_FRONTENDS)
|
||||
find_package(Qt${Qt_VERSION_MAJOR} ${QT_MIN_VERSION} NO_MODULE REQUIRED COMPONENTS Quick QuickControls2)
|
||||
set(KDDW_FRONTEND_QTQUICK ON)
|
||||
endif()
|
||||
|
||||
# dummy
|
||||
if("dummy" IN_LIST KDDockWidgets_FRONTENDS)
|
||||
# For now dummy still depends on Qt
|
||||
find_package(Qt${Qt_VERSION_MAJOR} ${QT_MIN_VERSION} NO_MODULE REQUIRED COMPONENTS Gui)
|
||||
set(KDDW_FRONTEND_DUMMY ON)
|
||||
endif()
|
||||
|
||||
# flutter
|
||||
if("flutter" IN_LIST KDDockWidgets_FRONTENDS)
|
||||
# For now flutter still depends on Qt
|
||||
find_package(Qt${Qt_VERSION_MAJOR} ${QT_MIN_VERSION} NO_MODULE REQUIRED COMPONENTS Gui)
|
||||
set(KDDW_FRONTEND_FLUTTER ON)
|
||||
endif()
|
||||
|
||||
else()
|
||||
add_definitions(-DKDDOCKWIDGETS_QTWIDGETS)
|
||||
set(ENABLED_FRONTENDS "")
|
||||
message("No frontends specified explicitly.")
|
||||
|
||||
# qtwidgets
|
||||
find_package(Qt${Qt_VERSION_MAJOR} ${QT_MIN_VERSION} NO_MODULE COMPONENTS Widgets Quick QuickControls2)
|
||||
|
||||
if(Qt${Qt_VERSION_MAJOR}Widgets_FOUND)
|
||||
list(APPEND ENABLED_FRONTENDS "qtwidgets")
|
||||
set(KDDW_FRONTEND_QTWIDGETS ON)
|
||||
endif()
|
||||
|
||||
# qtquick
|
||||
if(Qt${Qt_VERSION_MAJOR}Quick_FOUND AND Qt${Qt_VERSION_MAJOR}QuickControls2_FOUND)
|
||||
list(APPEND ENABLED_FRONTENDS "qtquick")
|
||||
set(KDDW_FRONTEND_QTQUICK ON)
|
||||
endif()
|
||||
|
||||
if(NOT ENABLED_FRONTENDS)
|
||||
message(FATAL_ERROR "Failed to enable any frontends. Please install the required libraries and try again.")
|
||||
endif()
|
||||
|
||||
message("Following frontends have been enabled:")
|
||||
|
||||
foreach(frontend ${ENABLED_FRONTENDS})
|
||||
message("* ${frontend}")
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
# END frontend enabling
|
||||
include(KDQtInstallPaths) # to set QT_INSTALL_FOO variables
|
||||
|
||||
add_definitions(-DQT_NO_KEYWORDS)
|
||||
|
||||
option(KDockWidgets_PRETTY_QTWIDGETS_HEADERS
|
||||
"Install DockWidget.h and MainWindow.h as synonyms to the *_qtwidgets.h counterparts."
|
||||
${KDDW_FRONTEND_QTWIDGETS}
|
||||
)
|
||||
|
||||
if(KDDW_FRONTEND_QTWIDGETS)
|
||||
set(KDDockWidgets_DEPS "widgets")
|
||||
endif()
|
||||
|
||||
if(KDDW_FRONTEND_QTQUICK)
|
||||
set(KDDockWidgets_DEPS "${KDDockWidgets_DEPS} quick quickcontrols2")
|
||||
endif()
|
||||
|
||||
if(NOT WIN32
|
||||
AND NOT APPLE
|
||||
AND NOT EMSCRIPTEN
|
||||
AND NOT ${PROJECT_NAME}_QT6
|
||||
AND ${PROJECT_NAME}_X11EXTRAS
|
||||
AND NOT KDDockWidgets_QT6
|
||||
AND KDDockWidgets_X11EXTRAS
|
||||
)
|
||||
set(${PROJECT_NAME}_DEPS "${${PROJECT_NAME}_DEPS} x11extras")
|
||||
set(KDDockWidgets_DEPS "${KDDockWidgets_DEPS} x11extras")
|
||||
endif()
|
||||
|
||||
#Always build the test harness in developer-mode
|
||||
if(${PROJECT_NAME}_DEVELOPER_MODE)
|
||||
set(${PROJECT_NAME}_TESTS ON)
|
||||
set(${PROJECT_NAME}_WERROR ON)
|
||||
# Always build the test harness in developer-mode
|
||||
if(KDDockWidgets_DEVELOPER_MODE)
|
||||
set(KDDockWidgets_TESTS ON)
|
||||
set(KDDockWidgets_WERROR ON)
|
||||
include(ECMEnableSanitizers)
|
||||
|
||||
# find_package(doctest REQUIRED) TODOm3
|
||||
endif()
|
||||
|
||||
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||
@@ -190,10 +250,8 @@ else()
|
||||
set(IS_CLANG_BUILD FALSE)
|
||||
endif()
|
||||
|
||||
if(${PROJECT_NAME}_QTQUICK)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
endif()
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
@@ -205,7 +263,7 @@ set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)
|
||||
|
||||
# Sets compiler flags for the specified target, taking platform into consideration.
|
||||
macro(set_compiler_flags targetName)
|
||||
if(${PROJECT_NAME}_DEVELOPER_MODE)
|
||||
if(KDDockWidgets_DEVELOPER_MODE)
|
||||
target_compile_definitions(
|
||||
${targetName}
|
||||
PUBLIC DOCKS_DEVELOPER_MODE
|
||||
@@ -222,7 +280,7 @@ macro(set_compiler_flags targetName)
|
||||
endif()
|
||||
|
||||
# Enable -Werror
|
||||
if(${PROJECT_NAME}_WERROR AND (NOT MSVC OR IS_CLANG_BUILD)) # clang-cl accepts these too
|
||||
if(KDDockWidgets_WERROR AND (NOT MSVC OR IS_CLANG_BUILD)) # clang-cl accepts these too
|
||||
target_compile_options(${targetName} PRIVATE -Werror -Wundef -Wno-error=deprecated-declarations)
|
||||
endif()
|
||||
endmacro()
|
||||
@@ -236,6 +294,7 @@ if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND NOT APPLE)
|
||||
set(CMAKE_MODULE_LINKER_FLAGS "-Wl,--fatal-warnings ${CMAKE_MODULE_LINKER_FLAGS}")
|
||||
|
||||
string(TOUPPER "CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE}" compileflags)
|
||||
|
||||
if("${CMAKE_CXX_FLAGS} ${${compileflags}}" MATCHES "-fsanitize")
|
||||
set(sanitizers_enabled TRUE)
|
||||
else()
|
||||
@@ -252,21 +311,21 @@ if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND NOT APPLE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(${PROJECT_NAME}_STATIC)
|
||||
set(${PROJECT_NAME}_LIBRARY_MODE "STATIC")
|
||||
if(KDDockWidgets_STATIC)
|
||||
set(KDDockWidgets_LIBRARY_MODE "STATIC")
|
||||
else()
|
||||
set(${PROJECT_NAME}_LIBRARY_MODE "SHARED")
|
||||
set(KDDockWidgets_LIBRARY_MODE "SHARED")
|
||||
endif()
|
||||
|
||||
if(KDAB_INSTALL)
|
||||
if(UNIX)
|
||||
set(CMAKE_INSTALL_PREFIX
|
||||
"/usr/local/KDAB/${PROJECT_NAME}-${${PROJECT_NAME}_VERSION}"
|
||||
"/usr/local/KDAB/KDDockWidgets-${KDDockWidgets_VERSION}"
|
||||
CACHE INTERNAL "Install to default KDAB Location"
|
||||
)
|
||||
elseif(WIN32)
|
||||
set(CMAKE_INSTALL_PREFIX
|
||||
"C:\\KDAB\\${PROJECT_NAME}-${${PROJECT_NAME}_VERSION}"
|
||||
"C:\\KDAB\\KDDockWidgets-${KDDockWidgets_VERSION}"
|
||||
CACHE INTERNAL "Install to default KDAB Location"
|
||||
)
|
||||
endif()
|
||||
@@ -276,9 +335,9 @@ endif()
|
||||
include(KDInstallLocation)
|
||||
|
||||
if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
|
||||
set(${PROJECT_NAME}_IS_ROOT_PROJECT TRUE)
|
||||
set(KDDockWidgets_IS_ROOT_PROJECT TRUE)
|
||||
|
||||
message(STATUS "Building ${PROJECT_NAME} ${${PROJECT_NAME}_VERSION} in ${CMAKE_BUILD_TYPE} mode. "
|
||||
message(STATUS "Building KDDockWidgets ${KDDockWidgets_VERSION} in ${CMAKE_BUILD_TYPE} mode. "
|
||||
"Installing to ${CMAKE_INSTALL_PREFIX}"
|
||||
)
|
||||
|
||||
@@ -289,18 +348,18 @@ if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
|
||||
install(FILES LICENSE.txt README.md DESTINATION ${INSTALL_DOC_DIR})
|
||||
install(DIRECTORY LICENSES DESTINATION ${INSTALL_DOC_DIR})
|
||||
|
||||
# Generate .pri file for qmake users (except when using the VS generator)
|
||||
# Generate .pri file for qmake users
|
||||
if(NOT CMAKE_CONFIGURATION_TYPES)
|
||||
if(Qt_VERSION_MAJOR EQUAL 5 OR (Qt_VERSION_MAJOR EQUAL 6 AND Qt6Core_VERSION VERSION_GREATER "6.2"))
|
||||
include(ECMGeneratePriFile)
|
||||
set(PROJECT_VERSION_STRING ${${PROJECT_NAME}_VERSION})
|
||||
set(PROJECT_VERSION_STRING ${KDDockWidgets_VERSION})
|
||||
ecm_generate_pri_file(
|
||||
BASE_NAME
|
||||
KDDockWidgets
|
||||
LIB_NAME
|
||||
kddockwidgets${${PROJECT_NAME}_LIBRARY_QTID}
|
||||
DEPS
|
||||
${${PROJECT_NAME}_DEPS}
|
||||
${KDDockWidgets_DEPS}
|
||||
FILENAME_VAR
|
||||
pri_filename
|
||||
INCLUDE_INSTALL_DIR
|
||||
@@ -310,50 +369,67 @@ if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
#Always disable tests, examples, docs when used as a submodule
|
||||
set(${PROJECT_NAME}_IS_ROOT_PROJECT FALSE)
|
||||
set(${PROJECT_NAME}_TESTS FALSE)
|
||||
set(${PROJECT_NAME}_EXAMPLES FALSE)
|
||||
set(${PROJECT_NAME}_DOCS FALSE)
|
||||
# Always disable tests, examples, docs when used as a submodule
|
||||
set(KDDockWidgets_IS_ROOT_PROJECT FALSE)
|
||||
set(KDDockWidgets_TESTS FALSE)
|
||||
set(KDDockWidgets_EXAMPLES FALSE)
|
||||
set(KDDockWidgets_DOCS FALSE)
|
||||
endif()
|
||||
|
||||
if(${PROJECT_NAME}_TESTS)
|
||||
if(KDDockWidgets_TESTS)
|
||||
enable_testing()
|
||||
endif()
|
||||
|
||||
add_subdirectory(src)
|
||||
|
||||
if(${PROJECT_NAME}_PYTHON_BINDINGS)
|
||||
if(CMAKE_BUILD_TYPE MATCHES "^[Dd]eb" OR ${PROJECT_NAME}_STATIC)
|
||||
if(KDDockWidgets_PYTHON_BINDINGS)
|
||||
if(CMAKE_BUILD_TYPE MATCHES "^[Dd]eb" OR KDDockWidgets_STATIC)
|
||||
message(FATAL_ERROR "** Python Bindings are disabled in debug or static builds.")
|
||||
endif()
|
||||
|
||||
if(CMAKE_UNITY_BUILD)
|
||||
message(FATAL_ERROR "** Python Bindings are disabled in Unity builds. " "Try again with CMAKE_UNITY_BUILD=OFF")
|
||||
message(FATAL_ERROR "** Python Bindings are disabled in Unity builds. Try again with CMAKE_UNITY_BUILD=OFF")
|
||||
endif()
|
||||
endif()
|
||||
if(${PROJECT_NAME}_PYTHON_BINDINGS)
|
||||
|
||||
add_subdirectory(python)
|
||||
endif()
|
||||
|
||||
if(${PROJECT_NAME}_EXAMPLES)
|
||||
if(${PROJECT_NAME}_QTQUICK)
|
||||
if(KDDockWidgets_EXAMPLES)
|
||||
if(KDDW_FRONTEND_QTQUICK)
|
||||
add_subdirectory(examples/qtquick)
|
||||
else()
|
||||
endif()
|
||||
|
||||
if(KDDW_FRONTEND_QTWIDGETS)
|
||||
add_subdirectory(examples/dockwidgets)
|
||||
add_subdirectory(examples/minimal)
|
||||
add_subdirectory(examples/minimal-mdi)
|
||||
add_subdirectory(examples/mdi)
|
||||
add_subdirectory(examples/mdi_with_docking)
|
||||
set_compiler_flags(kddockwidgets_example)
|
||||
set_compiler_flags(kddockwidgets_minimal_example)
|
||||
set_compiler_flags(kddockwidgets_mdi_with_docking_example)
|
||||
set_compiler_flags(qtwidgets_dockwidgets)
|
||||
set_compiler_flags(qtwidgets_minimal)
|
||||
set_compiler_flags(qtwidgets_mdi_with_docking)
|
||||
|
||||
set_target_properties(
|
||||
qtwidgets_dockwidgets PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/examples/"
|
||||
)
|
||||
set_target_properties(
|
||||
qtwidgets_mdi_with_docking PROPERTIES RUNTIME_OUTPUT_DIRECTORY
|
||||
"${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/examples/"
|
||||
)
|
||||
set_target_properties(
|
||||
qtwidgets_mdi PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/examples/"
|
||||
)
|
||||
set_target_properties(
|
||||
qtwidgets_minimal PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/examples/"
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(${PROJECT_NAME}_TESTS)
|
||||
if(${PROJECT_NAME}_DEVELOPER_MODE)
|
||||
if(KDDockWidgets_TESTS)
|
||||
if(KDDockWidgets_DEVELOPER_MODE)
|
||||
add_subdirectory(tests)
|
||||
|
||||
# tst_docks.exe is pretty big (160 tests), so split it in more runs so we can use threads.
|
||||
# tst_docks.exe is pretty big (160 tests), so split it in more runs so we
|
||||
# can use threads.
|
||||
add_test(NAME tst_docks0 COMMAND tests_launcher 0 5)
|
||||
add_test(NAME tst_docks1 COMMAND tests_launcher 1 5)
|
||||
add_test(NAME tst_docks2 COMMAND tests_launcher 2 5)
|
||||
@@ -377,19 +453,35 @@ if(${PROJECT_NAME}_TESTS)
|
||||
add_test(NAME tst_docks20 COMMAND tests_launcher 19 5)
|
||||
add_test(NAME tst_docks21 COMMAND tests_launcher 20 5) # one more for rounding leftovers
|
||||
|
||||
if(NOT ${PROJECT_NAME}_QTQUICK)
|
||||
# tst_multisplitter depends on QWidget
|
||||
add_test(NAME tst_multisplitter COMMAND tst_multisplitter)
|
||||
add_test(NAME tst_view COMMAND tst_view)
|
||||
add_test(NAME tst_window COMMAND tst_window)
|
||||
add_test(NAME tst_droparea COMMAND tst_droparea)
|
||||
add_test(NAME tst_platform COMMAND tst_platform)
|
||||
add_test(NAME tst_viewguard COMMAND tst_viewguard)
|
||||
add_test(NAME tst_group COMMAND tst_group)
|
||||
add_test(NAME tst_titlebar COMMAND tst_titlebar)
|
||||
add_test(NAME tst_stack COMMAND tst_stack)
|
||||
add_test(NAME tst_tabbar COMMAND tst_tabbar)
|
||||
add_test(NAME tst_separator COMMAND tst_separator)
|
||||
add_test(NAME tst_floatingwindow COMMAND tst_floatingwindow)
|
||||
add_test(NAME tst_dockwidget COMMAND tst_dockwidget)
|
||||
add_test(NAME tst_multisplitter COMMAND tst_multisplitter)
|
||||
|
||||
if(KDDW_FRONTEND_QTWIDGETS)
|
||||
add_test(NAME tst_qtwidgets COMMAND tst_qtwidgets)
|
||||
endif()
|
||||
|
||||
if(KDDW_FRONTEND_QTQUICK)
|
||||
add_test(NAME tst_qtquick COMMAND tst_qtquick)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(${PROJECT_NAME}_DOCS)
|
||||
if(KDDockWidgets_DOCS)
|
||||
add_subdirectory(docs) # needs to go last, in case there are build source files
|
||||
endif()
|
||||
|
||||
if(${PROJECT_NAME}_IS_ROOT_PROJECT)
|
||||
if(KDDockWidgets_IS_ROOT_PROJECT)
|
||||
# Add uninstall target (not for submodules since parent projects typically have uninstall too)
|
||||
include(ECMUninstallTarget)
|
||||
endif()
|
||||
|
||||
@@ -9,11 +9,12 @@
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"KDDockWidgets_DEVELOPER_MODE": "ON",
|
||||
"CMAKE_EXPORT_COMPILE_COMMANDS" : "ON",
|
||||
"KDDockWidgets_FUZZER" : "OFF"
|
||||
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
|
||||
"KDDockWidgets_FUZZER": "OFF",
|
||||
"KDDockWidgets_FRONTENDS": "qtwidgets;qtquick;dummy"
|
||||
},
|
||||
"warnings" : {
|
||||
"uninitialized" : true
|
||||
"warnings": {
|
||||
"uninitialized": true
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -25,12 +26,47 @@
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"KDDockWidgets_DEVELOPER_MODE": "ON",
|
||||
"CMAKE_EXPORT_COMPILE_COMMANDS" : "ON",
|
||||
"KDDockWidgets_FUZZER" : "OFF",
|
||||
"ECM_ENABLE_SANITIZERS" : "'address;undefined'"
|
||||
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
|
||||
"KDDockWidgets_FUZZER": "OFF",
|
||||
"ECM_ENABLE_SANITIZERS": "'address;undefined'",
|
||||
"KDDockWidgets_FRONTENDS": "qtwidgets;qtquick;dummy"
|
||||
},
|
||||
"warnings" : {
|
||||
"uninitialized" : true
|
||||
"warnings": {
|
||||
"uninitialized": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "dev-flutter",
|
||||
"displayName": "dev-flutter",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/build-dev-flutter",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"KDDockWidgets_DEVELOPER_MODE": "ON",
|
||||
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
|
||||
"KDDockWidgets_FUZZER": "OFF",
|
||||
"KDDockWidgets_FRONTENDS": "flutter",
|
||||
"ECM_ENABLE_SANITIZERS": "'address;undefined'"
|
||||
},
|
||||
"warnings": {
|
||||
"uninitialized": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "dev-lcov",
|
||||
"displayName": "dev-lcov",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/build-dev-lcov",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"KDDockWidgets_DEVELOPER_MODE": "ON",
|
||||
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
|
||||
"KDDockWidgets_FUZZER": "OFF",
|
||||
"KDDockWidgets_CODE_COVERAGE": "ON",
|
||||
"KDDockWidgets_FRONTENDS": "qtwidgets;qtquick"
|
||||
},
|
||||
"warnings": {
|
||||
"uninitialized": true
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -41,27 +77,12 @@
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"KDDockWidgets_WERROR": "ON",
|
||||
"KDDockWidgets_EXAMPLES" : "OFF"
|
||||
"KDDockWidgets_EXAMPLES": "OFF",
|
||||
"KDDockWidgets_FRONTENDS": "qtwidgets;qtquick;dummy;flutter"
|
||||
},
|
||||
"environment": {
|
||||
"CXX": "clazy",
|
||||
"CCACHE_DISABLE" : "ON"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "clazy-qtquick",
|
||||
"displayName": "clazy-qtquick",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/build-clazy-qtquick",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"KDDockWidgets_EXAMPLES" : "OFF",
|
||||
"KDDockWidgets_WERROR": "ON",
|
||||
"KDDockWidgets_QTQUICK": "ON"
|
||||
},
|
||||
"environment": {
|
||||
"CXX": "clazy",
|
||||
"CCACHE_DISABLE" : "ON"
|
||||
"CCACHE_DISABLE": "ON"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -70,7 +91,9 @@
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/build-release",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release"
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"CMAKE_UNITY_BUILD": "OFF",
|
||||
"KDDockWidgets_FRONTENDS": "qtwidgets;qtquick"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -80,31 +103,9 @@
|
||||
"binaryDir": "${sourceDir}/build-release-no-x11extras",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"KDDockWidgets_X11EXTRAS" : "OFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "release-qtquick",
|
||||
"displayName": "release-qtquick",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/build-release-qtquick",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"KDDockWidgets_QTQUICK": "ON"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "dev-qtquick",
|
||||
"displayName": "dev-qtquick",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/build-dev-qtquick",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"KDDockWidgets_QTQUICK": "ON",
|
||||
"KDDockWidgets_DEVELOPER_MODE": "ON",
|
||||
"ECM_ENABLE_SANITIZERS" : "'address;undefined'",
|
||||
"CMAKE_EXPORT_COMPILE_COMMANDS" : "ON",
|
||||
"KDDockWidgets_FUZZER" : "OFF"
|
||||
"CMAKE_UNITY_BUILD": "OFF",
|
||||
"KDDockWidgets_X11EXTRAS": "OFF",
|
||||
"KDDockWidgets_FRONTENDS": "qtwidgets;qtquick"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -114,7 +115,9 @@
|
||||
"binaryDir": "${sourceDir}/build-python",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"KDDockWidgets_PYTHON_BINDINGS": "ON"
|
||||
"KDDockWidgets_PYTHON_BINDINGS": "ON",
|
||||
"CMAKE_UNITY_BUILD": "OFF",
|
||||
"KDDockWidgets_FRONTENDS": "qtwidgets;qtquick"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -122,20 +125,10 @@
|
||||
"displayName": "static",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/build-static",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"KDDockWidgets_STATIC": "ON"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "static-qtquick",
|
||||
"displayName": "static-qtquick",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/build-static-qtquick",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"KDDockWidgets_STATIC": "ON",
|
||||
"KDDockWidgets_QTQUICK": "ON"
|
||||
"KDDockWidgets_FRONTENDS": "qtwidgets;qtquick"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -146,7 +139,9 @@
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"KDDockWidgets_QT6": "ON",
|
||||
"CMAKE_PREFIX_PATH" : "$env{QT6_DIR}"
|
||||
"CMAKE_UNITY_BUILD": "OFF",
|
||||
"CMAKE_PREFIX_PATH": "$env{QT6_DIR}",
|
||||
"KDDockWidgets_FRONTENDS": "qtwidgets;qtquick"
|
||||
},
|
||||
"environment": {
|
||||
"PATH": "$env{QT6_DIR}/bin:$penv{PATH}"
|
||||
@@ -161,9 +156,10 @@
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"KDDockWidgets_QT6": "ON",
|
||||
"KDDockWidgets_DEVELOPER_MODE": "ON",
|
||||
"CMAKE_EXPORT_COMPILE_COMMANDS" : "ON",
|
||||
"KDDockWidgets_FUZZER" : "OFF",
|
||||
"CMAKE_PREFIX_PATH" : "$env{QT6_DIR}"
|
||||
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
|
||||
"KDDockWidgets_FUZZER": "OFF",
|
||||
"CMAKE_PREFIX_PATH": "$env{QT6_DIR}",
|
||||
"KDDockWidgets_FRONTENDS": "qtwidgets;qtquick;dummy"
|
||||
},
|
||||
"environment": {
|
||||
"PATH": "$env{QT6_DIR}/bin:$penv{PATH}"
|
||||
@@ -178,50 +174,16 @@
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"KDDockWidgets_QT6": "ON",
|
||||
"KDDockWidgets_DEVELOPER_MODE": "ON",
|
||||
"CMAKE_EXPORT_COMPILE_COMMANDS" : "ON",
|
||||
"ECM_ENABLE_SANITIZERS" : "'address;undefined'",
|
||||
"KDDockWidgets_FUZZER" : "OFF",
|
||||
"CMAKE_PREFIX_PATH" : "$env{QT6_DIR}"
|
||||
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
|
||||
"ECM_ENABLE_SANITIZERS": "'address;undefined'",
|
||||
"KDDockWidgets_FUZZER": "OFF",
|
||||
"CMAKE_PREFIX_PATH": "$env{QT6_DIR}",
|
||||
"KDDockWidgets_FRONTENDS": "qtwidgets;qtquick;dummy"
|
||||
},
|
||||
"environment": {
|
||||
"PATH": "$env{QT6_DIR}/bin:$penv{PATH}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "release-qtquick6",
|
||||
"displayName": "release-qtquick6",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/build-release-qtquick6",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"KDDockWidgets_QTQUICK": "ON",
|
||||
"KDDockWidgets_QT6": "ON",
|
||||
"CMAKE_PREFIX_PATH" : "$env{QT6_DIR}"
|
||||
},
|
||||
"environment": {
|
||||
"PATH": "$env{QT6_DIR}/bin:$penv{PATH}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "dev-qtquick6",
|
||||
"displayName": "dev-qtquick6",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/build-dev-qtquick6",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"KDDockWidgets_QTQUICK": "ON",
|
||||
"CMAKE_EXPORT_COMPILE_COMMANDS" : "ON",
|
||||
"KDDockWidgets_DEVELOPER_MODE": "ON",
|
||||
"ECM_ENABLE_SANITIZERS" : "'address;undefined'",
|
||||
"KDDockWidgets_QT6": "ON",
|
||||
"CMAKE_PREFIX_PATH" : "$env{QT6_DIR}"
|
||||
},
|
||||
"environment": {
|
||||
"PATH": "$env{QT6_DIR}/bin:$penv{PATH}",
|
||||
"QML2_IMPORT_PATH" : "$env{QT6_DIR}/imports:$env{QT6_DIR}/qml",
|
||||
"LD_LIBRARY_PATH" : "$env{QT6_DIR}/lib"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "dev-clangcl",
|
||||
"displayName": "dev-clangcl",
|
||||
@@ -230,30 +192,12 @@
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"KDDockWidgets_DEVELOPER_MODE": "ON",
|
||||
"CMAKE_EXPORT_COMPILE_COMMANDS" : "ON",
|
||||
"KDDockWidgets_FUZZER" : "ON"
|
||||
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
|
||||
"KDDockWidgets_FUZZER": "ON",
|
||||
"KDDockWidgets_FRONTENDS": "qtwidgets;qtquick"
|
||||
},
|
||||
"warnings" : {
|
||||
"uninitialized" : true
|
||||
},
|
||||
"environment": {
|
||||
"CC": "clang-cl",
|
||||
"CXX": "clang-cl"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "dev-qtquick-clangcl",
|
||||
"displayName": "dev-qtquick-clangcl",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/build-dev-qtquick-clangcl",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"KDDockWidgets_DEVELOPER_MODE": "ON",
|
||||
"KDDockWidgets_FUZZER" : "OFF",
|
||||
"KDDockWidgets_QTQUICK": "ON"
|
||||
},
|
||||
"warnings" : {
|
||||
"uninitialized" : true
|
||||
"warnings": {
|
||||
"uninitialized": true
|
||||
},
|
||||
"environment": {
|
||||
"CC": "clang-cl",
|
||||
@@ -268,12 +212,13 @@
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"KDDockWidgets_DEVELOPER_MODE": "ON",
|
||||
"KDDockWidgets_FUZZER" : "ON",
|
||||
"KDDockWidgets_FUZZER": "ON",
|
||||
"KDDockWidgets_QT6": "ON",
|
||||
"CMAKE_PREFIX_PATH" : "$env{QT6_DIR}"
|
||||
"CMAKE_PREFIX_PATH": "$env{QT6_DIR}",
|
||||
"KDDockWidgets_FRONTENDS": "qtwidgets;qtquick"
|
||||
},
|
||||
"warnings" : {
|
||||
"uninitialized" : true
|
||||
"warnings": {
|
||||
"uninitialized": true
|
||||
},
|
||||
"environment": {
|
||||
"CC": "clang-cl",
|
||||
@@ -281,30 +226,6 @@
|
||||
"PATH": "$env{QT6_DIR}/bin:$penv{PATH}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "dev-qtquick-clangcl6",
|
||||
"displayName": "dev-qtquick-clangcl6",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/build-dev-qtquick-clangcl6",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"KDDockWidgets_DEVELOPER_MODE": "ON",
|
||||
"KDDockWidgets_FUZZER" : "OFF",
|
||||
"KDDockWidgets_QTQUICK": "ON",
|
||||
"KDDockWidgets_QT6": "ON",
|
||||
"CMAKE_PREFIX_PATH" : "$env{QT6_DIR}"
|
||||
},
|
||||
"warnings" : {
|
||||
"uninitialized" : true
|
||||
},
|
||||
"environment": {
|
||||
"CC": "clang-cl",
|
||||
"CXX": "clang-cl",
|
||||
"PATH": "$env{QT6_DIR}/bin:$penv{PATH}",
|
||||
"QML2_IMPORT_PATH" : "$env{QT6_DIR}/imports:$env{QT6_DIR}/qml",
|
||||
"LD_LIBRARY_PATH" : "$env{QT6_DIR}/lib"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "dev-time-trace",
|
||||
"displayName": "dev-time-trace",
|
||||
@@ -313,18 +234,19 @@
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"KDDockWidgets_DEVELOPER_MODE": "ON",
|
||||
"CMAKE_EXPORT_COMPILE_COMMANDS" : "ON",
|
||||
"KDDockWidgets_FUZZER" : "OFF",
|
||||
"CMAKE_C_FLAGS_INIT" : "-ftime-trace",
|
||||
"CMAKE_CXX_FLAGS_INIT": "-ftime-trace"
|
||||
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
|
||||
"KDDockWidgets_FUZZER": "OFF",
|
||||
"CMAKE_C_FLAGS_INIT": "-ftime-trace",
|
||||
"CMAKE_CXX_FLAGS_INIT": "-ftime-trace",
|
||||
"KDDockWidgets_FRONTENDS": "qtwidgets;qtquick"
|
||||
},
|
||||
"warnings" : {
|
||||
"uninitialized" : true
|
||||
"warnings": {
|
||||
"uninitialized": true
|
||||
},
|
||||
"environment": {
|
||||
"CC": "clang",
|
||||
"CXX": "clang++",
|
||||
"CCACHE_DISABLE" : "ON"
|
||||
"CCACHE_DISABLE": "ON"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -335,107 +257,138 @@
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"KDDockWidgets_DEVELOPER_MODE": "ON",
|
||||
"CMAKE_EXPORT_COMPILE_COMMANDS" : "ON",
|
||||
"KDDockWidgets_FUZZER" : "OFF",
|
||||
"KDDockWidgets_QT6" : "ON",
|
||||
"CMAKE_C_FLAGS_INIT" : "-ftime-trace",
|
||||
"CMAKE_CXX_FLAGS_INIT": "-ftime-trace"
|
||||
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
|
||||
"KDDockWidgets_FUZZER": "OFF",
|
||||
"KDDockWidgets_QT6": "ON",
|
||||
"CMAKE_C_FLAGS_INIT": "-ftime-trace",
|
||||
"CMAKE_CXX_FLAGS_INIT": "-ftime-trace",
|
||||
"KDDockWidgets_FRONTENDS": "qtwidgets;qtquick"
|
||||
},
|
||||
"warnings" : {
|
||||
"uninitialized" : true
|
||||
"warnings": {
|
||||
"uninitialized": true
|
||||
},
|
||||
"environment": {
|
||||
"CC": "clang",
|
||||
"CXX": "clang++",
|
||||
"CCACHE_DISABLE" : "ON"
|
||||
"CCACHE_DISABLE": "ON"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ci-dev-qtwidgets-qt5",
|
||||
"displayName": "ci-dev-qtwidgets-qt5",
|
||||
"description": "Qt5 QtWidgets dev-mode build",
|
||||
"binaryDir": "${sourceDir}/build-ci-dev-qtwidgets-qt5",
|
||||
"generator": "Ninja",
|
||||
"cacheVariables": {
|
||||
"KDDockWidgets_DEVELOPER_MODE": "ON",
|
||||
"CMAKE_BUILD_TYPE": "Debug"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ci-dev-qtquick-qt5",
|
||||
"displayName": "ci-dev-qtquick-qt5",
|
||||
"description": "Qt5 QtQuick dev-mode build",
|
||||
"binaryDir": "${sourceDir}/build-ci-dev-qtquick-qt5",
|
||||
"name": "ci-dev-qt5",
|
||||
"displayName": "ci-dev-qt5",
|
||||
"description": "Qt5 dev-mode build",
|
||||
"binaryDir": "${sourceDir}/build-ci-dev-qt5",
|
||||
"generator": "Ninja",
|
||||
"cacheVariables": {
|
||||
"KDDockWidgets_DEVELOPER_MODE": "ON",
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"KDDockWidgets_QTQUICK": "ON"
|
||||
"KDDockWidgets_FRONTENDS": "qtwidgets;qtquick"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ci-release-qt5",
|
||||
"displayName": "ci-release-qt5",
|
||||
"description": "Qt5 non dev-mode build",
|
||||
"binaryDir": "${sourceDir}/build-ci-release-qt5",
|
||||
"generator": "Ninja",
|
||||
"cacheVariables": {
|
||||
"KDDockWidgets_DEVELOPER_MODE": "OFF",
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"KDDockWidgets_FRONTENDS": "qtwidgets;qtquick"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ci-qtwidgets-qt5",
|
||||
"displayName": "ci-qtwidgets-qt5",
|
||||
"description": "Qt5 QtWidgets release build",
|
||||
"description": "Qt5 build which excludes QtQuick",
|
||||
"binaryDir": "${sourceDir}/build-ci-qtwidgets-qt5",
|
||||
"generator": "Ninja",
|
||||
"cacheVariables": {
|
||||
"KDDockWidgets_DEVELOPER_MODE": "OFF",
|
||||
"CMAKE_BUILD_TYPE": "Release"
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"KDDockWidgets_FRONTENDS": "qtwidgets"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ci-qtquick-qt5",
|
||||
"displayName": "ci-qtquick-qt5",
|
||||
"description": "Qt5 QtQuick release build",
|
||||
"description": "Qt5 build which excludes QtWidgets",
|
||||
"binaryDir": "${sourceDir}/build-ci-qtquick-qt5",
|
||||
"generator": "Ninja",
|
||||
"cacheVariables": {
|
||||
"KDDockWidgets_DEVELOPER_MODE": "OFF",
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"KDDockWidgets_QTQUICK": "ON"
|
||||
"KDDockWidgets_FRONTENDS": "qtquick"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ci-dev-qtwidgets-qt6",
|
||||
"displayName": "ci-dev-qtwidgets-qt6",
|
||||
"description": "Qt6 dev-mode",
|
||||
"binaryDir": "${sourceDir}/build-ci-dev-qtwidgets-qt6",
|
||||
"name": "ci-dummy",
|
||||
"displayName": "ci-dummy",
|
||||
"description": "Builds only the dummy frontend. Tests that build passes without Qt.",
|
||||
"binaryDir": "${sourceDir}/build-ci-dummy",
|
||||
"generator": "Ninja",
|
||||
"cacheVariables": {
|
||||
"KDDockWidgets_DEVELOPER_MODE": "ON",
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"KDDockWidgets_DEVELOPER_MODE": "OFF",
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"KDDockWidgets_FRONTENDS": "dummy",
|
||||
"KDDockWidgets_QT6": "ON"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ci-dev-qtquick-qt6",
|
||||
"displayName": "ci-dev-qtquick-qt6",
|
||||
"name": "ci-flutter",
|
||||
"displayName": "ci-flutter",
|
||||
"description": "Builds only the flutter frontend. Tests that build passes without Qt.",
|
||||
"binaryDir": "${sourceDir}/build-ci-flutter",
|
||||
"generator": "Ninja",
|
||||
"cacheVariables": {
|
||||
"KDDockWidgets_DEVELOPER_MODE": "OFF",
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"KDDockWidgets_FRONTENDS": "flutter",
|
||||
"KDDockWidgets_QT6": "ON"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ci-dev-qt6",
|
||||
"displayName": "ci-dev-qt6",
|
||||
"description": "Qt6 dev-mode",
|
||||
"binaryDir": "${sourceDir}/build-ci-dev-qtquick-qt6",
|
||||
"binaryDir": "${sourceDir}/build-ci-dev-qt6",
|
||||
"generator": "Ninja",
|
||||
"cacheVariables": {
|
||||
"KDDockWidgets_DEVELOPER_MODE": "ON",
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"KDDockWidgets_FRONTENDS": "qtwidgets;qtquick",
|
||||
"KDDockWidgets_QT6": "ON"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ci-release-qt6",
|
||||
"description": "Qt6 non dev-mode",
|
||||
"displayName": "ci-release-qt6",
|
||||
"binaryDir": "${sourceDir}/build-ci-release-qt6",
|
||||
"generator": "Ninja",
|
||||
"cacheVariables": {
|
||||
"KDDockWidgets_DEVELOPER_MODE": "OFF",
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"KDDockWidgets_QT6": "ON",
|
||||
"KDDockWidgets_QTQUICK": "ON"
|
||||
"KDDockWidgets_FRONTENDS": "qtwidgets;qtquick"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ci-qtwidgets-qt6",
|
||||
"description": "Qt6 QtWidgets release build",
|
||||
"description": "Qt6 build which excludes QtQuick",
|
||||
"displayName": "ci-qtwidgets-qt6",
|
||||
"binaryDir": "${sourceDir}/build-ci-qtwidgets-qt6",
|
||||
"generator": "Ninja",
|
||||
"cacheVariables": {
|
||||
"KDDockWidgets_DEVELOPER_MODE": "OFF",
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"KDDockWidgets_QT6": "ON"
|
||||
"KDDockWidgets_QT6": "ON",
|
||||
"KDDockWidgets_FRONTENDS": "qtwidgets"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ci-qtquick-qt6",
|
||||
"description": "Qt6 QtQuick release build",
|
||||
"description": "Qt6 build which excludes QtWidgets",
|
||||
"displayName": "ci-qtquick-qt6",
|
||||
"binaryDir": "${sourceDir}/build-ci-qtquick-qt6",
|
||||
"generator": "Ninja",
|
||||
@@ -443,23 +396,8 @@
|
||||
"KDDockWidgets_DEVELOPER_MODE": "OFF",
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"KDDockWidgets_QT6": "ON",
|
||||
"KDDockWidgets_QTQUICK": "ON"
|
||||
"KDDockWidgets_FRONTENDS": "qtquick"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ci-static",
|
||||
"inherits":["static"],
|
||||
"binaryDir": "${sourceDir}/build-ci-static"
|
||||
},
|
||||
{
|
||||
"name": "ci-static-qtquick",
|
||||
"inherits":["static-qtquick"],
|
||||
"binaryDir": "${sourceDir}/build-ci-static-qtquick"
|
||||
},
|
||||
{
|
||||
"name": "ci-python",
|
||||
"inherits":["python"],
|
||||
"binaryDir": "${sourceDir}/build-python"
|
||||
}
|
||||
],
|
||||
"buildPresets": [
|
||||
@@ -467,16 +405,8 @@
|
||||
"name": "clazy",
|
||||
"configurePreset": "clazy",
|
||||
"environment": {
|
||||
"CLAZY_CHECKS" : "level2,detaching-member,heap-allocated-small-trivial-type,isempty-vs-count,qstring-varargs,qvariant-template-instantiation,raw-environment-function,reserve-candidates,signal-with-return-value,thread-with-slots,no-ctor-missing-parent-argument,no-missing-typeinfo",
|
||||
"CCACHE_DISABLE" : "ON"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "clazy-qtquick",
|
||||
"configurePreset": "clazy-qtquick",
|
||||
"environment": {
|
||||
"CLAZY_CHECKS" : "level2,detaching-member,heap-allocated-small-trivial-type,isempty-vs-count,qstring-varargs,qvariant-template-instantiation,raw-environment-function,reserve-candidates,signal-with-return-value,thread-with-slots,no-ctor-missing-parent-argument,no-missing-typeinfo",
|
||||
"CCACHE_DISABLE" : "ON"
|
||||
"CLAZY_CHECKS": "level2,detaching-member,heap-allocated-small-trivial-type,isempty-vs-count,qstring-varargs,qvariant-template-instantiation,raw-environment-function,reserve-candidates,signal-with-return-value,thread-with-slots,no-ctor-missing-parent-argument,no-missing-typeinfo",
|
||||
"CCACHE_DISABLE": "ON"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
13
Changelog
13
Changelog
@@ -1,3 +1,14 @@
|
||||
* v2.0.0 (unreleased)
|
||||
- Architecture rewrite to support more frontends besides QtWidgets and QtQuick.
|
||||
2.0 isn't very interesting for users, but will allow developers to make KDDW
|
||||
support other GUI frameworks more easily. Also QtQuick is now better integrated,
|
||||
without being shoehorned with ifdefs into the QtWidgets implementation.
|
||||
- Split into a view/controller architecture
|
||||
- Non-gui logic moved to controllers
|
||||
- Each controller has a gui counter part, implemented for each supported frontend
|
||||
- Uses nlohmann JSON library (MIT) instead of QJsonDocument, for saving/restoring layouts
|
||||
- Added Config::setStartDragDistance()
|
||||
|
||||
* v1.7.0 (unreleased)
|
||||
- Introduce DockWidget::setFloatingWindowFlags(flags). Allows for different
|
||||
FloatingWindows to have different window flags. For example, some having
|
||||
@@ -43,7 +54,7 @@
|
||||
- FloatingWindow now honours the dockwidget's max-size, if there's a single
|
||||
dock widget docked. Tabbed cases are more difficult since QStackedLayout doesn't
|
||||
propagate size constraints.
|
||||
- Added MainWindowBase::frameCountChanged()
|
||||
- Added MainWindowBase::groupCountChanged()
|
||||
- Introduced Config::setDropIndicatorsInhibited(), which allows you to disable support
|
||||
for drop indicators while dragging.
|
||||
- Fixed embedding the main window into a non-kddw main window (#204, #168)
|
||||
|
||||
@@ -2,7 +2,7 @@ GNU GENERAL PUBLIC LICENSE
|
||||
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
|
||||
|
||||
9
LICENSES/MIT.txt
Normal file
9
LICENSES/MIT.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) <year> <copyright holders>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
@@ -2,28 +2,6 @@
|
||||
|
||||
These are the instructions for building the Python bindings for KDDockWidgets.
|
||||
|
||||
Currently unsupported:
|
||||
|
||||
- debug builds
|
||||
- builds against Qt debug libraries
|
||||
- static builds
|
||||
- python2 bindings
|
||||
- only some 32-bit platforms are supported. see <https://wiki.qt.io/Qt_for_Python>
|
||||
|
||||
Also, there are no plans to support the qmake buildsystem.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
You will need:
|
||||
|
||||
- a compiler with C++14 support (C++17 for Qt6 builds)
|
||||
- Python3.7 or higher
|
||||
- Qt5 version 5.12 or higher
|
||||
- Qt6 version 6.2 or higher
|
||||
- QtForPython provided by the Qt project.
|
||||
|
||||
## Install PySide2 for Qt5
|
||||
|
||||
Make sure you have PySide2, shiboken2 and shiboken2-generator installed.
|
||||
As this time, you cannot get shiboken2-generator because the wheels are not on PyPi.
|
||||
To use the wheels do this:
|
||||
@@ -35,49 +13,37 @@ To use the wheels do this:
|
||||
shiboken2 pyside2 shiboken2_generator
|
||||
```
|
||||
|
||||
For more info visit <https://doc.qt.io/qtforpython/shiboken2/gettingstarted.html>
|
||||
|
||||
afterwards run:
|
||||
|
||||
```bash
|
||||
pip3 list | grep PySide
|
||||
```
|
||||
For more info visit <https://doc.qt.io/qtforpython/shiboken2/gettingstarted.html>.
|
||||
|
||||
afterwards run 'pip3 list | grep PySide2'
|
||||
Note the version *must* match the same Qt you intend to use when building KDDockWidgets.
|
||||
|
||||
## Install PySide6 for Qt6
|
||||
Not supported:
|
||||
|
||||
Follow the same instructions as [the previous section](#Install PySide2 for Qt5),
|
||||
except installing `shiboken6 pyside6 shiboken6_generator` with pip3.
|
||||
- debug builds
|
||||
- static builds
|
||||
- python2 bindings
|
||||
- only some 32-bit platforms are supported (see <https://wiki.qt.io/Qt_for_Python>)
|
||||
|
||||
## Building KDDockWidgets Python Bindings
|
||||
Tell CMake to build the bindings by passing the `-DKDDockWidgets_PYTHON_BINDINGS=True' option,
|
||||
followed by the make command.
|
||||
|
||||
Tell CMake to build the bindings by passing the `-DKDDockWidgets_PYTHON_BINDINGS=True' option.
|
||||
Then run `cmake --build` as usual.
|
||||
|
||||
The bindings will be installed to `CMAKE_INSTALL_PREFIX`, which might require setting
|
||||
the `PYTHONPATH` env variable to point to that path when running applications.
|
||||
|
||||
For example, if you install to the default location on linux you would:
|
||||
|
||||
```bash
|
||||
export PYTHONPATH=/usr/local/KDAB/KDDockWidgets-1.7.0/lib64/python3.10/site-packages
|
||||
```
|
||||
|
||||
Alternatively, configure the bindings install location by passing (for example)
|
||||
`-DKDDockWidgets_PYTHON_BINDINGS_INSTALL_PREFIX=/usr/lib/python3.8/site-packages` to CMake
|
||||
and adjust to the PYTHONPATH accordingly, as necessary.
|
||||
The bindings will be installed to the passed `-DCMAKE_INSTALL_PREFIX`, which
|
||||
might require setting the `PYTHONPATH` env variable to point to that path when
|
||||
running applications. Alternatively, configure the bindings install location
|
||||
by passing `-DKDDockWidgets_PYTHON_BINDINGS_INSTALL_PREFIX=/usr/lib/python3.8/site-packages`
|
||||
to CMake (adjust to the python path on your system).
|
||||
|
||||
To run the KDDW python example
|
||||
|
||||
```bash
|
||||
export PYTHONPATH=/usr/local/KDAB/KDDockWidgets-1.7.0/lib64/python3.10/site-packages # adapt as needed
|
||||
export PYTHONPATH=/kddw/install/path # Only if needed
|
||||
cd python/examples/
|
||||
rcc -g python -o rc_assets.py ../../examples/dockwidgets/resources_example.qrc
|
||||
python3 main.py
|
||||
```
|
||||
|
||||
### Build Issues
|
||||
Build Issues
|
||||
|
||||
- If you see errors like "Unable to locate Clang's built-in include directory"
|
||||
then first mROUBLESHOOTINGake sure you have llvm installed. If you still have problems try
|
||||
|
||||
34
README.md
34
README.md
@@ -2,8 +2,9 @@
|
||||
|
||||
[](https://travis-ci.com/KDAB/KDDockWidgets)
|
||||
|
||||
> ⚠️⚠️: If you're using QtQuick/QML it's recommended to use 2.0 branch. 1.x will continue
|
||||
> to receive bug fixes for a long time but only for QtWidgets frontend.
|
||||
> ⚠️⚠️: 2.0 is under development, there might be API breaks before release.
|
||||
> Stick with version 1.6 if you're using QtWidgets. However, if you're using
|
||||
> QtQuick it's better to base on 2.0, as 1.6 won't be receiving much QtQuick development.
|
||||
|
||||
`KDDockWidgets` is a Qt dock widget library written by KDAB, suitable for replacing
|
||||
`QDockWidget` and implementing advanced functionalities missing in Qt.
|
||||
@@ -79,7 +80,7 @@ To build KDDockWidgets you'll need:
|
||||
- CMake
|
||||
- Qt 5.15.x or Qt6 >= 6.2
|
||||
- Ninja (Other generators might work but are untested)
|
||||
- C++17 capable compiler
|
||||
- C++17 capable compiler. Minimum VS2019 on Windows.
|
||||
- Qt Widgets module
|
||||
- Qt X11Extras module if on Linux/X11
|
||||
- Qt Quick and QuickControls2 modules if using the QtQuick support
|
||||
@@ -100,6 +101,15 @@ Adapt the instructions to suit your cmake generator and operating system.
|
||||
cmake --build . --target install
|
||||
```
|
||||
|
||||
Now build and run the example:
|
||||
|
||||
```bash
|
||||
cd path/to/kddockwidgets/examples/dockwidgets/
|
||||
cmake -G Ninja -DCMAKE_PREFIX_PATH=/path/where/to/install
|
||||
cmake --build .
|
||||
./bin/examples/qtwidgets_dockwidgets
|
||||
```
|
||||
|
||||
The installation directory defaults to `c:\KDAB\KDDockWidgets-<version>` on Windows
|
||||
and `/usr/local/KDAB/KDDockWidgets-<version>` on non-Windows.
|
||||
|
||||
@@ -147,18 +157,16 @@ Please refer to [README-bindings.md](README-bindings.md).
|
||||
|
||||
## Versioning
|
||||
|
||||
There's currently two lines of development: `v1` which is very mature and stable and `v2` which is an
|
||||
ongoing effort to make KDDW support multiple "frontends" (QtWidgets, QtQuick and even non-Qt technologies,
|
||||
like flutter).
|
||||
There's currently two lines of development: `v1` which is very mature and stable and `v2` which is an ongoing effort to make
|
||||
KDDW support multiple "frontends" (QtWidgets, QtQuick and even non-Qt technologies, like flutter).
|
||||
|
||||
1.x will be supported for many years to come, at least for bug fixes and small features.
|
||||
Use `v1.6.0` tag for the latest stable.
|
||||
Use `v1.6.0` tag for the latest stable.<br>
|
||||
|
||||
Use `2.0` if you need non-QtWidgets support, for example `QtQuick/QML`. While `1.6` has support for `QtQuick/QML`
|
||||
it won't be receiving bug fixes. `2.0` is under active development, you might encounter minor source/ABI
|
||||
incompatibilities. Despite that, it is pretty stable, and all 200 unit-tests pass.
|
||||
Use `2.0` if you need non-QtWidgets support, for example `QtQuick/QML`. While `1.6` has support for `QtQuick/QML` it won't be receiving bug fixes. `2.0` is under active development, you might encounter minor source/ABI incompatibilities. Despite that,
|
||||
it is pretty stable, and all 200 unit-tests pass.
|
||||
|
||||
We'll try to remain source-compatible across versions (except for the v1 -> v2 jump).
|
||||
We'll try to remain source-compatible across versions (except for the v1 -> v2 jump).<br>
|
||||
API will get a deprecation notice before being removed in the next version. Note that this
|
||||
compatibility effort is only for the public API. Private API (headers ending
|
||||
in _p.h) might change so you shouldn't depend on them. Private API is only
|
||||
@@ -171,8 +179,8 @@ your application whenever updating KDDW.
|
||||
## Styling
|
||||
|
||||
Almost all private widgets used by KDDW can be derived by the user to give them
|
||||
a custom look. That's done by providing your own FrameworkWidgetFactory. Run
|
||||
"kddockwidgets_example -p" to see that in action.
|
||||
a custom look. That's done by providing your own ViewFactory. Run
|
||||
"examples/qtwidgets_dockwidgets -p" to see that in action.
|
||||
|
||||
Qt StyleSheets are not, and will not, be supported. See the comments in
|
||||
`examples/dockwidgets/MyTitleBar_CSS.h` for why. You can however use some minimal
|
||||
|
||||
@@ -52,8 +52,9 @@ install:
|
||||
|
||||
before_build:
|
||||
- cmd: call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat"
|
||||
- cmd: set PATH=C:\Qt\6.2\msvc2019_64\bin;C:\Qt\5.15\msvc2019_64\bin;%PATH%
|
||||
- sh: if [ "`uname -s`" = "Darwin" ]; then export PATH=$HOME/Qt/6.2/macos/bin:$HOME/Qt/5.15/clang_64/bin:$PATH; else export PATH=$HOME/Qt/6.2/gcc_64/bin:$HOME/Qt/5.15/gcc_64/bin:$PATH; fi
|
||||
- cmd: set PATH=C:\Qt\6.3\msvc2019_64\bin;C:\Qt\5.15\msvc2019_64\bin;%PATH%
|
||||
- sh: export QT_QUICK_BACKEND=software
|
||||
- sh: if [ "`uname -s`" = "Darwin" ]; then export PATH=$HOME/Qt/6.3/macos/bin:$HOME/Qt/5.15/clang_64/bin:$PATH; else export PATH=$HOME/Qt/6.3/gcc_64/bin:$HOME/Qt/5.15/gcc_64/bin:$PATH; fi
|
||||
|
||||
build_script:
|
||||
- mkdir build
|
||||
@@ -64,7 +65,7 @@ build_script:
|
||||
- cmd: cmake --build . --target install
|
||||
- sh: sudo cmake --build . --target install
|
||||
- cmd: set PATH=.\bin;%PATH%
|
||||
- ctest --test-dir .
|
||||
- ctest --test-dir . -V
|
||||
|
||||
# to disable automatic builds
|
||||
#build: off
|
||||
|
||||
@@ -30,7 +30,7 @@ if(NOT INSTALL_DATADIR)
|
||||
set(INSTALL_DATADIR ${CMAKE_INSTALL_DATADIR})
|
||||
endif()
|
||||
if(NOT INSTALL_DOC_DIR)
|
||||
set(INSTALL_DOC_DIR ${CMAKE_INSTALL_DOCDIR}${${PROJECT_NAME}_LIBRARY_QTID})
|
||||
set(INSTALL_DOC_DIR ${CMAKE_INSTALL_DOCDIR}${KDDockWidgets_LIBRARY_QTID})
|
||||
endif()
|
||||
|
||||
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||
|
||||
@@ -1,148 +0,0 @@
|
||||
{
|
||||
"folders": [
|
||||
{
|
||||
"path": "."
|
||||
}
|
||||
],
|
||||
"settings": {
|
||||
"C_Cpp.default.compileCommands": "${workspaceFolder}/build-dev-qtquick/compile_commands.json",
|
||||
"C_Cpp.default.cStandard": "c17",
|
||||
"files.trimTrailingWhitespace": true,
|
||||
"editor.formatOnType": true,
|
||||
"C_Cpp.autocompleteAddParentheses": true,
|
||||
"cmake.copyCompileCommands": "${workspaceFolder}/compile_commands.json"
|
||||
},
|
||||
"launch": {
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "gdb-kddockwidgets_customtitlebar_quick",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev-qtquick/bin/kddockwidgets_customtitlebar_quick",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"MIMode": "gdb",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "gdb-kddockwidgets_example_mdi_quick",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev-qtquick/bin/kddockwidgets_example_mdi_quick",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"MIMode": "gdb",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "gdb-kddockwidgets_example_quick",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev-qtquick/bin/kddockwidgets_example_quick",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"MIMode": "gdb",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "gdb-tst_docks",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev-qtquick/bin/tst_docks",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"MIMode": "gdb",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "lldb-kddockwidgets_customtitlebar_quick",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev-qtquick/bin/kddockwidgets_customtitlebar_quick",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"MIMode": "lldb",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "lldb-kddockwidgets_example_mdi_quick",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev-qtquick/bin/kddockwidgets_example_mdi_quick",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"MIMode": "lldb",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "lldb-kddockwidgets_example_quick",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev-qtquick/bin/kddockwidgets_example_quick",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"MIMode": "lldb",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "lldb-tst_docks",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev-qtquick/bin/tst_docks",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"MIMode": "lldb",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "msvc-kddockwidgets_customtitlebar_quick",
|
||||
"type": "cppvsdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev-qtquick/bin/kddockwidgets_customtitlebar_quick",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "msvc-kddockwidgets_example_mdi_quick",
|
||||
"type": "cppvsdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev-qtquick/bin/kddockwidgets_example_mdi_quick",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "msvc-kddockwidgets_example_quick",
|
||||
"type": "cppvsdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev-qtquick/bin/kddockwidgets_example_quick",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "msvc-tst_docks",
|
||||
"type": "cppvsdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev-qtquick/bin/tst_docks",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
{
|
||||
"folders": [
|
||||
{
|
||||
"path": "."
|
||||
}
|
||||
],
|
||||
"settings": {
|
||||
"C_Cpp.default.compileCommands": "${workspaceFolder}/build-dev/compile_commands.json",
|
||||
"C_Cpp.default.cStandard": "c17",
|
||||
"files.trimTrailingWhitespace": true,
|
||||
"editor.formatOnType": true,
|
||||
"C_Cpp.autocompleteAddParentheses": true,
|
||||
"cmake.copyCompileCommands": "${workspaceFolder}/compile_commands.json"
|
||||
},
|
||||
"launch": {
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "kddockwidgets_example",
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev/bin/kddockwidgets_example",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}"
|
||||
},
|
||||
{
|
||||
"name": "kddockwidgets_minimal_example",
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev/bin/kddockwidgets_minimal_example",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}"
|
||||
},
|
||||
{
|
||||
"name": "kddockwidgets_minimal_mdi_example",
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev/bin/kddockwidgets_minimal_mdi_example",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}"
|
||||
},
|
||||
{
|
||||
"name": "kddockwidgets_mdi_with_docking_example",
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev/bin/kddockwidgets_mdi_with_docking_example",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}"
|
||||
},
|
||||
{
|
||||
"name": "tst_docks",
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev/bin/tst_docks",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}"
|
||||
},
|
||||
{
|
||||
"name": "msvc-kddockwidgets_example",
|
||||
"type": "cppvsdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev/bin/kddockwidgets_example",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "msvc-kddockwidgets_minimal_example",
|
||||
"type": "cppvsdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev/bin/kddockwidgets_minimal_example",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "msvc-kddockwidgets_minimal_mdi_example",
|
||||
"type": "cppvsdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev/bin/kddockwidgets_minimal_mdi_example",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "msvc-tst_docks",
|
||||
"type": "cppvsdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev/bin/tst_docks",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,148 +0,0 @@
|
||||
{
|
||||
"folders": [
|
||||
{
|
||||
"path": "."
|
||||
}
|
||||
],
|
||||
"settings": {
|
||||
"C_Cpp.default.compileCommands": "${workspaceFolder}/build-dev6/compile_commands.json",
|
||||
"C_Cpp.default.cStandard": "c17",
|
||||
"files.trimTrailingWhitespace": true,
|
||||
"editor.formatOnType": true,
|
||||
"C_Cpp.autocompleteAddParentheses": true,
|
||||
"cmake.copyCompileCommands": "${workspaceFolder}/compile_commands.json"
|
||||
},
|
||||
"launch": {
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "gdb-kddockwidgets_example",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev6/bin/kddockwidgets_example",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"MIMode": "gdb",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "gdb-kddockwidgets_minimal_example",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev6/bin/kddockwidgets_minimal_example",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"MIMode": "gdb",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "gdb-kddockwidgets_minimal_mdi_example",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev6/bin/kddockwidgets_minimal_mdi_example",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"MIMode": "gdb",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "gdb-tst_docks",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev6/bin/tst_docks",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"MIMode": "gdb",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "lldb-kddockwidgets_example",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev6/bin/kddockwidgets_example",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"MIMode": "lldb",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "lldb-kddockwidgets_minimal_example",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev6/bin/kddockwidgets_minimal_example",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"MIMode": "lldb",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "lldb-kddockwidgets_minimal_mdi_example",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev6/bin/kddockwidgets_minimal_mdi_example",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"MIMode": "lldb",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "lldb-tst_docks",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev6/bin/tst_docks",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"MIMode": "lldb",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "msvc-kddockwidgets_example",
|
||||
"type": "cppvsdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev6/bin/kddockwidgets_example",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "msvc-kddockwidgets_minimal_example",
|
||||
"type": "cppvsdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev6/bin/kddockwidgets_minimal_example",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "msvc-kddockwidgets_minimal_mdi_example",
|
||||
"type": "cppvsdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev6/bin/kddockwidgets_minimal_mdi_example",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "msvc-tst_docks",
|
||||
"type": "cppvsdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev6/bin/tst_docks",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
176
code.dev.code-workspace
Normal file
176
code.dev.code-workspace
Normal file
@@ -0,0 +1,176 @@
|
||||
{
|
||||
"folders": [
|
||||
{
|
||||
"name": "kddockwidgets",
|
||||
"path": "."
|
||||
},
|
||||
{
|
||||
"path": "/data/sources/kddockwidgets-flutter-example"
|
||||
}
|
||||
],
|
||||
"settings": {
|
||||
"C_Cpp.default.compileCommands": "${workspaceFolder:kddockwidgets}/build-dev/compile_commands.json",
|
||||
"C_Cpp.default.cStandard": "c17",
|
||||
"files.trimTrailingWhitespace": true,
|
||||
"editor.formatOnSave": true,
|
||||
"C_Cpp.autocompleteAddParentheses": true,
|
||||
"clangd.arguments": [
|
||||
"-header-insertion=never"
|
||||
],
|
||||
"todo-tree.tree.scanMode": "workspace only",
|
||||
"todo-tree.tree.disableCompactFolders": false,
|
||||
"todo-tree.tree.showBadges": true,
|
||||
"todo-tree.general.tags": [
|
||||
"BUG",
|
||||
"HACK",
|
||||
"FIXME",
|
||||
"TODO",
|
||||
"XXX",
|
||||
"[ ]",
|
||||
"[x]",
|
||||
"TODOm2",
|
||||
"TODOm3",
|
||||
"TODOm4"
|
||||
],
|
||||
"testMate.cpp.test.executables": "{build-dev}/**/*{tst}*",
|
||||
"todo-tree.filtering.excludeGlobs": [
|
||||
"**/ECM",
|
||||
"**/3rdparty"
|
||||
],
|
||||
"cmake.copyCompileCommands": "${workspaceFolder:kddockwidgets}/compile_commands.json"
|
||||
},
|
||||
"launch": {
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "qtwidgets_dockwidgets",
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder:kddockwidgets}/build-dev/bin/examples/qtwidgets_dockwidgets",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder:kddockwidgets}"
|
||||
},
|
||||
{
|
||||
"name": "qtwidgets_minimal",
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder:kddockwidgets}/build-dev/bin/examples/qtwidgets_minimal",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder:kddockwidgets}"
|
||||
},
|
||||
{
|
||||
"name": "qtwidgets_mdi",
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder:kddockwidgets}/build-dev/bin/examples/qtwidgets_mdi",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder:kddockwidgets}"
|
||||
},
|
||||
{
|
||||
"name": "qtwidgets_mdi_with_docking",
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder:kddockwidgets}/build-dev/bin/examples/qtwidgets_mdi_with_docking",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder:kddockwidgets}"
|
||||
},
|
||||
{
|
||||
"name": "qtquick_dockwidgets",
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder:kddockwidgets}/build-dev/bin/examples/qtquick_dockwidgets",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder:kddockwidgets}"
|
||||
},
|
||||
{
|
||||
"name": "qtquick_customtitlebar",
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder:kddockwidgets}/build-dev/bin/examples/qtquick_customtitlebar",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder:kddockwidgets}"
|
||||
},
|
||||
{
|
||||
"name": "tst_docks",
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder:kddockwidgets}/build-dev/bin/tst_docks",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder:kddockwidgets}"
|
||||
},
|
||||
{
|
||||
"name": "tst_droparea",
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder:kddockwidgets}/build-dev/bin/tst_droparea",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder:kddockwidgets}"
|
||||
},
|
||||
{
|
||||
"name": "tst_dockwidget",
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder:kddockwidgets}/build-dev/bin/tst_dockwidget",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder:kddockwidgets}"
|
||||
},
|
||||
{
|
||||
"name": "tst_group",
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder:kddockwidgets}/build-dev/bin/tst_group",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder:kddockwidgets}"
|
||||
},
|
||||
{
|
||||
"name": "tst_separator",
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder:kddockwidgets}/build-dev/bin/tst_separator",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder:kddockwidgets}"
|
||||
},
|
||||
{
|
||||
"name": "tst_stack",
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder:kddockwidgets}/build-dev/bin/tst_stack",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder:kddockwidgets}"
|
||||
},
|
||||
{
|
||||
"name": "tst_tabbar",
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder:kddockwidgets}/build-dev/bin/tst_tabbar",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder:kddockwidgets}"
|
||||
},
|
||||
{
|
||||
"name": "tst_floatingwindow",
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder:kddockwidgets}/build-dev/bin/tst_floatingwindow",
|
||||
"cwd": "${workspaceFolder:kddockwidgets}"
|
||||
},
|
||||
{
|
||||
"name": "tst_qtwidgets",
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder:kddockwidgets}/build-dev/bin/tst_qtwidgets",
|
||||
"args": [
|
||||
"tst_mainWindowAlwaysHasCentralWidget"
|
||||
],
|
||||
"cwd": "${workspaceFolder:kddockwidgets}"
|
||||
},
|
||||
{
|
||||
"name": "tst_qtquick",
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder:kddockwidgets}/build-dev/bin/tst_qtquick",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder:kddockwidgets}"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
142
code.dev6.code-workspace
Normal file
142
code.dev6.code-workspace
Normal file
@@ -0,0 +1,142 @@
|
||||
{
|
||||
"folders": [
|
||||
{
|
||||
"path": "."
|
||||
}
|
||||
],
|
||||
"settings": {
|
||||
"C_Cpp.default.compileCommands": "${workspaceFolder}/build-dev6/compile_commands.json",
|
||||
"C_Cpp.default.cStandard": "c17",
|
||||
"files.trimTrailingWhitespace": true,
|
||||
"editor.formatOnSave": true,
|
||||
"C_Cpp.autocompleteAddParentheses": true,
|
||||
"clangd.arguments": [
|
||||
"-header-insertion=never"
|
||||
],
|
||||
"todo-tree.tree.scanMode": "workspace only",
|
||||
"todo-tree.tree.disableCompactFolders": false,
|
||||
"todo-tree.tree.showBadges": true,
|
||||
"todo-tree.filtering.excludeGlobs": [
|
||||
"**/ECM",
|
||||
"**/3rdparty"
|
||||
],
|
||||
"todo-tree.general.tags": [
|
||||
"BUG",
|
||||
"HACK",
|
||||
"FIXME",
|
||||
"TODO",
|
||||
"XXX",
|
||||
"[ ]",
|
||||
"[x]",
|
||||
"TODOm2",
|
||||
"TODOm3",
|
||||
"TODOm4"
|
||||
],
|
||||
"testMate.cpp.test.executables": "{build-dev6}/**/*{tst}*"
|
||||
},
|
||||
"launch": {
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "qtwidgets_dockwidgets",
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev6/bin/examples/qtwidgets_dockwidgets",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}"
|
||||
},
|
||||
{
|
||||
"name": "qtwidgets_minimal",
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev6/bin/examples/qtwidgets_minimal",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}"
|
||||
},
|
||||
{
|
||||
"name": "qtwidgets_mdi",
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev6/bin/examples/qtwidgets_mdi",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}"
|
||||
},
|
||||
{
|
||||
"name": "qtwidgets_mdi_with_docking",
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev6/bin/examples/qtwidgets_mdi_with_docking",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}"
|
||||
},
|
||||
{
|
||||
"name": "qtquick_dockwidgets",
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev6/bin/examples/qtquick_dockwidgets",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}"
|
||||
},
|
||||
{
|
||||
"name": "tst_docks",
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev6/bin/tst_docks",
|
||||
"args": [
|
||||
"tst_addMDIDockWidget"
|
||||
],
|
||||
"cwd": "${workspaceFolder}"
|
||||
},
|
||||
{
|
||||
"name": "msvc-qtwidgets_dockwidgets",
|
||||
"type": "cppvsdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev6/bin/examples/qtwidgets_dockwidgets",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "msvc-qtwidgets_minimal",
|
||||
"type": "cppvsdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev6/bin/examples/qtwidgets_minimal",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "msvc-qtwidgets_mdi",
|
||||
"type": "cppvsdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev6/bin/examples/qtwidgets_mdi",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "msvc-qtquick_dockwidgets",
|
||||
"type": "cppvsdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev6/bin/examples/qtquick_dockwidgets.exe",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
},
|
||||
{
|
||||
"name": "msvc-tst_docks",
|
||||
"type": "cppvsdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build-dev6/bin/tst_docks",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"stopAtEntry": false,
|
||||
"externalConsole": false
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@ from conans import ConanFile, CMake, tools
|
||||
|
||||
class KDDockWidgetsConan(ConanFile):
|
||||
name = "kddockwidgets"
|
||||
version = "1.6.95"
|
||||
version = "1.5.0"
|
||||
default_user = "kdab"
|
||||
default_channel = "stable"
|
||||
license = ("https://raw.githubusercontent.com/KDAB/KDDockWidgets/master/LICENSES/GPL-2.0-only.txt",
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
kddockwidgets (1.6.0) release candidate; urgency=high
|
||||
|
||||
* 1.6.0 final
|
||||
|
||||
-- Allen Winter <allen.winter@kdab.com> Wed, 14 Sep 2022 11:40:00 -0500
|
||||
|
||||
kddockwidgets (1.5.0) release candidate; urgency=high
|
||||
|
||||
* 1.5.0 final
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#!/usr/bin/make -f
|
||||
DEB_CMAKE_EXTRA_FLAGS = -DCMAKE_BUILD_TYPE=Release
|
||||
include /usr/share/cdbs/1/rules/debhelper.mk
|
||||
include /usr/share/cdbs/1/class/cmake.mk
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
Format: 1.0
|
||||
Source: kddockwidgets
|
||||
Version: 1.6.0-1
|
||||
Version: 1.5.0-1
|
||||
Binary: kddockwidgets
|
||||
Maintainer: Allen Winter <allen.winter@kdab.com>
|
||||
Architecture: any
|
||||
Build-Depends: debhelper (>=9), cdbs, cmake, qtbase5-dev, qtbase5-private-dev, libqt5x11extras5-dev, libfontconfig-dev, libfreetype-dev
|
||||
|
||||
Files:
|
||||
00000000000000000000000000000000 00000 qt5-kddockwidgets-1.6.0.tar.gz
|
||||
00000000000000000000000000000000 00000 qt5-kddockwidgets-1.5.0.tar.gz
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
Name: qt5-kddockwidgets
|
||||
Version: 1.6.0
|
||||
Version: 1.5.0
|
||||
Release: 1
|
||||
Summary: KDAB's Dock Widget Framework for Qt5
|
||||
Source0: %{name}-%{version}.tar.gz
|
||||
@@ -98,8 +98,6 @@ cmake . -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release
|
||||
%{_libdir}/libkddockwidgets.so
|
||||
|
||||
%changelog
|
||||
* Wed Sep 14 2022 Allen Winter <allen.winter@kdab.com> 1.6.0
|
||||
1.6.0 final
|
||||
* Mon Nov 24 2021 Allen Winter <allen.winter@kdab.com> 1.5.0
|
||||
1.5.0 final
|
||||
* Fri Jul 16 2021 Allen Winter <allen.winter@kdab.com> 1.4.0
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
Format: 1.0
|
||||
Source: kddockwidgets
|
||||
Version: 1.6.0-1
|
||||
Version: 1.5.0-1
|
||||
Binary: kddockwidgets
|
||||
Maintainer: Allen Winter <allen.winter@kdab.com>
|
||||
Architecture: any
|
||||
Build-Depends: debhelper (>=9), cdbs, cmake, qt6-base-dev, qt6-base-private-dev, libgl1-mesa-dev, libfontconfig-dev, libfreetype-dev
|
||||
|
||||
Files:
|
||||
00000000000000000000000000000000 00000 qt6-kddockwidgets-1.6.0.tar.gz
|
||||
00000000000000000000000000000000 00000 qt6-kddockwidgets-1.5.0.tar.gz
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
Name: qt6-kddockwidgets
|
||||
Version: 1.6.0
|
||||
Version: 1.5.0
|
||||
Release: 1
|
||||
Summary: KDAB's Dock Widget Framework for Qt6
|
||||
Source0: %{name}-%{version}.tar.gz
|
||||
@@ -18,7 +18,7 @@ BuildRequires: libqt6-qtbase-devel libqt6-qtbase-private-headers-devel libqt6-q
|
||||
%endif
|
||||
|
||||
%if %{defined fedora}
|
||||
BuildRequires: gcc-c++ qt6-qtbase-devel qt6-qtbase-private-devel desktop-file-utils libxkbcommon-devel util-linux
|
||||
BuildRequires: gcc-c++ qt6-qtbase-devel qt6-qtbase-private-devel desktop-file-utils libxkbcommon-devel
|
||||
%endif
|
||||
|
||||
%if %{defined rhel}
|
||||
@@ -79,21 +79,14 @@ cmake . -DCMAKE_INSTALL_PREFIX=/usr -DKDDockWidgets_QT6=True -DCMAKE_BUILD_TYPE=
|
||||
|
||||
%files devel
|
||||
%defattr(-,root,root,-)
|
||||
%if 0%{?fedora} > 35
|
||||
%{_libdir}/qt6/mkspecs/modules/*
|
||||
%endif
|
||||
#%dir %{_prefix}/share/mkspecs
|
||||
#%dir %{_prefix}/share/mkspecs/features
|
||||
#%{_prefix}/share/mkspecs/features/kddockwidgets.prf
|
||||
%dir %{_includedir}/kddockwidgets-qt6
|
||||
%{_includedir}/kddockwidgets-qt6/kddockwidgets/*
|
||||
%dir %{_libdir}/cmake/KDDockWidgets-qt6
|
||||
%{_libdir}/cmake/KDDockWidgets-qt6/*
|
||||
%{_libdir}/libkddockwidgets-qt6.so
|
||||
#%{_prefix}/mkspecs/modules/* ECMGeneratePriFile isn't ported to Qt6 yet
|
||||
|
||||
%changelog
|
||||
* Wed Sep 14 2022 Allen Winter <allen.winter@kdab.com> 1.6.0
|
||||
1.6.0 final
|
||||
* Mon Nov 24 2021 Allen Winter <allen.winter@kdab.com> 1.5.0
|
||||
1.5.0 final
|
||||
* Fri Jul 16 2021 Allen Winter <allen.winter@kdab.com> 1.4.0
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
# $ docker build -t kddw-pyside2 .
|
||||
# $ docker run -it -v ~/Qt/5.15.2/gcc_64/:/Qt/ -v /tmp/.X11-unix:/tmp/.X11-unix kddw-pyside2
|
||||
# git checkout 1.6
|
||||
# git checkout 2.0
|
||||
# cmake --preset=python -G Ninja . && cd build-python/ && ninja
|
||||
|
||||
# Test with:
|
||||
|
||||
@@ -40,16 +40,17 @@ endif()
|
||||
file(GLOB _dox_deps *.dox *.html)
|
||||
set(DOXYGEN_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
#apidox generation using doxygen
|
||||
# apidox generation using doxygen
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.cmake ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${DOXYGEN_OUTPUT_DIR}/qch/kddockwidgets-api.qch
|
||||
COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
|
||||
#handle a bug in doxygen where image files referred to in markdown are not copied the output
|
||||
# handle a bug in doxygen where image files referred to in markdown are not
|
||||
# copied the output
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/../../screencap.gif
|
||||
${DOXYGEN_OUTPUT_DIR}/html
|
||||
#copy some files by-hand that are referred to by the markdown README
|
||||
# copy some files by-hand that are referred to by the markdown README
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/README-bindings.md ${DOXYGEN_OUTPUT_DIR}/html
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${DOXYGEN_OUTPUT_DIR}/html/LICENSES
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/LICENSES/GPL-2.0-only.txt
|
||||
@@ -67,7 +68,7 @@ add_custom_command(
|
||||
add_custom_target(
|
||||
kddockwidgets-api.qch ALL
|
||||
DEPENDS ${DOXYGEN_OUTPUT_DIR}/qch/kddockwidgets-api.qch
|
||||
COMMENT "Target generate the .qch file"
|
||||
COMMENT "Target to generate the .qch file"
|
||||
)
|
||||
add_custom_target(
|
||||
docs
|
||||
@@ -79,11 +80,5 @@ set(QCH_INSTALL_DIR
|
||||
${INSTALL_DOC_DIR}
|
||||
CACHE STRING "Install location of Qt Assistant help files."
|
||||
)
|
||||
install(
|
||||
FILES ${DOXYGEN_OUTPUT_DIR}/qch/kddockwidgets-api.qch
|
||||
DESTINATION ${QCH_INSTALL_DIR}
|
||||
)
|
||||
install(
|
||||
FILES ${DOXYGEN_OUTPUT_DIR}/kddockwidgets.tags
|
||||
DESTINATION ${INSTALL_DOC_DIR}
|
||||
)
|
||||
install(FILES ${DOXYGEN_OUTPUT_DIR}/qch/kddockwidgets-api.qch DESTINATION ${QCH_INSTALL_DIR})
|
||||
install(FILES ${DOXYGEN_OUTPUT_DIR}/kddockwidgets.tags DESTINATION ${INSTALL_DOC_DIR})
|
||||
|
||||
@@ -845,7 +845,6 @@ WARN_LOGFILE = doxygen.log
|
||||
# Note: If this tag is empty the current directory is searched.
|
||||
|
||||
INPUT = "@CMAKE_SOURCE_DIR@/README.md" \
|
||||
"@CMAKE_SOURCE_DIR@/README-bindings.md" \
|
||||
"@CMAKE_SOURCE_DIR@/src"
|
||||
|
||||
# This tag can be used to specify the character encoding of the source files
|
||||
|
||||
1
docs_devel/about.md
Normal file
1
docs_devel/about.md
Normal file
@@ -0,0 +1 @@
|
||||
# About
|
||||
82
docs_devel/concepts.md
Normal file
82
docs_devel/concepts.md
Normal file
@@ -0,0 +1,82 @@
|
||||
# Concepts
|
||||
|
||||
Before digging into code we need to learn some high level concepts which will make it easy
|
||||
to learn the API afterwards.
|
||||
|
||||
## Views or Widgets
|
||||
|
||||
A view, or widget is the most basic GUI element usually provided by your framework.
|
||||
KDDockWidget's has its roots in the Qt QWidget GUI framework, hence the term widget
|
||||
will appear in many places. However, since KDDW's goal is to support other GUI toolkits,
|
||||
we've introduced a more generic term, view.
|
||||
|
||||
For the QtWidget frontend, a view will be internally implemented as a QWidget, while for
|
||||
the QtQuick frontend it will be implemented as a QQuickItem.
|
||||
|
||||
## Guest View
|
||||
|
||||
This is the view that the user (library user) wants to dock. It has some custom content that
|
||||
is only relevant for the application. From KDDW's perspective we don't care what's inside,
|
||||
we'll just help dock it.
|
||||
|
||||
## DockWidget
|
||||
|
||||
The DockWidget is a visual container for the Guest, in other words, its visual parent.
|
||||
Visually, DockWidget and Guest might be indistinguishable, except for some margin added by
|
||||
DockWidget. One reason to have this extra indirection is that it allows us to have a common API
|
||||
to deal with the Guest. Since guest is provided by the application developer it doesn't have any interface.
|
||||
|
||||
## TitleBar
|
||||
|
||||
A TitleBar is the area that has the dock widget title and the float and close buttons.
|
||||
Usually KDDW won't use native OS title bars but draw its own.
|
||||
|
||||
## TabBar
|
||||
|
||||
DockWidgets can be grouped together in tabs. A tab bar is just a group of tabs.
|
||||
In Qt this is something like QTabBar.
|
||||
|
||||
## Stack
|
||||
|
||||
A stack is closely related to TabBar. A stack is a group of dock widgets where only one is visible
|
||||
at a time, the visible one is controlled by the current tab. In Qt this would be QTabWidget.
|
||||
|
||||
## Frame
|
||||
|
||||
The Frame is a container that ties the previous concepts all together.
|
||||
It's composed of 1 or more tabbed DockWidgets, a TitleBar, a Stack and a TabBar.
|
||||
|
||||
## Layout
|
||||
|
||||
Represents a docking layout. Currently 2 are supported, the traditional nested docking with
|
||||
resizable splitters (this is the default), implemented by MultiSplitter. And a MDI layout, where
|
||||
the dock widgets can be arbitrary positioned and even overlap inside an area.
|
||||
|
||||
The layouts deal in Frame. You add Frame objects to a layout.
|
||||
|
||||
## Separator
|
||||
|
||||
A visual separator between two widgets, which allows the user to resize dock widgets with mouse.
|
||||
|
||||
## FloatingWindow
|
||||
|
||||
When a dock widget isn't embedded into a window it's said to be floating. It's its own
|
||||
top-level native window. This class ties all the previous together. It contains one layout, which
|
||||
contains multiple groups.
|
||||
|
||||
## MainWindow
|
||||
|
||||
Not much different from FloatingWindow technically, but users will often add status bar, tool bar
|
||||
and menu bars to a main window, while FloatingWindow is just an utility window (Qt::Tool).
|
||||
MainWindow also has support for a SideBar.
|
||||
|
||||
## SideBar
|
||||
|
||||
A side bar is a place in the MainWindow where you can "minimize" dock widgets.
|
||||
It's also called the auto-hide future. When you send a dock widget to the sidebar it will close
|
||||
but show a button in the sidebar, if you press it, it will show the dock widget as an overlay.
|
||||
|
||||
## Drop Indicators
|
||||
|
||||
When dragging a dock widgets, KDDW will highlight the places where you can drop it, so
|
||||
it embeds in the correct position.
|
||||
1
docs_devel/index.md
Normal file
1
docs_devel/index.md
Normal file
@@ -0,0 +1 @@
|
||||
# Welcome to KDDockWidgets
|
||||
11
docs_devel/new_frontend.md
Normal file
11
docs_devel/new_frontend.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# Creating a new frontend
|
||||
|
||||
- Copy `src/dummy/` into `src/yourfrontend/`
|
||||
- Rename the files from `_dummy` to `_yourfrontend`
|
||||
- Edit `CMakeLists.txt` and `src/CMakeLists.txt`
|
||||
- Edit the `FrontendType` enum in `KDDockWidgets.h` and add a new enumerator for your frontend
|
||||
- Edit `Platform::frontendTypes()` in `Platform.cpp` and honour your new enumerator, properly ifdefed
|
||||
- In `Platform.cpp` add the needed `#include "yourplatform/Platform_yourplatform.h` include
|
||||
- Edit `Platform::tests_initPlatform()` and add your enumerator
|
||||
- Edit `Platform_yourfrontend::name()` to return an ID for your frontend
|
||||
- Run `./bin/tst_platform -tc="Platform::Platform,Platform::name"` , make sure it passes
|
||||
@@ -10,30 +10,20 @@
|
||||
#
|
||||
|
||||
cmake_minimum_required(VERSION 3.7)
|
||||
project(kddockwidgets_example)
|
||||
project(qtwidgets_dockwidgets)
|
||||
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
set(CMAKE_INCLUDE_CURRENT_DIRS ON)
|
||||
|
||||
if(NOT TARGET kddockwidgets)
|
||||
# This will look for Qt, do find_package yourself manually before
|
||||
# if you want to look for a specific Qt version for instance.
|
||||
# This will look for Qt, do find_package yourself manually before if you want
|
||||
# to look for a specific Qt version for instance.
|
||||
find_package(KDDockWidgets REQUIRED)
|
||||
endif()
|
||||
|
||||
set(RESOURCES_EXAMPLE_SRC ${CMAKE_CURRENT_SOURCE_DIR}/resources_example.qrc)
|
||||
|
||||
add_executable(
|
||||
kddockwidgets_example
|
||||
${RESOURCES_EXAMPLE_SRC}
|
||||
main.cpp
|
||||
MyFrameworkWidgetFactory.cpp
|
||||
MyMainWindow.cpp
|
||||
MyWidget.cpp
|
||||
)
|
||||
add_executable(qtwidgets_dockwidgets main.cpp MyViewFactory.cpp MyMainWindow.cpp MyWidget.cpp ${RESOURCES_EXAMPLE_SRC})
|
||||
|
||||
target_link_libraries(
|
||||
kddockwidgets_example
|
||||
PRIVATE KDAB::kddockwidgets
|
||||
)
|
||||
target_link_libraries(qtwidgets_dockwidgets PRIVATE KDAB::kddockwidgets)
|
||||
|
||||
@@ -1,106 +0,0 @@
|
||||
/*
|
||||
This file is part of KDDockWidgets.
|
||||
|
||||
SPDX-FileCopyrightText: 2019-2022 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
|
||||
Author: Sérgio Martins <sergio.martins@kdab.com>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
Contact KDAB at <info@kdab.com> for commercial licensing options.
|
||||
*/
|
||||
|
||||
#include "MyFrameworkWidgetFactory.h"
|
||||
#include "MyTitleBar_CSS.h"
|
||||
|
||||
#include <kddockwidgets/FrameworkWidgetFactory.h>
|
||||
|
||||
#include <kddockwidgets/private/TabWidget_p.h>
|
||||
#include <kddockwidgets/private/widgets/FrameWidget_p.h>
|
||||
#include <kddockwidgets/private/widgets/TabBarWidget_p.h>
|
||||
#include <kddockwidgets/private/widgets/TabWidgetWidget_p.h>
|
||||
#include <kddockwidgets/private/widgets/TitleBarWidget_p.h>
|
||||
#include <kddockwidgets/private/multisplitter/Separator_qwidget.h>
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
// clazy:excludeall=missing-qobject-macro,ctor-missing-parent-argument
|
||||
|
||||
class MyTitleBar : public KDDockWidgets::TitleBarWidget
|
||||
{
|
||||
public:
|
||||
explicit MyTitleBar(KDDockWidgets::Frame *frame)
|
||||
: KDDockWidgets::TitleBarWidget(frame)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
explicit MyTitleBar(KDDockWidgets::FloatingWindow *fw)
|
||||
: KDDockWidgets::TitleBarWidget(fw)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
~MyTitleBar() override;
|
||||
|
||||
void init()
|
||||
{
|
||||
setFixedHeight(60);
|
||||
}
|
||||
|
||||
void paintEvent(QPaintEvent *) override
|
||||
{
|
||||
QPainter p(this);
|
||||
QPen pen(Qt::black);
|
||||
const QColor focusedBackgroundColor = Qt::yellow;
|
||||
const QColor backgroundColor = focusedBackgroundColor.darker(115);
|
||||
QBrush brush(isFocused() ? focusedBackgroundColor : backgroundColor);
|
||||
pen.setWidth(4);
|
||||
p.setPen(pen);
|
||||
p.setBrush(brush);
|
||||
p.drawRect(rect().adjusted(4, 4, -4, -4));
|
||||
QFont f = qApp->font();
|
||||
f.setPixelSize(30);
|
||||
f.setBold(true);
|
||||
p.setFont(f);
|
||||
p.drawText(QPoint(10, 40), title());
|
||||
}
|
||||
};
|
||||
|
||||
MyTitleBar::~MyTitleBar() = default;
|
||||
|
||||
// Inheriting from SeparatorWidget instead of Separator as it handles moving and mouse cursor changing
|
||||
class MySeparator : public Layouting::SeparatorWidget
|
||||
{
|
||||
public:
|
||||
explicit MySeparator(Layouting::Widget *parent)
|
||||
: Layouting::SeparatorWidget(parent)
|
||||
{
|
||||
}
|
||||
|
||||
~MySeparator() override;
|
||||
|
||||
void paintEvent(QPaintEvent *) override
|
||||
{
|
||||
QPainter p(this);
|
||||
p.fillRect(QWidget::rect(), Qt::cyan);
|
||||
}
|
||||
};
|
||||
|
||||
MySeparator::~MySeparator() = default;
|
||||
|
||||
KDDockWidgets::TitleBar *CustomWidgetFactory::createTitleBar(KDDockWidgets::Frame *frame) const
|
||||
{
|
||||
// Feel free to return MyTitleBar_CSS here instead, but just for education purposes!
|
||||
return new MyTitleBar(frame);
|
||||
}
|
||||
|
||||
KDDockWidgets::TitleBar *CustomWidgetFactory::createTitleBar(KDDockWidgets::FloatingWindow *fw) const
|
||||
{
|
||||
// Feel free to return MyTitleBar_CSS here instead, but just for education purposes!
|
||||
return new MyTitleBar(fw);
|
||||
}
|
||||
|
||||
Layouting::Separator *CustomWidgetFactory::createSeparator(Layouting::Widget *parent) const
|
||||
{
|
||||
return new MySeparator(parent);
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
This file is part of KDDockWidgets.
|
||||
|
||||
SPDX-FileCopyrightText: 2019-2022 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
|
||||
Author: Sérgio Martins <sergio.martins@kdab.com>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
Contact KDAB at <info@kdab.com> for commercial licensing options.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <kddockwidgets/FrameworkWidgetFactory.h>
|
||||
|
||||
#include <QPainter>
|
||||
|
||||
// clazy:excludeall=ctor-missing-parent-argument
|
||||
|
||||
class CustomWidgetFactory : public KDDockWidgets::DefaultWidgetFactory
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
KDDockWidgets::TitleBar *createTitleBar(KDDockWidgets::Frame *frame) const override;
|
||||
KDDockWidgets::TitleBar *createTitleBar(KDDockWidgets::FloatingWindow *fw) const override;
|
||||
Layouting::Separator *createSeparator(Layouting::Widget *parent = nullptr) const override;
|
||||
};
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
This file is part of KDDockWidgets.
|
||||
|
||||
SPDX-FileCopyrightText: 2019-2022 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
|
||||
Author: Sérgio Martins <sergio.martins@kdab.com>
|
||||
SPDX-FileCopyrightText: 2019-2022 Klarälvdalens Datakonsult AB, a KDAB Group company
|
||||
<info@kdab.com> Author: Sérgio Martins <sergio.martins@kdab.com>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
@@ -45,11 +45,11 @@ static MyWidget *newMyWidget()
|
||||
}
|
||||
|
||||
MyMainWindow::MyMainWindow(const QString &uniqueName, KDDockWidgets::MainWindowOptions options,
|
||||
bool dockWidget0IsNonClosable, bool nonDockableDockWidget9, bool restoreIsRelative,
|
||||
bool maxSizeForDockWidget8, bool dockwidget5DoesntCloseBeforeRestore,
|
||||
bool dock0BlocksCloseEvent,
|
||||
bool dockWidget0IsNonClosable, bool nonDockableDockWidget9,
|
||||
bool restoreIsRelative, bool maxSizeForDockWidget8,
|
||||
bool dockwidget5DoesntCloseBeforeRestore, bool dock0BlocksCloseEvent,
|
||||
const QString &affinityName, QWidget *parent)
|
||||
: MainWindow(uniqueName, options, parent)
|
||||
: KDDockWidgets::Views::MainWindow_qtwidgets(uniqueName, options, parent)
|
||||
, m_dockWidget0IsNonClosable(dockWidget0IsNonClosable)
|
||||
, m_dockWidget9IsNonDockable(nonDockableDockWidget9)
|
||||
, m_restoreIsRelative(restoreIsRelative)
|
||||
@@ -73,10 +73,11 @@ MyMainWindow::MyMainWindow(const QString &uniqueName, KDDockWidgets::MainWindowO
|
||||
count++;
|
||||
auto w = newMyWidget();
|
||||
w->setGeometry(100, 100, 400, 400);
|
||||
auto dock = new KDDockWidgets::DockWidget(QStringLiteral("new dock %1").arg(count));
|
||||
auto dock = new KDDockWidgets::Views::DockWidget_qtwidgets(
|
||||
QStringLiteral("new dock %1").arg(count));
|
||||
dock->setWidget(w);
|
||||
dock->resize(600, 600);
|
||||
dock->show();
|
||||
dock->resize(QSize(600, 600));
|
||||
dock->open();
|
||||
});
|
||||
|
||||
auto saveLayoutAction = fileMenu->addAction(QStringLiteral("Save Layout"));
|
||||
@@ -103,12 +104,13 @@ MyMainWindow::MyMainWindow(const QString &uniqueName, KDDockWidgets::MainWindowO
|
||||
});
|
||||
|
||||
auto layoutEqually = fileMenu->addAction(QStringLiteral("Layout Equally"));
|
||||
connect(layoutEqually, &QAction::triggered, this, &MainWindow::layoutEqually);
|
||||
connect(layoutEqually, &QAction::triggered, this, [this] { this->layoutEqually(); });
|
||||
|
||||
auto quitAction = fileMenu->addAction(QStringLiteral("Quit"));
|
||||
connect(quitAction, &QAction::triggered, qApp, &QApplication::quit);
|
||||
|
||||
QAction *toggleDropIndicatorSupport = miscMenu->addAction(QStringLiteral("Toggle Drop Indicator Support"));
|
||||
QAction *toggleDropIndicatorSupport =
|
||||
miscMenu->addAction(QStringLiteral("Toggle Drop Indicator Support"));
|
||||
toggleDropIndicatorSupport->setCheckable(true);
|
||||
toggleDropIndicatorSupport->setChecked(true);
|
||||
connect(toggleDropIndicatorSupport, &QAction::toggled, this, [](bool checked) {
|
||||
@@ -134,8 +136,8 @@ void MyMainWindow::createDockWidgets()
|
||||
|
||||
const int numDockWidgets = m_dockWidget9IsNonDockable ? 10 : 9;
|
||||
|
||||
|
||||
// Create 9 KDDockWidget::DockWidget and the respective widgets they're hosting (MyWidget instances)
|
||||
// Create 9 KDDockWidget::DockWidget and the respective widgets they're hosting (MyWidget
|
||||
// instances)
|
||||
for (int i = 0; i < numDockWidgets; i++)
|
||||
m_dockwidgets << newDockWidget();
|
||||
|
||||
@@ -157,31 +159,34 @@ void MyMainWindow::createDockWidgets()
|
||||
m_dockwidgets[6]->addDockWidgetAsTab(m_dockwidgets.at(7));
|
||||
|
||||
// Floating windows also support nesting, here we add 8 to the bottom of the group
|
||||
m_dockwidgets[6]->addDockWidgetToContainingWindow(m_dockwidgets.at(8), KDDockWidgets::Location_OnBottom);
|
||||
m_dockwidgets[6]->addDockWidgetToContainingWindow(m_dockwidgets.at(8),
|
||||
KDDockWidgets::Location_OnBottom);
|
||||
|
||||
auto floatingWindow = m_dockwidgets.at(6)->window();
|
||||
auto floatingWindow = m_dockwidgets.at(6)->rootView();
|
||||
floatingWindow->move(100, 100);
|
||||
}
|
||||
|
||||
KDDockWidgets::DockWidgetBase *MyMainWindow::newDockWidget()
|
||||
KDDockWidgets::Views::DockWidget_qtwidgets *MyMainWindow::newDockWidget()
|
||||
{
|
||||
static int count = 0;
|
||||
|
||||
// Passing options is optional, we just want to illustrate Option_NotClosable here
|
||||
KDDockWidgets::DockWidget::Options options = KDDockWidgets::DockWidget::Option_None;
|
||||
KDDockWidgets::DockWidget::LayoutSaverOptions layoutSaverOptions = KDDockWidgets::DockWidget::LayoutSaverOption::None;
|
||||
KDDockWidgets::DockWidgetOptions options = KDDockWidgets::DockWidgetOption_None;
|
||||
KDDockWidgets::LayoutSaverOptions layoutSaverOptions = KDDockWidgets::LayoutSaverOption::None;
|
||||
|
||||
if (count == 0 && m_dockWidget0IsNonClosable)
|
||||
options |= KDDockWidgets::DockWidget::Option_NotClosable;
|
||||
options |= KDDockWidgets::DockWidgetOption_NotClosable;
|
||||
|
||||
if (count == 9 && m_dockWidget9IsNonDockable)
|
||||
options |= KDDockWidgets::DockWidget::Option_NotDockable;
|
||||
options |= KDDockWidgets::DockWidgetOption_NotDockable;
|
||||
|
||||
if (count == 5 && m_dockwidget5DoesntCloseBeforeRestore)
|
||||
layoutSaverOptions |= KDDockWidgets::DockWidget::LayoutSaverOption::Skip;
|
||||
layoutSaverOptions |= KDDockWidgets::LayoutSaverOption::Skip;
|
||||
|
||||
auto dock = new KDDockWidgets::DockWidget(QStringLiteral("DockWidget #%1").arg(count), options, layoutSaverOptions);
|
||||
dock->setAffinities(affinities()); // optional, just to show the feature. Pass -mi to the example to see incompatible dock widgets
|
||||
auto dock = new KDDockWidgets::Views::DockWidget_qtwidgets(
|
||||
QStringLiteral("DockWidget #%1").arg(count), options, layoutSaverOptions);
|
||||
dock->setAffinities(affinities()); // optional, just to show the feature. Pass -mi to the
|
||||
// example to see incompatible dock widgets
|
||||
|
||||
if (count == 1)
|
||||
dock->setIcon(QIcon::fromTheme(QStringLiteral("mail-message")));
|
||||
@@ -197,13 +202,13 @@ KDDockWidgets::DockWidgetBase *MyMainWindow::newDockWidget()
|
||||
|
||||
dock->setWidget(myWidget);
|
||||
|
||||
if (dock->options() & KDDockWidgets::DockWidget::Option_NotDockable) {
|
||||
if (dock->options() & KDDockWidgets::DockWidgetOption_NotDockable) {
|
||||
dock->setTitle(QStringLiteral("DockWidget #%1 (%2)").arg(count).arg("non dockable"));
|
||||
} else {
|
||||
dock->setTitle(QStringLiteral("DockWidget #%1").arg(count));
|
||||
}
|
||||
|
||||
dock->resize(600, 600);
|
||||
dock->resize(QSize(600, 600));
|
||||
m_toggleMenu->addAction(dock->toggleAction());
|
||||
dock->toggleAction()->setShortcut(QStringLiteral("ctrl+%1").arg(count));
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
This file is part of KDDockWidgets.
|
||||
|
||||
SPDX-FileCopyrightText: 2019-2022 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
|
||||
Author: Sérgio Martins <sergio.martins@kdab.com>
|
||||
SPDX-FileCopyrightText: 2019-2022 Klarälvdalens Datakonsult AB, a KDAB Group company
|
||||
<info@kdab.com> Author: Sérgio Martins <sergio.martins@kdab.com>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
@@ -14,20 +14,22 @@
|
||||
#include <kddockwidgets/DockWidget.h>
|
||||
#include <kddockwidgets/MainWindow.h>
|
||||
|
||||
class MyMainWindow : public KDDockWidgets::MainWindow
|
||||
class MyMainWindow : public KDDockWidgets::Views::MainWindow_qtwidgets
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MyMainWindow(const QString &uniqueName, KDDockWidgets::MainWindowOptions options,
|
||||
bool dockWidget0IsNonClosable, bool nonDockableDockWidget9, bool restoreIsRelative,
|
||||
bool maxSizeForDockWidget8, bool dockwidget5DoesntCloseBeforeRestore, bool dock0BlocksCloseEvent,
|
||||
const QString &affinityName = {}, // Usually not needed. Just here to show the feature.
|
||||
bool dockWidget0IsNonClosable, bool nonDockableDockWidget9,
|
||||
bool restoreIsRelative, bool maxSizeForDockWidget8,
|
||||
bool dockwidget5DoesntCloseBeforeRestore, bool dock0BlocksCloseEvent,
|
||||
const QString &affinityName = {}, // Usually not needed. Just here to show
|
||||
// the feature.
|
||||
QWidget *parent = nullptr);
|
||||
~MyMainWindow() override;
|
||||
|
||||
private:
|
||||
void createDockWidgets();
|
||||
KDDockWidgets::DockWidgetBase *newDockWidget();
|
||||
KDDockWidgets::Views::DockWidget_qtwidgets *newDockWidget();
|
||||
QMenu *m_toggleMenu = nullptr;
|
||||
const bool m_dockWidget0IsNonClosable;
|
||||
const bool m_dockWidget9IsNonDockable;
|
||||
@@ -35,5 +37,5 @@ private:
|
||||
const bool m_maxSizeForDockWidget8;
|
||||
const bool m_dockwidget5DoesntCloseBeforeRestore;
|
||||
const bool m_dock0BlocksCloseEvent;
|
||||
KDDockWidgets::DockWidget::List m_dockwidgets;
|
||||
QVector<KDDockWidgets::Views::DockWidget_qtwidgets *> m_dockwidgets;
|
||||
};
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
This file is part of KDDockWidgets.
|
||||
|
||||
SPDX-FileCopyrightText: 2019-2022 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
|
||||
Author: Sérgio Martins <sergio.martins@kdab.com>
|
||||
SPDX-FileCopyrightText: 2019-2022 Klarälvdalens Datakonsult AB, a KDAB Group company
|
||||
<info@kdab.com> Author: Sérgio Martins <sergio.martins@kdab.com>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
@@ -14,15 +14,16 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <kddockwidgets/private/widgets/TitleBarWidget_p.h>
|
||||
#include <kddockwidgets/views/TitleBar_qtwidgets.h>
|
||||
#include <kddockwidgets/controllers/TitleBar.h>
|
||||
|
||||
/**
|
||||
* @brief Shows how to implement a custom titlebar which uses "Qt StyleSheets".
|
||||
*
|
||||
* Derive from KDDockWidgets::DefaultWidgetFactory and override the two createTitleBar() methods.
|
||||
* Derive from KDDockWidgets::ViewFactory_qtwidgets and override the createTitleBar() method.
|
||||
*
|
||||
* To try it out, modify examples/dockwidgets/MyFrameworkWidgetFactory.cpp to return a MyTitleBar_CSS instance.
|
||||
* Run the example with: ./bin/kddockwidgets_example -p
|
||||
* To try it out, modify examples/dockwidgets/MyViewFactory.cpp to return a MyTitleBar_CSS instance.
|
||||
* Run the example with: ./bin/examples/qtwidgets_dockwidgets -p
|
||||
*
|
||||
* WARNINGS:
|
||||
* - Qt StyleSheets are not recommended for new applications. Often you are able to style 90% of
|
||||
@@ -30,27 +31,29 @@
|
||||
* - The Qt maintainers have manifested intention to deprecated stylesheets.
|
||||
* - Stylesheets are supported for built-in QWidgets (QPushButton, QComboBox, etc.), any widget
|
||||
* that's not in Qt needs to be crafted by the user, that includes, for example, having to paint
|
||||
* your background manually. KDDockWidget::TitleBarWidget does this for your convenience though.
|
||||
* your background manually. KDDockWidget::Views::TitleBar_qtwidgets does this for your
|
||||
* convenience though.
|
||||
* - Qt stylesheets don't react to property changes (known old bug in Qt), for example:
|
||||
* QLineEdit[readOnly="true"] { color: gray }
|
||||
* this won't trigger when readOnly changes to false, you need to set/unset. This is QTBUG-51236
|
||||
* - KDDockWidgets::TitleBarWidget::isFocused is a property, there for needs to workaround the
|
||||
* above bug by unsetting the sheet and setting it again.
|
||||
* - KDDockWidget::Views::TitleBar_qtwidgets::isFocused is a property, there for needs to
|
||||
* workaround the above bug by unsetting the sheet and setting it again.
|
||||
*/
|
||||
class MyTitleBar_CSS : public KDDockWidgets::TitleBarWidget
|
||||
class MyTitleBar_CSS : public KDDockWidgets::Views::TitleBar_qtwidgets
|
||||
{
|
||||
public:
|
||||
explicit MyTitleBar_CSS(KDDockWidgets::Frame *frame)
|
||||
: KDDockWidgets::TitleBarWidget(frame)
|
||||
explicit MyTitleBar_CSS(KDDockWidgets::Controllers::TitleBar *controller,
|
||||
View *parent = nullptr)
|
||||
: KDDockWidgets::Views::TitleBar_qtwidgets(controller, parent)
|
||||
{
|
||||
init();
|
||||
initStyleSheet();
|
||||
connect(controller, &KDDockWidgets::Controllers::TitleBar::isFocusedChanged, this, [this] {
|
||||
// Workaround QTBUG-51236, this makes the [isFocused=true] syntax useful
|
||||
setStyleSheet(QString());
|
||||
initStyleSheet();
|
||||
});
|
||||
}
|
||||
|
||||
explicit MyTitleBar_CSS(KDDockWidgets::FloatingWindow *fw)
|
||||
: KDDockWidgets::TitleBarWidget(fw)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
~MyTitleBar_CSS() override;
|
||||
|
||||
@@ -67,16 +70,6 @@ public:
|
||||
"background: green"
|
||||
"}"));
|
||||
}
|
||||
|
||||
void init()
|
||||
{
|
||||
initStyleSheet();
|
||||
connect(this, &KDDockWidgets::TitleBar::isFocusedChanged, this, [this] {
|
||||
// Workaround QTBUG-51236, this makes the [isFocused=true] syntax useful
|
||||
setStyleSheet(QString());
|
||||
initStyleSheet();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
MyTitleBar_CSS::~MyTitleBar_CSS()
|
||||
|
||||
93
examples/dockwidgets/MyViewFactory.cpp
Normal file
93
examples/dockwidgets/MyViewFactory.cpp
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
This file is part of KDDockWidgets.
|
||||
|
||||
SPDX-FileCopyrightText: 2019-2022 Klarälvdalens Datakonsult AB, a KDAB Group company
|
||||
<info@kdab.com> Author: Sérgio Martins <sergio.martins@kdab.com>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
Contact KDAB at <info@kdab.com> for commercial licensing options.
|
||||
*/
|
||||
|
||||
#include "MyViewFactory.h"
|
||||
#include "MyTitleBar_CSS.h"
|
||||
|
||||
#include <kddockwidgets/views/TitleBar_qtwidgets.h>
|
||||
#include <kddockwidgets/views/Separator_qtwidgets.h>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QPainter>
|
||||
|
||||
// clazy:excludeall=missing-qobject-macro,ctor-missing-parent-argument
|
||||
|
||||
class MyTitleBar : public KDDockWidgets::Views::TitleBar_qtwidgets
|
||||
{
|
||||
public:
|
||||
explicit MyTitleBar(KDDockWidgets::Controllers::TitleBar *controller, View *parent = nullptr)
|
||||
: KDDockWidgets::Views::TitleBar_qtwidgets(controller, parent)
|
||||
, m_controller(controller)
|
||||
{
|
||||
setFixedHeight(60);
|
||||
}
|
||||
|
||||
~MyTitleBar() override;
|
||||
|
||||
void paintEvent(QPaintEvent *) override
|
||||
{
|
||||
QPainter p(this);
|
||||
QPen pen(Qt::black);
|
||||
const QColor focusedBackgroundColor = Qt::yellow;
|
||||
const QColor backgroundColor = focusedBackgroundColor.darker(115);
|
||||
QBrush brush(m_controller->isFocused() ? focusedBackgroundColor : backgroundColor);
|
||||
pen.setWidth(4);
|
||||
p.setPen(pen);
|
||||
p.setBrush(brush);
|
||||
p.drawRect(rect().adjusted(4, 4, -4, -4));
|
||||
QFont f = qGuiApp->font();
|
||||
f.setPixelSize(30);
|
||||
f.setBold(true);
|
||||
p.setFont(f);
|
||||
p.drawText(QPoint(10, 40), m_controller->title());
|
||||
}
|
||||
|
||||
private:
|
||||
KDDockWidgets::Controllers::TitleBar *const m_controller;
|
||||
};
|
||||
|
||||
MyTitleBar::~MyTitleBar() = default;
|
||||
|
||||
// Inheriting from SeparatorWidget instead of Separator as it handles moving and mouse cursor
|
||||
// changing
|
||||
class MySeparator : public KDDockWidgets::Views::Separator_qtwidgets
|
||||
{
|
||||
public:
|
||||
explicit MySeparator(KDDockWidgets::Controllers::Separator *controller, View *parent)
|
||||
: KDDockWidgets::Views::Separator_qtwidgets(controller, parent)
|
||||
{
|
||||
}
|
||||
|
||||
~MySeparator() override;
|
||||
|
||||
void paintEvent(QPaintEvent *) override
|
||||
{
|
||||
QPainter p(this);
|
||||
p.fillRect(QWidget::rect(), Qt::cyan);
|
||||
}
|
||||
};
|
||||
|
||||
MySeparator::~MySeparator() = default;
|
||||
|
||||
KDDockWidgets::View *
|
||||
CustomWidgetFactory::createTitleBar(KDDockWidgets::Controllers::TitleBar *controller,
|
||||
KDDockWidgets::View *parent) const
|
||||
{
|
||||
// Feel free to return MyTitleBar_CSS here instead, but just for education purposes!
|
||||
return new MyTitleBar(controller, parent);
|
||||
}
|
||||
|
||||
KDDockWidgets::View *
|
||||
CustomWidgetFactory::createSeparator(KDDockWidgets::Controllers::Separator *controller,
|
||||
KDDockWidgets::View *parent) const
|
||||
{
|
||||
return new MySeparator(controller, parent);
|
||||
}
|
||||
26
examples/dockwidgets/MyViewFactory.h
Normal file
26
examples/dockwidgets/MyViewFactory.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
This file is part of KDDockWidgets.
|
||||
|
||||
SPDX-FileCopyrightText: 2019-2022 Klarälvdalens Datakonsult AB, a KDAB Group company
|
||||
<info@kdab.com> Author: Sérgio Martins <sergio.martins@kdab.com>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
Contact KDAB at <info@kdab.com> for commercial licensing options.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <kddockwidgets/ViewFactory_qtwidgets.h>
|
||||
|
||||
// clazy:excludeall=ctor-missing-parent-argument
|
||||
|
||||
class CustomWidgetFactory : public KDDockWidgets::ViewFactory_qtwidgets
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
KDDockWidgets::View *createTitleBar(KDDockWidgets::Controllers::TitleBar *,
|
||||
KDDockWidgets::View *parent) const override;
|
||||
KDDockWidgets::View *createSeparator(KDDockWidgets::Controllers::Separator *,
|
||||
KDDockWidgets::View *parent = nullptr) const override;
|
||||
};
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
This file is part of KDDockWidgets.
|
||||
|
||||
SPDX-FileCopyrightText: 2019-2022 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
|
||||
Author: Sérgio Martins <sergio.martins@kdab.com>
|
||||
SPDX-FileCopyrightText: 2019-2022 Klarälvdalens Datakonsult AB, a KDAB Group company
|
||||
<info@kdab.com> Author: Sérgio Martins <sergio.martins@kdab.com>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
@@ -62,8 +62,7 @@ void MyWidget::drawLogo(QPainter &p)
|
||||
|
||||
const int proposedHeight = int(maxWidth * ratio);
|
||||
|
||||
const int width = proposedHeight <= maxHeight ? maxWidth
|
||||
: int(maxHeight / ratio);
|
||||
const int width = proposedHeight <= maxHeight ? maxWidth : int(maxHeight / ratio);
|
||||
|
||||
const int height = int(width * ratio);
|
||||
QRect targetLogoRect(0, 0, width, height);
|
||||
@@ -86,7 +85,8 @@ void MyWidget::closeEvent(QCloseEvent *ev)
|
||||
}
|
||||
|
||||
MyWidget1::MyWidget1(MyWidget::QWidget *parent)
|
||||
: MyWidget(QStringLiteral(":/assets/triangles.png"), QStringLiteral(":/assets/KDAB_bubble_white.png"), parent)
|
||||
: MyWidget(QStringLiteral(":/assets/triangles.png"),
|
||||
QStringLiteral(":/assets/KDAB_bubble_white.png"), parent)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -112,7 +112,8 @@ void MyWidget2::paintEvent(QPaintEvent *)
|
||||
}
|
||||
|
||||
MyWidget3::MyWidget3(MyWidget::QWidget *parent)
|
||||
: MyWidget(QStringLiteral(":/assets/base.png"), QStringLiteral(":/assets/KDAB_bubble_fulcolor.png"), parent)
|
||||
: MyWidget(QStringLiteral(":/assets/base.png"),
|
||||
QStringLiteral(":/assets/KDAB_bubble_fulcolor.png"), parent)
|
||||
, m_triangle(QImage(QStringLiteral(":/assets/tri.png")))
|
||||
{
|
||||
}
|
||||
@@ -124,7 +125,8 @@ void MyWidget3::paintEvent(QPaintEvent *)
|
||||
|
||||
p.drawImage(m_background.rect(), m_background, m_background.rect());
|
||||
|
||||
const QRect targetRect = QRect({ width() - m_triangle.width(), height() - m_triangle.height() }, m_triangle.size());
|
||||
const QRect targetRect =
|
||||
QRect({ width() - m_triangle.width(), height() - m_triangle.height() }, m_triangle.size());
|
||||
|
||||
p.drawImage(targetRect, m_triangle, m_triangle.rect());
|
||||
drawLogo(p);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
This file is part of KDDockWidgets.
|
||||
|
||||
SPDX-FileCopyrightText: 2019-2022 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
|
||||
Author: Sérgio Martins <sergio.martins@kdab.com>
|
||||
SPDX-FileCopyrightText: 2019-2022 Klarälvdalens Datakonsult AB, a KDAB Group company
|
||||
<info@kdab.com> Author: Sérgio Martins <sergio.martins@kdab.com>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
@@ -24,7 +24,8 @@ class MyWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MyWidget(const QString &backgroundFile, const QString &logoFile, QWidget *parent = nullptr);
|
||||
explicit MyWidget(const QString &backgroundFile, const QString &logoFile,
|
||||
QWidget *parent = nullptr);
|
||||
~MyWidget();
|
||||
|
||||
// These two are just for demonstrating how to block the close event, if desired
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
This file is part of KDDockWidgets.
|
||||
|
||||
SPDX-FileCopyrightText: 2019-2022 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
|
||||
Author: Sérgio Martins <sergio.martins@kdab.com>
|
||||
SPDX-FileCopyrightText: 2019-2022 Klarälvdalens Datakonsult AB, a KDAB Group company
|
||||
<info@kdab.com> Author: Sérgio Martins <sergio.martins@kdab.com>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
@@ -11,16 +11,19 @@
|
||||
|
||||
#include "MyWidget.h"
|
||||
#include "MyMainWindow.h"
|
||||
#include "MyFrameworkWidgetFactory.h"
|
||||
#include "MyViewFactory.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <kddockwidgets/Config.h>
|
||||
#include <kddockwidgets/ViewFactory.h>
|
||||
#include <kddockwidgets/controllers/DockWidget.h>
|
||||
|
||||
#include <QStyleFactory>
|
||||
#include <QApplication>
|
||||
#include <QDebug>
|
||||
#include <QCommandLineParser>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
// clazy:excludeall=qstring-allocations
|
||||
|
||||
using namespace KDDockWidgets;
|
||||
@@ -32,10 +35,11 @@ int main(int argc, char **argv)
|
||||
QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
#endif
|
||||
QApplication app(argc, argv);
|
||||
|
||||
app.setOrganizationName(QStringLiteral("KDAB"));
|
||||
app.setApplicationName(QStringLiteral("Test app"));
|
||||
|
||||
KDDockWidgets::initFrontend(KDDockWidgets::FrontendType::QtWidgets);
|
||||
|
||||
QCommandLineParser parser;
|
||||
parser.setApplicationDescription("KDDockWidgets example application");
|
||||
parser.addHelpOption();
|
||||
@@ -43,110 +47,184 @@ int main(int argc, char **argv)
|
||||
// Fusion looks better in general, but feel free to change
|
||||
qApp->setStyle(QStyleFactory::create(QStringLiteral("Fusion")));
|
||||
|
||||
QCommandLineOption customStyle("p", QCoreApplication::translate("main", "Shows how to style framework internals via FrameworkWidgetFactory"));
|
||||
QCommandLineOption customStyle(
|
||||
"p",
|
||||
QCoreApplication::translate("main",
|
||||
"Shows how to style framework internals via ViewFactory"));
|
||||
parser.addOption(customStyle);
|
||||
|
||||
QCommandLineOption reorderTabsOption("r", QCoreApplication::translate("main", "Support re-ordering tabs with mouse"));
|
||||
QCommandLineOption reorderTabsOption(
|
||||
"r", QCoreApplication::translate("main", "Support re-ordering tabs with mouse"));
|
||||
parser.addOption(reorderTabsOption);
|
||||
|
||||
QCommandLineOption noTitleBars("t", QCoreApplication::translate("main", "Hide titlebars when tabs are visible"));
|
||||
QCommandLineOption noTitleBars(
|
||||
"t", QCoreApplication::translate("main", "Hide titlebars when tabs are visible"));
|
||||
parser.addOption(noTitleBars);
|
||||
|
||||
QCommandLineOption alwaysTitleBarWhenFloating("q", QCoreApplication::translate("main", "Don't hide title bars if floating, even if Flag_HideTitleBarWhenTabsVisible is specified."));
|
||||
QCommandLineOption alwaysTitleBarWhenFloating(
|
||||
"q",
|
||||
QCoreApplication::translate("main",
|
||||
"Don't hide title bars if floating, even if "
|
||||
"Flag_HideTitleBarWhenTabsVisible is specified."));
|
||||
parser.addOption(alwaysTitleBarWhenFloating);
|
||||
|
||||
QCommandLineOption alwaysTabs("z", QCoreApplication::translate("main", "Show tabs even if there's only one"));
|
||||
QCommandLineOption alwaysTabs(
|
||||
"z", QCoreApplication::translate("main", "Show tabs even if there's only one"));
|
||||
parser.addOption(alwaysTabs);
|
||||
|
||||
QCommandLineOption lazyResizeOption("l", QCoreApplication::translate("main", "Use lazy resize"));
|
||||
QCommandLineOption lazyResizeOption("l",
|
||||
QCoreApplication::translate("main", "Use lazy resize"));
|
||||
parser.addOption(lazyResizeOption);
|
||||
|
||||
QCommandLineOption multipleMainWindows("m", QCoreApplication::translate("main", "Shows two multiple main windows"));
|
||||
QCommandLineOption multipleMainWindows(
|
||||
"m", QCoreApplication::translate("main", "Shows two multiple main windows"));
|
||||
parser.addOption(multipleMainWindows);
|
||||
|
||||
QCommandLineOption incompatibleMainWindows("i", QCoreApplication::translate("main", "Only usable with -m. Make the two main windows incompatible with each other. (Illustrates (MainWindowBase::setAffinityName))"));
|
||||
QCommandLineOption incompatibleMainWindows(
|
||||
"i",
|
||||
QCoreApplication::translate(
|
||||
"main",
|
||||
"Only usable with -m. Make the two main windows incompatible with each other. "
|
||||
"(Illustrates (MainWindowBase::setAffinityName))"));
|
||||
parser.addOption(incompatibleMainWindows);
|
||||
|
||||
QCommandLineOption tabsHaveCloseButton("c", QCoreApplication::translate("main", "Tabs have a close button"));
|
||||
QCommandLineOption tabsHaveCloseButton(
|
||||
"c", QCoreApplication::translate("main", "Tabs have a close button"));
|
||||
parser.addOption(tabsHaveCloseButton);
|
||||
|
||||
QCommandLineOption nonClosableDockWidget("n", QCoreApplication::translate("main", "DockWidget #0 will be non-closable"));
|
||||
QCommandLineOption nonClosableDockWidget(
|
||||
"n", QCoreApplication::translate("main", "DockWidget #0 will be non-closable"));
|
||||
parser.addOption(nonClosableDockWidget);
|
||||
|
||||
QCommandLineOption relativeRestore("s", QCoreApplication::translate("main", "Don't restore main window geometry, restore dock widgets in relative sizes"));
|
||||
QCommandLineOption relativeRestore(
|
||||
"s",
|
||||
QCoreApplication::translate(
|
||||
"main", "Don't restore main window geometry, restore dock widgets in relative sizes"));
|
||||
parser.addOption(relativeRestore);
|
||||
|
||||
QCommandLineOption doubleClickMaximize("x", QCoreApplication::translate("main", "Double clicking a title bar will maximize a floating window"));
|
||||
QCommandLineOption doubleClickMaximize(
|
||||
"x",
|
||||
QCoreApplication::translate("main",
|
||||
"Double clicking a title bar will maximize a floating window"));
|
||||
parser.addOption(doubleClickMaximize);
|
||||
|
||||
QCommandLineOption nonDockable("d", QCoreApplication::translate("main", "DockWidget #9 will be non-dockable"));
|
||||
QCommandLineOption nonDockable(
|
||||
"d", QCoreApplication::translate("main", "DockWidget #9 will be non-dockable"));
|
||||
parser.addOption(nonDockable);
|
||||
|
||||
QCommandLineOption maximizeButtonOption("b", QCoreApplication::translate("main", "Floating dockWidgets have maximize/restore buttons instead of float/dock button"));
|
||||
QCommandLineOption maximizeButtonOption(
|
||||
"b",
|
||||
QCoreApplication::translate(
|
||||
"main",
|
||||
"Floating dockWidgets have maximize/restore buttons instead of float/dock button"));
|
||||
parser.addOption(maximizeButtonOption);
|
||||
|
||||
QCommandLineOption minimizeButtonOption("k", QCoreApplication::translate("main", "Floating dockWidgets have a minimize button. Implies not being an utility window (~Qt::Tool)"));
|
||||
QCommandLineOption minimizeButtonOption(
|
||||
"k",
|
||||
QCoreApplication::translate("main",
|
||||
"Floating dockWidgets have a minimize button. Implies not "
|
||||
"being an utility window (~Qt::Tool)"));
|
||||
parser.addOption(minimizeButtonOption);
|
||||
|
||||
QCommandLineOption segmentedIndicators("y", QCoreApplication::translate("main", "Use segmented indicators instead of classical"));
|
||||
QCommandLineOption segmentedIndicators(
|
||||
"y", QCoreApplication::translate("main", "Use segmented indicators instead of classical"));
|
||||
parser.addOption(segmentedIndicators);
|
||||
|
||||
QCommandLineOption noUtilityWindows("u", QCoreApplication::translate("main", "FloatingWindows will be normal windows instead of utility windows"));
|
||||
QCommandLineOption noUtilityWindows(
|
||||
"u",
|
||||
QCoreApplication::translate(
|
||||
"main", "FloatingWindows will be normal windows instead of utility windows"));
|
||||
parser.addOption(noUtilityWindows);
|
||||
|
||||
QCommandLineOption keepAbove("o", QCoreApplication::translate("main", "FloatingWindows will have Qt::WindowStaysOnTopHint. Implies not being an utility window (try it with -u too)"));
|
||||
QCommandLineOption keepAbove(
|
||||
"o",
|
||||
QCoreApplication::translate("main",
|
||||
"FloatingWindows will have Qt::WindowStaysOnTopHint. Implies "
|
||||
"not being an utility window (try it with -u too)"));
|
||||
parser.addOption(keepAbove);
|
||||
|
||||
parser.addPositionalArgument("savedlayout", QCoreApplication::translate("main", "loads the specified json file at startup"));
|
||||
parser.addPositionalArgument(
|
||||
"savedlayout",
|
||||
QCoreApplication::translate("main", "loads the specified json file at startup"));
|
||||
|
||||
#ifdef KDDOCKWIDGETS_SUPPORTS_NESTED_MAINWINDOWS
|
||||
QCommandLineOption dockableMainWindows("j", QCoreApplication::translate("main", "Allow main windows to be docked inside other main windows"));
|
||||
QCommandLineOption dockableMainWindows(
|
||||
"j",
|
||||
QCoreApplication::translate("main",
|
||||
"Allow main windows to be docked inside other main windows"));
|
||||
parser.addOption(dockableMainWindows);
|
||||
#endif
|
||||
|
||||
QCommandLineOption maxSizeOption("g", QCoreApplication::translate("main", "Make dock #8 have a max-size of 200x200."));
|
||||
QCommandLineOption maxSizeOption(
|
||||
"g", QCoreApplication::translate("main", "Make dock #8 have a max-size of 200x200."));
|
||||
parser.addOption(maxSizeOption);
|
||||
|
||||
QCommandLineOption centralFrame("f", QCoreApplication::translate("main", "Persistent central frame"));
|
||||
QCommandLineOption centralFrame(
|
||||
"f", QCoreApplication::translate("main", "Persistent central group"));
|
||||
|
||||
QCommandLineOption autoHideSupport("w", QCoreApplication::translate("main", "Enables auto-hide/minimization to side-bar support"));
|
||||
QCommandLineOption autoHideSupport(
|
||||
"w",
|
||||
QCoreApplication::translate("main", "Enables auto-hide/minimization to side-bar support"));
|
||||
parser.addOption(autoHideSupport);
|
||||
|
||||
QCommandLineOption closeOnlyCurrentTab("close-only-current-tab",
|
||||
QCoreApplication::translate("main", "The title bar's close button will only close the current tab instead of all. Illustrates using Config::Flag_CloseOnlyCurrentTab"));
|
||||
QCommandLineOption closeOnlyCurrentTab(
|
||||
"close-only-current-tab",
|
||||
QCoreApplication::translate(
|
||||
"main",
|
||||
"The title bar's close button will only close the current tab instead of all. "
|
||||
"Illustrates using Config::Flag_CloseOnlyCurrentTab"));
|
||||
parser.addOption(closeOnlyCurrentTab);
|
||||
|
||||
QCommandLineOption dontCloseBeforeRestore("dont-close-widget-before-restore", // krazy:exclude=spelling
|
||||
QCoreApplication::translate("main", "DockWidget #5 won't be closed before a restore. Illustrates LayoutSaverOption::DontCloseBeforeRestore"));
|
||||
QCommandLineOption dontCloseBeforeRestore(
|
||||
"dont-close-widget-before-restore", // krazy:exclude=spelling
|
||||
QCoreApplication::translate("main",
|
||||
"DockWidget #5 won't be closed before a restore. Illustrates "
|
||||
"LayoutSaverOption::DontCloseBeforeRestore"));
|
||||
parser.addOption(dontCloseBeforeRestore);
|
||||
|
||||
QCommandLineOption blockCloseEvent("block-close-event",
|
||||
QCoreApplication::translate("main", "DockWidget #0 will block close events"));
|
||||
QCommandLineOption blockCloseEvent(
|
||||
"block-close-event",
|
||||
QCoreApplication::translate("main", "DockWidget #0 will block close events"));
|
||||
parser.addOption(blockCloseEvent);
|
||||
|
||||
QCommandLineOption showButtonsInTabBarIfTitleBarHidden("show-buttons-in-tabbar-if-titlebar-hidden",
|
||||
QCoreApplication::translate("main", "If we're not using title bars we'll still show the close and float button in the tab bar"));
|
||||
QCommandLineOption showButtonsInTabBarIfTitleBarHidden(
|
||||
"show-buttons-in-tabbar-if-titlebar-hidden",
|
||||
QCoreApplication::translate("main",
|
||||
"If we're not using title bars we'll still show the close and "
|
||||
"float button in the tab bar"));
|
||||
parser.addOption(showButtonsInTabBarIfTitleBarHidden);
|
||||
|
||||
QCommandLineOption centralWidget("central-widget",
|
||||
QCoreApplication::translate("main", "The main window will have a non-detachable central widget"));
|
||||
QCommandLineOption centralWidget(
|
||||
"central-widget",
|
||||
QCoreApplication::translate("main",
|
||||
"The main window will have a non-detachable central widget"));
|
||||
parser.addOption(centralWidget);
|
||||
|
||||
QCommandLineOption ctxtMenuOnTabs("allow-switch-tabs-via-menu",
|
||||
QCoreApplication::translate("main", "Allow switching tabs via context menu in tabs area"));
|
||||
QCommandLineOption ctxtMenuOnTabs(
|
||||
"allow-switch-tabs-via-menu",
|
||||
QCoreApplication::translate("main", "Allow switching tabs via context menu in tabs area"));
|
||||
parser.addOption(ctxtMenuOnTabs);
|
||||
|
||||
QCommandLineOption hideCertainDockingIndicators("hide-certain-docking-indicators",
|
||||
QCoreApplication::translate("main", "Illustrates usage of Config::setDropIndicatorAllowedFunc()"));
|
||||
QCommandLineOption hideCertainDockingIndicators(
|
||||
"hide-certain-docking-indicators",
|
||||
QCoreApplication::translate("main",
|
||||
"Illustrates usage of Config::setDropIndicatorAllowedFunc()"));
|
||||
parser.addOption(hideCertainDockingIndicators);
|
||||
|
||||
#if defined(DOCKS_DEVELOPER_MODE)
|
||||
parser.addOption(centralFrame);
|
||||
|
||||
QCommandLineOption noQtTool("no-qttool", QCoreApplication::translate("main", "(internal) Don't use Qt::Tool"));
|
||||
QCommandLineOption noParentForFloating("no-parent-for-floating", QCoreApplication::translate("main", "(internal) FloatingWindows won't have a parent"));
|
||||
QCommandLineOption nativeTitleBar("native-title-bar", QCoreApplication::translate("main", "(internal) FloatingWindows a native title bar"));
|
||||
QCommandLineOption noDropIndicators("no-drop-indicators", QCoreApplication::translate("main", "(internal) Don't use any drop indicators"));
|
||||
QCommandLineOption noQtTool(
|
||||
"no-qttool", QCoreApplication::translate("main", "(internal) Don't use Qt::Tool"));
|
||||
QCommandLineOption noParentForFloating(
|
||||
"no-parent-for-floating",
|
||||
QCoreApplication::translate("main", "(internal) FloatingWindows won't have a parent"));
|
||||
QCommandLineOption nativeTitleBar(
|
||||
"native-title-bar",
|
||||
QCoreApplication::translate("main", "(internal) FloatingWindows a native title bar"));
|
||||
QCommandLineOption noDropIndicators(
|
||||
"no-drop-indicators",
|
||||
QCoreApplication::translate("main", "(internal) Don't use any drop indicators"));
|
||||
|
||||
parser.addOption(noQtTool);
|
||||
parser.addOption(noParentForFloating);
|
||||
@@ -154,7 +232,8 @@ int main(int argc, char **argv)
|
||||
parser.addOption(noDropIndicators);
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
QCommandLineOption noAeroSnap("no-aero-snap", QCoreApplication::translate("main", "(internal) Disable AeroSnap"));
|
||||
QCommandLineOption noAeroSnap(
|
||||
"no-aero-snap", QCoreApplication::translate("main", "(internal) Disable AeroSnap"));
|
||||
parser.addOption(noAeroSnap);
|
||||
#endif
|
||||
#else
|
||||
@@ -164,22 +243,22 @@ int main(int argc, char **argv)
|
||||
parser.process(app);
|
||||
|
||||
if (parser.isSet(customStyle)) {
|
||||
Config::self().setFrameworkWidgetFactory(new CustomWidgetFactory()); // Sets our custom factory
|
||||
Config::self().setViewFactory(new CustomWidgetFactory()); // Sets our custom factory
|
||||
|
||||
// Increase the separator size, just for demo
|
||||
Config::self().setSeparatorThickness(10);
|
||||
}
|
||||
|
||||
if (parser.isSet(segmentedIndicators))
|
||||
KDDockWidgets::DefaultWidgetFactory::s_dropIndicatorType = KDDockWidgets::DropIndicatorType::Segmented;
|
||||
KDDockWidgets::ViewFactory::s_dropIndicatorType =
|
||||
KDDockWidgets::DropIndicatorType::Segmented;
|
||||
|
||||
MainWindowOptions options = MainWindowOption_None;
|
||||
auto flags = KDDockWidgets::Config::self().flags();
|
||||
#if defined(DOCKS_DEVELOPER_MODE)
|
||||
auto internalFlags = KDDockWidgets::Config::self().internalFlags();
|
||||
|
||||
options = parser.isSet(centralFrame) ? MainWindowOption_HasCentralFrame
|
||||
: MainWindowOption_None;
|
||||
options = parser.isSet(centralFrame) ? MainWindowOption_HasCentralFrame : MainWindowOption_None;
|
||||
|
||||
if (parser.isSet(centralWidget))
|
||||
options |= MainWindowOption_HasCentralWidget;
|
||||
@@ -197,7 +276,7 @@ int main(int argc, char **argv)
|
||||
flags |= KDDockWidgets::Config::Flag_NativeTitleBar;
|
||||
|
||||
if (parser.isSet(noDropIndicators))
|
||||
KDDockWidgets::DefaultWidgetFactory::s_dropIndicatorType = KDDockWidgets::DropIndicatorType::None;
|
||||
KDDockWidgets::ViewFactory::s_dropIndicatorType = KDDockWidgets::DropIndicatorType::None;
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
if (parser.isSet(noAeroSnap))
|
||||
@@ -227,13 +306,16 @@ int main(int argc, char **argv)
|
||||
if (parser.isSet(alwaysTitleBarWhenFloating)) {
|
||||
flags |= KDDockWidgets::Config::Flag_AlwaysTitleBarWhenFloating;
|
||||
if (!(flags & KDDockWidgets::Config::Flag_HideTitleBarWhenTabsVisible)) {
|
||||
qWarning() << "Flag_AlwaysTitleBarWhenFloating is unneeded if Flag_HideTitleBarWhenTabsVisible isn't used."
|
||||
qWarning() << "Flag_AlwaysTitleBarWhenFloating is unneeded if "
|
||||
"Flag_HideTitleBarWhenTabsVisible isn't used."
|
||||
<< "As floating windows already have title bars by default.";
|
||||
}
|
||||
}
|
||||
|
||||
if (parser.isSet(customStyle) || qEnvironmentVariableIsSet("KDDW_DEBUG_FOCUS"))
|
||||
flags |= KDDockWidgets::Config::Flag_TitleBarIsFocusable; // also showing title bar focus with -p, just to not introduce another switch
|
||||
flags |= KDDockWidgets::Config::Flag_TitleBarIsFocusable; // also showing title bar focus
|
||||
// with -p, just to not introduce
|
||||
// another switch
|
||||
|
||||
if (parser.isSet(reorderTabsOption))
|
||||
flags |= KDDockWidgets::Config::Flag_AllowReorderTabs;
|
||||
@@ -264,16 +346,19 @@ int main(int argc, char **argv)
|
||||
|
||||
if (parser.isSet(hideCertainDockingIndicators)) {
|
||||
// Here we exemplify adding a restriction to "Dock Widget 8"
|
||||
// Dock widget 8 will only be allowed to dock to the outer areasa
|
||||
// Dock widget 8 will only be allowed to dock to the outer areas
|
||||
auto func = [](KDDockWidgets::DropLocation location,
|
||||
const KDDockWidgets::DockWidgetBase::List &source,
|
||||
const KDDockWidgets::DockWidgetBase::List &target,
|
||||
KDDockWidgets::DropArea *) {
|
||||
Q_UNUSED(target); // When dragging into a tab, 'target' would have the list of already tabbed dock widgets
|
||||
const KDDockWidgets::Controllers::DockWidget::List &source,
|
||||
const KDDockWidgets::Controllers::DockWidget::List &target,
|
||||
Controllers::DropArea *) {
|
||||
Q_UNUSED(target); // When dragging into a tab, 'target' would have the list of already
|
||||
// tabbed dock widgets
|
||||
|
||||
const bool isDraggingDW8 = std::find_if(source.cbegin(), source.cend(), [](KDDockWidgets::DockWidgetBase *dw) {
|
||||
return dw->uniqueName() == QLatin1String("DockWidget #8");
|
||||
})
|
||||
const bool isDraggingDW8 =
|
||||
std::find_if(source.cbegin(), source.cend(),
|
||||
[](KDDockWidgets::Controllers::DockWidget *dw) {
|
||||
return dw->uniqueName() == QLatin1String("DockWidget #8");
|
||||
})
|
||||
!= source.cend();
|
||||
|
||||
return (location & KDDockWidgets::DropLocation_Outter) || !isDraggingDW8;
|
||||
@@ -307,19 +392,21 @@ int main(int argc, char **argv)
|
||||
|
||||
if (usesMainWindowsWithAffinity) {
|
||||
if (usesDockableMainWindows) {
|
||||
qWarning() << "MainWindows with affinity option is incompatible with Dockable Main Windows option";
|
||||
qWarning() << "MainWindows with affinity option is incompatible with Dockable Main "
|
||||
"Windows option";
|
||||
return 1;
|
||||
}
|
||||
|
||||
// By default a dock widget can dock into any main window.
|
||||
// By setting an affinity name we can prevent that. Dock widgets of different affinities are incompatible.
|
||||
const QString affinity = parser.isSet(incompatibleMainWindows) ? QStringLiteral("affinity1")
|
||||
: QString();
|
||||
// By setting an affinity name we can prevent that. Dock widgets of different affinities are
|
||||
// incompatible.
|
||||
const QString affinity =
|
||||
parser.isSet(incompatibleMainWindows) ? QStringLiteral("affinity1") : QString();
|
||||
|
||||
auto mainWindow2 = new MyMainWindow(QStringLiteral("MyMainWindow-2"), options,
|
||||
nonClosableDockWidget0, nonDockableDockWidget9,
|
||||
restoreIsRelative, maxSizeForDockWidget8,
|
||||
dontCloseDockWidget5BeforeRestore, dock0BlocksCloseEvent, affinity);
|
||||
auto mainWindow2 =
|
||||
new MyMainWindow(QStringLiteral("MyMainWindow-2"), options, nonClosableDockWidget0,
|
||||
nonDockableDockWidget9, restoreIsRelative, maxSizeForDockWidget8,
|
||||
dontCloseDockWidget5BeforeRestore, dock0BlocksCloseEvent, affinity);
|
||||
if (affinity.isEmpty())
|
||||
mainWindow2->setWindowTitle("Main Window 2");
|
||||
else
|
||||
@@ -328,22 +415,22 @@ int main(int argc, char **argv)
|
||||
mainWindow2->resize(1200, 1200);
|
||||
mainWindow2->show();
|
||||
} else if (usesDockableMainWindows) {
|
||||
auto mainWindowDockWidget = new DockWidget(QStringLiteral("MyMainWindow-2-DW"));
|
||||
auto mainWindowDockWidget =
|
||||
new KDDockWidgets::Views::DockWidget_qtwidgets(QStringLiteral("MyMainWindow-2-DW"));
|
||||
|
||||
const QString affinity = QStringLiteral("Inner-DockWidgets-2");
|
||||
auto dockableMainWindow = new MyMainWindow(QStringLiteral("MyMainWindow-2"), options,
|
||||
false, false, restoreIsRelative, false,
|
||||
false, false, affinity);
|
||||
auto dockableMainWindow =
|
||||
new MyMainWindow(QStringLiteral("MyMainWindow-2"), options, false, false,
|
||||
restoreIsRelative, false, false, false, affinity);
|
||||
|
||||
dockableMainWindow->setAffinities({ affinity });
|
||||
|
||||
dockableMainWindow->setStyleSheet(QStringLiteral("background: yellow"));
|
||||
|
||||
dockableMainWindow->setWindowTitle("Dockable Main Window");
|
||||
dockableMainWindow->show();
|
||||
mainWindowDockWidget->setWidget(dockableMainWindow);
|
||||
mainWindowDockWidget->show();
|
||||
mainWindowDockWidget->resize(800, 800);
|
||||
mainWindowDockWidget->open();
|
||||
mainWindowDockWidget->resize(QSize(800, 800));
|
||||
}
|
||||
|
||||
const QStringList args = parser.positionalArguments();
|
||||
|
||||
@@ -10,15 +10,15 @@
|
||||
#
|
||||
|
||||
cmake_minimum_required(VERSION 3.7)
|
||||
project(kddockwidgets_minimal_mdi_example)
|
||||
project(qtwidgets_mdi)
|
||||
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
set(CMAKE_INCLUDE_CURRENT_DIRS ON)
|
||||
|
||||
if(NOT TARGET kddockwidgets)
|
||||
# This will look for Qt, do find_package yourself manually before
|
||||
# if you want to look for a specific Qt version for instance.
|
||||
# This will look for Qt, do find_package yourself manually before if you want
|
||||
# to look for a specific Qt version for instance.
|
||||
find_package(KDDockWidgets REQUIRED)
|
||||
endif()
|
||||
|
||||
@@ -27,12 +27,6 @@ set(RESOURCES_EXAMPLE_SRC ${CMAKE_CURRENT_SOURCE_DIR}/../dockwidgets/resources_e
|
||||
# Just to reuse MyWidget.h
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../dockwidgets/)
|
||||
|
||||
add_executable(
|
||||
kddockwidgets_minimal_mdi_example
|
||||
${RESOURCES_EXAMPLE_SRC} ../dockwidgets/MyWidget.cpp main.cpp
|
||||
)
|
||||
add_executable(qtwidgets_mdi main.cpp ../dockwidgets/MyWidget.cpp ${RESOURCES_EXAMPLE_SRC})
|
||||
|
||||
target_link_libraries(
|
||||
kddockwidgets_minimal_mdi_example
|
||||
PRIVATE KDAB::kddockwidgets
|
||||
)
|
||||
target_link_libraries(qtwidgets_mdi PRIVATE KDAB::kddockwidgets)
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
This file is part of KDDockWidgets.
|
||||
|
||||
SPDX-FileCopyrightText: 2019-2022 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
|
||||
Author: Sérgio Martins <sergio.martins@kdab.com>
|
||||
SPDX-FileCopyrightText: 2019-2022 Klarälvdalens Datakonsult AB, a KDAB Group company
|
||||
<info@kdab.com> Author: Sérgio Martins <sergio.martins@kdab.com>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
|
||||
#include "MyWidget.h"
|
||||
|
||||
#include <kddockwidgets/views/MainWindowMDI_qtwidgets.h>
|
||||
#include <kddockwidgets/DockWidget.h>
|
||||
#include <kddockwidgets/MainWindowMDI.h>
|
||||
|
||||
#include <QStyleFactory>
|
||||
#include <QApplication>
|
||||
@@ -30,26 +30,28 @@ int main(int argc, char **argv)
|
||||
app.setOrganizationName(QStringLiteral("KDAB"));
|
||||
app.setApplicationName(QStringLiteral("Test app"));
|
||||
|
||||
KDDockWidgets::initFrontend(KDDockWidgets::FrontendType::QtWidgets);
|
||||
|
||||
// Fusion looks better in general, but feel free to change
|
||||
qApp->setStyle(QStyleFactory::create(QStringLiteral("Fusion")));
|
||||
|
||||
// # 1. Create our main window
|
||||
|
||||
KDDockWidgets::MainWindowMDI mainWindow(QStringLiteral("MyMainWindow"));
|
||||
KDDockWidgets::Views::MainWindowMDI_qtwidgets mainWindow(QStringLiteral("MyMainWindow"));
|
||||
mainWindow.setWindowTitle("Main Window");
|
||||
mainWindow.resize(1200, 1200);
|
||||
mainWindow.show();
|
||||
|
||||
// # 2. Create a dock widget, it needs a unique name
|
||||
auto dock1 = new KDDockWidgets::DockWidget(QStringLiteral("MyDock1"));
|
||||
auto dock1 = new KDDockWidgets::Views::DockWidget_qtwidgets(QStringLiteral("MyDock1"));
|
||||
auto widget1 = new MyWidget1();
|
||||
dock1->setWidget(widget1);
|
||||
|
||||
auto dock2 = new KDDockWidgets::DockWidget(QStringLiteral("MyDock2"));
|
||||
auto dock2 = new KDDockWidgets::Views::DockWidget_qtwidgets(QStringLiteral("MyDock2"));
|
||||
auto widget2 = new MyWidget2();
|
||||
dock2->setWidget(widget2);
|
||||
|
||||
auto dock3 = new KDDockWidgets::DockWidget(QStringLiteral("MyDock3"));
|
||||
auto dock3 = new KDDockWidgets::Views::DockWidget_qtwidgets(QStringLiteral("MyDock3"));
|
||||
auto widget3 = new MyWidget3();
|
||||
dock3->setWidget(widget3);
|
||||
|
||||
@@ -10,15 +10,15 @@
|
||||
#
|
||||
|
||||
cmake_minimum_required(VERSION 3.7)
|
||||
project(kddockwidgets_mdi_with_docking_example)
|
||||
project(qtwidgets_mdi_with_docking)
|
||||
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
set(CMAKE_INCLUDE_CURRENT_DIRS ON)
|
||||
|
||||
if(NOT TARGET kddockwidgets)
|
||||
# This will look for Qt, do find_package yourself manually before
|
||||
# if you want to look for a specific Qt version for instance.
|
||||
# This will look for Qt, do find_package yourself manually before if you want
|
||||
# to look for a specific Qt version for instance.
|
||||
find_package(KDDockWidgets REQUIRED)
|
||||
endif()
|
||||
|
||||
@@ -27,12 +27,6 @@ set(RESOURCES_EXAMPLE_SRC ${CMAKE_CURRENT_SOURCE_DIR}/../dockwidgets/resources_e
|
||||
# Just to reuse MyWidget.h
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../dockwidgets/)
|
||||
|
||||
add_executable(
|
||||
kddockwidgets_mdi_with_docking_example
|
||||
${RESOURCES_EXAMPLE_SRC} ../dockwidgets/MyWidget.cpp main.cpp
|
||||
)
|
||||
add_executable(qtwidgets_mdi_with_docking main.cpp ../dockwidgets/MyWidget.cpp ${RESOURCES_EXAMPLE_SRC})
|
||||
|
||||
target_link_libraries(
|
||||
kddockwidgets_mdi_with_docking_example
|
||||
PRIVATE KDAB::kddockwidgets
|
||||
)
|
||||
target_link_libraries(qtwidgets_mdi_with_docking PRIVATE KDAB::kddockwidgets)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
This file is part of KDDockWidgets.
|
||||
|
||||
SPDX-FileCopyrightText: 2019-2022 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
|
||||
Author: Sérgio Martins <sergio.martins@kdab.com>
|
||||
SPDX-FileCopyrightText: 2019-2022 Klarälvdalens Datakonsult AB, a KDAB Group company
|
||||
<info@kdab.com> Author: Sérgio Martins <sergio.martins@kdab.com>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
@@ -11,9 +11,9 @@
|
||||
|
||||
#include "MyWidget.h"
|
||||
|
||||
#include <kddockwidgets/DockWidget.h>
|
||||
#include <kddockwidgets/MainWindow.h>
|
||||
#include <kddockwidgets/MDIArea.h>
|
||||
#include <kddockwidgets/DockWidget.h>
|
||||
#include <kddockwidgets/views/MDIArea_qtwidgets.h>
|
||||
|
||||
#include <QStyleFactory>
|
||||
#include <QApplication>
|
||||
@@ -32,11 +32,16 @@ int main(int argc, char **argv)
|
||||
app.setOrganizationName(QStringLiteral("KDAB"));
|
||||
app.setApplicationName(QStringLiteral("App supporting both docking and a MDI area"));
|
||||
|
||||
KDDockWidgets::initFrontend(KDDockWidgets::FrontendType::QtWidgets);
|
||||
|
||||
QCommandLineParser parser;
|
||||
parser.setApplicationDescription("KDDockWidgets MDI mixed with normal docking");
|
||||
parser.addHelpOption();
|
||||
|
||||
QCommandLineOption nestedDocking("n", QCoreApplication::translate("main", "The MDI dock widgets will serve as drop areas, allowing for further nesting"));
|
||||
QCommandLineOption nestedDocking(
|
||||
"n",
|
||||
QCoreApplication::translate(
|
||||
"main", "The MDI dock widgets will serve as drop areas, allowing for further nesting"));
|
||||
parser.addOption(nestedDocking);
|
||||
|
||||
parser.process(app);
|
||||
@@ -46,50 +51,51 @@ int main(int argc, char **argv)
|
||||
|
||||
// # 1. Create our main window
|
||||
|
||||
KDDockWidgets::MainWindow mainWindow(QStringLiteral("MyMainWindow"), KDDockWidgets::MainWindowOption_HasCentralWidget);
|
||||
KDDockWidgets::Views::MainWindow_qtwidgets mainWindow(
|
||||
QStringLiteral("MyMainWindow"), KDDockWidgets::MainWindowOption_HasCentralWidget);
|
||||
mainWindow.setWindowTitle("Main Window");
|
||||
mainWindow.resize(1600, 1200);
|
||||
mainWindow.show();
|
||||
|
||||
// # 2. Create a dock widget, it needs a unique name
|
||||
auto dock1 = new KDDockWidgets::DockWidget(QStringLiteral("MyDock1"));
|
||||
auto dock1 = new KDDockWidgets::Views::DockWidget_qtwidgets(QStringLiteral("MyDock1"));
|
||||
auto widget1 = new MyWidget1();
|
||||
dock1->setWidget(widget1);
|
||||
|
||||
auto dock2 = new KDDockWidgets::DockWidget(QStringLiteral("MyDock2"));
|
||||
auto dock2 = new KDDockWidgets::Views::DockWidget_qtwidgets(QStringLiteral("MyDock2"));
|
||||
auto widget2 = new MyWidget2();
|
||||
dock2->setWidget(widget2);
|
||||
|
||||
// # 3. Dock them
|
||||
mainWindow.addDockWidget(dock1, KDDockWidgets::Location_OnLeft, nullptr, KDDockWidgets::InitialOption(QSize(300, 0)));
|
||||
mainWindow.addDockWidget(dock2, KDDockWidgets::Location_OnBottom, nullptr, KDDockWidgets::InitialOption(QSize(0, 300)));
|
||||
mainWindow.addDockWidget(dock1, KDDockWidgets::Location_OnLeft, nullptr,
|
||||
KDDockWidgets::InitialOption(QSize(300, 0)));
|
||||
mainWindow.addDockWidget(dock2, KDDockWidgets::Location_OnBottom, nullptr,
|
||||
KDDockWidgets::InitialOption(QSize(0, 300)));
|
||||
|
||||
KDDockWidgets::DockWidgetBase::Options options = {};
|
||||
KDDockWidgets::DockWidgetOptions options = {};
|
||||
if (parser.isSet(nestedDocking)) {
|
||||
options |= KDDockWidgets::DockWidgetBase::Option_MDINestable;
|
||||
options |= KDDockWidgets::DockWidgetOption_MDINestable;
|
||||
}
|
||||
|
||||
// 4. Create our MDI widgets, which will go into the MDI area
|
||||
auto mdiWidget1 = new KDDockWidgets::DockWidget(QStringLiteral("MDI widget1"), options);
|
||||
auto mdiWidget1 =
|
||||
new KDDockWidgets::Views::DockWidget_qtwidgets(QStringLiteral("MDI widget1"), options);
|
||||
mdiWidget1->setWidget(new MyWidget1());
|
||||
|
||||
auto mdiWidget2 = new KDDockWidgets::DockWidget(QStringLiteral("MDI widget2"), options);
|
||||
auto mdiWidget2 =
|
||||
new KDDockWidgets::Views::DockWidget_qtwidgets(QStringLiteral("MDI widget2"), options);
|
||||
mdiWidget2->setWidget(new MyWidget2());
|
||||
|
||||
auto mdiWidget3 = new KDDockWidgets::DockWidget(QStringLiteral("MDI widget3"), options);
|
||||
auto widget3 = new MyWidget3();
|
||||
mdiWidget3->setWidget(widget3);
|
||||
auto mdiWidget3 =
|
||||
new KDDockWidgets::Views::DockWidget_qtwidgets(QStringLiteral("MDI widget3"), options);
|
||||
mdiWidget3->setWidget(new MyWidget3());
|
||||
|
||||
// Just for my personal testing: Overkill to add an option
|
||||
// widget3->blockCloseEvent();
|
||||
|
||||
auto mdiArea = new KDDockWidgets::MDIArea();
|
||||
auto mdiArea = new KDDockWidgets::Views::MDIArea_qtwidgets();
|
||||
mainWindow.setPersistentCentralWidget(mdiArea);
|
||||
|
||||
mdiArea->addDockWidget(mdiWidget1, QPoint(10, 10));
|
||||
mdiArea->addDockWidget(mdiWidget2, QPoint(50, 50));
|
||||
mdiArea->addDockWidget(mdiWidget3, QPoint(110, 110));
|
||||
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
|
||||
@@ -10,26 +10,20 @@
|
||||
#
|
||||
|
||||
cmake_minimum_required(VERSION 3.7)
|
||||
project(kddockwidgets_minimal_example)
|
||||
project(qtwidgets_minimal)
|
||||
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
set(CMAKE_INCLUDE_CURRENT_DIRS ON)
|
||||
|
||||
if(NOT TARGET kddockwidgets)
|
||||
# This will look for Qt, do find_package yourself manually before
|
||||
# if you want to look for a specific Qt version for instance.
|
||||
# This will look for Qt, do find_package yourself manually before if you want
|
||||
# to look for a specific Qt version for instance.
|
||||
find_package(KDDockWidgets REQUIRED)
|
||||
endif()
|
||||
|
||||
set(RESOURCES_EXAMPLE_SRC ${CMAKE_CURRENT_SOURCE_DIR}/../dockwidgets/resources_example.qrc)
|
||||
|
||||
add_executable(
|
||||
kddockwidgets_minimal_example
|
||||
${RESOURCES_EXAMPLE_SRC} ../dockwidgets/MyWidget.cpp main.cpp
|
||||
)
|
||||
add_executable(qtwidgets_minimal main.cpp MyWidget.cpp ${RESOURCES_EXAMPLE_SRC})
|
||||
|
||||
target_link_libraries(
|
||||
kddockwidgets_minimal_example
|
||||
PRIVATE KDAB::kddockwidgets
|
||||
)
|
||||
target_link_libraries(qtwidgets_minimal PRIVATE KDAB::kddockwidgets)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
This file is part of KDDockWidgets.
|
||||
|
||||
SPDX-FileCopyrightText: 2019-2022 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
|
||||
Author: Sérgio Martins <sergio.martins@kdab.com>
|
||||
SPDX-FileCopyrightText: 2019-2022 Klarälvdalens Datakonsult AB, a KDAB Group company
|
||||
<info@kdab.com> Author: Sérgio Martins <sergio.martins@kdab.com>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
@@ -61,8 +61,7 @@ void MyWidget::drawLogo(QPainter &p)
|
||||
|
||||
const int proposedHeight = int(maxWidth * ratio);
|
||||
|
||||
const int width = proposedHeight <= maxHeight ? maxWidth
|
||||
: int(maxHeight / ratio);
|
||||
const int width = proposedHeight <= maxHeight ? maxWidth : int(maxHeight / ratio);
|
||||
|
||||
const int height = int(width * ratio);
|
||||
QRect targetLogoRect(0, 0, width, height);
|
||||
@@ -71,7 +70,8 @@ void MyWidget::drawLogo(QPainter &p)
|
||||
}
|
||||
|
||||
MyWidget1::MyWidget1(MyWidget::QWidget *parent)
|
||||
: MyWidget(QStringLiteral(":/assets/triangles.png"), QStringLiteral(":/assets/KDAB_bubble_white.png"), parent)
|
||||
: MyWidget(QStringLiteral(":/assets/triangles.png"),
|
||||
QStringLiteral(":/assets/KDAB_bubble_white.png"), parent)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -97,7 +97,8 @@ void MyWidget2::paintEvent(QPaintEvent *)
|
||||
}
|
||||
|
||||
MyWidget3::MyWidget3(MyWidget::QWidget *parent)
|
||||
: MyWidget(QStringLiteral(":/assets/base.png"), QStringLiteral(":/assets/KDAB_bubble_fulcolor.png"), parent)
|
||||
: MyWidget(QStringLiteral(":/assets/base.png"),
|
||||
QStringLiteral(":/assets/KDAB_bubble_fulcolor.png"), parent)
|
||||
, m_triangle(QImage(QStringLiteral(":/assets/tri.png")))
|
||||
{
|
||||
}
|
||||
@@ -109,7 +110,8 @@ void MyWidget3::paintEvent(QPaintEvent *)
|
||||
|
||||
p.drawImage(m_background.rect(), m_background, m_background.rect());
|
||||
|
||||
const QRect targetRect = QRect({ width() - m_triangle.width(), height() - m_triangle.height() }, m_triangle.size());
|
||||
const QRect targetRect =
|
||||
QRect({ width() - m_triangle.width(), height() - m_triangle.height() }, m_triangle.size());
|
||||
|
||||
p.drawImage(targetRect, m_triangle, m_triangle.rect());
|
||||
drawLogo(p);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
This file is part of KDDockWidgets.
|
||||
|
||||
SPDX-FileCopyrightText: 2019-2022 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
|
||||
Author: Sérgio Martins <sergio.martins@kdab.com>
|
||||
SPDX-FileCopyrightText: 2019-2022 Klarälvdalens Datakonsult AB, a KDAB Group company
|
||||
<info@kdab.com> Author: Sérgio Martins <sergio.martins@kdab.com>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
@@ -25,7 +25,8 @@ class MyWidget : public QWidget
|
||||
Q_OBJECT
|
||||
public:
|
||||
MyWidget() = default;
|
||||
explicit MyWidget(const QString &backgroundFile, const QString &logoFile, QWidget *parent = nullptr);
|
||||
explicit MyWidget(const QString &backgroundFile, const QString &logoFile,
|
||||
QWidget *parent = nullptr);
|
||||
~MyWidget();
|
||||
|
||||
protected:
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
This file is part of KDDockWidgets.
|
||||
|
||||
SPDX-FileCopyrightText: 2019-2022 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
|
||||
Author: Sérgio Martins <sergio.martins@kdab.com>
|
||||
SPDX-FileCopyrightText: 2019-2022 Klarälvdalens Datakonsult AB, a KDAB Group company
|
||||
<info@kdab.com> Author: Sérgio Martins <sergio.martins@kdab.com>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
|
||||
#include "MyWidget.h"
|
||||
|
||||
#include <kddockwidgets/DockWidget.h>
|
||||
#include <kddockwidgets/MainWindow.h>
|
||||
#include <kddockwidgets/DockWidget.h>
|
||||
|
||||
#include <QStyleFactory>
|
||||
#include <QApplication>
|
||||
@@ -28,41 +28,42 @@ int main(int argc, char **argv)
|
||||
QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
#endif
|
||||
QApplication app(argc, argv);
|
||||
|
||||
app.setOrganizationName(QStringLiteral("KDAB"));
|
||||
app.setApplicationName(QStringLiteral("Test app"));
|
||||
|
||||
KDDockWidgets::initFrontend(KDDockWidgets::FrontendType::QtWidgets);
|
||||
|
||||
// Fusion looks better in general, but feel free to change
|
||||
qApp->setStyle(QStyleFactory::create(QStringLiteral("Fusion")));
|
||||
|
||||
// # 1. Create our main window
|
||||
|
||||
KDDockWidgets::MainWindow mainWindow(QStringLiteral("MyMainWindow"));
|
||||
KDDockWidgets::Views::MainWindow_qtwidgets mainWindow(QStringLiteral("MyMainWindow"));
|
||||
mainWindow.setWindowTitle("Main Window");
|
||||
mainWindow.resize(1200, 1200);
|
||||
mainWindow.show();
|
||||
|
||||
// # 2. Create a dock widget, it needs a unique name
|
||||
auto dock1 = new KDDockWidgets::DockWidget(QStringLiteral("MyDock1"));
|
||||
auto dock1 = new KDDockWidgets::Views::DockWidget_qtwidgets(QStringLiteral("MyDock1"));
|
||||
auto widget1 = new MyWidget();
|
||||
dock1->setWidget(widget1);
|
||||
|
||||
auto dock2 = new KDDockWidgets::DockWidget(QStringLiteral("MyDock2"));
|
||||
auto dock2 = new KDDockWidgets::Views::DockWidget_qtwidgets(QStringLiteral("MyDock2"));
|
||||
auto widget2 = new MyWidget(QStringLiteral(":/assets/base.png"),
|
||||
QStringLiteral(":/assets/KDAB_bubble_fulcolor.png"));
|
||||
dock2->setWidget(widget2);
|
||||
|
||||
auto dock3 = new KDDockWidgets::DockWidget(QStringLiteral("MyDock3"));
|
||||
auto dock3 = new KDDockWidgets::Views::DockWidget_qtwidgets(QStringLiteral("MyDock3"));
|
||||
auto widget3 = new MyWidget(QStringLiteral(":/assets/base.png"),
|
||||
QStringLiteral(":/assets/KDAB_bubble_fulcolor.png"));
|
||||
dock3->setWidget(widget3);
|
||||
|
||||
auto dock4 = new KDDockWidgets::DockWidget(QStringLiteral("MyDock4"));
|
||||
auto dock4 = new KDDockWidgets::Views::DockWidget_qtwidgets(QStringLiteral("MyDock4"));
|
||||
auto widget4 = new MyWidget(QStringLiteral(":/assets/base.png"),
|
||||
QStringLiteral(":/assets/KDAB_bubble_fulcolor.png"));
|
||||
dock4->setWidget(widget4);
|
||||
|
||||
auto dock5 = new KDDockWidgets::DockWidget(QStringLiteral("MyDock5"));
|
||||
auto dock5 = new KDDockWidgets::Views::DockWidget_qtwidgets(QStringLiteral("MyDock5"));
|
||||
auto widget5 = new MyWidget(QStringLiteral(":/assets/base.png"),
|
||||
QStringLiteral(":/assets/KDAB_bubble_fulcolor.png"));
|
||||
dock5->setWidget(widget5);
|
||||
@@ -80,7 +81,7 @@ int main(int argc, char **argv)
|
||||
|
||||
|
||||
// 5. dock5 will be its own top level (floating window)
|
||||
dock5->show();
|
||||
dock5->open();
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
|
||||
@@ -8,10 +8,24 @@
|
||||
# Contact KDAB at <info@kdab.com> for commercial licensing options.
|
||||
#
|
||||
|
||||
add_subdirectory(customtitlebar)
|
||||
add_subdirectory(dockwidgets)
|
||||
add_subdirectory(mdi)
|
||||
set_compiler_flags(qtquick_dockwidgets)
|
||||
set_target_properties(
|
||||
qtquick_dockwidgets PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/examples/"
|
||||
)
|
||||
|
||||
set_compiler_flags(kddockwidgets_example_quick)
|
||||
set_compiler_flags(kddockwidgets_example_mdi_quick)
|
||||
set_compiler_flags(kddockwidgets_customtitlebar_quick)
|
||||
add_subdirectory(mdi)
|
||||
set_compiler_flags(qtquick_mdi)
|
||||
set_target_properties(qtquick_mdi PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/examples/")
|
||||
|
||||
add_subdirectory(customtitlebar)
|
||||
set_compiler_flags(qtquick_customtitlebar)
|
||||
set_target_properties(
|
||||
qtquick_customtitlebar PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/examples/"
|
||||
)
|
||||
|
||||
add_subdirectory(customtabbar)
|
||||
set_compiler_flags(qtquick_customtabbar)
|
||||
set_target_properties(
|
||||
qtquick_customtabbar PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/examples/"
|
||||
)
|
||||
|
||||
31
examples/qtquick/customtabbar/CMakeLists.txt
Normal file
31
examples/qtquick/customtabbar/CMakeLists.txt
Normal file
@@ -0,0 +1,31 @@
|
||||
#
|
||||
# This file is part of KDDockWidgets.
|
||||
#
|
||||
# SPDX-FileCopyrightText: 2019-2022 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
|
||||
# Author: Sergio Martins <sergio.martins@kdab.com>
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
|
||||
#
|
||||
# Contact KDAB at <info@kdab.com> for commercial licensing options.
|
||||
#
|
||||
|
||||
cmake_minimum_required(VERSION 3.7)
|
||||
project(qtquick_customtabbar)
|
||||
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
set(CMAKE_INCLUDE_CURRENT_DIRS ON)
|
||||
|
||||
if(NOT TARGET kddockwidgets)
|
||||
# This will look for Qt, do find_package yourself manually before if you want
|
||||
# to look for a specific Qt version for instance.
|
||||
find_package(KDDockWidgets REQUIRED)
|
||||
endif()
|
||||
|
||||
set(RESOURCES_EXAMPLE_SRC ${CMAKE_CURRENT_SOURCE_DIR}/resources_qtquick_example.qrc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../dockwidgets/resources_example.qrc
|
||||
)
|
||||
|
||||
add_executable(qtquick_customtabbar main.cpp ${RESOURCES_EXAMPLE_SRC})
|
||||
|
||||
target_link_libraries(qtquick_customtabbar PRIVATE KDAB::kddockwidgets)
|
||||
36
examples/qtquick/customtabbar/Guest.qml
Normal file
36
examples/qtquick/customtabbar/Guest.qml
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
This file is part of KDDockWidgets.
|
||||
|
||||
SPDX-FileCopyrightText: 2020-2022 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
|
||||
Author: Sergio Martins <sergio.martins@kdab.com>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
Contact KDAB at <info@kdab.com> for commercial licensing options.
|
||||
*/
|
||||
|
||||
import QtQuick 2.9
|
||||
|
||||
Item {
|
||||
anchors.fill: parent
|
||||
|
||||
property alias background: background.source
|
||||
property alias logo: logo.source
|
||||
|
||||
|
||||
Image {
|
||||
id: background
|
||||
anchors.fill: parent
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
|
||||
Image {
|
||||
id: logo
|
||||
|
||||
fillMode: Image.PreserveAspectFit
|
||||
anchors {
|
||||
fill: parent
|
||||
margins: 50
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,4 +9,10 @@
|
||||
Contact KDAB at <info@kdab.com> for commercial licensing options.
|
||||
*/
|
||||
|
||||
#include "../../DockWidgetBase.h"
|
||||
import QtQuick 2.9
|
||||
|
||||
Guest {
|
||||
anchors.fill: parent
|
||||
background: "qrc:/assets/triangles.png"
|
||||
logo: "qrc:/assets/KDAB_bubble_white.png"
|
||||
}
|
||||
@@ -9,4 +9,9 @@
|
||||
Contact KDAB at <info@kdab.com> for commercial licensing options.
|
||||
*/
|
||||
|
||||
#include "../../FrameworkWidgetFactory.h"
|
||||
import QtQuick 2.9
|
||||
|
||||
Guest {
|
||||
anchors.fill: parent
|
||||
logo: "qrc:/assets/KDAB_bubble_blue.png"
|
||||
}
|
||||
@@ -9,4 +9,10 @@
|
||||
Contact KDAB at <info@kdab.com> for commercial licensing options.
|
||||
*/
|
||||
|
||||
#include "../../DockWidget.h"
|
||||
import QtQuick 2.9
|
||||
|
||||
Guest {
|
||||
anchors.fill: parent
|
||||
background: "qrc:/assets/base.png"
|
||||
logo: "qrc:/assets/KDAB_bubble_fulcolor.png"
|
||||
}
|
||||
95
examples/qtquick/customtabbar/MyTabBar.qml
Normal file
95
examples/qtquick/customtabbar/MyTabBar.qml
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
This file is part of KDDockWidgets.
|
||||
|
||||
SPDX-FileCopyrightText: 2020-2022 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
|
||||
Author: Sergio Martins <sergio.martins@kdab.com>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
Contact KDAB at <info@kdab.com> for commercial licensing options.
|
||||
*/
|
||||
|
||||
import QtQuick 2.6
|
||||
|
||||
// Will be moved to a plugin in the future, if there's enough demand
|
||||
import "qrc:/kddockwidgets/qtquick/views/qml/" as KDDW
|
||||
|
||||
/// Example of a QML Tab Bar that doesn't use QtQuick.Controls, just for demo purposes.
|
||||
/// Se the comments named "#HERE#" for important things you shouldn't forget.
|
||||
|
||||
KDDW.TabBarBase {
|
||||
id: root
|
||||
|
||||
implicitHeight: 30
|
||||
currentTabIndex: 0
|
||||
|
||||
/// #HERE#. This function required in all derived tab bars. It's called by C++;
|
||||
/// Returns the tab bar (QQuickItem*) at the specified index.
|
||||
function getTabAtIndex(index) {
|
||||
return tabBarRow.children[index];
|
||||
}
|
||||
|
||||
/// #HERE#. This function required in all derived tab bars. It's called by C++;
|
||||
/// Returns an int, with the index of the tab that's at the specified position.
|
||||
function getTabIndexAtPosition(globalPoint) {
|
||||
for (var i = 0; i < tabBarRow.children.length; ++i) {
|
||||
var tab = tabBarRow.children[i];
|
||||
var localPt = tab.mapFromGlobal(globalPoint.x, globalPoint.y);
|
||||
if (tab.contains(localPt)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
Row {
|
||||
id: tabBarRow
|
||||
|
||||
anchors.fill: parent
|
||||
spacing: 2
|
||||
|
||||
/// Needed only if you want to style hovered tabs differently
|
||||
property int hoveredIndex: -1;
|
||||
|
||||
/// ##HERE## The list of tabs is stored in a C++ model. This repeater populates our tab bar
|
||||
Repeater {
|
||||
model: root.groupCpp ? root.groupCpp.tabBar.dockWidgetModel : 0
|
||||
Rectangle {
|
||||
id: tab
|
||||
height: parent.height
|
||||
width: 100
|
||||
color: (tabBarRow.hoveredIndex == index) ? "#ba7600" : "orange"
|
||||
border.color: "black"
|
||||
|
||||
// ##HERE## Illustrating how to have a different style in case the tab is current
|
||||
border.width: index == root.groupCpp.currentIndex ? 3 : 1
|
||||
|
||||
// ##HERE## The index of the tab. This is required in all custom tab bar implementations
|
||||
// It is be used by "getTabAtIndex()" and "getTabIndexAtPosition()" functions
|
||||
readonly property int tabIndex: index
|
||||
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
text: title
|
||||
}
|
||||
|
||||
/// ##HERE## Tells the C++ backend that the current tab should change
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
root.currentTabIndex = index;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: tabBarCpp
|
||||
|
||||
function onHoveredTabIndexChanged(index) {
|
||||
tabBarRow.hoveredIndex = index;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
74
examples/qtquick/customtabbar/main.cpp
Normal file
74
examples/qtquick/customtabbar/main.cpp
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
This file is part of KDDockWidgets.
|
||||
|
||||
SPDX-FileCopyrightText: 2020-2022 Klarälvdalens Datakonsult AB, a KDAB Group company
|
||||
<info@kdab.com> Author: Sergio Martins <sergio.martins@kdab.com>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
Contact KDAB at <info@kdab.com> for commercial licensing options.
|
||||
*/
|
||||
|
||||
|
||||
#include <kddockwidgets/Config.h>
|
||||
#include <kddockwidgets/views/DockWidget_qtquick.h>
|
||||
#include <kddockwidgets/Platform_qtquick.h>
|
||||
#include <kddockwidgets/ViewFactory_qtquick.h>
|
||||
#include <kddockwidgets/private/DockRegistry.h>
|
||||
#include <kddockwidgets/views/MainWindow_qtquick.h>
|
||||
|
||||
|
||||
#include <QQuickView>
|
||||
#include <QGuiApplication>
|
||||
#include <QQmlApplicationEngine>
|
||||
|
||||
class CustomViewFactory : public KDDockWidgets::ViewFactory_qtquick
|
||||
{
|
||||
public:
|
||||
~CustomViewFactory() override;
|
||||
|
||||
QUrl tabbarFilename() const override
|
||||
{
|
||||
return QUrl("qrc:/MyTabBar.qml");
|
||||
}
|
||||
};
|
||||
|
||||
CustomViewFactory::~CustomViewFactory() = default;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
QGuiApplication::setAttribute(Qt::AA_UseOpenGLES);
|
||||
#endif
|
||||
QGuiApplication app(argc, argv);
|
||||
KDDockWidgets::initFrontend(KDDockWidgets::FrontendType::QtQuick);
|
||||
|
||||
auto &config = KDDockWidgets::Config::self();
|
||||
auto flags = config.flags();
|
||||
|
||||
config.setFlags(flags);
|
||||
config.setViewFactory(new CustomViewFactory());
|
||||
|
||||
QQmlApplicationEngine appEngine;
|
||||
KDDockWidgets::Platform_qtquick::instance()->setQmlEngine(&appEngine);
|
||||
appEngine.load((QUrl("qrc:/main.qml")));
|
||||
|
||||
auto dw1 = new KDDockWidgets::Views::DockWidget_qtquick("Dock #1");
|
||||
|
||||
dw1->setGuestItem(QStringLiteral("qrc:/Guest1.qml"));
|
||||
|
||||
auto dw2 = new KDDockWidgets::Views::DockWidget_qtquick("Dock #2");
|
||||
dw2->setGuestItem(QStringLiteral("qrc:/Guest2.qml"));
|
||||
|
||||
auto dw3 = new KDDockWidgets::Views::DockWidget_qtquick("Dock #3");
|
||||
dw3->setGuestItem(QStringLiteral("qrc:/Guest3.qml"));
|
||||
|
||||
// Access the main area we created in QML with DockingArea {}
|
||||
auto mainArea = KDDockWidgets::DockRegistry::self()->mainDockingAreas().constFirst();
|
||||
mainArea->addDockWidget(dw1, KDDockWidgets::Location_OnTop);
|
||||
|
||||
dw1->addDockWidgetAsTab(dw2);
|
||||
dw1->addDockWidgetAsTab(dw3);
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
27
examples/qtquick/customtabbar/main.qml
Normal file
27
examples/qtquick/customtabbar/main.qml
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
This file is part of KDDockWidgets.
|
||||
|
||||
SPDX-FileCopyrightText: 2020-2022 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
|
||||
Author: Sergio Martins <sergio.martins@kdab.com>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
Contact KDAB at <info@kdab.com> for commercial licensing options.
|
||||
*/
|
||||
|
||||
import QtQuick 2.6
|
||||
import QtQuick.Controls 2.12
|
||||
import com.kdab.dockwidgets 2.0 as KDDW
|
||||
|
||||
ApplicationWindow {
|
||||
visible: true
|
||||
width: 1000
|
||||
height: 800
|
||||
|
||||
KDDW.DockingArea {
|
||||
id: dockWidgetArea
|
||||
anchors.fill: parent
|
||||
|
||||
uniqueName: "MyMainLayout"
|
||||
}
|
||||
}
|
||||
10
examples/qtquick/customtabbar/resources_qtquick_example.qrc
Normal file
10
examples/qtquick/customtabbar/resources_qtquick_example.qrc
Normal file
@@ -0,0 +1,10 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>main.qml</file>
|
||||
<file>Guest1.qml</file>
|
||||
<file>Guest2.qml</file>
|
||||
<file>Guest3.qml</file>
|
||||
<file>Guest.qml</file>
|
||||
<file>MyTabBar.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
@@ -10,15 +10,15 @@
|
||||
#
|
||||
|
||||
cmake_minimum_required(VERSION 3.7)
|
||||
project(kddockwidgets_customtitlebar_quick)
|
||||
project(qtquick_customtitlebar)
|
||||
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
set(CMAKE_INCLUDE_CURRENT_DIRS ON)
|
||||
|
||||
if(NOT TARGET kddockwidgets)
|
||||
# This will look for Qt, do find_package yourself manually before
|
||||
# if you want to look for a specific Qt version for instance.
|
||||
# This will look for Qt, do find_package yourself manually before if you want
|
||||
# to look for a specific Qt version for instance.
|
||||
find_package(KDDockWidgets REQUIRED)
|
||||
endif()
|
||||
|
||||
@@ -26,12 +26,6 @@ set(RESOURCES_EXAMPLE_SRC ${CMAKE_CURRENT_SOURCE_DIR}/resources_qtquick_example.
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../dockwidgets/resources_example.qrc
|
||||
)
|
||||
|
||||
add_executable(
|
||||
kddockwidgets_customtitlebar_quick
|
||||
${RESOURCES_EXAMPLE_SRC} main.cpp
|
||||
)
|
||||
add_executable(qtquick_customtitlebar main.cpp ${RESOURCES_EXAMPLE_SRC})
|
||||
|
||||
target_link_libraries(
|
||||
kddockwidgets_customtitlebar_quick
|
||||
PRIVATE KDAB::kddockwidgets
|
||||
)
|
||||
target_link_libraries(qtquick_customtitlebar PRIVATE KDAB::kddockwidgets)
|
||||
|
||||
@@ -10,27 +10,40 @@
|
||||
*/
|
||||
|
||||
import QtQuick 2.9
|
||||
import QtQuick.Controls 2.12
|
||||
import QtQuick.Layouts 1.12
|
||||
import QtQuick.Controls 1.5 as QQC1
|
||||
|
||||
import com.kdab.dockwidgets 2.0 as KDDW
|
||||
|
||||
Item {
|
||||
anchors.fill: parent
|
||||
|
||||
property alias background: background.source
|
||||
property alias logo: logo.source
|
||||
property var background
|
||||
property var logo
|
||||
|
||||
KDDW.LayoutSaver {
|
||||
id: layoutSaver
|
||||
}
|
||||
|
||||
Image {
|
||||
id: background
|
||||
anchors.fill: parent
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: "green"
|
||||
|
||||
Image {
|
||||
id: logo
|
||||
ColumnLayout {
|
||||
Button {
|
||||
text: "Save"
|
||||
onClicked: {
|
||||
layoutSaver.saveToFile ("/tmp/layout");
|
||||
}
|
||||
}
|
||||
|
||||
fillMode: Image.PreserveAspectFit
|
||||
anchors {
|
||||
fill: parent
|
||||
margins: 50
|
||||
}
|
||||
}
|
||||
}
|
||||
Button {
|
||||
text: "Restore"
|
||||
onClicked: {
|
||||
layoutSaver.restoreFromFile ("/tmp/layout");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
|
||||
import QtQuick 2.6
|
||||
|
||||
// Will be moved to a plugin in the future
|
||||
import "qrc:/kddockwidgets/private/quick/qml/" as KDDW
|
||||
// Will be moved to a plugin in the future, if there's enough demand
|
||||
import "qrc:/kddockwidgets/qtquick/views/qml/" as KDDW
|
||||
|
||||
KDDW.TitleBarBase {
|
||||
id: root
|
||||
@@ -32,6 +32,26 @@ KDDW.TitleBarBase {
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: floatButton
|
||||
visible: root.floatButtonVisible
|
||||
radius: 5
|
||||
color: "red"
|
||||
height: root.height - 20
|
||||
width: height
|
||||
anchors {
|
||||
right: closeButton.left
|
||||
rightMargin: 10
|
||||
verticalCenter: root.verticalCenter
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
root.floatButtonClicked();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: closeButton
|
||||
enabled: root.closeButtonEnabled
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
This file is part of KDDockWidgets.
|
||||
|
||||
SPDX-FileCopyrightText: 2020-2022 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
|
||||
Author: Sergio Martins <sergio.martins@kdab.com>
|
||||
SPDX-FileCopyrightText: 2020-2022 Klarälvdalens Datakonsult AB, a KDAB Group company
|
||||
<info@kdab.com> Author: Sergio Martins <sergio.martins@kdab.com>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
@@ -11,18 +11,21 @@
|
||||
|
||||
|
||||
#include <kddockwidgets/Config.h>
|
||||
#include <kddockwidgets/DockWidgetQuick.h>
|
||||
#include <kddockwidgets/private/DockRegistry_p.h>
|
||||
#include <kddockwidgets/FrameworkWidgetFactory.h>
|
||||
#include <kddockwidgets/views/DockWidget_qtquick.h>
|
||||
#include <kddockwidgets/Platform_qtquick.h>
|
||||
#include <kddockwidgets/ViewFactory_qtquick.h>
|
||||
#include <kddockwidgets/private/DockRegistry.h>
|
||||
#include <kddockwidgets/views/MainWindow_qtquick.h>
|
||||
|
||||
|
||||
#include <QQuickView>
|
||||
#include <QGuiApplication>
|
||||
#include <QQmlApplicationEngine>
|
||||
|
||||
class CustomFrameworkWidgetFactory : public KDDockWidgets::DefaultWidgetFactory
|
||||
class CustomViewFactory : public KDDockWidgets::ViewFactory_qtquick
|
||||
{
|
||||
public:
|
||||
~CustomFrameworkWidgetFactory() override;
|
||||
~CustomViewFactory() override;
|
||||
|
||||
QUrl titleBarFilename() const override
|
||||
{
|
||||
@@ -30,7 +33,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
CustomFrameworkWidgetFactory::~CustomFrameworkWidgetFactory() = default;
|
||||
CustomViewFactory::~CustomViewFactory() = default;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
@@ -38,34 +41,39 @@ int main(int argc, char *argv[])
|
||||
QGuiApplication::setAttribute(Qt::AA_UseOpenGLES);
|
||||
#endif
|
||||
QGuiApplication app(argc, argv);
|
||||
KDDockWidgets::initFrontend(KDDockWidgets::FrontendType::QtQuick);
|
||||
|
||||
auto &config = KDDockWidgets::Config::self();
|
||||
auto flags = config.flags();
|
||||
|
||||
config.setFlags(flags);
|
||||
config.setFrameworkWidgetFactory(new CustomFrameworkWidgetFactory());
|
||||
config.setViewFactory(new CustomViewFactory());
|
||||
|
||||
QQmlApplicationEngine appEngine;
|
||||
KDDockWidgets::Config::self().setQmlEngine(&appEngine);
|
||||
KDDockWidgets::Platform_qtquick::instance()->setQmlEngine(&appEngine);
|
||||
appEngine.load((QUrl("qrc:/main.qml")));
|
||||
|
||||
auto dw1 = new KDDockWidgets::DockWidgetQuick("Dock #1");
|
||||
auto dw1 = new KDDockWidgets::Views::DockWidget_qtquick("Dock #1");
|
||||
|
||||
dw1->setWidget(QStringLiteral("qrc:/Guest1.qml"));
|
||||
dw1->setGuestItem(QStringLiteral("qrc:/Guest1.qml"));
|
||||
dw1->resize(QSize(800, 800));
|
||||
dw1->show();
|
||||
// dw1->open();
|
||||
|
||||
auto dw2 = new KDDockWidgets::DockWidgetQuick("Dock #2");
|
||||
dw2->setWidget(QStringLiteral("qrc:/Guest2.qml"));
|
||||
auto dw2 = new KDDockWidgets::Views::DockWidget_qtquick("Dock #2");
|
||||
dw2->setGuestItem(QStringLiteral("qrc:/Guest2.qml"));
|
||||
dw2->resize(QSize(800, 800));
|
||||
dw2->show();
|
||||
// dw2->open();
|
||||
|
||||
auto dw3 = new KDDockWidgets::DockWidgetQuick("Dock #3");
|
||||
dw3->setWidget(QStringLiteral("qrc:/Guest3.qml"));
|
||||
auto dw3 = new KDDockWidgets::Views::DockWidget_qtquick("Dock #3");
|
||||
dw3->setGuestItem(QStringLiteral("qrc:/Guest3.qml"));
|
||||
|
||||
dw1->addDockWidgetToContainingWindow(dw3, KDDockWidgets::Location_OnRight);
|
||||
// dw1->addDockWidgetToContainingWindow(dw3, KDDockWidgets::Location_OnRight);
|
||||
|
||||
// Access the main area we created in QML with DockingArea {}
|
||||
auto mainArea = KDDockWidgets::DockRegistry::self()->mainDockingAreas().constFirst();
|
||||
mainArea->addDockWidget(dw1, KDDockWidgets::Location_OnTop);
|
||||
mainArea->addDockWidget(dw2, KDDockWidgets::Location_OnTop);
|
||||
mainArea->addDockWidget(dw3, KDDockWidgets::Location_OnTop);
|
||||
|
||||
KDDockWidgets::MainWindowBase *mainWindow = KDDockWidgets::DockRegistry::self()->mainwindows().constFirst();
|
||||
mainWindow->addDockWidget(dw2, KDDockWidgets::Location_OnTop);
|
||||
return app.exec();
|
||||
}
|
||||
|
||||
@@ -11,14 +11,14 @@
|
||||
|
||||
import QtQuick 2.6
|
||||
import QtQuick.Controls 2.12
|
||||
import com.kdab.dockwidgets 1.0 as KDDW
|
||||
import com.kdab.dockwidgets 2.0 as KDDW
|
||||
|
||||
ApplicationWindow {
|
||||
visible: true
|
||||
width: 1000
|
||||
height: 800
|
||||
|
||||
KDDW.MainWindowLayout {
|
||||
KDDW.DockingArea {
|
||||
id: dockWidgetArea
|
||||
anchors.fill: parent
|
||||
|
||||
|
||||
@@ -10,15 +10,15 @@
|
||||
#
|
||||
|
||||
cmake_minimum_required(VERSION 3.7)
|
||||
project(kddockwidgets_example_quick)
|
||||
project(qtquick_dockwidgets)
|
||||
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
set(CMAKE_INCLUDE_CURRENT_DIRS ON)
|
||||
|
||||
if(NOT TARGET kddockwidgets)
|
||||
# This will look for Qt, do find_package yourself manually before
|
||||
# if you want to look for a specific Qt version for instance.
|
||||
# This will look for Qt, do find_package yourself manually before if you want
|
||||
# to look for a specific Qt version for instance.
|
||||
find_package(KDDockWidgets REQUIRED)
|
||||
endif()
|
||||
|
||||
@@ -26,12 +26,6 @@ set(RESOURCES_EXAMPLE_SRC ${CMAKE_CURRENT_SOURCE_DIR}/resources_qtquick_example.
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../dockwidgets/resources_example.qrc
|
||||
)
|
||||
|
||||
add_executable(
|
||||
kddockwidgets_example_quick
|
||||
${RESOURCES_EXAMPLE_SRC} main.cpp
|
||||
)
|
||||
add_executable(qtquick_dockwidgets main.cpp ${RESOURCES_EXAMPLE_SRC})
|
||||
|
||||
target_link_libraries(
|
||||
kddockwidgets_example_quick
|
||||
PRIVATE KDAB::kddockwidgets
|
||||
)
|
||||
target_link_libraries(qtquick_dockwidgets PRIVATE KDAB::kddockwidgets)
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*/
|
||||
|
||||
import QtQuick 2.9
|
||||
import com.kdab.dockwidgets 1.0 as KDDW
|
||||
import com.kdab.dockwidgets 2.0 as KDDW
|
||||
|
||||
Guest {
|
||||
anchors.fill: parent
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
This file is part of KDDockWidgets.
|
||||
|
||||
SPDX-FileCopyrightText: 2020-2022 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
|
||||
Author: Sergio Martins <sergio.martins@kdab.com>
|
||||
SPDX-FileCopyrightText: 2020-2022 Klarälvdalens Datakonsult AB, a KDAB Group company
|
||||
<info@kdab.com> Author: Sergio Martins <sergio.martins@kdab.com>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
@@ -11,9 +11,11 @@
|
||||
|
||||
|
||||
#include <kddockwidgets/Config.h>
|
||||
#include <kddockwidgets/DockWidgetQuick.h>
|
||||
#include <kddockwidgets/private/DockRegistry_p.h>
|
||||
#include <kddockwidgets/FrameworkWidgetFactory.h>
|
||||
#include <kddockwidgets/private/DockRegistry.h>
|
||||
#include <kddockwidgets/ViewFactory.h>
|
||||
#include <kddockwidgets/Platform_qtquick.h>
|
||||
#include <kddockwidgets/views/DockWidget_qtquick.h>
|
||||
#include "kddockwidgets/views/MainWindow_qtquick.h"
|
||||
|
||||
#include <QQmlApplicationEngine>
|
||||
#include <QGuiApplication>
|
||||
@@ -29,24 +31,45 @@ int main(int argc, char *argv[])
|
||||
QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
#endif
|
||||
QGuiApplication app(argc, argv);
|
||||
|
||||
KDDockWidgets::initFrontend(KDDockWidgets::FrontendType::QtQuick);
|
||||
|
||||
QCommandLineParser parser;
|
||||
parser.setApplicationDescription("KDDockWidgets example application");
|
||||
parser.addHelpOption();
|
||||
|
||||
QCommandLineOption noTitleBars(
|
||||
"t", QCoreApplication::translate("main", "Hide titlebars when tabs are visible"));
|
||||
parser.addOption(noTitleBars);
|
||||
|
||||
QCommandLineOption alwaysTabs(
|
||||
"z", QCoreApplication::translate("main", "Show tabs even if there's only one"));
|
||||
parser.addOption(alwaysTabs);
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
QCommandLineOption nativeTitleBar(
|
||||
"native-title-bar",
|
||||
QCoreApplication::translate("main", "(internal) FloatingWindows a native title bar"));
|
||||
parser.addOption(nativeTitleBar);
|
||||
#endif
|
||||
|
||||
#if defined(DOCKS_DEVELOPER_MODE)
|
||||
QCommandLineOption noQtTool("no-qttool", QCoreApplication::translate("main", "(internal) Don't use Qt::Tool"));
|
||||
QCommandLineOption noParentForFloating("no-parent-for-floating", QCoreApplication::translate("main", "(internal) FloatingWindows won't have a parent"));
|
||||
QCommandLineOption nativeTitleBar("native-title-bar", QCoreApplication::translate("main", "(internal) FloatingWindows a native title bar"));
|
||||
QCommandLineOption noDropIndicators("no-drop-indicators", QCoreApplication::translate("main", "(internal) Don't use any drop indicators"));
|
||||
QCommandLineOption noQtTool(
|
||||
"no-qttool", QCoreApplication::translate("main", "(internal) Don't use Qt::Tool"));
|
||||
QCommandLineOption noParentForFloating(
|
||||
"no-parent-for-floating",
|
||||
QCoreApplication::translate("main", "(internal) FloatingWindows won't have a parent"));
|
||||
QCommandLineOption noDropIndicators(
|
||||
"no-drop-indicators",
|
||||
QCoreApplication::translate("main", "(internal) Don't use any drop indicators"));
|
||||
|
||||
parser.addOption(noQtTool);
|
||||
parser.addOption(noParentForFloating);
|
||||
parser.addOption(nativeTitleBar);
|
||||
parser.addOption(noDropIndicators);
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
QCommandLineOption noAeroSnap("no-aero-snap", QCoreApplication::translate("main", "(internal) Disable AeroSnap"));
|
||||
QCommandLineOption noAeroSnap(
|
||||
"no-aero-snap", QCoreApplication::translate("main", "(internal) Disable AeroSnap"));
|
||||
parser.addOption(noAeroSnap);
|
||||
#endif
|
||||
#endif
|
||||
@@ -63,10 +86,8 @@ int main(int argc, char *argv[])
|
||||
if (parser.isSet(noParentForFloating))
|
||||
internalFlags |= KDDockWidgets::Config::InternalFlag_DontUseParentForFloatingWindows;
|
||||
|
||||
if (parser.isSet(nativeTitleBar))
|
||||
flags |= KDDockWidgets::Config::Flag_NativeTitleBar;
|
||||
else if (parser.isSet(noDropIndicators))
|
||||
KDDockWidgets::DefaultWidgetFactory::s_dropIndicatorType = KDDockWidgets::DropIndicatorType::None;
|
||||
if (parser.isSet(noDropIndicators))
|
||||
KDDockWidgets::ViewFactory::s_dropIndicatorType = KDDockWidgets::DropIndicatorType::None;
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
if (parser.isSet(noAeroSnap))
|
||||
@@ -77,35 +98,48 @@ int main(int argc, char *argv[])
|
||||
KDDockWidgets::Config::self().setInternalFlags(internalFlags);
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
// On Linux the title bar doesn't send us NonClient mouse events
|
||||
if (parser.isSet(nativeTitleBar))
|
||||
flags |= KDDockWidgets::Config::Flag_NativeTitleBar;
|
||||
#endif
|
||||
|
||||
if (parser.isSet(noTitleBars))
|
||||
flags |= KDDockWidgets::Config::Flag_HideTitleBarWhenTabsVisible;
|
||||
|
||||
if (parser.isSet(alwaysTabs))
|
||||
flags |= KDDockWidgets::Config::Flag_AlwaysShowTabs;
|
||||
|
||||
// Set any required flags. The defaults are usually fine.
|
||||
KDDockWidgets::Config::self().setFlags(flags);
|
||||
|
||||
// Create your engine which loads main.qml. A simple QQuickView would work too.
|
||||
QQmlApplicationEngine appEngine;
|
||||
KDDockWidgets::Config::self().setQmlEngine(&appEngine);
|
||||
KDDockWidgets::Platform_qtquick::instance()->setQmlEngine(&appEngine);
|
||||
appEngine.load((QUrl("qrc:/main.qml")));
|
||||
|
||||
// Below we illustrate usage of our C++ API. Alternative you can use declarative API.
|
||||
// See main.qml for examples of dockwidgets created directly in QML
|
||||
|
||||
auto dw1 = new KDDockWidgets::DockWidgetQuick("Dock #1");
|
||||
auto dw1 = new KDDockWidgets::Views::DockWidget_qtquick("Dock #1");
|
||||
|
||||
dw1->setWidget(QStringLiteral("qrc:/Guest1.qml"));
|
||||
dw1->setGuestItem(QStringLiteral("qrc:/Guest1.qml"));
|
||||
dw1->resize(QSize(800, 800));
|
||||
dw1->show();
|
||||
dw1->open();
|
||||
|
||||
auto dw2 = new KDDockWidgets::DockWidgetQuick("Dock #2");
|
||||
dw2->setWidget(QStringLiteral("qrc:/Guest2.qml"));
|
||||
auto dw2 = new KDDockWidgets::Views::DockWidget_qtquick("Dock #2");
|
||||
dw2->setGuestItem(QStringLiteral("qrc:/Guest2.qml"));
|
||||
dw2->resize(QSize(800, 800));
|
||||
dw2->show();
|
||||
dw2->open();
|
||||
|
||||
auto dw3 = new KDDockWidgets::DockWidgetQuick("Dock #3");
|
||||
dw3->setWidget(QStringLiteral("qrc:/Guest3.qml"));
|
||||
auto dw3 = new KDDockWidgets::Views::DockWidget_qtquick("Dock #3");
|
||||
dw3->setGuestItem(QStringLiteral("qrc:/Guest3.qml"));
|
||||
|
||||
dw1->addDockWidgetToContainingWindow(dw3, KDDockWidgets::Location_OnRight);
|
||||
|
||||
KDDockWidgets::MainWindowBase *mainWindow = KDDockWidgets::DockRegistry::self()->mainwindows().constFirst();
|
||||
mainWindow->addDockWidget(dw2, KDDockWidgets::Location_OnTop);
|
||||
// Access the main area we created in QML with DockingArea {}
|
||||
auto mainArea = KDDockWidgets::DockRegistry::self()->mainDockingAreas().constFirst();
|
||||
mainArea->addDockWidget(dw2, KDDockWidgets::Location_OnTop);
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
import QtQuick 2.6
|
||||
import QtQuick.Controls 2.12
|
||||
import com.kdab.dockwidgets 1.0 as KDDW
|
||||
import com.kdab.dockwidgets 2.0 as KDDW
|
||||
|
||||
ApplicationWindow {
|
||||
visible: true
|
||||
@@ -73,7 +73,7 @@ ApplicationWindow {
|
||||
}
|
||||
}
|
||||
|
||||
KDDW.MainWindowLayout {
|
||||
KDDW.DockingArea {
|
||||
anchors.fill: parent
|
||||
|
||||
// Each main layout needs a unique id
|
||||
@@ -109,6 +109,13 @@ ApplicationWindow {
|
||||
color: "black"
|
||||
}
|
||||
}
|
||||
KDDW.DockWidget {
|
||||
id: dock7
|
||||
uniqueName: "dock7"
|
||||
Rectangle {
|
||||
color: "green"
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
// Add dock4 to the Bottom location
|
||||
@@ -122,6 +129,10 @@ ApplicationWindow {
|
||||
// See MainWindowInstantiator_p.h for the API
|
||||
addDockWidget(dock6, KDDW.KDDockWidgets.Location_OnLeft, null,
|
||||
Qt.size(500, 100), KDDW.KDDockWidgets.StartHidden);
|
||||
|
||||
|
||||
// dock7 will be tabbed with dock7:
|
||||
dock5.addDockWidgetAsTab(dock7);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,15 +10,15 @@
|
||||
#
|
||||
|
||||
cmake_minimum_required(VERSION 3.7)
|
||||
project(kddockwidgets_example_mdi_quick)
|
||||
project(qtquick_mdi)
|
||||
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
set(CMAKE_INCLUDE_CURRENT_DIRS ON)
|
||||
|
||||
if(NOT TARGET kddockwidgets)
|
||||
# This will look for Qt, do find_package yourself manually before
|
||||
# if you want to look for a specific Qt version for instance.
|
||||
# This will look for Qt, do find_package yourself manually before if you want
|
||||
# to look for a specific Qt version for instance.
|
||||
find_package(KDDockWidgets REQUIRED)
|
||||
endif()
|
||||
|
||||
@@ -26,12 +26,6 @@ set(RESOURCES_EXAMPLE_SRC ${CMAKE_CURRENT_SOURCE_DIR}/resources_qtquick_mdi_exam
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../dockwidgets/resources_example.qrc
|
||||
)
|
||||
|
||||
add_executable(
|
||||
kddockwidgets_example_mdi_quick
|
||||
${RESOURCES_EXAMPLE_SRC} main.cpp
|
||||
)
|
||||
add_executable(qtquick_mdi main.cpp ${RESOURCES_EXAMPLE_SRC})
|
||||
|
||||
target_link_libraries(
|
||||
kddockwidgets_example_mdi_quick
|
||||
PRIVATE KDAB::kddockwidgets
|
||||
)
|
||||
target_link_libraries(qtquick_mdi PRIVATE KDAB::kddockwidgets)
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
import QtQuick 2.9
|
||||
import QtQuick.Controls 2.12
|
||||
import com.kdab.dockwidgets 1.0 as KDDW
|
||||
import com.kdab.dockwidgets 2.0 as KDDW
|
||||
|
||||
Guest {
|
||||
anchors.fill: parent
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
This file is part of KDDockWidgets.
|
||||
|
||||
SPDX-FileCopyrightText: 2020-2022 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
|
||||
Author: Sergio Martins <sergio.martins@kdab.com>
|
||||
SPDX-FileCopyrightText: 2020-2022 Klarälvdalens Datakonsult AB, a KDAB Group company
|
||||
<info@kdab.com> Author: Sergio Martins <sergio.martins@kdab.com>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
@@ -11,49 +11,53 @@
|
||||
|
||||
|
||||
#include <kddockwidgets/Config.h>
|
||||
#include <kddockwidgets/DockWidgetQuick.h>
|
||||
#include <kddockwidgets/private/DockRegistry_p.h>
|
||||
#include <kddockwidgets/FrameworkWidgetFactory.h>
|
||||
#include <kddockwidgets/MainWindowMDI.h>
|
||||
#include <kddockwidgets/views/DockWidget_qtquick.h>
|
||||
#include <kddockwidgets/views/MainWindowMDI_qtquick.h>
|
||||
#include <kddockwidgets/Platform_qtquick.h>
|
||||
#include <kddockwidgets/private/DockRegistry.h>
|
||||
#include <kddockwidgets/ViewFactory.h>
|
||||
#include "kddockwidgets/controllers/MainWindow.h"
|
||||
|
||||
#include <QQmlApplicationEngine>
|
||||
#include <QGuiApplication>
|
||||
#include <QCommandLineParser>
|
||||
|
||||
// Foro my own debugging, until we have better API
|
||||
#include "../../src/private/MDILayoutWidget_p.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
QGuiApplication::setAttribute(Qt::AA_UseOpenGLES);
|
||||
#endif
|
||||
QGuiApplication app(argc, argv);
|
||||
KDDockWidgets::initFrontend(KDDockWidgets::FrontendType::QtQuick);
|
||||
|
||||
QCommandLineParser parser;
|
||||
parser.setApplicationDescription("KDDockWidgets example application");
|
||||
parser.addHelpOption();
|
||||
|
||||
QQmlApplicationEngine appEngine;
|
||||
KDDockWidgets::Config::self().setQmlEngine(&appEngine);
|
||||
KDDockWidgets::Platform_qtquick::instance()->setQmlEngine(&appEngine);
|
||||
appEngine.load((QUrl("qrc:/main.qml")));
|
||||
|
||||
auto dw1 = new KDDockWidgets::DockWidgetQuick("Dock #1");
|
||||
dw1->setWidget(QStringLiteral("qrc:/Guest1.qml"));
|
||||
auto dw1 = new KDDockWidgets::Views::DockWidget_qtquick("Dock #1");
|
||||
dw1->setGuestItem(QStringLiteral("qrc:/Guest1.qml"));
|
||||
dw1->resize(QSize(400, 400));
|
||||
|
||||
auto dw2 = new KDDockWidgets::DockWidgetQuick("Dock #2");
|
||||
dw2->setWidget(QStringLiteral("qrc:/Guest2.qml"));
|
||||
auto dw2 = new KDDockWidgets::Views::DockWidget_qtquick("Dock #2");
|
||||
dw2->setGuestItem(QStringLiteral("qrc:/Guest2.qml"));
|
||||
dw2->resize(QSize(400, 400));
|
||||
|
||||
auto dw3 = new KDDockWidgets::DockWidgetQuick("Dock #3");
|
||||
dw3->setWidget(QStringLiteral("qrc:/Guest3.qml"));
|
||||
auto dw3 = new KDDockWidgets::Views::DockWidget_qtquick("Dock #3");
|
||||
dw3->setGuestItem(QStringLiteral("qrc:/Guest3.qml"));
|
||||
|
||||
auto mainWindow = static_cast<KDDockWidgets::MainWindowMDI *>(KDDockWidgets::DockRegistry::self()->mainwindows().constFirst());
|
||||
|
||||
mainWindow->addDockWidget(dw1, QPoint(10, 10));
|
||||
mainWindow->addDockWidget(dw2, QPoint(50, 50));
|
||||
mainWindow->addDockWidget(dw3, QPoint(90, 90));
|
||||
// See main.qml for how to add dock widgets from QML.
|
||||
// Here's a low level C++ example just for educational purposes:
|
||||
auto mainAreaView = KDDockWidgets::DockRegistry::self()->mainDockingAreas().constFirst();
|
||||
auto mainAreaMDI = static_cast<KDDockWidgets::Views::MainWindowMDI_qtquick *>(mainAreaView);
|
||||
|
||||
mainAreaMDI->addDockWidget(dw1, QPoint(10, 10));
|
||||
mainAreaMDI->addDockWidget(dw2, QPoint(50, 50));
|
||||
mainAreaMDI->addDockWidget(dw3, QPoint(90, 90));
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
|
||||
@@ -11,16 +11,29 @@
|
||||
|
||||
import QtQuick 2.6
|
||||
import QtQuick.Controls 2.12
|
||||
import com.kdab.dockwidgets 1.0 as KDDW
|
||||
import com.kdab.dockwidgets 2.0 as KDDW
|
||||
|
||||
ApplicationWindow {
|
||||
visible: true
|
||||
width: 1000
|
||||
height: 1200
|
||||
|
||||
KDDW.MainWindowLayout {
|
||||
KDDW.MDIDockingArea {
|
||||
id: dockingArea
|
||||
anchors.fill: parent
|
||||
uniqueName: "MyMainLayout"
|
||||
options: KDDW.KDDockWidgets.MainWindowOption_MDI
|
||||
}
|
||||
|
||||
KDDW.DockWidget {
|
||||
id: greenDock
|
||||
uniqueName: "greenDock"
|
||||
Rectangle {
|
||||
color: "green"
|
||||
anchors.fill: parent
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
dockingArea.addDockWidget(greenDock, Qt.point(200, 200));
|
||||
}
|
||||
}
|
||||
|
||||
8
mkdocs.yml
Normal file
8
mkdocs.yml
Normal file
@@ -0,0 +1,8 @@
|
||||
site_name: KDDockWidgets
|
||||
site_url: https://github.com/KDAB/KDDockWidgets/
|
||||
docs_dir: docs_devel
|
||||
nav:
|
||||
- Home: index.md
|
||||
- Concepts: concepts.md
|
||||
- About: about.md
|
||||
theme: readthedocs
|
||||
@@ -11,10 +11,10 @@
|
||||
set(PYTHON_BINDING_NAMESPACE "PyKDDockWidgets")
|
||||
|
||||
# Just to fix warnings with --warn-uninitialized
|
||||
if(NOT DEFINED SHIBOKEN_CUSTOM_PREFIX) #look for shiboken in a custom location
|
||||
if(NOT DEFINED SHIBOKEN_CUSTOM_PREFIX) # look for shiboken in a custom location
|
||||
set(SHIBOKEN_CUSTOM_PREFIX "")
|
||||
endif()
|
||||
if(NOT DEFINED PYSIDE_CUSTOM_PREFIX) #look for pyside in a custom location
|
||||
if(NOT DEFINED PYSIDE_CUSTOM_PREFIX) # look for pyside in a custom location
|
||||
set(PYSIDE_CUSTOM_PREFIX "")
|
||||
endif()
|
||||
|
||||
@@ -34,11 +34,11 @@ find_package(PySide${PYSIDE_MAJOR_VERSION} ${QtWidgets_VERSION} EXACT REQUIRED)
|
||||
if(NOT ${PROJECT_NAME}_PYTHON_BINDINGS_INSTALL_PREFIX)
|
||||
set(${PROJECT_NAME}_PYTHON_BINDINGS_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")
|
||||
endif()
|
||||
set(Python3_VERSION_MAJORMINOR "${Python3_VERSION_MAJOR}.${Python3_VERSION_MINOR}")
|
||||
set(Python3_VERSION_MAJORMIONR "${Python3_VERSION_MAJOR}.${Python3_VERSION_MINOR}")
|
||||
set(BINDINGS_DIR "${INSTALL_LIBRARY_DIR}/python${Python3_VERSION_MAJORMINOR}/site-packages/${PYTHON_BINDING_NAMESPACE}")
|
||||
set(${PROJECT_NAME}_PYTHON_BINDINGS_INSTALL_PREFIX "${${PROJECT_NAME}_PYTHON_BINDINGS_INSTALL_PREFIX}/${BINDINGS_DIR}")
|
||||
|
||||
include(KDPySide${PYSIDE_MAJOR_VERSION}ModuleBuild)
|
||||
include(PySide${PYSIDE_MAJOR_VERSION}ModuleBuild)
|
||||
add_subdirectory(PyKDDockWidgets)
|
||||
if(${PROJECT_NAME}_TESTS)
|
||||
add_subdirectory(tests)
|
||||
|
||||
@@ -35,29 +35,23 @@ set(PyKDDockWidgets_include_paths
|
||||
)
|
||||
|
||||
# A list of paths where shiboken should look for typesystem
|
||||
set(PyKDDockWidgets_typesystem_paths # PySide path, this variable was exposed by FindPySide2.cmake
|
||||
set(PyKDDockWidgets_typesystem_paths # PySide path, this variable was exposed by
|
||||
# FindPySide2.cmake
|
||||
${PYSIDE_TYPESYSTEMS}
|
||||
)
|
||||
|
||||
# Include flags/path that will be set in 'target_include_directories'
|
||||
set(PyKDDockWidgets_target_include_directories ${CMAKE_SOURCE_DIR}/src)
|
||||
|
||||
# Libraries that will be necessary to link the target, this will used in the command 'target_link_libraries'
|
||||
set(PyKDDockWidgets_target_link_libraries
|
||||
KDAB::kddockwidgets
|
||||
Qt${Qt_VERSION_MAJOR}::Core
|
||||
Qt${Qt_VERSION_MAJOR}::Gui
|
||||
Qt${Qt_VERSION_MAJOR}::Widgets
|
||||
${Python3_LIBRARIES}
|
||||
# Libraries that will be necessary to link the target, this will used in the
|
||||
# command 'target_link_libraries'
|
||||
set(PyKDDockWidgets_target_link_libraries KDAB::kddockwidgets Qt${Qt_VERSION_MAJOR}::Core Qt${Qt_VERSION_MAJOR}::Gui
|
||||
Qt${Qt_VERSION_MAJOR}::Widgets ${Python3_LIBRARIES}
|
||||
)
|
||||
|
||||
# changes on these files should trigger a new generation
|
||||
set(PyKDDockWidgets_DEPENDS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/kddockwidgets_global.h
|
||||
${CMAKE_SOURCE_DIR}/src/DockWidgetBase.h
|
||||
${CMAKE_SOURCE_DIR}/src/DockWidget.h
|
||||
${CMAKE_SOURCE_DIR}/src/MainWindowBase.h
|
||||
${CMAKE_SOURCE_DIR}/src/MainWindow.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/kddockwidgets_global.h ${CMAKE_SOURCE_DIR}/src/DockWidget.h
|
||||
${CMAKE_SOURCE_DIR}/src/DockWidget.h ${CMAKE_SOURCE_DIR}/src/MainWindow.h ${CMAKE_SOURCE_DIR}/src/MainWindow.h
|
||||
${CMAKE_SOURCE_DIR}/src/LayoutSaver.h
|
||||
)
|
||||
|
||||
@@ -78,9 +72,8 @@ create_python_bindings(
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/__init__.py.cmake ${CMAKE_CURRENT_BINARY_DIR}/__init__.py @ONLY)
|
||||
|
||||
# install
|
||||
install(
|
||||
FILES ${CMAKE_CURRENT_BINARY_DIR}/__init__.py $<TARGET_FILE:KDAB::kddockwidgets>
|
||||
DESTINATION ${${PROJECT_NAME}_PYTHON_BINDINGS_INSTALL_PREFIX}
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/__init__.py $<TARGET_FILE:KDAB::kddockwidgets>
|
||||
DESTINATION ${${PROJECT_NAME}_PYTHON_BINDINGS_INSTALL_PREFIX}
|
||||
)
|
||||
if(NOT WIN32)
|
||||
install(FILES $<TARGET_LINKER_FILE:KDAB::kddockwidgets> $<TARGET_SONAME_FILE:KDAB::kddockwidgets>
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
#define QT_WIDGETS_LIB
|
||||
#endif
|
||||
|
||||
#include <kddockwidgets/MainWindowBase.h>
|
||||
#include <kddockwidgets/MainWindow.h>
|
||||
#include <kddockwidgets/DockWidgetBase.h>
|
||||
#include <kddockwidgets/MainWindow.h>
|
||||
#include <kddockwidgets/DockWidget.h>
|
||||
#include <kddockwidgets/DockWidget.h>
|
||||
#include <kddockwidgets/LayoutSaver.h>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<namespace-type name="KDDockWidgets" visible="no">
|
||||
<!-- this is used in a public virtual pure function we need to declare it
|
||||
otherwise shiboken will ignore the function and will fail to create a wrapper -->
|
||||
<primitive-type name="DropAreaWithCentralFrame"/>
|
||||
<primitive-type name="DropArea"/>
|
||||
<primitive-type name="SideBar"/>
|
||||
|
||||
<!-- Some plublic enum and flags -->
|
||||
|
||||
21
src/3rdparty/doctest/LICENSE.txt
vendored
Normal file
21
src/3rdparty/doctest/LICENSE.txt
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016-2021 Viktor Kirilov
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
6816
src/3rdparty/doctest/doctest.h
vendored
Normal file
6816
src/3rdparty/doctest/doctest.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
298
src/3rdparty/kdbindings/binding.h
vendored
Normal file
298
src/3rdparty/kdbindings/binding.h
vendored
Normal file
@@ -0,0 +1,298 @@
|
||||
/*
|
||||
This file is part of KDBindings.
|
||||
|
||||
SPDX-FileCopyrightText: 2021-2022 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
|
||||
Author: Sean Harmer <sean.harmer@kdab.com>
|
||||
|
||||
SPDX-License-Identifier: MIT
|
||||
|
||||
Contact KDAB at <info@kdab.com> for commercial licensing options.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <kdbindings/node.h>
|
||||
#include <kdbindings/node_operators.h>
|
||||
#include <kdbindings/node_functions.h>
|
||||
#include <kdbindings/make_node.h>
|
||||
#include <kdbindings/binding_evaluator.h>
|
||||
#include <kdbindings/property_updater.h>
|
||||
|
||||
namespace KDBindings {
|
||||
|
||||
/**
|
||||
* @brief A combination of a root Node with an evaluator.
|
||||
*
|
||||
* A root Node is formed whenever multiple properties are combined inside
|
||||
* a expression and an evaluator is responsible for re-evaluating such
|
||||
* an expression whenever any of the constituent properties change.
|
||||
*
|
||||
* @tparam T The type of the value that the Binding expression evaluates to.
|
||||
* @tparam EvaluatorT The type of the evaluator that is used to evaluate the Binding.
|
||||
*/
|
||||
template<typename T, typename EvaluatorT = BindingEvaluator>
|
||||
class Binding : public PropertyUpdater<T>, public Private::Dirtyable
|
||||
{
|
||||
static_assert(
|
||||
std::is_base_of<BindingEvaluator, EvaluatorT>::value,
|
||||
"The EvaluatorT type must inherit from BindingEvaluator.");
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new Binding with a specific evaluator.
|
||||
*
|
||||
* @param rootNode Represents that expression contained in the Binding.
|
||||
* @param evaluator Used to evaluate the expression contained in the Binding.
|
||||
*/
|
||||
explicit Binding(Private::Node<T> &&rootNode, EvaluatorT const &evaluator)
|
||||
: m_rootNode{ std::move(rootNode) }
|
||||
, m_evaluator{ evaluator }
|
||||
{
|
||||
m_bindingId = m_evaluator.insert(this);
|
||||
m_rootNode.setParent(this);
|
||||
}
|
||||
|
||||
/** Destructs the Binding by deregistering it from its evaluator. */
|
||||
~Binding() override
|
||||
{
|
||||
m_evaluator.remove(m_bindingId);
|
||||
}
|
||||
|
||||
/** A Binding is not default constructible. */
|
||||
Binding() = delete;
|
||||
|
||||
/** A Binding cannot be copy constructed. */
|
||||
Binding(Binding const &other) = delete;
|
||||
/** A Binding cannot be copy assigned. */
|
||||
Binding &operator=(Binding const &other) = delete;
|
||||
|
||||
// Move construction would invalidate the this pointer passed to the evaluator
|
||||
// in the constructor
|
||||
/** A Binding can not be move constructed. */
|
||||
Binding(Binding &&other) = delete;
|
||||
/** A Binding can not be move assigned. */
|
||||
Binding &operator=(Binding &&other) = delete;
|
||||
|
||||
/** Set the function that should be used to notify
|
||||
* associated properties when the Binding re-evaluates.
|
||||
*/
|
||||
void setUpdateFunction(std::function<void(T &&)> const &updateFunction) override
|
||||
{
|
||||
m_propertyUpdateFunction = updateFunction;
|
||||
}
|
||||
|
||||
/** Returns the current value of the Binding. */
|
||||
T get() const override { return m_rootNode.evaluate(); }
|
||||
|
||||
/** Re-evaluates the value of the Binding and notifies all dependants of the change. */
|
||||
void evaluate()
|
||||
{
|
||||
T value = m_rootNode.evaluate();
|
||||
|
||||
// Use this to update any associated property via the PropertyUpdater's update function
|
||||
m_propertyUpdateFunction(std::move(value));
|
||||
}
|
||||
|
||||
protected:
|
||||
Private::Dirtyable **parentVariable() override { return nullptr; }
|
||||
const bool *dirtyVariable() const override { return nullptr; }
|
||||
|
||||
/** The root Node of the Binding represents the expression contained by the Binding. */
|
||||
Private::Node<T> m_rootNode;
|
||||
/** The evaluator responsible for evaluating this Binding. */
|
||||
EvaluatorT m_evaluator;
|
||||
/** The function used to notify associated properties when the Binding re-evaluates */
|
||||
std::function<void(T &&)> m_propertyUpdateFunction = [](T &&) {};
|
||||
/** The id of the Binding, used for keeping track of the Binding in its evaluator. */
|
||||
int m_bindingId = -1;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Helper function to create a Binding from a Property.
|
||||
*
|
||||
* @tparam T The type of the value that the Binding expression evaluates to.
|
||||
* @tparam EvaluatorT The type of the evaluator that is used to evaluate the Binding.
|
||||
* @param evaluator The evaluator that is used to evaluate the Binding.
|
||||
* @param property The Property to create a Binding from.
|
||||
* @return std::unique_ptr<Binding<T, EvaluatorT>> A new Binding that is powered by the evaluator.
|
||||
*
|
||||
* *Note: For the difference between makeBinding and makeBoundProperty, see the
|
||||
* ["Reassigning a Binding"](../../getting-started/data-binding/#reassigning-a-binding) section in the Getting Started guide.*
|
||||
*/
|
||||
template<typename T, typename EvaluatorT>
|
||||
inline std::unique_ptr<Binding<T, EvaluatorT>> makeBinding(EvaluatorT &evaluator, Property<T> &property)
|
||||
{
|
||||
return std::make_unique<Binding<T, EvaluatorT>>(Private::makeNode(property), evaluator);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Helper function to create a Binding from a root Node.
|
||||
*
|
||||
* @tparam T The type of the value that the Binding expression evaluates to.
|
||||
* @tparam EvaluatorT The type of the evaluator that is used to evaluate the Binding.
|
||||
* @param evaluator The evaluator that is used to evaluate the Binding.
|
||||
* @param rootNode Represents the expression that will be evaluated by the Binding.
|
||||
* @return std::unique_ptr<Binding<T, EvaluatorT>> A new Binding that combines the rootNode with the evaluator.
|
||||
*
|
||||
* *Note: For the difference between makeBinding and makeBoundProperty, see the
|
||||
* ["Reassigning a Binding"](../../getting-started/data-binding/#reassigning-a-binding) section in the Getting Started guide.*
|
||||
*/
|
||||
template<typename T, typename EvaluatorT>
|
||||
inline std::unique_ptr<Binding<T, EvaluatorT>> makeBinding(EvaluatorT &evaluator, Private::Node<T> &&rootNode)
|
||||
{
|
||||
return std::make_unique<Binding<T, EvaluatorT>>(std::move(rootNode), evaluator);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Helper function to create a Binding from a function and its arguments.
|
||||
*
|
||||
* @tparam EvaluatorT The type of the evaluator that is used to evaluate the Binding.
|
||||
* @param evaluator The evaluator that is used to evaluate the Binding.
|
||||
* @tparam Func The type of the function - may be any type that implements operator().
|
||||
* @param func The function object.
|
||||
* @tparam Args The function argument types
|
||||
* @param args The function arguments - Possible values include: Properties, Constants and Nodes
|
||||
* They will be automatically unwrapped, i.e. a Property<T> will pass a value of type T to func.
|
||||
* @return std::unique_ptr<Binding<ReturnType, EvaluatorT>> where ReturnType is the type that results from evaluationg func with the given arguments.
|
||||
* The Binding will be powered by the new evaluator.
|
||||
*
|
||||
* *Note: For the difference between makeBinding and makeBoundProperty, see the
|
||||
* ["Reassigning a Binding"](../../getting-started/data-binding/#reassigning-a-binding) section in the Getting Started guide.*
|
||||
*/
|
||||
template<typename EvaluatorT, typename Func, typename... Args, typename = std::enable_if_t<sizeof...(Args) != 0>, typename ResultType = Private::operator_node_result_t<Func, Args...>>
|
||||
inline std::unique_ptr<Binding<ResultType, EvaluatorT>> makeBinding(EvaluatorT &evaluator, Func &&func, Args &&...args)
|
||||
{
|
||||
return std::make_unique<Binding<ResultType, EvaluatorT>>(Private::makeNode(std::forward<Func>(func), std::forward<Args>(args)...), evaluator);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Provides a convenience for old-school, immediate mode Bindings.
|
||||
*
|
||||
* This works in conjunction with a do-nothing ImmediateBindingEvaluator class to update the
|
||||
* result of the Binding immediately upon any of the dependent bindables (i.e. Property instances)
|
||||
* notifying that they have changed. This can lead to a Property Binding being evaluated many
|
||||
* times before the result is ever used in a typical GUI application.
|
||||
*
|
||||
* @tparam T The type of the value that the Binding expression evaluates to.
|
||||
*/
|
||||
template<typename T>
|
||||
class Binding<T, ImmediateBindingEvaluator> : public Binding<T, BindingEvaluator>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new Binding with an immediate mode evaluator.
|
||||
*
|
||||
* @param rootNode Represents that expression contained in the Binding.
|
||||
*/
|
||||
explicit Binding(Private::Node<T> &&rootNode)
|
||||
: Binding<T, BindingEvaluator>(std::move(rootNode), ImmediateBindingEvaluator::instance())
|
||||
{
|
||||
}
|
||||
|
||||
/** A Binding is not default constructible. */
|
||||
Binding() = delete;
|
||||
|
||||
virtual ~Binding() = default;
|
||||
|
||||
/** A Binding cannot be copy constructed. */
|
||||
Binding(Binding const &other) = delete;
|
||||
/** A Binding cannot be copy assigned. */
|
||||
Binding &operator=(Binding const &other) = delete;
|
||||
|
||||
/** A Binding can not be move constructed. */
|
||||
Binding(Binding &&other) = delete;
|
||||
/** A Binding can not be move assigned. */
|
||||
Binding &operator=(Binding &&other) = delete;
|
||||
|
||||
void markDirty() override
|
||||
{
|
||||
Binding::evaluate();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Helper function to create an immediate mode Binding from a Property.
|
||||
*
|
||||
* @tparam T The type of the value that the Binding expression evaluates to.
|
||||
* @param property The Property to create a Binding from.
|
||||
* @return std::unique_ptr<Binding<T, ImmediateBindingEvaluator>>
|
||||
* An new Binding bound to an existing Property with immediate evaluation.
|
||||
*
|
||||
* *Note: For the difference between makeBinding and makeBoundProperty, see the
|
||||
* ["Reassigning a Binding"](../../getting-started/data-binding/#reassigning-a-binding) section in the Getting Started guide.*
|
||||
*/
|
||||
template<typename T>
|
||||
inline std::unique_ptr<Binding<T, ImmediateBindingEvaluator>> makeBinding(Property<T> &property)
|
||||
{
|
||||
return std::make_unique<Binding<T, ImmediateBindingEvaluator>>(Private::makeNode(property));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Helper function to create an immediate mode Binding from a root Node.
|
||||
*
|
||||
* @tparam T The type of the value that the Binding expression evaluates to.
|
||||
* @param rootNode Represents the expression that will be evaluated by the Binding.
|
||||
* Typically constructed from a unary/binary operator on a Property.
|
||||
* @return std::unique_ptr<Binding<<T, ImmediateBindingEvaluator>> An new Binding bound to a root Node with immediate evaluation.
|
||||
*
|
||||
* *Note: For the difference between makeBinding and makeBoundProperty, see the
|
||||
* ["Reassigning a Binding"](../../getting-started/data-binding/#reassigning-a-binding) section in the Getting Started guide.*
|
||||
*/
|
||||
template<typename T>
|
||||
inline std::unique_ptr<Binding<T, ImmediateBindingEvaluator>> makeBinding(Private::Node<T> &&rootNode)
|
||||
{
|
||||
return std::make_unique<Binding<T, ImmediateBindingEvaluator>>(std::move(rootNode));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Helper function to create an immediate mode Binding from a function and its arguments.
|
||||
*
|
||||
* @tparam Func The type of the function - may be any type that implements operator().
|
||||
* @param func The function object.
|
||||
* @tparam Args The function argument types
|
||||
* @param args The function arguments - Possible values include: Properties, Constants and Nodes
|
||||
* They will be automatically unwrapped, i.e. a Property<T> will pass a value of type T to func.
|
||||
* @return std::unique_ptr<Binding<ReturnType, ImmediateBindingEvaluator>> where ReturnType is the type that results from evaluationg func with the given arguments.
|
||||
* The Binding will feature immediate evaluation.
|
||||
*
|
||||
* *Note: For the difference between makeBinding and makeBoundProperty, see the
|
||||
* ["Reassigning a Binding"](../../getting-started/data-binding/#reassigning-a-binding) section in the Getting Started guide.*
|
||||
*/
|
||||
template<typename Func, typename... Args, typename = std::enable_if_t<sizeof...(Args) != 0>, typename ResultType = Private::operator_node_result_t<Func, Args...>>
|
||||
inline std::unique_ptr<Binding<ResultType, ImmediateBindingEvaluator>> makeBinding(Func &&func, Args &&...args)
|
||||
{
|
||||
return std::make_unique<Binding<ResultType, ImmediateBindingEvaluator>>(Private::makeNode(std::forward<Func>(func), std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Helper function to create a Property with a Binding.
|
||||
*
|
||||
* This function can take:
|
||||
* - Another Property.
|
||||
* - A Node, typically created by combining Property instances using operators.
|
||||
* - A function with arguments (Nodes, Constants or Properties)
|
||||
* By default this will construct a Property with an immediate binding evaluation.
|
||||
*
|
||||
* Alternatively a BindingEvaluator can be passed as the first argument to this function to control
|
||||
* when evaluation takes place.
|
||||
*
|
||||
* See the documentation for the various overloads of the free @ref makeBinding function for a
|
||||
* detailed description of which arguments can be used in which order.
|
||||
*
|
||||
* Examples:
|
||||
* - @ref 05-property-bindings/main.cpp
|
||||
* - @ref 06-lazy-property-bindings/main.cpp
|
||||
*
|
||||
* @return Property A new Property that is bound to the inputs
|
||||
*
|
||||
* *Note: For the difference between makeBinding and makeBoundProperty, see the
|
||||
* ["Reassigning a Binding"](../../getting-started/data-binding/#reassigning-a-binding) section in the Getting Started guide.*
|
||||
*/
|
||||
template<typename... T>
|
||||
inline auto makeBoundProperty(T &&...args)
|
||||
{
|
||||
auto binding = makeBinding(std::forward<T>(args)...);
|
||||
return Property<decltype(binding->get())>(std::move(binding));
|
||||
}
|
||||
|
||||
} // namespace KDBindings
|
||||
162
src/3rdparty/kdbindings/binding_evaluator.h
vendored
Normal file
162
src/3rdparty/kdbindings/binding_evaluator.h
vendored
Normal file
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
This file is part of KDBindings.
|
||||
|
||||
SPDX-FileCopyrightText: 2021-2022 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
|
||||
Author: Sean Harmer <sean.harmer@kdab.com>
|
||||
|
||||
SPDX-License-Identifier: MIT
|
||||
|
||||
Contact KDAB at <info@kdab.com> for commercial licensing options.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
namespace KDBindings {
|
||||
|
||||
/**
|
||||
* @brief A BindingEvaluator provides a mechanism to control the exact time
|
||||
* when a KDBindings::Binding is reevaluated.
|
||||
*
|
||||
* A BindingEvaluator represents a collection of Binding instances that can be
|
||||
* selectively reevaluated.
|
||||
*
|
||||
* If a Binding is created using KDBindings::makeBoundProperty with a BindingEvaluator,
|
||||
* the Binding will only be evaluated if BindingEvaluator::evaluateAll is called
|
||||
* on the given evaluator.
|
||||
*
|
||||
* Note that instances of BindingEvaluator internally wrap their collection of
|
||||
* Bindings in such a way that copying a BindingEvaluator does not actually
|
||||
* copy the collection of Bindings. Therefore adding a Binding to a copy of a
|
||||
* BindingEvaluator will also add it to the original.
|
||||
* This is done for ease of use, so evaluators can be passed around easily throughout
|
||||
* the codebase.
|
||||
*
|
||||
* Examples:
|
||||
* - @ref 06-lazy-property-bindings/main.cpp
|
||||
*/
|
||||
class BindingEvaluator
|
||||
{
|
||||
// We use pimpl here so that we can pass evaluators around by value (copies)
|
||||
// yet each copy refers to the same set of data
|
||||
struct Private {
|
||||
// TODO: Use std::vector here?
|
||||
std::map<int, std::function<void()>> m_bindingEvalFunctions;
|
||||
int m_currentId;
|
||||
};
|
||||
|
||||
public:
|
||||
/** A BindingEvaluator can be default constructed */
|
||||
BindingEvaluator() = default;
|
||||
|
||||
/**
|
||||
* A BindingEvaluator can be copy constructed.
|
||||
*
|
||||
* Note that copying the evaluator will NOT create a new collection of
|
||||
* Binding instances, but the new evaluator will refer to the same collection,
|
||||
* so creating a new Binding with this evaluator will also modify the previous one.
|
||||
*/
|
||||
BindingEvaluator(const BindingEvaluator &) noexcept = default;
|
||||
|
||||
/**
|
||||
* A BindingEvaluator can be copy assigned.
|
||||
*
|
||||
* Note that copying the evaluator will NOT create a new collection of
|
||||
* Binding instances, but the new evaluator will refer to the same collection,
|
||||
* so creating a new Binding with this evaluator will also modify the previous one.
|
||||
*/
|
||||
BindingEvaluator &operator=(const BindingEvaluator &) noexcept = default;
|
||||
|
||||
/**
|
||||
* A BindingEvaluator can not be move constructed.
|
||||
*/
|
||||
BindingEvaluator(BindingEvaluator &&other) noexcept = delete;
|
||||
|
||||
/**
|
||||
* A BindingEvaluator can not be move assigned.
|
||||
*/
|
||||
BindingEvaluator &operator=(BindingEvaluator &&other) noexcept = delete;
|
||||
|
||||
/**
|
||||
* This function evaluates all Binding instances that were constructed with this
|
||||
* evaluator, in the order they were inserted.
|
||||
*
|
||||
* It will therefore update the associated Property instances as well.
|
||||
*/
|
||||
void evaluateAll() const
|
||||
{
|
||||
// a std::map's ordering is deterministic, so the bindings are evaluated
|
||||
// in the order they were inserted, ensuring correct transitive dependency
|
||||
// evaluation.
|
||||
for (auto &[id, func] : m_d->m_bindingEvalFunctions)
|
||||
func();
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename BindingType>
|
||||
int insert(BindingType *binding)
|
||||
{
|
||||
m_d->m_bindingEvalFunctions.insert({ ++(m_d->m_currentId),
|
||||
[=]() { binding->evaluate(); } });
|
||||
return m_d->m_currentId;
|
||||
}
|
||||
|
||||
void remove(int id)
|
||||
{
|
||||
m_d->m_bindingEvalFunctions.erase(id);
|
||||
}
|
||||
|
||||
std::shared_ptr<Private> m_d{ std::make_shared<Private>() };
|
||||
|
||||
template<typename T, typename UpdaterT>
|
||||
friend class Binding;
|
||||
};
|
||||
|
||||
/**
|
||||
* This subclass of BindingEvaluator doesn't do anything special on its own.
|
||||
* It is used together with a template specialization of Binding to provide
|
||||
* old-school, immediate mode Bindings.
|
||||
*
|
||||
* Any Binding that is constructed with an ImmediateBindingEvaluator will not wait
|
||||
* for the evaluator to call evaluateAll, but rather evaluate the Binding immediately
|
||||
* when any of its bindables (i.e. Property instances) change.
|
||||
* This can lead to a Property Binding being evaluated many
|
||||
* times before the result is ever used in a typical GUI application.
|
||||
*/
|
||||
class ImmediateBindingEvaluator final : public BindingEvaluator
|
||||
{
|
||||
public:
|
||||
static inline ImmediateBindingEvaluator instance()
|
||||
{
|
||||
static ImmediateBindingEvaluator evaluator;
|
||||
return evaluator;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace KDBindings
|
||||
|
||||
/**
|
||||
* @example 06-lazy-property-bindings/main.cpp
|
||||
*
|
||||
* An example of how to use KDBindings::BindingEvaluator together
|
||||
* with a KDBindings::Property to create a Property binding that is
|
||||
* only reevaluated on demand.
|
||||
*
|
||||
* The output of this example is:
|
||||
* ```
|
||||
* The initial size of the image = 1920000 bytes
|
||||
* The new size of the image = 8294400 bytes
|
||||
* ```
|
||||
*
|
||||
* Note the difference to @ref 05-property-bindings/main.cpp, where the
|
||||
* new size of the image is calculated twice.
|
||||
*
|
||||
* This feature is especially useful to reduce the performance impact of
|
||||
* bindings and to create bindings that only update in specific intervals.
|
||||
* <br/><!-- This <br/> is a workaround for a bug in doxybook2 that causes
|
||||
* the rendering of the example code to break because it is missing a
|
||||
* newline-->
|
||||
*/
|
||||
207
src/3rdparty/kdbindings/genindex_array.h
vendored
Normal file
207
src/3rdparty/kdbindings/genindex_array.h
vendored
Normal file
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
This code has been adapted from MIT licensed code, originally by Jeremy burns and available at
|
||||
https://gist.github.com/jaburns/ca72487198832f6203e831133ffdfff4.
|
||||
The original license is provided below:
|
||||
|
||||
Copyright 2021 Jeremy Burns
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files
|
||||
(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
||||
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
#include <cassert>
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
namespace KDBindings {
|
||||
|
||||
namespace Private {
|
||||
|
||||
struct GenerationalIndex {
|
||||
uint32_t index = 0;
|
||||
uint32_t generation = 0;
|
||||
};
|
||||
|
||||
class GenerationalIndexAllocator
|
||||
{
|
||||
struct AllocatorEntry {
|
||||
bool isLive = false;
|
||||
uint32_t generation = 0;
|
||||
};
|
||||
|
||||
std::vector<AllocatorEntry> m_entries;
|
||||
std::vector<uint32_t> m_freeIndices;
|
||||
|
||||
public:
|
||||
GenerationalIndex allocate()
|
||||
{
|
||||
if (m_freeIndices.size() > 0) {
|
||||
uint32_t index = m_freeIndices.back();
|
||||
m_freeIndices.pop_back();
|
||||
|
||||
m_entries[index].generation += 1;
|
||||
m_entries[index].isLive = true;
|
||||
|
||||
return { index, m_entries[index].generation };
|
||||
} else {
|
||||
// check that we are still within the bounds of uint32_t
|
||||
if (m_entries.size() + 1 >= std::numeric_limits<uint32_t>::max()) {
|
||||
throw std::length_error(std::string("Maximum number of values inside GenerationalIndexArray reached: ") + std::to_string(m_entries.size()));
|
||||
}
|
||||
|
||||
m_entries.push_back({ true, 0 });
|
||||
return { static_cast<uint32_t>(m_entries.size()) - 1, 0 };
|
||||
}
|
||||
}
|
||||
|
||||
bool deallocate(GenerationalIndex index)
|
||||
{
|
||||
if (isLive(index)) {
|
||||
m_entries[index.index].isLive = false;
|
||||
m_freeIndices.emplace_back(index.index);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isLive(GenerationalIndex index) const noexcept
|
||||
{
|
||||
return index.index < m_entries.size() &&
|
||||
m_entries[index.index].generation == index.generation &&
|
||||
m_entries[index.index].isLive;
|
||||
}
|
||||
};
|
||||
|
||||
// A GenerationalIndexArray stores elements in contiguous memory just like an std::vector
|
||||
// and also allows items to be retrieved in constant time through indexed access, but it keeps
|
||||
// track of the "version"/generation of values at indices so that it can inform an accessor
|
||||
// when the item at the index it is trying to access is no longer the item that it wants.
|
||||
template<typename T>
|
||||
class GenerationalIndexArray
|
||||
{
|
||||
struct Entry {
|
||||
uint32_t generation;
|
||||
T value;
|
||||
};
|
||||
|
||||
// TODO: m_entries never shrinks after an entry has been deleted, it might be
|
||||
// a good idea to add a "trim" function at some point if this becomes an issue
|
||||
|
||||
std::vector<std::optional<Entry>> m_entries;
|
||||
GenerationalIndexAllocator m_allocator;
|
||||
|
||||
public:
|
||||
// Sets the value at a specific index inside the array
|
||||
void set(const GenerationalIndex index, T &&value)
|
||||
{
|
||||
while (m_entries.size() <= index.index)
|
||||
m_entries.emplace_back(std::nullopt);
|
||||
|
||||
#ifndef NDEBUG
|
||||
uint32_t previousGeneration = 0;
|
||||
|
||||
const auto &previousEntry = m_entries[index.index];
|
||||
if (previousEntry)
|
||||
previousGeneration = previousEntry->generation;
|
||||
|
||||
assert(index.generation >= previousGeneration);
|
||||
#endif
|
||||
|
||||
m_entries[index.index] = std::optional<Entry>{ { index.generation, std::move(value) } };
|
||||
}
|
||||
|
||||
// Insert a value at the first free index and get the index back
|
||||
GenerationalIndex insert(T &&value)
|
||||
{
|
||||
const auto index = m_allocator.allocate();
|
||||
set(index, std::move(value));
|
||||
return index;
|
||||
}
|
||||
|
||||
// Erase the value at the specified index and free up the index again
|
||||
void erase(GenerationalIndex index)
|
||||
{
|
||||
if (m_allocator.deallocate(index))
|
||||
m_entries[index.index] = std::nullopt;
|
||||
}
|
||||
|
||||
// Get a pointer to the value at the specified index
|
||||
T *get(GenerationalIndex index)
|
||||
{
|
||||
if (index.index >= m_entries.size())
|
||||
return nullptr;
|
||||
|
||||
auto &entry = m_entries[index.index];
|
||||
if (entry && entry->generation == index.generation) {
|
||||
return &entry->value;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Get a const pointer to the value at the specified index
|
||||
const T *get(GenerationalIndex index) const noexcept
|
||||
{
|
||||
return const_cast<const T *>(const_cast<GenerationalIndexArray *>(this)->get(index));
|
||||
}
|
||||
|
||||
// Erase all the values in the array and thus free up all indices too
|
||||
void clear()
|
||||
{
|
||||
const auto numEntries = entriesSize();
|
||||
|
||||
for (auto i = decltype(numEntries){ 0 }; i < numEntries; ++i) {
|
||||
const auto index = indexAtEntry(i);
|
||||
|
||||
if (index != std::nullopt)
|
||||
erase(*index);
|
||||
}
|
||||
}
|
||||
|
||||
// The number entries currently in the array, not all necessarily correspond to valid indices,
|
||||
// use "indexAtEntry" to translate from an entry index to a optional GenerationalIndex
|
||||
uint32_t entriesSize() const noexcept
|
||||
{
|
||||
// this cast is safe because the allocator checks that we never exceed the capacity of uint32_t
|
||||
return static_cast<uint32_t>(m_entries.size());
|
||||
}
|
||||
|
||||
// Convert an entry index into a GenerationalIndex, if possible otherwise returns nullopt
|
||||
std::optional<GenerationalIndex> indexAtEntry(uint32_t entryIndex) const
|
||||
{
|
||||
if (entryIndex >= entriesSize())
|
||||
return std::nullopt;
|
||||
|
||||
const auto &entry = m_entries[entryIndex];
|
||||
if (!entry)
|
||||
return std::nullopt;
|
||||
|
||||
GenerationalIndex index = { entryIndex, entry->generation };
|
||||
|
||||
if (m_allocator.isLive(index))
|
||||
return index;
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
};
|
||||
|
||||
} //namespace Private
|
||||
|
||||
} // namespace KDBindings
|
||||
95
src/3rdparty/kdbindings/make_node.h
vendored
Normal file
95
src/3rdparty/kdbindings/make_node.h
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
This file is part of KDBindings.
|
||||
|
||||
SPDX-FileCopyrightText: 2021-2022 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
|
||||
Author: Sean Harmer <sean.harmer@kdab.com>
|
||||
|
||||
SPDX-License-Identifier: MIT
|
||||
|
||||
Contact KDAB at <info@kdab.com> for commercial licensing options.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <kdbindings/node.h>
|
||||
#include <type_traits>
|
||||
|
||||
namespace KDBindings {
|
||||
|
||||
namespace Private {
|
||||
|
||||
template<typename T>
|
||||
struct bindable_value_type_ {
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct bindable_value_type_<Property<T>> {
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct bindable_value_type_<NodeInterface<T>> {
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct bindable_value_type_<Node<T>> {
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct bindable_value_type : bindable_value_type_<std::decay_t<T>> {
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
using bindable_value_type_t = typename bindable_value_type<T>::type;
|
||||
|
||||
// Find the type of a Node wrapping an operator and arguments
|
||||
template<typename Operator, typename... Ts>
|
||||
using operator_node_result =
|
||||
std::decay<
|
||||
std::invoke_result_t<
|
||||
std::decay_t<Operator>,
|
||||
bindable_value_type_t<Ts>...>>;
|
||||
|
||||
template<typename Operator, typename... Ts>
|
||||
using operator_node_result_t = typename operator_node_result<Operator, Ts...>::type;
|
||||
|
||||
// Node creation helpers
|
||||
template<typename T>
|
||||
inline Node<std::decay_t<T>> makeNode(T &&value)
|
||||
{
|
||||
return Node<std::decay_t<T>>(std::make_unique<ConstantNode<std::decay_t<T>>>(std::move(value)));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline Node<T> makeNode(Property<T> &property)
|
||||
{
|
||||
return Node<T>(std::make_unique<PropertyNode<T>>(property));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline Node<T> makeNode(Node<T> &&node)
|
||||
{
|
||||
return std::move(node);
|
||||
}
|
||||
|
||||
template<typename Operator, typename... Ts, typename = std::enable_if_t<sizeof...(Ts) >= 1>, typename ResultType = operator_node_result_t<Operator, Ts...>>
|
||||
inline Node<ResultType> makeNode(Operator &&op, Ts &&...args)
|
||||
{
|
||||
return Node<ResultType>(std::make_unique<OperatorNode<ResultType, std::decay_t<Operator>, bindable_value_type_t<Ts>...>>(
|
||||
std::forward<Operator>(op),
|
||||
makeNode(std::forward<Ts>(args))...));
|
||||
}
|
||||
|
||||
// Needed by function and operator helpers
|
||||
template<typename T>
|
||||
struct is_bindable : std::integral_constant<
|
||||
bool,
|
||||
is_property<T>::value || is_node<T>::value> {
|
||||
};
|
||||
|
||||
} // namespace Private
|
||||
|
||||
} // namespace KDBindings
|
||||
313
src/3rdparty/kdbindings/node.h
vendored
Normal file
313
src/3rdparty/kdbindings/node.h
vendored
Normal file
@@ -0,0 +1,313 @@
|
||||
/*
|
||||
This file is part of KDBindings.
|
||||
|
||||
SPDX-FileCopyrightText: 2021-2022 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
|
||||
Author: Sean Harmer <sean.harmer@kdab.com>
|
||||
|
||||
SPDX-License-Identifier: MIT
|
||||
|
||||
Contact KDAB at <info@kdab.com> for commercial licensing options.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <kdbindings/property.h>
|
||||
#include <kdbindings/signal.h>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace KDBindings {
|
||||
|
||||
/**
|
||||
* @brief A PropertyDestroyedError is thrown whenever a binding is evaluated
|
||||
* that references a property that no longer exists.
|
||||
*/
|
||||
class PropertyDestroyedError : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
PropertyDestroyedError() = delete;
|
||||
|
||||
using std::runtime_error::runtime_error;
|
||||
};
|
||||
|
||||
namespace Private {
|
||||
|
||||
class Dirtyable
|
||||
{
|
||||
public:
|
||||
virtual ~Dirtyable() = default;
|
||||
|
||||
Dirtyable() = default;
|
||||
|
||||
void setParent(Dirtyable *newParent)
|
||||
{
|
||||
auto **parentVar = parentVariable();
|
||||
if (parentVar) {
|
||||
*parentVar = newParent;
|
||||
}
|
||||
}
|
||||
|
||||
// overridden by Binding
|
||||
virtual void markDirty()
|
||||
{
|
||||
auto *dirtyVar = dirtyVariable();
|
||||
if (dirtyVar) {
|
||||
if (*dirtyVar) {
|
||||
return;
|
||||
// We are already dirty, don't bother marking the whole tree again.
|
||||
}
|
||||
|
||||
// we only want to have one override for dirtyVariable,
|
||||
// which is const, so we have to const cast here.
|
||||
*const_cast<bool *>(dirtyVar) = true;
|
||||
}
|
||||
|
||||
auto **parentVar = parentVariable();
|
||||
if (parentVar && *parentVar) {
|
||||
(*parentVar)->markDirty();
|
||||
}
|
||||
}
|
||||
|
||||
bool isDirty() const
|
||||
{
|
||||
auto *dirtyVar = dirtyVariable();
|
||||
return dirtyVar && *dirtyVar;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual Dirtyable **parentVariable() = 0;
|
||||
virtual const bool *dirtyVariable() const = 0;
|
||||
};
|
||||
|
||||
template<typename ResultType>
|
||||
class NodeInterface : public Dirtyable
|
||||
{
|
||||
public:
|
||||
// Returns a reference, because we cache each evaluated value.
|
||||
// const, because it shouldn't modify the return value of the AST.
|
||||
// Requires mutable caches
|
||||
virtual const ResultType &evaluate() const = 0;
|
||||
|
||||
protected:
|
||||
NodeInterface() = default;
|
||||
};
|
||||
|
||||
template<typename ResultType>
|
||||
class Node
|
||||
{
|
||||
public:
|
||||
Node(std::unique_ptr<NodeInterface<ResultType>> &&interface)
|
||||
: m_interface(std::move(interface))
|
||||
{
|
||||
}
|
||||
|
||||
const ResultType &evaluate() const
|
||||
{
|
||||
return m_interface->evaluate();
|
||||
}
|
||||
|
||||
void setParent(Dirtyable *newParent)
|
||||
{
|
||||
m_interface->setParent(newParent);
|
||||
}
|
||||
|
||||
bool isDirty() const
|
||||
{
|
||||
return m_interface->isDirty();
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<NodeInterface<ResultType>> m_interface;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class ConstantNode : public NodeInterface<T>
|
||||
{
|
||||
public:
|
||||
explicit ConstantNode(const T &value)
|
||||
: m_value{ value }
|
||||
{
|
||||
}
|
||||
|
||||
const T &evaluate() const override
|
||||
{
|
||||
return m_value;
|
||||
}
|
||||
|
||||
protected:
|
||||
// A constant can never be dirty, so it doesn't need to
|
||||
// know its parent, as it doesn't have to notify it.
|
||||
Dirtyable **parentVariable() override { return nullptr; }
|
||||
const bool *dirtyVariable() const override { return nullptr; }
|
||||
|
||||
private:
|
||||
T m_value;
|
||||
};
|
||||
|
||||
template<typename PropertyType>
|
||||
class PropertyNode : public NodeInterface<PropertyType>
|
||||
{
|
||||
public:
|
||||
explicit PropertyNode(Property<PropertyType> &property)
|
||||
: m_parent(nullptr), m_dirty(false)
|
||||
{
|
||||
setProperty(property);
|
||||
}
|
||||
|
||||
// PropertyNodes cannot be moved
|
||||
PropertyNode(PropertyNode<PropertyType> &&) = delete;
|
||||
|
||||
PropertyNode(const PropertyNode<PropertyType> &other)
|
||||
: Dirtyable(other.isDirty())
|
||||
{
|
||||
setProperty(*other.m_property);
|
||||
}
|
||||
|
||||
virtual ~PropertyNode()
|
||||
{
|
||||
m_valueChangedHandle.disconnect();
|
||||
m_movedHandle.disconnect();
|
||||
m_destroyedHandle.disconnect();
|
||||
}
|
||||
|
||||
const PropertyType &evaluate() const override
|
||||
{
|
||||
if (!m_property) {
|
||||
throw PropertyDestroyedError("The Property this node refers to no longer exists!");
|
||||
}
|
||||
|
||||
m_dirty = false;
|
||||
return m_property->get();
|
||||
}
|
||||
|
||||
// This must currently take a const reference, as the "moved" signal emits a const&
|
||||
void propertyMoved(Property<PropertyType> &property)
|
||||
{
|
||||
if (&property != m_property) {
|
||||
m_property = &property;
|
||||
} else {
|
||||
// Another property was moved into the property this node refers to.
|
||||
// Therefore it will no longer update this Node.
|
||||
m_property = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void propertyDestroyed()
|
||||
{
|
||||
m_property = nullptr;
|
||||
}
|
||||
|
||||
protected:
|
||||
Dirtyable **parentVariable() override { return &m_parent; }
|
||||
const bool *dirtyVariable() const override { return &m_dirty; }
|
||||
|
||||
private:
|
||||
void setProperty(Property<PropertyType> &property)
|
||||
{
|
||||
m_property = &property;
|
||||
m_valueChangedHandle = m_property->valueChanged().connect(&PropertyNode<PropertyType>::markDirty, this);
|
||||
m_movedHandle = m_property->moved().connect(&PropertyNode<PropertyType>::propertyMoved, this);
|
||||
m_destroyedHandle = m_property->destroyed().connect(&PropertyNode<PropertyType>::propertyDestroyed, this);
|
||||
}
|
||||
|
||||
Property<PropertyType> *m_property;
|
||||
ConnectionHandle m_movedHandle;
|
||||
ConnectionHandle m_valueChangedHandle;
|
||||
ConnectionHandle m_destroyedHandle;
|
||||
|
||||
Dirtyable *m_parent;
|
||||
mutable bool m_dirty;
|
||||
};
|
||||
|
||||
template<typename ResultType, typename Operator, typename... Ts>
|
||||
class OperatorNode : public NodeInterface<ResultType>
|
||||
{
|
||||
public:
|
||||
// add another typename template for the Operator type, so
|
||||
// it can be a universal reference.
|
||||
template<typename Op>
|
||||
explicit OperatorNode(Op &&op, Node<Ts> &&...arguments)
|
||||
: m_parent{ nullptr }, m_dirty{ true /*dirty until reevaluated*/ }, m_op{ std::move(op) }, m_values{ std::move(arguments)... }, m_result(reevaluate())
|
||||
{
|
||||
static_assert(
|
||||
std::is_convertible_v<decltype(m_op(std::declval<Ts>()...)), ResultType>,
|
||||
"The result of the Operator must be convertible to the ReturnType of the Node");
|
||||
|
||||
setParents<0>();
|
||||
}
|
||||
|
||||
template<std::size_t I>
|
||||
auto setParents() -> std::enable_if_t<I == sizeof...(Ts)>
|
||||
{
|
||||
}
|
||||
|
||||
// The enable_if_t confuses clang-format into thinking the
|
||||
// first "<" is a comparison, and not the second.
|
||||
// clang-format off
|
||||
template<std::size_t I>
|
||||
auto setParents() -> std::enable_if_t<I < sizeof...(Ts)>
|
||||
// clang-format on
|
||||
{
|
||||
std::get<I>(m_values).setParent(this);
|
||||
setParents<I + 1>();
|
||||
}
|
||||
|
||||
virtual ~OperatorNode() = default;
|
||||
|
||||
const ResultType &evaluate() const override
|
||||
{
|
||||
if (Dirtyable::isDirty()) {
|
||||
m_result = reevaluate();
|
||||
}
|
||||
|
||||
return m_result;
|
||||
}
|
||||
|
||||
protected:
|
||||
Dirtyable **parentVariable() override { return &m_parent; }
|
||||
const bool *dirtyVariable() const override { return &m_dirty; }
|
||||
|
||||
private:
|
||||
template<std::size_t... Is>
|
||||
ResultType reevaluate_helper(std::index_sequence<Is...>) const
|
||||
{
|
||||
return m_op(std::get<Is>(m_values).evaluate()...);
|
||||
}
|
||||
|
||||
ResultType reevaluate() const
|
||||
{
|
||||
m_dirty = false;
|
||||
|
||||
return reevaluate_helper(std::make_index_sequence<sizeof...(Ts)>());
|
||||
}
|
||||
|
||||
Dirtyable *m_parent;
|
||||
mutable bool m_dirty;
|
||||
|
||||
Operator m_op;
|
||||
std::tuple<Node<Ts>...> m_values;
|
||||
|
||||
// Note: it is important that m_result is evaluated last!
|
||||
// Otherwise the call to reevaluate in the constructor will fail.
|
||||
mutable ResultType m_result;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct is_node_helper : std::false_type {
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct is_node_helper<Node<T>> : std::true_type {
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct is_node : is_node_helper<T> {
|
||||
};
|
||||
|
||||
} // namespace Private
|
||||
|
||||
} // namespace KDBindings
|
||||
149
src/3rdparty/kdbindings/node_functions.h
vendored
Normal file
149
src/3rdparty/kdbindings/node_functions.h
vendored
Normal file
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
This file is part of KDBindings.
|
||||
|
||||
SPDX-FileCopyrightText: 2021-2022 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
|
||||
Author: Sean Harmer <sean.harmer@kdab.com>
|
||||
|
||||
SPDX-License-Identifier: MIT
|
||||
|
||||
Contact KDAB at <info@kdab.com> for commercial licensing options.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <kdbindings/make_node.h>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace KDBindings {
|
||||
|
||||
namespace Private {
|
||||
|
||||
template<typename... Ts>
|
||||
struct any_bindables;
|
||||
|
||||
// Check to see if a single type is a bindable (node or property)
|
||||
template<typename T>
|
||||
struct any_bindables<T> : is_bindable<T> {
|
||||
};
|
||||
|
||||
// Check the head of the typelist and recurse
|
||||
template<typename HEAD, typename... Ts>
|
||||
struct any_bindables<HEAD, Ts...> : std::integral_constant<
|
||||
bool,
|
||||
any_bindables<HEAD>::value || any_bindables<Ts...>::value> {
|
||||
};
|
||||
|
||||
} // namespace Private
|
||||
|
||||
/**
|
||||
* @brief KDBINDINGS_DECLARE_FUNCTION is a helper macro to declare and define functions for use in data binding.
|
||||
*
|
||||
* This macro can take any callable object or function reference and create a new function that may be used
|
||||
* in data binding expressions.
|
||||
* The result function that can be called with a Property or the result of a data binding expression
|
||||
* to create another data binding expression.
|
||||
*
|
||||
* Note that if a function is overloaded, it is impossible to reference all of its overloads at once.
|
||||
* Therefore we recommend declaring a struct with a templated operator() to use as the function object.
|
||||
* See the KDBindings::node_abs struct for an example of how to do this.
|
||||
*
|
||||
* @param NAME The name of the function to generate.
|
||||
* @param FUNC The function to wrap.
|
||||
*/
|
||||
#define KDBINDINGS_DECLARE_FUNCTION(NAME, FUNC) \
|
||||
template<typename... Ts> \
|
||||
inline auto NAME(Ts &&...args)->std::enable_if_t<KDBindings::Private::any_bindables<Ts...>::value, KDBindings::Private::Node<KDBindings::Private::operator_node_result_t<decltype(FUNC), Ts...>>> \
|
||||
{ \
|
||||
return Private::makeNode(FUNC, std::forward<Ts>(args)...); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief An example struct that is used with a call to KDBINDINGS_DECLARE_FUNCTION to declare all overloads
|
||||
* of std::abs as usable in data binding.
|
||||
*
|
||||
* Because of the way node_abs overloads its operator(), it can be used in a call to KDBINDINGS_DECLARE_FUNCTION like this:
|
||||
* @code
|
||||
* KDBINDINGS_DECLARE_FUNCTION(abs, node_abs{})
|
||||
* @endcode
|
||||
*
|
||||
* To generate such a struct for another function, use the KDBINDINGS_DECLARE_FUNCTION_OBJECT macro.
|
||||
*/
|
||||
struct node_abs {
|
||||
/**
|
||||
* @brief The operator() is overloaded so the struct can be used as a function object.
|
||||
*
|
||||
* Because this operator is templated, a single instance of node_abs
|
||||
* can refer to all overloads of std::abs.
|
||||
*/
|
||||
template<typename... Ts>
|
||||
auto operator()(Ts &&...x) const
|
||||
{
|
||||
return std::abs(std::forward<Ts>(x)...);
|
||||
}
|
||||
};
|
||||
KDBINDINGS_DECLARE_FUNCTION(abs, node_abs{})
|
||||
|
||||
/**
|
||||
* @brief This macro declares a callable struct that wraps a function with all
|
||||
* its overloads.
|
||||
*
|
||||
* The declared struct can be used as the FUNCTION argument to
|
||||
* KDBINDINGS_DECLARE_FUNCTION(NAME, FUNCTION) to pass a function with
|
||||
* all its overloads to the macro.
|
||||
*
|
||||
* See the KDBindings::node_abs struct for an example of what this macro would generate.
|
||||
*
|
||||
* @param NAME The name of the resulting struct.
|
||||
* @param FUNCTION The function to wrap.
|
||||
*/
|
||||
#define KDBINDINGS_DECLARE_FUNCTION_OBJECT(NAME, FUNCTION) \
|
||||
struct NAME { \
|
||||
template<typename... Ts> \
|
||||
auto operator()(Ts &&...x) const \
|
||||
{ \
|
||||
return FUNCTION(std::forward<Ts>(x)...); \
|
||||
} \
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief This macro allows you to declare any function in a non-nested namespace
|
||||
* as available in the context of data binding.
|
||||
*
|
||||
* @param NAMESPACE the name of the namespace the function is in.
|
||||
* @param NAME the name of the function to wrap.
|
||||
*
|
||||
* In comparison to KDBINDINGS_DECLARE_FUNCTION(NAME, FUNC), this macro will generate a
|
||||
* helper struct using #KDBINDINGS_DECLARE_FUNCTION_OBJECT, so all overloads of the function are
|
||||
* made available at once.
|
||||
*
|
||||
* #KDBINDINGS_DECLARE_STD_FUNCTION is basically just a call to this macro with
|
||||
* the NAMESPACE parameter set to `std`.
|
||||
*/
|
||||
#define KDBINDINGS_DECLARE_NAMESPACED_FUNCTION(NAMESPACE, NAME) \
|
||||
KDBINDINGS_DECLARE_FUNCTION_OBJECT(node_##NAMESPACE_##NAME, NAMESPACE::NAME) \
|
||||
KDBINDINGS_DECLARE_FUNCTION(NAME, node_##NAMESPACE_##NAME{})
|
||||
|
||||
/**
|
||||
* @brief This macro is based on KDBINDINGS_DECLARE_NAMESPACED_FUNCTION(NAMESPACE, FUNC)
|
||||
* to make it easier to declare any standard library function as available for data binding.
|
||||
*
|
||||
* It uses #KDBINDINGS_DECLARE_NAMESPACED_FUNCTION and can therefore make all overloads
|
||||
* of the `std::` function available at once.
|
||||
*
|
||||
* @param NAME The name of the function in the `std::` namespace.
|
||||
*/
|
||||
#define KDBINDINGS_DECLARE_STD_FUNCTION(NAME) \
|
||||
KDBINDINGS_DECLARE_NAMESPACED_FUNCTION(std, NAME)
|
||||
|
||||
// Define some common and useful functions
|
||||
KDBINDINGS_DECLARE_STD_FUNCTION(floor)
|
||||
KDBINDINGS_DECLARE_STD_FUNCTION(ceil)
|
||||
KDBINDINGS_DECLARE_STD_FUNCTION(sin)
|
||||
KDBINDINGS_DECLARE_STD_FUNCTION(cos)
|
||||
KDBINDINGS_DECLARE_STD_FUNCTION(tan)
|
||||
KDBINDINGS_DECLARE_STD_FUNCTION(asin)
|
||||
KDBINDINGS_DECLARE_STD_FUNCTION(acos)
|
||||
KDBINDINGS_DECLARE_STD_FUNCTION(atan)
|
||||
|
||||
} // namespace KDBindings
|
||||
135
src/3rdparty/kdbindings/node_operators.h
vendored
Normal file
135
src/3rdparty/kdbindings/node_operators.h
vendored
Normal file
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
This file is part of KDBindings.
|
||||
|
||||
SPDX-FileCopyrightText: 2021-2022 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
|
||||
Author: Sean Harmer <sean.harmer@kdab.com>
|
||||
|
||||
SPDX-License-Identifier: MIT
|
||||
|
||||
Contact KDAB at <info@kdab.com> for commercial licensing options.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <kdbindings/node.h>
|
||||
#include <kdbindings/make_node.h>
|
||||
|
||||
namespace KDBindings {
|
||||
|
||||
// Helper macro to declare free standing unary operators for Property and Node
|
||||
|
||||
#define KDBINDINGS_DEFINE_UNARY_OP(OP) \
|
||||
template<typename... T> \
|
||||
inline auto operator OP(Property<T...> &arg) noexcept(noexcept(OP arg.get())) \
|
||||
->Private::Node<std::decay_t<decltype(OP arg.get())>> \
|
||||
{ \
|
||||
return Private::makeNode([](auto &&v) { return (OP v); }, arg); \
|
||||
} \
|
||||
\
|
||||
template<typename T> \
|
||||
inline auto operator OP(Private::Node<T> &&arg) noexcept(noexcept(OP arg.evaluate())) \
|
||||
->Private::Node<std::decay_t<decltype(OP arg.evaluate())>> \
|
||||
{ \
|
||||
return Private::makeNode([](auto &&v) { return (OP v); }, std::move(arg)); \
|
||||
}
|
||||
|
||||
KDBINDINGS_DEFINE_UNARY_OP(!)
|
||||
KDBINDINGS_DEFINE_UNARY_OP(~) // Bitwise not
|
||||
KDBINDINGS_DEFINE_UNARY_OP(+)
|
||||
KDBINDINGS_DEFINE_UNARY_OP(-)
|
||||
|
||||
// Helper macro to declare free standing binary operators for Property and Node.
|
||||
// The combinations we need are:
|
||||
//
|
||||
// operator op (Property<A> &a, B&& b) [Property, value]
|
||||
// operator op (A&& a, Property<B> &b) [value, Property]
|
||||
// operator op (Property<A> &a, Property<B> &b) [Property, Property]
|
||||
//
|
||||
// operator op (Node<A>&& a, B&& b) [Node value]
|
||||
// operator op (A&& a, Node<B>&& b) [value, Node]
|
||||
// operator op (Node<A>&& a, Node<B>&& b) [Node, Node]
|
||||
//
|
||||
// operator op (Property<A> &a, Node<B>&& b) [Property, Node]
|
||||
// operaotr op (Node<A>&& a, Property<B> &b) [Node, Property]
|
||||
|
||||
#define KDBINDINGS_DEFINE_BINARY_OP(OP) \
|
||||
template<typename B, typename... A> \
|
||||
inline auto operator OP(Property<A...> &a, B &&b) noexcept(noexcept(a.get() OP b)) \
|
||||
->std::enable_if_t<!Private::is_bindable<B>::value, \
|
||||
Private::Node<decltype(a.get() OP b)>> \
|
||||
{ \
|
||||
return Private::makeNode([](auto &&av, auto &&bv) { return (av OP bv); }, a, std::forward<B>(b)); \
|
||||
} \
|
||||
\
|
||||
template<typename A, typename... B> \
|
||||
inline auto operator OP(A &&a, Property<B...> &b) noexcept(noexcept(a OP b.get())) \
|
||||
->std::enable_if_t<!Private::is_bindable<A>::value, \
|
||||
Private::Node<decltype(a OP b.get())>> \
|
||||
{ \
|
||||
return Private::makeNode([](auto &&av, auto &&bv) { return (av OP bv); }, std::forward<A>(a), b); \
|
||||
} \
|
||||
\
|
||||
template<typename A, typename B> \
|
||||
inline auto operator OP(Property<A> &a, Property<B> &b) noexcept(noexcept(a.get() OP b.get())) \
|
||||
->Private::Node<decltype(a.get() OP b.get())> \
|
||||
{ \
|
||||
return Private::makeNode([](auto &&av, auto &&bv) { return (av OP bv); }, a, b); \
|
||||
} \
|
||||
\
|
||||
template<typename A, typename B> \
|
||||
inline auto operator OP(Private::Node<A> &&a, B &&b) noexcept(noexcept(a.evaluate() OP b)) \
|
||||
->std::enable_if_t<!Private::is_bindable<B>::value, \
|
||||
Private::Node<decltype(a.evaluate() OP b)>> \
|
||||
{ \
|
||||
return Private::makeNode([](auto &&av, auto &&bv) { return (av OP bv); }, std::move(a), std::forward<B>(b)); \
|
||||
} \
|
||||
\
|
||||
template<typename A, typename B> \
|
||||
inline auto operator OP(A &&a, Private::Node<B> &&b) noexcept(noexcept(a OP b.evaluate())) \
|
||||
->std::enable_if_t<!Private::is_bindable<A>::value, \
|
||||
Private::Node<decltype(a OP b.evaluate())>> \
|
||||
{ \
|
||||
return Private::makeNode([](auto &&av, auto &&bv) { return (av OP bv); }, std::forward<A>(a), std::move(b)); \
|
||||
} \
|
||||
\
|
||||
template<typename A, typename B> \
|
||||
inline auto operator OP(Private::Node<A> &&a, Private::Node<B> &&b) noexcept(noexcept(a.evaluate() OP b.evaluate())) \
|
||||
->Private::Node<decltype(a.evaluate() OP b.evaluate())> \
|
||||
{ \
|
||||
return Private::makeNode([](auto &&av, auto &&bv) { return (av OP bv); }, std::move(a), std::move(b)); \
|
||||
} \
|
||||
\
|
||||
template<typename B, typename A> \
|
||||
inline auto operator OP(Property<A> &a, Private::Node<B> &&b) noexcept(noexcept(a.get() OP b.evaluate())) \
|
||||
->Private::Node<decltype(a.get() OP b.evaluate())> \
|
||||
{ \
|
||||
return Private::makeNode([](auto &&av, auto &&bv) { return (av OP bv); }, a, std::move(b)); \
|
||||
} \
|
||||
\
|
||||
template<typename A, typename B> \
|
||||
inline auto operator OP(Private::Node<A> &&a, Property<B> &b) noexcept(noexcept(a.evaluate() OP b.get())) \
|
||||
->Private::Node<decltype(a.evaluate() OP b.get())> \
|
||||
{ \
|
||||
return Private::makeNode([](auto &&av, auto &&bv) { return (av OP bv); }, std::move(a), b); \
|
||||
}
|
||||
|
||||
KDBINDINGS_DEFINE_BINARY_OP(*)
|
||||
KDBINDINGS_DEFINE_BINARY_OP(/)
|
||||
KDBINDINGS_DEFINE_BINARY_OP(%)
|
||||
KDBINDINGS_DEFINE_BINARY_OP(+)
|
||||
KDBINDINGS_DEFINE_BINARY_OP(-)
|
||||
KDBINDINGS_DEFINE_BINARY_OP(<<)
|
||||
KDBINDINGS_DEFINE_BINARY_OP(>>)
|
||||
KDBINDINGS_DEFINE_BINARY_OP(<)
|
||||
KDBINDINGS_DEFINE_BINARY_OP(<=)
|
||||
KDBINDINGS_DEFINE_BINARY_OP(>)
|
||||
KDBINDINGS_DEFINE_BINARY_OP(>=)
|
||||
KDBINDINGS_DEFINE_BINARY_OP(==)
|
||||
KDBINDINGS_DEFINE_BINARY_OP(!=)
|
||||
KDBINDINGS_DEFINE_BINARY_OP(&)
|
||||
KDBINDINGS_DEFINE_BINARY_OP(^)
|
||||
KDBINDINGS_DEFINE_BINARY_OP(|)
|
||||
KDBINDINGS_DEFINE_BINARY_OP(&&)
|
||||
KDBINDINGS_DEFINE_BINARY_OP(||)
|
||||
|
||||
} // namespace KDBindings
|
||||
446
src/3rdparty/kdbindings/property.h
vendored
Normal file
446
src/3rdparty/kdbindings/property.h
vendored
Normal file
@@ -0,0 +1,446 @@
|
||||
/*
|
||||
This file is part of KDBindings.
|
||||
|
||||
SPDX-FileCopyrightText: 2021-2022 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
|
||||
Author: Sean Harmer <sean.harmer@kdab.com>
|
||||
|
||||
SPDX-License-Identifier: MIT
|
||||
|
||||
Contact KDAB at <info@kdab.com> for commercial licensing options.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <kdbindings/property_updater.h>
|
||||
#include <kdbindings/signal.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
|
||||
namespace KDBindings {
|
||||
|
||||
/**
|
||||
* @brief A namespace containing parts of KDBindings that are not part of the public API.
|
||||
*
|
||||
* The contents of this namespace may only be accessed by the implementation of KDBindings, they
|
||||
* are not part of KDBindings public API and may be altered at any time and provide no guarantees
|
||||
* of any kind when used directly.
|
||||
**/
|
||||
namespace Private {
|
||||
|
||||
template<typename X, typename Y, typename = void>
|
||||
struct are_equality_comparable : std::false_type {
|
||||
};
|
||||
|
||||
template<typename X, typename Y>
|
||||
struct are_equality_comparable<X, Y,
|
||||
std::enable_if_t<
|
||||
std::is_same<
|
||||
std::decay_t<
|
||||
decltype(std::equal_to<>{}(std::declval<X>(), std::declval<Y>()))>,
|
||||
bool>::value>> : std::true_type {
|
||||
};
|
||||
|
||||
template<typename X, typename Y>
|
||||
constexpr bool are_equality_comparable_v = are_equality_comparable<X, Y>::value;
|
||||
|
||||
} // namespace Private
|
||||
|
||||
/**
|
||||
* A ReadOnlyProperty is thrown when trying to set the value of a Property
|
||||
* that has a PropertyUpdater associated with it.
|
||||
*
|
||||
* Most commonly because the property holds the result of a binding expression.
|
||||
*/
|
||||
struct ReadOnlyProperty : std::runtime_error {
|
||||
ReadOnlyProperty() = delete;
|
||||
|
||||
using std::runtime_error::runtime_error;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief An instance of the KDBindings::equal_to struct is used to decide whether
|
||||
* two values of type T are equal in the context of data binding.
|
||||
*
|
||||
* If a new value is assigned to a Property and the existing value is equal_to
|
||||
* the existing value, the Property will not emit the Property::valueChanged or
|
||||
* Property::valueAboutToChange signals and not change the stored value.
|
||||
*
|
||||
* By default, all classes T that are equality comparable using std::equal_to
|
||||
* delegate to std::equal_to for equality comparison. All other instances are
|
||||
* assumed to never be equal.
|
||||
* Therefore, to change the equality behavior of a Property<T>, either:
|
||||
* - Implement operator== for T (std::equal_to uses operator== for equality comparison)
|
||||
* - Provide a template spezialization of KDBindings::equal_to and implement operator()()
|
||||
*/
|
||||
template<typename T>
|
||||
struct equal_to {
|
||||
/**
|
||||
* This implementation of operator()() is only enabled if std::equal_to can be
|
||||
* used to compare values of type T.
|
||||
* In this case, std::equal_to is used to decide whether values of type T are equal.
|
||||
*
|
||||
* @return bool - Whether the values are equal.
|
||||
*/
|
||||
auto operator()(const T &x, const T &y) const noexcept
|
||||
-> std::enable_if_t<Private::are_equality_comparable_v<T, T>, bool>
|
||||
{
|
||||
return std::equal_to<>{}(x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* The fallback implementation of operator()() if the types are not equality comparable
|
||||
* using std::equal_to (i.e. no operator== implementation exists for this type).
|
||||
* In this case, two values of type T are assumed to never be equal.
|
||||
*
|
||||
* @return bool - Whether the values are equal - always false for this default implementation
|
||||
*/
|
||||
template<typename X, typename Y>
|
||||
auto operator()(const X &, const Y &) const noexcept
|
||||
-> std::enable_if_t<!Private::are_equality_comparable_v<X, Y>, bool>
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A property represents a value that can be part of or the result of data binding.
|
||||
*
|
||||
* Properties are at the basis of data binding.
|
||||
* They can contain a value of any type T.
|
||||
* The value can either represent the result of a data binding or a value that is used
|
||||
* in the calculation of a binding expression.
|
||||
*
|
||||
* If the value of a property is changed, either manually or because it is the result of a
|
||||
* binding expression, the Property will emit the valueAboutToChange(), and valueChanged() Signal.
|
||||
* If it is used as part of a binding expression, the expression will be marked
|
||||
* as dirty and (unless a custom BindingEvaluator is used) updated immediately.
|
||||
*
|
||||
* To create a property from a data binding expression, use the @ref makeBoundProperty or @ref makeBinding
|
||||
* functions in the @ref KDBindings namespace.
|
||||
*
|
||||
* Examples:
|
||||
* - @ref 04-simple-property/main.cpp
|
||||
* - @ref 05-property-bindings/main.cpp
|
||||
* - @ref 06-lazy-property-bindings/main.cpp
|
||||
*/
|
||||
template<typename T>
|
||||
class Property
|
||||
{
|
||||
public:
|
||||
typedef T valuetype;
|
||||
|
||||
/**
|
||||
* Properties are default constructable.
|
||||
*
|
||||
* The value of a default constructed property is then also default constructed.
|
||||
*/
|
||||
Property() = default;
|
||||
|
||||
/**
|
||||
* If a Property is destroyed, it emits the destroyed() Signal.
|
||||
*/
|
||||
~Property()
|
||||
{
|
||||
m_destroyed.emit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a Property from the provided value.
|
||||
*/
|
||||
explicit Property(T value) noexcept(std::is_nothrow_move_constructible<T>::value)
|
||||
: m_value{ std::move(value) }
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Properties are not copyable.
|
||||
*/
|
||||
Property(Property<T> const &other) = delete;
|
||||
Property &operator=(Property<T> const &other) = delete;
|
||||
|
||||
/**
|
||||
* @brief Properties are movable.
|
||||
*
|
||||
* This will emit the moved() Signal of the property that is moving as well as
|
||||
* the property being moved into.
|
||||
* All data bindings that depend on this Property will update their references
|
||||
* to the newly move-constructed Property using this Signal.
|
||||
*/
|
||||
Property(Property<T> &&other) noexcept(std::is_nothrow_move_constructible<T>::value)
|
||||
: m_value(std::move(other.m_value))
|
||||
, m_valueAboutToChange(std::move(other.m_valueAboutToChange))
|
||||
, m_valueChanged(std::move(other.m_valueChanged))
|
||||
, m_destroyed(std::move(other.m_destroyed))
|
||||
, m_updater(std::move(other.m_updater))
|
||||
{
|
||||
// We do not move the m_moved signal so that objects interested in the moved-into
|
||||
// property can recreate any connections they need.
|
||||
|
||||
// If we have an updater, let it know how to update our internal value
|
||||
if (m_updater) {
|
||||
using namespace std::placeholders;
|
||||
m_updater->setUpdateFunction(
|
||||
std::bind(&Property<T>::setHelper, this, _1));
|
||||
}
|
||||
|
||||
// Emit the moved signals for the moved from and moved to properties
|
||||
m_moved.emit(*this);
|
||||
other.m_moved.emit(*this);
|
||||
m_moved = std::move(other.m_moved);
|
||||
}
|
||||
|
||||
/**
|
||||
* See: Property(Property<T> &&other)
|
||||
*/
|
||||
Property &operator=(Property<T> &&other) noexcept(std::is_nothrow_move_assignable<T>::value)
|
||||
{
|
||||
// We do not move the m_moved signal so that objects interested in the moved-into
|
||||
// property can recreate any connections they need.
|
||||
m_value = std::move(other.m_value);
|
||||
m_valueAboutToChange = std::move(other.m_valueAboutToChange);
|
||||
m_valueChanged = std::move(other.m_valueChanged);
|
||||
m_destroyed = std::move(other.m_destroyed);
|
||||
m_updater = std::move(other.m_updater);
|
||||
|
||||
// If we have an updater, let it know how to update our internal value
|
||||
if (m_updater) {
|
||||
using namespace std::placeholders;
|
||||
m_updater->setUpdateFunction(
|
||||
std::bind(&Property<T>::setHelper, this, _1));
|
||||
}
|
||||
|
||||
// Emit the moved signals for the moved from and moved to properties
|
||||
m_moved.emit(*this);
|
||||
other.m_moved.emit(*this);
|
||||
m_moved = std::move(other.m_moved);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a property that will be updated by the specified PropertyUpdater.
|
||||
*
|
||||
* This constructor is usually called by the creation of a data binding
|
||||
* and usually doesn't need to be called manually.
|
||||
*/
|
||||
template<typename UpdaterT>
|
||||
explicit Property(std::unique_ptr<UpdaterT> &&updater)
|
||||
{
|
||||
*this = std::move(updater);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns a Binding or other Updater to this Property.
|
||||
*
|
||||
* In comparison to the move assignment operator, this does NOT change any
|
||||
* of the existing Signal connections. They are all kept as-is.
|
||||
* Only the source of the update is changed.
|
||||
*
|
||||
* This will immediately set the value of this Property to the
|
||||
* result of the updater and will call the valueAboutToChange or valueChanged
|
||||
* Signals respectively if necessary.
|
||||
*/
|
||||
template<typename UpdaterT>
|
||||
Property &operator=(std::unique_ptr<UpdaterT> &&updater)
|
||||
{
|
||||
m_updater = std::move(updater);
|
||||
|
||||
// Let the updater know how to update our internal value
|
||||
using namespace std::placeholders;
|
||||
m_updater->setUpdateFunction(
|
||||
std::bind(&Property<T>::setHelper, this, _1));
|
||||
|
||||
// Now synchronise our value with whatever the updator has right now.
|
||||
setHelper(m_updater->get());
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disconnects the binding from this Property
|
||||
*
|
||||
* If this Property has a binding, it will no longer update it.
|
||||
* Otherwise, this function does nothing.
|
||||
*
|
||||
* The value of the property does not change when it is reset.
|
||||
*/
|
||||
void reset()
|
||||
{
|
||||
m_updater.reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Signal that will be emitted before the value is changed.
|
||||
*
|
||||
* The first emitted value is the current value of the Property.<br>
|
||||
* The second emitted value is the new value of the Property.
|
||||
*/
|
||||
Signal<const T &, const T &> &valueAboutToChange() const { return m_valueAboutToChange; }
|
||||
|
||||
/**
|
||||
* Returns a Signal that will be emitted after the value of the property changed.
|
||||
*
|
||||
* The emitted value is the current (new) value of the Property.
|
||||
*/
|
||||
Signal<const T &> &valueChanged() const { return m_valueChanged; }
|
||||
|
||||
/**
|
||||
* Returns a Signal that will be emitted when the Property is moved.
|
||||
*
|
||||
* The emitted value is a reference to the newly constructed Property that
|
||||
* this Property was moved into.
|
||||
*
|
||||
* The Signal will also be emitted if another Property is moved into
|
||||
* this property.
|
||||
*/
|
||||
Signal<Property<T> &> &moved() { return m_moved; }
|
||||
Signal<Property<T> &> const &moved() const { return m_moved; }
|
||||
|
||||
/**
|
||||
* Returns a Signal that will be emitted when this Property is destructed.
|
||||
*/
|
||||
Signal<> &destroyed() const { return m_destroyed; }
|
||||
|
||||
/**
|
||||
* Assign a new value to this Property.
|
||||
*
|
||||
* If the new value is equal_to the existing value, the value will not be
|
||||
* changed and no Signal will be emitted.
|
||||
*
|
||||
* Otherwise, the valueAboutToChange() Signal will be emitted before the value
|
||||
* of the Property is changed.
|
||||
* Then, the provided value will be assigned, and the valueChanged() Signal
|
||||
* will be emitted.
|
||||
*
|
||||
* @throw ReadOnlyProperty If the Property has a PropertyUpdater associated with it (i.e. it is
|
||||
* the result of a binding expression).
|
||||
*/
|
||||
void set(T value)
|
||||
{
|
||||
if (m_updater) {
|
||||
throw ReadOnlyProperty{
|
||||
"Cannot set value on a read-only property. This property likely holds the result of a binding expression."
|
||||
};
|
||||
}
|
||||
setHelper(std::move(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value represented by this Property.
|
||||
*/
|
||||
T const &get() const
|
||||
{
|
||||
return m_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns a new value to this Property.
|
||||
*
|
||||
* See: set().
|
||||
*/
|
||||
Property<T> &operator=(T const &rhs)
|
||||
{
|
||||
set(std::move(rhs));
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value represented by this Property.
|
||||
*
|
||||
* See: get().
|
||||
*/
|
||||
T const &operator()() const
|
||||
{
|
||||
return Property<T>::get();
|
||||
}
|
||||
|
||||
private:
|
||||
void setHelper(T value)
|
||||
{
|
||||
if (equal_to<T>{}(value, m_value))
|
||||
return;
|
||||
|
||||
m_valueAboutToChange.emit(m_value, value);
|
||||
m_value = std::move(value);
|
||||
m_valueChanged.emit(m_value);
|
||||
}
|
||||
|
||||
T m_value;
|
||||
// the signals in a property are mutable, as a property
|
||||
// being "const" should mean that it's value or binding does
|
||||
// not change, not that nobody can listen to it anymore.
|
||||
mutable Signal<const T &, const T &> m_valueAboutToChange;
|
||||
mutable Signal<const T &> m_valueChanged; // By const ref so we can emit the signal for move-only types of T e.g. std::unique_ptr<int>
|
||||
Signal<Property<T> &> m_moved;
|
||||
mutable Signal<> m_destroyed;
|
||||
std::unique_ptr<PropertyUpdater<T>> m_updater;
|
||||
};
|
||||
|
||||
/**
|
||||
* Outputs the value of the Property onto an output stream.
|
||||
*/
|
||||
template<typename T>
|
||||
std::ostream &operator<<(std::ostream &stream, Property<T> const &property)
|
||||
{
|
||||
stream << property.get();
|
||||
return stream;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a value of type T from the input stream and assigns it to
|
||||
* the Property using set().
|
||||
*/
|
||||
template<typename T>
|
||||
std::istream &operator>>(std::istream &stream, Property<T> &prop)
|
||||
{
|
||||
T temp;
|
||||
stream >> temp;
|
||||
prop.set(std::move(temp));
|
||||
return stream;
|
||||
}
|
||||
|
||||
namespace Private {
|
||||
|
||||
template<typename T>
|
||||
struct is_property_helper : std::false_type {
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct is_property_helper<Property<T>> : std::true_type {
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct is_property : is_property_helper<std::decay_t<T>> {
|
||||
};
|
||||
|
||||
} // namespace Private
|
||||
|
||||
/**
|
||||
* @example 04-simple-property/main.cpp
|
||||
*
|
||||
* An example of how to create a KDBindings::Property and use its valueChanged() KDBindings::Signal to receive notifications whenever the value of the KDBindigns::Property changes.
|
||||
*
|
||||
* The output of this example is:
|
||||
* ```
|
||||
* The new value is 42
|
||||
* The new value is 69
|
||||
* Property value is 69
|
||||
* ```
|
||||
*/
|
||||
|
||||
/**
|
||||
* @example 05-property-bindings/main.cpp
|
||||
*
|
||||
* An example of how to use makeBoundProperty() to create a KDBindings::Property that is automatically updated once any of its inputs change.
|
||||
*
|
||||
* The output of this example is:
|
||||
* ```
|
||||
* The initial size of the image = 1920000 bytes
|
||||
* The new size of the image = 4608000 bytes
|
||||
* The new size of the image = 8294400 bytes
|
||||
* ```
|
||||
*/
|
||||
|
||||
} // namespace KDBindings
|
||||
66
src/3rdparty/kdbindings/property_updater.h
vendored
Normal file
66
src/3rdparty/kdbindings/property_updater.h
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
This file is part of KDBindings.
|
||||
|
||||
SPDX-FileCopyrightText: 2021-2022 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
|
||||
Author: Sean Harmer <sean.harmer@kdab.com>
|
||||
|
||||
SPDX-License-Identifier: MIT
|
||||
|
||||
Contact KDAB at <info@kdab.com> for commercial licensing options.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace KDBindings {
|
||||
|
||||
/**
|
||||
* @brief A PropertyUpdater defines the interface used to update a Property, e.g. from a binding expression.
|
||||
*
|
||||
* An instance of this class (wrapped in a std::unique_ptr) can be passed to the Property constructor.
|
||||
* The Property will then become read-only, meaning an instance of ReadOnlyProperty will be thrown if the
|
||||
* Property's value is updated through any other means than through the PropertyUpdater.
|
||||
*
|
||||
* The Property constructor will pass a function to setUpdateFunction() for this purpose.
|
||||
* This function is then the only way to update the Property without encountering a ReadOnlyProperty error.
|
||||
*
|
||||
* The most typical use of PropertyUpdater is in instances of Binding, which are created by makeBoundProperty().
|
||||
*/
|
||||
template<typename T>
|
||||
class PropertyUpdater
|
||||
{
|
||||
public:
|
||||
/** A PropertyUpdater can be default constructed. */
|
||||
PropertyUpdater() = default;
|
||||
|
||||
/** A PropertyUpdater has a virtual destructor. */
|
||||
virtual ~PropertyUpdater() = default;
|
||||
|
||||
/** A PropertyUpdater can be copy constructed. */
|
||||
PropertyUpdater(PropertyUpdater const &other) = default;
|
||||
/** A PropertyUpdater can be copy assigned. */
|
||||
PropertyUpdater &operator=(PropertyUpdater const &other) = default;
|
||||
|
||||
/** A PropertyUpdater can be move constructed. */
|
||||
PropertyUpdater(PropertyUpdater &&other) = default;
|
||||
/** A PropertyUpdater can be move assigned. */
|
||||
PropertyUpdater &operator=(PropertyUpdater &&other) = default;
|
||||
|
||||
/**
|
||||
* The Property will call this function when it constructed and pass a std::function as argument that allows
|
||||
* the PropertyUpdater to update the Property value.
|
||||
*
|
||||
* A PropertyUpdater typically saves this function and calls it once the value it computes changes.
|
||||
*/
|
||||
virtual void setUpdateFunction(std::function<void(T &&)> const &updateFunction) = 0;
|
||||
|
||||
/**
|
||||
* The get() function must return the current value the PropertyUpdater wants to assign to the Property.
|
||||
*
|
||||
* It is called from the Property constructor.
|
||||
*/
|
||||
virtual T get() const = 0;
|
||||
};
|
||||
|
||||
} // namespace KDBindings
|
||||
716
src/3rdparty/kdbindings/signal.h
vendored
Normal file
716
src/3rdparty/kdbindings/signal.h
vendored
Normal file
@@ -0,0 +1,716 @@
|
||||
/*
|
||||
This file is part of KDBindings.
|
||||
|
||||
SPDX-FileCopyrightText: 2021-2022 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
|
||||
Author: Sean Harmer <sean.harmer@kdab.com>
|
||||
|
||||
SPDX-License-Identifier: MIT
|
||||
|
||||
Contact KDAB at <info@kdab.com> for commercial licensing options.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <assert.h>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <stdexcept>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <kdbindings/genindex_array.h>
|
||||
#include <kdbindings/utils.h>
|
||||
|
||||
/**
|
||||
* @brief The main namespace of the KDBindings library.
|
||||
*
|
||||
* All public parts of KDBindings are members of this namespace.
|
||||
*/
|
||||
namespace KDBindings {
|
||||
|
||||
template<typename... Args>
|
||||
class Signal;
|
||||
|
||||
namespace Private {
|
||||
//
|
||||
// This class defines a virtual interface, that the Signal this ConnectionHandle refers
|
||||
// to must implement.
|
||||
// It allows ConnectionHandle to refer to this non-template class, which then dispatches
|
||||
// to the template implementation using virtual function calls.
|
||||
// It allows ConnectionHandle to be a non-template class.
|
||||
class SignalImplBase
|
||||
{
|
||||
public:
|
||||
SignalImplBase() = default;
|
||||
|
||||
virtual ~SignalImplBase() = default;
|
||||
|
||||
virtual void disconnect(const GenerationalIndex &id) = 0;
|
||||
virtual bool blockConnection(const GenerationalIndex &id, bool blocked) = 0;
|
||||
virtual bool isConnectionActive(const GenerationalIndex &id) const = 0;
|
||||
virtual bool isConnectionBlocked(const GenerationalIndex &id) const = 0;
|
||||
};
|
||||
|
||||
} // namespace Private
|
||||
|
||||
/**
|
||||
* @brief A ConnectionHandle represents the connection of a Signal
|
||||
* to a slot (i.e. a function that is called when the Signal is emitted).
|
||||
*
|
||||
* It is returned from a Signal when a connection is created and used to
|
||||
* manage the connection by disconnecting, (un)blocking it and checking its state.
|
||||
*
|
||||
* To make sure a Connection to an object is disconnected correctly, consider
|
||||
* storing a ScopedConnection to its ConnectionHandle inside the object.
|
||||
**/
|
||||
class ConnectionHandle
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* A ConnectionHandle can be default constructed.
|
||||
* In this case the ConnectionHandle will not reference any active connection (i.e. isActive() will return false),
|
||||
* and not belong to any Signal.
|
||||
**/
|
||||
ConnectionHandle() = default;
|
||||
|
||||
/**
|
||||
* A ConnectionHandle can be copied.
|
||||
**/
|
||||
ConnectionHandle(const ConnectionHandle &) = default;
|
||||
ConnectionHandle &operator=(const ConnectionHandle &) = default;
|
||||
|
||||
/**
|
||||
* A ConnectionHandle can be moved.
|
||||
**/
|
||||
ConnectionHandle(ConnectionHandle &&) = default;
|
||||
ConnectionHandle &operator=(ConnectionHandle &&) = default;
|
||||
|
||||
/**
|
||||
* Disconnect the slot.
|
||||
*
|
||||
* When this function is called, the function that was passed to Signal::connect
|
||||
* to create this ConnectionHandle will no longer be called when the Signal is emitted.
|
||||
*
|
||||
* If the ConnectionHandle is not active or the connection has already been disconnected,
|
||||
* nothing happens.
|
||||
*
|
||||
* After this call, the ConnectionHandle will be inactive (i.e. isActive() returns false)
|
||||
* and will no longer belong to any Signal (i.e. belongsTo returns false).
|
||||
**/
|
||||
void disconnect()
|
||||
{
|
||||
if (auto shared_impl = checkedLock()) {
|
||||
shared_impl->disconnect(m_id);
|
||||
}
|
||||
// ConnectionHandle is no longer active;
|
||||
m_signalImpl.reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the connection of this ConnectionHandle is active.
|
||||
*
|
||||
* @return true if the ConnectionHandle refers to an active Signal
|
||||
* and the connection was not disconnected previously, false otherwise.
|
||||
**/
|
||||
bool isActive() const
|
||||
{
|
||||
return static_cast<bool>(checkedLock());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the block state of the connection.
|
||||
* If a connection is blocked, emitting the Signal will no longer call this
|
||||
* connections slot, until the connection is unblocked.
|
||||
*
|
||||
* Behaves the same as calling Signal::blockConnection with this
|
||||
* ConnectionHandle as argument.
|
||||
*
|
||||
* To temporarily block a connection, consider using an instance of ConnectionBlocker,
|
||||
* which offers a RAII-style implementation that makes sure the connection is always
|
||||
* returned to its original state.
|
||||
*
|
||||
* @param blocked The new blocked state of the connection.
|
||||
* @return whether the connection was previously blocked.
|
||||
* @throw std::out_of_range Throws if the connection is not active (i.e. isActive() returns false).
|
||||
**/
|
||||
bool block(bool blocked)
|
||||
{
|
||||
if (auto shared_impl = checkedLock()) {
|
||||
return shared_impl->blockConnection(m_id, blocked);
|
||||
}
|
||||
throw std::out_of_range("Cannot block a non-active connection!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the connection is currently blocked.
|
||||
*
|
||||
* To change the blocked state of a connection, call ConnectionHandle::block.
|
||||
*
|
||||
* @return whether the connection is currently blocked.
|
||||
**/
|
||||
bool isBlocked() const
|
||||
{
|
||||
if (auto shared_impl = checkedLock()) {
|
||||
return shared_impl->isConnectionBlocked(m_id);
|
||||
}
|
||||
throw std::out_of_range("Cannot check whether a non-active connection is blocked!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether this ConnectionHandle belongs to the given Signal.
|
||||
*
|
||||
* @return true if this ConnectionHandle refers to a connection within the given Signal
|
||||
**/
|
||||
template<typename... Args>
|
||||
bool belongsTo(const Signal<Args...> &signal) const
|
||||
{
|
||||
auto shared_impl = m_signalImpl.lock();
|
||||
return shared_impl && shared_impl == std::static_pointer_cast<Private::SignalImplBase>(signal.m_impl);
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename...>
|
||||
friend class Signal;
|
||||
|
||||
std::weak_ptr<Private::SignalImplBase> m_signalImpl;
|
||||
Private::GenerationalIndex m_id;
|
||||
|
||||
// private, so it is only available from Signal
|
||||
ConnectionHandle(std::weak_ptr<Private::SignalImplBase> signalImpl, Private::GenerationalIndex id)
|
||||
: m_signalImpl{ std::move(signalImpl) }, m_id{ std::move(id) }
|
||||
{
|
||||
}
|
||||
|
||||
// Checks that the weak_ptr can be locked and that the connection is
|
||||
// still active
|
||||
std::shared_ptr<Private::SignalImplBase> checkedLock() const
|
||||
{
|
||||
auto shared_impl = m_signalImpl.lock();
|
||||
if (shared_impl && shared_impl->isConnectionActive(m_id)) {
|
||||
return shared_impl;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A Signal provides a mechanism for communication between objects.
|
||||
*
|
||||
* KDBindings::Signal recreates the <a href="https://doc.qt.io/qt-5/signalsandslots.html">Qt's Signals & Slots mechanism</a> in pure C++17.
|
||||
* A Signal can be used to notify any number of slots that a certain event has occurred.
|
||||
*
|
||||
* The slot can be almost any callable object, including member functions and lambdas.
|
||||
*
|
||||
* This connection happens in a type-safe manner, as a slot can only be connected to
|
||||
* a Signal when the arguments of the slot match the values the Signal emits.
|
||||
*
|
||||
* The Args type parameter pack describe which value types the Signal will emit.
|
||||
*
|
||||
* Examples:
|
||||
* - @ref 01-simple-connection/main.cpp
|
||||
* - @ref 02-signal-member/main.cpp
|
||||
* - @ref 03-member-arguments/main.cpp
|
||||
* - @ref 07-advanced-connections/main.cpp
|
||||
*/
|
||||
template<typename... Args>
|
||||
class Signal
|
||||
{
|
||||
static_assert(
|
||||
std::conjunction<std::negation<std::is_rvalue_reference<Args>>...>::value,
|
||||
"R-value references are not allowed as Signal parameters!");
|
||||
|
||||
// The Signal::Impl class exists, so Signals can be implemented in a PIMPL-like way.
|
||||
// This allows us to easily move Signals without losing their ConnectionHandles, as well as
|
||||
// making an unconnected Signal only sizeof(shared_ptr).
|
||||
class Impl : public Private::SignalImplBase
|
||||
{
|
||||
public:
|
||||
Impl() noexcept { }
|
||||
|
||||
~Impl() noexcept { }
|
||||
|
||||
// Signal::Impls are not copyable
|
||||
Impl(Impl const &other) = delete;
|
||||
Impl &operator=(Impl const &other) = delete;
|
||||
|
||||
// Signal::Impls are not moveable, this would break the ConnectionHandles
|
||||
Impl(Impl &&other) = delete;
|
||||
Impl &operator=(Impl &&other) = delete;
|
||||
|
||||
// Connects a std::function to the signal. The returned
|
||||
// value can be used to disconnect the function again.
|
||||
Private::GenerationalIndex connect(std::function<void(Args...)> const &slot)
|
||||
{
|
||||
return m_connections.insert({ slot });
|
||||
}
|
||||
|
||||
// Disconnects a previously connected function
|
||||
void disconnect(const Private::GenerationalIndex &id) override
|
||||
{
|
||||
m_connections.erase(id);
|
||||
}
|
||||
|
||||
// Disconnects all previously connected functions
|
||||
void disconnectAll()
|
||||
{
|
||||
m_connections.clear();
|
||||
}
|
||||
|
||||
bool blockConnection(const Private::GenerationalIndex &id, bool blocked) override
|
||||
{
|
||||
Connection *connection = m_connections.get(id);
|
||||
if (connection) {
|
||||
const bool wasBlocked = connection->blocked;
|
||||
connection->blocked = blocked;
|
||||
return wasBlocked;
|
||||
} else {
|
||||
throw std::out_of_range("Provided ConnectionHandle does not match any connection\nLikely the connection was deleted before!");
|
||||
}
|
||||
}
|
||||
|
||||
bool isConnectionActive(const Private::GenerationalIndex &id) const override
|
||||
{
|
||||
return m_connections.get(id);
|
||||
}
|
||||
|
||||
bool isConnectionBlocked(const Private::GenerationalIndex &id) const override
|
||||
{
|
||||
auto connection = m_connections.get(id);
|
||||
if (connection) {
|
||||
return connection->blocked;
|
||||
} else {
|
||||
throw std::out_of_range("Provided ConnectionHandle does not match any connection\nLikely the connection was deleted before!");
|
||||
}
|
||||
}
|
||||
|
||||
// Calls all connected functions
|
||||
void emit(Args... p) const
|
||||
{
|
||||
const auto numEntries = m_connections.entriesSize();
|
||||
|
||||
// This loop can tolerate signal handles being disconnected inside a slot,
|
||||
// but adding new connections to a signal inside a slot will still be undefined behaviour
|
||||
for (auto i = decltype(numEntries){ 0 }; i < numEntries; ++i) {
|
||||
const auto index = m_connections.indexAtEntry(i);
|
||||
|
||||
if (index) {
|
||||
const auto con = m_connections.get(*index);
|
||||
|
||||
if (!con->blocked)
|
||||
con->slot(p...);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
struct Connection {
|
||||
std::function<void(Args...)> slot;
|
||||
bool blocked{ false };
|
||||
};
|
||||
mutable Private::GenerationalIndexArray<Connection> m_connections;
|
||||
};
|
||||
|
||||
public:
|
||||
/** Signals are default constructible */
|
||||
Signal() = default;
|
||||
|
||||
/**
|
||||
* Signals cannot be copied.
|
||||
**/
|
||||
Signal(const Signal &) = delete;
|
||||
Signal &operator=(Signal const &other) = delete;
|
||||
|
||||
/** Signals can be moved */
|
||||
Signal(Signal &&other) noexcept = default;
|
||||
Signal &operator=(Signal &&other) noexcept = default;
|
||||
|
||||
/**
|
||||
* A signal disconnects all slots when it is destructed
|
||||
*
|
||||
* Therefore, all active ConnectionHandles that belonged to this Signal
|
||||
* will no longer be active (i.e. ConnectionHandle::isActive will return false).
|
||||
*/
|
||||
~Signal()
|
||||
{
|
||||
disconnectAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects a std::function to the signal.
|
||||
*
|
||||
* When emit() is called on the Signal, the functions will be called with
|
||||
* the arguments provided to emit().
|
||||
*
|
||||
* @return An instance of ConnectionHandle, that can be used to disconnect
|
||||
* or temporarily block the connection.
|
||||
*/
|
||||
ConnectionHandle connect(std::function<void(Args...)> const &slot)
|
||||
{
|
||||
ensureImpl();
|
||||
|
||||
return ConnectionHandle{ m_impl, m_impl->connect(slot) };
|
||||
}
|
||||
|
||||
/**
|
||||
* A template overload of Signal::connect that makes it easier to connect arbitrary functions to this
|
||||
* Signal.
|
||||
* It connects a function to this Signal, binds any provided arguments to that function and discards
|
||||
* any values emitted by this Signal that aren't needed by the resulting function.
|
||||
*
|
||||
* This is especially useful for connecting member functions to signals.
|
||||
*
|
||||
* Examples:
|
||||
* @code
|
||||
* Signal<int> signal;
|
||||
* std::vector<int> numbers{ 1, 2, 3 };
|
||||
* bool emitted = false;
|
||||
*
|
||||
* // disambiguation necessary, as push_back is overloaded.
|
||||
* void (std::vector<int>::*push_back)(const int &) = &std::vector<int>::push_back;
|
||||
* signal.connect(push_back, &numbers);
|
||||
*
|
||||
* // this slot doesn't require the int argument, so it will be discarded.
|
||||
* signal.connect([&emitted]() { emitted = true; });
|
||||
*
|
||||
* signal.emit(4); // Will add 4 to the vector and set emitted to true
|
||||
* @endcode
|
||||
*
|
||||
* For more examples see the @ref 07-advanced-connections/main.cpp example.
|
||||
*
|
||||
* @return An instance of a Signal::ConnectionHandle that refers to this connection.
|
||||
* Warning: When connecting a member function you must use the returned ConnectionHandle
|
||||
* to disconnect when the object containing the slot goes out of scope!
|
||||
**/
|
||||
// The enable_if_t makes sure that this connect function specialization is only
|
||||
// available if we provide a function that cannot be otherwise converted to a
|
||||
// std::function<void(Args...)>, as it otherwise tries to take precedence
|
||||
// over the normal connect function.
|
||||
template<typename Func, typename... FuncArgs, typename = std::enable_if_t<std::disjunction_v<std::negation<std::is_convertible<Func, std::function<void(Args...)>>>, std::integral_constant<bool, sizeof...(FuncArgs) /*Also enable this function if we want to bind at least one argument*/>>>>
|
||||
ConnectionHandle connect(Func &&slot, FuncArgs &&...args)
|
||||
{
|
||||
std::function<void(Args...)> bound = Private::bind_first(std::forward<Func>(slot), std::forward<FuncArgs>(args)...);
|
||||
return connect(bound);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnect a previously connected slot.
|
||||
*
|
||||
* After the slot was successfully disconnected, the ConnectionHandle will no
|
||||
* longer be active. (i.e. ConnectionHandle::isActive will return false).
|
||||
*
|
||||
* @throw std::out_of_range - If the ConnectionHandle does not belong to this
|
||||
* Signal (i.e. ConnectionHandle::belongsTo returns false).
|
||||
*/
|
||||
void disconnect(const ConnectionHandle &handle)
|
||||
{
|
||||
if (m_impl && handle.belongsTo(*this)) {
|
||||
m_impl->disconnect(handle.m_id);
|
||||
// TODO check if Impl is now empty and reset
|
||||
} else {
|
||||
throw std::out_of_range("Provided ConnectionHandle does not match any connection\nLikely the connection was deleted before!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnect all previously connected functions.
|
||||
*
|
||||
* All currently active ConnectionHandles that belong to this Signal will no
|
||||
* longer be active afterwards. (i.e. ConnectionHandle::isActive will return false).
|
||||
*/
|
||||
void disconnectAll()
|
||||
{
|
||||
if (m_impl) {
|
||||
m_impl->disconnectAll();
|
||||
// Once all connections are disconnected, we can release ownership of the Impl.
|
||||
// This does not destroy the Signal itself, just the Impl object.
|
||||
// If another slot is connected, another Impl object will be constructed.
|
||||
m_impl.reset();
|
||||
}
|
||||
// If m_impl is nullptr, we don't have any connections to disconnect
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the block state of the connection.
|
||||
* If a connection is blocked, emitting the Signal will no longer call this
|
||||
* connections slot, until the connection is unblocked.
|
||||
*
|
||||
* ConnectionHandle::block can be used as an alternative.
|
||||
*
|
||||
* To temporarily block a connection, consider using an instance of ConnectionBlocker,
|
||||
* which offers a RAII-style implementation that makes sure the connection is always
|
||||
* returned to its original state.
|
||||
*
|
||||
* @param blocked Whether the connection should be blocked from now on.
|
||||
* @param handle The ConnectionHandle to block.
|
||||
* @return Whether the connection was previously blocked.
|
||||
* @throw std::out_of_range - If the ConnectionHandle does not belong to this
|
||||
* Signal (i.e. ConnectionHandle::belongsTo returns false).
|
||||
*/
|
||||
bool blockConnection(const ConnectionHandle &handle, bool blocked)
|
||||
{
|
||||
if (m_impl && handle.belongsTo(*this)) {
|
||||
return m_impl->blockConnection(handle.m_id, blocked);
|
||||
} else {
|
||||
throw std::out_of_range("Provided ConnectionHandle does not match any connection\nLikely the connection was deleted before!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the connection is currently blocked.
|
||||
*
|
||||
* To change the blocked state of a connection, call blockConnection().
|
||||
*
|
||||
* @return Whether the connection is currently blocked
|
||||
* @throw std::out_of_range - If the ConnectionHandle does not belong to this
|
||||
* Signal (i.e. ConnectionHandle::belongsTo returns false).
|
||||
*/
|
||||
bool isConnectionBlocked(const ConnectionHandle &handle) const
|
||||
{
|
||||
assert(handle.belongsTo(*this));
|
||||
if (!m_impl) {
|
||||
throw std::out_of_range("Provided ConnectionHandle does not match any connection\nLikely the connection was deleted before!");
|
||||
}
|
||||
|
||||
return m_impl->isConnectionBlocked(handle.m_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Emits the Signal, which causes all connected slots to be called,
|
||||
* as long as they are not blocked.
|
||||
*
|
||||
* The arguments provided to emit will be passed to each slot by copy,
|
||||
* therefore consider using (const) references as the Args to the Signal
|
||||
* wherever possible.
|
||||
*
|
||||
* Note: Slots may disconnect themselves during an emit, however it is
|
||||
* undefined whether a slot that is connected during the emit function
|
||||
* of the Signal will also be called during this emit, or only at the next
|
||||
* emit.
|
||||
*/
|
||||
void emit(Args... p) const
|
||||
{
|
||||
if (m_impl)
|
||||
m_impl->emit(p...);
|
||||
|
||||
// if m_impl is nullptr, we don't have any slots connected, don't bother emitting
|
||||
}
|
||||
|
||||
private:
|
||||
friend class ConnectionHandle;
|
||||
|
||||
void ensureImpl()
|
||||
{
|
||||
if (!m_impl) {
|
||||
m_impl = std::make_shared<Impl>();
|
||||
}
|
||||
}
|
||||
|
||||
// shared_ptr is used here instead of unique_ptr, so ConnectionHandle instances can
|
||||
// use a weak_ptr to check if the Signal::Impl they reference is still alive.
|
||||
//
|
||||
// This makes Signals easily copyable in theory, but the semantics of this are unclear.
|
||||
// Copying could either simply copy the shared_ptr, which means the copy would share
|
||||
// the connections of the original, which is possibly unintuitive, or the Impl would
|
||||
// have to be copied as well.
|
||||
// This would however leave connections without handles to disconnect them.
|
||||
// So copying is forbidden for now.
|
||||
//
|
||||
// Think of this shared_ptr more like a unique_ptr with additional weak_ptr's
|
||||
// in ConnectionHandle that can check whether the Impl object is still alive.
|
||||
mutable std::shared_ptr<Impl> m_impl;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A ScopedConnection is a RAII-style way to make sure a Connection is disconnected.
|
||||
*
|
||||
* When the ScopedConnections scope ends, the connection this ScopedConnection guards will be disconnected.
|
||||
*
|
||||
* Example:
|
||||
* - @ref 08-managing-connections/main.cpp
|
||||
*/
|
||||
class ScopedConnection
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief A ScopedConnection can be default constructed
|
||||
*
|
||||
* A default constructed ScopedConnection has no connection to guard.
|
||||
* Therefore it does nothing when it is destructed, unless a ConnectionHandle is assigned to it.
|
||||
*/
|
||||
ScopedConnection() = default;
|
||||
|
||||
/** A ScopedConnection can be move constructed */
|
||||
ScopedConnection(ScopedConnection &&) = default;
|
||||
/** A ScopedConnection can be move assigned */
|
||||
ScopedConnection &operator=(ScopedConnection &&) = default;
|
||||
|
||||
/** A ScopedConnection cannot be copied */
|
||||
ScopedConnection(const ScopedConnection &) = delete;
|
||||
/** A ScopedConnection cannot be copied */
|
||||
ScopedConnection &operator=(const ScopedConnection &) = delete;
|
||||
|
||||
/**
|
||||
* A ScopedConnection can be constructed from a ConnectionHandle
|
||||
*/
|
||||
ScopedConnection(ConnectionHandle &&h)
|
||||
: m_connection(std::move(h))
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* A ScopedConnection can be assigned from a ConnectionHandle
|
||||
*/
|
||||
ScopedConnection &operator=(ConnectionHandle &&h)
|
||||
{
|
||||
m_connection.disconnect();
|
||||
m_connection = std::move(h);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the handle to the connection this instance is managing
|
||||
*/
|
||||
ConnectionHandle &handle()
|
||||
{
|
||||
return m_connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @overload
|
||||
*/
|
||||
const ConnectionHandle &handle() const
|
||||
{
|
||||
return m_connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience access to the underlying ConnectionHandle using the `->` operator.
|
||||
*/
|
||||
ConnectionHandle *operator->()
|
||||
{
|
||||
return &m_connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @overload
|
||||
*/
|
||||
const ConnectionHandle *operator->() const
|
||||
{
|
||||
return &m_connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* When a ConnectionHandle is destructed it disconnects the connection it guards.
|
||||
*/
|
||||
~ScopedConnection()
|
||||
{
|
||||
m_connection.disconnect();
|
||||
}
|
||||
|
||||
private:
|
||||
ConnectionHandle m_connection;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A ConnectionBlocker is a convenient RAII-style mechanism for temporarily blocking a connection.
|
||||
*
|
||||
* When a ConnectionBlocker is constructed, it will block the connection.
|
||||
*
|
||||
* When it is destructed, it will return the connection to the blocked state it was in
|
||||
* before the ConnectionBlocker was constructed.
|
||||
*
|
||||
* Example:
|
||||
* - @ref 08-managing-connections/main.cpp
|
||||
*/
|
||||
class ConnectionBlocker
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructs a new ConnectionBlocker and blocks the connection this ConnectionHandle
|
||||
* refers to.
|
||||
*
|
||||
* @throw std::out_of_range If the connection is not active (i.e. ConnectionHandle::isActive() returns false).
|
||||
*/
|
||||
explicit ConnectionBlocker(const ConnectionHandle &handle)
|
||||
: m_handle{ handle }
|
||||
{
|
||||
m_wasBlocked = m_handle.block(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructs the ConnectionBlocker and returns the connection into the blocked state it was in
|
||||
* before the ConnectionBlocker was constructed.
|
||||
*/
|
||||
~ConnectionBlocker()
|
||||
{
|
||||
m_handle.block(m_wasBlocked);
|
||||
}
|
||||
|
||||
private:
|
||||
ConnectionHandle m_handle;
|
||||
bool m_wasBlocked{ false };
|
||||
};
|
||||
|
||||
/**
|
||||
* @example 01-simple-connection/main.cpp
|
||||
*
|
||||
* A simple example of how to create a KDBindings::Signal and connect a lambda to it.
|
||||
*
|
||||
* The output of this example is:
|
||||
* ```
|
||||
* The answer: 42
|
||||
* ```
|
||||
*/
|
||||
|
||||
/**
|
||||
* @example 02-signal-member/main.cpp
|
||||
*
|
||||
* An example of how to connect a member function to a KDBindings::Signal.
|
||||
*
|
||||
* The output of this example is:
|
||||
* ```
|
||||
* Hello World!
|
||||
* ```
|
||||
*/
|
||||
|
||||
/**
|
||||
* @example 03-member-arguments/main.cpp
|
||||
*
|
||||
* An example of how to connect a member function with arguments to a KDBindings::Signal.
|
||||
*
|
||||
* The output of this example is:
|
||||
* ```
|
||||
* Bob received: Have a nice day!
|
||||
* Alice received: Thank you!
|
||||
* ```
|
||||
*/
|
||||
|
||||
/**
|
||||
* @example 07-advanced-connections/main.cpp
|
||||
*
|
||||
* An example of how to use the KDBindings::Signal::connect() overloaded function for advanced slot connections.
|
||||
*
|
||||
* The output of this example is:
|
||||
* ```
|
||||
* Hello World!
|
||||
* Emitted value: 5
|
||||
* true
|
||||
* ```
|
||||
*/
|
||||
|
||||
/**
|
||||
* @example 08-managing-connections/main.cpp
|
||||
*
|
||||
* An example of how to use a ScopedConnection and ConnectionBlocker to manage
|
||||
* when a Connection is disconnected or blocked.
|
||||
*
|
||||
* Expected output:
|
||||
* ```
|
||||
* Guard is connected: 1
|
||||
* Connection is not blocked: 3
|
||||
* Connection is not blocked: 5
|
||||
* ```
|
||||
*/
|
||||
|
||||
} // namespace KDBindings
|
||||
169
src/3rdparty/kdbindings/utils.h
vendored
Normal file
169
src/3rdparty/kdbindings/utils.h
vendored
Normal file
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
This file is part of KDBindings.
|
||||
|
||||
SPDX-FileCopyrightText: 2021-2022 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
|
||||
Author: Leon Matthes <leon.matthes@kdab.com>
|
||||
|
||||
SPDX-License-Identifier: MIT
|
||||
|
||||
Contact KDAB at <info@kdab.com> for commercial licensing options.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace KDBindings {
|
||||
|
||||
/**
|
||||
* The contents of this namespace may only be accessed by the implementation of KDBindings, they
|
||||
* are not part of KDBindings public API and may be altered at any time and provide no guarantees
|
||||
* of any kind when used directly.
|
||||
**/
|
||||
namespace Private {
|
||||
|
||||
// ------------------------ get_arity --------------------------
|
||||
// get_arity is a template function that returns the number of arguments
|
||||
// of (almost) any callable object.
|
||||
// The easiest way is to simply call get_arity<T>() for callable type T.
|
||||
// It needs to be constexpr in order so it can be used in template arguments.
|
||||
|
||||
// To overload get_arity, it needs a marker type, as C++ doesn't allow partial
|
||||
// function specialization.
|
||||
template<typename T>
|
||||
struct TypeMarker {
|
||||
constexpr TypeMarker() = default;
|
||||
};
|
||||
|
||||
// base implementation of get_arity refers to specialized implementations for each
|
||||
// type of callable object by using the overload for its specialized TypeMarker.
|
||||
template<typename T>
|
||||
constexpr size_t get_arity()
|
||||
{
|
||||
return get_arity(TypeMarker<std::decay_t<T>>{});
|
||||
}
|
||||
|
||||
// Syntactic sugar version of get_arity, allows to pass any callable object
|
||||
// to get_arity, instead of having to pass its decltype as a template argument.
|
||||
template<typename T>
|
||||
constexpr size_t get_arity(const T &)
|
||||
{
|
||||
return get_arity<T>();
|
||||
}
|
||||
|
||||
// The arity of a function pointer is simply its number of arguments.
|
||||
template<typename Return, typename... Arguments>
|
||||
constexpr size_t get_arity(TypeMarker<Return (*)(Arguments...)>)
|
||||
{
|
||||
return sizeof...(Arguments);
|
||||
}
|
||||
|
||||
template<typename Return, typename... Arguments>
|
||||
constexpr size_t get_arity(TypeMarker<Return (*)(Arguments...) noexcept>)
|
||||
{
|
||||
return sizeof...(Arguments);
|
||||
}
|
||||
|
||||
// The arity of a generic callable object is the arity of its operator() - 1, as the this
|
||||
// pointer is already known for such an object.
|
||||
template<typename T>
|
||||
constexpr size_t get_arity(TypeMarker<T>)
|
||||
{
|
||||
return get_arity(TypeMarker<decltype(&T::operator())>{}) - 1;
|
||||
}
|
||||
|
||||
// Macro to help define most combinations of possible member function qualifiers.
|
||||
// Add + 1 to sizeof...(Arguments) here as the "this" pointer is an implicit argument to any member function.
|
||||
#define KDBINDINGS_DEFINE_MEMBER_GET_ARITY(MODIFIERS) \
|
||||
template<typename Return, typename Class, typename... Arguments> \
|
||||
constexpr size_t get_arity(::KDBindings::Private::TypeMarker<Return (Class::*)(Arguments...) MODIFIERS>) \
|
||||
{ \
|
||||
return sizeof...(Arguments) + 1; \
|
||||
}
|
||||
|
||||
// Define the get_arity version without modifiers without using the macro.
|
||||
// MSVC otherwise complains about a call to the macro with too few arguments
|
||||
template<typename Return, typename Class, typename... Arguments>
|
||||
constexpr size_t get_arity(::KDBindings::Private::TypeMarker<Return (Class::*)(Arguments...)>)
|
||||
{
|
||||
return sizeof...(Arguments) + 1;
|
||||
}
|
||||
|
||||
KDBINDINGS_DEFINE_MEMBER_GET_ARITY(const)
|
||||
KDBINDINGS_DEFINE_MEMBER_GET_ARITY(&)
|
||||
KDBINDINGS_DEFINE_MEMBER_GET_ARITY(const &)
|
||||
KDBINDINGS_DEFINE_MEMBER_GET_ARITY(&&)
|
||||
KDBINDINGS_DEFINE_MEMBER_GET_ARITY(const &&)
|
||||
|
||||
KDBINDINGS_DEFINE_MEMBER_GET_ARITY(volatile)
|
||||
KDBINDINGS_DEFINE_MEMBER_GET_ARITY(volatile const)
|
||||
KDBINDINGS_DEFINE_MEMBER_GET_ARITY(volatile &)
|
||||
KDBINDINGS_DEFINE_MEMBER_GET_ARITY(volatile const &)
|
||||
KDBINDINGS_DEFINE_MEMBER_GET_ARITY(volatile &&)
|
||||
KDBINDINGS_DEFINE_MEMBER_GET_ARITY(volatile const &&)
|
||||
|
||||
KDBINDINGS_DEFINE_MEMBER_GET_ARITY(noexcept)
|
||||
KDBINDINGS_DEFINE_MEMBER_GET_ARITY(const noexcept)
|
||||
KDBINDINGS_DEFINE_MEMBER_GET_ARITY(&noexcept)
|
||||
KDBINDINGS_DEFINE_MEMBER_GET_ARITY(const &noexcept)
|
||||
KDBINDINGS_DEFINE_MEMBER_GET_ARITY(&&noexcept)
|
||||
KDBINDINGS_DEFINE_MEMBER_GET_ARITY(const &&noexcept)
|
||||
|
||||
KDBINDINGS_DEFINE_MEMBER_GET_ARITY(volatile noexcept)
|
||||
KDBINDINGS_DEFINE_MEMBER_GET_ARITY(volatile const noexcept)
|
||||
KDBINDINGS_DEFINE_MEMBER_GET_ARITY(volatile &noexcept)
|
||||
KDBINDINGS_DEFINE_MEMBER_GET_ARITY(volatile const &noexcept)
|
||||
KDBINDINGS_DEFINE_MEMBER_GET_ARITY(volatile &&noexcept)
|
||||
KDBINDINGS_DEFINE_MEMBER_GET_ARITY(volatile const &&noexcept)
|
||||
|
||||
// -------------------- placeholder and bind_first ---------------------
|
||||
// Inspired by https://gist.github.com/engelmarkus/fc1678adbed1b630584c90219f77eb48
|
||||
// A placeholder provides a way to construct something equivalent to a std::placeholders::_N
|
||||
// with N as a template argument.
|
||||
//
|
||||
// Note: As placeholders start at 1, therefore placeholder<0> is NOT a valid placeholder.
|
||||
template<int>
|
||||
struct placeholder {
|
||||
};
|
||||
|
||||
template<typename Func, typename... Args, std::size_t... Is>
|
||||
auto bind_first_helper(std::index_sequence<Is...>, Func &&fun, Args... args)
|
||||
{
|
||||
return std::bind(std::forward<Func>(fun), std::forward<Args>(args)..., placeholder<Is + 1>{}...);
|
||||
}
|
||||
|
||||
// bind_first binds the first arguments to the callable object (i.e. function) to the values provided by args.
|
||||
// The return value is a new function taking get_arity<Func> - sizeof...(Args) many arguments, with the first
|
||||
// sizeof...(Args) arguments bound to the values of args.
|
||||
// This is different to a call with std::bind(fun, args...), as the callable object created by std::bind would
|
||||
// in this case now take zero arguments, whilst bind_first still expects the remaining arguments to be provided
|
||||
//
|
||||
// For now, providing instances of std::placeholders in Args is not allowed, as the implications of this are
|
||||
// unclear if sizeof...(Args) != get_arity<Func>. The enable_if_t makes sure none of the Args value is a placeholder.
|
||||
//
|
||||
// In the future, we could provide another overload of this function that allows placeholders, as long as all arguments
|
||||
// are bound.
|
||||
template<
|
||||
typename Func,
|
||||
typename... Args,
|
||||
/*Disallow any placeholder arguments, they would mess with the number and ordering of required and bound arguments, and are, for now, unsupported*/
|
||||
typename = std::enable_if_t<std::conjunction_v<std::negation<std::is_placeholder<Args>>...>>>
|
||||
auto bind_first(Func &&fun, Args &&...args)
|
||||
{
|
||||
return bind_first_helper(std::make_index_sequence<get_arity<Func>() - sizeof...(Args)>{}, std::forward<Func>(fun), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
} // namespace Private
|
||||
|
||||
} // namespace KDBindings
|
||||
|
||||
namespace std {
|
||||
|
||||
// This allows a placeholder to be used as a replacement of a std::placeholders.
|
||||
template<int N>
|
||||
struct is_placeholder<KDBindings::Private::placeholder<N>>
|
||||
: integral_constant<int, N> {
|
||||
};
|
||||
|
||||
} // namespace std
|
||||
21
src/3rdparty/nlohmann/nlohmann/LICENSE.MIT
vendored
Normal file
21
src/3rdparty/nlohmann/nlohmann/LICENSE.MIT
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2013-2022 Niels Lohmann
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user