Compare commits
917 commits
21cb6859a2
...
de43670ec2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
de43670ec2 | ||
|
|
d0f4815ef9 | ||
|
|
e94e6fabd2 | ||
|
|
f59bb2be3e | ||
|
|
33419cfee3 | ||
|
|
72ddf606f3 | ||
|
|
335cb5d396 | ||
|
|
fa7904a469 | ||
|
|
e69cf0064a | ||
|
|
69b39bd884 | ||
|
|
ffe1e7efaf | ||
|
|
c82b9753c6 | ||
|
|
dc96e3e3ad | ||
|
|
26e7220959 | ||
|
|
fa71e1fc85 | ||
|
|
5b031b7095 | ||
|
|
89de7718e6 | ||
|
|
d9a7858c2d | ||
|
|
072865d2e5 | ||
|
|
193f42318c | ||
|
|
c5b858021f | ||
|
|
bd27d0e562 | ||
|
|
e0a4dee72b | ||
|
|
719142ca12 | ||
|
|
c76c9b57ed | ||
|
|
88d968a533 | ||
|
|
63e6ba7709 | ||
|
|
8b8387ff87 | ||
|
|
6c68edf955 | ||
|
|
7d6e30cb8e | ||
|
|
86838739f0 | ||
|
|
f497f1ef84 | ||
|
|
6b26d4e7b2 | ||
|
|
dfb00b96df | ||
|
|
258466e02c | ||
|
|
f85bf9283a | ||
|
|
94d81c0c6b | ||
|
|
5a8ebfa7ae | ||
|
|
35b7cf053c | ||
|
|
0f3c1af3e1 | ||
|
|
0f3a5fe010 | ||
|
|
43e6063eb4 | ||
|
|
76038686d5 | ||
|
|
73beea8842 | ||
|
|
2ffc1ca9b0 | ||
|
|
ad8569532a | ||
|
|
f387e1e525 | ||
|
|
9ac941686b | ||
|
|
9076772cf6 | ||
|
|
13a891b477 | ||
|
|
791bf16586 | ||
|
|
7527e845a9 | ||
|
|
7200acc382 | ||
|
|
5c9e90d805 | ||
|
|
51806d1742 | ||
|
|
6b09b7cb9b | ||
|
|
4e74a8d38e | ||
|
|
40fc41b724 | ||
|
|
d5cda9b353 | ||
|
|
6cb668f546 | ||
|
|
01ae858906 | ||
|
|
90f663ee1a | ||
|
|
c3d39e2571 | ||
|
|
cf2a495e26 | ||
|
|
17af5e27ac | ||
|
|
8e9db6a2fe | ||
|
|
a6f8547455 | ||
|
|
331b2d855f | ||
|
|
4bd749d976 | ||
|
|
d160ec2e28 | ||
|
|
7723aee1d8 | ||
|
|
fa50defe62 | ||
|
|
c0025abd32 | ||
|
|
0744740f9a | ||
|
|
327129999e | ||
|
|
1e821fdf6c | ||
|
|
bbb09f64f0 | ||
|
|
7722eeb539 | ||
|
|
b2653fd585 | ||
|
|
788bd114cc | ||
|
|
b8a0dae042 | ||
|
|
afcca785eb | ||
|
|
3a8cdb8ea1 | ||
|
|
2750168287 | ||
|
|
847c5d951e | ||
|
|
5f661df9fd | ||
|
|
5716d89d52 | ||
|
|
9eea0a4dc8 | ||
|
|
f684d62cb1 | ||
|
|
76c6ac2ccd | ||
|
|
b89938b48a | ||
|
|
e51fd8b77b | ||
|
|
ec06cc62e1 | ||
|
|
a81d6f340d | ||
|
|
559f577597 | ||
|
|
ceb58c1a4c | ||
|
|
55e7979070 | ||
|
|
2a24716d77 | ||
|
|
5262551e1d | ||
|
|
a656a723db | ||
|
|
41a2b989ae | ||
|
|
99219f1c44 | ||
|
|
9d13023a51 | ||
|
|
fdcc5f01c9 | ||
|
|
b626293f54 | ||
|
|
5d39d42061 | ||
|
|
dbde1adaa3 | ||
|
|
69d9137faf | ||
|
|
48c5dd4fc4 | ||
|
|
cfa7c774ac | ||
|
|
16a962dbec | ||
|
|
ccd27980a2 | ||
|
|
a5a96eb7c4 | ||
|
|
19e8e51505 | ||
|
|
3000e23cb1 | ||
|
|
8a56d3deed | ||
|
|
cb81287c08 | ||
|
|
337406971a | ||
|
|
ac4521483d | ||
|
|
9f641dcdc5 | ||
|
|
9f7f1bf860 | ||
|
|
d4b3c1869b | ||
|
|
696c277f94 | ||
|
|
b6aa85a916 | ||
|
|
e86fec8d99 | ||
|
|
012d70b3a2 | ||
|
|
58b6c5e1eb | ||
|
|
cb5f5379cb | ||
|
|
a87cb01935 | ||
|
|
8d7d29bf5e | ||
|
|
e3cf37f9ed | ||
|
|
26e24da4b5 | ||
|
|
7b6e0478d4 | ||
|
|
36b2e77ecf | ||
|
|
fbacb7dc13 | ||
|
|
52675721b4 | ||
|
|
28ca8df5df | ||
|
|
0ff0f6ea17 | ||
|
|
4306bb09ae | ||
|
|
34ec35caf0 | ||
|
|
4425c53c8e | ||
|
|
e76260dffa | ||
|
|
0b3f2c49db | ||
|
|
9ec1a62403 | ||
|
|
0dcf8eabab | ||
|
|
c9d1e4cd08 | ||
|
|
c36144bab3 | ||
|
|
f7ef3ad1f7 | ||
|
|
ed1bb7422d | ||
|
|
83c5d15cdf | ||
|
|
ad65bcf424 | ||
|
|
d12fe2b7a5 | ||
|
|
f3620d99a2 | ||
|
|
3718fc8872 | ||
|
|
7748d27b95 | ||
|
|
9ce411d85b | ||
|
|
ea2c2e8f58 | ||
|
|
ffbe3aedad | ||
|
|
0e90f8a7a1 | ||
|
|
ac475999f5 | ||
|
|
4ad2983c24 | ||
|
|
5e10cdd6b4 | ||
|
|
6fca723404 | ||
|
|
3de270c2a1 | ||
|
|
6667f46c53 | ||
|
|
102650e936 | ||
|
|
9c486d5018 | ||
|
|
ea7be1fa3a | ||
|
|
4e3600414e | ||
|
|
571fdfa692 | ||
|
|
0da5051408 | ||
|
|
25e32cf0ec | ||
|
|
6d23b094e6 | ||
|
|
6c7b5b3d22 | ||
|
|
10021a8ba2 | ||
|
|
81b0402e8a | ||
|
|
3cf6b96c8c | ||
|
|
9d188b7d95 | ||
|
|
c4af3724c1 | ||
|
|
8f84a42e26 | ||
|
|
e78aca7377 | ||
|
|
c7a19658ef | ||
|
|
fb675811dd | ||
|
|
9d6a0358d0 | ||
|
|
699f60d399 | ||
|
|
60d52b5c59 | ||
|
|
04e45978ad | ||
|
|
e845968e57 | ||
|
|
4ed1fda1ae | ||
|
|
38d36d37f6 | ||
|
|
68fcecdc15 | ||
|
|
f08a7d9a8d | ||
|
|
f3debc08de | ||
|
|
018052b78d | ||
|
|
ade40806b6 | ||
|
|
2a5068c4bb | ||
|
|
b0e7f24be2 | ||
|
|
c0280fcfab | ||
|
|
68a5baa5c4 | ||
|
|
e49adafda9 | ||
|
|
ef7caf5519 | ||
|
|
926cce1eac | ||
|
|
f709380a97 | ||
|
|
fd6c224fc2 | ||
|
|
2025698d88 | ||
|
|
0ec90737d3 | ||
|
|
dd76fbf748 | ||
|
|
4ad3e92730 | ||
|
|
b90deae897 | ||
|
|
fbc1351031 | ||
|
|
953975a851 | ||
|
|
4c8f0b4df6 | ||
|
|
a9067bf5d9 | ||
|
|
9e24a781a6 | ||
|
|
46cd75cff4 | ||
|
|
8e0c95d6ea | ||
|
|
d6e574c877 | ||
|
|
4955dcd2c9 | ||
|
|
d5e5019811 | ||
|
|
21e5697073 | ||
|
|
44a864f50f | ||
|
|
2d4ad2737e | ||
|
|
58f2609fe7 | ||
|
|
8989c0e88c | ||
|
|
0438b65208 | ||
|
|
969267b661 | ||
|
|
4906800a22 | ||
|
|
3d7da7d971 | ||
|
|
781aa40e8c | ||
|
|
2821eff71f | ||
|
|
3288ba30ec | ||
|
|
2daf4d8ba4 | ||
|
|
759a9e4379 | ||
|
|
e10ebdeb5e | ||
|
|
f481d57ed1 | ||
|
|
16a73ed872 | ||
|
|
309a5ed25e | ||
|
|
1f0d2a7a66 | ||
|
|
314d3f5b9b | ||
|
|
34eb3af698 | ||
|
|
0ac0e03ff8 | ||
|
|
0f95439b61 | ||
|
|
0bda6296c0 | ||
|
|
6ca76b9eca | ||
|
|
63585af26d | ||
|
|
094d286b41 | ||
|
|
8b7a3e9781 | ||
|
|
ac6d6093ec | ||
|
|
add57ff26f | ||
|
|
a754d66844 | ||
|
|
fc83a7a36f | ||
|
|
7c99bbc185 | ||
|
|
ac12cce5f2 | ||
|
|
7fef5789de | ||
|
|
9570dcf20e | ||
|
|
05335fad84 | ||
|
|
f0ef6b35dd | ||
|
|
4ddff43813 | ||
|
|
dcc7a1f637 | ||
|
|
b169f46f5f | ||
|
|
ef480f6d10 | ||
|
|
01dbb96f1f | ||
|
|
b084ccb1f4 | ||
|
|
3c5b126c67 | ||
|
|
73355c9424 | ||
|
|
4532327f50 | ||
|
|
dc074b0262 | ||
|
|
86926178df | ||
|
|
1fdefe83de | ||
|
|
490989ac2a | ||
|
|
0c59a0d4d2 | ||
|
|
f40c24ce6f | ||
|
|
671ec1d658 | ||
|
|
f37a77a9f7 | ||
|
|
4719badc54 | ||
|
|
228ec191f6 | ||
|
|
34fc6d584f | ||
|
|
82ba51909e | ||
|
|
56961efe76 | ||
|
|
81f09e07f0 | ||
|
|
8cdd8526eb | ||
|
|
2f2516b998 | ||
|
|
3ba569354e | ||
|
|
104fe790fb | ||
|
|
ae24991432 | ||
|
|
8dde98d2a9 | ||
|
|
65e3a66750 | ||
|
|
1a1c668d62 | ||
|
|
33e18765b7 | ||
|
|
e3ccce5d5b | ||
|
|
e82fa93fb0 | ||
|
|
7a8a0302e0 | ||
|
|
33c73ef0e2 | ||
|
|
1bdfdcafad | ||
|
|
b117d2088a | ||
|
|
05ff080d78 | ||
|
|
53ade7fc53 | ||
|
|
02ec27dd2f | ||
|
|
33cfd4bc0e | ||
|
|
cc54e4d834 | ||
|
|
e4fc13aa92 | ||
|
|
1e1422a3dd | ||
|
|
16507adbe9 | ||
|
|
3f83c8e4a9 | ||
|
|
d00b2fe063 | ||
|
|
d3d9823459 | ||
|
|
a6ba312f6b | ||
|
|
46972e8769 | ||
|
|
d63c2a3ef9 | ||
|
|
163b703964 | ||
|
|
b60318c393 | ||
|
|
8646c3da6d | ||
|
|
3998f0fe36 | ||
|
|
7e9895e002 | ||
|
|
c00016cb69 | ||
|
|
2eb65defbc | ||
|
|
f9e79b3e40 | ||
|
|
cf87cc9bf0 | ||
|
|
8da440ea1f | ||
|
|
e6cfef06a7 | ||
|
|
2720ad6a38 | ||
|
|
f06191f290 | ||
|
|
59a8fdbf56 | ||
|
|
cd7435a4d5 | ||
|
|
9f33189c18 | ||
|
|
895e760fee | ||
|
|
d34cd68471 | ||
|
|
a8da035566 | ||
|
|
549f7ece61 | ||
|
|
87af6479d6 | ||
|
|
6ecb3f6ffb | ||
|
|
4f58827c96 | ||
|
|
ef197bf578 | ||
|
|
33f92bcda5 | ||
|
|
d21a11963f | ||
|
|
b84c36c91a | ||
|
|
22ed4c36fc | ||
|
|
62414e5b10 | ||
|
|
2569e3e3d8 | ||
|
|
8f9338e4d3 | ||
|
|
66abfc853d | ||
|
|
e47a3c28c9 | ||
|
|
3d43360e21 | ||
|
|
12b0705322 | ||
|
|
db20e21ccb | ||
|
|
72f4296e1e | ||
|
|
64c2555b4b | ||
|
|
3168725b00 | ||
|
|
071c2f60bf | ||
|
|
27cfabcc66 | ||
|
|
b02dca5877 | ||
|
|
ef731038a2 | ||
|
|
152d072242 | ||
|
|
d6e2bfe9ab | ||
|
|
9f5c126b7f | ||
|
|
b4694d637b | ||
|
|
3f9f5fcb90 | ||
|
|
97693fdace | ||
|
|
3537a233ca | ||
|
|
d34224c135 | ||
|
|
44c37a8435 | ||
|
|
17b2db64ef | ||
|
|
81ec5f9f7a | ||
|
|
ddd8977586 | ||
|
|
ceb1ca8416 | ||
|
|
24f5f0a3e3 | ||
|
|
484c08c455 | ||
|
|
ac3c986568 | ||
|
|
443f5a3615 | ||
|
|
be972cdb7e | ||
|
|
5968fd981c | ||
|
|
316da55000 | ||
|
|
b74229a3f4 | ||
|
|
15f906ad5a | ||
|
|
6afcf1312f | ||
|
|
c29c0e82dd | ||
|
|
bdb73b645c | ||
|
|
58e2058efc | ||
|
|
751d443546 | ||
|
|
0f52aac32d | ||
|
|
da6fe3a6fb | ||
|
|
c64cd45953 | ||
|
|
fe61f31c40 | ||
|
|
260b7c73a4 | ||
|
|
1c23718654 | ||
|
|
1ff686629b | ||
|
|
0086dc3e0f | ||
|
|
77716e8f0b | ||
|
|
ae8eb3e05e | ||
|
|
430ff9e984 | ||
|
|
7c06aa8e6e | ||
|
|
529291d2a2 | ||
|
|
2ecc49ddb3 | ||
|
|
c07e2bca53 | ||
|
|
9c16a88b63 | ||
|
|
6b2f3dd84f | ||
|
|
7fdf25f1e7 | ||
|
|
b2e4215ea8 | ||
|
|
7380dbe21a | ||
|
|
fecea10525 | ||
|
|
401dc3ea69 | ||
|
|
7d2635608d | ||
|
|
f5ab6f3ef7 | ||
|
|
a7c6be2bab | ||
|
|
fee00b737a | ||
|
|
c9ead60dd4 | ||
|
|
eb925c2ca1 | ||
|
|
f00b92274a | ||
|
|
e25f56fcae | ||
|
|
71bfbcc6ce | ||
|
|
50006ada37 | ||
|
|
4ab4a8825b | ||
|
|
befa5f3ded | ||
|
|
dc72e9fbfc | ||
|
|
6509fc7043 | ||
|
|
504cde0e8b | ||
|
|
f0ba7296d5 | ||
|
|
8dfb2fe69c | ||
|
|
2be140d291 | ||
|
|
ec296d98eb | ||
|
|
ab682567c6 | ||
|
|
c139b156ee | ||
|
|
a9daf47741 | ||
|
|
c6596b3e7d | ||
|
|
9bd5af03f9 | ||
|
|
6d107f6c2d | ||
|
|
e641c0b0e5 | ||
|
|
35d642e76f | ||
|
|
fea9083f7d | ||
|
|
83f5fa92e0 | ||
|
|
e667155cd5 | ||
|
|
087f6ef310 | ||
|
|
f7ee395eba | ||
|
|
0b820b6d3e | ||
|
|
3ef794a25e | ||
|
|
61ac1e5612 | ||
|
|
0fff5f9e4d | ||
|
|
9e5890d95e | ||
|
|
f82ed0d9d4 | ||
|
|
a8568d24f6 | ||
|
|
5e368aaced | ||
|
|
e8e25e08cc | ||
|
|
ed357f6bb0 | ||
|
|
61d52fc45f | ||
|
|
7fc3d4e217 | ||
|
|
7e02add8de | ||
|
|
db6ff3e0a4 | ||
|
|
d5dadb5175 | ||
|
|
d633f7746c | ||
|
|
dc3258d149 | ||
|
|
8be9cc72de | ||
|
|
b4f888ad15 | ||
|
|
adf3e7fed6 | ||
|
|
827a5210c2 | ||
|
|
b536aa5336 | ||
|
|
68f05ece85 | ||
|
|
171ba471a2 | ||
|
|
17b1413c05 | ||
|
|
b4c133ac77 | ||
|
|
7e203415c4 | ||
|
|
f9a3ff2a83 | ||
|
|
2bdde92d1b | ||
|
|
7cb2ca3e05 | ||
|
|
f44b1918af | ||
|
|
506d05b3ca | ||
|
|
57a3dfd4eb | ||
|
|
7ee86867ad | ||
|
|
37af83676e | ||
|
|
e0c2f537a3 | ||
|
|
501ea22ea2 | ||
|
|
e189abea4d | ||
|
|
efb54b123c | ||
|
|
84ce6589a3 | ||
|
|
f2955a841a | ||
|
|
7b70d91093 | ||
|
|
75c4741d9a | ||
|
|
44b1cdd801 | ||
|
|
fbed3fc8ab | ||
|
|
e43c0594d1 | ||
|
|
0043283881 | ||
|
|
e8e7cd6dea | ||
|
|
2927419b6d | ||
|
|
36e8690ad1 | ||
|
|
4038fb2c43 | ||
|
|
bc79ed11a3 | ||
|
|
f3c846f0b1 | ||
|
|
64d24591f3 | ||
|
|
05c05fec5c | ||
|
|
f84a86a3a3 | ||
|
|
36339e613f | ||
|
|
ba62004002 | ||
|
|
0a3913bdee | ||
|
|
c1aeefb0eb | ||
|
|
517ec9b266 | ||
|
|
8e11ae5efd | ||
|
|
17982013be | ||
|
|
85eadf6f93 | ||
|
|
1d564ff7b9 | ||
|
|
11fc6ac495 | ||
|
|
3055284664 | ||
|
|
e094a9854f | ||
|
|
47a3c1a015 | ||
|
|
467cb35648 | ||
|
|
9d0a75d032 | ||
|
|
42314a64b2 | ||
|
|
508b5f55a2 | ||
|
|
69d5a36f55 | ||
|
|
165edc9a90 | ||
|
|
a92248b4d9 | ||
|
|
c94e483c6e | ||
|
|
e522f85a72 | ||
|
|
607d72d7bb | ||
|
|
a3e9d68dc4 | ||
|
|
3f5a0056e4 | ||
|
|
8e2674f83e | ||
|
|
e7b2981bd6 | ||
|
|
6ef24bf4ed | ||
|
|
0a749c1245 | ||
|
|
f7d2346924 | ||
|
|
be8237da72 | ||
|
|
3ea37ba104 | ||
|
|
eb3b76dcf4 | ||
|
|
87e43a528e | ||
|
|
2f9908b54e | ||
|
|
4a4075b50f | ||
|
|
6408e1b876 | ||
|
|
923dad4e2e | ||
|
|
71f967d536 | ||
|
|
d81f187d88 | ||
|
|
a947dc6b9f | ||
|
|
60b4833eb2 | ||
|
|
db95a11e17 | ||
|
|
736fd43b46 | ||
|
|
7edafe8d78 | ||
|
|
2fd94c6575 | ||
|
|
dc284974b3 | ||
|
|
91b4d6c2c2 | ||
|
|
23a99f081a | ||
|
|
9a5d24544e | ||
|
|
d9d8f8de8a | ||
|
|
7ab12e7b4b | ||
|
|
cac89129af | ||
|
|
e62ef3a7f3 | ||
|
|
3629dd36f2 | ||
|
|
89ef256647 | ||
|
|
d8233a2c41 | ||
|
|
5d8f3786de | ||
|
|
4432bcb93c | ||
|
|
5bb4a7f95a | ||
|
|
3685599693 | ||
|
|
7b72cb4c71 | ||
|
|
1a5503a6f6 | ||
|
|
05515c59b8 | ||
|
|
fc8d65d4d1 | ||
|
|
cfed61c6ff | ||
|
|
d0d9adfd1a | ||
|
|
1a32748b8e | ||
|
|
6da34fc151 | ||
|
|
7ed89fdd5d | ||
|
|
875fb8a8c9 | ||
|
|
1dce1b2b35 | ||
|
|
daa5bd24dc | ||
|
|
c73698619d | ||
|
|
84d88f5040 | ||
|
|
c78fd097a1 | ||
|
|
a792538e29 | ||
|
|
c7be1d37e0 | ||
|
|
5be46de20a | ||
|
|
4ba0c5e3ba | ||
|
|
7a064c750a | ||
|
|
432d794626 | ||
|
|
b5241ff1f7 | ||
|
|
d6f94f2e19 | ||
|
|
14f97347d5 | ||
|
|
2e973bf654 | ||
|
|
8ec983b654 | ||
|
|
99ec41c7c7 | ||
|
|
b1b06bc125 | ||
|
|
70c858d847 | ||
|
|
f156716173 | ||
|
|
517013633d | ||
|
|
097df7894e | ||
|
|
f01a357f98 | ||
|
|
0681b523fe | ||
|
|
f7a55ec85b | ||
|
|
f34a3e2145 | ||
|
|
6bf3ae833a | ||
|
|
983e9b467d | ||
|
|
4cd0885023 | ||
|
|
ddac6c1963 | ||
|
|
41a134eb6b | ||
|
|
9a171464ff | ||
|
|
27f8c1f56c | ||
|
|
ecf7579d8e | ||
|
|
9d0c1c539c | ||
|
|
c0b7f85278 | ||
|
|
9174a4de91 | ||
|
|
7dabda88ff | ||
|
|
74066aa195 | ||
|
|
f7a1668c3f | ||
|
|
bef8628bb6 | ||
|
|
88b1d5c2a7 | ||
|
|
0c17744bc6 | ||
|
|
80c3cb70d2 | ||
|
|
a3eb53a649 | ||
|
|
57b773d009 | ||
|
|
a65504a2cb | ||
|
|
cc0ebcd13c | ||
|
|
f010ea8fad | ||
|
|
77e02b76b1 | ||
|
|
3e681abfdb | ||
|
|
172203ec16 | ||
|
|
82ea0dacd3 | ||
|
|
ddf53b5b43 | ||
|
|
14b699d660 | ||
|
|
6a5e04b35a | ||
|
|
e3cee80eba | ||
|
|
83a1989cee | ||
|
|
37af0714ae | ||
|
|
10aabce3a1 | ||
|
|
1c4551522d | ||
|
|
7c884fec55 | ||
|
|
3562edcb7a | ||
|
|
b7970bb631 | ||
|
|
c492f11466 | ||
|
|
ac48ac24ab | ||
|
|
40149ae32c | ||
|
|
44f91a3a86 | ||
|
|
b93c76ef1b | ||
|
|
57f6b41a47 | ||
|
|
9f7026bf9c | ||
|
|
dcea34118f | ||
|
|
a8132ef9f1 | ||
|
|
d3ae404f7a | ||
|
|
e0cd3610a6 | ||
|
|
a5919ac917 | ||
|
|
1b07c6f5b5 | ||
|
|
80d5be956d | ||
|
|
e93697b162 | ||
|
|
bd4c8776a5 | ||
|
|
5be8d7b7c0 | ||
|
|
608b1af24f | ||
|
|
1ac85e253f | ||
|
|
1c8d7f5be9 | ||
|
|
84f0003bef | ||
|
|
13a015cd5f | ||
|
|
7b938f9458 | ||
|
|
a287789d87 | ||
|
|
aba904af3c | ||
|
|
fd7de65e86 | ||
|
|
372712745c | ||
|
|
64b679a002 | ||
|
|
cee1831fb2 | ||
|
|
000d0064ad | ||
|
|
7b99dffb3e | ||
|
|
40b3ecce16 | ||
|
|
82cec1d744 | ||
|
|
61a93dbc30 | ||
|
|
9e7075c7e5 | ||
|
|
f12f209a0d | ||
|
|
0f9b595ce7 | ||
|
|
e3fa3fdd61 | ||
|
|
f1e9296299 | ||
|
|
d45801bd50 | ||
|
|
d6a0a17d3f | ||
|
|
6e13ed2c85 | ||
|
|
27b2d79a65 | ||
|
|
036acf3c85 | ||
|
|
1ea94b02cd | ||
|
|
90aaf2bad6 | ||
|
|
6b3149fbce | ||
|
|
c74a56206c | ||
|
|
88807a05a1 | ||
|
|
eb47443bba | ||
|
|
d64eb762b4 | ||
|
|
e61ac8814d | ||
|
|
01f790020e | ||
|
|
d726da5d73 | ||
|
|
0dcc6ef4b1 | ||
|
|
ed353248e0 | ||
|
|
f2e1db491f | ||
|
|
df1fc2fe54 | ||
|
|
1fd696d787 | ||
|
|
8c7c04c797 | ||
|
|
9e07b03b78 | ||
|
|
a78d02617f | ||
|
|
b7d4cdd51c | ||
|
|
41f8434d35 | ||
|
|
ff60b3c891 | ||
|
|
5fb27151b3 | ||
|
|
3ec58659f5 | ||
|
|
5d91bbf32f | ||
|
|
6f70499105 | ||
|
|
07cac3a03f | ||
|
|
84bbfe4413 | ||
|
|
75a8f7f351 | ||
|
|
9ab9d6b2d0 | ||
|
|
fef83c8aa7 | ||
|
|
dab88ebb98 | ||
|
|
ed9e7ad72f | ||
|
|
d539f7723e | ||
|
|
71d2345e66 | ||
|
|
b1f32ab0f5 | ||
|
|
dbfacdfd28 | ||
|
|
5dd30131e3 | ||
|
|
c4f78df149 | ||
|
|
831e0f7d1b | ||
|
|
ee5719cb55 | ||
|
|
694d3224b5 | ||
|
|
756249c3ad | ||
|
|
4a66715923 | ||
|
|
f0bfca8588 | ||
|
|
950620de6e | ||
|
|
b13d2106d4 | ||
|
|
35f2c85a19 | ||
|
|
b5ac254259 | ||
|
|
0683cd2326 | ||
|
|
2029806a5f | ||
|
|
4cd98ef4ac | ||
|
|
ae91686d4c | ||
|
|
4471843f8b | ||
|
|
881502c970 | ||
|
|
f7949cc404 | ||
|
|
845d5b5707 | ||
|
|
2a9dc72721 | ||
|
|
d209ce97ea | ||
|
|
f1e35532b9 | ||
|
|
b466ac818c | ||
|
|
50b6a8dd9b | ||
|
|
6dbd020591 | ||
|
|
94bb3c9430 | ||
|
|
73d3eedcdc | ||
|
|
3f52f79210 | ||
|
|
7a070b3e7f | ||
|
|
e16db1823d | ||
|
|
20b8c0da7d | ||
|
|
158a4171d2 | ||
|
|
ccf5f6a3d8 | ||
|
|
8e114c555f | ||
|
|
e8f20938cd | ||
|
|
ac40fd93b7 | ||
|
|
b5a89b51db | ||
|
|
a7939a3a19 | ||
|
|
96c6baa6c9 | ||
|
|
67c510cbd8 | ||
|
|
57d65cf086 | ||
|
|
5c57ae0edc | ||
|
|
236d7c1e35 | ||
|
|
2c9a8a33a4 | ||
|
|
0bce0e2bd7 | ||
|
|
194638f759 | ||
|
|
6c2e31e3cb | ||
|
|
a5106f4640 | ||
|
|
b4652f6d2d | ||
|
|
5195519ef1 | ||
|
|
c04cbc2929 | ||
|
|
43d8fc5207 | ||
|
|
1843f387ff | ||
|
|
72a1697d65 | ||
|
|
fe9311325b | ||
|
|
a82e379f9b | ||
|
|
ee998232f7 | ||
|
|
a8845514c6 | ||
|
|
9ee6e2ee25 | ||
|
|
620a0dba25 | ||
|
|
907d80943e | ||
|
|
bf3454d9a4 | ||
|
|
bc3b1ad3d2 | ||
|
|
25fb9bdae0 | ||
|
|
67706dc186 | ||
|
|
78b453249a | ||
|
|
60a059078c | ||
|
|
0c20e49831 | ||
|
|
aec937aa97 | ||
|
|
e9ee5c6911 | ||
|
|
685f3cee10 | ||
|
|
2f37e42b38 | ||
|
|
1fd51d23f3 | ||
|
|
a03cf83d58 | ||
|
|
aabf4fcbb0 | ||
|
|
3b8e0d8180 | ||
|
|
0cfad82933 | ||
|
|
0ec81e5832 | ||
|
|
250a535fc3 | ||
|
|
534b679d63 | ||
|
|
491a33794f | ||
|
|
57625b9680 | ||
|
|
ad10e019fe | ||
|
|
9730ae581b | ||
|
|
411c570b67 | ||
|
|
20fd03bbdb | ||
|
|
19415cd0a1 | ||
|
|
84233868d6 | ||
|
|
74f3a15eb2 | ||
|
|
621cbb3d51 | ||
|
|
31940441ed | ||
|
|
cd16902635 | ||
|
|
da271c326a | ||
|
|
27828943f4 | ||
|
|
2b7d1ab7c9 | ||
|
|
0a0989e5f4 | ||
|
|
f5d867cf1a | ||
|
|
ec4387112e | ||
|
|
06a2a18c06 | ||
|
|
d92f6c7204 | ||
|
|
c2209908a0 | ||
|
|
fe9affcefe | ||
|
|
f8efa20b7c | ||
|
|
1436b7bba6 | ||
|
|
41c1125388 | ||
|
|
1a8f38cb4b | ||
|
|
4eeac9f830 | ||
|
|
fe4a324a04 | ||
|
|
a548497767 | ||
|
|
50cf49568d | ||
|
|
c811b95129 | ||
|
|
f672ff553a | ||
|
|
295bbda921 | ||
|
|
a1d9b25f0b | ||
|
|
2d8c3c8175 | ||
|
|
d039fef4f1 | ||
|
|
3434db279e | ||
|
|
94edeefee0 | ||
|
|
40d70b0a13 | ||
|
|
584f5943b6 | ||
|
|
dafb71e75c | ||
|
|
70cb3ab6d2 | ||
|
|
20dbc7f5b7 | ||
|
|
76809de2df | ||
|
|
6063de2095 | ||
|
|
928b3397d2 | ||
|
|
6b0aaea773 | ||
|
|
8212d24d34 | ||
|
|
9f4a798d67 | ||
|
|
47b7d475c8 | ||
|
|
efee1653e1 | ||
|
|
1a30743c0a | ||
|
|
cea2993665 | ||
|
|
c8dc8ed630 | ||
|
|
8fc392681a | ||
|
|
7101cdf183 | ||
|
|
38a2831779 | ||
|
|
829d8a3152 | ||
|
|
9182d170de | ||
|
|
0108799718 | ||
|
|
0481281680 | ||
|
|
f8e0ab5b56 | ||
|
|
da79f47416 | ||
|
|
88b8a8001f | ||
|
|
eda7751eb9 | ||
|
|
7254fc71fb | ||
|
|
a357489a55 | ||
|
|
d1e583d252 | ||
|
|
2d9d240a5a | ||
|
|
6c7f7f952f | ||
|
|
421cae6716 | ||
|
|
6953eddea6 | ||
|
|
1b79c37fd2 | ||
|
|
7c15a8272b | ||
|
|
ccacc7f7db | ||
|
|
264ed5a943 | ||
|
|
79e39021a6 | ||
|
|
88246b26fe | ||
|
|
4b4cc3b500 | ||
|
|
d5703fe522 | ||
|
|
3b5323cea0 | ||
|
|
c5d004aa48 | ||
|
|
d48baab44c | ||
|
|
02bf673105 | ||
|
|
46e0adee15 | ||
|
|
4a7bff0d37 | ||
|
|
ba7a518b4d | ||
|
|
403d7fdc2a | ||
|
|
fb94934d1b | ||
|
|
d9f9e89b19 | ||
|
|
797f26e461 | ||
|
|
2cd0a16028 | ||
|
|
0585ab828c | ||
|
|
5c3bcaa0ce | ||
|
|
b16a299b16 | ||
|
|
5f27d1e484 | ||
|
|
dfab86a4ad | ||
|
|
a4c945803c | ||
|
|
f5a5d3172f | ||
|
|
a2efe1a928 | ||
|
|
f2c9de4b36 | ||
|
|
3be82e1d1f | ||
|
|
80070109db | ||
|
|
e683154f02 | ||
|
|
97b5b6f4ca | ||
|
|
c92b881d4a | ||
|
|
838032c8d6 | ||
|
|
7f672f709b | ||
|
|
fe37d6080a | ||
|
|
d545656176 | ||
|
|
d0b843c103 | ||
|
|
a7b6a28c42 | ||
|
|
79138692cb | ||
|
|
9a1b95e63e | ||
|
|
d7adbb3a01 | ||
|
|
c363f5a1b7 | ||
|
|
9092599929 | ||
|
|
be5dad0195 | ||
|
|
d2cb5c1e93 | ||
|
|
5d051e127f | ||
|
|
475460ff84 | ||
|
|
1b16b903a0 | ||
|
|
449912e655 | ||
|
|
06efa2da58 | ||
|
|
83c833e89c | ||
|
|
6f2a087ef8 | ||
|
|
f1bc8d2b13 | ||
|
|
a94dc82c1f | ||
|
|
bc62236351 | ||
|
|
3789845a36 | ||
|
|
3ab18392b3 | ||
|
|
ef6494f4c3 |
1
.clang-format-ignore
Normal file
|
|
@ -0,0 +1 @@
|
|||
CMakePresets.json
|
||||
19
.clang-tidy
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
Checks:
|
||||
- '-*'
|
||||
- 'bugprone-*'
|
||||
- 'clang-analyzer-*'
|
||||
- 'cppcoreguidelines-*'
|
||||
- 'misc-*'
|
||||
- 'modernize-*'
|
||||
- 'performance-*'
|
||||
- '-bugprone-easily-swappable-parameters'
|
||||
- '-cppcoreguidelines-avoid-do-while'
|
||||
- '-cppcoreguidelines-avoid-non-const-global-variables'
|
||||
- '-cppcoreguidelines-pro-type-reinterpret-cast'
|
||||
- '-cppcoreguidelines-pro-type-union-access'
|
||||
- '-misc-include-cleaner'
|
||||
- '-misc-non-private-member-variables-in-classes'
|
||||
- '-misc-use-anonymous-namespace'
|
||||
- '-modernize-return-braced-init-list'
|
||||
- '-modernize-use-trailing-return-type'
|
||||
FormatStyle: 'file'
|
||||
252
.github/workflows/ci.yml
vendored
|
|
@ -11,7 +11,7 @@ on:
|
|||
|
||||
concurrency:
|
||||
# Cancel in-progress jobs for the same pull request
|
||||
group: ${{ github.head_ref || github.run_id }}
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
|
|
@ -20,61 +20,130 @@ jobs:
|
|||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- name: win64_msvc2022
|
||||
- name: windows_msvc2022_x64
|
||||
os: windows-2022
|
||||
build_type: Release
|
||||
env_cc: ''
|
||||
env_cxx: ''
|
||||
compiler: msvc
|
||||
cppflags: ''
|
||||
ldflags: ''
|
||||
msvc_arch: x64
|
||||
msvc_version: 2022
|
||||
qt_version: 6.7.2
|
||||
qt_arch_aqt: win64_msvc2019_64
|
||||
qt_arch_dir: msvc2019_64
|
||||
qt_version: 6.9.2
|
||||
qt_arch_aqt: win64_msvc2022_64
|
||||
qt_arch_dir: msvc2022_64
|
||||
qt_modules: qtimageformats qtmultimedia qtpositioning qtserialport
|
||||
qt_tools: ''
|
||||
conan_arch: x86_64
|
||||
conan_compiler: Visual Studio
|
||||
conan_compiler_version: 17
|
||||
conan_compiler_runtime: --settings compiler.runtime=MD
|
||||
conan_package_manager: ''
|
||||
conan_profile: scwx-windows_msvc2022_x64
|
||||
appimage_arch: ''
|
||||
artifact_suffix: windows-x64
|
||||
- name: linux64_gcc
|
||||
- name: linux_gcc_x64
|
||||
os: ubuntu-22.04
|
||||
build_type: Release
|
||||
env_cc: gcc-11
|
||||
env_cxx: g++-11
|
||||
compiler: gcc
|
||||
qt_version: 6.7.2
|
||||
cppflags: ''
|
||||
ldflags: ''
|
||||
qt_version: 6.9.2
|
||||
qt_arch_aqt: linux_gcc_64
|
||||
qt_arch_dir: gcc_64
|
||||
qt_modules: qtimageformats qtmultimedia qtpositioning qtserialport
|
||||
qt_tools: ''
|
||||
conan_arch: x86_64
|
||||
conan_compiler: gcc
|
||||
conan_compiler_version: 11
|
||||
conan_compiler_runtime: ''
|
||||
conan_package_manager: --conf tools.system.package_manager:mode=install --conf tools.system.package_manager:sudo=True
|
||||
conan_profile: scwx-linux_gcc-11
|
||||
appimage_arch: x86_64
|
||||
artifact_suffix: linux-x64
|
||||
compiler_packages: ''
|
||||
- name: linux_clang_x64
|
||||
os: ubuntu-24.04
|
||||
build_type: Release
|
||||
env_cc: clang-17
|
||||
env_cxx: clang++-17
|
||||
compiler: clang
|
||||
cppflags: ''
|
||||
ldflags: ''
|
||||
qt_version: 6.9.2
|
||||
qt_arch_aqt: linux_gcc_64
|
||||
qt_arch_dir: gcc_64
|
||||
qt_modules: qtimageformats qtmultimedia qtpositioning qtserialport
|
||||
qt_tools: ''
|
||||
conan_package_manager: --conf tools.system.package_manager:mode=install --conf tools.system.package_manager:sudo=True
|
||||
conan_profile: scwx-linux_clang-17
|
||||
appimage_arch: x86_64
|
||||
artifact_suffix: linux-clang-x64
|
||||
compiler_packages: clang-17
|
||||
- name: linux_gcc_arm64
|
||||
os: ubuntu-24.04-arm
|
||||
build_type: Release
|
||||
env_cc: gcc-11
|
||||
env_cxx: g++-11
|
||||
compiler: gcc
|
||||
cppflags: ''
|
||||
ldflags: ''
|
||||
qt_version: 6.9.2
|
||||
qt_arch_aqt: linux_gcc_arm64
|
||||
qt_arch_dir: gcc_arm64
|
||||
qt_modules: qtimageformats qtmultimedia qtpositioning qtserialport
|
||||
qt_tools: ''
|
||||
conan_package_manager: --conf tools.system.package_manager:mode=install --conf tools.system.package_manager:sudo=True
|
||||
conan_profile: scwx-linux_gcc-11_armv8
|
||||
appimage_arch: aarch64
|
||||
artifact_suffix: linux-arm64
|
||||
compiler_packages: g++-11
|
||||
- name: macos_clang18_x64
|
||||
os: macos-13
|
||||
build_type: Release
|
||||
env_cc: clang
|
||||
env_cxx: clang++
|
||||
compiler: clang
|
||||
qt_version: 6.9.2
|
||||
qt_arch_aqt: clang_64
|
||||
qt_arch_dir: macos
|
||||
qt_modules: qtimageformats qtmultimedia qtpositioning qtserialport
|
||||
qt_tools: ''
|
||||
conan_package_manager: ''
|
||||
conan_profile: scwx-macos_clang-18
|
||||
appimage_arch: ''
|
||||
artifact_suffix: macos-x64
|
||||
- name: macos_clang18_arm64
|
||||
os: macos-14
|
||||
build_type: Release
|
||||
env_cc: clang
|
||||
env_cxx: clang++
|
||||
compiler: clang
|
||||
qt_version: 6.9.2
|
||||
qt_arch_aqt: clang_64
|
||||
qt_arch_dir: macos
|
||||
qt_modules: qtimageformats qtmultimedia qtpositioning qtserialport
|
||||
qt_tools: ''
|
||||
conan_package_manager: ''
|
||||
conan_profile: scwx-macos_clang-18_armv8
|
||||
appimage_arch: ''
|
||||
artifact_suffix: macos-arm64
|
||||
name: ${{ matrix.name }}
|
||||
env:
|
||||
CC: ${{ matrix.env_cc }}
|
||||
CXX: ${{ matrix.env_cxx }}
|
||||
SCWX_VERSION: v0.4.5
|
||||
SCWX_VERSION: v0.5.1
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
- name: Setup
|
||||
run: git config --global core.longpaths true
|
||||
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
path: source
|
||||
submodules: recursive
|
||||
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v3
|
||||
uses: jdpurcell/install-qt-action@v5
|
||||
env:
|
||||
AQT_CONFIG: ${{ github.workspace }}/source/tools/aqt-settings.ini
|
||||
with:
|
||||
version: ${{ matrix.qt_version }}
|
||||
arch: ${{ matrix.qt_arch_aqt }}
|
||||
|
|
@ -89,50 +158,79 @@ jobs:
|
|||
vsversion: ${{ matrix.msvc_version }}
|
||||
|
||||
- name: Setup Ubuntu Environment
|
||||
if: matrix.os == 'ubuntu-22.04'
|
||||
if: ${{ startsWith(matrix.os, 'ubuntu') }}
|
||||
shell: bash
|
||||
run: |
|
||||
sudo apt-get install doxygen \
|
||||
libfuse2 \
|
||||
ninja-build
|
||||
ninja-build \
|
||||
wayland-protocols \
|
||||
libwayland-dev \
|
||||
libwayland-egl-backend-dev \
|
||||
flatpak \
|
||||
flatpak-builder \
|
||||
${{ matrix.compiler_packages }}
|
||||
|
||||
- name: Setup macOS Environment
|
||||
if: ${{ startsWith(matrix.os, 'macos') }}
|
||||
shell: bash
|
||||
run: |
|
||||
brew install llvm@18
|
||||
LLVM_PATH=$(brew --prefix llvm@18)
|
||||
echo "CC=${LLVM_PATH}/bin/clang" >> $GITHUB_ENV
|
||||
echo "CXX=${LLVM_PATH}/bin/clang++" >> $GITHUB_ENV
|
||||
echo "CPPFLAGS=-I${LLVM_PATH}/include" >> $GITHUB_ENV
|
||||
echo "LDFLAGS=-L${LLVM_PATH}/lib -L${LLVM_PATH}/lib/c++" >> $GITHUB_ENV
|
||||
|
||||
- name: Setup Python Environment
|
||||
shell: pwsh
|
||||
run: |
|
||||
pip install geopandas `
|
||||
GitPython
|
||||
GitPython `
|
||||
conan
|
||||
|
||||
- name: Cache Conan Packages
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.conan2
|
||||
key: build-${{ matrix.conan_profile }}-${{ hashFiles('./source/conanfile.py', './source/tools/conan/profiles/*') }}
|
||||
|
||||
- name: Install Conan Packages
|
||||
shell: pwsh
|
||||
run: |
|
||||
pip install "conan<2.0"
|
||||
conan profile new default --detect
|
||||
conan install ./source/ `
|
||||
conan config install `
|
||||
./source/tools/conan/profiles/${{ matrix.conan_profile }} `
|
||||
-tf profiles
|
||||
mkdir build
|
||||
cd build
|
||||
mkdir conan
|
||||
conan install ../source/ `
|
||||
--remote conancenter `
|
||||
--build missing `
|
||||
--settings arch=${{ matrix.conan_arch }} `
|
||||
--settings build_type=${{ matrix.build_type }} `
|
||||
--settings compiler="${{ matrix.conan_compiler }}" `
|
||||
--settings compiler.version=${{ matrix.conan_compiler_version }} `
|
||||
${{ matrix.conan_compiler_runtime }} `
|
||||
--profile:all ${{ matrix.conan_profile }} `
|
||||
--settings:all build_type=${{ matrix.build_type }} `
|
||||
--output-folder ./conan/ `
|
||||
${{ matrix.conan_package_manager }}
|
||||
|
||||
- name: Build Supercell Wx
|
||||
shell: pwsh
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ../source/ `
|
||||
-G Ninja `
|
||||
-DCMAKE_BUILD_TYPE="${{ matrix.build_type }}" `
|
||||
-DCMAKE_INSTALL_PREFIX="${{ github.workspace }}/supercell-wx"
|
||||
-DCMAKE_PROJECT_TOP_LEVEL_INCLUDES="${{ github.workspace }}/source/external/cmake-conan/conan_provider.cmake" `
|
||||
-DCMAKE_INSTALL_PREFIX="${{ github.workspace }}/supercell-wx" `
|
||||
-DCONAN_HOST_PROFILE="${{ matrix.conan_profile }}" `
|
||||
-DCONAN_BUILD_PROFILE="${{ matrix.conan_profile }}"
|
||||
ninja supercell-wx wxtest
|
||||
|
||||
- name: Separate Debug Symbols (Linux)
|
||||
if: matrix.os == 'ubuntu-22.04'
|
||||
if: ${{ startsWith(matrix.os, 'ubuntu') }}
|
||||
shell: bash
|
||||
run: |
|
||||
cd build/
|
||||
cd Release/
|
||||
cd bin/
|
||||
objcopy --only-keep-debug supercell-wx supercell-wx.debug
|
||||
objcopy --strip-debug --strip-unneeded supercell-wx
|
||||
|
|
@ -148,7 +246,7 @@ jobs:
|
|||
cmake --install . --component supercell-wx
|
||||
|
||||
- name: Collect Artifacts
|
||||
if: matrix.os == 'ubuntu-22.04'
|
||||
if: ${{ startsWith(matrix.os, 'ubuntu') }}
|
||||
shell: bash
|
||||
run: |
|
||||
pushd supercell-wx/
|
||||
|
|
@ -161,6 +259,8 @@ jobs:
|
|||
cd plugins/
|
||||
mkdir -p sqldrivers/
|
||||
cp "${RUNNER_WORKSPACE}/Qt/${{ matrix.qt_version }}/${{ matrix.qt_arch_dir }}/plugins/sqldrivers/libqsqlite.so" sqldrivers/
|
||||
mkdir -p platforms/
|
||||
cp ${RUNNER_WORKSPACE}/Qt/${{ matrix.qt_version }}/${{ matrix.qt_arch_dir }}/plugins/platforms/libqwayland* platforms/
|
||||
cd ..
|
||||
popd
|
||||
tar -czf supercell-wx-${{ matrix.artifact_suffix }}.tar.gz supercell-wx/
|
||||
|
|
@ -177,23 +277,23 @@ jobs:
|
|||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: supercell-wx-debug-${{ matrix.artifact_suffix }}
|
||||
path: ${{ github.workspace }}/build/bin/*.pdb
|
||||
path: ${{ github.workspace }}/build/Release/bin/*.pdb
|
||||
|
||||
- name: Upload Artifacts (Linux)
|
||||
if: matrix.os == 'ubuntu-22.04'
|
||||
if: ${{ startsWith(matrix.os, 'ubuntu') }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: supercell-wx-${{ matrix.artifact_suffix }}
|
||||
path: ${{ github.workspace }}/supercell-wx-${{ matrix.artifact_suffix }}.tar.gz
|
||||
|
||||
- name: Upload Debug Artifacts (Linux)
|
||||
if: matrix.os == 'ubuntu-22.04'
|
||||
if: ${{ startsWith(matrix.os, 'ubuntu') }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: supercell-wx-debug-${{ matrix.artifact_suffix }}
|
||||
path: |
|
||||
${{ github.workspace }}/build/bin/*.debug
|
||||
${{ github.workspace }}/build/lib/*.debug
|
||||
${{ github.workspace }}/build/Release/bin/*.debug
|
||||
${{ github.workspace }}/build/Release/lib/*.debug
|
||||
|
||||
- name: Build Installer (Windows)
|
||||
if: matrix.os == 'windows-2022'
|
||||
|
|
@ -210,42 +310,90 @@ jobs:
|
|||
path: ${{ github.workspace }}/build/supercell-wx-*.msi*
|
||||
|
||||
- name: Build AppImage (Linux)
|
||||
if: matrix.os == 'ubuntu-22.04'
|
||||
if: ${{ startsWith(matrix.os, 'ubuntu') }}
|
||||
env:
|
||||
APPIMAGE_DIR: ${{ github.workspace }}/supercell-wx/
|
||||
LDAI_UPDATE_INFORMATION: gh-releases-zsync|dpaulat|supercell-wx|latest|*x86_64.AppImage.zsync
|
||||
LDAI_OUTPUT: supercell-wx-${{ env.SCWX_VERSION }}-x86_64.AppImage
|
||||
INSTALL_DIR: ${{ github.workspace }}/supercell-wx/
|
||||
APPIMAGE_DIR: ${{ github.workspace }}/supercell-wx-appimage/
|
||||
LDAI_UPDATE_INFORMATION: gh-releases-zsync|dpaulat|supercell-wx|latest|*${{ matrix.appimage_arch }}.AppImage.zsync
|
||||
LDAI_OUTPUT: supercell-wx-${{ env.SCWX_VERSION }}-${{ matrix.appimage_arch }}.AppImage
|
||||
LINUXDEPLOY_OUTPUT_APP_NAME: supercell-wx
|
||||
LINUXDEPLOY_OUTPUT_VERSION: ${{ env.SCWX_VERSION }}
|
||||
shell: bash
|
||||
run: |
|
||||
wget https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage
|
||||
chmod +x linuxdeploy-x86_64.AppImage
|
||||
wget https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-${{ matrix.appimage_arch }}.AppImage
|
||||
chmod +x linuxdeploy-${{ matrix.appimage_arch }}.AppImage
|
||||
cp "${{ github.workspace }}/source/scwx-qt/res/icons/scwx-256.png" supercell-wx.png
|
||||
cp "${{ github.workspace }}/source/scwx-qt/res/linux/supercell-wx.desktop" .
|
||||
cp -r "${{ env.INSTALL_DIR }}" "${{ env.APPIMAGE_DIR }}"
|
||||
pushd "${{ env.APPIMAGE_DIR }}"
|
||||
mkdir -p usr/
|
||||
mv bin/ usr/
|
||||
mv lib/ usr/
|
||||
mv plugins/ usr/
|
||||
popd
|
||||
./linuxdeploy-x86_64.AppImage --appdir ${{ env.APPIMAGE_DIR }} -i supercell-wx.png -d supercell-wx.desktop
|
||||
./linuxdeploy-x86_64.AppImage --appdir ${{ env.APPIMAGE_DIR }} --output appimage
|
||||
rm -f linuxdeploy-x86_64.AppImage
|
||||
./linuxdeploy-${{ matrix.appimage_arch }}.AppImage --appdir ${{ env.APPIMAGE_DIR }} -i supercell-wx.png -d supercell-wx.desktop
|
||||
./linuxdeploy-${{ matrix.appimage_arch }}.AppImage --appdir ${{ env.APPIMAGE_DIR }} --output appimage
|
||||
rm -f linuxdeploy-${{ matrix.appimage_arch }}.AppImage
|
||||
|
||||
- name: Upload AppImage (Linux)
|
||||
if: matrix.os == 'ubuntu-22.04'
|
||||
if: ${{ startsWith(matrix.os, 'ubuntu') }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: supercell-wx-appimage-x64
|
||||
path: ${{ github.workspace }}/*-x86_64.AppImage*
|
||||
name: supercell-wx-appimage-${{ matrix.artifact_suffix }}
|
||||
path: ${{ github.workspace }}/*-${{ matrix.appimage_arch }}.AppImage*
|
||||
|
||||
- name: Build FlatPak (Linux)
|
||||
if: ${{ startsWith(matrix.os, 'ubuntu') }}
|
||||
env:
|
||||
INSTALL_DIR: ${{ github.workspace }}/supercell-wx/
|
||||
FLATPAK_DIR: ${{ github.workspace }}/supercell-wx-flatpak/
|
||||
shell: bash
|
||||
run: |
|
||||
cp -r ${{ env.INSTALL_DIR }} ${{ env.FLATPAK_DIR }}
|
||||
# Copy krb5 libraries to flatpak
|
||||
cp /usr/lib/*/libkrb5.so* \
|
||||
/usr/lib/*/libkrb5support.so* \
|
||||
/usr/lib/*/libgssapi_krb5.so* \
|
||||
/usr/lib/*/libk5crypto.so* \
|
||||
/usr/lib/*/libkeyutils.so* \
|
||||
${{ env.FLATPAK_DIR }}/lib
|
||||
|
||||
flatpak remote-add --if-not-exists --user flathub https://dl.flathub.org/repo/flathub.flatpakrepo
|
||||
flatpak-builder --force-clean \
|
||||
--user \
|
||||
--install-deps-from=flathub \
|
||||
--repo=flatpak-repo \
|
||||
--install flatpak-build \
|
||||
${{ github.workspace }}/source/tools/net.supercellwx.app.yml
|
||||
flatpak build-bundle flatpak-repo supercell-wx.flatpak net.supercellwx.app
|
||||
|
||||
- name: Upload FlatPak (Linux)
|
||||
if: ${{ startsWith(matrix.os, 'ubuntu') }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: supercell-wx-flatpak-${{ matrix.artifact_suffix }}
|
||||
path: ${{ github.workspace }}/supercell-wx.flatpak
|
||||
|
||||
- name: Build Disk Image (macOS)
|
||||
if: ${{ startsWith(matrix.os, 'macos') }}
|
||||
shell: pwsh
|
||||
run: |
|
||||
cd build
|
||||
cpack
|
||||
|
||||
- name: Upload Disk Image (macOS)
|
||||
if: ${{ startsWith(matrix.os, 'macos') }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: supercell-wx-${{ matrix.artifact_suffix }}
|
||||
path: ${{ github.workspace }}/build/supercell-wx-*.dmg*
|
||||
|
||||
- name: Test Supercell Wx
|
||||
working-directory: ${{ github.workspace }}/build
|
||||
env:
|
||||
MAPBOX_API_KEY: ${{ secrets.MAPBOX_API_KEY }}
|
||||
MAPTILER_API_KEY: ${{ secrets.MAPTILER_API_KEY }}
|
||||
run: ctest -C ${{ matrix.build_type }} --exclude-regex test_mln.*
|
||||
run: ctest -C ${{ matrix.build_type }} --exclude-regex "test_mln.*|NtpClient.*|UpdateManager.*"
|
||||
|
||||
- name: Upload Test Logs
|
||||
if: ${{ !cancelled() }}
|
||||
|
|
|
|||
42
.github/workflows/clang-format-check.yml
vendored
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
name: clang-format-check
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
branches:
|
||||
- 'develop'
|
||||
|
||||
concurrency:
|
||||
# Cancel in-progress jobs for the same pull request
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
format:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
submodules: false
|
||||
|
||||
- name: Update References
|
||||
shell: bash
|
||||
run: |
|
||||
git fetch origin develop
|
||||
|
||||
- name: Setup Ubuntu Environment
|
||||
shell: bash
|
||||
run: |
|
||||
sudo apt-get install clang-format-19
|
||||
sudo rm -f /usr/bin/clang-format
|
||||
sudo ln -s /usr/bin/clang-format-19 /usr/bin/clang-format
|
||||
|
||||
- name: Check Formatting
|
||||
shell: bash
|
||||
run: |
|
||||
MERGE_BASE=$(git merge-base origin/develop ${{ github.event.pull_request.head.sha || github.ref }})
|
||||
echo "Comparing against ${MERGE_BASE}"
|
||||
git clang-format-19 --diff --style=file -v ${MERGE_BASE}
|
||||
21
.github/workflows/clang-tidy-comments.yml
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
name: Post clang-tidy Review Comments
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: ["clang-tidy-review"]
|
||||
types:
|
||||
- completed
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event.workflow_run.conclusion != 'cancelled' }}
|
||||
|
||||
steps:
|
||||
- name: Post Comments
|
||||
uses: ZedThree/clang-tidy-review/post@v0.21.0
|
||||
with:
|
||||
lgtm_comment_body: ''
|
||||
annotations: false
|
||||
max_comments: 25
|
||||
num_comments_as_exitcode: false
|
||||
152
.github/workflows/clang-tidy-review.yml
vendored
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
name: clang-tidy-review
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- 'develop'
|
||||
|
||||
concurrency:
|
||||
# Cancel in-progress jobs for the same pull request
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- name: linux_clang-tidy_x64
|
||||
os: ubuntu-24.04
|
||||
build_type: Release
|
||||
env_cc: clang-18
|
||||
env_cxx: clang++-18
|
||||
qt_version: 6.9.2
|
||||
qt_arch_aqt: linux_gcc_64
|
||||
qt_modules: qtimageformats qtmultimedia qtpositioning qtserialport
|
||||
qt_tools: ''
|
||||
conan_package_manager: --conf tools.system.package_manager:mode=install --conf tools.system.package_manager:sudo=True
|
||||
conan_profile: scwx-linux_clang-18
|
||||
compiler_packages: clang-18 clang-tidy-18
|
||||
clang_tidy_binary: clang-tidy-18
|
||||
name: ${{ matrix.name }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
CC: ${{ matrix.env_cc }}
|
||||
CXX: ${{ matrix.env_cxx }}
|
||||
steps:
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
path: source
|
||||
submodules: recursive
|
||||
|
||||
- name: Checkout clang-tidy-review Repository
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
repository: ZedThree/clang-tidy-review
|
||||
ref: v0.20.1
|
||||
path: clang-tidy-review
|
||||
|
||||
- name: Install Qt
|
||||
uses: jdpurcell/install-qt-action@v5
|
||||
env:
|
||||
AQT_CONFIG: ${{ github.workspace }}/source/tools/aqt-settings.ini
|
||||
with:
|
||||
version: ${{ matrix.qt_version }}
|
||||
arch: ${{ matrix.qt_arch_aqt }}
|
||||
modules: ${{ matrix.qt_modules }}
|
||||
tools: ${{ matrix.qt_tools }}
|
||||
|
||||
- name: Setup Ubuntu Environment
|
||||
if: ${{ startsWith(matrix.os, 'ubuntu') }}
|
||||
shell: bash
|
||||
run: |
|
||||
sudo apt-get install doxygen \
|
||||
libfuse2 \
|
||||
ninja-build \
|
||||
wayland-protocols \
|
||||
libwayland-dev \
|
||||
libwayland-egl-backend-dev \
|
||||
${{ matrix.compiler_packages }}
|
||||
|
||||
- name: Setup Python Environment
|
||||
shell: pwsh
|
||||
run: |
|
||||
pip install geopandas `
|
||||
GitPython `
|
||||
conan
|
||||
pip install --break-system-packages clang-tidy-review/post/clang_tidy_review
|
||||
|
||||
- name: Cache Conan Packages
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.conan2
|
||||
key: build-${{ matrix.conan_profile }}-${{ hashFiles('./source/conanfile.py', './source/tools/conan/profiles/*') }}
|
||||
|
||||
- name: Install Conan Packages
|
||||
shell: pwsh
|
||||
run: |
|
||||
conan config install `
|
||||
./source/tools/conan/profiles/${{ matrix.conan_profile }} `
|
||||
-tf profiles
|
||||
mkdir build
|
||||
cd build
|
||||
mkdir conan
|
||||
conan install ../source/ `
|
||||
--remote conancenter `
|
||||
--build missing `
|
||||
--profile:all ${{ matrix.conan_profile }} `
|
||||
--settings:all build_type=${{ matrix.build_type }} `
|
||||
--output-folder ./conan/ `
|
||||
${{ matrix.conan_package_manager }}
|
||||
|
||||
- name: Autogenerate
|
||||
shell: pwsh
|
||||
run: |
|
||||
cd build
|
||||
cmake ../source/ `
|
||||
-G Ninja `
|
||||
-DCMAKE_BUILD_TYPE="${{ matrix.build_type }}" `
|
||||
-DCMAKE_PROJECT_TOP_LEVEL_INCLUDES="${{ github.workspace }}/source/external/cmake-conan/conan_provider.cmake" `
|
||||
-DCMAKE_INSTALL_PREFIX="${{ github.workspace }}/supercell-wx" `
|
||||
-DCONAN_HOST_PROFILE="${{ matrix.conan_profile }}" `
|
||||
-DCONAN_BUILD_PROFILE="${{ matrix.conan_profile }}" `
|
||||
-DCMAKE_EXPORT_COMPILE_COMMANDS=on
|
||||
ninja glad_gl_core_33 `
|
||||
scwx-qt_generate_counties_db `
|
||||
scwx-qt_generate_versions `
|
||||
scwx-qt_autogen
|
||||
|
||||
- name: Code Review
|
||||
id: review
|
||||
shell: bash
|
||||
run: |
|
||||
cd source
|
||||
review --clang_tidy_binary=${{ matrix.clang_tidy_binary }} \
|
||||
--token=${{ github.token }} \
|
||||
--repo='${{ github.repository }}' \
|
||||
--pr='${{ github.event.pull_request.number }}' \
|
||||
--build_dir='../build' \
|
||||
--base_dir='${{ github.workspace }}/source' \
|
||||
--clang_tidy_checks='' \
|
||||
--config_file='' \
|
||||
--include='*.[ch],*.[ch]xx,*.[chi]pp,*.[ch]++,*.cc,*.hh' \
|
||||
--exclude='' \
|
||||
--apt-packages='' \
|
||||
--cmake-command='' \
|
||||
--max-comments=25 \
|
||||
--lgtm-comment-body='' \
|
||||
--split_workflow=true \
|
||||
--annotations=false \
|
||||
--parallel=0
|
||||
rsync -avzh --ignore-missing-args clang-tidy-review-output.json ../
|
||||
rsync -avzh --ignore-missing-args clang-tidy-review-metadata.json ../
|
||||
rsync -avzh --ignore-missing-args clang_fixes.json ../
|
||||
|
||||
- name: Upload Review
|
||||
uses: ZedThree/clang-tidy-review/upload@v0.21.0
|
||||
|
||||
- name: Status Check
|
||||
if: steps.review.outputs.total_comments > 0
|
||||
run: exit 1
|
||||
11
.gitignore
vendored
|
|
@ -5,9 +5,20 @@ CMakeLists.txt.user
|
|||
CMakeCache.txt
|
||||
CMakeFiles
|
||||
CMakeScripts
|
||||
CMakeUserPresets.json
|
||||
Testing
|
||||
cmake_install.cmake
|
||||
install_manifest.txt
|
||||
compile_commands.json
|
||||
CTestTestfile.cmake
|
||||
_deps
|
||||
|
||||
# Editor directories
|
||||
.idea/
|
||||
.vs/
|
||||
|
||||
# Python Virtual Environment
|
||||
.venv/
|
||||
|
||||
# Specific excludes for Supercell Wx
|
||||
tools/lib/user-setup.sh
|
||||
|
|
|
|||
60
.gitmodules
vendored
|
|
@ -1,39 +1,45 @@
|
|||
[submodule "external/cmake-conan"]
|
||||
path = external/cmake-conan
|
||||
url = https://github.com/conan-io/cmake-conan.git
|
||||
[submodule "test/data"]
|
||||
path = test/data
|
||||
url = https://github.com/dpaulat/supercell-wx-test-data
|
||||
[submodule "external/hsluv-c"]
|
||||
path = external/hsluv-c
|
||||
url = https://github.com/hsluv/hsluv-c.git
|
||||
[submodule "external/stb"]
|
||||
path = external/stb
|
||||
url = https://github.com/nothings/stb.git
|
||||
[submodule "data"]
|
||||
path = data
|
||||
url = https://github.com/dpaulat/supercell-wx-data
|
||||
[submodule "external/aws-sdk-cpp"]
|
||||
path = external/aws-sdk-cpp
|
||||
url = https://github.com/aws/aws-sdk-cpp.git
|
||||
[submodule "external/cmake-conan"]
|
||||
path = external/cmake-conan
|
||||
url = https://github.com/conan-io/cmake-conan.git
|
||||
[submodule "external/date"]
|
||||
path = external/date
|
||||
url = https://github.com/HowardHinnant/date.git
|
||||
[submodule "external/glad"]
|
||||
path = external/glad
|
||||
url = https://github.com/Dav1dde/glad.git
|
||||
[submodule "external/hsluv-c"]
|
||||
path = external/hsluv-c
|
||||
url = https://github.com/hsluv/hsluv-c.git
|
||||
[submodule "external/imgui"]
|
||||
path = external/imgui
|
||||
url = https://github.com/ocornut/imgui.git
|
||||
[submodule "external/imgui-backend-qt"]
|
||||
path = external/imgui-backend-qt
|
||||
url = https://github.com/dpaulat/imgui-backend-qt
|
||||
[submodule "external/aws-sdk-cpp"]
|
||||
path = external/aws-sdk-cpp
|
||||
url = https://github.com/aws/aws-sdk-cpp.git
|
||||
[submodule "external/date"]
|
||||
path = external/date
|
||||
url = https://github.com/HowardHinnant/date.git
|
||||
[submodule "external/units"]
|
||||
path = external/units
|
||||
url = https://github.com/nholthaus/units.git
|
||||
[submodule "external/textflowcpp"]
|
||||
path = external/textflowcpp
|
||||
url = https://github.com/catchorg/textflowcpp.git
|
||||
[submodule "external/maplibre-native-qt"]
|
||||
path = external/maplibre-native-qt
|
||||
url = https://github.com/dpaulat/maplibre-native-qt.git
|
||||
[submodule "external/maplibre-native"]
|
||||
path = external/maplibre-native
|
||||
url = https://github.com/dpaulat/maplibre-gl-native.git
|
||||
[submodule "external/maplibre-native-qt"]
|
||||
path = external/maplibre-native-qt
|
||||
url = https://github.com/dpaulat/maplibre-native-qt.git
|
||||
[submodule "external/qt6ct"]
|
||||
path = external/qt6ct
|
||||
url = https://github.com/AdenKoperczak/qt6ct.git
|
||||
[submodule "external/stb"]
|
||||
path = external/stb
|
||||
url = https://github.com/nothings/stb.git
|
||||
[submodule "external/textflowcpp"]
|
||||
path = external/textflowcpp
|
||||
url = https://github.com/catchorg/textflowcpp.git
|
||||
[submodule "external/units"]
|
||||
path = external/units
|
||||
url = https://github.com/nholthaus/units.git
|
||||
[submodule "test/data"]
|
||||
path = test/data
|
||||
url = https://github.com/dpaulat/supercell-wx-test-data
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ Supercell Wx uses code from the following dependencies:
|
|||
| [FreeType GL](https://github.com/rougier/freetype-gl) | [BSD 2-Clause with views sentence](https://spdx.org/licenses/BSD-2-Clause-Views.html) |
|
||||
| [GeographicLib](https://geographiclib.sourceforge.io/) | [MIT License](https://spdx.org/licenses/MIT.html) |
|
||||
| [geos](https://libgeos.org/) | [GNU Lesser General Public License v2.1 or later](https://spdx.org/licenses/LGPL-2.1-or-later.html) |
|
||||
| [GLEW](https://www.opengl.org/sdk/libs/GLEW/) | [MIT License](https://spdx.org/licenses/MIT.html) |
|
||||
| [GLAD](https://github.com/Dav1dde/glad) | [MIT License](https://spdx.org/licenses/MIT.html) |
|
||||
| [GLM](https://github.com/g-truc/glm) | [MIT License](https://spdx.org/licenses/MIT.html) |
|
||||
| [GoogleTest](https://google.github.io/googletest/) | [BSD 3-Clause "New" or "Revised" License](https://spdx.org/licenses/BSD-3-Clause.html) |
|
||||
| [HSLuv](https://www.hsluv.org/) | [MIT License](https://spdx.org/licenses/MIT.html) |
|
||||
|
|
@ -32,9 +32,12 @@ Supercell Wx uses code from the following dependencies:
|
|||
| [libpng](http://libpng.org/pub/png/libpng.html) | [PNG Reference Library version 2](https://spdx.org/licenses/libpng-2.0.html) |
|
||||
| [libxml2](http://xmlsoft.org/) | [MIT License](https://spdx.org/licenses/MIT.html) |
|
||||
| [MapLibre Native](https://maplibre.org/projects/maplibre-native/) | [BSD 2-Clause "Simplified" License](https://spdx.org/licenses/BSD-2-Clause.html) |
|
||||
| [Mesa 3D](https://mesa3d.org/) | [MIT License](https://spdx.org/licenses/MIT.html) |
|
||||
| [nunicode](https://bitbucket.org/alekseyt/nunicode/src/master/) | [MIT License](https://spdx.org/licenses/MIT.html) | Modified for MapLibre Native |
|
||||
| [OpenSSL](https://www.openssl.org/) | [OpenSSL License](https://spdx.org/licenses/OpenSSL.html) |
|
||||
| [Qt](https://www.qt.io/) | [GNU Lesser General Public License v3.0 only](https://spdx.org/licenses/LGPL-3.0-only.html) | Qt Core, Qt GUI, Qt Multimedia, Qt Network, Qt OpenGL, Qt Positioning, Qt Serial Port, Qt SQL, Qt SVG, Qt Widgets<br/>Additional Licenses: https://doc.qt.io/qt-6/licenses-used-in-qt.html |
|
||||
| [qt6ct](https://github.com/trialuser02/qt6ct) | [BSD 2-Clause "Simplified" License](https://spdx.org/licenses/BSD-2-Clause.html) |
|
||||
| [range-v3](https://github.com/ericniebler/range-v3) | [Boost Software License 1.0](https://spdx.org/licenses/BSL-1.0.html)<br/>[MIT License](https://spdx.org/licenses/MIT.html)<br/>[Stepanov and McJones, "Elements of Programming" license](https://github.com/ericniebler/range-v3/tree/0.12.0?tab=License-1-ov-file)<br/>[SGI C++ Standard Template Library license](https://github.com/ericniebler/range-v3/tree/0.12.0?tab=License-1-ov-file) |
|
||||
| [re2](https://github.com/google/re2) | [BSD 3-Clause "New" or "Revised" License](https://spdx.org/licenses/BSD-3-Clause.html) |
|
||||
| [spdlog](https://github.com/gabime/spdlog) | [MIT License](https://spdx.org/licenses/MIT.html) |
|
||||
| [SQLite](https://www.sqlite.org/) | Public Domain |
|
||||
|
|
@ -67,6 +70,7 @@ Supercell Wx uses assets from the following sources:
|
|||
| [Font Awesome Free](https://fontawesome.com/) | CC BY 4.0 License |
|
||||
| [Inconsolata](https://fonts.google.com/specimen/Inconsolata) | SIL Open Font License |
|
||||
| [NOAA's Weather and Climate Toolkit](https://www.ncdc.noaa.gov/wct/) | Public Domain | Default Color Tables |
|
||||
| [qt6ct](https://github.com/trialuser02/qt6ct) | [BSD 2-Clause "Simplified" License](https://spdx.org/licenses/BSD-2-Clause.html) |
|
||||
| [Roboto Flex](https://fonts.google.com/specimen/Roboto+Flex) | SIL Open Font License |
|
||||
| [Supercell thunderstorm with dramatic clouds](https://www.shutterstock.com/image-photo/supercell-thunderstorm-dramatic-clouds-1354353521) | Shutterstock Standard License | Photo by John Sirlin
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,14 @@
|
|||
cmake_minimum_required(VERSION 3.21)
|
||||
cmake_minimum_required(VERSION 3.24)
|
||||
set(PROJECT_NAME supercell-wx)
|
||||
|
||||
include(tools/scwx_config.cmake)
|
||||
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET 12.0)
|
||||
|
||||
scwx_python_setup()
|
||||
|
||||
project(${PROJECT_NAME}
|
||||
VERSION 0.4.5
|
||||
VERSION 0.5.1
|
||||
DESCRIPTION "Supercell Wx is a free, open source advanced weather radar viewer."
|
||||
HOMEPAGE_URL "https://github.com/dpaulat/supercell-wx"
|
||||
LANGUAGES C CXX)
|
||||
|
|
@ -11,40 +18,21 @@ set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
|
|||
set(CMAKE_POLICY_DEFAULT_CMP0079 NEW)
|
||||
set(CMAKE_POLICY_DEFAULT_CMP0148 OLD) # aws-sdk-cpp uses FindPythonInterp
|
||||
|
||||
scwx_output_dirs_setup()
|
||||
|
||||
enable_testing()
|
||||
|
||||
set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
|
||||
|
||||
include(${PROJECT_SOURCE_DIR}/external/cmake-conan/conan.cmake)
|
||||
|
||||
set_property(DIRECTORY
|
||||
APPEND
|
||||
PROPERTY CMAKE_CONFIGURE_DEPENDS
|
||||
conanfile.py)
|
||||
|
||||
# Don't use RelWithDebInfo Conan packages
|
||||
if (${CMAKE_BUILD_TYPE} STREQUAL "RelWithDebInfo")
|
||||
set(conan_build_type "Release")
|
||||
else()
|
||||
set(conan_build_type ${CMAKE_BUILD_TYPE})
|
||||
endif()
|
||||
|
||||
conan_cmake_autodetect(settings
|
||||
BUILD_TYPE ${conan_build_type})
|
||||
|
||||
conan_cmake_install(PATH_OR_REFERENCE ${PROJECT_SOURCE_DIR}
|
||||
BUILD missing
|
||||
REMOTE conancenter
|
||||
SETTINGS ${settings})
|
||||
|
||||
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
|
||||
include(${CMAKE_BINARY_DIR}/conan_paths.cmake)
|
||||
conan_basic_setup(TARGETS)
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DBOOST_ALL_NO_LIB")
|
||||
|
||||
set(SCWX_DIR ${PROJECT_SOURCE_DIR})
|
||||
set(SCWX_VERSION "0.4.5")
|
||||
set(SCWX_VERSION "0.5.1")
|
||||
|
||||
option(SCWX_ADDRESS_SANITIZER "Build with Address Sanitizer" OFF)
|
||||
|
||||
|
|
|
|||
383
CMakePresets.json
Normal file
|
|
@ -0,0 +1,383 @@
|
|||
{
|
||||
"version": 5,
|
||||
"cmakeMinimumRequired": {
|
||||
"major": 3,
|
||||
"minor": 24,
|
||||
"patch": 0
|
||||
},
|
||||
"configurePresets": [
|
||||
{
|
||||
"name": "base",
|
||||
"hidden": true,
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/build/${presetName}",
|
||||
"cacheVariables": {
|
||||
"CMAKE_PROJECT_TOP_LEVEL_INCLUDES": "${sourceDir}/external/cmake-conan/conan_provider.cmake",
|
||||
"SCWX_VIRTUAL_ENV": "${sourceDir}/.venv"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "windows-base",
|
||||
"inherits": "base",
|
||||
"hidden": true,
|
||||
"generator": "Visual Studio 17 2022",
|
||||
"condition": {
|
||||
"type": "equals",
|
||||
"lhs": "${hostSystemName}",
|
||||
"rhs": "Windows"
|
||||
},
|
||||
"vendor": {
|
||||
"microsoft.com/VisualStudioSettings/CMake/1.0": {
|
||||
"hostOS": [
|
||||
"Windows"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "windows-x64-base",
|
||||
"inherits": "windows-base",
|
||||
"hidden": true
|
||||
},
|
||||
{
|
||||
"name": "linux-base",
|
||||
"inherits": "base",
|
||||
"hidden": true,
|
||||
"condition": {
|
||||
"type": "equals",
|
||||
"lhs": "${hostSystemName}",
|
||||
"rhs": "Linux"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "windows-msvc2022-x64-base",
|
||||
"inherits": "windows-x64-base",
|
||||
"hidden": true,
|
||||
"cacheVariables": {
|
||||
"CMAKE_PREFIX_PATH": "C:/Qt/6.9.2/msvc2022_64"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "windows-msvc2022-x64-ninja-base",
|
||||
"inherits": "windows-msvc2022-x64-base",
|
||||
"hidden": true,
|
||||
"generator": "Ninja",
|
||||
"cacheVariables": {
|
||||
"CMAKE_PREFIX_PATH": "C:/Qt/6.9.2/msvc2022_64"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "linux-gcc-base",
|
||||
"inherits": "linux-base",
|
||||
"hidden": true,
|
||||
"cacheVariables": {
|
||||
"CMAKE_PREFIX_PATH": "/opt/Qt/6.9.2/gcc_64"
|
||||
},
|
||||
"environment": {
|
||||
"CC": "gcc-11",
|
||||
"CXX": "g++-11"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "windows-msvc2022-x64-debug",
|
||||
"inherits": "windows-msvc2022-x64-base",
|
||||
"displayName": "Windows MSVC 2022 x64 Debug",
|
||||
"architecture": {
|
||||
"value": "x64",
|
||||
"strategy": "external"
|
||||
},
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"CONAN_HOST_PROFILE": "scwx-windows_msvc2022_x64-debug",
|
||||
"CONAN_BUILD_PROFILE": "scwx-windows_msvc2022_x64-debug"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "windows-msvc2022-x64-release",
|
||||
"inherits": "windows-msvc2022-x64-base",
|
||||
"displayName": "Windows MSVC 2022 x64 Release",
|
||||
"architecture": {
|
||||
"value": "x64",
|
||||
"strategy": "external"
|
||||
},
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"CONAN_HOST_PROFILE": "scwx-windows_msvc2022_x64",
|
||||
"CONAN_BUILD_PROFILE": "scwx-windows_msvc2022_x64"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "windows-msvc2022-x64-ninja-debug",
|
||||
"inherits": "windows-msvc2022-x64-ninja-base",
|
||||
"displayName": "Windows MSVC 2022 x64 Ninja Debug",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"CONAN_HOST_PROFILE": "scwx-windows_msvc2022_x64-debug",
|
||||
"CONAN_BUILD_PROFILE": "scwx-windows_msvc2022_x64-debug"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "windows-msvc2022-x64-ninja-release",
|
||||
"inherits": "windows-msvc2022-x64-ninja-base",
|
||||
"displayName": "Windows MSVC 2022 x64 Ninja Release",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"CONAN_HOST_PROFILE": "scwx-windows_msvc2022_x64",
|
||||
"CONAN_BUILD_PROFILE": "scwx-windows_msvc2022_x64"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "linux-gcc-debug",
|
||||
"inherits": "linux-gcc-base",
|
||||
"displayName": "Linux GCC Debug",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"CMAKE_INSTALL_PREFIX": "${sourceDir}/build/${presetName}/Debug/supercell-wx",
|
||||
"CONAN_HOST_PROFILE": "scwx-linux_gcc-11-debug",
|
||||
"CONAN_BUILD_PROFILE": "scwx-linux_gcc-11-debug"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "linux-gcc-release",
|
||||
"inherits": "linux-gcc-base",
|
||||
"displayName": "Linux GCC Release",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"CMAKE_INSTALL_PREFIX": "${sourceDir}/build/${presetName}/Release/supercell-wx",
|
||||
"CONAN_HOST_PROFILE": "scwx-linux_gcc-11",
|
||||
"CONAN_BUILD_PROFILE": "scwx-linux_gcc-11"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "linux-gcc-debug-asan",
|
||||
"inherits": "linux-gcc-base",
|
||||
"displayName": "Linux GCC Debug Address Sanitizer",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"CMAKE_INSTALL_PREFIX": "${sourceDir}/build/${presetName}/Debug/supercell-wx",
|
||||
"CONAN_HOST_PROFILE": "scwx-linux_gcc-11-debug",
|
||||
"CONAN_BUILD_PROFILE": "scwx-linux_gcc-11-debug",
|
||||
"SCWX_ADDRESS_SANITIZER": {
|
||||
"type": "BOOL",
|
||||
"value": "ON"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "linux-gcc-release-asan",
|
||||
"inherits": "linux-gcc-base",
|
||||
"displayName": "Linux GCC Release Address Sanitizer",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"CMAKE_INSTALL_PREFIX": "${sourceDir}/build/${presetName}/Release/supercell-wx",
|
||||
"CONAN_HOST_PROFILE": "scwx-linux_gcc-11",
|
||||
"CONAN_BUILD_PROFILE": "scwx-linux_gcc-11",
|
||||
"SCWX_ADDRESS_SANITIZER": {
|
||||
"type": "BOOL",
|
||||
"value": "ON"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ci-linux-gcc14",
|
||||
"inherits": "linux-gcc-base",
|
||||
"displayName": "CI Linux GCC 14",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"CONAN_HOST_PROFILE": "scwx-linux_gcc-14",
|
||||
"CONAN_BUILD_PROFILE": "scwx-linux_gcc-14"
|
||||
},
|
||||
"environment": {
|
||||
"CC": "gcc-14",
|
||||
"CXX": "g++-14"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ci-linux-clang17",
|
||||
"inherits": "linux-gcc-base",
|
||||
"displayName": "CI Linux Clang 17",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"CONAN_HOST_PROFILE": "scwx-linux_clang-17",
|
||||
"CONAN_BUILD_PROFILE": "scwx-linux_clang-17"
|
||||
},
|
||||
"environment": {
|
||||
"CC": "clang-17",
|
||||
"CXX": "clang++-17"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ci-linux-gcc-arm64",
|
||||
"inherits": "linux-gcc-base",
|
||||
"displayName": "CI Linux GCC ARM64",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"CMAKE_PREFIX_PATH": "/opt/Qt/6.9.2/gcc_arm64",
|
||||
"CONAN_HOST_PROFILE": "scwx-linux_gcc-11_armv8",
|
||||
"CONAN_BUILD_PROFILE": "scwx-linux_gcc-11_armv8"
|
||||
},
|
||||
"environment": {
|
||||
"CC": "gcc-11",
|
||||
"CXX": "g++-11"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "macos-base",
|
||||
"inherits": "base",
|
||||
"hidden": true,
|
||||
"cacheVariables": {
|
||||
"CMAKE_PREFIX_PATH": "$env{HOME}/Qt/6.9.2/macos"
|
||||
},
|
||||
"condition": {
|
||||
"type": "equals",
|
||||
"lhs": "${hostSystemName}",
|
||||
"rhs": "Darwin"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "macos-clang18-base",
|
||||
"inherits": "macos-base",
|
||||
"hidden": true
|
||||
},
|
||||
{
|
||||
"name": "macos-clang18-x64-base",
|
||||
"inherits": "macos-clang18-base",
|
||||
"hidden": true,
|
||||
"environment": {
|
||||
"CC": "/usr/local/opt/llvm@18/bin/clang",
|
||||
"CXX": "/usr/local/opt/llvm@18/bin/clang++",
|
||||
"PATH": "/usr/local/opt/llvm@18/bin:$penv{PATH}",
|
||||
"CPPFLAGS": "-I/usr/local/opt/llvm@18/include",
|
||||
"LDFLAGS": "-L/usr/local/opt/llvm@18/lib -L/usr/local/opt/llvm@18/lib/c++"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "macos-clang18-arm64-base",
|
||||
"inherits": "macos-clang18-base",
|
||||
"hidden": true,
|
||||
"environment": {
|
||||
"CC": "/opt/homebrew/opt/llvm@18/bin/clang",
|
||||
"CXX": "/opt/homebrew/opt/llvm@18/bin/clang++",
|
||||
"PATH": "/opt/homebrew/opt/llvm@18/bin:$penv{PATH}",
|
||||
"CPPFLAGS": "-I/opt/homebrew/opt/llvm@18/include",
|
||||
"LDFLAGS": "-L/opt/homebrew/opt/llvm@18/lib -L/opt/homebrew/opt/llvm@18/lib/c++"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "macos-clang18-x64-debug",
|
||||
"inherits": "macos-clang18-x64-base",
|
||||
"displayName": "macOS Clang 18 x64 Debug",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"CONAN_HOST_PROFILE": "scwx-macos_clang-18-debug",
|
||||
"CONAN_BUILD_PROFILE": "scwx-macos_clang-18-debug"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "macos-clang18-x64-release",
|
||||
"inherits": "macos-clang18-x64-base",
|
||||
"displayName": "macOS Clang 18 x64 Release",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"CONAN_HOST_PROFILE": "scwx-macos_clang-18",
|
||||
"CONAN_BUILD_PROFILE": "scwx-macos_clang-18"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "macos-clang18-arm64-debug",
|
||||
"inherits": "macos-clang18-arm64-base",
|
||||
"displayName": "macOS Clang 18 Arm64 Debug",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"CONAN_HOST_PROFILE": "scwx-macos_clang-18_armv8-debug",
|
||||
"CONAN_BUILD_PROFILE": "scwx-macos_clang-18_armv8-debug"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "macos-clang18-arm64-release",
|
||||
"inherits": "macos-clang18-arm64-base",
|
||||
"displayName": "macOS Clang 18 Arm64 Release",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"CONAN_HOST_PROFILE": "scwx-macos_clang-18_armv8",
|
||||
"CONAN_BUILD_PROFILE": "scwx-macos_clang-18_armv8"
|
||||
}
|
||||
}
|
||||
],
|
||||
"buildPresets": [
|
||||
{
|
||||
"name": "windows-msvc2022-x64-debug",
|
||||
"configurePreset": "windows-msvc2022-x64-debug",
|
||||
"displayName": "Windows MSVC 2022 x64 Debug",
|
||||
"configuration": "Debug"
|
||||
},
|
||||
{
|
||||
"name": "windows-msvc2022-x64-release",
|
||||
"configurePreset": "windows-msvc2022-x64-release",
|
||||
"displayName": "Windows MSVC 2022 x64 Release",
|
||||
"configuration": "Release"
|
||||
},
|
||||
{
|
||||
"name": "linux-gcc-debug",
|
||||
"configurePreset": "linux-gcc-debug",
|
||||
"displayName": "Linux GCC Debug",
|
||||
"configuration": "Debug"
|
||||
},
|
||||
{
|
||||
"name": "linux-gcc-release",
|
||||
"configurePreset": "linux-gcc-release",
|
||||
"displayName": "Linux GCC Release",
|
||||
"configuration": "Release"
|
||||
},
|
||||
{
|
||||
"name": "macos-clang18-x64-debug",
|
||||
"configurePreset": "macos-clang18-x64-debug",
|
||||
"displayName": "macOS Clang 18 x64 Debug",
|
||||
"configuration": "Debug"
|
||||
},
|
||||
{
|
||||
"name": "macos-clang18-x64-release",
|
||||
"configurePreset": "macos-clang18-x64-release",
|
||||
"displayName": "macOS Clang 18 x64 Release",
|
||||
"configuration": "Release"
|
||||
},
|
||||
{
|
||||
"name": "macos-clang18-arm64-debug",
|
||||
"configurePreset": "macos-clang18-arm64-debug",
|
||||
"displayName": "macOS Clang 18 Arm64 Debug",
|
||||
"configuration": "Debug"
|
||||
},
|
||||
{
|
||||
"name": "macos-clang18-arm64-release",
|
||||
"configurePreset": "macos-clang18-arm64-release",
|
||||
"displayName": "macOS Clang 18 Arm64 Release",
|
||||
"configuration": "Release"
|
||||
}
|
||||
],
|
||||
"testPresets": [
|
||||
{
|
||||
"name": "windows-msvc2022-x64-debug",
|
||||
"configurePreset": "windows-msvc2022-x64-debug",
|
||||
"displayName": "Windows MSVC 2022 x64 Debug",
|
||||
"configuration": "Debug"
|
||||
},
|
||||
{
|
||||
"name": "windows-msvc2022-x64-release",
|
||||
"configurePreset": "windows-msvc2022-x64-release",
|
||||
"displayName": "Windows MSVC 2022 x64 Release",
|
||||
"configuration": "Release"
|
||||
},
|
||||
{
|
||||
"name": "linux-gcc-debug",
|
||||
"configurePreset": "linux-gcc-debug",
|
||||
"displayName": "Linux GCC Debug",
|
||||
"configuration": "Debug"
|
||||
},
|
||||
{
|
||||
"name": "linux-gcc-release",
|
||||
"configurePreset": "linux-gcc-release",
|
||||
"displayName": "Linux GCC Release",
|
||||
"configuration": "Release"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2021-2024 Dan Paulat
|
||||
Copyright (c) 2021-2025 Dan Paulat
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
|||
18
README.md
|
|
@ -26,32 +26,36 @@ Supercell Wx supports the following 64-bit operating systems:
|
|||
- Fedora Linux 34+
|
||||
- openSUSE Tumbleweed
|
||||
- Ubuntu 22.04+
|
||||
- NixOS 25.05+
|
||||
- Most distributions supporting the GCC Standard C++ Library 11+
|
||||
|
||||
- macOS
|
||||
- 13.6+ for Intel-based Macs
|
||||
- 14.0+ for Apple silicon-based Macs
|
||||
|
||||
## Linux Dependencies
|
||||
|
||||
Supercell Wx requires the following Linux dependencies:
|
||||
|
||||
- Linux/X11 (Wayland works too) with support for GCC 11 and OpenGL 3.3
|
||||
- Linux/X11 (Wayland works too) with support for GCC 11, OpenGL 3.3 and OpenGL ES 3.0
|
||||
- X11/XCB libraries including xcb-cursor
|
||||
|
||||
|
||||
## FAQ
|
||||
|
||||
Frequently asked questions:
|
||||
|
||||
- Q: Why is the map black when loading for the first time?
|
||||
|
||||
|
||||
- A. You must obtain a free API key from either (or both) [MapTiler](https://cloud.maptiler.com/auth/widget?next=https://cloud.maptiler.com/maps/) which currently does not require a credit/debit card, or [Mapbox](https://account.mapbox.com/) which ***does*** require a credit/debit card, but as of writing, you will receive 200K free requests per month, which should be sufficient for an individual user.
|
||||
|
||||
- Q: Why is it that when I change my color table, API key, grid width/height settings, nothing happens after hitting apply?
|
||||
|
||||
- A. As of right now, you must restart Supercell Wx in order to apply these changes. In future iterations, this will no longer be an issue.
|
||||
|
||||
|
||||
- Q. Is it possible to get dark mode?
|
||||
|
||||
|
||||
- A. In Windows, make sure to set the flag `-style fusion` at the end of the target path of the .exe
|
||||
- Example: `C:\Users\Administrator\Desktop\Supercell-Wx\bin\supercell-wx.exe -style fusion`
|
||||
- A. In Linux, if you're using KDE, Supercell Wx should automatically follow your theme settings.
|
||||
|
||||
|
||||
- Q: How can I contribute?
|
||||
- A. Head to [Developer Setup](https://supercell-wx.readthedocs.io/en/stable/development/developer-setup.html) and [Contributing](CONTRIBUTING.md) to configure the Supercell Wx development environment for your IDE. Currently Visual Studio and Visual Studio Code are recommended, with other IDEs remaining untested at this time.
|
||||
|
|
|
|||
83
conanfile.py
|
|
@ -1,37 +1,66 @@
|
|||
from conans import ConanFile
|
||||
from conan import ConanFile
|
||||
from conan.tools.cmake import CMake
|
||||
from conan.tools.files import copy
|
||||
import os
|
||||
|
||||
class SupercellWxConan(ConanFile):
|
||||
settings = ("os", "compiler", "build_type", "arch")
|
||||
requires = ("boost/1.85.0",
|
||||
"cpr/1.10.5",
|
||||
requires = ("boost/1.88.0",
|
||||
"cpr/1.12.0",
|
||||
"fontconfig/2.15.0",
|
||||
"freetype/2.13.2",
|
||||
"geographiclib/2.3",
|
||||
"geos/3.12.2",
|
||||
"glew/2.2.0",
|
||||
"glm/cci.20230113",
|
||||
"gtest/1.15.0",
|
||||
"libcurl/8.9.1",
|
||||
"libxml2/2.12.7",
|
||||
"openssl/3.3.1",
|
||||
"re2/20240702",
|
||||
"spdlog/1.14.1",
|
||||
"sqlite3/3.46.0",
|
||||
"vulkan-loader/1.3.243.0",
|
||||
"geographiclib/2.4",
|
||||
"geos/3.13.0",
|
||||
"glm/1.0.1",
|
||||
"gtest/1.17.0",
|
||||
"libcurl/8.12.1",
|
||||
"libpng/1.6.50",
|
||||
"libxml2/2.14.5",
|
||||
"openssl/3.5.0",
|
||||
"range-v3/0.12.0",
|
||||
"re2/20250722",
|
||||
"spdlog/1.15.1",
|
||||
"sqlite3/3.49.1",
|
||||
"vulkan-loader/1.3.290.0",
|
||||
"zlib/1.3.1")
|
||||
generators = ("cmake",
|
||||
"cmake_find_package",
|
||||
"cmake_paths")
|
||||
default_options = {"geos:shared" : True,
|
||||
"libiconv:shared" : True,
|
||||
"openssl:no_module": True,
|
||||
"openssl:shared" : True}
|
||||
generators = ("CMakeDeps")
|
||||
default_options = {"geos/*:shared" : True,
|
||||
"libiconv/*:shared" : True}
|
||||
|
||||
def configure(self):
|
||||
if self.settings.os == "Windows":
|
||||
self.options["libcurl"].with_ssl = "schannel"
|
||||
elif self.settings.os == "Linux":
|
||||
self.options["openssl"].shared = True
|
||||
self.options["libcurl"].ca_bundle = "none"
|
||||
self.options["libcurl"].ca_path = "none"
|
||||
elif self.settings.os == "Macos":
|
||||
self.options["openssl"].shared = True
|
||||
self.options["libcurl"].ca_bundle = "none"
|
||||
self.options["libcurl"].ca_path = "none"
|
||||
|
||||
def requirements(self):
|
||||
if self.settings.os == "Linux":
|
||||
self.requires("onetbb/2021.12.0")
|
||||
self.requires("mesa-glu/9.0.3")
|
||||
self.requires("onetbb/2022.2.0")
|
||||
|
||||
def imports(self):
|
||||
self.copy("*.dll", dst="bin", src="bin")
|
||||
self.copy("*.dylib", dst="bin", src="lib")
|
||||
self.copy("license*", dst="licenses", src=".", folder=True, ignore_case=True)
|
||||
def generate(self):
|
||||
build_folder = os.path.join(self.build_folder,
|
||||
"..",
|
||||
str(self.settings.build_type),
|
||||
self.cpp_info.bindirs[0])
|
||||
|
||||
for dep in self.dependencies.values():
|
||||
if dep.cpp_info.bindirs:
|
||||
copy(self, "*.dll", dep.cpp_info.bindirs[0], build_folder)
|
||||
if dep.cpp_info.libdirs:
|
||||
copy(self, "*.dylib", dep.cpp_info.libdirs[0], build_folder)
|
||||
|
||||
def build(self):
|
||||
cmake = CMake(self)
|
||||
cmake.configure()
|
||||
cmake.build()
|
||||
|
||||
def package(self):
|
||||
cmake = CMake(self)
|
||||
cmake.install()
|
||||
|
|
|
|||
2
data
|
|
@ -1 +1 @@
|
|||
Subproject commit 8eb89b19fdd1c78e896cc6cb47e07425bb473699
|
||||
Subproject commit fd72b32cc12419b4a9c9a72487e58ffa04fb2a70
|
||||
8
external/CMakeLists.txt
vendored
|
|
@ -1,4 +1,4 @@
|
|||
cmake_minimum_required(VERSION 3.20)
|
||||
cmake_minimum_required(VERSION 3.24)
|
||||
set(PROJECT_NAME scwx-external)
|
||||
|
||||
set_property(DIRECTORY
|
||||
|
|
@ -6,18 +6,22 @@ set_property(DIRECTORY
|
|||
PROPERTY CMAKE_CONFIGURE_DEPENDS
|
||||
aws-sdk-cpp.cmake
|
||||
date.cmake
|
||||
glad.cmake
|
||||
hsluv-c.cmake
|
||||
imgui.cmake
|
||||
maplibre-native-qt.cmake
|
||||
stb.cmake
|
||||
textflowcpp.cmake
|
||||
units.cmake)
|
||||
units.cmake
|
||||
qt6ct.cmake)
|
||||
|
||||
include(aws-sdk-cpp.cmake)
|
||||
include(date.cmake)
|
||||
include(glad.cmake)
|
||||
include(hsluv-c.cmake)
|
||||
include(imgui.cmake)
|
||||
include(maplibre-native-qt.cmake)
|
||||
include(stb.cmake)
|
||||
include(textflowcpp.cmake)
|
||||
include(units.cmake)
|
||||
include(qt6ct.cmake)
|
||||
|
|
|
|||
2
external/aws-sdk-cpp
vendored
|
|
@ -1 +1 @@
|
|||
Subproject commit d5eb42fe7c632868d4535b454ee2e5ba0e349b7f
|
||||
Subproject commit 8d31e042f950fe70924391a205cceaf342ecec00
|
||||
6
external/aws-sdk-cpp.cmake
vendored
|
|
@ -1,4 +1,4 @@
|
|||
cmake_minimum_required(VERSION 3.20)
|
||||
cmake_minimum_required(VERSION 3.24)
|
||||
set(PROJECT_NAME scwx-aws-sdk-cpp)
|
||||
|
||||
set(AWS_SDK_WARNINGS_ARE_ERRORS OFF)
|
||||
|
|
@ -21,6 +21,10 @@ set(MINIMIZE_SIZE OFF CACHE BOOL "If enabled, the SDK will be built via
|
|||
# Save off ${CMAKE_CXX_FLAGS} before modifying compiler settings
|
||||
set(CMAKE_CXX_FLAGS_PREV "${CMAKE_CXX_FLAGS}")
|
||||
|
||||
# Configure OpenSSL crypto library
|
||||
find_package(OpenSSL)
|
||||
add_library(crypto ALIAS OpenSSL::Crypto)
|
||||
|
||||
# Fix CMake errors for internal variables not set
|
||||
include(aws-sdk-cpp/cmake/compiler_settings.cmake)
|
||||
set_msvc_warnings()
|
||||
|
|
|
|||
2
external/cmake-conan
vendored
|
|
@ -1 +1 @@
|
|||
Subproject commit b240c809b5ea097077fc8222cad71d2329288e48
|
||||
Subproject commit b0e4d1ec08edb35ef31033938567d621f6643c17
|
||||
2
external/date
vendored
|
|
@ -1 +1 @@
|
|||
Subproject commit cc4685a21e4a4fdae707ad1233c61bbaff241f93
|
||||
Subproject commit a5db3aecec580bc78b6c01c118f2628676769b69
|
||||
2
external/date.cmake
vendored
|
|
@ -1,4 +1,4 @@
|
|||
cmake_minimum_required(VERSION 3.20)
|
||||
cmake_minimum_required(VERSION 3.24)
|
||||
set(PROJECT_NAME scwx-date)
|
||||
|
||||
set(USE_SYSTEM_TZ_DB ON)
|
||||
|
|
|
|||
1
external/glad
vendored
Submodule
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 73db193f853e2ee079bf3ca8a64aa2eaf6459043
|
||||
11
external/glad.cmake
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
cmake_minimum_required(VERSION 3.24)
|
||||
set(PROJECT_NAME scwx-glad)
|
||||
|
||||
# Path to glad directory
|
||||
set(GLAD_SOURCES_DIR "${CMAKE_CURRENT_SOURCE_DIR}/glad/")
|
||||
|
||||
# Path to glad CMake files
|
||||
add_subdirectory("${GLAD_SOURCES_DIR}/cmake" glad_cmake)
|
||||
|
||||
# Specify glad settings
|
||||
glad_add_library(glad_gl_core_33 LOADER REPRODUCIBLE API gl:core=3.3)
|
||||
2
external/hsluv-c
vendored
|
|
@ -1 +1 @@
|
|||
Subproject commit 59539e04a6fa648935cbe57c2104041f23136c4a
|
||||
Subproject commit 982217c65a9ff574302335177d2dc078d9bfa6f5
|
||||
2
external/hsluv-c.cmake
vendored
|
|
@ -1,4 +1,4 @@
|
|||
cmake_minimum_required(VERSION 3.20)
|
||||
cmake_minimum_required(VERSION 3.24)
|
||||
set(PROJECT_NAME scwx-hsluv-c)
|
||||
|
||||
set(HSLUV_C_TESTS OFF)
|
||||
|
|
|
|||
2
external/imgui
vendored
|
|
@ -1 +1 @@
|
|||
Subproject commit 6ccc561a2ab497ad4ae6ee1dbd3b992ffada35cb
|
||||
Subproject commit 45acd5e0e82f4c954432533ae9985ff0e1aad6d5
|
||||
2
external/imgui-backend-qt
vendored
|
|
@ -1 +1 @@
|
|||
Subproject commit 0fe974ebd037844c9f23d6325dbcc128e9973749
|
||||
Subproject commit 023345ca8abf731fc50568c0197ceebe76bb4324
|
||||
7
external/imgui.cmake
vendored
|
|
@ -1,4 +1,4 @@
|
|||
cmake_minimum_required(VERSION 3.20)
|
||||
cmake_minimum_required(VERSION 3.24)
|
||||
set(PROJECT_NAME scwx-imgui)
|
||||
|
||||
find_package(QT NAMES Qt6
|
||||
|
|
@ -12,7 +12,7 @@ find_package(Qt${QT_VERSION_MAJOR}
|
|||
|
||||
find_package(Freetype)
|
||||
|
||||
set(IMGUI_SOURCES imgui/imconfig.h
|
||||
set(IMGUI_SOURCES include/scwx/external/imgui/imconfig.h
|
||||
imgui/imgui.cpp
|
||||
imgui/imgui.h
|
||||
imgui/imgui_demo.cpp
|
||||
|
|
@ -33,8 +33,9 @@ set(IMGUI_SOURCES imgui/imconfig.h
|
|||
add_library(imgui STATIC ${IMGUI_SOURCES})
|
||||
|
||||
target_include_directories(imgui PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/imgui)
|
||||
target_include_directories(imgui PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||
|
||||
target_compile_definitions(imgui PRIVATE IMGUI_ENABLE_FREETYPE)
|
||||
target_compile_definitions(imgui PUBLIC IMGUI_USER_CONFIG=<scwx/external/imgui/imconfig.h>)
|
||||
|
||||
target_link_libraries(imgui PRIVATE Qt${QT_VERSION_MAJOR}::Widgets
|
||||
Freetype::Freetype)
|
||||
|
|
|
|||
147
external/include/scwx/external/imgui/imconfig.h
vendored
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
// clang-format off
|
||||
//-----------------------------------------------------------------------------
|
||||
// DEAR IMGUI COMPILE-TIME OPTIONS
|
||||
// Runtime options (clipboard callbacks, enabling various features, etc.) can generally be set via the ImGuiIO structure.
|
||||
// You can use ImGui::SetAllocatorFunctions() before calling ImGui::CreateContext() to rewire memory allocation functions.
|
||||
//-----------------------------------------------------------------------------
|
||||
// A) You may edit imconfig.h (and not overwrite it when updating Dear ImGui, or maintain a patch/rebased branch with your modifications to it)
|
||||
// B) or '#define IMGUI_USER_CONFIG "my_imgui_config.h"' in your project and then add directives in your own file without touching this template.
|
||||
//-----------------------------------------------------------------------------
|
||||
// You need to make sure that configuration settings are defined consistently _everywhere_ Dear ImGui is used, which include the imgui*.cpp
|
||||
// files but also _any_ of your code that uses Dear ImGui. This is because some compile-time options have an affect on data structures.
|
||||
// Defining those options in imconfig.h will ensure every compilation unit gets to see the same data structure layouts.
|
||||
// Call IMGUI_CHECKVERSION() from your .cpp file to verify that the data structures your files are using are matching the ones imgui.cpp is using.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
//---- Define assertion handler. Defaults to calling assert().
|
||||
// If your macro uses multiple statements, make sure is enclosed in a 'do { .. } while (0)' block so it can be used as a single statement.
|
||||
//#define IM_ASSERT(_EXPR) MyAssert(_EXPR)
|
||||
//#define IM_ASSERT(_EXPR) ((void)(_EXPR)) // Disable asserts
|
||||
|
||||
//---- Define attributes of all API symbols declarations, e.g. for DLL under Windows
|
||||
// Using Dear ImGui via a shared library is not recommended, because of function call overhead and because we don't guarantee backward nor forward ABI compatibility.
|
||||
// - Windows DLL users: heaps and globals are not shared across DLL boundaries! You will need to call SetCurrentContext() + SetAllocatorFunctions()
|
||||
// for each static/DLL boundary you are calling from. Read "Context and Memory Allocators" section of imgui.cpp for more details.
|
||||
//#define IMGUI_API __declspec(dllexport) // MSVC Windows: DLL export
|
||||
//#define IMGUI_API __declspec(dllimport) // MSVC Windows: DLL import
|
||||
//#define IMGUI_API __attribute__((visibility("default"))) // GCC/Clang: override visibility when set is hidden
|
||||
|
||||
//---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to clean your code of obsolete function/names.
|
||||
#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
|
||||
//---- Disable all of Dear ImGui or don't implement standard windows/tools.
|
||||
// It is very strongly recommended to NOT disable the demo windows and debug tool during development. They are extremely useful in day to day work. Please read comments in imgui_demo.cpp.
|
||||
//#define IMGUI_DISABLE // Disable everything: all headers and source files will be empty.
|
||||
//#define IMGUI_DISABLE_DEMO_WINDOWS // Disable demo windows: ShowDemoWindow()/ShowStyleEditor() will be empty.
|
||||
//#define IMGUI_DISABLE_DEBUG_TOOLS // Disable metrics/debugger and other debug tools: ShowMetricsWindow(), ShowDebugLogWindow() and ShowIDStackToolWindow() will be empty.
|
||||
|
||||
//---- Don't implement some functions to reduce linkage requirements.
|
||||
//#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc. (user32.lib/.a, kernel32.lib/.a)
|
||||
//#define IMGUI_ENABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with Visual Studio] Implement default IME handler (require imm32.lib/.a, auto-link for Visual Studio, -limm32 on command-line for MinGW)
|
||||
//#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with non-Visual Studio compilers] Don't implement default IME handler (won't require imm32.lib/.a)
|
||||
//#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, IME).
|
||||
//#define IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS // [OSX] Implement default OSX clipboard handler (need to link with '-framework ApplicationServices', this is why this is not the default).
|
||||
//#define IMGUI_DISABLE_DEFAULT_SHELL_FUNCTIONS // Don't implement default platform_io.Platform_OpenInShellFn() handler (Win32: ShellExecute(), require shell32.lib/.a, Mac/Linux: use system("")).
|
||||
//#define IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS // Don't implement ImFormatString/ImFormatStringV so you can implement them yourself (e.g. if you don't want to link with vsnprintf)
|
||||
//#define IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 so you can implement them yourself.
|
||||
//#define IMGUI_DISABLE_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle at all (replace them with dummies)
|
||||
//#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle so you can implement them yourself if you don't want to link with fopen/fclose/fread/fwrite. This will also disable the LogToTTY() function.
|
||||
//#define IMGUI_DISABLE_DEFAULT_ALLOCATORS // Don't implement default allocators calling malloc()/free() to avoid linking with them. You will need to call ImGui::SetAllocatorFunctions().
|
||||
//#define IMGUI_DISABLE_DEFAULT_FONT // Disable default embedded font (ProggyClean.ttf), remove ~9.5 KB from output binary. AddFontDefault() will assert.
|
||||
//#define IMGUI_DISABLE_SSE // Disable use of SSE intrinsics even if available
|
||||
|
||||
//---- Enable Test Engine / Automation features.
|
||||
//#define IMGUI_ENABLE_TEST_ENGINE // Enable imgui_test_engine hooks. Generally set automatically by include "imgui_te_config.h", see Test Engine for details.
|
||||
|
||||
//---- Include imgui_user.h at the end of imgui.h as a convenience
|
||||
// May be convenient for some users to only explicitly include vanilla imgui.h and have extra stuff included.
|
||||
//#define IMGUI_INCLUDE_IMGUI_USER_H
|
||||
//#define IMGUI_USER_H_FILENAME "my_folder/my_imgui_user.h"
|
||||
|
||||
//---- Pack vertex colors as BGRA8 instead of RGBA8 (to avoid converting from one to another). Need dedicated backend support.
|
||||
//#define IMGUI_USE_BGRA_PACKED_COLOR
|
||||
|
||||
//---- Use legacy CRC32-adler tables (used before 1.91.6), in order to preserve old .ini data that you cannot afford to invalidate.
|
||||
//#define IMGUI_USE_LEGACY_CRC32_ADLER
|
||||
|
||||
//---- Use 32-bit for ImWchar (default is 16-bit) to support Unicode planes 1-16. (e.g. point beyond 0xFFFF like emoticons, dingbats, symbols, shapes, ancient languages, etc...)
|
||||
//#define IMGUI_USE_WCHAR32
|
||||
|
||||
//---- Avoid multiple STB libraries implementations, or redefine path/filenames to prioritize another version
|
||||
// By default the embedded implementations are declared static and not available outside of Dear ImGui sources files.
|
||||
//#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h"
|
||||
//#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h"
|
||||
//#define IMGUI_STB_SPRINTF_FILENAME "my_folder/stb_sprintf.h" // only used if IMGUI_USE_STB_SPRINTF is defined.
|
||||
//#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION
|
||||
//#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION
|
||||
//#define IMGUI_DISABLE_STB_SPRINTF_IMPLEMENTATION // only disabled if IMGUI_USE_STB_SPRINTF is defined.
|
||||
|
||||
//---- Use stb_sprintf.h for a faster implementation of vsnprintf instead of the one from libc (unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined)
|
||||
// Compatibility checks of arguments and formats done by clang and GCC will be disabled in order to support the extra formats provided by stb_sprintf.h.
|
||||
//#define IMGUI_USE_STB_SPRINTF
|
||||
|
||||
//---- Use FreeType to build and rasterize the font atlas (instead of stb_truetype which is embedded by default in Dear ImGui)
|
||||
// Requires FreeType headers to be available in the include path. Requires program to be compiled with 'misc/freetype/imgui_freetype.cpp' (in this repository) + the FreeType library (not provided).
|
||||
// On Windows you may use vcpkg with 'vcpkg install freetype --triplet=x64-windows' + 'vcpkg integrate install'.
|
||||
#define IMGUI_ENABLE_FREETYPE
|
||||
|
||||
//---- Use FreeType + plutosvg or lunasvg to render OpenType SVG fonts (SVGinOT)
|
||||
// Only works in combination with IMGUI_ENABLE_FREETYPE.
|
||||
// - plutosvg is currently easier to install, as e.g. it is part of vcpkg. It will support more fonts and may load them faster. See misc/freetype/README for instructions.
|
||||
// - Both require headers to be available in the include path + program to be linked with the library code (not provided).
|
||||
// - (note: lunasvg implementation is based on Freetype's rsvg-port.c which is licensed under CeCILL-C Free Software License Agreement)
|
||||
//#define IMGUI_ENABLE_FREETYPE_PLUTOSVG
|
||||
//#define IMGUI_ENABLE_FREETYPE_LUNASVG
|
||||
|
||||
//---- Use stb_truetype to build and rasterize the font atlas (default)
|
||||
// The only purpose of this define is if you want force compilation of the stb_truetype backend ALONG with the FreeType backend.
|
||||
//#define IMGUI_ENABLE_STB_TRUETYPE
|
||||
|
||||
//---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4.
|
||||
// This will be inlined as part of ImVec2 and ImVec4 class declarations.
|
||||
/*
|
||||
#define IM_VEC2_CLASS_EXTRA \
|
||||
constexpr ImVec2(const MyVec2& f) : x(f.x), y(f.y) {} \
|
||||
operator MyVec2() const { return MyVec2(x,y); }
|
||||
|
||||
#define IM_VEC4_CLASS_EXTRA \
|
||||
constexpr ImVec4(const MyVec4& f) : x(f.x), y(f.y), z(f.z), w(f.w) {} \
|
||||
operator MyVec4() const { return MyVec4(x,y,z,w); }
|
||||
*/
|
||||
//---- ...Or use Dear ImGui's own very basic math operators.
|
||||
//#define IMGUI_DEFINE_MATH_OPERATORS
|
||||
|
||||
//---- Use 32-bit vertex indices (default is 16-bit) is one way to allow large meshes with more than 64K vertices.
|
||||
// Your renderer backend will need to support it (most example renderer backends support both 16/32-bit indices).
|
||||
// Another way to allow large meshes while keeping 16-bit indices is to handle ImDrawCmd::VtxOffset in your renderer.
|
||||
// Read about ImGuiBackendFlags_RendererHasVtxOffset for details.
|
||||
//#define ImDrawIdx unsigned int
|
||||
|
||||
//---- Override ImDrawCallback signature (will need to modify renderer backends accordingly)
|
||||
//struct ImDrawList;
|
||||
//struct ImDrawCmd;
|
||||
//typedef void (*MyImDrawCallback)(const ImDrawList* draw_list, const ImDrawCmd* cmd, void* my_renderer_user_data);
|
||||
//#define ImDrawCallback MyImDrawCallback
|
||||
|
||||
//---- Debug Tools: Macro to break in Debugger (we provide a default implementation of this in the codebase)
|
||||
// (use 'Metrics->Tools->Item Picker' to pick widgets with the mouse and break into them for easy debugging.)
|
||||
//#define IM_DEBUG_BREAK IM_ASSERT(0)
|
||||
//#define IM_DEBUG_BREAK __debugbreak()
|
||||
|
||||
//---- Debug Tools: Enable highlight ID conflicts _before_ hovering items. When io.ConfigDebugHighlightIdConflicts is set.
|
||||
// (THIS WILL SLOW DOWN DEAR IMGUI. Only use occasionally and disable after use)
|
||||
//#define IMGUI_DEBUG_HIGHLIGHT_ALL_ID_CONFLICTS
|
||||
|
||||
//---- Debug Tools: Enable slower asserts
|
||||
//#define IMGUI_DEBUG_PARANOID
|
||||
|
||||
//---- Tip: You can add extra functions within the ImGui:: namespace from anywhere (e.g. your own sources/header files)
|
||||
/*
|
||||
namespace ImGui
|
||||
{
|
||||
void MyFunction(const char* name, MyMatrix44* mtx);
|
||||
}
|
||||
*/
|
||||
// clang-format on
|
||||
2
external/maplibre-native
vendored
|
|
@ -1 +1 @@
|
|||
Subproject commit 3d4ca3fdf07c50db3002b11bff93c81ec380e493
|
||||
Subproject commit 3654f5fa9f06534d7fd2d95b810049a82e5953ef
|
||||
2
external/maplibre-native-qt
vendored
|
|
@ -1 +1 @@
|
|||
Subproject commit 805ccf6204a546e43fed599631ad5d698f68ae86
|
||||
Subproject commit 8b40697895c19da4479cd037a76608f4c36935e8
|
||||
19
external/maplibre-native-qt.cmake
vendored
|
|
@ -1,4 +1,4 @@
|
|||
cmake_minimum_required(VERSION 3.20)
|
||||
cmake_minimum_required(VERSION 3.24)
|
||||
set(PROJECT_NAME scwx-mln)
|
||||
|
||||
set(gtest_disable_pthreads ON)
|
||||
|
|
@ -19,11 +19,28 @@ if (MSVC)
|
|||
target_link_options(MLNQtCore PRIVATE "$<$<CONFIG:Release>:/DEBUG>")
|
||||
target_link_options(MLNQtCore PRIVATE "$<$<CONFIG:Release>:/OPT:REF>")
|
||||
target_link_options(MLNQtCore PRIVATE "$<$<CONFIG:Release>:/OPT:ICF>")
|
||||
|
||||
# Enable multi-processor compilation
|
||||
target_compile_options(MLNQtCore PRIVATE "/MP")
|
||||
target_compile_options(mbgl-core PRIVATE "/MP")
|
||||
target_compile_options(mbgl-vendor-csscolorparser PRIVATE "/MP")
|
||||
target_compile_options(mbgl-vendor-nunicode PRIVATE "/MP")
|
||||
target_compile_options(mbgl-vendor-parsedate PRIVATE "/MP")
|
||||
|
||||
if (TARGET mbgl-vendor-sqlite)
|
||||
target_compile_options(mbgl-vendor-sqlite PRIVATE "/MP")
|
||||
endif()
|
||||
else()
|
||||
target_compile_options(mbgl-core PRIVATE "$<$<CONFIG:Release>:-g>")
|
||||
target_compile_options(MLNQtCore PRIVATE "$<$<CONFIG:Release>:-g>")
|
||||
endif()
|
||||
|
||||
if (APPLE)
|
||||
# Enable GL check error debug
|
||||
target_compile_definitions(mbgl-core PRIVATE MLN_GL_CHECK_ERRORS=1)
|
||||
target_compile_definitions(MLNQtCore PRIVATE MLN_GL_CHECK_ERRORS=1)
|
||||
endif()
|
||||
|
||||
set(MLN_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/maplibre-native/include
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/maplibre-native-qt/src/core/include
|
||||
${CMAKE_CURRENT_BINARY_DIR}/maplibre-native-qt/src/core/include PARENT_SCOPE)
|
||||
|
|
|
|||
1
external/qt6ct
vendored
Submodule
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 2c569c6c4776ea5a1299030c079b16f70473c9e6
|
||||
62
external/qt6ct.cmake
vendored
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
cmake_minimum_required(VERSION 3.16.0)
|
||||
set(PROJECT_NAME scwx-qt6ct)
|
||||
|
||||
find_package(QT NAMES Qt6
|
||||
COMPONENTS Gui Widgets
|
||||
REQUIRED)
|
||||
find_package(Qt${QT_VERSION_MAJOR}
|
||||
COMPONENTS Gui Widgets
|
||||
REQUIRED)
|
||||
|
||||
#extract version from qt6ct.h
|
||||
file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/qt6ct/src/qt6ct-common/qt6ct.h"
|
||||
QT6CT_VERSION_DATA REGEX "^#define[ \t]+QT6CT_VERSION_[A-Z]+[ \t]+[0-9]+.*$")
|
||||
|
||||
if(QT6CT_VERSION_DATA)
|
||||
foreach(item IN ITEMS MAJOR MINOR)
|
||||
string(REGEX REPLACE ".*#define[ \t]+QT6CT_VERSION_${item}[ \t]+([0-9]+).*"
|
||||
"\\1" QT6CT_VERSION_${item} ${QT6CT_VERSION_DATA})
|
||||
endforeach()
|
||||
set(QT6CT_VERSION "${QT6CT_VERSION_MAJOR}.${QT6CT_VERSION_MINOR}")
|
||||
set(QT6CT_SOVERSION "${QT6CT_VERSION_MAJOR}")
|
||||
message(STATUS "qt6ct version: ${QT6CT_VERSION}")
|
||||
else()
|
||||
message(FATAL_ERROR "invalid header")
|
||||
endif()
|
||||
|
||||
set(qt6ct-common-source
|
||||
qt6ct/src/qt6ct-common/qt6ct.cpp
|
||||
)
|
||||
|
||||
set(qt6ct-widgets-source
|
||||
qt6ct/src/qt6ct/paletteeditdialog.cpp
|
||||
qt6ct/src/qt6ct/paletteeditdialog.ui
|
||||
)
|
||||
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
|
||||
include_directories(qt6ct/src/qt6ct-common)
|
||||
|
||||
add_library(qt6ct-common STATIC ${qt6ct-common-source})
|
||||
set_target_properties(qt6ct-common PROPERTIES VERSION ${QT6CT_VERSION})
|
||||
target_link_libraries(qt6ct-common PRIVATE Qt6::Gui)
|
||||
target_compile_definitions(qt6ct-common PRIVATE QT6CT_LIBRARY)
|
||||
|
||||
add_library(qt6ct-widgets STATIC ${qt6ct-widgets-source})
|
||||
set_target_properties(qt6ct-widgets PROPERTIES VERSION ${QT6CT_VERSION})
|
||||
target_link_libraries(qt6ct-widgets PRIVATE Qt6::Widgets qt6ct-common)
|
||||
target_compile_definitions(qt6ct-widgets PRIVATE QT6CT_LIBRARY)
|
||||
|
||||
if (MSVC)
|
||||
# Produce PDB file for debug
|
||||
target_compile_options(qt6ct-common PRIVATE "$<$<CONFIG:Release>:/Zi>")
|
||||
target_compile_options(qt6ct-widgets PRIVATE "$<$<CONFIG:Release>:/Zi>")
|
||||
else()
|
||||
target_compile_options(qt6ct-common PRIVATE "$<$<CONFIG:Release>:-g>")
|
||||
target_compile_options(qt6ct-widgets PRIVATE "$<$<CONFIG:Release>:-g>")
|
||||
endif()
|
||||
|
||||
target_include_directories( qt6ct-common INTERFACE qt6ct/src )
|
||||
target_include_directories( qt6ct-widgets INTERFACE qt6ct/src )
|
||||
2
external/stb
vendored
|
|
@ -1 +1 @@
|
|||
Subproject commit beebb24b945efdea3b9bba23affb8eb3ba8982e7
|
||||
Subproject commit f58f558c120e9b32c217290b80bad1a0729fbb2c
|
||||
2
external/stb.cmake
vendored
|
|
@ -1,4 +1,4 @@
|
|||
cmake_minimum_required(VERSION 3.20)
|
||||
cmake_minimum_required(VERSION 3.24)
|
||||
set(PROJECT_NAME scwx-stb)
|
||||
|
||||
set(STB_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/stb PARENT_SCOPE)
|
||||
|
|
|
|||
2
external/textflowcpp.cmake
vendored
|
|
@ -1,4 +1,4 @@
|
|||
cmake_minimum_required(VERSION 3.20)
|
||||
cmake_minimum_required(VERSION 3.24)
|
||||
set(PROJECT_NAME scwx-textflowcpp)
|
||||
|
||||
set(TEXTFLOWCPP_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/textflowcpp PARENT_SCOPE)
|
||||
|
|
|
|||
2
external/units.cmake
vendored
|
|
@ -1,4 +1,4 @@
|
|||
cmake_minimum_required(VERSION 3.20)
|
||||
cmake_minimum_required(VERSION 3.24)
|
||||
set(PROJECT_NAME scwx-units)
|
||||
|
||||
add_subdirectory(units)
|
||||
|
|
|
|||
3
requirements.txt
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
conan
|
||||
geopandas
|
||||
GitPython
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
cmake_minimum_required(VERSION 3.21)
|
||||
cmake_minimum_required(VERSION 3.24)
|
||||
|
||||
set_property(DIRECTORY
|
||||
APPEND
|
||||
|
|
|
|||
|
|
@ -26,6 +26,9 @@ void main()
|
|||
// Always set displayed to true
|
||||
vsOut.displayed = 1;
|
||||
|
||||
// Initialize texCoord to default value
|
||||
vsOut.texCoord = vec3(0.0f, 0.0f, 0.0f);
|
||||
|
||||
// Pass the threshold and time range to the geometry shader
|
||||
vsOut.threshold = aThreshold;
|
||||
vsOut.timeRange = aTimeRange;
|
||||
|
|
|
|||
|
|
@ -9,14 +9,14 @@ uniform float uDataMomentScale;
|
|||
|
||||
uniform bool uCFPEnabled;
|
||||
|
||||
flat in uint dataMoment;
|
||||
flat in uint cfpMoment;
|
||||
in float dataMoment;
|
||||
in float cfpMoment;
|
||||
|
||||
layout (location = 0) out vec4 fragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
float texCoord = float(dataMoment - uDataMomentOffset) / uDataMomentScale;
|
||||
float texCoord = (dataMoment - float(uDataMomentOffset)) / uDataMomentScale;
|
||||
|
||||
if (uCFPEnabled && cfpMoment > 8u)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ layout (location = 2) in uint aCfpMoment;
|
|||
uniform mat4 uMVPMatrix;
|
||||
uniform vec2 uMapScreenCoord;
|
||||
|
||||
flat out uint dataMoment;
|
||||
flat out uint cfpMoment;
|
||||
out float dataMoment;
|
||||
out float cfpMoment;
|
||||
|
||||
vec2 latLngToScreenCoordinate(in vec2 latLng)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -21,7 +21,9 @@ smooth out vec4 color;
|
|||
void main()
|
||||
{
|
||||
if (gsIn[0].displayed != 0 &&
|
||||
(gsIn[0].threshold <= 0 || // If Threshold: 0 was specified, no threshold
|
||||
(gsIn[0].threshold == 0 || // If Threshold: 0 was specified, no threshold
|
||||
uMapDistance == 0 || // If uMapDistance is zero, threshold is disabled
|
||||
(gsIn[0].threshold < 0 && -(gsIn[0].threshold) <= uMapDistance) || // If Threshold is negative and below current map distance
|
||||
gsIn[0].threshold >= uMapDistance || // If Threshold is above current map distance
|
||||
gsIn[0].threshold >= 999) && // If Threshold: 999 was specified (or greater), no threshold
|
||||
(gsIn[0].timeRange[0] == 0 || // If there is no start time specified
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@
|
|||
{ "type": "wsr88d", "id": "KLVX", "lat": 37.9753058, "lon": -85.9438455, "country": "USA", "state": "KY", "place": "Louisville", "tz": "America/New_York", "elevation": 833.0 },
|
||||
{ "type": "wsr88d", "id": "KPAH", "lat": 37.068333, "lon": -88.771944, "country": "USA", "state": "KY", "place": "Paducah", "tz": "America/Chicago", "elevation": 506.0 },
|
||||
{ "type": "wsr88d", "id": "KPOE", "lat": 31.1556923, "lon": -92.9762596, "country": "USA", "state": "LA", "place": "Fort Polk", "tz": "America/Chicago", "elevation": 473.0 },
|
||||
{ "type": "wsr88d", "id": "KHDC", "lat": 30.519306, "lon": -90.424028, "country": "USA", "state": "LA", "place": "New Orleans (Hammond)", "tz": "America/Chicago", "elevation": 43.0 },
|
||||
{ "type": "wsr88d", "id": "KHDC", "lat": 30.5196, "lon": -90.4074, "country": "USA", "state": "LA", "place": "New Orleans (Hammond)", "tz": "America/Chicago", "elevation": 43.0 },
|
||||
{ "type": "wsr88d", "id": "KLCH", "lat": 30.125306, "lon": -93.215889, "country": "USA", "state": "LA", "place": "Lake Charles", "tz": "America/Chicago", "elevation": 137.0 },
|
||||
{ "type": "wsr88d", "id": "KSHV", "lat": 32.450833, "lon": -93.84125, "country": "USA", "state": "LA", "place": "Shreveport", "tz": "America/Chicago", "elevation": 387.0 },
|
||||
{ "type": "wsr88d", "id": "KLIX", "lat": 30.3367133, "lon": -89.8256618, "country": "USA", "state": "LA", "place": "New Orleans (Slidell)", "tz": "America/Chicago", "elevation": 179.0 },
|
||||
|
|
|
|||
1
scwx-qt/res/icons/font-awesome-6/briefcase-solid.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 512 512"><!--!Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path fill="#ffffff" d="M184 48l144 0c4.4 0 8 3.6 8 8l0 40L176 96l0-40c0-4.4 3.6-8 8-8zm-56 8l0 40L64 96C28.7 96 0 124.7 0 160l0 96 192 0 128 0 192 0 0-96c0-35.3-28.7-64-64-64l-64 0 0-40c0-30.9-25.1-56-56-56L184 0c-30.9 0-56 25.1-56 56zM512 288l-192 0 0 32c0 17.7-14.3 32-32 32l-64 0c-17.7 0-32-14.3-32-32l0-32L0 288 0 416c0 35.3 28.7 64 64 64l384 0c35.3 0 64-28.7 64-64l0-128z"/></svg>
|
||||
|
After Width: | Height: | Size: 623 B |
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 512 512"><!--!Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path fill="#ffffff" d="M243.4 2.6l-224 96c-14 6-21.8 21-18.7 35.8S16.8 160 32 160l0 8c0 13.3 10.7 24 24 24l400 0c13.3 0 24-10.7 24-24l0-8c15.2 0 28.3-10.7 31.3-25.6s-4.8-29.9-18.7-35.8l-224-96c-8-3.4-17.2-3.4-25.2 0zM128 224l-64 0 0 196.3c-.6 .3-1.2 .7-1.8 1.1l-48 32c-11.7 7.8-17 22.4-12.9 35.9S17.9 512 32 512l448 0c14.1 0 26.5-9.2 30.6-22.7s-1.1-28.1-12.9-35.9l-48-32c-.6-.4-1.2-.7-1.8-1.1L448 224l-64 0 0 192-40 0 0-192-64 0 0 192-48 0 0-192-64 0 0 192-40 0 0-192zM256 64a32 32 0 1 1 0 64 32 32 0 1 1 0-64z"/></svg>
|
||||
|
After Width: | Height: | Size: 757 B |
1
scwx-qt/res/icons/font-awesome-6/building-solid.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="16" viewBox="0 0 384 512"><!--!Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path fill="#ffffff" d="M48 0C21.5 0 0 21.5 0 48L0 464c0 26.5 21.5 48 48 48l96 0 0-80c0-26.5 21.5-48 48-48s48 21.5 48 48l0 80 96 0c26.5 0 48-21.5 48-48l0-416c0-26.5-21.5-48-48-48L48 0zM64 240c0-8.8 7.2-16 16-16l32 0c8.8 0 16 7.2 16 16l0 32c0 8.8-7.2 16-16 16l-32 0c-8.8 0-16-7.2-16-16l0-32zm112-16l32 0c8.8 0 16 7.2 16 16l0 32c0 8.8-7.2 16-16 16l-32 0c-8.8 0-16-7.2-16-16l0-32c0-8.8 7.2-16 16-16zm80 16c0-8.8 7.2-16 16-16l32 0c8.8 0 16 7.2 16 16l0 32c0 8.8-7.2 16-16 16l-32 0c-8.8 0-16-7.2-16-16l0-32zM80 96l32 0c8.8 0 16 7.2 16 16l0 32c0 8.8-7.2 16-16 16l-32 0c-8.8 0-16-7.2-16-16l0-32c0-8.8 7.2-16 16-16zm80 16c0-8.8 7.2-16 16-16l32 0c8.8 0 16 7.2 16 16l0 32c0 8.8-7.2 16-16 16l-32 0c-8.8 0-16-7.2-16-16l0-32zM272 96l32 0c8.8 0 16 7.2 16 16l0 32c0 8.8-7.2 16-16 16l-32 0c-8.8 0-16-7.2-16-16l0-32c0-8.8 7.2-16 16-16z"/></svg>
|
||||
|
After Width: | Height: | Size: 1 KiB |
1
scwx-qt/res/icons/font-awesome-6/caravan-solid.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="16" viewBox="0 0 640 512"><!--!Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path fill="#ffffff" d="M0 112C0 67.8 35.8 32 80 32l336 0c88.4 0 160 71.6 160 160l0 160 32 0c17.7 0 32 14.3 32 32s-14.3 32-32 32l-32 0-288 0c0 53-43 96-96 96s-96-43-96-96l-16 0c-44.2 0-80-35.8-80-80L0 112zM320 352l128 0 0-96-32 0c-8.8 0-16-7.2-16-16s7.2-16 16-16l32 0 0-64c0-17.7-14.3-32-32-32l-64 0c-17.7 0-32 14.3-32 32l0 192zM96 128c-17.7 0-32 14.3-32 32l0 64c0 17.7 14.3 32 32 32l128 0c17.7 0 32-14.3 32-32l0-64c0-17.7-14.3-32-32-32L96 128zm96 336a48 48 0 1 0 0-96 48 48 0 1 0 0 96z"/></svg>
|
||||
|
After Width: | Height: | Size: 732 B |
1
scwx-qt/res/icons/font-awesome-6/house-solid-white.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="18" viewBox="0 0 576 512"><!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2023 Fonticons, Inc.--><path opacity="1" fill="#ffffff" d="M575.8 255.5c0 18-15 32.1-32 32.1h-32l.7 160.2c0 2.7-.2 5.4-.5 8.1V472c0 22.1-17.9 40-40 40H456c-1.1 0-2.2 0-3.3-.1c-1.4 .1-2.8 .1-4.2 .1H416 392c-22.1 0-40-17.9-40-40V448 384c0-17.7-14.3-32-32-32H256c-17.7 0-32 14.3-32 32v64 24c0 22.1-17.9 40-40 40H160 128.1c-1.5 0-3-.1-4.5-.2c-1.2 .1-2.4 .2-3.6 .2H104c-22.1 0-40-17.9-40-40V360c0-.9 0-1.9 .1-2.8V287.6H32c-18 0-32-14-32-32.1c0-9 3-17 10-24L266.4 8c7-7 15-8 22-8s15 2 21 7L564.8 231.5c8 7 12 15 11 24z"/></svg>
|
||||
|
After Width: | Height: | Size: 735 B |
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 512 512"><!--!Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path fill="#ffffff" d="M256 0c17.7 0 32 14.3 32 32l0 34.7C368.4 80.1 431.9 143.6 445.3 224l34.7 0c17.7 0 32 14.3 32 32s-14.3 32-32 32l-34.7 0C431.9 368.4 368.4 431.9 288 445.3l0 34.7c0 17.7-14.3 32-32 32s-32-14.3-32-32l0-34.7C143.6 431.9 80.1 368.4 66.7 288L32 288c-17.7 0-32-14.3-32-32s14.3-32 32-32l34.7 0C80.1 143.6 143.6 80.1 224 66.7L224 32c0-17.7 14.3-32 32-32zM128 256a128 128 0 1 0 256 0 128 128 0 1 0 -256 0zm128-80a80 80 0 1 1 0 160 80 80 0 1 1 0-160z"/></svg>
|
||||
|
After Width: | Height: | Size: 708 B |
4
scwx-qt/res/icons/font-awesome-6/location-pin.svg
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="12" height="16" viewBox="0 0 384 512">
|
||||
<!--!Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.-->
|
||||
<path fill="#ffffff" d="M215.7 499.2C267 435 384 279.4 384 192C384 86 298 0 192 0S0 86 0 192c0 87.4 117 243 168.3 307.2c12.3 15.3 35.1 15.3 47.4 0zM192 128a64 64 0 1 1 0 128 64 64 0 1 1 0-128z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 463 B |
1
scwx-qt/res/icons/font-awesome-6/star-solid-white.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="18" viewBox="0 0 576 512"><!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2023 Fonticons, Inc.--><path opacity="1" fill="#ffffff" d="M316.9 18C311.6 7 300.4 0 288.1 0s-23.4 7-28.8 18L195 150.3 51.4 171.5c-12 1.8-22 10.2-25.7 21.7s-.7 24.2 7.9 32.7L137.8 329 113.2 474.7c-2 12 3 24.2 12.9 31.3s23 8 33.8 2.3l128.3-68.5 128.3 68.5c10.8 5.7 23.9 4.9 33.8-2.3s14.9-19.3 12.9-31.3L438.5 329 542.7 225.9c8.6-8.5 11.7-21.2 7.9-32.7s-13.7-19.9-25.7-21.7L381.2 150.3 316.9 18z"/></svg>
|
||||
|
After Width: | Height: | Size: 616 B |
1
scwx-qt/res/icons/font-awesome-6/tent-solid.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="16" viewBox="0 0 576 512"><!--!Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path fill="#ffffff" d="M269.4 6C280.5-2 295.5-2 306.6 6l224 160c7.4 5.3 12.2 13.5 13.2 22.5l32 288c1 9-1.9 18.1-8 24.9s-14.7 10.7-23.8 10.7l-80 0-28.2 0c-12.1 0-23.2-6.8-28.6-17.7L306.7 293.5c-1.7-3.4-5.1-5.5-8.8-5.5c-5.5 0-9.9 4.4-9.9 9.9L288 480c0 17.7-14.3 32-32 32l-16 0L32 512c-9.1 0-17.8-3.9-23.8-10.7s-9-15.8-8-24.9l32-288c1-9 5.8-17.2 13.2-22.5L269.4 6z"/></svg>
|
||||
|
After Width: | Height: | Size: 608 B |
BIN
scwx-qt/res/icons/scwx.icns
Normal file
7
scwx-qt/res/linux/net.supercellwx.app.desktop
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
[Desktop Entry]
|
||||
Type=Application
|
||||
Name=Supercell Wx
|
||||
Comment=Weather Radar and Data Viewer
|
||||
Exec=supercell-wx
|
||||
Icon=net.supercellwx.app.png
|
||||
Categories=Network;Science;
|
||||
42
scwx-qt/res/scwx-qt.plist.in
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
|
||||
<key>CFBundleName</key>
|
||||
<string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
|
||||
|
||||
<key>CFBundleVersion</key>
|
||||
<string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
|
||||
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>${CMAKE_OSX_DEPLOYMENT_TARGET}</string>
|
||||
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>${MACOSX_BUNDLE_COPYRIGHT}</string>
|
||||
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>${MACOSX_BUNDLE_ICON_FILE}</string>
|
||||
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleAllowMixedLocalizations</key>
|
||||
<true/>
|
||||
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
|
||||
<key>NSSupportsAutomaticGraphicsSwitching</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
9
scwx-qt/res/textures/images/dot.svg
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<svg version="1.1"
|
||||
viewBox="0 0 100 100"
|
||||
width="3" height="3"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
|
||||
<circle r="50" cx="50" cy="50" fill="black"></circle>
|
||||
<circle r="25" cx="50" cy="50" fill="white"></circle>
|
||||
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 241 B |
11
scwx-qt/res/textures/images/location-marker.svg
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<svg version="1.1"
|
||||
viewBox="0 0 170 150"
|
||||
width="17" height="15"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
|
||||
<path d="M 40,118 L 85,40 L 130,118 L 40,118 L 85,40 Z"
|
||||
stroke="black" stroke-width="40" fill="none"/>
|
||||
<path d="M 40,118 L 85,40 L 130,118 L 40,118 L 85,40 Z"
|
||||
stroke="#ffffff" stroke-width="20" fill="none"/>
|
||||
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 357 B |
|
|
@ -1,4 +1,4 @@
|
|||
cmake_minimum_required(VERSION 3.21)
|
||||
cmake_minimum_required(VERSION 3.24)
|
||||
|
||||
project(scwx-qt LANGUAGES CXX)
|
||||
|
||||
|
|
@ -6,17 +6,19 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
|||
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
set(CMAKE_AUTORCC OFF)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
OPTION(SCWX_DISABLE_CONSOLE "Disables the Windows console in release mode" ON)
|
||||
|
||||
find_package(Boost)
|
||||
find_package(Fontconfig)
|
||||
find_package(geographiclib)
|
||||
find_package(geos)
|
||||
find_package(GLEW)
|
||||
find_package(glm)
|
||||
find_package(OpenGL)
|
||||
find_package(Python COMPONENTS Interpreter)
|
||||
find_package(SQLite3)
|
||||
|
||||
|
|
@ -30,7 +32,9 @@ find_package(QT NAMES Qt6
|
|||
Positioning
|
||||
SerialPort
|
||||
Svg
|
||||
Widgets REQUIRED)
|
||||
Widgets
|
||||
Sql
|
||||
REQUIRED)
|
||||
|
||||
find_package(Qt${QT_VERSION_MAJOR}
|
||||
COMPONENTS Gui
|
||||
|
|
@ -49,9 +53,13 @@ find_package(Qt${QT_VERSION_MAJOR}
|
|||
set(SRC_EXE_MAIN source/scwx/qt/main/main.cpp)
|
||||
|
||||
set(HDR_MAIN source/scwx/qt/main/application.hpp
|
||||
source/scwx/qt/main/main_window.hpp)
|
||||
source/scwx/qt/main/check_privilege.hpp
|
||||
source/scwx/qt/main/main_window.hpp
|
||||
source/scwx/qt/main/process_validation.hpp)
|
||||
set(SRC_MAIN source/scwx/qt/main/application.cpp
|
||||
source/scwx/qt/main/main_window.cpp)
|
||||
source/scwx/qt/main/check_privilege.cpp
|
||||
source/scwx/qt/main/main_window.cpp
|
||||
source/scwx/qt/main/process_validation.cpp)
|
||||
set(UI_MAIN source/scwx/qt/main/main_window.ui)
|
||||
set(HDR_CONFIG source/scwx/qt/config/county_database.hpp
|
||||
source/scwx/qt/config/radar_site.hpp)
|
||||
|
|
@ -95,11 +103,13 @@ set(HDR_MANAGER source/scwx/qt/manager/alert_manager.hpp
|
|||
source/scwx/qt/manager/log_manager.hpp
|
||||
source/scwx/qt/manager/media_manager.hpp
|
||||
source/scwx/qt/manager/placefile_manager.hpp
|
||||
source/scwx/qt/manager/marker_manager.hpp
|
||||
source/scwx/qt/manager/position_manager.hpp
|
||||
source/scwx/qt/manager/radar_product_manager.hpp
|
||||
source/scwx/qt/manager/radar_product_manager_notifier.hpp
|
||||
source/scwx/qt/manager/resource_manager.hpp
|
||||
source/scwx/qt/manager/settings_manager.hpp
|
||||
source/scwx/qt/manager/task_manager.hpp
|
||||
source/scwx/qt/manager/text_event_manager.hpp
|
||||
source/scwx/qt/manager/thread_manager.hpp
|
||||
source/scwx/qt/manager/timeline_manager.hpp
|
||||
|
|
@ -111,11 +121,13 @@ set(SRC_MANAGER source/scwx/qt/manager/alert_manager.cpp
|
|||
source/scwx/qt/manager/log_manager.cpp
|
||||
source/scwx/qt/manager/media_manager.cpp
|
||||
source/scwx/qt/manager/placefile_manager.cpp
|
||||
source/scwx/qt/manager/marker_manager.cpp
|
||||
source/scwx/qt/manager/position_manager.cpp
|
||||
source/scwx/qt/manager/radar_product_manager.cpp
|
||||
source/scwx/qt/manager/radar_product_manager_notifier.cpp
|
||||
source/scwx/qt/manager/resource_manager.cpp
|
||||
source/scwx/qt/manager/settings_manager.cpp
|
||||
source/scwx/qt/manager/task_manager.cpp
|
||||
source/scwx/qt/manager/text_event_manager.cpp
|
||||
source/scwx/qt/manager/thread_manager.cpp
|
||||
source/scwx/qt/manager/timeline_manager.cpp
|
||||
|
|
@ -132,6 +144,7 @@ set(HDR_MAP source/scwx/qt/map/alert_layer.hpp
|
|||
source/scwx/qt/map/overlay_layer.hpp
|
||||
source/scwx/qt/map/overlay_product_layer.hpp
|
||||
source/scwx/qt/map/placefile_layer.hpp
|
||||
source/scwx/qt/map/marker_layer.hpp
|
||||
source/scwx/qt/map/radar_product_layer.hpp
|
||||
source/scwx/qt/map/radar_range_layer.hpp
|
||||
source/scwx/qt/map/radar_site_layer.hpp)
|
||||
|
|
@ -146,6 +159,7 @@ set(SRC_MAP source/scwx/qt/map/alert_layer.cpp
|
|||
source/scwx/qt/map/overlay_layer.cpp
|
||||
source/scwx/qt/map/overlay_product_layer.cpp
|
||||
source/scwx/qt/map/placefile_layer.cpp
|
||||
source/scwx/qt/map/marker_layer.cpp
|
||||
source/scwx/qt/map/radar_product_layer.cpp
|
||||
source/scwx/qt/map/radar_range_layer.cpp
|
||||
source/scwx/qt/map/radar_site_layer.cpp)
|
||||
|
|
@ -154,6 +168,7 @@ set(HDR_MODEL source/scwx/qt/model/alert_model.hpp
|
|||
source/scwx/qt/model/imgui_context_model.hpp
|
||||
source/scwx/qt/model/layer_model.hpp
|
||||
source/scwx/qt/model/placefile_model.hpp
|
||||
source/scwx/qt/model/marker_model.hpp
|
||||
source/scwx/qt/model/radar_site_model.hpp
|
||||
source/scwx/qt/model/tree_item.hpp
|
||||
source/scwx/qt/model/tree_model.hpp)
|
||||
|
|
@ -162,6 +177,7 @@ set(SRC_MODEL source/scwx/qt/model/alert_model.cpp
|
|||
source/scwx/qt/model/imgui_context_model.cpp
|
||||
source/scwx/qt/model/layer_model.cpp
|
||||
source/scwx/qt/model/placefile_model.cpp
|
||||
source/scwx/qt/model/marker_model.cpp
|
||||
source/scwx/qt/model/radar_site_model.cpp
|
||||
source/scwx/qt/model/tree_item.cpp
|
||||
source/scwx/qt/model/tree_model.cpp)
|
||||
|
|
@ -169,9 +185,11 @@ set(HDR_REQUEST source/scwx/qt/request/download_request.hpp
|
|||
source/scwx/qt/request/nexrad_file_request.hpp)
|
||||
set(SRC_REQUEST source/scwx/qt/request/download_request.cpp
|
||||
source/scwx/qt/request/nexrad_file_request.cpp)
|
||||
set(HDR_SETTINGS source/scwx/qt/settings/audio_settings.hpp
|
||||
set(HDR_SETTINGS source/scwx/qt/settings/alert_palette_settings.hpp
|
||||
source/scwx/qt/settings/audio_settings.hpp
|
||||
source/scwx/qt/settings/general_settings.hpp
|
||||
source/scwx/qt/settings/hotkey_settings.hpp
|
||||
source/scwx/qt/settings/line_settings.hpp
|
||||
source/scwx/qt/settings/map_settings.hpp
|
||||
source/scwx/qt/settings/palette_settings.hpp
|
||||
source/scwx/qt/settings/product_settings.hpp
|
||||
|
|
@ -185,9 +203,11 @@ set(HDR_SETTINGS source/scwx/qt/settings/audio_settings.hpp
|
|||
source/scwx/qt/settings/text_settings.hpp
|
||||
source/scwx/qt/settings/ui_settings.hpp
|
||||
source/scwx/qt/settings/unit_settings.hpp)
|
||||
set(SRC_SETTINGS source/scwx/qt/settings/audio_settings.cpp
|
||||
set(SRC_SETTINGS source/scwx/qt/settings/alert_palette_settings.cpp
|
||||
source/scwx/qt/settings/audio_settings.cpp
|
||||
source/scwx/qt/settings/general_settings.cpp
|
||||
source/scwx/qt/settings/hotkey_settings.cpp
|
||||
source/scwx/qt/settings/line_settings.cpp
|
||||
source/scwx/qt/settings/map_settings.cpp
|
||||
source/scwx/qt/settings/palette_settings.cpp
|
||||
source/scwx/qt/settings/product_settings.cpp
|
||||
|
|
@ -210,6 +230,7 @@ set(HDR_TYPES source/scwx/qt/types/alert_types.hpp
|
|||
source/scwx/qt/types/layer_types.hpp
|
||||
source/scwx/qt/types/location_types.hpp
|
||||
source/scwx/qt/types/map_types.hpp
|
||||
source/scwx/qt/types/marker_types.hpp
|
||||
source/scwx/qt/types/media_types.hpp
|
||||
source/scwx/qt/types/qt_types.hpp
|
||||
source/scwx/qt/types/radar_product_record.hpp
|
||||
|
|
@ -238,10 +259,13 @@ set(HDR_UI source/scwx/qt/ui/about_dialog.hpp
|
|||
source/scwx/qt/ui/alert_dialog.hpp
|
||||
source/scwx/qt/ui/alert_dock_widget.hpp
|
||||
source/scwx/qt/ui/animation_dock_widget.hpp
|
||||
source/scwx/qt/ui/api_key_edit_widget.hpp
|
||||
source/scwx/qt/ui/collapsible_group.hpp
|
||||
source/scwx/qt/ui/county_dialog.hpp
|
||||
source/scwx/qt/ui/wfo_dialog.hpp
|
||||
source/scwx/qt/ui/custom_layer_dialog.hpp
|
||||
source/scwx/qt/ui/download_dialog.hpp
|
||||
source/scwx/qt/ui/edit_line_dialog.hpp
|
||||
source/scwx/qt/ui/edit_marker_dialog.hpp
|
||||
source/scwx/qt/ui/flow_layout.hpp
|
||||
source/scwx/qt/ui/gps_info_dialog.hpp
|
||||
source/scwx/qt/ui/hotkey_edit.hpp
|
||||
|
|
@ -252,22 +276,29 @@ set(HDR_UI source/scwx/qt/ui/about_dialog.hpp
|
|||
source/scwx/qt/ui/level2_products_widget.hpp
|
||||
source/scwx/qt/ui/level2_settings_widget.hpp
|
||||
source/scwx/qt/ui/level3_products_widget.hpp
|
||||
source/scwx/qt/ui/line_label.hpp
|
||||
source/scwx/qt/ui/open_url_dialog.hpp
|
||||
source/scwx/qt/ui/placefile_dialog.hpp
|
||||
source/scwx/qt/ui/placefile_settings_widget.hpp
|
||||
source/scwx/qt/ui/marker_dialog.hpp
|
||||
source/scwx/qt/ui/marker_settings_widget.hpp
|
||||
source/scwx/qt/ui/progress_dialog.hpp
|
||||
source/scwx/qt/ui/radar_site_dialog.hpp
|
||||
source/scwx/qt/ui/serial_port_dialog.hpp
|
||||
source/scwx/qt/ui/settings_dialog.hpp
|
||||
source/scwx/qt/ui/update_dialog.hpp)
|
||||
source/scwx/qt/ui/update_dialog.hpp
|
||||
source/scwx/qt/ui/wfo_dialog.hpp)
|
||||
set(SRC_UI source/scwx/qt/ui/about_dialog.cpp
|
||||
source/scwx/qt/ui/alert_dialog.cpp
|
||||
source/scwx/qt/ui/alert_dock_widget.cpp
|
||||
source/scwx/qt/ui/animation_dock_widget.cpp
|
||||
source/scwx/qt/ui/api_key_edit_widget.cpp
|
||||
source/scwx/qt/ui/collapsible_group.cpp
|
||||
source/scwx/qt/ui/county_dialog.cpp
|
||||
source/scwx/qt/ui/wfo_dialog.cpp
|
||||
source/scwx/qt/ui/custom_layer_dialog.cpp
|
||||
source/scwx/qt/ui/download_dialog.cpp
|
||||
source/scwx/qt/ui/edit_line_dialog.cpp
|
||||
source/scwx/qt/ui/edit_marker_dialog.cpp
|
||||
source/scwx/qt/ui/flow_layout.cpp
|
||||
source/scwx/qt/ui/gps_info_dialog.cpp
|
||||
source/scwx/qt/ui/hotkey_edit.cpp
|
||||
|
|
@ -278,36 +309,47 @@ set(SRC_UI source/scwx/qt/ui/about_dialog.cpp
|
|||
source/scwx/qt/ui/level2_products_widget.cpp
|
||||
source/scwx/qt/ui/level2_settings_widget.cpp
|
||||
source/scwx/qt/ui/level3_products_widget.cpp
|
||||
source/scwx/qt/ui/line_label.cpp
|
||||
source/scwx/qt/ui/open_url_dialog.cpp
|
||||
source/scwx/qt/ui/placefile_dialog.cpp
|
||||
source/scwx/qt/ui/placefile_settings_widget.cpp
|
||||
source/scwx/qt/ui/marker_dialog.cpp
|
||||
source/scwx/qt/ui/marker_settings_widget.cpp
|
||||
source/scwx/qt/ui/progress_dialog.cpp
|
||||
source/scwx/qt/ui/radar_site_dialog.cpp
|
||||
source/scwx/qt/ui/settings_dialog.cpp
|
||||
source/scwx/qt/ui/serial_port_dialog.cpp
|
||||
source/scwx/qt/ui/update_dialog.cpp)
|
||||
source/scwx/qt/ui/update_dialog.cpp
|
||||
source/scwx/qt/ui/wfo_dialog.cpp)
|
||||
set(UI_UI source/scwx/qt/ui/about_dialog.ui
|
||||
source/scwx/qt/ui/alert_dialog.ui
|
||||
source/scwx/qt/ui/alert_dock_widget.ui
|
||||
source/scwx/qt/ui/animation_dock_widget.ui
|
||||
source/scwx/qt/ui/collapsible_group.ui
|
||||
source/scwx/qt/ui/county_dialog.ui
|
||||
source/scwx/qt/ui/wfo_dialog.ui
|
||||
source/scwx/qt/ui/custom_layer_dialog.ui
|
||||
source/scwx/qt/ui/edit_line_dialog.ui
|
||||
source/scwx/qt/ui/edit_marker_dialog.ui
|
||||
source/scwx/qt/ui/gps_info_dialog.ui
|
||||
source/scwx/qt/ui/imgui_debug_dialog.ui
|
||||
source/scwx/qt/ui/layer_dialog.ui
|
||||
source/scwx/qt/ui/open_url_dialog.ui
|
||||
source/scwx/qt/ui/placefile_dialog.ui
|
||||
source/scwx/qt/ui/placefile_settings_widget.ui
|
||||
source/scwx/qt/ui/marker_dialog.ui
|
||||
source/scwx/qt/ui/marker_settings_widget.ui
|
||||
source/scwx/qt/ui/progress_dialog.ui
|
||||
source/scwx/qt/ui/radar_site_dialog.ui
|
||||
source/scwx/qt/ui/settings_dialog.ui
|
||||
source/scwx/qt/ui/serial_port_dialog.ui
|
||||
source/scwx/qt/ui/update_dialog.ui)
|
||||
set(HDR_UI_SETTINGS source/scwx/qt/ui/settings/hotkey_settings_widget.hpp
|
||||
source/scwx/qt/ui/update_dialog.ui
|
||||
source/scwx/qt/ui/wfo_dialog.ui)
|
||||
set(HDR_UI_SETTINGS source/scwx/qt/ui/settings/alert_palette_settings_widget.hpp
|
||||
source/scwx/qt/ui/settings/hotkey_settings_widget.hpp
|
||||
source/scwx/qt/ui/settings/settings_page_widget.hpp
|
||||
source/scwx/qt/ui/settings/unit_settings_widget.hpp)
|
||||
set(SRC_UI_SETTINGS source/scwx/qt/ui/settings/hotkey_settings_widget.cpp
|
||||
set(SRC_UI_SETTINGS source/scwx/qt/ui/settings/alert_palette_settings_widget.cpp
|
||||
source/scwx/qt/ui/settings/hotkey_settings_widget.cpp
|
||||
source/scwx/qt/ui/settings/settings_page_widget.cpp
|
||||
source/scwx/qt/ui/settings/unit_settings_widget.cpp)
|
||||
set(HDR_UI_SETUP source/scwx/qt/ui/setup/audio_codec_page.hpp
|
||||
|
|
@ -322,6 +364,9 @@ set(SRC_UI_SETUP source/scwx/qt/ui/setup/audio_codec_page.cpp
|
|||
source/scwx/qt/ui/setup/map_provider_page.cpp
|
||||
source/scwx/qt/ui/setup/setup_wizard.cpp
|
||||
source/scwx/qt/ui/setup/welcome_page.cpp)
|
||||
set(HDR_UI_WIDGETS source/scwx/qt/ui/widgets/focused_combo_box.hpp
|
||||
source/scwx/qt/ui/widgets/focused_double_spin_box.hpp
|
||||
source/scwx/qt/ui/widgets/focused_spin_box.hpp)
|
||||
set(HDR_UTIL source/scwx/qt/util/color.hpp
|
||||
source/scwx/qt/util/file.hpp
|
||||
source/scwx/qt/util/geographic_lib.hpp
|
||||
|
|
@ -331,8 +376,10 @@ set(HDR_UTIL source/scwx/qt/util/color.hpp
|
|||
source/scwx/qt/util/network.hpp
|
||||
source/scwx/qt/util/streams.hpp
|
||||
source/scwx/qt/util/texture_atlas.hpp
|
||||
source/scwx/qt/util/q_color_modulate.hpp
|
||||
source/scwx/qt/util/q_file_buffer.hpp
|
||||
source/scwx/qt/util/q_file_input_stream.hpp
|
||||
source/scwx/qt/util/queue_counter.hpp
|
||||
source/scwx/qt/util/time.hpp
|
||||
source/scwx/qt/util/tooltip.hpp)
|
||||
set(SRC_UTIL source/scwx/qt/util/color.cpp
|
||||
|
|
@ -343,8 +390,10 @@ set(SRC_UTIL source/scwx/qt/util/color.cpp
|
|||
source/scwx/qt/util/maplibre.cpp
|
||||
source/scwx/qt/util/network.cpp
|
||||
source/scwx/qt/util/texture_atlas.cpp
|
||||
source/scwx/qt/util/q_color_modulate.cpp
|
||||
source/scwx/qt/util/q_file_buffer.cpp
|
||||
source/scwx/qt/util/q_file_input_stream.cpp
|
||||
source/scwx/qt/util/queue_counter.cpp
|
||||
source/scwx/qt/util/time.cpp
|
||||
source/scwx/qt/util/tooltip.cpp)
|
||||
set(HDR_VIEW source/scwx/qt/view/level2_product_view.hpp
|
||||
|
|
@ -385,13 +434,13 @@ set(JSON_FILES res/config/radar_sites.json)
|
|||
set(TS_FILES ts/scwx_en_US.ts)
|
||||
|
||||
set(RADAR_SITES_FILE ${scwx-qt_SOURCE_DIR}/res/config/radar_sites.json)
|
||||
set(COUNTY_DBF_FILES ${SCWX_DIR}/data/db/c_05mr24.dbf)
|
||||
set(ZONE_DBF_FILES ${SCWX_DIR}/data/db/fz05mr24.dbf
|
||||
${SCWX_DIR}/data/db/mz05mr24.dbf
|
||||
${SCWX_DIR}/data/db/oz05mr24.dbf
|
||||
${SCWX_DIR}/data/db/z_05mr24.dbf)
|
||||
set(STATE_DBF_FILES ${SCWX_DIR}/data/db/s_05mr24.dbf)
|
||||
set(WFO_DBF_FILES ${SCWX_DIR}/data/db/w_05mr24.dbf)
|
||||
set(COUNTY_DBF_FILES ${SCWX_DIR}/data/db/c_18mr25.dbf)
|
||||
set(ZONE_DBF_FILES ${SCWX_DIR}/data/db/fz18mr25.dbf
|
||||
${SCWX_DIR}/data/db/mz18mr25.dbf
|
||||
${SCWX_DIR}/data/db/oz18mr25.dbf
|
||||
${SCWX_DIR}/data/db/z_18mr25.dbf)
|
||||
set(STATE_DBF_FILES ${SCWX_DIR}/data/db/s_18mr25.dbf)
|
||||
set(WFO_DBF_FILES ${SCWX_DIR}/data/db/w_18mr25.dbf)
|
||||
set(COUNTIES_SQLITE_DB ${scwx-qt_BINARY_DIR}/res/db/counties.db)
|
||||
|
||||
set(RESOURCE_INPUT ${scwx-qt_SOURCE_DIR}/res/scwx-qt.rc.in)
|
||||
|
|
@ -429,17 +478,19 @@ set(PROJECT_SOURCES ${HDR_MAIN}
|
|||
${SRC_UI_SETTINGS}
|
||||
${HDR_UI_SETUP}
|
||||
${SRC_UI_SETUP}
|
||||
${HDR_UI_WIDGETS}
|
||||
${HDR_UTIL}
|
||||
${SRC_UTIL}
|
||||
${HDR_VIEW}
|
||||
${SRC_VIEW}
|
||||
${SHADER_FILES}
|
||||
${JSON_FILES}
|
||||
${RESOURCE_FILES}
|
||||
${TS_FILES}
|
||||
${CMAKE_FILES})
|
||||
set(EXECUTABLE_SOURCES ${SRC_EXE_MAIN})
|
||||
|
||||
qt_add_resources(PROJECT_SOURCES ${RESOURCE_FILES})
|
||||
|
||||
source_group("Header Files\\main" FILES ${HDR_MAIN})
|
||||
source_group("Source Files\\main" FILES ${SRC_MAIN})
|
||||
source_group("Header Files\\config" FILES ${HDR_CONFIG})
|
||||
|
|
@ -468,6 +519,7 @@ source_group("Header Files\\ui\\settings" FILES ${HDR_UI_SETTINGS})
|
|||
source_group("Source Files\\ui\\settings" FILES ${SRC_UI_SETTINGS})
|
||||
source_group("Header Files\\ui\\setup" FILES ${HDR_UI_SETUP})
|
||||
source_group("Source Files\\ui\\setup" FILES ${SRC_UI_SETUP})
|
||||
source_group("Header Files\\ui\\widgets" FILES ${HDR_UI_WIDGETS})
|
||||
source_group("UI Files\\ui" FILES ${UI_UI})
|
||||
source_group("Header Files\\util" FILES ${HDR_UTIL})
|
||||
source_group("Source Files\\util" FILES ${SRC_UTIL})
|
||||
|
|
@ -480,6 +532,7 @@ source_group("I18N Files" FILES ${TS_FILES})
|
|||
|
||||
add_library(scwx-qt OBJECT ${PROJECT_SOURCES})
|
||||
set_property(TARGET scwx-qt PROPERTY AUTOMOC ON)
|
||||
set_property(TARGET scwx-qt PROPERTY AUTOGEN_ORIGIN_DEPENDS OFF)
|
||||
|
||||
add_custom_command(OUTPUT ${COUNTIES_SQLITE_DB}
|
||||
COMMAND ${Python_EXECUTABLE}
|
||||
|
|
@ -526,7 +579,8 @@ else()
|
|||
-v ${SCWX_VERSION}
|
||||
-c ${VERSIONS_CACHE}
|
||||
-i ${VERSIONS_INPUT}
|
||||
-o ${VERSIONS_HEADER})
|
||||
-o ${VERSIONS_HEADER}
|
||||
-b ${SCWX_BUILD_NUM})
|
||||
endif()
|
||||
|
||||
add_custom_target(scwx-qt_generate_versions ALL
|
||||
|
|
@ -572,7 +626,29 @@ set_target_properties(scwx-qt_update_radar_sites PROPERTIES FOLDER generate)
|
|||
if (WIN32)
|
||||
set(APP_ICON_RESOURCE_WINDOWS ${RESOURCE_OUTPUT})
|
||||
qt_add_executable(supercell-wx ${EXECUTABLE_SOURCES} ${APP_ICON_RESOURCE_WINDOWS})
|
||||
set_target_properties(supercell-wx PROPERTIES WIN32_EXECUTABLE $<IF:$<CONFIG:Release>,TRUE,FALSE>)
|
||||
if (SCWX_DISABLE_CONSOLE)
|
||||
set_target_properties(supercell-wx PROPERTIES WIN32_EXECUTABLE $<IF:$<CONFIG:Release>,TRUE,FALSE>)
|
||||
endif()
|
||||
elseif (APPLE)
|
||||
set(SCWX_ICON "${scwx-qt_SOURCE_DIR}/res/icons/scwx.icns")
|
||||
|
||||
set_source_files_properties(${SCWX_ICON} PROPERTIES MACOSX_PACKAGE_LOCATION "Resources")
|
||||
|
||||
qt_add_executable(supercell-wx ${EXECUTABLE_SOURCES} ${SCWX_ICON})
|
||||
|
||||
string(TIMESTAMP CURRENT_YEAR "%Y")
|
||||
|
||||
set_target_properties(supercell-wx PROPERTIES
|
||||
MACOSX_BUNDLE TRUE
|
||||
MACOSX_BUNDLE_INFO_PLIST "${scwx-qt_SOURCE_DIR}/res/scwx-qt.plist.in"
|
||||
MACOSX_BUNDLE_GUI_IDENTIFIER "net.supercellwx.app"
|
||||
MACOSX_BUNDLE_BUNDLE_NAME "Supercell Wx"
|
||||
MACOSX_BUNDLE_BUNDLE_VERSION "${SCWX_VERSION}"
|
||||
MACOSX_BUNDLE_SHORT_VERSION_STRING "${SCWX_VERSION}"
|
||||
MACOSX_BUNDLE_COPYRIGHT "Copyright ${CURRENT_YEAR} Dan Paulat"
|
||||
MACOSX_BUNDLE_ICON_FILE "scwx.icns"
|
||||
MACOSX_BUNDLE_INFO_STRING "Free and open source advanced weather radar"
|
||||
RESOURCE ${SCWX_ICON})
|
||||
else()
|
||||
qt_add_executable(supercell-wx ${EXECUTABLE_SOURCES})
|
||||
endif()
|
||||
|
|
@ -582,12 +658,17 @@ if (WIN32)
|
|||
target_compile_definitions(supercell-wx PUBLIC WIN32_LEAN_AND_MEAN)
|
||||
endif()
|
||||
|
||||
if (NOT MSVC)
|
||||
if (LINUX)
|
||||
# Qt emit keyword is incompatible with TBB
|
||||
target_compile_definitions(scwx-qt PRIVATE QT_NO_EMIT)
|
||||
target_compile_definitions(supercell-wx PRIVATE QT_NO_EMIT)
|
||||
endif()
|
||||
|
||||
if (APPLE)
|
||||
target_compile_definitions(scwx-qt PRIVATE GL_SILENCE_DEPRECATION)
|
||||
target_compile_definitions(supercell-wx PRIVATE GL_SILENCE_DEPRECATION)
|
||||
endif()
|
||||
|
||||
target_include_directories(scwx-qt PUBLIC ${scwx-qt_SOURCE_DIR}/source
|
||||
${FTGL_INCLUDE_DIR}
|
||||
${IMGUI_INCLUDE_DIRS}
|
||||
|
|
@ -643,6 +724,25 @@ else()
|
|||
target_compile_options(supercell-wx PRIVATE "$<$<CONFIG:Release>:-g>")
|
||||
endif()
|
||||
|
||||
if (LINUX)
|
||||
# Add wayland client packages
|
||||
find_package(QT NAMES Qt6
|
||||
COMPONENTS WaylandClient
|
||||
REQUIRED)
|
||||
|
||||
find_package(Qt${QT_VERSION_MAJOR}
|
||||
COMPONENTS WaylandClient
|
||||
REQUIRED)
|
||||
target_link_libraries(scwx-qt PUBLIC Qt${QT_VERSION_MAJOR}::WaylandClient)
|
||||
endif()
|
||||
|
||||
if (LINUX)
|
||||
find_package(mesa-glu REQUIRED)
|
||||
target_link_libraries(scwx-qt PUBLIC mesa-glu::mesa-glu)
|
||||
else()
|
||||
target_link_libraries(scwx-qt PUBLIC OpenGL::GLU)
|
||||
endif()
|
||||
|
||||
target_link_libraries(scwx-qt PUBLIC Qt${QT_VERSION_MAJOR}::Widgets
|
||||
Qt${QT_VERSION_MAJOR}::OpenGLWidgets
|
||||
Qt${QT_VERSION_MAJOR}::Multimedia
|
||||
|
|
@ -651,6 +751,7 @@ target_link_libraries(scwx-qt PUBLIC Qt${QT_VERSION_MAJOR}::Widgets
|
|||
Qt${QT_VERSION_MAJOR}::Svg
|
||||
Boost::json
|
||||
Boost::timer
|
||||
Boost::atomic
|
||||
QMapLibre::Core
|
||||
$<$<CXX_COMPILER_ID:MSVC>:opengl32>
|
||||
$<$<CXX_COMPILER_ID:MSVC>:SetupAPI>
|
||||
|
|
@ -658,18 +759,22 @@ target_link_libraries(scwx-qt PUBLIC Qt${QT_VERSION_MAJOR}::Widgets
|
|||
GeographicLib::GeographicLib
|
||||
GEOS::geos
|
||||
GEOS::geos_cxx_flags
|
||||
GLEW::GLEW
|
||||
glad_gl_core_33
|
||||
glm::glm
|
||||
imgui
|
||||
qt6ct-common
|
||||
qt6ct-widgets
|
||||
SQLite::SQLite3
|
||||
wxdata)
|
||||
|
||||
target_link_libraries(supercell-wx PRIVATE scwx-qt
|
||||
wxdata)
|
||||
|
||||
# Set DT_RUNPATH for Linux targets
|
||||
set_target_properties(MLNQtCore PROPERTIES INSTALL_RPATH "\$ORIGIN/../lib") # QMapLibre::Core
|
||||
set_target_properties(supercell-wx PROPERTIES INSTALL_RPATH "\$ORIGIN/../lib")
|
||||
if (LINUX)
|
||||
# Set DT_RUNPATH for Linux targets
|
||||
set_target_properties(MLNQtCore PROPERTIES INSTALL_RPATH "\$ORIGIN/../lib") # QMapLibre::Core
|
||||
set_target_properties(supercell-wx PROPERTIES INSTALL_RPATH "\$ORIGIN/../lib")
|
||||
endif()
|
||||
|
||||
install(TARGETS supercell-wx
|
||||
MLNQtCore # QMapLibre::Core
|
||||
|
|
@ -679,7 +784,15 @@ install(TARGETS supercell-wx
|
|||
"^(/usr)?/lib/.*\\.so(\\..*)?"
|
||||
RUNTIME
|
||||
COMPONENT supercell-wx
|
||||
BUNDLE
|
||||
DESTINATION .
|
||||
COMPONENT supercell-wx
|
||||
OPTIONAL
|
||||
LIBRARY
|
||||
COMPONENT supercell-wx
|
||||
OPTIONAL
|
||||
FRAMEWORK
|
||||
DESTINATION Frameworks
|
||||
COMPONENT supercell-wx
|
||||
OPTIONAL)
|
||||
|
||||
|
|
@ -701,14 +814,64 @@ install(SCRIPT ${deploy_script_qmaplibre_core}
|
|||
install(SCRIPT ${deploy_script_scwx}
|
||||
COMPONENT supercell-wx)
|
||||
|
||||
if (APPLE)
|
||||
# Install additional script to fix up the bundle
|
||||
install(CODE [[
|
||||
include (BundleUtilities)
|
||||
|
||||
# Define the bundle path
|
||||
set(BUNDLE_PATH "${CMAKE_INSTALL_PREFIX}/supercell-wx.app")
|
||||
|
||||
file(GLOB_RECURSE PLUGIN_DYLIBS "${BUNDLE_PATH}/Contents/PlugIns/**/*.dylib")
|
||||
|
||||
# Add the correct rpath for plugins to find bundled frameworks
|
||||
foreach(PLUGIN_DYLIB ${PLUGIN_DYLIBS})
|
||||
execute_process(
|
||||
COMMAND install_name_tool -add_rpath "@loader_path/../../Frameworks"
|
||||
${PLUGIN_DYLIB}
|
||||
)
|
||||
endforeach()
|
||||
|
||||
# Fix up the bundle with all dependencies
|
||||
fixup_bundle(
|
||||
"${BUNDLE_PATH}"
|
||||
""
|
||||
"${CMAKE_INSTALL_PREFIX}/lib;${CMAKE_INSTALL_PREFIX}/Frameworks"
|
||||
)
|
||||
|
||||
# Re-sign the bundle
|
||||
execute_process(
|
||||
COMMAND codesign --force --deep --sign - "${BUNDLE_PATH}"
|
||||
)
|
||||
|
||||
# Verify the bundle
|
||||
verify_app("${BUNDLE_PATH}")
|
||||
|
||||
# Rename to "Supercell Wx.app"
|
||||
file(REMOVE_RECURSE
|
||||
"${CMAKE_INSTALL_PREFIX}/Supercell Wx.app")
|
||||
file(RENAME
|
||||
"${BUNDLE_PATH}"
|
||||
"${CMAKE_INSTALL_PREFIX}/Supercell Wx.app")
|
||||
|
||||
# Remove extra directories
|
||||
file(REMOVE_RECURSE
|
||||
"${CMAKE_INSTALL_PREFIX}/Frameworks")
|
||||
file(REMOVE_RECURSE
|
||||
"${CMAKE_INSTALL_PREFIX}/lib")
|
||||
]]
|
||||
COMPONENT supercell-wx)
|
||||
endif()
|
||||
|
||||
set(CPACK_PACKAGE_NAME "Supercell Wx")
|
||||
set(CPACK_PACKAGE_VENDOR "Dan Paulat")
|
||||
set(CPACK_PACKAGE_CHECKSUM SHA256)
|
||||
set(CPACK_RESOURCE_FILE_LICENSE "${SCWX_DIR}/LICENSE.txt")
|
||||
|
||||
if (MSVC)
|
||||
set(CPACK_PACKAGE_NAME "Supercell Wx")
|
||||
set(CPACK_PACKAGE_VENDOR "Dan Paulat")
|
||||
set(CPACK_PACKAGE_FILE_NAME "supercell-wx-v${SCWX_VERSION}-windows-x64")
|
||||
set(CPACK_PACKAGE_INSTALL_DIRECTORY "Supercell Wx")
|
||||
set(CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/res/icons/scwx-256.ico")
|
||||
set(CPACK_PACKAGE_CHECKSUM SHA256)
|
||||
set(CPACK_RESOURCE_FILE_LICENSE "${SCWX_DIR}/LICENSE.txt")
|
||||
set(CPACK_GENERATOR WIX)
|
||||
set(CPACK_PACKAGE_EXECUTABLES "supercell-wx;Supercell Wx")
|
||||
set(CPACK_WIX_UPGRADE_GUID 36AD0F51-4D4F-4B5D-AB61-94C6B4E4FE1C)
|
||||
|
|
@ -720,5 +883,15 @@ if (MSVC)
|
|||
set(CPACK_INSTALL_CMAKE_PROJECTS
|
||||
"${CMAKE_CURRENT_BINARY_DIR};${CMAKE_PROJECT_NAME};supercell-wx;/")
|
||||
|
||||
include(CPack)
|
||||
elseif(APPLE)
|
||||
set(CPACK_PACKAGE_FILE_NAME "supercell-wx-v${SCWX_VERSION}-macos")
|
||||
set(CPACK_PACKAGE_ICON "${SCWX_ICON}")
|
||||
set(CPACK_PACKAGE_VERSION "${SCWX_VERSION}")
|
||||
|
||||
set(CPACK_GENERATOR DragNDrop)
|
||||
|
||||
set(CPACK_COMPONENTS_ALL supercell-wx)
|
||||
|
||||
include(CPack)
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -32,6 +32,10 @@
|
|||
<file>res/icons/font-awesome-6/angles-up-solid.svg</file>
|
||||
<file>res/icons/font-awesome-6/backward-step-solid.svg</file>
|
||||
<file>res/icons/font-awesome-6/book-solid.svg</file>
|
||||
<file>res/icons/font-awesome-6/briefcase-solid.svg</file>
|
||||
<file>res/icons/font-awesome-6/building-columns-solid.svg</file>
|
||||
<file>res/icons/font-awesome-6/building-solid.svg</file>
|
||||
<file>res/icons/font-awesome-6/caravan-solid.svg</file>
|
||||
<file>res/icons/font-awesome-6/copy-regular.svg</file>
|
||||
<file>res/icons/font-awesome-6/discord.svg</file>
|
||||
<file>res/icons/font-awesome-6/earth-americas-solid.svg</file>
|
||||
|
|
@ -40,8 +44,11 @@
|
|||
<file>res/icons/font-awesome-6/gears-solid.svg</file>
|
||||
<file>res/icons/font-awesome-6/github.svg</file>
|
||||
<file>res/icons/font-awesome-6/house-solid.svg</file>
|
||||
<file>res/icons/font-awesome-6/house-solid-white.svg</file>
|
||||
<file>res/icons/font-awesome-6/keyboard-regular.svg</file>
|
||||
<file>res/icons/font-awesome-6/layer-group-solid.svg</file>
|
||||
<file>res/icons/font-awesome-6/location-crosshairs-solid.svg</file>
|
||||
<file>res/icons/font-awesome-6/location-pin.svg</file>
|
||||
<file>res/icons/font-awesome-6/palette-solid.svg</file>
|
||||
<file>res/icons/font-awesome-6/pause-solid.svg</file>
|
||||
<file>res/icons/font-awesome-6/play-solid.svg</file>
|
||||
|
|
@ -53,7 +60,9 @@
|
|||
<file>res/icons/font-awesome-6/square-minus-regular.svg</file>
|
||||
<file>res/icons/font-awesome-6/square-plus-regular.svg</file>
|
||||
<file>res/icons/font-awesome-6/star-solid.svg</file>
|
||||
<file>res/icons/font-awesome-6/star-solid-white.svg</file>
|
||||
<file>res/icons/font-awesome-6/stop-solid.svg</file>
|
||||
<file>res/icons/font-awesome-6/tent-solid.svg</file>
|
||||
<file>res/icons/font-awesome-6/volume-high-solid.svg</file>
|
||||
<file>res/palettes/wct/CC.pal</file>
|
||||
<file>res/palettes/wct/Default16.pal</file>
|
||||
|
|
@ -70,11 +79,20 @@
|
|||
<file>res/palettes/wct/SW.pal</file>
|
||||
<file>res/palettes/wct/VIL.pal</file>
|
||||
<file>res/palettes/wct/ZDR.pal</file>
|
||||
<file alias="res/qt6ct_colors/airy.conf">../external/qt6ct/colors/airy.conf</file>
|
||||
<file alias="res/qt6ct_colors/darker.conf">../external/qt6ct/colors/darker.conf</file>
|
||||
<file alias="res/qt6ct_colors/dusk.conf">../external/qt6ct/colors/dusk.conf</file>
|
||||
<file alias="res/qt6ct_colors/ia_ora.conf">../external/qt6ct/colors/ia_ora.conf</file>
|
||||
<file alias="res/qt6ct_colors/sand.conf">../external/qt6ct/colors/sand.conf</file>
|
||||
<file alias="res/qt6ct_colors/simple.conf">../external/qt6ct/colors/simple.conf</file>
|
||||
<file alias="res/qt6ct_colors/waves.conf">../external/qt6ct/colors/waves.conf</file>
|
||||
<file>res/textures/lines/default-1x7.png</file>
|
||||
<file>res/textures/lines/test-pattern.png</file>
|
||||
<file>res/textures/images/cursor-17.png</file>
|
||||
<file>res/textures/images/crosshairs-24.png</file>
|
||||
<file>res/textures/images/dot-3.png</file>
|
||||
<file>res/textures/images/dot.svg</file>
|
||||
<file>res/textures/images/location-marker.svg</file>
|
||||
<file>res/textures/images/mapbox-logo.svg</file>
|
||||
<file>res/textures/images/maptiler-logo.svg</file>
|
||||
</qresource>
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
#include <boost/json.hpp>
|
||||
|
||||
#if !defined(_MSC_VER)
|
||||
#if (__cpp_lib_chrono < 201907L)
|
||||
# include <date/date.h>
|
||||
#endif
|
||||
|
||||
|
|
@ -51,6 +51,7 @@ public:
|
|||
std::string state_ {};
|
||||
std::string place_ {};
|
||||
std::string tzName_ {};
|
||||
double altitude_ {0.0};
|
||||
|
||||
const scwx::util::time_zone* timeZone_ {nullptr};
|
||||
};
|
||||
|
|
@ -142,6 +143,11 @@ const scwx::util::time_zone* RadarSite::time_zone() const
|
|||
return p->timeZone_;
|
||||
}
|
||||
|
||||
units::length::feet<double> RadarSite::altitude() const
|
||||
{
|
||||
return units::length::feet<double>(p->altitude_);
|
||||
}
|
||||
|
||||
std::shared_ptr<RadarSite> RadarSite::Get(const std::string& id)
|
||||
{
|
||||
std::shared_lock lock(siteMutex_);
|
||||
|
|
@ -239,7 +245,7 @@ size_t RadarSite::ReadConfig(const std::string& path)
|
|||
bool dataValid = true;
|
||||
size_t sitesAdded = 0;
|
||||
|
||||
boost::json::value j = util::json::ReadJsonFile(path);
|
||||
boost::json::value j = util::json::ReadJsonQFile(path);
|
||||
|
||||
dataValid = j.is_array();
|
||||
|
||||
|
|
@ -268,10 +274,12 @@ size_t RadarSite::ReadConfig(const std::string& path)
|
|||
site->p->state_ = boost::json::value_to<std::string>(o.at("state"));
|
||||
site->p->place_ = boost::json::value_to<std::string>(o.at("place"));
|
||||
site->p->tzName_ = boost::json::value_to<std::string>(o.at("tz"));
|
||||
site->p->altitude_ =
|
||||
boost::json::value_to<double>(o.at("elevation"));
|
||||
|
||||
try
|
||||
{
|
||||
#if defined(_MSC_VER)
|
||||
#if (__cpp_lib_chrono >= 201907L)
|
||||
using namespace std::chrono;
|
||||
#else
|
||||
using namespace date;
|
||||
|
|
|
|||
|
|
@ -6,12 +6,9 @@
|
|||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <units/length.h>
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
namespace qt
|
||||
{
|
||||
namespace config
|
||||
namespace scwx::qt::config
|
||||
{
|
||||
|
||||
class RadarSiteImpl;
|
||||
|
|
@ -28,18 +25,19 @@ public:
|
|||
RadarSite(RadarSite&&) noexcept;
|
||||
RadarSite& operator=(RadarSite&&) noexcept;
|
||||
|
||||
std::string type() const;
|
||||
std::string type_name() const;
|
||||
std::string id() const;
|
||||
double latitude() const;
|
||||
double longitude() const;
|
||||
std::string country() const;
|
||||
std::string state() const;
|
||||
std::string place() const;
|
||||
std::string location_name() const;
|
||||
std::string tz_name() const;
|
||||
[[nodiscard]] std::string type() const;
|
||||
[[nodiscard]] std::string type_name() const;
|
||||
[[nodiscard]] std::string id() const;
|
||||
[[nodiscard]] double latitude() const;
|
||||
[[nodiscard]] double longitude() const;
|
||||
[[nodiscard]] std::string country() const;
|
||||
[[nodiscard]] std::string state() const;
|
||||
[[nodiscard]] std::string place() const;
|
||||
[[nodiscard]] std::string location_name() const;
|
||||
[[nodiscard]] std::string tz_name() const;
|
||||
[[nodiscard]] units::length::feet<double> altitude() const;
|
||||
|
||||
const scwx::util::time_zone* time_zone() const;
|
||||
[[nodiscard]] const scwx::util::time_zone* time_zone() const;
|
||||
|
||||
static std::shared_ptr<RadarSite> Get(const std::string& id);
|
||||
static std::vector<std::shared_ptr<RadarSite>> GetAll();
|
||||
|
|
@ -67,6 +65,4 @@ private:
|
|||
|
||||
std::string GetRadarIdFromSiteId(const std::string& siteId);
|
||||
|
||||
} // namespace config
|
||||
} // namespace qt
|
||||
} // namespace scwx
|
||||
} // namespace scwx::qt::config
|
||||
|
|
|
|||
|
|
@ -30,13 +30,11 @@ static const std::string logPrefix_ = "scwx::qt::gl::draw::draw_item";
|
|||
class DrawItem::Impl
|
||||
{
|
||||
public:
|
||||
explicit Impl(OpenGLFunctions& gl) : gl_ {gl} {}
|
||||
~Impl() {}
|
||||
|
||||
OpenGLFunctions& gl_;
|
||||
explicit Impl() = default;
|
||||
~Impl() = default;
|
||||
};
|
||||
|
||||
DrawItem::DrawItem(OpenGLFunctions& gl) : p(std::make_unique<Impl>(gl)) {}
|
||||
DrawItem::DrawItem() : p(std::make_unique<Impl>()) {}
|
||||
DrawItem::~DrawItem() = default;
|
||||
|
||||
DrawItem::DrawItem(DrawItem&&) noexcept = default;
|
||||
|
|
@ -74,7 +72,7 @@ void DrawItem::UseDefaultProjection(
|
|||
0.0f,
|
||||
static_cast<float>(params.height));
|
||||
|
||||
p->gl_.glUniformMatrix4fv(
|
||||
glUniformMatrix4fv(
|
||||
uMVPMatrixLocation, 1, GL_FALSE, glm::value_ptr(projection));
|
||||
}
|
||||
|
||||
|
|
@ -91,7 +89,7 @@ void DrawItem::UseRotationProjection(
|
|||
glm::radians<float>(params.bearing),
|
||||
glm::vec3(0.0f, 0.0f, 1.0f));
|
||||
|
||||
p->gl_.glUniformMatrix4fv(
|
||||
glUniformMatrix4fv(
|
||||
uMVPMatrixLocation, 1, GL_FALSE, glm::value_ptr(projection));
|
||||
}
|
||||
|
||||
|
|
@ -100,16 +98,14 @@ void DrawItem::UseMapProjection(
|
|||
GLint uMVPMatrixLocation,
|
||||
GLint uMapScreenCoordLocation)
|
||||
{
|
||||
OpenGLFunctions& gl = p->gl_;
|
||||
|
||||
const glm::mat4 uMVPMatrix = util::maplibre::GetMapMatrix(params);
|
||||
|
||||
gl.glUniform2fv(uMapScreenCoordLocation,
|
||||
1,
|
||||
glm::value_ptr(util::maplibre::LatLongToScreenCoordinate(
|
||||
{params.latitude, params.longitude})));
|
||||
glUniform2fv(uMapScreenCoordLocation,
|
||||
1,
|
||||
glm::value_ptr(util::maplibre::LatLongToScreenCoordinate(
|
||||
{params.latitude, params.longitude})));
|
||||
|
||||
gl.glUniformMatrix4fv(
|
||||
glUniformMatrix4fv(
|
||||
uMVPMatrixLocation, 1, GL_FALSE, glm::value_ptr(uMVPMatrix));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ namespace draw
|
|||
class DrawItem
|
||||
{
|
||||
public:
|
||||
explicit DrawItem(OpenGLFunctions& gl);
|
||||
~DrawItem();
|
||||
explicit DrawItem();
|
||||
virtual ~DrawItem();
|
||||
|
||||
DrawItem(const DrawItem&) = delete;
|
||||
DrawItem& operator=(const DrawItem&) = delete;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include <scwx/qt/util/texture_atlas.hpp>
|
||||
#include <scwx/qt/util/tooltip.hpp>
|
||||
#include <scwx/util/logger.hpp>
|
||||
#include <scwx/util/time.hpp>
|
||||
|
||||
#include <execution>
|
||||
|
||||
|
|
@ -38,7 +39,7 @@ static constexpr std::size_t kIntegersPerVertex_ = 4;
|
|||
static constexpr std::size_t kIntegerBufferLength_ =
|
||||
kNumTriangles * kVerticesPerTriangle * kIntegersPerVertex_;
|
||||
|
||||
struct GeoIconDrawItem
|
||||
struct GeoIconDrawItem : types::EventHandler
|
||||
{
|
||||
units::length::nautical_miles<double> threshold_ {};
|
||||
std::chrono::sys_time<std::chrono::seconds> startTime_ {};
|
||||
|
|
@ -144,7 +145,7 @@ public:
|
|||
};
|
||||
|
||||
GeoIcons::GeoIcons(const std::shared_ptr<GlContext>& context) :
|
||||
DrawItem(context->gl()), p(std::make_unique<Impl>(context))
|
||||
DrawItem(), p(std::make_unique<Impl>(context))
|
||||
{
|
||||
}
|
||||
GeoIcons::~GeoIcons() = default;
|
||||
|
|
@ -165,8 +166,6 @@ void GeoIcons::set_thresholded(bool thresholded)
|
|||
|
||||
void GeoIcons::Initialize()
|
||||
{
|
||||
gl::OpenGLFunctions& gl = p->context_->gl();
|
||||
|
||||
p->shaderProgram_ = p->context_->GetShaderProgram(
|
||||
{{GL_VERTEX_SHADER, ":/gl/geo_texture2d.vert"},
|
||||
{GL_GEOMETRY_SHADER, ":/gl/threshold.geom"},
|
||||
|
|
@ -181,88 +180,95 @@ void GeoIcons::Initialize()
|
|||
p->uSelectedTimeLocation_ =
|
||||
p->shaderProgram_->GetUniformLocation("uSelectedTime");
|
||||
|
||||
gl.glGenVertexArrays(1, &p->vao_);
|
||||
gl.glGenBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data());
|
||||
glGenVertexArrays(1, &p->vao_);
|
||||
glGenBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data());
|
||||
|
||||
gl.glBindVertexArray(p->vao_);
|
||||
gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]);
|
||||
gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW);
|
||||
glBindVertexArray(p->vao_);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]);
|
||||
glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW);
|
||||
|
||||
// NOLINTBEGIN(modernize-use-nullptr)
|
||||
// NOLINTBEGIN(performance-no-int-to-ptr)
|
||||
// NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers)
|
||||
|
||||
// aLatLong
|
||||
gl.glVertexAttribPointer(0,
|
||||
2,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
static_cast<void*>(0));
|
||||
gl.glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0,
|
||||
2,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
static_cast<void*>(0));
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
// aXYOffset
|
||||
gl.glVertexAttribPointer(1,
|
||||
2,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
reinterpret_cast<void*>(2 * sizeof(float)));
|
||||
gl.glEnableVertexAttribArray(1);
|
||||
glVertexAttribPointer(1,
|
||||
2,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
reinterpret_cast<void*>(2 * sizeof(float)));
|
||||
glEnableVertexAttribArray(1);
|
||||
|
||||
// aModulate
|
||||
gl.glVertexAttribPointer(3,
|
||||
4,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
reinterpret_cast<void*>(4 * sizeof(float)));
|
||||
gl.glEnableVertexAttribArray(3);
|
||||
glVertexAttribPointer(3,
|
||||
4,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
reinterpret_cast<void*>(4 * sizeof(float)));
|
||||
glEnableVertexAttribArray(3);
|
||||
|
||||
// aAngle
|
||||
gl.glVertexAttribPointer(4,
|
||||
1,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
reinterpret_cast<void*>(8 * sizeof(float)));
|
||||
gl.glEnableVertexAttribArray(4);
|
||||
glVertexAttribPointer(4,
|
||||
1,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
reinterpret_cast<void*>(8 * sizeof(float)));
|
||||
glEnableVertexAttribArray(4);
|
||||
|
||||
gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]);
|
||||
gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]);
|
||||
glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW);
|
||||
|
||||
// aTexCoord
|
||||
gl.glVertexAttribPointer(2,
|
||||
3,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerTexCoord * sizeof(float),
|
||||
static_cast<void*>(0));
|
||||
gl.glEnableVertexAttribArray(2);
|
||||
glVertexAttribPointer(2,
|
||||
3,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerTexCoord * sizeof(float),
|
||||
static_cast<void*>(0));
|
||||
glEnableVertexAttribArray(2);
|
||||
|
||||
gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[2]);
|
||||
gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[2]);
|
||||
glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW);
|
||||
|
||||
// aThreshold
|
||||
gl.glVertexAttribIPointer(5, //
|
||||
1,
|
||||
GL_INT,
|
||||
0,
|
||||
static_cast<void*>(0));
|
||||
gl.glEnableVertexAttribArray(5);
|
||||
glVertexAttribIPointer(5, //
|
||||
1,
|
||||
GL_INT,
|
||||
0,
|
||||
static_cast<void*>(0));
|
||||
glEnableVertexAttribArray(5);
|
||||
|
||||
// aTimeRange
|
||||
gl.glVertexAttribIPointer(6, //
|
||||
2,
|
||||
GL_INT,
|
||||
kIntegersPerVertex_ * sizeof(GLint),
|
||||
reinterpret_cast<void*>(1 * sizeof(GLint)));
|
||||
gl.glEnableVertexAttribArray(6);
|
||||
glVertexAttribIPointer(6, //
|
||||
2,
|
||||
GL_INT,
|
||||
kIntegersPerVertex_ * sizeof(GLint),
|
||||
reinterpret_cast<void*>(1 * sizeof(GLint)));
|
||||
glEnableVertexAttribArray(6);
|
||||
|
||||
// aDisplayed
|
||||
gl.glVertexAttribPointer(7,
|
||||
1,
|
||||
GL_INT,
|
||||
GL_FALSE,
|
||||
kIntegersPerVertex_ * sizeof(GLint),
|
||||
reinterpret_cast<void*>(3 * sizeof(float)));
|
||||
gl.glEnableVertexAttribArray(7);
|
||||
glVertexAttribIPointer(7,
|
||||
1,
|
||||
GL_INT,
|
||||
kIntegersPerVertex_ * sizeof(GLint),
|
||||
reinterpret_cast<void*>(3 * sizeof(GLint)));
|
||||
glEnableVertexAttribArray(7);
|
||||
|
||||
// NOLINTEND(cppcoreguidelines-avoid-magic-numbers)
|
||||
// NOLINTEND(performance-no-int-to-ptr)
|
||||
// NOLINTEND(modernize-use-nullptr)
|
||||
|
||||
p->dirty_ = true;
|
||||
}
|
||||
|
|
@ -284,9 +290,7 @@ void GeoIcons::Render(const QMapLibre::CustomLayerRenderParameters& params,
|
|||
|
||||
if (!p->currentIconList_.empty())
|
||||
{
|
||||
gl::OpenGLFunctions& gl = p->context_->gl();
|
||||
|
||||
gl.glBindVertexArray(p->vao_);
|
||||
glBindVertexArray(p->vao_);
|
||||
|
||||
p->Update(textureAtlasChanged);
|
||||
p->shaderProgram_->Use();
|
||||
|
|
@ -299,40 +303,38 @@ void GeoIcons::Render(const QMapLibre::CustomLayerRenderParameters& params,
|
|||
// If thresholding is enabled, set the map distance
|
||||
units::length::nautical_miles<float> mapDistance =
|
||||
util::maplibre::GetMapDistance(params);
|
||||
gl.glUniform1f(p->uMapDistanceLocation_, mapDistance.value());
|
||||
glUniform1f(p->uMapDistanceLocation_, mapDistance.value());
|
||||
}
|
||||
else
|
||||
{
|
||||
// If thresholding is disabled, set the map distance to 0
|
||||
gl.glUniform1f(p->uMapDistanceLocation_, 0.0f);
|
||||
glUniform1f(p->uMapDistanceLocation_, 0.0f);
|
||||
}
|
||||
|
||||
// Selected time
|
||||
std::chrono::system_clock::time_point selectedTime =
|
||||
(p->selectedTime_ == std::chrono::system_clock::time_point {}) ?
|
||||
std::chrono::system_clock::now() :
|
||||
scwx::util::time::now() :
|
||||
p->selectedTime_;
|
||||
gl.glUniform1i(
|
||||
glUniform1i(
|
||||
p->uSelectedTimeLocation_,
|
||||
static_cast<GLint>(std::chrono::duration_cast<std::chrono::minutes>(
|
||||
selectedTime.time_since_epoch())
|
||||
.count()));
|
||||
|
||||
// Interpolate texture coordinates
|
||||
gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
// Draw icons
|
||||
gl.glDrawArrays(GL_TRIANGLES, 0, p->numVertices_);
|
||||
glDrawArrays(GL_TRIANGLES, 0, p->numVertices_);
|
||||
}
|
||||
}
|
||||
|
||||
void GeoIcons::Deinitialize()
|
||||
{
|
||||
gl::OpenGLFunctions& gl = p->context_->gl();
|
||||
|
||||
gl.glDeleteVertexArrays(1, &p->vao_);
|
||||
gl.glDeleteBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data());
|
||||
glDeleteVertexArrays(1, &p->vao_);
|
||||
glDeleteBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data());
|
||||
|
||||
std::unique_lock lock {p->iconMutex_};
|
||||
|
||||
|
|
@ -692,7 +694,7 @@ void GeoIcons::Impl::UpdateSingleBuffer(
|
|||
hoverIcons.end(),
|
||||
[&di](auto& entry) { return entry.di_ == di; });
|
||||
|
||||
if (di->visible_ && !di->hoverText_.empty())
|
||||
if (di->visible_ && (!di->hoverText_.empty() || di->event_ != nullptr))
|
||||
{
|
||||
const units::angle::radians<double> radians = angle;
|
||||
|
||||
|
|
@ -848,8 +850,6 @@ void GeoIcons::Impl::UpdateModifiedIconBuffers()
|
|||
|
||||
void GeoIcons::Impl::Update(bool textureAtlasChanged)
|
||||
{
|
||||
gl::OpenGLFunctions& gl = context_->gl();
|
||||
|
||||
UpdateModifiedIconBuffers();
|
||||
|
||||
// If the texture atlas has changed
|
||||
|
|
@ -865,11 +865,12 @@ void GeoIcons::Impl::Update(bool textureAtlasChanged)
|
|||
UpdateTextureBuffer();
|
||||
|
||||
// Buffer texture data
|
||||
gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[1]);
|
||||
gl.glBufferData(GL_ARRAY_BUFFER,
|
||||
sizeof(float) * textureBuffer_.size(),
|
||||
textureBuffer_.data(),
|
||||
GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_[1]);
|
||||
glBufferData(
|
||||
GL_ARRAY_BUFFER,
|
||||
static_cast<GLsizeiptr>(sizeof(float) * textureBuffer_.size()),
|
||||
textureBuffer_.data(),
|
||||
GL_DYNAMIC_DRAW);
|
||||
|
||||
lastTextureAtlasChanged_ = false;
|
||||
}
|
||||
|
|
@ -878,18 +879,20 @@ void GeoIcons::Impl::Update(bool textureAtlasChanged)
|
|||
if (dirty_)
|
||||
{
|
||||
// Buffer vertex data
|
||||
gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]);
|
||||
gl.glBufferData(GL_ARRAY_BUFFER,
|
||||
sizeof(float) * currentIconBuffer_.size(),
|
||||
currentIconBuffer_.data(),
|
||||
GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]);
|
||||
glBufferData(
|
||||
GL_ARRAY_BUFFER,
|
||||
static_cast<GLsizeiptr>(sizeof(float) * currentIconBuffer_.size()),
|
||||
currentIconBuffer_.data(),
|
||||
GL_DYNAMIC_DRAW);
|
||||
|
||||
// Buffer threshold data
|
||||
gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[2]);
|
||||
gl.glBufferData(GL_ARRAY_BUFFER,
|
||||
sizeof(GLint) * currentIntegerBuffer_.size(),
|
||||
currentIntegerBuffer_.data(),
|
||||
GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_[2]);
|
||||
glBufferData(
|
||||
GL_ARRAY_BUFFER,
|
||||
static_cast<GLsizeiptr>(sizeof(GLint) * currentIntegerBuffer_.size()),
|
||||
currentIntegerBuffer_.data(),
|
||||
GL_DYNAMIC_DRAW);
|
||||
|
||||
numVertices_ =
|
||||
static_cast<GLsizei>(currentIconBuffer_.size() / kPointsPerVertex);
|
||||
|
|
@ -904,7 +907,7 @@ bool GeoIcons::RunMousePicking(
|
|||
const QPointF& mouseGlobalPos,
|
||||
const glm::vec2& mouseCoords,
|
||||
const common::Coordinate& /* mouseGeoCoords */,
|
||||
std::shared_ptr<types::EventHandler>& /* eventHandler */)
|
||||
std::shared_ptr<types::EventHandler>& eventHandler)
|
||||
{
|
||||
std::unique_lock lock {p->iconMutex_};
|
||||
|
||||
|
|
@ -928,7 +931,7 @@ bool GeoIcons::RunMousePicking(
|
|||
// If no time has been selected, use the current time
|
||||
std::chrono::system_clock::time_point selectedTime =
|
||||
(p->selectedTime_ == std::chrono::system_clock::time_point {}) ?
|
||||
std::chrono::system_clock::now() :
|
||||
scwx::util::time::now() :
|
||||
p->selectedTime_;
|
||||
|
||||
// For each pickable icon
|
||||
|
|
@ -947,8 +950,10 @@ bool GeoIcons::RunMousePicking(
|
|||
units::length::nautical_miles<double> {icon.di_->threshold_}
|
||||
.value())) < 999 &&
|
||||
|
||||
// Map distance is beyond the threshold
|
||||
icon.di_->threshold_ < mapDistance) ||
|
||||
// Map distance is beyond/within the threshold
|
||||
icon.di_->threshold_ < mapDistance &&
|
||||
(icon.di_->threshold_.value() >= 0.0 ||
|
||||
-(icon.di_->threshold_) > mapDistance)) ||
|
||||
|
||||
(
|
||||
// Geo icon has a start time
|
||||
|
|
@ -992,12 +997,27 @@ bool GeoIcons::RunMousePicking(
|
|||
if (it != p->currentHoverIcons_.crend())
|
||||
{
|
||||
itemPicked = true;
|
||||
util::tooltip::Show(it->di_->hoverText_, mouseGlobalPos);
|
||||
if (!it->di_->hoverText_.empty())
|
||||
{
|
||||
// Show tooltip
|
||||
util::tooltip::Show(it->di_->hoverText_, mouseGlobalPos);
|
||||
}
|
||||
if (it->di_->event_ != nullptr)
|
||||
{
|
||||
eventHandler = it->di_;
|
||||
}
|
||||
}
|
||||
|
||||
return itemPicked;
|
||||
}
|
||||
|
||||
void GeoIcons::RegisterEventHandler(
|
||||
const std::shared_ptr<GeoIconDrawItem>& di,
|
||||
const std::function<void(QEvent*)>& eventHandler)
|
||||
{
|
||||
di->event_ = eventHandler;
|
||||
}
|
||||
|
||||
} // namespace draw
|
||||
} // namespace gl
|
||||
} // namespace qt
|
||||
|
|
|
|||
|
|
@ -183,6 +183,16 @@ public:
|
|||
*/
|
||||
void FinishIcons();
|
||||
|
||||
/**
|
||||
* Registers an event handler for an icon.
|
||||
*
|
||||
* @param [in] di Icon draw item
|
||||
* @param [in] eventHandler Event handler function
|
||||
*/
|
||||
static void
|
||||
RegisterEventHandler(const std::shared_ptr<GeoIconDrawItem>& di,
|
||||
const std::function<void(QEvent*)>& eventHandler);
|
||||
|
||||
private:
|
||||
class Impl;
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include <scwx/qt/util/maplibre.hpp>
|
||||
#include <scwx/qt/util/tooltip.hpp>
|
||||
#include <scwx/util/logger.hpp>
|
||||
#include <scwx/util/time.hpp>
|
||||
|
||||
#include <execution>
|
||||
|
||||
|
|
@ -50,6 +51,7 @@ struct GeoLineDrawItem : types::EventHandler
|
|||
units::angle::degrees<float> angle_ {};
|
||||
std::string hoverText_ {};
|
||||
GeoLines::HoverCallback hoverCallback_ {nullptr};
|
||||
size_t lineIndex_ {0};
|
||||
};
|
||||
|
||||
class GeoLines::Impl
|
||||
|
|
@ -87,10 +89,10 @@ public:
|
|||
void UpdateBuffers();
|
||||
void UpdateModifiedLineBuffers();
|
||||
void UpdateSingleBuffer(const std::shared_ptr<GeoLineDrawItem>& di,
|
||||
std::size_t lineIndex,
|
||||
std::vector<float>& linesBuffer,
|
||||
std::vector<GLint>& integerBuffer,
|
||||
std::vector<LineHoverEntry>& hoverLines);
|
||||
std::vector<GLint>& integerBuffer,
|
||||
std::unordered_map<std::shared_ptr<GeoLineDrawItem>,
|
||||
LineHoverEntry>& hoverLines);
|
||||
|
||||
std::shared_ptr<GlContext> context_;
|
||||
|
||||
|
|
@ -112,8 +114,10 @@ public:
|
|||
std::vector<float> newLinesBuffer_ {};
|
||||
std::vector<GLint> newIntegerBuffer_ {};
|
||||
|
||||
std::vector<LineHoverEntry> currentHoverLines_ {};
|
||||
std::vector<LineHoverEntry> newHoverLines_ {};
|
||||
std::unordered_map<std::shared_ptr<GeoLineDrawItem>, LineHoverEntry>
|
||||
currentHoverLines_ {};
|
||||
std::unordered_map<std::shared_ptr<GeoLineDrawItem>, LineHoverEntry>
|
||||
newHoverLines_ {};
|
||||
|
||||
std::shared_ptr<ShaderProgram> shaderProgram_;
|
||||
GLint uMVPMatrixLocation_;
|
||||
|
|
@ -127,7 +131,7 @@ public:
|
|||
};
|
||||
|
||||
GeoLines::GeoLines(std::shared_ptr<GlContext> context) :
|
||||
DrawItem(context->gl()), p(std::make_unique<Impl>(context))
|
||||
DrawItem(), p(std::make_unique<Impl>(context))
|
||||
{
|
||||
}
|
||||
GeoLines::~GeoLines() = default;
|
||||
|
|
@ -148,8 +152,6 @@ void GeoLines::set_thresholded(bool thresholded)
|
|||
|
||||
void GeoLines::Initialize()
|
||||
{
|
||||
gl::OpenGLFunctions& gl = p->context_->gl();
|
||||
|
||||
p->shaderProgram_ = p->context_->GetShaderProgram(
|
||||
{{GL_VERTEX_SHADER, ":/gl/geo_texture2d.vert"},
|
||||
{GL_GEOMETRY_SHADER, ":/gl/threshold.geom"},
|
||||
|
|
@ -164,79 +166,86 @@ void GeoLines::Initialize()
|
|||
p->uSelectedTimeLocation_ =
|
||||
p->shaderProgram_->GetUniformLocation("uSelectedTime");
|
||||
|
||||
gl.glGenVertexArrays(1, &p->vao_);
|
||||
gl.glGenBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data());
|
||||
glGenVertexArrays(1, &p->vao_);
|
||||
glGenBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data());
|
||||
|
||||
gl.glBindVertexArray(p->vao_);
|
||||
gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]);
|
||||
gl.glBufferData(GL_ARRAY_BUFFER,
|
||||
sizeof(float) * kLineBufferLength_,
|
||||
nullptr,
|
||||
GL_DYNAMIC_DRAW);
|
||||
glBindVertexArray(p->vao_);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]);
|
||||
glBufferData(GL_ARRAY_BUFFER,
|
||||
sizeof(float) * kLineBufferLength_,
|
||||
nullptr,
|
||||
GL_DYNAMIC_DRAW);
|
||||
|
||||
// NOLINTBEGIN(modernize-use-nullptr)
|
||||
// NOLINTBEGIN(performance-no-int-to-ptr)
|
||||
// NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers)
|
||||
|
||||
// aLatLong
|
||||
gl.glVertexAttribPointer(0,
|
||||
2,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
static_cast<void*>(0));
|
||||
gl.glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0,
|
||||
2,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
static_cast<void*>(0));
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
// aXYOffset
|
||||
gl.glVertexAttribPointer(1,
|
||||
2,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
reinterpret_cast<void*>(2 * sizeof(float)));
|
||||
gl.glEnableVertexAttribArray(1);
|
||||
glVertexAttribPointer(1,
|
||||
2,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
reinterpret_cast<void*>(2 * sizeof(float)));
|
||||
glEnableVertexAttribArray(1);
|
||||
|
||||
// aModulate
|
||||
gl.glVertexAttribPointer(3,
|
||||
4,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
reinterpret_cast<void*>(4 * sizeof(float)));
|
||||
gl.glEnableVertexAttribArray(3);
|
||||
glVertexAttribPointer(3,
|
||||
4,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
reinterpret_cast<void*>(4 * sizeof(float)));
|
||||
glEnableVertexAttribArray(3);
|
||||
|
||||
// aAngle
|
||||
gl.glVertexAttribPointer(4,
|
||||
1,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
reinterpret_cast<void*>(8 * sizeof(float)));
|
||||
gl.glEnableVertexAttribArray(4);
|
||||
glVertexAttribPointer(4,
|
||||
1,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
reinterpret_cast<void*>(8 * sizeof(float)));
|
||||
glEnableVertexAttribArray(4);
|
||||
|
||||
gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]);
|
||||
gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]);
|
||||
glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW);
|
||||
|
||||
// aThreshold
|
||||
gl.glVertexAttribIPointer(5, //
|
||||
1,
|
||||
GL_INT,
|
||||
kIntegersPerVertex_ * sizeof(GLint),
|
||||
static_cast<void*>(0));
|
||||
gl.glEnableVertexAttribArray(5);
|
||||
glVertexAttribIPointer(5, //
|
||||
1,
|
||||
GL_INT,
|
||||
kIntegersPerVertex_ * sizeof(GLint),
|
||||
static_cast<void*>(0));
|
||||
glEnableVertexAttribArray(5);
|
||||
|
||||
// aTimeRange
|
||||
gl.glVertexAttribIPointer(6, //
|
||||
2,
|
||||
GL_INT,
|
||||
kIntegersPerVertex_ * sizeof(GLint),
|
||||
reinterpret_cast<void*>(1 * sizeof(GLint)));
|
||||
gl.glEnableVertexAttribArray(6);
|
||||
glVertexAttribIPointer(6, //
|
||||
2,
|
||||
GL_INT,
|
||||
kIntegersPerVertex_ * sizeof(GLint),
|
||||
reinterpret_cast<void*>(1 * sizeof(GLint)));
|
||||
glEnableVertexAttribArray(6);
|
||||
|
||||
// aDisplayed
|
||||
gl.glVertexAttribPointer(7,
|
||||
1,
|
||||
GL_INT,
|
||||
GL_FALSE,
|
||||
kIntegersPerVertex_ * sizeof(GLint),
|
||||
reinterpret_cast<void*>(3 * sizeof(float)));
|
||||
gl.glEnableVertexAttribArray(7);
|
||||
glVertexAttribIPointer(7,
|
||||
1,
|
||||
GL_INT,
|
||||
kIntegersPerVertex_ * sizeof(GLint),
|
||||
reinterpret_cast<void*>(3 * sizeof(GLint)));
|
||||
glEnableVertexAttribArray(7);
|
||||
|
||||
// NOLINTEND(cppcoreguidelines-avoid-magic-numbers)
|
||||
// NOLINTEND(performance-no-int-to-ptr)
|
||||
// NOLINTEND(modernize-use-nullptr)
|
||||
|
||||
p->dirty_ = true;
|
||||
}
|
||||
|
|
@ -252,9 +261,7 @@ void GeoLines::Render(const QMapLibre::CustomLayerRenderParameters& params)
|
|||
|
||||
if (p->newLineList_.size() > 0)
|
||||
{
|
||||
gl::OpenGLFunctions& gl = p->context_->gl();
|
||||
|
||||
gl.glBindVertexArray(p->vao_);
|
||||
glBindVertexArray(p->vao_);
|
||||
|
||||
p->Update();
|
||||
p->shaderProgram_->Use();
|
||||
|
|
@ -267,39 +274,37 @@ void GeoLines::Render(const QMapLibre::CustomLayerRenderParameters& params)
|
|||
// If thresholding is enabled, set the map distance
|
||||
units::length::nautical_miles<float> mapDistance =
|
||||
util::maplibre::GetMapDistance(params);
|
||||
gl.glUniform1f(p->uMapDistanceLocation_, mapDistance.value());
|
||||
glUniform1f(p->uMapDistanceLocation_, mapDistance.value());
|
||||
}
|
||||
else
|
||||
{
|
||||
// If thresholding is disabled, set the map distance to 0
|
||||
gl.glUniform1f(p->uMapDistanceLocation_, 0.0f);
|
||||
glUniform1f(p->uMapDistanceLocation_, 0.0f);
|
||||
}
|
||||
|
||||
// Selected time
|
||||
std::chrono::system_clock::time_point selectedTime =
|
||||
(p->selectedTime_ == std::chrono::system_clock::time_point {}) ?
|
||||
std::chrono::system_clock::now() :
|
||||
scwx::util::time::now() :
|
||||
p->selectedTime_;
|
||||
gl.glUniform1i(
|
||||
glUniform1i(
|
||||
p->uSelectedTimeLocation_,
|
||||
static_cast<GLint>(std::chrono::duration_cast<std::chrono::minutes>(
|
||||
selectedTime.time_since_epoch())
|
||||
.count()));
|
||||
|
||||
// Draw icons
|
||||
gl.glDrawArrays(GL_TRIANGLES,
|
||||
0,
|
||||
static_cast<GLsizei>(p->currentLineList_.size() *
|
||||
kVerticesPerRectangle));
|
||||
glDrawArrays(GL_TRIANGLES,
|
||||
0,
|
||||
static_cast<GLsizei>(p->currentLineList_.size() *
|
||||
kVerticesPerRectangle));
|
||||
}
|
||||
}
|
||||
|
||||
void GeoLines::Deinitialize()
|
||||
{
|
||||
gl::OpenGLFunctions& gl = p->context_->gl();
|
||||
|
||||
gl.glDeleteVertexArrays(1, &p->vao_);
|
||||
gl.glDeleteBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data());
|
||||
glDeleteVertexArrays(1, &p->vao_);
|
||||
glDeleteBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data());
|
||||
|
||||
std::unique_lock lock {p->lineMutex_};
|
||||
|
||||
|
|
@ -324,7 +329,9 @@ void GeoLines::StartLines()
|
|||
|
||||
std::shared_ptr<GeoLineDrawItem> GeoLines::AddLine()
|
||||
{
|
||||
return p->newLineList_.emplace_back(std::make_shared<GeoLineDrawItem>());
|
||||
auto& di = p->newLineList_.emplace_back(std::make_shared<GeoLineDrawItem>());
|
||||
di->lineIndex_ = p->newLineList_.size() - 1;
|
||||
return di;
|
||||
}
|
||||
|
||||
void GeoLines::SetLineLocation(const std::shared_ptr<GeoLineDrawItem>& di,
|
||||
|
|
@ -471,7 +478,7 @@ void GeoLines::Impl::UpdateBuffers()
|
|||
|
||||
// Update line buffer
|
||||
UpdateSingleBuffer(
|
||||
di, i, newLinesBuffer_, newIntegerBuffer_, newHoverLines_);
|
||||
di, newLinesBuffer_, newIntegerBuffer_, newHoverLines_);
|
||||
}
|
||||
|
||||
// All lines have been updated
|
||||
|
|
@ -489,23 +496,15 @@ void GeoLines::Impl::UpdateModifiedLineBuffers()
|
|||
// Update buffers for modified lines
|
||||
for (auto& di : dirtyLines_)
|
||||
{
|
||||
// Find modified line in the current list
|
||||
auto it =
|
||||
std::find(currentLineList_.cbegin(), currentLineList_.cend(), di);
|
||||
|
||||
// Ignore invalid lines
|
||||
if (it == currentLineList_.cend())
|
||||
// Check if modified line is in the current list
|
||||
if (di->lineIndex_ >= currentLineList_.size() ||
|
||||
currentLineList_[di->lineIndex_] != di)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
auto lineIndex = std::distance(currentLineList_.cbegin(), it);
|
||||
|
||||
UpdateSingleBuffer(di,
|
||||
lineIndex,
|
||||
currentLinesBuffer_,
|
||||
currentIntegerBuffer_,
|
||||
currentHoverLines_);
|
||||
UpdateSingleBuffer(
|
||||
di, currentLinesBuffer_, currentIntegerBuffer_, currentHoverLines_);
|
||||
}
|
||||
|
||||
// Clear list of modified lines
|
||||
|
|
@ -518,10 +517,10 @@ void GeoLines::Impl::UpdateModifiedLineBuffers()
|
|||
|
||||
void GeoLines::Impl::UpdateSingleBuffer(
|
||||
const std::shared_ptr<GeoLineDrawItem>& di,
|
||||
std::size_t lineIndex,
|
||||
std::vector<float>& lineBuffer,
|
||||
std::vector<GLint>& integerBuffer,
|
||||
std::vector<LineHoverEntry>& hoverLines)
|
||||
std::unordered_map<std::shared_ptr<GeoLineDrawItem>, LineHoverEntry>&
|
||||
hoverLines)
|
||||
{
|
||||
// Threshold value
|
||||
units::length::nautical_miles<double> threshold = di->threshold_;
|
||||
|
|
@ -589,10 +588,10 @@ void GeoLines::Impl::UpdateSingleBuffer(
|
|||
|
||||
// Buffer position data
|
||||
auto lineBufferPosition = lineBuffer.end();
|
||||
auto lineBufferOffset = lineIndex * kLineBufferLength_;
|
||||
auto lineBufferOffset = di->lineIndex_ * kLineBufferLength_;
|
||||
|
||||
auto integerBufferPosition = integerBuffer.end();
|
||||
auto integerBufferOffset = lineIndex * kIntegerBufferLength_;
|
||||
auto integerBufferOffset = di->lineIndex_ * kIntegerBufferLength_;
|
||||
|
||||
if (lineBufferOffset < lineBuffer.size())
|
||||
{
|
||||
|
|
@ -621,9 +620,7 @@ void GeoLines::Impl::UpdateSingleBuffer(
|
|||
std::copy(integerData.begin(), integerData.end(), integerBufferPosition);
|
||||
}
|
||||
|
||||
auto hoverIt = std::find_if(hoverLines.begin(),
|
||||
hoverLines.end(),
|
||||
[&di](auto& entry) { return entry.di_ == di; });
|
||||
auto hoverIt = hoverLines.find(di);
|
||||
|
||||
if (di->visible_ && (!di->hoverText_.empty() ||
|
||||
di->hoverCallback_ != nullptr || di->event_ != nullptr))
|
||||
|
|
@ -645,17 +642,23 @@ void GeoLines::Impl::UpdateSingleBuffer(
|
|||
|
||||
if (hoverIt == hoverLines.end())
|
||||
{
|
||||
hoverLines.emplace_back(
|
||||
LineHoverEntry {di, sc1, sc2, otl, otr, obl, obr});
|
||||
hoverLines.emplace(di,
|
||||
LineHoverEntry {.di_ = di,
|
||||
.p1_ = sc1,
|
||||
.p2_ = sc2,
|
||||
.otl_ = otl,
|
||||
.otr_ = otr,
|
||||
.obl_ = obl,
|
||||
.obr_ = obr});
|
||||
}
|
||||
else
|
||||
{
|
||||
hoverIt->p1_ = sc1;
|
||||
hoverIt->p2_ = sc2;
|
||||
hoverIt->otl_ = otl;
|
||||
hoverIt->otr_ = otr;
|
||||
hoverIt->obl_ = obl;
|
||||
hoverIt->obr_ = obr;
|
||||
hoverIt->second.p1_ = sc1;
|
||||
hoverIt->second.p2_ = sc2;
|
||||
hoverIt->second.otl_ = otl;
|
||||
hoverIt->second.otr_ = otr;
|
||||
hoverIt->second.obl_ = obl;
|
||||
hoverIt->second.obr_ = obr;
|
||||
}
|
||||
}
|
||||
else if (hoverIt != hoverLines.end())
|
||||
|
|
@ -671,21 +674,21 @@ void GeoLines::Impl::Update()
|
|||
// If the lines have been updated
|
||||
if (dirty_)
|
||||
{
|
||||
gl::OpenGLFunctions& gl = context_->gl();
|
||||
|
||||
// Buffer lines data
|
||||
gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]);
|
||||
gl.glBufferData(GL_ARRAY_BUFFER,
|
||||
sizeof(float) * currentLinesBuffer_.size(),
|
||||
currentLinesBuffer_.data(),
|
||||
GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]);
|
||||
glBufferData(
|
||||
GL_ARRAY_BUFFER,
|
||||
static_cast<GLsizeiptr>(sizeof(float) * currentLinesBuffer_.size()),
|
||||
currentLinesBuffer_.data(),
|
||||
GL_DYNAMIC_DRAW);
|
||||
|
||||
// Buffer threshold data
|
||||
gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[1]);
|
||||
gl.glBufferData(GL_ARRAY_BUFFER,
|
||||
sizeof(GLint) * currentIntegerBuffer_.size(),
|
||||
currentIntegerBuffer_.data(),
|
||||
GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_[1]);
|
||||
glBufferData(
|
||||
GL_ARRAY_BUFFER,
|
||||
static_cast<GLsizeiptr>(sizeof(GLint) * currentIntegerBuffer_.size()),
|
||||
currentIntegerBuffer_.data(),
|
||||
GL_DYNAMIC_DRAW);
|
||||
}
|
||||
|
||||
dirty_ = false;
|
||||
|
|
@ -721,16 +724,18 @@ bool GeoLines::RunMousePicking(
|
|||
// If no time has been selected, use the current time
|
||||
std::chrono::system_clock::time_point selectedTime =
|
||||
(p->selectedTime_ == std::chrono::system_clock::time_point {}) ?
|
||||
std::chrono::system_clock::now() :
|
||||
scwx::util::time::now() :
|
||||
p->selectedTime_;
|
||||
|
||||
// For each pickable line
|
||||
auto it = std::find_if(
|
||||
std::execution::par_unseq,
|
||||
p->currentHoverLines_.rbegin(),
|
||||
p->currentHoverLines_.rend(),
|
||||
[&mapDistance, &selectedTime, &mapMatrix, &mouseCoords](const auto& line)
|
||||
p->currentHoverLines_.cbegin(),
|
||||
p->currentHoverLines_.cend(),
|
||||
[&mapDistance, &selectedTime, &mapMatrix, &mouseCoords](
|
||||
const auto& lineIt)
|
||||
{
|
||||
const auto& line = lineIt.second;
|
||||
if ((
|
||||
// Placefile is thresholded
|
||||
mapDistance > units::length::meters<double> {0.0} &&
|
||||
|
|
@ -740,8 +745,10 @@ bool GeoLines::RunMousePicking(
|
|||
units::length::nautical_miles<double> {line.di_->threshold_}
|
||||
.value())) < 999 &&
|
||||
|
||||
// Map distance is beyond the threshold
|
||||
line.di_->threshold_ < mapDistance) ||
|
||||
// Map distance is beyond/within the threshold
|
||||
line.di_->threshold_ < mapDistance &&
|
||||
(line.di_->threshold_.value() >= 0.0 ||
|
||||
-(line.di_->threshold_) > mapDistance)) ||
|
||||
|
||||
(
|
||||
// Line has a start time
|
||||
|
|
@ -784,24 +791,24 @@ bool GeoLines::RunMousePicking(
|
|||
return util::maplibre::IsPointInPolygon({tl, bl, br, tr}, mouseCoords);
|
||||
});
|
||||
|
||||
if (it != p->currentHoverLines_.crend())
|
||||
if (it != p->currentHoverLines_.cend())
|
||||
{
|
||||
itemPicked = true;
|
||||
|
||||
if (!it->di_->hoverText_.empty())
|
||||
if (!it->second.di_->hoverText_.empty())
|
||||
{
|
||||
// Show tooltip
|
||||
util::tooltip::Show(it->di_->hoverText_, mouseGlobalPos);
|
||||
util::tooltip::Show(it->second.di_->hoverText_, mouseGlobalPos);
|
||||
}
|
||||
else if (it->di_->hoverCallback_ != nullptr)
|
||||
else if (it->second.di_->hoverCallback_ != nullptr)
|
||||
{
|
||||
it->di_->hoverCallback_(it->di_, mouseGlobalPos);
|
||||
it->second.di_->hoverCallback_(it->second.di_, mouseGlobalPos);
|
||||
}
|
||||
|
||||
if (it->di_->event_ != nullptr)
|
||||
if (it->second.di_->event_ != nullptr)
|
||||
{
|
||||
// Register event handler
|
||||
eventHandler = it->di_;
|
||||
eventHandler = it->second.di_;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,9 +19,8 @@ struct GeoLineDrawItem;
|
|||
class GeoLines : public DrawItem
|
||||
{
|
||||
public:
|
||||
typedef std::function<void(std::shared_ptr<GeoLineDrawItem>&,
|
||||
const QPointF&)>
|
||||
HoverCallback;
|
||||
using HoverCallback = std::function<void(
|
||||
const std::shared_ptr<GeoLineDrawItem>&, const QPointF&)>;
|
||||
|
||||
explicit GeoLines(std::shared_ptr<GlContext> context);
|
||||
~GeoLines();
|
||||
|
|
|
|||
|
|
@ -21,12 +21,11 @@ namespace draw
|
|||
static const std::string logPrefix_ = "scwx::qt::gl::draw::icons";
|
||||
static const auto logger_ = scwx::util::Logger::Create(logPrefix_);
|
||||
|
||||
static constexpr std::size_t kNumRectangles = 1;
|
||||
static constexpr std::size_t kNumTriangles = kNumRectangles * 2;
|
||||
static constexpr std::size_t kVerticesPerTriangle = 3;
|
||||
static constexpr std::size_t kVerticesPerRectangle = kVerticesPerTriangle * 2;
|
||||
static constexpr std::size_t kPointsPerVertex = 10;
|
||||
static constexpr std::size_t kPointsPerTexCoord = 3;
|
||||
static constexpr std::size_t kNumRectangles = 1;
|
||||
static constexpr std::size_t kNumTriangles = kNumRectangles * 2;
|
||||
static constexpr std::size_t kVerticesPerTriangle = 3;
|
||||
static constexpr std::size_t kPointsPerVertex = 10;
|
||||
static constexpr std::size_t kPointsPerTexCoord = 3;
|
||||
static constexpr std::size_t kIconBufferLength =
|
||||
kNumTriangles * kVerticesPerTriangle * kPointsPerVertex;
|
||||
static constexpr std::size_t kTextureBufferLength =
|
||||
|
|
@ -117,7 +116,7 @@ public:
|
|||
};
|
||||
|
||||
Icons::Icons(const std::shared_ptr<GlContext>& context) :
|
||||
DrawItem(context->gl()), p(std::make_unique<Impl>(context))
|
||||
DrawItem(), p(std::make_unique<Impl>(context))
|
||||
{
|
||||
}
|
||||
Icons::~Icons() = default;
|
||||
|
|
@ -127,8 +126,6 @@ Icons& Icons::operator=(Icons&&) noexcept = default;
|
|||
|
||||
void Icons::Initialize()
|
||||
{
|
||||
gl::OpenGLFunctions& gl = p->context_->gl();
|
||||
|
||||
p->shaderProgram_ = p->context_->GetShaderProgram(
|
||||
{{GL_VERTEX_SHADER, ":/gl/texture2d_array.vert"},
|
||||
{GL_GEOMETRY_SHADER, ":/gl/threshold.geom"},
|
||||
|
|
@ -136,69 +133,77 @@ void Icons::Initialize()
|
|||
|
||||
p->uMVPMatrixLocation_ = p->shaderProgram_->GetUniformLocation("uMVPMatrix");
|
||||
|
||||
gl.glGenVertexArrays(1, &p->vao_);
|
||||
gl.glGenBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data());
|
||||
glGenVertexArrays(1, &p->vao_);
|
||||
glGenBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data());
|
||||
|
||||
gl.glBindVertexArray(p->vao_);
|
||||
gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]);
|
||||
gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW);
|
||||
glBindVertexArray(p->vao_);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]);
|
||||
glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW);
|
||||
|
||||
// NOLINTBEGIN(modernize-use-nullptr)
|
||||
// NOLINTBEGIN(performance-no-int-to-ptr)
|
||||
// NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers)
|
||||
|
||||
// aVertex
|
||||
gl.glVertexAttribPointer(0,
|
||||
2,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
reinterpret_cast<void*>(0));
|
||||
gl.glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0,
|
||||
2,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
reinterpret_cast<void*>(0));
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
// aXYOffset
|
||||
gl.glVertexAttribPointer(1,
|
||||
2,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
reinterpret_cast<void*>(2 * sizeof(float)));
|
||||
gl.glEnableVertexAttribArray(1);
|
||||
glVertexAttribPointer(1,
|
||||
2,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
reinterpret_cast<void*>(2 * sizeof(float)));
|
||||
glEnableVertexAttribArray(1);
|
||||
|
||||
// aModulate
|
||||
gl.glVertexAttribPointer(3,
|
||||
4,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
reinterpret_cast<void*>(4 * sizeof(float)));
|
||||
gl.glEnableVertexAttribArray(3);
|
||||
glVertexAttribPointer(3,
|
||||
4,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
reinterpret_cast<void*>(4 * sizeof(float)));
|
||||
glEnableVertexAttribArray(3);
|
||||
|
||||
// aAngle
|
||||
gl.glVertexAttribPointer(4,
|
||||
1,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
reinterpret_cast<void*>(8 * sizeof(float)));
|
||||
gl.glEnableVertexAttribArray(4);
|
||||
glVertexAttribPointer(4,
|
||||
1,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
reinterpret_cast<void*>(8 * sizeof(float)));
|
||||
glEnableVertexAttribArray(4);
|
||||
|
||||
// aDisplayed
|
||||
gl.glVertexAttribPointer(5,
|
||||
1,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
reinterpret_cast<void*>(9 * sizeof(float)));
|
||||
gl.glEnableVertexAttribArray(5);
|
||||
glVertexAttribPointer(5,
|
||||
1,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
reinterpret_cast<void*>(9 * sizeof(float)));
|
||||
glEnableVertexAttribArray(5);
|
||||
|
||||
gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]);
|
||||
gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]);
|
||||
glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW);
|
||||
|
||||
// aTexCoord
|
||||
gl.glVertexAttribPointer(2,
|
||||
3,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerTexCoord * sizeof(float),
|
||||
static_cast<void*>(0));
|
||||
gl.glEnableVertexAttribArray(2);
|
||||
glVertexAttribPointer(2,
|
||||
3,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerTexCoord * sizeof(float),
|
||||
static_cast<void*>(0));
|
||||
glEnableVertexAttribArray(2);
|
||||
|
||||
// NOLINTEND(cppcoreguidelines-avoid-magic-numbers)
|
||||
// NOLINTEND(performance-no-int-to-ptr)
|
||||
// NOLINTEND(modernize-use-nullptr)
|
||||
|
||||
p->dirty_ = true;
|
||||
}
|
||||
|
|
@ -220,29 +225,25 @@ void Icons::Render(const QMapLibre::CustomLayerRenderParameters& params,
|
|||
|
||||
if (!p->currentIconList_.empty())
|
||||
{
|
||||
gl::OpenGLFunctions& gl = p->context_->gl();
|
||||
|
||||
gl.glBindVertexArray(p->vao_);
|
||||
glBindVertexArray(p->vao_);
|
||||
|
||||
p->Update(textureAtlasChanged);
|
||||
p->shaderProgram_->Use();
|
||||
UseDefaultProjection(params, p->uMVPMatrixLocation_);
|
||||
|
||||
// Interpolate texture coordinates
|
||||
gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
// Draw icons
|
||||
gl.glDrawArrays(GL_TRIANGLES, 0, p->numVertices_);
|
||||
glDrawArrays(GL_TRIANGLES, 0, p->numVertices_);
|
||||
}
|
||||
}
|
||||
|
||||
void Icons::Deinitialize()
|
||||
{
|
||||
gl::OpenGLFunctions& gl = p->context_->gl();
|
||||
|
||||
gl.glDeleteVertexArrays(1, &p->vao_);
|
||||
gl.glDeleteBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data());
|
||||
glDeleteVertexArrays(1, &p->vao_);
|
||||
glDeleteBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data());
|
||||
|
||||
std::unique_lock lock {p->iconMutex_};
|
||||
|
||||
|
|
@ -680,8 +681,6 @@ void Icons::Impl::UpdateModifiedIconBuffers()
|
|||
|
||||
void Icons::Impl::Update(bool textureAtlasChanged)
|
||||
{
|
||||
gl::OpenGLFunctions& gl = context_->gl();
|
||||
|
||||
UpdateModifiedIconBuffers();
|
||||
|
||||
// If the texture atlas has changed
|
||||
|
|
@ -697,11 +696,12 @@ void Icons::Impl::Update(bool textureAtlasChanged)
|
|||
UpdateTextureBuffer();
|
||||
|
||||
// Buffer texture data
|
||||
gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[1]);
|
||||
gl.glBufferData(GL_ARRAY_BUFFER,
|
||||
sizeof(float) * textureBuffer_.size(),
|
||||
textureBuffer_.data(),
|
||||
GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_[1]);
|
||||
glBufferData(
|
||||
GL_ARRAY_BUFFER,
|
||||
static_cast<GLsizeiptr>(sizeof(float) * textureBuffer_.size()),
|
||||
textureBuffer_.data(),
|
||||
GL_DYNAMIC_DRAW);
|
||||
|
||||
lastTextureAtlasChanged_ = false;
|
||||
}
|
||||
|
|
@ -710,11 +710,12 @@ void Icons::Impl::Update(bool textureAtlasChanged)
|
|||
if (dirty_)
|
||||
{
|
||||
// Buffer vertex data
|
||||
gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]);
|
||||
gl.glBufferData(GL_ARRAY_BUFFER,
|
||||
sizeof(float) * currentIconBuffer_.size(),
|
||||
currentIconBuffer_.data(),
|
||||
GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]);
|
||||
glBufferData(
|
||||
GL_ARRAY_BUFFER,
|
||||
static_cast<GLsizeiptr>(sizeof(float) * currentIconBuffer_.size()),
|
||||
currentIconBuffer_.data(),
|
||||
GL_DYNAMIC_DRAW);
|
||||
|
||||
numVertices_ =
|
||||
static_cast<GLsizei>(currentIconBuffer_.size() / kPointsPerVertex);
|
||||
|
|
@ -741,7 +742,7 @@ bool Icons::RunMousePicking(
|
|||
|
||||
// For each pickable icon
|
||||
auto it = std::find_if( //
|
||||
std::execution::par_unseq,
|
||||
std::execution::par,
|
||||
p->currentHoverIcons_.crbegin(),
|
||||
p->currentHoverIcons_.crend(),
|
||||
[&mouseLocalCoords](const auto& icon)
|
||||
|
|
|
|||
|
|
@ -63,14 +63,12 @@ class LinkedVectors::Impl
|
|||
{
|
||||
public:
|
||||
explicit Impl(std::shared_ptr<GlContext> context) :
|
||||
context_ {context}, geoLines_ {std::make_shared<GeoLines>(context)}
|
||||
geoLines_ {std::make_shared<GeoLines>(context)}
|
||||
{
|
||||
}
|
||||
|
||||
~Impl() {}
|
||||
|
||||
std::shared_ptr<GlContext> context_;
|
||||
|
||||
bool borderEnabled_ {true};
|
||||
bool visible_ {true};
|
||||
|
||||
|
|
@ -79,7 +77,7 @@ public:
|
|||
};
|
||||
|
||||
LinkedVectors::LinkedVectors(std::shared_ptr<GlContext> context) :
|
||||
DrawItem(context->gl()), p(std::make_unique<Impl>(context))
|
||||
DrawItem(), p(std::make_unique<Impl>(context))
|
||||
{
|
||||
}
|
||||
LinkedVectors::~LinkedVectors() = default;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include <scwx/qt/util/texture_atlas.hpp>
|
||||
#include <scwx/qt/util/tooltip.hpp>
|
||||
#include <scwx/util/logger.hpp>
|
||||
#include <scwx/util/time.hpp>
|
||||
|
||||
#include <execution>
|
||||
|
||||
|
|
@ -140,7 +141,7 @@ public:
|
|||
};
|
||||
|
||||
PlacefileIcons::PlacefileIcons(const std::shared_ptr<GlContext>& context) :
|
||||
DrawItem(context->gl()), p(std::make_unique<Impl>(context))
|
||||
DrawItem(), p(std::make_unique<Impl>(context))
|
||||
{
|
||||
}
|
||||
PlacefileIcons::~PlacefileIcons() = default;
|
||||
|
|
@ -161,9 +162,6 @@ void PlacefileIcons::set_thresholded(bool thresholded)
|
|||
|
||||
void PlacefileIcons::Initialize()
|
||||
{
|
||||
gl::OpenGLFunctions& gl = p->context_->gl();
|
||||
auto& gl30 = p->context_->gl30();
|
||||
|
||||
p->shaderProgram_ = p->context_->GetShaderProgram(
|
||||
{{GL_VERTEX_SHADER, ":/gl/geo_texture2d.vert"},
|
||||
{GL_GEOMETRY_SHADER, ":/gl/threshold.geom"},
|
||||
|
|
@ -178,82 +176,90 @@ void PlacefileIcons::Initialize()
|
|||
p->uSelectedTimeLocation_ =
|
||||
p->shaderProgram_->GetUniformLocation("uSelectedTime");
|
||||
|
||||
gl.glGenVertexArrays(1, &p->vao_);
|
||||
gl.glGenBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data());
|
||||
glGenVertexArrays(1, &p->vao_);
|
||||
glGenBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data());
|
||||
|
||||
gl.glBindVertexArray(p->vao_);
|
||||
gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]);
|
||||
gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW);
|
||||
glBindVertexArray(p->vao_);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]);
|
||||
glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW);
|
||||
|
||||
// NOLINTBEGIN(modernize-use-nullptr)
|
||||
// NOLINTBEGIN(performance-no-int-to-ptr)
|
||||
// NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers)
|
||||
|
||||
// aLatLong
|
||||
gl.glVertexAttribPointer(0,
|
||||
2,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
static_cast<void*>(0));
|
||||
gl.glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0,
|
||||
2,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
static_cast<void*>(0));
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
// aXYOffset
|
||||
gl.glVertexAttribPointer(1,
|
||||
2,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
reinterpret_cast<void*>(2 * sizeof(float)));
|
||||
gl.glEnableVertexAttribArray(1);
|
||||
glVertexAttribPointer(1,
|
||||
2,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
reinterpret_cast<void*>(2 * sizeof(float)));
|
||||
glEnableVertexAttribArray(1);
|
||||
|
||||
// aModulate
|
||||
gl.glVertexAttribPointer(3,
|
||||
4,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
reinterpret_cast<void*>(4 * sizeof(float)));
|
||||
gl.glEnableVertexAttribArray(3);
|
||||
glVertexAttribPointer(3,
|
||||
4,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
reinterpret_cast<void*>(4 * sizeof(float)));
|
||||
glEnableVertexAttribArray(3);
|
||||
|
||||
// aAngle
|
||||
gl.glVertexAttribPointer(4,
|
||||
1,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
reinterpret_cast<void*>(8 * sizeof(float)));
|
||||
gl.glEnableVertexAttribArray(4);
|
||||
glVertexAttribPointer(4,
|
||||
1,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
reinterpret_cast<void*>(8 * sizeof(float)));
|
||||
glEnableVertexAttribArray(4);
|
||||
|
||||
gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]);
|
||||
gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]);
|
||||
glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW);
|
||||
|
||||
// aTexCoord
|
||||
gl.glVertexAttribPointer(2,
|
||||
3,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerTexCoord * sizeof(float),
|
||||
static_cast<void*>(0));
|
||||
gl.glEnableVertexAttribArray(2);
|
||||
glVertexAttribPointer(2,
|
||||
3,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerTexCoord * sizeof(float),
|
||||
static_cast<void*>(0));
|
||||
glEnableVertexAttribArray(2);
|
||||
|
||||
gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[2]);
|
||||
gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[2]);
|
||||
glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW);
|
||||
|
||||
// aThreshold
|
||||
gl.glVertexAttribIPointer(5, //
|
||||
1,
|
||||
GL_INT,
|
||||
0,
|
||||
static_cast<void*>(0));
|
||||
gl.glEnableVertexAttribArray(5);
|
||||
glVertexAttribIPointer(5, //
|
||||
1,
|
||||
GL_INT,
|
||||
0,
|
||||
static_cast<void*>(0));
|
||||
glEnableVertexAttribArray(5);
|
||||
|
||||
// aTimeRange
|
||||
gl.glVertexAttribIPointer(6, //
|
||||
2,
|
||||
GL_INT,
|
||||
kIntegersPerVertex_ * sizeof(GLint),
|
||||
reinterpret_cast<void*>(1 * sizeof(GLint)));
|
||||
gl.glEnableVertexAttribArray(6);
|
||||
glVertexAttribIPointer(6, //
|
||||
2,
|
||||
GL_INT,
|
||||
kIntegersPerVertex_ * sizeof(GLint),
|
||||
reinterpret_cast<void*>(1 * sizeof(GLint)));
|
||||
glEnableVertexAttribArray(6);
|
||||
|
||||
// aDisplayed
|
||||
gl30.glVertexAttribI1i(7, 1);
|
||||
glVertexAttribI1i(7, 1);
|
||||
|
||||
// NOLINTEND(cppcoreguidelines-avoid-magic-numbers)
|
||||
// NOLINTEND(performance-no-int-to-ptr)
|
||||
// NOLINTEND(modernize-use-nullptr)
|
||||
|
||||
p->dirty_ = true;
|
||||
}
|
||||
|
|
@ -266,9 +272,7 @@ void PlacefileIcons::Render(
|
|||
|
||||
if (!p->currentIconList_.empty())
|
||||
{
|
||||
gl::OpenGLFunctions& gl = p->context_->gl();
|
||||
|
||||
gl.glBindVertexArray(p->vao_);
|
||||
glBindVertexArray(p->vao_);
|
||||
|
||||
p->Update(textureAtlasChanged);
|
||||
p->shaderProgram_->Use();
|
||||
|
|
@ -281,40 +285,38 @@ void PlacefileIcons::Render(
|
|||
// If thresholding is enabled, set the map distance
|
||||
units::length::nautical_miles<float> mapDistance =
|
||||
util::maplibre::GetMapDistance(params);
|
||||
gl.glUniform1f(p->uMapDistanceLocation_, mapDistance.value());
|
||||
glUniform1f(p->uMapDistanceLocation_, mapDistance.value());
|
||||
}
|
||||
else
|
||||
{
|
||||
// If thresholding is disabled, set the map distance to 0
|
||||
gl.glUniform1f(p->uMapDistanceLocation_, 0.0f);
|
||||
glUniform1f(p->uMapDistanceLocation_, 0.0f);
|
||||
}
|
||||
|
||||
// Selected time
|
||||
std::chrono::system_clock::time_point selectedTime =
|
||||
(p->selectedTime_ == std::chrono::system_clock::time_point {}) ?
|
||||
std::chrono::system_clock::now() :
|
||||
scwx::util::time::now() :
|
||||
p->selectedTime_;
|
||||
gl.glUniform1i(
|
||||
glUniform1i(
|
||||
p->uSelectedTimeLocation_,
|
||||
static_cast<GLint>(std::chrono::duration_cast<std::chrono::minutes>(
|
||||
selectedTime.time_since_epoch())
|
||||
.count()));
|
||||
|
||||
// Interpolate texture coordinates
|
||||
gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
// Draw icons
|
||||
gl.glDrawArrays(GL_TRIANGLES, 0, p->numVertices_);
|
||||
glDrawArrays(GL_TRIANGLES, 0, p->numVertices_);
|
||||
}
|
||||
}
|
||||
|
||||
void PlacefileIcons::Deinitialize()
|
||||
{
|
||||
gl::OpenGLFunctions& gl = p->context_->gl();
|
||||
|
||||
gl.glDeleteVertexArrays(1, &p->vao_);
|
||||
gl.glDeleteBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data());
|
||||
glDeleteVertexArrays(1, &p->vao_);
|
||||
glDeleteBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data());
|
||||
|
||||
std::unique_lock lock {p->iconMutex_};
|
||||
|
||||
|
|
@ -642,8 +644,6 @@ void PlacefileIcons::Impl::UpdateTextureBuffer()
|
|||
|
||||
void PlacefileIcons::Impl::Update(bool textureAtlasChanged)
|
||||
{
|
||||
gl::OpenGLFunctions& gl = context_->gl();
|
||||
|
||||
// If the texture atlas has changed
|
||||
if (dirty_ || textureAtlasChanged)
|
||||
{
|
||||
|
|
@ -657,29 +657,32 @@ void PlacefileIcons::Impl::Update(bool textureAtlasChanged)
|
|||
UpdateTextureBuffer();
|
||||
|
||||
// Buffer texture data
|
||||
gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[1]);
|
||||
gl.glBufferData(GL_ARRAY_BUFFER,
|
||||
sizeof(float) * textureBuffer_.size(),
|
||||
textureBuffer_.data(),
|
||||
GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_[1]);
|
||||
glBufferData(
|
||||
GL_ARRAY_BUFFER,
|
||||
static_cast<GLsizeiptr>(sizeof(float) * textureBuffer_.size()),
|
||||
textureBuffer_.data(),
|
||||
GL_DYNAMIC_DRAW);
|
||||
}
|
||||
|
||||
// If buffers need updating
|
||||
if (dirty_)
|
||||
{
|
||||
// Buffer vertex data
|
||||
gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]);
|
||||
gl.glBufferData(GL_ARRAY_BUFFER,
|
||||
sizeof(float) * currentIconBuffer_.size(),
|
||||
currentIconBuffer_.data(),
|
||||
GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]);
|
||||
glBufferData(
|
||||
GL_ARRAY_BUFFER,
|
||||
static_cast<GLsizeiptr>(sizeof(float) * currentIconBuffer_.size()),
|
||||
currentIconBuffer_.data(),
|
||||
GL_DYNAMIC_DRAW);
|
||||
|
||||
// Buffer threshold data
|
||||
gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[2]);
|
||||
gl.glBufferData(GL_ARRAY_BUFFER,
|
||||
sizeof(GLint) * currentIntegerBuffer_.size(),
|
||||
currentIntegerBuffer_.data(),
|
||||
GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_[2]);
|
||||
glBufferData(
|
||||
GL_ARRAY_BUFFER,
|
||||
static_cast<GLsizeiptr>(sizeof(GLint) * currentIntegerBuffer_.size()),
|
||||
currentIntegerBuffer_.data(),
|
||||
GL_DYNAMIC_DRAW);
|
||||
|
||||
numVertices_ =
|
||||
static_cast<GLsizei>(currentIconBuffer_.size() / kPointsPerVertex);
|
||||
|
|
@ -718,7 +721,7 @@ bool PlacefileIcons::RunMousePicking(
|
|||
// If no time has been selected, use the current time
|
||||
std::chrono::system_clock::time_point selectedTime =
|
||||
(p->selectedTime_ == std::chrono::system_clock::time_point {}) ?
|
||||
std::chrono::system_clock::now() :
|
||||
scwx::util::time::now() :
|
||||
p->selectedTime_;
|
||||
|
||||
// For each pickable icon
|
||||
|
|
@ -737,8 +740,10 @@ bool PlacefileIcons::RunMousePicking(
|
|||
units::length::nautical_miles<double> {icon.di_->threshold_}
|
||||
.value())) < 999 &&
|
||||
|
||||
// Map distance is beyond the threshold
|
||||
icon.di_->threshold_ < mapDistance) ||
|
||||
// Map distance is beyond/within the threshold
|
||||
icon.di_->threshold_ < mapDistance &&
|
||||
(icon.di_->threshold_.value() >= 0.0 ||
|
||||
-(icon.di_->threshold_) > mapDistance)) ||
|
||||
|
||||
(
|
||||
// Line has a start time
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#include <scwx/qt/util/maplibre.hpp>
|
||||
#include <scwx/qt/util/texture_atlas.hpp>
|
||||
#include <scwx/util/logger.hpp>
|
||||
#include <scwx/util/time.hpp>
|
||||
|
||||
#include <QDir>
|
||||
#include <QUrl>
|
||||
|
|
@ -117,7 +118,7 @@ public:
|
|||
};
|
||||
|
||||
PlacefileImages::PlacefileImages(const std::shared_ptr<GlContext>& context) :
|
||||
DrawItem(context->gl()), p(std::make_unique<Impl>(context))
|
||||
DrawItem(), p(std::make_unique<Impl>(context))
|
||||
{
|
||||
}
|
||||
PlacefileImages::~PlacefileImages() = default;
|
||||
|
|
@ -139,9 +140,6 @@ void PlacefileImages::set_thresholded(bool thresholded)
|
|||
|
||||
void PlacefileImages::Initialize()
|
||||
{
|
||||
gl::OpenGLFunctions& gl = p->context_->gl();
|
||||
auto& gl30 = p->context_->gl30();
|
||||
|
||||
p->shaderProgram_ = p->context_->GetShaderProgram(
|
||||
{{GL_VERTEX_SHADER, ":/gl/geo_texture2d.vert"},
|
||||
{GL_GEOMETRY_SHADER, ":/gl/threshold.geom"},
|
||||
|
|
@ -156,73 +154,81 @@ void PlacefileImages::Initialize()
|
|||
p->uSelectedTimeLocation_ =
|
||||
p->shaderProgram_->GetUniformLocation("uSelectedTime");
|
||||
|
||||
gl.glGenVertexArrays(1, &p->vao_);
|
||||
gl.glGenBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data());
|
||||
glGenVertexArrays(1, &p->vao_);
|
||||
glGenBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data());
|
||||
|
||||
gl.glBindVertexArray(p->vao_);
|
||||
gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]);
|
||||
gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW);
|
||||
glBindVertexArray(p->vao_);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]);
|
||||
glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW);
|
||||
|
||||
// NOLINTBEGIN(modernize-use-nullptr)
|
||||
// NOLINTBEGIN(performance-no-int-to-ptr)
|
||||
// NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers)
|
||||
|
||||
// aLatLong
|
||||
gl.glVertexAttribPointer(0,
|
||||
2,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
static_cast<void*>(0));
|
||||
gl.glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0,
|
||||
2,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
static_cast<void*>(0));
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
// aXYOffset
|
||||
gl.glVertexAttribPointer(1,
|
||||
2,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
reinterpret_cast<void*>(2 * sizeof(float)));
|
||||
gl.glEnableVertexAttribArray(1);
|
||||
glVertexAttribPointer(1,
|
||||
2,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
reinterpret_cast<void*>(2 * sizeof(float)));
|
||||
glEnableVertexAttribArray(1);
|
||||
|
||||
// aModulate
|
||||
gl.glVertexAttribPointer(3,
|
||||
4,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
reinterpret_cast<void*>(4 * sizeof(float)));
|
||||
gl.glEnableVertexAttribArray(3);
|
||||
glVertexAttribPointer(3,
|
||||
4,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
reinterpret_cast<void*>(4 * sizeof(float)));
|
||||
glEnableVertexAttribArray(3);
|
||||
|
||||
gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]);
|
||||
gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]);
|
||||
glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW);
|
||||
|
||||
// aTexCoord
|
||||
gl.glVertexAttribPointer(2,
|
||||
3,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerTexCoord * sizeof(float),
|
||||
static_cast<void*>(0));
|
||||
gl.glEnableVertexAttribArray(2);
|
||||
glVertexAttribPointer(2,
|
||||
3,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerTexCoord * sizeof(float),
|
||||
static_cast<void*>(0));
|
||||
glEnableVertexAttribArray(2);
|
||||
|
||||
gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[2]);
|
||||
gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[2]);
|
||||
glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW);
|
||||
|
||||
// aThreshold
|
||||
gl.glVertexAttribIPointer(5, //
|
||||
1,
|
||||
GL_INT,
|
||||
kIntegersPerVertex_ * sizeof(GLint),
|
||||
static_cast<void*>(0));
|
||||
gl.glEnableVertexAttribArray(5);
|
||||
glVertexAttribIPointer(5, //
|
||||
1,
|
||||
GL_INT,
|
||||
kIntegersPerVertex_ * sizeof(GLint),
|
||||
static_cast<void*>(0));
|
||||
glEnableVertexAttribArray(5);
|
||||
|
||||
// aTimeRange
|
||||
gl.glVertexAttribIPointer(6, //
|
||||
2,
|
||||
GL_INT,
|
||||
kIntegersPerVertex_ * sizeof(GLint),
|
||||
reinterpret_cast<void*>(1 * sizeof(GLint)));
|
||||
gl.glEnableVertexAttribArray(6);
|
||||
glVertexAttribIPointer(6, //
|
||||
2,
|
||||
GL_INT,
|
||||
kIntegersPerVertex_ * sizeof(GLint),
|
||||
reinterpret_cast<void*>(1 * sizeof(GLint)));
|
||||
glEnableVertexAttribArray(6);
|
||||
|
||||
// aDisplayed
|
||||
gl30.glVertexAttribI1i(7, 1);
|
||||
glVertexAttribI1i(7, 1);
|
||||
|
||||
// NOLINTEND(cppcoreguidelines-avoid-magic-numbers)
|
||||
// NOLINTEND(performance-no-int-to-ptr)
|
||||
// NOLINTEND(modernize-use-nullptr)
|
||||
|
||||
p->dirty_ = true;
|
||||
}
|
||||
|
|
@ -235,9 +241,7 @@ void PlacefileImages::Render(
|
|||
|
||||
if (!p->currentImageList_.empty())
|
||||
{
|
||||
gl::OpenGLFunctions& gl = p->context_->gl();
|
||||
|
||||
gl.glBindVertexArray(p->vao_);
|
||||
glBindVertexArray(p->vao_);
|
||||
|
||||
p->Update(textureAtlasChanged);
|
||||
p->shaderProgram_->Use();
|
||||
|
|
@ -250,40 +254,38 @@ void PlacefileImages::Render(
|
|||
// If thresholding is enabled, set the map distance
|
||||
units::length::nautical_miles<float> mapDistance =
|
||||
util::maplibre::GetMapDistance(params);
|
||||
gl.glUniform1f(p->uMapDistanceLocation_, mapDistance.value());
|
||||
glUniform1f(p->uMapDistanceLocation_, mapDistance.value());
|
||||
}
|
||||
else
|
||||
{
|
||||
// If thresholding is disabled, set the map distance to 0
|
||||
gl.glUniform1f(p->uMapDistanceLocation_, 0.0f);
|
||||
glUniform1f(p->uMapDistanceLocation_, 0.0f);
|
||||
}
|
||||
|
||||
// Selected time
|
||||
std::chrono::system_clock::time_point selectedTime =
|
||||
(p->selectedTime_ == std::chrono::system_clock::time_point {}) ?
|
||||
std::chrono::system_clock::now() :
|
||||
scwx::util::time::now() :
|
||||
p->selectedTime_;
|
||||
gl.glUniform1i(
|
||||
glUniform1i(
|
||||
p->uSelectedTimeLocation_,
|
||||
static_cast<GLint>(std::chrono::duration_cast<std::chrono::minutes>(
|
||||
selectedTime.time_since_epoch())
|
||||
.count()));
|
||||
|
||||
// Interpolate texture coordinates
|
||||
gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
// Draw images
|
||||
gl.glDrawArrays(GL_TRIANGLES, 0, p->numVertices_);
|
||||
glDrawArrays(GL_TRIANGLES, 0, p->numVertices_);
|
||||
}
|
||||
}
|
||||
|
||||
void PlacefileImages::Deinitialize()
|
||||
{
|
||||
gl::OpenGLFunctions& gl = p->context_->gl();
|
||||
|
||||
gl.glDeleteVertexArrays(1, &p->vao_);
|
||||
gl.glDeleteBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data());
|
||||
glDeleteVertexArrays(1, &p->vao_);
|
||||
glDeleteBuffers(static_cast<GLsizei>(p->vbo_.size()), p->vbo_.data());
|
||||
|
||||
std::unique_lock lock {p->imageMutex_};
|
||||
|
||||
|
|
@ -439,8 +441,6 @@ void PlacefileImages::Impl::UpdateTextureBuffer()
|
|||
|
||||
void PlacefileImages::Impl::Update(bool textureAtlasChanged)
|
||||
{
|
||||
gl::OpenGLFunctions& gl = context_->gl();
|
||||
|
||||
// If the texture atlas has changed
|
||||
if (dirty_ || textureAtlasChanged)
|
||||
{
|
||||
|
|
@ -454,29 +454,32 @@ void PlacefileImages::Impl::Update(bool textureAtlasChanged)
|
|||
UpdateTextureBuffer();
|
||||
|
||||
// Buffer texture data
|
||||
gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[1]);
|
||||
gl.glBufferData(GL_ARRAY_BUFFER,
|
||||
sizeof(float) * textureBuffer_.size(),
|
||||
textureBuffer_.data(),
|
||||
GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_[1]);
|
||||
glBufferData(
|
||||
GL_ARRAY_BUFFER,
|
||||
static_cast<GLsizeiptr>(sizeof(float) * textureBuffer_.size()),
|
||||
textureBuffer_.data(),
|
||||
GL_DYNAMIC_DRAW);
|
||||
}
|
||||
|
||||
// If buffers need updating
|
||||
if (dirty_)
|
||||
{
|
||||
// Buffer vertex data
|
||||
gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]);
|
||||
gl.glBufferData(GL_ARRAY_BUFFER,
|
||||
sizeof(float) * currentImageBuffer_.size(),
|
||||
currentImageBuffer_.data(),
|
||||
GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]);
|
||||
glBufferData(
|
||||
GL_ARRAY_BUFFER,
|
||||
static_cast<GLsizeiptr>(sizeof(float) * currentImageBuffer_.size()),
|
||||
currentImageBuffer_.data(),
|
||||
GL_DYNAMIC_DRAW);
|
||||
|
||||
// Buffer threshold data
|
||||
gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[2]);
|
||||
gl.glBufferData(GL_ARRAY_BUFFER,
|
||||
sizeof(GLint) * currentIntegerBuffer_.size(),
|
||||
currentIntegerBuffer_.data(),
|
||||
GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_[2]);
|
||||
glBufferData(
|
||||
GL_ARRAY_BUFFER,
|
||||
static_cast<GLsizeiptr>(sizeof(GLint) * currentIntegerBuffer_.size()),
|
||||
currentIntegerBuffer_.data(),
|
||||
GL_DYNAMIC_DRAW);
|
||||
|
||||
numVertices_ =
|
||||
static_cast<GLsizei>(currentImageBuffer_.size() / kPointsPerVertex);
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include <scwx/qt/util/maplibre.hpp>
|
||||
#include <scwx/qt/util/tooltip.hpp>
|
||||
#include <scwx/util/logger.hpp>
|
||||
#include <scwx/util/time.hpp>
|
||||
|
||||
#include <execution>
|
||||
|
||||
|
|
@ -18,13 +19,9 @@ namespace draw
|
|||
static const std::string logPrefix_ = "scwx::qt::gl::draw::placefile_lines";
|
||||
static const auto logger_ = scwx::util::Logger::Create(logPrefix_);
|
||||
|
||||
static constexpr std::size_t kNumRectangles = 1;
|
||||
static constexpr std::size_t kNumTriangles = kNumRectangles * 2;
|
||||
static constexpr std::size_t kVerticesPerTriangle = 3;
|
||||
static constexpr std::size_t kVerticesPerRectangle = kVerticesPerTriangle * 2;
|
||||
static constexpr std::size_t kPointsPerVertex = 9;
|
||||
static constexpr std::size_t kBufferLength =
|
||||
kNumTriangles * kVerticesPerTriangle * kPointsPerVertex;
|
||||
|
||||
// Threshold, start time, end time
|
||||
static constexpr std::size_t kIntegersPerVertex_ = 3;
|
||||
|
|
@ -110,7 +107,7 @@ public:
|
|||
};
|
||||
|
||||
PlacefileLines::PlacefileLines(const std::shared_ptr<GlContext>& context) :
|
||||
DrawItem(context->gl()), p(std::make_unique<Impl>(context))
|
||||
DrawItem(), p(std::make_unique<Impl>(context))
|
||||
{
|
||||
}
|
||||
PlacefileLines::~PlacefileLines() = default;
|
||||
|
|
@ -131,9 +128,6 @@ void PlacefileLines::set_thresholded(bool thresholded)
|
|||
|
||||
void PlacefileLines::Initialize()
|
||||
{
|
||||
gl::OpenGLFunctions& gl = p->context_->gl();
|
||||
auto& gl30 = p->context_->gl30();
|
||||
|
||||
p->shaderProgram_ = p->context_->GetShaderProgram(
|
||||
{{GL_VERTEX_SHADER, ":/gl/geo_texture2d.vert"},
|
||||
{GL_GEOMETRY_SHADER, ":/gl/threshold.geom"},
|
||||
|
|
@ -148,70 +142,78 @@ void PlacefileLines::Initialize()
|
|||
p->uSelectedTimeLocation_ =
|
||||
p->shaderProgram_->GetUniformLocation("uSelectedTime");
|
||||
|
||||
gl.glGenVertexArrays(1, &p->vao_);
|
||||
gl.glGenBuffers(2, p->vbo_.data());
|
||||
glGenVertexArrays(1, &p->vao_);
|
||||
glGenBuffers(2, p->vbo_.data());
|
||||
|
||||
gl.glBindVertexArray(p->vao_);
|
||||
gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]);
|
||||
gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW);
|
||||
glBindVertexArray(p->vao_);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]);
|
||||
glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW);
|
||||
|
||||
// NOLINTBEGIN(modernize-use-nullptr)
|
||||
// NOLINTBEGIN(performance-no-int-to-ptr)
|
||||
// NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers)
|
||||
|
||||
// aLatLong
|
||||
gl.glVertexAttribPointer(0,
|
||||
2,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
static_cast<void*>(0));
|
||||
gl.glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0,
|
||||
2,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
static_cast<void*>(0));
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
// aXYOffset
|
||||
gl.glVertexAttribPointer(1,
|
||||
2,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
reinterpret_cast<void*>(2 * sizeof(float)));
|
||||
gl.glEnableVertexAttribArray(1);
|
||||
glVertexAttribPointer(1,
|
||||
2,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
reinterpret_cast<void*>(2 * sizeof(float)));
|
||||
glEnableVertexAttribArray(1);
|
||||
|
||||
// aModulate
|
||||
gl.glVertexAttribPointer(3,
|
||||
4,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
reinterpret_cast<void*>(4 * sizeof(float)));
|
||||
gl.glEnableVertexAttribArray(3);
|
||||
glVertexAttribPointer(3,
|
||||
4,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
reinterpret_cast<void*>(4 * sizeof(float)));
|
||||
glEnableVertexAttribArray(3);
|
||||
|
||||
// aAngle
|
||||
gl.glVertexAttribPointer(4,
|
||||
1,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
reinterpret_cast<void*>(8 * sizeof(float)));
|
||||
gl.glEnableVertexAttribArray(4);
|
||||
glVertexAttribPointer(4,
|
||||
1,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
reinterpret_cast<void*>(8 * sizeof(float)));
|
||||
glEnableVertexAttribArray(4);
|
||||
|
||||
gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]);
|
||||
gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]);
|
||||
glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW);
|
||||
|
||||
// aThreshold
|
||||
gl.glVertexAttribIPointer(5, //
|
||||
1,
|
||||
GL_INT,
|
||||
kIntegersPerVertex_ * sizeof(GLint),
|
||||
static_cast<void*>(0));
|
||||
gl.glEnableVertexAttribArray(5);
|
||||
glVertexAttribIPointer(5, //
|
||||
1,
|
||||
GL_INT,
|
||||
kIntegersPerVertex_ * sizeof(GLint),
|
||||
static_cast<void*>(0));
|
||||
glEnableVertexAttribArray(5);
|
||||
|
||||
// aTimeRange
|
||||
gl.glVertexAttribIPointer(6, //
|
||||
2,
|
||||
GL_INT,
|
||||
kIntegersPerVertex_ * sizeof(GLint),
|
||||
reinterpret_cast<void*>(1 * sizeof(GLint)));
|
||||
gl.glEnableVertexAttribArray(6);
|
||||
glVertexAttribIPointer(6, //
|
||||
2,
|
||||
GL_INT,
|
||||
kIntegersPerVertex_ * sizeof(GLint),
|
||||
reinterpret_cast<void*>(1 * sizeof(GLint)));
|
||||
glEnableVertexAttribArray(6);
|
||||
|
||||
// aDisplayed
|
||||
gl30.glVertexAttribI1i(7, 1);
|
||||
glVertexAttribI1i(7, 1);
|
||||
|
||||
// NOLINTEND(cppcoreguidelines-avoid-magic-numbers)
|
||||
// NOLINTEND(performance-no-int-to-ptr)
|
||||
// NOLINTEND(modernize-use-nullptr)
|
||||
|
||||
p->dirty_ = true;
|
||||
}
|
||||
|
|
@ -223,9 +225,7 @@ void PlacefileLines::Render(
|
|||
|
||||
if (p->currentNumLines_ > 0)
|
||||
{
|
||||
gl::OpenGLFunctions& gl = p->context_->gl();
|
||||
|
||||
gl.glBindVertexArray(p->vao_);
|
||||
glBindVertexArray(p->vao_);
|
||||
|
||||
p->Update();
|
||||
p->shaderProgram_->Use();
|
||||
|
|
@ -238,36 +238,34 @@ void PlacefileLines::Render(
|
|||
// If thresholding is enabled, set the map distance
|
||||
units::length::nautical_miles<float> mapDistance =
|
||||
util::maplibre::GetMapDistance(params);
|
||||
gl.glUniform1f(p->uMapDistanceLocation_, mapDistance.value());
|
||||
glUniform1f(p->uMapDistanceLocation_, mapDistance.value());
|
||||
}
|
||||
else
|
||||
{
|
||||
// If thresholding is disabled, set the map distance to 0
|
||||
gl.glUniform1f(p->uMapDistanceLocation_, 0.0f);
|
||||
glUniform1f(p->uMapDistanceLocation_, 0.0f);
|
||||
}
|
||||
|
||||
// Selected time
|
||||
std::chrono::system_clock::time_point selectedTime =
|
||||
(p->selectedTime_ == std::chrono::system_clock::time_point {}) ?
|
||||
std::chrono::system_clock::now() :
|
||||
scwx::util::time::now() :
|
||||
p->selectedTime_;
|
||||
gl.glUniform1i(
|
||||
glUniform1i(
|
||||
p->uSelectedTimeLocation_,
|
||||
static_cast<GLint>(std::chrono::duration_cast<std::chrono::minutes>(
|
||||
selectedTime.time_since_epoch())
|
||||
.count()));
|
||||
|
||||
// Draw icons
|
||||
gl.glDrawArrays(GL_TRIANGLES, 0, p->numVertices_);
|
||||
glDrawArrays(GL_TRIANGLES, 0, p->numVertices_);
|
||||
}
|
||||
}
|
||||
|
||||
void PlacefileLines::Deinitialize()
|
||||
{
|
||||
gl::OpenGLFunctions& gl = p->context_->gl();
|
||||
|
||||
gl.glDeleteVertexArrays(1, &p->vao_);
|
||||
gl.glDeleteBuffers(2, p->vbo_.data());
|
||||
glDeleteVertexArrays(1, &p->vao_);
|
||||
glDeleteBuffers(2, p->vbo_.data());
|
||||
|
||||
std::unique_lock lock {p->lineMutex_};
|
||||
|
||||
|
|
@ -479,21 +477,21 @@ void PlacefileLines::Impl::Update()
|
|||
// If the placefile has been updated
|
||||
if (dirty_)
|
||||
{
|
||||
gl::OpenGLFunctions& gl = context_->gl();
|
||||
|
||||
// Buffer lines data
|
||||
gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]);
|
||||
gl.glBufferData(GL_ARRAY_BUFFER,
|
||||
sizeof(float) * currentLinesBuffer_.size(),
|
||||
currentLinesBuffer_.data(),
|
||||
GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]);
|
||||
glBufferData(
|
||||
GL_ARRAY_BUFFER,
|
||||
static_cast<GLsizeiptr>(sizeof(float) * currentLinesBuffer_.size()),
|
||||
currentLinesBuffer_.data(),
|
||||
GL_DYNAMIC_DRAW);
|
||||
|
||||
// Buffer threshold data
|
||||
gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[1]);
|
||||
gl.glBufferData(GL_ARRAY_BUFFER,
|
||||
sizeof(GLint) * currentIntegerBuffer_.size(),
|
||||
currentIntegerBuffer_.data(),
|
||||
GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_[1]);
|
||||
glBufferData(
|
||||
GL_ARRAY_BUFFER,
|
||||
static_cast<GLsizeiptr>(sizeof(GLint) * currentIntegerBuffer_.size()),
|
||||
currentIntegerBuffer_.data(),
|
||||
GL_DYNAMIC_DRAW);
|
||||
}
|
||||
|
||||
dirty_ = false;
|
||||
|
|
@ -529,7 +527,7 @@ bool PlacefileLines::RunMousePicking(
|
|||
// If no time has been selected, use the current time
|
||||
std::chrono::system_clock::time_point selectedTime =
|
||||
(p->selectedTime_ == std::chrono::system_clock::time_point {}) ?
|
||||
std::chrono::system_clock::now() :
|
||||
scwx::util::time::now() :
|
||||
p->selectedTime_;
|
||||
|
||||
// For each pickable line
|
||||
|
|
@ -548,8 +546,10 @@ bool PlacefileLines::RunMousePicking(
|
|||
units::length::nautical_miles<double> {line.di_->threshold_}
|
||||
.value())) < 999 &&
|
||||
|
||||
// Map distance is beyond the threshold
|
||||
line.di_->threshold_ < mapDistance) ||
|
||||
// Map distance is beyond/within the threshold
|
||||
line.di_->threshold_ < mapDistance &&
|
||||
(line.di_->threshold_.value() >= 0.0 ||
|
||||
-(line.di_->threshold_) > mapDistance)) ||
|
||||
|
||||
(
|
||||
// Line has a start time
|
||||
|
|
|
|||
|
|
@ -1,13 +1,19 @@
|
|||
#include <scwx/qt/gl/draw/placefile_polygons.hpp>
|
||||
#include <scwx/qt/util/maplibre.hpp>
|
||||
#include <scwx/util/logger.hpp>
|
||||
#include <scwx/util/time.hpp>
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include <GL/glu.h>
|
||||
#include <boost/container/stable_vector.hpp>
|
||||
|
||||
#if defined(_WIN32)
|
||||
#if !defined(__APPLE__)
|
||||
# include <GL/glu.h>
|
||||
#else
|
||||
# include <OpenGL/glu.h>
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) || defined(__APPLE__)
|
||||
typedef void (*_GLUfuncptr)(void);
|
||||
#endif
|
||||
|
||||
|
|
@ -31,7 +37,6 @@ static constexpr std::size_t kIntegersPerVertex_ = 3;
|
|||
|
||||
static constexpr std::size_t kTessVertexScreenX_ = 0;
|
||||
static constexpr std::size_t kTessVertexScreenY_ = 1;
|
||||
static constexpr std::size_t kTessVertexScreenZ_ = 2;
|
||||
static constexpr std::size_t kTessVertexXOffset_ = 3;
|
||||
static constexpr std::size_t kTessVertexYOffset_ = 4;
|
||||
static constexpr std::size_t kTessVertexR_ = 5;
|
||||
|
|
@ -126,7 +131,7 @@ public:
|
|||
|
||||
PlacefilePolygons::PlacefilePolygons(
|
||||
const std::shared_ptr<GlContext>& context) :
|
||||
DrawItem(context->gl()), p(std::make_unique<Impl>(context))
|
||||
DrawItem(), p(std::make_unique<Impl>(context))
|
||||
{
|
||||
}
|
||||
PlacefilePolygons::~PlacefilePolygons() = default;
|
||||
|
|
@ -148,8 +153,6 @@ void PlacefilePolygons::set_thresholded(bool thresholded)
|
|||
|
||||
void PlacefilePolygons::Initialize()
|
||||
{
|
||||
gl::OpenGLFunctions& gl = p->context_->gl();
|
||||
|
||||
p->shaderProgram_ = p->context_->GetShaderProgram(
|
||||
{{GL_VERTEX_SHADER, ":/gl/map_color.vert"},
|
||||
{GL_GEOMETRY_SHADER, ":/gl/threshold.geom"},
|
||||
|
|
@ -164,58 +167,66 @@ void PlacefilePolygons::Initialize()
|
|||
p->uSelectedTimeLocation_ =
|
||||
p->shaderProgram_->GetUniformLocation("uSelectedTime");
|
||||
|
||||
gl.glGenVertexArrays(1, &p->vao_);
|
||||
gl.glGenBuffers(2, p->vbo_.data());
|
||||
glGenVertexArrays(1, &p->vao_);
|
||||
glGenBuffers(2, p->vbo_.data());
|
||||
|
||||
gl.glBindVertexArray(p->vao_);
|
||||
gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]);
|
||||
gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW);
|
||||
glBindVertexArray(p->vao_);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]);
|
||||
glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW);
|
||||
|
||||
// NOLINTBEGIN(modernize-use-nullptr)
|
||||
// NOLINTBEGIN(performance-no-int-to-ptr)
|
||||
// NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers)
|
||||
|
||||
// aScreenCoord
|
||||
gl.glVertexAttribPointer(0,
|
||||
2,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
static_cast<void*>(0));
|
||||
gl.glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0,
|
||||
2,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
static_cast<void*>(0));
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
// aXYOffset
|
||||
gl.glVertexAttribPointer(1,
|
||||
2,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
reinterpret_cast<void*>(2 * sizeof(float)));
|
||||
gl.glEnableVertexAttribArray(1);
|
||||
glVertexAttribPointer(1,
|
||||
2,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
reinterpret_cast<void*>(2 * sizeof(float)));
|
||||
glEnableVertexAttribArray(1);
|
||||
|
||||
// aColor
|
||||
gl.glVertexAttribPointer(2,
|
||||
4,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
reinterpret_cast<void*>(4 * sizeof(float)));
|
||||
gl.glEnableVertexAttribArray(2);
|
||||
glVertexAttribPointer(2,
|
||||
4,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
reinterpret_cast<void*>(4 * sizeof(float)));
|
||||
glEnableVertexAttribArray(2);
|
||||
|
||||
gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]);
|
||||
gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]);
|
||||
glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW);
|
||||
|
||||
// aThreshold
|
||||
gl.glVertexAttribIPointer(3, //
|
||||
1,
|
||||
GL_INT,
|
||||
kIntegersPerVertex_ * sizeof(GLint),
|
||||
static_cast<void*>(0));
|
||||
gl.glEnableVertexAttribArray(3);
|
||||
glVertexAttribIPointer(3, //
|
||||
1,
|
||||
GL_INT,
|
||||
kIntegersPerVertex_ * sizeof(GLint),
|
||||
static_cast<void*>(0));
|
||||
glEnableVertexAttribArray(3);
|
||||
|
||||
// aTimeRange
|
||||
gl.glVertexAttribIPointer(4, //
|
||||
2,
|
||||
GL_INT,
|
||||
kIntegersPerVertex_ * sizeof(GLint),
|
||||
reinterpret_cast<void*>(1 * sizeof(GLint)));
|
||||
gl.glEnableVertexAttribArray(4);
|
||||
glVertexAttribIPointer(4, //
|
||||
2,
|
||||
GL_INT,
|
||||
kIntegersPerVertex_ * sizeof(GLint),
|
||||
reinterpret_cast<void*>(1 * sizeof(GLint)));
|
||||
glEnableVertexAttribArray(4);
|
||||
|
||||
// NOLINTEND(cppcoreguidelines-avoid-magic-numbers)
|
||||
// NOLINTEND(performance-no-int-to-ptr)
|
||||
// NOLINTEND(modernize-use-nullptr)
|
||||
|
||||
p->dirty_ = true;
|
||||
}
|
||||
|
|
@ -225,9 +236,7 @@ void PlacefilePolygons::Render(
|
|||
{
|
||||
if (!p->currentBuffer_.empty())
|
||||
{
|
||||
gl::OpenGLFunctions& gl = p->context_->gl();
|
||||
|
||||
gl.glBindVertexArray(p->vao_);
|
||||
glBindVertexArray(p->vao_);
|
||||
|
||||
p->Update();
|
||||
p->shaderProgram_->Use();
|
||||
|
|
@ -240,36 +249,34 @@ void PlacefilePolygons::Render(
|
|||
// If thresholding is enabled, set the map distance
|
||||
units::length::nautical_miles<float> mapDistance =
|
||||
util::maplibre::GetMapDistance(params);
|
||||
gl.glUniform1f(p->uMapDistanceLocation_, mapDistance.value());
|
||||
glUniform1f(p->uMapDistanceLocation_, mapDistance.value());
|
||||
}
|
||||
else
|
||||
{
|
||||
// If thresholding is disabled, set the map distance to 0
|
||||
gl.glUniform1f(p->uMapDistanceLocation_, 0.0f);
|
||||
glUniform1f(p->uMapDistanceLocation_, 0.0f);
|
||||
}
|
||||
|
||||
// Selected time
|
||||
std::chrono::system_clock::time_point selectedTime =
|
||||
(p->selectedTime_ == std::chrono::system_clock::time_point {}) ?
|
||||
std::chrono::system_clock::now() :
|
||||
scwx::util::time::now() :
|
||||
p->selectedTime_;
|
||||
gl.glUniform1i(
|
||||
glUniform1i(
|
||||
p->uSelectedTimeLocation_,
|
||||
static_cast<GLint>(std::chrono::duration_cast<std::chrono::minutes>(
|
||||
selectedTime.time_since_epoch())
|
||||
.count()));
|
||||
|
||||
// Draw icons
|
||||
gl.glDrawArrays(GL_TRIANGLES, 0, p->numVertices_);
|
||||
glDrawArrays(GL_TRIANGLES, 0, p->numVertices_);
|
||||
}
|
||||
}
|
||||
|
||||
void PlacefilePolygons::Deinitialize()
|
||||
{
|
||||
gl::OpenGLFunctions& gl = p->context_->gl();
|
||||
|
||||
gl.glDeleteVertexArrays(1, &p->vao_);
|
||||
gl.glDeleteBuffers(2, p->vbo_.data());
|
||||
glDeleteVertexArrays(1, &p->vao_);
|
||||
glDeleteBuffers(2, p->vbo_.data());
|
||||
|
||||
std::unique_lock lock {p->bufferMutex_};
|
||||
|
||||
|
|
@ -314,23 +321,23 @@ void PlacefilePolygons::Impl::Update()
|
|||
{
|
||||
if (dirty_)
|
||||
{
|
||||
gl::OpenGLFunctions& gl = context_->gl();
|
||||
|
||||
std::unique_lock lock {bufferMutex_};
|
||||
|
||||
// Buffer vertex data
|
||||
gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]);
|
||||
gl.glBufferData(GL_ARRAY_BUFFER,
|
||||
sizeof(GLfloat) * currentBuffer_.size(),
|
||||
currentBuffer_.data(),
|
||||
GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]);
|
||||
glBufferData(
|
||||
GL_ARRAY_BUFFER,
|
||||
static_cast<GLsizeiptr>(sizeof(GLfloat) * currentBuffer_.size()),
|
||||
currentBuffer_.data(),
|
||||
GL_DYNAMIC_DRAW);
|
||||
|
||||
// Buffer threshold data
|
||||
gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[1]);
|
||||
gl.glBufferData(GL_ARRAY_BUFFER,
|
||||
sizeof(GLint) * currentIntegerBuffer_.size(),
|
||||
currentIntegerBuffer_.data(),
|
||||
GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_[1]);
|
||||
glBufferData(
|
||||
GL_ARRAY_BUFFER,
|
||||
static_cast<GLsizeiptr>(sizeof(GLint) * currentIntegerBuffer_.size()),
|
||||
currentIntegerBuffer_.data(),
|
||||
GL_DYNAMIC_DRAW);
|
||||
|
||||
numVertices_ =
|
||||
static_cast<GLsizei>(currentBuffer_.size() / kPointsPerVertex);
|
||||
|
|
|
|||
|
|
@ -1,22 +1,16 @@
|
|||
#include <scwx/qt/gl/draw/placefile_text.hpp>
|
||||
#include <scwx/qt/manager/font_manager.hpp>
|
||||
#include <scwx/qt/manager/placefile_manager.hpp>
|
||||
#include <scwx/qt/settings/text_settings.hpp>
|
||||
#include <scwx/qt/util/maplibre.hpp>
|
||||
#include <scwx/qt/util/tooltip.hpp>
|
||||
#include <scwx/util/logger.hpp>
|
||||
#include <scwx/util/time.hpp>
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <imgui.h>
|
||||
#include <mbgl/util/constants.hpp>
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
namespace qt
|
||||
{
|
||||
namespace gl
|
||||
{
|
||||
namespace draw
|
||||
namespace scwx::qt::gl::draw
|
||||
{
|
||||
|
||||
static const std::string logPrefix_ = "scwx::qt::gl::draw::placefile_text";
|
||||
|
|
@ -25,13 +19,16 @@ static const auto logger_ = scwx::util::Logger::Create(logPrefix_);
|
|||
class PlacefileText::Impl
|
||||
{
|
||||
public:
|
||||
explicit Impl(const std::shared_ptr<GlContext>& context,
|
||||
const std::string& placefileName) :
|
||||
context_ {context}, placefileName_ {placefileName}
|
||||
explicit Impl(std::string placefileName) :
|
||||
placefileName_ {std::move(placefileName)}
|
||||
{
|
||||
}
|
||||
~Impl() = default;
|
||||
|
||||
~Impl() {}
|
||||
Impl(const Impl&) = delete;
|
||||
Impl& operator=(const Impl&) = delete;
|
||||
Impl(const Impl&&) = delete;
|
||||
Impl& operator=(const Impl&&) = delete;
|
||||
|
||||
void RenderTextDrawItem(
|
||||
const QMapLibre::CustomLayerRenderParameters& params,
|
||||
|
|
@ -43,8 +40,6 @@ public:
|
|||
float x,
|
||||
float y);
|
||||
|
||||
std::shared_ptr<GlContext> context_;
|
||||
|
||||
std::string placefileName_;
|
||||
|
||||
bool thresholded_ {false};
|
||||
|
|
@ -66,13 +61,16 @@ public:
|
|||
std::vector<std::shared_ptr<const gr::Placefile::TextDrawItem>> textList_ {};
|
||||
std::vector<std::shared_ptr<const gr::Placefile::TextDrawItem>> newList_ {};
|
||||
|
||||
std::vector<std::shared_ptr<types::ImGuiFont>> fonts_ {};
|
||||
std::vector<std::shared_ptr<types::ImGuiFont>> newFonts_ {};
|
||||
std::vector<std::pair<std::shared_ptr<types::ImGuiFont>,
|
||||
units::font_size::pixels<float>>>
|
||||
fonts_ {};
|
||||
std::vector<std::pair<std::shared_ptr<types::ImGuiFont>,
|
||||
units::font_size::pixels<float>>>
|
||||
newFonts_ {};
|
||||
};
|
||||
|
||||
PlacefileText::PlacefileText(const std::shared_ptr<GlContext>& context,
|
||||
const std::string& placefileName) :
|
||||
DrawItem(context->gl()), p(std::make_unique<Impl>(context, placefileName))
|
||||
PlacefileText::PlacefileText(const std::string& placefileName) :
|
||||
DrawItem(), p(std::make_unique<Impl>(placefileName))
|
||||
{
|
||||
}
|
||||
PlacefileText::~PlacefileText() = default;
|
||||
|
|
@ -133,10 +131,14 @@ void PlacefileText::Impl::RenderTextDrawItem(
|
|||
// If no time has been selected, use the current time
|
||||
std::chrono::system_clock::time_point selectedTime =
|
||||
(selectedTime_ == std::chrono::system_clock::time_point {}) ?
|
||||
std::chrono::system_clock::now() :
|
||||
scwx::util::time::now() :
|
||||
selectedTime_;
|
||||
|
||||
if ((!thresholded_ || mapDistance_ <= di->threshold_) &&
|
||||
const bool thresholdMet =
|
||||
!thresholded_ || mapDistance_ <= di->threshold_ ||
|
||||
(di->threshold_.value() < 0.0 && mapDistance_ >= -(di->threshold_));
|
||||
|
||||
if (thresholdMet &&
|
||||
(di->startTime_ == std::chrono::system_clock::time_point {} ||
|
||||
(di->startTime_ <= selectedTime && selectedTime < di->endTime_)))
|
||||
{
|
||||
|
|
@ -160,7 +162,8 @@ void PlacefileText::Impl::RenderTextDrawItem(
|
|||
std::size_t fontNumber = std::clamp<std::size_t>(di->fontNumber_, 0, 8);
|
||||
|
||||
// Set the font for the drop shadow and text
|
||||
ImGui::PushFont(fonts_[fontNumber]->font());
|
||||
ImGui::PushFont(fonts_[fontNumber].first->font(),
|
||||
fonts_[fontNumber].second.value());
|
||||
|
||||
if (settings::TextSettings::Instance()
|
||||
.placefile_text_drop_shadow_enabled()
|
||||
|
|
@ -262,9 +265,7 @@ void PlacefileText::StartText()
|
|||
p->newList_.clear();
|
||||
}
|
||||
|
||||
void PlacefileText::SetFonts(
|
||||
const boost::unordered_flat_map<std::size_t,
|
||||
std::shared_ptr<types::ImGuiFont>>& fonts)
|
||||
void PlacefileText::SetFonts(const manager::PlacefileManager::FontMap& fonts)
|
||||
{
|
||||
auto defaultFont = manager::FontManager::Instance().GetImGuiFont(
|
||||
types::FontCategory::Default);
|
||||
|
|
@ -306,7 +307,4 @@ void PlacefileText::FinishText()
|
|||
p->newFonts_.clear();
|
||||
}
|
||||
|
||||
} // namespace draw
|
||||
} // namespace gl
|
||||
} // namespace qt
|
||||
} // namespace scwx
|
||||
} // namespace scwx::qt::gl::draw
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include <scwx/qt/gl/gl_context.hpp>
|
||||
#include <scwx/qt/gl/draw/draw_item.hpp>
|
||||
#include <scwx/qt/manager/placefile_manager.hpp>
|
||||
#include <scwx/qt/types/imgui_font.hpp>
|
||||
#include <scwx/gr/placefile.hpp>
|
||||
|
||||
|
|
@ -19,8 +20,7 @@ namespace draw
|
|||
class PlacefileText : public DrawItem
|
||||
{
|
||||
public:
|
||||
explicit PlacefileText(const std::shared_ptr<GlContext>& context,
|
||||
const std::string& placefileName);
|
||||
explicit PlacefileText(const std::string& placefileName);
|
||||
~PlacefileText();
|
||||
|
||||
PlacefileText(const PlacefileText&) = delete;
|
||||
|
|
@ -55,10 +55,7 @@ public:
|
|||
*
|
||||
* @param [in] fonts A map of ImGui fonts
|
||||
*/
|
||||
void
|
||||
SetFonts(const boost::unordered_flat_map<std::size_t,
|
||||
std::shared_ptr<types::ImGuiFont>>&
|
||||
fonts);
|
||||
void SetFonts(const manager::PlacefileManager::FontMap& fonts);
|
||||
|
||||
/**
|
||||
* Adds placefile text to the internal draw list.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include <scwx/qt/gl/draw/placefile_triangles.hpp>
|
||||
#include <scwx/qt/util/maplibre.hpp>
|
||||
#include <scwx/util/logger.hpp>
|
||||
#include <scwx/util/time.hpp>
|
||||
|
||||
#include <mutex>
|
||||
|
||||
|
|
@ -74,7 +75,7 @@ public:
|
|||
|
||||
PlacefileTriangles::PlacefileTriangles(
|
||||
const std::shared_ptr<GlContext>& context) :
|
||||
DrawItem(context->gl()), p(std::make_unique<Impl>(context))
|
||||
DrawItem(), p(std::make_unique<Impl>(context))
|
||||
{
|
||||
}
|
||||
PlacefileTriangles::~PlacefileTriangles() = default;
|
||||
|
|
@ -96,8 +97,6 @@ void PlacefileTriangles::set_thresholded(bool thresholded)
|
|||
|
||||
void PlacefileTriangles::Initialize()
|
||||
{
|
||||
gl::OpenGLFunctions& gl = p->context_->gl();
|
||||
|
||||
p->shaderProgram_ = p->context_->GetShaderProgram(
|
||||
{{GL_VERTEX_SHADER, ":/gl/map_color.vert"},
|
||||
{GL_GEOMETRY_SHADER, ":/gl/threshold.geom"},
|
||||
|
|
@ -112,58 +111,66 @@ void PlacefileTriangles::Initialize()
|
|||
p->uSelectedTimeLocation_ =
|
||||
p->shaderProgram_->GetUniformLocation("uSelectedTime");
|
||||
|
||||
gl.glGenVertexArrays(1, &p->vao_);
|
||||
gl.glGenBuffers(2, p->vbo_.data());
|
||||
glGenVertexArrays(1, &p->vao_);
|
||||
glGenBuffers(2, p->vbo_.data());
|
||||
|
||||
gl.glBindVertexArray(p->vao_);
|
||||
gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]);
|
||||
gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW);
|
||||
glBindVertexArray(p->vao_);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]);
|
||||
glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW);
|
||||
|
||||
// NOLINTBEGIN(modernize-use-nullptr)
|
||||
// NOLINTBEGIN(performance-no-int-to-ptr)
|
||||
// NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers)
|
||||
|
||||
// aScreenCoord
|
||||
gl.glVertexAttribPointer(0,
|
||||
2,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
static_cast<void*>(0));
|
||||
gl.glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0,
|
||||
2,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
static_cast<void*>(0));
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
// aXYOffset
|
||||
gl.glVertexAttribPointer(1,
|
||||
2,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
reinterpret_cast<void*>(2 * sizeof(float)));
|
||||
gl.glEnableVertexAttribArray(1);
|
||||
glVertexAttribPointer(1,
|
||||
2,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
reinterpret_cast<void*>(2 * sizeof(float)));
|
||||
glEnableVertexAttribArray(1);
|
||||
|
||||
// aColor
|
||||
gl.glVertexAttribPointer(2,
|
||||
4,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
reinterpret_cast<void*>(4 * sizeof(float)));
|
||||
gl.glEnableVertexAttribArray(2);
|
||||
glVertexAttribPointer(2,
|
||||
4,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
kPointsPerVertex * sizeof(float),
|
||||
reinterpret_cast<void*>(4 * sizeof(float)));
|
||||
glEnableVertexAttribArray(2);
|
||||
|
||||
gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]);
|
||||
gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]);
|
||||
glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW);
|
||||
|
||||
// aThreshold
|
||||
gl.glVertexAttribIPointer(3, //
|
||||
1,
|
||||
GL_INT,
|
||||
kIntegersPerVertex_ * sizeof(GLint),
|
||||
static_cast<void*>(0));
|
||||
gl.glEnableVertexAttribArray(3);
|
||||
glVertexAttribIPointer(3, //
|
||||
1,
|
||||
GL_INT,
|
||||
kIntegersPerVertex_ * sizeof(GLint),
|
||||
static_cast<void*>(0));
|
||||
glEnableVertexAttribArray(3);
|
||||
|
||||
// aTimeRange
|
||||
gl.glVertexAttribIPointer(4, //
|
||||
2,
|
||||
GL_INT,
|
||||
kIntegersPerVertex_ * sizeof(GLint),
|
||||
reinterpret_cast<void*>(1 * sizeof(GLint)));
|
||||
gl.glEnableVertexAttribArray(4);
|
||||
glVertexAttribIPointer(4, //
|
||||
2,
|
||||
GL_INT,
|
||||
kIntegersPerVertex_ * sizeof(GLint),
|
||||
reinterpret_cast<void*>(1 * sizeof(GLint)));
|
||||
glEnableVertexAttribArray(4);
|
||||
|
||||
// NOLINTEND(cppcoreguidelines-avoid-magic-numbers)
|
||||
// NOLINTEND(performance-no-int-to-ptr)
|
||||
// NOLINTEND(modernize-use-nullptr)
|
||||
|
||||
p->dirty_ = true;
|
||||
}
|
||||
|
|
@ -173,9 +180,7 @@ void PlacefileTriangles::Render(
|
|||
{
|
||||
if (!p->currentBuffer_.empty())
|
||||
{
|
||||
gl::OpenGLFunctions& gl = p->context_->gl();
|
||||
|
||||
gl.glBindVertexArray(p->vao_);
|
||||
glBindVertexArray(p->vao_);
|
||||
|
||||
p->Update();
|
||||
p->shaderProgram_->Use();
|
||||
|
|
@ -188,36 +193,34 @@ void PlacefileTriangles::Render(
|
|||
// If thresholding is enabled, set the map distance
|
||||
units::length::nautical_miles<float> mapDistance =
|
||||
util::maplibre::GetMapDistance(params);
|
||||
gl.glUniform1f(p->uMapDistanceLocation_, mapDistance.value());
|
||||
glUniform1f(p->uMapDistanceLocation_, mapDistance.value());
|
||||
}
|
||||
else
|
||||
{
|
||||
// If thresholding is disabled, set the map distance to 0
|
||||
gl.glUniform1f(p->uMapDistanceLocation_, 0.0f);
|
||||
glUniform1f(p->uMapDistanceLocation_, 0.0f);
|
||||
}
|
||||
|
||||
// Selected time
|
||||
std::chrono::system_clock::time_point selectedTime =
|
||||
(p->selectedTime_ == std::chrono::system_clock::time_point {}) ?
|
||||
std::chrono::system_clock::now() :
|
||||
scwx::util::time::now() :
|
||||
p->selectedTime_;
|
||||
gl.glUniform1i(
|
||||
glUniform1i(
|
||||
p->uSelectedTimeLocation_,
|
||||
static_cast<GLint>(std::chrono::duration_cast<std::chrono::minutes>(
|
||||
selectedTime.time_since_epoch())
|
||||
.count()));
|
||||
|
||||
// Draw icons
|
||||
gl.glDrawArrays(GL_TRIANGLES, 0, p->numVertices_);
|
||||
glDrawArrays(GL_TRIANGLES, 0, p->numVertices_);
|
||||
}
|
||||
}
|
||||
|
||||
void PlacefileTriangles::Deinitialize()
|
||||
{
|
||||
gl::OpenGLFunctions& gl = p->context_->gl();
|
||||
|
||||
gl.glDeleteVertexArrays(1, &p->vao_);
|
||||
gl.glDeleteBuffers(2, p->vbo_.data());
|
||||
glDeleteVertexArrays(1, &p->vao_);
|
||||
glDeleteBuffers(2, p->vbo_.data());
|
||||
|
||||
std::unique_lock lock {p->bufferMutex_};
|
||||
|
||||
|
|
@ -320,23 +323,23 @@ void PlacefileTriangles::Impl::Update()
|
|||
{
|
||||
if (dirty_)
|
||||
{
|
||||
gl::OpenGLFunctions& gl = context_->gl();
|
||||
|
||||
std::unique_lock lock {bufferMutex_};
|
||||
|
||||
// Buffer vertex data
|
||||
gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]);
|
||||
gl.glBufferData(GL_ARRAY_BUFFER,
|
||||
sizeof(GLfloat) * currentBuffer_.size(),
|
||||
currentBuffer_.data(),
|
||||
GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]);
|
||||
glBufferData(
|
||||
GL_ARRAY_BUFFER,
|
||||
static_cast<GLsizeiptr>(sizeof(GLfloat) * currentBuffer_.size()),
|
||||
currentBuffer_.data(),
|
||||
GL_DYNAMIC_DRAW);
|
||||
|
||||
// Buffer threshold data
|
||||
gl.glBindBuffer(GL_ARRAY_BUFFER, vbo_[1]);
|
||||
gl.glBufferData(GL_ARRAY_BUFFER,
|
||||
sizeof(GLint) * currentIntegerBuffer_.size(),
|
||||
currentIntegerBuffer_.data(),
|
||||
GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_[1]);
|
||||
glBufferData(
|
||||
GL_ARRAY_BUFFER,
|
||||
static_cast<GLsizeiptr>(sizeof(GLint) * currentIntegerBuffer_.size()),
|
||||
currentIntegerBuffer_.data(),
|
||||
GL_DYNAMIC_DRAW);
|
||||
|
||||
numVertices_ =
|
||||
static_cast<GLsizei>(currentBuffer_.size() / kPointsPerVertex);
|
||||
|
|
|
|||
|
|
@ -3,13 +3,7 @@
|
|||
|
||||
#include <optional>
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
namespace qt
|
||||
{
|
||||
namespace gl
|
||||
{
|
||||
namespace draw
|
||||
namespace scwx::qt::gl::draw
|
||||
{
|
||||
|
||||
static const std::string logPrefix_ = "scwx::qt::gl::draw::rectangle";
|
||||
|
|
@ -27,7 +21,7 @@ class Rectangle::Impl
|
|||
{
|
||||
public:
|
||||
explicit Impl(std::shared_ptr<GlContext> context) :
|
||||
context_ {context},
|
||||
context_ {std::move(context)},
|
||||
dirty_ {false},
|
||||
visible_ {true},
|
||||
x_ {0.0f},
|
||||
|
|
@ -44,8 +38,12 @@ public:
|
|||
vbo_ {GL_INVALID_INDEX}
|
||||
{
|
||||
}
|
||||
~Impl() = default;
|
||||
|
||||
~Impl() {}
|
||||
Impl(const Impl&) = delete;
|
||||
Impl& operator=(const Impl&) = delete;
|
||||
Impl(const Impl&&) = delete;
|
||||
Impl& operator=(const Impl&&) = delete;
|
||||
|
||||
std::shared_ptr<GlContext> context_;
|
||||
|
||||
|
|
@ -73,7 +71,7 @@ public:
|
|||
};
|
||||
|
||||
Rectangle::Rectangle(std::shared_ptr<GlContext> context) :
|
||||
DrawItem(context->gl()), p(std::make_unique<Impl>(context))
|
||||
DrawItem(), p(std::make_unique<Impl>(context))
|
||||
{
|
||||
}
|
||||
Rectangle::~Rectangle() = default;
|
||||
|
|
@ -83,41 +81,45 @@ Rectangle& Rectangle::operator=(Rectangle&&) noexcept = default;
|
|||
|
||||
void Rectangle::Initialize()
|
||||
{
|
||||
gl::OpenGLFunctions& gl = p->context_->gl();
|
||||
|
||||
p->shaderProgram_ =
|
||||
p->context_->GetShaderProgram(":/gl/color.vert", ":/gl/color.frag");
|
||||
|
||||
p->uMVPMatrixLocation_ =
|
||||
gl.glGetUniformLocation(p->shaderProgram_->id(), "uMVPMatrix");
|
||||
glGetUniformLocation(p->shaderProgram_->id(), "uMVPMatrix");
|
||||
if (p->uMVPMatrixLocation_ == -1)
|
||||
{
|
||||
logger_->warn("Could not find uMVPMatrix");
|
||||
}
|
||||
|
||||
gl.glGenVertexArrays(1, &p->vao_);
|
||||
gl.glGenBuffers(1, &p->vbo_);
|
||||
glGenVertexArrays(1, &p->vao_);
|
||||
glGenBuffers(1, &p->vbo_);
|
||||
|
||||
gl.glBindVertexArray(p->vao_);
|
||||
gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_);
|
||||
gl.glBufferData(
|
||||
glBindVertexArray(p->vao_);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, p->vbo_);
|
||||
glBufferData(
|
||||
GL_ARRAY_BUFFER, sizeof(float) * BUFFER_LENGTH, nullptr, GL_DYNAMIC_DRAW);
|
||||
|
||||
gl.glVertexAttribPointer(0,
|
||||
3,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
POINTS_PER_VERTEX * sizeof(float),
|
||||
static_cast<void*>(0));
|
||||
gl.glEnableVertexAttribArray(0);
|
||||
// NOLINTBEGIN(modernize-use-nullptr)
|
||||
// NOLINTBEGIN(performance-no-int-to-ptr)
|
||||
|
||||
gl.glVertexAttribPointer(1,
|
||||
4,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
POINTS_PER_VERTEX * sizeof(float),
|
||||
reinterpret_cast<void*>(3 * sizeof(float)));
|
||||
gl.glEnableVertexAttribArray(1);
|
||||
glVertexAttribPointer(0,
|
||||
3,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
POINTS_PER_VERTEX * sizeof(float),
|
||||
static_cast<void*>(0));
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
glVertexAttribPointer(1,
|
||||
4,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
POINTS_PER_VERTEX * sizeof(float),
|
||||
reinterpret_cast<void*>(3 * sizeof(float)));
|
||||
glEnableVertexAttribArray(1);
|
||||
|
||||
// NOLINTEND(performance-no-int-to-ptr)
|
||||
// NOLINTEND(modernize-use-nullptr)
|
||||
|
||||
p->dirty_ = true;
|
||||
}
|
||||
|
|
@ -126,10 +128,8 @@ void Rectangle::Render(const QMapLibre::CustomLayerRenderParameters& params)
|
|||
{
|
||||
if (p->visible_)
|
||||
{
|
||||
gl::OpenGLFunctions& gl = p->context_->gl();
|
||||
|
||||
gl.glBindVertexArray(p->vao_);
|
||||
gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_);
|
||||
glBindVertexArray(p->vao_);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, p->vbo_);
|
||||
|
||||
p->Update();
|
||||
p->shaderProgram_->Use();
|
||||
|
|
@ -138,23 +138,23 @@ void Rectangle::Render(const QMapLibre::CustomLayerRenderParameters& params)
|
|||
if (p->fillColor_.has_value())
|
||||
{
|
||||
// Draw fill
|
||||
gl.glDrawArrays(GL_TRIANGLES, 24, 6);
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers)
|
||||
glDrawArrays(GL_TRIANGLES, 24, 6);
|
||||
}
|
||||
|
||||
if (p->borderWidth_ > 0.0f)
|
||||
{
|
||||
// Draw border
|
||||
gl.glDrawArrays(GL_TRIANGLES, 0, 24);
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers)
|
||||
glDrawArrays(GL_TRIANGLES, 0, 24);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Rectangle::Deinitialize()
|
||||
{
|
||||
gl::OpenGLFunctions& gl = p->context_->gl();
|
||||
|
||||
gl.glDeleteVertexArrays(1, &p->vao_);
|
||||
gl.glDeleteBuffers(1, &p->vbo_);
|
||||
glDeleteVertexArrays(1, &p->vao_);
|
||||
glDeleteBuffers(1, &p->vbo_);
|
||||
}
|
||||
|
||||
void Rectangle::SetBorder(float width, boost::gil::rgba8_pixel_t color)
|
||||
|
|
@ -206,8 +206,6 @@ void Rectangle::Impl::Update()
|
|||
{
|
||||
if (dirty_)
|
||||
{
|
||||
gl::OpenGLFunctions& gl = context_->gl();
|
||||
|
||||
const float lox = x_;
|
||||
const float rox = x_ + width_;
|
||||
const float boy = y_;
|
||||
|
|
@ -289,16 +287,13 @@ void Rectangle::Impl::Update()
|
|||
{lox, toy, z_, fc0, fc1, fc2, fc3} // TL
|
||||
}};
|
||||
|
||||
gl.glBufferData(GL_ARRAY_BUFFER,
|
||||
sizeof(float) * BUFFER_LENGTH,
|
||||
buffer,
|
||||
GL_DYNAMIC_DRAW);
|
||||
glBufferData(GL_ARRAY_BUFFER,
|
||||
sizeof(float) * BUFFER_LENGTH,
|
||||
static_cast<const void*>(buffer),
|
||||
GL_DYNAMIC_DRAW);
|
||||
|
||||
dirty_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace draw
|
||||
} // namespace gl
|
||||
} // namespace qt
|
||||
} // namespace scwx
|
||||
} // namespace scwx::qt::gl::draw
|
||||
|
|
|
|||
|
|
@ -1,25 +1,12 @@
|
|||
#pragma once
|
||||
|
||||
#include <QOpenGLFunctions_3_3_Core>
|
||||
#include <glad/gl.h>
|
||||
|
||||
#define SCWX_GL_CHECK_ERROR() \
|
||||
{ \
|
||||
GLenum err; \
|
||||
while ((err = gl.glGetError()) != GL_NO_ERROR) \
|
||||
while ((err = glGetError()) != GL_NO_ERROR) \
|
||||
{ \
|
||||
logger_->error("GL Error: {}, {}: {}", err, __FILE__, __LINE__); \
|
||||
} \
|
||||
}
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
namespace qt
|
||||
{
|
||||
namespace gl
|
||||
{
|
||||
|
||||
using OpenGLFunctions = QOpenGLFunctions_3_3_Core;
|
||||
|
||||
}
|
||||
} // namespace qt
|
||||
} // namespace scwx
|
||||
|
|
|
|||
|
|
@ -3,45 +3,38 @@
|
|||
#include <scwx/util/logger.hpp>
|
||||
|
||||
#include <boost/container_hash/hash.hpp>
|
||||
#include <QMessageBox>
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
namespace qt
|
||||
{
|
||||
namespace gl
|
||||
namespace scwx::qt::gl
|
||||
{
|
||||
|
||||
static const std::string logPrefix_ = "scwx::qt::gl::gl_context";
|
||||
static const auto logger_ = scwx::util::Logger::Create(logPrefix_);
|
||||
|
||||
class GlContext::Impl
|
||||
{
|
||||
public:
|
||||
explicit Impl() :
|
||||
gl_ {},
|
||||
shaderProgramMap_ {},
|
||||
shaderProgramMutex_ {},
|
||||
textureAtlas_ {GL_INVALID_INDEX},
|
||||
textureMutex_ {}
|
||||
{
|
||||
}
|
||||
~Impl() {}
|
||||
explicit Impl() = default;
|
||||
~Impl() = default;
|
||||
|
||||
Impl(const Impl&) = delete;
|
||||
Impl& operator=(const Impl&) = delete;
|
||||
Impl(const Impl&&) = delete;
|
||||
Impl& operator=(const Impl&&) = delete;
|
||||
|
||||
void InitializeGL();
|
||||
|
||||
static std::size_t
|
||||
GetShaderKey(std::initializer_list<std::pair<GLenum, std::string>> shaders);
|
||||
|
||||
gl::OpenGLFunctions gl_;
|
||||
QOpenGLFunctions_3_0 gl30_;
|
||||
|
||||
bool glInitialized_ {false};
|
||||
|
||||
std::unordered_map<std::size_t, std::shared_ptr<gl::ShaderProgram>>
|
||||
shaderProgramMap_;
|
||||
std::mutex shaderProgramMutex_;
|
||||
shaderProgramMap_ {};
|
||||
std::mutex shaderProgramMutex_ {};
|
||||
|
||||
GLuint textureAtlas_;
|
||||
std::mutex textureMutex_;
|
||||
GLuint textureAtlas_ {GL_INVALID_INDEX};
|
||||
std::mutex textureMutex_ {};
|
||||
|
||||
std::uint64_t textureBufferCount_ {};
|
||||
};
|
||||
|
|
@ -52,16 +45,6 @@ GlContext::~GlContext() = default;
|
|||
GlContext::GlContext(GlContext&&) noexcept = default;
|
||||
GlContext& GlContext::operator=(GlContext&&) noexcept = default;
|
||||
|
||||
gl::OpenGLFunctions& GlContext::gl()
|
||||
{
|
||||
return p->gl_;
|
||||
}
|
||||
|
||||
QOpenGLFunctions_3_0& GlContext::gl30()
|
||||
{
|
||||
return p->gl30_;
|
||||
}
|
||||
|
||||
std::uint64_t GlContext::texture_buffer_count() const
|
||||
{
|
||||
return p->textureBufferCount_;
|
||||
|
|
@ -74,10 +57,54 @@ void GlContext::Impl::InitializeGL()
|
|||
return;
|
||||
}
|
||||
|
||||
gl_.initializeOpenGLFunctions();
|
||||
gl30_.initializeOpenGLFunctions();
|
||||
const int gladVersion = gladLoaderLoadGL();
|
||||
if (!gladVersion)
|
||||
{
|
||||
logger_->error("gladLoaderLoadGL failed");
|
||||
|
||||
gl_.glGenTextures(1, &textureAtlas_);
|
||||
QMessageBox::critical(
|
||||
nullptr, "Supercell Wx", "Unable to initialize OpenGL");
|
||||
|
||||
throw std::runtime_error("Unable to initialize OpenGL");
|
||||
}
|
||||
|
||||
logger_->info("GLAD initialization complete: OpenGL {}.{}",
|
||||
GLAD_VERSION_MAJOR(gladVersion),
|
||||
GLAD_VERSION_MINOR(gladVersion));
|
||||
|
||||
auto glVersion = reinterpret_cast<const char*>(glGetString(GL_VERSION));
|
||||
auto glVendor = reinterpret_cast<const char*>(glGetString(GL_VENDOR));
|
||||
auto glRenderer = reinterpret_cast<const char*>(glGetString(GL_RENDERER));
|
||||
|
||||
logger_->info("OpenGL Version: {}", glVersion);
|
||||
logger_->info("OpenGL Vendor: {}", glVendor);
|
||||
logger_->info("OpenGL Renderer: {}", glRenderer);
|
||||
|
||||
// Get OpenGL version
|
||||
GLint major = 0;
|
||||
GLint minor = 0;
|
||||
glGetIntegerv(GL_MAJOR_VERSION, &major);
|
||||
glGetIntegerv(GL_MINOR_VERSION, &minor);
|
||||
|
||||
if (major < 3 || (major == 3 && minor < 3) || !GLAD_GL_VERSION_3_3)
|
||||
{
|
||||
logger_->error(
|
||||
"OpenGL 3.3 or greater is required, found {}.{}", major, minor);
|
||||
|
||||
QMessageBox::critical(
|
||||
nullptr,
|
||||
"Supercell Wx",
|
||||
QString("OpenGL 3.3 or greater is required, found %1.%2\n\n%3\n%4\n%5")
|
||||
.arg(major)
|
||||
.arg(minor)
|
||||
.arg(glVersion)
|
||||
.arg(glVendor)
|
||||
.arg(glRenderer));
|
||||
|
||||
throw std::runtime_error("OpenGL version too low");
|
||||
}
|
||||
|
||||
glGenTextures(1, &textureAtlas_);
|
||||
|
||||
glInitialized_ = true;
|
||||
}
|
||||
|
|
@ -102,7 +129,7 @@ std::shared_ptr<gl::ShaderProgram> GlContext::GetShaderProgram(
|
|||
|
||||
if (it == p->shaderProgramMap_.end())
|
||||
{
|
||||
shaderProgram = std::make_shared<gl::ShaderProgram>(p->gl_);
|
||||
shaderProgram = std::make_shared<gl::ShaderProgram>();
|
||||
shaderProgram->Load(shaders);
|
||||
p->shaderProgramMap_[key] = shaderProgram;
|
||||
}
|
||||
|
|
@ -125,7 +152,7 @@ GLuint GlContext::GetTextureAtlas()
|
|||
if (p->textureBufferCount_ != textureAtlas.BuildCount())
|
||||
{
|
||||
p->textureBufferCount_ = textureAtlas.BuildCount();
|
||||
textureAtlas.BufferAtlas(p->gl_, p->textureAtlas_);
|
||||
textureAtlas.BufferAtlas(p->textureAtlas_);
|
||||
}
|
||||
|
||||
return p->textureAtlas_;
|
||||
|
|
@ -138,10 +165,8 @@ void GlContext::Initialize()
|
|||
|
||||
void GlContext::StartFrame()
|
||||
{
|
||||
auto& gl = p->gl_;
|
||||
|
||||
gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
gl.glClear(GL_COLOR_BUFFER_BIT);
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
|
||||
std::size_t GlContext::Impl::GetShaderKey(
|
||||
|
|
@ -156,6 +181,4 @@ std::size_t GlContext::Impl::GetShaderKey(
|
|||
return seed;
|
||||
}
|
||||
|
||||
} // namespace gl
|
||||
} // namespace qt
|
||||
} // namespace scwx
|
||||
} // namespace scwx::qt::gl
|
||||
|
|
|
|||
|
|
@ -3,8 +3,6 @@
|
|||
#include <scwx/qt/gl/gl.hpp>
|
||||
#include <scwx/qt/gl/shader_program.hpp>
|
||||
|
||||
#include <QOpenGLFunctions_3_0>
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
namespace qt
|
||||
|
|
@ -24,9 +22,6 @@ public:
|
|||
GlContext(GlContext&&) noexcept;
|
||||
GlContext& operator=(GlContext&&) noexcept;
|
||||
|
||||
gl::OpenGLFunctions& gl();
|
||||
QOpenGLFunctions_3_0& gl30();
|
||||
|
||||
std::uint64_t texture_buffer_count() const;
|
||||
|
||||
std::shared_ptr<gl::ShaderProgram>
|
||||
|
|
|
|||
|
|
@ -2,12 +2,9 @@
|
|||
#include <scwx/util/logger.hpp>
|
||||
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
namespace qt
|
||||
{
|
||||
namespace gl
|
||||
namespace scwx::qt::gl
|
||||
{
|
||||
|
||||
static const std::string logPrefix_ = "scwx::qt::gl::shader_program";
|
||||
|
|
@ -23,29 +20,25 @@ static const std::unordered_map<GLenum, std::string> kShaderNames_ {
|
|||
class ShaderProgram::Impl
|
||||
{
|
||||
public:
|
||||
explicit Impl(OpenGLFunctions& gl) : gl_(gl), id_ {GL_INVALID_INDEX}
|
||||
{
|
||||
// Create shader program
|
||||
id_ = gl_.glCreateProgram();
|
||||
}
|
||||
explicit Impl() : id_ {glCreateProgram()} {}
|
||||
|
||||
~Impl()
|
||||
{
|
||||
// Delete shader program
|
||||
gl_.glDeleteProgram(id_);
|
||||
glDeleteProgram(id_);
|
||||
}
|
||||
|
||||
static std::string ShaderName(GLenum type);
|
||||
Impl(const Impl&) = delete;
|
||||
Impl& operator=(const Impl&) = delete;
|
||||
Impl(const Impl&&) = delete;
|
||||
Impl& operator=(const Impl&&) = delete;
|
||||
|
||||
OpenGLFunctions& gl_;
|
||||
static std::string ShaderName(GLenum type);
|
||||
|
||||
GLuint id_;
|
||||
};
|
||||
|
||||
ShaderProgram::ShaderProgram(OpenGLFunctions& gl) :
|
||||
p(std::make_unique<Impl>(gl))
|
||||
{
|
||||
}
|
||||
ShaderProgram::ShaderProgram() : p(std::make_unique<Impl>()) {}
|
||||
ShaderProgram::~ShaderProgram() = default;
|
||||
|
||||
ShaderProgram::ShaderProgram(ShaderProgram&&) noexcept = default;
|
||||
|
|
@ -58,7 +51,7 @@ GLuint ShaderProgram::id() const
|
|||
|
||||
GLint ShaderProgram::GetUniformLocation(const std::string& name)
|
||||
{
|
||||
GLint location = p->gl_.glGetUniformLocation(p->id_, name.c_str());
|
||||
const GLint location = glGetUniformLocation(p->id_, name.c_str());
|
||||
if (location == -1)
|
||||
{
|
||||
logger_->warn("Could not find {}", name);
|
||||
|
|
@ -88,8 +81,6 @@ bool ShaderProgram::Load(
|
|||
{
|
||||
logger_->debug("Load()");
|
||||
|
||||
OpenGLFunctions& gl = p->gl_;
|
||||
|
||||
GLint glSuccess;
|
||||
bool success = true;
|
||||
char infoLog[kInfoLogBufSize];
|
||||
|
|
@ -120,16 +111,17 @@ bool ShaderProgram::Load(
|
|||
const char* shaderSourceC = shaderSource.c_str();
|
||||
|
||||
// Create a shader
|
||||
GLuint shaderId = gl.glCreateShader(shader.first);
|
||||
const GLuint shaderId = glCreateShader(shader.first);
|
||||
shaderIds.push_back(shaderId);
|
||||
|
||||
// Attach the shader source code and compile the shader
|
||||
gl.glShaderSource(shaderId, 1, &shaderSourceC, NULL);
|
||||
gl.glCompileShader(shaderId);
|
||||
glShaderSource(shaderId, 1, &shaderSourceC, nullptr);
|
||||
glCompileShader(shaderId);
|
||||
|
||||
// Check for errors
|
||||
gl.glGetShaderiv(shaderId, GL_COMPILE_STATUS, &glSuccess);
|
||||
gl.glGetShaderInfoLog(shaderId, kInfoLogBufSize, &logLength, infoLog);
|
||||
glGetShaderiv(shaderId, GL_COMPILE_STATUS, &glSuccess);
|
||||
glGetShaderInfoLog(
|
||||
shaderId, kInfoLogBufSize, &logLength, static_cast<GLchar*>(infoLog));
|
||||
if (!glSuccess)
|
||||
{
|
||||
logger_->error("Shader compilation failed: {}", infoLog);
|
||||
|
|
@ -138,7 +130,7 @@ bool ShaderProgram::Load(
|
|||
}
|
||||
else if (logLength > 0)
|
||||
{
|
||||
logger_->error("Shader compiled with warnings: {}", infoLog);
|
||||
logger_->warn("Shader compiled with warnings: {}", infoLog);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -146,13 +138,14 @@ bool ShaderProgram::Load(
|
|||
{
|
||||
for (auto& shaderId : shaderIds)
|
||||
{
|
||||
gl.glAttachShader(p->id_, shaderId);
|
||||
glAttachShader(p->id_, shaderId);
|
||||
}
|
||||
gl.glLinkProgram(p->id_);
|
||||
glLinkProgram(p->id_);
|
||||
|
||||
// Check for errors
|
||||
gl.glGetProgramiv(p->id_, GL_LINK_STATUS, &glSuccess);
|
||||
gl.glGetProgramInfoLog(p->id_, kInfoLogBufSize, &logLength, infoLog);
|
||||
glGetProgramiv(p->id_, GL_LINK_STATUS, &glSuccess);
|
||||
glGetProgramInfoLog(
|
||||
p->id_, kInfoLogBufSize, &logLength, static_cast<GLchar*>(infoLog));
|
||||
if (!glSuccess)
|
||||
{
|
||||
logger_->error("Shader program link failed: {}", infoLog);
|
||||
|
|
@ -160,14 +153,14 @@ bool ShaderProgram::Load(
|
|||
}
|
||||
else if (logLength > 0)
|
||||
{
|
||||
logger_->error("Shader program linked with warnings: {}", infoLog);
|
||||
logger_->warn("Shader program linked with warnings: {}", infoLog);
|
||||
}
|
||||
}
|
||||
|
||||
// Delete shaders
|
||||
for (auto& shaderId : shaderIds)
|
||||
{
|
||||
gl.glDeleteShader(shaderId);
|
||||
glDeleteShader(shaderId);
|
||||
}
|
||||
|
||||
return success;
|
||||
|
|
@ -175,9 +168,7 @@ bool ShaderProgram::Load(
|
|||
|
||||
void ShaderProgram::Use() const
|
||||
{
|
||||
p->gl_.glUseProgram(p->id_);
|
||||
glUseProgram(p->id_);
|
||||
}
|
||||
|
||||
} // namespace gl
|
||||
} // namespace qt
|
||||
} // namespace scwx
|
||||
} // namespace scwx::qt::gl
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ namespace gl
|
|||
class ShaderProgram
|
||||
{
|
||||
public:
|
||||
explicit ShaderProgram(OpenGLFunctions& gl);
|
||||
explicit ShaderProgram();
|
||||
virtual ~ShaderProgram();
|
||||
|
||||
ShaderProgram(const ShaderProgram&) = delete;
|
||||
|
|
|
|||
|
|
@ -44,6 +44,14 @@ void WaitForInitialization()
|
|||
}
|
||||
}
|
||||
|
||||
// Only use for test cases
|
||||
void ResetInitilization()
|
||||
{
|
||||
logger_->debug("Application initialization reset");
|
||||
std::unique_lock lock(initializationMutex_);
|
||||
initialized_ = false;
|
||||
}
|
||||
|
||||
} // namespace Application
|
||||
} // namespace main
|
||||
} // namespace qt
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ namespace Application
|
|||
|
||||
void FinishInitialization();
|
||||
void WaitForInitialization();
|
||||
// Only use for test cases
|
||||
void ResetInitilization();
|
||||
|
||||
} // namespace Application
|
||||
} // namespace main
|
||||
|
|
|
|||
136
scwx-qt/source/scwx/qt/main/check_privilege.cpp
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
#include <scwx/qt/settings/general_settings.hpp>
|
||||
#include <scwx/qt/main/check_privilege.hpp>
|
||||
#include <QtGlobal>
|
||||
#include <QStandardPaths>
|
||||
#include <filesystem>
|
||||
#include <QObject>
|
||||
#include <QMessageBox>
|
||||
#include <QCheckBox>
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <windows.h>
|
||||
#else
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
namespace scwx::qt::main
|
||||
{
|
||||
|
||||
bool is_high_privilege()
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
bool isAdmin = false;
|
||||
HANDLE token = NULL;
|
||||
TOKEN_ELEVATION elevation;
|
||||
DWORD elevationSize = sizeof(TOKEN_ELEVATION);
|
||||
|
||||
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!GetTokenInformation(
|
||||
token, TokenElevation, &elevation, elevationSize, &elevationSize))
|
||||
{
|
||||
CloseHandle(token);
|
||||
return false;
|
||||
}
|
||||
isAdmin = elevation.TokenIsElevated;
|
||||
CloseHandle(token);
|
||||
return isAdmin;
|
||||
#elif defined(Q_OS_UNIX)
|
||||
// On UNIX root is always uid 0. On Linux this is enforced by the kernel.
|
||||
return geteuid() == 0;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(_WIN32)
|
||||
static const QString message = QObject::tr(
|
||||
"Supercell Wx has been run with administrator permissions. It is "
|
||||
"recommended to run it without administrator permissions Do you wish to "
|
||||
"continue?");
|
||||
#elif defined(Q_OS_UNIX)
|
||||
static const QString message = QObject::tr(
|
||||
"Supercell Wx has been run as root. It is recommended to run it as a normal "
|
||||
"user. Do you wish to continue?");
|
||||
#else
|
||||
static const QString message = QObject::tr("");
|
||||
#endif
|
||||
|
||||
static const QString title = QObject::tr("Supercell Wx");
|
||||
static const QString checkBoxText =
|
||||
QObject::tr("Do not show this warning again.");
|
||||
|
||||
class PrivilegeChecker::Impl
|
||||
{
|
||||
public:
|
||||
explicit Impl() :
|
||||
highPrivilege_ {is_high_privilege()},
|
||||
dialog_ {QMessageBox::Icon::Warning, title, message},
|
||||
checkBox_(new QCheckBox(checkBoxText, &dialog_))
|
||||
{
|
||||
const std::string appDataPath {
|
||||
QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)
|
||||
.toStdString()};
|
||||
hasAppData_ = std::filesystem::exists(appDataPath);
|
||||
|
||||
dialog_.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
|
||||
dialog_.setDefaultButton(QMessageBox::No);
|
||||
dialog_.setCheckBox(checkBox_);
|
||||
};
|
||||
|
||||
bool hasAppData_;
|
||||
bool firstCheckCheckBoxState_ {true};
|
||||
bool highPrivilege_;
|
||||
|
||||
QMessageBox dialog_;
|
||||
QCheckBox* checkBox_;
|
||||
};
|
||||
|
||||
PrivilegeChecker::PrivilegeChecker() :
|
||||
p(std::make_unique<PrivilegeChecker::Impl>())
|
||||
{
|
||||
}
|
||||
|
||||
PrivilegeChecker::~PrivilegeChecker() = default;
|
||||
|
||||
bool PrivilegeChecker::pre_settings_check()
|
||||
{
|
||||
if (p->hasAppData_ || !p->highPrivilege_)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const int result = p->dialog_.exec();
|
||||
p->firstCheckCheckBoxState_ = p->checkBox_->isChecked();
|
||||
|
||||
return result != QMessageBox::Yes;
|
||||
}
|
||||
|
||||
bool PrivilegeChecker::post_settings_check()
|
||||
{
|
||||
auto& highPrivilegeWarningEnabled =
|
||||
settings::GeneralSettings::Instance().high_privilege_warning_enabled();
|
||||
if (!highPrivilegeWarningEnabled.GetValue() || !p->highPrivilege_)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (!p->hasAppData_)
|
||||
{
|
||||
highPrivilegeWarningEnabled.StageValue(!p->firstCheckCheckBoxState_);
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (p->dialog_.exec())
|
||||
{
|
||||
case QMessageBox::Yes:
|
||||
highPrivilegeWarningEnabled.StageValue(!p->checkBox_->isChecked());
|
||||
return false;
|
||||
case QMessageBox::No:
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace scwx::qt::main
|
||||
30
scwx-qt/source/scwx/qt/main/check_privilege.hpp
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace scwx::qt::main
|
||||
{
|
||||
|
||||
bool is_high_privilege();
|
||||
|
||||
class PrivilegeChecker
|
||||
{
|
||||
public:
|
||||
explicit PrivilegeChecker();
|
||||
~PrivilegeChecker();
|
||||
|
||||
PrivilegeChecker(const PrivilegeChecker&) = delete;
|
||||
PrivilegeChecker& operator=(const PrivilegeChecker&) = delete;
|
||||
PrivilegeChecker(const PrivilegeChecker&&) = delete;
|
||||
PrivilegeChecker& operator=(const PrivilegeChecker&&) = delete;
|
||||
|
||||
// returning true means check failed.
|
||||
bool pre_settings_check();
|
||||
bool post_settings_check();
|
||||
|
||||
private:
|
||||
class Impl;
|
||||
std::unique_ptr<Impl> p;
|
||||
};
|
||||
|
||||
} // namespace scwx::qt::main
|
||||
|
|
@ -3,15 +3,18 @@
|
|||
#include <scwx/qt/config/county_database.hpp>
|
||||
#include <scwx/qt/config/radar_site.hpp>
|
||||
#include <scwx/qt/main/main_window.hpp>
|
||||
#include <scwx/qt/main/process_validation.hpp>
|
||||
#include <scwx/qt/main/versions.hpp>
|
||||
#include <scwx/qt/manager/log_manager.hpp>
|
||||
#include <scwx/qt/manager/radar_product_manager.hpp>
|
||||
#include <scwx/qt/manager/resource_manager.hpp>
|
||||
#include <scwx/qt/manager/settings_manager.hpp>
|
||||
#include <scwx/qt/manager/task_manager.hpp>
|
||||
#include <scwx/qt/manager/thread_manager.hpp>
|
||||
#include <scwx/qt/settings/general_settings.hpp>
|
||||
#include <scwx/qt/types/qt_types.hpp>
|
||||
#include <scwx/qt/ui/setup/setup_wizard.hpp>
|
||||
#include <scwx/qt/main/check_privilege.hpp>
|
||||
#include <scwx/network/cpr.hpp>
|
||||
#include <scwx/util/environment.hpp>
|
||||
#include <scwx/util/logger.hpp>
|
||||
|
|
@ -25,11 +28,21 @@
|
|||
#include <fmt/format.h>
|
||||
#include <QApplication>
|
||||
#include <QStandardPaths>
|
||||
#include <QStyleHints>
|
||||
#include <QSurfaceFormat>
|
||||
#include <QTranslator>
|
||||
#include <QPalette>
|
||||
#include <QStyle>
|
||||
|
||||
#define QT6CT_LIBRARY
|
||||
#include <qt6ct-common/qt6ct.h>
|
||||
#undef QT6CT_LIBRARY
|
||||
|
||||
static const std::string logPrefix_ = "scwx::main";
|
||||
static const auto logger_ = scwx::util::Logger::Create(logPrefix_);
|
||||
|
||||
static void ConfigureTheme(const std::vector<std::string>& args);
|
||||
static void InitializeOpenGL();
|
||||
static void OverrideDefaultStyle(const std::vector<std::string>& args);
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
|
|
@ -41,19 +54,28 @@ int main(int argc, char* argv[])
|
|||
args.push_back(argv[i]);
|
||||
}
|
||||
|
||||
if (!scwx::util::GetEnvironment("SCWX_TEST").empty())
|
||||
{
|
||||
QStandardPaths::setTestModeEnabled(true);
|
||||
}
|
||||
|
||||
// Initialize logger
|
||||
auto& logManager = scwx::qt::manager::LogManager::Instance();
|
||||
logManager.Initialize();
|
||||
|
||||
logger_->info("Supercell Wx v{} ({})",
|
||||
QCoreApplication::setApplicationName("Supercell Wx");
|
||||
|
||||
logManager.InitializeLogFile();
|
||||
|
||||
logger_->info("Supercell Wx v{}.{} ({})",
|
||||
scwx::qt::main::kVersionString_,
|
||||
scwx::qt::main::kBuildNumber_,
|
||||
scwx::qt::main::kCommitString_);
|
||||
|
||||
QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts, true);
|
||||
InitializeOpenGL();
|
||||
|
||||
QApplication a(argc, argv);
|
||||
|
||||
QCoreApplication::setApplicationName("Supercell Wx");
|
||||
scwx::network::cpr::SetUserAgent(
|
||||
fmt::format("SupercellWx/{}", scwx::qt::main::kVersionString_));
|
||||
|
||||
|
|
@ -64,9 +86,11 @@ int main(int argc, char* argv[])
|
|||
QCoreApplication::installTranslator(&translator);
|
||||
}
|
||||
|
||||
if (!scwx::util::GetEnvironment("SCWX_TEST").empty())
|
||||
// Test to see if scwx was run with high privilege
|
||||
scwx::qt::main::PrivilegeChecker privilegeChecker;
|
||||
if (privilegeChecker.pre_settings_check())
|
||||
{
|
||||
QStandardPaths::setTestModeEnabled(true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Start the io_context main loop
|
||||
|
|
@ -96,40 +120,54 @@ int main(int argc, char* argv[])
|
|||
Aws::InitAPI(awsSdkOptions);
|
||||
|
||||
// Initialize application
|
||||
logManager.InitializeLogFile();
|
||||
scwx::qt::config::RadarSite::Initialize();
|
||||
scwx::qt::config::CountyDatabase::Initialize();
|
||||
scwx::qt::manager::TaskManager::Initialize();
|
||||
scwx::qt::manager::SettingsManager::Instance().Initialize();
|
||||
scwx::qt::manager::ResourceManager::Initialize();
|
||||
|
||||
// Theme
|
||||
auto uiStyle = scwx::qt::types::GetUiStyle(
|
||||
scwx::qt::settings::GeneralSettings::Instance().theme().GetValue());
|
||||
ConfigureTheme(args);
|
||||
|
||||
if (uiStyle == scwx::qt::types::UiStyle::Default)
|
||||
// Check process modules for compatibility
|
||||
scwx::qt::main::CheckProcessModules();
|
||||
|
||||
int result = 0;
|
||||
if (privilegeChecker.post_settings_check())
|
||||
{
|
||||
OverrideDefaultStyle(args);
|
||||
result = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
QApplication::setStyle(
|
||||
QString::fromStdString(scwx::qt::types::GetUiStyleName(uiStyle)));
|
||||
}
|
||||
// Run initial setup if required
|
||||
if (scwx::qt::ui::setup::SetupWizard::IsSetupRequired())
|
||||
{
|
||||
scwx::qt::ui::setup::SetupWizard w;
|
||||
w.show();
|
||||
a.exec();
|
||||
}
|
||||
|
||||
// Run initial setup if required
|
||||
if (scwx::qt::ui::setup::SetupWizard::IsSetupRequired())
|
||||
{
|
||||
scwx::qt::ui::setup::SetupWizard w;
|
||||
w.show();
|
||||
a.exec();
|
||||
}
|
||||
// Run Qt main loop
|
||||
{
|
||||
scwx::qt::main::MainWindow w;
|
||||
|
||||
// Run Qt main loop
|
||||
int result;
|
||||
{
|
||||
scwx::qt::main::MainWindow w;
|
||||
w.show();
|
||||
result = a.exec();
|
||||
bool initialized = false;
|
||||
|
||||
try
|
||||
{
|
||||
w.show();
|
||||
initialized = true;
|
||||
}
|
||||
catch (const std::exception& ex)
|
||||
{
|
||||
logger_->critical(ex.what());
|
||||
}
|
||||
|
||||
if (initialized)
|
||||
{
|
||||
result = a.exec();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Deinitialize application
|
||||
|
|
@ -145,6 +183,7 @@ int main(int argc, char* argv[])
|
|||
// Shutdown application
|
||||
scwx::qt::manager::ResourceManager::Shutdown();
|
||||
scwx::qt::manager::SettingsManager::Instance().Shutdown();
|
||||
scwx::qt::manager::TaskManager::Shutdown();
|
||||
|
||||
// Shutdown AWS SDK
|
||||
Aws::ShutdownAPI(awsSdkOptions);
|
||||
|
|
@ -152,6 +191,73 @@ int main(int argc, char* argv[])
|
|||
return result;
|
||||
}
|
||||
|
||||
static void ConfigureTheme(const std::vector<std::string>& args)
|
||||
{
|
||||
auto& generalSettings = scwx::qt::settings::GeneralSettings::Instance();
|
||||
|
||||
auto uiStyle =
|
||||
scwx::qt::types::GetUiStyle(generalSettings.theme().GetValue());
|
||||
auto qtColorScheme = scwx::qt::types::GetQtColorScheme(uiStyle);
|
||||
|
||||
if (uiStyle == scwx::qt::types::UiStyle::Default)
|
||||
{
|
||||
OverrideDefaultStyle(args);
|
||||
}
|
||||
else
|
||||
{
|
||||
QApplication::setStyle(
|
||||
QString::fromStdString(scwx::qt::types::GetQtStyleName(uiStyle)));
|
||||
}
|
||||
|
||||
QGuiApplication::styleHints()->setColorScheme(qtColorScheme);
|
||||
|
||||
std::optional<std::string> paletteFile;
|
||||
if (uiStyle == scwx::qt::types::UiStyle::FusionCustom)
|
||||
{
|
||||
paletteFile = generalSettings.theme_file().GetValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
paletteFile = scwx::qt::types::GetQtPaletteFile(uiStyle);
|
||||
}
|
||||
|
||||
if (paletteFile)
|
||||
{
|
||||
QPalette defaultPalette = QApplication::style()->standardPalette();
|
||||
QPalette palette = Qt6CT::loadColorScheme(
|
||||
QString::fromStdString(*paletteFile), defaultPalette);
|
||||
|
||||
if (defaultPalette == palette)
|
||||
{
|
||||
logger_->warn("Failed to load palette file '{}'", *paletteFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
logger_->info("Loaded palette file '{}'", *paletteFile);
|
||||
}
|
||||
|
||||
QApplication::setPalette(palette);
|
||||
}
|
||||
}
|
||||
|
||||
static void InitializeOpenGL()
|
||||
{
|
||||
QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts, true);
|
||||
|
||||
QSurfaceFormat surfaceFormat = QSurfaceFormat::defaultFormat();
|
||||
surfaceFormat.setProfile(QSurfaceFormat::OpenGLContextProfile::CoreProfile);
|
||||
surfaceFormat.setRenderableType(QSurfaceFormat::RenderableType::OpenGL);
|
||||
|
||||
#if defined(__APPLE__)
|
||||
// For macOS, we must choose between OpenGL 4.1 Core and OpenGL 2.1
|
||||
// Compatibility. OpenGL 2.1 does not meet requirements for shaders used by
|
||||
// Supercell Wx.
|
||||
surfaceFormat.setVersion(4, 1);
|
||||
#endif
|
||||
|
||||
QSurfaceFormat::setDefaultFormat(surfaceFormat);
|
||||
}
|
||||
|
||||
static void
|
||||
OverrideDefaultStyle([[maybe_unused]] const std::vector<std::string>& args)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
#include "main_window.hpp"
|
||||
#include "./ui_main_window.h"
|
||||
|
||||
#include <scwx/qt/gl/gl_context.hpp>
|
||||
#include <scwx/qt/main/application.hpp>
|
||||
#include <scwx/qt/main/versions.hpp>
|
||||
#include <scwx/qt/manager/alert_manager.hpp>
|
||||
#include <scwx/qt/manager/hotkey_manager.hpp>
|
||||
#include <scwx/qt/manager/placefile_manager.hpp>
|
||||
#include <scwx/qt/manager/marker_manager.hpp>
|
||||
#include <scwx/qt/manager/position_manager.hpp>
|
||||
#include <scwx/qt/manager/radar_product_manager.hpp>
|
||||
#include <scwx/qt/manager/text_event_manager.hpp>
|
||||
|
|
@ -30,6 +32,7 @@
|
|||
#include <scwx/qt/ui/level2_settings_widget.hpp>
|
||||
#include <scwx/qt/ui/level3_products_widget.hpp>
|
||||
#include <scwx/qt/ui/placefile_dialog.hpp>
|
||||
#include <scwx/qt/ui/marker_dialog.hpp>
|
||||
#include <scwx/qt/ui/radar_site_dialog.hpp>
|
||||
#include <scwx/qt/ui/settings_dialog.hpp>
|
||||
#include <scwx/qt/ui/update_dialog.hpp>
|
||||
|
|
@ -52,10 +55,6 @@
|
|||
#include <QTimer>
|
||||
#include <QToolButton>
|
||||
|
||||
#if !defined(_MSC_VER)
|
||||
# include <date/date.h>
|
||||
#endif
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
namespace qt
|
||||
|
|
@ -90,11 +89,13 @@ public:
|
|||
imGuiDebugDialog_ {nullptr},
|
||||
layerDialog_ {nullptr},
|
||||
placefileDialog_ {nullptr},
|
||||
markerDialog_ {nullptr},
|
||||
radarSiteDialog_ {nullptr},
|
||||
settingsDialog_ {nullptr},
|
||||
updateDialog_ {nullptr},
|
||||
alertManager_ {manager::AlertManager::Instance()},
|
||||
placefileManager_ {manager::PlacefileManager::Instance()},
|
||||
markerManager_ {manager::MarkerManager::Instance()},
|
||||
positionManager_ {manager::PositionManager::Instance()},
|
||||
textEventManager_ {manager::TextEventManager::Instance()},
|
||||
timelineManager_ {manager::TimelineManager::Instance()},
|
||||
|
|
@ -139,6 +140,9 @@ public:
|
|||
}
|
||||
~MainWindowImpl()
|
||||
{
|
||||
homeRadarConnection_.disconnect();
|
||||
defaultTimeZoneConnection_.disconnect();
|
||||
|
||||
auto& generalSettings = settings::GeneralSettings::Instance();
|
||||
|
||||
auto& customStyleUrl = generalSettings.custom_style_url();
|
||||
|
|
@ -187,6 +191,8 @@ public:
|
|||
map::MapProvider mapProvider_;
|
||||
map::MapWidget* activeMap_;
|
||||
|
||||
std::shared_ptr<gl::GlContext> glContext_ {nullptr};
|
||||
|
||||
ui::CollapsibleGroup* mapSettingsGroup_;
|
||||
ui::CollapsibleGroup* level2ProductsGroup_;
|
||||
ui::CollapsibleGroup* level2SettingsGroup_;
|
||||
|
|
@ -207,6 +213,7 @@ public:
|
|||
ui::ImGuiDebugDialog* imGuiDebugDialog_;
|
||||
ui::LayerDialog* layerDialog_;
|
||||
ui::PlacefileDialog* placefileDialog_;
|
||||
ui::MarkerDialog* markerDialog_;
|
||||
ui::RadarSiteDialog* radarSiteDialog_;
|
||||
ui::SettingsDialog* settingsDialog_;
|
||||
ui::UpdateDialog* updateDialog_;
|
||||
|
|
@ -221,6 +228,7 @@ public:
|
|||
std::shared_ptr<manager::HotkeyManager> hotkeyManager_ {
|
||||
manager::HotkeyManager::Instance()};
|
||||
std::shared_ptr<manager::PlacefileManager> placefileManager_;
|
||||
std::shared_ptr<manager::MarkerManager> markerManager_;
|
||||
std::shared_ptr<manager::PositionManager> positionManager_;
|
||||
std::shared_ptr<manager::TextEventManager> textEventManager_;
|
||||
std::shared_ptr<manager::TimelineManager> timelineManager_;
|
||||
|
|
@ -237,9 +245,12 @@ public:
|
|||
layerActions_ {};
|
||||
bool layerActionsInitialized_ {false};
|
||||
|
||||
boost::signals2::scoped_connection homeRadarConnection_ {};
|
||||
boost::signals2::scoped_connection defaultTimeZoneConnection_ {};
|
||||
|
||||
std::vector<map::MapWidget*> maps_;
|
||||
|
||||
std::chrono::system_clock::time_point volumeTime_ {};
|
||||
std::chrono::system_clock::time_point selectedTime_ {};
|
||||
|
||||
public slots:
|
||||
void UpdateMapParameters(double latitude,
|
||||
|
|
@ -265,6 +276,7 @@ MainWindow::MainWindow(QWidget* parent) :
|
|||
ui->vcpLabel->setVisible(false);
|
||||
ui->vcpValueLabel->setVisible(false);
|
||||
ui->vcpDescriptionLabel->setVisible(false);
|
||||
ui->saveRadarProductsButton->setVisible(true);
|
||||
|
||||
p->radarSitePresetsMenu_ = new QMenu(this);
|
||||
ui->radarSitePresetsButton->setMenu(p->radarSitePresetsMenu_);
|
||||
|
|
@ -279,7 +291,6 @@ MainWindow::MainWindow(QWidget* parent) :
|
|||
|
||||
// Configure Alert Dock
|
||||
p->alertDockWidget_ = new ui::AlertDockWidget(this);
|
||||
p->alertDockWidget_->setVisible(false);
|
||||
addDockWidget(Qt::BottomDockWidgetArea, p->alertDockWidget_);
|
||||
|
||||
// GPS Info Dialog
|
||||
|
|
@ -308,18 +319,25 @@ MainWindow::MainWindow(QWidget* parent) :
|
|||
// Placefile Manager Dialog
|
||||
p->placefileDialog_ = new ui::PlacefileDialog(this);
|
||||
|
||||
// Marker Manager Dialog
|
||||
p->markerDialog_ = new ui::MarkerDialog(this);
|
||||
|
||||
// Layer Dialog
|
||||
p->layerDialog_ = new ui::LayerDialog(this);
|
||||
|
||||
// Settings Dialog
|
||||
p->settingsDialog_ = new ui::SettingsDialog(this);
|
||||
p->settingsDialog_ = new ui::SettingsDialog(p->settings_, this);
|
||||
|
||||
// Map Settings
|
||||
p->mapSettingsGroup_ = new ui::CollapsibleGroup(tr("Map Settings"), this);
|
||||
p->mapSettingsGroup_->GetContentsLayout()->addWidget(ui->mapStyleLabel);
|
||||
p->mapSettingsGroup_->GetContentsLayout()->addWidget(ui->mapStyleComboBox);
|
||||
p->mapSettingsGroup_->GetContentsLayout()->addWidget(
|
||||
ui->smoothRadarDataCheckBox);
|
||||
p->mapSettingsGroup_->GetContentsLayout()->addWidget(
|
||||
ui->trackLocationCheckBox);
|
||||
p->mapSettingsGroup_->GetContentsLayout()->addWidget(
|
||||
ui->saveRadarProductsButton);
|
||||
ui->radarToolboxScrollAreaContents->layout()->replaceWidget(
|
||||
ui->mapSettingsGroupBox, p->mapSettingsGroup_);
|
||||
ui->mapSettingsGroupBox->setVisible(false);
|
||||
|
|
@ -361,6 +379,7 @@ MainWindow::MainWindow(QWidget* parent) :
|
|||
p->animationDockWidget_ = new ui::AnimationDockWidget(this);
|
||||
p->timelineGroup_->GetContentsLayout()->addWidget(p->animationDockWidget_);
|
||||
ui->radarToolboxScrollAreaContents->layout()->addWidget(p->timelineGroup_);
|
||||
p->animationDockWidget_->UpdateTimeZone(p->activeMap_->GetDefaultTimeZone());
|
||||
|
||||
// Reset toolbox spacer at the bottom
|
||||
ui->radarToolboxScrollAreaContents->layout()->removeItem(
|
||||
|
|
@ -444,8 +463,37 @@ void MainWindow::keyReleaseEvent(QKeyEvent* ev)
|
|||
void MainWindow::showEvent(QShowEvent* event)
|
||||
{
|
||||
QMainWindow::showEvent(event);
|
||||
auto& uiSettings = settings::UiSettings::Instance();
|
||||
|
||||
resizeDocks({ui->radarToolboxDock}, {194}, Qt::Horizontal);
|
||||
// restore the geometry state
|
||||
std::string uiGeometry = uiSettings.main_ui_geometry().GetValue();
|
||||
restoreGeometry(
|
||||
QByteArray::fromBase64(QByteArray::fromStdString(uiGeometry)));
|
||||
|
||||
// restore the UI state
|
||||
std::string uiState = uiSettings.main_ui_state().GetValue();
|
||||
|
||||
bool restored =
|
||||
restoreState(QByteArray::fromBase64(QByteArray::fromStdString(uiState)));
|
||||
if (!restored)
|
||||
{
|
||||
resizeDocks({ui->radarToolboxDock}, {194}, Qt::Horizontal);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::closeEvent(QCloseEvent* event)
|
||||
{
|
||||
auto& uiSettings = settings::UiSettings::Instance();
|
||||
|
||||
// save the UI geometry
|
||||
QByteArray uiGeometry = saveGeometry().toBase64();
|
||||
uiSettings.main_ui_geometry().StageValue(uiGeometry.data());
|
||||
|
||||
// save the UI state
|
||||
QByteArray uiState = saveState().toBase64();
|
||||
uiSettings.main_ui_state().StageValue(uiState.data());
|
||||
|
||||
QMainWindow::closeEvent(event);
|
||||
}
|
||||
|
||||
void MainWindow::on_actionOpenNexrad_triggered()
|
||||
|
|
@ -461,12 +509,11 @@ void MainWindow::on_actionOpenNexrad_triggered()
|
|||
map::MapWidget* currentMap = p->activeMap_;
|
||||
|
||||
// Make sure the parent window properly repaints on close
|
||||
connect(
|
||||
dialog,
|
||||
&QFileDialog::finished,
|
||||
this,
|
||||
[this]() { update(); },
|
||||
Qt::QueuedConnection);
|
||||
connect(dialog,
|
||||
&QFileDialog::finished,
|
||||
this,
|
||||
static_cast<void (MainWindow::*)()>(&MainWindow::update),
|
||||
Qt::QueuedConnection);
|
||||
|
||||
connect(
|
||||
dialog,
|
||||
|
|
@ -527,12 +574,11 @@ void MainWindow::on_actionOpenTextEvent_triggered()
|
|||
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
// Make sure the parent window properly repaints on close
|
||||
connect(
|
||||
dialog,
|
||||
&QFileDialog::finished,
|
||||
this,
|
||||
[this]() { update(); },
|
||||
Qt::QueuedConnection);
|
||||
connect(dialog,
|
||||
&QFileDialog::finished,
|
||||
this,
|
||||
static_cast<void (MainWindow::*)()>(&MainWindow::update),
|
||||
Qt::QueuedConnection);
|
||||
|
||||
connect(dialog,
|
||||
&QFileDialog::fileSelected,
|
||||
|
|
@ -586,6 +632,11 @@ void MainWindow::on_actionPlacefileManager_triggered()
|
|||
p->placefileDialog_->show();
|
||||
}
|
||||
|
||||
void MainWindow::on_actionMarkerManager_triggered()
|
||||
{
|
||||
p->markerDialog_->show();
|
||||
}
|
||||
|
||||
void MainWindow::on_actionLayerManager_triggered()
|
||||
{
|
||||
p->layerDialog_->show();
|
||||
|
|
@ -606,6 +657,11 @@ void MainWindow::on_actionDumpRadarProductRecords_triggered()
|
|||
manager::RadarProductManager::DumpRecords();
|
||||
}
|
||||
|
||||
void MainWindow::on_actionRadarWireframe_triggered(bool checked)
|
||||
{
|
||||
p->activeMap_->SetRadarWireframeEnabled(checked);
|
||||
}
|
||||
|
||||
void MainWindow::on_actionUserManual_triggered()
|
||||
{
|
||||
QDesktopServices::openUrl(QUrl {"https://supercell-wx.readthedocs.io/"});
|
||||
|
|
@ -726,6 +782,8 @@ void MainWindowImpl::ConfigureMapLayout()
|
|||
}
|
||||
};
|
||||
|
||||
glContext_ = std::make_shared<gl::GlContext>();
|
||||
|
||||
for (int64_t y = 0; y < gridHeight; y++)
|
||||
{
|
||||
QSplitter* hs = new QSplitter(vs);
|
||||
|
|
@ -735,7 +793,9 @@ void MainWindowImpl::ConfigureMapLayout()
|
|||
{
|
||||
if (maps_.at(mapIndex) == nullptr)
|
||||
{
|
||||
maps_[mapIndex] = new map::MapWidget(mapIndex, settings_);
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-owning-memory): Owned by parent
|
||||
maps_[mapIndex] =
|
||||
new map::MapWidget(mapIndex, settings_, glContext_);
|
||||
}
|
||||
|
||||
hs->addWidget(maps_[mapIndex]);
|
||||
|
|
@ -768,9 +828,9 @@ void MainWindowImpl::ConfigureMapStyles()
|
|||
if ((customStyleAvailable_ && styleName == "Custom") ||
|
||||
std::find_if(mapProviderInfo.mapStyles_.cbegin(),
|
||||
mapProviderInfo.mapStyles_.cend(),
|
||||
[&](const auto& mapStyle) {
|
||||
return mapStyle.name_ == styleName;
|
||||
}) != mapProviderInfo.mapStyles_.cend())
|
||||
[&](const auto& mapStyle)
|
||||
{ return mapStyle.name_ == styleName; }) !=
|
||||
mapProviderInfo.mapStyles_.cend())
|
||||
{
|
||||
// Initialize map style from settings
|
||||
maps_.at(i)->SetInitialMapStyle(styleName);
|
||||
|
|
@ -913,11 +973,28 @@ void MainWindowImpl::ConnectMapSignals()
|
|||
}
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
connect(
|
||||
mapWidget,
|
||||
&map::MapWidget::IncomingLevel2ElevationChanged,
|
||||
this,
|
||||
[this](std::optional<float>)
|
||||
{ level2SettingsWidget_->UpdateSettings(activeMap_); },
|
||||
Qt::QueuedConnection);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindowImpl::ConnectAnimationSignals()
|
||||
{
|
||||
defaultTimeZoneConnection_ = settings::GeneralSettings::Instance()
|
||||
.default_time_zone()
|
||||
.changed_signal()
|
||||
.connect(
|
||||
[this]()
|
||||
{
|
||||
animationDockWidget_->UpdateTimeZone(
|
||||
activeMap_->GetDefaultTimeZone());
|
||||
});
|
||||
|
||||
connect(animationDockWidget_,
|
||||
&ui::AnimationDockWidget::DateTimeChanged,
|
||||
timelineManager_.get(),
|
||||
|
|
@ -961,21 +1038,16 @@ void MainWindowImpl::ConnectAnimationSignals()
|
|||
|
||||
connect(timelineManager_.get(),
|
||||
&manager::TimelineManager::SelectedTimeUpdated,
|
||||
[this]()
|
||||
{
|
||||
for (auto map : maps_)
|
||||
{
|
||||
map->update();
|
||||
}
|
||||
});
|
||||
connect(timelineManager_.get(),
|
||||
&manager::TimelineManager::VolumeTimeUpdated,
|
||||
[this](std::chrono::system_clock::time_point dateTime)
|
||||
{
|
||||
volumeTime_ = dateTime;
|
||||
selectedTime_ = dateTime;
|
||||
|
||||
for (auto map : maps_)
|
||||
{
|
||||
map->SelectTime(dateTime);
|
||||
textEventManager_->SelectTime(dateTime);
|
||||
QMetaObject::invokeMethod(
|
||||
map, static_cast<void (QWidget::*)()>(&QWidget::update));
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -1055,10 +1127,29 @@ void MainWindowImpl::ConnectOtherSignals()
|
|||
}
|
||||
}
|
||||
});
|
||||
connect(
|
||||
mainWindow_->ui->smoothRadarDataCheckBox,
|
||||
&QCheckBox::checkStateChanged,
|
||||
mainWindow_,
|
||||
[this](Qt::CheckState state)
|
||||
{
|
||||
const bool smoothingEnabled = (state == Qt::CheckState::Checked);
|
||||
|
||||
auto it = std::find(maps_.cbegin(), maps_.cend(), activeMap_);
|
||||
if (it != maps_.cend())
|
||||
{
|
||||
const std::size_t i = std::distance(maps_.cbegin(), it);
|
||||
settings::MapSettings::Instance().smoothing_enabled(i).StageValue(
|
||||
smoothingEnabled);
|
||||
}
|
||||
|
||||
// Turn on smoothing
|
||||
activeMap_->SetSmoothingEnabled(smoothingEnabled);
|
||||
});
|
||||
connect(mainWindow_->ui->trackLocationCheckBox,
|
||||
&QCheckBox::stateChanged,
|
||||
&QCheckBox::checkStateChanged,
|
||||
mainWindow_,
|
||||
[this](int state)
|
||||
[this](Qt::CheckState state)
|
||||
{
|
||||
bool trackingEnabled = (state == Qt::CheckState::Checked);
|
||||
|
||||
|
|
@ -1068,22 +1159,37 @@ void MainWindowImpl::ConnectOtherSignals()
|
|||
// Turn on location tracking
|
||||
positionManager_->TrackLocation(trackingEnabled);
|
||||
});
|
||||
connect(level2ProductsWidget_,
|
||||
&ui::Level2ProductsWidget::RadarProductSelected,
|
||||
mainWindow_,
|
||||
[&](common::RadarProductGroup group,
|
||||
const std::string& productName,
|
||||
int16_t productCode) {
|
||||
SelectRadarProduct(activeMap_, group, productName, productCode);
|
||||
});
|
||||
connect(level3ProductsWidget_,
|
||||
&ui::Level3ProductsWidget::RadarProductSelected,
|
||||
mainWindow_,
|
||||
[&](common::RadarProductGroup group,
|
||||
const std::string& productName,
|
||||
int16_t productCode) {
|
||||
SelectRadarProduct(activeMap_, group, productName, productCode);
|
||||
});
|
||||
connect(
|
||||
mainWindow_->ui->saveRadarProductsButton,
|
||||
&QAbstractButton::clicked,
|
||||
mainWindow_,
|
||||
[this]()
|
||||
{
|
||||
auto& mapSettings = settings::MapSettings::Instance();
|
||||
for (std::size_t i = 0; i < maps_.size(); i++)
|
||||
{
|
||||
const auto& map = maps_.at(i);
|
||||
mapSettings.radar_product_group(i).StageValue(
|
||||
common::GetRadarProductGroupName(map->GetRadarProductGroup()));
|
||||
mapSettings.radar_product(i).StageValue(map->GetRadarProductName());
|
||||
}
|
||||
});
|
||||
connect(
|
||||
level2ProductsWidget_,
|
||||
&ui::Level2ProductsWidget::RadarProductSelected,
|
||||
mainWindow_,
|
||||
[&](common::RadarProductGroup group,
|
||||
const std::string& productName,
|
||||
int16_t productCode)
|
||||
{ SelectRadarProduct(activeMap_, group, productName, productCode); });
|
||||
connect(
|
||||
level3ProductsWidget_,
|
||||
&ui::Level3ProductsWidget::RadarProductSelected,
|
||||
mainWindow_,
|
||||
[&](common::RadarProductGroup group,
|
||||
const std::string& productName,
|
||||
int16_t productCode)
|
||||
{ SelectRadarProduct(activeMap_, group, productName, productCode); });
|
||||
connect(level2SettingsWidget_,
|
||||
&ui::Level2SettingsWidget::ElevationSelected,
|
||||
mainWindow_,
|
||||
|
|
@ -1194,11 +1300,33 @@ void MainWindowImpl::ConnectOtherSignals()
|
|||
this,
|
||||
[this]()
|
||||
{
|
||||
timeLabel_->setText(QString::fromStdString(
|
||||
util::TimeString(std::chrono::system_clock::now())));
|
||||
timeLabel_->setText(
|
||||
QString::fromStdString(util::TimeString(util::time::now())));
|
||||
timeLabel_->setVisible(true);
|
||||
});
|
||||
clockTimer_.start(1000);
|
||||
|
||||
auto& generalSettings = settings::GeneralSettings::Instance();
|
||||
homeRadarConnection_ =
|
||||
generalSettings.default_radar_site().changed_signal().connect(
|
||||
[this]()
|
||||
{
|
||||
const std::shared_ptr<config::RadarSite> radarSite =
|
||||
activeMap_->GetRadarSite();
|
||||
const std::string homeRadarSite =
|
||||
settings::GeneralSettings::Instance()
|
||||
.default_radar_site()
|
||||
.GetValue();
|
||||
if (radarSite == nullptr)
|
||||
{
|
||||
mainWindow_->ui->saveRadarProductsButton->setVisible(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
mainWindow_->ui->saveRadarProductsButton->setVisible(
|
||||
radarSite->id() == homeRadarSite);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void MainWindowImpl::InitializeLayerDisplayActions()
|
||||
|
|
@ -1363,7 +1491,8 @@ void MainWindowImpl::SelectRadarProduct(map::MapWidget* mapWidget,
|
|||
UpdateRadarProductSettings();
|
||||
}
|
||||
|
||||
mapWidget->SelectRadarProduct(group, productName, productCode, volumeTime_);
|
||||
mapWidget->SelectRadarProduct(
|
||||
group, productName, productCode, selectedTime_);
|
||||
}
|
||||
|
||||
void MainWindowImpl::SetActiveMap(map::MapWidget* mapWidget)
|
||||
|
|
@ -1433,18 +1562,28 @@ void MainWindowImpl::UpdateRadarProductSettings()
|
|||
{
|
||||
if (activeMap_->GetRadarProductGroup() == common::RadarProductGroup::Level2)
|
||||
{
|
||||
level2SettingsWidget_->UpdateSettings(activeMap_);
|
||||
level2SettingsGroup_->setVisible(true);
|
||||
// This should be done after setting visible for correct sizing
|
||||
level2SettingsWidget_->UpdateSettings(activeMap_);
|
||||
}
|
||||
else
|
||||
{
|
||||
level2SettingsGroup_->setVisible(false);
|
||||
}
|
||||
|
||||
mainWindow_->ui->smoothRadarDataCheckBox->setCheckState(
|
||||
activeMap_->GetSmoothingEnabled() ? Qt::CheckState::Checked :
|
||||
Qt::CheckState::Unchecked);
|
||||
|
||||
mainWindow_->ui->actionRadarWireframe->setChecked(
|
||||
activeMap_->GetRadarWireframeEnabled());
|
||||
}
|
||||
|
||||
void MainWindowImpl::UpdateRadarSite()
|
||||
{
|
||||
std::shared_ptr<config::RadarSite> radarSite = activeMap_->GetRadarSite();
|
||||
const std::string homeRadarSite =
|
||||
settings::GeneralSettings::Instance().default_radar_site().GetValue();
|
||||
|
||||
if (radarSite != nullptr)
|
||||
{
|
||||
|
|
@ -1459,6 +1598,9 @@ void MainWindowImpl::UpdateRadarSite()
|
|||
radarSite->location_name().c_str());
|
||||
|
||||
timelineManager_->SetRadarSite(radarSite->id());
|
||||
|
||||
mainWindow_->ui->saveRadarProductsButton->setVisible(radarSite->id() ==
|
||||
homeRadarSite);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1466,12 +1608,15 @@ void MainWindowImpl::UpdateRadarSite()
|
|||
|
||||
mainWindow_->ui->radarSiteValueLabel->setVisible(false);
|
||||
mainWindow_->ui->radarLocationLabel->setVisible(false);
|
||||
mainWindow_->ui->saveRadarProductsButton->setVisible(false);
|
||||
|
||||
timelineManager_->SetRadarSite("?");
|
||||
}
|
||||
|
||||
alertManager_->SetRadarSite(radarSite);
|
||||
placefileManager_->SetRadarSite(radarSite);
|
||||
|
||||
animationDockWidget_->UpdateTimeZone(activeMap_->GetDefaultTimeZone());
|
||||
}
|
||||
|
||||
void MainWindowImpl::UpdateVcp()
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ public:
|
|||
void keyPressEvent(QKeyEvent* ev) override final;
|
||||
void keyReleaseEvent(QKeyEvent* ev) override final;
|
||||
void showEvent(QShowEvent* event) override;
|
||||
void closeEvent(QCloseEvent* event) override;
|
||||
|
||||
signals:
|
||||
void ActiveMapMoved(double latitude, double longitude);
|
||||
|
|
@ -43,10 +44,12 @@ private slots:
|
|||
void on_actionRadarRange_triggered(bool checked);
|
||||
void on_actionRadarSites_triggered(bool checked);
|
||||
void on_actionPlacefileManager_triggered();
|
||||
void on_actionMarkerManager_triggered();
|
||||
void on_actionLayerManager_triggered();
|
||||
void on_actionImGuiDebug_triggered();
|
||||
void on_actionDumpLayerList_triggered();
|
||||
void on_actionDumpRadarProductRecords_triggered();
|
||||
void on_actionRadarWireframe_triggered(bool checked);
|
||||
void on_actionUserManual_triggered();
|
||||
void on_actionDiscord_triggered();
|
||||
void on_actionGitHubRepository_triggered();
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1024</width>
|
||||
<height>33</height>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuFile">
|
||||
|
|
@ -97,6 +97,8 @@
|
|||
<addaction name="separator"/>
|
||||
<addaction name="actionDumpLayerList"/>
|
||||
<addaction name="actionDumpRadarProductRecords"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionRadarWireframe"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuTools">
|
||||
<property name="title">
|
||||
|
|
@ -104,6 +106,7 @@
|
|||
</property>
|
||||
<addaction name="actionPlacefileManager"/>
|
||||
<addaction name="actionLayerManager"/>
|
||||
<addaction name="actionMarkerManager"/>
|
||||
</widget>
|
||||
<addaction name="menuFile"/>
|
||||
<addaction name="menuView"/>
|
||||
|
|
@ -152,8 +155,8 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>190</width>
|
||||
<height>686</height>
|
||||
<width>191</width>
|
||||
<height>703</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
|
|
@ -171,39 +174,25 @@
|
|||
</property>
|
||||
<item>
|
||||
<widget class="QFrame" name="radarInfoFrame">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Shape::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Shadow::Raised</enum>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout" columnstretch="0,0,0,0,0">
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="radarSiteValueLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<item row="3" column="2" colspan="3">
|
||||
<widget class="QLabel" name="vcpValueLabel">
|
||||
<property name="text">
|
||||
<string notr="true">KLSX</string>
|
||||
<string notr="true">35</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<widget class="QLabel" name="vcpLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Volume Coverage Pattern</string>
|
||||
</property>
|
||||
<item row="4" column="2" colspan="3">
|
||||
<widget class="QLabel" name="vcpDescriptionLabel">
|
||||
<property name="text">
|
||||
<string>VCP</string>
|
||||
<string>Clear Air Mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2" colspan="3">
|
||||
<widget class="QLabel" name="radarLocationLabel">
|
||||
<property name="text">
|
||||
<string notr="true">St. Louis, MO</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
@ -268,34 +257,6 @@
|
|||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QLabel" name="radarSiteLabel">
|
||||
<property name="text">
|
||||
<string>Radar Site</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2" colspan="3">
|
||||
<widget class="QLabel" name="radarLocationLabel">
|
||||
<property name="text">
|
||||
<string notr="true">St. Louis, MO</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2" colspan="3">
|
||||
<widget class="QLabel" name="vcpValueLabel">
|
||||
<property name="text">
|
||||
<string notr="true">35</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="2" colspan="3">
|
||||
<widget class="QLabel" name="vcpDescriptionLabel">
|
||||
<property name="text">
|
||||
<string>Clear Air Mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QToolButton" name="radarSiteSelectButton">
|
||||
<property name="maximumSize">
|
||||
|
|
@ -309,6 +270,42 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<widget class="QLabel" name="vcpLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Volume Coverage Pattern</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>VCP</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QLabel" name="radarSiteLabel">
|
||||
<property name="text">
|
||||
<string>Radar Site</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="radarSiteValueLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">KLSX</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
@ -328,6 +325,13 @@
|
|||
<item>
|
||||
<widget class="QComboBox" name="mapStyleComboBox"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="smoothRadarDataCheckBox">
|
||||
<property name="text">
|
||||
<string>Smooth Radar Data</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="trackLocationCheckBox">
|
||||
<property name="text">
|
||||
|
|
@ -335,6 +339,13 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="saveRadarProductsButton">
|
||||
<property name="text">
|
||||
<string>Set As Default Products</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
@ -487,6 +498,23 @@
|
|||
<string>&GPS Info</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionMarkerManager">
|
||||
<property name="icon">
|
||||
<iconset resource="../../../../scwx-qt.qrc">
|
||||
<normaloff>:/res/icons/font-awesome-6/house-solid.svg</normaloff>:/res/icons/font-awesome-6/house-solid.svg</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Location &Marker Manager</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionRadarWireframe">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Radar &Wireframe</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../../../../scwx-qt.qrc"/>
|
||||
|
|
|
|||
109
scwx-qt/source/scwx/qt/main/process_validation.cpp
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
#include <scwx/qt/main/process_validation.hpp>
|
||||
#include <scwx/util/logger.hpp>
|
||||
|
||||
#if defined(_WIN32)
|
||||
# include <scwx/qt/settings/general_settings.hpp>
|
||||
|
||||
# include <wtypes.h>
|
||||
# include <Psapi.h>
|
||||
|
||||
# include <boost/algorithm/string/predicate.hpp>
|
||||
# include <boost/locale.hpp>
|
||||
# include <fmt/ranges.h>
|
||||
# include <QCheckBox>
|
||||
# include <QMessageBox>
|
||||
#endif
|
||||
|
||||
namespace scwx::qt::main
|
||||
{
|
||||
|
||||
static const std::string logPrefix_ = "scwx::qt::main::process_validation";
|
||||
static const auto logger_ = util::Logger::Create(logPrefix_);
|
||||
|
||||
void CheckProcessModules()
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
HANDLE process = GetCurrentProcess();
|
||||
HMODULE modules[1024];
|
||||
DWORD cbNeeded = 0;
|
||||
|
||||
std::vector<std::string> incompatibleDlls {};
|
||||
std::vector<std::string> descriptions {};
|
||||
|
||||
auto& processModuleWarningsEnabled =
|
||||
settings::GeneralSettings::Instance().process_module_warnings_enabled();
|
||||
|
||||
if (EnumProcessModules(process, modules, sizeof(modules), &cbNeeded))
|
||||
{
|
||||
std::uint32_t numModules = cbNeeded / sizeof(HMODULE);
|
||||
for (std::uint32_t i = 0; i < numModules; ++i)
|
||||
{
|
||||
char modulePath[MAX_PATH];
|
||||
if (GetModuleFileNameExA(process, modules[i], modulePath, MAX_PATH))
|
||||
{
|
||||
std::string path = modulePath;
|
||||
|
||||
logger_->trace("DLL Found: {}", path);
|
||||
|
||||
if (boost::algorithm::iends_with(path, "NahimicOSD.dll"))
|
||||
{
|
||||
std::string description =
|
||||
QObject::tr(
|
||||
"ASUS Sonic Studio injects a Nahimic driver, which causes "
|
||||
"Supercell Wx to hang. It is suggested to disable the "
|
||||
"Nahimic service, or to uninstall ASUS Sonic Studio and "
|
||||
"the Nahimic driver.")
|
||||
.toStdString();
|
||||
|
||||
logger_->warn("Incompatible DLL found: {}", path);
|
||||
logger_->warn("{}", description);
|
||||
|
||||
// Only populate vectors for the message box if warnings are
|
||||
// enabled
|
||||
if (processModuleWarningsEnabled.GetValue())
|
||||
{
|
||||
incompatibleDlls.push_back(path);
|
||||
descriptions.push_back(description);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!incompatibleDlls.empty())
|
||||
{
|
||||
const std::string header =
|
||||
QObject::tr(
|
||||
"The following DLLs have been injected into the Supercell Wx "
|
||||
"process:")
|
||||
.toStdString();
|
||||
const std::string defaultMessage =
|
||||
QObject::tr(
|
||||
"Supercell Wx is known to not run correctly with these DLLs "
|
||||
"injected. We suggest stopping or uninstalling these services if "
|
||||
"you experience crashes or unexpected behavior while using "
|
||||
"Supercell Wx.")
|
||||
.toStdString();
|
||||
|
||||
std::string message = fmt::format("{}\n\n{}\n\n{}\n\n{}",
|
||||
header,
|
||||
fmt::join(incompatibleDlls, "\n"),
|
||||
defaultMessage,
|
||||
fmt::join(descriptions, "\n"));
|
||||
|
||||
QMessageBox dialog(QMessageBox::Icon::Warning,
|
||||
QObject::tr("Supercell Wx"),
|
||||
QString::fromStdString(message));
|
||||
QCheckBox* checkBox =
|
||||
new QCheckBox(QObject::tr("Don't show this message again"), &dialog);
|
||||
dialog.setCheckBox(checkBox);
|
||||
dialog.exec();
|
||||
|
||||
// Stage the result of the checkbox. This value will be committed on
|
||||
// shutdown.
|
||||
processModuleWarningsEnabled.StageValue(!checkBox->isChecked());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace scwx::qt::main
|
||||
8
scwx-qt/source/scwx/qt/main/process_validation.hpp
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
namespace scwx::qt::main
|
||||
{
|
||||
|
||||
void CheckProcessModules();
|
||||
|
||||
} // namespace scwx::qt::main
|
||||
|
|
@ -3,17 +3,12 @@
|
|||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
namespace qt
|
||||
{
|
||||
namespace main
|
||||
namespace scwx::qt::main
|
||||
{
|
||||
|
||||
const std::uint32_t kBuildNumber_ {${build_number}u};
|
||||
const std::string kCommitString_ {"${commit_string}"};
|
||||
const std::uint16_t kCopyrightYear_ {${copyright_year}u};
|
||||
const std::string kVersionString_ {"${version_string}"};
|
||||
|
||||
} // namespace main
|
||||
} // namespace qt
|
||||
} // namespace scwx
|
||||
} // namespace scwx::qt::main
|
||||
|
|
|
|||
|
|
@ -2,12 +2,13 @@
|
|||
#include <scwx/qt/manager/media_manager.hpp>
|
||||
#include <scwx/qt/manager/position_manager.hpp>
|
||||
#include <scwx/qt/manager/text_event_manager.hpp>
|
||||
#include <scwx/qt/config/radar_site.hpp>
|
||||
#include <scwx/qt/settings/audio_settings.hpp>
|
||||
#include <scwx/qt/settings/general_settings.hpp>
|
||||
#include <scwx/qt/types/location_types.hpp>
|
||||
#include <scwx/qt/util/geographic_lib.hpp>
|
||||
#include <scwx/util/logger.hpp>
|
||||
#include <scwx/qt/config/radar_site.hpp>
|
||||
#include <scwx/qt/settings/general_settings.hpp>
|
||||
#include <scwx/util/time.hpp>
|
||||
|
||||
#include <boost/asio/post.hpp>
|
||||
#include <boost/asio/thread_pool.hpp>
|
||||
|
|
@ -138,8 +139,10 @@ common::Coordinate AlertManager::Impl::CurrentCoordinate(
|
|||
void AlertManager::Impl::HandleAlert(const types::TextEventKey& key,
|
||||
size_t messageIndex) const
|
||||
{
|
||||
auto messages = textEventManager_->message_list(key);
|
||||
|
||||
// Skip alert if there are more messages to be processed
|
||||
if (messageIndex + 1 < textEventManager_->message_count(key))
|
||||
if (messages.empty() || messageIndex + 1 < messages.size())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -153,7 +156,7 @@ void AlertManager::Impl::HandleAlert(const types::TextEventKey& key,
|
|||
audioSettings.alert_radius().GetValue());
|
||||
std::string alertWFO = audioSettings.alert_wfo().GetValue();
|
||||
|
||||
auto message = textEventManager_->message_list(key).at(messageIndex);
|
||||
auto message = messages.at(messageIndex);
|
||||
|
||||
for (auto& segment : message->segments())
|
||||
{
|
||||
|
|
@ -170,7 +173,7 @@ void AlertManager::Impl::HandleAlert(const types::TextEventKey& key,
|
|||
|
||||
// If the event has ended or is inactive, or if the alert is not enabled,
|
||||
// skip it
|
||||
if (eventEnd < std::chrono::system_clock::now() || !alertActive ||
|
||||
if (eventEnd < scwx::util::time::now() || !alertActive ||
|
||||
!audioSettings.alert_enabled(phenomenon).GetValue())
|
||||
{
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -155,7 +155,7 @@ void DownloadManager::Impl::DownloadSync(
|
|||
return !request->IsCanceled();
|
||||
}),
|
||||
cpr::WriteCallback(
|
||||
[&](std::string data, std::intptr_t /* userdata */)
|
||||
[&](const std::string_view& data, std::intptr_t /* userdata */)
|
||||
{
|
||||
// Write file
|
||||
ofs << data;
|
||||
|
|
|
|||
|
|
@ -15,19 +15,17 @@
|
|||
#include <boost/container_hash/hash.hpp>
|
||||
#include <boost/unordered/unordered_flat_map.hpp>
|
||||
#include <boost/unordered/unordered_flat_set.hpp>
|
||||
#include <fmt/ranges.h>
|
||||
#include <fontconfig/fontconfig.h>
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
namespace qt
|
||||
{
|
||||
namespace manager
|
||||
namespace scwx::qt::manager
|
||||
{
|
||||
|
||||
static const std::string logPrefix_ = "scwx::qt::manager::font_manager";
|
||||
static const auto logger_ = scwx::util::Logger::Create(logPrefix_);
|
||||
|
||||
static const std::string kFcTrueType_ {"TrueType"};
|
||||
static const std::string kFcOpenType_ {"CFF"};
|
||||
|
||||
struct FontRecord
|
||||
{
|
||||
|
|
@ -36,15 +34,13 @@ struct FontRecord
|
|||
std::string filename_ {};
|
||||
};
|
||||
|
||||
typedef std::pair<FontRecord, units::font_size::pixels<int>> FontRecordPair;
|
||||
|
||||
template<class Key>
|
||||
struct FontRecordHash;
|
||||
|
||||
template<>
|
||||
struct FontRecordHash<FontRecordPair>
|
||||
struct FontRecordHash<FontRecord>
|
||||
{
|
||||
size_t operator()(const FontRecordPair& x) const;
|
||||
size_t operator()(const FontRecord& x) const;
|
||||
};
|
||||
|
||||
class FontManager::Impl
|
||||
|
|
@ -69,6 +65,7 @@ public:
|
|||
|
||||
const std::vector<char>& GetRawFontData(const std::string& filename);
|
||||
|
||||
static bool CheckFontFormat(const FcChar8* format);
|
||||
static FontRecord MatchFontFile(const std::string& family,
|
||||
const std::vector<std::string>& styles);
|
||||
|
||||
|
|
@ -78,20 +75,20 @@ public:
|
|||
|
||||
std::shared_mutex imguiFontAtlasMutex_ {};
|
||||
|
||||
std::uint64_t imguiFontsBuildCount_ {};
|
||||
|
||||
boost::unordered_flat_map<FontRecordPair,
|
||||
boost::unordered_flat_map<FontRecord,
|
||||
std::shared_ptr<types::ImGuiFont>,
|
||||
FontRecordHash<FontRecordPair>>
|
||||
FontRecordHash<FontRecord>>
|
||||
imguiFonts_ {};
|
||||
std::shared_mutex imguiFontsMutex_ {};
|
||||
|
||||
boost::unordered_flat_map<std::string, std::vector<char>> rawFontData_ {};
|
||||
std::mutex rawFontDataMutex_ {};
|
||||
|
||||
std::shared_ptr<types::ImGuiFont> defaultFont_ {};
|
||||
std::pair<std::shared_ptr<types::ImGuiFont>, units::font_size::pixels<float>>
|
||||
defaultFont_ {};
|
||||
boost::unordered_flat_map<types::FontCategory,
|
||||
std::shared_ptr<types::ImGuiFont>>
|
||||
std::pair<std::shared_ptr<types::ImGuiFont>,
|
||||
units::font_size::pixels<float>>>
|
||||
fontCategoryImguiFontMap_ {};
|
||||
boost::unordered_flat_map<types::FontCategory, QFont>
|
||||
fontCategoryQFontMap_ {};
|
||||
|
|
@ -136,22 +133,22 @@ void FontManager::Impl::ConnectSignals()
|
|||
});
|
||||
}
|
||||
|
||||
QObject::connect(
|
||||
&SettingsManager::Instance(),
|
||||
&SettingsManager::SettingsSaved,
|
||||
self_,
|
||||
[this]()
|
||||
{
|
||||
std::scoped_lock lock {dirtyFontsMutex_, fontCategoryMutex_};
|
||||
QObject::connect(&SettingsManager::Instance(),
|
||||
&SettingsManager::SettingsSaved,
|
||||
self_,
|
||||
[this]()
|
||||
{
|
||||
const std::scoped_lock lock {dirtyFontsMutex_,
|
||||
fontCategoryMutex_};
|
||||
|
||||
for (auto fontCategory : dirtyFonts_)
|
||||
{
|
||||
UpdateImGuiFont(fontCategory);
|
||||
UpdateQFont(fontCategory);
|
||||
}
|
||||
for (auto fontCategory : dirtyFonts_)
|
||||
{
|
||||
UpdateImGuiFont(fontCategory);
|
||||
UpdateQFont(fontCategory);
|
||||
}
|
||||
|
||||
dirtyFonts_.clear();
|
||||
});
|
||||
dirtyFonts_.clear();
|
||||
});
|
||||
}
|
||||
|
||||
void FontManager::InitializeFonts()
|
||||
|
|
@ -163,6 +160,22 @@ void FontManager::InitializeFonts()
|
|||
}
|
||||
}
|
||||
|
||||
units::font_size::pixels<float>
|
||||
FontManager::ImFontSize(units::font_size::pixels<double> size)
|
||||
{
|
||||
static constexpr units::font_size::pixels<int> kMinFontSize_ {8};
|
||||
static constexpr units::font_size::pixels<int> kMaxFontSize_ {96};
|
||||
|
||||
// Only allow whole pixels, and clamp to 6-72 pt
|
||||
const units::font_size::pixels<double> pixels {size};
|
||||
const units::font_size::pixels<int> imFontSize {
|
||||
std::clamp(static_cast<int>(pixels.value()),
|
||||
kMinFontSize_.value(),
|
||||
kMaxFontSize_.value())};
|
||||
|
||||
return imFontSize;
|
||||
}
|
||||
|
||||
void FontManager::Impl::UpdateImGuiFont(types::FontCategory fontCategory)
|
||||
{
|
||||
auto& textSettings = settings::TextSettings::Instance();
|
||||
|
|
@ -173,7 +186,8 @@ void FontManager::Impl::UpdateImGuiFont(types::FontCategory fontCategory)
|
|||
textSettings.font_point_size(fontCategory).GetValue()};
|
||||
|
||||
fontCategoryImguiFontMap_.insert_or_assign(
|
||||
fontCategory, self_->LoadImGuiFont(family, {styles}, size));
|
||||
fontCategory,
|
||||
std::make_pair(self_->LoadImGuiFont(family, {styles}), ImFontSize(size)));
|
||||
}
|
||||
|
||||
void FontManager::Impl::UpdateQFont(types::FontCategory fontCategory)
|
||||
|
|
@ -188,7 +202,13 @@ void FontManager::Impl::UpdateQFont(types::FontCategory fontCategory)
|
|||
QFont font = QFontDatabase::font(QString::fromStdString(family),
|
||||
QString::fromStdString(styles),
|
||||
static_cast<int>(size.value()));
|
||||
|
||||
#if !defined(__APPLE__)
|
||||
font.setPointSizeF(size.value());
|
||||
#else
|
||||
const units::font_size::pixels<double> pixelSize {size};
|
||||
font.setPixelSize(static_cast<int>(pixelSize.value()));
|
||||
#endif
|
||||
|
||||
fontCategoryQFontMap_.insert_or_assign(fontCategory, font);
|
||||
}
|
||||
|
|
@ -198,11 +218,6 @@ std::shared_mutex& FontManager::imgui_font_atlas_mutex()
|
|||
return p->imguiFontAtlasMutex_;
|
||||
}
|
||||
|
||||
std::uint64_t FontManager::imgui_fonts_build_count() const
|
||||
{
|
||||
return p->imguiFontsBuildCount_;
|
||||
}
|
||||
|
||||
int FontManager::GetFontId(types::Font font) const
|
||||
{
|
||||
auto it = p->fontIds_.find(font);
|
||||
|
|
@ -213,7 +228,7 @@ int FontManager::GetFontId(types::Font font) const
|
|||
return -1;
|
||||
}
|
||||
|
||||
std::shared_ptr<types::ImGuiFont>
|
||||
std::pair<std::shared_ptr<types::ImGuiFont>, units::font_size::pixels<float>>
|
||||
FontManager::GetImGuiFont(types::FontCategory fontCategory)
|
||||
{
|
||||
std::unique_lock lock {p->fontCategoryMutex_};
|
||||
|
|
@ -241,31 +256,23 @@ QFont FontManager::GetQFont(types::FontCategory fontCategory)
|
|||
}
|
||||
|
||||
std::shared_ptr<types::ImGuiFont>
|
||||
FontManager::LoadImGuiFont(const std::string& family,
|
||||
const std::vector<std::string>& styles,
|
||||
units::font_size::points<double> size,
|
||||
bool loadIfNotFound)
|
||||
FontManager::LoadImGuiFont(const std::string& family,
|
||||
const std::vector<std::string>& styles,
|
||||
bool loadIfNotFound)
|
||||
{
|
||||
const std::string styleString = fmt::format("{}", fmt::join(styles, " "));
|
||||
const std::string fontString =
|
||||
fmt::format("{}-{}:{}", family, size.value(), styleString);
|
||||
const std::string fontString = fmt::format("{}:{}", family, styleString);
|
||||
|
||||
logger_->debug("LoadFontResource: {}", fontString);
|
||||
|
||||
FontRecord fontRecord = Impl::MatchFontFile(family, styles);
|
||||
|
||||
// Only allow whole pixels, and clamp to 6-72 pt
|
||||
units::font_size::pixels<double> pixels {size};
|
||||
units::font_size::pixels<int> imFontSize {
|
||||
std::clamp(static_cast<int>(pixels.value()), 8, 96)};
|
||||
auto imguiFontKey = std::make_pair(fontRecord, imFontSize);
|
||||
|
||||
// Search for a loaded ImGui font
|
||||
{
|
||||
std::shared_lock imguiFontLock {p->imguiFontsMutex_};
|
||||
|
||||
// Search for the associated ImGui font
|
||||
auto it = p->imguiFonts_.find(imguiFontKey);
|
||||
auto it = p->imguiFonts_.find(fontRecord);
|
||||
if (it != p->imguiFonts_.end())
|
||||
{
|
||||
return it->second;
|
||||
|
|
@ -290,7 +297,7 @@ FontManager::LoadImGuiFont(const std::string& family,
|
|||
|
||||
// Search for the associated ImGui font again, to prevent loading the same
|
||||
// font twice
|
||||
auto it = p->imguiFonts_.find(imguiFontKey);
|
||||
auto it = p->imguiFonts_.find(fontRecord);
|
||||
if (it != p->imguiFonts_.end())
|
||||
{
|
||||
return it->second;
|
||||
|
|
@ -301,25 +308,20 @@ FontManager::LoadImGuiFont(const std::string& family,
|
|||
try
|
||||
{
|
||||
fontName = fmt::format(
|
||||
"{}:{}",
|
||||
std::filesystem::path(fontRecord.filename_).filename().string(),
|
||||
imFontSize.value());
|
||||
"{}", std::filesystem::path(fontRecord.filename_).filename().string());
|
||||
}
|
||||
catch (const std::exception& ex)
|
||||
{
|
||||
logger_->warn(ex.what());
|
||||
fontName = fmt::format("{}:{}", fontRecord.filename_, imFontSize.value());
|
||||
fontName = fmt::format("{}", fontRecord.filename_);
|
||||
}
|
||||
|
||||
// Create an ImGui font
|
||||
std::shared_ptr<types::ImGuiFont> imguiFont =
|
||||
std::make_shared<types::ImGuiFont>(fontName, rawFontData, imFontSize);
|
||||
std::make_shared<types::ImGuiFont>(fontName, rawFontData);
|
||||
|
||||
// Store the ImGui font
|
||||
p->imguiFonts_.insert_or_assign(imguiFontKey, imguiFont);
|
||||
|
||||
// Increment ImGui font build count
|
||||
++p->imguiFontsBuildCount_;
|
||||
p->imguiFonts_.insert_or_assign(fontRecord, imguiFont);
|
||||
|
||||
// Return the ImGui font
|
||||
return imguiFont;
|
||||
|
|
@ -456,6 +458,13 @@ void FontManager::Impl::FinalizeFontconfig()
|
|||
FcFini();
|
||||
}
|
||||
|
||||
bool FontManager::Impl::CheckFontFormat(const FcChar8* format)
|
||||
{
|
||||
const std::string stdFormat = reinterpret_cast<const char*>(format);
|
||||
|
||||
return stdFormat == kFcTrueType_ || stdFormat == kFcOpenType_;
|
||||
}
|
||||
|
||||
FontRecord
|
||||
FontManager::Impl::MatchFontFile(const std::string& family,
|
||||
const std::vector<std::string>& styles)
|
||||
|
|
@ -468,9 +477,7 @@ FontManager::Impl::MatchFontFile(const std::string& family,
|
|||
|
||||
FcPatternAddString(
|
||||
pattern, FC_FAMILY, reinterpret_cast<const FcChar8*>(family.c_str()));
|
||||
FcPatternAddString(pattern,
|
||||
FC_FONTFORMAT,
|
||||
reinterpret_cast<const FcChar8*>(kFcTrueType_.c_str()));
|
||||
FcPatternAddBool(pattern, FC_SYMBOL, FcFalse);
|
||||
|
||||
if (!styles.empty())
|
||||
{
|
||||
|
|
@ -484,29 +491,55 @@ FontManager::Impl::MatchFontFile(const std::string& family,
|
|||
FcDefaultSubstitute(pattern);
|
||||
|
||||
// Find matching font
|
||||
FcResult result;
|
||||
FcPattern* match = FcFontMatch(nullptr, pattern, &result);
|
||||
FcResult result {};
|
||||
FcFontSet* matches = FcFontSort(nullptr, pattern, FcFalse, nullptr, &result);
|
||||
FontRecord record {};
|
||||
|
||||
if (match != nullptr)
|
||||
if (matches != nullptr)
|
||||
{
|
||||
FcChar8* fcFamily;
|
||||
FcChar8* fcStyle;
|
||||
FcChar8* fcFile;
|
||||
|
||||
// Match was found, get properties
|
||||
if (FcPatternGetString(match, FC_FAMILY, 0, &fcFamily) == FcResultMatch &&
|
||||
FcPatternGetString(match, FC_STYLE, 0, &fcStyle) == FcResultMatch &&
|
||||
FcPatternGetString(match, FC_FILE, 0, &fcFile) == FcResultMatch)
|
||||
for (int i = 0; i < matches->nfont; i++)
|
||||
{
|
||||
record.family_ = reinterpret_cast<char*>(fcFamily);
|
||||
record.style_ = reinterpret_cast<char*>(fcStyle);
|
||||
record.filename_ = reinterpret_cast<char*>(fcFile);
|
||||
FcPattern* match =
|
||||
// Using C code requires pointer arithmetic
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
FcFontRenderPrepare(nullptr, pattern, matches->fonts[i]);
|
||||
if (match == nullptr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
FcChar8* fcFamily = nullptr;
|
||||
FcChar8* fcStyle = nullptr;
|
||||
FcChar8* fcFile = nullptr;
|
||||
FcChar8* fcFormat = nullptr;
|
||||
FcBool fcSymbol = FcFalse;
|
||||
|
||||
logger_->debug("Found matching font: {}:{} ({})",
|
||||
record.family_,
|
||||
record.style_,
|
||||
record.filename_);
|
||||
// Match was found, get properties
|
||||
if (FcPatternGetString(match, FC_FAMILY, 0, &fcFamily) ==
|
||||
FcResultMatch &&
|
||||
FcPatternGetString(match, FC_STYLE, 0, &fcStyle) ==
|
||||
FcResultMatch &&
|
||||
FcPatternGetString(match, FC_FILE, 0, &fcFile) == FcResultMatch &&
|
||||
FcPatternGetBool(match, FC_SYMBOL, 0, &fcSymbol) ==
|
||||
FcResultMatch &&
|
||||
FcPatternGetString(match, FC_FONTFORMAT, 0, &fcFormat) ==
|
||||
FcResultMatch &&
|
||||
fcSymbol == FcFalse /*Must check fcSymbol manually*/ &&
|
||||
CheckFontFormat(fcFormat))
|
||||
{
|
||||
record.family_ = reinterpret_cast<char*>(fcFamily);
|
||||
record.style_ = reinterpret_cast<char*>(fcStyle);
|
||||
record.filename_ = reinterpret_cast<char*>(fcFile);
|
||||
|
||||
logger_->debug("Found matching font: {}:{} ({}) {}",
|
||||
record.family_,
|
||||
record.style_,
|
||||
record.filename_,
|
||||
fcSymbol);
|
||||
FcPatternDestroy(match);
|
||||
break;
|
||||
}
|
||||
|
||||
FcPatternDestroy(match);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -516,7 +549,7 @@ FontManager::Impl::MatchFontFile(const std::string& family,
|
|||
}
|
||||
|
||||
// Cleanup
|
||||
FcPatternDestroy(match);
|
||||
FcFontSetDestroy(matches);
|
||||
FcPatternDestroy(pattern);
|
||||
|
||||
return record;
|
||||
|
|
@ -528,13 +561,12 @@ FontManager& FontManager::Instance()
|
|||
return instance_;
|
||||
}
|
||||
|
||||
size_t FontRecordHash<FontRecordPair>::operator()(const FontRecordPair& x) const
|
||||
size_t FontRecordHash<FontRecord>::operator()(const FontRecord& x) const
|
||||
{
|
||||
size_t seed = 0;
|
||||
boost::hash_combine(seed, x.first.family_);
|
||||
boost::hash_combine(seed, x.first.style_);
|
||||
boost::hash_combine(seed, x.first.filename_);
|
||||
boost::hash_combine(seed, x.second.value());
|
||||
boost::hash_combine(seed, x.family_);
|
||||
boost::hash_combine(seed, x.style_);
|
||||
boost::hash_combine(seed, x.filename_);
|
||||
return seed;
|
||||
}
|
||||
|
||||
|
|
@ -545,6 +577,4 @@ bool operator==(const FontRecord& lhs, const FontRecord& rhs)
|
|||
lhs.filename_ == rhs.filename_;
|
||||
}
|
||||
|
||||
} // namespace manager
|
||||
} // namespace qt
|
||||
} // namespace scwx
|
||||
} // namespace scwx::qt::manager
|
||||
|
|
|
|||
|
|
@ -26,21 +26,22 @@ public:
|
|||
~FontManager();
|
||||
|
||||
std::shared_mutex& imgui_font_atlas_mutex();
|
||||
std::uint64_t imgui_fonts_build_count() const;
|
||||
|
||||
int GetFontId(types::Font font) const;
|
||||
std::shared_ptr<types::ImGuiFont>
|
||||
std::pair<std::shared_ptr<types::ImGuiFont>, units::font_size::pixels<float>>
|
||||
GetImGuiFont(types::FontCategory fontCategory);
|
||||
QFont GetQFont(types::FontCategory fontCategory);
|
||||
std::shared_ptr<types::ImGuiFont>
|
||||
LoadImGuiFont(const std::string& family,
|
||||
const std::vector<std::string>& styles,
|
||||
units::font_size::points<double> size,
|
||||
bool loadIfNotFound = true);
|
||||
LoadImGuiFont(const std::string& family,
|
||||
const std::vector<std::string>& styles,
|
||||
bool loadIfNotFound = true);
|
||||
|
||||
void LoadApplicationFont(types::Font font, const std::string& filename);
|
||||
void InitializeFonts();
|
||||
|
||||
static units::font_size::pixels<float>
|
||||
ImFontSize(units::font_size::pixels<double> size);
|
||||
|
||||
static FontManager& Instance();
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
#include <scwx/qt/manager/log_manager.hpp>
|
||||
#include <scwx/util/logger.hpp>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
#include <filesystem>
|
||||
#include <map>
|
||||
#include <ranges>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <boost/process/environment.hpp>
|
||||
#include <boost/process/v1/environment.hpp>
|
||||
#include <fmt/format.h>
|
||||
#include <spdlog/spdlog.h>
|
||||
#include <QStandardPaths>
|
||||
|
|
@ -57,6 +59,14 @@ void LogManager::InitializeLogFile()
|
|||
QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation)
|
||||
.toStdString();
|
||||
p->pid_ = boost::this_process::get_id();
|
||||
if (p->pid_ == 2)
|
||||
{
|
||||
// The pid == 2 means that this is likely a flatpak. We assign a random
|
||||
// number in this case to avoid overlap, scince it is always 2 in a
|
||||
// flatpak
|
||||
std::srand(std::time({}));
|
||||
p->pid_ = std::rand();
|
||||
}
|
||||
p->logFile_ = fmt::format("{}/supercell-wx.{}.log", p->logPath_, p->pid_);
|
||||
|
||||
// Create log directory if it doesn't exist
|
||||
|
|
|
|||