Compare commits
691 Commits
wip/jimmac
...
wip/radial
Author | SHA1 | Date | |
---|---|---|---|
|
210e031316 | ||
|
752fa801a6 | ||
|
d763b1f847 | ||
|
7842f77ac5 | ||
|
3e5c4b9e17 | ||
|
c780fc73be | ||
|
28e168e559 | ||
|
7ee3439522 | ||
|
71ea619274 | ||
|
f679ba566e | ||
|
2679e29375 | ||
|
e55bdf87b5 | ||
|
c09575d9cb | ||
|
c3b925d696 | ||
|
640856edec | ||
|
1e7fccf46f | ||
|
ff392fbfb6 | ||
|
498cbae95c | ||
|
fa9608fd02 | ||
|
8700e136da | ||
|
2e54810937 | ||
|
93a09a4a6a | ||
|
299b1bd848 | ||
|
1e9a9876d5 | ||
|
1de7440c8c | ||
|
5c87432a0c | ||
|
80e53e704c | ||
|
24bf01dd42 | ||
|
2113f98c5c | ||
|
b9d4654fca | ||
|
7151b1fc31 | ||
|
790733673f | ||
|
aff788e583 | ||
|
d5d4af585d | ||
|
93078e52c0 | ||
|
cee275980a | ||
|
b3aa5ad4f9 | ||
|
9b0b19d335 | ||
|
d47d036663 | ||
|
5c67fe0bc2 | ||
|
1057588a8f | ||
|
75f0b7acaa | ||
|
9a927176df | ||
|
cb5b375f43 | ||
|
dfccaa8831 | ||
|
cc58956dbb | ||
|
0ad10ccf39 | ||
|
8cb03a8cc0 | ||
|
df7cbdfff4 | ||
|
f4b410daa7 | ||
|
b3d3d81c82 | ||
|
3095bccd2e | ||
|
c72b2f6167 | ||
|
3d10b28df4 | ||
|
d6807b966c | ||
|
887d0b7411 | ||
|
3921476504 | ||
|
ae97284409 | ||
|
7cda32d49e | ||
|
fb99bde840 | ||
|
9dc5c6a0f3 | ||
|
107e49002d | ||
|
31a7574544 | ||
|
859df747ac | ||
|
81c835c418 | ||
|
33e633cc5c | ||
|
73b46eafe1 | ||
|
710ef690ec | ||
|
cb2b0688ca | ||
|
45c61fdbe3 | ||
|
ec49b68257 | ||
|
0092a08dfc | ||
|
bab7092a69 | ||
|
3b6941b04b | ||
|
fe429ffc45 | ||
|
d595c6ab12 | ||
|
2738d5bc93 | ||
|
5a8267dfae | ||
|
d03ce22446 | ||
|
350051c56e | ||
|
979ec828d2 | ||
|
99ddb3c927 | ||
|
770910e608 | ||
|
7180bfc288 | ||
|
bc80ed4240 | ||
|
4d45c2669c | ||
|
dd8ca7259f | ||
|
06c866f45e | ||
|
2bd7ed5ebd | ||
|
adc9d91e0e | ||
|
1150c23b0f | ||
|
9b8c175f23 | ||
|
e0134aaf15 | ||
|
bd7aa1782c | ||
|
007c9c6218 | ||
|
8c8baa9aa6 | ||
|
7ae0f56378 | ||
|
3fcf7adb25 | ||
|
8b38d1895c | ||
|
a4ba25f0f8 | ||
|
24389a0ef5 | ||
|
dfabe74c59 | ||
|
716c7b2f21 | ||
|
c74c38ad06 | ||
|
727f25f6da | ||
|
01959e1662 | ||
|
12afc10ec3 | ||
|
2f70279f85 | ||
|
ffc77ca926 | ||
|
021eeedef0 | ||
|
635492b016 | ||
|
bd226cc31e | ||
|
cbd3158d91 | ||
|
982cf0c4d3 | ||
|
d37cb36eb1 | ||
|
e374917c56 | ||
|
1dd4e91fee | ||
|
c1bf9f3b41 | ||
|
8a3621a125 | ||
|
81f84fbe8f | ||
|
60e37d3368 | ||
|
e0cc7b5d86 | ||
|
9843515736 | ||
|
41497aeb8b | ||
|
bb2a0e69f4 | ||
|
f70e37a341 | ||
|
1a445d79c4 | ||
|
925a01162f | ||
|
3bcbb4a7cc | ||
|
a8eae7afaa | ||
|
99a09e0d08 | ||
|
275302a9d5 | ||
|
749d0744da | ||
|
62f7395c77 | ||
|
f7f0bc0369 | ||
|
1896d7f463 | ||
|
927c4abf23 | ||
|
b322ddba5c | ||
|
b25871438d | ||
|
aff3cc6194 | ||
|
f2c4ad0087 | ||
|
1a131a04d3 | ||
|
887539e4ff | ||
|
98440142da | ||
|
acc2516b3c | ||
|
fd7a9069ce | ||
|
1a8f109af8 | ||
|
eee6d28c67 | ||
|
30ab8b3eca | ||
|
d5121af876 | ||
|
9512e461d5 | ||
|
70c5dee968 | ||
|
6c9fe63a23 | ||
|
a909f9d0f5 | ||
|
21b9dad9e6 | ||
|
ae5d1cd161 | ||
|
f53b59533d | ||
|
062822ab06 | ||
|
fc333ead79 | ||
|
746bdd3d47 | ||
|
c5c67cbb8c | ||
|
639c839ba4 | ||
|
5f8769e1a8 | ||
|
3569360949 | ||
|
7070459c40 | ||
|
1c0bf2604c | ||
|
c2786fefa8 | ||
|
1bbab5664d | ||
|
a3030d3a62 | ||
|
ec6d3ead03 | ||
|
87855dd375 | ||
|
0e6eba3968 | ||
|
aaef9bec7f | ||
|
391c05ef70 | ||
|
133a9a6784 | ||
|
b628338db3 | ||
|
7051fdee5d | ||
|
e36b594867 | ||
|
99a7a2188a | ||
|
3ac9f78141 | ||
|
a8d6ba9517 | ||
|
482794515b | ||
|
9377ce984d | ||
|
8d79a32c50 | ||
|
b661bd9775 | ||
|
87dd79bc17 | ||
|
d2d8b748e9 | ||
|
ccb447da02 | ||
|
4580e71250 | ||
|
76b5ff6a00 | ||
|
665955b81e | ||
|
501cf493bf | ||
|
684c36c13f | ||
|
d93eb0d88f | ||
|
64b049f798 | ||
|
03dd629257 | ||
|
6ccc6a5650 | ||
|
5adc1dc40f | ||
|
768e24afc1 | ||
|
4cf9228659 | ||
|
2f0a4c7128 | ||
|
e64b08ab90 | ||
|
9bc97fb52c | ||
|
077f21c9ff | ||
|
cff211ea1f | ||
|
17c4838569 | ||
|
bb6045f02d | ||
|
b98352de3e | ||
|
1125a4379c | ||
|
f085ac837c | ||
|
28d7f497ef | ||
|
b69e8d8e7b | ||
|
c7b6c2f441 | ||
|
2c5c938f0d | ||
|
cfade230ce | ||
|
238d52497d | ||
|
ba6070b7be | ||
|
8f1bf594b9 | ||
|
1b6f734019 | ||
|
cd284da794 | ||
|
591b52584e | ||
|
f30d32f609 | ||
|
33b65d5e61 | ||
|
00124b593e | ||
|
2d6c43b598 | ||
|
d6e1276fe1 | ||
|
151b9c71db | ||
|
c9eb497989 | ||
|
dc8b88393d | ||
|
7a05381825 | ||
|
e21b6a5721 | ||
|
d3042dabf4 | ||
|
830b2b7f30 | ||
|
af155838bd | ||
|
2212daf979 | ||
|
5ef0ed1189 | ||
|
071763c844 | ||
|
c69ac09afb | ||
|
4ba84d6426 | ||
|
fac0e7abd8 | ||
|
14daddfa9d | ||
|
0c150e48f1 | ||
|
c51f69c446 | ||
|
8e74687ab3 | ||
|
15c6760a96 | ||
|
6ffb3d3fe5 | ||
|
0f42d37f8b | ||
|
02d57f1fd7 | ||
|
1375fb4464 | ||
|
51b398b960 | ||
|
b0d89b1882 | ||
|
c1c2205018 | ||
|
7a8d71138f | ||
|
2bff84ca6c | ||
|
e8805eb9bf | ||
|
21e2c7fa33 | ||
|
53eed09e08 | ||
|
0fd8a287fc | ||
|
1d6ac9b47b | ||
|
acbb59bfae | ||
|
ea21e50cc1 | ||
|
e970c69843 | ||
|
ce737f69d7 | ||
|
e4ad403a9a | ||
|
722cab1b6b | ||
|
38c2555d46 | ||
|
ebef48f7df | ||
|
a67899870a | ||
|
a0565ea8d9 | ||
|
1d2634e73b | ||
|
18a85998dc | ||
|
c6fee8cee5 | ||
|
dc17cf19b4 | ||
|
df88abb9c4 | ||
|
bba7f444dc | ||
|
6b9db59e62 | ||
|
0077f95ace | ||
|
c770adb918 | ||
|
529b44625d | ||
|
c10636789d | ||
|
8124f5896d | ||
|
28f831ebb0 | ||
|
3ec7a6c861 | ||
|
8da4a02da0 | ||
|
e6d4555b34 | ||
|
f854c2850f | ||
|
d6392c9035 | ||
|
02631d2b6e | ||
|
9cddc36fe2 | ||
|
690d72e696 | ||
|
9dbf81e7d9 | ||
|
0546f09b1d | ||
|
22099ebb05 | ||
|
07ef594be1 | ||
|
d785212706 | ||
|
9b0c2e62ba | ||
|
983f072514 | ||
|
275b95841b | ||
|
7d9bc01797 | ||
|
028644d0ad | ||
|
76e83d3216 | ||
|
002376f837 | ||
|
39d71dbb0a | ||
|
b5e7499bbd | ||
|
fed6ba9bd0 | ||
|
5581f78f41 | ||
|
a97ea17c92 | ||
|
67f259cd1a | ||
|
e5f4459e4b | ||
|
890c7816f0 | ||
|
e25e73c56c | ||
|
8a2b3f0692 | ||
|
1ec4995d14 | ||
|
dd624de8e8 | ||
|
92737b27bf | ||
|
fe50286e14 | ||
|
9d65ee58c9 | ||
|
ad5a78b1e7 | ||
|
cd3a7b416e | ||
|
fc63c6371f | ||
|
d13fa73d04 | ||
|
c6976d6897 | ||
|
6371fca799 | ||
|
f3ebb76746 | ||
|
620388a071 | ||
|
f6adba57bb | ||
|
5533494839 | ||
|
5b5d2665d3 | ||
|
1a39ac64ab | ||
|
78134fc6d3 | ||
|
564ae4bdb1 | ||
|
e4215ec4c7 | ||
|
74f8c59236 | ||
|
dd0c43b7ba | ||
|
9de7390ea0 | ||
|
81e113d8aa | ||
|
b26f4d5429 | ||
|
0a59429dc8 | ||
|
70ae073394 | ||
|
6421355065 | ||
|
536966e848 | ||
|
1c44910dfe | ||
|
bf9bb71813 | ||
|
75915bc782 | ||
|
618891a41a | ||
|
0d82fcf76f | ||
|
0091de63b4 | ||
|
338d6adb10 | ||
|
c4c155d698 | ||
|
b9016229c1 | ||
|
cf257e6676 | ||
|
62ed769e74 | ||
|
f3a0357ab0 | ||
|
1d8ac79296 | ||
|
374c776749 | ||
|
8c9e1e7444 | ||
|
73d81d7178 | ||
|
84355ccbff | ||
|
b2c92392fc | ||
|
9e06e830b7 | ||
|
62a4a356c9 | ||
|
1e4c6cde10 | ||
|
372db8d239 | ||
|
d57e6b754f | ||
|
59e0959186 | ||
|
3b1300632d | ||
|
738f5f4523 | ||
|
4b1ea7c4a1 | ||
|
74a452df6c | ||
|
45046a53eb | ||
|
918996b047 | ||
|
b6eb85ee72 | ||
|
44741e1b77 | ||
|
eef1818cee | ||
|
fcaa6e98d0 | ||
|
f48a1e4069 | ||
|
c21b9bec95 | ||
|
659ec97456 | ||
|
42cc15bb74 | ||
|
8e452b2b54 | ||
|
740559a54f | ||
|
75cf990f74 | ||
|
612d2ea1f0 | ||
|
d58136e23d | ||
|
256c9c9873 | ||
|
fd568e63c2 | ||
|
797b3bd1b1 | ||
|
32a1cd13c8 | ||
|
1338dcddcb | ||
|
911a71c705 | ||
|
701a0dabd0 | ||
|
4dc1aea2ad | ||
|
09fa3886ba | ||
|
bb7d5b2de6 | ||
|
d906242c78 | ||
|
d9e8223b03 | ||
|
b79797ea97 | ||
|
5bfc95321e | ||
|
c0efadc0f3 | ||
|
ef837f0415 | ||
|
944607f240 | ||
|
43781652b3 | ||
|
9729a060f5 | ||
|
43ec96684a | ||
|
66e0f8505e | ||
|
22c914b7f5 | ||
|
fd7d61887c | ||
|
bdaf346128 | ||
|
6af7704858 | ||
|
7ff326e700 | ||
|
c890d5991c | ||
|
d27f9abbca | ||
|
08f58122d1 | ||
|
17dcb10707 | ||
|
2ac51ad827 | ||
|
2e72b663b0 | ||
|
e61f516a7c | ||
|
f71c9a2146 | ||
|
7428731e5b | ||
|
6043ed8c89 | ||
|
f394375719 | ||
|
ae2a914f07 | ||
|
cd9bee83ef | ||
|
ca0f136deb | ||
|
c0191c7225 | ||
|
d5114cc18d | ||
|
40d7092f4a | ||
|
dc963dcbcb | ||
|
c4d350c260 | ||
|
54e4bf8b75 | ||
|
0540337531 | ||
|
86acb13057 | ||
|
11314cf0b4 | ||
|
37ce545d72 | ||
|
85764ce505 | ||
|
ff5cdbaf03 | ||
|
420c4e1f16 | ||
|
a498aca3ab | ||
|
4eacfdba60 | ||
|
4fefea7471 | ||
|
bc132dae54 | ||
|
5822cdbc95 | ||
|
6a7a0f0b8a | ||
|
1948f8a07f | ||
|
8eb807d7f4 | ||
|
125ed52ccb | ||
|
e915a1aa7f | ||
|
7a9501b1fb | ||
|
81e88c1d9e | ||
|
f4511ff91c | ||
|
f00e2e2146 | ||
|
5a5b30681e | ||
|
ab5e62ddab | ||
|
936f3f1ad9 | ||
|
865b29500c | ||
|
7039f31391 | ||
|
ed67d9c103 | ||
|
5377026e61 | ||
|
40f3da19ae | ||
|
d4e069a629 | ||
|
a416650f6b | ||
|
e5d088208a | ||
|
3ef7772552 | ||
|
24ce38bb36 | ||
|
6315cd977c | ||
|
9770e064e8 | ||
|
2437622b5f | ||
|
bb8c818ba1 | ||
|
dd2e1e4867 | ||
|
5f630481db | ||
|
da6253eadc | ||
|
c6b261afa0 | ||
|
e07827e976 | ||
|
5a8f90357d | ||
|
a674832658 | ||
|
2031bcd388 | ||
|
4e157b33dc | ||
|
174c9a938e | ||
|
ec81ccd5f9 | ||
|
8acd60fda9 | ||
|
bcd0a9e5d8 | ||
|
5b35c5fb19 | ||
|
1dcb68c8e3 | ||
|
bca6113539 | ||
|
e35c000b4a | ||
|
29d7d652c4 | ||
|
581f224b61 | ||
|
aabb713594 | ||
|
a0af12e492 | ||
|
19c2cc1296 | ||
|
9b42edbef4 | ||
|
303e023c36 | ||
|
5e35ca5692 | ||
|
667b3b117d | ||
|
cb7c903594 | ||
|
e6e2d6b45a | ||
|
fa0a88ae22 | ||
|
17cdc13847 | ||
|
d40d4d5fae | ||
|
131e2f6e43 | ||
|
b3786b7b07 | ||
|
6cf8f1cdf2 | ||
|
79c2c3e353 | ||
|
ae7cefd97d | ||
|
35708162cc | ||
|
e29e569d6f | ||
|
3d7343144f | ||
|
3c44e9c563 | ||
|
8a13d18655 | ||
|
9786185cc0 | ||
|
22ac6d3148 | ||
|
97e0f1108d | ||
|
0ae7f794a3 | ||
|
15bd2a2a5c | ||
|
28c1e74220 | ||
|
e694a4137c | ||
|
005f9a995e | ||
|
e48a1d2df0 | ||
|
6191404656 | ||
|
6037d08bd8 | ||
|
bcc5e475fc | ||
|
a0cdb544ed | ||
|
80cddd4cc1 | ||
|
f4561d3fd5 | ||
|
c5963b960a | ||
|
df4c57c001 | ||
|
2b0e9542cb | ||
|
b49fd47276 | ||
|
bdb1d87859 | ||
|
d1b1b5bd9b | ||
|
283fc9d7e4 | ||
|
d8753a9fa3 | ||
|
a9858c6662 | ||
|
0279e1c76b | ||
|
cce3ff6f04 | ||
|
221786dda3 | ||
|
aacb06dbee | ||
|
ea887959bd | ||
|
4c78f628db | ||
|
0228c89011 | ||
|
b4508be3c9 | ||
|
dded2ddb21 | ||
|
e9afb63a01 | ||
|
3a0fdffe5e | ||
|
ff51d7b838 | ||
|
ef22c4a4fa | ||
|
ebaf533a31 | ||
|
88dcd2597a | ||
|
0d0807fc44 | ||
|
7226878916 | ||
|
afa9d9aa8c | ||
|
28a3911b15 | ||
|
94696490dc | ||
|
dbc6a94daf | ||
|
0a9acd10d2 | ||
|
3340a5ee04 | ||
|
5e2aeee9b0 | ||
|
9b0a5b1fde | ||
|
540cffee89 | ||
|
e0b95c6234 | ||
|
40c32bbef6 | ||
|
d0b192325a | ||
|
e16d108b68 | ||
|
f8b8c90c3d | ||
|
823219d429 | ||
|
102acd2581 | ||
|
82253d1a0a | ||
|
19b93fc9f7 | ||
|
e9d03d06fe | ||
|
63fb2126db | ||
|
90080d5bec | ||
|
be5b03224c | ||
|
091289a85d | ||
|
17710709f9 | ||
|
6fafc8b811 | ||
|
bc20fe3cca | ||
|
8cbca4f693 | ||
|
6e9de7f271 | ||
|
aa1b9531c1 | ||
|
66fa530574 | ||
|
e5247b7cbb | ||
|
da0955feeb | ||
|
2335953c5d | ||
|
42902085e5 | ||
|
230107cd84 | ||
|
b69dc3d054 | ||
|
a85fc0008c | ||
|
2bf9ae005f | ||
|
4650f7ec14 | ||
|
5dd0262a56 | ||
|
b13e1a5a7b | ||
|
ce1cd67fa4 | ||
|
eb5329d389 | ||
|
5b41612f28 | ||
|
473ed75ed5 | ||
|
3760d44f18 | ||
|
79f0687929 | ||
|
c80a612af7 | ||
|
358b698efa | ||
|
0f7b2159b6 | ||
|
7f565806a8 | ||
|
1d49f933e9 | ||
|
1d1d9de09e | ||
|
d1aacc01d4 | ||
|
2a3d3ec079 | ||
|
c60fba0267 | ||
|
75ad180c78 | ||
|
765fe201ce | ||
|
3469c639f6 | ||
|
d642bfc8ce | ||
|
c6a7b39ee1 | ||
|
112883186c | ||
|
57a213a4ea | ||
|
dbbc9b5c58 | ||
|
e18de295c6 | ||
|
4eaf08e964 | ||
|
2d5b44703c | ||
|
19c6ef38fe | ||
|
4f5e3b7b0d | ||
|
95cd8c1eb9 | ||
|
dfb16019f8 | ||
|
bef86d48af | ||
|
d1d269ea6b | ||
|
3d807f4b00 | ||
|
9654fff6e0 | ||
|
8a67899e0f | ||
|
bb30a23004 | ||
|
3faa7feb7c | ||
|
d099276b89 | ||
|
56afa05b97 | ||
|
c6fdfeae7e | ||
|
8725fd308b | ||
|
c40e23bde6 | ||
|
afcb9c0e63 | ||
|
fd1033f974 | ||
|
16505a4d1e | ||
|
a1ec68422f | ||
|
f8060b859d | ||
|
0c0ced1374 | ||
|
bfd8c5383f | ||
|
4d88e3af17 | ||
|
b694771728 | ||
|
51d6ec5131 | ||
|
7625ccd6fa | ||
|
95e2a2b4b3 | ||
|
4e774eddb9 | ||
|
35325ea11a | ||
|
5673310364 | ||
|
2d72ba21ce | ||
|
e0786a4a00 | ||
|
0b21883518 | ||
|
1ccab92813 | ||
|
f6d9e15c16 | ||
|
cd0b9a2359 | ||
|
96500816bc | ||
|
9d60047616 | ||
|
a95012caa3 | ||
|
51d55e4fbc | ||
|
05255bfc90 | ||
|
41ef2c5f34 | ||
|
4dfd413e0b | ||
|
6724d4250f | ||
|
8cd2f615ad | ||
|
517a34bdc8 | ||
|
658719a205 | ||
|
c27f811462 | ||
|
3590923c8b | ||
|
1b7004ffc7 | ||
|
85c713127e | ||
|
87a8fda163 | ||
|
79e6269058 | ||
|
6cf04c505f | ||
|
14900efe38 | ||
|
04c3c659f5 | ||
|
8557aaf327 | ||
|
052962a760 | ||
|
278fbcbbb4 | ||
|
26542778f7 | ||
|
a712ffa2ab | ||
|
12450cfcef | ||
|
71373ff6fb | ||
|
1fa9261fe3 | ||
|
c212dd4ec0 | ||
|
2ae1f40da2 | ||
|
0c82aa314c | ||
|
9e5ddeaa8a | ||
|
4e3251872c | ||
|
c13d70479b | ||
|
ecd50891ff | ||
|
71cec2ef5d | ||
|
a27c3039d0 |
@@ -17,8 +17,8 @@ stages:
|
||||
# Common variables
|
||||
variables:
|
||||
COMMON_MESON_FLAGS: "--fatal-meson-warnings -Dgtk:werror=true"
|
||||
BACKEND_FLAGS: "-Dx11-backend=true -Dwayland-backend=true -Dbroadway-backend=true -Dvulkan=yes"
|
||||
FEATURE_FLAGS: "-Dcloudproviders=true"
|
||||
BACKEND_FLAGS: "-Dx11-backend=true -Dwayland-backend=true -Dbroadway-backend=true"
|
||||
FEATURE_FLAGS: "-Dvulkan=enabled -Dcloudproviders=enabled"
|
||||
MESON_TEST_TIMEOUT_MULTIPLIER: 3
|
||||
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v22"
|
||||
FLATPAK_IMAGE: "registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:master"
|
||||
@@ -74,7 +74,7 @@ fedora-x86_64:
|
||||
script:
|
||||
- meson subprojects update
|
||||
- meson ${COMMON_MESON_FLAGS} ${EXTRA_MESON_FLAGS} ${BACKEND_FLAGS} ${FEATURE_FLAGS}
|
||||
-Dprofiler=true
|
||||
-Dsysprof=enabled
|
||||
_build
|
||||
- ninja -C _build
|
||||
- .gitlab-ci/run-tests.sh _build x11
|
||||
|
@@ -66,7 +66,7 @@ meson \
|
||||
-Dx11-backend=false \
|
||||
-Dwayland-backend=false \
|
||||
-Dwin32-backend=true \
|
||||
-Dvulkan=no \
|
||||
-Dvulkan=disabled \
|
||||
-Dintrospection=false \
|
||||
-Dgtk:werror=true \
|
||||
_build
|
||||
|
141
NEWS
141
NEWS
@@ -1,3 +1,67 @@
|
||||
Overview of Changes in GTK 3.99.2
|
||||
=================================
|
||||
|
||||
* GtkEntry:
|
||||
- Fix issues with Emoji insertion
|
||||
- Fix issues with dnd
|
||||
- Set correct hotspot for dnd icon
|
||||
|
||||
* GtkPasswordEntry:
|
||||
- Use non-pageable memory
|
||||
|
||||
* GtkSearchEntry:
|
||||
- Don't handle forwarded events twice
|
||||
|
||||
* GtkTextView:
|
||||
- Fix dnd
|
||||
- Improve undo state tracking
|
||||
|
||||
* GtkRevealer:
|
||||
- Fix clipping issues in the swing transitions
|
||||
|
||||
* GL renderer:
|
||||
- Fix clipping with projective transforms
|
||||
- Use linear interpolation for offscreen rendering
|
||||
with non-axis-aligned transforms
|
||||
- Fix texture caching to avoid size mismatches
|
||||
|
||||
* CSS:
|
||||
- Allow more than 64 selectors per rule
|
||||
|
||||
* API cleanup:
|
||||
- Make filter and sorter constructors return exact
|
||||
types
|
||||
|
||||
* Demos:
|
||||
- Bug fixes and cosmetic improvements
|
||||
- Add a Shadertoy demo
|
||||
|
||||
* Build:
|
||||
- Fix Vulkan dependency checking
|
||||
- Make sysprof truly optional
|
||||
|
||||
* Translation updates:
|
||||
Basque
|
||||
Catalan
|
||||
Croatian
|
||||
Czech
|
||||
Danish
|
||||
French
|
||||
Galician
|
||||
German
|
||||
Hungarian
|
||||
Indonesian
|
||||
Kazakh
|
||||
Lithuanian
|
||||
Persian
|
||||
Polish
|
||||
Slovak
|
||||
Slovenian
|
||||
Spanish
|
||||
Turkish
|
||||
Ukrainian
|
||||
|
||||
|
||||
Overview of Changes in GTK 3.99.1
|
||||
=================================
|
||||
|
||||
@@ -12,27 +76,102 @@ Overview of Changes in GTK 3.99.1
|
||||
* GtkTreeView:
|
||||
- Fix selection handling in cell editables
|
||||
|
||||
* GtkPopover:
|
||||
- Allow setting popup offset
|
||||
|
||||
* GtkPlacesSidebar:
|
||||
- Fix DND
|
||||
|
||||
* GtkTextview:
|
||||
- Speed up gtk_text_buffer_insert_markup
|
||||
|
||||
* GtkFrame:
|
||||
- Set GTK_OVERFLOW_HIDDEN
|
||||
|
||||
* GtkSpinButton:
|
||||
- Fix spinning
|
||||
|
||||
* GtkFontChooser:
|
||||
- Populate the list incrementally
|
||||
|
||||
* GtkButton: Simplify the button hierarchy; GtkRadioButton
|
||||
is gone, GtkCheckButton and GtkToggleButton can be grouped
|
||||
|
||||
* list widgets:
|
||||
- Change apis to make models explicitly GtkSelectionModel
|
||||
- Simplify constructors
|
||||
|
||||
* CSS:
|
||||
- Hexadecimal colors can now specify alpha
|
||||
- Fix parsing of numbers in scientific notation
|
||||
|
||||
* Themes:
|
||||
- Add and document highlevel list styles
|
||||
- Drop the style class defines. Just use string literals
|
||||
- Round the corners of frames
|
||||
- Make circular buttons square
|
||||
|
||||
* GL renderer:
|
||||
- Fix clipping with projective transforms
|
||||
|
||||
* Documentation:
|
||||
- Refresh the widget gallery
|
||||
- Add images for new widgets to the gallery
|
||||
- Fix many cross-references
|
||||
- Make sure tutorial examples are buildable
|
||||
|
||||
* Demos:
|
||||
- Numerous crash- and bug fixes
|
||||
- Improve about dialogs
|
||||
- gtk4-demo: Modernize source highlighting
|
||||
- gtk4-demo: Improve sidebar filtering
|
||||
- gtk4-demo: Drop some outdated demos
|
||||
- gtk4-demo: Polish a number of existing demos
|
||||
- gtk4-demo: Add several new demos
|
||||
- widget-factory: Show error states
|
||||
|
||||
* Fix build with cups < 2.3
|
||||
* Tools:
|
||||
- Make gtk4-builder-tool rewrite GtkBox
|
||||
- Make gtk4-builder-tool rewrite radio buttons
|
||||
- Rewrite the profiling support, drop support
|
||||
for D-Bus profiler activation, use SYSPROF_TRACE_FD
|
||||
|
||||
* Printing:
|
||||
- Fix build with cups < 2.3
|
||||
|
||||
* win32:
|
||||
- Default to the GL renderer when we can
|
||||
|
||||
* Broadway:
|
||||
- Fix handling of opaque colors
|
||||
- Fix handling of debug nodes
|
||||
- Prune clipped render nodes
|
||||
|
||||
* Wayland:
|
||||
- Support newer schemas for settings
|
||||
- Fix DND hotspot handling
|
||||
- Disconnect on display close
|
||||
|
||||
* Translation updates:
|
||||
Basque
|
||||
Brazilian Portuguese
|
||||
British English
|
||||
Catalan
|
||||
Chinese (China)
|
||||
Croatian
|
||||
Galician
|
||||
German
|
||||
Greek
|
||||
Indonesian
|
||||
Japanese
|
||||
Kazakh
|
||||
Korean
|
||||
Lithuanian
|
||||
Polish
|
||||
Romanian
|
||||
Slovenian
|
||||
Spanish
|
||||
Turkish
|
||||
Ukrainian
|
||||
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
GTK — The GTK toolkit
|
||||
=====================
|
||||
|
||||
[](https://gitlab.gnome.org/GNOME/gtk/pipelines)
|
||||
[](https://gitlab.gnome.org/GNOME/gtk/-/commits/master)
|
||||
|
||||
General information
|
||||
-------------------
|
||||
@@ -98,7 +98,7 @@ And, finally, you can install GTK using:
|
||||
$ sudo ninja install
|
||||
```
|
||||
|
||||
Complete information about installing GTK+ and related libraries
|
||||
Complete information about installing GTK and related libraries
|
||||
can be found in the file:
|
||||
|
||||
```
|
||||
@@ -161,3 +161,7 @@ version 2.1 or, at your option, any later version, as published by the Free
|
||||
Software Foundation.
|
||||
|
||||
Please, see the [`COPYING`](./COPYING) file for further information.
|
||||
|
||||
GTK includes a small number of source files under the Apache license:
|
||||
- A fork of the roaring bitmaps implementation in [gtk/roaring](./gtk/roaring)
|
||||
- An adaptation of timsort from python in [gtk/timsort](./gtk/timsort)
|
||||
|
@@ -1,29 +1,38 @@
|
||||
{
|
||||
"app-id": "org.gtk.Demo4",
|
||||
"runtime": "org.gnome.Platform",
|
||||
"runtime-version": "master",
|
||||
"sdk": "org.gnome.Sdk",
|
||||
"command": "gtk4-demo",
|
||||
"tags": ["devel", "development", "nightly"],
|
||||
"desktop-file-name-prefix": "(Development) ",
|
||||
"finish-args": [
|
||||
"app-id" : "org.gtk.Demo4",
|
||||
"runtime" : "org.gnome.Platform",
|
||||
"runtime-version" : "master",
|
||||
"sdk" : "org.gnome.Sdk",
|
||||
"command" : "gtk4-demo",
|
||||
"tags" : [
|
||||
"devel",
|
||||
"development",
|
||||
"nightly"
|
||||
],
|
||||
"desktop-file-name-prefix" : "(Development) ",
|
||||
"finish-args" : [
|
||||
"--device=dri",
|
||||
"--share=ipc",
|
||||
"--socket=fallback-x11",
|
||||
"--socket=wayland",
|
||||
"--talk-name=org.gtk.vfs", "--talk-name=org.gtk.vfs.*"
|
||||
"--talk-name=org.gtk.vfs",
|
||||
"--talk-name=org.gtk.vfs.*"
|
||||
],
|
||||
"cleanup": [
|
||||
"cleanup" : [
|
||||
"/include",
|
||||
"/lib/pkgconfig", "/share/pkgconfig",
|
||||
"/lib/pkgconfig",
|
||||
"/share/pkgconfig",
|
||||
"/share/aclocal",
|
||||
"/man", "/share/man", "/share/gtk-doc",
|
||||
"*.la", ".a",
|
||||
"/man",
|
||||
"/share/man",
|
||||
"/share/gtk-doc",
|
||||
"*.la",
|
||||
".a",
|
||||
"/lib/girepository-1.0",
|
||||
"/share/gir-1.0",
|
||||
"/share/doc"
|
||||
],
|
||||
"modules": [
|
||||
"modules" : [
|
||||
{
|
||||
"name" : "wayland",
|
||||
"buildsystem" : "autotools",
|
||||
@@ -39,18 +48,18 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "graphene",
|
||||
"buildsystem": "meson",
|
||||
"builddir": true,
|
||||
"config-opts": [
|
||||
"name" : "graphene",
|
||||
"buildsystem" : "meson",
|
||||
"builddir" : true,
|
||||
"config-opts" : [
|
||||
"--libdir=/app/lib",
|
||||
"-Dtests=false",
|
||||
"-Dbenchmarks=false"
|
||||
],
|
||||
"sources": [
|
||||
"sources" : [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/ebassi/graphene.git"
|
||||
"type" : "git",
|
||||
"url" : "https://github.com/ebassi/graphene.git"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -58,7 +67,7 @@
|
||||
"name" : "libsass",
|
||||
"buildsystem" : "meson",
|
||||
"builddir" : true,
|
||||
"config-opts": [
|
||||
"config-opts" : [
|
||||
"--libdir=/app/lib"
|
||||
],
|
||||
"sources" : [
|
||||
@@ -73,7 +82,7 @@
|
||||
"name" : "sassc",
|
||||
"buildsystem" : "meson",
|
||||
"builddir" : true,
|
||||
"config-opts": [
|
||||
"config-opts" : [
|
||||
"--libdir=/app/lib"
|
||||
],
|
||||
"sources" : [
|
||||
@@ -85,18 +94,25 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "gtk",
|
||||
"buildsystem": "meson",
|
||||
"builddir": true,
|
||||
"config-opts": [
|
||||
"--libdir=/app/lib"
|
||||
"name" : "gtk",
|
||||
"buildsystem" : "meson",
|
||||
"builddir" : true,
|
||||
"config-opts" : [
|
||||
"--libdir=/app/lib",
|
||||
"-Denable_vulkan=no",
|
||||
"-Dbuildtype=debugoptimized"
|
||||
],
|
||||
"sources": [
|
||||
"sources" : [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://gitlab.gnome.org/GNOME/gtk.git"
|
||||
"type" : "git",
|
||||
"url" : "https://gitlab.gnome.org/GNOME/gtk.git"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
],
|
||||
"build-options" : {
|
||||
"env" : {
|
||||
"GSK_RENDERER" : "opengl"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,29 +1,38 @@
|
||||
{
|
||||
"app-id": "org.gtk.IconBrowser4",
|
||||
"runtime": "org.gnome.Platform",
|
||||
"runtime-version": "master",
|
||||
"sdk": "org.gnome.Sdk",
|
||||
"command": "gtk4-icon-browser",
|
||||
"tags": ["devel", "development", "nightly"],
|
||||
"desktop-file-name-prefix": "(Development) ",
|
||||
"finish-args": [
|
||||
"app-id" : "org.gtk.IconBrowser4",
|
||||
"runtime" : "org.gnome.Platform",
|
||||
"runtime-version" : "master",
|
||||
"sdk" : "org.gnome.Sdk",
|
||||
"command" : "gtk4-icon-browser",
|
||||
"tags" : [
|
||||
"devel",
|
||||
"development",
|
||||
"nightly"
|
||||
],
|
||||
"desktop-file-name-prefix" : "(Development) ",
|
||||
"finish-args" : [
|
||||
"--device=dri",
|
||||
"--share=ipc",
|
||||
"--socket=fallback-x11",
|
||||
"--socket=wayland",
|
||||
"--talk-name=org.gtk.vfs", "--talk-name=org.gtk.vfs.*"
|
||||
"--talk-name=org.gtk.vfs",
|
||||
"--talk-name=org.gtk.vfs.*"
|
||||
],
|
||||
"cleanup": [
|
||||
"cleanup" : [
|
||||
"/include",
|
||||
"/lib/pkgconfig", "/share/pkgconfig",
|
||||
"/lib/pkgconfig",
|
||||
"/share/pkgconfig",
|
||||
"/share/aclocal",
|
||||
"/man", "/share/man", "/share/gtk-doc",
|
||||
"*.la", ".a",
|
||||
"/man",
|
||||
"/share/man",
|
||||
"/share/gtk-doc",
|
||||
"*.la",
|
||||
".a",
|
||||
"/lib/girepository-1.0",
|
||||
"/share/gir-1.0",
|
||||
"/share/doc"
|
||||
],
|
||||
"modules": [
|
||||
"modules" : [
|
||||
{
|
||||
"name" : "wayland",
|
||||
"buildsystem" : "autotools",
|
||||
@@ -39,18 +48,18 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "graphene",
|
||||
"buildsystem": "meson",
|
||||
"builddir": true,
|
||||
"config-opts": [
|
||||
"name" : "graphene",
|
||||
"buildsystem" : "meson",
|
||||
"builddir" : true,
|
||||
"config-opts" : [
|
||||
"--libdir=/app/lib",
|
||||
"-Dtests=false",
|
||||
"-Dbenchmarks=false"
|
||||
],
|
||||
"sources": [
|
||||
"sources" : [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/ebassi/graphene.git"
|
||||
"type" : "git",
|
||||
"url" : "https://github.com/ebassi/graphene.git"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -58,7 +67,7 @@
|
||||
"name" : "libsass",
|
||||
"buildsystem" : "meson",
|
||||
"builddir" : true,
|
||||
"config-opts": [
|
||||
"config-opts" : [
|
||||
"--libdir=/app/lib"
|
||||
],
|
||||
"sources" : [
|
||||
@@ -73,7 +82,7 @@
|
||||
"name" : "sassc",
|
||||
"buildsystem" : "meson",
|
||||
"builddir" : true,
|
||||
"config-opts": [
|
||||
"config-opts" : [
|
||||
"--libdir=/app/lib"
|
||||
],
|
||||
"sources" : [
|
||||
@@ -85,18 +94,24 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "gtk",
|
||||
"buildsystem": "meson",
|
||||
"builddir": true,
|
||||
"config-opts": [
|
||||
"--libdir=/app/lib"
|
||||
"name" : "gtk",
|
||||
"buildsystem" : "meson",
|
||||
"builddir" : true,
|
||||
"config-opts" : [
|
||||
"--libdir=/app/lib",
|
||||
"-Denable_vulkan=no",
|
||||
"-Dbuildtype=debugoptimized"
|
||||
],
|
||||
"sources": [
|
||||
"sources" : [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://gitlab.gnome.org/GNOME/gtk.git"
|
||||
"type" : "git",
|
||||
"url" : "https://gitlab.gnome.org/GNOME/gtk.git"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
],
|
||||
"build-options" : {
|
||||
"env" : {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -98,7 +98,9 @@
|
||||
"buildsystem" : "meson",
|
||||
"builddir" : true,
|
||||
"config-opts" : [
|
||||
"--libdir=/app/lib"
|
||||
"--libdir=/app/lib",
|
||||
"-Denable_vulkan=no",
|
||||
"-Dbuildtype=debugoptimized"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
@@ -110,7 +112,10 @@
|
||||
],
|
||||
"build-options" : {
|
||||
"env" : {
|
||||
"DBUS_SESSION_BUS_ADDRESS" : "''"
|
||||
"DBUS_SESSION_BUS_ADDRESS" : "''",
|
||||
"GSK_RENDERER" : "opengl",
|
||||
"GDK_DEBUG" : "vulkan-disable",
|
||||
"G_ENABLE_DEBUG" : "true"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -69,6 +69,9 @@
|
||||
/* Define to 1 if you have the `mkstemp' function. */
|
||||
#mesondefine HAVE_MKSTEMP
|
||||
|
||||
/* Define to 1 if you have the `mlock` function. */
|
||||
#mesondefine HAVE_MLOCK
|
||||
|
||||
/* Define to 1 if you have a working `mmap' system call. */
|
||||
#mesondefine HAVE_MMAP
|
||||
|
||||
@@ -103,7 +106,7 @@
|
||||
#mesondefine HAVE_SYS_PARAM_H
|
||||
|
||||
/* Have the sysprof-capture library */
|
||||
#mesondefine HAVE_SYSPROF_CAPTURE
|
||||
#mesondefine HAVE_SYSPROF
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#mesondefine HAVE_SYS_STAT_H
|
||||
|
@@ -177,11 +177,11 @@ constraint_view_init (ConstraintView *self)
|
||||
guides = gtk_constraint_layout_observe_guides (GTK_CONSTRAINT_LAYOUT (manager));
|
||||
|
||||
all_constraints = gtk_constraint_layout_observe_constraints (GTK_CONSTRAINT_LAYOUT (manager));
|
||||
filter = gtk_custom_filter_new (omit_internal, NULL, NULL);
|
||||
filter = GTK_FILTER (gtk_custom_filter_new (omit_internal, NULL, NULL));
|
||||
constraints = (GListModel *)gtk_filter_list_model_new (all_constraints, filter);
|
||||
|
||||
all_children = gtk_widget_observe_children (GTK_WIDGET (self));
|
||||
filter = gtk_custom_filter_new (omit_internal, NULL, NULL);
|
||||
filter = GTK_FILTER (gtk_custom_filter_new (omit_internal, NULL, NULL));
|
||||
children = (GListModel *)gtk_filter_list_model_new (all_children, filter);
|
||||
|
||||
list = g_list_store_new (G_TYPE_LIST_MODEL);
|
||||
|
345
demos/gtk-demo/alienplanet.glsl
Normal file
345
demos/gtk-demo/alienplanet.glsl
Normal file
@@ -0,0 +1,345 @@
|
||||
// Originally from: https://www.shadertoy.com/view/wsjBD3
|
||||
// License CC0: A battered alien planet
|
||||
// Been experimenting with space inspired shaders
|
||||
|
||||
#define PI 3.141592654
|
||||
#define TAU (2.0*PI)
|
||||
|
||||
#define TOLERANCE 0.00001
|
||||
#define MAX_ITER 65
|
||||
#define MIN_DISTANCE 0.01
|
||||
#define MAX_DISTANCE 9.0
|
||||
|
||||
const vec3 skyCol1 = vec3(0.35, 0.45, 0.6);
|
||||
const vec3 skyCol2 = vec3(0.4, 0.7, 1.0);
|
||||
const vec3 skyCol3 = pow(skyCol1, vec3(0.25));
|
||||
const vec3 sunCol1 = vec3(1.0,0.6,0.4);
|
||||
const vec3 sunCol2 = vec3(1.0,0.9,0.7);
|
||||
const vec3 smallSunCol1 = vec3(1.0,0.5,0.25)*0.5;
|
||||
const vec3 smallSunCol2 = vec3(1.0,0.5,0.25)*0.5;
|
||||
const vec3 mountainColor = 1.0*sqrt(vec3(0.95, 0.65, 0.45));
|
||||
const float cellWidth = 1.0;
|
||||
const vec4 planet = vec4(80.0, -20.0, 100.0, 50.0)*1000.0;
|
||||
|
||||
void rot(inout vec2 p, float a) {
|
||||
float c = cos(a);
|
||||
float s = sin(a);
|
||||
p = vec2(p.x*c + p.y*s, -p.x*s + p.y*c);
|
||||
}
|
||||
|
||||
vec2 mod2(inout vec2 p, vec2 size) {
|
||||
vec2 c = floor((p + size*0.5)/size);
|
||||
p = mod(p + size*0.5,size) - size*0.5;
|
||||
return c;
|
||||
}
|
||||
|
||||
float circle(vec2 p, float r) {
|
||||
return length(p) - r;
|
||||
}
|
||||
|
||||
float egg(vec2 p, float ra, float rb) {
|
||||
const float k = sqrt(3.0);
|
||||
p.x = abs(p.x);
|
||||
float r = ra - rb;
|
||||
return ((p.y<0.0) ? length(vec2(p.x, p.y )) - r :
|
||||
(k*(p.x+r)<p.y) ? length(vec2(p.x, p.y-k*r)) :
|
||||
length(vec2(p.x+r,p.y )) - 2.0*r) - rb;
|
||||
}
|
||||
|
||||
vec2 hash(vec2 p) {
|
||||
p = vec2(dot (p, vec2 (127.1, 311.7)), dot (p, vec2 (269.5, 183.3)));
|
||||
return -1. + 2.*fract (sin (p)*43758.5453123);
|
||||
}
|
||||
|
||||
vec2 raySphere(vec3 ro, vec3 rd, vec4 sphere) {
|
||||
vec3 center = sphere.xyz;
|
||||
float radius = sphere.w;
|
||||
vec3 m = ro - center.xyz;
|
||||
float b = dot(m, rd);
|
||||
float c = dot(m, m) - radius*radius;
|
||||
if(c > 0.0 && b > 0.0) return vec2(-1.0, -1.0);
|
||||
float discr = b * b - c;
|
||||
if(discr < 0.0) return vec2(-1.0);
|
||||
float normalMultiplier = 1.0;
|
||||
float s = sqrt(discr);
|
||||
float t0 = -b - s;
|
||||
float t1 = -b + s;;
|
||||
return vec2(t0, t1);
|
||||
}
|
||||
|
||||
float noise1(vec2 p) {
|
||||
vec2 n = mod2(p, vec2(cellWidth));
|
||||
vec2 hh = hash(sqrt(2.0)*(n+1000.0));
|
||||
hh.x *= hh.y;
|
||||
|
||||
float r = 0.225*cellWidth;
|
||||
|
||||
float d = circle(p, 2.0*r);
|
||||
|
||||
float h = hh.x*smoothstep(0.0, r, -d);
|
||||
|
||||
return h*0.25;
|
||||
}
|
||||
|
||||
float noise2(vec2 p) {
|
||||
vec2 n = mod2(p, vec2(cellWidth));
|
||||
vec2 hh = hash(sqrt(2.0)*(n+1000.0));
|
||||
hh.x *= hh.y;
|
||||
|
||||
rot(p, TAU*hh.y);
|
||||
float r = 0.45*cellWidth;
|
||||
|
||||
// float d = circle(p, 1.0*r);
|
||||
float d = egg(p, 0.75*r, 0.5*r*abs(hh.y));
|
||||
|
||||
float h = (hh.x)*smoothstep(0.0, r, -2.0*d);
|
||||
|
||||
return h*0.275;
|
||||
}
|
||||
|
||||
|
||||
float height(vec2 p, float dd, int mx) {
|
||||
const float aa = 0.45;
|
||||
const float ff = 2.03;
|
||||
const float tt = 1.2;
|
||||
const float oo = 3.93;
|
||||
const float near = 0.25;
|
||||
const float far = 0.65;
|
||||
|
||||
float a = 1.0;
|
||||
float o = 0.2;
|
||||
float s = 0.0;
|
||||
float d = 0.0;
|
||||
|
||||
int i = 0;
|
||||
|
||||
for (; i < 4;++i) {
|
||||
float nn = a*noise2(p);
|
||||
s += nn;
|
||||
d += abs(a);
|
||||
p += o;
|
||||
a *= aa;
|
||||
p *= ff;
|
||||
o *= oo;
|
||||
rot(p, tt);
|
||||
}
|
||||
|
||||
float lod = s/d;
|
||||
|
||||
float rdd = dd/MAX_DISTANCE;
|
||||
mx = int(mix(float(4), float(mx), step(rdd, far)));
|
||||
|
||||
for (; i < mx; ++i) {
|
||||
float nn = a*noise1(p);
|
||||
s += nn;
|
||||
d += abs(a);
|
||||
p += o;
|
||||
a *= aa;
|
||||
p *= ff;
|
||||
o *= oo;
|
||||
rot(p, tt);
|
||||
}
|
||||
|
||||
float hid = (s/d);
|
||||
|
||||
return mix(hid, lod, smoothstep(near, far, rdd));
|
||||
}
|
||||
|
||||
float loheight(vec2 p, float d) {
|
||||
return height(p, d, 0);
|
||||
}
|
||||
|
||||
float height(vec2 p, float d) {
|
||||
return height(p, d, 6);
|
||||
}
|
||||
|
||||
float hiheight(vec2 p, float d) {
|
||||
return height(p, d, 8);
|
||||
}
|
||||
|
||||
vec3 normal(vec2 p, float d) {
|
||||
vec2 eps = vec2(0.00125, 0.0);
|
||||
|
||||
vec3 n;
|
||||
|
||||
n.x = (hiheight(p - eps.xy, d) - hiheight(p + eps.xy, d));
|
||||
n.y = 2.0*eps.x;
|
||||
n.z = (hiheight(p - eps.yx, d) - hiheight(p + eps.yx, d));
|
||||
|
||||
return normalize(n);
|
||||
}
|
||||
|
||||
const float stepLength[] = float[](0.9, 0.25);
|
||||
|
||||
|
||||
float march(vec3 ro, vec3 rd, out int max_iter) {
|
||||
float dt = 0.1;
|
||||
float d = MIN_DISTANCE;
|
||||
int currentStep = 0;
|
||||
float lastd = d;
|
||||
for (int i = 0; i < MAX_ITER; ++i)
|
||||
{
|
||||
vec3 p = ro + d*rd;
|
||||
float h = height(p.xz, d);
|
||||
|
||||
if (d > MAX_DISTANCE) {
|
||||
max_iter = i;
|
||||
return MAX_DISTANCE;
|
||||
}
|
||||
|
||||
float hd = p.y - h;
|
||||
|
||||
if (hd < TOLERANCE) {
|
||||
++currentStep;
|
||||
if (currentStep >= stepLength.length()) {
|
||||
max_iter = i;
|
||||
return d;
|
||||
}
|
||||
|
||||
d = lastd;
|
||||
continue;
|
||||
}
|
||||
|
||||
float sl = stepLength[currentStep];
|
||||
|
||||
dt = max(hd, TOLERANCE)*sl + 0.0025*d;
|
||||
lastd = d;
|
||||
d += dt;
|
||||
}
|
||||
|
||||
max_iter = MAX_ITER;
|
||||
return MAX_DISTANCE;
|
||||
}
|
||||
|
||||
vec3 sunDirection() {
|
||||
return normalize(vec3(-0.5, 0.085, 1.0));
|
||||
}
|
||||
|
||||
vec3 smallSunDirection() {
|
||||
return normalize(vec3(-0.2, -0.05, 1.0));
|
||||
}
|
||||
|
||||
float psin(float f) {
|
||||
return 0.5 + 0.5*sin(f);
|
||||
}
|
||||
|
||||
vec3 skyColor(vec3 ro, vec3 rd) {
|
||||
vec3 sunDir = sunDirection();
|
||||
vec3 smallSunDir = smallSunDirection();
|
||||
|
||||
float sunDot = max(dot(rd, sunDir), 0.0);
|
||||
float smallSunDot = max(dot(rd, smallSunDir), 0.0);
|
||||
|
||||
float angle = atan(rd.y, length(rd.xz))*2.0/PI;
|
||||
|
||||
vec3 skyCol = mix(mix(skyCol1, skyCol2, max(0.0, angle)), skyCol3, clamp(-angle*2.0, 0.0, 1.0));
|
||||
|
||||
vec3 sunCol = 0.5*sunCol1*pow(sunDot, 20.0) + 8.0*sunCol2*pow(sunDot, 2000.0);
|
||||
vec3 smallSunCol = 0.5*smallSunCol1*pow(smallSunDot, 200.0) + 8.0*smallSunCol2*pow(smallSunDot, 20000.0);
|
||||
|
||||
vec3 dust = pow(sunCol2*mountainColor, vec3(1.75))*smoothstep(0.05, -0.1, rd.y)*0.5;
|
||||
|
||||
vec2 si = raySphere(ro, rd, planet);
|
||||
|
||||
vec3 planetSurface = ro + si.x*rd;
|
||||
vec3 planetNormal = normalize(planetSurface - planet.xyz);
|
||||
float planetDiff = max(dot(planetNormal, sunDir), 0.0);
|
||||
float planetBorder = max(dot(planetNormal, -rd), 0.0);
|
||||
float planetLat = (planetSurface.x+planetSurface.y)*0.0005;
|
||||
vec3 planetCol = mix(1.3*vec3(0.9, 0.8, 0.7), 0.3*vec3(0.9, 0.8, 0.7), pow(psin(planetLat+1.0)*psin(sqrt(2.0)*planetLat+2.0)*psin(sqrt(3.5)*planetLat+3.0), 0.5));
|
||||
|
||||
vec3 final = vec3(0.0);
|
||||
|
||||
final += step(0.0, si.x)*pow(planetDiff, 0.75)*planetCol*smoothstep(-0.075, 0.0, rd.y)*smoothstep(0.0, 0.1, planetBorder);
|
||||
|
||||
final += skyCol + sunCol + smallSunCol + dust;
|
||||
|
||||
return final;
|
||||
}
|
||||
|
||||
vec3 getColor(vec3 ro, vec3 rd) {
|
||||
int max_iter = 0;
|
||||
vec3 skyCol = skyColor(ro, rd);
|
||||
vec3 col = vec3(0);
|
||||
|
||||
float d = march(ro, rd, max_iter);
|
||||
|
||||
if (d < MAX_DISTANCE) {
|
||||
vec3 sunDir = sunDirection();
|
||||
vec3 osunDir = sunDir*vec3(-1.0, .0, -1.0);
|
||||
vec3 p = ro + d*rd;
|
||||
|
||||
vec3 normal = normal(p.xz, d);
|
||||
|
||||
float amb = 0.2;
|
||||
|
||||
float dif1 = max(0.0, dot(sunDir, normal));
|
||||
vec3 shd1 = sunCol2*mix(amb, 1.0, pow(dif1, 0.75));
|
||||
|
||||
float dif2 = max(0.0, dot(osunDir, normal));
|
||||
vec3 shd2 = sunCol1*mix(amb, 1.0, pow(dif2, 0.75));
|
||||
|
||||
vec3 ref = reflect(rd, normal);
|
||||
vec3 rcol = skyColor(p, ref);
|
||||
|
||||
col = mountainColor*amb*skyCol3;
|
||||
col += mix(shd1, shd2, -0.5)*mountainColor;
|
||||
float fre = max(dot(normal, -rd), 0.0);
|
||||
fre = pow(1.0 - fre, 5.0);
|
||||
col += rcol*fre*0.5;
|
||||
col += (1.0*p.y);
|
||||
col = tanh(col);
|
||||
col = mix(col, skyCol, smoothstep(0.5*MAX_DISTANCE, 1.0*MAX_DISTANCE, d));
|
||||
|
||||
} else {
|
||||
col = skyCol;
|
||||
}
|
||||
|
||||
// col += vec3(1.1, 0.0, 0.0)* smoothstep(0.25, 1.0,(float(max_iter)/float(MAX_ITER)));
|
||||
return col;
|
||||
}
|
||||
|
||||
vec3 getSample1(vec2 p, float time) {
|
||||
float off = 0.5*iTime;
|
||||
|
||||
vec3 ro = vec3(0.5, 1.0-0.25, -2.0 + off);
|
||||
vec3 la = ro + vec3(0.0, -0.30, 2.0);
|
||||
|
||||
vec3 ww = normalize(la - ro);
|
||||
vec3 uu = normalize(cross(vec3(0.0,1.0,0.0), ww));
|
||||
vec3 vv = normalize(cross(ww, uu));
|
||||
vec3 rd = normalize(p.x*uu + p.y*vv + 2.0*ww);
|
||||
|
||||
vec3 col = getColor(ro, rd) ;
|
||||
|
||||
return col;
|
||||
}
|
||||
|
||||
vec3 getSample2(vec2 p, float time) {
|
||||
p.y-=time*0.25;
|
||||
float h = height(p, 0.0);
|
||||
vec3 n = normal(p, 0.0);
|
||||
|
||||
vec3 lp = vec3(10.0, -1.2, 0.0);
|
||||
|
||||
vec3 ld = normalize(vec3(p.x, h, p.y)- lp);
|
||||
|
||||
float d = max(dot(ld, n), 0.0);
|
||||
|
||||
vec3 col = vec3(0.0);
|
||||
|
||||
col = vec3(1.0)*(h+0.1);
|
||||
col += vec3(1.5)*pow(d, 0.75);
|
||||
|
||||
return col;
|
||||
}
|
||||
|
||||
void mainImage(out vec4 fragColor, vec2 fragCoord) {
|
||||
vec2 q = fragCoord.xy/iResolution.xy;
|
||||
vec2 p = -1.0 + 2.0*q;
|
||||
p.x *= iResolution.x/iResolution.y;
|
||||
|
||||
vec3 col = getSample1(p, iTime);
|
||||
|
||||
fragColor = vec4(col, 1.0);
|
||||
}
|
@@ -1,4 +1,3 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
@@ -473,11 +472,11 @@ static void
|
||||
surface_state_changed (GtkWidget *widget)
|
||||
{
|
||||
DemoApplicationWindow *window = (DemoApplicationWindow *)widget;
|
||||
GdkSurfaceState new_state;
|
||||
GdkToplevelState new_state;
|
||||
|
||||
new_state = gdk_toplevel_get_state (GDK_TOPLEVEL (gtk_native_get_surface (GTK_NATIVE (widget))));
|
||||
window->maximized = (new_state & GDK_SURFACE_STATE_MAXIMIZED) != 0;
|
||||
window->fullscreen = (new_state & GDK_SURFACE_STATE_FULLSCREEN) != 0;
|
||||
window->maximized = (new_state & GDK_TOPLEVEL_STATE_MAXIMIZED) != 0;
|
||||
window->fullscreen = (new_state & GDK_TOPLEVEL_STATE_FULLSCREEN) != 0;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -8,6 +8,10 @@
|
||||
<property name="default-height">300</property>
|
||||
<child>
|
||||
<object class="GtkGrid">
|
||||
<property name="margin-start">12</property>
|
||||
<property name="margin-end">12</property>
|
||||
<property name="margin-top">12</property>
|
||||
<property name="margin-bottom">12</property>
|
||||
<property name="row-spacing">12</property>
|
||||
<property name="column-spacing">12</property>
|
||||
<child>
|
||||
|
@@ -132,10 +132,10 @@ blur_overlay_child_update_style_classes (BlurOverlay *overlay,
|
||||
gboolean is_left, is_right, is_top, is_bottom;
|
||||
gboolean has_left, has_right, has_top, has_bottom;
|
||||
|
||||
has_left = gtk_widget_has_css_class (child, GTK_STYLE_CLASS_LEFT);
|
||||
has_right = gtk_widget_has_css_class (child, GTK_STYLE_CLASS_RIGHT);
|
||||
has_top = gtk_widget_has_css_class (child, GTK_STYLE_CLASS_TOP);
|
||||
has_bottom = gtk_widget_has_css_class (child, GTK_STYLE_CLASS_BOTTOM);
|
||||
has_left = gtk_widget_has_css_class (child, "left");
|
||||
has_right = gtk_widget_has_css_class (child, "right");
|
||||
has_top = gtk_widget_has_css_class (child, "top");
|
||||
has_bottom = gtk_widget_has_css_class (child, "bottom");
|
||||
|
||||
is_left = is_right = is_top = is_bottom = FALSE;
|
||||
|
||||
@@ -158,24 +158,24 @@ blur_overlay_child_update_style_classes (BlurOverlay *overlay,
|
||||
is_bottom = (child_allocation->y + child_allocation->height == height);
|
||||
|
||||
if (has_left && !is_left)
|
||||
gtk_widget_remove_css_class (child, GTK_STYLE_CLASS_LEFT);
|
||||
gtk_widget_remove_css_class (child, "left");
|
||||
else if (!has_left && is_left)
|
||||
gtk_widget_add_css_class (child, GTK_STYLE_CLASS_LEFT);
|
||||
gtk_widget_add_css_class (child, "left");
|
||||
|
||||
if (has_right && !is_right)
|
||||
gtk_widget_remove_css_class (child, GTK_STYLE_CLASS_RIGHT);
|
||||
gtk_widget_remove_css_class (child, "right");
|
||||
else if (!has_right && is_right)
|
||||
gtk_widget_add_css_class (child, GTK_STYLE_CLASS_RIGHT);
|
||||
gtk_widget_add_css_class (child, "right");
|
||||
|
||||
if (has_top && !is_top)
|
||||
gtk_widget_remove_css_class (child, GTK_STYLE_CLASS_TOP);
|
||||
gtk_widget_remove_css_class (child, "top");
|
||||
else if (!has_top && is_top)
|
||||
gtk_widget_add_css_class (child, GTK_STYLE_CLASS_TOP);
|
||||
gtk_widget_add_css_class (child, "top");
|
||||
|
||||
if (has_bottom && !is_bottom)
|
||||
gtk_widget_remove_css_class (child, GTK_STYLE_CLASS_BOTTOM);
|
||||
gtk_widget_remove_css_class (child, "bottom");
|
||||
else if (!has_bottom && is_bottom)
|
||||
gtk_widget_add_css_class (child, GTK_STYLE_CLASS_BOTTOM);
|
||||
gtk_widget_add_css_class (child, "bottom");
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -21,15 +21,38 @@ about_activate (GSimpleAction *action,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *window = user_data;
|
||||
GtkBuilder *builder;
|
||||
GtkWidget *about_dlg;
|
||||
|
||||
builder = g_object_get_data (G_OBJECT (window), "builder");
|
||||
about_dlg = GTK_WIDGET (gtk_builder_get_object (builder, "aboutdialog1"));
|
||||
gtk_window_set_transient_for (GTK_WINDOW (about_dlg), GTK_WINDOW (window));
|
||||
gtk_window_set_hide_on_close (GTK_WINDOW (about_dlg), TRUE);
|
||||
g_signal_connect (about_dlg, "response", G_CALLBACK (gtk_widget_hide), NULL);
|
||||
gtk_widget_show (about_dlg);
|
||||
about_dlg = GTK_WIDGET (g_object_get_data (G_OBJECT (window), "about"));
|
||||
gtk_window_present (GTK_WINDOW (about_dlg));
|
||||
}
|
||||
|
||||
static void
|
||||
remove_timeout (gpointer data)
|
||||
{
|
||||
guint id = GPOINTER_TO_UINT (data);
|
||||
|
||||
g_source_remove (id);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
pop_status (gpointer data)
|
||||
{
|
||||
gtk_statusbar_pop (GTK_STATUSBAR (data), 0);
|
||||
g_object_set_data (G_OBJECT (data), "timeout", NULL);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
status_message (GtkStatusbar *status,
|
||||
const char *text)
|
||||
{
|
||||
guint id;
|
||||
|
||||
gtk_statusbar_push (GTK_STATUSBAR (status), 0, text);
|
||||
id = g_timeout_add (5000, pop_status, status);
|
||||
|
||||
g_object_set_data_full (G_OBJECT (status), "timeout", GUINT_TO_POINTER (id), remove_timeout);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -37,7 +60,10 @@ help_activate (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_print ("Help not available\n");
|
||||
GtkWidget *status;
|
||||
|
||||
status = GTK_WIDGET (g_object_get_data (G_OBJECT (user_data), "status"));
|
||||
status_message (GTK_STATUSBAR (status), "Help not available");
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -45,7 +71,13 @@ not_implemented (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_print ("Action “%s” not implemented\n", g_action_get_name (G_ACTION (action)));
|
||||
GtkWidget *status;
|
||||
char *text;
|
||||
|
||||
text = g_strdup_printf ("Action “%s” not implemented", g_action_get_name (G_ACTION (action)));
|
||||
status = GTK_WIDGET (g_object_get_data (G_OBJECT (user_data), "status"));
|
||||
status_message (GTK_STATUSBAR (status), text);
|
||||
g_free (text);
|
||||
}
|
||||
|
||||
static GActionEntry win_entries[] = {
|
||||
@@ -70,6 +102,8 @@ do_builder (GtkWidget *do_widget)
|
||||
if (!window)
|
||||
{
|
||||
GtkBuilder *builder;
|
||||
GtkWidget *about;
|
||||
GtkWidget *status;
|
||||
|
||||
builder = gtk_builder_new_from_resource ("/builder/demo.ui");
|
||||
|
||||
@@ -83,6 +117,16 @@ do_builder (GtkWidget *do_widget)
|
||||
window);
|
||||
gtk_widget_insert_action_group (window, "win", actions);
|
||||
|
||||
about = GTK_WIDGET (gtk_builder_get_object (builder, "aboutdialog1"));
|
||||
gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (window));
|
||||
gtk_window_set_hide_on_close (GTK_WINDOW (about), TRUE);
|
||||
g_signal_connect (about, "response", G_CALLBACK (gtk_widget_hide), NULL);
|
||||
g_object_set_data_full (G_OBJECT (window), "about",
|
||||
about, (GDestroyNotify)gtk_window_destroy);
|
||||
|
||||
status = GTK_WIDGET (gtk_builder_get_object (builder, "statusbar1"));
|
||||
g_object_set_data (G_OBJECT (window), "status", status);
|
||||
|
||||
g_object_unref (builder);
|
||||
}
|
||||
|
||||
|
224
demos/gtk-demo/cogs.glsl
Normal file
224
demos/gtk-demo/cogs.glsl
Normal file
@@ -0,0 +1,224 @@
|
||||
// Originally from: https://www.shadertoy.com/view/3ljyDD
|
||||
// License CC0: Hexagonal tiling + cog wheels
|
||||
// Nothing fancy, just hexagonal tiling + cog wheels
|
||||
|
||||
#define PI 3.141592654
|
||||
#define TAU (2.0*PI)
|
||||
#define MROT(a) mat2(cos(a), sin(a), -sin(a), cos(a))
|
||||
|
||||
float hash(in vec2 co) {
|
||||
return fract(sin(dot(co.xy ,vec2(12.9898,58.233))) * 13758.5453);
|
||||
}
|
||||
|
||||
float pcos(float a) {
|
||||
return 0.5 + 0.5*cos(a);
|
||||
}
|
||||
|
||||
void rot(inout vec2 p, float a) {
|
||||
float c = cos(a);
|
||||
float s = sin(a);
|
||||
p = vec2(c*p.x + s*p.y, -s*p.x + c*p.y);
|
||||
}
|
||||
|
||||
float modPolar(inout vec2 p, float repetitions) {
|
||||
float angle = 2.0*PI/repetitions;
|
||||
float a = atan(p.y, p.x) + angle/2.;
|
||||
float r = length(p);
|
||||
float c = floor(a/angle);
|
||||
a = mod(a,angle) - angle/2.;
|
||||
p = vec2(cos(a), sin(a))*r;
|
||||
// For an odd number of repetitions, fix cell index of the cell in -x direction
|
||||
// (cell index would be e.g. -5 and 5 in the two halves of the cell):
|
||||
if (abs(c) >= (repetitions/2.0)) c = abs(c);
|
||||
return c;
|
||||
}
|
||||
|
||||
float pmin(float a, float b, float k) {
|
||||
float h = clamp( 0.5+0.5*(b-a)/k, 0.0, 1.0 );
|
||||
return mix( b, a, h ) - k*h*(1.0-h);
|
||||
}
|
||||
|
||||
const vec2 sz = vec2(1.0, sqrt(3.0));
|
||||
const vec2 hsz = 0.5*sz;
|
||||
const float smallCount = 16.0;
|
||||
|
||||
vec2 hextile(inout vec2 p) {
|
||||
// See Art of Code: Hexagonal Tiling Explained!
|
||||
// https://www.youtube.com/watch?v=VmrIDyYiJBA
|
||||
|
||||
vec2 p1 = mod(p, sz)-hsz;
|
||||
vec2 p2 = mod(p - hsz*1.0, sz)-hsz;
|
||||
vec2 p3 = mix(p2, p1, vec2(length(p1) < length(p2)));
|
||||
vec2 n = p3 - p;
|
||||
p = p3;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
float circle(vec2 p, float r) {
|
||||
return length(p) - r;
|
||||
}
|
||||
|
||||
float box(vec2 p, vec2 b) {
|
||||
vec2 d = abs(p)-b;
|
||||
return length(max(d,0.0)) + min(max(d.x,d.y),0.0);
|
||||
}
|
||||
|
||||
float unevenCapsule(vec2 p, float r1, float r2, float h) {
|
||||
p.x = abs(p.x);
|
||||
float b = (r1-r2)/h;
|
||||
float a = sqrt(1.0-b*b);
|
||||
float k = dot(p,vec2(-b,a));
|
||||
if( k < 0.0 ) return length(p) - r1;
|
||||
if( k > a*h ) return length(p-vec2(0.0,h)) - r2;
|
||||
return dot(p, vec2(a,b) ) - r1;
|
||||
}
|
||||
|
||||
float cogwheel(vec2 p, float innerRadius, float outerRadius, float cogs, float holes) {
|
||||
float cogWidth = 0.25*innerRadius*TAU/cogs;
|
||||
|
||||
float d0 = circle(p, innerRadius);
|
||||
|
||||
vec2 icp = p;
|
||||
modPolar(icp, holes);
|
||||
icp -= vec2(innerRadius*0.55, 0.0);
|
||||
float d1 = circle(icp, innerRadius*0.25);
|
||||
|
||||
vec2 cp = p;
|
||||
modPolar(cp, cogs);
|
||||
cp -= vec2(innerRadius, 0.0);
|
||||
float d2 = unevenCapsule(cp.yx, cogWidth, cogWidth*0.75, (outerRadius-innerRadius));
|
||||
|
||||
float d3 = circle(p, innerRadius*0.20);
|
||||
|
||||
float d = 1E6;
|
||||
d = min(d, d0);
|
||||
d = pmin(d, d2, 0.5*cogWidth);
|
||||
d = min(d, d2);
|
||||
d = max(d, -d1);
|
||||
d = max(d, -d3);
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
float ccell1(vec2 p, float r) {
|
||||
float d = 1E6;
|
||||
const float bigCount = 60.0;
|
||||
|
||||
vec2 cp0 = p;
|
||||
rot(cp0, -iTime*TAU/bigCount);
|
||||
float d0 = cogwheel(cp0, 0.36, 0.38, bigCount, 5.0);
|
||||
|
||||
vec2 cp1 = p;
|
||||
float nm = modPolar(cp1, 6.0);
|
||||
|
||||
cp1 -= vec2(0.5, 0.0);
|
||||
rot(cp1, 0.2+TAU*nm/2.0 + iTime*TAU/smallCount);
|
||||
float d1 = cogwheel(cp1, 0.11, 0.125, smallCount, 5.0);
|
||||
|
||||
d = min(d, d0);
|
||||
d = min(d, d1);
|
||||
return d;
|
||||
}
|
||||
|
||||
float ccell2(vec2 p, float r) {
|
||||
float d = 1E6;
|
||||
vec2 cp0 = p;
|
||||
float nm = modPolar(cp0, 6.0);
|
||||
vec2 cp1 = cp0;
|
||||
const float off = 0.275;
|
||||
const float count = smallCount + 2.0;
|
||||
cp0 -= vec2(off, 0.0);
|
||||
rot(cp0, 0.+TAU*nm/2.0 - iTime*TAU/count);
|
||||
float d0 = cogwheel(cp0, 0.09, 0.105, count, 5.0);
|
||||
|
||||
|
||||
cp1 -= vec2(0.5, 0.0);
|
||||
rot(cp1, 0.2+TAU*nm/2.0 + iTime*TAU/smallCount);
|
||||
float d1 = cogwheel(cp1, 0.11, 0.125, smallCount, 5.0);
|
||||
|
||||
float l = length(p);
|
||||
float d2 = l - (off+0.055);
|
||||
float d3 = d2 + 0.020;;
|
||||
|
||||
vec2 tp0 = p;
|
||||
modPolar(tp0, 60.0);
|
||||
tp0.x -= off;
|
||||
float d4 = box(tp0, vec2(0.0125, 0.005));
|
||||
|
||||
float ctime = -(iTime*0.05 + r)*TAU;
|
||||
|
||||
vec2 tp1 = p;
|
||||
rot(tp1, ctime*12.0);
|
||||
tp1.x -= 0.13;
|
||||
float d5 = box(tp1, vec2(0.125, 0.005));
|
||||
|
||||
vec2 tp2 = p;
|
||||
rot(tp2, ctime);
|
||||
tp2.x -= 0.13*0.5;
|
||||
float d6 = box(tp2, vec2(0.125*0.5, 0.0075));
|
||||
|
||||
float d7 = l - 0.025;
|
||||
float d8 = l - 0.0125;
|
||||
|
||||
d = min(d, d0);
|
||||
d = min(d, d1);
|
||||
d = min(d, d2);
|
||||
d = max(d, -d3);
|
||||
d = min(d, d4);
|
||||
d = min(d, d5);
|
||||
d = min(d, d6);
|
||||
d = min(d, d7);
|
||||
d = max(d, -d8);
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
float df(vec2 p, float scale, inout vec2 nn) {
|
||||
p /= scale;
|
||||
nn = hextile(p);
|
||||
nn = round(nn);
|
||||
float r = hash(nn);
|
||||
|
||||
float d;;
|
||||
|
||||
if (r < 0.5) {
|
||||
d = ccell1(p, r);
|
||||
} else {
|
||||
d = ccell2(p, r);
|
||||
}
|
||||
|
||||
return d*scale;
|
||||
}
|
||||
|
||||
vec3 postProcess(vec3 col, vec2 q) {
|
||||
//col = saturate(col);
|
||||
col=pow(clamp(col,0.0,1.0),vec3(0.75));
|
||||
col=col*0.6+0.4*col*col*(3.0-2.0*col); // contrast
|
||||
col=mix(col, vec3(dot(col, vec3(0.33))), -0.4); // satuation
|
||||
col*=0.5+0.5*pow(19.0*q.x*q.y*(1.0-q.x)*(1.0-q.y),0.7); // vigneting
|
||||
return col;
|
||||
}
|
||||
|
||||
void mainImage(out vec4 fragColor, vec2 fragCoord) {
|
||||
vec2 q = fragCoord/iResolution.xy;
|
||||
vec2 p = -1.0 + 2.0*q;
|
||||
p.x *= iResolution.x/iResolution.y;
|
||||
float tm = iTime*0.1;
|
||||
p += vec2(cos(tm), sin(tm*sqrt(0.5)));
|
||||
float z = mix(0.5, 1.0, pcos(tm*sqrt(0.3)));
|
||||
float aa = 4.0 / iResolution.y;
|
||||
|
||||
vec2 nn = vec2(0.0);
|
||||
float d = df(p, z, nn);
|
||||
|
||||
vec3 col = vec3(160.0)/vec3(255.0);
|
||||
vec3 baseCol = vec3(0.3);
|
||||
vec4 logoCol = vec4(baseCol, 1.0)*smoothstep(-aa, 0.0, -d);
|
||||
col = mix(col, logoCol.xyz, pow(logoCol.w, 8.0));
|
||||
col += 0.4*pow(abs(sin(20.0*d)), 0.6);
|
||||
|
||||
col = postProcess(col, q);
|
||||
|
||||
fragColor = vec4(col, 1.0);
|
||||
}
|
@@ -254,15 +254,11 @@ do_constraints (GtkWidget *do_widget)
|
||||
|
||||
if (!window)
|
||||
{
|
||||
GtkWidget *header, *box, *grid, *button;
|
||||
GtkWidget *box, *grid;
|
||||
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Constraints");
|
||||
|
||||
header = gtk_header_bar_new ();
|
||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), FALSE);
|
||||
gtk_window_set_titlebar (GTK_WINDOW (window), header);
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
|
||||
@@ -272,12 +268,6 @@ do_constraints (GtkWidget *do_widget)
|
||||
gtk_widget_set_hexpand (grid, TRUE);
|
||||
gtk_widget_set_vexpand (grid, TRUE);
|
||||
gtk_box_append (GTK_BOX (box), grid);
|
||||
|
||||
button = gtk_button_new_with_label ("Close");
|
||||
gtk_box_append (GTK_BOX (box), button);
|
||||
gtk_widget_set_hexpand (grid, TRUE);
|
||||
g_signal_connect_swapped (button, "clicked",
|
||||
G_CALLBACK (gtk_window_destroy), window);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
|
@@ -210,15 +210,11 @@ do_constraints2 (GtkWidget *do_widget)
|
||||
|
||||
if (!window)
|
||||
{
|
||||
GtkWidget *header, *box, *grid, *button;
|
||||
GtkWidget *box, *grid;
|
||||
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Constraints");
|
||||
|
||||
header = gtk_header_bar_new ();
|
||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), FALSE);
|
||||
gtk_window_set_titlebar (GTK_WINDOW (window), header);
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
|
||||
@@ -228,12 +224,6 @@ do_constraints2 (GtkWidget *do_widget)
|
||||
gtk_widget_set_hexpand (grid, TRUE);
|
||||
gtk_widget_set_vexpand (grid, TRUE);
|
||||
gtk_box_append (GTK_BOX (box), grid);
|
||||
|
||||
button = gtk_button_new_with_label ("Close");
|
||||
gtk_box_append (GTK_BOX (box), button);
|
||||
gtk_widget_set_hexpand (grid, TRUE);
|
||||
g_signal_connect_swapped (button, "clicked",
|
||||
G_CALLBACK (gtk_window_destroy), window);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
|
@@ -130,15 +130,11 @@ do_constraints3 (GtkWidget *do_widget)
|
||||
|
||||
if (!window)
|
||||
{
|
||||
GtkWidget *header, *box, *grid, *button;
|
||||
GtkWidget *box, *grid;
|
||||
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Constraints");
|
||||
|
||||
header = gtk_header_bar_new ();
|
||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), FALSE);
|
||||
gtk_window_set_titlebar (GTK_WINDOW (window), header);
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
|
||||
@@ -148,12 +144,6 @@ do_constraints3 (GtkWidget *do_widget)
|
||||
gtk_widget_set_hexpand (grid, TRUE);
|
||||
gtk_widget_set_vexpand (grid, TRUE);
|
||||
gtk_box_append (GTK_BOX (box), grid);
|
||||
|
||||
button = gtk_button_new_with_label ("Close");
|
||||
gtk_box_append (GTK_BOX (box), button);
|
||||
gtk_widget_set_hexpand (grid, TRUE);
|
||||
g_signal_connect_swapped (button, "clicked",
|
||||
G_CALLBACK (gtk_window_destroy), window);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
|
@@ -15,6 +15,10 @@
|
||||
border: 1px solid;
|
||||
}
|
||||
|
||||
window {
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
/* Make sure selections are visible */
|
||||
selection {
|
||||
background-color: darkGreen;
|
||||
|
@@ -46,19 +46,19 @@
|
||||
}
|
||||
|
||||
@keyframes size-the-image {
|
||||
0% { background-size: 96px, 12px, 96px, 12px, 96px, 12px, 96px, 12px, auto }
|
||||
100% { background-size: 12px, 96px, 12px, 96px, 12px, 96px, 12px, 96px, auto }
|
||||
0% { background-size: 96px, 12px, 96px, 12px, 96px, 12px, 96px, 12px, auto; }
|
||||
100% { background-size: 12px, 96px, 12px, 96px, 12px, 96px, 12px, 96px, auto; }
|
||||
}
|
||||
|
||||
window {
|
||||
background-image: url("resource://css_pixbufs/apple-red.png"),
|
||||
url("resource://css_pixbufs/gnome-applets.png"),
|
||||
url("resource://css_pixbufs/gnome-calendar.png"),
|
||||
url("resource://css_pixbufs/gnome-foot.png"),
|
||||
url("resource://css_pixbufs/gnome-gmush.png"),
|
||||
url("resource://css_pixbufs/gnome-gimp.png"),
|
||||
url("resource://css_pixbufs/gnome-gsame.png"),
|
||||
url("resource://css_pixbufs/gnu-keys.png"),
|
||||
background-image: url("resource://css_pixbufs/images/apple-red.png"),
|
||||
url("resource://css_pixbufs/images/gnome-applets.png"),
|
||||
url("resource://css_pixbufs/images/gnome-calendar.png"),
|
||||
url("resource://css_pixbufs/images/gnome-foot.png"),
|
||||
url("resource://css_pixbufs/images/gnome-gmush.png"),
|
||||
url("resource://css_pixbufs/images/gnome-gimp.png"),
|
||||
url("resource://css_pixbufs/images/gnome-gsame.png"),
|
||||
url("resource://css_pixbufs/images/gnu-keys.png"),
|
||||
url("resource://css_pixbufs/background.jpg");
|
||||
background-position: 50.00% 75.00%, 67.68% 67.68%, 75.00% 50.00%, 67.68% 32.32%, 50.00% 25.00%, 32.32% 32.32%, 25.00% 50.00%, 32.32% 67.68%, 0% 0%;
|
||||
background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, repeat;
|
||||
|
@@ -106,6 +106,7 @@ do_css_shadows (GtkWidget *do_widget)
|
||||
|
||||
child = create_toolbar ();
|
||||
gtk_paned_set_start_child (GTK_PANED (paned), child);
|
||||
gtk_paned_set_resize_start_child (GTK_PANED (paned), FALSE);
|
||||
|
||||
text = gtk_text_buffer_new (NULL);
|
||||
gtk_text_buffer_create_tag (text,
|
||||
|
@@ -4,7 +4,7 @@
|
||||
<property name="name">default</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="default_cursor_image">
|
||||
<property name="texture">resource:///cursors/default_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/default_cursor.png</property>
|
||||
<property name="hotspot-x">5</property>
|
||||
<property name="hotspot-y">5</property>
|
||||
</object>
|
||||
@@ -13,7 +13,7 @@
|
||||
<property name="fallback">default_cursor_image</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="default_cursor_image_fallback">
|
||||
<property name="texture">resource:///cursors/default_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/default_cursor.png</property>
|
||||
<property name="hotspot-x">5</property>
|
||||
<property name="hotspot-y">5</property>
|
||||
<property name="fallback">default_cursor</property>
|
||||
@@ -22,21 +22,21 @@
|
||||
<property name="name">none</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="none_cursor_image">
|
||||
<property name="texture">resource:///cursors/none_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/none_cursor.png</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="none_cursor_fallback">
|
||||
<property name="name">none</property>
|
||||
<property name="fallback">none_cursor_image</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="none_cursor_image_fallback">
|
||||
<property name="texture">resource:///cursors/none_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/none_cursor.png</property>
|
||||
<property name="fallback">none_cursor</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="gtk-logo_cursor">
|
||||
<property name="name">gtk-logo</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="gtk-logo_cursor_image">
|
||||
<property name="texture">resource:///cursors/gtk_logo_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/gtk_logo_cursor.png</property>
|
||||
<property name="hotspot-x">18</property>
|
||||
<property name="hotspot-y">2</property>
|
||||
</object>
|
||||
@@ -45,7 +45,7 @@
|
||||
<property name="fallback">gtk-logo_cursor_image</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="gtk-logo_cursor_image_fallback">
|
||||
<property name="texture">resource:///cursors/gtk_logo_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/gtk_logo_cursor.png</property>
|
||||
<property name="hotspot-x">18</property>
|
||||
<property name="hotspot-y">2</property>
|
||||
<property name="fallback">gtk-logo_cursor</property>
|
||||
@@ -54,7 +54,7 @@
|
||||
<property name="name">context-menu</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="context-menu_cursor_image">
|
||||
<property name="texture">resource:///cursors/context_menu_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/context_menu_cursor.png</property>
|
||||
<property name="hotspot-x">5</property>
|
||||
<property name="hotspot-y">5</property>
|
||||
</object>
|
||||
@@ -63,7 +63,7 @@
|
||||
<property name="fallback">context-menu_cursor_image</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="context-menu_cursor_image_fallback">
|
||||
<property name="texture">resource:///cursors/context_menu_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/context_menu_cursor.png</property>
|
||||
<property name="hotspot-x">5</property>
|
||||
<property name="hotspot-y">5</property>
|
||||
<property name="fallback">context-menu_cursor</property>
|
||||
@@ -72,7 +72,7 @@
|
||||
<property name="name">help</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="help_cursor_image">
|
||||
<property name="texture">resource:///cursors/help_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/help_cursor.png</property>
|
||||
<property name="hotspot-x">16</property>
|
||||
<property name="hotspot-y">27</property>
|
||||
</object>
|
||||
@@ -81,7 +81,7 @@
|
||||
<property name="fallback">help_cursor_image</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="help_cursor_image_fallback">
|
||||
<property name="texture">resource:///cursors/help_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/help_cursor.png</property>
|
||||
<property name="hotspot-x">16</property>
|
||||
<property name="hotspot-y">27</property>
|
||||
<property name="fallback">help_cursor</property>
|
||||
@@ -90,7 +90,7 @@
|
||||
<property name="name">pointer</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="pointer_cursor_image">
|
||||
<property name="texture">resource:///cursors/pointer_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/pointer_cursor.png</property>
|
||||
<property name="hotspot-x">14</property>
|
||||
<property name="hotspot-y">9</property>
|
||||
</object>
|
||||
@@ -99,7 +99,7 @@
|
||||
<property name="fallback">pointer_cursor_image</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="pointer_cursor_image_fallback">
|
||||
<property name="texture">resource:///cursors/pointer_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/pointer_cursor.png</property>
|
||||
<property name="hotspot-x">14</property>
|
||||
<property name="hotspot-y">9</property>
|
||||
<property name="fallback">pointer_cursor</property>
|
||||
@@ -108,7 +108,7 @@
|
||||
<property name="name">progress</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="progress_cursor_image">
|
||||
<property name="texture">resource:///cursors/progress_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/progress_cursor.png</property>
|
||||
<property name="hotspot-x">5</property>
|
||||
<property name="hotspot-y">4</property>
|
||||
</object>
|
||||
@@ -117,7 +117,7 @@
|
||||
<property name="fallback">progress_cursor_image</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="progress_cursor_image_fallback">
|
||||
<property name="texture">resource:///cursors/progress_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/progress_cursor.png</property>
|
||||
<property name="hotspot-x">5</property>
|
||||
<property name="hotspot-y">4</property>
|
||||
<property name="fallback">progress_cursor</property>
|
||||
@@ -126,7 +126,7 @@
|
||||
<property name="name">wait</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="wait_cursor_image">
|
||||
<property name="texture">resource:///cursors/wait_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/wait_cursor.png</property>
|
||||
<property name="hotspot-x">11</property>
|
||||
<property name="hotspot-y">11</property>
|
||||
</object>
|
||||
@@ -135,7 +135,7 @@
|
||||
<property name="fallback">wait_cursor_image</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="wait_cursor_image_fallback">
|
||||
<property name="texture">resource:///cursors/wait_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/wait_cursor.png</property>
|
||||
<property name="hotspot-x">11</property>
|
||||
<property name="hotspot-y">11</property>
|
||||
<property name="fallback">wait_cursor</property>
|
||||
@@ -144,7 +144,7 @@
|
||||
<property name="name">cell</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="cell_cursor_image">
|
||||
<property name="texture">resource:///cursors/cell_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/cell_cursor.png</property>
|
||||
<property name="hotspot-x">15</property>
|
||||
<property name="hotspot-y">15</property>
|
||||
</object>
|
||||
@@ -153,7 +153,7 @@
|
||||
<property name="fallback">cell_cursor_image</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="cell_cursor_image_fallback">
|
||||
<property name="texture">resource:///cursors/cell_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/cell_cursor.png</property>
|
||||
<property name="hotspot-x">15</property>
|
||||
<property name="hotspot-y">15</property>
|
||||
<property name="fallback">cell_cursor</property>
|
||||
@@ -162,7 +162,7 @@
|
||||
<property name="name">crosshair</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="crosshair_cursor_image">
|
||||
<property name="texture">resource:///cursors/crosshair_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/crosshair_cursor.png</property>
|
||||
<property name="hotspot-x">15</property>
|
||||
<property name="hotspot-y">15</property>
|
||||
</object>
|
||||
@@ -171,7 +171,7 @@
|
||||
<property name="fallback">crosshair_cursor_image</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="crosshair_cursor_image_fallback">
|
||||
<property name="texture">resource:///cursors/crosshair_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/crosshair_cursor.png</property>
|
||||
<property name="hotspot-x">15</property>
|
||||
<property name="hotspot-y">15</property>
|
||||
<property name="fallback">crosshair_cursor</property>
|
||||
@@ -180,7 +180,7 @@
|
||||
<property name="name">text</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="text_cursor_image">
|
||||
<property name="texture">resource:///cursors/text_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/text_cursor.png</property>
|
||||
<property name="hotspot-x">14</property>
|
||||
<property name="hotspot-y">15</property>
|
||||
</object>
|
||||
@@ -189,7 +189,7 @@
|
||||
<property name="fallback">text_cursor_image</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="text_cursor_image_fallback">
|
||||
<property name="texture">resource:///cursors/text_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/text_cursor.png</property>
|
||||
<property name="hotspot-x">14</property>
|
||||
<property name="hotspot-y">15</property>
|
||||
<property name="fallback">text_cursor</property>
|
||||
@@ -198,7 +198,7 @@
|
||||
<property name="name">vertical-text</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="vertical-text_cursor_image">
|
||||
<property name="texture">resource:///cursors/vertical_text_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/vertical_text_cursor.png</property>
|
||||
<property name="hotspot-x">16</property>
|
||||
<property name="hotspot-y">15</property>
|
||||
</object>
|
||||
@@ -207,7 +207,7 @@
|
||||
<property name="fallback">vertical-text_cursor_image</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="vertical-text_cursor_image_fallback">
|
||||
<property name="texture">resource:///cursors/vertical_text_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/vertical_text_cursor.png</property>
|
||||
<property name="hotspot-x">16</property>
|
||||
<property name="hotspot-y">15</property>
|
||||
<property name="fallback">vertical-text_cursor</property>
|
||||
@@ -216,7 +216,7 @@
|
||||
<property name="name">alias</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="alias_cursor_image">
|
||||
<property name="texture">resource:///cursors/alias_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/alias_cursor.png</property>
|
||||
<property name="hotspot-x">12</property>
|
||||
<property name="hotspot-y">11</property>
|
||||
</object>
|
||||
@@ -225,7 +225,7 @@
|
||||
<property name="fallback">alias_cursor_image</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="alias_cursor_image_fallback">
|
||||
<property name="texture">resource:///cursors/alias_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/alias_cursor.png</property>
|
||||
<property name="hotspot-x">12</property>
|
||||
<property name="hotspot-y">11</property>
|
||||
<property name="fallback">alias_cursor</property>
|
||||
@@ -234,7 +234,7 @@
|
||||
<property name="name">copy</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="copy_cursor_image">
|
||||
<property name="texture">resource:///cursors/copy_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/copy_cursor.png</property>
|
||||
<property name="hotspot-x">12</property>
|
||||
<property name="hotspot-y">11</property>
|
||||
</object>
|
||||
@@ -243,7 +243,7 @@
|
||||
<property name="fallback">copy_cursor_image</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="copy_cursor_image_fallback">
|
||||
<property name="texture">resource:///cursors/copy_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/copy_cursor.png</property>
|
||||
<property name="hotspot-x">12</property>
|
||||
<property name="hotspot-y">11</property>
|
||||
<property name="fallback">copy_cursor</property>
|
||||
@@ -252,7 +252,7 @@
|
||||
<property name="name">move</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="move_cursor_image">
|
||||
<property name="texture">resource:///cursors/move_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/move_cursor.png</property>
|
||||
<property name="hotspot-x">12</property>
|
||||
<property name="hotspot-y">11</property>
|
||||
</object>
|
||||
@@ -261,7 +261,7 @@
|
||||
<property name="fallback">move_cursor_image</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="move_cursor_image_fallback">
|
||||
<property name="texture">resource:///cursors/move_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/move_cursor.png</property>
|
||||
<property name="hotspot-x">12</property>
|
||||
<property name="hotspot-y">11</property>
|
||||
<property name="fallback">move_cursor</property>
|
||||
@@ -270,7 +270,7 @@
|
||||
<property name="name">no-drop</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="no-drop_cursor_image">
|
||||
<property name="texture">resource:///cursors/no_drop_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/no_drop_cursor.png</property>
|
||||
<property name="hotspot-x">12</property>
|
||||
<property name="hotspot-y">11</property>
|
||||
</object>
|
||||
@@ -279,7 +279,7 @@
|
||||
<property name="fallback">no-drop_cursor_image</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="no-drop_cursor_image_fallback">
|
||||
<property name="texture">resource:///cursors/no_drop_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/no_drop_cursor.png</property>
|
||||
<property name="hotspot-x">12</property>
|
||||
<property name="hotspot-y">11</property>
|
||||
<property name="fallback">no-drop_cursor</property>
|
||||
@@ -288,7 +288,7 @@
|
||||
<property name="name">not-allowed</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="not-allowed_cursor_image">
|
||||
<property name="texture">resource:///cursors/not_allowed_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/not_allowed_cursor.png</property>
|
||||
<property name="hotspot-x">12</property>
|
||||
<property name="hotspot-y">11</property>
|
||||
</object>
|
||||
@@ -297,7 +297,7 @@
|
||||
<property name="fallback">not-allowed_cursor_image</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="not-allowed_cursor_image_fallback">
|
||||
<property name="texture">resource:///cursors/not_allowed_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/not_allowed_cursor.png</property>
|
||||
<property name="hotspot-x">12</property>
|
||||
<property name="hotspot-y">11</property>
|
||||
<property name="fallback">not-allowed_cursor</property>
|
||||
@@ -306,7 +306,7 @@
|
||||
<property name="name">grab</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="grab_cursor_image">
|
||||
<property name="texture">resource:///cursors/grab_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/grab_cursor.png</property>
|
||||
<property name="hotspot-x">10</property>
|
||||
<property name="hotspot-y">6</property>
|
||||
</object>
|
||||
@@ -315,7 +315,7 @@
|
||||
<property name="fallback">grab_cursor_image</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="grab_cursor_image_fallback">
|
||||
<property name="texture">resource:///cursors/grab_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/grab_cursor.png</property>
|
||||
<property name="hotspot-x">10</property>
|
||||
<property name="hotspot-y">6</property>
|
||||
<property name="fallback">grab_cursor</property>
|
||||
@@ -324,7 +324,7 @@
|
||||
<property name="name">grabbing</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="grabbing_cursor_image">
|
||||
<property name="texture">resource:///cursors/grabbing_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/grabbing_cursor.png</property>
|
||||
<property name="hotspot-x">15</property>
|
||||
<property name="hotspot-y">14</property>
|
||||
</object>
|
||||
@@ -333,7 +333,7 @@
|
||||
<property name="fallback">grabbing_cursor_image</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="grabbing_cursor_image_fallback">
|
||||
<property name="texture">resource:///cursors/grabbing_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/grabbing_cursor.png</property>
|
||||
<property name="hotspot-x">15</property>
|
||||
<property name="hotspot-y">14</property>
|
||||
<property name="fallback">grabbing_cursor</property>
|
||||
@@ -342,7 +342,7 @@
|
||||
<property name="name">all-scroll</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="all-scroll_cursor_image">
|
||||
<property name="texture">resource:///cursors/all_scroll_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/all_scroll_cursor.png</property>
|
||||
<property name="hotspot-x">15</property>
|
||||
<property name="hotspot-y">15</property>
|
||||
</object>
|
||||
@@ -351,7 +351,7 @@
|
||||
<property name="fallback">all-scroll_cursor_image</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="all-scroll_cursor_image_fallback">
|
||||
<property name="texture">resource:///cursors/all_scroll_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/all_scroll_cursor.png</property>
|
||||
<property name="hotspot-x">15</property>
|
||||
<property name="hotspot-y">15</property>
|
||||
<property name="fallback">all-scroll_cursor</property>
|
||||
@@ -360,7 +360,7 @@
|
||||
<property name="name">col-resize</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="col-resize_cursor_image">
|
||||
<property name="texture">resource:///cursors/col_resize_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/col_resize_cursor.png</property>
|
||||
<property name="hotspot-x">16</property>
|
||||
<property name="hotspot-y">15</property>
|
||||
</object>
|
||||
@@ -369,7 +369,7 @@
|
||||
<property name="fallback">col-resize_cursor_image</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="col-resize_cursor_image_fallback">
|
||||
<property name="texture">resource:///cursors/col_resize_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/col_resize_cursor.png</property>
|
||||
<property name="hotspot-x">16</property>
|
||||
<property name="hotspot-y">15</property>
|
||||
<property name="fallback">col-resize_cursor</property>
|
||||
@@ -378,7 +378,7 @@
|
||||
<property name="name">row-resize</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="row-resize_cursor_image">
|
||||
<property name="texture">resource:///cursors/row_resize_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/row_resize_cursor.png</property>
|
||||
<property name="hotspot-x">15</property>
|
||||
<property name="hotspot-y">17</property>
|
||||
</object>
|
||||
@@ -387,7 +387,7 @@
|
||||
<property name="fallback">row-resize_cursor_image</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="row-resize_cursor_image_fallback">
|
||||
<property name="texture">resource:///cursors/row_resize_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/row_resize_cursor.png</property>
|
||||
<property name="hotspot-x">15</property>
|
||||
<property name="hotspot-y">17</property>
|
||||
<property name="fallback">row-resize_cursor</property>
|
||||
@@ -396,7 +396,7 @@
|
||||
<property name="name">n-resize</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="n-resize_cursor_image">
|
||||
<property name="texture">resource:///cursors/n_resize_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/n_resize_cursor.png</property>
|
||||
<property name="hotspot-x">17</property>
|
||||
<property name="hotspot-y">7</property>
|
||||
</object>
|
||||
@@ -405,7 +405,7 @@
|
||||
<property name="fallback">n-resize_cursor_image</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="n-resize_cursor_image_fallback">
|
||||
<property name="texture">resource:///cursors/n_resize_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/n_resize_cursor.png</property>
|
||||
<property name="hotspot-x">17</property>
|
||||
<property name="hotspot-y">7</property>
|
||||
<property name="fallback">n-resize_cursor</property>
|
||||
@@ -414,7 +414,7 @@
|
||||
<property name="name">e-resize</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="e-resize_cursor_image">
|
||||
<property name="texture">resource:///cursors/e_resize_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/e_resize_cursor.png</property>
|
||||
<property name="hotspot-x">25</property>
|
||||
<property name="hotspot-y">17</property>
|
||||
</object>
|
||||
@@ -423,7 +423,7 @@
|
||||
<property name="fallback">e-resize_cursor_image</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="e-resize_cursor_image_fallback">
|
||||
<property name="texture">resource:///cursors/e_resize_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/e_resize_cursor.png</property>
|
||||
<property name="hotspot-x">25</property>
|
||||
<property name="hotspot-y">17</property>
|
||||
<property name="fallback">e-resize_cursor</property>
|
||||
@@ -432,7 +432,7 @@
|
||||
<property name="name">s-resize</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="s-resize_cursor_image">
|
||||
<property name="texture">resource:///cursors/s_resize_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/s_resize_cursor.png</property>
|
||||
<property name="hotspot-x">17</property>
|
||||
<property name="hotspot-y">23</property>
|
||||
</object>
|
||||
@@ -441,7 +441,7 @@
|
||||
<property name="fallback">s-resize_cursor_image</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="s-resize_cursor_image_fallback">
|
||||
<property name="texture">resource:///cursors/s_resize_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/s_resize_cursor.png</property>
|
||||
<property name="hotspot-x">17</property>
|
||||
<property name="hotspot-y">23</property>
|
||||
<property name="fallback">s-resize_cursor</property>
|
||||
@@ -450,7 +450,7 @@
|
||||
<property name="name">w-resize</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="w-resize_cursor_image">
|
||||
<property name="texture">resource:///cursors/w_resize_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/w_resize_cursor.png</property>
|
||||
<property name="hotspot-x">8</property>
|
||||
<property name="hotspot-y">17</property>
|
||||
</object>
|
||||
@@ -459,7 +459,7 @@
|
||||
<property name="fallback">w-resize_cursor_image</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="w-resize_cursor_image_fallback">
|
||||
<property name="texture">resource:///cursors/w_resize_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/w_resize_cursor.png</property>
|
||||
<property name="hotspot-x">8</property>
|
||||
<property name="hotspot-y">17</property>
|
||||
<property name="fallback">w-resize_cursor</property>
|
||||
@@ -468,7 +468,7 @@
|
||||
<property name="name">ne-resize</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="ne-resize_cursor_image">
|
||||
<property name="texture">resource:///cursors/ne_resize_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/ne_resize_cursor.png</property>
|
||||
<property name="hotspot-x">20</property>
|
||||
<property name="hotspot-y">13</property>
|
||||
</object>
|
||||
@@ -477,7 +477,7 @@
|
||||
<property name="fallback">ne-resize_cursor_image</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="ne-resize_cursor_image_fallback">
|
||||
<property name="texture">resource:///cursors/ne_resize_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/ne_resize_cursor.png</property>
|
||||
<property name="hotspot-x">20</property>
|
||||
<property name="hotspot-y">13</property>
|
||||
<property name="fallback">ne-resize_cursor</property>
|
||||
@@ -486,7 +486,7 @@
|
||||
<property name="name">nw-resize</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="nw-resize_cursor_image">
|
||||
<property name="texture">resource:///cursors/nw_resize_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/nw_resize_cursor.png</property>
|
||||
<property name="hotspot-x">13</property>
|
||||
<property name="hotspot-y">13</property>
|
||||
</object>
|
||||
@@ -495,7 +495,7 @@
|
||||
<property name="fallback">nw-resize_cursor_image</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="nw-resize_cursor_image_fallback">
|
||||
<property name="texture">resource:///cursors/nw_resize_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/nw_resize_cursor.png</property>
|
||||
<property name="hotspot-x">13</property>
|
||||
<property name="hotspot-y">13</property>
|
||||
<property name="fallback">nw-resize_cursor</property>
|
||||
@@ -504,7 +504,7 @@
|
||||
<property name="name">se-resize</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="se-resize_cursor_image">
|
||||
<property name="texture">resource:///cursors/se_resize_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/se_resize_cursor.png</property>
|
||||
<property name="hotspot-x">19</property>
|
||||
<property name="hotspot-y">19</property>
|
||||
</object>
|
||||
@@ -513,7 +513,7 @@
|
||||
<property name="fallback">se-resize_cursor_image</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="se-resize_cursor_image_fallback">
|
||||
<property name="texture">resource:///cursors/se_resize_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/se_resize_cursor.png</property>
|
||||
<property name="hotspot-x">19</property>
|
||||
<property name="hotspot-y">19</property>
|
||||
<property name="fallback">se-resize_cursor</property>
|
||||
@@ -522,7 +522,7 @@
|
||||
<property name="name">sw-resize</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="sw-resize_cursor_image">
|
||||
<property name="texture">resource:///cursors/sw_resize_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/sw_resize_cursor.png</property>
|
||||
<property name="hotspot-x">13</property>
|
||||
<property name="hotspot-y">19</property>
|
||||
</object>
|
||||
@@ -531,7 +531,7 @@
|
||||
<property name="fallback">sw-resize_cursor_image</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="sw-resize_cursor_image_fallback">
|
||||
<property name="texture">resource:///cursors/sw_resize_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/sw_resize_cursor.png</property>
|
||||
<property name="hotspot-x">13</property>
|
||||
<property name="hotspot-y">19</property>
|
||||
<property name="fallback">sw-resize_cursor</property>
|
||||
@@ -540,7 +540,7 @@
|
||||
<property name="name">ew-resize</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="ew-resize_cursor_image">
|
||||
<property name="texture">resource:///cursors/ew_resize_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/ew_resize_cursor.png</property>
|
||||
<property name="hotspot-x">16</property>
|
||||
<property name="hotspot-y">15</property>
|
||||
</object>
|
||||
@@ -549,7 +549,7 @@
|
||||
<property name="fallback">ew-resize_cursor_image</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="ew-resize_cursor_image_fallback">
|
||||
<property name="texture">resource:///cursors/ew_resize_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/ew_resize_cursor.png</property>
|
||||
<property name="hotspot-x">16</property>
|
||||
<property name="hotspot-y">15</property>
|
||||
<property name="fallback">ew-resize_cursor</property>
|
||||
@@ -558,7 +558,7 @@
|
||||
<property name="name">ns-resize</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="ns-resize_cursor_image">
|
||||
<property name="texture">resource:///cursors/ns_resize_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/ns_resize_cursor.png</property>
|
||||
<property name="hotspot-x">15</property>
|
||||
<property name="hotspot-y">17</property>
|
||||
</object>
|
||||
@@ -567,7 +567,7 @@
|
||||
<property name="fallback">ns-resize_cursor_image</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="ns-resize_cursor_image_fallback">
|
||||
<property name="texture">resource:///cursors/ns_resize_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/ns_resize_cursor.png</property>
|
||||
<property name="hotspot-x">15</property>
|
||||
<property name="hotspot-y">17</property>
|
||||
<property name="fallback">ns-resize_cursor</property>
|
||||
@@ -576,7 +576,7 @@
|
||||
<property name="name">nesw-resize</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="nesw-resize_cursor_image">
|
||||
<property name="texture">resource:///cursors/nesw_resize_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/nesw_resize_cursor.png</property>
|
||||
<property name="hotspot-x">14</property>
|
||||
<property name="hotspot-y">14</property>
|
||||
</object>
|
||||
@@ -585,7 +585,7 @@
|
||||
<property name="fallback">nesw-resize_cursor_image</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="nesw-resize_cursor_image_fallback">
|
||||
<property name="texture">resource:///cursors/nesw_resize_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/nesw_resize_cursor.png</property>
|
||||
<property name="hotspot-x">14</property>
|
||||
<property name="hotspot-y">14</property>
|
||||
<property name="fallback">nesw-resize_cursor</property>
|
||||
@@ -594,7 +594,7 @@
|
||||
<property name="name">nwse-resize</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="nwse-resize_cursor_image">
|
||||
<property name="texture">resource:///cursors/nwse_resize_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/nwse_resize_cursor.png</property>
|
||||
<property name="hotspot-x">14</property>
|
||||
<property name="hotspot-y">14</property>
|
||||
</object>
|
||||
@@ -603,7 +603,7 @@
|
||||
<property name="fallback">nwse-resize_cursor_image</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="nwse-resize_cursor_image_fallback">
|
||||
<property name="texture">resource:///cursors/nwse_resize_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/nwse_resize_cursor.png</property>
|
||||
<property name="hotspot-x">14</property>
|
||||
<property name="hotspot-y">14</property>
|
||||
<property name="fallback">nwse-resize_cursor</property>
|
||||
@@ -612,7 +612,7 @@
|
||||
<property name="name">zoom-in</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="zoom-in_cursor_image">
|
||||
<property name="texture">resource:///cursors/zoom_in_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/zoom_in_cursor.png</property>
|
||||
<property name="hotspot-x">14</property>
|
||||
<property name="hotspot-y">13</property>
|
||||
</object>
|
||||
@@ -621,7 +621,7 @@
|
||||
<property name="fallback">zoom-in_cursor_image</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="zoom-in_cursor_image_fallback">
|
||||
<property name="texture">resource:///cursors/zoom_in_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/zoom_in_cursor.png</property>
|
||||
<property name="hotspot-x">14</property>
|
||||
<property name="hotspot-y">13</property>
|
||||
<property name="fallback">zoom-in_cursor</property>
|
||||
@@ -630,7 +630,7 @@
|
||||
<property name="name">zoom-out</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="zoom-out_cursor_image">
|
||||
<property name="texture">resource:///cursors/zoom_out_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/zoom_out_cursor.png</property>
|
||||
<property name="hotspot-x">14</property>
|
||||
<property name="hotspot-y">13</property>
|
||||
</object>
|
||||
@@ -639,7 +639,7 @@
|
||||
<property name="fallback">zoom-out_cursor_image</property>
|
||||
</object>
|
||||
<object class="GdkCursor" id="zoom-out_cursor_image_fallback">
|
||||
<property name="texture">resource:///cursors/zoom_out_cursor.png</property>
|
||||
<property name="texture">resource:///cursors/images/zoom_out_cursor.png</property>
|
||||
<property name="hotspot-x">14</property>
|
||||
<property name="hotspot-y">13</property>
|
||||
<property name="fallback">zoom-out_cursor</property>
|
||||
@@ -682,7 +682,7 @@
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="paintable">resource:///cursors/default_cursor.png</property>
|
||||
<property name="paintable">resource:///cursors/images/default_cursor.png</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -742,7 +742,7 @@
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="paintable">resource:///cursors/none_cursor.png</property>
|
||||
<property name="paintable">resource:///cursors/images/none_cursor.png</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -802,7 +802,7 @@
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="paintable">resource:///cursors/gtk_logo_cursor.png</property>
|
||||
<property name="paintable">resource:///cursors/images/gtk_logo_cursor.png</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -875,7 +875,7 @@
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="paintable">resource:///cursors/context_menu_cursor.png</property>
|
||||
<property name="paintable">resource:///cursors/images/context_menu_cursor.png</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -935,7 +935,7 @@
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="paintable">resource:///cursors/help_cursor.png</property>
|
||||
<property name="paintable">resource:///cursors/images/help_cursor.png</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -995,7 +995,7 @@
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="paintable">resource:///cursors/pointer_cursor.png</property>
|
||||
<property name="paintable">resource:///cursors/images/pointer_cursor.png</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -1055,7 +1055,7 @@
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="paintable">resource:///cursors/progress_cursor.png</property>
|
||||
<property name="paintable">resource:///cursors/images/progress_cursor.png</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -1115,7 +1115,7 @@
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="paintable">resource:///cursors/wait_cursor.png</property>
|
||||
<property name="paintable">resource:///cursors/images/wait_cursor.png</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -1188,7 +1188,7 @@
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="paintable">resource:///cursors/cell_cursor.png</property>
|
||||
<property name="paintable">resource:///cursors/images/cell_cursor.png</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -1248,7 +1248,7 @@
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="paintable">resource:///cursors/crosshair_cursor.png</property>
|
||||
<property name="paintable">resource:///cursors/images/crosshair_cursor.png</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -1308,7 +1308,7 @@
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="paintable">resource:///cursors/text_cursor.png</property>
|
||||
<property name="paintable">resource:///cursors/images/text_cursor.png</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -1368,7 +1368,7 @@
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="paintable">resource:///cursors/vertical_text_cursor.png</property>
|
||||
<property name="paintable">resource:///cursors/images/vertical_text_cursor.png</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -1441,7 +1441,7 @@
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="paintable">resource:///cursors/alias_cursor.png</property>
|
||||
<property name="paintable">resource:///cursors/images/alias_cursor.png</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -1501,7 +1501,7 @@
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="paintable">resource:///cursors/copy_cursor.png</property>
|
||||
<property name="paintable">resource:///cursors/images/copy_cursor.png</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -1561,7 +1561,7 @@
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="paintable">resource:///cursors/move_cursor.png</property>
|
||||
<property name="paintable">resource:///cursors/images/move_cursor.png</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -1621,7 +1621,7 @@
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="paintable">resource:///cursors/no_drop_cursor.png</property>
|
||||
<property name="paintable">resource:///cursors/images/no_drop_cursor.png</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -1681,7 +1681,7 @@
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="paintable">resource:///cursors/not_allowed_cursor.png</property>
|
||||
<property name="paintable">resource:///cursors/images/not_allowed_cursor.png</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -1741,7 +1741,7 @@
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="paintable">resource:///cursors/grab_cursor.png</property>
|
||||
<property name="paintable">resource:///cursors/images/grab_cursor.png</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -1801,7 +1801,7 @@
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="paintable">resource:///cursors/grabbing_cursor.png</property>
|
||||
<property name="paintable">resource:///cursors/images/grabbing_cursor.png</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -1874,7 +1874,7 @@
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="paintable">resource:///cursors/all_scroll_cursor.png</property>
|
||||
<property name="paintable">resource:///cursors/images/all_scroll_cursor.png</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -1934,7 +1934,7 @@
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="paintable">resource:///cursors/col_resize_cursor.png</property>
|
||||
<property name="paintable">resource:///cursors/images/col_resize_cursor.png</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -1994,7 +1994,7 @@
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="paintable">resource:///cursors/row_resize_cursor.png</property>
|
||||
<property name="paintable">resource:///cursors/images/row_resize_cursor.png</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -2054,7 +2054,7 @@
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="paintable">resource:///cursors/n_resize_cursor.png</property>
|
||||
<property name="paintable">resource:///cursors/images/n_resize_cursor.png</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -2114,7 +2114,7 @@
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="paintable">resource:///cursors/e_resize_cursor.png</property>
|
||||
<property name="paintable">resource:///cursors/images/e_resize_cursor.png</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -2174,7 +2174,7 @@
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="paintable">resource:///cursors/s_resize_cursor.png</property>
|
||||
<property name="paintable">resource:///cursors/images/s_resize_cursor.png</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -2234,7 +2234,7 @@
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="paintable">resource:///cursors/w_resize_cursor.png</property>
|
||||
<property name="paintable">resource:///cursors/images/w_resize_cursor.png</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -2294,7 +2294,7 @@
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="paintable">resource:///cursors/ne_resize_cursor.png</property>
|
||||
<property name="paintable">resource:///cursors/images/ne_resize_cursor.png</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -2354,7 +2354,7 @@
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="paintable">resource:///cursors/nw_resize_cursor.png</property>
|
||||
<property name="paintable">resource:///cursors/images/nw_resize_cursor.png</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -2414,7 +2414,7 @@
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="paintable">resource:///cursors/sw_resize_cursor.png</property>
|
||||
<property name="paintable">resource:///cursors/images/sw_resize_cursor.png</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -2474,7 +2474,7 @@
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="paintable">resource:///cursors/se_resize_cursor.png</property>
|
||||
<property name="paintable">resource:///cursors/images/se_resize_cursor.png</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -2534,7 +2534,7 @@
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="paintable">resource:///cursors/ew_resize_cursor.png</property>
|
||||
<property name="paintable">resource:///cursors/images/ew_resize_cursor.png</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -2594,7 +2594,7 @@
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="paintable">resource:///cursors/ns_resize_cursor.png</property>
|
||||
<property name="paintable">resource:///cursors/images/ns_resize_cursor.png</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -2654,7 +2654,7 @@
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="paintable">resource:///cursors/nesw_resize_cursor.png</property>
|
||||
<property name="paintable">resource:///cursors/images/nesw_resize_cursor.png</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -2714,7 +2714,7 @@
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="paintable">resource:///cursors/nwse_resize_cursor.png</property>
|
||||
<property name="paintable">resource:///cursors/images/nwse_resize_cursor.png</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -2787,7 +2787,7 @@
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="paintable">resource:///cursors/zoom_in_cursor.png</property>
|
||||
<property name="paintable">resource:///cursors/images/zoom_in_cursor.png</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -2847,7 +2847,7 @@
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="paintable">resource:///cursors/zoom_out_cursor.png</property>
|
||||
<property name="paintable">resource:///cursors/images/zoom_out_cursor.png</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
|
@@ -51,6 +51,8 @@
|
||||
<file>cssview.css</file>
|
||||
<file>reset.css</file>
|
||||
<file>background.jpg</file>
|
||||
</gresource>
|
||||
<gresource prefix="/css_pixbufs/images">
|
||||
<file>apple-red.png</file>
|
||||
<file>gnome-applets.png</file>
|
||||
<file>gnome-calendar.png</file>
|
||||
@@ -67,6 +69,8 @@
|
||||
</gresource>
|
||||
<gresource prefix="/cursors">
|
||||
<file>cursors.ui</file>
|
||||
</gresource>
|
||||
<gresource prefix="/cursors/images">
|
||||
<file>alias_cursor.png</file>
|
||||
<file>all_scroll_cursor.png</file>
|
||||
<file>cell_cursor.png</file>
|
||||
@@ -117,6 +121,15 @@
|
||||
<file>gtkgears.c</file>
|
||||
<file>gtkgears.h</file>
|
||||
</gresource>
|
||||
<gresource prefix="/shadertoy">
|
||||
<file>gtkshadertoy.c</file>
|
||||
<file>gtkshadertoy.h</file>
|
||||
<file>alienplanet.glsl</file>
|
||||
<file>mandelbrot.glsl</file>
|
||||
<file>neon.glsl</file>
|
||||
<file>cogs.glsl</file>
|
||||
<file>glowingstars.glsl</file>
|
||||
</gresource>
|
||||
<gresource prefix="/iconscroll">
|
||||
<file>iconscroll.ui</file>
|
||||
</gresource>
|
||||
@@ -124,6 +137,24 @@
|
||||
<file>gnome-fs-directory.png</file>
|
||||
<file>gnome-fs-regular.png</file>
|
||||
</gresource>
|
||||
<gresource prefix="/layoutmanager">
|
||||
<file>demolayout.h</file>
|
||||
<file>demolayout.c</file>
|
||||
<file>demowidget.h</file>
|
||||
<file>demowidget.c</file>
|
||||
<file>demochild.h</file>
|
||||
<file>demochild.c</file>
|
||||
</gresource>
|
||||
<gresource prefix="/layoutmanager2">
|
||||
<file>demo2layout.h</file>
|
||||
<file>demo2layout.c</file>
|
||||
<file>demo2widget.h</file>
|
||||
<file>demo2widget.c</file>
|
||||
<file>four_point_transform.h</file>
|
||||
<file>four_point_transform.c</file>
|
||||
<file>singular_value_decomposition.h</file>
|
||||
<file>singular_value_decomposition.c</file>
|
||||
</gresource>
|
||||
<gresource prefix="/listview_filebrowser">
|
||||
<file>listview_filebrowser.ui</file>
|
||||
<file>listview_filebrowser.css</file>
|
||||
@@ -165,17 +196,6 @@
|
||||
<file>floppybuddy.gif</file>
|
||||
<file>gtk-logo.webm</file>
|
||||
</gresource>
|
||||
<gresource prefix="/pixbufs">
|
||||
<file>apple-red.png</file>
|
||||
<file>background.jpg</file>
|
||||
<file>gnome-applets.png</file>
|
||||
<file>gnome-calendar.png</file>
|
||||
<file>gnome-foot.png</file>
|
||||
<file>gnome-gmush.png</file>
|
||||
<file>gnome-gimp.png</file>
|
||||
<file>gnome-gsame.png</file>
|
||||
<file>gnu-keys.png</file>
|
||||
</gresource>
|
||||
<gresource prefix="/sources">
|
||||
<file>application_demo.c</file>
|
||||
<file>assistant.c</file>
|
||||
@@ -217,8 +237,11 @@
|
||||
<file>iconview_edit.c</file>
|
||||
<file>images.c</file>
|
||||
<file>infobar.c</file>
|
||||
<file>layoutmanager.c</file>
|
||||
<file>layoutmanager2.c</file>
|
||||
<file>links.c</file>
|
||||
<file>listbox.c</file>
|
||||
<file>listbox2.c</file>
|
||||
<file>listview_applauncher.c</file>
|
||||
<file>listview_colors.c</file>
|
||||
<file>listview_clocks.c</file>
|
||||
@@ -229,25 +252,25 @@
|
||||
<file>listview_words.c</file>
|
||||
<file>list_store.c</file>
|
||||
<file>markup.c</file>
|
||||
<file>modelbutton.c</file>
|
||||
<file>overlay.c</file>
|
||||
<file>overlay2.c</file>
|
||||
<file>paint.c</file>
|
||||
<file>pagesetup.c</file>
|
||||
<file>paintable.c</file>
|
||||
<file>paintable_animated.c</file>
|
||||
<file>paintable_emblem.c</file>
|
||||
<file>paintable_mediastream.c</file>
|
||||
<file>panes.c</file>
|
||||
<file>password_entry.c</file>
|
||||
<file>peg_solitaire.c</file>
|
||||
<file>pickers.c</file>
|
||||
<file>pixbufs.c</file>
|
||||
<file>printing.c</file>
|
||||
<file>revealer.c</file>
|
||||
<file>rotated_text.c</file>
|
||||
<file>scale.c</file>
|
||||
<file>search_entry.c</file>
|
||||
<file>search_entry2.c</file>
|
||||
<file>shadertoy.c</file>
|
||||
<file>shortcuts.c</file>
|
||||
<file>shortcut_triggers.c</file>
|
||||
<file>sizegroup.c</file>
|
||||
@@ -279,6 +302,9 @@
|
||||
<file>messages.txt</file>
|
||||
<file>apple-red.png</file>
|
||||
</gresource>
|
||||
<gresource prefix="/listbox2">
|
||||
<file>listbox2.ui</file>
|
||||
</gresource>
|
||||
<gresource prefix="/glarea">
|
||||
<file>glarea-gl.fs.glsl</file>
|
||||
<file>glarea-gl.vs.glsl</file>
|
||||
@@ -310,9 +336,6 @@
|
||||
<gresource prefix="/scale">
|
||||
<file>scale.ui</file>
|
||||
</gresource>
|
||||
<gresource prefix="/modelbutton">
|
||||
<file>modelbutton.ui</file>
|
||||
</gresource>
|
||||
<gresource prefix="/tagged_entry">
|
||||
<file>demotaggedentry.c</file>
|
||||
<file>demotaggedentry.h</file>
|
||||
|
204
demos/gtk-demo/demo2layout.c
Normal file
204
demos/gtk-demo/demo2layout.c
Normal file
@@ -0,0 +1,204 @@
|
||||
#include "demo2layout.h"
|
||||
#include "four_point_transform.h"
|
||||
|
||||
struct _Demo2Layout
|
||||
{
|
||||
GtkLayoutManager parent_instance;
|
||||
|
||||
float position;
|
||||
float offset;
|
||||
};
|
||||
|
||||
struct _Demo2LayoutClass
|
||||
{
|
||||
GtkLayoutManagerClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (Demo2Layout, demo2_layout, GTK_TYPE_LAYOUT_MANAGER)
|
||||
|
||||
static void
|
||||
demo2_layout_measure (GtkLayoutManager *layout_manager,
|
||||
GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
int for_size,
|
||||
int *minimum,
|
||||
int *natural,
|
||||
int *minimum_baseline,
|
||||
int *natural_baseline)
|
||||
{
|
||||
GtkWidget *child;
|
||||
int minimum_size = 0;
|
||||
int natural_size = 0;
|
||||
|
||||
for (child = gtk_widget_get_first_child (widget);
|
||||
child != NULL;
|
||||
child = gtk_widget_get_next_sibling (child))
|
||||
{
|
||||
int child_min = 0, child_nat = 0;
|
||||
|
||||
if (!gtk_widget_should_layout (child))
|
||||
continue;
|
||||
|
||||
gtk_widget_measure (child, orientation, -1,
|
||||
&child_min, &child_nat,
|
||||
NULL, NULL);
|
||||
minimum_size = MAX (minimum_size, child_min);
|
||||
natural_size = MAX (natural_size, child_nat);
|
||||
}
|
||||
|
||||
*minimum = minimum_size;
|
||||
*natural = 3 * natural_size;
|
||||
}
|
||||
|
||||
|
||||
#define RADIANS(angle) ((angle)*M_PI/180.0);
|
||||
|
||||
/* Spherical coordinates */
|
||||
#define SX(r,t,p) ((r) * sin (t) * cos (p))
|
||||
#define SZ(r,t,p) ((r) * sin (t) * sin (p))
|
||||
#define SY(r,t,p) ((r) * cos (t))
|
||||
|
||||
static double
|
||||
map_offset (double x)
|
||||
{
|
||||
x = fmod (x, 180.0);
|
||||
if (x < 0.0)
|
||||
x += 180.0;
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
static void
|
||||
demo2_layout_allocate (GtkLayoutManager *layout_manager,
|
||||
GtkWidget *widget,
|
||||
int width,
|
||||
int height,
|
||||
int baseline)
|
||||
{
|
||||
GtkWidget *child;
|
||||
GtkRequisition child_req;
|
||||
int i, j, k;
|
||||
float x0, y0;
|
||||
float w, h;
|
||||
graphene_point3d_t p1, p2, p3, p4;
|
||||
graphene_point3d_t q1, q2, q3, q4;
|
||||
double t_1, t_2, p_1, p_2;
|
||||
double r;
|
||||
graphene_matrix_t m;
|
||||
GskTransform *transform;
|
||||
double position = DEMO2_LAYOUT (layout_manager)->position;
|
||||
double offset = DEMO2_LAYOUT (layout_manager)->offset;
|
||||
|
||||
/* for simplicity, assume all children are the same size */
|
||||
gtk_widget_get_preferred_size (gtk_widget_get_first_child (widget), &child_req, NULL);
|
||||
w = child_req.width;
|
||||
h = child_req.height;
|
||||
|
||||
r = 300;
|
||||
x0 = y0 = 300;
|
||||
|
||||
for (child = gtk_widget_get_first_child (widget), i = 0;
|
||||
child != NULL;
|
||||
child = gtk_widget_get_next_sibling (child), i++)
|
||||
{
|
||||
j = i / 36;
|
||||
k = i % 36;
|
||||
|
||||
gtk_widget_set_child_visible (child, FALSE);
|
||||
|
||||
graphene_point3d_init (&p1, w, h, 1.);
|
||||
graphene_point3d_init (&p2, w, 0., 1.);
|
||||
graphene_point3d_init (&p3, 0., 0., 1.);
|
||||
graphene_point3d_init (&p4, 0., h, 1.);
|
||||
|
||||
t_1 = RADIANS (map_offset (offset + 10 * j));
|
||||
t_2 = RADIANS (map_offset (offset + 10 * (j + 1)));
|
||||
p_1 = RADIANS (position + 10 * k);
|
||||
p_2 = RADIANS (position + 10 * (k + 1));
|
||||
|
||||
if (t_2 < t_1)
|
||||
continue;
|
||||
|
||||
if (SZ (r, t_1, p_1) > 0 ||
|
||||
SZ (r, t_2, p_1) > 0 ||
|
||||
SZ (r, t_1, p_2) > 0 ||
|
||||
SZ (r, t_2, p_2) > 0)
|
||||
continue;
|
||||
|
||||
gtk_widget_set_child_visible (child, TRUE);
|
||||
|
||||
graphene_point3d_init (&q1, x0 + SX (r, t_1, p_1), y0 + SY (r, t_1, p_1), SZ (r, t_1, p_1));
|
||||
graphene_point3d_init (&q2, x0 + SX (r, t_2, p_1), y0 + SY (r, t_2, p_1), SZ (r, t_2, p_1));
|
||||
graphene_point3d_init (&q3, x0 + SX (r, t_2, p_2), y0 + SY (r, t_2, p_2), SZ (r, t_2, p_2));
|
||||
graphene_point3d_init (&q4, x0 + SX (r, t_1, p_2), y0 + SY (r, t_1, p_2), SZ (r, t_1, p_2));
|
||||
|
||||
/* Get a matrix that moves p1 -> q1, p2 -> q2, ... */
|
||||
perspective_3d (&p1, &p2, &p3, &p4,
|
||||
&q1, &q2, &q3, &q4,
|
||||
&m);
|
||||
|
||||
transform = gsk_transform_matrix (NULL, &m);
|
||||
|
||||
/* Since our matrix was built for transforming points with z = 1,
|
||||
* prepend a translation to the z = 1 plane.
|
||||
*/
|
||||
transform = gsk_transform_translate_3d (transform,
|
||||
&GRAPHENE_POINT3D_INIT (0, 0, 1));
|
||||
|
||||
gtk_widget_allocate (child, w, h, -1, transform);
|
||||
}
|
||||
}
|
||||
|
||||
static GtkSizeRequestMode
|
||||
demo2_layout_get_request_mode (GtkLayoutManager *layout_manager,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
return GTK_SIZE_REQUEST_CONSTANT_SIZE;
|
||||
}
|
||||
|
||||
static void
|
||||
demo2_layout_class_init (Demo2LayoutClass *klass)
|
||||
{
|
||||
GtkLayoutManagerClass *layout_class = GTK_LAYOUT_MANAGER_CLASS (klass);
|
||||
|
||||
layout_class->get_request_mode = demo2_layout_get_request_mode;
|
||||
layout_class->measure = demo2_layout_measure;
|
||||
layout_class->allocate = demo2_layout_allocate;
|
||||
}
|
||||
|
||||
static void
|
||||
demo2_layout_init (Demo2Layout *self)
|
||||
{
|
||||
}
|
||||
|
||||
GtkLayoutManager *
|
||||
demo2_layout_new (void)
|
||||
{
|
||||
return g_object_new (DEMO2_TYPE_LAYOUT, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
demo2_layout_set_position (Demo2Layout *layout,
|
||||
float position)
|
||||
{
|
||||
layout->position = position;
|
||||
}
|
||||
|
||||
float
|
||||
demo2_layout_get_position (Demo2Layout *layout)
|
||||
{
|
||||
return layout->position;
|
||||
}
|
||||
|
||||
void
|
||||
demo2_layout_set_offset (Demo2Layout *layout,
|
||||
float offset)
|
||||
{
|
||||
layout->offset = offset;
|
||||
}
|
||||
|
||||
float
|
||||
demo2_layout_get_offset (Demo2Layout *layout)
|
||||
{
|
||||
return layout->offset;
|
||||
}
|
16
demos/gtk-demo/demo2layout.h
Normal file
16
demos/gtk-demo/demo2layout.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#define DEMO2_TYPE_LAYOUT (demo2_layout_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (Demo2Layout, demo2_layout, DEMO2, LAYOUT, GtkLayoutManager)
|
||||
|
||||
GtkLayoutManager * demo2_layout_new (void);
|
||||
|
||||
void demo2_layout_set_position (Demo2Layout *layout,
|
||||
float position);
|
||||
float demo2_layout_get_position (Demo2Layout *layout);
|
||||
void demo2_layout_set_offset (Demo2Layout *layout,
|
||||
float offset);
|
||||
float demo2_layout_get_offset (Demo2Layout *layout);
|
172
demos/gtk-demo/demo2widget.c
Normal file
172
demos/gtk-demo/demo2widget.c
Normal file
@@ -0,0 +1,172 @@
|
||||
#include "demo2widget.h"
|
||||
#include "demo2layout.h"
|
||||
|
||||
struct _Demo2Widget
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
|
||||
gint64 start_time;
|
||||
gint64 end_time;
|
||||
float start_position;
|
||||
float end_position;
|
||||
float start_offset;
|
||||
float end_offset;
|
||||
gboolean animating;
|
||||
};
|
||||
|
||||
struct _Demo2WidgetClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (Demo2Widget, demo2_widget, GTK_TYPE_WIDGET)
|
||||
|
||||
static void
|
||||
demo2_widget_init (Demo2Widget *self)
|
||||
{
|
||||
gtk_widget_set_focusable (GTK_WIDGET (self), TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
demo2_widget_dispose (GObject *object)
|
||||
{
|
||||
GtkWidget *child;
|
||||
|
||||
while ((child = gtk_widget_get_first_child (GTK_WIDGET (object))))
|
||||
gtk_widget_unparent (child);
|
||||
|
||||
G_OBJECT_CLASS (demo2_widget_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
/* From clutter-easing.c, based on Robert Penner's
|
||||
* infamous easing equations, MIT license.
|
||||
*/
|
||||
static double
|
||||
ease_out_cubic (double t)
|
||||
{
|
||||
double p = t - 1;
|
||||
|
||||
return p * p * p + 1;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
update_position (GtkWidget *widget,
|
||||
GdkFrameClock *clock,
|
||||
gpointer data)
|
||||
{
|
||||
Demo2Widget *self = DEMO2_WIDGET (widget);
|
||||
Demo2Layout *layout = DEMO2_LAYOUT (gtk_widget_get_layout_manager (widget));
|
||||
gint64 now;
|
||||
double t;
|
||||
|
||||
now = gdk_frame_clock_get_frame_time (clock);
|
||||
|
||||
if (now >= self->end_time)
|
||||
{
|
||||
self->animating = FALSE;
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
t = (now - self->start_time) / (double) (self->end_time - self->start_time);
|
||||
|
||||
t = ease_out_cubic (t);
|
||||
|
||||
demo2_layout_set_position (layout, self->start_position + t * (self->end_position - self->start_position));
|
||||
demo2_layout_set_offset (layout, self->start_offset + t * (self->end_offset - self->start_offset));
|
||||
gtk_widget_queue_allocate (widget);
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
static void
|
||||
rotate_sphere (GtkWidget *widget,
|
||||
const char *action,
|
||||
GVariant *parameters)
|
||||
{
|
||||
Demo2Widget *self = DEMO2_WIDGET (widget);
|
||||
Demo2Layout *layout = DEMO2_LAYOUT (gtk_widget_get_layout_manager (widget));
|
||||
GtkOrientation orientation;
|
||||
int direction;
|
||||
|
||||
g_variant_get (parameters, "(ii)", &orientation, &direction);
|
||||
|
||||
self->end_position = self->start_position = demo2_layout_get_position (layout);
|
||||
self->end_offset = self->start_offset = demo2_layout_get_offset (layout);
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
self->end_position += 10 * direction;
|
||||
else
|
||||
self->end_offset += 10 * direction;
|
||||
self->start_time = g_get_monotonic_time ();
|
||||
self->end_time = self->start_time + 0.5 * G_TIME_SPAN_SECOND;
|
||||
|
||||
if (!self->animating)
|
||||
{
|
||||
gtk_widget_add_tick_callback (widget, update_position, NULL, NULL);
|
||||
self->animating = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
demo2_widget_snapshot (GtkWidget *widget,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
GtkWidget *child;
|
||||
|
||||
for (child = gtk_widget_get_first_child (widget);
|
||||
child != NULL;
|
||||
child = gtk_widget_get_next_sibling (child))
|
||||
{
|
||||
/* our layout manager sets this for children that are out of view */
|
||||
if (!gtk_widget_get_child_visible (child))
|
||||
continue;
|
||||
|
||||
gtk_widget_snapshot_child (widget, child, snapshot);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
demo2_widget_class_init (Demo2WidgetClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
||||
|
||||
object_class->dispose = demo2_widget_dispose;
|
||||
|
||||
widget_class->snapshot = demo2_widget_snapshot;
|
||||
|
||||
gtk_widget_class_install_action (widget_class, "rotate", "(ii)", rotate_sphere);
|
||||
|
||||
gtk_widget_class_add_binding_action (widget_class,
|
||||
GDK_KEY_Left, 0,
|
||||
"rotate",
|
||||
"(ii)", GTK_ORIENTATION_HORIZONTAL, -1);
|
||||
gtk_widget_class_add_binding_action (widget_class,
|
||||
GDK_KEY_Right, 0,
|
||||
"rotate",
|
||||
"(ii)", GTK_ORIENTATION_HORIZONTAL, 1);
|
||||
gtk_widget_class_add_binding_action (widget_class,
|
||||
GDK_KEY_Up, 0,
|
||||
"rotate",
|
||||
"(ii)", GTK_ORIENTATION_VERTICAL, 1);
|
||||
gtk_widget_class_add_binding_action (widget_class,
|
||||
GDK_KEY_Down, 0,
|
||||
"rotate",
|
||||
"(ii)", GTK_ORIENTATION_VERTICAL, -1);
|
||||
|
||||
/* here is where we use our custom layout manager */
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, DEMO2_TYPE_LAYOUT);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
demo2_widget_new (void)
|
||||
{
|
||||
return g_object_new (DEMO2_TYPE_WIDGET, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
demo2_widget_add_child (Demo2Widget *self,
|
||||
GtkWidget *child)
|
||||
{
|
||||
gtk_widget_set_parent (child, GTK_WIDGET (self));
|
||||
}
|
11
demos/gtk-demo/demo2widget.h
Normal file
11
demos/gtk-demo/demo2widget.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#define DEMO2_TYPE_WIDGET (demo2_widget_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (Demo2Widget, demo2_widget, DEMO2, WIDGET, GtkWidget)
|
||||
|
||||
GtkWidget * demo2_widget_new (void);
|
||||
|
||||
void demo2_widget_add_child (Demo2Widget *self,
|
||||
GtkWidget *child);
|
72
demos/gtk-demo/demochild.c
Normal file
72
demos/gtk-demo/demochild.c
Normal file
@@ -0,0 +1,72 @@
|
||||
#include "demochild.h"
|
||||
|
||||
/* This is a trivial child widget just for demo purposes.
|
||||
* It draws a 32x32 square in fixed color.
|
||||
*/
|
||||
|
||||
struct _DemoChild
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
GdkRGBA color;
|
||||
};
|
||||
|
||||
struct _DemoChildClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (DemoChild, demo_child, GTK_TYPE_WIDGET)
|
||||
|
||||
static void
|
||||
demo_child_init (DemoChild *self)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
demo_child_snapshot (GtkWidget *widget,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
DemoChild *self = DEMO_CHILD (widget);
|
||||
int width, height;
|
||||
|
||||
width = gtk_widget_get_width (widget);
|
||||
height = gtk_widget_get_height (widget);
|
||||
|
||||
gtk_snapshot_append_color (snapshot, &self->color,
|
||||
&GRAPHENE_RECT_INIT(0, 0, width, height));
|
||||
}
|
||||
|
||||
static void
|
||||
demo_child_measure (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
int for_size,
|
||||
int *minimum,
|
||||
int *natural,
|
||||
int *minimum_baseline,
|
||||
int *natural_baseline)
|
||||
{
|
||||
*minimum = *natural = 32;
|
||||
}
|
||||
|
||||
static void
|
||||
demo_child_class_init (DemoChildClass *class)
|
||||
{
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
||||
|
||||
widget_class->snapshot = demo_child_snapshot;
|
||||
widget_class->measure = demo_child_measure;
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
demo_child_new (const char *color)
|
||||
{
|
||||
DemoChild *self;
|
||||
|
||||
self = g_object_new (DEMO_TYPE_CHILD,
|
||||
"tooltip-text", color,
|
||||
NULL);
|
||||
|
||||
gdk_rgba_parse (&self->color, color);
|
||||
|
||||
return GTK_WIDGET (self);
|
||||
}
|
8
demos/gtk-demo/demochild.h
Normal file
8
demos/gtk-demo/demochild.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#define DEMO_TYPE_CHILD (demo_child_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (DemoChild, demo_child, DEMO, CHILD, GtkWidget)
|
||||
|
||||
GtkWidget * demo_child_new (const char *color);
|
189
demos/gtk-demo/demolayout.c
Normal file
189
demos/gtk-demo/demolayout.c
Normal file
@@ -0,0 +1,189 @@
|
||||
#include "demolayout.h"
|
||||
|
||||
struct _DemoLayout
|
||||
{
|
||||
GtkLayoutManager parent_instance;
|
||||
|
||||
float position;
|
||||
int pos[16];
|
||||
};
|
||||
|
||||
struct _DemoLayoutClass
|
||||
{
|
||||
GtkLayoutManagerClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (DemoLayout, demo_layout, GTK_TYPE_LAYOUT_MANAGER)
|
||||
|
||||
static void
|
||||
demo_layout_measure (GtkLayoutManager *layout_manager,
|
||||
GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
int for_size,
|
||||
int *minimum,
|
||||
int *natural,
|
||||
int *minimum_baseline,
|
||||
int *natural_baseline)
|
||||
{
|
||||
GtkWidget *child;
|
||||
int minimum_size = 0;
|
||||
int natural_size = 0;
|
||||
|
||||
for (child = gtk_widget_get_first_child (widget);
|
||||
child != NULL;
|
||||
child = gtk_widget_get_next_sibling (child))
|
||||
{
|
||||
int child_min = 0, child_nat = 0;
|
||||
|
||||
if (!gtk_widget_should_layout (child))
|
||||
continue;
|
||||
|
||||
gtk_widget_measure (child, orientation, -1,
|
||||
&child_min, &child_nat,
|
||||
NULL, NULL);
|
||||
minimum_size = MAX (minimum_size, child_min);
|
||||
natural_size = MAX (natural_size, child_nat);
|
||||
}
|
||||
|
||||
/* A back-of-a-napkin calculation to reserve enough
|
||||
* space for arranging 16 children in a circle.
|
||||
*/
|
||||
*minimum = 16 * minimum_size / G_PI + minimum_size;
|
||||
*natural = 16 * natural_size / G_PI + natural_size;
|
||||
}
|
||||
|
||||
static void
|
||||
demo_layout_allocate (GtkLayoutManager *layout_manager,
|
||||
GtkWidget *widget,
|
||||
int width,
|
||||
int height,
|
||||
int baseline)
|
||||
{
|
||||
DemoLayout *self = DEMO_LAYOUT (layout_manager);
|
||||
GtkWidget *child;
|
||||
int i;
|
||||
int child_width = 0;
|
||||
int child_height = 0;
|
||||
int x0, y0;
|
||||
float r;
|
||||
float t;
|
||||
|
||||
t = self->position;
|
||||
|
||||
for (child = gtk_widget_get_first_child (widget);
|
||||
child != NULL;
|
||||
child = gtk_widget_get_next_sibling (child))
|
||||
{
|
||||
GtkRequisition child_req;
|
||||
|
||||
if (!gtk_widget_should_layout (child))
|
||||
continue;
|
||||
|
||||
gtk_widget_get_preferred_size (child, &child_req, NULL);
|
||||
|
||||
child_width = MAX (child_width, child_req.width);
|
||||
child_height = MAX (child_height, child_req.height);
|
||||
}
|
||||
|
||||
/* the center of our layout */
|
||||
x0 = (width / 2);
|
||||
y0 = (height / 2);
|
||||
|
||||
/* the radius for our circle of children */
|
||||
r = 8 * child_width / G_PI;
|
||||
|
||||
for (child = gtk_widget_get_first_child (widget), i = 0;
|
||||
child != NULL;
|
||||
child = gtk_widget_get_next_sibling (child), i++)
|
||||
{
|
||||
GtkRequisition child_req;
|
||||
float a = self->pos[i] * G_PI / 8;
|
||||
int gx, gy;
|
||||
int cx, cy;
|
||||
int x, y;
|
||||
|
||||
if (!gtk_widget_should_layout (child))
|
||||
continue;
|
||||
|
||||
gtk_widget_get_preferred_size (child, &child_req, NULL);
|
||||
|
||||
/* The grid position of child. */
|
||||
gx = x0 + (i % 4 - 2) * child_width;
|
||||
gy = y0 + (i / 4 - 2) * child_height;
|
||||
|
||||
/* The circle position of child. Note that we
|
||||
* are adjusting the position by half the child size
|
||||
* to place the center of child on a centered circle.
|
||||
* This assumes that the children don't use align flags
|
||||
* or uneven margins that would shift the center.
|
||||
*/
|
||||
cx = x0 + sin (a) * r - child_req.width / 2;
|
||||
cy = y0 + cos (a) * r - child_req.height / 2;
|
||||
|
||||
/* we interpolate between the two layouts according to
|
||||
* the position value that has been set on the layout.
|
||||
*/
|
||||
x = t * cx + (1 - t) * gx;
|
||||
y = t * cy + (1 - t) * gy;
|
||||
|
||||
gtk_widget_size_allocate (child,
|
||||
&(const GtkAllocation){ x, y, child_width, child_height},
|
||||
-1);
|
||||
}
|
||||
}
|
||||
|
||||
static GtkSizeRequestMode
|
||||
demo_layout_get_request_mode (GtkLayoutManager *layout_manager,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
return GTK_SIZE_REQUEST_CONSTANT_SIZE;
|
||||
}
|
||||
|
||||
static void
|
||||
demo_layout_class_init (DemoLayoutClass *klass)
|
||||
{
|
||||
GtkLayoutManagerClass *layout_class = GTK_LAYOUT_MANAGER_CLASS (klass);
|
||||
|
||||
layout_class->get_request_mode = demo_layout_get_request_mode;
|
||||
layout_class->measure = demo_layout_measure;
|
||||
layout_class->allocate = demo_layout_allocate;
|
||||
}
|
||||
|
||||
static void
|
||||
demo_layout_init (DemoLayout *self)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
self->pos[i] = i;
|
||||
}
|
||||
|
||||
GtkLayoutManager *
|
||||
demo_layout_new (void)
|
||||
{
|
||||
return g_object_new (DEMO_TYPE_LAYOUT, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
demo_layout_set_position (DemoLayout *layout,
|
||||
float position)
|
||||
{
|
||||
layout->position = position;
|
||||
}
|
||||
|
||||
/* Shuffle the circle positions of the children.
|
||||
* Should be called when we are in the grid layout.
|
||||
*/
|
||||
void
|
||||
demo_layout_shuffle (DemoLayout *layout)
|
||||
{
|
||||
int i, j, tmp;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
j = g_random_int_range (0, i + 1);
|
||||
tmp = layout->pos[i];
|
||||
layout->pos[i] = layout->pos[j];
|
||||
layout->pos[j] = tmp;
|
||||
}
|
||||
}
|
13
demos/gtk-demo/demolayout.h
Normal file
13
demos/gtk-demo/demolayout.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#define DEMO_TYPE_LAYOUT (demo_layout_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (DemoLayout, demo_layout, DEMO, LAYOUT, GtkLayoutManager)
|
||||
|
||||
GtkLayoutManager * demo_layout_new (void);
|
||||
|
||||
void demo_layout_set_position (DemoLayout *layout,
|
||||
float position);
|
||||
void demo_layout_shuffle (DemoLayout *layout);
|
121
demos/gtk-demo/demowidget.c
Normal file
121
demos/gtk-demo/demowidget.c
Normal file
@@ -0,0 +1,121 @@
|
||||
#include "demowidget.h"
|
||||
#include "demolayout.h"
|
||||
|
||||
/* parent widget */
|
||||
|
||||
struct _DemoWidget
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
|
||||
gboolean backward; /* whether we go 0 -> 1 or 1 -> 0 */
|
||||
gint64 start_time; /* time the transition started */
|
||||
guint tick_id; /* our tick cb */
|
||||
};
|
||||
|
||||
struct _DemoWidgetClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (DemoWidget, demo_widget, GTK_TYPE_WIDGET)
|
||||
|
||||
/* The widget is controlling the transition by calling
|
||||
* demo_layout_set_position() in a tick callback.
|
||||
*
|
||||
* We take half a second to go from one layout to the other.
|
||||
*/
|
||||
|
||||
#define DURATION (0.5 * G_TIME_SPAN_SECOND)
|
||||
|
||||
static gboolean
|
||||
transition (GtkWidget *widget,
|
||||
GdkFrameClock *frame_clock,
|
||||
gpointer data)
|
||||
{
|
||||
DemoWidget *self = DEMO_WIDGET (widget);
|
||||
DemoLayout *demo_layout = DEMO_LAYOUT (gtk_widget_get_layout_manager (widget));
|
||||
gint64 now = g_get_monotonic_time ();
|
||||
|
||||
gtk_widget_queue_allocate (widget);
|
||||
|
||||
if (self->backward)
|
||||
demo_layout_set_position (demo_layout, 1.0 - (now - self->start_time) / DURATION);
|
||||
else
|
||||
demo_layout_set_position (demo_layout, (now - self->start_time) / DURATION);
|
||||
|
||||
if (now - self->start_time >= DURATION)
|
||||
{
|
||||
self->backward = !self->backward;
|
||||
demo_layout_set_position (demo_layout, self->backward ? 1.0 : 0.0);
|
||||
/* keep things interesting by shuffling the positions */
|
||||
if (!self->backward)
|
||||
demo_layout_shuffle (demo_layout);
|
||||
self->tick_id = 0;
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
static void
|
||||
clicked (GtkGestureClick *gesture,
|
||||
guint n_press,
|
||||
double x,
|
||||
double y,
|
||||
gpointer data)
|
||||
{
|
||||
DemoWidget *self = data;
|
||||
|
||||
if (self->tick_id != 0)
|
||||
return;
|
||||
|
||||
self->start_time = g_get_monotonic_time ();
|
||||
self->tick_id = gtk_widget_add_tick_callback (GTK_WIDGET (self), transition, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
demo_widget_init (DemoWidget *self)
|
||||
{
|
||||
GtkGesture *gesture;
|
||||
|
||||
gesture = gtk_gesture_click_new ();
|
||||
g_signal_connect (gesture, "pressed", G_CALLBACK (clicked), self);
|
||||
gtk_widget_add_controller (GTK_WIDGET (self), GTK_EVENT_CONTROLLER (gesture));
|
||||
}
|
||||
|
||||
static void
|
||||
demo_widget_dispose (GObject *object)
|
||||
{
|
||||
GtkWidget *child;
|
||||
|
||||
while ((child = gtk_widget_get_first_child (GTK_WIDGET (object))))
|
||||
gtk_widget_unparent (child);
|
||||
|
||||
G_OBJECT_CLASS (demo_widget_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
demo_widget_class_init (DemoWidgetClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
||||
|
||||
object_class->dispose = demo_widget_dispose;
|
||||
|
||||
/* here is where we use our custom layout manager */
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, DEMO_TYPE_LAYOUT);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
demo_widget_new (void)
|
||||
{
|
||||
return g_object_new (DEMO_TYPE_WIDGET, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
demo_widget_add_child (DemoWidget *self,
|
||||
GtkWidget *child)
|
||||
{
|
||||
gtk_widget_set_parent (child, GTK_WIDGET (self));
|
||||
}
|
11
demos/gtk-demo/demowidget.h
Normal file
11
demos/gtk-demo/demowidget.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#define DEMO_TYPE_WIDGET (demo_widget_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (DemoWidget, demo_widget, DEMO, WIDGET, GtkWidget)
|
||||
|
||||
GtkWidget * demo_widget_new (void);
|
||||
|
||||
void demo_widget_add_child (DemoWidget *self,
|
||||
GtkWidget *child);
|
@@ -153,6 +153,30 @@ click_done (GtkGesture *gesture)
|
||||
gtk_widget_insert_after (item, canvas, last_child);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
theme_is_dark (void)
|
||||
{
|
||||
GtkSettings *settings;
|
||||
char *theme;
|
||||
gboolean prefer_dark;
|
||||
gboolean dark;
|
||||
|
||||
settings = gtk_settings_get_default ();
|
||||
g_object_get (settings,
|
||||
"gtk-theme-name", &theme,
|
||||
"gtk-application-prefer-dark-theme", &prefer_dark,
|
||||
NULL);
|
||||
|
||||
if ((strcmp (theme, "Adwaita") == 0 && prefer_dark) || strcmp (theme, "HighContrastInverse") == 0)
|
||||
dark = TRUE;
|
||||
else
|
||||
dark = FALSE;
|
||||
|
||||
g_free (theme);
|
||||
|
||||
return dark;
|
||||
}
|
||||
|
||||
static void
|
||||
canvas_item_init (CanvasItem *item)
|
||||
{
|
||||
@@ -180,7 +204,11 @@ canvas_item_init (CanvasItem *item)
|
||||
gtk_widget_set_name (item->label, id);
|
||||
g_free (id);
|
||||
|
||||
gdk_rgba_parse (&rgba, "yellow");
|
||||
if (theme_is_dark ())
|
||||
gdk_rgba_parse (&rgba, "blue");
|
||||
else
|
||||
gdk_rgba_parse (&rgba, "yellow");
|
||||
|
||||
set_color (item, &rgba);
|
||||
|
||||
item->angle = 0;
|
||||
@@ -538,7 +566,6 @@ canvas_new (void)
|
||||
canvas = gtk_fixed_new ();
|
||||
gtk_widget_set_hexpand (canvas, TRUE);
|
||||
gtk_widget_set_vexpand (canvas, TRUE);
|
||||
gtk_widget_add_css_class (canvas, "frame");
|
||||
|
||||
source = gtk_drag_source_new ();
|
||||
gtk_drag_source_set_actions (source, GDK_ACTION_MOVE);
|
||||
@@ -736,6 +763,8 @@ do_dnd (GtkWidget *do_widget)
|
||||
y += 100;
|
||||
}
|
||||
|
||||
gtk_box_append (GTK_BOX (box), gtk_separator_new (GTK_ORIENTATION_HORIZONTAL));
|
||||
|
||||
sw = gtk_scrolled_window_new ();
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
|
@@ -35,6 +35,10 @@ do_expander (GtkWidget *do_widget)
|
||||
GtkWidget *sw;
|
||||
GtkWidget *tv;
|
||||
GtkTextBuffer *buffer;
|
||||
GtkTextIter start;
|
||||
GtkTextIter end;
|
||||
GtkTextTag *tag;
|
||||
GdkPaintable *paintable;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
@@ -64,12 +68,25 @@ do_expander (GtkWidget *do_widget)
|
||||
GTK_POLICY_NEVER,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
gtk_scrolled_window_set_propagate_natural_height (GTK_SCROLLED_WINDOW (sw), TRUE);
|
||||
gtk_widget_set_vexpand (sw, TRUE);
|
||||
|
||||
tv = gtk_text_view_new ();
|
||||
|
||||
g_object_set (tv,
|
||||
"left-margin", 10,
|
||||
"right-margin", 10,
|
||||
"top-margin", 10,
|
||||
"bottom-margin", 10,
|
||||
NULL);
|
||||
|
||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tv));
|
||||
gtk_text_view_set_editable (GTK_TEXT_VIEW (tv), FALSE);
|
||||
gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (tv), FALSE);
|
||||
gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (tv), GTK_WRAP_WORD);
|
||||
gtk_text_buffer_set_text (GTK_TEXT_BUFFER (buffer),
|
||||
gtk_text_view_set_pixels_above_lines (GTK_TEXT_VIEW (tv), 2);
|
||||
gtk_text_view_set_pixels_below_lines (GTK_TEXT_VIEW (tv), 2);
|
||||
|
||||
gtk_text_buffer_set_text (buffer,
|
||||
"Finally, the full story with all details. "
|
||||
"And all the inside information, including "
|
||||
"error codes, etc etc. Pages of information, "
|
||||
@@ -77,7 +94,22 @@ do_expander (GtkWidget *do_widget)
|
||||
"or even resize the window - it works !\n"
|
||||
"A second paragraph will contain even more "
|
||||
"innuendo, just to make you scroll down or "
|
||||
"resize the window. Do it already !", -1);
|
||||
"resize the window.\n"
|
||||
"Do it already!\n", -1);
|
||||
|
||||
gtk_text_buffer_get_end_iter (buffer, &start);
|
||||
paintable = GDK_PAINTABLE (gdk_texture_new_from_resource ("/cursors/images/gtk_logo_cursor.png"));
|
||||
gtk_text_buffer_insert_paintable (buffer, &start, paintable);
|
||||
g_object_unref (paintable);
|
||||
gtk_text_iter_backward_char (&start);
|
||||
|
||||
gtk_text_buffer_get_end_iter (buffer, &end);
|
||||
tag = gtk_text_buffer_create_tag (buffer, NULL,
|
||||
"pixels-above-lines", 200,
|
||||
"justification", GTK_JUSTIFY_RIGHT,
|
||||
NULL);
|
||||
gtk_text_buffer_apply_tag (buffer, tag, &start, &end);
|
||||
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), tv);
|
||||
gtk_expander_set_child (GTK_EXPANDER (expander), sw);
|
||||
gtk_box_append (GTK_BOX (area), expander);
|
||||
|
@@ -158,26 +158,38 @@ set_inconsistent (GtkCheckButton *button,
|
||||
}
|
||||
|
||||
static void
|
||||
feat_clicked (GtkWidget *feat,
|
||||
gpointer data)
|
||||
feat_pressed (GtkGestureClick *gesture,
|
||||
int n_press,
|
||||
double x,
|
||||
double y,
|
||||
GtkWidget *feat)
|
||||
{
|
||||
g_signal_handlers_block_by_func (feat, feat_clicked, NULL);
|
||||
const guint button = gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture));
|
||||
|
||||
if (gtk_check_button_get_inconsistent (GTK_CHECK_BUTTON (feat)))
|
||||
if (button == GDK_BUTTON_PRIMARY)
|
||||
{
|
||||
set_inconsistent (GTK_CHECK_BUTTON (feat), FALSE);
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (feat), TRUE);
|
||||
}
|
||||
else if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (feat)))
|
||||
{
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (feat), FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
set_inconsistent (GTK_CHECK_BUTTON (feat), TRUE);
|
||||
}
|
||||
g_signal_handlers_block_by_func (feat, feat_pressed, NULL);
|
||||
|
||||
g_signal_handlers_unblock_by_func (feat, feat_clicked, NULL);
|
||||
if (gtk_check_button_get_inconsistent (GTK_CHECK_BUTTON (feat)))
|
||||
{
|
||||
set_inconsistent (GTK_CHECK_BUTTON (feat), FALSE);
|
||||
gtk_check_button_set_active (GTK_CHECK_BUTTON (feat), TRUE);
|
||||
}
|
||||
|
||||
g_signal_handlers_unblock_by_func (feat, feat_pressed, NULL);
|
||||
}
|
||||
else if (button == GDK_BUTTON_SECONDARY)
|
||||
{
|
||||
gboolean inconsistent = gtk_check_button_get_inconsistent (GTK_CHECK_BUTTON (feat));
|
||||
set_inconsistent (GTK_CHECK_BUTTON (feat), !inconsistent);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
feat_toggled_cb (GtkCheckButton *check_button,
|
||||
gpointer data)
|
||||
{
|
||||
set_inconsistent (check_button, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -208,6 +220,7 @@ add_check_group (GtkWidget *box,
|
||||
unsigned int tag;
|
||||
GtkWidget *feat;
|
||||
FeatureItem *item;
|
||||
GtkGesture *gesture;
|
||||
|
||||
tag = hb_tag_from_string (tags[i], -1);
|
||||
|
||||
@@ -216,7 +229,12 @@ add_check_group (GtkWidget *box,
|
||||
|
||||
g_signal_connect (feat, "notify::active", G_CALLBACK (update_display), NULL);
|
||||
g_signal_connect (feat, "notify::inconsistent", G_CALLBACK (update_display), NULL);
|
||||
g_signal_connect (feat, "clicked", G_CALLBACK (feat_clicked), NULL);
|
||||
g_signal_connect (feat, "toggled", G_CALLBACK (feat_toggled_cb), NULL);
|
||||
|
||||
gesture = gtk_gesture_click_new ();
|
||||
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), GDK_BUTTON_SECONDARY);
|
||||
g_signal_connect (gesture, "pressed", G_CALLBACK (feat_pressed), feat);
|
||||
gtk_widget_add_controller (feat, GTK_EVENT_CONTROLLER (gesture));
|
||||
|
||||
gtk_box_append (GTK_BOX (group), feat);
|
||||
|
||||
@@ -267,10 +285,11 @@ add_radio_group (GtkWidget *box,
|
||||
tag = hb_tag_from_string (tags[i], -1);
|
||||
name = get_feature_display_name (tag);
|
||||
|
||||
feat = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (group_button),
|
||||
name ? name : _("Default"));
|
||||
feat = gtk_check_button_new_with_label (name ? name : _("Default"));
|
||||
if (group_button == NULL)
|
||||
group_button = feat;
|
||||
else
|
||||
gtk_check_button_set_group (GTK_CHECK_BUTTON (feat), GTK_CHECK_BUTTON (group_button));
|
||||
|
||||
g_signal_connect (feat, "notify::active", G_CALLBACK (update_display), NULL);
|
||||
g_object_set_data (G_OBJECT (feat), "default", group_button);
|
||||
@@ -343,32 +362,35 @@ update_display (void)
|
||||
if (!gtk_widget_is_sensitive (item->feat))
|
||||
continue;
|
||||
|
||||
if (GTK_IS_RADIO_BUTTON (item->feat))
|
||||
if (GTK_IS_CHECK_BUTTON (item->feat))
|
||||
{
|
||||
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (item->feat)) &&
|
||||
strcmp (item->name, "xxxx") != 0)
|
||||
if (g_object_get_data (G_OBJECT (item->feat), "default"))
|
||||
{
|
||||
if (gtk_check_button_get_active (GTK_CHECK_BUTTON (item->feat)) &&
|
||||
strcmp (item->name, "xxxx") != 0)
|
||||
{
|
||||
if (has_feature)
|
||||
g_string_append (s, ", ");
|
||||
g_string_append (s, item->name);
|
||||
g_string_append (s, " 1");
|
||||
has_feature = TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gtk_check_button_get_inconsistent (GTK_CHECK_BUTTON (item->feat)))
|
||||
continue;
|
||||
|
||||
if (has_feature)
|
||||
g_string_append (s, ", ");
|
||||
g_string_append (s, item->name);
|
||||
g_string_append (s, " 1");
|
||||
if (gtk_check_button_get_active (GTK_CHECK_BUTTON (item->feat)))
|
||||
g_string_append (s, " 1");
|
||||
else
|
||||
g_string_append (s, " 0");
|
||||
has_feature = TRUE;
|
||||
}
|
||||
}
|
||||
else if (GTK_IS_CHECK_BUTTON (item->feat))
|
||||
{
|
||||
if (gtk_check_button_get_inconsistent (GTK_CHECK_BUTTON (item->feat)))
|
||||
continue;
|
||||
|
||||
if (has_feature)
|
||||
g_string_append (s, ", ");
|
||||
g_string_append (s, item->name);
|
||||
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (item->feat)))
|
||||
g_string_append (s, " 1");
|
||||
else
|
||||
g_string_append (s, " 0");
|
||||
has_feature = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
features = g_string_free (s, FALSE);
|
||||
@@ -614,7 +636,7 @@ update_features (void)
|
||||
gtk_widget_hide (item->feat);
|
||||
gtk_widget_hide (gtk_widget_get_parent (item->feat));
|
||||
if (strcmp (item->name, "xxxx") == 0)
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (item->feat), TRUE);
|
||||
gtk_check_button_set_active (GTK_CHECK_BUTTON (item->feat), TRUE);
|
||||
}
|
||||
|
||||
/* set feature presence checks from the font features */
|
||||
@@ -668,14 +690,17 @@ update_features (void)
|
||||
{
|
||||
gtk_widget_show (item->feat);
|
||||
gtk_widget_show (gtk_widget_get_parent (item->feat));
|
||||
if (GTK_IS_RADIO_BUTTON (item->feat))
|
||||
if (GTK_IS_CHECK_BUTTON (item->feat))
|
||||
{
|
||||
GtkWidget *def = GTK_WIDGET (g_object_get_data (G_OBJECT (item->feat), "default"));
|
||||
gtk_widget_show (def);
|
||||
}
|
||||
else if (GTK_IS_CHECK_BUTTON (item->feat))
|
||||
{
|
||||
set_inconsistent (GTK_CHECK_BUTTON (item->feat), TRUE);
|
||||
if (def)
|
||||
{
|
||||
gtk_widget_show (def);
|
||||
gtk_widget_show (gtk_widget_get_parent (def));
|
||||
gtk_check_button_set_active (GTK_CHECK_BUTTON (def), TRUE);
|
||||
}
|
||||
else
|
||||
set_inconsistent (GTK_CHECK_BUTTON (item->feat), TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -697,14 +722,14 @@ update_features (void)
|
||||
p = strstr (feat, buf);
|
||||
if (p)
|
||||
{
|
||||
if (GTK_IS_RADIO_BUTTON (item->feat))
|
||||
if (GTK_IS_CHECK_BUTTON (item->feat) && g_object_get_data (G_OBJECT (item->feat), "default"))
|
||||
{
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (item->feat), p[6] == '1');
|
||||
gtk_check_button_set_active (GTK_CHECK_BUTTON (item->feat), p[6] == '1');
|
||||
}
|
||||
else if (GTK_IS_CHECK_BUTTON (item->feat))
|
||||
{
|
||||
set_inconsistent (GTK_CHECK_BUTTON (item->feat), FALSE);
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (item->feat), p[6] == '1');
|
||||
gtk_check_button_set_active (GTK_CHECK_BUTTON (item->feat), p[6] == '1');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1141,15 +1166,15 @@ font_features_reset_features (void)
|
||||
{
|
||||
FeatureItem *item = l->data;
|
||||
|
||||
if (GTK_IS_RADIO_BUTTON (item->feat))
|
||||
if (GTK_IS_CHECK_BUTTON (item->feat))
|
||||
{
|
||||
if (strcmp (item->name, "xxxx") == 0)
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (item->feat), TRUE);
|
||||
}
|
||||
else if (GTK_IS_CHECK_BUTTON (item->feat))
|
||||
{
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (item->feat), FALSE);
|
||||
set_inconsistent (GTK_CHECK_BUTTON (item->feat), TRUE);
|
||||
gtk_check_button_set_active (GTK_CHECK_BUTTON (item->feat), TRUE);
|
||||
else
|
||||
{
|
||||
gtk_check_button_set_active (GTK_CHECK_BUTTON (item->feat), FALSE);
|
||||
set_inconsistent (GTK_CHECK_BUTTON (item->feat), TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
458
demos/gtk-demo/fontify.c
Normal file
458
demos/gtk-demo/fontify.c
Normal file
@@ -0,0 +1,458 @@
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <glib/gstdio.h>
|
||||
|
||||
#ifdef HAVE_GIO_UNIX
|
||||
#include <gio/gunixoutputstream.h>
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
|
||||
/* This is the guts of gtk_text_buffer_insert_markup,
|
||||
* copied here so we can make an incremental version.
|
||||
*/
|
||||
static void
|
||||
insert_tags_for_attributes (GtkTextBuffer *buffer,
|
||||
PangoAttrIterator *iter,
|
||||
GtkTextIter *start,
|
||||
GtkTextIter *end)
|
||||
{
|
||||
GtkTextTagTable *table;
|
||||
PangoAttribute *attr;
|
||||
GtkTextTag *tag;
|
||||
char name[256];
|
||||
|
||||
table = gtk_text_buffer_get_tag_table (buffer);
|
||||
|
||||
#define STRING_ATTR(pango_attr_name, attr_name) \
|
||||
attr = pango_attr_iterator_get (iter, pango_attr_name); \
|
||||
if (attr) \
|
||||
{ \
|
||||
const char *string = ((PangoAttrString*)attr)->value; \
|
||||
g_snprintf (name, 256, #attr_name "=%s", string); \
|
||||
tag = gtk_text_tag_table_lookup (table, name); \
|
||||
if (!tag) \
|
||||
{ \
|
||||
tag = gtk_text_tag_new (name); \
|
||||
g_object_set (tag, #attr_name, string, NULL); \
|
||||
gtk_text_tag_table_add (table, tag); \
|
||||
g_object_unref (tag); \
|
||||
} \
|
||||
gtk_text_buffer_apply_tag (buffer, tag, start, end); \
|
||||
}
|
||||
|
||||
#define INT_ATTR(pango_attr_name, attr_name) \
|
||||
attr = pango_attr_iterator_get (iter, pango_attr_name); \
|
||||
if (attr) \
|
||||
{ \
|
||||
int value = ((PangoAttrInt*)attr)->value; \
|
||||
g_snprintf (name, 256, #attr_name "=%d", value); \
|
||||
tag = gtk_text_tag_table_lookup (table, name); \
|
||||
if (!tag) \
|
||||
{ \
|
||||
tag = gtk_text_tag_new (name); \
|
||||
g_object_set (tag, #attr_name, value, NULL); \
|
||||
gtk_text_tag_table_add (table, tag); \
|
||||
g_object_unref (tag); \
|
||||
} \
|
||||
gtk_text_buffer_apply_tag (buffer, tag, start, end); \
|
||||
}
|
||||
|
||||
#define FLOAT_ATTR(pango_attr_name, attr_name) \
|
||||
attr = pango_attr_iterator_get (iter, pango_attr_name); \
|
||||
if (attr) \
|
||||
{ \
|
||||
float value = ((PangoAttrFloat*)attr)->value; \
|
||||
g_snprintf (name, 256, #attr_name "=%g", value); \
|
||||
tag = gtk_text_tag_table_lookup (table, name); \
|
||||
if (!tag) \
|
||||
{ \
|
||||
tag = gtk_text_tag_new (name); \
|
||||
g_object_set (tag, #attr_name, value, NULL); \
|
||||
gtk_text_tag_table_add (table, tag); \
|
||||
g_object_unref (tag); \
|
||||
} \
|
||||
gtk_text_buffer_apply_tag (buffer, tag, start, end); \
|
||||
}
|
||||
|
||||
#define RGBA_ATTR(pango_attr_name, attr_name) \
|
||||
attr = pango_attr_iterator_get (iter, pango_attr_name); \
|
||||
if (attr) \
|
||||
{ \
|
||||
PangoColor *color; \
|
||||
GdkRGBA rgba; \
|
||||
color = &((PangoAttrColor*)attr)->color; \
|
||||
rgba.red = color->red / 65535.; \
|
||||
rgba.green = color->green / 65535.; \
|
||||
rgba.blue = color->blue / 65535.; \
|
||||
rgba.alpha = 1.; \
|
||||
char *str = gdk_rgba_to_string (&rgba); \
|
||||
g_snprintf (name, 256, #attr_name "=%s", str); \
|
||||
g_free (str); \
|
||||
tag = gtk_text_tag_table_lookup (table, name); \
|
||||
if (!tag) \
|
||||
{ \
|
||||
tag = gtk_text_tag_new (name); \
|
||||
g_object_set (tag, #attr_name, &rgba, NULL); \
|
||||
gtk_text_tag_table_add (table, tag); \
|
||||
g_object_unref (tag); \
|
||||
} \
|
||||
gtk_text_buffer_apply_tag (buffer, tag, start, end); \
|
||||
}
|
||||
|
||||
attr = pango_attr_iterator_get (iter, PANGO_ATTR_LANGUAGE);
|
||||
if (attr)
|
||||
{
|
||||
const char *language = pango_language_to_string (((PangoAttrLanguage*)attr)->value);
|
||||
g_snprintf (name, 256, "language=%s", language);
|
||||
tag = gtk_text_tag_table_lookup (table, name);
|
||||
if (!tag)
|
||||
{
|
||||
tag = gtk_text_tag_new (name);
|
||||
g_object_set (tag, "language", language, NULL);
|
||||
gtk_text_tag_table_add (table, tag);
|
||||
g_object_unref (tag);
|
||||
}
|
||||
gtk_text_buffer_apply_tag (buffer, tag, start, end);
|
||||
}
|
||||
|
||||
STRING_ATTR (PANGO_ATTR_FAMILY, family)
|
||||
INT_ATTR (PANGO_ATTR_STYLE, style)
|
||||
INT_ATTR (PANGO_ATTR_WEIGHT, weight)
|
||||
INT_ATTR (PANGO_ATTR_VARIANT, variant)
|
||||
INT_ATTR (PANGO_ATTR_STRETCH, stretch)
|
||||
INT_ATTR (PANGO_ATTR_SIZE, size)
|
||||
|
||||
attr = pango_attr_iterator_get (iter, PANGO_ATTR_FONT_DESC);
|
||||
if (attr)
|
||||
{
|
||||
PangoFontDescription *desc = ((PangoAttrFontDesc*)attr)->desc;
|
||||
char *str = pango_font_description_to_string (desc);
|
||||
g_snprintf (name, 256, "font-desc=%s", str);
|
||||
g_free (str);
|
||||
tag = gtk_text_tag_table_lookup (table, name);
|
||||
if (!tag)
|
||||
{
|
||||
tag = gtk_text_tag_new (name);
|
||||
g_object_set (tag, "font-desc", desc, NULL);
|
||||
gtk_text_tag_table_add (table, tag);
|
||||
g_object_unref (tag);
|
||||
}
|
||||
gtk_text_buffer_apply_tag (buffer, tag, start, end);
|
||||
}
|
||||
|
||||
RGBA_ATTR (PANGO_ATTR_FOREGROUND, foreground_rgba)
|
||||
RGBA_ATTR (PANGO_ATTR_BACKGROUND, background_rgba)
|
||||
INT_ATTR (PANGO_ATTR_UNDERLINE, underline)
|
||||
RGBA_ATTR (PANGO_ATTR_UNDERLINE_COLOR, underline_rgba)
|
||||
INT_ATTR (PANGO_ATTR_OVERLINE, overline)
|
||||
RGBA_ATTR (PANGO_ATTR_OVERLINE_COLOR, overline_rgba)
|
||||
INT_ATTR (PANGO_ATTR_STRIKETHROUGH, strikethrough)
|
||||
RGBA_ATTR (PANGO_ATTR_STRIKETHROUGH_COLOR, strikethrough_rgba)
|
||||
INT_ATTR (PANGO_ATTR_RISE, rise)
|
||||
FLOAT_ATTR (PANGO_ATTR_SCALE, scale)
|
||||
INT_ATTR (PANGO_ATTR_FALLBACK, fallback)
|
||||
INT_ATTR (PANGO_ATTR_LETTER_SPACING, letter_spacing)
|
||||
STRING_ATTR (PANGO_ATTR_FONT_FEATURES, font_features)
|
||||
INT_ATTR (PANGO_ATTR_ALLOW_BREAKS, allow_breaks)
|
||||
INT_ATTR (PANGO_ATTR_SHOW, show_spaces)
|
||||
INT_ATTR (PANGO_ATTR_INSERT_HYPHENS, insert_hyphens)
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GMarkupParseContext *parser;
|
||||
char *markup;
|
||||
gsize pos;
|
||||
gsize len;
|
||||
GtkTextBuffer *buffer;
|
||||
GtkTextIter iter;
|
||||
GtkTextMark *mark;
|
||||
PangoAttrList *attributes;
|
||||
char *text;
|
||||
PangoAttrIterator *attr;
|
||||
} MarkupData;
|
||||
|
||||
static void
|
||||
free_markup_data (MarkupData *mdata)
|
||||
{
|
||||
g_free (mdata->markup);
|
||||
g_clear_pointer (&mdata->parser, g_markup_parse_context_free);
|
||||
gtk_text_buffer_delete_mark (mdata->buffer, mdata->mark);
|
||||
g_clear_pointer (&mdata->attr, pango_attr_iterator_destroy);
|
||||
g_clear_pointer (&mdata->attributes, pango_attr_list_unref);
|
||||
g_free (mdata->text);
|
||||
g_object_unref (mdata->buffer);
|
||||
g_free (mdata);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
insert_markup_idle (gpointer data)
|
||||
{
|
||||
MarkupData *mdata = data;
|
||||
gint64 begin;
|
||||
|
||||
begin = g_get_monotonic_time ();
|
||||
|
||||
do
|
||||
{
|
||||
int start, end;
|
||||
int start_offset;
|
||||
GtkTextIter start_iter;
|
||||
|
||||
if (g_get_monotonic_time () - begin > G_TIME_SPAN_MILLISECOND)
|
||||
{
|
||||
g_idle_add (insert_markup_idle, data);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
pango_attr_iterator_range (mdata->attr, &start, &end);
|
||||
|
||||
if (end == G_MAXINT) /* last chunk */
|
||||
end = start - 1; /* resulting in -1 to be passed to _insert */
|
||||
|
||||
start_offset = gtk_text_iter_get_offset (&mdata->iter);
|
||||
gtk_text_buffer_insert (mdata->buffer, &mdata->iter, mdata->text + start, end - start);
|
||||
gtk_text_buffer_get_iter_at_offset (mdata->buffer, &start_iter, start_offset);
|
||||
|
||||
insert_tags_for_attributes (mdata->buffer, mdata->attr, &start_iter, &mdata->iter);
|
||||
|
||||
gtk_text_buffer_get_iter_at_mark (mdata->buffer, &mdata->iter, mdata->mark);
|
||||
}
|
||||
while (pango_attr_iterator_next (mdata->attr));
|
||||
|
||||
free_markup_data (mdata);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_markup_idle (gpointer data)
|
||||
{
|
||||
MarkupData *mdata = data;
|
||||
gint64 begin;
|
||||
GError *error = NULL;
|
||||
|
||||
begin = g_get_monotonic_time ();
|
||||
|
||||
do {
|
||||
if (g_get_monotonic_time () - begin > G_TIME_SPAN_MILLISECOND)
|
||||
{
|
||||
g_idle_add (parse_markup_idle, data);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
if (!g_markup_parse_context_parse (mdata->parser,
|
||||
mdata->markup + mdata->pos,
|
||||
MIN (4096, mdata->len - mdata->pos),
|
||||
&error))
|
||||
{
|
||||
g_warning ("Invalid markup string: %s", error->message);
|
||||
g_error_free (error);
|
||||
free_markup_data (mdata);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
mdata->pos += 4096;
|
||||
} while (mdata->pos < mdata->len);
|
||||
|
||||
if (!pango_markup_parser_finish (mdata->parser,
|
||||
&mdata->attributes,
|
||||
&mdata->text,
|
||||
NULL,
|
||||
&error))
|
||||
{
|
||||
g_warning ("Invalid markup string: %s", error->message);
|
||||
g_error_free (error);
|
||||
free_markup_data (mdata);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
if (!mdata->attributes)
|
||||
{
|
||||
gtk_text_buffer_insert (mdata->buffer, &mdata->iter, mdata->text, -1);
|
||||
free_markup_data (mdata);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
mdata->attr = pango_attr_list_get_iterator (mdata->attributes);
|
||||
insert_markup_idle (data);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
/* Takes a ref on @buffer while it is operating,
|
||||
* and consumes @markup.
|
||||
*/
|
||||
static void
|
||||
insert_markup (GtkTextBuffer *buffer,
|
||||
GtkTextIter *iter,
|
||||
char *markup,
|
||||
int len)
|
||||
{
|
||||
MarkupData *data;
|
||||
|
||||
g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
|
||||
|
||||
data = g_new0 (MarkupData, 1);
|
||||
|
||||
data->buffer = g_object_ref (buffer);
|
||||
data->iter = *iter;
|
||||
data->markup = markup;
|
||||
data->len = len;
|
||||
|
||||
data->parser = pango_markup_parser_new (0);
|
||||
data->pos = 0;
|
||||
|
||||
/* create mark with right gravity */
|
||||
data->mark = gtk_text_buffer_create_mark (buffer, NULL, iter, FALSE);
|
||||
|
||||
parse_markup_idle (data);
|
||||
}
|
||||
|
||||
static void
|
||||
fontify_finish (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer data)
|
||||
{
|
||||
GSubprocess *subprocess = G_SUBPROCESS (source);
|
||||
GtkTextBuffer *buffer = data;
|
||||
GBytes *stdout_buf = NULL;
|
||||
GBytes *stderr_buf = NULL;
|
||||
GError *error = NULL;
|
||||
|
||||
if (!g_subprocess_communicate_finish (subprocess,
|
||||
result,
|
||||
&stdout_buf,
|
||||
&stderr_buf,
|
||||
&error))
|
||||
{
|
||||
g_clear_pointer (&stdout_buf, g_bytes_unref);
|
||||
g_clear_pointer (&stderr_buf, g_bytes_unref);
|
||||
|
||||
g_warning ("%s", error->message);
|
||||
g_clear_error (&error);
|
||||
|
||||
g_object_unref (subprocess);
|
||||
g_object_unref (buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_subprocess_get_exit_status (subprocess) != 0)
|
||||
{
|
||||
if (stderr_buf)
|
||||
g_warning ("%s", (char *)g_bytes_get_data (stderr_buf, NULL));
|
||||
g_clear_pointer (&stderr_buf, g_bytes_unref);
|
||||
}
|
||||
|
||||
g_object_unref (subprocess);
|
||||
|
||||
g_clear_pointer (&stderr_buf, g_bytes_unref);
|
||||
|
||||
if (stdout_buf)
|
||||
{
|
||||
char *markup;
|
||||
gsize len;
|
||||
char *p;
|
||||
GtkTextIter start;
|
||||
|
||||
gtk_text_buffer_set_text (buffer, "", 0);
|
||||
|
||||
/* highlight puts a span with font and size around its output,
|
||||
* which we don't want.
|
||||
*/
|
||||
markup = g_bytes_unref_to_data (stdout_buf, &len);
|
||||
for (p = markup + strlen ("<span "); *p != '>'; p++) *p = ' ';
|
||||
|
||||
gtk_text_buffer_get_start_iter (buffer, &start);
|
||||
insert_markup (buffer, &start, markup, len);
|
||||
}
|
||||
|
||||
g_object_unref (buffer);
|
||||
}
|
||||
|
||||
void
|
||||
fontify (const char *format,
|
||||
GtkTextBuffer *source_buffer)
|
||||
{
|
||||
GSubprocess *subprocess;
|
||||
char *format_arg;
|
||||
GtkSettings *settings;
|
||||
char *theme;
|
||||
gboolean prefer_dark;
|
||||
const char *style_arg;
|
||||
const char *text;
|
||||
GtkTextIter start, end;
|
||||
GBytes *bytes;
|
||||
GError *error = NULL;
|
||||
|
||||
settings = gtk_settings_get_default ();
|
||||
g_object_get (settings,
|
||||
"gtk-theme-name", &theme,
|
||||
"gtk-application-prefer-dark-theme", &prefer_dark,
|
||||
NULL);
|
||||
|
||||
if (prefer_dark || strcmp (theme, "HighContrastInverse") == 0)
|
||||
style_arg = "--style=edit-vim-dark";
|
||||
else
|
||||
style_arg = "--style=edit-kwrite";
|
||||
|
||||
g_free (theme);
|
||||
|
||||
format_arg = g_strconcat ("--syntax=", format, NULL);
|
||||
subprocess = g_subprocess_new (G_SUBPROCESS_FLAGS_STDIN_PIPE |
|
||||
G_SUBPROCESS_FLAGS_STDOUT_PIPE |
|
||||
G_SUBPROCESS_FLAGS_STDERR_PIPE,
|
||||
&error,
|
||||
"highlight",
|
||||
format_arg,
|
||||
"--out-format=pango",
|
||||
style_arg,
|
||||
NULL);
|
||||
g_free (format_arg);
|
||||
|
||||
if (!subprocess)
|
||||
{
|
||||
if (g_error_matches (error, G_SPAWN_ERROR, G_SPAWN_ERROR_NOENT))
|
||||
{
|
||||
static gboolean warned = FALSE;
|
||||
|
||||
if (!warned)
|
||||
{
|
||||
warned = TRUE;
|
||||
g_message ("For syntax highlighting, install the “highlight” program");
|
||||
}
|
||||
}
|
||||
else
|
||||
g_warning ("%s", error->message);
|
||||
|
||||
g_clear_error (&error);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
gtk_text_buffer_get_bounds (source_buffer, &start, &end);
|
||||
text = gtk_text_buffer_get_text (source_buffer, &start, &end, TRUE);
|
||||
bytes = g_bytes_new_static (text, strlen (text));
|
||||
|
||||
#ifdef HAVE_GIO_UNIX
|
||||
/* Work around https://gitlab.gnome.org/GNOME/glib/-/issues/2182 */
|
||||
if (G_IS_UNIX_OUTPUT_STREAM (g_subprocess_get_stdin_pipe (subprocess)))
|
||||
{
|
||||
GOutputStream *stdin_pipe = g_subprocess_get_stdin_pipe (subprocess);
|
||||
int fd = g_unix_output_stream_get_fd (G_UNIX_OUTPUT_STREAM (stdin_pipe));
|
||||
fcntl (fd, F_SETFL, O_NONBLOCK);
|
||||
}
|
||||
#endif
|
||||
|
||||
g_subprocess_communicate_async (subprocess,
|
||||
bytes,
|
||||
NULL,
|
||||
fontify_finish,
|
||||
g_object_ref (source_buffer));
|
||||
}
|
6
demos/gtk-demo/fontify.h
Normal file
6
demos/gtk-demo/fontify.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
void fontify (const char *format,
|
||||
GtkTextBuffer *buffer);
|
@@ -19,7 +19,7 @@ static GtkWidget *show_extents = NULL;
|
||||
|
||||
static PangoContext *context;
|
||||
|
||||
static int scale = 10;
|
||||
static int scale = 9;
|
||||
|
||||
static void
|
||||
update_image (void)
|
||||
@@ -59,7 +59,7 @@ update_image (void)
|
||||
hintstyle = CAIRO_HINT_STYLE_DEFAULT;
|
||||
cairo_font_options_set_hint_style (fopt, hintstyle);
|
||||
|
||||
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (hint_metrics)))
|
||||
if (gtk_check_button_get_active (GTK_CHECK_BUTTON (hint_metrics)))
|
||||
hintmetrics = CAIRO_HINT_METRICS_ON;
|
||||
else
|
||||
hintmetrics = CAIRO_HINT_METRICS_OFF;
|
||||
@@ -107,7 +107,7 @@ update_image (void)
|
||||
cr = cairo_create (surface);
|
||||
cairo_set_line_width (cr, 1);
|
||||
|
||||
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (show_grid)))
|
||||
if (gtk_check_button_get_active (GTK_CHECK_BUTTON (show_grid)))
|
||||
{
|
||||
int i;
|
||||
cairo_set_source_rgba (cr, 0.2, 0, 0, 0.2);
|
||||
@@ -125,7 +125,7 @@ update_image (void)
|
||||
}
|
||||
}
|
||||
|
||||
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (show_extents)))
|
||||
if (gtk_check_button_get_active (GTK_CHECK_BUTTON (show_extents)))
|
||||
{
|
||||
cairo_set_source_rgba (cr, 0, 0, 1, 1);
|
||||
|
||||
|
@@ -6,164 +6,11 @@
|
||||
<property name="page-increment">4</property>
|
||||
</object>
|
||||
<object class="GtkWindow" id="window">
|
||||
<property name="default-width">600</property>
|
||||
<property name="default-height">300</property>
|
||||
<property name="title">Font rendering</property>
|
||||
<child>
|
||||
<object class="GtkGrid">
|
||||
<property name="margin-top">10</property>
|
||||
<property name="row-spacing">10</property>
|
||||
<property name="column-spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="margin-start">10</property>
|
||||
<property name="label">Text</property>
|
||||
<property name="xalign">1</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="entry">
|
||||
<property name="text">Fonts render</property>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="margin-start">10</property>
|
||||
<property name="label">Font</property>
|
||||
<property name="xalign">1</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFontButton" id="font_button">
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Hinting</property>
|
||||
<property name="xalign">1</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="column">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBoxText" id="hinting">
|
||||
<property name="active">0</property>
|
||||
<property name="valign">center</property>
|
||||
<items>
|
||||
<item translatable="yes" id="none">None</item>
|
||||
<item translatable="yes" id="slight">Slight</item>
|
||||
<item translatable="yes" id="medium">Medium</item>
|
||||
<item translatable="yes" id="full">Full</item>
|
||||
</items>
|
||||
<layout>
|
||||
<property name="column">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="hint_metrics">
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Hint Metrics</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<layout>
|
||||
<property name="column">3</property>
|
||||
<property name="row">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="show_extents">
|
||||
<property name="active">1</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Show Extents</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<layout>
|
||||
<property name="column">4</property>
|
||||
<property name="row">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="show_grid">
|
||||
<property name="active">1</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Show Grid</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<layout>
|
||||
<property name="column">4</property>
|
||||
<property name="row">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="up_button">
|
||||
<property name="icon-name">list-add-symbolic</property>
|
||||
<style>
|
||||
<class name="circular"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="column">5</property>
|
||||
<property name="row">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="down_button">
|
||||
<property name="icon-name">list-remove-symbolic</property>
|
||||
<style>
|
||||
<class name="circular"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="column">5</property>
|
||||
<property name="row">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="hexpand">1</property>
|
||||
<layout>
|
||||
<property name="column">6</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<property name="default-width">1080</property>
|
||||
<property name="default-height">430</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar">
|
||||
<child type="title">
|
||||
<object class="GtkBox">
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">center</property>
|
||||
@@ -171,29 +18,170 @@
|
||||
<class name="linked"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="text_radio">
|
||||
<property name="draw-indicator">0</property>
|
||||
<object class="GtkToggleButton" id="text_radio">
|
||||
<property name="label">Text</property>
|
||||
<property name="active">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="grid_radio">
|
||||
<property name="draw-indicator">0</property>
|
||||
<object class="GtkToggleButton" id="grid_radio">
|
||||
<property name="label">Grid</property>
|
||||
<property name="group">text_radio</property>
|
||||
</object>
|
||||
</child>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">3</property>
|
||||
<property name="column-span">7</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkGrid">
|
||||
<property name="halign">center</property>
|
||||
<property name="margin-top">10</property>
|
||||
<property name="margin-bottom">10</property>
|
||||
<property name="row-spacing">10</property>
|
||||
<property name="column-spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="margin-start">10</property>
|
||||
<property name="label">Text</property>
|
||||
<property name="xalign">1</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="entry">
|
||||
<property name="text">Fonts render</property>
|
||||
<layout>
|
||||
<property name="column">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="margin-start">10</property>
|
||||
<property name="label">Font</property>
|
||||
<property name="xalign">1</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="column">1</property>
|
||||
<property name="row">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFontButton" id="font_button">
|
||||
<layout>
|
||||
<property name="column">2</property>
|
||||
<property name="row">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Hinting</property>
|
||||
<property name="xalign">1</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="column">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBoxText" id="hinting">
|
||||
<property name="active">0</property>
|
||||
<property name="valign">center</property>
|
||||
<items>
|
||||
<item translatable="yes" id="none">None</item>
|
||||
<item translatable="yes" id="slight">Slight</item>
|
||||
<item translatable="yes" id="medium">Medium</item>
|
||||
<item translatable="yes" id="full">Full</item>
|
||||
</items>
|
||||
<layout>
|
||||
<property name="column">4</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="hint_metrics">
|
||||
<property name="label">Hint Metrics</property>
|
||||
<layout>
|
||||
<property name="column">4</property>
|
||||
<property name="row">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="show_extents">
|
||||
<property name="label">Show Extents</property>
|
||||
<property name="active">1</property>
|
||||
<layout>
|
||||
<property name="column">5</property>
|
||||
<property name="row">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="show_grid">
|
||||
<property name="active">1</property>
|
||||
<property name="label">Show Grid</property>
|
||||
<layout>
|
||||
<property name="column">5</property>
|
||||
<property name="row">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="up_button">
|
||||
<property name="icon-name">list-add-symbolic</property>
|
||||
<style>
|
||||
<class name="circular"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="column">6</property>
|
||||
<property name="row">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="down_button">
|
||||
<property name="icon-name">list-remove-symbolic</property>
|
||||
<style>
|
||||
<class name="circular"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="column">6</property>
|
||||
<property name="row">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="hexpand">1</property>
|
||||
<layout>
|
||||
<property name="column">7</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator"/>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="propagate-natural-height">1</property>
|
||||
<property name="has-frame">1</property>
|
||||
<property name="hexpand">1</property>
|
||||
<property name="vexpand">1</property>
|
||||
<child>
|
||||
@@ -203,11 +191,6 @@
|
||||
<property name="can-shrink">0</property>
|
||||
</object>
|
||||
</child>
|
||||
<layout>
|
||||
<property name="column">0</property>
|
||||
<property name="row">4</property>
|
||||
<property name="column-span">7</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
94
demos/gtk-demo/four_point_transform.c
Normal file
94
demos/gtk-demo/four_point_transform.c
Normal file
@@ -0,0 +1,94 @@
|
||||
#include "four_point_transform.h"
|
||||
#include "singular_value_decomposition.h"
|
||||
|
||||
/* Make a 4x4 matrix that maps
|
||||
* e1 -> p1
|
||||
* e2 -> p3
|
||||
* e3 -> p3
|
||||
* (1,1,1,0) -> p4
|
||||
*/
|
||||
static void
|
||||
unit_to (graphene_point3d_t *p1,
|
||||
graphene_point3d_t *p2,
|
||||
graphene_point3d_t *p3,
|
||||
graphene_point3d_t *p4,
|
||||
graphene_matrix_t *m)
|
||||
{
|
||||
graphene_vec3_t v1, v2, v3, v4;
|
||||
graphene_vec4_t vv1, vv2, vv3, vv4, p;
|
||||
graphene_matrix_t u, s;
|
||||
float v[16] = { 0., };
|
||||
double A[16];
|
||||
double U[16];
|
||||
double S[4];
|
||||
double V[16];
|
||||
double B[4];
|
||||
double x[4];
|
||||
int i, j;
|
||||
|
||||
graphene_point3d_to_vec3 (p1, &v1);
|
||||
graphene_point3d_to_vec3 (p2, &v2);
|
||||
graphene_point3d_to_vec3 (p3, &v3);
|
||||
graphene_point3d_to_vec3 (p4, &v4);
|
||||
|
||||
graphene_vec4_init_from_vec3 (&vv1, &v1, 1.);
|
||||
graphene_vec4_init_from_vec3 (&vv2, &v2, 1.);
|
||||
graphene_vec4_init_from_vec3 (&vv3, &v3, 1.);
|
||||
graphene_vec4_init_from_vec3 (&vv4, &v4, 1.);
|
||||
|
||||
graphene_vec4_init (&p, 0., 0., 0., 1.);
|
||||
|
||||
graphene_matrix_init_from_vec4 (&u, &vv1, &vv2, &vv3, &p);
|
||||
|
||||
/* solve x * u = vv4 */
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
for (j = 0; j < 4; j++)
|
||||
A[j * 4 + i] = graphene_matrix_get_value (&u, i, j);
|
||||
|
||||
B[0] = graphene_vec4_get_x (&vv4);
|
||||
B[1] = graphene_vec4_get_y (&vv4);
|
||||
B[2] = graphene_vec4_get_z (&vv4);
|
||||
B[3] = graphene_vec4_get_w (&vv4);
|
||||
|
||||
singular_value_decomposition (A, 4, 4, U, S, V);
|
||||
singular_value_decomposition_solve (U, S, V, 4, 4, B, x);
|
||||
|
||||
v[ 0] = x[0];
|
||||
v[ 5] = x[1];
|
||||
v[10] = x[2];
|
||||
v[15] = 1;
|
||||
|
||||
graphene_matrix_init_from_float (&s, (const float *)&v);
|
||||
graphene_matrix_multiply (&s, &u, m);
|
||||
}
|
||||
|
||||
/* Compute a 4x4 matrix m that maps
|
||||
* p1 -> q1
|
||||
* p2 -> q2
|
||||
* p3 -> q3
|
||||
* p4 -> q4
|
||||
*
|
||||
* This is not in general possible, because projective
|
||||
* transforms preserve coplanarity. But in the cases we
|
||||
* care about here, both sets of points are always coplanar.
|
||||
*/
|
||||
void
|
||||
perspective_3d (graphene_point3d_t *p1,
|
||||
graphene_point3d_t *p2,
|
||||
graphene_point3d_t *p3,
|
||||
graphene_point3d_t *p4,
|
||||
graphene_point3d_t *q1,
|
||||
graphene_point3d_t *q2,
|
||||
graphene_point3d_t *q3,
|
||||
graphene_point3d_t *q4,
|
||||
graphene_matrix_t *m)
|
||||
{
|
||||
graphene_matrix_t a, a_inv, b;
|
||||
|
||||
unit_to (p1, p2, p3, p4, &a);
|
||||
unit_to (q1, q2, q3, q4, &b);
|
||||
|
||||
graphene_matrix_inverse (&a, &a_inv);
|
||||
graphene_matrix_multiply (&a_inv, &b, m);
|
||||
}
|
13
demos/gtk-demo/four_point_transform.h
Normal file
13
demos/gtk-demo/four_point_transform.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include <graphene.h>
|
||||
|
||||
void perspective_3d (graphene_point3d_t *p1,
|
||||
graphene_point3d_t *p2,
|
||||
graphene_point3d_t *p3,
|
||||
graphene_point3d_t *p4,
|
||||
graphene_point3d_t *q1,
|
||||
graphene_point3d_t *q2,
|
||||
graphene_point3d_t *q3,
|
||||
graphene_point3d_t *q4,
|
||||
graphene_matrix_t *m);
|
174
demos/gtk-demo/glowingstars.glsl
Normal file
174
demos/gtk-demo/glowingstars.glsl
Normal file
@@ -0,0 +1,174 @@
|
||||
// Originally from: https://www.shadertoy.com/view/ttBcRV
|
||||
// License CC0: Flying through glowing stars
|
||||
// The result of playing around trying to improve an old shader
|
||||
|
||||
#define PI 3.141592654
|
||||
#define TAU (2.0*PI)
|
||||
#define TIME iTime
|
||||
#define RESOLUTION iResolution
|
||||
|
||||
#define LESS(a,b,c) mix(a,b,step(0.,c))
|
||||
#define SABS(x,k) LESS((.5/(k))*(x)*(x)+(k)*.5,abs(x),abs(x)-(k))
|
||||
|
||||
#define MROT(a) mat2(cos(a), sin(a), -sin(a), cos(a))
|
||||
|
||||
vec3 hsv2rgb(vec3 c) {
|
||||
const vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
|
||||
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
|
||||
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
|
||||
}
|
||||
|
||||
float hash(in vec3 co) {
|
||||
return fract(sin(dot(co, vec3(12.9898,58.233, 12.9898+58.233))) * 13758.5453);
|
||||
}
|
||||
|
||||
float starn(vec2 p, float r, int n, float m) {
|
||||
// From IQ: https://www.shadertoy.com/view/3tSGDy
|
||||
// https://iquilezles.org/www/articles/distfunctions2d/distfunctions2d.htm
|
||||
|
||||
// Minor tweak to use SABS over abs to smooth inner corners
|
||||
// SABS: https://www.shadertoy.com/view/Ws2SDK
|
||||
|
||||
// next 4 lines can be precomputed for a given shape
|
||||
float an = 3.141593/float(n);
|
||||
float en = 3.141593/m; // m is between 2 and n
|
||||
vec2 acs = vec2(cos(an),sin(an));
|
||||
vec2 ecs = vec2(cos(en),sin(en)); // ecs=vec2(0,1) for regular polygon,
|
||||
|
||||
float bn = mod(atan(p.x,p.y),2.0*an) - an;
|
||||
p = length(p)*vec2(cos(bn),SABS(sin(bn), 0.15));
|
||||
p -= r*acs;
|
||||
p += ecs*clamp( -dot(p,ecs), 0.0, r*acs.y/ecs.y);
|
||||
return length(p)*sign(p.x);
|
||||
}
|
||||
|
||||
vec4 alphaBlend(vec4 back, vec4 front) {
|
||||
vec3 xyz = mix(back.xyz*back.w, front.xyz, front.w);
|
||||
float w = mix(back.w, 1.0, front.w);
|
||||
return vec4(xyz, w);
|
||||
}
|
||||
|
||||
void rot(inout vec2 p, float a) {
|
||||
float c = cos(a);
|
||||
float s = sin(a);
|
||||
p = vec2(c*p.x + s*p.y, -s*p.x + c*p.y);
|
||||
}
|
||||
|
||||
vec3 offset(float z) {
|
||||
float a = z;
|
||||
vec2 p = -0.075*(vec2(cos(a), sin(a*sqrt(2.0))) + vec2(cos(a*sqrt(0.75)), sin(a*sqrt(0.5))));
|
||||
return vec3(p, z);
|
||||
}
|
||||
|
||||
vec3 doffset(float z) {
|
||||
float eps = 0.05;
|
||||
return 0.5*(offset(z + eps) - offset(z - eps))/eps;
|
||||
}
|
||||
|
||||
vec3 ddoffset(float z) {
|
||||
float eps = 0.05;
|
||||
return 0.5*(doffset(z + eps) - doffset(z - eps))/eps;
|
||||
}
|
||||
|
||||
vec4 planeCol(vec3 ro, vec3 rd, float n, vec3 pp) {
|
||||
const float s = 0.5;
|
||||
|
||||
vec2 p = pp.xy;
|
||||
float z = pp.z;
|
||||
vec2 dpy = dFdy(p);
|
||||
float aa = length(dpy);
|
||||
|
||||
p -= (1.0+5.0*(pp.z - ro.z))*offset(z).xy;
|
||||
|
||||
p *= s;
|
||||
float r = hash(vec3(floor(p+0.5), n));
|
||||
p = fract(p+0.5)-0.5;
|
||||
rot(p, ((TAU*r+n)*0.25));
|
||||
float d = starn(p, 0.20, 3 + 2*int(3.0*r), 3.0);
|
||||
d -= 0.06;
|
||||
d/=s;
|
||||
|
||||
float ds = -d+0.03;
|
||||
vec3 cols = hsv2rgb(vec3(337.0/360.0+0.1*sin(n*0.3), 0.8, 0.54+0.2*sin(n*0.3)));
|
||||
float ts = 1.0 - smoothstep(-aa, 0.0, ds);
|
||||
vec4 cs = vec4(cols, ts*0.93);
|
||||
|
||||
float db = abs(d) - (0.06);
|
||||
db = abs(db) - 0.03;
|
||||
db = abs(db) - 0.00;
|
||||
db = max(db, -d+0.03);
|
||||
vec3 colb = vec3(1.0, 0.7, 0.5);
|
||||
float tb = exp(-(db)*30.0*(1.0 - 10.0*aa));
|
||||
vec4 cb = vec4(1.5*colb, tb);
|
||||
|
||||
vec4 ct = alphaBlend(cs, cb);
|
||||
|
||||
return ct;
|
||||
}
|
||||
|
||||
vec3 color(vec3 ww, vec3 uu, vec3 vv, vec3 ro, vec2 p) {
|
||||
vec3 rd = normalize(p.x*uu + p.y*vv + (2.0-tanh(length(p)))*ww);
|
||||
|
||||
vec4 col = vec4(vec3(0.0), 1.0);
|
||||
|
||||
const float planeDist = 1.0;
|
||||
const int furthest = 6;
|
||||
const int fadeFrom = furthest-3;
|
||||
|
||||
float nz = floor(ro.z / planeDist);
|
||||
|
||||
for (int i = furthest; i >= 1; --i) {
|
||||
float pz = planeDist*nz + planeDist*float(i);
|
||||
|
||||
float pd = (pz - ro.z)/rd.z;
|
||||
|
||||
if (pd > 0.0) {
|
||||
vec3 pp = ro + rd*pd;
|
||||
|
||||
vec4 pcol = planeCol(ro, rd, nz+float(i), pp);
|
||||
float fadeIn = 1.0-smoothstep(planeDist*float(fadeFrom), planeDist*float(furthest), pp.z-ro.z);
|
||||
pcol.xyz *= sqrt(fadeIn);
|
||||
|
||||
col = alphaBlend(col, pcol);
|
||||
}
|
||||
}
|
||||
|
||||
return col.xyz*col.w;
|
||||
}
|
||||
|
||||
vec3 postProcess(vec3 col, vec2 q) {
|
||||
col=pow(clamp(col,0.0,1.0),vec3(0.75));
|
||||
col=col*0.6+0.4*col*col*(3.0-2.0*col);
|
||||
col=mix(col, vec3(dot(col, vec3(0.33))), -0.4);
|
||||
col*=0.5+0.5*pow(19.0*q.x*q.y*(1.0-q.x)*(1.0-q.y),0.7);
|
||||
return col;
|
||||
}
|
||||
|
||||
vec3 effect(vec2 p, vec2 q) {
|
||||
float tm = TIME*0.65;
|
||||
|
||||
vec3 ro = offset(tm);
|
||||
vec3 dro = doffset(tm);
|
||||
vec3 ddro = ddoffset(tm);
|
||||
|
||||
vec3 ww = normalize(dro);
|
||||
vec3 uu = normalize(cross(vec3(0.0,1.0,0.0)+1.5*ddro, ww));
|
||||
vec3 vv = normalize(cross(ww, uu));
|
||||
|
||||
vec3 col = color(ww, uu, vv, ro, p);
|
||||
col = postProcess(col, q);
|
||||
|
||||
const float fadeIn = 2.0;
|
||||
|
||||
return col*smoothstep(0.0, fadeIn, TIME);
|
||||
}
|
||||
|
||||
void mainImage(out vec4 fragColor, vec2 fragCoord) {
|
||||
vec2 q = fragCoord/RESOLUTION.xy;
|
||||
vec2 p = -1. + 2. * q;
|
||||
p.x *= RESOLUTION.x/RESOLUTION.y;
|
||||
|
||||
vec3 col = effect(p, q);
|
||||
|
||||
fragColor = vec4(col, 1.0);
|
||||
}
|
@@ -305,7 +305,7 @@ create_gear (GLfloat inner_radius,
|
||||
/* Create the 7 points (only x,y coords) used to draw a tooth */
|
||||
struct point p[7];
|
||||
|
||||
/* Calculate needed sin/cos for varius angles */
|
||||
/* Calculate needed sin/cos for various angles */
|
||||
sincos(i * 2.0 * G_PI / teeth + da * 0, &s[0], &c[0]);
|
||||
sincos(i * 2.0 * M_PI / teeth + da * 1, &s[1], &c[1]);
|
||||
sincos(i * 2.0 * M_PI / teeth + da * 2, &s[2], &c[2]);
|
||||
@@ -800,7 +800,7 @@ gtk_gears_realize (GtkWidget *widget)
|
||||
priv->LightSourcePosition_location = glGetUniformLocation(program, "LightSourcePosition");
|
||||
priv->MaterialColor_location = glGetUniformLocation(program, "MaterialColor");
|
||||
|
||||
/* Set the LightSourcePosition uniform which is constant throught the program */
|
||||
/* Set the LightSourcePosition uniform which is constant throughout the program */
|
||||
glUniform4fv(priv->LightSourcePosition_location, 1, priv->LightSourcePosition);
|
||||
|
||||
/* make the gears */
|
||||
|
524
demos/gtk-demo/gtkshadertoy.c
Normal file
524
demos/gtk-demo/gtkshadertoy.c
Normal file
@@ -0,0 +1,524 @@
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <epoxy/gl.h>
|
||||
|
||||
#include "gtkshadertoy.h"
|
||||
|
||||
const char *default_image_shader =
|
||||
"void mainImage(out vec4 fragColor, in vec2 fragCoord) {\n"
|
||||
" // Normalized pixel coordinates (from 0 to 1)\n"
|
||||
" vec2 uv = fragCoord/iResolution.xy;\n"
|
||||
"\n"
|
||||
" // Time varying pixel color\n"
|
||||
" vec3 col = 0.5 + 0.5*cos(iTime+uv.xyx+vec3(0,2,4));\n"
|
||||
"\n"
|
||||
" if (distance(iMouse.xy, fragCoord.xy) <= 10.0) {\n"
|
||||
" col = vec3(0.0);\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" // Output to screen\n"
|
||||
" fragColor = vec4(col,1.0);\n"
|
||||
"}\n";
|
||||
|
||||
const char *shadertoy_vertex_shader =
|
||||
"#version 150 core\n"
|
||||
"\n"
|
||||
"uniform vec3 iResolution;\n"
|
||||
"\n"
|
||||
"in vec2 position;\n"
|
||||
"out vec2 fragCoord;\n"
|
||||
"\n"
|
||||
"void main() {\n"
|
||||
" gl_Position = vec4(position, 0.0, 1.0);\n"
|
||||
"\n"
|
||||
" // Convert from OpenGL coordinate system (with origin in center\n"
|
||||
" // of screen) to Shadertoy/texture coordinate system (with origin\n"
|
||||
" // in lower left corner)\n"
|
||||
" fragCoord = (gl_Position.xy + vec2(1.0)) / vec2(2.0) * iResolution.xy;\n"
|
||||
"}\n";
|
||||
|
||||
const char *fragment_prefix =
|
||||
"#version 150 core\n"
|
||||
"\n"
|
||||
"uniform vec3 iResolution; // viewport resolution (in pixels)\n"
|
||||
"uniform float iTime; // shader playback time (in seconds)\n"
|
||||
"uniform float iTimeDelta; // render time (in seconds)\n"
|
||||
"uniform int iFrame; // shader playback frame\n"
|
||||
"uniform float iChannelTime[4]; // channel playback time (in seconds)\n"
|
||||
"uniform vec3 iChannelResolution[4]; // channel resolution (in pixels)\n"
|
||||
"uniform vec4 iMouse; // mouse pixel coords. xy: current (if MLB down), zw: click\n"
|
||||
"uniform sampler2D iChannel0;\n"
|
||||
"uniform sampler2D iChannel1;\n"
|
||||
"uniform sampler2D iChannel2;\n"
|
||||
"uniform sampler2D iChannel3;\n"
|
||||
"uniform vec4 iDate; // (year, month, day, time in seconds)\n"
|
||||
"uniform float iSampleRate; // sound sample rate (i.e., 44100)\n"
|
||||
"\n"
|
||||
"in vec2 fragCoord;\n"
|
||||
"out vec4 fragColor;\n";
|
||||
|
||||
|
||||
// Fragment shader suffix
|
||||
const char *fragment_suffix =
|
||||
" void main() {\n"
|
||||
" mainImage(fragColor, fragCoord);\n"
|
||||
" }\n";
|
||||
|
||||
typedef struct {
|
||||
char *image_shader;
|
||||
gboolean image_shader_dirty;
|
||||
|
||||
gboolean error_set;
|
||||
|
||||
/* Vertex buffers */
|
||||
GLuint vao;
|
||||
GLuint buffer;
|
||||
|
||||
/* Active program */
|
||||
GLuint program;
|
||||
|
||||
/* Location of uniforms for program */
|
||||
GLuint resolution_location;
|
||||
GLuint time_location;
|
||||
GLuint timedelta_location;
|
||||
GLuint frame_location;
|
||||
GLuint mouse_location;
|
||||
|
||||
/* Current uniform values */
|
||||
float resolution[3];
|
||||
float time;
|
||||
float timedelta;
|
||||
float mouse[4];
|
||||
int frame;
|
||||
|
||||
/* Animation data */
|
||||
gint64 first_frame_time;
|
||||
gint64 first_frame;
|
||||
guint tick;
|
||||
} GtkShadertoyPrivate;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GtkShadertoy, gtk_shadertoy, GTK_TYPE_GL_AREA)
|
||||
|
||||
static gboolean gtk_shadertoy_render (GtkGLArea *area,
|
||||
GdkGLContext *context);
|
||||
static void gtk_shadertoy_reshape (GtkGLArea *area,
|
||||
int width,
|
||||
int height);
|
||||
static void gtk_shadertoy_realize (GtkWidget *widget);
|
||||
static void gtk_shadertoy_unrealize (GtkWidget *widget);
|
||||
static gboolean gtk_shadertoy_tick (GtkWidget *widget,
|
||||
GdkFrameClock *frame_clock,
|
||||
gpointer user_data);
|
||||
|
||||
GtkWidget *
|
||||
gtk_shadertoy_new (void)
|
||||
{
|
||||
return g_object_new (gtk_shadertoy_get_type (), NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
drag_begin_cb (GtkGestureDrag *drag,
|
||||
double x,
|
||||
double y,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkShadertoy *shadertoy = GTK_SHADERTOY (user_data);
|
||||
GtkShadertoyPrivate *priv = gtk_shadertoy_get_instance_private (shadertoy);
|
||||
int height = gtk_widget_get_height (GTK_WIDGET (shadertoy));
|
||||
int scale = gtk_widget_get_scale_factor (GTK_WIDGET (shadertoy));
|
||||
|
||||
priv->mouse[0] = x * scale;
|
||||
priv->mouse[1] = (height - y) * scale;
|
||||
priv->mouse[2] = priv->mouse[0];
|
||||
priv->mouse[3] = priv->mouse[1];
|
||||
}
|
||||
|
||||
static void
|
||||
drag_update_cb (GtkGestureDrag *drag,
|
||||
double dx,
|
||||
double dy,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkShadertoy *shadertoy = GTK_SHADERTOY (user_data);
|
||||
GtkShadertoyPrivate *priv = gtk_shadertoy_get_instance_private (shadertoy);
|
||||
int width = gtk_widget_get_width (GTK_WIDGET (shadertoy));
|
||||
int height = gtk_widget_get_height (GTK_WIDGET (shadertoy));
|
||||
int scale = gtk_widget_get_scale_factor (GTK_WIDGET (shadertoy));
|
||||
double x, y;
|
||||
|
||||
gtk_gesture_drag_get_start_point (drag, &x, &y);
|
||||
x += dx;
|
||||
y += dy;
|
||||
|
||||
if (x >= 0 && x < width &&
|
||||
y >= 0 && y < height)
|
||||
{
|
||||
priv->mouse[0] = x * scale;
|
||||
priv->mouse[1] = (height - y) * scale;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
drag_end_cb (GtkGestureDrag *drag,
|
||||
gdouble dx,
|
||||
gdouble dy,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkShadertoy *shadertoy = GTK_SHADERTOY (user_data);
|
||||
GtkShadertoyPrivate *priv = gtk_shadertoy_get_instance_private (shadertoy);
|
||||
|
||||
priv->mouse[2] = -priv->mouse[2];
|
||||
priv->mouse[3] = -priv->mouse[3];
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_shadertoy_init (GtkShadertoy *shadertoy)
|
||||
{
|
||||
GtkShadertoyPrivate *priv = gtk_shadertoy_get_instance_private (shadertoy);
|
||||
GtkGesture *drag;
|
||||
|
||||
priv->image_shader = g_strdup (default_image_shader);
|
||||
priv->tick = gtk_widget_add_tick_callback (GTK_WIDGET (shadertoy), gtk_shadertoy_tick, shadertoy, NULL);
|
||||
|
||||
drag = gtk_gesture_drag_new ();
|
||||
gtk_widget_add_controller (GTK_WIDGET (shadertoy), GTK_EVENT_CONTROLLER (drag));
|
||||
g_signal_connect (drag, "drag-begin", (GCallback)drag_begin_cb, shadertoy);
|
||||
g_signal_connect (drag, "drag-update", (GCallback)drag_update_cb, shadertoy);
|
||||
g_signal_connect (drag, "drag-end", (GCallback)drag_end_cb, shadertoy);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_shadertoy_finalize (GObject *obj)
|
||||
{
|
||||
GtkShadertoy *shadertoy = GTK_SHADERTOY (obj);
|
||||
GtkShadertoyPrivate *priv = gtk_shadertoy_get_instance_private (shadertoy);
|
||||
|
||||
gtk_widget_remove_tick_callback (GTK_WIDGET (shadertoy), priv->tick);
|
||||
g_free (priv->image_shader);
|
||||
|
||||
G_OBJECT_CLASS (gtk_shadertoy_parent_class)->finalize (obj);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_shadertoy_class_init (GtkShadertoyClass *klass)
|
||||
{
|
||||
GTK_GL_AREA_CLASS (klass)->render = gtk_shadertoy_render;
|
||||
GTK_GL_AREA_CLASS (klass)->resize = gtk_shadertoy_reshape;
|
||||
|
||||
GTK_WIDGET_CLASS (klass)->realize = gtk_shadertoy_realize;
|
||||
GTK_WIDGET_CLASS (klass)->unrealize = gtk_shadertoy_unrealize;
|
||||
|
||||
G_OBJECT_CLASS (klass)->finalize = gtk_shadertoy_finalize;
|
||||
}
|
||||
|
||||
/* new window size or exposure */
|
||||
static void
|
||||
gtk_shadertoy_reshape (GtkGLArea *area, int width, int height)
|
||||
{
|
||||
GtkShadertoyPrivate *priv = gtk_shadertoy_get_instance_private ((GtkShadertoy *) area);
|
||||
|
||||
priv->resolution[0] = width;
|
||||
priv->resolution[1] = height;
|
||||
priv->resolution[2] = 1.0; /* screen aspect ratio */
|
||||
|
||||
/* Set the viewport */
|
||||
glViewport (0, 0, (GLint) width, (GLint) height);
|
||||
}
|
||||
|
||||
static GLuint
|
||||
create_shader (int type,
|
||||
const char *src,
|
||||
GError **error)
|
||||
{
|
||||
GLuint shader;
|
||||
int status;
|
||||
|
||||
shader = glCreateShader (type);
|
||||
glShaderSource (shader, 1, &src, NULL);
|
||||
glCompileShader (shader);
|
||||
|
||||
glGetShaderiv (shader, GL_COMPILE_STATUS, &status);
|
||||
if (status == GL_FALSE)
|
||||
{
|
||||
int log_len;
|
||||
char *buffer;
|
||||
|
||||
glGetShaderiv (shader, GL_INFO_LOG_LENGTH, &log_len);
|
||||
|
||||
buffer = g_malloc (log_len + 1);
|
||||
glGetShaderInfoLog (shader, log_len, NULL, buffer);
|
||||
|
||||
g_set_error (error, GDK_GL_ERROR, GDK_GL_ERROR_COMPILATION_FAILED,
|
||||
"Compile failure in %s shader:\n%s",
|
||||
type == GL_VERTEX_SHADER ? "vertex" : "fragment",
|
||||
buffer);
|
||||
|
||||
g_free (buffer);
|
||||
|
||||
glDeleteShader (shader);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
init_shaders (GtkShadertoy *shadertoy,
|
||||
const char *vertex_source,
|
||||
const char *fragment_source,
|
||||
GError **error)
|
||||
{
|
||||
GtkShadertoyPrivate *priv = gtk_shadertoy_get_instance_private (shadertoy);
|
||||
GLuint vertex, fragment;
|
||||
GLuint program = 0;
|
||||
int status;
|
||||
gboolean res = TRUE;
|
||||
|
||||
vertex = create_shader (GL_VERTEX_SHADER, vertex_source, error);
|
||||
if (vertex == 0)
|
||||
return FALSE;
|
||||
|
||||
fragment = create_shader (GL_FRAGMENT_SHADER, fragment_source, error);
|
||||
if (fragment == 0)
|
||||
{
|
||||
glDeleteShader (vertex);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
program = glCreateProgram ();
|
||||
glAttachShader (program, vertex);
|
||||
glAttachShader (program, fragment);
|
||||
|
||||
glLinkProgram (program);
|
||||
|
||||
glGetProgramiv (program, GL_LINK_STATUS, &status);
|
||||
if (status == GL_FALSE)
|
||||
{
|
||||
int log_len;
|
||||
char *buffer;
|
||||
|
||||
glGetProgramiv (program, GL_INFO_LOG_LENGTH, &log_len);
|
||||
|
||||
buffer = g_malloc (log_len + 1);
|
||||
glGetProgramInfoLog (program, log_len, NULL, buffer);
|
||||
|
||||
g_set_error (error, GDK_GL_ERROR, GDK_GL_ERROR_LINK_FAILED,
|
||||
"Linking failure:\n%s", buffer);
|
||||
res = FALSE;
|
||||
|
||||
g_free (buffer);
|
||||
|
||||
glDeleteProgram (program);
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (priv->program != 0)
|
||||
glDeleteProgram (priv->program);
|
||||
|
||||
priv->program = program;
|
||||
priv->resolution_location = glGetUniformLocation (program, "iResolution");
|
||||
priv->time_location = glGetUniformLocation (program, "iTime");
|
||||
priv->timedelta_location = glGetUniformLocation (program, "iTimeDelta");
|
||||
priv->frame_location = glGetUniformLocation (program, "iFrame");
|
||||
priv->mouse_location = glGetUniformLocation (program, "iMouse");
|
||||
|
||||
glDetachShader (program, vertex);
|
||||
glDetachShader (program, fragment);
|
||||
|
||||
out:
|
||||
/* These are now owned by the program and can be deleted */
|
||||
glDeleteShader (vertex);
|
||||
glDeleteShader (fragment);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_shadertoy_realize_shader (GtkShadertoy *shadertoy)
|
||||
{
|
||||
GtkShadertoyPrivate *priv = gtk_shadertoy_get_instance_private (shadertoy);
|
||||
char *fragment_shader;
|
||||
GError *error = NULL;
|
||||
|
||||
fragment_shader = g_strconcat (fragment_prefix, priv->image_shader, fragment_suffix, NULL);
|
||||
if (!init_shaders (shadertoy, shadertoy_vertex_shader, fragment_shader, &error))
|
||||
{
|
||||
priv->error_set = TRUE;
|
||||
gtk_gl_area_set_error (GTK_GL_AREA (shadertoy), error);
|
||||
g_error_free (error);
|
||||
}
|
||||
g_free (fragment_shader);
|
||||
|
||||
/* Start new shader at time zero */
|
||||
priv->first_frame_time = 0;
|
||||
priv->first_frame = 0;
|
||||
|
||||
priv->image_shader_dirty = FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_shadertoy_render (GtkGLArea *area,
|
||||
GdkGLContext *context)
|
||||
{
|
||||
GtkShadertoy *shadertoy = GTK_SHADERTOY (area);
|
||||
GtkShadertoyPrivate *priv = gtk_shadertoy_get_instance_private (shadertoy);
|
||||
|
||||
if (gtk_gl_area_get_error (area) != NULL)
|
||||
return FALSE;
|
||||
|
||||
if (priv->image_shader_dirty)
|
||||
gtk_shadertoy_realize_shader (shadertoy);
|
||||
|
||||
/* Clear the viewport */
|
||||
glClearColor (0.0, 0.0, 0.0, 1.0);
|
||||
glClear (GL_COLOR_BUFFER_BIT);
|
||||
|
||||
glUseProgram (priv->program);
|
||||
|
||||
/* Update uniforms */
|
||||
if (priv->resolution_location != -1)
|
||||
glUniform3fv (priv->resolution_location, 1, priv->resolution);
|
||||
if (priv->time_location != -1)
|
||||
glUniform1f (priv->time_location, priv->time);
|
||||
if (priv->timedelta_location != -1)
|
||||
glUniform1f (priv->timedelta_location, priv->timedelta);
|
||||
if (priv->frame_location != -1)
|
||||
glUniform1i (priv->frame_location, priv->frame);
|
||||
if (priv->mouse_location != -1)
|
||||
glUniform4fv (priv->mouse_location, 1, priv->mouse);
|
||||
|
||||
/* Use the vertices in our buffer */
|
||||
glBindBuffer (GL_ARRAY_BUFFER, priv->buffer);
|
||||
glEnableVertexAttribArray (0);
|
||||
glVertexAttribPointer (0, 4, GL_FLOAT, GL_FALSE, 0, 0);
|
||||
|
||||
glDrawArrays (GL_TRIANGLES, 0, 6);
|
||||
|
||||
/* We finished using the buffers and program */
|
||||
glDisableVertexAttribArray (0);
|
||||
glBindBuffer (GL_ARRAY_BUFFER, 0);
|
||||
glUseProgram (0);
|
||||
|
||||
/* Flush the contents of the pipeline */
|
||||
glFlush ();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
const char *
|
||||
gtk_shadertoy_get_image_shader (GtkShadertoy *shadertoy)
|
||||
{
|
||||
GtkShadertoyPrivate *priv = gtk_shadertoy_get_instance_private (shadertoy);
|
||||
|
||||
return priv->image_shader;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_shadertoy_set_image_shader (GtkShadertoy *shadertoy,
|
||||
const char *shader)
|
||||
{
|
||||
GtkShadertoyPrivate *priv = gtk_shadertoy_get_instance_private (shadertoy);
|
||||
|
||||
g_free (priv->image_shader);
|
||||
priv->image_shader = g_strdup (shader);
|
||||
|
||||
/* Don't override error we didn't set it ourselves */
|
||||
if (priv->error_set)
|
||||
{
|
||||
gtk_gl_area_set_error (GTK_GL_AREA (shadertoy), NULL);
|
||||
priv->error_set = FALSE;
|
||||
}
|
||||
priv->image_shader_dirty = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_shadertoy_realize (GtkWidget *widget)
|
||||
{
|
||||
GtkGLArea *glarea = GTK_GL_AREA (widget);
|
||||
GtkShadertoy *shadertoy = GTK_SHADERTOY (widget);
|
||||
GtkShadertoyPrivate *priv = gtk_shadertoy_get_instance_private (shadertoy);
|
||||
|
||||
/* Draw two triangles across whole screen */
|
||||
const GLfloat vertex_data[] = {
|
||||
-1.0f, -1.0f, 0.f, 1.f,
|
||||
-1.0f, 1.0f, 0.f, 1.f,
|
||||
1.0f, 1.0f, 0.f, 1.f,
|
||||
|
||||
-1.0f, -1.0f, 0.f, 1.f,
|
||||
1.0f, 1.0f, 0.f, 1.f,
|
||||
1.0f, -1.0f, 0.f, 1.f,
|
||||
};
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_shadertoy_parent_class)->realize (widget);
|
||||
|
||||
gtk_gl_area_make_current (glarea);
|
||||
if (gtk_gl_area_get_error (glarea) != NULL)
|
||||
return;
|
||||
|
||||
glGenVertexArrays (1, &priv->vao);
|
||||
glBindVertexArray (priv->vao);
|
||||
|
||||
glGenBuffers (1, &priv->buffer);
|
||||
glBindBuffer (GL_ARRAY_BUFFER, priv->buffer);
|
||||
glBufferData (GL_ARRAY_BUFFER, sizeof (vertex_data), vertex_data, GL_STATIC_DRAW);
|
||||
glBindBuffer (GL_ARRAY_BUFFER, 0);
|
||||
|
||||
gtk_shadertoy_realize_shader (shadertoy);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_shadertoy_unrealize (GtkWidget *widget)
|
||||
{
|
||||
GtkGLArea *glarea = GTK_GL_AREA (widget);
|
||||
GtkShadertoyPrivate *priv = gtk_shadertoy_get_instance_private ((GtkShadertoy *) widget);
|
||||
|
||||
gtk_gl_area_make_current (glarea);
|
||||
if (gtk_gl_area_get_error (glarea) == NULL)
|
||||
{
|
||||
if (priv->buffer != 0)
|
||||
glDeleteBuffers (1, &priv->buffer);
|
||||
|
||||
if (priv->vao != 0)
|
||||
glDeleteVertexArrays (1, &priv->vao);
|
||||
|
||||
if (priv->program != 0)
|
||||
glDeleteProgram (priv->program);
|
||||
}
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_shadertoy_parent_class)->unrealize (widget);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_shadertoy_tick (GtkWidget *widget,
|
||||
GdkFrameClock *frame_clock,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkShadertoy *shadertoy = GTK_SHADERTOY (widget);
|
||||
GtkShadertoyPrivate *priv = gtk_shadertoy_get_instance_private (shadertoy);
|
||||
gint64 frame_time;
|
||||
gint64 frame;
|
||||
float previous_time;
|
||||
|
||||
frame = gdk_frame_clock_get_frame_counter (frame_clock);
|
||||
frame_time = gdk_frame_clock_get_frame_time (frame_clock);
|
||||
|
||||
if (priv->first_frame_time == 0)
|
||||
{
|
||||
priv->first_frame_time = frame_time;
|
||||
priv->first_frame = frame;
|
||||
previous_time = 0;
|
||||
}
|
||||
else
|
||||
previous_time = priv->time;
|
||||
|
||||
priv->time = (frame_time - priv->first_frame_time) / 1000000.0f;
|
||||
priv->frame = frame - priv->first_frame;
|
||||
priv->timedelta = priv->time - previous_time;
|
||||
|
||||
gtk_widget_queue_draw (widget);
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
34
demos/gtk-demo/gtkshadertoy.h
Normal file
34
demos/gtk-demo/gtkshadertoy.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#ifndef __GTK_SHADERTOY_H__
|
||||
#define __GTK_SHADERTOY_H__
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_SHADERTOY (gtk_shadertoy_get_type ())
|
||||
#define GTK_SHADERTOY(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \
|
||||
GTK_TYPE_SHADERTOY, \
|
||||
GtkShadertoy))
|
||||
#define GTK_IS_SHADERTOY(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \
|
||||
GTK_TYPE_SHADERTOY))
|
||||
|
||||
typedef struct _GtkShadertoy GtkShadertoy;
|
||||
typedef struct _GtkShadertoyClass GtkShadertoyClass;
|
||||
|
||||
struct _GtkShadertoy {
|
||||
GtkGLArea parent;
|
||||
};
|
||||
|
||||
struct _GtkShadertoyClass {
|
||||
GtkGLAreaClass parent_class;
|
||||
};
|
||||
|
||||
GType gtk_shadertoy_get_type (void) G_GNUC_CONST;
|
||||
GtkWidget *gtk_shadertoy_new (void);
|
||||
const char *gtk_shadertoy_get_image_shader (GtkShadertoy *shadertoy);
|
||||
void gtk_shadertoy_set_image_shader (GtkShadertoy *shadertoy,
|
||||
const char *shader);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_SHADERTOY_H__ */
|
@@ -75,10 +75,10 @@ populate_icons (void)
|
||||
static char *content;
|
||||
static gsize content_len;
|
||||
|
||||
extern void fontify (GtkTextBuffer *buffer);
|
||||
extern void fontify (const char *format, GtkTextBuffer *buffer);
|
||||
|
||||
static void
|
||||
populate_text (gboolean hilight)
|
||||
populate_text (gboolean highlight)
|
||||
{
|
||||
GtkWidget *textview;
|
||||
GtkTextBuffer *buffer;
|
||||
@@ -94,8 +94,8 @@ populate_text (gboolean hilight)
|
||||
buffer = gtk_text_buffer_new (NULL);
|
||||
gtk_text_buffer_set_text (buffer, content, (int)content_len);
|
||||
|
||||
if (hilight)
|
||||
fontify (buffer);
|
||||
if (highlight)
|
||||
fontify ("c", buffer);
|
||||
|
||||
textview = gtk_text_view_new ();
|
||||
gtk_text_view_set_buffer (GTK_TEXT_VIEW (textview), buffer);
|
||||
@@ -153,14 +153,20 @@ populate_list (void)
|
||||
}
|
||||
|
||||
extern GtkWidget *create_color_grid (void);
|
||||
extern GListModel *gtk_color_list_new (guint size);
|
||||
|
||||
static void
|
||||
populate_grid (void)
|
||||
{
|
||||
GtkWidget *list;
|
||||
GtkNoSelection *selection;
|
||||
|
||||
list = create_color_grid ();
|
||||
|
||||
selection = gtk_no_selection_new (gtk_color_list_new (2097152));
|
||||
gtk_grid_view_set_model (GTK_GRID_VIEW (list), GTK_SELECTION_MODEL (selection));
|
||||
g_object_unref (selection);
|
||||
|
||||
hincrement = 0;
|
||||
vincrement = 5;
|
||||
|
||||
|
@@ -240,11 +240,11 @@ progressive_timeout (gpointer data)
|
||||
|
||||
pixbuf_loader = gdk_pixbuf_loader_new ();
|
||||
|
||||
g_signal_connect (pixbuf_loader, "area-prepared",
|
||||
G_CALLBACK (progressive_prepared_callback), picture);
|
||||
g_signal_connect_object (pixbuf_loader, "area-prepared",
|
||||
G_CALLBACK (progressive_prepared_callback), picture, 0);
|
||||
|
||||
g_signal_connect (pixbuf_loader, "area-updated",
|
||||
G_CALLBACK (progressive_updated_callback), picture);
|
||||
g_signal_connect_object (pixbuf_loader, "area-updated",
|
||||
G_CALLBACK (progressive_updated_callback), picture, 0);
|
||||
}
|
||||
|
||||
/* leave timeout installed */
|
||||
@@ -261,14 +261,16 @@ start_progressive_loading (GtkWidget *picture)
|
||||
* The timeout simply simulates a slow data source by inserting
|
||||
* pauses in the reading process.
|
||||
*/
|
||||
load_timeout = g_timeout_add (150, progressive_timeout, picture);
|
||||
load_timeout = g_timeout_add (1500, progressive_timeout, picture);
|
||||
g_source_set_name_by_id (load_timeout, "[gtk] progressive_timeout");
|
||||
}
|
||||
|
||||
static void
|
||||
cleanup_callback (GObject *object,
|
||||
gpointer data)
|
||||
cleanup_callback (gpointer data,
|
||||
GObject *former_object)
|
||||
{
|
||||
*(gpointer**)data = NULL;
|
||||
|
||||
if (load_timeout)
|
||||
{
|
||||
g_source_remove (load_timeout);
|
||||
@@ -327,10 +329,7 @@ do_images (GtkWidget *do_widget)
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Images");
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
|
||||
g_signal_connect (window, "destroy",
|
||||
G_CALLBACK (cleanup_callback), NULL);
|
||||
g_object_weak_ref (G_OBJECT (window), cleanup_callback, &window);
|
||||
|
||||
base_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 8);
|
||||
gtk_widget_set_margin_start (base_vbox, 16);
|
||||
|
62
demos/gtk-demo/layoutmanager.c
Normal file
62
demos/gtk-demo/layoutmanager.c
Normal file
@@ -0,0 +1,62 @@
|
||||
/* Layout Manager/Transition
|
||||
*
|
||||
* This demo shows a simple example of a custom layout manager
|
||||
* and a widget using it. The layout manager places the children
|
||||
* of the widget in a grid or a circle.
|
||||
*
|
||||
* The widget is animating the transition between the two layouts.
|
||||
*
|
||||
* Click to start the transition.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "demowidget.h"
|
||||
#include "demochild.h"
|
||||
|
||||
|
||||
GtkWidget *
|
||||
do_layoutmanager (GtkWidget *parent)
|
||||
{
|
||||
static GtkWidget *window = NULL;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
GtkWidget *child;
|
||||
const char *color[] = {
|
||||
"red", "orange", "yellow", "green",
|
||||
"blue", "grey", "magenta", "lime",
|
||||
"yellow", "firebrick", "aqua", "purple",
|
||||
"tomato", "pink", "thistle", "maroon"
|
||||
};
|
||||
int i;
|
||||
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Layout Manager—Transition");
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 600, 600);
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
|
||||
widget = demo_widget_new ();
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
child = demo_child_new (color[i]);
|
||||
gtk_widget_set_margin_start (child, 4);
|
||||
gtk_widget_set_margin_end (child, 4);
|
||||
gtk_widget_set_margin_top (child, 4);
|
||||
gtk_widget_set_margin_bottom (child, 4);
|
||||
demo_widget_add_child (DEMO_WIDGET (widget), child);
|
||||
}
|
||||
|
||||
gtk_window_set_child (GTK_WINDOW (window), widget);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
|
||||
return window;
|
||||
|
||||
}
|
198
demos/gtk-demo/layoutmanager2.c
Normal file
198
demos/gtk-demo/layoutmanager2.c
Normal file
@@ -0,0 +1,198 @@
|
||||
/* Layout Manager/Transformation
|
||||
*
|
||||
* This demo shows how to use transforms in a nontrivial
|
||||
* way with a custom layout manager. The layout manager places
|
||||
* icons on a sphere that can be rotated using arrow keys.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "demo2widget.h"
|
||||
#include "demo2layout.h"
|
||||
#include "demochild.h"
|
||||
|
||||
GtkWidget *
|
||||
do_layoutmanager2 (GtkWidget *parent)
|
||||
{
|
||||
static GtkWidget *window = NULL;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
GtkWidget *child;
|
||||
const char *name[] = {
|
||||
"action-unavailable-symbolic",
|
||||
"address-book-new-symbolic",
|
||||
"application-exit-symbolic",
|
||||
"appointment-new-symbolic",
|
||||
"bookmark-new-symbolic",
|
||||
"call-start-symbolic",
|
||||
"call-stop-symbolic",
|
||||
"camera-switch-symbolic",
|
||||
"chat-message-new-symbolic",
|
||||
"color-select-symbolic",
|
||||
"contact-new-symbolic",
|
||||
"document-edit-symbolic",
|
||||
"document-new-symbolic",
|
||||
"document-open-recent-symbolic",
|
||||
"document-open-symbolic",
|
||||
"document-page-setup-symbolic",
|
||||
"document-print-preview-symbolic",
|
||||
"document-print-symbolic",
|
||||
"document-properties-symbolic",
|
||||
"document-revert-symbolic-rtl",
|
||||
"document-revert-symbolic",
|
||||
"document-save-as-symbolic",
|
||||
"document-save-symbolic",
|
||||
"document-send-symbolic",
|
||||
"edit-clear-all-symbolic",
|
||||
"edit-clear-symbolic-rtl",
|
||||
"edit-clear-symbolic",
|
||||
"edit-copy-symbolic",
|
||||
"edit-cut-symbolic",
|
||||
"edit-delete-symbolic",
|
||||
"edit-find-replace-symbolic",
|
||||
"edit-find-symbolic",
|
||||
"edit-paste-symbolic",
|
||||
"edit-redo-symbolic-rtl",
|
||||
"edit-redo-symbolic",
|
||||
"edit-select-all-symbolic",
|
||||
"edit-select-symbolic",
|
||||
"edit-undo-symbolic-rtl",
|
||||
"edit-undo-symbolic",
|
||||
"error-correct-symbolic",
|
||||
"find-location-symbolic",
|
||||
"folder-new-symbolic",
|
||||
"font-select-symbolic",
|
||||
"format-indent-less-symbolic-rtl",
|
||||
"format-indent-less-symbolic",
|
||||
"format-indent-more-symbolic-rtl",
|
||||
"format-indent-more-symbolic",
|
||||
"format-justify-center-symbolic",
|
||||
"format-justify-fill-symbolic",
|
||||
"format-justify-left-symbolic",
|
||||
"format-justify-right-symbolic",
|
||||
"format-text-bold-symbolic",
|
||||
"format-text-direction-symbolic-rtl",
|
||||
"format-text-direction-symbolic",
|
||||
"format-text-italic-symbolic",
|
||||
"format-text-strikethrough-symbolic",
|
||||
"format-text-underline-symbolic",
|
||||
"go-bottom-symbolic",
|
||||
"go-down-symbolic",
|
||||
"go-first-symbolic-rtl",
|
||||
"go-first-symbolic",
|
||||
"go-home-symbolic",
|
||||
"go-jump-symbolic-rtl",
|
||||
"go-jump-symbolic",
|
||||
"go-last-symbolic-rtl",
|
||||
"go-last-symbolic",
|
||||
"go-next-symbolic-rtl",
|
||||
"go-next-symbolic",
|
||||
"go-previous-symbolic-rtl",
|
||||
"go-previous-symbolic",
|
||||
"go-top-symbolic",
|
||||
"go-up-symbolic",
|
||||
"help-about-symbolic",
|
||||
"insert-image-symbolic",
|
||||
"insert-link-symbolic",
|
||||
"insert-object-symbolic",
|
||||
"insert-text-symbolic",
|
||||
"list-add-symbolic",
|
||||
"list-remove-all-symbolic",
|
||||
"list-remove-symbolic",
|
||||
"mail-forward-symbolic",
|
||||
"mail-mark-important-symbolic",
|
||||
"mail-mark-junk-symbolic",
|
||||
"mail-mark-notjunk-symbolic",
|
||||
"mail-message-new-symbolic",
|
||||
"mail-reply-all-symbolic",
|
||||
"mail-reply-sender-symbolic",
|
||||
"mail-send-receive-symbolic",
|
||||
"mail-send-symbolic",
|
||||
"mark-location-symbolic",
|
||||
"media-eject-symbolic",
|
||||
"media-playback-pause-symbolic",
|
||||
"media-playback-start-symbolic",
|
||||
"media-playback-stop-symbolic",
|
||||
"media-record-symbolic",
|
||||
"media-seek-backward-symbolic",
|
||||
"media-seek-forward-symbolic",
|
||||
"media-skip-backward-symbolic",
|
||||
"media-skip-forward-symbolic",
|
||||
"media-view-subtitles-symbolic",
|
||||
"object-flip-horizontal-symbolic",
|
||||
"object-flip-vertical-symbolic",
|
||||
"object-rotate-left-symbolic",
|
||||
"object-rotate-right-symbolic",
|
||||
"object-select-symbolic",
|
||||
"open-menu-symbolic",
|
||||
"process-stop-symbolic",
|
||||
"send-to-symbolic",
|
||||
"sidebar-hide-symbolic",
|
||||
"sidebar-show-symbolic",
|
||||
"star-new-symbolic",
|
||||
"system-log-out-symbolic",
|
||||
"system-reboot-symbolic",
|
||||
"system-run-symbolic",
|
||||
"system-search-symbolic",
|
||||
"system-shutdown-symbolic",
|
||||
"system-switch-user-symbolic",
|
||||
"tab-new-symbolic",
|
||||
"tools-check-spelling-symbolic",
|
||||
"value-decrease-symbolic",
|
||||
"value-increase-symbolic",
|
||||
"view-app-grid-symbolic",
|
||||
"view-conceal-symbolic",
|
||||
"view-continuous-symbolic",
|
||||
"view-dual-symbolic",
|
||||
"view-fullscreen-symbolic",
|
||||
"view-grid-symbolic",
|
||||
"view-list-bullet-symbolic",
|
||||
"view-list-ordered-symbolic",
|
||||
"view-list-symbolic",
|
||||
"view-mirror-symbolic",
|
||||
"view-more-horizontal-symbolic",
|
||||
"view-more-symbolic",
|
||||
"view-paged-symbolic",
|
||||
"view-pin-symbolic",
|
||||
"view-refresh-symbolic",
|
||||
"view-restore-symbolic",
|
||||
"view-reveal-symbolic",
|
||||
"view-sort-ascending-symbolic",
|
||||
"view-sort-descending-symbolic",
|
||||
"zoom-fit-best-symbolic",
|
||||
"zoom-in-symbolic",
|
||||
"zoom-original-symbolic",
|
||||
"zoom-out-symbolic",
|
||||
};
|
||||
int i;
|
||||
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Layout Manager—Transformation");
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 600, 620);
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
|
||||
widget = demo2_widget_new ();
|
||||
|
||||
for (i = 0; i < 18 * 36; i++)
|
||||
{
|
||||
child = gtk_image_new_from_icon_name (name[i % G_N_ELEMENTS (name)]);
|
||||
gtk_widget_set_margin_start (child, 4);
|
||||
gtk_widget_set_margin_end (child, 4);
|
||||
gtk_widget_set_margin_top (child, 4);
|
||||
gtk_widget_set_margin_bottom (child, 4);
|
||||
demo2_widget_add_child (DEMO2_WIDGET (widget), child);
|
||||
}
|
||||
|
||||
gtk_window_set_child (GTK_WINDOW (window), widget);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
|
||||
return window;
|
||||
|
||||
}
|
@@ -47,7 +47,7 @@ static Bug bugs[] =
|
||||
{ FALSE, 56925, "Normal", "Gtkcalender size" },
|
||||
{ FALSE, 56221, "Normal", "Selectable label needs right-click copy menu" },
|
||||
{ TRUE, 50939, "Normal", "Add shift clicking to GtkTextView" },
|
||||
{ FALSE, 6112, "Enhancement","netscape-like collapsable toolbars" },
|
||||
{ FALSE, 6112, "Enhancement","netscape-like collapsible toolbars" },
|
||||
{ FALSE, 1, "Normal", "First bug :=)" },
|
||||
};
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
/* List Box
|
||||
/* List Box/Complex list
|
||||
*
|
||||
* GtkListBox allows lists with complicated layouts, using
|
||||
* regular widgets supporting sorting and filtering.
|
||||
|
71
demos/gtk-demo/listbox2.c
Normal file
71
demos/gtk-demo/listbox2.c
Normal file
@@ -0,0 +1,71 @@
|
||||
/* List Box/Controls
|
||||
*
|
||||
* GtkListBox is well-suited for creating “button strips” — lists of
|
||||
* controls for use in preference dialogs or settings panels. To create
|
||||
* this style of list, use the .rich-list style class.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
static GtkWidget *window;
|
||||
static GtkWidget *switch_widget;
|
||||
static GtkWidget *check;
|
||||
static GtkWidget *image;
|
||||
|
||||
static void
|
||||
row_activated (GtkListBox *list,
|
||||
GtkListBoxRow *row)
|
||||
{
|
||||
if (gtk_widget_is_ancestor (switch_widget, GTK_WIDGET (row)))
|
||||
{
|
||||
gtk_switch_set_active (GTK_SWITCH (switch_widget),
|
||||
!gtk_switch_get_active (GTK_SWITCH (switch_widget)));
|
||||
}
|
||||
else if (gtk_widget_is_ancestor (check, GTK_WIDGET (row)))
|
||||
{
|
||||
gtk_check_button_set_active (GTK_CHECK_BUTTON (check),
|
||||
!gtk_check_button_get_active (GTK_CHECK_BUTTON (check)));
|
||||
}
|
||||
else if (gtk_widget_is_ancestor (image, GTK_WIDGET (row)))
|
||||
{
|
||||
gtk_widget_set_opacity (image,
|
||||
1.0 - gtk_widget_get_opacity (image));
|
||||
}
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_listbox2 (GtkWidget *do_widget)
|
||||
{
|
||||
if (!window)
|
||||
{
|
||||
GtkBuilderScope *scope;
|
||||
GtkBuilder *builder;
|
||||
|
||||
scope = gtk_builder_cscope_new ();
|
||||
gtk_builder_cscope_add_callback_symbol (GTK_BUILDER_CSCOPE (scope),
|
||||
"row_activated", G_CALLBACK (row_activated));
|
||||
builder = gtk_builder_new ();
|
||||
gtk_builder_set_scope (builder, scope);
|
||||
|
||||
gtk_builder_add_from_resource (builder, "/listbox2/listbox2.ui", NULL);
|
||||
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
|
||||
switch_widget = GTK_WIDGET (gtk_builder_get_object (builder, "switch"));
|
||||
check = GTK_WIDGET (gtk_builder_get_object (builder, "check"));
|
||||
image = GTK_WIDGET (gtk_builder_get_object (builder, "image"));
|
||||
|
||||
g_object_unref (builder);
|
||||
g_object_unref (scope);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
|
||||
return window;
|
||||
}
|
298
demos/gtk-demo/listbox2.ui
Normal file
298
demos/gtk-demo/listbox2.ui
Normal file
@@ -0,0 +1,298 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<object class="GtkWindow" id="window">
|
||||
<property name="title" translatable="yes">List Box — Controls</property>
|
||||
<property name="default-height">400</property>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<property name="min-content-height">200</property>
|
||||
<property name="hexpand">0</property>
|
||||
<property name="vexpand">1</property>
|
||||
<child>
|
||||
<object class="GtkViewport">
|
||||
<property name="scroll-to-focus">1</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="margin-start">60</property>
|
||||
<property name="margin-end">60</property>
|
||||
<property name="margin-top">30</property>
|
||||
<property name="margin-bottom">30</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Group 1</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="margin-bottom">10</property>
|
||||
<style>
|
||||
<class name="title-2"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFrame">
|
||||
<child>
|
||||
<object class="GtkListBox">
|
||||
<property name="selection-mode">none</property>
|
||||
<property name="show-separators">1</property>
|
||||
<signal name="row-activated" handler="row_activated"/>
|
||||
<style>
|
||||
<class name="rich-list"/>
|
||||
</style>
|
||||
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel" id="switch_label">
|
||||
<property name="label" translatable="yes">Switch</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="switch">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel" id="check_label">
|
||||
<property name="label" translatable="yes">Check</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="check">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="margin-start">10</property>
|
||||
<property name="margin-end">10</property>
|
||||
<property name="active">1</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel" id="image_label">
|
||||
<property name="label" translatable="yes">Click here!</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage" id="image">
|
||||
<property name="icon-name">object-select-symbolic</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="margin-start">10</property>
|
||||
<property name="margin-end">10</property>
|
||||
<property name="opacity">0</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="margin-top">30</property>
|
||||
<property name="margin-bottom">10</property>
|
||||
<property name="label">Group 2</property>
|
||||
<property name="xalign">0</property>
|
||||
<style>
|
||||
<class name="title-2"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFrame">
|
||||
<child>
|
||||
<object class="GtkListBox">
|
||||
<property name="selection-mode">none</property>
|
||||
<property name="show-separators">1</property>
|
||||
<style>
|
||||
<class name="rich-list"/>
|
||||
</style>
|
||||
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<property name="activatable">0</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel" id="scale_label">
|
||||
<property name="label" translatable="yes">Scale</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScale">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="draw-value">0</property>
|
||||
<property name="width-request">150</property>
|
||||
<property name="adjustment">
|
||||
<object class="GtkAdjustment">
|
||||
<property name="upper">100</property>
|
||||
<property name="value">50</property>
|
||||
<property name="step-increment">1</property>
|
||||
<property name="page-increment">10</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<property name="activatable">0</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel" id="spin_label">
|
||||
<property name="label" translatable="yes">Spinbutton</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSpinButton">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="adjustment">
|
||||
<object class="GtkAdjustment">
|
||||
<property name="upper">100</property>
|
||||
<property name="value">50</property>
|
||||
<property name="step-increment">1</property>
|
||||
<property name="page-increment">10</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<property name="activatable">0</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel" id="dropdown_label">
|
||||
<property name="label" translatable="yes">Dropdown</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkDropDown">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="model">
|
||||
<object class="GtkStringList">
|
||||
<items>
|
||||
<item>Choice 1</item>
|
||||
<item>Choice 2</item>
|
||||
<item>Choice 3</item>
|
||||
<item>Choice 4</item>
|
||||
</items>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkListBoxRow">
|
||||
<property name="activatable">0</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkLabel" id="entry_label">
|
||||
<property name="label" translatable="yes">Entry</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry">
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="placeholder-text">Type here…</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkSizeGroup">
|
||||
<property name="mode">horizontal</property>
|
||||
<widgets>
|
||||
<widget name="switch_label"/>
|
||||
<widget name="check_label"/>
|
||||
<widget name="image_label"/>
|
||||
<widget name="scale_label"/>
|
||||
<widget name="spin_label"/>
|
||||
<widget name="dropdown_label"/>
|
||||
<widget name="entry_label"/>
|
||||
</widgets>
|
||||
</object>
|
||||
</interface>
|
@@ -104,7 +104,7 @@ activate_cb (GtkListView *list,
|
||||
GdkAppLaunchContext *context;
|
||||
GError *error = NULL;
|
||||
|
||||
app_info = g_list_model_get_item (gtk_list_view_get_model (list), position);
|
||||
app_info = g_list_model_get_item (G_LIST_MODEL (gtk_list_view_get_model (list)), position);
|
||||
|
||||
/* Prepare the context for launching the application and launch it. This
|
||||
* code is explained in detail in the documentation for #GdkAppLaunchContext
|
||||
@@ -176,7 +176,7 @@ do_listview_applauncher (GtkWidget *do_widget)
|
||||
|
||||
/* Create the list widget here.
|
||||
*/
|
||||
list = gtk_list_view_new_with_factory (model, factory);
|
||||
list = gtk_list_view_new (GTK_SELECTION_MODEL (gtk_single_selection_new (model)), factory);
|
||||
|
||||
/* We connect the activate signal here. It's the function we defined
|
||||
* above for launching the selected application.
|
||||
|
@@ -101,7 +101,7 @@ gtk_clock_snapshot (GdkPaintable *paintable,
|
||||
(GdkRGBA [4]) { BLACK, BLACK, BLACK, BLACK });
|
||||
|
||||
/* Next, draw the hour hand.
|
||||
* We do this using tranforms again: Instead of computing where the angle
|
||||
* We do this using transforms again: Instead of computing where the angle
|
||||
* points to, we just rotate everything and then draw the hand as if it
|
||||
* was :00. We don't even need to care about am/pm here because rotations
|
||||
* just work.
|
||||
@@ -462,7 +462,7 @@ do_listview_clocks (GtkWidget *do_widget)
|
||||
{
|
||||
GtkWidget *gridview, *sw;
|
||||
GtkListItemFactory *factory;
|
||||
GListModel *model;
|
||||
GtkSelectionModel *model;
|
||||
|
||||
/* This is the normal window setup code every demo does */
|
||||
window = gtk_window_new ();
|
||||
@@ -484,8 +484,8 @@ do_listview_clocks (GtkWidget *do_widget)
|
||||
factory = gtk_signal_list_item_factory_new ();
|
||||
g_signal_connect (factory, "setup", G_CALLBACK (setup_listitem_cb), NULL);
|
||||
|
||||
model = G_LIST_MODEL (gtk_no_selection_new (create_clocks_model ()));
|
||||
gridview = gtk_grid_view_new_with_factory (model, factory);
|
||||
model = GTK_SELECTION_MODEL (gtk_no_selection_new (create_clocks_model ()));
|
||||
gridview = gtk_grid_view_new (model, factory);
|
||||
gtk_scrollable_set_hscroll_policy (GTK_SCROLLABLE (gridview), GTK_SCROLL_NATURAL);
|
||||
gtk_scrollable_set_vscroll_policy (GTK_SCROLLABLE (gridview), GTK_SCROLL_NATURAL);
|
||||
|
||||
|
@@ -79,7 +79,7 @@ gtk_color_paintable_init (GdkPaintableInterface *iface)
|
||||
|
||||
/*
|
||||
* Finally, we define the type. The important part is adding the paintable
|
||||
* interface, so GTK knows that this object can indeed be drawm.
|
||||
* interface, so GTK knows that this object can indeed be drawn.
|
||||
*/
|
||||
G_DEFINE_TYPE_WITH_CODE (GtkColor, gtk_color, G_TYPE_OBJECT,
|
||||
G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE,
|
||||
@@ -226,7 +226,7 @@ gtk_color_set_property (GObject *object,
|
||||
break;
|
||||
|
||||
case PROP_COLOR:
|
||||
self->color = *(GdkRGBA *) g_value_dup_boxed (value);
|
||||
self->color = *(GdkRGBA *) g_value_get_boxed (value);
|
||||
rgb_to_hsv (&self->color, &h, &s, &v);
|
||||
self->h = round (360 * h);
|
||||
self->s = round (100 * s);
|
||||
@@ -523,7 +523,7 @@ gtk_color_list_init (GtkColorList *self)
|
||||
g_bytes_unref (data);
|
||||
}
|
||||
|
||||
static GListModel *
|
||||
GListModel *
|
||||
gtk_color_list_new (guint size)
|
||||
{
|
||||
return g_object_new (GTK_TYPE_COLOR_LIST,
|
||||
@@ -663,7 +663,7 @@ create_color_grid (void)
|
||||
GtkWidget *gridview;
|
||||
GtkListItemFactory *factory;
|
||||
|
||||
gridview = gtk_grid_view_new (NULL);
|
||||
gridview = gtk_grid_view_new (NULL, NULL);
|
||||
gtk_scrollable_set_hscroll_policy (GTK_SCROLLABLE (gridview), GTK_SCROLL_NATURAL);
|
||||
gtk_scrollable_set_vscroll_policy (GTK_SCROLLABLE (gridview), GTK_SCROLL_NATURAL);
|
||||
|
||||
@@ -866,7 +866,7 @@ do_listview_colors (GtkWidget *do_widget)
|
||||
guint len;
|
||||
GtkWidget *selection_view;
|
||||
GListModel *selection_filter;
|
||||
GListModel *no_selection;
|
||||
GtkSelectionModel *no_selection;
|
||||
GtkWidget *grid;
|
||||
GtkWidget *selection_size_label;
|
||||
GtkWidget *selection_average_picture;
|
||||
@@ -950,7 +950,7 @@ do_listview_colors (GtkWidget *do_widget)
|
||||
|
||||
factory = gtk_signal_list_item_factory_new ();
|
||||
g_signal_connect (factory, "setup", G_CALLBACK (setup_selection_listitem_cb), NULL);
|
||||
selection_view = gtk_grid_view_new_with_factory (NULL, factory);
|
||||
selection_view = gtk_grid_view_new (NULL, factory);
|
||||
gtk_widget_add_css_class (selection_view, "compact");
|
||||
gtk_grid_view_set_max_columns (GTK_GRID_VIEW (selection_view), 200);
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), selection_view);
|
||||
@@ -959,7 +959,7 @@ do_listview_colors (GtkWidget *do_widget)
|
||||
gtk_box_append (GTK_BOX (box), sw);
|
||||
|
||||
gridview = create_color_grid ();
|
||||
gtk_grid_view_set_model (GTK_GRID_VIEW (gridview), G_LIST_MODEL (selection));
|
||||
gtk_grid_view_set_model (GTK_GRID_VIEW (gridview), GTK_SELECTION_MODEL (selection));
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), gridview);
|
||||
gtk_widget_set_hexpand (sw, TRUE);
|
||||
gtk_widget_set_vexpand (sw, TRUE);
|
||||
@@ -968,7 +968,7 @@ do_listview_colors (GtkWidget *do_widget)
|
||||
g_signal_connect (selection_filter, "items-changed", G_CALLBACK (update_selection_count), selection_size_label);
|
||||
g_signal_connect (selection_filter, "items-changed", G_CALLBACK (update_selection_average), selection_average_picture);
|
||||
|
||||
no_selection = G_LIST_MODEL (gtk_no_selection_new (selection_filter));
|
||||
no_selection = GTK_SELECTION_MODEL (gtk_no_selection_new (selection_filter));
|
||||
gtk_grid_view_set_model (GTK_GRID_VIEW (selection_view), no_selection);
|
||||
g_object_unref (no_selection);
|
||||
|
||||
@@ -1022,31 +1022,31 @@ do_listview_colors (GtkWidget *do_widget)
|
||||
/* An empty multisorter doesn't do any sorting and the sortmodel is
|
||||
* smart enough to know that.
|
||||
*/
|
||||
sorter = gtk_multi_sorter_new ();
|
||||
sorter = GTK_SORTER (gtk_multi_sorter_new ());
|
||||
set_title (sorter, "Unsorted");
|
||||
g_list_store_append (sorters, sorter);
|
||||
g_object_unref (sorter);
|
||||
|
||||
sorter = gtk_string_sorter_new (gtk_property_expression_new (GTK_TYPE_COLOR, NULL, "name"));
|
||||
sorter = GTK_SORTER (gtk_string_sorter_new (gtk_property_expression_new (GTK_TYPE_COLOR, NULL, "name")));
|
||||
set_title (sorter, "Name");
|
||||
g_list_store_append (sorters, sorter);
|
||||
g_object_unref (sorter);
|
||||
|
||||
multi_sorter = gtk_multi_sorter_new ();
|
||||
multi_sorter = GTK_SORTER (gtk_multi_sorter_new ());
|
||||
|
||||
sorter = gtk_numeric_sorter_new (gtk_property_expression_new (GTK_TYPE_COLOR, NULL, "red"));
|
||||
sorter = GTK_SORTER (gtk_numeric_sorter_new (gtk_property_expression_new (GTK_TYPE_COLOR, NULL, "red")));
|
||||
gtk_numeric_sorter_set_sort_order (GTK_NUMERIC_SORTER (sorter), GTK_SORT_DESCENDING);
|
||||
set_title (sorter, "Red");
|
||||
g_list_store_append (sorters, sorter);
|
||||
gtk_multi_sorter_append (GTK_MULTI_SORTER (multi_sorter), sorter);
|
||||
|
||||
sorter = gtk_numeric_sorter_new (gtk_property_expression_new (GTK_TYPE_COLOR, NULL, "green"));
|
||||
sorter = GTK_SORTER (gtk_numeric_sorter_new (gtk_property_expression_new (GTK_TYPE_COLOR, NULL, "green")));
|
||||
gtk_numeric_sorter_set_sort_order (GTK_NUMERIC_SORTER (sorter), GTK_SORT_DESCENDING);
|
||||
set_title (sorter, "Green");
|
||||
g_list_store_append (sorters, sorter);
|
||||
gtk_multi_sorter_append (GTK_MULTI_SORTER (multi_sorter), sorter);
|
||||
|
||||
sorter = gtk_numeric_sorter_new (gtk_property_expression_new (GTK_TYPE_COLOR, NULL, "blue"));
|
||||
sorter = GTK_SORTER (gtk_numeric_sorter_new (gtk_property_expression_new (GTK_TYPE_COLOR, NULL, "blue")));
|
||||
gtk_numeric_sorter_set_sort_order (GTK_NUMERIC_SORTER (sorter), GTK_SORT_DESCENDING);
|
||||
set_title (sorter, "Blue");
|
||||
g_list_store_append (sorters, sorter);
|
||||
@@ -1056,21 +1056,21 @@ do_listview_colors (GtkWidget *do_widget)
|
||||
g_list_store_append (sorters, multi_sorter);
|
||||
g_object_unref (multi_sorter);
|
||||
|
||||
multi_sorter = gtk_multi_sorter_new ();
|
||||
multi_sorter = GTK_SORTER (gtk_multi_sorter_new ());
|
||||
|
||||
sorter = gtk_numeric_sorter_new (gtk_property_expression_new (GTK_TYPE_COLOR, NULL, "hue"));
|
||||
sorter = GTK_SORTER (gtk_numeric_sorter_new (gtk_property_expression_new (GTK_TYPE_COLOR, NULL, "hue")));
|
||||
gtk_numeric_sorter_set_sort_order (GTK_NUMERIC_SORTER (sorter), GTK_SORT_DESCENDING);
|
||||
set_title (sorter, "Hue");
|
||||
g_list_store_append (sorters, sorter);
|
||||
gtk_multi_sorter_append (GTK_MULTI_SORTER (multi_sorter), sorter);
|
||||
|
||||
sorter = gtk_numeric_sorter_new (gtk_property_expression_new (GTK_TYPE_COLOR, NULL, "saturation"));
|
||||
sorter = GTK_SORTER (gtk_numeric_sorter_new (gtk_property_expression_new (GTK_TYPE_COLOR, NULL, "saturation")));
|
||||
gtk_numeric_sorter_set_sort_order (GTK_NUMERIC_SORTER (sorter), GTK_SORT_DESCENDING);
|
||||
set_title (sorter, "Saturation");
|
||||
g_list_store_append (sorters, sorter);
|
||||
gtk_multi_sorter_append (GTK_MULTI_SORTER (multi_sorter), sorter);
|
||||
|
||||
sorter = gtk_numeric_sorter_new (gtk_property_expression_new (GTK_TYPE_COLOR, NULL, "value"));
|
||||
sorter = GTK_SORTER (gtk_numeric_sorter_new (gtk_property_expression_new (GTK_TYPE_COLOR, NULL, "value")));
|
||||
gtk_numeric_sorter_set_sort_order (GTK_NUMERIC_SORTER (sorter), GTK_SORT_DESCENDING);
|
||||
set_title (sorter, "Value");
|
||||
g_list_store_append (sorters, sorter);
|
||||
@@ -1118,6 +1118,8 @@ do_listview_colors (GtkWidget *do_widget)
|
||||
gtk_header_bar_pack_end (GTK_HEADER_BAR (header), box);
|
||||
|
||||
g_object_bind_property (dropdown, "selected-item", gridview, "factory", G_BINDING_SYNC_CREATE);
|
||||
|
||||
g_object_unref (selection);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
|
@@ -225,7 +225,7 @@ filebrowser_view_activated_cb (GtkGridView *view,
|
||||
{
|
||||
GFileInfo *info;
|
||||
|
||||
info = g_list_model_get_item (gtk_grid_view_get_model (view), pos);
|
||||
info = g_list_model_get_item (G_LIST_MODEL (gtk_grid_view_get_model (view)), pos);
|
||||
if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY)
|
||||
gtk_directory_list_set_file (list, G_FILE (g_file_info_get_attribute_object (info, "standard::file")));
|
||||
|
||||
|
@@ -165,8 +165,12 @@
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkDirectoryList" id="dirlist">
|
||||
<property name="attributes">standard::name,standard::display-name,standard::icon,standard::size,standard::content-type</property>
|
||||
<object class="GtkSingleSelection" id="selection_model">
|
||||
<property name="model">
|
||||
<object class="GtkDirectoryList" id="dirlist">
|
||||
<property name="attributes">standard::name,standard::display-name,standard::icon,standard::size,standard::content-type</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
<object class="GtkWindow" id="window">
|
||||
<property name="title" translatable="yes">File browser</property>
|
||||
@@ -227,7 +231,7 @@
|
||||
<property name="can-focus">1</property>
|
||||
<child>
|
||||
<object class="GtkGridView" id="view">
|
||||
<property name="model">dirlist</property>
|
||||
<property name="model">selection_model</property>
|
||||
<property name="max-columns">15</property>
|
||||
<binding name="factory">
|
||||
<lookup name="factory" type="FileBrowserView">
|
||||
|
@@ -5,6 +5,10 @@
|
||||
* It demonstrates how to implement support for trees with GtkListView.
|
||||
* It also shows how to set up sorting and filtering for columns in a
|
||||
* GtkColumnView.
|
||||
*
|
||||
* It also demonstrates different styles of list. The tree on the left
|
||||
* uses the .navigation-sidebar style class, the list on the right uses
|
||||
* the .data-table style class.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
@@ -243,7 +247,7 @@ transform_settings_to_keys (GBinding *binding,
|
||||
sort_model = gtk_sort_list_model_new (G_LIST_MODEL (store),
|
||||
g_object_ref (gtk_column_view_get_sorter (GTK_COLUMN_VIEW (data))));
|
||||
|
||||
filter = gtk_string_filter_new (gtk_property_expression_new (SETTINGS_TYPE_KEY, NULL, "name"));
|
||||
filter = GTK_FILTER (gtk_string_filter_new (gtk_property_expression_new (SETTINGS_TYPE_KEY, NULL, "name")));
|
||||
g_set_object (¤t_filter, filter);
|
||||
filter_model = gtk_filter_list_model_new (G_LIST_MODEL (sort_model), filter);
|
||||
|
||||
@@ -358,6 +362,8 @@ do_listview_settings (GtkWidget *do_widget)
|
||||
|
||||
builder = gtk_builder_new ();
|
||||
gtk_builder_set_scope (builder, scope);
|
||||
g_object_unref (scope);
|
||||
|
||||
gtk_builder_add_from_resource (builder, "/listview_settings/listview_settings.ui", NULL);
|
||||
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
|
||||
@@ -407,11 +413,11 @@ do_listview_settings (GtkWidget *do_widget)
|
||||
transform_settings_to_keys,
|
||||
NULL,
|
||||
columnview, NULL);
|
||||
gtk_list_view_set_model (GTK_LIST_VIEW (listview), G_LIST_MODEL (selection));
|
||||
gtk_list_view_set_model (GTK_LIST_VIEW (listview), GTK_SELECTION_MODEL (selection));
|
||||
g_object_unref (selection);
|
||||
|
||||
name_column = GTK_COLUMN_VIEW_COLUMN (gtk_builder_get_object (builder, "name_column"));
|
||||
sorter = gtk_string_sorter_new (gtk_property_expression_new (SETTINGS_TYPE_KEY, NULL, "name"));
|
||||
sorter = GTK_SORTER (gtk_string_sorter_new (gtk_property_expression_new (SETTINGS_TYPE_KEY, NULL, "name")));
|
||||
gtk_column_view_column_set_sorter (name_column, sorter);
|
||||
g_object_unref (sorter);
|
||||
|
||||
|
@@ -20,6 +20,9 @@
|
||||
<object class="GtkScrolledWindow">
|
||||
<child>
|
||||
<object class="GtkListView" id="listview">
|
||||
<style>
|
||||
<class name="navigation-sidebar"/>
|
||||
</style>
|
||||
<property name="factory">
|
||||
<object class="GtkBuilderListItemFactory">
|
||||
<property name="bytes"><![CDATA[
|
||||
@@ -73,6 +76,9 @@
|
||||
<property name="vexpand">1</property>
|
||||
<child>
|
||||
<object class="GtkColumnView" id="columnview">
|
||||
<style>
|
||||
<class name="data-table"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkColumnViewColumn" id="name_column">
|
||||
<property name="title">Name</property>
|
||||
|
@@ -281,14 +281,14 @@ GtkWidget *
|
||||
create_weather_view (void)
|
||||
{
|
||||
GtkWidget *listview;
|
||||
GListModel *model;
|
||||
GtkSelectionModel *model;
|
||||
GtkListItemFactory *factory;
|
||||
|
||||
factory = gtk_signal_list_item_factory_new ();
|
||||
g_signal_connect (factory, "setup", G_CALLBACK (setup_widget), NULL);
|
||||
g_signal_connect (factory, "bind", G_CALLBACK (bind_widget), NULL);
|
||||
model = G_LIST_MODEL (gtk_no_selection_new (create_weather_model ()));
|
||||
listview = gtk_list_view_new_with_factory (model, factory);
|
||||
model = GTK_SELECTION_MODEL (gtk_no_selection_new (create_weather_model ()));
|
||||
listview = gtk_list_view_new (model, factory);
|
||||
gtk_orientable_set_orientation (GTK_ORIENTABLE (listview), GTK_ORIENTATION_HORIZONTAL);
|
||||
gtk_list_view_set_show_separators (GTK_LIST_VIEW (listview), TRUE);
|
||||
|
||||
|
@@ -65,6 +65,7 @@ read_lines_cb (GObject *object,
|
||||
{
|
||||
g_print ("Could not read data: %s\n", error->message);
|
||||
g_clear_error (&error);
|
||||
g_object_unref (stringlist);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -74,6 +75,7 @@ read_lines_cb (GObject *object,
|
||||
{
|
||||
if (size)
|
||||
gtk_string_list_take (stringlist, g_utf8_make_valid (buffer, size));
|
||||
g_object_unref (stringlist);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -121,6 +123,7 @@ file_is_open_cb (GObject *file,
|
||||
{
|
||||
g_print ("Could not open file: %s\n", error->message);
|
||||
g_error_free (error);
|
||||
g_object_unref (data);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -134,7 +137,7 @@ load_file (GtkStringList *list,
|
||||
GFile *file)
|
||||
{
|
||||
gtk_string_list_splice (list, 0, g_list_model_get_n_items (G_LIST_MODEL (list)), NULL);
|
||||
g_file_read_async (file, G_PRIORITY_HIGH_IDLE, NULL, file_is_open_cb, list);
|
||||
g_file_read_async (file, G_PRIORITY_HIGH_IDLE, NULL, file_is_open_cb, g_object_ref (list));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -174,8 +177,9 @@ do_listview_words (GtkWidget *do_widget)
|
||||
stringlist = gtk_string_list_new ((const char **) words);
|
||||
g_strfreev (words);
|
||||
}
|
||||
g_object_unref (file);
|
||||
|
||||
filter = gtk_string_filter_new (gtk_property_expression_new (GTK_TYPE_STRING_OBJECT, NULL, "string"));
|
||||
filter = GTK_FILTER (gtk_string_filter_new (gtk_property_expression_new (GTK_TYPE_STRING_OBJECT, NULL, "string")));
|
||||
filter_model = gtk_filter_list_model_new (G_LIST_MODEL (stringlist), filter);
|
||||
gtk_filter_list_model_set_incremental (filter_model, TRUE);
|
||||
|
||||
@@ -213,8 +217,8 @@ do_listview_words (GtkWidget *do_widget)
|
||||
gtk_widget_set_vexpand (sw, TRUE);
|
||||
gtk_overlay_set_child (GTK_OVERLAY (overlay), sw);
|
||||
|
||||
listview = gtk_list_view_new_with_factory (
|
||||
G_LIST_MODEL (gtk_no_selection_new (G_LIST_MODEL (filter_model))),
|
||||
listview = gtk_list_view_new (
|
||||
GTK_SELECTION_MODEL (gtk_no_selection_new (G_LIST_MODEL (filter_model))),
|
||||
gtk_builder_list_item_factory_new_from_bytes (NULL,
|
||||
g_bytes_new_static (factory_text, strlen (factory_text))));
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), listview);
|
||||
|
@@ -9,6 +9,7 @@
|
||||
#include <glib/gstdio.h>
|
||||
|
||||
#include "demos.h"
|
||||
#include "fontify.h"
|
||||
|
||||
static GtkWidget *info_view;
|
||||
static GtkWidget *source_view;
|
||||
@@ -146,10 +147,16 @@ activate_about (GSimpleAction *action,
|
||||
NULL
|
||||
};
|
||||
char *version;
|
||||
char *os_name;
|
||||
char *os_version;
|
||||
GString *s;
|
||||
|
||||
s = g_string_new ("");
|
||||
|
||||
os_name = g_get_os_info (G_OS_INFO_KEY_NAME);
|
||||
os_version = g_get_os_info (G_OS_INFO_KEY_VERSION_ID);
|
||||
if (os_name && os_version)
|
||||
g_string_append_printf (s, "OS\t%s %s\n\n", os_name, os_version);
|
||||
g_string_append (s, "System libraries\n");
|
||||
g_string_append_printf (s, "\tGLib\t%d.%d.%d\n",
|
||||
glib_major_version,
|
||||
@@ -184,6 +191,8 @@ activate_about (GSimpleAction *action,
|
||||
|
||||
g_string_free (s, TRUE);
|
||||
g_free (version);
|
||||
g_free (os_name);
|
||||
g_free (os_version);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -226,373 +235,10 @@ activate_run (GSimpleAction *action,
|
||||
gtk_demo_run (demo, window);
|
||||
}
|
||||
|
||||
/* Stupid syntax highlighting.
|
||||
*
|
||||
* No regex was used in the making of this highlighting.
|
||||
* It should only work for simple cases. This is good, as
|
||||
* that's all we should have in the demos.
|
||||
*/
|
||||
/* This code should not be used elsewhere, except perhaps as an example of how
|
||||
* to iterate through a text buffer.
|
||||
*/
|
||||
enum {
|
||||
STATE_NORMAL,
|
||||
STATE_IN_COMMENT
|
||||
};
|
||||
|
||||
static const char *tokens[] =
|
||||
{
|
||||
"/*",
|
||||
"\"",
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char *types[] =
|
||||
{
|
||||
"static",
|
||||
"const ",
|
||||
"void",
|
||||
" int ",
|
||||
" char ",
|
||||
"char ",
|
||||
"float",
|
||||
"double",
|
||||
"gint8",
|
||||
"gint16",
|
||||
"gint32",
|
||||
"guint",
|
||||
"guint8",
|
||||
"guint16",
|
||||
"guint32",
|
||||
"guchar",
|
||||
"glong",
|
||||
"gboolean" ,
|
||||
"gshort",
|
||||
"gushort",
|
||||
"gulong",
|
||||
"gpointer",
|
||||
"NULL",
|
||||
"GList",
|
||||
"GSList",
|
||||
"FALSE",
|
||||
"TRUE",
|
||||
"FILE ",
|
||||
"GtkColorSelection ",
|
||||
"GtkWidget ",
|
||||
"GtkButton ",
|
||||
"GdkColor ",
|
||||
"GdkRectangle ",
|
||||
"GdkEventExpose ",
|
||||
"GdkGC ",
|
||||
"GdkPixbufLoader ",
|
||||
"GdkPixbuf ",
|
||||
"GError",
|
||||
"size_t",
|
||||
"GtkAboutDialog ",
|
||||
"GtkAction ",
|
||||
"GtkActionEntry ",
|
||||
"GtkRadioActionEntry ",
|
||||
"GtkIconFactory ",
|
||||
"GtkTextBuffer ",
|
||||
"GtkStatusbar ",
|
||||
"GtkTextIter ",
|
||||
"GtkTextMark ",
|
||||
"GdkEventWindowState ",
|
||||
"GtkActionGroup ",
|
||||
"GtkUIManager ",
|
||||
"GtkRadioAction ",
|
||||
"GtkActionClass ",
|
||||
"GtkToggleActionEntry ",
|
||||
"GtkAssistant ",
|
||||
"GtkBuilder ",
|
||||
"GtkSizeGroup ",
|
||||
"GtkTreeModel ",
|
||||
"GtkTreeSelection ",
|
||||
"GdkDisplay ",
|
||||
"GdkScreen ",
|
||||
"GdkSurface ",
|
||||
"GdkEventButton ",
|
||||
"GdkCursor ",
|
||||
"GtkTreeIter ",
|
||||
"GtkTreeViewColumn ",
|
||||
"GdkDisplayManager ",
|
||||
"GdkClipboard ",
|
||||
"GtkIconSize ",
|
||||
"GtkImage ",
|
||||
"GdkDragContext ",
|
||||
"GtkSelectionData ",
|
||||
"GtkDialog ",
|
||||
"GtkMenuItem ",
|
||||
"GtkListStore ",
|
||||
"GtkCellLayout ",
|
||||
"GtkCellRenderer ",
|
||||
"GtkTreePath ",
|
||||
"GtkTreeStore ",
|
||||
"GtkEntry ",
|
||||
"GtkEditable ",
|
||||
"GtkEditableInterface ",
|
||||
"GdkPixmap ",
|
||||
"GdkEventConfigure ",
|
||||
"GdkEventMotion ",
|
||||
"GdkModifierType ",
|
||||
"GtkEntryCompletion ",
|
||||
"GtkToolItem ",
|
||||
"GDir ",
|
||||
"GtkIconView ",
|
||||
"GtkCellRendererText ",
|
||||
"GtkContainer ",
|
||||
"GtkPaned ",
|
||||
"GtkPrintOperation ",
|
||||
"GtkPrintContext ",
|
||||
"cairo_t ",
|
||||
"PangoLayout "
|
||||
"PangoFontDescription ",
|
||||
"PangoRenderer ",
|
||||
"PangoMatrix ",
|
||||
"PangoContext ",
|
||||
"PangoLayout ",
|
||||
"GtkToggleButton ",
|
||||
"GString ",
|
||||
"GtkIconSize ",
|
||||
"GtkTreeView ",
|
||||
"GtkTextTag ",
|
||||
"GdkEvent ",
|
||||
"GdkEventKey ",
|
||||
"GtkTextView ",
|
||||
"GdkBitmap ",
|
||||
"GtkTextChildAnchor ",
|
||||
"GArray ",
|
||||
"GtkCellEditable ",
|
||||
"GtkCellRendererToggle ",
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char *control[] =
|
||||
{
|
||||
" if ",
|
||||
" while ",
|
||||
" else",
|
||||
" do ",
|
||||
" for ",
|
||||
"?",
|
||||
":",
|
||||
"return ",
|
||||
"goto ",
|
||||
NULL
|
||||
};
|
||||
void
|
||||
parse_chars (char *text,
|
||||
char **end_ptr,
|
||||
int *state,
|
||||
const char **tag,
|
||||
gboolean start)
|
||||
{
|
||||
int i;
|
||||
char *next_token;
|
||||
|
||||
/* Handle comments first */
|
||||
if (*state == STATE_IN_COMMENT)
|
||||
{
|
||||
*end_ptr = strstr (text, "*/");
|
||||
if (*end_ptr)
|
||||
{
|
||||
*end_ptr += 2;
|
||||
*state = STATE_NORMAL;
|
||||
*tag = "comment";
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
*tag = NULL;
|
||||
*end_ptr = NULL;
|
||||
|
||||
/* check for comment */
|
||||
if (!strncmp (text, "/*", 2))
|
||||
{
|
||||
*end_ptr = strstr (text, "*/");
|
||||
if (*end_ptr)
|
||||
*end_ptr += 2;
|
||||
else
|
||||
*state = STATE_IN_COMMENT;
|
||||
*tag = "comment";
|
||||
return;
|
||||
}
|
||||
|
||||
/* check for preprocessor defines */
|
||||
if (*text == '#' && start)
|
||||
{
|
||||
*end_ptr = NULL;
|
||||
*tag = "preprocessor";
|
||||
return;
|
||||
}
|
||||
|
||||
/* functions */
|
||||
if (start && * text != '\t' && *text != ' ' && *text != '{' && *text != '}')
|
||||
{
|
||||
if (strstr (text, "("))
|
||||
{
|
||||
*end_ptr = strstr (text, "(");
|
||||
*tag = "function";
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* check for types */
|
||||
for (i = 0; types[i] != NULL; i++)
|
||||
if (!strncmp (text, types[i], strlen (types[i])) ||
|
||||
(start && types[i][0] == ' ' && !strncmp (text, types[i] + 1, strlen (types[i]) - 1)))
|
||||
{
|
||||
*end_ptr = text + strlen (types[i]);
|
||||
*tag = "type";
|
||||
return;
|
||||
}
|
||||
|
||||
/* check for control */
|
||||
for (i = 0; control[i] != NULL; i++)
|
||||
if (!strncmp (text, control[i], strlen (control[i])))
|
||||
{
|
||||
*end_ptr = text + strlen (control[i]);
|
||||
*tag = "control";
|
||||
return;
|
||||
}
|
||||
|
||||
/* check for string */
|
||||
if (text[0] == '"')
|
||||
{
|
||||
int maybe_escape = FALSE;
|
||||
|
||||
*end_ptr = text + 1;
|
||||
*tag = "string";
|
||||
while (**end_ptr != '\000')
|
||||
{
|
||||
if (**end_ptr == '\"' && !maybe_escape)
|
||||
{
|
||||
*end_ptr += 1;
|
||||
return;
|
||||
}
|
||||
if (**end_ptr == '\\')
|
||||
maybe_escape = TRUE;
|
||||
else
|
||||
maybe_escape = FALSE;
|
||||
*end_ptr += 1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* not at the start of a tag. Find the next one. */
|
||||
for (i = 0; tokens[i] != NULL; i++)
|
||||
{
|
||||
next_token = strstr (text, tokens[i]);
|
||||
if (next_token)
|
||||
{
|
||||
if (*end_ptr)
|
||||
*end_ptr = (*end_ptr<next_token)?*end_ptr:next_token;
|
||||
else
|
||||
*end_ptr = next_token;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; types[i] != NULL; i++)
|
||||
{
|
||||
next_token = strstr (text, types[i]);
|
||||
if (next_token)
|
||||
{
|
||||
if (*end_ptr)
|
||||
*end_ptr = (*end_ptr<next_token)?*end_ptr:next_token;
|
||||
else
|
||||
*end_ptr = next_token;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; control[i] != NULL; i++)
|
||||
{
|
||||
next_token = strstr (text, control[i]);
|
||||
if (next_token)
|
||||
{
|
||||
if (*end_ptr)
|
||||
*end_ptr = (*end_ptr<next_token)?*end_ptr:next_token;
|
||||
else
|
||||
*end_ptr = next_token;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* While not as cool as c-mode, this will do as a quick attempt at highlighting */
|
||||
void
|
||||
fontify (GtkTextBuffer *source_buffer)
|
||||
{
|
||||
GtkTextIter start_iter, next_iter, tmp_iter;
|
||||
int state;
|
||||
char *text;
|
||||
char *start_ptr, *end_ptr;
|
||||
const char *tag;
|
||||
|
||||
gtk_text_buffer_create_tag (source_buffer, "source",
|
||||
"font", "monospace",
|
||||
NULL);
|
||||
gtk_text_buffer_create_tag (source_buffer, "comment",
|
||||
"foreground", "DodgerBlue",
|
||||
NULL);
|
||||
gtk_text_buffer_create_tag (source_buffer, "type",
|
||||
"foreground", "ForestGreen",
|
||||
NULL);
|
||||
gtk_text_buffer_create_tag (source_buffer, "string",
|
||||
"foreground", "RosyBrown",
|
||||
"weight", PANGO_WEIGHT_BOLD,
|
||||
NULL);
|
||||
gtk_text_buffer_create_tag (source_buffer, "control",
|
||||
"foreground", "purple",
|
||||
NULL);
|
||||
gtk_text_buffer_create_tag (source_buffer, "preprocessor",
|
||||
"style", PANGO_STYLE_OBLIQUE,
|
||||
"foreground", "burlywood4",
|
||||
NULL);
|
||||
gtk_text_buffer_create_tag (source_buffer, "function",
|
||||
"weight", PANGO_WEIGHT_BOLD,
|
||||
"foreground", "DarkGoldenrod4",
|
||||
NULL);
|
||||
|
||||
gtk_text_buffer_get_bounds (source_buffer, &start_iter, &tmp_iter);
|
||||
gtk_text_buffer_apply_tag_by_name (source_buffer, "source", &start_iter, &tmp_iter);
|
||||
|
||||
state = STATE_NORMAL;
|
||||
|
||||
gtk_text_buffer_get_iter_at_offset (source_buffer, &start_iter, 0);
|
||||
|
||||
next_iter = start_iter;
|
||||
while (gtk_text_iter_forward_line (&next_iter))
|
||||
{
|
||||
gboolean start = TRUE;
|
||||
start_ptr = text = gtk_text_iter_get_text (&start_iter, &next_iter);
|
||||
|
||||
do
|
||||
{
|
||||
parse_chars (start_ptr, &end_ptr, &state, &tag, start);
|
||||
|
||||
start = FALSE;
|
||||
if (end_ptr)
|
||||
{
|
||||
tmp_iter = start_iter;
|
||||
gtk_text_iter_forward_chars (&tmp_iter, end_ptr - start_ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp_iter = next_iter;
|
||||
}
|
||||
if (tag)
|
||||
gtk_text_buffer_apply_tag_by_name (source_buffer, tag, &start_iter, &tmp_iter);
|
||||
|
||||
start_iter = tmp_iter;
|
||||
start_ptr = end_ptr;
|
||||
}
|
||||
while (end_ptr);
|
||||
|
||||
g_free (text);
|
||||
start_iter = next_iter;
|
||||
}
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
display_image (const char *resource)
|
||||
display_image (const char *format,
|
||||
const char *resource,
|
||||
char **label)
|
||||
{
|
||||
GtkWidget *sw, *image;
|
||||
|
||||
@@ -606,11 +252,62 @@ display_image (const char *resource)
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
display_text (const char *resource)
|
||||
display_images (const char *format,
|
||||
const char *resource_dir,
|
||||
char **label)
|
||||
{
|
||||
char **resources;
|
||||
GtkWidget *grid;
|
||||
GtkWidget *sw;
|
||||
GtkWidget *widget;
|
||||
guint i;
|
||||
|
||||
resources = g_resources_enumerate_children (resource_dir, 0, NULL);
|
||||
if (resources == NULL)
|
||||
return NULL;
|
||||
|
||||
sw = gtk_scrolled_window_new ();
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
||||
GTK_POLICY_NEVER,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
grid = gtk_flow_box_new ();
|
||||
gtk_flow_box_set_selection_mode (GTK_FLOW_BOX (grid), GTK_SELECTION_NONE);
|
||||
gtk_widget_set_valign (grid, GTK_ALIGN_START);
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), grid);
|
||||
|
||||
for (i = 0; resources[i]; i++)
|
||||
{
|
||||
char *resource_name;
|
||||
GtkWidget *box;
|
||||
|
||||
resource_name = g_strconcat (resource_dir, "/", resources[i], NULL);
|
||||
|
||||
widget = display_image (NULL, resource_name, NULL);
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_box_append (GTK_BOX (box), widget);
|
||||
gtk_box_append (GTK_BOX (box), gtk_label_new (resources[i]));
|
||||
gtk_flow_box_insert (GTK_FLOW_BOX (grid), box, -1);
|
||||
|
||||
g_free (resource_name);
|
||||
}
|
||||
|
||||
g_strfreev (resources);
|
||||
|
||||
*label = g_strdup ("Images");
|
||||
|
||||
return sw;
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
display_text (const char *format,
|
||||
const char *resource,
|
||||
char **label)
|
||||
{
|
||||
GtkTextBuffer *buffer;
|
||||
GtkWidget *textview, *sw;
|
||||
GBytes *bytes;
|
||||
const char *text;
|
||||
gsize len;
|
||||
|
||||
bytes = g_resources_lookup_data (resource, 0, NULL);
|
||||
g_assert (bytes);
|
||||
@@ -630,14 +327,17 @@ display_text (const char *resource)
|
||||
gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (textview), GTK_WRAP_WORD);
|
||||
gtk_text_view_set_pixels_above_lines (GTK_TEXT_VIEW (textview), 2);
|
||||
gtk_text_view_set_pixels_below_lines (GTK_TEXT_VIEW (textview), 2);
|
||||
gtk_text_view_set_monospace (GTK_TEXT_VIEW (textview), TRUE);
|
||||
|
||||
buffer = gtk_text_buffer_new (NULL);
|
||||
gtk_text_buffer_set_text (buffer, g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes));
|
||||
if (g_str_has_suffix (resource, ".c"))
|
||||
fontify (buffer);
|
||||
gtk_text_view_set_buffer (GTK_TEXT_VIEW (textview), buffer);
|
||||
|
||||
g_bytes_unref (bytes);
|
||||
text = g_bytes_unref_to_data (bytes, &len);
|
||||
gtk_text_buffer_set_text (buffer, text, len);
|
||||
|
||||
if (format)
|
||||
fontify (format, buffer);
|
||||
|
||||
gtk_text_view_set_buffer (GTK_TEXT_VIEW (textview), buffer);
|
||||
|
||||
sw = gtk_scrolled_window_new ();
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
||||
@@ -649,7 +349,9 @@ display_text (const char *resource)
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
display_video (const char *resource)
|
||||
display_video (const char *format,
|
||||
const char *resource,
|
||||
char **label)
|
||||
{
|
||||
GtkWidget *video;
|
||||
|
||||
@@ -676,18 +378,22 @@ display_nothing (const char *resource)
|
||||
|
||||
static struct {
|
||||
const char *extension;
|
||||
GtkWidget * (* display_func) (const char *resource);
|
||||
const char *format;
|
||||
GtkWidget * (* display_func) (const char *format,
|
||||
const char *resource,
|
||||
char **label);
|
||||
} display_funcs[] = {
|
||||
{ ".gif", display_image },
|
||||
{ ".jpg", display_image },
|
||||
{ ".png", display_image },
|
||||
{ ".c", display_text },
|
||||
{ ".css", display_text },
|
||||
{ ".glsl", display_text },
|
||||
{ ".h", display_text },
|
||||
{ ".txt", display_text },
|
||||
{ ".ui", display_text },
|
||||
{ ".webm", display_video }
|
||||
{ ".gif", NULL, display_image },
|
||||
{ ".jpg", NULL, display_image },
|
||||
{ ".png", NULL, display_image },
|
||||
{ ".c", "c", display_text },
|
||||
{ ".css", "css", display_text },
|
||||
{ ".glsl", NULL, display_text },
|
||||
{ ".h", "c", display_text },
|
||||
{ ".txt", NULL, display_text },
|
||||
{ ".ui", "xml", display_text },
|
||||
{ ".webm", NULL, display_video },
|
||||
{ "images/", NULL, display_images }
|
||||
};
|
||||
|
||||
static void
|
||||
@@ -697,6 +403,7 @@ add_data_tab (const char *demoname)
|
||||
char **resources;
|
||||
GtkWidget *widget, *label;
|
||||
guint i, j;
|
||||
char *label_string;
|
||||
|
||||
resource_dir = g_strconcat ("/", demoname, NULL);
|
||||
resources = g_resources_enumerate_children (resource_dir, 0, NULL);
|
||||
@@ -710,18 +417,22 @@ add_data_tab (const char *demoname)
|
||||
{
|
||||
resource_name = g_strconcat (resource_dir, "/", resources[i], NULL);
|
||||
|
||||
for (j = 0; j < G_N_ELEMENTS(display_funcs); j++)
|
||||
for (j = 0; j < G_N_ELEMENTS (display_funcs); j++)
|
||||
{
|
||||
if (g_str_has_suffix (resource_name, display_funcs[j].extension))
|
||||
break;
|
||||
}
|
||||
|
||||
if (j < G_N_ELEMENTS(display_funcs))
|
||||
widget = display_funcs[j].display_func (resource_name);
|
||||
label_string = NULL;
|
||||
|
||||
if (j < G_N_ELEMENTS (display_funcs))
|
||||
widget = display_funcs[j].display_func (display_funcs[j].format,
|
||||
resource_name,
|
||||
&label_string);
|
||||
else
|
||||
widget = display_nothing (resource_name);
|
||||
|
||||
label = gtk_label_new (resources[i]);
|
||||
label = gtk_label_new (label_string ? label_string : resources[i]);
|
||||
gtk_widget_show (label);
|
||||
gtk_notebook_append_page (GTK_NOTEBOOK (notebook), widget, label);
|
||||
g_object_set (gtk_notebook_get_page (GTK_NOTEBOOK (notebook), widget),
|
||||
@@ -729,6 +440,7 @@ add_data_tab (const char *demoname)
|
||||
NULL);
|
||||
|
||||
g_free (resource_name);
|
||||
g_free (label_string);
|
||||
}
|
||||
|
||||
g_strfreev (resources);
|
||||
@@ -912,7 +624,7 @@ load_file (const char *demoname,
|
||||
|
||||
g_strfreev (lines);
|
||||
|
||||
fontify (source_buffer);
|
||||
fontify ("c", source_buffer);
|
||||
|
||||
gtk_text_buffer_end_irreversible_action (source_buffer);
|
||||
gtk_text_view_set_buffer (GTK_TEXT_VIEW (source_view), source_buffer);
|
||||
@@ -928,7 +640,8 @@ activate_cb (GtkWidget *widget,
|
||||
guint position,
|
||||
gpointer window)
|
||||
{
|
||||
GtkTreeListRow *row = g_list_model_get_item (gtk_list_view_get_model (GTK_LIST_VIEW (widget)), position);
|
||||
GListModel *model = G_LIST_MODEL (gtk_list_view_get_model (GTK_LIST_VIEW (widget)));
|
||||
GtkTreeListRow *row = g_list_model_get_item (model, position);
|
||||
GtkDemo *demo = gtk_tree_list_row_get_item (row);
|
||||
|
||||
gtk_demo_run (demo, window);
|
||||
@@ -966,7 +679,7 @@ filter_demo (GtkDemo *demo)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Show only if the name maches every needle */
|
||||
/* Show only if the name matches every needle */
|
||||
for (i = 0; search_needle[i]; i++)
|
||||
{
|
||||
if (!demo->title)
|
||||
@@ -982,12 +695,15 @@ filter_demo (GtkDemo *demo)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
demo_filter_by_name (GtkTreeListRow *row,
|
||||
GtkFilterListModel *model)
|
||||
demo_filter_by_name (gpointer item,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkTreeListRow *row = item;
|
||||
GtkFilterListModel *model = user_data;
|
||||
GListModel *children;
|
||||
GtkDemo *demo;
|
||||
guint i, n;
|
||||
GtkTreeListRow *parent;
|
||||
|
||||
/* Show all items if search is empty */
|
||||
if (!search_needle || !search_needle[0] || !*search_needle[0])
|
||||
@@ -996,6 +712,17 @@ demo_filter_by_name (GtkTreeListRow *row,
|
||||
g_assert (GTK_IS_TREE_LIST_ROW (row));
|
||||
g_assert (GTK_IS_FILTER_LIST_MODEL (model));
|
||||
|
||||
/* Show a row if itself of any parent matches */
|
||||
for (parent = row; parent; parent = gtk_tree_list_row_get_parent (parent))
|
||||
{
|
||||
demo = gtk_tree_list_row_get_item (parent);
|
||||
g_assert (GTK_IS_DEMO (demo));
|
||||
|
||||
if (filter_demo (demo))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Show a row if any child matches */
|
||||
children = gtk_tree_list_row_get_children (row);
|
||||
if (children)
|
||||
{
|
||||
@@ -1014,10 +741,7 @@ demo_filter_by_name (GtkTreeListRow *row,
|
||||
}
|
||||
}
|
||||
|
||||
demo = gtk_tree_list_row_get_item (row);
|
||||
g_assert (GTK_IS_DEMO (demo));
|
||||
|
||||
return filter_demo (demo);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1143,17 +867,19 @@ activate (GApplication *app)
|
||||
NULL,
|
||||
NULL);
|
||||
filter_model = gtk_filter_list_model_new (G_LIST_MODEL (treemodel), NULL);
|
||||
filter = gtk_custom_filter_new ((GtkCustomFilterFunc)demo_filter_by_name, filter_model, NULL);
|
||||
filter = GTK_FILTER (gtk_custom_filter_new (demo_filter_by_name, filter_model, NULL));
|
||||
gtk_filter_list_model_set_filter (filter_model, filter);
|
||||
g_object_unref (filter);
|
||||
|
||||
search_entry = GTK_WIDGET (gtk_builder_get_object (builder, "search-entry"));
|
||||
g_signal_connect (search_entry, "search-changed", G_CALLBACK (demo_search_changed_cb), filter);
|
||||
|
||||
selection = gtk_single_selection_new (G_LIST_MODEL (filter_model));
|
||||
g_signal_connect (selection, "notify::selected-item", G_CALLBACK (selection_cb), NULL);
|
||||
gtk_list_view_set_model (GTK_LIST_VIEW (listview), G_LIST_MODEL (selection));
|
||||
gtk_list_view_set_model (GTK_LIST_VIEW (listview), GTK_SELECTION_MODEL (selection));
|
||||
|
||||
selection_cb (selection, NULL, NULL);
|
||||
g_object_unref (selection);
|
||||
|
||||
g_object_unref (builder);
|
||||
}
|
||||
|
@@ -70,6 +70,9 @@
|
||||
|
||||
<child>
|
||||
<object class="GtkListView" id="listview">
|
||||
<style>
|
||||
<class name="navigation-sidebar"/>
|
||||
</style>
|
||||
<property name="factory">
|
||||
<object class="GtkBuilderListItemFactory">
|
||||
<property name="resource">/ui/main-listitem.ui</property>
|
||||
@@ -134,6 +137,10 @@
|
||||
<property name="bottom-margin">20</property>
|
||||
<property name="editable">0</property>
|
||||
<property name="cursor-visible">0</property>
|
||||
<property name="monospace">1</property>
|
||||
<property name="wrap-mode">word</property>
|
||||
<property name="pixels-above-lines">2</property>
|
||||
<property name="pixels-below-lines">2</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
95
demos/gtk-demo/mandelbrot.glsl
Normal file
95
demos/gtk-demo/mandelbrot.glsl
Normal file
@@ -0,0 +1,95 @@
|
||||
// Originally from: https://www.shadertoy.com/view/wdBfDK
|
||||
// License: CC0
|
||||
|
||||
#define MANDELBROT_ZOOM_START 0.0
|
||||
#define MANDELBROT_ITER 240
|
||||
|
||||
void pR(inout vec2 p, in float a) {
|
||||
p = cos(a)*p + sin(a)*vec2(p.y, -p.x);
|
||||
}
|
||||
|
||||
vec2 pMod2(inout vec2 p, in vec2 size) {
|
||||
vec2 c = floor((p + size*0.5)/size);
|
||||
p = mod(p + size*0.5,size) - size*0.5;
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
vec3 mandelbrot(float time, vec2 p, out float ii) {
|
||||
vec3 col = vec3(0.0);
|
||||
|
||||
float ztime = (time - MANDELBROT_ZOOM_START)*step(MANDELBROT_ZOOM_START, time);
|
||||
|
||||
float zoo = 0.64 + 0.36*cos(.07*ztime);
|
||||
float coa = cos(0.15*(1.0-zoo)*ztime);
|
||||
float sia = sin(0.15*(1.0-zoo)*ztime);
|
||||
zoo = pow(zoo,8.0);
|
||||
vec2 xy = vec2( p.x*coa-p.y*sia, p.x*sia+p.y*coa);
|
||||
vec2 c = vec2(-.745,.186) + xy*zoo;
|
||||
|
||||
const float B = 10.0;
|
||||
float l = 0.0;
|
||||
vec2 z = vec2(0.0);
|
||||
|
||||
vec2 zc = vec2(1.0);
|
||||
|
||||
pR(zc, ztime);
|
||||
|
||||
float d = 1e20;
|
||||
|
||||
int i = 0;
|
||||
|
||||
for(int j = 0; j < MANDELBROT_ITER; ++j) {
|
||||
float re2 = z.x*z.x;
|
||||
float im2 = z.y*z.y;
|
||||
float reim= z.x*z.y;
|
||||
|
||||
if(re2 + im2 > (B*B)) break;
|
||||
|
||||
z = vec2(re2 - im2, 2.0*reim) + c;
|
||||
|
||||
vec2 zm = z;
|
||||
vec2 n = pMod2(zm, vec2(4));
|
||||
vec2 pp = zm - zc;
|
||||
float dd = dot(pp, pp);
|
||||
|
||||
d = min(d, dd);
|
||||
|
||||
l += 1.0;
|
||||
|
||||
i = j;
|
||||
}
|
||||
|
||||
ii = float(i)/float(MANDELBROT_ITER);
|
||||
|
||||
float sl = l - log2(log2(dot(z,z))) + 4.0;
|
||||
|
||||
vec3 dc = vec3(pow(max(1.0 - d, 0.0), 20.0));
|
||||
vec3 gc = 0.5 + 0.5*cos(3.0 + sl*0.15 + vec3(0.1,0.5,0.9));
|
||||
return gc + dc*smoothstep(28.8, 29.0, ztime);
|
||||
}
|
||||
|
||||
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
|
||||
float s = 2.0/iResolution.y;
|
||||
|
||||
vec2 o1 = vec2(1.0/8.0, 3.0/8.0)*s;
|
||||
vec2 o2 = vec2(-3.0/8.0, 1.0/8.0)*s;
|
||||
|
||||
vec2 p = (-iResolution.xy + 2.0*fragCoord.xy)/iResolution.y;
|
||||
float ii = 0.0;
|
||||
vec3 col = mandelbrot(iTime, p+o1, ii);
|
||||
|
||||
// "smart" AA? Is that a good idea?
|
||||
vec2 dii2 = vec2(dFdx(ii), dFdy(ii));
|
||||
float dii = length(dii2);
|
||||
|
||||
if(abs(dii) > 0.01) {
|
||||
col += mandelbrot(iTime, p-o1, ii);
|
||||
col += mandelbrot(iTime, p+o2, ii);
|
||||
col += mandelbrot(iTime, p-o2, ii);
|
||||
col *=0.25;
|
||||
// col = vec3(1.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
fragColor = vec4(col, 1.0);
|
||||
}
|
@@ -38,8 +38,11 @@ demos = files([
|
||||
'iconview_edit.c',
|
||||
'images.c',
|
||||
'infobar.c',
|
||||
'layoutmanager.c',
|
||||
'layoutmanager2.c',
|
||||
'links.c',
|
||||
'listbox.c',
|
||||
'listbox2.c',
|
||||
'flowbox.c',
|
||||
'list_store.c',
|
||||
'listview_applauncher.c',
|
||||
@@ -51,24 +54,24 @@ demos = files([
|
||||
'listview_weather.c',
|
||||
'listview_words.c',
|
||||
'markup.c',
|
||||
'modelbutton.c',
|
||||
'overlay.c',
|
||||
'overlay2.c',
|
||||
'paint.c',
|
||||
'paintable.c',
|
||||
'paintable_animated.c',
|
||||
'paintable_emblem.c',
|
||||
'paintable_mediastream.c',
|
||||
'panes.c',
|
||||
'password_entry.c',
|
||||
'peg_solitaire.c',
|
||||
'pickers.c',
|
||||
'pixbufs.c',
|
||||
'printing.c',
|
||||
'revealer.c',
|
||||
'rotated_text.c',
|
||||
'scale.c',
|
||||
'search_entry.c',
|
||||
'search_entry2.c',
|
||||
'shadertoy.c',
|
||||
'shortcuts.c',
|
||||
'shortcut_triggers.c',
|
||||
'sidebar.c',
|
||||
@@ -93,13 +96,22 @@ demos = files([
|
||||
gtkdemo_deps = [ libgtk_dep, ]
|
||||
|
||||
extra_demo_sources = files(['main.c',
|
||||
'fontify.c',
|
||||
'gtkfishbowl.c',
|
||||
'fontplane.c',
|
||||
'gtkgears.c',
|
||||
'gtkshadertoy.c',
|
||||
'puzzlepiece.c',
|
||||
'bluroverlay.c',
|
||||
'demoimage.c',
|
||||
'demotaggedentry.c'])
|
||||
'demotaggedentry.c',
|
||||
'demochild.c',
|
||||
'demolayout.c',
|
||||
'demowidget.c',
|
||||
'demo2layout.c',
|
||||
'singular_value_decomposition.c',
|
||||
'four_point_transform.c',
|
||||
'demo2widget.c'])
|
||||
|
||||
if harfbuzz_dep.found() and pangoft_dep.found()
|
||||
demos += files('font_features.c')
|
||||
|
@@ -1,66 +0,0 @@
|
||||
/* Model Button
|
||||
*
|
||||
* GtkModelButton is a button widget that is designed to be used with
|
||||
* a GAction as model. The button will adjust its appearance according
|
||||
* to the kind of action it is connected to.
|
||||
*
|
||||
* It is also possible to use GtkModelButton without a GAction. In this
|
||||
* case, you should set the "role" attribute yourself, and connect to the
|
||||
* "clicked" signal as you would for any other button.
|
||||
*
|
||||
* A common use of GtkModelButton is to implement menu-like content
|
||||
* in popovers.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
void
|
||||
modelbutton_tool_clicked (GtkButton *button)
|
||||
{
|
||||
gboolean active;
|
||||
|
||||
g_object_get (button, "active", &active, NULL);
|
||||
g_object_set (button, "active", !active, NULL);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_modelbutton (GtkWidget *do_widget)
|
||||
{
|
||||
static GtkWidget *window = NULL;
|
||||
static GActionEntry win_entries[] = {
|
||||
{ "color", NULL, "s", "'red'", NULL },
|
||||
{ "chocolate", NULL, NULL, "true", NULL },
|
||||
{ "vanilla", NULL, NULL, "false", NULL },
|
||||
{ "sprinkles", NULL, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
if (!window)
|
||||
{
|
||||
GtkBuilder *builder;
|
||||
GActionGroup *actions;
|
||||
|
||||
builder = gtk_builder_new_from_resource ("/modelbutton/modelbutton.ui");
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window1"));
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
|
||||
actions = (GActionGroup*)g_simple_action_group_new ();
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (actions),
|
||||
win_entries, G_N_ELEMENTS (win_entries),
|
||||
window);
|
||||
gtk_widget_insert_action_group (window, "win", actions);
|
||||
|
||||
|
||||
g_object_unref (builder);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
|
||||
|
||||
return window;
|
||||
}
|
||||
|
@@ -1,133 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<object class="GtkWindow" id="window1">
|
||||
<property name="title" translatable="yes">Model Button</property>
|
||||
<property name="resizable">0</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar"/>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="margin-start">80</property>
|
||||
<property name="margin-end">80</property>
|
||||
<property name="margin-top">80</property>
|
||||
<property name="margin-bottom">80</property>
|
||||
<child>
|
||||
<object class="GtkMenuButton">
|
||||
<property name="popover">thing_a</property>
|
||||
<property name="label">_Color</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuButton">
|
||||
<property name="popover">thing_b</property>
|
||||
<property name="label">_Flavors</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuButton">
|
||||
<property name="popover">thing_c</property>
|
||||
<property name="label">_Tools</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkPopover" id="thing_a">
|
||||
<style>
|
||||
<class name="menu"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="action-name">win.color</property>
|
||||
<property name="action-target">'red'</property>
|
||||
<property name="text">Red</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="action-name">win.color</property>
|
||||
<property name="action-target">'green'</property>
|
||||
<property name="text">Green</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="action-name">win.color</property>
|
||||
<property name="action-target">'blue'</property>
|
||||
<property name="text">Blue</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkPopover" id="thing_b">
|
||||
<style>
|
||||
<class name="menu"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="action-name">win.chocolate</property>
|
||||
<property name="text">Chocolate</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="action-name">win.vanilla</property>
|
||||
<property name="text">Vanilla</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator"/>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="action-name">win.sprinkles</property>
|
||||
<property name="text">Add Sprinkles</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkPopover" id="thing_c">
|
||||
<style>
|
||||
<class name="menu"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="text">Hammer</property>
|
||||
<property name="role">check</property>
|
||||
<signal name="clicked" handler="modelbutton_tool_clicked"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="text">Screwdriver</property>
|
||||
<property name="role">check</property>
|
||||
<signal name="clicked" handler="modelbutton_tool_clicked"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="text">Drill</property>
|
||||
<property name="role">check</property>
|
||||
<signal name="clicked" handler="modelbutton_tool_clicked"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
220
demos/gtk-demo/neon.glsl
Normal file
220
demos/gtk-demo/neon.glsl
Normal file
@@ -0,0 +1,220 @@
|
||||
// Originally from: https://www.shadertoy.com/view/WlByzy
|
||||
// License CC0: Neonwave style road, sun and city
|
||||
// The result of a bit of experimenting with neonwave style colors.
|
||||
|
||||
#define PI 3.141592654
|
||||
#define TAU (2.0*PI)
|
||||
|
||||
#define TIME iTime
|
||||
#define RESOLUTION iResolution
|
||||
|
||||
vec3 hsv2rgb(vec3 c) {
|
||||
const vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
|
||||
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
|
||||
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
|
||||
}
|
||||
|
||||
float hash(in float co) {
|
||||
return fract(sin(co*12.9898) * 13758.5453);
|
||||
}
|
||||
|
||||
float hash(in vec2 co) {
|
||||
return fract(sin(dot(co.xy ,vec2(12.9898,58.233))) * 13758.5453);
|
||||
}
|
||||
|
||||
float psin(float a) {
|
||||
return 0.5 + 0.5*sin(a);
|
||||
}
|
||||
|
||||
float mod1(inout float p, float size) {
|
||||
float halfsize = size*0.5;
|
||||
float c = floor((p + halfsize)/size);
|
||||
p = mod(p + halfsize, size) - halfsize;
|
||||
return c;
|
||||
}
|
||||
|
||||
float circle(vec2 p, float r) {
|
||||
return length(p) - r;
|
||||
}
|
||||
|
||||
float box(vec2 p, vec2 b) {
|
||||
vec2 d = abs(p)-b;
|
||||
return length(max(d,0.0)) + min(max(d.x,d.y),0.0);
|
||||
}
|
||||
|
||||
float planex(vec2 p, float w) {
|
||||
return abs(p.y) - w;
|
||||
}
|
||||
|
||||
float planey(vec2 p, float w) {
|
||||
return abs(p.x) - w;
|
||||
}
|
||||
|
||||
float pmin(float a, float b, float k) {
|
||||
float h = clamp( 0.5+0.5*(b-a)/k, 0.0, 1.0 );
|
||||
return mix( b, a, h ) - k*h*(1.0-h);
|
||||
}
|
||||
|
||||
float pmax(float a, float b, float k) {
|
||||
return -pmin(-a, -b, k);
|
||||
}
|
||||
|
||||
float sun(vec2 p) {
|
||||
const float ch = 0.0125;
|
||||
vec2 sp = p;
|
||||
vec2 cp = p;
|
||||
mod1(cp.y, ch*6.0);
|
||||
|
||||
float d0 = circle(sp, 0.5);
|
||||
float d1 = planex(cp, ch);
|
||||
float d2 = p.y+ch*3.0;
|
||||
|
||||
float d = d0;
|
||||
d = pmax(d, -max(d1, d2), ch*2.0);
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
float city(vec2 p) {
|
||||
float sd = circle(p, 0.5);
|
||||
float cd = 1E6;
|
||||
|
||||
const float count = 5.0;
|
||||
const float width = 0.1;
|
||||
|
||||
for (float i = 0.0; i < count; ++i) {
|
||||
vec2 pp = p;
|
||||
pp.x += i*width/count;
|
||||
float nn = mod1(pp.x, width);
|
||||
float rr = hash(nn+sqrt(3.0)*i);
|
||||
float dd = box(pp-vec2(0.0, -0.5), vec2(0.02, 0.35*(1.0-smoothstep(0.0, 5.0, abs(nn)))*rr+0.1));
|
||||
cd = min(cd, dd);
|
||||
}
|
||||
|
||||
return max(sd,cd);
|
||||
}
|
||||
vec3 sunEffect(vec2 p) {
|
||||
float aa = 4.0 / RESOLUTION.y;
|
||||
|
||||
vec3 col = vec3(0.1);
|
||||
vec3 skyCol1 = hsv2rgb(vec3(283.0/360.0, 0.83, 0.16));
|
||||
vec3 skyCol2 = hsv2rgb(vec3(297.0/360.0, 0.79, 0.43));
|
||||
col = mix(skyCol1, skyCol2, pow(clamp(0.5*(1.0+p.y+0.1*sin(4.0*p.x+TIME*0.5)), 0.0, 1.0), 4.0));
|
||||
|
||||
p.y -= 0.375;
|
||||
float ds = sun(p);
|
||||
float dc = city(p);
|
||||
|
||||
float dd = circle(p, 0.5);
|
||||
|
||||
vec3 sunCol = mix(vec3(1.0, 1.0, 0.0), vec3(1.0, 0.0, 1.0), clamp(0.5 - 1.0*p.y, 0.0, 1.0));
|
||||
vec3 glareCol = sqrt(sunCol);
|
||||
vec3 cityCol = sunCol*sunCol;
|
||||
|
||||
col += glareCol*(exp(-30.0*ds))*step(0.0, ds);
|
||||
|
||||
|
||||
float t1 = smoothstep(0.0, 0.075, -dd);
|
||||
float t2 = smoothstep(0.0, 0.3, -dd);
|
||||
col = mix(col, sunCol, smoothstep(-aa, 0.0, -ds));
|
||||
col = mix(col, glareCol, smoothstep(-aa, 0.0, -dc)*t1);
|
||||
col += vec3(0.0, 0.25, 0.0)*(exp(-90.0*dc))*step(0.0, dc)*t2;
|
||||
|
||||
// col += 0.3*psin(d*400);
|
||||
|
||||
return col;
|
||||
}
|
||||
|
||||
float ground(vec2 p) {
|
||||
p.y += TIME*80.0;
|
||||
p *= 0.075;
|
||||
vec2 gp = p;
|
||||
gp = fract(gp) - vec2(0.5);
|
||||
float d0 = abs(gp.x);
|
||||
float d1 = abs(gp.y);
|
||||
float d2 = circle(gp, 0.05);
|
||||
|
||||
const float rw = 2.5;
|
||||
const float sw = 0.0125;
|
||||
|
||||
vec2 rp = p;
|
||||
mod1(rp.y, 12.0);
|
||||
float d3 = abs(rp.x) - rw;
|
||||
float d4 = abs(d3) - sw*2.0;
|
||||
float d5 = box(rp, vec2(sw*2.0, 2.0));
|
||||
vec2 sp = p;
|
||||
mod1(sp.y, 4.0);
|
||||
sp.x = abs(sp.x);
|
||||
sp -= vec2(rw - 0.125, 0.0);
|
||||
float d6 = box(sp, vec2(sw, 1.0));
|
||||
|
||||
float d = d0;
|
||||
d = pmin(d, d1, 0.1);
|
||||
d = max(d, -d3);
|
||||
d = min(d, d4);
|
||||
d = min(d, d5);
|
||||
d = min(d, d6);
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
vec3 groundEffect(vec2 p) {
|
||||
vec3 ro = vec3(0.0, 20.0, 0.0);
|
||||
vec3 ww = normalize(vec3(0.0, -0.025, 1.0));
|
||||
vec3 uu = normalize(cross(vec3(0.0,1.0,0.0), ww));
|
||||
vec3 vv = normalize(cross(ww,uu));
|
||||
vec3 rd = normalize(p.x*uu + p.y*vv + 2.5*ww);
|
||||
|
||||
float distg = (-9.0 - ro.y)/rd.y;
|
||||
|
||||
const vec3 shineCol = 0.75*vec3(0.5, 0.75, 1.0);
|
||||
const vec3 gridCol = vec3(1.0);
|
||||
|
||||
vec3 col = vec3(0.0);
|
||||
if (distg > 0.0) {
|
||||
vec3 pg = ro + rd*distg;
|
||||
float aa = length(dFdx(pg))*0.0002*RESOLUTION.x;
|
||||
|
||||
float dg = ground(pg.xz);
|
||||
|
||||
col = mix(col, gridCol, smoothstep(-aa, 0.0, -(dg+0.0175)));
|
||||
col += shineCol*(exp(-10.0*clamp(dg, 0.0, 1.0)));
|
||||
col = clamp(col, 0.0, 1.0);
|
||||
|
||||
// col += 0.3*psin(dg*100);
|
||||
col *= pow(1.0-smoothstep(ro.y*3.0, 220.0+ro.y*2.0, distg), 2.0);
|
||||
}
|
||||
|
||||
return col;
|
||||
}
|
||||
|
||||
vec3 postProcess(vec3 col, vec2 q) {
|
||||
col = clamp(col,0.0,1.0);
|
||||
// col=pow(col,vec3(0.75));
|
||||
col=col*0.6+0.4*col*col*(3.0-2.0*col);
|
||||
col=mix(col, vec3(dot(col, vec3(0.33))), -0.4);
|
||||
col*=0.5+0.5*pow(19.0*q.x*q.y*(1.0-q.x)*(1.0-q.y),0.7);
|
||||
return col;
|
||||
}
|
||||
|
||||
vec3 effect(vec2 p, vec2 q) {
|
||||
vec3 col = vec3(0.0);
|
||||
|
||||
vec2 off = vec2(0.0, 0.0);
|
||||
|
||||
col += sunEffect(p+off);
|
||||
col += groundEffect(p+off);
|
||||
|
||||
col = postProcess(col, q);
|
||||
return col;
|
||||
}
|
||||
|
||||
void mainImage(out vec4 fragColor, vec2 fragCoord) {
|
||||
vec2 q = fragCoord/iResolution.xy;
|
||||
vec2 p = -1. + 2. * q;
|
||||
p.x *= RESOLUTION.x / RESOLUTION.y;
|
||||
|
||||
vec3 col = effect(p, q);
|
||||
|
||||
fragColor = vec4(col, 1.0);
|
||||
}
|
@@ -2,7 +2,7 @@
|
||||
*
|
||||
* Shows widgets in static positions over a main widget.
|
||||
*
|
||||
* The overlayed widgets can be interactive controls such
|
||||
* The overlaid widgets can be interactive controls such
|
||||
* as the entry in this example, or just decorative, like
|
||||
* the big blue label.
|
||||
*/
|
||||
|
@@ -48,15 +48,17 @@ void
|
||||
gtk_nuclear_snapshot (GtkSnapshot *snapshot,
|
||||
double width,
|
||||
double height,
|
||||
double rotation)
|
||||
double rotation,
|
||||
gboolean draw_background)
|
||||
{
|
||||
#define RADIUS 0.3
|
||||
cairo_t *cr;
|
||||
double size;
|
||||
|
||||
gtk_snapshot_append_color (snapshot,
|
||||
&(GdkRGBA) { 0.9, 0.75, 0.15, 1.0 },
|
||||
&GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
if (draw_background)
|
||||
gtk_snapshot_append_color (snapshot,
|
||||
&(GdkRGBA) { 0.9, 0.75, 0.15, 1.0 },
|
||||
&GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
|
||||
size = MIN (width, height);
|
||||
cr = gtk_snapshot_append_cairo (snapshot,
|
||||
@@ -93,7 +95,8 @@ gtk_nuclear_icon_snapshot (GdkPaintable *paintable,
|
||||
|
||||
gtk_nuclear_snapshot (snapshot,
|
||||
width, height,
|
||||
nuclear->rotation);
|
||||
nuclear->rotation,
|
||||
TRUE);
|
||||
}
|
||||
|
||||
static GdkPaintableFlags
|
||||
@@ -161,6 +164,7 @@ do_paintable (GtkWidget *do_widget)
|
||||
gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Nuclear Icon");
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 300, 200);
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
|
||||
nuclear = gtk_nuclear_icon_new (0.0);
|
||||
image = gtk_image_new_from_paintable (nuclear);
|
||||
|
@@ -6,10 +6,11 @@
|
||||
void gtk_nuclear_snapshot (GtkSnapshot *snapshot,
|
||||
double width,
|
||||
double height,
|
||||
double rotation);
|
||||
double rotation,
|
||||
gboolean draw_background);
|
||||
|
||||
GdkPaintable * gtk_nuclear_icon_new (double rotation);
|
||||
GdkPaintable * gtk_nuclear_animation_new (void);
|
||||
GdkPaintable * gtk_nuclear_animation_new (gboolean draw_background);
|
||||
GtkMediaStream *gtk_nuclear_media_stream_new (void);
|
||||
|
||||
#endif /* __PAINTABLE_H__ */
|
||||
|
@@ -33,6 +33,8 @@ struct _GtkNuclearAnimation
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
gboolean draw_background;
|
||||
|
||||
/* This variable stores the progress of our animation.
|
||||
* We just count upwards until we hit MAX_PROGRESS and
|
||||
* then start from scratch.
|
||||
@@ -64,7 +66,8 @@ gtk_nuclear_animation_snapshot (GdkPaintable *paintable,
|
||||
/* We call the function from the previous example here. */
|
||||
gtk_nuclear_snapshot (snapshot,
|
||||
width, height,
|
||||
2 * G_PI * nuclear->progress / MAX_PROGRESS);
|
||||
2 * G_PI * nuclear->progress / MAX_PROGRESS,
|
||||
nuclear->draw_background);
|
||||
}
|
||||
|
||||
static GdkPaintable *
|
||||
@@ -175,9 +178,15 @@ gtk_nuclear_animation_init (GtkNuclearAnimation *nuclear)
|
||||
|
||||
/* And finally, we add the simple constructor we declared in the header. */
|
||||
GdkPaintable *
|
||||
gtk_nuclear_animation_new (void)
|
||||
gtk_nuclear_animation_new (gboolean draw_background)
|
||||
{
|
||||
return g_object_new (GTK_TYPE_NUCLEAR_ANIMATION, NULL);
|
||||
GtkNuclearAnimation *nuclear;
|
||||
|
||||
nuclear = g_object_new (GTK_TYPE_NUCLEAR_ANIMATION, NULL);
|
||||
|
||||
nuclear->draw_background = draw_background;
|
||||
|
||||
return GDK_PAINTABLE (nuclear);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
@@ -193,8 +202,9 @@ do_paintable_animated (GtkWidget *do_widget)
|
||||
gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Nuclear Animation");
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 300, 200);
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
|
||||
nuclear = gtk_nuclear_animation_new ();
|
||||
nuclear = gtk_nuclear_animation_new (TRUE);
|
||||
image = gtk_image_new_from_paintable (nuclear);
|
||||
gtk_window_set_child (GTK_WINDOW (window), image);
|
||||
g_object_unref (nuclear);
|
||||
|
186
demos/gtk-demo/paintable_emblem.c
Normal file
186
demos/gtk-demo/paintable_emblem.c
Normal file
@@ -0,0 +1,186 @@
|
||||
/* Paintable/Emblems
|
||||
*
|
||||
* This demo shows how GdkPaintable can be used to
|
||||
* overlay an emblem on top of an icon. The emblem
|
||||
* can either be another icon, or an arbitrary
|
||||
* paintable.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "paintable.h"
|
||||
|
||||
static GtkWidget *window = NULL;
|
||||
|
||||
#define DEMO_TYPE_ICON (demo_icon_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (DemoIcon, demo_icon, DEMO, ICON, GObject)
|
||||
|
||||
struct _DemoIcon
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
GdkPaintable *icon;
|
||||
GdkPaintable *emblem;
|
||||
GdkPaintableFlags flags;
|
||||
};
|
||||
|
||||
struct _DemoIconClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
void
|
||||
demo_icon_snapshot (GdkPaintable *paintable,
|
||||
GtkSnapshot *snapshot,
|
||||
double width,
|
||||
double height)
|
||||
{
|
||||
DemoIcon *self = DEMO_ICON (paintable);
|
||||
|
||||
gdk_paintable_snapshot (self->icon, snapshot, width, height);
|
||||
gtk_snapshot_save (snapshot);
|
||||
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (0.5 * width, 0));
|
||||
gdk_paintable_snapshot (self->emblem, snapshot, 0.5 * width, 0.5 * height);
|
||||
gtk_snapshot_restore (snapshot);
|
||||
}
|
||||
|
||||
static GdkPaintableFlags
|
||||
demo_icon_get_flags (GdkPaintable *paintable)
|
||||
{
|
||||
DemoIcon *self = DEMO_ICON (paintable);
|
||||
|
||||
return self->flags;
|
||||
}
|
||||
|
||||
static void
|
||||
demo_icon_paintable_init (GdkPaintableInterface *iface)
|
||||
{
|
||||
iface->snapshot = demo_icon_snapshot;
|
||||
iface->get_flags = demo_icon_get_flags;
|
||||
}
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (DemoIcon, demo_icon, G_TYPE_OBJECT,
|
||||
G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE,
|
||||
demo_icon_paintable_init))
|
||||
|
||||
static void
|
||||
demo_icon_dispose (GObject *object)
|
||||
{
|
||||
DemoIcon *self = DEMO_ICON (object);
|
||||
|
||||
g_signal_handlers_disconnect_by_func (self->emblem,
|
||||
gdk_paintable_invalidate_contents,
|
||||
self);
|
||||
|
||||
g_clear_object (&self->icon);
|
||||
g_clear_object (&self->emblem);
|
||||
|
||||
G_OBJECT_CLASS (demo_icon_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
demo_icon_class_init (DemoIconClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->dispose = demo_icon_dispose;
|
||||
}
|
||||
|
||||
static void
|
||||
demo_icon_init (DemoIcon *self)
|
||||
{
|
||||
self->flags = GDK_PAINTABLE_STATIC_SIZE | GDK_PAINTABLE_STATIC_CONTENTS;
|
||||
}
|
||||
|
||||
GdkPaintable *
|
||||
demo_icon_new_with_paintable (const char *icon_name,
|
||||
GdkPaintable *emblem)
|
||||
{
|
||||
GtkIconTheme *theme;
|
||||
GtkIconPaintable *icon;
|
||||
DemoIcon *self;
|
||||
|
||||
theme = gtk_icon_theme_get_for_display (gdk_display_get_default ());
|
||||
|
||||
icon = gtk_icon_theme_lookup_icon (theme,
|
||||
icon_name, NULL,
|
||||
128, 1,
|
||||
GTK_TEXT_DIR_LTR, 0);
|
||||
|
||||
self = g_object_new (DEMO_TYPE_ICON, NULL);
|
||||
|
||||
self->icon = GDK_PAINTABLE (icon);
|
||||
self->emblem = emblem;
|
||||
|
||||
if ((gdk_paintable_get_flags (emblem) & GDK_PAINTABLE_STATIC_CONTENTS) == 0)
|
||||
{
|
||||
self->flags &= ~GDK_PAINTABLE_STATIC_CONTENTS;
|
||||
|
||||
g_signal_connect_swapped (emblem, "invalidate-contents",
|
||||
G_CALLBACK (gdk_paintable_invalidate_contents), self);
|
||||
}
|
||||
|
||||
return GDK_PAINTABLE (self);
|
||||
}
|
||||
|
||||
GdkPaintable *
|
||||
demo_icon_new (const char *icon_name,
|
||||
const char *emblem_name)
|
||||
{
|
||||
GtkIconTheme *theme;
|
||||
GtkIconPaintable *emblem;
|
||||
|
||||
theme = gtk_icon_theme_get_for_display (gdk_display_get_default ());
|
||||
|
||||
emblem = gtk_icon_theme_lookup_icon (theme,
|
||||
emblem_name, NULL,
|
||||
128, 1,
|
||||
GTK_TEXT_DIR_LTR, 0);
|
||||
|
||||
return GDK_PAINTABLE (demo_icon_new_with_paintable (icon_name,
|
||||
GDK_PAINTABLE (emblem)));
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_paintable_emblem (GtkWidget *do_widget)
|
||||
{
|
||||
GdkPaintable *icon;
|
||||
GtkWidget *grid;
|
||||
GtkWidget *image;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Emblems");
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 300, 200);
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
|
||||
grid = gtk_grid_new ();
|
||||
|
||||
icon = demo_icon_new ("folder", "starred");
|
||||
image = gtk_image_new_from_paintable (icon);
|
||||
gtk_widget_set_hexpand (image, TRUE);
|
||||
gtk_widget_set_vexpand (image, TRUE);
|
||||
gtk_grid_attach (GTK_GRID (grid), image, 0, 0, 1, 1);
|
||||
|
||||
icon = demo_icon_new_with_paintable ("drive-multidisk",
|
||||
gtk_nuclear_animation_new (FALSE));
|
||||
image = gtk_image_new_from_paintable (icon);
|
||||
gtk_widget_set_hexpand (image, TRUE);
|
||||
gtk_widget_set_vexpand (image, TRUE);
|
||||
gtk_grid_attach (GTK_GRID (grid), image, 1, 0, 1, 1);
|
||||
|
||||
gtk_window_set_child (GTK_WINDOW (window), grid);
|
||||
g_object_unref (icon);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
|
||||
return window;
|
||||
}
|
||||
|
@@ -74,7 +74,8 @@ gtk_nuclear_media_stream_snapshot (GdkPaintable *paintable,
|
||||
/* We call the function from the previous example here. */
|
||||
gtk_nuclear_snapshot (snapshot,
|
||||
width, height,
|
||||
2 * G_PI * nuclear->progress / DURATION);
|
||||
2 * G_PI * nuclear->progress / DURATION,
|
||||
TRUE);
|
||||
}
|
||||
|
||||
static GdkPaintable *
|
||||
|
@@ -61,10 +61,6 @@ create_pane_options (GtkPaned *paned,
|
||||
child2 = gtk_paned_get_end_child (paned);
|
||||
|
||||
frame = gtk_frame_new (frame_label);
|
||||
gtk_widget_set_margin_start (frame, 4);
|
||||
gtk_widget_set_margin_end (frame, 4);
|
||||
gtk_widget_set_margin_top (frame, 4);
|
||||
gtk_widget_set_margin_bottom (frame, 4);
|
||||
|
||||
table = gtk_grid_new ();
|
||||
gtk_frame_set_child (GTK_FRAME (frame), table);
|
||||
@@ -79,7 +75,7 @@ create_pane_options (GtkPaned *paned,
|
||||
|
||||
check_button = gtk_check_button_new_with_mnemonic ("_Shrink");
|
||||
gtk_grid_attach (GTK_GRID (table), check_button, 0, 2, 1, 1);
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button), TRUE);
|
||||
gtk_check_button_set_active (GTK_CHECK_BUTTON (check_button), TRUE);
|
||||
g_signal_connect (check_button, "toggled",
|
||||
G_CALLBACK (toggle_shrink), child1);
|
||||
|
||||
@@ -88,13 +84,13 @@ create_pane_options (GtkPaned *paned,
|
||||
|
||||
check_button = gtk_check_button_new_with_mnemonic ("_Resize");
|
||||
gtk_grid_attach (GTK_GRID (table), check_button, 1, 1, 1, 1);
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button), TRUE);
|
||||
gtk_check_button_set_active (GTK_CHECK_BUTTON (check_button), TRUE);
|
||||
g_signal_connect (check_button, "toggled",
|
||||
G_CALLBACK (toggle_resize), child2);
|
||||
|
||||
check_button = gtk_check_button_new_with_mnemonic ("_Shrink");
|
||||
gtk_grid_attach (GTK_GRID (table), check_button, 1, 2, 1, 1);
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button), TRUE);
|
||||
gtk_check_button_set_active (GTK_CHECK_BUTTON (check_button), TRUE);
|
||||
g_signal_connect (check_button, "toggled",
|
||||
G_CALLBACK (toggle_shrink), child2);
|
||||
|
||||
@@ -110,6 +106,7 @@ do_panes (GtkWidget *do_widget)
|
||||
GtkWidget *vpaned;
|
||||
GtkWidget *button;
|
||||
GtkWidget *vbox;
|
||||
GtkWidget *box;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
@@ -120,33 +117,42 @@ do_panes (GtkWidget *do_widget)
|
||||
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Paned Widgets");
|
||||
|
||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 8);
|
||||
gtk_widget_set_margin_start (vbox, 8);
|
||||
gtk_widget_set_margin_end (vbox, 8);
|
||||
gtk_widget_set_margin_top (vbox, 8);
|
||||
gtk_widget_set_margin_bottom (vbox, 8);
|
||||
gtk_window_set_child (GTK_WINDOW (window), vbox);
|
||||
|
||||
frame = gtk_frame_new (NULL);
|
||||
gtk_box_append (GTK_BOX (vbox), frame);
|
||||
|
||||
vpaned = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
|
||||
gtk_widget_set_margin_start (vpaned, 5);
|
||||
gtk_widget_set_margin_end (vpaned, 5);
|
||||
gtk_widget_set_margin_top (vpaned, 5);
|
||||
gtk_widget_set_margin_bottom (vpaned, 5);
|
||||
gtk_box_append (GTK_BOX (vbox), vpaned);
|
||||
gtk_frame_set_child (GTK_FRAME (frame), vpaned);
|
||||
|
||||
hpaned = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);
|
||||
gtk_paned_set_start_child (GTK_PANED (vpaned), hpaned);
|
||||
|
||||
frame = gtk_frame_new (NULL);
|
||||
gtk_widget_set_size_request (frame, 60, 60);
|
||||
gtk_paned_set_start_child (GTK_PANED (hpaned), frame);
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_widget_set_size_request (box, 60, 60);
|
||||
gtk_paned_set_start_child (GTK_PANED (hpaned), box);
|
||||
|
||||
button = gtk_button_new_with_mnemonic ("_Hi there");
|
||||
gtk_frame_set_child (GTK_FRAME (frame), button);
|
||||
gtk_widget_set_margin_start (button, 4);
|
||||
gtk_widget_set_margin_end (button, 4);
|
||||
gtk_widget_set_margin_top (button, 4);
|
||||
gtk_widget_set_margin_bottom (button, 4);
|
||||
gtk_widget_set_hexpand (button, TRUE);
|
||||
gtk_widget_set_vexpand (button, TRUE);
|
||||
gtk_box_append (GTK_BOX (box), button);
|
||||
|
||||
frame = gtk_frame_new (NULL);
|
||||
gtk_widget_set_size_request (frame, 80, 60);
|
||||
gtk_paned_set_end_child (GTK_PANED (hpaned), frame);
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_widget_set_size_request (box, 80, 60);
|
||||
gtk_paned_set_end_child (GTK_PANED (hpaned), box);
|
||||
|
||||
frame = gtk_frame_new (NULL);
|
||||
gtk_widget_set_size_request (frame, 60, 80);
|
||||
gtk_paned_set_end_child (GTK_PANED (vpaned), frame);
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_widget_set_size_request (box, 60, 80);
|
||||
gtk_paned_set_end_child (GTK_PANED (vpaned), box);
|
||||
|
||||
/* Now create toggle buttons to control sizing */
|
||||
|
||||
|
@@ -4,10 +4,9 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
static GtkWidget *window = NULL;
|
||||
|
||||
/* Create an object for the pegs that get moved around in the game.
|
||||
*
|
||||
* We implement the GdkPaintable interface for them, so we can use GtkPicture
|
||||
@@ -56,11 +55,25 @@ solitaire_peg_get_flags (GdkPaintable *paintable)
|
||||
return GDK_PAINTABLE_STATIC_CONTENTS | GDK_PAINTABLE_STATIC_SIZE;
|
||||
}
|
||||
|
||||
static int
|
||||
solitaire_peg_get_intrinsic_width (GdkPaintable *paintable)
|
||||
{
|
||||
return 32;
|
||||
}
|
||||
|
||||
static int
|
||||
solitaire_peg_get_intrinsic_height (GdkPaintable *paintable)
|
||||
{
|
||||
return 32;
|
||||
}
|
||||
|
||||
static void
|
||||
solitaire_peg_paintable_init (GdkPaintableInterface *iface)
|
||||
{
|
||||
iface->snapshot = solitaire_peg_snapshot;
|
||||
iface->get_flags = solitaire_peg_get_flags;
|
||||
iface->get_intrinsic_width = solitaire_peg_get_intrinsic_width;
|
||||
iface->get_intrinsic_height = solitaire_peg_get_intrinsic_height;
|
||||
}
|
||||
|
||||
/* When defining the GType, we need to implement the GdkPaintable interface */
|
||||
@@ -103,6 +116,95 @@ solitaire_peg_new (void)
|
||||
return g_object_new (SOLITAIRE_TYPE_PEG, NULL);
|
||||
}
|
||||
|
||||
/*** Helper for finding a win ***/
|
||||
|
||||
static void
|
||||
ended (GObject *object)
|
||||
{
|
||||
g_object_unref (object);
|
||||
}
|
||||
|
||||
static void
|
||||
celebrate (gboolean win)
|
||||
{
|
||||
char *path;
|
||||
GtkMediaStream *stream;
|
||||
|
||||
if (win)
|
||||
path = g_build_filename (GTK_DATADIR, "sounds", "freedesktop", "stereo", "complete.oga", NULL);
|
||||
else
|
||||
path = g_build_filename (GTK_DATADIR, "sounds", "freedesktop", "stereo", "dialog-error.oga", NULL);
|
||||
stream = gtk_media_file_new_for_filename (path);
|
||||
gtk_media_stream_set_volume (stream, 1.0);
|
||||
gtk_media_stream_play (stream);
|
||||
|
||||
g_signal_connect (stream, "notify::ended", G_CALLBACK (ended), NULL);
|
||||
g_free (path);
|
||||
}
|
||||
|
||||
static int
|
||||
check_move (GtkGrid *grid,
|
||||
int x,
|
||||
int y,
|
||||
int dx,
|
||||
int dy)
|
||||
{
|
||||
GtkWidget *image;
|
||||
/* We have a peg at x, y.
|
||||
* Check if we can move the peg to x + 2*dx, y + 2*dy
|
||||
*/
|
||||
image = gtk_grid_get_child_at (grid, x + dx, y + dy);
|
||||
if (!GTK_IS_IMAGE (image) ||
|
||||
!SOLITAIRE_IS_PEG (gtk_image_get_paintable (GTK_IMAGE (image))))
|
||||
return 0;
|
||||
|
||||
image = gtk_grid_get_child_at (grid, x + 2*dx, y + 2*dy);
|
||||
if (!GTK_IMAGE (image) ||
|
||||
SOLITAIRE_IS_PEG (gtk_image_get_paintable (GTK_IMAGE (image))))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
check_for_end (GtkGrid *grid)
|
||||
{
|
||||
GtkWidget *image;
|
||||
int x, y;
|
||||
int pegs;
|
||||
int moves;
|
||||
|
||||
pegs = 0;
|
||||
moves = 0;
|
||||
for (x = 0; x < 7; x++)
|
||||
{
|
||||
for (y = 0; y < 7; y++)
|
||||
{
|
||||
image = gtk_grid_get_child_at (grid, x, y);
|
||||
if (GTK_IS_IMAGE (image) &&
|
||||
SOLITAIRE_IS_PEG (gtk_image_get_paintable (GTK_IMAGE (image))))
|
||||
{
|
||||
pegs++;
|
||||
moves += check_move (grid, x, y, 1, 0);
|
||||
moves += check_move (grid, x, y, -1, 0);
|
||||
moves += check_move (grid, x, y, 0, 1);
|
||||
moves += check_move (grid, x, y, 0, -1);
|
||||
}
|
||||
|
||||
if (pegs > 1 && moves > 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
image = gtk_grid_get_child_at (grid, 3, 3);
|
||||
if (pegs == 1 &&
|
||||
SOLITAIRE_IS_PEG (gtk_image_get_paintable (GTK_IMAGE (image))))
|
||||
celebrate (TRUE);
|
||||
else if (moves == 0)
|
||||
celebrate (FALSE);
|
||||
}
|
||||
|
||||
|
||||
/*** DRAG AND DROP ***/
|
||||
|
||||
/* The user tries to start a drag operation.
|
||||
@@ -154,7 +256,7 @@ drag_begin (GtkDragSource *source,
|
||||
gtk_image_clear (GTK_IMAGE (image));
|
||||
}
|
||||
|
||||
/* Thie is called once a drag operation has ended (successfully or not).
|
||||
/* This is called once a drag operation has ended (successfully or not).
|
||||
* We want to undo what we did in drag_begin() above and react
|
||||
* to a potential move of the peg.
|
||||
*/
|
||||
@@ -255,29 +357,120 @@ drop_drop (GtkDropTarget *target,
|
||||
solitaire_peg_set_position (peg, image_x, image_y);
|
||||
gtk_image_set_from_paintable (GTK_IMAGE (image), GDK_PAINTABLE (peg));
|
||||
|
||||
/* Maybe we have something to celebrate */
|
||||
check_for_end (grid);
|
||||
|
||||
/* Success! */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
create_board (GtkWidget *window)
|
||||
{
|
||||
GtkWidget *grid;
|
||||
GtkWidget *image;
|
||||
int x, y;
|
||||
GtkDragSource *source;
|
||||
GtkDropTarget *target;
|
||||
GtkCssProvider *provider;
|
||||
const char css[] =
|
||||
".solitaire-field {"
|
||||
" border: 1px solid lightgray;"
|
||||
"}";
|
||||
|
||||
provider = gtk_css_provider_new ();
|
||||
gtk_css_provider_load_from_data (provider, css, -1);
|
||||
|
||||
grid = gtk_grid_new ();
|
||||
gtk_widget_set_halign (grid, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign (grid, GTK_ALIGN_CENTER);
|
||||
gtk_grid_set_row_spacing (GTK_GRID (grid), 6);
|
||||
gtk_grid_set_column_spacing (GTK_GRID (grid), 6);
|
||||
gtk_grid_set_row_homogeneous (GTK_GRID (grid), TRUE);
|
||||
gtk_grid_set_column_homogeneous (GTK_GRID (grid), TRUE);
|
||||
gtk_window_set_child (GTK_WINDOW (window), grid);
|
||||
|
||||
for (x = 0; x < 7; x++)
|
||||
{
|
||||
for (y = 0; y < 7; y++)
|
||||
{
|
||||
if ((x < 2 || x >= 5) && (y < 2 || y >= 5))
|
||||
continue;
|
||||
|
||||
image = gtk_image_new ();
|
||||
gtk_style_context_add_provider (gtk_widget_get_style_context (image),
|
||||
GTK_STYLE_PROVIDER (provider),
|
||||
800);
|
||||
gtk_widget_add_css_class (image, "solitaire-field");
|
||||
gtk_image_set_icon_size (GTK_IMAGE (image), GTK_ICON_SIZE_LARGE);
|
||||
if (x != 3 || y != 3)
|
||||
{
|
||||
SolitairePeg *peg = solitaire_peg_new ();
|
||||
solitaire_peg_set_position (peg, x, y);
|
||||
gtk_image_set_from_paintable (GTK_IMAGE (image), GDK_PAINTABLE (peg));
|
||||
}
|
||||
|
||||
gtk_grid_attach (GTK_GRID (grid), image, x, y, 1, 1);
|
||||
|
||||
/* Set up the drag source.
|
||||
* This is rather straightforward: Set the supported actions
|
||||
* (in our case, pegs can only be moved) and connect all the
|
||||
* relevant signals.
|
||||
* And because all drag'n'drop handling is done via event controllers,
|
||||
* we need to add the controller to the widget.
|
||||
*/
|
||||
source = gtk_drag_source_new ();
|
||||
gtk_drag_source_set_actions (source, GDK_ACTION_MOVE);
|
||||
g_signal_connect (source, "prepare", G_CALLBACK (drag_prepare), image);
|
||||
g_signal_connect (source, "drag-begin", G_CALLBACK (drag_begin), image);
|
||||
g_signal_connect (source, "drag-end", G_CALLBACK (drag_end), image);
|
||||
gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (source));
|
||||
|
||||
/* Set up the drop target.
|
||||
* This is more involved, because the game logic goes here.
|
||||
*/
|
||||
|
||||
/* First we specify the data we accept: pegs.
|
||||
* And we only want moves.
|
||||
*/
|
||||
target = gtk_drop_target_new (SOLITAIRE_TYPE_PEG, GDK_ACTION_MOVE);
|
||||
/* Then we connect our signals.
|
||||
*/
|
||||
g_signal_connect (target, "accept", G_CALLBACK (drop_accept), image);
|
||||
g_signal_connect (target, "drop", G_CALLBACK (drop_drop), image);
|
||||
/* Finally, like above, we add it to the widget.
|
||||
*/
|
||||
gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (target));
|
||||
}
|
||||
}
|
||||
|
||||
g_object_unref (provider);
|
||||
}
|
||||
|
||||
static void
|
||||
restart_game (GtkButton *button,
|
||||
GtkWidget *window)
|
||||
{
|
||||
create_board (window);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_peg_solitaire (GtkWidget *do_widget)
|
||||
{
|
||||
static GtkWidget *window = NULL;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
GtkWidget *header;
|
||||
GtkWidget *restart;
|
||||
GtkWidget *grid;
|
||||
GtkWidget *image;
|
||||
int x, y;
|
||||
GtkDragSource *source;
|
||||
GtkDropTarget *target;
|
||||
|
||||
window = gtk_window_new ();
|
||||
|
||||
restart = gtk_button_new_from_icon_name ("view-refresh-symbolic");
|
||||
g_signal_connect (restart, "clicked", G_CALLBACK (restart), NULL);
|
||||
g_signal_connect (restart, "clicked", G_CALLBACK (restart_game), window);
|
||||
|
||||
header = gtk_header_bar_new ();
|
||||
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), restart);
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Peg Solitaire");
|
||||
@@ -285,63 +478,7 @@ do_peg_solitaire (GtkWidget *do_widget)
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 400, 300);
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
|
||||
grid = gtk_grid_new ();
|
||||
gtk_widget_set_halign (grid, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign (grid, GTK_ALIGN_CENTER);
|
||||
gtk_grid_set_row_spacing (GTK_GRID (grid), 6);
|
||||
gtk_grid_set_column_spacing (GTK_GRID (grid), 6);
|
||||
gtk_grid_set_row_homogeneous (GTK_GRID (grid), TRUE);
|
||||
gtk_grid_set_column_homogeneous (GTK_GRID (grid), TRUE);
|
||||
gtk_window_set_child (GTK_WINDOW (window), grid);
|
||||
|
||||
for (x = 0; x < 7; x++)
|
||||
{
|
||||
for (y = 0; y < 7; y++)
|
||||
{
|
||||
if ((x < 2 || x >= 5) && (y < 2 || y >= 5))
|
||||
continue;
|
||||
|
||||
image = gtk_image_new ();
|
||||
if (x != 3 || y != 3)
|
||||
{
|
||||
SolitairePeg *peg = solitaire_peg_new ();
|
||||
solitaire_peg_set_position (peg, x, y);
|
||||
gtk_image_set_from_paintable (GTK_IMAGE (image), GDK_PAINTABLE (peg));
|
||||
}
|
||||
|
||||
gtk_grid_attach (GTK_GRID (grid), image, x, y, 1, 1);
|
||||
|
||||
/* Set up the drag source.
|
||||
* This is rather straightforward: Set the supported actions
|
||||
* (in our case, pegs can only be moved) and connect all the
|
||||
* relevant signals.
|
||||
* And because all drag'n'drop handling is done via event controllers,
|
||||
* we need to add the controller to the widget.
|
||||
*/
|
||||
source = gtk_drag_source_new ();
|
||||
gtk_drag_source_set_actions (source, GDK_ACTION_MOVE);
|
||||
g_signal_connect (source, "prepare", G_CALLBACK (drag_prepare), image);
|
||||
g_signal_connect (source, "drag-begin", G_CALLBACK (drag_begin), image);
|
||||
g_signal_connect (source, "drag-end", G_CALLBACK (drag_end), image);
|
||||
gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (source));
|
||||
|
||||
/* Set up the drop target.
|
||||
* This is more involved, because the game logic goes here.
|
||||
*/
|
||||
|
||||
/* First we specify the data we accept: pegs.
|
||||
* And we only want moves.
|
||||
*/
|
||||
target = gtk_drop_target_new (SOLITAIRE_TYPE_PEG, GDK_ACTION_MOVE);
|
||||
/* Then we connect our signals.
|
||||
*/
|
||||
g_signal_connect (target, "accept", G_CALLBACK (drop_accept), image);
|
||||
g_signal_connect (target, "drop", G_CALLBACK (drop_drop), image);
|
||||
/* Finally, like above, we add it to the widget.
|
||||
*/
|
||||
gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (target));
|
||||
}
|
||||
}
|
||||
create_board (window);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
|
@@ -6,11 +6,34 @@
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#define COLOR(r,g,b) { r/255., g/255., b/255., 1.0 }
|
||||
|
||||
GtkWidget *
|
||||
do_pickers (GtkWidget *do_widget)
|
||||
{
|
||||
static GtkWidget *window = NULL;
|
||||
GtkWidget *table, *label, *picker;
|
||||
GdkRGBA solarized[] = {
|
||||
COLOR (0xff, 0xff, 0xff),
|
||||
COLOR (0x07, 0x36, 0x42),
|
||||
COLOR (0xdc, 0x32, 0x2f),
|
||||
COLOR (0x85, 0x99, 0x00),
|
||||
COLOR (0xb5, 0x89, 0x00),
|
||||
COLOR (0x26, 0x8b, 0xd2),
|
||||
COLOR (0xd3, 0x36, 0x82),
|
||||
COLOR (0x2a, 0xa1, 0x98),
|
||||
COLOR (0xee, 0xe8, 0xd5),
|
||||
|
||||
COLOR (0x00, 0x00, 0x00),
|
||||
COLOR (0x00, 0x2b, 0x36),
|
||||
COLOR (0xcb, 0x4b, 0x16),
|
||||
COLOR (0x58, 0x6e, 0x75),
|
||||
COLOR (0x65, 0x7b, 0x83),
|
||||
COLOR (0x83, 0x94, 0x96),
|
||||
COLOR (0x6c, 0x71, 0xc4),
|
||||
COLOR (0x93, 0xa1, 0xa1),
|
||||
COLOR (0xfd, 0xf6, 0xe3),
|
||||
};
|
||||
|
||||
if (!window)
|
||||
{
|
||||
@@ -34,6 +57,13 @@ do_pickers (GtkWidget *do_widget)
|
||||
gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_hexpand (label, TRUE);
|
||||
picker = gtk_color_button_new ();
|
||||
gtk_color_button_set_title (GTK_COLOR_BUTTON (picker), "Solarized colors");
|
||||
gtk_color_chooser_add_palette (GTK_COLOR_CHOOSER (picker),
|
||||
GTK_ORIENTATION_HORIZONTAL,
|
||||
9,
|
||||
18,
|
||||
solarized);
|
||||
|
||||
gtk_grid_attach (GTK_GRID (table), label, 0, 0, 1, 1);
|
||||
gtk_grid_attach (GTK_GRID (table), picker, 1, 0, 1, 1);
|
||||
|
||||
|
@@ -1,228 +0,0 @@
|
||||
/* Pixbufs
|
||||
*
|
||||
* A GdkPixbuf represents an image, normally in RGB or RGBA format.
|
||||
* Pixbufs are normally used to load files from disk and perform
|
||||
* image scaling.
|
||||
*
|
||||
* This demo is not all that educational, but looks cool. It was written
|
||||
* by Extreme Pixbuf Hacker Federico Mena Quintero. It also shows
|
||||
* off how to use GtkDrawingArea to do a simple animation.
|
||||
*
|
||||
* Look at the Image demo for additional pixbuf usage examples.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <math.h>
|
||||
|
||||
#define BACKGROUND_NAME "/pixbufs/background.jpg"
|
||||
|
||||
static const char *image_names[] = {
|
||||
"/pixbufs/apple-red.png",
|
||||
"/pixbufs/gnome-applets.png",
|
||||
"/pixbufs/gnome-calendar.png",
|
||||
"/pixbufs/gnome-foot.png",
|
||||
"/pixbufs/gnome-gmush.png",
|
||||
"/pixbufs/gnome-gimp.png",
|
||||
"/pixbufs/gnome-gsame.png",
|
||||
"/pixbufs/gnu-keys.png"
|
||||
};
|
||||
|
||||
#define N_IMAGES G_N_ELEMENTS (image_names)
|
||||
|
||||
/* demo window */
|
||||
static GtkWidget *window = NULL;
|
||||
|
||||
/* Current frame */
|
||||
static GdkPixbuf *frame;
|
||||
|
||||
/* Background image */
|
||||
static GdkPixbuf *background;
|
||||
static int back_width, back_height;
|
||||
|
||||
/* Images */
|
||||
static GdkPixbuf *images[N_IMAGES];
|
||||
|
||||
/* Widgets */
|
||||
static GtkWidget *da;
|
||||
|
||||
/* Loads the images for the demo and returns whether the operation succeeded */
|
||||
static gboolean
|
||||
load_pixbufs (GError **error)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (background)
|
||||
return TRUE; /* already loaded earlier */
|
||||
|
||||
background = gdk_pixbuf_new_from_resource (BACKGROUND_NAME, error);
|
||||
if (!background)
|
||||
return FALSE; /* Note that "error" was filled with a GError */
|
||||
|
||||
back_width = gdk_pixbuf_get_width (background);
|
||||
back_height = gdk_pixbuf_get_height (background);
|
||||
|
||||
for (i = 0; i < N_IMAGES; i++)
|
||||
{
|
||||
images[i] = gdk_pixbuf_new_from_resource (image_names[i], error);
|
||||
|
||||
if (!images[i])
|
||||
return FALSE; /* Note that "error" was filled with a GError */
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Expose callback for the drawing area */
|
||||
static void
|
||||
draw_func (GtkDrawingArea *area,
|
||||
cairo_t *cr,
|
||||
int width,
|
||||
int height,
|
||||
gpointer data)
|
||||
{
|
||||
gdk_cairo_set_source_pixbuf (cr, frame, 0, 0);
|
||||
cairo_paint (cr);
|
||||
}
|
||||
|
||||
#define CYCLE_TIME 3000000 /* 3 seconds */
|
||||
|
||||
static gint64 start_time;
|
||||
|
||||
/* Handler to regenerate the frame */
|
||||
static gboolean
|
||||
on_tick (GtkWidget *widget,
|
||||
GdkFrameClock *frame_clock,
|
||||
gpointer data)
|
||||
{
|
||||
gint64 current_time;
|
||||
double f;
|
||||
int i;
|
||||
double xmid, ymid;
|
||||
double radius;
|
||||
|
||||
gdk_pixbuf_copy_area (background, 0, 0, back_width, back_height,
|
||||
frame, 0, 0);
|
||||
|
||||
if (start_time == 0)
|
||||
start_time = gdk_frame_clock_get_frame_time (frame_clock);
|
||||
|
||||
current_time = gdk_frame_clock_get_frame_time (frame_clock);
|
||||
f = ((current_time - start_time) % CYCLE_TIME) / (double)CYCLE_TIME;
|
||||
|
||||
xmid = back_width / 2.0;
|
||||
ymid = back_height / 2.0;
|
||||
|
||||
radius = MIN (xmid, ymid) / 2.0;
|
||||
|
||||
for (i = 0; i < N_IMAGES; i++)
|
||||
{
|
||||
double ang;
|
||||
int xpos, ypos;
|
||||
int iw, ih;
|
||||
double r;
|
||||
GdkRectangle r1, r2, dest;
|
||||
double k;
|
||||
|
||||
ang = 2.0 * G_PI * (double) i / N_IMAGES - f * 2.0 * G_PI;
|
||||
|
||||
iw = gdk_pixbuf_get_width (images[i]);
|
||||
ih = gdk_pixbuf_get_height (images[i]);
|
||||
|
||||
r = radius + (radius / 3.0) * sin (f * 2.0 * G_PI);
|
||||
|
||||
xpos = floor (xmid + r * cos (ang) - iw / 2.0 + 0.5);
|
||||
ypos = floor (ymid + r * sin (ang) - ih / 2.0 + 0.5);
|
||||
|
||||
k = (i & 1) ? sin (f * 2.0 * G_PI) : cos (f * 2.0 * G_PI);
|
||||
k = 2.0 * k * k;
|
||||
k = MAX (0.25, k);
|
||||
|
||||
r1.x = xpos;
|
||||
r1.y = ypos;
|
||||
r1.width = iw * k;
|
||||
r1.height = ih * k;
|
||||
|
||||
r2.x = 0;
|
||||
r2.y = 0;
|
||||
r2.width = back_width;
|
||||
r2.height = back_height;
|
||||
|
||||
if (gdk_rectangle_intersect (&r1, &r2, &dest))
|
||||
gdk_pixbuf_composite (images[i],
|
||||
frame,
|
||||
dest.x, dest.y,
|
||||
dest.width, dest.height,
|
||||
xpos, ypos,
|
||||
k, k,
|
||||
GDK_INTERP_NEAREST,
|
||||
((i & 1)
|
||||
? MAX (127, fabs (255 * sin (f * 2.0 * G_PI)))
|
||||
: MAX (127, fabs (255 * cos (f * 2.0 * G_PI)))));
|
||||
}
|
||||
|
||||
gtk_widget_queue_draw (da);
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_pixbufs (GtkWidget *do_widget)
|
||||
{
|
||||
if (!window)
|
||||
{
|
||||
GError *error;
|
||||
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Pixbufs");
|
||||
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
|
||||
error = NULL;
|
||||
if (!load_pixbufs (&error))
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
|
||||
dialog = gtk_message_dialog_new (GTK_WINDOW (window),
|
||||
GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
GTK_MESSAGE_ERROR,
|
||||
GTK_BUTTONS_CLOSE,
|
||||
"Failed to load an image: %s",
|
||||
error->message);
|
||||
|
||||
g_error_free (error);
|
||||
|
||||
g_signal_connect (dialog, "response",
|
||||
G_CALLBACK (gtk_window_destroy), NULL);
|
||||
|
||||
gtk_widget_show (dialog);
|
||||
}
|
||||
else
|
||||
{
|
||||
frame = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, back_width, back_height);
|
||||
|
||||
da = gtk_drawing_area_new ();
|
||||
|
||||
gtk_drawing_area_set_content_width (GTK_DRAWING_AREA (da), back_width);
|
||||
gtk_drawing_area_set_content_height (GTK_DRAWING_AREA (da), back_height);
|
||||
gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (da), draw_func, NULL, NULL);
|
||||
|
||||
gtk_window_set_child (GTK_WINDOW (window), da);
|
||||
|
||||
gtk_widget_add_tick_callback (da, on_tick, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
{
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
g_object_unref (frame);
|
||||
}
|
||||
|
||||
return window;
|
||||
}
|
@@ -189,7 +189,7 @@ do_rotated_text (GtkWidget *do_widget)
|
||||
/* Add a drawing area */
|
||||
drawing_area = gtk_drawing_area_new ();
|
||||
gtk_box_append (GTK_BOX (box), drawing_area);
|
||||
gtk_widget_add_css_class (drawing_area, GTK_STYLE_CLASS_VIEW);
|
||||
gtk_widget_add_css_class (drawing_area, "view");
|
||||
|
||||
gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (drawing_area),
|
||||
rotated_text_draw,
|
||||
|
201
demos/gtk-demo/shadertoy.c
Normal file
201
demos/gtk-demo/shadertoy.c
Normal file
@@ -0,0 +1,201 @@
|
||||
/* OpenGL/Shadertoy
|
||||
*
|
||||
* Generate pixels using a custom fragment shader.
|
||||
*
|
||||
* The names of the uniforms are compatible with the shaders on shadertoy.com, so
|
||||
* many of the shaders there work here too.
|
||||
*/
|
||||
#include <math.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <epoxy/gl.h>
|
||||
#include "gtkshadertoy.h"
|
||||
|
||||
static GtkWidget *demo_window = NULL;
|
||||
static GtkWidget *shadertoy = NULL;
|
||||
static GtkTextBuffer *textbuffer = NULL;
|
||||
|
||||
static void
|
||||
run (void)
|
||||
{
|
||||
GtkTextIter start, end;
|
||||
char *text;
|
||||
|
||||
gtk_text_buffer_get_bounds (textbuffer, &start, &end);
|
||||
text = gtk_text_buffer_get_text (textbuffer, &start, &end, FALSE);
|
||||
|
||||
gtk_shadertoy_set_image_shader (GTK_SHADERTOY (shadertoy), text);
|
||||
g_free (text);
|
||||
}
|
||||
|
||||
static void
|
||||
run_clicked_cb (GtkWidget *button,
|
||||
gpointer user_data)
|
||||
{
|
||||
run ();
|
||||
}
|
||||
|
||||
static void
|
||||
load_clicked_cb (GtkWidget *button,
|
||||
gpointer user_data)
|
||||
{
|
||||
const char *path = user_data;
|
||||
GBytes *initial_shader;
|
||||
|
||||
initial_shader = g_resources_lookup_data (path, 0, NULL);
|
||||
gtk_text_buffer_set_text (textbuffer, g_bytes_get_data (initial_shader, NULL), -1);
|
||||
g_bytes_unref (initial_shader);
|
||||
|
||||
run ();
|
||||
}
|
||||
|
||||
static void
|
||||
clear_clicked_cb (GtkWidget *button,
|
||||
gpointer user_data)
|
||||
{
|
||||
gtk_text_buffer_set_text (textbuffer, "", 0);
|
||||
}
|
||||
|
||||
static void
|
||||
close_window (GtkWidget *widget)
|
||||
{
|
||||
/* Reset the state */
|
||||
demo_window = NULL;
|
||||
shadertoy = NULL;
|
||||
textbuffer = NULL;
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
new_shadertoy (const char *path)
|
||||
{
|
||||
GBytes *shader;
|
||||
GtkWidget *toy;
|
||||
|
||||
toy = gtk_shadertoy_new ();
|
||||
shader = g_resources_lookup_data (path, 0, NULL);
|
||||
gtk_shadertoy_set_image_shader (GTK_SHADERTOY (toy),
|
||||
g_bytes_get_data (shader, NULL));
|
||||
g_bytes_unref (shader);
|
||||
|
||||
return toy;
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
new_button (const char *path)
|
||||
{
|
||||
GtkWidget *button, *toy;
|
||||
|
||||
button = gtk_button_new ();
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (load_clicked_cb), (char *)path);
|
||||
|
||||
toy = new_shadertoy (path);
|
||||
gtk_widget_set_size_request (toy, 64, 36);
|
||||
gtk_button_set_child (GTK_BUTTON (button), toy);
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_shadertoy_window (GtkWidget *do_widget)
|
||||
{
|
||||
GtkWidget *window, *box, *hbox, *button, *textview, *sw, *aspect, *centerbox;
|
||||
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Shadertoy");
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 690, 740);
|
||||
g_signal_connect (window, "destroy", G_CALLBACK (close_window), NULL);
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, FALSE);
|
||||
gtk_widget_set_margin_start (box, 12);
|
||||
gtk_widget_set_margin_end (box, 12);
|
||||
gtk_widget_set_margin_top (box, 12);
|
||||
gtk_widget_set_margin_bottom (box, 12);
|
||||
gtk_box_set_spacing (GTK_BOX (box), 6);
|
||||
gtk_window_set_child (GTK_WINDOW (window), box);
|
||||
|
||||
aspect = gtk_aspect_frame_new (0.5, 0.5, 1.77777, FALSE);
|
||||
gtk_widget_set_hexpand (aspect, TRUE);
|
||||
gtk_widget_set_vexpand (aspect, TRUE);
|
||||
gtk_box_append (GTK_BOX (box), aspect);
|
||||
|
||||
shadertoy = new_shadertoy ("/shadertoy/alienplanet.glsl");
|
||||
gtk_aspect_frame_set_child (GTK_ASPECT_FRAME (aspect), shadertoy);
|
||||
|
||||
sw = gtk_scrolled_window_new ();
|
||||
gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW (sw), 250);
|
||||
gtk_scrolled_window_set_has_frame (GTK_SCROLLED_WINDOW (sw), TRUE);
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
gtk_widget_set_hexpand (sw, TRUE);
|
||||
gtk_box_append (GTK_BOX (box), sw);
|
||||
|
||||
textview = gtk_text_view_new ();
|
||||
gtk_text_view_set_monospace (GTK_TEXT_VIEW (textview), TRUE);
|
||||
g_object_set (textview,
|
||||
"left-margin", 20,
|
||||
"right-margin", 20,
|
||||
"top-margin", 20,
|
||||
"bottom-margin", 20,
|
||||
NULL);
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), textview);
|
||||
|
||||
textbuffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (textview));
|
||||
gtk_text_buffer_set_text (textbuffer,
|
||||
gtk_shadertoy_get_image_shader (GTK_SHADERTOY (shadertoy)),
|
||||
-1);
|
||||
|
||||
centerbox = gtk_center_box_new ();
|
||||
gtk_box_append (GTK_BOX (box), centerbox);
|
||||
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, FALSE);
|
||||
gtk_box_set_spacing (GTK_BOX (hbox), 6);
|
||||
gtk_center_box_set_start_widget (GTK_CENTER_BOX (centerbox), hbox);
|
||||
|
||||
button = gtk_button_new_from_icon_name ("view-refresh-symbolic");
|
||||
gtk_widget_set_tooltip_text (button, "Restart the demo");
|
||||
gtk_widget_set_valign (button, GTK_ALIGN_CENTER);
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (run_clicked_cb), NULL);
|
||||
gtk_box_append (GTK_BOX (hbox), button);
|
||||
|
||||
button = gtk_button_new_from_icon_name ("edit-clear-all-symbolic");
|
||||
gtk_widget_set_tooltip_text (button, "Clear the text view");
|
||||
gtk_widget_set_valign (button, GTK_ALIGN_CENTER);
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (clear_clicked_cb), NULL);
|
||||
gtk_box_append (GTK_BOX (hbox), button);
|
||||
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, FALSE);
|
||||
gtk_box_set_spacing (GTK_BOX (hbox), 6);
|
||||
gtk_center_box_set_end_widget (GTK_CENTER_BOX (centerbox), hbox);
|
||||
|
||||
button = new_button ("/shadertoy/alienplanet.glsl");
|
||||
gtk_box_append (GTK_BOX (hbox), button);
|
||||
|
||||
button = new_button ("/shadertoy/mandelbrot.glsl");
|
||||
gtk_box_append (GTK_BOX (hbox), button);
|
||||
|
||||
button = new_button ("/shadertoy/neon.glsl");
|
||||
gtk_box_append (GTK_BOX (hbox), button);
|
||||
|
||||
button = new_button ("/shadertoy/cogs.glsl");
|
||||
gtk_box_append (GTK_BOX (hbox), button);
|
||||
|
||||
button = new_button ("/shadertoy/glowingstars.glsl");
|
||||
gtk_box_append (GTK_BOX (hbox), button);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_shadertoy (GtkWidget *do_widget)
|
||||
{
|
||||
if (!demo_window)
|
||||
demo_window = create_shadertoy_window (do_widget);
|
||||
|
||||
if (!gtk_widget_get_visible (demo_window))
|
||||
gtk_widget_show (demo_window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (demo_window));
|
||||
|
||||
return demo_window;
|
||||
}
|
451
demos/gtk-demo/singular_value_decomposition.c
Normal file
451
demos/gtk-demo/singular_value_decomposition.c
Normal file
@@ -0,0 +1,451 @@
|
||||
#include <string.h>
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
#include <glib.h>
|
||||
|
||||
/* See Golub and Reinsch,
|
||||
* "Handbook for Automatic Computation vol II - Linear Algebra",
|
||||
* Springer, 1971
|
||||
*/
|
||||
|
||||
|
||||
#define MAX_ITERATION_COUNT 30
|
||||
|
||||
/* Perform Householder reduction to bidiagonal form
|
||||
*
|
||||
* Input: Matrix A of size nrows x ncols
|
||||
*
|
||||
* Output: Matrices and vectors such that
|
||||
* A = U*Bidiag(diagonal, superdiagonal)*Vt
|
||||
*
|
||||
* All matrices are allocated by the caller
|
||||
*
|
||||
* Sizes:
|
||||
* A, U: nrows x ncols
|
||||
* diagonal, superdiagonal: ncols
|
||||
* V: ncols x ncols
|
||||
*/
|
||||
static void
|
||||
householder_reduction (double *A,
|
||||
int nrows,
|
||||
int ncols,
|
||||
double *U,
|
||||
double *V,
|
||||
double *diagonal,
|
||||
double *superdiagonal)
|
||||
{
|
||||
int i, j, k, ip1;
|
||||
double s, s2, si, scale;
|
||||
double *pu, *pui, *pv, *pvi;
|
||||
double half_norm_squared;
|
||||
|
||||
memcpy (U, A, sizeof (double) * nrows * ncols);
|
||||
|
||||
diagonal[0] = 0.0;
|
||||
s = 0.0;
|
||||
scale = 0.0;
|
||||
for (i = 0, pui = U, ip1 = 1;
|
||||
i < ncols;
|
||||
pui += ncols, i++, ip1++)
|
||||
{
|
||||
superdiagonal[i] = scale * s;
|
||||
|
||||
for (j = i, pu = pui, scale = 0.0;
|
||||
j < nrows;
|
||||
j++, pu += ncols)
|
||||
scale += fabs( *(pu + i) );
|
||||
|
||||
if (scale > 0.0)
|
||||
{
|
||||
for (j = i, pu = pui, s2 = 0.0; j < nrows; j++, pu += ncols)
|
||||
{
|
||||
*(pu + i) /= scale;
|
||||
s2 += *(pu + i) * *(pu + i);
|
||||
}
|
||||
s = *(pui + i) < 0.0 ? sqrt (s2) : -sqrt (s2);
|
||||
half_norm_squared = *(pui + i) * s - s2;
|
||||
*(pui + i) -= s;
|
||||
|
||||
for (j = ip1; j < ncols; j++)
|
||||
{
|
||||
for (k = i, si = 0.0, pu = pui; k < nrows; k++, pu += ncols)
|
||||
si += *(pu + i) * *(pu + j);
|
||||
si /= half_norm_squared;
|
||||
for (k = i, pu = pui; k < nrows; k++, pu += ncols)
|
||||
*(pu + j) += si * *(pu + i);
|
||||
}
|
||||
}
|
||||
for (j = i, pu = pui; j < nrows; j++, pu += ncols)
|
||||
*(pu + i) *= scale;
|
||||
diagonal[i] = s * scale;
|
||||
s = 0.0;
|
||||
scale = 0.0;
|
||||
if (i >= nrows || i == ncols - 1)
|
||||
continue;
|
||||
for (j = ip1; j < ncols; j++)
|
||||
scale += fabs (*(pui + j));
|
||||
if (scale > 0.0)
|
||||
{
|
||||
for (j = ip1, s2 = 0.0; j < ncols; j++)
|
||||
{
|
||||
*(pui + j) /= scale;
|
||||
s2 += *(pui + j) * *(pui + j);
|
||||
}
|
||||
s = *(pui + ip1) < 0.0 ? sqrt (s2) : -sqrt (s2);
|
||||
half_norm_squared = *(pui + ip1) * s - s2;
|
||||
*(pui + ip1) -= s;
|
||||
for (k = ip1; k < ncols; k++)
|
||||
superdiagonal[k] = *(pui + k) / half_norm_squared;
|
||||
if (i < (nrows - 1))
|
||||
{
|
||||
for (j = ip1, pu = pui + ncols; j < nrows; j++, pu += ncols)
|
||||
{
|
||||
for (k = ip1, si = 0.0; k < ncols; k++)
|
||||
si += *(pui + k) * *(pu + k);
|
||||
for (k = ip1; k < ncols; k++)
|
||||
*(pu + k) += si * superdiagonal[k];
|
||||
}
|
||||
}
|
||||
for (k = ip1; k < ncols; k++)
|
||||
*(pui + k) *= scale;
|
||||
}
|
||||
}
|
||||
|
||||
pui = U + ncols * (ncols - 2);
|
||||
pvi = V + ncols * (ncols - 1);
|
||||
*(pvi + ncols - 1) = 1.0;
|
||||
s = superdiagonal[ncols - 1];
|
||||
pvi -= ncols;
|
||||
for (i = ncols - 2, ip1 = ncols - 1;
|
||||
i >= 0;
|
||||
i--, pui -= ncols, pvi -= ncols, ip1--)
|
||||
{
|
||||
if (s != 0.0)
|
||||
{
|
||||
pv = pvi + ncols;
|
||||
for (j = ip1; j < ncols; j++, pv += ncols)
|
||||
*(pv + i) = ( *(pui + j) / *(pui + ip1) ) / s;
|
||||
for (j = ip1; j < ncols; j++)
|
||||
{
|
||||
si = 0.0;
|
||||
for (k = ip1, pv = pvi + ncols; k < ncols; k++, pv += ncols)
|
||||
si += *(pui + k) * *(pv + j);
|
||||
for (k = ip1, pv = pvi + ncols; k < ncols; k++, pv += ncols)
|
||||
*(pv + j) += si * *(pv + i);
|
||||
}
|
||||
}
|
||||
pv = pvi + ncols;
|
||||
for (j = ip1; j < ncols; j++, pv += ncols)
|
||||
{
|
||||
*(pvi + j) = 0.0;
|
||||
*(pv + i) = 0.0;
|
||||
}
|
||||
*(pvi + i) = 1.0;
|
||||
s = superdiagonal[i];
|
||||
}
|
||||
|
||||
pui = U + ncols * (ncols - 1);
|
||||
for (i = ncols - 1, ip1 = ncols;
|
||||
i >= 0;
|
||||
ip1 = i, i--, pui -= ncols)
|
||||
{
|
||||
s = diagonal[i];
|
||||
for (j = ip1; j < ncols; j++)
|
||||
*(pui + j) = 0.0;
|
||||
if (s != 0.0)
|
||||
{
|
||||
for (j = ip1; j < ncols; j++)
|
||||
{
|
||||
si = 0.0;
|
||||
pu = pui + ncols;
|
||||
for (k = ip1; k < nrows; k++, pu += ncols)
|
||||
si += *(pu + i) * *(pu + j);
|
||||
si = (si / *(pui + i)) / s;
|
||||
for (k = i, pu = pui; k < nrows; k++, pu += ncols)
|
||||
*(pu + j) += si * *(pu + i);
|
||||
}
|
||||
for (j = i, pu = pui; j < nrows; j++, pu += ncols)
|
||||
*(pu + i) /= s;
|
||||
}
|
||||
else
|
||||
for (j = i, pu = pui; j < nrows; j++, pu += ncols)
|
||||
*(pu + i) = 0.0;
|
||||
*(pui + i) += 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Perform Givens reduction
|
||||
*
|
||||
* Input: Matrices such that
|
||||
* A = U*Bidiag(diagonal,superdiagonal)*Vt
|
||||
*
|
||||
* Output: The same, with superdiagonal = 0
|
||||
*
|
||||
* All matrices are allocated by the caller
|
||||
*
|
||||
* Sizes:
|
||||
* U: nrows x ncols
|
||||
* diagonal, superdiagonal: ncols
|
||||
* V: ncols x ncols
|
||||
*/
|
||||
static int
|
||||
givens_reduction (int nrows,
|
||||
int ncols,
|
||||
double *U,
|
||||
double *V,
|
||||
double *diagonal,
|
||||
double *superdiagonal)
|
||||
{
|
||||
double epsilon;
|
||||
double c, s;
|
||||
double f,g,h;
|
||||
double x,y,z;
|
||||
double *pu, *pv;
|
||||
int i,j,k,m;
|
||||
int rotation_test;
|
||||
int iteration_count;
|
||||
|
||||
for (i = 0, x = 0.0; i < ncols; i++)
|
||||
{
|
||||
y = fabs (diagonal[i]) + fabs (superdiagonal[i]);
|
||||
if (x < y)
|
||||
x = y;
|
||||
}
|
||||
epsilon = x * DBL_EPSILON;
|
||||
for (k = ncols - 1; k >= 0; k--)
|
||||
{
|
||||
iteration_count = 0;
|
||||
while (1)
|
||||
{
|
||||
rotation_test = 1;
|
||||
for (m = k; m >= 0; m--)
|
||||
{
|
||||
if (fabs (superdiagonal[m]) <= epsilon)
|
||||
{
|
||||
rotation_test = 0;
|
||||
break;
|
||||
}
|
||||
if (fabs (diagonal[m-1]) <= epsilon)
|
||||
break;
|
||||
}
|
||||
if (rotation_test)
|
||||
{
|
||||
c = 0.0;
|
||||
s = 1.0;
|
||||
for (i = m; i <= k; i++)
|
||||
{
|
||||
f = s * superdiagonal[i];
|
||||
superdiagonal[i] *= c;
|
||||
if (fabs (f) <= epsilon)
|
||||
break;
|
||||
g = diagonal[i];
|
||||
h = sqrt (f*f + g*g);
|
||||
diagonal[i] = h;
|
||||
c = g / h;
|
||||
s = -f / h;
|
||||
for (j = 0, pu = U; j < nrows; j++, pu += ncols)
|
||||
{
|
||||
y = *(pu + m - 1);
|
||||
z = *(pu + i);
|
||||
*(pu + m - 1 ) = y * c + z * s;
|
||||
*(pu + i) = -y * s + z * c;
|
||||
}
|
||||
}
|
||||
}
|
||||
z = diagonal[k];
|
||||
if (m == k)
|
||||
{
|
||||
if (z < 0.0)
|
||||
{
|
||||
diagonal[k] = -z;
|
||||
for (j = 0, pv = V; j < ncols; j++, pv += ncols)
|
||||
*(pv + k) = - *(pv + k);
|
||||
}
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (iteration_count >= MAX_ITERATION_COUNT)
|
||||
return -1;
|
||||
iteration_count++;
|
||||
x = diagonal[m];
|
||||
y = diagonal[k-1];
|
||||
g = superdiagonal[k-1];
|
||||
h = superdiagonal[k];
|
||||
f = ((y - z) * ( y + z ) + (g - h) * (g + h))/(2.0 * h * y);
|
||||
g = sqrt (f * f + 1.0);
|
||||
if (f < 0.0)
|
||||
g = -g;
|
||||
f = ((x - z) * (x + z) + h * (y / (f + g) - h)) / x;
|
||||
c = 1.0;
|
||||
s = 1.0;
|
||||
for (i = m + 1; i <= k; i++)
|
||||
{
|
||||
g = superdiagonal[i];
|
||||
y = diagonal[i];
|
||||
h = s * g;
|
||||
g *= c;
|
||||
z = sqrt (f * f + h * h);
|
||||
superdiagonal[i-1] = z;
|
||||
c = f / z;
|
||||
s = h / z;
|
||||
f = x * c + g * s;
|
||||
g = -x * s + g * c;
|
||||
h = y * s;
|
||||
y *= c;
|
||||
for (j = 0, pv = V; j < ncols; j++, pv += ncols)
|
||||
{
|
||||
x = *(pv + i - 1);
|
||||
z = *(pv + i);
|
||||
*(pv + i - 1) = x * c + z * s;
|
||||
*(pv + i) = -x * s + z * c;
|
||||
}
|
||||
z = sqrt (f * f + h * h);
|
||||
diagonal[i - 1] = z;
|
||||
if (z != 0.0)
|
||||
{
|
||||
c = f / z;
|
||||
s = h / z;
|
||||
}
|
||||
f = c * g + s * y;
|
||||
x = -s * g + c * y;
|
||||
for (j = 0, pu = U; j < nrows; j++, pu += ncols)
|
||||
{
|
||||
y = *(pu + i - 1);
|
||||
z = *(pu + i);
|
||||
*(pu + i - 1) = c * y + s * z;
|
||||
*(pu + i) = -s * y + c * z;
|
||||
}
|
||||
}
|
||||
superdiagonal[m] = 0.0;
|
||||
superdiagonal[k] = f;
|
||||
diagonal[k] = x;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Given a singular value decomposition
|
||||
* of an nrows x ncols matrix A = U*Diag(S)*Vt,
|
||||
* sort the values of S by decreasing value,
|
||||
* permuting V to match.
|
||||
*/
|
||||
static void
|
||||
sort_singular_values (int nrows,
|
||||
int ncols,
|
||||
double *S,
|
||||
double *U,
|
||||
double *V)
|
||||
{
|
||||
int i, j, max_index;
|
||||
double temp;
|
||||
double *p1, *p2;
|
||||
|
||||
for (i = 0; i < ncols - 1; i++)
|
||||
{
|
||||
max_index = i;
|
||||
for (j = i + 1; j < ncols; j++)
|
||||
if (S[j] > S[max_index])
|
||||
max_index = j;
|
||||
if (max_index == i)
|
||||
continue;
|
||||
temp = S[i];
|
||||
S[i] = S[max_index];
|
||||
S[max_index] = temp;
|
||||
p1 = U + max_index;
|
||||
p2 = U + i;
|
||||
for (j = 0; j < nrows; j++, p1 += ncols, p2 += ncols)
|
||||
{
|
||||
temp = *p1;
|
||||
*p1 = *p2;
|
||||
*p2 = temp;
|
||||
}
|
||||
p1 = V + max_index;
|
||||
p2 = V + i;
|
||||
for (j = 0; j < ncols; j++, p1 += ncols, p2 += ncols)
|
||||
{
|
||||
temp = *p1;
|
||||
*p1 = *p2;
|
||||
*p2 = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Compute a singular value decomposition of A,
|
||||
* A = U*Diag(S)*Vt
|
||||
*
|
||||
* All matrices are allocated by the caller
|
||||
*
|
||||
* Sizes:
|
||||
* A, U: nrows x ncols
|
||||
* S: ncols
|
||||
* V: ncols x ncols
|
||||
*/
|
||||
int
|
||||
singular_value_decomposition (double *A,
|
||||
int nrows,
|
||||
int ncols,
|
||||
double *U,
|
||||
double *S,
|
||||
double *V)
|
||||
{
|
||||
double *superdiagonal;
|
||||
|
||||
superdiagonal = g_alloca (sizeof (double) * ncols);
|
||||
|
||||
if (nrows < ncols)
|
||||
return -1;
|
||||
|
||||
householder_reduction (A, nrows, ncols, U, V, S, superdiagonal);
|
||||
|
||||
if (givens_reduction (nrows, ncols, U, V, S, superdiagonal) < 0)
|
||||
return -1;
|
||||
|
||||
sort_singular_values (nrows, ncols, S, U, V);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a singular value decomposition of A = U*Diag(S)*Vt,
|
||||
* compute the best approximation x to A*x = B.
|
||||
*
|
||||
* All matrices are allocated by the caller
|
||||
*
|
||||
* Sizes:
|
||||
* U: nrows x ncols
|
||||
* S: ncols
|
||||
* V: ncols x ncols
|
||||
* B, x: ncols
|
||||
*/
|
||||
void
|
||||
singular_value_decomposition_solve (double *U,
|
||||
double *S,
|
||||
double *V,
|
||||
int nrows,
|
||||
int ncols,
|
||||
double *B,
|
||||
double *x)
|
||||
{
|
||||
int i, j, k;
|
||||
double *pu, *pv;
|
||||
double d;
|
||||
double tolerance;
|
||||
|
||||
tolerance = DBL_EPSILON * S[0] * (double) ncols;
|
||||
|
||||
for ( i = 0, pv = V; i < ncols; i++, pv += ncols)
|
||||
{
|
||||
x[i] = 0.0;
|
||||
for (j = 0; j < ncols; j++)
|
||||
{
|
||||
if (S[j] > tolerance)
|
||||
{
|
||||
for (k = 0, d = 0.0, pu = U; k < nrows; k++, pu += ncols)
|
||||
d += *(pu + j) * B[k];
|
||||
x[i] += d * *(pv + j) / S[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
17
demos/gtk-demo/singular_value_decomposition.h
Normal file
17
demos/gtk-demo/singular_value_decomposition.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
int singular_value_decomposition (double *A,
|
||||
int nrows,
|
||||
int ncols,
|
||||
double *U,
|
||||
double *S,
|
||||
double *V);
|
||||
|
||||
void singular_value_decomposition_solve (double *U,
|
||||
double *S,
|
||||
double *V,
|
||||
int nrows,
|
||||
int ncols,
|
||||
double *B,
|
||||
double *x);
|
||||
|
@@ -152,7 +152,7 @@ do_sizegroup (GtkWidget *do_widget)
|
||||
check_button = gtk_check_button_new_with_mnemonic ("_Enable grouping");
|
||||
gtk_box_append (GTK_BOX (vbox), check_button);
|
||||
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button), TRUE);
|
||||
gtk_check_button_set_active (GTK_CHECK_BUTTON (check_button), TRUE);
|
||||
g_signal_connect (check_button, "toggled",
|
||||
G_CALLBACK (toggle_grouping), size_group);
|
||||
}
|
||||
|
@@ -435,9 +435,9 @@ do_sliding_puzzle (GtkWidget *do_widget)
|
||||
gtk_widget_set_margin_bottom (tweaks, 10);
|
||||
|
||||
choices = gtk_flow_box_new ();
|
||||
gtk_widget_add_css_class (choices, GTK_STYLE_CLASS_VIEW);
|
||||
gtk_widget_add_css_class (choices, "view");
|
||||
add_choice (choices, puzzle);
|
||||
add_choice (choices, gtk_nuclear_animation_new ());
|
||||
add_choice (choices, gtk_nuclear_animation_new (TRUE));
|
||||
media = gtk_media_file_new_for_resource ("/images/gtk-logo.webm");
|
||||
gtk_media_stream_set_loop (media, TRUE);
|
||||
gtk_media_stream_set_muted (media, TRUE);
|
||||
|
@@ -185,54 +185,54 @@ do_spinbutton (GtkWidget *do_widget)
|
||||
static GtkWidget *window;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
GtkBuilder *builder;
|
||||
GtkAdjustment *adj;
|
||||
GtkWidget *label;
|
||||
{
|
||||
GtkBuilder *builder;
|
||||
GtkAdjustment *adj;
|
||||
GtkWidget *label;
|
||||
|
||||
builder = gtk_builder_new_from_resource ("/spinbutton/spinbutton.ui");
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Spin Buttons");
|
||||
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
builder = gtk_builder_new_from_resource ("/spinbutton/spinbutton.ui");
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Spin Buttons");
|
||||
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
|
||||
adj = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "basic_adjustment"));
|
||||
label = GTK_WIDGET (gtk_builder_get_object (builder, "basic_label"));
|
||||
g_object_bind_property_full (adj, "value",
|
||||
label, "label",
|
||||
G_BINDING_SYNC_CREATE,
|
||||
value_to_label,
|
||||
NULL,
|
||||
NULL, NULL);
|
||||
adj = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "hex_adjustment"));
|
||||
label = GTK_WIDGET (gtk_builder_get_object (builder, "hex_label"));
|
||||
g_object_bind_property_full (adj, "value",
|
||||
label, "label",
|
||||
G_BINDING_SYNC_CREATE,
|
||||
value_to_label,
|
||||
NULL,
|
||||
NULL, NULL);
|
||||
adj = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "time_adjustment"));
|
||||
label = GTK_WIDGET (gtk_builder_get_object (builder, "time_label"));
|
||||
g_object_bind_property_full (adj, "value",
|
||||
label, "label",
|
||||
G_BINDING_SYNC_CREATE,
|
||||
value_to_label,
|
||||
NULL,
|
||||
NULL, NULL);
|
||||
adj = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "month_adjustment"));
|
||||
label = GTK_WIDGET (gtk_builder_get_object (builder, "month_label"));
|
||||
g_object_bind_property_full (adj, "value",
|
||||
label, "label",
|
||||
G_BINDING_SYNC_CREATE,
|
||||
value_to_label,
|
||||
NULL,
|
||||
NULL, NULL);
|
||||
adj = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "basic_adjustment"));
|
||||
label = GTK_WIDGET (gtk_builder_get_object (builder, "basic_label"));
|
||||
g_object_bind_property_full (adj, "value",
|
||||
label, "label",
|
||||
G_BINDING_SYNC_CREATE,
|
||||
value_to_label,
|
||||
NULL,
|
||||
NULL, NULL);
|
||||
adj = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "hex_adjustment"));
|
||||
label = GTK_WIDGET (gtk_builder_get_object (builder, "hex_label"));
|
||||
g_object_bind_property_full (adj, "value",
|
||||
label, "label",
|
||||
G_BINDING_SYNC_CREATE,
|
||||
value_to_label,
|
||||
NULL,
|
||||
NULL, NULL);
|
||||
adj = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "time_adjustment"));
|
||||
label = GTK_WIDGET (gtk_builder_get_object (builder, "time_label"));
|
||||
g_object_bind_property_full (adj, "value",
|
||||
label, "label",
|
||||
G_BINDING_SYNC_CREATE,
|
||||
value_to_label,
|
||||
NULL,
|
||||
NULL, NULL);
|
||||
adj = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "month_adjustment"));
|
||||
label = GTK_WIDGET (gtk_builder_get_object (builder, "month_label"));
|
||||
g_object_bind_property_full (adj, "value",
|
||||
label, "label",
|
||||
G_BINDING_SYNC_CREATE,
|
||||
value_to_label,
|
||||
NULL,
|
||||
NULL, NULL);
|
||||
|
||||
g_object_unref (builder);
|
||||
}
|
||||
g_object_unref (builder);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
|
@@ -61,7 +61,7 @@ do_textmask (GtkWidget *do_widget)
|
||||
{
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
|
||||
gtk_widget_set_size_request (window, 400, 200);
|
||||
gtk_widget_set_size_request (window, 400, 240);
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Text Mask");
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
|
||||
|
@@ -142,7 +142,7 @@ insert_text (GtkTextView *view)
|
||||
32, 1,
|
||||
gtk_widget_get_direction (widget),
|
||||
0);
|
||||
nuclear = gtk_nuclear_animation_new ();
|
||||
nuclear = gtk_nuclear_animation_new (TRUE);
|
||||
|
||||
/* get start of buffer; each insertion will revalidate the
|
||||
* iterator to point to just after the inserted text.
|
||||
|
@@ -1,6 +1,9 @@
|
||||
/* Benchmark/Themes
|
||||
*
|
||||
* This demo switches themes like a maniac, like some of you.
|
||||
*
|
||||
* Warning: This demo involves rapidly flashing changes and may
|
||||
* be hazardous to photosensitive viewers.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
@@ -123,51 +126,12 @@ change_theme (GtkWidget *widget,
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
static void
|
||||
clicked (GtkGestureClick *gesture,
|
||||
int n_press,
|
||||
double x,
|
||||
double y,
|
||||
gpointer data)
|
||||
{
|
||||
GtkWidget *window;
|
||||
GdkEvent *event;
|
||||
GdkModifierType state;
|
||||
|
||||
window = gtk_widget_get_ancestor (gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (gesture)), GTK_TYPE_WINDOW);
|
||||
|
||||
event = gtk_gesture_get_last_event (GTK_GESTURE (gesture), NULL);
|
||||
state = gdk_event_get_modifier_state (event);
|
||||
|
||||
if (state & GDK_CONTROL_MASK)
|
||||
{
|
||||
if (tick_cb)
|
||||
{
|
||||
gtk_widget_remove_tick_callback (window, tick_cb);
|
||||
tick_cb = 0;
|
||||
}
|
||||
|
||||
change_theme (window, NULL, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tick_cb)
|
||||
{
|
||||
gtk_widget_remove_tick_callback (window, tick_cb);
|
||||
tick_cb = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
tick_cb = gtk_widget_add_tick_callback (window, change_theme, data, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
toggle_cycle (GObject *button,
|
||||
GParamSpec *pspec,
|
||||
gpointer data)
|
||||
{
|
||||
GtkWidget *warning = data;
|
||||
gboolean active;
|
||||
GtkWidget *window;
|
||||
|
||||
@@ -177,7 +141,7 @@ toggle_cycle (GObject *button,
|
||||
|
||||
if (active && !tick_cb)
|
||||
{
|
||||
tick_cb = gtk_widget_add_tick_callback (window, change_theme, data, NULL);
|
||||
gtk_window_present (GTK_WINDOW (warning));
|
||||
}
|
||||
else if (!active && tick_cb)
|
||||
{
|
||||
@@ -186,6 +150,25 @@ toggle_cycle (GObject *button,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
warning_closed (GtkDialog *warning,
|
||||
int response_id,
|
||||
gpointer data)
|
||||
{
|
||||
GtkWidget *window;
|
||||
GtkWidget *button;
|
||||
|
||||
gtk_widget_hide (GTK_WIDGET (warning));
|
||||
|
||||
window = gtk_widget_get_ancestor (GTK_WIDGET (data), GTK_TYPE_WINDOW);
|
||||
button = GTK_WIDGET (g_object_get_data (G_OBJECT (window), "button"));
|
||||
|
||||
if (response_id == GTK_RESPONSE_OK)
|
||||
tick_cb = gtk_widget_add_tick_callback (window, change_theme, data, NULL);
|
||||
else
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_themes (GtkWidget *do_widget)
|
||||
{
|
||||
@@ -194,10 +177,9 @@ do_themes (GtkWidget *do_widget)
|
||||
if (!window)
|
||||
{
|
||||
GtkBuilder *builder;
|
||||
GtkWidget *header;
|
||||
GtkWidget *button;
|
||||
GtkWidget *label;
|
||||
GtkGesture *gesture;
|
||||
GtkWidget *warning;
|
||||
|
||||
builder = gtk_builder_new_from_resource ("/themes/themes.ui");
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
|
||||
@@ -205,15 +187,13 @@ do_themes (GtkWidget *do_widget)
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
|
||||
header = GTK_WIDGET (gtk_builder_get_object (builder, "header"));
|
||||
label = GTK_WIDGET (gtk_builder_get_object (builder, "fps"));
|
||||
|
||||
gesture = gtk_gesture_click_new ();
|
||||
g_signal_connect (gesture, "pressed", G_CALLBACK (clicked), label);
|
||||
gtk_widget_add_controller (header, GTK_EVENT_CONTROLLER (gesture));
|
||||
warning = GTK_WIDGET (gtk_builder_get_object (builder, "warning"));
|
||||
g_signal_connect (warning, "response", G_CALLBACK (warning_closed), label);
|
||||
|
||||
button = GTK_WIDGET (gtk_builder_get_object (builder, "toggle"));
|
||||
g_signal_connect (button, "notify::active", G_CALLBACK (toggle_cycle), label);
|
||||
g_object_set_data (G_OBJECT (window), "button", button);
|
||||
g_signal_connect (button, "notify::active", G_CALLBACK (toggle_cycle), warning);
|
||||
gtk_widget_realize (window);
|
||||
|
||||
g_object_unref (builder);
|
||||
|
@@ -1,5 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<object class="GtkMessageDialog" id="warning">
|
||||
<property name="transient-for">window</property>
|
||||
<property name="modal">1</property>
|
||||
<property name="hide-on-close">1</property>
|
||||
<property name="buttons">ok-cancel</property>
|
||||
<property name="message-type">warning</property>
|
||||
<property name="text" translatable="yes">Warning</property>
|
||||
<property name="secondary-text" translatable="yes">This demo involves rapidly flashing changes and may be hazardous to photosensitive viewers.</property>
|
||||
</object>
|
||||
<object class="GtkWindow" id="window">
|
||||
<property name="resizable">0</property>
|
||||
<child type="titlebar">
|
||||
|
@@ -31,6 +31,7 @@ open_clicked_cb (GtkWidget *button,
|
||||
GtkWidget *video)
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
GtkFileFilter *filter;
|
||||
|
||||
dialog = gtk_file_chooser_dialog_new ("Select a video",
|
||||
GTK_WINDOW (gtk_widget_get_root (button)),
|
||||
@@ -38,6 +39,11 @@ open_clicked_cb (GtkWidget *button,
|
||||
"_Cancel", GTK_RESPONSE_CANCEL,
|
||||
"_Open", GTK_RESPONSE_ACCEPT,
|
||||
NULL);
|
||||
filter = gtk_file_filter_new ();
|
||||
gtk_file_filter_add_mime_type (filter, "video/*");
|
||||
gtk_file_filter_set_name (filter, "Video");
|
||||
gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dialog), filter);
|
||||
g_object_unref (filter);
|
||||
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
|
||||
gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
|
||||
g_signal_connect (dialog, "response", G_CALLBACK (open_dialog_response_cb), video);
|
||||
@@ -67,6 +73,7 @@ do_video_player (GtkWidget *do_widget)
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Video Player");
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
|
||||
video = gtk_video_new ();
|
||||
|
@@ -38,7 +38,7 @@ network-transmit-receive=The icon used data is being both transmitted and receiv
|
||||
network-transmit=The icon used when data is being transmitted, while the computing device is connected to a network
|
||||
network-receive=The icon used when data is being received, while the computing device is connected to a network
|
||||
network-idle=The icon used when no data is being transmitted or received, while the computing device is connected to a network
|
||||
network-error=The icon used when an error occurs trying to intialize the network connection of the computing device
|
||||
network-error=The icon used when an error occurs trying to initialize the network connection of the computing device
|
||||
network-offline=The icon used when the computing device is disconnected from the network
|
||||
|
||||
[weather]
|
||||
@@ -112,7 +112,7 @@ document-edit=The icon for the action to edit a document
|
||||
object-flip-horizontal=The icon for the action to flip an object horizontally
|
||||
object-flip-vertical=The icon for the action to flip an object vertically
|
||||
object-rotate-left=The icon for the rotate left action performed on an object
|
||||
object-rotate-right=The icon for the rotate rigt action performed on an object
|
||||
object-rotate-right=The icon for the rotate right action performed on an object
|
||||
insert-image=The icon for the insert image action of an application
|
||||
insert-link=The icon for the insert link action of an application
|
||||
insert-object=The icon for the insert object action of an application
|
||||
@@ -406,7 +406,7 @@ media-zip=
|
||||
modem=The icon used for modem devices
|
||||
multimedia-player-apple-ipod-touch=
|
||||
network-vpn=
|
||||
pda=This is the fallback icon for Personal Digial Assistant devices. Primary use of this icon is for PDA devices connected to the PC. Connection medium is not an important aspect of the icon. The metaphor for this fallback icon should be a generic PDA device icon
|
||||
pda=This is the fallback icon for Personal Digital Assistant devices. Primary use of this icon is for PDA devices connected to the PC. Connection medium is not an important aspect of the icon. The metaphor for this fallback icon should be a generic PDA device icon
|
||||
phone-apple-iphone=
|
||||
uninterruptible-power-supply=
|
||||
emblem-default=The icon used as an emblem to specify the default selection of a printer for example
|
||||
|
@@ -50,6 +50,8 @@ about_activated (GSimpleAction *action,
|
||||
char *icon_theme;
|
||||
char *version;
|
||||
GString *s;
|
||||
char *os_name;
|
||||
char *os_version;
|
||||
|
||||
g_object_get (gtk_settings_get_default (),
|
||||
"gtk-icon-theme-name", &icon_theme,
|
||||
@@ -57,6 +59,10 @@ about_activated (GSimpleAction *action,
|
||||
|
||||
s = g_string_new ("");
|
||||
|
||||
os_name = g_get_os_info (G_OS_INFO_KEY_NAME);
|
||||
os_version = g_get_os_info (G_OS_INFO_KEY_VERSION_ID);
|
||||
if (os_name && os_version)
|
||||
g_string_append_printf (s, "OS\t%s %s\n\n", os_name, os_version);
|
||||
g_string_append (s, "System libraries\n");
|
||||
g_string_append_printf (s, "\tGLib\t%d.%d.%d\n",
|
||||
glib_major_version,
|
||||
@@ -91,6 +97,8 @@ about_activated (GSimpleAction *action,
|
||||
g_string_free (s, TRUE);
|
||||
g_free (version);
|
||||
g_free (icon_theme);
|
||||
g_free (os_name);
|
||||
g_free (os_version);
|
||||
}
|
||||
|
||||
static GActionEntry app_entries[] =
|
||||
|
@@ -172,7 +172,7 @@ item_activated (GtkGridView *view,
|
||||
guint position,
|
||||
IconBrowserWindow *win)
|
||||
{
|
||||
GListModel *model = gtk_grid_view_get_model (view);
|
||||
GListModel *model = G_LIST_MODEL (gtk_grid_view_get_model (view));
|
||||
IbIcon *icon = g_list_model_get_item (model, position);
|
||||
const char *name;
|
||||
const char *description;
|
||||
@@ -357,7 +357,7 @@ icon_browser_window_init (IconBrowserWindow *win)
|
||||
|
||||
filter = gtk_filter_list_model_get_filter (GTK_FILTER_LIST_MODEL (win->icon_filter_model));
|
||||
|
||||
win->name_filter = gtk_custom_filter_new (filter_by_icon_name, NULL, NULL);
|
||||
win->name_filter = GTK_FILTER (gtk_custom_filter_new (filter_by_icon_name, NULL, NULL));
|
||||
|
||||
gtk_multi_filter_append (GTK_MULTI_FILTER (filter), g_object_ref (win->name_filter));
|
||||
}
|
||||
|
@@ -27,14 +27,13 @@
|
||||
<class name="linked"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="normal_radio">
|
||||
<property name="draw-indicator">0</property>
|
||||
<object class="GtkToggleButton" id="normal_radio">
|
||||
<property name="label" translatable="yes">Normal</property>
|
||||
<property name="active">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="symbolic_radio">
|
||||
<property name="draw-indicator">0</property>
|
||||
<object class="GtkToggleButton" id="symbolic_radio">
|
||||
<property name="label" translatable="yes">Symbolic</property>
|
||||
<property name="group">normal_radio</property>
|
||||
<signal name="notify::active" handler="symbolic_toggled" swapped="yes" after="yes"/>
|
||||
@@ -70,6 +69,9 @@
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<child>
|
||||
<object class="GtkListView">
|
||||
<style>
|
||||
<class name="navigation-sidebar" />
|
||||
</style>
|
||||
<property name="model">
|
||||
<object class="GtkSingleSelection" id="context_model">
|
||||
<property name="model">
|
||||
|
@@ -20,11 +20,11 @@ executable('gtk4-node-editor',
|
||||
link_args: extra_demo_ldflags,
|
||||
install: false)
|
||||
|
||||
# icons
|
||||
icontheme_dir = join_paths(gtk_datadir, 'icons/hicolor')
|
||||
# icons, don't install them until we decide to install gtk4-node-editor
|
||||
#icontheme_dir = join_paths(gtk_datadir, 'icons/hicolor')
|
||||
|
||||
foreach size: ['scalable', 'symbolic']
|
||||
install_subdir('data/' + size,
|
||||
install_dir: icontheme_dir
|
||||
)
|
||||
endforeach
|
||||
#foreach size: ['scalable', 'symbolic']
|
||||
# install_subdir('data/' + size,
|
||||
# install_dir: icontheme_dir
|
||||
# )
|
||||
#endforeach
|
||||
|
@@ -60,8 +60,15 @@ activate_about (GSimpleAction *action,
|
||||
GString *s;
|
||||
GskRenderer *gsk_renderer;
|
||||
const char *renderer;
|
||||
char *os_name;
|
||||
char *os_version;
|
||||
GtkWidget *dialog;
|
||||
|
||||
os_name = g_get_os_info (G_OS_INFO_KEY_NAME);
|
||||
os_version = g_get_os_info (G_OS_INFO_KEY_VERSION_ID);
|
||||
s = g_string_new ("");
|
||||
if (os_name && os_version)
|
||||
g_string_append_printf (s, "OS\t%s %s\n\n", os_name, os_version);
|
||||
|
||||
g_string_append (s, "System libraries\n");
|
||||
g_string_append_printf (s, "\tGLib\t%d.%d.%d\n",
|
||||
@@ -93,7 +100,8 @@ activate_about (GSimpleAction *action,
|
||||
gtk_get_minor_version (),
|
||||
gtk_get_micro_version ());
|
||||
|
||||
gtk_show_about_dialog (GTK_WINDOW (gtk_application_get_active_window (app)),
|
||||
dialog = g_object_new (GTK_TYPE_ABOUT_DIALOG,
|
||||
"transient-for", gtk_application_get_active_window (app),
|
||||
"program-name", "GTK Node Editor",
|
||||
"version", version,
|
||||
"copyright", "© 2019—2020 The GTK Team",
|
||||
@@ -105,9 +113,15 @@ activate_about (GSimpleAction *action,
|
||||
"title", "About GTK Node Editor",
|
||||
"system-information", s->str,
|
||||
NULL);
|
||||
gtk_about_dialog_add_credit_section (GTK_ABOUT_DIALOG (dialog),
|
||||
"Artwork by", (const char *[]) { "Jakub Steiner", NULL });
|
||||
|
||||
gtk_window_present (GTK_WINDOW (dialog));
|
||||
|
||||
g_string_free (s, TRUE);
|
||||
g_free (version);
|
||||
g_free (os_name);
|
||||
g_free (os_version);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -667,7 +667,7 @@ testcase_save_clicked_cb (GtkWidget *button,
|
||||
png_file = g_build_filename (source_dir, png_file_name, NULL);
|
||||
g_free (png_file_name);
|
||||
|
||||
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->testcase_cairo_checkbutton)))
|
||||
if (gtk_check_button_get_active (GTK_CHECK_BUTTON (self->testcase_cairo_checkbutton)))
|
||||
texture = create_cairo_texture (self);
|
||||
else
|
||||
texture = create_texture (self);
|
||||
|
@@ -4,5 +4,6 @@
|
||||
<file preprocess="xml-stripblanks">node-editor-window.ui</file>
|
||||
<file preprocess="xml-stripblanks">help-window.ui</file>
|
||||
<file>node-format.md</file>
|
||||
<file alias='icons/apps/org.gtk.gtk4.NodeEditor.Devel.svg'>data/scalable/apps/org.gtk.gtk4.NodeEditor.Devel.svg</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user