Compare commits
720 Commits
columnview
...
wip/matthi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
825b2a4139 | ||
|
|
8a23649d40 | ||
|
|
bf367b219b | ||
|
|
77435d31fa | ||
|
|
6edb8f096f | ||
|
|
c4dfee8860 | ||
|
|
8ac1e77c9a | ||
|
|
65ceb6c15a | ||
|
|
f70d10f6ac | ||
|
|
0bbd083d79 | ||
|
|
102d2986c6 | ||
|
|
c74201ca87 | ||
|
|
b09019a5b4 | ||
|
|
1dd08ad8db | ||
|
|
eb0704855f | ||
|
|
c4c1d4a1b3 | ||
|
|
e6756f605e | ||
|
|
1f4b8e089e | ||
|
|
c0e08db739 | ||
|
|
1c337d350d | ||
|
|
81e675dfbf | ||
|
|
8556221429 | ||
|
|
1b4109a7fd | ||
|
|
df0786be7a | ||
|
|
3f545da08d | ||
|
|
7170fdebb9 | ||
|
|
7ccf32db57 | ||
|
|
520c2116a3 | ||
|
|
e818685921 | ||
|
|
6ddd9793f3 | ||
|
|
6bdca276a2 | ||
|
|
d4ff275002 | ||
|
|
2b6f243578 | ||
|
|
8770584bfb | ||
|
|
4f7f15700c | ||
|
|
cab6808673 | ||
|
|
b77110c35a | ||
|
|
c4e8218f49 | ||
|
|
c8b57154cb | ||
|
|
c4b2112f16 | ||
|
|
3132353ec5 | ||
|
|
3dc6267146 | ||
|
|
6a6146a9e0 | ||
|
|
01fbf8444b | ||
|
|
1f8c79eca1 | ||
|
|
5229069101 | ||
|
|
a6752bd3e0 | ||
|
|
93a51f77c4 | ||
|
|
9f2926dde3 | ||
|
|
d31bb8b503 | ||
|
|
d46b04631e | ||
|
|
30eca5a523 | ||
|
|
4fa71fd82a | ||
|
|
6819c7c792 | ||
|
|
0c9a0dfed1 | ||
|
|
5d9bcfb64a | ||
|
|
7047d68404 | ||
|
|
334f95479b | ||
|
|
9dff4d6ff3 | ||
|
|
4d7d031ee0 | ||
|
|
7c98af6358 | ||
|
|
ddcba4d33f | ||
|
|
59fe4a3a09 | ||
|
|
6774f36636 | ||
|
|
608cbc28af | ||
|
|
117c71faeb | ||
|
|
24d6a190af | ||
|
|
6a4b5ead86 | ||
|
|
674ede8665 | ||
|
|
8a269de89a | ||
|
|
ace4eac25a | ||
|
|
66bce08d10 | ||
|
|
65902367c6 | ||
|
|
8f0b92e42d | ||
|
|
f3d5f6628d | ||
|
|
4d687366ed | ||
|
|
3aa5019e70 | ||
|
|
4fb495d0fe | ||
|
|
c447fa8442 | ||
|
|
3a70ca9d03 | ||
|
|
5d11e9812d | ||
|
|
0d10982379 | ||
|
|
c20a966f06 | ||
|
|
64db05d3dd | ||
|
|
913cd91df0 | ||
|
|
2c5533589d | ||
|
|
cfdc81af02 | ||
|
|
7fa8a69fdc | ||
|
|
fd2861d683 | ||
|
|
cd9f5733b3 | ||
|
|
8b4560cbfb | ||
|
|
2d914d52be | ||
|
|
a26865e741 | ||
|
|
3558beaa61 | ||
|
|
9b9a9f14e2 | ||
|
|
0ce4f66976 | ||
|
|
b81bbde7c8 | ||
|
|
3f55bfe2cb | ||
|
|
4185ba242b | ||
|
|
e04191a5ea | ||
|
|
f07d304f19 | ||
|
|
1d1f618a13 | ||
|
|
e20610cdc6 | ||
|
|
721396b6d6 | ||
|
|
dc1dbe6158 | ||
|
|
30488e60e2 | ||
|
|
a5949960bc | ||
|
|
ec4a489093 | ||
|
|
7c52e03815 | ||
|
|
724c9361f3 | ||
|
|
147388e69a | ||
|
|
64aa281c97 | ||
|
|
c2b0330c56 | ||
|
|
de4803bb21 | ||
|
|
e574dcb091 | ||
|
|
488b0cbb69 | ||
|
|
6ceab55148 | ||
|
|
3d8b6f6b79 | ||
|
|
58d3213eef | ||
|
|
006dfdc55a | ||
|
|
a38c423ddb | ||
|
|
fa0295629b | ||
|
|
8395698090 | ||
|
|
277a91dbf8 | ||
|
|
ff36cfb5be | ||
|
|
db452f0c45 | ||
|
|
5b1195f874 | ||
|
|
d830724d4f | ||
|
|
0ef0edfa9a | ||
|
|
0ec868bd69 | ||
|
|
30e79e8412 | ||
|
|
c9b032acab | ||
|
|
1f410faccb | ||
|
|
d0e56106fe | ||
|
|
3d3d7dbc59 | ||
|
|
c0cbf9db5f | ||
|
|
db82eaec0a | ||
|
|
f4e200708d | ||
|
|
ba1944ded2 | ||
|
|
8eeef54b2e | ||
|
|
8e549d73a0 | ||
|
|
102d2a36f3 | ||
|
|
f046e27bb4 | ||
|
|
1c5cf17f1c | ||
|
|
ddb3a4be3e | ||
|
|
994f32704b | ||
|
|
1f798643c8 | ||
|
|
2f8d5e2dcd | ||
|
|
df30741535 | ||
|
|
762748028a | ||
|
|
f7c5cf137c | ||
|
|
455d91b0fc | ||
|
|
e834e51c0f | ||
|
|
bce518b214 | ||
|
|
3656994f82 | ||
|
|
fd5f6ef57f | ||
|
|
386b63b85d | ||
|
|
803103640a | ||
|
|
469a4a73f9 | ||
|
|
f401b05e7b | ||
|
|
42ed8a2748 | ||
|
|
f872eb64b5 | ||
|
|
29d054c421 | ||
|
|
7be6afe84d | ||
|
|
cf1fbdf8b5 | ||
|
|
6d2860efb7 | ||
|
|
5f29b8fcec | ||
|
|
59a8106373 | ||
|
|
c1d90273ca | ||
|
|
31b95ce47f | ||
|
|
4fe608e423 | ||
|
|
2cfeb1048c | ||
|
|
e8210d5865 | ||
|
|
fff981b220 | ||
|
|
a3f4caa291 | ||
|
|
ec54399d89 | ||
|
|
83f22fcce2 | ||
|
|
34a12f47f1 | ||
|
|
518462d882 | ||
|
|
1912513d7a | ||
|
|
1643e81c47 | ||
|
|
7ff427b456 | ||
|
|
91a96d27f1 | ||
|
|
a0f6ff101e | ||
|
|
9bcf401ef7 | ||
|
|
67a7ad069f | ||
|
|
367d24be7f | ||
|
|
1791c637d0 | ||
|
|
c6fe8818ed | ||
|
|
53a30eaa12 | ||
|
|
692cc42e10 | ||
|
|
9faaa5e8be | ||
|
|
418bbb2685 | ||
|
|
fb148027d9 | ||
|
|
05736afaf8 | ||
|
|
8a91d1d1ce | ||
|
|
2df139cf40 | ||
|
|
9f1208b595 | ||
|
|
9fd3212241 | ||
|
|
293f2e6b1c | ||
|
|
f83aa16f59 | ||
|
|
c73dd9ecaf | ||
|
|
607f08e79b | ||
|
|
511e5f39fa | ||
|
|
7d409dd2e0 | ||
|
|
9b8c0f3c7f | ||
|
|
727a78a74f | ||
|
|
a928ea6c57 | ||
|
|
d3f7dea624 | ||
|
|
456b7628ee | ||
|
|
f149beb474 | ||
|
|
1b0451761a | ||
|
|
1d26341b03 | ||
|
|
8348a113c6 | ||
|
|
bfdede7acc | ||
|
|
70894b48af | ||
|
|
b0c6b282fd | ||
|
|
393054dd3f | ||
|
|
97b10df723 | ||
|
|
62b214ffdf | ||
|
|
3549f43902 | ||
|
|
45167d5c0d | ||
|
|
0214b98c5e | ||
|
|
19c38158fc | ||
|
|
7ff35340ca | ||
|
|
a10340859d | ||
|
|
8475d88af0 | ||
|
|
79b1d24128 | ||
|
|
ad98e72884 | ||
|
|
3fab2b55cc | ||
|
|
2842030e59 | ||
|
|
7c2d21892f | ||
|
|
677bfe6857 | ||
|
|
b7ddf0b2e5 | ||
|
|
eb25fc1d5a | ||
|
|
395d40485d | ||
|
|
17af979b24 | ||
|
|
8511f25b97 | ||
|
|
290611f9ce | ||
|
|
6280066207 | ||
|
|
f054c317ee | ||
|
|
9555e611e1 | ||
|
|
5629ac3c63 | ||
|
|
110c316810 | ||
|
|
470a1aabdd | ||
|
|
b299d62a73 | ||
|
|
02b293b59c | ||
|
|
c659a231d6 | ||
|
|
4e56581222 | ||
|
|
e8ba16d9c2 | ||
|
|
4a43c77f66 | ||
|
|
55936087e0 | ||
|
|
3141eaecd0 | ||
|
|
69e14ba02f | ||
|
|
dffbcd8fdf | ||
|
|
ff3b03c5e2 | ||
|
|
32f4aa12cd | ||
|
|
fbb7948c13 | ||
|
|
d81a5a8338 | ||
|
|
652323a4bf | ||
|
|
e45518fb5f | ||
|
|
424e46849a | ||
|
|
68886ba847 | ||
|
|
da85815399 | ||
|
|
3bd648e72e | ||
|
|
2ae8ace784 | ||
|
|
1f89f21ca9 | ||
|
|
c6921cdc9d | ||
|
|
7c9f2949ce | ||
|
|
0b13e68bca | ||
|
|
5dde4c0a39 | ||
|
|
b2875d7b19 | ||
|
|
0c1cfbbad1 | ||
|
|
ddacf8cc43 | ||
|
|
395d13d5f1 | ||
|
|
1e6e522a93 | ||
|
|
f49a02e5b5 | ||
|
|
1e4dc90d62 | ||
|
|
2c3a41a81a | ||
|
|
203bb42cc1 | ||
|
|
461497e8d4 | ||
|
|
a974c83423 | ||
|
|
5eb181281a | ||
|
|
9eaeb04863 | ||
|
|
5e6c316603 | ||
|
|
77b4f6d68e | ||
|
|
a614716d0f | ||
|
|
1c856a208f | ||
|
|
c7916c8e48 | ||
|
|
0c023bb5bb | ||
|
|
df73bf38c2 | ||
|
|
7a1df3f914 | ||
|
|
3f78199cd5 | ||
|
|
0a55d4c981 | ||
|
|
7e03288724 | ||
|
|
979bf5c6fb | ||
|
|
a7f5b2e8fc | ||
|
|
94f246240d | ||
|
|
bd5fcf2998 | ||
|
|
c0cf839729 | ||
|
|
2a51d4fba8 | ||
|
|
cd1078563d | ||
|
|
a9943922d5 | ||
|
|
b46bfcafd1 | ||
|
|
6141c139e6 | ||
|
|
0fb83d7619 | ||
|
|
f64d0d8cbf | ||
|
|
e5d6bb68ce | ||
|
|
74899599a6 | ||
|
|
12c38c1d57 | ||
|
|
d243c6d7f9 | ||
|
|
c5481a125e | ||
|
|
68d80babce | ||
|
|
981c71c497 | ||
|
|
10bcbae68c | ||
|
|
1b265a7971 | ||
|
|
29c0dfb1d2 | ||
|
|
dbec5a8ce5 | ||
|
|
53eb85ba64 | ||
|
|
73fdefd65c | ||
|
|
86562a6c5a | ||
|
|
ceb63b83f2 | ||
|
|
7373e73067 | ||
|
|
985ba832fb | ||
|
|
de729e936d | ||
|
|
019f4b6b34 | ||
|
|
5bcb01e182 | ||
|
|
25c2059abb | ||
|
|
2a9c92f8e2 | ||
|
|
d468ea3efa | ||
|
|
d2cfe9f69a | ||
|
|
8dbe9e975b | ||
|
|
dd6174c496 | ||
|
|
7c1cf7781b | ||
|
|
9b363a62fe | ||
|
|
2cc39fe282 | ||
|
|
6255bd6c08 | ||
|
|
ab50d2090d | ||
|
|
c8843d0730 | ||
|
|
687da2ca6b | ||
|
|
990a87fd79 | ||
|
|
c4215a2bec | ||
|
|
342400d155 | ||
|
|
1ca308a5fd | ||
|
|
37eb0496b6 | ||
|
|
6a13bbbfef | ||
|
|
c175a7a470 | ||
|
|
937317e674 | ||
|
|
4248835ba1 | ||
|
|
180f7e4861 | ||
|
|
b526722000 | ||
|
|
b25bba4862 | ||
|
|
02ce417279 | ||
|
|
b0d2ae612f | ||
|
|
23e3d48eb9 | ||
|
|
14f26d2345 | ||
|
|
7c357423a3 | ||
|
|
cf2d6f6ec5 | ||
|
|
1443ef85be | ||
|
|
887aa2abdd | ||
|
|
9c5d6eaa71 | ||
|
|
c49318e973 | ||
|
|
131cc6497a | ||
|
|
d9d591ff7a | ||
|
|
f16b34f286 | ||
|
|
85d822b2e8 | ||
|
|
4e5689abeb | ||
|
|
b046c8d4ad | ||
|
|
72c72d0b37 | ||
|
|
5e69181d8d | ||
|
|
9c5a9fb100 | ||
|
|
ceb2349823 | ||
|
|
818b7c44be | ||
|
|
044026d330 | ||
|
|
66882f3825 | ||
|
|
1d0235780c | ||
|
|
770d6cb2bd | ||
|
|
106e1080ae | ||
|
|
07ecb3cb78 | ||
|
|
74ac435ae6 | ||
|
|
c80ba49a60 | ||
|
|
404d79153e | ||
|
|
ed9941ec2c | ||
|
|
c3b43f2ad2 | ||
|
|
86718439be | ||
|
|
933e373b07 | ||
|
|
e6dcd55480 | ||
|
|
0d901ef174 | ||
|
|
716e0db690 | ||
|
|
90b78132d4 | ||
|
|
c2285d923d | ||
|
|
4a79ac4473 | ||
|
|
2a3e5422ad | ||
|
|
e0c39dbf7e | ||
|
|
8c670b3b5d | ||
|
|
5dddec4dd9 | ||
|
|
93017bb8db | ||
|
|
059c45a85b | ||
|
|
63692a491d | ||
|
|
bbe79c1ef9 | ||
|
|
4b241f8da2 | ||
|
|
bdd6ae3252 | ||
|
|
24a3ff3aef | ||
|
|
ba988cd899 | ||
|
|
1bf1646d25 | ||
|
|
2c82151d65 | ||
|
|
d2235b71f3 | ||
|
|
ecc6c255ef | ||
|
|
57135acd2d | ||
|
|
54c098761f | ||
|
|
2f98400b80 | ||
|
|
ea7c9b93ea | ||
|
|
4317c008f0 | ||
|
|
d605d9ae73 | ||
|
|
c9fad25131 | ||
|
|
693200f1eb | ||
|
|
5f087a9dff | ||
|
|
b9cde6f8ea | ||
|
|
86eece78b1 | ||
|
|
8cb50ac6e9 | ||
|
|
997fbbde8f | ||
|
|
805ddc3c3a | ||
|
|
da9b3a9256 | ||
|
|
876560924f | ||
|
|
ca1c89c5bd | ||
|
|
7875e28d9f | ||
|
|
bd2f2a6f65 | ||
|
|
541aaa2392 | ||
|
|
d294b01cee | ||
|
|
5d9dc25115 | ||
|
|
c8988ec784 | ||
|
|
071dbc1115 | ||
|
|
80c5e4a156 | ||
|
|
6eac3063fa | ||
|
|
27925fcb0e | ||
|
|
5f4d21422a | ||
|
|
b0bb413faa | ||
|
|
37633985bd | ||
|
|
6ff8f1b2fd | ||
|
|
d13a3c7540 | ||
|
|
0a469d7bd6 | ||
|
|
115edc5fd1 | ||
|
|
a28c75f215 | ||
|
|
b9d7dab329 | ||
|
|
bb7500e984 | ||
|
|
e94268944b | ||
|
|
3225b487e8 | ||
|
|
e35c0e043e | ||
|
|
b251893030 | ||
|
|
15257e3922 | ||
|
|
180a5a1ad7 | ||
|
|
11f971d870 | ||
|
|
7c382c6b47 | ||
|
|
087f42d998 | ||
|
|
2abb5b6419 | ||
|
|
f2259adcdc | ||
|
|
a73457237d | ||
|
|
9f335d3ee6 | ||
|
|
856c8950ff | ||
|
|
61ccf4e719 | ||
|
|
1567db1f02 | ||
|
|
8316d5e366 | ||
|
|
8fca040163 | ||
|
|
c0fe1a7ffe | ||
|
|
e72c243aca | ||
|
|
14605d4b92 | ||
|
|
d1509971d8 | ||
|
|
951c9c5d73 | ||
|
|
3e6e247e56 | ||
|
|
27ce68b74a | ||
|
|
b0cf7a95b0 | ||
|
|
fd7f19c934 | ||
|
|
8090e213de | ||
|
|
de6327a885 | ||
|
|
8699c0f340 | ||
|
|
bda5454549 | ||
|
|
c3a6e35070 | ||
|
|
71c29bfcff | ||
|
|
647ed59d11 | ||
|
|
a0c489048a | ||
|
|
0f9def660d | ||
|
|
9fa65eadae | ||
|
|
facfff0022 | ||
|
|
f8b4083f47 | ||
|
|
b047b7838d | ||
|
|
b1c00ecee6 | ||
|
|
93abd8da59 | ||
|
|
3412f0554f | ||
|
|
61c83f9ffe | ||
|
|
3d7c1f8950 | ||
|
|
b0e81acc12 | ||
|
|
a682d97663 | ||
|
|
0e5137ae61 | ||
|
|
005a3da18f | ||
|
|
be6bcf882d | ||
|
|
fb344e8108 | ||
|
|
b99389bcb8 | ||
|
|
0fefdc99b2 | ||
|
|
e63419fbf4 | ||
|
|
428bb09a35 | ||
|
|
7c2c795681 | ||
|
|
165f352c58 | ||
|
|
3d6e702f63 | ||
|
|
597e9a96b4 | ||
|
|
6f4ed6c105 | ||
|
|
c3eafed472 | ||
|
|
7480fb703e | ||
|
|
24e8b484e0 | ||
|
|
d60f7f2e7a | ||
|
|
0dcffe7c33 | ||
|
|
9f09cfcfbd | ||
|
|
7373cd962c | ||
|
|
ac3f0df083 | ||
|
|
f95d54a13d | ||
|
|
fc512f0b9f | ||
|
|
f5ed59b7f2 | ||
|
|
9d51aa1443 | ||
|
|
f0bdc865b9 | ||
|
|
eda1703f9d | ||
|
|
51fc382582 | ||
|
|
6e52ef96a4 | ||
|
|
9606c1eee9 | ||
|
|
959c101400 | ||
|
|
6b096e5c5b | ||
|
|
9ac1eacdc8 | ||
|
|
8e7395a7e3 | ||
|
|
80fbc1b72d | ||
|
|
17ea03eee2 | ||
|
|
985b5a052e | ||
|
|
ed1872f0a8 | ||
|
|
34841c3a5f | ||
|
|
185f0181ac | ||
|
|
60d6a0f2d5 | ||
|
|
99a1d10bf1 | ||
|
|
2f1028ed79 | ||
|
|
f631e0e1e0 | ||
|
|
6df489d5a9 | ||
|
|
15c6ad88c0 | ||
|
|
40f6a9d830 | ||
|
|
bd06c00f3a | ||
|
|
f6d23f0c29 | ||
|
|
2a24459b92 | ||
|
|
f6da324670 | ||
|
|
11a18bd61a | ||
|
|
972134abe4 | ||
|
|
f8770b78ea | ||
|
|
10f2b11fda | ||
|
|
ea1cc4b991 | ||
|
|
8bee3e2fe0 | ||
|
|
1f7adfd9ff | ||
|
|
9e55cd68e4 | ||
|
|
2a6dc67fd7 | ||
|
|
1061ad289a | ||
|
|
0f81b58545 | ||
|
|
2437c5a0ae | ||
|
|
669a6ddeaa | ||
|
|
f5de46670b | ||
|
|
91af8a705b | ||
|
|
82c314f1af | ||
|
|
672413f1f6 | ||
|
|
843bf23f84 | ||
|
|
eeb2d2cc38 | ||
|
|
c370b8f309 | ||
|
|
acd9c12667 | ||
|
|
5535b26395 | ||
|
|
20611cf68c | ||
|
|
06c34ce02f | ||
|
|
4fb50c7408 | ||
|
|
c37bea1676 | ||
|
|
ed985640e8 | ||
|
|
2bd938952d | ||
|
|
623a56391c | ||
|
|
1b7fb10361 | ||
|
|
f6b6688186 | ||
|
|
99453e937c | ||
|
|
d3e0a1f68c | ||
|
|
76ff1a2a49 | ||
|
|
51c6ce1734 | ||
|
|
1998b673f4 | ||
|
|
627497f942 | ||
|
|
f9287941b4 | ||
|
|
5059854a2e | ||
|
|
aa8a061a83 | ||
|
|
3f2d44d517 | ||
|
|
b4af23be23 | ||
|
|
8ddf1f1ea5 | ||
|
|
475d8c4c11 | ||
|
|
fc823eb610 | ||
|
|
8707bab450 | ||
|
|
612955f2b7 | ||
|
|
36314c3ff7 | ||
|
|
33fb38d8de | ||
|
|
38e2a910df | ||
|
|
ef32df77be | ||
|
|
5154693ea4 | ||
|
|
4b68362981 | ||
|
|
658e4c5357 | ||
|
|
ce0dd650d7 | ||
|
|
77b65ada4f | ||
|
|
fa37225a42 | ||
|
|
78a06859b9 | ||
|
|
3ec8f4e84e | ||
|
|
f13a596d15 | ||
|
|
94f14778a3 | ||
|
|
7312284e4f | ||
|
|
ebc07d1458 | ||
|
|
510f719975 | ||
|
|
03c2202942 | ||
|
|
b3a97cb755 | ||
|
|
a9273e1c73 | ||
|
|
14d11ebcab | ||
|
|
7dc458d925 | ||
|
|
a0f04bdcf3 | ||
|
|
28f6e27276 | ||
|
|
5ef427bd65 | ||
|
|
03c1fa43f4 | ||
|
|
3b9f0ab866 | ||
|
|
9617a00ae3 | ||
|
|
1408199957 | ||
|
|
067df8d4dd | ||
|
|
2ab1b13092 | ||
|
|
964d0c219a | ||
|
|
c58eb9c276 | ||
|
|
5d4893b3f0 | ||
|
|
11b4e0d4c0 | ||
|
|
e637693131 | ||
|
|
c9d5b77403 | ||
|
|
574595993c | ||
|
|
50f4e53aef | ||
|
|
ac082e5504 | ||
|
|
f65f9591a1 | ||
|
|
a1eadde25b | ||
|
|
66e5027756 | ||
|
|
aa2d339508 | ||
|
|
d43aacefc9 | ||
|
|
f0a0e20b2f | ||
|
|
befdd8bb66 | ||
|
|
27ed2cc009 | ||
|
|
a60c866a12 | ||
|
|
a84f6228ca | ||
|
|
19da93b675 | ||
|
|
aa38fc712f | ||
|
|
0b1c91dc7c | ||
|
|
ab2c8de4de | ||
|
|
00f2b134e3 | ||
|
|
0b8cebd6ef | ||
|
|
53a9b7f6c0 | ||
|
|
667fd927ee | ||
|
|
a8956838d3 | ||
|
|
e7c9e2060c | ||
|
|
f6be407e33 | ||
|
|
2bf9b37e59 | ||
|
|
d2e0ada794 | ||
|
|
c07ae5806e | ||
|
|
5afe6f7825 | ||
|
|
d02c48f987 | ||
|
|
c835214540 | ||
|
|
cb2901ec40 | ||
|
|
f27bd061fb | ||
|
|
572386e4ce | ||
|
|
67a972182e | ||
|
|
5955e11a5a | ||
|
|
8daaafc864 | ||
|
|
ebaa96c0fa | ||
|
|
fb3d08c651 | ||
|
|
9d15e64f0b | ||
|
|
b62564fd98 | ||
|
|
0266bcab7a | ||
|
|
6652e14662 | ||
|
|
7a50f86f3f | ||
|
|
59218d02c8 | ||
|
|
fe73730d21 | ||
|
|
b814970bdd | ||
|
|
8dfbef5e6f | ||
|
|
0b9a3fc160 | ||
|
|
79105962a7 | ||
|
|
a36e2bc764 | ||
|
|
cc878160bd | ||
|
|
382153e82d | ||
|
|
e195341e30 | ||
|
|
c6c8263704 | ||
|
|
ed02bea20d | ||
|
|
f89a1b05fe | ||
|
|
af65b7e6d7 | ||
|
|
1995ad6d63 | ||
|
|
83c0937a46 | ||
|
|
f5cc2c0d20 | ||
|
|
931d68bc92 | ||
|
|
06946c35d3 | ||
|
|
cbe81fd443 | ||
|
|
173e919d2a | ||
|
|
73fdb8f7b0 | ||
|
|
8e0ba37866 | ||
|
|
8780f50e7e | ||
|
|
06dc357ea0 | ||
|
|
fb587cb529 | ||
|
|
a026677849 | ||
|
|
1c389b1f24 | ||
|
|
55b9aa0309 | ||
|
|
2d5cf2b4c4 | ||
|
|
4877bb5b5c | ||
|
|
b9269d5644 | ||
|
|
1a4723988e | ||
|
|
93353888ca | ||
|
|
c3a90b76d0 | ||
|
|
43e5ca9a1b | ||
|
|
c5829bd0e2 | ||
|
|
2a9d2cc7e9 | ||
|
|
0d9873d8bc | ||
|
|
23bc38ed06 | ||
|
|
42d26b4b05 | ||
|
|
04700789e1 | ||
|
|
e23baa59f0 | ||
|
|
e8e28b61db | ||
|
|
b766707f28 | ||
|
|
0787f262a0 | ||
|
|
d833f4a632 | ||
|
|
ce1e364ab8 | ||
|
|
adb5b299c9 | ||
|
|
0bd039a524 |
@@ -17,7 +17,12 @@ stages:
|
||||
# Common variables
|
||||
variables:
|
||||
COMMON_MESON_FLAGS: "--fatal-meson-warnings --werror"
|
||||
BACKEND_FLAGS: "-Dx11-backend=true -Dwayland-backend=true -Dbroadway-backend=true -Dvulkan=yes"
|
||||
FEATURE_FLAGS: "-Dcloudproviders=true"
|
||||
MESON_TEST_TIMEOUT_MULTIPLIER: 2
|
||||
FEDORA_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora:v17"
|
||||
FLATPAK_IMAGE: "registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:master"
|
||||
DOCS_IMAGE: "registry.gitlab.gnome.org/gnome/gtk/fedora-docs:v19"
|
||||
|
||||
.only-default:
|
||||
only:
|
||||
@@ -27,14 +32,14 @@ variables:
|
||||
|
||||
style-check-diff:
|
||||
extends: .only-default
|
||||
image: registry.gitlab.gnome.org/gnome/gtk/fedora:v17
|
||||
image: $FEDORA_IMAGE
|
||||
stage: .pre
|
||||
allow_failure: true
|
||||
script:
|
||||
- .gitlab-ci/run-style-check-diff.sh
|
||||
|
||||
.build-fedora-default:
|
||||
image: registry.gitlab.gnome.org/gnome/gtk/fedora:v17
|
||||
image: $FEDORA_IMAGE
|
||||
artifacts:
|
||||
when: always
|
||||
reports:
|
||||
@@ -66,11 +71,7 @@ fedora-x86_64:
|
||||
variables:
|
||||
EXTRA_MESON_FLAGS: "--buildtype=debug --default-library=both"
|
||||
script:
|
||||
- meson ${COMMON_MESON_FLAGS} ${EXTRA_MESON_FLAGS}
|
||||
-Dx11-backend=true
|
||||
-Dwayland-backend=true
|
||||
-Dbroadway-backend=true
|
||||
-Dvulkan=yes
|
||||
- meson ${COMMON_MESON_FLAGS} ${EXTRA_MESON_FLAGS} ${BACKEND_FLAGS} ${FEATURE_FLAGS}
|
||||
-Dprofiler=true
|
||||
_build
|
||||
- ninja -C _build
|
||||
@@ -84,11 +85,7 @@ release-build:
|
||||
variables:
|
||||
EXTRA_MESON_FLAGS: "--buildtype=release"
|
||||
script:
|
||||
- meson ${COMMON_MESON_FLAGS} ${EXTRA_MESON_FLAGS}
|
||||
-Dx11-backend=true
|
||||
-Dwayland-backend=true
|
||||
-Dbroadway-backend=true
|
||||
-Dvulkan=yes
|
||||
- meson ${COMMON_MESON_FLAGS} ${EXTRA_MESON_FLAGS} ${BACKEND_FLAGS} ${FEATURE_FLAGS}
|
||||
_build
|
||||
- ninja -C _build
|
||||
- .gitlab-ci/run-tests.sh _build x11
|
||||
@@ -110,14 +107,14 @@ release-build:
|
||||
- subprojects/libepoxy/
|
||||
- subprojects/pango/
|
||||
|
||||
msys2-mingw32:
|
||||
msys2-mingw64:
|
||||
extends: .mingw-defaults
|
||||
variables:
|
||||
MSYSTEM: "MINGW32"
|
||||
MSYSTEM: "MINGW64"
|
||||
CHERE_INVOKING: "yes"
|
||||
|
||||
.flatpak-defaults:
|
||||
image: registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:master
|
||||
image: $FLATPAK_IMAGE
|
||||
stage: flatpak
|
||||
allow_failure: true
|
||||
tags:
|
||||
@@ -171,7 +168,7 @@ flatpak-master:icon-browser:
|
||||
APPID: org.gtk.IconBrowser4
|
||||
|
||||
static-scan:
|
||||
image: registry.gitlab.gnome.org/gnome/gtk/fedora:v16
|
||||
image: $FEDORA_IMAGE
|
||||
stage: analysis
|
||||
variables:
|
||||
EXTRA_MESON_FLAGS: "--buildtype=debug"
|
||||
@@ -184,7 +181,7 @@ static-scan:
|
||||
allow_failure: true
|
||||
|
||||
reference:
|
||||
image: registry.gitlab.gnome.org/gnome/gtk/fedora-docs:v19
|
||||
image: $DOCS_IMAGE
|
||||
stage: docs
|
||||
variables:
|
||||
EXTRA_MESON_FLAGS: "--buildtype=release"
|
||||
|
||||
@@ -4,8 +4,15 @@ set -e
|
||||
|
||||
# We need to add a new remote for the upstream master, since this script could
|
||||
# be running in a personal fork of the repository which has out of date branches.
|
||||
git remote add upstream https://gitlab.gnome.org/GNOME/gtk.git
|
||||
git fetch upstream
|
||||
if [ "${CI_PROJECT_NAMESPACE}" != "GNOME" ]; then
|
||||
echo "Retrieving the current upstream repository from ${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}..."
|
||||
git remote add upstream https://gitlab.gnome.org/GNOME/gtk.git
|
||||
git fetch upstream
|
||||
ORIGIN="upstream"
|
||||
else
|
||||
echo "Reusing the existing repository on ${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}"
|
||||
ORIGIN="origin"
|
||||
fi
|
||||
|
||||
# Work out the newest common ancestor between the detached HEAD that this CI job
|
||||
# has checked out, and the upstream target branch (which will typically be
|
||||
@@ -13,7 +20,7 @@ git fetch upstream
|
||||
#
|
||||
# `${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}` is only defined if we’re running in
|
||||
# a merge request pipeline; fall back to `${CI_DEFAULT_BRANCH}` otherwise.
|
||||
newest_common_ancestor_sha=$(diff --old-line-format='' --new-line-format='' <(git rev-list --first-parent "upstream/${CI_MERGE_REQUEST_TARGET_BRANCH_NAME:-${CI_DEFAULT_BRANCH}}") <(git rev-list --first-parent HEAD) | head -1)
|
||||
newest_common_ancestor_sha=$(diff --old-line-format='' --new-line-format='' <(git rev-list --first-parent "${ORIGIN}/${CI_MERGE_REQUEST_TARGET_BRANCH_NAME:-${CI_DEFAULT_BRANCH}}") <(git rev-list --first-parent HEAD) | head -1)
|
||||
git diff -U0 --no-color "${newest_common_ancestor_sha}" | .gitlab-ci/clang-format-diff.py -binary "clang-format" -p1
|
||||
exit_status=$?
|
||||
|
||||
|
||||
89
NEWS
89
NEWS
@@ -1,3 +1,92 @@
|
||||
Overview of Changes in GTK 3.98.5
|
||||
=================================
|
||||
|
||||
* Introduce new list widgets and supporting infrastructure.
|
||||
The main APIs are:
|
||||
- GtkListView
|
||||
- GtkGridView
|
||||
- GtkColumnView and GtkColumnViewColumn
|
||||
- GtkDropDown
|
||||
- GtkListItemFactory and implementations
|
||||
- GtkExpression
|
||||
- GtkFilter and subclasses, and GtkFilterListModel
|
||||
- GtkSorter and subclasses, and GtkSortListModel
|
||||
- GtkSelectionModel and subclasses
|
||||
- GtkTreeListModel, GtkTreeExpander and GtkTreeListRowSorter
|
||||
|
||||
* GtkFileChooser:
|
||||
- Add a tracker3-based search engine implementation
|
||||
- Rate-limit updates from the trash monitor
|
||||
|
||||
* GtkWindow:
|
||||
- Redo the css node setup. There is now a single 'window' node
|
||||
- Fix rounded corners on tiled windows
|
||||
|
||||
* GtkApplication:
|
||||
- Drop app menu support. Menubar support is still there
|
||||
|
||||
* GtkFixed:
|
||||
- Change coordinate APIs to take doubles
|
||||
|
||||
* GtkOverlay:
|
||||
- Make GtkOverlayLayout public
|
||||
|
||||
* GtkTooltips:
|
||||
- Fix line wrapping of tooltips
|
||||
|
||||
* Shortcuts:
|
||||
- Fix mnemonic cycling
|
||||
- Fix using '0' as a mnemonic
|
||||
|
||||
* Menus:
|
||||
- Differentiate keypad keys in accelerators
|
||||
|
||||
* GtkIMContext:
|
||||
- Add gtk_im_context_filter_key to allow event reinjection
|
||||
|
||||
* Themes:
|
||||
- Adwaita: Limit the scope of backdrop
|
||||
|
||||
* Accessibility:
|
||||
- Clean up and reorganize the code to prepare for the
|
||||
dropping of ATK
|
||||
|
||||
* GDK:
|
||||
- Drop unused enum and struct definitions from headers
|
||||
- Make keymap translation API public again. Still needed
|
||||
- Frameclock: Always use compositor refresh rate info
|
||||
- Frameclock: Use quadratic correction for frame time jitter
|
||||
- Frameclock: Ensure monotonicity
|
||||
- Frameclock: Track resason for paint
|
||||
- X11: Improve sync when the Nvidia driver is used
|
||||
|
||||
* GSK:
|
||||
- GL renderer: Fix blurred outset shadows
|
||||
- GL renderer: handle nested transform nodes properly
|
||||
- GL renderer: Optimize clip handling
|
||||
|
||||
* gtk-demo:
|
||||
- Improve the Drag-and-Drop demo with proper drag icons
|
||||
- Don't show the main window if --run is given
|
||||
- Add demos for list widgets and GtkDropDrown
|
||||
|
||||
* Documentation:
|
||||
- Convert freestanding sections to markdown
|
||||
- Drop the glossary
|
||||
- Expand and improve the migration guide
|
||||
|
||||
* Build:
|
||||
- We require pandoc now, for building the documentation
|
||||
- Require Pango 1.45
|
||||
|
||||
* Translation updates:
|
||||
Polish
|
||||
Romanian
|
||||
Slovenian
|
||||
Turkish
|
||||
Ukrainian
|
||||
|
||||
|
||||
Overview of Changes in GTK 3.98.4
|
||||
=================================
|
||||
|
||||
|
||||
@@ -27,18 +27,6 @@
|
||||
/* Define to 1 if you have the `dcgettext' function. */
|
||||
#mesondefine HAVE_DCGETTEXT
|
||||
|
||||
/* Define to 1 if you have the declaration of `isinf', and to 0 if you don't.
|
||||
*/
|
||||
#mesondefine HAVE_DECL_ISINF
|
||||
|
||||
/* Define to 1 if you have the declaration of `isnan', and to 0 if you don't.
|
||||
*/
|
||||
#mesondefine HAVE_DECL_ISNAN
|
||||
|
||||
/* Define to 1 if you have the declaration of `isnanf', and to 0 if you don't.
|
||||
*/
|
||||
#mesondefine HAVE_DECL_ISNANF
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#mesondefine HAVE_DLFCN_H
|
||||
|
||||
@@ -84,9 +72,6 @@
|
||||
/* Define to 1 if you have a working `mmap' system call. */
|
||||
#mesondefine HAVE_MMAP
|
||||
|
||||
/* Define to 1 if you have the `nearbyint' function. */
|
||||
#mesondefine HAVE_NEARBYINT
|
||||
|
||||
/* Define to 1 if you have the `posix_fallocate' function. */
|
||||
#mesondefine HAVE_POSIX_FALLOCATE
|
||||
|
||||
@@ -96,21 +81,9 @@
|
||||
/* Have the Xrandr 1.5 extension library */
|
||||
#mesondefine HAVE_RANDR15
|
||||
|
||||
/* Define to 1 if you have the `rint' function. */
|
||||
#mesondefine HAVE_RINT
|
||||
|
||||
/* Define to 1 if you have the `round' function. */
|
||||
#mesondefine HAVE_ROUND
|
||||
|
||||
/* Define to 1 if you have the `sincos' function. */
|
||||
#mesondefine HAVE_SINCOS
|
||||
|
||||
/* Define to 1 if you have the `log2` function */
|
||||
#mesondefine HAVE_LOG2
|
||||
|
||||
/* Define to 1 if you ahve the `exp2` function */
|
||||
#mesondefine HAVE_EXP2
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#mesondefine HAVE_STDINT_H
|
||||
|
||||
@@ -150,6 +123,9 @@
|
||||
/* Have the Xcursor library */
|
||||
#mesondefine HAVE_XCURSOR
|
||||
|
||||
/* Have the XDAMAGE X extension */
|
||||
#mesondefine HAVE_XDAMAGE
|
||||
|
||||
/* Have the XFIXES X extension */
|
||||
#mesondefine HAVE_XFIXES
|
||||
|
||||
|
||||
@@ -1,247 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2018 Benjamin Otte
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Benjamin Otte <otte@gnome.org>
|
||||
*/
|
||||
|
||||
#include "award.h"
|
||||
|
||||
struct _GtkAward
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
char *explanation;
|
||||
char *name;
|
||||
char *title;
|
||||
GDateTime *granted; /* or NULL if not granted */
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_EXPLANATION,
|
||||
PROP_NAME,
|
||||
PROP_TITLE,
|
||||
PROP_GRANTED,
|
||||
|
||||
N_PROPS,
|
||||
};
|
||||
|
||||
static GParamSpec *properties[N_PROPS] = { NULL, };
|
||||
|
||||
G_DEFINE_TYPE (GtkAward, gtk_award, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
gtk_award_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
|
||||
{
|
||||
GtkAward *self = GTK_AWARD (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_EXPLANATION:
|
||||
self->explanation = g_value_dup_string (value);
|
||||
break;
|
||||
|
||||
case PROP_NAME:
|
||||
self->name = g_value_dup_string (value);
|
||||
break;
|
||||
|
||||
case PROP_TITLE:
|
||||
self->title = g_value_dup_string (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_award_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkAward *self = GTK_AWARD (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_EXPLANATION:
|
||||
g_value_set_string (value, self->explanation);
|
||||
break;
|
||||
|
||||
case PROP_NAME:
|
||||
g_value_set_string (value, self->name);
|
||||
break;
|
||||
|
||||
case PROP_TITLE:
|
||||
g_value_set_string (value, self->title);
|
||||
break;
|
||||
|
||||
case PROP_GRANTED:
|
||||
g_value_set_boxed (value, self->granted);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_award_dispose (GObject *object)
|
||||
{
|
||||
GtkAward *self = GTK_AWARD (object);
|
||||
|
||||
g_clear_pointer (&self->name, g_free);
|
||||
g_clear_pointer (&self->title, g_free);
|
||||
g_clear_pointer (&self->granted, g_date_time_unref);
|
||||
|
||||
G_OBJECT_CLASS (gtk_award_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_award_class_init (GtkAwardClass *class)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (class);
|
||||
|
||||
gobject_class->set_property = gtk_award_set_property;
|
||||
gobject_class->get_property = gtk_award_get_property;
|
||||
gobject_class->dispose = gtk_award_dispose;
|
||||
|
||||
properties[PROP_EXPLANATION] =
|
||||
g_param_spec_string ("explanation",
|
||||
"Explanation",
|
||||
"How to get the title",
|
||||
NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
properties[PROP_NAME] =
|
||||
g_param_spec_string ("name",
|
||||
"Name",
|
||||
"internal name of the award",
|
||||
NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
properties[PROP_TITLE] =
|
||||
g_param_spec_string ("title",
|
||||
"Title",
|
||||
"user-visible title",
|
||||
NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
properties[PROP_GRANTED] =
|
||||
g_param_spec_boxed ("granted",
|
||||
"Granted",
|
||||
"Timestamp the award was granted or NULL if not granted yet",
|
||||
G_TYPE_DATE_TIME,
|
||||
G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (gobject_class, N_PROPS, properties);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_award_init (GtkAward *self)
|
||||
{
|
||||
}
|
||||
|
||||
GListModel *
|
||||
gtk_award_get_list (void)
|
||||
{
|
||||
static GListModel *list = NULL;
|
||||
|
||||
if (list == NULL)
|
||||
{
|
||||
GtkBuilder *builder;
|
||||
|
||||
g_type_ensure (GTK_TYPE_AWARD);
|
||||
builder = gtk_builder_new_from_resource ("/awards.ui");
|
||||
list = G_LIST_MODEL (gtk_builder_get_object (builder, "list"));
|
||||
g_object_ref (list);
|
||||
g_object_unref (builder);
|
||||
}
|
||||
|
||||
return g_object_ref (list);
|
||||
}
|
||||
|
||||
const char *
|
||||
gtk_award_get_name (GtkAward *award)
|
||||
{
|
||||
return award->name;
|
||||
}
|
||||
|
||||
const char *
|
||||
gtk_award_get_title (GtkAward *award)
|
||||
{
|
||||
return award->title;
|
||||
}
|
||||
|
||||
GDateTime *
|
||||
gtk_award_get_granted (GtkAward *award)
|
||||
{
|
||||
return award->granted;
|
||||
}
|
||||
|
||||
GtkAward *
|
||||
award_find (const char *name)
|
||||
{
|
||||
GListModel *list;
|
||||
GtkAward *self;
|
||||
guint i;
|
||||
|
||||
list = gtk_award_get_list ();
|
||||
g_object_unref (list);
|
||||
|
||||
for (i = 0; i < g_list_model_get_n_items (list); i++)
|
||||
{
|
||||
self = g_list_model_get_item (list, i);
|
||||
g_object_unref (self);
|
||||
|
||||
if (g_ascii_strcasecmp (name, self->name) == 0)
|
||||
return self;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
award (const char *name)
|
||||
{
|
||||
GtkAward *self;
|
||||
GNotification *notification;
|
||||
|
||||
self = award_find (name);
|
||||
if (self == NULL)
|
||||
{
|
||||
g_warning ("Did not find award \"%s\"", name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (self->granted)
|
||||
return;
|
||||
|
||||
self->granted = g_date_time_new_now_utc ();
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_GRANTED]);
|
||||
|
||||
notification = g_notification_new ("You won an award!");
|
||||
g_notification_set_body (notification, self->title);
|
||||
g_application_send_notification (g_application_get_default (), NULL, notification);
|
||||
g_object_unref (notification);
|
||||
}
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
#ifndef __AWARD_H__
|
||||
#define __AWARD_H__
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#define GTK_TYPE_AWARD (gtk_award_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (GtkAward, gtk_award, GTK, AWARD, GObject)
|
||||
|
||||
GListModel * gtk_award_get_list (void);
|
||||
|
||||
const char * gtk_award_get_name (GtkAward *award);
|
||||
const char * gtk_award_get_title (GtkAward *award);
|
||||
GDateTime * gtk_award_get_granted (GtkAward *award);
|
||||
|
||||
void award (const char *name);
|
||||
|
||||
#endif /* __AWARD_H__ */
|
||||
@@ -1,11 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface domain="gtk40">
|
||||
<template class="GtkListItem">
|
||||
<property name="child">
|
||||
<object class="GtkLabel">
|
||||
<property name="label" bind-source="GtkListItem" bind-property="position"></property>
|
||||
<property name="margin">6</property>
|
||||
</object>
|
||||
</property>
|
||||
</template>
|
||||
</interface>
|
||||
@@ -1,89 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<object class="GListStore" id="list">
|
||||
<property name="item-type">GtkAward</property>
|
||||
<child>
|
||||
<object class="GtkAward">
|
||||
<property name="name">demo-inspector</property>
|
||||
<!-- Transformers -->
|
||||
<property name="title" translatable="yes">You got a high-rise double-pump carburetor.</property>
|
||||
<property name="explanation" translatable="yes">Launch the inspector</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkAward">
|
||||
<property name="name">demo-start</property>
|
||||
<!-- The Matrix -->
|
||||
<property name="title" translatable="yes">After this, there is no turning back.</property>
|
||||
<property name="explanation" translatable="yes">Start gtk-demo</property>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkAward">
|
||||
<property name="name">listbox-reshare</property>
|
||||
<!-- Mean Girls -->
|
||||
<property name="title" translatable="yes">Trying to make fetch happen</property>
|
||||
<property name="explanation" translatable="yes">Reshare a tweet</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkAward">
|
||||
<property name="name">listbox-100th-row</property>
|
||||
<!-- Aladdin -->
|
||||
<property name="title" translatable="yes">The ever impressive, long contained, often imitated, but never duplicated Genie of the lamp.</property>
|
||||
<property name="explanation" translatable="yes">Select a 100th row in a list</property>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkAward">
|
||||
<property name="name">password-best</property>
|
||||
<!-- Spaceballs -->
|
||||
<property name="title" translatable="yes">I've got the same combination on my luggage!</property>
|
||||
<property name="explanation" translatable="yes">Use "12345" as the password</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkAward">
|
||||
<property name="name">password-correct</property>
|
||||
<!-- Stanley Parable -->
|
||||
<property name="title" translatable="yes">Night Shark 1-1-5</property>
|
||||
<property name="explanation" translatable="yes">Correctly enter a password</property>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkAward">
|
||||
<property name="name">puzzle-give-up</property>
|
||||
<!-- Pretty Woman -->
|
||||
<property name="title" translatable="yes">Big Mistake. Big. Huge!</property>
|
||||
<property name="explanation" translatable="yes">Close the puzzle without finishing it</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkAward">
|
||||
<property name="name">puzzle-solve</property>
|
||||
<!-- The Incredibles -->
|
||||
<property name="title" translatable="yes">That was totally wicked!</property>
|
||||
<property name="explanation" translatable="yes">Solve a puzzle</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkAward">
|
||||
<property name="name">puzzle-solve-animated</property>
|
||||
<!-- The Phantom Menace -->
|
||||
<property name="title" translatable="yes">A surprise to be sure but a welcome one.</property>
|
||||
<property name="explanation" translatable="yes">Solve an animated puzzle</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkAward">
|
||||
<property name="name">puzzle-solve-large</property>
|
||||
<!-- Portal -->
|
||||
<property name="title" translatable="yes">Science isn't about WHY. It's about WHY NOT?!</property>
|
||||
<property name="explanation" translatable="yes">Solve a puzzle with at least 20 pieces</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
@@ -1,48 +0,0 @@
|
||||
/* Awards
|
||||
*
|
||||
* This demo demonstrates how to use lists to show the awards you have collected
|
||||
* while exploring this demo.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
/* Include the header for accessing the awards */
|
||||
#include "award.h"
|
||||
|
||||
static GtkWidget *window = NULL;
|
||||
|
||||
GtkWidget *
|
||||
do_awardview (GtkWidget *do_widget)
|
||||
{
|
||||
if (!window)
|
||||
{
|
||||
GtkWidget *sw, *listview;
|
||||
GListModel *list;
|
||||
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Awards");
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 400, 300);
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *) &window);
|
||||
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_window_set_child (GTK_WINDOW (window), sw);
|
||||
|
||||
listview = gtk_list_view_new_with_factory (
|
||||
gtk_builder_list_item_factory_new_from_resource (NULL, "/awardview/awardlistitem.ui"));
|
||||
list = gtk_award_get_list ();
|
||||
gtk_list_view_set_model (GTK_LIST_VIEW (listview), list);
|
||||
g_object_unref (list);
|
||||
gtk_list_view_set_show_separators (GTK_LIST_VIEW (listview), TRUE);
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), listview);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
|
||||
return window;
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
/* Constraints/Interactive
|
||||
*
|
||||
* Demonstrate how constraints can be updates during
|
||||
* user interaction.
|
||||
* Demonstrate how constraints can be updates during user interaction.
|
||||
* The vertical edge between the buttons can be dragged with the mouse.
|
||||
*/
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
@@ -94,7 +94,7 @@ do_css_basics (GtkWidget *do_widget)
|
||||
|
||||
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
|
||||
|
||||
container = gtk_scrolled_window_new (NULL, NULL);
|
||||
container = gtk_scrolled_window_new ();
|
||||
gtk_window_set_child (GTK_WINDOW (window), container);
|
||||
child = gtk_text_view_new_with_buffer (text);
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (container), child);
|
||||
|
||||
@@ -132,7 +132,7 @@ do_css_multiplebgs (GtkWidget *do_widget)
|
||||
|
||||
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
|
||||
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
sw = gtk_scrolled_window_new ();
|
||||
gtk_paned_set_end_child (GTK_PANED (paned), sw);
|
||||
child = gtk_text_view_new_with_buffer (text);
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), child);
|
||||
|
||||
@@ -101,7 +101,7 @@ do_css_pixbufs (GtkWidget *do_widget)
|
||||
|
||||
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
|
||||
|
||||
container = gtk_scrolled_window_new (NULL, NULL);
|
||||
container = gtk_scrolled_window_new ();
|
||||
gtk_paned_set_end_child (GTK_PANED (paned), container);
|
||||
child = gtk_text_view_new_with_buffer (text);
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (container), child);
|
||||
|
||||
@@ -119,7 +119,7 @@ do_css_shadows (GtkWidget *do_widget)
|
||||
|
||||
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
|
||||
|
||||
container = gtk_scrolled_window_new (NULL, NULL);
|
||||
container = gtk_scrolled_window_new ();
|
||||
gtk_paned_set_end_child (GTK_PANED (paned), container);
|
||||
child = gtk_text_view_new_with_buffer (text);
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (container), child);
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
/* Cursors
|
||||
*
|
||||
* Demonstrates a useful set of available cursors. The cursors shown here are the ones
|
||||
* defined by CSS, which we assume to be available.
|
||||
*
|
||||
* The example shows creating cursors by name or from an image, with or without a fallback.
|
||||
* Demonstrates a useful set of available cursors. The cursors shown here are the
|
||||
* ones defined by CSS, which we assume to be available. The example shows creating
|
||||
* cursors by name or from an image, with or without a fallback.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<gresources>
|
||||
<gresource prefix="/">
|
||||
<file>awards.ui</file>
|
||||
</gresource>
|
||||
<gresource prefix="/ui">
|
||||
<file preprocess="xml-stripblanks">main.ui</file>
|
||||
@@ -12,9 +11,6 @@
|
||||
<file>application.ui</file>
|
||||
<file>menus.ui</file>
|
||||
</gresource>
|
||||
<gresource prefix="/awardview">
|
||||
<file>awardlistitem.ui</file>
|
||||
</gresource>
|
||||
<gresource prefix="/builder">
|
||||
<file>demo.ui</file>
|
||||
</gresource>
|
||||
@@ -109,6 +105,9 @@
|
||||
<file>zoom_in_cursor.png</file>
|
||||
<file>zoom_out_cursor.png</file>
|
||||
</gresource>
|
||||
<gresource prefix="/dnd">
|
||||
<file>dnd.css</file>
|
||||
</gresource>
|
||||
<gresource prefix="/fishbowl">
|
||||
<file>fishbowl.ui</file>
|
||||
<file>gtkfishbowl.c</file>
|
||||
@@ -127,6 +126,7 @@
|
||||
</gresource>
|
||||
<gresource prefix="/listview_filebrowser">
|
||||
<file>listview_filebrowser.ui</file>
|
||||
<file>listview_filebrowser.css</file>
|
||||
</gresource>
|
||||
<gresource prefix="/listview_minesweeper">
|
||||
<file>listview_minesweeper.ui</file>
|
||||
@@ -177,7 +177,6 @@
|
||||
</gresource>
|
||||
<gresource prefix="/sources">
|
||||
<file>application_demo.c</file>
|
||||
<file>awardview.c</file>
|
||||
<file>assistant.c</file>
|
||||
<file>builder.c</file>
|
||||
<file>clipboard.c</file>
|
||||
@@ -194,6 +193,7 @@
|
||||
<file>cursors.c</file>
|
||||
<file>dialog.c</file>
|
||||
<file>drawingarea.c</file>
|
||||
<file>dropdown.c</file>
|
||||
<file>dnd.c</file>
|
||||
<file>editable_cells.c</file>
|
||||
<file>entry_completion.c</file>
|
||||
@@ -225,6 +225,7 @@
|
||||
<file>listview_minesweeper.c</file>
|
||||
<file>listview_settings.c</file>
|
||||
<file>listview_weather.c</file>
|
||||
<file>listview_words.c</file>
|
||||
<file>list_store.c</file>
|
||||
<file>markup.c</file>
|
||||
<file>modelbutton.c</file>
|
||||
@@ -299,6 +300,7 @@
|
||||
</gresource>
|
||||
<gresource prefix="/transparent">
|
||||
<file>portland-rose.jpg</file>
|
||||
<file>bluroverlay.h</file>
|
||||
<file>bluroverlay.c</file>
|
||||
</gresource>
|
||||
<gresource prefix="/markup">
|
||||
|
||||
@@ -25,31 +25,36 @@
|
||||
#include <gtk/gtk.h>
|
||||
#include <gtk/gtk-a11y.h>
|
||||
|
||||
typedef struct {
|
||||
struct _DemoTaggedEntry
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
|
||||
GtkWidget *box;
|
||||
GtkWidget *entry;
|
||||
} DemoTaggedEntryPrivate;
|
||||
};
|
||||
|
||||
struct _DemoTaggedEntryClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
};
|
||||
|
||||
static void demo_tagged_entry_editable_init (GtkEditableInterface *iface);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (DemoTaggedEntry, demo_tagged_entry, GTK_TYPE_WIDGET,
|
||||
G_ADD_PRIVATE (DemoTaggedEntry)
|
||||
G_IMPLEMENT_INTERFACE (GTK_TYPE_EDITABLE, demo_tagged_entry_editable_init))
|
||||
|
||||
static void
|
||||
demo_tagged_entry_init (DemoTaggedEntry *entry)
|
||||
{
|
||||
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
|
||||
entry->box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
gtk_widget_set_parent (entry->box, GTK_WIDGET (entry));
|
||||
|
||||
priv->box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
gtk_widget_set_parent (priv->box, GTK_WIDGET (entry));
|
||||
|
||||
priv->entry = gtk_text_new ();
|
||||
gtk_widget_set_hexpand (priv->entry, TRUE);
|
||||
gtk_widget_set_vexpand (priv->entry, TRUE);
|
||||
gtk_widget_set_hexpand (priv->box, FALSE);
|
||||
gtk_widget_set_vexpand (priv->box, FALSE);
|
||||
gtk_box_append (GTK_BOX (priv->box), priv->entry);
|
||||
entry->entry = gtk_text_new ();
|
||||
gtk_widget_set_hexpand (entry->entry, TRUE);
|
||||
gtk_widget_set_vexpand (entry->entry, TRUE);
|
||||
gtk_widget_set_hexpand (entry->box, FALSE);
|
||||
gtk_widget_set_vexpand (entry->box, FALSE);
|
||||
gtk_box_append (GTK_BOX (entry->box), entry->entry);
|
||||
gtk_editable_init_delegate (GTK_EDITABLE (entry));
|
||||
}
|
||||
|
||||
@@ -57,23 +62,16 @@ static void
|
||||
demo_tagged_entry_dispose (GObject *object)
|
||||
{
|
||||
DemoTaggedEntry *entry = DEMO_TAGGED_ENTRY (object);
|
||||
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
|
||||
|
||||
if (priv->entry)
|
||||
if (entry->entry)
|
||||
gtk_editable_finish_delegate (GTK_EDITABLE (entry));
|
||||
|
||||
g_clear_pointer (&priv->entry, gtk_widget_unparent);
|
||||
g_clear_pointer (&priv->box, gtk_widget_unparent);
|
||||
g_clear_pointer (&entry->entry, gtk_widget_unparent);
|
||||
g_clear_pointer (&entry->box, gtk_widget_unparent);
|
||||
|
||||
G_OBJECT_CLASS (demo_tagged_entry_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
demo_tagged_entry_finalize (GObject *object)
|
||||
{
|
||||
G_OBJECT_CLASS (demo_tagged_entry_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
demo_tagged_entry_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
@@ -98,44 +96,12 @@ demo_tagged_entry_get_property (GObject *object,
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
|
||||
static void
|
||||
demo_tagged_entry_measure (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
int for_size,
|
||||
int *minimum,
|
||||
int *natural,
|
||||
int *minimum_baseline,
|
||||
int *natural_baseline)
|
||||
{
|
||||
DemoTaggedEntry *entry = DEMO_TAGGED_ENTRY (widget);
|
||||
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
|
||||
|
||||
gtk_widget_measure (priv->box, orientation, for_size,
|
||||
minimum, natural,
|
||||
minimum_baseline, natural_baseline);
|
||||
}
|
||||
|
||||
static void
|
||||
demo_tagged_entry_size_allocate (GtkWidget *widget,
|
||||
int width,
|
||||
int height,
|
||||
int baseline)
|
||||
{
|
||||
DemoTaggedEntry *entry = DEMO_TAGGED_ENTRY (widget);
|
||||
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
|
||||
|
||||
gtk_widget_size_allocate (priv->box,
|
||||
&(GtkAllocation) { 0, 0, width, height },
|
||||
baseline);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
demo_tagged_entry_grab_focus (GtkWidget *widget)
|
||||
{
|
||||
DemoTaggedEntry *entry = DEMO_TAGGED_ENTRY (widget);
|
||||
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
|
||||
|
||||
return gtk_widget_grab_focus (priv->entry);
|
||||
return gtk_widget_grab_focus (entry->entry);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -145,16 +111,14 @@ demo_tagged_entry_class_init (DemoTaggedEntryClass *klass)
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->dispose = demo_tagged_entry_dispose;
|
||||
object_class->finalize = demo_tagged_entry_finalize;
|
||||
object_class->get_property = demo_tagged_entry_get_property;
|
||||
object_class->set_property = demo_tagged_entry_set_property;
|
||||
|
||||
widget_class->measure = demo_tagged_entry_measure;
|
||||
widget_class->size_allocate = demo_tagged_entry_size_allocate;
|
||||
widget_class->grab_focus = demo_tagged_entry_grab_focus;
|
||||
|
||||
|
||||
gtk_editable_install_properties (object_class, 1);
|
||||
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
|
||||
gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_ENTRY_ACCESSIBLE);
|
||||
gtk_widget_class_set_css_name (widget_class, "entry");
|
||||
}
|
||||
@@ -162,10 +126,7 @@ demo_tagged_entry_class_init (DemoTaggedEntryClass *klass)
|
||||
static GtkEditable *
|
||||
demo_tagged_entry_get_delegate (GtkEditable *editable)
|
||||
{
|
||||
DemoTaggedEntry *entry = DEMO_TAGGED_ENTRY (editable);
|
||||
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
|
||||
|
||||
return GTK_EDITABLE (priv->entry);
|
||||
return GTK_EDITABLE (DEMO_TAGGED_ENTRY (editable)->entry);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -184,11 +145,9 @@ void
|
||||
demo_tagged_entry_add_tag (DemoTaggedEntry *entry,
|
||||
GtkWidget *tag)
|
||||
{
|
||||
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
|
||||
|
||||
g_return_if_fail (DEMO_IS_TAGGED_ENTRY (entry));
|
||||
|
||||
gtk_box_append (GTK_BOX (priv->box), tag);
|
||||
gtk_box_append (GTK_BOX (entry->box), tag);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -196,30 +155,27 @@ demo_tagged_entry_insert_tag_after (DemoTaggedEntry *entry,
|
||||
GtkWidget *tag,
|
||||
GtkWidget *sibling)
|
||||
{
|
||||
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
|
||||
|
||||
g_return_if_fail (DEMO_IS_TAGGED_ENTRY (entry));
|
||||
|
||||
if (sibling == NULL)
|
||||
gtk_box_append (GTK_BOX (priv->box), tag);
|
||||
gtk_box_append (GTK_BOX (entry->box), tag);
|
||||
else
|
||||
gtk_box_insert_child_after (GTK_BOX (priv->box), tag, sibling);
|
||||
gtk_box_insert_child_after (GTK_BOX (entry->box), tag, sibling);
|
||||
}
|
||||
|
||||
void
|
||||
demo_tagged_entry_remove_tag (DemoTaggedEntry *entry,
|
||||
GtkWidget *tag)
|
||||
{
|
||||
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
|
||||
|
||||
g_return_if_fail (DEMO_IS_TAGGED_ENTRY (entry));
|
||||
|
||||
gtk_box_remove (GTK_BOX (priv->box), tag);
|
||||
gtk_box_remove (GTK_BOX (entry->box), tag);
|
||||
}
|
||||
|
||||
struct _DemoTaggedEntryTag
|
||||
{
|
||||
GtkWidget parent;
|
||||
|
||||
GtkWidget *box;
|
||||
GtkWidget *label;
|
||||
GtkWidget *button;
|
||||
@@ -250,11 +206,11 @@ static guint signals[LAST_SIGNAL] = { 0, };
|
||||
G_DEFINE_TYPE (DemoTaggedEntryTag, demo_tagged_entry_tag, GTK_TYPE_WIDGET)
|
||||
|
||||
static void
|
||||
on_released (GtkGestureClick *gesture,
|
||||
int n_press,
|
||||
double x,
|
||||
double y,
|
||||
DemoTaggedEntryTag *tag)
|
||||
on_released (GtkGestureClick *gesture,
|
||||
int n_press,
|
||||
double x,
|
||||
double y,
|
||||
DemoTaggedEntryTag *tag)
|
||||
{
|
||||
g_signal_emit (tag, signals[SIGNAL_CLICKED], 0);
|
||||
}
|
||||
@@ -469,7 +425,7 @@ demo_tagged_entry_tag_set_has_close_button (DemoTaggedEntryTag *tag,
|
||||
|
||||
image = gtk_image_new_from_icon_name ("window-close-symbolic");
|
||||
tag->button = gtk_button_new ();
|
||||
gtk_box_append (GTK_BOX (tag->button), image);
|
||||
gtk_button_set_child (GTK_BUTTON (tag->button), image);
|
||||
gtk_widget_set_halign (tag->button, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign (tag->button, GTK_ALIGN_CENTER);
|
||||
gtk_button_set_has_frame (GTK_BUTTON (tag->button), FALSE);
|
||||
|
||||
@@ -25,39 +25,11 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define DEMO_TYPE_TAGGED_ENTRY (demo_tagged_entry_get_type ())
|
||||
#define DEMO_TAGGED_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DEMO_TYPE_TAGGED_ENTRY, DemoTaggedEntry))
|
||||
#define DEMO_TAGGED_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DEMO_TYPE_TAGGED_ENTRY, DemoTaggedEntryClass))
|
||||
#define DEMO_IS_TAGGED_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DEMO_TYPE_TAGGED_ENTRY))
|
||||
#define DEMO_IS_TAGGED_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DEMO_TYPE_TAGGED_ENTRY))
|
||||
#define DEMO_TAGGED_ENTRY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DEMO_TYPE_TAGGED_ENTRY, DemoTaggedEntryClass))
|
||||
#define DEMO_TYPE_TAGGED_ENTRY (demo_tagged_entry_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (DemoTaggedEntry, demo_tagged_entry, DEMO, TAGGED_ENTRY, GtkWidget)
|
||||
|
||||
typedef struct _DemoTaggedEntry DemoTaggedEntry;
|
||||
typedef struct _DemoTaggedEntryClass DemoTaggedEntryClass;
|
||||
|
||||
struct _DemoTaggedEntry
|
||||
{
|
||||
GtkWidget parent;
|
||||
};
|
||||
|
||||
struct _DemoTaggedEntryClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
};
|
||||
|
||||
#define DEMO_TYPE_TAGGED_ENTRY_TAG (demo_tagged_entry_tag_get_type ())
|
||||
#define DEMO_TAGGED_ENTRY_TAG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DEMO_TYPE_TAGGED_ENTRY_TAG, DemoTaggedEntryTag))
|
||||
#define DEMO_TAGGED_ENTRY_TAG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DEMO_TYPE_TAGGED_ENTRY_TAG, DemoTaggedEntryTag))
|
||||
#define DEMO_IS_TAGGED_ENTRY_TAG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DEMO_TYPE_TAGGED_ENTRY_TAG))
|
||||
#define DEMO_IS_TAGGED_ENTRY_TAG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DEMO_TYPE_TAGGED_ENTRY_TAG))
|
||||
#define DEMO_TAGGED_ENTRY_TAG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DEMO_TYPE_TAGGED_ENTRY_TAG, DemoTaggedEntryTagClass))
|
||||
|
||||
typedef struct _DemoTaggedEntryTag DemoTaggedEntryTag;
|
||||
typedef struct _DemoTaggedEntryTagClass DemoTaggedEntryTagClass;
|
||||
|
||||
|
||||
GType demo_tagged_entry_get_type (void) G_GNUC_CONST;
|
||||
GType demo_tagged_entry_tag_get_type (void) G_GNUC_CONST;
|
||||
#define DEMO_TYPE_TAGGED_ENTRY_TAG (demo_tagged_entry_tag_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (DemoTaggedEntryTag, demo_tagged_entry_tag, DEMO, TAGGED_ENTRY_TAG, GtkWidget)
|
||||
|
||||
GtkWidget * demo_tagged_entry_new (void);
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/* Dialogs and Message Boxes
|
||||
/* Dialogs
|
||||
*
|
||||
* Dialog widgets are used to pop up a transient window for user feedback.
|
||||
* Dialogs are used to pop up transient windows for information
|
||||
* and user feedback.
|
||||
*/
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
@@ -21,10 +22,9 @@ message_dialog_clicked (GtkButton *button,
|
||||
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
GTK_MESSAGE_INFO,
|
||||
GTK_BUTTONS_OK_CANCEL,
|
||||
"This message box has been popped up the following\n"
|
||||
"number of times:");
|
||||
"Test message");
|
||||
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
|
||||
"%d", i);
|
||||
ngettext ("Has been shown once", "Has been shown %d times", i), i);
|
||||
g_signal_connect (dialog, "response", G_CALLBACK (gtk_window_destroy), NULL);
|
||||
gtk_widget_show (dialog);
|
||||
i++;
|
||||
@@ -61,8 +61,6 @@ interactive_dialog_clicked (GtkButton *button,
|
||||
{
|
||||
GtkWidget *content_area;
|
||||
GtkWidget *dialog;
|
||||
GtkWidget *hbox;
|
||||
GtkWidget *image;
|
||||
GtkWidget *table;
|
||||
GtkWidget *local_entry1;
|
||||
GtkWidget *local_entry2;
|
||||
@@ -71,26 +69,24 @@ interactive_dialog_clicked (GtkButton *button,
|
||||
|
||||
dialog = gtk_dialog_new_with_buttons ("Interactive Dialog",
|
||||
GTK_WINDOW (window),
|
||||
GTK_DIALOG_MODAL| GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
_("_OK"),
|
||||
GTK_RESPONSE_OK,
|
||||
"_Cancel",
|
||||
GTK_RESPONSE_CANCEL,
|
||||
GTK_DIALOG_MODAL| GTK_DIALOG_DESTROY_WITH_PARENT|GTK_DIALOG_USE_HEADER_BAR,
|
||||
_("_OK"), GTK_RESPONSE_OK,
|
||||
_("_Cancel"), GTK_RESPONSE_CANCEL,
|
||||
NULL);
|
||||
|
||||
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
|
||||
|
||||
content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
|
||||
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);
|
||||
gtk_box_append (GTK_BOX (content_area), hbox);
|
||||
|
||||
image = gtk_image_new_from_icon_name ("dialog-question");
|
||||
gtk_image_set_icon_size (GTK_IMAGE (image), GTK_ICON_SIZE_LARGE);
|
||||
gtk_box_append (GTK_BOX (hbox), image);
|
||||
|
||||
table = gtk_grid_new ();
|
||||
gtk_grid_set_row_spacing (GTK_GRID (table), 4);
|
||||
gtk_grid_set_column_spacing (GTK_GRID (table), 4);
|
||||
gtk_box_append (GTK_BOX (hbox), table);
|
||||
gtk_widget_set_hexpand (table, TRUE);
|
||||
gtk_widget_set_vexpand (table, TRUE);
|
||||
gtk_widget_set_halign (table, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign (table, GTK_ALIGN_CENTER);
|
||||
gtk_box_append (GTK_BOX (content_area), table);
|
||||
gtk_grid_set_row_spacing (GTK_GRID (table), 6);
|
||||
gtk_grid_set_column_spacing (GTK_GRID (table), 6);
|
||||
|
||||
label = gtk_label_new_with_mnemonic ("_Entry 1");
|
||||
gtk_grid_attach (GTK_GRID (table), label, 0, 0, 1, 1);
|
||||
local_entry1 = gtk_entry_new ();
|
||||
@@ -123,7 +119,6 @@ interactive_dialog_clicked (GtkButton *button,
|
||||
GtkWidget *
|
||||
do_dialog (GtkWidget *do_widget)
|
||||
{
|
||||
GtkWidget *frame;
|
||||
GtkWidget *vbox;
|
||||
GtkWidget *vbox2;
|
||||
GtkWidget *hbox;
|
||||
@@ -136,22 +131,16 @@ do_dialog (GtkWidget *do_widget)
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Dialogs and Message Boxes");
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Dialogs");
|
||||
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
|
||||
frame = gtk_frame_new ("Dialogs");
|
||||
gtk_widget_set_margin_start (frame, 8);
|
||||
gtk_widget_set_margin_end (frame, 8);
|
||||
gtk_widget_set_margin_top (frame, 8);
|
||||
gtk_widget_set_margin_bottom (frame, 8);
|
||||
gtk_window_set_child (GTK_WINDOW (window), frame);
|
||||
|
||||
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_frame_set_child (GTK_FRAME (frame), vbox);
|
||||
gtk_window_set_child (GTK_WINDOW (window), vbox);
|
||||
|
||||
/* Standard message dialog */
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);
|
||||
|
||||
@@ -38,15 +38,20 @@ set_color (CanvasItem *item,
|
||||
char *str;
|
||||
GtkStyleContext *context;
|
||||
GtkCssProvider *provider;
|
||||
const char *old_class;
|
||||
|
||||
str = gdk_rgba_to_string (color);
|
||||
css = g_strdup_printf ("* { background: %s; padding: 10px; margin: 1px; }", str);
|
||||
css = g_strdup_printf ("* { background: %s; }", str);
|
||||
|
||||
context = gtk_widget_get_style_context (item->label);
|
||||
provider = g_object_get_data (G_OBJECT (context), "style-provider");
|
||||
if (provider)
|
||||
gtk_style_context_remove_provider (context, GTK_STYLE_PROVIDER (provider));
|
||||
|
||||
old_class = (const char *)g_object_get_data (G_OBJECT (item->label), "css-class");
|
||||
if (old_class)
|
||||
gtk_widget_remove_css_class (item->label, old_class);
|
||||
|
||||
provider = gtk_css_provider_new ();
|
||||
gtk_css_provider_load_from_data (provider, css, -1);
|
||||
gtk_style_context_add_provider (gtk_widget_get_style_context (item->label), GTK_STYLE_PROVIDER (provider), 800);
|
||||
@@ -56,6 +61,27 @@ set_color (CanvasItem *item,
|
||||
g_free (css);
|
||||
}
|
||||
|
||||
static void
|
||||
set_css (CanvasItem *item,
|
||||
const char *class)
|
||||
{
|
||||
GtkStyleContext *context;
|
||||
GtkCssProvider *provider;
|
||||
const char *old_class;
|
||||
|
||||
context = gtk_widget_get_style_context (item->label);
|
||||
provider = g_object_get_data (G_OBJECT (context), "style-provider");
|
||||
if (provider)
|
||||
gtk_style_context_remove_provider (context, GTK_STYLE_PROVIDER (provider));
|
||||
|
||||
old_class = (const char *)g_object_get_data (G_OBJECT (item->label), "css-class");
|
||||
if (old_class)
|
||||
gtk_widget_remove_css_class (item->label, old_class);
|
||||
|
||||
g_object_set_data_full (G_OBJECT (item->label), "css-class", g_strdup (class), g_free);
|
||||
gtk_widget_add_css_class (item->label, class);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
item_drag_drop (GtkDropTarget *dest,
|
||||
const GValue *value,
|
||||
@@ -65,7 +91,10 @@ item_drag_drop (GtkDropTarget *dest,
|
||||
GtkWidget *label = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (dest));
|
||||
CanvasItem *item = CANVAS_ITEM (gtk_widget_get_parent (gtk_widget_get_parent (label)));
|
||||
|
||||
set_color (item, g_value_get_boxed (value));
|
||||
if (G_VALUE_TYPE (value) == GDK_TYPE_RGBA)
|
||||
set_color (item, g_value_get_boxed (value));
|
||||
else if (G_VALUE_TYPE (value) == G_TYPE_STRING)
|
||||
set_css (item, g_value_get_string (value));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -132,11 +161,13 @@ canvas_item_init (CanvasItem *item)
|
||||
GdkRGBA rgba;
|
||||
GtkDropTarget *dest;
|
||||
GtkGesture *gesture;
|
||||
GType types[2] = { GDK_TYPE_RGBA, G_TYPE_STRING };
|
||||
|
||||
n_items++;
|
||||
|
||||
text = g_strdup_printf ("Item %d", n_items);
|
||||
item->label = gtk_label_new (text);
|
||||
gtk_widget_add_css_class (item->label, "canvasitem");
|
||||
g_free (text);
|
||||
|
||||
item->fixed = gtk_fixed_new ();
|
||||
@@ -154,7 +185,8 @@ canvas_item_init (CanvasItem *item)
|
||||
|
||||
item->angle = 0;
|
||||
|
||||
dest = gtk_drop_target_new (GDK_TYPE_RGBA, GDK_ACTION_COPY);
|
||||
dest = gtk_drop_target_new (G_TYPE_INVALID, GDK_ACTION_COPY);
|
||||
gtk_drop_target_set_gtypes (dest, types, G_N_ELEMENTS (types));
|
||||
g_signal_connect (dest, "drop", G_CALLBACK (item_drag_drop), NULL);
|
||||
gtk_widget_add_controller (GTK_WIDGET (item->label), GTK_EVENT_CONTROLLER (dest));
|
||||
|
||||
@@ -529,6 +561,42 @@ canvas_new (void)
|
||||
return canvas;
|
||||
}
|
||||
|
||||
static GdkContentProvider *
|
||||
css_drag_prepare (GtkDragSource *source,
|
||||
double x,
|
||||
double y,
|
||||
GtkWidget *button)
|
||||
{
|
||||
const char *class;
|
||||
GdkPaintable *paintable;
|
||||
|
||||
class = (const char *)g_object_get_data (G_OBJECT (button), "css-class");
|
||||
|
||||
paintable = gtk_widget_paintable_new (button);
|
||||
gtk_drag_source_set_icon (source, paintable, 0, 0);
|
||||
g_object_unref (paintable);
|
||||
|
||||
return gdk_content_provider_new_typed (G_TYPE_STRING, class);
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
css_button_new (const char *class)
|
||||
{
|
||||
GtkWidget *button;
|
||||
GtkDragSource *source;
|
||||
|
||||
button = gtk_image_new ();
|
||||
gtk_widget_set_size_request (button, 48, 32);
|
||||
gtk_widget_add_css_class (button, class);
|
||||
g_object_set_data (G_OBJECT (button), "css-class", (gpointer)class);
|
||||
|
||||
source = gtk_drag_source_new ();
|
||||
g_signal_connect (source, "prepare", G_CALLBACK (css_drag_prepare), button);
|
||||
gtk_widget_add_controller (button, GTK_EVENT_CONTROLLER (source));
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
static GtkWidget *window = NULL;
|
||||
|
||||
GtkWidget *
|
||||
@@ -548,10 +616,18 @@ do_dnd (GtkWidget *do_widget)
|
||||
};
|
||||
int i;
|
||||
int x, y;
|
||||
GtkCssProvider *provider;
|
||||
|
||||
button = gtk_color_button_new ();
|
||||
g_object_unref (g_object_ref_sink (button));
|
||||
|
||||
provider = gtk_css_provider_new ();
|
||||
gtk_css_provider_load_from_resource (provider, "/dnd/dnd.css");
|
||||
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
|
||||
GTK_STYLE_PROVIDER (provider),
|
||||
800);
|
||||
g_object_unref (provider);
|
||||
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
@@ -583,7 +659,7 @@ do_dnd (GtkWidget *do_widget)
|
||||
y += 100;
|
||||
}
|
||||
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
sw = gtk_scrolled_window_new ();
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
GTK_POLICY_NEVER);
|
||||
@@ -606,6 +682,10 @@ do_dnd (GtkWidget *do_widget)
|
||||
NULL);
|
||||
gtk_box_append (GTK_BOX (box3), swatch);
|
||||
}
|
||||
|
||||
gtk_box_append (GTK_BOX (box3), css_button_new ("rainbow1"));
|
||||
gtk_box_append (GTK_BOX (box3), css_button_new ("rainbow2"));
|
||||
gtk_box_append (GTK_BOX (box3), css_button_new ("rainbow3"));
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
|
||||
37
demos/gtk-demo/dnd.css
Normal file
37
demos/gtk-demo/dnd.css
Normal file
@@ -0,0 +1,37 @@
|
||||
label.canvasitem {
|
||||
padding: 10px;
|
||||
margin: 1px;
|
||||
}
|
||||
|
||||
.canvasitem.rainbow1,
|
||||
image.rainbow1 {
|
||||
background: linear-gradient(140deg,red,orange,yellow,green,blue,purple);
|
||||
}
|
||||
|
||||
.canvasitem.rainbow2,
|
||||
image.rainbow2 {
|
||||
animation: rainbow2 1s infinite linear;
|
||||
}
|
||||
|
||||
@keyframes rainbow2 {
|
||||
0% { background: linear-gradient(0deg,red,orange,yellow,green,blue,purple); }
|
||||
25% { background: linear-gradient(90deg,red,orange,yellow,green,blue,purple); }
|
||||
50% { background: linear-gradient(180deg,red,orange,yellow,green,blue,purple); }
|
||||
75% { background: linear-gradient(270deg,red,orange,yellow,green,blue,purple); }
|
||||
100% { background: linear-gradient(360deg,red,orange,yellow,green,blue,purple); }
|
||||
}
|
||||
|
||||
.canvasitem.rainbow3,
|
||||
image.rainbow3 {
|
||||
animation: rainbow3 1s infinite linear;
|
||||
}
|
||||
|
||||
@keyframes rainbow3 {
|
||||
0% { background: linear-gradient(140deg,red,orange,yellow,green,blue,purple); }
|
||||
16.6% { background: linear-gradient(140deg,purple,red,orange,yellow,green,blue); }
|
||||
33.2% { background: linear-gradient(140deg,blue,purple,red,orange,yellow,green); }
|
||||
50% { background: linear-gradient(140deg,green,blue,purple,red,orange,yellow); }
|
||||
66.6% { background: linear-gradient(140deg,yellow,green,blue,purple,red,orange); }
|
||||
83.2% { background: linear-gradient(140deg,orange,yellow,green,blue,purple,red); }
|
||||
100% { background: linear-gradient(140deg,red,orange,yellow,green,blue,purple); }
|
||||
}
|
||||
305
demos/gtk-demo/dropdown.c
Normal file
305
demos/gtk-demo/dropdown.c
Normal file
@@ -0,0 +1,305 @@
|
||||
/* Drop Downs
|
||||
*
|
||||
* The GtkDropDown widget is a modern alternative to GtkComboBox.
|
||||
* It uses list models instead of tree models, and the content is
|
||||
* displayed using widgets instead of cell renderers.
|
||||
*
|
||||
* The examples here demonstrate how to use different kinds of
|
||||
* list models with GtkDropDown, how to use search and how to
|
||||
* display the selected item differently from the presentation
|
||||
* in the popup.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
|
||||
#define STRING_TYPE_HOLDER (string_holder_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (StringHolder, string_holder, STRING, HOLDER, GObject)
|
||||
|
||||
struct _StringHolder {
|
||||
GObject parent_instance;
|
||||
char *title;
|
||||
char *icon;
|
||||
char *description;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (StringHolder, string_holder, G_TYPE_OBJECT);
|
||||
|
||||
static void
|
||||
string_holder_init (StringHolder *holder)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
string_holder_finalize (GObject *object)
|
||||
{
|
||||
StringHolder *holder = STRING_HOLDER (object);
|
||||
|
||||
g_free (holder->title);
|
||||
g_free (holder->icon);
|
||||
g_free (holder->description);
|
||||
|
||||
G_OBJECT_CLASS (string_holder_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
string_holder_class_init (StringHolderClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
|
||||
object_class->finalize = string_holder_finalize;
|
||||
}
|
||||
|
||||
static StringHolder *
|
||||
string_holder_new (const char *title, const char *icon, const char *description)
|
||||
{
|
||||
StringHolder *holder = g_object_new (STRING_TYPE_HOLDER, NULL);
|
||||
holder->title = g_strdup (title);
|
||||
holder->icon = g_strdup (icon);
|
||||
holder->description = g_strdup (description);
|
||||
return holder;
|
||||
}
|
||||
|
||||
static void
|
||||
strings_setup_item_single_line (GtkSignalListItemFactory *factory,
|
||||
GtkListItem *item)
|
||||
{
|
||||
GtkWidget *box, *image, *title;
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
|
||||
|
||||
image = gtk_image_new ();
|
||||
title = gtk_label_new ("");
|
||||
gtk_label_set_xalign (GTK_LABEL (title), 0.0);
|
||||
|
||||
gtk_box_append (GTK_BOX (box), image);
|
||||
gtk_box_append (GTK_BOX (box), title);
|
||||
|
||||
g_object_set_data (G_OBJECT (item), "title", title);
|
||||
g_object_set_data (G_OBJECT (item), "image", image);
|
||||
|
||||
gtk_list_item_set_child (item, box);
|
||||
}
|
||||
|
||||
static void
|
||||
strings_setup_item_full (GtkSignalListItemFactory *factory,
|
||||
GtkListItem *item)
|
||||
{
|
||||
GtkWidget *box, *box2, *image, *title, *description;
|
||||
|
||||
image = gtk_image_new ();
|
||||
title = gtk_label_new ("");
|
||||
gtk_label_set_xalign (GTK_LABEL (title), 0.0);
|
||||
description = gtk_label_new ("");
|
||||
gtk_label_set_xalign (GTK_LABEL (description), 0.0);
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (description), "dim-label");
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
|
||||
box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
|
||||
|
||||
gtk_box_append (GTK_BOX (box), image);
|
||||
gtk_box_append (GTK_BOX (box), box2);
|
||||
gtk_box_append (GTK_BOX (box2), title);
|
||||
gtk_box_append (GTK_BOX (box2), description);
|
||||
|
||||
g_object_set_data (G_OBJECT (item), "title", title);
|
||||
g_object_set_data (G_OBJECT (item), "image", image);
|
||||
g_object_set_data (G_OBJECT (item), "description", description);
|
||||
|
||||
gtk_list_item_set_child (item, box);
|
||||
}
|
||||
|
||||
static void
|
||||
strings_bind_item (GtkSignalListItemFactory *factory,
|
||||
GtkListItem *item)
|
||||
{
|
||||
GtkWidget *image, *title, *description;
|
||||
StringHolder *holder;
|
||||
|
||||
holder = gtk_list_item_get_item (item);
|
||||
|
||||
title = g_object_get_data (G_OBJECT (item), "title");
|
||||
image = g_object_get_data (G_OBJECT (item), "image");
|
||||
description = g_object_get_data (G_OBJECT (item), "description");
|
||||
|
||||
gtk_label_set_label (GTK_LABEL (title), holder->title);
|
||||
if (image)
|
||||
{
|
||||
gtk_image_set_from_icon_name (GTK_IMAGE (image), holder->icon);
|
||||
gtk_widget_set_visible (image, holder->icon != NULL);
|
||||
}
|
||||
if (description)
|
||||
{
|
||||
gtk_label_set_label (GTK_LABEL (description), holder->description);
|
||||
gtk_widget_set_visible (description , holder->description != NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static GtkListItemFactory *
|
||||
strings_factory_new (gboolean full)
|
||||
{
|
||||
GtkListItemFactory *factory;
|
||||
|
||||
factory = gtk_signal_list_item_factory_new ();
|
||||
if (full)
|
||||
g_signal_connect (factory, "setup", G_CALLBACK (strings_setup_item_full), NULL);
|
||||
else
|
||||
g_signal_connect (factory, "setup", G_CALLBACK (strings_setup_item_single_line), NULL);
|
||||
g_signal_connect (factory, "bind", G_CALLBACK (strings_bind_item), NULL);
|
||||
|
||||
return factory;
|
||||
}
|
||||
|
||||
static GListModel *
|
||||
strings_model_new (const char *const *titles,
|
||||
const char *const *icons,
|
||||
const char *const *descriptions)
|
||||
{
|
||||
GListStore *store;
|
||||
int i;
|
||||
|
||||
store = g_list_store_new (STRING_TYPE_HOLDER);
|
||||
for (i = 0; titles[i]; i++)
|
||||
{
|
||||
StringHolder *holder = string_holder_new (titles[i],
|
||||
icons ? icons[i] : NULL,
|
||||
descriptions ? descriptions[i] : NULL);
|
||||
g_list_store_append (store, holder);
|
||||
g_object_unref (holder);
|
||||
}
|
||||
|
||||
return G_LIST_MODEL (store);
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
drop_down_new_from_strings (const char *const *titles,
|
||||
const char *const *icons,
|
||||
const char *const *descriptions)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
GListModel *model;
|
||||
GtkListItemFactory *factory;
|
||||
GtkListItemFactory *list_factory;
|
||||
|
||||
g_return_val_if_fail (titles != NULL, NULL);
|
||||
g_return_val_if_fail (icons == NULL || g_strv_length ((char **)icons) == g_strv_length ((char **)titles), NULL);
|
||||
g_return_val_if_fail (descriptions == NULL || g_strv_length ((char **)icons) == g_strv_length ((char **)descriptions), NULL);
|
||||
|
||||
model = strings_model_new (titles, icons, descriptions);
|
||||
factory = strings_factory_new (FALSE);
|
||||
if (icons != NULL || descriptions != NULL)
|
||||
list_factory = strings_factory_new (TRUE);
|
||||
else
|
||||
list_factory = NULL;
|
||||
|
||||
widget = g_object_new (GTK_TYPE_DROP_DOWN,
|
||||
"model", model,
|
||||
"factory", factory,
|
||||
"list-factory", list_factory,
|
||||
NULL);
|
||||
|
||||
g_object_unref (model);
|
||||
g_object_unref (factory);
|
||||
if (list_factory)
|
||||
g_object_unref (list_factory);
|
||||
|
||||
return widget;
|
||||
}
|
||||
|
||||
static char *
|
||||
get_family_name (gpointer item)
|
||||
{
|
||||
return g_strdup (pango_font_family_get_name (PANGO_FONT_FAMILY (item)));
|
||||
}
|
||||
|
||||
static char *
|
||||
get_title (gpointer item)
|
||||
{
|
||||
return g_strdup (STRING_HOLDER (item)->title);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_dropdown (GtkWidget *do_widget)
|
||||
{
|
||||
static GtkWidget *window = NULL;
|
||||
GtkWidget *button, *box, *spin, *check;
|
||||
GListModel *model;
|
||||
GtkExpression *expression;
|
||||
const char * const times[] = { "1 minute", "2 minutes", "5 minutes", "20 minutes", NULL };
|
||||
const char * const many_times[] = {
|
||||
"1 minute", "2 minutes", "5 minutes", "10 minutes", "15 minutes", "20 minutes",
|
||||
"25 minutes", "30 minutes", "35 minutes", "40 minutes", "45 minutes", "50 minutes",
|
||||
"55 minutes", "1 hour", "2 hours", "3 hours", "5 hours", "6 hours", "7 hours",
|
||||
"8 hours", "9 hours", "10 hours", "11 hours", "12 hours", NULL
|
||||
};
|
||||
const char * const device_titles[] = { "Digital Output", "Headphones", "Digital Output", "Analog Output", NULL };
|
||||
const char * const device_icons[] = { "audio-card-symbolic", "audio-headphones-symbolic", "audio-card-symbolic", "audio-card-symbolic", NULL };
|
||||
const char * const device_descriptions[] = {
|
||||
"Built-in Audio", "Built-in audio", "Thinkpad Tunderbolt 3 Dock USB Audio", "Thinkpad Tunderbolt 3 Dock USB Audio", NULL
|
||||
};
|
||||
|
||||
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), "Drop Downs");
|
||||
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
|
||||
gtk_widget_set_margin_start (box, 10);
|
||||
gtk_widget_set_margin_end (box, 10);
|
||||
gtk_widget_set_margin_top (box, 10);
|
||||
gtk_widget_set_margin_bottom (box, 10);
|
||||
gtk_window_set_child (GTK_WINDOW (window), box);
|
||||
|
||||
button = gtk_drop_down_new ();
|
||||
|
||||
model = G_LIST_MODEL (pango_cairo_font_map_get_default ());
|
||||
gtk_drop_down_set_model (GTK_DROP_DOWN (button), model);
|
||||
gtk_drop_down_set_selected (GTK_DROP_DOWN (button), 0);
|
||||
|
||||
expression = gtk_cclosure_expression_new (G_TYPE_STRING, NULL,
|
||||
0, NULL,
|
||||
(GCallback)get_family_name,
|
||||
NULL, NULL);
|
||||
gtk_drop_down_set_expression (GTK_DROP_DOWN (button), expression);
|
||||
gtk_expression_unref (expression);
|
||||
gtk_box_append (GTK_BOX (box), button);
|
||||
|
||||
spin = gtk_spin_button_new_with_range (-1, g_list_model_get_n_items (G_LIST_MODEL (model)), 1);
|
||||
gtk_widget_set_halign (spin, GTK_ALIGN_START);
|
||||
g_object_bind_property (button, "selected", spin, "value", G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
|
||||
gtk_box_append (GTK_BOX (box), spin);
|
||||
|
||||
check = gtk_check_button_new_with_label ("Enable search");
|
||||
g_object_bind_property (button, "enable-search", check, "active", G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
|
||||
gtk_box_append (GTK_BOX (box), check);
|
||||
|
||||
g_object_unref (model);
|
||||
|
||||
button = drop_down_new_from_strings (times, NULL, NULL);
|
||||
gtk_box_append (GTK_BOX (box), button);
|
||||
|
||||
button = drop_down_new_from_strings (many_times, NULL, NULL);
|
||||
gtk_drop_down_set_enable_search (GTK_DROP_DOWN (button), TRUE);
|
||||
expression = gtk_cclosure_expression_new (G_TYPE_STRING, NULL,
|
||||
0, NULL,
|
||||
(GCallback)get_title,
|
||||
NULL, NULL);
|
||||
gtk_drop_down_set_expression (GTK_DROP_DOWN (button), expression);
|
||||
gtk_expression_unref (expression);
|
||||
gtk_box_append (GTK_BOX (box), button);
|
||||
|
||||
button = drop_down_new_from_strings (device_titles, device_icons, device_descriptions);
|
||||
gtk_box_append (GTK_BOX (box), button);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
|
||||
return window;
|
||||
}
|
||||
@@ -364,7 +364,7 @@ do_editable_cells (GtkWidget *do_widget)
|
||||
gtk_box_append (GTK_BOX (vbox),
|
||||
gtk_label_new ("Shopping list (you can edit the cells!)"));
|
||||
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
sw = gtk_scrolled_window_new ();
|
||||
gtk_scrolled_window_set_has_frame (GTK_SCROLLED_WINDOW (sw), TRUE);
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Entry/Entry Completion
|
||||
/* Entry/Completion
|
||||
*
|
||||
* GtkEntryCompletion provides a mechanism for adding support for
|
||||
* completion in GtkEntry.
|
||||
@@ -12,22 +12,48 @@
|
||||
static GtkTreeModel *
|
||||
create_completion_model (void)
|
||||
{
|
||||
const char *strings[] = {
|
||||
"GNOME",
|
||||
"gnominious",
|
||||
"Gnomonic projection",
|
||||
"Gnosophy",
|
||||
"total",
|
||||
"totally",
|
||||
"toto",
|
||||
"tottery",
|
||||
"totterer",
|
||||
"Totten trust",
|
||||
"Tottenham hotspurs",
|
||||
"totipotent",
|
||||
"totipotency",
|
||||
"totemism",
|
||||
"totem pole",
|
||||
"Totara",
|
||||
"totalizer",
|
||||
"totalizator",
|
||||
"totalitarianism",
|
||||
"total parenteral nutrition",
|
||||
"total eclipse",
|
||||
"Totipresence",
|
||||
"Totipalmi",
|
||||
"zombie",
|
||||
"aæx",
|
||||
"aæy",
|
||||
"aæz",
|
||||
NULL
|
||||
};
|
||||
int i;
|
||||
GtkListStore *store;
|
||||
GtkTreeIter iter;
|
||||
|
||||
store = gtk_list_store_new (1, G_TYPE_STRING);
|
||||
|
||||
/* Append one word */
|
||||
gtk_list_store_append (store, &iter);
|
||||
gtk_list_store_set (store, &iter, 0, "GNOME", -1);
|
||||
|
||||
/* Append another word */
|
||||
gtk_list_store_append (store, &iter);
|
||||
gtk_list_store_set (store, &iter, 0, "total", -1);
|
||||
|
||||
/* And another word */
|
||||
gtk_list_store_append (store, &iter);
|
||||
gtk_list_store_set (store, &iter, 0, "totally", -1);
|
||||
for (i = 0; strings[i]; i++)
|
||||
{
|
||||
/* Append one word */
|
||||
gtk_list_store_append (store, &iter);
|
||||
gtk_list_store_set (store, &iter, 0, strings[i], -1);
|
||||
}
|
||||
|
||||
return GTK_TREE_MODEL (store);
|
||||
}
|
||||
@@ -48,7 +74,7 @@ do_entry_completion (GtkWidget *do_widget)
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Entry Completion");
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Completion");
|
||||
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
|
||||
@@ -60,7 +86,7 @@ do_entry_completion (GtkWidget *do_widget)
|
||||
gtk_window_set_child (GTK_WINDOW (window), vbox);
|
||||
|
||||
label = gtk_label_new (NULL);
|
||||
gtk_label_set_markup (GTK_LABEL (label), "Completion demo, try writing <b>total</b> or <b>gnome</b> for example.");
|
||||
gtk_label_set_markup (GTK_LABEL (label), "Try writing <b>total</b> or <b>gnome</b> for example.");
|
||||
gtk_box_append (GTK_BOX (vbox), label);
|
||||
|
||||
/* Create our entry */
|
||||
@@ -81,6 +107,9 @@ do_entry_completion (GtkWidget *do_widget)
|
||||
|
||||
/* Use model column 0 as the text column */
|
||||
gtk_entry_completion_set_text_column (completion, 0);
|
||||
|
||||
gtk_entry_completion_set_inline_completion (completion, TRUE);
|
||||
gtk_entry_completion_set_inline_selection (completion, TRUE);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/* Entry/Entry Undo
|
||||
/* Entry/Undo and Redo
|
||||
*
|
||||
* GtkEntry can provide basic Undo/Redo support using standard keyboard
|
||||
* accelerators such as Primary+z to undo and Primary+Shift+z to redo.
|
||||
* Additionally, Primary+y can be used to redo.
|
||||
* accelerators such as Control+z to undo and Control+Shift+z to redo.
|
||||
* Additionally, Control+y can be used to redo.
|
||||
*
|
||||
* Use gtk_entry_set_enable_undo() to enable undo/redo support.
|
||||
*/
|
||||
@@ -23,7 +23,7 @@ do_entry_undo (GtkWidget *do_widget)
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Entry Undo");
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Undo and Redo");
|
||||
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ do_expander (GtkWidget *do_widget)
|
||||
|
||||
expander = gtk_expander_new ("Details:");
|
||||
gtk_widget_set_vexpand (expander, TRUE);
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
sw = gtk_scrolled_window_new ();
|
||||
gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW (sw), 100);
|
||||
gtk_scrolled_window_set_has_frame (GTK_SCROLLED_WINDOW (sw), TRUE);
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Fixed layout
|
||||
/* Fixed Layout
|
||||
*
|
||||
* GtkFixed is a container that allows placing and transforming
|
||||
* widgets manually.
|
||||
@@ -126,11 +126,11 @@ create_demo_window (GtkWidget *do_widget)
|
||||
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Fixed layout");
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Fixed Layout");
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
|
||||
g_signal_connect (window, "destroy", G_CALLBACK (close_window), NULL);
|
||||
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
sw = gtk_scrolled_window_new ();
|
||||
gtk_window_set_child (GTK_WINDOW (window), sw);
|
||||
|
||||
fixed = gtk_fixed_new ();
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
/* Flow Box
|
||||
*
|
||||
* GtkFlowBox allows flexible and responsive grids which reflow
|
||||
* as needed and support sorting and filtering.
|
||||
*
|
||||
* The children of a GtkFlowBox are regular widgets
|
||||
* as needed and support sorting and filtering. The children of
|
||||
* a GtkFlowBox are regular widgets
|
||||
*
|
||||
* The dataset used here has 665 colors.
|
||||
*/
|
||||
@@ -728,7 +727,7 @@ do_flowbox (GtkWidget *do_widget)
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 400, 600);
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
|
||||
scrolled = gtk_scrolled_window_new (NULL, NULL);
|
||||
scrolled = gtk_scrolled_window_new ();
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
|
||||
flowbox = gtk_flow_box_new ();
|
||||
gtk_widget_set_valign (flowbox, GTK_ALIGN_START);
|
||||
|
||||
@@ -25,7 +25,7 @@ typedef struct _GtkFishbowlChild GtkFishbowlChild;
|
||||
struct _GtkFishbowlPrivate
|
||||
{
|
||||
GtkFishCreationFunc creation_func;
|
||||
GList *children;
|
||||
GHashTable *children;
|
||||
guint count;
|
||||
|
||||
gint64 last_frame_time;
|
||||
@@ -67,6 +67,8 @@ gtk_fishbowl_init (GtkFishbowl *fishbowl)
|
||||
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
|
||||
|
||||
priv->update_delay = G_USEC_PER_SEC;
|
||||
priv->children = g_hash_table_new_full (NULL, NULL,
|
||||
NULL, (GDestroyNotify) g_free);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -93,20 +95,18 @@ gtk_fishbowl_measure (GtkWidget *widget,
|
||||
{
|
||||
GtkFishbowl *fishbowl = GTK_FISHBOWL (widget);
|
||||
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
|
||||
GHashTableIter iter;
|
||||
gpointer key, value;
|
||||
GtkFishbowlChild *child;
|
||||
GList *children;
|
||||
gint child_min, child_nat;
|
||||
|
||||
*minimum = 0;
|
||||
*natural = 0;
|
||||
|
||||
for (children = priv->children; children; children = children->next)
|
||||
g_hash_table_iter_init (&iter, priv->children);
|
||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
{
|
||||
child = children->data;
|
||||
|
||||
if (!gtk_widget_get_visible (child->widget))
|
||||
continue;
|
||||
|
||||
child = value;
|
||||
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
@@ -136,14 +136,13 @@ gtk_fishbowl_size_allocate (GtkWidget *widget,
|
||||
GtkFishbowlChild *child;
|
||||
GtkAllocation child_allocation;
|
||||
GtkRequisition child_requisition;
|
||||
GList *children;
|
||||
GHashTableIter iter;
|
||||
gpointer key, value;
|
||||
|
||||
for (children = priv->children; children; children = children->next)
|
||||
g_hash_table_iter_init (&iter, priv->children);
|
||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
{
|
||||
child = children->data;
|
||||
|
||||
if (!gtk_widget_get_visible (child->widget))
|
||||
continue;
|
||||
child = value;
|
||||
|
||||
gtk_widget_get_preferred_size (child->widget, &child_requisition, NULL);
|
||||
child_allocation.x = round (child->x * (width - child_requisition.width));
|
||||
@@ -181,7 +180,7 @@ gtk_fishbowl_add (GtkFishbowl *fishbowl,
|
||||
|
||||
gtk_widget_set_parent (widget, GTK_WIDGET (fishbowl));
|
||||
|
||||
priv->children = g_list_prepend (priv->children, child_info);
|
||||
g_hash_table_insert (priv->children, widget, child_info);
|
||||
priv->count++;
|
||||
g_object_notify_by_pspec (G_OBJECT (fishbowl), props[PROP_COUNT]);
|
||||
}
|
||||
@@ -191,34 +190,26 @@ gtk_fishbowl_remove (GtkFishbowl *fishbowl,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
|
||||
GtkFishbowlChild *child;
|
||||
GtkWidget *widget_bowl = GTK_WIDGET (fishbowl);
|
||||
GList *children;
|
||||
|
||||
for (children = priv->children; children; children = children->next)
|
||||
if (g_hash_table_remove (priv->children, widget))
|
||||
{
|
||||
child = children->data;
|
||||
gtk_widget_unparent (widget);
|
||||
|
||||
if (child->widget == widget)
|
||||
{
|
||||
gboolean was_visible = gtk_widget_get_visible (widget);
|
||||
|
||||
gtk_widget_unparent (widget);
|
||||
|
||||
priv->children = g_list_remove_link (priv->children, children);
|
||||
g_list_free (children);
|
||||
g_free (child);
|
||||
|
||||
if (was_visible && gtk_widget_get_visible (widget_bowl))
|
||||
gtk_widget_queue_resize (widget_bowl);
|
||||
|
||||
priv->count--;
|
||||
g_object_notify_by_pspec (G_OBJECT (fishbowl), props[PROP_COUNT]);
|
||||
break;
|
||||
}
|
||||
priv->count--;
|
||||
g_object_notify_by_pspec (G_OBJECT (fishbowl), props[PROP_COUNT]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_fishbowl_finalize (GObject *object)
|
||||
{
|
||||
GtkFishbowl *fishbowl = GTK_FISHBOWL (object);
|
||||
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
|
||||
|
||||
g_hash_table_destroy (priv->children);
|
||||
priv->children = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_fishbowl_dispose (GObject *object)
|
||||
{
|
||||
@@ -304,6 +295,7 @@ gtk_fishbowl_class_init (GtkFishbowlClass *klass)
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->finalize = gtk_fishbowl_finalize;
|
||||
object_class->dispose = gtk_fishbowl_dispose;
|
||||
object_class->set_property = gtk_fishbowl_set_property;
|
||||
object_class->get_property = gtk_fishbowl_get_property;
|
||||
@@ -535,8 +527,9 @@ gtk_fishbowl_tick (GtkWidget *widget,
|
||||
GtkFishbowl *fishbowl = GTK_FISHBOWL (widget);
|
||||
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
|
||||
GtkFishbowlChild *child;
|
||||
GList *l;
|
||||
gint64 frame_time, elapsed;
|
||||
GHashTableIter iter;
|
||||
gpointer key, value;
|
||||
gboolean do_update;
|
||||
|
||||
frame_time = gdk_frame_clock_get_frame_time (gtk_widget_get_frame_clock (widget));
|
||||
@@ -548,9 +541,10 @@ gtk_fishbowl_tick (GtkWidget *widget,
|
||||
if (elapsed == frame_time)
|
||||
return G_SOURCE_CONTINUE;
|
||||
|
||||
for (l = priv->children; l; l = l->next)
|
||||
g_hash_table_iter_init (&iter, priv->children);
|
||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
{
|
||||
child = l->data;
|
||||
child = value;
|
||||
|
||||
child->x += child->dx * ((double) elapsed / G_USEC_PER_SEC);
|
||||
child->y += child->dy * ((double) elapsed / G_USEC_PER_SEC);
|
||||
|
||||
@@ -260,7 +260,7 @@ do_hypertext (GtkWidget *do_widget)
|
||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
|
||||
gtk_text_buffer_set_enable_undo (buffer, TRUE);
|
||||
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
sw = gtk_scrolled_window_new ();
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
|
||||
@@ -12,7 +12,7 @@ static GtkWidget *window = NULL;
|
||||
static GtkWidget *scrolledwindow;
|
||||
static int selected;
|
||||
|
||||
#define N_WIDGET_TYPES 4
|
||||
#define N_WIDGET_TYPES 6
|
||||
|
||||
|
||||
static int hincrement = 5;
|
||||
@@ -64,6 +64,7 @@ populate_icons (void)
|
||||
gtk_grid_attach (GTK_GRID (grid), create_icon (), left, top, 1, 1);
|
||||
|
||||
hincrement = 0;
|
||||
vincrement = 5;
|
||||
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow),
|
||||
GTK_POLICY_NEVER,
|
||||
@@ -100,6 +101,7 @@ populate_text (gboolean hilight)
|
||||
gtk_text_view_set_buffer (GTK_TEXT_VIEW (textview), buffer);
|
||||
|
||||
hincrement = 0;
|
||||
vincrement = 5;
|
||||
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow),
|
||||
GTK_POLICY_NEVER,
|
||||
@@ -124,6 +126,7 @@ populate_image (void)
|
||||
gtk_picture_set_can_shrink (GTK_PICTURE (image), FALSE);
|
||||
|
||||
hincrement = 5;
|
||||
vincrement = 5;
|
||||
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow),
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
@@ -131,6 +134,42 @@ populate_image (void)
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scrolledwindow), image);
|
||||
}
|
||||
|
||||
extern GtkWidget *create_weather_view (void);
|
||||
|
||||
static void
|
||||
populate_list (void)
|
||||
{
|
||||
GtkWidget *list;
|
||||
|
||||
list = create_weather_view ();
|
||||
|
||||
hincrement = 5;
|
||||
vincrement = 0;
|
||||
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow),
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scrolledwindow), list);
|
||||
}
|
||||
|
||||
extern GtkWidget *create_color_grid (void);
|
||||
|
||||
static void
|
||||
populate_grid (void)
|
||||
{
|
||||
GtkWidget *list;
|
||||
|
||||
list = create_color_grid ();
|
||||
|
||||
hincrement = 0;
|
||||
vincrement = 5;
|
||||
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow),
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scrolledwindow), list);
|
||||
}
|
||||
|
||||
static void
|
||||
set_widget_type (int type)
|
||||
{
|
||||
@@ -164,6 +203,16 @@ set_widget_type (int type)
|
||||
populate_image ();
|
||||
break;
|
||||
|
||||
case 4:
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Scrolling a list");
|
||||
populate_list ();
|
||||
break;
|
||||
|
||||
case 5:
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Scrolling a grid");
|
||||
populate_grid ();
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
@@ -276,7 +276,7 @@ do_iconview (GtkWidget *do_widget)
|
||||
gtk_box_append (GTK_BOX (tool_bar), home_button);
|
||||
|
||||
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
sw = gtk_scrolled_window_new ();
|
||||
gtk_scrolled_window_set_has_frame (GTK_SCROLLED_WINDOW (sw), TRUE);
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
|
||||
@@ -269,7 +269,7 @@ do_list_store (GtkWidget *do_widget)
|
||||
label = gtk_label_new ("This is the bug list (note: not based on real data, it would be nice to have a nice ODBC interface to bugzilla or so, though).");
|
||||
gtk_box_append (GTK_BOX (vbox), label);
|
||||
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
sw = gtk_scrolled_window_new ();
|
||||
gtk_scrolled_window_set_has_frame (GTK_SCROLLED_WINDOW (sw), TRUE);
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
||||
GTK_POLICY_NEVER,
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include <gtk/gtk.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "award.h"
|
||||
|
||||
static GdkPixbuf *avatar_pixbuf_other;
|
||||
static GtkWidget *window = NULL;
|
||||
@@ -235,7 +234,6 @@ reshare_clicked (GtkMessageRow *row,
|
||||
{
|
||||
GtkMessageRowPrivate *priv = row->priv;
|
||||
|
||||
award ("listbox-reshare");
|
||||
priv->message->n_reshares++;
|
||||
gtk_message_row_update (row);
|
||||
}
|
||||
@@ -262,8 +260,6 @@ gtk_message_row_state_flags_changed (GtkWidget *widget,
|
||||
|
||||
visible = flags & (GTK_STATE_FLAG_PRELIGHT | GTK_STATE_FLAG_SELECTED) ? TRUE : FALSE;
|
||||
gtk_widget_set_visible (priv->extra_buttons_box, visible);
|
||||
if (visible && gtk_list_box_row_get_index (GTK_LIST_BOX_ROW (widget)) % 100 == 99)
|
||||
award ("listbox-100th-row");
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_message_row_parent_class)->state_flags_changed (widget, previous_state_flags);
|
||||
}
|
||||
@@ -362,7 +358,7 @@ do_listbox (GtkWidget *do_widget)
|
||||
gtk_window_set_child (GTK_WINDOW (window), vbox);
|
||||
label = gtk_label_new ("Messages from GTK and friends");
|
||||
gtk_box_append (GTK_BOX (vbox), label);
|
||||
scrolled = gtk_scrolled_window_new (NULL, NULL);
|
||||
scrolled = gtk_scrolled_window_new ();
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
|
||||
gtk_widget_set_vexpand (scrolled, TRUE);
|
||||
gtk_box_append (GTK_BOX (vbox), scrolled);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Lists/Application launcher
|
||||
*
|
||||
* This demo uses the GtkCoverFlow widget as a fancy application launcher.
|
||||
* This demo uses the GtkListView widget as a fancy application launcher.
|
||||
*
|
||||
* It is also a very small introduction to listviews.
|
||||
*/
|
||||
@@ -30,9 +30,7 @@ create_application_list (void)
|
||||
apps = g_app_info_get_all ();
|
||||
|
||||
for (l = apps; l; l = l->next)
|
||||
{
|
||||
g_list_store_append (store, l->data);
|
||||
}
|
||||
g_list_store_append (store, l->data);
|
||||
|
||||
g_list_free_full (apps, g_object_unref);
|
||||
|
||||
@@ -40,19 +38,24 @@ create_application_list (void)
|
||||
}
|
||||
|
||||
/* This is the function we use for setting up new listitems to display.
|
||||
* We add just a #GtkImage here to display the application's icon as this is just
|
||||
* a simple demo.
|
||||
* We add just an #GtkImage and a #GtkKabel here to display the application's
|
||||
* icon and name, as this is just a simple demo.
|
||||
*/
|
||||
static void
|
||||
setup_listitem_cb (GtkListItemFactory *factory,
|
||||
GtkListItem *list_item)
|
||||
{
|
||||
GtkWidget *box;
|
||||
GtkWidget *image;
|
||||
GtkWidget *label;
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
|
||||
image = gtk_image_new ();
|
||||
gtk_image_set_icon_size (GTK_IMAGE (image), GTK_ICON_SIZE_LARGE);
|
||||
|
||||
gtk_list_item_set_child (list_item, image);
|
||||
gtk_box_append (GTK_BOX (box), image);
|
||||
label = gtk_label_new ("");
|
||||
gtk_box_append (GTK_BOX (box), label);
|
||||
gtk_list_item_set_child (list_item, box);
|
||||
}
|
||||
|
||||
/* Here we need to prepare the listitem for displaying its item. We get the
|
||||
@@ -66,12 +69,15 @@ bind_listitem_cb (GtkListItemFactory *factory,
|
||||
GtkListItem *list_item)
|
||||
{
|
||||
GtkWidget *image;
|
||||
GtkWidget *label;
|
||||
GAppInfo *app_info;
|
||||
|
||||
image = gtk_list_item_get_child (list_item);
|
||||
image = gtk_widget_get_first_child (gtk_list_item_get_child (list_item));
|
||||
label = gtk_widget_get_next_sibling (image);
|
||||
app_info = gtk_list_item_get_item (list_item);
|
||||
|
||||
gtk_image_set_from_gicon (GTK_IMAGE (image), g_app_info_get_icon (app_info));
|
||||
gtk_label_set_label (GTK_LABEL (label), g_app_info_get_display_name (app_info));
|
||||
}
|
||||
|
||||
/* In more complex code, we would also need functions to unbind and teardown
|
||||
@@ -90,7 +96,7 @@ bind_listitem_cb (GtkListItemFactory *factory,
|
||||
* above, but this is a simple demo, so we'll use the simple way.
|
||||
*/
|
||||
static void
|
||||
activate_cb (GtkCoverFlow *coverflow,
|
||||
activate_cb (GtkListView *list,
|
||||
guint position,
|
||||
gpointer unused)
|
||||
{
|
||||
@@ -98,15 +104,15 @@ activate_cb (GtkCoverFlow *coverflow,
|
||||
GdkAppLaunchContext *context;
|
||||
GError *error = NULL;
|
||||
|
||||
app_info = g_list_model_get_item (gtk_cover_flow_get_model (coverflow), position);
|
||||
app_info = g_list_model_get_item (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
|
||||
* and #GAppInfo.
|
||||
*/
|
||||
context = gdk_display_get_app_launch_context (gtk_widget_get_display (GTK_WIDGET (coverflow)));
|
||||
context = gdk_display_get_app_launch_context (gtk_widget_get_display (GTK_WIDGET (list)));
|
||||
if (!g_app_info_launch (app_info,
|
||||
NULL,
|
||||
NULL,
|
||||
G_APP_LAUNCH_CONTEXT (context),
|
||||
&error))
|
||||
{
|
||||
@@ -115,7 +121,7 @@ activate_cb (GtkCoverFlow *coverflow,
|
||||
/* And because error handling is important, even a simple demo has it:
|
||||
* We display an error dialog that something went wrong.
|
||||
*/
|
||||
dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (coverflow))),
|
||||
dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (list))),
|
||||
GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL,
|
||||
GTK_MESSAGE_ERROR,
|
||||
GTK_BUTTONS_CLOSE,
|
||||
@@ -136,7 +142,7 @@ do_listview_applauncher (GtkWidget *do_widget)
|
||||
{
|
||||
if (window == NULL)
|
||||
{
|
||||
GtkWidget *coverflow, *sw;;
|
||||
GtkWidget *list, *sw;
|
||||
GListModel *model;
|
||||
GtkListItemFactory *factory;
|
||||
|
||||
@@ -147,7 +153,7 @@ do_listview_applauncher (GtkWidget *do_widget)
|
||||
gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Application Launcher");
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *) &window);
|
||||
|
||||
|
||||
/* The #GtkListitemFactory is what is used to create #GtkListItems
|
||||
* to display the data from the model. So it is absolutely necessary
|
||||
* to create one.
|
||||
@@ -160,34 +166,31 @@ do_listview_applauncher (GtkWidget *do_widget)
|
||||
g_signal_connect (factory, "setup", G_CALLBACK (setup_listitem_cb), NULL);
|
||||
g_signal_connect (factory, "bind", G_CALLBACK (bind_listitem_cb), NULL);
|
||||
|
||||
/* Create the list widget here: We use a coverflow widget because it's
|
||||
* the coolest one. We could just as well use other list widgets such
|
||||
* as a #GtkListView or a #GtkGridView and the code would look very
|
||||
* similar.
|
||||
/* Create the list widget here.
|
||||
*/
|
||||
coverflow = gtk_cover_flow_new_with_factory (factory);
|
||||
list = gtk_list_view_new_with_factory (factory);
|
||||
/* We connect the activate signal here. It's the function we defined
|
||||
* above for launching the selected application.
|
||||
*/
|
||||
g_signal_connect (coverflow, "activate", G_CALLBACK (activate_cb), NULL);
|
||||
g_signal_connect (list, "activate", G_CALLBACK (activate_cb), NULL);
|
||||
|
||||
/* And of course we need to set the data model. Here we call the function
|
||||
* we wrote above that gives us the list of applications. Then we set
|
||||
* it on the coverflow list widget.
|
||||
* The coverflow will now take items from the model and use the factory
|
||||
* it on the list widget.
|
||||
* The list will now take items from the model and use the factory
|
||||
* to create as many listitems as it needs to show itself to the user.
|
||||
*/
|
||||
model = create_application_list ();
|
||||
gtk_cover_flow_set_model (GTK_COVER_FLOW (coverflow), model);
|
||||
gtk_list_view_set_model (GTK_LIST_VIEW (list), model);
|
||||
g_object_unref (model);
|
||||
|
||||
/* List widgets should always be contained in a #GtkScrolledWindow,
|
||||
* because otherwise they might get too large or they might not
|
||||
* be scrollable.
|
||||
*/
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
sw = gtk_scrolled_window_new ();
|
||||
gtk_window_set_child (GTK_WINDOW (window), sw);
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), coverflow);
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), list);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
|
||||
@@ -3,10 +3,9 @@
|
||||
* This demo displays the time in different timezones.
|
||||
*
|
||||
* The goal is to show how to set up expressions that track changes
|
||||
* in objects and make them update widgets.
|
||||
*
|
||||
* For that, we create a GtkClock object that updates its time every
|
||||
* second and then use various ways to display that time.
|
||||
* in objects and make them update widgets. For that, we create a
|
||||
* GtkClock object that updates its time every second and then use
|
||||
* various ways to display that time.
|
||||
*
|
||||
* Typically, this will be done using GtkBuilder .ui files with the
|
||||
* help of the <binding> tag, but this demo shows the code that runs
|
||||
@@ -41,7 +40,8 @@ enum {
|
||||
|
||||
/* This function returns the current time in the clock's timezone.
|
||||
* Note that this returns a new object every time, so we need to
|
||||
* remember to unref it after use. */
|
||||
* remember to unref it after use.
|
||||
*/
|
||||
static GDateTime *
|
||||
gtk_clock_get_time (GtkClock *clock)
|
||||
{
|
||||
@@ -51,10 +51,11 @@ gtk_clock_get_time (GtkClock *clock)
|
||||
return g_date_time_new_now_local ();
|
||||
}
|
||||
|
||||
/* Here, we implement the functionality required by the GdkPaintable interface.
|
||||
* This way we have a trivial way to display an analog clock.
|
||||
* It also allows demonstrating how to directly use objects in the listview
|
||||
* later by making this object do something interesting. */
|
||||
/* Here, we implement the functionality required by the GdkPaintable
|
||||
* interface. This way we have a trivial way to display an analog clock.
|
||||
* It also allows demonstrating how to directly use objects in the
|
||||
* listview later by making this object do something interesting.
|
||||
*/
|
||||
static void
|
||||
gtk_clock_snapshot (GdkPaintable *paintable,
|
||||
GdkSnapshot *snapshot,
|
||||
@@ -68,26 +69,31 @@ gtk_clock_snapshot (GdkPaintable *paintable,
|
||||
#define BLACK ((GdkRGBA) { 0, 0, 0, 1 })
|
||||
|
||||
/* save/restore() is necessary so we can undo the transforms we start
|
||||
* out with. */
|
||||
* out with.
|
||||
*/
|
||||
gtk_snapshot_save (snapshot);
|
||||
|
||||
/* First, we move the (0, 0) point to the center of the area so
|
||||
* we can draw everything relative to it. */
|
||||
* we can draw everything relative to it.
|
||||
*/
|
||||
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (width / 2, height / 2));
|
||||
|
||||
/* Next we scale it, so that we can pretend that the clock is
|
||||
* 100px in size. That way, we don't need to do any complicated
|
||||
* math later.
|
||||
* We use MIN() here so that we use the smaller dimension for sizing.
|
||||
* That way we don't overdraw but keep the aspect ratio. */
|
||||
* math later. We use MIN() here so that we use the smaller
|
||||
* dimension for sizing. That way we don't overdraw but keep
|
||||
* the aspect ratio.
|
||||
*/
|
||||
gtk_snapshot_scale (snapshot, MIN (width, height) / 100.0, MIN (width, height) / 100.0);
|
||||
/* Now we have a circle with diameter 100px (and radius 50px) that
|
||||
* has its (0, 0) point at the center.
|
||||
* Let's draw a simple clock into it. */
|
||||
|
||||
/* Now we have a circle with diameter 100px (and radius 50px) that
|
||||
* has its (0, 0) point at the center. Let's draw a simple clock into it.
|
||||
*/
|
||||
time = gtk_clock_get_time (self);
|
||||
|
||||
/* First, draw a circle. This is a neat little trick to draw a circle
|
||||
* without requiring Cairo. */
|
||||
* without requiring Cairo.
|
||||
*/
|
||||
gsk_rounded_rect_init_from_rect (&outline, &GRAPHENE_RECT_INIT(-50, -50, 100, 100), 50);
|
||||
gtk_snapshot_append_border (snapshot,
|
||||
&outline,
|
||||
@@ -95,9 +101,11 @@ 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 points
|
||||
* to, we just rotate everything and then draw the hand as if if was :00.
|
||||
* We don't even need to care about am/pm here because rotations just work. */
|
||||
* We do this using tranforms 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.
|
||||
*/
|
||||
gtk_snapshot_save (snapshot);
|
||||
gtk_snapshot_rotate (snapshot, 30 * g_date_time_get_hour (time) + 0.5 * g_date_time_get_minute (time));
|
||||
gsk_rounded_rect_init_from_rect (&outline, &GRAPHENE_RECT_INIT(-2, -23, 4, 25), 2);
|
||||
@@ -107,7 +115,8 @@ gtk_clock_snapshot (GdkPaintable *paintable,
|
||||
gtk_snapshot_restore (snapshot);
|
||||
|
||||
/* And the same as above for the minute hand. Just make this one longer
|
||||
* so people can tell the hands apart. */
|
||||
* so people can tell the hands apart.
|
||||
*/
|
||||
gtk_snapshot_save (snapshot);
|
||||
gtk_snapshot_rotate (snapshot, 6 * g_date_time_get_minute (time));
|
||||
gsk_rounded_rect_init_from_rect (&outline, &GRAPHENE_RECT_INIT(-2, -43, 4, 45), 2);
|
||||
@@ -125,8 +134,9 @@ gtk_clock_snapshot (GdkPaintable *paintable,
|
||||
gtk_snapshot_pop (snapshot);
|
||||
gtk_snapshot_restore (snapshot);
|
||||
|
||||
/* And finally, don't forget to restore the initial save() that we did for
|
||||
* the initial transformations. */
|
||||
/* And finally, don't forget to restore the initial save() that
|
||||
* we did for the initial transformations.
|
||||
*/
|
||||
gtk_snapshot_restore (snapshot);
|
||||
|
||||
g_date_time_unref (time);
|
||||
@@ -145,10 +155,9 @@ gtk_clock_get_intrinsic_height (GdkPaintable *paintable)
|
||||
return 100;
|
||||
}
|
||||
|
||||
/* Initialize the paintable interface. This way we turn our clock objects
|
||||
* into objects that can be drawn.
|
||||
* There are more functions to this interface to define desired size,
|
||||
* but this is enough.
|
||||
/* Initialize the paintable interface. This way we turn our clocks
|
||||
* into objects that can be drawn. There are more functions to this
|
||||
* interface to define desired size, but this is enough.
|
||||
*/
|
||||
static void
|
||||
gtk_clock_paintable_init (GdkPaintableInterface *iface)
|
||||
@@ -158,8 +167,9 @@ gtk_clock_paintable_init (GdkPaintableInterface *iface)
|
||||
iface->get_intrinsic_height = gtk_clock_get_intrinsic_height;
|
||||
}
|
||||
|
||||
/* Finally, we define the type. The important part is adding the paintable
|
||||
* interface, so GTK knows that this object can indeed be drawm.
|
||||
/* Finally, we define the type. The important part is adding the
|
||||
* paintable interface, so GTK knows that this object can indeed
|
||||
* be drawn.
|
||||
*/
|
||||
G_DEFINE_TYPE_WITH_CODE (GtkClock, gtk_clock, G_TYPE_OBJECT,
|
||||
G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE,
|
||||
@@ -221,11 +231,14 @@ gtk_clock_set_property (GObject *object,
|
||||
|
||||
/* This is the list of all the ticking clocks */
|
||||
static GSList *ticking_clocks = NULL;
|
||||
/* This is the id of the timeout source that is updating all ticking clocks */
|
||||
|
||||
/* This is the ID of the timeout source that is updating all
|
||||
* ticking clocks.
|
||||
*/
|
||||
static guint ticking_clock_id = 0;
|
||||
|
||||
/* Every second, this function is called to tell everybody that the
|
||||
* clocks are ticking.
|
||||
/* Every second, this function is called to tell everybody that
|
||||
* the clocks are ticking.
|
||||
*/
|
||||
static gboolean
|
||||
gtk_clock_tick (gpointer unused)
|
||||
@@ -236,10 +249,11 @@ gtk_clock_tick (gpointer unused)
|
||||
{
|
||||
GtkClock *clock = l->data;
|
||||
|
||||
/* We will now return a different value for the time porperty,
|
||||
/* We will now return a different value for the time property,
|
||||
* so notify about that.
|
||||
*/
|
||||
g_object_notify_by_pspec (G_OBJECT (clock), properties[PROP_TIME]);
|
||||
|
||||
/* We will also draw the hands of the clock differently.
|
||||
* So notify about that, too.
|
||||
*/
|
||||
@@ -309,16 +323,16 @@ gtk_clock_init (GtkClock *self)
|
||||
|
||||
static GtkClock *
|
||||
gtk_clock_new (const char *location,
|
||||
GTimeZone *timezone)
|
||||
GTimeZone *_tz)
|
||||
{
|
||||
GtkClock *result;
|
||||
|
||||
result = g_object_new (GTK_TYPE_CLOCK,
|
||||
"location", location,
|
||||
"timezone", timezone,
|
||||
"timezone", _tz,
|
||||
NULL);
|
||||
|
||||
g_clear_pointer (&timezone, g_time_zone_unref);
|
||||
g_clear_pointer (&_tz, g_time_zone_unref);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -343,6 +357,9 @@ create_clocks_model (void)
|
||||
clock = gtk_clock_new ("San Francisco", g_time_zone_new ("America/Los_Angeles"));
|
||||
g_list_store_append (result, clock);
|
||||
g_object_unref (clock);
|
||||
clock = gtk_clock_new ("Xalapa", g_time_zone_new ("America/Mexico_City"));
|
||||
g_list_store_append (result, clock);
|
||||
g_object_unref (clock);
|
||||
clock = gtk_clock_new ("Boston", g_time_zone_new ("America/New_York"));
|
||||
g_list_store_append (result, clock);
|
||||
g_object_unref (clock);
|
||||
@@ -457,7 +474,7 @@ do_listview_clocks (GtkWidget *do_widget)
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *) &window);
|
||||
|
||||
/* List widgets go into a scrolled window. Always. */
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
sw = gtk_scrolled_window_new ();
|
||||
gtk_window_set_child (GTK_WINDOW (window), sw);
|
||||
|
||||
/* Create the factory that creates the listitems. Because we
|
||||
|
||||
@@ -1,16 +1,23 @@
|
||||
/* Lists/Colors
|
||||
*
|
||||
* This demo displays a list of named colors.
|
||||
* This demo displays a grid of colors.
|
||||
*
|
||||
* It is using a GtkGridView, and shows how to display
|
||||
* and sort the data in various ways. The controls for
|
||||
* this are implemented using GtkDropDown.
|
||||
*
|
||||
* The dataset used here has 9283 items.
|
||||
* The dataset used here has up to 16 777 216 items.
|
||||
*
|
||||
* Note that this demo also functions as a performance
|
||||
* test for some of the list model machinery, and the
|
||||
* biggest sizes here can lock up the application for
|
||||
* extended times when used with sorting.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#define GTK_TYPE_COLOR (gtk_color_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (GtkColor, gtk_color, GTK, COLOR, GObject)
|
||||
|
||||
@@ -21,7 +28,7 @@ struct _GtkColor
|
||||
GObject parent_instance;
|
||||
|
||||
char *name;
|
||||
GdkRGBA *color;
|
||||
GdkRGBA color;
|
||||
int h, s, v;
|
||||
};
|
||||
|
||||
@@ -36,7 +43,7 @@ enum {
|
||||
PROP_SATURATION,
|
||||
PROP_VALUE,
|
||||
|
||||
N_PROPS
|
||||
N_COLOR_PROPS
|
||||
};
|
||||
|
||||
static void
|
||||
@@ -47,7 +54,7 @@ gtk_color_snapshot (GdkPaintable *paintable,
|
||||
{
|
||||
GtkColor *self = GTK_COLOR (paintable);
|
||||
|
||||
gtk_snapshot_append_color (snapshot, self->color, &GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
gtk_snapshot_append_color (snapshot, &self->color, &GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -78,7 +85,82 @@ G_DEFINE_TYPE_WITH_CODE (GtkColor, gtk_color, G_TYPE_OBJECT,
|
||||
G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE,
|
||||
gtk_color_paintable_init))
|
||||
|
||||
static GParamSpec *properties[N_PROPS] = { NULL, };
|
||||
static GParamSpec *color_properties[N_COLOR_PROPS] = { NULL, };
|
||||
|
||||
static void
|
||||
rgb_to_hsv (GdkRGBA *rgba,
|
||||
gdouble *h_out,
|
||||
gdouble *s_out,
|
||||
gdouble *v_out)
|
||||
{
|
||||
gdouble red, green, blue;
|
||||
gdouble h, s, v;
|
||||
gdouble min, max;
|
||||
gdouble delta;
|
||||
|
||||
red = rgba->red;
|
||||
green = rgba->green;
|
||||
blue = rgba->blue;
|
||||
|
||||
h = 0.0;
|
||||
|
||||
if (red > green)
|
||||
{
|
||||
if (red > blue)
|
||||
max = red;
|
||||
else
|
||||
max = blue;
|
||||
|
||||
if (green < blue)
|
||||
min = green;
|
||||
else
|
||||
min = blue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (green > blue)
|
||||
max = green;
|
||||
else
|
||||
max = blue;
|
||||
|
||||
if (red < blue)
|
||||
min = red;
|
||||
else
|
||||
min = blue;
|
||||
}
|
||||
|
||||
v = max;
|
||||
|
||||
if (max != 0.0)
|
||||
s = (max - min) / max;
|
||||
else
|
||||
s = 0.0;
|
||||
|
||||
if (s == 0.0)
|
||||
h = 0.0;
|
||||
else
|
||||
{
|
||||
delta = max - min;
|
||||
|
||||
if (red == max)
|
||||
h = (green - blue) / delta;
|
||||
else if (green == max)
|
||||
h = 2 + (blue - red) / delta;
|
||||
else if (blue == max)
|
||||
h = 4 + (red - green) / delta;
|
||||
|
||||
h /= 6.0;
|
||||
|
||||
if (h < 0.0)
|
||||
h += 1.0;
|
||||
else if (h > 1.0)
|
||||
h -= 1.0;
|
||||
}
|
||||
|
||||
*h_out = h;
|
||||
*s_out = s;
|
||||
*v_out = v;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_color_get_property (GObject *object,
|
||||
@@ -95,19 +177,19 @@ gtk_color_get_property (GObject *object,
|
||||
break;
|
||||
|
||||
case PROP_COLOR:
|
||||
g_value_set_boxed (value, self->color);
|
||||
g_value_set_boxed (value, &self->color);
|
||||
break;
|
||||
|
||||
case PROP_RED:
|
||||
g_value_set_float (value, self->color->red);
|
||||
g_value_set_float (value, self->color.red);
|
||||
break;
|
||||
|
||||
case PROP_GREEN:
|
||||
g_value_set_float (value, self->color->green);
|
||||
g_value_set_float (value, self->color.green);
|
||||
break;
|
||||
|
||||
case PROP_BLUE:
|
||||
g_value_set_float (value, self->color->blue);
|
||||
g_value_set_float (value, self->color.blue);
|
||||
break;
|
||||
|
||||
case PROP_HUE:
|
||||
@@ -135,6 +217,7 @@ gtk_color_set_property (GObject *object,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkColor *self = GTK_COLOR (object);
|
||||
double h, s, v;
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
@@ -143,19 +226,11 @@ gtk_color_set_property (GObject *object,
|
||||
break;
|
||||
|
||||
case PROP_COLOR:
|
||||
self->color = g_value_dup_boxed (value);
|
||||
break;
|
||||
|
||||
case PROP_HUE:
|
||||
self->h = g_value_get_int (value);
|
||||
break;
|
||||
|
||||
case PROP_SATURATION:
|
||||
self->s = g_value_get_int (value);
|
||||
break;
|
||||
|
||||
case PROP_VALUE:
|
||||
self->v = g_value_get_int (value);
|
||||
self->color = *(GdkRGBA *) g_value_dup_boxed (value);
|
||||
rgb_to_hsv (&self->color, &h, &s, &v);
|
||||
self->h = round (360 * h);
|
||||
self->s = round (100 * s);
|
||||
self->v = round (100 * v);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -170,7 +245,6 @@ gtk_color_finalize (GObject *object)
|
||||
GtkColor *self = GTK_COLOR (object);
|
||||
|
||||
g_free (self->name);
|
||||
g_clear_pointer (&self->color, gdk_rgba_free);
|
||||
|
||||
G_OBJECT_CLASS (gtk_color_parent_class)->finalize (object);
|
||||
}
|
||||
@@ -184,24 +258,24 @@ gtk_color_class_init (GtkColorClass *klass)
|
||||
gobject_class->set_property = gtk_color_set_property;
|
||||
gobject_class->finalize = gtk_color_finalize;
|
||||
|
||||
properties[PROP_NAME] =
|
||||
color_properties[PROP_NAME] =
|
||||
g_param_spec_string ("name", NULL, NULL, NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
|
||||
properties[PROP_COLOR] =
|
||||
color_properties[PROP_COLOR] =
|
||||
g_param_spec_boxed ("color", NULL, NULL, GDK_TYPE_RGBA, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
|
||||
properties[PROP_RED] =
|
||||
color_properties[PROP_RED] =
|
||||
g_param_spec_float ("red", NULL, NULL, 0, 1, 0, G_PARAM_READABLE);
|
||||
properties[PROP_GREEN] =
|
||||
color_properties[PROP_GREEN] =
|
||||
g_param_spec_float ("green", NULL, NULL, 0, 1, 0, G_PARAM_READABLE);
|
||||
properties[PROP_BLUE] =
|
||||
color_properties[PROP_BLUE] =
|
||||
g_param_spec_float ("blue", NULL, NULL, 0, 1, 0, G_PARAM_READABLE);
|
||||
properties[PROP_HUE] =
|
||||
g_param_spec_int ("hue", NULL, NULL, 0, 360, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
|
||||
properties[PROP_SATURATION] =
|
||||
g_param_spec_int ("saturation", NULL, NULL, 0, 100, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
|
||||
properties[PROP_VALUE] =
|
||||
g_param_spec_int ("value", NULL, NULL, 0, 100, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
|
||||
color_properties[PROP_HUE] =
|
||||
g_param_spec_int ("hue", NULL, NULL, 0, 360, 0, G_PARAM_READABLE);
|
||||
color_properties[PROP_SATURATION] =
|
||||
g_param_spec_int ("saturation", NULL, NULL, 0, 100, 0, G_PARAM_READABLE);
|
||||
color_properties[PROP_VALUE] =
|
||||
g_param_spec_int ("value", NULL, NULL, 0, 100, 0, G_PARAM_READABLE);
|
||||
|
||||
g_object_class_install_properties (gobject_class, N_PROPS, properties);
|
||||
g_object_class_install_properties (gobject_class, N_COLOR_PROPS, color_properties);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -211,8 +285,7 @@ gtk_color_init (GtkColor *self)
|
||||
|
||||
static GtkColor *
|
||||
gtk_color_new (const char *name,
|
||||
float r, float g, float b,
|
||||
int h, int s, int v)
|
||||
float r, float g, float b)
|
||||
{
|
||||
GtkColor *result;
|
||||
GdkRGBA color = { r, g, b, 1.0 };
|
||||
@@ -220,24 +293,206 @@ gtk_color_new (const char *name,
|
||||
result = g_object_new (GTK_TYPE_COLOR,
|
||||
"name", name,
|
||||
"color", &color,
|
||||
"hue", h,
|
||||
"saturation", s,
|
||||
"value", v,
|
||||
NULL);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static GListModel *
|
||||
create_colors_model (void)
|
||||
#define N_COLORS (256 * 256 * 256)
|
||||
|
||||
#define GTK_TYPE_COLOR_LIST (gtk_color_list_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (GtkColorList, gtk_color_list, GTK, COLOR_LIST, GObject)
|
||||
|
||||
enum {
|
||||
LIST_PROP_0,
|
||||
LIST_PROP_SIZE,
|
||||
|
||||
N_LIST_PROPS
|
||||
};
|
||||
|
||||
typedef struct _GtkColorList GtkColorList;
|
||||
struct _GtkColorList
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
GtkColor **colors; /* Always N_COLORS */
|
||||
|
||||
guint size; /* How many colors we allow */
|
||||
};
|
||||
|
||||
static GType
|
||||
gtk_color_list_get_item_type (GListModel *list)
|
||||
{
|
||||
return GTK_TYPE_COLOR;
|
||||
}
|
||||
|
||||
static guint
|
||||
gtk_color_list_get_n_items (GListModel *list)
|
||||
{
|
||||
GtkColorList *self = GTK_COLOR_LIST (list);
|
||||
|
||||
return self->size;
|
||||
}
|
||||
|
||||
static guint
|
||||
position_to_color (guint position)
|
||||
{
|
||||
static guint map[] = {
|
||||
0xFF0000, 0x00FF00, 0x0000FF,
|
||||
0x7F0000, 0x007F00, 0x00007F,
|
||||
0x3F0000, 0x003F00, 0x00003F,
|
||||
0x1F0000, 0x001F00, 0x00001F,
|
||||
0x0F0000, 0x000F00, 0x00000F,
|
||||
0x070000, 0x000700, 0x000007,
|
||||
0x030000, 0x000300, 0x000003,
|
||||
0x010000, 0x000100, 0x000001
|
||||
};
|
||||
guint result, i;
|
||||
|
||||
result = 0;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (map); i++)
|
||||
{
|
||||
if (position & (1 << i))
|
||||
result ^= map[i];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static gpointer
|
||||
gtk_color_list_get_item (GListModel *list,
|
||||
guint position)
|
||||
{
|
||||
GtkColorList *self = GTK_COLOR_LIST (list);
|
||||
|
||||
if (position >= self->size)
|
||||
return NULL;
|
||||
|
||||
position = position_to_color (position);
|
||||
|
||||
if (self->colors[position] == NULL)
|
||||
{
|
||||
guint red, green, blue;
|
||||
|
||||
red = (position >> 16) & 0xFF;
|
||||
green = (position >> 8) & 0xFF;
|
||||
blue = position & 0xFF;
|
||||
|
||||
self->colors[position] = gtk_color_new ("", red / 255., green / 255., blue / 255.);
|
||||
}
|
||||
|
||||
return g_object_ref (self->colors[position]);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_color_list_model_init (GListModelInterface *iface)
|
||||
{
|
||||
iface->get_item_type = gtk_color_list_get_item_type;
|
||||
iface->get_n_items = gtk_color_list_get_n_items;
|
||||
iface->get_item = gtk_color_list_get_item;
|
||||
}
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GtkColorList, gtk_color_list, G_TYPE_OBJECT,
|
||||
G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL,
|
||||
gtk_color_list_model_init))
|
||||
|
||||
static GParamSpec *list_properties[N_LIST_PROPS] = { NULL, };
|
||||
|
||||
static void
|
||||
gtk_color_list_get_property (GObject *object,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkColorList *self = GTK_COLOR_LIST (object);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case LIST_PROP_SIZE:
|
||||
g_value_set_uint (value, self->size);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_color_list_set_size (GtkColorList *self,
|
||||
guint size)
|
||||
{
|
||||
guint old_size = self->size;
|
||||
|
||||
self->size = size;
|
||||
if (self->size > old_size)
|
||||
g_list_model_items_changed (G_LIST_MODEL (self), old_size, 0, self->size - old_size);
|
||||
else if (old_size > self->size)
|
||||
g_list_model_items_changed (G_LIST_MODEL (self), self->size, old_size - self->size, 0);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), list_properties[LIST_PROP_SIZE]);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_color_list_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkColorList *self = GTK_COLOR_LIST (object);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case LIST_PROP_SIZE:
|
||||
gtk_color_list_set_size (self, g_value_get_uint (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_color_list_dispose (GObject *object)
|
||||
{
|
||||
GtkColorList *self = GTK_COLOR_LIST (object);
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < N_COLORS; i++)
|
||||
{
|
||||
g_clear_object (&self->colors[i]);
|
||||
}
|
||||
g_free (self->colors);
|
||||
|
||||
G_OBJECT_CLASS (gtk_color_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_color_list_class_init (GtkColorListClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
gobject_class->get_property = gtk_color_list_get_property;
|
||||
gobject_class->set_property = gtk_color_list_set_property;
|
||||
gobject_class->dispose = gtk_color_list_dispose;
|
||||
|
||||
list_properties[LIST_PROP_SIZE] =
|
||||
g_param_spec_uint ("size", NULL, NULL, 0, N_COLORS, 0, G_PARAM_READWRITE);
|
||||
|
||||
g_object_class_install_properties (gobject_class, N_LIST_PROPS, list_properties);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_color_list_init (GtkColorList *self)
|
||||
{
|
||||
GListStore *result;
|
||||
GtkColor *color;
|
||||
GBytes *data;
|
||||
char **lines;
|
||||
guint i;
|
||||
|
||||
result = g_list_store_new (GTK_TYPE_COLOR);
|
||||
self->colors = g_new0 (GtkColor *, N_COLORS);
|
||||
|
||||
data = g_resources_lookup_data ("/listview_colors/color.names.txt", 0, NULL);
|
||||
lines = g_strsplit (g_bytes_get_data (data, NULL), "\n", 0);
|
||||
|
||||
@@ -246,7 +501,7 @@ create_colors_model (void)
|
||||
const char *name;
|
||||
char **fields;
|
||||
int red, green, blue;
|
||||
int h, s, v;
|
||||
guint pos;
|
||||
|
||||
if (lines[i][0] == '#' || lines[i][0] == '\0')
|
||||
continue;
|
||||
@@ -256,21 +511,24 @@ create_colors_model (void)
|
||||
red = atoi (fields[3]);
|
||||
green = atoi (fields[4]);
|
||||
blue = atoi (fields[5]);
|
||||
h = atoi (fields[9]);
|
||||
s = atoi (fields[10]);
|
||||
v = atoi (fields[11]);
|
||||
|
||||
color = gtk_color_new (name, red / 255., green / 255., blue / 255., h, s, v);
|
||||
g_list_store_append (result, color);
|
||||
g_object_unref (color);
|
||||
|
||||
pos = ((red & 0xFF) << 16) | ((green & 0xFF) << 8) | blue;
|
||||
if (self->colors[pos] == NULL)
|
||||
self->colors[pos] = gtk_color_new (name, red / 255., green / 255., blue / 255.);
|
||||
|
||||
g_strfreev (fields);
|
||||
}
|
||||
g_strfreev (lines);
|
||||
|
||||
g_bytes_unref (data);
|
||||
}
|
||||
|
||||
return G_LIST_MODEL (result);
|
||||
static GListModel *
|
||||
gtk_color_list_new (guint size)
|
||||
{
|
||||
return g_object_new (GTK_TYPE_COLOR_LIST,
|
||||
"size", size,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static char *
|
||||
@@ -281,9 +539,9 @@ get_rgb_markup (gpointer this,
|
||||
return NULL;
|
||||
|
||||
return g_strdup_printf ("<b>R:</b> %d <b>G:</b> %d <b>B:</b> %d",
|
||||
(int)(color->color->red * 255),
|
||||
(int)(color->color->green * 255),
|
||||
(int)(color->color->blue * 255));
|
||||
(int)(color->color.red * 255),
|
||||
(int)(color->color.green * 255),
|
||||
(int)(color->color.blue * 255));
|
||||
}
|
||||
|
||||
static char *
|
||||
@@ -310,6 +568,7 @@ setup_simple_listitem_cb (GtkListItemFactory *factory,
|
||||
color_expression = gtk_property_expression_new (GTK_TYPE_LIST_ITEM, expression, "item");
|
||||
|
||||
picture = gtk_picture_new ();
|
||||
gtk_widget_set_size_request (picture, 32, 32);
|
||||
gtk_expression_bind (color_expression, picture, "paintable", NULL);
|
||||
|
||||
gtk_list_item_set_child (list_item, picture);
|
||||
@@ -319,7 +578,7 @@ static void
|
||||
setup_listitem_cb (GtkListItemFactory *factory,
|
||||
GtkListItem *list_item)
|
||||
{
|
||||
GtkWidget *box, *picture, *name_label, *rgb_label, *hsv_label;;
|
||||
GtkWidget *box, *picture, *name_label, *rgb_label, *hsv_label;
|
||||
GtkExpression *color_expression, *expression;
|
||||
GtkExpression *params[1];
|
||||
|
||||
@@ -381,27 +640,141 @@ get_title (gpointer item)
|
||||
return g_strdup ((char *)g_object_get_data (G_OBJECT (item), "title"));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
set_item (GBinding *binding,
|
||||
const GValue *from,
|
||||
GValue *to,
|
||||
gpointer data)
|
||||
GtkWidget *
|
||||
create_color_grid (void)
|
||||
{
|
||||
GObject *source = g_binding_get_source (binding);
|
||||
GListModel *model;
|
||||
guint selected;
|
||||
gpointer item;
|
||||
GtkWidget *gridview;
|
||||
GtkListItemFactory *factory;
|
||||
GListModel *model, *selection;
|
||||
|
||||
selected = g_value_get_uint (from);
|
||||
gridview = gtk_grid_view_new ();
|
||||
gtk_scrollable_set_hscroll_policy (GTK_SCROLLABLE (gridview), GTK_SCROLL_NATURAL);
|
||||
gtk_scrollable_set_vscroll_policy (GTK_SCROLLABLE (gridview), GTK_SCROLL_NATURAL);
|
||||
|
||||
model = gtk_drop_down_get_model (GTK_DROP_DOWN (source));
|
||||
item = g_list_model_get_item (model, selected);
|
||||
factory = gtk_signal_list_item_factory_new ();
|
||||
g_signal_connect (factory, "setup", G_CALLBACK (setup_simple_listitem_cb), NULL);
|
||||
gtk_grid_view_set_factory (GTK_GRID_VIEW (gridview), factory);
|
||||
g_object_unref (factory);
|
||||
|
||||
g_value_set_object (to, item);
|
||||
gtk_grid_view_set_max_columns (GTK_GRID_VIEW (gridview), 24);
|
||||
gtk_grid_view_set_enable_rubberband (GTK_GRID_VIEW (gridview), TRUE);
|
||||
|
||||
g_clear_object (&item);
|
||||
model = G_LIST_MODEL (gtk_sort_list_model_new (gtk_color_list_new (0), NULL));
|
||||
|
||||
return TRUE;
|
||||
selection = G_LIST_MODEL (gtk_multi_selection_new (model));
|
||||
gtk_grid_view_set_model (GTK_GRID_VIEW (gridview), selection);
|
||||
g_object_unref (selection);
|
||||
g_object_unref (model);
|
||||
|
||||
return gridview;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
add_colors (GtkWidget *widget,
|
||||
GdkFrameClock *clock,
|
||||
gpointer data)
|
||||
{
|
||||
GtkColorList *colors = data;
|
||||
guint limit;
|
||||
|
||||
limit = GPOINTER_TO_UINT (g_object_get_data (data, "limit"));
|
||||
gtk_color_list_set_size (colors, MIN (limit, colors->size + MAX (1, limit / 4096)));
|
||||
|
||||
if (colors->size >= limit)
|
||||
return G_SOURCE_REMOVE;
|
||||
else
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
static void
|
||||
refill (GtkWidget *button,
|
||||
GtkColorList *colors)
|
||||
{
|
||||
gtk_color_list_set_size (colors, 0);
|
||||
gtk_widget_add_tick_callback (button, add_colors, g_object_ref (colors), g_object_unref);
|
||||
}
|
||||
|
||||
static void
|
||||
limit_changed_cb (GtkDropDown *dropdown,
|
||||
GParamSpec *pspec,
|
||||
GtkColorList *colors)
|
||||
{
|
||||
guint new_limit, old_limit;
|
||||
|
||||
old_limit = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (colors), "limit"));
|
||||
new_limit = 1 << (3 * (gtk_drop_down_get_selected (dropdown) + 1));
|
||||
|
||||
g_object_set_data (G_OBJECT (colors), "limit", GUINT_TO_POINTER (new_limit));
|
||||
|
||||
if (old_limit == colors->size)
|
||||
gtk_color_list_set_size (colors, new_limit);
|
||||
}
|
||||
|
||||
static void
|
||||
limit_changed_cb2 (GtkDropDown *dropdown,
|
||||
GParamSpec *pspec,
|
||||
GtkLabel *label)
|
||||
{
|
||||
char *string;
|
||||
int len;
|
||||
guint limit;
|
||||
|
||||
limit = 1 << (3 * (gtk_drop_down_get_selected (dropdown) + 1));
|
||||
|
||||
string = g_strdup_printf ("%'u", limit);
|
||||
len = g_utf8_strlen (string, -1);
|
||||
g_free (string);
|
||||
|
||||
gtk_label_set_width_chars (label, len + 2); /* for " /" */
|
||||
}
|
||||
|
||||
static void
|
||||
items_changed_cb (GListModel *model,
|
||||
guint position,
|
||||
guint removed,
|
||||
guint added,
|
||||
GtkWidget *label)
|
||||
{
|
||||
guint n = g_list_model_get_n_items (model);
|
||||
char *text;
|
||||
|
||||
text = g_strdup_printf ("%'u /", n);
|
||||
gtk_label_set_label (GTK_LABEL (label), text);
|
||||
g_free (text);
|
||||
}
|
||||
|
||||
static void
|
||||
setup_number_item (GtkSignalListItemFactory *factory,
|
||||
GtkListItem *item)
|
||||
{
|
||||
GtkWidget *label;
|
||||
PangoAttrList *attrs;
|
||||
|
||||
label = gtk_label_new ("");
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 1);
|
||||
|
||||
attrs = pango_attr_list_new ();
|
||||
pango_attr_list_insert (attrs, pango_attr_font_features_new ("tnum"));
|
||||
gtk_label_set_attributes (GTK_LABEL (label), attrs);
|
||||
pango_attr_list_unref (attrs);
|
||||
|
||||
gtk_list_item_set_child (item, label);
|
||||
}
|
||||
|
||||
static void
|
||||
bind_number_item (GtkSignalListItemFactory *factory,
|
||||
GtkListItem *item)
|
||||
{
|
||||
GtkWidget *label;
|
||||
guint limit;
|
||||
char *string;
|
||||
|
||||
label = gtk_list_item_get_child (item);
|
||||
|
||||
limit = 1 << (3 * (gtk_list_item_get_position (item) + 1));
|
||||
string = g_strdup_printf ("%'u", limit);
|
||||
gtk_label_set_label (GTK_LABEL (label), string);
|
||||
g_free (string);
|
||||
}
|
||||
|
||||
static GtkWidget *window = NULL;
|
||||
@@ -415,11 +788,15 @@ do_listview_colors (GtkWidget *do_widget)
|
||||
GtkListItemFactory *factory;
|
||||
GListStore *factories;
|
||||
GListModel *model;
|
||||
GtkNoSelection *selection;
|
||||
GtkSorter *sorter;
|
||||
GtkSorter *multi_sorter;
|
||||
GListStore *sorters;
|
||||
GtkExpression *expression;
|
||||
GtkWidget *button;
|
||||
GtkWidget *label;
|
||||
PangoAttrList *attrs;
|
||||
char *string;
|
||||
guint len;
|
||||
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Colors");
|
||||
@@ -432,23 +809,62 @@ do_listview_colors (GtkWidget *do_widget)
|
||||
gtk_widget_get_display (do_widget));
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer*)&window);
|
||||
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
sw = gtk_scrolled_window_new ();
|
||||
gtk_window_set_child (GTK_WINDOW (window), sw);
|
||||
|
||||
gridview = gtk_grid_view_new ();
|
||||
gtk_scrollable_set_hscroll_policy (GTK_SCROLLABLE (gridview), GTK_SCROLL_NATURAL);
|
||||
gtk_scrollable_set_vscroll_policy (GTK_SCROLLABLE (gridview), GTK_SCROLL_NATURAL);
|
||||
|
||||
gtk_grid_view_set_max_columns (GTK_GRID_VIEW (gridview), 24);
|
||||
|
||||
model = G_LIST_MODEL (gtk_sort_list_model_new (create_colors_model (), NULL));
|
||||
selection = gtk_no_selection_new (model);
|
||||
gtk_grid_view_set_model (GTK_GRID_VIEW (gridview), G_LIST_MODEL (selection));
|
||||
gridview = create_color_grid ();
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), gridview);
|
||||
g_object_unref (selection);
|
||||
model = gtk_grid_view_get_model (GTK_GRID_VIEW (gridview));
|
||||
g_object_get (model, "model", &model, NULL);
|
||||
|
||||
button = gtk_button_new_with_mnemonic ("_Refill");
|
||||
g_signal_connect (button, "clicked",
|
||||
G_CALLBACK (refill),
|
||||
gtk_sort_list_model_get_model (GTK_SORT_LIST_MODEL (model)));
|
||||
|
||||
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), button);
|
||||
|
||||
label = gtk_label_new ("0 /");
|
||||
attrs = pango_attr_list_new ();
|
||||
pango_attr_list_insert (attrs, pango_attr_font_features_new ("tnum"));
|
||||
gtk_label_set_attributes (GTK_LABEL (label), attrs);
|
||||
pango_attr_list_unref (attrs);
|
||||
string = g_strdup_printf ("%'u", 4096);
|
||||
len = g_utf8_strlen (string, -1);
|
||||
g_free (string);
|
||||
gtk_label_set_width_chars (GTK_LABEL (label), len + 2);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 1);
|
||||
|
||||
g_signal_connect (gtk_grid_view_get_model (GTK_GRID_VIEW (gridview)),
|
||||
"items-changed", G_CALLBACK (items_changed_cb), label);
|
||||
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), label);
|
||||
|
||||
dropdown = gtk_drop_down_new ();
|
||||
gtk_drop_down_set_from_strings (GTK_DROP_DOWN (dropdown), (const char *[]) { "8", "64", "512", "4096", "32768", "262144", "2097152", "16777216", NULL });
|
||||
g_signal_connect (dropdown, "notify::selected",
|
||||
G_CALLBACK (limit_changed_cb),
|
||||
gtk_sort_list_model_get_model (GTK_SORT_LIST_MODEL (model)));
|
||||
g_signal_connect (dropdown, "notify::selected",
|
||||
G_CALLBACK (limit_changed_cb2),
|
||||
label);
|
||||
factory = gtk_signal_list_item_factory_new ();
|
||||
g_signal_connect (factory, "setup", G_CALLBACK (setup_number_item), NULL);
|
||||
g_signal_connect (factory, "bind", G_CALLBACK (bind_number_item), NULL);
|
||||
gtk_drop_down_set_factory (GTK_DROP_DOWN (dropdown), factory);
|
||||
g_object_unref (factory);
|
||||
gtk_drop_down_set_selected (GTK_DROP_DOWN (dropdown), 3); /* 4096 */
|
||||
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), dropdown);
|
||||
|
||||
sorters = g_list_store_new (GTK_TYPE_SORTER);
|
||||
|
||||
/* An empty multisorter doesn't do any sorting and the sortmodel is
|
||||
* smart enough to know that.
|
||||
*/
|
||||
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"));
|
||||
set_title (sorter, "Name");
|
||||
g_list_store_append (sorters, sorter);
|
||||
@@ -519,11 +935,7 @@ do_listview_colors (GtkWidget *do_widget)
|
||||
gtk_drop_down_set_model (GTK_DROP_DOWN (dropdown), G_LIST_MODEL (sorters));
|
||||
g_object_unref (sorters);
|
||||
|
||||
g_object_bind_property_full (dropdown, "selected",
|
||||
model, "sorter",
|
||||
G_BINDING_SYNC_CREATE,
|
||||
set_item, NULL,
|
||||
NULL, NULL);
|
||||
g_object_bind_property (dropdown, "selected-item", model, "sorter", G_BINDING_SYNC_CREATE);
|
||||
|
||||
factories = g_list_store_new (GTK_TYPE_LIST_ITEM_FACTORY);
|
||||
|
||||
@@ -554,12 +966,7 @@ do_listview_colors (GtkWidget *do_widget)
|
||||
gtk_drop_down_set_model (GTK_DROP_DOWN (dropdown), G_LIST_MODEL (factories));
|
||||
g_object_unref (factories);
|
||||
|
||||
g_object_bind_property_full (dropdown, "selected",
|
||||
gridview, "factory",
|
||||
G_BINDING_SYNC_CREATE,
|
||||
set_item, NULL,
|
||||
NULL, NULL);
|
||||
|
||||
g_object_bind_property (dropdown, "selected-item", gridview, "factory", G_BINDING_SYNC_CREATE);
|
||||
g_object_unref (model);
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ struct _FileBrowserView
|
||||
|
||||
GtkListItemFactory *factory;
|
||||
char *icon_name;
|
||||
char *title;
|
||||
GtkOrientation orientation;
|
||||
};
|
||||
|
||||
@@ -25,6 +26,7 @@ enum {
|
||||
PROP_0,
|
||||
PROP_FACTORY,
|
||||
PROP_ICON_NAME,
|
||||
PROP_TITLE,
|
||||
PROP_ORIENTATION,
|
||||
|
||||
N_PROPS
|
||||
@@ -54,6 +56,10 @@ file_browser_view_get_property (GObject *object,
|
||||
g_value_set_string (value, self->icon_name);
|
||||
break;
|
||||
|
||||
case PROP_TITLE:
|
||||
g_value_set_string (value, self->title);
|
||||
break;
|
||||
|
||||
case PROP_ORIENTATION:
|
||||
g_value_set_enum (value, self->orientation);
|
||||
break;
|
||||
@@ -83,6 +89,11 @@ file_browser_view_set_property (GObject *object,
|
||||
self->icon_name = g_value_dup_string (value);
|
||||
break;
|
||||
|
||||
case PROP_TITLE:
|
||||
g_free (self->title);
|
||||
self->title = g_value_dup_string (value);
|
||||
break;
|
||||
|
||||
case PROP_ORIENTATION:
|
||||
self->orientation = g_value_get_enum (value);
|
||||
break;
|
||||
@@ -100,6 +111,7 @@ file_browser_view_finalize (GObject *object)
|
||||
|
||||
g_object_unref (self->factory);
|
||||
g_free (self->icon_name);
|
||||
g_free (self->title);
|
||||
|
||||
G_OBJECT_CLASS (file_browser_view_parent_class)->dispose (object);
|
||||
}
|
||||
@@ -125,6 +137,12 @@ file_browser_view_class_init (FileBrowserViewClass *klass)
|
||||
"icon to display for selecting this view",
|
||||
NULL,
|
||||
G_PARAM_READWRITE);
|
||||
properties[PROP_TITLE] =
|
||||
g_param_spec_string ("title",
|
||||
"title",
|
||||
"title to display for selecting this view",
|
||||
NULL,
|
||||
G_PARAM_READWRITE);
|
||||
properties[PROP_ORIENTATION] =
|
||||
g_param_spec_enum ("orientation",
|
||||
"orientation",
|
||||
@@ -224,6 +242,14 @@ do_listview_filebrowser (GtkWidget *do_widget)
|
||||
GtkDirectoryList *dirlist;
|
||||
GFile *file;
|
||||
char *cwd;
|
||||
GtkCssProvider *provider;
|
||||
|
||||
provider = gtk_css_provider_new ();
|
||||
gtk_css_provider_load_from_resource (provider, "/listview_filebrowser/listview_filebrowser.css");
|
||||
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
|
||||
GTK_STYLE_PROVIDER (provider),
|
||||
800);
|
||||
g_object_unref (provider);
|
||||
|
||||
builder = gtk_builder_new_from_resource ("/listview_filebrowser/listview_filebrowser.ui");
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
|
||||
|
||||
11
demos/gtk-demo/listview_filebrowser.css
Normal file
11
demos/gtk-demo/listview_filebrowser.css
Normal file
@@ -0,0 +1,11 @@
|
||||
list.viewswitcher {
|
||||
border: 1px solid gray;
|
||||
}
|
||||
|
||||
list.viewswitcher > row {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
list.viewswitcher row:selected {
|
||||
background: gray;
|
||||
}
|
||||
@@ -39,12 +39,14 @@
|
||||
</object>
|
||||
</property>
|
||||
<property name="icon-name">view-list-symbolic</property>
|
||||
<property name="title" translatable="yes">List</property>
|
||||
<property name="orientation">horizontal</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="FileBrowserView">
|
||||
<property name="icon-name">view-grid-symbolic</property>
|
||||
<property name="title" translatable="yes">Grid</property>
|
||||
<property name="factory">
|
||||
<object class="GtkBuilderListItemFactory">
|
||||
<property name="bytes"><![CDATA[
|
||||
@@ -92,6 +94,7 @@
|
||||
<child>
|
||||
<object class="FileBrowserView">
|
||||
<property name="icon-name">view-paged-symbolic</property>
|
||||
<property name="title" translatable="yes">Paged</property>
|
||||
<property name="factory">
|
||||
<object class="GtkBuilderListItemFactory">
|
||||
<property name="bytes"><![CDATA[
|
||||
@@ -174,7 +177,7 @@
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="icon-name">go-up</property>
|
||||
<property name="icon-name">go-up-symbolic</property>
|
||||
<signal name="clicked" handler="filebrowser_up_clicked_cb" object="dirlist" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
@@ -184,6 +187,7 @@
|
||||
<property name="orientation">horizontal</property>
|
||||
<style>
|
||||
<class name="linked"/>
|
||||
<class name="viewswitcher"/>
|
||||
</style>
|
||||
<property name="model">
|
||||
<object class="GtkSingleSelection" id="selected-view">
|
||||
@@ -203,6 +207,11 @@
|
||||
<lookup name="item">GtkListItem</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
<binding name="tooltip-text">
|
||||
<lookup type="FileBrowserView" name="title">
|
||||
<lookup name="item">GtkListItem</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
</object>
|
||||
</property>
|
||||
</template>
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Create an object that wraps GSettingsSchemaKey because that's a boxed type */
|
||||
typedef struct _SettingsKey SettingsKey;
|
||||
struct _SettingsKey
|
||||
@@ -25,6 +27,8 @@ enum {
|
||||
PROP_SUMMARY,
|
||||
PROP_DESCRIPTION,
|
||||
PROP_VALUE,
|
||||
PROP_TYPE,
|
||||
PROP_DEFAULT_VALUE,
|
||||
|
||||
N_PROPS
|
||||
};
|
||||
@@ -65,6 +69,21 @@ settings_key_get_property (GObject *object,
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_TYPE:
|
||||
{
|
||||
const GVariantType *type = g_settings_schema_key_get_value_type (self->key);
|
||||
g_value_set_string (value, g_variant_type_peek_string (type));
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_DEFAULT_VALUE:
|
||||
{
|
||||
GVariant *variant = g_settings_schema_key_get_default_value (self->key);
|
||||
g_value_take_string (value, g_variant_print (variant, FALSE));
|
||||
g_variant_unref (variant);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
@@ -98,6 +117,10 @@ settings_key_class_init (SettingsKeyClass *klass)
|
||||
g_param_spec_string ("summary", NULL, NULL, NULL, G_PARAM_READABLE);
|
||||
properties[PROP_VALUE] =
|
||||
g_param_spec_string ("value", NULL, NULL, NULL, G_PARAM_READABLE);
|
||||
properties[PROP_TYPE] =
|
||||
g_param_spec_string ("type", NULL, NULL, NULL, G_PARAM_READABLE);
|
||||
properties[PROP_DEFAULT_VALUE] =
|
||||
g_param_spec_string ("default-value", NULL, NULL, NULL, G_PARAM_READABLE);
|
||||
|
||||
g_object_class_install_properties (gobject_class, N_PROPS, properties);
|
||||
}
|
||||
@@ -119,6 +142,53 @@ settings_key_new (GSettings *settings,
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
item_value_changed (GtkEditableLabel *label,
|
||||
GParamSpec *pspec,
|
||||
GtkListItem *item)
|
||||
{
|
||||
SettingsKey *self;
|
||||
const char *text;
|
||||
const GVariantType *type;
|
||||
GVariant *variant;
|
||||
GError *error = NULL;
|
||||
const char *name;
|
||||
char *value;
|
||||
|
||||
text = gtk_editable_get_text (GTK_EDITABLE (label));
|
||||
|
||||
g_object_get (item, "item", &self, NULL);
|
||||
g_object_unref (self);
|
||||
|
||||
type = g_settings_schema_key_get_value_type (self->key);
|
||||
name = g_settings_schema_key_get_name (self->key);
|
||||
|
||||
variant = g_variant_parse (type, text, NULL, NULL, &error);
|
||||
if (!variant)
|
||||
{
|
||||
g_warning ("%s", error->message);
|
||||
g_clear_error (&error);
|
||||
goto revert;
|
||||
}
|
||||
|
||||
if (!g_settings_schema_key_range_check (self->key, variant))
|
||||
{
|
||||
g_warning ("Not a valid value for %s", name);
|
||||
goto revert;
|
||||
}
|
||||
|
||||
g_settings_set_value (self->settings, name, variant);
|
||||
g_variant_unref (variant);
|
||||
return;
|
||||
|
||||
revert:
|
||||
gtk_widget_error_bell (GTK_WIDGET (label));
|
||||
|
||||
g_object_get (self, "value", &value, NULL);
|
||||
gtk_editable_set_text (GTK_EDITABLE (label), value);
|
||||
g_free (value);
|
||||
}
|
||||
|
||||
static int
|
||||
strvcmp (gconstpointer p1,
|
||||
gconstpointer p2)
|
||||
@@ -144,6 +214,7 @@ transform_settings_to_keys (GBinding *binding,
|
||||
GtkSortListModel *sort_model;
|
||||
GtkFilterListModel *filter_model;
|
||||
GtkFilter *filter;
|
||||
GtkNoSelection *selection_model;
|
||||
GtkExpression *expression;
|
||||
char **keys;
|
||||
guint i;
|
||||
@@ -186,7 +257,10 @@ transform_settings_to_keys (GBinding *binding,
|
||||
|
||||
g_object_unref (filter);
|
||||
|
||||
g_value_take_object (to_value, filter_model);
|
||||
selection_model = gtk_no_selection_new (G_LIST_MODEL (filter_model));
|
||||
g_object_unref (filter_model);
|
||||
|
||||
g_value_take_object (to_value, selection_model);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -279,7 +353,13 @@ do_listview_settings (GtkWidget *do_widget)
|
||||
GtkBuilderScope *scope;
|
||||
GtkBuilder *builder;
|
||||
GtkColumnViewColumn *name_column;
|
||||
GtkColumnViewColumn *type_column;
|
||||
GtkColumnViewColumn *default_column;
|
||||
GtkColumnViewColumn *summary_column;
|
||||
GtkColumnViewColumn *description_column;
|
||||
GtkSorter *sorter;
|
||||
GActionGroup *actions;
|
||||
GAction *action;
|
||||
|
||||
g_type_ensure (SETTINGS_TYPE_KEY);
|
||||
|
||||
@@ -287,6 +367,7 @@ do_listview_settings (GtkWidget *do_widget)
|
||||
gtk_builder_cscope_add_callback_symbol (GTK_BUILDER_CSCOPE (scope), "search_enabled", (GCallback)search_enabled);
|
||||
gtk_builder_cscope_add_callback_symbol (GTK_BUILDER_CSCOPE (scope), "search_changed", (GCallback)search_changed);
|
||||
gtk_builder_cscope_add_callback_symbol (GTK_BUILDER_CSCOPE (scope), "stop_search", (GCallback)stop_search);
|
||||
gtk_builder_cscope_add_callback_symbol (GTK_BUILDER_CSCOPE (scope), "item_value_changed", (GCallback)item_value_changed);
|
||||
|
||||
builder = gtk_builder_new ();
|
||||
gtk_builder_set_scope (builder, scope);
|
||||
@@ -299,6 +380,32 @@ do_listview_settings (GtkWidget *do_widget)
|
||||
|
||||
listview = GTK_WIDGET (gtk_builder_get_object (builder, "listview"));
|
||||
columnview = GTK_WIDGET (gtk_builder_get_object (builder, "columnview"));
|
||||
type_column = GTK_COLUMN_VIEW_COLUMN (gtk_builder_get_object (builder, "type_column"));
|
||||
default_column = GTK_COLUMN_VIEW_COLUMN (gtk_builder_get_object (builder, "default_column"));
|
||||
summary_column = GTK_COLUMN_VIEW_COLUMN (gtk_builder_get_object (builder, "summary_column"));
|
||||
description_column = GTK_COLUMN_VIEW_COLUMN (gtk_builder_get_object (builder, "description_column"));
|
||||
|
||||
actions = G_ACTION_GROUP (g_simple_action_group_new ());
|
||||
|
||||
action = G_ACTION (g_property_action_new ("show-type", type_column, "visible"));
|
||||
g_action_map_add_action (G_ACTION_MAP (actions), action);
|
||||
g_object_unref (action);
|
||||
|
||||
action = G_ACTION (g_property_action_new ("show-default", default_column, "visible"));
|
||||
g_action_map_add_action (G_ACTION_MAP (actions), action);
|
||||
g_object_unref (action);
|
||||
|
||||
action = G_ACTION (g_property_action_new ("show-summary", summary_column, "visible"));
|
||||
g_action_map_add_action (G_ACTION_MAP (actions), action);
|
||||
g_object_unref (action);
|
||||
|
||||
action = G_ACTION (g_property_action_new ("show-description", description_column, "visible"));
|
||||
g_action_map_add_action (G_ACTION_MAP (actions), action);
|
||||
g_object_unref (action);
|
||||
|
||||
gtk_widget_insert_action_group (columnview, "columnview", actions);
|
||||
g_object_unref (actions);
|
||||
|
||||
model = create_settings_model (NULL, NULL);
|
||||
treemodel = gtk_tree_list_model_new (FALSE,
|
||||
model,
|
||||
@@ -322,6 +429,8 @@ do_listview_settings (GtkWidget *do_widget)
|
||||
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);
|
||||
|
||||
g_object_unref (builder);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
|
||||
@@ -77,6 +77,7 @@
|
||||
<child>
|
||||
<object class="GtkColumnViewColumn" id="name_column">
|
||||
<property name="title">Name</property>
|
||||
<property name="header-menu">header_menu</property>
|
||||
<property name="factory">
|
||||
<object class="GtkBuilderListItemFactory">
|
||||
<property name="bytes"><![CDATA[
|
||||
@@ -103,6 +104,36 @@
|
||||
<child>
|
||||
<object class="GtkColumnViewColumn">
|
||||
<property name="title">Value</property>
|
||||
<property name="resizable">1</property>
|
||||
<property name="header-menu">header_menu</property>
|
||||
<property name="factory">
|
||||
<object class="GtkBuilderListItemFactory">
|
||||
<property name="bytes"><![CDATA[
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="GtkListItem">
|
||||
<property name="child">
|
||||
<object class="GtkEditableLabel">
|
||||
<binding name="text">
|
||||
<lookup name="value" type="SettingsKey">
|
||||
<lookup name="item">GtkListItem</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
<signal name="notify::label" handler="item_value_changed"/>
|
||||
</object>
|
||||
</property>
|
||||
</template>
|
||||
</interface>
|
||||
]]></property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkColumnViewColumn" id="type_column">
|
||||
<property name="title">Type</property>
|
||||
<property name="resizable">1</property>
|
||||
<property name="header-menu">header_menu</property>
|
||||
<property name="factory">
|
||||
<object class="GtkBuilderListItemFactory">
|
||||
<property name="bytes"><![CDATA[
|
||||
@@ -113,7 +144,98 @@
|
||||
<object class="GtkLabel">
|
||||
<property name="xalign">0</property>
|
||||
<binding name="label">
|
||||
<lookup name="value" type="SettingsKey">
|
||||
<lookup name="type" type="SettingsKey">
|
||||
<lookup name="item">GtkListItem</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
</object>
|
||||
</property>
|
||||
</template>
|
||||
</interface>
|
||||
]]></property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkColumnViewColumn" id="default_column">
|
||||
<property name="title">Default</property>
|
||||
<property name="resizable">1</property>
|
||||
<property name="expand">1</property>
|
||||
<property name="header-menu">header_menu</property>
|
||||
<property name="factory">
|
||||
<object class="GtkBuilderListItemFactory">
|
||||
<property name="bytes"><![CDATA[
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="GtkListItem">
|
||||
<property name="child">
|
||||
<object class="GtkLabel">
|
||||
<property name="xalign">0</property>
|
||||
<binding name="label">
|
||||
<lookup name="default-value" type="SettingsKey">
|
||||
<lookup name="item">GtkListItem</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
</object>
|
||||
</property>
|
||||
</template>
|
||||
</interface>
|
||||
]]></property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkColumnViewColumn" id="summary_column">
|
||||
<property name="title">Summary</property>
|
||||
<property name="resizable">1</property>
|
||||
<property name="visible">0</property>
|
||||
<property name="expand">1</property>
|
||||
<property name="header-menu">header_menu</property>
|
||||
<property name="factory">
|
||||
<object class="GtkBuilderListItemFactory">
|
||||
<property name="bytes"><![CDATA[
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="GtkListItem">
|
||||
<property name="child">
|
||||
<object class="GtkLabel">
|
||||
<property name="xalign">0</property>
|
||||
<property name="wrap">1</property>
|
||||
<binding name="label">
|
||||
<lookup name="summary" type="SettingsKey">
|
||||
<lookup name="item">GtkListItem</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
</object>
|
||||
</property>
|
||||
</template>
|
||||
</interface>
|
||||
]]></property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkColumnViewColumn" id="description_column">
|
||||
<property name="title">Description</property>
|
||||
<property name="resizable">1</property>
|
||||
<property name="visible">0</property>
|
||||
<property name="expand">1</property>
|
||||
<property name="header-menu">header_menu</property>
|
||||
<property name="factory">
|
||||
<object class="GtkBuilderListItemFactory">
|
||||
<property name="bytes"><![CDATA[
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="GtkListItem">
|
||||
<property name="child">
|
||||
<object class="GtkLabel">
|
||||
<property name="xalign">0</property>
|
||||
<property name="wrap">1</property>
|
||||
<binding name="label">
|
||||
<lookup name="description" type="SettingsKey">
|
||||
<lookup name="item">GtkListItem</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
@@ -135,4 +257,24 @@
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<menu id="header_menu">
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">Type</attribute>
|
||||
<attribute name="action">columnview.show-type</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">Default value</attribute>
|
||||
<attribute name="action">columnview.show-default</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">Summary</attribute>
|
||||
<attribute name="action">columnview.show-summary</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">Description</attribute>
|
||||
<attribute name="action">columnview.show-description</attribute>
|
||||
</item>
|
||||
</section>
|
||||
</menu>
|
||||
</interface>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
* A GtkNoSelectionModel is used to make sure no item in the list can be
|
||||
* selected. All other interactions with the items is still possible.
|
||||
*
|
||||
* The dataset used here has 70000 items.
|
||||
* The dataset used here has 70 000 items.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
@@ -70,7 +70,6 @@ gtk_weather_info_new (GDateTime *timestamp,
|
||||
{
|
||||
result->temperature = copy_from->temperature;
|
||||
result->weather_type = copy_from->weather_type;
|
||||
g_object_unref (copy_from);
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -78,13 +77,13 @@ gtk_weather_info_new (GDateTime *timestamp,
|
||||
|
||||
static GDateTime *
|
||||
parse_timestamp (const char *string,
|
||||
GTimeZone *timezone)
|
||||
GTimeZone *_tz)
|
||||
{
|
||||
char *with_seconds;
|
||||
GDateTime *result;
|
||||
|
||||
with_seconds = g_strconcat (string, ":00", NULL);
|
||||
result = g_date_time_new_from_iso8601 (with_seconds, timezone);
|
||||
result = g_date_time_new_from_iso8601 (with_seconds, _tz);
|
||||
g_free (with_seconds);
|
||||
|
||||
return result;
|
||||
@@ -161,6 +160,7 @@ create_weather_model (void)
|
||||
timestamp = g_date_time_new (utc, 2011, 1, 1, 0, 0, 0);
|
||||
info = gtk_weather_info_new (timestamp, NULL);
|
||||
g_list_store_append (store, info);
|
||||
g_object_unref (info);
|
||||
|
||||
for (i = 0; lines[i] != NULL && *lines[i]; i++)
|
||||
{
|
||||
@@ -176,6 +176,7 @@ create_weather_model (void)
|
||||
timestamp = new_timestamp;
|
||||
info = gtk_weather_info_new (timestamp, info);
|
||||
g_list_store_append (store, info);
|
||||
g_object_unref (info);
|
||||
}
|
||||
|
||||
info->temperature = parse_temperature (fields[1], info->temperature);
|
||||
@@ -184,6 +185,7 @@ create_weather_model (void)
|
||||
g_strfreev (fields);
|
||||
}
|
||||
|
||||
g_date_time_unref (timestamp);
|
||||
g_strfreev (lines);
|
||||
g_bytes_unref (data);
|
||||
g_time_zone_unref (utc);
|
||||
@@ -275,13 +277,33 @@ bind_widget (GtkListItem *list_item,
|
||||
|
||||
static GtkWidget *window = NULL;
|
||||
|
||||
GtkWidget *
|
||||
create_weather_view (void)
|
||||
{
|
||||
GtkWidget *listview;
|
||||
GListModel *model, *selection;
|
||||
|
||||
listview = gtk_list_view_new_with_factory (
|
||||
gtk_functions_list_item_factory_new (setup_widget,
|
||||
bind_widget,
|
||||
NULL, NULL));
|
||||
gtk_orientable_set_orientation (GTK_ORIENTABLE (listview), GTK_ORIENTATION_HORIZONTAL);
|
||||
gtk_list_view_set_show_separators (GTK_LIST_VIEW (listview), TRUE);
|
||||
model = create_weather_model ();
|
||||
selection = G_LIST_MODEL (gtk_no_selection_new (model));
|
||||
gtk_list_view_set_model (GTK_LIST_VIEW (listview), selection);
|
||||
g_object_unref (selection);
|
||||
g_object_unref (model);
|
||||
|
||||
return listview;
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_listview_weather (GtkWidget *do_widget)
|
||||
{
|
||||
if (window == NULL)
|
||||
{
|
||||
GtkWidget *listview, *sw;;
|
||||
GListModel *model, *selection;
|
||||
GtkWidget *listview, *sw;
|
||||
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
|
||||
@@ -291,21 +313,9 @@ do_listview_weather (GtkWidget *do_widget)
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Weather");
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *) &window);
|
||||
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
sw = gtk_scrolled_window_new ();
|
||||
gtk_window_set_child (GTK_WINDOW (window), sw);
|
||||
|
||||
listview = gtk_list_view_new_with_factory (
|
||||
gtk_functions_list_item_factory_new (setup_widget,
|
||||
bind_widget,
|
||||
NULL, NULL));
|
||||
gtk_orientable_set_orientation (GTK_ORIENTABLE (listview), GTK_ORIENTATION_HORIZONTAL);
|
||||
gtk_list_view_set_show_separators (GTK_LIST_VIEW (listview), TRUE);
|
||||
model = create_weather_model ();
|
||||
selection = G_LIST_MODEL (gtk_no_selection_new (model));
|
||||
gtk_list_view_set_model (GTK_LIST_VIEW (listview), selection);
|
||||
g_object_unref (selection);
|
||||
g_object_unref (model);
|
||||
|
||||
listview = create_weather_view ();
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), listview);
|
||||
}
|
||||
|
||||
|
||||
241
demos/gtk-demo/listview_words.c
Normal file
241
demos/gtk-demo/listview_words.c
Normal file
@@ -0,0 +1,241 @@
|
||||
/* Lists/Words
|
||||
*
|
||||
* This demo shows filtering a long list - of words.
|
||||
*
|
||||
* You should have the file `/usr/share/dict/words` installed for
|
||||
* this demo to work.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
static GtkWidget *window = NULL;
|
||||
static GtkWidget *progress;
|
||||
|
||||
const char *factory_text =
|
||||
"<?xml version='1.0' encoding='UTF-8'?>\n"
|
||||
"<interface>\n"
|
||||
" <template class='GtkListItem'>\n"
|
||||
" <property name='child'>\n"
|
||||
" <object class='GtkLabel'>\n"
|
||||
" <property name='ellipsize'>end</property>\n"
|
||||
" <property name='xalign'>0</property>\n"
|
||||
" <binding name='label'>\n"
|
||||
" <lookup name='string' type='GtkStringObject'>\n"
|
||||
" <lookup name='item'>GtkListItem</lookup>\n"
|
||||
" </lookup>\n"
|
||||
" </binding>\n"
|
||||
" </object>\n"
|
||||
" </property>\n"
|
||||
" </template>\n"
|
||||
"</interface>\n";
|
||||
|
||||
static void
|
||||
update_title_cb (GtkFilterListModel *model)
|
||||
{
|
||||
guint total;
|
||||
char *title;
|
||||
guint pending;
|
||||
|
||||
total = g_list_model_get_n_items (gtk_filter_list_model_get_model (model));
|
||||
pending = gtk_filter_list_model_get_pending (model);
|
||||
|
||||
title = g_strdup_printf ("%u lines", g_list_model_get_n_items (G_LIST_MODEL (model)));
|
||||
|
||||
gtk_widget_set_visible (progress, pending != 0);
|
||||
gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progress), (total - pending) / (double) total);
|
||||
gtk_window_set_title (GTK_WINDOW (window), title);
|
||||
g_free (title);
|
||||
}
|
||||
|
||||
static void
|
||||
read_lines_cb (GObject *object,
|
||||
GAsyncResult *result,
|
||||
gpointer data)
|
||||
{
|
||||
GBufferedInputStream *stream = G_BUFFERED_INPUT_STREAM (object);
|
||||
GtkStringList *stringlist = data;
|
||||
GError *error = NULL;
|
||||
gsize size;
|
||||
GPtrArray *lines;
|
||||
gssize n_filled;
|
||||
const char *buffer, *newline;
|
||||
|
||||
n_filled = g_buffered_input_stream_fill_finish (stream, result, &error);
|
||||
if (n_filled < 0)
|
||||
{
|
||||
g_print ("Could not read data: %s\n", error->message);
|
||||
g_clear_error (&error);
|
||||
return;
|
||||
}
|
||||
|
||||
buffer = g_buffered_input_stream_peek_buffer (stream, &size);
|
||||
|
||||
if (n_filled == 0)
|
||||
{
|
||||
if (size)
|
||||
gtk_string_list_take (stringlist, g_utf8_make_valid (buffer, size));
|
||||
return;
|
||||
}
|
||||
|
||||
lines = NULL;
|
||||
while ((newline = memchr (buffer, '\n', size)))
|
||||
{
|
||||
if (newline > buffer)
|
||||
{
|
||||
if (lines == NULL)
|
||||
lines = g_ptr_array_new_with_free_func (g_free);
|
||||
g_ptr_array_add (lines, g_utf8_make_valid (buffer, newline - buffer));
|
||||
}
|
||||
if (g_input_stream_skip (G_INPUT_STREAM (stream), newline - buffer + 1, NULL, &error) < 0)
|
||||
{
|
||||
g_clear_error (&error);
|
||||
break;
|
||||
}
|
||||
buffer = g_buffered_input_stream_peek_buffer (stream, &size);
|
||||
}
|
||||
if (lines == NULL)
|
||||
{
|
||||
g_buffered_input_stream_set_buffer_size (stream, g_buffered_input_stream_get_buffer_size (stream) + 4096);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_ptr_array_add (lines, NULL);
|
||||
gtk_string_list_splice (stringlist, g_list_model_get_n_items (G_LIST_MODEL (stringlist)), 0, (const char **) lines->pdata);
|
||||
g_ptr_array_free (lines, TRUE);
|
||||
}
|
||||
|
||||
g_buffered_input_stream_fill_async (stream, -1, G_PRIORITY_HIGH_IDLE, NULL, read_lines_cb, data);
|
||||
}
|
||||
|
||||
static void
|
||||
file_is_open_cb (GObject *file,
|
||||
GAsyncResult *result,
|
||||
gpointer data)
|
||||
{
|
||||
GError *error = NULL;
|
||||
GFileInputStream *file_stream;
|
||||
GBufferedInputStream *stream;
|
||||
|
||||
file_stream = g_file_read_finish (G_FILE (file), result, &error);
|
||||
if (file_stream == NULL)
|
||||
{
|
||||
g_print ("Could not open file: %s\n", error->message);
|
||||
g_error_free (error);
|
||||
return;
|
||||
}
|
||||
|
||||
stream = G_BUFFERED_INPUT_STREAM (g_buffered_input_stream_new (G_INPUT_STREAM (file_stream)));
|
||||
g_buffered_input_stream_fill_async (stream, -1, G_PRIORITY_HIGH_IDLE, NULL, read_lines_cb, data);
|
||||
g_object_unref (stream);
|
||||
}
|
||||
|
||||
static void
|
||||
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);
|
||||
}
|
||||
|
||||
static void
|
||||
file_selected_cb (GtkWidget *button,
|
||||
GtkStringList *stringlist)
|
||||
{
|
||||
GFile *file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (button));
|
||||
|
||||
if (file)
|
||||
{
|
||||
load_file (stringlist, file);
|
||||
g_object_unref (file);
|
||||
}
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_listview_words (GtkWidget *do_widget)
|
||||
{
|
||||
if (window == NULL)
|
||||
{
|
||||
GtkWidget *header, *listview, *sw, *vbox, *search_entry, *open_button, *overlay;
|
||||
GtkFilterListModel *filter_model;
|
||||
GtkNoSelection *selection;
|
||||
GtkStringList *stringlist;
|
||||
GtkFilter *filter;
|
||||
GtkExpression *expression;
|
||||
GFile *file;
|
||||
|
||||
file = g_file_new_for_path ("/usr/share/dict/words");
|
||||
if (g_file_query_exists (file, NULL))
|
||||
{
|
||||
stringlist = gtk_string_list_new (NULL);
|
||||
load_file (stringlist, file);
|
||||
}
|
||||
else
|
||||
{
|
||||
char **words;
|
||||
words = g_strsplit ("lorem ipsum dolor sit amet consectetur adipisci elit sed eiusmod tempor incidunt labore et dolore magna aliqua ut enim ad minim veniam quis nostrud exercitation ullamco laboris nisi ut aliquid ex ea commodi consequat", " ", -1);
|
||||
stringlist = gtk_string_list_new ((const char **) words);
|
||||
g_strfreev (words);
|
||||
}
|
||||
|
||||
filter = gtk_string_filter_new ();
|
||||
expression = gtk_property_expression_new (GTK_TYPE_STRING_OBJECT, NULL, "string");
|
||||
gtk_string_filter_set_expression (GTK_STRING_FILTER (filter), expression);
|
||||
gtk_expression_unref (expression);
|
||||
filter_model = gtk_filter_list_model_new (G_LIST_MODEL (stringlist), filter);
|
||||
gtk_filter_list_model_set_incremental (filter_model, TRUE);
|
||||
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 400, 600);
|
||||
|
||||
header = gtk_header_bar_new ();
|
||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), TRUE);
|
||||
open_button = gtk_file_chooser_button_new ("_Open", GTK_FILE_CHOOSER_ACTION_OPEN);
|
||||
g_signal_connect (open_button, "file-set", G_CALLBACK (file_selected_cb), stringlist);
|
||||
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), open_button);
|
||||
gtk_window_set_titlebar (GTK_WINDOW (window), header);
|
||||
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer*)&window);
|
||||
|
||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_window_set_child (GTK_WINDOW (window), vbox);
|
||||
|
||||
search_entry = gtk_search_entry_new ();
|
||||
g_object_bind_property (search_entry, "text", filter, "search", 0);
|
||||
gtk_box_append (GTK_BOX (vbox), search_entry);
|
||||
|
||||
overlay = gtk_overlay_new ();
|
||||
gtk_box_append (GTK_BOX (vbox), overlay);
|
||||
|
||||
progress = gtk_progress_bar_new ();
|
||||
gtk_widget_set_halign (progress, GTK_ALIGN_FILL);
|
||||
gtk_widget_set_valign (progress, GTK_ALIGN_START);
|
||||
gtk_widget_set_hexpand (progress, TRUE);
|
||||
gtk_overlay_add_overlay (GTK_OVERLAY (overlay), progress);
|
||||
|
||||
sw = gtk_scrolled_window_new ();
|
||||
gtk_overlay_set_child (GTK_OVERLAY (overlay), sw);
|
||||
|
||||
listview = gtk_list_view_new_with_factory (
|
||||
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);
|
||||
selection = gtk_no_selection_new (G_LIST_MODEL (filter_model));
|
||||
gtk_list_view_set_model (GTK_LIST_VIEW (listview), G_LIST_MODEL (selection));
|
||||
g_object_unref (selection);
|
||||
|
||||
g_signal_connect (filter_model, "items-changed", G_CALLBACK (update_title_cb), progress);
|
||||
g_signal_connect (filter_model, "notify::pending", G_CALLBACK (update_title_cb), progress);
|
||||
update_title_cb (filter_model);
|
||||
|
||||
g_object_unref (filter_model);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
|
||||
return window;
|
||||
}
|
||||
@@ -8,7 +8,6 @@
|
||||
#include <gtk/gtk.h>
|
||||
#include <glib/gstdio.h>
|
||||
|
||||
#include "award.h"
|
||||
#include "demos.h"
|
||||
|
||||
static GtkWidget *info_view;
|
||||
@@ -134,7 +133,7 @@ gtk_demo_run (GtkDemo *self,
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
activate_about (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
@@ -213,7 +212,6 @@ activate_inspector (GSimpleAction *action,
|
||||
gpointer user_data)
|
||||
{
|
||||
gtk_window_set_interactive_debugging (TRUE);
|
||||
award ("demo-inspector");
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -601,10 +599,10 @@ display_image (const char *resource)
|
||||
{
|
||||
GtkWidget *sw, *image;
|
||||
|
||||
image = gtk_image_new_from_resource (resource);
|
||||
image = gtk_picture_new_for_resource (resource);
|
||||
gtk_widget_set_halign (image, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign (image, GTK_ALIGN_CENTER);
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
sw = gtk_scrolled_window_new ();
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), image);
|
||||
|
||||
return sw;
|
||||
@@ -644,7 +642,7 @@ display_text (const char *resource)
|
||||
|
||||
g_bytes_unref (bytes);
|
||||
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
sw = gtk_scrolled_window_new ();
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
@@ -1037,23 +1035,18 @@ activate (GApplication *app)
|
||||
listview = GTK_WIDGET (gtk_builder_get_object (builder, "listview"));
|
||||
g_signal_connect (listview, "activate", G_CALLBACK (activate_cb), window);
|
||||
|
||||
load_file (gtk_demos[0].name, gtk_demos[0].filename);
|
||||
|
||||
listmodel = create_demo_model ();
|
||||
treemodel = gtk_tree_list_model_new (FALSE,
|
||||
G_LIST_MODEL (listmodel),
|
||||
FALSE,
|
||||
TRUE,
|
||||
get_child_model,
|
||||
NULL,
|
||||
NULL);
|
||||
selection = gtk_single_selection_new (G_LIST_MODEL (treemodel));
|
||||
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), G_LIST_MODEL (selection));
|
||||
|
||||
award ("demo-start");
|
||||
|
||||
gtk_widget_show (GTK_WIDGET (window));
|
||||
selection_cb (selection, NULL, NULL);
|
||||
|
||||
g_object_unref (builder);
|
||||
}
|
||||
@@ -1113,11 +1106,11 @@ command_line (GApplication *app,
|
||||
return 0;
|
||||
}
|
||||
|
||||
window = gtk_application_get_windows (GTK_APPLICATION (app))->data;
|
||||
|
||||
if (name == NULL)
|
||||
goto out;
|
||||
|
||||
window = gtk_application_get_windows (GTK_APPLICATION (app))->data;
|
||||
|
||||
d = gtk_demos;
|
||||
|
||||
while (d->title)
|
||||
@@ -1147,7 +1140,11 @@ out:
|
||||
|
||||
gtk_window_set_transient_for (GTK_WINDOW (demo), GTK_WINDOW (window));
|
||||
gtk_window_set_modal (GTK_WINDOW (demo), TRUE);
|
||||
|
||||
g_signal_connect_swapped (G_OBJECT (demo), "destroy", G_CALLBACK (g_application_quit), app);
|
||||
}
|
||||
else
|
||||
gtk_widget_show (GTK_WIDGET (window));
|
||||
|
||||
if (autoquit)
|
||||
g_timeout_add_seconds (1, auto_quit, app);
|
||||
@@ -1158,7 +1155,7 @@ out:
|
||||
static void
|
||||
print_version (void)
|
||||
{
|
||||
g_print ("gtk3-demo %d.%d.%d\n",
|
||||
g_print ("gtk4-demo %d.%d.%d\n",
|
||||
gtk_get_major_version (),
|
||||
gtk_get_minor_version (),
|
||||
gtk_get_micro_version ());
|
||||
@@ -1200,16 +1197,6 @@ main (int argc, char **argv)
|
||||
};
|
||||
int i;
|
||||
|
||||
/* Most code in gtk-demo is intended to be exemplary, but not
|
||||
* these few lines, which are just a hack so gtk-demo will work
|
||||
* in the GTK tree without installing it.
|
||||
*/
|
||||
if (g_file_test ("../../modules/input/immodules.cache", G_FILE_TEST_EXISTS))
|
||||
{
|
||||
g_setenv ("GTK_IM_MODULE_FILE", "../../modules/input/immodules.cache", TRUE);
|
||||
}
|
||||
/* -- End of hack -- */
|
||||
|
||||
app = gtk_application_new ("org.gtk.Demo4", G_APPLICATION_NON_UNIQUE|G_APPLICATION_HANDLES_COMMAND_LINE);
|
||||
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (app),
|
||||
|
||||
@@ -16,15 +16,6 @@
|
||||
</item>
|
||||
</section>
|
||||
</menu>
|
||||
<object class="GtkTreeStore" id="treestore">
|
||||
<columns>
|
||||
<column type="gchararray"/>
|
||||
<column type="gchararray"/>
|
||||
<column type="gchararray"/>
|
||||
<column type="gpointer"/>
|
||||
<column type="gint"/>
|
||||
</columns>
|
||||
</object>
|
||||
<object class="GtkApplicationWindow" id="window">
|
||||
<style>
|
||||
<class name="devel"/>
|
||||
|
||||
@@ -81,7 +81,7 @@ do_markup (GtkWidget *do_widget)
|
||||
gtk_text_view_set_left_margin (GTK_TEXT_VIEW (view), 10);
|
||||
gtk_text_view_set_right_margin (GTK_TEXT_VIEW (view), 10);
|
||||
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
sw = gtk_scrolled_window_new ();
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
@@ -94,7 +94,7 @@ do_markup (GtkWidget *do_widget)
|
||||
gtk_text_view_set_left_margin (GTK_TEXT_VIEW (view2), 10);
|
||||
gtk_text_view_set_right_margin (GTK_TEXT_VIEW (view2), 10);
|
||||
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
sw = gtk_scrolled_window_new ();
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
|
||||
@@ -5,7 +5,7 @@ Text <span color="gray">c<span color="green">o</span>l<span color="tomato">o</sp
|
||||
|
||||
Colorful <span underline="low" underline-color="blue"><span underline="double" underline-color="red">under</span>lines</span> and <span background="pink"><span underline="error">mo</span><span underline="error" underline-color="green">re</span></span>
|
||||
|
||||
Colorful <span strikethrough="true" strikethrough-color="magenta">strikethroughs</span>
|
||||
Colorful <span strikethrough="true" strikethrough-color="magenta">strikethroughs</span> and <span overline="single" overline_color="green">overlines</span>
|
||||
|
||||
Superscripts and subscripts: 𝜀<span rise="-6000" size="x-small" font_desc="italic">0</span> = 𝜔<span rise="8000" size="smaller">𝜔<span rise="14000" size="smaller">𝜔<span rise="20000">.<span rise="23000">.<span rise="26000">.</span></span></span></span></span>
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
demos = files([
|
||||
'application_demo.c',
|
||||
'assistant.c',
|
||||
'awardview.c',
|
||||
'builder.c',
|
||||
'clipboard.c',
|
||||
'combobox.c',
|
||||
@@ -19,6 +18,7 @@ demos = files([
|
||||
'cursors.c',
|
||||
'dialog.c',
|
||||
'drawingarea.c',
|
||||
'dropdown.c',
|
||||
'dnd.c',
|
||||
'editable_cells.c',
|
||||
'entry_completion.c',
|
||||
@@ -49,6 +49,7 @@ demos = files([
|
||||
'listview_minesweeper.c',
|
||||
'listview_settings.c',
|
||||
'listview_weather.c',
|
||||
'listview_words.c',
|
||||
'markup.c',
|
||||
'modelbutton.c',
|
||||
'overlay.c',
|
||||
@@ -92,7 +93,6 @@ demos = files([
|
||||
gtkdemo_deps = [ libgtk_dep, ]
|
||||
|
||||
extra_demo_sources = files(['main.c',
|
||||
'award.c',
|
||||
'gtkfishbowl.c',
|
||||
'fontplane.c',
|
||||
'gtkgears.c',
|
||||
|
||||
@@ -259,7 +259,7 @@
|
||||
259|GTK+ and friends|GTKtoolkit|#java bindings version 4.0.16 released: http://article.gmane.org/gmane.comp.gnome.bindings.java/1796 #gtk|1276885917|0||0|0
|
||||
260|GTK+ and friends|GTKtoolkit|RT @cwiiis: MxIconTheme and MxIcon respect system's icon theme (and changes) now in #mx master :) Made possible by @thosw's XSettings work|1276883019|0||0|0
|
||||
261|GTK+ and friends|GTKtoolkit|#javascript mailing list just created. Discuss its usage in GObject libraries: GTK+, Glib ... http://ur1.ca/08lwz by @jwendell #gtk|1276842639|0||0|0
|
||||
262|GTK+ and friends|GTKtoolkit|Note fot Win32 users: XP theming is back in 2.90.3 . Please test. #gtk|1276829697|0||0|0
|
||||
262|GTK+ and friends|GTKtoolkit|Note for Win32 users: XP theming is back in 2.90.3 . Please test. #gtk|1276829697|0||0|0
|
||||
263|GTK+ and friends|GTKtoolkit|GTK+ 2.90.3 (unstable) released: http://mail.gnome.org/archives/gtk-devel-list/2010-June/msg00137.html #gtk|1276829633|0||0|0
|
||||
264|GTK+ and friends|GTKtoolkit|GLib 2.25.9 (unstable) released: http://ur1.ca/08hrl WARNING: API changes in GDBus, GSettings and GApplication #gtk|1276829581|0||0|0
|
||||
265|scaroo|scaroo|RT @scaroo: #SeedKit does RGBA window with css shadows and stuff : http://dl.dropbox.com/u/5746554/seedkit-does-rgba.png|1276734086|0|GTKtoolkit|0|1
|
||||
|
||||
@@ -40,7 +40,7 @@ do_overlay2 (GtkWidget *do_widget)
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Decorative Overlay");
|
||||
|
||||
overlay = gtk_overlay_new ();
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
sw = gtk_scrolled_window_new ();
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "award.h"
|
||||
|
||||
static GtkWidget *entry;
|
||||
static GtkWidget *entry2;
|
||||
@@ -27,17 +26,12 @@ update_button (GObject *object,
|
||||
|
||||
gtk_widget_set_sensitive (button,
|
||||
text[0] != '\0' && g_str_equal (text, text2));
|
||||
|
||||
if (g_str_equal (text, text2) &&
|
||||
g_ascii_strcasecmp (text, "12345") == 0)
|
||||
award ("password-best");
|
||||
}
|
||||
|
||||
static void
|
||||
button_pressed (GtkButton *widget,
|
||||
GtkWidget *window)
|
||||
{
|
||||
award ("password-correct");
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Sliding puzzle
|
||||
/* Sliding Puzzle
|
||||
*
|
||||
* This demo demonstrates how to use gestures and paintables to create a
|
||||
* small sliding puzzle game.
|
||||
@@ -11,8 +11,6 @@
|
||||
#include "puzzlepiece.h"
|
||||
#include "paintable.h"
|
||||
|
||||
/* Give out awards */
|
||||
#include "award.h"
|
||||
|
||||
static GtkWidget *window = NULL;
|
||||
static GtkWidget *frame = NULL;
|
||||
@@ -159,14 +157,6 @@ check_solved (GtkWidget *grid)
|
||||
picture = gtk_grid_get_child_at (GTK_GRID (grid), pos_x, pos_y);
|
||||
gtk_picture_set_paintable (GTK_PICTURE (picture), piece);
|
||||
|
||||
/* Hand out a bunch of awards
|
||||
*/
|
||||
award ("puzzle-solve");
|
||||
if ((gdk_paintable_get_flags (piece) & GDK_PAINTABLE_STATIC_CONTENTS) == 0)
|
||||
award ("puzzle-solve-animated");
|
||||
if (height * width > 20)
|
||||
award ("puzzle-solve-large");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -251,6 +241,8 @@ puzzle_button_pressed (GtkGestureClick *gesture,
|
||||
{
|
||||
gtk_widget_error_bell (grid);
|
||||
}
|
||||
|
||||
check_solved (grid);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -291,6 +283,8 @@ start_puzzle (GdkPaintable *paintable)
|
||||
/* Add shortcuts so people can use the arrow
|
||||
* keys to move the puzzle */
|
||||
controller = gtk_shortcut_controller_new ();
|
||||
gtk_shortcut_controller_set_scope (GTK_SHORTCUT_CONTROLLER (controller),
|
||||
GTK_SHORTCUT_SCOPE_GLOBAL);
|
||||
add_move_binding (GTK_SHORTCUT_CONTROLLER (controller),
|
||||
GDK_KEY_Left, GDK_KEY_KP_Left,
|
||||
-1, 0);
|
||||
@@ -351,11 +345,16 @@ reshuffle (void)
|
||||
{
|
||||
GtkWidget *grid;
|
||||
|
||||
grid = gtk_aspect_frame_get_child (GTK_ASPECT_FRAME (frame));
|
||||
if (solved)
|
||||
start_puzzle (puzzle);
|
||||
{
|
||||
start_puzzle (puzzle);
|
||||
grid = gtk_aspect_frame_get_child (GTK_ASPECT_FRAME (frame));
|
||||
}
|
||||
else
|
||||
shuffle_puzzle (grid);
|
||||
{
|
||||
grid = gtk_aspect_frame_get_child (GTK_ASPECT_FRAME (frame));
|
||||
shuffle_puzzle (grid);
|
||||
}
|
||||
gtk_widget_grab_focus (grid);
|
||||
}
|
||||
|
||||
@@ -407,9 +406,6 @@ widget_destroyed (gpointer data,
|
||||
{
|
||||
if (data)
|
||||
*(gpointer *) data = NULL;
|
||||
|
||||
if (!solved)
|
||||
award ("puzzle-give-up");
|
||||
}
|
||||
|
||||
|
||||
@@ -447,7 +443,7 @@ do_sliding_puzzle (GtkWidget *do_widget)
|
||||
gtk_media_stream_set_muted (media, TRUE);
|
||||
gtk_media_stream_play (media);
|
||||
add_choice (choices, GDK_PAINTABLE (media));
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
sw = gtk_scrolled_window_new ();
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), choices);
|
||||
gtk_grid_attach (GTK_GRID (tweaks), sw, 0, 0, 2, 1);
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ do_tabs (GtkWidget *do_widget)
|
||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
|
||||
gtk_text_buffer_set_text (buffer, "one\ttwo\tthree\nfour\tfive\tsix\nseven\teight\tnine", -1);
|
||||
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
sw = gtk_scrolled_window_new ();
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
|
||||
@@ -57,7 +57,6 @@ do_tagged_entry (GtkWidget *do_widget)
|
||||
static GtkWidget *window = NULL;
|
||||
GtkWidget *box;
|
||||
GtkWidget *box2;
|
||||
GtkWidget *header;
|
||||
GtkWidget *entry;
|
||||
GtkWidget *button;
|
||||
|
||||
@@ -66,12 +65,9 @@ do_tagged_entry (GtkWidget *do_widget)
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
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);
|
||||
gtk_window_set_title (GTK_WINDOW (window), "A tagged entry");
|
||||
gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
|
||||
gtk_window_set_deletable (GTK_WINDOW (window), FALSE);
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Tagged Entry");
|
||||
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
|
||||
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
|
||||
@@ -95,13 +91,6 @@ do_tagged_entry (GtkWidget *do_widget)
|
||||
button = gtk_check_button_new_with_mnemonic ("_Spinner");
|
||||
g_signal_connect (button, "toggled", G_CALLBACK (toggle_spinner), entry);
|
||||
gtk_box_append (GTK_BOX (box2), button);
|
||||
|
||||
button = gtk_button_new_with_mnemonic ("_Done");
|
||||
gtk_widget_add_css_class (button, "suggested-action");
|
||||
g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_window_destroy), window);
|
||||
gtk_header_bar_pack_end (GTK_HEADER_BAR (header), button);
|
||||
|
||||
gtk_window_set_default_widget (GTK_WINDOW (window), button);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
|
||||
@@ -156,7 +156,7 @@ create_text_view (GtkWidget *hbox,
|
||||
GtkWidget *textview;
|
||||
guint timeout;
|
||||
|
||||
swindow = gtk_scrolled_window_new (NULL, NULL);
|
||||
swindow = gtk_scrolled_window_new ();
|
||||
gtk_box_append (GTK_BOX (hbox), swindow);
|
||||
textview = gtk_text_view_new ();
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (swindow), textview);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* GtkTextBuffer. You can enable or disable undo support using
|
||||
* gtk_text_buffer_set_enable_undo().
|
||||
*
|
||||
* Use Primary+Z to undo and Primary+Shift+Z or Primary+Y to
|
||||
* Use Control+z to undo and Control+Shift+z or Control+y to
|
||||
* redo previously undone operations.
|
||||
*/
|
||||
|
||||
@@ -29,7 +29,7 @@ do_textundo (GtkWidget *do_widget)
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 450, 450);
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
|
||||
gtk_window_set_title (GTK_WINDOW (window), "TextView Undo");
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Undo and Redo");
|
||||
|
||||
view = gtk_text_view_new ();
|
||||
gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view), GTK_WRAP_WORD);
|
||||
@@ -46,7 +46,7 @@ do_textundo (GtkWidget *do_widget)
|
||||
-1);
|
||||
gtk_text_buffer_end_irreversible_action (buffer);
|
||||
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
sw = gtk_scrolled_window_new ();
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
|
||||
@@ -494,7 +494,7 @@ do_textview (GtkWidget *do_widget)
|
||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view1));
|
||||
view2 = gtk_text_view_new_with_buffer (buffer);
|
||||
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
sw = gtk_scrolled_window_new ();
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
@@ -504,7 +504,7 @@ do_textview (GtkWidget *do_widget)
|
||||
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), view1);
|
||||
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
sw = gtk_scrolled_window_new ();
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
@@ -590,7 +590,7 @@ easter_egg_callback (GtkWidget *button,
|
||||
g_object_unref (buffer);
|
||||
|
||||
window = gtk_window_new ();
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
sw = gtk_scrolled_window_new ();
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
|
||||
@@ -92,12 +92,11 @@ static Theme themes[] = {
|
||||
static int theme;
|
||||
|
||||
static gboolean
|
||||
change_theme (GtkWidget *widget,
|
||||
change_theme (GtkWidget *widget,
|
||||
GdkFrameClock *frame_clock,
|
||||
gpointer data)
|
||||
gpointer data)
|
||||
{
|
||||
GtkBuilder *builder = data;
|
||||
GtkWidget *label;
|
||||
GtkWidget *label = data;
|
||||
Theme next = themes[theme++ % G_N_ELEMENTS (themes)];
|
||||
char *name;
|
||||
|
||||
@@ -110,7 +109,6 @@ change_theme (GtkWidget *widget,
|
||||
gtk_window_set_title (GTK_WINDOW (widget), name);
|
||||
g_free (name);
|
||||
|
||||
label = GTK_WIDGET (gtk_builder_get_object (builder, "fps"));
|
||||
if (frame_clock)
|
||||
{
|
||||
char *fps;
|
||||
@@ -127,10 +125,10 @@ change_theme (GtkWidget *widget,
|
||||
|
||||
static void
|
||||
clicked (GtkGestureClick *gesture,
|
||||
int n_press,
|
||||
double x,
|
||||
double y,
|
||||
gpointer data)
|
||||
int n_press,
|
||||
double x,
|
||||
double y,
|
||||
gpointer data)
|
||||
{
|
||||
GtkWidget *window;
|
||||
GdkEvent *event;
|
||||
@@ -165,6 +163,29 @@ clicked (GtkGestureClick *gesture,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
toggle_cycle (GObject *button,
|
||||
GParamSpec *pspec,
|
||||
gpointer data)
|
||||
{
|
||||
gboolean active;
|
||||
GtkWidget *window;
|
||||
|
||||
g_object_get (button, "active", &active, NULL);
|
||||
|
||||
window = gtk_widget_get_ancestor (GTK_WIDGET (button), GTK_TYPE_WINDOW);
|
||||
|
||||
if (active && !tick_cb)
|
||||
{
|
||||
tick_cb = gtk_widget_add_tick_callback (window, change_theme, data, NULL);
|
||||
}
|
||||
else if (!active && tick_cb)
|
||||
{
|
||||
gtk_widget_remove_tick_callback (window, tick_cb);
|
||||
tick_cb = 0;
|
||||
}
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_themes (GtkWidget *do_widget)
|
||||
{
|
||||
@@ -174,6 +195,8 @@ do_themes (GtkWidget *do_widget)
|
||||
{
|
||||
GtkBuilder *builder;
|
||||
GtkWidget *header;
|
||||
GtkWidget *button;
|
||||
GtkWidget *label;
|
||||
GtkGesture *gesture;
|
||||
|
||||
builder = gtk_builder_new_from_resource ("/themes/themes.ui");
|
||||
@@ -183,11 +206,17 @@ do_themes (GtkWidget *do_widget)
|
||||
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), builder);
|
||||
g_signal_connect (gesture, "pressed", G_CALLBACK (clicked), label);
|
||||
gtk_widget_add_controller (header, GTK_EVENT_CONTROLLER (gesture));
|
||||
|
||||
button = GTK_WIDGET (gtk_builder_get_object (builder, "toggle"));
|
||||
g_signal_connect (button, "notify::active", G_CALLBACK (toggle_cycle), label);
|
||||
gtk_widget_realize (window);
|
||||
|
||||
g_object_unref (builder);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
|
||||
@@ -5,6 +5,11 @@
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="header">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child type="start">
|
||||
<object class="GtkToggleButton" id="toggle">
|
||||
<property name="label">Cycle</property>
|
||||
</object>
|
||||
</child>
|
||||
<child type="end">
|
||||
<object class="GtkLabel" id="fps"/>
|
||||
</child>
|
||||
|
||||
@@ -84,7 +84,7 @@ static TreeItem may[] =
|
||||
static TreeItem june[] =
|
||||
{
|
||||
{ "June Fathers' Day", FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, NULL },
|
||||
{ "Juneteenth (Liberation of Slaves)", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL },
|
||||
{ "Juneteenth (Liberation Day)", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL },
|
||||
{ "Flag Day", FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, NULL },
|
||||
{ NULL }
|
||||
};
|
||||
@@ -406,7 +406,7 @@ do_tree_store (GtkWidget *do_widget)
|
||||
gtk_box_append (GTK_BOX (vbox),
|
||||
gtk_label_new ("Jonathan's Holiday Card Planning Sheet"));
|
||||
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
sw = gtk_scrolled_window_new ();
|
||||
gtk_scrolled_window_set_has_frame (GTK_SCROLLED_WINDOW (sw), TRUE);
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
<gresources>
|
||||
<gresource prefix="/org/gtk/iconbrowser/gtk">
|
||||
<file preprocess="xml-stripblanks">window.ui</file>
|
||||
<file preprocess="xml-stripblanks">menus.ui</file>
|
||||
<file>icon.list</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
|
||||
156
demos/icon-browser/iconbrowsercontext.c
Normal file
156
demos/icon-browser/iconbrowsercontext.c
Normal file
@@ -0,0 +1,156 @@
|
||||
#include "iconbrowsercontext.h"
|
||||
|
||||
struct _IbContext
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
char *id;
|
||||
char *name;
|
||||
char *description;
|
||||
};
|
||||
|
||||
struct _IbContextClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_ID = 1,
|
||||
PROP_NAME,
|
||||
PROP_DESCRIPTION,
|
||||
PROP_NUM_PROPERTIES
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (IbContext, ib_context, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
ib_context_init (IbContext *context)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
ib_context_finalize (GObject *object)
|
||||
{
|
||||
IbContext *context = IB_CONTEXT (object);
|
||||
|
||||
g_free (context->id);
|
||||
g_free (context->name);
|
||||
g_free (context->description);
|
||||
|
||||
G_OBJECT_CLASS (ib_context_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
ib_context_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
IbContext *context = IB_CONTEXT (object);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_ID:
|
||||
g_free (context->id);
|
||||
context->id = g_value_dup_string (value);
|
||||
break;
|
||||
|
||||
case PROP_NAME:
|
||||
g_free (context->name);
|
||||
context->name = g_value_dup_string (value);
|
||||
break;
|
||||
|
||||
case PROP_DESCRIPTION:
|
||||
g_free (context->description);
|
||||
context->description = g_value_dup_string (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ib_context_get_property (GObject *object,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
IbContext *context = IB_CONTEXT (object);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_ID:
|
||||
g_value_set_string (value, context->id);
|
||||
break;
|
||||
|
||||
case PROP_NAME:
|
||||
g_value_set_string (value, context->name);
|
||||
break;
|
||||
|
||||
case PROP_DESCRIPTION:
|
||||
g_value_set_string (value, context->description);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ib_context_class_init (IbContextClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
GParamSpec *pspec;
|
||||
|
||||
object_class->finalize = ib_context_finalize;
|
||||
object_class->set_property = ib_context_set_property;
|
||||
object_class->get_property = ib_context_get_property;
|
||||
|
||||
pspec = g_param_spec_string ("id", "Id", "Id",
|
||||
NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||
g_object_class_install_property (object_class, PROP_ID, pspec);
|
||||
|
||||
pspec = g_param_spec_string ("name", "Name", "Name",
|
||||
NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||
g_object_class_install_property (object_class, PROP_NAME, pspec);
|
||||
|
||||
pspec = g_param_spec_string ("description", "Description", "Description",
|
||||
NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||
g_object_class_install_property (object_class, PROP_DESCRIPTION, pspec);
|
||||
}
|
||||
|
||||
IbContext *
|
||||
ib_context_new (const char *id,
|
||||
const char *name,
|
||||
const char *description)
|
||||
{
|
||||
return g_object_new (IB_TYPE_CONTEXT,
|
||||
"id", id,
|
||||
"name", name,
|
||||
"description", description,
|
||||
NULL);
|
||||
}
|
||||
|
||||
const char *
|
||||
ib_context_get_id (IbContext *context)
|
||||
{
|
||||
return context->id;
|
||||
}
|
||||
|
||||
const char *
|
||||
ib_context_get_name (IbContext *context)
|
||||
{
|
||||
return context->name;
|
||||
}
|
||||
|
||||
const char *
|
||||
ib_context_get_description (IbContext *context)
|
||||
{
|
||||
return context->description;
|
||||
}
|
||||
14
demos/icon-browser/iconbrowsercontext.h
Normal file
14
demos/icon-browser/iconbrowsercontext.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtk.h>
|
||||
|
||||
#define IB_TYPE_CONTEXT (ib_context_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (IbContext, ib_context, IB, CONTEXT, GObject)
|
||||
|
||||
IbContext *ib_context_new (const char *id,
|
||||
const char *name,
|
||||
const char *description);
|
||||
|
||||
const char *ib_context_get_id (IbContext *context);
|
||||
const char *ib_context_get_name (IbContext *context);
|
||||
const char *ib_context_get_description (IbContext *context);
|
||||
228
demos/icon-browser/iconbrowsericon.c
Normal file
228
demos/icon-browser/iconbrowsericon.c
Normal file
@@ -0,0 +1,228 @@
|
||||
#include "iconbrowsericon.h"
|
||||
|
||||
struct _IbIcon
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
gboolean use_symbolic;
|
||||
|
||||
char *regular_name;
|
||||
char *symbolic_name;
|
||||
char *description;
|
||||
char *context;
|
||||
};
|
||||
|
||||
struct _IbIconClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_NAME = 1,
|
||||
PROP_REGULAR_NAME,
|
||||
PROP_SYMBOLIC_NAME,
|
||||
PROP_USE_SYMBOLIC,
|
||||
PROP_DESCRIPTION,
|
||||
PROP_CONTEXT,
|
||||
PROP_NUM_PROPERTIES
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (IbIcon, ib_icon, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
ib_icon_init (IbIcon *icon)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
ib_icon_finalize (GObject *object)
|
||||
{
|
||||
IbIcon *icon = IB_ICON (object);
|
||||
|
||||
g_free (icon->regular_name);
|
||||
g_free (icon->symbolic_name);
|
||||
g_free (icon->description);
|
||||
g_free (icon->context);
|
||||
|
||||
G_OBJECT_CLASS (ib_icon_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
ib_icon_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
IbIcon *icon = IB_ICON (object);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_REGULAR_NAME:
|
||||
g_free (icon->regular_name);
|
||||
icon->regular_name = g_value_dup_string (value);
|
||||
if (!icon->use_symbolic)
|
||||
g_object_notify (object, "name");
|
||||
break;
|
||||
|
||||
case PROP_SYMBOLIC_NAME:
|
||||
g_free (icon->symbolic_name);
|
||||
icon->symbolic_name = g_value_dup_string (value);
|
||||
if (icon->use_symbolic)
|
||||
g_object_notify (object, "name");
|
||||
break;
|
||||
|
||||
case PROP_USE_SYMBOLIC:
|
||||
icon->use_symbolic = g_value_get_boolean (value);
|
||||
g_object_notify (object, "name");
|
||||
break;
|
||||
|
||||
case PROP_DESCRIPTION:
|
||||
g_free (icon->description);
|
||||
icon->description = g_value_dup_string (value);
|
||||
break;
|
||||
|
||||
case PROP_CONTEXT:
|
||||
g_free (icon->context);
|
||||
icon->context = g_value_dup_string (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ib_icon_get_property (GObject *object,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
IbIcon *icon = IB_ICON (object);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_NAME:
|
||||
g_value_set_string (value, ib_icon_get_name (icon));
|
||||
break;
|
||||
|
||||
case PROP_REGULAR_NAME:
|
||||
g_value_set_string (value, icon->regular_name);
|
||||
break;
|
||||
|
||||
case PROP_SYMBOLIC_NAME:
|
||||
g_value_set_string (value, icon->symbolic_name);
|
||||
break;
|
||||
|
||||
case PROP_USE_SYMBOLIC:
|
||||
g_value_set_boolean (value, icon->use_symbolic);
|
||||
break;
|
||||
|
||||
case PROP_DESCRIPTION:
|
||||
g_value_set_string (value, icon->description);
|
||||
break;
|
||||
|
||||
case PROP_CONTEXT:
|
||||
g_value_set_string (value, icon->context);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ib_icon_class_init (IbIconClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
GParamSpec *pspec;
|
||||
|
||||
object_class->finalize = ib_icon_finalize;
|
||||
object_class->set_property = ib_icon_set_property;
|
||||
object_class->get_property = ib_icon_get_property;
|
||||
|
||||
pspec = g_param_spec_string ("name", "Name", "Name",
|
||||
NULL,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
g_object_class_install_property (object_class, PROP_NAME, pspec);
|
||||
|
||||
pspec = g_param_spec_string ("regular-name", "Regular Name", "Regular Name",
|
||||
NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||
g_object_class_install_property (object_class, PROP_REGULAR_NAME, pspec);
|
||||
|
||||
pspec = g_param_spec_string ("symbolic-name", "Symbolic Name", "Symbolic Name",
|
||||
NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||
g_object_class_install_property (object_class, PROP_SYMBOLIC_NAME, pspec);
|
||||
|
||||
pspec = g_param_spec_boolean ("use-symbolic", "Use Symbolic", "Use Symbolic",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||
g_object_class_install_property (object_class, PROP_USE_SYMBOLIC, pspec);
|
||||
|
||||
pspec = g_param_spec_string ("description", "Description", "Description",
|
||||
NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||
g_object_class_install_property (object_class, PROP_DESCRIPTION, pspec);
|
||||
|
||||
pspec = g_param_spec_string ("context", "Context", "Context",
|
||||
NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||
g_object_class_install_property (object_class, PROP_CONTEXT, pspec);
|
||||
}
|
||||
|
||||
IbIcon *
|
||||
ib_icon_new (const char *regular_name,
|
||||
const char *symbolic_name,
|
||||
const char *description,
|
||||
const char *context)
|
||||
{
|
||||
return g_object_new (IB_TYPE_ICON,
|
||||
"regular-name", regular_name,
|
||||
"symbolic-name", symbolic_name,
|
||||
"description", description,
|
||||
"context", context,
|
||||
NULL);
|
||||
}
|
||||
|
||||
const char *
|
||||
ib_icon_get_name (IbIcon *icon)
|
||||
{
|
||||
if (icon->use_symbolic)
|
||||
return icon->symbolic_name;
|
||||
else
|
||||
return icon->regular_name;
|
||||
}
|
||||
|
||||
const char *
|
||||
ib_icon_get_regular_name (IbIcon *icon)
|
||||
{
|
||||
return icon->regular_name;
|
||||
}
|
||||
|
||||
const char *
|
||||
ib_icon_get_symbolic_name (IbIcon *icon)
|
||||
{
|
||||
return icon->symbolic_name;
|
||||
}
|
||||
|
||||
gboolean
|
||||
ib_icon_get_use_symbolic (IbIcon *icon)
|
||||
{
|
||||
return icon->use_symbolic;
|
||||
}
|
||||
|
||||
const char *
|
||||
ib_icon_get_description (IbIcon *icon)
|
||||
{
|
||||
return icon->description;
|
||||
}
|
||||
|
||||
const char *
|
||||
ib_icon_get_context (IbIcon *icon)
|
||||
{
|
||||
return icon->context;
|
||||
}
|
||||
|
||||
18
demos/icon-browser/iconbrowsericon.h
Normal file
18
demos/icon-browser/iconbrowsericon.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include <gtk.h>
|
||||
|
||||
#define IB_TYPE_ICON (ib_icon_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (IbIcon, ib_icon, IB, ICON, GObject)
|
||||
|
||||
IbIcon *ib_icon_new (const char *regular_name,
|
||||
const char *symbolic_name,
|
||||
const char *description,
|
||||
const char *context);
|
||||
|
||||
const char *ib_icon_get_name (IbIcon *icon);
|
||||
const char *ib_icon_get_regular_name (IbIcon *icon);
|
||||
const char *ib_icon_get_symbolic_name (IbIcon *icon);
|
||||
gboolean ib_icon_get_use_symbolic (IbIcon *icon);
|
||||
const char *ib_icon_get_description (IbIcon *icon);
|
||||
const char *ib_icon_get_context (IbIcon *icon);
|
||||
@@ -1,48 +1,22 @@
|
||||
#include <string.h>
|
||||
#include "iconbrowserapp.h"
|
||||
#include "iconbrowserwin.h"
|
||||
#include "iconstore.h"
|
||||
#include "iconbrowsericon.h"
|
||||
#include "iconbrowsercontext.h"
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
/* Drag 'n Drop */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gchar *id;
|
||||
gchar *name;
|
||||
gchar *description;
|
||||
} Context;
|
||||
|
||||
static void
|
||||
context_free (gpointer data)
|
||||
{
|
||||
Context *context = data;
|
||||
|
||||
g_free (context->id);
|
||||
g_free (context->name);
|
||||
g_free (context->description);
|
||||
g_free (context);
|
||||
}
|
||||
|
||||
struct _IconBrowserWindow
|
||||
{
|
||||
GtkApplicationWindow parent;
|
||||
GHashTable *contexts;
|
||||
|
||||
GtkWidget *context_list;
|
||||
Context *current_context;
|
||||
gboolean symbolic;
|
||||
GtkWidget *symbolic_radio;
|
||||
GtkTreeModelFilter *filter_model;
|
||||
GtkWidget *details;
|
||||
|
||||
GtkListStore *store;
|
||||
GtkCellRenderer *cell;
|
||||
GtkCellRenderer *text_cell;
|
||||
GtkWidget *search;
|
||||
GtkWidget *searchbar;
|
||||
GtkWidget *searchentry;
|
||||
GtkWidget *list;
|
||||
GListModel *icon_filter_model;
|
||||
GListStore *icon_store;
|
||||
GListStore *context_store;
|
||||
GtkFilter *name_filter;
|
||||
GtkWidget *details;
|
||||
GtkWidget *image1;
|
||||
GtkWidget *image2;
|
||||
GtkWidget *image3;
|
||||
@@ -68,87 +42,6 @@ icon_browser_window_get_icon_theme (IconBrowserWindow *win)
|
||||
return gtk_icon_theme_get_for_display (gtk_widget_get_display (GTK_WIDGET (win)));
|
||||
}
|
||||
|
||||
static void
|
||||
search_text_changed (GtkEntry *entry, IconBrowserWindow *win)
|
||||
{
|
||||
const gchar *text;
|
||||
|
||||
text = gtk_editable_get_text (GTK_EDITABLE (entry));
|
||||
|
||||
if (text[0] == '\0')
|
||||
return;
|
||||
|
||||
gtk_tree_model_filter_refilter (win->filter_model);
|
||||
}
|
||||
|
||||
static void
|
||||
set_image (GtkWidget *image, const gchar *name, gint size)
|
||||
{
|
||||
gtk_image_set_from_icon_name (GTK_IMAGE (image), name);
|
||||
gtk_image_set_pixel_size (GTK_IMAGE (image), size);
|
||||
}
|
||||
|
||||
static void
|
||||
item_activated (GtkIconView *icon_view, GtkTreePath *path, IconBrowserWindow *win)
|
||||
{
|
||||
GtkIconTheme *icon_theme = icon_browser_window_get_icon_theme (win);
|
||||
GtkTreeIter iter;
|
||||
gchar *name;
|
||||
gchar *description;
|
||||
gint column;
|
||||
|
||||
gtk_tree_model_get_iter (GTK_TREE_MODEL (win->filter_model), &iter, path);
|
||||
|
||||
if (win->symbolic)
|
||||
column = ICON_STORE_SYMBOLIC_NAME_COLUMN;
|
||||
else
|
||||
column = ICON_STORE_NAME_COLUMN;
|
||||
gtk_tree_model_get (GTK_TREE_MODEL (win->filter_model), &iter,
|
||||
column, &name,
|
||||
ICON_STORE_DESCRIPTION_COLUMN, &description,
|
||||
-1);
|
||||
|
||||
if (name == NULL || !gtk_icon_theme_has_icon (icon_theme, name))
|
||||
{
|
||||
g_free (description);
|
||||
return;
|
||||
}
|
||||
|
||||
gtk_window_set_title (GTK_WINDOW (win->details), name);
|
||||
set_image (win->image1, name, 8);
|
||||
set_image (win->image2, name, 16);
|
||||
set_image (win->image3, name, 18);
|
||||
set_image (win->image4, name, 24);
|
||||
set_image (win->image5, name, 32);
|
||||
set_image (win->image6, name, 48);
|
||||
set_image (win->image7, name, 64);
|
||||
if (win->symbolic)
|
||||
{
|
||||
gtk_widget_show (win->image8);
|
||||
gtk_widget_show (win->label8);
|
||||
set_image (win->image8, name, 64);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_widget_hide (win->image8);
|
||||
gtk_widget_hide (win->label8);
|
||||
}
|
||||
if (description && description[0])
|
||||
{
|
||||
gtk_label_set_text (GTK_LABEL (win->description), description);
|
||||
gtk_widget_show (win->description);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_widget_hide (win->description);
|
||||
}
|
||||
|
||||
gtk_window_present (GTK_WINDOW (win->details));
|
||||
|
||||
g_free (name);
|
||||
g_free (description);
|
||||
}
|
||||
|
||||
static void
|
||||
add_icon (IconBrowserWindow *win,
|
||||
const gchar *name,
|
||||
@@ -158,6 +51,7 @@ add_icon (IconBrowserWindow *win,
|
||||
GtkIconTheme *icon_theme = icon_browser_window_get_icon_theme (win);
|
||||
gchar *regular_name;
|
||||
gchar *symbolic_name;
|
||||
IbIcon *icon;
|
||||
|
||||
regular_name = g_strdup (name);
|
||||
if (!gtk_icon_theme_has_icon (icon_theme, regular_name))
|
||||
@@ -173,12 +67,12 @@ add_icon (IconBrowserWindow *win,
|
||||
symbolic_name = NULL;
|
||||
}
|
||||
|
||||
gtk_list_store_insert_with_values (win->store, NULL, -1,
|
||||
ICON_STORE_NAME_COLUMN, regular_name,
|
||||
ICON_STORE_SYMBOLIC_NAME_COLUMN, symbolic_name,
|
||||
ICON_STORE_DESCRIPTION_COLUMN, description,
|
||||
ICON_STORE_CONTEXT_COLUMN, context,
|
||||
-1);
|
||||
icon = ib_icon_new (regular_name, symbolic_name, description, context);
|
||||
g_object_bind_property (win->symbolic_radio, "active",
|
||||
icon, "use-symbolic",
|
||||
G_BINDING_DEFAULT);
|
||||
g_list_store_append (win->icon_store, icon);
|
||||
g_object_unref (icon);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -187,50 +81,11 @@ add_context (IconBrowserWindow *win,
|
||||
const gchar *name,
|
||||
const gchar *description)
|
||||
{
|
||||
Context *c;
|
||||
GtkWidget *row;
|
||||
IbContext *context;
|
||||
|
||||
c = g_new (Context, 1);
|
||||
c->id = g_strdup (id);
|
||||
c->name = g_strdup (name);
|
||||
c->description = g_strdup (description);
|
||||
|
||||
g_hash_table_insert (win->contexts, c->id, c);
|
||||
|
||||
row = gtk_label_new (name);
|
||||
gtk_label_set_xalign (GTK_LABEL (row), 0);
|
||||
g_object_set_data (G_OBJECT (row), "context", c);
|
||||
gtk_widget_show (row);
|
||||
gtk_widget_set_margin_start (row, 10);
|
||||
gtk_widget_set_margin_end (row, 10);
|
||||
gtk_widget_set_margin_top (row, 10);
|
||||
gtk_widget_set_margin_bottom (row, 10);
|
||||
|
||||
gtk_list_box_insert (GTK_LIST_BOX (win->context_list), row, -1);
|
||||
|
||||
/* set the tooltip on the list box row */
|
||||
row = gtk_widget_get_parent (row);
|
||||
gtk_widget_set_tooltip_text (row, description);
|
||||
|
||||
if (win->current_context == NULL)
|
||||
win->current_context = c;
|
||||
}
|
||||
|
||||
static void
|
||||
selected_context_changed (GtkListBox *list, IconBrowserWindow *win)
|
||||
{
|
||||
GtkWidget *row;
|
||||
GtkWidget *label;
|
||||
|
||||
row = GTK_WIDGET (gtk_list_box_get_selected_row (list));
|
||||
if (row == NULL)
|
||||
return;
|
||||
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (win->search), FALSE);
|
||||
|
||||
label = gtk_list_box_row_get_child (GTK_LIST_BOX_ROW (row));
|
||||
win->current_context = g_object_get_data (G_OBJECT (label), "context");
|
||||
gtk_tree_model_filter_refilter (win->filter_model);
|
||||
context = ib_context_new (id, name, description);
|
||||
g_list_store_append (win->context_store, context);
|
||||
g_object_unref (context);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -282,6 +137,19 @@ populate (IconBrowserWindow *win)
|
||||
g_strfreev (groups);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
filter_by_icon_name (gpointer item,
|
||||
gpointer data)
|
||||
{
|
||||
return ib_icon_get_name (IB_ICON (item)) != NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
symbolic_toggled (IconBrowserWindow *win)
|
||||
{
|
||||
gtk_filter_changed (win->name_filter, GTK_FILTER_CHANGE_DIFFERENT);
|
||||
}
|
||||
|
||||
static void
|
||||
copy_to_clipboard (GtkButton *button,
|
||||
IconBrowserWindow *win)
|
||||
@@ -292,70 +160,60 @@ copy_to_clipboard (GtkButton *button,
|
||||
gdk_clipboard_set_text (clipboard, gtk_window_get_title (GTK_WINDOW (win->details)));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
icon_visible_func (GtkTreeModel *model,
|
||||
GtkTreeIter *iter,
|
||||
gpointer data)
|
||||
static void
|
||||
set_image (GtkWidget *image, const gchar *name, gint size)
|
||||
{
|
||||
IconBrowserWindow *win = data;
|
||||
gchar *context;
|
||||
gchar *name;
|
||||
gint column;
|
||||
gboolean search;
|
||||
const gchar *search_text;
|
||||
gboolean visible;
|
||||
|
||||
search = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (win->search));
|
||||
search_text = gtk_editable_get_text (GTK_EDITABLE (win->searchentry));
|
||||
|
||||
if (win->symbolic)
|
||||
column = ICON_STORE_SYMBOLIC_NAME_COLUMN;
|
||||
else
|
||||
column = ICON_STORE_NAME_COLUMN;
|
||||
|
||||
gtk_tree_model_get (model, iter,
|
||||
column, &name,
|
||||
ICON_STORE_CONTEXT_COLUMN, &context,
|
||||
-1);
|
||||
if (!name)
|
||||
visible = FALSE;
|
||||
else if (search)
|
||||
visible = strstr (name, search_text) != NULL;
|
||||
else
|
||||
visible = win->current_context != NULL && g_strcmp0 (context, win->current_context->id) == 0;
|
||||
|
||||
g_free (name);
|
||||
g_free (context);
|
||||
|
||||
return visible;
|
||||
gtk_image_set_from_icon_name (GTK_IMAGE (image), name);
|
||||
gtk_image_set_pixel_size (GTK_IMAGE (image), size);
|
||||
}
|
||||
|
||||
static void
|
||||
symbolic_toggled (GtkToggleButton *toggle, IconBrowserWindow *win)
|
||||
item_activated (GtkGridView *view,
|
||||
guint position,
|
||||
IconBrowserWindow *win)
|
||||
{
|
||||
gint column;
|
||||
GListModel *model = gtk_grid_view_get_model (view);
|
||||
IbIcon *icon = g_list_model_get_item (model, position);
|
||||
const char *name;
|
||||
const char *description;
|
||||
gboolean symbolic;
|
||||
|
||||
win->symbolic = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (toggle));
|
||||
name = ib_icon_get_name (icon);
|
||||
description = ib_icon_get_description (icon);
|
||||
symbolic = ib_icon_get_use_symbolic (icon);
|
||||
|
||||
if (win->symbolic)
|
||||
column = ICON_STORE_SYMBOLIC_NAME_COLUMN;
|
||||
gtk_window_set_title (GTK_WINDOW (win->details), name);
|
||||
set_image (win->image1, name, 8);
|
||||
set_image (win->image2, name, 16);
|
||||
set_image (win->image3, name, 18);
|
||||
set_image (win->image4, name, 24);
|
||||
set_image (win->image5, name, 32);
|
||||
set_image (win->image6, name, 48);
|
||||
set_image (win->image7, name, 64);
|
||||
if (symbolic)
|
||||
{
|
||||
gtk_widget_show (win->image8);
|
||||
gtk_widget_show (win->label8);
|
||||
set_image (win->image8, name, 64);
|
||||
}
|
||||
else
|
||||
column = ICON_STORE_NAME_COLUMN;
|
||||
{
|
||||
gtk_widget_hide (win->image8);
|
||||
gtk_widget_hide (win->label8);
|
||||
}
|
||||
if (description && description[0])
|
||||
{
|
||||
gtk_label_set_text (GTK_LABEL (win->description), description);
|
||||
gtk_widget_show (win->description);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_widget_hide (win->description);
|
||||
}
|
||||
|
||||
icon_store_set_text_column (ICON_STORE (win->store), column);
|
||||
gtk_window_present (GTK_WINDOW (win->details));
|
||||
|
||||
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (win->list), win->cell, "icon-name", column, NULL);
|
||||
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (win->list), win->text_cell, "text", column, NULL);
|
||||
|
||||
gtk_tree_model_filter_refilter (win->filter_model);
|
||||
gtk_widget_queue_draw (win->list);
|
||||
}
|
||||
|
||||
static void
|
||||
search_mode_toggled (GObject *searchbar, GParamSpec *pspec, IconBrowserWindow *win)
|
||||
{
|
||||
if (gtk_search_bar_get_search_mode (GTK_SEARCH_BAR (searchbar)))
|
||||
gtk_list_box_unselect_all (GTK_LIST_BOX (win->context_list));
|
||||
g_object_unref (icon);
|
||||
}
|
||||
|
||||
static GdkPaintable *
|
||||
@@ -381,7 +239,10 @@ get_image_paintable (GtkImage *image)
|
||||
gtk_widget_get_direction (GTK_WIDGET (image)),
|
||||
0);
|
||||
if (icon == NULL)
|
||||
return NULL;
|
||||
{
|
||||
g_print ("no icon for %s\n", icon_name);
|
||||
return NULL;
|
||||
}
|
||||
return GDK_PAINTABLE (icon);
|
||||
case GTK_IMAGE_GICON:
|
||||
case GTK_IMAGE_EMPTY:
|
||||
@@ -419,10 +280,10 @@ drag_prepare_texture (GtkDragSource *source,
|
||||
{
|
||||
GdkPaintable *paintable = get_image_paintable (GTK_IMAGE (widget));
|
||||
|
||||
if (!GDK_IS_TEXTURE (paintable))
|
||||
if (!GDK_IS_PAINTABLE (paintable))
|
||||
return NULL;
|
||||
|
||||
return gdk_content_provider_new_typed (GDK_TYPE_TEXTURE, paintable);
|
||||
return gdk_content_provider_new_typed (GDK_TYPE_PAINTABLE, paintable);
|
||||
}
|
||||
|
||||
static GdkContentProvider *
|
||||
@@ -476,17 +337,10 @@ setup_scalable_image_dnd (GtkWidget *image)
|
||||
static void
|
||||
icon_browser_window_init (IconBrowserWindow *win)
|
||||
{
|
||||
GdkContentFormats *list;
|
||||
GtkFilter *filter;
|
||||
|
||||
gtk_widget_init_template (GTK_WIDGET (win));
|
||||
|
||||
list = gdk_content_formats_new_for_gtype (G_TYPE_STRING);
|
||||
gtk_icon_view_enable_model_drag_source (GTK_ICON_VIEW (win->list),
|
||||
GDK_BUTTON1_MASK,
|
||||
list,
|
||||
GDK_ACTION_COPY);
|
||||
gdk_content_formats_unref (list);
|
||||
|
||||
setup_image_dnd (win->image1);
|
||||
setup_image_dnd (win->image2);
|
||||
setup_image_dnd (win->image3);
|
||||
@@ -496,19 +350,16 @@ icon_browser_window_init (IconBrowserWindow *win)
|
||||
setup_image_dnd (win->image7);
|
||||
setup_scalable_image_dnd (win->image8);
|
||||
|
||||
win->contexts = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, context_free);
|
||||
|
||||
gtk_tree_model_filter_set_visible_func (win->filter_model, icon_visible_func, win, NULL);
|
||||
gtk_window_set_transient_for (GTK_WINDOW (win->details), GTK_WINDOW (win));
|
||||
|
||||
g_signal_connect (win->searchbar, "notify::search-mode-enabled",
|
||||
G_CALLBACK (search_mode_toggled), win);
|
||||
gtk_search_bar_set_key_capture_widget (GTK_SEARCH_BAR (win->searchbar),
|
||||
GTK_WIDGET (win));
|
||||
|
||||
symbolic_toggled (GTK_TOGGLE_BUTTON (win->symbolic_radio), win);
|
||||
gtk_search_bar_set_key_capture_widget (GTK_SEARCH_BAR (win->searchbar), GTK_WIDGET (win));
|
||||
|
||||
populate (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);
|
||||
|
||||
gtk_multi_filter_append (GTK_MULTI_FILTER (filter), g_object_ref (win->name_filter));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -516,7 +367,7 @@ icon_browser_window_finalize (GObject *object)
|
||||
{
|
||||
IconBrowserWindow *win = ICON_BROWSER_WINDOW (object);
|
||||
|
||||
g_hash_table_unref (win->contexts);
|
||||
g_clear_object (&win->name_filter);
|
||||
|
||||
G_OBJECT_CLASS (icon_browser_window_parent_class)->finalize (object);
|
||||
}
|
||||
@@ -528,23 +379,19 @@ icon_browser_window_class_init (IconBrowserWindowClass *class)
|
||||
|
||||
object_class->finalize = icon_browser_window_finalize;
|
||||
|
||||
g_type_ensure (ICON_STORE_TYPE);
|
||||
g_type_ensure (IB_TYPE_ICON);
|
||||
g_type_ensure (IB_TYPE_CONTEXT);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
|
||||
"/org/gtk/iconbrowser/gtk/window.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, context_list);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, filter_model);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, symbolic_radio);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, details);
|
||||
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, store);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, cell);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, text_cell);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, search);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, searchbar);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, searchentry);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, list);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, icon_store);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, icon_filter_model);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, context_store);
|
||||
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, details);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, image1);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, image2);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, image3);
|
||||
@@ -556,11 +403,9 @@ icon_browser_window_class_init (IconBrowserWindowClass *class)
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, label8);
|
||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, description);
|
||||
|
||||
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), search_text_changed);
|
||||
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), item_activated);
|
||||
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), selected_context_changed);
|
||||
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), symbolic_toggled);
|
||||
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), copy_to_clipboard);
|
||||
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), symbolic_toggled);
|
||||
}
|
||||
|
||||
IconBrowserWindow *
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
#include "iconstore.h"
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
struct _IconStore
|
||||
{
|
||||
GtkListStore parent;
|
||||
|
||||
gint text_column;
|
||||
};
|
||||
|
||||
struct _IconStoreClass
|
||||
{
|
||||
GtkListStoreClass parent_class;
|
||||
};
|
||||
|
||||
static void icon_store_drag_source_init (GtkTreeDragSourceIface *iface);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (IconStore, icon_store, GTK_TYPE_LIST_STORE,
|
||||
G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_DRAG_SOURCE,
|
||||
icon_store_drag_source_init))
|
||||
|
||||
|
||||
static void
|
||||
icon_store_init (IconStore *store)
|
||||
{
|
||||
GType types[4] = { G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING };
|
||||
|
||||
gtk_list_store_set_column_types (GTK_LIST_STORE (store), 4, types);
|
||||
|
||||
store->text_column = ICON_STORE_NAME_COLUMN;
|
||||
}
|
||||
|
||||
static void
|
||||
icon_store_class_init (IconStoreClass *class)
|
||||
{
|
||||
}
|
||||
|
||||
static gboolean
|
||||
row_draggable (GtkTreeDragSource *drag_source,
|
||||
GtkTreePath *path)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
drag_data_delete (GtkTreeDragSource *drag_source,
|
||||
GtkTreePath *path)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
|
||||
if (gtk_tree_model_get_iter (GTK_TREE_MODEL (drag_source), &iter, path))
|
||||
return gtk_list_store_remove (GTK_LIST_STORE (drag_source), &iter);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static GdkContentProvider *
|
||||
drag_data_get (GtkTreeDragSource *drag_source,
|
||||
GtkTreePath *path)
|
||||
{
|
||||
GdkContentProvider *content;
|
||||
GtkTreeIter iter;
|
||||
gchar *text;
|
||||
|
||||
if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (drag_source), &iter, path))
|
||||
return NULL;
|
||||
|
||||
gtk_tree_model_get (GTK_TREE_MODEL (drag_source), &iter,
|
||||
ICON_STORE (drag_source)->text_column, &text,
|
||||
-1);
|
||||
|
||||
content = gdk_content_provider_new_typed (G_TYPE_STRING, text);
|
||||
|
||||
g_free (text);
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
icon_store_drag_source_init (GtkTreeDragSourceIface *iface)
|
||||
{
|
||||
iface->row_draggable = row_draggable;
|
||||
iface->drag_data_delete = drag_data_delete;
|
||||
iface->drag_data_get = drag_data_get;
|
||||
}
|
||||
|
||||
void
|
||||
icon_store_set_text_column (IconStore *store, gint text_column)
|
||||
{
|
||||
store->text_column = text_column;
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
#ifndef __ICON_STORE_H
|
||||
#define __ICON_STORE_H
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
|
||||
#define ICON_STORE_TYPE (icon_store_get_type ())
|
||||
#define ICON_STORE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ICON_STORE_TYPE, IconStore))
|
||||
|
||||
|
||||
typedef struct _IconStore IconStore;
|
||||
typedef struct _IconStoreClass IconStoreClass;
|
||||
|
||||
enum {
|
||||
ICON_STORE_NAME_COLUMN,
|
||||
ICON_STORE_SYMBOLIC_NAME_COLUMN,
|
||||
ICON_STORE_DESCRIPTION_COLUMN,
|
||||
ICON_STORE_CONTEXT_COLUMN
|
||||
};
|
||||
|
||||
GType icon_store_get_type (void);
|
||||
|
||||
void icon_store_set_text_column (IconStore *store,
|
||||
gint column);
|
||||
|
||||
#endif /* __ICON_STORE_H */
|
||||
@@ -1,10 +0,0 @@
|
||||
<interface>
|
||||
<menu id="app-menu">
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Quit</attribute>
|
||||
<attribute name="action">app.quit</attribute>
|
||||
</item>
|
||||
</section>
|
||||
</menu>
|
||||
</interface>
|
||||
@@ -2,7 +2,8 @@ iconbrowser_sources = [
|
||||
'main.c',
|
||||
'iconbrowserapp.c',
|
||||
'iconbrowserwin.c',
|
||||
'iconstore.c'
|
||||
'iconbrowsericon.c',
|
||||
'iconbrowsercontext.c'
|
||||
]
|
||||
|
||||
iconbrowser_resources = gnome.compile_resources('iconbrowser_resources',
|
||||
@@ -17,14 +18,3 @@ executable('gtk4-icon-browser',
|
||||
gui_app: true,
|
||||
link_args: extra_demo_ldflags,
|
||||
install: true)
|
||||
|
||||
install_data('org.gtk.IconBrowser4.desktop', install_dir: gtk_applicationsdir)
|
||||
|
||||
# icons
|
||||
icontheme_dir = join_paths(gtk_datadir, 'icons/hicolor')
|
||||
|
||||
foreach size: ['scalable', 'symbolic']
|
||||
install_subdir('data/' + size,
|
||||
install_dir: icontheme_dir
|
||||
)
|
||||
endforeach
|
||||
|
||||
@@ -12,10 +12,6 @@
|
||||
</item>
|
||||
</section>
|
||||
</menu>
|
||||
<object class="IconStore" id="store"/>
|
||||
<object class="GtkTreeModelFilter" id="filter_model">
|
||||
<property name="child-model">store</property>
|
||||
</object>
|
||||
<template class="IconBrowserWindow" parent="GtkApplicationWindow">
|
||||
<style>
|
||||
<class name="devel"/>
|
||||
@@ -42,7 +38,7 @@
|
||||
<property name="draw-indicator">0</property>
|
||||
<property name="label" translatable="yes">Symbolic</property>
|
||||
<property name="group">normal_radio</property>
|
||||
<signal name="toggled" handler="symbolic_toggled"/>
|
||||
<signal name="notify::active" handler="symbolic_toggled" swapped="yes" after="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
@@ -71,8 +67,44 @@
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkListBox" id="context_list">
|
||||
<signal name="selected-rows-changed" handler="selected_context_changed"/>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<child>
|
||||
<object class="GtkListView">
|
||||
<property name="model">
|
||||
<object class="GtkSingleSelection" id="context_model">
|
||||
<property name="model">
|
||||
<object class="GListStore" id="context_store">
|
||||
<property name="item-type">IbContext</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</property>
|
||||
<property name="factory">
|
||||
<object class="GtkBuilderListItemFactory">
|
||||
<property name="bytes">
|
||||
<![CDATA[
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="GtkListItem">
|
||||
<property name="child">
|
||||
<object class="GtkLabel">
|
||||
<property name="xalign">0</property>
|
||||
<binding name="label">
|
||||
<lookup name="name" type="IbContext">
|
||||
<lookup name="item">GtkListItem</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
</object>
|
||||
</property>
|
||||
</template>
|
||||
</interface>
|
||||
]]>
|
||||
</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -88,7 +120,6 @@
|
||||
<property name="search-mode-enabled" bind-source="search" bind-property="active" bind-flags="bidirectional"/>
|
||||
<child>
|
||||
<object class="GtkSearchEntry" id="searchentry">
|
||||
<signal name="search-changed" handler="search_text_changed"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
@@ -99,23 +130,91 @@
|
||||
<property name="vexpand">1</property>
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<child>
|
||||
<object class="GtkIconView" id="list">
|
||||
<property name="model">filter_model</property>
|
||||
<property name="selection-mode">none</property>
|
||||
<property name="activate-on-single-click">1</property>
|
||||
<signal name="item_activated" handler="item_activated"/>
|
||||
<child>
|
||||
<object class="GtkCellRendererPixbuf" id="cell">
|
||||
<property name="xpad">10</property>
|
||||
<property name="ypad">10</property>
|
||||
<object class="GtkGridView" id="list">
|
||||
<signal name="activate" handler="item_activated"/>
|
||||
<property name="single-click-activate">1</property>
|
||||
<property name="model">
|
||||
<object class="GtkNoSelection">
|
||||
<property name="model">
|
||||
<object class="GtkFilterListModel" id="icon_filter_model">
|
||||
<property name="filter">
|
||||
<object class="GtkEveryFilter">
|
||||
<child>
|
||||
<object class="GtkStringFilter">
|
||||
<property name="expression">
|
||||
<lookup name="name" type="IbIcon"/>
|
||||
</property>
|
||||
<binding name="search">
|
||||
<lookup name="text" type="GtkSearchEntry">
|
||||
searchentry
|
||||
</lookup>
|
||||
</binding>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStringFilter">
|
||||
<property name="ignore-case">0</property>
|
||||
<property name="match-mode">exact</property>
|
||||
<property name="expression">
|
||||
<lookup name="context" type="IbIcon"/>
|
||||
</property>
|
||||
<binding name="search">
|
||||
<lookup name="id" type="IbContext">
|
||||
<lookup name="selected-item" type="GtkSingleSelection">
|
||||
context_model
|
||||
</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
<property name="model">
|
||||
<object class="GListStore" id="icon_store">
|
||||
<property name="item-type">IbIcon</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="text_cell">
|
||||
<property name="xpad">10</property>
|
||||
<property name="ypad">10</property>
|
||||
</property>
|
||||
<property name="factory">
|
||||
<object class="GtkBuilderListItemFactory">
|
||||
<property name="bytes">
|
||||
<![CDATA[
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="GtkListItem">
|
||||
<property name="child">
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="pixel-size">48</property>
|
||||
<binding name="icon-name">
|
||||
<lookup name="name" type="IbIcon">
|
||||
<lookup name="item">GtkListItem</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<binding name="label">
|
||||
<lookup name="name" type="IbIcon">
|
||||
<lookup name="item">GtkListItem</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</template>
|
||||
</interface>
|
||||
]]>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
@@ -125,14 +224,7 @@
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
<object class="GtkSizeGroup">
|
||||
<property name="mode">vertical</property>
|
||||
<widgets>
|
||||
<widget name="normal_radio"/>
|
||||
<widget name="symbolic_radio"/>
|
||||
<widget name="search"/>
|
||||
</widgets>
|
||||
</object>
|
||||
|
||||
<object class="GtkDialog" id="details">
|
||||
<property name="modal">1</property>
|
||||
<property name="use-header-bar">1</property>
|
||||
@@ -164,7 +256,7 @@
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage" id="image2">
|
||||
<object class="GtkImage" id="image2">
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">end</property>
|
||||
<accessibility>
|
||||
@@ -373,7 +465,7 @@
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label8">
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">baseline</property>
|
||||
@@ -404,7 +496,7 @@
|
||||
<signal name="clicked" handler="copy_to_clipboard"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="description">
|
||||
<property name="margin-start">10</property>
|
||||
<property name="margin-end">10</property>
|
||||
@@ -419,3 +511,4 @@
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
|
||||
|
||||
27
demos/node-editor/help-window.ui
Normal file
27
demos/node-editor/help-window.ui
Normal file
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<object class="GtkWindow" id="window">
|
||||
<style>
|
||||
<class name="devel"/>
|
||||
</style>
|
||||
<property name="title" translatable="yes">Help</property>
|
||||
<property name="default-width">720</property>
|
||||
<property name="default-height">520</property>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<child>
|
||||
<object class="GtkTextView" id="text_view">
|
||||
<property name="wrap-mode">word</property>
|
||||
<property name="left-margin">20</property>
|
||||
<property name="right-margin">20</property>
|
||||
<property name="top-margin">20</property>
|
||||
<property name="bottom-margin">20</property>
|
||||
<property name="buffer">
|
||||
<object class="GtkTextBuffer" id="buffer"/>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
@@ -51,21 +51,121 @@ node_editor_application_init (NodeEditorApplication *app)
|
||||
}
|
||||
|
||||
static void
|
||||
quit_activated (GSimpleAction *action,
|
||||
activate_about (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer data)
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkApplication *app = user_data;
|
||||
char *version;
|
||||
GString *s;
|
||||
GskRenderer *gsk_renderer;
|
||||
const char *renderer;
|
||||
|
||||
s = g_string_new ("");
|
||||
|
||||
g_string_append (s, "System libraries\n");
|
||||
g_string_append_printf (s, "\tGLib\t%d.%d.%d\n",
|
||||
glib_major_version,
|
||||
glib_minor_version,
|
||||
glib_micro_version);
|
||||
g_string_append_printf (s, "\tPango\t%s\n",
|
||||
pango_version_string ());
|
||||
g_string_append_printf (s, "\tGTK\t%d.%d.%d\n",
|
||||
gtk_get_major_version (),
|
||||
gtk_get_minor_version (),
|
||||
gtk_get_micro_version ());
|
||||
|
||||
gsk_renderer = gtk_native_get_renderer (GTK_NATIVE (gtk_application_get_active_window (app)));
|
||||
if (strcmp (G_OBJECT_TYPE_NAME (gsk_renderer), "GskVulkanRenderer") == 0)
|
||||
renderer = "Vulkan";
|
||||
else if (strcmp (G_OBJECT_TYPE_NAME (gsk_renderer), "GskGLRenderer") == 0)
|
||||
renderer = "OpenGL";
|
||||
else if (strcmp (G_OBJECT_TYPE_NAME (gsk_renderer), "GskCairoRenderer") == 0)
|
||||
renderer = "Cairo";
|
||||
else
|
||||
renderer = "Unknown";
|
||||
|
||||
g_string_append_printf (s, "\nRenderer\n\t%s", renderer);
|
||||
|
||||
version = g_strdup_printf ("%s\nRunning against GTK %d.%d.%d",
|
||||
PACKAGE_VERSION,
|
||||
gtk_get_major_version (),
|
||||
gtk_get_minor_version (),
|
||||
gtk_get_micro_version ());
|
||||
|
||||
gtk_show_about_dialog (GTK_WINDOW (gtk_application_get_active_window (app)),
|
||||
"program-name", "GTK Node Editor",
|
||||
"version", version,
|
||||
"copyright", "© 2019—2020 The GTK Team",
|
||||
"license-type", GTK_LICENSE_LGPL_2_1,
|
||||
"website", "http://www.gtk.org",
|
||||
"comments", "Program to test GTK rendering",
|
||||
"authors", (const char *[]){ "Benjamin Otte", "Timm Bäder", NULL},
|
||||
"logo-icon-name", "text-editor-symbolic",
|
||||
"title", "About GTK Node Editor",
|
||||
"system-information", s->str,
|
||||
NULL);
|
||||
|
||||
g_string_free (s, TRUE);
|
||||
g_free (version);
|
||||
}
|
||||
|
||||
static void
|
||||
activate_quit (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer data)
|
||||
{
|
||||
g_application_quit (G_APPLICATION (data));
|
||||
}
|
||||
|
||||
static void
|
||||
activate_inspector (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
gtk_window_set_interactive_debugging (TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
activate_help (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkBuilder *builder;
|
||||
GtkWidget *window;
|
||||
GtkTextBuffer *buffer;
|
||||
GBytes *bytes;
|
||||
const char *text;
|
||||
gsize len;
|
||||
|
||||
builder = gtk_builder_new ();
|
||||
gtk_builder_add_from_resource (builder, "/org/gtk/gtk4/node-editor/help-window.ui", NULL);
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
|
||||
buffer = GTK_TEXT_BUFFER (gtk_builder_get_object (builder, "buffer"));
|
||||
|
||||
bytes = g_resources_lookup_data ("/org/gtk/gtk4/node-editor/node-format.md",
|
||||
G_RESOURCE_LOOKUP_FLAGS_NONE,
|
||||
NULL);
|
||||
text = g_bytes_get_data (bytes, &len);
|
||||
gtk_text_buffer_set_text (buffer, text, len);
|
||||
g_bytes_unref (bytes);
|
||||
|
||||
gtk_window_present (GTK_WINDOW (window));
|
||||
g_object_unref (builder);
|
||||
}
|
||||
|
||||
static GActionEntry app_entries[] =
|
||||
{
|
||||
{ "quit", quit_activated, NULL, NULL, NULL }
|
||||
{ "about", activate_about, NULL, NULL, NULL },
|
||||
{ "quit", activate_quit, NULL, NULL, NULL },
|
||||
{ "inspector", activate_inspector, NULL, NULL, NULL },
|
||||
{ "help", activate_help, NULL, NULL, NULL },
|
||||
};
|
||||
|
||||
static void
|
||||
node_editor_application_startup (GApplication *app)
|
||||
{
|
||||
const char *help_accels[2] = { "F1", NULL };
|
||||
const char *quit_accels[2] = { "<Ctrl>Q", NULL };
|
||||
const char *open_accels[2] = { "<Ctrl>O", NULL };
|
||||
GtkCssProvider *provider;
|
||||
@@ -75,6 +175,7 @@ node_editor_application_startup (GApplication *app)
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (app),
|
||||
app_entries, G_N_ELEMENTS (app_entries),
|
||||
app);
|
||||
gtk_application_set_accels_for_action (GTK_APPLICATION (app), "app.help", help_accels);
|
||||
gtk_application_set_accels_for_action (GTK_APPLICATION (app), "app.quit", quit_accels);
|
||||
gtk_application_set_accels_for_action (GTK_APPLICATION (app), "win.open", open_accels);
|
||||
|
||||
|
||||
@@ -825,6 +825,7 @@ node_editor_window_create_renderer_widget (gpointer item,
|
||||
gtk_widget_set_size_request (box, 120, 90);
|
||||
|
||||
label = gtk_label_new (g_object_get_data (G_OBJECT (paintable), "description"));
|
||||
gtk_widget_add_css_class (label, "title-4");
|
||||
gtk_box_append (GTK_BOX (box), label);
|
||||
|
||||
picture = gtk_picture_new_for_paintable (paintable);
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<menu id="gear_menu">
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Help</attribute>
|
||||
<attribute name="action">app.help</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Inspector</attribute>
|
||||
<attribute name="action">app.inspector</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_About Node Editor</attribute>
|
||||
<attribute name="action">app.about</attribute>
|
||||
</item>
|
||||
</section>
|
||||
</menu>
|
||||
|
||||
<object class="GtkPopover" id="testcase_popover">
|
||||
<child>
|
||||
<object class="GtkGrid">
|
||||
@@ -119,6 +136,13 @@
|
||||
<property name="popover">testcase_popover</property>
|
||||
</object>
|
||||
</child>
|
||||
<child type="end">
|
||||
<object class="GtkMenuButton" id="gear_menu_button">
|
||||
<property name="valign">center</property>
|
||||
<property name="menu-model">gear_menu</property>
|
||||
<property name="icon-name">open-menu-symbolic</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
|
||||
@@ -2,5 +2,7 @@
|
||||
<gresources>
|
||||
<gresource prefix="/org/gtk/gtk4/node-editor">
|
||||
<file preprocess="xml-stripblanks">node-editor-window.ui</file>
|
||||
<file preprocess="xml-stripblanks">help-window.ui</file>
|
||||
<file>node-format.md</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
|
||||
213
demos/node-editor/node-format.md
Normal file
213
demos/node-editor/node-format.md
Normal file
@@ -0,0 +1,213 @@
|
||||
# The Node file format
|
||||
|
||||
GSK render nodes can be serialized and deserialized using APIs such as `gsk_render_node_serialize()` and `gsk_render_node_deserialize()`. The intended use for this is development - primarily the development of GTK - by allowing things such as creating testsuites and benchmarks, exchanging nodes in bug reports. GTK includes the `gtk4-node-editor` application for creating such test files.
|
||||
|
||||
The format is a text format that follows the [CSS syntax rules](https://drafts.csswg.org/css-syntax-3/). In particular, this means that every array of bytes will produce a render node when parsed, as there is a defined error recovery method. For more details on error handling, please refer to the documentation of the aprsing APIs.
|
||||
|
||||
The grammar of a node text representation using [the CSS value definition syntax](https://drafts.csswg.org/css-values-3/#value-defs) looks like this:
|
||||
**document**: `<node>\*`
|
||||
**node**: container { <document> } | `<node-name> { <property>* }`
|
||||
**property**: `<property-name>: <node> | <value> ;`
|
||||
|
||||
Each node has its own `<node-name>` and supports a custom set of properties, each with their own `<property-name>` and syntax. The following paragraphs document each of the nodes and their properties.
|
||||
|
||||
When serializing and the value of a property equals the default value, this value will not be serialized. Serialization aims to produce an output as small as possible.
|
||||
|
||||
# Nodes
|
||||
|
||||
### container
|
||||
|
||||
The **container** node is a special node that allows specifying a list of child nodes. Its contents follow the same rules as an empty document.
|
||||
|
||||
### blend
|
||||
|
||||
| property | syntax | default | printed |
|
||||
| -------- | ---------------- | ---------------------- | ----------- |
|
||||
| bottom | `<node>` | color { color: #AF0; } | always |
|
||||
| mode | `<blend-mode>` | normal | non-default |
|
||||
| top | `<node>` | color { } | always |
|
||||
|
||||
Creates a node like `gsk_blend_node_new()` with the given properties.
|
||||
|
||||
### blur
|
||||
|
||||
| property | syntax | default | printed |
|
||||
| -------- | ---------------- | ---------------------- | ----------- |
|
||||
| blur | `<number>` | 1 | non-default |
|
||||
| child | `<node>` | color { } | always |
|
||||
|
||||
Creates a node like `gsk_blur_node_new()` with the given properties.
|
||||
|
||||
### border
|
||||
|
||||
| property | syntax | default | printed |
|
||||
| -------- | ---------------- | ---------------------- | ----------- |
|
||||
| color | `<color>{1,4}` | black | non-default |
|
||||
| outline | `<rounded-rect>` | 50 | always |
|
||||
| width | `<number>{1,4}` | 1 | non-default |
|
||||
|
||||
Creates a node like `gsk_border_node_new()` with the given properties.
|
||||
|
||||
For the color and width properties, the values follow the typical CSS order of top, right, bottom, left. If the last/left value isn't given, the 2nd/right value is used. If the 3rd/bottom value isn't given, the 1st/top value is used. And if the 2nd/right value also isn't given, the 1st/top value is used for every 4 values.
|
||||
|
||||
### clip
|
||||
|
||||
| property | syntax | default | printed |
|
||||
| -------- | ---------------- | ---------------------- | ----------- |
|
||||
| child | `<node>` | color { } | always |
|
||||
| clip | `<rounded-rect>` | 50 | always |
|
||||
|
||||
Creates a node like `gsk_clip_node_new()` with the given properties.
|
||||
|
||||
As an extension, this node allows specifying a rounded rectangle for the clip property. If that rectangle is indeed rounded, a node like `gsk_rounded_clip_node_new()` will be created instead.
|
||||
|
||||
### color
|
||||
|
||||
| property | syntax | default | printed |
|
||||
| -------- | ---------------- | ---------------------- | ----------- |
|
||||
| bounds | `<rect>` | 50 | always |
|
||||
| color | `<color>` | #FF00CC | always |
|
||||
|
||||
Creates a node like `gsk_color_node_new()` with the given properties.
|
||||
|
||||
The color is chosen as an error pink so it is visible while also reminding people to change it.
|
||||
|
||||
### color-matrix
|
||||
|
||||
| property | syntax | default | printed |
|
||||
| -------- | ---------------- | ---------------------- | ----------- |
|
||||
| child | `<node>` | color { } | always |
|
||||
| matrix | `<transform>` | none | non-default |
|
||||
| offset | `<number>{4}` | 0 0 0 0 | non-default |
|
||||
|
||||
Creates a node like `gsk_color_matrix_node_new()` with the given properties.
|
||||
|
||||
The matrix property accepts a <transform> for compatibility purposes, but you should be aware that the allowed values are meant to be used on 3D transformations, so their naming might appear awkward. However, it is always possible to use the matrix3d() production to specify all 16 values individually.
|
||||
|
||||
### cross-fade
|
||||
|
||||
| property | syntax | default | printed |
|
||||
| -------- | ---------------- | ---------------------- | ----------- |
|
||||
| end | `<node>` | color { } | always |
|
||||
| mode | `<number>` | 0.5 | non-default |
|
||||
| start | `<node>` | color { color: #AF0; } | always |
|
||||
|
||||
Creates a node like `gsk_cross_fade_node_new()` with the given properties.
|
||||
|
||||
### debug
|
||||
|
||||
| property | syntax | default | printed |
|
||||
| -------- | ---------------- | ---------------------- | ----------- |
|
||||
| child | `<node>` | color { } | always |
|
||||
| message | `<string>` | "" | non-default |
|
||||
|
||||
Creates a node like `gsk_debug_node_new()` with the given properties.
|
||||
|
||||
### inset-shadow
|
||||
|
||||
| property | syntax | default | printed |
|
||||
| -------- | ---------------- | ---------------------- | ----------- |
|
||||
| blur | `<number>` | 0 | non-default |
|
||||
| color | `<color>` | black | non-default |
|
||||
| dx | `<number>` | 1 | non-default |
|
||||
| dy | `<number>` | 1 | non-default |
|
||||
| outline | `<rounded-rect>` | 50 | always |
|
||||
| spread | `<number>` | 0 | non-default |
|
||||
|
||||
Creates a node like `gsk_inset_shadow_node_new()` with the given properties.
|
||||
|
||||
### linear-gradient
|
||||
|
||||
| property | syntax | default | printed |
|
||||
| -------- | ---------------- | ---------------------- | ----------- |
|
||||
| bounds | `<rect>` | 50 | always |
|
||||
| end | `<point>` | 0 50 | always |
|
||||
| start | `<point>` | 0 0 | always |
|
||||
| stops | `<color-stop>` | 0 #AF0, 1 #F0C | always |
|
||||
|
||||
Creates a node like `gsk_linear_gradient_node_new()` with the given properties.
|
||||
|
||||
### opacity
|
||||
|
||||
| property | syntax | default | printed |
|
||||
| -------- | ---------------- | ---------------------- | ----------- |
|
||||
| child | `<node>` | color { } | always |
|
||||
| opacity | `<number>` | 0.5 | non-default |
|
||||
|
||||
Creates a node like `gsk_transform_node_new()` with the given properties.
|
||||
|
||||
### outset-shadow
|
||||
|
||||
| property | syntax | default | printed |
|
||||
| -------- | ---------------- | ---------------------- | ----------- |
|
||||
| blur | `<number>` | 0 | non-default |
|
||||
| color | `<color>` | black | non-default |
|
||||
| dx | `<number>` | 1 | non-default |
|
||||
| dy | `<number>` | 1 | non-default |
|
||||
| outline | `<rounded-rect>` | 50 | always |
|
||||
| spread | `<number>` | 0 | non-default |
|
||||
|
||||
Creates a node like `gsk_outset_shadow_node_new()` with the given properties.
|
||||
|
||||
### repeat
|
||||
|
||||
| property | syntax | default | printed |
|
||||
| -------- | ---------------- | ---------------------- | ----------- |
|
||||
| bounds | `<rect>` | *bounds of child node* | non-default |
|
||||
| child | `<node>` | color { } | always |
|
||||
| child-bounds| `<rect>` | *bounds of child node* | non-default |
|
||||
|
||||
Creates a node like `gsk_repeat_node_new()` with the given properties.
|
||||
|
||||
### rounded-clip
|
||||
|
||||
| property | syntax | default | printed |
|
||||
| -------- | ---------------- | ---------------------- | ----------- |
|
||||
| child | `<node>` | color { } | always |
|
||||
| clip | `<rounded-rect>` | 50 | always |
|
||||
|
||||
Creates a node like `gsk_rounded_clip_node_new()` with the given properties.
|
||||
|
||||
### shadow
|
||||
|
||||
| property | syntax | default | printed |
|
||||
| -------- | ---------------- | ---------------------- | ----------- |
|
||||
| child | `<node>` | color { } | always |
|
||||
| shadow | `<shadow>` | black 1 1 | always |
|
||||
|
||||
Creates a node like `gsk_shadow_node_new()` with the given properties.
|
||||
|
||||
### text
|
||||
|
||||
| property | syntax | default | printed |
|
||||
| -------- | ---------------- | ---------------------- | ----------- |
|
||||
| color | `<color>` | black | non-default |
|
||||
| font | `<string>` | "Cantarell 11" | always |
|
||||
| glyphs | `<glyphs>` | "Hello" | always |
|
||||
| offset | `<point>` | 0 0 | non-default |
|
||||
|
||||
Creates a node like `gsk_text_node_new()` with the given properties.
|
||||
|
||||
If the given font does not exist or the given glyphs are invalid for the given font, an error node will be returned.
|
||||
|
||||
### texture
|
||||
|
||||
| property | syntax | default | printed |
|
||||
| -------- | ---------------- | ---------------------- | ----------- |
|
||||
| bounds | `<rect>` | 50 | always |
|
||||
| texture | `<url>` | *see below* | always |
|
||||
|
||||
Creates a node like `gsk_texture_node_new()` with the given properties.
|
||||
|
||||
The default texture is a 10x10 checkerboard with the top left and bottom right 5x5 being in the color #FF00CC and the other part being transparent. A possible representation for this texture is `url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAABmJLR0QA/wD/AP+gvaeTAAAAKUlEQVQYlWP8z3DmPwMaYGQwYUQXY0IXwAUGUCGGoxkYGBiweXAoeAYAz44F3e3U1xUAAAAASUVORK5CYII=")
|
||||
`.
|
||||
|
||||
### transform
|
||||
|
||||
| property | syntax | default | printed |
|
||||
| -------- | ---------------- | ---------------------- | ----------- |
|
||||
| child | `<node>` | color { } | always |
|
||||
| transform| `<transform>` | none | non-default |
|
||||
|
||||
Creates a node like `gsk_transform_node_new()` with the given properties.
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
executable('print-editor',
|
||||
executable('gtk4-print-editor',
|
||||
['print-editor.c'],
|
||||
c_args: common_cflags,
|
||||
dependencies: libgtk_dep,
|
||||
include_directories: confinc,
|
||||
gui_app: true,
|
||||
link_args: extra_demo_ldflags)
|
||||
link_args: extra_demo_ldflags,
|
||||
install: true)
|
||||
|
||||
# desktop file
|
||||
install_data('org.gtk.PrintEditor4.desktop', install_dir: gtk_applicationsdir)
|
||||
|
||||
# appdata
|
||||
install_data('org.gtk.PrintEditor4.appdata.xml', install_dir: gtk_appdatadir)
|
||||
|
||||
34
demos/print-editor/org.gtk.PrintEditor4.appdata.xml
Normal file
34
demos/print-editor/org.gtk.PrintEditor4.appdata.xml
Normal file
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component type="desktop">
|
||||
<id>org.gtk.PrintEditor4.desktop</id>
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<project_license>LGPL-2.0+</project_license>
|
||||
<name>GTK Print Editor</name>
|
||||
<summary>Program to demonstrate GTK printing</summary>
|
||||
<description>
|
||||
<p>
|
||||
GTK Print Editor is a simple editor to demonstrate GTK printing.
|
||||
</p>
|
||||
</description>
|
||||
<screenshots>
|
||||
<screenshot>
|
||||
<image>https://static.gnome.org/appdata/gtk4-print-editor/gtk-print-editor1.png</image>
|
||||
<caption>Print Editor</caption>
|
||||
</screenshot>
|
||||
</screenshots>
|
||||
<kudos>
|
||||
<kudo>HiDpiIcon</kudo>
|
||||
<kudo>ModernToolkit</kudo>
|
||||
</kudos>
|
||||
<url type="homepage">https://www.gtk.org</url>
|
||||
<translation type="gettext">gtk-4.0</translation>
|
||||
<update_contact>matthias.clasen_at_gmail.com</update_contact>
|
||||
<developer_name>Matthias Clasen and others</developer_name>
|
||||
<releases>
|
||||
<release version="3.99.0" date="2020">
|
||||
<description>
|
||||
<p>A new developers snapshot towards GTK 4.0.</p>
|
||||
</description>
|
||||
</release>
|
||||
</releases>
|
||||
</component>
|
||||
10
demos/print-editor/org.gtk.PrintEditor4.desktop
Normal file
10
demos/print-editor/org.gtk.PrintEditor4.desktop
Normal file
@@ -0,0 +1,10 @@
|
||||
[Desktop Entry]
|
||||
Name=Print Editor
|
||||
Comment=A simple editor demonstrating GTK printing
|
||||
Exec=gtk4-print-editor %f
|
||||
Icon=text-editor-symbolic
|
||||
Terminal=false
|
||||
Type=Application
|
||||
StartupNotify=true
|
||||
Categories=Development;GTK;
|
||||
NoDisplay=true
|
||||
@@ -23,7 +23,7 @@ update_title (GtkWindow *window)
|
||||
else
|
||||
basename = g_file_get_basename (filename);
|
||||
|
||||
title = g_strdup_printf ("Simple Editor with printing - %s", basename);
|
||||
title = g_strdup_printf ("GTK Print Editor — %s", basename);
|
||||
g_free (basename);
|
||||
|
||||
gtk_window_set_title (window, title);
|
||||
@@ -592,18 +592,54 @@ activate_about (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
const gchar *authors[] = {
|
||||
"Alexander Larsson",
|
||||
NULL
|
||||
};
|
||||
char *version;
|
||||
GString *sysinfo;
|
||||
char *setting;
|
||||
char **backends;
|
||||
int i;
|
||||
|
||||
sysinfo = g_string_new ("System libraries\n");
|
||||
g_string_append_printf (sysinfo, "\tGLib\t%d.%d.%d\n",
|
||||
glib_major_version,
|
||||
glib_minor_version,
|
||||
glib_micro_version);
|
||||
g_string_append_printf (sysinfo, "\tPango\t%s\n",
|
||||
pango_version_string ());
|
||||
g_string_append_printf (sysinfo, "\tGTK\t%d.%d.%d\n",
|
||||
gtk_get_major_version (),
|
||||
gtk_get_minor_version (),
|
||||
gtk_get_micro_version ());
|
||||
|
||||
g_string_append (sysinfo, "\nPrint backends\n");
|
||||
|
||||
g_object_get (gtk_settings_get_default (), "gtk-print-backends", &setting, NULL);
|
||||
backends = g_strsplit (setting, ",", -1);
|
||||
for (i = 0; backends[i]; i++)
|
||||
g_string_append_printf (sysinfo, "\t%s\n", backends[i]);
|
||||
g_strfreev (backends);
|
||||
g_free (setting);
|
||||
|
||||
version = g_strdup_printf ("%s\nRunning against GTK %d.%d.%d",
|
||||
PACKAGE_VERSION,
|
||||
gtk_get_major_version (),
|
||||
gtk_get_minor_version (),
|
||||
gtk_get_micro_version ());
|
||||
|
||||
gtk_show_about_dialog (GTK_WINDOW (main_window),
|
||||
"name", "Print Test Editor",
|
||||
"logo-icon-name", "text-editor-symbolic",
|
||||
"version", PACKAGE_VERSION,
|
||||
"program-name", "GTK Print Editor",
|
||||
"version", version,
|
||||
"copyright", "© 2006-2020 Red Hat, Inc",
|
||||
"comments", "Program to demonstrate GTK printing.",
|
||||
"authors", authors,
|
||||
"license-type", GTK_LICENSE_LGPL_2_1,
|
||||
"website", "http://www.gtk.org",
|
||||
"comments", "Program to demonstrate GTK printing",
|
||||
"authors", (const char *[]){ "Alexander Larsson", NULL },
|
||||
"logo-icon-name", "text-editor-symbolic",
|
||||
"title", "About GTK Print Editor",
|
||||
"system-information", sysinfo->str,
|
||||
NULL);
|
||||
|
||||
g_string_free (sysinfo, TRUE);
|
||||
g_free (version);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -643,23 +679,6 @@ static const gchar ui_info[] =
|
||||
"<interface>"
|
||||
" <menu id='menubar'>"
|
||||
" <submenu>"
|
||||
" <attribute name='label'>_Application</attribute>"
|
||||
" <section>"
|
||||
" <item>"
|
||||
" <attribute name='label'>_About</attribute>"
|
||||
" <attribute name='action'>app.about</attribute>"
|
||||
" <attribute name='accel'><Primary>a</attribute>"
|
||||
" </item>"
|
||||
" </section>"
|
||||
" <section>"
|
||||
" <item>"
|
||||
" <attribute name='label'>_Quit</attribute>"
|
||||
" <attribute name='action'>app.quit</attribute>"
|
||||
" <attribute name='accel'><Primary>q</attribute>"
|
||||
" </item>"
|
||||
" </section>"
|
||||
" </submenu>"
|
||||
" <submenu>"
|
||||
" <attribute name='label'>_File</attribute>"
|
||||
" <section>"
|
||||
" <item>"
|
||||
@@ -696,6 +715,23 @@ static const gchar ui_info[] =
|
||||
" <attribute name='action'>app.print</attribute>"
|
||||
" </item>"
|
||||
" </section>"
|
||||
" <section>"
|
||||
" <item>"
|
||||
" <attribute name='label'>_Quit</attribute>"
|
||||
" <attribute name='action'>app.quit</attribute>"
|
||||
" <attribute name='accel'><Primary>q</attribute>"
|
||||
" </item>"
|
||||
" </section>"
|
||||
" </submenu>"
|
||||
" <submenu>"
|
||||
" <attribute name='label'>_Help</attribute>"
|
||||
" <section>"
|
||||
" <item>"
|
||||
" <attribute name='label'>_About Print Editor</attribute>"
|
||||
" <attribute name='action'>app.about</attribute>"
|
||||
" <attribute name='accel'><Primary>a</attribute>"
|
||||
" </item>"
|
||||
" </section>"
|
||||
" </submenu>"
|
||||
" </menu>"
|
||||
"</interface>";
|
||||
@@ -716,25 +752,6 @@ mark_set_callback (GtkTextBuffer *text_buffer,
|
||||
update_statusbar ();
|
||||
}
|
||||
|
||||
static gint
|
||||
command_line (GApplication *application,
|
||||
GApplicationCommandLine *command_line)
|
||||
{
|
||||
int argc;
|
||||
char **argv;
|
||||
|
||||
argv = g_application_command_line_get_arguments (command_line, &argc);
|
||||
|
||||
if (argc == 2)
|
||||
{
|
||||
GFile *file = g_file_new_for_commandline_arg (argv[1]);
|
||||
load_file (file);
|
||||
g_object_unref (file);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
startup (GApplication *app)
|
||||
{
|
||||
@@ -768,7 +785,7 @@ activate (GApplication *app)
|
||||
gtk_window_set_child (GTK_WINDOW (main_window), box);
|
||||
|
||||
/* Create document */
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
sw = gtk_scrolled_window_new ();
|
||||
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
@@ -809,6 +826,20 @@ activate (GApplication *app)
|
||||
gtk_widget_show (main_window);
|
||||
}
|
||||
|
||||
static void
|
||||
open (GApplication *application,
|
||||
GFile **files,
|
||||
int n_files,
|
||||
const char *hint)
|
||||
{
|
||||
if (n_files > 1)
|
||||
g_warning ("Can only open a single file");
|
||||
|
||||
activate (application);
|
||||
|
||||
load_file (files[0]);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
@@ -832,7 +863,7 @@ main (int argc, char **argv)
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
app = gtk_application_new ("org.gtk.PrintEditor", 0);
|
||||
app = gtk_application_new ("org.gtk.PrintEditor4", G_APPLICATION_HANDLES_OPEN);
|
||||
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (app),
|
||||
app_entries, G_N_ELEMENTS (app_entries),
|
||||
@@ -840,7 +871,7 @@ main (int argc, char **argv)
|
||||
|
||||
g_signal_connect (app, "startup", G_CALLBACK (startup), NULL);
|
||||
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
|
||||
g_signal_connect (app, "command-line", G_CALLBACK (command_line), NULL);
|
||||
g_signal_connect (app, "open", G_CALLBACK (open), NULL);
|
||||
|
||||
g_application_run (G_APPLICATION (app), argc, argv);
|
||||
|
||||
|
||||
@@ -408,6 +408,8 @@ activate_print (GSimpleAction *action,
|
||||
g_signal_connect (op, "draw-page", G_CALLBACK (print_operation_page), window);
|
||||
g_signal_connect (op, "done", G_CALLBACK (print_operation_done), NULL);
|
||||
|
||||
gtk_print_operation_set_embed_page_setup (op, TRUE);
|
||||
|
||||
res = gtk_print_operation_run (op, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG, window, NULL);
|
||||
|
||||
if (res == GTK_PRINT_OPERATION_RESULT_IN_PROGRESS)
|
||||
|
||||
@@ -93,7 +93,6 @@ gdk_display_get_clipboard
|
||||
gdk_display_get_primary_clipboard
|
||||
gdk_display_get_setting
|
||||
gdk_display_get_startup_notification_id
|
||||
gdk_display_setup_window_visual
|
||||
|
||||
<SUBSECTION>
|
||||
gdk_display_put_event
|
||||
@@ -208,8 +207,6 @@ GdkModifierType
|
||||
GDK_MODIFIER_MASK
|
||||
|
||||
<SUBSECTION>
|
||||
gdk_surface_get_support_multidevice
|
||||
gdk_surface_set_support_multidevice
|
||||
gdk_surface_get_device_cursor
|
||||
gdk_surface_set_device_cursor
|
||||
|
||||
@@ -358,17 +355,13 @@ gdk_device_get_name
|
||||
gdk_device_get_vendor_id
|
||||
gdk_device_get_product_id
|
||||
gdk_device_get_source
|
||||
gdk_device_set_key
|
||||
gdk_device_get_key
|
||||
gdk_device_set_axis_use
|
||||
gdk_device_get_axis_use
|
||||
gdk_device_get_associated_device
|
||||
gdk_device_list_slave_devices
|
||||
gdk_device_list_physical_devices
|
||||
gdk_device_get_device_type
|
||||
gdk_device_get_display
|
||||
gdk_device_get_has_cursor
|
||||
gdk_device_get_n_axes
|
||||
gdk_device_get_n_keys
|
||||
gdk_device_get_axes
|
||||
gdk_device_get_seat
|
||||
gdk_device_get_num_touches
|
||||
@@ -383,13 +376,8 @@ gdk_device_has_bidi_layouts
|
||||
<SUBSECTION>
|
||||
gdk_device_get_state
|
||||
gdk_device_get_surface_at_position
|
||||
gdk_device_get_history
|
||||
gdk_device_free_history
|
||||
GdkTimeCoord
|
||||
gdk_device_get_axis
|
||||
gdk_device_get_axis_names
|
||||
gdk_device_get_axis_value
|
||||
gdk_device_get_last_event_surface
|
||||
|
||||
<SUBSECTION>
|
||||
gdk_device_tool_get_serial
|
||||
@@ -450,8 +438,7 @@ gdk_seat_get_display
|
||||
gdk_seat_get_capabilities
|
||||
gdk_seat_get_pointer
|
||||
gdk_seat_get_keyboard
|
||||
gdk_seat_get_slaves
|
||||
gdk_seat_get_master_pointers
|
||||
gdk_seat_get_physical_devices
|
||||
|
||||
<SUBSECTION Standard>
|
||||
GDK_SEAT
|
||||
@@ -495,13 +482,16 @@ gdk_event_get_source_device
|
||||
gdk_event_get_device_tool
|
||||
gdk_event_get_time
|
||||
gdk_event_get_display
|
||||
gdk_event_get_seat
|
||||
GdkEventSequence
|
||||
gdk_event_get_event_sequence
|
||||
gdk_event_get_modifier_state
|
||||
gdk_event_get_position
|
||||
gdk_event_get_axes
|
||||
gdk_event_get_axis
|
||||
gdk_event_get_history
|
||||
gdk_event_get_pointer_emulated
|
||||
gdk_event_triggers_context_menu
|
||||
gdk_button_event_get_button
|
||||
gdk_scroll_event_get_direction
|
||||
gdk_scroll_event_get_deltas
|
||||
@@ -520,6 +510,7 @@ gdk_crossing_event_get_mode
|
||||
gdk_crossing_event_get_detail
|
||||
gdk_crossing_event_get_focus
|
||||
gdk_grab_broken_event_get_grab_surface
|
||||
gdk_grab_broken_event_get_implicit
|
||||
gdk_dnd_event_get_drop
|
||||
gdk_configure_event_get_size
|
||||
gdk_touchpad_event_get_gesture_phase
|
||||
@@ -530,7 +521,6 @@ gdk_touchpad_event_get_pinch_scale
|
||||
gdk_pad_event_get_axis_value
|
||||
gdk_pad_event_get_button
|
||||
gdk_pad_event_get_group_mode
|
||||
gdk_motion_event_get_history
|
||||
|
||||
<SUBSECTION>
|
||||
gdk_events_get_angle
|
||||
@@ -545,8 +535,23 @@ GDK_TYPE_CROSSING_MODE
|
||||
GDK_TYPE_SCROLL_DIRECTION
|
||||
GDK_TYPE_NOTIFY_TYPE
|
||||
GDK_IS_EVENT
|
||||
|
||||
gdk_event_get_type
|
||||
gdk_event_sequence_get_type
|
||||
gdk_button_event_get_type
|
||||
gdk_configure_event_get_type
|
||||
gdk_crossing_event_get_type
|
||||
gdk_delete_event_get_type
|
||||
gdk_dnd_event_get_type
|
||||
gdk_focus_event_get_type
|
||||
gdk_grab_broken_event_get_type
|
||||
gdk_key_event_get_type
|
||||
gdk_motion_event_get_type
|
||||
gdk_pad_event_get_type
|
||||
gdk_proximity_event_get_type
|
||||
gdk_scroll_event_get_type
|
||||
gdk_touch_event_get_type
|
||||
gdk_touchpad_event_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
|
||||
@@ -27,15 +27,19 @@ private_headers = [
|
||||
'gdkmonitorprivate.h',
|
||||
'gdkmemorytextureprivate.h',
|
||||
'gdkpipeiostreamprivate.h',
|
||||
'gdkpopupprivate.h',
|
||||
'gdkprofilerprivate.h',
|
||||
'gdkscreenprivate.h',
|
||||
'gdkseatdefaultprivate.h',
|
||||
'gdkseatprivate.h',
|
||||
'gdksnapshotprivate.h',
|
||||
'gdksurfaceimpl.h',
|
||||
'gdksurfaceprivate.h',
|
||||
'gdktextureprivate.h',
|
||||
'gdktoplevelprivate.h',
|
||||
'gdkvulkancontextprivate.h',
|
||||
'keyname-table.h',
|
||||
'gdkprivate-x11.h',
|
||||
'x11/gdkprivate-x11.h',
|
||||
'x11/gdkeventsource.h',
|
||||
'gtk-primary-selection-client-protocol.h',
|
||||
'gtk-shell-client-protocol.h',
|
||||
|
||||
@@ -236,7 +236,6 @@ gsk_transform_to_translate
|
||||
gsk_transform_transform
|
||||
gsk_transform_invert
|
||||
gsk_transform_matrix
|
||||
gsk_transform_matrix_with_category
|
||||
gsk_transform_translate
|
||||
gsk_transform_translate_3d
|
||||
gsk_transform_rotate
|
||||
|
||||
@@ -9,9 +9,11 @@ private_headers = [
|
||||
'gskprofilerprivate.h',
|
||||
'gskrendererprivate.h',
|
||||
'gskrendernodeprivate.h',
|
||||
'gskrendernodeparserprivate.h',
|
||||
'gskroundedrectprivate.h',
|
||||
'gskshaderbuilderprivate.h',
|
||||
'gsktextureprivate.h',
|
||||
'gsktransformprivate.h',
|
||||
'gskvulkanblendpipelineprivate.h',
|
||||
'gskvulkanborderpipelineprivate.h',
|
||||
'gskvulkanboxshadowpipelineprivate.h',
|
||||
|
||||
@@ -37,7 +37,7 @@ this range will trigger compiler warnings.
|
||||
Here is how you would compile hello.c if you want to allow it
|
||||
to use symbols that were not deprecated in 4.2:
|
||||
```
|
||||
$ cc `pkg-config --cflags gtk4` -DGDK_VERSION_MIN_REQIRED=GDK_VERSION_4_2 hello.c -o hello `pkg-config --libs gtk4`
|
||||
$ cc `pkg-config --cflags gtk4` -DGDK_VERSION_MIN_REQUIRED=GDK_VERSION_4_2 hello.c -o hello `pkg-config --libs gtk4`
|
||||
```
|
||||
|
||||
And here is how you would compile hello.c if you don't want
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
|
||||
<chapter id="Lists">
|
||||
<title>GListModel support</title>
|
||||
<xi:include href="xml/gtkbitset.xml" />
|
||||
<xi:include href="xml/gtkexpression.xml" />
|
||||
<xi:include href="xml/gtkfilterlistmodel.xml" />
|
||||
<section>
|
||||
@@ -68,9 +69,14 @@
|
||||
<xi:include href="xml/gtkmultisorter.xml" />
|
||||
</section>
|
||||
<xi:include href="xml/gtkselectionmodel.xml" />
|
||||
<xi:include href="xml/gtknoselection.xml" />
|
||||
<xi:include href="xml/gtksingleselection.xml" />
|
||||
<section>
|
||||
<xi:include href="xml/gtknoselection.xml" />
|
||||
<xi:include href="xml/gtksingleselection.xml" />
|
||||
<xi:include href="xml/gtkmultiselection.xml" />
|
||||
</section>
|
||||
<xi:include href="xml/gtkbookmarklist.xml" />
|
||||
<xi:include href="xml/gtkdirectorylist.xml" />
|
||||
<xi:include href="xml/gtkstringlist.xml" />
|
||||
</chapter>
|
||||
|
||||
<chapter id="ListContainers">
|
||||
@@ -90,8 +96,11 @@
|
||||
</chapter>
|
||||
|
||||
<chapter id="Trees">
|
||||
<xi:include href="xml/gtktreelistrow.xml" />
|
||||
<title>Tree support</title>
|
||||
<xi:include href="xml/gtktreelistmodel.xml" />
|
||||
<section>
|
||||
<xi:include href="xml/gtktreelistrow.xml" />
|
||||
</section>
|
||||
<xi:include href="xml/gtktreelistrowsorter.xml" />
|
||||
<xi:include href="xml/gtktreeexpander.xml" />
|
||||
</chapter>
|
||||
@@ -120,6 +129,7 @@
|
||||
<xi:include href="xml/gtkaboutdialog.xml" />
|
||||
<xi:include href="xml/gtkassistant.xml" />
|
||||
<xi:include href="xml/gtkwindowgroup.xml" />
|
||||
<xi:include href="xml/gtknativedialog.xml" />
|
||||
</chapter>
|
||||
|
||||
<chapter id="LayoutContainers">
|
||||
@@ -208,6 +218,7 @@
|
||||
<xi:include href="xml/gtkspinbutton.xml" />
|
||||
<xi:include href="xml/gtksearchentry.xml" />
|
||||
<xi:include href="xml/gtksearchbar.xml" />
|
||||
<xi:include href="xml/gtkeditablelabel.xml" />
|
||||
</chapter>
|
||||
|
||||
<chapter id="TextWidgetObjects">
|
||||
|
||||
@@ -312,6 +312,8 @@ gtk_list_box_bind_model
|
||||
gtk_list_box_row_new
|
||||
gtk_list_box_row_changed
|
||||
gtk_list_box_row_is_selected
|
||||
gtk_list_box_row_get_child
|
||||
gtk_list_box_row_set_child
|
||||
gtk_list_box_row_get_header
|
||||
gtk_list_box_row_set_header
|
||||
gtk_list_box_row_get_index
|
||||
@@ -339,18 +341,69 @@ gtk_list_box_get_type
|
||||
gtk_list_box_row_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkbitset</FILE>
|
||||
<TITLE>GtkBitset</TITLE>
|
||||
GtkBitset
|
||||
gtk_bitset_ref
|
||||
gtk_bitset_unref
|
||||
gtk_bitset_new_empty
|
||||
gtk_bitset_new_range
|
||||
gtk_bitset_copy
|
||||
<SUBSECTION>
|
||||
gtk_bitset_contains
|
||||
gtk_bitset_is_empty
|
||||
gtk_bitset_equals
|
||||
gtk_bitset_get_minimum
|
||||
gtk_bitset_get_maximum
|
||||
gtk_bitset_get_size
|
||||
gtk_bitset_get_size_in_range
|
||||
gtk_bitset_get_nth
|
||||
<SUBSECTION>
|
||||
gtk_bitset_remove_all
|
||||
gtk_bitset_add
|
||||
gtk_bitset_remove
|
||||
gtk_bitset_add_range
|
||||
gtk_bitset_remove_range
|
||||
gtk_bitset_add_range_closed
|
||||
gtk_bitset_remove_range_closed
|
||||
gtk_bitset_add_rectangle
|
||||
gtk_bitset_remove_rectangle
|
||||
gtk_bitset_union
|
||||
gtk_bitset_intersect
|
||||
gtk_bitset_subtract
|
||||
gtk_bitset_difference
|
||||
gtk_bitset_shift_left
|
||||
gtk_bitset_shift_right
|
||||
gtk_bitset_slice
|
||||
<SUBSECTION>
|
||||
GtkBitsetIter
|
||||
gtk_bitset_iter_init_first
|
||||
gtk_bitset_iter_init_last
|
||||
gtk_bitset_iter_init_at
|
||||
gtk_bitset_iter_next
|
||||
gtk_bitset_iter_previous
|
||||
gtk_bitset_iter_get_value
|
||||
gtk_bitset_iter_is_valid
|
||||
<SUBSECTION Private>
|
||||
GTK_TYPE_BITSET
|
||||
gtk_bitset_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkselectionmodel</FILE>
|
||||
<TITLE>GtkSelectionModel</TITLE>
|
||||
GtkSelectionModel
|
||||
gtk_selection_model_is_selected
|
||||
gtk_selection_model_get_selection
|
||||
gtk_selection_model_get_selection_in_range
|
||||
gtk_selection_model_select_item
|
||||
gtk_selection_model_unselect_item
|
||||
gtk_selection_model_select_range
|
||||
gtk_selection_model_unselect_range
|
||||
gtk_selection_model_select_all
|
||||
gtk_selection_model_unselect_all
|
||||
gtk_selection_model_query_range
|
||||
gtk_selection_model_set_selection
|
||||
<SUBSECTION>
|
||||
gtk_selection_model_selection_changed
|
||||
<SUBSECTION Standard>
|
||||
@@ -392,6 +445,15 @@ gtk_single_selection_set_can_unselect
|
||||
gtk_single_selection_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkmultiselection</FILE>
|
||||
<TITLE>GtkMultiSeledction</TITLE>
|
||||
GtkMultiSelection
|
||||
gtk_multi_selection_new
|
||||
<SUBSECTION Private>
|
||||
gtk_multi_selection_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtklistitem</FILE>
|
||||
<TITLE>GtkListItem</TITLE>
|
||||
@@ -403,6 +465,8 @@ gtk_list_item_set_child
|
||||
gtk_list_item_get_selected
|
||||
gtk_list_item_get_selectable
|
||||
gtk_list_item_set_selectable
|
||||
gtk_list_item_get_activatable
|
||||
gtk_list_item_set_activatable
|
||||
<SUBSECTION Standard>
|
||||
GTK_LIST_ITEM
|
||||
GTK_LIST_ITEM_CLASS
|
||||
@@ -479,6 +543,8 @@ gtk_list_view_set_show_separators
|
||||
gtk_list_view_get_show_separators
|
||||
gtk_list_view_set_single_click_activate
|
||||
gtk_list_view_get_single_click_activate
|
||||
gtk_list_view_set_enable_rubberband
|
||||
gtk_list_view_get_enable_rubberband
|
||||
<SUBSECTION Standard>
|
||||
GTK_LIST_VIEW
|
||||
GTK_LIST_VIEW_CLASS
|
||||
@@ -496,16 +562,23 @@ gtk_list_view_get_type
|
||||
GtkColumnView
|
||||
gtk_column_view_new
|
||||
gtk_column_view_append_column
|
||||
gtk_column_view_insert_column
|
||||
gtk_column_view_remove_column
|
||||
gtk_column_view_get_columns
|
||||
gtk_column_view_get_model
|
||||
gtk_column_view_set_model
|
||||
gtk_column_view_get_sorter
|
||||
gtk_column_view_get_show_separators
|
||||
gtk_column_view_set_show_separators
|
||||
gtk_column_view_get_show_row_separators
|
||||
gtk_column_view_set_show_row_separators
|
||||
gtk_column_view_get_show_column_separators
|
||||
gtk_column_view_set_show_column_separators
|
||||
gtk_column_view_sort_by_column
|
||||
gtk_column_view_set_single_click_activate
|
||||
gtk_column_view_get_single_click_activate
|
||||
gtk_column_view_set_reorderable
|
||||
gtk_column_view_get_reorderable
|
||||
gtk_column_view_set_enable_rubberband
|
||||
gtk_column_view_get_enable_rubberband
|
||||
<SUBSECTION Standard>
|
||||
GTK_COLUMN_VIEW
|
||||
GTK_COLUMN_VIEW_CLASS
|
||||
@@ -530,6 +603,17 @@ gtk_column_view_column_set_title
|
||||
gtk_column_view_column_get_title
|
||||
gtk_column_view_column_set_sorter
|
||||
gtk_column_view_column_get_sorter
|
||||
gtk_column_view_column_set_visible
|
||||
gtk_column_view_column_get_visible
|
||||
gtk_column_view_column_set_resizable
|
||||
gtk_column_view_column_get_resizable
|
||||
gtk_column_view_column_set_header_menu
|
||||
gtk_column_view_column_get_header_menu
|
||||
gtk_column_view_column_set_fixed_width
|
||||
gtk_column_view_column_get_fixed_width
|
||||
gtk_column_view_column_set_expand
|
||||
gtk_column_view_column_get_expand
|
||||
|
||||
<SUBSECTION Standard>
|
||||
GTK_COLUMN_VIEW_COLUMN
|
||||
GTK_COLUMN_VIEW_COLUMN_CLASS
|
||||
@@ -546,6 +630,7 @@ gtk_column_view_column_get_type
|
||||
<TITLE>GtkGridView</TITLE>
|
||||
GtkGridView
|
||||
gtk_grid_view_new
|
||||
gtk_grid_view_new_with_factory
|
||||
gtk_grid_view_set_model
|
||||
gtk_grid_view_get_model
|
||||
gtk_grid_view_set_max_columns
|
||||
@@ -554,6 +639,10 @@ gtk_grid_view_set_min_columns
|
||||
gtk_grid_view_get_min_columns
|
||||
gtk_grid_view_set_single_click_activate
|
||||
gtk_grid_view_get_single_click_activate
|
||||
gtk_grid_view_set_enable_rubberband
|
||||
gtk_grid_view_get_enable_rubberband
|
||||
gtk_grid_view_set_factory
|
||||
gtk_grid_view_get_factory
|
||||
<SUBSECTION Standard>
|
||||
GTK_GRID_VIEW
|
||||
GTK_GRID_VIEW_CLASS
|
||||
@@ -937,6 +1026,18 @@ GTK_EDITABLE_GET_IFACE
|
||||
gtk_editable_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkeditablelabel</FILE>
|
||||
<TITLE>GtkEditableLabel</TITLE>
|
||||
GtkEditableLabel
|
||||
gtk_editable_label_new
|
||||
gtk_editable_label_get_editing
|
||||
gtk_editable_label_start_editing
|
||||
gtk_editable_label_stop_editing
|
||||
<SUBSECTION Private>
|
||||
gtk_editable_label_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtktext</FILE>
|
||||
<TITLE>GtkText</TITLE>
|
||||
@@ -1357,6 +1458,21 @@ GTK_DIRECTORY_LIST_GET_CLASS
|
||||
gtk_directory_list_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkbookmarklist</FILE>
|
||||
<TITLE>GtkBookmarkList</TITLE>
|
||||
GtkBookmarkList
|
||||
gtk_bookmark_list_new
|
||||
gtk_bookmark_list_get_filename
|
||||
gtk_bookmark_list_set_attributes
|
||||
gtk_bookmark_list_get_attributes
|
||||
gtk_bookmark_list_set_io_priority
|
||||
gtk_bookmark_list_get_io_priority
|
||||
gtk_bookmark_list_is_loading
|
||||
<SUBSECTION Standard>
|
||||
GTK_TYPE_BOOKMARK_LIST
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkfilter</FILE>
|
||||
<TITLE>GtkFilter</TITLE>
|
||||
@@ -1366,8 +1482,6 @@ gtk_filter_get_strictness
|
||||
<SUBSECTION>
|
||||
GtkFilterChange
|
||||
gtk_filter_changed
|
||||
<SUBSECTION>
|
||||
gtk_custom_filter_new
|
||||
<SUBSECTION Standard>
|
||||
GTK_FILTER
|
||||
GTK_IS_FILTER
|
||||
@@ -1385,6 +1499,7 @@ gtk_filter_get_type
|
||||
GtkCustomFilter
|
||||
GtkCustomFilterFunc
|
||||
gtk_custom_filter_new
|
||||
gtk_custom_filter_set_filter_func
|
||||
<SUBSECTION Standard>
|
||||
GTK_CUSTOM_FILTER
|
||||
GTK_IS_CUSTOM_FILTER
|
||||
@@ -1423,13 +1538,15 @@ gtk_custom_filter_get_type
|
||||
<FILE>gtkfilterlistmodel</FILE>
|
||||
<TITLE>GtkFilterListModel</TITLE>
|
||||
GtkFilterListModel
|
||||
GtkFilterListModelFilterFunc
|
||||
gtk_filter_list_model_new
|
||||
gtk_filter_list_model_new_for_type
|
||||
gtk_filter_list_model_set_model
|
||||
gtk_filter_list_model_get_model
|
||||
gtk_filter_list_model_set_filter
|
||||
gtk_filter_list_model_get_filter
|
||||
gtk_filter_list_model_set_incremental
|
||||
gtk_filter_list_model_get_incremental
|
||||
gtk_filter_list_model_get_pending
|
||||
<SUBSECTION Standard>
|
||||
GTK_FILTER_LIST_MODEL
|
||||
GTK_IS_FILTER_LIST_MODEL
|
||||
@@ -1449,6 +1566,9 @@ gtk_fixed_new
|
||||
gtk_fixed_put
|
||||
gtk_fixed_remove
|
||||
gtk_fixed_move
|
||||
gtk_fixed_get_child_position
|
||||
gtk_fixed_get_child_transform
|
||||
gtk_fixed_set_child_transform
|
||||
<SUBSECTION Standard>
|
||||
GTK_FIXED
|
||||
GTK_IS_FIXED
|
||||
@@ -2013,7 +2133,7 @@ gtk_info_bar_get_type
|
||||
<SECTION>
|
||||
<FILE>gtknativedialog</FILE>
|
||||
<TITLE>GtkNativeDialog</TITLE>
|
||||
GTK_TYPE_NATIVE_DIALOG
|
||||
GtkNativeDialog
|
||||
GtkNativeDialogClass
|
||||
gtk_native_dialog_show
|
||||
gtk_native_dialog_hide
|
||||
@@ -2025,9 +2145,8 @@ gtk_native_dialog_set_title
|
||||
gtk_native_dialog_get_title
|
||||
gtk_native_dialog_set_transient_for
|
||||
gtk_native_dialog_get_transient_for
|
||||
<SUBSECTION Standard>
|
||||
GtkNativeDialog
|
||||
<SUBSECTION Private>
|
||||
GTK_TYPE_NATIVE_DIALOG
|
||||
gtk_native_dialog_get_type
|
||||
</SECTION>
|
||||
|
||||
@@ -2101,12 +2220,18 @@ GtkNotebookPrivate
|
||||
<TITLE>GtkPaned</TITLE>
|
||||
GtkPaned
|
||||
gtk_paned_new
|
||||
gtk_paned_add1
|
||||
gtk_paned_add2
|
||||
gtk_paned_pack1
|
||||
gtk_paned_pack2
|
||||
gtk_paned_get_child1
|
||||
gtk_paned_get_child2
|
||||
gtk_paned_set_start_child
|
||||
gtk_paned_get_start_child
|
||||
gtk_paned_set_end_child
|
||||
gtk_paned_get_end_child
|
||||
gtk_paned_set_resize_start_child
|
||||
gtk_paned_get_resize_start_child
|
||||
gtk_paned_set_resize_end_child
|
||||
gtk_paned_get_resize_end_child
|
||||
gtk_paned_set_shrink_start_child
|
||||
gtk_paned_get_shrink_start_child
|
||||
gtk_paned_set_shrink_end_child
|
||||
gtk_paned_get_shrink_end_child
|
||||
gtk_paned_set_position
|
||||
gtk_paned_get_position
|
||||
gtk_paned_set_wide_handle
|
||||
@@ -2657,6 +2782,8 @@ gtk_numeric_sorter_get_type
|
||||
<TITLE>GtkCustomSorter</TITLE>
|
||||
GtkCustomSorter
|
||||
gtk_custom_sorter_new
|
||||
|
||||
gtk_custom_sorter_set_sort_func
|
||||
<SUBSECTION Standard>
|
||||
GTK_CUSTOM_SORTER
|
||||
GTK_IS_CUSTOM_SORTER
|
||||
@@ -4425,11 +4552,8 @@ gtk_widget_has_visible_focus
|
||||
gtk_widget_is_drawable
|
||||
gtk_widget_set_receives_default
|
||||
gtk_widget_get_receives_default
|
||||
gtk_widget_set_support_multidevice
|
||||
gtk_widget_get_support_multidevice
|
||||
gtk_widget_get_realized
|
||||
gtk_widget_get_mapped
|
||||
gtk_widget_device_is_shadowed
|
||||
gtk_widget_get_opacity
|
||||
gtk_widget_set_opacity
|
||||
gtk_widget_get_overflow
|
||||
@@ -5984,6 +6108,16 @@ gtk_header_bar_get_type
|
||||
GtkStackPage
|
||||
gtk_stack_page_get_visible
|
||||
gtk_stack_page_set_visible
|
||||
gtk_stack_page_get_title
|
||||
gtk_stack_page_set_title
|
||||
gtk_stack_page_get_name
|
||||
gtk_stack_page_set_name
|
||||
gtk_stack_page_get_needs_attention
|
||||
gtk_stack_page_set_needs_attention
|
||||
gtk_stack_page_get_use_underline
|
||||
gtk_stack_page_set_use_underline
|
||||
gtk_stack_page_get_icon_name
|
||||
gtk_stack_page_set_icon_name
|
||||
gtk_stack_page_get_child
|
||||
GtkStack
|
||||
gtk_stack_new
|
||||
@@ -7454,6 +7588,7 @@ gtk_drop_down_set_model
|
||||
gtk_drop_down_get_model
|
||||
gtk_drop_down_set_selected
|
||||
gtk_drop_down_get_selected
|
||||
gtk_drop_down_get_selected_item
|
||||
gtk_drop_down_set_factory
|
||||
gtk_drop_down_get_factory
|
||||
gtk_drop_down_set_list_factory
|
||||
@@ -7467,3 +7602,17 @@ GTK_TYPE_DROP_DOWN
|
||||
<SUBSECTION Private>
|
||||
gtk_drop_down_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkstringlist</FILE>
|
||||
<TITLE>GtkStringList</TITLE>
|
||||
GtkStringList
|
||||
gtk_string_list_new
|
||||
gtk_string_list_append
|
||||
gtk_string_list_take
|
||||
gtk_string_list_remove
|
||||
gtk_string_list_splice
|
||||
gtk_string_list_get_string
|
||||
GtkStringObject
|
||||
gtk_string_object_get_string
|
||||
</SECTION>
|
||||
|
||||
@@ -18,6 +18,8 @@ gtk_aspect_frame_get_type
|
||||
gtk_assistant_get_type
|
||||
gtk_assistant_page_get_type
|
||||
gtk_bin_layout_get_type
|
||||
gtk_bitset_get_type
|
||||
gtk_bookmark_list_get_type
|
||||
gtk_box_get_type
|
||||
gtk_box_layout_get_type
|
||||
gtk_buildable_get_type
|
||||
@@ -68,6 +70,7 @@ gtk_drop_target_get_type
|
||||
gtk_drop_target_async_get_type
|
||||
gtk_drop_down_get_type
|
||||
gtk_editable_get_type
|
||||
gtk_editable_label_get_type
|
||||
gtk_emoji_chooser_get_type
|
||||
gtk_entry_buffer_get_type
|
||||
gtk_entry_completion_get_type
|
||||
@@ -139,6 +142,7 @@ gtk_menu_button_get_type
|
||||
gtk_message_dialog_get_type
|
||||
gtk_mount_operation_get_type
|
||||
gtk_multi_filter_get_type
|
||||
gtk_multi_selection_get_type
|
||||
gtk_multi_sorter_get_type
|
||||
gtk_native_get_type
|
||||
gtk_native_dialog_get_type
|
||||
@@ -206,6 +210,8 @@ gtk_stack_sidebar_get_type
|
||||
gtk_stack_switcher_get_type
|
||||
gtk_statusbar_get_type
|
||||
gtk_string_filter_get_type
|
||||
gtk_string_list_get_type
|
||||
gtk_string_object_get_type
|
||||
gtk_string_sorter_get_type
|
||||
gtk_switch_get_type
|
||||
gtk_level_bar_get_type
|
||||
|
||||
@@ -5,7 +5,7 @@ in what happens to translate a key press or mouse motion of the users into a
|
||||
change of a GTK widget, you should read this chapter. This knowledge will also
|
||||
be useful if you decide to implement your own widgets.
|
||||
|
||||
Devices and events
|
||||
## Devices and events
|
||||
|
||||
The most basic input devices that every computer user has interacted with are
|
||||
keyboards and mice; beyond these, GTK supports touchpads, touchscreens and
|
||||
@@ -13,14 +13,14 @@ more exotic input devices such as graphics tablets. Inside GTK, every such
|
||||
input device is represented by a #GdkDevice object.
|
||||
|
||||
To simplify dealing with the variability between these input devices, GTK
|
||||
has a concept of master and slave devices. The concrete physical devices that
|
||||
has a concept of logical and physical devices. The concrete physical devices that
|
||||
have many different characteristics (mice may have 2 or 3 or 8 buttons,
|
||||
keyboards have different layouts and may or may not have a separate number
|
||||
block, etc) are represented as slave devices. Each slave device is
|
||||
associated with a virtual master device. Master devices always come in
|
||||
block, etc) are represented as physical devices. Each physical device is
|
||||
associated with a virtual logical device. Logical devices always come in
|
||||
pointer/keyboard pairs - you can think of such a pair as a 'seat'.
|
||||
|
||||
GTK widgets generally deal with the master devices, and thus can be used
|
||||
GTK widgets generally deal with the logical devices, and thus can be used
|
||||
with any pointing device or keyboard.
|
||||
|
||||
When a user interacts with an input device (e.g. moves a mouse or presses
|
||||
|
||||
@@ -1,101 +0,0 @@
|
||||
# List widgets
|
||||
|
||||
GTK provides powerful widgets to display and edit lists of data. This document gives an overview over the concepts and how they work together to allow developers to implement lists.
|
||||
|
||||
Lists are intended to be used whenever developers want to display lists of objects in roughly the same way.
|
||||
|
||||
Lists are perfectly fine to be used for very short list of only 2 or 3 elements, but generally scale fine to millions of items. Of course, the larger the list grows, the more care needs to be taken to choose the right data structures to keep things running well.
|
||||
|
||||
Lists are meant to be used with changing data, both with the items itself changing as well as the list adding and removing items. Of course, they work just as well with static data.
|
||||
|
||||
## Terminology
|
||||
|
||||
These terms are used throughout the documentation when talking about lists and you should be aware of what they refer to. These are often generic terms that have a specific meaning in this context.
|
||||
|
||||
**_Views_** or **_list widgets_** are the widgets that hold and manage the lists. Examples of thse widgets would be #GtkListView or #GtkGridView.
|
||||
|
||||
Views display data from a **_model_**. A model is a #GListModel and models can be provided in 3 ways or combinations thereof:
|
||||
|
||||
* Many list models implementations already exist. There are models that provide specific data, like #GtkDirectoryList. And there are models like #GListStore that allow building lists manually.
|
||||
|
||||
* Wrapping list models exists like #GtkFilterListModel or #GtkSortListModel that modify or adapt or combine other models.
|
||||
|
||||
* Last but not least, developers are encouraged to create their own #GListModel implementations. The interface is kept deliberately small to make this easy.
|
||||
|
||||
The same model can be used in multiple different views and wrapped with multiple different models at once.
|
||||
|
||||
The elements in a model are called **_items_**. All items are #GObjects.
|
||||
|
||||
Every item in a model has a **_position_** which is the unsigned integer that describes where in the model the item is located. This position can of course change as items are added or removed from the model.
|
||||
|
||||
It is important to be aware of the difference between items and positions because the mapping from position to item is not permanent, so developers should think about whether they want to track items or positions when working with models. Oftentimes some things are really hard to do one way but very easy the other way.
|
||||
|
||||
The other important part of a view is a **_factory_**. Each factory is a #GtkListItemFactory implementation that takes care of mapping the items of the model to widgets that can be shown in the view.
|
||||
|
||||
The way factories do this is by creating a **_listitem_** for each item that is currently in use. Listitems are always #GtkListItem objects. They are only ever created by GTK and provide information about what item they are meant to display.
|
||||
|
||||
Different factory implementations use various different methods to allow developers to add the right widgets to listitems and to link those widgets with the item managed by the listitem. Finding a suitable factory implementation for the data displayed, the programming language and development environment is an important task that can simplify setting up the view tremendously.
|
||||
|
||||
Views support selections via a **_selection model_**. A selection model is an implementation of the #GtkSelectionModel interface on top of the #GListModel interface that allows marking each item in a model as either selected or not selected. Just like regular models, this can be implemented either by implementing #GtkSelectionModel directly or by wrapping a model with one of the GTK models provided for this purposes, such as #GtkNoSelection or #GtkSingleSelection. The behavior of selection models - ie which items they allow selecting and what effect this has on other items - is completely up to the selection model. As such, single-selections, multi-selections or sharing selection state between different selection models and/or views is possible. The selection state of an item is exposed in the listitem via the GtkListItem:selected property.
|
||||
|
||||
Views and listitems also support activation. Activation means that double clicking or pressing enter while inside a focused row will cause the view to emit and activation signal such as GtkListView::activate. This provides an easy way to set up lists, but can also be turned off on listitems if undesired.
|
||||
|
||||
Both selections and activation are supported among other things via widget actions (FIXME: Link docs). This allows developers to add widgets to their lists that cause selections to change or to trigger activation via the #GtkActionable interface. For a list of all supported actions see the relevant documentation. (FIXME: where do we document actions and how to I link that?)
|
||||
|
||||
## Behind the scenes
|
||||
|
||||
While for short lists it is not a problem to instantiate widgets for every item in the model, once lists grow to thousands or millions of elements, this gets less feasible. Because of this, the views only create a limited amount of listitems and recycle them by binding them to new items. In general, views try to keep listitems available only for the items that can actually be seen on screen.
|
||||
|
||||
While this behavior allows views to scale effortlessly to huge lists, it has a few implication on what can be done with views. For example, it is not possible to query a view for a listitem used for a certain position - there might not be one and even if there is, that listitem might soon be recycled for a new position.
|
||||
|
||||
It is also important that developers save state they care about in the item and do not rely on the widgets they created as those widgets can be recycled for a new position at any time causing any state to be lost.
|
||||
|
||||
Another important requirement for views is that they need to know which items are not visible so they can be recycled. Views achieve that by implementing the #GtkScrollable interface and expecting to be placed directly into a #GtkScrolledWindow.
|
||||
|
||||
Of course, if you are only using models with few items, this is not important and you can treat views like any other widget. But if you use large lists and your performance suffers, you should be aware of this. Views also allow tuning the number of listitems they create such as with gtk_grid_view_set_max_columns(), and developers running into performance problems should definitely study the tradeoffs of those and experiment with them.
|
||||
|
||||
## Displaying trees
|
||||
|
||||
While #GtkTreeView provided builtin support for trees, the list widgets, and in particular #GListModel do not. This was a design choice because the common use case is displaying lists and not trees and it greatly simplifies the API interface provided.
|
||||
|
||||
However, GTK provides functionality to make trees look and behave like lists for the people who still want to display lists. This is achieved by using the #GtkTreeListModel model to flatten a tree into a list. The #GtkTreeExpander widget can then be used inside a listitem to allow users to expand and collapse rows and provide a similar experience to #GtkTreeView.
|
||||
|
||||
Developers should refer to those objects' API reference for more discussion on the topic.
|
||||
|
||||
## comparison to GtkTreeView
|
||||
|
||||
Developers familiar with #GtkTreeView may wonder how this way of doing lists compares to the way they know. This section will try to outline the similarities and differences between the two.
|
||||
|
||||
This new approach tries to provide roughly the same functionality as the old approach but often uses a very different approach to achieve these goals.
|
||||
|
||||
The main difference and one of the primary reasons for this new development is that items can be displayed using regular widgets and #GtkCellRenderer is no longer necessary. This allows all benefits that widgets provide, such as complex layout and animating widgets and not only makes cell renderers obsolete, but also #GtkCellArea.
|
||||
|
||||
The other big difference is the massive change to the data model. #GtkTreeModel was a rather complex interface for a tree data structure and #GListModel was deliberately designed to be a simple data structure for lists only. (See above (FIXME: link) for how to still do trees with this new model.) Another big change is that the new model allows for bulk changes via the #GListModel:items-changed signal while #GtkTreeModel only allows a single item to change at once. The goal here is of course to encourage implementation of custom list models.
|
||||
|
||||
Another consequence of the new model is that it is now easily possible to refer to the contents of a row in the model directly by keeping the item, while #GtkTreeRowReference was a very slow mechanism to achieve the same. And because the items are real objects, developers can make them emit change signals causing listitems and their children to update, which wasn't possible with #GtkTreeModel.
|
||||
|
||||
The selection handling is also different. While selections used to be managed via custom code in each widget, selection state is now meant to be managed by the selection models. In particular this allows for complex use cases with specialized requirements (FIXME: Can I add a shoutout to @mitch here because I vividly remember a huge discussion about GtkTreeView's selection behavior and the Gimp).
|
||||
|
||||
Finally here's a quick list of equivalent functionality to look for when transitioning code for easy lookup:
|
||||
|
||||
| old | new |
|
||||
| ------------------- | ----------------------------------- |
|
||||
| #GtkTreeModel | #GListModel |
|
||||
| #GtkTreePath | #guint position, #GtkTreeListRow |
|
||||
| #GtkTreeIter | #guint position |
|
||||
| GtkTreeRowReference | #GObject item |
|
||||
| #GtkListStore | #GListStore |
|
||||
| #GtkTreeStore | #GtkTreeListModel, #GtkTreeExpander |
|
||||
| #GtkTreeSelection | #GtkSelectionModel |
|
||||
| #GtkTreeViewColumn | #GtkColumnView |
|
||||
| #GtkTreeView | #GtkListView, #GtkColumnView |
|
||||
| #GtkCellView | |
|
||||
| #GtkComboBox | |
|
||||
| #GtkIconView | #GtkGridView |
|
||||
| #GtkTreeSortable | |
|
||||
| #GtkTreeModelSort | #GtkSortListModel |
|
||||
| #GtkTreeModelFilter | #GtkFilterListModel |
|
||||
| #GtkCellLayout | #GtkListItemFactory |
|
||||
| #GtkCellArea | #GtkWidget |
|
||||
| #GtkCellRenderer | #GtkWidget |
|
||||
|
||||
@@ -13,6 +13,7 @@ private_headers = [
|
||||
'gtkappchooserprivate.h',
|
||||
'gtkapplicationaccelsprivate.h',
|
||||
'gtkapplicationprivate.h',
|
||||
'gtkarrayimplprivate.h',
|
||||
'gtkbindingsprivate.h',
|
||||
'gtkbitmaskprivate.h',
|
||||
'gtkbuilderprivate.h',
|
||||
@@ -148,11 +149,14 @@ private_headers = [
|
||||
'gtkmagnifierprivate.h',
|
||||
'gtkmediafileprivate.h',
|
||||
'gtkmenubuttonprivate.h',
|
||||
'gtkmenusectionboxprivate.h',
|
||||
'gtkmenutrackeritemprivate.h',
|
||||
'gtkmenutrackerprivate.h',
|
||||
'gtkmodulesprivate.h',
|
||||
'gtkmountoperationprivate.h',
|
||||
'gtknativedialogprivate.h',
|
||||
'gtknomediafileprivate.h',
|
||||
'gtkorientableprivate.h',
|
||||
'gtkpango.h',
|
||||
'gtkplacessidebarprivate.h',
|
||||
'gtkplacesviewprivate.h',
|
||||
'gtkplacesviewrowprivate.h',
|
||||
@@ -162,6 +166,7 @@ private_headers = [
|
||||
'gtkprintoperation-private.h',
|
||||
'gtkprivate.h',
|
||||
'gtkprogresstrackerprivate.h',
|
||||
'gtkquery.h',
|
||||
'gtkrangeprivate.h',
|
||||
'gtkrbtreeprivate.h',
|
||||
'gtkrenderbackgroundprivate.h',
|
||||
@@ -172,6 +177,7 @@ private_headers = [
|
||||
'gtkscalerprivate.h',
|
||||
'gtksearchentryprivate.h',
|
||||
'gtksettingsprivate.h',
|
||||
'gtkshortcutcontrollerprivate.h',
|
||||
'gtkshortcutsshortcutprivate.h',
|
||||
'gtkshortcutswindowprivate.h',
|
||||
'gtksidebarrowprivate.h',
|
||||
@@ -198,7 +204,9 @@ private_headers = [
|
||||
'gtktoolbarprivate.h',
|
||||
'gtktooltipprivate.h',
|
||||
'gtktooltipwindowprivate.h',
|
||||
'gtktreepopoverprivate.h',
|
||||
'gtktreeprivate.h',
|
||||
'gtktreerbtreeprivate.h',
|
||||
'gtkutilsprivate.h',
|
||||
'gtkwidgetpaintableprivate.h',
|
||||
'gtkwidgetpathprivate.h',
|
||||
@@ -207,6 +215,7 @@ private_headers = [
|
||||
'gtkwin32themeprivate.h',
|
||||
'gtkwindowprivate.h',
|
||||
'gtk-text-input-client-protocol.h',
|
||||
'roaring.h',
|
||||
]
|
||||
|
||||
images = [
|
||||
|
||||
@@ -457,6 +457,11 @@ as property. GtkNotebook and GtkAssistant are similar.
|
||||
gtk4-builder-tool can help with this conversion, with the --3to4 option
|
||||
of the simplify command.
|
||||
|
||||
### Adapt to GtkScrolledWindow API changes
|
||||
|
||||
The constructor for GtkScrolledWindow no longer takes the adjustments
|
||||
as arguments - these were almost always %NULL.
|
||||
|
||||
### Adapt to GtkBin removal
|
||||
|
||||
The abstract base class GtkBin for single-child containers has been
|
||||
@@ -638,7 +643,7 @@ nodes.
|
||||
|
||||
If you are using a #GtkDrawingArea for custom drawing, you need to switch
|
||||
to using gtk_drawing_area_set_draw_func() to set a draw function instead
|
||||
of connnecting a handler to the #GtkWidget::draw signal.
|
||||
of connecting a handler to the #GtkWidget::draw signal.
|
||||
|
||||
### Stop using APIs to query GdkSurfaces
|
||||
|
||||
@@ -940,3 +945,18 @@ You can replace calls to <function>gtk_dialog_run()</function>
|
||||
by specifying that the #GtkDialog must be modal using
|
||||
gtk_window_set_modal() or the %GTK_DIALOG_MODAL flag, and
|
||||
connecting to the #GtkDialog::response signal.
|
||||
|
||||
## Changes to consider after the switch
|
||||
|
||||
GTK 4 has a number of new features that you may want to take
|
||||
advantage of once the dust has settled over the initial migration.
|
||||
|
||||
### Consider porting to the new list widgets
|
||||
|
||||
In GTK 2 and 3, GtkTreeModel and GtkCellRenderer and widgets using
|
||||
these were the primary way of displaying data and lists. GTK 4 brings
|
||||
a new family of widgets for this purpose that uses list models instead
|
||||
of tree models, and widgets instead of cell renderers.
|
||||
|
||||
To learn more about the new list widgets, you can read the [List Widget
|
||||
Overview](#ListWidget).
|
||||
|
||||
@@ -4,9 +4,10 @@
|
||||
|
||||
GTK inspects a number of environment variables in addition to
|
||||
standard variables like `LANG`, `PATH`, `HOME` or `DISPLAY`; mostly
|
||||
to determine paths to look for certain files. The [X11]{#x11-envar},
|
||||
[Windows]{#win32-envar} and [Broadway]{#broadway-envar} GDK backends
|
||||
use some additional environment variables.
|
||||
to determine paths to look for certain files. The [X11](#x11-envar),
|
||||
[Wayland](#wayland-envar), [Windows](#win32-envar) and
|
||||
[Broadway](#broadway-envar) GDK backends use some additional
|
||||
environment variables.
|
||||
|
||||
### GTK_DEBUG {#GTK_Debug-Options}
|
||||
|
||||
|
||||
@@ -1,85 +1,182 @@
|
||||
# List Widget Overview {#ListWidget}
|
||||
|
||||
GTK provides powerful widgets to display and edit lists of data. This document gives an overview over the concepts and how they work together to allow developers to implement lists.
|
||||
GTK provides powerful widgets to display and edit lists of data. This document
|
||||
gives an overview over the concepts and how they work together to allow
|
||||
developers to implement lists.
|
||||
|
||||
Lists are intended to be used whenever developers want to display lists of objects in roughly the same way.
|
||||
Lists are intended to be used whenever developers want to display many objects
|
||||
in roughly the same way.
|
||||
|
||||
Lists are perfectly fine to be used for very short list of only 2 or 3 elements, but generally scale fine to millions of items. Of course, the larger the list grows, the more care needs to be taken to choose the right data structures to keep things running well.
|
||||
Lists are perfectly fine to be used for very short list of only 2 or 3 elements,
|
||||
but generally scale fine to millions of items. Of course, the larger the list
|
||||
grows, the more care needs to be taken to choose the right data structures to
|
||||
keep things running well.
|
||||
|
||||
Lists are meant to be used with changing data, both with the items itself changing as well as the list adding and removing items. Of course, they work just as well with static data.
|
||||
Lists are meant to be used with changing data, both with the items itself changing
|
||||
as well as the list adding and removing items. Of course, they work just as well
|
||||
with static data.
|
||||
|
||||
## Terminology
|
||||
|
||||
These terms are used throughout the documentation when talking about lists and you should be aware of what they refer to. These are often generic terms that have a specific meaning in this context.
|
||||
These terms are used throughout the documentation when talking about lists and
|
||||
you should be aware of what they refer to. These are often generic terms that
|
||||
have a specific meaning in this context.
|
||||
|
||||
**_Views_** or **_list widgets_** are the widgets that hold and manage the lists. Examples of thse widgets would be #GtkListView or #GtkGridView.
|
||||
**_Views_** or **_list widgets_** are the widgets that hold and manage the lists.
|
||||
Examples of these widgets would be #GtkListView or #GtkGridView.
|
||||
|
||||
Views display data from a **_model_**. A model is a #GListModel and models can be provided in 3 ways or combinations thereof:
|
||||
Views display data from a **_model_**. A model is a #GListModel and models can
|
||||
be provided in 3 ways or combinations thereof:
|
||||
|
||||
* Many list models implementations already exist. There are models that provide specific data, like #GtkDirectoryList. And there are models like #GListStore that allow building lists manually.
|
||||
* Many list models implementations already exist. There are models that provide
|
||||
specific data, like #GtkDirectoryList. And there are models like #GListStore
|
||||
that allow building lists manually.
|
||||
|
||||
* Wrapping list models exists like #GtkFilterListModel or #GtkSortListModel that modify or adapt or combine other models.
|
||||
* Wrapping list models like #GtkFilterListModel or #GtkSortListModel
|
||||
modify, adapt or combine other models.
|
||||
|
||||
* Last but not least, developers are encouraged to create their own #GListModel implementations. The interface is kept deliberately small to make this easy.
|
||||
* Last but not least, developers are encouraged to create their own #GListModel
|
||||
implementations. The interface is kept deliberately small to make this easy.
|
||||
|
||||
The same model can be used in multiple different views and wrapped with multiple different models at once.
|
||||
The same model can be used in multiple different views and wrapped with
|
||||
multiple different models at once.
|
||||
|
||||
The elements in a model are called **_items_**. All items are #GObjects.
|
||||
|
||||
Every item in a model has a **_position_** which is the unsigned integer that describes where in the model the item is located. This position can of course change as items are added or removed from the model.
|
||||
Every item in a model has a **_position_** which is the unsigned integer that
|
||||
describes where in the model the item is located. The first item in a model is
|
||||
at position 0. The position of an item can of course change as other items are
|
||||
added or removed from the model.
|
||||
|
||||
It is important to be aware of the difference between items and positions because the mapping from position to item is not permanent, so developers should think about whether they want to track items or positions when working with models. Oftentimes some things are really hard to do one way but very easy the other way.
|
||||
It is important to be aware of the difference between items and positions
|
||||
because the mapping from position to item is not permanent, so developers
|
||||
should think about whether they want to track items or positions when working
|
||||
with models. Oftentimes some things are really hard to do one way but very easy
|
||||
the other way.
|
||||
|
||||
The other important part of a view is a **_factory_**. Each factory is a #GtkListItemFactory implementation that takes care of mapping the items of the model to widgets that can be shown in the view.
|
||||
The other important part of a view is a **_factory_**. Each factory is
|
||||
a #GtkListItemFactory implementation that takes care of mapping the items
|
||||
of the model to widgets that can be shown in the view.
|
||||
|
||||
The way factories do this is by creating a **_listitem_** for each item that is currently in use. Listitems are always #GtkListItem objects. They are only ever created by GTK and provide information about what item they are meant to display.
|
||||
The way factories do this is by creating a **_listitem_** for each item that
|
||||
is currently in use. Listitems are always #GtkListItem objects. They are only
|
||||
ever created by GTK and provide information about what item they are meant
|
||||
to display.
|
||||
|
||||
Different factory implementations use various different methods to allow developers to add the right widgets to listitems and to link those widgets with the item managed by the listitem. Finding a suitable factory implementation for the data displayed, the programming language and development environment is an important task that can simplify setting up the view tremendously.
|
||||
Different factory implementations use various different methods to allow
|
||||
developers to add the right widgets to listitems and to link those widgets
|
||||
with the item managed by the listitem. Finding a suitable factory implementation
|
||||
for the data displayed, the programming language and development environment
|
||||
is an important task that can simplify setting up the view tremendously.
|
||||
|
||||
Views support selections via a **_selection model_**. A selection model is an implementation of the #GtkSelectionModel interface on top of the #GListModel interface that allows marking each item in a model as either selected or not selected. Just like regular models, this can be implemented either by implementing #GtkSelectionModel directly or by wrapping a model with one of the GTK models provided for this purposes, such as #GtkNoSelection or #GtkSingleSelection.
|
||||
The behavior of selection models - ie which items they allow selecting and what effect this has on other items - is completely up to the selection model. As such, single-selections, multi-selections or sharing selection state between different selection models and/or views is possible.
|
||||
The selection state of an item is exposed in the listitem via the GtkListItem:selected property.
|
||||
Views support selections via a **_selection model_**. A selection model is an
|
||||
implementation of the #GtkSelectionModel interface on top of the #GListModel
|
||||
interface that allows marking each item in a model as either selected or not
|
||||
selected. Just like regular models, this can be implemented either by
|
||||
implementing #GtkSelectionModel directly or by wrapping a model with one of
|
||||
the GTK models provided for this purposes, such as #GtkNoSelection
|
||||
or #GtkSingleSelection.
|
||||
|
||||
Views and listitems also support activation. Activation means that double clicking or pressing enter while inside a focused row will cause the view to emit and activation signal such as GtkListView::activate. This provides an easy way to set up lists, but can also be turned off on listitems if undesired.
|
||||
The behavior of selection models - ie which items they allow selecting and
|
||||
what effect this has on other items - is completely up to the selection model.
|
||||
As such, single-selections, multi-selections or sharing selection state between
|
||||
different selection models and/or views is possible. The selection state of an
|
||||
item is exposed in the listitem via the #GtkListItem:selected property.
|
||||
|
||||
Both selections and activation are supported among other things via widget actions (FIXME: Link docs). This allows developers to add widgets to their lists that cause selections to change or to trigger activation via the #GtkActionable interface. For a list of all supported actions see the relevant documentation. (FIXME: where do we document actions and how to I link that?)
|
||||
Views and listitems also support activation. Activation means that double
|
||||
clicking or pressing enter while inside a focused row will cause the view
|
||||
to emit and activation signal such as #GtkListView::activate. This provides
|
||||
an easy way to set up lists, but can also be turned off on listitems if undesired.
|
||||
|
||||
Both selections and activation are supported among other things via widget
|
||||
[actions](#actions-overview). This allows developers to add widgets to their
|
||||
lists that cause selections to change or to trigger activation via
|
||||
the #GtkActionable interface. For a list of all supported actions see the
|
||||
relevant documentation.
|
||||
|
||||
## Behind the scenes
|
||||
|
||||
While for short lists it is not a problem to instantiate widgets for every item in the model, once lists grow to thousands or millions of elements, this gets less feasible. Because of this, the views only create a limited amount of listitems and recycle them by binding them to new items. In general, views try to keep listitems available only for the items that can actually be seen on screen.
|
||||
While for short lists it is not a problem to instantiate widgets for every
|
||||
item in the model, once lists grow to thousands or millions of elements, this
|
||||
gets less feasible. Because of this, the views only create a limited amount of
|
||||
listitems and recycle them by binding them to new items. In general, views try
|
||||
to keep listitems available only for the items that can actually be seen on screen.
|
||||
|
||||
While this behavior allows views to scale effortlessly to huge lists, it has a few implication on what can be done with views. For example, it is not possible to query a view for a listitem used for a certain position - there might not be one and even if there is, that listitem might soon be recycled for a new position.
|
||||
While this behavior allows views to scale effortlessly to huge lists, it has a
|
||||
few implication on what can be done with views. For example, it is not possible
|
||||
to query a view for a listitem used for a certain position - there might not be
|
||||
one and even if there is, that listitem might soon be recycled for a new position.
|
||||
|
||||
It is also important that developers save state they care about in the item and do not rely on the widgets they created as those widgets can be recycled for a new position at any time causing any state to be lost.
|
||||
It is also important that developers save state they care about in the item and
|
||||
do not rely on the widgets they created as those widgets can be recycled for a
|
||||
new position at any time causing any state to be lost.
|
||||
|
||||
Another important requirement for views is that they need to know which items are not visible so they can be recycled. Views achieve that by implementing the #GtkScrollable interface and expecting to be placed directly into a #GtkScrolledWindow.
|
||||
Another important requirement for views is that they need to know which items
|
||||
are not visible so they can be recycled. Views achieve that by implementing
|
||||
the #GtkScrollable interface and expecting to be placed directly into
|
||||
a #GtkScrolledWindow.
|
||||
|
||||
Of course, if you are only using models with few items, this is not important and you can treat views like any other widget. But if you use large lists and your performance suffers, you should be aware of this. Views also allow tuning the number of listitems they create such as with gtk_grid_view_set_max_columns(), and developers running into performance problems should definitely study the tradeoffs of those and experiment with them.
|
||||
Of course, if you are only using models with few items, this is not important
|
||||
and you can treat views like any other widget. But if you use large lists and
|
||||
your performance suffers, you should be aware of this. Views also allow tuning
|
||||
the number of listitems they create such as with gtk_grid_view_set_max_columns(),
|
||||
and developers running into performance problems should definitely study the
|
||||
tradeoffs of those and experiment with them.
|
||||
|
||||
## Displaying trees
|
||||
## Displaying trees {#displaying-trees}
|
||||
|
||||
While #GtkTreeView provided builtin support for trees, the list widgets, and in particular #GListModel do not. This was a design choice because the common use case is displaying lists and not trees and it greatly simplifies the API interface provided.
|
||||
While #GtkTreeView provided built-in support for trees, the list widgets, and
|
||||
in particular #GListModel do not. This was a design choice because the common
|
||||
use case is displaying lists and not trees and it greatly simplifies the API
|
||||
interface provided.
|
||||
|
||||
However, GTK provides functionality to make trees look and behave like lists for the people who still want to display lists. This is achieved by using the #GtkTreeListModel model to flatten a tree into a list. The #GtkTreeExpander widget can then be used inside a listitem to allow users to expand and collapse rows and provide a similar experience to #GtkTreeView.
|
||||
However, GTK provides functionality to make trees look and behave like lists
|
||||
for the people who still want to display lists. This is achieved by using
|
||||
the #GtkTreeListModel model to flatten a tree into a list. The #GtkTreeExpander
|
||||
widget can then be used inside a listitem to allow users to expand and collapse
|
||||
rows and provide a similar experience to #GtkTreeView.
|
||||
|
||||
Developers should refer to those objects' API reference for more discussion on the topic.
|
||||
Developers should refer to those objects' API reference for more discussion
|
||||
on the topic.
|
||||
|
||||
## comparison to GtkTreeView
|
||||
## Comparison to GtkTreeView
|
||||
|
||||
Developers familiar with #GtkTreeView may wonder how this way of doing lists compares to the way they know. This section will try to outline the similarities and differences between the two.
|
||||
Developers familiar with #GtkTreeView may wonder how this way of doing lists
|
||||
compares to the way they know. This section will try to outline the similarities
|
||||
and differences between the two.
|
||||
|
||||
This new approach tries to provide roughly the same functionality as the old approach but often uses a very different approach to achieve these goals.
|
||||
This new approach tries to provide roughly the same functionality as the old
|
||||
approach but often uses a very different approach to achieve these goals.
|
||||
|
||||
The main difference and one of the primary reasons for this new development is that items can be displayed using regular widgets and #GtkCellRenderer is no longer necessary. This allows all benefits that widgets provide, such as complex layout and animating widgets and not only makes cell renderers obsolete, but also #GtkCellArea.
|
||||
The main difference and one of the primary reasons for this new development is
|
||||
that items can be displayed using regular widgets and #GtkCellRenderer is no
|
||||
longer necessary. This allows all benefits that widgets provide, such as complex
|
||||
layout and animating widgets and not only makes cell renderers obsolete, but
|
||||
also #GtkCellArea.
|
||||
|
||||
The other big difference is the massive change to the data model. #GtkTreeModel was a rather complex interface for a tree data structure and #GListModel was deliberately designed to be a simple data structure for lists only. (See above (FIXME: link) for how to still do trees with this new model.) Another big change is that the new model allows for bulk changes via the #GListModel:items-changed signal while #GtkTreeModel only allows a single item to change at once.
|
||||
The goal here is of course to encourage implementation of custom list models.
|
||||
The other big difference is the massive change to the data model. #GtkTreeModel
|
||||
was a rather complex interface for a tree data structure and #GListModel was
|
||||
deliberately designed to be a simple data structure for lists only. (See
|
||||
[above](#displaying-trees)) for how to still do trees with this new model.)
|
||||
Another big change is that the new model allows for bulk changes via
|
||||
the #GListModel:items-changed signal while #GtkTreeModel only allows a single
|
||||
item to change at once. The goal here is of course to encourage implementation
|
||||
of custom list models.
|
||||
|
||||
Another consequence of the new model is that it is now easily possible to refer to the contents of a row in the model directly by keeping the item, while #GtkTreeRowReference was a very slow mechanism to achieve the same. And because the items are real objects, developers can make them emit change signals causing listitems and their children to update, which wasn't possible with #GtkTreeModel.
|
||||
Another consequence of the new model is that it is now easily possible to
|
||||
refer to the contents of a row in the model directly by keeping the item,
|
||||
while #GtkTreeRowReference was a very slow mechanism to achieve the same.
|
||||
And because the items are real objects, developers can make them emit change
|
||||
signals causing listitems and their children to update, which wasn't possible
|
||||
with #GtkTreeModel.
|
||||
|
||||
The selection handling is also different. While selections used to be managed via custom code in each widget, selection state is now meant to be managed by the selection models. In particular this allows for complex use cases with specialized requirements (FIXME: Can I add a shoutout to @mitch here because I vividly remember a huge discussion about GtkTreeView's selection behavior and the Gimp).
|
||||
The selection handling is also different. While selections used to be managed
|
||||
via custom code in each widget, selection state is now meant to be managed by
|
||||
the selection models. In particular this allows for complex use cases with
|
||||
specialized requirements.
|
||||
|
||||
Finally here's a quick list of equivalent functionality to look for when transitioning code for easy lookup:
|
||||
Finally here's a quick list of equivalent functionality to look for when
|
||||
transitioning code for easy lookup:
|
||||
|
||||
| Old | New |
|
||||
| ------------------- | ----------------------------------- |
|
||||
|
||||
@@ -7,4 +7,13 @@ the Wayland backend by setting `GDK_BACKEND=wayland`.
|
||||
On UNIX, the Wayland backend is enabled by default, so you don't need to
|
||||
do anything special when compiling it, and everything should "just work."
|
||||
|
||||
Currently, the Wayland backend does not use any additional environment variables.
|
||||
## Wayland-specific environment variables {#wayland-envar}
|
||||
|
||||
### WAYLAND_DISPLAY
|
||||
|
||||
Specifies the name of the Wayland display to use. Typically, wayland-0
|
||||
or wayland-1.
|
||||
|
||||
### XDG_RUNTIME_DIR
|
||||
|
||||
Used to locate the Wayland socket to use.
|
||||
|
||||
@@ -16,7 +16,6 @@ variables.
|
||||
### GDK_IGNORE_WINTAB
|
||||
|
||||
If this variable is set, GTK doesn't use the Wintab API for tablet support.
|
||||
</para>
|
||||
|
||||
### GDK_USE_WINTAB
|
||||
|
||||
@@ -37,10 +36,10 @@ can override GTK settings in the `settings.ini` file or at runtime in the
|
||||
GTK Inspector.
|
||||
|
||||
Themes are loaded from normal Windows variants of the XDG locations:
|
||||
`%HOME%/icons/THEME/cursors`,
|
||||
`%APPDATA%/icons/THEME/cursors`,
|
||||
`%HOME%/icons/THEME/cursors`,
|
||||
`%APPDATA%/icons/THEME/cursors`,
|
||||
`RUNTIME_PREFIX/share/icons/THEME/cursors`
|
||||
|
||||
The `gtk-cursor-theme-size`> setting is ignored, GTK will use
|
||||
The `gtk-cursor-theme-size` setting is ignored, GTK will use
|
||||
the cursor size that Windows tells it to use.
|
||||
|
||||
|
||||
@@ -881,7 +881,7 @@ create_scrolledwindow (void)
|
||||
{
|
||||
GtkWidget *scrolledwin, *label;
|
||||
|
||||
scrolledwin = gtk_scrolled_window_new (NULL, NULL);
|
||||
scrolledwin = gtk_scrolled_window_new ();
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwin),
|
||||
GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
|
||||
label = gtk_label_new ("Scrolled Window");
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user